Files
claude-code/src/workflow/wiring.ts
claude-code-best 54d2bf6f12 feat(workflow): 复刻 ultracode 手册并修复 worktree/inline/opt-in 三处缺口
围绕 ultracode skill 审查 agent 系统一致性后:
- ultracode.ts: 用系统提示版完整 Workflow 编排手册替换中文精简版
- HIGH#1 isolation:'worktree': claudeCodeBackend.run() 用 createAgentWorktree +
  runWithCwdOverride 包裹 runAgent + finally 清理实现真正的 cwd 隔离;slug 用
  sha256(runId:agentId) 派生以匹配 cleanupStaleAgentWorktrees 清理正则
  (修 runId 为 w+base36 非 UUID 导致的泄漏盲区);worktree.ts 注释同步修正
- HIGH#2 inline 持久化: 新增 persistInlineScript,WorkflowTool + service 两条
  inline 路径对称持久化到 .claude/workflow-runs/<runId>/script.js,返回可复用
  scriptPath(闭环 inline→编辑→scriptPath 重提迭代循环)
- HIGH#3 opt-in 分工: ultracode/WorkflowTool/effort 注明 session reminder 由
  harness 注入,repo 内无 ultracode 信号,保持 feature('WORKFLOW_SCRIPTS') +
  isEnabled 两层 gate,不自造注入
- 测试: 新增 persistInline.test.ts;扩展 claudeCodeBackend(isolation 4 用例)/
  WorkflowTool(inline)/service(scriptPath)/ultracode(harness)

含配套 workflow engine/panel 完善与 run-state-persistence design doc。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 23:04:33 +08:00

65 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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'
/**
* 把引擎自包含描述符适配为 buildTool 兼容的 Tool。
* 描述符统一走 service 单例(共享 ports/registry/store
*
* ports 解析延迟到首次实际方法调用lazytools.ts 在模块加载阶段feature-gated
* 调用 createWorkflowToolCore(),若此时立即解析 ports 会触发 service 实例化,
* 进而调用 getProjectRoot 等模块级副作用——这在 bootstrap 完成前可能拿到错误路径。
* Tool 对象本身的单例由 createWorkflowToolCore 的 cached 保证PermissionRequest
* 按引用匹配ports 单例由 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),
})
}
// 单例tools.ts 注册与 PermissionRequest 引用需为同一实例switch 按引用匹配)。
let cached: Tool | null = null
export function createWorkflowToolCore(): Tool {
if (!cached) cached = buildWorkflowTool()
return cached
}