@canonmsg/codex-plugin 0.11.6 → 0.11.8

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 (2) hide show
  1. package/dist/host.js +46 -2
  2. package/package.json +3 -3
package/dist/host.js CHANGED
@@ -54,6 +54,7 @@ const CONTROL_POLL_MS = 2_000;
54
54
  const CODEX_RUNTIME_CAPABILITIES = {
55
55
  ...DEFAULT_RUNTIME_CAPABILITIES,
56
56
  supportsInterrupt: true,
57
+ supportsInputInterrupt: true,
57
58
  supportsQueue: true,
58
59
  supportsNonFinalPermanentMessages: false,
59
60
  };
@@ -121,7 +122,12 @@ function buildCodexModelOptions(model) {
121
122
  function normalizeRuntimeTurnState(value) {
122
123
  const normalizedTurn = normalizeTurnState(value);
123
124
  if (normalizedTurn) {
124
- return { state: normalizedTurn.state };
125
+ return {
126
+ state: normalizedTurn.state,
127
+ ...(normalizedTurn.openedAt !== undefined ? { openedAt: normalizedTurn.openedAt } : {}),
128
+ ...(normalizedTurn.updatedAt !== undefined ? { updatedAt: normalizedTurn.updatedAt } : {}),
129
+ ...(normalizedTurn.turnUpdatedAt !== undefined ? { turnUpdatedAt: normalizedTurn.turnUpdatedAt } : {}),
130
+ };
125
131
  }
126
132
  return null;
127
133
  }
@@ -471,6 +477,10 @@ export async function main() {
471
477
  }).catch(() => { });
472
478
  }
473
479
  function writeTurn(session) {
480
+ const isOpenTurn = session.turnState === 'thinking'
481
+ || session.turnState === 'streaming'
482
+ || session.turnState === 'tool'
483
+ || session.turnState === 'waiting_input';
474
484
  runtimeState.writeTurnState(session.conversationId, {
475
485
  turnId: session.currentTurnId,
476
486
  state: session.turnState,
@@ -479,11 +489,15 @@ export async function main() {
479
489
  lastAcceptedIntent: session.lastAcceptedIntent,
480
490
  capabilities: CODEX_RUNTIME_CAPABILITIES,
481
491
  ...(session.currentTurnOpenedAt ? { openedAt: session.currentTurnOpenedAt } : {}),
492
+ ...(isOpenTurn && session.currentTurnUpdatedAt ? { turnUpdatedAt: session.currentTurnUpdatedAt } : {}),
482
493
  ...(session.turnState === 'idle' || session.turnState === 'completed' || session.turnState === 'interrupted'
483
494
  ? { completedAt: { '.sv': 'timestamp' } }
484
495
  : {}),
485
496
  }).catch(() => { });
486
497
  }
498
+ function markTurnProgress(session) {
499
+ session.currentTurnUpdatedAt = Date.now();
500
+ }
487
501
  async function markQueuedMessageAccepted(conversationId, sourceMessageId, markAccepted) {
488
502
  if (!markAccepted || !sourceMessageId)
489
503
  return;
@@ -496,6 +510,16 @@ export async function main() {
496
510
  return client.updateMessageDisposition(conversationId, prompt.sourceMessageId, 'rejected').catch(() => { });
497
511
  }));
498
512
  }
513
+ function removeQueuedPrompt(conversationId, sourceMessageId) {
514
+ const session = sessions.get(conversationId);
515
+ if (!session || session.queue.length === 0)
516
+ return;
517
+ const before = session.queue.length;
518
+ session.queue = session.queue.filter((prompt) => prompt.sourceMessageId !== sourceMessageId);
519
+ if (session.queue.length !== before) {
520
+ writeTurn(session);
521
+ }
522
+ }
499
523
  function clearStreaming(conversationId) {
500
524
  runtimeState.clearStreaming(conversationId).catch(() => { });
501
525
  }
@@ -555,6 +579,7 @@ export async function main() {
555
579
  session.turnState = 'idle';
556
580
  session.currentTurnId = null;
557
581
  session.currentTurnOpenedAt = null;
582
+ session.currentTurnUpdatedAt = null;
558
583
  session.lastAcceptedIntent = null;
559
584
  session.resetRequested = false;
560
585
  }
@@ -641,6 +666,7 @@ export async function main() {
641
666
  turnState: 'idle',
642
667
  currentTurnId: null,
643
668
  currentTurnOpenedAt: null,
669
+ currentTurnUpdatedAt: null,
644
670
  activeSelfContextId: null,
645
671
  lastAcceptedIntent: null,
646
672
  resetRequested: false,
@@ -782,6 +808,7 @@ export async function main() {
782
808
  session.state.state = 'running';
783
809
  session.currentTurnId = randomUUID();
784
810
  session.currentTurnOpenedAt = Date.now();
811
+ session.currentTurnUpdatedAt = session.currentTurnOpenedAt;
785
812
  session.lastAcceptedIntent = nextTurn.intent;
786
813
  session.turnState = 'thinking';
787
814
  session.lastActivity = Date.now();
@@ -812,6 +839,7 @@ export async function main() {
812
839
  }
813
840
  if (event.type === 'message') {
814
841
  session.turnState = 'streaming';
842
+ markTurnProgress(session);
815
843
  writeTurn(session);
816
844
  stopVisibleWorkSignal(session);
817
845
  client.setTyping(session.conversationId, false).catch(() => { });
@@ -823,6 +851,7 @@ export async function main() {
823
851
  }
824
852
  if (event.type === 'command.started') {
825
853
  session.turnState = 'tool';
854
+ markTurnProgress(session);
826
855
  writeTurn(session);
827
856
  startVisibleWorkSignal(session);
828
857
  runtimeState.writeStreaming(session.conversationId, {
@@ -831,6 +860,15 @@ export async function main() {
831
860
  }).catch(() => { });
832
861
  return;
833
862
  }
863
+ if (event.type === 'command.completed') {
864
+ if (session.turnState === 'tool') {
865
+ session.turnState = 'thinking';
866
+ markTurnProgress(session);
867
+ writeTurn(session);
868
+ startVisibleWorkSignal(session);
869
+ }
870
+ return;
871
+ }
834
872
  if (event.type === 'turn.completed') {
835
873
  writeState(session);
836
874
  }
@@ -936,6 +974,7 @@ export async function main() {
936
974
  session.turnState = 'idle';
937
975
  session.currentTurnId = null;
938
976
  session.currentTurnOpenedAt = null;
977
+ session.currentTurnUpdatedAt = null;
939
978
  session.lastAcceptedIntent = null;
940
979
  session.resetRequested = false;
941
980
  session.lastActivity = Date.now();
@@ -1132,6 +1171,9 @@ export async function main() {
1132
1171
  });
1133
1172
  }
1134
1173
  },
1174
+ onMessageDeleted: (payload) => {
1175
+ removeQueuedPrompt(payload.conversationId, payload.messageId);
1176
+ },
1135
1177
  onConversationUpdated: (payload) => {
1136
1178
  handleConversationUpdated(payload);
1137
1179
  },
@@ -1337,7 +1379,9 @@ export async function main() {
1337
1379
  const heartbeat = setInterval(() => {
1338
1380
  for (const session of sessions.values()) {
1339
1381
  writeState(session);
1340
- writeTurn(session);
1382
+ if (!session.running) {
1383
+ writeTurn(session);
1384
+ }
1341
1385
  }
1342
1386
  void publishRuntimeHeartbeat();
1343
1387
  }, HEARTBEAT_MS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/codex-plugin",
3
- "version": "0.11.6",
3
+ "version": "0.11.8",
4
4
  "description": "Canon host integration for Codex CLI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,8 +29,8 @@
29
29
  "prepack": "npm run build"
30
30
  },
31
31
  "dependencies": {
32
- "@canonmsg/agent-sdk": "^1.5.1",
33
- "@canonmsg/core": "^0.19.2"
32
+ "@canonmsg/agent-sdk": "^1.5.3",
33
+ "@canonmsg/core": "^0.20.0"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=18.0.0"