@linzumi/cli 0.0.71-beta → 0.0.73-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.
package/dist/index.js CHANGED
@@ -1831,6 +1831,10 @@ function interruptQueuedMessages(queue, throughSeq) {
1831
1831
  }
1832
1832
  function fuseQueuedMessages(selected) {
1833
1833
  const last = selected[selected.length - 1];
1834
+ const receivedAtMs = selected.reduce(
1835
+ (earliest, message) => message.receivedAtMs === void 0 ? earliest : earliest === void 0 ? message.receivedAtMs : Math.min(earliest, message.receivedAtMs),
1836
+ void 0
1837
+ );
1834
1838
  if (last === void 0) {
1835
1839
  return void 0;
1836
1840
  }
@@ -1839,7 +1843,8 @@ function fuseQueuedMessages(selected) {
1839
1843
  actorSlug: "kandan",
1840
1844
  actorUserId: void 0,
1841
1845
  body: selected.map(codexInputForQueuedKandanMessage).join("\n\n---\n\n"),
1842
- attachments: selected.flatMap((message) => message.attachments)
1846
+ attachments: selected.flatMap((message) => message.attachments),
1847
+ receivedAtMs
1843
1848
  };
1844
1849
  }
1845
1850
  var init_kandanQueue = __esm({
@@ -4069,7 +4074,10 @@ async function handleChannelSessionControl(args, state, payloadContext, control)
4069
4074
  interruptedActiveSeq,
4070
4075
  {
4071
4076
  status: "processed"
4072
- }
4077
+ },
4078
+ void 0,
4079
+ void 0,
4080
+ state.codexThreadId
4073
4081
  );
4074
4082
  break;
4075
4083
  case "starting":
@@ -4093,10 +4101,18 @@ async function handleChannelSessionControl(args, state, payloadContext, control)
4093
4101
  });
4094
4102
  if (interrupted.ok) {
4095
4103
  for (const seq of interrupted.selectedSeqs) {
4096
- await publishMessageState(args, state.kandanThreadId, seq, {
4097
- status: "processing",
4098
- reason: "interrupt requested"
4099
- });
4104
+ await publishMessageState(
4105
+ args,
4106
+ state.kandanThreadId,
4107
+ seq,
4108
+ {
4109
+ status: "processing",
4110
+ reason: "interrupt requested"
4111
+ },
4112
+ void 0,
4113
+ void 0,
4114
+ state.codexThreadId
4115
+ );
4100
4116
  }
4101
4117
  }
4102
4118
  await drainKandanMessageQueue(args, state, payloadContext);
@@ -4365,6 +4381,9 @@ async function resolvePendingPortForwardRequest(args, state, payloadContext, con
4365
4381
  if (request === void 0) {
4366
4382
  return void 0;
4367
4383
  }
4384
+ if (control.threadId !== void 0 && state.codexThreadId !== control.threadId) {
4385
+ return void 0;
4386
+ }
4368
4387
  if (!portForwardControlSenderAllowed(args, payloadContext, control)) {
4369
4388
  args.log("port_forward.request_resolution_ignored", {
4370
4389
  request_id: control.requestId,
@@ -4633,11 +4652,19 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
4633
4652
  allowedActorUserId: args.options.channelSession.listenUser.toLowerCase() === (payloadContext.runnerIdentity.actorUsername ?? "").toLowerCase() ? payloadContext.runnerIdentity.actorUserId : void 0
4634
4653
  }
4635
4654
  };
4636
- await publishMessageState(args, state.kandanThreadId, sourceSeq, {
4637
- status: "processing",
4638
- reason: "awaiting approval",
4639
- approval: state.activeProcessingState.approval
4640
- });
4655
+ await publishMessageState(
4656
+ args,
4657
+ state.kandanThreadId,
4658
+ sourceSeq,
4659
+ {
4660
+ status: "processing",
4661
+ reason: "awaiting approval",
4662
+ approval: state.activeProcessingState.approval
4663
+ },
4664
+ void 0,
4665
+ void 0,
4666
+ state.codexThreadId
4667
+ );
4641
4668
  await publishForwardPortRequestedEvent(args, state, request, processIdentity);
4642
4669
  args.log("port_forward.request_pending", {
4643
4670
  request_id: requestId,
@@ -4826,7 +4853,10 @@ async function publishMessageStateForPortForwardResult(args, state, request, sta
4826
4853
  {
4827
4854
  status: "processing",
4828
4855
  reason: "running terminal command"
4829
- }
4856
+ },
4857
+ void 0,
4858
+ void 0,
4859
+ state.codexThreadId
4830
4860
  );
4831
4861
  return;
4832
4862
  }
@@ -4851,15 +4881,31 @@ async function publishMessageStateForPortForwardResult(args, state, request, sta
4851
4881
  }
4852
4882
  switch (status) {
4853
4883
  case "processed":
4854
- await publishMessageState(args, state.kandanThreadId, request.sourceSeq, {
4855
- status: "processed"
4856
- });
4884
+ await publishMessageState(
4885
+ args,
4886
+ state.kandanThreadId,
4887
+ request.sourceSeq,
4888
+ {
4889
+ status: "processed"
4890
+ },
4891
+ void 0,
4892
+ void 0,
4893
+ state.codexThreadId
4894
+ );
4857
4895
  break;
4858
4896
  case "failed":
4859
- await publishMessageState(args, state.kandanThreadId, request.sourceSeq, {
4860
- status: "failed",
4861
- reason: failedReason
4862
- });
4897
+ await publishMessageState(
4898
+ args,
4899
+ state.kandanThreadId,
4900
+ request.sourceSeq,
4901
+ {
4902
+ status: "failed",
4903
+ reason: failedReason
4904
+ },
4905
+ void 0,
4906
+ void 0,
4907
+ state.codexThreadId
4908
+ );
4863
4909
  break;
4864
4910
  }
4865
4911
  }
@@ -4873,6 +4919,10 @@ function parsePortForwardDecision(body) {
4873
4919
  requestId: match[2] ?? ""
4874
4920
  };
4875
4921
  }
4922
+ function runnerConsoleBodyPreview(body) {
4923
+ const normalized = body.replace(/\s+/g, " ").trim();
4924
+ return normalized.length <= 50 ? normalized : `${normalized.slice(0, 47)}...`;
4925
+ }
4876
4926
  async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext, event) {
4877
4927
  const session = args.options.channelSession;
4878
4928
  if (event.type !== "thread.message") {
@@ -4991,17 +5041,25 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
4991
5041
  });
4992
5042
  return;
4993
5043
  }
5044
+ const receivedAtMs = Date.now();
4994
5045
  enqueuePendingKandanMessage(state.queue, {
4995
5046
  seq: event.seq,
4996
5047
  actorSlug: event.actorSlug,
4997
5048
  actorUserId: event.actorUserId,
4998
5049
  body: event.body,
4999
- attachments: event.attachments
5050
+ attachments: event.attachments,
5051
+ receivedAtMs
5000
5052
  });
5001
5053
  args.log("kandan.message_queued", {
5002
5054
  seq: event.seq,
5003
5055
  actor_slug: event.actorSlug ?? null,
5004
5056
  actor_user_id: event.actorUserId ?? null,
5057
+ linzumi_thread_id: state.kandanThreadId ?? null,
5058
+ codex_thread_id: state.codexThreadId ?? null,
5059
+ runner_console: {
5060
+ body_preview: runnerConsoleBodyPreview(event.body),
5061
+ message_received_at_ms: receivedAtMs
5062
+ },
5005
5063
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5006
5064
  });
5007
5065
  await publishKandanMessageState(args, event, { status: "queued" });
@@ -5070,13 +5128,20 @@ async function startThreadMessageTurn(args, state, payloadContext, message) {
5070
5128
  actorSlug: message.actorSlug,
5071
5129
  actorUserId: message.actorUserId,
5072
5130
  body: message.body,
5073
- attachments: []
5131
+ attachments: [],
5132
+ receivedAtMs: Date.now()
5074
5133
  };
5075
5134
  enqueuePendingKandanMessage(state.queue, queued);
5076
5135
  args.log("kandan.message_queued", {
5077
5136
  seq: queued.seq,
5078
5137
  actor_slug: queued.actorSlug ?? null,
5079
5138
  actor_user_id: queued.actorUserId ?? null,
5139
+ linzumi_thread_id: state.kandanThreadId ?? null,
5140
+ codex_thread_id: state.codexThreadId ?? null,
5141
+ runner_console: {
5142
+ body_preview: runnerConsoleBodyPreview(queued.body),
5143
+ message_received_at_ms: queued.receivedAtMs ?? Date.now()
5144
+ },
5080
5145
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5081
5146
  });
5082
5147
  await publishQueuedMessageState(args, state, queued, { status: "queued" });
@@ -5199,7 +5264,12 @@ async function drainKandanMessageQueue(args, state, payloadContext) {
5199
5264
  queued_seq: next.seq,
5200
5265
  actor_slug: next.actorSlug ?? null,
5201
5266
  actor_user_id: next.actorUserId ?? null,
5267
+ linzumi_thread_id: state.kandanThreadId ?? null,
5202
5268
  codex_thread_id: state.codexThreadId ?? null,
5269
+ runner_console: {
5270
+ body_preview: runnerConsoleBodyPreview(next.body),
5271
+ message_received_at_ms: next.receivedAtMs ?? Date.now()
5272
+ },
5203
5273
  queue_depth: pendingKandanMessageQueueLength(state.queue)
5204
5274
  });
5205
5275
  await publishQueuedMessageState(args, state, next, {
@@ -5239,9 +5309,17 @@ async function drainKandanMessageQueue(args, state, payloadContext) {
5239
5309
  state.turn = { status: "idle" };
5240
5310
  clearActiveProcessingState(state, next.seq);
5241
5311
  if (state.kandanThreadId !== void 0) {
5242
- await publishMessageState(args, state.kandanThreadId, next.seq, {
5243
- status: "processed"
5244
- });
5312
+ await publishMessageState(
5313
+ args,
5314
+ state.kandanThreadId,
5315
+ next.seq,
5316
+ {
5317
+ status: "processed"
5318
+ },
5319
+ void 0,
5320
+ void 0,
5321
+ state.codexThreadId
5322
+ );
5245
5323
  }
5246
5324
  await drainKandanMessageQueue(args, state, payloadContext);
5247
5325
  }
@@ -5257,7 +5335,7 @@ async function drainKandanMessageQueue(args, state, payloadContext) {
5257
5335
  state.codexThreadId = newCodexThreadId;
5258
5336
  await bindCurrentCodexThread(args, state);
5259
5337
  args.log("codex.thread_rebound", {
5260
- kandan_thread_id: state.kandanThreadId,
5338
+ linzumi_thread_id: state.kandanThreadId,
5261
5339
  old_codex_thread_id: oldCodexThreadId ?? null,
5262
5340
  new_codex_thread_id: newCodexThreadId
5263
5341
  });
@@ -5917,7 +5995,12 @@ async function postCompletedOutputProjection(args, state, payloadContext, params
5917
5995
  );
5918
5996
  break;
5919
5997
  }
5920
- logCompletedCodexOutput(args, params.turnId, params.output.message);
5998
+ logCompletedCodexOutput(
5999
+ args,
6000
+ state,
6001
+ params.turnId,
6002
+ params.output.message
6003
+ );
5921
6004
  break;
5922
6005
  }
5923
6006
  case "cached_reasoning": {
@@ -5939,7 +6022,7 @@ async function postCompletedOutputProjection(args, state, payloadContext, params
5939
6022
  message.structured
5940
6023
  );
5941
6024
  forgetStreamingReasoningOutput(state, output.itemKey);
5942
- logCompletedCodexOutput(args, params.turnId, message);
6025
+ logCompletedCodexOutput(args, state, params.turnId, message);
5943
6026
  break;
5944
6027
  }
5945
6028
  case "cached_command": {
@@ -5966,7 +6049,7 @@ async function postCompletedOutputProjection(args, state, payloadContext, params
5966
6049
  message.structured
5967
6050
  );
5968
6051
  forgetStreamingCommandOutput(state, output.itemKey);
5969
- logCompletedCodexOutput(args, params.turnId, message);
6052
+ logCompletedCodexOutput(args, state, params.turnId, message);
5970
6053
  break;
5971
6054
  }
5972
6055
  case "cached_file_change": {
@@ -5989,16 +6072,21 @@ async function postCompletedOutputProjection(args, state, payloadContext, params
5989
6072
  message.structured
5990
6073
  );
5991
6074
  forgetStreamingFileChangeOutput(state, output.itemKey);
5992
- logCompletedCodexOutput(args, params.turnId, message);
6075
+ logCompletedCodexOutput(args, state, params.turnId, message);
5993
6076
  break;
5994
6077
  }
5995
6078
  }
5996
6079
  }
5997
- function logCompletedCodexOutput(args, turnId, message) {
6080
+ function logCompletedCodexOutput(args, state, turnId, message) {
5998
6081
  args.log("kandan.codex_output_forwarded", {
5999
6082
  turn_id: turnId,
6000
6083
  item_key: message.itemKey,
6084
+ linzumi_thread_id: state.kandanThreadId,
6085
+ codex_thread_id: state.codexThreadId,
6001
6086
  structured_kind: stringValue(message.structured.kind) ?? null,
6087
+ runner_console: {
6088
+ body_preview: runnerConsoleBodyPreview(message.body)
6089
+ },
6002
6090
  command: stringValue(message.structured.command) ?? null,
6003
6091
  file_paths: fileChangePaths(message.structured)
6004
6092
  });
@@ -6232,6 +6320,8 @@ async function forwardAssistantDeltaPayload(args, state, delta, payloadContext)
6232
6320
  args.log("kandan.codex_delta_forwarded", {
6233
6321
  item_key: delta.itemKey,
6234
6322
  turn_id: delta.turnId ?? null,
6323
+ linzumi_thread_id: state.kandanThreadId,
6324
+ codex_thread_id: state.codexThreadId,
6235
6325
  content_length: nextContent.length
6236
6326
  });
6237
6327
  }
@@ -6478,6 +6568,8 @@ async function forwardReasoningDeltaPayload(args, state, delta, payloadContext)
6478
6568
  args.log("kandan.codex_reasoning_delta_forwarded", {
6479
6569
  item_key: delta.itemKey,
6480
6570
  turn_id: turnId,
6571
+ linzumi_thread_id: state.kandanThreadId,
6572
+ codex_thread_id: state.codexThreadId,
6481
6573
  content_length: nextContent.length
6482
6574
  });
6483
6575
  }
@@ -6666,6 +6758,8 @@ async function forwardCommandOutputDeltaPayload(args, state, delta, payloadConte
6666
6758
  args.log("kandan.codex_command_output_forwarded", {
6667
6759
  item_key: delta.itemKey,
6668
6760
  turn_id: turnId,
6761
+ linzumi_thread_id: state.kandanThreadId,
6762
+ codex_thread_id: state.codexThreadId,
6669
6763
  process_id: delta.processId ?? null,
6670
6764
  stream: delta.stream,
6671
6765
  output_length: persistedOutput.length
@@ -6749,6 +6843,8 @@ async function forwardFileChangeDeltaPayload(args, state, delta, payloadContext)
6749
6843
  args.log("kandan.codex_file_change_forwarded", {
6750
6844
  item_key: delta.itemKey,
6751
6845
  turn_id: turnId,
6846
+ linzumi_thread_id: state.kandanThreadId,
6847
+ codex_thread_id: state.codexThreadId,
6752
6848
  patch_length: patchText.length
6753
6849
  });
6754
6850
  }
@@ -6887,6 +6983,8 @@ async function forwardTerminalInput(args, state, params, payloadContext) {
6887
6983
  args.log("kandan.codex_output_forwarded", {
6888
6984
  turn_id: turnId,
6889
6985
  item_key: terminal.itemKey,
6986
+ linzumi_thread_id: state.kandanThreadId,
6987
+ codex_thread_id: state.codexThreadId,
6890
6988
  structured_kind: "codex_terminal_input",
6891
6989
  command: null,
6892
6990
  file_paths: []
@@ -6974,6 +7072,8 @@ async function forwardWebSearchProgress(args, state, params, payloadContext) {
6974
7072
  args.log("kandan.codex_web_search_progress_forwarded", {
6975
7073
  turn_id: progress.turnId,
6976
7074
  item_key: progress.itemKey,
7075
+ linzumi_thread_id: state.kandanThreadId,
7076
+ codex_thread_id: state.codexThreadId,
6977
7077
  query_count: queries.length
6978
7078
  });
6979
7079
  }
@@ -7755,7 +7855,9 @@ async function stopCodexTyping(args, state) {
7755
7855
  {
7756
7856
  workspace: session.workspaceSlug,
7757
7857
  channel: session.channelSlug,
7758
- thread_id: state.kandanThreadId
7858
+ thread_id: state.kandanThreadId,
7859
+ instance_id: args.instanceId,
7860
+ codex_thread_id: state.codexThreadId ?? null
7759
7861
  },
7760
7862
  args.log
7761
7863
  );
@@ -7774,7 +7876,9 @@ function startCodexTypingHeartbeat(args, state, threadId) {
7774
7876
  {
7775
7877
  workspace: session.workspaceSlug,
7776
7878
  channel: session.channelSlug,
7777
- thread_id: threadId
7879
+ thread_id: threadId,
7880
+ instance_id: args.instanceId,
7881
+ codex_thread_id: state.codexThreadId ?? null
7778
7882
  },
7779
7883
  args.log
7780
7884
  ).then(() => refreshActiveProcessingHeartbeat(args, state)).catch((error) => {
@@ -7819,7 +7923,8 @@ async function publishQueuedMessageState(args, state, message, messageState) {
7819
7923
  message.seq,
7820
7924
  messageState,
7821
7925
  message.actorSlug,
7822
- message.actorUserId
7926
+ message.actorUserId,
7927
+ state.codexThreadId
7823
7928
  );
7824
7929
  }
7825
7930
  async function publishMessageState(args, threadId, seq, state, actorSlug, actorUserId, codexThreadId) {
@@ -7828,6 +7933,7 @@ async function publishMessageState(args, threadId, seq, state, actorSlug, actorU
7828
7933
  workspace: session.workspaceSlug,
7829
7934
  channel: session.channelSlug,
7830
7935
  thread_id: threadId,
7936
+ instance_id: args.instanceId,
7831
7937
  ...codexThreadId === void 0 ? {} : { codex_thread_id: codexThreadId },
7832
7938
  seq,
7833
7939
  status: state.status,
@@ -7881,10 +7987,18 @@ async function failActiveCodexTurn(args, state, turnId, reason, payloadContext)
7881
7987
  }
7882
7988
  const seq = activeQueuedSeqForTurn(state.turn, turnId);
7883
7989
  if (seq !== void 0 && state.kandanThreadId !== void 0) {
7884
- await publishMessageState(args, state.kandanThreadId, seq, {
7885
- status: "failed",
7886
- reason
7887
- });
7990
+ await publishMessageState(
7991
+ args,
7992
+ state.kandanThreadId,
7993
+ seq,
7994
+ {
7995
+ status: "failed",
7996
+ reason
7997
+ },
7998
+ void 0,
7999
+ void 0,
8000
+ state.codexThreadId
8001
+ );
7888
8002
  clearActiveProcessingState(state, seq);
7889
8003
  }
7890
8004
  forgetLocalTuiTurnId(state, turnId);
@@ -7907,10 +8021,18 @@ async function refreshActiveProcessingState(args, state, turnId, reason) {
7907
8021
  return;
7908
8022
  }
7909
8023
  state.activeProcessingState = { seq, reason };
7910
- await publishMessageState(args, state.kandanThreadId, seq, {
7911
- status: "processing",
7912
- reason
7913
- });
8024
+ await publishMessageState(
8025
+ args,
8026
+ state.kandanThreadId,
8027
+ seq,
8028
+ {
8029
+ status: "processing",
8030
+ reason
8031
+ },
8032
+ void 0,
8033
+ void 0,
8034
+ state.codexThreadId
8035
+ );
7914
8036
  }
7915
8037
  async function refreshActiveProcessingHeartbeat(args, state) {
7916
8038
  const activeProcessingState = state.activeProcessingState;
@@ -8827,7 +8949,7 @@ function createRunnerLogger(logFile, consoleReporter) {
8827
8949
  `,
8828
8950
  "utf8"
8829
8951
  );
8830
- consoleReporter?.(event, redacted);
8952
+ consoleReporter?.(event, runnerConsolePayload(redacted, payload));
8831
8953
  });
8832
8954
  Object.defineProperty(logger, "close", {
8833
8955
  value: () => closeStream(stream)
@@ -8882,12 +9004,19 @@ function redactObject(value) {
8882
9004
  const headerName = typeof value.name === "string" ? value.name.toLowerCase() : void 0;
8883
9005
  const shouldRedactHeaderValue = headerName === "authorization" || headerName === "cookie" || headerName === "set-cookie";
8884
9006
  return Object.fromEntries(
8885
- Object.entries(value).map(([key, entry]) => [
9007
+ Object.entries(value).filter(([key]) => key !== "runner_console").map(([key, entry]) => [
8886
9008
  key,
8887
9009
  shouldRedactHeaderValue && key === "value" ? sensitiveMarker : redactValue(entry, key)
8888
9010
  ])
8889
9011
  );
8890
9012
  }
9013
+ function runnerConsolePayload(redacted, original) {
9014
+ const consoleFields = objectValue2(original.runner_console);
9015
+ return consoleFields === void 0 ? redacted : { ...redacted, ...redactForCliLog(consoleFields) };
9016
+ }
9017
+ function objectValue2(value) {
9018
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
9019
+ }
8891
9020
  function redactArgs(args) {
8892
9021
  let redactNext = false;
8893
9022
  return args.map((arg) => {
@@ -9130,7 +9259,9 @@ var init_mcpConfig = __esm({
9130
9259
  });
9131
9260
 
9132
9261
  // src/codexAppServer.ts
9133
- import { spawn } from "node:child_process";
9262
+ import {
9263
+ spawn
9264
+ } from "node:child_process";
9134
9265
  import { createServer } from "node:net";
9135
9266
  async function chooseLoopbackPort() {
9136
9267
  return new Promise((resolve11, reject) => {
@@ -9158,6 +9289,7 @@ async function startCodexAppServer(codexBin, cwd, options = {}) {
9158
9289
  const port = await chooseLoopbackPort();
9159
9290
  const url = `ws://127.0.0.1:${port}`;
9160
9291
  const args = codexAppServerArgs(url, options);
9292
+ const stdio = codexAppServerStdio(process.stdout.isTTY === true);
9161
9293
  writeCliAuditEvent("process.spawn", {
9162
9294
  command: codexBin,
9163
9295
  args,
@@ -9167,9 +9299,15 @@ async function startCodexAppServer(codexBin, cwd, options = {}) {
9167
9299
  const child = spawn(codexBin, args, {
9168
9300
  cwd,
9169
9301
  env: codexAppServerEnv(options.env),
9170
- stdio: ["ignore", "inherit", "inherit"],
9302
+ stdio,
9171
9303
  detached: true
9172
9304
  });
9305
+ if (stdio[1] === "pipe") {
9306
+ drainCodexAppServerOutput(child, "stdout");
9307
+ }
9308
+ if (stdio[2] === "pipe") {
9309
+ drainCodexAppServerOutput(child, "stderr");
9310
+ }
9173
9311
  const stop = () => stopCodexAppServerProcess(child);
9174
9312
  writeCliAuditEvent("process.spawned", {
9175
9313
  command: codexBin,
@@ -9203,6 +9341,25 @@ async function startCodexAppServer(codexBin, cwd, options = {}) {
9203
9341
  }
9204
9342
  return { url, process: child, stop };
9205
9343
  }
9344
+ function codexAppServerStdio(stdoutIsTty) {
9345
+ return stdoutIsTty ? ["ignore", "pipe", "pipe"] : ["ignore", "inherit", "inherit"];
9346
+ }
9347
+ function drainCodexAppServerOutput(child, streamName) {
9348
+ const stream = child[streamName];
9349
+ if (stream === null) {
9350
+ return;
9351
+ }
9352
+ stream.on("data", (chunk) => {
9353
+ const text2 = chunk.toString();
9354
+ writeCliAuditEvent("process.output", {
9355
+ pid: child.pid,
9356
+ purpose: "codex.app_server",
9357
+ stream: streamName,
9358
+ chars: text2.length,
9359
+ output: text2
9360
+ });
9361
+ });
9362
+ }
9206
9363
  function codexAppServerEnv(overrides) {
9207
9364
  const env = { ...process.env };
9208
9365
  for (const key of blockedCodexAppServerEnvKeys) {
@@ -9543,9 +9700,9 @@ function codexConfigWithTrustedProject(config, projectPath) {
9543
9700
  trust_level = "trusted"
9544
9701
  `;
9545
9702
  }
9546
- const table = config.slice(range.start, range.end);
9703
+ const table2 = config.slice(range.start, range.end);
9547
9704
  const trustLine = /^(\s*trust_level\s*=\s*).*(\r?)$/m;
9548
- const nextTable = trustLine.test(table) ? table.replace(trustLine, '$1"trusted"$2') : `${trimTrailingNewlines(table)}
9705
+ const nextTable = trustLine.test(table2) ? table2.replace(trustLine, '$1"trusted"$2') : `${trimTrailingNewlines(table2)}
9549
9706
  trust_level = "trusted"
9550
9707
  `;
9551
9708
  return `${config.slice(0, range.start)}${nextTable}${config.slice(range.end)}`;
@@ -9577,6 +9734,125 @@ var init_codexProjectTrust = __esm({
9577
9734
  }
9578
9735
  });
9579
9736
 
9737
+ // src/codexNotificationConsoleStats.ts
9738
+ function codexNotificationConsoleLogPayload(method, params) {
9739
+ return {
9740
+ method,
9741
+ metadata: extractCodexIds(params),
9742
+ ...codexNotificationConsoleStats(method, params)
9743
+ };
9744
+ }
9745
+ function codexNotificationConsoleStats(method, params) {
9746
+ switch (method) {
9747
+ case "thread/tokenUsage/updated":
9748
+ return {
9749
+ token_usage_summary: tokenUsageSummary(params) ?? "seen (no details)"
9750
+ };
9751
+ case "account/rateLimits/updated":
9752
+ return {
9753
+ rate_limit_summary: rateLimitSummary(params) ?? "seen (no details)"
9754
+ };
9755
+ default:
9756
+ return {};
9757
+ }
9758
+ }
9759
+ 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));
9763
+ const summary = [
9764
+ total === void 0 ? void 0 : `total ${total}`,
9765
+ last === void 0 ? void 0 : `last ${last}`
9766
+ ].filter((value) => value !== void 0);
9767
+ return summary.length === 0 ? void 0 : summary.join(" | ");
9768
+ }
9769
+ function tokenUsageBreakdownSummary(breakdown) {
9770
+ if (breakdown === void 0) {
9771
+ return void 0;
9772
+ }
9773
+ const inputDetails = objectValue3(breakdown.inputTokensDetails) ?? objectValue3(breakdown.input_tokens_details);
9774
+ const outputDetails = objectValue3(breakdown.outputTokensDetails) ?? objectValue3(breakdown.output_tokens_details);
9775
+ const input = integerValue2(breakdown.inputTokens) ?? integerValue2(breakdown.input_tokens) ?? integerValue2(breakdown.promptTokens) ?? integerValue2(breakdown.prompt_tokens);
9776
+ const output = integerValue2(breakdown.outputTokens) ?? integerValue2(breakdown.output_tokens) ?? integerValue2(breakdown.completionTokens) ?? integerValue2(breakdown.completion_tokens);
9777
+ const total = integerValue2(breakdown.totalTokens) ?? integerValue2(breakdown.total_tokens);
9778
+ const cached = integerValue2(breakdown.cachedInputTokens) ?? integerValue2(breakdown.cached_input_tokens) ?? integerValue2(breakdown.cacheReadInputTokens) ?? integerValue2(breakdown.cache_read_input_tokens) ?? integerValue2(inputDetails?.cachedTokens) ?? integerValue2(inputDetails?.cached_tokens);
9779
+ const reasoning = integerValue2(breakdown.reasoningOutputTokens) ?? integerValue2(breakdown.reasoning_output_tokens) ?? integerValue2(breakdown.reasoningTokens) ?? integerValue2(breakdown.reasoning_tokens) ?? integerValue2(outputDetails?.reasoningTokens) ?? integerValue2(outputDetails?.reasoning_tokens);
9780
+ const values = [
9781
+ input === void 0 ? void 0 : `${input} in`,
9782
+ output === void 0 ? void 0 : `${output} out`,
9783
+ total === void 0 ? void 0 : `${total} total`,
9784
+ cached === void 0 ? void 0 : `${cached} cached`,
9785
+ reasoning === void 0 ? void 0 : `${reasoning} reasoning`
9786
+ ].filter((value) => value !== void 0);
9787
+ return values.length === 0 ? void 0 : values.join(" / ");
9788
+ }
9789
+ function rateLimitSummary(params) {
9790
+ const rateLimits = objectValue3(params.rateLimits) ?? objectValue3(params.rate_limits) ?? objectValue3(params.limits) ?? params;
9791
+ const direct = rateLimitBucketSummary(rateLimits, void 0);
9792
+ const children = Object.entries(rateLimits).flatMap(([name, value]) => {
9793
+ const bucket = objectValue3(value);
9794
+ return bucket === void 0 ? [] : [rateLimitBucketSummary(bucket, name)];
9795
+ });
9796
+ const summaries = [direct, ...children].filter(
9797
+ (value) => value !== void 0
9798
+ );
9799
+ return summaries.length === 0 ? void 0 : summaries.join(" | ");
9800
+ }
9801
+ 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);
9804
+ const remaining = integerValue2(bucket.remaining) ?? integerValue2(bucket.remainingRequests) ?? integerValue2(bucket.remaining_requests) ?? integerValue2(bucket.remainingTokens) ?? integerValue2(bucket.remaining_tokens);
9805
+ 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);
9807
+ const usedPercent = integerValue2(bucket.usedPercent) ?? integerValue2(bucket.used_percent);
9808
+ const windowDurationMins = integerValue2(bucket.windowDurationMins) ?? integerValue2(bucket.window_duration_mins);
9809
+ const label = [name, plan].filter((value) => value !== void 0).join(" ");
9810
+ const prefix = label === "" ? void 0 : label;
9811
+ const remainingSummary = remaining === void 0 ? void 0 : limit === void 0 ? `${remaining} remaining` : `${remaining}/${limit} remaining`;
9812
+ const fields = [
9813
+ remainingSummary,
9814
+ usedPercent === void 0 ? void 0 : `${usedPercent}% used`,
9815
+ windowDurationMins === void 0 ? void 0 : `${windowDurationMins}m window`,
9816
+ reset === void 0 ? void 0 : `reset ${reset}`
9817
+ ].filter((value) => value !== void 0);
9818
+ switch (fields.length) {
9819
+ case 0:
9820
+ return prefix === void 0 ? void 0 : `${prefix} seen (no details)`;
9821
+ default:
9822
+ return prefix === void 0 ? fields.join(" ") : `${prefix} ${fields.join(" ")}`;
9823
+ }
9824
+ }
9825
+ function secondsValue(value) {
9826
+ const seconds = integerValue2(value);
9827
+ return seconds === void 0 ? void 0 : `${seconds}s`;
9828
+ }
9829
+ function unixTimestampValue(value) {
9830
+ const seconds = integerValue2(value);
9831
+ return seconds === void 0 ? void 0 : new Date(seconds * 1e3).toISOString();
9832
+ }
9833
+ function objectValue3(value) {
9834
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
9835
+ }
9836
+ function stringValue2(value) {
9837
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
9838
+ }
9839
+ function integerValue2(value) {
9840
+ if (typeof value === "number" && Number.isSafeInteger(value)) {
9841
+ return value;
9842
+ }
9843
+ if (typeof value !== "string") {
9844
+ return void 0;
9845
+ }
9846
+ const parsed = Number.parseInt(value, 10);
9847
+ return Number.isSafeInteger(parsed) && parsed.toString() === value.trim() ? parsed : void 0;
9848
+ }
9849
+ var init_codexNotificationConsoleStats = __esm({
9850
+ "src/codexNotificationConsoleStats.ts"() {
9851
+ "use strict";
9852
+ init_protocol();
9853
+ }
9854
+ });
9855
+
9580
9856
  // src/localCapabilities.ts
9581
9857
  import { realpathSync as realpathSync2 } from "node:fs";
9582
9858
  import { homedir as homedir6 } from "node:os";
@@ -13351,7 +13627,7 @@ var linzumiCliVersion, linzumiCliVersionText;
13351
13627
  var init_version = __esm({
13352
13628
  "src/version.ts"() {
13353
13629
  "use strict";
13354
- linzumiCliVersion = "0.0.71-beta";
13630
+ linzumiCliVersion = "0.0.73-beta";
13355
13631
  linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
13356
13632
  }
13357
13633
  });
@@ -13623,13 +13899,193 @@ var init_runnerLock = __esm({
13623
13899
  });
13624
13900
 
13625
13901
  // src/runnerConsoleReporter.ts
13902
+ import blessed from "blessed";
13626
13903
  function reportRunnerConsoleEvent(event, payload) {
13904
+ if (shouldRenderDashboard()) {
13905
+ const tui = initializeDashboardTui(dashboardState);
13906
+ updateRunnerConsoleDashboard(dashboardState, event, payload, Date.now());
13907
+ if (tui !== void 0) {
13908
+ tui.render(Date.now());
13909
+ return;
13910
+ }
13911
+ initializeDashboardKeyboard(dashboardState);
13912
+ initializeDashboardTicker(dashboardState);
13913
+ const screen = renderRunnerConsoleDashboard(dashboardState, Date.now());
13914
+ if (screen !== void 0) {
13915
+ redrawScreen(screen);
13916
+ return;
13917
+ }
13918
+ }
13627
13919
  const line = formatRunnerConsoleEvent(event, payload);
13628
13920
  if (line !== void 0) {
13629
13921
  process.stdout.write(`${line}
13630
13922
  `);
13631
13923
  }
13632
13924
  }
13925
+ function shouldRenderDashboard() {
13926
+ switch (process.env.LINZUMI_RUNNER_CONSOLE) {
13927
+ case "dashboard":
13928
+ return true;
13929
+ case "lines":
13930
+ return false;
13931
+ default:
13932
+ return process.stdout.isTTY === true;
13933
+ }
13934
+ }
13935
+ function updateRunnerConsoleDashboard(state, event, payload, nowMs) {
13936
+ state.lastUpdateAtMs = nowMs;
13937
+ const previousJobKey = latestDashboardJob(state)?.key;
13938
+ switch (event) {
13939
+ case "kandan.message_queued":
13940
+ case "codex.turn_starting": {
13941
+ 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;
13945
+ job.lastIncomingAtMs = numberValue(payload.message_received_at_ms) ?? job.lastIncomingAtMs;
13946
+ job.queueDepth = numberValue(payload.queue_depth) ?? job.queueDepth;
13947
+ job.eventType = dashboardEventLabel(event);
13948
+ job.updatedAtMs = nowMs;
13949
+ break;
13950
+ }
13951
+ case "codex.notification": {
13952
+ const tokenUsage = stringValue3(payload.token_usage_summary);
13953
+ const rateLimit = stringValue3(payload.rate_limit_summary);
13954
+ if (tokenUsage !== void 0) {
13955
+ state.tokenUsage = tokenUsage;
13956
+ }
13957
+ if (rateLimit !== void 0) {
13958
+ state.rateLimit = mergeRateLimitSummary(state.rateLimit, rateLimit);
13959
+ }
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;
13963
+ if (!metadataHasJobSignal) {
13964
+ break;
13965
+ }
13966
+ const codexThreadId = stringValue3(metadata?.threadId);
13967
+ const job = codexThreadId === void 0 ? latestDashboardJob(state) : dashboardJobForKey(state, `codex:${codexThreadId}`, nowMs);
13968
+ if (job !== void 0) {
13969
+ job.codexThreadId = codexThreadId ?? job.codexThreadId;
13970
+ job.tokenUsage = tokenUsage ?? job.tokenUsage;
13971
+ job.latestCodexEventId = codexEventId(payload);
13972
+ job.eventType = method ?? event;
13973
+ job.turnId = stringValue3(metadata?.turnId) ?? job.turnId;
13974
+ job.updatedAtMs = nowMs;
13975
+ }
13976
+ break;
13977
+ }
13978
+ case "kandan.codex_output_forwarded":
13979
+ case "kandan.codex_delta_forwarded":
13980
+ case "kandan.codex_reasoning_delta_forwarded":
13981
+ case "kandan.codex_command_output_forwarded":
13982
+ case "kandan.codex_file_change_forwarded":
13983
+ case "kandan.codex_web_search_progress_forwarded": {
13984
+ const job = dashboardJobForPayload(state, payload, nowMs);
13985
+ job.latestCodexEventId = stringValue3(payload.item_key) ?? job.latestCodexEventId;
13986
+ 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;
13990
+ job.lastAssistantAtMs = nowMs;
13991
+ }
13992
+ job.updatedAtMs = nowMs;
13993
+ break;
13994
+ }
13995
+ default:
13996
+ break;
13997
+ }
13998
+ rememberRawLine(state, event, payload, previousJobKey);
13999
+ }
14000
+ function renderRunnerConsoleDashboard(state, nowMs) {
14001
+ if (state.jobs.size === 0 && state.tokenUsage === void 0 && state.rateLimit === void 0) {
14002
+ return void 0;
14003
+ }
14004
+ const jobs = Array.from(state.jobs.values()).sort(
14005
+ (left, right) => right.updatedAtMs - left.updatedAtMs
14006
+ );
14007
+ switch (state.mode.type) {
14008
+ case "table":
14009
+ return renderDashboardTable(state, jobs, nowMs);
14010
+ case "raw_all":
14011
+ return renderRawDashboard(
14012
+ state,
14013
+ "Raw Stream",
14014
+ void 0,
14015
+ "esc: table",
14016
+ state.rawLines,
14017
+ nowMs
14018
+ );
14019
+ case "raw_job": {
14020
+ const jobKey = state.mode.jobKey;
14021
+ const job = state.jobs.get(jobKey);
14022
+ const title = `Raw Stream: ${shortId(job?.linzumiThreadId)} / ${agentId(job?.codexThreadId)}`;
14023
+ return renderRawDashboard(
14024
+ state,
14025
+ title,
14026
+ job?.tokenUsage,
14027
+ "esc: table",
14028
+ state.rawLines.filter((line) => line.jobKey === jobKey),
14029
+ nowMs
14030
+ );
14031
+ }
14032
+ }
14033
+ }
14034
+ function renderDashboardTable(state, jobs, nowMs) {
14035
+ const model = dashboardTableModel(state, jobs, nowMs);
14036
+ return [
14037
+ "Linzumi Commander",
14038
+ "",
14039
+ `Jobs: ${jobs.length} Last update: ${timeAgo(state.lastUpdateAtMs, nowMs)}`,
14040
+ `Overall Token Usage: ${state.tokenUsage ?? "?"}`,
14041
+ `Account rate limits: ${state.rateLimit ?? "?"}`,
14042
+ "Controls: up/down select | enter raw job | r raw stream | esc table",
14043
+ "",
14044
+ table(model.rows),
14045
+ ""
14046
+ ].join("\n");
14047
+ }
14048
+ function dashboardTableModel(state, jobs, nowMs) {
14049
+ const selectedJobKey = selectedDashboardJobKey(state, jobs);
14050
+ const rows = jobs.length === 0 ? [dashboardTableHeader(), emptyJobRow()] : [
14051
+ dashboardTableHeader(),
14052
+ ...jobs.map((job) => jobRow(job, selectedJobKey, nowMs))
14053
+ ];
14054
+ return {
14055
+ jobs,
14056
+ selectedJobKey,
14057
+ rows
14058
+ };
14059
+ }
14060
+ function dashboardTableHeader() {
14061
+ return [
14062
+ "",
14063
+ "Linzumi thread",
14064
+ "Agent",
14065
+ "Last user message",
14066
+ "Ago",
14067
+ "Last assistant reply",
14068
+ "Ago",
14069
+ "Latest event",
14070
+ "Event type"
14071
+ ];
14072
+ }
14073
+ function mergeRateLimitSummary(previous, next) {
14074
+ if (previous === void 0) {
14075
+ return next;
14076
+ }
14077
+ const buckets = /* @__PURE__ */ new Map();
14078
+ for (const summary of previous.split(" | ")) {
14079
+ buckets.set(rateLimitSummaryKey(summary), summary);
14080
+ }
14081
+ for (const summary of next.split(" | ")) {
14082
+ buckets.set(rateLimitSummaryKey(summary), summary);
14083
+ }
14084
+ return Array.from(buckets.values()).join(" | ");
14085
+ }
14086
+ function rateLimitSummaryKey(summary) {
14087
+ return summary.split(" ", 1)[0] ?? summary;
14088
+ }
13633
14089
  function formatRunnerConsoleEvent(event, payload) {
13634
14090
  switch (event) {
13635
14091
  case "runner.instance_started":
@@ -13648,13 +14104,19 @@ function formatRunnerConsoleEvent(event, payload) {
13648
14104
  case "kandan.chat_event_failed":
13649
14105
  return `Incoming message handling failed: seq=${text(payload.seq)} reason=${text(payload.message)}`;
13650
14106
  case "kandan.reconnected":
13651
- return `Kandan reconnected: codex_session=${text(payload.codex_thread_id)} cursor=${text(payload.min_seq)}`;
14107
+ return `Linzumi reconnected: codex_session=${text(payload.codex_thread_id)} cursor=${text(payload.min_seq)}`;
13652
14108
  case "codex.turn_starting":
13653
14109
  return `Incoming message from ${sender(payload)}: forwarding to Codex session ${text(payload.codex_thread_id)} seq=${text(payload.queued_seq)}`;
13654
14110
  case "codex.turn_started":
13655
14111
  return `Codex turn started: id=${text(payload.turn_id)}`;
13656
- case "codex.notification":
13657
- return `Codex event [id=${codexEventId(payload)}]: ${text(payload.method)}`;
14112
+ case "codex.notification": {
14113
+ const summary = [
14114
+ stringValue3(payload.token_usage_summary),
14115
+ stringValue3(payload.rate_limit_summary)
14116
+ ].filter((value) => value !== void 0).join(" | ");
14117
+ const suffix = summary === "" ? "" : ` ${summary}`;
14118
+ return `Codex event [id=${codexEventId(payload)}]: ${text(payload.method)}${suffix}`;
14119
+ }
13658
14120
  case "codex.turn_completed":
13659
14121
  return `Codex turn completed: id=${text(payload.turn_id)} outputs=${text(payload.output_count)}`;
13660
14122
  case "kandan.codex_output_forwarded":
@@ -13687,11 +14149,11 @@ function connectedRunnerMessage(payload) {
13687
14149
  ].filter((line) => line !== void 0).join("\n");
13688
14150
  }
13689
14151
  function optionalLine(label, value) {
13690
- const normalized = stringValue2(value) ?? numberValue(value)?.toString();
14152
+ const normalized = stringValue3(value) ?? numberValue(value)?.toString();
13691
14153
  return normalized === void 0 ? void 0 : `${label}: ${normalized}`;
13692
14154
  }
13693
14155
  function optionalField(label, value) {
13694
- const normalized = stringValue2(value) ?? numberValue(value)?.toString();
14156
+ const normalized = stringValue3(value) ?? numberValue(value)?.toString();
13695
14157
  return normalized === void 0 ? void 0 : `${label}=${normalized}`;
13696
14158
  }
13697
14159
  function ignoredMessage(payload) {
@@ -13715,17 +14177,17 @@ function replacementLines(value) {
13715
14177
  return [];
13716
14178
  }
13717
14179
  const record = entry;
13718
- const runnerId = stringValue2(record.runnerId);
14180
+ const runnerId = stringValue3(record.runnerId);
13719
14181
  if (runnerId === void 0) {
13720
14182
  return [];
13721
14183
  }
13722
- const version = stringValue2(record.version);
14184
+ const version = stringValue3(record.version);
13723
14185
  const suffix = version === void 0 ? "" : ` (CLI ${version})`;
13724
14186
  return [`Replaced older runner from this machine: ${runnerId}${suffix}`];
13725
14187
  });
13726
14188
  }
13727
14189
  function sender(payload) {
13728
- const slug = stringValue2(payload.actor_slug);
14190
+ const slug = stringValue3(payload.actor_slug);
13729
14191
  const userId = numberValue(payload.actor_user_id);
13730
14192
  if (slug !== void 0 && userId !== void 0) {
13731
14193
  return `${slug}#${userId}`;
@@ -13733,7 +14195,7 @@ function sender(payload) {
13733
14195
  return slug ?? (userId === void 0 ? "unknown" : `user#${userId}`);
13734
14196
  }
13735
14197
  function codexOutputLabel(payload) {
13736
- const kind = stringValue2(payload.structured_kind) ?? "output";
14198
+ const kind = stringValue3(payload.structured_kind) ?? "output";
13737
14199
  switch (kind) {
13738
14200
  case "codex_assistant_message":
13739
14201
  return "assistant_message";
@@ -13759,22 +14221,653 @@ function codexEventId(payload) {
13759
14221
  const metadata = payload.metadata;
13760
14222
  if (typeof metadata === "object" && metadata !== null && !Array.isArray(metadata)) {
13761
14223
  const record = metadata;
13762
- return stringValue2(record.turnId) ?? stringValue2(record.itemId) ?? stringValue2(record.threadId) ?? "?";
14224
+ return stringValue3(record.turnId) ?? stringValue3(record.itemId) ?? stringValue3(record.threadId) ?? "?";
13763
14225
  }
13764
14226
  return "?";
13765
14227
  }
14228
+ function rememberRawLine(state, event, payload, previousJobKey) {
14229
+ const line = formatRunnerConsoleEvent(event, payload);
14230
+ if (line === void 0) {
14231
+ return;
14232
+ }
14233
+ const jobKey = dashboardRawLineJobKey(state, payload, previousJobKey);
14234
+ state.rawLines.push({ jobKey, line });
14235
+ if (state.rawLines.length > maxRawLines) {
14236
+ state.rawLines.splice(0, state.rawLines.length - maxRawLines);
14237
+ }
14238
+ }
14239
+ function dashboardRawLineJobKey(state, payload, previousJobKey) {
14240
+ const linzumiThreadId = stringValue3(payload.linzumi_thread_id);
14241
+ const codexThreadId = stringValue3(payload.codex_thread_id);
14242
+ if (linzumiThreadId !== void 0) {
14243
+ return `linzumi:${linzumiThreadId}`;
14244
+ }
14245
+ if (codexThreadId !== void 0) {
14246
+ return Array.from(state.jobs.values()).find(
14247
+ (job) => job.codexThreadId === codexThreadId
14248
+ )?.key;
14249
+ }
14250
+ const metadata = objectValue4(payload.metadata);
14251
+ const metadataCodexThreadId = stringValue3(metadata?.threadId);
14252
+ if (metadataCodexThreadId !== void 0) {
14253
+ return Array.from(state.jobs.values()).find(
14254
+ (job) => job.codexThreadId === metadataCodexThreadId
14255
+ )?.key;
14256
+ }
14257
+ return previousJobKey;
14258
+ }
14259
+ function selectedDashboardJobKey(state, jobs) {
14260
+ if (jobs.length === 0) {
14261
+ state.selectedJobKey = void 0;
14262
+ return void 0;
14263
+ }
14264
+ if (state.selectedJobKey === void 0 || jobs.every((job) => job.key !== state.selectedJobKey)) {
14265
+ state.selectedJobKey = jobs[0]?.key;
14266
+ }
14267
+ return state.selectedJobKey;
14268
+ }
14269
+ function renderRawDashboard(state, title, tokenUsage, controls, lines, nowMs) {
14270
+ const visibleLines = lines.slice(-40).map((entry) => entry.line);
14271
+ return [
14272
+ "Linzumi Commander",
14273
+ "",
14274
+ `${title} Last update: ${timeAgo(state.lastUpdateAtMs, nowMs)}`,
14275
+ ...tokenUsage === void 0 ? [] : [`Token usage: ${tokenUsage}`],
14276
+ `Controls: ${controls}`,
14277
+ "",
14278
+ ...visibleLines.length === 0 ? ["No raw events yet."] : visibleLines,
14279
+ ""
14280
+ ].join("\n");
14281
+ }
14282
+ function rawDashboardModel(state, mode) {
14283
+ switch (mode.type) {
14284
+ case "raw_all":
14285
+ return {
14286
+ title: "Raw Stream",
14287
+ tokenUsage: void 0,
14288
+ lines: state.rawLines.map((entry) => entry.line)
14289
+ };
14290
+ case "raw_job": {
14291
+ const jobKey = mode.jobKey;
14292
+ const job = state.jobs.get(jobKey);
14293
+ return {
14294
+ title: `Raw Stream: ${shortId(job?.linzumiThreadId)} / ${agentId(job?.codexThreadId)}`,
14295
+ tokenUsage: job?.tokenUsage,
14296
+ lines: state.rawLines.filter((line) => line.jobKey === jobKey).map((entry) => entry.line)
14297
+ };
14298
+ }
14299
+ }
14300
+ }
14301
+ function dashboardJobs(state) {
14302
+ return Array.from(state.jobs.values()).sort(
14303
+ (left, right) => right.updatedAtMs - left.updatedAtMs
14304
+ );
14305
+ }
14306
+ function selectDashboardJobAtVisibleIndex(state, index) {
14307
+ const jobs = dashboardJobs(state);
14308
+ const job = jobs[index];
14309
+ if (job !== void 0) {
14310
+ state.selectedJobKey = job.key;
14311
+ }
14312
+ }
14313
+ function moveSelection(state, direction) {
14314
+ const jobs = dashboardJobs(state);
14315
+ if (jobs.length === 0) {
14316
+ state.selectedJobKey = void 0;
14317
+ return;
14318
+ }
14319
+ const selectedKey = selectedDashboardJobKey(state, jobs);
14320
+ const currentIndex = Math.max(
14321
+ 0,
14322
+ jobs.findIndex((job) => job.key === selectedKey)
14323
+ );
14324
+ const nextIndex = Math.min(
14325
+ jobs.length - 1,
14326
+ Math.max(0, currentIndex + direction)
14327
+ );
14328
+ state.selectedJobKey = jobs[nextIndex]?.key;
14329
+ }
14330
+ function initializeDashboardKeyboard(state) {
14331
+ if (keyboardState.initialized || process.stdin.isTTY !== true || typeof process.stdin.setRawMode !== "function") {
14332
+ return;
14333
+ }
14334
+ keyboardState.initialized = true;
14335
+ process.stdin.setRawMode(true);
14336
+ process.stdin.resume();
14337
+ process.stdin.on("data", (chunk) => {
14338
+ handleDashboardKey(state, chunk.toString("utf8"));
14339
+ });
14340
+ }
14341
+ function initializeDashboardTicker(state) {
14342
+ if (tickerState.stop !== void 0) {
14343
+ return;
14344
+ }
14345
+ tickerState.stop = startRunnerConsoleDashboardTicker(state);
14346
+ }
14347
+ function initializeDashboardTui(state) {
14348
+ if (tuiState.dashboard !== void 0) {
14349
+ return tuiState.dashboard;
14350
+ }
14351
+ if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
14352
+ return void 0;
14353
+ }
14354
+ const dashboard = createRunnerConsoleDashboardTui(state);
14355
+ tuiState.dashboard = dashboard;
14356
+ tuiState.stop = startRunnerConsoleDashboardRenderTicker(() => {
14357
+ dashboard.render(Date.now());
14358
+ });
14359
+ return dashboard;
14360
+ }
14361
+ function startRunnerConsoleDashboardTicker(state, redraw = redrawScreen, intervalMs = 1e3) {
14362
+ const interval = setInterval(() => {
14363
+ const screen = renderRunnerConsoleDashboard(state, Date.now());
14364
+ if (screen !== void 0) {
14365
+ redraw(screen);
14366
+ }
14367
+ }, intervalMs);
14368
+ interval.unref?.();
14369
+ return () => {
14370
+ clearInterval(interval);
14371
+ };
14372
+ }
14373
+ function startRunnerConsoleDashboardRenderTicker(render, intervalMs = 1e3) {
14374
+ const interval = setInterval(render, intervalMs);
14375
+ interval.unref?.();
14376
+ return () => {
14377
+ clearInterval(interval);
14378
+ };
14379
+ }
14380
+ function handleDashboardKey(state, key, exitProcess = () => process.kill(process.pid, "SIGINT")) {
14381
+ if (key === ctrlCKey) {
14382
+ exitProcess();
14383
+ return;
14384
+ }
14385
+ updateRunnerConsoleDashboardMode(state, key);
14386
+ const screen = renderRunnerConsoleDashboard(state, Date.now());
14387
+ if (screen !== void 0) {
14388
+ redrawScreen(screen);
14389
+ }
14390
+ }
14391
+ function createRunnerConsoleDashboardTui(state, exitProcess = () => process.kill(process.pid, "SIGINT")) {
14392
+ let rendering = false;
14393
+ let rawScrollAnchor;
14394
+ const screen = blessed.screen({
14395
+ title: "Linzumi Commander",
14396
+ smartCSR: true,
14397
+ fullUnicode: true,
14398
+ mouse: true
14399
+ });
14400
+ const header = blessed.box({
14401
+ top: 0,
14402
+ left: 0,
14403
+ width: "100%",
14404
+ height: 6,
14405
+ tags: false
14406
+ });
14407
+ const tableElement = blessed.listtable({
14408
+ top: 6,
14409
+ left: 0,
14410
+ width: "100%",
14411
+ bottom: 1,
14412
+ keys: true,
14413
+ vi: true,
14414
+ mouse: true,
14415
+ scrollable: true,
14416
+ alwaysScroll: true,
14417
+ border: "line",
14418
+ pad: 1,
14419
+ data: [dashboardTableHeader(), emptyJobRow()],
14420
+ scrollbar: {
14421
+ ch: " ",
14422
+ style: { inverse: true }
14423
+ },
14424
+ style: {
14425
+ header: { bold: true },
14426
+ cell: {
14427
+ selected: {
14428
+ inverse: true
14429
+ }
14430
+ },
14431
+ border: {
14432
+ fg: "grey"
14433
+ }
14434
+ }
14435
+ });
14436
+ const rawTitle = blessed.box({
14437
+ top: 0,
14438
+ left: 12,
14439
+ right: 0,
14440
+ height: 2,
14441
+ tags: false,
14442
+ hidden: true
14443
+ });
14444
+ const backButton = blessed.button({
14445
+ top: 0,
14446
+ left: 0,
14447
+ width: 10,
14448
+ height: 1,
14449
+ content: "< Back",
14450
+ mouse: true,
14451
+ keys: true,
14452
+ shrink: true,
14453
+ hidden: true,
14454
+ style: {
14455
+ focus: { inverse: true },
14456
+ hover: { inverse: true }
14457
+ }
14458
+ });
14459
+ const rawBox = blessed.box({
14460
+ top: 3,
14461
+ left: 0,
14462
+ width: "100%",
14463
+ bottom: 0,
14464
+ keys: true,
14465
+ vi: true,
14466
+ mouse: true,
14467
+ scrollable: true,
14468
+ alwaysScroll: true,
14469
+ border: "line",
14470
+ tags: false,
14471
+ hidden: true,
14472
+ scrollbar: {
14473
+ ch: " ",
14474
+ style: { inverse: true }
14475
+ },
14476
+ style: {
14477
+ border: {
14478
+ fg: "grey"
14479
+ }
14480
+ }
14481
+ });
14482
+ screen.append(header);
14483
+ screen.append(tableElement);
14484
+ screen.append(rawTitle);
14485
+ screen.append(backButton);
14486
+ screen.append(rawBox);
14487
+ const showTable = () => {
14488
+ state.mode = { type: "table" };
14489
+ render(Date.now());
14490
+ };
14491
+ const showAllRaw = () => {
14492
+ state.mode = { type: "raw_all" };
14493
+ render(Date.now());
14494
+ };
14495
+ const showSelectedRaw = () => {
14496
+ const selectedKey = selectedDashboardJobKey(state, dashboardJobs(state));
14497
+ if (selectedKey !== void 0) {
14498
+ state.mode = { type: "raw_job", jobKey: selectedKey };
14499
+ render(Date.now());
14500
+ }
14501
+ };
14502
+ screen.key(["C-c"], () => {
14503
+ destroy();
14504
+ exitProcess();
14505
+ });
14506
+ screen.key(["escape"], showTable);
14507
+ screen.key(["r"], showAllRaw);
14508
+ tableElement.key(["enter"], showSelectedRaw);
14509
+ tableElement.on("select item", (_item, index) => {
14510
+ if (rendering || state.mode.type !== "table") {
14511
+ return;
14512
+ }
14513
+ selectDashboardJobAtVisibleIndex(state, index - 1);
14514
+ });
14515
+ tableElement.on("select", (_item, index) => {
14516
+ if (rendering || state.mode.type !== "table") {
14517
+ return;
14518
+ }
14519
+ selectDashboardJobAtVisibleIndex(state, index - 1);
14520
+ showSelectedRaw();
14521
+ });
14522
+ backButton.on("press", showTable);
14523
+ backButton.on("click", showTable);
14524
+ function render(nowMs) {
14525
+ rendering = true;
14526
+ try {
14527
+ switch (state.mode.type) {
14528
+ case "table": {
14529
+ const model = dashboardTableModel(state, dashboardJobs(state), nowMs);
14530
+ header.setContent(tuiHeaderContent(state, model.jobs.length, nowMs));
14531
+ header.show();
14532
+ tableElement.setData(model.rows);
14533
+ tableElement.show();
14534
+ rawTitle.hide();
14535
+ backButton.hide();
14536
+ rawBox.hide();
14537
+ rawScrollAnchor = void 0;
14538
+ syncTuiTableSelection(tableElement, model);
14539
+ tableElement.focus();
14540
+ break;
14541
+ }
14542
+ case "raw_all":
14543
+ case "raw_job": {
14544
+ const model = rawDashboardModel(state, state.mode);
14545
+ const nextRawScrollAnchor = `${state.mode.type}:${state.mode.type === "raw_job" ? state.mode.jobKey : "*"}:${model.lines.length}`;
14546
+ header.hide();
14547
+ tableElement.hide();
14548
+ rawTitle.setContent(
14549
+ [
14550
+ `${model.title} Last update: ${timeAgo(state.lastUpdateAtMs, nowMs)} esc/back: table`,
14551
+ model.tokenUsage === void 0 ? void 0 : `Token usage: ${model.tokenUsage}`
14552
+ ].filter((value) => value !== void 0).join("\n")
14553
+ );
14554
+ rawBox.setContent(
14555
+ model.lines.length === 0 ? "No raw events yet." : model.lines.join("\n")
14556
+ );
14557
+ rawTitle.show();
14558
+ backButton.show();
14559
+ rawBox.show();
14560
+ if (rawScrollAnchor !== nextRawScrollAnchor) {
14561
+ rawBox.setScrollPerc(100);
14562
+ rawScrollAnchor = nextRawScrollAnchor;
14563
+ }
14564
+ rawBox.focus();
14565
+ break;
14566
+ }
14567
+ }
14568
+ screen.render();
14569
+ } finally {
14570
+ rendering = false;
14571
+ }
14572
+ }
14573
+ function destroy() {
14574
+ tuiState.stop?.();
14575
+ tuiState.stop = void 0;
14576
+ tuiState.dashboard = void 0;
14577
+ screen.destroy();
14578
+ }
14579
+ return { render, destroy };
14580
+ }
14581
+ function syncTuiTableSelection(tableElement, model) {
14582
+ const selectedIndex = model.jobs.findIndex(
14583
+ (job) => job.key === model.selectedJobKey
14584
+ );
14585
+ const tableIndex = selectedIndex < 0 ? 1 : selectedIndex + 1;
14586
+ tableElement.select(tableIndex);
14587
+ }
14588
+ function tuiHeaderContent(state, jobCount, nowMs) {
14589
+ return [
14590
+ "Linzumi Commander",
14591
+ `Jobs: ${jobCount} Last update: ${timeAgo(state.lastUpdateAtMs, nowMs)}`,
14592
+ `Overall Token Usage: ${state.tokenUsage ?? "?"}`,
14593
+ `Account rate limits: ${state.rateLimit ?? "?"}`,
14594
+ "Controls: click row/enter raw job | r raw stream | esc/back table | mouse wheel scroll"
14595
+ ].join("\n");
14596
+ }
14597
+ function updateRunnerConsoleDashboardMode(state, key) {
14598
+ switch (key) {
14599
+ case "r":
14600
+ state.mode = { type: "raw_all" };
14601
+ break;
14602
+ case escapeKey:
14603
+ state.mode = { type: "table" };
14604
+ break;
14605
+ case enterKey: {
14606
+ const selectedKey = selectedDashboardJobKey(state, dashboardJobs(state));
14607
+ if (selectedKey !== void 0) {
14608
+ state.mode = { type: "raw_job", jobKey: selectedKey };
14609
+ }
14610
+ break;
14611
+ }
14612
+ case upKey:
14613
+ moveSelection(state, -1);
14614
+ break;
14615
+ case downKey:
14616
+ moveSelection(state, 1);
14617
+ break;
14618
+ default:
14619
+ break;
14620
+ }
14621
+ }
14622
+ function dashboardJobForPayload(state, payload, nowMs) {
14623
+ const linzumiThreadId = stringValue3(payload.linzumi_thread_id);
14624
+ const codexThreadId = stringValue3(payload.codex_thread_id);
14625
+ const existingByCodex = codexThreadId !== void 0 ? Array.from(state.jobs.values()).find(
14626
+ (job) => job.codexThreadId === codexThreadId
14627
+ ) : void 0;
14628
+ if (existingByCodex !== void 0) {
14629
+ return promoteDashboardJobKey(state, existingByCodex, linzumiThreadId);
14630
+ }
14631
+ const key = linzumiThreadId === void 0 ? codexThreadId === void 0 ? "job:unknown" : `codex:${codexThreadId}` : `linzumi:${linzumiThreadId}`;
14632
+ const existing = state.jobs.get(key);
14633
+ if (existing !== void 0) {
14634
+ return existing;
14635
+ }
14636
+ const created = {
14637
+ key,
14638
+ linzumiThreadId,
14639
+ codexThreadId,
14640
+ tokenUsage: void 0,
14641
+ lastIncomingPreview: void 0,
14642
+ lastIncomingAtMs: void 0,
14643
+ lastAssistantPreview: void 0,
14644
+ lastAssistantAtMs: void 0,
14645
+ latestCodexEventId: void 0,
14646
+ eventType: void 0,
14647
+ queueDepth: void 0,
14648
+ turnId: void 0,
14649
+ updatedAtMs: nowMs
14650
+ };
14651
+ state.jobs.set(key, created);
14652
+ return created;
14653
+ }
14654
+ function promoteDashboardJobKey(state, job, linzumiThreadId) {
14655
+ if (linzumiThreadId === void 0) {
14656
+ return job;
14657
+ }
14658
+ const key = `linzumi:${linzumiThreadId}`;
14659
+ if (job.key === key) {
14660
+ job.linzumiThreadId = linzumiThreadId;
14661
+ return job;
14662
+ }
14663
+ const promoted = { ...job, key, linzumiThreadId };
14664
+ state.jobs.delete(job.key);
14665
+ state.jobs.set(key, promoted);
14666
+ if (state.selectedJobKey === job.key) {
14667
+ state.selectedJobKey = key;
14668
+ }
14669
+ if (state.mode.type === "raw_job" && state.mode.jobKey === job.key) {
14670
+ state.mode = { type: "raw_job", jobKey: key };
14671
+ }
14672
+ state.rawLines.splice(
14673
+ 0,
14674
+ state.rawLines.length,
14675
+ ...state.rawLines.map(
14676
+ (line) => line.jobKey === job.key ? { ...line, jobKey: key } : line
14677
+ )
14678
+ );
14679
+ return promoted;
14680
+ }
14681
+ function dashboardJobForKey(state, key, nowMs) {
14682
+ if (key.startsWith("codex:")) {
14683
+ const codexThreadId = key.slice("codex:".length);
14684
+ const existingByCodex = Array.from(state.jobs.values()).find(
14685
+ (job) => job.codexThreadId === codexThreadId
14686
+ );
14687
+ if (existingByCodex !== void 0) {
14688
+ return existingByCodex;
14689
+ }
14690
+ }
14691
+ const existing = state.jobs.get(key);
14692
+ if (existing !== void 0) {
14693
+ return existing;
14694
+ }
14695
+ const created = {
14696
+ key,
14697
+ linzumiThreadId: void 0,
14698
+ codexThreadId: key.startsWith("codex:") ? key.slice("codex:".length) : void 0,
14699
+ tokenUsage: void 0,
14700
+ lastIncomingPreview: void 0,
14701
+ lastIncomingAtMs: void 0,
14702
+ lastAssistantPreview: void 0,
14703
+ lastAssistantAtMs: void 0,
14704
+ latestCodexEventId: void 0,
14705
+ eventType: void 0,
14706
+ queueDepth: void 0,
14707
+ turnId: void 0,
14708
+ updatedAtMs: nowMs
14709
+ };
14710
+ state.jobs.set(key, created);
14711
+ return created;
14712
+ }
14713
+ function latestDashboardJob(state) {
14714
+ return Array.from(state.jobs.values()).sort(
14715
+ (left, right) => right.updatedAtMs - left.updatedAtMs
14716
+ )[0];
14717
+ }
14718
+ function jobRow(job, selectedJobKey, nowMs) {
14719
+ return [
14720
+ job.key === selectedJobKey ? ">" : " ",
14721
+ shortId(job.linzumiThreadId),
14722
+ agentId(job.codexThreadId),
14723
+ truncate(job.lastIncomingPreview ?? "?", 50),
14724
+ timeAgo(job.lastIncomingAtMs, nowMs),
14725
+ truncate(job.lastAssistantPreview ?? "?", 50),
14726
+ timeAgo(job.lastAssistantAtMs, nowMs),
14727
+ lastFour(job.latestCodexEventId),
14728
+ truncate(job.eventType ?? "?", 34)
14729
+ ];
14730
+ }
14731
+ function emptyJobRow() {
14732
+ return [" ", "?", "?", "?", "?", "?", "?", "?", "?"];
14733
+ }
14734
+ function codexOutputDashboardLabel(event, payload) {
14735
+ switch (event) {
14736
+ case "kandan.codex_output_forwarded":
14737
+ return codexOutputLabel(payload);
14738
+ case "kandan.codex_delta_forwarded":
14739
+ return "assistant_delta";
14740
+ case "kandan.codex_reasoning_delta_forwarded":
14741
+ return "reasoning_delta";
14742
+ case "kandan.codex_command_output_forwarded":
14743
+ return `command_output ${text(payload.stream)}`;
14744
+ case "kandan.codex_file_change_forwarded":
14745
+ return "file_change";
14746
+ case "kandan.codex_web_search_progress_forwarded":
14747
+ return "search_progress";
14748
+ default:
14749
+ return event;
14750
+ }
14751
+ }
14752
+ function dashboardEventLabel(event) {
14753
+ switch (event) {
14754
+ case "kandan.message_queued":
14755
+ return "message_queued";
14756
+ case "codex.turn_starting":
14757
+ return "turn_starting";
14758
+ default:
14759
+ return event;
14760
+ }
14761
+ }
14762
+ function table(rows) {
14763
+ if (rows.length === 0) {
14764
+ return "";
14765
+ }
14766
+ const widths = dashboardTableColumns.map((column) => column.width);
14767
+ const divider = widths.map((width) => "-".repeat(width)).join("-+-");
14768
+ return rows.map((row, index) => {
14769
+ const line = row.map(
14770
+ (cell, cellIndex) => fixedWidthCell(cell, widths[cellIndex] ?? displayWidth(cell))
14771
+ ).join(" | ");
14772
+ return index === 0 ? `${line}
14773
+ ${divider}` : line;
14774
+ }).join("\n");
14775
+ }
14776
+ function displayWidth(value) {
14777
+ return value.length;
14778
+ }
14779
+ function shortId(value) {
14780
+ return value === void 0 ? "?" : truncate(value, 18);
14781
+ }
14782
+ function agentId(codexThreadId) {
14783
+ if (codexThreadId === void 0) {
14784
+ return "?";
14785
+ }
14786
+ return `codex/...${lastN(codexThreadId, 5)}`;
14787
+ }
14788
+ function fixedWidthCell(value, width) {
14789
+ return truncate(value, width).padEnd(width, " ");
14790
+ }
14791
+ function truncate(value, maxLength) {
14792
+ if (value.length <= maxLength) {
14793
+ return value;
14794
+ }
14795
+ return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
14796
+ }
14797
+ function lastFour(value) {
14798
+ if (value === void 0) {
14799
+ return "?";
14800
+ }
14801
+ return lastN(value, 4);
14802
+ }
14803
+ function lastN(value, count) {
14804
+ return value.length <= count ? value : value.slice(-count);
14805
+ }
14806
+ function timeAgo(valueMs, nowMs) {
14807
+ if (valueMs === void 0) {
14808
+ return "?";
14809
+ }
14810
+ const seconds = Math.max(0, Math.floor((nowMs - valueMs) / 1e3));
14811
+ if (seconds < 60) {
14812
+ return `${seconds}s`;
14813
+ }
14814
+ const minutes = Math.floor(seconds / 60);
14815
+ if (minutes < 60) {
14816
+ return `${minutes}m`;
14817
+ }
14818
+ return `${Math.floor(minutes / 60)}h`;
14819
+ }
14820
+ function objectValue4(value) {
14821
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
14822
+ }
13766
14823
  function text(value) {
13767
- return stringValue2(value) ?? numberValue(value)?.toString() ?? "?";
14824
+ return stringValue3(value) ?? numberValue(value)?.toString() ?? "?";
13768
14825
  }
13769
- function stringValue2(value) {
14826
+ function stringValue3(value) {
13770
14827
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
13771
14828
  }
13772
14829
  function numberValue(value) {
13773
14830
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
13774
14831
  }
14832
+ var dashboardState, maxRawLines, escapeKey, ctrlCKey, enterKey, upKey, downKey, dashboardTableColumns, redrawScreen, keyboardState, tickerState, tuiState;
13775
14833
  var init_runnerConsoleReporter = __esm({
13776
14834
  "src/runnerConsoleReporter.ts"() {
13777
14835
  "use strict";
14836
+ dashboardState = {
14837
+ jobs: /* @__PURE__ */ new Map(),
14838
+ rawLines: [],
14839
+ mode: { type: "table" },
14840
+ selectedJobKey: void 0,
14841
+ tokenUsage: void 0,
14842
+ rateLimit: void 0,
14843
+ lastUpdateAtMs: void 0
14844
+ };
14845
+ maxRawLines = 500;
14846
+ escapeKey = "\x1B";
14847
+ ctrlCKey = "";
14848
+ enterKey = "\r";
14849
+ upKey = "\x1B[A";
14850
+ downKey = "\x1B[B";
14851
+ dashboardTableColumns = [
14852
+ { width: 1 },
14853
+ { width: 20 },
14854
+ { width: 16 },
14855
+ { width: 38 },
14856
+ { width: 6 },
14857
+ { width: 42 },
14858
+ { width: 6 },
14859
+ { width: 12 },
14860
+ { width: 24 }
14861
+ ];
14862
+ redrawScreen = (screen) => {
14863
+ process.stdout.write(`\x1B[2J\x1B[H${screen}`);
14864
+ };
14865
+ keyboardState = { initialized: false };
14866
+ tickerState = { stop: void 0 };
14867
+ tuiState = {
14868
+ dashboard: void 0,
14869
+ stop: void 0
14870
+ };
13778
14871
  }
13779
14872
  });
13780
14873
 
@@ -15536,7 +16629,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15536
16629
  if (workspaceSlug === void 0 || channelSlug === void 0 || kandanThreadId === void 0) {
15537
16630
  return void 0;
15538
16631
  }
15539
- const existingSession = dynamicChannelSessions.get(kandanThreadId);
16632
+ const existingSession = dynamicChannelSessions.get(codexThreadId);
15540
16633
  if (existingSession !== void 0) {
15541
16634
  return existingSession;
15542
16635
  }
@@ -15599,16 +16692,15 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15599
16692
  },
15600
16693
  log
15601
16694
  });
15602
- dynamicChannelSessions.set(kandanThreadId, session);
16695
+ dynamicChannelSessions.set(codexThreadId, session);
15603
16696
  if (sessionCodex !== codex) {
15604
16697
  sessionCodex.onNotification((notification) => {
15605
16698
  seq.value += 1;
15606
16699
  const params = notification.params ?? {};
15607
- const metadata = extractCodexIds(params);
15608
- log("codex.notification", {
15609
- method: notification.method,
15610
- metadata
15611
- });
16700
+ log(
16701
+ "codex.notification",
16702
+ codexNotificationConsoleLogPayload(notification.method, params)
16703
+ );
15612
16704
  session.handleCodexNotification(notification.method, params);
15613
16705
  });
15614
16706
  }
@@ -15823,14 +16915,17 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15823
16915
  codex.onNotification((notification) => {
15824
16916
  seq.value += 1;
15825
16917
  const params = notification.params ?? {};
15826
- const metadata = extractCodexIds(params);
16918
+ const logPayload = codexNotificationConsoleLogPayload(
16919
+ notification.method,
16920
+ params
16921
+ );
15827
16922
  if (channelSession === void 0) {
15828
16923
  void kandan.push(topic, "codex_notification", {
15829
16924
  instanceId,
15830
16925
  seq: seq.value,
15831
16926
  method: notification.method,
15832
16927
  params,
15833
- metadata,
16928
+ metadata: logPayload.metadata,
15834
16929
  receivedAt: (/* @__PURE__ */ new Date()).toISOString()
15835
16930
  }).catch((error) => {
15836
16931
  log("kandan.codex_notification_push_failed", {
@@ -15838,10 +16933,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15838
16933
  });
15839
16934
  });
15840
16935
  }
15841
- log("codex.notification", {
15842
- method: notification.method,
15843
- metadata
15844
- });
16936
+ log("codex.notification", logPayload);
15845
16937
  channelSession?.handleCodexNotification(notification.method, params);
15846
16938
  for (const session of dynamicChannelSessions.values()) {
15847
16939
  session.handleCodexNotification(notification.method, params);
@@ -16170,13 +17262,35 @@ function controlThreadId(control) {
16170
17262
  async function resolveSessionControl(channelSession, dynamicChannelSessions, control) {
16171
17263
  const targetThreadId = controlThreadId(control);
16172
17264
  if (targetThreadId !== void 0) {
16173
- const targetDynamicSession = dynamicChannelSessions.get(targetThreadId);
17265
+ const directDynamicSession = dynamicChannelSessions.get(targetThreadId);
17266
+ const targetDynamicSessions = Array.from(
17267
+ /* @__PURE__ */ new Set([
17268
+ ...directDynamicSession === void 0 ? [] : [directDynamicSession],
17269
+ ...Array.from(dynamicChannelSessions.values()).filter(
17270
+ (session) => session.currentKandanThreadId() === targetThreadId
17271
+ )
17272
+ ])
17273
+ );
16174
17274
  const targetSessions = [
16175
17275
  ...channelSession?.currentKandanThreadId() === targetThreadId ? [channelSession] : [],
16176
- ...targetDynamicSession !== void 0 && targetDynamicSession !== channelSession ? [targetDynamicSession] : []
17276
+ ...targetDynamicSessions.filter((session) => session !== channelSession)
16177
17277
  ].filter(
16178
17278
  (session) => session !== void 0
16179
17279
  );
17280
+ if (control.type === "update_thread_interaction_access") {
17281
+ let firstHandled;
17282
+ let firstOk;
17283
+ for (const session of targetSessions) {
17284
+ const handled = await session.handleControl(control);
17285
+ if (handled !== void 0) {
17286
+ firstHandled ??= handled;
17287
+ if (handled.ok === true) {
17288
+ firstOk ??= handled;
17289
+ }
17290
+ }
17291
+ }
17292
+ return firstOk ?? firstHandled;
17293
+ }
16180
17294
  for (const session of targetSessions) {
16181
17295
  const handled = await session.handleControl(control);
16182
17296
  if (handled !== void 0) {
@@ -16430,7 +17544,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16430
17544
  topic,
16431
17545
  control,
16432
17546
  cwd.reason,
16433
- allowedCwds.value
17547
+ allowedCwds.value,
17548
+ { instanceId }
16434
17549
  );
16435
17550
  } catch (error) {
16436
17551
  log("kandan.start_instance_cwd_failed_state_push_failed", {
@@ -16454,7 +17569,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16454
17569
  topic,
16455
17570
  control,
16456
17571
  "failed",
16457
- startInstanceUnavailableReason(agentProvider)
17572
+ startInstanceUnavailableReason(agentProvider),
17573
+ { instanceId }
16458
17574
  );
16459
17575
  } catch (error) {
16460
17576
  log("kandan.start_instance_unavailable_state_push_failed", {
@@ -16472,7 +17588,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16472
17588
  const processingStatePayload = startInstanceMessageStatePayload(
16473
17589
  control,
16474
17590
  "processing",
16475
- `starting ${startInstanceAgentLabel(agentProvider)} session`
17591
+ `starting ${startInstanceAgentLabel(agentProvider)} session`,
17592
+ { instanceId }
16476
17593
  );
16477
17594
  if (processingStatePayload !== void 0) {
16478
17595
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16542,7 +17659,7 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16542
17659
  control,
16543
17660
  "failed",
16544
17661
  failureReason,
16545
- { codexThreadId: startedCodexThreadId }
17662
+ { codexThreadId: startedCodexThreadId, instanceId }
16546
17663
  );
16547
17664
  } catch (_publishError) {
16548
17665
  }
@@ -16560,7 +17677,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16560
17677
  topic,
16561
17678
  control,
16562
17679
  cwd.reason,
16563
- allowedCwds.value
17680
+ allowedCwds.value,
17681
+ { instanceId }
16564
17682
  );
16565
17683
  } catch (error) {
16566
17684
  log("kandan.reconnect_thread_cwd_failed_state_push_failed", {
@@ -16596,7 +17714,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16596
17714
  topic,
16597
17715
  control,
16598
17716
  "failed",
16599
- startInstanceUnavailableReason(agentProvider)
17717
+ startInstanceUnavailableReason(agentProvider),
17718
+ { instanceId }
16600
17719
  );
16601
17720
  } catch (error) {
16602
17721
  log("kandan.reconnect_thread_unavailable_state_push_failed", {
@@ -16635,7 +17754,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16635
17754
  const processingStatePayload = startInstanceMessageStatePayload(
16636
17755
  control,
16637
17756
  "processing",
16638
- "queued Claude Code input"
17757
+ "queued Claude Code input",
17758
+ { instanceId, codexThreadId }
16639
17759
  );
16640
17760
  if (processingStatePayload !== void 0) {
16641
17761
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16670,7 +17790,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16670
17790
  topic,
16671
17791
  control,
16672
17792
  "failed",
16673
- reason
17793
+ reason,
17794
+ { instanceId, codexThreadId }
16674
17795
  );
16675
17796
  } catch (error) {
16676
17797
  log("kandan.reconnect_thread_queue_failed_state_push_failed", {
@@ -16700,7 +17821,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16700
17821
  topic,
16701
17822
  control,
16702
17823
  "failed",
16703
- reason
17824
+ reason,
17825
+ { instanceId, codexThreadId }
16704
17826
  );
16705
17827
  } catch (pushError) {
16706
17828
  log("kandan.reconnect_thread_queue_closed_state_push_failed", {
@@ -16739,7 +17861,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16739
17861
  const processingStatePayload = startInstanceMessageStatePayload(
16740
17862
  control,
16741
17863
  "processing",
16742
- "resuming Claude Code session"
17864
+ "resuming Claude Code session",
17865
+ { instanceId, codexThreadId }
16743
17866
  );
16744
17867
  if (processingStatePayload !== void 0) {
16745
17868
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16785,7 +17908,7 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16785
17908
  control,
16786
17909
  "failed",
16787
17910
  failureReason,
16788
- { codexThreadId }
17911
+ { codexThreadId, instanceId }
16789
17912
  );
16790
17913
  } catch (_publishError) {
16791
17914
  }
@@ -17536,7 +18659,8 @@ async function startClaudeCodeProviderInstance(args) {
17536
18659
  args.topic,
17537
18660
  args.control,
17538
18661
  "failed",
17539
- reason
18662
+ reason,
18663
+ { instanceId: args.instanceId }
17540
18664
  );
17541
18665
  } catch (error) {
17542
18666
  args.log(
@@ -18361,7 +19485,7 @@ async function publishStartInstanceMessageState(kandan, topic, control, status,
18361
19485
  }
18362
19486
  await kandan.push(topic, "message_state", payload);
18363
19487
  }
18364
- async function publishStartInstanceCwdFailureMessageState(kandan, topic, control, reason, allowedCwds) {
19488
+ async function publishStartInstanceCwdFailureMessageState(kandan, topic, control, reason, allowedCwds, diagnostics = {}) {
18365
19489
  const rootSeq = integerValue(control.rootSeq);
18366
19490
  const sourceSeq = integerValue(control.sourceSeq) ?? rootSeq;
18367
19491
  if (sourceSeq === void 0) {
@@ -18377,6 +19501,7 @@ async function publishStartInstanceCwdFailureMessageState(kandan, topic, control
18377
19501
  workspace,
18378
19502
  channel,
18379
19503
  thread_id: threadId,
19504
+ ...diagnostics.instanceId === void 0 ? {} : { instance_id: diagnostics.instanceId },
18380
19505
  seq: sourceSeq,
18381
19506
  status: "failed",
18382
19507
  reason,
@@ -18414,6 +19539,7 @@ function startInstanceMessageStatePayload(control, status, reason, diagnostics =
18414
19539
  workspace,
18415
19540
  channel,
18416
19541
  thread_id: threadId,
19542
+ ...diagnostics.instanceId === void 0 ? {} : { instance_id: diagnostics.instanceId },
18417
19543
  seq: sourceSeq,
18418
19544
  status,
18419
19545
  reason,
@@ -19369,6 +20495,7 @@ var init_runner = __esm({
19369
20495
  init_codexAppServer();
19370
20496
  init_codexProjectTrust();
19371
20497
  init_codexRuntimeOptions();
20498
+ init_codexNotificationConsoleStats();
19372
20499
  init_json();
19373
20500
  init_linzumiContext();
19374
20501
  init_localCapabilities();
@@ -29718,23 +30845,23 @@ var require_sbcs = __commonJS({
29718
30845
  this.ngramList = theNgramList;
29719
30846
  this.byteMap = theByteMap;
29720
30847
  }
29721
- search(table, value) {
30848
+ search(table2, value) {
29722
30849
  let index = 0;
29723
- if (table[index + 32] <= value)
30850
+ if (table2[index + 32] <= value)
29724
30851
  index += 32;
29725
- if (table[index + 16] <= value)
30852
+ if (table2[index + 16] <= value)
29726
30853
  index += 16;
29727
- if (table[index + 8] <= value)
30854
+ if (table2[index + 8] <= value)
29728
30855
  index += 8;
29729
- if (table[index + 4] <= value)
30856
+ if (table2[index + 4] <= value)
29730
30857
  index += 4;
29731
- if (table[index + 2] <= value)
30858
+ if (table2[index + 2] <= value)
29732
30859
  index += 2;
29733
- if (table[index + 1] <= value)
30860
+ if (table2[index + 1] <= value)
29734
30861
  index += 1;
29735
- if (table[index] > value)
30862
+ if (table2[index] > value)
29736
30863
  index -= 1;
29737
- if (index < 0 || table[index] != value)
30864
+ if (index < 0 || table2[index] != value)
29738
30865
  return -1;
29739
30866
  return index;
29740
30867
  }
@@ -36373,15 +37500,15 @@ var require_dbcs_codec = __commonJS({
36373
37500
  this.nodeIdx = 0;
36374
37501
  return ret;
36375
37502
  };
36376
- function findIdx(table, val) {
36377
- if (table[0] > val) {
37503
+ function findIdx(table2, val) {
37504
+ if (table2[0] > val) {
36378
37505
  return -1;
36379
37506
  }
36380
37507
  var l = 0;
36381
- var r = table.length;
37508
+ var r = table2.length;
36382
37509
  while (l < r - 1) {
36383
37510
  var mid = l + (r - l + 1 >> 1);
36384
- if (table[mid] <= val) {
37511
+ if (table2[mid] <= val) {
36385
37512
  l = mid;
36386
37513
  } else {
36387
37514
  r = mid;
@@ -38432,8 +39559,8 @@ var init_esm6 = __esm({
38432
39559
  if (status === "loading") {
38433
39560
  helpTip = theme.style.help("Received");
38434
39561
  } else if (status === "idle") {
38435
- const enterKey = theme.style.key("enter");
38436
- helpTip = theme.style.help(`Press ${enterKey} to launch your preferred editor.`);
39562
+ const enterKey2 = theme.style.key("enter");
39563
+ helpTip = theme.style.help(`Press ${enterKey2} to launch your preferred editor.`);
38437
39564
  }
38438
39565
  let error = "";
38439
39566
  if (errorMsg) {
@@ -39463,15 +40590,15 @@ function signupErrorCodeFromResponseText(text2) {
39463
40590
  function renderEmailCodeStart(value) {
39464
40591
  const body = objectRecord(value, "signup email-code start response");
39465
40592
  return {
39466
- pendingId: stringValue4(body, "pending_id"),
39467
- email: stringValue4(body, "email")
40593
+ pendingId: stringValue5(body, "pending_id"),
40594
+ email: stringValue5(body, "email")
39468
40595
  };
39469
40596
  }
39470
40597
  function renderEmailCodeVerify(value) {
39471
40598
  const body = objectRecord(value, "signup email-code verify response");
39472
40599
  return {
39473
- accessToken: stringValue4(body, "access_token"),
39474
- refreshToken: stringValue4(body, "refresh_token"),
40600
+ accessToken: stringValue5(body, "access_token"),
40601
+ refreshToken: stringValue5(body, "refresh_token"),
39475
40602
  expiresInSeconds: positiveIntegerValue(body, "expires_in"),
39476
40603
  user: renderUserRef(requiredValue(body, "user")),
39477
40604
  isNewUser: booleanValue(body, "is_new_user"),
@@ -39511,7 +40638,7 @@ function renderMissionControlComplete(value) {
39511
40638
  localRunnerToken: renderLocalRunnerToken(
39512
40639
  requiredValue(body, "local_runner_token")
39513
40640
  ),
39514
- launchUrl: stringValue4(body, "launch_url"),
40641
+ launchUrl: stringValue5(body, "launch_url"),
39515
40642
  ...missionControlUrl === void 0 ? {} : { missionControlUrl },
39516
40643
  config: {
39517
40644
  allowedCwds: arrayValue2(config, "allowed_cwds").map(
@@ -39531,21 +40658,21 @@ function renderLocalRunnerToken(value) {
39531
40658
  const body = objectRecord(value, "signup local runner token");
39532
40659
  const expiresInSeconds = optionalPositiveIntegerValue(body, "expires_in");
39533
40660
  return {
39534
- accessToken: stringValue4(body, "access_token"),
40661
+ accessToken: stringValue5(body, "access_token"),
39535
40662
  ...expiresInSeconds === void 0 ? {} : { expiresInSeconds },
39536
- workspaceSlug: stringValue4(body, "workspace"),
39537
- channelSlug: stringValue4(body, "channel")
40663
+ workspaceSlug: stringValue5(body, "workspace"),
40664
+ channelSlug: stringValue5(body, "channel")
39538
40665
  };
39539
40666
  }
39540
40667
  function renderTaskStartResult(value) {
39541
40668
  const body = objectRecord(value, "signup task start");
39542
- const status = stringValue4(body, "status");
40669
+ const status = stringValue5(body, "status");
39543
40670
  if (status !== "queued" && status !== "started" && status !== "failed") {
39544
40671
  throw new Error("signup task start status was incomplete");
39545
40672
  }
39546
40673
  return {
39547
- threadId: stringValue4(body, "thread_id"),
39548
- title: stringValue4(body, "title"),
40674
+ threadId: stringValue5(body, "thread_id"),
40675
+ title: stringValue5(body, "title"),
39549
40676
  status,
39550
40677
  ...optionalStringValue(body, "runner_id") === void 0 ? {} : { runnerId: optionalStringValue(body, "runner_id") },
39551
40678
  ...optionalStringValue(body, "error") === void 0 ? {} : { error: optionalStringValue(body, "error") }
@@ -39555,7 +40682,7 @@ function renderUserRef(value) {
39555
40682
  const body = objectRecord(value, "signup user");
39556
40683
  return {
39557
40684
  id: positiveIntegerValue(body, "id"),
39558
- username: stringValue4(body, "username"),
40685
+ username: stringValue5(body, "username"),
39559
40686
  ...optionalStringValue(body, "display_name") === void 0 ? {} : { displayName: optionalStringValue(body, "display_name") },
39560
40687
  ...optionalStringValue(body, "primary_email") === void 0 ? {} : { primaryEmail: optionalStringValue(body, "primary_email") }
39561
40688
  };
@@ -39564,23 +40691,23 @@ function renderWorkspaceRef(value) {
39564
40691
  const body = objectRecord(value, "signup workspace");
39565
40692
  return {
39566
40693
  id: positiveIntegerValue(body, "id"),
39567
- slug: stringValue4(body, "slug"),
39568
- name: stringValue4(body, "name")
40694
+ slug: stringValue5(body, "slug"),
40695
+ name: stringValue5(body, "name")
39569
40696
  };
39570
40697
  }
39571
40698
  function renderChannelRef(value) {
39572
40699
  const body = objectRecord(value, "signup channel");
39573
40700
  return {
39574
40701
  id: positiveIntegerValue(body, "id"),
39575
- slug: stringValue4(body, "slug"),
39576
- name: stringValue4(body, "name")
40702
+ slug: stringValue5(body, "slug"),
40703
+ name: stringValue5(body, "name")
39577
40704
  };
39578
40705
  }
39579
40706
  function renderThreadRef(value) {
39580
40707
  const body = objectRecord(value, "signup thread");
39581
40708
  return {
39582
- threadId: stringValue4(body, "thread_id"),
39583
- title: stringValue4(body, "title"),
40709
+ threadId: stringValue5(body, "thread_id"),
40710
+ title: stringValue5(body, "title"),
39584
40711
  rootSeq: positiveIntegerValue(body, "root_seq"),
39585
40712
  threadSeq: positiveIntegerValue(body, "thread_seq")
39586
40713
  };
@@ -39598,7 +40725,7 @@ function requiredValue(record, key) {
39598
40725
  }
39599
40726
  return value;
39600
40727
  }
39601
- function stringValue4(record, key) {
40728
+ function stringValue5(record, key) {
39602
40729
  return stringFromUnknown(requiredValue(record, key), `signup ${key}`);
39603
40730
  }
39604
40731
  function optionalStringValue(record, key) {
@@ -55960,16 +57087,16 @@ async function runMcpServer(args) {
55960
57087
  const kandanUrl = required(values, "api-url");
55961
57088
  const auth = await resolveMcpAuth({
55962
57089
  kandanUrl,
55963
- explicitToken: stringValue3(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
55964
- authFilePath: stringValue3(values, "auth-file"),
55965
- delegationAuthFilePath: stringValue3(values, "delegation-auth-file"),
55966
- workspaceSlug: stringValue3(values, "workspace"),
55967
- channelSlug: stringValue3(values, "channel")
55968
- });
55969
- const ownerUsername = stringValue3(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME;
55970
- const operatingMode = mcpOperatingMode(stringValue3(values, "mode"));
55971
- const cwd = stringValue3(values, "cwd") ?? process.cwd();
55972
- const defaultThreadId = stringValue3(values, "thread-id") ?? process.env.LINZUMI_THREAD_RUNNER_KANDAN_THREAD_ID;
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;
55973
57100
  const client = createLinzumiMcpApiClient({
55974
57101
  kandanUrl,
55975
57102
  accessToken: auth.accessToken,
@@ -56214,22 +57341,22 @@ function registerEmptyMcpResources(server) {
56214
57341
  async function runMcpConfig(args) {
56215
57342
  const values = strictFlagValues(args);
56216
57343
  const kandanUrl = required(values, "api-url");
56217
- const format = stringValue3(values, "format") ?? "codex";
56218
- const operatingMode = mcpOperatingMode(stringValue3(values, "mode"));
57344
+ const format = stringValue4(values, "format") ?? "codex";
57345
+ const operatingMode = mcpOperatingMode(stringValue4(values, "mode"));
56219
57346
  const token = values.get("include-token") === true ? (await resolveMcpAuth({
56220
57347
  kandanUrl,
56221
- explicitToken: stringValue3(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
56222
- authFilePath: stringValue3(values, "auth-file"),
56223
- delegationAuthFilePath: stringValue3(values, "delegation-auth-file"),
56224
- workspaceSlug: stringValue3(values, "workspace"),
56225
- channelSlug: stringValue3(values, "channel")
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")
56226
57353
  })).accessToken : void 0;
56227
57354
  const config = linzumiMcpServerConfig({
56228
- command: stringValue3(values, "command"),
57355
+ command: stringValue4(values, "command"),
56229
57356
  kandanUrl,
56230
57357
  accessToken: token,
56231
- delegationAuthFilePath: stringValue3(values, "delegation-auth-file"),
56232
- ownerUsername: stringValue3(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME,
57358
+ delegationAuthFilePath: stringValue4(values, "delegation-auth-file"),
57359
+ ownerUsername: stringValue4(values, "owner-username") ?? process.env.LINZUMI_MCP_OWNER_USERNAME,
56233
57360
  operatingMode
56234
57361
  });
56235
57362
  switch (format) {
@@ -56248,19 +57375,19 @@ async function runMcpDoctor(args) {
56248
57375
  const kandanUrl = required(values, "api-url");
56249
57376
  const auth = await resolveMcpAuth({
56250
57377
  kandanUrl,
56251
- explicitToken: stringValue3(values, "token") ?? process.env.LINZUMI_MCP_ACCESS_TOKEN,
56252
- authFilePath: stringValue3(values, "auth-file"),
56253
- delegationAuthFilePath: stringValue3(values, "delegation-auth-file"),
56254
- workspaceSlug: stringValue3(values, "workspace"),
56255
- channelSlug: stringValue3(values, "channel")
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")
56256
57383
  });
56257
57384
  switch (auth.mode) {
56258
57385
  case "local-runner": {
56259
57386
  const ok = await validateLocalRunnerToken({
56260
57387
  kandanUrl,
56261
57388
  accessToken: auth.accessToken,
56262
- workspaceSlug: stringValue3(values, "workspace"),
56263
- channelSlug: stringValue3(values, "channel")
57389
+ workspaceSlug: stringValue4(values, "workspace"),
57390
+ channelSlug: stringValue4(values, "channel")
56264
57391
  });
56265
57392
  if (!ok) {
56266
57393
  throw new Error("Linzumi MCP auth validation failed");
@@ -56272,7 +57399,7 @@ async function runMcpDoctor(args) {
56272
57399
  kandanUrl,
56273
57400
  accessToken: auth.accessToken,
56274
57401
  authMode: auth.mode,
56275
- operatingMode: mcpOperatingMode(stringValue3(values, "mode"))
57402
+ operatingMode: mcpOperatingMode(stringValue4(values, "mode"))
56276
57403
  });
56277
57404
  await client.validateAuth();
56278
57405
  break;
@@ -56343,7 +57470,7 @@ function strictFlagValues(args) {
56343
57470
  }
56344
57471
  return values;
56345
57472
  }
56346
- function stringValue3(values, key) {
57473
+ function stringValue4(values, key) {
56347
57474
  const value = values.get(key);
56348
57475
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
56349
57476
  }
@@ -56359,7 +57486,7 @@ function mcpOperatingMode(value) {
56359
57486
  }
56360
57487
  }
56361
57488
  function required(values, key) {
56362
- const value = stringValue3(values, key);
57489
+ const value = stringValue4(values, key);
56363
57490
  if (value === void 0) {
56364
57491
  throw new Error(`--${key} is required`);
56365
57492
  }
@@ -56578,11 +57705,11 @@ function runHelloCommand(args) {
56578
57705
  process.stdout.write(helloHelpText());
56579
57706
  return;
56580
57707
  }
56581
- const rootPath = stringValue5(values, "dir");
56582
- const parentDir = stringValue5(values, "parent-dir");
56583
- const name = stringValue5(values, "name");
57708
+ const rootPath = stringValue6(values, "dir");
57709
+ const parentDir = stringValue6(values, "parent-dir");
57710
+ const name = stringValue6(values, "name");
56584
57711
  const port = tcpPortValue(values, "port");
56585
- const host = stringValue5(values, "host");
57712
+ const host = stringValue6(values, "host");
56586
57713
  const project = createHelloLinzumiProject({
56587
57714
  ...rootPath === void 0 ? {} : { rootPath },
56588
57715
  ...parentDir === void 0 ? {} : { parentDir: resolveUserPath(parentDir) },
@@ -56722,8 +57849,8 @@ async function runCommanderDaemonCommand(args) {
56722
57849
  runnerId,
56723
57850
  cwd,
56724
57851
  args: stripDaemonSupervisorFlags(flagArgs),
56725
- logFile: stringValue5(values, "log-file"),
56726
- statusDir: stringValue5(values, "status-dir")
57852
+ logFile: stringValue6(values, "log-file"),
57853
+ statusDir: stringValue6(values, "status-dir")
56727
57854
  });
56728
57855
  process.stdout.write("commander_status: daemon_started\n");
56729
57856
  process.stdout.write(`runner_id: ${record.runnerId}
@@ -56744,7 +57871,7 @@ async function runCommanderDaemonCommand(args) {
56744
57871
  const runnerId = ensureLocalRunnerIdForLinzumiUrl(kandanUrl);
56745
57872
  const status = commanderDaemonStatus(
56746
57873
  runnerId,
56747
- stringValue5(values, "status-dir")
57874
+ stringValue6(values, "status-dir")
56748
57875
  );
56749
57876
  process.stdout.write(`${JSON.stringify(status)}
56750
57877
  `);
@@ -56758,7 +57885,7 @@ async function runCommanderDaemonCommand(args) {
56758
57885
  const result = await waitForCommanderDaemon({
56759
57886
  runnerId,
56760
57887
  timeoutMs,
56761
- statusDir: stringValue5(values, "status-dir")
57888
+ statusDir: stringValue6(values, "status-dir")
56762
57889
  });
56763
57890
  if (result.ok) {
56764
57891
  process.stdout.write("commander_status: connected\n");
@@ -56776,7 +57903,7 @@ async function runCommanderDaemonCommand(args) {
56776
57903
  const runnerId = ensureLocalRunnerIdForLinzumiUrl(kandanUrl);
56777
57904
  const status = stopCommanderDaemon(
56778
57905
  runnerId,
56779
- stringValue5(values, "status-dir")
57906
+ stringValue6(values, "status-dir")
56780
57907
  );
56781
57908
  process.stdout.write(`${JSON.stringify(status)}
56782
57909
  `);
@@ -56805,13 +57932,13 @@ async function runAuthCommand(args) {
56805
57932
  kandanUrl,
56806
57933
  workspaceSlug: target?.workspaceSlug,
56807
57934
  channelSlug: target?.channelSlug,
56808
- callbackHost: stringValue5(values, "oauth-callback-host")
57935
+ callbackHost: stringValue6(values, "oauth-callback-host")
56809
57936
  });
56810
57937
  const cached = writeCachedLocalRunnerToken({
56811
57938
  kandanUrl,
56812
57939
  accessToken: token.accessToken,
56813
57940
  expiresInSeconds: token.expiresInSeconds,
56814
- authFilePath: stringValue5(values, "auth-file")
57941
+ authFilePath: stringValue6(values, "auth-file")
56815
57942
  });
56816
57943
  process.stdout.write(
56817
57944
  `Saved Linzumi local runner auth for ${cached.kandanBaseUrl}
@@ -56838,11 +57965,11 @@ async function parseStartRunnerArgs(args, deps = {
56838
57965
  const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
56839
57966
  const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
56840
57967
  const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
56841
- parseAllowedCwdList(stringValue5(values, "allowed-cwd"))
57968
+ parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
56842
57969
  ) : [];
56843
57970
  const allowedCwds = Array.from(/* @__PURE__ */ new Set([cwd, ...explicitAllowedCwds]));
56844
- const requestedCodexBin = stringValue5(values, "codex-bin") ?? "codex";
56845
- const customCodeServerBin = stringValue5(values, "code-server-bin");
57971
+ const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
57972
+ const customCodeServerBin = stringValue6(values, "code-server-bin");
56846
57973
  const initialDependencyStatus = await deps.buildDependencyStatus({
56847
57974
  cwd,
56848
57975
  codexBin: requestedCodexBin,
@@ -56850,9 +57977,9 @@ async function parseStartRunnerArgs(args, deps = {
56850
57977
  });
56851
57978
  assertStartDependencies(initialDependencyStatus);
56852
57979
  const codexBin = initialDependencyStatus.codex.command;
56853
- const explicitToken = stringValue5(values, "token");
56854
- const authFilePath = stringValue5(values, "auth-file");
56855
- const callbackHost = stringValue5(values, "oauth-callback-host");
57980
+ const explicitToken = stringValue6(values, "token");
57981
+ const authFilePath = stringValue6(values, "auth-file");
57982
+ const callbackHost = stringValue6(values, "oauth-callback-host");
56856
57983
  const reportRejectedCachedToken = () => {
56857
57984
  process.stderr.write(
56858
57985
  "Cached Linzumi local runner auth was rejected; starting OAuth.\n"
@@ -56905,13 +58032,13 @@ async function parseStartRunnerArgs(args, deps = {
56905
58032
  workspaceSlug: target.workspaceSlug,
56906
58033
  cwd,
56907
58034
  codexBin,
56908
- codexUrl: stringValue5(values, "codex-url"),
58035
+ codexUrl: stringValue6(values, "codex-url"),
56909
58036
  launchTui: values.get("launch-tui") === true,
56910
58037
  fast: values.get("fast") === true,
56911
- logFile: stringValue5(values, "log-file"),
58038
+ logFile: stringValue6(values, "log-file"),
56912
58039
  allowedCwds,
56913
58040
  allowedForwardPorts: parseAllowedPortList(
56914
- stringValue5(values, "forward-port")
58041
+ stringValue6(values, "forward-port")
56915
58042
  ),
56916
58043
  codeServerBin: editorRuntime.codeServerBin,
56917
58044
  editorRuntime: editorRuntime.runtime,
@@ -56922,12 +58049,12 @@ async function parseStartRunnerArgs(args, deps = {
56922
58049
  channelSession: {
56923
58050
  workspaceSlug: target.workspaceSlug,
56924
58051
  channelSlug: target.channelSlug,
56925
- kandanThreadId: stringValue5(values, "linzumi-thread-id"),
56926
- listenUser: stringValue5(values, "listen-user") ?? defaultListenUserFromToken(targetToken),
56927
- model: stringValue5(values, "model"),
56928
- reasoningEffort: stringValue5(values, "reasoning-effort"),
56929
- sandbox: stringValue5(values, "sandbox"),
56930
- approvalPolicy: stringValue5(values, "approval-policy"),
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"),
56931
58058
  allowPortForwardingByDefault: true,
56932
58059
  streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
56933
58060
  }
@@ -56952,32 +58079,32 @@ async function parseAgentRunnerArgs(args, deps = {
56952
58079
  "linzumi commander accepts either <folder> or --cwd, not both"
56953
58080
  );
56954
58081
  }
56955
- const tokenFilePath = stringValue5(values, "agent-token-file") ?? defaultAgentTokenFilePath();
58082
+ const tokenFilePath = stringValue6(values, "agent-token-file") ?? defaultAgentTokenFilePath();
56956
58083
  const tokenFile = readStoredAgentTokenFile(tokenFilePath, deps.readTextFile);
56957
58084
  const channelSlug = tokenFile.channelId;
56958
58085
  rejectWorkspaceCommanderThreadFlags(values, channelSlug);
56959
58086
  const channelSession = channelSlug === void 0 ? void 0 : {
56960
58087
  workspaceSlug: tokenFile.workspaceId,
56961
58088
  channelSlug,
56962
- kandanThreadId: stringValue5(values, "linzumi-thread-id"),
56963
- listenUser: stringValue5(values, "listen-user") ?? requiredStoredOwnerUsername(tokenFile.ownerUsername),
56964
- model: stringValue5(values, "model"),
56965
- reasoningEffort: stringValue5(values, "reasoning-effort"),
56966
- sandbox: stringValue5(values, "sandbox"),
56967
- approvalPolicy: stringValue5(values, "approval-policy"),
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"),
56968
58095
  allowPortForwardingByDefault: true,
56969
58096
  streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
56970
58097
  };
56971
58098
  const kandanUrl = kandanUrlValue(values) ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
56972
- const requestedCwdValue = cwdArg ?? stringValue5(values, "cwd");
58099
+ const requestedCwdValue = cwdArg ?? stringValue6(values, "cwd");
56973
58100
  const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
56974
58101
  const configuredAllowedCwds2 = requestedCwdValue === void 0 && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
56975
58102
  const allowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
56976
- parseAllowedCwdList(stringValue5(values, "allowed-cwd"))
58103
+ parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
56977
58104
  ) : requestedCwdValue === void 0 ? configuredAllowedCwds2.allowedCwds.length > 0 ? [...configuredAllowedCwds2.allowedCwds] : assertConfiguredAllowedCwds([requestedCwd]) : assertConfiguredAllowedCwds([requestedCwd]);
56978
58105
  const cwd = allowedCwds[0] ?? requestedCwd;
56979
- const requestedCodexBin = stringValue5(values, "codex-bin") ?? "codex";
56980
- const customCodeServerBin = stringValue5(values, "code-server-bin");
58106
+ const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
58107
+ const customCodeServerBin = stringValue6(values, "code-server-bin");
56981
58108
  const initialDependencyStatus = await deps.buildDependencyStatus({
56982
58109
  cwd,
56983
58110
  codexBin: requestedCodexBin,
@@ -57008,14 +58135,14 @@ async function parseAgentRunnerArgs(args, deps = {
57008
58135
  workspaceSlug: tokenFile.workspaceId,
57009
58136
  cwd,
57010
58137
  codexBin,
57011
- codexUrl: stringValue5(values, "codex-url"),
58138
+ codexUrl: stringValue6(values, "codex-url"),
57012
58139
  launchTui: values.get("launch-tui") === true,
57013
58140
  fast: values.get("fast") === true,
57014
- logFile: stringValue5(values, "log-file"),
58141
+ logFile: stringValue6(values, "log-file"),
57015
58142
  allowedCwds,
57016
58143
  missingAllowedCwds: configuredAllowedCwds2.missingAllowedCwds,
57017
58144
  allowedForwardPorts: parseAllowedPortList(
57018
- stringValue5(values, "forward-port")
58145
+ stringValue6(values, "forward-port")
57019
58146
  ),
57020
58147
  codeServerBin: editorRuntime.codeServerBin,
57021
58148
  editorRuntime: editorRuntime.runtime,
@@ -57128,16 +58255,16 @@ async function parseRunnerArgs(args, deps = {
57128
58255
  process.exit(0);
57129
58256
  }
57130
58257
  rejectConnectChannelFlags(values);
57131
- const workspaceSlug = stringValue5(values, "workspace");
58258
+ const workspaceSlug = stringValue6(values, "workspace");
57132
58259
  const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
57133
- const cwd = stringValue5(values, "cwd") ?? process.cwd();
58260
+ const cwd = stringValue6(values, "cwd") ?? process.cwd();
57134
58261
  const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
57135
58262
  const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
57136
58263
  const configuredAllowedCwds2 = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
57137
- parseAllowedCwdList(stringValue5(values, "allowed-cwd"))
58264
+ parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
57138
58265
  ) : [...localConfiguredAllowedCwds.allowedCwds];
57139
- const requestedCodexBin = stringValue5(values, "codex-bin") ?? "codex";
57140
- const customCodeServerBin = stringValue5(values, "code-server-bin");
58266
+ const requestedCodexBin = stringValue6(values, "codex-bin") ?? "codex";
58267
+ const customCodeServerBin = stringValue6(values, "code-server-bin");
57141
58268
  const initialDependencyStatus = await deps.buildDependencyStatus({
57142
58269
  cwd,
57143
58270
  codexBin: requestedCodexBin,
@@ -57145,13 +58272,13 @@ async function parseRunnerArgs(args, deps = {
57145
58272
  });
57146
58273
  assertStartDependencies(initialDependencyStatus);
57147
58274
  const codexBin = initialDependencyStatus.codex.command;
57148
- const explicitToken = stringValue5(values, "token");
58275
+ const explicitToken = stringValue6(values, "token");
57149
58276
  const token = await deps.resolveToken({
57150
58277
  kandanUrl,
57151
58278
  explicitToken,
57152
58279
  workspaceSlug,
57153
- authFilePath: stringValue5(values, "auth-file"),
57154
- callbackHost: stringValue5(values, "oauth-callback-host"),
58280
+ authFilePath: stringValue6(values, "auth-file"),
58281
+ callbackHost: stringValue6(values, "oauth-callback-host"),
57155
58282
  reportRejectedCachedToken: () => {
57156
58283
  process.stderr.write(
57157
58284
  "Cached Linzumi local runner auth was rejected; starting OAuth.\n"
@@ -57180,16 +58307,16 @@ async function parseRunnerArgs(args, deps = {
57180
58307
  ),
57181
58308
  cwd,
57182
58309
  codexBin,
57183
- codexUrl: stringValue5(values, "codex-url"),
58310
+ codexUrl: stringValue6(values, "codex-url"),
57184
58311
  launchTui: values.get("launch-tui") === true,
57185
58312
  fast: values.get("fast") === true,
57186
- logFile: stringValue5(values, "log-file"),
58313
+ logFile: stringValue6(values, "log-file"),
57187
58314
  allowedCwds: Array.from(
57188
58315
  /* @__PURE__ */ new Set([...cwdAllowedCwds, ...configuredAllowedCwds2])
57189
58316
  ),
57190
58317
  missingAllowedCwds: localConfiguredAllowedCwds.missingAllowedCwds,
57191
58318
  allowedForwardPorts: parseAllowedPortList(
57192
- stringValue5(values, "forward-port")
58319
+ stringValue6(values, "forward-port")
57193
58320
  ),
57194
58321
  codeServerBin: editorRuntime.codeServerBin,
57195
58322
  editorRuntime: editorRuntime.runtime,
@@ -57203,16 +58330,16 @@ async function parseRunnerArgs(args, deps = {
57203
58330
  }
57204
58331
  function runnerRuntimeDefaultsFromValues(values) {
57205
58332
  return {
57206
- model: stringValue5(values, "model"),
57207
- reasoningEffort: stringValue5(values, "reasoning-effort"),
57208
- approvalPolicy: stringValue5(values, "approval-policy"),
57209
- sandbox: stringValue5(values, "sandbox"),
58333
+ model: stringValue6(values, "model"),
58334
+ reasoningEffort: stringValue6(values, "reasoning-effort"),
58335
+ approvalPolicy: stringValue6(values, "approval-policy"),
58336
+ sandbox: stringValue6(values, "sandbox"),
57210
58337
  allowPortForwardingByDefault: true
57211
58338
  };
57212
58339
  }
57213
58340
  function kandanUrlValue(values) {
57214
- const apiUrl = stringValue5(values, "api-url");
57215
- const linzumiUrl = stringValue5(values, "linzumi-url");
58341
+ const apiUrl = stringValue6(values, "api-url");
58342
+ const linzumiUrl = stringValue6(values, "linzumi-url");
57216
58343
  if (apiUrl !== void 0 && linzumiUrl !== void 0 && apiUrl !== linzumiUrl) {
57217
58344
  throw new Error("use only one of --api-url or --linzumi-url");
57218
58345
  }
@@ -57351,8 +58478,8 @@ function rejectConnectChannelFlags(values) {
57351
58478
  );
57352
58479
  }
57353
58480
  function parseOptionalChannelTarget(values) {
57354
- const channel = stringValue5(values, "channel");
57355
- const workspace = stringValue5(values, "workspace");
58481
+ const channel = stringValue6(values, "channel");
58482
+ const workspace = stringValue6(values, "workspace");
57356
58483
  if (channel === void 0) {
57357
58484
  if (workspace === void 0) {
57358
58485
  return void 0;
@@ -57386,9 +58513,9 @@ function withLocalMachineId(options) {
57386
58513
  function parseThreadCodexWorkerArgs(args) {
57387
58514
  const values = strictFlagValues2(args);
57388
58515
  const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
57389
- const cwd = stringValue5(values, "cwd") ?? process.cwd();
58516
+ const cwd = stringValue6(values, "cwd") ?? process.cwd();
57390
58517
  const configuredAllowedCwds2 = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(
57391
- parseAllowedCwdList(stringValue5(values, "allowed-cwd"))
58518
+ parseAllowedCwdList(stringValue6(values, "allowed-cwd"))
57392
58519
  ) : assertConfiguredAllowedCwds([cwd]);
57393
58520
  const kandanThreadId = requiredThreadRunnerKandanThreadId();
57394
58521
  const token = requiredThreadRunnerToken();
@@ -57398,17 +58525,17 @@ function parseThreadCodexWorkerArgs(args) {
57398
58525
  runnerId: `thread-codex-worker:${kandanThreadId}`,
57399
58526
  machineId: void 0,
57400
58527
  runnerLockConfigPath: void 0,
57401
- workspaceSlug: stringValue5(values, "workspace"),
58528
+ workspaceSlug: stringValue6(values, "workspace"),
57402
58529
  cwd,
57403
- codexBin: stringValue5(values, "codex-bin") ?? "codex",
58530
+ codexBin: stringValue6(values, "codex-bin") ?? "codex",
57404
58531
  codexUrl: void 0,
57405
58532
  launchTui: false,
57406
58533
  fast: values.get("fast") === true ? true : void 0,
57407
- logFile: stringValue5(values, "log-file"),
58534
+ logFile: stringValue6(values, "log-file"),
57408
58535
  allowedCwds: configuredAllowedCwds2.allowedCwds,
57409
58536
  missingAllowedCwds: configuredAllowedCwds2.missingAllowedCwds,
57410
58537
  allowedForwardPorts: parseAllowedPortList(
57411
- stringValue5(values, "forward-port")
58538
+ stringValue6(values, "forward-port")
57412
58539
  ),
57413
58540
  codeServerBin: void 0,
57414
58541
  editorRuntime: void 0,
@@ -57438,13 +58565,13 @@ function requiredThreadRunnerToken() {
57438
58565
  return token;
57439
58566
  }
57440
58567
  function required2(values, key) {
57441
- const value = stringValue5(values, key);
58568
+ const value = stringValue6(values, key);
57442
58569
  if (value === void 0) {
57443
58570
  throw new Error(`missing --${key}`);
57444
58571
  }
57445
58572
  return value;
57446
58573
  }
57447
- function stringValue5(values, key) {
58574
+ function stringValue6(values, key) {
57448
58575
  const value = values.get(key);
57449
58576
  if (typeof value === "string" && value.trim() !== "") {
57450
58577
  return value;
@@ -57452,7 +58579,7 @@ function stringValue5(values, key) {
57452
58579
  return void 0;
57453
58580
  }
57454
58581
  function positiveIntegerValue2(values, key) {
57455
- const value = stringValue5(values, key);
58582
+ const value = stringValue6(values, key);
57456
58583
  if (value === void 0) {
57457
58584
  return void 0;
57458
58585
  }
@@ -57463,7 +58590,7 @@ function positiveIntegerValue2(values, key) {
57463
58590
  throw new Error(`--${key} must be a positive integer`);
57464
58591
  }
57465
58592
  function tcpPortValue(values, key) {
57466
- const value = stringValue5(values, key);
58593
+ const value = stringValue6(values, key);
57467
58594
  if (value === void 0) {
57468
58595
  return void 0;
57469
58596
  }