@nggaigc/cli 0.1.15 → 0.1.17
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 +1 -1
- package/dist/bin.js +0 -0
- package/dist/bundle.js +1 -1
- package/dist/independent-skill.js +211 -44
- package/dist/install.js +1 -1
- package/dist/skill-command.js +1 -1
- package/package.json +4 -5
- package/vendor/manifest.json +22 -21
- package/vendor/{nggaigc-plugin-1.1.17.zip → nggaigc-plugin-1.1.18.zip} +0 -0
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
|
-
|
|
11
|
+
本源码的 CLI 0.1.17 / Plugin 1.1.18 是待整合验收与正式签名的候选,不代表当前 `@latest`。候选保留 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
13
|
macOS arm64 辅助程序沿用已编译并通过完整性校验的产物;本次 Windows 修复未进行 Mac 实机回归。Intel Mac 不在支持范围内。签名和 registry 读回前,不要将本候选标为已发布。
|
package/dist/bin.js
CHANGED
|
File without changes
|
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.
|
|
50
|
+
manifestValue.version !== "1.1.18" ||
|
|
51
51
|
manifestValue.artifactPath !==
|
|
52
52
|
`packages/plugins/nggaigc-plugin-${manifestValue.version}.zip` ||
|
|
53
53
|
typeof manifestValue.sourceCommit !== "string" ||
|
|
@@ -381,6 +381,16 @@ async function existingReceipt(target, entry, trust) {
|
|
|
381
381
|
const facts = await lstat(target);
|
|
382
382
|
if (!facts.isDirectory() || facts.isSymbolicLink())
|
|
383
383
|
fail("INSTALL_CONFLICT");
|
|
384
|
+
for (const [name, maximum] of [
|
|
385
|
+
[".nggaigc-package.json", 65536],
|
|
386
|
+
[".nggaigc-package.bin", MAX_PACKAGE_BYTES],
|
|
387
|
+
]) {
|
|
388
|
+
const metadata = await lstat(path.join(target, name));
|
|
389
|
+
if (!metadata.isFile() ||
|
|
390
|
+
metadata.isSymbolicLink() ||
|
|
391
|
+
metadata.size > maximum)
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
384
394
|
const value = JSON.parse(await readFile(path.join(target, ".nggaigc-package.json"), "utf8"));
|
|
385
395
|
if (!record(value) ||
|
|
386
396
|
typeof value.id !== "string" ||
|
|
@@ -485,6 +495,184 @@ async function download(entry, releaseId, origin, fetcher) {
|
|
|
485
495
|
fail("PACKAGE_DOWNLOAD_FAILED");
|
|
486
496
|
return bytes;
|
|
487
497
|
}
|
|
498
|
+
/** Historical authenticity cannot grant start/rollback eligibility. The active
|
|
499
|
+
* catalog and online admission remain the only source of new-start authority. */
|
|
500
|
+
async function replacementEntry(directory, id, options) {
|
|
501
|
+
let receipt;
|
|
502
|
+
try {
|
|
503
|
+
const facts = await lstat(directory);
|
|
504
|
+
if (!facts.isDirectory() || facts.isSymbolicLink())
|
|
505
|
+
fail("INSTALL_CONFLICT");
|
|
506
|
+
const receiptFacts = await lstat(path.join(directory, ".nggaigc-package.json"));
|
|
507
|
+
if (!receiptFacts.isFile() ||
|
|
508
|
+
receiptFacts.isSymbolicLink() ||
|
|
509
|
+
receiptFacts.size > 65536)
|
|
510
|
+
fail("INSTALL_CONFLICT");
|
|
511
|
+
const value = JSON.parse(await readFile(path.join(directory, ".nggaigc-package.json"), "utf8"));
|
|
512
|
+
if (!record(value) ||
|
|
513
|
+
value.id !== id ||
|
|
514
|
+
typeof value.version !== "string" ||
|
|
515
|
+
!VERSION.test(value.version) ||
|
|
516
|
+
typeof value.manifestSha256 !== "string" ||
|
|
517
|
+
!DIGEST.test(value.manifestSha256))
|
|
518
|
+
fail("INSTALL_CONFLICT");
|
|
519
|
+
receipt = value;
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
fail("INSTALL_CONFLICT");
|
|
523
|
+
}
|
|
524
|
+
const current = options.index.entries.filter((entry) => entry.id === id && entry.version === receipt.version);
|
|
525
|
+
if (current.length) {
|
|
526
|
+
if (current.length === 1 && current[0].state === "disabled")
|
|
527
|
+
fail("HISTORICAL_VERSION_BLOCKED");
|
|
528
|
+
if (current.length !== 1)
|
|
529
|
+
fail("INSTALL_CONFLICT");
|
|
530
|
+
if (!(await existingReceipt(directory, current[0], options.trust)))
|
|
531
|
+
fail("INSTALL_CONFLICT");
|
|
532
|
+
return current[0];
|
|
533
|
+
}
|
|
534
|
+
const origin = options.origin ?? "https://api.nggaigc.com/";
|
|
535
|
+
if (origin !== "https://api.nggaigc.com/" &&
|
|
536
|
+
origin !== "https://api.nggaigc.com")
|
|
537
|
+
fail("PACKAGE_SOURCE_REJECTED");
|
|
538
|
+
const url = new URL(`/v1/skill-packages/${encodeURIComponent(id)}/${encodeURIComponent(receipt.version)}/verification`, origin);
|
|
539
|
+
url.searchParams.set("manifestSha256", receipt.manifestSha256);
|
|
540
|
+
let value;
|
|
541
|
+
try {
|
|
542
|
+
const response = await (options.fetcher ?? fetch)(url, {
|
|
543
|
+
method: "GET",
|
|
544
|
+
redirect: "error",
|
|
545
|
+
credentials: "omit",
|
|
546
|
+
cache: "no-store",
|
|
547
|
+
signal: AbortSignal.timeout(15000),
|
|
548
|
+
});
|
|
549
|
+
if (response.status === 410 &&
|
|
550
|
+
!response.redirected &&
|
|
551
|
+
response.url === url.href)
|
|
552
|
+
fail("HISTORICAL_VERSION_BLOCKED");
|
|
553
|
+
if (!response.ok ||
|
|
554
|
+
response.redirected ||
|
|
555
|
+
response.url !== url.href ||
|
|
556
|
+
Number(response.headers.get("content-length") ?? 0) > 16384)
|
|
557
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
558
|
+
const reader = response.body?.getReader();
|
|
559
|
+
if (!reader)
|
|
560
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
561
|
+
const chunks = [];
|
|
562
|
+
let size = 0;
|
|
563
|
+
try {
|
|
564
|
+
while (true) {
|
|
565
|
+
const chunk = await reader.read();
|
|
566
|
+
if (chunk.done)
|
|
567
|
+
break;
|
|
568
|
+
size += chunk.value.length;
|
|
569
|
+
if (size > 16384)
|
|
570
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
571
|
+
chunks.push(chunk.value);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
finally {
|
|
575
|
+
await reader.cancel();
|
|
576
|
+
}
|
|
577
|
+
value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
if (error instanceof IndependentSkillError)
|
|
581
|
+
throw error;
|
|
582
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
583
|
+
}
|
|
584
|
+
if (!record(value) ||
|
|
585
|
+
value.schemaVersion !== "nggaigc-skill-verification/v1" ||
|
|
586
|
+
value.scope !== "replacement-verification" ||
|
|
587
|
+
value.status !== "verified-published" ||
|
|
588
|
+
value.id !== id ||
|
|
589
|
+
value.version !== receipt.version ||
|
|
590
|
+
value.manifestSha256 !== receipt.manifestSha256 ||
|
|
591
|
+
!record(value.package))
|
|
592
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
593
|
+
const pkg = value.package;
|
|
594
|
+
if (typeof pkg.sha256 !== "string" ||
|
|
595
|
+
!DIGEST.test(pkg.sha256) ||
|
|
596
|
+
!Number.isSafeInteger(pkg.sizeBytes) ||
|
|
597
|
+
pkg.sizeBytes < 1 ||
|
|
598
|
+
pkg.sizeBytes > MAX_PACKAGE_BYTES ||
|
|
599
|
+
!record(pkg.signature) ||
|
|
600
|
+
pkg.signature.algorithm !== "ed25519" ||
|
|
601
|
+
typeof pkg.signature.keyId !== "string" ||
|
|
602
|
+
typeof pkg.signature.value !== "string" ||
|
|
603
|
+
!record(pkg.compatibility) ||
|
|
604
|
+
!record(pkg.compatibility.rootSkill) ||
|
|
605
|
+
!record(pkg.compatibility.platform))
|
|
606
|
+
fail("HISTORICAL_VERIFICATION_UNAVAILABLE");
|
|
607
|
+
const entry = {
|
|
608
|
+
id,
|
|
609
|
+
version: value.version,
|
|
610
|
+
manifestSha256: value.manifestSha256,
|
|
611
|
+
state: "superseded",
|
|
612
|
+
manifest: {
|
|
613
|
+
id,
|
|
614
|
+
version: value.version,
|
|
615
|
+
lifecycle: { status: "published" },
|
|
616
|
+
requires: [],
|
|
617
|
+
package: pkg,
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
// Never trust a locally editable receipt as file ownership evidence: the cached
|
|
621
|
+
// ZIP must verify against the pinned signing key, and EVERY installed file.
|
|
622
|
+
if (!(await existingReceipt(directory, entry, options.trust)))
|
|
623
|
+
fail("INSTALL_CONFLICT");
|
|
624
|
+
return entry;
|
|
625
|
+
}
|
|
626
|
+
async function acquireInstallLock(lock) {
|
|
627
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
628
|
+
try {
|
|
629
|
+
const handle = await open(lock, "wx", 0o600);
|
|
630
|
+
await handle.writeFile(JSON.stringify({ schemaVersion: 1, pid: process.pid }));
|
|
631
|
+
await handle.sync();
|
|
632
|
+
return handle;
|
|
633
|
+
}
|
|
634
|
+
catch {
|
|
635
|
+
// Only our positively identified, dead-owner locks may be recovered. Legacy
|
|
636
|
+
// empty locks, malformed state and permission errors remain fail-closed.
|
|
637
|
+
if (attempt)
|
|
638
|
+
fail("INSTALL_BUSY");
|
|
639
|
+
let reclaim;
|
|
640
|
+
try {
|
|
641
|
+
// Serialize reclaimers so one cannot unlink a newly acquired live lock
|
|
642
|
+
// after another has recovered the dead owner.
|
|
643
|
+
reclaim = await open(`${lock}.reclaim`, "wx", 0o600);
|
|
644
|
+
const facts = await lstat(lock);
|
|
645
|
+
if (!facts.isFile() || facts.isSymbolicLink() || facts.size > 1024)
|
|
646
|
+
fail("INSTALL_BUSY");
|
|
647
|
+
const state = JSON.parse(await readFile(lock, "utf8"));
|
|
648
|
+
if (!record(state) ||
|
|
649
|
+
state.schemaVersion !== 1 ||
|
|
650
|
+
!Number.isSafeInteger(state.pid) ||
|
|
651
|
+
state.pid <= 0)
|
|
652
|
+
fail("INSTALL_BUSY");
|
|
653
|
+
try {
|
|
654
|
+
process.kill(state.pid, 0);
|
|
655
|
+
fail("INSTALL_BUSY");
|
|
656
|
+
}
|
|
657
|
+
catch (error) {
|
|
658
|
+
if (!record(error) || error.code !== "ESRCH")
|
|
659
|
+
fail("INSTALL_BUSY");
|
|
660
|
+
}
|
|
661
|
+
await rm(lock);
|
|
662
|
+
}
|
|
663
|
+
catch {
|
|
664
|
+
fail("INSTALL_BUSY");
|
|
665
|
+
}
|
|
666
|
+
finally {
|
|
667
|
+
if (reclaim) {
|
|
668
|
+
await reclaim.close();
|
|
669
|
+
await rm(`${lock}.reclaim`);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return fail("INSTALL_BUSY");
|
|
675
|
+
}
|
|
488
676
|
export async function prepareIndependentSkill(options) {
|
|
489
677
|
const ordered = resolve(options.index, options.skillId, options.skillVersion, options.rootSkillVersion, options.platformVersion);
|
|
490
678
|
if (!path.isAbsolute(options.codexHome))
|
|
@@ -505,33 +693,17 @@ export async function prepareIndependentSkill(options) {
|
|
|
505
693
|
fail("INSTALL_CONFLICT");
|
|
506
694
|
const target = path.join(skillsRoot, slug);
|
|
507
695
|
const lock = path.join(stateRoot, `.nggaigc-${slug}.lock`);
|
|
508
|
-
|
|
509
|
-
try {
|
|
510
|
-
handle = await open(lock, "wx", 0o600);
|
|
511
|
-
}
|
|
512
|
-
catch {
|
|
513
|
-
fail("INSTALL_BUSY");
|
|
514
|
-
}
|
|
696
|
+
const handle = await acquireInstallLock(lock);
|
|
515
697
|
try {
|
|
516
698
|
const backup = path.join(stateRoot, `.nggaigc-backup-${slug}`);
|
|
517
699
|
if ((await lstat(backup).then(() => true, () => false)) &&
|
|
518
700
|
!(await lstat(target).then(() => true, () => false))) {
|
|
519
|
-
let version;
|
|
520
701
|
try {
|
|
521
|
-
|
|
522
|
-
if (!record(receipt) || typeof receipt.version !== "string")
|
|
523
|
-
fail("ROLLBACK_PENDING");
|
|
524
|
-
version = receipt.version;
|
|
702
|
+
await replacementEntry(backup, entry.id, options);
|
|
525
703
|
}
|
|
526
704
|
catch {
|
|
527
705
|
fail("ROLLBACK_PENDING");
|
|
528
706
|
}
|
|
529
|
-
const previous = options.index.entries.find((candidate) => candidate.id === entry.id &&
|
|
530
|
-
candidate.version === version &&
|
|
531
|
-
candidate.state === "active");
|
|
532
|
-
if (!previous ||
|
|
533
|
-
!(await existingReceipt(backup, previous, options.trust)))
|
|
534
|
-
fail("ROLLBACK_PENDING");
|
|
535
707
|
await rename(backup, target);
|
|
536
708
|
}
|
|
537
709
|
if (await existingReceipt(target, entry, options.trust)) {
|
|
@@ -560,26 +732,13 @@ export async function prepareIndependentSkill(options) {
|
|
|
560
732
|
});
|
|
561
733
|
const targetExists = await lstat(target).then(() => true, () => false);
|
|
562
734
|
if (targetExists) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
fail("INSTALL_CONFLICT");
|
|
570
|
-
oldReceipt = { id: value.id, version: value.version };
|
|
571
|
-
}
|
|
572
|
-
catch {
|
|
573
|
-
fail("INSTALL_CONFLICT");
|
|
735
|
+
await replacementEntry(target, entry.id, options);
|
|
736
|
+
if (await lstat(backup).then(() => true, () => false)) {
|
|
737
|
+
// Retain exactly the immediately previous verified version. Do not
|
|
738
|
+
// delete a tampered/unowned backup merely to make an update succeed.
|
|
739
|
+
await replacementEntry(backup, entry.id, options);
|
|
740
|
+
await rm(backup, { recursive: true });
|
|
574
741
|
}
|
|
575
|
-
const oldEntry = options.index.entries.find((candidate) => candidate.id === oldReceipt.id &&
|
|
576
|
-
candidate.version === oldReceipt.version);
|
|
577
|
-
if (oldReceipt.id !== entry.id ||
|
|
578
|
-
!oldEntry ||
|
|
579
|
-
!(await existingReceipt(target, oldEntry, options.trust)))
|
|
580
|
-
fail("INSTALL_CONFLICT");
|
|
581
|
-
if (await lstat(backup).then(() => true, () => false))
|
|
582
|
-
fail("ROLLBACK_PENDING");
|
|
583
742
|
await rename(target, backup);
|
|
584
743
|
}
|
|
585
744
|
try {
|
|
@@ -591,6 +750,20 @@ export async function prepareIndependentSkill(options) {
|
|
|
591
750
|
await rename(backup, target);
|
|
592
751
|
fail("INSTALL_FAILED");
|
|
593
752
|
}
|
|
753
|
+
let activatedValid = false;
|
|
754
|
+
try {
|
|
755
|
+
await options.afterActivate?.(target);
|
|
756
|
+
activatedValid = await existingReceipt(target, entry, options.trust);
|
|
757
|
+
}
|
|
758
|
+
catch {
|
|
759
|
+
activatedValid = false;
|
|
760
|
+
}
|
|
761
|
+
if (!activatedValid) {
|
|
762
|
+
await rm(target, { recursive: true, force: true });
|
|
763
|
+
if (targetExists)
|
|
764
|
+
await rename(backup, target);
|
|
765
|
+
fail("INSTALL_FAILED");
|
|
766
|
+
}
|
|
594
767
|
result = {
|
|
595
768
|
id: entry.id,
|
|
596
769
|
version: entry.version,
|
|
@@ -655,13 +828,7 @@ export async function rollbackIndependentSkill(options) {
|
|
|
655
828
|
const target = path.join(skillsRoot, slug);
|
|
656
829
|
const backup = path.join(stateRoot, `.nggaigc-backup-${slug}`);
|
|
657
830
|
const lock = path.join(stateRoot, `.nggaigc-${slug}.lock`);
|
|
658
|
-
|
|
659
|
-
try {
|
|
660
|
-
handle = await open(lock, "wx", 0o600);
|
|
661
|
-
}
|
|
662
|
-
catch {
|
|
663
|
-
fail("INSTALL_BUSY");
|
|
664
|
-
}
|
|
831
|
+
const handle = await acquireInstallLock(lock);
|
|
665
832
|
const retired = path.join(stateRoot, `.nggaigc-retired-${slug}-${randomUUID()}`);
|
|
666
833
|
try {
|
|
667
834
|
if (!(await existingReceipt(target, current, options.trust)) ||
|
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.
|
|
11
|
+
archive: path.join(vendor, "nggaigc-plugin-1.1.18.zip"),
|
|
12
12
|
manifest: path.join(vendor, "manifest.json"),
|
|
13
13
|
trust: path.join(vendor, "trusted-keys.json"),
|
|
14
14
|
};
|
package/dist/skill-command.js
CHANGED
|
@@ -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.
|
|
18
|
+
archive: path.join(vendor, "nggaigc-plugin-1.1.18.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.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Secure one-command NGGAIGC Skill installer for Codex.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,12 +22,11 @@
|
|
|
22
22
|
"x64",
|
|
23
23
|
"arm64"
|
|
24
24
|
],
|
|
25
|
+
"license": "UNLICENSED",
|
|
25
26
|
"scripts": {
|
|
26
27
|
"build": "tsc -p tsconfig.build.json",
|
|
27
|
-
"prepack": "tsc -p tsconfig.build.json && node scripts/stage-assets.mjs",
|
|
28
28
|
"test": "vitest run src --exclude 'src/windows-secure-store.integration.test.ts'",
|
|
29
29
|
"test:credential:os": "tsc -p tsconfig.build.json && vitest run src/windows-secure-store.integration.test.ts",
|
|
30
30
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/vendor/manifest.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "nggaigc-plugin-package/v1",
|
|
3
3
|
"artifactId": "plugin.nggaigc",
|
|
4
|
-
"version": "1.1.
|
|
5
|
-
"sourceCommit": "
|
|
6
|
-
"artifactPath": "packages/plugins/nggaigc-plugin-1.1.
|
|
7
|
-
"sha256": "
|
|
8
|
-
"sizeBytes":
|
|
9
|
-
"fileCount":
|
|
4
|
+
"version": "1.1.18",
|
|
5
|
+
"sourceCommit": "44a6a19b363015ab1774c568ffdd509689c3444b",
|
|
6
|
+
"artifactPath": "packages/plugins/nggaigc-plugin-1.1.18.zip",
|
|
7
|
+
"sha256": "9d8da5a4100c05e5a7daa9071fbe0bcca36a414d7f34f60093a21a4f90316db4",
|
|
8
|
+
"sizeBytes": 395352,
|
|
9
|
+
"fileCount": 22,
|
|
10
10
|
"platforms": ["win32-x64", "win32-arm64", "darwin-arm64"],
|
|
11
11
|
"files": {
|
|
12
|
-
".codex-plugin/plugin.json": "
|
|
13
|
-
"installer/install.cjs": "
|
|
12
|
+
".codex-plugin/plugin.json": "b450ba745df8d2d041e8b63cc56261b028078eb6c0b1a943c209b20d26af32d4",
|
|
13
|
+
"installer/install.cjs": "85b3ebd5a82968384e2868956e62088be27014681bf373ca601a70d007e66e7c",
|
|
14
14
|
"installer/legacy-root-digests.json": "922552646a5aa6cff8616c372912a37b1d5f263351206b85785ed9b2eae31641",
|
|
15
15
|
"installer/signed-pair-1.1.16.json": "ccb22a90302cc5c9c585067ebc211a27b0c9d8a177c2740a5678a58a3d70bfe9",
|
|
16
|
-
"
|
|
17
|
-
"migration/seedream-1.1.
|
|
18
|
-
"migration/seedream-1.1.
|
|
19
|
-
"migration/seedream-1.1.
|
|
20
|
-
"migration/seedream-1.1.
|
|
16
|
+
"installer/signed-pair-1.1.17.json": "a3697506c929aaa085a6d994fc3a1b9a87e522ec6e1e32f3f760e6a534effa2b",
|
|
17
|
+
"migration/seedream-1.1.3/agents/openai.yaml": "3cbf034ddccd64a7972acd37e7433683a3944f3d8c7b5bdccbbd70e517bf5a8c",
|
|
18
|
+
"migration/seedream-1.1.3/references/image-generation.md": "91e70d577c9990cc1315b3ef41144dbb40ca420b7ae36376def23f0b0c1fd7e4",
|
|
19
|
+
"migration/seedream-1.1.3/references/source.json": "75998d079a229435d1097b00bd008703bd38026fc6485c312254925bf55398a8",
|
|
20
|
+
"migration/seedream-1.1.3/scripts/seedream.mjs": "f235aa1222d88a4c888417dca02f4830ab90fa241d1511aaf6565087bc0347f7",
|
|
21
|
+
"migration/seedream-1.1.3/SKILL.md": "e71b612fc05ab2a0f8a45a745b01a83a5565163f2c671c91b3403b2d8e0b37f4",
|
|
21
22
|
"skills/nggaigc/agents/openai.yaml": "8936d97b9821e687e224e9349cc42be2ee5fc20988562efffbcb70080aedf87c",
|
|
22
|
-
"skills/nggaigc/references/catalog-and-updates.md": "
|
|
23
|
-
"skills/nggaigc/references/source.json": "
|
|
24
|
-
"skills/nggaigc/scripts/bootstrap-public.json": "
|
|
25
|
-
"skills/nggaigc/scripts/launch-ngg-client.cjs": "
|
|
23
|
+
"skills/nggaigc/references/catalog-and-updates.md": "d4ef563e4c0b23d917275da1fb91e5f7f7e652cf2b072a230087bb3702bdef9a",
|
|
24
|
+
"skills/nggaigc/references/source.json": "932b9d5ebf25af8ff195f94a5fb2149655b2d6dbabf8303f70c946044311a9dd",
|
|
25
|
+
"skills/nggaigc/scripts/bootstrap-public.json": "d616d9e0ff7e27717ff40b75727786a9a1ea35a9e8c34073ea4b142515dea1cf",
|
|
26
|
+
"skills/nggaigc/scripts/launch-ngg-client.cjs": "f948a4fa2a5d1867f8e58a08bdf53cf03611e0ea60d2d39c8aee8be09de2210e",
|
|
26
27
|
"skills/nggaigc/scripts/macos-keychain": "b0bdf29d14219d38ca18c7e5c599deb0daa8c8ac70b0babbc7d4fb23673079ec",
|
|
27
28
|
"skills/nggaigc/scripts/macos-keychain.swift": "1b57e74fde66c824fe970547dd8ca0883a3334c34c065e85a8a2a90d4556a7f5",
|
|
28
|
-
"skills/nggaigc/scripts/ngg_client.mjs": "
|
|
29
|
-
"skills/nggaigc/scripts/ngg-session.mjs": "
|
|
29
|
+
"skills/nggaigc/scripts/ngg_client.mjs": "703a6f7dfe7f1bc70716da7c880887ccece4733c14704f27a5856630dddc0bc6",
|
|
30
|
+
"skills/nggaigc/scripts/ngg-session.mjs": "e4d8b4eec48fc55a2533fbd9ba933bc5f56b5fe0226b7bbaf00cbb6223b34853",
|
|
30
31
|
"skills/nggaigc/scripts/supported-platforms.json": "ec8b0754c489e04534a1d9880dd6664ba9c5bcd07789e06d138e0923f23575ff",
|
|
31
32
|
"skills/nggaigc/scripts/windows-credential.ps1": "ce097f2a8601664522fcfa8c9505243439ff786a45f15a1dba702b8f9b13dab1",
|
|
32
|
-
"skills/nggaigc/SKILL.md": "
|
|
33
|
+
"skills/nggaigc/SKILL.md": "4dc24674e0aa4058beb7c4940ef2fe6c60b28eae05a6e38d0d74190d47c048e5"
|
|
33
34
|
},
|
|
34
35
|
"signature": {
|
|
35
36
|
"algorithm": "ed25519",
|
|
36
37
|
"keyId": "ngg-signing-skill-release-1",
|
|
37
38
|
"scope": "artifact-bytes",
|
|
38
|
-
"value": "
|
|
39
|
+
"value": "ZAYCQgoT4dYK1GYyWd9STOlImKO7sMdOjpfREUvsocBBnZOCZGYlsr+9FLIM/ZwdasMtMsWmZZFR91hDxQZLBw=="
|
|
39
40
|
}
|
|
40
41
|
}
|
|
index d34f0d1..6bb8ad5 100644
|
|
|
Binary file
|