@numa-tech/numa 1.23.1 → 1.25.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.
Files changed (51) hide show
  1. package/README.md +4 -0
  2. package/dist/authorization/application-client.d.ts +608 -6
  3. package/dist/authorization/application-client.js +1 -1
  4. package/dist/authorization/application-client.js.map +1 -1
  5. package/dist/authorization/application-schemas.d.ts +171 -0
  6. package/dist/authorization/application-schemas.js +14 -1
  7. package/dist/authorization/application-schemas.js.map +1 -1
  8. package/dist/authorization/commands.d.ts +2 -1
  9. package/dist/authorization/commands.js +2 -0
  10. package/dist/authorization/commands.js.map +1 -1
  11. package/dist/authorization/managed-keycloak-client.d.ts +863 -0
  12. package/dist/authorization/managed-keycloak-client.js +182 -0
  13. package/dist/authorization/managed-keycloak-client.js.map +1 -0
  14. package/dist/authorization/managed-keycloak-commands.d.ts +10 -0
  15. package/dist/authorization/managed-keycloak-commands.js +113 -0
  16. package/dist/authorization/managed-keycloak-commands.js.map +1 -0
  17. package/dist/authorization/managed-keycloak-schemas.d.ts +178 -0
  18. package/dist/authorization/managed-keycloak-schemas.js +55 -0
  19. package/dist/authorization/managed-keycloak-schemas.js.map +1 -0
  20. package/dist/business-issuer.js +3 -5
  21. package/dist/business-issuer.js.map +1 -1
  22. package/dist/command-catalog.js +2 -0
  23. package/dist/command-catalog.js.map +1 -1
  24. package/dist/kb/client.js +10 -5
  25. package/dist/kb/client.js.map +1 -1
  26. package/dist/kb/commands.js +2 -2
  27. package/dist/kb/commands.js.map +1 -1
  28. package/dist/kb/config.d.ts +3 -3
  29. package/dist/kb/config.js +25 -20
  30. package/dist/kb/config.js.map +1 -1
  31. package/dist/login-recovery.js +2 -2
  32. package/dist/login-recovery.js.map +1 -1
  33. package/dist/mcp-gateway/profile.d.ts +4 -0
  34. package/dist/mcp-gateway/profile.js +6 -3
  35. package/dist/mcp-gateway/profile.js.map +1 -1
  36. package/dist/mcp-gateway/runtime.js +14 -0
  37. package/dist/mcp-gateway/runtime.js.map +1 -1
  38. package/docs/design/kb-cli.md +4 -4
  39. package/docs/kb-access.md +14 -7
  40. package/docs/keycloak-managed-import.md +41 -0
  41. package/examples/jev/README.md +65 -0
  42. package/examples/jev/platform-client.test.ts +136 -0
  43. package/examples/jev/platform-client.ts +122 -0
  44. package/package.json +6 -5
  45. package/skills/numa-jev/LICENSE +21 -0
  46. package/skills/numa-jev/SKILL.md +54 -0
  47. package/skills/numa-jev/assets/decision.json +37 -0
  48. package/skills/numa-jev/numa-skill.json +8 -0
  49. package/skills/numa-jev/references/application-integration.md +36 -0
  50. package/skills/numa-jev/references/mcp-usage.md +53 -0
  51. package/skills/numa-jev/references/upstream.md +13 -0
@@ -8,6 +8,8 @@ import { AiRegistryError } from "../ai-registry/errors.js";
8
8
  import { gatewayError } from "./profile.js";
9
9
  const MAX_BYTES = 4 * 1024 * 1024;
10
10
  export function serviceEndpoint(binding, service) {
11
+ if (service === "@catalog" && binding.metadata.catalogMode === "NATIVE")
12
+ throw gatewayError("Native MCP has no directory bridge; select a published service.");
11
13
  if (service === "@catalog")
12
14
  return binding.baseUrl + "/catalog/mcp" + (binding.metadata.publishedEndpoints !== undefined ? `?gatewayId=${encodeURIComponent(binding.metadata.gatewayId)}` : "");
13
15
  if (!/^[a-z0-9][a-z0-9-]{0,62}$/u.test(service))
@@ -27,6 +29,8 @@ export function gatewayFetch(binding, auth, dependencies = {}, exactEndpoint) {
27
29
  const catalogPath = base.pathname + "/api/v1/catalog";
28
30
  const catalogRequest = url.pathname === catalogPath || /^\/[a-z0-9][a-z0-9-]{0,62}$/u.test(url.pathname.slice(catalogPath.length)) && url.pathname.startsWith(catalogPath + "/");
29
31
  const validQuery = !url.search || (catalogRequest || url.pathname === base.pathname + "/catalog/mcp") && [...url.searchParams.keys()].every(k => k === "gatewayId") && url.searchParams.getAll("gatewayId").length === 1 && url.searchParams.get("gatewayId") === binding.metadata.gatewayId;
32
+ if (binding.metadata.catalogMode === "NATIVE" && !binding.metadata.publishedEndpoints?.some(e => e.url === url.toString()))
33
+ throw gatewayError("MCP request escaped the published native endpoints.");
30
34
  const allowedPath = exactEndpoint ? url.origin + url.pathname === new URL(exactEndpoint).origin + new URL(exactEndpoint).pathname && url.search === new URL(exactEndpoint).search : catalogRequest || url.pathname.startsWith(base.pathname + "/");
31
35
  if (url.origin !== base.origin || !allowedPath || url.username || url.password || !validQuery || url.hash) {
32
36
  throw gatewayError("MCP request escaped the selected gateway application.");
@@ -117,6 +121,16 @@ export async function callGatewayTool(binding, auth, service, tool, argumentsVal
117
121
  export async function gatewayCatalog(binding, auth, service, dependencies = {}) {
118
122
  if (service)
119
123
  serviceEndpoint(binding, service);
124
+ if (binding.metadata.catalogMode === "NATIVE") {
125
+ // Listing published metadata is not a claim of runtime access. Inspection checks
126
+ // the selected server directly; a refusal never falls back to a Router.
127
+ const rows = (binding.metadata.publishedEndpoints ?? []).map(endpoint => ({ ...endpoint,
128
+ gatewayId: binding.metadata.gatewayId, source: "PROFILE" }));
129
+ if (!service)
130
+ return { services: rows, source: "PROFILE" };
131
+ return { ...rows.find(row => row.serviceId === service),
132
+ ...(await listGatewayTools(binding, auth, service, dependencies)) };
133
+ }
120
134
  try {
121
135
  const response = await gatewayFetch(binding, auth, dependencies)(binding.baseUrl + "/api/v1/catalog" + (service ? `/${service}` : "") + (binding.metadata.publishedEndpoints !== undefined ? `?gatewayId=${encodeURIComponent(binding.metadata.gatewayId)}` : ""));
122
136
  if (!response.ok)
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/mcp-gateway/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/mcp-gateway/runtime.ts"],"names":[],"mappings":"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"}
@@ -27,11 +27,11 @@
27
27
 
28
28
  ## 认证与地址
29
29
 
30
- 平台 profile 可声明 `services.kb`,由服务自己的 authority/audience 选择 Numa 已有 Keycloak 凭据。无 profile 时显式使用 `NUMA_KB_BASE_URL`;不把平台管理 API 地址推断为 KB 地址。有 profile 时不允许 env 把 KB 请求换到其他服务。API Key 由 `NUMA_KB_API_KEY` 或 `NUMA_KB_API_KEY_FILE` 提供(二者互斥);不进入命令参数、检查点、日志。
30
+ 平台 profile 可声明 `services.kb`,由服务自己的 authority/audience 选择 Numa 已有 Keycloak 凭据。无 profile 时显式使用 `NUMA_KB_BASE_URL`;不把平台管理 API 地址推断为 KB 地址。有 profile 时不允许 env 把 KB 请求换到其他服务。显式旧 Key 模式才读取 `NUMA_KB_API_KEY` 或 `NUMA_KB_API_KEY_FILE`(二者互斥);默认 JWT 模式忽略旧 Key 配置。凭据不进入 Skill、命令参数、检查点、日志。
31
31
 
32
- 独立服务登录使用 `numa login --service kb --no-console --no-config`;同一选项也用于 auth status/logout、profile,确保登录与请求使用同一 authority/audience 缓存。
32
+ 独立服务登录使用 `numa login --service kb --no-console --no-config`;同一选项也用于 auth status/logout、profile,确保登录与请求使用同一 authority/audience 缓存。默认采用 `services.kb.authority`;显式 `--issuer` 复用已有 `services.kb.issuerAuthorities` 白名单和解析器,KB 请求、登录及会话管理使用同一选项。未知别名拒绝;失败后的登录恢复命令保留所选别名,不新增身份路由或缓存机制。
33
33
 
34
- 默认 `NUMA_KB_AUTH_MODE=keycloak`:KB 控制请求携带当前 Numa Keycloak Bearer 与 X-Api-Key。明确配置 `api-key` 模式时只用 KB API Key,适合不要求 Keycloak 的部署;不得在鉴权失败后自动降级。HTTP 仅允许 loopback 测试地址,其他地址 HTTPS,禁止 URL 内嵌凭据、查询或 fragment。代理下载必须落在同一 KB 服务路径内才可附带身份;OSS 签名 URL 不带 KB/Keycloak 凭据,不跟随重定向。
34
+ 默认 `NUMA_KB_AUTH_MODE=keycloak`:KB 控制请求及同源代理上传/下载仅携带所选服务的 Numa Keycloak Bearer,不发送 X-Api-Key。明确配置 `api-key` 模式时只用旧 KB API Key,适合仍支持该协议的部署;不得发送双头或在鉴权失败后自动降级。Skill 直接调用 CLI,不增加 MCP 注册、独立登录体系或另一套服务选择逻辑。HTTP 仅允许 loopback 测试地址,其他地址 HTTPS,禁止 URL 内嵌凭据、查询或 fragment。代理下载必须落在同一 KB 服务路径内才可附带身份;OSS 签名 URL 不带 KB/Keycloak 凭据,不跟随重定向。
35
35
 
36
36
  ## API client 与契约
37
37
 
@@ -45,7 +45,7 @@
45
45
 
46
46
  扫描/计算 SHA256 与 Base64 MD5 → 保存私有 manifest → 创建/恢复会话 → 读取待传文件签名 → 并发 PUT → complete → submitted → 可选轮询解析。
47
47
 
48
- manifest 版本化,包含目标绑定、collectionId、本地绝对路径和内容摘要、按批固定 requestId、sessionId/batchId;不含 Token、API Key、签名 URL。文件 0600、父目录 0700、原子更新;持有互斥锁防止两个进程使用同一状态文件。恢复时重新验证文件内容和目标绑定,源变化拒绝;创建响应丢失时复用原 requestId。异常保留 state 路径;Ctrl-C 中止活动传输并保留恢复记录。已经 submitted 的会话不重新上传或创建任务。
48
+ manifest 版本化,包含目标绑定、collectionId、本地绝对路径和内容摘要、按批固定 requestId、sessionId/batchId;不含 Token、API Key、签名 URL。文件 0600、父目录 0700、原子更新;持有互斥锁防止两个进程使用同一状态文件。恢复时重新验证文件内容和目标绑定,源变化拒绝;创建响应丢失时复用原 requestId。JWT 绑定摘要不包含旧 Key,保留地址、认证模式、租户和 Issuer/Client/Audience;旧双头绑定不自动迁移。摘要不含登录用户 subject,KB 必须继续校验上传会话所有者,不能以本地摘要充当用户授权。异常保留 state 路径;Ctrl-C 中止活动传输并保留恢复记录。已经 submitted 的会话不重新上传或创建任务。
49
49
 
50
50
  PUT 过期/结果未知后先向 KB 查询并续签,已存在对象按服务端状态处理。本地读取期间检测变化;遵守票据 method/headers/size,校验错误不继续 complete。检查点表示传输进度,不替代服务端的 SHA256 验证。代理模式使用外部 `/api/v1/external/documents/batch-upload`,显式传 `conflict_policy=reject`,按批同 request_id 和原内容恢复,任务 ID 保存在相同 manifest。后端保留旧 detect/force_upload 默认和行为;reject 在有候选冲突时返回 409,不自动切换版本。旧后端不支持 reject 时明确失败,不降级 detect。
51
51
 
package/docs/kb-access.md CHANGED
@@ -6,9 +6,7 @@
6
6
 
7
7
  平台 Profile 提供 `services.kb` 时,CLI 使用其服务地址、身份源与 audience。没有 Profile 时需显式配置 `NUMA_KB_BASE_URL`,其值是包含网关服务前缀的根地址,例如 `https://gateway.example.com/kb-management`,不追加 `/api/v1`。有 Profile 时不能用环境变量改到其他服务。
8
8
 
9
- KB API Key 使用 `NUMA_KB_API_KEY_FILE` 指向已有的私有凭据文件,或使用 `NUMA_KB_API_KEY` 环境变量,二者不能同时配置。Key 应由知识库授权主体签发,范围覆盖目标知识库和所需操作。不要将 Key 写入命令参数或检查点。
10
-
11
- 默认同时使用 Keycloak 和 API Key。独立 KB 服务使用对应的登录缓存:
9
+ 默认 `NUMA_KB_AUTH_MODE=keycloak`,仅使用所选服务的 Keycloak Bearer JWT,不要求或发送 KB API Key。Skill 可直接执行 `numa kb`,无需注册 MCP;CLI 复用现有服务 Profile、登录缓存及 Token 刷新能力。独立 KB 服务使用对应的登录缓存:
12
10
 
13
11
  ```bash
14
12
  numa login --service kb --no-console --no-config
@@ -16,9 +14,18 @@ numa auth status --service kb --json
16
14
  numa profile --service kb --json
17
15
  ```
18
16
 
19
- 机器身份沿用 Numa 的 `NUMA_KEYCLOAK_AUTH_MODE=client_credentials` 和专用 client 配置,无需浏览器登录。对只要求 KB API Key 的部署,可显式设置 `NUMA_KB_AUTH_MODE=api-key`。CLI 不会在认证失败时自动降级或更换身份。
17
+ 机器身份沿用 Numa 的 `NUMA_KEYCLOAK_AUTH_MODE=client_credentials` 和专用 client 配置,无需浏览器登录。仅对仍支持旧 KB API Key 的部署,可显式设置 `NUMA_KB_AUTH_MODE=api-key`,再用 `NUMA_KB_API_KEY_FILE` 指向私有凭据文件,或设置 `NUMA_KB_API_KEY`(二者互斥)。该模式仅发送 Key,不发送 Bearer。默认 JWT 模式忽略这两个旧 Key 配置,即使环境中仍残留,也不会读取 Key 文件或发送双头。CLI 不会在认证失败时自动降级或更换身份。不要将凭据写入 Skill、命令参数或检查点。
18
+
19
+ Profile 的 `services.kb.authority` 是默认身份源;如平台同时下发了 `services.kb.issuerAuthorities`,可使用已有的 `--issuer` 选择其中的别名。登录、状态、请求和退出必须选择相同别名:
20
+
21
+ ```bash
22
+ numa login --service kb --issuer BUSINESS_ALIAS --no-console --no-config
23
+ numa auth status --service kb --issuer BUSINESS_ALIAS --json
24
+ numa --issuer BUSINESS_ALIAS kb collections list --json
25
+ numa auth logout --service kb --issuer BUSINESS_ALIAS
26
+ ```
20
27
 
21
- 退出 KB 登录使用 `numa auth logout --service kb`。这不会删除其他服务的缓存。
28
+ 不传 `--issuer` 时使用平台默认配置;未知别名和未下发的身份源会被拒绝,不接受任意 Issuer URL。该选项只选择服务允许的身份源,不改变 KB 服务地址。退出只删除对应 Issuer/Client/租户/Audience 的会话缓存。
22
29
 
23
30
  ## 基本操作
24
31
 
@@ -55,7 +62,7 @@ numa kb tasks status TASK --wait --timeout 600 --json
55
62
  numa kb tasks retry TASK --json
56
63
  ```
57
64
 
58
- 首次上传在传输前保存检查点;不指定 `--state-file` 时自动生成,并在回执中返回路径。检查点只保存目标绑定、文件摘要、固定请求 ID、会话和任务 ID,不保存 API Key、Token 或签名 URL。上传中断后保留该文件,使用相同文件源和凭据配置运行 `--resume`;本地文件变化或目标身份变化时拒绝恢复。
65
+ 首次上传在传输前保存检查点;不指定 `--state-file` 时自动生成,并在回执中返回路径。检查点只保存目标绑定、文件摘要、固定请求 ID、会话和任务 ID,不保存 API Key、Token 或签名 URL。上传中断后保留该文件,使用相同文件源和凭据配置运行 `--resume`;本地文件变化或目标绑定变化时拒绝恢复。绑定包含服务地址、认证模式、配置的租户、Issuer、Client 和 Audience;它不是当前登录用户的标识,不能代替 KB 对会话所有者的校验。旧的 JWT + Key 检查点因认证绑定变化会被拒绝复用;先查询原任务/会话结果,再决定是否发起新上传,勿直接重复提交。
59
66
 
60
67
  恢复是文件级:向 KB 查询哪些对象已上传,跳过已上传项,只重新传输缺失项。单次 PUT 中断后从该文件起点重新开始。CLI 不会为已提交的会话重复创建解析任务。Ctrl-C 中止当前工作并保留恢复记录。
61
68
 
@@ -82,4 +89,4 @@ npm run test:kb
82
89
  npm run root:typecheck
83
90
  ```
84
91
 
85
- 去掉 `--check` 可在审查服务端变化后更新快照。导出不连接部署环境,不加载真实业务数据。受控本地 HTTP 测试覆盖协议和文件行为,不能代替目标环境的真实网关、Keycloak、API Key 和 OSS 联调。
92
+ 去掉 `--check` 可在审查服务端变化后更新快照。导出不连接部署环境,不加载真实业务数据。受控本地 HTTP 测试覆盖协议和文件行为,不能代替目标环境的真实网关、Keycloak 和 OSS 联调(旧 Key 模式另行验证)。
@@ -0,0 +1,41 @@
1
+ # Keycloak 受管配置导入导出
2
+
3
+ CLI 使用当前 Numa 平台登录身份调用 DevOps API;管理凭据由平台保存。使用前运行 `numa doctor`,确认平台 API 与登录目标。
4
+
5
+ 受管声明包使用 `kind: KEYCLOAK_API_KEY_CONFIGURATION`、`schemaVersion: "1"`。它引用平台登记的 Issuer、应用、环境和 Client,不接受任意 Realm dump、脚本、用户、密码、Secret 或 API Key 数据。Web 和 CLI 使用同一套保存、预览、发布及回读流程。
6
+
7
+ ```sh
8
+ numa authorization keycloak-config capabilities <issuer-id>
9
+ numa authorization keycloak-config show --issuer-id <issuer-id> --app <application-id> --platform-environment-id <environment-id>
10
+ numa authorization keycloak-config export --issuer-id <issuer-id> --app <application-id> --platform-environment-id <environment-id> --view current --output declaration.json
11
+ ```
12
+
13
+ 编辑声明后,将 `show` 返回的 `version`、`issuerVersion`、`intentVersion` 分别放入保存请求的 `expectedVersion`、`expectedIssuerVersion`、`expectedIntentVersion`,声明放入 `configuration`。保存发生版本冲突时重新读取并编辑,CLI 不自动覆盖。
14
+
15
+ ```sh
16
+ numa authorization keycloak-config save <issuer-id> --file save-request.json --yes
17
+ numa authorization keycloak-config preview --file declaration.json --request-id <new-request-uuid>
18
+ ```
19
+
20
+ 保存只修改平台当前配置。预览返回既有发布作业;审核具体差异后,使用 `authorization application publication` 的执行、查询和重新核验命令继续。创建预览不会向 Keycloak 写配置。网络中断后先查询原作业,不能通过重新生成请求 ID 猜测原操作结果。
21
+
22
+ 首次纳管缺少字段基线时,先核对观察结果;确认后可在保存命令中使用 `--adopt-current-fields`。它仅采纳受控字段,不采纳整个 Client,也不执行远端修改。
23
+
24
+ `export --view observed` 导出只读观察快照,类型为 `KEYCLOAK_MANAGED_OBSERVATION`,不能作为保存或预览输入。`--view current` 导出可编辑声明。导出文件以仅当前用户可读写权限创建,拒绝覆盖已有文件;输入文件最大 2 MiB,拒绝符号链接。
25
+
26
+ Realm/Profile 变更需要页面引导的短期管理员 bootstrap。CLI 不接收管理员密码,也不把高权限 Token 保存到作业。发布会保留其他应用的授权贡献及受控字段以外的配置;出现归属、基线或回读冲突时,先处理该作业的具体阻断项。
27
+
28
+ 对已结束或已终止的受管导入作业,可生成恢复预览:
29
+
30
+ ```sh
31
+ numa authorization keycloak-config restore-preview <source-job-id> --app <application-id> --file recovery-request.json
32
+ ```
33
+
34
+ 请求文件只含新的 `requestId`、原作业的 `expectedVersion` 和 `expectedDigest`。平台从原任务记录生成反向差异,不接受自带反向字段或任意 JSON Patch。预览仍需审核并通过现有发布命令执行;远端已被其他操作修改、对象依赖或归属无法确认时会阻断,保留保护规则等事项会明确列出。停止原任务不等于撤销已生效配置。
35
+
36
+
37
+ ### Client 配置唯一来源与保存版本
38
+
39
+ 交换 Client 开关保存到应用 Client 的 `definition.configuration.apiKeyEnabled`:省略保留远端,false 停用,true 启用。v1 声明包仍使用 `exchangeClient.enabled` 导入导出,服务端转换到同一份 Client 定义。
40
+
41
+ `save` 输入必须额外携带 `expectedExchangeClientVersion`。已有声明从 `show` 返回的 `exchangeClientVersion` 获取;首次选择或更换 Client,用 `show --exchange-client-instance-id <uuid>` 读取指定目标修订,返回的 `exchangeClientInstanceId` 必须与声明一致。先读取再编辑;冲突后核对重新编辑,不自动读取最新版并重试写入。
@@ -0,0 +1,65 @@
1
+ # Jev 三场景接入样例
2
+
3
+ 本目录和 [numa-jev Skill](../../skills/numa-jev/SKILL.md) 是源码交付;未发布到企业仓库,未部署到目标环境。OpenRouter 仅由 DevOps 平台经指定代理调用。测试完全离线,不使用真实 Key 或推理额度。
4
+
5
+ ## 终端 Agent / WorkBuddy
6
+
7
+ 分别安装经过核验的 Skill 与 MCP 资源。安装步骤沿用 [Numa Skills/MCP 工作流](../../skills/numa-cli/references/skills-workflows.md),不要将资源名、namespace、instance、版本猜成文档中的示例值。
8
+
9
+ 工具发现后调用 `numa_jev_capabilities({})`。将 [合成请求](../../skills/numa-jev/assets/decision.json) 放入 `numa_jev_decide` 参数的 `body` 中。成功取 `structuredContent.data.answers`;HTTP API 不使用这个封装。连接、Jev 权限、上游能力分别核验。
10
+
11
+ ## ChatGPT
12
+
13
+ 目标为正式远程 HTTPS MCP + 用户 OAuth,使用同样的工具合同。现有源码的本地 stdio 服务或安装 Skill 不能证明该链路可用。上线必须补齐远程 OAuth 兼容、实际 Router 导出和客户端连接验证;工具说明承担本地 Skill 中必要的用法指导。
14
+
15
+ 验收时用真实授权测试用户检查:连接 OAuth 完成、工具可见、capabilities 可读、一次合成请求成功;无 Jev 权限的身份不能执行推理。这里只列验收步骤,不执行外部调用或创建连接。
16
+
17
+ ## K8s 自研 Agent
18
+
19
+ [platform-client.ts](platform-client.ts) 展示固定平台地址、服务令牌注入、无自动重放的 HTTP 调用。它是供复制调整的薄示例,不是已发布 SDK;业务应按自己的 schema 检查答案类型/概率并应用经过验证的阈值。网关前缀保留在 base URL 中,例如 `https://platform.example.invalid/devops`。
20
+
21
+ Node 应用可复用已核实版本的 `@numa-tech/cli-auth`,而非自己保存/解析用户 token 缓存:
22
+
23
+ ```ts
24
+ import { ensureAccessToken, type AuthConfig } from "@numa-tech/cli-auth";
25
+ import { createJevClient } from "./platform-client.js";
26
+
27
+ // All values come from the workload's reviewed environment configuration.
28
+ // JEV_OIDC_CLIENT_SECRET is injected by a K8s Secret, never committed.
29
+ const auth: AuthConfig = {
30
+ authenticationMode: "client_credentials",
31
+ discoveryUrl: process.env.JEV_OIDC_DISCOVERY_URL!,
32
+ issuerUrl: process.env.JEV_OIDC_ISSUER!,
33
+ clientId: process.env.JEV_OIDC_CLIENT_ID!,
34
+ clientSecret: process.env.JEV_OIDC_CLIENT_SECRET!,
35
+ scope: process.env.JEV_OIDC_SCOPE ?? "",
36
+ // Required by the shared config type; machine mode never writes user caches.
37
+ tokenFile: "/unused-in-client-credentials-mode",
38
+ redirectHost: "127.0.0.1",
39
+ redirectPort: 8765,
40
+ redirectPath: "/callback",
41
+ openBrowser: false
42
+ };
43
+ const client = createJevClient({
44
+ platformBaseUrl: process.env.JEV_PLATFORM_BASE_URL!,
45
+ getAccessToken: () => ensureAccessToken(auth)
46
+ });
47
+ // Call client.decide(request) inside the application's authorized workflow.
48
+ // Validate required environment variables at service startup. Do not log auth.
49
+ ```
50
+
51
+ 部署配置应包含平台/issuer 地址、独立服务 client、Secret 注入、相应 Jev 功能授权及到这些企业服务的网络权限。`OPENROUTER_API_KEY`、代理配置及代理认证仅归平台。若应用自身使用出网代理访问企业服务,按现有客户端网络配置处理;不能以此替代平台的 OpenRouter 代理绑定。
52
+
53
+ ## 离线验证与待验收项
54
+
55
+ 从 Numa 仓库根目录运行:
56
+
57
+ ```sh
58
+ node --import tsx --test examples/jev/platform-client.test.ts
59
+ ```
60
+
61
+ 测试验证路径前缀、HTTP/MCP 请求分层、每次操作令牌获取、鉴权失败不调用平台、401/403/429/5xx/断连无重放、缺少答案失败及禁止凭据 URL。合成答案只用于 transport 测试,不表示模型质量。
62
+
63
+ 示例仅保留白名单平台错误码和 HTTP 状态,有界读取错误响应;身份 SDK 的原始异常转换为 `IDENTITY_UNAVAILABLE`,且不会派发推理请求。遇到新增未知错误码仍保留状态,按平台维护后的白名单更新示例,不输出上游原文。
64
+
65
+ 目标环境上线后另外验证:用户与服务身份授权;OpenRouter 必须有代理;代理停用后无直连回退;ChatGPT OAuth 的真实往返;用量与审计归属正确。真实端到端验收会调用收费上游,须使用新配置的有效密钥与明确授权的环境。本目录离线验证不宣称这些上线项完成。
@@ -0,0 +1,136 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFile } from "node:fs/promises";
3
+ import test from "node:test";
4
+ import { createJevClient, JevCallError, type JevRequest } from "./platform-client.js";
5
+
6
+ const body: JevRequest = JSON.parse(await readFile(new URL("../../skills/numa-jev/assets/decision.json", import.meta.url), "utf8"));
7
+ const responseBody = {
8
+ model: "synthetic-offline-fixture",
9
+ answers: {
10
+ urgent: { type: "noul", noul: 0.9 },
11
+ department: { type: "choice", choice: "billing", probabilities: { billing: 0.85, technical: 0.05, sales: 0.05, other: 0.05 }, confidence: 0.6 },
12
+ frustration: { type: "score", score: 1.1, legend: { "0": "calm", "1": "frustrated", "2": "angry" }, probabilities: { "0": 0.1, "1": 0.7, "2": 0.2 }, confidence: 0.3 }
13
+ },
14
+ usage: { input_tokens: 0, output_tokens: 0 },
15
+ id: "offline-fixture"
16
+ };
17
+
18
+ test("K8s HTTP transport preserves the gateway prefix and sends only the platform contract", async () => {
19
+ let calls = 0;
20
+ const client = createJevClient({
21
+ platformBaseUrl: "https://platform.example.invalid/devops/",
22
+ getAccessToken: async () => "fake-platform-token",
23
+ fetch: async (input, init) => {
24
+ calls++;
25
+ assert.equal(String(input), "https://platform.example.invalid/devops/api/v1/jev/decisions");
26
+ assert.equal(init?.redirect, "error");
27
+ assert.equal(new Headers(init?.headers).get("authorization"), "Bearer fake-platform-token");
28
+ assert.deepEqual(JSON.parse(String(init?.body)), body);
29
+ assert.equal(init?.method, "POST");
30
+ return Response.json(responseBody);
31
+ }
32
+ });
33
+ assert.deepEqual(await client.decide(body), responseBody);
34
+ assert.equal(calls, 1);
35
+ });
36
+
37
+ for (const status of [401, 403, 429, 502, 503]) {
38
+ test(`HTTP ${status} never triggers a second possibly billable POST`, async () => {
39
+ let calls = 0;
40
+ const client = createJevClient({
41
+ platformBaseUrl: "https://platform.example.invalid",
42
+ getAccessToken: async () => "fake-platform-token",
43
+ fetch: async () => {
44
+ calls++;
45
+ return Response.json({ message: "private-upstream-detail" }, { status });
46
+ }
47
+ });
48
+ await assert.rejects(client.decide(body), (error: unknown) => {
49
+ assert.ok(error instanceof JevCallError);
50
+ assert.equal(error.status, status);
51
+ assert.equal(error.message.includes("private-upstream-detail"), false);
52
+ return true;
53
+ });
54
+ assert.equal(calls, 1);
55
+ });
56
+ }
57
+
58
+ test("network interruption is unknown result, not a new request or direct fallback", async () => {
59
+ let calls = 0;
60
+ const client = createJevClient({
61
+ platformBaseUrl: "https://platform.example.invalid",
62
+ getAccessToken: async () => "fake-platform-token",
63
+ fetch: async () => { calls++; throw new Error("transport detail containing credentials"); }
64
+ });
65
+ await assert.rejects(client.decide(body), { code: "RESULT_UNKNOWN" });
66
+ assert.equal(calls, 1);
67
+ });
68
+
69
+ test("missing answers cannot be consumed as a successful empty decision", async () => {
70
+ const client = createJevClient({
71
+ platformBaseUrl: "https://platform.example.invalid",
72
+ getAccessToken: async () => "fake-platform-token",
73
+ fetch: async () => Response.json({ model: "fixture", answers: {} })
74
+ });
75
+ await assert.rejects(client.decide(body), { code: "MISSING_ANSWER" });
76
+ });
77
+
78
+ test("identity failure prevents dispatch and token is acquired per logical operation", async () => {
79
+ let tokenRequests = 0;
80
+ let calls = 0;
81
+ const client = createJevClient({
82
+ platformBaseUrl: "https://platform.example.invalid",
83
+ getAccessToken: async () => {
84
+ if (++tokenRequests === 2) throw new Error("issuer raw error containing fixture-secret");
85
+ return "fake-platform-token";
86
+ },
87
+ fetch: async () => { calls++; return Response.json(responseBody); }
88
+ });
89
+ await client.decide(body);
90
+ await assert.rejects(client.decide(body), (error: unknown) => {
91
+ assert.ok(error instanceof JevCallError);
92
+ assert.equal(error.code, "IDENTITY_UNAVAILABLE");
93
+ assert.equal(error.message.includes("fixture-secret"), false);
94
+ assert.equal(error.cause, undefined);
95
+ return true;
96
+ });
97
+ assert.equal(tokenRequests, 2);
98
+ assert.equal(calls, 1);
99
+ });
100
+
101
+ test("known platform codes survive while provider details and unknown codes stay private", async () => {
102
+ for (const code of ["OUTBOUND_PROXY_REQUIRED", "JEV_AUDIT_UNAVAILABLE", "fixture-secret"]) {
103
+ const client = createJevClient({
104
+ platformBaseUrl: "https://platform.example.invalid",
105
+ getAccessToken: async () => "fake-platform-token",
106
+ fetch: async () => Response.json({ code, message: "fixture-secret" }, { status: 503 })
107
+ });
108
+ await assert.rejects(client.decide(body), (error: unknown) => {
109
+ assert.ok(error instanceof JevCallError);
110
+ assert.equal(error.code, code === "fixture-secret" ? "PLATFORM_HTTP_ERROR" : code);
111
+ assert.equal(error.status, 503);
112
+ assert.equal(error.message.includes("fixture-secret"), false);
113
+ return true;
114
+ });
115
+ }
116
+ });
117
+
118
+ test("oversized error streams are cancelled before interpreting untrusted error content", async () => {
119
+ let cancelled = false;
120
+ const client = createJevClient({
121
+ platformBaseUrl: "https://platform.example.invalid",
122
+ getAccessToken: async () => "fake-platform-token",
123
+ fetch: async () => new Response(new ReadableStream<Uint8Array>({
124
+ start(controller) { controller.enqueue(new Uint8Array(16 * 1024 + 1)); },
125
+ cancel() { cancelled = true; }
126
+ }), { status: 502 })
127
+ });
128
+ await assert.rejects(client.decide(body), { status: 502, code: "PLATFORM_HTTP_ERROR" });
129
+ assert.equal(cancelled, true);
130
+ });
131
+
132
+ test("caller credentials cannot be placed in a URL and HTTPS is required", () => {
133
+ for (const platformBaseUrl of ["http://platform.example.invalid", "https://user:secret@platform.example.invalid", "https://platform.example.invalid?token=secret"]) {
134
+ assert.throws(() => createJevClient({ platformBaseUrl, getAccessToken: async () => "unused" }), /trusted HTTPS/u);
135
+ }
136
+ });
@@ -0,0 +1,122 @@
1
+ /** Example transport for K8s services. No upstream key, proxy, or retry logic. */
2
+ export interface JevRequest {
3
+ state: string | Record<string, unknown> | unknown[];
4
+ questions: Record<string, unknown>;
5
+ model?: string;
6
+ }
7
+
8
+ export interface JevResult {
9
+ model: string;
10
+ answers: Record<string, unknown>;
11
+ usage?: Record<string, unknown>;
12
+ id?: string;
13
+ provider?: string;
14
+ [key: string]: unknown;
15
+ }
16
+
17
+ export class JevCallError extends Error {
18
+ constructor(public readonly status: number | undefined, public readonly code: string) {
19
+ // Do not include request data, bearer tokens, or the upstream error body.
20
+ super(`Jev call failed (${status ?? "transport"}, ${code}); not retried.`);
21
+ this.name = "JevCallError";
22
+ }
23
+ }
24
+
25
+ const SAFE_PLATFORM_CODES = new Set([
26
+ "JEV_ACCESS_DENIED", "JEV_AUTHENTICATION_REQUIRED", "JEV_PERMISSION_UNAVAILABLE",
27
+ "JEV_INVALID_REQUEST", "JEV_REQUEST_TOO_LARGE", "JEV_INVALID_RESPONSE", "JEV_NOT_CONFIGURED",
28
+ "JEV_BUSY", "JEV_AUDIT_UNAVAILABLE", "JEV_BALANCE_INSUFFICIENT", "JEV_RATE_LIMITED",
29
+ "JEV_PROXY_AUTH_REQUIRED", "JEV_UPSTREAM_FORBIDDEN", "JEV_UPSTREAM_REJECTED",
30
+ "JEV_UPSTREAM_TIMEOUT", "JEV_UPSTREAM_UNAUTHORIZED", "JEV_UPSTREAM_UNAVAILABLE",
31
+ "OUTBOUND_PROXY_REQUIRED", "OUTBOUND_PROXY_UNAVAILABLE", "OUTBOUND_PROXY_AUTH_REQUIRED",
32
+ "OUTBOUND_CONNECT_FAILED", "OUTBOUND_CREDENTIAL_UNAVAILABLE", "OUTBOUND_INVALID_CONFIGURATION"
33
+ ]);
34
+
35
+ async function safeErrorCode(response: Response): Promise<string> {
36
+ const fallback = "PLATFORM_HTTP_ERROR";
37
+ const reader = response.body?.getReader();
38
+ if (!reader) return fallback;
39
+ try {
40
+ let bytes = 0;
41
+ let text = "";
42
+ const decoder = new TextDecoder();
43
+ while (true) {
44
+ const chunk = await reader.read();
45
+ if (chunk.done) break;
46
+ bytes += chunk.value.byteLength;
47
+ if (bytes > 16 * 1024) return fallback;
48
+ text += decoder.decode(chunk.value, { stream: true });
49
+ }
50
+ const value: unknown = JSON.parse(text + decoder.decode());
51
+ if (value && typeof value === "object" && "code" in value
52
+ && typeof value.code === "string" && SAFE_PLATFORM_CODES.has(value.code)) return value.code;
53
+ return fallback;
54
+ } catch {
55
+ return fallback;
56
+ } finally {
57
+ await reader.cancel().catch(() => undefined);
58
+ reader.releaseLock();
59
+ }
60
+ }
61
+
62
+ export function createJevClient(options: {
63
+ platformBaseUrl: string;
64
+ getAccessToken: () => Promise<string>;
65
+ fetch?: typeof fetch;
66
+ timeoutMs?: number;
67
+ }) {
68
+ const base = new URL(options.platformBaseUrl);
69
+ if (base.protocol !== "https:" || base.username || base.password || base.search || base.hash) {
70
+ throw new Error("Configure a trusted HTTPS platform base URL without credentials, query, or fragment.");
71
+ }
72
+ base.pathname = `${base.pathname.replace(/\/+$/u, "")}/api/v1/jev/decisions`;
73
+ const timeoutMs = options.timeoutMs ?? 45_000;
74
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) throw new Error("timeoutMs must be positive.");
75
+
76
+ return {
77
+ async decide(body: JevRequest): Promise<JevResult> {
78
+ // Fetch a current service token for each operation; the identity provider
79
+ // wrapper owns expiry-aware in-memory caching, not this transport.
80
+ let token: string;
81
+ try {
82
+ token = await options.getAccessToken();
83
+ if (!token || /\s/u.test(token)) throw new Error();
84
+ } catch {
85
+ // Identity SDKs may include raw issuer responses in exceptions. No
86
+ // inference was sent, and neither the error nor its cause is propagated.
87
+ throw new JevCallError(undefined, "IDENTITY_UNAVAILABLE");
88
+ }
89
+ try {
90
+ const response = await (options.fetch ?? fetch)(base, {
91
+ method: "POST",
92
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
93
+ body: JSON.stringify(body),
94
+ redirect: "error",
95
+ signal: AbortSignal.timeout(timeoutMs)
96
+ });
97
+ if (!response.ok) {
98
+ // Avoid trusting arbitrary upstream messages or echoing request state.
99
+ throw new JevCallError(response.status, await safeErrorCode(response));
100
+ }
101
+ const value: unknown = await response.json();
102
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
103
+ throw new JevCallError(response.status, "INVALID_RESPONSE");
104
+ }
105
+ const result = value as JevResult;
106
+ if (typeof result.model !== "string" || !result.answers || typeof result.answers !== "object" || Array.isArray(result.answers)) {
107
+ throw new JevCallError(response.status, "INVALID_RESPONSE");
108
+ }
109
+ for (const name of Object.keys(body.questions)) {
110
+ if (!Object.hasOwn(result.answers, name)) {
111
+ throw new JevCallError(response.status, "MISSING_ANSWER");
112
+ }
113
+ }
114
+ return result;
115
+ } catch (error) {
116
+ if (error instanceof JevCallError) throw error;
117
+ // A transport/parse failure can happen after inference was billed.
118
+ throw new JevCallError(undefined, "RESULT_UNKNOWN");
119
+ }
120
+ }
121
+ };
122
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@numa-tech/numa",
3
- "version": "1.23.1",
3
+ "version": "1.25.0",
4
4
  "description": "Cross-platform CLI for the Numa internal developer platform with Keycloak authentication and MCP support.",
5
5
  "author": "numa-tech",
6
6
  "keywords": [
@@ -36,7 +36,8 @@
36
36
  "src/kb/openapi-contract.json",
37
37
  "docs/authorization-configuration-publication.md",
38
38
  "docs/oss-policy-client-governance.md",
39
- "docs/environment-configuration-publication.md"
39
+ "docs/environment-configuration-publication.md",
40
+ "docs/keycloak-managed-import.md"
40
41
  ],
41
42
  "scripts": {
42
43
  "clean": "node scripts/clean.mjs",
@@ -48,7 +49,7 @@
48
49
  "dev:oss-web": "tsx src/cli.ts oss web",
49
50
  "test:oss-web": "node --import tsx --test src/oss/web.test.ts src/oss/web-session.test.ts src/oss/web-transfers.test.ts src/oss/web-command.test.ts src/oss/local-picker.test.ts src/oss/transfer-paths.test.ts src/oss/transfer-worker.test.ts src/oss/transfer-queue.test.ts src/oss/web-page.test.ts src/oss/file-operations.test.ts src/oss/download-links.test.ts",
50
51
  "test:oss-auth-code": "node scripts/test-oss-auth-code.mjs",
51
- "root:test": "node --import tsx --test --test-concurrency=4 src/mcp-gateway/profile.test.ts src/mcp-gateway/runtime.test.ts src/mcp-gateway/install.test.ts src/branding.test.ts src/app-config.test.ts src/platform-profile.test.ts src/profile-migration.test.ts src/identity.test.ts src/backend.test.ts src/oauth.test.ts src/web-console.test.ts src/cli-options.test.ts src/mail/client.test.ts src/wecom/client.test.ts src/wecom/commands.test.ts src/wecom/tools.test.ts src/ai-registry/client.test.ts src/ai-registry/bootstrap.test.ts src/ai-registry/install-defaults.test.ts src/ai-registry/workspace.test.ts src/ai-registry/namespace.test.ts src/compatibility/registry-instance.test.ts src/ai-registry/sync.test.ts src/ai-registry/bridge.test.ts src/ai-registry/skill-installer.test.ts src/ai-registry/skill-uninstaller.test.ts src/ai-registry/skill-dependencies.test.ts src/ai-registry/updates.test.ts src/maintenance/scheduler.test.ts src/maintenance/codex.test.ts src/ai-registry/mcp-installer.test.ts src/media/client.test.ts src/media/commands.test.ts src/media/transfers.test.ts src/oss/client.test.ts src/oss/governance.test.ts src/oss/commands.test.ts src/oss/auth-code.test.ts src/oss/clipboard.test.ts src/oss/web.test.ts src/oss/web-session.test.ts src/oss/web-transfers.test.ts src/oss/web-command.test.ts src/oss/local-picker.test.ts src/oss/transfer-paths.test.ts src/oss/transfer-worker.test.ts src/oss/transfer-queue.test.ts src/oss/web-page.test.ts src/oss/file-operations.test.ts src/oss/download-links.test.ts src/oss/bootstrap.test.ts src/oss/transfers.test.ts src/oss/search.test.ts src/oss/tools.test.ts src/mcp/install.test.ts src/mcp/catalog.test.ts src/tasks/runtime.test.ts src/tasks/stdio.test.ts src/tasks/wecom-notify.test.ts src/tasks/oss-query.test.ts src/interactive/wizard.test.ts src/pipeline/client.test.ts src/pipeline/commands.test.ts src/gitops/client.test.ts src/gitops/commands.test.ts src/gitops/workload-input.test.ts src/gitops/workload-client.test.ts src/gitops/workload-commands.test.ts src/repositories/client.test.ts src/repositories/commands.test.ts src/publications/scanner.test.ts src/publications/client.test.ts src/publications/commands.test.ts src/jenkins-jobs/client.test.ts src/jenkins-jobs/commands.test.ts src/clusters/client.test.ts src/clusters/commands.test.ts src/clusters/kubeconfig-discovery.test.ts src/teams/client.test.ts src/teams/commands.test.ts src/authorization/bootstrap-client.test.ts src/authorization/commands.test.ts src/authorization/access-request-client.test.ts src/authorization/access-request-commands.test.ts src/application-candidates/client.test.ts src/application-candidates/commands.test.ts src/application-onboarding/client.test.ts src/application-onboarding/commands.test.ts src/application-onboarding/tui.test.ts src/chatgpt-desktop.test.ts src/codex-integration.test.ts scripts/release-all.test.mjs src/authorization/enrollment.test.ts src/authorization/application-commands.test.ts src/authorization/application-client.test.ts src/authorization/application-schemas.test.ts src/authorization/enrollment-client.test.ts src/notion/client.test.ts src/notion/commands.test.ts src/notion/tools.test.ts src/notion/machine-cli.test.ts src/cloud/accounts.test.ts src/cloud/bootstrap.test.ts src/cloud/business-bootstrap.test.ts src/cloud/maintenance.test.ts src/cloud/wizard.test.ts src/cloud/oss-bootstrap.test.ts src/business-issuer.test.ts src/login-configuration.test.ts src/login-recovery.test.ts src/ai-registry/mcp-management.test.ts src/ai-registry/mcp-runtime.test.ts src/ai-registry/mcp-stdio.test.ts src/kb/client.test.ts src/kb/config.test.ts src/kb/commands.test.ts src/kb/login.test.ts src/kb/transfers.test.ts src/kb/contract.test.ts src/authorization/environment-governance-client.test.ts src/authorization/environment-governance-commands.test.ts src/authorization/environment-publication.test.ts",
52
+ "root:test": "node --import tsx --test --test-concurrency=4 src/mcp-gateway/profile.test.ts src/mcp-gateway/runtime.test.ts src/mcp-gateway/install.test.ts src/branding.test.ts src/app-config.test.ts src/platform-profile.test.ts src/profile-migration.test.ts src/identity.test.ts src/backend.test.ts src/oauth.test.ts src/web-console.test.ts src/cli-options.test.ts src/mail/client.test.ts src/wecom/client.test.ts src/wecom/commands.test.ts src/wecom/tools.test.ts src/ai-registry/client.test.ts src/ai-registry/bootstrap.test.ts src/ai-registry/install-defaults.test.ts src/ai-registry/workspace.test.ts src/ai-registry/namespace.test.ts src/compatibility/registry-instance.test.ts src/ai-registry/sync.test.ts src/ai-registry/bridge.test.ts src/ai-registry/skill-installer.test.ts src/ai-registry/skill-uninstaller.test.ts src/ai-registry/skill-dependencies.test.ts src/ai-registry/updates.test.ts src/maintenance/scheduler.test.ts src/maintenance/codex.test.ts src/ai-registry/mcp-installer.test.ts src/media/client.test.ts src/media/commands.test.ts src/media/transfers.test.ts src/oss/client.test.ts src/oss/governance.test.ts src/oss/commands.test.ts src/oss/auth-code.test.ts src/oss/clipboard.test.ts src/oss/web.test.ts src/oss/web-session.test.ts src/oss/web-transfers.test.ts src/oss/web-command.test.ts src/oss/local-picker.test.ts src/oss/transfer-paths.test.ts src/oss/transfer-worker.test.ts src/oss/transfer-queue.test.ts src/oss/web-page.test.ts src/oss/file-operations.test.ts src/oss/download-links.test.ts src/oss/bootstrap.test.ts src/oss/transfers.test.ts src/oss/search.test.ts src/oss/tools.test.ts src/mcp/install.test.ts src/mcp/catalog.test.ts src/tasks/runtime.test.ts src/tasks/stdio.test.ts src/tasks/wecom-notify.test.ts src/tasks/oss-query.test.ts src/interactive/wizard.test.ts src/pipeline/client.test.ts src/pipeline/commands.test.ts src/gitops/client.test.ts src/gitops/commands.test.ts src/gitops/workload-input.test.ts src/gitops/workload-client.test.ts src/gitops/workload-commands.test.ts src/repositories/client.test.ts src/repositories/commands.test.ts src/publications/scanner.test.ts src/publications/client.test.ts src/publications/commands.test.ts src/jenkins-jobs/client.test.ts src/jenkins-jobs/commands.test.ts src/clusters/client.test.ts src/clusters/commands.test.ts src/clusters/kubeconfig-discovery.test.ts src/teams/client.test.ts src/teams/commands.test.ts src/authorization/bootstrap-client.test.ts src/authorization/commands.test.ts src/authorization/access-request-client.test.ts src/authorization/access-request-commands.test.ts src/application-candidates/client.test.ts src/application-candidates/commands.test.ts src/application-onboarding/client.test.ts src/application-onboarding/commands.test.ts src/application-onboarding/tui.test.ts src/chatgpt-desktop.test.ts src/codex-integration.test.ts scripts/release-all.test.mjs src/authorization/enrollment.test.ts src/authorization/application-commands.test.ts src/authorization/application-client.test.ts src/authorization/application-schemas.test.ts src/authorization/enrollment-client.test.ts src/notion/client.test.ts src/notion/commands.test.ts src/notion/tools.test.ts src/notion/machine-cli.test.ts src/cloud/accounts.test.ts src/cloud/bootstrap.test.ts src/cloud/business-bootstrap.test.ts src/cloud/maintenance.test.ts src/cloud/wizard.test.ts src/cloud/oss-bootstrap.test.ts src/business-issuer.test.ts src/login-configuration.test.ts src/login-recovery.test.ts src/ai-registry/mcp-management.test.ts src/ai-registry/mcp-runtime.test.ts src/ai-registry/mcp-stdio.test.ts src/kb/client.test.ts src/kb/config.test.ts src/kb/commands.test.ts src/kb/login.test.ts src/kb/transfers.test.ts src/kb/contract.test.ts src/authorization/environment-governance-client.test.ts src/authorization/environment-governance-commands.test.ts src/authorization/environment-publication.test.ts src/authorization/managed-keycloak.test.ts src/authorization/managed-keycloak-producer.test.ts",
52
53
  "pack:check": "turbo run pack:check root:pack:check",
53
54
  "root:pack:check": "node scripts/check-root-package.mjs",
54
55
  "boundaries": "node scripts/check-workspace-boundaries.mjs",
@@ -74,8 +75,8 @@
74
75
  "dependencies": {
75
76
  "@clack/prompts": "^1.7.0",
76
77
  "@modelcontextprotocol/sdk": "^1.29.0",
77
- "@numa-tech/cli-auth": "1.23.1",
78
- "@tokensrc/codex": "1.23.1",
78
+ "@numa-tech/cli-auth": "1.25.0",
79
+ "@tokensrc/codex": "1.25.0",
79
80
  "ali-oss": "^6.23.0",
80
81
  "commander": "^14.0.3",
81
82
  "ink": "^6.8.0",
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TypeSafe AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.