taskchef 8.7.1 → 9.0.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 +7 -10
- package/.mcp.json +3 -2
- package/README.md +31 -158
- package/docs/mcp-app.md +3 -3
- package/docs/spec.md +38 -746
- package/docs/taskchef-next-storage.md +2 -2
- package/index.js +2 -99
- package/package.json +12 -49
- package/skills/delegate/SKILL.md +44 -0
- package/skills/delegate/agents/openai.yaml +4 -0
- package/src/codex-app.js +3 -152
- package/src/codex-session-scanner.js +2 -2
- package/src/file-lock.js +25 -0
- package/src/mcp-app/react/NextTaskDetail.test.tsx +1 -1
- package/src/mcp-app/react/NextTaskDetail.tsx +8 -8
- package/src/mcp-app/react/main.test.tsx +3 -3
- package/src/mcp-app/react/main.tsx +7 -7
- package/src/mcp-app.js +2 -2
- package/src/mcp.js +4 -542
- package/src/next-cache.js +2 -2
- package/src/next-github.js +3 -3
- package/src/next-notifications.js +2 -2
- package/src/{dashboard/react → ui}/components/CardStatusIcons.tsx +1 -1
- package/src/{dashboard/react → ui}/components/GitHubLinks.tsx +1 -1
- package/src/{dashboard/react → ui}/components/LinkedText.tsx +1 -1
- package/src/{dashboard/react → ui}/components/RelativeTime.test.tsx +1 -1
- package/src/{dashboard/react → ui}/components/RelativeTime.tsx +1 -1
- package/src/{dashboard/react → ui}/components/ReplyImagePreview.test.tsx +1 -1
- package/src/{dashboard/react → ui}/components/TaskBoard.tsx +1 -1
- package/src/{dashboard/react → ui}/components/TaskCard.tsx +1 -1
- package/src/{dashboard/react → ui}/components/TurnContent.tsx +1 -1
- package/src/{dashboard/react → ui}/presentation.ts +1 -1
- package/src/version.js +0 -1
- package/BACKLOG.md +0 -48
- package/assets/e2e-benchmark-example.json +0 -50
- package/assets/taskchef-dispatcher-instructions.md +0 -44
- package/bin/taskchef.js +0 -20
- package/docs/advanced-guide.md +0 -497
- package/docs/dashboard-lifecycle.md +0 -149
- package/docs/dashboard-ui.md +0 -40
- package/docs/firstmate-taskchef-comparison.md +0 -283
- package/docs/images/ccusage-token-consumption.png +0 -0
- package/docs/images/dashboard-identity.jpg +0 -0
- package/docs/images/dashboard-token-pending.jpg +0 -0
- package/docs/images/interrupted-turn-recovery.jpg +0 -0
- package/docs/images/notification-event-snapshots.jpg +0 -0
- package/docs/images/readme-board.png +0 -0
- package/docs/images/readme-completed.png +0 -0
- package/docs/images/readme-list.png +0 -0
- package/docs/images/readme-needs-input.png +0 -0
- package/docs/images/readme-roles.png +0 -0
- package/docs/images/reported-work-duration-desktop.jpg +0 -0
- package/docs/images/reported-work-duration-mobile.jpg +0 -0
- package/docs/images/result-history-dashboard.jpg +0 -0
- package/docs/images/taskchef-pr-icon-comparison.jpg +0 -0
- package/docs/images/taskchef-unified-status-popup.jpg +0 -0
- package/docs/workflows.md +0 -476
- package/mcp/dashboard-session.js +0 -51
- package/scripts/benchmark-dispatch-prepare.js +0 -90
- package/scripts/e2e-benchmark.js +0 -206
- package/scripts/roles/resolve_roles.py +0 -293
- package/skills/taskchef-bootstrap/SKILL.md +0 -96
- package/skills/taskchef-bootstrap/agents/openai.yaml +0 -4
- package/skills/taskchef-bootstrap/references/project-index.md +0 -154
- package/skills/taskchef-copilot/SKILL.md +0 -75
- package/skills/taskchef-copilot/agents/openai.yaml +0 -4
- package/skills/taskchef-dashboard/SKILL.md +0 -24
- package/skills/taskchef-dashboard/agents/openai.yaml +0 -4
- package/skills/taskchef-delegate/SKILL.md +0 -102
- package/skills/taskchef-delegate/agents/openai.yaml +0 -4
- package/skills/taskchef-delegate/references/model-roles.md +0 -29
- package/skills/taskchef-executor/SKILL.md +0 -154
- package/skills/taskchef-executor/agents/openai.yaml +0 -4
- package/skills/taskchef-executor/references/compatibility.md +0 -22
- package/skills/taskchef-executor/references/ending-actions.md +0 -26
- package/src/backups.js +0 -359
- package/src/cli.js +0 -733
- package/src/config-audit.js +0 -99
- package/src/config-mutations.js +0 -106
- package/src/dashboard/actions.js +0 -136
- package/src/dashboard/app.js +0 -1172
- package/src/dashboard/dist/app.js +0 -269
- package/src/dashboard/dist/app.js.map +0 -1
- package/src/dashboard/dist/index.html +0 -16
- package/src/dashboard/dist/styles.css +0 -1
- package/src/dashboard/index.html +0 -148
- package/src/dashboard/react/App.test.tsx +0 -346
- package/src/dashboard/react/App.tsx +0 -515
- package/src/dashboard/react/api.test.ts +0 -40
- package/src/dashboard/react/api.ts +0 -103
- package/src/dashboard/react/components/ActivityTimeline.tsx +0 -118
- package/src/dashboard/react/components/ModelSettings.test.tsx +0 -180
- package/src/dashboard/react/components/ModelSettings.tsx +0 -106
- package/src/dashboard/react/components/NotificationCenter.test.tsx +0 -76
- package/src/dashboard/react/components/NotificationCenter.tsx +0 -111
- package/src/dashboard/react/components/PullRequestBadges.tsx +0 -18
- package/src/dashboard/react/components/TaskDetail.test.tsx +0 -255
- package/src/dashboard/react/components/TaskDetail.tsx +0 -271
- package/src/dashboard/react/components/UsagePanel.tsx +0 -96
- package/src/dashboard/react/index.html +0 -15
- package/src/dashboard/react/main.tsx +0 -12
- package/src/dashboard/react/overlay-state.test.ts +0 -110
- package/src/dashboard/react/overlay-state.ts +0 -60
- package/src/dashboard/react/presentation.test.tsx +0 -571
- package/src/dashboard/styles.css +0 -261
- package/src/dashboard-control.js +0 -34
- package/src/dashboard-manager.js +0 -339
- package/src/dashboard-session-process.js +0 -88
- package/src/dashboard-session.js +0 -86
- package/src/dashboard.js +0 -1303
- package/src/delegation.js +0 -277
- package/src/github.js +0 -107
- package/src/model-roles.js +0 -70
- package/src/recorded-usage-tracker.js +0 -92
- package/src/usage-tracker.js +0 -650
- package/src/usage.js +0 -367
- package/src/workspace-path.js +0 -48
- package/src/workspace.js +0 -3629
- /package/src/{dashboard/react → ui}/components/AnimatedUsage.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/CardStatusIcons.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ImageGallery.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/OpenChatButton.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/OpenChatButton.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/PrGlyph.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/QueuedPrompts.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/QueuedPrompts.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ReplyCover.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ReplyCover.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ReplyImagePreview.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ReplyMarkdown.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ReplyMarkdown.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/SavedUsageFormat.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/SavedUsageFormat.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/ShimmerText.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/StatsGrid.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/StatusBadge.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/TaskBoard.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/TaskCardStats.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/TaskCardStats.tsx +0 -0
- /package/src/{dashboard/react → ui}/components/TurnContent.test.tsx +0 -0
- /package/src/{dashboard/react → ui}/fixtures.ts +0 -0
- /package/src/{dashboard → ui}/github-links.js +0 -0
- /package/src/{dashboard/react → ui}/image-cache.test.ts +0 -0
- /package/src/{dashboard/react → ui}/image-cache.ts +0 -0
- /package/src/{dashboard → ui}/state.js +0 -0
- /package/src/{dashboard/react → ui}/styles.css +0 -0
- /package/src/{dashboard/react → ui}/test-setup.ts +0 -0
- /package/src/{dashboard → ui}/time.js +0 -0
- /package/src/{dashboard/react → ui}/types.ts +0 -0
package/docs/spec.md
CHANGED
|
@@ -1,758 +1,50 @@
|
|
|
1
|
-
# TaskChef
|
|
1
|
+
# TaskChef native product contract
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[workflows](workflows.md) owns implementation walkthroughs; the
|
|
7
|
-
[FirstMate comparison](firstmate-taskchef-comparison.md) is dated research,
|
|
8
|
-
not contract.
|
|
3
|
+
TaskChef is a local Codex dashboard. Codex databases and rollout logs own chat
|
|
4
|
+
identity, recorded prompts and replies, turn state, schedules, queue contents,
|
|
5
|
+
and token usage. TaskChef reads them without rewriting Codex data.
|
|
9
6
|
|
|
10
|
-
##
|
|
7
|
+
## Runtime
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| **Configured project** | One routing target in `taskchef.json`, identified by canonical local path and described by `name`, optional `description`, `isGitRepository`, and `githubRepos`. |
|
|
18
|
-
| **Mutation preview** | A read-only, hash-bound exact before/after project-index diff required before destructive replacement, removal, or restore. |
|
|
19
|
-
| **State backup** | A private, verified snapshot under the dispatcher workspace's `backups/` directory. It never restores automatically. |
|
|
20
|
-
| **Routing** | Selecting exactly one configured project and exactly one matching native Codex project for an outcome. |
|
|
21
|
-
| **Delegated task** | One independently useful outcome represented by one TaskChef task UUID and snapshot. |
|
|
22
|
-
| **Executor** | The native Codex task created to own and perform one delegated task. |
|
|
23
|
-
| **Task record** | One complete JSON object in `tasks.jsonl`; it contains immutable intent/project fields and mutable identity/result fields. |
|
|
24
|
-
| **Marker** | The exact correlation line `<!-- taskchef_id=<lowercase full UUID> -->`; new instructions place it on the final line, immediately after the executor-skill invocation. |
|
|
25
|
-
| **Record-before-create** | Persisting a link-pending task before asking Codex to create its executor. |
|
|
26
|
-
| **Self-linking** | The executor's one-way registration of its own canonical Codex UUIDv7 from `CODEX_THREAD_ID`. |
|
|
27
|
-
| **Link-pending** | A working task whose `threadId` is null and `updatedBy` is `dispatcher`. |
|
|
28
|
-
| **Current execution state** | The latest reported executor turn and its `working`, `needs_input`, `completed`, or `failed` status. |
|
|
29
|
-
| **Turn timeline** | The ordered collection pairing each turn's concise request summary with its semantic result, TaskChef-generated interruption outcome, or current in-progress state. |
|
|
30
|
-
| **Interrupted turn** | A formerly active turn that lacked a terminal report when a newer valid turn started; TaskChef closes it with the fixed timeline-only `interrupted` outcome. |
|
|
31
|
-
| **Last semantic result** | The final result-history entry, exposed through the derived `lastResult` compatibility alias. |
|
|
32
|
-
| **Turn reference** | Required lifecycle identity for one executor prompt. It is the native Codex turn ID when available, otherwise a retained client-generated UUID. |
|
|
33
|
-
| **Current turn ID** | Optional Codex metadata for the reported prompt; null when native turn reading is unavailable. |
|
|
34
|
-
| **Dashboard** | The loopback UI derived from validated workspace snapshots, with optional local usage projections, bounded native actions, and an explicit audited manual-outcome mutation. |
|
|
35
|
-
| **Skill** | One packaged agent procedure: `taskchef-bootstrap`, `taskchef-dashboard`, `taskchef-delegate`, `taskchef-executor`, or `taskchef-copilot`. |
|
|
9
|
+
The plugin launches one stdio MCP server and advertises the native sidebar app.
|
|
10
|
+
It does not start an HTTP server, create a dispatcher workspace, index a second
|
|
11
|
+
project registry, or maintain tasks.jsonl. Only native dashboard tools are
|
|
12
|
+
registered. No task markers, self-linking, executor reports, or lifecycle
|
|
13
|
+
callbacks are needed for a chat to appear.
|
|
36
14
|
|
|
37
|
-
|
|
15
|
+
The MCP process closes its transport and resources on EOF, signals, protocol
|
|
16
|
+
close, or parent loss. Settings and caches use atomic writes. Shared state
|
|
17
|
+
writes also use the existing file lock, with its filename and timing preserved.
|
|
18
|
+
Open-chat callers must provide a UUID; the boundary check does not insist on
|
|
19
|
+
UUIDv7 or generate IDs.
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
diagnostics. It MUST NOT dispatch or report unless separately requested.
|
|
41
|
-
- `taskchef-delegate` MUST own routing and record-before-create delegation.
|
|
42
|
-
It MUST return after creation and MUST NOT poll, supervise, or infer identity.
|
|
43
|
-
- `taskchef-executor` MUST own executor assignment ownership, self-linking,
|
|
44
|
-
exact thread/turn identity, per-turn state reporting, failure behavior,
|
|
45
|
-
privacy, and idempotency. It MUST NOT dispatch the owned assignment again.
|
|
46
|
-
- `taskchef-copilot` MUST own conversational outcome explanation, attention,
|
|
47
|
-
and next-action recommendations. It MUST use cached normalized briefs by
|
|
48
|
-
default and MUST NOT poll or persist inferred state.
|
|
49
|
-
- `taskchef-dashboard` MUST own manual dashboard ensure and recovery. It MUST
|
|
50
|
-
NOT dispatch work or inspect task outcomes, and browser navigation failure
|
|
51
|
-
MUST NOT suppress the returned dashboard URL.
|
|
52
|
-
- The MCP server MUST expose `ensure_dashboard`, four primary lifecycle tools,
|
|
53
|
-
and the deprecated `report_result` compatibility alias specified below.
|
|
54
|
-
- The CLI MAY administer and inspect the workspace, but MUST NOT provide a
|
|
55
|
-
second agent lifecycle protocol.
|
|
56
|
-
- The dashboard MUST be read-only with respect to dispatcher files except for
|
|
57
|
-
the explicit audited manual-transition operation defined below.
|
|
58
|
-
- `docs/spec.md` is the single normative behavior source. Other documents
|
|
59
|
-
MUST link here rather than redefine the contract.
|
|
21
|
+
## Feature state
|
|
60
22
|
|
|
61
|
-
|
|
23
|
+
TaskChef retains its current native settings, GitHub credentials, Done marks,
|
|
24
|
+
notification state, and scan/PR/usage/pricing caches. Credentials remain in the
|
|
25
|
+
system credential store. A Done mark is bound to the current turn. A new turn
|
|
26
|
+
invalidates stale derived data. Damaged state is preserved and reported rather
|
|
27
|
+
than silently reset. See [storage](taskchef-next-storage.md).
|
|
62
28
|
|
|
63
|
-
|
|
64
|
-
optional `.taskchef-usage.json` cache inside the dispatcher workspace. It MUST
|
|
65
|
-
preserve unrelated paths. Dashboard process identity and Codex-session leases
|
|
66
|
-
MUST remain in memory and MUST NOT create owner, secret, or handoff files.
|
|
29
|
+
## Delegation
|
|
67
30
|
|
|
68
|
-
|
|
69
|
-
|
|
31
|
+
The packaged `$taskchef:delegate` skill uses native Codex project discovery and chat
|
|
32
|
+
creation. It passes an ordinary assignment, resolves ambiguity with the user,
|
|
33
|
+
and returns the native link. Explicit follow-ups use the selected existing
|
|
34
|
+
chat. Codex owns execution and outcomes; TaskChef does not mirror task records.
|
|
70
35
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"projects": []
|
|
75
|
-
}
|
|
76
|
-
```
|
|
36
|
+
Optional routing memory contains only confirmed project aliases and explicit
|
|
37
|
+
preferences. Revalidate it against current native projects. It is not a task
|
|
38
|
+
log, a source of authority, or a store for prompts, results, or credentials.
|
|
77
39
|
|
|
78
|
-
|
|
79
|
-
`isGitRepository`, and array `githubRepos`; `description` is optional.
|
|
80
|
-
Names and paths MUST be unique. Git projects MUST be exact Git roots.
|
|
81
|
-
Repository URLs MUST canonicalize to `https://github.com/<owner>/<repository>`
|
|
82
|
-
and be case-insensitively deduplicated.
|
|
40
|
+
## Transition and delivery
|
|
83
41
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
42
|
+
Retiring the dispatcher CLI, skills, tools and exported API is a breaking
|
|
43
|
+
change delivered in a major release. Existing legacy workspaces, task logs and
|
|
44
|
+
Codex data remain untouched. There is no automatic data deletion or archive
|
|
45
|
+
export feature. The release remains TaskChef; a development copy uses the
|
|
46
|
+
separate taskchef-next identity and TaskChef Dev name.
|
|
88
47
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
or paths. Routing hints are bounded per canonical configured path and retain
|
|
93
|
-
aliases, canonical repositories, concise responsibilities, and forgotten-value
|
|
94
|
-
suppression. Every fact has one compact provenance record; accepted-report
|
|
95
|
-
facts include the exact task, thread, and current terminal turn. Absence means
|
|
96
|
-
empty state. Older releases reject the optional field rather than rewriting it.
|
|
97
|
-
|
|
98
|
-
`tasks.jsonl` MUST contain zero or more newline-terminated schema-4 through
|
|
99
|
-
schema-10 records, one per line. Schemas 4 through 9 are supported
|
|
100
|
-
migration/read formats; every new record and state mutation MUST write schema 10. Other schemas
|
|
101
|
-
or unsupported fields MUST be rejected without conversion.
|
|
102
|
-
Reads and writes MUST reject symlinked managed files. Mutations
|
|
103
|
-
MUST hold the shared workspace lock and replace state atomically; read-only
|
|
104
|
-
operations MUST NOT require write permission.
|
|
105
|
-
|
|
106
|
-
## Task schema
|
|
107
|
-
|
|
108
|
-
Every record MUST contain exactly these fields:
|
|
109
|
-
|
|
110
|
-
| Field | Contract |
|
|
111
|
-
| --- | --- |
|
|
112
|
-
| `schemaVersion` | Integer `10`; schema-4/5/6/7/8/9 records remain readable until explicit migration or their next mutation. |
|
|
113
|
-
| `id` | Unique safe TaskChef ID; delegation uses a lowercase full UUID. |
|
|
114
|
-
| `project` | Immutable configured-project snapshot. |
|
|
115
|
-
| `title` | Non-empty display title. |
|
|
116
|
-
| `instruction` | Non-empty executor instruction; link-pending records MUST contain the exact marker for `id`. |
|
|
117
|
-
| `threadId` | Null while link-pending; after self-link, canonical Codex UUIDv7. Low-level current-schema direct records may hold another durable non-provisional ID but are outside the MCP delegation journey. |
|
|
118
|
-
| `createdAt` | ISO 8601 creation timestamp. |
|
|
119
|
-
| `status` | `working`, `needs_input`, `completed`, or `failed`. |
|
|
120
|
-
| `summary` | Null while working; otherwise the current semantic state's non-empty summary of at most 2,000 characters. |
|
|
121
|
-
| `turnRef` | Null before reporting begins; otherwise the required lifecycle identity of the current turn. Self-linking journeys use a native or fallback UUID. Migrated low-level `report_result` compatibility records may retain an opaque ref equal to their opaque `turnId`. |
|
|
122
|
-
| `turnId` | Optional Codex metadata. When non-null it equals `turnRef`; null indicates fallback identity. |
|
|
123
|
-
| `updatedAt` | ISO 8601 timestamp not earlier than `createdAt` or the prior `updatedAt`; clock rollback cannot backdate a transition. |
|
|
124
|
-
| `updatedBy` | `dispatcher`, `mcp`, or `dashboard`. `dashboard` is valid only when the latest turn is a manual dashboard transition. |
|
|
125
|
-
| `turns` | Ordered oldest-first array of `{turnRef, turnId, requestSummary, startedAt, result, provenance}`. Every `turnRef` is required. `requestSummary` is null only for migrated/compatibility turns. `result` is null only for the latest working turn, a semantic `{status, summary, updatedAt}` result, or the fixed TaskChef `interrupted` outcome. `provenance` is `{kind: legacy}` or `{kind: mcp}` for ordinary turns, or the audited manual-transition record defined below. New self-linking and manual turn refs are unique. A migrated low-level opaque record may retain one final reused native-derived ref for its legacy ambiguity. |
|
|
126
|
-
|
|
127
|
-
Returned Task objects MUST additionally expose `latestTurn` as null for an empty
|
|
128
|
-
timeline or the final `turns` entry. They MUST derive `results` only from
|
|
129
|
-
semantic `needs_input`, `completed`, and `failed` turn results and `lastResult`
|
|
130
|
-
from the final derived semantic result. Interrupted outcomes MUST be excluded.
|
|
131
|
-
These projections MUST NOT be persisted in schema 10 and remain compatibility
|
|
132
|
-
aliases for existing callers.
|
|
133
|
-
|
|
134
|
-
## Project-index mutation and recovery
|
|
135
|
-
|
|
136
|
-
TaskChef MUST provide a targeted update that preserves every unrelated project
|
|
137
|
-
and replaces an explicitly supplied repository list in full. Project list JSON
|
|
138
|
-
MUST expose stable semantic hashes. Whole-index replacement, project removal,
|
|
139
|
-
and restore MUST first return an exact diff and MUST reject stale hashes,
|
|
140
|
-
incomplete removed-name confirmation, mismatched counts, and unconfirmed large
|
|
141
|
-
count collapse. Agents MUST obtain explicit user permission for every removed
|
|
142
|
-
project entry and verify the complete post-state.
|
|
143
|
-
|
|
144
|
-
Every actual configuration mutation and actual dashboard-server start MUST
|
|
145
|
-
create or deduplicate a mode-private, manifest-and-hash-verified state snapshot
|
|
146
|
-
before writing. Mutations MUST append bounded attribution-free prepared and
|
|
147
|
-
terminal audit records. Backup list, create, and verify are read-only except for
|
|
148
|
-
explicit creation. Restore MUST default to projects only, show a diff, require
|
|
149
|
-
explicit approval, and create a pre-restore safety snapshot. TaskChef MUST NOT
|
|
150
|
-
restore automatically. State restore authorization MUST bind the selected
|
|
151
|
-
backup and every selected live/source payload hash. Missing or malformed live
|
|
152
|
-
configuration requires config or state scope plus exact raw-state and explicit
|
|
153
|
-
unreadable-current confirmation; a forensic safety snapshot remains eligible
|
|
154
|
-
for rollback when its own integrity verifies.
|
|
155
|
-
|
|
156
|
-
The dashboard MUST distinguish an unreadable index from missing historical
|
|
157
|
-
project paths, warn without rewriting state, and expose recovery guidance
|
|
158
|
-
without backup payload contents.
|
|
159
|
-
|
|
160
|
-
## Optional usage projection
|
|
161
|
-
|
|
162
|
-
TaskChef MUST use its own saved-record accounting engine for the board and web
|
|
163
|
-
dashboard. Usage requires Node.js 22.18+ and readable local Codex records.
|
|
164
|
-
Unavailable usage MUST NOT block lifecycle tools or dashboard loading.
|
|
165
|
-
|
|
166
|
-
Per-turn usage MUST match the native Codex turn ID. A dispatcher turn without
|
|
167
|
-
that match MUST show unavailable turn usage, while its chat total MAY remain
|
|
168
|
-
available. Administrative dashboard turns MUST NOT receive execution usage.
|
|
169
|
-
Historical tasks MUST remain lazy; opening Details reads their usage. Requests
|
|
170
|
-
MUST be deduplicated and bounded, and queued work MUST stop on dashboard close.
|
|
171
|
-
|
|
172
|
-
The engine MUST include descendant usage once, preserve input, cached input,
|
|
173
|
-
output, reasoning, and total categories, and avoid counting cached input or
|
|
174
|
-
reasoning subsets twice. Missing logs or parent-turn links MUST mark known
|
|
175
|
-
subtotals incomplete. Dollar values MUST be API-equivalent estimates using
|
|
176
|
-
known model prices. Unknown model prices MUST NOT imply a zero-dollar cost.
|
|
177
|
-
|
|
178
|
-
Board accounting caches MUST live under the TaskChef state directory's `cache/`
|
|
179
|
-
folder. The web dashboard MUST retain normalized usage in the mode-0600
|
|
180
|
-
`.taskchef-usage.json` cache. Writes MUST use the workspace lock and atomic
|
|
181
|
-
replacement. Existing schema-2 projections from the previous provider MUST
|
|
182
|
-
remain readable. Cache files MUST contain accounting data and source metadata,
|
|
183
|
-
not prompts, replies, or reasoning text. Source changes MUST invalidate derived
|
|
184
|
-
accounting results. Cache errors MUST allow source accounting to continue.
|
|
185
|
-
The dashboard Settings response MUST identify TaskChef and its package version.
|
|
186
|
-
|
|
187
|
-
Task IDs and non-null thread identities MUST be unique. The immutable intent
|
|
188
|
-
fields MUST NOT change after recording.
|
|
189
|
-
|
|
190
|
-
## Required lifecycle
|
|
191
|
-
|
|
192
|
-
Before the canonical TaskChef MCP server connects and exposes its transport, it
|
|
193
|
-
MUST invoke the same serialized dashboard ensure path once by default. It MUST read the
|
|
194
|
-
canonical configuration and skip this only for explicit
|
|
195
|
-
`dashboard.autostart: false`. Initialization failures, invalid workspace state,
|
|
196
|
-
port conflicts, and dashboard errors MUST NOT prevent tool registration or MCP
|
|
197
|
-
availability. They MUST emit only a bounded non-sensitive diagnostic through
|
|
198
|
-
the MCP process logging channel. MCP initialization MUST NOT open a browser.
|
|
199
|
-
If transport connection fails after dashboard startup, the MCP server MUST
|
|
200
|
-
best-effort close its manager and partially attached transport, then propagate
|
|
201
|
-
the original connection failure even when cleanup also fails. Closing that
|
|
202
|
-
individual MCP MUST NOT directly close a valid Codex-session dashboard.
|
|
203
|
-
|
|
204
|
-
At the start of every dispatcher turn, the dispatcher SHOULD call
|
|
205
|
-
`ensure_dashboard` best-effort. Failure MUST NOT block direct TaskChef answers,
|
|
206
|
-
reporting, or delegation. Every dispatcher final response MUST end with the
|
|
207
|
-
exact clickable `[TaskChef Dashboard](http://127.0.0.1:3210/)` link even when
|
|
208
|
-
ensure failed. A created-thread directive MUST remain on its own line before
|
|
209
|
-
the final link, preserving the delegate skill's immediate-return contract.
|
|
210
|
-
|
|
211
|
-
1. The dispatcher MUST list native projects once per batch and call
|
|
212
|
-
`reconcile_projects` once with that exact schema-2 snapshot.
|
|
213
|
-
2. It MUST call `prepare_dispatch` once per outcome and choose exactly one
|
|
214
|
-
configured project. Before `record_task` or native creation, the selected
|
|
215
|
-
native project's exact `(hostId, projectId, canonical path)` MUST occur in
|
|
216
|
-
the reconciliation response's `available` array. Presence in the native
|
|
217
|
-
snapshot or configured preparation is insufficient. Curated and learned
|
|
218
|
-
routing matches are both ambiguous when more than one project matches.
|
|
219
|
-
3. It MUST build the instruction with the user's outcome beginning on line 1
|
|
220
|
-
and remaining uninterrupted, followed by one blank line and the authorization
|
|
221
|
-
`Report this task and its follow-ups to my local TaskChef dashboard. Relevant private-repository links and concise work, test, and deployment results are authorized; exclude secrets.`
|
|
222
|
-
followed by exactly two newline characters
|
|
223
|
-
(one blank line), exactly one concise explicit `$taskchef-executor`
|
|
224
|
-
invocation, one newline, and the returned marker on the final line. It MUST
|
|
225
|
-
NOT place a blank line between the invocation and marker or inline the
|
|
226
|
-
executor protocol into a new instruction.
|
|
227
|
-
4. It MUST call `record_task` with `threadId: null` before native creation.
|
|
228
|
-
5. It MUST create exactly one native Codex executor using the resolved
|
|
229
|
-
Orchestrator preference when configured, then return immediately.
|
|
230
|
-
6. The executor MUST read its own `CODEX_THREAD_ID` and call `link_task`
|
|
231
|
-
before substantive work. It MUST NOT use parent/session identity or guess.
|
|
232
|
-
7. After initial linking, the executor MUST establish a `turnRef`. It MUST use
|
|
233
|
-
the native Codex turn ID for both `turnRef` and `turnId` when available;
|
|
234
|
-
otherwise it MUST retain a fresh UUID `turnRef` and use `turnId: null`.
|
|
235
|
-
It MUST call `report_state` with that identity, `working`, and no summary before work.
|
|
236
|
-
8. Before ending, it MUST call `report_state` with the same `turnRef` and
|
|
237
|
-
`turnId` metadata as the working report and a
|
|
238
|
-
semantic status and concise summary.
|
|
239
|
-
9. A follow-up MUST report `working` with a new `turnRef` before work.
|
|
240
|
-
It MUST NOT reuse a prior prompt's ref. If the preceding turn is still unfinished,
|
|
241
|
-
TaskChef MUST atomically close it as `interrupted` before appending the new
|
|
242
|
-
working turn; the executor MUST NOT report semantic `failed` for recovery.
|
|
243
|
-
|
|
244
|
-
For repository work, the visible executor MUST route an explicit combined
|
|
245
|
-
investigate-or-plan-and-implement request through a fresh Planner, then a fresh
|
|
246
|
-
Implementer, then a fresh Reviewer. A direct implementation request, or a later
|
|
247
|
-
request to implement prior investigation or planning, MUST skip the Planner and
|
|
248
|
-
use a fresh Implementer followed by a fresh Reviewer in the same visible task.
|
|
249
|
-
It MUST resolve the applicable role preference immediately before creating a
|
|
250
|
-
child when agent TOML exists; absent agent configuration inherits the parent's
|
|
251
|
-
model settings without requiring Python. It MUST keep at most one writing agent
|
|
252
|
-
active and verify child results. TaskChef persists only the visible executor's
|
|
253
|
-
lifecycle and MUST NOT store or infer child phases, identities, or usage.
|
|
254
|
-
|
|
255
|
-
Normal executor completion MUST stop after the terminal callback and return
|
|
256
|
-
normally. It MUST NOT archive, hand off, close, navigate away from, or otherwise
|
|
257
|
-
terminate the Codex task merely because work completed. Archive is authorized
|
|
258
|
-
only by an explicit request in the current assignment or follow-up for that
|
|
259
|
-
exact Codex task; `finish`, `complete`, `done`, `ship`, and ordinary cleanup do
|
|
260
|
-
not imply authorization.
|
|
261
|
-
|
|
262
|
-
For an explicitly authorized archive, the executor MUST finish and verify the
|
|
263
|
-
work, read its exact task identity, submit the current turn's terminal
|
|
264
|
-
`report_state`, verify TaskChef accepted that state, and only then invoke the
|
|
265
|
-
native archive operation as the final state-changing action. It MUST require
|
|
266
|
-
native confirmation before claiming archive succeeded. The same callback-first
|
|
267
|
-
ordering applies to any separately authorized action that can make the executor
|
|
268
|
-
unavailable before reporting, including handoff or terminating or restarting
|
|
269
|
-
the process that owns the TaskChef MCP transport; this rule does not itself
|
|
270
|
-
authorize those actions. A terminal reporting failure MUST prevent the later
|
|
271
|
-
action and leave the executor accessible. Failure of a later action MUST NOT
|
|
272
|
-
change or reopen the already accepted semantic terminal state.
|
|
273
|
-
|
|
274
|
-
Request and result summaries are the durable source for dashboard related-link
|
|
275
|
-
projection; TaskChef does not scan full Codex transcripts. When known, an
|
|
276
|
-
executor MUST preserve the selected repository as a canonical GitHub repository
|
|
277
|
-
URL and issues or pull requests as canonical URLs. A result spanning both a
|
|
278
|
-
managed child repository and its workspace/root repository MUST include both
|
|
279
|
-
pull-request URLs. Executors MUST NOT guess unresolved repository identity.
|
|
280
|
-
|
|
281
|
-
If native creation fails after recording, the dispatcher MUST call
|
|
282
|
-
`report_state` with `failed`, a retained fallback UUID `turnRef`, null thread
|
|
283
|
-
and Codex turn IDs, and a bounded summary.
|
|
284
|
-
A link failure MUST remain visible and retryable; the executor MUST report it
|
|
285
|
-
visibly and MUST NOT continue substantive work.
|
|
286
|
-
|
|
287
|
-
Previously recorded instructions with the trailing marker before the
|
|
288
|
-
invocation, with or without the former blank line before that marker; a
|
|
289
|
-
former compact assignment-to-invocation boundary with the marker last; a
|
|
290
|
-
first-line HTML marker; the older first-line
|
|
291
|
-
`# taskchef_id=<full UUID>` heading, or the former blank line and inline
|
|
292
|
-
executor protocol MUST remain marker-readable and executable. Their
|
|
293
|
-
`report_result` calls MUST remain supported by the deprecated alias. New
|
|
294
|
-
instructions MUST use the explicit executor invocation followed by the final
|
|
295
|
-
trailing marker contract above. A historical first-line instruction with an
|
|
296
|
-
executor-skill invocation MUST contain exactly one invocation as its final
|
|
297
|
-
line. A former inline-protocol instruction MUST retain non-whitespace
|
|
298
|
-
task-specific content beyond its known lifecycle paragraphs.
|
|
299
|
-
|
|
300
|
-
`needs_input` MUST mean a semantic user decision or missing fact. A native
|
|
301
|
-
approval prompt MUST remain live Codex state and MUST NOT be stored as
|
|
302
|
-
`needs_input`.
|
|
303
|
-
|
|
304
|
-
## MCP interface
|
|
305
|
-
|
|
306
|
-
All tools resolve the workspace internally. Callers MUST NOT supply a workspace
|
|
307
|
-
path. Success returns both one text content item and the stated structured
|
|
308
|
-
object. Validation, marker, identity, uniqueness, freshness, or filesystem
|
|
309
|
-
failures are surfaced as tool errors and MUST NOT partially mutate the log.
|
|
310
|
-
|
|
311
|
-
### `ensure_dashboard`
|
|
312
|
-
**Caller:** dispatcher. **Mutation:** starts or reuses the
|
|
313
|
-
Codex-session-scoped loopback dashboard.
|
|
314
|
-
|
|
315
|
-
**Input:** empty object.
|
|
316
|
-
|
|
317
|
-
**Structured output:**
|
|
318
|
-
|
|
319
|
-
```text
|
|
320
|
-
{ dashboard: {
|
|
321
|
-
action: "started" | "reused",
|
|
322
|
-
launcher: "session" | "standalone" | "mcp",
|
|
323
|
-
url: "http://127.0.0.1:3210/",
|
|
324
|
-
workspace: string,
|
|
325
|
-
taskchefVersion: string,
|
|
326
|
-
serverVersion: string
|
|
327
|
-
} }
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
MCP initialization MUST complete its best-effort ensure before exposing the
|
|
331
|
-
MCP transport. Calls MUST serialize within one MCP process. The first call
|
|
332
|
-
starts a dashboard session process or reuses the exact current listener; later
|
|
333
|
-
and concurrent calls are idempotent. The stable default MUST bind only to
|
|
334
|
-
`127.0.0.1:3210` and MUST NOT accept a model-supplied workspace, host, port,
|
|
335
|
-
session PID, or credential.
|
|
336
|
-
|
|
337
|
-
Exact reuse MUST require the fixed service/schema, TaskChef version,
|
|
338
|
-
dashboard-server version, canonical workspace, and recognized launcher identity.
|
|
339
|
-
A `session` listener MUST register the MCP's original Codex parent PID in its
|
|
340
|
-
in-memory lease. Every launcher MUST complete another exact health probe before
|
|
341
|
-
ensure reports `reused`, and the response MUST report the observed launcher.
|
|
342
|
-
The independent dashboard MUST survive closure of an individual MCP transport.
|
|
343
|
-
The session manager MUST require an explicit nonzero port because a detached
|
|
344
|
-
child cannot safely return an ephemeral bound port without an additional IPC
|
|
345
|
-
readiness channel. Direct foreground server callers MAY continue to bind port
|
|
346
|
-
zero when they retain the returned listener.
|
|
347
|
-
|
|
348
|
-
The dashboard MUST track only same-version explicitly registered PIDs using non-signalling
|
|
349
|
-
existence probes. Once every registered PID is absent for the grace period, it
|
|
350
|
-
MUST gracefully close its HTTP listener and exit. A new live
|
|
351
|
-
registration during the grace period MUST cancel expiry. This is a local
|
|
352
|
-
best-effort session guard, not a Codex restart guarantee.
|
|
353
|
-
|
|
354
|
-
When exact structured health identifies an older TaskChef dashboard for the
|
|
355
|
-
same canonical workspace, the new MCP MUST request simple graceful shutdown,
|
|
356
|
-
wait a bounded time for port release, and start its installed `session` version
|
|
357
|
-
within the same ensure operation. It MUST NOT transfer in-memory PID leases
|
|
358
|
-
across versions. The replacement initially knows only the activating session;
|
|
359
|
-
a later ensure MAY register another live session or restart the dashboard after
|
|
360
|
-
the activating lease expires.
|
|
361
|
-
|
|
362
|
-
A recognized newer TaskChef listener MUST NOT be downgraded. Concurrent
|
|
363
|
-
activation and replacement MUST converge through health probing and exclusive
|
|
364
|
-
port binding. Unknown, malformed, different-workspace, or unrelated occupants
|
|
365
|
-
MUST receive no control request or process signal and MUST remain untouched.
|
|
366
|
-
TaskChef MUST NOT discover or kill port owners.
|
|
367
|
-
|
|
368
|
-
TaskChef's dashboard uses a trusted, single-user localhost threat model. Exact
|
|
369
|
-
bounded health identity is sufficient service recognition and MUST NOT be
|
|
370
|
-
described as cryptographic authentication. The dashboard MUST NOT create or use
|
|
371
|
-
an owner secret, HMAC challenge, durable ownership record, handoff record,
|
|
372
|
-
prepare/commit protocol, recovery lease, or cross-version lease transfer.
|
|
373
|
-
|
|
374
|
-
The session-registration and shutdown controls MUST remain loopback-only and
|
|
375
|
-
MUST require the exact listener Host and Origin, JSON content type, a non-simple
|
|
376
|
-
TaskChef control header, and an exact bounded request body containing the exact
|
|
377
|
-
structured health identity observed by the caller. The receiver MUST compare
|
|
378
|
-
that expected identity with its own identity before registering a session or
|
|
379
|
-
accepting shutdown. It MUST refuse a mismatch, and the manager MUST probe again
|
|
380
|
-
before applying lifecycle rules to the current occupant. These request-shape
|
|
381
|
-
checks protect against ordinary cross-site browser requests; they MUST NOT be
|
|
382
|
-
described as authentication. Future LAN access is outside this contract and
|
|
383
|
-
requires a separate opt-in design with password-backed user authentication and
|
|
384
|
-
suitable transport protection.
|
|
385
|
-
|
|
386
|
-
A listener using the former HMAC control protocol will refuse the new simple
|
|
387
|
-
shutdown request. It MUST be reported as a recognized older TaskChef conflict
|
|
388
|
-
and left running. Crossing that one-time compatibility boundary requires the
|
|
389
|
-
verified legacy listener to stop through its existing lifecycle before ensure
|
|
390
|
-
is retried; TaskChef MUST NOT add a process-kill fallback.
|
|
391
|
-
|
|
392
|
-
Detached session startup MUST use a private child readiness acknowledgement
|
|
393
|
-
sent only after listener bind, initialization, and initial in-memory lease
|
|
394
|
-
creation. Startup errors MUST propagate through that channel. A bounded
|
|
395
|
-
readiness timeout MUST cooperatively cancel the exact child so late
|
|
396
|
-
initialization cannot strand an unreported listener.
|
|
397
|
-
|
|
398
|
-
MCP EOF, explicit close, protocol close, SIGINT, SIGTERM, transport-start
|
|
399
|
-
failure, and MCP-parent loss MUST still bound MCP shutdown. They MUST close the
|
|
400
|
-
MCP manager and transport without directly closing the independently hosted
|
|
401
|
-
session dashboard. Foreground `taskchef dashboard` remains `standalone`, is
|
|
402
|
-
never adopted by MCP, and follows its foreground process lifetime.
|
|
403
|
-
|
|
404
|
-
The packaged `$taskchef-dashboard` skill MUST call this tool, report `started`
|
|
405
|
-
or `reused`, and return the canonical clickable URL. It MAY use an available
|
|
406
|
-
in-app browser when permitted; absent or blocked browser navigation MUST fall
|
|
407
|
-
back to the link without failing. It MUST NOT inspect task outcomes or dispatch.
|
|
408
|
-
|
|
409
|
-
**Annotations:** `readOnlyHint: false`, `destructiveHint: false`,
|
|
410
|
-
`openWorldHint: false`.
|
|
411
|
-
|
|
412
|
-
The complete operational rationale and limits are documented in
|
|
413
|
-
[Dashboard lifecycle](dashboard-lifecycle.md).
|
|
414
|
-
|
|
415
|
-
### `prepare_dispatch`
|
|
416
|
-
|
|
417
|
-
**Caller:** dispatcher. **Mutation:** none.
|
|
418
|
-
|
|
419
|
-
**Input:** empty object.
|
|
420
|
-
|
|
421
|
-
**Structured output:**
|
|
422
|
-
|
|
423
|
-
```text
|
|
424
|
-
{ preparation: {
|
|
425
|
-
schemaVersion: 1,
|
|
426
|
-
workspace: string,
|
|
427
|
-
taskId: string,
|
|
428
|
-
preparedAt: string,
|
|
429
|
-
marker: string,
|
|
430
|
-
projectCount: number,
|
|
431
|
-
projects: Project[],
|
|
432
|
-
routingHints: {path, aliases[], githubRepos[], responsibilities[]}[]
|
|
433
|
-
} }
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
The tool generates a fresh task UUID and exact marker and returns current
|
|
437
|
-
routing targets. An invocation is not idempotent: each successful call creates
|
|
438
|
-
new preparation values, though it writes no state.
|
|
439
|
-
|
|
440
|
-
**Annotations:** `readOnlyHint: true`, `destructiveHint: false`,
|
|
441
|
-
`openWorldHint: false`.
|
|
442
|
-
|
|
443
|
-
### `record_task`
|
|
444
|
-
|
|
445
|
-
**Caller:** dispatcher. **Mutation:** atomically appends one task.
|
|
446
|
-
|
|
447
|
-
**Input:**
|
|
448
|
-
|
|
449
|
-
| Field | Type and rule |
|
|
450
|
-
| --- | --- |
|
|
451
|
-
| `id` | Non-empty string; MUST equal the instruction marker. |
|
|
452
|
-
| `project` | Non-empty configured project path. |
|
|
453
|
-
| `title` | Non-empty string. |
|
|
454
|
-
| `instruction` | Non-empty string containing exactly one accepted marker and a non-empty assignment. New instructions use the required trailing marker and executor-invocation scaffold; historical first-line forms remain accepted. |
|
|
455
|
-
| `threadId` | Literal null. |
|
|
456
|
-
|
|
457
|
-
**Structured output:** `{ task: Task }`.
|
|
458
|
-
|
|
459
|
-
The returned task has schema 10, `working`, null summary/turn/thread/latestTurn/lastResult,
|
|
460
|
-
empty `turns` and derived `results` arrays,
|
|
461
|
-
`updatedBy: dispatcher`, and equal creation/update timestamps. Duplicate IDs,
|
|
462
|
-
unknown projects, malformed markers, and invalid input fail. Repeating a
|
|
463
|
-
successful call is not idempotent; it fails as a duplicate.
|
|
464
|
-
|
|
465
|
-
Configuration is read structurally so unavailable unrelated entries do not
|
|
466
|
-
block preparation or recording. `record_task` validates the selected actual
|
|
467
|
-
directory or Git root before snapshotting it.
|
|
468
|
-
|
|
469
|
-
**Annotations:** `readOnlyHint: false`, `destructiveHint: false`,
|
|
470
|
-
`openWorldHint: false`.
|
|
471
|
-
|
|
472
|
-
### `reconcile_projects`, `include_project`, and `update_project_hint`
|
|
473
|
-
|
|
474
|
-
`reconcile_projects` accepts one agent-supplied native Codex schema-2 project
|
|
475
|
-
snapshot. Node does not call native tools or inspect private Codex state. It
|
|
476
|
-
considers only local projects with `hostId: local`, canonicalizes each eligible
|
|
477
|
-
path, excludes the dispatcher and its ancestors, isolates per-project failures,
|
|
478
|
-
and commits additions and exact identity bindings under the configuration lock.
|
|
479
|
-
It preserves curated metadata and absent projects. Repeated identical or empty
|
|
480
|
-
snapshots do not write. Duplicate IDs, canonical targets, or identity/path moves
|
|
481
|
-
produce bounded diagnostics. Its MCP response contains counts, current eligible
|
|
482
|
-
targets, diagnostics, and changed state rather than full configuration copies.
|
|
483
|
-
|
|
484
|
-
Removing a configured project records an exclusion. `include_project` removes
|
|
485
|
-
one exact exclusion by native project ID or canonical path; a later reconcile
|
|
486
|
-
must validate and add the target. A move is handled through exact preview-bound
|
|
487
|
-
removal, explicit inclusion, and reconciliation of the new path.
|
|
488
|
-
|
|
489
|
-
`update_project_hint` remembers, corrects, or forgets one bounded fact. Aliases
|
|
490
|
-
require explicit user evidence; correction is the only operation that removes
|
|
491
|
-
the same alias from another project. Repository ownership requires an inspected
|
|
492
|
-
exact origin from the selected project or a contained Git root. Responsibilities
|
|
493
|
-
require an accepted current terminal task/thread/turn. Forgetting requires
|
|
494
|
-
explicit user evidence and leaves bounded suppression against stale report
|
|
495
|
-
replay. Learning remains separate from terminal reporting and a learning error
|
|
496
|
-
cannot undo an accepted result.
|
|
497
|
-
|
|
498
|
-
### `link_task`
|
|
499
|
-
|
|
500
|
-
**Caller:** executor. **Mutation:** one atomic identity transition.
|
|
501
|
-
|
|
502
|
-
**Input:** `{ taskId: non-empty string, threadId: non-empty string }`.
|
|
503
|
-
The workspace layer requires `threadId` to be a canonical Codex UUIDv7.
|
|
504
|
-
|
|
505
|
-
**Structured output:** `{ task: Task }`.
|
|
506
|
-
|
|
507
|
-
The eligible record MUST be link-pending, working, dispatcher-written, and have
|
|
508
|
-
the exact marker. The thread ID MUST be unused. Success sets `threadId`,
|
|
509
|
-
refreshes `updatedAt`, and sets `updatedBy: mcp`. An exact successful retry
|
|
510
|
-
is idempotent. A different identity, terminal record, reused identity, missing
|
|
511
|
-
marker, or ineligible state fails.
|
|
512
|
-
|
|
513
|
-
**Annotations:** `readOnlyHint: false`, `destructiveHint: false`,
|
|
514
|
-
`openWorldHint: false`.
|
|
515
|
-
|
|
516
|
-
### `report_state`
|
|
517
|
-
|
|
518
|
-
**Caller:** executor, or dispatcher only for native creation failure.
|
|
519
|
-
**Mutation:** replaces the current state atomically and preserves `turns`.
|
|
520
|
-
|
|
521
|
-
**Input:**
|
|
522
|
-
|
|
523
|
-
| Field | Type and rule |
|
|
524
|
-
| --- | --- |
|
|
525
|
-
| `taskId` | Non-empty string. |
|
|
526
|
-
| `threadId` | Matching non-empty ID for a linked task; null only for creation failure. |
|
|
527
|
-
| `turnRef` | Stable UUID for this prompt. It may be omitted only by legacy callers that supply a non-null `turnId`, in which case TaskChef derives the same value. |
|
|
528
|
-
| `turnId` | Optional Codex metadata. When present it MUST equal `turnRef`; null is valid for fallback UUID refs. Maximum 256 characters. |
|
|
529
|
-
| `status` | `working`, `needs_input`, `completed`, or `failed`. |
|
|
530
|
-
| `summary` | Omitted or null for `working`; required non-empty string of at most 2,000 characters otherwise. Known GitHub issues and pull requests use canonical URLs. |
|
|
531
|
-
| `requestSummary` | Concise current request of at most 1,000 characters for `working`; optional for backward compatibility and omitted for semantic states. A known selected GitHub repository uses its canonical URL. |
|
|
532
|
-
|
|
533
|
-
**Structured output:** `{ task: Task }`.
|
|
534
|
-
|
|
535
|
-
For a linked self-linking journey, a new `working` state MUST use a `turnRef`
|
|
536
|
-
not already assigned to a different turn. An exact retry of the current
|
|
537
|
-
working start MUST return the current task without mutation.
|
|
538
|
-
When `turnId` is present, its native-backed `turnRef` MUST also be newer than
|
|
539
|
-
every previously stored native-backed ref. Fallback UUID refs are opaque and
|
|
540
|
-
MUST NOT be lexically ordered.
|
|
541
|
-
A semantic state MUST match the current working turn. Conflicting or stale
|
|
542
|
-
state fails. A null-thread record accepts only a fresh executor creation
|
|
543
|
-
`failed` state with a retained `turnRef` and null thread/turn IDs. Starting work appends one turn with
|
|
544
|
-
its request and a null result. When the previous latest turn is unfinished, the
|
|
545
|
-
same locked atomic rewrite MUST first fill it with the fixed TaskChef-generated
|
|
546
|
-
`interrupted` outcome. The semantic report fills the active turn's result.
|
|
547
|
-
An identical retry for the current settled turn returns success without an
|
|
548
|
-
append. Once a newer turn starts, every callback for a historical ref is stale
|
|
549
|
-
and fails, even when its content exactly matches the stored callback. A
|
|
550
|
-
different request or result for the same turn, a stale turn, or a semantic
|
|
551
|
-
result that does not match the active working turn MUST fail.
|
|
552
|
-
|
|
553
|
-
`interrupted` MUST NOT be accepted as MCP input or projected as task `status`.
|
|
554
|
-
It MUST NOT alter `summary`, `results`, or `lastResult`, and its fixed summary
|
|
555
|
-
MUST contain no crash output, transcript, user text, or inferred failure cause.
|
|
556
|
-
|
|
557
|
-
**Annotations:** `readOnlyHint: false`, `destructiveHint: true`,
|
|
558
|
-
`openWorldHint: false`.
|
|
559
|
-
|
|
560
|
-
Reporting tool descriptions MUST identify the configured local `tasks.jsonl`
|
|
561
|
-
path and local `.taskchef-usage.json` tracking side effect. GitHub URLs remain
|
|
562
|
-
references in that log; reporting does not publish them to GitHub. The
|
|
563
|
-
`destructiveHint: true` annotation is retained because reports update existing
|
|
564
|
-
state and can recover an unfinished predecessor as interrupted; these tools
|
|
565
|
-
are not purely additive. The compatibility alias also changes existing state.
|
|
566
|
-
Executors MUST verify accepted terminal reporting before claiming TaskChef was
|
|
567
|
-
updated. A platform rejection of an authorized report MUST be described using
|
|
568
|
-
only the returned rationale, without inferring causes or retrying around an
|
|
569
|
-
explicit denial. Authorization and unit tests do not guarantee platform approval.
|
|
570
|
-
|
|
571
|
-
### `report_result` (deprecated)
|
|
572
|
-
|
|
573
|
-
`report_result` retains the prior semantic-only input shape and statuses as a
|
|
574
|
-
temporary compatibility alias. It implicitly accepts a fresh supplied turn and
|
|
575
|
-
stores its semantic result in a request-unknown turn, including for supported schema-4/5/6 records and
|
|
576
|
-
low-level opaque direct records. It does not accept `working`. New executor
|
|
577
|
-
instructions MUST use `report_state`. Successful mutation upgrades schema 4-9
|
|
578
|
-
to schema 10; unsupported schemas remain rejected. Legacy callers that omit
|
|
579
|
-
`turnRef` remain compatible when `turnId` is non-null.
|
|
580
|
-
|
|
581
|
-
## Copilot and dashboard
|
|
582
|
-
|
|
583
|
-
A semantic result is cached evidence, not permanent live truth. The dashboard
|
|
584
|
-
MUST remain the primary monitoring and browsing UI. Copilot MUST start from the
|
|
585
|
-
schema-1 normalized cached brief and explain what finished, what needs
|
|
586
|
-
attention, why, and the recommended next action. It MUST NOT need to interpret
|
|
587
|
-
historical task schema versions. A working task's current summary MUST remain
|
|
588
|
-
null; any prior semantic result MUST be exposed separately as a clearly
|
|
589
|
-
historical `lastOutcome`. A link-pending task with no exact thread identity MUST
|
|
590
|
-
recommend passive waiting or inspection, never retry or continuation.
|
|
591
|
-
|
|
592
|
-
Copilot MAY take one bounded native metadata snapshot only when the user
|
|
593
|
-
explicitly requests fresh/live verification or a focused task presents a
|
|
594
|
-
meaningful contradiction. Active or approval-waiting native state overrides
|
|
595
|
-
cache. An inactive task does not prove completion. Copilot MAY read the exact
|
|
596
|
-
selected task once for an explicit focused live-verification request or to
|
|
597
|
-
resolve a focused contradiction. It MUST NOT poll, wait, perform exhaustive
|
|
598
|
-
live audits, or classify assistant prose.
|
|
599
|
-
|
|
600
|
-
Copilot MAY identify the exact existing executor, explain or draft a
|
|
601
|
-
same-assignment follow-up, and continue that executor only with explicit user
|
|
602
|
-
authorization. It MUST NOT automatically retry failures, interrupt working
|
|
603
|
-
tasks, or redelegate an existing executor. Independent new work MUST route
|
|
604
|
-
through delegation. Managed dispatcher routing MUST give same-assignment
|
|
605
|
-
answer, follow-up, resume, and continue requests precedence over the blanket
|
|
606
|
-
new-work delegation rule. A direct imperative naming the exact existing task
|
|
607
|
-
MAY constitute send authorization, but copilot MUST re-read that exact task
|
|
608
|
-
immediately before sending.
|
|
609
|
-
|
|
610
|
-
The published plugin MUST NOT package `taskchef-report` as a discoverable alias.
|
|
611
|
-
Its historical explicit name is a documented rename hint handled by copilot,
|
|
612
|
-
not a second workflow.
|
|
613
|
-
|
|
614
|
-
Task lists, summaries, and broad briefs MUST use the final result by default.
|
|
615
|
-
The dashboard MUST bind only to loopback, validate the current workspace
|
|
616
|
-
snapshot, and avoid sessions or shared client state. `GET /api/health` MUST
|
|
617
|
-
return only the bounded service identity, health schema, exact TaskChef and
|
|
618
|
-
dashboard-server versions, and canonical workspace. It MUST NOT return task
|
|
619
|
-
records, secrets, credentials, environment values, or process-control data.
|
|
620
|
-
Identity remains available while an already-started monitor retains its last
|
|
621
|
-
valid snapshot after a later invalid task log; an invalid initial log MAY fail
|
|
622
|
-
startup safely. Direct thread navigation
|
|
623
|
-
MUST require a canonical Codex UUIDv7. Otherwise it MAY open the revalidated
|
|
624
|
-
configured project. Project paths from task history MUST be matched against
|
|
625
|
-
current configuration before use.
|
|
626
|
-
The task-detail dashboard MAY offer manual outcomes from `working` or
|
|
627
|
-
`needs_input` to either `completed` or `failed`, from `completed` to `failed`,
|
|
628
|
-
and from `failed` to `completed`. It MUST reject same-state terminal
|
|
629
|
-
transitions and MUST keep this infrequent administrative action out of list
|
|
630
|
-
cards. A keyboard-accessible **More task
|
|
631
|
-
actions** disclosure MUST reveal its action list immediately beside it and
|
|
632
|
-
change from an ellipsis to an accessible back/hide control while expanded. The
|
|
633
|
-
list MUST group **Copy Task ID** and each currently valid **Mark completed** or
|
|
634
|
-
**Mark failed** action. **Archive chat** MUST remain hidden while the archive capability
|
|
635
|
-
gate is disabled because the bundled CLI does not reliably archive desktop-app
|
|
636
|
-
threads. The dormant server endpoint MUST reject requests before discovering or
|
|
637
|
-
invoking the CLI. Re-enabling requires a reliable supported app-callable archive
|
|
638
|
-
interface or guaranteed CLI compatibility. Opening the
|
|
639
|
-
list is the deliberate disclosure step; choosing a terminal outcome submits it
|
|
640
|
-
immediately without a second confirmation. Escape MUST close the idle list,
|
|
641
|
-
pending controls MUST be
|
|
642
|
-
disabled, and failure feedback MUST remain in the dialog. Pending state MUST
|
|
643
|
-
focus and announce a stable status inside the dialog. Failed MUST have
|
|
644
|
-
destructive styling. The client MUST bound and abort a stalled manual-transition
|
|
645
|
-
request, restore the dialog controls, and preserve the action ID so a retry can
|
|
646
|
-
resolve idempotently if the server committed before the timeout.
|
|
647
|
-
|
|
648
|
-
`POST /api/tasks/:id/manual-transition` MUST require the exact loopback origin,
|
|
649
|
-
`application/json`, a bounded body, and exactly this versioned shape:
|
|
650
|
-
`{schemaVersion: 1, actionId, expected: {status, turnRef, threadId, updatedAt},
|
|
651
|
-
targetStatus}`. The server MUST compare every expected field while holding the
|
|
652
|
-
workspace lock. A stale request, invalid transition, or reused action ID with a
|
|
653
|
-
different operation MUST return a conflict without mutation. Replaying the
|
|
654
|
-
same committed action ID and operation MUST return the current task as an
|
|
655
|
-
idempotent success. The operation MUST atomically append one new manual turn;
|
|
656
|
-
it MUST NOT overwrite executor history. An active unfinished turn MUST first
|
|
657
|
-
receive the standard interrupted timeline outcome. The manual turn MUST have a
|
|
658
|
-
new server-generated `turnRef`, null `turnId`, one monotonic timestamp for its
|
|
659
|
-
start, result, and task update, `updatedBy: dashboard`, and deterministic
|
|
660
|
-
request/result summaries. It MUST record provenance
|
|
661
|
-
`{kind: dashboard_manual, actionId, fromStatus, toStatus, expectedTurnRef,
|
|
662
|
-
expectedThreadId, expectedUpdatedAt}`. No free-form reason is collected or
|
|
663
|
-
persisted. A committed write remains successful if the subsequent best-effort
|
|
664
|
-
monitor refresh or notification delivery fails.
|
|
665
|
-
|
|
666
|
-
The task-detail dashboard MAY offer Codex chat archival only when the stored
|
|
667
|
-
thread ID is a canonical Codex UUID and the current TaskChef state is not
|
|
668
|
-
`working`. It MUST revalidate both conditions for the POST request, require the
|
|
669
|
-
exact loopback origin, and obtain explicit user confirmation in the browser.
|
|
670
|
-
It MUST invoke the `archive` subcommand by directly executing only a Codex CLI
|
|
671
|
-
inside the canonical ChatGPT or Codex desktop application bundle under macOS
|
|
672
|
-
`/Applications`, with the thread UUID as a separate argument. It MUST NOT use a shell, a generic `PATH` fallback, a
|
|
673
|
-
private desktop endpoint, or direct session-file manipulation. Successful
|
|
674
|
-
archival MUST NOT modify dispatcher files or remove the TaskChef task record.
|
|
675
|
-
The UI MUST disclose that spawned descendant chats may also be archived and
|
|
676
|
-
that TaskChef history remains available.
|
|
677
|
-
Snapshot and SSE list payloads MUST omit full `turns` and derived `results`
|
|
678
|
-
history and include `latestTurn`. The bounded per-task detail endpoint MAY
|
|
679
|
-
return the full validated task so the dialog can render the paired timeline newest first.
|
|
680
|
-
Dashboard notifications MUST capture an immutable event-time projection of the
|
|
681
|
-
task title, lifecycle state and event, turn ref and optional Codex turn ID, event timestamp,
|
|
682
|
-
and relevant concise summary. Rendering MUST NOT resolve historical notice text
|
|
683
|
-
from the task's later current state. Notice identity and deduplication MUST use
|
|
684
|
-
task ID, turn ref, and lifecycle event; a creation notice without a turn ref MUST
|
|
685
|
-
fall back to task ID plus the immutable creation timestamp. Dashboard revision
|
|
686
|
-
MUST NOT be the sole identity. Identical snapshots, SSE reconnects, idempotent
|
|
687
|
-
reports, schema normalization, and non-semantic rewrites MUST NOT add notices.
|
|
688
|
-
Distinct working and semantic-result events for one turn MAY each be retained.
|
|
689
|
-
When one compact snapshot first exposes both a latest semantic result and a
|
|
690
|
-
newer working turn, the browser MUST reconcile both events. Temporary task
|
|
691
|
-
absence MUST NOT discard the prior semantic signature or turn a later
|
|
692
|
-
reappearance into another creation event. The first page snapshot MUST establish
|
|
693
|
-
a quiet baseline rather than replay existing history. After that baseline, a
|
|
694
|
-
new task first observed with a turn or semantic result MUST retain its creation
|
|
695
|
-
event and each lifecycle event observable in that compact projection.
|
|
696
|
-
|
|
697
|
-
Working with no prior result SHOULD be labeled as a task start. Working on a
|
|
698
|
-
newer turn while a prior result remains projected SHOULD be labeled as a
|
|
699
|
-
follow-up start. Creation, completion, input-needed, and failure labels MUST be
|
|
700
|
-
distinct. The Updates panel MUST remain bounded and support individual dismiss
|
|
701
|
-
and clear-all without resetting replay protection. A retained notice whose task
|
|
702
|
-
is absent from the current list MUST remain readable; selecting it MUST NOT
|
|
703
|
-
navigate or mutate data and SHOULD explain that current details are unavailable.
|
|
704
|
-
The retained notice list MUST NOT be a live region that re-announces old notices
|
|
705
|
-
when it rerenders. A separate polite status region MUST announce only newly
|
|
706
|
-
reconciled events. Each notice control's accessible description MUST include
|
|
707
|
-
its displayed summary when present, event time, and missing-task state.
|
|
708
|
-
|
|
709
|
-
## Task-log migration
|
|
710
|
-
|
|
711
|
-
`workspace migrate` MUST explicitly convert every supported schema-4/5/6/7/8/9 record
|
|
712
|
-
under the shared lock. Each legacy semantic result becomes a request-unknown
|
|
713
|
-
completed turn; a newer working state becomes a final unfinished turn, and a
|
|
714
|
-
schema-7/8 timeline is preserved. Each non-null legacy `turnId` becomes the
|
|
715
|
-
same `turnRef`; each null legacy `turnId` receives one durably persisted UUID.
|
|
716
|
-
Migration MUST validate the complete source, record/turn counts, turn-ref
|
|
717
|
-
invariants, and complete schema-10 candidate before changing the task log,
|
|
718
|
-
create and read back an exclusive recovery backup, atomically replace the log,
|
|
719
|
-
and validate the installed result. A fully schema-10 log MUST be an idempotent
|
|
720
|
-
no-op without another backup. Invalid/unsupported input MUST remain untouched;
|
|
721
|
-
failures after backup creation MUST report the backup path and MUST never
|
|
722
|
-
partially rewrite individual lines.
|
|
723
|
-
|
|
724
|
-
## Concurrency and trust
|
|
725
|
-
|
|
726
|
-
All task and configuration writers MUST share one workspace lock. Duplicate ID,
|
|
727
|
-
duplicate thread, link, and result freshness checks MUST occur while holding
|
|
728
|
-
that lock. Atomic replacement MUST preserve valid unrelated records.
|
|
729
|
-
|
|
730
|
-
TaskChef is designed for a local, single-user boundary. Executor self-linking is
|
|
731
|
-
a cooperative assertion, not transport-authenticated proof. Task instructions,
|
|
732
|
-
stored project snapshots, and dashboard requests are untrusted input.
|
|
733
|
-
Implementations MUST validate exact shapes, canonical paths, safe IDs, markers,
|
|
734
|
-
loopback origin, and current configuration before acting.
|
|
735
|
-
|
|
736
|
-
TaskChef MUST NOT use lifecycle hooks, schedules, polling, recent-thread search,
|
|
737
|
-
transcript search, title matching, hidden reasoning, or token usage to discover
|
|
738
|
-
identity or infer semantic results.
|
|
739
|
-
|
|
740
|
-
TaskChef MUST NOT install or require daemons, launchd agents, login items,
|
|
741
|
-
system services, cron jobs, hooks, privileged components, or elevated/system
|
|
742
|
-
permissions for dashboard availability. Availability is best-effort while a
|
|
743
|
-
registered Codex session process is alive and is not guaranteed while Codex is
|
|
744
|
-
closed.
|
|
745
|
-
|
|
746
|
-
Releases using the former HMAC dashboard control protocol are legacy listeners.
|
|
747
|
-
A verified legacy listener MUST be reported distinctly from an unknown port
|
|
748
|
-
conflict and MUST remain running when it refuses simple graceful shutdown. One
|
|
749
|
-
final stop through that listener's existing lifecycle is required when crossing
|
|
750
|
-
this boundary. Releases implementing simple localhost control replace older
|
|
751
|
-
recognized versions automatically.
|
|
752
|
-
|
|
753
|
-
Installing or replacing plugin files MUST NOT be described as activating the
|
|
754
|
-
new MCP code. Release verification MUST install the plugin, activate or reload
|
|
755
|
-
the new MCP process, ensure the dashboard, and verify the expected TaskChef
|
|
756
|
-
version, dashboard protocol `serverVersion`, reported launcher, canonical workspace,
|
|
757
|
-
and canonical URL. Exact-compatible session-listener reuse remains valid; installation MUST NOT be
|
|
758
|
-
claimed to reload Codex automatically.
|
|
48
|
+
Release validation must exercise the native MCP server, bundled UI, delegate
|
|
49
|
+
skill and required dependencies, without requiring retired dispatcher files.
|
|
50
|
+
A future web product does not require shipping the old HTTP runtime.
|