task-while 0.0.1 → 0.0.2

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.
package/README.md CHANGED
@@ -163,7 +163,7 @@ Batch behavior:
163
163
  - execution state is written beside the YAML file in `state.json`
164
164
  - structured results are written beside the YAML file in `results.json`
165
165
  - result keys are relative to the directory that contains `batch.yaml`
166
- - `--verbose` prints per-file failure reasons to `stderr`
166
+ - `--verbose` streams provider agent events to `stderr` during batch execution
167
167
  - rerunning the command resumes unfinished work and skips files that already have accepted results
168
168
  - when the current `pending` queue is exhausted and `failed` is non-empty, the command persists a recycle transition that moves `failed` back into `pending` for the next round
169
169
  - the command exits only when both `pending` and `failed` are empty
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-while",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "packageManager": "pnpm@10.32.1",
5
5
  "description": "Git-first task orchestrator for task-source workspaces",
6
6
  "author": "Zhang Yu",
@@ -0,0 +1,50 @@
1
+ import type { ClaudeAgentEvent, ClaudeAgentEventHandler } from './claude'
2
+ import type { CodexThreadEvent, CodexThreadEventHandler } from './codex'
3
+
4
+ function writeCodexEvent(event: CodexThreadEvent) {
5
+ const itemType =
6
+ event.type === 'item.completed' ||
7
+ event.type === 'item.started' ||
8
+ event.type === 'item.updated'
9
+ ? event.item.type
10
+ : null
11
+ process.stderr.write(
12
+ `[codex] ${event.type}${itemType ? ` ${itemType}` : ''}\n`,
13
+ )
14
+ if (
15
+ event.type === 'item.completed' &&
16
+ event.item.type === 'agent_message' &&
17
+ event.item.text?.trim()
18
+ ) {
19
+ process.stderr.write(`[codex] message ${event.item.text.trim()}\n`)
20
+ }
21
+ if (event.type === 'error') {
22
+ process.stderr.write(`[codex] error ${event.message}\n`)
23
+ }
24
+ if (event.type === 'turn.failed') {
25
+ process.stderr.write(`[codex] error ${event.error.message}\n`)
26
+ }
27
+ }
28
+
29
+ function writeClaudeEvent(event: ClaudeAgentEvent) {
30
+ const detail = event.type === 'text' ? ` ${event.delta}` : ''
31
+ process.stderr.write(`[claude] ${event.type}${detail}\n`)
32
+ }
33
+
34
+ export function createCodexEventHandler(
35
+ verbose: boolean | undefined,
36
+ ): CodexThreadEventHandler | undefined {
37
+ if (!verbose) {
38
+ return undefined
39
+ }
40
+ return writeCodexEvent
41
+ }
42
+
43
+ export function createClaudeEventHandler(
44
+ verbose: boolean | undefined,
45
+ ): ClaudeAgentEventHandler | undefined {
46
+ if (!verbose) {
47
+ return undefined
48
+ }
49
+ return writeClaudeEvent
50
+ }
@@ -1,5 +1,9 @@
1
1
  import { ClaudeAgentClient } from '../agents/claude'
2
2
  import { CodexAgentClient } from '../agents/codex'
3
+ import {
4
+ createClaudeEventHandler,
5
+ createCodexEventHandler,
6
+ } from '../agents/event-log'
3
7
 
4
8
  import type { WorkflowRoleProviderOptions } from '../agents/provider-options'
5
9
 
@@ -17,6 +21,7 @@ export interface BatchStructuredOutputProvider {
17
21
 
18
22
  export type CreateBatchStructuredOutputProviderInput =
19
23
  WorkflowRoleProviderOptions & {
24
+ verbose?: boolean
20
25
  workspaceRoot: string
21
26
  }
22
27
 
@@ -60,19 +65,23 @@ export function createBatchStructuredOutputProvider(
60
65
  input: CreateBatchStructuredOutputProviderInput,
61
66
  ): BatchStructuredOutputProvider {
62
67
  if (input.provider === 'codex') {
68
+ const onEvent = createCodexEventHandler(input.verbose)
63
69
  return new CodexBatchStructuredOutputProvider(
64
70
  new CodexAgentClient({
65
71
  ...(input.effort ? { effort: input.effort } : {}),
66
72
  ...(input.model ? { model: input.model } : {}),
73
+ ...(onEvent ? { onEvent } : {}),
67
74
  workspaceRoot: input.workspaceRoot,
68
75
  }),
69
76
  )
70
77
  }
71
78
 
79
+ const onEvent = createClaudeEventHandler(input.verbose)
72
80
  return new ClaudeBatchStructuredOutputProvider(
73
81
  new ClaudeAgentClient({
74
82
  ...(input.effort ? { effort: input.effort } : {}),
75
83
  ...(input.model ? { model: input.model } : {}),
84
+ ...(onEvent ? { onEvent } : {}),
76
85
  workspaceRoot: input.workspaceRoot,
77
86
  }),
78
87
  )
@@ -158,12 +158,16 @@ async function recycleFailedFiles(
158
158
  return nextState
159
159
  }
160
160
 
161
- function createProvider(config: BatchConfig): BatchStructuredOutputProvider {
161
+ function createProvider(
162
+ config: BatchConfig,
163
+ verbose: boolean | undefined,
164
+ ): BatchStructuredOutputProvider {
162
165
  if (config.provider === 'codex') {
163
166
  return createBatchStructuredOutputProvider({
164
167
  provider: 'codex',
165
168
  ...(config.effort ? { effort: config.effort } : {}),
166
169
  ...(config.model ? { model: config.model } : {}),
170
+ ...(verbose === undefined ? {} : { verbose }),
167
171
  workspaceRoot: config.configDir,
168
172
  })
169
173
  }
@@ -172,6 +176,7 @@ function createProvider(config: BatchConfig): BatchStructuredOutputProvider {
172
176
  provider: 'claude',
173
177
  ...(config.effort ? { effort: config.effort } : {}),
174
178
  ...(config.model ? { model: config.model } : {}),
179
+ ...(verbose === undefined ? {} : { verbose }),
175
180
  workspaceRoot: config.configDir,
176
181
  })
177
182
  }
@@ -223,7 +228,7 @@ export async function runBatchCommand(
223
228
  await writeJsonAtomic(statePath, state)
224
229
 
225
230
  try {
226
- provider ??= createProvider(config)
231
+ provider ??= createProvider(config, input.verbose)
227
232
  const absoluteFilePath = path.join(config.configDir, filePath)
228
233
  const content = await readFile(absoluteFilePath, 'utf8')
229
234
  const output = await provider.runFile({
@@ -1,13 +1,9 @@
1
+ import { createClaudeProvider } from '../agents/claude'
2
+ import { createCodexProvider } from '../agents/codex'
1
3
  import {
2
- createClaudeProvider,
3
- type ClaudeAgentEvent,
4
- type ClaudeAgentEventHandler,
5
- } from '../agents/claude'
6
- import {
7
- createCodexProvider,
8
- type CodexThreadEvent,
9
- type CodexThreadEventHandler,
10
- } from '../agents/codex'
4
+ createClaudeEventHandler,
5
+ createCodexEventHandler,
6
+ } from '../agents/event-log'
11
7
  import { providerOptionsEqual } from '../agents/provider-options'
12
8
  import { runWorkflow, type WorkflowRunResult } from '../core/orchestrator'
13
9
  import { buildTaskTopology } from '../core/task-topology'
@@ -62,54 +58,6 @@ export type RemoteReviewerResolver = (
62
58
  providerName: WorkflowProvider,
63
59
  ) => RemoteReviewerProvider
64
60
 
65
- function writeCodexEvent(event: CodexThreadEvent) {
66
- const itemType =
67
- event.type === 'item.completed' ||
68
- event.type === 'item.started' ||
69
- event.type === 'item.updated'
70
- ? event.item.type
71
- : null
72
- process.stderr.write(
73
- `[codex] ${event.type}${itemType ? ` ${itemType}` : ''}\n`,
74
- )
75
- if (
76
- event.type === 'item.completed' &&
77
- event.item.type === 'agent_message' &&
78
- event.item.text?.trim()
79
- ) {
80
- process.stderr.write(`[codex] message ${event.item.text.trim()}\n`)
81
- }
82
- if (event.type === 'error') {
83
- process.stderr.write(`[codex] error ${event.message}\n`)
84
- }
85
- if (event.type === 'turn.failed') {
86
- process.stderr.write(`[codex] error ${event.error.message}\n`)
87
- }
88
- }
89
-
90
- function createCodexEventHandler(
91
- verbose: boolean | undefined,
92
- ): CodexThreadEventHandler | undefined {
93
- if (!verbose) {
94
- return undefined
95
- }
96
- return writeCodexEvent
97
- }
98
-
99
- function writeClaudeEvent(event: ClaudeAgentEvent) {
100
- const detail = event.type === 'text' ? ` ${event.delta}` : ''
101
- process.stderr.write(`[claude] ${event.type}${detail}\n`)
102
- }
103
-
104
- function createClaudeEventHandler(
105
- verbose: boolean | undefined,
106
- ): ClaudeAgentEventHandler | undefined {
107
- if (!verbose) {
108
- return undefined
109
- }
110
- return writeClaudeEvent
111
- }
112
-
113
61
  function createProviderResolver(
114
62
  context: WorkspaceContext,
115
63
  verbose: boolean | undefined,