pi-fovea 0.29.0 → 0.29.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.
package/README.md CHANGED
@@ -258,7 +258,11 @@ is absorbed silently, so broad umbrella coverage does not become broad model
258
258
  context. Set `sync.scope` to `"repository"` to restore root-wide steering.
259
259
 
260
260
  A meaningful current, mixed, or unattributed change inside the attention scope
261
- can still ship post-turn with `deliverAs: "steer"` and `triggerTurn`. A relevant
261
+ can still ship post-turn with `deliverAs: "steer"` and `triggerTurn`. If
262
+ [pi-queue-steer](https://github.com/monotykamary/pi-queue-steer-factory) still
263
+ holds rows (`globalThis.__tmustierPiQueueSteerState.pending > 0`), that same
264
+ notice rides `nextTurn` instead so a queued user row stays first in Pi's native
265
+ lane and Fovea cannot `triggerTurn` ahead of it. A relevant
262
266
  change attributed solely to another Fovea-enabled session is queued for the
263
267
  next user prompt instead; it never restarts an idle agent. The compact update
264
268
  names changed files, route deltas, and newly relevant files. Shell commands,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-fovea",
3
- "version": "0.29.0",
3
+ "version": "0.29.2",
4
4
  "description": "Token-budgeted repo mapping for agent sessions: foveated heat diffusion over a cross-language code graph, with progressive disclosure.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -71,8 +71,8 @@
71
71
  "test:smoke": "vitest run tests/startup.test.ts tests/config.test.ts tests/settings.test.ts tests/substrate.test.ts tests/scan.test.ts tests/extract.test.ts tests/join.test.ts tests/heat.test.ts tests/nuclei.test.ts tests/render.test.ts"
72
72
  },
73
73
  "devDependencies": {
74
- "@earendil-works/pi-coding-agent": "0.85.1",
75
- "@earendil-works/pi-tui": "0.85.1",
74
+ "@earendil-works/pi-coding-agent": "0.86.0",
75
+ "@earendil-works/pi-tui": "0.86.0",
76
76
  "@types/node": "^22.0.0",
77
77
  "esbuild": "^0.28.1",
78
78
  "knip": "^6.32.0",
@@ -49,7 +49,7 @@ See README's “Many projects, one conversation” and `docs/workspace.md`.
49
49
 
50
50
  ## Turn sync
51
51
 
52
- Before an agent starts, pi-fovea establishes its baseline or injects relevant out-of-band semantic drift into that run. After each assistant turn it compares again. The default `sync.scope: "session"` indexes the whole root but steers only for top-level directories/root files this conversation entered through path-bearing tools or focus. Sibling-directory drift advances the index and baseline silently. Current, mixed, and unattributed changes in scope may trigger a continuation; changes owned solely by another Fovea session wait for the next user prompt and cannot restart an idle agent. Comment- and formatting-only edits stay silent. Set `sync.scope: "repository"` only when root-wide steering is intentional.
52
+ Before an agent starts, pi-fovea establishes its baseline or injects relevant out-of-band semantic drift into that run. After each assistant turn it compares again. The default `sync.scope: "session"` indexes the whole root but steers only for top-level directories/root files this conversation entered through path-bearing tools or focus. Sibling-directory drift advances the index and baseline silently. Current, mixed, and unattributed changes in scope may trigger a continuation; parked pi-queue-steer rows (`pending > 0` on its globalThis mirror) and changes owned solely by another Fovea session wait for the next user prompt and cannot restart an idle agent. Comment- and formatting-only edits stay silent. Set `sync.scope: "repository"` only when root-wide steering is intentional.
53
53
 
54
54
  Sync is **mutation-path agnostic**: pi's edit/write tools, a pi-fabric `fabric_exec` program's inner `pi.edit`, a bash heredoc, a subagent, or an editor save outside the session all register identically. Content hashes are the source of truth; tool events establish attention but are not the drift oracle. Successful edit/write events additionally record exact hash transitions so sync can label current-session, other-Fovea-session, and mixed provenance; uninstrumented mutation paths remain explicitly unattributed. In repos with no `.git` directory content drift is also the only change signal — do not fall back to `git status` assumptions.
55
55
 
package/src/index.ts CHANGED
@@ -92,6 +92,21 @@ const text = (s: string) => ({ type: "text" as const, text: s });
92
92
  const syncRuns = (config: FoveaConfig): boolean => config.sync.mode !== "disabled";
93
93
  const syncDisplays = (config: FoveaConfig): boolean => config.sync.mode === "enabled";
94
94
 
95
+ /** pi-queue-steer mirrors `{ pending, paused, blocked }` on globalThis so
96
+ * peers can yield the native steer/follow-up lane without a package
97
+ * dependency or listener-order race (same snapshot pi-ledger reads). */
98
+ const queueSteerPending = (): number => {
99
+ const state = (globalThis as { __tmustierPiQueueSteerState?: { pending?: unknown } }).__tmustierPiQueueSteerState;
100
+ return typeof state?.pending === "number" && Number.isFinite(state.pending) ? Math.max(0, state.pending) : 0;
101
+ };
102
+
103
+ /** Parked queue-steer rows own the next native slot. Do not `triggerTurn` a
104
+ * Fovea steer in front of them — ride `nextTurn` until that backlog drains. */
105
+ const syncDelivery = (nextPrompt: boolean): { deliverAs: "nextTurn" } | { deliverAs: "steer"; triggerTurn: true } =>
106
+ nextPrompt || queueSteerPending() > 0
107
+ ? { deliverAs: "nextTurn" }
108
+ : { deliverAs: "steer", triggerTurn: true };
109
+
95
110
  const NODE_KINDS = new Set<NodeKind>([
96
111
  "function", "method", "class", "interface", "type", "field", "decl", "file", "anchor",
97
112
  ]);
@@ -461,8 +476,7 @@ export default function fovea(pi: ExtensionAPI) {
461
476
  turnFiles = [];
462
477
  for (const notice of await pollRoots(ctx, "cheap", files)) {
463
478
  pi.sendMessage({ customType: "pi-fovea-sync", content: notice.content,
464
- display: notice.display, details: notice.details }, notice.nextPrompt
465
- ? { deliverAs: "nextTurn" } : { deliverAs: "steer", triggerTurn: true });
479
+ display: notice.display, details: notice.details }, syncDelivery(notice.nextPrompt));
466
480
  }
467
481
  });
468
482