@nggaigc/cli 0.1.50 → 0.1.52

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @nggaigc/cli
2
2
 
3
- NGGAIGC Skill 的受信安装器。Codex 与 WorkBuddy 使用同一条安装命令,自动识别当前宿主。
3
+ NGGAIGC Skill 的受信安装器。Codex、WorkBuddy 与豆包工作使用同一条安装命令,自动识别当前宿主。
4
4
 
5
5
  ```powershell
6
6
  npx --yes @nggaigc/cli@latest install
@@ -8,17 +8,17 @@ npx --yes @nggaigc/cli@latest install
8
8
 
9
9
  安装器会先验证内置 Plugin 的 Ed25519 签名、归档哈希和逐文件哈希,再原子安装 Skill。首次运行会打开 NGGAIGC 浏览器授权页;浏览器仅接收短期连接挑战,安装器通过内存中的独立轮询凭据获取连接结果,设备凭据只通过标准输入进入操作系统受保护的凭据存储(Windows Credential Manager 或 macOS Keychain)。安装器不接受 API Key、授权码或设备凭据参数,也不从环境变量读取这些值。
10
10
 
11
- CLI 保留 macOS npm symlink 入口与 packed-TGZ launcher 检查,并验证随包的已签名 Plugin;实际版本以包内签名清单为准。支持 Windows x64/arm64 与 Apple 芯片 Mac arm64,使用本机 Node.js 22.x(22.13 起)或 24.x,不下载或内嵌 Node.js。Windows PowerShell 5.1 默认 `Restricted` 时,安装器仅为受信凭据辅助脚本的子进程指定 `RemoteSigned`;不修改系统或用户执行策略。安装成功但连接失败会明确分开报告,无需重装;由于系统 URL 处理器退出码不能证明浏览器窗口已显示,安装器会同时给出短期一次性手动授权链接。
11
+ CLI 保留 macOS npm symlink 入口与 packed-TGZ launcher 检查,并验证随包的已签名 Plugin;实际版本以包内签名清单为准。允许 Windows x64/arm64、Apple 芯片 Mac arm64 和 Intel Mac x64 安装,使用本机 Node.js 22.x(22.13 起)或 24.x,不下载或内嵌 Node.js。Windows PowerShell 5.1 默认 `Restricted` 时,安装器仅为受信凭据辅助脚本的子进程指定 `RemoteSigned`;不修改系统或用户执行策略。安装成功但连接失败会明确分开报告,无需重装;由于系统 URL 处理器退出码不能证明浏览器窗口已显示,安装器会同时给出短期一次性手动授权链接。
12
12
 
13
- macOS arm64 辅助程序沿用已签名 Plugin 中通过完整性校验的字节;Intel Mac 不在支持范围内。实际公开版本和 `@latest` 状态以 npm registry 为准,Apple Silicon 真机验收需单独进行。
13
+ 从 CLI `0.1.52` 起,Intel Mac 仅放开安装限制,安装的签名包与 macOS 辅助程序字节保持不变;未做 Intel 兼容性适配或真机验收,不保证登录及工作流可用,运行失败按原有机制报告。实际公开版本和 `@latest` 状态以 npm registry 为准,Apple Silicon 真机验收需单独进行。
14
14
 
15
15
  ## 统一安装入口(0.1.46 起)
16
16
 
17
- 不带目录参数时,`install`、`start-skill`、`client` 使用同一套宿主识别:Codex 的当前会话标记,或 WorkBuddy 的会话标记/实际工作会话与专属应用标记组合。配置目录、已安装应用和通用终端变量本身不代表当前宿主;环境标记只是便利提示,不用于认证或授权。
17
+ 不带目录参数时,`install`、`start-skill`、`client` 使用同一套宿主识别:Codex 的当前会话标记,或 WorkBuddy 的会话标记/实际工作会话与专属应用标记组合。豆包工作使用本地命令环境同时提供的 `DOUBAO_OFFICE_APP_ID` 与 `DOUBAO_OFFICE_ANSWER_MESSAGE_ID` 标记,不读取 token。配置目录、已安装应用和通用终端变量本身不代表当前宿主;环境标记只是便利提示,不用于认证或授权。
18
18
 
19
- 无法识别或同时命中两个宿主时,有交互终端可选择 Codex 或 WorkBuddy;非交互调用立即返回 `status: selection-required`、两项 `choices` 和退出码 3,不安装、不打开授权网页。当前 Agent 应让用户选择一次,再把 `--agent codex` 或 `--agent workbuddy` 加到原命令继续;`client` 的目标选项放在 `--` 分隔符之前,业务参数保持原样。安装结果始终返回真实 `skillsDirectory` 和 `skillPath`,连接失败也保留该位置,后续继续使用同一位置。
19
+ 无法识别或同时命中多个宿主时,有交互终端可选择 Codex、WorkBuddy 或豆包工作;非交互调用立即返回 `status: selection-required`、三项 `choices` 和退出码 3,不安装、不打开授权网页。当前 Agent 应让用户选择一次,再由 Agent 将返回的目标值作为 `--agent <所选目标>` 加到原命令继续;`client` 的目标选项放在 `--` 分隔符之前,业务参数保持原样。安装结果始终返回真实 `skillsDirectory` 和 `skillPath`,连接失败也保留该位置,后续继续使用同一位置。
20
20
 
21
- 本次仅 Codex 与 WorkBuddy 为自动识别支持范围;旧 `universal` 与自定义目录参数仍兼容,但不代表其他 Agent 已获验收。
21
+ 豆包工作的本地目录为 `~/DoubaoWork/skills`,根包和后续独立 Skill 统一使用该位置;不会改动另一宿主的安装。豆包工作自动识别从 CLI `0.1.51` 起提供。此次适配依据 macOS 豆包工作 2.32.14 的真实命令环境和已声明技能根目录,其他平台及具体工作流效果须分别验收。旧 `universal` 与自定义目录参数仍兼容。
22
22
 
23
23
  ## 显式目标(0.1.45 起)
24
24
 
@@ -32,13 +32,13 @@ npx --yes @nggaigc/cli@latest start-skill skill.<id> [version] --skills-dir "/ab
32
32
  npx --yes @nggaigc/cli@latest client --skills-dir "/absolute/project/.codebuddy/skills" -- <原command> <原args>
33
33
  ```
34
34
 
35
- `install`、`start-skill` 和 `client` 支持互斥的 `--agent codex|workbuddy|universal` 或 `--skills-dir <绝对目录>`。识别或选择 Codex 后使用 `CODEX_HOME/skills`,未设置时为 `~/.codex/skills`。WorkBuddy 优先使用实际进程提供的 `WORKBUDDY_CONFIG_DIR/skills`(其次 `CODEBUDDY_CONFIG_DIR/skills`),否则使用 `~/.workbuddy/skills`;在宿主外升级时,若现代目录没有根 Skill 而旧 `~/.codebuddy/skills` 已安装,则继续使用旧位置。不会删除或迁移旧安装。`--skills-dir` 始终精确指定项目级或其他现有安装。universal 使用 `~/.agents/skills`,不保证所有 Agent 自动识别。`--no-login` 仅跳过安装后的登录,不绕过签名、哈希、路径检查或后续鉴权。
35
+ `install`、`start-skill` 和 `client` 支持互斥的 `--agent codex|workbuddy|doubao-work|universal` 或 `--skills-dir <绝对目录>`。识别或选择 Codex 后使用 `CODEX_HOME/skills`,未设置时为 `~/.codex/skills`。WorkBuddy 优先使用实际进程提供的 `WORKBUDDY_CONFIG_DIR/skills`(其次 `CODEBUDDY_CONFIG_DIR/skills`),否则使用 `~/.workbuddy/skills`;在宿主外升级时,若现代目录没有根 Skill 而旧 `~/.codebuddy/skills` 已安装,则继续使用旧位置。不会删除或迁移旧安装。`--skills-dir` 始终精确指定项目级或其他现有安装。universal 使用 `~/.agents/skills`,不保证所有 Agent 自动识别。`--no-login` 仅跳过安装后的登录,不绕过签名、哈希、路径检查或后续鉴权。
36
36
 
37
37
  根 Skill 按实际读取的 `SKILL.md` 定位父目录及其上一级 `skillsDirectory`;后续升级与 `start-skill` 显式使用同一目录。准备回执增加 `skillsDirectory`、`rootLauncherPath`,保留 `preparedSkills`;宿主应显式读取返回的真实路径。独立包的原客户端调用使用回执的受信根启动器;`client` 是同目录根包验签桥,保留原命令/参数,不增加 API 专用业务分支。安装新包不证明当前宿主热加载,必要时开启新会话。
38
38
 
39
39
  本地技能包导入可能复制文件,需核导入后的实际路径和独立包同级关系。交互使用宿主可用的提问工具或当前聊天,交付使用宿主可用的媒体/附件能力;不依赖 Codex 专用工具。切换宿主继续复用当前系统用户的系统凭证库和任务历史,不迁移凭据、不要求重新粘贴密钥。资金、权限与未知结果同幂等键恢复规则不变。
40
40
 
41
- 此功能不增加 Linux、Intel Mac 支持,也不代表已接入或认证 WorkBuddy 官方连接器市场;现有系统、Node.js 与正式发布门禁保持适用。
41
+ 此功能不增加 Linux 支持;Intel Mac 仅允许安装,不代表兼容性已验证,也不代表已接入或认证 WorkBuddy 官方连接器市场;现有系统、Node.js 与正式发布门禁保持适用。
42
42
 
43
43
  ## 受信本地 Python 工具文件合同(开发候选)
44
44
 
@@ -3,6 +3,7 @@ import { resolveSkillLocation, } from "./skill-location.js";
3
3
  export const agentChoices = [
4
4
  { agent: "codex", label: "Codex" },
5
5
  { agent: "workbuddy", label: "WorkBuddy" },
6
+ { agent: "doubao-work", label: "豆包工作" },
6
7
  ];
7
8
  export class AgentSelectionRequired extends Error {
8
9
  reason;
@@ -23,12 +24,18 @@ export function detectCallingAgent(environment) {
23
24
  (present(environment.CODEBUDDY_SESSION_ID) &&
24
25
  present(environment.WORKBUDDY_APP_VERSION) &&
25
26
  present(environment.WORKBUDDY_APP_PATH));
26
- if (codex && workbuddy)
27
+ // Observed in Doubao Work's local AgentInfraService shell. Neither marker
28
+ // contains a credential; installed directories and token variables are ignored.
29
+ const doubao = present(environment.DOUBAO_OFFICE_APP_ID) &&
30
+ present(environment.DOUBAO_OFFICE_ANSWER_MESSAGE_ID);
31
+ if ([codex, workbuddy, doubao].filter(Boolean).length > 1)
27
32
  return { reason: "conflicting" };
28
33
  if (codex)
29
34
  return { agent: "codex" };
30
35
  if (workbuddy)
31
36
  return { agent: "workbuddy" };
37
+ if (doubao)
38
+ return { agent: "doubao-work" };
32
39
  return { reason: "unknown" };
33
40
  }
34
41
  async function chooseInTerminal() {
@@ -41,13 +48,15 @@ async function chooseInTerminal() {
41
48
  terminal.once("SIGINT", cancel);
42
49
  terminal.once("close", cancel);
43
50
  try {
44
- const answer = (await terminal.question("请选择使用 NGGAIGC 的 AI 助手:1. Codex 2. WorkBuddy\n输入 1 或 2:", { signal: controller.signal }))
51
+ const answer = (await terminal.question("请选择使用 NGGAIGC 的 AI 助手:1. Codex 2. WorkBuddy 3. 豆包工作\n输入 1、2 或 3:", { signal: controller.signal }))
45
52
  .trim()
46
53
  .toLowerCase();
47
54
  if (answer === "1" || answer === "codex")
48
55
  return "codex";
49
56
  if (answer === "2" || answer === "workbuddy")
50
57
  return "workbuddy";
58
+ if (answer === "3" || answer === "doubao-work")
59
+ return "doubao-work";
51
60
  return undefined;
52
61
  }
53
62
  catch {
@@ -76,7 +85,7 @@ export async function selectCommandLocation(options, runtime = {}) {
76
85
  ? chooseInTerminal
77
86
  : undefined);
78
87
  const agent = await choose?.();
79
- if (agent === "codex" || agent === "workbuddy")
88
+ if (agent === "codex" || agent === "workbuddy" || agent === "doubao-work")
80
89
  return { ...options, agent };
81
90
  throw new AgentSelectionRequired(detected.reason);
82
91
  }
@@ -84,7 +93,7 @@ export function selectionRequiredResult(error) {
84
93
  return {
85
94
  status: "selection-required",
86
95
  error: { code: error.code, reason: error.reason },
87
- message: "请选择当前使用的 AI 助手,然后在原命令中添加 --agent codex 或 --agent workbuddy 继续;client 命令的选项须放在 -- 分隔符之前。",
96
+ message: "请选择当前使用的 AI 助手,再按所选目标继续;已识别的 Codex、WorkBuddy 和豆包工作均使用统一安装命令,无需增加目标参数。client 命令的选项须放在 -- 分隔符之前。",
88
97
  choices: agentChoices,
89
98
  nextAction: "select-agent-and-retry",
90
99
  };
package/dist/install.js CHANGED
@@ -20,7 +20,9 @@ function validateRuntime(platform, architecture) {
20
20
  throw new CliError("RUNTIME_UNSUPPORTED");
21
21
  if (platform !== "win32" && platform !== "darwin")
22
22
  throw new CliError("UNSUPPORTED_PLATFORM");
23
- if ((platform === "darwin" && architecture !== "arm64") ||
23
+ if ((platform === "darwin" &&
24
+ architecture !== "arm64" &&
25
+ architecture !== "x64") ||
24
26
  (platform === "win32" && architecture !== "x64" && architecture !== "arm64"))
25
27
  throw new CliError("UNSUPPORTED_PLATFORM");
26
28
  }
@@ -220,7 +222,13 @@ export async function runInstall(options = {}) {
220
222
  const report = options.reporter ?? (() => undefined);
221
223
  report("verifying");
222
224
  const bundle = await verifyBundle(options.bundle ?? defaultBundle());
223
- if (!bundle.platforms.includes(`${options.platform ?? process.platform}-${options.architecture ?? process.arch}`))
225
+ // Intel Macs may install the unchanged, verified macOS package as-is.
226
+ // This is installation admission only, not a new signed runtime support claim.
227
+ const intelMacInstallation = (options.platform ?? process.platform) === "darwin" &&
228
+ (options.architecture ?? process.arch) === "x64" &&
229
+ bundle.platforms.includes("darwin-arm64");
230
+ if (!bundle.platforms.includes(`${options.platform ?? process.platform}-${options.architecture ?? process.arch}`) &&
231
+ !intelMacInstallation)
224
232
  throw new CliError("UNSUPPORTED_PLATFORM");
225
233
  const temporaryParent = path.resolve(options.temporaryRoot ?? os.tmpdir());
226
234
  const temporary = await mkdtemp(path.join(temporaryParent, "nggaigc-cli-"));
package/dist/main.js CHANGED
@@ -41,11 +41,11 @@ export async function main(args, runtime = {}) {
41
41
  if (args.length === 1 && ["--help", "-h", "help"].includes(args[0])) {
42
42
  output([
43
43
  "NGGAIGC CLI",
44
- "install [--agent codex|workbuddy|universal | --skills-dir <absolute-directory>] [--no-login]",
45
- "start-skill skill.<id> [version] [--agent codex|workbuddy|universal | --skills-dir <absolute-directory>]",
46
- "client [--agent codex|workbuddy|universal | --skills-dir <absolute-directory>] -- <command> [arguments]",
47
- "Default: automatically detect Codex or WorkBuddy. If unknown or conflicting, select one; non-interactive calls return selection-required (exit 3).",
48
- "Codex: existing CODEX_HOME is preserved, otherwise ~/.codex/skills. WorkBuddy: its runtime config directory/skills, otherwise ~/.workbuddy/skills; existing legacy ~/.codebuddy installs are reused. Explicit legacy universal/custom targets remain supported.",
44
+ "install [--agent codex|workbuddy|doubao-work|universal | --skills-dir <absolute-directory>] [--no-login]",
45
+ "start-skill skill.<id> [version] [--agent codex|workbuddy|doubao-work|universal | --skills-dir <absolute-directory>]",
46
+ "client [--agent codex|workbuddy|doubao-work|universal | --skills-dir <absolute-directory>] -- <command> [arguments]",
47
+ "Default: automatically detect Codex, WorkBuddy or Doubao Work. If unknown or conflicting, select one; non-interactive calls return selection-required (exit 3).",
48
+ "Codex: existing CODEX_HOME is preserved, otherwise ~/.codex/skills. WorkBuddy: its runtime config directory/skills, otherwise ~/.workbuddy/skills; existing legacy ~/.codebuddy installs are reused. Doubao Work: ~/DoubaoWork/skills. Explicit legacy universal/custom targets remain supported.",
49
49
  "Use the same target for install and subsequent commands. --no-login installs verified files without opening a browser.",
50
50
  "client examples: -- status, -- login, -- account-status, -- workflows, -- history, -- disconnect",
51
51
  "",
@@ -54,7 +54,7 @@ export function resolveSkillLocation(options = {}, environment = process.env) {
54
54
  }
55
55
  const profile = absoluteDirectory(options.profile ?? os.homedir());
56
56
  const agent = options.agent ?? "codex";
57
- if (!["codex", "workbuddy", "universal"].includes(agent))
57
+ if (!["codex", "workbuddy", "doubao-work", "universal"].includes(agent))
58
58
  throw new CliError("INVALID_INPUT");
59
59
  const home = absoluteDirectory(options.codexHome ??
60
60
  (agent === "codex"
@@ -63,7 +63,9 @@ export function resolveSkillLocation(options = {}, environment = process.env) {
63
63
  : undefined) ?? path.join(profile, ".codex"))
64
64
  : agent === "workbuddy"
65
65
  ? workbuddyHome(profile, options.profile === undefined ? environment : {})
66
- : path.join(profile, ".agents")));
66
+ : agent === "doubao-work"
67
+ ? path.join(profile, "DoubaoWork")
68
+ : path.join(profile, ".agents")));
67
69
  return {
68
70
  skillsDirectory: path.join(home, "skills"),
69
71
  // Explicit and named-host calls for the same directory share one journal.
@@ -85,7 +87,7 @@ export function parseSkillLocation(args) {
85
87
  if (!argument || argument.startsWith("--"))
86
88
  throw new CliError("INVALID_INPUT");
87
89
  if (value === "--agent") {
88
- if (!["codex", "workbuddy", "universal"].includes(argument))
90
+ if (!["codex", "workbuddy", "doubao-work", "universal"].includes(argument))
89
91
  throw new CliError("INVALID_INPUT");
90
92
  location.agent = argument;
91
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nggaigc/cli",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Secure NGGAIGC Skill installer for Codex, WorkBuddy and compatible agents.",
5
5
  "type": "module",
6
6
  "bin": {