@themoltnet/pi-extension 0.26.1 → 0.26.3

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/dist/index.d.ts CHANGED
@@ -83,6 +83,8 @@ declare interface ClaimedTask {
83
83
  task: Task;
84
84
  /** Attempt number assigned by the source/queue. */
85
85
  attemptN: number;
86
+ /** Runtime profile id selected by the source when claim routing is profile-scoped. */
87
+ profileId?: string;
86
88
  /** W3C trace headers from the claim response for OTel context propagation. */
87
89
  traceHeaders: Record<string, string>;
88
90
  }
@@ -242,6 +244,13 @@ export declare function executePiTask(claimedTask: ClaimedTask, reporter: TaskRe
242
244
  export declare interface ExecutePiTaskOptions {
243
245
  /** MoltNet agent whose credentials the VM boots with. */
244
246
  agentName: string;
247
+ /**
248
+ * Host root that owns `.moltnet/<agentName>/`.
249
+ *
250
+ * Defaults to `mountPath`, but callers that mount scratch workspaces should
251
+ * pass the stable sandbox root.
252
+ */
253
+ agentRootDir?: string;
245
254
  /** Host cwd that the VM mounts into the guest (defaults to `process.cwd()`). */
246
255
  mountPath?: string;
247
256
  /** LLM selection. */
@@ -905,6 +914,13 @@ export declare interface VmConfig {
905
914
  checkpointPath: string;
906
915
  /** MoltNet agent name (used to resolve credentials). */
907
916
  agentName: string;
917
+ /**
918
+ * Host root that owns `.moltnet/<agentName>/`.
919
+ *
920
+ * Defaults to the main git worktree for backwards compatibility. Daemon
921
+ * callers pass the sandbox root so non-git scratch/shared tasks can boot.
922
+ */
923
+ agentRootDir?: string;
908
924
  /** Host directory to mount into the VM. */
909
925
  mountPath: string;
910
926
  /** Effective workspace shape selected by the caller. */
package/dist/index.js CHANGED
@@ -8716,11 +8716,20 @@ function shouldRunResumeCommand(entry, ctx) {
8716
8716
  * only exists in the main worktree, not in git worktrees).
8717
8717
  */
8718
8718
  function findMainWorktree() {
8719
- const output = execFileSync("git", [
8720
- "worktree",
8721
- "list",
8722
- "--porcelain"
8723
- ], { encoding: "utf8" });
8719
+ let output;
8720
+ try {
8721
+ output = execFileSync("git", [
8722
+ "worktree",
8723
+ "list",
8724
+ "--porcelain"
8725
+ ], {
8726
+ encoding: "utf8",
8727
+ stdio: "pipe"
8728
+ });
8729
+ } catch (err) {
8730
+ const message = err instanceof Error ? err.message : String(err);
8731
+ throw new Error(`Git worktree discovery requires a git repository: ${message}`);
8732
+ }
8724
8733
  for (const block of output.split("\n\n")) {
8725
8734
  const lines = block.split("\n");
8726
8735
  const wt = lines.find((l) => l.startsWith("worktree "));
@@ -8728,6 +8737,10 @@ function findMainWorktree() {
8728
8737
  }
8729
8738
  throw new Error("Could not find main git worktree");
8730
8739
  }
8740
+ function resolveVmAgentDir(config) {
8741
+ const rootDir = config.agentRootDir ?? findMainWorktree();
8742
+ return path.join(rootDir, ".moltnet", config.agentName);
8743
+ }
8731
8744
  function loadCredentials(agentDir) {
8732
8745
  const moltnetJson = readFileSync(path.join(agentDir, "moltnet.json"), "utf8");
8733
8746
  const agentEnvRaw = readFileSync(path.join(agentDir, "env"), "utf8");
@@ -8826,8 +8839,7 @@ function nonErrorMessage(err) {
8826
8839
  */
8827
8840
  async function resumeVm(config) {
8828
8841
  throwIfAborted(config.signal, "VM resume");
8829
- const mainRepo = findMainWorktree();
8830
- const agentDir = path.join(mainRepo, ".moltnet", config.agentName);
8842
+ const agentDir = resolveVmAgentDir(config);
8831
8843
  const guestWorkspace = path.resolve(config.mountPath);
8832
8844
  if (!existsSync(agentDir)) throw new Error(`Agent directory not found: ${agentDir}. Run: moltnet register --name ${config.agentName}`);
8833
8845
  const creds = loadCredentials(agentDir);
@@ -13831,7 +13843,7 @@ _Object_({
13831
13843
  minLength: 1,
13832
13844
  maxLength: 100
13833
13845
  }),
13834
- daemonProfileId: Union([String$1({ format: "uuid" }), Null()]),
13846
+ runtimeProfileId: Union([String$1({ format: "uuid" }), Null()]),
13835
13847
  provider: String$1({
13836
13848
  minLength: 1,
13837
13849
  maxLength: 100
@@ -13862,7 +13874,7 @@ _Object_({
13862
13874
  minLength: 1,
13863
13875
  maxLength: 100
13864
13876
  }),
13865
- daemonProfileId: Optional(String$1({ format: "uuid" })),
13877
+ runtimeProfileId: String$1({ format: "uuid" }),
13866
13878
  provider: String$1({
13867
13879
  minLength: 1,
13868
13880
  maxLength: 100
@@ -13893,6 +13905,7 @@ _Object_({
13893
13905
  minLength: 1,
13894
13906
  maxLength: 100
13895
13907
  }),
13908
+ runtimeProfileId: String$1({ format: "uuid" }),
13896
13909
  provider: String$1({
13897
13910
  minLength: 1,
13898
13911
  maxLength: 100
@@ -23441,7 +23454,7 @@ function prepareTaskWorkspace(task, requestedMountPath, executionPlan) {
23441
23454
  cleanup: () => {}
23442
23455
  };
23443
23456
  if (workspaceMode === "scratch_mount") {
23444
- const scratchDir = resolveTaskScratchPath(findMainWorktree(), executionPlan?.workspaceId ?? `task-${task.id}`);
23457
+ const scratchDir = resolveTaskScratchPath(requestedMountPath, executionPlan?.workspaceId ?? `task-${task.id}`);
23445
23458
  const keepWorkspace = executionPlan?.workspaceScope === "session" && executionPlan.sessionKey !== null;
23446
23459
  if (keepWorkspace) mkdirSync(scratchDir, { recursive: true });
23447
23460
  else {
@@ -23473,7 +23486,7 @@ function prepareTaskWorkspace(task, requestedMountPath, executionPlan) {
23473
23486
  branch: null,
23474
23487
  cleanup: () => {}
23475
23488
  };
23476
- const mainRepo = findMainWorktree();
23489
+ const mainRepo = findMainWorktreeForDedicatedTask();
23477
23490
  const worktreeDir = resolveTaskWorktreePath(mainRepo, executionPlan?.workspaceId ?? `task-${task.id}`);
23478
23491
  const relMount = relative(mainRepo, requestedMountPath);
23479
23492
  const cwdPath = relMount === "" || relMount.startsWith("..") ? worktreeDir : join(worktreeDir, relMount);
@@ -23504,8 +23517,8 @@ function prepareTaskWorkspace(task, requestedMountPath, executionPlan) {
23504
23517
  function resolveTaskWorktreePath(mainRepo, workspaceId) {
23505
23518
  return join(mainRepo, ".worktrees", workspaceId);
23506
23519
  }
23507
- function resolveTaskScratchPath(mainRepo, workspaceId) {
23508
- return join(mainRepo, ".moltnet", "d", "task-workspaces", workspaceId);
23520
+ function resolveTaskScratchPath(stateRoot, workspaceId) {
23521
+ return join(stateRoot, ".moltnet", "d", "task-workspaces", workspaceId);
23509
23522
  }
23510
23523
  function ensureReusableTaskWorktree(mainRepo, worktreeDir, branch, baseRefOverride = null) {
23511
23524
  if (isRegisteredWorktree(mainRepo, worktreeDir)) return;
@@ -23576,6 +23589,14 @@ function gitRefExists(mainRepo, ref) {
23576
23589
  return false;
23577
23590
  }
23578
23591
  }
23592
+ function findMainWorktreeForDedicatedTask() {
23593
+ try {
23594
+ return findMainWorktree();
23595
+ } catch (err) {
23596
+ const message = err instanceof Error ? err.message : String(err);
23597
+ throw new Error(`Dedicated worktree tasks require a git repository: ${message}`);
23598
+ }
23599
+ }
23579
23600
  function copyDirectoryContents(sourceDir, targetDir) {
23580
23601
  if (!existsSync(sourceDir)) throw new Error(`Workspace seed source is missing: ${sourceDir}`);
23581
23602
  if (existsSync(join(sourceDir, ".git"))) initializeScratchGitRepo(sourceDir, targetDir);
@@ -23697,6 +23718,7 @@ async function executePiTask(claimedTask, reporter, opts) {
23697
23718
  const attemptN = claimedTask.attemptN;
23698
23719
  const startTime = Date.now();
23699
23720
  const requestedMountPath = opts.mountPath ?? process.cwd();
23721
+ const agentRootDir = opts.agentRootDir ?? requestedMountPath;
23700
23722
  const executionPlan = await opts.makeExecutionPlan?.(claimedTask) ?? null;
23701
23723
  let workspace = null;
23702
23724
  let mountPath = requestedMountPath;
@@ -23808,6 +23830,7 @@ async function executePiTask(claimedTask, reporter, opts) {
23808
23830
  managed = await resumeVm({
23809
23831
  checkpointPath,
23810
23832
  agentName: opts.agentName,
23833
+ agentRootDir,
23811
23834
  mountPath,
23812
23835
  workspaceMode: workspace.mode,
23813
23836
  extraAllowedHosts: opts.extraAllowedHosts,
@@ -23825,8 +23848,7 @@ async function executePiTask(claimedTask, reporter, opts) {
23825
23848
  }
23826
23849
  const diaryId = task.diaryId ?? "";
23827
23850
  const taskTeamId = task.teamId ?? "";
23828
- const mainRepo = findMainWorktree();
23829
- activateAgentEnv(managed.credentials.agentEnv, mainRepo);
23851
+ activateAgentEnv(managed.credentials.agentEnv, agentRootDir);
23830
23852
  const activeWorkspace = workspace;
23831
23853
  if (!activeWorkspace) throw new Error("task workspace not prepared");
23832
23854
  await emit("info", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@themoltnet/pi-extension",
3
- "version": "0.26.1",
3
+ "version": "0.26.3",
4
4
  "type": "module",
5
5
  "description": "MoltNet pi extension — sandboxed tool execution in Gondolin VMs with MoltNet identity and persistent memory",
6
6
  "keywords": [
@@ -36,7 +36,7 @@
36
36
  "@earendil-works/gondolin": "^0.9.1",
37
37
  "@opentelemetry/api": "^1.9.0",
38
38
  "typebox": "^1.2.8",
39
- "@themoltnet/agent-runtime": "0.27.0",
39
+ "@themoltnet/agent-runtime": "0.28.0",
40
40
  "@themoltnet/sdk": "0.109.0"
41
41
  },
42
42
  "peerDependencies": {