@x-code-cli/core 0.2.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/compression.d.ts +12 -2
- package/dist/agent/compression.d.ts.map +1 -1
- package/dist/agent/compression.js +51 -2
- package/dist/agent/compression.js.map +1 -1
- package/dist/agent/file-ingest.js +2 -2
- package/dist/agent/file-ingest.js.map +1 -1
- package/dist/agent/loop-state.d.ts +3 -2
- package/dist/agent/loop-state.d.ts.map +1 -1
- package/dist/agent/loop-state.js.map +1 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +134 -5
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-extractor.js +5 -5
- package/dist/agent/memory-extractor.js.map +1 -1
- package/dist/agent/plan-storage.js +1 -1
- package/dist/agent/plan-storage.js.map +1 -1
- package/dist/agent/sub-agents/index.d.ts +2 -1
- package/dist/agent/sub-agents/index.d.ts.map +1 -1
- package/dist/agent/sub-agents/index.js +1 -1
- package/dist/agent/sub-agents/index.js.map +1 -1
- package/dist/agent/sub-agents/loader.d.ts +13 -3
- package/dist/agent/sub-agents/loader.d.ts.map +1 -1
- package/dist/agent/sub-agents/loader.js +36 -9
- package/dist/agent/sub-agents/loader.js.map +1 -1
- package/dist/agent/sub-agents/registry.d.ts +18 -1
- package/dist/agent/sub-agents/registry.d.ts.map +1 -1
- package/dist/agent/sub-agents/registry.js +38 -5
- package/dist/agent/sub-agents/registry.js.map +1 -1
- package/dist/agent/sub-agents/runner.d.ts.map +1 -1
- package/dist/agent/sub-agents/runner.js +45 -1
- package/dist/agent/sub-agents/runner.js.map +1 -1
- package/dist/agent/sub-agents/types.d.ts +4 -1
- package/dist/agent/sub-agents/types.d.ts.map +1 -1
- package/dist/agent/system-prompt.d.ts +21 -0
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +68 -2
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-execution.d.ts.map +1 -1
- package/dist/agent/tool-execution.js +220 -1
- package/dist/agent/tool-execution.js.map +1 -1
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/loader.d.ts +13 -0
- package/dist/commands/loader.d.ts.map +1 -0
- package/dist/commands/loader.js +93 -0
- package/dist/commands/loader.js.map +1 -0
- package/dist/commands/registry.d.ts +44 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +102 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/types.d.ts +23 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +26 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +12 -10
- package/dist/config/index.js.map +1 -1
- package/dist/hooks/bus.d.ts +54 -0
- package/dist/hooks/bus.d.ts.map +1 -0
- package/dist/hooks/bus.js +165 -0
- package/dist/hooks/bus.js.map +1 -0
- package/dist/hooks/config-schema.d.ts +854 -0
- package/dist/hooks/config-schema.d.ts.map +1 -0
- package/dist/hooks/config-schema.js +79 -0
- package/dist/hooks/config-schema.js.map +1 -0
- package/dist/hooks/executor.d.ts +16 -0
- package/dist/hooks/executor.d.ts.map +1 -0
- package/dist/hooks/executor.js +183 -0
- package/dist/hooks/executor.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registry.d.ts +23 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +49 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/types.d.ts +165 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +25 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/hooks/variables.d.ts +22 -0
- package/dist/hooks/variables.d.ts.map +1 -0
- package/dist/hooks/variables.js +80 -0
- package/dist/hooks/variables.js.map +1 -0
- package/dist/index.d.ts +56 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge/auto-memory.d.ts +1 -1
- package/dist/knowledge/auto-memory.d.ts.map +1 -1
- package/dist/knowledge/auto-memory.js +10 -10
- package/dist/knowledge/auto-memory.js.map +1 -1
- package/dist/knowledge/loader.js +12 -12
- package/dist/knowledge/loader.js.map +1 -1
- package/dist/mcp/arg-parser.d.ts +49 -0
- package/dist/mcp/arg-parser.d.ts.map +1 -0
- package/dist/mcp/arg-parser.js +357 -0
- package/dist/mcp/arg-parser.js.map +1 -0
- package/dist/mcp/client.d.ts +73 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +376 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config-schema.d.ts +64 -0
- package/dist/mcp/config-schema.d.ts.map +1 -0
- package/dist/mcp/config-schema.js +86 -0
- package/dist/mcp/config-schema.js.map +1 -0
- package/dist/mcp/config-writer.d.ts +41 -0
- package/dist/mcp/config-writer.d.ts.map +1 -0
- package/dist/mcp/config-writer.js +138 -0
- package/dist/mcp/config-writer.js.map +1 -0
- package/dist/mcp/env-safety.d.ts +12 -0
- package/dist/mcp/env-safety.d.ts.map +1 -0
- package/dist/mcp/env-safety.js +80 -0
- package/dist/mcp/env-safety.js.map +1 -0
- package/dist/mcp/expand-env.d.ts +14 -0
- package/dist/mcp/expand-env.d.ts.map +1 -0
- package/dist/mcp/expand-env.js +52 -0
- package/dist/mcp/expand-env.js.map +1 -0
- package/dist/mcp/loader.d.ts +81 -0
- package/dist/mcp/loader.d.ts.map +1 -0
- package/dist/mcp/loader.js +223 -0
- package/dist/mcp/loader.js.map +1 -0
- package/dist/mcp/name-mangling.d.ts +11 -0
- package/dist/mcp/name-mangling.d.ts.map +1 -0
- package/dist/mcp/name-mangling.js +82 -0
- package/dist/mcp/name-mangling.js.map +1 -0
- package/dist/mcp/oauth/callback-server.d.ts +25 -0
- package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
- package/dist/mcp/oauth/callback-server.js +118 -0
- package/dist/mcp/oauth/callback-server.js.map +1 -0
- package/dist/mcp/oauth/provider.d.ts +80 -0
- package/dist/mcp/oauth/provider.d.ts.map +1 -0
- package/dist/mcp/oauth/provider.js +292 -0
- package/dist/mcp/oauth/provider.js.map +1 -0
- package/dist/mcp/oauth/token-storage.d.ts +42 -0
- package/dist/mcp/oauth/token-storage.d.ts.map +1 -0
- package/dist/mcp/oauth/token-storage.js +121 -0
- package/dist/mcp/oauth/token-storage.js.map +1 -0
- package/dist/mcp/permissions.d.ts +28 -0
- package/dist/mcp/permissions.d.ts.map +1 -0
- package/dist/mcp/permissions.js +105 -0
- package/dist/mcp/permissions.js.map +1 -0
- package/dist/mcp/registry.d.ts +150 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +334 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +7 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +40 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/tool-bridge.d.ts +16 -0
- package/dist/mcp/tool-bridge.d.ts.map +1 -0
- package/dist/mcp/tool-bridge.js +56 -0
- package/dist/mcp/tool-bridge.js.map +1 -0
- package/dist/mcp/trust.d.ts +31 -0
- package/dist/mcp/trust.d.ts.map +1 -0
- package/dist/mcp/trust.js +103 -0
- package/dist/mcp/trust.js.map +1 -0
- package/dist/mcp/types.d.ts +73 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +13 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/permissions/session-store.d.ts +4 -1
- package/dist/permissions/session-store.d.ts.map +1 -1
- package/dist/permissions/session-store.js +6 -1
- package/dist/permissions/session-store.js.map +1 -1
- package/dist/plugins/consent.d.ts +87 -0
- package/dist/plugins/consent.d.ts.map +1 -0
- package/dist/plugins/consent.js +181 -0
- package/dist/plugins/consent.js.map +1 -0
- package/dist/plugins/enable-state.d.ts +34 -0
- package/dist/plugins/enable-state.d.ts.map +1 -0
- package/dist/plugins/enable-state.js +159 -0
- package/dist/plugins/enable-state.js.map +1 -0
- package/dist/plugins/installer.d.ts +64 -0
- package/dist/plugins/installer.d.ts.map +1 -0
- package/dist/plugins/installer.js +416 -0
- package/dist/plugins/installer.js.map +1 -0
- package/dist/plugins/integration.d.ts +91 -0
- package/dist/plugins/integration.d.ts.map +1 -0
- package/dist/plugins/integration.js +233 -0
- package/dist/plugins/integration.js.map +1 -0
- package/dist/plugins/loader.d.ts +69 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +243 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manifest.d.ts +23 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +143 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/marketplace.d.ts +100 -0
- package/dist/plugins/marketplace.d.ts.map +1 -0
- package/dist/plugins/marketplace.js +529 -0
- package/dist/plugins/marketplace.js.map +1 -0
- package/dist/plugins/paths.d.ts +44 -0
- package/dist/plugins/paths.d.ts.map +1 -0
- package/dist/plugins/paths.js +89 -0
- package/dist/plugins/paths.js.map +1 -0
- package/dist/plugins/refresh.d.ts +61 -0
- package/dist/plugins/refresh.d.ts.map +1 -0
- package/dist/plugins/refresh.js +98 -0
- package/dist/plugins/refresh.js.map +1 -0
- package/dist/plugins/registry.d.ts +40 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +80 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/types.d.ts +225 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +16 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/user-config.d.ts +22 -0
- package/dist/plugins/user-config.d.ts.map +1 -0
- package/dist/plugins/user-config.js +96 -0
- package/dist/plugins/user-config.js.map +1 -0
- package/dist/skills/loader.d.ts +19 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +197 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +74 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +136 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/settings.d.ts +13 -0
- package/dist/skills/settings.d.ts.map +1 -0
- package/dist/skills/settings.js +100 -0
- package/dist/skills/settings.js.map +1 -0
- package/dist/tools/activate-skill.d.ts +5 -0
- package/dist/tools/activate-skill.d.ts.map +1 -0
- package/dist/tools/activate-skill.js +33 -0
- package/dist/tools/activate-skill.js.map +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/todo-write.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +2 -1
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/types/index.d.ts +46 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils.d.ts +23 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +76 -20
- package/dist/utils.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type LoadCommandsOptions } from './loader.js';
|
|
2
|
+
import type { CommandDefinition } from './types.js';
|
|
3
|
+
/** Diff returned by reload — drives the /plugin refresh message. */
|
|
4
|
+
export interface CommandReloadSummary {
|
|
5
|
+
added: string[];
|
|
6
|
+
removed: string[];
|
|
7
|
+
changed: string[];
|
|
8
|
+
unchanged: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare class CommandRegistry {
|
|
11
|
+
private byName;
|
|
12
|
+
constructor(commands?: ReadonlyArray<CommandDefinition>);
|
|
13
|
+
get(name: string): CommandDefinition | undefined;
|
|
14
|
+
list(): CommandDefinition[];
|
|
15
|
+
names(): string[];
|
|
16
|
+
/** Replace the in-memory command set with a fresh load. Used by
|
|
17
|
+
* /plugin refresh — keeps registry identity stable so captured
|
|
18
|
+
* `options.commandRegistry` references stay valid. */
|
|
19
|
+
reload(commands: ReadonlyArray<CommandDefinition>): CommandReloadSummary;
|
|
20
|
+
}
|
|
21
|
+
export declare function createCommandRegistry(opts?: LoadCommandsOptions): Promise<CommandRegistry>;
|
|
22
|
+
/** Re-scan plugin command dirs and rebuild the registry in place.
|
|
23
|
+
* Caller is responsible for passing the latest plugin-derived extraDirs. */
|
|
24
|
+
export declare function reloadCommandRegistry(registry: CommandRegistry, opts?: LoadCommandsOptions): Promise<CommandReloadSummary>;
|
|
25
|
+
/** Apply Claude Code-style placeholder substitutions to a command
|
|
26
|
+
* body before sending it as a model prompt. Recognised placeholders
|
|
27
|
+
* match real Claude Code plugin command files (verified against
|
|
28
|
+
* `anthropics/claude-code/plugins/<plugin>/commands/<cmd>.md`):
|
|
29
|
+
*
|
|
30
|
+
* $ARGUMENTS / ${ARGUMENTS} — text the user typed after the
|
|
31
|
+
* command name (`/code-review 123`
|
|
32
|
+
* → `123`). Empty string when no
|
|
33
|
+
* argument was given.
|
|
34
|
+
* ${CLAUDE_PLUGIN_ROOT} — absolute path to the owning
|
|
35
|
+
* plugin's installed dir (versioned;
|
|
36
|
+
* wiped on reinstall).
|
|
37
|
+
* ${CLAUDE_PLUGIN_DATA} — persistent per-plugin data dir
|
|
38
|
+
* (`~/.x-code/plugins/data/<id>/`)
|
|
39
|
+
* that survives reinstalls and
|
|
40
|
+
* upgrades. Auto-created on first
|
|
41
|
+
* substitution. Left verbatim when
|
|
42
|
+
* the command has no plugin context. */
|
|
43
|
+
export declare function expandCommandBody(cmd: CommandDefinition, args: string): string;
|
|
44
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,aAAa,CAAA;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgC;gBAElC,QAAQ,GAAE,aAAa,CAAC,iBAAiB,CAAM;IAO3D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhD,IAAI,IAAI,iBAAiB,EAAE;IAI3B,KAAK,IAAI,MAAM,EAAE;IAIjB;;2DAEuD;IACvD,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,oBAAoB;CAkBzE;AAED,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,eAAe,CAAC,CAGpG;AAED;6EAC6E;AAC7E,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,eAAe,EACzB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAG/B;AAED;;;;;;;;;;;;;;;;;4EAiB4E;AAC5E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAkB9E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @x-code-cli/core — Slash command registry
|
|
2
|
+
//
|
|
3
|
+
// Built once at CLI startup from plugin-contributed command files.
|
|
4
|
+
// Lookups happen from the App.tsx default slash-dispatcher when a typed
|
|
5
|
+
// `/<name>` doesn't match any built-in command or skill. Same
|
|
6
|
+
// startup-frozen / byte-stability model as SkillRegistry.
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import { pluginDataDir } from '../plugins/paths.js';
|
|
9
|
+
import { loadPluginCommands } from './loader.js';
|
|
10
|
+
export class CommandRegistry {
|
|
11
|
+
byName;
|
|
12
|
+
constructor(commands = []) {
|
|
13
|
+
this.byName = new Map();
|
|
14
|
+
// Last-write wins on name collision (consistent with how
|
|
15
|
+
// SkillRegistry merges user → plugin → project).
|
|
16
|
+
for (const c of commands)
|
|
17
|
+
this.byName.set(c.name, c);
|
|
18
|
+
}
|
|
19
|
+
get(name) {
|
|
20
|
+
return this.byName.get(name);
|
|
21
|
+
}
|
|
22
|
+
list() {
|
|
23
|
+
return [...this.byName.values()];
|
|
24
|
+
}
|
|
25
|
+
names() {
|
|
26
|
+
return [...this.byName.keys()];
|
|
27
|
+
}
|
|
28
|
+
/** Replace the in-memory command set with a fresh load. Used by
|
|
29
|
+
* /plugin refresh — keeps registry identity stable so captured
|
|
30
|
+
* `options.commandRegistry` references stay valid. */
|
|
31
|
+
reload(commands) {
|
|
32
|
+
const previous = this.byName;
|
|
33
|
+
const next = new Map();
|
|
34
|
+
for (const c of commands)
|
|
35
|
+
next.set(c.name, c);
|
|
36
|
+
const summary = { added: [], removed: [], changed: [], unchanged: [] };
|
|
37
|
+
for (const [name, cmd] of next) {
|
|
38
|
+
const prev = previous.get(name);
|
|
39
|
+
if (!prev)
|
|
40
|
+
summary.added.push(name);
|
|
41
|
+
else if (prev.body !== cmd.body || prev.pluginId !== cmd.pluginId || prev.pluginRoot !== cmd.pluginRoot)
|
|
42
|
+
summary.changed.push(name);
|
|
43
|
+
else
|
|
44
|
+
summary.unchanged.push(name);
|
|
45
|
+
}
|
|
46
|
+
for (const name of previous.keys()) {
|
|
47
|
+
if (!next.has(name))
|
|
48
|
+
summary.removed.push(name);
|
|
49
|
+
}
|
|
50
|
+
this.byName = next;
|
|
51
|
+
return summary;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function createCommandRegistry(opts = {}) {
|
|
55
|
+
const commands = await loadPluginCommands(opts);
|
|
56
|
+
return new CommandRegistry(commands);
|
|
57
|
+
}
|
|
58
|
+
/** Re-scan plugin command dirs and rebuild the registry in place.
|
|
59
|
+
* Caller is responsible for passing the latest plugin-derived extraDirs. */
|
|
60
|
+
export async function reloadCommandRegistry(registry, opts = {}) {
|
|
61
|
+
const commands = await loadPluginCommands(opts);
|
|
62
|
+
return registry.reload(commands);
|
|
63
|
+
}
|
|
64
|
+
/** Apply Claude Code-style placeholder substitutions to a command
|
|
65
|
+
* body before sending it as a model prompt. Recognised placeholders
|
|
66
|
+
* match real Claude Code plugin command files (verified against
|
|
67
|
+
* `anthropics/claude-code/plugins/<plugin>/commands/<cmd>.md`):
|
|
68
|
+
*
|
|
69
|
+
* $ARGUMENTS / ${ARGUMENTS} — text the user typed after the
|
|
70
|
+
* command name (`/code-review 123`
|
|
71
|
+
* → `123`). Empty string when no
|
|
72
|
+
* argument was given.
|
|
73
|
+
* ${CLAUDE_PLUGIN_ROOT} — absolute path to the owning
|
|
74
|
+
* plugin's installed dir (versioned;
|
|
75
|
+
* wiped on reinstall).
|
|
76
|
+
* ${CLAUDE_PLUGIN_DATA} — persistent per-plugin data dir
|
|
77
|
+
* (`~/.x-code/plugins/data/<id>/`)
|
|
78
|
+
* that survives reinstalls and
|
|
79
|
+
* upgrades. Auto-created on first
|
|
80
|
+
* substitution. Left verbatim when
|
|
81
|
+
* the command has no plugin context. */
|
|
82
|
+
export function expandCommandBody(cmd, args) {
|
|
83
|
+
const root = cmd.pluginRoot ?? '';
|
|
84
|
+
let dataDir = '';
|
|
85
|
+
if (cmd.pluginId && cmd.body.includes('${CLAUDE_PLUGIN_DATA}')) {
|
|
86
|
+
dataDir = pluginDataDir(cmd.pluginId);
|
|
87
|
+
try {
|
|
88
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// mkdir failure leaves dataDir set to the path string anyway —
|
|
92
|
+
// the user's shell script will surface a sensible error if it
|
|
93
|
+
// actually tries to write there.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return cmd.body
|
|
97
|
+
.replaceAll('${CLAUDE_PLUGIN_ROOT}', root)
|
|
98
|
+
.replaceAll('${CLAUDE_PLUGIN_DATA}', dataDir)
|
|
99
|
+
.replaceAll('${ARGUMENTS}', args)
|
|
100
|
+
.replaceAll('$ARGUMENTS', args);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CommandDefinition {
|
|
2
|
+
/** Command invocation name without the leading slash. Derived from
|
|
3
|
+
* the filename (`code-review.md` → `code-review`). */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Short one-line summary from the frontmatter `description` field —
|
|
6
|
+
* used by `/help` and `/plugin info` to label the command. */
|
|
7
|
+
description?: string;
|
|
8
|
+
/** The prompt template (everything after the frontmatter), trimmed. */
|
|
9
|
+
body: string;
|
|
10
|
+
/** Where this command came from. `'plugin'` is the only kind today
|
|
11
|
+
* since we don't (yet) scan `~/.x-code/commands/` for user-authored
|
|
12
|
+
* ones. Reserved for symmetry with SkillDefinition. */
|
|
13
|
+
source: 'plugin';
|
|
14
|
+
/** When source === 'plugin', the owning plugin's id
|
|
15
|
+
* (`name@marketplace`). Used by `/plugin info` and to set
|
|
16
|
+
* `${CLAUDE_PLUGIN_ROOT}` correctly. */
|
|
17
|
+
pluginId?: string;
|
|
18
|
+
/** Absolute path to the plugin's root dir. Substituted in for
|
|
19
|
+
* `${CLAUDE_PLUGIN_ROOT}` in the body — so command bodies that
|
|
20
|
+
* reference bundled scripts can resolve them correctly. */
|
|
21
|
+
pluginRoot?: string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,iBAAiB;IAChC;2DACuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ;mEAC+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAA;IACZ;;4DAEwD;IACxD,MAAM,EAAE,QAAQ,CAAA;IAChB;;6CAEyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;gEAE4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @x-code-cli/core — File-based slash command types
|
|
2
|
+
//
|
|
3
|
+
// A "command" is a markdown file shipped by a plugin (or, in future,
|
|
4
|
+
// authored directly under ~/.x-code/commands/) that turns into a slash
|
|
5
|
+
// command at startup. Real Claude Code plugins ship them as
|
|
6
|
+
// `commands/<name>.md` next to their plugin.json — `code-review.md`
|
|
7
|
+
// inside `code-review` plugin's `commands/` registers as `/code-review`.
|
|
8
|
+
//
|
|
9
|
+
// File format (matches Claude Code spec verified against
|
|
10
|
+
// anthropics/claude-code real plugin contents):
|
|
11
|
+
//
|
|
12
|
+
// ---
|
|
13
|
+
// description: Code review a pull request
|
|
14
|
+
// allowed-tools: Bash(gh pr view:*), … # ignored by us today
|
|
15
|
+
// ---
|
|
16
|
+
//
|
|
17
|
+
// <body — a prompt template the model executes>
|
|
18
|
+
//
|
|
19
|
+
// Substitutions applied to the body before sending to the model:
|
|
20
|
+
// $ARGUMENTS — text typed after the command name
|
|
21
|
+
// ${ARGUMENTS} — same, brace form
|
|
22
|
+
// ${CLAUDE_PLUGIN_ROOT} — absolute path to the plugin root
|
|
23
|
+
// (so command bodies can reference
|
|
24
|
+
// bundled scripts via shell)
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,uEAAuE;AACvE,4DAA4D;AAC5D,oEAAoE;AACpE,yEAAyE;AACzE,EAAE;AACF,yDAAyD;AACzD,gDAAgD;AAChD,EAAE;AACF,UAAU;AACV,8CAA8C;AAC9C,sEAAsE;AACtE,UAAU;AACV,EAAE;AACF,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,qDAAqD;AACrD,qEAAqE;AACrE,qEAAqE;AACrE,+DAA+D"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -22,7 +22,16 @@ export interface UserConfig {
|
|
|
22
22
|
* because core doesn't depend on the CLI's theme list. Unknown
|
|
23
23
|
* values fall back to the default ('dark') silently. */
|
|
24
24
|
theme?: string;
|
|
25
|
+
/** MCP server declarations. Loose-typed here because the schema is
|
|
26
|
+
* validated in `mcp/config-schema.ts` — we don't want to drag a Zod
|
|
27
|
+
* type into the config module's surface. Loader uses
|
|
28
|
+
* `parseServersBlock` to validate before constructing clients. */
|
|
29
|
+
mcpServers?: Record<string, unknown>;
|
|
25
30
|
}
|
|
31
|
+
/** Path to the user config file. Exposed so other modules that want to
|
|
32
|
+
* read the same JSON (e.g. the MCP loader for the `mcpServers` field)
|
|
33
|
+
* honour the X_CODE_HOME override automatically. */
|
|
34
|
+
export declare function getUserConfigPath(): string;
|
|
26
35
|
/** Read the user config. Returns empty object on any failure (missing file,
|
|
27
36
|
* parse error, wrong shape) so callers don't have to null-check. */
|
|
28
37
|
export declare function loadUserConfig(): UserConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAuCA,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAMhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW5D;AAgBD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;6DAIyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAuCA,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAMhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW5D;AAgBD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;6DAIyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;uEAGmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED;;qDAEqD;AACrD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAMD;qEACqE;AACrE,wBAAgB,cAAc,IAAI,UAAU,CAW3C;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAWhE;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB;;;;;;;;;;;;;EAejC"}
|
package/dist/config/index.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import fsSync from 'node:fs';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { MODEL_ALIASES, PROVIDER_DETECTION_ORDER } from '../types/index.js';
|
|
19
|
-
import {
|
|
19
|
+
import { userXcodeDir } from '../utils.js';
|
|
20
20
|
/** Provider → environment variable mapping */
|
|
21
21
|
const ENV_MAP = {
|
|
22
22
|
anthropic: 'ANTHROPIC_API_KEY',
|
|
@@ -66,15 +66,14 @@ export function resolveModelId(input) {
|
|
|
66
66
|
}
|
|
67
67
|
return null;
|
|
68
68
|
}
|
|
69
|
+
/** Path to the user config file. Exposed so other modules that want to
|
|
70
|
+
* read the same JSON (e.g. the MCP loader for the `mcpServers` field)
|
|
71
|
+
* honour the X_CODE_HOME override automatically. */
|
|
72
|
+
export function getUserConfigPath() {
|
|
73
|
+
return userConfigPath();
|
|
74
|
+
}
|
|
69
75
|
function userConfigPath() {
|
|
70
|
-
|
|
71
|
-
// at a scratch tmpdir so the real user's config doesn't leak into
|
|
72
|
-
// assertions, and available to end users who want to sandbox the CLI's
|
|
73
|
-
// state. Falls through to `~/.x-code` otherwise.
|
|
74
|
-
const override = process.env.X_CODE_HOME;
|
|
75
|
-
if (override)
|
|
76
|
-
return path.join(override, 'config.json');
|
|
77
|
-
return path.join(GLOBAL_XCODE_DIR, 'config.json');
|
|
76
|
+
return path.join(userXcodeDir(), 'config.json');
|
|
78
77
|
}
|
|
79
78
|
/** Read the user config. Returns empty object on any failure (missing file,
|
|
80
79
|
* parse error, wrong shape) so callers don't have to null-check. */
|
|
@@ -95,7 +94,10 @@ export function loadUserConfig() {
|
|
|
95
94
|
export function saveUserConfig(update) {
|
|
96
95
|
const merged = { ...loadUserConfig(), ...update };
|
|
97
96
|
try {
|
|
98
|
-
|
|
97
|
+
// mkdir the SAME root userConfigPath() points at — otherwise an
|
|
98
|
+
// X_CODE_HOME override creates `~/.x-code/` but writes to the override
|
|
99
|
+
// and the write silently fails on a missing parent.
|
|
100
|
+
fsSync.mkdirSync(userXcodeDir(), { recursive: true });
|
|
99
101
|
fsSync.writeFileSync(userConfigPath(), JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
100
102
|
}
|
|
101
103
|
catch {
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,0EAA0E;AAC1E,oEAAoE;AACpE,EAAE;AACF,yEAAyE;AACzE,iDAAiD;AACjD,0EAA0E;AAC1E,2CAA2C;AAC3C,8EAA8E;AAC9E,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,sEAAsE;AACtE,yBAAyB;AACzB,OAAO,MAAM,MAAM,SAAS,CAAA;AAC5B,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ExecuteHookOptions } from './executor.js';
|
|
2
|
+
import { type HookRegistry } from './registry.js';
|
|
3
|
+
import type { HookDecision, HookEvent } from './types.js';
|
|
4
|
+
export interface EmitOptions extends ExecuteHookOptions {
|
|
5
|
+
/** Force parallel execution. Default is serial for decision events
|
|
6
|
+
* and parallel for fire-and-forget. Caller almost never overrides. */
|
|
7
|
+
parallel?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class HookBus {
|
|
10
|
+
private registry;
|
|
11
|
+
constructor(registry: HookRegistry);
|
|
12
|
+
has(event: HookEvent['name']): boolean;
|
|
13
|
+
/** Replace the internal registry. Used by /plugin refresh after a
|
|
14
|
+
* rescan to pick up newly-installed / removed plugin hooks. */
|
|
15
|
+
replaceRegistry(registry: HookRegistry): void;
|
|
16
|
+
/** Emit an event. Returns the per-hook decisions in run order — empty
|
|
17
|
+
* when no hooks matched. Callers typically only inspect the result
|
|
18
|
+
* for the three DecisionEvents; for the others they just await
|
|
19
|
+
* completion for side effects. */
|
|
20
|
+
emit(event: HookEvent, opts?: EmitOptions): Promise<HookDecision[]>;
|
|
21
|
+
}
|
|
22
|
+
/** A bus with no registered hooks. The CLI passes this when plugins
|
|
23
|
+
* are disabled (`--no-plugins`) so the agent loop's emit-sites don't
|
|
24
|
+
* need null-checks. */
|
|
25
|
+
export declare function emptyHookBus(): HookBus;
|
|
26
|
+
/** Collapse a list of PreToolUse decisions into a single effective
|
|
27
|
+
* outcome. Order matters: deny short-circuits earlier in `emit`, so
|
|
28
|
+
* if we see a `deny` here it's the final word. Modifications stack —
|
|
29
|
+
* the last `modify` with `args` wins (later plugins refine earlier
|
|
30
|
+
* plugins). */
|
|
31
|
+
export interface PreToolEffect {
|
|
32
|
+
decision: 'allow' | 'deny';
|
|
33
|
+
reason?: string;
|
|
34
|
+
/** Modified args, or undefined to use the original. */
|
|
35
|
+
args?: unknown;
|
|
36
|
+
/** Extra context to inject (rare for PreToolUse; supported for symmetry). */
|
|
37
|
+
context?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function aggregatePreToolUse(decisions: ReadonlyArray<HookDecision>): PreToolEffect;
|
|
40
|
+
export interface PostToolEffect {
|
|
41
|
+
/** Replacement output, or undefined to keep original. */
|
|
42
|
+
output?: string;
|
|
43
|
+
context?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function aggregatePostToolUse(decisions: ReadonlyArray<HookDecision>): PostToolEffect;
|
|
46
|
+
export interface UserPromptEffect {
|
|
47
|
+
decision: 'allow' | 'deny';
|
|
48
|
+
reason?: string;
|
|
49
|
+
/** Concatenated context from every hook, ready to prepend to the user
|
|
50
|
+
* message. Empty string when no hook injected anything. */
|
|
51
|
+
context: string;
|
|
52
|
+
}
|
|
53
|
+
export declare function aggregateUserPromptSubmit(decisions: ReadonlyArray<HookDecision>): UserPromptEffect;
|
|
54
|
+
//# sourceMappingURL=bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/hooks/bus.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,kBAAkB,EAAe,MAAM,eAAe,CAAA;AACpE,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,eAAe,CAAA;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAA;AAEzE,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD;2EACuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,qBAAa,OAAO;IAMN,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAE1C,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO;IAItC;oEACgE;IAChE,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI7C;;;uCAGmC;IAC7B,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CA6C9E;AAED;;wBAEwB;AACxB,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAiBD;;;;gBAIgB;AAChB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uDAAuD;IACvD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,aAAa,CAazF;AAED,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,cAAc,CAY3F;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;gEAC4D;IAC5D,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,gBAAgB,CAUlG"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// @x-code-cli/core — Hook event bus
|
|
2
|
+
//
|
|
3
|
+
// Thin orchestration layer over [[HookRegistry]]. The agent loop,
|
|
4
|
+
// tool-execution, compression, and sub-agent runner call `bus.emit(event)`
|
|
5
|
+
// at ten lifecycle points; the bus filters hooks by matcher (PreToolUse /
|
|
6
|
+
// PostToolUse only), runs them, and returns the aggregated decisions.
|
|
7
|
+
//
|
|
8
|
+
// Serial vs parallel:
|
|
9
|
+
//
|
|
10
|
+
// Decision events (UserPromptSubmit / PreToolUse / PostToolUse) run
|
|
11
|
+
// serially. A `deny` short-circuits the remaining hooks — the agent
|
|
12
|
+
// stops at the first stop. Order is registration order, so plugin
|
|
13
|
+
// authors get deterministic behaviour.
|
|
14
|
+
//
|
|
15
|
+
// Fire-and-forget events (SessionStart / PreCompact / PostCompact /
|
|
16
|
+
// SubagentStart / SubagentStop / TurnComplete / SessionEnd) run in
|
|
17
|
+
// parallel — they have no decisions and no ordering concerns.
|
|
18
|
+
//
|
|
19
|
+
// The bus catches per-hook errors and degrades to `allow` so one
|
|
20
|
+
// broken hook never blocks the loop. The executor already does the
|
|
21
|
+
// "non-zero exit / timeout → allow" handling — this layer adds the
|
|
22
|
+
// matcher-regex error guard.
|
|
23
|
+
import { debugLog } from '../utils.js';
|
|
24
|
+
import { executeHook } from './executor.js';
|
|
25
|
+
import { emptyHookRegistry } from './registry.js';
|
|
26
|
+
export class HookBus {
|
|
27
|
+
registry;
|
|
28
|
+
// Mutable so /plugin refresh can swap in a fresh registry without
|
|
29
|
+
// forcing callers to re-capture the bus reference. New incoming
|
|
30
|
+
// event emissions then see the new hooks; any in-flight executeHook
|
|
31
|
+
// calls finish against the old registry (deliberate — finishing the
|
|
32
|
+
// hook is cheaper than coordinating shutdown).
|
|
33
|
+
constructor(registry) {
|
|
34
|
+
this.registry = registry;
|
|
35
|
+
}
|
|
36
|
+
has(event) {
|
|
37
|
+
return this.registry.has(event);
|
|
38
|
+
}
|
|
39
|
+
/** Replace the internal registry. Used by /plugin refresh after a
|
|
40
|
+
* rescan to pick up newly-installed / removed plugin hooks. */
|
|
41
|
+
replaceRegistry(registry) {
|
|
42
|
+
this.registry = registry;
|
|
43
|
+
}
|
|
44
|
+
/** Emit an event. Returns the per-hook decisions in run order — empty
|
|
45
|
+
* when no hooks matched. Callers typically only inspect the result
|
|
46
|
+
* for the three DecisionEvents; for the others they just await
|
|
47
|
+
* completion for side effects. */
|
|
48
|
+
async emit(event, opts = {}) {
|
|
49
|
+
const hooks = this.registry.get(event.name);
|
|
50
|
+
if (hooks.length === 0)
|
|
51
|
+
return [];
|
|
52
|
+
const applicable = hooks.filter((h) => matches(h, event));
|
|
53
|
+
if (applicable.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const isDecisionEvent = event.name === 'UserPromptSubmit' || event.name === 'PreToolUse' || event.name === 'PostToolUse';
|
|
56
|
+
const parallel = opts.parallel ?? !isDecisionEvent;
|
|
57
|
+
if (parallel) {
|
|
58
|
+
// For fire-and-forget events we still await the results so the
|
|
59
|
+
// caller's await-for-completion semantics work; we just don't
|
|
60
|
+
// serialise execution. Individual hook failures don't fail the
|
|
61
|
+
// batch (executor returns `allow` on failure).
|
|
62
|
+
const settled = await Promise.allSettled(applicable.map((h) => executeHook(h, event, opts)));
|
|
63
|
+
const out = [];
|
|
64
|
+
for (const r of settled) {
|
|
65
|
+
if (r.status === 'fulfilled')
|
|
66
|
+
out.push(r.value);
|
|
67
|
+
else {
|
|
68
|
+
if (opts.signal?.aborted)
|
|
69
|
+
throw r.reason;
|
|
70
|
+
debugLog('hooks.bus-error', `${event.name}: ${String(r.reason)}`);
|
|
71
|
+
out.push({ decision: 'allow' });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
// Serial: first `deny` halts the rest. modify decisions stack on
|
|
77
|
+
// the next hook's input via the caller (we just collect them).
|
|
78
|
+
const decisions = [];
|
|
79
|
+
for (const h of applicable) {
|
|
80
|
+
try {
|
|
81
|
+
const d = await executeHook(h, event, opts);
|
|
82
|
+
decisions.push(d);
|
|
83
|
+
if (d.decision === 'deny')
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (opts.signal?.aborted)
|
|
88
|
+
throw err;
|
|
89
|
+
debugLog('hooks.bus-error', `${h.pluginId} ${event.name}: ${String(err)}`);
|
|
90
|
+
decisions.push({ decision: 'allow' });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return decisions;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** A bus with no registered hooks. The CLI passes this when plugins
|
|
97
|
+
* are disabled (`--no-plugins`) so the agent loop's emit-sites don't
|
|
98
|
+
* need null-checks. */
|
|
99
|
+
export function emptyHookBus() {
|
|
100
|
+
return new HookBus(emptyHookRegistry());
|
|
101
|
+
}
|
|
102
|
+
function matches(hook, event) {
|
|
103
|
+
if (event.name !== 'PreToolUse' && event.name !== 'PostToolUse')
|
|
104
|
+
return true;
|
|
105
|
+
if (!hook.entry.matcher)
|
|
106
|
+
return true;
|
|
107
|
+
try {
|
|
108
|
+
return new RegExp(hook.entry.matcher).test(event.tool.name);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
// Bad regex shouldn't silently disable the hook — degrade to
|
|
112
|
+
// "matches every tool" but log so support can spot the bad pattern.
|
|
113
|
+
debugLog('hooks.matcher-invalid', `${hook.pluginId}: ${String(err)}`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export function aggregatePreToolUse(decisions) {
|
|
118
|
+
let args;
|
|
119
|
+
let context;
|
|
120
|
+
for (const d of decisions) {
|
|
121
|
+
if (d.decision === 'deny')
|
|
122
|
+
return { decision: 'deny', reason: d.reason };
|
|
123
|
+
if (d.decision === 'modify') {
|
|
124
|
+
if (d.args !== undefined)
|
|
125
|
+
args = d.args;
|
|
126
|
+
if (d.context)
|
|
127
|
+
context = d.context;
|
|
128
|
+
}
|
|
129
|
+
else if (d.decision === 'allow' && d.context) {
|
|
130
|
+
context = d.context;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { decision: 'allow', args, context };
|
|
134
|
+
}
|
|
135
|
+
export function aggregatePostToolUse(decisions) {
|
|
136
|
+
let output;
|
|
137
|
+
let context;
|
|
138
|
+
for (const d of decisions) {
|
|
139
|
+
if (d.decision === 'modify') {
|
|
140
|
+
if (typeof d.output === 'string')
|
|
141
|
+
output = d.output;
|
|
142
|
+
if (d.context)
|
|
143
|
+
context = d.context;
|
|
144
|
+
}
|
|
145
|
+
else if (d.decision === 'allow' && d.context) {
|
|
146
|
+
context = d.context;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { output, context };
|
|
150
|
+
}
|
|
151
|
+
export function aggregateUserPromptSubmit(decisions) {
|
|
152
|
+
const contexts = [];
|
|
153
|
+
for (const d of decisions) {
|
|
154
|
+
if (d.decision === 'deny')
|
|
155
|
+
return { decision: 'deny', reason: d.reason, context: '' };
|
|
156
|
+
// `context` is present on both 'allow' and 'modify' branches; the
|
|
157
|
+
// narrowing above eliminates 'deny', so this is safe.
|
|
158
|
+
if (d.decision === 'allow' && d.context)
|
|
159
|
+
contexts.push(d.context);
|
|
160
|
+
else if (d.decision === 'modify' && d.context)
|
|
161
|
+
contexts.push(d.context);
|
|
162
|
+
}
|
|
163
|
+
return { decision: 'allow', context: contexts.join('\n\n') };
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bus.js","sourceRoot":"","sources":["../../src/hooks/bus.ts"],"names":[],"mappings":"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"}
|