@nggaigc/cli 0.1.21 → 0.1.23

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
@@ -8,6 +8,6 @@ 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 0.1.21 / Plugin 1.1.21 是待 Apple Silicon 实机验收与正式发布批准的候选,不代表当前 `@latest`。CLI 0.1.21 包含 macOS npm symlink 入口修复及 packed-TGZ launcher 回归。候选保留 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 1.1.21。支持 Windows x64/arm64 与 Apple 芯片 Mac arm64,使用本机 Node.js 22.x(22.13 起)或 24.x,不下载或内嵌 Node.js。Windows PowerShell 5.1 默认 `Restricted` 时,安装器仅为受信凭据辅助脚本的子进程指定 `RemoteSigned`;不修改系统或用户执行策略。安装成功但连接失败会明确分开报告,无需重装;由于系统 URL 处理器退出码不能证明浏览器窗口已显示,安装器会同时给出短期一次性手动授权链接。
12
12
 
13
- macOS arm64 辅助程序沿用已编译并通过完整性校验的产物;本次 Windows 修复未进行 Mac 实机回归。Intel Mac 不在支持范围内。签名和 registry 读回前,不要将本候选标为已发布。
13
+ macOS arm64 辅助程序沿用已签名 Plugin 中通过完整性校验的字节;Intel Mac 不在支持范围内。实际公开版本和 `@latest` 状态以 npm registry 为准,Apple Silicon 真机验收需单独进行。
package/dist/bundle.js CHANGED
@@ -47,7 +47,7 @@ export async function verifyBundle(input) {
47
47
  !exactKeys(manifestValue, manifestKeys) ||
48
48
  manifestValue.schemaVersion !== "nggaigc-plugin-package/v1" ||
49
49
  manifestValue.artifactId !== "plugin.nggaigc" ||
50
- manifestValue.version !== "1.1.21" ||
50
+ manifestValue.version !== "1.1.23" ||
51
51
  manifestValue.artifactPath !==
52
52
  `packages/plugins/nggaigc-plugin-${manifestValue.version}.zip` ||
53
53
  typeof manifestValue.sourceCommit !== "string" ||
@@ -1,5 +1,5 @@
1
1
  import { createHash, createPublicKey, randomUUID, verify } from "node:crypto";
2
- import { open, lstat, mkdir, readFile, readdir, realpath, rename, rm, writeFile, } from "node:fs/promises";
2
+ import { open, lstat, mkdir, readFile, readdir, rename, rm, writeFile, } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  const ID = /^skill\.[a-z0-9][a-z0-9.-]{0,79}$/;
5
5
  const VERSION = /^\d+\.\d+\.\d+$/;
@@ -17,6 +17,26 @@ export class IndependentSkillError extends Error {
17
17
  function fail(code) {
18
18
  throw new IndependentSkillError(code);
19
19
  }
20
+ async function hasLinkedPathComponent(value, allowMissing = false) {
21
+ const absolute = path.resolve(value);
22
+ const root = path.parse(absolute).root;
23
+ let current = root;
24
+ for (const component of absolute.slice(root.length).split(path.sep)) {
25
+ if (!component)
26
+ continue;
27
+ current = path.join(current, component);
28
+ try {
29
+ if ((await lstat(current)).isSymbolicLink())
30
+ return true;
31
+ }
32
+ catch (error) {
33
+ if (allowMissing && error.code === "ENOENT")
34
+ return false;
35
+ throw error;
36
+ }
37
+ }
38
+ return false;
39
+ }
20
40
  function record(value) {
21
41
  return value !== null && typeof value === "object" && !Array.isArray(value);
22
42
  }
@@ -679,11 +699,15 @@ export async function prepareIndependentSkill(options) {
679
699
  fail("INSTALL_PATH_UNSAFE");
680
700
  const skillsRoot = path.join(options.codexHome, "skills");
681
701
  const stateRoot = path.join(options.codexHome, ".nggaigc-managed");
702
+ if (await hasLinkedPathComponent(skillsRoot, true).catch(() => true))
703
+ fail("INSTALL_PATH_UNSAFE");
704
+ if (await hasLinkedPathComponent(stateRoot, true).catch(() => true))
705
+ fail("INSTALL_PATH_UNSAFE");
682
706
  await mkdir(skillsRoot, { recursive: true });
683
707
  await mkdir(stateRoot, { recursive: true });
684
- if ((await realpath(skillsRoot)) !== path.resolve(skillsRoot))
708
+ if (await hasLinkedPathComponent(skillsRoot).catch(() => true))
685
709
  fail("INSTALL_PATH_UNSAFE");
686
- if ((await realpath(stateRoot)) !== path.resolve(stateRoot))
710
+ if (await hasLinkedPathComponent(stateRoot).catch(() => true))
687
711
  fail("INSTALL_PATH_UNSAFE");
688
712
  const fetcher = options.fetcher ?? fetch;
689
713
  let result;
@@ -820,9 +844,9 @@ export async function rollbackIndependentSkill(options) {
820
844
  fail("INSTALL_PATH_UNSAFE");
821
845
  const skillsRoot = path.join(options.codexHome, "skills");
822
846
  const stateRoot = path.join(options.codexHome, ".nggaigc-managed");
823
- if ((await realpath(skillsRoot).catch(() => "")) !== path.resolve(skillsRoot))
847
+ if (await hasLinkedPathComponent(skillsRoot).catch(() => true))
824
848
  fail("INSTALL_PATH_UNSAFE");
825
- if ((await realpath(stateRoot).catch(() => "")) !== path.resolve(stateRoot))
849
+ if (await hasLinkedPathComponent(stateRoot).catch(() => true))
826
850
  fail("INSTALL_PATH_UNSAFE");
827
851
  const slug = options.skillId.slice("skill.".length);
828
852
  const target = path.join(skillsRoot, slug);
package/dist/install.js CHANGED
@@ -8,7 +8,7 @@ import { CliError, fixedErrorCode } from "./errors.js";
8
8
  function defaultBundle() {
9
9
  const vendor = fileURLToPath(new URL("../vendor/", import.meta.url));
10
10
  return {
11
- archive: path.join(vendor, "nggaigc-plugin-1.1.21.zip"),
11
+ archive: path.join(vendor, "nggaigc-plugin-1.1.23.zip"),
12
12
  manifest: path.join(vendor, "manifest.json"),
13
13
  trust: path.join(vendor, "trusted-keys.json"),
14
14
  };
@@ -180,7 +180,9 @@ function assertDisposableRoot(value, expectedParent) {
180
180
  export async function runInstall(options = {}) {
181
181
  validateRuntime(options.platform ?? process.platform, options.architecture ?? process.arch);
182
182
  const profile = safeProfile(options.profile ?? os.homedir());
183
- const codexHome = safeProfile(options.codexHome ?? process.env.CODEX_HOME ?? path.join(profile, ".codex"));
183
+ const codexHome = safeProfile(options.codexHome ??
184
+ (options.profile ? undefined : process.env.CODEX_HOME) ??
185
+ path.join(profile, ".codex"));
184
186
  const report = options.reporter ?? (() => undefined);
185
187
  report("verifying");
186
188
  const bundle = await verifyBundle(options.bundle ?? defaultBundle());
@@ -15,7 +15,7 @@ function record(value) {
15
15
  async function productionDependencies(codexHome) {
16
16
  const vendor = fileURLToPath(new URL("../vendor/", import.meta.url));
17
17
  const bundle = await verifyBundle({
18
- archive: path.join(vendor, "nggaigc-plugin-1.1.21.zip"),
18
+ archive: path.join(vendor, "nggaigc-plugin-1.1.23.zip"),
19
19
  manifest: path.join(vendor, "manifest.json"),
20
20
  trust: path.join(vendor, "trusted-keys.json"),
21
21
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nggaigc/cli",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "Secure one-command NGGAIGC Skill installer for Codex.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "schemaVersion": "nggaigc-plugin-package/v1",
3
3
  "artifactId": "plugin.nggaigc",
4
- "version": "1.1.21",
5
- "sourceCommit": "171b45dd832a0960b6a45ae3bb0bc6cec72f8a35",
6
- "artifactPath": "packages/plugins/nggaigc-plugin-1.1.21.zip",
7
- "sha256": "6bc099942f8f3be99388f3e4c46330297927267edb66b3c4e2dcd29755c089f3",
8
- "sizeBytes": 401478,
4
+ "version": "1.1.23",
5
+ "sourceCommit": "5683c0baa5a5629cc65ea9ff7c18febf648f34d0",
6
+ "artifactPath": "packages/plugins/nggaigc-plugin-1.1.23.zip",
7
+ "sha256": "4b034ea8a904dcd8e80eee968c0e79201c4a7f90248117caf7de038770705a99",
8
+ "sizeBytes": 409450,
9
9
  "fileCount": 22,
10
- "platforms": ["win32-x64", "win32-arm64", "darwin-arm64"],
10
+ "platforms": [
11
+ "win32-x64",
12
+ "win32-arm64",
13
+ "darwin-arm64"
14
+ ],
11
15
  "files": {
12
- ".codex-plugin/plugin.json": "1b4e2ce356fc95ce2cba765a1e7ff83651b53bd0d6468cbe00bb946ebfdeb308",
16
+ ".codex-plugin/plugin.json": "2212dbc88e4c2b95c189a1c200d7f564301ecb1954e9bc10eabf095acf4784ca",
13
17
  "installer/install.cjs": "a0c94ed71edf4cd7eb4a66609a4dcf73049abbd14aa273ee65b9b3029be2da2b",
14
18
  "installer/legacy-root-digests.json": "922552646a5aa6cff8616c372912a37b1d5f263351206b85785ed9b2eae31641",
15
19
  "installer/signed-pair-1.1.16.json": "ccb22a90302cc5c9c585067ebc211a27b0c9d8a177c2740a5678a58a3d70bfe9",
@@ -17,17 +21,17 @@
17
21
  "migration/seedream-1.1.3/agents/openai.yaml": "3cbf034ddccd64a7972acd37e7433683a3944f3d8c7b5bdccbbd70e517bf5a8c",
18
22
  "migration/seedream-1.1.3/references/image-generation.md": "208389b3ea4647040232c65a9b91ebcc20787818f57535f16664a7c4db842b3f",
19
23
  "migration/seedream-1.1.3/references/source.json": "75998d079a229435d1097b00bd008703bd38026fc6485c312254925bf55398a8",
20
- "migration/seedream-1.1.3/scripts/seedream.mjs": "3ba352e16232edf7e87c9949f19d2a651d67ab5dbb694760e8ed9cc000c6a293",
24
+ "migration/seedream-1.1.3/scripts/seedream.mjs": "5e6ea3ec48772ce88c21011d17ea8b18d7f2ca002b290d43f50d3daceb01e2ba",
21
25
  "migration/seedream-1.1.3/SKILL.md": "5c5cf3c2d99376f246425e873c5566436ed528256372ac3208abb60364c4517c",
22
26
  "skills/nggaigc/agents/openai.yaml": "8936d97b9821e687e224e9349cc42be2ee5fc20988562efffbcb70080aedf87c",
23
- "skills/nggaigc/references/catalog-and-updates.md": "b53e6da29caf1652a90d1daa8d19f8ef172986f6d74702560b6d83edf0483be8",
24
- "skills/nggaigc/references/source.json": "e6c8798263ba17e018eeb42695fd3491e9c9eb619b13f0aa07be828680313e18",
25
- "skills/nggaigc/scripts/bootstrap-public.json": "69b83d621226a811968e541fadc38bc69d5e0352b7f04f88003d334d3f3ee7c4",
26
- "skills/nggaigc/scripts/launch-ngg-client.cjs": "91283c889cdddd223f68d41c6abf73e1e138015c509e427357b858ca48405f5e",
27
+ "skills/nggaigc/references/catalog-and-updates.md": "52caaea46b6935477b5722c985ea0256b33a55dfbbdc853a5ea139e81b79c611",
28
+ "skills/nggaigc/references/source.json": "eb7aa0f387c93b68de0862b8dc23185e9e68c5409c2e94db5b47835077ce4d8d",
29
+ "skills/nggaigc/scripts/bootstrap-public.json": "4738a7f00192295682158294f1829c8da59ae57431f9ac83b932d4dfe40510fd",
30
+ "skills/nggaigc/scripts/launch-ngg-client.cjs": "2558078a70c2314d3dd20f92b310827430f85a72195eaf5ae2971fe20b0adb91",
27
31
  "skills/nggaigc/scripts/macos-keychain": "b0bdf29d14219d38ca18c7e5c599deb0daa8c8ac70b0babbc7d4fb23673079ec",
28
32
  "skills/nggaigc/scripts/macos-keychain.swift": "1b57e74fde66c824fe970547dd8ca0883a3334c34c065e85a8a2a90d4556a7f5",
29
- "skills/nggaigc/scripts/ngg_client.mjs": "297bbaadcaa90fee1eaf522883626120305d382bbf0585fadd39ca75beb88ec1",
30
- "skills/nggaigc/scripts/ngg-session.mjs": "9f82fcada1607cffb444d5b146013e9c1764de9beec3c67d6ba5f14c8f3dd28c",
33
+ "skills/nggaigc/scripts/ngg_client.mjs": "794ef5b46505aad233cfae9d9851284713589cf3abce0366f3e0b7fe737c7b2e",
34
+ "skills/nggaigc/scripts/ngg-session.mjs": "39a8fd0622823b31f189a024155864a514621d85d9ada53a4a1349bfddc9629e",
31
35
  "skills/nggaigc/scripts/supported-platforms.json": "ec8b0754c489e04534a1d9880dd6664ba9c5bcd07789e06d138e0923f23575ff",
32
36
  "skills/nggaigc/scripts/windows-credential.ps1": "ce097f2a8601664522fcfa8c9505243439ff786a45f15a1dba702b8f9b13dab1",
33
37
  "skills/nggaigc/SKILL.md": "9572e4cddaa2799d06417c21c326d25a6b3107824d042a757c41b0a56efa1bb8"
@@ -36,6 +40,6 @@
36
40
  "algorithm": "ed25519",
37
41
  "keyId": "ngg-signing-skill-release-1",
38
42
  "scope": "artifact-bytes",
39
- "value": "RdxoA4m7OHNH5Bm3RZ0RmgpIeC86TVXaKZgvmuSWUFZ1N1oiA7EV6IEfFemi/43T/uPyEEzQ6i1kwqi/wOwrAQ=="
43
+ "value": "G8f+zRaUjhkwxYwzOhuM8szobxGuqTxUT5FbRa/x64wDkwDeT+Wt6GMKfgVEhiYKNaTmyuKxpQC3oxNJl//9Dw=="
40
44
  }
41
45
  }
index 6941935..21bdfbf 100644
Binary file