@phuetz/code-buddy 0.1.18 → 0.1.20

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 (355) 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/analytics/dashboard.js +1 -1
  29. package/dist/analytics/dashboard.js.map +1 -1
  30. package/dist/channels/imessage/index.d.ts +40 -0
  31. package/dist/channels/imessage/index.js +69 -0
  32. package/dist/channels/imessage/index.js.map +1 -0
  33. package/dist/channels/line/index.d.ts +36 -0
  34. package/dist/channels/line/index.js +71 -0
  35. package/dist/channels/line/index.js.map +1 -0
  36. package/dist/channels/mattermost/index.d.ts +34 -0
  37. package/dist/channels/mattermost/index.js +56 -0
  38. package/dist/channels/mattermost/index.js.map +1 -0
  39. package/dist/channels/nextcloud-talk/index.d.ts +37 -0
  40. package/dist/channels/nextcloud-talk/index.js +67 -0
  41. package/dist/channels/nextcloud-talk/index.js.map +1 -0
  42. package/dist/channels/niche-channels.d.ts +61 -0
  43. package/dist/channels/niche-channels.js +131 -0
  44. package/dist/channels/niche-channels.js.map +1 -0
  45. package/dist/channels/nostr/index.d.ts +30 -0
  46. package/dist/channels/nostr/index.js +68 -0
  47. package/dist/channels/nostr/index.js.map +1 -0
  48. package/dist/channels/twilio-voice/index.d.ts +37 -0
  49. package/dist/channels/twilio-voice/index.js +76 -0
  50. package/dist/channels/twilio-voice/index.js.map +1 -0
  51. package/dist/channels/whatsapp/index.js +0 -1
  52. package/dist/channels/whatsapp/index.js.map +1 -1
  53. package/dist/channels/zalo/index.d.ts +28 -0
  54. package/dist/channels/zalo/index.js +53 -0
  55. package/dist/channels/zalo/index.js.map +1 -0
  56. package/dist/cloud/cloud-sessions.d.ts +56 -0
  57. package/dist/cloud/cloud-sessions.js +187 -0
  58. package/dist/cloud/cloud-sessions.js.map +1 -0
  59. package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
  60. package/dist/codebuddy/tool-definitions/advanced-tools.js +24 -0
  61. package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
  62. package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
  63. package/dist/codebuddy/tool-definitions/index.js +1 -1
  64. package/dist/codebuddy/tool-definitions/index.js.map +1 -1
  65. package/dist/commands/delegate.js +2 -2
  66. package/dist/commands/delegate.js.map +1 -1
  67. package/dist/commands/features.d.ts +1 -1
  68. package/dist/commands/features.js +1 -1
  69. package/dist/commands/handlers/auth-handler.d.ts +32 -0
  70. package/dist/commands/handlers/auth-handler.js +137 -0
  71. package/dist/commands/handlers/auth-handler.js.map +1 -0
  72. package/dist/commands/handlers/context-handler.d.ts +46 -0
  73. package/dist/commands/handlers/context-handler.js +102 -0
  74. package/dist/commands/handlers/context-handler.js.map +1 -0
  75. package/dist/commands/handlers/core-handlers.js +1 -1
  76. package/dist/commands/handlers/core-handlers.js.map +1 -1
  77. package/dist/commands/handlers/keybindings-handler.d.ts +30 -0
  78. package/dist/commands/handlers/keybindings-handler.js +124 -0
  79. package/dist/commands/handlers/keybindings-handler.js.map +1 -0
  80. package/dist/commands/handlers/missing-handlers.js +15 -14
  81. package/dist/commands/handlers/missing-handlers.js.map +1 -1
  82. package/dist/commands/handlers/session-commands.d.ts +17 -0
  83. package/dist/commands/handlers/session-commands.js +119 -0
  84. package/dist/commands/handlers/session-commands.js.map +1 -0
  85. package/dist/commands/handlers/worktree-handlers.d.ts +1 -1
  86. package/dist/commands/handlers/worktree-handlers.js +2 -2
  87. package/dist/commands/slash/builtin-commands.js +2 -2
  88. package/dist/commands/slash/builtin-commands.js.map +1 -1
  89. package/dist/config/admin-config.d.ts +54 -0
  90. package/dist/config/admin-config.js +144 -0
  91. package/dist/config/admin-config.js.map +1 -0
  92. package/dist/config/advanced-config.d.ts +118 -0
  93. package/dist/config/advanced-config.js +364 -0
  94. package/dist/config/advanced-config.js.map +1 -0
  95. package/dist/config/constants.d.ts +2 -2
  96. package/dist/config/constants.js +2 -2
  97. package/dist/config/constants.js.map +1 -1
  98. package/dist/config/managed-policies.d.ts +50 -0
  99. package/dist/config/managed-policies.js +120 -0
  100. package/dist/config/managed-policies.js.map +1 -0
  101. package/dist/config/settings-hierarchy.d.ts +59 -0
  102. package/dist/config/settings-hierarchy.js +188 -0
  103. package/dist/config/settings-hierarchy.js.map +1 -0
  104. package/dist/config/toml-config.js +1 -1
  105. package/dist/config/toml-config.js.map +1 -1
  106. package/dist/config/tool-profiles.d.ts +37 -0
  107. package/dist/config/tool-profiles.js +150 -0
  108. package/dist/config/tool-profiles.js.map +1 -0
  109. package/dist/config/user-settings.d.ts +31 -0
  110. package/dist/config/user-settings.js +66 -0
  111. package/dist/config/user-settings.js.map +1 -0
  112. package/dist/context/context-files.d.ts +1 -1
  113. package/dist/context/context-files.js +3 -3
  114. package/dist/context/context-files.js.map +1 -1
  115. package/dist/context/partial-summarizer.d.ts +32 -0
  116. package/dist/context/partial-summarizer.js +144 -0
  117. package/dist/context/partial-summarizer.js.map +1 -0
  118. package/dist/desktop/desktop-app.d.ts +44 -0
  119. package/dist/desktop/desktop-app.js +136 -0
  120. package/dist/desktop/desktop-app.js.map +1 -0
  121. package/dist/features/index.d.ts +1 -1
  122. package/dist/features/index.js +2 -2
  123. package/dist/features/index.js.map +1 -1
  124. package/dist/git/worktree-sessions.d.ts +24 -0
  125. package/dist/git/worktree-sessions.js +93 -0
  126. package/dist/git/worktree-sessions.js.map +1 -0
  127. package/dist/hooks/advanced-hooks.d.ts +110 -0
  128. package/dist/hooks/advanced-hooks.js +256 -0
  129. package/dist/hooks/advanced-hooks.js.map +1 -0
  130. package/dist/hooks/async-hooks.d.ts +73 -0
  131. package/dist/hooks/async-hooks.js +213 -0
  132. package/dist/hooks/async-hooks.js.map +1 -0
  133. package/dist/hooks/env-persistence.d.ts +58 -0
  134. package/dist/hooks/env-persistence.js +195 -0
  135. package/dist/hooks/env-persistence.js.map +1 -0
  136. package/dist/hooks/hook-events.d.ts +36 -0
  137. package/dist/hooks/hook-events.js +55 -0
  138. package/dist/hooks/hook-events.js.map +1 -0
  139. package/dist/hooks/hook-system.js +1 -1
  140. package/dist/hooks/hook-system.js.map +1 -1
  141. package/dist/hooks/smart-hooks.d.ts +85 -0
  142. package/dist/hooks/smart-hooks.js +199 -0
  143. package/dist/hooks/smart-hooks.js.map +1 -0
  144. package/dist/ide/jetbrains-plugin.d.ts +55 -0
  145. package/dist/ide/jetbrains-plugin.js +156 -0
  146. package/dist/ide/jetbrains-plugin.js.map +1 -0
  147. package/dist/ide/vscode-extension.d.ts +94 -0
  148. package/dist/ide/vscode-extension.js +229 -0
  149. package/dist/ide/vscode-extension.js.map +1 -0
  150. package/dist/index.js +77 -3
  151. package/dist/index.js.map +1 -1
  152. package/dist/input/file-autocomplete.d.ts +42 -0
  153. package/dist/input/file-autocomplete.js +154 -0
  154. package/dist/input/file-autocomplete.js.map +1 -0
  155. package/dist/integrations/chrome-bridge.d.ts +90 -0
  156. package/dist/integrations/chrome-bridge.js +151 -0
  157. package/dist/integrations/chrome-bridge.js.map +1 -0
  158. package/dist/integrations/github-action-runner.d.ts +40 -0
  159. package/dist/integrations/github-action-runner.js +163 -0
  160. package/dist/integrations/github-action-runner.js.map +1 -0
  161. package/dist/integrations/github-actions.js +1 -1
  162. package/dist/integrations/github-actions.js.map +1 -1
  163. package/dist/integrations/gitlab-ci-runner.d.ts +34 -0
  164. package/dist/integrations/gitlab-ci-runner.js +104 -0
  165. package/dist/integrations/gitlab-ci-runner.js.map +1 -0
  166. package/dist/integrations/pr-session-linker.d.ts +44 -0
  167. package/dist/integrations/pr-session-linker.js +103 -0
  168. package/dist/integrations/pr-session-linker.js.map +1 -0
  169. package/dist/integrations/tailscale.d.ts +36 -0
  170. package/dist/integrations/tailscale.js +101 -0
  171. package/dist/integrations/tailscale.js.map +1 -0
  172. package/dist/lsp/lsp-client.d.ts +68 -0
  173. package/dist/lsp/lsp-client.js +182 -0
  174. package/dist/lsp/lsp-client.js.map +1 -0
  175. package/dist/lsp/server.js +3 -3
  176. package/dist/lsp/server.js.map +1 -1
  177. package/dist/mcp/connectors.d.ts +28 -0
  178. package/dist/mcp/connectors.js +148 -0
  179. package/dist/mcp/connectors.js.map +1 -0
  180. package/dist/mcp/index.d.ts +7 -4
  181. package/dist/mcp/index.js +7 -4
  182. package/dist/mcp/index.js.map +1 -1
  183. package/dist/mcp/mcp-auto-discovery.d.ts +49 -0
  184. package/dist/mcp/mcp-auto-discovery.js +104 -0
  185. package/dist/mcp/mcp-auto-discovery.js.map +1 -0
  186. package/dist/mcp/mcp-server.d.ts +70 -0
  187. package/dist/mcp/mcp-server.js +374 -0
  188. package/dist/mcp/mcp-server.js.map +1 -0
  189. package/dist/memory/auto-memory.d.ts +53 -0
  190. package/dist/memory/auto-memory.js +250 -0
  191. package/dist/memory/auto-memory.js.map +1 -0
  192. package/dist/memory/hybrid-search.d.ts +51 -0
  193. package/dist/memory/hybrid-search.js +199 -0
  194. package/dist/memory/hybrid-search.js.map +1 -0
  195. package/dist/memory/memory-flush.d.ts +51 -0
  196. package/dist/memory/memory-flush.js +102 -0
  197. package/dist/memory/memory-flush.js.map +1 -0
  198. package/dist/memory/subagent-memory.d.ts +73 -0
  199. package/dist/memory/subagent-memory.js +172 -0
  200. package/dist/memory/subagent-memory.js.map +1 -0
  201. package/dist/nodes/device-node.d.ts +40 -0
  202. package/dist/nodes/device-node.js +117 -0
  203. package/dist/nodes/device-node.js.map +1 -0
  204. package/dist/observability/dashboard.d.ts +1 -1
  205. package/dist/observability/dashboard.js +2 -2
  206. package/dist/observability/dashboard.js.map +1 -1
  207. package/dist/offline/offline-mode.d.ts +1 -1
  208. package/dist/offline/offline-mode.js +1 -1
  209. package/dist/output/json-schema-output.d.ts +67 -0
  210. package/dist/output/json-schema-output.js +273 -0
  211. package/dist/output/json-schema-output.js.map +1 -0
  212. package/dist/persistence/session-picker.d.ts +22 -0
  213. package/dist/persistence/session-picker.js +47 -0
  214. package/dist/persistence/session-picker.js.map +1 -0
  215. package/dist/persistence/session-store.d.ts +11 -0
  216. package/dist/persistence/session-store.js +17 -0
  217. package/dist/persistence/session-store.js.map +1 -1
  218. package/dist/plugins/git-pinned-marketplace.d.ts +39 -0
  219. package/dist/plugins/git-pinned-marketplace.js +152 -0
  220. package/dist/plugins/git-pinned-marketplace.js.map +1 -0
  221. package/dist/plugins/marketplace.d.ts +1 -1
  222. package/dist/plugins/marketplace.js +1 -1
  223. package/dist/plugins/plugin-manifest.d.ts +116 -0
  224. package/dist/plugins/plugin-manifest.js +283 -0
  225. package/dist/plugins/plugin-manifest.js.map +1 -0
  226. package/dist/prompts/index.d.ts +1 -1
  227. package/dist/prompts/index.js +1 -1
  228. package/dist/providers/local-llm-provider.d.ts +1 -1
  229. package/dist/providers/local-llm-provider.js +1 -1
  230. package/dist/sandbox/os-sandbox.d.ts +49 -1
  231. package/dist/sandbox/os-sandbox.js +347 -6
  232. package/dist/sandbox/os-sandbox.js.map +1 -1
  233. package/dist/scripting/codebuddy-bindings.js +1 -1
  234. package/dist/scripting/codebuddy-bindings.js.map +1 -1
  235. package/dist/sdk/agent-sdk.d.ts +61 -0
  236. package/dist/sdk/agent-sdk.js +90 -0
  237. package/dist/sdk/agent-sdk.js.map +1 -0
  238. package/dist/security/index.d.ts +1 -1
  239. package/dist/security/index.js +1 -1
  240. package/dist/security/permission-modes.d.ts +76 -0
  241. package/dist/security/permission-modes.js +195 -0
  242. package/dist/security/permission-modes.js.map +1 -0
  243. package/dist/security/permission-patterns.d.ts +61 -0
  244. package/dist/security/permission-patterns.js +171 -0
  245. package/dist/security/permission-patterns.js.map +1 -0
  246. package/dist/security/safe-binaries.d.ts +23 -0
  247. package/dist/security/safe-binaries.js +96 -0
  248. package/dist/security/safe-binaries.js.map +1 -0
  249. package/dist/security/sender-policies.d.ts +46 -0
  250. package/dist/security/sender-policies.js +90 -0
  251. package/dist/security/sender-policies.js.map +1 -0
  252. package/dist/server/dashboard.d.ts +53 -0
  253. package/dist/server/dashboard.js +93 -0
  254. package/dist/server/dashboard.js.map +1 -0
  255. package/dist/services/system-prompt-override.d.ts +34 -0
  256. package/dist/services/system-prompt-override.js +64 -0
  257. package/dist/services/system-prompt-override.js.map +1 -0
  258. package/dist/skills/skill-enhancements.d.ts +37 -0
  259. package/dist/skills/skill-enhancements.js +69 -0
  260. package/dist/skills/skill-enhancements.js.map +1 -0
  261. package/dist/telemetry/otel-tracer.d.ts +98 -0
  262. package/dist/telemetry/otel-tracer.js +245 -0
  263. package/dist/telemetry/otel-tracer.js.map +1 -0
  264. package/dist/templates/export/html.template.js +2 -2
  265. package/dist/templates/export/markdown.template.js +1 -1
  266. package/dist/templates/export/markdown.template.js.map +1 -1
  267. package/dist/themes/default-themes.d.ts +1 -1
  268. package/dist/themes/default-themes.js +1 -1
  269. package/dist/themes/index.d.ts +1 -1
  270. package/dist/themes/index.js +1 -1
  271. package/dist/themes/theme-manager.d.ts +1 -1
  272. package/dist/themes/theme-manager.js +1 -1
  273. package/dist/themes/theme.d.ts +1 -1
  274. package/dist/themes/theme.js +1 -1
  275. package/dist/tools/browser-stub.d.ts +61 -0
  276. package/dist/tools/browser-stub.js +184 -0
  277. package/dist/tools/browser-stub.js.map +1 -0
  278. package/dist/tools/gateway-tool.d.ts +43 -0
  279. package/dist/tools/gateway-tool.js +92 -0
  280. package/dist/tools/gateway-tool.js.map +1 -0
  281. package/dist/tools/image-stub.d.ts +32 -0
  282. package/dist/tools/image-stub.js +97 -0
  283. package/dist/tools/image-stub.js.map +1 -0
  284. package/dist/tools/js-repl.d.ts +78 -0
  285. package/dist/tools/js-repl.js +280 -0
  286. package/dist/tools/js-repl.js.map +1 -0
  287. package/dist/tools/message-tool.d.ts +42 -0
  288. package/dist/tools/message-tool.js +113 -0
  289. package/dist/tools/message-tool.js.map +1 -0
  290. package/dist/types/errors.d.ts +1 -1
  291. package/dist/types/errors.js +1 -1
  292. package/dist/ui/app.js +1 -1
  293. package/dist/ui/app.js.map +1 -1
  294. package/dist/ui/cli-enhancements.d.ts +178 -0
  295. package/dist/ui/cli-enhancements.js +430 -0
  296. package/dist/ui/cli-enhancements.js.map +1 -0
  297. package/dist/ui/components/HelpSystem.d.ts +1 -1
  298. package/dist/ui/components/HelpSystem.js +1 -1
  299. package/dist/ui/context/theme-context.d.ts +1 -1
  300. package/dist/ui/context/theme-context.js +1 -1
  301. package/dist/ui/dashboard/dashboard.js +1 -1
  302. package/dist/ui/dashboard/dashboard.js.map +1 -1
  303. package/dist/ui/status-line.d.ts +90 -0
  304. package/dist/ui/status-line.js +160 -0
  305. package/dist/ui/status-line.js.map +1 -0
  306. package/dist/ui/terminal-enhancements.d.ts +34 -0
  307. package/dist/ui/terminal-enhancements.js +97 -0
  308. package/dist/ui/terminal-enhancements.js.map +1 -0
  309. package/dist/ui/ui-enhancements.d.ts +38 -0
  310. package/dist/ui/ui-enhancements.js +116 -0
  311. package/dist/ui/ui-enhancements.js.map +1 -0
  312. package/dist/undo/checkpoint-manager.d.ts +1 -1
  313. package/dist/undo/checkpoint-manager.js +1 -1
  314. package/dist/utils/codebuddy-home.d.ts +1 -1
  315. package/dist/utils/codebuddy-home.js +1 -1
  316. package/dist/utils/conversation-export.js +3 -3
  317. package/dist/utils/conversation-export.js.map +1 -1
  318. package/dist/utils/custom-commands.js +1 -1
  319. package/dist/utils/custom-instructions.js +4 -1
  320. package/dist/utils/custom-instructions.js.map +1 -1
  321. package/dist/utils/debug-logger.d.ts +1 -1
  322. package/dist/utils/debug-logger.js +1 -1
  323. package/dist/utils/errors.d.ts +2 -2
  324. package/dist/utils/errors.js +2 -2
  325. package/dist/utils/export-manager.js +3 -3
  326. package/dist/utils/export-manager.js.map +1 -1
  327. package/dist/utils/headless-output.js +1 -1
  328. package/dist/utils/headless-output.js.map +1 -1
  329. package/dist/utils/init-project.d.ts +1 -1
  330. package/dist/utils/init-project.js +20 -20
  331. package/dist/utils/init-project.js.map +1 -1
  332. package/dist/utils/logger.d.ts +1 -1
  333. package/dist/utils/logger.js +1 -1
  334. package/dist/utils/output-schema-validator.d.ts +40 -0
  335. package/dist/utils/output-schema-validator.js +137 -0
  336. package/dist/utils/output-schema-validator.js.map +1 -0
  337. package/dist/utils/safety-misc.d.ts +24 -0
  338. package/dist/utils/safety-misc.js +91 -0
  339. package/dist/utils/safety-misc.js.map +1 -0
  340. package/dist/utils/session-enhancements.d.ts +40 -0
  341. package/dist/utils/session-enhancements.js +118 -0
  342. package/dist/utils/session-enhancements.js.map +1 -0
  343. package/dist/utils/shell-completions.js +6 -6
  344. package/dist/utils/shell-snapshot.d.ts +38 -0
  345. package/dist/utils/shell-snapshot.js +323 -0
  346. package/dist/utils/shell-snapshot.js.map +1 -0
  347. package/dist/utils/stream-json-formatter.d.ts +77 -0
  348. package/dist/utils/stream-json-formatter.js +61 -0
  349. package/dist/utils/stream-json-formatter.js.map +1 -0
  350. package/dist/utils/terminal-notifications.js +1 -1
  351. package/dist/utils/terminal-notifications.js.map +1 -1
  352. package/dist/workflows/lobster-engine.d.ts +43 -0
  353. package/dist/workflows/lobster-engine.js +167 -0
  354. package/dist/workflows/lobster-engine.js.map +1 -0
  355. package/package.json +3 -6
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Pattern-based Permissions
3
+ *
4
+ * Provides fine-grained permission control for tool executions using
5
+ * glob-pattern matching. Rules are evaluated in order; first match wins.
6
+ *
7
+ * Tool specifier format:
8
+ * Bash(npm run *) → matches Bash tool with commands starting "npm run "
9
+ * Edit(./src/**) → matches Edit tool with paths under ./src/
10
+ * Read(./.env) → matches Read tool on exactly ./.env
11
+ * WebFetch(domain:example.com) → matches WebFetch for a specific domain
12
+ * Bash → matches all Bash invocations (no pattern)
13
+ *
14
+ * Pattern rules:
15
+ * * → matches any characters except /
16
+ * ** → matches anything including /
17
+ */
18
+ import { logger } from '../utils/logger.js';
19
+ // ============================================================================
20
+ // Pattern Matching
21
+ // ============================================================================
22
+ /**
23
+ * Convert a glob pattern to a RegExp.
24
+ * ** → matches anything (including /)
25
+ * * → matches anything except /
26
+ */
27
+ function globToRegex(pattern) {
28
+ let result = '';
29
+ let i = 0;
30
+ while (i < pattern.length) {
31
+ const char = pattern[i];
32
+ if (char === '*' && pattern[i + 1] === '*') {
33
+ // ** matches anything including /
34
+ result += '.*';
35
+ i += 2;
36
+ // skip trailing / after **
37
+ if (pattern[i] === '/') {
38
+ i++;
39
+ }
40
+ }
41
+ else if (char === '*') {
42
+ // * matches anything except /
43
+ result += '[^/]*';
44
+ i++;
45
+ }
46
+ else if (char === '?') {
47
+ result += '[^/]';
48
+ i++;
49
+ }
50
+ else {
51
+ // Escape regex special characters
52
+ result += char.replace(/[.+^${}()|[\]\\]/g, '\\$&');
53
+ i++;
54
+ }
55
+ }
56
+ return new RegExp('^' + result + '$');
57
+ }
58
+ // ============================================================================
59
+ // PermissionPatternMatcher
60
+ // ============================================================================
61
+ export class PermissionPatternMatcher {
62
+ rules = [];
63
+ /**
64
+ * Add a permission rule.
65
+ */
66
+ addRule(rule) {
67
+ this.rules.push(rule);
68
+ }
69
+ /**
70
+ * Check permission for a tool call. Evaluates rules in order; first match wins.
71
+ * If no rule matches, returns 'ask' as default.
72
+ */
73
+ checkPermission(tool, input) {
74
+ for (const rule of this.rules) {
75
+ if (rule.tool !== tool) {
76
+ continue;
77
+ }
78
+ // If rule has no pattern, it matches all invocations of this tool
79
+ if (!rule.pattern) {
80
+ return rule.action;
81
+ }
82
+ // Domain-based matching for WebFetch
83
+ if (rule.pattern.startsWith('domain:')) {
84
+ const domain = rule.pattern.slice('domain:'.length);
85
+ if (input.includes(domain)) {
86
+ return rule.action;
87
+ }
88
+ continue;
89
+ }
90
+ // Glob pattern matching
91
+ const regex = globToRegex(rule.pattern);
92
+ if (regex.test(input)) {
93
+ return rule.action;
94
+ }
95
+ }
96
+ // Default: ask
97
+ return 'ask';
98
+ }
99
+ /**
100
+ * Parse a tool specifier string like "Bash(npm run *)" into components.
101
+ */
102
+ parseToolSpecifier(spec) {
103
+ const match = spec.match(/^([A-Za-z_]+)(?:\((.+)\))?$/);
104
+ if (!match) {
105
+ throw new Error(`Invalid tool specifier: ${spec}`);
106
+ }
107
+ return {
108
+ tool: match[1],
109
+ pattern: match[2] || undefined,
110
+ };
111
+ }
112
+ /**
113
+ * Load rules from an array of strings like "allow:Bash(npm run *)".
114
+ */
115
+ loadRules(ruleStrings) {
116
+ for (const ruleStr of ruleStrings) {
117
+ const colonIndex = ruleStr.indexOf(':');
118
+ if (colonIndex === -1) {
119
+ logger.warn('Invalid rule string (missing action prefix)', { rule: ruleStr });
120
+ continue;
121
+ }
122
+ const action = ruleStr.slice(0, colonIndex);
123
+ if (action !== 'allow' && action !== 'ask' && action !== 'deny') {
124
+ logger.warn('Invalid permission action', { action, rule: ruleStr });
125
+ continue;
126
+ }
127
+ const specStr = ruleStr.slice(colonIndex + 1);
128
+ const spec = this.parseToolSpecifier(specStr);
129
+ this.addRule({
130
+ tool: spec.tool,
131
+ pattern: spec.pattern,
132
+ action,
133
+ });
134
+ }
135
+ }
136
+ /**
137
+ * Get all current rules.
138
+ */
139
+ getRules() {
140
+ return [...this.rules];
141
+ }
142
+ /**
143
+ * Clear all rules.
144
+ */
145
+ clearRules() {
146
+ this.rules = [];
147
+ }
148
+ /**
149
+ * Remove a rule by index.
150
+ */
151
+ removeRule(index) {
152
+ if (index < 0 || index >= this.rules.length) {
153
+ throw new Error(`Rule index out of bounds: ${index}`);
154
+ }
155
+ this.rules.splice(index, 1);
156
+ }
157
+ }
158
+ // ============================================================================
159
+ // Singleton
160
+ // ============================================================================
161
+ let instance = null;
162
+ export function getPermissionMatcher() {
163
+ if (!instance) {
164
+ instance = new PermissionPatternMatcher();
165
+ }
166
+ return instance;
167
+ }
168
+ export function resetPermissionMatcher() {
169
+ instance = null;
170
+ }
171
+ //# sourceMappingURL=permission-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-patterns.js","sourceRoot":"","sources":["../../src/security/permission-patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Safe Binaries System
3
+ *
4
+ * Maintains a list of commands that are safe to execute without
5
+ * user approval. These are read-only or informational commands
6
+ * that cannot modify the filesystem or system state.
7
+ */
8
+ export declare const SAFE_BINARIES: readonly string[];
9
+ export declare class SafeBinariesChecker {
10
+ private static instance;
11
+ private safeBinaries;
12
+ private customized;
13
+ private constructor();
14
+ static getInstance(): SafeBinariesChecker;
15
+ static resetInstance(): void;
16
+ isSafe(command: string): boolean;
17
+ isSafeChain(command: string): boolean;
18
+ getSafeBinaries(): string[];
19
+ addSafeBinary(name: string): void;
20
+ removeSafeBinary(name: string): void;
21
+ isCustomized(): boolean;
22
+ private extractFirstWord;
23
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Safe Binaries System
3
+ *
4
+ * Maintains a list of commands that are safe to execute without
5
+ * user approval. These are read-only or informational commands
6
+ * that cannot modify the filesystem or system state.
7
+ */
8
+ import { logger } from '../utils/logger.js';
9
+ // ============================================================================
10
+ // Safe Binaries List
11
+ // ============================================================================
12
+ export const SAFE_BINARIES = [
13
+ 'ls', 'cat', 'head', 'tail', 'wc', 'grep', 'rg', 'find',
14
+ 'which', 'whoami', 'pwd', 'echo', 'date', 'uname', 'hostname',
15
+ 'env', 'printenv', 'file', 'stat', 'du', 'df', 'free', 'uptime',
16
+ 'id', 'groups', 'locale', 'tty', 'stty', 'basename', 'dirname',
17
+ 'realpath', 'readlink', 'md5sum', 'sha256sum', 'sort', 'uniq',
18
+ 'tr', 'cut', 'paste', 'diff', 'comm', 'tee', 'xargs', 'seq',
19
+ 'yes', 'true', 'false', 'test', 'expr',
20
+ ];
21
+ // ============================================================================
22
+ // SafeBinariesChecker
23
+ // ============================================================================
24
+ export class SafeBinariesChecker {
25
+ static instance = null;
26
+ safeBinaries;
27
+ customized = false;
28
+ constructor() {
29
+ this.safeBinaries = new Set(SAFE_BINARIES);
30
+ }
31
+ static getInstance() {
32
+ if (!SafeBinariesChecker.instance) {
33
+ SafeBinariesChecker.instance = new SafeBinariesChecker();
34
+ }
35
+ return SafeBinariesChecker.instance;
36
+ }
37
+ static resetInstance() {
38
+ SafeBinariesChecker.instance = null;
39
+ }
40
+ isSafe(command) {
41
+ const trimmed = command.trim();
42
+ if (!trimmed)
43
+ return false;
44
+ const firstWord = this.extractFirstWord(trimmed);
45
+ return this.safeBinaries.has(firstWord);
46
+ }
47
+ isSafeChain(command) {
48
+ const trimmed = command.trim();
49
+ if (!trimmed)
50
+ return false;
51
+ // Split on pipes, &&, ||, and ;
52
+ const parts = trimmed.split(/\s*(?:\|{1,2}|&&|;)\s*/);
53
+ for (const part of parts) {
54
+ const cleaned = part.trim();
55
+ if (!cleaned)
56
+ continue;
57
+ if (!this.isSafe(cleaned)) {
58
+ return false;
59
+ }
60
+ }
61
+ return true;
62
+ }
63
+ getSafeBinaries() {
64
+ return Array.from(this.safeBinaries).sort();
65
+ }
66
+ addSafeBinary(name) {
67
+ this.safeBinaries.add(name);
68
+ this.customized = true;
69
+ logger.debug('Added safe binary', { name });
70
+ }
71
+ removeSafeBinary(name) {
72
+ this.safeBinaries.delete(name);
73
+ this.customized = true;
74
+ logger.debug('Removed safe binary', { name });
75
+ }
76
+ isCustomized() {
77
+ return this.customized;
78
+ }
79
+ extractFirstWord(command) {
80
+ // Handle env var prefixes like FOO=bar cmd
81
+ let cmd = command;
82
+ while (/^\w+=\S*\s+/.test(cmd)) {
83
+ cmd = cmd.replace(/^\w+=\S*\s+/, '');
84
+ }
85
+ // Handle sudo/command prefixes
86
+ const prefixes = ['sudo', 'command', 'builtin'];
87
+ let firstWord = cmd.split(/\s+/)[0];
88
+ if (prefixes.includes(firstWord) && cmd.split(/\s+/).length > 1) {
89
+ firstWord = cmd.split(/\s+/)[1];
90
+ }
91
+ // Strip path prefix (e.g., /usr/bin/ls -> ls)
92
+ const basename = firstWord.split('/').pop() || firstWord;
93
+ return basename;
94
+ }
95
+ }
96
+ //# sourceMappingURL=safe-binaries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-binaries.js","sourceRoot":"","sources":["../../src/security/safe-binaries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Per-Sender Policies & Agents List
3
+ * Tool access control per sender identity and agent registry.
4
+ */
5
+ export interface SenderIdentity {
6
+ username?: string;
7
+ userId?: string;
8
+ phone?: string;
9
+ displayName?: string;
10
+ }
11
+ export interface SenderPolicy {
12
+ identity: SenderIdentity;
13
+ allowedTools: string[];
14
+ deniedTools: string[];
15
+ maxTurns?: number;
16
+ }
17
+ export declare class SenderPolicyManager {
18
+ private static instance;
19
+ private policies;
20
+ static getInstance(): SenderPolicyManager;
21
+ static resetInstance(): void;
22
+ addPolicy(policy: SenderPolicy): void;
23
+ removePolicy(identity: SenderIdentity): boolean;
24
+ getPolicy(identity: SenderIdentity): SenderPolicy | undefined;
25
+ isToolAllowed(identity: SenderIdentity, tool: string): boolean;
26
+ matchIdentity(sender: SenderIdentity, policy: SenderPolicy): boolean;
27
+ listPolicies(): SenderPolicy[];
28
+ clearPolicies(): void;
29
+ }
30
+ interface AgentInfo {
31
+ name: string;
32
+ description: string;
33
+ status: 'active' | 'inactive';
34
+ }
35
+ export declare class AgentListTool {
36
+ private static instance;
37
+ private agents;
38
+ static getInstance(): AgentListTool;
39
+ static resetInstance(): void;
40
+ listAgents(): AgentInfo[];
41
+ addAgent(name: string, description: string): void;
42
+ removeAgent(name: string): boolean;
43
+ getAgent(name: string): AgentInfo | undefined;
44
+ getAgentCount(): number;
45
+ }
46
+ export {};
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Per-Sender Policies & Agents List
3
+ * Tool access control per sender identity and agent registry.
4
+ */
5
+ import { logger } from '../utils/logger.js';
6
+ export class SenderPolicyManager {
7
+ static instance = null;
8
+ policies = [];
9
+ static getInstance() {
10
+ if (!SenderPolicyManager.instance) {
11
+ SenderPolicyManager.instance = new SenderPolicyManager();
12
+ }
13
+ return SenderPolicyManager.instance;
14
+ }
15
+ static resetInstance() {
16
+ SenderPolicyManager.instance = null;
17
+ }
18
+ addPolicy(policy) {
19
+ // Remove existing policy for same identity
20
+ this.policies = this.policies.filter(p => !this.matchIdentity(policy.identity, p));
21
+ this.policies.push(policy);
22
+ logger.debug(`Added policy for sender: ${JSON.stringify(policy.identity)}`);
23
+ }
24
+ removePolicy(identity) {
25
+ const before = this.policies.length;
26
+ this.policies = this.policies.filter(p => !this.matchIdentity(identity, p));
27
+ return this.policies.length < before;
28
+ }
29
+ getPolicy(identity) {
30
+ return this.policies.find(p => this.matchIdentity(identity, p));
31
+ }
32
+ isToolAllowed(identity, tool) {
33
+ const policy = this.getPolicy(identity);
34
+ if (!policy)
35
+ return true; // No policy means no restrictions
36
+ if (policy.deniedTools.includes(tool))
37
+ return false;
38
+ if (policy.allowedTools.length > 0 && !policy.allowedTools.includes(tool))
39
+ return false;
40
+ return true;
41
+ }
42
+ matchIdentity(sender, policy) {
43
+ const pi = policy.identity;
44
+ if (sender.username && pi.username && sender.username === pi.username)
45
+ return true;
46
+ if (sender.userId && pi.userId && sender.userId === pi.userId)
47
+ return true;
48
+ if (sender.phone && pi.phone && sender.phone === pi.phone)
49
+ return true;
50
+ if (sender.displayName && pi.displayName && sender.displayName === pi.displayName)
51
+ return true;
52
+ return false;
53
+ }
54
+ listPolicies() {
55
+ return [...this.policies];
56
+ }
57
+ clearPolicies() {
58
+ this.policies = [];
59
+ }
60
+ }
61
+ export class AgentListTool {
62
+ static instance = null;
63
+ agents = new Map();
64
+ static getInstance() {
65
+ if (!AgentListTool.instance) {
66
+ AgentListTool.instance = new AgentListTool();
67
+ }
68
+ return AgentListTool.instance;
69
+ }
70
+ static resetInstance() {
71
+ AgentListTool.instance = null;
72
+ }
73
+ listAgents() {
74
+ return Array.from(this.agents.values());
75
+ }
76
+ addAgent(name, description) {
77
+ this.agents.set(name, { name, description, status: 'active' });
78
+ logger.debug(`Registered agent: ${name}`);
79
+ }
80
+ removeAgent(name) {
81
+ return this.agents.delete(name);
82
+ }
83
+ getAgent(name) {
84
+ return this.agents.get(name);
85
+ }
86
+ getAgentCount() {
87
+ return this.agents.size;
88
+ }
89
+ }
90
+ //# sourceMappingURL=sender-policies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sender-policies.js","sourceRoot":"","sources":["../../src/security/sender-policies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Web Control UI Dashboard
3
+ *
4
+ * Provides an HTTP-based admin dashboard for monitoring
5
+ * agent status, sessions, channels, tools, and system health.
6
+ */
7
+ export interface DashboardConfig {
8
+ port?: number;
9
+ authToken?: string;
10
+ }
11
+ export interface DashboardStatus {
12
+ running: boolean;
13
+ port: number;
14
+ uptime: number;
15
+ connectedClients: number;
16
+ }
17
+ export interface DashboardMetrics {
18
+ agent: {
19
+ status: string;
20
+ model: string;
21
+ mode: string;
22
+ };
23
+ sessions: number;
24
+ channels: string[];
25
+ tools: number;
26
+ memory: {
27
+ used: number;
28
+ total: number;
29
+ };
30
+ system: {
31
+ cpuPercent: number;
32
+ memoryPercent: number;
33
+ };
34
+ }
35
+ export declare class Dashboard {
36
+ private static instance;
37
+ private config;
38
+ private running;
39
+ private startTime;
40
+ private connectedClients;
41
+ constructor(config?: DashboardConfig);
42
+ static getInstance(config?: DashboardConfig): Dashboard;
43
+ static resetInstance(): void;
44
+ start(port?: number): void;
45
+ stop(): void;
46
+ isRunning(): boolean;
47
+ getPort(): number;
48
+ getUrl(): string;
49
+ getStatus(): DashboardStatus;
50
+ generateDashboardHtml(): string;
51
+ getMetrics(): DashboardMetrics;
52
+ setConnectedClients(count: number): void;
53
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Web Control UI Dashboard
3
+ *
4
+ * Provides an HTTP-based admin dashboard for monitoring
5
+ * agent status, sessions, channels, tools, and system health.
6
+ */
7
+ import { logger } from '../utils/logger.js';
8
+ // ============================================================================
9
+ // Dashboard
10
+ // ============================================================================
11
+ export class Dashboard {
12
+ static instance = null;
13
+ config;
14
+ running = false;
15
+ startTime = 0;
16
+ connectedClients = 0;
17
+ constructor(config) {
18
+ this.config = config || { port: 8080 };
19
+ }
20
+ static getInstance(config) {
21
+ if (!Dashboard.instance) {
22
+ Dashboard.instance = new Dashboard(config);
23
+ }
24
+ return Dashboard.instance;
25
+ }
26
+ static resetInstance() {
27
+ Dashboard.instance = null;
28
+ }
29
+ start(port) {
30
+ if (port !== undefined) {
31
+ this.config.port = port;
32
+ }
33
+ logger.info(`Starting dashboard on port ${this.config.port || 8080}`);
34
+ this.running = true;
35
+ this.startTime = Date.now();
36
+ this.connectedClients = 0;
37
+ }
38
+ stop() {
39
+ logger.info('Stopping dashboard');
40
+ this.running = false;
41
+ this.startTime = 0;
42
+ this.connectedClients = 0;
43
+ }
44
+ isRunning() {
45
+ return this.running;
46
+ }
47
+ getPort() {
48
+ return this.config.port || 8080;
49
+ }
50
+ getUrl() {
51
+ return `http://localhost:${this.getPort()}`;
52
+ }
53
+ getStatus() {
54
+ return {
55
+ running: this.running,
56
+ port: this.getPort(),
57
+ uptime: this.running ? Math.floor((Date.now() - this.startTime) / 1000) : 0,
58
+ connectedClients: this.connectedClients,
59
+ };
60
+ }
61
+ generateDashboardHtml() {
62
+ return `<!DOCTYPE html>
63
+ <html lang="en">
64
+ <head>
65
+ <meta charset="UTF-8">
66
+ <title>Code Buddy Dashboard</title>
67
+ </head>
68
+ <body>
69
+ <h1>Code Buddy Admin Dashboard</h1>
70
+ <section id="agent-status"><h2>Agent Status</h2></section>
71
+ <section id="active-sessions"><h2>Active Sessions</h2></section>
72
+ <section id="channel-status"><h2>Channel Status</h2></section>
73
+ <section id="tool-usage"><h2>Tool Usage</h2></section>
74
+ <section id="memory-stats"><h2>Memory Stats</h2></section>
75
+ <section id="system-health"><h2>System Health</h2></section>
76
+ </body>
77
+ </html>`;
78
+ }
79
+ getMetrics() {
80
+ return {
81
+ agent: { status: 'idle', model: 'grok-3', mode: 'code' },
82
+ sessions: 0,
83
+ channels: ['telegram', 'discord', 'slack'],
84
+ tools: 25,
85
+ memory: { used: 0, total: 1024 },
86
+ system: { cpuPercent: 0, memoryPercent: 0 },
87
+ };
88
+ }
89
+ setConnectedClients(count) {
90
+ this.connectedClients = count;
91
+ }
92
+ }
93
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/server/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AA2B5C,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,MAAM,OAAO,SAAS;IACZ,MAAM,CAAC,QAAQ,GAAqB,IAAI,CAAC;IACzC,MAAM,CAAkB;IACxB,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,GAAG,CAAC,CAAC;IACd,gBAAgB,GAAG,CAAC,CAAC;IAE7B,YAAY,MAAwB;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,MAAwB;QACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,aAAa;QAClB,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAa;QACjB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI;QACF,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;IAClC,CAAC;IAED,MAAM;QACJ,OAAO,oBAAoB,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,SAAS;QACP,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE;YACpB,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3E,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;IAED,qBAAqB;QACnB,OAAO;;;;;;;;;;;;;;;QAeH,CAAC;IACP,CAAC;IAED,UAAU;QACR,OAAO;YACL,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;YACxD,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC;YAC1C,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;YAChC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;SAC5C,CAAC;IACJ,CAAC;IAED,mBAAmB,CAAC,KAAa;QAC/B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * System Prompt Override
3
+ *
4
+ * Handles CLI flags for replacing or appending to the system prompt:
5
+ * - --system-prompt <text> → replace entire prompt
6
+ * - --system-prompt-file <path> → replace from file
7
+ * - --append-system-prompt <text> → append text to default prompt
8
+ * - --append-system-prompt-file <path> → append file contents
9
+ */
10
+ export interface OverrideOptions {
11
+ /** Replace the entire system prompt with this text */
12
+ systemPrompt?: string;
13
+ /** Replace the entire system prompt with contents of this file */
14
+ systemPromptFile?: string;
15
+ /** Append this text to the default system prompt */
16
+ appendSystemPrompt?: string;
17
+ /** Append contents of this file to the default system prompt */
18
+ appendSystemPromptFile?: string;
19
+ }
20
+ export declare class SystemPromptOverride {
21
+ /**
22
+ * Apply override options to a base system prompt.
23
+ *
24
+ * - If systemPrompt or systemPromptFile is set, the base prompt is REPLACED.
25
+ * - If appendSystemPrompt or appendSystemPromptFile is set, content is APPENDED.
26
+ * - Cannot use both replace and append simultaneously.
27
+ * - If no overrides, returns the base prompt unchanged.
28
+ */
29
+ apply(basePrompt: string, options: OverrideOptions): string;
30
+ /**
31
+ * Read a file from disk. Throws if the file does not exist.
32
+ */
33
+ private readFile;
34
+ }