@linzumi/cli 0.0.73-beta → 0.0.74-beta

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +961 -330
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -140,6 +140,7 @@ function parseKandanChatEvent(value) {
140
140
  actorSlug: stringValue(actor?.slug),
141
141
  actorUserId: integerValue(value.actor_user_id),
142
142
  threadId: stringValue(payload.thread_id),
143
+ threadTitle: kandanThreadTitle(value, payload),
143
144
  replyToSeq: integerValue(payload.reply_to_seq),
144
145
  localRunnerEventType: localRunnerEventType(payload),
145
146
  body: stringValue(value.body) ?? stringValue(value.text) ?? stringValue(payload.body) ?? stringValue(payload.text) ?? "",
@@ -148,6 +149,11 @@ function parseKandanChatEvent(value) {
148
149
  )
149
150
  };
150
151
  }
152
+ function kandanThreadTitle(value, payload) {
153
+ const payloadThread = objectValue(payload.thread);
154
+ const eventThread = objectValue(value.thread);
155
+ return stringValue(payload.thread_title) ?? stringValue(payload.threadTitle) ?? stringValue(payload.title) ?? stringValue(payloadThread?.thread_title) ?? stringValue(payloadThread?.threadTitle) ?? stringValue(payloadThread?.title) ?? stringValue(value.thread_title) ?? stringValue(value.threadTitle) ?? stringValue(value.title) ?? stringValue(eventThread?.thread_title) ?? stringValue(eventThread?.threadTitle) ?? stringValue(eventThread?.title);
156
+ }
151
157
  function parseKandanChatAttachments(attachments) {
152
158
  return attachments.flatMap((attachment) => {
153
159
  const value = objectValue(attachment);
@@ -797,6 +803,130 @@ var init_commanderAttachments = __esm({
797
803
  }
798
804
  });
799
805
 
806
+ // src/codexNotificationDiagnostics.ts
807
+ function codexNotificationDiagnosticDetails(method, params) {
808
+ switch (method) {
809
+ case "warning":
810
+ case "error":
811
+ return {
812
+ diagnostic_summary: codexNotificationDiagnosticSummary(method, params) ?? `${method}: seen (no details)`,
813
+ diagnostic_payload: redactedJsonValue(params, 0),
814
+ diagnostic_payload_keys: Object.keys(params).sort()
815
+ };
816
+ default:
817
+ return {};
818
+ }
819
+ }
820
+ function codexNotificationDiagnosticSummary(method, params) {
821
+ const error = objectValue2(params.error);
822
+ const item = objectValue2(params.item);
823
+ const code = stringValue2(params.code) ?? numberStringValue(params.code) ?? stringValue2(error?.code) ?? numberStringValue(error?.code) ?? stringValue2(params.status) ?? numberStringValue(params.status);
824
+ const message = stringValue2(params.message) ?? stringValue2(params.detail) ?? stringValue2(params.reason) ?? stringValue2(error?.message) ?? stringValue2(error?.detail) ?? stringValue2(error?.reason);
825
+ const itemType = stringValue2(item?.type);
826
+ const redactedCode = code === void 0 ? void 0 : redactedDiagnosticText(code);
827
+ const prefix = redactedCode === void 0 ? method : `${method} ${redactedCode}`;
828
+ const detail = message === void 0 ? itemType === void 0 ? void 0 : `item.type=${itemType}` : redactedDiagnosticText(message);
829
+ return detail === void 0 ? void 0 : `${prefix}: ${detail}`;
830
+ }
831
+ function redactedJsonValue(value, depth) {
832
+ if (value === void 0) {
833
+ return null;
834
+ }
835
+ if (typeof value === "string") {
836
+ const redacted = redactedDiagnosticText(value);
837
+ return redacted.length <= maxDiagnosticStringLength ? redacted : `${redacted.slice(0, maxDiagnosticStringLength)}...`;
838
+ }
839
+ if (value === null || typeof value === "boolean" || typeof value === "number") {
840
+ return value;
841
+ }
842
+ if (depth >= maxDiagnosticDepth) {
843
+ return "[max-depth]";
844
+ }
845
+ if (Array.isArray(value)) {
846
+ return value.map((entry) => redactedJsonValue(entry, depth + 1));
847
+ }
848
+ return Object.fromEntries(
849
+ Object.entries(value).map(([key, entry]) => [
850
+ key,
851
+ sensitiveKey(key) ? redactedValue : redactedJsonValue(entry, depth + 1)
852
+ ])
853
+ );
854
+ }
855
+ function sensitiveKey(key) {
856
+ const normalizedKey = key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
857
+ switch (normalizedKey) {
858
+ case "authorization":
859
+ case "cookie":
860
+ case "cookies":
861
+ case "credential":
862
+ case "credentials":
863
+ case "password":
864
+ case "secret":
865
+ case "token":
866
+ case "access_key":
867
+ case "api_key":
868
+ case "auth_token":
869
+ case "bearer_token":
870
+ case "client_secret":
871
+ case "id_token":
872
+ case "private_key":
873
+ case "proxy_authorization":
874
+ case "refresh_token":
875
+ case "secret_key":
876
+ case "session_token":
877
+ case "set_cookie":
878
+ case "sig":
879
+ case "signature":
880
+ case "signing_key":
881
+ case "x_amz_signature":
882
+ case "x_api_key":
883
+ return true;
884
+ default:
885
+ return normalizedKey.endsWith("_api_key") || normalizedKey.endsWith("_access_key") || normalizedKey.endsWith("_private_key") || normalizedKey.endsWith("_secret_key") || normalizedKey.endsWith("_authorization") || normalizedKey.endsWith("_cookie") || normalizedKey.endsWith("_cookies") || normalizedKey.endsWith("_token") || normalizedKey.endsWith("_secret") || normalizedKey.endsWith("_password") || normalizedKey.endsWith("_signature") || normalizedKey.endsWith("_sig") || normalizedKey.endsWith("_credential") || normalizedKey.endsWith("_credentials");
886
+ }
887
+ }
888
+ function redactedDiagnosticText(value) {
889
+ return value.replace(
890
+ /https?:\/\/\S*(?:token|secret|signature|sig|x-amz-signature|api[_-]?key|access[_-]?key|private[_-]?key|refresh)\S*/gi,
891
+ redactedUrl
892
+ ).replace(
893
+ /(^|[^A-Za-z0-9_-])(["']?)(set-cookie|cookie)\2\s*(:|=)\s*(["']?)[^\r\n"']*\5/gi,
894
+ (_match, prefix, keyQuote, key, separator, valueQuote) => {
895
+ const spacing = separator === ":" && valueQuote === "" ? " " : "";
896
+ return `${prefix}${keyQuote}${key}${keyQuote}${separator}${spacing}${valueQuote}${redactedValue}${valueQuote}`;
897
+ }
898
+ ).replace(
899
+ new RegExp(
900
+ `(^|[^A-Za-z0-9_-])(["']?)(${credentialTextKeyPattern})\\2\\s*(:|=)\\s*(["']?)(?:(?:Bearer|Basic|Digest|Token|ApiKey|OAuth|Negotiate)\\s+)?[^"'\\s,;}&]+\\5`,
901
+ "gi"
902
+ ),
903
+ (_match, prefix, keyQuote, key, separator, valueQuote) => {
904
+ const spacing = separator === ":" && valueQuote === "" ? " " : "";
905
+ return `${prefix}${keyQuote}${key}${keyQuote}${separator}${spacing}${valueQuote}${redactedValue}${valueQuote}`;
906
+ }
907
+ ).replace(/\bBearer\s+[^\s,;]+/gi, "Bearer [redacted]");
908
+ }
909
+ function objectValue2(value) {
910
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
911
+ }
912
+ function stringValue2(value) {
913
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
914
+ }
915
+ function numberStringValue(value) {
916
+ return typeof value === "number" && Number.isFinite(value) ? value.toString() : void 0;
917
+ }
918
+ var redactedValue, redactedUrl, maxDiagnosticDepth, maxDiagnosticStringLength, credentialTextKeyPattern;
919
+ var init_codexNotificationDiagnostics = __esm({
920
+ "src/codexNotificationDiagnostics.ts"() {
921
+ "use strict";
922
+ redactedValue = "[redacted]";
923
+ redactedUrl = "[redacted-url]";
924
+ maxDiagnosticDepth = 12;
925
+ maxDiagnosticStringLength = 8e3;
926
+ credentialTextKeyPattern = "(?:(?:[A-Za-z0-9]+[_-]+)*(?:proxy-authorization|authorization|set-cookie|cookie|x-api-key|api[_-]?key|access[_-]?key|access[_-]?token|private[_-]?key|refresh(?:[_-]?token)?|auth[_-]?token|id[_-]?token|client[_-]?secret|bearer[_-]?token|session[_-]?token|secret[_-]?key|signing[_-]?key|credential|credentials|token|secret|password|signature|sig))";
927
+ }
928
+ });
929
+
800
930
  // src/codexRuntimeOptions.ts
801
931
  function codexThreadRuntimeOverrides(options) {
802
932
  const session = options.channelSession;
@@ -2351,6 +2481,7 @@ function coalesceAssistantDeltas(deltas) {
2351
2481
  return coalesceTextDeltas(deltas, (delta) => ({
2352
2482
  itemKey: delta.itemKey,
2353
2483
  turnId: delta.turnId,
2484
+ sourceMessageSeq: delta.sourceMessageSeq,
2354
2485
  delta: delta.delta
2355
2486
  }));
2356
2487
  }
@@ -3653,8 +3784,15 @@ async function attachChannelSession(args) {
3653
3784
  handleCodexNotification: (method, params) => {
3654
3785
  const turnId = codexNotificationTurnId(params);
3655
3786
  const threadId = codexNotificationThreadId(params);
3656
- const routedTurnId = turnId ?? codexNotificationActiveTurnFallback(method, state, params);
3787
+ const routedTurnId = turnId ?? codexNotificationActiveTurnFallback(method, state, params, threadId);
3657
3788
  if (codexNotificationBelongsToSession(state, threadId, routedTurnId)) {
3789
+ rememberRecentCodexDiagnostic(
3790
+ state,
3791
+ method,
3792
+ params,
3793
+ threadId,
3794
+ routedTurnId
3795
+ );
3658
3796
  const processingReason = processingReasonForCodexNotification(
3659
3797
  method,
3660
3798
  params
@@ -3718,7 +3856,15 @@ async function attachChannelSession(args) {
3718
3856
  break;
3719
3857
  }
3720
3858
  case "item/agentMessage/delta":
3721
- enqueueAssistantDelta(args, state, params, payloadContext);
3859
+ const assistantDeltaSourceSeq = routedTurnId === void 0 ? startingSourceMessageSeq(state) : void 0;
3860
+ enqueueAssistantDelta(
3861
+ args,
3862
+ state,
3863
+ params,
3864
+ payloadContext,
3865
+ routedTurnId,
3866
+ assistantDeltaSourceSeq
3867
+ );
3722
3868
  break;
3723
3869
  case "item/reasoning/textDelta":
3724
3870
  enqueueReasoningDelta(args, state, params, payloadContext);
@@ -3739,16 +3885,26 @@ async function attachChannelSession(args) {
3739
3885
  case "item/completed":
3740
3886
  enqueueWebSearchProgress(args, state, params, payloadContext);
3741
3887
  enqueueCompletedFileChange(args, state, params, payloadContext);
3888
+ const pendingCompletedAssistantSourceSeq = routedTurnId === void 0 ? startingSourceMessageSeq(state) : void 0;
3742
3889
  const completedAssistantItemForward = forwardCompletedAssistantItem(
3743
3890
  args,
3744
3891
  state,
3745
3892
  params,
3746
- payloadContext
3893
+ payloadContext,
3894
+ routedTurnId,
3895
+ pendingCompletedAssistantSourceSeq
3747
3896
  );
3748
- if (turnId !== void 0) {
3897
+ if (routedTurnId !== void 0) {
3749
3898
  rememberPendingCompletedAssistantItemForward(
3750
3899
  state,
3751
- turnId,
3900
+ routedTurnId,
3901
+ completedAssistantItemForward
3902
+ );
3903
+ }
3904
+ if (pendingCompletedAssistantSourceSeq !== void 0) {
3905
+ rememberPendingCompletedAssistantItemSourceForward(
3906
+ state,
3907
+ pendingCompletedAssistantSourceSeq,
3752
3908
  completedAssistantItemForward
3753
3909
  );
3754
3910
  }
@@ -3757,29 +3913,38 @@ async function attachChannelSession(args) {
3757
3913
  message: error instanceof Error ? error.message : String(error)
3758
3914
  });
3759
3915
  }).finally(() => {
3760
- if (turnId !== void 0) {
3916
+ if (routedTurnId !== void 0) {
3761
3917
  forgetPendingCompletedAssistantItemForward(
3762
3918
  state,
3763
- turnId,
3919
+ routedTurnId,
3920
+ completedAssistantItemForward
3921
+ );
3922
+ }
3923
+ if (pendingCompletedAssistantSourceSeq !== void 0) {
3924
+ forgetPendingCompletedAssistantItemSourceForward(
3925
+ state,
3926
+ pendingCompletedAssistantSourceSeq,
3764
3927
  completedAssistantItemForward
3765
3928
  );
3766
3929
  }
3767
3930
  });
3768
- if (turnId !== void 0) {
3931
+ if (routedTurnId !== void 0) {
3769
3932
  const promise = mirrorLocalTuiInputFromNotification(
3770
3933
  args,
3771
3934
  state,
3772
- turnId,
3935
+ routedTurnId,
3773
3936
  params,
3774
3937
  payloadContext
3775
3938
  );
3776
- rememberPendingTuiInputMirror(state, turnId, promise);
3939
+ rememberPendingTuiInputMirror(state, routedTurnId, promise);
3777
3940
  void promise.catch((error) => {
3778
3941
  args.log("codex.tui_input_mirror_failed", {
3779
- turn_id: turnId,
3942
+ turn_id: routedTurnId,
3780
3943
  message: error instanceof Error ? error.message : String(error)
3781
3944
  });
3782
- }).finally(() => forgetPendingTuiInputMirror(state, turnId));
3945
+ }).finally(
3946
+ () => forgetPendingTuiInputMirror(state, routedTurnId)
3947
+ );
3783
3948
  }
3784
3949
  break;
3785
3950
  case "response_item":
@@ -3850,6 +4015,7 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
3850
4015
  return {
3851
4016
  rootSeq,
3852
4017
  kandanThreadId,
4018
+ kandanThreadTitle: void 0,
3853
4019
  codexThreadId,
3854
4020
  turn: { status: "idle" },
3855
4021
  closed: false,
@@ -3860,7 +4026,10 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
3860
4026
  recoveredCompletingTurnIds: /* @__PURE__ */ new Set(),
3861
4027
  retryableTurnIds: /* @__PURE__ */ new Set(),
3862
4028
  completedAssistantItemKeys: /* @__PURE__ */ new Set(),
4029
+ completedAssistantItemTurns: createBoundedCache(maxForwardedTurnIds),
4030
+ completedAssistantItemSourceSeqs: createBoundedCache(maxForwardedTurnIds),
3863
4031
  pendingCompletedAssistantItemForwards: /* @__PURE__ */ new Map(),
4032
+ pendingCompletedAssistantItemSourceForwards: /* @__PURE__ */ new Map(),
3864
4033
  claimedKandanMessageKeys: /* @__PURE__ */ new Set(),
3865
4034
  localTuiTurnIds: /* @__PURE__ */ new Set(),
3866
4035
  mirroredTuiInputProjections: createBoundedCache(maxForwardedTurnIds),
@@ -3872,6 +4041,7 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
3872
4041
  pendingCommandOutputs: createBoundedCache(maxForwardedTurnIds),
3873
4042
  observedCommandOutputCommands: createBoundedCache(maxForwardedTurnIds * 3),
3874
4043
  streamingFileChangeOutputs: createBoundedCache(maxForwardedTurnIds),
4044
+ recentCodexDiagnostics: createBoundedCache(maxForwardedTurnIds * 3),
3875
4045
  assistantDeltaQueue: createStreamDeltaQueue(),
3876
4046
  reasoningDeltaQueue: createStreamDeltaQueue(),
3877
4047
  commandOutputQueue: createStreamDeltaQueue(),
@@ -3974,6 +4144,7 @@ async function bindChannelSession(args, state, payloadContext) {
3974
4144
  state.minSeq = Math.max(state.minSeq, state.rootSeq);
3975
4145
  }
3976
4146
  } else if (state.codexThreadId !== void 0) {
4147
+ await hydrateKandanThreadTitleFromThreadContext(args, state);
3977
4148
  await bindCurrentCodexThread(args, state);
3978
4149
  } else {
3979
4150
  const resolved = await pushOk2(
@@ -3988,6 +4159,10 @@ async function bindChannelSession(args, state, payloadContext) {
3988
4159
  );
3989
4160
  state.rootSeq = integerValue(resolved.seq);
3990
4161
  state.codexThreadId = stringValue(resolved.codex_thread_id);
4162
+ updateKandanThreadTitle(
4163
+ state,
4164
+ kandanThreadTitleFromResolvedMessage(resolved.message)
4165
+ );
3991
4166
  if (state.codexThreadId === void 0) {
3992
4167
  throw new Error(
3993
4168
  "Kandan thread root metadata did not include a Codex thread id"
@@ -4923,6 +5098,46 @@ function runnerConsoleBodyPreview(body) {
4923
5098
  const normalized = body.replace(/\s+/g, " ").trim();
4924
5099
  return normalized.length <= 50 ? normalized : `${normalized.slice(0, 47)}...`;
4925
5100
  }
5101
+ function updateKandanThreadTitle(state, title) {
5102
+ if (title !== void 0) {
5103
+ state.kandanThreadTitle = title;
5104
+ }
5105
+ }
5106
+ function kandanThreadTitleFromResolvedMessage(message) {
5107
+ return message === void 0 ? void 0 : parseKandanChatEvent(message)?.threadTitle;
5108
+ }
5109
+ function kandanThreadTitleFromWireMessages(messages) {
5110
+ if (!Array.isArray(messages)) {
5111
+ return void 0;
5112
+ }
5113
+ for (const message of messages) {
5114
+ const title = parseKandanChatEvent(message)?.threadTitle;
5115
+ if (title !== void 0) {
5116
+ return title;
5117
+ }
5118
+ }
5119
+ return void 0;
5120
+ }
5121
+ async function hydrateKandanThreadTitleFromThreadContext(args, state) {
5122
+ if (state.kandanThreadId === void 0 || state.kandanThreadTitle !== void 0) {
5123
+ return;
5124
+ }
5125
+ const session = args.options.channelSession;
5126
+ const reply = await pushOk2(
5127
+ args.kandan,
5128
+ args.topic,
5129
+ "session:thread_context",
5130
+ {
5131
+ workspace: session.workspaceSlug,
5132
+ channel: session.channelSlug,
5133
+ thread_id: state.kandanThreadId
5134
+ }
5135
+ );
5136
+ updateKandanThreadTitle(
5137
+ state,
5138
+ kandanThreadTitleFromWireMessages(reply.messages)
5139
+ );
5140
+ }
4926
5141
  async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext, event) {
4927
5142
  const session = args.options.channelSession;
4928
5143
  if (event.type !== "thread.message") {
@@ -5032,6 +5247,7 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
5032
5247
  });
5033
5248
  return;
5034
5249
  }
5250
+ updateKandanThreadTitle(state, event.threadTitle);
5035
5251
  if (!claimKandanMessage(args, state, event)) {
5036
5252
  args.log("kandan.message_ignored", {
5037
5253
  seq: event.seq,
@@ -5058,7 +5274,8 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
5058
5274
  codex_thread_id: state.codexThreadId ?? null,
5059
5275
  runner_console: {
5060
5276
  body_preview: runnerConsoleBodyPreview(event.body),
5061
- message_received_at_ms: receivedAtMs
5277
+ message_received_at_ms: receivedAtMs,
5278
+ ...state.kandanThreadTitle === void 0 ? {} : { linzumi_thread_title: state.kandanThreadTitle }
5062
5279
  },
5063
5280
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5064
5281
  });
@@ -5140,7 +5357,8 @@ async function startThreadMessageTurn(args, state, payloadContext, message) {
5140
5357
  codex_thread_id: state.codexThreadId ?? null,
5141
5358
  runner_console: {
5142
5359
  body_preview: runnerConsoleBodyPreview(queued.body),
5143
- message_received_at_ms: queued.receivedAtMs ?? Date.now()
5360
+ message_received_at_ms: queued.receivedAtMs ?? Date.now(),
5361
+ ...state.kandanThreadTitle === void 0 ? {} : { linzumi_thread_title: state.kandanThreadTitle }
5144
5362
  },
5145
5363
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5146
5364
  });
@@ -5165,11 +5383,15 @@ async function bindUnboundHistoricalThread(args, state, event) {
5165
5383
  );
5166
5384
  const rootSeq = integerValue(resolved.seq);
5167
5385
  const codexThreadId = stringValue(resolved.codex_thread_id);
5386
+ const resolvedThreadTitle = kandanThreadTitleFromResolvedMessage(
5387
+ resolved.message
5388
+ );
5168
5389
  if (rootSeq !== event.replyToSeq || codexThreadId === void 0) {
5169
5390
  return false;
5170
5391
  }
5171
5392
  state.rootSeq = rootSeq;
5172
5393
  state.kandanThreadId = event.threadId;
5394
+ updateKandanThreadTitle(state, event.threadTitle ?? resolvedThreadTitle);
5173
5395
  state.codexThreadId = codexThreadId;
5174
5396
  await bindCurrentCodexThread(args, state);
5175
5397
  args.log("kandan.thread_bound_from_historical_reply", {
@@ -5268,7 +5490,8 @@ async function drainKandanMessageQueue(args, state, payloadContext) {
5268
5490
  codex_thread_id: state.codexThreadId ?? null,
5269
5491
  runner_console: {
5270
5492
  body_preview: runnerConsoleBodyPreview(next.body),
5271
- message_received_at_ms: next.receivedAtMs ?? Date.now()
5493
+ message_received_at_ms: next.receivedAtMs ?? Date.now(),
5494
+ ...state.kandanThreadTitle === void 0 ? {} : { linzumi_thread_title: state.kandanThreadTitle }
5272
5495
  },
5273
5496
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5274
5497
  });
@@ -5581,6 +5804,15 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
5581
5804
  if (completingTurnWasRecovered(state, turnId)) {
5582
5805
  return;
5583
5806
  }
5807
+ if (completingQueuedSeq !== void 0) {
5808
+ await waitForPendingCompletedAssistantItemSourceForwards(
5809
+ state,
5810
+ completingQueuedSeq
5811
+ );
5812
+ }
5813
+ if (completingTurnWasRecovered(state, turnId)) {
5814
+ return;
5815
+ }
5584
5816
  await waitForStreamingForwardChains(args, state, payloadContext);
5585
5817
  if (completingTurnWasRecovered(state, turnId)) {
5586
5818
  return;
@@ -5643,6 +5875,13 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
5643
5875
  );
5644
5876
  const sourceMessageSeq = sourceMessageSeqForTurn(state, turnId);
5645
5877
  const rootSeq = state.rootSeq;
5878
+ const completedAssistantOutputCount = completedOutputs.filter(
5879
+ completedOutputProjectionIsAssistant
5880
+ ).length;
5881
+ const completedForwardedAssistantSnapshotCount = forwardedAssistantSnapshotOutputCount(state, messages);
5882
+ const completedSourceSeqAssistantItemCount = sourceMessageSeq === void 0 ? 0 : completedAssistantItemForwardedForSourceSeq(state, sourceMessageSeq);
5883
+ const completedStreamingAssistantOutputCount = completedAssistantOutputCount === 0 ? await completeStreamingAssistantOutputsForTurn(args, state, turnId) : 0;
5884
+ const completedAssistantResponseSeen = completedAssistantOutputCount > 0 || completedForwardedAssistantSnapshotCount > 0 || completedSourceSeqAssistantItemCount > 0 || completedStreamingAssistantOutputCount > 0 || completedAssistantItemForwardedForTurn(state, turnId);
5646
5885
  for (const output of completedOutputs) {
5647
5886
  if (completingTurnWasRecovered(state, turnId)) {
5648
5887
  return;
@@ -5660,6 +5899,35 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
5660
5899
  if (completingTurnWasRecovered(state, turnId)) {
5661
5900
  return;
5662
5901
  }
5902
+ if (!completedAssistantResponseSeen) {
5903
+ const recentError = recentCodexDiagnosticSummaryForTurn(
5904
+ state,
5905
+ "error",
5906
+ state.codexThreadId,
5907
+ turnId
5908
+ );
5909
+ const recentWarning = recentCodexDiagnosticSummaryForTurn(
5910
+ state,
5911
+ "warning",
5912
+ state.codexThreadId,
5913
+ turnId
5914
+ );
5915
+ args.log("codex.turn_completed_without_assistant_output", {
5916
+ turn_id: turnId,
5917
+ codex_thread_id: state.codexThreadId,
5918
+ kandan_thread_id: state.kandanThreadId,
5919
+ source_seq: sourceMessageSeq ?? null,
5920
+ output_count: completedOutputs.length,
5921
+ assistant_output_count: completedAssistantOutputCount,
5922
+ forwarded_assistant_snapshot_output_count: completedForwardedAssistantSnapshotCount,
5923
+ source_seq_assistant_item_count: completedSourceSeqAssistantItemCount,
5924
+ completed_streaming_assistant_output_count: completedStreamingAssistantOutputCount,
5925
+ thread_read_output_count: readMessages.length,
5926
+ session_log_output_count: sessionLogMessages.length,
5927
+ recent_error: recentError ?? null,
5928
+ recent_warning: recentWarning ?? null
5929
+ });
5930
+ }
5663
5931
  rememberForwardedTurnId(state, turnId);
5664
5932
  forgetLocalTuiTurnId(state, turnId);
5665
5933
  if (completingQueuedSeq !== void 0) {
@@ -5667,8 +5935,9 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
5667
5935
  args,
5668
5936
  state.kandanThreadId,
5669
5937
  completingQueuedSeq,
5670
- {
5671
- status: "processed"
5938
+ completedAssistantResponseSeen ? { status: "processed" } : {
5939
+ status: "failed",
5940
+ reason: "Codex completed without producing a response."
5672
5941
  }
5673
5942
  );
5674
5943
  clearActiveProcessingState(state, completingQueuedSeq);
@@ -5818,6 +6087,21 @@ function completedOutputProjectionsForTurn(state, turnId, messages) {
5818
6087
  compareCompletedOutputProjection
5819
6088
  );
5820
6089
  }
6090
+ function completedOutputProjectionIsAssistant(output) {
6091
+ switch (output.kind) {
6092
+ case "snapshot":
6093
+ return stringValue(output.message.structured.kind) === "codex_assistant_message";
6094
+ case "cached_reasoning":
6095
+ case "cached_command":
6096
+ case "cached_file_change":
6097
+ return false;
6098
+ }
6099
+ }
6100
+ function forwardedAssistantSnapshotOutputCount(state, messages) {
6101
+ return messages.filter(
6102
+ (message) => stringValue(message.structured.kind) === "codex_assistant_message" && completedAssistantItemForwarded(state, message.itemKey)
6103
+ ).length;
6104
+ }
5821
6105
  async function sessionLogOutputMessagesForTurn(args, codexThreadId, turnId) {
5822
6106
  try {
5823
6107
  return await codexSessionLogOutputMessagesForTurn({
@@ -5834,39 +6118,76 @@ async function sessionLogOutputMessagesForTurn(args, codexThreadId, turnId) {
5834
6118
  }
5835
6119
  }
5836
6120
  function completedMessagesWithSessionLog(readMessages, sessionLogMessages) {
5837
- const readExactKeys = new Set(readMessages.map(completedMessageExactKey));
5838
- const readSemanticCounts = completedMessageSemanticCounts(readMessages);
5839
- const missingSessionStructuredMessages = [];
5840
- for (const message of sessionLogMessages) {
5841
- if (stringValue(message.structured.kind) === "codex_assistant_message") {
5842
- continue;
5843
- }
5844
- if (readExactKeys.has(completedMessageExactKey(message))) {
5845
- continue;
6121
+ if (sessionLogMessages.length === 0) {
6122
+ return [...readMessages];
6123
+ }
6124
+ const consumedReadIndexes = /* @__PURE__ */ new Set();
6125
+ const sessionOrderedEntries = sessionLogMessages.map((message) => {
6126
+ const readIndex = findUnconsumedCompletedMessageIndex(
6127
+ readMessages,
6128
+ consumedReadIndexes,
6129
+ completedMessageExactKey(message)
6130
+ );
6131
+ if (readIndex >= 0) {
6132
+ consumedReadIndexes.add(readIndex);
6133
+ return { kind: "read", readIndex };
5846
6134
  }
5847
- const semanticKey = completedMessageSemanticKey(message);
5848
- const remainingReadCount = readSemanticCounts.get(semanticKey) ?? 0;
5849
- if (remainingReadCount > 0) {
5850
- readSemanticCounts.set(semanticKey, remainingReadCount - 1);
5851
- continue;
6135
+ const semanticReadIndex = findUnconsumedCompletedMessageSemanticIndex(
6136
+ readMessages,
6137
+ consumedReadIndexes,
6138
+ completedMessageSemanticKey(message)
6139
+ );
6140
+ if (semanticReadIndex >= 0) {
6141
+ consumedReadIndexes.add(semanticReadIndex);
6142
+ return { kind: "read", readIndex: semanticReadIndex };
6143
+ }
6144
+ return { kind: "session", message };
6145
+ });
6146
+ const mergedMessages = [];
6147
+ let nextReadIndex = 0;
6148
+ for (const entry of sessionOrderedEntries) {
6149
+ switch (entry.kind) {
6150
+ case "read":
6151
+ while (nextReadIndex < entry.readIndex) {
6152
+ if (!consumedReadIndexes.has(nextReadIndex)) {
6153
+ const message = readMessages[nextReadIndex];
6154
+ if (message !== void 0) {
6155
+ mergedMessages.push(message);
6156
+ }
6157
+ }
6158
+ nextReadIndex += 1;
6159
+ }
6160
+ mergedMessages.push(readMessages[entry.readIndex]);
6161
+ nextReadIndex = Math.max(nextReadIndex, entry.readIndex + 1);
6162
+ break;
6163
+ case "session":
6164
+ mergedMessages.push(entry.message);
6165
+ break;
5852
6166
  }
5853
- missingSessionStructuredMessages.push(message);
5854
6167
  }
5855
- if (missingSessionStructuredMessages.length === 0) {
5856
- return [...readMessages];
6168
+ while (nextReadIndex < readMessages.length) {
6169
+ if (!consumedReadIndexes.has(nextReadIndex)) {
6170
+ const message = readMessages[nextReadIndex];
6171
+ if (message !== void 0) {
6172
+ mergedMessages.push(message);
6173
+ }
6174
+ }
6175
+ nextReadIndex += 1;
5857
6176
  }
5858
- return [...missingSessionStructuredMessages, ...readMessages];
6177
+ return mergedMessages;
5859
6178
  }
5860
6179
  function completedMessageExactKey(message) {
5861
6180
  return `${stringValue(message.structured.kind) ?? ""}:${message.itemKey}`;
5862
6181
  }
5863
- function completedMessageSemanticCounts(messages) {
5864
- const counts = /* @__PURE__ */ new Map();
5865
- for (const message of messages) {
5866
- const key = completedMessageSemanticKey(message);
5867
- counts.set(key, (counts.get(key) ?? 0) + 1);
5868
- }
5869
- return counts;
6182
+ function findUnconsumedCompletedMessageIndex(messages, consumedIndexes, exactKey) {
6183
+ return messages.findIndex(
6184
+ (message, index) => !consumedIndexes.has(index) && completedMessageExactKey(message) === exactKey
6185
+ );
6186
+ }
6187
+ function findUnconsumedCompletedMessageSemanticIndex(messages, consumedIndexes, semanticKey) {
6188
+ return messages.findIndex(
6189
+ (message, index) => !consumedIndexes.has(index) && completedMessageSemanticKey(message) === semanticKey
6190
+ );
5870
6191
  }
5871
6192
  function completedMessageSemanticKey(message) {
5872
6193
  const kind = stringValue(message.structured.kind) ?? "";
@@ -6091,12 +6412,13 @@ function logCompletedCodexOutput(args, state, turnId, message) {
6091
6412
  file_paths: fileChangePaths(message.structured)
6092
6413
  });
6093
6414
  }
6094
- async function forwardCompletedAssistantItem(args, state, params, payloadContext) {
6415
+ async function forwardCompletedAssistantItem(args, state, params, payloadContext, fallbackTurnId = void 0, fallbackSourceMessageSeq = void 0) {
6095
6416
  if (state.kandanThreadId === void 0 || state.codexThreadId === void 0) {
6096
6417
  return;
6097
6418
  }
6098
- const turnId = stringValue(params.turnId) ?? stringValue(params.turn_id) ?? stringValue(objectValue(params.turn)?.id);
6099
6419
  const item = objectValue(params.item) ?? params;
6420
+ const itemTurn = objectValue(item.turn);
6421
+ const turnId = stringValue(params.turnId) ?? stringValue(params.turn_id) ?? stringValue(objectValue(params.turn)?.id) ?? stringValue(item.turnId) ?? stringValue(item.turn_id) ?? stringValue(itemTurn?.id) ?? fallbackTurnId;
6100
6422
  const completedItemKey = stringValue(params.itemId) ?? stringValue(params.item_id) ?? stringValue(objectValue(params.item)?.id);
6101
6423
  if (turnId !== void 0) {
6102
6424
  await waitForPendingTuiInputMirror(state, turnId);
@@ -6128,7 +6450,7 @@ async function forwardCompletedAssistantItem(args, state, params, payloadContext
6128
6450
  if (message === void 0 || completedAssistantItemForwarded(state, message.itemKey)) {
6129
6451
  return;
6130
6452
  }
6131
- const sourceMessageSeq = messageTurnId === void 0 ? void 0 : sourceMessageSeqForTurn(state, messageTurnId);
6453
+ const sourceMessageSeq = messageTurnId === void 0 ? fallbackSourceMessageSeq ?? startingSourceMessageSeq(state) : sourceMessageSeqForTurn(state, messageTurnId);
6132
6454
  if (messageTurnId !== void 0 && sourceMessageSeq === void 0) {
6133
6455
  args.log("codex.completed_assistant_item_without_source_message", {
6134
6456
  turn_id: messageTurnId,
@@ -6176,11 +6498,21 @@ async function forwardCompletedAssistantItem(args, state, params, payloadContext
6176
6498
  `Cannot reconcile completed assistant item ${message.itemKey} from item notification; ${streamed.candidateCount} active streamed assistant outputs exist`
6177
6499
  );
6178
6500
  }
6179
- rememberCompletedAssistantItemKey(state, message.itemKey);
6180
- logCompletedCodexOutput(args, messageTurnId ?? `item:${message.itemKey}`, {
6181
- ...message,
6182
- structured
6183
- });
6501
+ rememberCompletedAssistantItemKey(
6502
+ state,
6503
+ message.itemKey,
6504
+ messageTurnId,
6505
+ sourceMessageSeq
6506
+ );
6507
+ logCompletedCodexOutput(
6508
+ args,
6509
+ state,
6510
+ messageTurnId ?? `item:${message.itemKey}`,
6511
+ {
6512
+ ...message,
6513
+ structured
6514
+ }
6515
+ );
6184
6516
  }
6185
6517
  function compareCompletedOutputProjection(left, right) {
6186
6518
  if (left.kind === "snapshot" && right.kind === "snapshot" && left.match.kind !== right.match.kind && (left.match.kind === "none" || right.match.kind === "none")) {
@@ -6252,7 +6584,7 @@ async function forwardAssistantDeltaPayload(args, state, delta, payloadContext)
6252
6584
  }
6253
6585
  const existing = findStreamingAssistantOutput(state, delta.itemKey);
6254
6586
  const nextContent = `${existing?.content ?? ""}${delta.delta}`;
6255
- const sourceMessageSeq = delta.turnId === void 0 ? void 0 : sourceMessageSeqForTurn(state, delta.turnId);
6587
+ const sourceMessageSeq = delta.turnId === void 0 ? delta.sourceMessageSeq : sourceMessageSeqForTurn(state, delta.turnId);
6256
6588
  const rootSeq = state.rootSeq;
6257
6589
  if (delta.turnId !== void 0 && sourceMessageSeq === void 0) {
6258
6590
  args.log("codex.delta_without_source_message", {
@@ -6299,6 +6631,7 @@ async function forwardAssistantDeltaPayload(args, state, delta, payloadContext)
6299
6631
  rememberStreamingAssistantOutput(state, {
6300
6632
  itemKey: delta.itemKey,
6301
6633
  turnId: delta.turnId,
6634
+ sourceMessageSeq,
6302
6635
  seq,
6303
6636
  content: nextContent
6304
6637
  });
@@ -6314,6 +6647,7 @@ async function forwardAssistantDeltaPayload(args, state, delta, payloadContext)
6314
6647
  );
6315
6648
  rememberStreamingAssistantOutput(state, {
6316
6649
  ...existing,
6650
+ sourceMessageSeq: existing.sourceMessageSeq ?? sourceMessageSeq,
6317
6651
  content: nextContent
6318
6652
  });
6319
6653
  }
@@ -6325,11 +6659,12 @@ async function forwardAssistantDeltaPayload(args, state, delta, payloadContext)
6325
6659
  content_length: nextContent.length
6326
6660
  });
6327
6661
  }
6328
- function enqueueAssistantDelta(args, state, params, payloadContext) {
6329
- const delta = codexAssistantDeltaFromNotification(params);
6330
- if (delta === void 0) {
6662
+ function enqueueAssistantDelta(args, state, params, payloadContext, fallbackTurnId = void 0, fallbackSourceMessageSeq = void 0) {
6663
+ const parsedDelta = codexAssistantDeltaFromNotification(params);
6664
+ if (parsedDelta === void 0) {
6331
6665
  return;
6332
6666
  }
6667
+ const delta = parsedDelta.turnId === void 0 && fallbackTurnId !== void 0 ? { ...parsedDelta, turnId: fallbackTurnId } : { ...parsedDelta, sourceMessageSeq: fallbackSourceMessageSeq };
6333
6668
  enqueueStreamDelta(
6334
6669
  state.assistantDeltaQueue,
6335
6670
  delta,
@@ -7129,8 +7464,42 @@ async function completeInterruptedAssistantOutputs(args, state, turnId, payloadC
7129
7464
  "completed"
7130
7465
  );
7131
7466
  forgetStreamingAssistantOutput(state, output.itemKey);
7132
- rememberCompletedAssistantItemKey(state, output.itemKey);
7467
+ rememberCompletedAssistantItemKey(state, output.itemKey, turnId);
7468
+ }
7469
+ }
7470
+ async function completeStreamingAssistantOutputsForTurn(args, state, turnId) {
7471
+ const sourceMessageSeq = sourceMessageSeqForTurn(state, turnId);
7472
+ const outputs = boundedCacheValues(state.streamingAssistantOutputs).filter(
7473
+ (output) => output.turnId === turnId || sourceMessageSeq !== void 0 && output.sourceMessageSeq === sourceMessageSeq
7474
+ );
7475
+ for (const output of outputs) {
7476
+ const message = {
7477
+ itemKey: output.itemKey,
7478
+ body: output.content,
7479
+ structured: codexAssistantStructuredMessage(
7480
+ output.itemKey,
7481
+ output.content,
7482
+ "completed"
7483
+ )
7484
+ };
7485
+ await editStreamedCodexOutput(
7486
+ args,
7487
+ state,
7488
+ output.seq,
7489
+ output.itemKey,
7490
+ output.content,
7491
+ "completed"
7492
+ );
7493
+ forgetStreamingAssistantOutput(state, output.itemKey);
7494
+ rememberCompletedAssistantItemKey(
7495
+ state,
7496
+ output.itemKey,
7497
+ turnId,
7498
+ output.sourceMessageSeq
7499
+ );
7500
+ logCompletedCodexOutput(args, state, turnId, message);
7133
7501
  }
7502
+ return outputs.length;
7134
7503
  }
7135
7504
  function streamingClientMessageId(instanceId, delta) {
7136
7505
  const digest = createHash("sha256").update(`${instanceId}:${delta.turnId ?? "turn"}:${delta.itemKey}`).digest("hex").slice(0, 32);
@@ -7508,12 +7877,34 @@ function forgetStreamingAssistantOutput(state, itemKey) {
7508
7877
  function completedAssistantItemForwarded(state, itemKey) {
7509
7878
  return state.completedAssistantItemKeys.has(itemKey);
7510
7879
  }
7511
- function rememberCompletedAssistantItemKey(state, itemKey) {
7880
+ function completedAssistantItemForwardedForTurn(state, turnId) {
7881
+ return boundedCacheValues(state.completedAssistantItemTurns).some(
7882
+ (item) => item.turnId === turnId
7883
+ );
7884
+ }
7885
+ function completedAssistantItemForwardedForSourceSeq(state, sourceSeq) {
7886
+ return boundedCacheValues(state.completedAssistantItemSourceSeqs).filter(
7887
+ (item) => item.sourceSeq === sourceSeq
7888
+ ).length;
7889
+ }
7890
+ function rememberCompletedAssistantItemKey(state, itemKey, turnId = void 0, sourceSeq = void 0) {
7512
7891
  rememberBoundedStringSet(
7513
7892
  state.completedAssistantItemKeys,
7514
7893
  itemKey,
7515
7894
  maxForwardedTurnIds
7516
7895
  );
7896
+ if (turnId !== void 0) {
7897
+ rememberBoundedCacheValue(state.completedAssistantItemTurns, itemKey, {
7898
+ itemKey,
7899
+ turnId
7900
+ });
7901
+ }
7902
+ if (sourceSeq !== void 0) {
7903
+ rememberBoundedCacheValue(state.completedAssistantItemSourceSeqs, itemKey, {
7904
+ itemKey,
7905
+ sourceSeq
7906
+ });
7907
+ }
7517
7908
  }
7518
7909
  function rememberStreamingReasoningOutput(state, output) {
7519
7910
  rememberBoundedCacheValue(
@@ -7588,7 +7979,9 @@ function mergeWebSearchQueries(existing, incoming) {
7588
7979
  }
7589
7980
  function codexNotificationTurnId(params) {
7590
7981
  const turn = objectValue(params.turn);
7591
- return stringValue(turn?.id) ?? stringValue(params.turnId) ?? stringValue(params.turn_id);
7982
+ const item = objectValue(params.item);
7983
+ const itemTurn = objectValue(item?.turn);
7984
+ return stringValue(turn?.id) ?? stringValue(params.turnId) ?? stringValue(params.turn_id) ?? stringValue(item?.turnId) ?? stringValue(item?.turn_id) ?? stringValue(itemTurn?.id);
7592
7985
  }
7593
7986
  function codexNotificationThreadId(params) {
7594
7987
  const thread = objectValue(params.thread);
@@ -7628,11 +8021,58 @@ function inferThreadOnlyCompletedTurnId(args, state, threadId) {
7628
8021
  return void 0;
7629
8022
  }
7630
8023
  }
7631
- function codexNotificationActiveTurnFallback(method, state, params) {
7632
- if (method !== "response_item" || codexCompletedFileChangeFromNotification(params) === void 0) {
8024
+ function codexNotificationActiveTurnFallback(method, state, params, threadId) {
8025
+ if (threadId === void 0 || state.codexThreadId !== threadId) {
7633
8026
  return void 0;
7634
8027
  }
7635
- return activeTurnId(state.turn);
8028
+ switch (method) {
8029
+ case "response_item":
8030
+ return codexCompletedFileChangeFromNotification(params) === void 0 ? void 0 : activeTurnId(state.turn);
8031
+ case "item/agentMessage/delta":
8032
+ case "item/completed":
8033
+ case "warning":
8034
+ case "error":
8035
+ return activeTurnId(state.turn);
8036
+ default:
8037
+ return void 0;
8038
+ }
8039
+ }
8040
+ function rememberRecentCodexDiagnostic(state, method, params, threadId, turnId) {
8041
+ switch (method) {
8042
+ case "warning":
8043
+ case "error": {
8044
+ const summary = codexNotificationDiagnosticSummary(method, params) ?? `${method}: seen (no details)`;
8045
+ const cacheKey = [
8046
+ method,
8047
+ threadId ?? "no-thread",
8048
+ turnId ?? "no-turn"
8049
+ ].join(":");
8050
+ if (getBoundedCacheValue(state.recentCodexDiagnostics, cacheKey)) {
8051
+ break;
8052
+ }
8053
+ rememberBoundedCacheValue(state.recentCodexDiagnostics, cacheKey, {
8054
+ method,
8055
+ threadId,
8056
+ turnId,
8057
+ summary
8058
+ });
8059
+ break;
8060
+ }
8061
+ default:
8062
+ break;
8063
+ }
8064
+ }
8065
+ function recentCodexDiagnosticSummaryForTurn(state, method, threadId, turnId) {
8066
+ return getBoundedCacheValue(
8067
+ state.recentCodexDiagnostics,
8068
+ [method, threadId, turnId].join(":")
8069
+ )?.summary ?? getBoundedCacheValue(
8070
+ state.recentCodexDiagnostics,
8071
+ [method, "no-thread", turnId].join(":")
8072
+ )?.summary ?? getBoundedCacheValue(
8073
+ state.recentCodexDiagnostics,
8074
+ [method, threadId, "no-turn"].join(":")
8075
+ )?.summary;
7636
8076
  }
7637
8077
  function rememberLocalTuiTurnIfNeeded(args, state, threadId, turnId) {
7638
8078
  if (args.options.launchTui !== true || state.codexThreadId !== threadId || state.turn.status !== "idle") {
@@ -7696,6 +8136,35 @@ function forgetPendingCompletedAssistantItemForward(state, turnId, promise) {
7696
8136
  state.pendingCompletedAssistantItemForwards.delete(turnId);
7697
8137
  }
7698
8138
  }
8139
+ function rememberPendingCompletedAssistantItemSourceForward(state, sourceMessageSeq, promise) {
8140
+ const existing = state.pendingCompletedAssistantItemSourceForwards.get(sourceMessageSeq);
8141
+ const pending = existing ?? /* @__PURE__ */ new Set();
8142
+ pending.add(promise);
8143
+ state.pendingCompletedAssistantItemSourceForwards.set(
8144
+ sourceMessageSeq,
8145
+ pending
8146
+ );
8147
+ trimBoundedMap(
8148
+ state.pendingCompletedAssistantItemSourceForwards,
8149
+ maxForwardedTurnIds
8150
+ );
8151
+ }
8152
+ function forgetPendingCompletedAssistantItemSourceForward(state, sourceMessageSeq, promise) {
8153
+ const pending = state.pendingCompletedAssistantItemSourceForwards.get(sourceMessageSeq);
8154
+ if (pending === void 0) {
8155
+ return;
8156
+ }
8157
+ pending.delete(promise);
8158
+ if (pending.size === 0) {
8159
+ state.pendingCompletedAssistantItemSourceForwards.delete(sourceMessageSeq);
8160
+ }
8161
+ }
8162
+ async function waitForPendingCompletedAssistantItemSourceForwards(state, sourceMessageSeq) {
8163
+ const pending = state.pendingCompletedAssistantItemSourceForwards.get(sourceMessageSeq);
8164
+ if (pending !== void 0) {
8165
+ await Promise.allSettled([...pending]);
8166
+ }
8167
+ }
7699
8168
  async function waitForPendingCompletedAssistantItemForwards(state, turnId) {
7700
8169
  const pending = state.pendingCompletedAssistantItemForwards.get(turnId);
7701
8170
  if (pending !== void 0) {
@@ -7746,6 +8215,16 @@ function rememberTurnReplyTarget(state, turnId, replyToSeq) {
7746
8215
  function sourceMessageSeqForTurn(state, turnId) {
7747
8216
  return getBoundedCacheValue(state.turnReplyTargets, turnId)?.replyToSeq;
7748
8217
  }
8218
+ function startingSourceMessageSeq(state) {
8219
+ switch (state.turn.status) {
8220
+ case "starting":
8221
+ return state.turn.queuedSeq;
8222
+ case "active":
8223
+ case "completing":
8224
+ case "idle":
8225
+ return void 0;
8226
+ }
8227
+ }
7749
8228
  function fileChangePaths(structured) {
7750
8229
  const changes = arrayValue(structured.changes) ?? [];
7751
8230
  return changes.filter(isJsonObject).map((change) => stringValue(change.path) ?? "").filter((path2) => path2.trim() !== "");
@@ -8228,6 +8707,7 @@ var init_channelSession = __esm({
8228
8707
  "use strict";
8229
8708
  init_channelSessionSupport();
8230
8709
  init_commanderAttachments();
8710
+ init_codexNotificationDiagnostics();
8231
8711
  init_codexRuntimeOptions();
8232
8712
  init_codexOutput();
8233
8713
  init_codexSessionLog();
@@ -8986,7 +9466,7 @@ function redactForCliLog(value) {
8986
9466
  return redactObject(value);
8987
9467
  }
8988
9468
  function redactValue(value, key) {
8989
- if (sensitiveKey(key)) {
9469
+ if (sensitiveKey2(key)) {
8990
9470
  return sensitiveMarker;
8991
9471
  }
8992
9472
  if (typeof value === "string") {
@@ -9011,10 +9491,10 @@ function redactObject(value) {
9011
9491
  );
9012
9492
  }
9013
9493
  function runnerConsolePayload(redacted, original) {
9014
- const consoleFields = objectValue2(original.runner_console);
9494
+ const consoleFields = objectValue3(original.runner_console);
9015
9495
  return consoleFields === void 0 ? redacted : { ...redacted, ...redactForCliLog(consoleFields) };
9016
9496
  }
9017
- function objectValue2(value) {
9497
+ function objectValue3(value) {
9018
9498
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
9019
9499
  }
9020
9500
  function redactArgs(args) {
@@ -9043,7 +9523,7 @@ function splitArgAssignment(value) {
9043
9523
  const index = value.indexOf("=");
9044
9524
  return index === -1 ? [value, void 0] : [value.slice(0, index), value.slice(index + 1)];
9045
9525
  }
9046
- function sensitiveKey(key) {
9526
+ function sensitiveKey2(key) {
9047
9527
  if (key === void 0) {
9048
9528
  return false;
9049
9529
  }
@@ -9286,10 +9766,15 @@ async function chooseLoopbackPort() {
9286
9766
  });
9287
9767
  }
9288
9768
  async function startCodexAppServer(codexBin, cwd, options = {}) {
9769
+ return startCodexAppServerAttempt(codexBin, cwd, options, 1);
9770
+ }
9771
+ async function startCodexAppServerAttempt(codexBin, cwd, options, attempt) {
9289
9772
  const port = await chooseLoopbackPort();
9290
9773
  const url = `ws://127.0.0.1:${port}`;
9291
9774
  const args = codexAppServerArgs(url, options);
9292
- const stdio = codexAppServerStdio(process.stdout.isTTY === true);
9775
+ let stderrText = "";
9776
+ const configuredStdio = codexAppServerStdio(process.stdout.isTTY === true);
9777
+ const stdio = [configuredStdio[0], configuredStdio[1], "pipe"];
9293
9778
  writeCliAuditEvent("process.spawn", {
9294
9779
  command: codexBin,
9295
9780
  args,
@@ -9306,7 +9791,12 @@ async function startCodexAppServer(codexBin, cwd, options = {}) {
9306
9791
  drainCodexAppServerOutput(child, "stdout");
9307
9792
  }
9308
9793
  if (stdio[2] === "pipe") {
9309
- drainCodexAppServerOutput(child, "stderr");
9794
+ drainCodexAppServerOutput(child, "stderr", (chunk) => {
9795
+ stderrText = boundedText(`${stderrText}${chunk}`);
9796
+ if (configuredStdio[2] === "inherit") {
9797
+ process.stderr.write(chunk);
9798
+ }
9799
+ });
9310
9800
  }
9311
9801
  const stop = () => stopCodexAppServerProcess(child);
9312
9802
  writeCliAuditEvent("process.spawned", {
@@ -9337,20 +9827,40 @@ async function startCodexAppServer(codexBin, cwd, options = {}) {
9337
9827
  await waitForReadyz(url, child);
9338
9828
  } catch (error) {
9339
9829
  stop();
9830
+ if (shouldRetryCodexAppServerBindFailure(error, stderrText, attempt)) {
9831
+ writeCliAuditEvent("process.spawn.retry", {
9832
+ command: codexBin,
9833
+ cwd,
9834
+ attempt,
9835
+ reason: "loopback_bind_in_use",
9836
+ purpose: "codex.app_server"
9837
+ });
9838
+ return startCodexAppServerAttempt(codexBin, cwd, options, attempt + 1);
9839
+ }
9340
9840
  throw error;
9341
9841
  }
9342
9842
  return { url, process: child, stop };
9343
9843
  }
9844
+ function boundedText(value) {
9845
+ const maxBytes = 12e3;
9846
+ return value.length > maxBytes ? value.slice(value.length - maxBytes) : value;
9847
+ }
9848
+ function shouldRetryCodexAppServerBindFailure(error, stderrText, attempt) {
9849
+ const maxAttempts = 3;
9850
+ const message = error instanceof Error ? error.message : String(error);
9851
+ return attempt < maxAttempts && message.includes("codex app-server exited before readyz") && stderrText.includes("EADDRINUSE") && stderrText.includes("listen");
9852
+ }
9344
9853
  function codexAppServerStdio(stdoutIsTty) {
9345
9854
  return stdoutIsTty ? ["ignore", "pipe", "pipe"] : ["ignore", "inherit", "inherit"];
9346
9855
  }
9347
- function drainCodexAppServerOutput(child, streamName) {
9856
+ function drainCodexAppServerOutput(child, streamName, onText = void 0) {
9348
9857
  const stream = child[streamName];
9349
9858
  if (stream === null) {
9350
9859
  return;
9351
9860
  }
9352
9861
  stream.on("data", (chunk) => {
9353
9862
  const text2 = chunk.toString();
9863
+ onText?.(text2);
9354
9864
  writeCliAuditEvent("process.output", {
9355
9865
  pid: child.pid,
9356
9866
  purpose: "codex.app_server",
@@ -9752,14 +10262,17 @@ function codexNotificationConsoleStats(method, params) {
9752
10262
  return {
9753
10263
  rate_limit_summary: rateLimitSummary(params) ?? "seen (no details)"
9754
10264
  };
10265
+ case "warning":
10266
+ case "error":
10267
+ return codexNotificationDiagnosticDetails(method, params);
9755
10268
  default:
9756
10269
  return {};
9757
10270
  }
9758
10271
  }
9759
10272
  function tokenUsageSummary(params) {
9760
- const usage = objectValue3(params.tokenUsage) ?? objectValue3(params.token_usage) ?? objectValue3(params.usage) ?? params;
9761
- const total = tokenUsageBreakdownSummary(objectValue3(usage.total)) ?? tokenUsageBreakdownSummary(objectValue3(usage.totalUsage)) ?? tokenUsageBreakdownSummary(objectValue3(usage.total_usage)) ?? tokenUsageBreakdownSummary(objectValue3(params.totalTokenUsage)) ?? tokenUsageBreakdownSummary(objectValue3(params.total_token_usage)) ?? tokenUsageBreakdownSummary(usage);
9762
- const last = tokenUsageBreakdownSummary(objectValue3(usage.last)) ?? tokenUsageBreakdownSummary(objectValue3(usage.lastUsage)) ?? tokenUsageBreakdownSummary(objectValue3(usage.last_usage)) ?? tokenUsageBreakdownSummary(objectValue3(params.lastTokenUsage)) ?? tokenUsageBreakdownSummary(objectValue3(params.last_token_usage));
10273
+ const usage = objectValue4(params.tokenUsage) ?? objectValue4(params.token_usage) ?? objectValue4(params.usage) ?? params;
10274
+ const total = tokenUsageBreakdownSummary(objectValue4(usage.total)) ?? tokenUsageBreakdownSummary(objectValue4(usage.totalUsage)) ?? tokenUsageBreakdownSummary(objectValue4(usage.total_usage)) ?? tokenUsageBreakdownSummary(objectValue4(params.totalTokenUsage)) ?? tokenUsageBreakdownSummary(objectValue4(params.total_token_usage)) ?? tokenUsageBreakdownSummary(usage);
10275
+ const last = tokenUsageBreakdownSummary(objectValue4(usage.last)) ?? tokenUsageBreakdownSummary(objectValue4(usage.lastUsage)) ?? tokenUsageBreakdownSummary(objectValue4(usage.last_usage)) ?? tokenUsageBreakdownSummary(objectValue4(params.lastTokenUsage)) ?? tokenUsageBreakdownSummary(objectValue4(params.last_token_usage));
9763
10276
  const summary = [
9764
10277
  total === void 0 ? void 0 : `total ${total}`,
9765
10278
  last === void 0 ? void 0 : `last ${last}`
@@ -9770,8 +10283,8 @@ function tokenUsageBreakdownSummary(breakdown) {
9770
10283
  if (breakdown === void 0) {
9771
10284
  return void 0;
9772
10285
  }
9773
- const inputDetails = objectValue3(breakdown.inputTokensDetails) ?? objectValue3(breakdown.input_tokens_details);
9774
- const outputDetails = objectValue3(breakdown.outputTokensDetails) ?? objectValue3(breakdown.output_tokens_details);
10286
+ const inputDetails = objectValue4(breakdown.inputTokensDetails) ?? objectValue4(breakdown.input_tokens_details);
10287
+ const outputDetails = objectValue4(breakdown.outputTokensDetails) ?? objectValue4(breakdown.output_tokens_details);
9775
10288
  const input = integerValue2(breakdown.inputTokens) ?? integerValue2(breakdown.input_tokens) ?? integerValue2(breakdown.promptTokens) ?? integerValue2(breakdown.prompt_tokens);
9776
10289
  const output = integerValue2(breakdown.outputTokens) ?? integerValue2(breakdown.output_tokens) ?? integerValue2(breakdown.completionTokens) ?? integerValue2(breakdown.completion_tokens);
9777
10290
  const total = integerValue2(breakdown.totalTokens) ?? integerValue2(breakdown.total_tokens);
@@ -9787,10 +10300,10 @@ function tokenUsageBreakdownSummary(breakdown) {
9787
10300
  return values.length === 0 ? void 0 : values.join(" / ");
9788
10301
  }
9789
10302
  function rateLimitSummary(params) {
9790
- const rateLimits = objectValue3(params.rateLimits) ?? objectValue3(params.rate_limits) ?? objectValue3(params.limits) ?? params;
10303
+ const rateLimits = objectValue4(params.rateLimits) ?? objectValue4(params.rate_limits) ?? objectValue4(params.limits) ?? params;
9791
10304
  const direct = rateLimitBucketSummary(rateLimits, void 0);
9792
10305
  const children = Object.entries(rateLimits).flatMap(([name, value]) => {
9793
- const bucket = objectValue3(value);
10306
+ const bucket = objectValue4(value);
9794
10307
  return bucket === void 0 ? [] : [rateLimitBucketSummary(bucket, name)];
9795
10308
  });
9796
10309
  const summaries = [direct, ...children].filter(
@@ -9799,11 +10312,11 @@ function rateLimitSummary(params) {
9799
10312
  return summaries.length === 0 ? void 0 : summaries.join(" | ");
9800
10313
  }
9801
10314
  function rateLimitBucketSummary(bucket, fallbackName) {
9802
- const name = stringValue2(bucket.limitName) ?? stringValue2(bucket.limit_name) ?? stringValue2(bucket.name) ?? stringValue2(bucket.type) ?? fallbackName;
9803
- const plan = stringValue2(bucket.planType) ?? stringValue2(bucket.plan_type) ?? stringValue2(bucket.plan);
10315
+ const name = stringValue3(bucket.limitName) ?? stringValue3(bucket.limit_name) ?? stringValue3(bucket.name) ?? stringValue3(bucket.type) ?? fallbackName;
10316
+ const plan = stringValue3(bucket.planType) ?? stringValue3(bucket.plan_type) ?? stringValue3(bucket.plan);
9804
10317
  const remaining = integerValue2(bucket.remaining) ?? integerValue2(bucket.remainingRequests) ?? integerValue2(bucket.remaining_requests) ?? integerValue2(bucket.remainingTokens) ?? integerValue2(bucket.remaining_tokens);
9805
10318
  const limit = integerValue2(bucket.limit) ?? integerValue2(bucket.requestLimit) ?? integerValue2(bucket.request_limit) ?? integerValue2(bucket.limitRequests) ?? integerValue2(bucket.limit_requests) ?? integerValue2(bucket.tokenLimit) ?? integerValue2(bucket.token_limit) ?? integerValue2(bucket.limitTokens) ?? integerValue2(bucket.limit_tokens);
9806
- const reset = stringValue2(bucket.resetAt) ?? stringValue2(bucket.reset_at) ?? stringValue2(bucket.resetsAt) ?? stringValue2(bucket.resets_at) ?? unixTimestampValue(bucket.resetsAt) ?? unixTimestampValue(bucket.resets_at) ?? secondsValue(bucket.resetAfterSeconds) ?? secondsValue(bucket.reset_after_seconds) ?? secondsValue(bucket.retryAfterSeconds) ?? secondsValue(bucket.retry_after_seconds);
10319
+ const reset = stringValue3(bucket.resetAt) ?? stringValue3(bucket.reset_at) ?? stringValue3(bucket.resetsAt) ?? stringValue3(bucket.resets_at) ?? unixTimestampValue(bucket.resetsAt) ?? unixTimestampValue(bucket.resets_at) ?? secondsValue(bucket.resetAfterSeconds) ?? secondsValue(bucket.reset_after_seconds) ?? secondsValue(bucket.retryAfterSeconds) ?? secondsValue(bucket.retry_after_seconds);
9807
10320
  const usedPercent = integerValue2(bucket.usedPercent) ?? integerValue2(bucket.used_percent);
9808
10321
  const windowDurationMins = integerValue2(bucket.windowDurationMins) ?? integerValue2(bucket.window_duration_mins);
9809
10322
  const label = [name, plan].filter((value) => value !== void 0).join(" ");
@@ -9830,10 +10343,10 @@ function unixTimestampValue(value) {
9830
10343
  const seconds = integerValue2(value);
9831
10344
  return seconds === void 0 ? void 0 : new Date(seconds * 1e3).toISOString();
9832
10345
  }
9833
- function objectValue3(value) {
10346
+ function objectValue4(value) {
9834
10347
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
9835
10348
  }
9836
- function stringValue2(value) {
10349
+ function stringValue3(value) {
9837
10350
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
9838
10351
  }
9839
10352
  function integerValue2(value) {
@@ -9849,6 +10362,7 @@ function integerValue2(value) {
9849
10362
  var init_codexNotificationConsoleStats = __esm({
9850
10363
  "src/codexNotificationConsoleStats.ts"() {
9851
10364
  "use strict";
10365
+ init_codexNotificationDiagnostics();
9852
10366
  init_protocol();
9853
10367
  }
9854
10368
  });
@@ -9895,13 +10409,17 @@ function assertConfiguredAllowedCwds(paths) {
9895
10409
  }
9896
10410
  function expandUserPath(pathValue) {
9897
10411
  if (pathValue === "~") {
9898
- return homedir6();
10412
+ return currentHomeDirectory();
9899
10413
  }
9900
10414
  if (pathValue.startsWith("~/")) {
9901
- return resolve3(homedir6(), pathValue.slice(2));
10415
+ return resolve3(currentHomeDirectory(), pathValue.slice(2));
9902
10416
  }
9903
10417
  return pathValue;
9904
10418
  }
10419
+ function currentHomeDirectory() {
10420
+ const configuredHome = process.env.HOME;
10421
+ return configuredHome === void 0 || configuredHome.trim() === "" ? homedir6() : configuredHome;
10422
+ }
9905
10423
  function resolveAllowedCwd(requestedCwd, allowedRoots) {
9906
10424
  if (requestedCwd === void 0 || requestedCwd.trim() === "") {
9907
10425
  return { ok: false, reason: "missing_cwd" };
@@ -13321,7 +13839,8 @@ var init_dependencyStatus = __esm({
13321
13839
  });
13322
13840
 
13323
13841
  // src/phoenix.ts
13324
- function phoenixWebsocketUrl(baseUrl, token) {
13842
+ import { Buffer as Buffer3 } from "node:buffer";
13843
+ function phoenixWebsocketUrl(baseUrl) {
13325
13844
  const parsed = new URL(baseUrl);
13326
13845
  switch (parsed.protocol) {
13327
13846
  case "http:":
@@ -13332,11 +13851,18 @@ function phoenixWebsocketUrl(baseUrl, token) {
13332
13851
  break;
13333
13852
  }
13334
13853
  parsed.pathname = parsed.pathname.replace(/\/$/, "") + "/socket/websocket";
13335
- parsed.searchParams.set("token", token);
13336
13854
  parsed.searchParams.set("vsn", "2.0.0");
13337
13855
  return parsed.toString();
13338
13856
  }
13339
- async function connectPhoenixClient(baseUrl, token, socketFactory = (url) => new WebSocket(url), options = {}) {
13857
+ function phoenixWebsocketProtocols(token) {
13858
+ return [
13859
+ `${phoenixAuthTokenProtocolPrefix}${Buffer3.from(token, "utf8").toString(
13860
+ "base64url"
13861
+ )}`,
13862
+ "phoenix"
13863
+ ];
13864
+ }
13865
+ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protocols) => new WebSocket(url, protocols), options = {}) {
13340
13866
  const pending = /* @__PURE__ */ new Map();
13341
13867
  const joins = /* @__PURE__ */ new Map();
13342
13868
  const controlCallbacks = /* @__PURE__ */ new Set();
@@ -13475,7 +14001,10 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url) => new
13475
14001
  if (state.closed) {
13476
14002
  return;
13477
14003
  }
13478
- const websocket = socketFactory(phoenixWebsocketUrl(baseUrl, token));
14004
+ const websocket = socketFactory(
14005
+ phoenixWebsocketUrl(baseUrl),
14006
+ phoenixWebsocketProtocols(token)
14007
+ );
13479
14008
  state.websocket = websocket;
13480
14009
  websocket.addEventListener("message", handleMessage);
13481
14010
  websocket.addEventListener(
@@ -13613,12 +14142,13 @@ function waitForOpen2(websocket) {
13613
14142
  );
13614
14143
  });
13615
14144
  }
13616
- var defaultPushTimeoutMs;
14145
+ var defaultPushTimeoutMs, phoenixAuthTokenProtocolPrefix;
13617
14146
  var init_phoenix = __esm({
13618
14147
  "src/phoenix.ts"() {
13619
14148
  "use strict";
13620
14149
  init_protocol();
13621
14150
  defaultPushTimeoutMs = 3e4;
14151
+ phoenixAuthTokenProtocolPrefix = "base64url.bearer.phx.";
13622
14152
  }
13623
14153
  });
13624
14154
 
@@ -13627,7 +14157,7 @@ var linzumiCliVersion, linzumiCliVersionText;
13627
14157
  var init_version = __esm({
13628
14158
  "src/version.ts"() {
13629
14159
  "use strict";
13630
- linzumiCliVersion = "0.0.73-beta";
14160
+ linzumiCliVersion = "0.0.74-beta";
13631
14161
  linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
13632
14162
  }
13633
14163
  });
@@ -13939,9 +14469,10 @@ function updateRunnerConsoleDashboard(state, event, payload, nowMs) {
13939
14469
  case "kandan.message_queued":
13940
14470
  case "codex.turn_starting": {
13941
14471
  const job = dashboardJobForPayload(state, payload, nowMs);
13942
- job.linzumiThreadId = stringValue3(payload.linzumi_thread_id) ?? job.linzumiThreadId;
13943
- job.codexThreadId = stringValue3(payload.codex_thread_id) ?? job.codexThreadId;
13944
- job.lastIncomingPreview = stringValue3(payload.body_preview) ?? job.lastIncomingPreview;
14472
+ job.linzumiThreadId = stringValue4(payload.linzumi_thread_id) ?? job.linzumiThreadId;
14473
+ job.linzumiThreadTitle = dashboardLinzumiThreadTitle(payload) ?? job.linzumiThreadTitle;
14474
+ job.codexThreadId = stringValue4(payload.codex_thread_id) ?? job.codexThreadId;
14475
+ job.lastIncomingPreview = stringValue4(payload.body_preview) ?? job.lastIncomingPreview;
13945
14476
  job.lastIncomingAtMs = numberValue(payload.message_received_at_ms) ?? job.lastIncomingAtMs;
13946
14477
  job.queueDepth = numberValue(payload.queue_depth) ?? job.queueDepth;
13947
14478
  job.eventType = dashboardEventLabel(event);
@@ -13949,28 +14480,28 @@ function updateRunnerConsoleDashboard(state, event, payload, nowMs) {
13949
14480
  break;
13950
14481
  }
13951
14482
  case "codex.notification": {
13952
- const tokenUsage = stringValue3(payload.token_usage_summary);
13953
- const rateLimit = stringValue3(payload.rate_limit_summary);
14483
+ const tokenUsage = stringValue4(payload.token_usage_summary);
14484
+ const rateLimit = stringValue4(payload.rate_limit_summary);
13954
14485
  if (tokenUsage !== void 0) {
13955
14486
  state.tokenUsage = tokenUsage;
13956
14487
  }
13957
14488
  if (rateLimit !== void 0) {
13958
14489
  state.rateLimit = mergeRateLimitSummary(state.rateLimit, rateLimit);
13959
14490
  }
13960
- const method = stringValue3(payload.method);
13961
- const metadata = objectValue4(payload.metadata);
13962
- const metadataHasJobSignal = stringValue3(metadata?.threadId) !== void 0 || stringValue3(metadata?.turnId) !== void 0 || stringValue3(metadata?.itemId) !== void 0;
14491
+ const method = stringValue4(payload.method);
14492
+ const metadata = objectValue5(payload.metadata);
14493
+ const metadataHasJobSignal = stringValue4(metadata?.threadId) !== void 0 || stringValue4(metadata?.turnId) !== void 0 || stringValue4(metadata?.itemId) !== void 0;
13963
14494
  if (!metadataHasJobSignal) {
13964
14495
  break;
13965
14496
  }
13966
- const codexThreadId = stringValue3(metadata?.threadId);
14497
+ const codexThreadId = stringValue4(metadata?.threadId);
13967
14498
  const job = codexThreadId === void 0 ? latestDashboardJob(state) : dashboardJobForKey(state, `codex:${codexThreadId}`, nowMs);
13968
14499
  if (job !== void 0) {
13969
14500
  job.codexThreadId = codexThreadId ?? job.codexThreadId;
13970
14501
  job.tokenUsage = tokenUsage ?? job.tokenUsage;
13971
14502
  job.latestCodexEventId = codexEventId(payload);
13972
14503
  job.eventType = method ?? event;
13973
- job.turnId = stringValue3(metadata?.turnId) ?? job.turnId;
14504
+ job.turnId = stringValue4(metadata?.turnId) ?? job.turnId;
13974
14505
  job.updatedAtMs = nowMs;
13975
14506
  }
13976
14507
  break;
@@ -13982,11 +14513,11 @@ function updateRunnerConsoleDashboard(state, event, payload, nowMs) {
13982
14513
  case "kandan.codex_file_change_forwarded":
13983
14514
  case "kandan.codex_web_search_progress_forwarded": {
13984
14515
  const job = dashboardJobForPayload(state, payload, nowMs);
13985
- job.latestCodexEventId = stringValue3(payload.item_key) ?? job.latestCodexEventId;
14516
+ job.latestCodexEventId = stringValue4(payload.item_key) ?? job.latestCodexEventId;
13986
14517
  job.eventType = codexOutputDashboardLabel(event, payload);
13987
- job.turnId = stringValue3(payload.turn_id) ?? job.turnId;
13988
- if (stringValue3(payload.structured_kind) === "codex_assistant_message") {
13989
- job.lastAssistantPreview = stringValue3(payload.body_preview) ?? job.lastAssistantPreview;
14518
+ job.turnId = stringValue4(payload.turn_id) ?? job.turnId;
14519
+ if (stringValue4(payload.structured_kind) === "codex_assistant_message") {
14520
+ job.lastAssistantPreview = stringValue4(payload.body_preview) ?? job.lastAssistantPreview;
13990
14521
  job.lastAssistantAtMs = nowMs;
13991
14522
  }
13992
14523
  job.updatedAtMs = nowMs;
@@ -14001,9 +14532,7 @@ function renderRunnerConsoleDashboard(state, nowMs) {
14001
14532
  if (state.jobs.size === 0 && state.tokenUsage === void 0 && state.rateLimit === void 0) {
14002
14533
  return void 0;
14003
14534
  }
14004
- const jobs = Array.from(state.jobs.values()).sort(
14005
- (left, right) => right.updatedAtMs - left.updatedAtMs
14006
- );
14535
+ const jobs = dashboardJobs(state);
14007
14536
  switch (state.mode.type) {
14008
14537
  case "table":
14009
14538
  return renderDashboardTable(state, jobs, nowMs);
@@ -14111,8 +14640,9 @@ function formatRunnerConsoleEvent(event, payload) {
14111
14640
  return `Codex turn started: id=${text(payload.turn_id)}`;
14112
14641
  case "codex.notification": {
14113
14642
  const summary = [
14114
- stringValue3(payload.token_usage_summary),
14115
- stringValue3(payload.rate_limit_summary)
14643
+ stringValue4(payload.token_usage_summary),
14644
+ stringValue4(payload.rate_limit_summary),
14645
+ stringValue4(payload.diagnostic_summary)
14116
14646
  ].filter((value) => value !== void 0).join(" | ");
14117
14647
  const suffix = summary === "" ? "" : ` ${summary}`;
14118
14648
  return `Codex event [id=${codexEventId(payload)}]: ${text(payload.method)}${suffix}`;
@@ -14149,11 +14679,11 @@ function connectedRunnerMessage(payload) {
14149
14679
  ].filter((line) => line !== void 0).join("\n");
14150
14680
  }
14151
14681
  function optionalLine(label, value) {
14152
- const normalized = stringValue3(value) ?? numberValue(value)?.toString();
14682
+ const normalized = stringValue4(value) ?? numberValue(value)?.toString();
14153
14683
  return normalized === void 0 ? void 0 : `${label}: ${normalized}`;
14154
14684
  }
14155
14685
  function optionalField(label, value) {
14156
- const normalized = stringValue3(value) ?? numberValue(value)?.toString();
14686
+ const normalized = stringValue4(value) ?? numberValue(value)?.toString();
14157
14687
  return normalized === void 0 ? void 0 : `${label}=${normalized}`;
14158
14688
  }
14159
14689
  function ignoredMessage(payload) {
@@ -14177,17 +14707,17 @@ function replacementLines(value) {
14177
14707
  return [];
14178
14708
  }
14179
14709
  const record = entry;
14180
- const runnerId = stringValue3(record.runnerId);
14710
+ const runnerId = stringValue4(record.runnerId);
14181
14711
  if (runnerId === void 0) {
14182
14712
  return [];
14183
14713
  }
14184
- const version = stringValue3(record.version);
14714
+ const version = stringValue4(record.version);
14185
14715
  const suffix = version === void 0 ? "" : ` (CLI ${version})`;
14186
14716
  return [`Replaced older runner from this machine: ${runnerId}${suffix}`];
14187
14717
  });
14188
14718
  }
14189
14719
  function sender(payload) {
14190
- const slug = stringValue3(payload.actor_slug);
14720
+ const slug = stringValue4(payload.actor_slug);
14191
14721
  const userId = numberValue(payload.actor_user_id);
14192
14722
  if (slug !== void 0 && userId !== void 0) {
14193
14723
  return `${slug}#${userId}`;
@@ -14195,7 +14725,7 @@ function sender(payload) {
14195
14725
  return slug ?? (userId === void 0 ? "unknown" : `user#${userId}`);
14196
14726
  }
14197
14727
  function codexOutputLabel(payload) {
14198
- const kind = stringValue3(payload.structured_kind) ?? "output";
14728
+ const kind = stringValue4(payload.structured_kind) ?? "output";
14199
14729
  switch (kind) {
14200
14730
  case "codex_assistant_message":
14201
14731
  return "assistant_message";
@@ -14221,7 +14751,7 @@ function codexEventId(payload) {
14221
14751
  const metadata = payload.metadata;
14222
14752
  if (typeof metadata === "object" && metadata !== null && !Array.isArray(metadata)) {
14223
14753
  const record = metadata;
14224
- return stringValue3(record.turnId) ?? stringValue3(record.itemId) ?? stringValue3(record.threadId) ?? "?";
14754
+ return stringValue4(record.turnId) ?? stringValue4(record.itemId) ?? stringValue4(record.threadId) ?? "?";
14225
14755
  }
14226
14756
  return "?";
14227
14757
  }
@@ -14237,8 +14767,8 @@ function rememberRawLine(state, event, payload, previousJobKey) {
14237
14767
  }
14238
14768
  }
14239
14769
  function dashboardRawLineJobKey(state, payload, previousJobKey) {
14240
- const linzumiThreadId = stringValue3(payload.linzumi_thread_id);
14241
- const codexThreadId = stringValue3(payload.codex_thread_id);
14770
+ const linzumiThreadId = stringValue4(payload.linzumi_thread_id);
14771
+ const codexThreadId = stringValue4(payload.codex_thread_id);
14242
14772
  if (linzumiThreadId !== void 0) {
14243
14773
  return `linzumi:${linzumiThreadId}`;
14244
14774
  }
@@ -14247,8 +14777,8 @@ function dashboardRawLineJobKey(state, payload, previousJobKey) {
14247
14777
  (job) => job.codexThreadId === codexThreadId
14248
14778
  )?.key;
14249
14779
  }
14250
- const metadata = objectValue4(payload.metadata);
14251
- const metadataCodexThreadId = stringValue3(metadata?.threadId);
14780
+ const metadata = objectValue5(payload.metadata);
14781
+ const metadataCodexThreadId = stringValue4(metadata?.threadId);
14252
14782
  if (metadataCodexThreadId !== void 0) {
14253
14783
  return Array.from(state.jobs.values()).find(
14254
14784
  (job) => job.codexThreadId === metadataCodexThreadId
@@ -14299,9 +14829,32 @@ function rawDashboardModel(state, mode) {
14299
14829
  }
14300
14830
  }
14301
14831
  function dashboardJobs(state) {
14302
- return Array.from(state.jobs.values()).sort(
14303
- (left, right) => right.updatedAtMs - left.updatedAtMs
14304
- );
14832
+ return Array.from(state.jobs.values()).sort(compareDashboardJobsByCreated);
14833
+ }
14834
+ function dashboardJobsByUpdatedAt(state) {
14835
+ return Array.from(state.jobs.values()).sort((left, right) => {
14836
+ const updated = right.updatedAtMs - left.updatedAtMs;
14837
+ if (updated !== 0) {
14838
+ return updated;
14839
+ }
14840
+ return compareDashboardJobsByCreated(left, right);
14841
+ });
14842
+ }
14843
+ function compareDashboardJobsByCreated(left, right) {
14844
+ const created = right.createdAtMs - left.createdAtMs;
14845
+ if (created !== 0) {
14846
+ return created;
14847
+ }
14848
+ const ordinal = right.createdOrdinal - left.createdOrdinal;
14849
+ if (ordinal !== 0) {
14850
+ return ordinal;
14851
+ }
14852
+ return left.key.localeCompare(right.key);
14853
+ }
14854
+ function nextDashboardJobOrdinal(state) {
14855
+ const ordinal = state.nextJobOrdinal;
14856
+ state.nextJobOrdinal = state.nextJobOrdinal + 1;
14857
+ return ordinal;
14305
14858
  }
14306
14859
  function selectDashboardJobAtVisibleIndex(state, index) {
14307
14860
  const jobs = dashboardJobs(state);
@@ -14620,8 +15173,8 @@ function updateRunnerConsoleDashboardMode(state, key) {
14620
15173
  }
14621
15174
  }
14622
15175
  function dashboardJobForPayload(state, payload, nowMs) {
14623
- const linzumiThreadId = stringValue3(payload.linzumi_thread_id);
14624
- const codexThreadId = stringValue3(payload.codex_thread_id);
15176
+ const linzumiThreadId = stringValue4(payload.linzumi_thread_id);
15177
+ const codexThreadId = stringValue4(payload.codex_thread_id);
14625
15178
  const existingByCodex = codexThreadId !== void 0 ? Array.from(state.jobs.values()).find(
14626
15179
  (job) => job.codexThreadId === codexThreadId
14627
15180
  ) : void 0;
@@ -14635,7 +15188,10 @@ function dashboardJobForPayload(state, payload, nowMs) {
14635
15188
  }
14636
15189
  const created = {
14637
15190
  key,
15191
+ createdAtMs: numberValue(payload.message_received_at_ms) ?? nowMs,
15192
+ createdOrdinal: nextDashboardJobOrdinal(state),
14638
15193
  linzumiThreadId,
15194
+ linzumiThreadTitle: dashboardLinzumiThreadTitle(payload),
14639
15195
  codexThreadId,
14640
15196
  tokenUsage: void 0,
14641
15197
  lastIncomingPreview: void 0,
@@ -14694,7 +15250,10 @@ function dashboardJobForKey(state, key, nowMs) {
14694
15250
  }
14695
15251
  const created = {
14696
15252
  key,
15253
+ createdAtMs: nowMs,
15254
+ createdOrdinal: nextDashboardJobOrdinal(state),
14697
15255
  linzumiThreadId: void 0,
15256
+ linzumiThreadTitle: void 0,
14698
15257
  codexThreadId: key.startsWith("codex:") ? key.slice("codex:".length) : void 0,
14699
15258
  tokenUsage: void 0,
14700
15259
  lastIncomingPreview: void 0,
@@ -14711,14 +15270,12 @@ function dashboardJobForKey(state, key, nowMs) {
14711
15270
  return created;
14712
15271
  }
14713
15272
  function latestDashboardJob(state) {
14714
- return Array.from(state.jobs.values()).sort(
14715
- (left, right) => right.updatedAtMs - left.updatedAtMs
14716
- )[0];
15273
+ return dashboardJobsByUpdatedAt(state)[0];
14717
15274
  }
14718
15275
  function jobRow(job, selectedJobKey, nowMs) {
14719
15276
  return [
14720
15277
  job.key === selectedJobKey ? ">" : " ",
14721
- shortId(job.linzumiThreadId),
15278
+ linzumiThreadLabel(job),
14722
15279
  agentId(job.codexThreadId),
14723
15280
  truncate(job.lastIncomingPreview ?? "?", 50),
14724
15281
  timeAgo(job.lastIncomingAtMs, nowMs),
@@ -14779,6 +15336,15 @@ function displayWidth(value) {
14779
15336
  function shortId(value) {
14780
15337
  return value === void 0 ? "?" : truncate(value, 18);
14781
15338
  }
15339
+ function linzumiThreadLabel(job) {
15340
+ if (job.linzumiThreadTitle === void 0) {
15341
+ return shortId(job.linzumiThreadId);
15342
+ }
15343
+ return firstN(job.linzumiThreadTitle, 30);
15344
+ }
15345
+ function dashboardLinzumiThreadTitle(payload) {
15346
+ return stringValue4(payload.linzumi_thread_title) ?? stringValue4(payload.thread_title) ?? stringValue4(payload.threadTitle) ?? stringValue4(payload.title);
15347
+ }
14782
15348
  function agentId(codexThreadId) {
14783
15349
  if (codexThreadId === void 0) {
14784
15350
  return "?";
@@ -14794,6 +15360,9 @@ function truncate(value, maxLength) {
14794
15360
  }
14795
15361
  return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
14796
15362
  }
15363
+ function firstN(value, maxLength) {
15364
+ return value.length <= maxLength ? value : value.slice(0, maxLength);
15365
+ }
14797
15366
  function lastFour(value) {
14798
15367
  if (value === void 0) {
14799
15368
  return "?";
@@ -14817,13 +15386,13 @@ function timeAgo(valueMs, nowMs) {
14817
15386
  }
14818
15387
  return `${Math.floor(minutes / 60)}h`;
14819
15388
  }
14820
- function objectValue4(value) {
15389
+ function objectValue5(value) {
14821
15390
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
14822
15391
  }
14823
15392
  function text(value) {
14824
- return stringValue3(value) ?? numberValue(value)?.toString() ?? "?";
15393
+ return stringValue4(value) ?? numberValue(value)?.toString() ?? "?";
14825
15394
  }
14826
- function stringValue3(value) {
15395
+ function stringValue4(value) {
14827
15396
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
14828
15397
  }
14829
15398
  function numberValue(value) {
@@ -14836,6 +15405,7 @@ var init_runnerConsoleReporter = __esm({
14836
15405
  dashboardState = {
14837
15406
  jobs: /* @__PURE__ */ new Map(),
14838
15407
  rawLines: [],
15408
+ nextJobOrdinal: 0,
14839
15409
  mode: { type: "table" },
14840
15410
  selectedJobKey: void 0,
14841
15411
  tokenUsage: void 0,
@@ -14850,7 +15420,7 @@ var init_runnerConsoleReporter = __esm({
14850
15420
  downKey = "\x1B[B";
14851
15421
  dashboardTableColumns = [
14852
15422
  { width: 1 },
14853
- { width: 20 },
15423
+ { width: 30 },
14854
15424
  { width: 16 },
14855
15425
  { width: 38 },
14856
15426
  { width: 6 },
@@ -15579,8 +16149,8 @@ import {
15579
16149
  statSync
15580
16150
  } from "node:fs";
15581
16151
  import { createServer as createServer3 } from "node:http";
15582
- import { homedir as homedir10, hostname as hostname2, tmpdir as tmpdir3 } from "node:os";
15583
- import { dirname as dirname9, join as join14, resolve as resolve7 } from "node:path";
16152
+ import { hostname as hostname2, tmpdir as tmpdir3 } from "node:os";
16153
+ import { dirname as dirname9, isAbsolute as isAbsolute3, join as join14, resolve as resolve7 } from "node:path";
15584
16154
  async function runLocalCodexRunner(options) {
15585
16155
  const log = makeRunnerLogger(options);
15586
16156
  const cleanup = {
@@ -16743,6 +17313,11 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
16743
17313
  }
16744
17314
  const spawnThreadRunner = options.spawnThreadRunner ?? spawnLocalThreadRunnerProcess;
16745
17315
  const readyTimeoutMs = threadRunnerReadyTimeoutMs(options);
17316
+ log("runner.thread_process_starting", {
17317
+ kandanThreadId,
17318
+ cwd,
17319
+ readyTimeoutMs
17320
+ });
16746
17321
  const startingEntry = {
16747
17322
  kind: "starting",
16748
17323
  promise: withThreadRunnerReadyTimeout(
@@ -16770,6 +17345,11 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
16770
17345
  if (threadRunnerProcesses.get(kandanThreadId) === startingEntry) {
16771
17346
  threadRunnerProcesses.delete(kandanThreadId);
16772
17347
  }
17348
+ log("runner.thread_process_start_failed", {
17349
+ kandanThreadId,
17350
+ cwd,
17351
+ message: error instanceof Error ? error.message : String(error)
17352
+ });
16773
17353
  throw error;
16774
17354
  }
16775
17355
  for (const port of handle.commanderManagedPorts ?? []) {
@@ -17538,6 +18118,11 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
17538
18118
  }
17539
18119
  const agentProvider = agentProviderResult.provider;
17540
18120
  if (!cwd.ok) {
18121
+ log("kandan.start_instance_cwd_rejected", {
18122
+ thread_id: controlThreadId(control) ?? null,
18123
+ reason: cwd.reason,
18124
+ allowedCwdCount: allowedCwds.value.length
18125
+ });
17541
18126
  try {
17542
18127
  await publishStartInstanceCwdFailureMessageState(
17543
18128
  kandan,
@@ -19757,13 +20342,8 @@ async function closeThreadRunnerEntry(entry) {
19757
20342
  }
19758
20343
  }
19759
20344
  async function spawnLocalThreadRunnerProcess(options) {
19760
- const scriptPath = process.argv[1];
20345
+ const scriptPath = threadRunnerScriptPath(process.argv[1], process.cwd());
19761
20346
  const kandanThreadId = options.threadProcess?.kandanThreadId ?? "";
19762
- if (scriptPath === void 0 || scriptPath.trim() === "") {
19763
- throw new Error(
19764
- "cannot fork thread runner without current CLI script path"
19765
- );
19766
- }
19767
20347
  const args = ["run", ...threadRunnerCliArgs(options)];
19768
20348
  const nodeArgs = threadRunnerNodeArgs(scriptPath, args);
19769
20349
  const redactedNodeArgs = threadRunnerNodeArgs(
@@ -19891,6 +20471,14 @@ async function spawnLocalThreadRunnerProcess(options) {
19891
20471
  function threadRunnerNodeArgs(scriptPath, args) {
19892
20472
  return [...threadRunnerLoaderExecArgv(process.execArgv), scriptPath, ...args];
19893
20473
  }
20474
+ function threadRunnerScriptPath(scriptPath, cwd) {
20475
+ if (scriptPath === void 0 || scriptPath.trim() === "") {
20476
+ throw new Error(
20477
+ "cannot fork thread runner without current CLI script path"
20478
+ );
20479
+ }
20480
+ return isAbsolute3(scriptPath) ? scriptPath : resolve7(cwd, scriptPath);
20481
+ }
19894
20482
  function threadRunnerLoaderExecArgv(execArgv, index = 0) {
19895
20483
  const current = execArgv[index];
19896
20484
  if (current === void 0) {
@@ -20269,7 +20857,7 @@ function isGitProjectDirectory(cwd) {
20269
20857
  }
20270
20858
  function browseRunnerDirectory(control, options) {
20271
20859
  const requestId = stringValue(control.requestId) ?? null;
20272
- const requestedPath = stringValue(control.path) ?? homedir10();
20860
+ const requestedPath = stringValue(control.path) ?? currentHomeDirectory();
20273
20861
  try {
20274
20862
  const currentPath = realpathSync5(resolve7(expandUserPath(requestedPath)));
20275
20863
  const stats = statSync(currentPath);
@@ -20300,7 +20888,7 @@ function browseRunnerDirectory(control, options) {
20300
20888
  ok: true,
20301
20889
  currentPath,
20302
20890
  parentPath: parent === currentPath ? null : parent,
20303
- homePath: homedir10(),
20891
+ homePath: currentHomeDirectory(),
20304
20892
  runnerCwd: resolve7(options.cwd),
20305
20893
  entries,
20306
20894
  isGit: isGitProjectDirectory(currentPath)
@@ -20353,7 +20941,7 @@ function createRunnerProject(control, options, allowedCwds) {
20353
20941
  error: "invalid_project_template"
20354
20942
  };
20355
20943
  }
20356
- const projectsRoot = join14(homedir10(), "linzumi");
20944
+ const projectsRoot = join14(currentHomeDirectory(), "linzumi");
20357
20945
  const resolvedProjectDirName = template === "hello_linzumi_demo" ? availableProjectDirectoryName(projectsRoot, projectDirName) : projectDirName;
20358
20946
  const projectPath = join14(projectsRoot, resolvedProjectDirName);
20359
20947
  let createdProjectPath = false;
@@ -20380,16 +20968,18 @@ function createRunnerProject(control, options, allowedCwds) {
20380
20968
  }
20381
20969
  const git = spawnSync4("git", ["init"], {
20382
20970
  cwd: projectPath,
20383
- encoding: "utf8"
20971
+ encoding: "utf8",
20972
+ env: process.env
20384
20973
  });
20385
20974
  if (git.status !== 0) {
20386
20975
  const cleanupError = removeCreatedProjectDirectory(projectPath);
20976
+ const gitFailure = git.error instanceof Error ? git.error.message : git.stderr || git.stdout || git.status;
20387
20977
  return {
20388
20978
  instanceId: options.runnerId,
20389
20979
  controlType: control.type,
20390
20980
  requestId,
20391
20981
  ok: false,
20392
- error: cleanupError === void 0 ? `git_init_failed:${git.stderr || git.stdout || git.status}` : `git_init_cleanup_failed:${cleanupError}`
20982
+ error: cleanupError === void 0 ? `git_init_failed:${gitFailure}` : `git_init_cleanup_failed:${cleanupError}`
20393
20983
  };
20394
20984
  }
20395
20985
  const projectRealPath = realpathSync5(projectPath);
@@ -20569,9 +21159,12 @@ function trustedWebSocketFactory(trust, WebSocketImpl = WsWebSocket) {
20569
21159
  if (trust === void 0) {
20570
21160
  return void 0;
20571
21161
  }
20572
- return (url) => new WebSocketImpl(url, {
20573
- ca: trust.ca
20574
- });
21162
+ return (url, protocols) => {
21163
+ const options = {
21164
+ ca: trust.ca
21165
+ };
21166
+ return protocols === void 0 ? new WebSocketImpl(url, options) : new WebSocketImpl(url, protocols, options);
21167
+ };
20575
21168
  }
20576
21169
  var init_kandanTls = __esm({
20577
21170
  "src/kandanTls.ts"() {
@@ -35491,7 +36084,7 @@ var require_safer = __commonJS({
35491
36084
  "../../node_modules/safer-buffer/safer.js"(exports, module) {
35492
36085
  "use strict";
35493
36086
  var buffer = __require("buffer");
35494
- var Buffer3 = buffer.Buffer;
36087
+ var Buffer4 = buffer.Buffer;
35495
36088
  var safer = {};
35496
36089
  var key;
35497
36090
  for (key in buffer) {
@@ -35500,12 +36093,12 @@ var require_safer = __commonJS({
35500
36093
  safer[key] = buffer[key];
35501
36094
  }
35502
36095
  var Safer = safer.Buffer = {};
35503
- for (key in Buffer3) {
35504
- if (!Buffer3.hasOwnProperty(key)) continue;
36096
+ for (key in Buffer4) {
36097
+ if (!Buffer4.hasOwnProperty(key)) continue;
35505
36098
  if (key === "allocUnsafe" || key === "allocUnsafeSlow") continue;
35506
- Safer[key] = Buffer3[key];
36099
+ Safer[key] = Buffer4[key];
35507
36100
  }
35508
- safer.Buffer.prototype = Buffer3.prototype;
36101
+ safer.Buffer.prototype = Buffer4.prototype;
35509
36102
  if (!Safer.from || Safer.from === Uint8Array.from) {
35510
36103
  Safer.from = function(value, encodingOrOffset, length) {
35511
36104
  if (typeof value === "number") {
@@ -35514,7 +36107,7 @@ var require_safer = __commonJS({
35514
36107
  if (value && typeof value.length === "undefined") {
35515
36108
  throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value);
35516
36109
  }
35517
- return Buffer3(value, encodingOrOffset, length);
36110
+ return Buffer4(value, encodingOrOffset, length);
35518
36111
  };
35519
36112
  }
35520
36113
  if (!Safer.alloc) {
@@ -35525,7 +36118,7 @@ var require_safer = __commonJS({
35525
36118
  if (size < 0 || size >= 2 * (1 << 30)) {
35526
36119
  throw new RangeError('The value "' + size + '" is invalid for option "size"');
35527
36120
  }
35528
- var buf = Buffer3(size);
36121
+ var buf = Buffer4(size);
35529
36122
  if (!fill || fill.length === 0) {
35530
36123
  buf.fill(0);
35531
36124
  } else if (typeof encoding === "string") {
@@ -35620,7 +36213,7 @@ var require_merge_exports = __commonJS({
35620
36213
  var require_internal = __commonJS({
35621
36214
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/internal.js"(exports, module) {
35622
36215
  "use strict";
35623
- var Buffer3 = require_safer().Buffer;
36216
+ var Buffer4 = require_safer().Buffer;
35624
36217
  module.exports = {
35625
36218
  // Encodings
35626
36219
  utf8: { type: "_internal", bomAware: true },
@@ -35644,7 +36237,7 @@ var require_internal = __commonJS({
35644
36237
  } else if (this.enc === "cesu8") {
35645
36238
  this.enc = "utf8";
35646
36239
  this.encoder = InternalEncoderCesu8;
35647
- if (Buffer3.from("eda0bdedb2a9", "hex").toString() !== "\u{1F4A9}") {
36240
+ if (Buffer4.from("eda0bdedb2a9", "hex").toString() !== "\u{1F4A9}") {
35648
36241
  this.decoder = InternalDecoderCesu8;
35649
36242
  this.defaultCharUnicode = iconv2.defaultCharUnicode;
35650
36243
  }
@@ -35657,8 +36250,8 @@ var require_internal = __commonJS({
35657
36250
  this.decoder = new StringDecoder(codec.enc);
35658
36251
  }
35659
36252
  InternalDecoder.prototype.write = function(buf) {
35660
- if (!Buffer3.isBuffer(buf)) {
35661
- buf = Buffer3.from(buf);
36253
+ if (!Buffer4.isBuffer(buf)) {
36254
+ buf = Buffer4.from(buf);
35662
36255
  }
35663
36256
  return this.decoder.write(buf);
35664
36257
  };
@@ -35669,7 +36262,7 @@ var require_internal = __commonJS({
35669
36262
  this.enc = codec.enc;
35670
36263
  }
35671
36264
  InternalEncoder.prototype.write = function(str) {
35672
- return Buffer3.from(str, this.enc);
36265
+ return Buffer4.from(str, this.enc);
35673
36266
  };
35674
36267
  InternalEncoder.prototype.end = function() {
35675
36268
  };
@@ -35681,15 +36274,15 @@ var require_internal = __commonJS({
35681
36274
  var completeQuads = str.length - str.length % 4;
35682
36275
  this.prevStr = str.slice(completeQuads);
35683
36276
  str = str.slice(0, completeQuads);
35684
- return Buffer3.from(str, "base64");
36277
+ return Buffer4.from(str, "base64");
35685
36278
  };
35686
36279
  InternalEncoderBase64.prototype.end = function() {
35687
- return Buffer3.from(this.prevStr, "base64");
36280
+ return Buffer4.from(this.prevStr, "base64");
35688
36281
  };
35689
36282
  function InternalEncoderCesu8(options, codec) {
35690
36283
  }
35691
36284
  InternalEncoderCesu8.prototype.write = function(str) {
35692
- var buf = Buffer3.alloc(str.length * 3);
36285
+ var buf = Buffer4.alloc(str.length * 3);
35693
36286
  var bufIdx = 0;
35694
36287
  for (var i = 0; i < str.length; i++) {
35695
36288
  var charCode = str.charCodeAt(i);
@@ -35785,13 +36378,13 @@ var require_internal = __commonJS({
35785
36378
  str = str.slice(0, str.length - 1);
35786
36379
  }
35787
36380
  }
35788
- return Buffer3.from(str, this.enc);
36381
+ return Buffer4.from(str, this.enc);
35789
36382
  };
35790
36383
  InternalEncoderUtf8.prototype.end = function() {
35791
36384
  if (this.highSurrogate) {
35792
36385
  var str = this.highSurrogate;
35793
36386
  this.highSurrogate = "";
35794
- return Buffer3.from(str, this.enc);
36387
+ return Buffer4.from(str, this.enc);
35795
36388
  }
35796
36389
  };
35797
36390
  }
@@ -35801,7 +36394,7 @@ var require_internal = __commonJS({
35801
36394
  var require_utf32 = __commonJS({
35802
36395
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/utf32.js"(exports) {
35803
36396
  "use strict";
35804
- var Buffer3 = require_safer().Buffer;
36397
+ var Buffer4 = require_safer().Buffer;
35805
36398
  exports._utf32 = Utf32Codec;
35806
36399
  function Utf32Codec(codecOptions, iconv2) {
35807
36400
  this.iconv = iconv2;
@@ -35819,8 +36412,8 @@ var require_utf32 = __commonJS({
35819
36412
  this.highSurrogate = 0;
35820
36413
  }
35821
36414
  Utf32Encoder.prototype.write = function(str) {
35822
- var src = Buffer3.from(str, "ucs2");
35823
- var dst = Buffer3.alloc(src.length * 2);
36415
+ var src = Buffer4.from(str, "ucs2");
36416
+ var dst = Buffer4.alloc(src.length * 2);
35824
36417
  var write32 = this.isLE ? dst.writeUInt32LE : dst.writeUInt32BE;
35825
36418
  var offset = 0;
35826
36419
  for (var i = 0; i < src.length; i += 2) {
@@ -35856,7 +36449,7 @@ var require_utf32 = __commonJS({
35856
36449
  if (!this.highSurrogate) {
35857
36450
  return;
35858
36451
  }
35859
- var buf = Buffer3.alloc(4);
36452
+ var buf = Buffer4.alloc(4);
35860
36453
  if (this.isLE) {
35861
36454
  buf.writeUInt32LE(this.highSurrogate, 0);
35862
36455
  } else {
@@ -35876,7 +36469,7 @@ var require_utf32 = __commonJS({
35876
36469
  }
35877
36470
  var i = 0;
35878
36471
  var codepoint = 0;
35879
- var dst = Buffer3.alloc(src.length + 4);
36472
+ var dst = Buffer4.alloc(src.length + 4);
35880
36473
  var offset = 0;
35881
36474
  var isLE = this.isLE;
35882
36475
  var overflow = this.overflow;
@@ -36032,7 +36625,7 @@ var require_utf32 = __commonJS({
36032
36625
  var require_utf16 = __commonJS({
36033
36626
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/utf16.js"(exports) {
36034
36627
  "use strict";
36035
- var Buffer3 = require_safer().Buffer;
36628
+ var Buffer4 = require_safer().Buffer;
36036
36629
  exports.utf16be = Utf16BECodec;
36037
36630
  function Utf16BECodec() {
36038
36631
  }
@@ -36042,7 +36635,7 @@ var require_utf16 = __commonJS({
36042
36635
  function Utf16BEEncoder() {
36043
36636
  }
36044
36637
  Utf16BEEncoder.prototype.write = function(str) {
36045
- var buf = Buffer3.from(str, "ucs2");
36638
+ var buf = Buffer4.from(str, "ucs2");
36046
36639
  for (var i = 0; i < buf.length; i += 2) {
36047
36640
  var tmp = buf[i];
36048
36641
  buf[i] = buf[i + 1];
@@ -36059,7 +36652,7 @@ var require_utf16 = __commonJS({
36059
36652
  if (buf.length == 0) {
36060
36653
  return "";
36061
36654
  }
36062
- var buf2 = Buffer3.alloc(buf.length + 1);
36655
+ var buf2 = Buffer4.alloc(buf.length + 1);
36063
36656
  var i = 0;
36064
36657
  var j = 0;
36065
36658
  if (this.overflowByte !== -1) {
@@ -36175,7 +36768,7 @@ var require_utf16 = __commonJS({
36175
36768
  var require_utf7 = __commonJS({
36176
36769
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/utf7.js"(exports) {
36177
36770
  "use strict";
36178
- var Buffer3 = require_safer().Buffer;
36771
+ var Buffer4 = require_safer().Buffer;
36179
36772
  exports.utf7 = Utf7Codec;
36180
36773
  exports.unicode11utf7 = "utf7";
36181
36774
  function Utf7Codec(codecOptions, iconv2) {
@@ -36189,7 +36782,7 @@ var require_utf7 = __commonJS({
36189
36782
  this.iconv = codec.iconv;
36190
36783
  }
36191
36784
  Utf7Encoder.prototype.write = function(str) {
36192
- return Buffer3.from(str.replace(nonDirectChars, function(chunk) {
36785
+ return Buffer4.from(str.replace(nonDirectChars, function(chunk) {
36193
36786
  return "+" + (chunk === "+" ? "" : this.iconv.encode(chunk, "utf16-be").toString("base64").replace(/=+$/, "")) + "-";
36194
36787
  }.bind(this)));
36195
36788
  };
@@ -36227,7 +36820,7 @@ var require_utf7 = __commonJS({
36227
36820
  res += "+";
36228
36821
  } else {
36229
36822
  var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i2), "ascii");
36230
- res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be");
36823
+ res += this.iconv.decode(Buffer4.from(b64str, "base64"), "utf16-be");
36231
36824
  }
36232
36825
  if (buf[i2] != minusChar) {
36233
36826
  i2--;
@@ -36245,7 +36838,7 @@ var require_utf7 = __commonJS({
36245
36838
  var canBeDecoded = b64str.length - b64str.length % 8;
36246
36839
  base64Accum = b64str.slice(canBeDecoded);
36247
36840
  b64str = b64str.slice(0, canBeDecoded);
36248
- res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be");
36841
+ res += this.iconv.decode(Buffer4.from(b64str, "base64"), "utf16-be");
36249
36842
  }
36250
36843
  this.inBase64 = inBase64;
36251
36844
  this.base64Accum = base64Accum;
@@ -36254,7 +36847,7 @@ var require_utf7 = __commonJS({
36254
36847
  Utf7Decoder.prototype.end = function() {
36255
36848
  var res = "";
36256
36849
  if (this.inBase64 && this.base64Accum.length > 0) {
36257
- res = this.iconv.decode(Buffer3.from(this.base64Accum, "base64"), "utf16-be");
36850
+ res = this.iconv.decode(Buffer4.from(this.base64Accum, "base64"), "utf16-be");
36258
36851
  }
36259
36852
  this.inBase64 = false;
36260
36853
  this.base64Accum = "";
@@ -36270,14 +36863,14 @@ var require_utf7 = __commonJS({
36270
36863
  function Utf7IMAPEncoder(options, codec) {
36271
36864
  this.iconv = codec.iconv;
36272
36865
  this.inBase64 = false;
36273
- this.base64Accum = Buffer3.alloc(6);
36866
+ this.base64Accum = Buffer4.alloc(6);
36274
36867
  this.base64AccumIdx = 0;
36275
36868
  }
36276
36869
  Utf7IMAPEncoder.prototype.write = function(str) {
36277
36870
  var inBase64 = this.inBase64;
36278
36871
  var base64Accum = this.base64Accum;
36279
36872
  var base64AccumIdx = this.base64AccumIdx;
36280
- var buf = Buffer3.alloc(str.length * 5 + 10);
36873
+ var buf = Buffer4.alloc(str.length * 5 + 10);
36281
36874
  var bufIdx = 0;
36282
36875
  for (var i2 = 0; i2 < str.length; i2++) {
36283
36876
  var uChar = str.charCodeAt(i2);
@@ -36316,7 +36909,7 @@ var require_utf7 = __commonJS({
36316
36909
  return buf.slice(0, bufIdx);
36317
36910
  };
36318
36911
  Utf7IMAPEncoder.prototype.end = function() {
36319
- var buf = Buffer3.alloc(10);
36912
+ var buf = Buffer4.alloc(10);
36320
36913
  var bufIdx = 0;
36321
36914
  if (this.inBase64) {
36322
36915
  if (this.base64AccumIdx > 0) {
@@ -36353,7 +36946,7 @@ var require_utf7 = __commonJS({
36353
36946
  res += "&";
36354
36947
  } else {
36355
36948
  var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i2), "ascii").replace(/,/g, "/");
36356
- res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be");
36949
+ res += this.iconv.decode(Buffer4.from(b64str, "base64"), "utf16-be");
36357
36950
  }
36358
36951
  if (buf[i2] != minusChar) {
36359
36952
  i2--;
@@ -36371,7 +36964,7 @@ var require_utf7 = __commonJS({
36371
36964
  var canBeDecoded = b64str.length - b64str.length % 8;
36372
36965
  base64Accum = b64str.slice(canBeDecoded);
36373
36966
  b64str = b64str.slice(0, canBeDecoded);
36374
- res += this.iconv.decode(Buffer3.from(b64str, "base64"), "utf16-be");
36967
+ res += this.iconv.decode(Buffer4.from(b64str, "base64"), "utf16-be");
36375
36968
  }
36376
36969
  this.inBase64 = inBase64;
36377
36970
  this.base64Accum = base64Accum;
@@ -36380,7 +36973,7 @@ var require_utf7 = __commonJS({
36380
36973
  Utf7IMAPDecoder.prototype.end = function() {
36381
36974
  var res = "";
36382
36975
  if (this.inBase64 && this.base64Accum.length > 0) {
36383
- res = this.iconv.decode(Buffer3.from(this.base64Accum, "base64"), "utf16-be");
36976
+ res = this.iconv.decode(Buffer4.from(this.base64Accum, "base64"), "utf16-be");
36384
36977
  }
36385
36978
  this.inBase64 = false;
36386
36979
  this.base64Accum = "";
@@ -36393,7 +36986,7 @@ var require_utf7 = __commonJS({
36393
36986
  var require_sbcs_codec = __commonJS({
36394
36987
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/sbcs-codec.js"(exports) {
36395
36988
  "use strict";
36396
- var Buffer3 = require_safer().Buffer;
36989
+ var Buffer4 = require_safer().Buffer;
36397
36990
  exports._sbcs = SBCSCodec;
36398
36991
  function SBCSCodec(codecOptions, iconv2) {
36399
36992
  if (!codecOptions) {
@@ -36409,8 +37002,8 @@ var require_sbcs_codec = __commonJS({
36409
37002
  }
36410
37003
  codecOptions.chars = asciiString + codecOptions.chars;
36411
37004
  }
36412
- this.decodeBuf = Buffer3.from(codecOptions.chars, "ucs2");
36413
- var encodeBuf = Buffer3.alloc(65536, iconv2.defaultCharSingleByte.charCodeAt(0));
37005
+ this.decodeBuf = Buffer4.from(codecOptions.chars, "ucs2");
37006
+ var encodeBuf = Buffer4.alloc(65536, iconv2.defaultCharSingleByte.charCodeAt(0));
36414
37007
  for (var i = 0; i < codecOptions.chars.length; i++) {
36415
37008
  encodeBuf[codecOptions.chars.charCodeAt(i)] = i;
36416
37009
  }
@@ -36422,7 +37015,7 @@ var require_sbcs_codec = __commonJS({
36422
37015
  this.encodeBuf = codec.encodeBuf;
36423
37016
  }
36424
37017
  SBCSEncoder.prototype.write = function(str) {
36425
- var buf = Buffer3.alloc(str.length);
37018
+ var buf = Buffer4.alloc(str.length);
36426
37019
  for (var i = 0; i < str.length; i++) {
36427
37020
  buf[i] = this.encodeBuf[str.charCodeAt(i)];
36428
37021
  }
@@ -36435,7 +37028,7 @@ var require_sbcs_codec = __commonJS({
36435
37028
  }
36436
37029
  SBCSDecoder.prototype.write = function(buf) {
36437
37030
  var decodeBuf = this.decodeBuf;
36438
- var newBuf = Buffer3.alloc(buf.length * 2);
37031
+ var newBuf = Buffer4.alloc(buf.length * 2);
36439
37032
  var idx1 = 0;
36440
37033
  var idx2 = 0;
36441
37034
  for (var i = 0; i < buf.length; i++) {
@@ -37063,7 +37656,7 @@ var require_sbcs_data_generated = __commonJS({
37063
37656
  var require_dbcs_codec = __commonJS({
37064
37657
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/encodings/dbcs-codec.js"(exports) {
37065
37658
  "use strict";
37066
- var Buffer3 = require_safer().Buffer;
37659
+ var Buffer4 = require_safer().Buffer;
37067
37660
  exports._dbcs = DBCSCodec;
37068
37661
  var UNASSIGNED = -1;
37069
37662
  var GB18030_CODE = -2;
@@ -37299,7 +37892,7 @@ var require_dbcs_codec = __commonJS({
37299
37892
  this.gb18030 = codec.gb18030;
37300
37893
  }
37301
37894
  DBCSEncoder.prototype.write = function(str) {
37302
- var newBuf = Buffer3.alloc(str.length * (this.gb18030 ? 4 : 3));
37895
+ var newBuf = Buffer4.alloc(str.length * (this.gb18030 ? 4 : 3));
37303
37896
  var leadSurrogate = this.leadSurrogate;
37304
37897
  var seqObj = this.seqObj;
37305
37898
  var nextChar = -1;
@@ -37403,7 +37996,7 @@ var require_dbcs_codec = __commonJS({
37403
37996
  if (this.leadSurrogate === -1 && this.seqObj === void 0) {
37404
37997
  return;
37405
37998
  }
37406
- var newBuf = Buffer3.alloc(10);
37999
+ var newBuf = Buffer4.alloc(10);
37407
38000
  var j = 0;
37408
38001
  if (this.seqObj) {
37409
38002
  var dbcsCode = this.seqObj[DEF_CHAR];
@@ -37434,7 +38027,7 @@ var require_dbcs_codec = __commonJS({
37434
38027
  this.gb18030 = codec.gb18030;
37435
38028
  }
37436
38029
  DBCSDecoder.prototype.write = function(buf) {
37437
- var newBuf = Buffer3.alloc(buf.length * 2);
38030
+ var newBuf = Buffer4.alloc(buf.length * 2);
37438
38031
  var nodeIdx = this.nodeIdx;
37439
38032
  var prevBytes = this.prevBytes;
37440
38033
  var prevOffset = this.prevBytes.length;
@@ -39043,7 +39636,7 @@ var require_encodings = __commonJS({
39043
39636
  var require_streams = __commonJS({
39044
39637
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/lib/streams.js"(exports, module) {
39045
39638
  "use strict";
39046
- var Buffer3 = require_safer().Buffer;
39639
+ var Buffer4 = require_safer().Buffer;
39047
39640
  module.exports = function(streamModule) {
39048
39641
  var Transform = streamModule.Transform;
39049
39642
  function IconvLiteEncoderStream(conv, options) {
@@ -39083,7 +39676,7 @@ var require_streams = __commonJS({
39083
39676
  chunks.push(chunk);
39084
39677
  });
39085
39678
  this.on("end", function() {
39086
- cb(null, Buffer3.concat(chunks));
39679
+ cb(null, Buffer4.concat(chunks));
39087
39680
  });
39088
39681
  return this;
39089
39682
  };
@@ -39097,7 +39690,7 @@ var require_streams = __commonJS({
39097
39690
  constructor: { value: IconvLiteDecoderStream }
39098
39691
  });
39099
39692
  IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) {
39100
- if (!Buffer3.isBuffer(chunk) && !(chunk instanceof Uint8Array)) {
39693
+ if (!Buffer4.isBuffer(chunk) && !(chunk instanceof Uint8Array)) {
39101
39694
  return done(new Error("Iconv decoding stream needs buffers as its input."));
39102
39695
  }
39103
39696
  try {
@@ -39140,7 +39733,7 @@ var require_streams = __commonJS({
39140
39733
  var require_lib3 = __commonJS({
39141
39734
  "../../node_modules/@inquirer/external-editor/node_modules/iconv-lite/lib/index.js"(exports, module) {
39142
39735
  "use strict";
39143
- var Buffer3 = require_safer().Buffer;
39736
+ var Buffer4 = require_safer().Buffer;
39144
39737
  var bomHandling = require_bom_handling();
39145
39738
  var mergeModules = require_merge_exports();
39146
39739
  var iconv2 = module.exports;
@@ -39152,7 +39745,7 @@ var require_lib3 = __commonJS({
39152
39745
  var encoder = iconv2.getEncoder(encoding, options);
39153
39746
  var res = encoder.write(str);
39154
39747
  var trail = encoder.end();
39155
- return trail && trail.length > 0 ? Buffer3.concat([res, trail]) : res;
39748
+ return trail && trail.length > 0 ? Buffer4.concat([res, trail]) : res;
39156
39749
  };
39157
39750
  iconv2.decode = function decode(buf, encoding, options) {
39158
39751
  if (typeof buf === "string") {
@@ -39160,7 +39753,7 @@ var require_lib3 = __commonJS({
39160
39753
  console.error("Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding");
39161
39754
  iconv2.skipDecodeWarning = true;
39162
39755
  }
39163
- buf = Buffer3.from("" + (buf || ""), "binary");
39756
+ buf = Buffer4.from("" + (buf || ""), "binary");
39164
39757
  }
39165
39758
  var decoder = iconv2.getDecoder(encoding, options);
39166
39759
  var res = decoder.write(buf);
@@ -40590,15 +41183,15 @@ function signupErrorCodeFromResponseText(text2) {
40590
41183
  function renderEmailCodeStart(value) {
40591
41184
  const body = objectRecord(value, "signup email-code start response");
40592
41185
  return {
40593
- pendingId: stringValue5(body, "pending_id"),
40594
- email: stringValue5(body, "email")
41186
+ pendingId: stringValue6(body, "pending_id"),
41187
+ email: stringValue6(body, "email")
40595
41188
  };
40596
41189
  }
40597
41190
  function renderEmailCodeVerify(value) {
40598
41191
  const body = objectRecord(value, "signup email-code verify response");
40599
41192
  return {
40600
- accessToken: stringValue5(body, "access_token"),
40601
- refreshToken: stringValue5(body, "refresh_token"),
41193
+ accessToken: stringValue6(body, "access_token"),
41194
+ refreshToken: stringValue6(body, "refresh_token"),
40602
41195
  expiresInSeconds: positiveIntegerValue(body, "expires_in"),
40603
41196
  user: renderUserRef(requiredValue(body, "user")),
40604
41197
  isNewUser: booleanValue(body, "is_new_user"),
@@ -40638,7 +41231,7 @@ function renderMissionControlComplete(value) {
40638
41231
  localRunnerToken: renderLocalRunnerToken(
40639
41232
  requiredValue(body, "local_runner_token")
40640
41233
  ),
40641
- launchUrl: stringValue5(body, "launch_url"),
41234
+ launchUrl: stringValue6(body, "launch_url"),
40642
41235
  ...missionControlUrl === void 0 ? {} : { missionControlUrl },
40643
41236
  config: {
40644
41237
  allowedCwds: arrayValue2(config, "allowed_cwds").map(
@@ -40658,21 +41251,21 @@ function renderLocalRunnerToken(value) {
40658
41251
  const body = objectRecord(value, "signup local runner token");
40659
41252
  const expiresInSeconds = optionalPositiveIntegerValue(body, "expires_in");
40660
41253
  return {
40661
- accessToken: stringValue5(body, "access_token"),
41254
+ accessToken: stringValue6(body, "access_token"),
40662
41255
  ...expiresInSeconds === void 0 ? {} : { expiresInSeconds },
40663
- workspaceSlug: stringValue5(body, "workspace"),
40664
- channelSlug: stringValue5(body, "channel")
41256
+ workspaceSlug: stringValue6(body, "workspace"),
41257
+ channelSlug: stringValue6(body, "channel")
40665
41258
  };
40666
41259
  }
40667
41260
  function renderTaskStartResult(value) {
40668
41261
  const body = objectRecord(value, "signup task start");
40669
- const status = stringValue5(body, "status");
41262
+ const status = stringValue6(body, "status");
40670
41263
  if (status !== "queued" && status !== "started" && status !== "failed") {
40671
41264
  throw new Error("signup task start status was incomplete");
40672
41265
  }
40673
41266
  return {
40674
- threadId: stringValue5(body, "thread_id"),
40675
- title: stringValue5(body, "title"),
41267
+ threadId: stringValue6(body, "thread_id"),
41268
+ title: stringValue6(body, "title"),
40676
41269
  status,
40677
41270
  ...optionalStringValue(body, "runner_id") === void 0 ? {} : { runnerId: optionalStringValue(body, "runner_id") },
40678
41271
  ...optionalStringValue(body, "error") === void 0 ? {} : { error: optionalStringValue(body, "error") }
@@ -40682,7 +41275,7 @@ function renderUserRef(value) {
40682
41275
  const body = objectRecord(value, "signup user");
40683
41276
  return {
40684
41277
  id: positiveIntegerValue(body, "id"),
40685
- username: stringValue5(body, "username"),
41278
+ username: stringValue6(body, "username"),
40686
41279
  ...optionalStringValue(body, "display_name") === void 0 ? {} : { displayName: optionalStringValue(body, "display_name") },
40687
41280
  ...optionalStringValue(body, "primary_email") === void 0 ? {} : { primaryEmail: optionalStringValue(body, "primary_email") }
40688
41281
  };
@@ -40691,23 +41284,23 @@ function renderWorkspaceRef(value) {
40691
41284
  const body = objectRecord(value, "signup workspace");
40692
41285
  return {
40693
41286
  id: positiveIntegerValue(body, "id"),
40694
- slug: stringValue5(body, "slug"),
40695
- name: stringValue5(body, "name")
41287
+ slug: stringValue6(body, "slug"),
41288
+ name: stringValue6(body, "name")
40696
41289
  };
40697
41290
  }
40698
41291
  function renderChannelRef(value) {
40699
41292
  const body = objectRecord(value, "signup channel");
40700
41293
  return {
40701
41294
  id: positiveIntegerValue(body, "id"),
40702
- slug: stringValue5(body, "slug"),
40703
- name: stringValue5(body, "name")
41295
+ slug: stringValue6(body, "slug"),
41296
+ name: stringValue6(body, "name")
40704
41297
  };
40705
41298
  }
40706
41299
  function renderThreadRef(value) {
40707
41300
  const body = objectRecord(value, "signup thread");
40708
41301
  return {
40709
- threadId: stringValue5(body, "thread_id"),
40710
- title: stringValue5(body, "title"),
41302
+ threadId: stringValue6(body, "thread_id"),
41303
+ title: stringValue6(body, "title"),
40711
41304
  rootSeq: positiveIntegerValue(body, "root_seq"),
40712
41305
  threadSeq: positiveIntegerValue(body, "thread_seq")
40713
41306
  };
@@ -40725,7 +41318,7 @@ function requiredValue(record, key) {
40725
41318
  }
40726
41319
  return value;
40727
41320
  }
40728
- function stringValue5(record, key) {
41321
+ function stringValue6(record, key) {
40729
41322
  return stringFromUnknown(requiredValue(record, key), `signup ${key}`);
40730
41323
  }
40731
41324
  function optionalStringValue(record, key) {
@@ -40800,6 +41393,7 @@ __export(signupFlow_exports, {
40800
41393
  resolveSignupCodexCommandForTest: () => resolveSignupCodexCommandForTest,
40801
41394
  runSignupFlow: () => runSignupFlow,
40802
41395
  signupCodexTaskSuggestionProcessForTest: () => signupCodexTaskSuggestionProcessForTest,
41396
+ signupCommanderAllowedCwdsForTest: () => signupCommanderAllowedCwdsForTest,
40803
41397
  signupDiscoverProjectsForStartForTest: () => signupDiscoverProjectsForStartForTest,
40804
41398
  signupEmailPickerChoiceNamesForTest: () => signupEmailPickerChoiceNamesForTest,
40805
41399
  signupHelpText: () => signupHelpText,
@@ -40828,7 +41422,7 @@ import {
40828
41422
  writeFileSync as writeFileSync11
40829
41423
  } from "node:fs";
40830
41424
  import { access } from "node:fs/promises";
40831
- import { homedir as homedir13, tmpdir as tmpdir4 } from "node:os";
41425
+ import { homedir as homedir12, tmpdir as tmpdir4 } from "node:os";
40832
41426
  import { delimiter as delimiter3, dirname as dirname12, join as join17, resolve as resolve9 } from "node:path";
40833
41427
  import { stdin as defaultStdin, stdout as defaultStdout } from "node:process";
40834
41428
  import { emitKeypressEvents } from "node:readline";
@@ -42186,8 +42780,9 @@ async function signupCommanderRunnerOptions(args, runnerId) {
42186
42780
  codexUrl: void 0,
42187
42781
  launchTui: false,
42188
42782
  fast: false,
42189
- allowedCwds: Array.from(
42190
- /* @__PURE__ */ new Set([args.projectPath, ...args.selectedProjectPaths])
42783
+ allowedCwds: signupCommanderAllowedCwds(
42784
+ args.projectPath,
42785
+ args.selectedProjectPaths
42191
42786
  ),
42192
42787
  allowedForwardPorts: [],
42193
42788
  codeServerBin: editorRuntime.codeServerBin,
@@ -42204,6 +42799,12 @@ async function signupCommanderRunnerOptions(args, runnerId) {
42204
42799
  channelSession: void 0
42205
42800
  };
42206
42801
  }
42802
+ function signupCommanderAllowedCwds(projectPath, selectedProjectPaths) {
42803
+ return assertConfiguredAllowedCwds([projectPath, ...selectedProjectPaths]);
42804
+ }
42805
+ function signupCommanderAllowedCwdsForTest(projectPath, selectedProjectPaths) {
42806
+ return signupCommanderAllowedCwds(projectPath, selectedProjectPaths);
42807
+ }
42207
42808
  function signupConnectRestartCommand(args) {
42208
42809
  return [
42209
42810
  "npx",
@@ -43131,7 +43732,7 @@ async function runSignupPreflights(runtime) {
43131
43732
  function defaultPreflightRuntime() {
43132
43733
  return {
43133
43734
  cwd: process.cwd(),
43134
- homeDir: homedir13(),
43735
+ homeDir: homedir12(),
43135
43736
  probeTool,
43136
43737
  readGitEmail,
43137
43738
  discoverCodeRoots,
@@ -43340,7 +43941,7 @@ function codexTaskSuggestionProcess2(args) {
43340
43941
  function signupCodexTaskSuggestionProcessForTest(args) {
43341
43942
  return codexTaskSuggestionProcess2(args);
43342
43943
  }
43343
- async function resolveSignupCodexCommand(env = process.env, homeDir = homedir13(), executableExists = fileIsExecutable) {
43944
+ async function resolveSignupCodexCommand(env = process.env, homeDir = homedir12(), executableExists = fileIsExecutable) {
43344
43945
  const override = firstConfiguredValue([
43345
43946
  env.LINZUMI_SIGNUP_CODEX_BIN,
43346
43947
  env.LINZUMI_CODEX_BIN
@@ -43979,10 +44580,10 @@ function directoryExists(path2) {
43979
44580
  }
43980
44581
  function expandHomePath(path2) {
43981
44582
  if (path2 === "~") {
43982
- return homedir13();
44583
+ return homedir12();
43983
44584
  }
43984
44585
  if (path2.startsWith("~/")) {
43985
- return join17(homedir13(), path2.slice(2));
44586
+ return join17(homedir12(), path2.slice(2));
43986
44587
  }
43987
44588
  return resolve9(path2);
43988
44589
  }
@@ -44023,6 +44624,7 @@ var init_signupFlow = __esm({
44023
44624
  init_helloLinzumiProject();
44024
44625
  init_localEditorRuntime();
44025
44626
  init_runner();
44627
+ init_localCapabilities();
44026
44628
  init_kandanTls();
44027
44629
  init_userFacingErrors();
44028
44630
  maxSignupVerificationCodeAttempts = 3;
@@ -44071,7 +44673,7 @@ init_runner();
44071
44673
  init_claudeCodeSession();
44072
44674
  init_authCache();
44073
44675
  import { existsSync as existsSync13, readFileSync as readFileSync16, realpathSync as realpathSync6 } from "node:fs";
44074
- import { homedir as homedir14 } from "node:os";
44676
+ import { homedir as homedir13 } from "node:os";
44075
44677
  import { resolve as resolve10 } from "node:path";
44076
44678
  import { fileURLToPath as fileURLToPath4 } from "node:url";
44077
44679
 
@@ -44134,7 +44736,7 @@ init_json();
44134
44736
  init_defaultUrls();
44135
44737
  import { existsSync as existsSync10, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
44136
44738
  import { dirname as dirname10, join as join15 } from "node:path";
44137
- import { homedir as homedir11 } from "node:os";
44739
+ import { homedir as homedir10 } from "node:os";
44138
44740
  async function runAgentCliCommand(args, deps = {
44139
44741
  fetchImpl: fetch,
44140
44742
  stdout: process.stdout,
@@ -44842,7 +45444,7 @@ function agentTokenFile(flags) {
44842
45444
  return flags.get("agent-token-file") ?? defaultAgentTokenFilePath();
44843
45445
  }
44844
45446
  function defaultAgentTokenFilePath() {
44845
- return join15(homedir11(), ".linzumi", "agent-token.json");
45447
+ return join15(homedir10(), ".linzumi", "agent-token.json");
44846
45448
  }
44847
45449
  function normalizedApiUrl(apiUrl) {
44848
45450
  return apiUrl.endsWith("/") ? apiUrl : `${apiUrl}/`;
@@ -44950,13 +45552,13 @@ import {
44950
45552
  watch,
44951
45553
  writeFileSync as writeFileSync9
44952
45554
  } from "node:fs";
44953
- import { homedir as homedir12 } from "node:os";
45555
+ import { homedir as homedir11 } from "node:os";
44954
45556
  import { dirname as dirname11, join as join16, resolve as resolve8 } from "node:path";
44955
45557
  import { execFileSync, spawn as spawn8 } from "node:child_process";
44956
45558
  import { fileURLToPath as fileURLToPath3 } from "node:url";
44957
45559
  var connectedMarkers = ["Connected to Linzumi", "Runner connected:"];
44958
45560
  function commanderStatusDir() {
44959
- return join16(homedir12(), ".linzumi", "commanders");
45561
+ return join16(homedir11(), ".linzumi", "commanders");
44960
45562
  }
44961
45563
  function commanderStatusFile(runnerId, statusDir = commanderStatusDir()) {
44962
45564
  return join16(statusDir, `${safeRunnerId(runnerId)}.json`);
@@ -57004,12 +57606,14 @@ function createLinzumiMcpApiClient(options) {
57004
57606
  getMessage: (params) => request("GET", `${apiPrefix}/message`, params),
57005
57607
  getThread: (params) => request("GET", `${apiPrefix}/thread`, params),
57006
57608
  getChannel: (params) => request("GET", `${apiPrefix}/channel`, params),
57609
+ listVaultSecrets: (params) => request("GET", `${apiPrefix}/vault-secrets`, params),
57007
57610
  sendChannelMessage: (params) => request("POST", `${apiPrefix}/channel-message`, params),
57008
57611
  prepareMessageUploads: (params) => request("POST", `${apiPrefix}/message-uploads/prepare`, params),
57009
57612
  attachMessageFiles: (params) => request("POST", `${apiPrefix}/message-files/attach`, params),
57010
57613
  sendThreadReply: (params) => request("POST", `${apiPrefix}/thread-reply`, params),
57011
57614
  sendDm: (params) => request("POST", `${apiPrefix}/dm`, params),
57012
- dmOwner: (params) => request("POST", `${apiPrefix}/dm-owner`, params)
57615
+ dmOwner: (params) => request("POST", `${apiPrefix}/dm-owner`, params),
57616
+ getVaultValues: (params) => request("POST", `${apiPrefix}/vault-values`, params)
57013
57617
  };
57014
57618
  }
57015
57619
 
@@ -57066,12 +57670,16 @@ Tools:
57066
57670
  linzumi_get_message Read one message by scoped seq or Linzumi message URL.
57067
57671
  linzumi_get_thread Read one bounded thread by ID.
57068
57672
  linzumi_get_channel Read bounded recent messages and channel metadata.
57673
+ linzumi_list_vault_secrets
57674
+ List vault secret names, descriptions, and owner scope.
57069
57675
  linzumi_send_channel_message
57070
57676
  Send a plain-text message to the scoped channel.
57071
57677
  linzumi_send_thread_reply
57072
57678
  Send a plain-text reply to an existing scoped thread.
57073
57679
  linzumi_send_dm Send a plain-text DM to a visible user.
57074
57680
  linzumi_dm_owner Send a plain-text DM to the configured owner username.
57681
+ linzumi_get_vault_values
57682
+ Request approved named vault values for a thread.
57075
57683
 
57076
57684
  Auth:
57077
57685
  Uses --token, LINZUMI_MCP_ACCESS_TOKEN, or cached local runner OAuth from linzumi auth.
@@ -57087,16 +57695,16 @@ async function runMcpServer(args) {
57087
57695
  const kandanUrl = required(values, "api-url");
57088
57696
  const auth = await resolveMcpAuth({
57089
57697
  kandanUrl,
57090
- explicitToken: stringValue4(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
57091
- authFilePath: stringValue4(values, "auth-file"),
57092
- delegationAuthFilePath: stringValue4(values, "delegation-auth-file"),
57093
- workspaceSlug: stringValue4(values, "workspace"),
57094
- channelSlug: stringValue4(values, "channel")
57095
- });
57096
- const ownerUsername = stringValue4(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME;
57097
- const operatingMode = mcpOperatingMode(stringValue4(values, "mode"));
57098
- const cwd = stringValue4(values, "cwd") ?? process.cwd();
57099
- const defaultThreadId = stringValue4(values, "thread-id") ?? process.env.LINZUMI_THREAD_RUNNER_KANDAN_THREAD_ID;
57698
+ explicitToken: stringValue5(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
57699
+ authFilePath: stringValue5(values, "auth-file"),
57700
+ delegationAuthFilePath: stringValue5(values, "delegation-auth-file"),
57701
+ workspaceSlug: stringValue5(values, "workspace"),
57702
+ channelSlug: stringValue5(values, "channel")
57703
+ });
57704
+ const ownerUsername = stringValue5(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME;
57705
+ const operatingMode = mcpOperatingMode(stringValue5(values, "mode"));
57706
+ const cwd = stringValue5(values, "cwd") ?? process.cwd();
57707
+ const defaultThreadId = stringValue5(values, "thread-id") ?? process.env.LINZUMI_THREAD_RUNNER_KANDAN_THREAD_ID;
57100
57708
  const client = createLinzumiMcpApiClient({
57101
57709
  kandanUrl,
57102
57710
  accessToken: auth.accessToken,
@@ -57187,6 +57795,12 @@ async function runMcpServer(args) {
57187
57795
  return mcpJsonResult(result);
57188
57796
  }
57189
57797
  );
57798
+ server.tool(
57799
+ "linzumi_list_vault_secrets",
57800
+ "List vault secret names, descriptions, and whether each secret is personal or workspace-owned. Does not return secret values.",
57801
+ {},
57802
+ async (params) => mcpJsonResult(await client.listVaultSecrets(params))
57803
+ );
57190
57804
  server.tool(
57191
57805
  "linzumi_dm_owner",
57192
57806
  "Send a plain-text DM to the configured Commander owner. Requires dm.write and a visible owner username.",
@@ -57243,6 +57857,23 @@ async function runMcpServer(args) {
57243
57857
  },
57244
57858
  async (params) => mcpJsonResult(await client.sendDm(params))
57245
57859
  );
57860
+ server.tool(
57861
+ "linzumi_get_vault_values",
57862
+ "Request values for explicit vault env var names after a thread-scoped human approval. Requires vault.read; thread_id resolves the approval thread.",
57863
+ {
57864
+ workspace: external_exports2.string().optional().describe("Workspace slug. Omit to use the authenticated token scope."),
57865
+ channel: external_exports2.string().optional().describe(
57866
+ "Channel slug used to disambiguate the approval thread when needed."
57867
+ ),
57868
+ thread_id: external_exports2.string().uuid().describe("Existing Linzumi thread UUID for the inline approval."),
57869
+ env_var_names: external_exports2.array(external_exports2.string().regex(/^[A-Z][A-Z0-9_]{0,127}$/)).min(1).max(20).describe(
57870
+ "Explicit vault env var names to request. This tool cannot list all vault keys."
57871
+ ),
57872
+ description: external_exports2.string().min(1).max(500).describe("Human-readable reason shown in the approval request."),
57873
+ justification: external_exports2.string().min(10).max(1e3).describe("Agent justification shown to the approver.")
57874
+ },
57875
+ async (params) => mcpJsonResult(await client.getVaultValues(params))
57876
+ );
57246
57877
  await server.connect(new StdioServerTransport());
57247
57878
  }
57248
57879
  async function uploadFilesWithClient(args) {
@@ -57341,22 +57972,22 @@ function registerEmptyMcpResources(server) {
57341
57972
  async function runMcpConfig(args) {
57342
57973
  const values = strictFlagValues(args);
57343
57974
  const kandanUrl = required(values, "api-url");
57344
- const format = stringValue4(values, "format") ?? "codex";
57345
- const operatingMode = mcpOperatingMode(stringValue4(values, "mode"));
57975
+ const format = stringValue5(values, "format") ?? "codex";
57976
+ const operatingMode = mcpOperatingMode(stringValue5(values, "mode"));
57346
57977
  const token = values.get("include-token") === true ? (await resolveMcpAuth({
57347
57978
  kandanUrl,
57348
- explicitToken: stringValue4(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
57349
- authFilePath: stringValue4(values, "auth-file"),
57350
- delegationAuthFilePath: stringValue4(values, "delegation-auth-file"),
57351
- workspaceSlug: stringValue4(values, "workspace"),
57352
- channelSlug: stringValue4(values, "channel")
57979
+ explicitToken: stringValue5(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
57980
+ authFilePath: stringValue5(values, "auth-file"),
57981
+ delegationAuthFilePath: stringValue5(values, "delegation-auth-file"),
57982
+ workspaceSlug: stringValue5(values, "workspace"),
57983
+ channelSlug: stringValue5(values, "channel")
57353
57984
  })).accessToken : void 0;
57354
57985
  const config = linzumiMcpServerConfig({
57355
- command: stringValue4(values, "command"),
57986
+ command: stringValue5(values, "command"),
57356
57987
  kandanUrl,
57357
57988
  accessToken: token,
57358
- delegationAuthFilePath: stringValue4(values, "delegation-auth-file"),
57359
- ownerUsername: stringValue4(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME,
57989
+ delegationAuthFilePath: stringValue5(values, "delegation-auth-file"),
57990
+ ownerUsername: stringValue5(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME,
57360
57991
  operatingMode
57361
57992
  });
57362
57993
  switch (format) {
@@ -57375,19 +58006,19 @@ async function runMcpDoctor(args) {
57375
58006
  const kandanUrl = required(values, "api-url");
57376
58007
  const auth = await resolveMcpAuth({
57377
58008
  kandanUrl,
57378
- explicitToken: stringValue4(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
57379
- authFilePath: stringValue4(values, "auth-file"),
57380
- delegationAuthFilePath: stringValue4(values, "delegation-auth-file"),
57381
- workspaceSlug: stringValue4(values, "workspace"),
57382
- channelSlug: stringValue4(values, "channel")
58009
+ explicitToken: stringValue5(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
58010
+ authFilePath: stringValue5(values, "auth-file"),
58011
+ delegationAuthFilePath: stringValue5(values, "delegation-auth-file"),
58012
+ workspaceSlug: stringValue5(values, "workspace"),
58013
+ channelSlug: stringValue5(values, "channel")
57383
58014
  });
57384
58015
  switch (auth.mode) {
57385
58016
  case "local-runner": {
57386
58017
  const ok = await validateLocalRunnerToken({
57387
58018
  kandanUrl,
57388
58019
  accessToken: auth.accessToken,
57389
- workspaceSlug: stringValue4(values, "workspace"),
57390
- channelSlug: stringValue4(values, "channel")
58020
+ workspaceSlug: stringValue5(values, "workspace"),
58021
+ channelSlug: stringValue5(values, "channel")
57391
58022
  });
57392
58023
  if (!ok) {
57393
58024
  throw new Error("Linzumi MCP auth validation failed");
@@ -57399,7 +58030,7 @@ async function runMcpDoctor(args) {
57399
58030
  kandanUrl,
57400
58031
  accessToken: auth.accessToken,
57401
58032
  authMode: auth.mode,
57402
- operatingMode: mcpOperatingMode(stringValue4(values, "mode"))
58033
+ operatingMode: mcpOperatingMode(stringValue5(values, "mode"))
57403
58034
  });
57404
58035
  await client.validateAuth();
57405
58036
  break;
@@ -57470,7 +58101,7 @@ function strictFlagValues(args) {
57470
58101
  }
57471
58102
  return values;
57472
58103
  }
57473
- function stringValue4(values, key) {
58104
+ function stringValue5(values, key) {
57474
58105
  const value = values.get(key);
57475
58106
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
57476
58107
  }
@@ -57486,7 +58117,7 @@ function mcpOperatingMode(value) {
57486
58117
  }
57487
58118
  }
57488
58119
  function required(values, key) {
57489
- const value = stringValue4(values, key);
58120
+ const value = stringValue5(values, key);
57490
58121
  if (value === void 0) {
57491
58122
  throw new Error(`--${key} is required`);
57492
58123
  }
@@ -57705,11 +58336,11 @@ function runHelloCommand(args) {
57705
58336
  process.stdout.write(helloHelpText());
57706
58337
  return;
57707
58338
  }
57708
- const rootPath = stringValue6(values, "dir");
57709
- const parentDir = stringValue6(values, "parent-dir");
57710
- const name = stringValue6(values, "name");
58339
+ const rootPath = stringValue7(values, "dir");
58340
+ const parentDir = stringValue7(values, "parent-dir");
58341
+ const name = stringValue7(values, "name");
57711
58342
  const port = tcpPortValue(values, "port");
57712
- const host = stringValue6(values, "host");
58343
+ const host = stringValue7(values, "host");
57713
58344
  const project = createHelloLinzumiProject({
57714
58345
  ...rootPath === void 0 ? {} : { rootPath },
57715
58346
  ...parentDir === void 0 ? {} : { parentDir: resolveUserPath(parentDir) },
@@ -57849,8 +58480,8 @@ async function runCommanderDaemonCommand(args) {
57849
58480
  runnerId,
57850
58481
  cwd,
57851
58482
  args: stripDaemonSupervisorFlags(flagArgs),
57852
- logFile: stringValue6(values, "log-file"),
57853
- statusDir: stringValue6(values, "status-dir")
58483
+ logFile: stringValue7(values, "log-file"),
58484
+ statusDir: stringValue7(values, "status-dir")
57854
58485
  });
57855
58486
  process.stdout.write("commander_status: daemon_started\n");
57856
58487
  process.stdout.write(`runner_id: ${record.runnerId}
@@ -57871,7 +58502,7 @@ async function runCommanderDaemonCommand(args) {
57871
58502
  const runnerId = ensureLocalRunnerIdForLinzumiUrl(kandanUrl);
57872
58503
  const status = commanderDaemonStatus(
57873
58504
  runnerId,
57874
- stringValue6(values, "status-dir")
58505
+ stringValue7(values, "status-dir")
57875
58506
  );
57876
58507
  process.stdout.write(`${JSON.stringify(status)}
57877
58508
  `);
@@ -57885,7 +58516,7 @@ async function runCommanderDaemonCommand(args) {
57885
58516
  const result = await waitForCommanderDaemon({
57886
58517
  runnerId,
57887
58518
  timeoutMs,
57888
- statusDir: stringValue6(values, "status-dir")
58519
+ statusDir: stringValue7(values, "status-dir")
57889
58520
  });
57890
58521
  if (result.ok) {
57891
58522
  process.stdout.write("commander_status: connected\n");
@@ -57903,7 +58534,7 @@ async function runCommanderDaemonCommand(args) {
57903
58534
  const runnerId = ensureLocalRunnerIdForLinzumiUrl(kandanUrl);
57904
58535
  const status = stopCommanderDaemon(
57905
58536
  runnerId,
57906
- stringValue6(values, "status-dir")
58537
+ stringValue7(values, "status-dir")
57907
58538
  );
57908
58539
  process.stdout.write(`${JSON.stringify(status)}
57909
58540
  `);
@@ -57932,13 +58563,13 @@ async function runAuthCommand(args) {
57932
58563
  kandanUrl,
57933
58564
  workspaceSlug: target?.workspaceSlug,
57934
58565
  channelSlug: target?.channelSlug,
57935
- callbackHost: stringValue6(values, "oauth-callback-host")
58566
+ callbackHost: stringValue7(values, "oauth-callback-host")
57936
58567
  });
57937
58568
  const cached = writeCachedLocalRunnerToken({
57938
58569
  kandanUrl,
57939
58570
  accessToken: token.accessToken,
57940
58571
  expiresInSeconds: token.expiresInSeconds,
57941
- authFilePath: stringValue6(values, "auth-file")
58572
+ authFilePath: stringValue7(values, "auth-file")
57942
58573
  });
57943
58574
  process.stdout.write(
57944
58575
  `Saved Linzumi local runner auth for ${cached.kandanBaseUrl}
@@ -57965,11 +58596,11 @@ async function parseStartRunnerArgs(args, deps = {
57965
58596
  const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
57966
58597
  const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
57967
58598
  const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
57968
- parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
58599
+ parseAllowedCwdList(stringValue7(values, "allowed-cwd"))
57969
58600
  ) : [];
57970
58601
  const allowedCwds = Array.from(/* @__PURE__ */ new Set([cwd, ...explicitAllowedCwds]));
57971
- const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
57972
- const customCodeServerBin = stringValue6(values, "code-server-bin");
58602
+ const requestedCodexBin = stringValue7(values, "codex-bin") ?? "codex";
58603
+ const customCodeServerBin = stringValue7(values, "code-server-bin");
57973
58604
  const initialDependencyStatus = await deps.buildDependencyStatus({
57974
58605
  cwd,
57975
58606
  codexBin: requestedCodexBin,
@@ -57977,9 +58608,9 @@ async function parseStartRunnerArgs(args, deps = {
57977
58608
  });
57978
58609
  assertStartDependencies(initialDependencyStatus);
57979
58610
  const codexBin = initialDependencyStatus.codex.command;
57980
- const explicitToken = stringValue6(values, "token");
57981
- const authFilePath = stringValue6(values, "auth-file");
57982
- const callbackHost = stringValue6(values, "oauth-callback-host");
58611
+ const explicitToken = stringValue7(values, "token");
58612
+ const authFilePath = stringValue7(values, "auth-file");
58613
+ const callbackHost = stringValue7(values, "oauth-callback-host");
57983
58614
  const reportRejectedCachedToken = () => {
57984
58615
  process.stderr.write(
57985
58616
  "Cached Linzumi local runner auth was rejected; starting OAuth.\n"
@@ -58032,13 +58663,13 @@ async function parseStartRunnerArgs(args, deps = {
58032
58663
  workspaceSlug: target.workspaceSlug,
58033
58664
  cwd,
58034
58665
  codexBin,
58035
- codexUrl: stringValue6(values, "codex-url"),
58666
+ codexUrl: stringValue7(values, "codex-url"),
58036
58667
  launchTui: values.get("launch-tui") === true,
58037
58668
  fast: values.get("fast") === true,
58038
- logFile: stringValue6(values, "log-file"),
58669
+ logFile: stringValue7(values, "log-file"),
58039
58670
  allowedCwds,
58040
58671
  allowedForwardPorts: parseAllowedPortList(
58041
- stringValue6(values, "forward-port")
58672
+ stringValue7(values, "forward-port")
58042
58673
  ),
58043
58674
  codeServerBin: editorRuntime.codeServerBin,
58044
58675
  editorRuntime: editorRuntime.runtime,
@@ -58049,12 +58680,12 @@ async function parseStartRunnerArgs(args, deps = {
58049
58680
  channelSession: {
58050
58681
  workspaceSlug: target.workspaceSlug,
58051
58682
  channelSlug: target.channelSlug,
58052
- kandanThreadId: stringValue6(values, "linzumi-thread-id"),
58053
- listenUser: stringValue6(values, "listen-user") ?? defaultListenUserFromToken(targetToken),
58054
- model: stringValue6(values, "model"),
58055
- reasoningEffort: stringValue6(values, "reasoning-effort"),
58056
- sandbox: stringValue6(values, "sandbox"),
58057
- approvalPolicy: stringValue6(values, "approval-policy"),
58683
+ kandanThreadId: stringValue7(values, "linzumi-thread-id"),
58684
+ listenUser: stringValue7(values, "listen-user") ?? defaultListenUserFromToken(targetToken),
58685
+ model: stringValue7(values, "model"),
58686
+ reasoningEffort: stringValue7(values, "reasoning-effort"),
58687
+ sandbox: stringValue7(values, "sandbox"),
58688
+ approvalPolicy: stringValue7(values, "approval-policy"),
58058
58689
  allowPortForwardingByDefault: true,
58059
58690
  streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
58060
58691
  }
@@ -58079,32 +58710,32 @@ async function parseAgentRunnerArgs(args, deps = {
58079
58710
  "linzumi commander accepts either <folder> or --cwd, not both"
58080
58711
  );
58081
58712
  }
58082
- const tokenFilePath = stringValue6(values, "agent-token-file") ?? defaultAgentTokenFilePath();
58713
+ const tokenFilePath = stringValue7(values, "agent-token-file") ?? defaultAgentTokenFilePath();
58083
58714
  const tokenFile = readStoredAgentTokenFile(tokenFilePath, deps.readTextFile);
58084
58715
  const channelSlug = tokenFile.channelId;
58085
58716
  rejectWorkspaceCommanderThreadFlags(values, channelSlug);
58086
58717
  const channelSession = channelSlug === void 0 ? void 0 : {
58087
58718
  workspaceSlug: tokenFile.workspaceId,
58088
58719
  channelSlug,
58089
- kandanThreadId: stringValue6(values, "linzumi-thread-id"),
58090
- listenUser: stringValue6(values, "listen-user") ?? requiredStoredOwnerUsername(tokenFile.ownerUsername),
58091
- model: stringValue6(values, "model"),
58092
- reasoningEffort: stringValue6(values, "reasoning-effort"),
58093
- sandbox: stringValue6(values, "sandbox"),
58094
- approvalPolicy: stringValue6(values, "approval-policy"),
58720
+ kandanThreadId: stringValue7(values, "linzumi-thread-id"),
58721
+ listenUser: stringValue7(values, "listen-user") ?? requiredStoredOwnerUsername(tokenFile.ownerUsername),
58722
+ model: stringValue7(values, "model"),
58723
+ reasoningEffort: stringValue7(values, "reasoning-effort"),
58724
+ sandbox: stringValue7(values, "sandbox"),
58725
+ approvalPolicy: stringValue7(values, "approval-policy"),
58095
58726
  allowPortForwardingByDefault: true,
58096
58727
  streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
58097
58728
  };
58098
58729
  const kandanUrl = kandanUrlValue(values) ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
58099
- const requestedCwdValue = cwdArg ?? stringValue6(values, "cwd");
58730
+ const requestedCwdValue = cwdArg ?? stringValue7(values, "cwd");
58100
58731
  const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
58101
58732
  const configuredAllowedCwds2 = requestedCwdValue === void 0 && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
58102
58733
  const allowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
58103
- parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
58734
+ parseAllowedCwdList(stringValue7(values, "allowed-cwd"))
58104
58735
  ) : requestedCwdValue === void 0 ? configuredAllowedCwds2.allowedCwds.length > 0 ? [...configuredAllowedCwds2.allowedCwds] : assertConfiguredAllowedCwds([requestedCwd]) : assertConfiguredAllowedCwds([requestedCwd]);
58105
58736
  const cwd = allowedCwds[0] ?? requestedCwd;
58106
- const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
58107
- const customCodeServerBin = stringValue6(values, "code-server-bin");
58737
+ const requestedCodexBin = stringValue7(values, "codex-bin") ?? "codex";
58738
+ const customCodeServerBin = stringValue7(values, "code-server-bin");
58108
58739
  const initialDependencyStatus = await deps.buildDependencyStatus({
58109
58740
  cwd,
58110
58741
  codexBin: requestedCodexBin,
@@ -58135,14 +58766,14 @@ async function parseAgentRunnerArgs(args, deps = {
58135
58766
  workspaceSlug: tokenFile.workspaceId,
58136
58767
  cwd,
58137
58768
  codexBin,
58138
- codexUrl: stringValue6(values, "codex-url"),
58769
+ codexUrl: stringValue7(values, "codex-url"),
58139
58770
  launchTui: values.get("launch-tui") === true,
58140
58771
  fast: values.get("fast") === true,
58141
- logFile: stringValue6(values, "log-file"),
58772
+ logFile: stringValue7(values, "log-file"),
58142
58773
  allowedCwds,
58143
58774
  missingAllowedCwds: configuredAllowedCwds2.missingAllowedCwds,
58144
58775
  allowedForwardPorts: parseAllowedPortList(
58145
- stringValue6(values, "forward-port")
58776
+ stringValue7(values, "forward-port")
58146
58777
  ),
58147
58778
  codeServerBin: editorRuntime.codeServerBin,
58148
58779
  editorRuntime: editorRuntime.runtime,
@@ -58255,16 +58886,16 @@ async function parseRunnerArgs(args, deps = {
58255
58886
  process.exit(0);
58256
58887
  }
58257
58888
  rejectConnectChannelFlags(values);
58258
- const workspaceSlug = stringValue6(values, "workspace");
58889
+ const workspaceSlug = stringValue7(values, "workspace");
58259
58890
  const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
58260
- const cwd = stringValue6(values, "cwd") ?? process.cwd();
58891
+ const cwd = stringValue7(values, "cwd") ?? process.cwd();
58261
58892
  const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
58262
58893
  const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
58263
58894
  const configuredAllowedCwds2 = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
58264
- parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
58895
+ parseAllowedCwdList(stringValue7(values, "allowed-cwd"))
58265
58896
  ) : [...localConfiguredAllowedCwds.allowedCwds];
58266
- const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
58267
- const customCodeServerBin = stringValue6(values, "code-server-bin");
58897
+ const requestedCodexBin = stringValue7(values, "codex-bin") ?? "codex";
58898
+ const customCodeServerBin = stringValue7(values, "code-server-bin");
58268
58899
  const initialDependencyStatus = await deps.buildDependencyStatus({
58269
58900
  cwd,
58270
58901
  codexBin: requestedCodexBin,
@@ -58272,13 +58903,13 @@ async function parseRunnerArgs(args, deps = {
58272
58903
  });
58273
58904
  assertStartDependencies(initialDependencyStatus);
58274
58905
  const codexBin = initialDependencyStatus.codex.command;
58275
- const explicitToken = stringValue6(values, "token");
58906
+ const explicitToken = stringValue7(values, "token");
58276
58907
  const token = await deps.resolveToken({
58277
58908
  kandanUrl,
58278
58909
  explicitToken,
58279
58910
  workspaceSlug,
58280
- authFilePath: stringValue6(values, "auth-file"),
58281
- callbackHost: stringValue6(values, "oauth-callback-host"),
58911
+ authFilePath: stringValue7(values, "auth-file"),
58912
+ callbackHost: stringValue7(values, "oauth-callback-host"),
58282
58913
  reportRejectedCachedToken: () => {
58283
58914
  process.stderr.write(
58284
58915
  "Cached Linzumi local runner auth was rejected; starting OAuth.\n"
@@ -58307,16 +58938,16 @@ async function parseRunnerArgs(args, deps = {
58307
58938
  ),
58308
58939
  cwd,
58309
58940
  codexBin,
58310
- codexUrl: stringValue6(values, "codex-url"),
58941
+ codexUrl: stringValue7(values, "codex-url"),
58311
58942
  launchTui: values.get("launch-tui") === true,
58312
58943
  fast: values.get("fast") === true,
58313
- logFile: stringValue6(values, "log-file"),
58944
+ logFile: stringValue7(values, "log-file"),
58314
58945
  allowedCwds: Array.from(
58315
58946
  /* @__PURE__ */ new Set([...cwdAllowedCwds, ...configuredAllowedCwds2])
58316
58947
  ),
58317
58948
  missingAllowedCwds: localConfiguredAllowedCwds.missingAllowedCwds,
58318
58949
  allowedForwardPorts: parseAllowedPortList(
58319
- stringValue6(values, "forward-port")
58950
+ stringValue7(values, "forward-port")
58320
58951
  ),
58321
58952
  codeServerBin: editorRuntime.codeServerBin,
58322
58953
  editorRuntime: editorRuntime.runtime,
@@ -58330,16 +58961,16 @@ async function parseRunnerArgs(args, deps = {
58330
58961
  }
58331
58962
  function runnerRuntimeDefaultsFromValues(values) {
58332
58963
  return {
58333
- model: stringValue6(values, "model"),
58334
- reasoningEffort: stringValue6(values, "reasoning-effort"),
58335
- approvalPolicy: stringValue6(values, "approval-policy"),
58336
- sandbox: stringValue6(values, "sandbox"),
58964
+ model: stringValue7(values, "model"),
58965
+ reasoningEffort: stringValue7(values, "reasoning-effort"),
58966
+ approvalPolicy: stringValue7(values, "approval-policy"),
58967
+ sandbox: stringValue7(values, "sandbox"),
58337
58968
  allowPortForwardingByDefault: true
58338
58969
  };
58339
58970
  }
58340
58971
  function kandanUrlValue(values) {
58341
- const apiUrl = stringValue6(values, "api-url");
58342
- const linzumiUrl = stringValue6(values, "linzumi-url");
58972
+ const apiUrl = stringValue7(values, "api-url");
58973
+ const linzumiUrl = stringValue7(values, "linzumi-url");
58343
58974
  if (apiUrl !== void 0 && linzumiUrl !== void 0 && apiUrl !== linzumiUrl) {
58344
58975
  throw new Error("use only one of --api-url or --linzumi-url");
58345
58976
  }
@@ -58448,10 +59079,10 @@ function rejectStartTargetingFlags(values) {
58448
59079
  }
58449
59080
  function resolveUserPath(pathValue) {
58450
59081
  if (pathValue === "~") {
58451
- return homedir14();
59082
+ return homedir13();
58452
59083
  }
58453
59084
  if (pathValue.startsWith("~/")) {
58454
- return resolve10(homedir14(), pathValue.slice(2));
59085
+ return resolve10(homedir13(), pathValue.slice(2));
58455
59086
  }
58456
59087
  return resolve10(pathValue);
58457
59088
  }
@@ -58478,8 +59109,8 @@ function rejectConnectChannelFlags(values) {
58478
59109
  );
58479
59110
  }
58480
59111
  function parseOptionalChannelTarget(values) {
58481
- const channel = stringValue6(values, "channel");
58482
- const workspace = stringValue6(values, "workspace");
59112
+ const channel = stringValue7(values, "channel");
59113
+ const workspace = stringValue7(values, "workspace");
58483
59114
  if (channel === void 0) {
58484
59115
  if (workspace === void 0) {
58485
59116
  return void 0;
@@ -58513,9 +59144,9 @@ function withLocalMachineId(options) {
58513
59144
  function parseThreadCodexWorkerArgs(args) {
58514
59145
  const values = strictFlagValues2(args);
58515
59146
  const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
58516
- const cwd = stringValue6(values, "cwd") ?? process.cwd();
59147
+ const cwd = stringValue7(values, "cwd") ?? process.cwd();
58517
59148
  const configuredAllowedCwds2 = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
58518
- parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
59149
+ parseAllowedCwdList(stringValue7(values, "allowed-cwd"))
58519
59150
  ) : assertConfiguredAllowedCwds([cwd]);
58520
59151
  const kandanThreadId = requiredThreadRunnerKandanThreadId();
58521
59152
  const token = requiredThreadRunnerToken();
@@ -58525,17 +59156,17 @@ function parseThreadCodexWorkerArgs(args) {
58525
59156
  runnerId: `thread-codex-worker:${kandanThreadId}`,
58526
59157
  machineId: void 0,
58527
59158
  runnerLockConfigPath: void 0,
58528
- workspaceSlug: stringValue6(values, "workspace"),
59159
+ workspaceSlug: stringValue7(values, "workspace"),
58529
59160
  cwd,
58530
- codexBin: stringValue6(values, "codex-bin") ?? "codex",
59161
+ codexBin: stringValue7(values, "codex-bin") ?? "codex",
58531
59162
  codexUrl: void 0,
58532
59163
  launchTui: false,
58533
59164
  fast: values.get("fast") === true ? true : void 0,
58534
- logFile: stringValue6(values, "log-file"),
59165
+ logFile: stringValue7(values, "log-file"),
58535
59166
  allowedCwds: configuredAllowedCwds2.allowedCwds,
58536
59167
  missingAllowedCwds: configuredAllowedCwds2.missingAllowedCwds,
58537
59168
  allowedForwardPorts: parseAllowedPortList(
58538
- stringValue6(values, "forward-port")
59169
+ stringValue7(values, "forward-port")
58539
59170
  ),
58540
59171
  codeServerBin: void 0,
58541
59172
  editorRuntime: void 0,
@@ -58565,13 +59196,13 @@ function requiredThreadRunnerToken() {
58565
59196
  return token;
58566
59197
  }
58567
59198
  function required2(values, key) {
58568
- const value = stringValue6(values, key);
59199
+ const value = stringValue7(values, key);
58569
59200
  if (value === void 0) {
58570
59201
  throw new Error(`missing --${key}`);
58571
59202
  }
58572
59203
  return value;
58573
59204
  }
58574
- function stringValue6(values, key) {
59205
+ function stringValue7(values, key) {
58575
59206
  const value = values.get(key);
58576
59207
  if (typeof value === "string" && value.trim() !== "") {
58577
59208
  return value;
@@ -58579,7 +59210,7 @@ function stringValue6(values, key) {
58579
59210
  return void 0;
58580
59211
  }
58581
59212
  function positiveIntegerValue2(values, key) {
58582
- const value = stringValue6(values, key);
59213
+ const value = stringValue7(values, key);
58583
59214
  if (value === void 0) {
58584
59215
  return void 0;
58585
59216
  }
@@ -58590,7 +59221,7 @@ function positiveIntegerValue2(values, key) {
58590
59221
  throw new Error(`--${key} must be a positive integer`);
58591
59222
  }
58592
59223
  function tcpPortValue(values, key) {
58593
- const value = stringValue6(values, key);
59224
+ const value = stringValue7(values, key);
58594
59225
  if (value === void 0) {
58595
59226
  return void 0;
58596
59227
  }