codesesh 1.0.4 → 1.0.6

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 (59) hide show
  1. package/README.md +5 -4
  2. package/dist/{chunk-W4PZHL2C.js → chunk-4ND6AT6W.js} +154 -92
  3. package/dist/chunk-4ND6AT6W.js.map +1 -0
  4. package/dist/chunk-4QFNZCBR.js +1271 -0
  5. package/dist/chunk-4QFNZCBR.js.map +1 -0
  6. package/dist/{chunk-MBZ4VV4C.js → chunk-A3MT6L6Z.js} +3 -3
  7. package/dist/chunk-COZSWVCH.js +89 -0
  8. package/dist/chunk-COZSWVCH.js.map +1 -0
  9. package/dist/{chunk-YCUN52HA.js → chunk-L3DDWTYV.js} +81 -115
  10. package/dist/chunk-L3DDWTYV.js.map +1 -0
  11. package/dist/{chunk-BYB77UAJ.js → chunk-XQDYKKRC.js} +139 -80
  12. package/dist/chunk-XQDYKKRC.js.map +1 -0
  13. package/dist/{chunk-3SXCTDD6.js → chunk-YZ6XCSVQ.js} +4 -3
  14. package/dist/{discovery-K3GLISI6.js → discovery-ADSQARBV.js} +11 -5
  15. package/dist/index.js +1538 -1030
  16. package/dist/index.js.map +1 -1
  17. package/dist/project-identity-worker.js +4 -4
  18. package/dist/scan-refresh-worker.js +17 -7
  19. package/dist/scan-refresh-worker.js.map +1 -1
  20. package/dist/search-index-worker.js +16 -8
  21. package/dist/search-index-worker.js.map +1 -1
  22. package/dist/session-detail-worker.js +79 -0
  23. package/dist/session-detail-worker.js.map +1 -0
  24. package/dist/smart-tag-worker.js +3 -3
  25. package/dist/web/assets/CustomTimeWindowDialog-D2bx7uDv.js +1 -0
  26. package/dist/web/assets/InteractiveReceipt-BFpIdno8.js +1 -0
  27. package/dist/web/assets/OverviewScreen-D_KXfiJi.js +1 -0
  28. package/dist/web/assets/{PrismHighlighter-B1a2dPJO.js → PrismHighlighter-BgVkYu_S.js} +1 -1
  29. package/dist/web/assets/Projects-CN44UpuR.js +1 -0
  30. package/dist/web/assets/SearchResultsPanel-CWD01v-a.js +1 -0
  31. package/dist/web/assets/SessionDetail-D8taQ6Tl.js +53 -0
  32. package/dist/web/assets/api-B9lJtVbO.js +1 -0
  33. package/dist/web/assets/index-XpolWMY4.js +1423 -0
  34. package/dist/web/assets/index-xbEEMszv.css +1 -0
  35. package/dist/web/assets/session-indexes-fib48ZKn.js +4 -0
  36. package/dist/web/assets/translate-Dmym1ZDl.js +2 -0
  37. package/dist/web/assets/utils-Bk66u8b3.js +1 -0
  38. package/dist/web/index.html +7 -7
  39. package/package.json +3 -3
  40. package/dist/chunk-BYB77UAJ.js.map +0 -1
  41. package/dist/chunk-G4HRD3AR.js +0 -246
  42. package/dist/chunk-G4HRD3AR.js.map +0 -1
  43. package/dist/chunk-W4PZHL2C.js.map +0 -1
  44. package/dist/chunk-YCUN52HA.js.map +0 -1
  45. package/dist/web/assets/InteractiveReceipt-Dk50TBsH.js +0 -1
  46. package/dist/web/assets/OverviewScreen-5hvQVp4H.js +0 -1
  47. package/dist/web/assets/Projects-Cy_v2yep.js +0 -1
  48. package/dist/web/assets/SearchResultsPanel-DfheEwpz.js +0 -1
  49. package/dist/web/assets/SessionDetail-DRI8R3st.js +0 -53
  50. package/dist/web/assets/api-GP9UCedC.js +0 -1
  51. package/dist/web/assets/contract-xJyW5u7a.js +0 -2
  52. package/dist/web/assets/index-Bd-YkWkZ.css +0 -1
  53. package/dist/web/assets/index-DEjvzumm.js +0 -1410
  54. package/dist/web/assets/panel-ND0J63d3.js +0 -1
  55. package/dist/web/assets/session-indexes-BsgjUoc1.js +0 -4
  56. package/dist/web/assets/utils-C7BqyxxV.js +0 -1
  57. /package/dist/{chunk-MBZ4VV4C.js.map → chunk-A3MT6L6Z.js.map} +0 -0
  58. /package/dist/{chunk-3SXCTDD6.js.map → chunk-YZ6XCSVQ.js.map} +0 -0
  59. /package/dist/{discovery-K3GLISI6.js.map → discovery-ADSQARBV.js.map} +0 -0
@@ -4,16 +4,17 @@ import {
4
4
  computeIdentity,
5
5
  computeIdentityProjection,
6
6
  filterSessionsByProjectScope,
7
+ matchesProjectScope,
7
8
  normalizeProjectDirectory,
8
9
  normalizeProjectScopePath,
9
10
  realFs
10
- } from "./chunk-3SXCTDD6.js";
11
+ } from "./chunk-YZ6XCSVQ.js";
11
12
  import {
12
13
  SessionScanError,
13
14
  createAgentScanFailure,
14
15
  createRegisteredAgents,
15
16
  reportAgentScanFailure
16
- } from "./chunk-YCUN52HA.js";
17
+ } from "./chunk-L3DDWTYV.js";
17
18
  import {
18
19
  SMART_TAG_CLASSIFIER_REVISION,
19
20
  assertIdentifiedSessionHead,
@@ -40,12 +41,12 @@ import {
40
41
  setUserVersion,
41
42
  sortSessionsByActivity,
42
43
  tableExists
43
- } from "./chunk-W4PZHL2C.js";
44
+ } from "./chunk-4ND6AT6W.js";
44
45
 
45
- // ../core/dist/chunk-XGIUX4DD.mjs
46
- var CACHE_SCHEMA_VERSION = 32;
46
+ // ../core/dist/chunk-N4DVJ6NZ.mjs
47
+ var CACHE_SCHEMA_VERSION = 33;
47
48
 
48
- // ../core/dist/chunk-A6L44WG2.mjs
49
+ // ../core/dist/chunk-GNQUMU2M.mjs
49
50
  import { existsSync } from "fs";
50
51
  import { join } from "path";
51
52
  import { homedir } from "os";
@@ -60,6 +61,11 @@ function getCacheConnection(path) {
60
61
  if (cached) return cached;
61
62
  const db = openDb(path);
62
63
  if (!db) return null;
64
+ db.function(
65
+ "codesesh_project_scope_path",
66
+ { deterministic: true },
67
+ (directory) => normalizeProjectScopePath(String(directory ?? ""))
68
+ );
63
69
  const connection = { db, ftsReady: false, publicationStagingCleaned: false };
64
70
  cacheConnections.set(path, connection);
65
71
  return connection;
@@ -862,7 +868,14 @@ function createSessionTables(db) {
862
868
 
863
869
  CREATE INDEX IF NOT EXISTS idx_messages_session
864
870
  ON messages(agent_name, session_id, message_index);
865
-
871
+ `);
872
+ createMessageUsageIndex(db);
873
+ createSessionModelCostTable(db);
874
+ createSessionCostSummaryTable(db);
875
+ createMessageToolTables(db);
876
+ }
877
+ function createMessageUsageIndex(db) {
878
+ db.exec(`
866
879
  CREATE INDEX IF NOT EXISTS idx_messages_usage_time
867
880
  ON messages(
868
881
  CASE
@@ -870,12 +883,14 @@ function createSessionTables(db) {
870
883
  WHEN time_created > 0 THEN time_created
871
884
  END,
872
885
  agent_name,
873
- session_id
886
+ session_id,
887
+ message_index,
888
+ model,
889
+ tokens_json,
890
+ cost,
891
+ cost_source
874
892
  );
875
893
  `);
876
- createSessionModelCostTable(db);
877
- createSessionCostSummaryTable(db);
878
- createMessageToolTables(db);
879
894
  }
880
895
  function createSessionModelCostTable(db) {
881
896
  db.exec(`
@@ -1220,8 +1235,12 @@ function runSearchIndexWrite(db, rebuild, write, transaction = "immediate") {
1220
1235
  let rebuildDurationMs;
1221
1236
  if (rebuild) {
1222
1237
  const rebuildStartedAt = performance.now();
1238
+ getCoreDiagnostics()?.info?.("search_index.fts_rebuild.started");
1223
1239
  rebuildSearchIndex(db);
1224
1240
  rebuildDurationMs = performance.now() - rebuildStartedAt;
1241
+ getCoreDiagnostics()?.info?.("search_index.fts_rebuild.completed", {
1242
+ duration_ms: Math.round(rebuildDurationMs)
1243
+ });
1225
1244
  createSearchTriggers(db);
1226
1245
  }
1227
1246
  return { value, rebuildDurationMs };
@@ -2106,7 +2125,14 @@ function ensureCacheSchema(db, dbPath) {
2106
2125
  { version: 29, migrate: addSessionUsageSummary },
2107
2126
  { version: 30, destructive: true, migrate: dropDerivedSessionSlug },
2108
2127
  { version: 31, migrate: dropDurablePublicationStaging },
2109
- { version: 32, migrate: dropLegacyCacheTables }
2128
+ { version: 32, migrate: dropLegacyCacheTables },
2129
+ {
2130
+ version: 33,
2131
+ migrate(db2) {
2132
+ db2.exec("DROP INDEX IF EXISTS idx_messages_usage_time");
2133
+ createMessageUsageIndex(db2);
2134
+ }
2135
+ }
2110
2136
  ]
2111
2137
  });
2112
2138
  createLatestCacheSchema(db);
@@ -2697,12 +2723,13 @@ var SEARCH_INDEX_COMMIT_CHUNK_SIZE = 64;
2697
2723
  function createSearchIndexLoadTiming() {
2698
2724
  return { calls: 0, reused: 0, getSessionDataMs: 0, materializationMs: 0 };
2699
2725
  }
2700
- function shouldBulkSyncSearchIndex(options, changedCount) {
2726
+ function shouldBulkSyncSearchIndex(db, options, changedCount) {
2701
2727
  if (options.isBulk != null) {
2702
2728
  return options.isBulk;
2703
2729
  }
2704
2730
  const threshold = options.bulkThreshold ?? SEARCH_INDEX_BULK_SYNC_THRESHOLD;
2705
- return threshold > 0 && changedCount >= threshold;
2731
+ if (!(threshold > 0 && changedCount >= threshold)) return false;
2732
+ return options.bulkThreshold != null || db.prepare("SELECT 1 FROM session_documents LIMIT 1").get() === void 0;
2706
2733
  }
2707
2734
  function loadSearchIndexEntry(agentName, change, loadSessionData, detailVersion, failures, timing) {
2708
2735
  const sessionId = change.session.reference.sessionId;
@@ -2966,7 +2993,8 @@ function readSearchIndexPlanInput(db, agentName, request, options) {
2966
2993
  startedAt
2967
2994
  };
2968
2995
  }
2969
- function createSearchIndexPlan(input) {
2996
+ function planSearchIndexWrite(db, agentName, request, options) {
2997
+ const input = readSearchIndexPlanInput(db, agentName, request, options);
2970
2998
  const changes = input.candidates.filter(
2971
2999
  ({ session }) => searchIndexEntryNeedsUpdate(input.state, session, input.options)
2972
3000
  );
@@ -2987,7 +3015,7 @@ function createSearchIndexPlan(input) {
2987
3015
  })
2988
3016
  );
2989
3017
  const changedCount = input.removedSessionIds.length + changes.length;
2990
- const isBulk = shouldBulkSyncSearchIndex(input.options, changedCount);
3018
+ const isBulk = shouldBulkSyncSearchIndex(db, input.options, changedCount);
2991
3019
  return {
2992
3020
  agentName: input.agentName,
2993
3021
  mode: isBulk ? "bulk" : "incremental",
@@ -3000,9 +3028,6 @@ function createSearchIndexPlan(input) {
3000
3028
  startedAt: input.startedAt
3001
3029
  };
3002
3030
  }
3003
- function planSearchIndexWrite(db, agentName, request, options) {
3004
- return createSearchIndexPlan(readSearchIndexPlanInput(db, agentName, request, options));
3005
- }
3006
3031
  function detailVersionForPlan(plan, sessionId) {
3007
3032
  return plan.detailVersionBySessionId.get(sessionId) ?? sessionDetailVersion(null);
3008
3033
  }
@@ -3238,6 +3263,24 @@ function syncSessionSearchIndexChanges(agentName, changes, removedSessionIds, lo
3238
3263
  )
3239
3264
  );
3240
3265
  }
3266
+ function buildSessionQueryScopeFilters(scope) {
3267
+ const clauses = [];
3268
+ const params = [];
3269
+ if (scope?.agents?.length) {
3270
+ clauses.push(`s.agent_name IN (${scope.agents.map(() => "?").join(", ")})`);
3271
+ params.push(...scope.agents);
3272
+ }
3273
+ if (scope?.projectScope) {
3274
+ const project = scope.projectScope;
3275
+ const path = normalizeProjectScopePath(project.path);
3276
+ const directory = "codesesh_project_scope_path(s.directory)";
3277
+ clauses.push(
3278
+ `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR (s.directory <> '' AND (${directory} = ? OR instr(${directory}, ? || '/') = 1 OR instr(?, ${directory} || '/') = 1)))`
3279
+ );
3280
+ params.push(project.identity.kind, project.identity.key, path, path, path);
3281
+ }
3282
+ return { clauses, params };
3283
+ }
3241
3284
  function escapeFtsTerm(value) {
3242
3285
  return value.replaceAll('"', '""');
3243
3286
  }
@@ -3433,9 +3476,8 @@ function sessionMatchesSearchCost(session, options, cost = session.stats.total_c
3433
3476
  }
3434
3477
  return true;
3435
3478
  }
3436
- function buildSessionSearchFilters(options) {
3437
- const clauses = [];
3438
- const params = [];
3479
+ function buildSessionSearchFilters(options, queryScope) {
3480
+ const { clauses, params } = buildSessionQueryScopeFilters(queryScope);
3439
3481
  if (options.agent) {
3440
3482
  clauses.push("s.agent_name = ?");
3441
3483
  params.push(options.agent);
@@ -3449,18 +3491,9 @@ function buildSessionSearchFilters(options) {
3449
3491
  }
3450
3492
  }
3451
3493
  if (options.projectScope) {
3452
- const scopePath = normalizeProjectScopePath(options.projectScope.path).toLowerCase();
3453
- const normalizedDirectory = "REPLACE(LOWER(s.directory), char(92), '/')";
3454
- clauses.push(
3455
- `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR ${normalizedDirectory} = ? OR instr(${normalizedDirectory}, ? || '/') = 1 OR instr(?, ${normalizedDirectory} || '/') = 1)`
3456
- );
3457
- params.push(
3458
- options.projectScope.identity.kind,
3459
- options.projectScope.identity.key,
3460
- scopePath,
3461
- scopePath,
3462
- scopePath
3463
- );
3494
+ const project = buildSessionQueryScopeFilters({ projectScope: options.projectScope });
3495
+ clauses.push(...project.clauses);
3496
+ params.push(...project.params);
3464
3497
  }
3465
3498
  if (options.project) {
3466
3499
  clauses.push(
@@ -3758,14 +3791,14 @@ function rowsToSearchResults(db, rows, textQuery) {
3758
3791
  };
3759
3792
  });
3760
3793
  }
3761
- function searchSessions(query, options = {}) {
3794
+ function searchSessions(query, options = {}, queryScope) {
3762
3795
  const search = mergeSearchQueryOptions(query, options);
3763
3796
  const normalizedQuery = search.text.trim();
3764
3797
  if (!hasCacheStorage()) {
3765
3798
  return [];
3766
3799
  }
3767
3800
  const results = withSearchDb((db) => {
3768
- const filters = buildSessionSearchFilters(search.options);
3801
+ const filters = buildSessionSearchFilters(search.options, queryScope);
3769
3802
  if (!normalizedQuery) {
3770
3803
  const rows2 = db.prepare(
3771
3804
  `
@@ -3808,14 +3841,10 @@ function searchSessions(query, options = {}) {
3808
3841
  }
3809
3842
  function fileActivityFilters(options) {
3810
3843
  const path = options.path ? normalizeFilePathSearch(options.path) : "";
3811
- const scope = options.projectScope;
3812
3844
  return {
3813
3845
  projectKind: options.projectKind ?? null,
3814
3846
  projectKey: options.projectKey ?? null,
3815
3847
  projectLike: options.project ? likePattern(options.project) : null,
3816
- scopeKind: scope?.identity.kind ?? null,
3817
- scopeKey: scope?.identity.key ?? null,
3818
- scopePath: scope ? normalizeProjectScopePath(scope.path).toLowerCase() : null,
3819
3848
  path,
3820
3849
  pathLike: path ? likePattern(path) : null
3821
3850
  };
@@ -3833,10 +3862,9 @@ function fileActivityFromRow(row) {
3833
3862
  latestTime: Number(row.latest_time ?? 0)
3834
3863
  };
3835
3864
  }
3836
- function buildFileActivityWhere(options) {
3865
+ function buildFileActivityWhere(options, queryScope) {
3837
3866
  const filters = fileActivityFilters(options);
3838
- const clauses = [];
3839
- const params = [];
3867
+ const { clauses, params } = buildSessionQueryScopeFilters(queryScope);
3840
3868
  if (options.agent != null) {
3841
3869
  clauses.push("fa.agent_name = ?");
3842
3870
  params.push(options.agent);
@@ -3859,18 +3887,10 @@ function buildFileActivityWhere(options) {
3859
3887
  );
3860
3888
  params.push(filters.projectLike, filters.projectLike, filters.projectLike);
3861
3889
  }
3862
- if (filters.scopeKey != null && filters.scopePath != null) {
3863
- const normalizedDirectory = "REPLACE(LOWER(s.directory), char(92), '/')";
3864
- clauses.push(
3865
- `((s.project_identity_kind = ? AND s.project_identity_key = ?) OR ${normalizedDirectory} = ? OR instr(${normalizedDirectory}, ? || '/') = 1 OR instr(?, ${normalizedDirectory} || '/') = 1)`
3866
- );
3867
- params.push(
3868
- filters.scopeKind,
3869
- filters.scopeKey,
3870
- filters.scopePath,
3871
- filters.scopePath,
3872
- filters.scopePath
3873
- );
3890
+ if (options.projectScope) {
3891
+ const project = buildSessionQueryScopeFilters({ projectScope: options.projectScope });
3892
+ clauses.push(...project.clauses);
3893
+ params.push(...project.params);
3874
3894
  }
3875
3895
  if (filters.pathLike != null) {
3876
3896
  const pathQuery = filePathFtsQuery(filters.path);
@@ -3935,11 +3955,11 @@ var FILE_ACTIVITY_JOIN = `
3935
3955
  AND s.publication_id IS NULL
3936
3956
  `;
3937
3957
  var FILE_ACTIVITY_ORDER = "fa.latest_time DESC, fa.count DESC, fa.path";
3938
- function listFileActivity(options = {}) {
3939
- return queryFileActivity(options);
3958
+ function listFileActivity(options = {}, queryScope) {
3959
+ return queryFileActivity({ options, queryScope });
3940
3960
  }
3941
3961
  function fileActivityWhere(query) {
3942
- const filters = buildFileActivityWhere(query.options);
3962
+ const filters = buildFileActivityWhere(query.options, query.queryScope);
3943
3963
  const sessionFilters = query.sessionSearchOptions ? buildSessionSearchFilters(query.sessionSearchOptions) : { where: "", params: [] };
3944
3964
  const clauses = [
3945
3965
  filters.where.replace(/^WHERE /, ""),
@@ -3982,11 +4002,11 @@ function fileActivitySql(query, where) {
3982
4002
  LIMIT ?
3983
4003
  `;
3984
4004
  }
3985
- function queryFileActivity(options, sessionSearchOptions, onePerSession = false) {
4005
+ function queryFileActivity(query) {
3986
4006
  if (!hasCacheStorage()) {
3987
4007
  return [];
3988
4008
  }
3989
- const query = { options, sessionSearchOptions, onePerSession };
4009
+ const { options } = query;
3990
4010
  const { where, params } = fileActivityWhere(query);
3991
4011
  const sql = fileActivitySql(query, where);
3992
4012
  const queryRows = (db) => db.prepare(sql).all(...params, options.limit ?? 50);
@@ -4010,19 +4030,20 @@ function findFilePathHighlightRanges(path, query) {
4010
4030
  if (index < 0) return [];
4011
4031
  return [{ start: index, end: index + needle.length }];
4012
4032
  }
4013
- function searchFileActivitySessions(query, options = {}) {
4033
+ function searchFileActivitySessions(query, options = {}, queryScope) {
4014
4034
  const search = mergeSearchQueryOptions(query, options);
4015
4035
  const path = normalizeFilePathSearch(search.options.file ?? search.text);
4016
4036
  if (!path) return [];
4017
- const rows = queryFileActivity(
4018
- {
4037
+ const rows = queryFileActivity({
4038
+ options: {
4019
4039
  path,
4020
4040
  kind: search.options.fileKind,
4021
4041
  limit: search.options.limit ?? 50
4022
4042
  },
4023
- search.options,
4024
- true
4025
- );
4043
+ sessionSearchOptions: search.options,
4044
+ onePerSession: true,
4045
+ queryScope
4046
+ });
4026
4047
  return rows.map((row) => {
4027
4048
  const prefix = `${row.kind} `;
4028
4049
  return {
@@ -4037,8 +4058,12 @@ function searchFileActivitySessions(query, options = {}) {
4037
4058
  };
4038
4059
  });
4039
4060
  }
4061
+ function matchesSessionQueryScope(session, scope) {
4062
+ if (scope?.agents?.length && !scope.agents.includes(session.reference.agentName)) return false;
4063
+ return !scope?.projectScope || matchesProjectScope(session, scope.projectScope);
4064
+ }
4040
4065
 
4041
- // ../core/dist/chunk-A6Y7IAJ7.mjs
4066
+ // ../core/dist/chunk-KTS67TNO.mjs
4042
4067
  import { existsSync as existsSync2, rmSync, unlinkSync } from "fs";
4043
4068
  import { availableParallelism } from "os";
4044
4069
  import { Worker } from "worker_threads";
@@ -4340,10 +4365,12 @@ function readCachedSessionMessageRows(db, agentName, sessionId, startIndex) {
4340
4365
  }
4341
4366
  function loadCachedSessionRawEntry(agentName, sessionId) {
4342
4367
  if (!hasCacheStorage()) return null;
4343
- const outcome = withCacheDbReadOnly((db) => {
4344
- const entry = loadCachedSessionEntryBase(db, agentName, sessionId);
4345
- return entry ? { ...entry, messageRows: readCachedSessionMessageRows(db, agentName, sessionId, 0) } : null;
4346
- });
4368
+ const outcome = withCacheDbReadOnly(
4369
+ (db) => db.transaction(() => {
4370
+ const entry = loadCachedSessionEntryBase(db, agentName, sessionId);
4371
+ return entry ? { ...entry, messageRows: readCachedSessionMessageRows(db, agentName, sessionId, 0) } : null;
4372
+ })()
4373
+ );
4347
4374
  return outcome.status === "success" ? outcome.value : null;
4348
4375
  }
4349
4376
  function readCachedSessionMessageDigest(db, agentName, sessionId, messageCount) {
@@ -4926,6 +4953,17 @@ async function selectAgentRefresh(agent, options) {
4926
4953
  }
4927
4954
  return { ...inspection, availabilityDurationMs };
4928
4955
  }
4956
+ async function beginAgentRefresh(agent, options) {
4957
+ const selection = await selectAgentRefresh(agent, options);
4958
+ return {
4959
+ selection,
4960
+ commit: () => {
4961
+ if (selection.kind === "recompute-derived" || selection.kind === "full-scan" || selection.kind === "incremental-scan") {
4962
+ commitAgentRefreshCheck(selection);
4963
+ }
4964
+ }
4965
+ };
4966
+ }
4929
4967
  function commitAgentRefreshCheck(refresh) {
4930
4968
  refresh.source.commitChangeCheck();
4931
4969
  }
@@ -5136,11 +5174,12 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5136
5174
  onProgress
5137
5175
  });
5138
5176
  }
5139
- const refresh = await selectAgentRefresh(agent, {
5177
+ const refreshTransaction = await beginAgentRefresh(agent, {
5140
5178
  initialized: true,
5141
5179
  sinceTimestamp: cached.timestamp,
5142
5180
  cachedSessions: cached.sessions
5143
5181
  });
5182
+ const refresh = refreshTransaction.selection;
5144
5183
  if (refresh.kind === "unavailable") {
5145
5184
  return finalizeAgentScanFailure(
5146
5185
  agent,
@@ -5235,7 +5274,7 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5235
5274
  ),
5236
5275
  onProgress
5237
5276
  });
5238
- if (result2.cachePersistence === "persisted") commitAgentRefreshCheck(refresh);
5277
+ if (result2.cachePersistence === "persisted") refreshTransaction.commit();
5239
5278
  return result2;
5240
5279
  }
5241
5280
  const result = await finalizeAgentScan(agent, cached.sessions, {
@@ -5246,7 +5285,7 @@ async function scanAgentSmart(agent, options, cacheReadState, onProgress) {
5246
5285
  completeness: "complete",
5247
5286
  onProgress
5248
5287
  });
5249
- commitAgentRefreshCheck(refresh);
5288
+ refreshTransaction.commit();
5250
5289
  return result;
5251
5290
  }
5252
5291
  }
@@ -5549,11 +5588,19 @@ function materializeStructuredSessionDetail(context, reference, cachedEntry = lo
5549
5588
  } : null;
5550
5589
  let sourceError;
5551
5590
  if (!data && head) {
5591
+ const sourceStartedAt = performance.now();
5552
5592
  try {
5553
5593
  data = agent.getSessionData(reference.sessionId);
5554
5594
  if (data) freshness = "fresh";
5555
5595
  } catch (error) {
5556
5596
  sourceError = error;
5597
+ } finally {
5598
+ getCoreDiagnostics()?.info?.("session_detail.source_read", {
5599
+ agent: reference.agentName,
5600
+ session_id: reference.sessionId,
5601
+ duration_ms: Math.round(performance.now() - sourceStartedAt),
5602
+ failed: sourceError != null
5603
+ });
5557
5604
  }
5558
5605
  }
5559
5606
  if (!data && cacheState === "stale" && cachedEntry) {
@@ -5603,7 +5650,12 @@ function* serializeCachedMessages(messageRows) {
5603
5650
  yield messageJsonFromCachedRow(messageRow);
5604
5651
  }
5605
5652
  }
5606
- function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5653
+ function materializeSessionDetail(scanResult, reference) {
5654
+ const context = getSessionDetailContext(scanResult, reference);
5655
+ if (!context) return { status: "unknown-agent" };
5656
+ return materializeStructuredSessionDetail(context, reference);
5657
+ }
5658
+ function materializeCachedSessionDetailResponse(scanResult, reference, options = {}) {
5607
5659
  const context = getSessionDetailContext(scanResult, reference);
5608
5660
  if (!context) return { status: "unknown-agent" };
5609
5661
  const currentMeta = context.head ? context.agent.getSessionCacheMeta(reference.sessionId) : void 0;
@@ -5620,16 +5672,14 @@ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5620
5672
  const cachedEntry = cursorRead?.entry ?? null;
5621
5673
  const cacheState = cursorRead?.cacheState ?? "missing";
5622
5674
  if (!cachedEntry || cacheState !== "fresh" || cachedEntry.data.smart_tags == null || cachedEntry.data.smart_tags_classifier_revision !== SMART_TAG_CLASSIFIER_REVISION) {
5623
- const result = materializeStructuredSessionDetail(context, reference, void 0);
5624
- return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5675
+ return null;
5625
5676
  }
5626
5677
  const data = cachedEntry.data;
5627
5678
  assertSessionMatchesReference(data, reference);
5628
5679
  const projectIdentity = getProjectIdentity(data, context.head);
5629
5680
  const stream = cursorRead?.stream;
5630
5681
  if (!stream) {
5631
- const result = materializeStructuredSessionDetail(context, reference, void 0);
5632
- return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5682
+ return null;
5633
5683
  }
5634
5684
  const partsJsonBytes = stream.messageRows.reduce(
5635
5685
  (total, row) => total + Buffer.byteLength(String(row.parts_json)),
@@ -5658,6 +5708,12 @@ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5658
5708
  sentMessageCount: stream.messageRows.length
5659
5709
  };
5660
5710
  }
5711
+ function materializeSessionDetailResponse(scanResult, reference, options = {}) {
5712
+ const cached = materializeCachedSessionDetailResponse(scanResult, reference, options);
5713
+ if (cached) return cached;
5714
+ const result = materializeSessionDetail(scanResult, reference);
5715
+ return result.status === "found" ? { ...result, data: { ...result.data, message_update: "reset" } } : result;
5716
+ }
5661
5717
  function listCachedProjectGroups(sessions) {
5662
5718
  if (sessions) {
5663
5719
  return buildProjectGroups(sessions);
@@ -6017,6 +6073,7 @@ export {
6017
6073
  searchSessions,
6018
6074
  listFileActivity,
6019
6075
  searchFileActivitySessions,
6076
+ matchesSessionQueryScope,
6020
6077
  readCachedSessions,
6021
6078
  loadCachedSessionHeads,
6022
6079
  readAgentCacheInitialization,
@@ -6043,12 +6100,14 @@ export {
6043
6100
  planAgentScan,
6044
6101
  inspectAgentRefresh,
6045
6102
  selectAgentRefresh,
6103
+ beginAgentRefresh,
6046
6104
  commitAgentRefreshCheck,
6047
6105
  scanSessions,
6106
+ materializeCachedSessionDetailResponse,
6048
6107
  materializeSessionDetailResponse,
6049
6108
  listCachedProjectGroups,
6050
6109
  listDashboardCostFacts,
6051
6110
  listModelCostDistribution,
6052
6111
  commitDurableSessionPublication
6053
6112
  };
6054
- //# sourceMappingURL=chunk-BYB77UAJ.js.map
6113
+ //# sourceMappingURL=chunk-XQDYKKRC.js.map