@phuetz/code-buddy 0.1.25 → 0.1.26

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 (253) 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/repo-profiler.d.ts +61 -0
  21. package/dist/agent/repo-profiler.js +295 -0
  22. package/dist/agent/repo-profiler.js.map +1 -0
  23. package/dist/agent/response-constraint.d.ts +61 -0
  24. package/dist/agent/response-constraint.js +91 -0
  25. package/dist/agent/response-constraint.js.map +1 -0
  26. package/dist/agent/todo-tracker.d.ts +67 -0
  27. package/dist/agent/todo-tracker.js +245 -0
  28. package/dist/agent/todo-tracker.js.map +1 -0
  29. package/dist/agent/tool-handler.d.ts +11 -0
  30. package/dist/agent/tool-handler.js +79 -1
  31. package/dist/agent/tool-handler.js.map +1 -1
  32. package/dist/agent/types.d.ts +20 -2
  33. package/dist/agent/wide-research.d.ts +93 -0
  34. package/dist/agent/wide-research.js +232 -0
  35. package/dist/agent/wide-research.js.map +1 -0
  36. package/dist/channels/index.d.ts +2 -0
  37. package/dist/channels/index.js +2 -0
  38. package/dist/channels/index.js.map +1 -1
  39. package/dist/channels/pro/callback-router.d.ts +54 -0
  40. package/dist/channels/pro/callback-router.js +178 -0
  41. package/dist/channels/pro/callback-router.js.map +1 -0
  42. package/dist/channels/pro/ci-watcher.d.ts +86 -0
  43. package/dist/channels/pro/ci-watcher.js +343 -0
  44. package/dist/channels/pro/ci-watcher.js.map +1 -0
  45. package/dist/channels/pro/diff-first.d.ts +63 -0
  46. package/dist/channels/pro/diff-first.js +187 -0
  47. package/dist/channels/pro/diff-first.js.map +1 -0
  48. package/dist/channels/pro/enhanced-commands.d.ts +83 -0
  49. package/dist/channels/pro/enhanced-commands.js +218 -0
  50. package/dist/channels/pro/enhanced-commands.js.map +1 -0
  51. package/dist/channels/pro/index.d.ts +19 -0
  52. package/dist/channels/pro/index.js +21 -0
  53. package/dist/channels/pro/index.js.map +1 -0
  54. package/dist/channels/pro/pro-features.d.ts +79 -0
  55. package/dist/channels/pro/pro-features.js +203 -0
  56. package/dist/channels/pro/pro-features.js.map +1 -0
  57. package/dist/channels/pro/run-commands.d.ts +59 -0
  58. package/dist/channels/pro/run-commands.js +122 -0
  59. package/dist/channels/pro/run-commands.js.map +1 -0
  60. package/dist/channels/pro/run-tracker.d.ts +74 -0
  61. package/dist/channels/pro/run-tracker.js +252 -0
  62. package/dist/channels/pro/run-tracker.js.map +1 -0
  63. package/dist/channels/pro/scoped-auth.d.ts +97 -0
  64. package/dist/channels/pro/scoped-auth.js +340 -0
  65. package/dist/channels/pro/scoped-auth.js.map +1 -0
  66. package/dist/channels/pro/text-formatter.d.ts +27 -0
  67. package/dist/channels/pro/text-formatter.js +269 -0
  68. package/dist/channels/pro/text-formatter.js.map +1 -0
  69. package/dist/channels/pro/types.d.ts +242 -0
  70. package/dist/channels/pro/types.js +14 -0
  71. package/dist/channels/pro/types.js.map +1 -0
  72. package/dist/channels/streaming-policy.d.ts +66 -0
  73. package/dist/channels/streaming-policy.js +266 -0
  74. package/dist/channels/streaming-policy.js.map +1 -0
  75. package/dist/channels/telegram/ci-watcher.d.ts +5 -0
  76. package/dist/channels/telegram/ci-watcher.js +5 -0
  77. package/dist/channels/telegram/ci-watcher.js.map +1 -0
  78. package/dist/channels/telegram/client.d.ts +28 -0
  79. package/dist/channels/telegram/client.js +147 -1
  80. package/dist/channels/telegram/client.js.map +1 -1
  81. package/dist/channels/telegram/diff-first.d.ts +5 -0
  82. package/dist/channels/telegram/diff-first.js +5 -0
  83. package/dist/channels/telegram/diff-first.js.map +1 -0
  84. package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
  85. package/dist/channels/telegram/enhanced-commands.js +6 -0
  86. package/dist/channels/telegram/enhanced-commands.js.map +1 -0
  87. package/dist/channels/telegram/index.d.ts +6 -0
  88. package/dist/channels/telegram/index.js +6 -0
  89. package/dist/channels/telegram/index.js.map +1 -1
  90. package/dist/channels/telegram/pro-formatter.d.ts +30 -0
  91. package/dist/channels/telegram/pro-formatter.js +276 -0
  92. package/dist/channels/telegram/pro-formatter.js.map +1 -0
  93. package/dist/channels/telegram/run-commands.d.ts +5 -0
  94. package/dist/channels/telegram/run-commands.js +6 -0
  95. package/dist/channels/telegram/run-commands.js.map +1 -0
  96. package/dist/channels/telegram/run-tracker.d.ts +5 -0
  97. package/dist/channels/telegram/run-tracker.js +5 -0
  98. package/dist/channels/telegram/run-tracker.js.map +1 -0
  99. package/dist/channels/telegram/scoped-auth.d.ts +6 -0
  100. package/dist/channels/telegram/scoped-auth.js +5 -0
  101. package/dist/channels/telegram/scoped-auth.js.map +1 -0
  102. package/dist/channels/telegram/types.d.ts +34 -0
  103. package/dist/codebuddy/client.js +14 -1
  104. package/dist/codebuddy/client.js.map +1 -1
  105. package/dist/commands/dev/index.d.ts +12 -0
  106. package/dist/commands/dev/index.js +231 -0
  107. package/dist/commands/dev/index.js.map +1 -0
  108. package/dist/commands/dev/workflows.d.ts +31 -0
  109. package/dist/commands/dev/workflows.js +214 -0
  110. package/dist/commands/dev/workflows.js.map +1 -0
  111. package/dist/commands/execpolicy.d.ts +17 -0
  112. package/dist/commands/execpolicy.js +155 -0
  113. package/dist/commands/execpolicy.js.map +1 -0
  114. package/dist/commands/knowledge.d.ts +13 -0
  115. package/dist/commands/knowledge.js +142 -0
  116. package/dist/commands/knowledge.js.map +1 -0
  117. package/dist/commands/lessons.d.ts +11 -0
  118. package/dist/commands/lessons.js +129 -0
  119. package/dist/commands/lessons.js.map +1 -0
  120. package/dist/commands/pairing.d.ts +14 -0
  121. package/dist/commands/pairing.js +132 -0
  122. package/dist/commands/pairing.js.map +1 -0
  123. package/dist/commands/research/index.d.ts +13 -0
  124. package/dist/commands/research/index.js +91 -0
  125. package/dist/commands/research/index.js.map +1 -0
  126. package/dist/commands/run-cli/index.d.ts +11 -0
  127. package/dist/commands/run-cli/index.js +49 -0
  128. package/dist/commands/run-cli/index.js.map +1 -0
  129. package/dist/commands/todos.d.ts +9 -0
  130. package/dist/commands/todos.js +119 -0
  131. package/dist/commands/todos.js.map +1 -0
  132. package/dist/config/toml-config.d.ts +21 -0
  133. package/dist/config/toml-config.js +15 -0
  134. package/dist/config/toml-config.js.map +1 -1
  135. package/dist/context/enhanced-compression.js +12 -1
  136. package/dist/context/enhanced-compression.js.map +1 -1
  137. package/dist/context/observation-variator.d.ts +44 -0
  138. package/dist/context/observation-variator.js +83 -0
  139. package/dist/context/observation-variator.js.map +1 -0
  140. package/dist/context/precompaction-flush.d.ts +40 -0
  141. package/dist/context/precompaction-flush.js +134 -0
  142. package/dist/context/precompaction-flush.js.map +1 -0
  143. package/dist/context/restorable-compression.d.ts +80 -0
  144. package/dist/context/restorable-compression.js +228 -0
  145. package/dist/context/restorable-compression.js.map +1 -0
  146. package/dist/daemon/daily-reset.d.ts +77 -0
  147. package/dist/daemon/daily-reset.js +175 -0
  148. package/dist/daemon/daily-reset.js.map +1 -0
  149. package/dist/daemon/index.d.ts +1 -0
  150. package/dist/daemon/index.js +1 -0
  151. package/dist/daemon/index.js.map +1 -1
  152. package/dist/index.js +53 -0
  153. package/dist/index.js.map +1 -1
  154. package/dist/knowledge/knowledge-manager.d.ts +77 -0
  155. package/dist/knowledge/knowledge-manager.js +244 -0
  156. package/dist/knowledge/knowledge-manager.js.map +1 -0
  157. package/dist/observability/run-store.d.ts +133 -0
  158. package/dist/observability/run-store.js +419 -0
  159. package/dist/observability/run-store.js.map +1 -0
  160. package/dist/observability/run-viewer.d.ts +33 -0
  161. package/dist/observability/run-viewer.js +254 -0
  162. package/dist/observability/run-viewer.js.map +1 -0
  163. package/dist/optimization/cache-breakpoints.d.ts +52 -0
  164. package/dist/optimization/cache-breakpoints.js +97 -0
  165. package/dist/optimization/cache-breakpoints.js.map +1 -0
  166. package/dist/persistence/session-store.d.ts +3 -1
  167. package/dist/persistence/session-store.js +1 -1
  168. package/dist/persistence/session-store.js.map +1 -1
  169. package/dist/prompts/system-base.js +51 -7
  170. package/dist/prompts/system-base.js.map +1 -1
  171. package/dist/prompts/variation-injector.d.ts +55 -0
  172. package/dist/prompts/variation-injector.js +171 -0
  173. package/dist/prompts/variation-injector.js.map +1 -0
  174. package/dist/prompts/workflow-rules.d.ts +10 -0
  175. package/dist/prompts/workflow-rules.js +79 -0
  176. package/dist/prompts/workflow-rules.js.map +1 -0
  177. package/dist/sandbox/execpolicy.d.ts +45 -0
  178. package/dist/sandbox/execpolicy.js +80 -0
  179. package/dist/sandbox/execpolicy.js.map +1 -1
  180. package/dist/sandbox/os-sandbox.d.ts +25 -0
  181. package/dist/sandbox/os-sandbox.js +73 -0
  182. package/dist/sandbox/os-sandbox.js.map +1 -1
  183. package/dist/security/security-audit.d.ts +10 -0
  184. package/dist/security/security-audit.js +116 -0
  185. package/dist/security/security-audit.js.map +1 -1
  186. package/dist/security/shell-env-policy.d.ts +45 -0
  187. package/dist/security/shell-env-policy.js +141 -0
  188. package/dist/security/shell-env-policy.js.map +1 -0
  189. package/dist/security/ssrf-guard.d.ts +61 -0
  190. package/dist/security/ssrf-guard.js +382 -0
  191. package/dist/security/ssrf-guard.js.map +1 -0
  192. package/dist/security/write-policy.d.ts +57 -0
  193. package/dist/security/write-policy.js +117 -0
  194. package/dist/security/write-policy.js.map +1 -0
  195. package/dist/services/prompt-builder.js +37 -0
  196. package/dist/services/prompt-builder.js.map +1 -1
  197. package/dist/themes/theme-schema.d.ts +10 -10
  198. package/dist/tools/ask-human-tool.d.ts +62 -0
  199. package/dist/tools/ask-human-tool.js +112 -0
  200. package/dist/tools/ask-human-tool.js.map +1 -0
  201. package/dist/tools/bash/bash-tool.d.ts +15 -0
  202. package/dist/tools/bash/bash-tool.js +62 -0
  203. package/dist/tools/bash/bash-tool.js.map +1 -1
  204. package/dist/tools/bash/command-validator.d.ts +1 -0
  205. package/dist/tools/bash/command-validator.js +5 -0
  206. package/dist/tools/bash/command-validator.js.map +1 -1
  207. package/dist/tools/create-skill-tool.d.ts +87 -0
  208. package/dist/tools/create-skill-tool.js +142 -0
  209. package/dist/tools/create-skill-tool.js.map +1 -0
  210. package/dist/tools/fetch-tool.js +5 -3
  211. package/dist/tools/fetch-tool.js.map +1 -1
  212. package/dist/tools/index.d.ts +1 -0
  213. package/dist/tools/index.js +1 -0
  214. package/dist/tools/index.js.map +1 -1
  215. package/dist/tools/plan-tool.d.ts +22 -0
  216. package/dist/tools/plan-tool.js +128 -0
  217. package/dist/tools/plan-tool.js.map +1 -0
  218. package/dist/tools/registry/attention-tools.d.ts +32 -0
  219. package/dist/tools/registry/attention-tools.js +225 -0
  220. package/dist/tools/registry/attention-tools.js.map +1 -0
  221. package/dist/tools/registry/index.d.ts +9 -1
  222. package/dist/tools/registry/index.js +30 -2
  223. package/dist/tools/registry/index.js.map +1 -1
  224. package/dist/tools/registry/knowledge-tools.d.ts +46 -0
  225. package/dist/tools/registry/knowledge-tools.js +293 -0
  226. package/dist/tools/registry/knowledge-tools.js.map +1 -0
  227. package/dist/tools/registry/lessons-tools.d.ts +48 -0
  228. package/dist/tools/registry/lessons-tools.js +359 -0
  229. package/dist/tools/registry/lessons-tools.js.map +1 -0
  230. package/dist/tools/registry/plan-tools.d.ts +2 -0
  231. package/dist/tools/registry/plan-tools.js +7 -0
  232. package/dist/tools/registry/plan-tools.js.map +1 -0
  233. package/dist/tools/registry/script-tools.d.ts +2 -0
  234. package/dist/tools/registry/script-tools.js +7 -0
  235. package/dist/tools/registry/script-tools.js.map +1 -0
  236. package/dist/tools/registry/tool-aliases.d.ts +44 -0
  237. package/dist/tools/registry/tool-aliases.js +130 -0
  238. package/dist/tools/registry/tool-aliases.js.map +1 -0
  239. package/dist/tools/run-script-tool.d.ts +13 -0
  240. package/dist/tools/run-script-tool.js +146 -0
  241. package/dist/tools/run-script-tool.js.map +1 -0
  242. package/dist/tools/web-search.d.ts +25 -0
  243. package/dist/tools/web-search.js +68 -6
  244. package/dist/tools/web-search.js.map +1 -1
  245. package/dist/utils/config-validation/schema.d.ts +2 -2
  246. package/dist/utils/debug-logger.d.ts +1 -1
  247. package/dist/utils/stable-json.d.ts +27 -0
  248. package/dist/utils/stable-json.js +50 -0
  249. package/dist/utils/stable-json.js.map +1 -0
  250. package/dist/webhooks/webhook-manager.d.ts +7 -0
  251. package/dist/webhooks/webhook-manager.js +29 -0
  252. package/dist/webhooks/webhook-manager.js.map +1 -1
  253. package/package.json +1 -1
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Lessons Tracker — Self-improvement loop for recurring patterns
3
+ *
4
+ * Maintains a persistent `lessons.md` in `.codebuddy/lessons.md` (project)
5
+ * and `~/.codebuddy/lessons.md` (global). On every agent turn the active
6
+ * lessons are injected BEFORE the todo suffix (stable rules before recency
7
+ * bias), so the model internalises learned patterns across sessions.
8
+ *
9
+ * The agent calls `lessons_add` to capture a new lesson after a correction;
10
+ * `lessons_search` to find relevant lessons before similar tasks.
11
+ *
12
+ * Categories follow a structured taxonomy:
13
+ * PATTERN — "What went wrong → correct approach"
14
+ * RULE — Invariant to always follow (e.g. "run tests before marking done")
15
+ * CONTEXT — Project/domain-specific facts (e.g. "this repo uses ESM imports")
16
+ * INSIGHT — Non-obvious observation useful for future tasks
17
+ */
18
+ import * as fs from 'fs';
19
+ import * as path from 'path';
20
+ import * as os from 'os';
21
+ // ============================================================================
22
+ // Singleton registry (one tracker per working directory)
23
+ // ============================================================================
24
+ const registry = new Map();
25
+ export function getLessonsTracker(workDir = process.cwd()) {
26
+ const key = path.resolve(workDir);
27
+ if (!registry.has(key)) {
28
+ registry.set(key, new LessonsTracker(key));
29
+ }
30
+ return registry.get(key);
31
+ }
32
+ // ============================================================================
33
+ // LessonsTracker
34
+ // ============================================================================
35
+ export class LessonsTracker {
36
+ workDir;
37
+ projectPath;
38
+ globalPath;
39
+ items = [];
40
+ loaded = false;
41
+ constructor(workDir) {
42
+ this.workDir = workDir;
43
+ const projectDir = path.join(workDir, '.codebuddy');
44
+ this.projectPath = path.join(projectDir, 'lessons.md');
45
+ this.globalPath = path.join(os.homedir(), '.codebuddy', 'lessons.md');
46
+ }
47
+ // --------------------------------------------------------------------------
48
+ // Public API
49
+ // --------------------------------------------------------------------------
50
+ load() {
51
+ if (this.loaded)
52
+ return;
53
+ this.loaded = true;
54
+ const globalItems = this.loadFile(this.globalPath);
55
+ const projectItems = this.loadFile(this.projectPath);
56
+ // Merge: project overrides global for duplicate ids
57
+ const byId = new Map();
58
+ for (const item of [...globalItems, ...projectItems]) {
59
+ byId.set(item.id, item);
60
+ }
61
+ this.items = Array.from(byId.values());
62
+ }
63
+ save() {
64
+ this.load();
65
+ // Save to project path only (global is managed manually or by `lessons_add --global`)
66
+ try {
67
+ const dir = path.dirname(this.projectPath);
68
+ if (!fs.existsSync(dir)) {
69
+ fs.mkdirSync(dir, { recursive: true });
70
+ }
71
+ fs.writeFileSync(this.projectPath, this.serialise(), 'utf-8');
72
+ }
73
+ catch {
74
+ // non-fatal
75
+ }
76
+ }
77
+ add(category, content, source = 'manual', context) {
78
+ this.load();
79
+ const item = {
80
+ id: Date.now().toString(36) + Math.random().toString(36).slice(2, 5),
81
+ category,
82
+ content,
83
+ context,
84
+ createdAt: Date.now(),
85
+ source,
86
+ };
87
+ this.items.push(item);
88
+ this.save();
89
+ return item;
90
+ }
91
+ remove(id) {
92
+ this.load();
93
+ const idx = this.items.findIndex(i => i.id === id);
94
+ if (idx === -1)
95
+ return false;
96
+ this.items.splice(idx, 1);
97
+ this.save();
98
+ return true;
99
+ }
100
+ clearByCategory(category) {
101
+ this.load();
102
+ const before = this.items.length;
103
+ this.items = category
104
+ ? this.items.filter(i => i.category !== category)
105
+ : [];
106
+ this.save();
107
+ return before - this.items.length;
108
+ }
109
+ list(category) {
110
+ this.load();
111
+ return category ? this.items.filter(i => i.category === category) : this.items;
112
+ }
113
+ search(query, category) {
114
+ this.load();
115
+ const q = query.toLowerCase();
116
+ return this.items.filter(item => {
117
+ if (category && item.category !== category)
118
+ return false;
119
+ return (item.content.toLowerCase().includes(q) ||
120
+ (item.context?.toLowerCase().includes(q) ?? false));
121
+ });
122
+ }
123
+ /**
124
+ * Build the per-turn context block injected BEFORE the todo suffix.
125
+ * Returns null when there are no lessons (avoids noisy injections).
126
+ */
127
+ buildContextBlock() {
128
+ this.load();
129
+ if (this.items.length === 0)
130
+ return null;
131
+ const lines = [
132
+ '<lessons_context>',
133
+ '## Active Lessons (apply to this turn)',
134
+ '',
135
+ ];
136
+ const grouped = new Map();
137
+ for (const item of this.items) {
138
+ const arr = grouped.get(item.category) ?? [];
139
+ arr.push(item);
140
+ grouped.set(item.category, arr);
141
+ }
142
+ const order = ['RULE', 'PATTERN', 'CONTEXT', 'INSIGHT'];
143
+ for (const cat of order) {
144
+ const catItems = grouped.get(cat);
145
+ if (!catItems || catItems.length === 0)
146
+ continue;
147
+ for (const item of catItems) {
148
+ const ctx = item.context ? ` _(${item.context})_` : '';
149
+ lines.push(`**[${item.category}]**${ctx} ${item.content}`);
150
+ }
151
+ }
152
+ lines.push('</lessons_context>');
153
+ return lines.join('\n');
154
+ }
155
+ // --------------------------------------------------------------------------
156
+ // Markdown serialisation / parsing
157
+ // --------------------------------------------------------------------------
158
+ serialise() {
159
+ const lines = [
160
+ '# Lessons Learned',
161
+ `<!-- auto-generated by Code Buddy — last updated ${new Date().toISOString()} -->`,
162
+ '',
163
+ ];
164
+ const grouped = new Map();
165
+ for (const item of this.items) {
166
+ const arr = grouped.get(item.category) ?? [];
167
+ arr.push(item);
168
+ grouped.set(item.category, arr);
169
+ }
170
+ const order = ['PATTERN', 'RULE', 'CONTEXT', 'INSIGHT'];
171
+ for (const cat of order) {
172
+ const catItems = grouped.get(cat);
173
+ if (!catItems || catItems.length === 0)
174
+ continue;
175
+ lines.push(`## ${cat}`);
176
+ for (const item of catItems) {
177
+ const date = new Date(item.createdAt).toISOString().slice(0, 10);
178
+ const ctx = item.context ? `:${item.context}` : '';
179
+ lines.push(`- [${item.id}] ${item.content} <!-- ${date} ${item.source}${ctx} -->`);
180
+ }
181
+ lines.push('');
182
+ }
183
+ return lines.join('\n');
184
+ }
185
+ loadFile(filePath) {
186
+ if (!fs.existsSync(filePath))
187
+ return [];
188
+ try {
189
+ const content = fs.readFileSync(filePath, 'utf-8');
190
+ return this.parseMd(content);
191
+ }
192
+ catch {
193
+ return [];
194
+ }
195
+ }
196
+ parseMd(content) {
197
+ const items = [];
198
+ let currentCategory = 'INSIGHT';
199
+ for (const rawLine of content.split('\n')) {
200
+ // Category header: ## PATTERN
201
+ const catMatch = rawLine.match(/^## (PATTERN|RULE|CONTEXT|INSIGHT)\s*$/);
202
+ if (catMatch) {
203
+ currentCategory = catMatch[1];
204
+ continue;
205
+ }
206
+ // Item: - [id] content <!-- date source:context -->
207
+ const itemMatch = rawLine.match(/^- \[([^\]]+)\] (.+?) <!-- ([^\s]+) ([^\s:]+)(?::([^-]+))? -->/);
208
+ if (itemMatch) {
209
+ items.push({
210
+ id: itemMatch[1],
211
+ content: itemMatch[2].trim(),
212
+ category: currentCategory,
213
+ createdAt: new Date(itemMatch[3]).getTime() || 0,
214
+ source: itemMatch[4] ?? 'manual',
215
+ context: itemMatch[5]?.trim() || undefined,
216
+ });
217
+ continue;
218
+ }
219
+ // Plain item fallback: - content
220
+ const plainMatch = rawLine.match(/^- (.+)/);
221
+ if (plainMatch) {
222
+ items.push({
223
+ id: Date.now().toString(36) + Math.random().toString(36).slice(2, 5),
224
+ content: plainMatch[1].trim(),
225
+ category: currentCategory,
226
+ createdAt: 0,
227
+ source: 'manual',
228
+ });
229
+ }
230
+ }
231
+ return items;
232
+ }
233
+ }
234
+ //# sourceMappingURL=lessons-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lessons-tracker.js","sourceRoot":"","sources":["../../src/agent/lessons-tracker.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  * - collect: Messages are batched into a single string for the next turn
10
10
  */
11
11
  import { EventEmitter } from 'events';
12
- export type MessageQueueMode = 'steer' | 'followup' | 'collect';
12
+ export type MessageQueueMode = 'steer' | 'followup' | 'collect' | 'steer-backlog';
13
13
  export interface QueuedMessage {
14
14
  /** Message content */
15
15
  content: string;
@@ -18,10 +18,33 @@ export interface QueuedMessage {
18
18
  /** When the message was enqueued */
19
19
  timestamp: Date;
20
20
  }
21
+ export interface MessageQueueOptions {
22
+ /**
23
+ * Wait for this many ms of silence before starting a followup turn.
24
+ * Prevents rapid "continue continue" bursts from spamming turns.
25
+ * Default: 1000 ms.
26
+ */
27
+ debounceMs?: number;
28
+ /**
29
+ * Maximum queued messages before overflow handling kicks in.
30
+ * Default: 20.
31
+ */
32
+ cap?: number;
33
+ /**
34
+ * How to handle overflow when `cap` is exceeded.
35
+ * 'drop' — silently drop the oldest message
36
+ * 'summarize' — replace the queue with a single synthetic bullet-list prompt
37
+ * Default: 'drop'.
38
+ */
39
+ drop?: 'drop' | 'summarize';
40
+ }
21
41
  export declare class MessageQueue extends EventEmitter {
22
42
  private mode;
23
43
  private queue;
24
44
  private processing;
45
+ private opts;
46
+ private debounceTimer;
47
+ constructor(options?: MessageQueueOptions);
25
48
  /**
26
49
  * Set the queue mode
27
50
  */
@@ -31,9 +54,23 @@ export declare class MessageQueue extends EventEmitter {
31
54
  */
32
55
  getMode(): MessageQueueMode;
33
56
  /**
34
- * Enqueue a message
57
+ * Enqueue a message.
58
+ * Handles debounce (followup mode), cap enforcement with overflow policy,
59
+ * and steer-backlog mode.
35
60
  */
36
61
  enqueue(msg: QueuedMessage): void;
62
+ /**
63
+ * Collapse all queued messages + incoming overflow into a single synthetic prompt.
64
+ */
65
+ private _summarizeOverflow;
66
+ /**
67
+ * Update queue options at runtime (e.g. from /queue steer debounce:2s cap:25)
68
+ */
69
+ configure(options: Partial<MessageQueueOptions>): void;
70
+ /**
71
+ * Get current queue options
72
+ */
73
+ getOptions(): Readonly<Required<MessageQueueOptions>>;
37
74
  /**
38
75
  * Check if a steering message is available (steer mode)
39
76
  */
@@ -16,6 +16,16 @@ export class MessageQueue extends EventEmitter {
16
16
  mode = 'followup';
17
17
  queue = [];
18
18
  processing = false;
19
+ opts;
20
+ debounceTimer = null;
21
+ constructor(options = {}) {
22
+ super();
23
+ this.opts = {
24
+ debounceMs: options.debounceMs ?? 1000,
25
+ cap: options.cap ?? 20,
26
+ drop: options.drop ?? 'drop',
27
+ };
28
+ }
19
29
  /**
20
30
  * Set the queue mode
21
31
  */
@@ -30,14 +40,69 @@ export class MessageQueue extends EventEmitter {
30
40
  return this.mode;
31
41
  }
32
42
  /**
33
- * Enqueue a message
43
+ * Enqueue a message.
44
+ * Handles debounce (followup mode), cap enforcement with overflow policy,
45
+ * and steer-backlog mode.
34
46
  */
35
47
  enqueue(msg) {
48
+ // Enforce capacity cap
49
+ if (this.queue.length >= this.opts.cap) {
50
+ if (this.opts.drop === 'summarize') {
51
+ this._summarizeOverflow(msg);
52
+ return;
53
+ }
54
+ else {
55
+ // Drop oldest
56
+ this.queue.shift();
57
+ }
58
+ }
36
59
  this.queue.push(msg);
37
60
  this.emit('message-enqueued', msg);
38
- if (this.mode === 'steer' && this.processing) {
61
+ if ((this.mode === 'steer' || this.mode === 'steer-backlog') && this.processing) {
39
62
  this.emit('steering-available');
40
63
  }
64
+ // Debounce: reset timer on each new message in followup/collect mode
65
+ if ((this.mode === 'followup' || this.mode === 'collect') && !this.processing) {
66
+ if (this.debounceTimer)
67
+ clearTimeout(this.debounceTimer);
68
+ this.debounceTimer = setTimeout(() => {
69
+ this.debounceTimer = null;
70
+ this.emit('debounce-ready');
71
+ }, this.opts.debounceMs);
72
+ }
73
+ }
74
+ /**
75
+ * Collapse all queued messages + incoming overflow into a single synthetic prompt.
76
+ */
77
+ _summarizeOverflow(incoming) {
78
+ const all = [...this.queue, incoming];
79
+ this.queue = [];
80
+ const bullets = all.map(m => `- [${m.source}] ${m.content}`).join('\n');
81
+ const synthetic = {
82
+ content: `Multiple queued messages (summarized due to overflow):\n${bullets}`,
83
+ source: 'queue-summary',
84
+ timestamp: new Date(),
85
+ };
86
+ this.queue.push(synthetic);
87
+ this.emit('message-enqueued', synthetic);
88
+ this.emit('overflow-summarized', { count: all.length });
89
+ }
90
+ /**
91
+ * Update queue options at runtime (e.g. from /queue steer debounce:2s cap:25)
92
+ */
93
+ configure(options) {
94
+ if (options.debounceMs !== undefined)
95
+ this.opts.debounceMs = options.debounceMs;
96
+ if (options.cap !== undefined)
97
+ this.opts.cap = options.cap;
98
+ if (options.drop !== undefined)
99
+ this.opts.drop = options.drop;
100
+ }
101
+ /**
102
+ * Get current queue options
103
+ */
104
+ getOptions() {
105
+ return { ...this.opts };
41
106
  }
42
107
  /**
43
108
  * Check if a steering message is available (steer mode)
@@ -1 +1 @@
1
- {"version":3,"file":"message-queue.js","sourceRoot":"","sources":["../../src/agent/message-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAiBtC,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAM,OAAO,YAAa,SAAQ,YAAY;IACpC,IAAI,GAAqB,UAAU,CAAC;IACpC,KAAK,GAAoB,EAAE,CAAC;IAC5B,UAAU,GAAG,KAAK,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,IAAsB;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,GAAkB;QACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAEnC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACtC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,aAAa;QACX,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"message-queue.js","sourceRoot":"","sources":["../../src/agent/message-queue.ts"],"names":[],"mappings":"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"}
@@ -12,3 +12,4 @@ export { CostLimitMiddleware } from './cost-limit.js';
12
12
  export { ContextWarningMiddleware } from './context-warning.js';
13
13
  export { AutoObservationMiddleware } from './auto-observation.js';
14
14
  export type { AutoObservationConfig } from './auto-observation.js';
15
+ export { WorkflowGuardMiddleware } from './workflow-guard.js';
@@ -10,4 +10,5 @@ export { TurnLimitMiddleware } from './turn-limit.js';
10
10
  export { CostLimitMiddleware } from './cost-limit.js';
11
11
  export { ContextWarningMiddleware } from './context-warning.js';
12
12
  export { AutoObservationMiddleware } from './auto-observation.js';
13
+ export { WorkflowGuardMiddleware } from './workflow-guard.js';
13
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Workflow Guard Middleware
3
+ *
4
+ * Detects tasks that require planning before acting (priority 45).
5
+ * When the first user message contains 3+ distinct action verbs AND
6
+ * there is no existing PLAN.md, emits a `steer` hint suggesting
7
+ * the agent create a plan before diving into implementation.
8
+ *
9
+ * This resolves the plan-first vs bug-fix tension:
10
+ * - Single-file fixes with 1-2 verbs: proceed directly
11
+ * - Multi-verb, multi-file tasks: steer toward plan init
12
+ *
13
+ * Priority 45 — runs after cost-limit (10) and turn-limit (10),
14
+ * but before most business logic middlewares (100+).
15
+ */
16
+ import type { ConversationMiddleware, MiddlewareContext, MiddlewareResult } from './types.js';
17
+ export declare class WorkflowGuardMiddleware implements ConversationMiddleware {
18
+ readonly name = "workflow-guard";
19
+ readonly priority = 45;
20
+ beforeTurn(context: MiddlewareContext): MiddlewareResult;
21
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Workflow Guard Middleware
3
+ *
4
+ * Detects tasks that require planning before acting (priority 45).
5
+ * When the first user message contains 3+ distinct action verbs AND
6
+ * there is no existing PLAN.md, emits a `steer` hint suggesting
7
+ * the agent create a plan before diving into implementation.
8
+ *
9
+ * This resolves the plan-first vs bug-fix tension:
10
+ * - Single-file fixes with 1-2 verbs: proceed directly
11
+ * - Multi-verb, multi-file tasks: steer toward plan init
12
+ *
13
+ * Priority 45 — runs after cost-limit (10) and turn-limit (10),
14
+ * but before most business logic middlewares (100+).
15
+ */
16
+ import * as fs from 'fs';
17
+ import * as path from 'path';
18
+ // Action verbs that indicate non-trivial scope
19
+ const ACTION_VERBS = new Set([
20
+ 'create', 'add', 'implement', 'build', 'write',
21
+ 'fix', 'repair', 'resolve', 'debug', 'patch',
22
+ 'update', 'change', 'modify', 'edit', 'refactor',
23
+ 'test', 'verify', 'validate', 'check',
24
+ 'deploy', 'release', 'publish', 'push',
25
+ 'remove', 'delete', 'drop', 'clean',
26
+ 'migrate', 'upgrade', 'downgrade',
27
+ 'integrate', 'connect', 'setup', 'configure',
28
+ 'optimise', 'optimize', 'improve', 'enhance',
29
+ 'document', 'explain', 'analyse', 'analyze',
30
+ ]);
31
+ function countDistinctActionVerbs(text) {
32
+ const words = text.toLowerCase().match(/\b\w+\b/g) ?? [];
33
+ const found = new Set();
34
+ for (const word of words) {
35
+ // Check base form and common conjugations
36
+ if (ACTION_VERBS.has(word))
37
+ found.add(word);
38
+ // Strip trailing 's' for 3rd person singular (creates → create)
39
+ else if (word.endsWith('s') && ACTION_VERBS.has(word.slice(0, -1)))
40
+ found.add(word.slice(0, -1));
41
+ // Strip 'ing' (creating → create)
42
+ else if (word.endsWith('ing') && ACTION_VERBS.has(word.slice(0, -3)))
43
+ found.add(word.slice(0, -3));
44
+ // Strip 'ed' (created → create)
45
+ else if (word.endsWith('ed') && ACTION_VERBS.has(word.slice(0, -2)))
46
+ found.add(word.slice(0, -2));
47
+ }
48
+ return found.size;
49
+ }
50
+ function hasPlanFile(cwd) {
51
+ return (fs.existsSync(path.join(cwd, 'PLAN.md')) ||
52
+ fs.existsSync(path.join(cwd, '.codebuddy', 'PLAN.md')));
53
+ }
54
+ export class WorkflowGuardMiddleware {
55
+ name = 'workflow-guard';
56
+ priority = 45;
57
+ beforeTurn(context) {
58
+ // Only trigger on the very first turn (round 0) of a session
59
+ if (context.toolRound !== 0) {
60
+ return { action: 'continue' };
61
+ }
62
+ // Extract last user message
63
+ const lastUser = [...context.messages]
64
+ .reverse()
65
+ .find(m => m.role === 'user');
66
+ if (!lastUser)
67
+ return { action: 'continue' };
68
+ const text = typeof lastUser.content === 'string'
69
+ ? lastUser.content
70
+ : Array.isArray(lastUser.content)
71
+ ? lastUser.content.map((c) => {
72
+ if (typeof c === 'object' && c !== null && 'text' in c) {
73
+ return c.text;
74
+ }
75
+ return '';
76
+ }).join(' ')
77
+ : '';
78
+ const verbCount = countDistinctActionVerbs(text);
79
+ // Trigger if 3+ distinct action verbs and no plan file exists
80
+ if (verbCount >= 3 && !hasPlanFile(process.cwd())) {
81
+ return {
82
+ action: 'warn',
83
+ message: [
84
+ `[workflow-guard] This task involves ${verbCount} distinct actions.`,
85
+ 'Consider initialising a plan first: call the `plan` tool with action="init"',
86
+ 'or create PLAN.md to break the work into verifiable steps before acting.',
87
+ 'Proceeding without a plan — but be mindful of the Verification Contract.',
88
+ ].join(' '),
89
+ };
90
+ }
91
+ return { action: 'continue' };
92
+ }
93
+ }
94
+ //# sourceMappingURL=workflow-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-guard.js","sourceRoot":"","sources":["../../../src/agent/middleware/workflow-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * RepoProfiler
3
+ *
4
+ * Scans the current repository to detect language, framework, package manager,
5
+ * and build/test commands. Produces a compact contextPack string injected into
6
+ * the agent system prompt to give it awareness of project conventions.
7
+ *
8
+ * Result is cached in .codebuddy/repoProfile.json and invalidated when
9
+ * package.json (or equivalent) changes.
10
+ */
11
+ export interface RepoProfile {
12
+ detectedAt: string;
13
+ languages: string[];
14
+ framework?: string;
15
+ packageManager?: 'npm' | 'pnpm' | 'yarn' | 'poetry' | 'pip' | 'cargo' | 'dotnet' | 'go';
16
+ commands: {
17
+ test?: string;
18
+ lint?: string;
19
+ format?: string;
20
+ build?: string;
21
+ };
22
+ directories: {
23
+ src?: string;
24
+ tests?: string;
25
+ docs?: string;
26
+ };
27
+ conventions: {
28
+ naming?: string;
29
+ lintRules?: string[];
30
+ };
31
+ /** Compact string injected into agent system prompt */
32
+ contextPack: string;
33
+ /** mtime of the primary config file used for cache invalidation */
34
+ _configMtime?: number;
35
+ }
36
+ /**
37
+ * Profiles a repository to produce structured metadata.
38
+ */
39
+ export declare class RepoProfiler {
40
+ private cwd;
41
+ private cachePath;
42
+ constructor(cwd?: string);
43
+ /**
44
+ * Get or compute the repo profile.
45
+ * Uses cached result if the primary config file hasn't changed.
46
+ */
47
+ getProfile(): Promise<RepoProfile>;
48
+ /**
49
+ * Force recompute (ignores cache).
50
+ */
51
+ refresh(): Promise<RepoProfile>;
52
+ private computeProfile;
53
+ private buildContextPack;
54
+ private loadCache;
55
+ private isCacheStale;
56
+ private saveCache;
57
+ private exists;
58
+ private mtime;
59
+ private glob;
60
+ }
61
+ export declare function getRepoProfiler(cwd?: string): RepoProfiler;