@workerdeck/core 1.4.0 → 2.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/build/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
3
  import { getSessionInfo, getSessionMessages, listSessions, query } from "@anthropic-ai/claude-agent-sdk";
4
- import { ENGINE_CAPABILITIES, PROTOCOL_VERSION, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, contextReading, imagePartRef, replayCoalesceKey, replayRetains, sanitizeToolTitle, snapshotRetains, transcriptActivity, transcriptContent, transcriptProse } from "@workerdeck/protocol";
4
+ import { CHECKLIST_TEXT_MAX, ENGINE_CAPABILITIES, PROTOCOL_VERSION, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, contextReading, imagePartRef, parseTodoWriteInput, replayCoalesceKey, replayRetains, sanitizeToolTitle, snapshotRetains, transcriptActivity, transcriptContent, transcriptProse } from "@workerdeck/protocol";
5
5
  import { ToolLoopAgent, generateText, isStepCount, tool } from "ai";
6
6
  import { execFile, spawn } from "node:child_process";
7
7
  import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
@@ -85,6 +85,55 @@ function decodeText(base64) {
85
85
  return Buffer.from(base64, "base64").toString("utf8");
86
86
  }
87
87
  //#endregion
88
+ //#region src/lib/checklist.ts
89
+ const TODO_WRITE = "TodoWrite";
90
+ function clamp(items) {
91
+ return items.map((item) => item.text.length > CHECKLIST_TEXT_MAX ? {
92
+ ...item,
93
+ text: item.text.slice(0, CHECKLIST_TEXT_MAX)
94
+ } : item);
95
+ }
96
+ function checklistFromBody(body) {
97
+ if (body.type !== "assistant_message" || body.parentToolUseId != null) return;
98
+ const content = body.message.content;
99
+ if (typeof content === "string") return;
100
+ let items;
101
+ for (const block of content) {
102
+ if (block.type !== "tool_use" || block.name !== TODO_WRITE) continue;
103
+ items = parseTodoWriteInput(block.input) ?? items;
104
+ }
105
+ return items === void 0 ? void 0 : clamp(items);
106
+ }
107
+ function checklistFromPlan(plan) {
108
+ if (!Array.isArray(plan)) return;
109
+ const out = [];
110
+ for (const value of plan) {
111
+ if (typeof value !== "object" || value === null) return;
112
+ const raw = value;
113
+ const text = typeof raw.step === "string" ? raw.step.trim() : "";
114
+ if (text === "") return;
115
+ if (raw.status === "pending") out.push({
116
+ text,
117
+ status: "pending"
118
+ });
119
+ else if (raw.status === "inProgress" || raw.status === "in_progress") out.push({
120
+ text,
121
+ status: "in_progress"
122
+ });
123
+ else if (raw.status === "completed") out.push({
124
+ text,
125
+ status: "completed"
126
+ });
127
+ else return;
128
+ }
129
+ return clamp(out);
130
+ }
131
+ function sameChecklist(a, b) {
132
+ const left = a ?? [];
133
+ if (left.length !== b.length) return false;
134
+ return left.every((item, i) => item.text === b[i].text && item.status === b[i].status);
135
+ }
136
+ //#endregion
88
137
  //#region src/lib/input-queue.ts
89
138
  var InputQueue = class {
90
139
  #buffer = [];
@@ -412,6 +461,7 @@ var EventLog = class {
412
461
  #activityCount = 0;
413
462
  #proseCount = 0;
414
463
  #contextUsage;
464
+ #checklist;
415
465
  #resetSeq = 0;
416
466
  #lastActivityAt;
417
467
  get events() {
@@ -429,6 +479,9 @@ var EventLog = class {
429
479
  get contextUsage() {
430
480
  return this.#contextUsage;
431
481
  }
482
+ get checklist() {
483
+ return this.#checklist;
484
+ }
432
485
  get resetSeq() {
433
486
  return this.#resetSeq;
434
487
  }
@@ -455,6 +508,7 @@ var EventLog = class {
455
508
  this.#activityCount = 0;
456
509
  this.#proseCount = 0;
457
510
  this.#contextUsage = void 0;
511
+ this.#checklist = void 0;
458
512
  this.#resetSeq = 0;
459
513
  for (const event of this.#events) this.#fold(event);
460
514
  this.#lastActivityAt = lastActivityAt;
@@ -463,9 +517,11 @@ var EventLog = class {
463
517
  this.#activityCount += transcriptActivity(event);
464
518
  this.#proseCount += transcriptProse(event);
465
519
  this.#contextUsage = contextReading(event) ?? this.#contextUsage;
520
+ if (event.type === "checklist") this.#checklist = event.items.length > 0 ? event.items : void 0;
466
521
  if (event.type === "conversation_reset") {
467
522
  this.#resetSeq = event.seq;
468
523
  this.#contextUsage = void 0;
524
+ this.#checklist = void 0;
469
525
  }
470
526
  }
471
527
  };
@@ -892,6 +948,7 @@ var SessionRunner = class {
892
948
  contextUsage: this.#log.contextUsage,
893
949
  pendingPermissionCount: this.#pending.size,
894
950
  subagents: this.#subagents.list(),
951
+ checklist: this.#log.checklist,
895
952
  meta: this.#config.meta,
896
953
  scope: this.#config.scope,
897
954
  title: sessionTitle(this.#config, this.#engineTitle),
@@ -1367,6 +1424,11 @@ var SessionRunner = class {
1367
1424
  const event = this.#log.append(body);
1368
1425
  this.#subagents.observe(body, event.ts);
1369
1426
  this.#subscribers.emit(event);
1427
+ const items = checklistFromBody(body);
1428
+ if (items && !sameChecklist(this.#log.checklist, items)) this.#emit({
1429
+ type: "checklist",
1430
+ items
1431
+ });
1370
1432
  }
1371
1433
  };
1372
1434
  function recommendedAnswers(input) {
@@ -1481,6 +1543,7 @@ var AiSdkRunner = class {
1481
1543
  activityCount: this.#log.activityCount,
1482
1544
  proseCount: this.#log.proseCount,
1483
1545
  contextUsage: this.#log.contextUsage,
1546
+ checklist: this.#log.checklist,
1484
1547
  pendingPermissionCount: this.#pendingApprovals.size,
1485
1548
  meta: this.#config.meta,
1486
1549
  scope: this.#config.scope,
@@ -3700,7 +3763,8 @@ const GRANULAR_NEVER = { granular: {
3700
3763
  const THREAD_SCOPED_NOTIFICATIONS = /* @__PURE__ */ new Set([
3701
3764
  "turn/started",
3702
3765
  "turn/completed",
3703
- "thread/tokenUsage/updated"
3766
+ "thread/tokenUsage/updated",
3767
+ "turn/plan/updated"
3704
3768
  ]);
3705
3769
  const APPROVAL_POLICY_BY_MODE = {
3706
3770
  default: GRANULAR_ASK,
@@ -4058,7 +4122,8 @@ var CodexRunner = class {
4058
4122
  totalCostUsd: this.#totalCostUsd,
4059
4123
  numTurns: this.#numTurns || void 0,
4060
4124
  lastActivityAt: this.#log.lastActivityAt,
4061
- subagents: this.#agents.list()
4125
+ subagents: this.#agents.list(),
4126
+ checklist: this.#log.checklist
4062
4127
  };
4063
4128
  }
4064
4129
  setTitle(title) {
@@ -4698,20 +4763,11 @@ var CodexRunner = class {
4698
4763
  this.#emitRateLimits(params?.rateLimits);
4699
4764
  },
4700
4765
  "turn/plan/updated": (params) => {
4701
- const active = this.#activeTurn;
4702
- if (!active) return;
4703
- const plan = params?.plan;
4704
- if (!Array.isArray(plan)) return;
4705
- this.#emit({
4706
- type: "sdk_event",
4707
- payload: {
4708
- type: "codex.todo_list",
4709
- id: `${active.nonce}:plan`,
4710
- items: plan.map((step) => ({
4711
- text: step.step,
4712
- completed: step.status === "completed"
4713
- }))
4714
- }
4766
+ if (!this.#activeTurn) return;
4767
+ const items = checklistFromPlan(params?.plan);
4768
+ if (items && !sameChecklist(this.#log.checklist, items)) this.#emit({
4769
+ type: "checklist",
4770
+ items
4715
4771
  });
4716
4772
  },
4717
4773
  "serverRequest/resolved": (params) => {