bobs-workshop 0.3.3 → 3.1.1

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 (200) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +199 -210
  3. package/bin/bobs-workshop.js +109 -0
  4. package/config/agents.json +27 -0
  5. package/dist/plugins/bobs-workshop.js +34 -0
  6. package/dist/tools/background-agent/cancel.d.ts +3 -0
  7. package/dist/tools/background-agent/cancel.d.ts.map +1 -0
  8. package/dist/tools/background-agent/cancel.js +52 -0
  9. package/dist/tools/background-agent/concurrency.d.ts +15 -0
  10. package/dist/tools/background-agent/concurrency.d.ts.map +1 -0
  11. package/dist/tools/background-agent/concurrency.js +61 -0
  12. package/dist/tools/background-agent/index.d.ts +8 -0
  13. package/dist/tools/background-agent/index.d.ts.map +1 -0
  14. package/dist/tools/background-agent/index.js +7 -0
  15. package/dist/tools/background-agent/launch.d.ts +6 -0
  16. package/dist/tools/background-agent/launch.d.ts.map +1 -0
  17. package/dist/tools/background-agent/launch.js +33 -0
  18. package/dist/tools/background-agent/list.d.ts +7 -0
  19. package/dist/tools/background-agent/list.d.ts.map +1 -0
  20. package/dist/tools/background-agent/list.js +40 -0
  21. package/dist/tools/background-agent/manager.d.ts +29 -0
  22. package/dist/tools/background-agent/manager.d.ts.map +1 -0
  23. package/dist/tools/background-agent/manager.js +388 -0
  24. package/dist/tools/background-agent/output.d.ts +3 -0
  25. package/dist/tools/background-agent/output.d.ts.map +1 -0
  26. package/dist/tools/background-agent/output.js +41 -0
  27. package/dist/tools/background-agent/types.d.ts +46 -0
  28. package/dist/tools/background-agent/types.d.ts.map +1 -0
  29. package/dist/tools/background-agent/types.js +1 -0
  30. package/dist/tools/index.d.ts +9 -0
  31. package/dist/tools/index.d.ts.map +1 -0
  32. package/dist/tools/index.js +8 -0
  33. package/dist/tools/manual/index.d.ts +3 -0
  34. package/dist/tools/manual/index.d.ts.map +1 -0
  35. package/dist/tools/manual/index.js +2 -0
  36. package/dist/tools/manual/manual-update.d.ts +4 -0
  37. package/dist/tools/manual/manual-update.d.ts.map +1 -0
  38. package/dist/tools/manual/manual-update.js +190 -0
  39. package/dist/tools/manual/verify-manual.d.ts +4 -0
  40. package/dist/tools/manual/verify-manual.d.ts.map +1 -0
  41. package/dist/tools/manual/verify-manual.js +51 -0
  42. package/package.json +34 -66
  43. package/postinstall.js +193 -0
  44. package/src/agents/alice.md +466 -0
  45. package/src/agents/bob-rev.md +493 -0
  46. package/src/agents/bob-send.md +277 -0
  47. package/src/agents/bob.md +442 -0
  48. package/src/agents/trace.md +451 -0
  49. package/src/plugins/bobs-workshop.ts +45 -0
  50. package/src/skills/api-patterns/SKILL.md +376 -0
  51. package/src/skills/architecture/SKILL.md +271 -0
  52. package/src/skills/bobs-workshop/performance/icon.svg +3 -0
  53. package/src/skills/brainstorming/SKILL.md +210 -0
  54. package/src/skills/clean-code/SKILL.md +151 -0
  55. package/src/skills/code-review-checklist/SKILL.md +220 -0
  56. package/src/skills/database-design/SKILL.md +271 -0
  57. package/src/skills/exploration/SKILL.md +257 -0
  58. package/src/skills/frontend-ui-ux/SKILL.md +78 -0
  59. package/src/skills/git-master/SKILL.md +1105 -0
  60. package/src/skills/performance/SKILL.md +144 -0
  61. package/src/skills/performance/icon.svg +3 -0
  62. package/src/skills/plan-writing/SKILL.md +225 -0
  63. package/src/skills/security/SKILL.md +410 -0
  64. package/src/skills/simplification/SKILL.md +238 -0
  65. package/src/skills/systematic-debugging/SKILL.md +175 -0
  66. package/src/skills/testing-patterns/SKILL.md +305 -0
  67. package/src/skills/verification/SKILL.md +286 -0
  68. package/src/tools/background-agent/cancel.ts +67 -0
  69. package/src/tools/background-agent/concurrency.ts +71 -0
  70. package/src/tools/background-agent/index.ts +7 -0
  71. package/src/tools/background-agent/launch.ts +39 -0
  72. package/src/tools/background-agent/list.ts +50 -0
  73. package/src/tools/background-agent/manager.ts +466 -0
  74. package/src/tools/background-agent/output.ts +57 -0
  75. package/src/tools/background-agent/types.ts +55 -0
  76. package/src/tools/index.ts +8 -0
  77. package/src/tools/manual/index.ts +2 -0
  78. package/src/tools/manual/manual-update.ts +197 -0
  79. package/src/tools/manual/verify-manual.ts +60 -0
  80. package/uninstall.js +64 -0
  81. package/Claude.md +0 -162
  82. package/bin/bobs-mcp-server.js +0 -11
  83. package/bin/bobs-mcp.js +0 -130
  84. package/dist/api/taskLogger.js +0 -106
  85. package/dist/api/taskLogger.js.map +0 -1
  86. package/dist/cli/checker.js +0 -401
  87. package/dist/cli/checker.js.map +0 -1
  88. package/dist/cli/cleanup.js +0 -131
  89. package/dist/cli/cleanup.js.map +0 -1
  90. package/dist/cli/debug.js +0 -157
  91. package/dist/cli/debug.js.map +0 -1
  92. package/dist/cli/health.js +0 -97
  93. package/dist/cli/health.js.map +0 -1
  94. package/dist/cli/setup.js +0 -81
  95. package/dist/cli/setup.js.map +0 -1
  96. package/dist/cli/workshop.js +0 -42
  97. package/dist/cli/workshop.js.map +0 -1
  98. package/dist/dashboard/server.js +0 -1203
  99. package/dist/dashboard/server.js.map +0 -1
  100. package/dist/index.js +0 -960
  101. package/dist/index.js.map +0 -1
  102. package/dist/prompts/architect.js +0 -221
  103. package/dist/prompts/architect.js.map +0 -1
  104. package/dist/prompts/debugger.js +0 -257
  105. package/dist/prompts/debugger.js.map +0 -1
  106. package/dist/prompts/engineer.js +0 -249
  107. package/dist/prompts/engineer.js.map +0 -1
  108. package/dist/prompts/orchestrator.js +0 -304
  109. package/dist/prompts/orchestrator.js.map +0 -1
  110. package/dist/prompts/reviewer.js +0 -289
  111. package/dist/prompts/reviewer.js.map +0 -1
  112. package/dist/services/activitySummarizer.js +0 -388
  113. package/dist/services/activitySummarizer.js.map +0 -1
  114. package/dist/services/changeValidator.js +0 -396
  115. package/dist/services/changeValidator.js.map +0 -1
  116. package/dist/services/claudeOrchestrator.js +0 -343
  117. package/dist/services/claudeOrchestrator.js.map +0 -1
  118. package/dist/services/fileMonitor.js +0 -250
  119. package/dist/services/fileMonitor.js.map +0 -1
  120. package/dist/services/implementationSummarizer.js +0 -306
  121. package/dist/services/implementationSummarizer.js.map +0 -1
  122. package/dist/services/liveMonitor.js +0 -315
  123. package/dist/services/liveMonitor.js.map +0 -1
  124. package/dist/services/mcpAuditLogger.js +0 -104
  125. package/dist/services/mcpAuditLogger.js.map +0 -1
  126. package/dist/services/mcpLogger.js +0 -223
  127. package/dist/services/mcpLogger.js.map +0 -1
  128. package/dist/services/tmuxManager.js +0 -541
  129. package/dist/services/tmuxManager.js.map +0 -1
  130. package/dist/tools/approvalTools.js +0 -244
  131. package/dist/tools/approvalTools.js.map +0 -1
  132. package/dist/tools/autoDebugger.js +0 -147
  133. package/dist/tools/autoDebugger.js.map +0 -1
  134. package/dist/tools/cleanupService.js +0 -221
  135. package/dist/tools/cleanupService.js.map +0 -1
  136. package/dist/tools/dashboardTools.js +0 -342
  137. package/dist/tools/dashboardTools.js.map +0 -1
  138. package/dist/tools/developmentNudges.js +0 -336
  139. package/dist/tools/developmentNudges.js.map +0 -1
  140. package/dist/tools/gitTools.js +0 -741
  141. package/dist/tools/gitTools.js.map +0 -1
  142. package/dist/tools/orchestratorTools.js +0 -832
  143. package/dist/tools/orchestratorTools.js.map +0 -1
  144. package/dist/tools/searchCache.js +0 -64
  145. package/dist/tools/searchCache.js.map +0 -1
  146. package/dist/tools/searchTools.js +0 -1107
  147. package/dist/tools/searchTools.js.map +0 -1
  148. package/dist/tools/semgrep-patterns.js +0 -296
  149. package/dist/tools/semgrep-patterns.js.map +0 -1
  150. package/dist/tools/specTools.js +0 -332
  151. package/dist/tools/specTools.js.map +0 -1
  152. package/dist/tools/structural/__tests__/orchestrator.test.js +0 -61
  153. package/dist/tools/structural/__tests__/orchestrator.test.js.map +0 -1
  154. package/dist/tools/structural/cache.js +0 -226
  155. package/dist/tools/structural/cache.js.map +0 -1
  156. package/dist/tools/structural/engines/python/index.js +0 -118
  157. package/dist/tools/structural/engines/python/index.js.map +0 -1
  158. package/dist/tools/structural/engines/typescript/__tests__/typescript-engine.test.js +0 -97
  159. package/dist/tools/structural/engines/typescript/__tests__/typescript-engine.test.js.map +0 -1
  160. package/dist/tools/structural/engines/typescript/analyzer.js +0 -433
  161. package/dist/tools/structural/engines/typescript/analyzer.js.map +0 -1
  162. package/dist/tools/structural/engines/typescript/index.js +0 -381
  163. package/dist/tools/structural/engines/typescript/index.js.map +0 -1
  164. package/dist/tools/structural/engines/typescript/utils.js +0 -279
  165. package/dist/tools/structural/engines/typescript/utils.js.map +0 -1
  166. package/dist/tools/structural/index.js +0 -248
  167. package/dist/tools/structural/index.js.map +0 -1
  168. package/dist/tools/structural/types.js +0 -18
  169. package/dist/tools/structural/types.js.map +0 -1
  170. package/dist/tools/tmuxTools.js +0 -100
  171. package/dist/tools/tmuxTools.js.map +0 -1
  172. package/dist/tools/workRecorder.js +0 -215
  173. package/dist/tools/workRecorder.js.map +0 -1
  174. package/dist/tools/worktreeTools.js +0 -705
  175. package/dist/tools/worktreeTools.js.map +0 -1
  176. package/dist/utils/__tests__/integration.test.js +0 -57
  177. package/dist/utils/__tests__/integration.test.js.map +0 -1
  178. package/dist/utils/__tests__/serverDetection.test.js +0 -151
  179. package/dist/utils/__tests__/serverDetection.test.js.map +0 -1
  180. package/dist/utils/errorHandling.js +0 -336
  181. package/dist/utils/errorHandling.js.map +0 -1
  182. package/dist/utils/processManager.js +0 -172
  183. package/dist/utils/processManager.js.map +0 -1
  184. package/dist/utils/reliability.js +0 -263
  185. package/dist/utils/reliability.js.map +0 -1
  186. package/dist/utils/responseFormatter.js +0 -250
  187. package/dist/utils/responseFormatter.js.map +0 -1
  188. package/dist/utils/serverDetection.js +0 -133
  189. package/dist/utils/serverDetection.js.map +0 -1
  190. package/dist/utils/specMigration.js +0 -105
  191. package/dist/utils/specMigration.js.map +0 -1
  192. package/dist/validation/schemas.js +0 -299
  193. package/dist/validation/schemas.js.map +0 -1
  194. package/public/.well-known/mcp/manifest.json +0 -473
  195. package/public/index.html +0 -3157
  196. package/public/index.html.backup +0 -2805
  197. package/public/index.html.backup2 +0 -1292
  198. package/scripts/cleanup-system-logs.ts +0 -121
  199. package/scripts/init-workspace.js +0 -63
  200. package/scripts/install-search-tools.js +0 -116
@@ -1,343 +0,0 @@
1
- // src/services/claudeOrchestrator.ts
2
- import { exec } from "child_process";
3
- import { promisify } from "util";
4
- import { EventEmitter } from "events";
5
- import fs from "fs-extra";
6
- const execAsync = promisify(exec);
7
- /**
8
- * Claude Orchestrator Service
9
- * Manages Claude CLI processes within tmux sessions with lifecycle management
10
- */
11
- export class ClaudeOrchestrator extends EventEmitter {
12
- constructor() {
13
- super();
14
- this.processes = new Map();
15
- this.monitoringIntervals = new Map();
16
- }
17
- /**
18
- * Spawn Claude process in existing tmux session
19
- */
20
- async spawnClaudeInSession(sessionName, prompt, workingDir) {
21
- try {
22
- // Verify tmux session exists
23
- await this.verifySessionExists(sessionName);
24
- // Start Claude in interactive mode
25
- await execAsync(`tmux send-keys -t "${sessionName}" "claude --dangerously-skip-permissions" C-m`);
26
- // Wait for Claude to be ready by monitoring output
27
- await this.waitForClaudeReady(sessionName);
28
- // Write prompt to temp file and use tmux paste to preserve formatting
29
- const tempFile = `/tmp/claude-prompt-${Date.now()}.txt`;
30
- await fs.writeFile(tempFile, prompt);
31
- // Load the prompt into tmux buffer and paste it
32
- await execAsync(`tmux load-buffer "${tempFile}"`);
33
- await execAsync(`tmux paste-buffer -t "${sessionName}"`);
34
- // Send enter to submit the prompt
35
- await execAsync(`tmux send-keys -t "${sessionName}" C-m`);
36
- // Clean up temp file
37
- await fs.unlink(tempFile).catch(() => { });
38
- // Create process record
39
- const claudeProcess = {
40
- sessionName,
41
- status: 'initializing',
42
- startTime: new Date().toISOString(),
43
- lastActivity: new Date().toISOString(),
44
- workingDirectory: workingDir,
45
- prompt
46
- };
47
- this.processes.set(sessionName, claudeProcess);
48
- // Start monitoring this process
49
- this.startProcessMonitoring(sessionName);
50
- // Emit process started event
51
- this.emit('processStarted', claudeProcess);
52
- return claudeProcess;
53
- }
54
- catch (error) {
55
- const errorMessage = error instanceof Error ? error.message : String(error);
56
- throw new Error(`Failed to spawn Claude in session ${sessionName}: ${errorMessage}`);
57
- }
58
- }
59
- /**
60
- * Stop Claude process in session (send Ctrl-C)
61
- */
62
- async stopClaudeProcess(sessionName) {
63
- try {
64
- await this.verifySessionExists(sessionName);
65
- // Send Ctrl-C to interrupt Claude
66
- await execAsync(`tmux send-keys -t "${sessionName}" C-c`);
67
- // Update process status
68
- const process = this.processes.get(sessionName);
69
- if (process) {
70
- process.status = 'terminated';
71
- process.lastActivity = new Date().toISOString();
72
- this.processes.set(sessionName, process);
73
- // Stop monitoring
74
- this.stopProcessMonitoring(sessionName);
75
- // Emit process stopped event
76
- this.emit('processStopped', process);
77
- }
78
- }
79
- catch (error) {
80
- throw new Error(`Failed to stop Claude process in session ${sessionName}: ${error instanceof Error ? error.message : String(error)}`);
81
- }
82
- }
83
- /**
84
- * Send message/command to interactive Claude session
85
- */
86
- async sendCommand(sessionName, command) {
87
- try {
88
- await this.verifySessionExists(sessionName);
89
- // Send message directly to Claude (interactive mode)
90
- // Just escape quotes for the tmux command itself
91
- const escapedCommand = command.replace(/"/g, '\\"');
92
- await execAsync(`tmux send-keys -t "${sessionName}" "${escapedCommand}" C-m`);
93
- // Update last activity
94
- const process = this.processes.get(sessionName);
95
- if (process) {
96
- process.lastActivity = new Date().toISOString();
97
- this.processes.set(sessionName, process);
98
- }
99
- }
100
- catch (error) {
101
- throw new Error(`Failed to send command to session ${sessionName}: ${error instanceof Error ? error.message : String(error)}`);
102
- }
103
- }
104
- /**
105
- * Get process status
106
- */
107
- async getProcessStatus(sessionName) {
108
- return this.processes.get(sessionName) || null;
109
- }
110
- /**
111
- * Restart Claude process with same or new prompt
112
- */
113
- async restartProcess(sessionName, newPrompt) {
114
- const existingProcess = this.processes.get(sessionName);
115
- if (!existingProcess) {
116
- throw new Error(`No process found for session ${sessionName}`);
117
- }
118
- // Stop current process if running
119
- if (existingProcess.status === 'running') {
120
- await this.stopClaudeProcess(sessionName);
121
- // Wait a moment for cleanup
122
- await new Promise(resolve => setTimeout(resolve, 1000));
123
- }
124
- // Restart with new or existing prompt
125
- const prompt = newPrompt || existingProcess.prompt;
126
- return await this.spawnClaudeInSession(sessionName, prompt, existingProcess.workingDirectory);
127
- }
128
- /**
129
- * Get all managed processes
130
- */
131
- getAllProcesses() {
132
- return Array.from(this.processes.values());
133
- }
134
- /**
135
- * Clean up terminated or orphaned processes
136
- */
137
- async cleanup() {
138
- let cleanedCount = 0;
139
- for (const [sessionName, process] of this.processes) {
140
- try {
141
- // Check if tmux session still exists
142
- const sessionExists = await this.sessionExists(sessionName);
143
- if (!sessionExists || process.status === 'terminated') {
144
- this.stopProcessMonitoring(sessionName);
145
- this.processes.delete(sessionName);
146
- cleanedCount++;
147
- }
148
- }
149
- catch (error) {
150
- console.warn(`Cleanup error for session ${sessionName}:`, error);
151
- }
152
- }
153
- return cleanedCount;
154
- }
155
- /**
156
- * Start monitoring a Claude process for status changes
157
- */
158
- startProcessMonitoring(sessionName) {
159
- // Clear existing monitoring if any
160
- this.stopProcessMonitoring(sessionName);
161
- const monitorInterval = setInterval(async () => {
162
- try {
163
- await this.checkProcessStatus(sessionName);
164
- }
165
- catch (error) {
166
- console.error(`Monitoring error for session ${sessionName}:`, error);
167
- }
168
- }, 2000); // Check every 2 seconds
169
- this.monitoringIntervals.set(sessionName, monitorInterval);
170
- }
171
- /**
172
- * Stop monitoring a process
173
- */
174
- stopProcessMonitoring(sessionName) {
175
- const interval = this.monitoringIntervals.get(sessionName);
176
- if (interval) {
177
- clearInterval(interval);
178
- this.monitoringIntervals.delete(sessionName);
179
- }
180
- }
181
- /**
182
- * Check process status by capturing tmux output
183
- */
184
- async checkProcessStatus(sessionName) {
185
- const process = this.processes.get(sessionName);
186
- if (!process)
187
- return;
188
- try {
189
- // Capture recent output from tmux session
190
- const { stdout } = await execAsync(`tmux capture-pane -t "${sessionName}" -p -S -50`);
191
- // Detect status from output
192
- const newStatus = this.detectStatusFromOutput(stdout);
193
- const previousStatus = process.status;
194
- // Update process if status changed
195
- if (newStatus !== previousStatus) {
196
- process.status = newStatus;
197
- process.lastActivity = new Date().toISOString();
198
- // Detect error messages
199
- if (newStatus === 'error') {
200
- const errorMatch = stdout.match(/(?:Error|Failed|Exception):\s*(.+)/i);
201
- if (errorMatch) {
202
- process.errorMessage = errorMatch[1].trim();
203
- }
204
- }
205
- this.processes.set(sessionName, process);
206
- // Emit status change event
207
- const statusUpdate = {
208
- sessionName,
209
- status: newStatus,
210
- lastOutput: stdout.split('\n').slice(-3).join('\n').trim(),
211
- timestamp: new Date().toISOString(),
212
- errorMessage: process.errorMessage
213
- };
214
- this.emit('statusChange', statusUpdate);
215
- // Stop monitoring if process completed or terminated
216
- if (newStatus === 'completed' || newStatus === 'terminated') {
217
- this.stopProcessMonitoring(sessionName);
218
- }
219
- }
220
- }
221
- catch (error) {
222
- // Session might have been terminated
223
- if (error instanceof Error && error.message.includes('no session found')) {
224
- process.status = 'terminated';
225
- this.processes.set(sessionName, process);
226
- this.stopProcessMonitoring(sessionName);
227
- }
228
- }
229
- }
230
- /**
231
- * Detect Claude process status from output patterns
232
- */
233
- detectStatusFromOutput(output) {
234
- const lowerOutput = output.toLowerCase();
235
- // Error patterns
236
- if (/(?:error|failed|exception|crashed)/i.test(output)) {
237
- return 'error';
238
- }
239
- // Completion patterns
240
- if (/(?:done|complete|finished|success)[\s\S]*$/i.test(output) ||
241
- /✓|✅|🎉/i.test(output)) {
242
- return 'completed';
243
- }
244
- // Waiting for input patterns
245
- if (/(?:waiting|please|enter|input|continue|\?)[\s\S]*$/i.test(output)) {
246
- return 'waiting_input';
247
- }
248
- // Running patterns (Claude is processing)
249
- if (/(?:processing|running|executing|thinking|working)/i.test(output)) {
250
- return 'running';
251
- }
252
- // If we see Claude's typical output, assume it's running
253
- if (output.includes('Claude') || output.includes('claude') ||
254
- /I'll|I'm|Let me/i.test(output)) {
255
- return 'running';
256
- }
257
- // Default to running if we can't determine
258
- return 'running';
259
- }
260
- /**
261
- * Verify tmux session exists
262
- */
263
- async verifySessionExists(sessionName) {
264
- const exists = await this.sessionExists(sessionName);
265
- if (!exists) {
266
- throw new Error(`tmux session '${sessionName}' does not exist`);
267
- }
268
- }
269
- /**
270
- * Check if tmux session exists
271
- */
272
- async sessionExists(sessionName) {
273
- try {
274
- await execAsync(`tmux has-session -t "${sessionName}"`);
275
- return true;
276
- }
277
- catch (error) {
278
- return false;
279
- }
280
- }
281
- /**
282
- * Escape string for shell command using printf approach to avoid quote nesting
283
- */
284
- escapeForShell(str) {
285
- // Use printf approach to completely avoid quote escaping issues
286
- // Replace newlines with \n and escape single quotes for printf
287
- return str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r');
288
- }
289
- /**
290
- * Wait for Claude to be ready by monitoring output
291
- */
292
- async waitForClaudeReady(sessionName) {
293
- const maxWaitTime = 30000; // 30 seconds max
294
- const checkInterval = 1000; // Check every 1 second
295
- const startTime = Date.now();
296
- while (Date.now() - startTime < maxWaitTime) {
297
- try {
298
- const { stdout } = await execAsync(`tmux capture-pane -t "${sessionName}" -p -S -50`);
299
- // Check if Claude is ready for input (shows login, theme selection or ready prompt)
300
- if (stdout.includes('Choose the text style') ||
301
- stdout.includes('Select login method') ||
302
- stdout.includes('How can I help you today?') ||
303
- stdout.includes('I\'m Claude') ||
304
- stdout.toLowerCase().includes('claude:')) {
305
- // If it's showing login selection, auto-select option 1
306
- if (stdout.includes('Select login method') && stdout.includes('Claude account with subscription')) {
307
- await execAsync(`tmux send-keys -t "${sessionName}" "1" C-m`);
308
- // Wait a bit more for login to complete
309
- await new Promise(resolve => setTimeout(resolve, 3000));
310
- }
311
- // If it's showing theme selection, auto-select dark mode
312
- if (stdout.includes('Choose the text style') && stdout.includes('Dark mode ✔')) {
313
- await execAsync(`tmux send-keys -t "${sessionName}" "1" C-m`);
314
- // Wait a bit more for theme selection to complete
315
- await new Promise(resolve => setTimeout(resolve, 2000));
316
- }
317
- return; // Claude is ready
318
- }
319
- }
320
- catch (error) {
321
- // Session might not exist yet, continue waiting
322
- }
323
- await new Promise(resolve => setTimeout(resolve, checkInterval));
324
- }
325
- // If we get here, we timed out - just proceed anyway
326
- console.warn(`Timed out waiting for Claude to be ready in session ${sessionName}`);
327
- }
328
- /**
329
- * Graceful shutdown - stop all monitoring
330
- */
331
- async shutdown() {
332
- // Stop all monitoring intervals
333
- for (const interval of this.monitoringIntervals.values()) {
334
- clearInterval(interval);
335
- }
336
- this.monitoringIntervals.clear();
337
- // Emit shutdown event
338
- this.emit('shutdown');
339
- }
340
- }
341
- // Export singleton instance
342
- export const claudeOrchestrator = new ClaudeOrchestrator();
343
- //# sourceMappingURL=claudeOrchestrator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claudeOrchestrator.js","sourceRoot":"","sources":["../../src/services/claudeOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -1,250 +0,0 @@
1
- // src/services/fileMonitor.ts
2
- import * as chokidar from 'chokidar';
3
- import path from 'path';
4
- import fs from 'fs-extra';
5
- import simpleGit from 'simple-git';
6
- import { mcpLogger } from './mcpLogger.js';
7
- const git = simpleGit();
8
- class FileMonitor {
9
- constructor(projectRoot = process.cwd()) {
10
- this.watcher = null;
11
- this.changeBuffer = [];
12
- this.untracked = [];
13
- this.projectRoot = projectRoot;
14
- }
15
- start() {
16
- if (this.watcher) {
17
- console.log('File monitor already running');
18
- return;
19
- }
20
- console.log('Starting file monitor...');
21
- // Watch entire repo except node_modules, .git, and dist
22
- this.watcher = chokidar.watch(this.projectRoot, {
23
- ignored: [
24
- '**/node_modules/**',
25
- '**/.git/**',
26
- '**/dist/**',
27
- '**/.bob/specs/**', // Don't watch our own spec files
28
- '**/build/**',
29
- '**/coverage/**'
30
- ],
31
- persistent: true,
32
- ignoreInitial: true
33
- });
34
- this.watcher
35
- .on('add', (filePath) => this.handleFileChange('added', filePath))
36
- .on('change', (filePath) => this.handleFileChange('changed', filePath))
37
- .on('unlink', (filePath) => this.handleFileChange('unlinked', filePath))
38
- .on('error', (error) => console.error('File watcher error:', error));
39
- console.log('File monitor started successfully');
40
- }
41
- stop() {
42
- if (this.watcher) {
43
- this.watcher.close();
44
- this.watcher = null;
45
- console.log('File monitor stopped');
46
- }
47
- }
48
- async handleFileChange(type, filePath) {
49
- try {
50
- const relativePath = path.relative(this.projectRoot, filePath);
51
- const timestamp = new Date().toISOString();
52
- // Get current branch and latest commit
53
- const branch = await git.revparse(['--abbrev-ref', 'HEAD']);
54
- let commit_hash = 'pending';
55
- try {
56
- const latestCommit = await git.log(['--max-count=1']);
57
- if (latestCommit.latest) {
58
- commit_hash = latestCommit.latest.hash.substring(0, 8);
59
- }
60
- }
61
- catch (error) {
62
- // Ignore commit errors for now
63
- }
64
- const changeEvent = {
65
- type,
66
- path: relativePath,
67
- timestamp,
68
- branch,
69
- commit_hash
70
- };
71
- // Try to map to a manual
72
- const spec_id = await this.mapFileToSpec(relativePath, branch);
73
- if (spec_id) {
74
- changeEvent.spec_id = spec_id;
75
- await this.attachToSpecFeed(spec_id, changeEvent);
76
- // Check for active operations for this manual and add file change as sub-event
77
- const activeOps = mcpLogger.getActiveOperationsForSpec(spec_id);
78
- for (const operationId of activeOps) {
79
- await mcpLogger.addSubEvent(operationId, {
80
- timestamp: changeEvent.timestamp,
81
- event: `📄 File ${type}: ${path.basename(relativePath)}`,
82
- details: {
83
- file: changeEvent.path,
84
- change_type: changeEvent.type,
85
- branch: changeEvent.branch
86
- }
87
- });
88
- }
89
- }
90
- else {
91
- // Add to untracked bucket
92
- this.addToUntracked(changeEvent);
93
- }
94
- this.changeBuffer.push(changeEvent);
95
- // Keep buffer size manageable
96
- if (this.changeBuffer.length > 1000) {
97
- this.changeBuffer = this.changeBuffer.slice(-500);
98
- }
99
- console.log(`File ${type}: ${relativePath} ${spec_id ? `→ ${spec_id}` : '→ untracked'}`);
100
- }
101
- catch (error) {
102
- console.error('Error handling file change:', error);
103
- }
104
- }
105
- async mapFileToSpec(filePath, branch) {
106
- try {
107
- // Strategy 1: Check if branch name contains manual ID
108
- const specIdMatch = branch.match(/SPEC-\d{8}-[^\/]+/);
109
- if (specIdMatch) {
110
- return specIdMatch[0];
111
- }
112
- // Strategy 2: Look for manual files that reference this file
113
- const specsDir = path.join(this.projectRoot, '.bob/specs');
114
- if (await fs.pathExists(specsDir)) {
115
- const specFiles = await fs.readdir(specsDir);
116
- for (const specFile of specFiles) {
117
- if (specFile.endsWith('.json')) {
118
- try {
119
- const specData = await fs.readJson(path.join(specsDir, specFile));
120
- // Check execution logs for file references
121
- const executionLogs = specData.execution_logs || specData.execution_log || [];
122
- for (const log of executionLogs) {
123
- if (log.files_changed && log.files_changed.includes(filePath)) {
124
- return specData.spec_id;
125
- }
126
- }
127
- // Check implementation plan for file references
128
- const implPlan = specData.implementation_plan || [];
129
- for (const task of implPlan) {
130
- if (task.description && task.description.includes(filePath)) {
131
- return specData.spec_id;
132
- }
133
- }
134
- }
135
- catch (error) {
136
- // Skip invalid spec files
137
- continue;
138
- }
139
- }
140
- }
141
- }
142
- return null;
143
- }
144
- catch (error) {
145
- console.error('Error mapping file to manual:', error);
146
- return null;
147
- }
148
- }
149
- async attachToSpecFeed(spec_id, changeEvent) {
150
- try {
151
- const specsDir = path.join(this.projectRoot, '.bob/specs');
152
- const specFile = path.join(specsDir, `${spec_id}.json`);
153
- if (await fs.pathExists(specFile)) {
154
- const specData = await fs.readJson(specFile);
155
- // Add to file_changes feed
156
- if (!specData.file_changes) {
157
- specData.file_changes = [];
158
- }
159
- specData.file_changes.push({
160
- timestamp: changeEvent.timestamp,
161
- type: changeEvent.type,
162
- file: changeEvent.path,
163
- branch: changeEvent.branch,
164
- commit_hash: changeEvent.commit_hash
165
- });
166
- // Keep only last 100 file changes per manual
167
- if (specData.file_changes.length > 100) {
168
- specData.file_changes = specData.file_changes.slice(-100);
169
- }
170
- specData.updated_at = changeEvent.timestamp;
171
- await fs.writeJson(specFile, specData, { spaces: 2 });
172
- // Notify dashboard if it's running
173
- try {
174
- await this.notifyDashboard(spec_id, 'file_changed', {
175
- file: changeEvent.path,
176
- type: changeEvent.type,
177
- timestamp: changeEvent.timestamp
178
- });
179
- }
180
- catch (error) {
181
- // Dashboard not running, ignore
182
- }
183
- }
184
- }
185
- catch (error) {
186
- console.error('Error attaching to manual feed:', error);
187
- }
188
- }
189
- addToUntracked(changeEvent) {
190
- const existing = this.untracked.find(u => u.branch === changeEvent.branch &&
191
- Math.abs(new Date(u.timestamp).getTime() - new Date(changeEvent.timestamp).getTime()) < 60000 // within 1 minute
192
- );
193
- if (existing) {
194
- existing.files.push(changeEvent.path);
195
- }
196
- else {
197
- this.untracked.push({
198
- files: [changeEvent.path],
199
- timestamp: changeEvent.timestamp,
200
- branch: changeEvent.branch || 'unknown',
201
- commit_hash: changeEvent.commit_hash
202
- });
203
- }
204
- // Keep only last 50 untracked entries
205
- if (this.untracked.length > 50) {
206
- this.untracked = this.untracked.slice(-50);
207
- }
208
- }
209
- async notifyDashboard(spec_id, event, data) {
210
- try {
211
- const response = await fetch('http://localhost:4577/api/updates', {
212
- method: 'POST',
213
- headers: { 'Content-Type': 'application/json' },
214
- body: JSON.stringify({
215
- spec_id,
216
- event,
217
- data,
218
- timestamp: new Date().toISOString()
219
- })
220
- });
221
- return response.ok;
222
- }
223
- catch (error) {
224
- // Dashboard not running
225
- return false;
226
- }
227
- }
228
- getRecentChanges(limit = 50) {
229
- return this.changeBuffer.slice(-limit);
230
- }
231
- getUntrackedChanges() {
232
- return this.untracked;
233
- }
234
- async manuallyAssignToSpec(files, spec_id) {
235
- for (const file of files) {
236
- const changeEvent = {
237
- type: 'changed',
238
- path: file,
239
- timestamp: new Date().toISOString(),
240
- spec_id
241
- };
242
- await this.attachToSpecFeed(spec_id, changeEvent);
243
- }
244
- // Remove from untracked
245
- this.untracked = this.untracked.filter(u => !u.files.some(f => files.includes(f)));
246
- }
247
- }
248
- // Singleton instance
249
- export const fileMonitor = new FileMonitor();
250
- //# sourceMappingURL=fileMonitor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fileMonitor.js","sourceRoot":"","sources":["../../src/services/fileMonitor.ts"],"names":[],"mappings":"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"}