@oisin-ee/pi-prewalk 0.7.1 → 0.8.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
@@ -1,6 +1,7 @@
1
1
  # @oisin-ee/pi-prewalk
2
2
 
3
- Prewalk starts with the active planner model. After the planning nudge, a successful `todo` call opens the handoff gate.
3
+ Prewalk starts with the active planner model. After the planning nudge, validated local task activation opens the handoff gate.
4
+ Without the task-provider capability, a successful `todo` call opens the gate instead. Imported workers need no bookkeeping call.
4
5
  The first subsequent `edit` or `write` result switches the session to the target model, even if that result failed.
5
6
  Nested calls through codemode also count. Without a callable `todo` tool, the gate is open.
6
7
 
@@ -27,7 +28,7 @@ The startup flags are `--prewalk`, `--no-prewalk`, and `--prewalk-into provider/
27
28
  Do not combine `--no-prewalk` with either arming flag.
28
29
  Flags affect only the startup session. New sessions use `enabled` from config. Resumed sessions do not arm automatically.
29
30
 
30
- For a wrangle child, add `"pi_args": ["--prewalk-into", "alias/luna"]` to its profile.
31
+ For a dogsled child, add `"pi_args": ["--prewalk-into", "alias/luna"]` to its profile.
31
32
  To suppress configured prewalk for that child, use `"pi_args": ["--no-prewalk"]`.
32
33
 
33
34
  ## State and context
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oisin-ee/pi-prewalk",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "A one-shot planner-to-executor handoff for pi, with branch-backed Rust rules.",
5
5
  "keywords": [
6
6
  "pi-extension",
package/src/adapter.ts CHANGED
@@ -4,6 +4,7 @@ import type { BoundaryResult, SessionBoundaryDraft } from "@earendil-works/pi-co
4
4
  import type { Context, Files, Host } from "./ports.ts";
5
5
  import { branchRecords, calls } from "./branch.ts";
6
6
  import type { CallEvidence } from "./branch.ts";
7
+ import { activeTask } from "./tasks.ts";
7
8
  import { decide } from "./wasm.ts";
8
9
 
9
10
  /**
@@ -117,6 +118,7 @@ class Adapter {
117
118
  todo.exposure === "deferred" ||
118
119
  this.#pi.getActiveTools().includes("todo"));
119
120
  return {
121
+ active_unit: activeTask(this.#pi.events),
120
122
  available: ctx.modelRegistry
121
123
  .getAvailable()
122
124
  .map((candidate) => `${candidate.provider}/${candidate.id}`),
@@ -55,6 +55,10 @@ export interface Facts {
55
55
  * Is todo callable (directly or through codemode)?
56
56
  */
57
57
  todo: boolean;
58
+ /**
59
+ * Current provider activation; absent preserves the legacy successful-todo rule.
60
+ */
61
+ active_unit?: boolean | undefined;
58
62
  /**
59
63
  * Todo source identity for status.
60
64
  */
Binary file
package/src/ports.ts CHANGED
@@ -12,7 +12,7 @@ type Host = Pick<
12
12
  | "getThinkingLevel"
13
13
  | "setThinkingLevel"
14
14
  | "setModel"
15
- >;
15
+ > & { readonly events: Readonly<ExtensionAPI["events"]> };
16
16
  /** Read-only pi facts. */
17
17
  interface Context {
18
18
  readonly cwd: string;
package/src/tasks.ts ADDED
@@ -0,0 +1,48 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+
3
+ interface ActiveProvider {
4
+ readonly active: () => unknown;
5
+ }
6
+
7
+ /**
8
+ * Validates only the capability method this consumer needs.
9
+ * @param {unknown} value Capability response.
10
+ * @returns {boolean} Whether the active query is callable.
11
+ */
12
+ const isProvider = (value: unknown): value is ActiveProvider =>
13
+ typeof value === "object" &&
14
+ value !== null &&
15
+ "active" in value &&
16
+ typeof value.active === "function",
17
+ /**
18
+ * Queries current activation without loading todo or interpreting its snapshots.
19
+ * @param {Readonly<ExtensionAPI["events"]>} events Extension capability bus.
20
+ * @returns {boolean | undefined} Activation, or unavailable legacy capability.
21
+ */
22
+ activeTask = (events: Readonly<ExtensionAPI["events"]>): boolean | undefined => {
23
+ const replies: unknown[] = [];
24
+ events.emit("oisin.tasks.acquire.v1", {
25
+ reply: (provider: unknown): void => {
26
+ replies.push(provider);
27
+ },
28
+ version: 1,
29
+ });
30
+ const [provider] = replies,
31
+ one = 1;
32
+ if (replies.length !== one || !isProvider(provider)) {
33
+ return undefined;
34
+ }
35
+ const result: unknown = provider.active();
36
+ if (
37
+ typeof result !== "object" ||
38
+ result === null ||
39
+ !("ok" in result) ||
40
+ result.ok !== true ||
41
+ !("value" in result)
42
+ ) {
43
+ return undefined;
44
+ }
45
+ return result.value !== null && result.value !== undefined;
46
+ };
47
+
48
+ export { activeTask };