@zmice/zc 0.2.8 → 0.3.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.
- package/README.md +430 -430
- package/dist/cli/__tests__/platform.test.js +89 -112
- package/dist/cli/__tests__/platform.test.js.map +1 -1
- package/dist/cli/__tests__/surface.test.js +1 -1
- package/dist/cli/__tests__/surface.test.js.map +1 -1
- package/dist/cli/platform.d.ts.map +1 -1
- package/dist/cli/platform.js +5 -62
- package/dist/cli/platform.js.map +1 -1
- package/dist/node_modules/@zmice/platform-core/dist/index.test.js +3 -5
- package/dist/node_modules/@zmice/platform-core/dist/index.test.js.map +1 -1
- package/dist/runtime/worktree-manager.js +2 -2
- package/dist/runtime/worktree-manager.js.map +1 -1
- package/dist/utils/install-target.test.js +2 -3
- package/dist/utils/install-target.test.js.map +1 -1
- package/dist/utils/qwen-extension-cli.d.ts.map +1 -1
- package/dist/utils/qwen-extension-cli.js +4 -4
- package/dist/utils/qwen-extension-cli.js.map +1 -1
- package/dist/utils/qwen-extension-cli.test.js +6 -9
- package/dist/utils/qwen-extension-cli.test.js.map +1 -1
- package/dist/utils/workspace.js +1 -1
- package/dist/utils/workspace.js.map +1 -1
- package/dist/utils/workspace.test.js +0 -14
- package/dist/utils/workspace.test.js.map +1 -1
- package/package.json +5 -5
- package/vendor/node_modules/@zmice/platform-core/dist/index.test.js +3 -5
- package/vendor/node_modules/@zmice/platform-core/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-claude/dist/index.js +75 -75
- package/vendor/packages/platform-claude/dist/index.test.js +8 -11
- package/vendor/packages/platform-claude/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-codex/dist/index.js +194 -194
- package/vendor/packages/platform-codex/dist/index.test.js +13 -16
- package/vendor/packages/platform-codex/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-opencode/dist/index.js +75 -75
- package/vendor/packages/platform-opencode/dist/index.test.js +15 -19
- package/vendor/packages/platform-opencode/dist/index.test.js.map +1 -1
- package/vendor/packages/platform-qwen/dist/index.js +75 -75
- package/vendor/packages/platform-qwen/dist/index.test.js +7 -9
- package/vendor/packages/platform-qwen/dist/index.test.js.map +1 -1
- package/vendor/packages/toolkit/dist/content-lint.test.js +161 -1
- package/vendor/packages/toolkit/dist/content-lint.test.js.map +1 -1
- package/vendor/packages/toolkit/dist/lint/content-lint.d.ts.map +1 -1
- package/vendor/packages/toolkit/dist/lint/content-lint.js +183 -2
- package/vendor/packages/toolkit/dist/lint/content-lint.js.map +1 -1
- package/vendor/packages/toolkit/dist/manifests.test.js +9 -0
- package/vendor/packages/toolkit/dist/manifests.test.js.map +1 -1
- package/vendor/packages/toolkit/src/content/agents/architect/body.md +42 -42
- package/vendor/packages/toolkit/src/content/agents/code-reviewer/body.md +41 -41
- package/vendor/packages/toolkit/src/content/agents/product-owner/body.md +40 -40
- package/vendor/packages/toolkit/src/content/commands/plan-review/body.md +42 -31
- package/vendor/packages/toolkit/src/content/commands/start/body.md +236 -197
- package/vendor/packages/toolkit/src/content/commands/start/meta.yaml +55 -55
- package/vendor/packages/toolkit/src/content/skills/branch-finish-and-cleanup/body.md +172 -172
- package/vendor/packages/toolkit/src/content/skills/browser-qa-testing/body.md +111 -111
- package/vendor/packages/toolkit/src/content/skills/ci-cd-and-automation/body.md +86 -86
- package/vendor/packages/toolkit/src/content/skills/code-review-and-quality/body.md +140 -140
- package/vendor/packages/toolkit/src/content/skills/code-simplification/body.md +80 -80
- package/vendor/packages/toolkit/src/content/skills/context-engineering/body.md +67 -67
- package/vendor/packages/toolkit/src/content/skills/continuous-learning/body.md +102 -102
- package/vendor/packages/toolkit/src/content/skills/documentation-and-adrs/body.md +8 -6
- package/vendor/packages/toolkit/src/content/skills/engineering-principles/body.md +10 -5
- package/vendor/packages/toolkit/src/content/skills/git-workflow-and-versioning/body.md +9 -9
- package/vendor/packages/toolkit/src/content/skills/multi-perspective-review/body.md +129 -81
- package/vendor/packages/toolkit/src/content/skills/parallel-agent-dispatch/body.md +143 -113
- package/vendor/packages/toolkit/src/content/skills/performance-optimization/body.md +75 -75
- package/vendor/packages/toolkit/src/content/skills/planning-and-task-breakdown/body.md +162 -83
- package/vendor/packages/toolkit/src/content/skills/sdd-tdd-workflow/body.md +130 -95
- package/vendor/packages/toolkit/src/content/skills/sprint-retrospective/body.md +99 -99
- package/vendor/packages/toolkit/src/content/skills/subagent-driven-development/body.md +49 -7
- package/vendor/packages/toolkit/src/content/skills/team-orchestration/body.md +133 -126
- package/vendor/packages/toolkit/src/content/skills/test-driven-development/body.md +78 -78
- package/vendor/packages/toolkit/src/content/skills/using-agent-skills/body.md +193 -193
- package/vendor/references/upstreams.yaml +94 -94
- package/dist/cli/setup.d.ts +0 -3
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -41
- package/dist/cli/setup.js.map +0 -1
- package/dist/utils/codex-config-merge.d.ts +0 -3
- package/dist/utils/codex-config-merge.d.ts.map +0 -1
- package/dist/utils/codex-config-merge.js +0 -43
- package/dist/utils/codex-config-merge.js.map +0 -1
- package/dist/utils/codex-config-merge.test.d.ts +0 -2
- package/dist/utils/codex-config-merge.test.d.ts.map +0 -1
- package/dist/utils/codex-config-merge.test.js +0 -64
- package/dist/utils/codex-config-merge.test.js.map +0 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
|
-
const abs = (path) => resolve(path);
|
|
5
3
|
const platformMocks = vi.hoisted(() => ({
|
|
6
4
|
ArtifactConflictError: class ArtifactConflictError extends Error {
|
|
7
5
|
conflicts;
|
|
@@ -226,15 +224,15 @@ describe("platform CLI", () => {
|
|
|
226
224
|
root: options.dir ?? options.cwd ?? process.cwd(),
|
|
227
225
|
source: options.dir ? "explicit" : "cwd",
|
|
228
226
|
}));
|
|
229
|
-
platformMocks.resolvePlatformInstallReceiptPath.mockImplementation((plan) => (
|
|
227
|
+
platformMocks.resolvePlatformInstallReceiptPath.mockImplementation((plan) => (`${plan.destinationRoot}/.zc/platform-state/${plan.platform}.install-receipt.json`));
|
|
230
228
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
231
229
|
kind: "up-to-date",
|
|
232
230
|
platform: "codex",
|
|
233
|
-
receiptPath:
|
|
231
|
+
receiptPath: "/tmp/install/.zc/platform-state/codex.install-receipt.json",
|
|
234
232
|
receipt: {
|
|
235
233
|
schemaVersion: 1,
|
|
236
234
|
platform: "codex",
|
|
237
|
-
destinationRoot:
|
|
235
|
+
destinationRoot: "/tmp/install",
|
|
238
236
|
manifestSource: "/repo/packages/toolkit/src/content",
|
|
239
237
|
overwrite: "error",
|
|
240
238
|
installedAt: "2026-04-19T12:00:00.000Z",
|
|
@@ -266,18 +264,18 @@ describe("platform CLI", () => {
|
|
|
266
264
|
platformMocks.deletePlatformInstallReceipt.mockResolvedValue(undefined);
|
|
267
265
|
platformMocks.writePlatformInstallReceiptForPlan.mockResolvedValue({});
|
|
268
266
|
platformMocks.syncQwenOfficialCliSourceBundle.mockResolvedValue({
|
|
269
|
-
sourceDir:
|
|
267
|
+
sourceDir: "/tmp/qwen-source",
|
|
270
268
|
extensionName: "zc-toolkit",
|
|
271
269
|
artifactCount: 1,
|
|
272
270
|
});
|
|
273
271
|
platformMocks.syncQwenOfficialCliReleaseBundle.mockResolvedValue({
|
|
274
|
-
bundleDir:
|
|
272
|
+
bundleDir: "/tmp/qwen-release",
|
|
275
273
|
extensionName: "zc-toolkit",
|
|
276
274
|
artifactCount: 1,
|
|
277
275
|
});
|
|
278
276
|
platformMocks.toQwenOfficialCliReleaseArtifacts.mockImplementation((_plan, bundleDir) => [
|
|
279
|
-
{ path:
|
|
280
|
-
{ path:
|
|
277
|
+
{ path: `${bundleDir}/QWEN.md`, content: "# context" },
|
|
278
|
+
{ path: `${bundleDir}/commands/zc/start.md`, content: "# start" },
|
|
281
279
|
]);
|
|
282
280
|
platformMocks.installQwenExtensionFromOfficialRepoWithCli.mockResolvedValue(undefined);
|
|
283
281
|
platformMocks.installQwenExtensionWithOfficialCli.mockResolvedValue(undefined);
|
|
@@ -286,7 +284,6 @@ describe("platform CLI", () => {
|
|
|
286
284
|
platformMocks.relinkQwenExtensionWithOfficialCli.mockResolvedValue(undefined);
|
|
287
285
|
});
|
|
288
286
|
it("uses safe overwrite defaults for platform generate writes", async () => {
|
|
289
|
-
const outputRoot = abs("/tmp/out");
|
|
290
287
|
platformMocks.createQwenGenerationPlan.mockReturnValue(createGenerationPlan([{ path: "QWEN.md", content: "# context" }]));
|
|
291
288
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
292
289
|
created: 1,
|
|
@@ -296,10 +293,9 @@ describe("platform CLI", () => {
|
|
|
296
293
|
dryRun: false,
|
|
297
294
|
});
|
|
298
295
|
await runPlatformGenerate("qwen", { dir: "/tmp/out" });
|
|
299
|
-
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path:
|
|
296
|
+
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path: "/tmp/out/QWEN.md", content: "# context" }], { dryRun: false, overwrite: "error" });
|
|
300
297
|
});
|
|
301
298
|
it("prints a JSON plan without writing files when generate uses --plan", async () => {
|
|
302
|
-
const outputRoot = abs("/tmp/out");
|
|
303
299
|
platformMocks.createQwenGenerationPlan.mockReturnValue(createGenerationPlan([{ path: "QWEN.md", content: "# context" }]));
|
|
304
300
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
305
301
|
await runPlatformGenerate("qwen", { dir: "/tmp/out", plan: true, json: true });
|
|
@@ -309,18 +305,17 @@ describe("platform CLI", () => {
|
|
|
309
305
|
mode: "plan",
|
|
310
306
|
action: "generate",
|
|
311
307
|
target: "qwen",
|
|
312
|
-
root:
|
|
308
|
+
root: "/tmp/out",
|
|
313
309
|
artifactCount: 1,
|
|
314
|
-
artifacts: [{ path:
|
|
310
|
+
artifacts: [{ path: "/tmp/out/QWEN.md", content: "# context" }],
|
|
315
311
|
}));
|
|
316
312
|
logSpy.mockRestore();
|
|
317
313
|
});
|
|
318
314
|
it("exports a standalone qwen release bundle during generate", async () => {
|
|
319
|
-
const bundleRoot = abs("/tmp/zc-toolkit");
|
|
320
315
|
platformMocks.createQwenGenerationPlan.mockReturnValue(createGenerationPlan([{ path: "QWEN.md", content: "# context" }]));
|
|
321
|
-
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan(
|
|
322
|
-
{ path:
|
|
323
|
-
{ path:
|
|
316
|
+
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan("/tmp/zc-toolkit", [
|
|
317
|
+
{ path: "/tmp/zc-toolkit/extensions/zc-toolkit/QWEN.md", content: "# context" },
|
|
318
|
+
{ path: "/tmp/zc-toolkit/extensions/zc-toolkit/commands/zc/start.md", content: "# start" },
|
|
324
319
|
]));
|
|
325
320
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
326
321
|
created: 2,
|
|
@@ -331,16 +326,15 @@ describe("platform CLI", () => {
|
|
|
331
326
|
});
|
|
332
327
|
await runPlatformGenerate("qwen", { dir: "/tmp/zc-toolkit", bundle: "release-bundle" });
|
|
333
328
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
334
|
-
{ path:
|
|
335
|
-
{ path:
|
|
329
|
+
{ path: "/tmp/zc-toolkit/QWEN.md", content: "# context" },
|
|
330
|
+
{ path: "/tmp/zc-toolkit/commands/zc/start.md", content: "# start" },
|
|
336
331
|
], { dryRun: false, overwrite: "error" });
|
|
337
332
|
});
|
|
338
333
|
it("prints qwen release bundle plan paths without native extension nesting", async () => {
|
|
339
|
-
const bundleRoot = abs("/tmp/zc-toolkit");
|
|
340
334
|
platformMocks.createQwenGenerationPlan.mockReturnValue(createGenerationPlan([{ path: "QWEN.md", content: "# context" }]));
|
|
341
|
-
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan(
|
|
342
|
-
{ path:
|
|
343
|
-
{ path:
|
|
335
|
+
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan("/tmp/zc-toolkit", [
|
|
336
|
+
{ path: "/tmp/zc-toolkit/extensions/zc-toolkit/QWEN.md", content: "# context" },
|
|
337
|
+
{ path: "/tmp/zc-toolkit/extensions/zc-toolkit/commands/zc/start.md", content: "# start" },
|
|
344
338
|
]));
|
|
345
339
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
346
340
|
await runPlatformGenerate("qwen", {
|
|
@@ -354,12 +348,12 @@ describe("platform CLI", () => {
|
|
|
354
348
|
mode: "plan",
|
|
355
349
|
action: "generate",
|
|
356
350
|
target: "qwen",
|
|
357
|
-
root:
|
|
351
|
+
root: "/tmp/zc-toolkit",
|
|
358
352
|
bundleType: "release-bundle",
|
|
359
|
-
bundlePath:
|
|
353
|
+
bundlePath: "/tmp/zc-toolkit",
|
|
360
354
|
artifacts: [
|
|
361
|
-
{ path:
|
|
362
|
-
{ path:
|
|
355
|
+
{ path: "/tmp/zc-toolkit/QWEN.md", content: "# context" },
|
|
356
|
+
{ path: "/tmp/zc-toolkit/commands/zc/start.md", content: "# start" },
|
|
363
357
|
],
|
|
364
358
|
}));
|
|
365
359
|
logSpy.mockRestore();
|
|
@@ -406,14 +400,13 @@ describe("platform CLI", () => {
|
|
|
406
400
|
});
|
|
407
401
|
expect(platformMocks.createCodexMarketplaceGenerationPlan).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ scope: "global" }));
|
|
408
402
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
409
|
-
{ path:
|
|
410
|
-
{ path:
|
|
411
|
-
{ path:
|
|
412
|
-
{ path:
|
|
403
|
+
{ path: `${homedir()}/.agents/plugins/marketplace.json`, content: "{}" },
|
|
404
|
+
{ path: `${homedir()}/.codex/AGENTS.md`, content: "# plugin entry" },
|
|
405
|
+
{ path: `${homedir()}/.codex/plugins/zc-toolkit/.codex-plugin/plugin.json`, content: "{}" },
|
|
406
|
+
{ path: `${homedir()}/.codex/agents/zc-code-reviewer.toml`, content: "name = \"zc_code_reviewer\"\n" },
|
|
413
407
|
], { dryRun: false, overwrite: "error" });
|
|
414
408
|
});
|
|
415
409
|
it("exports codex marketplace to the resolved project root with --project", async () => {
|
|
416
|
-
const projectRoot = join("/repo", "project");
|
|
417
410
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
418
411
|
root: "/repo/project",
|
|
419
412
|
source: "project-root",
|
|
@@ -451,13 +444,12 @@ describe("platform CLI", () => {
|
|
|
451
444
|
expect(platformMocks.resolveInstallTarget).toHaveBeenCalledWith("codex", { project: true });
|
|
452
445
|
expect(platformMocks.createCodexMarketplaceGenerationPlan).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ scope: "project" }));
|
|
453
446
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
454
|
-
{ path:
|
|
455
|
-
{ path:
|
|
456
|
-
{ path:
|
|
447
|
+
{ path: "/repo/project/.agents/plugins/marketplace.json", content: "{}" },
|
|
448
|
+
{ path: "/repo/project/AGENTS.md", content: "# plugin entry" },
|
|
449
|
+
{ path: "/repo/project/plugins/zc-toolkit/.codex-plugin/plugin.json", content: "{}" },
|
|
457
450
|
], { dryRun: false, overwrite: "error" });
|
|
458
451
|
});
|
|
459
452
|
it("uses a short codex plugin command for the project marketplace by default", async () => {
|
|
460
|
-
const projectRoot = join("/repo", "project");
|
|
461
453
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
462
454
|
root: "/repo/project",
|
|
463
455
|
source: "project-root",
|
|
@@ -492,9 +484,9 @@ describe("platform CLI", () => {
|
|
|
492
484
|
expect(platformMocks.resolveInstallTarget).toHaveBeenCalledWith("codex", { project: true });
|
|
493
485
|
expect(platformMocks.createCodexMarketplaceGenerationPlan).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ scope: "project" }));
|
|
494
486
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
495
|
-
{ path:
|
|
496
|
-
{ path:
|
|
497
|
-
{ path:
|
|
487
|
+
{ path: "/repo/project/.agents/plugins/marketplace.json", content: "{}" },
|
|
488
|
+
{ path: "/repo/project/AGENTS.md", content: "# plugin entry" },
|
|
489
|
+
{ path: "/repo/project/plugins/zc-toolkit/.codex-plugin/plugin.json", content: "{}" },
|
|
498
490
|
], { dryRun: false, overwrite: "error" });
|
|
499
491
|
});
|
|
500
492
|
it("uses the personal marketplace for codex plugin when --global is explicit", async () => {
|
|
@@ -527,9 +519,9 @@ describe("platform CLI", () => {
|
|
|
527
519
|
expect(platformMocks.resolveInstallTarget).not.toHaveBeenCalled();
|
|
528
520
|
expect(platformMocks.createCodexMarketplaceGenerationPlan).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining({ scope: "global" }));
|
|
529
521
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
530
|
-
{ path:
|
|
531
|
-
{ path:
|
|
532
|
-
{ path:
|
|
522
|
+
{ path: `${homedir()}/.agents/plugins/marketplace.json`, content: "{}" },
|
|
523
|
+
{ path: `${homedir()}/.codex/AGENTS.md`, content: "# plugin entry" },
|
|
524
|
+
{ path: `${homedir()}/.codex/plugins/zc-toolkit/.codex-plugin/plugin.json`, content: "{}" },
|
|
533
525
|
], { dryRun: false, overwrite: "error" });
|
|
534
526
|
});
|
|
535
527
|
it("cleans the generated Codex plugin skills directory on force writes", async () => {
|
|
@@ -561,18 +553,17 @@ describe("platform CLI", () => {
|
|
|
561
553
|
});
|
|
562
554
|
await runPlatformPlugin("codex", { global: true, force: true });
|
|
563
555
|
expect(platformMocks.removeManagedPaths).toHaveBeenCalledWith([
|
|
564
|
-
|
|
556
|
+
`${homedir()}/.codex/plugins/zc-toolkit/skills`,
|
|
565
557
|
]);
|
|
566
558
|
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([
|
|
567
|
-
{ path:
|
|
568
|
-
{ path:
|
|
569
|
-
{ path:
|
|
570
|
-
{ path:
|
|
559
|
+
{ path: `${homedir()}/.agents/plugins/marketplace.json`, content: "{}" },
|
|
560
|
+
{ path: `${homedir()}/.codex/AGENTS.md`, content: "# plugin entry" },
|
|
561
|
+
{ path: `${homedir()}/.codex/plugins/zc-toolkit/.codex-plugin/plugin.json`, content: "{}" },
|
|
562
|
+
{ path: `${homedir()}/.codex/plugins/zc-toolkit/skills/start/SKILL.md`, content: "# start" },
|
|
571
563
|
], { dryRun: false, overwrite: "force" });
|
|
572
564
|
});
|
|
573
565
|
it("uses safe overwrite defaults for platform install and writes a receipt", async () => {
|
|
574
|
-
|
|
575
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", installRoot, [{ path: join(installRoot, "AGENTS.md"), content: "# agents" }]));
|
|
566
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents" }]));
|
|
576
567
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
577
568
|
created: 1,
|
|
578
569
|
overwritten: 0,
|
|
@@ -582,20 +573,19 @@ describe("platform CLI", () => {
|
|
|
582
573
|
});
|
|
583
574
|
await runPlatformInstall("codex", { dir: "/tmp/install" });
|
|
584
575
|
expect(platformMocks.createCodexInstallPlan).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
|
|
585
|
-
destinationRoot:
|
|
576
|
+
destinationRoot: "/tmp/install",
|
|
586
577
|
scope: "dir",
|
|
587
578
|
overwrite: "error",
|
|
588
579
|
}));
|
|
589
|
-
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path:
|
|
580
|
+
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path: "/tmp/install/AGENTS.md", content: "# agents" }], { dryRun: false, overwrite: "error" });
|
|
590
581
|
expect(platformMocks.writePlatformInstallReceiptForPlan).toHaveBeenCalledWith(expect.objectContaining({
|
|
591
|
-
destinationRoot:
|
|
582
|
+
destinationRoot: "/tmp/install",
|
|
592
583
|
}), expect.objectContaining({
|
|
593
584
|
zcVersion: expect.any(String),
|
|
594
585
|
}));
|
|
595
586
|
});
|
|
596
587
|
it("forwards force installs to artifact writes", async () => {
|
|
597
|
-
|
|
598
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", installRoot, [{ path: join(installRoot, "AGENTS.md"), content: "# agents" }]));
|
|
588
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents" }]));
|
|
599
589
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
600
590
|
created: 0,
|
|
601
591
|
overwritten: 1,
|
|
@@ -604,11 +594,10 @@ describe("platform CLI", () => {
|
|
|
604
594
|
dryRun: false,
|
|
605
595
|
});
|
|
606
596
|
await runPlatformInstall("codex", { dir: "/tmp/install", force: true });
|
|
607
|
-
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path:
|
|
597
|
+
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path: "/tmp/install/AGENTS.md", content: "# agents" }], { dryRun: false, overwrite: "force" });
|
|
608
598
|
});
|
|
609
599
|
it("uses the resolved project root when install target is omitted", async () => {
|
|
610
|
-
|
|
611
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", projectRoot, [{ path: join(projectRoot, "AGENTS.md"), content: "# agents" }]));
|
|
600
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/workspace/project", [{ path: "/workspace/project/AGENTS.md", content: "# agents" }]));
|
|
612
601
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
613
602
|
created: 1,
|
|
614
603
|
overwritten: 0,
|
|
@@ -630,15 +619,14 @@ describe("platform CLI", () => {
|
|
|
630
619
|
global: undefined,
|
|
631
620
|
});
|
|
632
621
|
expect(platformMocks.createCodexInstallPlan).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
|
|
633
|
-
destinationRoot:
|
|
622
|
+
destinationRoot: "/workspace/project",
|
|
634
623
|
scope: "project",
|
|
635
624
|
}));
|
|
636
625
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("安装目录自动解析(project-root)"));
|
|
637
626
|
logSpy.mockRestore();
|
|
638
627
|
});
|
|
639
628
|
it("prints a JSON install plan without writing files when install uses --plan", async () => {
|
|
640
|
-
|
|
641
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", installRoot, [{ path: join(installRoot, "AGENTS.md"), content: "# agents" }], "dir", "error"));
|
|
629
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents" }], "dir", "error"));
|
|
642
630
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
643
631
|
await runPlatformInstall("codex", { dir: "/tmp/install", plan: true, json: true });
|
|
644
632
|
expect(platformMocks.writeArtifacts).not.toHaveBeenCalled();
|
|
@@ -647,14 +635,14 @@ describe("platform CLI", () => {
|
|
|
647
635
|
mode: "plan",
|
|
648
636
|
action: "install",
|
|
649
637
|
target: "codex",
|
|
650
|
-
root:
|
|
638
|
+
root: "/tmp/install",
|
|
651
639
|
scope: "dir",
|
|
652
640
|
rootSource: "explicit",
|
|
653
641
|
artifactCount: 1,
|
|
654
642
|
overwrite: "error",
|
|
655
643
|
artifacts: expect.arrayContaining([
|
|
656
644
|
expect.objectContaining({
|
|
657
|
-
path:
|
|
645
|
+
path: "/tmp/install/AGENTS.md",
|
|
658
646
|
content: "# agents",
|
|
659
647
|
}),
|
|
660
648
|
]),
|
|
@@ -662,22 +650,21 @@ describe("platform CLI", () => {
|
|
|
662
650
|
logSpy.mockRestore();
|
|
663
651
|
});
|
|
664
652
|
it("prints platform status from receipt and current plan", async () => {
|
|
665
|
-
const installRoot = abs("/tmp/install");
|
|
666
653
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
667
654
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
668
655
|
root: "/tmp/install",
|
|
669
656
|
source: "explicit",
|
|
670
657
|
});
|
|
671
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex",
|
|
658
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents" }]));
|
|
672
659
|
await runPlatformStatus("codex", { dir: "/tmp/install", json: true });
|
|
673
660
|
expect(platformMocks.resolvePlatformInstallStatus).toHaveBeenCalledWith(expect.objectContaining({
|
|
674
|
-
destinationRoot:
|
|
661
|
+
destinationRoot: "/tmp/install",
|
|
675
662
|
}));
|
|
676
663
|
const payload = JSON.parse(logSpy.mock.calls[0]?.[0] ?? "{}");
|
|
677
664
|
expect(payload).toEqual(expect.objectContaining({
|
|
678
665
|
mode: "status",
|
|
679
666
|
target: "codex",
|
|
680
|
-
root:
|
|
667
|
+
root: "/tmp/install",
|
|
681
668
|
status: "up-to-date",
|
|
682
669
|
installedContentFingerprint: "installed-fingerprint",
|
|
683
670
|
contentFingerprint: "current-fingerprint",
|
|
@@ -685,34 +672,32 @@ describe("platform CLI", () => {
|
|
|
685
672
|
logSpy.mockRestore();
|
|
686
673
|
});
|
|
687
674
|
it("prints qwen platform status json with installed metadata from receipt", async () => {
|
|
688
|
-
const qwenRoot = abs("/home/test/.qwen");
|
|
689
|
-
const qwenBundleRoot = abs("/tmp/qwen-release/zc-toolkit");
|
|
690
675
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
691
676
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
692
677
|
root: "/home/test/.qwen",
|
|
693
678
|
source: "official-global",
|
|
694
679
|
hint: "Qwen 官方文档定义用户级配置目录为 `~/.qwen`。",
|
|
695
680
|
});
|
|
696
|
-
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan(
|
|
681
|
+
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan("/home/test/.qwen", [{ path: "/home/test/.qwen/extensions/zc-toolkit/QWEN.md", content: "# context" }], "global"));
|
|
697
682
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
698
683
|
kind: "up-to-date",
|
|
699
684
|
platform: "qwen",
|
|
700
|
-
receiptPath:
|
|
685
|
+
receiptPath: "/home/test/.qwen/.zc/platform-state/qwen.install-receipt.json",
|
|
701
686
|
receipt: {
|
|
702
687
|
schemaVersion: 1,
|
|
703
688
|
platform: "qwen",
|
|
704
|
-
destinationRoot:
|
|
689
|
+
destinationRoot: "/home/test/.qwen",
|
|
705
690
|
manifestSource: "/repo/packages/toolkit/src/content",
|
|
706
691
|
overwrite: "error",
|
|
707
692
|
installedAt: "2026-04-19T12:00:00.000Z",
|
|
708
693
|
installMethod: "filesystem",
|
|
709
694
|
installSource: "local-bundle",
|
|
710
|
-
sourceRef:
|
|
695
|
+
sourceRef: "/tmp/qwen-release/zc-toolkit",
|
|
711
696
|
bundleType: "release-bundle",
|
|
712
|
-
bundlePath:
|
|
697
|
+
bundlePath: "/tmp/qwen-release/zc-toolkit",
|
|
713
698
|
artifacts: [
|
|
714
699
|
{
|
|
715
|
-
path:
|
|
700
|
+
path: "/home/test/.qwen/extensions/zc-toolkit/QWEN.md",
|
|
716
701
|
sha256: "sha",
|
|
717
702
|
bytes: 9,
|
|
718
703
|
},
|
|
@@ -733,27 +718,26 @@ describe("platform CLI", () => {
|
|
|
733
718
|
expect(payload).toEqual(expect.objectContaining({
|
|
734
719
|
mode: "status",
|
|
735
720
|
target: "qwen",
|
|
736
|
-
root:
|
|
721
|
+
root: "/home/test/.qwen",
|
|
737
722
|
installMethod: "filesystem",
|
|
738
723
|
installSource: "local-bundle",
|
|
739
|
-
sourceRef:
|
|
724
|
+
sourceRef: "/tmp/qwen-release/zc-toolkit",
|
|
740
725
|
bundleType: "release-bundle",
|
|
741
|
-
bundlePath:
|
|
726
|
+
bundlePath: "/tmp/qwen-release/zc-toolkit",
|
|
742
727
|
recommendedInstallMethod: "qwen-cli",
|
|
743
728
|
recommendedInstallSource: "github-repo",
|
|
744
729
|
recommendedSourceRef: "https://github.com/zmice/zc-qwen-extension.git",
|
|
745
730
|
recommendedBundleType: "release-bundle",
|
|
746
|
-
recommendedBundlePath:
|
|
731
|
+
recommendedBundlePath: "/home/test/.qwen/.zc/platform-bundles/qwen/zc-toolkit",
|
|
747
732
|
}));
|
|
748
733
|
logSpy.mockRestore();
|
|
749
734
|
});
|
|
750
735
|
it("prints update plan when status shows update-available", async () => {
|
|
751
|
-
const installRoot = abs("/tmp/install");
|
|
752
736
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
753
737
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
754
738
|
kind: "update-available",
|
|
755
739
|
platform: "codex",
|
|
756
|
-
receiptPath:
|
|
740
|
+
receiptPath: "/tmp/install/.zc/platform-state/codex.install-receipt.json",
|
|
757
741
|
receipt: null,
|
|
758
742
|
contentFingerprint: "current-fingerprint",
|
|
759
743
|
installedContentFingerprint: "installed-fingerprint",
|
|
@@ -765,7 +749,7 @@ describe("platform CLI", () => {
|
|
|
765
749
|
},
|
|
766
750
|
artifacts: [],
|
|
767
751
|
});
|
|
768
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex",
|
|
752
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents v2" }], "dir", "error"));
|
|
769
753
|
await runPlatformUpdate("codex", { dir: "/tmp/install", plan: true, json: true });
|
|
770
754
|
expect(platformMocks.writeArtifacts).not.toHaveBeenCalled();
|
|
771
755
|
const payload = JSON.parse(logSpy.mock.calls[0]?.[0] ?? "{}");
|
|
@@ -774,16 +758,15 @@ describe("platform CLI", () => {
|
|
|
774
758
|
action: "update",
|
|
775
759
|
target: "codex",
|
|
776
760
|
status: "update-available",
|
|
777
|
-
root:
|
|
761
|
+
root: "/tmp/install",
|
|
778
762
|
}));
|
|
779
763
|
logSpy.mockRestore();
|
|
780
764
|
});
|
|
781
765
|
it("treats update-available as managed overwrite and refreshes the receipt", async () => {
|
|
782
|
-
const installRoot = abs("/tmp/install");
|
|
783
766
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
784
767
|
kind: "update-available",
|
|
785
768
|
platform: "codex",
|
|
786
|
-
receiptPath:
|
|
769
|
+
receiptPath: "/tmp/install/.zc/platform-state/codex.install-receipt.json",
|
|
787
770
|
receipt: null,
|
|
788
771
|
contentFingerprint: "current-fingerprint",
|
|
789
772
|
installedContentFingerprint: "installed-fingerprint",
|
|
@@ -795,7 +778,7 @@ describe("platform CLI", () => {
|
|
|
795
778
|
},
|
|
796
779
|
artifacts: [],
|
|
797
780
|
});
|
|
798
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex",
|
|
781
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents v2" }], "dir", "error"));
|
|
799
782
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
800
783
|
created: 0,
|
|
801
784
|
overwritten: 1,
|
|
@@ -805,10 +788,10 @@ describe("platform CLI", () => {
|
|
|
805
788
|
});
|
|
806
789
|
await runPlatformUpdate("codex", { dir: "/tmp/install" });
|
|
807
790
|
expect(platformMocks.createCodexInstallPlan).toHaveBeenLastCalledWith(expect.anything(), expect.objectContaining({
|
|
808
|
-
destinationRoot:
|
|
791
|
+
destinationRoot: "/tmp/install",
|
|
809
792
|
overwrite: "force",
|
|
810
793
|
}));
|
|
811
|
-
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path:
|
|
794
|
+
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path: "/tmp/install/AGENTS.md", content: "# agents v2" }], { dryRun: false, overwrite: "force" });
|
|
812
795
|
expect(platformMocks.writePlatformInstallReceiptForPlan).toHaveBeenCalled();
|
|
813
796
|
});
|
|
814
797
|
it("reports a no-op update when the installation is already up-to-date", async () => {
|
|
@@ -874,8 +857,7 @@ describe("platform CLI", () => {
|
|
|
874
857
|
errorSpy.mockRestore();
|
|
875
858
|
});
|
|
876
859
|
it("passes global scope through install target resolution and exposes official path hints", async () => {
|
|
877
|
-
|
|
878
|
-
platformMocks.createClaudeInstallPlan.mockReturnValue(createInstallPlan("claude", claudeRoot, [{ path: join(claudeRoot, "CLAUDE.md"), content: "# claude" }]));
|
|
860
|
+
platformMocks.createClaudeInstallPlan.mockReturnValue(createInstallPlan("claude", "/home/test/.claude", [{ path: "/home/test/.claude/CLAUDE.md", content: "# claude" }]));
|
|
879
861
|
platformMocks.writeArtifacts.mockResolvedValue({
|
|
880
862
|
created: 1,
|
|
881
863
|
overwritten: 0,
|
|
@@ -897,15 +879,14 @@ describe("platform CLI", () => {
|
|
|
897
879
|
global: true,
|
|
898
880
|
});
|
|
899
881
|
expect(platformMocks.createClaudeInstallPlan).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({
|
|
900
|
-
destinationRoot:
|
|
882
|
+
destinationRoot: "/home/test/.claude",
|
|
901
883
|
scope: "global",
|
|
902
884
|
}));
|
|
903
885
|
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("提示:Claude Code 官方文档定义用户级 memory 文件位于 `~/.claude/CLAUDE.md`。"));
|
|
904
886
|
logSpy.mockRestore();
|
|
905
887
|
});
|
|
906
888
|
it("prefers the official qwen extensions CLI for global installs", async () => {
|
|
907
|
-
|
|
908
|
-
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan(qwenRoot, [{ path: join(qwenRoot, "extensions/zc-toolkit/QWEN.md"), content: "# context" }], "global"));
|
|
889
|
+
platformMocks.createQwenInstallPlan.mockReturnValue(createQwenInstallPlan("/home/test/.qwen", [{ path: "/home/test/.qwen/extensions/zc-toolkit/QWEN.md", content: "# context" }], "global"));
|
|
909
890
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
910
891
|
root: "/home/test/.qwen",
|
|
911
892
|
source: "official-global",
|
|
@@ -914,7 +895,7 @@ describe("platform CLI", () => {
|
|
|
914
895
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
915
896
|
kind: "not-installed",
|
|
916
897
|
platform: "qwen",
|
|
917
|
-
receiptPath:
|
|
898
|
+
receiptPath: "/home/test/.qwen/.zc/platform-state/qwen.install-receipt.json",
|
|
918
899
|
receipt: null,
|
|
919
900
|
contentFingerprint: "current-fingerprint",
|
|
920
901
|
installedContentFingerprint: undefined,
|
|
@@ -934,8 +915,7 @@ describe("platform CLI", () => {
|
|
|
934
915
|
expect(platformMocks.writeArtifacts).not.toHaveBeenCalled();
|
|
935
916
|
});
|
|
936
917
|
it("prints a JSON install plan with scope metadata", async () => {
|
|
937
|
-
|
|
938
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", codexRoot, [{ path: join(codexRoot, "AGENTS.md"), content: "# agents" }], "global", "error"));
|
|
918
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/home/test/.codex", [{ path: "/home/test/.codex/AGENTS.md", content: "# agents" }], "global", "error"));
|
|
939
919
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
940
920
|
root: "/home/test/.codex",
|
|
941
921
|
source: "official-global",
|
|
@@ -949,7 +929,7 @@ describe("platform CLI", () => {
|
|
|
949
929
|
action: "install",
|
|
950
930
|
target: "codex",
|
|
951
931
|
scope: "global",
|
|
952
|
-
root:
|
|
932
|
+
root: "/home/test/.codex",
|
|
953
933
|
rootSource: "official-global",
|
|
954
934
|
hint: "Codex 官方文档将 Codex home(默认 `~/.codex`)定义为全局级 `AGENTS.md` 的位置。",
|
|
955
935
|
}));
|
|
@@ -1074,23 +1054,22 @@ describe("platform CLI", () => {
|
|
|
1074
1054
|
expect(platformMocks.deletePlatformInstallReceipt).toHaveBeenCalledWith("/home/test/.qwen/.zc/platform-state/qwen.install-receipt.json");
|
|
1075
1055
|
});
|
|
1076
1056
|
it("repairs drifted filesystem installs by rewriting managed artifacts", async () => {
|
|
1077
|
-
|
|
1078
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", installRoot, [{ path: join(installRoot, "AGENTS.md"), content: "# agents repaired" }]));
|
|
1057
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/tmp/install", [{ path: "/tmp/install/AGENTS.md", content: "# agents repaired" }]));
|
|
1079
1058
|
platformMocks.resolvePlatformInstallStatus.mockResolvedValue({
|
|
1080
1059
|
kind: "drifted",
|
|
1081
1060
|
platform: "codex",
|
|
1082
|
-
receiptPath:
|
|
1061
|
+
receiptPath: "/tmp/install/.zc/platform-state/codex.install-receipt.json",
|
|
1083
1062
|
receipt: {
|
|
1084
1063
|
schemaVersion: 1,
|
|
1085
1064
|
platform: "codex",
|
|
1086
|
-
destinationRoot:
|
|
1065
|
+
destinationRoot: "/tmp/install",
|
|
1087
1066
|
manifestSource: "/repo/packages/toolkit/src/content",
|
|
1088
1067
|
overwrite: "error",
|
|
1089
1068
|
installedAt: "2026-04-19T12:00:00.000Z",
|
|
1090
1069
|
installMethod: "filesystem",
|
|
1091
1070
|
artifacts: [
|
|
1092
1071
|
{
|
|
1093
|
-
path:
|
|
1072
|
+
path: "/tmp/install/AGENTS.md",
|
|
1094
1073
|
sha256: "old-sha",
|
|
1095
1074
|
bytes: 8,
|
|
1096
1075
|
},
|
|
@@ -1106,7 +1085,7 @@ describe("platform CLI", () => {
|
|
|
1106
1085
|
},
|
|
1107
1086
|
artifacts: [
|
|
1108
1087
|
{
|
|
1109
|
-
path:
|
|
1088
|
+
path: "/tmp/install/AGENTS.md",
|
|
1110
1089
|
receiptSha256: "old-sha",
|
|
1111
1090
|
actualSha256: "drifted-sha",
|
|
1112
1091
|
plannedSha256: "new-sha",
|
|
@@ -1124,10 +1103,10 @@ describe("platform CLI", () => {
|
|
|
1124
1103
|
});
|
|
1125
1104
|
await runPlatformRepair("codex", { dir: "/tmp/install" });
|
|
1126
1105
|
expect(platformMocks.createCodexInstallPlan).toHaveBeenLastCalledWith(expect.anything(), expect.objectContaining({
|
|
1127
|
-
destinationRoot:
|
|
1106
|
+
destinationRoot: "/tmp/install",
|
|
1128
1107
|
overwrite: "force",
|
|
1129
1108
|
}));
|
|
1130
|
-
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path:
|
|
1109
|
+
expect(platformMocks.writeArtifacts).toHaveBeenCalledWith([{ path: "/tmp/install/AGENTS.md", content: "# agents repaired" }], { dryRun: false, overwrite: "force" });
|
|
1131
1110
|
expect(platformMocks.writePlatformInstallReceiptForPlan).toHaveBeenCalled();
|
|
1132
1111
|
});
|
|
1133
1112
|
it("prints platform doctor health and issues", async () => {
|
|
@@ -1186,8 +1165,7 @@ describe("platform CLI", () => {
|
|
|
1186
1165
|
logSpy.mockRestore();
|
|
1187
1166
|
});
|
|
1188
1167
|
it("prints resolved install targets via platform where", async () => {
|
|
1189
|
-
|
|
1190
|
-
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", codexRoot, [{ path: join(codexRoot, "AGENTS.md"), content: "# agents" }], "global"));
|
|
1168
|
+
platformMocks.createCodexInstallPlan.mockReturnValue(createInstallPlan("codex", "/home/test/.codex", [{ path: "/home/test/.codex/AGENTS.md", content: "# agents" }], "global"));
|
|
1191
1169
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
1192
1170
|
root: "/home/test/.codex",
|
|
1193
1171
|
source: "official-global",
|
|
@@ -1206,7 +1184,7 @@ describe("platform CLI", () => {
|
|
|
1206
1184
|
mode: "where",
|
|
1207
1185
|
target: "codex",
|
|
1208
1186
|
scope: "global",
|
|
1209
|
-
root:
|
|
1187
|
+
root: "/home/test/.codex",
|
|
1210
1188
|
rootSource: "official-global",
|
|
1211
1189
|
capability: expect.objectContaining({
|
|
1212
1190
|
namespace: "zc",
|
|
@@ -1216,13 +1194,12 @@ describe("platform CLI", () => {
|
|
|
1216
1194
|
logSpy.mockRestore();
|
|
1217
1195
|
});
|
|
1218
1196
|
it("resolves qwen global scope to the user-level ~/.qwen directory", async () => {
|
|
1219
|
-
const qwenRoot = abs("/home/test/.qwen");
|
|
1220
1197
|
platformMocks.createQwenInstallPlan.mockReturnValue({
|
|
1221
1198
|
platform: "qwen",
|
|
1222
1199
|
packageName: "@zmice/platform-qwen",
|
|
1223
1200
|
manifestSource: "/repo/packages/toolkit/src/content#generatedAt=2026-04-19T12:00:00.000Z",
|
|
1224
1201
|
matchedAssets: [],
|
|
1225
|
-
destinationRoot:
|
|
1202
|
+
destinationRoot: "/home/test/.qwen",
|
|
1226
1203
|
scope: "global",
|
|
1227
1204
|
overwrite: "error",
|
|
1228
1205
|
capability: {
|
|
@@ -1234,7 +1211,7 @@ describe("platform CLI", () => {
|
|
|
1234
1211
|
agentsDir: "agents",
|
|
1235
1212
|
extensionDir: "extensions/zc-toolkit",
|
|
1236
1213
|
},
|
|
1237
|
-
artifacts: [{ path:
|
|
1214
|
+
artifacts: [{ path: "/home/test/.qwen/extensions/zc-toolkit/QWEN.md", content: "# context" }],
|
|
1238
1215
|
});
|
|
1239
1216
|
platformMocks.resolveInstallTarget.mockResolvedValue({
|
|
1240
1217
|
root: "/home/test/.qwen",
|
|
@@ -1248,7 +1225,7 @@ describe("platform CLI", () => {
|
|
|
1248
1225
|
mode: "where",
|
|
1249
1226
|
target: "qwen",
|
|
1250
1227
|
scope: "global",
|
|
1251
|
-
root:
|
|
1228
|
+
root: "/home/test/.qwen",
|
|
1252
1229
|
rootSource: "official-global",
|
|
1253
1230
|
hint: "Qwen 官方文档定义用户级配置目录为 `~/.qwen`,并在官方帮助文档中给出 Qwen CLI 的用户级 `QWEN.md` 位置为 `~/.qwen/QWEN.md`。",
|
|
1254
1231
|
}));
|