@morty-build/cli 0.4.13 → 0.4.15

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.
Files changed (49) hide show
  1. package/dist/{chunk-SPF6MCPU.js → chunk-D5ASHLUO.js} +2 -2
  2. package/dist/{chunk-SPF6MCPU.js.map → chunk-D5ASHLUO.js.map} +1 -1
  3. package/dist/{chunk-LZZG3QZL.js → chunk-QEHEPZW2.js} +234 -116
  4. package/dist/{chunk-LZZG3QZL.js.map → chunk-QEHEPZW2.js.map} +4 -4
  5. package/dist/{cli-4X34ILGE.js → cli-M7EVWTLM.js} +3 -3
  6. package/dist/cli.js +2 -2
  7. package/dist/engine/acp/harness/codex/app-server-client.d.ts +1 -1
  8. package/dist/engine/acp/harness/codex/app-server-client.d.ts.map +1 -1
  9. package/dist/engine/acp/harness/codex/app-server-client.js +2 -3
  10. package/dist/engine/acp/harness/codex/app-server-client.js.map +1 -1
  11. package/dist/engine/runtime/command/registry/session.d.ts.map +1 -1
  12. package/dist/engine/runtime/command/registry/session.js +18 -18
  13. package/dist/engine/runtime/command/registry/session.js.map +1 -1
  14. package/dist/engine/session/manager/session-manager.d.ts +6 -0
  15. package/dist/engine/session/manager/session-manager.d.ts.map +1 -1
  16. package/dist/engine/session/manager/session-manager.js +29 -0
  17. package/dist/engine/session/manager/session-manager.js.map +1 -1
  18. package/dist/engine/session/prompt/apply-session-configuration.d.ts +10 -1
  19. package/dist/engine/session/prompt/apply-session-configuration.d.ts.map +1 -1
  20. package/dist/engine/session/prompt/apply-session-configuration.js +38 -21
  21. package/dist/engine/session/prompt/apply-session-configuration.js.map +1 -1
  22. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  23. package/dist/engine/session/prompt/execute-prompt.js +1 -1
  24. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  25. package/dist/engine/util/process/executable.d.ts +5 -3
  26. package/dist/engine/util/process/executable.d.ts.map +1 -1
  27. package/dist/engine/util/process/executable.js +22 -30
  28. package/dist/engine/util/process/executable.js.map +1 -1
  29. package/dist/engine/util/process/platform/contracts.d.ts +16 -1
  30. package/dist/engine/util/process/platform/contracts.d.ts.map +1 -1
  31. package/dist/engine/util/process/platform/index.d.ts.map +1 -1
  32. package/dist/engine/util/process/platform/index.js +2 -2
  33. package/dist/engine/util/process/platform/index.js.map +1 -1
  34. package/dist/engine/util/process/platform/linux.d.ts.map +1 -1
  35. package/dist/engine/util/process/platform/linux.js +2 -2
  36. package/dist/engine/util/process/platform/linux.js.map +1 -1
  37. package/dist/engine/util/process/platform/macos.d.ts.map +1 -1
  38. package/dist/engine/util/process/platform/macos.js +2 -2
  39. package/dist/engine/util/process/platform/macos.js.map +1 -1
  40. package/dist/engine/util/process/platform/posix.d.ts +2 -2
  41. package/dist/engine/util/process/platform/posix.d.ts.map +1 -1
  42. package/dist/engine/util/process/platform/posix.js +34 -1
  43. package/dist/engine/util/process/platform/posix.js.map +1 -1
  44. package/dist/engine/util/process/platform/windows.d.ts.map +1 -1
  45. package/dist/engine/util/process/platform/windows.js +70 -5
  46. package/dist/engine/util/process/platform/windows.js.map +1 -1
  47. package/dist/engine.js +2 -2
  48. package/package.json +1 -1
  49. /package/dist/{cli-4X34ILGE.js.map → cli-M7EVWTLM.js.map} +0 -0
@@ -80,7 +80,7 @@ var __callDispose = (stack, error, hasError) => {
80
80
  // package.json
81
81
  var package_default = {
82
82
  name: "@morty-build/cli",
83
- version: "0.4.13",
83
+ version: "0.4.15",
84
84
  description: "Morty CLI for installing, pairing, and operating the Morty background service.",
85
85
  type: "module",
86
86
  bin: {
@@ -176,4 +176,4 @@ export {
176
176
  __callDispose,
177
177
  package_default
178
178
  };
179
- //# sourceMappingURL=chunk-SPF6MCPU.js.map
179
+ //# sourceMappingURL=chunk-D5ASHLUO.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../package.json"],
4
- "sourcesContent": ["{\n \"name\": \"@morty-build/cli\",\n \"version\": \"0.4.13\",\n \"description\": \"Morty CLI for installing, pairing, and operating the Morty background service.\",\n \"type\": \"module\",\n \"bin\": {\n \"morty\": \"dist/cli.js\"\n },\n \"exports\": {\n \"./engine\": {\n \"morty-source\": \"./src/exports/engine.ts\",\n \"types\": \"./dist/exports/engine.d.ts\",\n \"default\": \"./dist/engine.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"LICENSE\",\n \"NOTICE\",\n \"THIRD-PARTY-NOTICES.txt\"\n ],\n \"engines\": {\n \"node\": \"^22.19.0 || ^24.20.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"exports\": {\n \"./engine\": {\n \"types\": \"./dist/exports/engine.d.ts\",\n \"import\": \"./dist/engine.js\",\n \"default\": \"./dist/engine.js\"\n }\n }\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/moxt-ai/mobius-morty.git\",\n \"directory\": \"packages/cli\"\n },\n \"scripts\": {\n \"prebuild\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"build\": \"node scripts/build.ts && tsc --project tsconfig.build.json\",\n \"dev\": \"node --watch src/cli/entrypoint.ts\",\n \"pretypecheck\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"prepack\": \"pnpm build\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --project tsconfig.json && tsc --project tests/tsconfig.json\",\n \"pretest:controlled\": \"pnpm build && pnpm pack:test\",\n \"test:controlled\": \"vitest run tests/sessions tests/runtime\",\n \"pretest:manual\": \"pnpm pretest:controlled\",\n \"test:manual\": \"vitest run tests/manual\",\n \"pretest:agents\": \"pnpm build && pnpm pack:test\",\n \"test:agents\": \"vitest run tests/agents --maxWorkers=2\",\n \"pretest:pressure\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"test:pressure\": \"node tests/pressure/concurrent-sessions.mjs\",\n \"pack:test\": \"node scripts/pack-test-release.ts\"\n },\n \"dependencies\": {\n \"undici\": \"8.12.2\"\n },\n \"devDependencies\": {\n \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.3.257\",\n \"@anthropic-ai/sdk\": \"0.122.0\",\n \"@morty-build/client\": \"workspace:*\",\n \"@morty-build/platform-test-support\": \"workspace:*\",\n \"@types/node\": \"^24.13.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@types/ws\": \"^8.18.1\",\n \"commander\": \"15.0.0\",\n \"drizzle-kit\": \"1.0.0-rc.4\",\n \"drizzle-orm\": \"1.0.0-rc.4\",\n \"esbuild\": \"0.28.2\",\n \"semver\": \"^7.8.5\",\n \"valibot\": \"1.5.0\",\n \"ws\": \"^8.21.3\",\n \"zod\": \"^4.6.7\",\n \"@morty-build/local-state\": \"workspace:*\",\n \"miniflare\": \"catalog:\"\n },\n \"keywords\": [],\n \"author\": \"Moxt\",\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/moxt-ai/mobius-morty/issues\"\n },\n \"homepage\": \"https://morty.build\",\n \"private\": false\n}\n"],
4
+ "sourcesContent": ["{\n \"name\": \"@morty-build/cli\",\n \"version\": \"0.4.15\",\n \"description\": \"Morty CLI for installing, pairing, and operating the Morty background service.\",\n \"type\": \"module\",\n \"bin\": {\n \"morty\": \"dist/cli.js\"\n },\n \"exports\": {\n \"./engine\": {\n \"morty-source\": \"./src/exports/engine.ts\",\n \"types\": \"./dist/exports/engine.d.ts\",\n \"default\": \"./dist/engine.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"LICENSE\",\n \"NOTICE\",\n \"THIRD-PARTY-NOTICES.txt\"\n ],\n \"engines\": {\n \"node\": \"^22.19.0 || ^24.20.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"exports\": {\n \"./engine\": {\n \"types\": \"./dist/exports/engine.d.ts\",\n \"import\": \"./dist/engine.js\",\n \"default\": \"./dist/engine.js\"\n }\n }\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/moxt-ai/mobius-morty.git\",\n \"directory\": \"packages/cli\"\n },\n \"scripts\": {\n \"prebuild\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"build\": \"node scripts/build.ts && tsc --project tsconfig.build.json\",\n \"dev\": \"node --watch src/cli/entrypoint.ts\",\n \"pretypecheck\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"prepack\": \"pnpm build\",\n \"start\": \"node dist/cli.js\",\n \"typecheck\": \"tsc --project tsconfig.json && tsc --project tests/tsconfig.json\",\n \"pretest:controlled\": \"pnpm build && pnpm pack:test\",\n \"test:controlled\": \"vitest run tests/sessions tests/runtime\",\n \"pretest:manual\": \"pnpm pretest:controlled\",\n \"test:manual\": \"vitest run tests/manual\",\n \"pretest:agents\": \"pnpm build && pnpm pack:test\",\n \"test:agents\": \"vitest run tests/agents --maxWorkers=2\",\n \"pretest:pressure\": \"tsc --project src/engine/acp/harness/claude/upstream/tsconfig.json && tsc --project src/engine/acp/harness/pi/upstream/tsconfig.json\",\n \"test:pressure\": \"node tests/pressure/concurrent-sessions.mjs\",\n \"pack:test\": \"node scripts/pack-test-release.ts\"\n },\n \"dependencies\": {\n \"undici\": \"8.12.2\"\n },\n \"devDependencies\": {\n \"@agentclientprotocol/sdk\": \"^1.4.0\",\n \"@anthropic-ai/claude-agent-sdk\": \"0.3.257\",\n \"@anthropic-ai/sdk\": \"0.122.0\",\n \"@morty-build/client\": \"workspace:*\",\n \"@morty-build/platform-test-support\": \"workspace:*\",\n \"@types/node\": \"^24.13.5\",\n \"@types/semver\": \"^7.8.0\",\n \"@types/ws\": \"^8.18.1\",\n \"commander\": \"15.0.0\",\n \"drizzle-kit\": \"1.0.0-rc.4\",\n \"drizzle-orm\": \"1.0.0-rc.4\",\n \"esbuild\": \"0.28.2\",\n \"semver\": \"^7.8.5\",\n \"valibot\": \"1.5.0\",\n \"ws\": \"^8.21.3\",\n \"zod\": \"^4.6.7\",\n \"@morty-build/local-state\": \"workspace:*\",\n \"miniflare\": \"catalog:\"\n },\n \"keywords\": [],\n \"author\": \"Moxt\",\n \"license\": \"Apache-2.0\",\n \"bugs\": {\n \"url\": \"https://github.com/moxt-ai/mobius-morty/issues\"\n },\n \"homepage\": \"https://morty.build\",\n \"private\": false\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACI,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,KAAO;AAAA,IACH,OAAS;AAAA,EACb;AAAA,EACA,SAAW;AAAA,IACP,YAAY;AAAA,MACR,gBAAgB;AAAA,MAChB,OAAS;AAAA,MACT,SAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,OAAS;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,SAAW;AAAA,IACP,MAAQ;AAAA,EACZ;AAAA,EACA,eAAiB;AAAA,IACb,QAAU;AAAA,IACV,SAAW;AAAA,MACP,YAAY;AAAA,QACR,OAAS;AAAA,QACT,QAAU;AAAA,QACV,SAAW;AAAA,MACf;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,YAAc;AAAA,IACV,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,WAAa;AAAA,EACjB;AAAA,EACA,SAAW;AAAA,IACP,UAAY;AAAA,IACZ,OAAS;AAAA,IACT,KAAO;AAAA,IACP,cAAgB;AAAA,IAChB,SAAW;AAAA,IACX,OAAS;AAAA,IACT,WAAa;AAAA,IACb,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACjB;AAAA,EACA,cAAgB;AAAA,IACZ,QAAU;AAAA,EACd;AAAA,EACA,iBAAmB;AAAA,IACf,4BAA4B;AAAA,IAC5B,kCAAkC;AAAA,IAClC,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,sCAAsC;AAAA,IACtC,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,WAAa;AAAA,IACb,eAAe;AAAA,IACf,eAAe;AAAA,IACf,SAAW;AAAA,IACX,QAAU;AAAA,IACV,SAAW;AAAA,IACX,IAAM;AAAA,IACN,KAAO;AAAA,IACP,4BAA4B;AAAA,IAC5B,WAAa;AAAA,EACjB;AAAA,EACA,UAAY,CAAC;AAAA,EACb,QAAU;AAAA,EACV,SAAW;AAAA,EACX,MAAQ;AAAA,IACJ,KAAO;AAAA,EACX;AAAA,EACA,UAAY;AAAA,EACZ,SAAW;AACf;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@ import {
3
3
  __export,
4
4
  __using,
5
5
  package_default
6
- } from "./chunk-SPF6MCPU.js";
6
+ } from "./chunk-D5ASHLUO.js";
7
7
 
8
8
  // src/engine/runtime/relay/runtime-revocation.ts
9
9
  var runtimeRevocationCloseCode = 1008;
@@ -21188,12 +21188,11 @@ var sessionCloseCommandSchema = external_exports.object({
21188
21188
  }).readonly();
21189
21189
  var sessionPrepareCommandSchema = external_exports.object({
21190
21190
  ...sessionIdentityFields,
21191
- configuration: external_exports.object({
21192
- booleanValue: external_exports.boolean(),
21193
- configId: external_exports.string().min(1).max(128),
21194
- value: external_exports.string().max(500),
21195
- valueType: external_exports.enum(["boolean", "select"])
21196
- }).readonly().optional(),
21191
+ /**
21192
+ * The complete settings a new Session starts with. The Runtime applies them in dependency order as part of
21193
+ * creating the Session: it answers only once every selection holds, and otherwise creates nothing.
21194
+ */
21195
+ configurations: sessionConfigurationSelectionsSchema.optional(),
21197
21196
  kind: external_exports.literal(SESSION_PREPARE_KIND),
21198
21197
  requestId: identifierStringSchema,
21199
21198
  sessionState: external_exports.literal("provisioned").optional(),
@@ -21207,6 +21206,13 @@ var sessionPrepareCommandSchema = external_exports.object({
21207
21206
  path: ["sessionState"]
21208
21207
  });
21209
21208
  }
21209
+ if (command2.configurations !== void 0 && (command2.transient === true || command2.sessionState !== void 0)) {
21210
+ context.addIssue({
21211
+ code: "custom",
21212
+ message: "Only a Session being created states its initial settings",
21213
+ path: ["configurations"]
21214
+ });
21215
+ }
21210
21216
  }).readonly();
21211
21217
  var runtimeTimingsSchema = external_exports.array(
21212
21218
  external_exports.object({
@@ -71284,6 +71290,33 @@ function readProcessTableWithPs(executable) {
71284
71290
  );
71285
71291
  });
71286
71292
  }
71293
+ function selectPosixProcessTree(entries, rootProcessId) {
71294
+ const processIds = /* @__PURE__ */ new Set([rootProcessId]);
71295
+ for (const entry of entries) {
71296
+ if (entry.processGroupId === rootProcessId) {
71297
+ processIds.add(entry.processId);
71298
+ }
71299
+ }
71300
+ let previousSize = 0;
71301
+ while (previousSize !== processIds.size) {
71302
+ previousSize = processIds.size;
71303
+ for (const entry of entries) {
71304
+ if (processIds.has(entry.parentProcessId)) {
71305
+ processIds.add(entry.processId);
71306
+ }
71307
+ }
71308
+ }
71309
+ return entries.filter((entry) => processIds.has(entry.processId)).map((entry) => ({
71310
+ processGroupId: entry.processGroupId,
71311
+ processId: entry.processId
71312
+ }));
71313
+ }
71314
+ function posixProcessTreeCapture(readSynchronously, read) {
71315
+ return async (root) => {
71316
+ const entries = readSynchronously();
71317
+ return selectPosixProcessTree(entries.length > 0 ? entries : await read(), root.processId);
71318
+ };
71319
+ }
71287
71320
  function processExists(processId) {
71288
71321
  try {
71289
71322
  process.kill(processId, 0);
@@ -71445,7 +71478,7 @@ function processExists2(processId) {
71445
71478
  var linuxProcessPlatform = {
71446
71479
  ...posixOperations2,
71447
71480
  readProcessTable: readLinuxProcessTableWithFallback,
71448
- readProcessTableSynchronously: readLinuxProcessTableSynchronously,
71481
+ captureProcessTree: posixProcessTreeCapture(readLinuxProcessTableSynchronously, readLinuxProcessTableWithFallback),
71449
71482
  processExists: processExists2
71450
71483
  };
71451
71484
 
@@ -71453,7 +71486,10 @@ var linuxProcessPlatform = {
71453
71486
  var macosProcessPlatform = {
71454
71487
  ...posixOperations2,
71455
71488
  readProcessTable: () => readProcessTableWithPs("/bin/ps"),
71456
- readProcessTableSynchronously: () => [],
71489
+ captureProcessTree: posixProcessTreeCapture(
71490
+ () => [],
71491
+ () => readProcessTableWithPs("/bin/ps")
71492
+ ),
71457
71493
  processExists
71458
71494
  };
71459
71495
 
@@ -71532,7 +71568,24 @@ function executableLaunch(command2, args) {
71532
71568
  }
71533
71569
  return { command: command2, arguments: args };
71534
71570
  }
71535
- function readProcessTable() {
71571
+ function parseWindowsProcesses(output2) {
71572
+ const processes = [];
71573
+ for (const line of output2.split("\n")) {
71574
+ const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<created>\d+)\s*$/.exec(line)?.groups;
71575
+ if (groups === void 0) {
71576
+ continue;
71577
+ }
71578
+ const processId = Number(groups["pid"]);
71579
+ const parentProcessId = Number(groups["ppid"]);
71580
+ const createdAt = Number(groups["created"]);
71581
+ if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(createdAt)) {
71582
+ continue;
71583
+ }
71584
+ processes.push({ processId, parentProcessId, createdAt });
71585
+ }
71586
+ return processes;
71587
+ }
71588
+ function readWindowsProcesses() {
71536
71589
  const systemRoot = environmentValue2(process.env, "SystemRoot");
71537
71590
  if (systemRoot === void 0) {
71538
71591
  return Promise.resolve([]);
@@ -71545,7 +71598,8 @@ function readProcessTable() {
71545
71598
  "-NoProfile",
71546
71599
  "-NonInteractive",
71547
71600
  "-Command",
71548
- "Get-CimInstance Win32_Process | ForEach-Object { '{0} {1} {0}' -f $_.ProcessId, $_.ParentProcessId }"
71601
+ // Processes without a creation time, such as the System process, are never part of a spawned tree.
71602
+ "Get-CimInstance Win32_Process | Where-Object { $_.CreationDate } | ForEach-Object { '{0} {1} {2}' -f $_.ProcessId, $_.ParentProcessId, ([DateTimeOffset]$_.CreationDate.ToUniversalTime()).ToUnixTimeMilliseconds() }"
71549
71603
  ],
71550
71604
  {
71551
71605
  encoding: "utf8",
@@ -71554,10 +71608,44 @@ function readProcessTable() {
71554
71608
  signal: AbortSignal.timeout(1e4),
71555
71609
  maxBuffer: 1024 * 1024
71556
71610
  },
71557
- (error62, stdout) => resolveTable(error62 === null ? parseProcessTable(stdout) : [])
71611
+ (error62, stdout) => resolveTable(error62 === null ? parseWindowsProcesses(stdout) : [])
71558
71612
  );
71559
71613
  });
71560
71614
  }
71615
+ async function readProcessTable() {
71616
+ return (await readWindowsProcesses()).map(({ processId, parentProcessId }) => ({
71617
+ processId,
71618
+ parentProcessId,
71619
+ processGroupId: processId
71620
+ }));
71621
+ }
71622
+ function selectWindowsProcessTree(processes, root) {
71623
+ const running = new Map(processes.map((entry) => [entry.processId, entry]));
71624
+ const members2 = /* @__PURE__ */ new Set();
71625
+ if (root.state === "running" && running.has(root.processId)) {
71626
+ members2.add(root.processId);
71627
+ }
71628
+ const belongsToTree = (entry) => {
71629
+ const parent = running.get(entry.parentProcessId);
71630
+ if (parent !== void 0 && parent.createdAt <= entry.createdAt) {
71631
+ return members2.has(parent.processId);
71632
+ }
71633
+ return root.state === "exited" && entry.parentProcessId === root.processId && root.spawnedAt <= entry.createdAt && entry.createdAt <= root.exitedAt;
71634
+ };
71635
+ let previousSize = -1;
71636
+ while (previousSize !== members2.size) {
71637
+ previousSize = members2.size;
71638
+ for (const entry of processes) {
71639
+ if (!members2.has(entry.processId) && belongsToTree(entry)) {
71640
+ members2.add(entry.processId);
71641
+ }
71642
+ }
71643
+ }
71644
+ return [...members2].map((processId) => ({ processGroupId: processId, processId }));
71645
+ }
71646
+ async function captureProcessTree(root) {
71647
+ return selectWindowsProcessTree(await readWindowsProcesses(), root);
71648
+ }
71561
71649
  function signalCapturedProcesses2(processes, _rootProcessId, signal) {
71562
71650
  for (const identity2 of [...processes].reverse()) {
71563
71651
  try {
@@ -71582,7 +71670,7 @@ var windowsProcessPlatform = {
71582
71670
  signalCapturedProcesses: signalCapturedProcesses2,
71583
71671
  terminateProcess: terminateProcess2,
71584
71672
  readProcessTable,
71585
- readProcessTableSynchronously: () => [],
71673
+ captureProcessTree,
71586
71674
  processExists
71587
71675
  };
71588
71676
 
@@ -71590,7 +71678,10 @@ var windowsProcessPlatform = {
71590
71678
  var fallbackPlatform2 = {
71591
71679
  ...posixOperations2,
71592
71680
  readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
71593
- readProcessTableSynchronously: () => [],
71681
+ captureProcessTree: posixProcessTreeCapture(
71682
+ () => [],
71683
+ () => readProcessTableWithPs("/usr/bin/ps")
71684
+ ),
71594
71685
  processExists
71595
71686
  };
71596
71687
  var platforms2 = /* @__PURE__ */ new Map([
@@ -71696,29 +71787,25 @@ function appendBounded(chunks, chunk, currentBytes, limitBytes) {
71696
71787
  chunks.push(chunk);
71697
71788
  return nextBytes;
71698
71789
  }
71699
- function readProcessTable2() {
71700
- return hostPlatform.readProcessTable();
71701
- }
71702
- function selectProcessTree(entries, rootProcessId) {
71703
- const processIds = /* @__PURE__ */ new Set([rootProcessId]);
71704
- for (const entry of entries) {
71705
- if (entry.processGroupId === rootProcessId) {
71706
- processIds.add(entry.processId);
71707
- }
71790
+ var lifetimes = /* @__PURE__ */ new WeakMap();
71791
+ function spawnProcess(command2, args, options) {
71792
+ const spawnedAt = Date.now();
71793
+ const child = spawn3(command2, [...args], options);
71794
+ const processId = child.pid;
71795
+ if (processId !== void 0) {
71796
+ lifetimes.set(child, { state: "running", processId, spawnedAt });
71797
+ child.once("exit", () => {
71798
+ lifetimes.set(child, { state: "exited", processId, spawnedAt, exitedAt: Date.now() });
71799
+ });
71708
71800
  }
71709
- let previousSize = 0;
71710
- while (previousSize !== processIds.size) {
71711
- previousSize = processIds.size;
71712
- for (const entry of entries) {
71713
- if (processIds.has(entry.parentProcessId)) {
71714
- processIds.add(entry.processId);
71715
- }
71716
- }
71801
+ return child;
71802
+ }
71803
+ function spawnedProcess(child) {
71804
+ const lifetime = lifetimes.get(child);
71805
+ if (lifetime === void 0) {
71806
+ throw new Error("Only a child started by spawnProcess has an identifiable process tree");
71717
71807
  }
71718
- return entries.filter((entry) => processIds.has(entry.processId)).map((entry) => ({
71719
- processGroupId: entry.processGroupId,
71720
- processId: entry.processId
71721
- }));
71808
+ return lifetime;
71722
71809
  }
71723
71810
  function mergeProcessTrees(captured, current) {
71724
71811
  const processes = /* @__PURE__ */ new Map();
@@ -71730,15 +71817,11 @@ function mergeProcessTrees(captured, current) {
71730
71817
  }
71731
71818
  return [...processes.values()];
71732
71819
  }
71733
- async function captureProcessTree(child) {
71820
+ async function captureProcessTree2(child) {
71734
71821
  if (child.pid === void 0) {
71735
71822
  return [];
71736
71823
  }
71737
- const entries = hostPlatform.readProcessTableSynchronously();
71738
- if (entries.length > 0) {
71739
- return selectProcessTree(entries, child.pid);
71740
- }
71741
- return selectProcessTree(await readProcessTable2(), child.pid);
71824
+ return await hostPlatform.captureProcessTree(spawnedProcess(child));
71742
71825
  }
71743
71826
  async function waitForCapturedProcessesExit(processes, rootProcessId) {
71744
71827
  const processIds = processes.map((identity2) => identity2.processId).filter((processId) => processId !== rootProcessId);
@@ -71746,7 +71829,7 @@ async function waitForCapturedProcessesExit(processes, rootProcessId) {
71746
71829
  if (processIds.every((processId) => !hostPlatform.processExists(processId))) {
71747
71830
  return true;
71748
71831
  }
71749
- await readProcessTable2();
71832
+ await hostPlatform.readProcessTable();
71750
71833
  }
71751
71834
  return processIds.every((processId) => !hostPlatform.processExists(processId));
71752
71835
  }
@@ -71756,7 +71839,7 @@ async function stopProcessTree(child, capturedProcesses = []) {
71756
71839
  return;
71757
71840
  }
71758
71841
  const childExited = child.exitCode !== null || child.signalCode !== null;
71759
- const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child));
71842
+ const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree2(child));
71760
71843
  if (childExited && processes.length === 0) {
71761
71844
  return;
71762
71845
  }
@@ -71806,7 +71889,7 @@ async function runBoundedProcess(options) {
71806
71889
  options.signal.throwIfAborted();
71807
71890
  const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
71808
71891
  const launch = executableLaunch2(options.command, options.arguments);
71809
- const child = spawn3(launch.command, [...launch.arguments], {
71892
+ const child = spawnProcess(launch.command, launch.arguments, {
71810
71893
  cwd: options.cwd,
71811
71894
  ...hostPlatform.spawnOptions,
71812
71895
  env: { ...options.environment },
@@ -71996,9 +72079,6 @@ var ClaudeCodeAgentSpecification = class extends InProcessAcpAgentSpecification
71996
72079
  };
71997
72080
  };
71998
72081
 
71999
- // src/engine/acp/harness/codex/app-server-client.ts
72000
- import { spawn as spawn4 } from "node:child_process";
72001
-
72002
72082
  // src/engine/acp/harness/codex/app-server-protocol.ts
72003
72083
  import { isAbsolute as isAbsolute8 } from "node:path";
72004
72084
  var boundedText = (maximum) => external_exports.string().max(maximum);
@@ -72331,7 +72411,7 @@ var CodexAppServerClient = class {
72331
72411
  constructor(options) {
72332
72412
  this.#handlers = options.handlers;
72333
72413
  const launch = executableLaunch2(options.command, ["app-server"]);
72334
- this.#child = spawn4(launch.command, [...launch.arguments], {
72414
+ this.#child = spawnProcess(launch.command, launch.arguments, {
72335
72415
  cwd: options.cwd,
72336
72416
  ...platformSpawnOptions,
72337
72417
  env: { ...process.env, ...options.environment },
@@ -72730,12 +72810,12 @@ function presentToolItem(item) {
72730
72810
  };
72731
72811
  }
72732
72812
  if (item.type === "collabAgentToolCall") {
72733
- const spawn6 = item.tool === "spawnAgent";
72813
+ const spawn5 = item.tool === "spawnAgent";
72734
72814
  return {
72735
72815
  content: [],
72736
72816
  kind: "other",
72737
72817
  locations: [],
72738
- rawInput: spawn6 ? {
72818
+ rawInput: spawn5 ? {
72739
72819
  model: item.model,
72740
72820
  prompt: item.prompt,
72741
72821
  reasoningEffort: item.reasoningEffort,
@@ -72743,10 +72823,10 @@ function presentToolItem(item) {
72743
72823
  } : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
72744
72824
  rawOutput: {
72745
72825
  agentsStates: item.agentsStates,
72746
- ...spawn6 ? { receiverThreadIds: item.receiverThreadIds } : {}
72826
+ ...spawn5 ? { receiverThreadIds: item.receiverThreadIds } : {}
72747
72827
  },
72748
72828
  status: collaborationStatus(item.status),
72749
- title: spawn6 ? "Dispatch subagent" : "Wait for subagent"
72829
+ title: spawn5 ? "Dispatch subagent" : "Wait for subagent"
72750
72830
  };
72751
72831
  }
72752
72832
  if (item.type === "subAgentActivity" && item.kind === "started") {
@@ -74929,7 +75009,7 @@ var CodexAcpAgent = class {
74929
75009
  this.#appServer.detach();
74930
75010
  const child = this.#appServer.child();
74931
75011
  try {
74932
- const captured = await captureProcessTree(child);
75012
+ const captured = await captureProcessTree2(child);
74933
75013
  await stopProcessTree(child, captured);
74934
75014
  } finally {
74935
75015
  this.#connection?.close();
@@ -75070,7 +75150,7 @@ import { existsSync as existsSync8, readdirSync as readdirSync6, readFileSync as
75070
75150
  import { basename as basename5, dirname as dirname9, isAbsolute as isAbsolute12, join as join21 } from "node:path";
75071
75151
 
75072
75152
  // src/engine/acp/harness/pi/upstream/dist/pi-rpc/process.js
75073
- import { spawn as spawn5 } from "node:child_process";
75153
+ import { spawn as spawn4 } from "node:child_process";
75074
75154
  import * as readline from "node:readline";
75075
75155
 
75076
75156
  // src/engine/acp/harness/pi/upstream/dist/pi-rpc/command.js
@@ -75187,7 +75267,7 @@ var PiRpcProcess = class _PiRpcProcess {
75187
75267
  args.push("--fork", params.origin.sessionPath);
75188
75268
  break;
75189
75269
  }
75190
- const child = spawn5(cmd, args, {
75270
+ const child = spawn4(cmd, args, {
75191
75271
  cwd: params.cwd,
75192
75272
  stdio: "pipe",
75193
75273
  env: params.environment,
@@ -91460,6 +91540,33 @@ var SessionManager2 = class {
91460
91540
  );
91461
91541
  }
91462
91542
  prepareSession = async (options, metrics = unmeasuredOperationMetrics, closed = "reopen") => await this.#prepareSession(options, { kind: "interactive-only" }, closed, metrics);
91543
+ /**
91544
+ * Creates a Session with the initial settings `configure` applies, and answers with the configured snapshot. A
91545
+ * Session this call created that cannot take its settings is discarded, so a refused creation leaves nothing
91546
+ * behind. A Session that already existed, such as one whose creation answer was lost, is configured again and kept.
91547
+ */
91548
+ createSession = async (options, configure, metrics = unmeasuredOperationMetrics, closed = "reopen") => {
91549
+ const created = !this.#isKnownSession(options.sessionId);
91550
+ try {
91551
+ await configure(await this.prepareSession(options, metrics, closed));
91552
+ return await this.prepareSession(options, metrics, closed);
91553
+ } catch (error62) {
91554
+ if (created) {
91555
+ await this.#discardCreatedSession(options.sessionId);
91556
+ }
91557
+ throw error62;
91558
+ }
91559
+ };
91560
+ async #discardCreatedSession(sessionId) {
91561
+ const runtime = this.#executionProcesses.get(sessionId);
91562
+ try {
91563
+ if (runtime !== void 0) {
91564
+ await this.#retireSessionProcess(sessionId, runtime, async () => await runtime.close());
91565
+ }
91566
+ } finally {
91567
+ this.#store.remove(sessionId);
91568
+ }
91569
+ }
91463
91570
  restoreSession = async (options, metrics = unmeasuredOperationMetrics, closed = "reopen") => await this.#prepareSession(options, { kind: "history-required" }, closed, metrics);
91464
91571
  /**
91465
91572
  * Opens a short-lived native ACP session only to read the local Agent's
@@ -95882,16 +95989,19 @@ function sessionConfigurationMatches(option, selection) {
95882
95989
  validateSessionConfigurationSelection(option, selection);
95883
95990
  return option.type === "boolean" ? option.booleanValue === selection.booleanValue : option.currentValue === selection.value;
95884
95991
  }
95885
- function assertAppliedSessionConfiguration(options, selections) {
95886
- const selectionsById = new Map(selections.map((selection) => [selection.configId, selection]));
95887
- for (const option of options) {
95888
- const selection = selectionsById.get(option.id);
95889
- if (selection === void 0 || !sessionConfigurationSelectionIsAvailable(option, selection)) {
95992
+ function sessionConfigurationConflict(message) {
95993
+ return new AcpExecutionError(message, {}, "session_configuration_conflict");
95994
+ }
95995
+ function assertAppliedSessionConfiguration(options, selections, unavailable) {
95996
+ for (const selection of selections) {
95997
+ const option = options.find((candidate) => candidate.id === selection.configId);
95998
+ const holds = option !== void 0 && sessionConfigurationSelectionIsAvailable(option, selection) ? sessionConfigurationMatches(option, selection) : unavailable === "ignore";
95999
+ if (holds) {
95890
96000
  continue;
95891
96001
  }
95892
- if (!sessionConfigurationMatches(option, selection)) {
95893
- throw invalidSessionConfiguration(`The Turn configuration does not match Agent setting ${option.id}`);
95894
- }
96002
+ throw unavailable === "refuse" ? sessionConfigurationConflict(
96003
+ `The Agent did not retain the selected setting "${selection.configId}". Review the settings and try again.`
96004
+ ) : invalidSessionConfiguration(`The Turn configuration does not match Agent setting ${selection.configId}`);
95895
96005
  }
95896
96006
  }
95897
96007
  function unavailableSessionConfigurationCategory(selection) {
@@ -95903,57 +96013,42 @@ function unavailableSessionConfigurationCategory(selection) {
95903
96013
  }
95904
96014
  return "unknown";
95905
96015
  }
95906
- async function applySessionConfigurationSelection(sessions, options, selection, agent2, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
95907
- const option = options.find((candidate) => candidate.id === selection.configId);
96016
+ function unavailableReason(option, selection) {
95908
96017
  if (option === void 0) {
95909
- warnIgnoredSetting(
95910
- "session_configuration_setting_ignored",
95911
- commandId,
95912
- sessionId,
95913
- agent2.id,
95914
- selection,
95915
- unavailableSessionConfigurationCategory(selection),
95916
- "setting_unavailable"
95917
- );
95918
- return options;
96018
+ return "setting_unavailable";
95919
96019
  }
95920
96020
  if (option.type !== selection.valueType) {
95921
- warnIgnoredSetting(
95922
- "session_configuration_setting_ignored",
95923
- commandId,
95924
- sessionId,
95925
- agent2.id,
95926
- selection,
95927
- option.category,
95928
- "setting_schema_mismatch"
95929
- );
95930
- return options;
96021
+ return "setting_schema_mismatch";
95931
96022
  }
95932
96023
  if (option.type === "boolean" && selection.value.length > 0 || option.type === "select" && selection.booleanValue) {
95933
- warnIgnoredSetting(
95934
- "session_configuration_setting_ignored",
95935
- commandId,
95936
- sessionId,
95937
- agent2.id,
95938
- selection,
95939
- option.category,
95940
- "selection_schema_mismatch"
95941
- );
95942
- return options;
96024
+ return "selection_schema_mismatch";
95943
96025
  }
95944
96026
  if (option.type === "select" && !option.values.some((value) => value.value === selection.value)) {
96027
+ return "value_unavailable";
96028
+ }
96029
+ return null;
96030
+ }
96031
+ async function applySessionConfigurationSelection(sessions, options, selection, unavailable, agent2, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
96032
+ const option = options.find((candidate) => candidate.id === selection.configId);
96033
+ const reason = unavailableReason(option, selection);
96034
+ if (reason !== null) {
96035
+ if (unavailable === "refuse") {
96036
+ throw sessionConfigurationConflict(
96037
+ `The selected Agent setting "${selection.configId}" is no longer available. Refresh the settings and try again.`
96038
+ );
96039
+ }
95945
96040
  warnIgnoredSetting(
95946
96041
  "session_configuration_setting_ignored",
95947
96042
  commandId,
95948
96043
  sessionId,
95949
96044
  agent2.id,
95950
96045
  selection,
95951
- option.category,
95952
- "value_unavailable"
96046
+ option?.category ?? unavailableSessionConfigurationCategory(selection),
96047
+ reason
95953
96048
  );
95954
96049
  return options;
95955
96050
  }
95956
- if (sessionConfigurationMatches(option, selection)) {
96051
+ if (option === void 0 || sessionConfigurationMatches(option, selection)) {
95957
96052
  return options;
95958
96053
  }
95959
96054
  return (await sessions.applySessionConfiguration({
@@ -95970,13 +96065,14 @@ async function applySessionConfigurationSelection(sessions, options, selection,
95970
96065
  valueType: selection.valueType
95971
96066
  })).configOptions;
95972
96067
  }
95973
- async function applyCompleteSessionConfiguration(sessions, initialOptions, selections, agent2, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
96068
+ async function applyCompleteSessionConfiguration(sessions, initialOptions, selections, unavailable, agent2, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
95974
96069
  let options = initialOptions;
95975
96070
  for (const selection of inDependencyOrder(selections, initialOptions)) {
95976
96071
  options = await applySessionConfigurationSelection(
95977
96072
  sessions,
95978
96073
  options,
95979
96074
  selection,
96075
+ unavailable,
95980
96076
  agent2,
95981
96077
  adapter,
95982
96078
  cwd,
@@ -95986,7 +96082,7 @@ async function applyCompleteSessionConfiguration(sessions, initialOptions, selec
95986
96082
  signal
95987
96083
  );
95988
96084
  }
95989
- assertAppliedSessionConfiguration(options, selections);
96085
+ assertAppliedSessionConfiguration(options, selections, unavailable);
95990
96086
  }
95991
96087
  function warnIgnoredSetting(event, commandId, sessionId, agentId, selection, category, reason) {
95992
96088
  const details = {
@@ -96052,6 +96148,7 @@ async function executePrompt({
96052
96148
  sessions,
96053
96149
  prepared.configOptions,
96054
96150
  sessionConfigurations ?? [],
96151
+ "ignore",
96055
96152
  executionAgent,
96056
96153
  adapter,
96057
96154
  resolved.cwd,
@@ -96364,19 +96461,40 @@ async function prepareSession(command2, recovery, closed, config2, resolveAgent,
96364
96461
  sessionId: command2.sessionId,
96365
96462
  signal
96366
96463
  };
96367
- const prepared = command2.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics, closed) : await sessions.prepareSession(preparation, metrics, closed);
96368
- const configuration = command2.configuration;
96369
- const snapshot = configuration === void 0 ? prepared : await metrics.measure(
96370
- "configuration",
96371
- async () => await sessions.applySessionConfiguration({
96372
- ...preparation,
96373
- booleanValue: configuration.booleanValue,
96374
- configId: configuration.configId,
96375
- requestId: command2.requestId,
96376
- value: configuration.value,
96377
- valueType: configuration.valueType
96378
- })
96379
- );
96464
+ const prepare = async () => {
96465
+ if (command2.transient === true) {
96466
+ return await sessions.inspectSession(preparation, metrics);
96467
+ }
96468
+ if (recovery.kind === "history-required") {
96469
+ return await sessions.restoreSession(preparation, metrics, closed);
96470
+ }
96471
+ const configurations = command2.configurations;
96472
+ if (configurations === void 0) {
96473
+ return await sessions.prepareSession(preparation, metrics, closed);
96474
+ }
96475
+ return await sessions.createSession(
96476
+ preparation,
96477
+ async (created) => await metrics.measure(
96478
+ "configuration",
96479
+ async () => await applyCompleteSessionConfiguration(
96480
+ sessions,
96481
+ created.configOptions,
96482
+ configurations,
96483
+ "refuse",
96484
+ resolvedAgent.agent,
96485
+ resolvedAgent.adapter,
96486
+ resolved.cwd,
96487
+ resolved.additionalDirectories,
96488
+ command2.requestId,
96489
+ command2.sessionId,
96490
+ signal
96491
+ )
96492
+ ),
96493
+ metrics,
96494
+ closed
96495
+ );
96496
+ };
96497
+ const prepared = await prepare();
96380
96498
  return {
96381
96499
  additionalDirectories: resolved.additionalDirectoryEntries,
96382
96500
  agentId: command2.agentId,
@@ -96384,8 +96502,8 @@ async function prepareSession(command2, recovery, closed, config2, resolveAgent,
96384
96502
  agentVersion: prepared.agentVersion,
96385
96503
  capabilities: prepared.capabilities,
96386
96504
  commands: prepared.commands,
96387
- configOptions: snapshot.configOptions,
96388
- configurationRevision: snapshot.configurationRevision,
96505
+ configOptions: prepared.configOptions,
96506
+ configurationRevision: prepared.configurationRevision,
96389
96507
  directoryId: command2.directoryId,
96390
96508
  directoryLabel: resolved.directoryLabel,
96391
96509
  kind: "session.ready",
@@ -97907,4 +98025,4 @@ export {
97907
98025
  * MIT Licensed
97908
98026
  *)
97909
98027
  */
97910
- //# sourceMappingURL=chunk-LZZG3QZL.js.map
98028
+ //# sourceMappingURL=chunk-QEHEPZW2.js.map