@phuetz/code-buddy 0.1.25 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/README.md +1049 -741
  2. package/dist/agent/codebuddy-agent.d.ts +5 -0
  3. package/dist/agent/codebuddy-agent.js +46 -1
  4. package/dist/agent/codebuddy-agent.js.map +1 -1
  5. package/dist/agent/execution/agent-executor.d.ts +12 -0
  6. package/dist/agent/execution/agent-executor.js +147 -6
  7. package/dist/agent/execution/agent-executor.js.map +1 -1
  8. package/dist/agent/lessons-tracker.d.ts +50 -0
  9. package/dist/agent/lessons-tracker.js +234 -0
  10. package/dist/agent/lessons-tracker.js.map +1 -0
  11. package/dist/agent/message-queue.d.ts +39 -2
  12. package/dist/agent/message-queue.js +67 -2
  13. package/dist/agent/message-queue.js.map +1 -1
  14. package/dist/agent/middleware/index.d.ts +1 -0
  15. package/dist/agent/middleware/index.js +1 -0
  16. package/dist/agent/middleware/index.js.map +1 -1
  17. package/dist/agent/middleware/workflow-guard.d.ts +21 -0
  18. package/dist/agent/middleware/workflow-guard.js +94 -0
  19. package/dist/agent/middleware/workflow-guard.js.map +1 -0
  20. package/dist/agent/orchestrator/supervisor-agent.d.ts +9 -0
  21. package/dist/agent/orchestrator/supervisor-agent.js +21 -1
  22. package/dist/agent/orchestrator/supervisor-agent.js.map +1 -1
  23. package/dist/agent/repo-profiler.d.ts +61 -0
  24. package/dist/agent/repo-profiler.js +295 -0
  25. package/dist/agent/repo-profiler.js.map +1 -0
  26. package/dist/agent/response-constraint.d.ts +61 -0
  27. package/dist/agent/response-constraint.js +91 -0
  28. package/dist/agent/response-constraint.js.map +1 -0
  29. package/dist/agent/todo-tracker.d.ts +67 -0
  30. package/dist/agent/todo-tracker.js +245 -0
  31. package/dist/agent/todo-tracker.js.map +1 -0
  32. package/dist/agent/tool-handler.d.ts +11 -0
  33. package/dist/agent/tool-handler.js +79 -1
  34. package/dist/agent/tool-handler.js.map +1 -1
  35. package/dist/agent/types.d.ts +20 -2
  36. package/dist/agent/wide-research.d.ts +93 -0
  37. package/dist/agent/wide-research.js +232 -0
  38. package/dist/agent/wide-research.js.map +1 -0
  39. package/dist/channels/index.d.ts +2 -0
  40. package/dist/channels/index.js +2 -0
  41. package/dist/channels/index.js.map +1 -1
  42. package/dist/channels/pro/callback-router.d.ts +54 -0
  43. package/dist/channels/pro/callback-router.js +178 -0
  44. package/dist/channels/pro/callback-router.js.map +1 -0
  45. package/dist/channels/pro/ci-watcher.d.ts +86 -0
  46. package/dist/channels/pro/ci-watcher.js +343 -0
  47. package/dist/channels/pro/ci-watcher.js.map +1 -0
  48. package/dist/channels/pro/diff-first.d.ts +63 -0
  49. package/dist/channels/pro/diff-first.js +187 -0
  50. package/dist/channels/pro/diff-first.js.map +1 -0
  51. package/dist/channels/pro/enhanced-commands.d.ts +83 -0
  52. package/dist/channels/pro/enhanced-commands.js +218 -0
  53. package/dist/channels/pro/enhanced-commands.js.map +1 -0
  54. package/dist/channels/pro/index.d.ts +19 -0
  55. package/dist/channels/pro/index.js +21 -0
  56. package/dist/channels/pro/index.js.map +1 -0
  57. package/dist/channels/pro/pro-features.d.ts +79 -0
  58. package/dist/channels/pro/pro-features.js +203 -0
  59. package/dist/channels/pro/pro-features.js.map +1 -0
  60. package/dist/channels/pro/run-commands.d.ts +59 -0
  61. package/dist/channels/pro/run-commands.js +122 -0
  62. package/dist/channels/pro/run-commands.js.map +1 -0
  63. package/dist/channels/pro/run-tracker.d.ts +74 -0
  64. package/dist/channels/pro/run-tracker.js +252 -0
  65. package/dist/channels/pro/run-tracker.js.map +1 -0
  66. package/dist/channels/pro/scoped-auth.d.ts +97 -0
  67. package/dist/channels/pro/scoped-auth.js +340 -0
  68. package/dist/channels/pro/scoped-auth.js.map +1 -0
  69. package/dist/channels/pro/text-formatter.d.ts +27 -0
  70. package/dist/channels/pro/text-formatter.js +269 -0
  71. package/dist/channels/pro/text-formatter.js.map +1 -0
  72. package/dist/channels/pro/types.d.ts +242 -0
  73. package/dist/channels/pro/types.js +14 -0
  74. package/dist/channels/pro/types.js.map +1 -0
  75. package/dist/channels/streaming-policy.d.ts +66 -0
  76. package/dist/channels/streaming-policy.js +266 -0
  77. package/dist/channels/streaming-policy.js.map +1 -0
  78. package/dist/channels/telegram/ci-watcher.d.ts +5 -0
  79. package/dist/channels/telegram/ci-watcher.js +5 -0
  80. package/dist/channels/telegram/ci-watcher.js.map +1 -0
  81. package/dist/channels/telegram/client.d.ts +28 -0
  82. package/dist/channels/telegram/client.js +147 -1
  83. package/dist/channels/telegram/client.js.map +1 -1
  84. package/dist/channels/telegram/diff-first.d.ts +5 -0
  85. package/dist/channels/telegram/diff-first.js +5 -0
  86. package/dist/channels/telegram/diff-first.js.map +1 -0
  87. package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
  88. package/dist/channels/telegram/enhanced-commands.js +6 -0
  89. package/dist/channels/telegram/enhanced-commands.js.map +1 -0
  90. package/dist/channels/telegram/index.d.ts +6 -0
  91. package/dist/channels/telegram/index.js +6 -0
  92. package/dist/channels/telegram/index.js.map +1 -1
  93. package/dist/channels/telegram/pro-formatter.d.ts +30 -0
  94. package/dist/channels/telegram/pro-formatter.js +276 -0
  95. package/dist/channels/telegram/pro-formatter.js.map +1 -0
  96. package/dist/channels/telegram/run-commands.d.ts +5 -0
  97. package/dist/channels/telegram/run-commands.js +6 -0
  98. package/dist/channels/telegram/run-commands.js.map +1 -0
  99. package/dist/channels/telegram/run-tracker.d.ts +5 -0
  100. package/dist/channels/telegram/run-tracker.js +5 -0
  101. package/dist/channels/telegram/run-tracker.js.map +1 -0
  102. package/dist/channels/telegram/scoped-auth.d.ts +6 -0
  103. package/dist/channels/telegram/scoped-auth.js +5 -0
  104. package/dist/channels/telegram/scoped-auth.js.map +1 -0
  105. package/dist/channels/telegram/types.d.ts +34 -0
  106. package/dist/codebuddy/client.js +14 -1
  107. package/dist/codebuddy/client.js.map +1 -1
  108. package/dist/commands/dev/index.d.ts +12 -0
  109. package/dist/commands/dev/index.js +231 -0
  110. package/dist/commands/dev/index.js.map +1 -0
  111. package/dist/commands/dev/workflows.d.ts +31 -0
  112. package/dist/commands/dev/workflows.js +214 -0
  113. package/dist/commands/dev/workflows.js.map +1 -0
  114. package/dist/commands/execpolicy.d.ts +17 -0
  115. package/dist/commands/execpolicy.js +155 -0
  116. package/dist/commands/execpolicy.js.map +1 -0
  117. package/dist/commands/knowledge.d.ts +13 -0
  118. package/dist/commands/knowledge.js +142 -0
  119. package/dist/commands/knowledge.js.map +1 -0
  120. package/dist/commands/lessons.d.ts +11 -0
  121. package/dist/commands/lessons.js +129 -0
  122. package/dist/commands/lessons.js.map +1 -0
  123. package/dist/commands/pairing.d.ts +14 -0
  124. package/dist/commands/pairing.js +132 -0
  125. package/dist/commands/pairing.js.map +1 -0
  126. package/dist/commands/research/index.d.ts +13 -0
  127. package/dist/commands/research/index.js +91 -0
  128. package/dist/commands/research/index.js.map +1 -0
  129. package/dist/commands/run-cli/index.d.ts +11 -0
  130. package/dist/commands/run-cli/index.js +49 -0
  131. package/dist/commands/run-cli/index.js.map +1 -0
  132. package/dist/commands/slash/builtin-commands.js +70 -2
  133. package/dist/commands/slash/builtin-commands.js.map +1 -1
  134. package/dist/commands/todos.d.ts +9 -0
  135. package/dist/commands/todos.js +119 -0
  136. package/dist/commands/todos.js.map +1 -0
  137. package/dist/config/toml-config.d.ts +21 -0
  138. package/dist/config/toml-config.js +15 -0
  139. package/dist/config/toml-config.js.map +1 -1
  140. package/dist/context/enhanced-compression.js +12 -1
  141. package/dist/context/enhanced-compression.js.map +1 -1
  142. package/dist/context/observation-variator.d.ts +44 -0
  143. package/dist/context/observation-variator.js +83 -0
  144. package/dist/context/observation-variator.js.map +1 -0
  145. package/dist/context/precompaction-flush.d.ts +40 -0
  146. package/dist/context/precompaction-flush.js +134 -0
  147. package/dist/context/precompaction-flush.js.map +1 -0
  148. package/dist/context/restorable-compression.d.ts +80 -0
  149. package/dist/context/restorable-compression.js +228 -0
  150. package/dist/context/restorable-compression.js.map +1 -0
  151. package/dist/daemon/daily-reset.d.ts +77 -0
  152. package/dist/daemon/daily-reset.js +175 -0
  153. package/dist/daemon/daily-reset.js.map +1 -0
  154. package/dist/daemon/index.d.ts +1 -0
  155. package/dist/daemon/index.js +1 -0
  156. package/dist/daemon/index.js.map +1 -1
  157. package/dist/index.js +53 -0
  158. package/dist/index.js.map +1 -1
  159. package/dist/knowledge/knowledge-manager.d.ts +77 -0
  160. package/dist/knowledge/knowledge-manager.js +244 -0
  161. package/dist/knowledge/knowledge-manager.js.map +1 -0
  162. package/dist/memory/semantic-memory-search.d.ts +7 -0
  163. package/dist/memory/semantic-memory-search.js +49 -5
  164. package/dist/memory/semantic-memory-search.js.map +1 -1
  165. package/dist/observability/run-store.d.ts +133 -0
  166. package/dist/observability/run-store.js +419 -0
  167. package/dist/observability/run-store.js.map +1 -0
  168. package/dist/observability/run-viewer.d.ts +33 -0
  169. package/dist/observability/run-viewer.js +254 -0
  170. package/dist/observability/run-viewer.js.map +1 -0
  171. package/dist/optimization/cache-breakpoints.d.ts +52 -0
  172. package/dist/optimization/cache-breakpoints.js +97 -0
  173. package/dist/optimization/cache-breakpoints.js.map +1 -0
  174. package/dist/persistence/session-store.d.ts +3 -1
  175. package/dist/persistence/session-store.js +1 -1
  176. package/dist/persistence/session-store.js.map +1 -1
  177. package/dist/prompts/system-base.js +51 -7
  178. package/dist/prompts/system-base.js.map +1 -1
  179. package/dist/prompts/variation-injector.d.ts +55 -0
  180. package/dist/prompts/variation-injector.js +171 -0
  181. package/dist/prompts/variation-injector.js.map +1 -0
  182. package/dist/prompts/workflow-rules.d.ts +10 -0
  183. package/dist/prompts/workflow-rules.js +79 -0
  184. package/dist/prompts/workflow-rules.js.map +1 -0
  185. package/dist/sandbox/execpolicy.d.ts +45 -0
  186. package/dist/sandbox/execpolicy.js +80 -0
  187. package/dist/sandbox/execpolicy.js.map +1 -1
  188. package/dist/sandbox/os-sandbox.d.ts +25 -0
  189. package/dist/sandbox/os-sandbox.js +73 -0
  190. package/dist/sandbox/os-sandbox.js.map +1 -1
  191. package/dist/scheduler/cron-scheduler.d.ts +9 -0
  192. package/dist/scheduler/cron-scheduler.js +17 -1
  193. package/dist/scheduler/cron-scheduler.js.map +1 -1
  194. package/dist/security/security-audit.d.ts +10 -0
  195. package/dist/security/security-audit.js +116 -0
  196. package/dist/security/security-audit.js.map +1 -1
  197. package/dist/security/shell-env-policy.d.ts +45 -0
  198. package/dist/security/shell-env-policy.js +141 -0
  199. package/dist/security/shell-env-policy.js.map +1 -0
  200. package/dist/security/ssrf-guard.d.ts +61 -0
  201. package/dist/security/ssrf-guard.js +382 -0
  202. package/dist/security/ssrf-guard.js.map +1 -0
  203. package/dist/security/write-policy.d.ts +57 -0
  204. package/dist/security/write-policy.js +117 -0
  205. package/dist/security/write-policy.js.map +1 -0
  206. package/dist/services/prompt-builder.js +37 -0
  207. package/dist/services/prompt-builder.js.map +1 -1
  208. package/dist/themes/theme-schema.d.ts +10 -10
  209. package/dist/tools/ask-human-tool.d.ts +62 -0
  210. package/dist/tools/ask-human-tool.js +112 -0
  211. package/dist/tools/ask-human-tool.js.map +1 -0
  212. package/dist/tools/bash/bash-tool.d.ts +15 -0
  213. package/dist/tools/bash/bash-tool.js +62 -0
  214. package/dist/tools/bash/bash-tool.js.map +1 -1
  215. package/dist/tools/bash/command-validator.d.ts +1 -0
  216. package/dist/tools/bash/command-validator.js +5 -0
  217. package/dist/tools/bash/command-validator.js.map +1 -1
  218. package/dist/tools/create-skill-tool.d.ts +87 -0
  219. package/dist/tools/create-skill-tool.js +142 -0
  220. package/dist/tools/create-skill-tool.js.map +1 -0
  221. package/dist/tools/fetch-tool.js +5 -3
  222. package/dist/tools/fetch-tool.js.map +1 -1
  223. package/dist/tools/index.d.ts +1 -0
  224. package/dist/tools/index.js +1 -0
  225. package/dist/tools/index.js.map +1 -1
  226. package/dist/tools/plan-tool.d.ts +22 -0
  227. package/dist/tools/plan-tool.js +128 -0
  228. package/dist/tools/plan-tool.js.map +1 -0
  229. package/dist/tools/registry/attention-tools.d.ts +32 -0
  230. package/dist/tools/registry/attention-tools.js +225 -0
  231. package/dist/tools/registry/attention-tools.js.map +1 -0
  232. package/dist/tools/registry/index.d.ts +9 -1
  233. package/dist/tools/registry/index.js +30 -2
  234. package/dist/tools/registry/index.js.map +1 -1
  235. package/dist/tools/registry/knowledge-tools.d.ts +46 -0
  236. package/dist/tools/registry/knowledge-tools.js +293 -0
  237. package/dist/tools/registry/knowledge-tools.js.map +1 -0
  238. package/dist/tools/registry/lessons-tools.d.ts +48 -0
  239. package/dist/tools/registry/lessons-tools.js +359 -0
  240. package/dist/tools/registry/lessons-tools.js.map +1 -0
  241. package/dist/tools/registry/plan-tools.d.ts +2 -0
  242. package/dist/tools/registry/plan-tools.js +7 -0
  243. package/dist/tools/registry/plan-tools.js.map +1 -0
  244. package/dist/tools/registry/script-tools.d.ts +2 -0
  245. package/dist/tools/registry/script-tools.js +7 -0
  246. package/dist/tools/registry/script-tools.js.map +1 -0
  247. package/dist/tools/registry/tool-aliases.d.ts +44 -0
  248. package/dist/tools/registry/tool-aliases.js +130 -0
  249. package/dist/tools/registry/tool-aliases.js.map +1 -0
  250. package/dist/tools/run-script-tool.d.ts +13 -0
  251. package/dist/tools/run-script-tool.js +146 -0
  252. package/dist/tools/run-script-tool.js.map +1 -0
  253. package/dist/tools/web-search.d.ts +25 -0
  254. package/dist/tools/web-search.js +68 -6
  255. package/dist/tools/web-search.js.map +1 -1
  256. package/dist/utils/config-validation/schema.d.ts +2 -2
  257. package/dist/utils/debug-logger.d.ts +1 -1
  258. package/dist/utils/stable-json.d.ts +27 -0
  259. package/dist/utils/stable-json.js +50 -0
  260. package/dist/utils/stable-json.js.map +1 -0
  261. package/dist/webhooks/webhook-manager.d.ts +7 -0
  262. package/dist/webhooks/webhook-manager.js +29 -0
  263. package/dist/webhooks/webhook-manager.js.map +1 -1
  264. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ /**
2
+ * WritePolicy — enforces diff-first writes at the tool-handler level.
3
+ *
4
+ * Modes:
5
+ * strict — blocks any direct file write; the caller must use applyPatch()
6
+ * confirm — allows writes but records a decision event in RunStore (existing confirmation UX)
7
+ * off — no restriction (current default behaviour)
8
+ *
9
+ * The singleton is injectable for tests via WritePolicy.setInstance().
10
+ */
11
+ export type WritePolicyMode = 'strict' | 'confirm' | 'off';
12
+ export interface WriteOperation {
13
+ /** Tool name triggering the write */
14
+ toolName: string;
15
+ /** File path(s) being written */
16
+ paths: string[];
17
+ /** Patch content if already prepared */
18
+ patch?: string;
19
+ /** Short description for decision log */
20
+ description?: string;
21
+ }
22
+ export interface GateResult {
23
+ allowed: boolean;
24
+ /** True if the caller must route through applyPatch() */
25
+ requiresPatch: boolean;
26
+ reason?: string;
27
+ }
28
+ export declare const WRITE_TOOL_NAMES: Set<string>;
29
+ export declare class WritePolicy {
30
+ private static _instance;
31
+ private mode;
32
+ private listeners;
33
+ static getInstance(): WritePolicy;
34
+ /** Replace the singleton (for testing). */
35
+ static setInstance(instance: WritePolicy): void;
36
+ static resetInstance(): void;
37
+ setMode(mode: WritePolicyMode): void;
38
+ getMode(): WritePolicyMode;
39
+ /**
40
+ * Check whether the operation is allowed under the current policy.
41
+ *
42
+ * Called by tool-handler before executing str_replace_editor / create_file / multi_edit.
43
+ *
44
+ * @param operation - The write operation being attempted
45
+ * @param runId - Active run ID for decision logging (optional)
46
+ */
47
+ gate(operation: WriteOperation, _runId?: string): Promise<GateResult>;
48
+ /**
49
+ * Returns true if the tool name is subject to write-policy gating.
50
+ */
51
+ isWriteTool(toolName: string): boolean;
52
+ /**
53
+ * Subscribe to gate decisions (for RunStore integration).
54
+ */
55
+ onGate(listener: (op: WriteOperation, result: GateResult) => void): void;
56
+ private notifyListeners;
57
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * WritePolicy — enforces diff-first writes at the tool-handler level.
3
+ *
4
+ * Modes:
5
+ * strict — blocks any direct file write; the caller must use applyPatch()
6
+ * confirm — allows writes but records a decision event in RunStore (existing confirmation UX)
7
+ * off — no restriction (current default behaviour)
8
+ *
9
+ * The singleton is injectable for tests via WritePolicy.setInstance().
10
+ */
11
+ import { logger } from '../utils/logger.js';
12
+ // ──────────────────────────────────────────────────────────────────
13
+ // Tool names that trigger write-policy gating
14
+ // ──────────────────────────────────────────────────────────────────
15
+ export const WRITE_TOOL_NAMES = new Set([
16
+ 'str_replace_editor',
17
+ 'create_file',
18
+ 'multi_edit',
19
+ 'apply_patch',
20
+ 'edit_file', // Morph Fast Apply
21
+ 'write_file',
22
+ ]);
23
+ // ──────────────────────────────────────────────────────────────────
24
+ // WritePolicy
25
+ // ──────────────────────────────────────────────────────────────────
26
+ export class WritePolicy {
27
+ static _instance = null;
28
+ mode = 'confirm';
29
+ listeners = [];
30
+ // ── Singleton ────────────────────────────────────────────────
31
+ static getInstance() {
32
+ if (!WritePolicy._instance) {
33
+ WritePolicy._instance = new WritePolicy();
34
+ }
35
+ return WritePolicy._instance;
36
+ }
37
+ /** Replace the singleton (for testing). */
38
+ static setInstance(instance) {
39
+ WritePolicy._instance = instance;
40
+ }
41
+ static resetInstance() {
42
+ WritePolicy._instance = null;
43
+ }
44
+ // ── Configuration ─────────────────────────────────────────────
45
+ setMode(mode) {
46
+ this.mode = mode;
47
+ logger.debug(`WritePolicy: mode set to ${mode}`);
48
+ }
49
+ getMode() {
50
+ return this.mode;
51
+ }
52
+ // ── Gating ────────────────────────────────────────────────────
53
+ /**
54
+ * Check whether the operation is allowed under the current policy.
55
+ *
56
+ * Called by tool-handler before executing str_replace_editor / create_file / multi_edit.
57
+ *
58
+ * @param operation - The write operation being attempted
59
+ * @param runId - Active run ID for decision logging (optional)
60
+ */
61
+ async gate(operation, _runId) {
62
+ const { toolName } = operation;
63
+ // apply_patch is always allowed — it IS the diff-first path
64
+ if (toolName === 'apply_patch') {
65
+ return { allowed: true, requiresPatch: false };
66
+ }
67
+ switch (this.mode) {
68
+ case 'off':
69
+ return { allowed: true, requiresPatch: false };
70
+ case 'confirm': {
71
+ // In confirm mode, direct writes are allowed but we log the decision
72
+ const result = { allowed: true, requiresPatch: false };
73
+ this.notifyListeners(operation, result);
74
+ return result;
75
+ }
76
+ case 'strict': {
77
+ // In strict mode, block direct writes if no patch is provided
78
+ if (operation.patch) {
79
+ // Caller has already produced a patch — allow it
80
+ return { allowed: true, requiresPatch: false };
81
+ }
82
+ const result = {
83
+ allowed: false,
84
+ requiresPatch: true,
85
+ reason: `WritePolicy (strict): tool "${toolName}" attempted a direct file write. Use apply_patch with a unified diff instead.`,
86
+ };
87
+ this.notifyListeners(operation, result);
88
+ logger.info(`WritePolicy blocked: ${toolName}`, { paths: operation.paths });
89
+ return result;
90
+ }
91
+ }
92
+ }
93
+ /**
94
+ * Returns true if the tool name is subject to write-policy gating.
95
+ */
96
+ isWriteTool(toolName) {
97
+ return WRITE_TOOL_NAMES.has(toolName);
98
+ }
99
+ // ── Observability ─────────────────────────────────────────────
100
+ /**
101
+ * Subscribe to gate decisions (for RunStore integration).
102
+ */
103
+ onGate(listener) {
104
+ this.listeners.push(listener);
105
+ }
106
+ notifyListeners(op, result) {
107
+ for (const l of this.listeners) {
108
+ try {
109
+ l(op, result);
110
+ }
111
+ catch {
112
+ // Ignore listener errors
113
+ }
114
+ }
115
+ }
116
+ }
117
+ //# sourceMappingURL=write-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-policy.js","sourceRoot":"","sources":["../../src/security/write-policy.ts"],"names":[],"mappings":"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"}
@@ -118,8 +118,45 @@ export class PromptBuilder {
118
118
  catch (err) {
119
119
  logger.warn("Failed to load bootstrap context", { error: getErrorMessage(err) });
120
120
  }
121
+ // Inject workflow orchestration rules (concrete plan triggers, verification contract, etc.)
122
+ try {
123
+ const { getWorkflowRulesBlock } = await import('../prompts/workflow-rules.js');
124
+ systemPrompt += '\n\n' + getWorkflowRulesBlock();
125
+ logger.debug('Injected workflow orchestration rules into system prompt');
126
+ }
127
+ catch (err) {
128
+ logger.warn('Failed to inject workflow rules', { error: getErrorMessage(err) });
129
+ }
130
+ // Manus AI structured variation — shuffle reminder blocks to prevent
131
+ // the model from falling into brittle repetition patterns.
132
+ // Only the footer guideline section is varied; the preamble/tools are left
133
+ // untouched so prompt caching remains effective on the stable prefix.
134
+ try {
135
+ const { varySystemPrompt } = await import('../prompts/variation-injector.js');
136
+ // Use a daily seed so the variation is stable within a single day
137
+ // (same day → same order → consistent cache), but rotates across days.
138
+ const daySeed = Math.floor(Date.now() / 86_400_000);
139
+ systemPrompt = varySystemPrompt(systemPrompt, {
140
+ seed: daySeed,
141
+ shuffleOrder: true,
142
+ alternativePhrasing: true,
143
+ variationRate: 0.3,
144
+ });
145
+ }
146
+ catch {
147
+ // non-critical — proceed with original prompt
148
+ }
121
149
  // Cache system prompt for optimization
122
150
  this.promptCacheManager.cacheSystemPrompt(systemPrompt);
151
+ // Store stable/dynamic split for cache-breakpoint injection (Manus AI #11/#20)
152
+ try {
153
+ const { buildStableDynamicSplit } = await import('../optimization/cache-breakpoints.js');
154
+ const split = buildStableDynamicSplit(systemPrompt);
155
+ // The split is used by the client to inject cache_control breakpoints.
156
+ // Attach it to the PromptCacheManager for inspection if needed.
157
+ this.promptCacheManager._stableDynamicSplit = split;
158
+ }
159
+ catch { /* non-critical */ }
123
160
  return systemPrompt;
124
161
  }
125
162
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/services/prompt-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/services/prompt-builder.ts"],"names":[],"mappings":"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"}
@@ -12,14 +12,14 @@ export declare const avatarConfigSchema: z.ZodObject<{
12
12
  tool: z.ZodString;
13
13
  system: z.ZodString;
14
14
  }, "strip", z.ZodTypeAny, {
15
+ system: string;
15
16
  user: string;
16
17
  assistant: string;
17
- system: string;
18
18
  tool: string;
19
19
  }, {
20
+ system: string;
20
21
  user: string;
21
22
  assistant: string;
22
- system: string;
23
23
  tool: string;
24
24
  }>;
25
25
  /**
@@ -178,14 +178,14 @@ export declare const themeSchema: z.ZodObject<{
178
178
  tool: z.ZodString;
179
179
  system: z.ZodString;
180
180
  }, "strip", z.ZodTypeAny, {
181
+ system: string;
181
182
  user: string;
182
183
  assistant: string;
183
- system: string;
184
184
  tool: string;
185
185
  }, {
186
+ system: string;
186
187
  user: string;
187
188
  assistant: string;
188
- system: string;
189
189
  tool: string;
190
190
  }>;
191
191
  isBuiltin: z.ZodBoolean;
@@ -220,9 +220,9 @@ export declare const themeSchema: z.ZodObject<{
220
220
  codeBackground?: string | undefined;
221
221
  };
222
222
  avatars: {
223
+ system: string;
223
224
  user: string;
224
225
  assistant: string;
225
- system: string;
226
226
  tool: string;
227
227
  };
228
228
  isBuiltin: boolean;
@@ -257,9 +257,9 @@ export declare const themeSchema: z.ZodObject<{
257
257
  codeBackground?: string | undefined;
258
258
  };
259
259
  avatars: {
260
+ system: string;
260
261
  user: string;
261
262
  assistant: string;
262
- system: string;
263
263
  tool: string;
264
264
  };
265
265
  isBuiltin: boolean;
@@ -277,14 +277,14 @@ export declare const themePreferencesSchema: z.ZodObject<{
277
277
  tool: z.ZodOptional<z.ZodString>;
278
278
  system: z.ZodOptional<z.ZodString>;
279
279
  }, "strip", z.ZodTypeAny, {
280
+ system?: string | undefined;
280
281
  user?: string | undefined;
281
282
  assistant?: string | undefined;
282
- system?: string | undefined;
283
283
  tool?: string | undefined;
284
284
  }, {
285
+ system?: string | undefined;
285
286
  user?: string | undefined;
286
287
  assistant?: string | undefined;
287
- system?: string | undefined;
288
288
  tool?: string | undefined;
289
289
  }>>;
290
290
  customColors: z.ZodOptional<z.ZodObject<{
@@ -360,9 +360,9 @@ export declare const themePreferencesSchema: z.ZodObject<{
360
360
  }, "strip", z.ZodTypeAny, {
361
361
  activeTheme: string;
362
362
  customAvatars?: {
363
+ system?: string | undefined;
363
364
  user?: string | undefined;
364
365
  assistant?: string | undefined;
365
- system?: string | undefined;
366
366
  tool?: string | undefined;
367
367
  } | undefined;
368
368
  customColors?: {
@@ -392,9 +392,9 @@ export declare const themePreferencesSchema: z.ZodObject<{
392
392
  }, {
393
393
  activeTheme: string;
394
394
  customAvatars?: {
395
+ system?: string | undefined;
395
396
  user?: string | undefined;
396
397
  assistant?: string | undefined;
397
- system?: string | undefined;
398
398
  tool?: string | undefined;
399
399
  } | undefined;
400
400
  customColors?: {
@@ -0,0 +1,62 @@
1
+ /**
2
+ * AskHuman Tool (OpenManus-inspired)
3
+ *
4
+ * Allows the agent to pause mid-task and ask the user a clarifying
5
+ * question. In CLI mode this blocks on readline. In non-interactive
6
+ * environments it returns a timeout message so the agent can proceed
7
+ * with a best-effort answer.
8
+ *
9
+ * The LLM should call this tool when:
10
+ * - It needs information that cannot be inferred from context
11
+ * - Multiple valid interpretations exist and the wrong one would waste effort
12
+ * - A destructive or irreversible action requires explicit human sign-off
13
+ */
14
+ import type { ToolResult } from '../types/index.js';
15
+ export interface AskHumanInput {
16
+ /** The question to ask the user */
17
+ question: string;
18
+ /** Optional suggested options (presented as a numbered list) */
19
+ options?: string[];
20
+ /** Timeout in seconds before the tool returns a default answer (default: 120) */
21
+ timeout?: number;
22
+ /** Default answer returned on timeout (default: "no answer provided, use best judgement") */
23
+ default?: string;
24
+ }
25
+ export declare class AskHumanTool {
26
+ /**
27
+ * Pause agent execution and ask the human a question.
28
+ * Returns the user's typed response as the tool output.
29
+ */
30
+ execute(input: AskHumanInput): Promise<ToolResult>;
31
+ getSchema(): {
32
+ name: string;
33
+ description: string;
34
+ parameters: {
35
+ type: "object";
36
+ properties: {
37
+ question: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ options: {
42
+ type: string;
43
+ items: {
44
+ type: string;
45
+ };
46
+ description: string;
47
+ };
48
+ timeout: {
49
+ type: string;
50
+ description: string;
51
+ };
52
+ default: {
53
+ type: string;
54
+ description: string;
55
+ };
56
+ };
57
+ required: string[];
58
+ };
59
+ };
60
+ }
61
+ export declare function getAskHumanTool(): AskHumanTool;
62
+ export declare function resetAskHumanTool(): void;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * AskHuman Tool (OpenManus-inspired)
3
+ *
4
+ * Allows the agent to pause mid-task and ask the user a clarifying
5
+ * question. In CLI mode this blocks on readline. In non-interactive
6
+ * environments it returns a timeout message so the agent can proceed
7
+ * with a best-effort answer.
8
+ *
9
+ * The LLM should call this tool when:
10
+ * - It needs information that cannot be inferred from context
11
+ * - Multiple valid interpretations exist and the wrong one would waste effort
12
+ * - A destructive or irreversible action requires explicit human sign-off
13
+ */
14
+ import * as readline from 'readline';
15
+ export class AskHumanTool {
16
+ /**
17
+ * Pause agent execution and ask the human a question.
18
+ * Returns the user's typed response as the tool output.
19
+ */
20
+ async execute(input) {
21
+ const { question, options, timeout = 120, default: defaultAnswer = 'No answer provided – use your best judgement and continue.', } = input;
22
+ // Detect non-interactive environments
23
+ if (!process.stdin.isTTY) {
24
+ return {
25
+ success: true,
26
+ output: defaultAnswer,
27
+ };
28
+ }
29
+ return new Promise((resolve) => {
30
+ const rl = readline.createInterface({
31
+ input: process.stdin,
32
+ output: process.stdout,
33
+ terminal: true,
34
+ });
35
+ let prompt = `\n🤔 Agent needs your input:\n${question}\n`;
36
+ if (options && options.length > 0) {
37
+ prompt += '\nOptions:\n';
38
+ options.forEach((opt, i) => {
39
+ prompt += ` ${i + 1}. ${opt}\n`;
40
+ });
41
+ prompt += '\nEnter your choice (number or free text): ';
42
+ }
43
+ else {
44
+ prompt += '\nYour answer: ';
45
+ }
46
+ // Auto-timeout
47
+ const timer = setTimeout(() => {
48
+ rl.close();
49
+ resolve({
50
+ success: true,
51
+ output: defaultAnswer,
52
+ });
53
+ }, timeout * 1000);
54
+ rl.question(prompt, (answer) => {
55
+ clearTimeout(timer);
56
+ rl.close();
57
+ // If user picked a number from the options list, expand it
58
+ if (options && options.length > 0) {
59
+ const n = parseInt(answer.trim(), 10);
60
+ if (!isNaN(n) && n >= 1 && n <= options.length) {
61
+ resolve({ success: true, output: options[n - 1] });
62
+ return;
63
+ }
64
+ }
65
+ resolve({
66
+ success: true,
67
+ output: answer.trim() || defaultAnswer,
68
+ });
69
+ });
70
+ });
71
+ }
72
+ getSchema() {
73
+ return {
74
+ name: 'ask_human',
75
+ description: 'Pause execution and ask the user a clarifying question. Use when you need information that cannot be inferred from context, or when multiple interpretations would lead to very different outcomes. Returns the human\'s typed response.',
76
+ parameters: {
77
+ type: 'object',
78
+ properties: {
79
+ question: {
80
+ type: 'string',
81
+ description: 'The question to ask the user (be concise and specific)',
82
+ },
83
+ options: {
84
+ type: 'array',
85
+ items: { type: 'string' },
86
+ description: 'Optional list of suggested answers the user can pick from',
87
+ },
88
+ timeout: {
89
+ type: 'number',
90
+ description: 'Seconds to wait before returning a default answer (default: 120)',
91
+ },
92
+ default: {
93
+ type: 'string',
94
+ description: 'Default answer to return if the user does not respond in time',
95
+ },
96
+ },
97
+ required: ['question'],
98
+ },
99
+ };
100
+ }
101
+ }
102
+ let instance = null;
103
+ export function getAskHumanTool() {
104
+ if (!instance) {
105
+ instance = new AskHumanTool();
106
+ }
107
+ return instance;
108
+ }
109
+ export function resetAskHumanTool() {
110
+ instance = null;
111
+ }
112
+ //# sourceMappingURL=ask-human-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-human-tool.js","sourceRoot":"","sources":["../../src/tools/ask-human-tool.ts"],"names":[],"mappings":"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"}
@@ -77,6 +77,21 @@ export declare class BashTool implements Disposable {
77
77
  * Parses command arguments to identify file targets of rm, mv, etc.
78
78
  */
79
79
  private checkpointDestructiveTargets;
80
+ /**
81
+ * Shell-free exec — Codex-inspired direct process execution.
82
+ *
83
+ * Executes a pre-parsed command token array via spawn with `shell: false`,
84
+ * bypassing shell interpretation entirely. Prevents shell injection when the
85
+ * caller has already validated / split the argument vector.
86
+ *
87
+ * Use this when the command has been parsed by bash-parser and you want to
88
+ * avoid double-interpretation through sh/bash.
89
+ *
90
+ * @param argv - [command, ...args] token array (must have at least 1 element)
91
+ * @param timeout - Max execution time in ms (default: 30000)
92
+ * @param cwd - Working directory (default: currentDirectory)
93
+ */
94
+ shellFreeExec(argv: string[], timeout?: number, cwd?: string): Promise<ToolResult>;
80
95
  /**
81
96
  * Enable or disable self-healing
82
97
  */
@@ -412,6 +412,68 @@ export class BashTool {
412
412
  // Parsing failed — skip checkpointing (command already validated)
413
413
  }
414
414
  }
415
+ /**
416
+ * Shell-free exec — Codex-inspired direct process execution.
417
+ *
418
+ * Executes a pre-parsed command token array via spawn with `shell: false`,
419
+ * bypassing shell interpretation entirely. Prevents shell injection when the
420
+ * caller has already validated / split the argument vector.
421
+ *
422
+ * Use this when the command has been parsed by bash-parser and you want to
423
+ * avoid double-interpretation through sh/bash.
424
+ *
425
+ * @param argv - [command, ...args] token array (must have at least 1 element)
426
+ * @param timeout - Max execution time in ms (default: 30000)
427
+ * @param cwd - Working directory (default: currentDirectory)
428
+ */
429
+ async shellFreeExec(argv, timeout = 30000, cwd) {
430
+ if (!argv || argv.length === 0) {
431
+ return { success: false, error: 'shellFreeExec: argv must be non-empty' };
432
+ }
433
+ const [cmd, ...args] = argv;
434
+ const workDir = cwd ?? this.currentDirectory;
435
+ const filteredEnv = getFilteredEnv();
436
+ return new Promise((resolve) => {
437
+ let stdout = '';
438
+ let stderr = '';
439
+ let timedOut = false;
440
+ const proc = spawn(cmd, args, {
441
+ shell: false,
442
+ cwd: workDir,
443
+ env: filteredEnv,
444
+ stdio: ['ignore', 'pipe', 'pipe'],
445
+ });
446
+ const timer = setTimeout(() => {
447
+ timedOut = true;
448
+ proc.kill('SIGKILL');
449
+ }, timeout);
450
+ const maxBuf = 1024 * 1024;
451
+ proc.stdout?.on('data', (d) => {
452
+ if (stdout.length < maxBuf)
453
+ stdout += d.toString();
454
+ });
455
+ proc.stderr?.on('data', (d) => {
456
+ if (stderr.length < maxBuf)
457
+ stderr += d.toString();
458
+ });
459
+ proc.on('close', (code) => {
460
+ clearTimeout(timer);
461
+ if (timedOut) {
462
+ resolve({ success: false, error: 'Command timed out' });
463
+ }
464
+ else if (code === 0) {
465
+ resolve({ success: true, output: stdout.trim() || 'Done' });
466
+ }
467
+ else {
468
+ resolve({ success: false, error: stderr.trim() || `Exit code ${code}` });
469
+ }
470
+ });
471
+ proc.on('error', (err) => {
472
+ clearTimeout(timer);
473
+ resolve({ success: false, error: err.message });
474
+ });
475
+ });
476
+ }
415
477
  /**
416
478
  * Enable or disable self-healing
417
479
  */