@astrosheep/keiyaku 4.5.25 → 4.5.26

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.
@@ -104,6 +104,10 @@ function isPendingTell(row) {
104
104
  function isActiveTool(row) {
105
105
  return row.kind === "tool" && row.state === "active";
106
106
  }
107
+ function isProtectedCurrentTurnActivity(row) {
108
+ return (row.kind === "said" ||
109
+ (row.kind === "tool" && row.call.kind === "fileChange" && row.state !== "active" && row.state !== "unsettled"));
110
+ }
107
111
  function isSettledTellDeliveredTo(row, turnSequence) {
108
112
  return (row.kind === "tell" &&
109
113
  row.state === "told" &&
@@ -146,6 +150,7 @@ export function selectSnapshot(ledger, input) {
146
150
  const opening = openingInput(ledger);
147
151
  const pinSet = new Set([
148
152
  ...window.filter(isActiveTool),
153
+ ...window.filter(isProtectedCurrentTurnActivity),
149
154
  ...pins,
150
155
  ...(opening === undefined ? [] : [opening]),
151
156
  ]);
@@ -281,6 +281,12 @@ function isMutableStreamRow(row) {
281
281
  function settledRows(activity) {
282
282
  return activity.rows.filter(isSettledStreamRow);
283
283
  }
284
+ function isProtectedStreamRow(row) {
285
+ return row.kind === "said" || (row.kind === "tool" && row.call.kind === "fileChange");
286
+ }
287
+ function isBoundedStreamTool(row) {
288
+ return row.kind === "tool" && !isProtectedStreamRow(row);
289
+ }
284
290
  function rememberMutableRows(state, activity) {
285
291
  for (const row of activity.rows)
286
292
  if (isMutableStreamRow(row))
@@ -320,7 +326,7 @@ function coalesceDeferredGaps(state) {
320
326
  }, []);
321
327
  }
322
328
  function omitOldestDeferredTool(state) {
323
- const index = state.deferred.findIndex((entry) => entry.kind === "row" && entry.row.kind === "tool");
329
+ const index = state.deferred.findIndex((entry) => entry.kind === "row" && isBoundedStreamTool(entry.row));
324
330
  if (index === -1)
325
331
  throw new Error("activity tail lost its pending tool");
326
332
  state.deferred[index] = { kind: "gap", count: 1 };
@@ -330,7 +336,7 @@ function omitOldestDeferredTool(state) {
330
336
  function flushSafeActivityPrefix(state, lines, context, layout) {
331
337
  for (;;) {
332
338
  const first = state.deferred[0];
333
- if (first === undefined || (first.kind === "row" && first.row.kind === "tool"))
339
+ if (first === undefined || (first.kind === "row" && isBoundedStreamTool(first.row)))
334
340
  return;
335
341
  if (first.kind === "row") {
336
342
  state.deferred.shift();
@@ -338,7 +344,7 @@ function flushSafeActivityPrefix(state, lines, context, layout) {
338
344
  continue;
339
345
  }
340
346
  const next = state.deferred[1];
341
- if (next === undefined || (next.kind === "row" && next.row.kind === "tool"))
347
+ if (next === undefined || (next.kind === "row" && isBoundedStreamTool(next.row)))
342
348
  return;
343
349
  state.deferred.shift();
344
350
  lines.push(layout.marker(first.count));
@@ -375,18 +381,18 @@ function observeActivitySnapshot(state, activity, context, layout) {
375
381
  state.newestSettledSequence = observedRows.reduce((newest, row) => Math.max(newest, row.sequence), state.newestSettledSequence ?? observedRows[0].sequence);
376
382
  const rows = observedRows.filter((row) => row.kind !== "thought");
377
383
  for (const row of rows) {
378
- if (row.kind === "tool" && state.openingTools < OPENING_TOOL_BUDGET) {
384
+ if (isBoundedStreamTool(row) && state.openingTools < OPENING_TOOL_BUDGET) {
379
385
  state.openingTools += 1;
380
386
  renderStreamRow(state, row, lines, context, layout);
381
387
  continue;
382
388
  }
383
- if (row.kind !== "tool" && state.deferred.length === 0) {
389
+ if (!isBoundedStreamTool(row) && state.deferred.length === 0) {
384
390
  renderStreamRow(state, row, lines, context, layout);
385
391
  continue;
386
392
  }
387
393
  state.deferred.push({ kind: "row", row });
388
- if (row.kind === "tool") {
389
- const pendingTools = state.deferred.filter((entry) => entry.kind === "row" && entry.row.kind === "tool").length;
394
+ if (isBoundedStreamTool(row)) {
395
+ const pendingTools = state.deferred.filter((entry) => entry.kind === "row" && isBoundedStreamTool(entry.row)).length;
390
396
  if (pendingTools > RECENT_TOOL_BUDGET)
391
397
  omitOldestDeferredTool(state);
392
398
  }
@@ -52,15 +52,17 @@ function searchText(call) {
52
52
  ...(call.glob === undefined ? [] : [oneLine(call.glob)]),
53
53
  ].join(" · ");
54
54
  }
55
- function fileChange(call) {
55
+ function fileChange(call, state) {
56
56
  const first = call.changes[0];
57
57
  if (first === undefined)
58
58
  return { label: "edit", text: "files" };
59
59
  const label = call.changes.length === 1 ? (first.op === "add" ? "write" : first.op === "delete" ? "delete" : "edit") : "edit";
60
60
  const subject = call.changes.length === 1 ? oneLine(first.path) : `${call.changes.length} files · ${oneLine(first.path)} ...`;
61
61
  const complete = call.changes.every((change) => change.diffstat !== undefined);
62
- if (!complete)
62
+ if (!complete && (state === "active" || state === "unsettled"))
63
63
  return { label, text: subject };
64
+ if (!complete)
65
+ return { label, text: `${subject} — +? -?` };
64
66
  const totals = call.changes.reduce((sum, change) => ({
65
67
  added: sum.added + change.diffstat.added,
66
68
  removed: sum.removed + change.diffstat.removed,
@@ -85,7 +87,7 @@ export function toolRepr(row) {
85
87
  core = { label: searchLabel(row.call.scope), text: searchText(row.call) };
86
88
  break;
87
89
  case "fileChange":
88
- core = fileChange(row.call);
90
+ core = fileChange(row.call, row.state);
89
91
  break;
90
92
  case "other":
91
93
  core = { label: "use", text: oneLine(row.call.display || row.name) };
@@ -384,7 +384,7 @@ async function publishCall(born, execution) {
384
384
  ...(born.signal === undefined ? {} : { signal: born.signal }),
385
385
  })
386
386
  .then(async (initial) => {
387
- if (!defaultWaitComplete(initial) || (deadline !== undefined && remaining() <= 0))
387
+ if (initial.life !== "asleep" || !defaultWaitComplete(initial) || (deadline !== undefined && remaining() <= 0))
388
388
  return undefined;
389
389
  const signal = schemaSignal();
390
390
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "4.5.25",
3
+ "version": "4.5.26",
4
4
  "workspaces": [
5
5
  "plugins/*"
6
6
  ],
@@ -80,8 +80,8 @@
80
80
  "dependencies": {
81
81
  "@agentclientprotocol/sdk": "^1.3.0",
82
82
  "@anthropic-ai/claude-agent-sdk": "^0.3.226",
83
- "@astrosheep/keiyaku-plugin-square": "0.1.5",
84
- "@astrosheep/square": "^0.3.50",
83
+ "@astrosheep/keiyaku-plugin-square": "0.1.6",
84
+ "@astrosheep/square": "^0.3.57",
85
85
  "@earendil-works/pi-coding-agent": "0.85.1",
86
86
  "@opencode-ai/sdk": "1.18.3",
87
87
  "cross-spawn": "^7.0.6",