taskchef 7.4.0 → 7.6.0
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/.codex-plugin/plugin.json +1 -1
- package/README.md +31 -14
- package/assets/codex.svg +3 -0
- package/docs/images/result-history-dashboard.jpg +0 -0
- package/docs/spec.md +40 -14
- package/docs/workflows.md +35 -17
- package/index.js +1 -0
- package/package.json +2 -1
- package/skills/taskchef-report/SKILL.md +8 -6
- package/src/cli.js +20 -0
- package/src/dashboard/app.js +128 -20
- package/src/dashboard/index.html +6 -3
- package/src/dashboard/styles.css +16 -4
- package/src/dashboard/time.js +146 -0
- package/src/dashboard.js +32 -1
- package/src/mcp.js +7 -1
- package/src/workspace.js +164 -68
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
TaskChef is a local dispatch desk for Codex. Give one dispatcher a request and
|
|
4
4
|
it records each independently useful outcome, creates a normal Codex task in
|
|
5
5
|
the right project, and returns immediately. The executor task is where live
|
|
6
|
-
work, approvals, and follow-ups happen; TaskChef keeps
|
|
7
|
-
|
|
6
|
+
work, approvals, and follow-ups happen; TaskChef keeps every semantic result
|
|
7
|
+
while projecting the latest one for compact navigation and reporting.
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
|
-
request -> recorded TaskChef task -> Codex executor -> current state +
|
|
10
|
+
request -> recorded TaskChef task -> Codex executor -> current state + result history
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Which document should I read?
|
|
@@ -49,7 +49,7 @@ The canonical workspace is `~/.agents/taskchef`. TaskChef owns only:
|
|
|
49
49
|
```text
|
|
50
50
|
AGENTS.md managed dispatcher instructions plus user additions
|
|
51
51
|
taskchef.json schema-2 configured projects and routing metadata
|
|
52
|
-
tasks.jsonl one
|
|
52
|
+
tasks.jsonl one task snapshot per line (schema 6; schema 4/5 migration supported)
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
List or change routing targets conversationally:
|
|
@@ -119,10 +119,12 @@ when a turn starts and one semantic outcome before that same turn ends:
|
|
|
119
119
|
- `failed`: the executor or creation attempt ended unsuccessfully.
|
|
120
120
|
|
|
121
121
|
A native approval prompt is live Codex state, not `needs_input`.
|
|
122
|
-
TaskChef stores the current reported execution state and
|
|
123
|
-
|
|
124
|
-
immediately without erasing
|
|
125
|
-
|
|
122
|
+
TaskChef stores the current reported execution state and appends every concise
|
|
123
|
+
semantic result to `results`. A follow-up therefore appears as `working`
|
|
124
|
+
immediately without erasing any prior outcome. The final entry is exposed as a
|
|
125
|
+
derived `lastResult` compatibility alias; it is not persisted independently and
|
|
126
|
+
is planned for removal in the next major version after callers move to
|
|
127
|
+
`results.at(-1)`. TaskChef does not store transcripts or non-semantic events.
|
|
126
128
|
|
|
127
129
|
Delegated tasks created by earlier TaskChef versions remain compatible: their
|
|
128
130
|
inline executor protocol still parses, self-links, and may use the deprecated
|
|
@@ -172,7 +174,13 @@ taskchef dashboard --port 3211
|
|
|
172
174
|
```
|
|
173
175
|
|
|
174
176
|
The loopback dashboard watches `tasks.jsonl`, groups current states, and opens
|
|
175
|
-
linked Codex tasks.
|
|
177
|
+
linked Codex tasks. List snapshots and SSE events carry only the latest-result
|
|
178
|
+
projection; opening task details fetches the full newest-first result history.
|
|
179
|
+
Task and result times are relative through 29 days (with minute detail for the
|
|
180
|
+
first six hours), then use a locale-aware calendar date. Each time is a keyboard-
|
|
181
|
+
accessible toggle for its full locale-aware date and time, and one shared
|
|
182
|
+
30-second timer keeps relative labels current without reloading the page.
|
|
183
|
+
It does not mutate TaskChef data and prints its local URL.
|
|
176
184
|
When a compatible foreground dashboard already owns port 3210,
|
|
177
185
|
`ensure_dashboard` reuses it but does not take ownership. If an unknown,
|
|
178
186
|
different-workspace, or stale-version process owns the port, TaskChef reports a
|
|
@@ -183,6 +191,8 @@ The health endpoint contains only a fixed service marker, health schema,
|
|
|
183
191
|
TaskChef version, dashboard-server version, and canonical workspace. It exposes
|
|
184
192
|
no task data, credentials, environment variables, process control, or secrets.
|
|
185
193
|
|
|
194
|
+

|
|
195
|
+
|
|
186
196
|
## Common recovery
|
|
187
197
|
|
|
188
198
|
Check the managed workspace:
|
|
@@ -190,20 +200,27 @@ Check the managed workspace:
|
|
|
190
200
|
```sh
|
|
191
201
|
taskchef doctor
|
|
192
202
|
taskchef workspace init
|
|
203
|
+
taskchef workspace migrate
|
|
193
204
|
taskchef doctor
|
|
194
205
|
```
|
|
195
206
|
|
|
196
|
-
`doctor` is read-only. `workspace init` creates missing
|
|
197
|
-
|
|
198
|
-
|
|
207
|
+
`doctor` is read-only. `workspace init` creates missing files and refreshes
|
|
208
|
+
managed instructions. `workspace migrate` explicitly upgrades supported schema
|
|
209
|
+
4/5 task lines to schema 6 under the workspace lock. It validates the complete
|
|
210
|
+
source and converted log before writing, creates an exclusive `tasks.jsonl.pre-v6-*.bak`
|
|
211
|
+
backup, atomically replaces the log, validates the result, and becomes an
|
|
212
|
+
idempotent no-op after migration. If replacement fails, the original remains
|
|
213
|
+
or the reported backup can be restored; unsupported or invalid input is rejected
|
|
214
|
+
before a backup or rewrite.
|
|
199
215
|
|
|
200
216
|
If a new record has no thread ID, the executor is link-pending. Reopen that
|
|
201
217
|
executor so its first action can retry `link_task`. Do not guess an identity
|
|
202
218
|
or edit `tasks.jsonl`. If native task creation failed, the record is retained
|
|
203
219
|
as `failed` with null thread and turn IDs.
|
|
204
220
|
|
|
205
|
-
|
|
206
|
-
|
|
221
|
+
Schemas other than 4, 5, and 6 remain unsupported. Retain such a workspace
|
|
222
|
+
unchanged and create a current workspace; the migration command deliberately
|
|
223
|
+
does not guess how to convert unknown formats.
|
|
207
224
|
|
|
208
225
|
## Boundaries
|
|
209
226
|
|
package/assets/codex.svg
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
|
2
|
+
<path fill="currentColor" d="M3 1.5h10A1.5 1.5 0 0 1 14.5 3v10a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 13V3A1.5 1.5 0 0 1 3 1.5Zm0 1a.5.5 0 0 0-.5.5v10a.5.5 0 0 0 .5.5h10a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5H3Zm1.15 3.1.7-.7L7.95 8l-3.1 3.1-.7-.7L6.55 8l-2.4-2.4ZM8 10h4v1H8v-1Z"/>
|
|
3
|
+
</svg>
|
|
Binary file
|
package/docs/spec.md
CHANGED
|
@@ -23,7 +23,8 @@ is dated research, not contract.
|
|
|
23
23
|
| **Self-linking** | The executor's one-way registration of its own canonical Codex UUIDv7 from `CODEX_THREAD_ID`. |
|
|
24
24
|
| **Link-pending** | A working task whose `threadId` is null and `updatedBy` is `dispatcher`. |
|
|
25
25
|
| **Current execution state** | The latest reported executor turn and its `working`, `needs_input`, `completed`, or `failed` status. |
|
|
26
|
-
| **
|
|
26
|
+
| **Result history** | The ordered collection of every accepted `completed`, `needs_input`, or `failed` per-turn outcome. |
|
|
27
|
+
| **Last semantic result** | The final result-history entry, exposed through the derived `lastResult` compatibility alias. |
|
|
27
28
|
| **Current turn ID** | The canonical Codex UUIDv7 returned by an exact native read of the linked executor for the turn being reported. |
|
|
28
29
|
| **Dashboard** | The loopback, read-only UI derived from validated workspace snapshots and bounded native actions. |
|
|
29
30
|
| **Skill** | One packaged agent procedure: `taskchef-bootstrap`, `taskchef-delegate`, `taskchef-executor`, or `taskchef-report`. |
|
|
@@ -67,10 +68,10 @@ Names and paths MUST be unique. Git projects MUST be exact Git roots.
|
|
|
67
68
|
Repository URLs MUST canonicalize to `https://github.com/<owner>/<repository>`
|
|
68
69
|
and be case-insensitively deduplicated.
|
|
69
70
|
|
|
70
|
-
`tasks.jsonl` MUST contain zero or more newline-terminated schema-4
|
|
71
|
-
records, one per line.
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
`tasks.jsonl` MUST contain zero or more newline-terminated schema-4, schema-5,
|
|
72
|
+
or schema-6 records, one per line. Schemas 4 and 5 are supported migration/read
|
|
73
|
+
formats; every new record and state mutation MUST write schema 6. Other schemas
|
|
74
|
+
or unsupported fields MUST be rejected without conversion.
|
|
74
75
|
Reads and writes MUST reject symlinked managed files. Mutations
|
|
75
76
|
MUST hold the shared workspace lock and replace state atomically; read-only
|
|
76
77
|
operations MUST NOT require write permission.
|
|
@@ -81,7 +82,7 @@ Every record MUST contain exactly these fields:
|
|
|
81
82
|
|
|
82
83
|
| Field | Contract |
|
|
83
84
|
| --- | --- |
|
|
84
|
-
| `schemaVersion` | Integer `
|
|
85
|
+
| `schemaVersion` | Integer `6`; schema-4/5 records remain readable until explicit migration or their next mutation. |
|
|
85
86
|
| `id` | Unique safe TaskChef ID; delegation uses a lowercase full UUID. |
|
|
86
87
|
| `project` | Immutable configured-project snapshot. |
|
|
87
88
|
| `title` | Non-empty display title. |
|
|
@@ -93,7 +94,13 @@ Every record MUST contain exactly these fields:
|
|
|
93
94
|
| `turnId` | Null before turn reporting; otherwise the current reported turn. Linked MCP journeys use a canonical Codex UUIDv7. |
|
|
94
95
|
| `updatedAt` | ISO 8601 timestamp not earlier than `createdAt` or the prior `updatedAt`; clock rollback cannot backdate a transition. |
|
|
95
96
|
| `updatedBy` | `dispatcher` or `mcp`. |
|
|
96
|
-
| `
|
|
97
|
+
| `results` | Ordered oldest-first array of `{status, summary, turnId, updatedAt}` semantic results, with unique turn IDs and nondecreasing timestamps. |
|
|
98
|
+
|
|
99
|
+
Returned Task objects MUST additionally expose `lastResult` as null for an empty
|
|
100
|
+
history or the final `results` entry. `lastResult` MUST be derived and MUST NOT
|
|
101
|
+
be persisted in schema 6. It is a compatibility alias for schema-4/5, CLI,
|
|
102
|
+
MCP, reporting-skill, and dashboard-list callers, with removal planned for the
|
|
103
|
+
next major version after callers migrate to `results.at(-1)`.
|
|
97
104
|
|
|
98
105
|
Task IDs and non-null thread identities MUST be unique. The immutable intent
|
|
99
106
|
fields MUST NOT change after recording.
|
|
@@ -231,7 +238,8 @@ new preparation values, though it writes no state.
|
|
|
231
238
|
|
|
232
239
|
**Structured output:** `{ task: Task }`.
|
|
233
240
|
|
|
234
|
-
The returned task has schema
|
|
241
|
+
The returned task has schema 6, `working`, null summary/turn/thread/lastResult,
|
|
242
|
+
an empty `results` array,
|
|
235
243
|
`updatedBy: dispatcher`, and equal creation/update timestamps. Duplicate IDs,
|
|
236
244
|
unknown projects, malformed markers, and invalid input fail. Repeating a
|
|
237
245
|
successful call is not idempotent; it fails as a duplicate.
|
|
@@ -260,7 +268,7 @@ marker, or ineligible state fails.
|
|
|
260
268
|
### `report_state`
|
|
261
269
|
|
|
262
270
|
**Caller:** executor, or dispatcher only for native creation failure.
|
|
263
|
-
**Mutation:** replaces the current state atomically and preserves `
|
|
271
|
+
**Mutation:** replaces the current state atomically and preserves `results`.
|
|
264
272
|
|
|
265
273
|
**Input:**
|
|
266
274
|
|
|
@@ -279,8 +287,10 @@ the current turn and last semantic result. A semantic state MUST match the
|
|
|
279
287
|
current working turn. Repeating an identical state is idempotent; conflicting
|
|
280
288
|
or older state fails. A null-identity record accepts only a fresh executor
|
|
281
289
|
creation `failed` state with both IDs null. Success sets the current state and
|
|
282
|
-
|
|
283
|
-
|
|
290
|
+
appends a semantic result to `results`; starting newer work preserves the entire
|
|
291
|
+
collection. An identical retry for any settled turn returns success without an
|
|
292
|
+
append. A different result for a settled turn, a stale turn, or a semantic
|
|
293
|
+
result that does not match the active working turn MUST fail.
|
|
284
294
|
|
|
285
295
|
**Annotations:** `readOnlyHint: false`, `destructiveHint: true`,
|
|
286
296
|
`openWorldHint: false`.
|
|
@@ -289,10 +299,10 @@ that result.
|
|
|
289
299
|
|
|
290
300
|
`report_result` retains the prior semantic-only input shape and statuses as a
|
|
291
301
|
temporary compatibility alias. It implicitly accepts a fresh supplied turn and
|
|
292
|
-
stores its semantic result, including for supported schema-4 records and
|
|
302
|
+
stores its semantic result, including for supported schema-4/5 records and
|
|
293
303
|
low-level opaque direct records. It does not accept `working`. New executor
|
|
294
|
-
instructions MUST use `report_state`. Successful mutation upgrades schema 4
|
|
295
|
-
schema
|
|
304
|
+
instructions MUST use `report_state`. Successful mutation upgrades schema 4/5
|
|
305
|
+
to schema 6; unsupported schemas remain rejected.
|
|
296
306
|
|
|
297
307
|
## Reporting and dashboard
|
|
298
308
|
|
|
@@ -302,6 +312,7 @@ state overrides cache. An inactive task does not prove completion. Focused
|
|
|
302
312
|
reports MAY read a selected task once when metadata is newer or evidence is
|
|
303
313
|
uncertain. Reports MUST NOT poll or classify assistant prose.
|
|
304
314
|
|
|
315
|
+
Task lists, summaries, and broad reports MUST use the final result by default.
|
|
305
316
|
The dashboard MUST bind only to loopback, validate the current workspace
|
|
306
317
|
snapshot, and avoid sessions or shared client state. `GET /api/health` MUST
|
|
307
318
|
return only the bounded service identity, health schema, exact TaskChef and
|
|
@@ -313,6 +324,21 @@ startup safely. Direct thread navigation
|
|
|
313
324
|
MUST require a canonical Codex UUIDv7. Otherwise it MAY open the revalidated
|
|
314
325
|
configured project. Project paths from task history MUST be matched against
|
|
315
326
|
current configuration before use.
|
|
327
|
+
Snapshot and SSE list payloads MUST omit full `results` history and include the
|
|
328
|
+
derived latest-result projection. The bounded per-task detail endpoint MAY
|
|
329
|
+
return the full validated task so the dialog can render history newest first.
|
|
330
|
+
|
|
331
|
+
## Task-log migration
|
|
332
|
+
|
|
333
|
+
`workspace migrate` MUST explicitly convert every supported schema-4/5 record
|
|
334
|
+
under the shared lock. A legacy `lastResult`, or a schema-4 current semantic
|
|
335
|
+
state, becomes zero or one initial `results` entry. Migration MUST validate the
|
|
336
|
+
complete source and complete schema-6 candidate before changing the task log,
|
|
337
|
+
create and read back an exclusive recovery backup, atomically replace the log,
|
|
338
|
+
and validate the installed result. A fully schema-6 log MUST be an idempotent
|
|
339
|
+
no-op without another backup. Invalid/unsupported input MUST remain untouched;
|
|
340
|
+
failures after backup creation MUST report the backup path and MUST never
|
|
341
|
+
partially rewrite individual lines.
|
|
316
342
|
|
|
317
343
|
## Concurrency and trust
|
|
318
344
|
|
package/docs/workflows.md
CHANGED
|
@@ -18,7 +18,7 @@ research.
|
|
|
18
18
|
| `src/delegation.js` | UUID marker, concise executor-skill invocation shape, and creation-failure handling. |
|
|
19
19
|
| `src/workspace.js` | Current schemas, validation, locking, atomic JSONL writes, linking, and result freshness. |
|
|
20
20
|
| `src/cli.js` | Administration, inspection, diagnostics, and dashboard startup. |
|
|
21
|
-
| `src/dashboard.js` | Versioned health identity, validated snapshots, SSE fan-out, and bounded open actions. |
|
|
21
|
+
| `src/dashboard.js` | Versioned health identity, validated compact snapshots, SSE fan-out, on-demand details, and bounded open actions. |
|
|
22
22
|
| `src/dashboard-manager.js` | Concurrent singleton ensure, exact listener reuse, conflicts, and owned shutdown. |
|
|
23
23
|
|
|
24
24
|
The MCP process resolves `TASKCHEF_WORKSPACE` once and never accepts a model
|
|
@@ -89,7 +89,7 @@ sequenceDiagram
|
|
|
89
89
|
D->>D: Choose one configured and native project
|
|
90
90
|
D->>M: record_task(id, project, title, instruction, null)
|
|
91
91
|
M->>W: recordTask()
|
|
92
|
-
W->>W: Lock, validate, append schema-
|
|
92
|
+
W->>W: Lock, validate, append schema-6 snapshot
|
|
93
93
|
W-->>M: working link-pending task
|
|
94
94
|
M-->>D: task
|
|
95
95
|
D->>C: Create executor with marked instruction
|
|
@@ -116,8 +116,8 @@ semantic callbacks.
|
|
|
116
116
|
## State reporting
|
|
117
117
|
|
|
118
118
|
The executor obtains the turn identity from an exact native read of its own
|
|
119
|
-
linked task. `report_state` records live turn state while preserving the
|
|
120
|
-
semantic result
|
|
119
|
+
linked task. `report_state` records live turn state while preserving the ordered
|
|
120
|
+
semantic result history.
|
|
121
121
|
|
|
122
122
|
```mermaid
|
|
123
123
|
sequenceDiagram
|
|
@@ -130,13 +130,13 @@ sequenceDiagram
|
|
|
130
130
|
C-->>E: Current turn ID
|
|
131
131
|
E->>M: report_state(..., working, null)
|
|
132
132
|
M->>W: reportTaskState()
|
|
133
|
-
W->>W: Store current turn and preserve
|
|
133
|
+
W->>W: Store current turn and preserve results
|
|
134
134
|
E->>E: Work, finish, or reach semantic decision
|
|
135
135
|
E->>M: report_state(..., semantic status, summary)
|
|
136
136
|
M->>W: reportTaskState()
|
|
137
137
|
W->>W: Lock and validate identity and freshness
|
|
138
138
|
alt Same current working turn
|
|
139
|
-
W->>W:
|
|
139
|
+
W->>W: Append semantic result and derive lastResult
|
|
140
140
|
W-->>M: Updated task
|
|
141
141
|
M-->>E: Recorded result
|
|
142
142
|
else Same turn and same result
|
|
@@ -173,9 +173,9 @@ sequenceDiagram
|
|
|
173
173
|
C-->>E: turnB
|
|
174
174
|
E->>M: report_state(..., turnB, working, null)
|
|
175
175
|
M->>W: reportTaskState()
|
|
176
|
-
W->>W: Require turnB greater and preserve
|
|
177
|
-
W-->>M: working snapshot plus
|
|
178
|
-
M-->>E: working snapshot plus
|
|
176
|
+
W->>W: Require turnB greater and preserve results
|
|
177
|
+
W-->>M: working snapshot plus history A
|
|
178
|
+
M-->>E: working snapshot plus history A
|
|
179
179
|
E->>M: report_state(..., turnB, completed, summaryB)
|
|
180
180
|
M->>W: reportTaskState()
|
|
181
181
|
W-->>M: completed snapshot plus result B
|
|
@@ -263,7 +263,9 @@ sequenceDiagram
|
|
|
263
263
|
F-->>D: Filesystem change
|
|
264
264
|
D->>F: Bounded read from one descriptor
|
|
265
265
|
D->>D: Validate current schema and sort
|
|
266
|
-
D-->>B: SSE snapshot
|
|
266
|
+
D-->>B: Compact SSE snapshot without results
|
|
267
|
+
B->>D: GET task detail on demand
|
|
268
|
+
D-->>B: Full validated history
|
|
267
269
|
B->>D: Open task action
|
|
268
270
|
alt Canonical Codex UUIDv7
|
|
269
271
|
D->>C: Direct thread navigation
|
|
@@ -273,10 +275,25 @@ sequenceDiagram
|
|
|
273
275
|
end
|
|
274
276
|
```
|
|
275
277
|
|
|
276
|
-
The dashboard binds to `127.0.0.1`, has no shared session state, limits
|
|
277
|
-
|
|
278
|
-
bounded identity endpoint contains no task data
|
|
279
|
-
|
|
278
|
+
The dashboard binds to `127.0.0.1`, has no shared session state, limits task
|
|
279
|
+
count, file size, result count, and display fields, and checks origin/authority
|
|
280
|
+
for stateful local actions. Its bounded identity endpoint contains no task data
|
|
281
|
+
or secrets. The monitor already validates the complete log, but
|
|
282
|
+
snapshot/SSE list projections omit `results` so repeated updates do not resend
|
|
283
|
+
unnecessary history. A read-only per-task endpoint returns full history only
|
|
284
|
+
when the dialog opens. Historical project paths are untrusted until matched
|
|
285
|
+
against current configuration.
|
|
286
|
+
|
|
287
|
+
## Schema 4/5 migration
|
|
288
|
+
|
|
289
|
+
`taskchef workspace migrate` acquires the same workspace lock as lifecycle
|
|
290
|
+
writers, validates the complete legacy log, converts each schema-4/5 latest
|
|
291
|
+
result into zero or one initial schema-6 `results` entry, then validates the
|
|
292
|
+
complete candidate. Before replacement it writes and reads back an exclusive
|
|
293
|
+
`tasks.jsonl.pre-v6-*.bak` file. The task log is replaced atomically and
|
|
294
|
+
validated again. A second run sees only schema 6 and returns unchanged without
|
|
295
|
+
another backup. Unsupported or malformed input fails before backup/rewrite;
|
|
296
|
+
after a later filesystem failure, the reported backup is the recovery source.
|
|
280
297
|
|
|
281
298
|
## Concurrency and trust boundaries
|
|
282
299
|
|
|
@@ -291,6 +308,7 @@ summary is cryptographically authenticated; this is a local single-user trust
|
|
|
291
308
|
model. Managed files, instructions, project snapshots, MCP inputs, and dashboard
|
|
292
309
|
requests are validated at every action boundary.
|
|
293
310
|
|
|
294
|
-
Configuration schema 2 and task schemas 4 and
|
|
295
|
-
read
|
|
296
|
-
schema
|
|
311
|
+
Configuration schema 2 and task schemas 4, 5, and 6 are accepted. Schemas 4/5
|
|
312
|
+
are read/migration compatibility until an explicit migration or lifecycle
|
|
313
|
+
mutation upgrades each record to schema 6. Schema 6 persists `results` only and
|
|
314
|
+
derives `lastResult` for compatibility. Other schemas are rejected without rewrite.
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskchef",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.0",
|
|
4
4
|
"description": "A non-blocking interactive dispatcher for visible Codex tasks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Favo Yang",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"docs/spec.md",
|
|
27
27
|
"docs/workflows.md",
|
|
28
28
|
"docs/firstmate-taskchef-comparison.md",
|
|
29
|
+
"docs/images/result-history-dashboard.jpg",
|
|
29
30
|
"index.js",
|
|
30
31
|
"mcp",
|
|
31
32
|
"scripts/benchmark-dispatch-prepare.js",
|
|
@@ -44,14 +44,16 @@ all deterministic task-log operations.
|
|
|
44
44
|
detailed read. Native approval is live Codex state, not a `needs_input`
|
|
45
45
|
callback. An inactive status never proves semantic completion; it only
|
|
46
46
|
permits a trustworthy cached MCP result to stand.
|
|
47
|
-
4. In schema
|
|
48
|
-
execution state and treat `
|
|
49
|
-
|
|
47
|
+
4. In schema 6, treat `status`, `turnId`, and `updatedAt` as the latest reported
|
|
48
|
+
execution state and treat `results` as the ordered semantic history.
|
|
49
|
+
`lastResult` is the derived compatibility alias for `results.at(-1)`; prefer
|
|
50
|
+
the collection when full history matters and the alias for compact latest-state
|
|
51
|
+
reporting. A `working` state with a non-null `lastResult` means a newer executor
|
|
50
52
|
turn started after that result; show the prior result as history, not as the
|
|
51
53
|
current outcome. Treat a failed `lastResult` with null thread and turn IDs as
|
|
52
|
-
a fresh executor-creation failure.
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
a fresh executor-creation failure. Schema 4/5 snapshots normalize zero or one
|
|
55
|
+
semantic result into `results` and `lastResult` without rewriting their log line.
|
|
56
|
+
No live read is possible or needed for that creation failure. When identity is certain and
|
|
55
57
|
metadata says the thread is inactive, trust the latest semantic result by
|
|
56
58
|
default in a broad overview unless a newer working state makes it historical.
|
|
57
59
|
Do not read every idle terminal task in an overview merely because native
|
package/src/cli.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
initializeWorkspace,
|
|
15
15
|
listProjects,
|
|
16
16
|
listTasks,
|
|
17
|
+
migrateTaskLog,
|
|
17
18
|
prepareDispatch,
|
|
18
19
|
recordTask,
|
|
19
20
|
removeProject,
|
|
@@ -182,11 +183,28 @@ function taskDetails(task) {
|
|
|
182
183
|
`Updated by: ${singleLineDetail(task.updatedBy ?? "-")}`,
|
|
183
184
|
`Task ID: ${singleLineDetail(task.id)}`,
|
|
184
185
|
`Thread ID: ${singleLineDetail(task.threadId ?? "-")}`,
|
|
186
|
+
`Result count: ${task.results.length}`,
|
|
187
|
+
"Result history (newest first):",
|
|
188
|
+
...[...task.results].reverse().map((result) => (
|
|
189
|
+
`- ${singleLineDetail(result.updatedAt)} | ${singleLineDetail(result.status)} | turn ${singleLineDetail(result.turnId ?? "-")} | ${singleLineDetail(result.summary)}`
|
|
190
|
+
)),
|
|
185
191
|
"Instruction:",
|
|
186
192
|
task.instruction,
|
|
187
193
|
].join("\n");
|
|
188
194
|
}
|
|
189
195
|
|
|
196
|
+
async function migrate(args) {
|
|
197
|
+
validateCommandArgs(args, 2, { values: ["--workspace"], switches: ["--json"] });
|
|
198
|
+
const result = await migrateTaskLog(workspaceRoot(args));
|
|
199
|
+
print(result, args, (value) => [
|
|
200
|
+
`Task log: ${value.action}`,
|
|
201
|
+
`Tasks: ${value.taskCount}`,
|
|
202
|
+
`Migrated: ${value.migratedCount}`,
|
|
203
|
+
`Backup: ${value.backupPath ?? "not needed"}`,
|
|
204
|
+
].join("\n"));
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
|
|
190
208
|
async function readTaskForShow(workspace, taskId) {
|
|
191
209
|
const id = requireSafeId(taskId, "taskId");
|
|
192
210
|
const tasks = await listTasks(workspace);
|
|
@@ -456,6 +474,7 @@ Usage:
|
|
|
456
474
|
taskchef doctor [--json] [--workspace <path>]
|
|
457
475
|
taskchef workspace path [--json] [--workspace <path>]
|
|
458
476
|
taskchef workspace init [--register-codex] [--codex-cli <path>] [--json] [--workspace <path>]
|
|
477
|
+
taskchef workspace migrate [--json] [--workspace <path>]
|
|
459
478
|
taskchef project add <path> [--name <name>] [--description <text>] [--github-repo <url> ... | --no-github] [--json] [--workspace <path>]
|
|
460
479
|
taskchef project import [<file> | -] [--replace] [--json] [--workspace <path>]
|
|
461
480
|
taskchef project list [--json] [--workspace <path>]
|
|
@@ -489,6 +508,7 @@ export async function runCli(args) {
|
|
|
489
508
|
if (args[0] === "doctor") return doctor(args);
|
|
490
509
|
if (args[0] === "workspace" && args[1] === "path") return workspacePath(args);
|
|
491
510
|
if (args[0] === "workspace" && args[1] === "init") return initialize(args);
|
|
511
|
+
if (args[0] === "workspace" && args[1] === "migrate") return migrate(args);
|
|
492
512
|
if (args[0] === "project" && args[1] === "add") return projectAdd(args);
|
|
493
513
|
if (args[0] === "project" && args[1] === "import") return projectImport(args);
|
|
494
514
|
if (args[0] === "project" && args[1] === "list") return projectList(args);
|