@themoltnet/pi-extension 0.18.1 → 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
@@ -140,7 +140,14 @@ the base snapshot is used (Alpine + git + gh + MoltNet CLI + agent user).
140
140
  "cpus": 2,
141
141
  "memory": "6G"
142
142
  },
143
- "resumeCommands": ["corepack enable"],
143
+ "resumeCommands": [
144
+ {
145
+ "run": "corepack enable",
146
+ "when": {
147
+ "workspaceMode": ["shared_mount", "dedicated_worktree"]
148
+ }
149
+ }
150
+ ],
144
151
  "snapshot": {
145
152
  "allowedHosts": ["unofficial-builds.nodejs.org"],
146
153
  "overlaySize": "8G",
@@ -191,10 +198,34 @@ Important properties:
191
198
  - not part of the snapshot cache key
192
199
  - each command runs in a fresh shell with `set -eu` and `set -o pipefail`
193
200
  - first non-zero exit aborts VM resume
201
+ - object form supports `when.workspaceMode` so bootstrap can key off the
202
+ effective mounted workspace shape instead of task type
194
203
 
195
204
  This split exists so repo-specific bootstrap can live in `sandbox.json` while
196
205
  `pi-extension` stays consumer-agnostic.
197
206
 
207
+ Object form:
208
+
209
+ ```json
210
+ {
211
+ "retries": 2,
212
+ "retryBackoffMs": 5000,
213
+ "run": "cd /workspace && pnpm install --frozen-lockfile",
214
+ "when": {
215
+ "workspaceMode": ["shared_mount", "dedicated_worktree"]
216
+ }
217
+ }
218
+ ```
219
+
220
+ `when.workspaceMode` matches the executor's effective workspace shape:
221
+
222
+ - `shared_mount`: task runs directly against the mounted checkout
223
+ - `dedicated_worktree`: task runs in a disposable git worktree
224
+ - `scratch_mount`: task runs in an empty scratch workspace with no repo checkout
225
+
226
+ Use this when a resume step assumes a repository exists under `/workspace` and
227
+ should be skipped for repo-free scratch runs.
228
+
198
229
  ### `vfs`
199
230
 
200
231
  VFS shadow configuration — hide host paths from the guest mount.
package/dist/index.d.ts CHANGED
@@ -67,6 +67,7 @@ declare interface BuildAgentSessionArgs {
67
67
  */
68
68
  sessionPersistence?: {
69
69
  sessionDir: string;
70
+ forkFromSessionPath?: string | null;
70
71
  };
71
72
  }
72
73
 
@@ -92,13 +93,18 @@ declare interface ClaimedTask {
92
93
  * name under the runtime's skill discovery path. Must be
93
94
  * kebab-case-safe (alphanumeric + dashes/underscores).
94
95
  * - `binding` — how the bytes are delivered to the LLM (see above).
95
- * - `content` — the actual bytes (UTF-8 text). Capped at 32 KiB per
96
+ * - `content` — the actual bytes (UTF-8 text). Capped at 64 KiB per
96
97
  * entry; total per-task context bytes are bounded by the
97
98
  * soft `maxItems` cap and per-binding daemon limits.
99
+ * Raised from 32 KiB in 2026-05 — protocol-heavy operator
100
+ * skills (e.g. `.claude/skills/legreffier/SKILL.md`) ship
101
+ * at ~35 KiB inline, and the original cap was sized for
102
+ * short example skills, not the kind of skill the eval
103
+ * substrate is dogfooded on (#943, #823).
98
104
  */
99
105
  declare const ContextRef: TObject< {
100
106
  slug: TString;
101
- binding: TUnion<[TLiteral<"skill">, TLiteral<"prompt_prefix">, TLiteral<"user_inline">]>;
107
+ binding: TUnion<[TLiteral<"skill">, TLiteral<"context_inline">, TLiteral<"prompt_prefix">, TLiteral<"user_inline">]>;
102
108
  content: TString;
103
109
  }>;
104
110
 
@@ -465,9 +471,16 @@ export declare interface PiOtelOptions {
465
471
 
466
472
  export declare interface PiSessionPersistencePlan {
467
473
  sessionDir: string;
474
+ forkFromSessionPath?: string | null;
468
475
  }
469
476
 
470
477
  export declare interface PiTaskExecutionPlan {
478
+ /**
479
+ * Effective workspace mode for this task instance.
480
+ * `scratch_mount` means mount an empty scratch directory rather than the
481
+ * daemon checkout.
482
+ */
483
+ workspaceMode: 'shared_mount' | 'dedicated_worktree' | 'scratch_mount';
471
484
  /**
472
485
  * Daemon-local reuse key. When set alongside `workspaceScope: 'session'`,
473
486
  * dedicated worktrees may be retained and reopened across related tasks.
@@ -488,6 +501,12 @@ export declare interface PiTaskExecutionPlan {
488
501
  * `attempt` = disposable; `session` = keep stable for the reuse key.
489
502
  */
490
503
  workspaceScope: 'attempt' | 'session';
504
+ /**
505
+ * Optional existing workspace root to attach instead of creating a fresh
506
+ * shared/worktree/scratch workspace. Used for read-only-ish producer
507
+ * inspection by applying VFS shadowing on top of the mounted path.
508
+ */
509
+ workspaceAttachment?: PiWorkspaceAttachmentPlan | null;
491
510
  /**
492
511
  * Optional location for file-backed Pi session history. When omitted,
493
512
  * the executor keeps the conversation in memory for this attempt only.
@@ -497,8 +516,36 @@ export declare interface PiTaskExecutionPlan {
497
516
 
498
517
  export declare type PiTaskExecutionPlanFactory = (claimedTask: ClaimedTask) => PiTaskExecutionPlan | null;
499
518
 
519
+ declare interface PiWorkspaceAttachmentPlan {
520
+ mountPath: string;
521
+ cwdPath: string;
522
+ shadowWrites?: 'deny' | 'tmpfs';
523
+ }
524
+
500
525
  export declare function resolveTaskWorktreePath(mainRepo: string, workspaceId: string): string;
501
526
 
527
+ export declare interface ResumeCommand {
528
+ /** Shell command, same semantics as the string form. */
529
+ run: string;
530
+ /** Optional generic runtime predicate for whether this step should run. */
531
+ when?: ResumeCommandWhen;
532
+ /** Additional attempts on non-zero exit. Default 0. */
533
+ retries?: number;
534
+ /** Linear backoff between attempts in ms. Delay before attempt N+1 is
535
+ * `(N + 1) * retryBackoffMs` (so 2s, 4s, … with the default). */
536
+ retryBackoffMs?: number;
537
+ }
538
+
539
+ /** Structured form of a resume command with optional retry policy. */
540
+ declare interface ResumeCommandWhen {
541
+ /**
542
+ * Effective workspace mode(s) that should run this command.
543
+ * Evaluated by the runtime from the mounted workspace shape rather than
544
+ * from task type semantics.
545
+ */
546
+ workspaceMode?: ('shared_mount' | 'dedicated_worktree' | 'scratch_mount')[];
547
+ }
548
+
502
549
  /**
503
550
  * Resume a VM from a checkpoint, inject credentials, configure egress +
504
551
  * TLS. Returns the managed VM handle.
@@ -524,8 +571,18 @@ export declare interface SandboxConfig {
524
571
  * every resume without triggering a snapshot rebuild. Each command
525
572
  * runs in a fresh shell with `set -eu` and `set -o pipefail`; a
526
573
  * non-zero exit (including from any segment of a pipeline) aborts
527
- * resume with the failing command's stderr/stdout tail. */
528
- resumeCommands?: string[];
574
+ * resume with the failing command's stderr/stdout tail.
575
+ *
576
+ * Each entry is either a raw string (no retries) or an object
577
+ * `{ run, when?, retries?, retryBackoffMs? }`. `when` gates the
578
+ * command on generic runtime properties such as effective
579
+ * `workspaceMode`; this keeps sandbox policy decoupled from task
580
+ * types. `retries` is the number of ADDITIONAL attempts after the
581
+ * first failure (default 0 = no retry). Use for steps that hit the
582
+ * network and may legitimately race DHCP/registry availability on a
583
+ * fresh resume (e.g. `pnpm install`). The wrapped command must be
584
+ * idempotent. */
585
+ resumeCommands?: (string | ResumeCommand)[];
529
586
  /** VFS shadow settings — hide host paths from the guest. */
530
587
  vfs?: {
531
588
  /** Paths (relative to workspace root) to shadow from the host mount. */
@@ -661,7 +718,7 @@ declare type Task = Static<typeof Task>;
661
718
  /** Reusable input fragment for any task type. Soft cap at 5 items. */
662
719
  declare const TaskContext: TArray<TObject< {
663
720
  slug: TString;
664
- binding: TUnion<[TLiteral<"skill">, TLiteral<"prompt_prefix">, TLiteral<"user_inline">]>;
721
+ binding: TUnion<[TLiteral<"skill">, TLiteral<"context_inline">, TLiteral<"prompt_prefix">, TLiteral<"user_inline">]>;
665
722
  content: TString;
666
723
  }>>;
667
724
 
@@ -814,6 +871,8 @@ export declare interface VmConfig {
814
871
  agentName: string;
815
872
  /** Host directory to mount at /workspace in the VM. */
816
873
  mountPath: string;
874
+ /** Effective workspace shape selected by the caller. */
875
+ workspaceMode?: 'shared_mount' | 'dedicated_worktree' | 'scratch_mount';
817
876
  /** Additional hosts to allow in egress policy. */
818
877
  extraAllowedHosts?: string[];
819
878
  /** Full sandbox config (vfs shadows, env overrides). */