@cortexkit/opencode-magic-context 0.43.1 → 0.43.2

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 (51) hide show
  1. package/dist/{conflict-warning-hook-956fkedc.js → conflict-warning-hook-hyk9y29x.js} +3 -3
  2. package/dist/features/magic-context/dreamer/classify.d.ts +12 -0
  3. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  4. package/dist/features/magic-context/store-generation-rebase.d.ts +62 -1
  5. package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
  6. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  7. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +6 -0
  8. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  9. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +7 -0
  10. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +60 -8
  12. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
  13. package/dist/hooks/magic-context/hook.d.ts +3 -1
  14. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/system-prompt-hash.d.ts +9 -0
  16. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  19. package/dist/{index-kpmmr8s0.js → index-6j8th2hd.js} +1 -1
  20. package/dist/{index-v8qr6tt2.js → index-bmzt6xgy.js} +2 -2
  21. package/dist/{index-7wpwr2e2.js → index-g6hpfkqa.js} +250 -36
  22. package/dist/{index-yc81txp4.js → index-jgnag7sa.js} +1 -1
  23. package/dist/{index-1gtwrdc4.js → index-pa67brzn.js} +2 -2
  24. package/dist/{index-j7cnyvq1.js → index-tdrv6nd0.js} +1 -1
  25. package/dist/index.js +238 -28
  26. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  27. package/dist/{read-session-chunk-z7fv0qjv.js → read-session-chunk-53a7qbrh.js} +2 -2
  28. package/dist/{recomp-orchestrator-r00aa5t3.js → recomp-orchestrator-adsgqgse.js} +4 -4
  29. package/dist/{send-session-notification-3warjyjp.js → send-session-notification-e28r4xx2.js} +2 -2
  30. package/dist/shared/opencode-db-path.d.ts.map +1 -1
  31. package/dist/shared/test-fake-executable.d.ts +38 -0
  32. package/dist/shared/test-fake-executable.d.ts.map +1 -0
  33. package/dist/shared/user-facing-codes.d.ts +10 -0
  34. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  35. package/dist/v2/hooks/context.d.ts.map +1 -1
  36. package/dist/v2/hooks/refusal.d.ts +9 -1
  37. package/dist/v2/hooks/refusal.d.ts.map +1 -1
  38. package/dist/v2/hooks/restore-rows.d.ts +29 -0
  39. package/dist/v2/hooks/restore-rows.d.ts.map +1 -0
  40. package/dist/v2/hooks/update-check.d.ts +8 -0
  41. package/dist/v2/hooks/update-check.d.ts.map +1 -1
  42. package/dist/v2/server.js +470 -61
  43. package/dist/v2/store-reader.d.ts +8 -0
  44. package/dist/v2/store-reader.d.ts.map +1 -1
  45. package/dist/{wrapup-orchestrator-y0bs7t5a.js → wrapup-orchestrator-8xzbpvm8.js} +5 -5
  46. package/package.json +1 -1
  47. package/src/shared/opencode-db-path.test.ts +18 -0
  48. package/src/shared/opencode-db-path.ts +5 -2
  49. package/src/shared/test-fake-executable.test.ts +54 -0
  50. package/src/shared/test-fake-executable.ts +110 -0
  51. package/src/shared/user-facing-codes.ts +11 -0
package/dist/index.js CHANGED
@@ -474,7 +474,7 @@ import {
474
474
  setRecompStarting2,
475
475
  setRecompTerminal2,
476
476
  runManagedRecomp2
477
- } from "./index-7wpwr2e2.js";
477
+ } from "./index-g6hpfkqa.js";
478
478
  import {
479
479
  stripJsonComments,
480
480
  isPrototypePollutionKey,
@@ -528,7 +528,7 @@ import {
528
528
  latestPersistedMessageForRecovery,
529
529
  getMessageTimesFromOpenCodeDb,
530
530
  findLastAssistantModelFromOpenCodeDb
531
- } from "./index-v8qr6tt2.js";
531
+ } from "./index-bmzt6xgy.js";
532
532
  import {
533
533
  textMentionsRecentCommit,
534
534
  hasMeaningfulUserText2,
@@ -646,7 +646,7 @@ import {
646
646
  readRawSessionMessageById2,
647
647
  readSessionChunk2,
648
648
  readRawSessionSeedTail2
649
- } from "./index-j7cnyvq1.js";
649
+ } from "./index-tdrv6nd0.js";
650
650
  import"./index-febg06dy.js";
651
651
  import {
652
652
  getErrorMessage,
@@ -656,13 +656,13 @@ import {
656
656
  clearIgnoredMessages2,
657
657
  observeIgnoredNotificationEvent2,
658
658
  sendStatusNotification2
659
- } from "./index-yc81txp4.js";
659
+ } from "./index-jgnag7sa.js";
660
660
  import {
661
661
  detectConflicts,
662
662
  resolveCompactionForBoot,
663
663
  sendConflictWarning2,
664
664
  cleanupConflictWarnings2
665
- } from "./index-kpmmr8s0.js";
665
+ } from "./index-6j8th2hd.js";
666
666
  import {
667
667
  resolveModelCalibration,
668
668
  calibrateBuckets
@@ -708,7 +708,7 @@ import {
708
708
  } from "./index-fmsr7v69.js";
709
709
  import {
710
710
  runManagedWrapup2
711
- } from "./index-1gtwrdc4.js";
711
+ } from "./index-pa67brzn.js";
712
712
  import {
713
713
  logSlowWriteTransaction
714
714
  } from "./index-9r1cbh9e.js";
@@ -15157,8 +15157,11 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
15157
15157
  anchors
15158
15158
  });
15159
15159
  if (moduleRoute) {
15160
- const run = await runClassifyThroughModule(args, chunk, anchors, signal);
15161
- recordInvocation(args, startedAt, { status: "completed" });
15160
+ const { accounting, ...run } = await runClassifyThroughModule(args, chunk, anchors, signal);
15161
+ recordInvocation(args, startedAt, {
15162
+ status: "completed",
15163
+ moduleAccounting: accounting
15164
+ });
15162
15165
  return run;
15163
15166
  }
15164
15167
  const executor = resolveHiddenCompletionExecutor(args.hiddenCompletionExecutor, args.client, args.db, args.sessionDirectory, "classify-memories");
@@ -15260,7 +15263,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
15260
15263
  task: "classify",
15261
15264
  command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash5("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
15262
15265
  authority_generation: args.moduleAuthorityGeneration,
15263
- ...resolvedModelChain.length > 0 ? { model_chain: resolvedModelChain } : {},
15266
+ model_chain: resolvedModelChain,
15264
15267
  payload: {
15265
15268
  prompt_body: prompt,
15266
15269
  items: chunk.map((candidate) => ({
@@ -15281,6 +15284,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
15281
15284
  if (result.truncated === true) {
15282
15285
  throw new Error("classify returned length-capped output");
15283
15286
  }
15287
+ const accounting = moduleClassifyAccounting(result);
15284
15288
  const parsed = validateClassifyManifest(manifestText, new Set(chunk.map((candidate) => candidate.id)));
15285
15289
  const rows = parsed.map((entry) => {
15286
15290
  const candidate = chunk.find((item) => item.id === entry.id);
@@ -15353,7 +15357,39 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
15353
15357
  throw new Error(`module accepted unknown memory ${moduleId}`);
15354
15358
  return candidate.contextMemory.id;
15355
15359
  });
15356
- return { classified: acceptedContextIds.length, changed: acceptedContextIds.length };
15360
+ return {
15361
+ classified: acceptedContextIds.length,
15362
+ changed: acceptedContextIds.length,
15363
+ accounting
15364
+ };
15365
+ }
15366
+ function nonNegativeCount(value) {
15367
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
15368
+ }
15369
+ function moduleClassifyAccounting(result) {
15370
+ const accounting = {};
15371
+ const usage = result.usage;
15372
+ if (usage && typeof usage === "object") {
15373
+ const record = usage;
15374
+ accounting.tokens = {
15375
+ input: nonNegativeCount(record.input),
15376
+ output: nonNegativeCount(record.output),
15377
+ cacheRead: nonNegativeCount(record.cache_read),
15378
+ cacheWrite: nonNegativeCount(record.cache_write)
15379
+ };
15380
+ }
15381
+ const diagnostics = result.diagnostics;
15382
+ const model = diagnostics && typeof diagnostics === "object" ? diagnostics.model : undefined;
15383
+ if (typeof model === "string") {
15384
+ const parsed = parseProviderModel(model);
15385
+ if (parsed) {
15386
+ accounting.providerId = parsed.providerID;
15387
+ accounting.modelId = parsed.modelID;
15388
+ } else if (model.trim()) {
15389
+ accounting.modelId = model.trim();
15390
+ }
15391
+ }
15392
+ return accounting;
15357
15393
  }
15358
15394
  function applyClassifications(args, chunk, manifestText) {
15359
15395
  const byId = new Map(chunk.map((m) => [m.id, m]));
@@ -15398,6 +15434,11 @@ function recordInvocation(args, startedAt, params) {
15398
15434
  providerId: params.completion.providerId,
15399
15435
  modelId: params.completion.modelId
15400
15436
  } : {},
15437
+ ...params.moduleAccounting ? {
15438
+ tokens: params.moduleAccounting.tokens,
15439
+ providerId: params.moduleAccounting.providerId,
15440
+ modelId: params.moduleAccounting.modelId
15441
+ } : {},
15401
15442
  error: params.error
15402
15443
  });
15403
15444
  }
@@ -26098,6 +26139,8 @@ var TODOWRITE_TOOL = "todowrite";
26098
26139
  var availabilityBySession = new BoundedSessionMap(1000);
26099
26140
  var permissionDeniedBySession = new BoundedSessionMap(2000);
26100
26141
  var ctxReducePermissionDenyLogged = new BoundedSessionMap(1000);
26142
+ var ctxReduceSpawnPermissionDenied = new BoundedSessionMap(1000);
26143
+ var ctxReduceSpawnPermissionReads = new Map;
26101
26144
  function permissionCacheKey(toolName, sessionId) {
26102
26145
  return `${toolName}\x00${sessionId}`;
26103
26146
  }
@@ -26116,6 +26159,12 @@ function verdictFromToolsMap(tools, toolName) {
26116
26159
  return false;
26117
26160
  return null;
26118
26161
  }
26162
+ function unfrozenVerdict(sessionId, toolName, mapVerdict) {
26163
+ if (toolName === CTX_REDUCE_TOOL && ctxReduceSpawnPermissionDenied.get(sessionId) === true) {
26164
+ return false;
26165
+ }
26166
+ return mapVerdict ?? true;
26167
+ }
26119
26168
  function resolveToolAvailabilityFromMessages(sessionId, toolName, messages) {
26120
26169
  if (toolName === CTX_REDUCE_TOOL && !ctxReduceRegisteredGlobally) {
26121
26170
  return { callable: false, frozen: true };
@@ -26127,7 +26176,7 @@ function resolveToolAvailabilityFromMessages(sessionId, toolName, messages) {
26127
26176
  for (const message of messages) {
26128
26177
  if (message.info?.role !== "user")
26129
26178
  continue;
26130
- const verdict = verdictFromToolsMap(message.info.tools, toolName) ?? true;
26179
+ const verdict = unfrozenVerdict(sessionId, toolName, verdictFromToolsMap(message.info.tools, toolName));
26131
26180
  availabilityBySession.set(key, verdict);
26132
26181
  return { callable: verdict, frozen: true };
26133
26182
  }
@@ -26150,7 +26199,7 @@ function resolveToolAvailability(sessionId, toolName) {
26150
26199
  if (!row)
26151
26200
  return { callable: true, frozen: false };
26152
26201
  const verdict = row.tools === null ? null : verdictFromToolsMap(JSON.parse(row.tools), toolName);
26153
- const resolved = verdict ?? true;
26202
+ const resolved = unfrozenVerdict(sessionId, toolName, verdict);
26154
26203
  availabilityBySession.set(key, resolved);
26155
26204
  return { callable: resolved, frozen: true };
26156
26205
  } catch (error) {
@@ -26266,6 +26315,58 @@ async function resolveToolPermissionDenied(client, sessionId, toolName, activeAg
26266
26315
  permissionDeniedBySession.set(permissionCacheKey(toolName, sessionId), denied);
26267
26316
  return denied;
26268
26317
  }
26318
+ function primeCtxReduceSpawnPermission(client, sessionId, spawnAgent) {
26319
+ if (!ctxReduceSpawnPermissionReadNeeded(sessionId))
26320
+ return Promise.resolve();
26321
+ const inFlight = ctxReduceSpawnPermissionReads.get(sessionId);
26322
+ if (inFlight)
26323
+ return inFlight;
26324
+ const read = (async () => {
26325
+ try {
26326
+ const denied = await resolveToolPermissionDenied(client, sessionId, CTX_REDUCE_TOOL, spawnAgent);
26327
+ ctxReduceSpawnPermissionDenied.set(sessionId, denied);
26328
+ if (denied) {
26329
+ sessionLog(sessionId, `ctx_reduce permission is denied for agent=${spawnAgent ?? "(session default)"}; session freezes without ctx_reduce tags, guidance, or nudges`);
26330
+ }
26331
+ } catch (error) {
26332
+ sessionLog(sessionId, "ctx_reduce permission read before freeze failed (fail-open):", error);
26333
+ } finally {
26334
+ ctxReduceSpawnPermissionReads.delete(sessionId);
26335
+ }
26336
+ })();
26337
+ ctxReduceSpawnPermissionReads.set(sessionId, read);
26338
+ return read;
26339
+ }
26340
+ function ctxReduceSpawnPermissionReadNeeded(sessionId) {
26341
+ return ctxReduceRegisteredGlobally && availabilityBySession.get(cacheKey(CTX_REDUCE_TOOL, sessionId)) === undefined && ctxReduceSpawnPermissionDenied.get(sessionId) === undefined;
26342
+ }
26343
+ function spawnAgentFromMessages(messages) {
26344
+ for (const message of messages) {
26345
+ if (message.info?.role !== "user")
26346
+ continue;
26347
+ const agent = message.info.agent;
26348
+ return typeof agent === "string" && agent.length > 0 ? agent : undefined;
26349
+ }
26350
+ return;
26351
+ }
26352
+ function spawnAgentFromOpenCodeDb(sessionId) {
26353
+ if (!openCodeDbExists())
26354
+ return { persisted: false };
26355
+ try {
26356
+ const row = withReadOnlySessionDb((db) => db.prepare(`SELECT json_extract(data, '$.agent') AS agent FROM message
26357
+ WHERE session_id = ? AND json_extract(data, '$.role') = 'user'
26358
+ ORDER BY time_created ASC LIMIT 1`).get(sessionId));
26359
+ if (!row)
26360
+ return { persisted: false };
26361
+ return {
26362
+ persisted: true,
26363
+ agent: typeof row.agent === "string" && row.agent.length > 0 ? row.agent : undefined
26364
+ };
26365
+ } catch (error) {
26366
+ sessionLog(sessionId, "ctx_reduce spawn agent read failed:", error);
26367
+ return { persisted: false };
26368
+ }
26369
+ }
26269
26370
  function todowritePermissionDenied(client, sessionId, activeAgent) {
26270
26371
  return resolveToolPermissionDenied(client, sessionId, TODOWRITE_TOOL, activeAgent);
26271
26372
  }
@@ -27415,6 +27516,12 @@ function moduleResponseValue(response) {
27415
27516
  function rustCommandId(operation) {
27416
27517
  return `opencode-${operation}-${randomUUID2()}`;
27417
27518
  }
27519
+ var LEGACY_TRANSFORM_NOT_OBSERVED_SUMMARY = "wrapup unavailable until a full session transform has been observed";
27520
+ function wrapupNeedsSessionMessage(value) {
27521
+ if (value.reason === "transform_not_observed")
27522
+ return true;
27523
+ return value.reason === "snapshot_unavailable" && value.summary === LEGACY_TRANSFORM_NOT_OBSERVED_SUMMARY;
27524
+ }
27418
27525
  function formatRustOperationMessage(operation, value) {
27419
27526
  const disposition = typeof value.disposition === "string" ? value.disposition : "failed";
27420
27527
  const summary = typeof value.summary === "string" ? value.summary : "";
@@ -27436,7 +27543,7 @@ ${summary || "Nothing to compact."}`;
27436
27543
  case "retryable":
27437
27544
  return `## Magic Wrapup — Partial
27438
27545
 
27439
- ${renderCapabilityRefusal("history_compression")}`;
27546
+ ${wrapupNeedsSessionMessage(value) ? renderUserFacingFailure("history_compression_needs_message") : renderCapabilityRefusal("history_compression")}`;
27440
27547
  default:
27441
27548
  return `## Magic Wrapup — Failed
27442
27549
 
@@ -31111,8 +31218,8 @@ function registerRpcHandlers(rpcServer, args) {
31111
31218
  const db = getDb();
31112
31219
  if (!db)
31113
31220
  return { ok: false, error: "db unavailable" };
31114
- const { runManagedRecomp } = await import("./recomp-orchestrator-r00aa5t3.js");
31115
- const { sendIgnoredMessage } = await import("./send-session-notification-3warjyjp.js");
31221
+ const { runManagedRecomp } = await import("./recomp-orchestrator-adsgqgse.js");
31222
+ const { sendIgnoredMessage } = await import("./send-session-notification-e28r4xx2.js");
31116
31223
  log(`[rpc] recomp requested for session ${sessionId}`);
31117
31224
  const ctx = await buildManagedCtx(db);
31118
31225
  runManagedRecomp(ctx, sessionId).then((message) => {
@@ -31170,7 +31277,7 @@ function registerRpcHandlers(rpcServer, args) {
31170
31277
  const db = getDb();
31171
31278
  if (!db)
31172
31279
  return { ok: false, error: "db unavailable" };
31173
- const { runManagedWrapup } = await import("./wrapup-orchestrator-y0bs7t5a.js");
31280
+ const { runManagedWrapup } = await import("./wrapup-orchestrator-8xzbpvm8.js");
31174
31281
  const model = liveSessionState.liveModelBySession.get(sessionId);
31175
31282
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
31176
31283
  const ctx = {
@@ -39606,6 +39713,9 @@ function createTransform(deps) {
39606
39713
  passOutcome.record("compaction-mode-transition-failure");
39607
39714
  sessionLog(sessionId, "compaction mode transition failed (retrying next pass):", error);
39608
39715
  }
39716
+ if (deps.client !== undefined && !compactionOff) {
39717
+ await primeCtxReduceSpawnPermission(deps.client, sessionId, spawnAgentFromMessages(messages));
39718
+ }
39609
39719
  if (deps.transformMode === "rust") {
39610
39720
  if (!rustModeTransform) {
39611
39721
  sessionLog(sessionId, "rust transform unavailable; using raw passthrough");
@@ -41331,6 +41441,12 @@ function createSystemPromptHashHandler(deps) {
41331
41441
  sessionLog(sessionId, "system-prompt-hash session meta load failed:", error);
41332
41442
  }
41333
41443
  const isSubagentSession = sessionMetaEarly?.isSubagent === true;
41444
+ if (deps.client && ctxReduceSpawnPermissionReadNeeded(sessionId)) {
41445
+ const spawn = spawnAgentFromOpenCodeDb(sessionId);
41446
+ if (spawn.persisted) {
41447
+ await primeCtxReduceSpawnPermission(deps.client, sessionId, spawn.agent);
41448
+ }
41449
+ }
41334
41450
  const availability = resolveCtxReduceAvailability(sessionId);
41335
41451
  const ctxReduceCallable = availability.callable;
41336
41452
  const subagentReduceMode = isSubagentSession && ctxReduceCallable;
@@ -42236,6 +42352,7 @@ function createMagicContextHook(deps) {
42236
42352
  "<!-- magic-context: skip -->"
42237
42353
  ],
42238
42354
  internalChildSessions,
42355
+ client: deps.client,
42239
42356
  experimentalUserMemories: userMemoryCollectionEnabled2(deps.config.dreamer),
42240
42357
  experimentalTemporalAwareness: deps.config.temporal_awareness === true,
42241
42358
  experimentalCavemanTextCompression: deps.config.caveman_text_compression?.enabled === true
@@ -47108,6 +47225,17 @@ class V2StoreReader {
47108
47225
  range(sessionID, after, through) {
47109
47226
  return trackDecodeOperation("range", () => through <= after ? [] : this.all(sessionID, after, undefined, through));
47110
47227
  }
47228
+ spanRowStamps(sessionID, after, through) {
47229
+ if (!Number.isSafeInteger(after) || !Number.isSafeInteger(through))
47230
+ throw new Error("Invalid seq span");
47231
+ const rows = this.db.prepare(`SELECT seq, id, time_updated AS updated, length(CAST(data AS BLOB)) AS bytes
47232
+ FROM session_message WHERE session_id = ? AND seq > ? AND seq <= ?
47233
+ ORDER BY seq ASC`).all(sessionID, after, through);
47234
+ const stamps = new Map;
47235
+ for (const row of rows)
47236
+ stamps.set(row.seq, `${row.id}\x00${row.updated ?? ""}\x00${row.bytes ?? ""}`);
47237
+ return stamps;
47238
+ }
47111
47239
  rawRowsThrough(sessionID, throughSeq, limit) {
47112
47240
  return trackDecodeOperation("rawRowsThrough", () => {
47113
47241
  if (!Number.isSafeInteger(throughSeq))
@@ -47890,13 +48018,18 @@ class V2ContextRefusal extends Error {
47890
48018
  this.name = "V2ContextRefusal";
47891
48019
  }
47892
48020
  }
47893
- async function interruptBeforeProvider(session, sessionID) {
48021
+ var INTERRUPT_CONFIRMATION_TIMEOUT_MS = 2000;
48022
+ var systemTimers = {
48023
+ setTimeout: (callback, ms) => setTimeout(callback, ms),
48024
+ clearTimeout: (handle) => clearTimeout(handle)
48025
+ };
48026
+ async function interruptBeforeProvider(session, sessionID, timers = systemTimers) {
47894
48027
  let timer;
47895
48028
  try {
47896
48029
  const result = await Promise.race([
47897
48030
  session.interrupt({ sessionID }),
47898
48031
  new Promise((_, reject) => {
47899
- timer = setTimeout(() => reject(new Error("interrupt exceeded 2000 ms")), 2000);
48032
+ timer = timers.setTimeout(() => reject(new Error(`interrupt exceeded ${INTERRUPT_CONFIRMATION_TIMEOUT_MS} ms`)), INTERRUPT_CONFIRMATION_TIMEOUT_MS);
47900
48033
  })
47901
48034
  ]);
47902
48035
  if (result.interrupted !== true)
@@ -47904,9 +48037,79 @@ async function interruptBeforeProvider(session, sessionID) {
47904
48037
  } catch (cause) {
47905
48038
  throw new V2ContextRefusal(undefined, { cause });
47906
48039
  } finally {
47907
- clearTimeout(timer);
48040
+ if (timer !== undefined)
48041
+ timers.clearTimeout(timer);
48042
+ }
48043
+ }
48044
+
48045
+ // src/v2/hooks/restore-rows.ts
48046
+ class RestoredRowCache {
48047
+ capacity;
48048
+ sessions = new Map;
48049
+ constructor(capacity = 16) {
48050
+ this.capacity = capacity;
48051
+ }
48052
+ rows(reader, sessionID, after, through) {
48053
+ if (through <= after)
48054
+ return [];
48055
+ const kept = this.sessions.get(sessionID) ?? new Map;
48056
+ const stamps = reader.spanRowStamps(sessionID, after, through);
48057
+ const runs = [];
48058
+ let previous = after;
48059
+ let open;
48060
+ for (const [seq, stamp] of stamps) {
48061
+ if (kept.get(seq)?.stamp === stamp) {
48062
+ open = undefined;
48063
+ } else if (open) {
48064
+ open.through = seq;
48065
+ } else {
48066
+ open = { after: previous, through: seq };
48067
+ runs.push(open);
48068
+ }
48069
+ previous = seq;
48070
+ }
48071
+ const fresh = new Map;
48072
+ for (const run of runs)
48073
+ for (const row of readPages(reader, sessionID, run.after, run.through))
48074
+ fresh.set(row.seq, row);
48075
+ const next = new Map;
48076
+ const rows = [];
48077
+ for (const [seq, stamp] of stamps) {
48078
+ const row = fresh.get(seq) ?? kept.get(seq)?.row;
48079
+ if (!row)
48080
+ continue;
48081
+ next.set(seq, { stamp, row });
48082
+ rows.push(row);
48083
+ }
48084
+ this.sessions.delete(sessionID);
48085
+ this.sessions.set(sessionID, next);
48086
+ while (this.sessions.size > this.capacity) {
48087
+ const oldest = this.sessions.keys().next().value;
48088
+ if (oldest === undefined)
48089
+ break;
48090
+ this.sessions.delete(oldest);
48091
+ }
48092
+ return structuredClone(rows);
48093
+ }
48094
+ forget(sessionID) {
48095
+ this.sessions.delete(sessionID);
48096
+ }
48097
+ clear() {
48098
+ this.sessions.clear();
47908
48099
  }
47909
48100
  }
48101
+ function readPages(reader, sessionID, after, through) {
48102
+ const rows = [];
48103
+ let cursor = after;
48104
+ while (cursor < through) {
48105
+ const page = reader.page(sessionID, { after: cursor, through, limit: 100 });
48106
+ rows.push(...page.rows);
48107
+ if (page.rows.length < 100 || page.cursor === undefined)
48108
+ break;
48109
+ cursor = page.cursor;
48110
+ }
48111
+ return rows;
48112
+ }
47910
48113
 
47911
48114
  // src/v2/hooks/rpc-live-state.ts
47912
48115
  function createV2RpcLiveSessionState(overrides) {
@@ -48431,6 +48634,7 @@ async function registerContext(context) {
48431
48634
  const historyRefreshSessions = new Set;
48432
48635
  const pendingMaterializationSessions = new Set;
48433
48636
  const lastHeuristicsTurnId = new Map;
48637
+ const restoredRows = new RestoredRowCache;
48434
48638
  const rawProviders = new Map;
48435
48639
  let passDuties;
48436
48640
  let toolDuties;
@@ -48591,6 +48795,7 @@ async function registerContext(context) {
48591
48795
  historyRefreshSessions.delete(sessionID);
48592
48796
  pendingMaterializationSessions.delete(sessionID);
48593
48797
  lastHeuristicsTurnId.delete(sessionID);
48798
+ restoredRows.forget(sessionID);
48594
48799
  systemPromptRefreshSessions.delete(sessionID);
48595
48800
  systemPrompt?.clearSession(sessionID);
48596
48801
  tagger.cleanup(sessionID);
@@ -48815,7 +49020,7 @@ async function registerContext(context) {
48815
49020
  const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
48816
49021
  const boundary = servedBoundary?.seq ?? reader.sequenceForId(draft.sessionID, boundaryID) ?? (reader.earliestSequence(draft.sessionID) ?? 0) - 1;
48817
49022
  const present = new Set(draft.messages.map((message) => message.id));
48818
- const restored = reader.range(draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
49023
+ const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
48819
49024
  asset: hostMediaAsset,
48820
49025
  unavailable: (detail) => sessionLog(draft.sessionID, `v2 restore: attachment replaced by a note row=${detail.rowID} name=${JSON.stringify(detail.name ?? null)} mediaType=${detail.mediaType} reason=${JSON.stringify(detail.reason)}`)
48821
49026
  } : undefined));
@@ -48968,6 +49173,7 @@ ${baseline}
48968
49173
  for (const release of rawProviders.values())
48969
49174
  release();
48970
49175
  rawProviders.clear();
49176
+ restoredRows.clear();
48971
49177
  }
48972
49178
  };
48973
49179
  }
@@ -48994,6 +49200,9 @@ function packageInfo() {
48994
49200
  directory = parent;
48995
49201
  }
48996
49202
  }
49203
+ function formatUpdateAvailableMessage(latest, current) {
49204
+ return `Magic Context ${latest} is available (running ${current}). To install it, open /plugins, select Magic Context and press ctrl+u, or run \`opencode plugin update\`. A version-pinned plugin entry must be changed in your OpenCode config instead.`;
49205
+ }
48997
49206
  function startUpdateChecks(context, check = (signal) => {
48998
49207
  return packageInfo().development ? Promise.resolve(null) : getLatestVersion("latest", { signal });
48999
49208
  }) {
@@ -49008,10 +49217,11 @@ function startUpdateChecks(context, check = (signal) => {
49008
49217
  continue;
49009
49218
  await context.storage.set("version-check-at", Date.now());
49010
49219
  const latest = await check(controller.signal);
49011
- const comparison = latest ? compareSemverCore(latest, packageInfo().version) : null;
49012
- if (!controller.signal.aborted && comparison !== null && comparison > 0) {
49220
+ const current = packageInfo().version;
49221
+ const comparison = latest ? compareSemverCore(latest, current) : null;
49222
+ if (latest && !controller.signal.aborted && comparison !== null && comparison > 0) {
49013
49223
  pushNotification2("toast", {
49014
- message: `Magic Context ${latest} is available. Update the plugin to install it.`,
49224
+ message: formatUpdateAvailableMessage(latest, current),
49015
49225
  variant: "info"
49016
49226
  });
49017
49227
  }
@@ -49106,7 +49316,7 @@ var server = async (ctx) => {
49106
49316
  if (hasBannerEntries)
49107
49317
  setTimeout(async () => {
49108
49318
  try {
49109
- const { sendStatusNotification } = await import("./send-session-notification-3warjyjp.js");
49319
+ const { sendStatusNotification } = await import("./send-session-notification-e28r4xx2.js");
49110
49320
  const clientWithSessions = ctx.client;
49111
49321
  const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
49112
49322
  const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
@@ -49123,7 +49333,7 @@ var server = async (ctx) => {
49123
49333
  log(`[magic-context] opencode_db_missing path=${openCodeDbResolution.path} source=${openCodeDbResolution.source}`);
49124
49334
  setTimeout(async () => {
49125
49335
  try {
49126
- const { sendStatusNotification } = await import("./send-session-notification-3warjyjp.js");
49336
+ const { sendStatusNotification } = await import("./send-session-notification-e28r4xx2.js");
49127
49337
  const clientWithSessions = ctx.client;
49128
49338
  const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
49129
49339
  const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
@@ -49390,12 +49600,12 @@ var server = async (ctx) => {
49390
49600
  {
49391
49601
  const fence = getSchemaFenceRejection();
49392
49602
  if (fence) {
49393
- import("./conflict-warning-hook-956fkedc.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
49603
+ import("./conflict-warning-hook-hyk9y29x.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
49394
49604
  }
49395
49605
  }
49396
49606
  const serverUrl = ctx.serverUrl;
49397
49607
  const serverUrlStr = serverUrl instanceof URL ? serverUrl.toString().replace(/\/$/, "") : typeof serverUrl === "string" ? serverUrl.replace(/\/$/, "") : undefined;
49398
- import("./send-session-notification-3warjyjp.js").then(({ setNotificationServerUrl }) => {
49608
+ import("./send-session-notification-e28r4xx2.js").then(({ setNotificationServerUrl }) => {
49399
49609
  setNotificationServerUrl(serverUrlStr);
49400
49610
  });
49401
49611
  if (conflictResult?.hasConflict) {
@@ -49418,7 +49628,7 @@ var server = async (ctx) => {
49418
49628
  }) => {
49419
49629
  if (!shouldShowAnnouncement())
49420
49630
  return;
49421
- return import("./conflict-warning-hook-956fkedc.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
49631
+ return import("./conflict-warning-hook-hyk9y29x.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
49422
49632
  }).catch(() => {});
49423
49633
  }, 8000);
49424
49634
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAGnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,wBAAwB;;;;;;;;;;;;;mBAQxD,CAAC;aACb,CAAC;aACE,CAAC;eACI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;2BAoHo5gC,CAAC;;;;eAA6iB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA3Gz9hC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC/C;;;;;;;;;;qBAkG2jF,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;;;;;;;;qBAA3gC,CAAC;mBAA6B,CAAC;iBAA2B,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;iBAA2D,CAAC;;oBAA4D,CAAC;uBAAiC,CAAC;yBAAoC,CAAC;;;;;;0BAAyk6D,CAAC;;;;;;;;;;;;;;EAvDh/9D;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACjE;;;;;;;;;;qBA6C2jF,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;;;;;;;;qBAA3gC,CAAC;mBAA6B,CAAC;iBAA2B,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;iBAA2D,CAAC;;oBAA4D,CAAC;uBAAiC,CAAC;yBAAoC,CAAC;;;;;;0BAAyk6D,CAAC;;;;;;;;;;;;;;GADh/9D"}
1
+ {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAGnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,wBAAwB;;;;;;;;;;;;;mBAQxD,CAAC;aACb,CAAC;aACE,CAAC;eACI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;2BAoHo5gC,CAAC;;;;eAA6iB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA3Gz9hC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC/C;;;;;;;;;;qBAkG4oG,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;;;;;;;;qBAA5lD,CAAC;mBAA6B,CAAC;iBAA2B,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;iBAA2D,CAAC;;oBAA4D,CAAC;uBAAiC,CAAC;yBAAoC,CAAC;;;;;;0BAAsm6D,CAAC;;;;;;;;;;;;;;EAvD7g+D;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACjE;;;;;;;;;;qBA6C4oG,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;;;;;;;;qBAA5lD,CAAC;mBAA6B,CAAC;iBAA2B,CAAC;iBAA2B,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;iBAA2D,CAAC;;oBAA4D,CAAC;uBAAiC,CAAC;yBAAoC,CAAC;;;;;;0BAAsm6D,CAAC;;;;;;;;;;;;;;GAD7g+D"}
@@ -26,9 +26,9 @@ import {
26
26
  getLegacyProtectedTailStartOrdinal2,
27
27
  readSessionChunk2,
28
28
  readRawSessionSeedTail2
29
- } from "./index-j7cnyvq1.js";
29
+ } from "./index-tdrv6nd0.js";
30
30
  import"./index-y5145x8k.js";
31
- import"./index-v8qr6tt2.js";
31
+ import"./index-bmzt6xgy.js";
32
32
  import"./index-wgzyeyf5.js";
33
33
  import"./index-6z9g64js.js";
34
34
  export {
@@ -2,13 +2,13 @@ import {
2
2
  setRecompStarting2,
3
3
  setRecompTerminal2,
4
4
  runManagedRecomp2
5
- } from "./index-7wpwr2e2.js";
5
+ } from "./index-g6hpfkqa.js";
6
6
  import"./index-sd3egckz.js";
7
7
  import"./index-0ccmyzbj.js";
8
- import"./index-yc81txp4.js";
9
- import"./index-j7cnyvq1.js";
8
+ import"./index-jgnag7sa.js";
9
+ import"./index-tdrv6nd0.js";
10
10
  import"./index-y5145x8k.js";
11
- import"./index-v8qr6tt2.js";
11
+ import"./index-bmzt6xgy.js";
12
12
  import"./index-9r1cbh9e.js";
13
13
  import"./index-jdxxq8cz.js";
14
14
  import"./index-febg06dy.js";
@@ -6,8 +6,8 @@ import {
6
6
  clearIgnoredMessages2,
7
7
  observeIgnoredNotificationEvent2,
8
8
  sendStatusNotification2
9
- } from "./index-yc81txp4.js";
10
- import"./index-v8qr6tt2.js";
9
+ } from "./index-jgnag7sa.js";
10
+ import"./index-bmzt6xgy.js";
11
11
  import"./index-febg06dy.js";
12
12
  import"./index-wgzyeyf5.js";
13
13
  import"./index-6z9g64js.js";
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-db-path.d.ts","sourceRoot":"","sources":["../../src/shared/opencode-db-path.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;AACxF,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,IAAI,CAAC;AACjD,MAAM,MAAM,uBAAuB,GAAG,sBAAsB,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,4BAA4B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC7C,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,sBAAsB,CAKxB;AAED,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACnE,OAAO,EAAE,MAAM,CAAC;CACnB;AAwGD,wFAAwF;AACxF,wBAAgB,8BAA8B,CAC1C,cAAc,EAAE,sBAAsB,EACtC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACrC,MAAM,CAoBR;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,cAAc,GAAE,sBAA6B,EAC7C,OAAO,GAAE,4BAAiC,GAC3C,wBAAwB,CAuB1B;AAcD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAC9B,EAAE,EAAE,2BAA2B,EAC/B,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,OAAO,CAGT;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CACzC,EAAE,EAAE,2BAA2B,EAC/B,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,uBAAuB,CAOzB;AAwBD,kFAAkF;AAClF,wBAAgB,6BAA6B,CACzC,EAAE,EAAE,2BAA2B,EAC/B,QAAQ,EAAE,sBAAsB,EAChC,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,IAAI,CAYN;AAED,wBAAgB,oBAAoB,CAChC,UAAU,GAAE,wBAAkD,GAC/D,OAAO,CAET;AAED,wBAAgB,8BAA8B,CAC1C,UAAU,GAAE,wBAAkD,GAC/D,MAAM,EAAE,CAgBV;AAMD,wBAAgB,6BAA6B,CACzC,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,iCAAiC,CAC7C,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,0BAA0B,CACtC,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAE5F;AAED,wBAAgB,2BAA2B,CACvC,UAAU,EAAE,wBAAwB,EACpC,KAAK,EAAE,OAAO,GACf,qBAAqB,CAIvB;AAED,wBAAgB,0BAA0B,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9D;AAED,wBAAgB,wBAAwB,IAAI,qBAAqB,GAAG,IAAI,CAEvE;AAED,wBAAgB,6BAA6B,CACzC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,wBAAwB,GACrC,OAAO,CAKT;AAED,yEAAyE;AACzE,wBAAgB,kCAAkC,IAAI,IAAI,CAIzD"}
1
+ {"version":3,"file":"opencode-db-path.d.ts","sourceRoot":"","sources":["../../src/shared/opencode-db-path.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;AACxF,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,IAAI,CAAC;AACjD,MAAM,MAAM,uBAAuB,GAAG,sBAAsB,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,4BAA4B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC7C,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,sBAAsB,CAKxB;AAED,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACnE,OAAO,EAAE,MAAM,CAAC;CACnB;AAwGD,wFAAwF;AACxF,wBAAgB,8BAA8B,CAC1C,cAAc,EAAE,sBAAsB,EACtC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACrC,MAAM,CAoBR;AAmBD;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,cAAc,GAAE,sBAA6B,EAC7C,OAAO,GAAE,4BAAiC,GAC3C,wBAAwB,CAuB1B;AAcD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAC9B,EAAE,EAAE,2BAA2B,EAC/B,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,OAAO,CAGT;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CACzC,EAAE,EAAE,2BAA2B,EAC/B,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,uBAAuB,CAOzB;AAwBD,kFAAkF;AAClF,wBAAgB,6BAA6B,CACzC,EAAE,EAAE,2BAA2B,EAC/B,QAAQ,EAAE,sBAAsB,EAChC,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,MAAM,GAAG,aAAsB,GACxC,IAAI,CAYN;AAED,wBAAgB,oBAAoB,CAChC,UAAU,GAAE,wBAAkD,GAC/D,OAAO,CAET;AAED,wBAAgB,8BAA8B,CAC1C,UAAU,GAAE,wBAAkD,GAC/D,MAAM,EAAE,CAgBV;AAMD,wBAAgB,6BAA6B,CACzC,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,iCAAiC,CAC7C,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,0BAA0B,CACtC,UAAU,GAAE,wBAAkD,GAC/D,MAAM,CAER;AAED,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAE5F;AAED,wBAAgB,2BAA2B,CACvC,UAAU,EAAE,wBAAwB,EACpC,KAAK,EAAE,OAAO,GACf,qBAAqB,CAIvB;AAED,wBAAgB,0BAA0B,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9D;AAED,wBAAgB,wBAAwB,IAAI,qBAAqB,GAAG,IAAI,CAEvE;AAED,wBAAgB,6BAA6B,CACzC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,wBAAwB,GACrC,OAAO,CAKT;AAED,yEAAyE;AACzE,wBAAgB,kCAAkC,IAAI,IAAI,CAIzD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Test-only helper for fake executables (shell stubs standing in for opencode,
3
+ * sqlite3, bun, ...).
4
+ *
5
+ * macOS runs a malware assessment the first time any new executable file is
6
+ * launched. Writing a fresh stub into a fresh temp directory for every test
7
+ * case therefore triggers one assessment per case per run. Instead, each
8
+ * distinct stub lives at a fixed, content-addressed path and is written only
9
+ * once; later tests and later runs reuse the same file.
10
+ *
11
+ * Callers must never delete these files in per-test cleanup, and must never
12
+ * modify one in place: a test that needs a stub to "change" between steps asks
13
+ * for a second stub with different content, which lands at a different path.
14
+ */
15
+ /** Directory name under the OS temp dir that holds every shared fake executable. */
16
+ export declare const TEST_EXECUTABLE_ROOT_NAME = "magic-context-test-bin";
17
+ export declare function testExecutableRoot(): string;
18
+ export interface WriteTestExecutableOptions {
19
+ /**
20
+ * Kept verbatim in front of the hash in the directory name. Use it only when
21
+ * the test depends on the directory name itself, for example to exercise
22
+ * quoting of spaces or shell metacharacters in the executable's path.
23
+ */
24
+ dirPrefix?: string;
25
+ }
26
+ /**
27
+ * Returns the path of an executable named `name` whose bytes are `content`,
28
+ * creating it only when no identical file exists yet. The path is
29
+ * `<tmpdir>/magic-context-test-bin/<dirPrefix><first 16 hex of sha256(name, content)>/<name>`,
30
+ * so each directory holds exactly one executable and pointing PATH at it
31
+ * exposes nothing else.
32
+ *
33
+ * The file is written to a unique temporary name in the same directory and
34
+ * then renamed into place, so concurrent test processes never observe a
35
+ * half-written stub.
36
+ */
37
+ export declare function writeTestExecutable(name: string, content: string, options?: WriteTestExecutableOptions): string;
38
+ //# sourceMappingURL=test-fake-executable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-fake-executable.d.ts","sourceRoot":"","sources":["../../src/shared/test-fake-executable.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;GAaG;AAEH,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAElE,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAqBD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,0BAA+B,GACzC,MAAM,CA+BR"}
@@ -11,6 +11,11 @@ export declare const USER_FACING_FAILURES: {
11
11
  readonly sentence: "Some finished background sessions could not be removed from this host.";
12
12
  readonly action: "They are removed automatically the next time Magic Context runs inside a registered OpenCode service.";
13
13
  };
14
+ readonly historian_saved_history_misaligned: {
15
+ readonly code: "MC-H03";
16
+ readonly sentence: "History compression is paused because this session's saved summaries no longer line up with its messages.";
17
+ readonly action: "Run /ctx-recomp to rebuild them.";
18
+ };
14
19
  readonly recomp_unavailable: {
15
20
  readonly code: "MC-R01";
16
21
  readonly sentence: "History compression could not be rebuilt.";
@@ -181,6 +186,11 @@ export declare const USER_FACING_FAILURES: {
181
186
  readonly sentence: "History compression is paused while the engine syncs.";
182
187
  readonly action: "Retry in a moment.";
183
188
  };
189
+ readonly history_compression_needs_message: {
190
+ readonly code: "MC-C12";
191
+ readonly sentence: "History compression has not seen this session since Magic Context reconnected.";
192
+ readonly action: "Send a message in this session first, then run /ctx-wrapup again.";
193
+ };
184
194
  readonly context_service_unavailable: {
185
195
  readonly code: "MC-C10";
186
196
  readonly sentence: "Magic Context is temporarily unavailable.";
@@ -1 +1 @@
1
- {"version":3,"file":"user-facing-codes.d.ts","sourceRoot":"","sources":["../../src/shared/user-facing-codes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqNvB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,wBAAgB,uBAAuB,CACnC,GAAG,EAAE,oBAAoB,EACzB,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAIR;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAEvE;AAED,MAAM,MAAM,iBAAiB,GACvB,cAAc,GACd,eAAe,GACf,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,iBAAiB,GACjB,sBAAsB,GACtB,qBAAqB,GACrB,iBAAiB,CAAC;AAcxB,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAE3E;AA0BD,wBAAgB,kBAAkB,CAC9B,YAAY,EAAE,kBAAkB,EAChC,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,kBAAkB,GAAG,MAAM,CAEzE;AAED,wBAAgB,sBAAsB,CAClC,YAAY,EAAE,qBAAqB,EACnC,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,qBAAqB,GAAG,MAAM,CAEhF"}
1
+ {"version":3,"file":"user-facing-codes.d.ts","sourceRoot":"","sources":["../../src/shared/user-facing-codes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgOvB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAErE,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,wBAAgB,uBAAuB,CACnC,GAAG,EAAE,oBAAoB,EACzB,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAIR;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAEvE;AAED,MAAM,MAAM,iBAAiB,GACvB,cAAc,GACd,eAAe,GACf,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,iBAAiB,GACjB,sBAAsB,GACtB,qBAAqB,GACrB,iBAAiB,CAAC;AAcxB,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAE3E;AA0BD,wBAAgB,kBAAkB,CAC9B,YAAY,EAAE,kBAAkB,EAChC,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,kBAAkB,GAAG,MAAM,CAEzE;AAED,wBAAgB,sBAAsB,CAClC,YAAY,EAAE,qBAAqB,EACnC,KAAK,GAAE,mBAAgC,GACxC,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,qBAAqB,GAAG,MAAM,CAEhF"}