@tacuchi/agent-workflow-cli 20.24.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 (63) hide show
  1. package/README.md +34 -11
  2. package/dist/application/dev-only-services.js +17 -14
  3. package/dist/application/dev-only-services.js.map +1 -1
  4. package/dist/application/mcp-host-reader.js +3 -1
  5. package/dist/application/mcp-host-reader.js.map +1 -1
  6. package/dist/application/mcp-host-writer.js +86 -41
  7. package/dist/application/mcp-host-writer.js.map +1 -1
  8. package/dist/application/plugin-doctor/hooks.js +7 -1
  9. package/dist/application/plugin-doctor/hooks.js.map +1 -1
  10. package/dist/application/self/bootstrap.js +30 -16
  11. package/dist/application/self/bootstrap.js.map +1 -1
  12. package/dist/application/self/clean-legacy.js +5 -0
  13. package/dist/application/self/clean-legacy.js.map +1 -1
  14. package/dist/application/self/detect-hosts.js +31 -45
  15. package/dist/application/self/detect-hosts.js.map +1 -1
  16. package/dist/application/self/doctor-self.js +7 -2
  17. package/dist/application/self/doctor-self.js.map +1 -1
  18. package/dist/application/self/hooks-toml.js +232 -0
  19. package/dist/application/self/hooks-toml.js.map +1 -0
  20. package/dist/application/self/host-states.js +290 -0
  21. package/dist/application/self/host-states.js.map +1 -0
  22. package/dist/application/self/install-hooks.js +98 -4
  23. package/dist/application/self/install-hooks.js.map +1 -1
  24. package/dist/application/self/install-skill.js +28 -16
  25. package/dist/application/self/install-skill.js.map +1 -1
  26. package/dist/application/self/install-targets.js +23 -0
  27. package/dist/application/self/install-targets.js.map +1 -1
  28. package/dist/application/self/mcp-config.js +13 -19
  29. package/dist/application/self/mcp-config.js.map +1 -1
  30. package/dist/application/self/skills-manager.js +9 -0
  31. package/dist/application/self/skills-manager.js.map +1 -1
  32. package/dist/application/self/uninstall.js +162 -26
  33. package/dist/application/self/uninstall.js.map +1 -1
  34. package/dist/cli/commands/dev-only.js +4 -1
  35. package/dist/cli/commands/dev-only.js.map +1 -1
  36. package/dist/cli/commands/mcp.js +16 -8
  37. package/dist/cli/commands/mcp.js.map +1 -1
  38. package/dist/cli/tui/components/host-admin-section.js +69 -60
  39. package/dist/cli/tui/components/host-admin-section.js.map +1 -1
  40. package/dist/cli/tui/data/workflow-content.js +6 -0
  41. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  42. package/dist/cli/tui/hosts.js +39 -17
  43. package/dist/cli/tui/hosts.js.map +1 -1
  44. package/dist/cli/tui/tabs/config-tab.js +3 -3
  45. package/dist/cli/tui/tabs/config-tab.js.map +1 -1
  46. package/dist/cli/tui/tabs/mcp-tab-helpers.js +7 -1
  47. package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
  48. package/dist/cli/tui/tabs/mcp-tab.js +32 -10
  49. package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
  50. package/dist/cli/tui/tabs/skills-tab.js +13 -4
  51. package/dist/cli/tui/tabs/skills-tab.js.map +1 -1
  52. package/dist/cli/tui/tabs/status-tab.js +11 -17
  53. package/dist/cli/tui/tabs/status-tab.js.map +1 -1
  54. package/dist/cli/tui/tabs/workflow-tab.js +7 -3
  55. package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
  56. package/dist/cli/tui/tui-prefs.js +7 -1
  57. package/dist/cli/tui/tui-prefs.js.map +1 -1
  58. package/dist/domain/harnesses.js +129 -0
  59. package/dist/domain/harnesses.js.map +1 -1
  60. package/dist/domain/host-verification.js +20 -0
  61. package/dist/domain/host-verification.js.map +1 -0
  62. package/package.json +3 -2
  63. package/skills/w/harness/HARNESS.md +23 -16
@@ -1,55 +1,41 @@
1
- import { dirname, join } from "node:path";
2
- import { crushGlobalMcpFile, opencodeGlobalMcpFile } from "../mcp-host-paths.js";
3
- import { resolveWarpGlobalMcpPath } from "../multiroot/warp.js";
4
- import { INSTALL_TARGETS, SKILL_DIR_NAME, TARGET_ROOTS, } from "./install-skill.js";
5
- // Config dirs that do NOT follow the ~/.<target> convention. OpenCode and Crush
6
- // resolve via mcp-host-paths.ts (XDG_CONFIG_HOME; crush win32 = LOCALAPPDATA);
7
- // Warp is platform-divergent (darwin ~/.warp, linux ~/.config/warp-terminal,
8
- // win32 %LOCALAPPDATA%/warp/Warp/config) and derives from the registry via
9
- // resolveWarpGlobalMcpPath — same source as the MCP writer/reader; the rest use
10
- // ~/.<target>.
11
- function overrideConfigDir(target, home) {
12
- if (target === "opencode")
13
- return dirname(opencodeGlobalMcpFile(home));
14
- if (target === "crush")
15
- return dirname(crushGlobalMcpFile(home));
16
- if (target === "warp") {
17
- const mcpFile = resolveWarpGlobalMcpPath(process.platform, () => home);
18
- return mcpFile ? dirname(mcpFile) : null;
19
- }
20
- return null;
21
- }
1
+ import { reportAllHostStates, reportSharedDestinations, } from "./host-states.js";
2
+ /**
3
+ * Reports every host with its four observable states and the evidence for each.
4
+ *
5
+ * It answers with the catalog, not with guesses: it no longer counts the shared
6
+ * `agents` dir as a host, no longer invents a `~/.oz` that no host ever creates,
7
+ * and no longer depends on env markers — a host that exports none (Kimi Code) is
8
+ * still detected through its binary and its config dir.
9
+ */
22
10
  export async function selfDetectHosts(ctx) {
23
- const home = ctx.env.homeDir();
24
- const hosts = [];
25
- for (const target of INSTALL_TARGETS) {
26
- const skillPath = join(home, ...TARGET_ROOTS[target], SKILL_DIR_NAME);
27
- const configDir = overrideConfigDir(target, home) ?? join(home, `.${target}`);
28
- const [configPresent, skillInstalled] = await Promise.all([
29
- ctx.fs.exists(configDir),
30
- ctx.fs.exists(skillPath),
31
- ]);
32
- hosts.push({
33
- target,
34
- config_dir: configDir,
35
- config_dir_present: configPresent,
36
- skill_installed: skillInstalled,
37
- skill_path: skillPath,
38
- });
39
- }
40
- const detectedCount = hosts.filter((h) => h.config_dir_present).length;
41
- const installedCount = hosts.filter((h) => h.skill_installed).length;
42
- const summary = buildSummary(detectedCount, installedCount);
11
+ const [hosts, sharedDestinations] = await Promise.all([
12
+ reportAllHostStates(ctx),
13
+ reportSharedDestinations(ctx),
14
+ ]);
15
+ const detectedCount = hosts.filter((h) => h.status === "ready" || h.status === "installable").length;
16
+ const installedCount = hosts.filter((h) => h.workline.installed).length;
17
+ const residualCount = hosts.filter((h) => h.status === "residual-config").length;
43
18
  return {
44
19
  ok: true,
45
- data: { hosts, detected_count: detectedCount, installed_count: installedCount, summary },
20
+ data: {
21
+ hosts,
22
+ shared_destinations: sharedDestinations,
23
+ detected_count: detectedCount,
24
+ installed_count: installedCount,
25
+ residual_count: residualCount,
26
+ summary: buildSummary(hosts.length, detectedCount, installedCount, residualCount),
27
+ },
46
28
  exitCode: 0,
47
29
  };
48
30
  }
49
- function buildSummary(detected, installed) {
31
+ function buildSummary(total, detected, installed, residual) {
50
32
  if (detected === 0) {
51
- return "No host config directories detected. Run any host (Claude Code / Codex / Warp / OZ / Gemini / OpenCode / Crush) once to create them.";
33
+ const tail = residual > 0
34
+ ? ` ${residual} config dir(s) left behind with no runtime — see each host's advice.`
35
+ : "";
36
+ return `No host runtime detected out of ${total} in the catalog.${tail} Shared skills dirs are listed apart and never count as hosts.`;
52
37
  }
53
- return `Detected ${detected} host config dir(s); SKILL installed in ${installed}.`;
38
+ const tail = residual > 0 ? ` ${residual} with residual config only.` : "";
39
+ return `${detected}/${total} hosts present; Workline installed in ${installed}.${tail} Shared skills dirs are listed apart and never count as hosts.`;
54
40
  }
55
41
  //# sourceMappingURL=detect-hosts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detect-hosts.js","sourceRoot":"","sources":["../../../src/application/self/detect-hosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,eAAe,EAEf,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAiB5B,gFAAgF;AAChF,+EAA+E;AAC/E,6EAA6E;AAC7E,2EAA2E;AAC3E,gFAAgF;AAChF,eAAe;AACf,SAAS,iBAAiB,CAAC,MAAqB,EAAE,IAAY;IAC5D,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvE,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAe;IAEf,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACxD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;YACxB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;SACzB,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC;YACT,MAAM;YACN,UAAU,EAAE,SAAS;YACrB,kBAAkB,EAAE,aAAa;YACjC,eAAe,EAAE,cAAc;YAC/B,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAE5D,OAAO;QACL,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE;QACxF,QAAQ,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB,EAAE,SAAiB;IACvD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,sIAAsI,CAAC;IAChJ,CAAC;IACD,OAAO,YAAY,QAAQ,2CAA2C,SAAS,GAAG,CAAC;AACrF,CAAC"}
1
+ {"version":3,"file":"detect-hosts.js","sourceRoot":"","sources":["../../../src/application/self/detect-hosts.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAiB1B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAe;IAEf,MAAM,CAAC,KAAK,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpD,mBAAmB,CAAC,GAAG,CAAC;QACxB,wBAAwB,CAAC,GAAG,CAAC;KAC9B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa,CAC1D,CAAC,MAAM,CAAC;IACT,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,iBAAiB,CAAC,CAAC,MAAM,CAAC;IAEjF,OAAO;QACL,EAAE,EAAE,IAAI;QACR,IAAI,EAAE;YACJ,KAAK;YACL,mBAAmB,EAAE,kBAAkB;YACvC,cAAc,EAAE,aAAa;YAC7B,eAAe,EAAE,cAAc;YAC/B,cAAc,EAAE,aAAa;YAC7B,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,CAAC;SAClF;QACD,QAAQ,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,KAAa,EACb,QAAgB,EAChB,SAAiB,EACjB,QAAgB;IAEhB,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,GACR,QAAQ,GAAG,CAAC;YACV,CAAC,CAAC,IAAI,QAAQ,sEAAsE;YACpF,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,mCAAmC,KAAK,mBAAmB,IAAI,gEAAgE,CAAC;IACzI,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,GAAG,QAAQ,IAAI,KAAK,yCAAyC,SAAS,IAAI,IAAI,gEAAgE,CAAC;AACxJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { join } from "node:path";
2
- import { HARNESSES } from "../../domain/harnesses.js";
2
+ import { HOST_INSTALL_TARGETS } from "../../domain/harnesses.js";
3
3
  import { readPackageVersion } from "../../runtime/version.js";
4
4
  import { AGENTS_LOCK_REL, LEGACY_SKILL_NAMES, SKILL_DIR_NAME, TARGET_ROOTS, } from "./install-skill.js";
5
5
  /** First existing legacy skill dir among LEGACY_SKILL_NAMES under `roots`, or null. */
@@ -11,7 +11,12 @@ async function firstExistingLegacy(ctx, home, roots) {
11
11
  }
12
12
  return null;
13
13
  }
14
- const FS_TARGETS = HARNESSES.filter((h) => h.mcpHostId !== null).map((h) => h.installTarget);
14
+ // Every host in the catalog, shared destinations apart (`agents` gets its own
15
+ // report below, with its lock file). It used to filter on `mcpHostId !== null`,
16
+ // which silently dropped Oz — the one host that takes MCP through a launch flag
17
+ // instead of a config file — so an Oz install was invisible to the doctor and,
18
+ // through it, to the whole TUI.
19
+ const FS_TARGETS = HOST_INSTALL_TARGETS;
15
20
  export async function selfDoctor(ctx) {
16
21
  const home = ctx.env.homeDir();
17
22
  const targetReports = [];
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-self.js","sourceRoot":"","sources":["../../../src/application/self/doctor-self.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor-self.js","sourceRoot":"","sources":["../../../src/application/self/doctor-self.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ // Transformation of the bundled hooks template into Kimi Code's TOML dialect,
2
+ // plus the managed-block surgery that keeps the user's own `config.toml`
3
+ // untouched around it.
4
+ //
5
+ // The two formats are NOT interchangeable. Claude nests
6
+ // `hooks.<Event>[].hooks[]` with `{type, command, timeout}`; Kimi takes a flat
7
+ // array of `[[hooks]]` tables with a STRICT schema — `event` (enum), `matcher`
8
+ // (optional), `command` (required), `timeout` (optional int, 1..600 seconds).
9
+ // Verified against the shipped v0.29.2 binary (HookDefSchema, .strict()).
10
+ //
11
+ // Two consequences the transformation has to be honest about, both surfaced in
12
+ // the install result instead of being silently dropped:
13
+ //
14
+ // 1. A `type: "prompt"` hook has no command, so Kimi cannot express it. It is
15
+ // skipped and REPORTED — the capability degrades visibly.
16
+ // 2. A matcher only transfers where the two hosts match on the same value.
17
+ // Kimi tests `new RegExp(matcher)` against a per-event value: the TOOL NAME
18
+ // for PreToolUse/PostToolUse (same vocabulary — its built-ins are Edit,
19
+ // Write, Bash, Read, Grep), but the session `source`/`reason` for the
20
+ // lifecycle events, whose vocabulary is NOT ours. Carrying Claude's
21
+ // `"startup|resume|clear"` there would produce a regex that never matches
22
+ // and a hook that silently never fires, so the matcher is dropped for those
23
+ // events — and an absent matcher means "always", which is exactly what that
24
+ // Claude matcher expresses.
25
+ export const MANAGED_BLOCK_BEGIN = "# >>> agent-workflow (Workline) managed hooks — do not edit inside this block >>>";
26
+ export const MANAGED_BLOCK_END = "# <<< agent-workflow (Workline) managed hooks <<<";
27
+ /** Events whose matcher value is the tool name, so a tool-name regex transfers as-is. */
28
+ const TOOL_NAME_MATCH_EVENTS = new Set(["PreToolUse", "PostToolUse"]);
29
+ /**
30
+ * The events Kimi Code accepts, from `HOOK_EVENT_TYPES` in the shipped v0.29.2
31
+ * binary. Its schema is `.strict()` and its config loader drops the WHOLE
32
+ * `hooks` section when one entry fails validation — including the user's own
33
+ * hooks — so an event this host does not know must be skipped here rather than
34
+ * written and left to break their config.
35
+ */
36
+ const KIMI_HOOK_EVENTS = new Set([
37
+ "PreToolUse",
38
+ "PostToolUse",
39
+ "PostToolUseFailure",
40
+ "PermissionRequest",
41
+ "PermissionResult",
42
+ "UserPromptSubmit",
43
+ "Stop",
44
+ "StopFailure",
45
+ "Interrupt",
46
+ "SessionStart",
47
+ "SessionEnd",
48
+ "SubagentStart",
49
+ "SubagentStop",
50
+ "PreCompact",
51
+ "PostCompact",
52
+ "Notification",
53
+ ]);
54
+ /** Kimi's `timeout` bounds (seconds), from its strict schema. */
55
+ const TIMEOUT_MIN = 1;
56
+ const TIMEOUT_MAX = 600;
57
+ /** Flattens the bundled template into Kimi's `[[hooks]]` entries. */
58
+ export function hooksTemplateToToml(template) {
59
+ const entries = [];
60
+ const skipped = [];
61
+ for (const [event, groups] of Object.entries(template.hooks)) {
62
+ if (!KIMI_HOOK_EVENTS.has(event)) {
63
+ skipped.push({
64
+ event,
65
+ reason: "Kimi Code does not define this event; writing it would invalidate its whole hooks section",
66
+ });
67
+ continue;
68
+ }
69
+ for (const group of groups) {
70
+ for (const hook of group.hooks ?? []) {
71
+ if (typeof hook.command !== "string" || hook.command.length === 0) {
72
+ skipped.push({
73
+ event,
74
+ reason: `hook of type '${hook.type}' has no command — Kimi Code only runs command hooks`,
75
+ });
76
+ continue;
77
+ }
78
+ const matcher = carriedMatcher(event, group.matcher);
79
+ const timeout = clampTimeout(hook.timeout);
80
+ entries.push({
81
+ event,
82
+ ...(matcher === undefined ? {} : { matcher }),
83
+ command: hook.command,
84
+ ...(timeout === undefined ? {} : { timeout }),
85
+ });
86
+ }
87
+ }
88
+ }
89
+ return { entries, skipped };
90
+ }
91
+ function carriedMatcher(event, matcher) {
92
+ if (matcher === undefined || matcher.trim().length === 0)
93
+ return undefined;
94
+ return TOOL_NAME_MATCH_EVENTS.has(event) ? matcher : undefined;
95
+ }
96
+ function clampTimeout(timeout) {
97
+ if (timeout === undefined || !Number.isFinite(timeout))
98
+ return undefined;
99
+ return Math.min(TIMEOUT_MAX, Math.max(TIMEOUT_MIN, Math.round(timeout)));
100
+ }
101
+ /** TOML basic string — same escaping rules as JSON for the characters we emit. */
102
+ function tomlString(value) {
103
+ return JSON.stringify(value);
104
+ }
105
+ /** The managed block, markers included. Ends with a newline. */
106
+ export function renderManagedHooksBlock(entries) {
107
+ const lines = [MANAGED_BLOCK_BEGIN];
108
+ for (const entry of entries) {
109
+ lines.push("[[hooks]]");
110
+ lines.push(`event = ${tomlString(entry.event)}`);
111
+ if (entry.matcher !== undefined)
112
+ lines.push(`matcher = ${tomlString(entry.matcher)}`);
113
+ lines.push(`command = ${tomlString(entry.command)}`);
114
+ if (entry.timeout !== undefined)
115
+ lines.push(`timeout = ${entry.timeout}`);
116
+ lines.push("");
117
+ }
118
+ lines.push(MANAGED_BLOCK_END);
119
+ return `${lines.join("\n")}\n`;
120
+ }
121
+ /**
122
+ * OWNERSHIP IS BY DATA, NOT BY COMMENT.
123
+ *
124
+ * The marked block is for humans reading the file. It cannot be the identity of
125
+ * our entries, because Kimi Code rewrites its own `config.toml` whenever it
126
+ * touches a setting (`kimi provider remove`, an OAuth refresh, …): it
127
+ * re-serializes the parsed config, which keeps the `hooks` array and drops
128
+ * EVERY comment — our markers included. Identity therefore rests on the same
129
+ * signal the Claude side uses: every command we install invokes this CLI.
130
+ *
131
+ * Without this, one routine Kimi command left our hooks armed and unremovable,
132
+ * and every reinstall appended a duplicate set.
133
+ */
134
+ // The boundary is whitespace or the closing quote, NOT `\b`: `\b` also matches
135
+ // before a hyphen, so `agent-workflow-lookalike` would have counted as ours and
136
+ // been deleted from the user's file.
137
+ const OUR_COMMAND_RE = /^\s*command\s*=\s*["']agent-workflow(?=[\s"']|$)/;
138
+ const HOOK_TABLE_HEADER = "[[hooks]]";
139
+ const TOML_KEY_RE = /^\s*[A-Za-z_][\w-]*\s*=/;
140
+ /** True when this command line invokes THIS CLI (and not a lookalike binary). */
141
+ export function isOurCommand(command) {
142
+ const trimmed = command.trimStart();
143
+ return trimmed === "agent-workflow" || trimmed.startsWith("agent-workflow ");
144
+ }
145
+ /**
146
+ * Removes every `[[hooks]]` entry that is OURS — wherever it sits and whether or
147
+ * not our comment markers survived — plus the markers themselves. Anything else
148
+ * in the file, including hooks the user wrote, is preserved verbatim.
149
+ *
150
+ * The one whitespace liberty it takes: a run of blank lines at end-of-file is
151
+ * collapsed to a single newline, since our appended block always ends the file.
152
+ */
153
+ export function stripOurHookEntries(text) {
154
+ const lines = text.split("\n");
155
+ const out = [];
156
+ let removed = 0;
157
+ for (let i = 0; i < lines.length;) {
158
+ const line = lines[i] ?? "";
159
+ const trimmed = line.trim();
160
+ if (trimmed === MANAGED_BLOCK_BEGIN || trimmed === MANAGED_BLOCK_END) {
161
+ i += 1;
162
+ continue;
163
+ }
164
+ if (trimmed !== HOOK_TABLE_HEADER) {
165
+ out.push(line);
166
+ i += 1;
167
+ continue;
168
+ }
169
+ // A `[[hooks]]` table: its header plus the key lines that follow it.
170
+ const block = [line];
171
+ let j = i + 1;
172
+ while (j < lines.length && TOML_KEY_RE.test(lines[j] ?? "")) {
173
+ block.push(lines[j] ?? "");
174
+ j += 1;
175
+ }
176
+ const ours = block.some((l) => OUR_COMMAND_RE.test(l));
177
+ if (!ours) {
178
+ out.push(...block);
179
+ i = j;
180
+ continue;
181
+ }
182
+ // Ours: drop it, and with it the blank lines that separated it from the next
183
+ // entry, so repeated install→uninstall cycles cannot grow the file.
184
+ while (j < lines.length && (lines[j] ?? "").trim() === "")
185
+ j += 1;
186
+ removed += 1;
187
+ i = j;
188
+ }
189
+ let result = out.join("\n");
190
+ if (removed > 0)
191
+ result = result.replace(/\n+$/, text.endsWith("\n") ? "\n" : "");
192
+ return { text: result, removed };
193
+ }
194
+ /**
195
+ * How many of our hook entries the file declares, read through a real TOML
196
+ * parse. Format-independent: it sees them whether they are written as
197
+ * `[[hooks]]` tables or re-serialized by the host in any other valid shape.
198
+ * Returns null when the file cannot be parsed.
199
+ */
200
+ export function countOurHookEntries(text, parseToml) {
201
+ let parsed;
202
+ try {
203
+ parsed = parseToml(text);
204
+ }
205
+ catch {
206
+ return null;
207
+ }
208
+ const hooks = parsed?.hooks;
209
+ if (!Array.isArray(hooks))
210
+ return 0;
211
+ return hooks.filter((h) => {
212
+ const command = h?.command;
213
+ return typeof command === "string" && isOurCommand(command);
214
+ }).length;
215
+ }
216
+ /**
217
+ * Reconciles our hooks in the file: drops every entry of ours that is already
218
+ * there (wherever it is) and appends the current set inside a fresh marked
219
+ * block. Idempotent by construction, and correct even after the host has
220
+ * rewritten the file and erased the markers.
221
+ *
222
+ * The only change to foreign content: a trailing newline added when the file
223
+ * lacked one — without it the block would glue onto the user's last line.
224
+ */
225
+ export function upsertManagedHooksBlock(text, entries) {
226
+ const swept = stripOurHookEntries(text).text;
227
+ const block = renderManagedHooksBlock(entries);
228
+ if (swept.length === 0)
229
+ return { text: block };
230
+ return { text: swept.endsWith("\n") ? `${swept}${block}` : `${swept}\n${block}` };
231
+ }
232
+ //# sourceMappingURL=hooks-toml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-toml.js","sourceRoot":"","sources":["../../../src/application/self/hooks-toml.ts"],"names":[],"mappings":"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"}