@adhdev/daemon-core 0.9.82-rc.473 → 0.9.82-rc.475

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.
@@ -861,6 +861,119 @@ function parseConversationDb(
861
861
  return messages.length > 0 ? messages : null;
862
862
  }
863
863
 
864
+ /**
865
+ * Assemble the history.jsonl user-prompt index for a single session id into a
866
+ * partial NativeHistorySession (user prompts only — history.jsonl never carries
867
+ * assistant answers). Returns null when the index has no rows for this session.
868
+ * Shared by the history.jsonl read case and the .db sibling fallback.
869
+ */
870
+ function readHistoryJsonlSession(
871
+ resolvedSessionId: string,
872
+ workspace?: string,
873
+ ): NativeHistorySession | null {
874
+ if (!isUuidLike(resolvedSessionId)) return null;
875
+ const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
876
+ if (rows.length === 0) return null;
877
+
878
+ rows.sort((a, b) => a.receivedAt - b.receivedAt);
879
+ const firstWorkspace = workspace || rows.find((r) => r.workspace)?.workspace || '';
880
+
881
+ const messages: NativeHistoryMessage[] = [];
882
+ if (firstWorkspace) {
883
+ messages.push({
884
+ ts: new Date(rows[0].receivedAt).toISOString(),
885
+ receivedAt: rows[0].receivedAt,
886
+ role: 'system',
887
+ content: firstWorkspace,
888
+ kind: 'session_start',
889
+ agent: 'antigravity-cli',
890
+ historySessionId: resolvedSessionId,
891
+ workspace: firstWorkspace,
892
+ });
893
+ }
894
+
895
+ for (const row of rows) {
896
+ const msg: NativeHistoryMessage = {
897
+ ts: new Date(row.receivedAt).toISOString(),
898
+ receivedAt: row.receivedAt,
899
+ role: 'user',
900
+ content: row.display,
901
+ kind: 'standard',
902
+ agent: 'antigravity-cli',
903
+ historySessionId: resolvedSessionId,
904
+ };
905
+ if (row.workspace) msg.workspace = row.workspace;
906
+ messages.push(msg);
907
+ }
908
+
909
+ return {
910
+ messages,
911
+ providerSessionId: resolvedSessionId,
912
+ source: 'provider-native',
913
+ sourcePath: historyJsonlPath(),
914
+ sourceMtimeMs: statMtimeMs(historyJsonlPath()),
915
+ nativeHistoryCoverage: 'partial',
916
+ partialReason: 'antigravity_cli_history_jsonl_contains_user_prompts_only',
917
+ };
918
+ }
919
+
920
+ /**
921
+ * ANTIGRAVITY-COMPLETION-DASHBOARD-GAP: recover a bound session's transcript
922
+ * from the legacy sibling sources when its per-session .db read came back empty
923
+ * (transient WAL lock, assistant step not yet flushed, or a decode miss on a
924
+ * future step_payload schema). Tried in descending fidelity for the SAME
925
+ * session id — never cross-binds to another conversation:
926
+ * 1. brain transcript (full coverage, authoritative when present),
927
+ * 2. sibling conversations/<uuid>.pb (best-effort raw text),
928
+ * 3. history.jsonl (partial — user prompts only).
929
+ * Returns null when no sibling yields any message.
930
+ */
931
+ function readAntigravitySiblingFallback(
932
+ sessionId: string,
933
+ workspace?: string,
934
+ ): NativeHistorySession | null {
935
+ if (!isUuidLike(sessionId)) return null;
936
+
937
+ // (1) brain transcript — full coverage when antigravity actually wrote it.
938
+ const brainPath = findBrainTranscriptPath(sessionId);
939
+ if (brainPath && statMtimeMs(brainPath) > 0) {
940
+ const brainMessages = parseBrainTranscript(brainPath, sessionId, workspace);
941
+ if (brainMessages && brainMessages.length > 0) {
942
+ return {
943
+ messages: brainMessages,
944
+ providerSessionId: sessionId,
945
+ source: 'provider-native',
946
+ sourcePath: brainPath,
947
+ sourceMtimeMs: statMtimeMs(brainPath),
948
+ nativeHistoryCoverage: 'full',
949
+ workspace,
950
+ };
951
+ }
952
+ }
953
+
954
+ // (2) sibling .pb — best-effort raw text extraction.
955
+ const pbPath = resolvePathInside(conversationsRoot(), `${sessionId}.pb`);
956
+ if (pbPath && fs.existsSync(pbPath)) {
957
+ const pbMessages = parsePbFile(pbPath, sessionId);
958
+ if (pbMessages && pbMessages.length > 0) {
959
+ return {
960
+ messages: pbMessages,
961
+ providerSessionId: sessionId,
962
+ source: 'provider-native',
963
+ sourcePath: pbPath,
964
+ sourceMtimeMs: statMtimeMs(pbPath),
965
+ nativeHistoryCoverage: 'best-effort',
966
+ partialReason: 'antigravity_cli_pb_raw_text_extraction',
967
+ workspace,
968
+ };
969
+ }
970
+ }
971
+
972
+ // (3) history.jsonl — partial (user prompts only). Last resort so the
973
+ // dashboard at least shows the prompt when no answer source is readable.
974
+ return readHistoryJsonlSession(sessionId, workspace);
975
+ }
976
+
864
977
  // ─── Public API ─────────────────────────────────────────────────────────────
865
978
 
866
979
  /**
@@ -916,17 +1029,31 @@ export function readSession(
916
1029
  if (!isUuidLike(dbSessionId)) return null;
917
1030
 
918
1031
  const messages = parseConversationDb(sessionPath, dbSessionId, workspace);
919
- if (!messages || messages.length === 0) return null;
1032
+ if (messages && messages.length > 0) {
1033
+ return {
1034
+ messages,
1035
+ providerSessionId: dbSessionId,
1036
+ source: 'provider-native',
1037
+ sourcePath: sessionPath,
1038
+ sourceMtimeMs,
1039
+ nativeHistoryCoverage: 'full',
1040
+ workspace,
1041
+ };
1042
+ }
920
1043
 
921
- return {
922
- messages,
923
- providerSessionId: dbSessionId,
924
- source: 'provider-native',
925
- sourcePath: sessionPath,
926
- sourceMtimeMs,
927
- nativeHistoryCoverage: 'full',
928
- workspace,
929
- };
1044
+ // ANTIGRAVITY-COMPLETION-DASHBOARD-GAP: the bound .db yielded nothing this
1045
+ // read — transient (WAL lock / assistant step not yet flushed) or a decode
1046
+ // miss on a future schema. The dispatcher binds STRAIGHT to <uuid>.db once
1047
+ // the session id is known and never re-resolves to a sibling source, so a
1048
+ // null here previously collapsed the whole read to native-unavailable even
1049
+ // when the SAME session's assistant answer was recoverable from the legacy
1050
+ // brain transcript / .pb / history.jsonl. Fall back across those sibling
1051
+ // sources for the same session id before giving up. This is read-only,
1052
+ // scoped to the bound session, and cannot cross-bind to another conversation.
1053
+ const siblingFallback = readAntigravitySiblingFallback(dbSessionId, workspace);
1054
+ if (siblingFallback) return siblingFallback;
1055
+
1056
+ return null;
930
1057
  }
931
1058
 
932
1059
  // ── Case 2b: .pb conversation file (legacy protobuf) ─────────────────────
@@ -950,52 +1077,7 @@ export function readSession(
950
1077
 
951
1078
  // ── Case 3: history.jsonl (user prompts index) ──────────────────────────
952
1079
  if (path.basename(sessionPath) === 'history.jsonl') {
953
- const resolvedSessionId = sessionId || '';
954
- if (!resolvedSessionId || !isUuidLike(resolvedSessionId)) return null;
955
-
956
- const rows = readHistoryRows().filter((r) => r.conversationId === resolvedSessionId);
957
- if (rows.length === 0) return null;
958
-
959
- rows.sort((a, b) => a.receivedAt - b.receivedAt);
960
- const firstWorkspace = workspace || rows.find((r) => r.workspace)?.workspace || '';
961
-
962
- const messages: NativeHistoryMessage[] = [];
963
- if (firstWorkspace) {
964
- messages.push({
965
- ts: new Date(rows[0].receivedAt).toISOString(),
966
- receivedAt: rows[0].receivedAt,
967
- role: 'system',
968
- content: firstWorkspace,
969
- kind: 'session_start',
970
- agent: 'antigravity-cli',
971
- historySessionId: resolvedSessionId,
972
- workspace: firstWorkspace,
973
- });
974
- }
975
-
976
- for (const row of rows) {
977
- const msg: NativeHistoryMessage = {
978
- ts: new Date(row.receivedAt).toISOString(),
979
- receivedAt: row.receivedAt,
980
- role: 'user',
981
- content: row.display,
982
- kind: 'standard',
983
- agent: 'antigravity-cli',
984
- historySessionId: resolvedSessionId,
985
- };
986
- if (row.workspace) msg.workspace = row.workspace;
987
- messages.push(msg);
988
- }
989
-
990
- return {
991
- messages,
992
- providerSessionId: resolvedSessionId,
993
- source: 'provider-native',
994
- sourcePath: sessionPath,
995
- sourceMtimeMs,
996
- nativeHistoryCoverage: 'partial',
997
- partialReason: 'antigravity_cli_history_jsonl_contains_user_prompts_only',
998
- };
1080
+ return readHistoryJsonlSession(sessionId || '', workspace);
999
1081
  }
1000
1082
 
1001
1083
  return null;