Coding Net
Query and operate on Tencent Coding DevOps platform (e.coding.net) data — iterations, issues (requirements/defects/tasks), and team members — including creat...
wangyin717
@wangyin717
What This Skill Does
Query and operate on Tencent Coding DevOps platform data including iterations, issues (requirements/defects/tasks), and team members. Supports creating requirements and defects through a Python script interface that requires a CODING_TOKEN environment variable.
Replaces manual navigation of the Coding.net web interface by providing programmatic access to iterations, issues, and team member data through a structured API.
When to Use It
- List all iterations in a Coding.net project to track sprint progress
- Query open defects assigned to a specific team member
- Create a new requirement in the current iteration
- Retrieve team member list with IDs for assignment operations
- Get custom fields from issues for reporting or export
- Describe a single issue's full details by its ID
Install
$ openclaw skills install @wangyin717/coding-netCoding Open API Skill
Bootstrap (must run at the start of every conversation)
Step 1: Collect the token
Check whether the user's message already includes a token. If not, check the environment variable:
python3 -c "import os; print('set' if os.environ.get('CODING_TOKEN') else 'not set')"
If neither is available, ask the user: "Please provide your Coding personal access token (Bearer Token)."
Step 2: Validate the token and confirm the team
import sys; sys.path.insert(0, "path/to/coding-net/scripts")
from core import bootstrap
result = bootstrap(token="<token>")
if result["error"]:
print("✗", result["error"])
else:
t = result["team"]
print(f"✓ Token valid Team: {t['name']} ({t['host']})")
Step 3: Confirm the project identifier
Let the user know the team has been verified, then ask:
"Please provide the project URL or project identifier. The URL format is https://<team>.coding.net/p/<project-identifier>/, where the project identifier is the part after /p/ (e.g. biaopin-swiftagent)."
⚠️ Never guess the project name. Coding.net distinguishes between "display name" and "project identifier" — the API only accepts the identifier. The user saying "the project is called swiftagent" does NOT mean the identifier is
swiftagent; always ask for the URL to confirm.
Step 4: Validate the project + show the iteration list for the user to choose from
result = bootstrap("biaopin-swiftagent", token="<token>")
if result["error"]:
print("✗", result["error"])
else:
print("Iterations in this project:")
for it in result["iterations"]:
print(f" [{it['code']}] {it['name']}")
Show the iteration list to the user and ask: "Which iteration would you like to look at?"
Only after completing these four steps should you proceed with the user's actual query.
Environment configuration (optional — set these to skip passing parameters)
| Variable | Description |
|---|---|
CODING_TOKEN | Bearer Token |
CODING_DEFAULT_PROJECT_NAME | Default project identifier (the part after /p/ in the URL) |
CODING_DEFAULT_ITERATION_CODE | Default iteration Code (integer) |
Script layout
scripts/
├── core.py — HTTP client, token resolution, CodingAPIError
├── iterations.py — Iteration API (depends on core)
├── issues.py — Issue API (depends on core + iterations)
└── members.py — Team member API (depends on core)
Usage in Python (the scripts already handle sys.path, so just import directly):
import sys
sys.path.insert(0, "path/to/scripts")
from iterations import get_iteration_list_code_and_name
from issues import describe_issue, describe_issue_list, create_issue, describe_defect_types, \
extract_members_from_issue_list, get_custom_fields_from_issues
from members import get_team_members_id_and_name
Public function reference
iterations.py
get_iteration_list_code_and_name(project_name=None, *, token=None) -> [{'code': int, 'name': str}]
Paginates through and returns the full iteration list. The returned code is the value needed by describe_issue_list(iteration=...).
issues.py
describe_issue_list(
project_name=None, *, # falls back to CODING_DEFAULT_PROJECT_NAME if omitted
issue_type="ALL", # ALL / REQUIREMENT / DEFECT / MISSION
limit="2000",
assignee_ids=None, # [int] — server-side filter (unreliable; pair with filter_issues for a client-side re-filter)
iteration=None, # int — falls back to CODING_DEFAULT_ITERATION_CODE if omitted; a client-side re-filter is already built in
status_types=None, # None→TODO+PROCESSING; []→no filter; ['TODO',...]→specific types
base_issue_type=None, # REQUIREMENT / DEFECT / MISSION
token=None,
) -> dict
# Each entry in Response.IssueList contains:
# Code, Name, Type, IssueStatusName, IssueStatusType, Priority,
# Assignees([{"id": int, "name": str}]), ← array of assignees (not Creator/Handler)
# IterationCode, IterationName, StartDate, DueDate, CustomFields
filter_issues(
items: list, # the IssueList returned by describe_issue_list
*,
assignee_name=None, # assignee name (fuzzy match, case-insensitive)
assignee_id=None, # assignee ID (exact match)
iteration_code=None, # secondary iteration Code filter (use when server-side filtering fails)
) -> list
describe_issue(project_name=None, issue_code=0, *, token=None) -> dict
# Returns {Name, Description, IssueStatusName, AssigneeName, CreatorName}
create_issue(
project_name=None, *,
name: str, # title (required)
issue_type="REQUIREMENT", # REQUIREMENT / DEFECT / MISSION
description="",
priority=2, # 0=Low 1=Medium 2=High(default) 3=Urgent (per API docs)
assignee_id=None, # int — member ID (see members.py, or look it up from the issue list)
iteration=None, # int — falls back to CODING_DEFAULT_ITERATION_CODE if omitted
start_date=None, # str 'YYYY-MM-DD' — required in some projects
due_date=None, # str 'YYYY-MM-DD' — required in some projects
label_ids=None, # [int] — required in some projects; missing value raises issue_project_label_required
working_hours=None, # float — estimated hours; required in some projects
issue_type_id=None, # int — issue category ID (not the defect subtype)
defect_type_id=None, # int — defect subtype ID, from describe_defect_types
token=None,
) -> dict # {Code, Name, IssueStatusName, AssigneeName, CreatorName}
describe_defect_types(project_name=None, *, token=None) -> [{'id': int, 'name': str}]
# Returns the list of defect subtypes, for use with create_issue(defect_type_id=...)
extract_members_from_issue_list(issues_result: dict) -> [{'id': int, 'name': str}]
# Extracts a deduplicated member list from the return value of describe_issue_list — a fallback for
# when the token lacks permission for DescribeTeamMembers
get_custom_fields_from_issues(
project_name=None, *,
issue_type="REQUIREMENT", # sample by issue type
sample=10, # number of items to sample
token=None,
) -> [{'id': int, 'name': str}]
# Infers a project's custom fields by sampling existing issues
# (works around DescribeIssueCustomFieldsBoundToProject, which requires elevated permissions)
# Must be called before creating an issue, so any required fields can be passed to
# create_issue via custom_field_values
members.py
get_team_members_id_and_name(*, token=None) -> [{'id': int, 'name': str}]
Paginates through and returns the full team member list. id can be used to filter with describe_issue_list(assignee_ids=[...]).
Note: Some tokens lack the DescribeTeamMembers permission, which causes an error — fall back to extract_members_from_issue_list in that case.
Common workflows
Query a specific assignee's requirements in a given iteration (standard flow):
import sys; sys.path.insert(0, "path/to/coding-net/scripts")
from issues import describe_issue_list, filter_issues
result = describe_issue_list(project_name, iteration=22904, issue_type="REQUIREMENT", status_types=[])
issues = result["Response"]["IssueList"]
# Filter by assignee client-side (server-side filtering is unreliable)
my_issues = filter_issues(issues, assignee_name="wangyin")
for it in my_issues:
assignees = ", ".join(a["name"] for a in it["Assignees"])
print(f"#{it['Code']} [{it['IssueStatusName']}] {it['Name']} — {assignees}")
Extract members from the issue list (fallback when DescribeTeamMembers is not permitted):
from issues import describe_issue_list, extract_members_from_issue_list
result = describe_issue_list(project_name, iteration=code, status_types=[])
members = extract_members_from_issue_list(result)
# [{'id': 9403993, 'name': 'wangyin'}, ...]
Query the details of a single issue (including description):
from issues import describe_issue
detail = describe_issue(project_name, issue_code=12345)
Create a requirement (must detect custom fields first):
⚠️ A project may have required custom fields configured (e.g. "test submission date"); creating without them raises
issue_custom_field_required. First callget_custom_fields_from_issues()to infer the field list, then passcustom_field_values.
from issues import create_issue, get_custom_fields_from_issues
# Step 1: Detect the project's custom fields
custom_fields = get_custom_fields_from_issues(project_name, issue_type="REQUIREMENT")
# Example return: [{"id": 38589683, "name": "Test submission date"}, ...]
# Confirm each field's value with the user; required fields must be passed in
# Step 2: Create the requirement
issue = create_issue(
project_name,
name="Support feature XX",
start_date="2026-06-17",
due_date="2026-06-30",
custom_field_values=[
{"Id": 38589683, "Content": "2026-06-30"}, # Test submission date
# other required custom fields...
],
)
print(issue["Code"], issue["Name"])
Create a defect (including project-level required fields):
from issues import describe_issue_list, extract_members_from_issue_list, describe_defect_types, create_issue, filter_issues
# 1. Look up member ID from the issue list
result = describe_issue_list(project_name, iteration=code, status_types=[])
members = extract_members_from_issue_list(result)
uid = next(m["id"] for m in members if m["name"] == "Zhang San")
# 2. Look up defect subtypes
defect_types = describe_defect_types(project_name) # [{'id': 36666669, 'name': 'Functional defect'}, ...]
# 3. Create (whether start_date/due_date/label_ids/working_hours are required depends on project config)
issue = create_issue(
project_name,
name="Login page returns a 500 error",
issue_type="DEFECT",
priority=1,
assignee_id=uid,
iteration=code,
start_date="2026-06-17",
due_date="2026-06-20",
label_ids=[123],
working_hours=2.0,
defect_type_id=defect_types[0]["id"],
)
Top skills in this category
Skill Vetter
@spclaudehomeSecurity-first skill vetting for AI agents. Use before installing any skill from ClawdHub, GitHub, or other sources. Checks for red flags, permission scope, and suspicious patterns.
Github
@steipeteInteract with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Humanizer
@biostartechnologyRemove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's comprehensive "Signs of AI writing" guide. Detects and fixes patterns including: inflated symbolism, promotional language, superficial -ing analyses, vague attributions, em dash overuse, rule of three, AI vocabulary words, negative parallelisms, and excessive conjunctive phrases.
Free Ride - Unlimited free AI
@shaivpidadiManages free AI models from OpenRouter for OpenClaw. Automatically ranks models by quality, configures fallbacks for rate-limit handling, and updates opencla...
Elite Longterm Memory
@nextfrontierbuildsUltimate AI agent memory system for Cursor, Claude, ChatGPT & Copilot. WAL protocol + vector search + git-notes + cloud backup. Never lose context again. Vibe-coding ready.