@alpsckr/unitycli 0.4.1 → 0.4.2

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 (36) hide show
  1. package/README.md +15 -12
  2. package/contracts/init-contract.json +11 -4
  3. package/contracts/package-files.json +3 -3
  4. package/dist/cli-commands/init-discovery.d.ts +9 -2
  5. package/dist/cli-commands/init-discovery.js +60 -50
  6. package/dist/cli-commands/init-discovery.js.map +1 -1
  7. package/dist/cli-commands/init-help.js +13 -9
  8. package/dist/cli-commands/init-help.js.map +1 -1
  9. package/dist/cli-commands/init-skill.d.ts +1 -1
  10. package/dist/cli-commands/init-skill.js +92 -26
  11. package/dist/cli-commands/init-skill.js.map +1 -1
  12. package/dist/cli-commands/package.js +59 -12
  13. package/dist/cli-commands/package.js.map +1 -1
  14. package/dist/cli-commands/skill-installer.d.ts +15 -7
  15. package/dist/cli-commands/skill-installer.js +106 -66
  16. package/dist/cli-commands/skill-installer.js.map +1 -1
  17. package/dist/cli-commands/types.d.ts +3 -0
  18. package/dist/cli.js +5 -3
  19. package/dist/cli.js.map +1 -1
  20. package/dist/package-manager.d.ts +5 -1
  21. package/dist/package-manager.js +21 -9
  22. package/dist/package-manager.js.map +1 -1
  23. package/dist/unity-project-processes.d.ts +7 -0
  24. package/dist/unity-project-processes.js +54 -0
  25. package/dist/unity-project-processes.js.map +1 -1
  26. package/docs/architecture.md +3 -3
  27. package/docs/error-codes.md +16 -0
  28. package/docs/extensions.md +3 -1
  29. package/package.json +1 -1
  30. package/schemas/init.schema.json +95 -10
  31. package/skills/unitycli/SKILL.md +1 -1
  32. package/skills/unitycli/manifest.json +1 -1
  33. package/skills/unitycli/references/operation-protocol.md +1 -1
  34. package/skills/unitycli/reports/output_quality_scorecard.md +1 -1
  35. package/skills/unitycli/reports/trust-report.md +1 -1
  36. package/unitypkg/package.json +1 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@ Windows-first Unity Editor automation CLI for AI agents. The executable is `unit
8
8
  - Node.js 20 or newer
9
9
  - Unity 2022.3 or newer
10
10
  - A Unity project when installing the Bridge
11
- - An opened Unity Editor only when using live Unity capabilities; installation does not start or stop Unity
11
+ - An opened Unity Editor only when using live Unity capabilities; installation may normally close only the exact target Editor after explicit user approval
12
12
 
13
13
  ## Install
14
14
 
@@ -22,14 +22,7 @@ Start your AI in the directory where you normally work and tell it:
22
22
 
23
23
  > 执行 unitycli init help,然后照做。
24
24
 
25
- `init help` contains the complete AI installation protocol. The AI first runs read-only discovery, then asks you:
26
-
27
- - which discovered Unity projects should receive the Bridge;
28
- - whether the Skill target is generic Agent Skills (`.agents`) or Claude;
29
- - whether the Skill belongs to one workspace or to the current user;
30
- - which directory is your normal AI workspace when workspace scope is selected.
31
-
32
- The AI does not silently choose these values. Multiple Bridge projects are installed one at a time. Installation does not start, close, restart, or terminate Unity.
25
+ `init help` contains the complete AI installation protocol. Read-only discovery uses the unique current Unity project and workspace without asking you to repeat them, reports the installed and available Bridge versions, and accepts any exact Skill directory you already named. It asks only when a real choice remains, including permission to normally close the exact target Unity Editor before replacing an in-use Bridge. It never force-terminates Unity or decides an unsaved-scene prompt.
33
26
 
34
27
  ## Manual Setup
35
28
 
@@ -40,14 +33,22 @@ unitycli init help
40
33
  unitycli init discover
41
34
  ```
42
35
 
43
- Install or repair the Bridge in one explicit Unity project:
36
+ Install or repair the Bridge in one explicit Unity project. Use `--close-editor` only after the user approves normally closing that exact project:
44
37
 
45
38
  ```powershell
46
39
  unitycli init package --project C:\path\UnityProject
40
+ unitycli init package --project C:\path\UnityProject --close-editor
47
41
  unitycli init package --project C:\path\UnityProject --check
48
42
  ```
49
43
 
50
- Install or check generic Agent Skills in one workspace:
44
+ Install or check an exact user-selected Skill directory, including Pi:
45
+
46
+ ```powershell
47
+ unitycli init skill --target C:\path\Workspace\.pi\skills\unitycli
48
+ unitycli init skill --target C:\path\Workspace\.pi\skills\unitycli --check
49
+ ```
50
+
51
+ Generic Agent Skills remain available as a preset:
51
52
 
52
53
  ```powershell
53
54
  unitycli init skill --agent .agents --scope workspace --workspace C:\path\Workspace
@@ -71,7 +72,7 @@ unitycli init skill --agent claude --scope user
71
72
  unitycli init skill --agent claude --scope user --check
72
73
  ```
73
74
 
74
- Workspace and user scope are separate choices. UnityCLI does not install both automatically. A workspace can be the parent of one or more Unity projects.
75
+ Preset workspace and user scope are separate choices. An exact `--target` is final user intent and cannot be combined with preset agent/scope options. Bridge and Skill are independently authorized effects; failure of one does not invalidate or block the other.
75
76
 
76
77
  ## Verify And Diagnose
77
78
 
@@ -79,6 +80,7 @@ Package and Skill checks are read-only:
79
80
 
80
81
  ```powershell
81
82
  unitycli init package --project C:\path\UnityProject --check
83
+ unitycli init skill --target C:\path\Workspace\.pi\skills\unitycli --check
82
84
  unitycli init skill --agent .agents --scope workspace --workspace C:\path\Workspace --check
83
85
  ```
84
86
 
@@ -161,6 +163,7 @@ unitycli init help
161
163
  To remove a workspace or user Skill, delete only the selected `unitycli` Skill directory:
162
164
 
163
165
  ```text
166
+ <explicit-target>/unitycli
164
167
  <workspace>/.agents/skills/unitycli
165
168
  <workspace>/.claude/skills/unitycli
166
169
  ~/.agents/skills/unitycli
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": 1,
2
+ "version": 2,
3
3
  "topLevel": "init",
4
4
  "schema": "schemas/init.schema.json",
5
5
  "subcommands": {
@@ -12,6 +12,7 @@
12
12
  "package": {
13
13
  "options": [
14
14
  "project",
15
+ "close-editor",
15
16
  "check",
16
17
  "timeout-ms"
17
18
  ],
@@ -31,12 +32,18 @@
31
32
  "agent",
32
33
  "scope",
33
34
  "workspace",
35
+ "target",
34
36
  "check",
35
37
  "timeout-ms"
36
38
  ],
37
- "required": [
38
- "agent",
39
- "scope"
39
+ "requiredAnyOf": [
40
+ [
41
+ "target"
42
+ ],
43
+ [
44
+ "agent",
45
+ "scope"
46
+ ]
40
47
  ],
41
48
  "agents": [
42
49
  ".agents",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "packageName": "com.alpsckr.unitycli",
4
- "packageVersion": "0.4.1",
5
- "sourceHash": "a8eda19a9815e4bd522fe3fab9411f1a1387edf7e863a086a62d7e429b866b87",
4
+ "packageVersion": "0.4.2",
5
+ "sourceHash": "3849b321c2e4793eec4ec7368c27a58a167913e1b92903a2b1c53f6578193d61",
6
6
  "files": [
7
7
  {
8
8
  "path": "Editor/Bridge/BridgeCommandContext.cs",
@@ -1947,7 +1947,7 @@
1947
1947
  {
1948
1948
  "path": "package.json",
1949
1949
  "size": 268,
1950
- "sha256": "d4bb4b63708abe75ac76b8428141a227ae0eefc4819e5e946152fb5b61f2d28d"
1950
+ "sha256": "35d9fba8bf248922183ec5dd3f70d4fafb66ef3ffab59f9adf4ccc549ed2f9fd"
1951
1951
  }
1952
1952
  ]
1953
1953
  }
@@ -1,4 +1,11 @@
1
+ import { type PackageBridgeInspection } from "../package-manager.js";
1
2
  import type { CliResult } from "../types.js";
2
- export declare function discoverInitEnvironment(cwdInput: string, userHomeInput: string): Promise<Record<string, unknown>>;
3
+ import type { Runtime } from "./types.js";
4
+ export interface InitDiscoveryRuntime {
5
+ findUnityProjectProcesses?: Runtime["findUnityProjectProcesses"];
6
+ inspectPackageBridge?: (projectPath: string) => Promise<PackageBridgeInspection>;
7
+ }
8
+ /** 当前项目常见路径返回完整安装计划;多项目搜索只保留选择所需信息。 */
9
+ export declare function discoverInitEnvironment(cwdInput: string, userHomeInput: string, runtime?: InitDiscoveryRuntime): Promise<Record<string, unknown>>;
3
10
  /** 从当前工作目录有界发现安装现场,不修改文件或进程。 */
4
- export declare function handleInitDiscover(args: string[], flags: Record<string, string | boolean>, requestId: string): Promise<CliResult>;
11
+ export declare function handleInitDiscover(args: string[], flags: Record<string, string | boolean>, runtime: Runtime, requestId: string): Promise<CliResult>;
@@ -1,12 +1,14 @@
1
1
  import { lstat, readFile, readdir, realpath, stat } from "node:fs/promises";
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { homedir } from "node:os";
4
+ import { inspectPackageBridge } from "../package-manager.js";
5
+ import { resolveProjectIdentityAsync } from "../project-identity.js";
4
6
  import { failure, success } from "../output.js";
7
+ import { findUnityProjectProcesses } from "../unity-project-processes.js";
5
8
  import { findSkillSourcePath, inspectSkillTarget, resolveSkillTarget } from "./skill-installer.js";
6
9
  const maxDescendantDepth = 4;
7
10
  const maxScannedDirectories = 2000;
8
11
  const maxUnityProjects = 100;
9
- const maxWorkspaceCandidates = 20;
10
12
  const ignoredDirectories = new Set([".git", "node_modules", "library", "temp", "logs", "obj"]);
11
13
  async function directoryExists(path) { try {
12
14
  return (await stat(path)).isDirectory();
@@ -65,7 +67,9 @@ async function discoverUnityProjects(cwd) {
65
67
  };
66
68
  let ancestor = cwd;
67
69
  for (let depth = 0; depth < 64; depth += 1) {
68
- add(await unityProjectCandidate(ancestor, depth === 0 ? "cwd" : "ancestor", depth));
70
+ const candidate = await unityProjectCandidate(ancestor, depth === 0 ? "cwd" : "ancestor", depth);
71
+ if (candidate)
72
+ return { projects: [candidate], scannedDirectories: 0, truncated: false };
69
73
  const parent = dirname(ancestor);
70
74
  if (parent === ancestor)
71
75
  break;
@@ -104,69 +108,75 @@ async function discoverUnityProjects(cwd) {
104
108
  projects.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
105
109
  return { projects, scannedDirectories: Math.min(scannedDirectories, maxScannedDirectories), truncated };
106
110
  }
107
- function workspaceCandidates(cwd, repositoryRoot, projects) {
108
- const values = [{ path: cwd, reason: "current-working-directory" }];
109
- if (repositoryRoot && pathIdentity(repositoryRoot) !== pathIdentity(cwd))
110
- values.push({ path: repositoryRoot, reason: "repository-root" });
111
- for (const project of projects)
112
- values.push({ path: dirname(project.path), reason: "unity-project-parent" });
113
- const seen = new Set();
114
- return values.filter((item) => { const id = pathIdentity(item.path); if (seen.has(id) || seen.size >= maxWorkspaceCandidates)
115
- return false; seen.add(id); return true; });
116
- }
117
- export async function discoverInitEnvironment(cwdInput, userHomeInput) {
111
+ /** 当前项目常见路径返回完整安装计划;多项目搜索只保留选择所需信息。 */
112
+ export async function discoverInitEnvironment(cwdInput, userHomeInput, runtime = {}) {
118
113
  const cwd = await realpath(resolve(cwdInput));
119
- const userHome = await realpath(resolve(userHomeInput));
114
+ await realpath(resolve(userHomeInput));
120
115
  const repositoryRoot = await findRepositoryRoot(cwd);
121
116
  const discovery = await discoverUnityProjects(cwd);
122
- const workspaces = workspaceCandidates(cwd, repositoryRoot, discovery.projects);
123
- const sourcePath = await findSkillSourcePath();
124
- const copies = [];
125
- for (const workspace of workspaces)
126
- for (const agent of [".agents", "claude"]) {
127
- const targetPath = resolveSkillTarget(workspace.path, agent);
128
- copies.push({ scope: "workspace", workspace: workspace.path, agent, ...await inspectSkillTarget(sourcePath, targetPath) });
117
+ const inspectBridge = runtime.inspectPackageBridge ?? inspectPackageBridge;
118
+ const findEditors = runtime.findUnityProjectProcesses ?? findUnityProjectProcesses;
119
+ const inspectLiveState = discovery.projects.length === 1;
120
+ const unityProjects = [];
121
+ for (const project of discovery.projects) {
122
+ let bridge = { status: "not-inspected" };
123
+ let editor = { status: "not-inspected" };
124
+ if (inspectLiveState) {
125
+ try {
126
+ const inspection = await inspectBridge(project.path);
127
+ bridge = {
128
+ status: inspection.status,
129
+ availableVersion: inspection.availableVersion,
130
+ ...(inspection.installedVersion ? { installedVersion: inspection.installedVersion } : {}),
131
+ ...(inspection.reasonCode ? { reasonCode: inspection.reasonCode } : {}),
132
+ };
133
+ }
134
+ catch {
135
+ bridge = { status: "unverifiable", reasonCode: "INIT_BRIDGE_STATE_UNVERIFIABLE" };
136
+ }
137
+ try {
138
+ const identity = await resolveProjectIdentityAsync(project.path, { timeoutMs: 3_000 });
139
+ const processes = await findEditors(identity.instanceId, identity.canonicalProjectPath, 3_000);
140
+ editor = { status: processes.length ? "running" : "stopped", processCount: processes.length };
141
+ }
142
+ catch {
143
+ editor = { status: "unverifiable" };
144
+ }
129
145
  }
130
- for (const agent of [".agents", "claude"]) {
131
- const targetPath = resolveSkillTarget(userHome, agent);
132
- copies.push({ scope: "user", agent, ...await inspectSkillTarget(sourcePath, targetPath) });
146
+ unityProjects.push({ ...project, bridge, editor });
147
+ }
148
+ const sourcePath = await findSkillSourcePath();
149
+ const recommendedTarget = resolveSkillTarget(cwd, ".agents");
150
+ const recommendedSkill = await inspectSkillTarget(sourcePath, recommendedTarget);
151
+ const requiredDecisions = [];
152
+ if (unityProjects.length > 1) {
153
+ requiredDecisions.push({ id: "bridgeProjects", question: "Which discovered Unity projects should receive the UnityCLI Bridge?", choices: unityProjects.map((project) => project.path), multiple: true });
154
+ }
155
+ else if ((unityProjects[0]?.editor?.status) === "running") {
156
+ requiredDecisions.push({ id: "closeEditor", question: "May UnityCLI normally close the exact target Unity project before Bridge installation?", projectPath: unityProjects[0].path, multiple: false });
133
157
  }
134
- const shadowingRisks = [".agents", "claude"].flatMap((agent) => {
135
- const matches = copies.filter((copy) => copy.agent === agent && copy.status !== "missing");
136
- if (matches.length < 2)
137
- return [];
138
- return [{
139
- skill: "unitycli",
140
- agent,
141
- precedence: agent === "claude" ? ["user", "workspace"] : ["workspace", "user"],
142
- copies: matches,
143
- note: agent === "claude" ? "Claude personal skills override workspace skills." : "Generic Agent Skills commonly prefer workspace skills over user skills.",
144
- }];
145
- });
146
158
  return {
147
- action: "init_discover", cwd, repositoryRoot: repositoryRoot ?? null,
148
- limits: { maxDescendantDepth, maxScannedDirectories, maxUnityProjects, maxWorkspaceCandidates },
149
- scan: { scannedDirectories: discovery.scannedDirectories, truncated: discovery.truncated },
150
- unityProjects: discovery.projects, skillWorkspaces: workspaces, skillCopies: copies,
151
- shadowingRisks,
152
- requiredDecisions: [
153
- { id: "bridgeProjects", question: "Which discovered Unity projects should receive the UnityCLI Bridge?", choices: discovery.projects.map((project) => project.path), multiple: true },
154
- { id: "skillAgent", question: "Which Skill host should be configured?", choices: [".agents", "claude"], multiple: false },
155
- { id: "skillScope", question: "Should the Skill be installed for one workspace or for the current user?", choices: ["workspace", "user"], multiple: false },
156
- { id: "skillWorkspace", question: "If workspace scope is selected, which directory is the user's normal AI working directory?", choices: workspaces.map((workspace) => workspace.path), multiple: false },
157
- ],
158
- nextActions: ["Ask the user every required decision before running any installation effect.", "Use the exact command templates returned by `unitycli init help` after the user answers."],
159
+ action: "init_discover",
160
+ cwd,
161
+ repositoryRoot: repositoryRoot ?? null,
162
+ unityProjects,
163
+ skill: { workspace: cwd, recommendedTarget, explicitTargetSupported: true, ...recommendedSkill },
164
+ requiredDecisions,
165
+ ...(discovery.scannedDirectories > 0 || discovery.truncated ? { scan: { scannedDirectories: discovery.scannedDirectories, truncated: discovery.truncated, maxDescendantDepth, maxScannedDirectories, maxUnityProjects } } : {}),
166
+ nextActions: requiredDecisions.length
167
+ ? ["Ask only the returned required decisions; keep any target the user already specified."]
168
+ : ["Use the unique current project and the user's explicit Skill target, or the recommended workspace target when none was specified."],
159
169
  };
160
170
  }
161
171
  /** 从当前工作目录有界发现安装现场,不修改文件或进程。 */
162
- export async function handleInitDiscover(args, flags, requestId) {
172
+ export async function handleInitDiscover(args, flags, runtime, requestId) {
163
173
  if (args.length)
164
174
  return failure(requestId, "E_INIT_ARGUMENT_UNEXPECTED", "init discover does not accept positional arguments.", ["Run `unitycli init discover` without additional arguments."]);
165
175
  const unknown = Object.keys(flags).find((name) => name !== "pretty");
166
176
  if (unknown)
167
177
  return failure(requestId, "E_UNKNOWN_OPTION", `Unknown option for init discover: --${unknown}.`, ["Run `unitycli init discover` without options."], { option: `--${unknown}` });
168
178
  try {
169
- return success(requestId, await discoverInitEnvironment(process.cwd(), homedir()));
179
+ return success(requestId, await discoverInitEnvironment(process.cwd(), homedir(), { findUnityProjectProcesses: runtime.findUnityProjectProcesses }));
170
180
  }
171
181
  catch (error) {
172
182
  return failure(requestId, "INIT_DISCOVERY_FAILED", error instanceof Error ? error.message : String(error), ["Run `unitycli init discover` from an existing readable working directory."]);
@@ -1 +1 @@
1
- {"version":3,"file":"init-discovery.js","sourceRoot":"","sources":["../../src/cli-commands/init-discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init-discovery.js","sourceRoot":"","sources":["../../src/cli-commands/init-discovery.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,10 @@ import { failure, success } from "../output.js";
2
2
  const commands = {
3
3
  discover: "unitycli init discover",
4
4
  packageInstall: "unitycli init package --project <UnityProject>",
5
+ packageInstallAndCloseEditor: "unitycli init package --project <UnityProject> --close-editor",
5
6
  packageCheck: "unitycli init package --project <UnityProject> --check",
7
+ explicitSkillInstall: "unitycli init skill --target <SkillDirectory>",
8
+ explicitSkillCheck: "unitycli init skill --target <SkillDirectory> --check",
6
9
  workspaceSkillInstall: "unitycli init skill --agent <.agents|claude> --scope workspace --workspace <path>",
7
10
  workspaceSkillCheck: "unitycli init skill --agent <.agents|claude> --scope workspace --workspace <path> --check",
8
11
  userSkillInstall: "unitycli init skill --agent <.agents|claude> --scope user",
@@ -18,16 +21,17 @@ export function handleInitHelp(args, flags, requestId) {
18
21
  return success(requestId, {
19
22
  action: "init_help",
20
23
  audience: "ai",
21
- protocolVersion: 1,
24
+ protocolVersion: 2,
22
25
  aiInstructions: [
23
- "Run `unitycli init discover` from the user's current working directory before making installation decisions.",
24
- "Use discovery.requiredDecisions to ask the user which discovered Unity projects should receive the Bridge and which single Skill agent/scope/workspace target should be configured; do not infer or silently choose these values.",
25
- "For multiple selected Unity projects, run one `init package` call at a time in strict serial order. Wait for and verify each terminal result before submitting the next call.",
26
- "Install the UnityCLI Skill only once at the user-selected `.agents` or Claude workspace/user target unless the user explicitly requests more targets.",
27
- "After every successful package or Skill installation, run the corresponding command with `--check` and verify its business status.",
28
- "Stop immediately after the first unexpected CLI failure or failed business check. Report that terminal result and do not retry, change parameters, or continue with later installation effects.",
29
- "Do not start, close, restart, or terminate Unity Editor as part of installation. Package import occurs when the user next opens or refreshes the selected project.",
30
- "CLI installation calls are the authorized effects after the user answers the required decisions; do not add another confirmation gate.",
26
+ "Run `unitycli init discover` from the user's current working directory and use its compact current-project plan.",
27
+ "Treat every project, scope, host, or Skill directory the user already specified as final; never ask them to choose it again. Use `init skill --target` for an explicit directory such as `.pi/skills/unitycli`.",
28
+ "When discovery returns one current or ancestor Unity project, use it without another project-selection question. Ask only entries present in discovery.requiredDecisions.",
29
+ "If the exact target Unity project is running, ask once whether it may be closed normally. After approval use `init package --close-editor`; never force-terminate Unity or decide an unsaved-scene prompt for the user.",
30
+ "Bridge and Skill installation are independent authorized effects. A failure blocks only that effect and its check; continue other user-authorized independent installation effects and report every final status.",
31
+ "Run one corresponding `--check` after each successful package or Skill installation and verify its business status.",
32
+ "For a recoverable installation error, follow its exact nextActions after the required external state changes. Do not create unbounded retries or change the user's selected targets.",
33
+ "Do not start or restart Unity Editor during installation. Normal close is allowed only for the exact project and only through the explicitly authorized --close-editor package call.",
34
+ "The user's installation request authorizes the selected package and Skill effects; do not add confirmation gates except the separate close-Editor decision.",
31
35
  ],
32
36
  commands,
33
37
  nextCommand: commands.discover,
@@ -1 +1 @@
1
- {"version":3,"file":"init-help.js","sourceRoot":"","sources":["../../src/cli-commands/init-help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,QAAQ,GAAG;IACf,QAAQ,EAAE,wBAAwB;IAClC,cAAc,EAAE,gDAAgD;IAChE,YAAY,EAAE,wDAAwD;IACtE,qBAAqB,EAAE,mFAAmF;IAC1G,mBAAmB,EAAE,2FAA2F;IAChH,gBAAgB,EAAE,2DAA2D;IAC7E,cAAc,EAAE,mEAAmE;CAC3E,CAAC;AAEX,8BAA8B;AAC9B,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,KAAuC,EAAE,SAAiB;IACvG,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC,SAAS,EAAE,4BAA4B,EAAE,iDAAiD,EAAE,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACxL,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACrE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,mCAAmC,OAAO,GAAG,EAAE,CAAC,2CAA2C,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,OAAO,EAAE,EAAE,CAAC,CAAC;IACrL,OAAO,OAAO,CAAC,SAAS,EAAE;QACxB,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,IAAI;QACd,eAAe,EAAE,CAAC;QAClB,cAAc,EAAE;YACd,8GAA8G;YAC9G,mOAAmO;YACnO,+KAA+K;YAC/K,uJAAuJ;YACvJ,oIAAoI;YACpI,iMAAiM;YACjM,oKAAoK;YACpK,wIAAwI;SACzI;QACD,QAAQ;QACR,WAAW,EAAE,QAAQ,CAAC,QAAQ;QAC9B,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;KACjC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"init-help.js","sourceRoot":"","sources":["../../src/cli-commands/init-help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,QAAQ,GAAG;IACf,QAAQ,EAAE,wBAAwB;IAClC,cAAc,EAAE,gDAAgD;IAChE,4BAA4B,EAAE,+DAA+D;IAC7F,YAAY,EAAE,wDAAwD;IACtE,oBAAoB,EAAE,+CAA+C;IACrE,kBAAkB,EAAE,uDAAuD;IAC3E,qBAAqB,EAAE,mFAAmF;IAC1G,mBAAmB,EAAE,2FAA2F;IAChH,gBAAgB,EAAE,2DAA2D;IAC7E,cAAc,EAAE,mEAAmE;CAC3E,CAAC;AAEX,8BAA8B;AAC9B,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,KAAuC,EAAE,SAAiB;IACvG,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC,SAAS,EAAE,4BAA4B,EAAE,iDAAiD,EAAE,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACxL,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACrE,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,mCAAmC,OAAO,GAAG,EAAE,CAAC,2CAA2C,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,OAAO,EAAE,EAAE,CAAC,CAAC;IACrL,OAAO,OAAO,CAAC,SAAS,EAAE;QACxB,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,IAAI;QACd,eAAe,EAAE,CAAC;QAClB,cAAc,EAAE;YACd,kHAAkH;YAClH,iNAAiN;YACjN,2KAA2K;YAC3K,yNAAyN;YACzN,mNAAmN;YACnN,qHAAqH;YACrH,sLAAsL;YACtL,sLAAsL;YACtL,6JAA6J;SAC9J;QACD,QAAQ;QACR,WAAW,EAAE,QAAQ,CAAC,QAAQ;QAC9B,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;KACjC,CAAC,CAAC;AACL,CAAC"}
@@ -6,5 +6,5 @@ export declare function resolveInitSkillTarget(agent: AgentKind, scope: SkillSco
6
6
  basePath: string;
7
7
  targetPath: string;
8
8
  };
9
- /** 安装或只读检查一个明确 agent/scope Skill target。 */
9
+ /** 安装或只读检查一个预设agent目标或用户明确给出的精确Skill目录。 */
10
10
  export declare function handleInitSkill(args: string[], flags: Record<string, string | boolean>, runtime: Runtime, requestId: string): Promise<CliResult>;
@@ -1,9 +1,9 @@
1
1
  import { lstat, realpath, rm } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
- import { join, resolve } from "node:path";
3
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { getBoolean, getString } from "../args.js";
5
5
  import { failure, success } from "../output.js";
6
- import { agentSkillInstaller, findSkillSourcePath, inspectSkillTarget, parseAgentList, resolveSkillTarget, SkillInstallerError } from "./skill-installer.js";
6
+ import { agentSkillInstaller, findSkillSourcePath, inspectSkillTarget, installSkillTarget, parseAgentList, resolveSkillTarget, SkillInstallerError } from "./skill-installer.js";
7
7
  export function resolveInitSkillTarget(agent, scope, workspace, userHome) {
8
8
  const basePath = scope === "user" ? resolve(userHome) : resolve(workspace);
9
9
  return { basePath, targetPath: resolveSkillTarget(basePath, agent) };
@@ -41,43 +41,110 @@ function timeout(flags) {
41
41
  const value = Number(raw);
42
42
  return Number.isSafeInteger(value) && value > 0 ? value : undefined;
43
43
  }
44
- /** 安装或只读检查一个明确 agent/scope Skill target。 */
44
+ /** 明确目标允许尚未创建,但所有既有祖先必须是真实目录且入口名固定为unitycli。 */
45
+ async function resolveExplicitSkillTarget(raw) {
46
+ const targetPath = resolve(raw);
47
+ if (basename(targetPath).toLowerCase() !== "unitycli") {
48
+ throw new SkillInstallerError("E_INIT_SKILL_TARGET_INVALID", "init skill --target must name the exact unitycli Skill directory.", ["Pass a path ending in the `unitycli` directory, such as `.pi/skills/unitycli`."]);
49
+ }
50
+ if (process.platform === "win32" && !/^[a-z]:\\/i.test(targetPath)) {
51
+ throw new SkillInstallerError("E_INIT_SKILL_TARGET_INVALID", "init skill --target must resolve to a fixed local Windows path.", ["Use a local drive path for the exact UnityCLI Skill directory."]);
52
+ }
53
+ if (targetPath.split(/[\\/]/).some((segment) => segment === ".unitycli-install")) {
54
+ throw new SkillInstallerError("E_INIT_SKILL_TARGET_INVALID", "init skill --target cannot be inside the installer transaction directory.", ["Choose the final UnityCLI Skill directory outside `.unitycli-install`."]);
55
+ }
56
+ let current = targetPath;
57
+ while (true) {
58
+ try {
59
+ const info = await lstat(current);
60
+ if (info.isSymbolicLink() || !info.isDirectory()) {
61
+ throw new SkillInstallerError("E_SKILL_TARGET_UNSAFE", `Skill target ancestors must be real directories: ${current}`, ["Replace the linked or non-directory target ancestor before retrying."]);
62
+ }
63
+ }
64
+ catch (error) {
65
+ if (error.code !== "ENOENT")
66
+ throw error;
67
+ }
68
+ const parent = dirname(current);
69
+ if (parent === current)
70
+ break;
71
+ current = parent;
72
+ }
73
+ return targetPath;
74
+ }
75
+ function pathContains(parent, child) {
76
+ const fromParent = relative(parent, child);
77
+ return fromParent === "" || (!fromParent.startsWith("..") && !isAbsolute(fromParent));
78
+ }
79
+ /** bundled source与target不得互相包含,避免安装事务改写自己的准源。 */
80
+ function rejectSkillSourceOverlap(sourcePath, targetPath) {
81
+ const sourceRoot = resolve(dirname(sourcePath));
82
+ const targetRoot = resolve(targetPath);
83
+ const normalize = (value) => process.platform === "win32" ? value.toLowerCase() : value;
84
+ const sourceIdentity = normalize(sourceRoot);
85
+ const targetIdentity = normalize(targetRoot);
86
+ if (pathContains(sourceIdentity, targetIdentity) || pathContains(targetIdentity, sourceIdentity)) {
87
+ throw new SkillInstallerError("E_SKILL_TARGET_OVERLAPS_SOURCE", "The selected Skill target overlaps the bundled UnityCLI Skill source.", ["Choose a separate installed Skill directory."]);
88
+ }
89
+ }
90
+ /** 安装或只读检查一个预设agent目标或用户明确给出的精确Skill目录。 */
45
91
  export async function handleInitSkill(args, flags, runtime, requestId) {
46
92
  if (args.length)
47
93
  return failure(requestId, "E_INIT_ARGUMENT_UNEXPECTED", "init skill does not accept positional arguments.", ["Run `unitycli init skill` using only documented options."]);
48
94
  const agentRaw = getString(flags, "agent");
49
95
  const scopeRaw = getString(flags, "scope");
50
- if (!agentRaw)
51
- return failure(requestId, "E_INIT_AGENT_REQUIRED", "init skill requires --agent <.agents|claude>.", ["Choose the Skill host after asking the user."], { option: "--agent" });
52
- let agent;
53
- try {
54
- const agents = parseAgentList(agentRaw);
55
- if (agents.length !== 1)
56
- throw new SkillInstallerError("E_INIT_AGENT_INVALID", "init skill accepts exactly one agent target.", ["Pass either --agent .agents or --agent claude."]);
57
- agent = agents[0];
58
- }
59
- catch (error) {
60
- if (error instanceof SkillInstallerError)
61
- return failure(requestId, error.code, error.message, error.nextActions);
62
- throw error;
63
- }
64
- if (scopeRaw !== "workspace" && scopeRaw !== "user")
65
- return failure(requestId, "E_INIT_SCOPE_INVALID", "init skill requires --scope <workspace|user>.", ["Ask the user whether this Skill belongs to one workspace or the current user."], { option: "--scope", actual: scopeRaw ?? null });
66
- const scope = scopeRaw;
67
96
  const workspaceRaw = getString(flags, "workspace");
68
- if (scope === "workspace" && !workspaceRaw)
69
- return failure(requestId, "E_INIT_WORKSPACE_REQUIRED", "Workspace Skill scope requires --workspace <path>.", ["Pass the user's normal AI working directory."], { option: "--workspace" });
70
- if (scope === "user" && workspaceRaw)
71
- return failure(requestId, "E_INIT_WORKSPACE_FORBIDDEN", "User Skill scope does not accept --workspace.", ["Remove --workspace or choose --scope workspace."], { option: "--workspace" });
97
+ const explicitTargetRaw = getString(flags, "target");
98
+ if (explicitTargetRaw && (agentRaw || scopeRaw || workspaceRaw)) {
99
+ return failure(requestId, "E_INIT_SKILL_TARGET_CONFLICT", "init skill --target cannot be combined with --agent, --scope, or --workspace.", ["Use either one exact --target directory or one preset agent/scope target."], { option: "--target" });
100
+ }
101
+ if (!explicitTargetRaw && !agentRaw)
102
+ return failure(requestId, "E_INIT_SKILL_TARGET_REQUIRED", "init skill requires either --target <SkillDirectory> or --agent <.agents|claude> with --scope.", ["Use the user's explicit Skill directory when provided; otherwise choose one preset host."], { options: ["--target", "--agent"] });
72
103
  const timeoutMs = timeout(flags);
73
104
  if (timeoutMs === undefined)
74
105
  return failure(requestId, "E_INIT_TIMEOUT_INVALID", "init skill --timeout-ms must be a positive integer.", ["Pass --timeout-ms <positive-integer>."], { option: "--timeout-ms" });
106
+ const deadlineMs = Date.now() + timeoutMs;
75
107
  try {
108
+ const sourcePath = await findSkillSourcePath();
109
+ if (explicitTargetRaw) {
110
+ const targetPath = await resolveExplicitSkillTarget(explicitTargetRaw);
111
+ rejectSkillSourceOverlap(sourcePath, targetPath);
112
+ const installCommand = `unitycli init skill --target ${JSON.stringify(targetPath)}`;
113
+ if (getBoolean(flags, "check")) {
114
+ const inspection = await inspectSkillTarget(sourcePath, targetPath);
115
+ return success(requestId, { action: "init_skill_check", target: targetPath, skill: inspection, nextActions: inspection.status === "installed" ? [] : [installCommand] });
116
+ }
117
+ const installRoot = join(dirname(targetPath), ".unitycli-install");
118
+ const change = await installSkillTarget(sourcePath, targetPath, installRoot, deadlineMs);
119
+ const inspection = await inspectSkillTarget(sourcePath, targetPath);
120
+ if (inspection.status !== "installed")
121
+ throw new SkillInstallerError("E_SKILL_INSTALL_PROJECTION_INVALID", "Skill installation did not reach an installed readback state.", ["Inspect the reported target before retrying."]);
122
+ await rm(installRoot, { recursive: true, force: true });
123
+ return success(requestId, { action: "init_skill", target: targetPath, changes: [change], skill: inspection, nextActions: [`${installCommand} --check`] });
124
+ }
125
+ let agent;
126
+ try {
127
+ const agents = parseAgentList(agentRaw);
128
+ if (agents.length !== 1)
129
+ throw new SkillInstallerError("E_INIT_AGENT_INVALID", "init skill accepts exactly one preset agent target.", ["Pass either --agent .agents or --agent claude."]);
130
+ agent = agents[0];
131
+ }
132
+ catch (error) {
133
+ if (error instanceof SkillInstallerError)
134
+ return failure(requestId, error.code, error.message, error.nextActions);
135
+ throw error;
136
+ }
137
+ if (scopeRaw !== "workspace" && scopeRaw !== "user")
138
+ return failure(requestId, "E_INIT_SCOPE_INVALID", "Preset Skill installation requires --scope <workspace|user>.", ["Choose workspace for the current project or user for the current Windows account."], { option: "--scope", actual: scopeRaw ?? null });
139
+ const scope = scopeRaw;
140
+ if (scope === "workspace" && !workspaceRaw)
141
+ return failure(requestId, "E_INIT_WORKSPACE_REQUIRED", "Workspace Skill scope requires --workspace <path>.", ["Pass the user's normal AI working directory."], { option: "--workspace" });
142
+ if (scope === "user" && workspaceRaw)
143
+ return failure(requestId, "E_INIT_WORKSPACE_FORBIDDEN", "User Skill scope does not accept --workspace.", ["Remove --workspace or choose --scope workspace."], { option: "--workspace" });
76
144
  const baseCandidate = scope === "user" ? resolve(runtime.userHome ?? homedir()) : resolve(workspaceRaw);
77
145
  const basePath = await assertRealDirectory(baseCandidate, scope === "user" ? "User home" : "Workspace");
78
146
  await rejectLinkedTargetAncestors(basePath, agent);
79
147
  const targetPath = resolveSkillTarget(basePath, agent);
80
- const sourcePath = await findSkillSourcePath();
81
148
  if (getBoolean(flags, "check")) {
82
149
  const inspection = await inspectSkillTarget(sourcePath, targetPath);
83
150
  const installCommand = scope === "workspace"
@@ -88,7 +155,6 @@ export async function handleInitSkill(args, flags, runtime, requestId) {
88
155
  const installRoot = scope === "user"
89
156
  ? join(runtime.dataDir, ".temp", "skill-install", agent === ".agents" ? "agents" : agent)
90
157
  : join(basePath, agent === ".agents" ? ".agents" : ".claude", "skills", ".unitycli-install");
91
- const deadlineMs = Date.now() + timeoutMs;
92
158
  const changes = await agentSkillInstaller.installForAgents([agent], sourcePath, basePath, deadlineMs, installRoot);
93
159
  const inspection = await inspectSkillTarget(sourcePath, targetPath);
94
160
  if (inspection.status !== "installed")