@@ -48,7 +48,7 @@ function mockPorts(
4848 return { ports, events, runStatus }
4949}
5050
51- test ( 'call 返回 launch 消息并在后台完成 ' , async ( ) => {
51+ test ( 'call returns launch message and completes in background ' , async ( ) => {
5252 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
5353 try {
5454 const { ports, runStatus } = mockPorts (
@@ -74,7 +74,7 @@ test('call 返回 launch 消息并在后台完成', async () => {
7474 }
7575} )
7676
77- test ( 'inline script 持久化到 run 目录,返回真实 scriptPath' , async ( ) => {
77+ test ( 'inline script persists to run directory, returns real scriptPath' , async ( ) => {
7878 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
7979 try {
8080 const { ports } = mockPorts (
@@ -102,7 +102,7 @@ test('inline script 持久化到 run 目录,返回真实 scriptPath', async ()
102102 }
103103} )
104104
105- test ( '缺少 script/name/scriptPath → 返回错误(不进后台) ' , async ( ) => {
105+ test ( 'missing script/name/scriptPath → returns error (does not enter background) ' , async ( ) => {
106106 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
107107 try {
108108 const { ports, runStatus } = mockPorts ( dir , new Map ( ) )
@@ -115,7 +115,7 @@ test('缺少 script/name/scriptPath → 返回错误(不进后台)', async (
115115 }
116116} )
117117
118- test ( '脚本语法错 → 返回校验错误(不进后台) ' , async ( ) => {
118+ test ( 'script syntax error → returns validation error (does not enter background) ' , async ( ) => {
119119 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
120120 try {
121121 const { ports, runStatus } = mockPorts ( dir , new Map ( ) )
@@ -126,14 +126,14 @@ test('脚本语法错 → 返回校验错误(不进后台)', async () => {
126126 undefined ,
127127 undefined ,
128128 )
129- expect ( res . data . output ) . toMatch ( / 校 验 失 败 | E r r o r / )
129+ expect ( res . data . output ) . toMatch ( / v a l i d a t i o n f a i l e d | E r r o r / i )
130130 expect ( runStatus . size ) . toBe ( 0 )
131131 } finally {
132132 await rm ( dir , { recursive : true , force : true } )
133133 }
134134} )
135135
136- test ( 'name 解析到 .claude/workflows/<name>.ts' , async ( ) => {
136+ test ( 'name resolves to .claude/workflows/<name>.ts' , async ( ) => {
137137 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
138138 try {
139139 await mkdir ( join ( dir , '.claude' , 'workflows' ) , { recursive : true } )
@@ -180,7 +180,7 @@ test('renderToolUseMessage / mapToolResultToToolResultBlockParam', () => {
180180 expect ( block . content [ 0 ] ! . text ) . toBe ( 'hi' )
181181} )
182182
183- test ( 'scriptPath 解析到文件内容并后台执行 ' , async ( ) => {
183+ test ( 'scriptPath resolves to file content and runs in background ' , async ( ) => {
184184 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
185185 try {
186186 const scriptFile = join ( dir , 'external.ts' )
@@ -209,7 +209,7 @@ test('scriptPath 解析到文件内容并后台执行', async () => {
209209 }
210210} )
211211
212- test ( '脚本运行时失败 → onFinish 路由到 fail' , async ( ) => {
212+ test ( 'script runtime failure → onFinish routes to fail' , async ( ) => {
213213 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
214214 try {
215215 const { ports, runStatus } = mockPorts ( dir , new Map ( ) )
@@ -229,7 +229,7 @@ test('脚本运行时失败 → onFinish 路由到 fail', async () => {
229229 }
230230} )
231231
232- test ( '元数据方法: description/prompt/renderToolUseMessage' , async ( ) => {
232+ test ( 'metadata methods: description/prompt/renderToolUseMessage' , async ( ) => {
233233 const { ports } = mockPorts ( '/tmp' , new Map ( ) )
234234 const tool = createWorkflowTool ( ports )
235235 expect ( tool . isEnabled ( ) ) . toBe ( true )
@@ -242,7 +242,7 @@ test('元数据方法:description/prompt/renderToolUseMessage', async () => {
242242 )
243243} )
244244
245- test ( 'prompt 包含默认并发 3 + AskUserQuestion 指引 ' , async ( ) => {
245+ test ( 'prompt includes default concurrency 3 + AskUserQuestion guidance ' , async ( ) => {
246246 const { ports } = mockPorts ( '/tmp' , new Map ( ) )
247247 const tool = createWorkflowTool ( ports )
248248 const p = await tool . prompt ( )
@@ -251,7 +251,7 @@ test('prompt 包含默认并发 3 + AskUserQuestion 指引', async () => {
251251 expect ( p ) . toMatch ( / A s k U s e r Q u e s t i o n / i)
252252} )
253253
254- test ( 'name 不存在 → 返回错误(不进后台) ' , async ( ) => {
254+ test ( 'name does not exist → returns error (does not enter background) ' , async ( ) => {
255255 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
256256 try {
257257 await mkdir ( join ( dir , '.claude' , 'workflows' ) , { recursive : true } )
@@ -270,7 +270,7 @@ test('name 不存在 → 返回错误(不进后台)', async () => {
270270 }
271271} )
272272
273- test ( 'workflow 被 abort → onFinish 路由 kill' , async ( ) => {
273+ test ( 'workflow aborted → onFinish routes to kill' , async ( ) => {
274274 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
275275 try {
276276 const runStatus = new Map < string , string > ( )
@@ -321,7 +321,7 @@ test('workflow 被 abort → onFinish 路由 kill', async () => {
321321 }
322322} )
323323
324- test ( 'args 为 JSON 字符串化的对象时防御性 parse(向后兼容旧 z.string() 契约) ' , async ( ) => {
324+ test ( 'args defensively parses when a JSON-stringified object (backward compatible with old z.string() contract) ' , async ( ) => {
325325 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
326326 try {
327327 const capturedPrompts : unknown [ ] = [ ]
@@ -360,7 +360,7 @@ test('args 为 JSON 字符串化的对象时防御性 parse(向后兼容旧 z.
360360 await tool . call (
361361 {
362362 script : `return agent(args.commit)` ,
363- // 模拟旧契约下模型发送的字符串化 JSON
363+ // simulate stringified JSON sent by model under old contract
364364 args : '{"commit":"abc123"}' ,
365365 } ,
366366 undefined ,
@@ -370,15 +370,15 @@ test('args 为 JSON 字符串化的对象时防御性 parse(向后兼容旧 z.
370370 await new Promise ( r => {
371371 setTimeout ( r , 50 )
372372 } )
373- // 若 args 未归一化: args.commit === undefined( string 上无 commit 属性)
374- // 若 args 归一化: args.commit === 'abc123'
373+ // if args not normalized: args.commit === undefined ( string has no commit property)
374+ // if args normalized: args.commit === 'abc123'
375375 expect ( capturedPrompts ) . toContain ( 'abc123' )
376376 } finally {
377377 await rm ( dir , { recursive : true , force : true } )
378378 }
379379} )
380380
381- test ( 'args 为非合法 JSON 字符串时保持原值不抛 ' , async ( ) => {
381+ test ( 'args keeps original value for non-legal JSON string without throwing ' , async ( ) => {
382382 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
383383 try {
384384 const capturedPrompts : unknown [ ] = [ ]
@@ -416,7 +416,7 @@ test('args 为非合法 JSON 字符串时保持原值不抛', async () => {
416416 const tool = createWorkflowTool ( ports )
417417 await tool . call (
418418 {
419- // 脚本把 args 当字符串用: agent(args) → agent('hello')
419+ // script uses args as a string: agent(args) → agent('hello')
420420 script : `return agent(args)` ,
421421 args : 'hello' ,
422422 } ,
@@ -427,22 +427,22 @@ test('args 为非合法 JSON 字符串时保持原值不抛', async () => {
427427 await new Promise ( r => {
428428 setTimeout ( r , 50 )
429429 } )
430- // 'hello' 不是合法 JSON,应保持为字符串
430+ // 'hello' is not valid JSON, should be kept as a string
431431 expect ( capturedPrompts ) . toContain ( 'hello' )
432432 } finally {
433433 await rm ( dir , { recursive : true , force : true } )
434434 }
435435} )
436436
437- test ( 'scriptPath 越界(resolve 后在 cwd 之外)→ 拒绝并报错(防任意文件读) ' , async ( ) => {
437+ test ( 'scriptPath out of bounds (resolved outside cwd) → rejected with error (prevents arbitrary file read) ' , async ( ) => {
438438 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
439439 try {
440440 const subDir = join ( dir , 'sub' )
441441 await mkdir ( subDir , { recursive : true } )
442- // 在 subDir 之外(dir 内)放置一个脚本
442+ // place a script outside subDir (inside dir)
443443 const outsideScript = join ( dir , 'outside.ts' )
444444 await writeFile ( outsideScript , `return agent('x')` )
445- // host.cwd = subDir, scriptPath 是 subDir 外的绝对路径
445+ // host.cwd = subDir, scriptPath is an absolute path outside subDir
446446 const { ports, runStatus } = mockPorts ( subDir , new Map ( ) )
447447 const tool = createWorkflowTool ( ports )
448448 const res = await tool . call (
@@ -452,22 +452,22 @@ test('scriptPath 越界(resolve 后在 cwd 之外)→ 拒绝并报错(防
452452 undefined ,
453453 )
454454 expect ( res . data . output ) . toMatch ( / ^ E r r o r : / )
455- expect ( res . data . output ) . toMatch ( / 越 界 | 外 | o u t s i d e | c o n t a i n / i)
455+ expect ( res . data . output ) . toMatch ( / o u t o f b o u n d s | o u t s i d e | n o t w i t h i n / i)
456456 expect ( runStatus . size ) . toBe ( 0 )
457457 } finally {
458458 await rm ( dir , { recursive : true , force : true } )
459459 }
460460} )
461461
462- test ( 'name 含 ".." 路径段 → 拒绝(防路径遍历逃出 workflowDir) ' , async ( ) => {
462+ test ( 'name contains ".." path segment → rejected (prevents path traversal escaping workflowDir) ' , async ( ) => {
463463 const outer = await mkdtemp ( join ( tmpdir ( ) , 'wf-outer-' ) )
464464 try {
465- // 在 outer 根下放置 evil.ts(在 .claude/workflows 之外)
465+ // place evil.ts at outer root (outside .claude/workflows)
466466 await writeFile ( join ( outer , 'evil.ts' ) , `return agent('x')` )
467467 await mkdir ( join ( outer , '.claude' , 'workflows' ) , { recursive : true } )
468468 const { ports, runStatus } = mockPorts ( outer , new Map ( ) )
469469 const tool = createWorkflowTool ( ports )
470- // name = '../../evil' → join 后逃离 workflows 目录到 outer/evil.ts
470+ // name = '../../evil' → after join escapes the workflows directory to outer/evil.ts
471471 const res = await tool . call (
472472 { name : '../../evil' } ,
473473 undefined ,
@@ -481,7 +481,7 @@ test('name 含 ".." 路径段 → 拒绝(防路径遍历逃出 workflowDir)'
481481 }
482482} )
483483
484- test ( 'name 含路径分隔符或为绝对路径 → 拒绝 ' , async ( ) => {
484+ test ( 'name contains path separators or is absolute → rejected ' , async ( ) => {
485485 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
486486 try {
487487 await mkdir ( join ( dir , '.claude' , 'workflows' ) , { recursive : true } )
@@ -501,7 +501,7 @@ test('name 含路径分隔符或为绝对路径 → 拒绝', async () => {
501501 }
502502} )
503503
504- test ( 'returnValue 为对象 → complete( formatValue 走 JSON 分支) ' , async ( ) => {
504+ test ( 'returnValue is an object → complete ( formatValue takes JSON branch) ' , async ( ) => {
505505 const dir = await mkdtemp ( join ( tmpdir ( ) , 'wf-tool-' ) )
506506 try {
507507 const { ports, runStatus } = mockPorts (
0 commit comments