pi-continual-harness 0.18.0 → 0.19.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/README.md CHANGED
@@ -505,7 +505,7 @@ implementation on first `propose()`) directly into
505
505
 
506
506
  ## Status
507
507
 
508
- 0.12.x. Requires **pi ≥ 0.99.0**. Implemented:
508
+ 0.18.x. Requires **pi ≥ 1.2.0**. Implemented:
509
509
 
510
510
  - Unified harness-state store with branch-local snapshots (`/tree` rollback).
511
511
  - Online `/refine` + `harness_mutate` / `harness_list` tools.
@@ -535,7 +535,10 @@ implementation on first `propose()`) directly into
535
535
  model instead of the router id, so a router selection does not silently
536
536
  reset the harness. Owned items can be carried across models explicitly with
537
537
  `/harness adopt --from <provider/id> [--all]` (agent-filtered copy; see
538
- [Model binding](#model-binding-per-model-isolation)).
538
+ [Model binding](#model-binding-per-model-isolation)). Since pi 1.2,
539
+ `before_agent_start` also fires for runs started by `pi.sendMessage(...,
540
+ { triggerTurn: true })`, so scheduled and extension-triggered runs get the
541
+ same binding, orphan adoption, and injection as interactive prompts.
539
542
  - **Bounded injection (on by default)**: the supplemental block is
540
543
  importance-ordered and capped per kind + by a total token budget, so a growing
541
544
  harness never balloons the system prompt. Tunable / opt-out via the `injection`
@@ -124,7 +124,11 @@ export async function handleAutoRefineTurnEnd(pi, event, ctx) {
124
124
  // continue — otherwise fall back to the legacy steering send.
125
125
  if (result.steeringMessage) {
126
126
  if (event.context?.canContinue === false) {
127
- pi.sendUserMessage(result.steeringMessage);
127
+ // deliverAs "followUp": queue after the in-flight run instead of
128
+ // throwing — pi 1.2 counts the session as busy from run start, so a
129
+ // bare sendUserMessage can fail here when another extension is
130
+ // starting a run at this turn_end.
131
+ pi.sendUserMessage(result.steeringMessage, { deliverAs: "followUp" });
128
132
  return;
129
133
  }
130
134
  // Hygiene (pi ≥ 0.87 context edits): omit every LIVE prior auto-refine
package/dist/harness.js CHANGED
@@ -519,7 +519,9 @@ async function handleSplit(pi, ctx) {
519
519
  ctx.ui.notify("No active items to split (run /refine first).", "warning");
520
520
  return;
521
521
  }
522
- pi.sendUserMessage(buildSplitPrompt(items, projectSlug(ctx.cwd), ctx.cwd));
522
+ // deliverAs "followUp": queue behind any in-flight run (pi ≥ 1.2 busy window
523
+ // starts at run start; a bare send would throw) rather than steering mid-task.
524
+ pi.sendUserMessage(buildSplitPrompt(items, projectSlug(ctx.cwd), ctx.cwd), { deliverAs: "followUp" });
523
525
  ctx.ui.notify(`Steering agent to classify ${items.length} item(s) global vs project "${projectSlug(ctx.cwd)}".`, "info");
524
526
  }
525
527
  /** Active items grouped by owning model key ("provider/id" → count). The
@@ -640,7 +642,7 @@ async function handleAdopt(pi, ctx, rest) {
640
642
  if (foreign > 0)
641
643
  bits.push(`${foreign} foreign-project skipped`);
642
644
  const suffix = bits.length > 0 ? ` (${bits.join("; ")})` : "";
643
- pi.sendUserMessage(buildAdoptPrompt(items, from, { all: rest.includes("--all") }));
645
+ pi.sendUserMessage(buildAdoptPrompt(items, from, { all: rest.includes("--all") }), { deliverAs: "followUp" });
644
646
  ctx.ui.notify(`Steering agent to ${rest.includes("--all") ? "adopt" : "review for adoption"} ${items.length} item(s) from ${from}${suffix}.`, "info");
645
647
  }
646
648
  /** Compose a steering message that asks the agent to persist the given active
@@ -691,7 +693,7 @@ async function handlePushMem(pi, ctx, rest) {
691
693
  const scope = all ? "item(s)" : `${kind ?? "memory"} item(s)`;
692
694
  const modelNote = modelFilter !== undefined ? ` [model ${modelFilter || "(orphan)"}]` : "";
693
695
  const msg = buildPushMemPrompt(items, scope);
694
- pi.sendUserMessage(msg);
696
+ pi.sendUserMessage(msg, { deliverAs: "followUp" });
695
697
  ctx.ui.notify(`Steering agent to persist ${items.length} ${scope}${modelNote} to pi-mem.`, "info");
696
698
  }
697
699
  async function handleStatus(ctx) {
package/dist/refine.js CHANGED
@@ -170,7 +170,10 @@ export async function runRefine(pi, ctx, options = {}, source = "manual") {
170
170
  // continue — see auto-refine.ts. Returned via RefineResult.
171
171
  }
172
172
  else {
173
- pi.sendUserMessage(result.steeringMessage);
173
+ // deliverAs "steer": injects mid-run when the session is busy, ignored
174
+ // when idle (starts the refine run). Required since pi 1.2 — the busy
175
+ // window now includes run start, and a bare send throws there.
176
+ pi.sendUserMessage(result.steeringMessage, { deliverAs: "steer" });
174
177
  }
175
178
  }
176
179
  ctx.ui.setStatus("harness", undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-continual-harness",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Online self-improvement layer for pi. A unified, in-trajectory harness-state store (prompt notes, memory, skill descriptions, sub-agent specs) with a manual /refine that proposes evidence-backed structured CRUD deltas. Composes with pi-reflect (offline) and pi-mem (storage); owns only the online optimizer layer. Inspired by Continual Harness (arXiv 2605.09998) and ACE (arXiv 2510.04618).",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -36,13 +36,13 @@
36
36
  "node": ">=20.0.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "@earendil-works/pi-coding-agent": ">=0.99.0",
40
- "@earendil-works/pi-ai": ">=0.99.0",
39
+ "@earendil-works/pi-coding-agent": ">=1.2.0",
40
+ "@earendil-works/pi-ai": ">=1.2.0",
41
41
  "typebox": ">=1.0.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@earendil-works/pi-coding-agent": ">=0.99.0",
45
- "@earendil-works/pi-ai": ">=0.99.0",
44
+ "@earendil-works/pi-coding-agent": "^1.3.0",
45
+ "@earendil-works/pi-ai": "^1.3.0",
46
46
  "typebox": ">=1.0.0",
47
47
  "@types/node": "^22.0.0",
48
48
  "typescript": "^5.6.0",