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.
Files changed (149) hide show
  1. package/.codex-plugin/plugin.json +7 -10
  2. package/.mcp.json +3 -2
  3. package/README.md +31 -158
  4. package/docs/mcp-app.md +3 -3
  5. package/docs/spec.md +38 -746
  6. package/docs/taskchef-next-storage.md +2 -2
  7. package/index.js +2 -99
  8. package/package.json +12 -49
  9. package/skills/delegate/SKILL.md +44 -0
  10. package/skills/delegate/agents/openai.yaml +4 -0
  11. package/src/codex-app.js +3 -152
  12. package/src/codex-session-scanner.js +2 -2
  13. package/src/file-lock.js +25 -0
  14. package/src/mcp-app/react/NextTaskDetail.test.tsx +1 -1
  15. package/src/mcp-app/react/NextTaskDetail.tsx +8 -8
  16. package/src/mcp-app/react/main.test.tsx +3 -3
  17. package/src/mcp-app/react/main.tsx +7 -7
  18. package/src/mcp-app.js +2 -2
  19. package/src/mcp.js +4 -542
  20. package/src/next-cache.js +2 -2
  21. package/src/next-github.js +3 -3
  22. package/src/next-notifications.js +2 -2
  23. package/src/{dashboard/react → ui}/components/CardStatusIcons.tsx +1 -1
  24. package/src/{dashboard/react → ui}/components/GitHubLinks.tsx +1 -1
  25. package/src/{dashboard/react → ui}/components/LinkedText.tsx +1 -1
  26. package/src/{dashboard/react → ui}/components/RelativeTime.test.tsx +1 -1
  27. package/src/{dashboard/react → ui}/components/RelativeTime.tsx +1 -1
  28. package/src/{dashboard/react → ui}/components/ReplyImagePreview.test.tsx +1 -1
  29. package/src/{dashboard/react → ui}/components/TaskBoard.tsx +1 -1
  30. package/src/{dashboard/react → ui}/components/TaskCard.tsx +1 -1
  31. package/src/{dashboard/react → ui}/components/TurnContent.tsx +1 -1
  32. package/src/{dashboard/react → ui}/presentation.ts +1 -1
  33. package/src/version.js +0 -1
  34. package/BACKLOG.md +0 -48
  35. package/assets/e2e-benchmark-example.json +0 -50
  36. package/assets/taskchef-dispatcher-instructions.md +0 -44
  37. package/bin/taskchef.js +0 -20
  38. package/docs/advanced-guide.md +0 -497
  39. package/docs/dashboard-lifecycle.md +0 -149
  40. package/docs/dashboard-ui.md +0 -40
  41. package/docs/firstmate-taskchef-comparison.md +0 -283
  42. package/docs/images/ccusage-token-consumption.png +0 -0
  43. package/docs/images/dashboard-identity.jpg +0 -0
  44. package/docs/images/dashboard-token-pending.jpg +0 -0
  45. package/docs/images/interrupted-turn-recovery.jpg +0 -0
  46. package/docs/images/notification-event-snapshots.jpg +0 -0
  47. package/docs/images/readme-board.png +0 -0
  48. package/docs/images/readme-completed.png +0 -0
  49. package/docs/images/readme-list.png +0 -0
  50. package/docs/images/readme-needs-input.png +0 -0
  51. package/docs/images/readme-roles.png +0 -0
  52. package/docs/images/reported-work-duration-desktop.jpg +0 -0
  53. package/docs/images/reported-work-duration-mobile.jpg +0 -0
  54. package/docs/images/result-history-dashboard.jpg +0 -0
  55. package/docs/images/taskchef-pr-icon-comparison.jpg +0 -0
  56. package/docs/images/taskchef-unified-status-popup.jpg +0 -0
  57. package/docs/workflows.md +0 -476
  58. package/mcp/dashboard-session.js +0 -51
  59. package/scripts/benchmark-dispatch-prepare.js +0 -90
  60. package/scripts/e2e-benchmark.js +0 -206
  61. package/scripts/roles/resolve_roles.py +0 -293
  62. package/skills/taskchef-bootstrap/SKILL.md +0 -96
  63. package/skills/taskchef-bootstrap/agents/openai.yaml +0 -4
  64. package/skills/taskchef-bootstrap/references/project-index.md +0 -154
  65. package/skills/taskchef-copilot/SKILL.md +0 -75
  66. package/skills/taskchef-copilot/agents/openai.yaml +0 -4
  67. package/skills/taskchef-dashboard/SKILL.md +0 -24
  68. package/skills/taskchef-dashboard/agents/openai.yaml +0 -4
  69. package/skills/taskchef-delegate/SKILL.md +0 -102
  70. package/skills/taskchef-delegate/agents/openai.yaml +0 -4
  71. package/skills/taskchef-delegate/references/model-roles.md +0 -29
  72. package/skills/taskchef-executor/SKILL.md +0 -154
  73. package/skills/taskchef-executor/agents/openai.yaml +0 -4
  74. package/skills/taskchef-executor/references/compatibility.md +0 -22
  75. package/skills/taskchef-executor/references/ending-actions.md +0 -26
  76. package/src/backups.js +0 -359
  77. package/src/cli.js +0 -733
  78. package/src/config-audit.js +0 -99
  79. package/src/config-mutations.js +0 -106
  80. package/src/dashboard/actions.js +0 -136
  81. package/src/dashboard/app.js +0 -1172
  82. package/src/dashboard/dist/app.js +0 -269
  83. package/src/dashboard/dist/app.js.map +0 -1
  84. package/src/dashboard/dist/index.html +0 -16
  85. package/src/dashboard/dist/styles.css +0 -1
  86. package/src/dashboard/index.html +0 -148
  87. package/src/dashboard/react/App.test.tsx +0 -346
  88. package/src/dashboard/react/App.tsx +0 -515
  89. package/src/dashboard/react/api.test.ts +0 -40
  90. package/src/dashboard/react/api.ts +0 -103
  91. package/src/dashboard/react/components/ActivityTimeline.tsx +0 -118
  92. package/src/dashboard/react/components/ModelSettings.test.tsx +0 -180
  93. package/src/dashboard/react/components/ModelSettings.tsx +0 -106
  94. package/src/dashboard/react/components/NotificationCenter.test.tsx +0 -76
  95. package/src/dashboard/react/components/NotificationCenter.tsx +0 -111
  96. package/src/dashboard/react/components/PullRequestBadges.tsx +0 -18
  97. package/src/dashboard/react/components/TaskDetail.test.tsx +0 -255
  98. package/src/dashboard/react/components/TaskDetail.tsx +0 -271
  99. package/src/dashboard/react/components/UsagePanel.tsx +0 -96
  100. package/src/dashboard/react/index.html +0 -15
  101. package/src/dashboard/react/main.tsx +0 -12
  102. package/src/dashboard/react/overlay-state.test.ts +0 -110
  103. package/src/dashboard/react/overlay-state.ts +0 -60
  104. package/src/dashboard/react/presentation.test.tsx +0 -571
  105. package/src/dashboard/styles.css +0 -261
  106. package/src/dashboard-control.js +0 -34
  107. package/src/dashboard-manager.js +0 -339
  108. package/src/dashboard-session-process.js +0 -88
  109. package/src/dashboard-session.js +0 -86
  110. package/src/dashboard.js +0 -1303
  111. package/src/delegation.js +0 -277
  112. package/src/github.js +0 -107
  113. package/src/model-roles.js +0 -70
  114. package/src/recorded-usage-tracker.js +0 -92
  115. package/src/usage-tracker.js +0 -650
  116. package/src/usage.js +0 -367
  117. package/src/workspace-path.js +0 -48
  118. package/src/workspace.js +0 -3629
  119. /package/src/{dashboard/react → ui}/components/AnimatedUsage.test.tsx +0 -0
  120. /package/src/{dashboard/react → ui}/components/CardStatusIcons.test.tsx +0 -0
  121. /package/src/{dashboard/react → ui}/components/ImageGallery.tsx +0 -0
  122. /package/src/{dashboard/react → ui}/components/OpenChatButton.test.tsx +0 -0
  123. /package/src/{dashboard/react → ui}/components/OpenChatButton.tsx +0 -0
  124. /package/src/{dashboard/react → ui}/components/PrGlyph.tsx +0 -0
  125. /package/src/{dashboard/react → ui}/components/QueuedPrompts.test.tsx +0 -0
  126. /package/src/{dashboard/react → ui}/components/QueuedPrompts.tsx +0 -0
  127. /package/src/{dashboard/react → ui}/components/ReplyCover.test.tsx +0 -0
  128. /package/src/{dashboard/react → ui}/components/ReplyCover.tsx +0 -0
  129. /package/src/{dashboard/react → ui}/components/ReplyImagePreview.tsx +0 -0
  130. /package/src/{dashboard/react → ui}/components/ReplyMarkdown.test.tsx +0 -0
  131. /package/src/{dashboard/react → ui}/components/ReplyMarkdown.tsx +0 -0
  132. /package/src/{dashboard/react → ui}/components/SavedUsageFormat.test.tsx +0 -0
  133. /package/src/{dashboard/react → ui}/components/SavedUsageFormat.tsx +0 -0
  134. /package/src/{dashboard/react → ui}/components/ShimmerText.tsx +0 -0
  135. /package/src/{dashboard/react → ui}/components/StatsGrid.tsx +0 -0
  136. /package/src/{dashboard/react → ui}/components/StatusBadge.tsx +0 -0
  137. /package/src/{dashboard/react → ui}/components/TaskBoard.test.tsx +0 -0
  138. /package/src/{dashboard/react → ui}/components/TaskCardStats.test.tsx +0 -0
  139. /package/src/{dashboard/react → ui}/components/TaskCardStats.tsx +0 -0
  140. /package/src/{dashboard/react → ui}/components/TurnContent.test.tsx +0 -0
  141. /package/src/{dashboard/react → ui}/fixtures.ts +0 -0
  142. /package/src/{dashboard → ui}/github-links.js +0 -0
  143. /package/src/{dashboard/react → ui}/image-cache.test.ts +0 -0
  144. /package/src/{dashboard/react → ui}/image-cache.ts +0 -0
  145. /package/src/{dashboard → ui}/state.js +0 -0
  146. /package/src/{dashboard/react → ui}/styles.css +0 -0
  147. /package/src/{dashboard/react → ui}/test-setup.ts +0 -0
  148. /package/src/{dashboard → ui}/time.js +0 -0
  149. /package/src/{dashboard/react → ui}/types.ts +0 -0
@@ -1,110 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { fixtureTask } from "./fixtures";
3
- import type { NotificationSnapshot } from "./types";
4
- import {
5
- clearNotificationHistory,
6
- listUsageSignature,
7
- mergeListTaskIntoDetail,
8
- notificationAppeared,
9
- notificationClicked,
10
- type OverlayState,
11
- } from "./overlay-state";
12
-
13
- const taskUpdate: NotificationSnapshot = {
14
- id: "task-one-completed",
15
- taskId: "task-one",
16
- title: "Review reconciliation",
17
- status: "completed",
18
- event: "completed",
19
- turnRef: "turn-two",
20
- turnId: null,
21
- timestamp: "2026-08-30T08:10:00.000Z",
22
- summary: "Review completed.",
23
- };
24
- const unrelated: NotificationSnapshot = {
25
- ...taskUpdate,
26
- id: "task-two-failed",
27
- taskId: "task-two",
28
- title: "Validate fixture",
29
- status: "failed",
30
- event: "failed",
31
- turnRef: "turn-three",
32
- };
33
-
34
- function state(overrides: Partial<OverlayState> = {}): OverlayState {
35
- return {
36
- detailTaskId: null,
37
- detailOpened: false,
38
- highlightTurnRef: null,
39
- notifications: [],
40
- refreshGeneration: 0,
41
- ...overrides,
42
- };
43
- }
44
-
45
- describe("overlay coordination", () => {
46
- test("a later notification changes visibility without changing the open detail", () => {
47
- const open = state({ detailTaskId: "task-one", detailOpened: true });
48
- expect(notificationAppeared(open, [taskUpdate])).toEqual({
49
- ...open,
50
- notifications: [taskUpdate],
51
- });
52
- });
53
-
54
- test("clicking a notification dismisses only it and opens its detail above prior content", () => {
55
- const next = notificationClicked(state({ notifications: [taskUpdate, unrelated] }), taskUpdate, true);
56
- expect(next.detailOpened).toBe(true);
57
- expect(next.detailTaskId).toBe("task-one");
58
- expect(next.highlightTurnRef).toBe("turn-two");
59
- expect(next.notifications).toEqual([unrelated]);
60
- expect(next.refreshGeneration).toBe(1);
61
- });
62
-
63
- test("clicking an update for the already-open task refreshes and highlights without closing unrelated messages", () => {
64
- const current = state({
65
- detailTaskId: "task-one",
66
- detailOpened: true,
67
- notifications: [taskUpdate, unrelated],
68
- refreshGeneration: 4,
69
- });
70
- const next = notificationClicked(current, taskUpdate, true);
71
- expect(next.detailTaskId).toBe(current.detailTaskId);
72
- expect(next.detailOpened).toBe(true);
73
- expect(next.highlightTurnRef).toBe("turn-two");
74
- expect(next.refreshGeneration).toBe(5);
75
- expect(next.notifications).toEqual([unrelated]);
76
- });
77
-
78
- test("clearing notification history leaves detail state untouched", () => {
79
- const current = state({ detailTaskId: "task-one", detailOpened: true, notifications: [taskUpdate] });
80
- expect(clearNotificationHistory(current)).toEqual({ ...current, notifications: [] });
81
- });
82
-
83
- test("a cache-only list update preserves rich detail usage and requests a refresh", () => {
84
- const detail = fixtureTask({
85
- usage: {
86
- generationTurnRef: "turn-one",
87
- status: "available",
88
- task: { totalTokens: 1200, estimatedCostUsd: 0.24, models: { "gpt-5": {} } },
89
- turns: { "turn-one": { status: "available", totalTokens: 1200 } },
90
- updatedAt: "2026-08-30T08:00:00.000Z",
91
- },
92
- });
93
- const list = fixtureTask({
94
- turns: undefined,
95
- results: undefined,
96
- usage: {
97
- generationTurnRef: "turn-one",
98
- status: "available",
99
- task: { totalTokens: 1800, estimatedCostUsd: 0.36 },
100
- updatedAt: "2026-08-30T08:01:00.000Z",
101
- },
102
- });
103
-
104
- const merged = mergeListTaskIntoDetail(detail, list);
105
- expect(merged.usage).toBe(detail.usage);
106
- expect(merged.turns).toBe(detail.turns);
107
- expect(merged.results).toBe(detail.results);
108
- expect(listUsageSignature(list)).not.toBe(listUsageSignature(detail));
109
- });
110
- });
@@ -1,60 +0,0 @@
1
- import type { NotificationSnapshot, Task } from "./types";
2
-
3
- export interface OverlayState {
4
- detailTaskId: string | null;
5
- detailOpened: boolean;
6
- highlightTurnRef: string | null;
7
- notifications: NotificationSnapshot[];
8
- refreshGeneration: number;
9
- }
10
-
11
- export function notificationAppeared(
12
- state: OverlayState,
13
- notifications: NotificationSnapshot[],
14
- ): OverlayState {
15
- // Visibility changes only; focus remains where the operator left it.
16
- return { ...state, notifications };
17
- }
18
-
19
- export function notificationClicked(
20
- state: OverlayState,
21
- notification: NotificationSnapshot,
22
- taskAvailable: boolean,
23
- ): OverlayState {
24
- const notifications = state.notifications.filter(({ id }) => id !== notification.id);
25
- if (!taskAvailable) return { ...state, notifications };
26
- return {
27
- ...state,
28
- detailTaskId: notification.taskId,
29
- detailOpened: true,
30
- highlightTurnRef: notification.turnRef ?? notification.turnId,
31
- notifications,
32
- refreshGeneration: state.refreshGeneration + 1,
33
- };
34
- }
35
-
36
- export function clearNotificationHistory(state: OverlayState): OverlayState {
37
- return { ...state, notifications: [] };
38
- }
39
-
40
- export function mergeListTaskIntoDetail(current: Task, updated: Task): Task {
41
- const currentIsDetail = Array.isArray(current.turns) && Array.isArray(current.results);
42
- const updatedIsList = !Array.isArray(updated.turns) && !Array.isArray(updated.results);
43
- return {
44
- ...current,
45
- ...updated,
46
- ...(currentIsDetail && updatedIsList
47
- ? { results: current.results, turns: current.turns, usage: current.usage }
48
- : {}),
49
- };
50
- }
51
-
52
- export function listUsageSignature(task: Task | null | undefined): string {
53
- return JSON.stringify([
54
- task?.usage?.generationTurnRef ?? null,
55
- task?.usage?.status ?? null,
56
- task?.usage?.updatedAt ?? null,
57
- task?.usage?.task?.totalTokens ?? null,
58
- task?.usage?.task?.estimatedCostUsd ?? null,
59
- ]);
60
- }