@cortexkit/opencode-magic-context 0.34.2 → 0.35.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.
- package/README.md +3 -1
- package/dist/agents/hidden-agent-registrations.d.ts +10 -2
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +2 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +4 -3
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +3 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/agent-overrides.d.ts +1 -1
- package/dist/config/schema/magic-context.d.ts +51 -10
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-fvpfvt0w.js → conflict-warning-hook-p2pmhvn7.js} +2 -1
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +15 -0
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts +6 -2
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts +4 -4
- package/dist/hooks/magic-context/compartment-prompt.d.ts +6 -6
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -14
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +16 -2
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +10 -3
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +2 -1
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +5 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +2 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +6 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +19 -5
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +3 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index-0c9dmw9m.js +116 -0
- package/dist/{index-dtas91s5.js → index-8aaadh98.js} +7 -119
- package/dist/index-dpdnjawy.js +2892 -0
- package/dist/{index-z70pxrq1.js → index-fkyamz2w.js} +732 -613
- package/dist/{index-cn960ffd.js → index-h5zjfesc.js} +1 -1
- package/dist/{index-fcyvznch.js → index-w0nygb4p.js} +45 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +843 -818
- package/dist/plugin/hooks/create-session-hooks.d.ts +12 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +1 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts +4 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-6cd3nrt7.js → recomp-orchestrator-29f4rqax.js} +5 -4
- package/dist/{send-session-notification-6njqewzk.js → send-session-notification-sr5g06hz.js} +2 -2
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/prompt-surface-a1-golden.d.ts +28 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +43 -0
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
- package/dist/shared/prompt-surface.d.ts +49 -0
- package/dist/shared/prompt-surface.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +13 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/{storage-meta-session-xt41zbw4.js → storage-meta-session-ev8b55a9.js} +2 -2
- package/dist/tools/ctx-expand/tools.d.ts +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts +1 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts +1 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +1 -0
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts +1 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +6 -0
- package/dist/tools/light-descriptions.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/agents/hidden-agent-registrations.ts +49 -1
- package/src/agents/magic-context-prompt.test.ts +144 -0
- package/src/agents/magic-context-prompt.ts +53 -2
- package/src/agents/permissions.ts +4 -3
- package/src/config/index.test.ts +53 -0
- package/src/config/index.ts +4 -0
- package/src/config/project-security.test.ts +20 -0
- package/src/config/project-security.ts +23 -0
- package/src/config/schema/magic-context.test.ts +58 -0
- package/src/config/schema/magic-context.ts +61 -1
- package/src/shared/index.ts +2 -0
- package/src/shared/prompt-surface-a1-golden.md +458 -0
- package/src/shared/prompt-surface-a1-golden.ts +41 -0
- package/src/shared/prompt-surface-runtime.test.ts +141 -0
- package/src/shared/prompt-surface-runtime.ts +250 -0
- package/src/shared/prompt-surface.test.ts +109 -0
- package/src/shared/prompt-surface.ts +138 -0
- package/src/shared/sqlite.test.ts +32 -0
- package/src/shared/sqlite.ts +85 -9
- package/dist/index-b563sga5.js +0 -134784
|
@@ -290,3 +290,147 @@ describe("buildMagicContextSection — compaction-off guidance variant (#266 S4)
|
|
|
290
290
|
expect(reduce).toContain("tagged with §N§ identifiers");
|
|
291
291
|
});
|
|
292
292
|
});
|
|
293
|
+
|
|
294
|
+
describe("buildMagicContextSection — prompt-surface composition", () => {
|
|
295
|
+
it("keeps full bytes stable while serving compressed light guidance", () => {
|
|
296
|
+
const implicit = buildMagicContextSection(
|
|
297
|
+
null,
|
|
298
|
+
20,
|
|
299
|
+
true,
|
|
300
|
+
true,
|
|
301
|
+
true,
|
|
302
|
+
true,
|
|
303
|
+
false,
|
|
304
|
+
"tr",
|
|
305
|
+
true,
|
|
306
|
+
);
|
|
307
|
+
const explicitFull = buildMagicContextSection(
|
|
308
|
+
null,
|
|
309
|
+
20,
|
|
310
|
+
true,
|
|
311
|
+
true,
|
|
312
|
+
true,
|
|
313
|
+
true,
|
|
314
|
+
false,
|
|
315
|
+
"tr",
|
|
316
|
+
true,
|
|
317
|
+
"full",
|
|
318
|
+
);
|
|
319
|
+
const light = buildMagicContextSection(
|
|
320
|
+
null,
|
|
321
|
+
20,
|
|
322
|
+
true,
|
|
323
|
+
true,
|
|
324
|
+
true,
|
|
325
|
+
true,
|
|
326
|
+
false,
|
|
327
|
+
"tr",
|
|
328
|
+
true,
|
|
329
|
+
"light",
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
expect(explicitFull).toBe(implicit);
|
|
333
|
+
expect(light).not.toBe(implicit);
|
|
334
|
+
expect(light).toContain("In primary sessions with ctx_reduce");
|
|
335
|
+
expect(light).toContain("NEVER narrate ctx_reduce");
|
|
336
|
+
expect(light).toContain("DO NOT mimic this style");
|
|
337
|
+
expect(light).toContain("Keep code, identifiers, file paths");
|
|
338
|
+
expect(light).not.toContain("### Reduction Triggers");
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("keeps feature-gated and shared fragments orthogonal to light", () => {
|
|
342
|
+
const light = (options: {
|
|
343
|
+
reduce?: boolean;
|
|
344
|
+
dreamer?: boolean;
|
|
345
|
+
temporal?: boolean;
|
|
346
|
+
caveman?: boolean;
|
|
347
|
+
subagent?: boolean;
|
|
348
|
+
language?: string;
|
|
349
|
+
memory?: boolean;
|
|
350
|
+
}) =>
|
|
351
|
+
buildMagicContextSection(
|
|
352
|
+
null,
|
|
353
|
+
20,
|
|
354
|
+
options.reduce ?? true,
|
|
355
|
+
options.dreamer ?? false,
|
|
356
|
+
options.temporal ?? false,
|
|
357
|
+
options.caveman ?? false,
|
|
358
|
+
options.subagent ?? false,
|
|
359
|
+
options.language,
|
|
360
|
+
options.memory ?? true,
|
|
361
|
+
"light",
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
const memoryOff = light({ memory: false });
|
|
365
|
+
expect(memoryOff).not.toContain("Use `ctx_memory`");
|
|
366
|
+
expect(memoryOff).toContain("ctx_search");
|
|
367
|
+
|
|
368
|
+
const noReduce = light({ reduce: false });
|
|
369
|
+
expect(noReduce).not.toContain("In primary sessions with ctx_reduce");
|
|
370
|
+
expect(noReduce).not.toContain("drop grammar");
|
|
371
|
+
|
|
372
|
+
const gatedOff = light({ dreamer: false, temporal: false, caveman: false });
|
|
373
|
+
expect(gatedOff).not.toContain("surface_condition creates");
|
|
374
|
+
expect(gatedOff).not.toContain("**Temporal awareness**");
|
|
375
|
+
expect(gatedOff).not.toContain("**BEWARE**");
|
|
376
|
+
|
|
377
|
+
const gatedOn = light({ dreamer: true, temporal: true, caveman: true, language: "tr" });
|
|
378
|
+
expect(gatedOn).toContain("surface_condition creates");
|
|
379
|
+
expect(gatedOn).toContain("**Temporal awareness**");
|
|
380
|
+
expect(gatedOn).toContain("**BEWARE**");
|
|
381
|
+
expect(gatedOn).toContain("Keep code, identifiers, file paths");
|
|
382
|
+
|
|
383
|
+
const subagent = light({ subagent: true });
|
|
384
|
+
expect(subagent).toContain("In bounded subagent sessions");
|
|
385
|
+
expect(subagent).toContain("[dropped §N§]");
|
|
386
|
+
expect(subagent).not.toContain("long-term partner");
|
|
387
|
+
expect(subagent).not.toContain("ctx_search");
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it("appends shared runtime fragments after a complete primary override", () => {
|
|
391
|
+
const override = "## Magic Context\n\nUser-owned primary guidance.";
|
|
392
|
+
const output = buildMagicContextSection(
|
|
393
|
+
null,
|
|
394
|
+
20,
|
|
395
|
+
true,
|
|
396
|
+
true,
|
|
397
|
+
true,
|
|
398
|
+
true,
|
|
399
|
+
false,
|
|
400
|
+
"tr",
|
|
401
|
+
true,
|
|
402
|
+
"full",
|
|
403
|
+
override,
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
expect(output.startsWith(override)).toBe(true);
|
|
407
|
+
expect(output.match(/^## Magic Context$/gm)).toHaveLength(1);
|
|
408
|
+
expect(output).toContain("**Temporal awareness**");
|
|
409
|
+
expect(output).toContain("**BEWARE**: History compression is on");
|
|
410
|
+
expect(output).toContain("Use Turkish (Türkçe) for your natural-language replies");
|
|
411
|
+
expect(output.indexOf("**Temporal awareness**")).toBeGreaterThan(
|
|
412
|
+
output.indexOf("User-owned primary guidance."),
|
|
413
|
+
);
|
|
414
|
+
expect(output).not.toContain("### Reduction Triggers");
|
|
415
|
+
expect(output).not.toContain("surface_condition");
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it("keeps subagent guidance independent from a primary override", () => {
|
|
419
|
+
const output = buildMagicContextSection(
|
|
420
|
+
null,
|
|
421
|
+
20,
|
|
422
|
+
true,
|
|
423
|
+
false,
|
|
424
|
+
false,
|
|
425
|
+
false,
|
|
426
|
+
true,
|
|
427
|
+
undefined,
|
|
428
|
+
true,
|
|
429
|
+
"full",
|
|
430
|
+
"## Magic Context\n\nPrimary override must not reach subagents.",
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
expect(output).toContain("§N§ identifiers");
|
|
434
|
+
expect(output).not.toContain("Primary override must not reach subagents");
|
|
435
|
+
});
|
|
436
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Generic magic context system prompt section shared by all agents. */
|
|
2
2
|
|
|
3
|
+
import type { PromptSurfacePreset } from "../shared/prompt-surface";
|
|
3
4
|
import { buildPrimaryLanguageDirective } from "./language-directive";
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -30,6 +31,10 @@ const PARTNER_FRAME_CLOSER_REDUCE = `\nReduction prompts are routine housekeepin
|
|
|
30
31
|
/** Closer for sessions where ctx_reduce is unavailable — context is managed fully automatically. */
|
|
31
32
|
const PARTNER_FRAME_CLOSER_NO_REDUCE = `\nContext is managed for you entirely automatically — there's nothing to prune and no warnings to act on. Stay reasonably concise per operation, and never let context size change *what* work you take on or *how thoroughly* you do it.`;
|
|
32
33
|
|
|
34
|
+
const PARTNER_FRAME_CLOSER_REDUCE_LIGHT = `\nWhen ctx_reduce is available, use it only as routine housekeeping; never cut task scope or depth because context is large.`;
|
|
35
|
+
|
|
36
|
+
const PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT = `\nWhen ctx_reduce is unavailable, context is automatic; never prune, heed reduction warnings, or cut task scope or depth because context is large.`;
|
|
37
|
+
|
|
33
38
|
/**
|
|
34
39
|
* Shared `ctx_note` guidance for both intro variants. Generalizes two observed
|
|
35
40
|
* misuse patterns: (1) taking a note for work that's only a few turns away — that
|
|
@@ -107,6 +112,23 @@ Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`##
|
|
|
107
112
|
\`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
|
|
108
113
|
${TOOL_HISTORY_GUIDANCE}`;
|
|
109
114
|
|
|
115
|
+
const LIGHT_SEARCH_RECOVERY = `Use ctx_search before asking the user about prior project context; it searches memories, commits, and compacted conversation. When a session-history summary lacks exact wording, values, errors, or reasoning, call ctx_expand with its heading range instead of guessing.`;
|
|
116
|
+
|
|
117
|
+
const BASE_INTRO_LIGHT = (
|
|
118
|
+
protectedTags: number,
|
|
119
|
+
memoryEnabled: boolean,
|
|
120
|
+
): string => `In primary sessions with ctx_reduce, the system tags messages and tool outputs as §N§ (for example §1§ and §42§); never imitate these prefixes in replies because only injected tag numbers are valid ctx_reduce handles.
|
|
121
|
+
In primary sessions, NEVER narrate ctx_reduce; call it silently after extracting a spent output because it marks content discardable and QUEUES release rather than deleting immediately. The last ${protectedTags} tags stay protected until they age out. Use drop grammar "3-5", "1,2,9", or "1-5,8,12-15".
|
|
122
|
+
${CTX_NOTE_GUIDANCE}
|
|
123
|
+
${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
|
|
124
|
+
${TOOL_HISTORY_GUIDANCE}
|
|
125
|
+
For primary ctx_reduce choices, NEVER blanket-drop a large range because mixed-value evidence may be lost: inspect every tag first. Drop only analyzed reads, searches, diagnostics, or build/test outputs after use. NEVER drop user directives or assistant prose unless exceptionally large; keep requirements, constraints, unresolved errors or decisions, exact wording, raw evidence, and active files or work. Only extracted pasted user payloads may go.
|
|
126
|
+
Consider small targeted drops after acted-on reads or searches, completed logical steps, before context switches, and before the turn ends; this keeps the working set tidy without changing task scope.`;
|
|
127
|
+
|
|
128
|
+
const BASE_INTRO_NO_REDUCE_LIGHT = (memoryEnabled: boolean): string => `${CTX_NOTE_GUIDANCE}
|
|
129
|
+
${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
|
|
130
|
+
${TOOL_HISTORY_GUIDANCE}`;
|
|
131
|
+
|
|
110
132
|
const GENERIC_SECTION = `
|
|
111
133
|
### Reduction Triggers
|
|
112
134
|
- After reading files or search results you already acted on — drop raw outputs.
|
|
@@ -124,6 +146,8 @@ const GENERIC_SECTION = `
|
|
|
124
146
|
- Recent errors and unresolved decisions.
|
|
125
147
|
- Active work context and files being edited.`;
|
|
126
148
|
|
|
149
|
+
const SMART_NOTE_GUIDANCE_LIGHT = `\nsurface_condition creates a smart note checked nightly against external signals on ctx_note write.`;
|
|
150
|
+
|
|
127
151
|
const TEMPORAL_AWARENESS_GUIDANCE = `\n**Temporal awareness**: User messages may be preceded by HTML comments like \`<!-- +12m -->\`, \`<!-- +2h 15m -->\`, or \`<!-- +3d 4h -->\` indicating time elapsed since the previous message's completion. Compartments in \`<session-history>\` carry \`start-date\` and \`end-date\` attributes (YYYY-MM-DD) showing real-time boundaries. Use these when reasoning about workflow pacing, log durations, build times, or how long ago something happened.`;
|
|
128
152
|
|
|
129
153
|
/**
|
|
@@ -142,6 +166,12 @@ Use \`ctx_reduce\` to drop tool outputs you have already finished with, keeping
|
|
|
142
166
|
Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-50"); review each tag first. Do not drop user or assistant text messages — only large tool outputs are worth dropping.
|
|
143
167
|
Older tool calls may show \`[dropped §N§]\` sentinels; that is normal context management, not a pattern to copy. ALWAYS make fresh real tool calls when you need data again; never fabricate or inline tool output.`;
|
|
144
168
|
|
|
169
|
+
const SUBAGENT_REDUCE_INTRO_LIGHT = (
|
|
170
|
+
protectedTags: number,
|
|
171
|
+
): string => `In bounded subagent sessions, the system tags messages and tool outputs as §N§; use only those IDs in ctx_reduce drop ranges such as "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags stay protected.
|
|
172
|
+
When dropping, do it silently and NEVER choose a large range before reviewing every tag; drop only finished large tool outputs, never user or assistant messages.
|
|
173
|
+
If older calls show [dropped §N§], never copy that system sentinel because it is not reply syntax; make a fresh real tool call and never fabricate or inline output.`;
|
|
174
|
+
|
|
145
175
|
const CAVEMAN_COMPRESSION_WARNING = `\n**BEWARE**: History compression is on; older user AND assistant text — including your own earlier responses — has been deterministically rewritten in a terse caveman style (dropped articles, missing auxiliaries, \`//\` instead of connectives like \`because\`). This is automatic context compression that runs after the fact, not your actual prior wording or the user's. **DO NOT mimic this style in new turns.** Write fresh responses in normal prose. If you notice your output drifting into caveman cadence, that drift is in-context-learning bleeding from the compressed history — consciously revert to full sentences.`;
|
|
146
176
|
|
|
147
177
|
export function buildMagicContextSection(
|
|
@@ -154,6 +184,8 @@ export function buildMagicContextSection(
|
|
|
154
184
|
subagentMode = false,
|
|
155
185
|
language?: string,
|
|
156
186
|
memoryEnabled = true,
|
|
187
|
+
preset: PromptSurfacePreset = "full",
|
|
188
|
+
primaryOverride?: string,
|
|
157
189
|
): string {
|
|
158
190
|
// Subagent sessions: minimal §N§ + ctx_reduce mechanics only. Bypasses the
|
|
159
191
|
// long-term-partner frame, memory/search/note guidance, and the reduction
|
|
@@ -162,10 +194,16 @@ export function buildMagicContextSection(
|
|
|
162
194
|
// when ctx_reduce is off the subagent gets no §N§ prefix, so describing the
|
|
163
195
|
// tag system would be noise.
|
|
164
196
|
if (subagentMode) {
|
|
165
|
-
|
|
197
|
+
const intro =
|
|
198
|
+
preset === "light"
|
|
199
|
+
? SUBAGENT_REDUCE_INTRO_LIGHT(protectedTags)
|
|
200
|
+
: SUBAGENT_REDUCE_INTRO(protectedTags);
|
|
201
|
+
return `## Magic Context\n\n${intro}`;
|
|
166
202
|
}
|
|
167
203
|
const smartNoteGuidance = dreamerEnabled
|
|
168
|
-
?
|
|
204
|
+
? preset === "light"
|
|
205
|
+
? SMART_NOTE_GUIDANCE_LIGHT
|
|
206
|
+
: `\nWhen \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.\nThe dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.\nExample: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\``
|
|
169
207
|
: "";
|
|
170
208
|
const temporalGuidance = temporalAwarenessEnabled ? TEMPORAL_AWARENESS_GUIDANCE : "";
|
|
171
209
|
// Caveman compression is independent of ctx_reduce availability. Emit the
|
|
@@ -175,8 +213,21 @@ export function buildMagicContextSection(
|
|
|
175
213
|
const languageDirective = buildPrimaryLanguageDirective(language);
|
|
176
214
|
const languageGuidance = languageDirective ? `\n\n${languageDirective}` : "";
|
|
177
215
|
|
|
216
|
+
if (primaryOverride !== undefined) {
|
|
217
|
+
// A user override owns the complete primary section. Runtime clauses stay
|
|
218
|
+
// composer-owned so an override cannot suppress temporal guidance, the
|
|
219
|
+
// warning against overly compressed prose, or the language directive.
|
|
220
|
+
return `${primaryOverride}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
221
|
+
}
|
|
222
|
+
|
|
178
223
|
if (!ctxReduceCallable) {
|
|
224
|
+
if (preset === "light") {
|
|
225
|
+
return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT}\n\n${BASE_INTRO_NO_REDUCE_LIGHT(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
226
|
+
}
|
|
179
227
|
return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_NO_REDUCE}\n\n${BASE_INTRO_NO_REDUCE(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
180
228
|
}
|
|
229
|
+
if (preset === "light") {
|
|
230
|
+
return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE_LIGHT}\n\n${BASE_INTRO_LIGHT(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
231
|
+
}
|
|
181
232
|
return `## Magic Context\n\n${LONG_TERM_PARTNER_FRAME}\n${PARTNER_FRAME_CLOSER_REDUCE}\n\n${BASE_INTRO(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}\n${GENERIC_SECTION}\n\nPrefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
|
|
182
233
|
}
|
|
@@ -6,9 +6,10 @@ import { log } from "../shared/logger";
|
|
|
6
6
|
* # Why this exists
|
|
7
7
|
*
|
|
8
8
|
* Hidden agents (`historian`, `historian-editor`, `dreamer`, `sidekick`) are
|
|
9
|
-
* registered with `mode: "
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* registered with `mode: "primary"` and `hidden: true`: primary mode keeps
|
|
10
|
+
* them out of OpenCode's general Task candidate list, while hidden keeps them
|
|
11
|
+
* out of the UI picker. Those flags do NOT restrict which tools the spawned
|
|
12
|
+
* session can call. By default a registered agent
|
|
12
13
|
* inherits the FULL primary-agent tool surface: `task`, `bash`, `edit`,
|
|
13
14
|
* `webfetch`, `websearch`, `read`, `grep`, `glob`, every MCP tool, etc.
|
|
14
15
|
*
|
package/src/config/index.test.ts
CHANGED
|
@@ -934,3 +934,56 @@ describe("transform_mode resolution", () => {
|
|
|
934
934
|
expect(result.subc?.connection_file).not.toContain("project-controlled.sock");
|
|
935
935
|
});
|
|
936
936
|
});
|
|
937
|
+
|
|
938
|
+
describe("loadPluginConfigDetailed — prompt-surface registration owner", () => {
|
|
939
|
+
it("captures the user default before project guidance routing is merged", () => {
|
|
940
|
+
const xdg = mkdtempSync(join(tmpdir(), "mc-config-prompt-surface-"));
|
|
941
|
+
const projectDir = mkdtempSync(join(tmpdir(), "mc-project-prompt-surface-"));
|
|
942
|
+
const fs = require("node:fs") as typeof import("node:fs");
|
|
943
|
+
const userDir = join(xdg, "cortexkit");
|
|
944
|
+
const projectConfigDir = join(projectDir, ".cortexkit");
|
|
945
|
+
fs.mkdirSync(userDir, { recursive: true });
|
|
946
|
+
fs.mkdirSync(projectConfigDir, { recursive: true });
|
|
947
|
+
writeFileSync(
|
|
948
|
+
join(userDir, "magic-context.jsonc"),
|
|
949
|
+
JSON.stringify({
|
|
950
|
+
prompt_surface: {
|
|
951
|
+
default: "light",
|
|
952
|
+
guidance_override_path: "guidance.md",
|
|
953
|
+
tool_descriptions: { ctx_search: "user text" },
|
|
954
|
+
},
|
|
955
|
+
}),
|
|
956
|
+
);
|
|
957
|
+
writeFileSync(
|
|
958
|
+
join(projectConfigDir, "magic-context.jsonc"),
|
|
959
|
+
JSON.stringify({
|
|
960
|
+
prompt_surface: {
|
|
961
|
+
default: "full",
|
|
962
|
+
models: { "openai/*": "light" },
|
|
963
|
+
},
|
|
964
|
+
}),
|
|
965
|
+
);
|
|
966
|
+
const originalXdg = process.env.XDG_CONFIG_HOME;
|
|
967
|
+
process.env.XDG_CONFIG_HOME = xdg;
|
|
968
|
+
|
|
969
|
+
try {
|
|
970
|
+
const result = loadPluginConfigDetailed(projectDir);
|
|
971
|
+
expect(result.config.prompt_surface).toEqual({
|
|
972
|
+
default: "full",
|
|
973
|
+
models: { "openai/*": "light" },
|
|
974
|
+
guidance_override_path: "guidance.md",
|
|
975
|
+
tool_descriptions: { ctx_search: "user text" },
|
|
976
|
+
});
|
|
977
|
+
expect(result.registrationPromptSurface).toEqual({
|
|
978
|
+
default: "light",
|
|
979
|
+
guidance_override_path: "guidance.md",
|
|
980
|
+
tool_descriptions: { ctx_search: "user text" },
|
|
981
|
+
});
|
|
982
|
+
} finally {
|
|
983
|
+
if (originalXdg === undefined) delete process.env.XDG_CONFIG_HOME;
|
|
984
|
+
else process.env.XDG_CONFIG_HOME = originalXdg;
|
|
985
|
+
rmSync(xdg, { recursive: true, force: true });
|
|
986
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
});
|
package/src/config/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
|
|
3
3
|
import { detectConfigFile, parseJsonc } from "../shared/jsonc-parser";
|
|
4
4
|
import { setOutputReserveConfig } from "../shared/models-dev-cache";
|
|
5
|
+
import type { PromptSurfaceConfig } from "../shared/prompt-surface";
|
|
5
6
|
import { isCompactionEnabled, migrateLegacyAgentEnabledInMemory } from "./agent-disable";
|
|
6
7
|
import {
|
|
7
8
|
cortexKitProjectConfigBasePath,
|
|
@@ -82,6 +83,8 @@ export type LoadOutcome =
|
|
|
82
83
|
|
|
83
84
|
export interface LoadResultDetailed {
|
|
84
85
|
config: MagicContextPluginConfig & { configWarnings?: string[] };
|
|
86
|
+
/** USER-tier default/overrides captured before project routing is merged. */
|
|
87
|
+
registrationPromptSurface: PromptSurfaceConfig;
|
|
85
88
|
loadOutcome: LoadOutcome;
|
|
86
89
|
sources: {
|
|
87
90
|
userConfig: LoadOutcome;
|
|
@@ -593,6 +596,7 @@ export function loadPluginConfigDetailed(directory: string): LoadResultDetailed
|
|
|
593
596
|
|
|
594
597
|
return {
|
|
595
598
|
config,
|
|
599
|
+
registrationPromptSurface: trustedBaseConfig.prompt_surface,
|
|
596
600
|
loadOutcome: combinedOutcome({ sources, substitutionFailures, recoveredTopLevelKeys }),
|
|
597
601
|
sources,
|
|
598
602
|
substitutionFailures,
|
|
@@ -48,6 +48,26 @@ describe("stripUnsafeProjectConfigFields", () => {
|
|
|
48
48
|
expect(warnings.some((w) => w.includes("output_reserve"))).toBe(true);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
it("strips prompt-surface text overrides but keeps project routing", () => {
|
|
52
|
+
const raw: Record<string, unknown> = {
|
|
53
|
+
prompt_surface: {
|
|
54
|
+
default: "light",
|
|
55
|
+
models: { "openai/*": "full" },
|
|
56
|
+
guidance_override_path: "/repo/guidance.md",
|
|
57
|
+
tool_descriptions: { ctx_search: "repo-controlled text" },
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const warnings = stripUnsafeProjectConfigFields(raw);
|
|
62
|
+
|
|
63
|
+
expect(raw.prompt_surface).toEqual({
|
|
64
|
+
default: "light",
|
|
65
|
+
models: { "openai/*": "full" },
|
|
66
|
+
});
|
|
67
|
+
expect(warnings).toHaveLength(1);
|
|
68
|
+
expect(warnings[0]).toContain("prompt_surface.guidance_override_path/tool_descriptions");
|
|
69
|
+
});
|
|
70
|
+
|
|
51
71
|
it("strips language from project config", () => {
|
|
52
72
|
const raw: Record<string, unknown> = { language: "tr", dreamer: { model: "x" } };
|
|
53
73
|
const warnings = stripUnsafeProjectConfigFields(raw);
|
|
@@ -16,6 +16,7 @@ import { DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE } from "./schema/magic-context";
|
|
|
16
16
|
/** Hidden agents that run with elevated/autonomous capability. */
|
|
17
17
|
const HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"] as const;
|
|
18
18
|
const HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"] as const;
|
|
19
|
+
const PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"] as const;
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Fields on a hidden-agent block that constitute a privilege-escalation /
|
|
@@ -217,6 +218,9 @@ function makeProjectThresholdWarning(field: string, reason: string): string {
|
|
|
217
218
|
* a cloned repo cannot choose a model that sends project memory to a provider.
|
|
218
219
|
* - `pi.subagent_extensions` — a cloned repo must not choose which extensions
|
|
219
220
|
* the user's Pi child processes load.
|
|
221
|
+
* - `prompt_surface.guidance_override_path` / `tool_descriptions` — a repository
|
|
222
|
+
* may select a reviewed preset, but must not inject arbitrary guidance or tool
|
|
223
|
+
* description text into the user's provider-visible prompt.
|
|
220
224
|
* - hidden-agent `prompt`/`permission`/`tools` — a repo must not reprogram or
|
|
221
225
|
* re-permission the historian/dreamer/sidekick.
|
|
222
226
|
*/
|
|
@@ -290,6 +294,25 @@ export function stripUnsafeProjectConfigFields(projectRaw: Record<string, unknow
|
|
|
290
294
|
);
|
|
291
295
|
}
|
|
292
296
|
|
|
297
|
+
// Repositories may select preset routing, but project settings cannot add
|
|
298
|
+
// guidance or tool-description text to the provider-visible prompt; those
|
|
299
|
+
// user-only fields are removed before project settings are merged.
|
|
300
|
+
const promptSurface = projectRaw.prompt_surface;
|
|
301
|
+
if (isPlainObject(promptSurface)) {
|
|
302
|
+
const removed: string[] = [];
|
|
303
|
+
for (const field of PROMPT_SURFACE_USER_ONLY_FIELDS) {
|
|
304
|
+
if (field in promptSurface) {
|
|
305
|
+
delete promptSurface[field];
|
|
306
|
+
removed.push(field);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (removed.length > 0) {
|
|
310
|
+
warnings.push(
|
|
311
|
+
`Ignoring prompt_surface.${removed.join("/")} from project config (security: repositories may select prompt presets but only user config may provide guidance or tool-description text).`,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
293
316
|
const pi = projectRaw.pi;
|
|
294
317
|
if (isPlainObject(pi) && "subagent_extensions" in pi) {
|
|
295
318
|
delete pi.subagent_extensions;
|
|
@@ -19,6 +19,7 @@ describe("MagicContextConfigSchema", () => {
|
|
|
19
19
|
transform_mode: "ts",
|
|
20
20
|
storage: { enforce_private_permissions: true },
|
|
21
21
|
cache_ttl: "5m",
|
|
22
|
+
prompt_surface: { default: "full" },
|
|
22
23
|
execute_threshold_percentage: 65,
|
|
23
24
|
protected_tags: 20,
|
|
24
25
|
clear_reasoning_age: 50,
|
|
@@ -79,6 +80,7 @@ describe("MagicContextConfigSchema", () => {
|
|
|
79
80
|
auto_update: false,
|
|
80
81
|
toast_duration_ms: 5000,
|
|
81
82
|
cache_ttl: "10m",
|
|
83
|
+
prompt_surface: { default: "full" },
|
|
82
84
|
protected_tags: 3,
|
|
83
85
|
execute_threshold_percentage: 75,
|
|
84
86
|
clear_reasoning_age: 60,
|
|
@@ -257,6 +259,23 @@ describe("MagicContextConfigSchema", () => {
|
|
|
257
259
|
|
|
258
260
|
expect(result.cache_ttl).toEqual(input.cache_ttl);
|
|
259
261
|
});
|
|
262
|
+
|
|
263
|
+
// Accepts preset routing, a guidance override path, and tool-description overrides.
|
|
264
|
+
it("parses prompt-surface defaults, routes, and user overrides", () => {
|
|
265
|
+
const promptSurface = {
|
|
266
|
+
default: "light" as const,
|
|
267
|
+
models: {
|
|
268
|
+
"anthropic/claude/sonnet": "full" as const,
|
|
269
|
+
"openai/*": "light" as const,
|
|
270
|
+
},
|
|
271
|
+
guidance_override_path: "./guidance.md",
|
|
272
|
+
tool_descriptions: { ctx_search: "Search project context" },
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
expect(
|
|
276
|
+
MagicContextConfigSchema.parse({ prompt_surface: promptSurface }).prompt_surface,
|
|
277
|
+
).toEqual(promptSurface);
|
|
278
|
+
});
|
|
260
279
|
});
|
|
261
280
|
|
|
262
281
|
describe("validation", () => {
|
|
@@ -264,6 +283,45 @@ describe("MagicContextConfigSchema", () => {
|
|
|
264
283
|
expect(() => MagicContextConfigSchema.parse({ transform_mode: "wasm" })).toThrow();
|
|
265
284
|
});
|
|
266
285
|
|
|
286
|
+
it("rejects malformed prompt-surface model keys and empty override text", () => {
|
|
287
|
+
const malformedKeys = [
|
|
288
|
+
"",
|
|
289
|
+
"provider",
|
|
290
|
+
"/model",
|
|
291
|
+
"provider/",
|
|
292
|
+
"provider//model",
|
|
293
|
+
"provider/model*",
|
|
294
|
+
"provider/*/nested",
|
|
295
|
+
"provider//model",
|
|
296
|
+
"provider/model/",
|
|
297
|
+
"provider/ model",
|
|
298
|
+
"*/model",
|
|
299
|
+
];
|
|
300
|
+
for (const key of malformedKeys) {
|
|
301
|
+
expect(
|
|
302
|
+
MagicContextConfigSchema.safeParse({
|
|
303
|
+
prompt_surface: { models: { [key]: "light" } },
|
|
304
|
+
}).success,
|
|
305
|
+
).toBe(false);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
expect(
|
|
309
|
+
MagicContextConfigSchema.safeParse({
|
|
310
|
+
prompt_surface: { guidance_override_path: " " },
|
|
311
|
+
}).success,
|
|
312
|
+
).toBe(false);
|
|
313
|
+
expect(
|
|
314
|
+
MagicContextConfigSchema.safeParse({
|
|
315
|
+
prompt_surface: { tool_descriptions: { ctx_search: " " } },
|
|
316
|
+
}).success,
|
|
317
|
+
).toBe(false);
|
|
318
|
+
expect(
|
|
319
|
+
MagicContextConfigSchema.safeParse({
|
|
320
|
+
prompt_surface: { tool_descriptions: { " ": "description" } },
|
|
321
|
+
}).success,
|
|
322
|
+
).toBe(false);
|
|
323
|
+
});
|
|
324
|
+
|
|
267
325
|
it("rejects empty Pi subagent extension entries", () => {
|
|
268
326
|
expect(() =>
|
|
269
327
|
MagicContextConfigSchema.parse({ pi: { subagent_extensions: [" "] } }),
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
AGENTIC_DREAM_TASKS,
|
|
8
8
|
DreamTaskName,
|
|
9
9
|
} from "../../features/magic-context/dreamer/task-registry";
|
|
10
|
+
import { isValidPromptSurfaceModelKey } from "../../shared/prompt-surface";
|
|
10
11
|
import { AgentOverrideConfigSchema } from "./agent-overrides";
|
|
11
12
|
|
|
12
13
|
export const DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
@@ -49,6 +50,60 @@ export const PiConfigSchema = z
|
|
|
49
50
|
.optional();
|
|
50
51
|
export type PiConfig = NonNullable<z.infer<typeof PiConfigSchema>>;
|
|
51
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Route the built-in prompt surface without changing guidance or tool registration.
|
|
55
|
+
* Project config can choose preset routing; only user config can provide override text.
|
|
56
|
+
*/
|
|
57
|
+
export const PromptSurfacePresetSchema = z.enum(["full", "light"]);
|
|
58
|
+
export type { PromptSurfacePreset } from "../../shared/prompt-surface";
|
|
59
|
+
|
|
60
|
+
const PromptSurfaceModelKeySchema = z.string().refine(isValidPromptSurfaceModelKey, {
|
|
61
|
+
message:
|
|
62
|
+
"Use a non-empty provider/model key or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive.",
|
|
63
|
+
});
|
|
64
|
+
// Tool-description keys must be non-empty IDs; harness-specific known-tool
|
|
65
|
+
// validation can run when a user override is applied.
|
|
66
|
+
const PromptSurfaceToolKeySchema = z.string().refine((value) => value.trim().length > 0, {
|
|
67
|
+
message: "tool description keys must not be empty or whitespace-only",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const PromptSurfaceConfigSchema = z
|
|
71
|
+
.object({
|
|
72
|
+
default: PromptSurfacePresetSchema.default("full").describe(
|
|
73
|
+
'Fallback prompt-surface preset ("full" or "light").',
|
|
74
|
+
),
|
|
75
|
+
models: z
|
|
76
|
+
.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema)
|
|
77
|
+
.optional()
|
|
78
|
+
.describe(
|
|
79
|
+
"Literal per-model routing. Keys are provider/model or provider/*; matching is case-sensitive and preserves additional slashes in model IDs.",
|
|
80
|
+
),
|
|
81
|
+
guidance_override_path: z
|
|
82
|
+
.string()
|
|
83
|
+
.refine((value) => value.trim().length > 0, {
|
|
84
|
+
message: "guidance_override_path must not be empty or whitespace-only",
|
|
85
|
+
})
|
|
86
|
+
.optional()
|
|
87
|
+
.describe(
|
|
88
|
+
"USER-LEVEL ONLY path to a complete primary guidance section. Relative paths resolve from the user config file.",
|
|
89
|
+
),
|
|
90
|
+
tool_descriptions: z
|
|
91
|
+
.record(
|
|
92
|
+
PromptSurfaceToolKeySchema,
|
|
93
|
+
z.string().refine((value) => value.trim().length > 0, {
|
|
94
|
+
message: "tool description values must not be empty or whitespace-only",
|
|
95
|
+
}),
|
|
96
|
+
)
|
|
97
|
+
.optional()
|
|
98
|
+
.describe(
|
|
99
|
+
"USER-LEVEL ONLY top-level description overrides keyed by ctx_* tool ID; parameter schemas and descriptions are unchanged.",
|
|
100
|
+
),
|
|
101
|
+
})
|
|
102
|
+
.describe(
|
|
103
|
+
"Prompt-surface preset routing. Project config may select default/models, while guidance_override_path and tool_descriptions are user-level only.",
|
|
104
|
+
);
|
|
105
|
+
export type PromptSurfaceConfig = z.infer<typeof PromptSurfaceConfigSchema>;
|
|
106
|
+
|
|
52
107
|
/** A 5-field cron expression, or "" to disable the task. */
|
|
53
108
|
const CronScheduleSchema = z
|
|
54
109
|
.string()
|
|
@@ -416,6 +471,8 @@ export interface MagicContextConfig {
|
|
|
416
471
|
historian?: HistorianConfig;
|
|
417
472
|
dreamer?: DreamerConfig;
|
|
418
473
|
cache_ttl: string | { default: string; [modelKey: string]: string };
|
|
474
|
+
/** Preset routing for guidance and provider-visible prompt surfaces. */
|
|
475
|
+
prompt_surface: PromptSurfaceConfig;
|
|
419
476
|
/** User-only output-token reservation override. Zero disables reservation. */
|
|
420
477
|
output_reserve?: number | { default: number; [modelKey: string]: number };
|
|
421
478
|
/** TUI toast lifetime in milliseconds for Magic Context notifications. Default: 5000. */
|
|
@@ -637,6 +694,9 @@ export const MagicContextConfigSchema = z
|
|
|
637
694
|
.describe(
|
|
638
695
|
'Cache TTL: string (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" for lanes kept warm by an external keepwarm proxy — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time.',
|
|
639
696
|
),
|
|
697
|
+
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe(
|
|
698
|
+
"Prompt-surface presets: default is full; models use the literal provider/model or provider/* routing grammar. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes).",
|
|
699
|
+
),
|
|
640
700
|
output_reserve: z
|
|
641
701
|
.union([
|
|
642
702
|
z.number().min(0),
|
|
@@ -828,7 +888,7 @@ export const MagicContextConfigSchema = z
|
|
|
828
888
|
.boolean()
|
|
829
889
|
.default(true)
|
|
830
890
|
.describe(
|
|
831
|
-
"When false, Magic Context stops managing the context window and keeps its knowledge layer: memory and docs/user-profile/key-files injection through additive m[0]/m[1], raw-message FTS indexing, dreamer, notes, ctx_search, ctx_expand, ctx_memory, and /ctx-embed remain available. MC's historian/compartment preparation, tagging, markers, pruning, folding, drops, strips, splicing, synthetic context-management todos, temporal markers, nudges, and fail-closed blocking stop; ctx_expand remains a knowledge-surface tool. fail_closed_blocking is inert: a transform failure passes the input messages through without blocking or cancelling. This setting does not enable native compaction: OpenCode's compaction.auto / compaction.prune or Pi's equivalent owns the window, or nothing does. MC's compaction.enabled in magic-context.jsonc is distinct from OpenCode's compaction.auto / compaction.prune in opencode.jsonc; they are different files and different owners. On the first turn after disabling, a long session may trigger one native compaction cycle; MC removes only its own marker boundary, leaves native boundaries and stored compartments intact, and does no pre-trimming mitigation. Marker cleanup is lazy per session, so an unresumed session is cleaned when it is next resumed. If compaction is enabled again, run /ctx-wrapup when the historian is runnable to catch up. OpenCode peer verification against v1.18.4 confirms native compaction covers child sessions: subagents receive additive memory/docs injection and no MC reclaim in this mode, so keep subagent tasks small or leave compaction.enabled on for long subagent runs.
|
|
891
|
+
"When false, Magic Context stops managing the context window and keeps its knowledge layer: memory and docs/user-profile/key-files injection through additive m[0]/m[1], raw-message FTS indexing, dreamer, notes, ctx_search, ctx_expand, ctx_memory, and /ctx-embed remain available. MC's historian/compartment preparation, tagging, markers, pruning, folding, drops, strips, splicing, synthetic context-management todos, temporal markers, nudges, and fail-closed blocking stop; ctx_expand remains a knowledge-surface tool. fail_closed_blocking is inert: a transform failure passes the input messages through without blocking or cancelling. This setting does not enable native compaction: OpenCode's compaction.auto / compaction.prune or Pi's equivalent owns the window, or nothing does. MC's compaction.enabled in magic-context.jsonc is distinct from OpenCode's compaction.auto / compaction.prune in opencode.jsonc; they are different files and different owners. On the first turn after disabling, a long session may trigger one native compaction cycle; MC removes only its own marker boundary, leaves native boundaries and stored compartments intact, and does no pre-trimming mitigation. Marker cleanup is lazy per session, so an unresumed session is cleaned when it is next resumed. If compaction is enabled again, run /ctx-wrapup when the historian is runnable to catch up. OpenCode peer verification against v1.18.4 confirms native compaction covers child sessions: subagents receive additive memory/docs injection and no MC reclaim in this mode, so keep subagent tasks small or leave compaction.enabled on for long subagent runs. This is boot-resolved and requires a process restart; project-tier compaction.enabled is stripped so a cloned repository cannot disable the user's setting. The sidebar reports raw usage as Context: <pct>% · native compaction or Context: <pct>% · no active compaction and does not show an MC execute-threshold fill. /ctx-wrapup, /ctx-recomp, /ctx-flush, and /ctx-session-upgrade refuse without context-management side effects; /ctx-embed remains functional. Raw content hidden by a native boundary before Magic Context's first pass is not retroactively indexed.",
|
|
832
892
|
),
|
|
833
893
|
})
|
|
834
894
|
.default({ enabled: true })
|