@phuetz/code-buddy 0.1.18 → 0.1.19

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 (273) hide show
  1. package/dist/agent/background-tasks.d.ts +49 -0
  2. package/dist/agent/background-tasks.js +153 -0
  3. package/dist/agent/background-tasks.js.map +1 -0
  4. package/dist/agent/definitions/agent-definition-loader.d.ts +21 -0
  5. package/dist/agent/definitions/agent-definition-loader.js +161 -0
  6. package/dist/agent/definitions/agent-definition-loader.js.map +1 -0
  7. package/dist/agent/definitions/index.d.ts +1 -0
  8. package/dist/agent/definitions/index.js +2 -0
  9. package/dist/agent/definitions/index.js.map +1 -0
  10. package/dist/agent/extended-thinking.d.ts +64 -0
  11. package/dist/agent/extended-thinking.js +103 -0
  12. package/dist/agent/extended-thinking.js.map +1 -0
  13. package/dist/agent/prompt-suggestions.d.ts +55 -0
  14. package/dist/agent/prompt-suggestions.js +125 -0
  15. package/dist/agent/prompt-suggestions.js.map +1 -0
  16. package/dist/agent/rewind-manager.d.ts +59 -0
  17. package/dist/agent/rewind-manager.js +124 -0
  18. package/dist/agent/rewind-manager.js.map +1 -0
  19. package/dist/agent/teams/agent-team.d.ts +54 -0
  20. package/dist/agent/teams/agent-team.js +114 -0
  21. package/dist/agent/teams/agent-team.js.map +1 -0
  22. package/dist/agent/teams/index.d.ts +1 -0
  23. package/dist/agent/teams/index.js +2 -0
  24. package/dist/agent/teams/index.js.map +1 -0
  25. package/dist/agent/teams/team-v2.d.ts +166 -0
  26. package/dist/agent/teams/team-v2.js +376 -0
  27. package/dist/agent/teams/team-v2.js.map +1 -0
  28. package/dist/channels/imessage/index.d.ts +40 -0
  29. package/dist/channels/imessage/index.js +69 -0
  30. package/dist/channels/imessage/index.js.map +1 -0
  31. package/dist/channels/line/index.d.ts +36 -0
  32. package/dist/channels/line/index.js +71 -0
  33. package/dist/channels/line/index.js.map +1 -0
  34. package/dist/channels/mattermost/index.d.ts +34 -0
  35. package/dist/channels/mattermost/index.js +56 -0
  36. package/dist/channels/mattermost/index.js.map +1 -0
  37. package/dist/channels/nextcloud-talk/index.d.ts +37 -0
  38. package/dist/channels/nextcloud-talk/index.js +67 -0
  39. package/dist/channels/nextcloud-talk/index.js.map +1 -0
  40. package/dist/channels/niche-channels.d.ts +61 -0
  41. package/dist/channels/niche-channels.js +131 -0
  42. package/dist/channels/niche-channels.js.map +1 -0
  43. package/dist/channels/nostr/index.d.ts +30 -0
  44. package/dist/channels/nostr/index.js +68 -0
  45. package/dist/channels/nostr/index.js.map +1 -0
  46. package/dist/channels/twilio-voice/index.d.ts +37 -0
  47. package/dist/channels/twilio-voice/index.js +76 -0
  48. package/dist/channels/twilio-voice/index.js.map +1 -0
  49. package/dist/channels/whatsapp/index.js +0 -1
  50. package/dist/channels/whatsapp/index.js.map +1 -1
  51. package/dist/channels/zalo/index.d.ts +28 -0
  52. package/dist/channels/zalo/index.js +53 -0
  53. package/dist/channels/zalo/index.js.map +1 -0
  54. package/dist/cloud/cloud-sessions.d.ts +56 -0
  55. package/dist/cloud/cloud-sessions.js +187 -0
  56. package/dist/cloud/cloud-sessions.js.map +1 -0
  57. package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
  58. package/dist/codebuddy/tool-definitions/advanced-tools.js +24 -0
  59. package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
  60. package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
  61. package/dist/codebuddy/tool-definitions/index.js +1 -1
  62. package/dist/codebuddy/tool-definitions/index.js.map +1 -1
  63. package/dist/commands/handlers/auth-handler.d.ts +32 -0
  64. package/dist/commands/handlers/auth-handler.js +137 -0
  65. package/dist/commands/handlers/auth-handler.js.map +1 -0
  66. package/dist/commands/handlers/context-handler.d.ts +46 -0
  67. package/dist/commands/handlers/context-handler.js +102 -0
  68. package/dist/commands/handlers/context-handler.js.map +1 -0
  69. package/dist/commands/handlers/keybindings-handler.d.ts +30 -0
  70. package/dist/commands/handlers/keybindings-handler.js +124 -0
  71. package/dist/commands/handlers/keybindings-handler.js.map +1 -0
  72. package/dist/commands/handlers/session-commands.d.ts +17 -0
  73. package/dist/commands/handlers/session-commands.js +119 -0
  74. package/dist/commands/handlers/session-commands.js.map +1 -0
  75. package/dist/commands/slash/builtin-commands.js +1 -1
  76. package/dist/commands/slash/builtin-commands.js.map +1 -1
  77. package/dist/config/admin-config.d.ts +54 -0
  78. package/dist/config/admin-config.js +144 -0
  79. package/dist/config/admin-config.js.map +1 -0
  80. package/dist/config/advanced-config.d.ts +118 -0
  81. package/dist/config/advanced-config.js +364 -0
  82. package/dist/config/advanced-config.js.map +1 -0
  83. package/dist/config/managed-policies.d.ts +50 -0
  84. package/dist/config/managed-policies.js +120 -0
  85. package/dist/config/managed-policies.js.map +1 -0
  86. package/dist/config/settings-hierarchy.d.ts +59 -0
  87. package/dist/config/settings-hierarchy.js +188 -0
  88. package/dist/config/settings-hierarchy.js.map +1 -0
  89. package/dist/config/tool-profiles.d.ts +37 -0
  90. package/dist/config/tool-profiles.js +150 -0
  91. package/dist/config/tool-profiles.js.map +1 -0
  92. package/dist/config/user-settings.d.ts +31 -0
  93. package/dist/config/user-settings.js +66 -0
  94. package/dist/config/user-settings.js.map +1 -0
  95. package/dist/context/context-files.d.ts +1 -1
  96. package/dist/context/context-files.js +2 -2
  97. package/dist/context/context-files.js.map +1 -1
  98. package/dist/context/partial-summarizer.d.ts +32 -0
  99. package/dist/context/partial-summarizer.js +144 -0
  100. package/dist/context/partial-summarizer.js.map +1 -0
  101. package/dist/desktop/desktop-app.d.ts +44 -0
  102. package/dist/desktop/desktop-app.js +136 -0
  103. package/dist/desktop/desktop-app.js.map +1 -0
  104. package/dist/git/worktree-sessions.d.ts +24 -0
  105. package/dist/git/worktree-sessions.js +93 -0
  106. package/dist/git/worktree-sessions.js.map +1 -0
  107. package/dist/hooks/advanced-hooks.d.ts +110 -0
  108. package/dist/hooks/advanced-hooks.js +256 -0
  109. package/dist/hooks/advanced-hooks.js.map +1 -0
  110. package/dist/hooks/async-hooks.d.ts +73 -0
  111. package/dist/hooks/async-hooks.js +213 -0
  112. package/dist/hooks/async-hooks.js.map +1 -0
  113. package/dist/hooks/env-persistence.d.ts +58 -0
  114. package/dist/hooks/env-persistence.js +195 -0
  115. package/dist/hooks/env-persistence.js.map +1 -0
  116. package/dist/hooks/hook-events.d.ts +36 -0
  117. package/dist/hooks/hook-events.js +55 -0
  118. package/dist/hooks/hook-events.js.map +1 -0
  119. package/dist/hooks/smart-hooks.d.ts +85 -0
  120. package/dist/hooks/smart-hooks.js +199 -0
  121. package/dist/hooks/smart-hooks.js.map +1 -0
  122. package/dist/ide/jetbrains-plugin.d.ts +55 -0
  123. package/dist/ide/jetbrains-plugin.js +156 -0
  124. package/dist/ide/jetbrains-plugin.js.map +1 -0
  125. package/dist/ide/vscode-extension.d.ts +94 -0
  126. package/dist/ide/vscode-extension.js +229 -0
  127. package/dist/ide/vscode-extension.js.map +1 -0
  128. package/dist/index.js +77 -3
  129. package/dist/index.js.map +1 -1
  130. package/dist/input/file-autocomplete.d.ts +42 -0
  131. package/dist/input/file-autocomplete.js +154 -0
  132. package/dist/input/file-autocomplete.js.map +1 -0
  133. package/dist/integrations/chrome-bridge.d.ts +90 -0
  134. package/dist/integrations/chrome-bridge.js +151 -0
  135. package/dist/integrations/chrome-bridge.js.map +1 -0
  136. package/dist/integrations/github-action-runner.d.ts +40 -0
  137. package/dist/integrations/github-action-runner.js +163 -0
  138. package/dist/integrations/github-action-runner.js.map +1 -0
  139. package/dist/integrations/gitlab-ci-runner.d.ts +34 -0
  140. package/dist/integrations/gitlab-ci-runner.js +104 -0
  141. package/dist/integrations/gitlab-ci-runner.js.map +1 -0
  142. package/dist/integrations/pr-session-linker.d.ts +44 -0
  143. package/dist/integrations/pr-session-linker.js +103 -0
  144. package/dist/integrations/pr-session-linker.js.map +1 -0
  145. package/dist/integrations/tailscale.d.ts +36 -0
  146. package/dist/integrations/tailscale.js +101 -0
  147. package/dist/integrations/tailscale.js.map +1 -0
  148. package/dist/lsp/lsp-client.d.ts +68 -0
  149. package/dist/lsp/lsp-client.js +182 -0
  150. package/dist/lsp/lsp-client.js.map +1 -0
  151. package/dist/mcp/connectors.d.ts +28 -0
  152. package/dist/mcp/connectors.js +148 -0
  153. package/dist/mcp/connectors.js.map +1 -0
  154. package/dist/mcp/index.d.ts +7 -4
  155. package/dist/mcp/index.js +7 -4
  156. package/dist/mcp/index.js.map +1 -1
  157. package/dist/mcp/mcp-auto-discovery.d.ts +49 -0
  158. package/dist/mcp/mcp-auto-discovery.js +104 -0
  159. package/dist/mcp/mcp-auto-discovery.js.map +1 -0
  160. package/dist/mcp/mcp-server.d.ts +70 -0
  161. package/dist/mcp/mcp-server.js +374 -0
  162. package/dist/mcp/mcp-server.js.map +1 -0
  163. package/dist/memory/auto-memory.d.ts +53 -0
  164. package/dist/memory/auto-memory.js +250 -0
  165. package/dist/memory/auto-memory.js.map +1 -0
  166. package/dist/memory/hybrid-search.d.ts +51 -0
  167. package/dist/memory/hybrid-search.js +199 -0
  168. package/dist/memory/hybrid-search.js.map +1 -0
  169. package/dist/memory/memory-flush.d.ts +51 -0
  170. package/dist/memory/memory-flush.js +102 -0
  171. package/dist/memory/memory-flush.js.map +1 -0
  172. package/dist/memory/subagent-memory.d.ts +73 -0
  173. package/dist/memory/subagent-memory.js +172 -0
  174. package/dist/memory/subagent-memory.js.map +1 -0
  175. package/dist/nodes/device-node.d.ts +40 -0
  176. package/dist/nodes/device-node.js +117 -0
  177. package/dist/nodes/device-node.js.map +1 -0
  178. package/dist/output/json-schema-output.d.ts +67 -0
  179. package/dist/output/json-schema-output.js +273 -0
  180. package/dist/output/json-schema-output.js.map +1 -0
  181. package/dist/persistence/session-picker.d.ts +22 -0
  182. package/dist/persistence/session-picker.js +47 -0
  183. package/dist/persistence/session-picker.js.map +1 -0
  184. package/dist/persistence/session-store.d.ts +11 -0
  185. package/dist/persistence/session-store.js +17 -0
  186. package/dist/persistence/session-store.js.map +1 -1
  187. package/dist/plugins/git-pinned-marketplace.d.ts +39 -0
  188. package/dist/plugins/git-pinned-marketplace.js +152 -0
  189. package/dist/plugins/git-pinned-marketplace.js.map +1 -0
  190. package/dist/plugins/plugin-manifest.d.ts +116 -0
  191. package/dist/plugins/plugin-manifest.js +283 -0
  192. package/dist/plugins/plugin-manifest.js.map +1 -0
  193. package/dist/sandbox/os-sandbox.d.ts +49 -1
  194. package/dist/sandbox/os-sandbox.js +347 -6
  195. package/dist/sandbox/os-sandbox.js.map +1 -1
  196. package/dist/sdk/agent-sdk.d.ts +61 -0
  197. package/dist/sdk/agent-sdk.js +90 -0
  198. package/dist/sdk/agent-sdk.js.map +1 -0
  199. package/dist/security/permission-modes.d.ts +76 -0
  200. package/dist/security/permission-modes.js +195 -0
  201. package/dist/security/permission-modes.js.map +1 -0
  202. package/dist/security/permission-patterns.d.ts +61 -0
  203. package/dist/security/permission-patterns.js +171 -0
  204. package/dist/security/permission-patterns.js.map +1 -0
  205. package/dist/security/safe-binaries.d.ts +23 -0
  206. package/dist/security/safe-binaries.js +96 -0
  207. package/dist/security/safe-binaries.js.map +1 -0
  208. package/dist/security/sender-policies.d.ts +46 -0
  209. package/dist/security/sender-policies.js +90 -0
  210. package/dist/security/sender-policies.js.map +1 -0
  211. package/dist/server/dashboard.d.ts +53 -0
  212. package/dist/server/dashboard.js +93 -0
  213. package/dist/server/dashboard.js.map +1 -0
  214. package/dist/services/system-prompt-override.d.ts +34 -0
  215. package/dist/services/system-prompt-override.js +64 -0
  216. package/dist/services/system-prompt-override.js.map +1 -0
  217. package/dist/skills/skill-enhancements.d.ts +37 -0
  218. package/dist/skills/skill-enhancements.js +69 -0
  219. package/dist/skills/skill-enhancements.js.map +1 -0
  220. package/dist/telemetry/otel-tracer.d.ts +98 -0
  221. package/dist/telemetry/otel-tracer.js +245 -0
  222. package/dist/telemetry/otel-tracer.js.map +1 -0
  223. package/dist/tools/browser-stub.d.ts +61 -0
  224. package/dist/tools/browser-stub.js +184 -0
  225. package/dist/tools/browser-stub.js.map +1 -0
  226. package/dist/tools/gateway-tool.d.ts +43 -0
  227. package/dist/tools/gateway-tool.js +92 -0
  228. package/dist/tools/gateway-tool.js.map +1 -0
  229. package/dist/tools/image-stub.d.ts +32 -0
  230. package/dist/tools/image-stub.js +97 -0
  231. package/dist/tools/image-stub.js.map +1 -0
  232. package/dist/tools/js-repl.d.ts +78 -0
  233. package/dist/tools/js-repl.js +280 -0
  234. package/dist/tools/js-repl.js.map +1 -0
  235. package/dist/tools/message-tool.d.ts +42 -0
  236. package/dist/tools/message-tool.js +113 -0
  237. package/dist/tools/message-tool.js.map +1 -0
  238. package/dist/ui/cli-enhancements.d.ts +178 -0
  239. package/dist/ui/cli-enhancements.js +430 -0
  240. package/dist/ui/cli-enhancements.js.map +1 -0
  241. package/dist/ui/status-line.d.ts +90 -0
  242. package/dist/ui/status-line.js +160 -0
  243. package/dist/ui/status-line.js.map +1 -0
  244. package/dist/ui/terminal-enhancements.d.ts +34 -0
  245. package/dist/ui/terminal-enhancements.js +97 -0
  246. package/dist/ui/terminal-enhancements.js.map +1 -0
  247. package/dist/ui/ui-enhancements.d.ts +38 -0
  248. package/dist/ui/ui-enhancements.js +116 -0
  249. package/dist/ui/ui-enhancements.js.map +1 -0
  250. package/dist/utils/custom-instructions.js +4 -1
  251. package/dist/utils/custom-instructions.js.map +1 -1
  252. package/dist/utils/init-project.d.ts +1 -1
  253. package/dist/utils/init-project.js +20 -20
  254. package/dist/utils/init-project.js.map +1 -1
  255. package/dist/utils/output-schema-validator.d.ts +40 -0
  256. package/dist/utils/output-schema-validator.js +137 -0
  257. package/dist/utils/output-schema-validator.js.map +1 -0
  258. package/dist/utils/safety-misc.d.ts +24 -0
  259. package/dist/utils/safety-misc.js +91 -0
  260. package/dist/utils/safety-misc.js.map +1 -0
  261. package/dist/utils/session-enhancements.d.ts +40 -0
  262. package/dist/utils/session-enhancements.js +118 -0
  263. package/dist/utils/session-enhancements.js.map +1 -0
  264. package/dist/utils/shell-snapshot.d.ts +38 -0
  265. package/dist/utils/shell-snapshot.js +323 -0
  266. package/dist/utils/shell-snapshot.js.map +1 -0
  267. package/dist/utils/stream-json-formatter.d.ts +77 -0
  268. package/dist/utils/stream-json-formatter.js +61 -0
  269. package/dist/utils/stream-json-formatter.js.map +1 -0
  270. package/dist/workflows/lobster-engine.d.ts +43 -0
  271. package/dist/workflows/lobster-engine.js +167 -0
  272. package/dist/workflows/lobster-engine.js.map +1 -0
  273. package/package.json +3 -6
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Advanced Hook System
3
+ *
4
+ * Extends the basic hook system with Claude Code-like capabilities:
5
+ * - Command hooks: run shell commands, parse JSON stdout for decisions
6
+ * - Prompt hooks: LLM-evaluated hooks (stub - returns allow with stored prompt)
7
+ * - Agent hooks: spawns subagent evaluation (stub - returns allow)
8
+ *
9
+ * Supports event matching with regex matchers, async fire-and-forget,
10
+ * one-shot hooks, and a registry for CRUD operations.
11
+ */
12
+ import { spawn } from 'child_process';
13
+ import { logger } from '../utils/logger.js';
14
+ export var HookEvent;
15
+ (function (HookEvent) {
16
+ HookEvent["PreToolUse"] = "PreToolUse";
17
+ HookEvent["PostToolUse"] = "PostToolUse";
18
+ HookEvent["PreBash"] = "PreBash";
19
+ HookEvent["PostBash"] = "PostBash";
20
+ HookEvent["PreEdit"] = "PreEdit";
21
+ HookEvent["PostEdit"] = "PostEdit";
22
+ HookEvent["SessionStart"] = "SessionStart";
23
+ HookEvent["SessionEnd"] = "SessionEnd";
24
+ HookEvent["PreCompact"] = "PreCompact";
25
+ HookEvent["Notification"] = "Notification";
26
+ HookEvent["SubagentStart"] = "SubagentStart";
27
+ HookEvent["SubagentStop"] = "SubagentStop";
28
+ HookEvent["PermissionRequest"] = "PermissionRequest";
29
+ HookEvent["TaskCompleted"] = "TaskCompleted";
30
+ })(HookEvent || (HookEvent = {}));
31
+ // ============================================================================
32
+ // AdvancedHookRunner
33
+ // ============================================================================
34
+ export class AdvancedHookRunner {
35
+ workingDirectory;
36
+ timeout;
37
+ constructor(workingDirectory = process.cwd(), timeout = 30000) {
38
+ this.workingDirectory = workingDirectory;
39
+ this.timeout = timeout;
40
+ }
41
+ /**
42
+ * Run a hook and return a decision
43
+ */
44
+ async runHook(hook, context) {
45
+ switch (hook.type) {
46
+ case 'command':
47
+ return this.runCommandHook(hook, context);
48
+ case 'prompt':
49
+ return this.runPromptHook(hook, context);
50
+ case 'agent':
51
+ return this.runAgentHook(hook, context);
52
+ default:
53
+ logger.warn(`Unknown hook type: ${hook.type}`, { source: 'AdvancedHookRunner' });
54
+ return { action: 'allow' };
55
+ }
56
+ }
57
+ /**
58
+ * Fire-and-forget async hook execution
59
+ */
60
+ async runHookAsync(hook, context) {
61
+ this.runHook(hook, context).catch((error) => {
62
+ logger.warn(`Async hook "${hook.name}" failed: ${error}`, { source: 'AdvancedHookRunner' });
63
+ });
64
+ }
65
+ /**
66
+ * Check if a hook matches a given event and optional tool name
67
+ */
68
+ matchesEvent(hook, event, toolName) {
69
+ if (hook.event !== event) {
70
+ return false;
71
+ }
72
+ if (hook.matcher && toolName) {
73
+ return hook.matcher.test(toolName);
74
+ }
75
+ // If no matcher, match all tools for that event
76
+ if (!hook.matcher) {
77
+ return true;
78
+ }
79
+ // Has matcher but no toolName provided - no match
80
+ return false;
81
+ }
82
+ async runCommandHook(hook, context) {
83
+ if (!hook.command) {
84
+ logger.warn(`Command hook "${hook.name}" has no command`, { source: 'AdvancedHookRunner' });
85
+ return { action: 'allow' };
86
+ }
87
+ return new Promise((resolve) => {
88
+ let timedOut = false;
89
+ const child = spawn(hook.command, [], {
90
+ cwd: this.workingDirectory,
91
+ shell: true,
92
+ env: {
93
+ ...process.env,
94
+ HOOK_EVENT: context.event,
95
+ HOOK_TOOL: context.toolName || '',
96
+ HOOK_INPUT: JSON.stringify(context.input || {}),
97
+ },
98
+ });
99
+ let stdout = '';
100
+ let stderr = '';
101
+ const timeoutId = setTimeout(() => {
102
+ timedOut = true;
103
+ child.kill('SIGTERM');
104
+ }, this.timeout);
105
+ child.stdout?.on('data', (data) => {
106
+ stdout += data.toString();
107
+ });
108
+ child.stderr?.on('data', (data) => {
109
+ stderr += data.toString();
110
+ });
111
+ child.on('close', (code) => {
112
+ clearTimeout(timeoutId);
113
+ if (timedOut) {
114
+ logger.warn(`Command hook "${hook.name}" timed out`, { source: 'AdvancedHookRunner' });
115
+ resolve({ action: 'allow' });
116
+ return;
117
+ }
118
+ if (code !== 0) {
119
+ logger.warn(`Command hook "${hook.name}" exited with code ${code}: ${stderr}`, { source: 'AdvancedHookRunner' });
120
+ resolve({ action: 'allow' });
121
+ return;
122
+ }
123
+ try {
124
+ const decision = JSON.parse(stdout.trim());
125
+ if (decision.action && ['allow', 'deny', 'ask'].includes(decision.action)) {
126
+ resolve(decision);
127
+ }
128
+ else {
129
+ logger.warn(`Command hook "${hook.name}" returned invalid action`, { source: 'AdvancedHookRunner' });
130
+ resolve({ action: 'allow' });
131
+ }
132
+ }
133
+ catch {
134
+ // Non-JSON output: if exit code 0, allow; non-zero handled above
135
+ resolve({ action: 'allow' });
136
+ }
137
+ });
138
+ child.on('error', (error) => {
139
+ clearTimeout(timeoutId);
140
+ logger.warn(`Command hook "${hook.name}" failed: ${error.message}`, { source: 'AdvancedHookRunner' });
141
+ resolve({ action: 'allow' });
142
+ });
143
+ });
144
+ }
145
+ async runPromptHook(hook, _context) {
146
+ // Stub: returns allow with the prompt text stored as additional context
147
+ logger.debug(`Prompt hook "${hook.name}" evaluated (stub)`, { source: 'AdvancedHookRunner' });
148
+ return {
149
+ action: 'allow',
150
+ additionalContext: hook.prompt || undefined,
151
+ };
152
+ }
153
+ async runAgentHook(hook, _context) {
154
+ // Stub: returns allow
155
+ logger.debug(`Agent hook "${hook.name}" evaluated (stub)`, { source: 'AdvancedHookRunner' });
156
+ return { action: 'allow' };
157
+ }
158
+ }
159
+ // ============================================================================
160
+ // HookRegistry
161
+ // ============================================================================
162
+ export class HookRegistry {
163
+ hooks = new Map();
164
+ firedOnceHooks = new Set();
165
+ /**
166
+ * Add a hook to the registry
167
+ */
168
+ addHook(hook) {
169
+ this.hooks.set(hook.name, hook);
170
+ logger.debug(`Hook "${hook.name}" registered for event ${hook.event}`, { source: 'HookRegistry' });
171
+ }
172
+ /**
173
+ * Remove a hook by name
174
+ */
175
+ removeHook(name) {
176
+ const deleted = this.hooks.delete(name);
177
+ this.firedOnceHooks.delete(name);
178
+ if (deleted) {
179
+ logger.debug(`Hook "${name}" removed`, { source: 'HookRegistry' });
180
+ }
181
+ return deleted;
182
+ }
183
+ /**
184
+ * Get all hooks that match a given event, filtering out already-fired once hooks
185
+ */
186
+ getHooksForEvent(event, toolName) {
187
+ const runner = new AdvancedHookRunner();
188
+ const matching = [];
189
+ for (const hook of this.hooks.values()) {
190
+ // Skip once hooks that already fired
191
+ if (hook.once && this.firedOnceHooks.has(hook.name)) {
192
+ continue;
193
+ }
194
+ if (runner.matchesEvent(hook, event, toolName)) {
195
+ matching.push(hook);
196
+ }
197
+ }
198
+ return matching;
199
+ }
200
+ /**
201
+ * Mark a once hook as fired
202
+ */
203
+ markFired(hookName) {
204
+ const hook = this.hooks.get(hookName);
205
+ if (hook?.once) {
206
+ this.firedOnceHooks.add(hookName);
207
+ }
208
+ }
209
+ /**
210
+ * List all registered hooks
211
+ */
212
+ listHooks() {
213
+ return Array.from(this.hooks.values());
214
+ }
215
+ /**
216
+ * Get a hook by name
217
+ */
218
+ getHook(name) {
219
+ return this.hooks.get(name);
220
+ }
221
+ /**
222
+ * Clear all hooks
223
+ */
224
+ clear() {
225
+ this.hooks.clear();
226
+ this.firedOnceHooks.clear();
227
+ }
228
+ /**
229
+ * Get the number of registered hooks
230
+ */
231
+ get size() {
232
+ return this.hooks.size;
233
+ }
234
+ }
235
+ // ============================================================================
236
+ // Singleton
237
+ // ============================================================================
238
+ let registryInstance = null;
239
+ let runnerInstance = null;
240
+ export function getHookRegistry() {
241
+ if (!registryInstance) {
242
+ registryInstance = new HookRegistry();
243
+ }
244
+ return registryInstance;
245
+ }
246
+ export function getAdvancedHookRunner(workingDirectory) {
247
+ if (!runnerInstance || workingDirectory) {
248
+ runnerInstance = new AdvancedHookRunner(workingDirectory);
249
+ }
250
+ return runnerInstance;
251
+ }
252
+ export function resetAdvancedHooks() {
253
+ registryInstance = null;
254
+ runnerInstance = null;
255
+ }
256
+ //# sourceMappingURL=advanced-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced-hooks.js","sourceRoot":"","sources":["../../src/hooks/advanced-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Async Hook Manager
3
+ *
4
+ * Manages asynchronous hook execution with concurrency control,
5
+ * job tracking, and result collection. Completed hook results
6
+ * can be injected as system messages into the next conversation turn.
7
+ */
8
+ import type { SmartHookConfig, SmartHookResult } from './smart-hooks.js';
9
+ export type AsyncHookStatus = 'running' | 'completed' | 'failed' | 'timeout' | 'cancelled';
10
+ export interface AsyncHookJob {
11
+ /** Unique job ID */
12
+ id: string;
13
+ /** Hook configuration */
14
+ hookConfig: SmartHookConfig;
15
+ /** Input data */
16
+ input: Record<string, any>;
17
+ /** Start timestamp */
18
+ startTime: number;
19
+ /** Current status */
20
+ status: AsyncHookStatus;
21
+ /** Result (when completed) */
22
+ result?: SmartHookResult;
23
+ /** Error message (when failed) */
24
+ error?: string;
25
+ }
26
+ export declare class AsyncHookManager {
27
+ private jobs;
28
+ private maxConcurrent;
29
+ private runner;
30
+ private completedSinceLastCheck;
31
+ private cancelTokens;
32
+ constructor(maxConcurrent?: number);
33
+ /**
34
+ * Submit an async hook for execution
35
+ */
36
+ submit(hook: SmartHookConfig, input: Record<string, any>): string;
37
+ /**
38
+ * Execute a job asynchronously
39
+ */
40
+ private executeJob;
41
+ /**
42
+ * Get a job by ID
43
+ */
44
+ getJob(jobId: string): AsyncHookJob | null;
45
+ /**
46
+ * Get all jobs completed since the last call to this method
47
+ */
48
+ getCompletedJobs(): AsyncHookJob[];
49
+ /**
50
+ * Get results formatted as system messages for the next conversation turn
51
+ */
52
+ getSystemMessages(): string[];
53
+ /**
54
+ * Clear all completed/failed jobs
55
+ */
56
+ clearCompleted(): void;
57
+ /**
58
+ * Cancel a running job
59
+ */
60
+ cancel(jobId: string): boolean;
61
+ /**
62
+ * Get the number of currently running jobs
63
+ */
64
+ getRunningCount(): number;
65
+ /**
66
+ * Get the total number of tracked jobs
67
+ */
68
+ getTotalCount(): number;
69
+ /**
70
+ * Dispose of all jobs and clean up
71
+ */
72
+ dispose(): void;
73
+ }
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Async Hook Manager
3
+ *
4
+ * Manages asynchronous hook execution with concurrency control,
5
+ * job tracking, and result collection. Completed hook results
6
+ * can be injected as system messages into the next conversation turn.
7
+ */
8
+ import { randomUUID } from 'crypto';
9
+ import { logger } from '../utils/logger.js';
10
+ import { SmartHookRunner } from './smart-hooks.js';
11
+ // ============================================================================
12
+ // AsyncHookManager
13
+ // ============================================================================
14
+ export class AsyncHookManager {
15
+ jobs = new Map();
16
+ maxConcurrent;
17
+ runner;
18
+ completedSinceLastCheck = [];
19
+ cancelTokens = new Map();
20
+ constructor(maxConcurrent) {
21
+ this.maxConcurrent = maxConcurrent ?? 10;
22
+ this.runner = new SmartHookRunner();
23
+ logger.debug(`AsyncHookManager initialized with max ${this.maxConcurrent} concurrent`, { source: 'AsyncHookManager' });
24
+ }
25
+ /**
26
+ * Submit an async hook for execution
27
+ */
28
+ submit(hook, input) {
29
+ // Check concurrency limit
30
+ const runningCount = this.getRunningCount();
31
+ if (runningCount >= this.maxConcurrent) {
32
+ logger.warn(`Max concurrent hooks reached (${this.maxConcurrent}), rejecting`, { source: 'AsyncHookManager' });
33
+ const jobId = randomUUID();
34
+ const job = {
35
+ id: jobId,
36
+ hookConfig: hook,
37
+ input,
38
+ startTime: Date.now(),
39
+ status: 'failed',
40
+ error: 'Max concurrent hooks reached',
41
+ };
42
+ this.jobs.set(jobId, job);
43
+ this.completedSinceLastCheck.push(jobId);
44
+ return jobId;
45
+ }
46
+ const jobId = randomUUID();
47
+ const job = {
48
+ id: jobId,
49
+ hookConfig: hook,
50
+ input,
51
+ startTime: Date.now(),
52
+ status: 'running',
53
+ };
54
+ this.jobs.set(jobId, job);
55
+ this.cancelTokens.set(jobId, false);
56
+ // Execute in background
57
+ this.executeJob(jobId, hook, input);
58
+ return jobId;
59
+ }
60
+ /**
61
+ * Execute a job asynchronously
62
+ */
63
+ async executeJob(jobId, hook, input) {
64
+ const timeout = hook.timeout ?? 30000;
65
+ try {
66
+ // Create a timeout race
67
+ const resultPromise = this.runner.runHook(hook, input);
68
+ const timeoutPromise = new Promise((_, reject) => {
69
+ setTimeout(() => reject(new Error('Hook execution timed out')), timeout);
70
+ });
71
+ const result = await Promise.race([resultPromise, timeoutPromise]);
72
+ const job = this.jobs.get(jobId);
73
+ if (!job)
74
+ return;
75
+ // Check if cancelled
76
+ if (this.cancelTokens.get(jobId)) {
77
+ job.status = 'cancelled';
78
+ job.error = 'Job was cancelled';
79
+ this.completedSinceLastCheck.push(jobId);
80
+ this.cancelTokens.delete(jobId);
81
+ return;
82
+ }
83
+ job.status = 'completed';
84
+ job.result = result;
85
+ this.completedSinceLastCheck.push(jobId);
86
+ this.cancelTokens.delete(jobId);
87
+ logger.debug(`Async hook ${jobId} completed`, { source: 'AsyncHookManager' });
88
+ }
89
+ catch (error) {
90
+ const job = this.jobs.get(jobId);
91
+ if (!job)
92
+ return;
93
+ const message = error instanceof Error ? error.message : String(error);
94
+ if (message.includes('timed out')) {
95
+ job.status = 'timeout';
96
+ job.error = 'Hook execution timed out';
97
+ }
98
+ else {
99
+ job.status = 'failed';
100
+ job.error = message;
101
+ }
102
+ this.completedSinceLastCheck.push(jobId);
103
+ this.cancelTokens.delete(jobId);
104
+ logger.warn(`Async hook ${jobId} failed: ${message}`, { source: 'AsyncHookManager' });
105
+ }
106
+ }
107
+ /**
108
+ * Get a job by ID
109
+ */
110
+ getJob(jobId) {
111
+ return this.jobs.get(jobId) ?? null;
112
+ }
113
+ /**
114
+ * Get all jobs completed since the last call to this method
115
+ */
116
+ getCompletedJobs() {
117
+ const completed = [];
118
+ for (const jobId of this.completedSinceLastCheck) {
119
+ const job = this.jobs.get(jobId);
120
+ if (job && job.status !== 'running') {
121
+ completed.push({ ...job });
122
+ }
123
+ }
124
+ this.completedSinceLastCheck = [];
125
+ return completed;
126
+ }
127
+ /**
128
+ * Get results formatted as system messages for the next conversation turn
129
+ */
130
+ getSystemMessages() {
131
+ const completed = this.getCompletedJobs();
132
+ const messages = [];
133
+ for (const job of completed) {
134
+ if (job.status === 'completed' && job.result) {
135
+ const prefix = `[Async Hook: ${job.hookConfig.event}]`;
136
+ if (job.result.ok) {
137
+ messages.push(`${prefix} Success: ${job.result.output ?? 'No output'}`);
138
+ }
139
+ else {
140
+ messages.push(`${prefix} Failed: ${job.result.reason ?? 'Unknown error'}`);
141
+ }
142
+ }
143
+ else if (job.status === 'failed' || job.status === 'timeout') {
144
+ messages.push(`[Async Hook: ${job.hookConfig.event}] Error: ${job.error ?? 'Unknown error'}`);
145
+ }
146
+ else if (job.status === 'cancelled') {
147
+ messages.push(`[Async Hook: ${job.hookConfig.event}] Cancelled`);
148
+ }
149
+ }
150
+ return messages;
151
+ }
152
+ /**
153
+ * Clear all completed/failed jobs
154
+ */
155
+ clearCompleted() {
156
+ const toRemove = [];
157
+ this.jobs.forEach((job, id) => {
158
+ if (job.status !== 'running') {
159
+ toRemove.push(id);
160
+ }
161
+ });
162
+ for (const id of toRemove) {
163
+ this.jobs.delete(id);
164
+ this.cancelTokens.delete(id);
165
+ }
166
+ logger.debug(`Cleared ${toRemove.length} completed jobs`, { source: 'AsyncHookManager' });
167
+ }
168
+ /**
169
+ * Cancel a running job
170
+ */
171
+ cancel(jobId) {
172
+ const job = this.jobs.get(jobId);
173
+ if (!job || job.status !== 'running') {
174
+ return false;
175
+ }
176
+ this.cancelTokens.set(jobId, true);
177
+ return true;
178
+ }
179
+ /**
180
+ * Get the number of currently running jobs
181
+ */
182
+ getRunningCount() {
183
+ let count = 0;
184
+ this.jobs.forEach((job) => {
185
+ if (job.status === 'running') {
186
+ count++;
187
+ }
188
+ });
189
+ return count;
190
+ }
191
+ /**
192
+ * Get the total number of tracked jobs
193
+ */
194
+ getTotalCount() {
195
+ return this.jobs.size;
196
+ }
197
+ /**
198
+ * Dispose of all jobs and clean up
199
+ */
200
+ dispose() {
201
+ // Mark all running as cancelled
202
+ this.jobs.forEach((job, id) => {
203
+ if (job.status === 'running') {
204
+ this.cancelTokens.set(id, true);
205
+ }
206
+ });
207
+ this.jobs.clear();
208
+ this.cancelTokens.clear();
209
+ this.completedSinceLastCheck = [];
210
+ logger.debug('AsyncHookManager disposed', { source: 'AsyncHookManager' });
211
+ }
212
+ }
213
+ //# sourceMappingURL=async-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-hooks.js","sourceRoot":"","sources":["../../src/hooks/async-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Environment Persistence
3
+ *
4
+ * Persists environment variables across sessions via env files.
5
+ * Supports setup hooks that modify env and captures changes for replay.
6
+ *
7
+ * Format: standard shell-compatible `export VAR=value` lines.
8
+ */
9
+ export declare class EnvPersistence {
10
+ private envFilePath;
11
+ private sessionEnv;
12
+ private sessionId;
13
+ constructor(sessionId?: string);
14
+ /**
15
+ * Get the path to the env persistence file
16
+ */
17
+ getEnvFilePath(): string;
18
+ /**
19
+ * Get the session ID
20
+ */
21
+ getSessionId(): string;
22
+ /**
23
+ * Set an environment variable and persist it
24
+ */
25
+ setVar(name: string, value: string): void;
26
+ /**
27
+ * Remove an environment variable
28
+ */
29
+ unsetVar(name: string): void;
30
+ /**
31
+ * Load all persisted environment variables from the env file
32
+ */
33
+ loadEnv(): Record<string, string>;
34
+ /**
35
+ * Apply all persisted env vars to process.env
36
+ */
37
+ applyToProcess(): void;
38
+ /**
39
+ * Parse an env file with `export VAR=value` format
40
+ */
41
+ parseEnvFile(content: string): Record<string, string>;
42
+ /**
43
+ * Serialize env vars to file content
44
+ */
45
+ serializeEnv(env: Record<string, string>): string;
46
+ /**
47
+ * Capture environment changes between before and after snapshots
48
+ */
49
+ captureEnvChanges(beforeEnv: Record<string, string>, afterEnv: Record<string, string>): Record<string, string>;
50
+ /**
51
+ * Clean up the env file
52
+ */
53
+ cleanup(): void;
54
+ /**
55
+ * Write current env state to file
56
+ */
57
+ private flush;
58
+ }