forked from claude-code-best/claude-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwiring.ts
More file actions
65 lines (62 loc) · 2.36 KB
/
Copy pathwiring.ts
File metadata and controls
65 lines (62 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import {
createWorkflowTool,
workflowInputSchema,
WORKFLOW_TOOL_NAME,
type WorkflowToolDescriptor,
} from '@claude-code-best/workflow-engine'
import { buildTool, type Tool } from '../Tool.js'
import { getWorkflowService } from './service.js'
/**
* Adapts the engine's self-contained descriptor into a buildTool-compatible Tool.
* The descriptor routes through the service singleton (sharing ports/registry/store).
*
* ports resolution is deferred to the first real method call (lazy): tools.ts calls
* createWorkflowToolCore() during module-load (feature-gated), and resolving ports
* immediately would trigger service instantiation, which in turn calls module-level
* side effects like getProjectRoot — yielding wrong paths before bootstrap completes.
* The Tool object itself is a singleton via createWorkflowToolCore's cached (PermissionRequest
* matches by reference), and the ports singleton is guaranteed by getWorkflowService.
*/
function buildWorkflowTool(): Tool {
let cachedDescriptor: WorkflowToolDescriptor | null = null
const descriptor = (): WorkflowToolDescriptor => {
if (!cachedDescriptor) {
const { ports } = getWorkflowService()
cachedDescriptor = createWorkflowTool(ports)
}
return cachedDescriptor
}
return buildTool({
name: WORKFLOW_TOOL_NAME,
maxResultSizeChars: 50_000,
inputSchema: workflowInputSchema,
isEnabled: () => descriptor().isEnabled(),
isReadOnly: input => descriptor().isReadOnly(input),
isConcurrencySafe: () => true,
async description() {
return descriptor().description()
},
async prompt() {
return descriptor().prompt()
},
async call(input, context, canUseTool, parentMessage, onProgress) {
const result = await descriptor().call(
input,
context,
canUseTool,
parentMessage,
onProgress,
)
return { data: result.data }
},
renderToolUseMessage: input => descriptor().renderToolUseMessage(input),
mapToolResultToToolResultBlockParam: (data, toolUseId) =>
descriptor().mapToolResultToToolResultBlockParam(data, toolUseId),
})
}
// Singleton: tools.ts registration and PermissionRequest must reference the same instance (switch matches by reference).
let cached: Tool | null = null
export function createWorkflowToolCore(): Tool {
if (!cached) cached = buildWorkflowTool()
return cached
}