@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,195 @@
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
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import * as os from 'os';
12
+ import { randomUUID } from 'crypto';
13
+ import { logger } from '../utils/logger.js';
14
+ // ============================================================================
15
+ // EnvPersistence
16
+ // ============================================================================
17
+ export class EnvPersistence {
18
+ envFilePath;
19
+ sessionEnv;
20
+ sessionId;
21
+ constructor(sessionId) {
22
+ this.sessionId = sessionId ?? randomUUID();
23
+ this.envFilePath = path.join(os.tmpdir(), '.codebuddy-env', `session-${this.sessionId}.env`);
24
+ this.sessionEnv = {};
25
+ // Ensure directory exists
26
+ const dir = path.dirname(this.envFilePath);
27
+ if (!fs.existsSync(dir)) {
28
+ fs.mkdirSync(dir, { recursive: true });
29
+ }
30
+ // Load existing env file if present
31
+ if (fs.existsSync(this.envFilePath)) {
32
+ this.sessionEnv = this.loadEnv();
33
+ }
34
+ logger.debug(`EnvPersistence initialized for session ${this.sessionId}`, { source: 'EnvPersistence' });
35
+ }
36
+ /**
37
+ * Get the path to the env persistence file
38
+ */
39
+ getEnvFilePath() {
40
+ return this.envFilePath;
41
+ }
42
+ /**
43
+ * Get the session ID
44
+ */
45
+ getSessionId() {
46
+ return this.sessionId;
47
+ }
48
+ /**
49
+ * Set an environment variable and persist it
50
+ */
51
+ setVar(name, value) {
52
+ this.sessionEnv[name] = value;
53
+ this.flush();
54
+ logger.debug(`Env var set: ${name}`, { source: 'EnvPersistence' });
55
+ }
56
+ /**
57
+ * Remove an environment variable
58
+ */
59
+ unsetVar(name) {
60
+ delete this.sessionEnv[name];
61
+ this.flush();
62
+ logger.debug(`Env var unset: ${name}`, { source: 'EnvPersistence' });
63
+ }
64
+ /**
65
+ * Load all persisted environment variables from the env file
66
+ */
67
+ loadEnv() {
68
+ try {
69
+ if (!fs.existsSync(this.envFilePath)) {
70
+ return {};
71
+ }
72
+ const content = fs.readFileSync(this.envFilePath, 'utf-8');
73
+ const parsed = this.parseEnvFile(content);
74
+ this.sessionEnv = { ...parsed };
75
+ return { ...parsed };
76
+ }
77
+ catch (error) {
78
+ logger.warn(`Failed to load env file: ${error}`, { source: 'EnvPersistence' });
79
+ return {};
80
+ }
81
+ }
82
+ /**
83
+ * Apply all persisted env vars to process.env
84
+ */
85
+ applyToProcess() {
86
+ for (const [key, value] of Object.entries(this.sessionEnv)) {
87
+ process.env[key] = value;
88
+ }
89
+ logger.debug(`Applied ${Object.keys(this.sessionEnv).length} env vars to process`, { source: 'EnvPersistence' });
90
+ }
91
+ /**
92
+ * Parse an env file with `export VAR=value` format
93
+ */
94
+ parseEnvFile(content) {
95
+ const env = {};
96
+ const lines = content.split('\n');
97
+ for (const line of lines) {
98
+ const trimmed = line.trim();
99
+ // Skip empty lines and comments
100
+ if (!trimmed || trimmed.startsWith('#')) {
101
+ continue;
102
+ }
103
+ // Strip optional 'export ' prefix
104
+ const withoutExport = trimmed.startsWith('export ')
105
+ ? trimmed.slice(7)
106
+ : trimmed;
107
+ // Find first = sign
108
+ const eqIndex = withoutExport.indexOf('=');
109
+ if (eqIndex === -1) {
110
+ continue;
111
+ }
112
+ const key = withoutExport.slice(0, eqIndex).trim();
113
+ let value = withoutExport.slice(eqIndex + 1).trim();
114
+ // Strip surrounding quotes
115
+ if ((value.startsWith('"') && value.endsWith('"')) ||
116
+ (value.startsWith("'") && value.endsWith("'"))) {
117
+ value = value.slice(1, -1);
118
+ }
119
+ if (key) {
120
+ env[key] = value;
121
+ }
122
+ }
123
+ return env;
124
+ }
125
+ /**
126
+ * Serialize env vars to file content
127
+ */
128
+ serializeEnv(env) {
129
+ const lines = [
130
+ '# Code Buddy session environment',
131
+ `# Session: ${this.sessionId}`,
132
+ `# Generated: ${new Date().toISOString()}`,
133
+ '',
134
+ ];
135
+ const sortedKeys = Object.keys(env).sort();
136
+ for (const key of sortedKeys) {
137
+ const value = env[key];
138
+ // Quote values that contain spaces or special characters
139
+ const needsQuoting = /[\s"'$`\\!#&|;()]/.test(value);
140
+ const quotedValue = needsQuoting ? `"${value.replace(/["\\]/g, '\\$&')}"` : value;
141
+ lines.push(`export ${key}=${quotedValue}`);
142
+ }
143
+ return lines.join('\n') + '\n';
144
+ }
145
+ /**
146
+ * Capture environment changes between before and after snapshots
147
+ */
148
+ captureEnvChanges(beforeEnv, afterEnv) {
149
+ const changes = {};
150
+ for (const [key, value] of Object.entries(afterEnv)) {
151
+ if (beforeEnv[key] !== value) {
152
+ changes[key] = value;
153
+ }
154
+ }
155
+ // Persist captured changes
156
+ for (const [key, value] of Object.entries(changes)) {
157
+ this.sessionEnv[key] = value;
158
+ }
159
+ if (Object.keys(changes).length > 0) {
160
+ this.flush();
161
+ }
162
+ return changes;
163
+ }
164
+ /**
165
+ * Clean up the env file
166
+ */
167
+ cleanup() {
168
+ try {
169
+ if (fs.existsSync(this.envFilePath)) {
170
+ fs.unlinkSync(this.envFilePath);
171
+ }
172
+ }
173
+ catch (error) {
174
+ logger.warn(`Failed to cleanup env file: ${error}`, { source: 'EnvPersistence' });
175
+ }
176
+ this.sessionEnv = {};
177
+ }
178
+ /**
179
+ * Write current env state to file
180
+ */
181
+ flush() {
182
+ try {
183
+ const dir = path.dirname(this.envFilePath);
184
+ if (!fs.existsSync(dir)) {
185
+ fs.mkdirSync(dir, { recursive: true });
186
+ }
187
+ const content = this.serializeEnv(this.sessionEnv);
188
+ fs.writeFileSync(this.envFilePath, content, 'utf-8');
189
+ }
190
+ catch (error) {
191
+ logger.warn(`Failed to write env file: ${error}`, { source: 'EnvPersistence' });
192
+ }
193
+ }
194
+ }
195
+ //# sourceMappingURL=env-persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-persistence.js","sourceRoot":"","sources":["../../src/hooks/env-persistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Hook Events
3
+ *
4
+ * EventEmitter-based hook system for PreCompact, Notification, and PermissionRequest events.
5
+ * Singleton pattern for global event coordination.
6
+ */
7
+ import { EventEmitter } from 'events';
8
+ export interface PreCompactContext {
9
+ messageCount: number;
10
+ tokenCount: number;
11
+ }
12
+ export type NotificationType = 'permission_prompt' | 'idle_prompt' | 'auth_success' | 'elicitation_dialog';
13
+ export interface NotificationPayload {
14
+ type: NotificationType;
15
+ message: string;
16
+ }
17
+ export interface PermissionRequestPayload {
18
+ tool: string;
19
+ input: string;
20
+ }
21
+ export interface PermissionResponse {
22
+ action: 'allow' | 'deny' | 'ask';
23
+ updatedPermissions?: Record<string, string>;
24
+ }
25
+ export declare class HookEventEmitter extends EventEmitter {
26
+ private static instance;
27
+ constructor();
28
+ static getInstance(): HookEventEmitter;
29
+ static resetInstance(): void;
30
+ emitPreCompact(context: PreCompactContext): void;
31
+ emitNotification(notification: NotificationPayload): void;
32
+ emitPermissionRequest(request: PermissionRequestPayload): PermissionResponse;
33
+ onPreCompact(handler: (context: PreCompactContext) => void): void;
34
+ onNotification(handler: (notification: NotificationPayload) => void): void;
35
+ onPermissionRequest(handler: (request: PermissionRequestPayload) => PermissionResponse): void;
36
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Hook Events
3
+ *
4
+ * EventEmitter-based hook system for PreCompact, Notification, and PermissionRequest events.
5
+ * Singleton pattern for global event coordination.
6
+ */
7
+ import { EventEmitter } from 'events';
8
+ import { logger } from '../utils/logger.js';
9
+ // ============================================================================
10
+ // HookEventEmitter
11
+ // ============================================================================
12
+ export class HookEventEmitter extends EventEmitter {
13
+ static instance = null;
14
+ constructor() {
15
+ super();
16
+ logger.debug('HookEventEmitter initialized');
17
+ }
18
+ static getInstance() {
19
+ if (!HookEventEmitter.instance) {
20
+ HookEventEmitter.instance = new HookEventEmitter();
21
+ }
22
+ return HookEventEmitter.instance;
23
+ }
24
+ static resetInstance() {
25
+ if (HookEventEmitter.instance) {
26
+ HookEventEmitter.instance.removeAllListeners();
27
+ }
28
+ HookEventEmitter.instance = null;
29
+ }
30
+ emitPreCompact(context) {
31
+ this.emit('PreCompact', context);
32
+ }
33
+ emitNotification(notification) {
34
+ this.emit('Notification', notification);
35
+ }
36
+ emitPermissionRequest(request) {
37
+ const listeners = this.listeners('PermissionRequest');
38
+ if (listeners.length === 0) {
39
+ return { action: 'ask' };
40
+ }
41
+ // Call the first listener synchronously and return its result
42
+ const handler = listeners[0];
43
+ return handler(request);
44
+ }
45
+ onPreCompact(handler) {
46
+ this.on('PreCompact', handler);
47
+ }
48
+ onNotification(handler) {
49
+ this.on('Notification', handler);
50
+ }
51
+ onPermissionRequest(handler) {
52
+ this.on('PermissionRequest', handler);
53
+ }
54
+ }
55
+ //# sourceMappingURL=hook-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-events.js","sourceRoot":"","sources":["../../src/hooks/hook-events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AA4B5C,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACxC,MAAM,CAAC,QAAQ,GAA4B,IAAI,CAAC;IAExD;QACE,KAAK,EAAE,CAAC;QACR,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC;YAC/B,gBAAgB,CAAC,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,gBAAgB,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,aAAa;QAClB,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC;YAC9B,gBAAgB,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QACjD,CAAC;QACD,gBAAgB,CAAC,QAAQ,GAAG,IAAI,CAAC;IACnC,CAAC;IAED,cAAc,CAAC,OAA0B;QACvC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB,CAAC,YAAiC;QAChD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED,qBAAqB,CAAC,OAAiC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACtD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;QACD,8DAA8D;QAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAA0D,CAAC;QACtF,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,OAA6C;QACxD,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,cAAc,CAAC,OAAoD;QACjE,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,mBAAmB,CAAC,OAAkE;QACpF,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Smart Hook System
3
+ *
4
+ * Extends the hook system with prompt-based and agent-based hooks.
5
+ * Supports three hook types:
6
+ * - command: runs shell commands and parses output
7
+ * - prompt: evaluates LLM prompts with template rendering
8
+ * - agent: spawns sub-agent with restricted tool access
9
+ *
10
+ * Also supports async hook execution with result tracking.
11
+ */
12
+ export type SmartHookType = 'command' | 'prompt' | 'agent';
13
+ export interface SmartHookConfig {
14
+ /** Hook type */
15
+ type: SmartHookType;
16
+ /** Event name this hook responds to */
17
+ event: string;
18
+ /** For type: 'command' - shell command to run */
19
+ command?: string;
20
+ /** For type: 'prompt' - LLM prompt template with {{input}} placeholders */
21
+ prompt?: string;
22
+ /** For type: 'prompt' - model to use for evaluation */
23
+ model?: string;
24
+ /** For type: 'agent' - agent system prompt */
25
+ agentPrompt?: string;
26
+ /** For type: 'agent' - tools available to the agent */
27
+ agentTools?: string[];
28
+ /** For type: 'agent' - maximum agent turns (default: 5) */
29
+ maxTurns?: number;
30
+ /** Run in background */
31
+ async?: boolean;
32
+ /** Timeout in ms (default: 30000) */
33
+ timeout?: number;
34
+ }
35
+ export interface SmartHookResult {
36
+ /** Whether the hook succeeded */
37
+ ok: boolean;
38
+ /** Reason for failure */
39
+ reason?: string;
40
+ /** Hook output */
41
+ output?: string;
42
+ /** Execution duration in ms */
43
+ duration?: number;
44
+ }
45
+ export declare class SmartHookRunner {
46
+ private pendingResults;
47
+ private pendingCount;
48
+ constructor();
49
+ /**
50
+ * Run a hook synchronously and return result
51
+ */
52
+ runHook(hook: SmartHookConfig, input: Record<string, any>): Promise<SmartHookResult>;
53
+ /**
54
+ * Run a command-type hook
55
+ */
56
+ private runCommandHook;
57
+ /**
58
+ * Run a prompt-type hook (evaluates an LLM prompt template)
59
+ */
60
+ private runPromptHook;
61
+ /**
62
+ * Run an agent-type hook (spawns a sub-agent)
63
+ */
64
+ private runAgentHook;
65
+ /**
66
+ * Render a template string by replacing {{key}} placeholders with input values
67
+ */
68
+ renderTemplate(template: string, input: Record<string, any>): string;
69
+ /**
70
+ * Run a hook asynchronously in the background
71
+ */
72
+ runAsync(hook: SmartHookConfig, input: Record<string, any>): Promise<string>;
73
+ /**
74
+ * Get the result of an async hook by ID
75
+ */
76
+ getAsyncResult(hookId: string): SmartHookResult | null;
77
+ /**
78
+ * Check if there are any pending async hooks
79
+ */
80
+ hasPendingHooks(): boolean;
81
+ /**
82
+ * Get the number of pending async hooks
83
+ */
84
+ getPendingCount(): number;
85
+ }
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Smart Hook System
3
+ *
4
+ * Extends the hook system with prompt-based and agent-based hooks.
5
+ * Supports three hook types:
6
+ * - command: runs shell commands and parses output
7
+ * - prompt: evaluates LLM prompts with template rendering
8
+ * - agent: spawns sub-agent with restricted tool access
9
+ *
10
+ * Also supports async hook execution with result tracking.
11
+ */
12
+ import { spawn } from 'child_process';
13
+ import { randomUUID } from 'crypto';
14
+ import { logger } from '../utils/logger.js';
15
+ // ============================================================================
16
+ // SmartHookRunner
17
+ // ============================================================================
18
+ export class SmartHookRunner {
19
+ pendingResults = new Map();
20
+ pendingCount = 0;
21
+ constructor() {
22
+ logger.debug('SmartHookRunner initialized', { source: 'SmartHookRunner' });
23
+ }
24
+ /**
25
+ * Run a hook synchronously and return result
26
+ */
27
+ async runHook(hook, input) {
28
+ const startTime = Date.now();
29
+ try {
30
+ let result;
31
+ switch (hook.type) {
32
+ case 'command':
33
+ result = await this.runCommandHook(hook, input);
34
+ break;
35
+ case 'prompt':
36
+ result = await this.runPromptHook(hook, input);
37
+ break;
38
+ case 'agent':
39
+ result = await this.runAgentHook(hook, input);
40
+ break;
41
+ default:
42
+ result = {
43
+ ok: false,
44
+ reason: `Unknown hook type: ${hook.type}`,
45
+ };
46
+ }
47
+ result.duration = Date.now() - startTime;
48
+ return result;
49
+ }
50
+ catch (error) {
51
+ return {
52
+ ok: false,
53
+ reason: error instanceof Error ? error.message : String(error),
54
+ duration: Date.now() - startTime,
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Run a command-type hook
60
+ */
61
+ async runCommandHook(hook, input) {
62
+ if (!hook.command) {
63
+ return { ok: false, reason: 'No command specified for command hook' };
64
+ }
65
+ const renderedCommand = this.renderTemplate(hook.command, input);
66
+ const timeout = hook.timeout ?? 30000;
67
+ return new Promise((resolve) => {
68
+ let timedOut = false;
69
+ const child = spawn('/bin/sh', ['-c', renderedCommand], {
70
+ stdio: ['ignore', 'pipe', 'pipe'],
71
+ env: {
72
+ ...process.env,
73
+ HOOK_EVENT: hook.event,
74
+ HOOK_INPUT: JSON.stringify(input),
75
+ },
76
+ });
77
+ let stdout = '';
78
+ let stderr = '';
79
+ const timeoutId = setTimeout(() => {
80
+ timedOut = true;
81
+ child.kill('SIGTERM');
82
+ }, timeout);
83
+ child.stdout?.on('data', (data) => {
84
+ stdout += data.toString();
85
+ });
86
+ child.stderr?.on('data', (data) => {
87
+ stderr += data.toString();
88
+ });
89
+ child.on('close', (code) => {
90
+ clearTimeout(timeoutId);
91
+ if (timedOut) {
92
+ resolve({ ok: false, reason: 'Command hook timed out' });
93
+ return;
94
+ }
95
+ if (code !== 0) {
96
+ resolve({
97
+ ok: false,
98
+ reason: `Command exited with code ${code}: ${stderr.trim()}`,
99
+ output: stdout.trim(),
100
+ });
101
+ return;
102
+ }
103
+ resolve({
104
+ ok: true,
105
+ output: stdout.trim(),
106
+ });
107
+ });
108
+ child.on('error', (error) => {
109
+ clearTimeout(timeoutId);
110
+ resolve({ ok: false, reason: error.message });
111
+ });
112
+ });
113
+ }
114
+ /**
115
+ * Run a prompt-type hook (evaluates an LLM prompt template)
116
+ */
117
+ async runPromptHook(hook, input) {
118
+ if (!hook.prompt) {
119
+ return { ok: false, reason: 'No prompt specified for prompt hook' };
120
+ }
121
+ const renderedPrompt = this.renderTemplate(hook.prompt, input);
122
+ // Stub implementation: in production this would call the LLM
123
+ // For now, return the rendered prompt as output
124
+ logger.debug(`Prompt hook evaluated: ${renderedPrompt.substring(0, 100)}`, { source: 'SmartHookRunner' });
125
+ return {
126
+ ok: true,
127
+ output: renderedPrompt,
128
+ };
129
+ }
130
+ /**
131
+ * Run an agent-type hook (spawns a sub-agent)
132
+ */
133
+ async runAgentHook(hook, input) {
134
+ if (!hook.agentPrompt) {
135
+ return { ok: false, reason: 'No agent prompt specified for agent hook' };
136
+ }
137
+ const renderedPrompt = this.renderTemplate(hook.agentPrompt, input);
138
+ const maxTurns = hook.maxTurns ?? 5;
139
+ const tools = hook.agentTools ?? [];
140
+ // Stub implementation: in production this would spawn a sub-agent
141
+ logger.debug(`Agent hook evaluated with ${tools.length} tools, max ${maxTurns} turns`, { source: 'SmartHookRunner' });
142
+ return {
143
+ ok: true,
144
+ output: `Agent evaluated: ${renderedPrompt.substring(0, 200)}`,
145
+ };
146
+ }
147
+ /**
148
+ * Render a template string by replacing {{key}} placeholders with input values
149
+ */
150
+ renderTemplate(template, input) {
151
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
152
+ if (key in input) {
153
+ const value = input[key];
154
+ return typeof value === 'string' ? value : JSON.stringify(value);
155
+ }
156
+ return match;
157
+ });
158
+ }
159
+ /**
160
+ * Run a hook asynchronously in the background
161
+ */
162
+ async runAsync(hook, input) {
163
+ const hookId = randomUUID();
164
+ this.pendingCount++;
165
+ // Fire and forget
166
+ this.runHook(hook, input)
167
+ .then((result) => {
168
+ this.pendingResults.set(hookId, result);
169
+ this.pendingCount--;
170
+ })
171
+ .catch((error) => {
172
+ this.pendingResults.set(hookId, {
173
+ ok: false,
174
+ reason: error instanceof Error ? error.message : String(error),
175
+ });
176
+ this.pendingCount--;
177
+ });
178
+ return hookId;
179
+ }
180
+ /**
181
+ * Get the result of an async hook by ID
182
+ */
183
+ getAsyncResult(hookId) {
184
+ return this.pendingResults.get(hookId) ?? null;
185
+ }
186
+ /**
187
+ * Check if there are any pending async hooks
188
+ */
189
+ hasPendingHooks() {
190
+ return this.pendingCount > 0;
191
+ }
192
+ /**
193
+ * Get the number of pending async hooks
194
+ */
195
+ getPendingCount() {
196
+ return this.pendingCount;
197
+ }
198
+ }
199
+ //# sourceMappingURL=smart-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-hooks.js","sourceRoot":"","sources":["../../src/hooks/smart-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * JetBrains Plugin Scaffold
3
+ *
4
+ * Bridge between Code Buddy and JetBrains IDEs (IntelliJ IDEA, PyCharm,
5
+ * WebStorm, GoLand, etc). Provides diff viewing, selection sharing,
6
+ * diagnostic sharing, and quick launch integration.
7
+ */
8
+ export interface JetBrainsConfig {
9
+ enableDiffViewer: boolean;
10
+ enableSelectionSharing: boolean;
11
+ enableDiagnosticSharing: boolean;
12
+ quickLaunchShortcut: string;
13
+ supportedIDEs: string[];
14
+ }
15
+ export interface JetBrainsDiff {
16
+ file: string;
17
+ before: string;
18
+ after: string;
19
+ changeType: 'created' | 'modified' | 'deleted';
20
+ }
21
+ interface SharedSelection {
22
+ file: string;
23
+ text: string;
24
+ timestamp: number;
25
+ }
26
+ interface SharedDiagnostic {
27
+ file: string;
28
+ line: number;
29
+ message: string;
30
+ type: string;
31
+ }
32
+ export declare class JetBrainsBridge {
33
+ private config;
34
+ private diffs;
35
+ private sharedSelections;
36
+ private diagnostics;
37
+ constructor(config?: Partial<JetBrainsConfig>);
38
+ createDiff(file: string, before: string, after: string): JetBrainsDiff;
39
+ getDiffs(): JetBrainsDiff[];
40
+ acceptDiff(file: string): boolean;
41
+ rejectDiff(file: string): boolean;
42
+ clearDiffs(): void;
43
+ shareSelection(file: string, text: string): void;
44
+ getSharedSelections(): SharedSelection[];
45
+ shareDiagnostic(file: string, line: number, message: string, type: string): void;
46
+ getDiagnostics(): SharedDiagnostic[];
47
+ clearDiagnostics(): void;
48
+ getQuickLaunchShortcut(): string;
49
+ setQuickLaunchShortcut(shortcut: string): void;
50
+ getSupportedIDEs(): string[];
51
+ isIDESupported(ide: string): boolean;
52
+ generatePluginXml(): string;
53
+ getDiffCount(): number;
54
+ }
55
+ export {};