@lumenflow/core 1.0.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 (263) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +119 -0
  3. package/dist/active-wu-detector.d.ts +33 -0
  4. package/dist/active-wu-detector.js +106 -0
  5. package/dist/adapters/filesystem-metrics.adapter.d.ts +108 -0
  6. package/dist/adapters/filesystem-metrics.adapter.js +519 -0
  7. package/dist/adapters/terminal-renderer.adapter.d.ts +106 -0
  8. package/dist/adapters/terminal-renderer.adapter.js +337 -0
  9. package/dist/arg-parser.d.ts +63 -0
  10. package/dist/arg-parser.js +560 -0
  11. package/dist/backlog-editor.d.ts +98 -0
  12. package/dist/backlog-editor.js +179 -0
  13. package/dist/backlog-generator.d.ts +111 -0
  14. package/dist/backlog-generator.js +381 -0
  15. package/dist/backlog-parser.d.ts +45 -0
  16. package/dist/backlog-parser.js +102 -0
  17. package/dist/backlog-sync-validator.d.ts +78 -0
  18. package/dist/backlog-sync-validator.js +294 -0
  19. package/dist/branch-drift.d.ts +34 -0
  20. package/dist/branch-drift.js +51 -0
  21. package/dist/cleanup-install-config.d.ts +33 -0
  22. package/dist/cleanup-install-config.js +37 -0
  23. package/dist/cleanup-lock.d.ts +139 -0
  24. package/dist/cleanup-lock.js +313 -0
  25. package/dist/code-path-validator.d.ts +146 -0
  26. package/dist/code-path-validator.js +537 -0
  27. package/dist/code-paths-overlap.d.ts +55 -0
  28. package/dist/code-paths-overlap.js +245 -0
  29. package/dist/commands-logger.d.ts +77 -0
  30. package/dist/commands-logger.js +254 -0
  31. package/dist/commit-message-utils.d.ts +25 -0
  32. package/dist/commit-message-utils.js +41 -0
  33. package/dist/compliance-parser.d.ts +150 -0
  34. package/dist/compliance-parser.js +507 -0
  35. package/dist/constants/backlog-patterns.d.ts +20 -0
  36. package/dist/constants/backlog-patterns.js +23 -0
  37. package/dist/constants/dora-constants.d.ts +49 -0
  38. package/dist/constants/dora-constants.js +53 -0
  39. package/dist/constants/gate-constants.d.ts +15 -0
  40. package/dist/constants/gate-constants.js +15 -0
  41. package/dist/constants/linter-constants.d.ts +16 -0
  42. package/dist/constants/linter-constants.js +16 -0
  43. package/dist/constants/tokenizer-constants.d.ts +15 -0
  44. package/dist/constants/tokenizer-constants.js +15 -0
  45. package/dist/core/scope-checker.d.ts +97 -0
  46. package/dist/core/scope-checker.js +163 -0
  47. package/dist/core/tool-runner.d.ts +161 -0
  48. package/dist/core/tool-runner.js +393 -0
  49. package/dist/core/tool.constants.d.ts +105 -0
  50. package/dist/core/tool.constants.js +101 -0
  51. package/dist/core/tool.schemas.d.ts +226 -0
  52. package/dist/core/tool.schemas.js +226 -0
  53. package/dist/core/worktree-guard.d.ts +130 -0
  54. package/dist/core/worktree-guard.js +242 -0
  55. package/dist/coverage-gate.d.ts +108 -0
  56. package/dist/coverage-gate.js +196 -0
  57. package/dist/date-utils.d.ts +75 -0
  58. package/dist/date-utils.js +140 -0
  59. package/dist/dependency-graph.d.ts +142 -0
  60. package/dist/dependency-graph.js +550 -0
  61. package/dist/dependency-guard.d.ts +54 -0
  62. package/dist/dependency-guard.js +142 -0
  63. package/dist/dependency-validator.d.ts +105 -0
  64. package/dist/dependency-validator.js +154 -0
  65. package/dist/docs-path-validator.d.ts +36 -0
  66. package/dist/docs-path-validator.js +95 -0
  67. package/dist/domain/orchestration.constants.d.ts +99 -0
  68. package/dist/domain/orchestration.constants.js +97 -0
  69. package/dist/domain/orchestration.schemas.d.ts +280 -0
  70. package/dist/domain/orchestration.schemas.js +211 -0
  71. package/dist/domain/orchestration.types.d.ts +133 -0
  72. package/dist/domain/orchestration.types.js +12 -0
  73. package/dist/error-handler.d.ts +116 -0
  74. package/dist/error-handler.js +136 -0
  75. package/dist/file-classifiers.d.ts +62 -0
  76. package/dist/file-classifiers.js +108 -0
  77. package/dist/gates-agent-mode.d.ts +81 -0
  78. package/dist/gates-agent-mode.js +94 -0
  79. package/dist/generate-traceability.d.ts +107 -0
  80. package/dist/generate-traceability.js +411 -0
  81. package/dist/git-adapter.d.ts +395 -0
  82. package/dist/git-adapter.js +649 -0
  83. package/dist/git-staged-validator.d.ts +32 -0
  84. package/dist/git-staged-validator.js +48 -0
  85. package/dist/hardcoded-strings.d.ts +61 -0
  86. package/dist/hardcoded-strings.js +270 -0
  87. package/dist/incremental-lint.d.ts +78 -0
  88. package/dist/incremental-lint.js +129 -0
  89. package/dist/incremental-test.d.ts +39 -0
  90. package/dist/incremental-test.js +61 -0
  91. package/dist/index.d.ts +42 -0
  92. package/dist/index.js +61 -0
  93. package/dist/invariants/check-automated-tests.d.ts +50 -0
  94. package/dist/invariants/check-automated-tests.js +166 -0
  95. package/dist/invariants-runner.d.ts +103 -0
  96. package/dist/invariants-runner.js +527 -0
  97. package/dist/lane-checker.d.ts +50 -0
  98. package/dist/lane-checker.js +319 -0
  99. package/dist/lane-inference.d.ts +39 -0
  100. package/dist/lane-inference.js +195 -0
  101. package/dist/lane-lock.d.ts +211 -0
  102. package/dist/lane-lock.js +474 -0
  103. package/dist/lane-validator.d.ts +48 -0
  104. package/dist/lane-validator.js +114 -0
  105. package/dist/logs-lib.d.ts +104 -0
  106. package/dist/logs-lib.js +207 -0
  107. package/dist/lumenflow-config-schema.d.ts +272 -0
  108. package/dist/lumenflow-config-schema.js +207 -0
  109. package/dist/lumenflow-config.d.ts +95 -0
  110. package/dist/lumenflow-config.js +236 -0
  111. package/dist/manual-test-validator.d.ts +80 -0
  112. package/dist/manual-test-validator.js +200 -0
  113. package/dist/merge-lock.d.ts +115 -0
  114. package/dist/merge-lock.js +251 -0
  115. package/dist/micro-worktree.d.ts +159 -0
  116. package/dist/micro-worktree.js +427 -0
  117. package/dist/migration-deployer.d.ts +69 -0
  118. package/dist/migration-deployer.js +151 -0
  119. package/dist/orchestration-advisory-loader.d.ts +28 -0
  120. package/dist/orchestration-advisory-loader.js +87 -0
  121. package/dist/orchestration-advisory.d.ts +58 -0
  122. package/dist/orchestration-advisory.js +94 -0
  123. package/dist/orchestration-di.d.ts +48 -0
  124. package/dist/orchestration-di.js +57 -0
  125. package/dist/orchestration-rules.d.ts +57 -0
  126. package/dist/orchestration-rules.js +201 -0
  127. package/dist/orphan-detector.d.ts +131 -0
  128. package/dist/orphan-detector.js +226 -0
  129. package/dist/path-classifiers.d.ts +57 -0
  130. package/dist/path-classifiers.js +93 -0
  131. package/dist/piped-command-detector.d.ts +34 -0
  132. package/dist/piped-command-detector.js +64 -0
  133. package/dist/ports/dashboard-renderer.port.d.ts +112 -0
  134. package/dist/ports/dashboard-renderer.port.js +25 -0
  135. package/dist/ports/metrics-collector.port.d.ts +132 -0
  136. package/dist/ports/metrics-collector.port.js +26 -0
  137. package/dist/process-detector.d.ts +84 -0
  138. package/dist/process-detector.js +172 -0
  139. package/dist/prompt-linter.d.ts +72 -0
  140. package/dist/prompt-linter.js +312 -0
  141. package/dist/prompt-monitor.d.ts +15 -0
  142. package/dist/prompt-monitor.js +205 -0
  143. package/dist/rebase-artifact-cleanup.d.ts +145 -0
  144. package/dist/rebase-artifact-cleanup.js +433 -0
  145. package/dist/retry-strategy.d.ts +189 -0
  146. package/dist/retry-strategy.js +283 -0
  147. package/dist/risk-detector.d.ts +108 -0
  148. package/dist/risk-detector.js +252 -0
  149. package/dist/rollback-utils.d.ts +76 -0
  150. package/dist/rollback-utils.js +104 -0
  151. package/dist/section-headings.d.ts +43 -0
  152. package/dist/section-headings.js +49 -0
  153. package/dist/spawn-escalation.d.ts +90 -0
  154. package/dist/spawn-escalation.js +253 -0
  155. package/dist/spawn-monitor.d.ts +229 -0
  156. package/dist/spawn-monitor.js +672 -0
  157. package/dist/spawn-recovery.d.ts +82 -0
  158. package/dist/spawn-recovery.js +298 -0
  159. package/dist/spawn-registry-schema.d.ts +98 -0
  160. package/dist/spawn-registry-schema.js +108 -0
  161. package/dist/spawn-registry-store.d.ts +146 -0
  162. package/dist/spawn-registry-store.js +273 -0
  163. package/dist/spawn-tree.d.ts +121 -0
  164. package/dist/spawn-tree.js +285 -0
  165. package/dist/stamp-status-validator.d.ts +84 -0
  166. package/dist/stamp-status-validator.js +134 -0
  167. package/dist/stamp-utils.d.ts +100 -0
  168. package/dist/stamp-utils.js +229 -0
  169. package/dist/state-machine.d.ts +26 -0
  170. package/dist/state-machine.js +83 -0
  171. package/dist/system-map-validator.d.ts +80 -0
  172. package/dist/system-map-validator.js +272 -0
  173. package/dist/telemetry.d.ts +80 -0
  174. package/dist/telemetry.js +213 -0
  175. package/dist/token-counter.d.ts +51 -0
  176. package/dist/token-counter.js +145 -0
  177. package/dist/usecases/get-dashboard-data.usecase.d.ts +52 -0
  178. package/dist/usecases/get-dashboard-data.usecase.js +61 -0
  179. package/dist/usecases/get-suggestions.usecase.d.ts +100 -0
  180. package/dist/usecases/get-suggestions.usecase.js +153 -0
  181. package/dist/user-normalizer.d.ts +41 -0
  182. package/dist/user-normalizer.js +141 -0
  183. package/dist/validators/phi-constants.d.ts +97 -0
  184. package/dist/validators/phi-constants.js +152 -0
  185. package/dist/validators/phi-scanner.d.ts +58 -0
  186. package/dist/validators/phi-scanner.js +215 -0
  187. package/dist/worktree-ownership.d.ts +50 -0
  188. package/dist/worktree-ownership.js +74 -0
  189. package/dist/worktree-scanner.d.ts +103 -0
  190. package/dist/worktree-scanner.js +168 -0
  191. package/dist/worktree-symlink.d.ts +99 -0
  192. package/dist/worktree-symlink.js +359 -0
  193. package/dist/wu-backlog-updater.d.ts +17 -0
  194. package/dist/wu-backlog-updater.js +37 -0
  195. package/dist/wu-checkpoint.d.ts +124 -0
  196. package/dist/wu-checkpoint.js +233 -0
  197. package/dist/wu-claim-helpers.d.ts +26 -0
  198. package/dist/wu-claim-helpers.js +63 -0
  199. package/dist/wu-claim-resume.d.ts +106 -0
  200. package/dist/wu-claim-resume.js +276 -0
  201. package/dist/wu-consistency-checker.d.ts +95 -0
  202. package/dist/wu-consistency-checker.js +567 -0
  203. package/dist/wu-constants.d.ts +1275 -0
  204. package/dist/wu-constants.js +1382 -0
  205. package/dist/wu-create-validators.d.ts +42 -0
  206. package/dist/wu-create-validators.js +93 -0
  207. package/dist/wu-done-branch-only.d.ts +63 -0
  208. package/dist/wu-done-branch-only.js +191 -0
  209. package/dist/wu-done-messages.d.ts +119 -0
  210. package/dist/wu-done-messages.js +185 -0
  211. package/dist/wu-done-pr.d.ts +72 -0
  212. package/dist/wu-done-pr.js +174 -0
  213. package/dist/wu-done-retry-helpers.d.ts +85 -0
  214. package/dist/wu-done-retry-helpers.js +172 -0
  215. package/dist/wu-done-ui.d.ts +37 -0
  216. package/dist/wu-done-ui.js +69 -0
  217. package/dist/wu-done-validators.d.ts +411 -0
  218. package/dist/wu-done-validators.js +1229 -0
  219. package/dist/wu-done-worktree.d.ts +182 -0
  220. package/dist/wu-done-worktree.js +1097 -0
  221. package/dist/wu-helpers.d.ts +128 -0
  222. package/dist/wu-helpers.js +248 -0
  223. package/dist/wu-lint.d.ts +70 -0
  224. package/dist/wu-lint.js +234 -0
  225. package/dist/wu-paths.d.ts +171 -0
  226. package/dist/wu-paths.js +178 -0
  227. package/dist/wu-preflight-validators.d.ts +86 -0
  228. package/dist/wu-preflight-validators.js +251 -0
  229. package/dist/wu-recovery.d.ts +138 -0
  230. package/dist/wu-recovery.js +341 -0
  231. package/dist/wu-repair-core.d.ts +131 -0
  232. package/dist/wu-repair-core.js +669 -0
  233. package/dist/wu-schema-normalization.d.ts +17 -0
  234. package/dist/wu-schema-normalization.js +82 -0
  235. package/dist/wu-schema.d.ts +793 -0
  236. package/dist/wu-schema.js +881 -0
  237. package/dist/wu-spawn-helpers.d.ts +121 -0
  238. package/dist/wu-spawn-helpers.js +271 -0
  239. package/dist/wu-spawn.d.ts +158 -0
  240. package/dist/wu-spawn.js +1306 -0
  241. package/dist/wu-state-schema.d.ts +213 -0
  242. package/dist/wu-state-schema.js +156 -0
  243. package/dist/wu-state-store.d.ts +264 -0
  244. package/dist/wu-state-store.js +691 -0
  245. package/dist/wu-status-transition.d.ts +63 -0
  246. package/dist/wu-status-transition.js +382 -0
  247. package/dist/wu-status-updater.d.ts +25 -0
  248. package/dist/wu-status-updater.js +116 -0
  249. package/dist/wu-transaction-collectors.d.ts +116 -0
  250. package/dist/wu-transaction-collectors.js +272 -0
  251. package/dist/wu-transaction.d.ts +170 -0
  252. package/dist/wu-transaction.js +273 -0
  253. package/dist/wu-validation-constants.d.ts +60 -0
  254. package/dist/wu-validation-constants.js +66 -0
  255. package/dist/wu-validation.d.ts +118 -0
  256. package/dist/wu-validation.js +243 -0
  257. package/dist/wu-validator.d.ts +62 -0
  258. package/dist/wu-validator.js +325 -0
  259. package/dist/wu-yaml-fixer.d.ts +97 -0
  260. package/dist/wu-yaml-fixer.js +264 -0
  261. package/dist/wu-yaml.d.ts +86 -0
  262. package/dist/wu-yaml.js +222 -0
  263. package/package.json +114 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * @file tool-runner.mjs
3
+ * @description Unified tool execution layer integrating all core components (WU-1398)
4
+ *
5
+ * This module provides a higher-order function pattern for executing tools with:
6
+ * - Input validation via Zod schemas (tool.schemas.ts)
7
+ * - Worktree context detection (worktree-guard.mjs)
8
+ * - Scope validation against code_paths (scope-checker.mjs)
9
+ * - Audit logging for telemetry (.beacon/telemetry/tools.ndjson)
10
+ * - Consistent error handling with agent-friendly messages
11
+ *
12
+ * Usage:
13
+ * import { runTool, ToolRunner, createToolConfig } from './tool-runner.js';
14
+ *
15
+ * // Direct invocation
16
+ * const result = await runTool(toolDefinition, { arg: 'value' });
17
+ *
18
+ * // Registry-based invocation
19
+ * const runner = new ToolRunner();
20
+ * runner.register(myTool);
21
+ * const result = await runner.run('tool:name', { arg: 'value' });
22
+ *
23
+ * @see tools/lib/core/tool.schemas.ts - Zod schemas for tool I/O
24
+ * @see tools/lib/core/worktree-guard.mjs - WU context detection
25
+ * @see tools/lib/core/scope-checker.mjs - Code path validation
26
+ */
27
+ import { TOOL_ERROR_CODES, PERMISSION_LEVELS, TOOL_STATUS, DEFAULT_TOOL_TIMEOUT_MS, } from './tool.constants.js';
28
+ import { validateToolInput, createErrorOutput } from './tool.schemas.js';
29
+ import { getWUContext, assertWorktreeRequired } from './worktree-guard.js';
30
+ import { getActiveScope, isPathInScope } from './scope-checker.js';
31
+ /**
32
+ * Default configuration values for tool runner
33
+ */
34
+ export const RUNNER_DEFAULTS = {
35
+ /** Default timeout for tool execution in milliseconds */
36
+ TIMEOUT_MS: DEFAULT_TOOL_TIMEOUT_MS,
37
+ /** Enable audit logging by default */
38
+ ENABLE_AUDIT_LOG: true,
39
+ /** Default: read tools don't require worktree */
40
+ REQUIRES_WORKTREE: false,
41
+ /** Default: read tools don't require scope check */
42
+ REQUIRES_SCOPE: false,
43
+ };
44
+ /**
45
+ * Create tool configuration with sensible defaults
46
+ *
47
+ * @param {object} tool - Tool definition
48
+ * @param {object} options - Configuration overrides
49
+ * @returns {object} Merged configuration
50
+ */
51
+ export function createToolConfig(tool, options = {}) {
52
+ const isWriteOperation = tool.metadata.permission === PERMISSION_LEVELS.WRITE ||
53
+ tool.metadata.permission === PERMISSION_LEVELS.ADMIN;
54
+ return {
55
+ requiresWorktree: options.requiresWorktree ?? isWriteOperation,
56
+ requiresScope: options.requiresScope ?? isWriteOperation,
57
+ enableAuditLog: options.enableAuditLog ?? RUNNER_DEFAULTS.ENABLE_AUDIT_LOG,
58
+ timeoutMs: options.timeoutMs ?? RUNNER_DEFAULTS.TIMEOUT_MS,
59
+ };
60
+ }
61
+ /**
62
+ * Extract file path from tool input if present
63
+ *
64
+ * @param {object} input - Tool input
65
+ * @returns {string|null} File path or null
66
+ */
67
+ function extractFilePath(input) {
68
+ // Common field names for file paths
69
+ const pathFields = ['path', 'filePath', 'file', 'targetPath'];
70
+ for (const field of pathFields) {
71
+ if (typeof input[field] === 'string') {
72
+ return input[field];
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ /**
78
+ * Create default dependencies using real implementations
79
+ *
80
+ * @returns {object} Default dependency implementations
81
+ */
82
+ function createDefaultDependencies() {
83
+ return {
84
+ getWUContext,
85
+ getActiveScope,
86
+ isPathInScope,
87
+ assertWorktreeRequired,
88
+ logAudit: createAuditLogger(),
89
+ };
90
+ }
91
+ /**
92
+ * Create audit logger function
93
+ *
94
+ * @returns {Function} Audit logging function
95
+ */
96
+ function createAuditLogger() {
97
+ return (entry) => {
98
+ // Write to NDJSON telemetry file
99
+ // Implementation deferred - currently no-op for testing
100
+ // Will integrate with .beacon/telemetry/tools.ndjson in future WU
101
+ void entry;
102
+ };
103
+ }
104
+ /**
105
+ * Generate helpful suggestions for validation errors
106
+ *
107
+ * @param {object} tool - Tool definition
108
+ * @param {object} zodError - Zod validation error
109
+ * @returns {string[]} Array of suggestions
110
+ */
111
+ function generateValidationHints(tool, zodError) {
112
+ const hints = [];
113
+ // Add field-specific hints
114
+ for (const issue of zodError.issues) {
115
+ const path = issue.path.join('.');
116
+ hints.push(`Field '${path}': ${issue.message}`);
117
+ }
118
+ // Add general help hint
119
+ hints.push(`Run with --help to see valid arguments for ${tool.metadata.name}`);
120
+ return hints;
121
+ }
122
+ /**
123
+ * Run a tool with full validation and guards
124
+ *
125
+ * @param {object} tool - Tool definition (metadata, inputSchema, execute)
126
+ * @param {object} input - Tool input arguments
127
+ * @param {object} options - Execution options
128
+ * @param {object} options.dependencies - Injected dependencies (for testing)
129
+ * @param {object} options.config - Configuration overrides
130
+ * @param {object} options.context - Execution context (sessionId, etc.)
131
+ * @returns {Promise<object>} Tool output (success/failure with data/error)
132
+ */
133
+ export async function runTool(tool, input, options = {}) {
134
+ const startTime = Date.now();
135
+ const startedAt = new Date().toISOString();
136
+ // Merge dependencies with defaults
137
+ const deps = {
138
+ ...createDefaultDependencies(),
139
+ ...options.dependencies,
140
+ };
141
+ // Create configuration
142
+ const config = createToolConfig(tool, options.config);
143
+ // Get WU context for audit logging
144
+ let wuContext = null;
145
+ try {
146
+ wuContext = await deps.getWUContext();
147
+ }
148
+ catch {
149
+ // Context retrieval failure is non-fatal
150
+ wuContext = null;
151
+ }
152
+ // Build execution metadata
153
+ const metadata = {
154
+ startedAt,
155
+ durationMs: 0,
156
+ };
157
+ // Helper to create audit log entry
158
+ const createAuditEntry = (status, output, error) => ({
159
+ tool: tool.metadata.name,
160
+ status,
161
+ startedAt,
162
+ completedAt: new Date().toISOString(),
163
+ durationMs: Date.now() - startTime,
164
+ input,
165
+ output,
166
+ error,
167
+ context: wuContext
168
+ ? {
169
+ wuId: wuContext.wuId,
170
+ lane: wuContext.lane,
171
+ worktreePath: wuContext.worktreePath,
172
+ }
173
+ : {},
174
+ });
175
+ try {
176
+ // Step 1: Validate input schema
177
+ const validation = validateToolInput(input, tool.inputSchema);
178
+ if (!validation.success) {
179
+ const validationError = validation;
180
+ const errorOutput = createErrorOutput({
181
+ code: TOOL_ERROR_CODES.SCHEMA_VALIDATION_FAILED,
182
+ message: `Input validation failed for ${tool.metadata.name}`,
183
+ details: { issues: validationError.error.issues },
184
+ tryNext: generateValidationHints(tool, validationError.error),
185
+ }, metadata);
186
+ if (config.enableAuditLog) {
187
+ deps.logAudit(createAuditEntry(TOOL_STATUS.FAILED, null, errorOutput.error));
188
+ }
189
+ return errorOutput;
190
+ }
191
+ // Narrow validation to success case
192
+ const validatedInput = validation;
193
+ // Step 2: Check worktree requirement
194
+ if (config.requiresWorktree) {
195
+ try {
196
+ await deps.assertWorktreeRequired({
197
+ operation: tool.metadata.name,
198
+ });
199
+ }
200
+ catch (err) {
201
+ const errMessage = err instanceof Error ? err.message : String(err);
202
+ const errorOutput = createErrorOutput({
203
+ code: TOOL_ERROR_CODES.PERMISSION_DENIED,
204
+ message: errMessage,
205
+ tryNext: [
206
+ 'Claim a WU first: pnpm wu:claim --id WU-XXX --lane "Your Lane"',
207
+ 'Then change to the worktree directory',
208
+ ],
209
+ }, metadata);
210
+ if (config.enableAuditLog) {
211
+ deps.logAudit(createAuditEntry(TOOL_STATUS.FAILED, null, errorOutput.error));
212
+ }
213
+ return errorOutput;
214
+ }
215
+ }
216
+ // Step 3: Check scope for write operations with file paths
217
+ if (config.requiresScope) {
218
+ const filePath = extractFilePath(validatedInput.data);
219
+ if (filePath) {
220
+ const scope = await deps.getActiveScope();
221
+ // If we have a scope, validate the path
222
+ if (scope &&
223
+ !deps.isPathInScope(filePath, scope)) {
224
+ const errorOutput = createErrorOutput({
225
+ code: TOOL_ERROR_CODES.PERMISSION_DENIED,
226
+ message: `Path '${filePath}' is outside WU scope for ${scope.wuId}`,
227
+ details: {
228
+ path: filePath,
229
+ allowedPaths: scope.code_paths,
230
+ },
231
+ tryNext: [
232
+ `Only modify files matching: ${scope.code_paths.join(', ')}`,
233
+ 'Update WU code_paths if this file should be in scope',
234
+ ],
235
+ }, metadata);
236
+ if (config.enableAuditLog) {
237
+ deps.logAudit(createAuditEntry(TOOL_STATUS.FAILED, null, errorOutput.error));
238
+ }
239
+ return errorOutput;
240
+ }
241
+ }
242
+ }
243
+ // Step 4: Execute the tool
244
+ const result = (await tool.execute(validatedInput.data, options.context));
245
+ // Step 5: Validate output if schema defined
246
+ if (tool.outputSchema && result.success && result.data) {
247
+ const outputValidation = validateToolInput(result.data, tool.outputSchema);
248
+ if (!outputValidation.success) {
249
+ const outputValidationError = outputValidation;
250
+ const errorOutput = createErrorOutput({
251
+ code: TOOL_ERROR_CODES.INVALID_OUTPUT,
252
+ message: `Tool ${tool.metadata.name} produced invalid output`,
253
+ details: { issues: outputValidationError.error.issues },
254
+ }, { ...metadata, durationMs: Date.now() - startTime });
255
+ if (config.enableAuditLog) {
256
+ deps.logAudit(createAuditEntry(TOOL_STATUS.FAILED, null, errorOutput.error));
257
+ }
258
+ return errorOutput;
259
+ }
260
+ }
261
+ // Add metadata to result
262
+ const resultMetadata = result.metadata || {};
263
+ const finalResult = {
264
+ ...result,
265
+ metadata: {
266
+ ...resultMetadata,
267
+ ...metadata,
268
+ durationMs: Date.now() - startTime,
269
+ },
270
+ };
271
+ // Log successful execution
272
+ if (config.enableAuditLog) {
273
+ deps.logAudit(createAuditEntry(TOOL_STATUS.SUCCESS, finalResult, null));
274
+ }
275
+ return finalResult;
276
+ }
277
+ catch (err) {
278
+ // Handle unexpected execution errors
279
+ const errorMessage = err instanceof Error ? err.message : String(err);
280
+ const errorStack = err instanceof Error ? err.stack : undefined;
281
+ const errorOutput = createErrorOutput({
282
+ code: TOOL_ERROR_CODES.EXECUTION_FAILED,
283
+ message: errorMessage,
284
+ stack: errorStack,
285
+ tryNext: ['Check tool input and try again', 'Report issue if problem persists'],
286
+ }, { ...metadata, durationMs: Date.now() - startTime });
287
+ if (config.enableAuditLog) {
288
+ deps.logAudit(createAuditEntry(TOOL_STATUS.FAILED, null, errorOutput.error));
289
+ }
290
+ return errorOutput;
291
+ }
292
+ }
293
+ /**
294
+ * Tool registry and runner class
295
+ *
296
+ * Provides a registry for tool definitions and a unified execution interface.
297
+ */
298
+ export class ToolRunner {
299
+ #tools = new Map();
300
+ #config;
301
+ #dependencies;
302
+ /**
303
+ * Create a new ToolRunner instance
304
+ *
305
+ * @param {object} options - Runner options
306
+ * @param {boolean} options.enableAuditLog - Enable audit logging
307
+ * @param {number} options.timeoutMs - Default timeout
308
+ * @param {object} options.dependencies - Injected dependencies
309
+ */
310
+ constructor(options = {}) {
311
+ this.#config = {
312
+ enableAuditLog: options.enableAuditLog ?? RUNNER_DEFAULTS.ENABLE_AUDIT_LOG,
313
+ timeoutMs: options.timeoutMs ?? RUNNER_DEFAULTS.TIMEOUT_MS,
314
+ };
315
+ this.#dependencies = options.dependencies || createDefaultDependencies();
316
+ }
317
+ /**
318
+ * Register a tool definition
319
+ *
320
+ * @param {object} tool - Tool definition
321
+ * @throws {Error} If tool with same name already registered
322
+ */
323
+ register(tool) {
324
+ const name = tool.metadata.name;
325
+ if (this.#tools.has(name)) {
326
+ throw new Error(`Tool '${name}' is already registered`);
327
+ }
328
+ this.#tools.set(name, tool);
329
+ }
330
+ /**
331
+ * Check if a tool is registered
332
+ *
333
+ * @param {string} name - Tool name
334
+ * @returns {boolean} True if tool exists
335
+ */
336
+ hasTool(name) {
337
+ return this.#tools.has(name);
338
+ }
339
+ /**
340
+ * Run a registered tool by name
341
+ *
342
+ * @param {string} name - Tool name
343
+ * @param {object} input - Tool input
344
+ * @param {object} options - Execution options
345
+ * @returns {Promise<object>} Tool output
346
+ */
347
+ async run(name, input, options = {}) {
348
+ const tool = this.#tools.get(name);
349
+ if (!tool) {
350
+ return createErrorOutput({
351
+ code: TOOL_ERROR_CODES.TOOL_NOT_FOUND,
352
+ message: `Tool '${name}' not found in registry`,
353
+ tryNext: ['Check tool name spelling', 'Use runner.listTools() to see available tools'],
354
+ });
355
+ }
356
+ return runTool(tool, input, {
357
+ ...options,
358
+ dependencies: this.#dependencies,
359
+ config: { ...this.#config, ...options.config },
360
+ });
361
+ }
362
+ /**
363
+ * Get runner configuration
364
+ *
365
+ * @returns {object} Current configuration
366
+ */
367
+ getConfig() {
368
+ return { ...this.#config };
369
+ }
370
+ /**
371
+ * List all registered tools
372
+ *
373
+ * @param {object} options - Filter options
374
+ * @param {string} options.domain - Filter by domain
375
+ * @returns {object[]} Array of tool metadata
376
+ */
377
+ listTools(options = {}) {
378
+ const tools = [];
379
+ for (const tool of this.#tools.values()) {
380
+ if (options.domain && tool.metadata.domain !== options.domain) {
381
+ continue;
382
+ }
383
+ tools.push({
384
+ name: tool.metadata.name,
385
+ description: tool.metadata.description,
386
+ domain: tool.metadata.domain,
387
+ permission: tool.metadata.permission,
388
+ version: tool.metadata.version,
389
+ });
390
+ }
391
+ return tools;
392
+ }
393
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @file tool.constants.ts
3
+ * @description Shared constants for tool abstraction layer (WU-1394)
4
+ *
5
+ * Provides domain enums, error codes, and permission levels for unified
6
+ * tool system. Used by tool registry, audit logging, and provider adapters.
7
+ */
8
+ /**
9
+ * Tool domain categories for classification and routing
10
+ */
11
+ export declare const TOOL_DOMAINS: {
12
+ /** Work Unit lifecycle operations (claim, done, block, etc.) */
13
+ readonly WU: "wu";
14
+ /** Git operations (commit, push, merge, etc.) */
15
+ readonly GIT: "git";
16
+ /** File system operations (read, write, delete, etc.) */
17
+ readonly FILE: "file";
18
+ /** Code exploration and search (grep, glob, find, etc.) */
19
+ readonly EXPLORE: "explore";
20
+ /** Testing operations (run tests, coverage, etc.) */
21
+ readonly TEST: "test";
22
+ /** Database operations (migrations, queries, etc.) */
23
+ readonly DB: "db";
24
+ /** Security operations (auth, permissions, audit, etc.) */
25
+ readonly SECURITY: "security";
26
+ /** Initiative management operations */
27
+ readonly INITIATIVE: "initiative";
28
+ /** Metrics and reporting operations */
29
+ readonly METRICS: "metrics";
30
+ /** Orchestration operations (status, suggest, etc.) */
31
+ readonly ORCHESTRATION: "orchestration";
32
+ /** Documentation operations (linting, validation, etc.) */
33
+ readonly DOCS: "docs";
34
+ /** General utility operations */
35
+ readonly UTIL: "util";
36
+ };
37
+ export type ToolDomain = (typeof TOOL_DOMAINS)[keyof typeof TOOL_DOMAINS];
38
+ /**
39
+ * Permission levels for access control
40
+ */
41
+ export declare const PERMISSION_LEVELS: {
42
+ /** Read-only operations (no state changes) */
43
+ readonly READ: "read";
44
+ /** Write operations (modifies state) */
45
+ readonly WRITE: "write";
46
+ /** Administrative operations (destructive, requires elevated access) */
47
+ readonly ADMIN: "admin";
48
+ };
49
+ export type PermissionLevel = (typeof PERMISSION_LEVELS)[keyof typeof PERMISSION_LEVELS];
50
+ /**
51
+ * Tool error codes (extends existing ErrorCodes from error-handler.mjs)
52
+ */
53
+ export declare const TOOL_ERROR_CODES: {
54
+ /** Tool not found in registry */
55
+ readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND";
56
+ /** Invalid tool input schema */
57
+ readonly INVALID_INPUT: "INVALID_INPUT";
58
+ /** Invalid tool output schema */
59
+ readonly INVALID_OUTPUT: "INVALID_OUTPUT";
60
+ /** Tool execution failed */
61
+ readonly EXECUTION_FAILED: "EXECUTION_FAILED";
62
+ /** Permission denied for tool operation */
63
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
64
+ /** Tool timeout */
65
+ readonly TIMEOUT: "TIMEOUT";
66
+ /** Tool not available in current context */
67
+ readonly NOT_AVAILABLE: "NOT_AVAILABLE";
68
+ /** Schema validation failed */
69
+ readonly SCHEMA_VALIDATION_FAILED: "SCHEMA_VALIDATION_FAILED";
70
+ /** Missing required argument */
71
+ readonly MISSING_ARGUMENT: "MISSING_ARGUMENT";
72
+ /** Invalid argument type */
73
+ readonly INVALID_ARGUMENT_TYPE: "INVALID_ARGUMENT_TYPE";
74
+ /** Tool already registered */
75
+ readonly DUPLICATE_TOOL: "DUPLICATE_TOOL";
76
+ /** Provider adapter error */
77
+ readonly PROVIDER_ERROR: "PROVIDER_ERROR";
78
+ };
79
+ export type ToolErrorCode = (typeof TOOL_ERROR_CODES)[keyof typeof TOOL_ERROR_CODES];
80
+ /**
81
+ * Tool execution status values
82
+ */
83
+ export declare const TOOL_STATUS: {
84
+ /** Tool execution pending */
85
+ readonly PENDING: "pending";
86
+ /** Tool currently executing */
87
+ readonly RUNNING: "running";
88
+ /** Tool execution completed successfully */
89
+ readonly SUCCESS: "success";
90
+ /** Tool execution failed */
91
+ readonly FAILED: "failed";
92
+ /** Tool execution timed out */
93
+ readonly TIMEOUT: "timeout";
94
+ /** Tool execution cancelled */
95
+ readonly CANCELLED: "cancelled";
96
+ };
97
+ export type ToolStatus = (typeof TOOL_STATUS)[keyof typeof TOOL_STATUS];
98
+ /**
99
+ * Default timeout for tool execution (milliseconds)
100
+ */
101
+ export declare const DEFAULT_TOOL_TIMEOUT_MS = 30000;
102
+ /**
103
+ * Maximum number of retries for transient failures
104
+ */
105
+ export declare const MAX_TOOL_RETRIES = 3;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @file tool.constants.ts
3
+ * @description Shared constants for tool abstraction layer (WU-1394)
4
+ *
5
+ * Provides domain enums, error codes, and permission levels for unified
6
+ * tool system. Used by tool registry, audit logging, and provider adapters.
7
+ */
8
+ /**
9
+ * Tool domain categories for classification and routing
10
+ */
11
+ export const TOOL_DOMAINS = {
12
+ /** Work Unit lifecycle operations (claim, done, block, etc.) */
13
+ WU: 'wu',
14
+ /** Git operations (commit, push, merge, etc.) */
15
+ GIT: 'git',
16
+ /** File system operations (read, write, delete, etc.) */
17
+ FILE: 'file',
18
+ /** Code exploration and search (grep, glob, find, etc.) */
19
+ EXPLORE: 'explore',
20
+ /** Testing operations (run tests, coverage, etc.) */
21
+ TEST: 'test',
22
+ /** Database operations (migrations, queries, etc.) */
23
+ DB: 'db',
24
+ /** Security operations (auth, permissions, audit, etc.) */
25
+ SECURITY: 'security',
26
+ /** Initiative management operations */
27
+ INITIATIVE: 'initiative',
28
+ /** Metrics and reporting operations */
29
+ METRICS: 'metrics',
30
+ /** Orchestration operations (status, suggest, etc.) */
31
+ ORCHESTRATION: 'orchestration',
32
+ /** Documentation operations (linting, validation, etc.) */
33
+ DOCS: 'docs',
34
+ /** General utility operations */
35
+ UTIL: 'util',
36
+ };
37
+ /**
38
+ * Permission levels for access control
39
+ */
40
+ export const PERMISSION_LEVELS = {
41
+ /** Read-only operations (no state changes) */
42
+ READ: 'read',
43
+ /** Write operations (modifies state) */
44
+ WRITE: 'write',
45
+ /** Administrative operations (destructive, requires elevated access) */
46
+ ADMIN: 'admin',
47
+ };
48
+ /**
49
+ * Tool error codes (extends existing ErrorCodes from error-handler.mjs)
50
+ */
51
+ export const TOOL_ERROR_CODES = {
52
+ /** Tool not found in registry */
53
+ TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',
54
+ /** Invalid tool input schema */
55
+ INVALID_INPUT: 'INVALID_INPUT',
56
+ /** Invalid tool output schema */
57
+ INVALID_OUTPUT: 'INVALID_OUTPUT',
58
+ /** Tool execution failed */
59
+ EXECUTION_FAILED: 'EXECUTION_FAILED',
60
+ /** Permission denied for tool operation */
61
+ PERMISSION_DENIED: 'PERMISSION_DENIED',
62
+ /** Tool timeout */
63
+ TIMEOUT: 'TIMEOUT',
64
+ /** Tool not available in current context */
65
+ NOT_AVAILABLE: 'NOT_AVAILABLE',
66
+ /** Schema validation failed */
67
+ SCHEMA_VALIDATION_FAILED: 'SCHEMA_VALIDATION_FAILED',
68
+ /** Missing required argument */
69
+ MISSING_ARGUMENT: 'MISSING_ARGUMENT',
70
+ /** Invalid argument type */
71
+ INVALID_ARGUMENT_TYPE: 'INVALID_ARGUMENT_TYPE',
72
+ /** Tool already registered */
73
+ DUPLICATE_TOOL: 'DUPLICATE_TOOL',
74
+ /** Provider adapter error */
75
+ PROVIDER_ERROR: 'PROVIDER_ERROR',
76
+ };
77
+ /**
78
+ * Tool execution status values
79
+ */
80
+ export const TOOL_STATUS = {
81
+ /** Tool execution pending */
82
+ PENDING: 'pending',
83
+ /** Tool currently executing */
84
+ RUNNING: 'running',
85
+ /** Tool execution completed successfully */
86
+ SUCCESS: 'success',
87
+ /** Tool execution failed */
88
+ FAILED: 'failed',
89
+ /** Tool execution timed out */
90
+ TIMEOUT: 'timeout',
91
+ /** Tool execution cancelled */
92
+ CANCELLED: 'cancelled',
93
+ };
94
+ /**
95
+ * Default timeout for tool execution (milliseconds)
96
+ */
97
+ export const DEFAULT_TOOL_TIMEOUT_MS = 30000; // 30 seconds
98
+ /**
99
+ * Maximum number of retries for transient failures
100
+ */
101
+ export const MAX_TOOL_RETRIES = 3;