taskchef 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +6 -5
- package/docs/firstmate-taskchef-comparison.md +1 -1
- package/docs/spec.md +15 -9
- package/docs/workflows.md +5 -4
- package/package.json +1 -1
- package/skills/taskchef-delegate/SKILL.md +18 -9
- package/skills/taskchef-executor/SKILL.md +16 -6
- package/src/delegation.js +96 -6
- package/src/mcp.js +1 -1
- package/src/workspace.js +1 -1
package/README.md
CHANGED
|
@@ -87,17 +87,18 @@ $taskchef-delegate In payments, add structured logs for failed retries and test
|
|
|
87
87
|
|
|
88
88
|
TaskChef prepares a UUID and marker, persists the task before native creation,
|
|
89
89
|
creates the executor, and returns its task link. New executor instructions keep
|
|
90
|
-
the assignment visible
|
|
91
|
-
`$taskchef-executor` invocation. That skill
|
|
92
|
-
`CODEX_THREAD_ID`, self-links, and reports lifecycle
|
|
93
|
-
may become separate executors; dependent work
|
|
90
|
+
the assignment visible from the first line, then place the correlation marker
|
|
91
|
+
immediately before an explicit `$taskchef-executor` invocation. That skill
|
|
92
|
+
reads the executor's own `CODEX_THREAD_ID`, self-links, and reports lifecycle
|
|
93
|
+
state. Independent outcomes may become separate executors; dependent work
|
|
94
|
+
should stay together.
|
|
94
95
|
|
|
95
96
|
For example, TaskChef generates this shape:
|
|
96
97
|
|
|
97
98
|
```text
|
|
98
|
-
<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->
|
|
99
99
|
Fix duplicate charges after a retry and add a regression test.
|
|
100
100
|
|
|
101
|
+
<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->
|
|
101
102
|
Use $taskchef-executor to execute and report this delegated TaskChef assignment.
|
|
102
103
|
```
|
|
103
104
|
|
|
@@ -108,7 +108,7 @@ also insert an interpretation layer between user and worker.
|
|
|
108
108
|
|
|
109
109
|
### TaskChef
|
|
110
110
|
|
|
111
|
-
**Fact:** `prepare_dispatch` allocates a TaskChef UUID and exact
|
|
111
|
+
**Fact:** `prepare_dispatch` allocates a TaskChef UUID and exact correlation
|
|
112
112
|
marker. `record_task` persists the marked instruction before native task
|
|
113
113
|
creation. The executor then reads its own `CODEX_THREAD_ID` and calls
|
|
114
114
|
`link_task`; the dispatcher neither searches recent tasks nor repairs identity.
|
package/docs/spec.md
CHANGED
|
@@ -18,7 +18,7 @@ is dated research, not contract.
|
|
|
18
18
|
| **Delegated task** | One independently useful outcome represented by one TaskChef task UUID and snapshot. |
|
|
19
19
|
| **Executor** | The native Codex task created to own and perform one delegated task. |
|
|
20
20
|
| **Task record** | One complete JSON object in `tasks.jsonl`; it contains immutable intent/project fields and mutable identity/result fields. |
|
|
21
|
-
| **Marker** | The exact
|
|
21
|
+
| **Marker** | The exact correlation line `<!-- taskchef_id=<lowercase full UUID> -->`; new instructions place it after the complete assignment and immediately before the executor-skill invocation. |
|
|
22
22
|
| **Record-before-create** | Persisting a link-pending task before asking Codex to create its executor. |
|
|
23
23
|
| **Self-linking** | The executor's one-way registration of its own canonical Codex UUIDv7 from `CODEX_THREAD_ID`. |
|
|
24
24
|
| **Link-pending** | A working task whose `threadId` is null and `updatedBy` is `dispatcher`. |
|
|
@@ -102,10 +102,11 @@ fields MUST NOT change after recording.
|
|
|
102
102
|
|
|
103
103
|
1. The dispatcher MUST call `prepare_dispatch` once per outcome.
|
|
104
104
|
2. It MUST choose exactly one configured project and exact native-project path.
|
|
105
|
-
3. It MUST build the instruction with the
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
inline the executor protocol into a new
|
|
105
|
+
3. It MUST build the instruction with the user's outcome beginning on line 1
|
|
106
|
+
and remaining uninterrupted, followed by one blank line, the returned
|
|
107
|
+
marker, and exactly one concise explicit `$taskchef-executor` invocation on
|
|
108
|
+
the final line. It MUST NOT inline the executor protocol into a new
|
|
109
|
+
instruction.
|
|
109
110
|
4. It MUST call `record_task` with `threadId: null` before native creation.
|
|
110
111
|
5. It MUST create exactly one native Codex executor and return immediately.
|
|
111
112
|
6. The executor MUST read its own `CODEX_THREAD_ID` and call `link_task`
|
|
@@ -122,10 +123,15 @@ If native creation fails after recording, the dispatcher MUST call
|
|
|
122
123
|
A link failure MUST remain visible and retryable; the executor MUST report it
|
|
123
124
|
visibly and MUST NOT continue substantive work.
|
|
124
125
|
|
|
125
|
-
Previously recorded instructions with
|
|
126
|
-
|
|
126
|
+
Previously recorded instructions with a first-line HTML marker, the older
|
|
127
|
+
first-line `# taskchef_id=<full UUID>` heading, or the former blank line and
|
|
128
|
+
inline executor protocol MUST remain marker-readable and executable. Their
|
|
127
129
|
`report_result` calls MUST remain supported by the deprecated alias. New
|
|
128
|
-
instructions MUST use the explicit executor skill contract
|
|
130
|
+
instructions MUST use the trailing marker and explicit executor skill contract
|
|
131
|
+
above. A historical first-line instruction with an executor-skill invocation
|
|
132
|
+
MUST contain exactly one invocation as its final line. A former inline-protocol
|
|
133
|
+
instruction MUST retain non-whitespace task-specific content beyond its known
|
|
134
|
+
lifecycle paragraphs.
|
|
129
135
|
|
|
130
136
|
`needs_input` MUST mean a semantic user decision or missing fact. A native
|
|
131
137
|
approval prompt MUST remain live Codex state and MUST NOT be stored as
|
|
@@ -176,7 +182,7 @@ new preparation values, though it writes no state.
|
|
|
176
182
|
| `id` | Non-empty string; MUST equal the instruction marker. |
|
|
177
183
|
| `project` | Non-empty configured project path. |
|
|
178
184
|
| `title` | Non-empty string. |
|
|
179
|
-
| `instruction` | Non-empty string
|
|
185
|
+
| `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. |
|
|
180
186
|
| `threadId` | Literal null. |
|
|
181
187
|
|
|
182
188
|
**Structured output:** `{ task: Task }`.
|
package/docs/workflows.md
CHANGED
|
@@ -68,10 +68,11 @@ Record-before-create makes native creation failure observable. Executor
|
|
|
68
68
|
self-linking removes dispatcher-side polling, task search, title matching, and
|
|
69
69
|
parent/child identity inference.
|
|
70
70
|
|
|
71
|
-
The generated task
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
the deprecated `report_result` alias preserves their
|
|
71
|
+
The generated task begins with the complete assignment, then places its marker
|
|
72
|
+
immediately before one explicit `$taskchef-executor` invocation. Older
|
|
73
|
+
recorded tasks with first-line HTML or heading markers and former inline
|
|
74
|
+
protocol remain readable; the deprecated `report_result` alias preserves their
|
|
75
|
+
semantic callbacks.
|
|
75
76
|
|
|
76
77
|
## State reporting
|
|
77
78
|
|
package/package.json
CHANGED
|
@@ -10,11 +10,18 @@ and return immediately.
|
|
|
10
10
|
|
|
11
11
|
## Invocation boundary
|
|
12
12
|
|
|
13
|
-
A task whose initial structured `codexDelegation.input`
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
A task whose initial structured `codexDelegation.input` contains either the
|
|
14
|
+
exact new trailing TaskChef marker plus final `$taskchef-executor` invocation,
|
|
15
|
+
an exact first-line HTML marker, or the historical first-line
|
|
16
|
+
`# taskchef_id=<full UUID>` heading already owns that delegated assignment.
|
|
17
|
+
This includes former inline-protocol tasks that lack the skill invocation.
|
|
18
|
+
An owned instruction must have exactly one accepted marker and a non-whitespace
|
|
19
|
+
task-specific assignment. If it contains an executor-skill invocation, require
|
|
20
|
+
exactly one as the final line. Marker-only, duplicate-marker, scaffold-only, or
|
|
21
|
+
misplaced-invocation inputs are not valid delegated tasks. Execute a valid one
|
|
22
|
+
in the current task. Do not re-dispatch it merely because it concerns TaskChef
|
|
23
|
+
or a configured project. Explicit requests to delegate separate work remain
|
|
24
|
+
valid.
|
|
18
25
|
|
|
19
26
|
Use the bundled `prepare_dispatch`, `record_task`, and `report_state` MCP tools
|
|
20
27
|
directly. Never fall back to shell writes. If a required tool is unavailable,
|
|
@@ -43,11 +50,13 @@ stop and report that the TaskChef plugin must be reloaded or installed.
|
|
|
43
50
|
match and an exact native-project path. Ask instead of guessing.
|
|
44
51
|
4. Build each executor instruction in this exact shape:
|
|
45
52
|
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
- Begin with the actual assignment on the first line and keep its complete
|
|
54
|
+
body uninterrupted.
|
|
55
|
+
- After the assignment, add one blank line and the preparation's exact
|
|
56
|
+
marker on its own line.
|
|
57
|
+
- Immediately after the marker, end the instruction with exactly:
|
|
50
58
|
`Use $taskchef-executor to execute and report this delegated TaskChef assignment.`
|
|
59
|
+
- Include exactly one marker and exactly one executor-skill invocation.
|
|
51
60
|
- Do not inline executor ownership, identity, linking, or result-reporting
|
|
52
61
|
protocol. The explicitly invoked executor skill owns those mechanics.
|
|
53
62
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: taskchef-executor
|
|
3
|
-
description: "Execute an assignment
|
|
3
|
+
description: "Execute an assignment carrying either the new exact TaskChef marker-plus-invocation scaffold or an accepted historical first-line TaskChef marker or inline protocol. Includes executor ownership, self-linking, per-turn lifecycle reporting, identity safety, and final semantic state. Use when explicitly invoked by a new delegated instruction or when resuming the same new or historical executor task. Do not use to dispatch work or report on other TaskChef tasks."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# TaskChef Executor
|
|
@@ -9,10 +9,12 @@ Own and execute the delegated assignment in the current Codex task. Do not
|
|
|
9
9
|
re-dispatch it merely because it concerns TaskChef or a configured project.
|
|
10
10
|
Explicit requests to delegate separate work remain valid.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
`<!-- taskchef_id=<full UUID>
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
New instructions present the complete assignment first, followed by one blank
|
|
13
|
+
line, the exact `<!-- taskchef_id=<full UUID> -->` marker, and the final
|
|
14
|
+
explicit skill invocation. Treat that UUID as the TaskChef task ID. The
|
|
15
|
+
assignment is everything before the blank line that precedes the marker; the
|
|
16
|
+
marker and invocation are lifecycle scaffolding, not part of the deliverable.
|
|
17
|
+
Require exactly one marker and do not infer an ID from similar prose.
|
|
16
18
|
|
|
17
19
|
## Start every execution turn
|
|
18
20
|
|
|
@@ -66,4 +68,12 @@ Existing delegated tasks may include the former inline ownership, linking, and
|
|
|
66
68
|
re-dispatching. Prefer `report_state` when available. If an older installed
|
|
67
69
|
TaskChef exposes only `report_result`, follow its inline protocol; after an
|
|
68
70
|
upgrade, the deprecated `report_result` alias remains available for exact
|
|
69
|
-
legacy retries.
|
|
71
|
+
legacy retries. Also accept historical instructions whose exact HTML marker is
|
|
72
|
+
the first line, with or without the former blank line, and the older exact
|
|
73
|
+
first-line `# taskchef_id=<full UUID>` heading. These compatibility forms do
|
|
74
|
+
not change the identity or lifecycle rules above. For either first-line form,
|
|
75
|
+
the assignment follows the marker. Ignore the final executor invocation and
|
|
76
|
+
any recognizable former inline ownership, linking, working-state, or
|
|
77
|
+
result-reporting paragraphs as lifecycle scaffolding; execute the remaining
|
|
78
|
+
task-specific body. Require non-whitespace task-specific content and never
|
|
79
|
+
treat an invocation by itself as an assignment.
|
package/src/delegation.js
CHANGED
|
@@ -9,11 +9,34 @@ export const EXECUTOR_WORKING_PARAGRAPH = "After a successful initial link, and
|
|
|
9
9
|
/** @deprecated Historical v7 inline-prompt snapshot. New delegations use taskchef-executor. */
|
|
10
10
|
export const EXECUTOR_RESULT_PARAGRAPH = "Before ending, read this exact Codex thread again and call TaskChef report_state for the same current working turn with status completed, needs_input, or failed and a concise summary. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.";
|
|
11
11
|
export const EXECUTOR_SKILL_INVOCATION = "Use $taskchef-executor to execute and report this delegated TaskChef assignment.";
|
|
12
|
+
const HISTORICAL_RESULT_WITH_TURN_PARAGRAPH = "Before ending, call the TaskChef report_result MCP tool with the marked task ID, this executor's self-linked thread ID, the current turn ID from an exact native read of that same thread, completed, needs_input, or failed, and a concise summary. Never reuse a prior turn ID after a follow-up. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.";
|
|
13
|
+
const HISTORICAL_RESULT_PARAGRAPH = "Before ending, call the TaskChef report_result MCP tool with completed, needs_input, or failed and a concise summary. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.";
|
|
14
|
+
const HISTORICAL_EXECUTOR_SCAFFOLD_LINES = new Set([
|
|
15
|
+
EXECUTOR_OWNERSHIP_PARAGRAPH,
|
|
16
|
+
EXECUTOR_LINK_PARAGRAPH,
|
|
17
|
+
EXECUTOR_WORKING_PARAGRAPH,
|
|
18
|
+
EXECUTOR_RESULT_PARAGRAPH,
|
|
19
|
+
HISTORICAL_RESULT_WITH_TURN_PARAGRAPH,
|
|
20
|
+
HISTORICAL_RESULT_PARAGRAPH,
|
|
21
|
+
]);
|
|
22
|
+
const HISTORICAL_INLINE_PROTOCOLS = [
|
|
23
|
+
[EXECUTOR_OWNERSHIP_PARAGRAPH, EXECUTOR_LINK_PARAGRAPH, EXECUTOR_WORKING_PARAGRAPH, EXECUTOR_RESULT_PARAGRAPH],
|
|
24
|
+
[EXECUTOR_OWNERSHIP_PARAGRAPH, EXECUTOR_LINK_PARAGRAPH, HISTORICAL_RESULT_WITH_TURN_PARAGRAPH],
|
|
25
|
+
[EXECUTOR_OWNERSHIP_PARAGRAPH, HISTORICAL_RESULT_PARAGRAPH],
|
|
26
|
+
[EXECUTOR_OWNERSHIP_PARAGRAPH],
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
function hasTaskSpecificContent(lines) {
|
|
30
|
+
return lines.some((line) => (
|
|
31
|
+
line.trim().length > 0 && !HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line)
|
|
32
|
+
));
|
|
33
|
+
}
|
|
12
34
|
|
|
13
35
|
const UUID_SOURCE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
14
36
|
const UUID_PATTERN = new RegExp(`^${UUID_SOURCE}$`);
|
|
15
37
|
const CODEX_UUID_V7_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
16
38
|
const TASKCHEF_MARKER_PATTERN = new RegExp(`^<!-- taskchef_id=(${UUID_SOURCE}) -->$`);
|
|
39
|
+
const LEGACY_TASKCHEF_MARKER_PATTERN = new RegExp(`^# taskchef_id=(${UUID_SOURCE})$`);
|
|
17
40
|
|
|
18
41
|
function requireObject(value, name) {
|
|
19
42
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
|
|
@@ -89,10 +112,66 @@ export function taskChefMarker(taskId) {
|
|
|
89
112
|
|
|
90
113
|
export function parseTaskChefMarker(instruction) {
|
|
91
114
|
if (typeof instruction !== "string") return null;
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
const lines = instruction.split(/\r\n|\r|\n/);
|
|
116
|
+
const hasHistoricalAssignment = () => {
|
|
117
|
+
const rest = lines.slice(1);
|
|
118
|
+
const executorSkillInvocationIndices = rest.flatMap((line, index) => (
|
|
119
|
+
line === EXECUTOR_SKILL_INVOCATION ? [index] : []
|
|
120
|
+
));
|
|
121
|
+
if (executorSkillInvocationIndices.length > 0) {
|
|
122
|
+
const bodyLines = rest.slice(0, -2);
|
|
123
|
+
return executorSkillInvocationIndices.length === 1
|
|
124
|
+
&& executorSkillInvocationIndices[0] === rest.length - 1
|
|
125
|
+
&& lines.at(-1) === EXECUTOR_SKILL_INVOCATION
|
|
126
|
+
&& lines.at(-2) === ""
|
|
127
|
+
&& bodyLines.length > 0
|
|
128
|
+
&& bodyLines[0].trim().length > 0
|
|
129
|
+
&& bodyLines.at(-1).trim().length > 0
|
|
130
|
+
&& hasTaskSpecificContent(bodyLines)
|
|
131
|
+
&& !bodyLines.some((line) => HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const containsInlineScaffold = rest.some((line) => HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line));
|
|
135
|
+
if (!containsInlineScaffold) return rest.join("\n").trim().length > 0;
|
|
136
|
+
return HISTORICAL_INLINE_PROTOCOLS.some((protocol) => {
|
|
137
|
+
const prefix = ["", ...protocol.flatMap((line) => [line, ""])];
|
|
138
|
+
if (!prefix.every((line, index) => rest[index] === line)) return false;
|
|
139
|
+
const bodyLines = rest.slice(prefix.length);
|
|
140
|
+
return hasTaskSpecificContent(bodyLines)
|
|
141
|
+
&& !bodyLines.some((line) => HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line));
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
const currentMatches = lines.flatMap((line, index) => {
|
|
145
|
+
const match = line.match(TASKCHEF_MARKER_PATTERN);
|
|
146
|
+
return match === null ? [] : [{ id: match[1], index }];
|
|
147
|
+
});
|
|
148
|
+
const legacyMatches = lines.flatMap((line, index) => {
|
|
149
|
+
const match = line.match(LEGACY_TASKCHEF_MARKER_PATTERN);
|
|
150
|
+
return match === null ? [] : [{ id: match[1], index }];
|
|
151
|
+
});
|
|
152
|
+
if (currentMatches.length + legacyMatches.length !== 1) return null;
|
|
153
|
+
|
|
154
|
+
if (legacyMatches.length === 1) {
|
|
155
|
+
const [{ id, index }] = legacyMatches;
|
|
156
|
+
if (index !== 0) return null;
|
|
157
|
+
return hasHistoricalAssignment() ? id : null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const [{ id, index }] = currentMatches;
|
|
161
|
+
if (index === 0) {
|
|
162
|
+
return hasHistoricalAssignment() ? id : null;
|
|
163
|
+
}
|
|
164
|
+
const executorSkillReferences = instruction.match(/\$taskchef-executor\b/gi) ?? [];
|
|
165
|
+
const isTrailingScaffold = index === lines.length - 2
|
|
166
|
+
&& index >= 2
|
|
167
|
+
&& lines[0].trim().length > 0
|
|
168
|
+
&& lines.at(-3) === ""
|
|
169
|
+
&& lines.at(-4).trim().length > 0
|
|
170
|
+
&& lines.at(-1) === EXECUTOR_SKILL_INVOCATION
|
|
171
|
+
&& hasTaskSpecificContent(lines.slice(0, index - 1))
|
|
172
|
+
&& !lines.slice(0, index - 1).some((line) => HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line))
|
|
173
|
+
&& executorSkillReferences.length === 1;
|
|
174
|
+
return isTrailingScaffold ? id : null;
|
|
96
175
|
}
|
|
97
176
|
|
|
98
177
|
export function prepareDelegation(instruction, { taskId = randomUUID() } = {}) {
|
|
@@ -101,14 +180,25 @@ export function prepareDelegation(instruction, { taskId = randomUUID() } = {}) {
|
|
|
101
180
|
throw new Error("instruction must begin with useful task content on its first line");
|
|
102
181
|
}
|
|
103
182
|
const body = rawBody.replace(/(?:(?:\r\n|\r|\n)[^\S\r\n]*)+$/, "");
|
|
104
|
-
if (
|
|
183
|
+
if (body.split(/\r\n|\r|\n/).some((line) => (
|
|
184
|
+
TASKCHEF_MARKER_PATTERN.test(line) || LEGACY_TASKCHEF_MARKER_PATTERN.test(line)
|
|
185
|
+
))) {
|
|
186
|
+
throw new Error("instruction already contains a TaskChef marker");
|
|
187
|
+
}
|
|
105
188
|
if (/\$taskchef-executor\b/i.test(body)) {
|
|
106
189
|
throw new Error("instruction contains a reserved TaskChef executor skill reference");
|
|
107
190
|
}
|
|
191
|
+
const bodyLines = body.split(/\r\n|\r|\n/);
|
|
192
|
+
if (!hasTaskSpecificContent(bodyLines)) {
|
|
193
|
+
throw new Error("instruction must contain task-specific content, not only TaskChef lifecycle scaffolding");
|
|
194
|
+
}
|
|
195
|
+
if (bodyLines.some((line) => HISTORICAL_EXECUTOR_SCAFFOLD_LINES.has(line))) {
|
|
196
|
+
throw new Error("instruction contains reserved historical TaskChef lifecycle scaffolding");
|
|
197
|
+
}
|
|
108
198
|
const id = requireUuid(taskId);
|
|
109
199
|
return {
|
|
110
200
|
id,
|
|
111
|
-
instruction: `${
|
|
201
|
+
instruction: `${body}\n\n${taskChefMarker(id)}\n${EXECUTOR_SKILL_INVOCATION}`,
|
|
112
202
|
};
|
|
113
203
|
}
|
|
114
204
|
|
package/src/mcp.js
CHANGED
|
@@ -114,7 +114,7 @@ export function createTaskChefMcpServer({
|
|
|
114
114
|
},
|
|
115
115
|
async (input) => {
|
|
116
116
|
if (parseTaskChefMarker(input.instruction) !== input.id) {
|
|
117
|
-
throw new Error("record_task instruction must
|
|
117
|
+
throw new Error("record_task instruction must contain its exact TaskChef marker in an accepted scaffold");
|
|
118
118
|
}
|
|
119
119
|
const task = await record(workspace, input);
|
|
120
120
|
return toolResult("task", task, `Recorded TaskChef task ${task.id}.`);
|
package/src/workspace.js
CHANGED
|
@@ -737,7 +737,7 @@ async function validateDispatchShape(dispatch, name = "task") {
|
|
|
737
737
|
id,
|
|
738
738
|
project,
|
|
739
739
|
title: requireString(dispatch.title, `${name}.title`).trim(),
|
|
740
|
-
instruction: requireString(dispatch.instruction, `${name}.instruction`)
|
|
740
|
+
instruction: requireString(dispatch.instruction, `${name}.instruction`),
|
|
741
741
|
threadId: dispatch.threadId === null
|
|
742
742
|
? null
|
|
743
743
|
: normalizeDurableThreadId(dispatch.threadId, `${name}.threadId`),
|