taskchef 8.7.0 → 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 +21 -4
- 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 +4 -4
- 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 +2 -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
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { realpath } from "node:fs/promises";
|
|
2
|
-
|
|
3
|
-
import { createDashboardServer } from "./dashboard.js";
|
|
4
|
-
import { createDashboardSessionLease, validSessionPid } from "./dashboard-session.js";
|
|
5
|
-
import { DASHBOARD_SERVER_VERSION, TASKCHEF_VERSION } from "./version.js";
|
|
6
|
-
|
|
7
|
-
export async function runDashboardSessionProcess({
|
|
8
|
-
workspace = process.env.TASKCHEF_DASHBOARD_WORKSPACE,
|
|
9
|
-
host = process.env.TASKCHEF_DASHBOARD_HOST ?? "127.0.0.1",
|
|
10
|
-
port = Number(process.env.TASKCHEF_DASHBOARD_PORT ?? 3210),
|
|
11
|
-
sessionPid = Number(process.env.TASKCHEF_DASHBOARD_SESSION_PID),
|
|
12
|
-
taskchefVersion = TASKCHEF_VERSION,
|
|
13
|
-
serverVersion = DASHBOARD_SERVER_VERSION,
|
|
14
|
-
createServer = createDashboardServer,
|
|
15
|
-
createLease = createDashboardSessionLease,
|
|
16
|
-
processObject = process,
|
|
17
|
-
signal,
|
|
18
|
-
checkIntervalMs = Number(process.env.TASKCHEF_DASHBOARD_CHECK_INTERVAL_MS ?? 1_000),
|
|
19
|
-
exitGraceMs = Number(process.env.TASKCHEF_DASHBOARD_EXIT_GRACE_MS ?? 15_000),
|
|
20
|
-
} = {}) {
|
|
21
|
-
if (processObject.env) {
|
|
22
|
-
delete processObject.env.TASKCHEF_DASHBOARD_SECRET;
|
|
23
|
-
delete processObject.env.TASKCHEF_DASHBOARD_SESSION_PIDS;
|
|
24
|
-
}
|
|
25
|
-
if (!workspace) throw new Error("dashboard session workspace is required");
|
|
26
|
-
if (!validSessionPid(sessionPid)) throw new Error("dashboard session PID is invalid");
|
|
27
|
-
|
|
28
|
-
const canonicalWorkspace = await realpath(workspace);
|
|
29
|
-
let server = null;
|
|
30
|
-
let lease = null;
|
|
31
|
-
let closePromise = null;
|
|
32
|
-
let closeChain = Promise.resolve();
|
|
33
|
-
let closedLease = null;
|
|
34
|
-
let closedServer = null;
|
|
35
|
-
let closing = false;
|
|
36
|
-
const abortError = () => Object.assign(new Error("dashboard session startup was cancelled"), {
|
|
37
|
-
code: "TASKCHEF_DASHBOARD_START_TIMEOUT",
|
|
38
|
-
});
|
|
39
|
-
const removeListeners = () => {
|
|
40
|
-
processObject.off("SIGINT", close);
|
|
41
|
-
processObject.off("SIGTERM", close);
|
|
42
|
-
};
|
|
43
|
-
const close = () => {
|
|
44
|
-
closing = true;
|
|
45
|
-
closePromise = closeChain.then(async () => {
|
|
46
|
-
let failure = null;
|
|
47
|
-
if (lease && lease !== closedLease) {
|
|
48
|
-
closedLease = lease;
|
|
49
|
-
try { lease.close(); } catch (error) { failure = error; }
|
|
50
|
-
}
|
|
51
|
-
if (server && server !== closedServer) {
|
|
52
|
-
closedServer = server;
|
|
53
|
-
try { await server.close(); } catch (error) { failure ??= error; }
|
|
54
|
-
}
|
|
55
|
-
if (failure) throw failure;
|
|
56
|
-
}).finally(removeListeners);
|
|
57
|
-
closeChain = closePromise.catch(() => {});
|
|
58
|
-
return closePromise;
|
|
59
|
-
};
|
|
60
|
-
const onAbort = () => { void close().catch(() => {}); };
|
|
61
|
-
if (signal?.aborted) throw abortError();
|
|
62
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
63
|
-
processObject.once("SIGINT", close);
|
|
64
|
-
processObject.once("SIGTERM", close);
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const control = {
|
|
68
|
-
onShutdown: close,
|
|
69
|
-
onSession: (pid) => {
|
|
70
|
-
if (closing) throw Object.assign(new Error("dashboard session is retiring"), {
|
|
71
|
-
code: "TASKCHEF_DASHBOARD_SESSION_RETIRING",
|
|
72
|
-
});
|
|
73
|
-
lease.register(pid);
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
server = await createServer({ workspace: canonicalWorkspace, host, port,
|
|
77
|
-
taskchefVersion, serverVersion, launcher: "session", control });
|
|
78
|
-
if (closing || signal?.aborted) throw abortError();
|
|
79
|
-
lease = createLease({ initialPid: sessionPid, checkIntervalMs, exitGraceMs, onExpire: close });
|
|
80
|
-
if (closing || signal?.aborted) throw abortError();
|
|
81
|
-
signal?.removeEventListener("abort", onAbort);
|
|
82
|
-
return { server, lease, close };
|
|
83
|
-
} catch (error) {
|
|
84
|
-
signal?.removeEventListener("abort", onAbort);
|
|
85
|
-
await close().catch(() => {});
|
|
86
|
-
throw error;
|
|
87
|
-
}
|
|
88
|
-
}
|
package/src/dashboard-session.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
const DEFAULT_CHECK_INTERVAL_MS = 1_000;
|
|
2
|
-
const DEFAULT_EXIT_GRACE_MS = 15_000;
|
|
3
|
-
export const MAX_DASHBOARD_SESSION_PIDS = 64;
|
|
4
|
-
|
|
5
|
-
export function processIsAlive(pid, processObject = process) {
|
|
6
|
-
try {
|
|
7
|
-
processObject.kill(pid, 0);
|
|
8
|
-
return true;
|
|
9
|
-
} catch (error) {
|
|
10
|
-
return error?.code === "EPERM";
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function validSessionPid(pid) {
|
|
15
|
-
return Number.isSafeInteger(pid) && pid > 1;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function createDashboardSessionLease({
|
|
19
|
-
initialPid,
|
|
20
|
-
checkIntervalMs = DEFAULT_CHECK_INTERVAL_MS,
|
|
21
|
-
exitGraceMs = DEFAULT_EXIT_GRACE_MS,
|
|
22
|
-
isAlive = processIsAlive,
|
|
23
|
-
now = Date.now,
|
|
24
|
-
onExpire,
|
|
25
|
-
} = {}) {
|
|
26
|
-
if (!validSessionPid(initialPid)) throw new Error("dashboard session PID is invalid");
|
|
27
|
-
if (!Number.isFinite(checkIntervalMs) || checkIntervalMs <= 0) {
|
|
28
|
-
throw new Error("dashboard session check interval must be positive");
|
|
29
|
-
}
|
|
30
|
-
if (!Number.isFinite(exitGraceMs) || exitGraceMs < 0) {
|
|
31
|
-
throw new Error("dashboard session exit grace must be non-negative");
|
|
32
|
-
}
|
|
33
|
-
if (typeof onExpire !== "function") throw new Error("dashboard session expiry callback is required");
|
|
34
|
-
|
|
35
|
-
const pids = new Set([initialPid]);
|
|
36
|
-
let absentSince = null;
|
|
37
|
-
let expiryPromise = null;
|
|
38
|
-
let timer = null;
|
|
39
|
-
|
|
40
|
-
const activePids = () => {
|
|
41
|
-
let active = false;
|
|
42
|
-
for (const pid of pids) {
|
|
43
|
-
if (isAlive(pid)) active = true;
|
|
44
|
-
else pids.delete(pid);
|
|
45
|
-
}
|
|
46
|
-
return active;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const tick = () => {
|
|
50
|
-
if (expiryPromise) return;
|
|
51
|
-
const active = activePids();
|
|
52
|
-
if (active) {
|
|
53
|
-
absentSince = null;
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
absentSince ??= now();
|
|
57
|
-
if (now() - absentSince < exitGraceMs) return;
|
|
58
|
-
expiryPromise = Promise.resolve().then(onExpire).catch(() => {});
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
timer = setInterval(tick, checkIntervalMs);
|
|
62
|
-
timer.unref?.();
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
register(pid) {
|
|
66
|
-
if (!validSessionPid(pid)) throw new Error("dashboard session PID is invalid");
|
|
67
|
-
if (expiryPromise) {
|
|
68
|
-
throw Object.assign(new Error("dashboard session is expiring"), {
|
|
69
|
-
code: "TASKCHEF_DASHBOARD_SESSION_RETIRING",
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
activePids();
|
|
73
|
-
if (!pids.has(pid) && pids.size >= MAX_DASHBOARD_SESSION_PIDS) {
|
|
74
|
-
throw new Error("dashboard session PID limit reached");
|
|
75
|
-
}
|
|
76
|
-
pids.add(pid);
|
|
77
|
-
absentSince = null;
|
|
78
|
-
},
|
|
79
|
-
tick,
|
|
80
|
-
close() {
|
|
81
|
-
if (timer) clearInterval(timer);
|
|
82
|
-
timer = null;
|
|
83
|
-
},
|
|
84
|
-
get sessionCount() { return pids.size; },
|
|
85
|
-
};
|
|
86
|
-
}
|