@mu-cabin/coding-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@mu-cabin/coding-cli",
3
+ "version": "0.1.0",
4
+ "description": "Agent-first CLI for operating a CODING instance over its OpenAPI surface.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "coding": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "generated/",
13
+ "skills/"
14
+ ],
15
+ "engines": {
16
+ "node": ">=18"
17
+ },
18
+ "dependencies": {
19
+ "commander": "^12.1.0",
20
+ "yaml": "^2.5.1"
21
+ },
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "build:spec": "tsx scripts/build-spec.ts",
25
+ "regen": "pnpm build && pnpm build:spec",
26
+ "typecheck": "tsc --noEmit",
27
+ "test": "tsx --test test/*.test.ts",
28
+ "clean": "rm -rf dist"
29
+ }
30
+ }
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: coding
3
+ version: 0.1.0
4
+ description: "Operate a self-hosted or SaaS CODING DevOps platform via the `coding` CLI — a generic OpenAPI passthrough over all 429 actions / 17 categories, with per-domain playbooks in references/ that load on demand. Use whenever the user mentions CODING, the instance host (e.g. coding.example.com), or any CODING resource — projects/项目, programs/项目集, issues 事项/迭代, merge requests 合并请求, CI 流水线 & CD 部署, 制品/artifacts, test 测试, Wiki, 权限, org/部门/成员, service-hook 服务钩子, file upload/导出 — even without naming the platform."
5
+ metadata:
6
+ requires:
7
+ bins: ["coding"]
8
+ cliHelp: "coding --help"
9
+ ---
10
+
11
+ # coding
12
+
13
+ Drive a CODING instance over its OpenAPI surface. The CLI is a **generic passthrough**:
14
+ one `coding call <Action>` invokes any of the 429 actions, with a bundled action index for
15
+ discovery, validation, and safety. Always pass `--json` when you need to parse output.
16
+
17
+ For any task in a specific domain (issues, code/MRs, CI, CD, deploys, artifacts, wiki, permissions,
18
+ …), read the matching playbook in `references/` **before** falling back to the generic
19
+ search→schema→call recipe below — see the router in §9. The playbook front-loads the right action
20
+ names, identifier resolution, enums, and gotchas, so you avoid failed calls and wasted context.
21
+ Each builds on this page (bootstrap, exit codes, the exit-10 gate) and doesn't repeat it, so skim
22
+ this file first, then load only the one playbook your task needs.
23
+
24
+ ## 1. Bootstrap (config + token)
25
+
26
+ 1. **Config** (**required** — the built-in default `coding.example.com` is a non-working placeholder):
27
+ point the CLI at the real instance with `coding config init --base-url <url>` (writes
28
+ `~/.coding/config.json`), the `--base-url` flag, or `CODING_API_BASE`. `coding config show` reports
29
+ the resolved base URL and whether a token is present.
30
+ 2. **Token** — CODING uses a static **personal access token** (`Authorization: token <…>`). There is
31
+ no device-flow login. The token is a secret:
32
+ - **Never** accept a token pasted into chat, never put it in argv, never echo it.
33
+ - Hand the user this to run **in their own terminal**: `coding auth login` (hidden prompt), or
34
+ `coding auth login --token -` to pipe it. `CODING_TOKEN` env var also works and overrides the file.
35
+ 3. **Verify**: `coding auth status --json` → current user. Run this first when unsure.
36
+
37
+ > **Token scope is the #1 source of friction.** A valid token only reaches the actions its scope
38
+ > covers (see §5). `UnauthorizedOperation` means "expand the token's scope", **not** "wrong token".
39
+
40
+ ## 2. Discovery recipe — search → schema → call
41
+
42
+ Don't guess action names; the index knows 429 of them. The server hides unknown actions behind a
43
+ scope error, so it will **not** tell you a name is mistyped — the CLI's validation will.
44
+
45
+ ```bash
46
+ coding actions --search <keyword> --json # find by name/summary/description
47
+ coding actions --category "08-项目协同" --json # filter by category
48
+ coding categories --json # the 17 categories
49
+ coding schema <Action> --json # params (name/type/required), response, errors, risk
50
+ ```
51
+
52
+ `coding schema <Action>` is the source of truth for an action's params, response shape, and errors —
53
+ read it before calling an action you haven't used.
54
+
55
+ If an action seems missing or stale, refresh the bundled index from the live spec:
56
+ `coding update` (or `coding update --dry-run` to preview the added/removed diff first).
57
+
58
+ ## 3. Call recipe
59
+
60
+ ```bash
61
+ # canonical: JSON body (handles nested objects & arrays)
62
+ coding call CreateIssue --data '{"ProjectName":"demo","Type":"REQUIREMENT","Name":"…","Priority":"1"}' --json # Priority "0"低 "1"中 "2"高 "3"紧急
63
+ coding call DescribeIssueList --data @body.json --json
64
+ echo '{…}' | coding call <Action> --data - --json
65
+
66
+ # convenience: flat params, coerced by index type (Id=1 → number, Foo=true → bool)
67
+ coding call DescribeIssue --param ProjectName=demo --param IssueCode=42 --json
68
+
69
+ # keep context lean: project just the fields you need, cap arrays
70
+ coding call DescribeIssueList --param ProjectName=demo --param IssueType=ALL \
71
+ --select 'IssueList[].Code,IssueList[].Name' --limit 20 --json
72
+ ```
73
+
74
+ - `--param` merges on top of `--data`. `--select` paths are relative to the response `data`
75
+ (dot notation, `[]` to map an array, `[n]` to index). `--limit N` truncates arrays.
76
+ - Validation rejects unknown action / missing-required / unknown-param by default. If your instance
77
+ has an action the public spec lacks, add `--force` (alias `--no-validate`) to send anyway.
78
+
79
+ ## 4. Output & exit codes
80
+
81
+ `--json` success: `{ ok:true, action, requestId, data }` (the server `Response` minus `RequestId`).
82
+ Error: `{ ok:false, action?, requestId?, error:{ code?|type?, message, hint?, risk? } }`.
83
+ **Parse the envelope yourself** — don't assume `jq`/`python` exist.
84
+
85
+ | exit | meaning | what to do |
86
+ |---|---|---|
87
+ | 0 | ok | — |
88
+ | 2 | usage | fix CLI args |
89
+ | 3 | auth (`AuthFailure`) | token missing/invalid → user re-runs `coding auth login` |
90
+ | 4 | not-found | resource (or action not in index for `schema`) |
91
+ | 5 | remote/network | retry later / inspect `error.message` |
92
+ | 7 | config invalid | malformed config file → fix it or re-run `coding config init` (a *missing* config is non-fatal: defaults apply) |
93
+ | 8 | forbidden (`UnauthorizedOperation`/`OperationDenied`) | **expand token scope** for this action |
94
+ | 9 | rate-limit (`RequestLimitExceeded`) | back off & pace — CLI does **not** auto-retry (30 req/s/team/action) |
95
+ | 10 | confirmation required | destructive action — see §6 |
96
+ | 11 | validation | fix params, or `--force` to bypass |
97
+
98
+ ## 5. Error playbook
99
+
100
+ - **exit 3 `AuthFailure`** — "User not found, authorization invalid": the token is bad/absent. Ask the
101
+ user to re-run `coding auth login`. Do not retry blindly.
102
+ - **exit 8 `UnauthorizedOperation`** — token valid, scope insufficient. Tell the user which action
103
+ needs which scope and to mint a token with that scope in their instance's token settings. Do **not**
104
+ run `auth login` to fix this (the token isn't wrong).
105
+ - **exit 9 `RequestLimitExceeded`** — pause and pace requests; never tight-loop retries.
106
+ - **exit 11 validation** — usually a typo or a missing required param; re-check with `coding schema`.
107
+
108
+ ## 6. Safety — the exit-10 confirmation gate
109
+
110
+ Destructive actions (`Delete*`, `Remove*`, `Disable*`, `Revoke*`, `Reset*`, `Clear*`, `Stop*`,
111
+ `Terminate*`, `Unbind*`, …) are gated. Calling one without `--yes` exits **10** with
112
+ `error.type == "confirmation_required"` and an `error.risk` block.
113
+
114
+ **Protocol:**
115
+ 1. See exit 10 + `confirmation_required` → do **not** treat it as a normal error.
116
+ 2. Show the user `error.risk.action` and the key params; state plainly it's destructive; wait for
117
+ explicit approval.
118
+ 3. Approved → re-run the **same argv with `--yes` appended**.
119
+ 4. Declined → stop. Never silently add `--yes`, never rewrite params to dodge the gate.
120
+
121
+ Preview anything first with `--dry-run` (prints the full request, redacted token, **does not** trip
122
+ the gate and **does not** send). Use it to show the user a destructive call before running it.
123
+
124
+ > Actions absent from the index with an **unrecognized verb** are gated as destructive (fail-safe),
125
+ > since the CLI has no risk metadata for them. Combine `--force` (to bypass validation) with `--yes`
126
+ > (after user approval) only when you're sure such an action is safe.
127
+
128
+ ## 7. Scope notes for the agent
129
+
130
+ - Write/delete only after the user's intent is explicit; prefer `--dry-run` to confirm shape.
131
+ - Resolve identifiers before mutating: resolve the **project** first (§8), then the resource key
132
+ (e.g. the issue code before `ModifyIssue`/`DeleteIssue`).
133
+ - Large lists: always pair list calls with `--select`/`--limit` to protect your context window.
134
+
135
+ ## 8. Resolving a project — the near-universal first step
136
+
137
+ Almost every domain action needs a project identifier, and there are three — don't mix them up:
138
+ - **`ProjectId`** (numeric) — primary key for most writes/reads (modify, members, labels, delete).
139
+ - **`ProjectName`** (string) — the project's **`Name`** *slug* (as used in URLs, e.g. `demo-project`),
140
+ **not** its `DisplayName` (the UI label). Used by name-based reads.
141
+
142
+ Resolve one before mutating, then cache it for the session:
143
+
144
+ ```bash
145
+ # name slug → ProjectId (+ the rest)
146
+ coding call DescribeProjectByName --param ProjectName=demo-project \
147
+ --select 'Project.Id,Project.Name,Project.DisplayName' --json
148
+ # the current user's projects — UserId from `coding auth status` / DescribeCodingCurrentUser
149
+ coding call DescribeUserProjects --param UserId=254 \
150
+ --select 'ProjectList[].Id,ProjectList[].Name,ProjectList[].DisplayName' --json
151
+ # team-wide paged list (optional ProjectName filter; QueryArchived to include archived)
152
+ coding call DescribeCodingProjects --param PageNumber=1 --param PageSize=50 \
153
+ --select 'Data.ProjectList[].Id,Data.ProjectList[].Name,Data.ProjectList[].DisplayName' --json
154
+ ```
155
+
156
+ `references/project.md` covers the rest of this category (create/modify/archive, members & roles,
157
+ labels, announcements).
158
+
159
+ ## 9. Domain playbooks (read the matching one on demand)
160
+
161
+ Each API category has a curated playbook under `references/` — the identifiers to resolve first, the
162
+ common recipes, condition keys, and gotchas, all ground-truthed against the action index. **For a task
163
+ in any domain below, read that file before improvising with the generic recipe** — it's the curated
164
+ shortcut. Read **just** the one file (not all of them): it assumes everything on this page and adds
165
+ only the domain specifics. Most playbooks need a project identifier first — resolve it via §8.
166
+
167
+ Each playbook deliberately **omits the param dictionary**: run `coding schema <Action>` for the
168
+ authoritative param/response/error list. The files instead give you what `schema` can't — which
169
+ action to call, runnable examples, value encodings and enums, multi-step sequencing, and the spots
170
+ where the spec itself is misleading.
171
+
172
+ | Category | Read | Use it for |
173
+ |---|---|---|
174
+ | 项目协同 / Issues (08) | `references/issues.md` | 事项/需求/缺陷/任务, 迭代/sprints, 版本/releases, comments, work-hours |
175
+ | 代码托管 / Code (09) | `references/code.md` | repos, branches, files, commits, tags, merge requests / code review |
176
+ | 持续集成 / CI (10) | `references/ci.md` | 构建计划/build plans, trigger builds, build logs, debug a failed build |
177
+ | 持续部署 / CD (11) | `references/cd.md` | deploy applications, 部署流程, trigger/cancel deploys, host groups, deploy metrics |
178
+ | 制品仓库 / Artifacts (12) | `references/artifacts.md` | Docker/Maven/npm/… packages & versions, download URLs, release/forbid, 授信 |
179
+ | 项目 / Project (04) | `references/project.md` | resolve/create/modify projects, members & roles, labels, announcements (foundational) |
180
+ | 测试管理 / Test (15) | `references/test.md` | 测试计划/runs, 测试用例, record results, link defects, test reports |
181
+ | 权限 / Permissions (03) | `references/permissions.md` | 权限组/policies, 用户组, grant/revoke on a resource, inheritance |
182
+ | 组织和成员 / Org (02) | `references/org.md` | team members, lock/remove, 部门 org tree, department heads, LDAP sync |
183
+ | Wiki (13) | `references/wiki.md` | wiki page tree, read/create/edit, move/rename, recycle bin, ZIP import |
184
+ | Service Hook (06) | `references/servicehook.md` | webhooks/robots (WeCom/DingDing/FeiShu/Jenkins), test/resend deliveries |
185
+ | 项目集 / Program (05) | `references/program.md` | portfolios grouping projects, program membership & permissions |
186
+ | 文件网盘 / Files (14) | `references/files.md` | upload files / issue attachments (presign → upload → register), folders |
187
+ | 导出任务 / Export (17) | `references/export.md` | export wiki/pages to a ZIP of Markdown (async create → start → poll) |
188
+ | 团队·关联资源·其他 (01/07/16) | `references/admin.md` | current user & team info, resource reference graph, 汉字→拼音 |
@@ -0,0 +1,65 @@
1
+ # coding-admin
2
+
3
+ A curated playbook bundling three tiny categories — **团队 (01)**, **关联资源 (07)**, **其他 (16)** —
4
+ 5 actions, **all read-only** (no exit-10 gate).
5
+
6
+ ## 1. Current user & team (团队)
7
+
8
+ ```bash
9
+ # the logged-in user (no params). NOTE: the CLI already wraps this as `coding auth status` / `coding whoami`
10
+ # — prefer those for an identity check; call the action directly only when you want the raw User object.
11
+ coding call DescribeCodingCurrentUser --select 'User.Id,User.Name,User.GlobalKey,User.Email,User.TeamId' --json
12
+
13
+ # team / instance info (no params) → wrapped under Data
14
+ coding call DescribeTeam --select 'Data.Id,Data.Name,Data.TeamHost,Data.TeamOwner.Name' --json
15
+ ```
16
+
17
+ `DescribeCodingCurrentUser` → top-level **`User`**; `DescribeTeam` → **`Data`** (a `TeamData` with
18
+ `TeamHost`, `Name`, `Id`, `TeamOwner`). Neither takes parameters.
19
+
20
+ ## 2. Resource reference graph (关联资源)
21
+
22
+ Both actions take the **same three params** and return `Resource[]` (top-level array of
23
+ `{Scope, Resource}`). They describe the two directions of the link graph for one resource:
24
+
25
+ - **`DescribeResourceReferencesCiting`** (引用) — resources that the given resource **references**
26
+ (its outbound links).
27
+ - **`DescribeResourceReferencesCited`** (被引用) — resources that **reference** the given resource
28
+ (inbound backlinks).
29
+
30
+ ```bash
31
+ # what does resource X reference? (ScopeType: 1=project, 2=team; ScopeId = that project/team id)
32
+ coding call DescribeResourceReferencesCiting --data '{"ScopeType":1,"ScopeId":341,"ResourceCode":"<code>"}' \
33
+ --select 'Resource[].Resource.Title,Resource[].Resource.ResourceType,Resource[].Resource.ResourceCode,Resource[].Scope.ScopeName' --json
34
+
35
+ # what references resource X?
36
+ coding call DescribeResourceReferencesCited --data '{"ScopeType":1,"ScopeId":341,"ResourceCode":"<code>"}' \
37
+ --select 'Resource[].Resource.Title,Resource[].Resource.ResourceType,Resource[].Scope.ScopeName' --json
38
+ ```
39
+
40
+ > The Citing/Cited direction above is the natural reading of 引用/被引用, but since both take identical
41
+ > params, **confirm the direction against the returned data** (each item's `Scope` tells you which side
42
+ > the listed resource sits on) before relying on it.
43
+
44
+ ## 3. Chinese → pinyin (其他)
45
+
46
+ ```bash
47
+ # Heteronym=true returns all readings for polyphonic chars; Style is the output style (e.g. NORMAL).
48
+ coding call DescribePinyin --data '{"Value":"学生","Heteronym":true,"Style":"NORMAL"}' \
49
+ --select 'Data.Value,Data.Array[].Value' --json
50
+ ```
51
+
52
+ `Data.Value` is the flat pinyin list; `Data.Array[].Value` is the per-character (segmented) readings.
53
+ Useful for computing the `NamePinyin`/sort keys other categories expose as read-only fields.
54
+
55
+ ## 4. Gotchas
56
+
57
+ - **`DescribeCodingCurrentUser` is what `coding auth status`/`coding whoami` already call** — use the
58
+ built-in commands for a quick identity/connectivity check; hit the action directly only for the raw
59
+ `User` fields.
60
+ - **Uneven wrapping**: `DescribeCodingCurrentUser` → top-level `User`; `DescribeTeam` → `Data`;
61
+ reference reads → top-level `Resource[]`; `DescribePinyin` → `Data`.
62
+ - **`ScopeType` is `1`=project / `2`=team**, and `ScopeId` must be the matching id; `ResourceCode` is
63
+ the resource's code (not its numeric id). Citing vs Cited is the only difference between the two
64
+ reference actions — verify the direction against the response.
65
+ - **All read-only** — nothing here mutates, so no `--yes`/exit-10 concerns.
@@ -0,0 +1,138 @@
1
+ # coding-artifacts
2
+
3
+ A curated playbook for the **制品仓库 (12)** category — the 19 artifact-repository actions.
4
+
5
+ ## 1. The identifier hierarchy
6
+
7
+ Almost every action keys off the same chain — supply the whole path down to the level you're acting on:
8
+
9
+ - **`ProjectId`** (numeric) + **`Repository`** (the repo *name*, a string) → identify a repository.
10
+ - **`Package`** (name) → a package/image within the repo (e.g. a Docker image name, a Maven artifact).
11
+ - **`PackageVersion`** (name) → one version/tag of that package.
12
+ - **`FileName`** → a specific file inside a version (for download).
13
+
14
+ **Repository `Type`** is a numeric enum: `1` generic · `2` docker · `3` maven · `4` npm · `5` pypi ·
15
+ `6` helm · `7` composer · `8` nuget · `9` conan · `10` cocoapods · `11` rpm.
16
+
17
+ > ⚠️ Identifier exceptions:
18
+ > - **`DescribeArtifactRepositoryFileList`** uses **`Project` (the project *name*)** + `Repository`, and
19
+ > selects artifacts via an **`Artifacts` array** of `{PackageName, VersionName}` objects (passed with
20
+ > `--data`) — not the flat `ProjectId`/`Package`/`PackageVersion` params.
21
+ > - **`DescribeTeamArtifacts`** and the four **credit (授信)** actions take **no project identifier** at
22
+ > all. The `ProjectId` chain applies to the per-repo repository/package/version/property actions.
23
+
24
+ ## 2. Discover repositories & packages
25
+
26
+ ```bash
27
+ # repositories in a project (Type optional — filter to e.g. 2 for docker)
28
+ coding call DescribeArtifactRepositoryList --param ProjectId=341 --param PageSize=50 \
29
+ --select 'Data.InstanceSet[].Id,Data.InstanceSet[].Name,Data.InstanceSet[].Type' --json
30
+
31
+ # packages / images in a repo (PackagePrefix narrows by name)
32
+ coding call DescribeArtifactPackageList --param ProjectId=341 --param Repository=maven-local --param PageSize=50 \
33
+ --select 'Data.InstanceSet[].Name,Data.InstanceSet[].LatestVersionName,Data.InstanceSet[].VersionCount' --json
34
+
35
+ # team-wide artifact search (cross-project); Rule is an optional structured filter
36
+ coding call DescribeTeamArtifacts --param PageSize=50 \
37
+ --select 'Data.InstanceSet[].Package,Data.InstanceSet[].PackageVersion,Data.InstanceSet[].Repository,Data.InstanceSet[].ProjectName' --json
38
+ ```
39
+
40
+ ## 3. Versions, files, downloads, checksums
41
+
42
+ ```bash
43
+ # versions of a package
44
+ coding call DescribeArtifactVersionList --param ProjectId=341 --param Repository=maven-local --param Package=com.demo.app \
45
+ --select 'Data.InstanceSet[].Version,Data.InstanceSet[].ReleaseStatus,Data.InstanceSet[].Size,Data.InstanceSet[].DownloadCount' --json
46
+
47
+ # files inside a version (Maven coordinates go in the optional Maven object).
48
+ # NOTE: this action only supports types 1-generic / 3-maven / 4-npm / 5-pypi — NOT docker.
49
+ coding call DescribeArtifactVersionFileList --param ProjectId=341 --param Repository=maven-local \
50
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --select 'InstanceSet[].Name,InstanceSet[].Size' --json
51
+
52
+ # temporary signed download URL for one file (Timeout = link TTL in seconds)
53
+ coding call DescribeArtifactFileDownloadUrl --param ProjectId=341 --param Repository=maven-local \
54
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --param FileName=api-1.2.0.jar --param Timeout=600 --json
55
+ # → response top-level `Url` (a string). Hand the URL to the user; don't try to fetch it through the CLI.
56
+
57
+ coding call DescribeArtifactChecksums --param ProjectId=341 --param Repository=maven-local \
58
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --json
59
+ ```
60
+
61
+ ## 4. Properties (version metadata)
62
+
63
+ Properties are name/value pairs attached to a specific `PackageVersion`.
64
+
65
+ ```bash
66
+ coding call DescribeArtifactProperties --param ProjectId=341 --param Repository=maven-local \
67
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --select 'InstanceSet[].Name,InstanceSet[].Value' --json
68
+
69
+ # add / modify: PropertySet is an array of {Name,Value} — pass via --data
70
+ coding call CreateArtifactProperties --data '{"ProjectId":341,"Repository":"maven-local","Package":"com.demo.app",
71
+ "PackageVersion":"1.2.0","PropertySet":[{"Name":"qa-status","Value":"passed"}]}' --json
72
+ coding call ModifyArtifactProperties --data '{"ProjectId":341,"Repository":"maven-local","Package":"com.demo.app",
73
+ "PackageVersion":"1.2.0","PropertySet":[{"Name":"qa-status","Value":"failed"}]}' --json
74
+
75
+ # delete: PropertyNameSet is an array of property names (the only exit-10 gated action here — see §6)
76
+ coding call DeleteArtifactProperties --data '{"ProjectId":341,"Repository":"maven-local","Package":"com.demo.app",
77
+ "PackageVersion":"1.2.0","PropertyNameSet":["qa-status"]}' --yes --json
78
+ ```
79
+
80
+ ## 5. Version lifecycle — release & forbid
81
+
82
+ ```bash
83
+ # promote a version to "released"
84
+ coding call ReleaseArtifactVersion --param ProjectId=341 --param Repository=maven-local \
85
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --json
86
+
87
+ # block (or unblock) downloading a version — ForbiddenAction ∈ FORBIDDEN | UNFORBIDDEN
88
+ coding call ForbiddenArtifactVersion --param ProjectId=341 --param Repository=maven-local \
89
+ --param Package=com.demo.app --param PackageVersion=1.2.0 --param ForbiddenAction=FORBIDDEN \
90
+ --param ForbiddenNote="CVE-2026-1234" --json
91
+ ```
92
+
93
+ > `ForbiddenArtifactVersion FORBIDDEN` instantly stops anyone pulling that version — it's classified
94
+ > `write` (not exit-10 gated), but it's consequential. Confirm the package/version with the user first.
95
+
96
+ ## 6. Repositories & trust (授信) lists
97
+
98
+ ```bash
99
+ coding call CreateArtifactRepository --data '{"ProjectId":341,"RepositoryName":"maven-local","Type":3,
100
+ "Description":"app jars","AllowProxy":false}' --json # Type per the §1 enum (3 = maven)
101
+
102
+ # trust lists (授信清单) — rules for which artifacts are trusted/allowed.
103
+ # DescribeArtifactCreditList enumerates (no params); DescribeArtifactCredit is a DETAIL call (needs an Id).
104
+ coding call DescribeArtifactCreditList --select 'InstanceSet[].Id,InstanceSet[].Name' --json
105
+ coding call DescribeArtifactCredit --param ArtifactCreditId=7 --json
106
+ ```
107
+
108
+ Creating/updating a credit takes **structured `Ranges` and `Rules` arrays** (schema types
109
+ `ArtifactsOpenApiCreateArtifactCreditsRangeData[]` / `ArtifactsOpenApiArtifactCreditsRuleData[]`) — too
110
+ nested to hand-roll blind. Required fields: `CreateArtifactCredit` needs `Name`, `Enabled`, `Ranges`,
111
+ `Rules`; **`ModifyArtifactCredit` additionally requires `Id`**. Get the exact shape from
112
+ `coding schema CreateArtifactCredit` and an existing credit (`DescribeArtifactCredit`), then send via
113
+ `--data @credit.json`. Don't copy the field list as literal JSON — fill in concrete `Ranges`/`Rules`.
114
+
115
+ ## 7. Destructive actions (exit-10 gated)
116
+
117
+ Only one action in this category is gated: **`DeleteArtifactProperties`** (removes the named properties
118
+ from a version). Follow SKILL.md's protocol — preview with `--dry-run`, get explicit user approval,
119
+ re-run the **same argv with `--yes`**. Note that **deleting/forbidding versions or repos is not exposed
120
+ here**; `ForbiddenArtifactVersion FORBIDDEN` (§5) is the closest to a "remove", and it's reversible via
121
+ `UNFORBIDDEN`.
122
+
123
+ ## 8. Gotchas
124
+
125
+ - **Supply the full identifier chain.** Most actions need `ProjectId` + `Repository` + `Package` +
126
+ `PackageVersion` together; a missing level is a validation error (exit 11).
127
+ - **`DescribeArtifactRepositoryFileList` is the odd one out** — `Project` (name) + `Repository`, with an
128
+ `Artifacts` array of `{PackageName, VersionName}`, not the flat `ProjectId`/`Package`/`PackageVersion`.
129
+ `DescribeTeamArtifacts` and the credit actions take no project id at all.
130
+ - **`Repository` is the repo name (string), `Type` is the numeric enum** (§1) — don't pass a type string.
131
+ - **List wrappers differ**: the **paged** lists (repository / package / version / team /
132
+ repository-file) nest the array under `Data.InstanceSet[]`; the **non-paged** lists (properties,
133
+ credit, version-file, **checksums**)
134
+ put it at the top level as `InstanceSet[]`. Match your `--select` path accordingly — a wrong wrapper
135
+ selects nothing. When unsure, run `coding schema <Action>` and check whether the response top level is
136
+ `Data` or `InstanceSet`.
137
+ - **`DescribeArtifactFileDownloadUrl` returns a `Url` string** — give it to the user; the CLI won't
138
+ download the bytes for you.
@@ -0,0 +1,103 @@
1
+ # coding-cd
2
+
3
+ A curated playbook for the **持续部署 (11)** category — the 33 CD actions.
4
+
5
+ > Note: this is **CODING CD** (deployment). Builds (CI / 构建计划) are a separate category — see `references/ci.md`.
6
+
7
+ ## 1. Identifiers
8
+
9
+ - **`Application`** — the deployment application **name** (a string); the primary key for most CD ops.
10
+ - **`PipelineName` / `PipelineNameOrId`** — a deploy flow (部署流程) within an application.
11
+ - **`PipelineExecutionId`** — one **execution** of a pipeline; the key to track or cancel a deploy.
12
+ - **`TaskExecutionId`** — one CD task execution (`CreateCdTask` / `DescribeCdTask`).
13
+
14
+ Flow: find the `Application` → pick a pipeline config → trigger → track the `PipelineExecutionId`.
15
+
16
+ ## 2. Find applications & pipelines
17
+
18
+ ```bash
19
+ coding call DescribeCdApplications --select 'Data.Applications[].Name' --json # all CD apps (no params)
20
+ coding call DescribeCdApplicationsByProject --param ProjectName=demo \
21
+ --select 'Data.Applications[].Name' --json # apps bound to a project
22
+ coding call DescribeCdApplication --param Application=payments --json # one app's detail
23
+
24
+ # the deploy flows configured on an application
25
+ coding call DescribeCdPipelineConfigs --param Application=payments \
26
+ --select 'Data.PipelineConfigs[].Id,Data.PipelineConfigs[].Name' --json
27
+ coding call DescribeCdPipelineConfig --param Application=payments --param PipelineName=deploy-prod --json
28
+ ```
29
+
30
+ `DescribeCdPipelineConfig` returns the flow's full **config** JSON at `Data.PipelineConfig.JsonContent`.
31
+ That is the *pipeline definition*, **not** the trigger payload — don't feed it back into `TriggerJsonContent` (§3).
32
+
33
+ ## 3. Trigger a deploy & track it
34
+
35
+ ```bash
36
+ # TriggerJsonContent is a JSON *string* of trigger PARAMETERS (artifact/version/build params) — distinct
37
+ # from the pipeline config JSON. Get its shape from the UI's "trigger" dialog; an empty object runs defaults.
38
+ coding call TriggerCdPipeline --data '{"Application":"payments","PipelineNameOrId":"deploy-prod",
39
+ "TriggerJsonContent":"{\"version\":\"1.2.0\"}"}' --json
40
+ # response → Data.PipelineExecutionId (track / cancel with this)
41
+
42
+ coding call DescribeCdPipeline --param PipelineExecutionId=<id> \
43
+ --select 'Data.PipelineName,Data.PipelineExecutionStatus,Data.Application' --json # poll status
44
+ coding call DescribeCdTask --param TaskExecutionId=<id> --json # a single task's record
45
+ ```
46
+
47
+ `CreateCdTask` (param `TaskJsonContent`, a JSON string) and `CreateCdPipeline` (`PipelineJsonContent`)
48
+ take opaque JSON blobs — only use them when you already have the exact config shape.
49
+
50
+ ## 4. Infrastructure (host groups, cloud accounts)
51
+
52
+ ```bash
53
+ coding call DescribeCdHostServerGroups --param PageSize=50 --json # 主机组 list
54
+ coding call DescribeCdHostServerGroup --param Id=12 --json # one group (keyed by Id)
55
+ coding call DescribeHostServerInstance --param Account=prod --param ServerGroupName=web --json # per-host deploy detail
56
+ coding call DescribeCdCloudAccounts --param PageSize=50 --json # 云账号
57
+ coding call DescribeAgentSecret --json # 堡垒机安装 secret (sensitive — don't echo)
58
+ ```
59
+
60
+ Create/modify counterparts: `CreateCdHostServerGroup`/`ModifyCdHostServerGroup`,
61
+ `CreateCdCloudAccount`/`ModifyCdCloudAccount`, `BindCdApplicationToProject`.
62
+
63
+ ## 5. Deploy metrics
64
+
65
+ ```bash
66
+ # by project or by application — frequency / duration / trend. StartAt + EndAt are REQUIRED and must be
67
+ # full timestamps "yyyy-MM-dd HH:mm:ss" (date-only is rejected).
68
+ coding call DescribeCdDeployCountByProject --param ProjectName=demo \
69
+ --param "StartAt=2026-05-01 00:00:00" --param "EndAt=2026-05-21 23:59:59" --json
70
+ # by-application variants: the key is Application (singular name) but its value is an ARRAY of names,
71
+ # so pass it via --data, not --param:
72
+ coding call DescribeCdDeployCountByApplications --data '{"Application":["payments"],
73
+ "StartAt":"2026-05-01 00:00:00","EndAt":"2026-05-21 23:59:59"}' --json
74
+ # also: DescribeCdDeployTimeBy* (duration) and DescribeCdDeployTrendBy* (trend over time)
75
+ ```
76
+
77
+ ## 6. Destructive actions (exit-10 gated)
78
+
79
+ - **`CancelCdPipeline`** (`PipelineExecutionId`, optional `Reason`) — aborts a *running* deploy.
80
+ - **`DeleteCdPipeline`** — deletes a deploy-flow config.
81
+ - **`DeleteCdHostServerGroup`** — deletes a host group.
82
+ - **`DeleteCdCloudAccount`** — deletes a cloud account.
83
+
84
+ Follow SKILL.md's protocol: `--dry-run` to preview, explicit user approval, re-run the **same argv
85
+ with `--yes`**. **Cancelling a deploy mid-run can leave an environment half-deployed** — always confirm
86
+ the execution id and target with the user first.
87
+
88
+ ```bash
89
+ coding call CancelCdPipeline --param PipelineExecutionId=<id> --param Reason="bad build" --dry-run --json
90
+ coding call CancelCdPipeline --param PipelineExecutionId=<id> --param Reason="bad build" --yes --json
91
+ ```
92
+
93
+ ## 7. Gotchas
94
+
95
+ - **`Application` is a name (string), not an id** — it keys most CD reads/writes.
96
+ - **Trigger/task/pipeline JSON is passed as a string field** (`TriggerJsonContent`/`TaskJsonContent`/
97
+ `PipelineJsonContent`), i.e. **JSON-inside-JSON** — escape it inside `--data`. Note `TriggerJsonContent`
98
+ is *trigger params* (version/artifact), **not** the pipeline-config JSON from `DescribeCdPipelineConfig`
99
+ — conflating the two is the #1 mistake.
100
+ - **Track deploys by `PipelineExecutionId`** (returned by `TriggerCdPipeline`), not by application name.
101
+ - **Triggering a deploy is consequential even though it's not exit-10 gated** (`TriggerCdPipeline` is
102
+ `write`) — confirm the application, pipeline, and target/version with the user before triggering prod.
103
+ - **`DescribeAgentSecret` returns a secret** — never echo it.
@@ -0,0 +1,99 @@
1
+ # coding-ci
2
+
3
+ A curated playbook for the **持续集成 (10)** category — the 24 CI actions.
4
+
5
+ > Note: this is **CODING CI** (Jenkins-based 构建计划). Deployment (CD) is a separate category — see
6
+ > `references/cd.md`.
7
+
8
+ ## 1. Two identifiers
9
+
10
+ - **`JobId`** — a **build plan** (构建计划): the reusable pipeline definition attached to a repo.
11
+ - **`BuildId`** — a single **build run** of a plan. Most inspection actions key off `BuildId`.
12
+
13
+ Flow: find the `JobId` → trigger or list its builds → drill into a `BuildId` for status/logs/artifacts.
14
+
15
+ ## 2. Find build plans (Jobs)
16
+
17
+ ```bash
18
+ coding call DescribeCodingCIJobs --param ProjectId=341 \
19
+ --select 'JobList[].Id,JobList[].Name,JobList[].DepotName,JobList[].BranchSelector' --json
20
+ coding call DescribeCodingCIJob --param JobId=88 --json # one plan's full config
21
+ ```
22
+
23
+ ## 3. Trigger a build
24
+
25
+ ```bash
26
+ # minimal: run the plan's default branch
27
+ coding call TriggerCodingCIBuild --param JobId=88 --json
28
+ # pin a revision (branch or commit sha) and pass build env vars
29
+ coding call TriggerCodingCIBuild --data '{"JobId":88,"Revision":"feature/login",
30
+ "ParamList":[{"Key":"ENV","Value":"staging"}]}' --json
31
+ ```
32
+
33
+ `Reentrant` controls re-trigger behavior; `Revision` defaults to the plan's branch selector. The
34
+ response carries the new build under `Data.Build` (note its `Id` → that's the `BuildId` to track).
35
+
36
+ ## 4. Inspect build runs
37
+
38
+ ```bash
39
+ # builds of a plan (paged), newest first
40
+ coding call DescribeCodingCIBuilds --param JobId=88 --param PageNumber=1 --param PageSize=20 \
41
+ --select 'Data.BuildList[].Id,Data.BuildList[].Number,Data.BuildList[].Status,Data.BuildList[].Branch,Data.BuildList[].Duration' --json
42
+
43
+ coding call DescribeCodingCIBuild --param BuildId=9001 --json # one run's detail (Status, Cause, TestResult…)
44
+ coding call DescribeCodingCIBuildStage --param BuildId=9001 --json # stages (each has a StageId)
45
+ coding call DescribeCodingCIBuildStep --param BuildId=9001 --param StageId=3 --json # steps in a stage
46
+ ```
47
+
48
+ `Status` tells you success/failure/running; on failure read `FailedMessage` and the logs (§5).
49
+
50
+ ## 5. Logs, artifacts & reports
51
+
52
+ ```bash
53
+ # logs are paginated by line offset — Start=0 first, then advance by what you got
54
+ coding call DescribeCodingCIBuildLog --param BuildId=9001 --param Start=0 --json
55
+ coding call DescribeCodingCIBuildLogRaw --param BuildId=9001 --param Start=0 --json # plain raw log
56
+ coding call DescribeCodingCIBuildStepLog --param BuildId=9001 --param StageId=3 --param StepId=1 --param Start=0 --json # per-step
57
+
58
+ coding call DescribeCodingCIBuildArtifacts --param BuildId=9001 --json
59
+ coding call DescribeCodingCIBuildHtmlReports --param BuildId=9001 --json
60
+ ```
61
+
62
+ For triage of a failed build: `DescribeCodingCIBuild` (get Status/FailedMessage) → `DescribeCodingCIBuildStage`
63
+ to find the failing stage → its `DescribeCodingCIBuildStep` → step log. Don't dump full logs into context —
64
+ page with `Start` and grep for the error.
65
+
66
+ ## 6. Manage plans (write)
67
+
68
+ ```bash
69
+ coding call ModifyCodingCIJob --data '{...}' --json # edit an existing plan (read DescribeCodingCIJob first for shape)
70
+ coding call CreateCodingCIJob --data '{...}' --json # create — many required fields; prefer the UI or a team template
71
+ coding call CreateCodingCIJobByTeamTemplate --data '{...}' --json
72
+ coding call ModifyCodingCIAgentEnable --data '{...}' --json # enable/disable a self-hosted build node
73
+ ```
74
+
75
+ `CreateCodingCIJob` has ~10 required fields (`DepotId`, `DepotType`, `ExecuteIn`, `HookType`,
76
+ `JenkinsFileFromType`, `JobFromType`, `Name`, `ProjectId`, two `AutoCancelSame*` bools). Inspect
77
+ `coding schema CreateCodingCIJob` and copy an existing plan's config rather than hand-rolling it.
78
+
79
+ ## 7. Destructive actions (exit-10 gated)
80
+
81
+ - **`StopCodingCIBuild`** (`BuildId`) — aborts a *running* build.
82
+ - **`DeleteCodingCIBuild`** (`BuildId`) — deletes a build record.
83
+ - **`DeleteCodingCIJob`** (`JobId`) — deletes the whole build plan.
84
+ - **`ClearCodingCIJobCache`** — clears a plan's cache; **its param is `Id` (= the JobId)**, not `JobId`.
85
+
86
+ Follow SKILL.md's protocol: `--dry-run` to preview, get explicit user approval, re-run the **same
87
+ argv with `--yes`**. Stopping a build mid-run can leave a deploy half-done — confirm with the user.
88
+
89
+ ```bash
90
+ coding call StopCodingCIBuild --param BuildId=9001 --dry-run --json # show user
91
+ coding call StopCodingCIBuild --param BuildId=9001 --yes --json # after approval
92
+ ```
93
+
94
+ ## 8. Gotchas
95
+
96
+ - **`JobId` (plan) vs `BuildId` (run)** — triggering/listing-plans use `JobId`; everything about a
97
+ specific run uses `BuildId`. The trigger response gives you the new `BuildId` under `Data.Build.Id`.
98
+ - **`ClearCodingCIJobCache` uses `Id`, not `JobId`** — easy to miss.
99
+ - **Logs paginate by `Start`** (a line offset, required) — fetch incrementally, don't expect the whole log.