@canonmsg/codex-plugin 0.11.7 → 0.11.9

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 +36 -5
  2. package/package.json +3 -3
package/dist/host.js CHANGED
@@ -122,7 +122,12 @@ function buildCodexModelOptions(model) {
122
122
  function normalizeRuntimeTurnState(value) {
123
123
  const normalizedTurn = normalizeTurnState(value);
124
124
  if (normalizedTurn) {
125
- 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
+ };
126
131
  }
127
132
  return null;
128
133
  }
@@ -472,6 +477,10 @@ export async function main() {
472
477
  }).catch(() => { });
473
478
  }
474
479
  function writeTurn(session) {
480
+ const isOpenTurn = session.turnState === 'thinking'
481
+ || session.turnState === 'streaming'
482
+ || session.turnState === 'tool'
483
+ || session.turnState === 'waiting_input';
475
484
  runtimeState.writeTurnState(session.conversationId, {
476
485
  turnId: session.currentTurnId,
477
486
  state: session.turnState,
@@ -480,11 +489,15 @@ export async function main() {
480
489
  lastAcceptedIntent: session.lastAcceptedIntent,
481
490
  capabilities: CODEX_RUNTIME_CAPABILITIES,
482
491
  ...(session.currentTurnOpenedAt ? { openedAt: session.currentTurnOpenedAt } : {}),
492
+ ...(isOpenTurn && session.currentTurnUpdatedAt ? { turnUpdatedAt: session.currentTurnUpdatedAt } : {}),
483
493
  ...(session.turnState === 'idle' || session.turnState === 'completed' || session.turnState === 'interrupted'
484
494
  ? { completedAt: { '.sv': 'timestamp' } }
485
495
  : {}),
486
496
  }).catch(() => { });
487
497
  }
498
+ function markTurnProgress(session) {
499
+ session.currentTurnUpdatedAt = Date.now();
500
+ }
488
501
  async function markQueuedMessageAccepted(conversationId, sourceMessageId, markAccepted) {
489
502
  if (!markAccepted || !sourceMessageId)
490
503
  return;
@@ -566,6 +579,7 @@ export async function main() {
566
579
  session.turnState = 'idle';
567
580
  session.currentTurnId = null;
568
581
  session.currentTurnOpenedAt = null;
582
+ session.currentTurnUpdatedAt = null;
569
583
  session.lastAcceptedIntent = null;
570
584
  session.resetRequested = false;
571
585
  }
@@ -652,6 +666,7 @@ export async function main() {
652
666
  turnState: 'idle',
653
667
  currentTurnId: null,
654
668
  currentTurnOpenedAt: null,
669
+ currentTurnUpdatedAt: null,
655
670
  activeSelfContextId: null,
656
671
  lastAcceptedIntent: null,
657
672
  resetRequested: false,
@@ -742,6 +757,9 @@ export async function main() {
742
757
  }
743
758
  console.error(`[canon-codex] [${input.conversationId.slice(0, 8)}] Message from ${input.senderName}: "${content.slice(0, 80)}" (${autoReply.reason})`);
744
759
  markGroupContextModeUsed(input.conversationId, participantContext.groupContextMode);
760
+ const turnMetadata = normalizeTurnMetadata(input.message.metadata);
761
+ const deliveryIntent = turnMetadata?.deliveryIntent ?? 'queue';
762
+ const shouldMarkAccepted = turnMetadata?.inboundDisposition === 'queued';
745
763
  let session;
746
764
  try {
747
765
  session = await getOrCreateSession(input.conversationId);
@@ -750,6 +768,7 @@ export async function main() {
750
768
  const message = error instanceof Error ? error.message : String(error);
751
769
  const userMessage = error instanceof ExecutionEnvironmentError ? error.userMessage : message;
752
770
  console.error(`[canon-codex] [${input.conversationId.slice(0, 8)}] Failed to create session: ${message}`);
771
+ await markQueuedMessageAccepted(input.conversationId, input.message.id, shouldMarkAccepted);
753
772
  await client.sendMessage(input.conversationId, `I couldn't start a coding session for this workspace: ${userMessage}`, {
754
773
  ...(activeSelfContextId ? { selfContextId: activeSelfContextId } : {}),
755
774
  metadata: {
@@ -760,10 +779,7 @@ export async function main() {
760
779
  }).catch(() => { });
761
780
  return;
762
781
  }
763
- const turnMetadata = normalizeTurnMetadata(input.message.metadata);
764
782
  session.activeSelfContextId = activeSelfContextId;
765
- const deliveryIntent = turnMetadata?.deliveryIntent ?? 'queue';
766
- const shouldMarkAccepted = turnMetadata?.inboundDisposition === 'queued';
767
783
  const prompt = buildCanonPrompt({
768
784
  content,
769
785
  conversationId: input.conversationId,
@@ -793,6 +809,7 @@ export async function main() {
793
809
  session.state.state = 'running';
794
810
  session.currentTurnId = randomUUID();
795
811
  session.currentTurnOpenedAt = Date.now();
812
+ session.currentTurnUpdatedAt = session.currentTurnOpenedAt;
796
813
  session.lastAcceptedIntent = nextTurn.intent;
797
814
  session.turnState = 'thinking';
798
815
  session.lastActivity = Date.now();
@@ -823,6 +840,7 @@ export async function main() {
823
840
  }
824
841
  if (event.type === 'message') {
825
842
  session.turnState = 'streaming';
843
+ markTurnProgress(session);
826
844
  writeTurn(session);
827
845
  stopVisibleWorkSignal(session);
828
846
  client.setTyping(session.conversationId, false).catch(() => { });
@@ -834,6 +852,7 @@ export async function main() {
834
852
  }
835
853
  if (event.type === 'command.started') {
836
854
  session.turnState = 'tool';
855
+ markTurnProgress(session);
837
856
  writeTurn(session);
838
857
  startVisibleWorkSignal(session);
839
858
  runtimeState.writeStreaming(session.conversationId, {
@@ -842,6 +861,15 @@ export async function main() {
842
861
  }).catch(() => { });
843
862
  return;
844
863
  }
864
+ if (event.type === 'command.completed') {
865
+ if (session.turnState === 'tool') {
866
+ session.turnState = 'thinking';
867
+ markTurnProgress(session);
868
+ writeTurn(session);
869
+ startVisibleWorkSignal(session);
870
+ }
871
+ return;
872
+ }
845
873
  if (event.type === 'turn.completed') {
846
874
  writeState(session);
847
875
  }
@@ -947,6 +975,7 @@ export async function main() {
947
975
  session.turnState = 'idle';
948
976
  session.currentTurnId = null;
949
977
  session.currentTurnOpenedAt = null;
978
+ session.currentTurnUpdatedAt = null;
950
979
  session.lastAcceptedIntent = null;
951
980
  session.resetRequested = false;
952
981
  session.lastActivity = Date.now();
@@ -1351,7 +1380,9 @@ export async function main() {
1351
1380
  const heartbeat = setInterval(() => {
1352
1381
  for (const session of sessions.values()) {
1353
1382
  writeState(session);
1354
- writeTurn(session);
1383
+ if (!session.running) {
1384
+ writeTurn(session);
1385
+ }
1355
1386
  }
1356
1387
  void publishRuntimeHeartbeat();
1357
1388
  }, HEARTBEAT_MS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/codex-plugin",
3
- "version": "0.11.7",
3
+ "version": "0.11.9",
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.2",
33
- "@canonmsg/core": "^0.19.3"
32
+ "@canonmsg/agent-sdk": "^1.5.5",
33
+ "@canonmsg/core": "^0.21.0"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=18.0.0"