@numa-tech/numa 1.12.8 → 1.12.11
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/README.md +140 -16
- package/dist/ai-registry/commands.js +33 -33
- package/dist/ai-registry/commands.js.map +1 -1
- package/dist/app-config.d.ts +0 -1
- package/dist/app-config.js +4 -2
- package/dist/app-config.js.map +1 -1
- package/dist/application-candidates/client.d.ts +167 -0
- package/dist/application-candidates/client.js +103 -0
- package/dist/application-candidates/client.js.map +1 -0
- package/dist/application-candidates/commands.d.ts +13 -0
- package/dist/application-candidates/commands.js +225 -0
- package/dist/application-candidates/commands.js.map +1 -0
- package/dist/application-candidates/schemas.d.ts +171 -0
- package/dist/application-candidates/schemas.js +80 -0
- package/dist/application-candidates/schemas.js.map +1 -0
- package/dist/application-onboarding/client.d.ts +256 -0
- package/dist/application-onboarding/client.js +213 -0
- package/dist/application-onboarding/client.js.map +1 -0
- package/dist/application-onboarding/commands.d.ts +64 -0
- package/dist/application-onboarding/commands.js +694 -0
- package/dist/application-onboarding/commands.js.map +1 -0
- package/dist/application-onboarding/errors.d.ts +11 -0
- package/dist/application-onboarding/errors.js +51 -0
- package/dist/application-onboarding/errors.js.map +1 -0
- package/dist/application-onboarding/schemas.d.ts +1167 -0
- package/dist/application-onboarding/schemas.js +459 -0
- package/dist/application-onboarding/schemas.js.map +1 -0
- package/dist/application-onboarding/scm-credentials.d.ts +8 -0
- package/dist/application-onboarding/scm-credentials.js +98 -0
- package/dist/application-onboarding/scm-credentials.js.map +1 -0
- package/dist/application-onboarding/tui-model.d.ts +131 -0
- package/dist/application-onboarding/tui-model.js +554 -0
- package/dist/application-onboarding/tui-model.js.map +1 -0
- package/dist/application-onboarding/tui.d.ts +14 -0
- package/dist/application-onboarding/tui.js +554 -0
- package/dist/application-onboarding/tui.js.map +1 -0
- package/dist/authorization/access-request-client.d.ts +45 -0
- package/dist/authorization/access-request-client.js +93 -0
- package/dist/authorization/access-request-client.js.map +1 -0
- package/dist/authorization/access-request-commands.d.ts +25 -0
- package/dist/authorization/access-request-commands.js +196 -0
- package/dist/authorization/access-request-commands.js.map +1 -0
- package/dist/authorization/access-request-schemas.d.ts +123 -0
- package/dist/authorization/access-request-schemas.js +67 -0
- package/dist/authorization/access-request-schemas.js.map +1 -0
- package/dist/authorization/client.d.ts +50 -0
- package/dist/authorization/client.js +113 -0
- package/dist/authorization/client.js.map +1 -0
- package/dist/authorization/commands.d.ts +40 -0
- package/dist/authorization/commands.js +296 -0
- package/dist/authorization/commands.js.map +1 -0
- package/dist/authorization/errors.d.ts +13 -0
- package/dist/authorization/errors.js +70 -0
- package/dist/authorization/errors.js.map +1 -0
- package/dist/authorization/schemas.d.ts +187 -0
- package/dist/authorization/schemas.js +101 -0
- package/dist/authorization/schemas.js.map +1 -0
- package/dist/cli.js +44 -8
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.js +270 -26
- package/dist/command-catalog.js.map +1 -1
- package/dist/web-console-page.d.ts +1 -1
- package/dist/web-console-page.js +1 -1
- package/dist/web-console.js +6 -5
- package/dist/web-console.js.map +1 -1
- package/examples/ai-registry/README.md +18 -0
- package/examples/ai-registry/nacos-instance.username-password.example.json +25 -0
- package/package.json +4 -4
- package/skills/numa-ai-registry/SKILL.md +5 -5
- package/skills/numa-ai-registry/evals/evals.json +1 -1
- package/skills/numa-ai-registry/references/command-contract.md +22 -22
- package/skills/numa-cli/SKILL.md +44 -0
- package/skills/numa-cli/agents/openai.yaml +4 -0
- package/skills/numa-cli/evals/evals.json +35 -0
- package/skills/numa-cli/references/pipeline-release.md +107 -0
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- 包含 Realm 角色、Client 角色和用户组的个人信息页;
|
|
11
11
|
- 使用服务端托管的 Codex 账号启动官方 Codex CLI,客户端不保存 refresh token;
|
|
12
12
|
- 通过平台授权代理发现、治理并安装私有 Nacos Skills 与 MCP Servers;
|
|
13
|
+
- 通过可恢复的 `app` 会话和统一 Web/API 契约创建新应用或录入存量仓库;
|
|
13
14
|
- 通过领域化 `media` 命令安全调用平台托管的 TTS、视频、资产和素材库服务;
|
|
14
15
|
- 兼容原有 stdio MCP 服务。
|
|
15
16
|
|
|
@@ -34,10 +35,10 @@ npm config set @numa-tech:registry=https://registry.npmjs.org/
|
|
|
34
35
|
```
|
|
35
36
|
|
|
36
37
|
脚本会先检查 Git 工作区干净、当前分支与 upstream 完全同步,再于修改版本号之前检查公共
|
|
37
|
-
npm 身份以及 `@tokensrc`、`@numa-tech` scope
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
npm 身份以及 `@tokensrc`、`@numa-tech` scope 权限。发布认证默认完全交给 npm 处理;
|
|
39
|
+
需要时 npm 会启动自己的浏览器认证或 2FA 流程,脚本不会额外询问 OTP。也可以临时通过
|
|
40
|
+
`NUMA_PUBLIC_NPM_OTP` 显式提供 6 位 OTP;自动化发布更推荐使用带 bypass 2FA 权限的
|
|
41
|
+
granular token 或 npm trusted publishing。
|
|
41
42
|
|
|
42
43
|
首次从本机发布公共包,或公共登录已经过期时,先运行:
|
|
43
44
|
|
|
@@ -188,10 +189,13 @@ numa config \
|
|
|
188
189
|
| `numa registry instances list/create/update/delete` | 需登录 | 管理数据库中的 Nacos 实例和 OIDC 配置;写操作需要 Registry admin |
|
|
189
190
|
| `numa registry namespaces list/resolve/check/create/update/delete` | 需登录 | 管理多实例 namespace 路由与跨集群默认项;写操作需要 Registry admin |
|
|
190
191
|
| `numa registry capabilities/init/lock/sync/upgrade` | 需登录 | 读取授权边界并以可提交的 manifest/lock 确定性安装 |
|
|
191
|
-
| `numa
|
|
192
|
-
| `numa
|
|
192
|
+
| `numa skills list/inspect/install/upload/...` | 需登录 | 发现、安装和治理 Nacos Skills;服务端按团队、角色和生命周期授权 |
|
|
193
|
+
| `numa mcp list/inspect/install/bridge/...` | 需登录 | 通过企业 Router 安装/桥接 MCP,并维护版本、标签和工具状态 |
|
|
193
194
|
| `numa registry approvals/router/audit` | 需登录 | 两人制发布、Router 健康/对账和追加式审计 |
|
|
194
195
|
| `numa registry tui` | 需登录 | 打开 namespace、Skills、MCP、审批、Router、审计全屏工作台 |
|
|
196
|
+
| `numa app onboard/apply/resume/inspect/list/tui` | 需登录 | 创建新应用、录入存量应用并恢复服务端入驻会话 |
|
|
197
|
+
| `numa app options` | 需登录 | 查询应用归属所需的团队、系统、业务域和环境 ID |
|
|
198
|
+
| `numa app candidate list/inspect/preview/review/adopt` | 需登录 | 审查应用发现候选并确认收录,服务端执行最终管理员授权和审计 |
|
|
195
199
|
| `numa media capabilities` | 需登录 | 查询媒体 API、Provider 和版本能力 |
|
|
196
200
|
| `numa media tts submit` | 需登录 | 提交 TTS 异步任务 |
|
|
197
201
|
| `numa media video submit` | 需登录 | 提交视频生成异步任务 |
|
|
@@ -320,7 +324,8 @@ SSRF 安全策略仍由 `AI_REGISTRY_ALLOWED_UPSTREAM_HOSTS`、
|
|
|
320
324
|
`AI_REGISTRY_ALLOWED_TOKEN_HOSTS` 控制,allow-list 为空时 fail closed;HTTP 只可通过
|
|
321
325
|
`AI_REGISTRY_ALLOW_HTTP=true` 用于开发环境。
|
|
322
326
|
|
|
323
|
-
Nacos 实例文件示例(凭据字段仅写入,实际字段以平台 capability/API revision
|
|
327
|
+
Nacos 实例文件示例(凭据字段仅写入,实际字段以平台 capability/API revision 为准)。完整的
|
|
328
|
+
用户名密码认证模板见 `examples/ai-registry/nacos-instance.username-password.example.json`:
|
|
324
329
|
|
|
325
330
|
```json
|
|
326
331
|
{
|
|
@@ -387,18 +392,18 @@ numa registry lock --json
|
|
|
387
392
|
numa registry sync --json
|
|
388
393
|
numa registry upgrade release-helper --json
|
|
389
394
|
|
|
390
|
-
numa
|
|
391
|
-
numa
|
|
392
|
-
numa
|
|
395
|
+
numa skills list --namespace team-ai --search deploy --json
|
|
396
|
+
numa skills inspect release-helper --namespace team-ai --json
|
|
397
|
+
numa skills install release-helper \
|
|
393
398
|
--namespace team-ai --agent cursor --scope project --label latest --json
|
|
394
399
|
|
|
395
|
-
numa
|
|
396
|
-
numa
|
|
397
|
-
numa
|
|
400
|
+
numa mcp list --namespace team-ai --json
|
|
401
|
+
numa mcp inspect internal-docs --namespace team-ai --json
|
|
402
|
+
numa mcp install internal-docs \
|
|
398
403
|
--namespace team-ai --instance cluster-b --agent claude --scope project --transport remote --json
|
|
399
404
|
|
|
400
405
|
# 仅供 stdio Agent;复用 Numa 登录/刷新连接 Router
|
|
401
|
-
numa
|
|
406
|
+
numa mcp bridge --namespace team-ai
|
|
402
407
|
|
|
403
408
|
# 也可使用终端交互界面
|
|
404
409
|
numa registry tui
|
|
@@ -407,7 +412,7 @@ numa registry tui
|
|
|
407
412
|
两人制发布生命周期:
|
|
408
413
|
|
|
409
414
|
```bash
|
|
410
|
-
numa
|
|
415
|
+
numa skills upload ./release-helper.zip \
|
|
411
416
|
--namespace team-ai --target-version 1.0.0 --json
|
|
412
417
|
numa registry approvals submit skill release-helper \
|
|
413
418
|
--namespace team-ai --resource-version 1.0.0 --reason "scanner passed" --json
|
|
@@ -442,7 +447,7 @@ capability 发布且健康的企业 Router,不安装 Nacos 中的下游 endpoi
|
|
|
442
447
|
| OpenClaw | `.openclaw/skills` | 调用官方 `openclaw mcp set`,仅 user scope |
|
|
443
448
|
|
|
444
449
|
ChatGPT 不能启动本地 stdio bridge;它直接连接企业 Router 的远程 HTTPS OAuth resource。
|
|
445
|
-
其他只支持 stdio 的 Agent 可运行 `numa
|
|
450
|
+
其他只支持 stdio 的 Agent 可运行 `numa mcp bridge`,由 Numa 获取/刷新用户 Token
|
|
446
451
|
并只发送给 Router,不向 Nacos 或下游 MCP 透传。ChatGPT workspace 仍需管理员按计划和
|
|
447
452
|
RBAC 开启 Developer mode。
|
|
448
453
|
|
|
@@ -451,6 +456,125 @@ RBAC 开启 Developer mode。
|
|
|
451
456
|
Nacos token、绕过 403 或未经确认覆盖本地配置。对应场景评测在
|
|
452
457
|
`skills/numa-ai-registry/evals/evals.json`。
|
|
453
458
|
|
|
459
|
+
## 应用创建与存量录入
|
|
460
|
+
|
|
461
|
+
`numa app` 使用 platform profile 的 `platform` service 和现有 `mcp-client` Keycloak 会话调用
|
|
462
|
+
`/api/v1/application-onboarding`。Web、CLI 和 TUI 共享服务端 `sessionNo`、乐观锁 `revision`、
|
|
463
|
+
`planHash` 和单调递增的 event sequence;CLI 只展示服务端状态,不会在本地推断任务已完成。
|
|
464
|
+
|
|
465
|
+
交互终端直接运行 `numa app onboard` 会打开 Ink TUI,并可在同一服务端草稿中完成
|
|
466
|
+
`MODE → BASIC_INFORMATION → OWNERSHIP → SOURCE_CONTROL → TECHNOLOGY → STANDARDIZATION → DELIVERY → REVIEW → EXECUTION`
|
|
467
|
+
九步。`[` / `]` 切换步骤(切换时保存 `revision` 与稳定 `currentStep`),方向键选择字段和目录项,
|
|
468
|
+
`Enter` / `e` 编辑,`s` 保存;`REVIEW` 中先按 `p` 查看阻断、警告与 `planHash`,再按 `a`、`y`
|
|
469
|
+
二次确认执行。目录接口不可用时仍可手工输入实体 ID;仓库 Provider 返回 501 时会明确提示手工输入
|
|
470
|
+
稳定 `externalId` 与 `expectedHead`,不会把 URL 或凭据写入草稿。
|
|
471
|
+
|
|
472
|
+
非交互、CI 和 AI 调用必须提供 `--spec`。spec 使用 `schemaVersion: 1`,不得包含 Token、密码、
|
|
473
|
+
SCM credential 或 secret ref:
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
# 只保存草稿并预检,不产生仓库、分支或 Jenkins 等外部副作用
|
|
477
|
+
numa app onboard --spec onboarding.json --plan --json
|
|
478
|
+
|
|
479
|
+
# 接续 Web/TUI 中已保存的同一草稿;使用服务端最新 revision,避免静默覆盖
|
|
480
|
+
numa app onboard --session <session-no> --spec onboarding.json --plan --json
|
|
481
|
+
|
|
482
|
+
# 一步式使用服务端最新 planHash 提交异步执行;幂等键为必填
|
|
483
|
+
numa app onboard \
|
|
484
|
+
--spec onboarding.json \
|
|
485
|
+
--apply \
|
|
486
|
+
--idempotency-key app-order-20260819 \
|
|
487
|
+
--json
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
自动化更推荐先运行 `--plan`、保存返回的 `session_no`,再明确提交该会话。这样即使网络在
|
|
491
|
+
apply 返回前中断,也可以对同一会话复用原幂等键,而不会重新创建草稿:
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
numa app apply <session-no> --idempotency-key app-order-20260819 --json
|
|
495
|
+
numa app inspect <session-no> --watch --after-sequence 42
|
|
496
|
+
numa app resume <session-no> --json
|
|
497
|
+
numa app tui --session <session-no>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
`inspect --watch` 每次都从最后已确认的 sequence 补拉,断线重连不会重复展示事件;Ctrl+C
|
|
501
|
+
只停止本地观察,不取消服务端任务。取消必须显式执行 `numa app cancel <session-no> --yes`,
|
|
502
|
+
且不会回滚已经完成的外部副作用。完整 spec schema、状态机和入驻流程由 DevOps 平台的
|
|
503
|
+
Application Onboarding 契约定义。
|
|
504
|
+
|
|
505
|
+
SCM 目录和连接诊断使用同一身份。仓库查询支持服务端 search/cursor 分页,返回稳定的
|
|
506
|
+
`externalId`、`defaultBranch`、`headRevision`;向导选中仓库后会把 `headRevision` 固定为
|
|
507
|
+
`expectedHead`。HTTP 429 会保留服务端 `Retry-After` 诊断,Provider 未安装(501)时 TUI
|
|
508
|
+
明确退回手工填写稳定标识:
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
numa app scm list --provider codeup --json
|
|
512
|
+
numa app scm inspect codeup-main --repositories --search order --limit 50 --json
|
|
513
|
+
numa app scm inspect codeup-main --repositories --cursor '<next-cursor>' --limit 50 --json
|
|
514
|
+
numa app scm probe codeup-main --json
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
SCM 管理接口位于 `/api/v1/admin/scm-connections`,最终权限始终由网关和后端按 canonical
|
|
518
|
+
Client Role 校验。metadata JSON 只允许 provider、URL、组织、auth type 以及服务端托管的
|
|
519
|
+
`aliyunAccountId`/`aliyunAssumeRoleId` 引用;Numa 不接收云 AK。CODEUP 必须引用
|
|
520
|
+
`aliyunAccountId`,没有 access token 时直接使用服务端 Aliyun identity,不写入空 credential。
|
|
521
|
+
GitHub App/PAT 或可选 Codeup access token 只能从 owner-only 文件或重定向 stdin 读取,禁止放在
|
|
522
|
+
argv、环境变量和 metadata JSON 中,且不会出现在输出或错误中:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
numa app scm create --input codeup.json --json
|
|
526
|
+
chmod 600 github-app.private.json
|
|
527
|
+
numa app scm create --input github.json --credential-file github-app.private.json --json
|
|
528
|
+
numa app scm rotate github-main --revision 4 --credential-stdin --yes --json < github-pat.private.json
|
|
529
|
+
numa app scm disable old-codeup --revision 7 --yes --json
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
## 应用候选收录
|
|
533
|
+
|
|
534
|
+
Jenkins 发现任务只生成可审查的应用候选,不会直接创建正式应用。Numa 对外把后续动作称为
|
|
535
|
+
“候选收录”(`adopt`):候选可能创建新应用,也可能合并到已有应用,同时确认候选携带的
|
|
536
|
+
Jenkins Job 绑定。“转正”容易与 npm 发布晋级、环境晋级或人员状态混淆,因此不作为 CLI
|
|
537
|
+
命令和用户提示;服务端继续使用既有 `/promote` API 与审计事件,保持兼容。
|
|
538
|
+
|
|
539
|
+
先查询候选和所需目录 ID:
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
numa app options team --search platform --json
|
|
543
|
+
numa app options system --json
|
|
544
|
+
numa profile --json
|
|
545
|
+
|
|
546
|
+
numa app candidate list --status new --json
|
|
547
|
+
numa app candidate inspect 123 --json
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
`candidate list` 仅返回 `APPLICATION` 类型候选;列表中的 `id` 是后续操作使用的稳定候选 ID,
|
|
551
|
+
不等同于 Jenkins Job ID 或 Build Number。Job ID、环境层及绑定证据来自候选的
|
|
552
|
+
`proposed_relationships`,CLI 不要求用户重复填写。
|
|
553
|
+
|
|
554
|
+
收录必须先通过服务端预检,并在写入时显式确认:
|
|
555
|
+
|
|
556
|
+
```bash
|
|
557
|
+
numa app candidate preview 123 --json
|
|
558
|
+
numa app candidate adopt 123 --yes --json
|
|
559
|
+
|
|
560
|
+
# 最多批量处理 200 个候选;任一预检阻断时不会提交本批收录
|
|
561
|
+
numa app candidate adopt 123 124 --yes --json
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
如果候选缺少名称、环境证据不明确,或需要合并到已有应用,先 `inspect` 获取完整候选与
|
|
565
|
+
`version`,再用完整 review JSON 和乐观锁版本提交修复:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
numa app candidate review 123 \
|
|
569
|
+
--input candidate-review.json \
|
|
570
|
+
--revision 4 \
|
|
571
|
+
--json
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
review JSON 必须包含 `operation`、`proposedFields`、`proposedRelationships` 和 `confidence`,
|
|
575
|
+
且禁止嵌入凭据或 secret 引用。最终 Scope、候选状态、Job 时效性、CREATE/MERGE 冲突、逐候选
|
|
576
|
+
事务和审计记录均由网关及 DevOps 后端校验,CLI 本地隐藏或显示命令不构成授权。
|
|
577
|
+
|
|
454
578
|
## Jenkins 流水线与生产操作
|
|
455
579
|
|
|
456
580
|
`numa pipeline` 通过平台授权代理查询和操作 Jenkins。CLI 不接收 Jenkins 用户名、Token 或
|
|
@@ -216,8 +216,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
216
216
|
await new AiRegistryClient(loadConfig("aiRegistry")).deleteNamespace(namespaceId);
|
|
217
217
|
await output(command, { ok: true, deleted: { id: namespaceId } }, `namespace 已删除: ${namespaceId}`);
|
|
218
218
|
}), ["numa registry namespaces delete 7 --yes --json"]);
|
|
219
|
-
const
|
|
220
|
-
addExamples(
|
|
219
|
+
const skills = program.command("skills").description("查看、上传、治理和安装 Nacos Skills");
|
|
220
|
+
addExamples(skills.command("list")
|
|
221
221
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
222
222
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
223
223
|
.option("-q, --search <text>", "搜索关键词")
|
|
@@ -233,8 +233,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
233
233
|
});
|
|
234
234
|
const items = pageItems(result);
|
|
235
235
|
await output(command, { ok: true, namespace: targetNamespace, skills: result }, items.map((item, index) => itemName(item, `skill-${index + 1}`)).join("\n") || "没有找到 Skill");
|
|
236
|
-
}), ["numa
|
|
237
|
-
addExamples(
|
|
236
|
+
}), ["numa skills list --namespace team-ai --search deploy --json"]);
|
|
237
|
+
addExamples(skills.command("inspect <name>")
|
|
238
238
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
239
239
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
240
240
|
.action(async (name, options, command) => {
|
|
@@ -242,8 +242,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
242
242
|
const targetNamespace = await resolveNamespace(client, options);
|
|
243
243
|
const result = await client.getSkill(targetNamespace.id, name);
|
|
244
244
|
await output(command, { ok: true, namespace: targetNamespace, skill: result }, JSON.stringify(sanitizeRegistryOutput(result), null, 2));
|
|
245
|
-
}), ["numa
|
|
246
|
-
addExamples(
|
|
245
|
+
}), ["numa skills inspect release-helper --namespace team-ai --json"]);
|
|
246
|
+
addExamples(skills.command("install <name>")
|
|
247
247
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
248
248
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
249
249
|
.requiredOption("-a, --agent <agent>", "chatgpt|codex|claude|cursor|workbuddy|openclaw|agents|custom")
|
|
@@ -270,10 +270,10 @@ export function registerAiRegistryCommands(program) {
|
|
|
270
270
|
}, version, download.sha256, result.installedPath);
|
|
271
271
|
await output(command, { ok: true, namespace: context.namespace, resolvedVersion: version, download: { sha256: download.sha256, fileName: download.fileName }, installation: result, lock }, `已安装 ${name}@${version}: ${result.installedPath}${result.backupPath ? `\n原版本备份: ${result.backupPath}` : ""}`);
|
|
272
272
|
}), [
|
|
273
|
-
"numa
|
|
274
|
-
"numa
|
|
273
|
+
"numa skills install release-helper --namespace team-ai --agent claude",
|
|
274
|
+
"numa skills install release-helper --namespace team-ai --instance cluster-b --agent cursor --scope user --label latest --json"
|
|
275
275
|
]);
|
|
276
|
-
addExamples(
|
|
276
|
+
addExamples(skills.command("draft <name>")
|
|
277
277
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
278
278
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
279
279
|
.option("--from-version <semver>", "从在线版本创建草稿")
|
|
@@ -282,8 +282,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
282
282
|
const targetNamespace = await resolveNamespace(client, options);
|
|
283
283
|
const result = await client.createSkillDraft(targetNamespace.id, name, { baseVersion: options.fromVersion });
|
|
284
284
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name} 草稿已创建`);
|
|
285
|
-
}), ["numa
|
|
286
|
-
addExamples(
|
|
285
|
+
}), ["numa skills draft release-helper --from-version 1.0.0 --json"]);
|
|
286
|
+
addExamples(skills.command("upload <zip>")
|
|
287
287
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
288
288
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
289
289
|
.option("--overwrite", "覆盖现有 draft")
|
|
@@ -294,9 +294,9 @@ export function registerAiRegistryCommands(program) {
|
|
|
294
294
|
const targetNamespace = await resolveNamespace(client, options);
|
|
295
295
|
const result = await client.uploadSkill(targetNamespace.id, zip, options);
|
|
296
296
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ZIP 已上传到 ${targetNamespace.displayName}`);
|
|
297
|
-
}), ["numa
|
|
297
|
+
}), ["numa skills upload ./release-helper.zip --namespace team-ai --target-version 1.0.0 --json"]);
|
|
298
298
|
for (const action of ["submit", "publish", "online", "offline"]) {
|
|
299
|
-
addExamples(
|
|
299
|
+
addExamples(skills.command(`${action} <name>`)
|
|
300
300
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
301
301
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
302
302
|
.option("--version <semver>", "版本(publish 必填)")
|
|
@@ -307,9 +307,9 @@ export function registerAiRegistryCommands(program) {
|
|
|
307
307
|
const targetNamespace = await resolveNamespace(client, options);
|
|
308
308
|
const result = await client.skillAction(targetNamespace.id, name, action, { version: options.version });
|
|
309
309
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name}: ${action} 完成`);
|
|
310
|
-
}), [`numa
|
|
310
|
+
}), [`numa skills ${action} release-helper --namespace team-ai${action === "publish" ? " --version 1.0.0" : ""}`]);
|
|
311
311
|
}
|
|
312
|
-
addExamples(
|
|
312
|
+
addExamples(skills.command("scope <name> <scope>")
|
|
313
313
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
314
314
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
315
315
|
.action(async (name, scope, options, command) => {
|
|
@@ -320,8 +320,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
320
320
|
const targetNamespace = await resolveNamespace(client, options);
|
|
321
321
|
const result = await client.skillAction(targetNamespace.id, name, "scope", { scope: normalized });
|
|
322
322
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name} scope 已更新为 ${normalized}`);
|
|
323
|
-
}), ["numa
|
|
324
|
-
addExamples(
|
|
323
|
+
}), ["numa skills scope release-helper PRIVATE --namespace team-ai"]);
|
|
324
|
+
addExamples(skills.command("tags <name> <tags...>")
|
|
325
325
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
326
326
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
327
327
|
.action(async (name, tags, options, command) => {
|
|
@@ -333,8 +333,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
333
333
|
const targetNamespace = await resolveNamespace(client, options);
|
|
334
334
|
const result = await client.skillAction(targetNamespace.id, name, "biz-tags", { bizTags: normalized });
|
|
335
335
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name} tags 已更新`);
|
|
336
|
-
}), ["numa
|
|
337
|
-
addExamples(
|
|
336
|
+
}), ["numa skills tags release-helper deploy java --namespace team-ai --json"]);
|
|
337
|
+
addExamples(skills.command("labels <name> <labels...>")
|
|
338
338
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
339
339
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
340
340
|
.requiredOption("--version <semver>", "绑定标签的精确版本")
|
|
@@ -346,8 +346,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
346
346
|
const targetNamespace = await resolveNamespace(client, options);
|
|
347
347
|
const result = await client.skillAction(targetNamespace.id, name, "labels", { version: options.version, labels: normalized });
|
|
348
348
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name}@${options.version} labels 已更新`);
|
|
349
|
-
}), ["numa
|
|
350
|
-
addExamples(
|
|
349
|
+
}), ["numa skills labels release-helper latest stable --version 1.2.0 --json"]);
|
|
350
|
+
addExamples(skills.command("delete <name>")
|
|
351
351
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
352
352
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
353
353
|
.option("--yes", "确认不可逆的远端删除")
|
|
@@ -358,8 +358,8 @@ export function registerAiRegistryCommands(program) {
|
|
|
358
358
|
const targetNamespace = await resolveNamespace(client, options);
|
|
359
359
|
const result = await client.skillAction(targetNamespace.id, name, "delete");
|
|
360
360
|
await output(command, { ok: true, namespace: targetNamespace, result }, `Skill ${name} 已从远端删除`);
|
|
361
|
-
}), ["numa
|
|
362
|
-
const mcp =
|
|
361
|
+
}), ["numa skills delete obsolete-skill --namespace team-ai --yes --json"]);
|
|
362
|
+
const mcp = program.command("mcp").description("查看、维护和安装 Nacos MCP Servers");
|
|
363
363
|
addExamples(mcp.command("list")
|
|
364
364
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
365
365
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
@@ -375,7 +375,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
375
375
|
pageSize: positiveInteger(options.limit, "limit", 20, 100)
|
|
376
376
|
});
|
|
377
377
|
await output(command, { ok: true, namespace: targetNamespace, mcpServers: result }, pageItems(result).map((item, index) => itemName(item, `mcp-${index + 1}`)).join("\n") || "没有找到 MCP Server");
|
|
378
|
-
}), ["numa
|
|
378
|
+
}), ["numa mcp list --namespace team-ai --json"]);
|
|
379
379
|
addExamples(mcp.command("inspect <name>")
|
|
380
380
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
381
381
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
@@ -385,7 +385,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
385
385
|
const targetNamespace = await resolveNamespace(client, options);
|
|
386
386
|
const result = await client.getMcpServer(targetNamespace.id, name, options.version);
|
|
387
387
|
await output(command, { ok: true, namespace: targetNamespace, mcpServer: result }, JSON.stringify(sanitizeRegistryOutput(result), null, 2));
|
|
388
|
-
}), ["numa
|
|
388
|
+
}), ["numa mcp inspect internal-docs --namespace team-ai --json"]);
|
|
389
389
|
addExamples(mcp.command("install <name>")
|
|
390
390
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
391
391
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
@@ -421,14 +421,14 @@ export function registerAiRegistryCommands(program) {
|
|
|
421
421
|
? `已生成 ChatGPT MCP 安装指引: ${result.endpoint}\n${result.manualSteps.map((step, index) => `${index + 1}. ${step}`).join("\n")}`
|
|
422
422
|
: `MCP ${name} 已安装${result.configPath ? `: ${result.configPath}` : "(由客户端 CLI 管理)"}${result.backupPath ? `\n原配置备份: ${result.backupPath}` : ""}`;
|
|
423
423
|
await output(command, { ok: true, namespace: context.namespace, resolvedVersion: version, installation: result, lock }, textResult);
|
|
424
|
-
}), ["numa
|
|
424
|
+
}), ["numa mcp install internal-docs --namespace team-ai --agent cursor"]);
|
|
425
425
|
addExamples(mcp.command("bridge").description("把 namespace 企业 Router 桥接为本地 stdio MCP")
|
|
426
426
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
427
427
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
428
428
|
.option("--workspace <path>", "项目目录")
|
|
429
429
|
.action(async (options) => {
|
|
430
430
|
await runMcpBridge(new AiRegistryClient(loadConfig("aiRegistry")), options);
|
|
431
|
-
}), ["numa
|
|
431
|
+
}), ["numa mcp bridge --namespace team-ai"]);
|
|
432
432
|
for (const action of ["online", "offline"]) {
|
|
433
433
|
addExamples(mcp.command(`${action} <name>`)
|
|
434
434
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
@@ -439,7 +439,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
439
439
|
const targetNamespace = await resolveNamespace(client, options);
|
|
440
440
|
const result = await client.mcpAction(targetNamespace.id, name, action, { version: options.version });
|
|
441
441
|
await output(command, { ok: true, namespace: targetNamespace, result }, `MCP ${name}: ${action} 完成`);
|
|
442
|
-
}), [`numa
|
|
442
|
+
}), [`numa mcp ${action} internal-docs --version 1.0.0 --json`]);
|
|
443
443
|
}
|
|
444
444
|
addExamples(mcp.command("tags <name> <tags...>")
|
|
445
445
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
@@ -452,7 +452,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
452
452
|
const targetNamespace = await resolveNamespace(client, options);
|
|
453
453
|
const result = await client.mcpAction(targetNamespace.id, name, "biz-tags", { bizTags: normalized });
|
|
454
454
|
await output(command, { ok: true, namespace: targetNamespace, result }, `MCP ${name} tags 已更新`);
|
|
455
|
-
}), ["numa
|
|
455
|
+
}), ["numa mcp tags internal-docs knowledge search --json"]);
|
|
456
456
|
const tools = mcp.command("tool").description("启用或禁用 MCP 工具");
|
|
457
457
|
for (const action of ["enable", "disable"]) {
|
|
458
458
|
addExamples(tools.command(`${action} <mcp-name> <tool-name>`)
|
|
@@ -465,7 +465,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
465
465
|
const version = options.version == null ? undefined : nonnegativeInteger(options.version, "version");
|
|
466
466
|
const result = await client.setMcpToolEnabled(targetNamespace.id, mcpName, toolName, action === "enable", version);
|
|
467
467
|
await output(command, { ok: true, namespace: targetNamespace, result }, `MCP tool ${mcpName}/${toolName}: ${action} 完成`);
|
|
468
|
-
}), [`numa
|
|
468
|
+
}), [`numa mcp tool ${action} internal-docs search --version 3 --json`]);
|
|
469
469
|
}
|
|
470
470
|
addExamples(mcp.command("create <json>")
|
|
471
471
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
@@ -475,7 +475,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
475
475
|
const targetNamespace = await resolveNamespace(client, options);
|
|
476
476
|
const result = await client.createMcpServer(targetNamespace.id, await readObject(file));
|
|
477
477
|
await output(command, { ok: true, namespace: targetNamespace, result }, "MCP create 完成");
|
|
478
|
-
}), ["numa
|
|
478
|
+
}), ["numa mcp create ./mcp.json --namespace team-ai --json"]);
|
|
479
479
|
addExamples(mcp.command("update <name> <json>")
|
|
480
480
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
481
481
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
@@ -484,7 +484,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
484
484
|
const targetNamespace = await resolveNamespace(client, options);
|
|
485
485
|
const result = await client.updateMcpServer(targetNamespace.id, name, await readObject(file));
|
|
486
486
|
await output(command, { ok: true, namespace: targetNamespace, result }, "MCP update 完成");
|
|
487
|
-
}), ["numa
|
|
487
|
+
}), ["numa mcp update internal-docs ./mcp.json --namespace team-ai --json"]);
|
|
488
488
|
addExamples(mcp.command("delete <name>")
|
|
489
489
|
.option("-n, --namespace <key>", "namespaceKey")
|
|
490
490
|
.option("-i, --instance <id-or-code>", "同名 namespace 的实例消歧")
|
|
@@ -497,7 +497,7 @@ export function registerAiRegistryCommands(program) {
|
|
|
497
497
|
const targetNamespace = await resolveNamespace(client, options);
|
|
498
498
|
const result = await client.deleteMcpServer(targetNamespace.id, name, options.version);
|
|
499
499
|
await output(command, { ok: true, namespace: targetNamespace, result }, `MCP ${name} 已从远端删除`);
|
|
500
|
-
}), ["numa
|
|
500
|
+
}), ["numa mcp delete obsolete --namespace team-ai --yes --json"]);
|
|
501
501
|
const approvals = registry.command("approvals").description("查看、审核和发布两人制 release request");
|
|
502
502
|
addExamples(approvals.command("submit <type> <name>")
|
|
503
503
|
.option("-n, --namespace <key>", "namespaceKey")
|