@cortexkit/opencode-magic-context 0.41.0 → 0.41.1

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 (73) hide show
  1. package/dist/config/schema/magic-context.d.ts +15 -0
  2. package/dist/config/schema/magic-context.d.ts.map +1 -1
  3. package/dist/{conflict-warning-hook-xj1r88a7.js → conflict-warning-hook-rf17b6et.js} +3 -3
  4. package/dist/{derive-budgets-3xfyphvk.js → derive-budgets-bb7mrpzs.js} +2 -2
  5. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +12 -16
  6. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  7. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  8. package/dist/features/magic-context/memory/embedding-failure.d.ts +1 -1
  9. package/dist/features/magic-context/memory/embedding-failure.d.ts.map +1 -1
  10. package/dist/features/magic-context/memory/embedding-local.d.ts +12 -2
  11. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  12. package/dist/features/magic-context/memory/embedding-synapse.d.ts +10 -1
  13. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  14. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  15. package/dist/features/magic-context/memory/project-identity.d.ts +4 -0
  16. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  17. package/dist/features/magic-context/memory/transformers-web-entry.d.ts +2 -0
  18. package/dist/features/magic-context/memory/transformers-web-entry.d.ts.map +1 -0
  19. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  20. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  21. package/dist/features/magic-context/search.d.ts +18 -0
  22. package/dist/features/magic-context/search.d.ts.map +1 -1
  23. package/dist/features/magic-context/storage-ops.d.ts +2 -0
  24. package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
  25. package/dist/features/magic-context/storage.d.ts +1 -1
  26. package/dist/features/magic-context/storage.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/boundary-execution.d.ts +3 -0
  28. package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/hook.d.ts +1 -3
  31. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +3 -0
  33. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  35. package/dist/{index-2bykz3bx.js → index-2d4kf2ve.js} +1 -1
  36. package/dist/{index-b4gv9f7g.js → index-4x691bz5.js} +87 -2
  37. package/dist/{index-knna83k0.js → index-9j3tx8hy.js} +1 -1
  38. package/dist/{index-jmwq2wxr.js → index-b9j85d29.js} +1 -1
  39. package/dist/{index-bf799gbq.js → index-d1mxrd3p.js} +0 -1
  40. package/dist/{index-w8rkbhn6.js → index-dh0vfghk.js} +318 -143
  41. package/dist/{index-dmgbar7r.js → index-eq9wr75c.js} +2 -2
  42. package/dist/{index-26ds03jd.js → index-vnz6jvdc.js} +1 -1
  43. package/dist/{index-x9dmzyp5.js → index-z893kjyt.js} +3 -3
  44. package/dist/{index-88za3sz8.js → index-zwjhba2r.js} +3 -3
  45. package/dist/index.js +366 -148
  46. package/dist/{model-resolution-jgrkt0z2.js → model-resolution-6w6wzw18.js} +1 -1
  47. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  48. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  49. package/dist/{recomp-orchestrator-1w4xj6jt.js → recomp-orchestrator-w7xg48e3.js} +6 -6
  50. package/dist/{safe-notification-target-p0c0csxw.js → safe-notification-target-2a8py95v.js} +2 -2
  51. package/dist/{send-session-notification-kn34g7mx.js → send-session-notification-bw7eex6w.js} +3 -3
  52. package/dist/shared/logger.d.ts.map +1 -1
  53. package/dist/shared/model-resolution.d.ts.map +1 -1
  54. package/dist/shared/test-temp-dir.d.ts +40 -0
  55. package/dist/shared/test-temp-dir.d.ts.map +1 -0
  56. package/dist/{storage-meta-session-snbzd26z.js → storage-meta-session-gr4zn7sq.js} +3 -3
  57. package/dist/{task-config-ty08ptc2.js → task-config-gv6s04fp.js} +2 -2
  58. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  59. package/dist/transformers-web.js +24570 -0
  60. package/dist/transformers.node-b1wa0hgx.js +28808 -0
  61. package/package.json +7 -3
  62. package/src/config/index.test.ts +9 -4
  63. package/src/config/schema/magic-context.test.ts +20 -0
  64. package/src/config/schema/magic-context.ts +8 -0
  65. package/src/shared/conflict-detector.test.ts +6 -19
  66. package/src/shared/conflict-fixer.test.ts +5 -8
  67. package/src/shared/logger.test.ts +135 -40
  68. package/src/shared/logger.ts +115 -2
  69. package/src/shared/model-resolution.test.ts +4 -6
  70. package/src/shared/model-resolution.ts +0 -1
  71. package/src/shared/test-temp-dir.test.ts +57 -0
  72. package/src/shared/test-temp-dir.ts +165 -0
  73. /package/dist/{index-rpgg35ms.js → index-8sseka65.js} +0 -0
package/dist/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ import {
2
+ ANNOUNCEMENT_FEATURES,
3
+ ANNOUNCEMENT_FOOTER,
4
+ ANNOUNCEMENT_VERSION,
5
+ compareSemverCore,
6
+ isValidSemver,
7
+ markAnnouncementSeen,
8
+ shouldShowAnnouncement
9
+ } from "./index-dmvy29z0.js";
1
10
  import {
2
11
  CANONICAL_DREAM_TASKS,
3
12
  buildDreamTaskRuntimeConfigs,
@@ -8,12 +17,12 @@ import {
8
17
  leaseKindFor,
9
18
  processedDreamTaskItems,
10
19
  userMemoryCollectionEnabled
11
- } from "./index-knna83k0.js";
20
+ } from "./index-9j3tx8hy.js";
12
21
  import {
13
22
  resolveHistorianAgentOverrides,
14
23
  resolveHistorianModel,
15
24
  resolveOpenCodeAgentOverrides
16
- } from "./index-bf799gbq.js";
25
+ } from "./index-d1mxrd3p.js";
17
26
  import {
18
27
  AGE_RECLAIM_MIN_TOKENS,
19
28
  AdmissionClass,
@@ -139,6 +148,7 @@ import {
139
148
  demoteTrailingBlankKeepDecisions,
140
149
  deriveTagLoadFloor,
141
150
  detectOverflow,
151
+ directoryHasGitMetadata,
142
152
  dismissNote,
143
153
  dismissUserMemory,
144
154
  drainAuthority,
@@ -232,6 +242,7 @@ import {
232
242
  getOverflowState,
233
243
  getPendingCompactionMarkerState,
234
244
  getPendingOps,
245
+ getPendingOpsCount,
235
246
  getPendingSmartNotes,
236
247
  getPersistedCompactionMarkerState,
237
248
  getPersistedNoteNudge,
@@ -494,7 +505,7 @@ import {
494
505
  verificationFileExists,
495
506
  withContentLanguageDirective,
496
507
  withRawSessionMessageCache
497
- } from "./index-w8rkbhn6.js";
508
+ } from "./index-dh0vfghk.js";
498
509
  import {
499
510
  deriveHistorianChunkTokens,
500
511
  deriveTriggerBudget,
@@ -509,7 +520,7 @@ import {
509
520
  setStoragePrivatePermissionEnforcement,
510
521
  setWindowOverlayPath,
511
522
  shouldEnforcePrivateStoragePermissions
512
- } from "./index-2bykz3bx.js";
523
+ } from "./index-2d4kf2ve.js";
513
524
  import {
514
525
  clearIgnoredMessages,
515
526
  describeError,
@@ -517,7 +528,7 @@ import {
517
528
  getErrorMessage,
518
529
  sendIgnoredMessage,
519
530
  sendUserPrompt
520
- } from "./index-88za3sz8.js";
531
+ } from "./index-zwjhba2r.js";
521
532
  import {
522
533
  advanceToolReclaimWatermark,
523
534
  clearSession,
@@ -526,7 +537,7 @@ import {
526
537
  markSessionCleanupPending,
527
538
  retryPendingSessionCleanups,
528
539
  updateSessionMeta
529
- } from "./index-x9dmzyp5.js";
540
+ } from "./index-z893kjyt.js";
530
541
  import {
531
542
  modelRefLookupOrder,
532
543
  piModelRefToCanonical
@@ -539,28 +550,19 @@ import {
539
550
  isMidTurn,
540
551
  openCodeDbExists,
541
552
  withReadOnlySessionDb
542
- } from "./index-jmwq2wxr.js";
553
+ } from "./index-b9j85d29.js";
543
554
  import {
544
555
  cleanupConflictWarnings,
545
556
  detectConflicts,
546
557
  resolveCompactionForBoot,
547
558
  sendConflictWarning
548
- } from "./index-dmgbar7r.js";
559
+ } from "./index-eq9wr75c.js";
549
560
  import {
550
561
  detectConfigFile,
551
562
  isPrototypePollutionKey,
552
563
  parseJsonc,
553
564
  stripJsonComments
554
565
  } from "./index-8mtsfhyg.js";
555
- import {
556
- ANNOUNCEMENT_FEATURES,
557
- ANNOUNCEMENT_FOOTER,
558
- ANNOUNCEMENT_VERSION,
559
- compareSemverCore,
560
- isValidSemver,
561
- markAnnouncementSeen,
562
- shouldShowAnnouncement
563
- } from "./index-dmvy29z0.js";
564
566
  import {
565
567
  acknowledgeNotifications,
566
568
  drainNotifications,
@@ -568,13 +570,13 @@ import {
568
570
  pushNotification,
569
571
  registerNotificationSink
570
572
  } from "./index-d62ypazr.js";
571
- import"./index-26ds03jd.js";
573
+ import"./index-vnz6jvdc.js";
572
574
  import {
573
575
  getLoggerDiagnostics,
574
576
  hasShareabilitySensitiveText,
575
577
  log,
576
578
  sessionLog
577
- } from "./index-b4gv9f7g.js";
579
+ } from "./index-4x691bz5.js";
578
580
  import {
579
581
  getDataDir,
580
582
  getHarness,
@@ -16680,7 +16682,7 @@ function getAsyncModule() {
16680
16682
  asyncModulePromise ??= (async () => {
16681
16683
  const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await Promise.all([
16682
16684
  import("./index-rgdqj8nj.js").then((m)=>__toESM(m.default,1)),
16683
- import("./index-rpgg35ms.js")
16685
+ import("./index-8sseka65.js")
16684
16686
  ]);
16685
16687
  return newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
16686
16688
  })();
@@ -21940,6 +21942,7 @@ function fallbackConfig(config, provider) {
21940
21942
  return {
21941
21943
  provider: "local",
21942
21944
  model: model || DEFAULT_LOCAL_EMBEDDING_MODEL,
21945
+ local_runtime: raw.local_runtime === "native" || raw.local_runtime === "wasm" ? raw.local_runtime : "auto",
21943
21946
  ...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
21944
21947
  };
21945
21948
  }
@@ -23253,8 +23256,16 @@ var GIT_COMMIT_SOURCE_BOOST = 1.2;
23253
23256
  var PRIMER_SOURCE_BOOST = 1.25;
23254
23257
  var messageSearchStatements = new WeakMap;
23255
23258
  var messageSearchStatementsWithCutoff = new WeakMap;
23259
+ var messageSearchDiagnosticStatements = new WeakMap;
23256
23260
  var batchedMessageSearchStatements = new WeakMap;
23257
23261
  var batchedFtsCountStatements = new WeakMap;
23262
+ function createUnifiedSearchDiagnostics() {
23263
+ return {
23264
+ suppressedVisibleMemoryIds: [],
23265
+ suppressedLiveMessageMatches: 0,
23266
+ gitCommitUnavailable: null
23267
+ };
23268
+ }
23258
23269
  function normalizeLimit(limit) {
23259
23270
  if (typeof limit !== "number" || !Number.isFinite(limit)) {
23260
23271
  return DEFAULT_UNIFIED_SEARCH_LIMIT;
@@ -23345,6 +23356,51 @@ function getMessageSearchStatementWithCutoff(db) {
23345
23356
  }
23346
23357
  return stmt;
23347
23358
  }
23359
+ function getMessageSearchDiagnosticStatement(db) {
23360
+ let stmt = messageSearchDiagnosticStatements.get(db);
23361
+ if (!stmt) {
23362
+ stmt = db.prepare(`
23363
+ WITH matches AS MATERIALIZED (
23364
+ SELECT
23365
+ message_ordinal AS messageOrdinal,
23366
+ message_id AS messageId,
23367
+ role,
23368
+ content,
23369
+ CAST(message_ordinal AS INTEGER) AS ordinalValue,
23370
+ bm25(message_history_fts) AS ftsRank
23371
+ FROM message_history_fts
23372
+ WHERE session_id = ? AND message_history_fts MATCH ?
23373
+ ),
23374
+ eligible AS (
23375
+ SELECT * FROM matches
23376
+ WHERE ordinalValue <= ?
23377
+ ORDER BY ftsRank, ordinalValue ASC
23378
+ LIMIT ?
23379
+ ),
23380
+ summary AS (
23381
+ SELECT COUNT(*) AS suppressedCount
23382
+ FROM matches
23383
+ WHERE ordinalValue > ?
23384
+ )
23385
+ SELECT
23386
+ eligible.messageOrdinal,
23387
+ eligible.messageId,
23388
+ eligible.role,
23389
+ eligible.content,
23390
+ eligible.ftsRank,
23391
+ summary.suppressedCount,
23392
+ 0 AS summaryOnly
23393
+ FROM eligible CROSS JOIN summary
23394
+ UNION ALL
23395
+ SELECT NULL, NULL, NULL, NULL, NULL, summary.suppressedCount, 1
23396
+ FROM summary
23397
+ WHERE NOT EXISTS (SELECT 1 FROM eligible)
23398
+ ORDER BY summaryOnly ASC, ftsRank ASC, messageOrdinal ASC
23399
+ `);
23400
+ messageSearchDiagnosticStatements.set(db, stmt);
23401
+ }
23402
+ return stmt;
23403
+ }
23348
23404
  function getBatchedFtsCountStatement(db, queryCount, cutoff) {
23349
23405
  let statements = batchedFtsCountStatements.get(db);
23350
23406
  if (!statements) {
@@ -23485,10 +23541,8 @@ function mergeMemoryResults(args) {
23485
23541
  const memoryById = new Map(args.memories.map((memory) => [memory.id, memory]));
23486
23542
  const candidateIds = new Set([...args.semanticScores.keys(), ...args.ftsScores.keys()]);
23487
23543
  const results = [];
23544
+ const suppressedVisibleIds = [];
23488
23545
  for (const id of candidateIds) {
23489
- if (args.visibleMemoryIds?.has(id)) {
23490
- continue;
23491
- }
23492
23546
  const memory = memoryById.get(id);
23493
23547
  if (!memory) {
23494
23548
  continue;
@@ -23510,6 +23564,10 @@ function mergeMemoryResults(args) {
23510
23564
  if (score <= 0) {
23511
23565
  continue;
23512
23566
  }
23567
+ if (args.visibleMemoryIds?.has(id)) {
23568
+ suppressedVisibleIds.push(id);
23569
+ continue;
23570
+ }
23513
23571
  results.push({
23514
23572
  source: "memory",
23515
23573
  content: previewText(memory.content),
@@ -23520,20 +23578,23 @@ function mergeMemoryResults(args) {
23520
23578
  sourceName: args.sourceNameByMemoryId?.get(memory.id)
23521
23579
  });
23522
23580
  }
23523
- return results.sort((left, right) => {
23524
- if (right.score !== left.score) {
23525
- return right.score - left.score;
23526
- }
23527
- return left.memoryId - right.memoryId;
23528
- }).slice(0, args.limit);
23581
+ return {
23582
+ results: results.sort((left, right) => {
23583
+ if (right.score !== left.score) {
23584
+ return right.score - left.score;
23585
+ }
23586
+ return left.memoryId - right.memoryId;
23587
+ }).slice(0, args.limit),
23588
+ suppressedVisibleIds: suppressedVisibleIds.sort((left, right) => left - right)
23589
+ };
23529
23590
  }
23530
23591
  async function searchMemories(args) {
23531
23592
  if (!args.memoryEnabled) {
23532
- return [];
23593
+ return { results: [], suppressedVisibleIds: [] };
23533
23594
  }
23534
23595
  const memories = args.workspace?.isWorkspaced ? getMemoriesByProjects(args.db, args.workspace.expandedIdentities, ["active", "permanent"], Date.now(), args.workspace.ownIdentities, args.workspace.shareCategories) : getMemoriesByProject(args.db, args.projectPath);
23535
23596
  if (memories.length === 0) {
23536
- return [];
23597
+ return { results: [], suppressedVisibleIds: [] };
23537
23598
  }
23538
23599
  const ftsMatches = getFtsMatches({
23539
23600
  db: args.db,
@@ -23610,6 +23671,21 @@ function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
23610
23671
  }
23611
23672
  return result;
23612
23673
  }
23674
+ function runMessageFtsQueryWithDiagnostics(args) {
23675
+ if (args.ftsQuery.length === 0)
23676
+ return { rows: [], suppressedCount: 0 };
23677
+ const rawRows = getMessageSearchDiagnosticStatement(args.db).all(args.sessionId, args.ftsQuery, args.cutoff, args.fetchLimit, args.cutoff).map((row) => row);
23678
+ const suppressedCount = rawRows[0]?.suppressedCount ?? 0;
23679
+ const rows = [];
23680
+ for (const row of rawRows) {
23681
+ if (row.summaryOnly === 1)
23682
+ continue;
23683
+ const normalized = normalizeMessageSearchRow(row, args.cutoff);
23684
+ if (normalized)
23685
+ rows.push(normalized);
23686
+ }
23687
+ return { rows, suppressedCount };
23688
+ }
23613
23689
  function getBatchedMessageSearchStatement(db, queryCount, cutoff) {
23614
23690
  let statements = batchedMessageSearchStatements.get(db);
23615
23691
  if (!statements) {
@@ -23676,7 +23752,20 @@ function searchMessages(args) {
23676
23752
  const baseQuery = sanitizeFtsQuery(args.query.trim());
23677
23753
  const probes = args.probes ?? [];
23678
23754
  if (probes.length === 0) {
23679
- const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
23755
+ const outcome = args.diagnostics && cutoff !== null ? runMessageFtsQueryWithDiagnostics({
23756
+ db: args.db,
23757
+ sessionId: args.sessionId,
23758
+ ftsQuery: baseQuery,
23759
+ fetchLimit,
23760
+ cutoff
23761
+ }) : {
23762
+ rows: runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff),
23763
+ suppressedCount: 0
23764
+ };
23765
+ if (args.diagnostics) {
23766
+ args.diagnostics.suppressedLiveMessageMatches = outcome.suppressedCount;
23767
+ }
23768
+ const filtered = outcome.rows.slice(0, args.limit);
23680
23769
  return filtered.map((row, rank) => ({
23681
23770
  source: "message",
23682
23771
  content: previewText(row.content),
@@ -23689,8 +23778,19 @@ function searchMessages(args) {
23689
23778
  const sanitizedProbes = probes.map((probe) => ({ probe, query: sanitizeFtsQuery(probe) })).filter((entry) => entry.query.length > 0);
23690
23779
  const corpusSize = getIndexedMessageCorpusSize(args.db, args.sessionId, cutoff);
23691
23780
  const probeCounts = countSessionFtsMatchesBatch(args.db, args.sessionId, sanitizedProbes.map((entry) => entry.query), cutoff);
23781
+ const collectBaseDiagnostics = args.diagnostics !== undefined && cutoff !== null;
23782
+ const baseOutcome = collectBaseDiagnostics && baseQuery.length > 0 ? runMessageFtsQueryWithDiagnostics({
23783
+ db: args.db,
23784
+ sessionId: args.sessionId,
23785
+ ftsQuery: baseQuery,
23786
+ fetchLimit,
23787
+ cutoff
23788
+ }) : null;
23789
+ if (args.diagnostics) {
23790
+ args.diagnostics.suppressedLiveMessageMatches = baseOutcome?.suppressedCount ?? 0;
23791
+ }
23692
23792
  const searchQueries = [
23693
- ...baseQuery.length > 0 ? [baseQuery] : [],
23793
+ ...!collectBaseDiagnostics && baseQuery.length > 0 ? [baseQuery] : [],
23694
23794
  ...sanitizedProbes.map((entry) => entry.query)
23695
23795
  ];
23696
23796
  const rowsByQuery = runMessageFtsQueriesBatch(args.db, args.sessionId, searchQueries, fetchLimit, cutoff);
@@ -23698,10 +23798,11 @@ function searchMessages(args) {
23698
23798
  let queryIndex = 0;
23699
23799
  if (baseQuery.length > 0) {
23700
23800
  queryLists.push({
23701
- rows: rowsByQuery[queryIndex] ?? [],
23801
+ rows: baseOutcome?.rows ?? rowsByQuery[queryIndex] ?? [],
23702
23802
  weight: 1
23703
23803
  });
23704
- queryIndex += 1;
23804
+ if (!collectBaseDiagnostics)
23805
+ queryIndex += 1;
23705
23806
  }
23706
23807
  const probeWeights = new Map;
23707
23808
  sanitizedProbes.forEach((entry, probeIndex) => {
@@ -24088,6 +24189,9 @@ function memoriesToIdLookupResults(args) {
24088
24189
  }));
24089
24190
  }
24090
24191
  function resolveMemoriesByIdsForSearch(args) {
24192
+ if (args.diagnostics) {
24193
+ args.diagnostics.suppressedVisibleMemoryIds = [];
24194
+ }
24091
24195
  if (args.ids.length === 0) {
24092
24196
  return null;
24093
24197
  }
@@ -24098,16 +24202,22 @@ function resolveMemoriesByIdsForSearch(args) {
24098
24202
  }
24099
24203
  const memoriesById = new Map(fetched.map((memory) => [memory.id, memory]));
24100
24204
  const ordered = [];
24205
+ const suppressedVisibleIds = new Set;
24101
24206
  for (const id of args.ids) {
24102
24207
  const memory = memoriesById.get(id);
24103
24208
  if (!memory)
24104
24209
  continue;
24105
- if (args.visibleMemoryIds?.has(id))
24210
+ if (args.visibleMemoryIds?.has(id)) {
24211
+ suppressedVisibleIds.add(id);
24106
24212
  continue;
24213
+ }
24107
24214
  ordered.push(memory);
24108
24215
  if (ordered.length >= args.limit)
24109
24216
  break;
24110
24217
  }
24218
+ if (args.diagnostics) {
24219
+ args.diagnostics.suppressedVisibleMemoryIds = [...suppressedVisibleIds].sort((left, right) => left - right);
24220
+ }
24111
24221
  if (ordered.length === 0) {
24112
24222
  return null;
24113
24223
  }
@@ -24129,6 +24239,11 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24129
24239
  }
24130
24240
  const limit = normalizeLimit(options.limit);
24131
24241
  const tierLimit = Math.max(limit * 3, DEFAULT_UNIFIED_SEARCH_LIMIT);
24242
+ if (options.diagnostics) {
24243
+ options.diagnostics.suppressedVisibleMemoryIds = [];
24244
+ options.diagnostics.suppressedLiveMessageMatches = 0;
24245
+ options.diagnostics.gitCommitUnavailable = null;
24246
+ }
24132
24247
  const embeddingEnabled = options.embeddingEnabled ?? true;
24133
24248
  const embedQuery = options.embedQuery ?? embedText;
24134
24249
  const isEmbeddingRuntimeEnabled = options.isEmbeddingRuntimeEnabled ?? isEmbeddingEnabled;
@@ -24138,6 +24253,9 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24138
24253
  const runMemory = activeSources.has("memory") && memoryFeatureEnabled;
24139
24254
  const runMessages = activeSources.has("message");
24140
24255
  const runGitCommits = activeSources.has("git_commit") && gitCommitsEnabled;
24256
+ if (options.diagnostics && activeSources.has("git_commit") && options.gitRepositoryAvailable === false) {
24257
+ options.diagnostics.gitCommitUnavailable = "no_git_repository";
24258
+ }
24141
24259
  const runPrimers = activeSources.has("primer") && memoryFeatureEnabled;
24142
24260
  const runNotes = activeSources.has("note");
24143
24261
  const runCompartmentChunks = runMessages && memoryFeatureEnabled && embeddingEnabled;
@@ -24154,7 +24272,8 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24154
24272
  query: trimmedQuery,
24155
24273
  limit: tierLimit,
24156
24274
  maxOrdinal: options.maxMessageOrdinal,
24157
- probes: messageProbes
24275
+ probes: messageProbes,
24276
+ diagnostics: options.diagnostics
24158
24277
  }) : [];
24159
24278
  const capturedQuery = await queryEmbeddingPromise;
24160
24279
  const embeddingSnapshot = getProjectEmbeddingSnapshot(projectPath);
@@ -24178,7 +24297,7 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24178
24297
  compartments: compartmentResults,
24179
24298
  limit: tierLimit
24180
24299
  });
24181
- const [memoryResults, gitCommitResults, primerResults, noteResults] = await Promise.all([
24300
+ const [memoryOutcome, gitCommitResults, primerResults, noteResults] = await Promise.all([
24182
24301
  runMemory ? searchMemories({
24183
24302
  db,
24184
24303
  projectPath,
@@ -24189,7 +24308,10 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24189
24308
  queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
24190
24309
  workspace,
24191
24310
  visibleMemoryIds: options.visibleMemoryIds
24192
- }) : Promise.resolve([]),
24311
+ }) : Promise.resolve({
24312
+ results: [],
24313
+ suppressedVisibleIds: []
24314
+ }),
24193
24315
  runGitCommits ? Promise.resolve(searchGitCommits({
24194
24316
  db,
24195
24317
  projectPath,
@@ -24215,8 +24337,11 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24215
24337
  probes: messageProbes
24216
24338
  })) : Promise.resolve([])
24217
24339
  ]);
24340
+ if (options.diagnostics) {
24341
+ options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
24342
+ }
24218
24343
  const results = [
24219
- ...memoryResults,
24344
+ ...memoryOutcome.results,
24220
24345
  ...primerResults,
24221
24346
  ...messageLikeResults,
24222
24347
  ...gitCommitResults,
@@ -24254,6 +24379,123 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
24254
24379
  }
24255
24380
  return results;
24256
24381
  }
24382
+ var SEARCH_NOTE_EXPAND_HINT = "Use ctx_expand(start=N-10, end=N) around any note @msg anchor above to read the surrounding conversation context.";
24383
+ function formatSearchAge(timestampMs) {
24384
+ const ageMs = Date.now() - timestampMs;
24385
+ if (ageMs < 0)
24386
+ return "future";
24387
+ const days = Math.floor(ageMs / (24 * 60 * 60 * 1000));
24388
+ if (days <= 0)
24389
+ return "today";
24390
+ if (days === 1)
24391
+ return "1d ago";
24392
+ if (days < 30)
24393
+ return `${days}d ago`;
24394
+ const months = Math.floor(days / 30);
24395
+ if (months === 1)
24396
+ return "1mo ago";
24397
+ if (months < 12)
24398
+ return `${months}mo ago`;
24399
+ const years = Math.floor(days / 365);
24400
+ return years === 1 ? "1y ago" : `${years}y ago`;
24401
+ }
24402
+ function formatUnifiedSearchResult(result, index, currentSessionId) {
24403
+ if (result.source === "memory") {
24404
+ const source = result.sourceName ? ` source=${result.sourceName}` : "";
24405
+ return [
24406
+ `[${index}] [memory] score=${result.score.toFixed(2)} id=${result.memoryId} category=${result.category}${source} match=${result.matchType}`,
24407
+ result.content
24408
+ ].join(`
24409
+ `);
24410
+ }
24411
+ if (result.source === "git_commit") {
24412
+ return [
24413
+ `[${index}] [git_commit] score=${result.score.toFixed(2)} sha=${result.shortSha} ${formatSearchAge(result.committedAtMs)} match=${result.matchType}`,
24414
+ result.content
24415
+ ].join(`
24416
+ `);
24417
+ }
24418
+ if (result.source === "primer") {
24419
+ return [
24420
+ `[${index}] [primer] score=${result.score.toFixed(2)} id=${result.primerId} support=${result.support} match=${result.matchType}`,
24421
+ result.content
24422
+ ].join(`
24423
+ `);
24424
+ }
24425
+ if (result.source === "note") {
24426
+ const anchor = result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId ? ` @msg ${result.anchorOrdinal}` : "";
24427
+ return [
24428
+ `[${index}] [note] score=${result.score.toFixed(2)} id=#${result.noteId} status=${result.status} ${formatSearchAge(result.createdAt)}${anchor}`,
24429
+ result.content
24430
+ ].join(`
24431
+ `);
24432
+ }
24433
+ if (result.source === "compartment") {
24434
+ return [
24435
+ `[${index}] [message] score=${result.score.toFixed(2)} compartment_id=${result.compartmentId} range=${result.startOrdinal}-${result.endOrdinal} match=${result.matchType} title=${result.title}`,
24436
+ result.snippet ? `Snippet: ${result.snippet}` : result.content
24437
+ ].join(`
24438
+ `);
24439
+ }
24440
+ const expandStart = Math.max(1, result.messageOrdinal - 3);
24441
+ const expandEnd = result.messageOrdinal + 3;
24442
+ return [
24443
+ `[${index}] [message] score=${result.score.toFixed(2)} ordinal=${result.messageOrdinal} range=${expandStart}-${expandEnd} role=${result.role}`,
24444
+ result.content
24445
+ ].join(`
24446
+ `);
24447
+ }
24448
+ function formatSearchDiagnosticLines(results, diagnostics) {
24449
+ if (!diagnostics)
24450
+ return [];
24451
+ const lines = [];
24452
+ const visibleIds = [...diagnostics.suppressedVisibleMemoryIds].sort((left, right) => left - right);
24453
+ if (visibleIds.length > 0) {
24454
+ const count = visibleIds.length;
24455
+ const noun = count === 1 ? "match" : "matches";
24456
+ const ids = visibleIds.join(", ");
24457
+ if (results.some((result) => result.source === "memory")) {
24458
+ lines.push(`Memories: ${count} additional ${noun} suppressed because ${count === 1 ? "it is" : "they are"} already visible in your project-memory block (ids ${ids}).`);
24459
+ } else {
24460
+ lines.push(`Memories: ${count} ${noun} found, all already visible in your project-memory block (ids ${ids}).`);
24461
+ }
24462
+ }
24463
+ if (diagnostics.suppressedLiveMessageMatches > 0) {
24464
+ const count = diagnostics.suppressedLiveMessageMatches;
24465
+ lines.push(`Message history: ${count} raw-message ${count === 1 ? "match is" : "matches are"} newer than the last compartment boundary (already in your context).`);
24466
+ }
24467
+ if (diagnostics.gitCommitUnavailable === "no_git_repository") {
24468
+ lines.push("Git commits: no git repository — commit search unavailable for this project.");
24469
+ }
24470
+ return lines;
24471
+ }
24472
+ function formatSearchResults(query, results, currentSessionId, diagnostics) {
24473
+ const diagnosticLines = formatSearchDiagnosticLines(results, diagnostics);
24474
+ if (results.length === 0) {
24475
+ if (diagnosticLines.length > 0) {
24476
+ return `No hidden results found for "${query}".
24477
+
24478
+ ${diagnosticLines.join(`
24479
+ `)}`;
24480
+ }
24481
+ return `No results found for "${query}" across notes, memories, primers, git commits, or message history.`;
24482
+ }
24483
+ const bodyParts = results.map((result, index) => formatUnifiedSearchResult(result, index + 1, currentSessionId));
24484
+ if (diagnosticLines.length > 0)
24485
+ bodyParts.push(diagnosticLines.join(`
24486
+ `));
24487
+ if (results.some((result) => result.source === "message" || result.source === "compartment")) {
24488
+ bodyParts.push("Use ctx_expand(start, end) with the range from any message result above to read the full conversation context.");
24489
+ }
24490
+ if (results.some((result) => result.source === "note" && result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId)) {
24491
+ bodyParts.push(SEARCH_NOTE_EXPAND_HINT);
24492
+ }
24493
+ return `Found ${results.length} result${results.length === 1 ? "" : "s"} for "${query}":
24494
+
24495
+ ${bodyParts.join(`
24496
+
24497
+ `)}`;
24498
+ }
24257
24499
 
24258
24500
  // src/hooks/magic-context/caveman.ts
24259
24501
  var PRESERVATION_PATTERNS = [
@@ -25602,7 +25844,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
25602
25844
  const forceMaterializationPercentage = escalationBands(executeThresholdPercentage).forceMaterializationPercentage;
25603
25845
  if (usage.percentage >= forceMaterializationPercentage) {
25604
25846
  if (projectedPostDropPercentage !== null && projectedPostDropPercentage <= relativePostDropTarget) {
25605
- sessionLog(sessionId, `compartment trigger: skipping force band ${forceMaterializationPercentage}% because projected post-drop usage is ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%)`);
25847
+ sessionLog(sessionId, `historian redundancy skip: summarizer not needed this pass — force band is ${forceMaterializationPercentage}%; queued/automatic drops are projected to reclaim to ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%) on the next eligible execute pass`);
25606
25848
  return { shouldFire: false };
25607
25849
  }
25608
25850
  sessionLog(sessionId, `compartment trigger: force-firing at ${usage.percentage.toFixed(1)}% (projected post-drop ${formatProjectedPostDropPercentage(projectedPostDropPercentage)})`);
@@ -25663,7 +25905,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
25663
25905
  return { shouldFire: false };
25664
25906
  }
25665
25907
  if (projectedPostDropPercentage !== null && projectedPostDropPercentage <= relativePostDropTarget) {
25666
- sessionLog(sessionId, `compartment trigger: not firing at ${usage.percentage.toFixed(1)}% because projected post-drop usage is ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%)`);
25908
+ sessionLog(sessionId, `historian redundancy skip: summarizer not needed this pass — usage is ${usage.percentage.toFixed(1)}%; queued/automatic drops are projected to reclaim to ${projectedPostDropPercentage.toFixed(1)}% (target ${relativePostDropTarget.toFixed(1)}%) on the next eligible execute pass`);
25667
25909
  return { shouldFire: false };
25668
25910
  }
25669
25911
  if (!tailInfo.hasProtectedEligibleHead || !tailInfo.isMeaningful) {
@@ -27565,9 +27807,9 @@ function registerRpcHandlers(rpcServer, args) {
27565
27807
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
27566
27808
  });
27567
27809
  const buildManagedCtx = async (db) => {
27568
- const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-3xfyphvk.js");
27569
- const { resolveHistorianModel: resolveHistorianModel2 } = await import("./model-resolution-jgrkt0z2.js");
27570
- const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-ty08ptc2.js");
27810
+ const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-bb7mrpzs.js");
27811
+ const { resolveHistorianModel: resolveHistorianModel2 } = await import("./model-resolution-6w6wzw18.js");
27812
+ const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-gv6s04fp.js");
27571
27813
  const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
27572
27814
  const historianModel = resolveHistorianModel2(config, "opencode");
27573
27815
  return {
@@ -27598,8 +27840,8 @@ function registerRpcHandlers(rpcServer, args) {
27598
27840
  const db = getDb();
27599
27841
  if (!db)
27600
27842
  return { ok: false, error: "db unavailable" };
27601
- const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-1w4xj6jt.js");
27602
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-kn34g7mx.js");
27843
+ const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-w7xg48e3.js");
27844
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
27603
27845
  log(`[rpc] recomp requested for session ${sessionId}`);
27604
27846
  const ctx = await buildManagedCtx(db);
27605
27847
  runManagedRecomp2(ctx, sessionId).then((message) => {
@@ -27617,8 +27859,8 @@ function registerRpcHandlers(rpcServer, args) {
27617
27859
  const db = getDb();
27618
27860
  if (!db)
27619
27861
  return { ok: false, error: "db unavailable" };
27620
- const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-1w4xj6jt.js");
27621
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-kn34g7mx.js");
27862
+ const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-w7xg48e3.js");
27863
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
27622
27864
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
27623
27865
  const ctx = await buildManagedCtx(db);
27624
27866
  runManagedUpgrade2(ctx, sessionId).then((message) => {
@@ -27634,7 +27876,7 @@ function registerRpcHandlers(rpcServer, args) {
27634
27876
  if (!db)
27635
27877
  return { ok: false, error: "db unavailable" };
27636
27878
  try {
27637
- const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-snbzd26z.js");
27879
+ const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-gr4zn7sq.js");
27638
27880
  updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
27639
27881
  return { ok: true };
27640
27882
  } catch (error) {
@@ -28261,15 +28503,31 @@ function detectMidTurnBypassReason(input) {
28261
28503
  }
28262
28504
  function applyMidTurnDeferral(input) {
28263
28505
  if (input.base === "defer") {
28264
- return { midTurnAdjustedSchedulerDecision: "defer", sideEffect: "none" };
28506
+ return {
28507
+ midTurnAdjustedSchedulerDecision: "defer",
28508
+ sideEffect: "none",
28509
+ deferReason: "scheduler_defer"
28510
+ };
28265
28511
  }
28266
28512
  if (input.bypassReason !== "none") {
28267
- return { midTurnAdjustedSchedulerDecision: "execute", sideEffect: "none" };
28513
+ return {
28514
+ midTurnAdjustedSchedulerDecision: "execute",
28515
+ sideEffect: "none",
28516
+ deferReason: null
28517
+ };
28268
28518
  }
28269
28519
  if (input.midTurn) {
28270
- return { midTurnAdjustedSchedulerDecision: "defer", sideEffect: "set-flag" };
28520
+ return {
28521
+ midTurnAdjustedSchedulerDecision: "defer",
28522
+ sideEffect: "set-flag",
28523
+ deferReason: "mid_turn_boundary"
28524
+ };
28271
28525
  }
28272
- return { midTurnAdjustedSchedulerDecision: "execute", sideEffect: "none" };
28526
+ return {
28527
+ midTurnAdjustedSchedulerDecision: "execute",
28528
+ sideEffect: "none",
28529
+ deferReason: null
28530
+ };
28273
28531
  }
28274
28532
 
28275
28533
  // src/hooks/magic-context/cache-busting-signals.ts
@@ -32964,6 +33222,10 @@ async function runPostTransformPhase(args) {
32964
33222
  const shouldReadPendingOps = !compactionOff && (materializationRequested || args.schedulerDecision === "execute" || forceMaterialization || foldExecutedThisPass || compartmentRunning);
32965
33223
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
32966
33224
  const hasPendingUserOps = pendingOps.length > 0;
33225
+ const formatPendingOpsDepth = () => {
33226
+ const depth = getPendingOpsCount(args.db, args.sessionId);
33227
+ return depth === null ? "not loaded (deferred pass)" : String(depth);
33228
+ };
32967
33229
  const shouldApplyPendingOps = !compactionOff && (args.schedulerDecision === "execute" || materializationRequested || forceMaterialization || foldExecutedThisPass) && (!compartmentRunning || bypassCompartmentGate);
32968
33230
  const shouldRunHeuristics = !compactionOff && (!compartmentRunning || bypassCompartmentGate) && (materializationRequested || forceMaterialization || foldExecutedThisPass || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
32969
33231
  const isCacheBustingPass = shouldApplyPendingOps || shouldRunHeuristics;
@@ -32983,10 +33245,15 @@ async function runPostTransformPhase(args) {
32983
33245
  const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
32984
33246
  const reason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `scheduler_execute_subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
32985
33247
  sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
33248
+ } else if (args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
33249
+ sessionLog(args.sessionId, `heuristics WILL NOT RUN — reason=${args.schedulerDeferReason}`);
32986
33250
  }
32987
33251
  if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
32988
33252
  sessionLog(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
32989
33253
  }
33254
+ if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
33255
+ sessionLog(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
33256
+ }
32990
33257
  if (compartmentRunning && hasPendingUserOps) {
32991
33258
  if (bypassCompartmentGate) {
32992
33259
  const bypassReason = forceMaterialization ? `emergency >=${args.forceMaterializationPercentage}%` : "m0 hard fold";
@@ -33021,7 +33288,7 @@ async function runPostTransformPhase(args) {
33021
33288
  try {
33022
33289
  if (shouldApplyPendingOps) {
33023
33290
  const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
33024
- sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
33291
+ sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${formatPendingOpsDepth()}, context=${args.contextUsage.percentage.toFixed(1)}%`);
33025
33292
  const tApply = performance.now();
33026
33293
  pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
33027
33294
  if (pendingOpsDidMutate) {
@@ -36295,7 +36562,11 @@ function createTransform(deps) {
36295
36562
  sessionId,
36296
36563
  effectiveExecuteThresholdPercentage
36297
36564
  });
36298
- const { midTurnAdjustedSchedulerDecision, sideEffect } = applyMidTurnDeferral({
36565
+ const {
36566
+ midTurnAdjustedSchedulerDecision,
36567
+ sideEffect,
36568
+ deferReason: schedulerDeferReason
36569
+ } = applyMidTurnDeferral({
36299
36570
  base: schedulerDecisionEarly,
36300
36571
  bypassReason,
36301
36572
  midTurn
@@ -36664,6 +36935,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
36664
36935
  contextUsage,
36665
36936
  usableWindow: resolvedContextLimit ?? 0,
36666
36937
  schedulerDecision,
36938
+ schedulerDeferReason,
36667
36939
  fullFeatureMode,
36668
36940
  compactionOff,
36669
36941
  canRunCompartments,
@@ -37298,6 +37570,32 @@ function createEventHandler2(deps) {
37298
37570
  };
37299
37571
  }
37300
37572
 
37573
+ // src/hooks/magic-context/format-embed-failure.ts
37574
+ function formatEmbedFailureSummary(embedded, remaining, failure) {
37575
+ const compartment = `compartment${embedded === 1 ? "" : "s"}`;
37576
+ if (!failure) {
37577
+ return `Embedded ${embedded} ${compartment}; ${remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`;
37578
+ }
37579
+ const retry = " Run /ctx-embed start again to retry them.";
37580
+ switch (failure.class) {
37581
+ case "substitution_rejected":
37582
+ return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: set embedding.model to the served spelling.`;
37583
+ case "http_error": {
37584
+ const fix = failure.reason.startsWith("HTTP 401") || failure.reason.startsWith("HTTP 403") ? " Fix: check embedding.api_key." : failure.reason.startsWith("HTTP 402") ? " Fix: check provider quota or billing." : failure.reason.startsWith("HTTP 404") ? " Fix: check embedding.endpoint and embedding.model." : failure.retryable ? retry : " Fix: check embedding.endpoint, embedding.model, and credentials.";
37585
+ return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${fix}`;
37586
+ }
37587
+ case "invalid_envelope":
37588
+ return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: configure an OpenAI-compatible embedding endpoint that returns data[].embedding.`;
37589
+ case "certification_refusal":
37590
+ return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: recertify SYNAPSE or configure embedding.fallback_provider, then run /ctx-embed start again.`;
37591
+ case "credential_required":
37592
+ return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: reauthenticate SYNAPSE, then run /ctx-embed start again.`;
37593
+ case "empty_result":
37594
+ case "transport_error":
37595
+ return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${failure.retryable ? retry : ""}`;
37596
+ }
37597
+ }
37598
+
37301
37599
  // src/hooks/magic-context/text-complete.ts
37302
37600
  function createTextCompleteHandler() {
37303
37601
  return async (_input, output) => {
@@ -38372,7 +38670,7 @@ function createMagicContextHook(deps) {
38372
38670
  return terminal("skipped", msg);
38373
38671
  }
38374
38672
  case "stalled":
38375
- return terminal("skipped", `Embedded ${outcome.embedded} compartments; ${outcome.remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`);
38673
+ return terminal("skipped", formatEmbedFailureSummary(outcome.embedded, outcome.remaining, outcome.failure));
38376
38674
  default:
38377
38675
  return terminal("done", `Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search${runFailed > 0 ? ` (${runFailed} failed)` : ""}.`);
38378
38676
  }
@@ -41379,90 +41677,6 @@ function normalizeSources(sources) {
41379
41677
  }
41380
41678
  return result;
41381
41679
  }
41382
- function formatAge2(committedAtMs) {
41383
- const ageMs = Date.now() - committedAtMs;
41384
- if (ageMs < 0)
41385
- return "future";
41386
- const days = Math.floor(ageMs / (24 * 60 * 60 * 1000));
41387
- if (days <= 0)
41388
- return "today";
41389
- if (days === 1)
41390
- return "1d ago";
41391
- if (days < 30)
41392
- return `${days}d ago`;
41393
- const months = Math.floor(days / 30);
41394
- if (months === 1)
41395
- return "1mo ago";
41396
- if (months < 12)
41397
- return `${months}mo ago`;
41398
- const years = Math.floor(days / 365);
41399
- return years === 1 ? "1y ago" : `${years}y ago`;
41400
- }
41401
- var NOTE_EXPAND_HINT = "Use ctx_expand(start=N-10, end=N) around any note @msg anchor above to read the surrounding conversation context.";
41402
- function formatResult(result, index, currentSessionId) {
41403
- if (result.source === "memory") {
41404
- const source = result.sourceName ? ` source=${result.sourceName}` : "";
41405
- return [
41406
- `[${index}] [memory] score=${result.score.toFixed(2)} id=${result.memoryId} category=${result.category}${source} match=${result.matchType}`,
41407
- result.content
41408
- ].join(`
41409
- `);
41410
- }
41411
- if (result.source === "git_commit") {
41412
- return [
41413
- `[${index}] [git_commit] score=${result.score.toFixed(2)} sha=${result.shortSha} ${formatAge2(result.committedAtMs)} match=${result.matchType}`,
41414
- result.content
41415
- ].join(`
41416
- `);
41417
- }
41418
- if (result.source === "primer") {
41419
- return [
41420
- `[${index}] [primer] score=${result.score.toFixed(2)} id=${result.primerId} support=${result.support} match=${result.matchType}`,
41421
- result.content
41422
- ].join(`
41423
- `);
41424
- }
41425
- if (result.source === "note") {
41426
- const anchor = result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId ? ` @msg ${result.anchorOrdinal}` : "";
41427
- return [
41428
- `[${index}] [note] score=${result.score.toFixed(2)} id=#${result.noteId} status=${result.status} ${formatAge2(result.createdAt)}${anchor}`,
41429
- result.content
41430
- ].join(`
41431
- `);
41432
- }
41433
- if (result.source === "compartment") {
41434
- return [
41435
- `[${index}] [message] score=${result.score.toFixed(2)} compartment_id=${result.compartmentId} range=${result.startOrdinal}-${result.endOrdinal} match=${result.matchType} title=${result.title}`,
41436
- result.snippet ? `Snippet: ${result.snippet}` : result.content
41437
- ].join(`
41438
- `);
41439
- }
41440
- const expandStart = Math.max(1, result.messageOrdinal - 3);
41441
- const expandEnd = result.messageOrdinal + 3;
41442
- return [
41443
- `[${index}] [message] score=${result.score.toFixed(2)} ordinal=${result.messageOrdinal} range=${expandStart}-${expandEnd} role=${result.role}`,
41444
- result.content
41445
- ].join(`
41446
- `);
41447
- }
41448
- function formatSearchResults(query, results, currentSessionId) {
41449
- if (results.length === 0) {
41450
- return `No results found for "${query}" across notes, memories, primers, git commits, or message history.`;
41451
- }
41452
- const bodyParts = results.map((result, index) => formatResult(result, index + 1, currentSessionId));
41453
- if (results.some((result) => result.source === "message" || result.source === "compartment")) {
41454
- bodyParts.push("Use ctx_expand(start, end) with the range from any message result above to read the full conversation context.");
41455
- }
41456
- if (results.some((result) => result.source === "note" && result.anchorOrdinal !== null && result.sourceSessionId === currentSessionId)) {
41457
- bodyParts.push(NOTE_EXPAND_HINT);
41458
- }
41459
- const body = bodyParts.join(`
41460
-
41461
- `);
41462
- return `Found ${results.length} result${results.length === 1 ? "" : "s"} for "${query}":
41463
-
41464
- ${body}`;
41465
- }
41466
41680
  var ctxSearchArgsShape = {
41467
41681
  query: tool5.schema.string().optional().describe("Search query. Matches against memory content, Primers, git commit messages, and raw user/assistant message text."),
41468
41682
  limit: tool5.schema.number().optional().describe("Maximum results to return (default: 10)"),
@@ -41493,6 +41707,7 @@ function createCtxSearchTool(deps) {
41493
41707
  const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, toolContext.sessionID);
41494
41708
  const messageOrdinalCutoff = lastCompartmentEnd >= 0 ? lastCompartmentEnd : 0;
41495
41709
  const visibleMemoryIds = getVisibleMemoryIds(deps.db, toolContext.sessionID);
41710
+ const diagnostics = createUnifiedSearchDiagnostics();
41496
41711
  const projectPath = deps.resolveProjectPath(toolContext.directory);
41497
41712
  if (!projectPath) {
41498
41713
  return "Error: Could not resolve project identity for search.";
@@ -41509,10 +41724,11 @@ function createCtxSearchTool(deps) {
41509
41724
  projectPath,
41510
41725
  ids: idShape,
41511
41726
  limit: Math.max(normalizeLimit3(args.limit), idShape.length),
41512
- visibleMemoryIds
41727
+ visibleMemoryIds,
41728
+ diagnostics
41513
41729
  });
41514
- if (idResults !== null) {
41515
- return formatSearchResults(query, idResults, toolContext.sessionID);
41730
+ if (idResults !== null || diagnostics.suppressedVisibleMemoryIds.length > 0) {
41731
+ return formatSearchResults(query, idResults ?? [], toolContext.sessionID, diagnostics);
41516
41732
  }
41517
41733
  }
41518
41734
  const results = await unifiedSearch(deps.db, toolContext.sessionID, projectPath, query, {
@@ -41529,9 +41745,11 @@ function createCtxSearchTool(deps) {
41529
41745
  gitCommitsEnabled,
41530
41746
  sources: normalizeSources(args.sources),
41531
41747
  visibleMemoryIds,
41748
+ diagnostics,
41749
+ gitRepositoryAvailable: typeof toolContext.directory === "string" ? directoryHasGitMetadata(toolContext.directory) : undefined,
41532
41750
  explicitSearch: true
41533
41751
  });
41534
- return formatSearchResults(query, results, toolContext.sessionID);
41752
+ return formatSearchResults(query, results, toolContext.sessionID, diagnostics);
41535
41753
  }
41536
41754
  });
41537
41755
  }
@@ -41980,7 +42198,7 @@ var server = async (ctx) => {
41980
42198
  `);
41981
42199
  setTimeout(async () => {
41982
42200
  try {
41983
- const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-kn34g7mx.js");
42201
+ const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bw7eex6w.js");
41984
42202
  const clientWithSessions = ctx.client;
41985
42203
  const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
41986
42204
  const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
@@ -42173,7 +42391,7 @@ var server = async (ctx) => {
42173
42391
  {
42174
42392
  const fence = getSchemaFenceRejection();
42175
42393
  if (fence) {
42176
- import("./conflict-warning-hook-xj1r88a7.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
42394
+ import("./conflict-warning-hook-rf17b6et.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
42177
42395
  }
42178
42396
  }
42179
42397
  if (conflictResult?.hasConflict) {
@@ -42194,7 +42412,7 @@ var server = async (ctx) => {
42194
42412
  } = await import("./announcement-3g9xg433.js");
42195
42413
  if (shouldShowAnnouncement2()) {
42196
42414
  setTimeout(() => {
42197
- import("./conflict-warning-hook-xj1r88a7.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
42415
+ import("./conflict-warning-hook-rf17b6et.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
42198
42416
  }, 8000);
42199
42417
  }
42200
42418
  } catch {}