@tacuchi/agent-workflow-cli 20.23.0 → 20.25.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.
Files changed (137) hide show
  1. package/README.md +34 -11
  2. package/dist/application/context/budget-service.js +128 -0
  3. package/dist/application/context/budget-service.js.map +1 -0
  4. package/dist/application/context/bundle-root.js +41 -0
  5. package/dist/application/context/bundle-root.js.map +1 -0
  6. package/dist/application/context/manifest.js +150 -0
  7. package/dist/application/context/manifest.js.map +1 -0
  8. package/dist/application/context/measure.js +227 -0
  9. package/dist/application/context/measure.js.map +1 -0
  10. package/dist/application/context/plan-service.js +177 -0
  11. package/dist/application/context/plan-service.js.map +1 -0
  12. package/dist/application/dev-only-services.js +17 -14
  13. package/dist/application/dev-only-services.js.map +1 -1
  14. package/dist/application/mcp-host-reader.js +3 -1
  15. package/dist/application/mcp-host-reader.js.map +1 -1
  16. package/dist/application/mcp-host-writer.js +86 -41
  17. package/dist/application/mcp-host-writer.js.map +1 -1
  18. package/dist/application/plugin-doctor/hooks.js +7 -1
  19. package/dist/application/plugin-doctor/hooks.js.map +1 -1
  20. package/dist/application/self/bootstrap.js +30 -16
  21. package/dist/application/self/bootstrap.js.map +1 -1
  22. package/dist/application/self/clean-legacy.js +5 -0
  23. package/dist/application/self/clean-legacy.js.map +1 -1
  24. package/dist/application/self/detect-hosts.js +31 -45
  25. package/dist/application/self/detect-hosts.js.map +1 -1
  26. package/dist/application/self/doctor-self.js +7 -2
  27. package/dist/application/self/doctor-self.js.map +1 -1
  28. package/dist/application/self/hooks-toml.js +232 -0
  29. package/dist/application/self/hooks-toml.js.map +1 -0
  30. package/dist/application/self/host-states.js +290 -0
  31. package/dist/application/self/host-states.js.map +1 -0
  32. package/dist/application/self/install-hooks.js +98 -4
  33. package/dist/application/self/install-hooks.js.map +1 -1
  34. package/dist/application/self/install-skill.js +28 -16
  35. package/dist/application/self/install-skill.js.map +1 -1
  36. package/dist/application/self/install-targets.js +23 -0
  37. package/dist/application/self/install-targets.js.map +1 -1
  38. package/dist/application/self/mcp-config.js +13 -19
  39. package/dist/application/self/mcp-config.js.map +1 -1
  40. package/dist/application/self/skills-manager.js +9 -0
  41. package/dist/application/self/skills-manager.js.map +1 -1
  42. package/dist/application/self/uninstall.js +162 -26
  43. package/dist/application/self/uninstall.js.map +1 -1
  44. package/dist/cli/commands/context-budget.js +79 -0
  45. package/dist/cli/commands/context-budget.js.map +1 -0
  46. package/dist/cli/commands/context-plan.js +75 -0
  47. package/dist/cli/commands/context-plan.js.map +1 -0
  48. package/dist/cli/commands/dev-only.js +4 -1
  49. package/dist/cli/commands/dev-only.js.map +1 -1
  50. package/dist/cli/commands/index.js +4 -0
  51. package/dist/cli/commands/index.js.map +1 -1
  52. package/dist/cli/commands/mcp.js +16 -8
  53. package/dist/cli/commands/mcp.js.map +1 -1
  54. package/dist/cli/help-groups.js +4 -0
  55. package/dist/cli/help-groups.js.map +1 -1
  56. package/dist/cli/parser.js +4 -0
  57. package/dist/cli/parser.js.map +1 -1
  58. package/dist/cli/tui/components/host-admin-section.js +69 -60
  59. package/dist/cli/tui/components/host-admin-section.js.map +1 -1
  60. package/dist/cli/tui/data/workflow-content.js +6 -0
  61. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  62. package/dist/cli/tui/hosts.js +39 -17
  63. package/dist/cli/tui/hosts.js.map +1 -1
  64. package/dist/cli/tui/tabs/config-tab.js +3 -3
  65. package/dist/cli/tui/tabs/config-tab.js.map +1 -1
  66. package/dist/cli/tui/tabs/mcp-tab-helpers.js +7 -1
  67. package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
  68. package/dist/cli/tui/tabs/mcp-tab.js +32 -10
  69. package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
  70. package/dist/cli/tui/tabs/skills-tab.js +13 -4
  71. package/dist/cli/tui/tabs/skills-tab.js.map +1 -1
  72. package/dist/cli/tui/tabs/status-tab.js +11 -17
  73. package/dist/cli/tui/tabs/status-tab.js.map +1 -1
  74. package/dist/cli/tui/tabs/workflow-tab.js +7 -3
  75. package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
  76. package/dist/cli/tui/tui-prefs.js +7 -1
  77. package/dist/cli/tui/tui-prefs.js.map +1 -1
  78. package/dist/domain/harnesses.js +129 -0
  79. package/dist/domain/harnesses.js.map +1 -1
  80. package/dist/domain/host-verification.js +20 -0
  81. package/dist/domain/host-verification.js.map +1 -0
  82. package/package.json +3 -2
  83. package/skills/w/SKILL.md +2 -2
  84. package/skills/w/commands/export-diagrams.md +10 -27
  85. package/skills/w/commands/export-manuals.md +13 -29
  86. package/skills/w/commands/export-reports.md +11 -27
  87. package/skills/w/commands/export-scripts.md +12 -29
  88. package/skills/w/commands/fix-git.md +21 -32
  89. package/skills/w/commands/generate-launch.md +13 -32
  90. package/skills/w/commands/persist.md +8 -29
  91. package/skills/w/commands/plan-exec.md +14 -30
  92. package/skills/w/commands/plan-new.md +11 -38
  93. package/skills/w/commands/plan-refine.md +13 -41
  94. package/skills/w/commands/quick.md +13 -20
  95. package/skills/w/commands/resume.md +17 -33
  96. package/skills/w/commands/spec-new.md +28 -69
  97. package/skills/w/commands/spec-refine.md +12 -37
  98. package/skills/w/commands/status.md +12 -19
  99. package/skills/w/commands/workspace-init.md +13 -20
  100. package/skills/w/context/MANIFEST.json +486 -0
  101. package/skills/w/harness/HARNESS.md +24 -17
  102. package/skills/w/loops/CHASSIS.md +53 -104
  103. package/skills/w/loops/CODE-POLICIES.md +4 -9
  104. package/skills/w/loops/plan-exec-loop/LOOP.md +5 -12
  105. package/skills/w/loops/plan-new-loop/LOOP.md +8 -32
  106. package/skills/w/loops/plan-refine-loop/LOOP.md +8 -36
  107. package/skills/w/loops/quick-loop/LOOP.md +4 -10
  108. package/skills/w/loops/spec-refine-loop/LOOP.md +7 -49
  109. package/skills/w/modules/ADOPTED-CONTEXT.md +10 -0
  110. package/skills/w/modules/COMPACTION.md +13 -0
  111. package/skills/w/modules/DB-RESEARCH-RULE.md +11 -0
  112. package/skills/w/modules/DB-SCRIPTS-ONLY.md +12 -0
  113. package/skills/w/modules/EXEC-DB-POLICY.md +7 -0
  114. package/skills/w/modules/EXEC-PROBE-TASKS.md +11 -0
  115. package/skills/w/modules/IDEATION-GATE.md +16 -0
  116. package/skills/w/modules/INCREMENTAL-STRATEGY.md +7 -0
  117. package/skills/w/modules/LAUNCH-DETECTION.md +26 -0
  118. package/skills/w/modules/PERSIST-ROUTING.md +16 -0
  119. package/skills/w/modules/PLAN-DESIGN-SPECS.md +12 -0
  120. package/skills/w/modules/PLAN-INPUT.md +26 -0
  121. package/skills/w/modules/PLAN-MODE.md +26 -0
  122. package/skills/w/modules/PLAN-PROBE-TASKS.md +10 -0
  123. package/skills/w/modules/PLAN-REFINE-DESIGN-SPECS.md +7 -0
  124. package/skills/w/modules/PLAN-REFINE-KEYS.md +9 -0
  125. package/skills/w/modules/PLAN-REFINE-SPLIT.md +12 -0
  126. package/skills/w/modules/PLAN-SPLIT-GATE.md +14 -0
  127. package/skills/w/modules/PROBE.md +12 -0
  128. package/skills/w/modules/PROMPT-CONTINUITY.md +13 -0
  129. package/skills/w/modules/RECONNAISSANCE.md +48 -0
  130. package/skills/w/modules/REPLANNING.md +12 -0
  131. package/skills/w/modules/SESSION-NUMBERING.md +19 -0
  132. package/skills/w/modules/SIMULATION-LIFECYCLE.md +11 -0
  133. package/skills/w/modules/SPEC-CHANGE-SHAPE.md +37 -0
  134. package/skills/w/modules/SPEC-REFINE-KEYS.md +14 -0
  135. package/skills/w/modules/SPLIT-GATE.md +42 -0
  136. package/skills/w/modules/WORKSPACE-SCAFFOLD.md +28 -0
  137. package/skills/w/roles/ui-spec/ROLE.md +1 -1
@@ -0,0 +1,290 @@
1
+ // Observable host states — the single place that answers "what is really true
2
+ // about this host on this machine".
3
+ //
4
+ // Detection used to be one boolean (`~/.<host>` exists?) doing four jobs at
5
+ // once, so a leftover config dir read as a live host and a host that exports no
6
+ // env marker read as absent. The four states are now separate and each one
7
+ // carries its evidence:
8
+ //
9
+ // 1. config present — the host's config dir exists on disk
10
+ // 2. runtime available — its binary can actually be invoked (NOT env markers:
11
+ // several hosts export none to their subprocesses)
12
+ // 3. Workline installed — our bundle is in that host's skills root
13
+ // 4. capabilities — which Workline mechanisms this host can really use
14
+ //
15
+ // Shared destinations (`~/.agents/skills`) are reported apart: they have no
16
+ // runtime and must never inflate a host count (spec 010, criterion 3).
17
+ import { dirname, join } from "node:path";
18
+ import { parse as parseToml } from "smol-toml";
19
+ import { HARNESSES, SHARED_SKILL_DESTINATIONS, verificationFor, } from "../../domain/harnesses.js";
20
+ import { crushGlobalMcpFile, opencodeGlobalMcpFile } from "../mcp-host-paths.js";
21
+ import { resolveWarpGlobalMcpPath } from "../multiroot/warp.js";
22
+ import { countOurHookEntries } from "./hooks-toml.js";
23
+ import { SKILL_DIR_NAME, USER_COMMANDS_BY_TARGET } from "./install-skill.js";
24
+ import { COMMAND_SKILLS_HOSTS, TARGET_ROOTS } from "./install-targets.js";
25
+ /** Upper bound for a single `--version` call. Probes run in parallel across hosts. */
26
+ const RUNTIME_PROBE_TIMEOUT_MS = 2500;
27
+ function expandHome(path, home) {
28
+ return path.startsWith("~") ? join(home, path.slice(1)) : path;
29
+ }
30
+ /**
31
+ * Global config dir for a host, or null when it keeps none of its own.
32
+ * Platform-divergent hosts derive it from their global MCP path — the same
33
+ * registry the MCP writer and reader use, never a second source.
34
+ */
35
+ export function resolveHostConfigDir(spec, home) {
36
+ if (spec.configDir.kind === "dir")
37
+ return { path: expandHome(spec.configDir.path, home) };
38
+ if (spec.configDir.kind === "none")
39
+ return { path: null, reason: spec.configDir.reason };
40
+ if (spec.id === "opencode")
41
+ return { path: dirname(opencodeGlobalMcpFile(home)) };
42
+ if (spec.id === "crush")
43
+ return { path: dirname(crushGlobalMcpFile(home)) };
44
+ if (spec.id === "warp") {
45
+ const mcpFile = resolveWarpGlobalMcpPath(process.platform, () => home);
46
+ return mcpFile
47
+ ? { path: dirname(mcpFile) }
48
+ : { path: null, reason: "no global MCP path on this platform" };
49
+ }
50
+ return { path: null, reason: "no config dir resolver for this host" };
51
+ }
52
+ /** First `<major>.<minor>…` token in the output — covers every host's `--version` shape. */
53
+ export function extractVersion(output) {
54
+ return /\d+\.\d+[\w.\-+]*/.exec(output)?.[0] ?? null;
55
+ }
56
+ /**
57
+ * Is the runtime actually invocable? Looks for the binary (PATH first, then the
58
+ * locations the catalog declares — Kimi installs to `~/.kimi-code/bin`, which
59
+ * only interactive shells add) and reads its version.
60
+ */
61
+ export async function probeRuntime(spec, ctx) {
62
+ const { bins, fallbackBinPaths = [], versionArgs } = spec.runtime;
63
+ if (bins.length === 0) {
64
+ return {
65
+ state: "not-probeable",
66
+ bin: null,
67
+ version: null,
68
+ evidence: `${spec.label} ships no CLI of its own — presence is judged by its config dir.`,
69
+ };
70
+ }
71
+ const home = ctx.env.homeDir();
72
+ let found = null;
73
+ for (const bin of bins) {
74
+ const resolved = await ctx.process.which(bin);
75
+ if (resolved !== undefined) {
76
+ found = { bin: resolved, how: `'${bin}' on PATH` };
77
+ break;
78
+ }
79
+ }
80
+ if (found === null) {
81
+ for (const candidate of fallbackBinPaths) {
82
+ const abs = expandHome(candidate, home);
83
+ if (await ctx.fs.exists(abs)) {
84
+ found = { bin: abs, how: `declared path ${candidate} (not on PATH)` };
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ if (found === null) {
90
+ const where = [`PATH (${bins.join(", ")})`, ...fallbackBinPaths].join(" · ");
91
+ return { state: "missing", bin: null, version: null, evidence: `not found in ${where}` };
92
+ }
93
+ try {
94
+ const res = await ctx.process.run(found.bin, [...versionArgs], {
95
+ timeoutMs: RUNTIME_PROBE_TIMEOUT_MS,
96
+ });
97
+ const version = extractVersion(`${res.stdout}\n${res.stderr}`);
98
+ return {
99
+ state: "available",
100
+ bin: found.bin,
101
+ version,
102
+ evidence: version === null
103
+ ? `${found.how}; ran ${versionArgs.join(" ")} but no version in its output`
104
+ : `${found.how}; reported ${version}`,
105
+ };
106
+ }
107
+ catch (err) {
108
+ // The binary IS there — a failed version call does not make the host absent.
109
+ return {
110
+ state: "available",
111
+ bin: found.bin,
112
+ version: null,
113
+ evidence: `${found.how}; version probe failed: ${err.message}`,
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Which Workline mechanisms this host can really use. Every row is DERIVED from
119
+ * the catalog and the installer's own maps, so no surface can announce a
120
+ * capability the installer does not implement (spec 010, criterion 6).
121
+ */
122
+ export function capabilitiesFor(spec) {
123
+ const commands = USER_COMMANDS_BY_TARGET[spec.installTarget];
124
+ return [
125
+ {
126
+ id: "skills",
127
+ status: "native",
128
+ detail: `auto-discovered from ${spec.skillsDirs.join(", ")}`,
129
+ },
130
+ commands !== null
131
+ ? { id: "commands", status: "native", detail: `~/${commands.relpath} (${commands.format})` }
132
+ : COMMAND_SKILLS_HOSTS.has(spec.installTarget)
133
+ ? {
134
+ id: "commands",
135
+ status: "degraded",
136
+ detail: "no commands dir: each command ships as a top-level 'w-<command>' skill next to the bundle",
137
+ }
138
+ : {
139
+ id: "commands",
140
+ status: "unsupported",
141
+ detail: "no commands dir and no skill-as-command wrappers installed for this host",
142
+ },
143
+ spec.hooks === null
144
+ ? { id: "hooks", status: "unsupported", detail: "this host has no hook system" }
145
+ : spec.hooks.managed
146
+ ? { id: "hooks", status: "native", detail: `installed into ${spec.hooks.mechanism}` }
147
+ : {
148
+ id: "hooks",
149
+ status: "degraded",
150
+ detail: `host supports hooks (${spec.hooks.mechanism}); Workline does not install them here — the CLI commands stay callable`,
151
+ },
152
+ spec.mcpHostId === null
153
+ ? {
154
+ id: "mcp",
155
+ status: "degraded",
156
+ detail: "no MCP config file: this host takes servers through a launch flag",
157
+ }
158
+ : { id: "mcp", status: "native", detail: `written to its ${spec.mcpHostId} MCP config` },
159
+ ];
160
+ }
161
+ function deriveStatus(present, runtime, installed) {
162
+ // A CLI-less host cannot be probed, so its config dir IS the presence signal.
163
+ const here = runtime.state === "available" || (runtime.state === "not-probeable" && present);
164
+ if (here)
165
+ return installed ? "ready" : "installable";
166
+ return present ? "residual-config" : "absent";
167
+ }
168
+ function deriveAdvice(status, spec, configPath) {
169
+ if (status === "installable") {
170
+ return `Run 'agent-workflow self install-skill --target ${spec.installTarget}' to install the bundle.`;
171
+ }
172
+ if (status === "residual-config") {
173
+ return `Config dir ${configPath ?? "(unknown)"} exists but no ${spec.label} runtime answers. Reinstall the host, or run 'agent-workflow self uninstall --target ${spec.installTarget}' to clear what Workline left there.`;
174
+ }
175
+ return null;
176
+ }
177
+ /** Full state report for one host. */
178
+ export async function reportHostState(spec, ctx) {
179
+ const home = ctx.env.homeDir();
180
+ const config = resolveHostConfigDir(spec, home);
181
+ const worklinePath = join(home, ...TARGET_ROOTS[spec.installTarget], SKILL_DIR_NAME);
182
+ const [configPresent, installed, runtime] = await Promise.all([
183
+ config.path === null ? Promise.resolve(false) : ctx.fs.exists(config.path),
184
+ ctx.fs.exists(worklinePath),
185
+ probeRuntime(spec, ctx),
186
+ ]);
187
+ const status = deriveStatus(configPresent, runtime, installed);
188
+ return {
189
+ host: spec.id,
190
+ target: spec.installTarget,
191
+ label: spec.label,
192
+ tier: spec.support.tier,
193
+ unstable_surface: spec.support.unstableSurface === true,
194
+ verified: verificationFor(spec.id),
195
+ config: {
196
+ present: configPresent,
197
+ path: config.path,
198
+ ...(config.reason ? { reason: config.reason } : {}),
199
+ },
200
+ runtime,
201
+ workline: { installed, path: worklinePath },
202
+ capabilities: capabilitiesFor(spec),
203
+ status,
204
+ advice: deriveAdvice(status, spec, config.path),
205
+ };
206
+ }
207
+ /** State report for every host in the catalog. Probes run in parallel. */
208
+ export async function reportAllHostStates(ctx) {
209
+ return Promise.all(HARNESSES.map((spec) => reportHostState(spec, ctx)));
210
+ }
211
+ /**
212
+ * Per-host "are OUR hooks in place" probes. Only hosts whose hooks Workline
213
+ * MANAGES appear here — `hooksArmedProbeCoverage()` proves the two sets match,
214
+ * so a host can never be declared managed while nothing can tell whether its
215
+ * hooks are actually armed.
216
+ */
217
+ const HOOKS_ARMED_PROBES = {
218
+ claude: async (ctx, home) => {
219
+ const path = join(home, ".claude", "settings.json");
220
+ return { armed: await claudeHooksArmed(ctx, path), path };
221
+ },
222
+ kimi: async (ctx, home) => {
223
+ // Read through a real TOML parse, NOT by looking for our comment markers:
224
+ // Kimi rewrites this file on its own and drops every comment while keeping
225
+ // the hooks. Marker-based detection reported "off" while our hooks were live.
226
+ const path = join(home, ".kimi-code", "config.toml");
227
+ if (!(await ctx.fs.exists(path)))
228
+ return { armed: false, path };
229
+ try {
230
+ const ours = countOurHookEntries(await ctx.fs.readText(path), parseToml);
231
+ return { armed: (ours ?? 0) > 0, path };
232
+ }
233
+ catch {
234
+ return { armed: false, path };
235
+ }
236
+ },
237
+ };
238
+ /**
239
+ * A non-empty `hooks{}` is NOT enough: the user may keep hooks of their own.
240
+ * Ours are the entries whose command invokes this CLI.
241
+ */
242
+ async function claudeHooksArmed(ctx, path) {
243
+ if (!(await ctx.fs.exists(path)))
244
+ return false;
245
+ try {
246
+ const parsed = JSON.parse(await ctx.fs.readText(path));
247
+ if (!parsed.hooks || Object.keys(parsed.hooks).length === 0)
248
+ return false;
249
+ return JSON.stringify(parsed.hooks).includes("agent-workflow");
250
+ }
251
+ catch {
252
+ return false;
253
+ }
254
+ }
255
+ /** Targets whose hooks Workline manages but that have no armed-probe. Must be empty. */
256
+ export function hooksArmedProbeCoverage() {
257
+ return HARNESSES.filter((h) => h.hooks?.managed === true)
258
+ .map((h) => h.installTarget)
259
+ .filter((t) => HOOKS_ARMED_PROBES[t] === undefined);
260
+ }
261
+ /** Hook state for every host whose hooks Workline manages. */
262
+ export async function reportHooksArmed(ctx) {
263
+ const home = ctx.env.homeDir();
264
+ const managed = HARNESSES.filter((h) => h.hooks?.managed === true);
265
+ return Promise.all(managed.map(async (spec) => {
266
+ const probe = HOOKS_ARMED_PROBES[spec.installTarget];
267
+ if (probe === undefined) {
268
+ // Guarded by hooksArmedProbeCoverage(); reported, never guessed.
269
+ return { target: spec.installTarget, label: spec.label, armed: false, path: "(no probe)" };
270
+ }
271
+ const { armed, path } = await probe(ctx, home);
272
+ return { target: spec.installTarget, label: spec.label, armed, path };
273
+ }));
274
+ }
275
+ /** Shared skills dirs — install destinations, never hosts. */
276
+ export async function reportSharedDestinations(ctx) {
277
+ const home = ctx.env.homeDir();
278
+ return Promise.all(SHARED_SKILL_DESTINATIONS.map(async (dest) => {
279
+ const path = join(home, ...TARGET_ROOTS[dest.id], SKILL_DIR_NAME);
280
+ return {
281
+ target: dest.id,
282
+ label: dest.label,
283
+ path,
284
+ installed: await ctx.fs.exists(path),
285
+ read_by: dest.readBy.map((id) => HARNESSES.find((h) => h.id === id)?.label ?? id),
286
+ note: "Shared skills dir, not a host: it has no runtime and never counts as one.",
287
+ };
288
+ }));
289
+ }
290
+ //# sourceMappingURL=host-states.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-states.js","sourceRoot":"","sources":["../../../src/application/self/host-states.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,14 @@
1
1
  import { copyFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import { isDeepStrictEqual } from "node:util";
4
+ import { hooksTemplateToToml, upsertManagedHooksBlock } from "./hooks-toml.js";
4
5
  import { INSTALL_TARGETS, SKILL_DIR_NAME, findUpward, } from "./install-skill.js";
6
+ import { HOOKS_MANAGED_TARGETS } from "./install-targets.js";
5
7
  // Every install target is a valid --target; hooks merge-into-config is only
6
8
  // implemented for claude, so the rest resolve to an explanatory "unsupported"
7
9
  // result (not a generic INVALID_TARGET). Derived from INSTALL_TARGETS so a new
8
10
  // host can't silently fall into the invalid bucket (the clean-legacy lesson).
9
11
  const HOOK_TARGET_CHOICES = INSTALL_TARGETS;
10
- const SUPPORTED_HOOK_TARGETS = new Set(["claude"]);
11
12
  export async function selfInstallHooks(args, ctx, resolveTemplate = resolveBundledHookTemplate) {
12
13
  const dryRun = args.flags.has("--dry-run");
13
14
  const targetArg = args.values.get("target");
@@ -32,7 +33,7 @@ export async function selfInstallHooks(args, ctx, resolveTemplate = resolveBundl
32
33
  };
33
34
  }
34
35
  const target = targetArg;
35
- if (!SUPPORTED_HOOK_TARGETS.has(target)) {
36
+ if (!HOOKS_MANAGED_TARGETS.has(target)) {
36
37
  return {
37
38
  ok: true,
38
39
  data: {
@@ -42,7 +43,7 @@ export async function selfInstallHooks(args, ctx, resolveTemplate = resolveBundl
42
43
  events_installed: [],
43
44
  events_already_present: [],
44
45
  backup_path: null,
45
- warning: `Hooks via merge-into-config are not yet implemented for host '${target}'. Currently supported: claude. Other hosts use file-based or no-hook mechanisms.`,
46
+ warning: `Workline does not manage hooks on '${target}'. Managed hosts: ${[...HOOKS_MANAGED_TARGETS].join(", ")}. The rest use file-based or no-hook mechanisms.`,
46
47
  },
47
48
  exitCode: 0,
48
49
  };
@@ -94,8 +95,101 @@ export async function selfInstallHooks(args, ctx, resolveTemplate = resolveBundl
94
95
  exitCode: 1,
95
96
  };
96
97
  }
97
- return installClaudeHooks(ctx, target, template, dryRun);
98
+ return installHooksFor(target, ctx, template, dryRun);
98
99
  }
100
+ /**
101
+ * Per-host hook installers. A host in `HOOKS_MANAGED_TARGETS` MUST have one —
102
+ * `hookInstallerCoverage()` proves it, so "managed" can never mean "declared
103
+ * managed and quietly doing nothing".
104
+ */
105
+ const HOOK_INSTALLERS = {
106
+ claude: installClaudeHooks,
107
+ kimi: installKimiHooks,
108
+ };
109
+ /** Managed targets with no installer wired. Must be empty. */
110
+ export function hookInstallerCoverage() {
111
+ return [...HOOKS_MANAGED_TARGETS].filter((t) => HOOK_INSTALLERS[t] === undefined);
112
+ }
113
+ function installHooksFor(target, ctx, template, dryRun) {
114
+ const installer = HOOK_INSTALLERS[target];
115
+ if (installer === undefined) {
116
+ return Promise.resolve({
117
+ ok: false,
118
+ error: {
119
+ code: "HOOKS_INSTALLER_MISSING",
120
+ message: `'${target}' is declared as a hooks-managed host but has no installer wired. This is a bug in the CLI, not in your setup.`,
121
+ },
122
+ exitCode: 1,
123
+ });
124
+ }
125
+ return installer(ctx, target, template, dryRun);
126
+ }
127
+ /**
128
+ * Kimi Code keeps hooks in `[[hooks]]` tables inside its USER-GLOBAL
129
+ * `config.toml` — there is no project-level config to write instead (verified
130
+ * against v0.29.2 plus a live probe). Our entries live inside a marked block so
131
+ * everything the user wrote around it survives install, reinstall and uninstall
132
+ * untouched, and the file is backed up before any write.
133
+ */
134
+ async function installKimiHooks(ctx, target, template, dryRun) {
135
+ const configPath = join(ctx.env.homeDir(), ".kimi-code", "config.toml");
136
+ const existing = (await ctx.fs.exists(configPath)) ? await ctx.fs.readText(configPath) : "";
137
+ const { entries, skipped } = hooksTemplateToToml(template);
138
+ const eventsInstalled = [...new Set(entries.map((e) => e.event))];
139
+ const next = upsertManagedHooksBlock(existing, entries).text;
140
+ const warning = skipped.length > 0
141
+ ? `Not expressible in Kimi Code and therefore skipped: ${skipped
142
+ .map((s) => `${s.event} (${s.reason})`)
143
+ .join("; ")}.`
144
+ : undefined;
145
+ if (next === existing) {
146
+ return {
147
+ ok: true,
148
+ data: {
149
+ status: "noop",
150
+ target,
151
+ config_path: configPath,
152
+ events_installed: [],
153
+ events_already_present: eventsInstalled,
154
+ backup_path: null,
155
+ ...(warning ? { warning } : {}),
156
+ },
157
+ exitCode: 0,
158
+ };
159
+ }
160
+ if (dryRun) {
161
+ return {
162
+ ok: true,
163
+ data: {
164
+ status: "dry-run",
165
+ target,
166
+ config_path: configPath,
167
+ events_installed: eventsInstalled,
168
+ events_already_present: [],
169
+ backup_path: null,
170
+ ...(warning ? { warning } : {}),
171
+ },
172
+ exitCode: 0,
173
+ };
174
+ }
175
+ await ctx.fs.mkdirp(dirname(configPath));
176
+ const backup = await tryBackup(configPath, ctx);
177
+ await ctx.fs.writeText(configPath, next);
178
+ return {
179
+ ok: true,
180
+ data: {
181
+ status: "installed",
182
+ target,
183
+ config_path: configPath,
184
+ events_installed: eventsInstalled,
185
+ events_already_present: [],
186
+ backup_path: backup,
187
+ ...(warning ? { warning } : {}),
188
+ },
189
+ exitCode: 0,
190
+ };
191
+ }
192
+ /** Claude Code: JSON merge into `~/.claude/settings.json` → `hooks{}`. */
99
193
  async function installClaudeHooks(ctx, target, template, dryRun) {
100
194
  const settingsPath = join(ctx.env.homeDir(), ".claude", "settings.json");
101
195
  let existingData = {};
@@ -1 +1 @@
1
- {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../../src/application/self/install-hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../../src/application/self/install-hooks.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,9 @@ import { mkdir, readFile, rm, rmdir, stat, writeFile } from "node:fs/promises";
2
2
  import { readdir } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { harnessByInstallTarget } from "../../domain/harnesses.js";
5
6
  import { copyDir, hasValidFrontmatter } from "./install-plugin-skills.js";
6
- import { COMMAND_SKILLS_HOSTS, INSTALL_TARGETS, LEGACY_SKILL_ROOTS_BY_TARGET, TARGET_ROOTS, } from "./install-targets.js";
7
+ import { COMMAND_SKILLS_HOSTS, HOOKS_MANAGED_TARGETS, HOST_INSTALL_TARGETS, INSTALL_TARGETS, LEGACY_SKILL_ROOTS_BY_TARGET, SHARED_INSTALL_TARGETS, TARGET_ROOTS, } from "./install-targets.js";
7
8
  import { selfClearPluginCache } from "./plugin-cache-clear.js";
8
9
  export const SKILL_DIR_NAME = "w";
9
10
  export const BUNDLED_SKILL_REL_PATH = `skills/${SKILL_DIR_NAME}`;
@@ -17,8 +18,12 @@ export const AGENTS_LOCK_REL = [".agents", ".skill-lock.json"];
17
18
  */
18
19
  export const LEGACY_SKILL_NAMES = ["agent-workflow-manager", "agent-workflow"];
19
20
  const TARGET_CHOICES = [...INSTALL_TARGETS, "all"];
20
- // `--target all` skips `agents`: it is the shared cross-host dir, not a host.
21
- const ALL_INSTALL_TARGETS = INSTALL_TARGETS.filter((t) => t !== "agents");
21
+ // `--target all` means EVERY HOST shared skills dirs are destinations, not
22
+ // hosts, and are reached explicitly with `--target agents`. `uninstall` uses the
23
+ // same rule, so the round trip matches: what `all` installs is what `all`
24
+ // removes. (Note that `oz` installs INTO the shared root, so that dir is still
25
+ // covered under `all` through its host — see TARGET_ROOTS.)
26
+ const ALL_INSTALL_TARGETS = HOST_INSTALL_TARGETS;
22
27
  const CACHE_CLEAR_HOSTS = new Set([
23
28
  "claude",
24
29
  "codex",
@@ -56,6 +61,8 @@ export const USER_COMMANDS_BY_TARGET = {
56
61
  gemini: { relpath: ".gemini/commands/w", format: "gemini-toml" },
57
62
  opencode: { relpath: ".opencode/command/w", format: "opencode-md" },
58
63
  crush: { relpath: ".crush/commands/w", format: "crush-md" },
64
+ // kimi: skills ARE the command surface (`/skill:w-<cmd>`) — no commands dir.
65
+ kimi: null,
59
66
  };
60
67
  // Stale user-commands dirs from prior releases, removed on install/uninstall:
61
68
  // the pre-`w`-rename namespace (`/agent-workflow:*`) everywhere, plus the
@@ -70,6 +77,7 @@ const LEGACY_USER_COMMANDS_RELPATHS_BY_TARGET = {
70
77
  gemini: [],
71
78
  opencode: [],
72
79
  crush: [],
80
+ kimi: [],
73
81
  };
74
82
  /** rmdir succeeds only on empty dirs — clears purposeless leftovers (e.g. the
75
83
  * inert ~/.codex/commands parent once its w/ subdir is gone) while anything
@@ -166,10 +174,6 @@ async function cleanLegacyArtifacts(target, home, ctx) {
166
174
  }
167
175
  return removed;
168
176
  }
169
- // Hosts where install-hooks merges into a user-level config (JSON/TOML).
170
- // Codex has a different config format (TOML) and no settled hook syntax at
171
- // the user level yet — see DEC-W4 for Warp/OZ (no hook system at all).
172
- const HOOKS_AUTOINSTALL_TARGETS = new Set(["claude"]);
173
177
  function explainSkipReason(target, kind) {
174
178
  if (kind === "commands") {
175
179
  if (COMMAND_SKILLS_HOSTS.has(target)) {
@@ -177,14 +181,16 @@ function explainSkipReason(target, kind) {
177
181
  }
178
182
  return `${target}: shared cross-host skills dir, not a host — no command wrapper to install.`;
179
183
  }
180
- // hooks
181
- if (target === "warp" || target === "oz") {
182
- return `${target}: no hook system per DEC-W4. Skipped silently.`;
184
+ // hooks — the reason comes from the catalog, so it can never contradict what
185
+ // the host actually offers (it used to name warp/oz/codex by hand).
186
+ const spec = harnessByInstallTarget(target);
187
+ if (spec === null) {
188
+ return `${target}: shared cross-host skills dir, not a host — nothing to arm hooks on.`;
183
189
  }
184
- if (target === "codex") {
185
- return `codex: hook merge into config.toml not implemented yet (different format from Claude's settings.json). SKILL works without hooks; CLI commands still callable manually.`;
190
+ if (spec.hooks === null) {
191
+ return `${target}: this host has no hook system. Skipped silently.`;
186
192
  }
187
- return `${target}: hooks auto-install not supported yet.`;
193
+ return `${target}: hooks live in ${spec.hooks.mechanism}, which Workline does not write yet. The SKILL works without them and the CLI commands stay callable manually.`;
188
194
  }
189
195
  export async function selfInstallSkill(args, ctx, resolveBundled = resolveBundledSkillPath) {
190
196
  const force = args.flags.has("--force");
@@ -211,7 +217,7 @@ export async function selfInstallSkill(args, ctx, resolveBundled = resolveBundle
211
217
  ok: false,
212
218
  error: {
213
219
  code: "CONFIRM_ALL_REQUIRED",
214
- message: `--target all installs into every supported host. Pass --confirm-all to acknowledge, or pick a specific host (${ALL_INSTALL_TARGETS.join("|")}).`,
220
+ message: `--target all installs into every HOST (${ALL_INSTALL_TARGETS.join("|")}) and leaves the shared skills dirs alone (${SHARED_INSTALL_TARGETS.join("|")} — install those explicitly). Pass --confirm-all to acknowledge, or pick a specific target.`,
215
221
  },
216
222
  exitCode: 1,
217
223
  };
@@ -614,7 +620,7 @@ async function installUserCommands(target, sourceSkillPath, ctx) {
614
620
  return { installed: true, dest: destDir, files_copied: copied };
615
621
  }
616
622
  async function installHooksForTarget(target, ctx) {
617
- if (!HOOKS_AUTOINSTALL_TARGETS.has(target)) {
623
+ if (!HOOKS_MANAGED_TARGETS.has(target)) {
618
624
  return {
619
625
  status: "skipped",
620
626
  warning: explainSkipReason(target, "hooks"),
@@ -633,7 +639,13 @@ async function installHooksForTarget(target, ctx) {
633
639
  if (!result.ok) {
634
640
  return { status: "error", warning: result.error?.message ?? "unknown error" };
635
641
  }
636
- return { status: result.data?.status ?? "unknown" };
642
+ // Carry the hook installer's warning through. Dropping it meant a Kimi user
643
+ // was told "installed" with no hint that the PostCompact prompt hook — the
644
+ // one that resumes the loop after a compact — cannot exist on that host.
645
+ return {
646
+ status: result.data?.status ?? "unknown",
647
+ ...(result.data?.warning ? { warning: result.data.warning } : {}),
648
+ };
637
649
  }
638
650
  catch (err) {
639
651
  return { status: "exception", warning: err.message };