@linzumi/cli 0.0.71-beta → 0.0.72-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +155 -50
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -58,7 +58,7 @@ Install the CLI or run it with `npx`:
58
58
  ```bash
59
59
  npm install -g @linzumi/cli@latest
60
60
  npx -y @linzumi/cli@latest signup
61
- npx -y @linzumi/cli@0.0.71-beta --version
61
+ npx -y @linzumi/cli@0.0.72-beta --version
62
62
  linzumi --version
63
63
  ```
64
64
 
package/dist/index.js CHANGED
@@ -4069,7 +4069,10 @@ async function handleChannelSessionControl(args, state, payloadContext, control)
4069
4069
  interruptedActiveSeq,
4070
4070
  {
4071
4071
  status: "processed"
4072
- }
4072
+ },
4073
+ void 0,
4074
+ void 0,
4075
+ state.codexThreadId
4073
4076
  );
4074
4077
  break;
4075
4078
  case "starting":
@@ -4093,10 +4096,18 @@ async function handleChannelSessionControl(args, state, payloadContext, control)
4093
4096
  });
4094
4097
  if (interrupted.ok) {
4095
4098
  for (const seq of interrupted.selectedSeqs) {
4096
- await publishMessageState(args, state.kandanThreadId, seq, {
4097
- status: "processing",
4098
- reason: "interrupt requested"
4099
- });
4099
+ await publishMessageState(
4100
+ args,
4101
+ state.kandanThreadId,
4102
+ seq,
4103
+ {
4104
+ status: "processing",
4105
+ reason: "interrupt requested"
4106
+ },
4107
+ void 0,
4108
+ void 0,
4109
+ state.codexThreadId
4110
+ );
4100
4111
  }
4101
4112
  }
4102
4113
  await drainKandanMessageQueue(args, state, payloadContext);
@@ -4365,6 +4376,9 @@ async function resolvePendingPortForwardRequest(args, state, payloadContext, con
4365
4376
  if (request === void 0) {
4366
4377
  return void 0;
4367
4378
  }
4379
+ if (control.threadId !== void 0 && state.codexThreadId !== control.threadId) {
4380
+ return void 0;
4381
+ }
4368
4382
  if (!portForwardControlSenderAllowed(args, payloadContext, control)) {
4369
4383
  args.log("port_forward.request_resolution_ignored", {
4370
4384
  request_id: control.requestId,
@@ -4633,11 +4647,19 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
4633
4647
  allowedActorUserId: args.options.channelSession.listenUser.toLowerCase() === (payloadContext.runnerIdentity.actorUsername ?? "").toLowerCase() ? payloadContext.runnerIdentity.actorUserId : void 0
4634
4648
  }
4635
4649
  };
4636
- await publishMessageState(args, state.kandanThreadId, sourceSeq, {
4637
- status: "processing",
4638
- reason: "awaiting approval",
4639
- approval: state.activeProcessingState.approval
4640
- });
4650
+ await publishMessageState(
4651
+ args,
4652
+ state.kandanThreadId,
4653
+ sourceSeq,
4654
+ {
4655
+ status: "processing",
4656
+ reason: "awaiting approval",
4657
+ approval: state.activeProcessingState.approval
4658
+ },
4659
+ void 0,
4660
+ void 0,
4661
+ state.codexThreadId
4662
+ );
4641
4663
  await publishForwardPortRequestedEvent(args, state, request, processIdentity);
4642
4664
  args.log("port_forward.request_pending", {
4643
4665
  request_id: requestId,
@@ -4826,7 +4848,10 @@ async function publishMessageStateForPortForwardResult(args, state, request, sta
4826
4848
  {
4827
4849
  status: "processing",
4828
4850
  reason: "running terminal command"
4829
- }
4851
+ },
4852
+ void 0,
4853
+ void 0,
4854
+ state.codexThreadId
4830
4855
  );
4831
4856
  return;
4832
4857
  }
@@ -4851,15 +4876,31 @@ async function publishMessageStateForPortForwardResult(args, state, request, sta
4851
4876
  }
4852
4877
  switch (status) {
4853
4878
  case "processed":
4854
- await publishMessageState(args, state.kandanThreadId, request.sourceSeq, {
4855
- status: "processed"
4856
- });
4879
+ await publishMessageState(
4880
+ args,
4881
+ state.kandanThreadId,
4882
+ request.sourceSeq,
4883
+ {
4884
+ status: "processed"
4885
+ },
4886
+ void 0,
4887
+ void 0,
4888
+ state.codexThreadId
4889
+ );
4857
4890
  break;
4858
4891
  case "failed":
4859
- await publishMessageState(args, state.kandanThreadId, request.sourceSeq, {
4860
- status: "failed",
4861
- reason: failedReason
4862
- });
4892
+ await publishMessageState(
4893
+ args,
4894
+ state.kandanThreadId,
4895
+ request.sourceSeq,
4896
+ {
4897
+ status: "failed",
4898
+ reason: failedReason
4899
+ },
4900
+ void 0,
4901
+ void 0,
4902
+ state.codexThreadId
4903
+ );
4863
4904
  break;
4864
4905
  }
4865
4906
  }
@@ -5239,9 +5280,17 @@ async function drainKandanMessageQueue(args, state, payloadContext) {
5239
5280
  state.turn = { status: "idle" };
5240
5281
  clearActiveProcessingState(state, next.seq);
5241
5282
  if (state.kandanThreadId !== void 0) {
5242
- await publishMessageState(args, state.kandanThreadId, next.seq, {
5243
- status: "processed"
5244
- });
5283
+ await publishMessageState(
5284
+ args,
5285
+ state.kandanThreadId,
5286
+ next.seq,
5287
+ {
5288
+ status: "processed"
5289
+ },
5290
+ void 0,
5291
+ void 0,
5292
+ state.codexThreadId
5293
+ );
5245
5294
  }
5246
5295
  await drainKandanMessageQueue(args, state, payloadContext);
5247
5296
  }
@@ -7755,7 +7804,9 @@ async function stopCodexTyping(args, state) {
7755
7804
  {
7756
7805
  workspace: session.workspaceSlug,
7757
7806
  channel: session.channelSlug,
7758
- thread_id: state.kandanThreadId
7807
+ thread_id: state.kandanThreadId,
7808
+ instance_id: args.instanceId,
7809
+ codex_thread_id: state.codexThreadId ?? null
7759
7810
  },
7760
7811
  args.log
7761
7812
  );
@@ -7774,7 +7825,9 @@ function startCodexTypingHeartbeat(args, state, threadId) {
7774
7825
  {
7775
7826
  workspace: session.workspaceSlug,
7776
7827
  channel: session.channelSlug,
7777
- thread_id: threadId
7828
+ thread_id: threadId,
7829
+ instance_id: args.instanceId,
7830
+ codex_thread_id: state.codexThreadId ?? null
7778
7831
  },
7779
7832
  args.log
7780
7833
  ).then(() => refreshActiveProcessingHeartbeat(args, state)).catch((error) => {
@@ -7819,7 +7872,8 @@ async function publishQueuedMessageState(args, state, message, messageState) {
7819
7872
  message.seq,
7820
7873
  messageState,
7821
7874
  message.actorSlug,
7822
- message.actorUserId
7875
+ message.actorUserId,
7876
+ state.codexThreadId
7823
7877
  );
7824
7878
  }
7825
7879
  async function publishMessageState(args, threadId, seq, state, actorSlug, actorUserId, codexThreadId) {
@@ -7828,6 +7882,7 @@ async function publishMessageState(args, threadId, seq, state, actorSlug, actorU
7828
7882
  workspace: session.workspaceSlug,
7829
7883
  channel: session.channelSlug,
7830
7884
  thread_id: threadId,
7885
+ instance_id: args.instanceId,
7831
7886
  ...codexThreadId === void 0 ? {} : { codex_thread_id: codexThreadId },
7832
7887
  seq,
7833
7888
  status: state.status,
@@ -7881,10 +7936,18 @@ async function failActiveCodexTurn(args, state, turnId, reason, payloadContext)
7881
7936
  }
7882
7937
  const seq = activeQueuedSeqForTurn(state.turn, turnId);
7883
7938
  if (seq !== void 0 && state.kandanThreadId !== void 0) {
7884
- await publishMessageState(args, state.kandanThreadId, seq, {
7885
- status: "failed",
7886
- reason
7887
- });
7939
+ await publishMessageState(
7940
+ args,
7941
+ state.kandanThreadId,
7942
+ seq,
7943
+ {
7944
+ status: "failed",
7945
+ reason
7946
+ },
7947
+ void 0,
7948
+ void 0,
7949
+ state.codexThreadId
7950
+ );
7888
7951
  clearActiveProcessingState(state, seq);
7889
7952
  }
7890
7953
  forgetLocalTuiTurnId(state, turnId);
@@ -7907,10 +7970,18 @@ async function refreshActiveProcessingState(args, state, turnId, reason) {
7907
7970
  return;
7908
7971
  }
7909
7972
  state.activeProcessingState = { seq, reason };
7910
- await publishMessageState(args, state.kandanThreadId, seq, {
7911
- status: "processing",
7912
- reason
7913
- });
7973
+ await publishMessageState(
7974
+ args,
7975
+ state.kandanThreadId,
7976
+ seq,
7977
+ {
7978
+ status: "processing",
7979
+ reason
7980
+ },
7981
+ void 0,
7982
+ void 0,
7983
+ state.codexThreadId
7984
+ );
7914
7985
  }
7915
7986
  async function refreshActiveProcessingHeartbeat(args, state) {
7916
7987
  const activeProcessingState = state.activeProcessingState;
@@ -13351,7 +13422,7 @@ var linzumiCliVersion, linzumiCliVersionText;
13351
13422
  var init_version = __esm({
13352
13423
  "src/version.ts"() {
13353
13424
  "use strict";
13354
- linzumiCliVersion = "0.0.71-beta";
13425
+ linzumiCliVersion = "0.0.72-beta";
13355
13426
  linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
13356
13427
  }
13357
13428
  });
@@ -15536,7 +15607,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15536
15607
  if (workspaceSlug === void 0 || channelSlug === void 0 || kandanThreadId === void 0) {
15537
15608
  return void 0;
15538
15609
  }
15539
- const existingSession = dynamicChannelSessions.get(kandanThreadId);
15610
+ const existingSession = dynamicChannelSessions.get(codexThreadId);
15540
15611
  if (existingSession !== void 0) {
15541
15612
  return existingSession;
15542
15613
  }
@@ -15599,7 +15670,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
15599
15670
  },
15600
15671
  log
15601
15672
  });
15602
- dynamicChannelSessions.set(kandanThreadId, session);
15673
+ dynamicChannelSessions.set(codexThreadId, session);
15603
15674
  if (sessionCodex !== codex) {
15604
15675
  sessionCodex.onNotification((notification) => {
15605
15676
  seq.value += 1;
@@ -16170,13 +16241,35 @@ function controlThreadId(control) {
16170
16241
  async function resolveSessionControl(channelSession, dynamicChannelSessions, control) {
16171
16242
  const targetThreadId = controlThreadId(control);
16172
16243
  if (targetThreadId !== void 0) {
16173
- const targetDynamicSession = dynamicChannelSessions.get(targetThreadId);
16244
+ const directDynamicSession = dynamicChannelSessions.get(targetThreadId);
16245
+ const targetDynamicSessions = Array.from(
16246
+ /* @__PURE__ */ new Set([
16247
+ ...directDynamicSession === void 0 ? [] : [directDynamicSession],
16248
+ ...Array.from(dynamicChannelSessions.values()).filter(
16249
+ (session) => session.currentKandanThreadId() === targetThreadId
16250
+ )
16251
+ ])
16252
+ );
16174
16253
  const targetSessions = [
16175
16254
  ...channelSession?.currentKandanThreadId() === targetThreadId ? [channelSession] : [],
16176
- ...targetDynamicSession !== void 0 && targetDynamicSession !== channelSession ? [targetDynamicSession] : []
16255
+ ...targetDynamicSessions.filter((session) => session !== channelSession)
16177
16256
  ].filter(
16178
16257
  (session) => session !== void 0
16179
16258
  );
16259
+ if (control.type === "update_thread_interaction_access") {
16260
+ let firstHandled;
16261
+ let firstOk;
16262
+ for (const session of targetSessions) {
16263
+ const handled = await session.handleControl(control);
16264
+ if (handled !== void 0) {
16265
+ firstHandled ??= handled;
16266
+ if (handled.ok === true) {
16267
+ firstOk ??= handled;
16268
+ }
16269
+ }
16270
+ }
16271
+ return firstOk ?? firstHandled;
16272
+ }
16180
16273
  for (const session of targetSessions) {
16181
16274
  const handled = await session.handleControl(control);
16182
16275
  if (handled !== void 0) {
@@ -16430,7 +16523,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16430
16523
  topic,
16431
16524
  control,
16432
16525
  cwd.reason,
16433
- allowedCwds.value
16526
+ allowedCwds.value,
16527
+ { instanceId }
16434
16528
  );
16435
16529
  } catch (error) {
16436
16530
  log("kandan.start_instance_cwd_failed_state_push_failed", {
@@ -16454,7 +16548,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16454
16548
  topic,
16455
16549
  control,
16456
16550
  "failed",
16457
- startInstanceUnavailableReason(agentProvider)
16551
+ startInstanceUnavailableReason(agentProvider),
16552
+ { instanceId }
16458
16553
  );
16459
16554
  } catch (error) {
16460
16555
  log("kandan.start_instance_unavailable_state_push_failed", {
@@ -16472,7 +16567,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16472
16567
  const processingStatePayload = startInstanceMessageStatePayload(
16473
16568
  control,
16474
16569
  "processing",
16475
- `starting ${startInstanceAgentLabel(agentProvider)} session`
16570
+ `starting ${startInstanceAgentLabel(agentProvider)} session`,
16571
+ { instanceId }
16476
16572
  );
16477
16573
  if (processingStatePayload !== void 0) {
16478
16574
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16542,7 +16638,7 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16542
16638
  control,
16543
16639
  "failed",
16544
16640
  failureReason,
16545
- { codexThreadId: startedCodexThreadId }
16641
+ { codexThreadId: startedCodexThreadId, instanceId }
16546
16642
  );
16547
16643
  } catch (_publishError) {
16548
16644
  }
@@ -16560,7 +16656,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16560
16656
  topic,
16561
16657
  control,
16562
16658
  cwd.reason,
16563
- allowedCwds.value
16659
+ allowedCwds.value,
16660
+ { instanceId }
16564
16661
  );
16565
16662
  } catch (error) {
16566
16663
  log("kandan.reconnect_thread_cwd_failed_state_push_failed", {
@@ -16596,7 +16693,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16596
16693
  topic,
16597
16694
  control,
16598
16695
  "failed",
16599
- startInstanceUnavailableReason(agentProvider)
16696
+ startInstanceUnavailableReason(agentProvider),
16697
+ { instanceId }
16600
16698
  );
16601
16699
  } catch (error) {
16602
16700
  log("kandan.reconnect_thread_unavailable_state_push_failed", {
@@ -16635,7 +16733,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16635
16733
  const processingStatePayload = startInstanceMessageStatePayload(
16636
16734
  control,
16637
16735
  "processing",
16638
- "queued Claude Code input"
16736
+ "queued Claude Code input",
16737
+ { instanceId, codexThreadId }
16639
16738
  );
16640
16739
  if (processingStatePayload !== void 0) {
16641
16740
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16670,7 +16769,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16670
16769
  topic,
16671
16770
  control,
16672
16771
  "failed",
16673
- reason
16772
+ reason,
16773
+ { instanceId, codexThreadId }
16674
16774
  );
16675
16775
  } catch (error) {
16676
16776
  log("kandan.reconnect_thread_queue_failed_state_push_failed", {
@@ -16700,7 +16800,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16700
16800
  topic,
16701
16801
  control,
16702
16802
  "failed",
16703
- reason
16803
+ reason,
16804
+ { instanceId, codexThreadId }
16704
16805
  );
16705
16806
  } catch (pushError) {
16706
16807
  log("kandan.reconnect_thread_queue_closed_state_push_failed", {
@@ -16739,7 +16840,8 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16739
16840
  const processingStatePayload = startInstanceMessageStatePayload(
16740
16841
  control,
16741
16842
  "processing",
16742
- "resuming Claude Code session"
16843
+ "resuming Claude Code session",
16844
+ { instanceId, codexThreadId }
16743
16845
  );
16744
16846
  if (processingStatePayload !== void 0) {
16745
16847
  void kandan.push(topic, "message_state", processingStatePayload).catch((error) => {
@@ -16785,7 +16887,7 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
16785
16887
  control,
16786
16888
  "failed",
16787
16889
  failureReason,
16788
- { codexThreadId }
16890
+ { codexThreadId, instanceId }
16789
16891
  );
16790
16892
  } catch (_publishError) {
16791
16893
  }
@@ -17536,7 +17638,8 @@ async function startClaudeCodeProviderInstance(args) {
17536
17638
  args.topic,
17537
17639
  args.control,
17538
17640
  "failed",
17539
- reason
17641
+ reason,
17642
+ { instanceId: args.instanceId }
17540
17643
  );
17541
17644
  } catch (error) {
17542
17645
  args.log(
@@ -18361,7 +18464,7 @@ async function publishStartInstanceMessageState(kandan, topic, control, status,
18361
18464
  }
18362
18465
  await kandan.push(topic, "message_state", payload);
18363
18466
  }
18364
- async function publishStartInstanceCwdFailureMessageState(kandan, topic, control, reason, allowedCwds) {
18467
+ async function publishStartInstanceCwdFailureMessageState(kandan, topic, control, reason, allowedCwds, diagnostics = {}) {
18365
18468
  const rootSeq = integerValue(control.rootSeq);
18366
18469
  const sourceSeq = integerValue(control.sourceSeq) ?? rootSeq;
18367
18470
  if (sourceSeq === void 0) {
@@ -18377,6 +18480,7 @@ async function publishStartInstanceCwdFailureMessageState(kandan, topic, control
18377
18480
  workspace,
18378
18481
  channel,
18379
18482
  thread_id: threadId,
18483
+ ...diagnostics.instanceId === void 0 ? {} : { instance_id: diagnostics.instanceId },
18380
18484
  seq: sourceSeq,
18381
18485
  status: "failed",
18382
18486
  reason,
@@ -18414,6 +18518,7 @@ function startInstanceMessageStatePayload(control, status, reason, diagnostics =
18414
18518
  workspace,
18415
18519
  channel,
18416
18520
  thread_id: threadId,
18521
+ ...diagnostics.instanceId === void 0 ? {} : { instance_id: diagnostics.instanceId },
18417
18522
  seq: sourceSeq,
18418
18523
  status,
18419
18524
  reason,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.71-beta",
3
+ "version": "0.0.72-beta",
4
4
  "description": "Linzumi CLI — point a Codex agent at the real code on your laptop, with your team watching and steering from shared threads.",
5
5
  "type": "module",
6
6
  "bin": {