mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 22:05:50 +00:00
围绕 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>
65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
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 解析延迟到首次实际方法调用(lazy):tools.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
|
||
}
|