taskchef 2.0.0 → 3.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/.codex-plugin/plugin.json +3 -3
- package/BACKLOG.md +35 -82
- package/README.md +211 -108
- package/SPEC.md +114 -246
- package/assets/taskchef-dispatcher-instructions.md +3 -2
- package/index.js +2 -5
- package/package.json +6 -2
- package/skills/taskchef-bootstrap/SKILL.md +11 -11
- package/skills/taskchef-delegate/SKILL.md +16 -18
- package/skills/taskchef-report/SKILL.md +38 -0
- package/skills/taskchef-report/agents/openai.yaml +4 -0
- package/src/cli.js +26 -70
- package/src/workspace.js +315 -251
- package/skills/taskchef-reconcile/SKILL.md +0 -35
- package/skills/taskchef-reconcile/agents/openai.yaml +0 -4
package/src/cli.js
CHANGED
|
@@ -3,17 +3,15 @@ import path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
addProject,
|
|
6
|
-
buildReconciliationCandidates,
|
|
7
6
|
buildTaskSummary,
|
|
8
|
-
createTask,
|
|
9
7
|
doctorWorkspace,
|
|
10
8
|
filterTasks,
|
|
11
9
|
importProjects,
|
|
12
10
|
initializeWorkspace,
|
|
13
11
|
listProjects,
|
|
14
12
|
readTask,
|
|
13
|
+
recordTask,
|
|
15
14
|
removeProject,
|
|
16
|
-
updateTask,
|
|
17
15
|
} from "./workspace.js";
|
|
18
16
|
|
|
19
17
|
async function readStdin() {
|
|
@@ -38,19 +36,6 @@ function option(args, name, fallback) {
|
|
|
38
36
|
return args[index + 1];
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
function options(args, name) {
|
|
42
|
-
const values = [];
|
|
43
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
44
|
-
if (args[index] !== name) continue;
|
|
45
|
-
if (!args[index + 1] || args[index + 1].startsWith("--")) {
|
|
46
|
-
throw new Error(`${name} requires a value`);
|
|
47
|
-
}
|
|
48
|
-
values.push(args[index + 1]);
|
|
49
|
-
index += 1;
|
|
50
|
-
}
|
|
51
|
-
return values;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
39
|
function validateCommandArgs(
|
|
55
40
|
args,
|
|
56
41
|
startIndex,
|
|
@@ -106,6 +91,8 @@ async function initialize(args) {
|
|
|
106
91
|
print(result, args, (value) => [
|
|
107
92
|
`Workspace: ${value.workspace}`,
|
|
108
93
|
`Configuration: ${value.config.action}`,
|
|
94
|
+
`Task log: ${value.tasks.action}`,
|
|
95
|
+
`Legacy tasks: ${value.legacyTasks.action}`,
|
|
109
96
|
`Instructions: ${value.instructions.action}`,
|
|
110
97
|
`Legacy skill links removed: ${value.legacySkills.removed.length}`,
|
|
111
98
|
].join("\n"));
|
|
@@ -179,30 +166,21 @@ async function projectRemove(args) {
|
|
|
179
166
|
if (!args[2] || args[2].startsWith("--")) throw new Error("project remove requires a name");
|
|
180
167
|
validateCommandArgs(args, 3, {
|
|
181
168
|
values: ["--workspace"],
|
|
182
|
-
switches: ["--json"
|
|
183
|
-
});
|
|
184
|
-
const result = await removeProject(workspaceRoot(args), args[2], {
|
|
185
|
-
force: args.includes("--force"),
|
|
169
|
+
switches: ["--json"],
|
|
186
170
|
});
|
|
171
|
+
const result = await removeProject(workspaceRoot(args), args[2]);
|
|
187
172
|
print(result, args, (value) => `Removed ${value.project.name}: ${value.project.path}`);
|
|
188
173
|
return 0;
|
|
189
174
|
}
|
|
190
175
|
|
|
191
|
-
async function
|
|
176
|
+
async function taskRecord(args) {
|
|
192
177
|
validateCommandArgs(args, 2, { values: ["--workspace"], switches: ["--json"] });
|
|
193
|
-
const
|
|
194
|
-
print(
|
|
195
|
-
return 0;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async function update(args) {
|
|
199
|
-
validateCommandArgs(args, 3, { values: ["--workspace"], switches: ["--json"] });
|
|
200
|
-
const task = await updateTask(workspaceRoot(args), args[2], await readJsonStdin());
|
|
201
|
-
print(task, args, (value) => `Updated ${value.id}: ${value.status}`);
|
|
178
|
+
const dispatch = await recordTask(workspaceRoot(args), await readJsonStdin());
|
|
179
|
+
print(dispatch, args, (value) => `Recorded ${value.id}: ${value.title}`);
|
|
202
180
|
return 0;
|
|
203
181
|
}
|
|
204
182
|
|
|
205
|
-
async function
|
|
183
|
+
async function taskShow(args) {
|
|
206
184
|
validateCommandArgs(args, 3, { values: ["--workspace"], switches: ["--json"] });
|
|
207
185
|
print(await readTask(workspaceRoot(args), args[2]), args);
|
|
208
186
|
return 0;
|
|
@@ -210,24 +188,20 @@ async function show(args) {
|
|
|
210
188
|
|
|
211
189
|
async function taskList(args) {
|
|
212
190
|
validateCommandArgs(args, 2, {
|
|
213
|
-
values: ["--workspace", "--
|
|
191
|
+
values: ["--workspace", "--project"],
|
|
214
192
|
switches: ["--json"],
|
|
215
|
-
repeatable: ["--status"],
|
|
216
193
|
});
|
|
217
|
-
const
|
|
218
|
-
statuses: options(args, "--status"),
|
|
194
|
+
const dispatches = await filterTasks(workspaceRoot(args), {
|
|
219
195
|
project: option(args, "--project", null),
|
|
220
196
|
});
|
|
221
|
-
const
|
|
222
|
-
const projectNames = new Map(projects.map((project) => [project.path, project.name]));
|
|
223
|
-
const result = { taskCount: tasks.length, tasks };
|
|
197
|
+
const result = { taskCount: dispatches.length, tasks: dispatches };
|
|
224
198
|
print(result, args, (value) => table(
|
|
225
|
-
["ID", "
|
|
226
|
-
value.tasks.map((
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
199
|
+
["ID", "CREATED", "PROJECT", "TITLE"],
|
|
200
|
+
value.tasks.map((dispatch) => [
|
|
201
|
+
dispatch.id,
|
|
202
|
+
dispatch.createdAt,
|
|
203
|
+
dispatch.project.name,
|
|
204
|
+
dispatch.title,
|
|
231
205
|
]),
|
|
232
206
|
));
|
|
233
207
|
return 0;
|
|
@@ -238,23 +212,11 @@ async function taskSummary(args) {
|
|
|
238
212
|
const summary = await buildTaskSummary(workspaceRoot(args));
|
|
239
213
|
print(summary, args, (value) => [
|
|
240
214
|
`Tasks: ${value.taskCount}`,
|
|
241
|
-
...Object.entries(value.
|
|
215
|
+
...Object.entries(value.projectCounts).map(([project, count]) => `${project}: ${count}`),
|
|
242
216
|
].join("\n"));
|
|
243
217
|
return 0;
|
|
244
218
|
}
|
|
245
219
|
|
|
246
|
-
async function reconciliationCandidates(args) {
|
|
247
|
-
validateCommandArgs(args, 2, {
|
|
248
|
-
values: ["--workspace"],
|
|
249
|
-
switches: ["--json", "--include-finished"],
|
|
250
|
-
});
|
|
251
|
-
const result = await buildReconciliationCandidates(workspaceRoot(args), {
|
|
252
|
-
includeFinished: args.includes("--include-finished"),
|
|
253
|
-
});
|
|
254
|
-
print(result, args);
|
|
255
|
-
return 0;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
220
|
function usage() {
|
|
259
221
|
process.stdout.write(`TaskChef workspace utility
|
|
260
222
|
|
|
@@ -265,16 +227,14 @@ Usage:
|
|
|
265
227
|
taskchef project add <path> [--name <name>] [--description <text>] [--github-repo <url> | --no-github] [--json] [--workspace <path>]
|
|
266
228
|
taskchef project import [<file> | -] [--replace] [--json] [--workspace <path>]
|
|
267
229
|
taskchef project list [--json] [--workspace <path>]
|
|
268
|
-
taskchef project remove <name> [--
|
|
269
|
-
taskchef task
|
|
270
|
-
taskchef task update <task-id> [--json] [--workspace <path>]
|
|
230
|
+
taskchef project remove <name> [--json] [--workspace <path>]
|
|
231
|
+
taskchef task record [--json] [--workspace <path>]
|
|
271
232
|
taskchef task show <task-id> [--json] [--workspace <path>]
|
|
272
|
-
taskchef task list [--
|
|
233
|
+
taskchef task list [--project <name-or-path>] [--json] [--workspace <path>]
|
|
273
234
|
taskchef task summary [--json] [--workspace <path>]
|
|
274
|
-
taskchef task reconcile-candidates [--include-finished] [--json] [--workspace <path>]
|
|
275
235
|
|
|
276
|
-
Task
|
|
277
|
-
|
|
236
|
+
Task record reads JSON from standard input. Project import reads a JSON
|
|
237
|
+
array from a file, or from standard input when the source is '-' or omitted.
|
|
278
238
|
`);
|
|
279
239
|
}
|
|
280
240
|
|
|
@@ -289,14 +249,10 @@ export async function runCli(args) {
|
|
|
289
249
|
if (args[0] === "project" && args[1] === "import") return projectImport(args);
|
|
290
250
|
if (args[0] === "project" && args[1] === "list") return projectList(args);
|
|
291
251
|
if (args[0] === "project" && args[1] === "remove") return projectRemove(args);
|
|
292
|
-
if (args[0] === "task" && args[1] === "
|
|
293
|
-
if (args[0] === "task" && args[1] === "
|
|
294
|
-
if (args[0] === "task" && args[1] === "show" && args[2]) return show(args);
|
|
252
|
+
if (args[0] === "task" && args[1] === "record") return taskRecord(args);
|
|
253
|
+
if (args[0] === "task" && args[1] === "show" && args[2]) return taskShow(args);
|
|
295
254
|
if (args[0] === "task" && args[1] === "list") return taskList(args);
|
|
296
255
|
if (args[0] === "task" && args[1] === "summary") return taskSummary(args);
|
|
297
|
-
if (args[0] === "task" && args[1] === "reconcile-candidates") {
|
|
298
|
-
return reconciliationCandidates(args);
|
|
299
|
-
}
|
|
300
256
|
process.stderr.write(`Unknown command: ${args.join(" ")}\n`);
|
|
301
257
|
usage();
|
|
302
258
|
return 2;
|