@cortexkit/opencode-magic-context 0.42.0 → 0.42.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 (70) hide show
  1. package/dist/config/project-security.d.ts +3 -2
  2. package/dist/config/project-security.d.ts.map +1 -1
  3. package/dist/config/schema/magic-context.d.ts +20 -0
  4. package/dist/config/schema/magic-context.d.ts.map +1 -1
  5. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +8 -4
  6. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  7. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  9. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  10. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  11. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  12. package/dist/features/magic-context/memory/embedding-model-match.d.ts +41 -0
  13. package/dist/features/magic-context/memory/embedding-model-match.d.ts.map +1 -0
  14. package/dist/features/magic-context/memory/embedding-openai.d.ts +7 -20
  15. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  16. package/dist/features/magic-context/memory/embedding-provider.d.ts +2 -2
  17. package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
  18. package/dist/features/magic-context/memory/embedding-synapse.d.ts +5 -4
  19. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  20. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  21. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  23. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  25. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
  26. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/embed-session-state.d.ts +1 -1
  28. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/execute-status.d.ts +2 -0
  30. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  31. package/dist/hooks/magic-context/format-embed-failure.d.ts +2 -1
  32. package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -1
  33. package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -2
  34. package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -1
  35. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  36. package/dist/{index-c9hamh36.js → index-1q9kay7n.js} +534 -120
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +264 -108
  39. package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
  40. package/dist/plugin/embedding-routing.d.ts.map +1 -1
  41. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  42. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  43. package/dist/{recomp-orchestrator-3atsasjy.js → recomp-orchestrator-m33b3rk9.js} +1 -1
  44. package/dist/shared/rpc-types.d.ts +10 -0
  45. package/dist/shared/rpc-types.d.ts.map +1 -1
  46. package/dist/shared/status-detail-text.d.ts +3 -1
  47. package/dist/shared/status-detail-text.d.ts.map +1 -1
  48. package/dist/shared/status-summary.d.ts +30 -0
  49. package/dist/shared/status-summary.d.ts.map +1 -0
  50. package/dist/shared/tail-hygiene-status.d.ts +1 -0
  51. package/dist/shared/tail-hygiene-status.d.ts.map +1 -1
  52. package/dist/shared/user-facing-codes.d.ts +191 -0
  53. package/dist/shared/user-facing-codes.d.ts.map +1 -0
  54. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  55. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  56. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/src/config/project-security.test.ts +10 -2
  59. package/src/config/project-security.ts +12 -5
  60. package/src/config/schema/magic-context.test.ts +29 -0
  61. package/src/config/schema/magic-context.ts +24 -0
  62. package/src/shared/rpc-types.ts +10 -0
  63. package/src/shared/status-detail-text.test.ts +93 -24
  64. package/src/shared/status-detail-text.ts +9 -2
  65. package/src/shared/status-summary.ts +167 -0
  66. package/src/shared/tail-hygiene-status.ts +8 -0
  67. package/src/shared/user-facing-codes.test.ts +140 -0
  68. package/src/shared/user-facing-codes.ts +276 -0
  69. package/src/tui/index.tsx +41 -8
  70. package/src/tui-compiled/index.tsx +660 -647
package/dist/index.js CHANGED
@@ -372,6 +372,13 @@ import {
372
372
  hasLengthCappedOutput,
373
373
  setKeepSubagents,
374
374
  teardownChildSession,
375
+ renderUserFacingFailure,
376
+ userFacingFailureCode,
377
+ renderCapabilityRefusal,
378
+ capabilityRefusalCode,
379
+ renderDreamFailure,
380
+ dreamFailureCode,
381
+ renderEmbeddingFailure,
375
382
  getCompartmentEvents,
376
383
  SYNAPSE_DEFAULT_MODEL,
377
384
  toSynapseLaneDescriptor,
@@ -533,7 +540,7 @@ import {
533
540
  setRecompTerminal2,
534
541
  runManagedRecomp2,
535
542
  runManagedUpgrade2
536
- } from "./index-c9hamh36.js";
543
+ } from "./index-1q9kay7n.js";
537
544
  import {
538
545
  stripJsonComments,
539
546
  isPrototypePollutionKey,
@@ -9191,7 +9198,13 @@ var HARNESS_KEYS = PER_HARNESS_MODEL_KEYS;
9191
9198
  var HISTORIAN_USER_ONLY_FIELDS = PER_HARNESS_MIGRATION_INVENTORY.historian.migrated_execution;
9192
9199
  var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
9193
9200
  var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools"];
9194
- var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
9201
+ var EMBEDDING_USER_ONLY_FIELDS = [
9202
+ "endpoint",
9203
+ "provider",
9204
+ "fallback_provider",
9205
+ "query_instruction",
9206
+ "document_prefix"
9207
+ ];
9195
9208
  var PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.";
9196
9209
  var TOKEN_THRESHOLD_REASON = "security: a repository may only raise execute_threshold_tokens above the user's trusted token threshold; it cannot force earlier historian work or cloned-repo cost escalation.";
9197
9210
  var TOKEN_THRESHOLD_INTRODUCTION_REASON = "security: a repository cannot introduce a new execute_threshold_tokens override when the user has no trusted token threshold for that key; that could force earlier historian work or cloned-repo cost escalation.";
@@ -9425,14 +9438,14 @@ function stripUnsafeProjectConfigFields(projectRaw) {
9425
9438
  const embedding = projectRaw.embedding;
9426
9439
  if (isPlainObject(embedding)) {
9427
9440
  const removed = [];
9428
- for (const field of EMBEDDING_DESTINATION_FIELDS) {
9441
+ for (const field of EMBEDDING_USER_ONLY_FIELDS) {
9429
9442
  if (field in embedding) {
9430
9443
  delete embedding[field];
9431
9444
  removed.push(field);
9432
9445
  }
9433
9446
  }
9434
9447
  if (removed.length > 0) {
9435
- warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where private text is embedded).");
9448
+ warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where or how private text is embedded).");
9436
9449
  }
9437
9450
  }
9438
9451
  for (const agentKey of HIDDEN_AGENT_KEYS) {
@@ -14925,12 +14938,12 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
14925
14938
  });
14926
14939
  } catch (error) {
14927
14940
  if (isRustAuthorityDrainingError(error)) {
14928
- throw new Error("Rust memory authority is not ready; TypeScript fallback is disabled.");
14941
+ throw new Error(renderCapabilityRefusal("memory_write"));
14929
14942
  }
14930
14943
  throw error;
14931
14944
  }
14932
14945
  if (isRustAuthorityDrainingError(applied)) {
14933
- throw new Error("Rust memory authority is not ready; TypeScript fallback is disabled.");
14946
+ throw new Error(renderCapabilityRefusal("memory_write"));
14934
14947
  }
14935
14948
  const applyResult = applied?.result ?? applied;
14936
14949
  if (!applyResult || typeof applyResult !== "object") {
@@ -18168,14 +18181,7 @@ function unescapeXml2(value) {
18168
18181
 
18169
18182
  // src/features/magic-context/dreamer/storage-dream-runs.ts
18170
18183
  function formatDreamRunFailure(failure) {
18171
- const parts = [failure.failure_class];
18172
- if (failure.model_attempted)
18173
- parts.push(`model: ${failure.model_attempted}`);
18174
- if (failure.provider_error)
18175
- parts.push(failure.provider_error.split(/\r?\n/, 1)[0].trim());
18176
- else if (failure.timeout_ms !== null)
18177
- parts.push(`timeout: ${failure.timeout_ms}ms`);
18178
- return parts.join(" · ");
18184
+ return renderDreamFailure(failure.failure_class);
18179
18185
  }
18180
18186
  var insertDreamRunStatements = new WeakMap;
18181
18187
  var getDreamRunsByProjectStatements = new Map;
@@ -19494,7 +19500,7 @@ function createDreamTaskExecutor(deps) {
19494
19500
  const { transient, brief } = classifyFailure(error);
19495
19501
  const failure = dreamRunFailureDetail(error);
19496
19502
  recordRun("failed", brief, { failure });
19497
- log(`[dreamer] task ${config.task} failed (transient=${transient}): ${brief}`);
19503
+ log(`[dreamer] task ${config.task} failed code=${dreamFailureCode(failure.failure_class)} (transient=${transient}): ${brief}`);
19498
19504
  return {
19499
19505
  status: "failed",
19500
19506
  transient,
@@ -20931,6 +20937,8 @@ var EMBEDDING_AFFECTING_KEYS = new Set([
20931
20937
  "embedding.truncate",
20932
20938
  "embedding.max_input_tokens",
20933
20939
  "embedding.query_input_type",
20940
+ "embedding.query_instruction",
20941
+ "embedding.document_prefix",
20934
20942
  "embedding.fallback_provider",
20935
20943
  "subc",
20936
20944
  "subc.connection_file",
@@ -21044,6 +21052,8 @@ function fallbackConfig(config, provider) {
21044
21052
  const apiKey = typeof raw.api_key === "string" ? raw.api_key.trim() : "";
21045
21053
  const inputType = typeof raw.input_type === "string" ? raw.input_type.trim() : "";
21046
21054
  const queryInputType = typeof raw.query_input_type === "string" ? raw.query_input_type.trim() : "";
21055
+ const queryInstruction = typeof raw.query_instruction === "string" || raw.query_instruction === false ? raw.query_instruction : undefined;
21056
+ const documentPrefix = typeof raw.document_prefix === "string" ? raw.document_prefix : undefined;
21047
21057
  const truncate = typeof raw.truncate === "string" ? raw.truncate.trim() : "";
21048
21058
  const maxInputTokens = typeof raw.max_input_tokens === "number" ? raw.max_input_tokens : undefined;
21049
21059
  if (provider === "off")
@@ -21056,6 +21066,8 @@ function fallbackConfig(config, provider) {
21056
21066
  ...apiKey ? { api_key: apiKey } : {},
21057
21067
  ...inputType ? { input_type: inputType } : {},
21058
21068
  ...queryInputType ? { query_input_type: queryInputType } : {},
21069
+ ...queryInstruction !== undefined ? { query_instruction: queryInstruction } : {},
21070
+ ...documentPrefix !== undefined ? { document_prefix: documentPrefix } : {},
21059
21071
  ...truncate ? { truncate } : {},
21060
21072
  ...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
21061
21073
  };
@@ -22217,7 +22229,8 @@ function getEmbedDrainUiStatus(sessionId, progress) {
22217
22229
  if (embedPauseBySession.has(sessionId)) {
22218
22230
  return { status: "paused" };
22219
22231
  }
22220
- if (progress?.kind === "embed" && progress.phase === "recomp") {
22232
+ const activeRun = embedRunStateBySession.get(sessionId);
22233
+ if (activeRun && !activeRun.signal.aborted || progress?.kind === "embed" && progress.phase === "recomp") {
22221
22234
  return { status: "running" };
22222
22235
  }
22223
22236
  if (progress?.kind === "embed" && (progress.phase === "failed" || progress.phase === "skipped") && progress.message) {
@@ -24793,10 +24806,122 @@ function formatCacheTtlDisplay(display) {
24793
24806
  // src/shared/rust-mode-status.ts
24794
24807
  var RUST_MODE_HOST_PATHS_LINE = "Host backends → MODULE: ctx_memory, ctx_note; historian: module-side";
24795
24808
 
24796
- // src/shared/status-detail-text.ts
24809
+ // src/shared/status-summary.ts
24810
+ function statusSummaryFromDetail(detail) {
24811
+ const compressionState = detail.compaction_enabled === false ? "off" : detail.historianRunning || detail.compartmentInProgress || detail.recompProgress?.phase === "recomp" && detail.recompProgress.kind !== "embed" ? "compressing" : detail.compartmentCount > 0 ? "ready" : "waiting";
24812
+ const warnings = [];
24813
+ if (detail.lastTransformError)
24814
+ warnings.push("transform_update_failed");
24815
+ if ((detail.historianFailureCount ?? 0) > 0)
24816
+ warnings.push("historian_unavailable");
24817
+ if ((detail.configParseFailures?.length ?? 0) > 0)
24818
+ warnings.push("configuration_warning");
24819
+ if (detail.embedding?.state === "stopped")
24820
+ warnings.push("embedding_unavailable");
24821
+ if ((detail.loggerDiagnostics?.swallowedWriteCount ?? 0) > 0) {
24822
+ warnings.push("status_log_unavailable");
24823
+ }
24824
+ return {
24825
+ inputTokens: detail.inputTokens,
24826
+ usableContextTokens: detail.contextLimit,
24827
+ usagePercentage: detail.usagePercentage,
24828
+ cacheLifetime: formatCacheTtlDisplay({
24829
+ value: detail.cacheTtl,
24830
+ source: detail.cacheTtlSource ?? "session",
24831
+ modelKey: detail.cacheTtlModelKey
24832
+ }).replace(/^Cache TTL:\s*/, ""),
24833
+ automaticCompressionThreshold: detail.compaction_enabled === false ? null : detail.executeThreshold,
24834
+ compression: {
24835
+ state: compressionState,
24836
+ historyBlockCount: detail.compartmentCount
24837
+ },
24838
+ reclaimable: {
24839
+ toolOutputCount: detail.tailHygiene?.reclaimableToolOutputCount ?? 0,
24840
+ tokens: detail.tailHygiene?.u ?? 0
24841
+ },
24842
+ memoryCount: detail.memoryCount,
24843
+ noteCount: (detail.sessionNoteCount ?? 0) + (detail.readySmartNoteCount ?? 0),
24844
+ embedding: detail.embedding ?? {
24845
+ state: "waiting",
24846
+ indexed: 0,
24847
+ total: 0
24848
+ },
24849
+ warnings: [...new Set(warnings)]
24850
+ };
24851
+ }
24797
24852
  function formatCount(value) {
24798
24853
  return Math.round(value).toLocaleString();
24799
24854
  }
24855
+ function compressionText(summary) {
24856
+ const historyBlocks = `${summary.compression.historyBlockCount} history block${summary.compression.historyBlockCount === 1 ? "" : "s"}`;
24857
+ switch (summary.compression.state) {
24858
+ case "off":
24859
+ return "Off";
24860
+ case "compressing":
24861
+ return `Compressing history · ${historyBlocks}`;
24862
+ case "ready":
24863
+ return `Ready · ${historyBlocks}`;
24864
+ case "waiting":
24865
+ return "Waiting for enough conversation history";
24866
+ }
24867
+ }
24868
+ function reclaimableText(summary) {
24869
+ const count = Math.max(0, Math.floor(summary.reclaimable.toolOutputCount));
24870
+ if (count === 0)
24871
+ return "none";
24872
+ const outputs = `${count} spent tool output${count === 1 ? "" : "s"}`;
24873
+ return `${outputs} (~${Math.round(Math.max(0, summary.reclaimable.tokens) / 1000)}k tokens)`;
24874
+ }
24875
+ function embeddingText(summary) {
24876
+ if (summary.embedding.state === "off")
24877
+ return "Off";
24878
+ const coverage = `${formatCount(summary.embedding.indexed)} / ${formatCount(summary.embedding.total)} history blocks indexed`;
24879
+ switch (summary.embedding.state) {
24880
+ case "running":
24881
+ return `Running · ${coverage}`;
24882
+ case "paused":
24883
+ return `Paused · ${coverage}`;
24884
+ case "stopped":
24885
+ return `Paused after an issue · ${coverage}`;
24886
+ case "ready":
24887
+ return `Ready · ${coverage}`;
24888
+ case "waiting":
24889
+ return `Waiting · ${coverage}`;
24890
+ }
24891
+ }
24892
+ function renderUserStatusSummary(summary, style) {
24893
+ const context = `${summary.usagePercentage.toFixed(1)}% of usable context (${formatCount(summary.inputTokens)} / ${summary.usableContextTokens > 0 ? formatCount(summary.usableContextTokens) : "?"} tokens)`;
24894
+ const values = [
24895
+ ["Context", context],
24896
+ ["Cache lifetime", summary.cacheLifetime],
24897
+ [
24898
+ "Automatic compression",
24899
+ summary.automaticCompressionThreshold === null ? "Off" : `at ${summary.automaticCompressionThreshold.toFixed(1)}% of usable context`
24900
+ ],
24901
+ ["History compression", compressionText(summary)],
24902
+ ["Reclaimable", reclaimableText(summary)],
24903
+ [
24904
+ "Memory",
24905
+ `${formatCount(summary.memoryCount)} memories · ${formatCount(summary.noteCount)} notes`
24906
+ ],
24907
+ ["Search indexing", embeddingText(summary)]
24908
+ ];
24909
+ const lines = style === "markdown" ? [
24910
+ "## Magic Context Status",
24911
+ "",
24912
+ ...values.map(([label, value]) => `- **${label}:** ${value}`)
24913
+ ] : ["Magic Context Status", ...values.map(([label, value]) => `${label}: ${value}`)];
24914
+ for (const warning of summary.warnings) {
24915
+ lines.push(style === "markdown" ? `- **Warning:** ${renderUserFacingFailure(warning)}` : `Warning: ${renderUserFacingFailure(warning)}`);
24916
+ }
24917
+ return lines.join(`
24918
+ `);
24919
+ }
24920
+
24921
+ // src/shared/status-detail-text.ts
24922
+ function formatCount2(value) {
24923
+ return Math.round(value).toLocaleString();
24924
+ }
24800
24925
  function formatCacheLane(detail) {
24801
24926
  if (detail.cacheNeverExpires)
24802
24927
  return `never expires; TTL ${detail.cacheTtl}`;
@@ -24807,7 +24932,10 @@ function formatCacheLane(detail) {
24807
24932
  return `live (${Math.round(detail.cacheRemainingMs / 1000)}s remaining); TTL ${detail.cacheTtl}`;
24808
24933
  }
24809
24934
  function formatStatusDetailMarkdown(detail) {
24810
- const usableLimit = detail.contextLimit > 0 ? `${formatCount(detail.contextLimit)} usable tokens` : "? usable tokens";
24935
+ return renderUserStatusSummary(statusSummaryFromDetail(detail), "markdown");
24936
+ }
24937
+ function formatStatusDiagnosticsMarkdown(detail) {
24938
+ const usableLimit = detail.contextLimit > 0 ? `${formatCount2(detail.contextLimit)} usable tokens` : "? usable tokens";
24811
24939
  const historianState = detail.historianRunning ? "running" : "idle";
24812
24940
  const historianDetails = [
24813
24941
  detail.boundaryPresent === undefined ? undefined : `boundary ${detail.boundaryPresent ? "present" : "absent"}`,
@@ -24825,19 +24953,19 @@ function formatStatusDetailMarkdown(detail) {
24825
24953
  "",
24826
24954
  `- **Mode:** ${mode}`,
24827
24955
  `- **Active profile:** ${detail.activeProfile ?? "none"}`,
24828
- `- **Usage:** ${detail.usagePercentage.toFixed(1)}% (${formatCount(detail.inputTokens)} / ${usableLimit})`,
24956
+ `- **Usage:** ${detail.usagePercentage.toFixed(1)}% (${formatCount2(detail.inputTokens)} / ${usableLimit})`,
24829
24957
  `- **${formatCacheTtlDisplay({ value: detail.cacheTtl, source: detail.cacheTtlSource ?? "session", modelKey: detail.cacheTtlModelKey })}**; ${formatCacheLane(detail)}`,
24830
24958
  `- **Historian:** ${[historianState, ...historianDetails].join("; ")}`,
24831
24959
  ...detail.hostBackendsModuleSide ? [`- ${RUST_MODE_HOST_PATHS_LINE}`] : [],
24832
- `- **Memory:** ${formatCount(detail.memoryCount)} active; ${formatCount(detail.memoryBlockCount)} injected`,
24833
- `- **Tags:** ${formatCount(detail.activeTags)} active, ${formatCount(detail.droppedTags)} dropped; ${formatCount(detail.pendingOpsCount)} pending drops`,
24960
+ `- **Memory:** ${formatCount2(detail.memoryCount)} active; ${formatCount2(detail.memoryBlockCount)} injected`,
24961
+ `- **Tags:** ${formatCount2(detail.activeTags)} active, ${formatCount2(detail.droppedTags)} dropped; ${formatCount2(detail.pendingOpsCount)} pending drops`,
24834
24962
  `- **Execute threshold:** ${detail.executeThreshold.toFixed(1)}%${detail.executeThresholdClamped ? " (clamped)" : ""}`
24835
24963
  ];
24836
24964
  if (detail.recompProgress?.phase === "recomp") {
24837
- lines.push(`- **${detail.recompProgress.kind === "embed" ? "Embed" : "Historian"} progress:** ${formatCount(detail.recompProgress.processedMessages)} / ${formatCount(detail.recompProgress.totalMessages)}`);
24965
+ lines.push(`- **${detail.recompProgress.kind === "embed" ? "Embed" : "Historian"} progress:** ${formatCount2(detail.recompProgress.processedMessages)} / ${formatCount2(detail.recompProgress.totalMessages)}`);
24838
24966
  }
24839
24967
  if (detail.lastTransformError) {
24840
- lines.push(`- **Last transform error:** ${detail.lastTransformError}`);
24968
+ lines.push(`- **Warning:** ${renderUserFacingFailure("transform_update_failed")}`);
24841
24969
  }
24842
24970
  return lines.join(`
24843
24971
  `);
@@ -24858,7 +24986,8 @@ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
24858
24986
  evaluable: rustBaseline.evaluable === true,
24859
24987
  generationInvalidated: rustBaseline.generation_invalidated === true,
24860
24988
  baselineGeneration: Math.max(0, finiteNumber(rustBaseline.baseline_generation)),
24861
- computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms))
24989
+ computedAt: Math.max(0, finiteNumber(rustBaseline.computed_at_ms)),
24990
+ reclaimableToolOutputCount: Math.max(0, Math.floor(finiteNumber(rustBaseline.reclaimable_tool_output_count)))
24862
24991
  };
24863
24992
  }
24864
24993
  if (tsBaseline === undefined)
@@ -24872,7 +25001,8 @@ function resolveTailHygieneStatus(tsBaseline, rustBaseline) {
24872
25001
  evaluable: tsBaseline.evaluable && !tsBaseline.generationInvalidated,
24873
25002
  generationInvalidated: tsBaseline.generationInvalidated,
24874
25003
  baselineGeneration: Math.max(0, tsBaseline.baselineGeneration),
24875
- computedAt: Math.max(0, tsBaseline.computedAt)
25004
+ computedAt: Math.max(0, tsBaseline.computedAt),
25005
+ reclaimableToolOutputCount: tsBaseline.baselineParts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length
24876
25006
  };
24877
25007
  }
24878
25008
  function formatTailHygiene(status) {
@@ -25313,7 +25443,7 @@ function executeStatus(db, sessionId, executeThresholdPercentageConfig = DEFAULT
25313
25443
  `- Drops: ${pendingOps.length}`,
25314
25444
  `- Total queued: ${pendingOps.length}`,
25315
25445
  "",
25316
- ...meta.lastTransformError ? ["### Last Transform Error", `- ${meta.lastTransformError}`, ""] : [],
25446
+ ...meta.lastTransformError ? ["### Warning", `- ${renderUserFacingFailure("transform_update_failed")}`, ""] : [],
25317
25447
  "### Cache TTL",
25318
25448
  `- ${formatCacheTtlDisplay(ttlDisplay)}`,
25319
25449
  `- Last response: ${meta.lastResponseTime > 0 ? `${Math.round(elapsed / 1000)}s ago` : "never"}`,
@@ -25352,6 +25482,30 @@ ${c.content}
25352
25482
  }
25353
25483
  const budgetTokens = historyBudgetPercentage && displayContextLimit > 0 ? Math.floor(displayContextLimit * (Math.min(executeThresholdPercentage, 80) / 100) * historyBudgetPercentage) : null;
25354
25484
  const budgetUsage = budgetTokens ? (historyBlockTokens / budgetTokens * 100).toFixed(0) : null;
25485
+ if (display?.diagnostics === false) {
25486
+ return renderUserStatusSummary({
25487
+ inputTokens: displayInputTokens,
25488
+ usableContextTokens: displayContextLimit,
25489
+ usagePercentage: displayPercentage,
25490
+ cacheLifetime: formatCacheTtlDisplay(ttlDisplay).replace(/^Cache TTL:\s*/, ""),
25491
+ automaticCompressionThreshold: display?.compactionEnabled === false ? null : thresholdDetail.percentage,
25492
+ compression: {
25493
+ state: meta.compartmentInProgress ? "compressing" : compartments.length > 0 ? "ready" : "waiting",
25494
+ historyBlockCount: compartments.length
25495
+ },
25496
+ reclaimable: {
25497
+ toolOutputCount: tailHygiene?.reclaimableToolOutputCount ?? 0,
25498
+ tokens: tailHygiene?.u ?? 0
25499
+ },
25500
+ memoryCount: 0,
25501
+ noteCount: 0,
25502
+ embedding: { state: "waiting", indexed: 0, total: 0 },
25503
+ warnings: [
25504
+ ...meta.lastTransformError ? ["transform_update_failed"] : [],
25505
+ ...parseFailureLines.length > 0 ? ["configuration_warning"] : []
25506
+ ]
25507
+ }, "markdown");
25508
+ }
25355
25509
  lines.push("", "### History Compression", `- Compartments: ${compartments.length}`, `- History block: ~${historyBlockTokens.toLocaleString()} tokens`, ...budgetTokens ? [
25356
25510
  `- History budget: ~${budgetTokens.toLocaleString()} tokens (${budgetUsage}% used)`,
25357
25511
  `- Older compartments demote tiers automatically at render time to fit the budget`
@@ -25371,14 +25525,14 @@ ${c.content}
25371
25525
  return lines.join(`
25372
25526
  `);
25373
25527
  } catch (error) {
25374
- sessionLog(sessionId, "ctx-status failed:", error);
25375
- return `Error: Failed to read context status. ${getErrorMessage(error)}`;
25528
+ sessionLog(sessionId, `ctx-status failed code=${userFacingFailureCode("status_unavailable")}: ${getErrorMessage(error)}`);
25529
+ return `Error: ${renderUserFacingFailure("status_unavailable")}`;
25376
25530
  }
25377
25531
  }
25378
25532
 
25379
25533
  // src/hooks/magic-context/maintenance-authority.ts
25380
- var RUST_SESSION_UPGRADE_REFUSAL = "Session upgrade is unavailable while Rust transform authority is active. The module owns compartment and memory state; switch authority through the documented drain flow before upgrading.";
25381
- var RUST_PARTIAL_RECOMP_REFUSAL = "Partial recomp is unavailable while Rust transform authority is active. The module supports only a full-session recomp; no state was changed.";
25534
+ var RUST_SESSION_UPGRADE_REFUSAL = renderCapabilityRefusal("session_upgrade");
25535
+ var RUST_PARTIAL_RECOMP_REFUSAL = renderCapabilityRefusal("partial_history");
25382
25536
 
25383
25537
  // src/hooks/magic-context/command-handler.ts
25384
25538
  var recompConfirmationBySession = new Map;
@@ -25449,7 +25603,10 @@ function parseWrapupArgs(raw) {
25449
25603
  return { ok: true, messagesToKeep };
25450
25604
  }
25451
25605
  var commandArgumentValidators = {
25452
- "ctx-status": (raw) => raw.trim() === "",
25606
+ "ctx-status": (raw) => {
25607
+ const mode = raw.trim().toLowerCase();
25608
+ return mode === "" || mode === "diagnostics";
25609
+ },
25453
25610
  "ctx-recomp": (raw) => parseRecompArgs(raw).kind !== "error",
25454
25611
  "ctx-wrapup": (raw) => parseWrapupArgs(raw).ok,
25455
25612
  "ctx-session-upgrade": (raw) => raw.trim() === "",
@@ -25524,11 +25681,11 @@ ${summary || "Nothing to compact."}`;
25524
25681
  case "retryable":
25525
25682
  return `## Magic Wrapup — Partial
25526
25683
 
25527
- ${summary || "Wrapup made progress but stopped before the keep watermark."} Run /ctx-wrapup again to continue.`;
25684
+ ${renderCapabilityRefusal("history_compression")}`;
25528
25685
  default:
25529
25686
  return `## Magic Wrapup — Failed
25530
25687
 
25531
- ${summary || "Wrapup failed; try /ctx-wrapup again."}${rounds > 0 ? ` (${rounds} round${rounds === 1 ? "" : "s"})` : ""}`;
25688
+ ${renderCapabilityRefusal("history_compression")}`;
25532
25689
  }
25533
25690
  }
25534
25691
  switch (disposition) {
@@ -25539,7 +25696,7 @@ Recomp started. Rebuilding the compressed history from raw session history now;
25539
25696
  case "already_in_progress":
25540
25697
  return `## Magic Recomp — Skipped
25541
25698
 
25542
- Historian recomp is already running for this session. Wait for it to finish, then try /ctx-recomp again.`;
25699
+ History compression is already running for this session. Wait for it to finish, then try /ctx-recomp again.`;
25543
25700
  case "nothing_to_do":
25544
25701
  return `## Magic Recomp
25545
25702
 
@@ -25547,7 +25704,7 @@ Nothing to rebuild: this session has no published compartments.`;
25547
25704
  default:
25548
25705
  return `## Magic Recomp — Failed
25549
25706
 
25550
- ${summary || "Historian recomp failed; try /ctx-recomp again."}`;
25707
+ ${renderCapabilityRefusal("history_compression")}`;
25551
25708
  }
25552
25709
  }
25553
25710
  function formatRustStatusText(value) {
@@ -25656,8 +25813,15 @@ Unknown task "${requested}". Valid tasks: ${CANONICAL_DREAM_TASKS.join(", ")}.`,
25656
25813
  formatDreamTaskBacklogs(backlogBefore, backlogTasks)
25657
25814
  ].join(`
25658
25815
  `), dreamNotificationParams);
25659
- const summary = await deps.dreamer.runManual(task);
25660
- await deps.sendNotification(sessionId, summarizeManualDream(summary), dreamNotificationParams);
25816
+ try {
25817
+ const summary = await deps.dreamer.runManual(task);
25818
+ await deps.sendNotification(sessionId, summarizeManualDream(summary), dreamNotificationParams);
25819
+ } catch (error) {
25820
+ sessionLog(sessionId, `ctx-dream failed code=${userFacingFailureCode("dream_unknown")}`, error);
25821
+ await deps.sendNotification(sessionId, `## /ctx-dream
25822
+
25823
+ ${renderUserFacingFailure("dream_unknown")}`, dreamNotificationParams);
25824
+ }
25661
25825
  throwSentinel("CTX-DREAM");
25662
25826
  }
25663
25827
  function createMagicContextCommandHandler(deps) {
@@ -25756,7 +25920,8 @@ Embedding status is unavailable.`;
25756
25920
  });
25757
25921
  result = value.armed === false ? "No pending operations to flush." : "Flushed: Changes take effect on next message.";
25758
25922
  } catch (error) {
25759
- result = `Error: Failed to flush context operations. ${error instanceof Error ? error.message : String(error)}`;
25923
+ sessionLog(sessionId, `ctx-flush failed code=${capabilityRefusalCode("context_cleanup")}`, error);
25924
+ result = renderCapabilityRefusal("context_cleanup");
25760
25925
  }
25761
25926
  } else {
25762
25927
  result = executeFlush(deps.db, sessionId);
@@ -25769,6 +25934,7 @@ Embedding status is unavailable.`;
25769
25934
  }
25770
25935
  }
25771
25936
  if (isStatus) {
25937
+ const statusDiagnostics = input.arguments.trim().toLowerCase() === "diagnostics";
25772
25938
  let rustStatus;
25773
25939
  if (rustMode) {
25774
25940
  try {
@@ -25782,7 +25948,7 @@ Embedding status is unavailable.`;
25782
25948
  }
25783
25949
  }
25784
25950
  if (isTuiConnected2(sessionId)) {
25785
- pushNotification2("action", { action: "show-status-dialog" }, sessionId);
25951
+ pushNotification2("action", { action: "show-status-dialog", diagnostics: statusDiagnostics }, sessionId);
25786
25952
  sessionLog(sessionId, "command ctx-status: pushed show-status-dialog to TUI");
25787
25953
  throwSentinel(input.command);
25788
25954
  }
@@ -25792,9 +25958,9 @@ Embedding status is unavailable.`;
25792
25958
  if (rustMode && !rustStatus) {
25793
25959
  combinedStatus = `## Magic Status — Unavailable
25794
25960
 
25795
- Rust module status could not be read. Canonical session usage, tags, and compartments live in mc-store, so context.db mirror values are intentionally omitted.`;
25961
+ ${renderUserFacingFailure("status_unavailable")}`;
25796
25962
  } else if (detail) {
25797
- combinedStatus = formatStatusDetailMarkdown(detail);
25963
+ combinedStatus = statusDiagnostics ? formatStatusDiagnosticsMarkdown(detail) : formatStatusDetailMarkdown(detail);
25798
25964
  } else {
25799
25965
  const liveModelKey = deps.getLiveModelKey?.(sessionId);
25800
25966
  const liveContextLimit = deps.getContextLimit?.(sessionId);
@@ -25808,12 +25974,14 @@ Rust module status could not be read. Canonical session usage, tags, and compart
25808
25974
  } : undefined, windowGeometry, tailHygiene, undefined, Boolean(rustMode), {
25809
25975
  cacheTtlConfig: deps.cacheTtlConfig ?? "5m",
25810
25976
  cacheTtlConfigured: deps.cacheTtlConfigured === true,
25811
- configParseFailures: deps.configParseFailures ?? []
25977
+ configParseFailures: deps.configParseFailures ?? [],
25978
+ diagnostics: statusDiagnostics,
25979
+ compactionEnabled: !deps.compactionOff
25812
25980
  });
25813
- const moduleStatus = rustStatus ? `
25981
+ const moduleStatus = rustStatus && statusDiagnostics ? `
25814
25982
 
25815
25983
  ${formatRustStatusText(rustStatus)}` : "";
25816
- const modeStatus = deps.compactionOff ? `**Compaction:** disabled (${COMPACTION_ENABLED_PATH}: false) — native compaction owns the context window.
25984
+ const modeStatus = deps.compactionOff && statusDiagnostics ? `**Compaction:** disabled (${COMPACTION_ENABLED_PATH}: false) — native compaction owns the context window.
25817
25985
 
25818
25986
  ` : "";
25819
25987
  combinedStatus = `${modeStatus}${statusOutput}${moduleStatus}`;
@@ -25822,7 +25990,7 @@ ${formatRustStatusText(rustStatus)}` : "";
25822
25990
  sessionLog(sessionId, "shared ctx-status detail failed; using compatibility text:", error);
25823
25991
  combinedStatus = rustMode ? `## Magic Status — Unavailable
25824
25992
 
25825
- Rust module status failed while formatting. Canonical session usage, tags, and compartments live in mc-store, so context.db mirror values are intentionally omitted.` : executeStatus(deps.db, sessionId);
25993
+ ${renderUserFacingFailure("status_unavailable")}` : executeStatus(deps.db, sessionId);
25826
25994
  }
25827
25995
  result += result ? `
25828
25996
 
@@ -25853,9 +26021,10 @@ Starting wrapup…`, {});
25853
26021
  }, MAX_WRAPUP_REQUEST_BUDGET_MS);
25854
26022
  result = formatRustOperationMessage("wrapup", value);
25855
26023
  } catch (error) {
26024
+ sessionLog(sessionId, `ctx-wrapup failed code=${capabilityRefusalCode("history_compression")}`, error);
25856
26025
  result = `## Magic Wrapup — Failed
25857
26026
 
25858
- ${error instanceof Error ? error.message : String(error)}`;
26027
+ ${renderCapabilityRefusal("history_compression")}`;
25859
26028
  }
25860
26029
  } else if (!deps.executeWrapup) {
25861
26030
  result = `## Magic Wrapup
@@ -25889,9 +26058,10 @@ ${RUST_PARTIAL_RECOMP_REFUSAL}`;
25889
26058
  });
25890
26059
  result = formatRustOperationMessage("recomp", value);
25891
26060
  } catch (error) {
26061
+ sessionLog(sessionId, `ctx-recomp failed code=${capabilityRefusalCode("history_compression")}`, error);
25892
26062
  result = `## Magic Recomp — Failed
25893
26063
 
25894
- ${error instanceof Error ? error.message : String(error)}`;
26064
+ ${renderCapabilityRefusal("history_compression")}`;
25895
26065
  }
25896
26066
  } else if (isTuiConnected2(sessionId)) {
25897
26067
  pushNotification2("action", { action: "show-recomp-dialog" }, sessionId);
@@ -28697,6 +28867,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28697
28867
  lastResponseTime: 0,
28698
28868
  lastNudgeTokens: 0,
28699
28869
  lastTransformError: null,
28870
+ historianFailureCount: 0,
28700
28871
  isSubagent: false,
28701
28872
  pendingOps: [],
28702
28873
  contextLimit: 0,
@@ -28742,6 +28913,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28742
28913
  detail.lastResponseTime = Number(meta.last_response_time ?? 0);
28743
28914
  detail.lastNudgeTokens = Number(meta.last_nudge_tokens ?? 0);
28744
28915
  detail.lastTransformError = meta.last_transform_error ? String(meta.last_transform_error) : null;
28916
+ detail.historianFailureCount = Number(meta.historian_failure_count ?? 0);
28745
28917
  detail.isSubagent = Boolean(meta.is_subagent);
28746
28918
  persistedCacheTtl = typeof meta.cache_ttl === "string" && meta.cache_ttl.length > 0 ? meta.cache_ttl : "5m";
28747
28919
  persistedModelKey = typeof meta.last_observed_model_key === "string" && meta.last_observed_model_key.length > 0 ? meta.last_observed_model_key : null;
@@ -28821,6 +28993,19 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessi
28821
28993
  detail.cacheExpired = detail.cacheRemainingMs === 0;
28822
28994
  }
28823
28995
  }
28996
+ if (base.projectIdentity) {
28997
+ try {
28998
+ const coverage = getEmbeddingCoverageStatus(db, base.projectIdentity, sessionId);
28999
+ const runState = getEmbedDrainUiStatus(sessionId, base.recompProgress ?? undefined).status;
29000
+ detail.embedding = {
29001
+ state: !coverage.enabled ? "off" : runState !== "idle" ? runState : coverage.session.total > 0 && coverage.session.embedded >= coverage.session.total ? "ready" : "waiting",
29002
+ indexed: coverage.session.embedded,
29003
+ total: coverage.session.total
29004
+ };
29005
+ } catch {
29006
+ detail.embedding = { state: "waiting", indexed: 0, total: 0 };
29007
+ }
29008
+ }
28824
29009
  try {
28825
29010
  const histTokens = base.compartmentTokens + base.factTokens;
28826
29011
  detail.historyBlockTokens = histTokens;
@@ -29158,7 +29343,7 @@ function registerRpcHandlers(rpcServer, args) {
29158
29343
  const db = getDb();
29159
29344
  if (!db)
29160
29345
  return { ok: false, error: "db unavailable" };
29161
- const { runManagedRecomp } = await import("./recomp-orchestrator-3atsasjy.js");
29346
+ const { runManagedRecomp } = await import("./recomp-orchestrator-m33b3rk9.js");
29162
29347
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29163
29348
  log(`[rpc] recomp requested for session ${sessionId}`);
29164
29349
  const ctx = await buildManagedCtx(db);
@@ -29177,7 +29362,7 @@ function registerRpcHandlers(rpcServer, args) {
29177
29362
  const db = getDb();
29178
29363
  if (!db)
29179
29364
  return { ok: false, error: "db unavailable" };
29180
- const { runManagedUpgrade } = await import("./recomp-orchestrator-3atsasjy.js");
29365
+ const { runManagedUpgrade } = await import("./recomp-orchestrator-m33b3rk9.js");
29181
29366
  const { sendIgnoredMessage } = await import("./send-session-notification-1qeqkswb.js");
29182
29367
  log(`[rpc] session-upgrade requested for session ${sessionId}`);
29183
29368
  const ctx = await buildManagedCtx(db);
@@ -38238,37 +38423,10 @@ function createEventHandler2(deps) {
38238
38423
  }
38239
38424
 
38240
38425
  // src/hooks/magic-context/format-embed-failure.ts
38241
- function formatEmbedFailureSummary(embedded, remaining, failure) {
38242
- const compartment = `compartment${embedded === 1 ? "" : "s"}`;
38243
- if (!failure) {
38244
- return `Embedded ${embedded} ${compartment}; ${remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`;
38245
- }
38246
- const retry = " Run /ctx-embed start again to retry them.";
38247
- switch (failure.class) {
38248
- case "substitution_rejected":
38249
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: set embedding.model to the served spelling.`;
38250
- case "http_error": {
38251
- 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.";
38252
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${fix}`;
38253
- }
38254
- case "invalid_envelope":
38255
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: configure an OpenAI-compatible embedding endpoint that returns data[].embedding.`;
38256
- case "certification_refusal":
38257
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: recertify SYNAPSE or configure embedding.fallback_provider, then run /ctx-embed start again.`;
38258
- case "credential_required":
38259
- return `Embedded ${embedded} ${compartment}; ${remaining} rejected: ${failure.reason}. Fix: reauthenticate SYNAPSE, then run /ctx-embed start again.`;
38260
- case "local_binding_missing":
38261
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` to verify the WASM fallback. On Intel macOS, onnxruntime-node@1.23.0 may be pinned manually for optional native speed.`;
38262
- case "local_fs_unavailable":
38263
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: update or reinstall Magic Context so its Node WASM bundle can persist the model, then run /ctx-embed start again.`;
38264
- case "local_download_failure":
38265
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: check network/proxy access to the model host.${retry}`;
38266
- case "local_runtime_error":
38267
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}. Fix: run \`npx @cortexkit/magic-context@latest doctor\` for local runtime diagnostics.`;
38268
- case "empty_result":
38269
- case "transport_error":
38270
- return `Embedded ${embedded} ${compartment}; ${remaining} failed: ${failure.reason}.${failure.retryable ? retry : ""}`;
38271
- }
38426
+ function formatEmbedFailureSummary(embedded, remaining, failure, style = "markdown") {
38427
+ const historyBlocks = `history block${embedded === 1 ? "" : "s"}`;
38428
+ const progress = `Indexed ${embedded} ${historyBlocks}; ${remaining} remain.`;
38429
+ return `${progress} ${renderEmbeddingFailure(failure?.class ?? "empty_result", style)}`;
38272
38430
  }
38273
38431
 
38274
38432
  // src/hooks/magic-context/text-complete.ts
@@ -40702,13 +40860,9 @@ function normalizeCategory(category) {
40702
40860
  const trimmed = category?.trim();
40703
40861
  return trimmed ? trimmed : undefined;
40704
40862
  }
40705
- function memoryAuthorityRefusal(args, cause) {
40706
- const readiness = "Rust memory authority is not ready.";
40707
- const refusal = (args.action === "write" || args.action === "update" || args.action === "merge") && typeof args.content === "string" ? `Error: ${readiness} Write REFUSED and NOT saved; RESEND the same call after authority is ready; the Rust module typically recovers in seconds-to-minutes.
40708
- Content to resend:
40709
- ${args.content}` : `Error: ${readiness} Request REFUSED and NOT applied; RESEND the same call after authority is ready; the Rust module typically recovers in seconds-to-minutes.`;
40710
- return cause ? `${cause}
40711
- ${refusal}` : refusal;
40863
+ function memoryAuthorityRefusal(args) {
40864
+ const isMutation = args.action !== undefined && ["write", "update", "archive", "merge"].includes(args.action);
40865
+ return renderCapabilityRefusal(isMutation ? "memory_write" : "memory_access");
40712
40866
  }
40713
40867
  function moduleMemoryText(response, args) {
40714
40868
  let value = response;
@@ -40990,14 +41144,14 @@ function createCtxMemoryTool(deps) {
40990
41144
  }) ?? null;
40991
41145
  } catch (error) {
40992
41146
  if (marker) {
40993
- const detail = error instanceof Error ? error.message : String(error);
40994
- return memoryAuthorityRefusal(args, `Error: Rust memory authority is unavailable. ${detail}`);
41147
+ sessionLog(toolContext.sessionID, "ctx_memory capability refusal", error);
41148
+ return memoryAuthorityRefusal(args);
40995
41149
  }
40996
41150
  }
40997
41151
  if (authorityState === "MODULE") {
40998
41152
  const memoryBackend = deps.rustToolBackends?.memory;
40999
41153
  if (!memoryBackend) {
41000
- return "Error: Rust memory authority is active, but this module transport does not support ctx_memory.";
41154
+ return memoryAuthorityRefusal(args);
41001
41155
  }
41002
41156
  try {
41003
41157
  const commandId = toolCallIdFromContext(toolContext);
@@ -41024,13 +41178,13 @@ function createCtxMemoryTool(deps) {
41024
41178
  ids: moduleArgs.ids,
41025
41179
  reason: moduleArgs.reason
41026
41180
  }), moduleArgs);
41027
- return text ?? "Error: Rust module returned an invalid ctx_memory response.";
41181
+ return text ?? memoryAuthorityRefusal(args);
41028
41182
  } catch (error) {
41029
41183
  if (isRustAuthorityDrainingError(error)) {
41030
41184
  return memoryAuthorityRefusal(args);
41031
41185
  }
41032
- const detail = error instanceof Error ? error.message : String(error);
41033
- return memoryAuthorityRefusal(args, `Error: Rust module ctx_memory failed. ${detail}`);
41186
+ sessionLog(toolContext.sessionID, "ctx_memory capability refusal", error);
41187
+ return memoryAuthorityRefusal(args);
41034
41188
  }
41035
41189
  }
41036
41190
  if (marker || authorityState === "PREPARING" || authorityState === "DRAINING") {
@@ -41961,14 +42115,9 @@ ${footer}` : ""}`);
41961
42115
  }
41962
42116
  return sections;
41963
42117
  }
41964
- function noteAuthorityRefusal(args, action) {
41965
- const readiness = "Rust notes authority is not ready.";
41966
- if ((action === "write" || action === "update") && typeof args.content === "string") {
41967
- return `Error: ${readiness} Write REFUSED and NOT saved; RESEND after authority is ready.
41968
- Content to resend:
41969
- ${args.content}`;
41970
- }
41971
- return `Error: ${readiness} Request REFUSED and NOT applied; RESEND after authority is ready.`;
42118
+ function noteAuthorityRefusal(_args, action) {
42119
+ const isMutation = action === "write" || action === "update" || action === "dismiss";
42120
+ return renderCapabilityRefusal(isMutation ? "note_change" : "note_access");
41972
42121
  }
41973
42122
  function moduleNoteText(response, args, action) {
41974
42123
  let value = response;
@@ -42066,19 +42215,20 @@ function createCtxNoteTool(deps) {
42066
42215
  });
42067
42216
  } catch (error) {
42068
42217
  if (marker) {
42069
- return `Error: Rust notes authority is unavailable. ${error instanceof Error ? error.message : String(error)}`;
42218
+ sessionLog(sessionId, "ctx_note capability refusal", error);
42219
+ return noteAuthorityRefusal(args, action);
42070
42220
  }
42071
42221
  }
42072
42222
  }
42073
42223
  if (notesAuthority === "MODULE") {
42074
42224
  const rustNote = deps.rustToolBackends?.note;
42075
42225
  if (!rustNote || !projectIdentity) {
42076
- return "Error: Rust notes authority is active, but this module transport does not support ctx_note.";
42226
+ return noteAuthorityRefusal(args, action);
42077
42227
  }
42078
42228
  let compilation;
42079
42229
  if ((action === "write" || action === "update") && surfaceCondition) {
42080
42230
  if (deps.rustToolBackends?.noteEvaluationAvailable?.(projectIdentity) !== true) {
42081
- return "Error: Smart-note evaluation is unavailable for this Rust-authority project; the note was not written.";
42231
+ return renderCapabilityRefusal("smart_note_condition");
42082
42232
  }
42083
42233
  compilation = await compileSurfaceCondition(surfaceCondition, {
42084
42234
  projectPath: toolContext.directory
@@ -42104,7 +42254,7 @@ function createCtxNoteTool(deps) {
42104
42254
  try {
42105
42255
  const text = moduleNoteText(await rustNote(request), args, action);
42106
42256
  if (text === null) {
42107
- return "Error: Rust module returned an invalid ctx_note response.";
42257
+ return noteAuthorityRefusal(args, action);
42108
42258
  }
42109
42259
  if (text.startsWith("Error:"))
42110
42260
  return text;
@@ -42119,7 +42269,8 @@ wake plane active — create a scheduled wake instead; stored as a plain note.`;
42119
42269
  if (isRustAuthorityDrainingError(error)) {
42120
42270
  return noteAuthorityRefusal(args, action);
42121
42271
  }
42122
- return `Error: Rust module ctx_note failed. ${error instanceof Error ? error.message : String(error)}`;
42272
+ sessionLog(sessionId, "ctx_note capability refusal", error);
42273
+ return noteAuthorityRefusal(args, action);
42123
42274
  }
42124
42275
  }
42125
42276
  if (marker || notesAuthority === "PREPARING" || notesAuthority === "DRAINING") {
@@ -42375,7 +42526,8 @@ function createCtxReduceTool(deps) {
42375
42526
  const error = record && "error" in record ? record.error : undefined;
42376
42527
  const errorRecord = error !== null && typeof error === "object" ? error : undefined;
42377
42528
  const message = (typeof error === "string" && error.trim() ? error : undefined) ?? (typeof errorRecord?.message === "string" && errorRecord.message.trim() ? errorRecord.message : undefined) ?? (typeof record?.message === "string" && record.message.trim() ? record.message : "module rejected agent_drops.append");
42378
- return `Error: Failed to queue ctx_reduce operations. ${message}`;
42529
+ sessionLog(sessionId, "ctx_reduce capability refusal", message);
42530
+ return renderCapabilityRefusal("context_cleanup");
42379
42531
  }
42380
42532
  const queued = typeof record.queued === "number" ? record.queued : 0;
42381
42533
  if (queued <= 0) {
@@ -42383,7 +42535,8 @@ function createCtxReduceTool(deps) {
42383
42535
  }
42384
42536
  return `Queued: drop ${formatRawDropForAck(args.drop)}.`;
42385
42537
  } catch (error) {
42386
- return `Error: Failed to queue ctx_reduce operations. ${getErrorMessage(error)}`;
42538
+ sessionLog(sessionId, "ctx_reduce capability refusal", error);
42539
+ return renderCapabilityRefusal("context_cleanup");
42387
42540
  }
42388
42541
  }
42389
42542
  let dropIds = [];
@@ -43454,6 +43607,9 @@ var server = async (ctx) => {
43454
43607
  return;
43455
43608
  recordToolDefinition(lastChatContext.providerID, lastChatContext.modelID, lastChatContext.agentName, typedInput.toolID, typeof typedOutput.description === "string" ? typedOutput.description : "", typedOutput.parameters);
43456
43609
  },
43610
+ "tool.execute.before": async (input, output) => {
43611
+ await magicContextRuntime.magicContext?.["tool.execute.before"]?.(input, output);
43612
+ },
43457
43613
  "tool.execute.after": async (input, output) => {
43458
43614
  await magicContextRuntime.magicContext?.["tool.execute.after"]?.(input, output);
43459
43615
  },