overlord-cli 0.2609181229.0 → 0.2609221008.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/dist/index.js CHANGED
@@ -3282,12 +3282,12 @@ function createBackendClient() {
3282
3282
  const clientDevice = clientDeviceIdentity();
3283
3283
  async function request({
3284
3284
  method,
3285
- path: path37,
3285
+ path: path38,
3286
3286
  body,
3287
3287
  extraHeaders,
3288
3288
  rawBody
3289
3289
  }) {
3290
- const url2 = `${baseUrl}${path37.startsWith("/") ? path37 : `/${path37}`}`;
3290
+ const url2 = `${baseUrl}${path38.startsWith("/") ? path38 : `/${path38}`}`;
3291
3291
  const auth = resolveAuthHeaders({ baseUrl });
3292
3292
  if (auth.storedCredentialBackendUrl) {
3293
3293
  throw new CliError({
@@ -3323,14 +3323,14 @@ Start the Desktop/local backend or run \`ovld config set cloud <url>\`.
3323
3323
  throw new CliError({ message: formatExecutionRequestAlreadyLinkedDiagnostic() });
3324
3324
  }
3325
3325
  if (response.status === 401 && auth.headers.Authorization) {
3326
- const detail = errorMessageFromJson2(payload) ?? `Backend request failed: ${method} ${path37} (${response.status})`;
3326
+ const detail = errorMessageFromJson2(payload) ?? `Backend request failed: ${method} ${path38} (${response.status})`;
3327
3327
  throw new CliError({
3328
3328
  message: `${detail}
3329
3329
  ` + (auth.fromStored ? "Your saved credentials were rejected. Run `ovld auth login` to sign in again." : "Run `ovld auth login` or refresh your USER_TOKEN environment variable.")
3330
3330
  });
3331
3331
  }
3332
3332
  throw new CliError({
3333
- message: errorMessageFromJson2(payload) ?? `Backend request failed: ${method} ${path37} (${response.status})`
3333
+ message: errorMessageFromJson2(payload) ?? `Backend request failed: ${method} ${path38} (${response.status})`
3334
3334
  });
3335
3335
  }
3336
3336
  return payload;
@@ -3338,13 +3338,13 @@ Start the Desktop/local backend or run \`ovld config set cloud <url>\`.
3338
3338
  return {
3339
3339
  baseUrl,
3340
3340
  health: () => request({ method: "GET", path: "/api/health" }),
3341
- get: (path37) => request({ method: "GET", path: path37 }),
3342
- post: ({ path: path37, body }) => request({ method: "POST", path: path37, body }),
3343
- patch: ({ path: path37, body }) => request({ method: "PATCH", path: path37, body }),
3344
- delete: (path37) => request({ method: "DELETE", path: path37 }),
3345
- postRaw: ({ path: path37, body, contentType, filename }) => request({
3341
+ get: (path38) => request({ method: "GET", path: path38 }),
3342
+ post: ({ path: path38, body }) => request({ method: "POST", path: path38, body }),
3343
+ patch: ({ path: path38, body }) => request({ method: "PATCH", path: path38, body }),
3344
+ delete: (path38) => request({ method: "DELETE", path: path38 }),
3345
+ postRaw: ({ path: path38, body, contentType, filename }) => request({
3346
3346
  method: "POST",
3347
- path: path37,
3347
+ path: path38,
3348
3348
  rawBody: body,
3349
3349
  extraHeaders: {
3350
3350
  "Content-Type": contentType || "application/octet-stream",
@@ -8008,8 +8008,8 @@ function accessModeToResourcePathPermission({ accessMode, isPrimary = false }) {
8008
8008
  return "rw";
8009
8009
  return accessMode === "read" ? "ro" : "rw";
8010
8010
  }
8011
- function formatResourcePathWithPermission({ path: path37, accessMode, isPrimary = false }) {
8012
- const trimmed7 = path37.trim();
8011
+ function formatResourcePathWithPermission({ path: path38, accessMode, isPrimary = false }) {
8012
+ const trimmed7 = path38.trim();
8013
8013
  if (!trimmed7)
8014
8014
  return "";
8015
8015
  const permission = accessModeToResourcePathPermission({ accessMode, isPrimary });
@@ -8023,11 +8023,11 @@ function formatProjectResourcePathsFromManifest(projectResources) {
8023
8023
  if (!entry || typeof entry !== "object")
8024
8024
  continue;
8025
8025
  const record2 = entry;
8026
- const path37 = typeof record2.path === "string" ? record2.path.trim() : "";
8027
- if (!path37)
8026
+ const path38 = typeof record2.path === "string" ? record2.path.trim() : "";
8027
+ if (!path38)
8028
8028
  continue;
8029
8029
  paths.push(formatResourcePathWithPermission({
8030
- path: path37,
8030
+ path: path38,
8031
8031
  accessMode: typeof record2.accessMode === "string" ? record2.accessMode : null,
8032
8032
  isPrimary: record2.isPrimary === true
8033
8033
  }));
@@ -8109,11 +8109,11 @@ function createChannelClient({
8109
8109
  token
8110
8110
  }) {
8111
8111
  const root = `${baseUrl.replace(/\/+$/, "")}/api/agent-session-channels/v1`;
8112
- async function request(method, path37, body, timeoutMs) {
8112
+ async function request(method, path38, body, timeoutMs) {
8113
8113
  const controller = new AbortController();
8114
8114
  const timer = setTimeout(() => controller.abort(), timeoutMs);
8115
8115
  try {
8116
- const response = await fetch(`${root}${path37}`, {
8116
+ const response = await fetch(`${root}${path38}`, {
8117
8117
  method,
8118
8118
  // The credential travels here and only here: an Authorization header on a request the
8119
8119
  // CLI itself constructs. Not in the URL, which lands in access logs; not in the body,
@@ -8139,8 +8139,8 @@ function createChannelClient({
8139
8139
  }
8140
8140
  }
8141
8141
  return {
8142
- post: (path37, body, options) => request("POST", path37, body ?? {}, options?.timeoutMs ?? DEFAULT_TIMEOUT_MS),
8143
- get: (path37, options) => request("GET", path37, void 0, options?.timeoutMs ?? DEFAULT_TIMEOUT_MS)
8142
+ post: (path38, body, options) => request("POST", path38, body ?? {}, options?.timeoutMs ?? DEFAULT_TIMEOUT_MS),
8143
+ get: (path38, options) => request("GET", path38, void 0, options?.timeoutMs ?? DEFAULT_TIMEOUT_MS)
8144
8144
  };
8145
8145
  }
8146
8146
  var DEFAULT_TIMEOUT_MS;
@@ -8239,9 +8239,9 @@ function reduceUrl(rawUrl) {
8239
8239
  try {
8240
8240
  const url2 = new URL(raw);
8241
8241
  const hadQuery = url2.search !== "" || url2.hash !== "";
8242
- const path37 = url2.pathname === "/" ? "" : url2.pathname;
8242
+ const path38 = url2.pathname === "/" ? "" : url2.pathname;
8243
8243
  return {
8244
- display: safeText(`${url2.protocol}//${url2.host}${path37}`).text,
8244
+ display: safeText(`${url2.protocol}//${url2.host}${path38}`).text,
8245
8245
  host: url2.host || null,
8246
8246
  scheme: url2.protocol.replace(/:$/, ""),
8247
8247
  hadQuery
@@ -8406,17 +8406,17 @@ var init_mcp = __esm({
8406
8406
  function describeRead({ input, projectRoot }) {
8407
8407
  const record2 = input && typeof input === "object" ? input : {};
8408
8408
  const raw = typeof record2.file_path === "string" && record2.file_path || typeof record2.filePath === "string" && record2.filePath || typeof record2.path === "string" && record2.path || typeof record2.notebook_path === "string" && record2.notebook_path || null;
8409
- const path37 = reducePath(raw, projectRoot);
8409
+ const path38 = reducePath(raw, projectRoot);
8410
8410
  const markers = [
8411
- path37?.outsideProject && "outside-project-directory",
8412
- path37?.nonAscii && "non-ascii-path"
8411
+ path38?.outsideProject && "outside-project-directory",
8412
+ path38?.nonAscii && "non-ascii-path"
8413
8413
  ];
8414
- if (path37 && /(^|\/)(\.env|\.npmrc|\.netrc|id_rsa|id_ed25519|credentials)(\.|$)/.test(path37.display)) {
8414
+ if (path38 && /(^|\/)(\.env|\.npmrc|\.netrc|id_rsa|id_ed25519|credentials)(\.|$)/.test(path38.display)) {
8415
8415
  markers.push("secret-adjacent");
8416
8416
  }
8417
8417
  return {
8418
8418
  action: "Read a file",
8419
- subject: path37?.display ?? null,
8419
+ subject: path38?.display ?? null,
8420
8420
  detail: null,
8421
8421
  riskMarkers: normalizeMarkers(markers)
8422
8422
  };
@@ -8558,21 +8558,21 @@ function isOverwrite(record2) {
8558
8558
  }
8559
8559
  function describeWrite({ input, projectRoot }) {
8560
8560
  const record2 = input && typeof input === "object" ? input : {};
8561
- const path37 = reducePath(readPath(record2), projectRoot);
8561
+ const path38 = reducePath(readPath(record2), projectRoot);
8562
8562
  const overwrite = isOverwrite(record2);
8563
8563
  const bytes = byteLength(readContent(record2));
8564
8564
  const markers = [
8565
8565
  overwrite && "overwrites-existing",
8566
- path37?.outsideProject && "outside-project-directory",
8567
- path37?.nonAscii && "non-ascii-path"
8566
+ path38?.outsideProject && "outside-project-directory",
8567
+ path38?.nonAscii && "non-ascii-path"
8568
8568
  ];
8569
- if (path37 && /(^|\/)(\.env|\.npmrc|\.netrc|id_rsa|id_ed25519|credentials)(\.|$)/.test(path37.display)) {
8569
+ if (path38 && /(^|\/)(\.env|\.npmrc|\.netrc|id_rsa|id_ed25519|credentials)(\.|$)/.test(path38.display)) {
8570
8570
  markers.push("secret-adjacent");
8571
8571
  }
8572
8572
  const detail = bytes === null ? overwrite ? "replacing existing text" : null : `${bytes} byte${bytes === 1 ? "" : "s"}${overwrite ? ", replacing existing text" : ""}`;
8573
8573
  return {
8574
8574
  action: overwrite ? "Overwrite a file" : "Write a file",
8575
- subject: path37?.display ?? null,
8575
+ subject: path38?.display ?? null,
8576
8576
  detail,
8577
8577
  riskMarkers: normalizeMarkers(markers)
8578
8578
  };
@@ -8778,16 +8778,16 @@ function readPath2(source, dotted) {
8778
8778
  return current;
8779
8779
  }
8780
8780
  function firstString(source, paths) {
8781
- for (const path37 of paths ?? []) {
8782
- const value = readPath2(source, path37);
8781
+ for (const path38 of paths ?? []) {
8782
+ const value = readPath2(source, path38);
8783
8783
  if (typeof value === "string" && value.trim() !== "")
8784
8784
  return value.trim();
8785
8785
  }
8786
8786
  return null;
8787
8787
  }
8788
8788
  function firstLiteralString(source, paths) {
8789
- for (const path37 of paths ?? []) {
8790
- const value = readPath2(source, path37);
8789
+ for (const path38 of paths ?? []) {
8790
+ const value = readPath2(source, path38);
8791
8791
  if (typeof value === "string" && value.length > 0)
8792
8792
  return value;
8793
8793
  }
@@ -9339,8 +9339,8 @@ async function runAgentSessionInbox({
9339
9339
  const scope = resolveAgentSessionScope({ agent, env });
9340
9340
  if (!scope) return emptyResult("Empty");
9341
9341
  const payload = payloadRaw === void 0 ? parseNativePayload(readBoundedStdin()) : parseNativePayload(payloadRaw);
9342
- const path37 = resolveInjectPath({ agent, payload });
9343
- if (path37 === "unsupported") return emptyResult("Unsupported");
9342
+ const path38 = resolveInjectPath({ agent, payload });
9343
+ if (path38 === "unsupported") return emptyResult("Unsupported");
9344
9344
  const baseUrl = env.OVERLORD_BACKEND_URL?.trim();
9345
9345
  if (!baseUrl && !injectedClient) return emptyResult("Empty");
9346
9346
  const client = injectedClient ?? createChannelClient({ baseUrl, channelId: scope.channelId, token: scope.token });
@@ -9354,15 +9354,15 @@ async function runAgentSessionInbox({
9354
9354
  );
9355
9355
  if (!claimed.ok || !claimed.value.input) return emptyResult("Empty");
9356
9356
  const input = claimed.value.input;
9357
- return await emitClaimedInput({ agent, path: path37, input, client });
9357
+ return await emitClaimedInput({ agent, path: path38, input, client });
9358
9358
  }
9359
9359
  async function emitClaimedInput({
9360
9360
  agent,
9361
- path: path37,
9361
+ path: path38,
9362
9362
  input,
9363
9363
  client
9364
9364
  }) {
9365
- if (path37 === "claude-mid-turn") {
9365
+ if (path38 === "claude-mid-turn") {
9366
9366
  const emitted = await client.post(`/inputs/${input.id}/emitted`, {
9367
9367
  leaseId: input.leaseId,
9368
9368
  deliveryOutcome: "delivered"
@@ -9377,7 +9377,7 @@ async function emitClaimedInput({
9377
9377
  inputId: input.id
9378
9378
  };
9379
9379
  }
9380
- if (path37 === "claude-turn-boundary") {
9380
+ if (path38 === "claude-turn-boundary") {
9381
9381
  const emitted = await client.post(`/inputs/${input.id}/emitted`, {
9382
9382
  leaseId: input.leaseId,
9383
9383
  deliveryOutcome: "delivered"
@@ -9392,7 +9392,7 @@ async function emitClaimedInput({
9392
9392
  inputId: input.id
9393
9393
  };
9394
9394
  }
9395
- if (path37 === "cursor-turn-boundary") {
9395
+ if (path38 === "cursor-turn-boundary") {
9396
9396
  const emitted = await client.post(`/inputs/${input.id}/emitted`, {
9397
9397
  leaseId: input.leaseId,
9398
9398
  deliveryOutcome: "queued_turn_boundary"
@@ -9406,7 +9406,7 @@ async function emitClaimedInput({
9406
9406
  inputId: input.id
9407
9407
  };
9408
9408
  }
9409
- if (path37 === "codex-turn-boundary") {
9409
+ if (path38 === "codex-turn-boundary") {
9410
9410
  const emitted = await client.post(`/inputs/${input.id}/emitted`, {
9411
9411
  leaseId: input.leaseId,
9412
9412
  deliveryOutcome: "delivered"
@@ -9421,7 +9421,7 @@ async function emitClaimedInput({
9421
9421
  inputId: input.id
9422
9422
  };
9423
9423
  }
9424
- if (path37 === "pi-mid-turn") {
9424
+ if (path38 === "pi-mid-turn") {
9425
9425
  return {
9426
9426
  report: "Empty",
9427
9427
  exitCode: 0,
@@ -9526,8 +9526,8 @@ var init_inbox = __esm({
9526
9526
 
9527
9527
  // ../packages/core/dist/service/agent-session/pure/decision.js
9528
9528
  function firstValue(source, paths) {
9529
- for (const path37 of paths ?? []) {
9530
- const value = readPath2(source, path37);
9529
+ for (const path38 of paths ?? []) {
9530
+ const value = readPath2(source, path38);
9531
9531
  if (value !== void 0 && value !== null)
9532
9532
  return value;
9533
9533
  }
@@ -10117,10 +10117,10 @@ async function reconcileState({
10117
10117
  }) {
10118
10118
  let posted = 0;
10119
10119
  let duplicates = 0;
10120
- for (const path37 of ["/permission", "/question"]) {
10120
+ for (const path38 of ["/permission", "/question"]) {
10121
10121
  let entries;
10122
10122
  try {
10123
- const response = await doFetch(`${controlPlaneBaseUrl(port)}${path37}`, {
10123
+ const response = await doFetch(`${controlPlaneBaseUrl(port)}${path38}`, {
10124
10124
  headers: authHeaders(password)
10125
10125
  });
10126
10126
  if (!response.ok) continue;
@@ -10130,7 +10130,7 @@ async function reconcileState({
10130
10130
  continue;
10131
10131
  }
10132
10132
  for (const entry of entries) {
10133
- if (path37 === "/permission") {
10133
+ if (path38 === "/permission") {
10134
10134
  await syncOpenCodePermission({
10135
10135
  client,
10136
10136
  frame: { event: "permission.updated", data: JSON.stringify(entry) },
@@ -10663,17 +10663,17 @@ var require_visit = __commonJS({
10663
10663
  visit.BREAK = BREAK;
10664
10664
  visit.SKIP = SKIP;
10665
10665
  visit.REMOVE = REMOVE;
10666
- function visit_(key, node, visitor, path37) {
10667
- const ctrl = callVisitor(key, node, visitor, path37);
10666
+ function visit_(key, node, visitor, path38) {
10667
+ const ctrl = callVisitor(key, node, visitor, path38);
10668
10668
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
10669
- replaceNode(key, path37, ctrl);
10670
- return visit_(key, ctrl, visitor, path37);
10669
+ replaceNode(key, path38, ctrl);
10670
+ return visit_(key, ctrl, visitor, path38);
10671
10671
  }
10672
10672
  if (typeof ctrl !== "symbol") {
10673
10673
  if (identity.isCollection(node)) {
10674
- path37 = Object.freeze(path37.concat(node));
10674
+ path38 = Object.freeze(path38.concat(node));
10675
10675
  for (let i = 0; i < node.items.length; ++i) {
10676
- const ci = visit_(i, node.items[i], visitor, path37);
10676
+ const ci = visit_(i, node.items[i], visitor, path38);
10677
10677
  if (typeof ci === "number")
10678
10678
  i = ci - 1;
10679
10679
  else if (ci === BREAK)
@@ -10684,13 +10684,13 @@ var require_visit = __commonJS({
10684
10684
  }
10685
10685
  }
10686
10686
  } else if (identity.isPair(node)) {
10687
- path37 = Object.freeze(path37.concat(node));
10688
- const ck = visit_("key", node.key, visitor, path37);
10687
+ path38 = Object.freeze(path38.concat(node));
10688
+ const ck = visit_("key", node.key, visitor, path38);
10689
10689
  if (ck === BREAK)
10690
10690
  return BREAK;
10691
10691
  else if (ck === REMOVE)
10692
10692
  node.key = null;
10693
- const cv = visit_("value", node.value, visitor, path37);
10693
+ const cv = visit_("value", node.value, visitor, path38);
10694
10694
  if (cv === BREAK)
10695
10695
  return BREAK;
10696
10696
  else if (cv === REMOVE)
@@ -10711,17 +10711,17 @@ var require_visit = __commonJS({
10711
10711
  visitAsync.BREAK = BREAK;
10712
10712
  visitAsync.SKIP = SKIP;
10713
10713
  visitAsync.REMOVE = REMOVE;
10714
- async function visitAsync_(key, node, visitor, path37) {
10715
- const ctrl = await callVisitor(key, node, visitor, path37);
10714
+ async function visitAsync_(key, node, visitor, path38) {
10715
+ const ctrl = await callVisitor(key, node, visitor, path38);
10716
10716
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
10717
- replaceNode(key, path37, ctrl);
10718
- return visitAsync_(key, ctrl, visitor, path37);
10717
+ replaceNode(key, path38, ctrl);
10718
+ return visitAsync_(key, ctrl, visitor, path38);
10719
10719
  }
10720
10720
  if (typeof ctrl !== "symbol") {
10721
10721
  if (identity.isCollection(node)) {
10722
- path37 = Object.freeze(path37.concat(node));
10722
+ path38 = Object.freeze(path38.concat(node));
10723
10723
  for (let i = 0; i < node.items.length; ++i) {
10724
- const ci = await visitAsync_(i, node.items[i], visitor, path37);
10724
+ const ci = await visitAsync_(i, node.items[i], visitor, path38);
10725
10725
  if (typeof ci === "number")
10726
10726
  i = ci - 1;
10727
10727
  else if (ci === BREAK)
@@ -10732,13 +10732,13 @@ var require_visit = __commonJS({
10732
10732
  }
10733
10733
  }
10734
10734
  } else if (identity.isPair(node)) {
10735
- path37 = Object.freeze(path37.concat(node));
10736
- const ck = await visitAsync_("key", node.key, visitor, path37);
10735
+ path38 = Object.freeze(path38.concat(node));
10736
+ const ck = await visitAsync_("key", node.key, visitor, path38);
10737
10737
  if (ck === BREAK)
10738
10738
  return BREAK;
10739
10739
  else if (ck === REMOVE)
10740
10740
  node.key = null;
10741
- const cv = await visitAsync_("value", node.value, visitor, path37);
10741
+ const cv = await visitAsync_("value", node.value, visitor, path38);
10742
10742
  if (cv === BREAK)
10743
10743
  return BREAK;
10744
10744
  else if (cv === REMOVE)
@@ -10765,23 +10765,23 @@ var require_visit = __commonJS({
10765
10765
  }
10766
10766
  return visitor;
10767
10767
  }
10768
- function callVisitor(key, node, visitor, path37) {
10768
+ function callVisitor(key, node, visitor, path38) {
10769
10769
  if (typeof visitor === "function")
10770
- return visitor(key, node, path37);
10770
+ return visitor(key, node, path38);
10771
10771
  if (identity.isMap(node))
10772
- return visitor.Map?.(key, node, path37);
10772
+ return visitor.Map?.(key, node, path38);
10773
10773
  if (identity.isSeq(node))
10774
- return visitor.Seq?.(key, node, path37);
10774
+ return visitor.Seq?.(key, node, path38);
10775
10775
  if (identity.isPair(node))
10776
- return visitor.Pair?.(key, node, path37);
10776
+ return visitor.Pair?.(key, node, path38);
10777
10777
  if (identity.isScalar(node))
10778
- return visitor.Scalar?.(key, node, path37);
10778
+ return visitor.Scalar?.(key, node, path38);
10779
10779
  if (identity.isAlias(node))
10780
- return visitor.Alias?.(key, node, path37);
10780
+ return visitor.Alias?.(key, node, path38);
10781
10781
  return void 0;
10782
10782
  }
10783
- function replaceNode(key, path37, node) {
10784
- const parent = path37[path37.length - 1];
10783
+ function replaceNode(key, path38, node) {
10784
+ const parent = path38[path38.length - 1];
10785
10785
  if (identity.isCollection(parent)) {
10786
10786
  parent.items[key] = node;
10787
10787
  } else if (identity.isPair(parent)) {
@@ -11391,10 +11391,10 @@ var require_Collection = __commonJS({
11391
11391
  var createNode = require_createNode();
11392
11392
  var identity = require_identity();
11393
11393
  var Node = require_Node();
11394
- function collectionFromPath(schema, path37, value) {
11394
+ function collectionFromPath(schema, path38, value) {
11395
11395
  let v = value;
11396
- for (let i = path37.length - 1; i >= 0; --i) {
11397
- const k = path37[i];
11396
+ for (let i = path38.length - 1; i >= 0; --i) {
11397
+ const k = path38[i];
11398
11398
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
11399
11399
  const a = [];
11400
11400
  a[k] = v;
@@ -11413,7 +11413,7 @@ var require_Collection = __commonJS({
11413
11413
  sourceObjects: /* @__PURE__ */ new Map()
11414
11414
  });
11415
11415
  }
11416
- var isEmptyPath = (path37) => path37 == null || typeof path37 === "object" && !!path37[Symbol.iterator]().next().done;
11416
+ var isEmptyPath = (path38) => path38 == null || typeof path38 === "object" && !!path38[Symbol.iterator]().next().done;
11417
11417
  var Collection = class extends Node.NodeBase {
11418
11418
  constructor(type, schema) {
11419
11419
  super(type);
@@ -11443,11 +11443,11 @@ var require_Collection = __commonJS({
11443
11443
  * be a Pair instance or a `{ key, value }` object, which may not have a key
11444
11444
  * that already exists in the map.
11445
11445
  */
11446
- addIn(path37, value) {
11447
- if (isEmptyPath(path37))
11446
+ addIn(path38, value) {
11447
+ if (isEmptyPath(path38))
11448
11448
  this.add(value);
11449
11449
  else {
11450
- const [key, ...rest] = path37;
11450
+ const [key, ...rest] = path38;
11451
11451
  const node = this.get(key, true);
11452
11452
  if (identity.isCollection(node))
11453
11453
  node.addIn(rest, value);
@@ -11461,8 +11461,8 @@ var require_Collection = __commonJS({
11461
11461
  * Removes a value from the collection.
11462
11462
  * @returns `true` if the item was found and removed.
11463
11463
  */
11464
- deleteIn(path37) {
11465
- const [key, ...rest] = path37;
11464
+ deleteIn(path38) {
11465
+ const [key, ...rest] = path38;
11466
11466
  if (rest.length === 0)
11467
11467
  return this.delete(key);
11468
11468
  const node = this.get(key, true);
@@ -11476,8 +11476,8 @@ var require_Collection = __commonJS({
11476
11476
  * scalar values from their surrounding node; to disable set `keepScalar` to
11477
11477
  * `true` (collections are always returned intact).
11478
11478
  */
11479
- getIn(path37, keepScalar) {
11480
- const [key, ...rest] = path37;
11479
+ getIn(path38, keepScalar) {
11480
+ const [key, ...rest] = path38;
11481
11481
  const node = this.get(key, true);
11482
11482
  if (rest.length === 0)
11483
11483
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -11495,8 +11495,8 @@ var require_Collection = __commonJS({
11495
11495
  /**
11496
11496
  * Checks if the collection includes a value with the key `key`.
11497
11497
  */
11498
- hasIn(path37) {
11499
- const [key, ...rest] = path37;
11498
+ hasIn(path38) {
11499
+ const [key, ...rest] = path38;
11500
11500
  if (rest.length === 0)
11501
11501
  return this.has(key);
11502
11502
  const node = this.get(key, true);
@@ -11506,8 +11506,8 @@ var require_Collection = __commonJS({
11506
11506
  * Sets a value in this collection. For `!!set`, `value` needs to be a
11507
11507
  * boolean to add/remove the item from the set.
11508
11508
  */
11509
- setIn(path37, value) {
11510
- const [key, ...rest] = path37;
11509
+ setIn(path38, value) {
11510
+ const [key, ...rest] = path38;
11511
11511
  if (rest.length === 0) {
11512
11512
  this.set(key, value);
11513
11513
  } else {
@@ -14022,9 +14022,9 @@ var require_Document = __commonJS({
14022
14022
  this.contents.add(value);
14023
14023
  }
14024
14024
  /** Adds a value to the document. */
14025
- addIn(path37, value) {
14025
+ addIn(path38, value) {
14026
14026
  if (assertCollection(this.contents))
14027
- this.contents.addIn(path37, value);
14027
+ this.contents.addIn(path38, value);
14028
14028
  }
14029
14029
  /**
14030
14030
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -14099,14 +14099,14 @@ var require_Document = __commonJS({
14099
14099
  * Removes a value from the document.
14100
14100
  * @returns `true` if the item was found and removed.
14101
14101
  */
14102
- deleteIn(path37) {
14103
- if (Collection.isEmptyPath(path37)) {
14102
+ deleteIn(path38) {
14103
+ if (Collection.isEmptyPath(path38)) {
14104
14104
  if (this.contents == null)
14105
14105
  return false;
14106
14106
  this.contents = null;
14107
14107
  return true;
14108
14108
  }
14109
- return assertCollection(this.contents) ? this.contents.deleteIn(path37) : false;
14109
+ return assertCollection(this.contents) ? this.contents.deleteIn(path38) : false;
14110
14110
  }
14111
14111
  /**
14112
14112
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -14121,10 +14121,10 @@ var require_Document = __commonJS({
14121
14121
  * scalar values from their surrounding node; to disable set `keepScalar` to
14122
14122
  * `true` (collections are always returned intact).
14123
14123
  */
14124
- getIn(path37, keepScalar) {
14125
- if (Collection.isEmptyPath(path37))
14124
+ getIn(path38, keepScalar) {
14125
+ if (Collection.isEmptyPath(path38))
14126
14126
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
14127
- return identity.isCollection(this.contents) ? this.contents.getIn(path37, keepScalar) : void 0;
14127
+ return identity.isCollection(this.contents) ? this.contents.getIn(path38, keepScalar) : void 0;
14128
14128
  }
14129
14129
  /**
14130
14130
  * Checks if the document includes a value with the key `key`.
@@ -14135,10 +14135,10 @@ var require_Document = __commonJS({
14135
14135
  /**
14136
14136
  * Checks if the document includes a value at `path`.
14137
14137
  */
14138
- hasIn(path37) {
14139
- if (Collection.isEmptyPath(path37))
14138
+ hasIn(path38) {
14139
+ if (Collection.isEmptyPath(path38))
14140
14140
  return this.contents !== void 0;
14141
- return identity.isCollection(this.contents) ? this.contents.hasIn(path37) : false;
14141
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path38) : false;
14142
14142
  }
14143
14143
  /**
14144
14144
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -14155,13 +14155,13 @@ var require_Document = __commonJS({
14155
14155
  * Sets a value in this document. For `!!set`, `value` needs to be a
14156
14156
  * boolean to add/remove the item from the set.
14157
14157
  */
14158
- setIn(path37, value) {
14159
- if (Collection.isEmptyPath(path37)) {
14158
+ setIn(path38, value) {
14159
+ if (Collection.isEmptyPath(path38)) {
14160
14160
  this.contents = value;
14161
14161
  } else if (this.contents == null) {
14162
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path37), value);
14162
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path38), value);
14163
14163
  } else if (assertCollection(this.contents)) {
14164
- this.contents.setIn(path37, value);
14164
+ this.contents.setIn(path38, value);
14165
14165
  }
14166
14166
  }
14167
14167
  /**
@@ -16121,9 +16121,9 @@ var require_cst_visit = __commonJS({
16121
16121
  visit.BREAK = BREAK;
16122
16122
  visit.SKIP = SKIP;
16123
16123
  visit.REMOVE = REMOVE;
16124
- visit.itemAtPath = (cst, path37) => {
16124
+ visit.itemAtPath = (cst, path38) => {
16125
16125
  let item = cst;
16126
- for (const [field, index] of path37) {
16126
+ for (const [field, index] of path38) {
16127
16127
  const tok = item?.[field];
16128
16128
  if (tok && "items" in tok) {
16129
16129
  item = tok.items[index];
@@ -16132,23 +16132,23 @@ var require_cst_visit = __commonJS({
16132
16132
  }
16133
16133
  return item;
16134
16134
  };
16135
- visit.parentCollection = (cst, path37) => {
16136
- const parent = visit.itemAtPath(cst, path37.slice(0, -1));
16137
- const field = path37[path37.length - 1][0];
16135
+ visit.parentCollection = (cst, path38) => {
16136
+ const parent = visit.itemAtPath(cst, path38.slice(0, -1));
16137
+ const field = path38[path38.length - 1][0];
16138
16138
  const coll = parent?.[field];
16139
16139
  if (coll && "items" in coll)
16140
16140
  return coll;
16141
16141
  throw new Error("Parent collection not found");
16142
16142
  };
16143
- function _visit(path37, item, visitor) {
16144
- let ctrl = visitor(item, path37);
16143
+ function _visit(path38, item, visitor) {
16144
+ let ctrl = visitor(item, path38);
16145
16145
  if (typeof ctrl === "symbol")
16146
16146
  return ctrl;
16147
16147
  for (const field of ["key", "value"]) {
16148
16148
  const token = item[field];
16149
16149
  if (token && "items" in token) {
16150
16150
  for (let i = 0; i < token.items.length; ++i) {
16151
- const ci = _visit(Object.freeze(path37.concat([[field, i]])), token.items[i], visitor);
16151
+ const ci = _visit(Object.freeze(path38.concat([[field, i]])), token.items[i], visitor);
16152
16152
  if (typeof ci === "number")
16153
16153
  i = ci - 1;
16154
16154
  else if (ci === BREAK)
@@ -16159,10 +16159,10 @@ var require_cst_visit = __commonJS({
16159
16159
  }
16160
16160
  }
16161
16161
  if (typeof ctrl === "function" && field === "key")
16162
- ctrl = ctrl(item, path37);
16162
+ ctrl = ctrl(item, path38);
16163
16163
  }
16164
16164
  }
16165
- return typeof ctrl === "function" ? ctrl(item, path37) : ctrl;
16165
+ return typeof ctrl === "function" ? ctrl(item, path38) : ctrl;
16166
16166
  }
16167
16167
  exports.visit = visit;
16168
16168
  }
@@ -18955,6 +18955,19 @@ var init_latch_gateway = __esm({
18955
18955
  });
18956
18956
 
18957
18957
  // ../packages/core/dist/service/latch-launch.js
18958
+ import path23 from "node:path";
18959
+ function selectLatchAgentLaunch({ agent, argv, preCommand, preLaunchCommands, extensions, shell }) {
18960
+ if (!extensions.includes(LATCH_AGENT_LAUNCH_EXTENSION))
18961
+ return null;
18962
+ if (agent !== "claude" && agent !== "codex")
18963
+ return null;
18964
+ if (preCommand?.trim() || !path23.isAbsolute(shell))
18965
+ return null;
18966
+ if (path23.basename(argv[0] ?? "") !== agent)
18967
+ return null;
18968
+ const prelude = (preLaunchCommands ?? []).map((command) => command.trim()).filter(Boolean).join("; ");
18969
+ return { agent, argv, ...prelude ? { prelude } : {} };
18970
+ }
18958
18971
  function trimmed5(value) {
18959
18972
  return typeof value === "string" && value.trim() ? value.trim() : null;
18960
18973
  }
@@ -18966,8 +18979,11 @@ function formatObjectiveLatchDisplay({ objectiveDisplayId, objectiveTitle }) {
18966
18979
  title: titlePart ? `${name} \u2014 ${titlePart}` : name
18967
18980
  };
18968
18981
  }
18969
- function buildLatchCreateManifest({ commandString, shell = process.env.SHELL?.trim() || "/bin/bash", cwd, env, size = DEFAULT_LATCH_TERMINAL_SIZE, title, name, commandLabel, externalRunId }) {
18982
+ function buildLatchCreateManifest({ commandString, agentLaunch, shell = process.env.SHELL?.trim() || "/bin/bash", cwd, env, size = DEFAULT_LATCH_TERMINAL_SIZE, title, name, commandLabel, externalRunId }) {
18970
18983
  const shellPath = trimmed5(shell) ?? "/bin/bash";
18984
+ if (agentLaunch && path23.basename(agentLaunch.argv[0] ?? "") !== agentLaunch.agent) {
18985
+ throw new Error("Latch agent launch argv must start with the declared agent executable");
18986
+ }
18971
18987
  const cleanedEnv = {};
18972
18988
  for (const [key, value] of Object.entries(env)) {
18973
18989
  if (key.trim() && typeof value === "string")
@@ -18988,14 +19004,21 @@ function buildLatchCreateManifest({ commandString, shell = process.env.SHELL?.tr
18988
19004
  return {
18989
19005
  format_version: LATCH_MANIFEST_FORMAT_VERSION,
18990
19006
  launch: {
18991
- argv: [shellPath, "-ilc", commandString],
19007
+ argv: agentLaunch ? [...agentLaunch.argv] : [shellPath, "-ilc", commandString],
18992
19008
  cwd,
18993
19009
  env: cleanedEnv,
18994
19010
  inherit_env: true,
18995
19011
  size: {
18996
19012
  cols: Math.max(1, Math.floor(size.cols) || DEFAULT_LATCH_TERMINAL_SIZE.cols),
18997
19013
  rows: Math.max(1, Math.floor(size.rows) || DEFAULT_LATCH_TERMINAL_SIZE.rows)
18998
- }
19014
+ },
19015
+ ...agentLaunch ? {
19016
+ agent: agentLaunch.agent,
19017
+ login_shell: {
19018
+ path: shellPath,
19019
+ ...agentLaunch.prelude ? { prelude: agentLaunch.prelude } : {}
19020
+ }
19021
+ } : {}
18999
19022
  },
19000
19023
  display
19001
19024
  };
@@ -19098,13 +19121,14 @@ function latchAttachCommand({ executable = "latch", providerSessionId }) {
19098
19121
  function shouldUseLatchProvider({ providerKind, latchSelectable }) {
19099
19122
  return trimmed5(providerKind)?.toLowerCase() === "latch" && latchSelectable === true;
19100
19123
  }
19101
- var LATCH_MANIFEST_FORMAT_VERSION, DEFAULT_LATCH_TERMINAL_SIZE, LATCH_OPEN_AS_MIN_PRODUCT_VERSION, LATCH_OPEN_BACKGROUND_MIN_PRODUCT_VERSION;
19124
+ var LATCH_MANIFEST_FORMAT_VERSION, DEFAULT_LATCH_TERMINAL_SIZE, LATCH_AGENT_LAUNCH_EXTENSION, LATCH_OPEN_AS_MIN_PRODUCT_VERSION, LATCH_OPEN_BACKGROUND_MIN_PRODUCT_VERSION;
19102
19125
  var init_latch_launch = __esm({
19103
19126
  "../packages/core/dist/service/latch-launch.js"() {
19104
19127
  "use strict";
19105
19128
  init_terminal_profile_types2();
19106
19129
  LATCH_MANIFEST_FORMAT_VERSION = 1;
19107
19130
  DEFAULT_LATCH_TERMINAL_SIZE = { cols: 120, rows: 36 };
19131
+ LATCH_AGENT_LAUNCH_EXTENSION = "agent-launch";
19108
19132
  LATCH_OPEN_AS_MIN_PRODUCT_VERSION = "0.2608140931.0";
19109
19133
  LATCH_OPEN_BACKGROUND_MIN_PRODUCT_VERSION = "0.2609181007.0";
19110
19134
  }
@@ -19543,19 +19567,19 @@ var init_git_run = __esm({
19543
19567
  // ../packages/core/dist/service/local-target/worktree-git.js
19544
19568
  import { existsSync as existsSync22, realpathSync as realpathSync4 } from "node:fs";
19545
19569
  import os5 from "node:os";
19546
- import path23 from "node:path";
19570
+ import path24 from "node:path";
19547
19571
  function resolveManagedWorktreeRoot() {
19548
19572
  const override = process.env.OVERLORD_WORKTREE_ROOT?.trim();
19549
19573
  if (override)
19550
- return path23.resolve(override);
19574
+ return path24.resolve(override);
19551
19575
  const home = process.env.OVLD_HOME?.trim() || process.env.OVERLORD_HOME?.trim();
19552
- return path23.join(home ? path23.resolve(home) : path23.join(os5.homedir(), ".ovld"), "worktrees");
19576
+ return path24.join(home ? path24.resolve(home) : path24.join(os5.homedir(), ".ovld"), "worktrees");
19553
19577
  }
19554
19578
  function resolveRealPath(targetPath) {
19555
19579
  try {
19556
19580
  return realpathSync4.native(targetPath);
19557
19581
  } catch {
19558
- return path23.resolve(targetPath);
19582
+ return path24.resolve(targetPath);
19559
19583
  }
19560
19584
  }
19561
19585
  function worktreeIsDirty(worktreePath) {
@@ -19612,7 +19636,7 @@ function collectManagedWorktrees({ worktreeRoot, projects }) {
19612
19636
  if (!currentPath)
19613
19637
  return;
19614
19638
  const resolved = resolveRealPath(currentPath);
19615
- const underRoot = resolved === resolvedRoot || resolved.startsWith(resolvedRoot + path23.sep);
19639
+ const underRoot = resolved === resolvedRoot || resolved.startsWith(resolvedRoot + path24.sep);
19616
19640
  if (underRoot && !seen.has(resolved)) {
19617
19641
  seen.add(resolved);
19618
19642
  entries.push({
@@ -19640,7 +19664,7 @@ function collectManagedWorktrees({ worktreeRoot, projects }) {
19640
19664
  return entries;
19641
19665
  }
19642
19666
  function removeManagedWorktree({ path: worktreePath, primaryRepoPath, force }) {
19643
- const target = path23.resolve(worktreePath);
19667
+ const target = path24.resolve(worktreePath);
19644
19668
  if (!force && worktreeIsDirty(target)) {
19645
19669
  return {
19646
19670
  removed: [],
@@ -19654,7 +19678,7 @@ function purgeManagedWorktrees({ entries }) {
19654
19678
  const removed = [];
19655
19679
  const skipped = [];
19656
19680
  for (const entry of entries) {
19657
- const target = path23.resolve(entry.path);
19681
+ const target = path24.resolve(entry.path);
19658
19682
  if (worktreeIsDirty(target)) {
19659
19683
  skipped.push({ path: target, reason: "uncommitted changes" });
19660
19684
  continue;
@@ -19680,13 +19704,13 @@ var init_worktree_git = __esm({
19680
19704
 
19681
19705
  // ../packages/core/dist/service/local-target/branch-actions-git.js
19682
19706
  function resolveActionCheckout(input) {
19683
- const path37 = resolveBranchCheckoutPath({
19707
+ const path38 = resolveBranchCheckoutPath({
19684
19708
  repoPath: input.primaryRepoPath,
19685
19709
  branchName: input.branchName,
19686
19710
  worktreePathHint: input.worktreePath
19687
19711
  });
19688
- if (path37)
19689
- return { ok: true, path: path37 };
19712
+ if (path38)
19713
+ return { ok: true, path: path38 };
19690
19714
  return {
19691
19715
  ok: false,
19692
19716
  code: "BRANCH_NO_WORKTREE",
@@ -20728,10 +20752,10 @@ function mergeDefs(...defs) {
20728
20752
  function cloneDef(schema) {
20729
20753
  return mergeDefs(schema._zod.def);
20730
20754
  }
20731
- function getElementAtPath(obj, path37) {
20732
- if (!path37)
20755
+ function getElementAtPath(obj, path38) {
20756
+ if (!path38)
20733
20757
  return obj;
20734
- return path37.reduce((acc, key) => acc?.[key], obj);
20758
+ return path38.reduce((acc, key) => acc?.[key], obj);
20735
20759
  }
20736
20760
  function promiseAllObject(promisesObj) {
20737
20761
  const keys = Object.keys(promisesObj);
@@ -21059,11 +21083,11 @@ function explicitlyAborted(x, startIndex = 0) {
21059
21083
  }
21060
21084
  return false;
21061
21085
  }
21062
- function prefixIssues(path37, issues) {
21086
+ function prefixIssues(path38, issues) {
21063
21087
  return issues.map((iss) => {
21064
21088
  var _a3;
21065
21089
  (_a3 = iss).path ?? (_a3.path = []);
21066
- iss.path.unshift(path37);
21090
+ iss.path.unshift(path38);
21067
21091
  return iss;
21068
21092
  });
21069
21093
  }
@@ -21280,16 +21304,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
21280
21304
  }
21281
21305
  function formatError(error51, mapper = (issue2) => issue2.message) {
21282
21306
  const fieldErrors = { _errors: [] };
21283
- const processError = (error52, path37 = []) => {
21307
+ const processError = (error52, path38 = []) => {
21284
21308
  for (const issue2 of error52.issues) {
21285
21309
  if (issue2.code === "invalid_union" && issue2.errors.length) {
21286
- issue2.errors.map((issues) => processError({ issues }, [...path37, ...issue2.path]));
21310
+ issue2.errors.map((issues) => processError({ issues }, [...path38, ...issue2.path]));
21287
21311
  } else if (issue2.code === "invalid_key") {
21288
- processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
21312
+ processError({ issues: issue2.issues }, [...path38, ...issue2.path]);
21289
21313
  } else if (issue2.code === "invalid_element") {
21290
- processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
21314
+ processError({ issues: issue2.issues }, [...path38, ...issue2.path]);
21291
21315
  } else {
21292
- const fullpath = [...path37, ...issue2.path];
21316
+ const fullpath = [...path38, ...issue2.path];
21293
21317
  if (fullpath.length === 0) {
21294
21318
  fieldErrors._errors.push(mapper(issue2));
21295
21319
  } else {
@@ -21316,17 +21340,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
21316
21340
  }
21317
21341
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
21318
21342
  const result = { errors: [] };
21319
- const processError = (error52, path37 = []) => {
21343
+ const processError = (error52, path38 = []) => {
21320
21344
  var _a3, _b;
21321
21345
  for (const issue2 of error52.issues) {
21322
21346
  if (issue2.code === "invalid_union" && issue2.errors.length) {
21323
- issue2.errors.map((issues) => processError({ issues }, [...path37, ...issue2.path]));
21347
+ issue2.errors.map((issues) => processError({ issues }, [...path38, ...issue2.path]));
21324
21348
  } else if (issue2.code === "invalid_key") {
21325
- processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
21349
+ processError({ issues: issue2.issues }, [...path38, ...issue2.path]);
21326
21350
  } else if (issue2.code === "invalid_element") {
21327
- processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
21351
+ processError({ issues: issue2.issues }, [...path38, ...issue2.path]);
21328
21352
  } else {
21329
- const fullpath = [...path37, ...issue2.path];
21353
+ const fullpath = [...path38, ...issue2.path];
21330
21354
  if (fullpath.length === 0) {
21331
21355
  result.errors.push(mapper(issue2));
21332
21356
  continue;
@@ -21358,8 +21382,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
21358
21382
  }
21359
21383
  function toDotPath(_path) {
21360
21384
  const segs = [];
21361
- const path37 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
21362
- for (const seg of path37) {
21385
+ const path38 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
21386
+ for (const seg of path38) {
21363
21387
  if (typeof seg === "number")
21364
21388
  segs.push(`[${seg}]`);
21365
21389
  else if (typeof seg === "symbol")
@@ -34789,13 +34813,13 @@ function resolveRef2(ref, ctx) {
34789
34813
  if (!ref.startsWith("#")) {
34790
34814
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
34791
34815
  }
34792
- const path37 = ref.slice(1).split("/").filter(Boolean);
34793
- if (path37.length === 0) {
34816
+ const path38 = ref.slice(1).split("/").filter(Boolean);
34817
+ if (path38.length === 0) {
34794
34818
  return ctx.rootSchema;
34795
34819
  }
34796
34820
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
34797
- if (path37[0] === defsKey) {
34798
- const key = path37[1];
34821
+ if (path38[0] === defsKey) {
34822
+ const key = path38[1];
34799
34823
  if (!key || !ctx.defs[key]) {
34800
34824
  throw new Error(`Reference not found: ${ref}`);
34801
34825
  }
@@ -35795,7 +35819,7 @@ var init_local_target_mutation_runner = __esm({
35795
35819
  });
35796
35820
 
35797
35821
  // ../packages/core/dist/service/project-resource-key.js
35798
- import path24 from "node:path";
35822
+ import path25 from "node:path";
35799
35823
  function deriveProjectResourceKey({ resourceKey, label, directoryPath }) {
35800
35824
  const explicit = resourceKey?.trim();
35801
35825
  if (explicit)
@@ -35803,7 +35827,7 @@ function deriveProjectResourceKey({ resourceKey, label, directoryPath }) {
35803
35827
  const labelKey = label?.trim();
35804
35828
  if (labelKey)
35805
35829
  return slugify(labelKey);
35806
- return slugify(path24.basename(path24.resolve(directoryPath)));
35830
+ return slugify(path25.basename(path25.resolve(directoryPath)));
35807
35831
  }
35808
35832
  var init_project_resource_key = __esm({
35809
35833
  "../packages/core/dist/service/project-resource-key.js"() {
@@ -35813,7 +35837,7 @@ var init_project_resource_key = __esm({
35813
35837
  });
35814
35838
 
35815
35839
  // src/branch-planning.ts
35816
- import path25 from "node:path";
35840
+ import path26 from "node:path";
35817
35841
  function stripCombiningMarks(value) {
35818
35842
  return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
35819
35843
  }
@@ -35846,7 +35870,7 @@ function missionWorktreePath({
35846
35870
  branch
35847
35871
  }) {
35848
35872
  const key = resourceKey.trim() || "project";
35849
- return path25.join(worktreeRoot, projectSlug || "project", key, branchLeaf(branch));
35873
+ return path26.join(worktreeRoot, projectSlug || "project", key, branchLeaf(branch));
35850
35874
  }
35851
35875
  function normalizeRemoteRef(ref) {
35852
35876
  return ref.replace(/^origin\//, "").replace(/^refs\/heads\//, "").replace(/^refs\/remotes\/origin\//, "");
@@ -35962,7 +35986,7 @@ var init_branch_planning = __esm({
35962
35986
  // src/branch-preparation.ts
35963
35987
  import { execFileSync as execFileSync6 } from "node:child_process";
35964
35988
  import { existsSync as existsSync25, mkdirSync as mkdirSync11, statSync as statSync5 } from "node:fs";
35965
- import path26 from "node:path";
35989
+ import path27 from "node:path";
35966
35990
  function runGit3(cwd, args, options = {}) {
35967
35991
  try {
35968
35992
  return execFileSync6("git", args, {
@@ -35983,7 +36007,7 @@ function lines(value) {
35983
36007
  function resolveGitRoot2(workingDirectory) {
35984
36008
  const root = runGit3(workingDirectory, ["rev-parse", "--show-toplevel"]);
35985
36009
  if (!root) throw new Error(`${workingDirectory} is not inside a git repository.`);
35986
- return path26.resolve(root);
36010
+ return path27.resolve(root);
35987
36011
  }
35988
36012
  function repoDefaultBranch(gitRoot) {
35989
36013
  const symbolic = runGit3(gitRoot, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], {
@@ -36143,7 +36167,7 @@ function ensureBranchRef(gitRoot, decision) {
36143
36167
  }
36144
36168
  function ensureWorktree(gitRoot, decision) {
36145
36169
  ensureBranchRef(gitRoot, decision);
36146
- mkdirSync11(path26.dirname(decision.worktreePath), { recursive: true });
36170
+ mkdirSync11(path27.dirname(decision.worktreePath), { recursive: true });
36147
36171
  if (existsSync25(decision.worktreePath)) {
36148
36172
  if (!statSync5(decision.worktreePath).isDirectory()) {
36149
36173
  throw new Error(`Worktree path exists and is not a directory: ${decision.worktreePath}`);
@@ -36342,7 +36366,7 @@ var init_branch_preparation = __esm({
36342
36366
  });
36343
36367
 
36344
36368
  // src/capture-change.ts
36345
- import path27 from "node:path";
36369
+ import path28 from "node:path";
36346
36370
  function exactProjectDirectory(value) {
36347
36371
  if (typeof value !== "string") return null;
36348
36372
  if (!value || value.length > 4096 || hasControlCharacters(value)) return null;
@@ -36355,9 +36379,9 @@ function resolveHookWorkingDirectory({
36355
36379
  }) {
36356
36380
  for (const payloadPath of projectRootPaths ?? []) {
36357
36381
  const projectDirectory = exactProjectDirectory(readPath2(payload, payloadPath));
36358
- if (projectDirectory) return path27.resolve(projectDirectory);
36382
+ if (projectDirectory) return path28.resolve(projectDirectory);
36359
36383
  }
36360
- return path27.resolve(fallbackCwd);
36384
+ return path28.resolve(fallbackCwd);
36361
36385
  }
36362
36386
  function withProjectRootFallback({
36363
36387
  payload,
@@ -36378,8 +36402,8 @@ function collectAbsolutePathHints(payload) {
36378
36402
  const visit = (value, depth) => {
36379
36403
  if (hints.length >= MAX_PATH_HINTS || depth > 4) return;
36380
36404
  if (typeof value === "string") {
36381
- if (path27.isAbsolute(value) && value.length <= 4096 && !hasControlCharacters(value)) {
36382
- hints.push(path27.resolve(value));
36405
+ if (path28.isAbsolute(value) && value.length <= 4096 && !hasControlCharacters(value)) {
36406
+ hints.push(path28.resolve(value));
36383
36407
  }
36384
36408
  return;
36385
36409
  }
@@ -36503,7 +36527,7 @@ var init_capture_change = __esm({
36503
36527
  });
36504
36528
 
36505
36529
  // src/discover-project-local.ts
36506
- import path28 from "node:path";
36530
+ import path29 from "node:path";
36507
36531
  async function resolvePreferredExecutionTargetId({
36508
36532
  backend,
36509
36533
  workspaceId
@@ -36522,14 +36546,14 @@ function discoverProjectJsonFromFilesystem({
36522
36546
  workingDirectory,
36523
36547
  preferredExecutionTargetId
36524
36548
  }) {
36525
- let current = path28.resolve(workingDirectory);
36549
+ let current = path29.resolve(workingDirectory);
36526
36550
  while (true) {
36527
- const projectJsonPath = path28.join(current, ".overlord", "project.json");
36551
+ const projectJsonPath = path29.join(current, ".overlord", "project.json");
36528
36552
  const links = readProjectJsonLinks(projectJsonPath, { preferredExecutionTargetId });
36529
36553
  if (links.length > 0) {
36530
36554
  return { resourcePath: current, links };
36531
36555
  }
36532
- const parent = path28.dirname(current);
36556
+ const parent = path29.dirname(current);
36533
36557
  if (parent === current) break;
36534
36558
  current = parent;
36535
36559
  }
@@ -36656,7 +36680,7 @@ async function discoverProjectOnClient({
36656
36680
  const resolvedLocal = localWithTarget ?? local;
36657
36681
  if (!resolvedLocal) {
36658
36682
  throw new CliError({
36659
- message: `No linked Overlord project found for ${path28.resolve(workingDirectory)}. Run \`ovld add-cwd\` or \`ovld create-project\`.`
36683
+ message: `No linked Overlord project found for ${path29.resolve(workingDirectory)}. Run \`ovld add-cwd\` or \`ovld create-project\`.`
36660
36684
  });
36661
36685
  }
36662
36686
  const selectedLink = selectPrimaryProjectLink(resolvedLocal.links);
@@ -36676,7 +36700,7 @@ async function discoverProjectOnClient({
36676
36700
  }
36677
36701
  if (!chosenProject || !chosenLink) {
36678
36702
  throw new CliError({
36679
- message: `No linked Overlord project found for ${path28.resolve(workingDirectory)}. Run \`ovld add-cwd\` or \`ovld create-project\`.`
36703
+ message: `No linked Overlord project found for ${path29.resolve(workingDirectory)}. Run \`ovld add-cwd\` or \`ovld create-project\`.`
36680
36704
  });
36681
36705
  }
36682
36706
  const accessible = resolvedLocal.links.length > 1 ? await listAccessibleProjects({ backend }) : [chosenProject];
@@ -36705,9 +36729,9 @@ var init_discover_project_local = __esm({
36705
36729
  });
36706
36730
 
36707
36731
  // src/latch-discovery.ts
36708
- import path29 from "node:path";
36732
+ import path30 from "node:path";
36709
36733
  function latchDiscoveryCachePath(dataDir = resolveGlobalDataDir()) {
36710
- return path29.join(dataDir, LATCH_DISCOVERY_CACHE_FILENAME);
36734
+ return path30.join(dataDir, LATCH_DISCOVERY_CACHE_FILENAME);
36711
36735
  }
36712
36736
  function discoverLatchOnThisDevice({
36713
36737
  executionTargetId,
@@ -36752,6 +36776,7 @@ function spawnLatchJson({
36752
36776
  function createLatchSession({
36753
36777
  executable = DEFAULT_LATCH_EXECUTABLE,
36754
36778
  commandString,
36779
+ agentLaunch,
36755
36780
  cwd,
36756
36781
  env,
36757
36782
  title,
@@ -36763,6 +36788,7 @@ function createLatchSession({
36763
36788
  }) {
36764
36789
  const manifest = buildLatchCreateManifest({
36765
36790
  commandString,
36791
+ agentLaunch,
36766
36792
  shell,
36767
36793
  cwd,
36768
36794
  env,
@@ -36870,10 +36896,10 @@ function primaryResourcePath(projectResources) {
36870
36896
  for (const entry of projectResources) {
36871
36897
  if (!entry || typeof entry !== "object") continue;
36872
36898
  const record2 = entry;
36873
- const path37 = typeof record2.path === "string" ? record2.path.trim() : "";
36874
- if (!path37) continue;
36875
- if (record2.isPrimary === true) return path37;
36876
- if (record2.isCurrent === true && !currentPath) currentPath = path37;
36899
+ const path38 = typeof record2.path === "string" ? record2.path.trim() : "";
36900
+ if (!path38) continue;
36901
+ if (record2.isPrimary === true) return path38;
36902
+ if (record2.isCurrent === true && !currentPath) currentPath = path38;
36877
36903
  }
36878
36904
  return currentPath;
36879
36905
  }
@@ -37250,7 +37276,7 @@ var init_terminal_launcher = __esm({
37250
37276
  // src/launch.ts
37251
37277
  import { spawnSync as spawnSync3 } from "node:child_process";
37252
37278
  import { chmodSync as chmodSync5, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "node:fs";
37253
- import path30 from "node:path";
37279
+ import path31 from "node:path";
37254
37280
  function interactiveLoginShellInvocation(command, configuredShell = process.env.SHELL) {
37255
37281
  const shell = configuredShell?.trim() || "/bin/bash";
37256
37282
  return { command: shell, args: ["-ilc", command] };
@@ -37487,7 +37513,7 @@ function launchScriptPath({
37487
37513
  executionRequestId
37488
37514
  }) {
37489
37515
  const requestPart = executionRequestId ? safeLaunchScriptPart(executionRequestId) : `${process.pid}`;
37490
- return path30.join(tmpDir, `launch-${safeLaunchScriptPart(displayId)}-${requestPart}.sh`);
37516
+ return path31.join(tmpDir, `launch-${safeLaunchScriptPart(displayId)}-${requestPart}.sh`);
37491
37517
  }
37492
37518
  async function buildLaunchPlan({
37493
37519
  runtime,
@@ -37501,8 +37527,8 @@ async function buildLaunchPlan({
37501
37527
  pruneStaleProjectTmp({ workingDirectory: options.workingDirectory, create: true });
37502
37528
  const tmpDir = ensureProjectTmpDir(options.workingDirectory);
37503
37529
  const contextFileStem = context.objectiveDisplayId ? `objective-${context.objectiveDisplayId.replace(/[^a-zA-Z0-9_-]/g, "-")}` : `mission-${context.displayId.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
37504
- const contextFile = path30.join(tmpDir, `${contextFileStem}.md`);
37505
- const sessionScratchDir = path30.join(
37530
+ const contextFile = path31.join(tmpDir, `${contextFileStem}.md`);
37531
+ const sessionScratchDir = path31.join(
37506
37532
  projectTmpSessionsDir(options.workingDirectory),
37507
37533
  sessionScratchName({
37508
37534
  missionDisplayId: context.displayId,
@@ -37607,6 +37633,7 @@ async function buildLaunchPlan({
37607
37633
  execution,
37608
37634
  env: exportedEnv,
37609
37635
  latchCommandString,
37636
+ latchPreLaunchCommands: preLaunchCommands,
37610
37637
  launchSession: options.launchSession ?? null,
37611
37638
  missionTitle: options.missionTitle ?? context.title,
37612
37639
  missionDisplayId: options.missionDisplayId ?? context.displayId,
@@ -37634,6 +37661,7 @@ async function launchAgent({
37634
37661
  let useLatch = false;
37635
37662
  let resolvedLatchExecutable = executable;
37636
37663
  let latchProductVersion = null;
37664
+ let latchExtensions = [];
37637
37665
  const existingProviderSession = providerKind === "latch" ? existingLatchProviderSession({
37638
37666
  latchSessionId: process.env.LATCH_SESSION_ID,
37639
37667
  executionTargetId: options.executionTargetId
@@ -37678,6 +37706,7 @@ async function launchAgent({
37678
37706
  if (useLatch && discovery.state === "found") {
37679
37707
  resolvedLatchExecutable = discovery.resolvedPath;
37680
37708
  latchProductVersion = discovery.productVersion;
37709
+ latchExtensions = discovery.capabilities.extensions;
37681
37710
  }
37682
37711
  if (!useLatch) {
37683
37712
  providerFallbackWarning = discovery.state === "not_installed" ? `Latch is not installed on this execution target (${discovery.installCommand}); falling back to direct launch.` : discovery.state === "incompatible" ? `Latch is incompatible (${discovery.missingCapability}: ${discovery.detail}); falling back to direct launch.` : "Latch is unavailable; falling back to direct launch.";
@@ -37685,6 +37714,15 @@ async function launchAgent({
37685
37714
  }
37686
37715
  }
37687
37716
  if (useLatch && plan.latchCommandString) {
37717
+ const shell = process.env.SHELL?.trim() || "/bin/bash";
37718
+ const agentLaunch = selectLatchAgentLaunch({
37719
+ agent: options.agent,
37720
+ argv: [plan.command, ...plan.args],
37721
+ preCommand: options.preCommand,
37722
+ preLaunchCommands: plan.latchPreLaunchCommands,
37723
+ extensions: latchExtensions,
37724
+ shell
37725
+ });
37688
37726
  const latchDisplay = formatObjectiveLatchDisplay({
37689
37727
  objectiveDisplayId: plan.objectiveDisplayId ?? plan.missionDisplayId ?? options.missionId,
37690
37728
  objectiveTitle: plan.objectiveTitle ?? plan.missionTitle
@@ -37692,6 +37730,8 @@ async function launchAgent({
37692
37730
  const created = createLatchSession({
37693
37731
  executable: resolvedLatchExecutable,
37694
37732
  commandString: plan.latchCommandString,
37733
+ agentLaunch,
37734
+ shell,
37695
37735
  cwd: options.workingDirectory,
37696
37736
  env: plan.env,
37697
37737
  title: latchDisplay.title,
@@ -37775,7 +37815,7 @@ var init_launch = __esm({
37775
37815
 
37776
37816
  // src/launch-bootstrap.ts
37777
37817
  import { existsSync as existsSync26, readdirSync as readdirSync5, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
37778
- import path31 from "node:path";
37818
+ import path32 from "node:path";
37779
37819
  function firstCapture(match) {
37780
37820
  if (!match) return null;
37781
37821
  const value = match[1] ?? match[2] ?? match[3] ?? null;
@@ -37803,7 +37843,7 @@ function recoverLaunchBootstrapFromProjectTmp({
37803
37843
  try {
37804
37844
  for (const name of readdirSync5(tmpDir)) {
37805
37845
  if (!name.startsWith(prefix) || !name.endsWith(".sh")) continue;
37806
- const filePath = path31.join(tmpDir, name);
37846
+ const filePath = path32.join(tmpDir, name);
37807
37847
  try {
37808
37848
  const mtimeMs = statSync6(filePath).mtimeMs;
37809
37849
  if (!newest || mtimeMs > newest.mtimeMs) {
@@ -37842,7 +37882,7 @@ var init_launch_bootstrap = __esm({
37842
37882
 
37843
37883
  // src/org-setup.ts
37844
37884
  import { readFileSync as readFileSync18 } from "node:fs";
37845
- import path32 from "node:path";
37885
+ import path33 from "node:path";
37846
37886
  import { createInterface as createInterface3 } from "node:readline";
37847
37887
  function suggestSlug(name) {
37848
37888
  const cleaned = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -37921,12 +37961,12 @@ async function runOrgSetupCommand({
37921
37961
  let logoWarning = null;
37922
37962
  if (logoPath) {
37923
37963
  try {
37924
- const resolvedPath = path32.resolve(logoPath);
37964
+ const resolvedPath = path33.resolve(logoPath);
37925
37965
  const bytes = readFileSync18(resolvedPath);
37926
37966
  const stored = await runtime.backend.postRaw({
37927
37967
  path: "/api/uploads/organization-images",
37928
37968
  body: bytes,
37929
- filename: path32.basename(resolvedPath)
37969
+ filename: path33.basename(resolvedPath)
37930
37970
  });
37931
37971
  await runtime.backend.patch({
37932
37972
  path: `/api/organizations/${encodeURIComponent(organization.id)}`,
@@ -38951,13 +38991,13 @@ var init_resource_observations = __esm({
38951
38991
  import { randomUUID as randomUUID3 } from "node:crypto";
38952
38992
  import { existsSync as existsSync27, mkdirSync as mkdirSync13, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
38953
38993
  import { hostname as hostname6 } from "node:os";
38954
- import path33 from "node:path";
38994
+ import path34 from "node:path";
38955
38995
  function envValue(name) {
38956
38996
  const value = process.env[name]?.trim();
38957
38997
  return value && value.length > 0 ? value : null;
38958
38998
  }
38959
38999
  function runnerInstanceStatePath(dataDir = resolveGlobalDataDir()) {
38960
- return path33.join(dataDir, RUNNER_INSTANCE_STATE_FILENAME);
39000
+ return path34.join(dataDir, RUNNER_INSTANCE_STATE_FILENAME);
38961
39001
  }
38962
39002
  function resolveRunnerInstanceId(dataDir = resolveGlobalDataDir()) {
38963
39003
  const pinned = envValue("OVERLORD_RUNNER_INSTANCE_ID");
@@ -38974,7 +39014,7 @@ function resolveRunnerInstanceId(dataDir = resolveGlobalDataDir()) {
38974
39014
  }
38975
39015
  const runnerInstanceId = randomUUID3();
38976
39016
  try {
38977
- mkdirSync13(path33.dirname(statePath), { recursive: true });
39017
+ mkdirSync13(path34.dirname(statePath), { recursive: true });
38978
39018
  writeFileSync11(statePath, `${JSON.stringify({ runnerInstanceId }, null, 2)}
38979
39019
  `, { mode: 384 });
38980
39020
  } catch {
@@ -39027,14 +39067,14 @@ import {
39027
39067
  writeFileSync as writeFileSync12
39028
39068
  } from "node:fs";
39029
39069
  import os6 from "node:os";
39030
- import path34 from "node:path";
39070
+ import path35 from "node:path";
39031
39071
  import { promisify } from "node:util";
39032
39072
  function writeServiceFile(filePath, contents) {
39033
39073
  writeFileSync12(filePath, contents, { mode: 384 });
39034
39074
  chmodSync6(filePath, 384);
39035
39075
  }
39036
39076
  function resolveRunnerEntryScript(argv = process.argv) {
39037
- return argv[1] ? path34.resolve(argv[1]) : null;
39077
+ return argv[1] ? path35.resolve(argv[1]) : null;
39038
39078
  }
39039
39079
  function readRunnerExecutableFileIdentity(filePath, stat = statSync7) {
39040
39080
  try {
@@ -39081,7 +39121,7 @@ function emptyRunnerServiceState() {
39081
39121
  };
39082
39122
  }
39083
39123
  function runnerServiceStatePath(dataDir = resolveGlobalDataDir()) {
39084
- return path34.join(dataDir, RUNNER_SERVICE_STATE_FILENAME);
39124
+ return path35.join(dataDir, RUNNER_SERVICE_STATE_FILENAME);
39085
39125
  }
39086
39126
  function readRunnerServiceState(dataDir = resolveGlobalDataDir()) {
39087
39127
  const filePath = runnerServiceStatePath(dataDir);
@@ -39115,11 +39155,11 @@ function resolveOverlordAppInvocation({
39115
39155
  if (platform2 !== "darwin") return null;
39116
39156
  const appDirs = [
39117
39157
  "/Applications/Overlord.app",
39118
- path34.join(homedir2, "Applications", "Overlord.app")
39158
+ path35.join(homedir2, "Applications", "Overlord.app")
39119
39159
  ];
39120
39160
  for (const appDir of appDirs) {
39121
- const program = path34.join(appDir, "Contents", "MacOS", "Overlord");
39122
- const script = path34.join(appDir, "Contents", "Resources", "cli", "bin", "ovld.mjs");
39161
+ const program = path35.join(appDir, "Contents", "MacOS", "Overlord");
39162
+ const script = path35.join(appDir, "Contents", "Resources", "cli", "bin", "ovld.mjs");
39123
39163
  if (exists(program) && exists(script)) {
39124
39164
  return { program, args: [script, "runner", "supervise"], runAsElectronNode: true };
39125
39165
  }
@@ -39131,7 +39171,7 @@ function resolveOvldInvocation(argv = process.argv, execPath = process.execPath)
39131
39171
  if (override) {
39132
39172
  return { program: override, args: ["runner", "supervise"] };
39133
39173
  }
39134
- const scriptPath = argv[1] ? path34.resolve(argv[1]) : "";
39174
+ const scriptPath = argv[1] ? path35.resolve(argv[1]) : "";
39135
39175
  if (process.env.ELECTRON_RUN_AS_NODE) {
39136
39176
  return scriptPath ? { program: execPath, args: [scriptPath, "runner", "supervise"], runAsElectronNode: true } : { program: execPath, args: ["runner", "supervise"], runAsElectronNode: true };
39137
39177
  }
@@ -39145,7 +39185,7 @@ function resolveOvldInvocation(argv = process.argv, execPath = process.execPath)
39145
39185
  function composeRunnerServicePath({
39146
39186
  homeDir = os6.homedir()
39147
39187
  } = {}) {
39148
- const localBin = path34.join(homeDir, ".local", "bin");
39188
+ const localBin = path35.join(homeDir, ".local", "bin");
39149
39189
  const dirs = [...RUNNER_SERVICE_PATH_PREFIX_DIRS, localBin, ...RUNNER_SERVICE_SYSTEM_PATH_DIRS];
39150
39190
  return [...new Set(dirs)].join(":");
39151
39191
  }
@@ -39173,7 +39213,7 @@ function runnerServiceReinstallHint({
39173
39213
  installed,
39174
39214
  publisher,
39175
39215
  processType,
39176
- path: path37
39216
+ path: path38
39177
39217
  }) {
39178
39218
  if (!installed) return null;
39179
39219
  const hints = [];
@@ -39187,7 +39227,7 @@ function runnerServiceReinstallHint({
39187
39227
  `This LaunchAgent is ProcessType=${processType}. App auto-update respawns the supervisor but does not rewrite ProcessType, so Apple Events to Terminal/iTerm stay App-Napped. Reinstall with \`ovld runner service install\` (or Desktop \u2192 Reinstall service) to switch to ${LAUNCHD_PROCESS_TYPE}.`
39188
39228
  );
39189
39229
  }
39190
- if (path37 !== void 0 && path37 !== composeRunnerServicePath()) {
39230
+ if (path38 !== void 0 && path38 !== composeRunnerServicePath()) {
39191
39231
  hints.push(
39192
39232
  "This LaunchAgent PATH is not the deterministic prefix (`/opt/homebrew/bin:/usr/local/bin:$HOME/.local/bin` plus system dirs). App auto-update respawns the supervisor but does not rewrite PATH, so Latch/`open`/agent binaries spawned by the service may be missing. Reinstall with `ovld runner service install` (or Desktop \u2192 Reinstall service) to apply it."
39193
39233
  );
@@ -39205,7 +39245,7 @@ function buildRunnerServiceEnv({
39205
39245
  };
39206
39246
  if (!isLoopbackBackendUrl(backendUrl)) env.OVERLORD_BACKEND_URL = backendUrl;
39207
39247
  const home = overlordHome?.trim() || process.env.OVLD_HOME?.trim();
39208
- if (home) env.OVLD_HOME = path34.resolve(home);
39248
+ if (home) env.OVLD_HOME = path35.resolve(home);
39209
39249
  const token = process.env.OVERLORD_USER_TOKEN?.trim() || process.env.OVLD_USER_TOKEN?.trim();
39210
39250
  if (token) env.OVERLORD_USER_TOKEN = token;
39211
39251
  if (runAsElectronNode || process.env.ELECTRON_RUN_AS_NODE) env.ELECTRON_RUN_AS_NODE = "1";
@@ -39244,9 +39284,9 @@ ${envEntries}
39244
39284
  <key>KeepAlive</key>
39245
39285
  <true/>
39246
39286
  <key>StandardOutPath</key>
39247
- <string>${xmlEscape(path34.join(logDir, "runner-service.out.log"))}</string>
39287
+ <string>${xmlEscape(path35.join(logDir, "runner-service.out.log"))}</string>
39248
39288
  <key>StandardErrorPath</key>
39249
- <string>${xmlEscape(path34.join(logDir, "runner-service.err.log"))}</string>
39289
+ <string>${xmlEscape(path35.join(logDir, "runner-service.err.log"))}</string>
39250
39290
  <key>ProcessType</key>
39251
39291
  <string>${LAUNCHD_PROCESS_TYPE}</string>
39252
39292
  </dict>
@@ -39277,12 +39317,12 @@ WantedBy=default.target
39277
39317
  `;
39278
39318
  }
39279
39319
  function launchAgentsDir() {
39280
- return path34.join(os6.homedir(), "Library", "LaunchAgents");
39320
+ return path35.join(os6.homedir(), "Library", "LaunchAgents");
39281
39321
  }
39282
39322
  function systemdUserDir() {
39283
39323
  const xdg = process.env.XDG_CONFIG_HOME?.trim();
39284
- const base = xdg ? path34.resolve(xdg) : path34.join(os6.homedir(), ".config");
39285
- return path34.join(base, "systemd", "user");
39324
+ const base = xdg ? path35.resolve(xdg) : path35.join(os6.homedir(), ".config");
39325
+ return path35.join(base, "systemd", "user");
39286
39326
  }
39287
39327
  async function runCommand(program, args) {
39288
39328
  const { stdout } = await execFileAsync(program, args);
@@ -39334,7 +39374,7 @@ var init_runner_service = __esm({
39334
39374
  this.exec = exec ?? ((args) => runCommand("launchctl", args));
39335
39375
  }
39336
39376
  unitPath() {
39337
- return path34.join(launchAgentsDir(), `${LAUNCHD_LABEL}.plist`);
39377
+ return path35.join(launchAgentsDir(), `${LAUNCHD_LABEL}.plist`);
39338
39378
  }
39339
39379
  uid() {
39340
39380
  return process.getuid?.() ?? "";
@@ -39362,12 +39402,12 @@ var init_runner_service = __esm({
39362
39402
  label: LAUNCHD_LABEL,
39363
39403
  invocation: opts.invocation,
39364
39404
  env: opts.env,
39365
- logDir: path34.join(resolveGlobalDataDir(), "logs")
39405
+ logDir: path35.join(resolveGlobalDataDir(), "logs")
39366
39406
  });
39367
39407
  }
39368
39408
  async install(opts) {
39369
39409
  mkdirSync14(launchAgentsDir(), { recursive: true });
39370
- mkdirSync14(path34.join(resolveGlobalDataDir(), "logs"), { recursive: true });
39410
+ mkdirSync14(path35.join(resolveGlobalDataDir(), "logs"), { recursive: true });
39371
39411
  await this.runSteps(planLaunchdUnloadCommands({ uid: this.uid() }));
39372
39412
  writeServiceFile(this.unitPath(), this.render(opts));
39373
39413
  if (opts.autoStart) await this.start();
@@ -39408,7 +39448,7 @@ var init_runner_service = __esm({
39408
39448
  kind = "systemd";
39409
39449
  identifier = `${SYSTEMD_UNIT_NAME}.service`;
39410
39450
  unitPath() {
39411
- return path34.join(systemdUserDir(), `${SYSTEMD_UNIT_NAME}.service`);
39451
+ return path35.join(systemdUserDir(), `${SYSTEMD_UNIT_NAME}.service`);
39412
39452
  }
39413
39453
  render(opts) {
39414
39454
  return renderSystemdUnit(opts);
@@ -39510,7 +39550,7 @@ var init_select_prompt = __esm({
39510
39550
  // src/session-key.ts
39511
39551
  import { createHash as createHash10 } from "node:crypto";
39512
39552
  import { existsSync as existsSync29, opendirSync, rmSync as rmSync6 } from "node:fs";
39513
- import path35 from "node:path";
39553
+ import path36 from "node:path";
39514
39554
  function sessionKeyCachePath({
39515
39555
  missionId,
39516
39556
  workingDirectory,
@@ -39519,7 +39559,7 @@ function sessionKeyCachePath({
39519
39559
  const resolved = canonicalDirectory(workingDirectory);
39520
39560
  const material = `${resolved}\0${missionId}\0${objectiveId.trim()}`;
39521
39561
  const key = createHash10("sha256").update(material).digest("hex");
39522
- return path35.join(resolveGlobalDataDir(), "protocol-session-keys", key);
39562
+ return path36.join(resolveGlobalDataDir(), "protocol-session-keys", key);
39523
39563
  }
39524
39564
  function readSessionKeyFile(filePath) {
39525
39565
  try {
@@ -39544,7 +39584,7 @@ function writeSessionKeyFile({
39544
39584
  filePath,
39545
39585
  sessionKey
39546
39586
  }) {
39547
- ensureOwnerOnlyDirectory(path35.dirname(filePath));
39587
+ ensureOwnerOnlyDirectory(path36.dirname(filePath));
39548
39588
  const contents = JSON.stringify({ sessionKey, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
39549
39589
  if (Buffer.byteLength(contents, "utf8") > MAX_SESSION_KEY_CACHE_FILE_BYTES) return;
39550
39590
  writeOwnerOnlyFileAtomically(filePath, contents);
@@ -39575,7 +39615,7 @@ function clearCachedSessionKey({
39575
39615
  const files = /* @__PURE__ */ new Set();
39576
39616
  const trimmedSessionKey = sessionKey?.trim();
39577
39617
  if (trimmedSessionKey) {
39578
- const cacheDir = path35.join(resolveGlobalDataDir(), "protocol-session-keys");
39618
+ const cacheDir = path36.join(resolveGlobalDataDir(), "protocol-session-keys");
39579
39619
  if (existsSync29(cacheDir)) {
39580
39620
  const directory = opendirSync(cacheDir);
39581
39621
  let scanned = 0;
@@ -39590,7 +39630,7 @@ function clearCachedSessionKey({
39590
39630
  }
39591
39631
  scanned += 1;
39592
39632
  if (!entry.isFile() || !/^[a-f0-9]{64}$/.test(entry.name)) continue;
39593
- const filePath = path35.join(cacheDir, entry.name);
39633
+ const filePath = path36.join(cacheDir, entry.name);
39594
39634
  if (readSessionKeyFile(filePath) === trimmedSessionKey) files.add(filePath);
39595
39635
  }
39596
39636
  } finally {
@@ -39639,7 +39679,7 @@ __export(commands_exports, {
39639
39679
  shouldRefuseInlineRunnerLaunch: () => shouldRefuseInlineRunnerLaunch
39640
39680
  });
39641
39681
  import { readFileSync as readFileSync21 } from "node:fs";
39642
- import path36 from "node:path";
39682
+ import path37 from "node:path";
39643
39683
  function resourceAccessModeBody(value) {
39644
39684
  if (typeof value !== "string") return {};
39645
39685
  const normalized = value.trim().toLowerCase();
@@ -39731,7 +39771,7 @@ function deliveredBriefingPath({
39731
39771
  const displayId = objectiveAliases.find((alias) => OBJECTIVE_DISPLAY_ID_RE.test(alias.trim()));
39732
39772
  const stem = displayId ? `objective-${safeTmpNamePart(displayId.trim())}` : missionId.includes(":") && !missionId.includes(".") ? `mission-${safeTmpNamePart(missionId.trim())}` : null;
39733
39773
  if (!stem) return null;
39734
- const candidate = path36.join(projectTmpDir(workingDirectory), `${stem}.md`);
39774
+ const candidate = path37.join(projectTmpDir(workingDirectory), `${stem}.md`);
39735
39775
  return isSessionScratchDir(workingDirectory, candidate) ? null : candidate;
39736
39776
  }
39737
39777
  async function syncObjectiveLedger({
@@ -40473,7 +40513,7 @@ async function runManagementCommand({
40473
40513
  }
40474
40514
  case "add-cwd": {
40475
40515
  const directory = flagValue(parsed.flags, "--directory") ?? process.cwd();
40476
- const existingLinks = readProjectJsonLinks(path36.join(directory, ".overlord", "project.json"));
40516
+ const existingLinks = readProjectJsonLinks(path37.join(directory, ".overlord", "project.json"));
40477
40517
  let projectId = flagValue(parsed.flags, "--project-id");
40478
40518
  if (!projectId) {
40479
40519
  const allProjects = await listAccessibleProjects({ backend: runtime.backend });
@@ -40950,13 +40990,13 @@ async function runManagementCommand({
40950
40990
  rationales: `/api/missions/${encodeURIComponent(missionId)}/file-changes`,
40951
40991
  deliveries: `/api/missions/${encodeURIComponent(missionId)}/deliveries`
40952
40992
  };
40953
- const path37 = sub ? pathBySub[sub] : void 0;
40954
- if (!path37) {
40993
+ const path38 = sub ? pathBySub[sub] : void 0;
40994
+ if (!path38) {
40955
40995
  throw new CliError({
40956
40996
  message: "Usage: ovld mission context|events|deliveries|artifacts|rationales <missionId> [--json]"
40957
40997
  });
40958
40998
  }
40959
- const result = await runtime.backend.get(path37);
40999
+ const result = await runtime.backend.get(path38);
40960
41000
  if (json2 || sub === "context") printJson(result);
40961
41001
  else {
40962
41002
  const items = missionEvidenceItems(result);