taskchef 8.7.1 → 9.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.
Files changed (150) hide show
  1. package/.codex-plugin/plugin.json +7 -10
  2. package/.mcp.json +3 -2
  3. package/README.md +35 -158
  4. package/docs/mcp-app.md +23 -6
  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/user-prompt.js +11 -0
  34. package/src/version.js +0 -1
  35. package/BACKLOG.md +0 -48
  36. package/assets/e2e-benchmark-example.json +0 -50
  37. package/assets/taskchef-dispatcher-instructions.md +0 -44
  38. package/bin/taskchef.js +0 -20
  39. package/docs/advanced-guide.md +0 -497
  40. package/docs/dashboard-lifecycle.md +0 -149
  41. package/docs/dashboard-ui.md +0 -40
  42. package/docs/firstmate-taskchef-comparison.md +0 -283
  43. package/docs/images/ccusage-token-consumption.png +0 -0
  44. package/docs/images/dashboard-identity.jpg +0 -0
  45. package/docs/images/dashboard-token-pending.jpg +0 -0
  46. package/docs/images/interrupted-turn-recovery.jpg +0 -0
  47. package/docs/images/notification-event-snapshots.jpg +0 -0
  48. package/docs/images/readme-board.png +0 -0
  49. package/docs/images/readme-completed.png +0 -0
  50. package/docs/images/readme-list.png +0 -0
  51. package/docs/images/readme-needs-input.png +0 -0
  52. package/docs/images/readme-roles.png +0 -0
  53. package/docs/images/reported-work-duration-desktop.jpg +0 -0
  54. package/docs/images/reported-work-duration-mobile.jpg +0 -0
  55. package/docs/images/result-history-dashboard.jpg +0 -0
  56. package/docs/images/taskchef-pr-icon-comparison.jpg +0 -0
  57. package/docs/images/taskchef-unified-status-popup.jpg +0 -0
  58. package/docs/workflows.md +0 -476
  59. package/mcp/dashboard-session.js +0 -51
  60. package/scripts/benchmark-dispatch-prepare.js +0 -90
  61. package/scripts/e2e-benchmark.js +0 -206
  62. package/scripts/roles/resolve_roles.py +0 -293
  63. package/skills/taskchef-bootstrap/SKILL.md +0 -96
  64. package/skills/taskchef-bootstrap/agents/openai.yaml +0 -4
  65. package/skills/taskchef-bootstrap/references/project-index.md +0 -154
  66. package/skills/taskchef-copilot/SKILL.md +0 -75
  67. package/skills/taskchef-copilot/agents/openai.yaml +0 -4
  68. package/skills/taskchef-dashboard/SKILL.md +0 -24
  69. package/skills/taskchef-dashboard/agents/openai.yaml +0 -4
  70. package/skills/taskchef-delegate/SKILL.md +0 -102
  71. package/skills/taskchef-delegate/agents/openai.yaml +0 -4
  72. package/skills/taskchef-delegate/references/model-roles.md +0 -29
  73. package/skills/taskchef-executor/SKILL.md +0 -154
  74. package/skills/taskchef-executor/agents/openai.yaml +0 -4
  75. package/skills/taskchef-executor/references/compatibility.md +0 -22
  76. package/skills/taskchef-executor/references/ending-actions.md +0 -26
  77. package/src/backups.js +0 -359
  78. package/src/cli.js +0 -733
  79. package/src/config-audit.js +0 -99
  80. package/src/config-mutations.js +0 -106
  81. package/src/dashboard/actions.js +0 -136
  82. package/src/dashboard/app.js +0 -1172
  83. package/src/dashboard/dist/app.js +0 -269
  84. package/src/dashboard/dist/app.js.map +0 -1
  85. package/src/dashboard/dist/index.html +0 -16
  86. package/src/dashboard/dist/styles.css +0 -1
  87. package/src/dashboard/index.html +0 -148
  88. package/src/dashboard/react/App.test.tsx +0 -346
  89. package/src/dashboard/react/App.tsx +0 -515
  90. package/src/dashboard/react/api.test.ts +0 -40
  91. package/src/dashboard/react/api.ts +0 -103
  92. package/src/dashboard/react/components/ActivityTimeline.tsx +0 -118
  93. package/src/dashboard/react/components/ModelSettings.test.tsx +0 -180
  94. package/src/dashboard/react/components/ModelSettings.tsx +0 -106
  95. package/src/dashboard/react/components/NotificationCenter.test.tsx +0 -76
  96. package/src/dashboard/react/components/NotificationCenter.tsx +0 -111
  97. package/src/dashboard/react/components/PullRequestBadges.tsx +0 -18
  98. package/src/dashboard/react/components/TaskDetail.test.tsx +0 -255
  99. package/src/dashboard/react/components/TaskDetail.tsx +0 -271
  100. package/src/dashboard/react/components/UsagePanel.tsx +0 -96
  101. package/src/dashboard/react/index.html +0 -15
  102. package/src/dashboard/react/main.tsx +0 -12
  103. package/src/dashboard/react/overlay-state.test.ts +0 -110
  104. package/src/dashboard/react/overlay-state.ts +0 -60
  105. package/src/dashboard/react/presentation.test.tsx +0 -571
  106. package/src/dashboard/styles.css +0 -261
  107. package/src/dashboard-control.js +0 -34
  108. package/src/dashboard-manager.js +0 -339
  109. package/src/dashboard-session-process.js +0 -88
  110. package/src/dashboard-session.js +0 -86
  111. package/src/dashboard.js +0 -1303
  112. package/src/delegation.js +0 -277
  113. package/src/github.js +0 -107
  114. package/src/model-roles.js +0 -70
  115. package/src/recorded-usage-tracker.js +0 -92
  116. package/src/usage-tracker.js +0 -650
  117. package/src/usage.js +0 -367
  118. package/src/workspace-path.js +0 -48
  119. package/src/workspace.js +0 -3629
  120. /package/src/{dashboard/react → ui}/components/AnimatedUsage.test.tsx +0 -0
  121. /package/src/{dashboard/react → ui}/components/CardStatusIcons.test.tsx +0 -0
  122. /package/src/{dashboard/react → ui}/components/ImageGallery.tsx +0 -0
  123. /package/src/{dashboard/react → ui}/components/OpenChatButton.test.tsx +0 -0
  124. /package/src/{dashboard/react → ui}/components/OpenChatButton.tsx +0 -0
  125. /package/src/{dashboard/react → ui}/components/PrGlyph.tsx +0 -0
  126. /package/src/{dashboard/react → ui}/components/QueuedPrompts.test.tsx +0 -0
  127. /package/src/{dashboard/react → ui}/components/QueuedPrompts.tsx +0 -0
  128. /package/src/{dashboard/react → ui}/components/ReplyCover.test.tsx +0 -0
  129. /package/src/{dashboard/react → ui}/components/ReplyCover.tsx +0 -0
  130. /package/src/{dashboard/react → ui}/components/ReplyImagePreview.tsx +0 -0
  131. /package/src/{dashboard/react → ui}/components/ReplyMarkdown.test.tsx +0 -0
  132. /package/src/{dashboard/react → ui}/components/ReplyMarkdown.tsx +0 -0
  133. /package/src/{dashboard/react → ui}/components/SavedUsageFormat.test.tsx +0 -0
  134. /package/src/{dashboard/react → ui}/components/SavedUsageFormat.tsx +0 -0
  135. /package/src/{dashboard/react → ui}/components/ShimmerText.tsx +0 -0
  136. /package/src/{dashboard/react → ui}/components/StatsGrid.tsx +0 -0
  137. /package/src/{dashboard/react → ui}/components/StatusBadge.tsx +0 -0
  138. /package/src/{dashboard/react → ui}/components/TaskBoard.test.tsx +0 -0
  139. /package/src/{dashboard/react → ui}/components/TaskCardStats.test.tsx +0 -0
  140. /package/src/{dashboard/react → ui}/components/TaskCardStats.tsx +0 -0
  141. /package/src/{dashboard/react → ui}/components/TurnContent.test.tsx +0 -0
  142. /package/src/{dashboard/react → ui}/fixtures.ts +0 -0
  143. /package/src/{dashboard → ui}/github-links.js +0 -0
  144. /package/src/{dashboard/react → ui}/image-cache.test.ts +0 -0
  145. /package/src/{dashboard/react → ui}/image-cache.ts +0 -0
  146. /package/src/{dashboard → ui}/state.js +0 -0
  147. /package/src/{dashboard/react → ui}/styles.css +0 -0
  148. /package/src/{dashboard/react → ui}/test-setup.ts +0 -0
  149. /package/src/{dashboard → ui}/time.js +0 -0
  150. /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
- }