@tryarcanist/cli 0.1.28 → 0.1.29

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 +185 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -405,6 +405,155 @@ 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 getRawSessionEventPromptId(event) {
437
+ if (isCanonicalRawSessionEvent(event)) {
438
+ return canonicalPromptId(event);
439
+ }
440
+ return typeof event.data?.promptId === "string" && event.data.promptId.length > 0 ? event.data.promptId : void 0;
441
+ }
442
+ function getRawSessionEventKind(event) {
443
+ if (!isCanonicalRawSessionEvent(event)) return event.type;
444
+ const payload = compatPayload(event);
445
+ const bridgeEventType = compatBridgeEventType(event);
446
+ switch (event.phase) {
447
+ case "text.delta":
448
+ return payload.channel === "reasoning" ? "reasoning" : "text";
449
+ case "tool.call":
450
+ return "tool_call";
451
+ case "tool.result":
452
+ return "tool_update";
453
+ case "prompt.enqueue":
454
+ return "prompt_enqueued";
455
+ case "prompt.dispatch":
456
+ return "prompt_processing";
457
+ case "prompt.complete":
458
+ return payload.success === false ? "prompt_failed" : "prompt_completed";
459
+ case "user_question":
460
+ return "question";
461
+ case "error":
462
+ return "session_error";
463
+ case "bridge.event":
464
+ return bridgeEventType ?? event.phase;
465
+ case "idle":
466
+ return bridgeEventType ?? "session_idle";
467
+ case "opencode.session.create":
468
+ case "git.push":
469
+ case "pr.open":
470
+ case "session.create":
471
+ case "sandbox.spawn":
472
+ case "bridge.connect":
473
+ return bridgeEventType ?? event.phase;
474
+ default:
475
+ return bridgeEventType ?? event.phase;
476
+ }
477
+ }
478
+ function getRawSessionEventData(event) {
479
+ if (!isCanonicalRawSessionEvent(event)) {
480
+ return isRecord(event.data) ? event.data : void 0;
481
+ }
482
+ const payload = compatPayload(event);
483
+ const base = withPromptId(event, compatBridgeData(event));
484
+ switch (event.phase) {
485
+ case "text.delta":
486
+ return withPromptId(event, {
487
+ ...base,
488
+ ...typeof payload.partId === "string" && payload.partId.length > 0 ? { id: payload.partId } : {},
489
+ text: payload.text
490
+ });
491
+ case "tool.call":
492
+ return withPromptId(event, {
493
+ ...base,
494
+ id: payload.callId,
495
+ tool: payload.tool,
496
+ input: isRecord(payload.args) ? payload.args : {},
497
+ summary: typeof payload.summary === "string" ? payload.summary : ""
498
+ });
499
+ case "tool.result":
500
+ return withPromptId(event, {
501
+ ...base,
502
+ id: payload.callId,
503
+ status: typeof base.status === "string" ? base.status : payload.ok ? "completed" : "error"
504
+ });
505
+ case "prompt.enqueue":
506
+ return withPromptId(event, {
507
+ ...base,
508
+ source: payload.source,
509
+ ...payload.actorUserId !== void 0 ? { actorUserId: payload.actorUserId } : {},
510
+ ...typeof payload.agent === "string" ? { agent: payload.agent } : {},
511
+ ...payload.model !== void 0 ? { model: payload.model } : {}
512
+ });
513
+ case "prompt.dispatch":
514
+ return withPromptId(event, {
515
+ ...base,
516
+ ...payload.startupAttemptId !== void 0 ? { startupAttemptId: payload.startupAttemptId } : {}
517
+ });
518
+ case "prompt.complete":
519
+ return withPromptId(event, {
520
+ ...base,
521
+ success: payload.success,
522
+ ...typeof payload.error === "string" ? { error: payload.error } : {},
523
+ ...typeof payload.errorCode === "string" ? { code: payload.errorCode } : {},
524
+ ...payload.errorDetails !== void 0 ? { errorDetails: payload.errorDetails } : {}
525
+ });
526
+ case "user_question":
527
+ return withPromptId(event, {
528
+ ...base,
529
+ id: payload.questionId,
530
+ question: payload.question,
531
+ ...Array.isArray(payload.options) ? { options: payload.options } : {}
532
+ });
533
+ case "error":
534
+ return withPromptId(event, {
535
+ ...base,
536
+ error: payload.message,
537
+ ...typeof payload.code === "string" ? { code: payload.code } : {},
538
+ ...payload.details !== void 0 ? { errorDetails: payload.details } : {}
539
+ });
540
+ case "idle":
541
+ return withPromptId(event, {
542
+ ...base,
543
+ ...typeof payload.taskType === "string" ? { taskType: payload.taskType } : {},
544
+ ...typeof payload.sessionEditCount === "number" ? { sessionEditCount: payload.sessionEditCount } : {},
545
+ ...typeof payload.sessionPromptCount === "number" ? { sessionPromptCount: payload.sessionPromptCount } : {}
546
+ });
547
+ default:
548
+ return withPromptId(event, base);
549
+ }
550
+ }
551
+ function normalizeRawSessionEvent(event) {
552
+ return {
553
+ type: getRawSessionEventKind(event),
554
+ data: getRawSessionEventData(event)
555
+ };
556
+ }
408
557
  function shouldAppendTextDelta(existingText, incomingText) {
409
558
  if (!incomingText) return false;
410
559
  if (incomingText.length < DUPLICATE_TEXT_DELTA_MIN_CHARS) return true;
@@ -452,8 +601,10 @@ function flattenSessionEvents(raw) {
452
601
  const toolCallIndexById = /* @__PURE__ */ new Map();
453
602
  const questionIndexById = /* @__PURE__ */ new Map();
454
603
  for (const event of raw) {
455
- const data = isRecord(event.data) ? event.data : void 0;
456
- if (event.type === "sandbox_compaction_start") {
604
+ const normalized = normalizeRawSessionEvent(event);
605
+ const { type } = normalized;
606
+ const data = normalized.data;
607
+ if (type === "sandbox_compaction_start") {
457
608
  merged.push({
458
609
  type: "compaction_start",
459
610
  id: `cs-${data?.timestamp ?? merged.length}`,
@@ -462,7 +613,7 @@ function flattenSessionEvents(raw) {
462
613
  });
463
614
  continue;
464
615
  }
465
- if (event.type === "sandbox_compaction_complete") {
616
+ if (type === "sandbox_compaction_complete") {
466
617
  merged.push({
467
618
  type: "compaction_complete",
468
619
  id: `cc-${data?.timestamp ?? merged.length}`,
@@ -472,7 +623,7 @@ function flattenSessionEvents(raw) {
472
623
  });
473
624
  continue;
474
625
  }
475
- if (event.type === "sandbox_context_fill_warning") {
626
+ if (type === "sandbox_context_fill_warning") {
476
627
  merged.push({
477
628
  type: "context_fill_warning",
478
629
  id: `cfw-${data?.timestamp ?? merged.length}`,
@@ -483,7 +634,7 @@ function flattenSessionEvents(raw) {
483
634
  });
484
635
  continue;
485
636
  }
486
- if (event.type === "sandbox_tool_truncated") {
637
+ if (type === "sandbox_tool_truncated") {
487
638
  merged.push({
488
639
  type: "tool_truncated",
489
640
  id: typeof data?.callId === "string" ? data.callId : String(merged.length),
@@ -492,7 +643,7 @@ function flattenSessionEvents(raw) {
492
643
  });
493
644
  continue;
494
645
  }
495
- if (event.type === "retry_status") {
646
+ if (type === "retry_status") {
496
647
  merged.push({
497
648
  type: "retry_status",
498
649
  id: `rs-${data?.timestamp ?? merged.length}`,
@@ -509,7 +660,7 @@ function flattenSessionEvents(raw) {
509
660
  });
510
661
  continue;
511
662
  }
512
- if (event.type === "branch_changed") {
663
+ if (type === "branch_changed") {
513
664
  merged.push({
514
665
  type: "branch_changed",
515
666
  id: `bc-${data?.timestamp ?? merged.length}`,
@@ -518,7 +669,7 @@ function flattenSessionEvents(raw) {
518
669
  });
519
670
  continue;
520
671
  }
521
- if (event.type === "session_error") {
672
+ if (type === "session_error") {
522
673
  merged.push({
523
674
  type: "session_error",
524
675
  id: resolveEventId(data, "err", merged.length),
@@ -528,7 +679,7 @@ function flattenSessionEvents(raw) {
528
679
  });
529
680
  continue;
530
681
  }
531
- if (event.type === "raw_opencode") {
682
+ if (type === "raw_opencode") {
532
683
  const partType = typeof data?.partType === "string" ? data.partType : void 0;
533
684
  const eventType = typeof data?.eventType === "string" ? data.eventType : void 0;
534
685
  if (partType === "text") continue;
@@ -543,7 +694,7 @@ function flattenSessionEvents(raw) {
543
694
  });
544
695
  continue;
545
696
  }
546
- if (event.type === "reasoning") {
697
+ if (type === "reasoning") {
547
698
  const streamId = resolveEventId(data, "reasoning", merged.length);
548
699
  const key = streamableKey("reasoning", streamId);
549
700
  const text = resolveTextValue(data);
@@ -574,7 +725,7 @@ function flattenSessionEvents(raw) {
574
725
  }
575
726
  continue;
576
727
  }
577
- if (event.type === "patch") {
728
+ if (type === "patch") {
578
729
  const files = Array.isArray(data?.files) ? data.files.filter((item) => typeof item === "string") : [];
579
730
  if (files.length > 0) {
580
731
  merged.push({ type: "patch", id: `patch-${merged.length}`, files });
@@ -585,7 +736,7 @@ function flattenSessionEvents(raw) {
585
736
  }
586
737
  continue;
587
738
  }
588
- if (event.type === "todo_update") {
739
+ if (type === "todo_update") {
589
740
  const todos = Array.isArray(data?.todos) ? data.todos : [];
590
741
  if (todos.length > 0) {
591
742
  for (let index = merged.length - 1; index >= 0; index--) {
@@ -598,7 +749,7 @@ function flattenSessionEvents(raw) {
598
749
  }
599
750
  continue;
600
751
  }
601
- if (event.type === "answer") {
752
+ if (type === "answer") {
602
753
  const questionId = typeof data?.id === "string" ? data.id : void 0;
603
754
  if (!questionId) continue;
604
755
  const existingIdx = questionIndexById.get(questionId);
@@ -613,10 +764,10 @@ function flattenSessionEvents(raw) {
613
764
  }
614
765
  continue;
615
766
  }
616
- if (event.type !== "text" && event.type !== "tool_call" && event.type !== "tool_update" && event.type !== "question") {
767
+ if (type !== "text" && type !== "tool_call" && type !== "tool_update" && type !== "question") {
617
768
  continue;
618
769
  }
619
- if (event.type === "text") {
770
+ if (type === "text") {
620
771
  const streamId = resolveEventId(data, "text", merged.length);
621
772
  const key = streamableKey("text", streamId);
622
773
  const text = resolveTextValue(data);
@@ -647,7 +798,7 @@ function flattenSessionEvents(raw) {
647
798
  }
648
799
  continue;
649
800
  }
650
- if (event.type === "tool_call") {
801
+ if (type === "tool_call") {
651
802
  const id = resolveEventId(data, "tool", merged.length);
652
803
  const nextEntry = {
653
804
  type: "tool_call",
@@ -674,7 +825,7 @@ function flattenSessionEvents(raw) {
674
825
  }
675
826
  continue;
676
827
  }
677
- if (event.type === "tool_update") {
828
+ if (type === "tool_update") {
678
829
  const id = typeof data?.id === "string" ? data.id : "";
679
830
  const existingIdx = toolCallIndexById.get(id);
680
831
  if (existingIdx !== void 0) {
@@ -709,8 +860,9 @@ function partitionEventsByPrompt(allEvents, promptIds) {
709
860
  const buckets = new Map(promptIds.map((id) => [id, []]));
710
861
  let currentPromptId = null;
711
862
  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") {
863
+ const eventPromptId = getRawSessionEventPromptId(event);
864
+ const explicitPromptId = typeof eventPromptId === "string" && promptSet.has(eventPromptId) ? eventPromptId : null;
865
+ if (getRawSessionEventKind(event) === "prompt_processing") {
714
866
  currentPromptId = explicitPromptId;
715
867
  }
716
868
  const targetPromptId = explicitPromptId ?? currentPromptId;
@@ -724,8 +876,9 @@ function partitionEventsByPrompt(allEvents, promptIds) {
724
876
  function getEmbeddedTerminalHistory(raw) {
725
877
  for (let index = raw.length - 1; index >= 0; index--) {
726
878
  const event = raw[index];
727
- if (event.type !== "prompt_completed" && event.type !== "prompt_failed") continue;
728
- const history = event.data?.history;
879
+ const eventType = getRawSessionEventKind(event);
880
+ if (eventType !== "prompt_completed" && eventType !== "prompt_failed") continue;
881
+ const history = getRawSessionEventData(event)?.history;
729
882
  if (!Array.isArray(history) || history.length === 0) return null;
730
883
  return history;
731
884
  }
@@ -741,16 +894,17 @@ function extractSubagentInfo(raw) {
741
894
  toolToChildSessions: /* @__PURE__ */ new Map(),
742
895
  subagentUsage: /* @__PURE__ */ new Map()
743
896
  };
744
- if (!raw.some((event) => SUBAGENT_EVENT_TYPES.has(event.type))) return empty;
897
+ if (!raw.some((event) => SUBAGENT_EVENT_TYPES.has(getRawSessionEventKind(event)))) return empty;
745
898
  const { names, activity, toolToChildSessions, subagentUsage } = empty;
746
899
  for (const event of raw) {
747
- const data = event.data;
900
+ const type = getRawSessionEventKind(event);
901
+ const data = getRawSessionEventData(event);
748
902
  if (!data) continue;
749
903
  const childSessionId = typeof data.childSessionId === "string" ? data.childSessionId : void 0;
750
904
  const parentToolId = typeof data.parentToolId === "string" ? data.parentToolId : void 0;
751
905
  const key = childSessionId || parentToolId;
752
906
  if (!key) continue;
753
- if (event.type === "subagent_start" || event.type === "subagent_complete") {
907
+ if (type === "subagent_start" || type === "subagent_complete") {
754
908
  const name = typeof data.name === "string" ? data.name : "";
755
909
  if (name) names.set(key, name);
756
910
  if (parentToolId && childSessionId) {
@@ -758,7 +912,7 @@ function extractSubagentInfo(raw) {
758
912
  if (!existing.includes(childSessionId)) existing.push(childSessionId);
759
913
  toolToChildSessions.set(parentToolId, existing);
760
914
  }
761
- if (event.type === "subagent_complete" && isRecord(data.tokenUsage)) {
915
+ if (type === "subagent_complete" && isRecord(data.tokenUsage)) {
762
916
  subagentUsage.set(key, {
763
917
  input: Number(data.tokenUsage.input ?? 0),
764
918
  output: Number(data.tokenUsage.output ?? 0),
@@ -768,7 +922,7 @@ function extractSubagentInfo(raw) {
768
922
  }
769
923
  continue;
770
924
  }
771
- if (event.type === "subagent_tool_call") {
925
+ if (type === "subagent_tool_call") {
772
926
  const items = activity.get(key) ?? [];
773
927
  items.push({
774
928
  type: "tool",
@@ -778,7 +932,7 @@ function extractSubagentInfo(raw) {
778
932
  activity.set(key, items);
779
933
  continue;
780
934
  }
781
- if (event.type === "subagent_text") {
935
+ if (type === "subagent_text") {
782
936
  const delta = typeof data.delta === "string" ? data.delta : typeof data.text === "string" ? data.text : "";
783
937
  if (!delta) continue;
784
938
  const items = activity.get(key) ?? [];
@@ -1500,7 +1654,10 @@ async function sessionEventsCommand(sessionId, options, command) {
1500
1654
  const state = { promptLabels, toolCalls: /* @__PURE__ */ new Map() };
1501
1655
  let textOpen = false;
1502
1656
  for (const event of payload.events) {
1503
- const rendered = renderWatchEvent(event, state);
1657
+ const rendered = renderWatchEvent({
1658
+ type: getRawSessionEventKind(event),
1659
+ data: getRawSessionEventData(event) ?? {}
1660
+ }, state);
1504
1661
  if (rendered?.kind === "line") {
1505
1662
  if (textOpen) {
1506
1663
  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.29",
4
4
  "description": "CLI for Arcanist — create and manage coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {