taskchef 0.0.1 → 1.0.1
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/BACKLOG.md +67 -0
- package/README.md +156 -3
- package/SPEC.md +310 -0
- package/assets/AGENTS.md.template +18 -0
- package/bin/taskchef.js +7 -2
- package/index.js +23 -3
- package/package.json +20 -5
- package/skills/taskchef-bootstrap/SKILL.md +50 -0
- package/skills/taskchef-bootstrap/agents/openai.yaml +4 -0
- package/skills/taskchef-delegate/SKILL.md +43 -0
- package/skills/taskchef-delegate/agents/openai.yaml +4 -0
- package/skills/taskchef-reconcile/SKILL.md +35 -0
- package/skills/taskchef-reconcile/agents/openai.yaml +4 -0
- package/src/cli.js +303 -0
- package/src/workspace.js +882 -0
package/BACKLOG.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# TaskChef backlog
|
|
2
|
+
|
|
3
|
+
This document contains capabilities intentionally excluded from the v1 MVP.
|
|
4
|
+
`SPEC.md` is the canonical v1 contract.
|
|
5
|
+
|
|
6
|
+
## Task activity and automatic reporting
|
|
7
|
+
|
|
8
|
+
- Determine whether Codex hook `session_id` reliably maps to a recorded task
|
|
9
|
+
`threadId`.
|
|
10
|
+
- Evaluate task-specific hooks without inferring ownership from project path.
|
|
11
|
+
- Evaluate an explicit executor callback such as `taskchef task report`.
|
|
12
|
+
- Decide how delegated tasks can safely update the data workspace across Codex
|
|
13
|
+
filesystem boundaries.
|
|
14
|
+
- Add automatic finish signals only after task attribution is proven reliable.
|
|
15
|
+
- Design event ordering, deduplication, cursors, and replay semantics before
|
|
16
|
+
introducing `events.jsonl`.
|
|
17
|
+
|
|
18
|
+
## Reconciliation and continuity
|
|
19
|
+
|
|
20
|
+
- Add event-driven, scheduled, or background reconciliation only if interactive
|
|
21
|
+
reconciliation proves insufficient.
|
|
22
|
+
- Evaluate heartbeat behavior, restart recovery, and recovery after the
|
|
23
|
+
dispatcher task is deleted.
|
|
24
|
+
- Add a reconciliation cursor only when repeated full snapshots become costly
|
|
25
|
+
or incorrect.
|
|
26
|
+
- Determine whether thread status alone is sufficient after Codex or machine
|
|
27
|
+
restarts.
|
|
28
|
+
|
|
29
|
+
## Grouping and history
|
|
30
|
+
|
|
31
|
+
- Add dispatch or run records only when batch cancellation, aggregate status,
|
|
32
|
+
replay, or decomposition history has a concrete use case.
|
|
33
|
+
- Decide whether and how to retain the original broad prompt.
|
|
34
|
+
- Add archival and retention policies for old task records.
|
|
35
|
+
|
|
36
|
+
## V2: remote connection projects
|
|
37
|
+
|
|
38
|
+
- Import remote connection projects returned by the native project-list tool.
|
|
39
|
+
- Persist the native `projectId` and `hostId` needed to distinguish identical
|
|
40
|
+
paths on different hosts and route task creation.
|
|
41
|
+
- Re-resolve stored native identities against the project list before every
|
|
42
|
+
dispatch instead of assuming they remain valid indefinitely.
|
|
43
|
+
- Validate remote paths and Git state through native host-aware project data;
|
|
44
|
+
do not run local filesystem validation against a remote path.
|
|
45
|
+
- Persist enough host context with delegated tasks to reconcile remote threads
|
|
46
|
+
reliably without arbitrary task discovery.
|
|
47
|
+
- Define unavailable-host, renamed-project, moved-path, and stale-identity
|
|
48
|
+
behavior before enabling remote dispatch.
|
|
49
|
+
- Evaluate worktrees and isolated execution for concurrent tasks in one
|
|
50
|
+
project.
|
|
51
|
+
- Define conflict handling when several tasks modify the same checkout.
|
|
52
|
+
|
|
53
|
+
## Data model extensions
|
|
54
|
+
|
|
55
|
+
- Add richer result fields only when real integrations require them.
|
|
56
|
+
- Evaluate structured verification, artifacts, commits, and completion outcome
|
|
57
|
+
fields.
|
|
58
|
+
- Support multiple executor threads for one logical task if needed.
|
|
59
|
+
- Define schema migrations and compatibility rules after the first persisted
|
|
60
|
+
v1 records exist.
|
|
61
|
+
|
|
62
|
+
## Integrations and distribution
|
|
63
|
+
|
|
64
|
+
- Add GitHub automation beyond storing PR and issue URLs.
|
|
65
|
+
- Evaluate automatic project discovery instead of an explicit configured list.
|
|
66
|
+
- Consider npm registry publication only after the GitHub-source installation
|
|
67
|
+
and local managed-checkout workflows are stable.
|
package/README.md
CHANGED
|
@@ -1,7 +1,160 @@
|
|
|
1
|
-
#
|
|
1
|
+
# TaskChef
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TaskChef is a non-blocking interactive dispatcher for visible Codex tasks. It
|
|
4
|
+
keeps a data-only workspace, routes independent assignments to real Codex
|
|
5
|
+
tasks, records their latest reconciled state, and returns control immediately.
|
|
6
|
+
|
|
7
|
+
The canonical contract is [SPEC.md](SPEC.md). Deferred ideas are in
|
|
8
|
+
[BACKLOG.md](BACKLOG.md).
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
TaskChef requires Node.js 18 or newer and Git.
|
|
13
|
+
|
|
14
|
+
Install the CLI and its bundled skills from npm:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm install --global taskchef
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then initialize a dispatcher workspace. Initialization links the three bundled
|
|
21
|
+
TaskChef skills into that workspace; no separate skill installation is needed.
|
|
4
22
|
|
|
5
23
|
```sh
|
|
6
|
-
|
|
24
|
+
taskchef workspace init --workspace <workspace>
|
|
25
|
+
taskchef doctor --workspace <workspace>
|
|
7
26
|
```
|
|
27
|
+
|
|
28
|
+
Contributors working from a source checkout can run `node bin/taskchef.js`
|
|
29
|
+
directly; this managed skills workspace installs the checkout CLI and skills
|
|
30
|
+
with symlinks. To install an unreleased revision, use
|
|
31
|
+
`npm install --global github:favoyang/taskchef`.
|
|
32
|
+
|
|
33
|
+
## Workspace
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
AGENTS.md
|
|
37
|
+
taskchef.json
|
|
38
|
+
.agents/skills/taskchef-bootstrap -> <source>/skills/taskchef-bootstrap
|
|
39
|
+
.agents/skills/taskchef-delegate -> <source>/skills/taskchef-delegate
|
|
40
|
+
.agents/skills/taskchef-reconcile -> <source>/skills/taskchef-reconcile
|
|
41
|
+
tasks/<task-id>/task.json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Create or repair the managed scaffold without supplying configuration:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
taskchef workspace init --workspace <workspace>
|
|
48
|
+
taskchef doctor --workspace <workspace>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Initialization is idempotent. It creates an empty configuration when missing
|
|
52
|
+
and preserves existing configured projects.
|
|
53
|
+
|
|
54
|
+
## Projects
|
|
55
|
+
|
|
56
|
+
Add one project. Git status, the exact Git root, and a canonical GitHub origin
|
|
57
|
+
are detected automatically:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
taskchef project add /workspace/payments \
|
|
61
|
+
--name payments \
|
|
62
|
+
--description "Owns payment authorization, capture, and refunds." \
|
|
63
|
+
--workspace <workspace>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Import a JSON array from a file or stdin:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
taskchef project import projects.json --workspace <workspace>
|
|
70
|
+
taskchef project import - --workspace <workspace> < projects.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Import merges by canonical path. Existing names and descriptions are preserved
|
|
74
|
+
when omitted. `--replace` explicitly replaces the configured project set.
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
taskchef project list --workspace <workspace>
|
|
78
|
+
taskchef project remove payments --workspace <workspace>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Removal refuses to orphan existing task records unless `--force` is supplied.
|
|
82
|
+
|
|
83
|
+
## Tasks
|
|
84
|
+
|
|
85
|
+
Task creation and update read JSON from stdin:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
printf '%s\n' '{"id":"t1","project":"/workspace/payments","title":"Echo input","instruction":"Create and test echo_input.py."}' |
|
|
89
|
+
taskchef task create --json --workspace <workspace>
|
|
90
|
+
|
|
91
|
+
printf '%s\n' '{"status":"running","threadId":"019f..."}' |
|
|
92
|
+
taskchef task update t1 --json --workspace <workspace>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Inspection commands:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
taskchef task show <task-id> --workspace <workspace>
|
|
99
|
+
taskchef task list --workspace <workspace>
|
|
100
|
+
taskchef task list --status running --status blocked --project payments --workspace <workspace>
|
|
101
|
+
taskchef task summary --workspace <workspace>
|
|
102
|
+
taskchef task reconcile-candidates --json --workspace <workspace>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`task reconcile-candidates` returns only `running` and `blocked` tasks with
|
|
106
|
+
thread IDs. Pass `--include-finished` only for an explicit full refresh or when
|
|
107
|
+
a finished executor is known to have received new work.
|
|
108
|
+
|
|
109
|
+
## Complete CLI
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
taskchef help
|
|
113
|
+
taskchef doctor
|
|
114
|
+
taskchef workspace init
|
|
115
|
+
taskchef project add <path>
|
|
116
|
+
taskchef project import [<file> | -]
|
|
117
|
+
taskchef project list
|
|
118
|
+
taskchef project remove <name>
|
|
119
|
+
taskchef task create
|
|
120
|
+
taskchef task update <task-id>
|
|
121
|
+
taskchef task show <task-id>
|
|
122
|
+
taskchef task list
|
|
123
|
+
taskchef task summary
|
|
124
|
+
taskchef task reconcile-candidates
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
All commands accept `--workspace <path>`. Add `--json` for deterministic JSON
|
|
128
|
+
output used by the TaskChef skills; otherwise the CLI prints human-readable
|
|
129
|
+
output.
|
|
130
|
+
|
|
131
|
+
## Release
|
|
132
|
+
|
|
133
|
+
Releases are automated with semantic-release from the `Release` GitHub Actions
|
|
134
|
+
workflow on `main`. Use Semantic Commit Messages so the release type can be
|
|
135
|
+
calculated:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
fix: correct task reconciliation
|
|
139
|
+
feat: add a new CLI command
|
|
140
|
+
feat!: change the workspace data contract
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Publishing uses npm trusted publishing from `.github/workflows/release.yml`.
|
|
144
|
+
The workflow runs the test suite, validates the npm tarball, publishes the
|
|
145
|
+
calculated version, creates the GitHub release, and commits the updated
|
|
146
|
+
`package.json` version back to `main`.
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
npm test
|
|
152
|
+
npm pack --dry-run
|
|
153
|
+
npx -y -p semantic-release@25 -p @semantic-release/git semantic-release --dry-run
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Boundaries
|
|
157
|
+
|
|
158
|
+
TaskChef is not an agent runtime, scheduler, hook service, or background
|
|
159
|
+
worker. Delegated work runs in real Codex tasks, never subagents.
|
|
160
|
+
Reconciliation is a single immediate snapshot pass and never polls or waits.
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# TaskChef specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
TaskChef is an interactive Codex dispatcher. It turns a user request into
|
|
6
|
+
independent assignments, creates real Codex tasks in the selected projects,
|
|
7
|
+
records their latest reconciled state, and returns control immediately.
|
|
8
|
+
|
|
9
|
+
TaskChef is not an agent runtime, scheduler, or background service.
|
|
10
|
+
|
|
11
|
+
## Core behavior
|
|
12
|
+
|
|
13
|
+
1. The user opens the TaskChef workspace and submits a request.
|
|
14
|
+
2. TaskChef splits the request into the smallest useful independent tasks.
|
|
15
|
+
3. TaskChef classifies each assignment using configured project metadata and
|
|
16
|
+
validates every target against the configured project list.
|
|
17
|
+
4. TaskChef creates one `task.json` record per delegated task with status
|
|
18
|
+
`pending`.
|
|
19
|
+
5. TaskChef creates one independently openable Codex task in each target
|
|
20
|
+
project.
|
|
21
|
+
6. TaskChef records the returned `threadId`, changes the status to `running`,
|
|
22
|
+
and returns immediately without waiting.
|
|
23
|
+
7. The user may open and prompt any delegated task directly.
|
|
24
|
+
8. The next user prompt in the dispatcher triggers one bounded reconciliation
|
|
25
|
+
of active `running` and `blocked` threads.
|
|
26
|
+
9. Reconciliation updates each task's current status and result, then returns
|
|
27
|
+
control without waiting for future activity.
|
|
28
|
+
|
|
29
|
+
Multiple ongoing tasks may target the same project.
|
|
30
|
+
|
|
31
|
+
## Workspace layout
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
taskchef-workspace/
|
|
35
|
+
├── AGENTS.md
|
|
36
|
+
├── taskchef.json
|
|
37
|
+
├── .agents/
|
|
38
|
+
│ └── skills/
|
|
39
|
+
│ ├── taskchef-bootstrap -> <TaskChef bootstrap skill>
|
|
40
|
+
│ ├── taskchef-delegate -> <TaskChef delegate skill>
|
|
41
|
+
│ └── taskchef-reconcile -> <TaskChef reconciliation skill>
|
|
42
|
+
└── tasks/
|
|
43
|
+
└── <task-id>/
|
|
44
|
+
└── task.json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The workspace contains TaskChef-managed dispatcher instructions, user
|
|
48
|
+
configuration, and task data. TaskChef source, tests, reports, and
|
|
49
|
+
implementation utilities remain in the source repository.
|
|
50
|
+
|
|
51
|
+
## Dispatcher instructions
|
|
52
|
+
|
|
53
|
+
TaskChef owns a marked block in the workspace `AGENTS.md`. The block tells
|
|
54
|
+
Codex to use `taskchef-bootstrap` for workspace setup and repair, use
|
|
55
|
+
`taskchef-reconcile` once for active work, then use
|
|
56
|
+
`taskchef-delegate` for actionable requests without completing delegated work
|
|
57
|
+
in the dispatcher thread.
|
|
58
|
+
|
|
59
|
+
`workspace init` copies the canonical file when `AGENTS.md` does not exist. When it
|
|
60
|
+
does exist, bootstrap preserves unrelated user content and adds or refreshes
|
|
61
|
+
only the TaskChef managed block. Repeating the merge is idempotent. Malformed
|
|
62
|
+
or duplicate TaskChef markers fail safely instead of overwriting the file.
|
|
63
|
+
Initialization also installs all three TaskChef skill links. It is idempotent,
|
|
64
|
+
takes no configuration input, creates `{ "schemaVersion": 1, "projects": [] }`
|
|
65
|
+
when configuration is missing, and preserves existing configured projects.
|
|
66
|
+
|
|
67
|
+
`doctor` diagnoses configuration, task storage, managed instructions, skill
|
|
68
|
+
links, project paths, and task records without modifying the workspace.
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
`taskchef.json` is the only user-facing configuration file.
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"schemaVersion": 1,
|
|
77
|
+
"projects": [
|
|
78
|
+
{
|
|
79
|
+
"name": "payments-api",
|
|
80
|
+
"path": "/workspace/payments-api",
|
|
81
|
+
"isGitRepository": true,
|
|
82
|
+
"githubRepo": "https://github.com/example/payments-api",
|
|
83
|
+
"description": "Owns payment authorization, capture, refunds, and provider integrations. Use for changes to the public payments API or its transaction lifecycle."
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "local-data-tools",
|
|
87
|
+
"path": "/workspace/local-data-tools",
|
|
88
|
+
"isGitRepository": false,
|
|
89
|
+
"githubRepo": null
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- `schemaVersion` identifies the configuration format.
|
|
96
|
+
- `projects` lists the local projects TaskChef may classify and manage.
|
|
97
|
+
- `name` is the unique human-readable project identity. It is explicit even
|
|
98
|
+
when it matches the checkout directory name.
|
|
99
|
+
- `path` is the exact canonical local project directory.
|
|
100
|
+
- `isGitRepository` states whether the saved Codex project is a Git repository.
|
|
101
|
+
When true, `path` must be the exact Git root. When false, the project runs
|
|
102
|
+
directly in its canonical directory without Git assumptions.
|
|
103
|
+
- `githubRepo` is the canonical GitHub repository URL, or `null` when the
|
|
104
|
+
project has no canonical GitHub remote. It may be `null` for either Git or
|
|
105
|
+
non-Git projects.
|
|
106
|
+
- `description` is an optional semantic routing description. When present, it
|
|
107
|
+
explains the project's responsibilities and the kinds of requests that
|
|
108
|
+
should target it, similarly to a skill trigger description.
|
|
109
|
+
|
|
110
|
+
Project paths must exist, resolve to canonical directories, and match the
|
|
111
|
+
project selected for delegation. A Git project path must resolve to its exact
|
|
112
|
+
repository root. A non-Git project must use `githubRepo: null`. Names and paths
|
|
113
|
+
must be unique.
|
|
114
|
+
|
|
115
|
+
TaskChef classifies a requested outcome against `name`, `githubRepo`, and the
|
|
116
|
+
optional `description`. The path identifies the checkout but is not a
|
|
117
|
+
classification signal. A description should be specific enough to distinguish
|
|
118
|
+
the project from its neighbors; generic technology labels are insufficient.
|
|
119
|
+
TaskChef selects a project only when the metadata yields one clear match; it
|
|
120
|
+
asks the user when no project or several projects plausibly match. It must not
|
|
121
|
+
guess solely from a directory name.
|
|
122
|
+
|
|
123
|
+
Project configuration is managed through `project add`, `project import`,
|
|
124
|
+
`project list`, and `project remove`. Add and import detect Git status, exact
|
|
125
|
+
Git roots, and canonical GitHub origins. Import accepts a JSON array from a
|
|
126
|
+
file or stdin, merges by canonical path, and preserves an existing name or
|
|
127
|
+
description when omitted. `--replace` is the only replacement mode.
|
|
128
|
+
|
|
129
|
+
The configuration does not store dispatcher identity, project-to-task
|
|
130
|
+
assignments, execution modes, scheduling options, host information, or the
|
|
131
|
+
workspace path. The directory containing `taskchef.json` is the workspace, and
|
|
132
|
+
the currently open Codex task is the dispatcher.
|
|
133
|
+
|
|
134
|
+
## Task record
|
|
135
|
+
|
|
136
|
+
Each independent assignment has one `tasks/<task-id>/task.json` file.
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"schemaVersion": 1,
|
|
141
|
+
"id": "t1-echo-input-20260808",
|
|
142
|
+
"project": "/workspace/t1",
|
|
143
|
+
"title": "Echo user input",
|
|
144
|
+
"instruction": "Create echo_input.py so it reads one line from standard input and echoes it exactly. Test the script and report the result.",
|
|
145
|
+
"status": "finished",
|
|
146
|
+
"threadId": "019f9d46-f42c-7482-9707-3c107bf241ee",
|
|
147
|
+
"result": {
|
|
148
|
+
"message": "Created and tested echo_input.py.",
|
|
149
|
+
"githubPRs": [],
|
|
150
|
+
"githubIssues": []
|
|
151
|
+
},
|
|
152
|
+
"createdAt": "2026-08-08T10:00:00.000Z",
|
|
153
|
+
"updatedAt": "2026-08-08T10:05:00.000Z"
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Fields
|
|
158
|
+
|
|
159
|
+
- `schemaVersion`: task format version.
|
|
160
|
+
- `id`: stable TaskChef task identifier.
|
|
161
|
+
- `project`: exact configured project directory.
|
|
162
|
+
- `title`: short human-readable task name.
|
|
163
|
+
- `instruction`: complete task-specific instruction.
|
|
164
|
+
- `status`: current reconciled lifecycle state.
|
|
165
|
+
- `threadId`: independently openable Codex task ID, or `null` while pending.
|
|
166
|
+
- `result`: latest meaningful report, or `null` when none exists.
|
|
167
|
+
- `createdAt`: task creation time as an ISO 8601 timestamp.
|
|
168
|
+
- `updatedAt`: latest task update time as an ISO 8601 timestamp.
|
|
169
|
+
|
|
170
|
+
The task-specific instruction includes the requested outcome, constraints,
|
|
171
|
+
expected testing, and reporting expectations. Task records have no separate acceptance or
|
|
172
|
+
decision fields.
|
|
173
|
+
|
|
174
|
+
## Status model
|
|
175
|
+
|
|
176
|
+
TaskChef supports four statuses:
|
|
177
|
+
|
|
178
|
+
- `pending`: the record exists, but executor creation has not completed.
|
|
179
|
+
- `running`: the executor thread exists and may be working.
|
|
180
|
+
- `blocked`: progress requires user input, permission, credentials, or another
|
|
181
|
+
external condition.
|
|
182
|
+
- `finished`: the executor concluded its current attempt and reported a result.
|
|
183
|
+
|
|
184
|
+
Typical transitions are:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
pending → running → finished
|
|
188
|
+
↘ blocked → running
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`finished` describes the executor lifecycle. It does not guarantee that the
|
|
192
|
+
goal was achieved. The result message explains success, partial completion,
|
|
193
|
+
failure, or uncertainty. A finished task returns to `running` if the user gives
|
|
194
|
+
its thread more work.
|
|
195
|
+
|
|
196
|
+
## Result
|
|
197
|
+
|
|
198
|
+
`result` is `null` until there is a meaningful report.
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"result": null
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
When present, it has exactly three fields:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"result": {
|
|
211
|
+
"message": "Implemented the change and opened a pull request.",
|
|
212
|
+
"githubPRs": [
|
|
213
|
+
"https://github.com/example/t1/pull/12"
|
|
214
|
+
],
|
|
215
|
+
"githubIssues": [
|
|
216
|
+
"https://github.com/example/t1/issues/8"
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- `message` is a required concise outcome, progress report, or blocker.
|
|
223
|
+
- `githubPRs` is a list of canonical GitHub pull-request URLs.
|
|
224
|
+
- `githubIssues` is a list of canonical GitHub issue URLs.
|
|
225
|
+
|
|
226
|
+
The URL lists are empty when no related resources exist. TaskChef does not store
|
|
227
|
+
separate artifact, verification, commit, decision, or completion fields.
|
|
228
|
+
|
|
229
|
+
## Dispatch workflow
|
|
230
|
+
|
|
231
|
+
For each delegated task, TaskChef:
|
|
232
|
+
|
|
233
|
+
1. classifies and validates the target against project metadata in
|
|
234
|
+
`taskchef.json`;
|
|
235
|
+
2. writes `task.json` with `status: pending`, `threadId: null`, and
|
|
236
|
+
`result: null`;
|
|
237
|
+
3. creates a real Codex task rooted at the exact project;
|
|
238
|
+
4. records its `threadId` and changes the status to `running`;
|
|
239
|
+
5. returns control after all requested tasks have been dispatched.
|
|
240
|
+
|
|
241
|
+
TaskChef does not wait for delegated tasks to finish.
|
|
242
|
+
|
|
243
|
+
## Reconciliation workflow
|
|
244
|
+
|
|
245
|
+
The next user prompt in the dispatcher triggers reconciliation:
|
|
246
|
+
|
|
247
|
+
1. use `task reconcile-candidates --json` to load only `running` and `blocked`
|
|
248
|
+
task records with executor thread IDs;
|
|
249
|
+
2. query each returned `threadId` once using an immediate native task snapshot;
|
|
250
|
+
3. do not wait for future activity;
|
|
251
|
+
4. update `status`, `result`, and `updatedAt` from the current thread state;
|
|
252
|
+
5. report the concise current state and return control.
|
|
253
|
+
|
|
254
|
+
The native Codex thread is the live source of truth between reconciliations.
|
|
255
|
+
`task.json` is only the latest reconciled snapshot. It may still say `running`
|
|
256
|
+
after the executor has finished and before the user next prompts the
|
|
257
|
+
dispatcher.
|
|
258
|
+
|
|
259
|
+
Reconciliation must be safe to repeat. TaskChef has no reconciliation timestamp,
|
|
260
|
+
event cursor, event log, callback, or automatic workspace update.
|
|
261
|
+
Finished records are excluded from normal reconciliation. An explicit full
|
|
262
|
+
refresh uses `--include-finished` to detect a new attempt added directly to a
|
|
263
|
+
finished executor thread.
|
|
264
|
+
|
|
265
|
+
## Inspection workflow
|
|
266
|
+
|
|
267
|
+
`task list` returns task records with optional repeated `--status` filters and
|
|
268
|
+
an optional configured project name or path. `task summary` returns total and
|
|
269
|
+
per-status counts. These commands only inspect persisted TaskChef state and do
|
|
270
|
+
not query native executor threads.
|
|
271
|
+
|
|
272
|
+
## Boundaries
|
|
273
|
+
|
|
274
|
+
TaskChef is local, interactive, task-focused, and asynchronous. It does not include:
|
|
275
|
+
|
|
276
|
+
- `runs/` or records of the original broad prompt;
|
|
277
|
+
- `events.jsonl` or lifecycle history;
|
|
278
|
+
- hooks or automatic completion signals;
|
|
279
|
+
- executor callbacks;
|
|
280
|
+
- schedules, polling, daemons, heartbeats, or background reconciliation;
|
|
281
|
+
- remote hosts or `hostId` storage;
|
|
282
|
+
- project-to-current-task assignments;
|
|
283
|
+
- one-active-task-per-project restrictions;
|
|
284
|
+
- transcript or hidden-reasoning collection;
|
|
285
|
+
- arbitrary Codex task discovery;
|
|
286
|
+
- npm registry publication; the supported distribution is a GitHub-source
|
|
287
|
+
global install or a managed source checkout.
|
|
288
|
+
|
|
289
|
+
See `BACKLOG.md` for deferred capabilities and experiments.
|
|
290
|
+
|
|
291
|
+
## MVP acceptance test
|
|
292
|
+
|
|
293
|
+
The MVP is successful when:
|
|
294
|
+
|
|
295
|
+
1. `taskchef.json` describes two local projects with names, paths,
|
|
296
|
+
`isGitRepository`, GitHub repositories or explicit `null` values, and
|
|
297
|
+
optional routing descriptions; at least one acceptance fixture is non-Git.
|
|
298
|
+
2. One request produces two task-specific `task.json` records.
|
|
299
|
+
3. Two independently openable Codex tasks are created in the correct projects.
|
|
300
|
+
4. Both `threadId` values are recorded.
|
|
301
|
+
5. The dispatcher returns without waiting for execution.
|
|
302
|
+
6. The user can open and prompt either delegated task directly.
|
|
303
|
+
7. The next dispatcher prompt reconciles each active thread once without
|
|
304
|
+
reading finished executor threads.
|
|
305
|
+
8. Status and result snapshots are updated correctly.
|
|
306
|
+
9. Two ongoing tasks may target the same project without data collisions.
|
|
307
|
+
10. The workspace contains dispatcher instructions, configuration, task
|
|
308
|
+
records, and the three TaskChef skill links.
|
|
309
|
+
11. Bootstrap creates or idempotently merges the TaskChef-managed `AGENTS.md`
|
|
310
|
+
block without overwriting unrelated instructions.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- taskchef:dispatcher-instructions:start -->
|
|
2
|
+
# TaskChef Dispatcher Instructions
|
|
3
|
+
|
|
4
|
+
This repository is a TaskChef dispatcher workspace.
|
|
5
|
+
|
|
6
|
+
- Use `taskchef-bootstrap` when initializing or refreshing this workspace,
|
|
7
|
+
changing or listing its configured projects, running TaskChef doctor,
|
|
8
|
+
repairing its managed instructions, or upgrading its TaskChef skill links.
|
|
9
|
+
- For every ordinary user prompt, use `taskchef-reconcile` first to refresh
|
|
10
|
+
active recorded work once.
|
|
11
|
+
- For every actionable work request, then use `taskchef-delegate`
|
|
12
|
+
automatically, even when the user does not explicitly say "delegate" or
|
|
13
|
+
mention TaskChef.
|
|
14
|
+
- Do not perform delegated work directly in the dispatcher thread.
|
|
15
|
+
- Return immediately after dispatch, as required by `taskchef-delegate`.
|
|
16
|
+
- Answer directly only when the user explicitly asks about TaskChef itself or
|
|
17
|
+
explicitly says not to delegate.
|
|
18
|
+
<!-- taskchef:dispatcher-instructions:end -->
|
package/bin/taskchef.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { runCli } from "../src/cli.js";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
try {
|
|
6
|
+
process.exitCode = await runCli(process.argv.slice(2));
|
|
7
|
+
} catch (error) {
|
|
8
|
+
process.stderr.write(`taskchef: ${error.message}\n`);
|
|
9
|
+
process.exitCode = 1;
|
|
10
|
+
}
|
package/index.js
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export {
|
|
2
|
+
addProject,
|
|
3
|
+
buildTaskSummary,
|
|
4
|
+
buildReconciliationCandidates,
|
|
5
|
+
canonicalDirectory,
|
|
6
|
+
canonicalGitRoot,
|
|
7
|
+
createTask,
|
|
8
|
+
doctorWorkspace,
|
|
9
|
+
ensureWorkspaceInstructions,
|
|
10
|
+
ensureWorkspaceSkills,
|
|
11
|
+
filterTasks,
|
|
12
|
+
importProjects,
|
|
13
|
+
initializeWorkspace,
|
|
14
|
+
listProjects,
|
|
15
|
+
listTasks,
|
|
16
|
+
readConfig,
|
|
17
|
+
readTask,
|
|
18
|
+
requireSafeId,
|
|
19
|
+
removeProject,
|
|
20
|
+
updateTask,
|
|
21
|
+
validateConfig,
|
|
22
|
+
validateResult,
|
|
23
|
+
} from "./src/workspace.js";
|
package/package.json
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskchef",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "A non-blocking interactive dispatcher for visible Codex tasks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Favo Yang",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/favoyang/taskchef.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/favoyang/taskchef/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/favoyang/taskchef#readme",
|
|
7
15
|
"type": "module",
|
|
8
16
|
"exports": "./index.js",
|
|
9
17
|
"bin": {
|
|
10
|
-
"taskchef": "
|
|
18
|
+
"taskchef": "bin/taskchef.js"
|
|
11
19
|
},
|
|
12
20
|
"files": [
|
|
21
|
+
"assets",
|
|
22
|
+
"BACKLOG.md",
|
|
13
23
|
"bin",
|
|
14
|
-
"index.js"
|
|
24
|
+
"index.js",
|
|
25
|
+
"SPEC.md",
|
|
26
|
+
"src",
|
|
27
|
+
"skills/taskchef-bootstrap",
|
|
28
|
+
"skills/taskchef-delegate",
|
|
29
|
+
"skills/taskchef-reconcile"
|
|
15
30
|
],
|
|
16
31
|
"engines": {
|
|
17
32
|
"node": ">=18"
|
|
18
33
|
},
|
|
19
34
|
"scripts": {
|
|
20
|
-
"test": "node --test"
|
|
35
|
+
"test": "node --test tests/taskchef.test.js"
|
|
21
36
|
}
|
|
22
37
|
}
|