@linzumi/cli 0.0.42-beta → 0.0.43-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/README.md CHANGED
@@ -63,7 +63,7 @@ Install the CLI or run it with `npx`:
63
63
 
64
64
  ```bash
65
65
  npm install -g @linzumi/cli@latest
66
- npx -y @linzumi/cli@0.0.42-beta --version
66
+ npx -y @linzumi/cli@0.0.43-beta --version
67
67
  linzumi --version
68
68
  ```
69
69
 
package/dist/index.js CHANGED
@@ -2461,6 +2461,8 @@ function shellCommandTokens(command) {
2461
2461
  var codexTypingHeartbeatMs = 5000;
2462
2462
  var defaultStreamFlushIntervalMs = 150;
2463
2463
  var maxForwardedTurnIds = 64;
2464
+ var maxClaimedKandanMessageKeys = 1024;
2465
+ var claimedKandanMessageKeys = new Set;
2464
2466
  async function attachChannelSession(args) {
2465
2467
  const session = args.options.channelSession;
2466
2468
  const chatTopic = `chat:${session.workspaceSlug}:${session.channelSlug}`;
@@ -2609,6 +2611,7 @@ async function attachChannelSession(args) {
2609
2611
  clearPendingStreamFlushTimers(state);
2610
2612
  rejectPendingApprovalRequests(state, new Error("runner closed"));
2611
2613
  await stopCodexTyping(args, state);
2614
+ releaseKandanMessageClaims(state);
2612
2615
  }
2613
2616
  };
2614
2617
  }
@@ -2650,6 +2653,7 @@ function initialChannelSessionState(cursor, rootSeq, kandanThreadId, codexThread
2650
2653
  forwardedTurnIds: new Set,
2651
2654
  forwardingTurnIds: new Set,
2652
2655
  retryableTurnIds: new Set,
2656
+ claimedKandanMessageKeys: new Set,
2653
2657
  localTuiTurnIds: new Set,
2654
2658
  mirroredTuiInputProjections: createBoundedCache(maxForwardedTurnIds),
2655
2659
  pendingTuiInputMirrors: new Map,
@@ -3376,6 +3380,15 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
3376
3380
  });
3377
3381
  return;
3378
3382
  }
3383
+ if (!claimKandanMessage(args, state, event)) {
3384
+ args.log("kandan.message_ignored", {
3385
+ seq: event.seq,
3386
+ actor_slug: event.actorSlug ?? null,
3387
+ actor_user_id: event.actorUserId ?? null,
3388
+ reason: "duplicate_message_claim"
3389
+ });
3390
+ return;
3391
+ }
3379
3392
  enqueuePendingKandanMessage(state.queue, {
3380
3393
  seq: event.seq,
3381
3394
  actorSlug: event.actorSlug,
@@ -3392,6 +3405,43 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
3392
3405
  await publishKandanMessageState(args, event, { status: "queued" });
3393
3406
  await drainKandanMessageQueue(args, state, payloadContext);
3394
3407
  }
3408
+ function kandanMessageClaimKey(args, threadId, seq) {
3409
+ const session = args.options.channelSession;
3410
+ return [
3411
+ args.options.runnerId,
3412
+ args.instanceId,
3413
+ session.workspaceSlug,
3414
+ session.channelSlug,
3415
+ threadId,
3416
+ String(seq)
3417
+ ].join(":");
3418
+ }
3419
+ function claimKandanMessage(args, state, event) {
3420
+ const threadId = event.threadId;
3421
+ if (threadId === undefined) {
3422
+ return false;
3423
+ }
3424
+ const key = kandanMessageClaimKey(args, threadId, event.seq);
3425
+ if (claimedKandanMessageKeys.has(key)) {
3426
+ return false;
3427
+ }
3428
+ claimedKandanMessageKeys.add(key);
3429
+ state.claimedKandanMessageKeys.add(key);
3430
+ if (state.claimedKandanMessageKeys.size > maxClaimedKandanMessageKeys) {
3431
+ const [expiredKey] = state.claimedKandanMessageKeys;
3432
+ if (expiredKey !== undefined) {
3433
+ state.claimedKandanMessageKeys.delete(expiredKey);
3434
+ claimedKandanMessageKeys.delete(expiredKey);
3435
+ }
3436
+ }
3437
+ return true;
3438
+ }
3439
+ function releaseKandanMessageClaims(state) {
3440
+ for (const key of state.claimedKandanMessageKeys) {
3441
+ claimedKandanMessageKeys.delete(key);
3442
+ }
3443
+ state.claimedKandanMessageKeys.clear();
3444
+ }
3395
3445
  async function startThreadMessageTurn(args, state, payloadContext, message) {
3396
3446
  if (state.kandanThreadId === undefined || state.codexThreadId === undefined) {
3397
3447
  throw new Error("cannot start a local Codex turn before thread binding");
@@ -8133,7 +8183,7 @@ function realpathOrResolved(pathValue) {
8133
8183
  }
8134
8184
 
8135
8185
  // src/version.ts
8136
- var linzumiCliVersion = "0.0.42-beta";
8186
+ var linzumiCliVersion = "0.0.43-beta";
8137
8187
  var linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
8138
8188
 
8139
8189
  // src/runnerLock.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.42-beta",
3
+ "version": "0.0.43-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": {