taskchef 9.0.1 → 9.0.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "9.0.1",
3
+ "version": "9.0.2",
4
4
  "description": "Native Codex dashboard with lightweight project delegation.",
5
5
  "author": {
6
6
  "name": "Favo Yang",
package/docs/mcp-app.md CHANGED
@@ -45,7 +45,7 @@ See the [storage schema](taskchef-next-storage.md), including the editable diagr
45
45
 
46
46
  ### TaskChef card content
47
47
 
48
- Cards show the chat title, project, a plain two-line preview, activity time, and Open chat. Running cards show the current request; other cards show the latest response. Excerpts are capped at 2,000 characters. Actual scheduled inputs display the recorded heartbeat instructions, even after the schedule is removed. No model summarizes or judges the text.
48
+ Cards show the chat title, project, a plain two-line preview, activity time, and Open chat. Running cards show the current request; other cards show the latest response. Interrupted cards also show the latest turn’s recorded error message, when available. Details show the same message in a rounded notice after the response. A new running or completed turn clears the notice. Excerpts are capped at 2,000 characters. Actual scheduled inputs display the recorded heartbeat instructions, even after the schedule is removed. No model summarizes or judges the text.
49
49
 
50
50
  Details pairs the full recorded latest-turn request and response, each initially capped at three lines with independent Show more/Show less controls. Selected quotes render as Markdown quotes and file/image references as named attachments. Generated request headings and context metadata are hidden in the display. Recorded input remains unchanged. Raw HTML is ignored and relative file links appear as text.
51
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "9.0.1",
3
+ "version": "9.0.2",
4
4
  "description": "A native Codex dashboard for chats, usage, pull requests, and schedules.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Favo Yang",
@@ -232,7 +232,8 @@ function readDatabaseRecords(state, history) {
232
232
  const eligible = `coalesce(thread_source, '') NOT IN ('subagent', 'guardian_review')
233
233
  AND CASE WHEN json_valid(source) THEN json_type(source, '$.subagent') IS NULL ELSE 1 END
234
234
  AND NOT EXISTS (SELECT 1 FROM thread_spawn_edges WHERE child_thread_id = threads.id)`;
235
- const latestTurn = history.prepare(`SELECT turn_id, status, started_at, duration_ms, first_user_item_id, final_agent_item_id
235
+ const hasTurnError = history.prepare("PRAGMA table_info(thread_turns)").all().some(column => column.name === "error_json");
236
+ const latestTurn = history.prepare(`SELECT turn_id, status, started_at, duration_ms, first_user_item_id, final_agent_item_id, ${hasTurnError ? "error_json" : "NULL AS error_json"}
236
237
  FROM thread_turns WHERE thread_id = ? ORDER BY rollout_ordinal DESC LIMIT 1`);
237
238
  const turns = new Map();
238
239
  const needsAnswers = new Map();
@@ -334,6 +335,13 @@ function buildDatabaseSnapshot(records, now, doneMarks, schedules, scheduleError
334
335
  const status = row.archived ? "archived" : manualDone ? "completed" : manualScheduled ? "scheduled" : active ? "working"
335
336
  : ["failed", "interrupted"].includes(turn.status) ? "interrupted"
336
337
  : turn.status === "completed" ? scheduled && inputSource === "scheduled" ? "scheduled" : "needs_input" : null;
338
+ let turnError = null;
339
+ if (status === "interrupted" && turn.error_json) {
340
+ try {
341
+ const error = JSON.parse(turn.error_json);
342
+ if (typeof error?.message === "string") turnError = error.message.trim() || null;
343
+ } catch { /* Invalid optional error metadata must not hide the chat. */ }
344
+ }
337
345
  const statusLabel = status === "archived" ? "Archived" : status === "completed" ? "Done" : status === "working" ? "Running" : status === "needs_input" ? "Waiting for input/review" : status === "scheduled" ? "Scheduled" : status === "interrupted" ? "Interrupted" : "Unverified";
338
346
  const reason = row.archived ? "Chat is archived." : manualDone ? "Marked Done in TaskChef. A new turn resets this mark."
339
347
  : active ? "Latest selected turn is in progress."
@@ -344,7 +352,7 @@ function buildDatabaseSnapshot(records, now, doneMarks, schedules, scheduleError
344
352
  return {
345
353
  id: row.id, title: row.name?.trim() || row.title?.trim() || `Codex chat ${row.id.slice(0, 8)}`,
346
354
  instruction: "Chat name and title are local metadata and can contain user text.",
347
- summary: reason, promptExcerpt, replyExcerpt, annotations, promptImages, promptImage: promptImages[0] ?? null, replyImage: images.get(row.id),
355
+ summary: reason, turnError, promptExcerpt, replyExcerpt, annotations, promptImages, promptImage: promptImages[0] ?? null, replyImage: images.get(row.id),
348
356
  needsAnswer: !row.archived && (records.needsAnswers.get(historyId(row))?.length ?? 0) > 0,
349
357
  pendingQuestions: row.archived ? [] : records.needsAnswers.get(historyId(row)) ?? [],
350
358
  status, statusLabel, scheduled, nextRunAt, manualDone, manualScheduled, inputSource,
@@ -542,7 +550,7 @@ export class CodexSessionScanner {
542
550
  catch { throw new ProjectMetadataError("TaskChef cannot read Codex project metadata. Check .codex-global-state.json and the project worktree metadata, then refresh."); }
543
551
  const nextTasks = new Map(grouped.tasks.map((task) => [task.id, task]));
544
552
  const signature = (tasks) => JSON.stringify([...tasks.values()].map((task) => [
545
- task.id, task.title, task.project.path, task.project.id, task.project.name, task.updatedAt, task.status, task.summary,
553
+ task.id, task.title, task.project.path, task.project.id, task.project.name, task.updatedAt, task.status, task.summary, task.turnError,
546
554
  task.observed.archive, task.observed.unread, task.observed.lastTurnEvent, task.observed.directChildCount, task.observed.latestTurnDurationMs,
547
555
  task.scheduled, task.nextRunAt, task.inputSource, task.turnId, task.promptExcerpt, task.replyExcerpt, task.annotations, task.promptImages, task.promptImage, task.replyImage, task.queuedPrompts, task.needsAnswer, task.pendingQuestions, task.pullRequests,
548
556
  ]));