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,332 +0,0 @@
1
- // src/tools/specTools.ts
2
- import fs from "fs-extra";
3
- import path from "path";
4
- import { z } from "zod";
5
- import { formatConciseActivityLog } from "../utils/responseFormatter.js";
6
- import { createEnhancedActivity } from "../services/activitySummarizer.js";
7
- export const SpecCreateInput = z.object({
8
- title: z.string(),
9
- author: z.string().optional(),
10
- category: z.string().optional(),
11
- priority: z.string().optional(),
12
- tags: z.array(z.string()).optional(),
13
- initial_state: z.enum(["draft", "ready", "engineered", "done"]).default("draft")
14
- });
15
- export const SpecCreateOutput = z.object({
16
- spec_id: z.string(),
17
- path: z.string(),
18
- state: z.string(),
19
- created_at: z.string()
20
- });
21
- export const SpecUpdateInput = z.object({
22
- spec_id: z.string(),
23
- section: z.enum(["executive_summary", "product_specifications", "architecture_analysis", "implementation_plan", "testing", "risk_assessment", "review"]).optional(),
24
- content: z.string().optional(),
25
- execution_log: z.object({
26
- timestamp: z.string(),
27
- engineer: z.string(),
28
- action: z.string(),
29
- task_id: z.string(),
30
- files_changed: z.array(z.string()),
31
- commit_hash: z.string(),
32
- note: z.string()
33
- }).optional(),
34
- debug_log: z.object({
35
- timestamp: z.string(),
36
- issue: z.string(),
37
- root_cause: z.string(),
38
- fix: z.string(),
39
- confidence: z.string()
40
- }).optional(),
41
- worktree: z.object({
42
- branch: z.string().optional(),
43
- path: z.string().optional(),
44
- status: z.enum(["pending", "active", "removed", "merged"]).optional(),
45
- created_at: z.string().optional(),
46
- removed_at: z.string().optional()
47
- }).optional(),
48
- state: z.enum(["draft", "ready", "engineered", "done"]).optional()
49
- });
50
- export const SpecGetInput = z.object({
51
- spec_id: z.string()
52
- });
53
- export const SpecListInput = z.object({
54
- filter: z.string().optional()
55
- });
56
- export async function specCreateHandler(input) {
57
- console.log("specCreateHandler called with:", input);
58
- const validated = SpecCreateInput.parse(input);
59
- const sanitized = validated.title.replace(/[^a-z0-9\- ]/gi, "").trim().replace(/\s+/g, "-").toLowerCase();
60
- const specId = `SPEC-${new Date().toISOString().slice(0, 10)}-${sanitized}`;
61
- const specsDir = path.resolve(process.cwd(), ".bob/specs");
62
- await fs.ensureDir(specsDir);
63
- // Create full SPEC JSON with corrected schema
64
- const specData = {
65
- spec_id: specId,
66
- title: validated.title,
67
- author: validated.author || "unknown",
68
- state: validated.initial_state,
69
- category: validated.category || "general",
70
- priority: validated.priority || "medium",
71
- tags: validated.tags || [],
72
- related_specs: [],
73
- parent_spec_id: null,
74
- completion: 0,
75
- created_at: new Date().toISOString(),
76
- updated_at: new Date().toISOString(),
77
- // Worktree metadata
78
- worktree: {
79
- branch: "",
80
- path: "",
81
- status: "pending",
82
- created_at: "",
83
- removed_at: ""
84
- },
85
- // Required fields for validation
86
- executive_summary: "",
87
- product_specifications: "",
88
- architecture_analysis: "",
89
- implementation_plan: [],
90
- testing: "",
91
- risk_assessment: "",
92
- review: "",
93
- execution_logs: [],
94
- debug_logs: [],
95
- // Legacy format for backward compatibility
96
- sections: {
97
- executive_summary: { content: "", updated_at: "" },
98
- product_specifications: { content: "", updated_at: "" },
99
- architecture_analysis: { content: "", updated_at: "" },
100
- implementation_plan: { content: "", updated_at: "" },
101
- testing: { content: "", updated_at: "" },
102
- risk_assessment: { content: "", updated_at: "" },
103
- review: { content: "", updated_at: "" }
104
- },
105
- execution_log: [],
106
- debug_log: [],
107
- activity: [{ timestamp: new Date().toISOString(), role: "system", note: "SPEC created" }]
108
- };
109
- const filePath = path.join(specsDir, `${specId}.json`);
110
- await fs.writeFile(filePath, JSON.stringify(specData, null, 2), "utf8");
111
- // Update index.json
112
- const indexPath = path.join(specsDir, "index.json");
113
- let indexData = { specs: [] };
114
- if (await fs.pathExists(indexPath)) {
115
- indexData = await fs.readJson(indexPath);
116
- }
117
- indexData.specs.push({
118
- spec_id: specId,
119
- title: validated.title,
120
- state: specData.state,
121
- category: specData.category,
122
- updated_at: specData.updated_at
123
- });
124
- await fs.writeFile(indexPath, JSON.stringify(indexData, null, 2), "utf8");
125
- return {
126
- spec_id: specId,
127
- path: `.bob/specs/${specId}.json`,
128
- state: specData.state,
129
- created_at: specData.created_at
130
- };
131
- }
132
- export async function specUpdateHandler(input) {
133
- const validated = SpecUpdateInput.parse(input);
134
- const specsDir = path.resolve(process.cwd(), ".bob/specs");
135
- const filePath = path.join(specsDir, `${validated.spec_id}.json`);
136
- if (!await fs.pathExists(filePath)) {
137
- throw new Error(`SPEC ${validated.spec_id} not found`);
138
- }
139
- const specData = await fs.readJson(filePath);
140
- const timestamp = new Date().toISOString();
141
- specData.updated_at = timestamp;
142
- if (validated.section && validated.content) {
143
- specData.sections[validated.section] = {
144
- content: validated.content,
145
- updated_at: timestamp
146
- };
147
- // Concise activity log for terminal, detailed for dashboard
148
- const sectionName = validated.section.replace(/_/g, ' ');
149
- const contentLength = validated.content.length;
150
- const wordCount = validated.content.split(/\s+/).length;
151
- const completedSectionsCount = Object.values(specData.sections).filter((section) => section.content?.trim()).length;
152
- // Terminal-friendly concise log
153
- const conciseNote = formatConciseActivityLog('section_updated', {
154
- section: validated.section,
155
- wordCount,
156
- completedSectionsCount
157
- });
158
- // Detailed log for dashboard (preserved in a separate field)
159
- const detailedNote = `Updated ${sectionName} section: Added ${contentLength} characters (${wordCount} words). ${completedSectionsCount}/7 sections now completed. Section contains: ${validated.content.substring(0, 100)}${contentLength > 100 ? '...' : ''}`;
160
- specData.activity.push({
161
- timestamp,
162
- role: "system",
163
- note: conciseNote,
164
- details: detailedNote // Full details for dashboard
165
- });
166
- }
167
- // Explicit state management - no auto-detection (independent of section updates)
168
- if (validated.state) {
169
- const oldState = specData.state;
170
- specData.state = validated.state;
171
- specData.activity.push({
172
- timestamp,
173
- role: "system",
174
- note: `State explicitly changed from ${oldState} to ${validated.state}`
175
- });
176
- console.log(`[SPEC STATE] Explicit transition: ${oldState} → ${validated.state}`);
177
- }
178
- if (validated.execution_log) {
179
- // Add to both legacy and new format
180
- specData.execution_log.push(validated.execution_log);
181
- specData.execution_logs.push(validated.execution_log);
182
- // Concise execution log for terminal, detailed for dashboard
183
- const filesChangedCount = validated.execution_log.files_changed.length;
184
- const fileTypes = [...new Set(validated.execution_log.files_changed.map(file => file.split('.').pop() || 'unknown'))].join(', ');
185
- // Terminal-friendly concise log
186
- const conciseNote = formatConciseActivityLog('execution_log', {
187
- taskId: validated.execution_log.task_id,
188
- filesCount: filesChangedCount,
189
- action: validated.execution_log.action
190
- });
191
- // Detailed log for dashboard
192
- const detailedNote = `🛠️ ${validated.execution_log.action}: ${validated.execution_log.note}. Modified ${filesChangedCount} files (${fileTypes}). Task: ${validated.execution_log.task_id}. Engineer: ${validated.execution_log.engineer}. Files: ${validated.execution_log.files_changed.join(', ')}`;
193
- specData.activity.push({
194
- timestamp,
195
- role: "engineer",
196
- note: conciseNote,
197
- details: detailedNote
198
- });
199
- // Create enhanced activity for engineer execution log
200
- if (!specData.enhanced_activities) {
201
- specData.enhanced_activities = [];
202
- }
203
- const filesWithPlaceholderDiff = validated.execution_log.files_changed.map((file) => ({
204
- path: file,
205
- change_type: 'modified',
206
- lines_added: 0, // Git diff will be calculated by dashboard server
207
- lines_removed: 0
208
- }));
209
- const enhancedActivity = createEnhancedActivity(validated.spec_id, 'engineer', {
210
- summary: validated.execution_log.note,
211
- tasks_completed: [validated.execution_log.task_id],
212
- tasks_remaining: []
213
- }, filesWithPlaceholderDiff);
214
- specData.enhanced_activities.push(enhancedActivity);
215
- // No auto-detection for execution logs - state changes must be explicit
216
- }
217
- if (validated.debug_log) {
218
- // Add to both legacy and new format
219
- specData.debug_log.push(validated.debug_log);
220
- specData.debug_logs.push(validated.debug_log);
221
- // Concise debug log for terminal, detailed for dashboard
222
- const conciseNote = formatConciseActivityLog('debug_log', {
223
- confidence: validated.debug_log.confidence
224
- });
225
- const detailedNote = `🐛 Debug Issue: ${validated.debug_log.issue}. Root Cause: ${validated.debug_log.root_cause}. Fix Applied: ${validated.debug_log.fix}. Confidence: ${validated.debug_log.confidence}`;
226
- specData.activity.push({
227
- timestamp,
228
- role: "debugger",
229
- note: conciseNote,
230
- details: detailedNote
231
- });
232
- // Create enhanced activity for debugger
233
- if (!specData.enhanced_activities) {
234
- specData.enhanced_activities = [];
235
- }
236
- const enhancedActivity = createEnhancedActivity(validated.spec_id, 'debugger', {
237
- issue: validated.debug_log.issue,
238
- root_cause: validated.debug_log.root_cause,
239
- fix: validated.debug_log.fix,
240
- confidence: validated.debug_log.confidence.toLowerCase(),
241
- affected_systems: []
242
- }, []);
243
- specData.enhanced_activities.push(enhancedActivity);
244
- }
245
- // Handle worktree metadata updates
246
- if (validated.worktree) {
247
- // Ensure worktree object exists
248
- if (!specData.worktree) {
249
- specData.worktree = {
250
- branch: "",
251
- path: "",
252
- status: "pending",
253
- created_at: "",
254
- removed_at: ""
255
- };
256
- }
257
- // Update worktree fields
258
- if (validated.worktree.branch !== undefined) {
259
- specData.worktree.branch = validated.worktree.branch;
260
- }
261
- if (validated.worktree.path !== undefined) {
262
- specData.worktree.path = validated.worktree.path;
263
- }
264
- if (validated.worktree.status !== undefined) {
265
- const oldStatus = specData.worktree.status;
266
- specData.worktree.status = validated.worktree.status;
267
- // Log status changes
268
- if (oldStatus !== validated.worktree.status) {
269
- specData.activity.push({
270
- timestamp,
271
- role: "system",
272
- note: `Worktree status: ${oldStatus} → ${validated.worktree.status}`,
273
- details: `Worktree ${specData.worktree.branch} at ${specData.worktree.path} status changed from ${oldStatus} to ${validated.worktree.status}`
274
- });
275
- }
276
- }
277
- if (validated.worktree.created_at !== undefined) {
278
- specData.worktree.created_at = validated.worktree.created_at;
279
- }
280
- if (validated.worktree.removed_at !== undefined) {
281
- specData.worktree.removed_at = validated.worktree.removed_at;
282
- }
283
- }
284
- await fs.writeFile(filePath, JSON.stringify(specData, null, 2), "utf8");
285
- // Update index for dashboard real-time updates
286
- const indexPath = path.join(specsDir, "index.json");
287
- if (await fs.pathExists(indexPath)) {
288
- const indexData = await fs.readJson(indexPath);
289
- const specIndex = indexData.specs.findIndex((spec) => spec.spec_id === validated.spec_id);
290
- if (specIndex >= 0) {
291
- indexData.specs[specIndex].state = specData.state;
292
- indexData.specs[specIndex].updated_at = timestamp;
293
- await fs.writeFile(indexPath, JSON.stringify(indexData, null, 2), "utf8");
294
- }
295
- }
296
- // Dashboard reads from SPEC files directly - no separate update needed
297
- return { spec_id: validated.spec_id, updated_at: specData.updated_at, state: specData.state };
298
- }
299
- export async function specGetHandler(input) {
300
- const validated = input;
301
- const specsDir = path.resolve(process.cwd(), ".bob/specs");
302
- const filePath = path.join(specsDir, `${validated.spec_id}.json`);
303
- if (!await fs.pathExists(filePath)) {
304
- throw new Error(`SPEC ${validated.spec_id} not found`);
305
- }
306
- return await fs.readJson(filePath);
307
- }
308
- export async function specListHandler(input) {
309
- const validated = input;
310
- const specsDir = path.resolve(process.cwd(), ".bob/specs");
311
- const indexPath = path.join(specsDir, "index.json");
312
- if (!await fs.pathExists(indexPath)) {
313
- return { specs: [] };
314
- }
315
- const indexData = await fs.readJson(indexPath);
316
- let specs = indexData.specs || [];
317
- // Deduplicate specs by spec_id (keep the most recent one based on updated_at)
318
- const uniqueSpecs = new Map();
319
- specs.forEach((spec) => {
320
- const existing = uniqueSpecs.get(spec.spec_id);
321
- if (!existing || new Date(spec.updated_at) > new Date(existing.updated_at)) {
322
- uniqueSpecs.set(spec.spec_id, spec);
323
- }
324
- });
325
- specs = Array.from(uniqueSpecs.values());
326
- if (validated.filter) {
327
- specs = specs.filter((spec) => spec.title.toLowerCase().includes(validated.filter.toLowerCase()) ||
328
- spec.category.toLowerCase().includes(validated.filter.toLowerCase()));
329
- }
330
- return { specs };
331
- }
332
- //# sourceMappingURL=specTools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"specTools.js","sourceRoot":"","sources":["../../src/tools/specTools.ts"],"names":[],"mappings":"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"}
@@ -1,61 +0,0 @@
1
- import { StructuralSearchOrchestrator } from '../index.js';
2
- import { describe, it, expect, beforeEach } from '@jest/globals';
3
- describe('StructuralSearchOrchestrator', () => {
4
- let orchestrator;
5
- beforeEach(() => {
6
- orchestrator = new StructuralSearchOrchestrator();
7
- });
8
- describe('search', () => {
9
- it('should handle references queries', async () => {
10
- const results = await orchestrator.search('find references to TypeScriptEngine', { scope: __dirname, maxResults: 10 });
11
- expect(Array.isArray(results)).toBe(true);
12
- }, 30000);
13
- it('should handle definition queries', async () => {
14
- const results = await orchestrator.search('where is TypeScriptEngine defined', { scope: __dirname, maxResults: 10 });
15
- expect(Array.isArray(results)).toBe(true);
16
- }, 30000);
17
- it('should handle dependency queries', async () => {
18
- const results = await orchestrator.search('show dependencies for orchestrator.test.ts', { scope: __filename, maxResults: 10 });
19
- expect(Array.isArray(results)).toBe(true);
20
- }, 30000);
21
- it('should handle architectural issue queries', async () => {
22
- const results = await orchestrator.search('find circular dependencies', { scope: __dirname, maxResults: 10 });
23
- expect(Array.isArray(results)).toBe(true);
24
- }, 30000);
25
- it('should handle unused export queries', async () => {
26
- const results = await orchestrator.search('find unused exports', { scope: __dirname, maxResults: 10 });
27
- expect(Array.isArray(results)).toBe(true);
28
- }, 30000);
29
- it('should handle call graph queries', async () => {
30
- const results = await orchestrator.search('what calls search', { scope: __dirname, maxResults: 10 });
31
- expect(Array.isArray(results)).toBe(true);
32
- }, 30000);
33
- it('should detect TypeScript language from .ts file', async () => {
34
- const results = await orchestrator.search('find references to describe', { scope: __filename, maxResults: 10 });
35
- expect(Array.isArray(results)).toBe(true);
36
- }, 30000);
37
- it('should throw error for unsupported languages', async () => {
38
- // Python engine is not enabled yet, should throw error
39
- await expect(orchestrator.search('find references to something', { scope: '/tmp/test.py', maxResults: 10 })).rejects.toThrow('No structural search engine available for language: python');
40
- }, 30000);
41
- });
42
- describe('query parsing', () => {
43
- it('should parse "find references to X" pattern', async () => {
44
- const results = await orchestrator.search('find references to TypeScriptEngine', { scope: __dirname, maxResults: 5 });
45
- expect(Array.isArray(results)).toBe(true);
46
- }, 30000);
47
- it('should parse "show usages of X" pattern', async () => {
48
- const results = await orchestrator.search('show usages of TypeScriptEngine', { scope: __dirname, maxResults: 5 });
49
- expect(Array.isArray(results)).toBe(true);
50
- }, 30000);
51
- it('should parse "go to definition of X" pattern', async () => {
52
- const results = await orchestrator.search('go to definition of TypeScriptEngine', { scope: __dirname, maxResults: 5 });
53
- expect(Array.isArray(results)).toBe(true);
54
- }, 30000);
55
- it('should parse "what does X import" pattern', async () => {
56
- const results = await orchestrator.search('what does orchestrator.test.ts import', { scope: __filename, maxResults: 5 });
57
- expect(Array.isArray(results)).toBe(true);
58
- }, 30000);
59
- });
60
- });
61
- //# sourceMappingURL=orchestrator.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"orchestrator.test.js","sourceRoot":"","sources":["../../../../src/tools/structural/__tests__/orchestrator.test.ts"],"names":[],"mappings":"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"}
@@ -1,226 +0,0 @@
1
- import { LRUCache } from "lru-cache";
2
- import { createHash } from "crypto";
3
- import { readFile, stat } from "fs/promises";
4
- import { AnalysisError, ErrorCode } from "./types.js";
5
- export class CacheManager {
6
- constructor(options = {}) {
7
- this.stats = {
8
- hits: 0,
9
- misses: 0,
10
- evictions: 0,
11
- memoryUsage: 0
12
- };
13
- this.options = {
14
- invalidation: options.invalidation || "content-hash",
15
- ttl: options.ttl || 3600000 // 1 hour default
16
- };
17
- // Initialize LRU caches as per specification
18
- this.fileCache = new LRUCache({
19
- max: 1000,
20
- dispose: (value) => {
21
- // Clean up source file when evicted
22
- if (value?.sourceFile) {
23
- try {
24
- value.sourceFile.forget();
25
- }
26
- catch (e) {
27
- // Ignore cleanup errors
28
- }
29
- }
30
- this.stats.evictions++;
31
- }
32
- });
33
- this.symbolCache = new LRUCache({
34
- max: 10000,
35
- dispose: () => {
36
- this.stats.evictions++;
37
- }
38
- });
39
- this.analysisCache = new LRUCache({
40
- max: 5000,
41
- dispose: () => {
42
- this.stats.evictions++;
43
- }
44
- });
45
- }
46
- async getContentHash(filePath) {
47
- try {
48
- const content = await readFile(filePath, "utf8");
49
- return createHash("sha256").update(content).digest("hex");
50
- }
51
- catch (error) {
52
- throw new AnalysisError({
53
- code: ErrorCode.FILE_NOT_FOUND,
54
- message: `Failed to read file for hashing: ${filePath}`,
55
- details: { file: filePath }
56
- });
57
- }
58
- }
59
- async getFileStats(filePath) {
60
- try {
61
- const stats = await stat(filePath);
62
- return {
63
- lastModified: stats.mtimeMs,
64
- size: stats.size
65
- };
66
- }
67
- catch (error) {
68
- throw new AnalysisError({
69
- code: ErrorCode.FILE_NOT_FOUND,
70
- message: `Failed to get file stats: ${filePath}`,
71
- details: { file: filePath }
72
- });
73
- }
74
- }
75
- async isFileCacheValid(filePath, cached) {
76
- if (this.options.invalidation === "manual") {
77
- return true;
78
- }
79
- const stats = await this.getFileStats(filePath);
80
- if (this.options.invalidation === "timestamp") {
81
- return stats.lastModified <= cached.lastModified;
82
- }
83
- if (this.options.invalidation === "content-hash") {
84
- const currentHash = await this.getContentHash(filePath);
85
- return currentHash === cached.contentHash;
86
- }
87
- return false;
88
- }
89
- async getCachedFile(filePath) {
90
- const cached = this.fileCache.get(filePath);
91
- if (cached && await this.isFileCacheValid(filePath, cached)) {
92
- this.stats.hits++;
93
- return cached;
94
- }
95
- if (cached) {
96
- this.fileCache.delete(filePath);
97
- }
98
- this.stats.misses++;
99
- return undefined;
100
- }
101
- async setCachedFile(filePath, sourceFile) {
102
- const stats = await this.getFileStats(filePath);
103
- const contentHash = this.options.invalidation === "content-hash"
104
- ? await this.getContentHash(filePath)
105
- : "";
106
- this.fileCache.set(filePath, {
107
- sourceFile,
108
- lastModified: stats.lastModified,
109
- contentHash
110
- });
111
- }
112
- getCachedSymbol(key) {
113
- const cached = this.symbolCache.get(key);
114
- if (cached) {
115
- this.stats.hits++;
116
- return cached;
117
- }
118
- this.stats.misses++;
119
- return undefined;
120
- }
121
- setCachedSymbol(key, symbol) {
122
- this.symbolCache.set(key, symbol);
123
- }
124
- async getCachedAnalysis(key) {
125
- const cached = this.analysisCache.get(key);
126
- if (!cached) {
127
- this.stats.misses++;
128
- return undefined;
129
- }
130
- // Check TTL
131
- if (Date.now() - cached.timestamp > this.options.ttl) {
132
- this.analysisCache.delete(key);
133
- this.stats.misses++;
134
- return undefined;
135
- }
136
- this.stats.hits++;
137
- return cached.data;
138
- }
139
- async setCachedAnalysis(key, data) {
140
- this.analysisCache.set(key, {
141
- data,
142
- timestamp: Date.now()
143
- });
144
- }
145
- generateCacheKey(...parts) {
146
- const normalized = parts.map(part => {
147
- if (part === undefined || part === null) {
148
- return "null";
149
- }
150
- if (typeof part === "object") {
151
- return JSON.stringify(part, Object.keys(part).sort());
152
- }
153
- return String(part);
154
- }).join(":");
155
- return createHash("sha256").update(normalized).digest("hex");
156
- }
157
- async clearFileCache() {
158
- this.fileCache.clear();
159
- }
160
- async clearSymbolCache() {
161
- this.symbolCache.clear();
162
- }
163
- async clearAnalysisCache() {
164
- this.analysisCache.clear();
165
- }
166
- async clearAll() {
167
- await this.clearFileCache();
168
- await this.clearSymbolCache();
169
- await this.clearAnalysisCache();
170
- }
171
- getMemoryUsage() {
172
- const fileCount = this.fileCache.size;
173
- const symbolCount = this.symbolCache.size;
174
- const analysisCount = this.analysisCache.size;
175
- // Rough estimation of memory usage
176
- const avgFileSize = 50 * 1024; // 50KB average per file
177
- const avgSymbolSize = 1024; // 1KB average per symbol
178
- const avgAnalysisSize = 2 * 1024; // 2KB average per analysis
179
- const totalMemory = (fileCount * avgFileSize) + (symbolCount * avgSymbolSize) + (analysisCount * avgAnalysisSize);
180
- this.stats.memoryUsage = totalMemory;
181
- return totalMemory;
182
- }
183
- getStats() {
184
- return {
185
- fileCache: {
186
- size: this.fileCache.size,
187
- capacity: 1000
188
- },
189
- symbolCache: {
190
- size: this.symbolCache.size,
191
- capacity: 10000
192
- },
193
- analysisCache: {
194
- size: this.analysisCache.size,
195
- capacity: 5000
196
- },
197
- stats: { ...this.stats, memoryUsage: this.getMemoryUsage() }
198
- };
199
- }
200
- // Cache strategy based on project size
201
- static getCacheStrategy(fileCount) {
202
- if (fileCount < 100)
203
- return "memory";
204
- if (fileCount < 1000)
205
- return "memory";
206
- if (fileCount < 5000)
207
- return "hybrid";
208
- return "disk";
209
- }
210
- }
211
- // Global cache instance
212
- export const cacheManager = new CacheManager();
213
- // Helper for caching function results
214
- export function memoize(fn, keyGenerator) {
215
- return (async (...args) => {
216
- const key = keyGenerator ? keyGenerator(...args) : cacheManager.generateCacheKey(...args);
217
- const cached = await cacheManager.getCachedAnalysis(key);
218
- if (cached !== undefined) {
219
- return cached;
220
- }
221
- const result = await fn(...args);
222
- await cacheManager.setCachedAnalysis(key, result);
223
- return result;
224
- });
225
- }
226
- //# sourceMappingURL=cache.js.map