bobs-workshop 0.3.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +377 -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 +46 -0
  42. package/package.json +35 -67
  43. package/postinstall.js +190 -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 +455 -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 +55 -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,100 +0,0 @@
1
- // src/tools/tmuxTools.ts
2
- import { z } from "zod";
3
- import { tmuxManager } from "../services/tmuxManager.js";
4
- // Input schema for tmux list sessions tool
5
- export const TmuxListSessionsInput = z.object({
6
- filter_pattern: z.string()
7
- .optional()
8
- .describe("Optional regex pattern to filter sessions by name, spec_id, or worktree_id")
9
- });
10
- export const TmuxListSessionsOutput = z.object({
11
- available: z.boolean().describe("Whether tmux is available on the system"),
12
- sessions: z.array(z.object({
13
- session_name: z.string(),
14
- spec_id: z.string(),
15
- worktree_id: z.string(),
16
- worktree_path: z.string(),
17
- status: z.enum(['active', 'detached', 'inactive']),
18
- created_at: z.string(),
19
- attached_clients: z.number(),
20
- attach_command: z.string().describe("Command to attach to this session")
21
- })),
22
- total_sessions: z.number(),
23
- active_sessions: z.number(),
24
- detached_sessions: z.number()
25
- });
26
- export const TmuxCheckAvailabilityOutput = z.object({
27
- available: z.boolean().describe("Whether tmux is available on the system"),
28
- version: z.string().optional().describe("tmux version if available")
29
- });
30
- /**
31
- * MCP tool handler for listing tmux sessions (read-only observability)
32
- */
33
- export async function tmuxListSessionsHandler(input) {
34
- try {
35
- const available = await tmuxManager.checkAvailability();
36
- if (!available) {
37
- return {
38
- available: false,
39
- sessions: [],
40
- total_sessions: 0,
41
- active_sessions: 0,
42
- detached_sessions: 0
43
- };
44
- }
45
- const sessions = await tmuxManager.listSessions(input.filter_pattern);
46
- const enhancedSessions = sessions.map(session => ({
47
- ...session,
48
- attach_command: tmuxManager.getAttachCommand(session.session_name)
49
- }));
50
- const activeCount = sessions.filter(s => s.status === 'active').length;
51
- const detachedCount = sessions.filter(s => s.status === 'detached').length;
52
- return {
53
- available: true,
54
- sessions: enhancedSessions,
55
- total_sessions: sessions.length,
56
- active_sessions: activeCount,
57
- detached_sessions: detachedCount
58
- };
59
- }
60
- catch (error) {
61
- console.error("tmux list sessions error:", error);
62
- return {
63
- available: false,
64
- sessions: [],
65
- total_sessions: 0,
66
- active_sessions: 0,
67
- detached_sessions: 0
68
- };
69
- }
70
- }
71
- /**
72
- * Check tmux availability (helper for dashboard)
73
- */
74
- export async function tmuxCheckAvailabilityHandler() {
75
- try {
76
- const available = await tmuxManager.checkAvailability();
77
- if (!available) {
78
- return { available: false };
79
- }
80
- // Try to get version
81
- try {
82
- const { exec } = await import("child_process");
83
- const { promisify } = await import("util");
84
- const execAsync = promisify(exec);
85
- const { stdout } = await execAsync("tmux -V");
86
- const version = stdout.trim();
87
- return {
88
- available: true,
89
- version
90
- };
91
- }
92
- catch (versionError) {
93
- return { available: true };
94
- }
95
- }
96
- catch (error) {
97
- return { available: false };
98
- }
99
- }
100
- //# sourceMappingURL=tmuxTools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tmuxTools.js","sourceRoot":"","sources":["../../src/tools/tmuxTools.ts"],"names":[],"mappings":"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"}
@@ -1,215 +0,0 @@
1
- // src/tools/workRecorder.ts
2
- import { specUpdateHandler } from "./specTools.js";
3
- /**
4
- * Record detailed work activity with auto-interval logging
5
- */
6
- export class WorkRecorder {
7
- constructor(context) {
8
- this.activities = [];
9
- this.context = context;
10
- this.lastActivity = new Date();
11
- }
12
- /**
13
- * Start automatic work recording (no periodic updates - rely on explicit logging)
14
- */
15
- startRecording() {
16
- this.lastActivity = new Date();
17
- // Auto-stop after 30 minutes of inactivity (no periodic logging noise)
18
- this.intervalId = setInterval(async () => {
19
- const now = new Date();
20
- const minutesSinceLastActivity = (now.getTime() - this.lastActivity.getTime()) / (1000 * 60);
21
- // Auto-stop recording after 30 minutes of inactivity
22
- if (minutesSinceLastActivity >= 30) {
23
- console.log(`[WorkRecorder] Auto-stopping recording for ${this.context.spec_id} after 30 minutes of inactivity`);
24
- this.stopRecording();
25
- return;
26
- }
27
- }, 5 * 60 * 1000); // Check every 5 minutes
28
- // Initial recording
29
- this.recordActivity("started_work_session", "WORK_SESSION_START", [], `Started ${this.context.phase} phase work session as ${this.context.role}`);
30
- }
31
- /**
32
- * Stop automatic recording
33
- */
34
- stopRecording() {
35
- if (this.intervalId) {
36
- clearInterval(this.intervalId);
37
- this.intervalId = undefined;
38
- }
39
- this.recordActivity("ended_work_session", "WORK_SESSION_END", [], `Ended ${this.context.phase} phase work session. Total activities: ${this.activities.length}`);
40
- }
41
- /**
42
- * Record a specific work activity
43
- */
44
- async recordActivity(action, task_id, files_changed, note, commit_hash = "pending") {
45
- this.lastActivity = new Date();
46
- const activity = {
47
- timestamp: new Date().toISOString(),
48
- engineer: this.context.role,
49
- action: `${this.context.phase}: ${action}`,
50
- task_id,
51
- files_changed,
52
- commit_hash,
53
- note: `[${this.context.phase}] ${note}`
54
- };
55
- this.activities.push(activity);
56
- // Log to spec
57
- await specUpdateHandler({
58
- spec_id: this.context.spec_id,
59
- execution_log: activity
60
- });
61
- }
62
- /**
63
- * Record progress on a specific task
64
- */
65
- async recordProgress(task_id, progress_description, files_involved = [], completion_percentage) {
66
- const progressNote = completion_percentage
67
- ? `${progress_description} (${completion_percentage}% complete)`
68
- : progress_description;
69
- await this.recordActivity("task_progress", task_id, files_involved, `📈 Progress: ${progressNote}. Files involved: ${files_involved.join(', ') || 'none'}`);
70
- }
71
- /**
72
- * Record decision made during work
73
- */
74
- async recordDecision(task_id, decision, reasoning, files_affected = []) {
75
- await this.recordActivity("decision_made", task_id, files_affected, `🧠 Decision: ${decision}. Reasoning: ${reasoning}. Files affected: ${files_affected.join(', ') || 'none'}`);
76
- }
77
- /**
78
- * Record milestone completion
79
- */
80
- async recordMilestone(task_id, milestone, deliverables, next_steps = []) {
81
- const nextStepsText = next_steps.length > 0 ? ` Next: ${next_steps.join(', ')}` : "";
82
- await this.recordActivity("milestone_completed", task_id, deliverables, `🎯 Milestone: ${milestone}. Deliverables: ${deliverables.join(', ')}.${nextStepsText}`);
83
- // Check if this is a completion milestone
84
- if (milestone.toLowerCase().includes('complete') || milestone.toLowerCase().includes('finished')) {
85
- await this.recordActivity("implementation_completed", task_id, deliverables, `✅ Implementation completed: ${milestone}. Work session ending.`);
86
- // Auto-stop recording for completed implementations
87
- console.log(`[WorkRecorder] Auto-stopping recording for ${this.context.spec_id} - implementation completed`);
88
- this.stopRecording();
89
- }
90
- }
91
- /**
92
- * Get recording statistics
93
- */
94
- getStats() {
95
- const uniqueFiles = [...new Set(this.activities.flatMap(a => a.files_changed))];
96
- const uniqueTasks = [...new Set(this.activities.map(a => a.task_id))];
97
- const sessionStart = this.activities[0]?.timestamp ? new Date(this.activities[0].timestamp) : new Date();
98
- const sessionDuration = (new Date().getTime() - sessionStart.getTime()) / (1000 * 60); // minutes
99
- return {
100
- totalActivities: this.activities.length,
101
- sessionDuration: Math.floor(sessionDuration),
102
- filesModified: uniqueFiles,
103
- tasksWorkedOn: uniqueTasks
104
- };
105
- }
106
- /**
107
- * Update activity context (e.g., when phase changes)
108
- */
109
- updateContext(newContext) {
110
- this.context = { ...this.context, ...newContext };
111
- }
112
- }
113
- /**
114
- * Global work recorder instances by spec_id
115
- */
116
- const activeRecorders = new Map();
117
- /**
118
- * Start work recording for a spec
119
- */
120
- export function startWorkRecording(context) {
121
- const existing = activeRecorders.get(context.spec_id);
122
- if (existing) {
123
- existing.stopRecording();
124
- }
125
- const recorder = new WorkRecorder(context);
126
- recorder.startRecording();
127
- activeRecorders.set(context.spec_id, recorder);
128
- return recorder;
129
- }
130
- /**
131
- * Stop work recording for a spec
132
- */
133
- export function stopWorkRecording(spec_id) {
134
- const recorder = activeRecorders.get(spec_id);
135
- if (recorder) {
136
- recorder.stopRecording();
137
- activeRecorders.delete(spec_id);
138
- }
139
- }
140
- /**
141
- * Get active recorder for a spec
142
- */
143
- export function getWorkRecorder(spec_id) {
144
- return activeRecorders.get(spec_id);
145
- }
146
- /**
147
- * Record quick activity for a spec (creates recorder if needed)
148
- */
149
- export async function recordQuickActivity(spec_id, action, task_id, files_changed, note, context) {
150
- let recorder = activeRecorders.get(spec_id);
151
- if (!recorder && context) {
152
- const fullContext = {
153
- spec_id,
154
- phase: "implementation",
155
- role: "engineer",
156
- ...context
157
- };
158
- recorder = startWorkRecording(fullContext);
159
- }
160
- if (recorder) {
161
- await recorder.recordActivity(action, task_id, files_changed, note);
162
- }
163
- }
164
- /**
165
- * Cleanup orphaned work recorders (for completed SPECs)
166
- */
167
- export async function cleanupOrphanedRecorders() {
168
- const stoppedSpecs = [];
169
- for (const [spec_id, recorder] of activeRecorders.entries()) {
170
- try {
171
- // Check if SPEC is completed by reading its file
172
- const fs = await import('fs-extra');
173
- const path = await import('path');
174
- const specsDir = path.resolve(process.cwd(), ".bob/specs");
175
- const filePath = path.join(specsDir, `${spec_id}.json`);
176
- if (await fs.pathExists(filePath)) {
177
- const specData = await fs.readJson(filePath);
178
- // Stop recording for completed SPECs
179
- if (specData.state === "completed") {
180
- console.log(`[WorkRecorder] Stopping orphaned recorder for completed SPEC: ${spec_id}`);
181
- recorder.stopRecording();
182
- activeRecorders.delete(spec_id);
183
- stoppedSpecs.push(spec_id);
184
- }
185
- }
186
- }
187
- catch (error) {
188
- console.error(`[WorkRecorder] Error checking SPEC ${spec_id}:`, error);
189
- }
190
- }
191
- return {
192
- stopped: stoppedSpecs,
193
- active: activeRecorders.size
194
- };
195
- }
196
- /**
197
- * Get statistics about active recorders
198
- */
199
- export function getActiveRecorderStats() {
200
- const stats = {
201
- total: activeRecorders.size,
202
- specs: Array.from(activeRecorders.keys()),
203
- oldestSession: null
204
- };
205
- let oldestTime = Infinity;
206
- for (const [spec_id, recorder] of activeRecorders.entries()) {
207
- const recorderStats = recorder.getStats();
208
- if (recorderStats.sessionDuration < oldestTime) {
209
- oldestTime = recorderStats.sessionDuration;
210
- stats.oldestSession = { spec_id, duration: recorderStats.sessionDuration };
211
- }
212
- }
213
- return stats;
214
- }
215
- //# sourceMappingURL=workRecorder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workRecorder.js","sourceRoot":"","sources":["../../src/tools/workRecorder.ts"],"names":[],"mappings":"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"}