@tryarcanist/cli 0.1.28 → 0.1.30

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/index.js +205 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -405,6 +405,175 @@ var RAW_OPENCODE_NOISE = /* @__PURE__ */ new Set([
405
405
  "lsp.updated",
406
406
  "lsp.client.diagnostics"
407
407
  ]);
408
+ function isCanonicalRawSessionEvent(event) {
409
+ return "phase" in event && typeof event.phase === "string";
410
+ }
411
+ function compatPayload(event) {
412
+ return event.payload;
413
+ }
414
+ function compatBridgeData(event) {
415
+ const bridgeData = compatPayload(event).bridgeData;
416
+ return isRecord(bridgeData) ? { ...bridgeData } : {};
417
+ }
418
+ function compatBridgeEventType(event) {
419
+ const bridgeEventType = compatPayload(event).bridgeEventType;
420
+ return typeof bridgeEventType === "string" && bridgeEventType.length > 0 ? bridgeEventType : void 0;
421
+ }
422
+ function canonicalPromptId(event) {
423
+ if (typeof event.promptId === "string" && event.promptId.length > 0) {
424
+ return event.promptId;
425
+ }
426
+ const bridgeData = compatBridgeData(event);
427
+ if (typeof bridgeData.promptId === "string" && bridgeData.promptId.length > 0) {
428
+ return bridgeData.promptId;
429
+ }
430
+ return typeof bridgeData.messageId === "string" && bridgeData.messageId.length > 0 ? bridgeData.messageId : void 0;
431
+ }
432
+ function withPromptId(event, data) {
433
+ const promptId = canonicalPromptId(event);
434
+ return promptId && data.promptId === void 0 ? { ...data, promptId } : data;
435
+ }
436
+ function normalizeBridgeCompatEventData(event, bridgeEventType, bridgeData) {
437
+ switch (bridgeEventType) {
438
+ case "tool_call":
439
+ return withPromptId(event, {
440
+ ...bridgeData,
441
+ ...typeof bridgeData.callId === "string" && bridgeData.callId.length > 0 && !(typeof bridgeData.id === "string" && bridgeData.id.length > 0) ? { id: bridgeData.callId } : {},
442
+ ...isRecord(bridgeData.args) && bridgeData.input === void 0 ? { input: bridgeData.args } : {}
443
+ });
444
+ case "tool_update":
445
+ return withPromptId(event, {
446
+ ...bridgeData,
447
+ ...typeof bridgeData.callId === "string" && bridgeData.callId.length > 0 && !(typeof bridgeData.id === "string" && bridgeData.id.length > 0) ? { id: bridgeData.callId } : {}
448
+ });
449
+ default:
450
+ return withPromptId(event, bridgeData);
451
+ }
452
+ }
453
+ function getRawSessionEventPromptId(event) {
454
+ if (isCanonicalRawSessionEvent(event)) {
455
+ return canonicalPromptId(event);
456
+ }
457
+ return typeof event.data?.promptId === "string" && event.data.promptId.length > 0 ? event.data.promptId : void 0;
458
+ }
459
+ function getRawSessionEventKind(event) {
460
+ if (!isCanonicalRawSessionEvent(event)) return event.type;
461
+ const payload = compatPayload(event);
462
+ const bridgeEventType = compatBridgeEventType(event);
463
+ switch (event.phase) {
464
+ case "text.delta":
465
+ return payload.channel === "reasoning" ? "reasoning" : "text";
466
+ case "tool.call":
467
+ return "tool_call";
468
+ case "tool.result":
469
+ return "tool_update";
470
+ case "prompt.enqueue":
471
+ return "prompt_enqueued";
472
+ case "prompt.dispatch":
473
+ return "prompt_processing";
474
+ case "prompt.complete":
475
+ return payload.success === false ? "prompt_failed" : "prompt_completed";
476
+ case "user_question":
477
+ return "question";
478
+ case "error":
479
+ return "session_error";
480
+ case "bridge.event":
481
+ return bridgeEventType ?? event.phase;
482
+ case "idle":
483
+ return bridgeEventType ?? "session_idle";
484
+ case "opencode.session.create":
485
+ case "git.push":
486
+ case "pr.open":
487
+ case "session.create":
488
+ case "sandbox.spawn":
489
+ case "bridge.connect":
490
+ return bridgeEventType ?? event.phase;
491
+ default:
492
+ return bridgeEventType ?? event.phase;
493
+ }
494
+ }
495
+ function getRawSessionEventData(event) {
496
+ if (!isCanonicalRawSessionEvent(event)) {
497
+ return isRecord(event.data) ? event.data : void 0;
498
+ }
499
+ const payload = compatPayload(event);
500
+ const bridgeEventType = compatBridgeEventType(event);
501
+ const base = withPromptId(event, compatBridgeData(event));
502
+ switch (event.phase) {
503
+ case "text.delta":
504
+ return withPromptId(event, {
505
+ ...base,
506
+ ...typeof payload.partId === "string" && payload.partId.length > 0 ? { id: payload.partId } : {},
507
+ text: payload.text
508
+ });
509
+ case "tool.call":
510
+ return withPromptId(event, {
511
+ ...base,
512
+ id: payload.callId,
513
+ tool: payload.tool,
514
+ input: isRecord(payload.args) ? payload.args : {},
515
+ summary: typeof payload.summary === "string" ? payload.summary : ""
516
+ });
517
+ case "tool.result":
518
+ return withPromptId(event, {
519
+ ...base,
520
+ id: payload.callId,
521
+ status: typeof base.status === "string" ? base.status : payload.ok ? "completed" : "error"
522
+ });
523
+ case "prompt.enqueue":
524
+ return withPromptId(event, {
525
+ ...base,
526
+ source: payload.source,
527
+ ...payload.actorUserId !== void 0 ? { actorUserId: payload.actorUserId } : {},
528
+ ...typeof payload.agent === "string" ? { agent: payload.agent } : {},
529
+ ...payload.model !== void 0 ? { model: payload.model } : {}
530
+ });
531
+ case "prompt.dispatch":
532
+ return withPromptId(event, {
533
+ ...base,
534
+ ...payload.startupAttemptId !== void 0 ? { startupAttemptId: payload.startupAttemptId } : {}
535
+ });
536
+ case "prompt.complete":
537
+ return withPromptId(event, {
538
+ ...base,
539
+ success: payload.success,
540
+ ...typeof payload.error === "string" ? { error: payload.error } : {},
541
+ ...typeof payload.errorCode === "string" ? { code: payload.errorCode } : {},
542
+ ...payload.errorDetails !== void 0 ? { errorDetails: payload.errorDetails } : {}
543
+ });
544
+ case "user_question":
545
+ return withPromptId(event, {
546
+ ...base,
547
+ id: payload.questionId,
548
+ question: payload.question,
549
+ ...Array.isArray(payload.options) ? { options: payload.options } : {}
550
+ });
551
+ case "error":
552
+ return withPromptId(event, {
553
+ ...base,
554
+ error: payload.message,
555
+ ...typeof payload.code === "string" ? { code: payload.code } : {},
556
+ ...payload.details !== void 0 ? { errorDetails: payload.details } : {}
557
+ });
558
+ case "bridge.event":
559
+ return normalizeBridgeCompatEventData(event, bridgeEventType, base);
560
+ case "idle":
561
+ return withPromptId(event, {
562
+ ...base,
563
+ ...typeof payload.taskType === "string" ? { taskType: payload.taskType } : {},
564
+ ...typeof payload.sessionEditCount === "number" ? { sessionEditCount: payload.sessionEditCount } : {},
565
+ ...typeof payload.sessionPromptCount === "number" ? { sessionPromptCount: payload.sessionPromptCount } : {}
566
+ });
567
+ default:
568
+ return withPromptId(event, base);
569
+ }
570
+ }
571
+ function normalizeRawSessionEvent(event) {
572
+ return {
573
+ type: getRawSessionEventKind(event),
574
+ data: getRawSessionEventData(event)
575
+ };
576
+ }
408
577
  function shouldAppendTextDelta(existingText, incomingText) {
409
578
  if (!incomingText) return false;
410
579
  if (incomingText.length < DUPLICATE_TEXT_DELTA_MIN_CHARS) return true;
@@ -452,8 +621,10 @@ function flattenSessionEvents(raw) {
452
621
  const toolCallIndexById = /* @__PURE__ */ new Map();
453
622
  const questionIndexById = /* @__PURE__ */ new Map();
454
623
  for (const event of raw) {
455
- const data = isRecord(event.data) ? event.data : void 0;
456
- if (event.type === "sandbox_compaction_start") {
624
+ const normalized = normalizeRawSessionEvent(event);
625
+ const { type } = normalized;
626
+ const data = normalized.data;
627
+ if (type === "sandbox_compaction_start") {
457
628
  merged.push({
458
629
  type: "compaction_start",
459
630
  id: `cs-${data?.timestamp ?? merged.length}`,
@@ -462,7 +633,7 @@ function flattenSessionEvents(raw) {
462
633
  });
463
634
  continue;
464
635
  }
465
- if (event.type === "sandbox_compaction_complete") {
636
+ if (type === "sandbox_compaction_complete") {
466
637
  merged.push({
467
638
  type: "compaction_complete",
468
639
  id: `cc-${data?.timestamp ?? merged.length}`,
@@ -472,7 +643,7 @@ function flattenSessionEvents(raw) {
472
643
  });
473
644
  continue;
474
645
  }
475
- if (event.type === "sandbox_context_fill_warning") {
646
+ if (type === "sandbox_context_fill_warning") {
476
647
  merged.push({
477
648
  type: "context_fill_warning",
478
649
  id: `cfw-${data?.timestamp ?? merged.length}`,
@@ -483,7 +654,7 @@ function flattenSessionEvents(raw) {
483
654
  });
484
655
  continue;
485
656
  }
486
- if (event.type === "sandbox_tool_truncated") {
657
+ if (type === "sandbox_tool_truncated") {
487
658
  merged.push({
488
659
  type: "tool_truncated",
489
660
  id: typeof data?.callId === "string" ? data.callId : String(merged.length),
@@ -492,7 +663,7 @@ function flattenSessionEvents(raw) {
492
663
  });
493
664
  continue;
494
665
  }
495
- if (event.type === "retry_status") {
666
+ if (type === "retry_status") {
496
667
  merged.push({
497
668
  type: "retry_status",
498
669
  id: `rs-${data?.timestamp ?? merged.length}`,
@@ -509,7 +680,7 @@ function flattenSessionEvents(raw) {
509
680
  });
510
681
  continue;
511
682
  }
512
- if (event.type === "branch_changed") {
683
+ if (type === "branch_changed") {
513
684
  merged.push({
514
685
  type: "branch_changed",
515
686
  id: `bc-${data?.timestamp ?? merged.length}`,
@@ -518,7 +689,7 @@ function flattenSessionEvents(raw) {
518
689
  });
519
690
  continue;
520
691
  }
521
- if (event.type === "session_error") {
692
+ if (type === "session_error") {
522
693
  merged.push({
523
694
  type: "session_error",
524
695
  id: resolveEventId(data, "err", merged.length),
@@ -528,7 +699,7 @@ function flattenSessionEvents(raw) {
528
699
  });
529
700
  continue;
530
701
  }
531
- if (event.type === "raw_opencode") {
702
+ if (type === "raw_opencode") {
532
703
  const partType = typeof data?.partType === "string" ? data.partType : void 0;
533
704
  const eventType = typeof data?.eventType === "string" ? data.eventType : void 0;
534
705
  if (partType === "text") continue;
@@ -543,7 +714,7 @@ function flattenSessionEvents(raw) {
543
714
  });
544
715
  continue;
545
716
  }
546
- if (event.type === "reasoning") {
717
+ if (type === "reasoning") {
547
718
  const streamId = resolveEventId(data, "reasoning", merged.length);
548
719
  const key = streamableKey("reasoning", streamId);
549
720
  const text = resolveTextValue(data);
@@ -574,7 +745,7 @@ function flattenSessionEvents(raw) {
574
745
  }
575
746
  continue;
576
747
  }
577
- if (event.type === "patch") {
748
+ if (type === "patch") {
578
749
  const files = Array.isArray(data?.files) ? data.files.filter((item) => typeof item === "string") : [];
579
750
  if (files.length > 0) {
580
751
  merged.push({ type: "patch", id: `patch-${merged.length}`, files });
@@ -585,7 +756,7 @@ function flattenSessionEvents(raw) {
585
756
  }
586
757
  continue;
587
758
  }
588
- if (event.type === "todo_update") {
759
+ if (type === "todo_update") {
589
760
  const todos = Array.isArray(data?.todos) ? data.todos : [];
590
761
  if (todos.length > 0) {
591
762
  for (let index = merged.length - 1; index >= 0; index--) {
@@ -598,7 +769,7 @@ function flattenSessionEvents(raw) {
598
769
  }
599
770
  continue;
600
771
  }
601
- if (event.type === "answer") {
772
+ if (type === "answer") {
602
773
  const questionId = typeof data?.id === "string" ? data.id : void 0;
603
774
  if (!questionId) continue;
604
775
  const existingIdx = questionIndexById.get(questionId);
@@ -613,10 +784,10 @@ function flattenSessionEvents(raw) {
613
784
  }
614
785
  continue;
615
786
  }
616
- if (event.type !== "text" && event.type !== "tool_call" && event.type !== "tool_update" && event.type !== "question") {
787
+ if (type !== "text" && type !== "tool_call" && type !== "tool_update" && type !== "question") {
617
788
  continue;
618
789
  }
619
- if (event.type === "text") {
790
+ if (type === "text") {
620
791
  const streamId = resolveEventId(data, "text", merged.length);
621
792
  const key = streamableKey("text", streamId);
622
793
  const text = resolveTextValue(data);
@@ -647,7 +818,7 @@ function flattenSessionEvents(raw) {
647
818
  }
648
819
  continue;
649
820
  }
650
- if (event.type === "tool_call") {
821
+ if (type === "tool_call") {
651
822
  const id = resolveEventId(data, "tool", merged.length);
652
823
  const nextEntry = {
653
824
  type: "tool_call",
@@ -674,7 +845,7 @@ function flattenSessionEvents(raw) {
674
845
  }
675
846
  continue;
676
847
  }
677
- if (event.type === "tool_update") {
848
+ if (type === "tool_update") {
678
849
  const id = typeof data?.id === "string" ? data.id : "";
679
850
  const existingIdx = toolCallIndexById.get(id);
680
851
  if (existingIdx !== void 0) {
@@ -709,8 +880,9 @@ function partitionEventsByPrompt(allEvents, promptIds) {
709
880
  const buckets = new Map(promptIds.map((id) => [id, []]));
710
881
  let currentPromptId = null;
711
882
  for (const event of allEvents) {
712
- const explicitPromptId = typeof event.data?.promptId === "string" && promptSet.has(event.data.promptId) ? event.data.promptId : null;
713
- if (event.type === "prompt_processing") {
883
+ const eventPromptId = getRawSessionEventPromptId(event);
884
+ const explicitPromptId = typeof eventPromptId === "string" && promptSet.has(eventPromptId) ? eventPromptId : null;
885
+ if (getRawSessionEventKind(event) === "prompt_processing") {
714
886
  currentPromptId = explicitPromptId;
715
887
  }
716
888
  const targetPromptId = explicitPromptId ?? currentPromptId;
@@ -724,8 +896,9 @@ function partitionEventsByPrompt(allEvents, promptIds) {
724
896
  function getEmbeddedTerminalHistory(raw) {
725
897
  for (let index = raw.length - 1; index >= 0; index--) {
726
898
  const event = raw[index];
727
- if (event.type !== "prompt_completed" && event.type !== "prompt_failed") continue;
728
- const history = event.data?.history;
899
+ const eventType = getRawSessionEventKind(event);
900
+ if (eventType !== "prompt_completed" && eventType !== "prompt_failed") continue;
901
+ const history = getRawSessionEventData(event)?.history;
729
902
  if (!Array.isArray(history) || history.length === 0) return null;
730
903
  return history;
731
904
  }
@@ -741,16 +914,17 @@ function extractSubagentInfo(raw) {
741
914
  toolToChildSessions: /* @__PURE__ */ new Map(),
742
915
  subagentUsage: /* @__PURE__ */ new Map()
743
916
  };
744
- if (!raw.some((event) => SUBAGENT_EVENT_TYPES.has(event.type))) return empty;
917
+ if (!raw.some((event) => SUBAGENT_EVENT_TYPES.has(getRawSessionEventKind(event)))) return empty;
745
918
  const { names, activity, toolToChildSessions, subagentUsage } = empty;
746
919
  for (const event of raw) {
747
- const data = event.data;
920
+ const type = getRawSessionEventKind(event);
921
+ const data = getRawSessionEventData(event);
748
922
  if (!data) continue;
749
923
  const childSessionId = typeof data.childSessionId === "string" ? data.childSessionId : void 0;
750
924
  const parentToolId = typeof data.parentToolId === "string" ? data.parentToolId : void 0;
751
925
  const key = childSessionId || parentToolId;
752
926
  if (!key) continue;
753
- if (event.type === "subagent_start" || event.type === "subagent_complete") {
927
+ if (type === "subagent_start" || type === "subagent_complete") {
754
928
  const name = typeof data.name === "string" ? data.name : "";
755
929
  if (name) names.set(key, name);
756
930
  if (parentToolId && childSessionId) {
@@ -758,7 +932,7 @@ function extractSubagentInfo(raw) {
758
932
  if (!existing.includes(childSessionId)) existing.push(childSessionId);
759
933
  toolToChildSessions.set(parentToolId, existing);
760
934
  }
761
- if (event.type === "subagent_complete" && isRecord(data.tokenUsage)) {
935
+ if (type === "subagent_complete" && isRecord(data.tokenUsage)) {
762
936
  subagentUsage.set(key, {
763
937
  input: Number(data.tokenUsage.input ?? 0),
764
938
  output: Number(data.tokenUsage.output ?? 0),
@@ -768,7 +942,7 @@ function extractSubagentInfo(raw) {
768
942
  }
769
943
  continue;
770
944
  }
771
- if (event.type === "subagent_tool_call") {
945
+ if (type === "subagent_tool_call") {
772
946
  const items = activity.get(key) ?? [];
773
947
  items.push({
774
948
  type: "tool",
@@ -778,7 +952,7 @@ function extractSubagentInfo(raw) {
778
952
  activity.set(key, items);
779
953
  continue;
780
954
  }
781
- if (event.type === "subagent_text") {
955
+ if (type === "subagent_text") {
782
956
  const delta = typeof data.delta === "string" ? data.delta : typeof data.text === "string" ? data.text : "";
783
957
  if (!delta) continue;
784
958
  const items = activity.get(key) ?? [];
@@ -1500,7 +1674,10 @@ async function sessionEventsCommand(sessionId, options, command) {
1500
1674
  const state = { promptLabels, toolCalls: /* @__PURE__ */ new Map() };
1501
1675
  let textOpen = false;
1502
1676
  for (const event of payload.events) {
1503
- const rendered = renderWatchEvent(event, state);
1677
+ const rendered = renderWatchEvent({
1678
+ type: getRawSessionEventKind(event),
1679
+ data: getRawSessionEventData(event) ?? {}
1680
+ }, state);
1504
1681
  if (rendered?.kind === "line") {
1505
1682
  if (textOpen) {
1506
1683
  process.stdout.write("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryarcanist/cli",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "CLI for Arcanist — create and manage coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {