@cortexkit/opencode-magic-context 0.42.4 → 0.42.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +2 -2
  2. package/dist/config/index.d.ts +9 -0
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/schema/magic-context.d.ts +1 -0
  5. package/dist/config/schema/magic-context.d.ts.map +1 -1
  6. package/dist/{conflict-warning-hook-jyj54gbe.js → conflict-warning-hook-aktepwpz.js} +3 -3
  7. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  8. package/dist/features/magic-context/context-authority.d.ts +28 -1
  9. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  10. package/dist/features/magic-context/dreamer/curate-category-rotation.d.ts +26 -0
  11. package/dist/features/magic-context/dreamer/curate-category-rotation.d.ts.map +1 -0
  12. package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +7 -5
  14. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
  15. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/task-gates.d.ts +1 -0
  17. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/task-prompts.d.ts +3 -0
  19. package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/task-registry.d.ts +6 -0
  21. package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +5 -1
  23. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  24. package/dist/features/magic-context/memory/embedding-local.d.ts +12 -0
  25. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  26. package/dist/features/magic-context/memory/embedding.d.ts +1 -1
  27. package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
  28. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  29. package/dist/features/magic-context/migrations.d.ts +12 -0
  30. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  31. package/dist/features/magic-context/project-embedding-registry.d.ts +1 -0
  32. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  33. package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
  34. package/dist/features/magic-context/storage-db.d.ts +1 -1
  35. package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
  36. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/cache-busting-signals.d.ts +0 -1
  38. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/channel2-delivery.d.ts +8 -0
  40. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +12 -0
  42. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/hook.d.ts +4 -4
  44. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  45. package/dist/hooks/magic-context/module-state-sync.d.ts +3 -0
  46. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  47. package/dist/hooks/magic-context/module-transport.d.ts +24 -2
  48. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/module-wire.d.ts +1 -1
  50. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/producer-window-guard.d.ts +31 -1
  52. package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/read-session-chunk.d.ts +6 -0
  54. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/read-session-db.d.ts +8 -0
  56. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/read-session-formatting.d.ts +6 -0
  58. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/rust-mode-transform.d.ts +30 -0
  60. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/rust-refusal-recovery.d.ts +28 -0
  62. package/dist/hooks/magic-context/rust-refusal-recovery.d.ts.map +1 -0
  63. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  64. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/transform.d.ts +7 -0
  66. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  67. package/dist/{index-bkg2fdj1.js → index-4wwr6cz0.js} +3 -0
  68. package/dist/{index-jkrqhc7y.js → index-a9ssj59b.js} +94 -15
  69. package/dist/{index-faay035c.js → index-djp6rwz6.js} +484 -57
  70. package/dist/{index-p474rw9p.js → index-ngjmj6xx.js} +1 -1
  71. package/dist/{index-d8mgqezq.js → index-s61hh7gv.js} +50 -17
  72. package/dist/{index-1ar7b3e9.js → index-znraa0kv.js} +1 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +1667 -380
  75. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
  76. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  77. package/dist/plugin/memory-id-translation.d.ts +23 -0
  78. package/dist/plugin/memory-id-translation.d.ts.map +1 -0
  79. package/dist/plugin/rust-tool-backends.d.ts +1 -1
  80. package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
  81. package/dist/{recomp-orchestrator-c4sa354a.js → recomp-orchestrator-0xx1364v.js} +4 -4
  82. package/dist/{send-session-notification-xnypkxpx.js → send-session-notification-jbxknvar.js} +2 -2
  83. package/dist/shared/auto-update-provenance.d.ts +9 -0
  84. package/dist/shared/auto-update-provenance.d.ts.map +1 -0
  85. package/dist/shared/conflict-detector.d.ts +5 -1
  86. package/dist/shared/conflict-detector.d.ts.map +1 -1
  87. package/dist/shared/opencode-db-path.d.ts +31 -2
  88. package/dist/shared/opencode-db-path.d.ts.map +1 -1
  89. package/dist/shared/prompt-surface-runtime.d.ts +3 -3
  90. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
  91. package/dist/{storage-meta-session-x3j0q9qy.js → storage-meta-session-z818pn1e.js} +2 -2
  92. package/dist/{task-config-ys0arma5.js → task-config-cv8k9y8r.js} +1 -1
  93. package/dist/tools/ctx-expand/mode.d.ts +31 -0
  94. package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
  95. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  96. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  97. package/dist/tools/ctx-note/constants.d.ts +1 -1
  98. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  99. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  100. package/dist/tools/ctx-note/types.d.ts +1 -1
  101. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  102. package/dist/tools/ctx-reduce/constants.d.ts +1 -1
  103. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
  104. package/dist/tools/ctx-search/types.d.ts +1 -1
  105. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  106. package/dist/tools/light-descriptions.d.ts +2 -2
  107. package/dist/tools/light-descriptions.d.ts.map +1 -1
  108. package/dist/v2/hidden-completion.d.ts +69 -13
  109. package/dist/v2/hidden-completion.d.ts.map +1 -1
  110. package/dist/v2/hooks/context.d.ts +13 -1
  111. package/dist/v2/hooks/context.d.ts.map +1 -1
  112. package/dist/v2/hooks/hidden-child.d.ts +31 -0
  113. package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
  114. package/dist/v2/hooks/store.d.ts.map +1 -1
  115. package/dist/v2/hooks/types.d.ts +99 -19
  116. package/dist/v2/hooks/types.d.ts.map +1 -1
  117. package/dist/v2/server.d.ts +19 -0
  118. package/dist/v2/server.d.ts.map +1 -1
  119. package/dist/v2/server.js +2311 -2724
  120. package/dist/v2/store-reader.d.ts +11 -5
  121. package/dist/v2/store-reader.d.ts.map +1 -1
  122. package/dist/v2/tui/index.d.ts +10 -0
  123. package/dist/v2/tui/index.d.ts.map +1 -0
  124. package/dist/v2/tui/types.d.ts +80 -0
  125. package/dist/v2/tui/types.d.ts.map +1 -0
  126. package/package.json +5 -4
  127. package/src/agents/magic-context-prompt.ts +1 -1
  128. package/src/config/index.ts +31 -1
  129. package/src/config/protected-tokens.test.ts +40 -0
  130. package/src/config/schema/magic-context.ts +8 -3
  131. package/src/features/magic-context/dreamer/task-registry.ts +10 -0
  132. package/src/shared/auto-update-provenance.ts +42 -0
  133. package/src/shared/conflict-detector.test.ts +53 -0
  134. package/src/shared/conflict-detector.ts +88 -19
  135. package/src/shared/models-dev-cache.test.ts +25 -0
  136. package/src/shared/opencode-db-path.test.ts +96 -0
  137. package/src/shared/opencode-db-path.ts +146 -15
  138. package/src/shared/prompt-surface-a1-golden.md +12 -16
  139. package/src/shared/prompt-surface-runtime.test.ts +20 -0
  140. package/src/shared/prompt-surface-runtime.ts +7 -5
  141. package/src/tui/entry.mjs +11 -1
  142. package/src/v2/tui/host-contract.test.ts +202 -0
  143. package/src/v2/tui/index.ts +270 -0
  144. package/src/v2/tui/types.ts +67 -0
@@ -1,15 +1,19 @@
1
- /** Source rule: oc-audit-7a31b5c0f7.md:186-202; sanitization follows owner R16.
2
- * The real GA CLI 2.0.3 placement probe confirms OPENCODE_DB is honoured.
3
- * Isolation must still use private XDG roots, not rely solely on the filename.
4
- */
1
+ /** Compatibility export; shared/opencode-db-path.ts is the single filename authority. */
5
2
  export declare function sourceDatabaseFilename(channel: string, env?: NodeJS.ProcessEnv): string;
6
- /** GA data root: aft-playbook-fe8d4871f.md:46-48, with the CLI filename rule. */
3
+ /** GA data root resolved by the shared host-generation-aware resolver. */
7
4
  export declare function gaDatabasePath(dataHome: string, channel?: string, env?: NodeJS.ProcessEnv): string;
8
5
  export type MessageType = "agent-switched" | "model-switched" | "location-switched" | "user" | "synthetic" | "system" | "skill" | "shell" | "assistant" | "compaction" | "idle";
9
6
  export interface MessageData {
10
7
  [key: string]: unknown;
11
8
  content?: Array<Record<string, unknown>>;
12
9
  text?: string;
10
+ finish?: string;
11
+ error?: unknown;
12
+ model?: {
13
+ id: string;
14
+ providerID: string;
15
+ variant?: string;
16
+ };
13
17
  tokens?: {
14
18
  input: number;
15
19
  output: number;
@@ -56,6 +60,8 @@ export declare class V2StoreReader {
56
60
  };
57
61
  latestCompaction(sessionID: string): StoreRow<"compaction"> | undefined;
58
62
  idleRows(sessionID: string, after?: number): StoreRow<"idle">[];
63
+ latestSequence(sessionID: string): number;
64
+ latestAssistant(sessionID: string): StoreRow<"assistant"> | undefined;
59
65
  /** Include the completed checkpoint itself, matching the host history cut. */
60
66
  window(sessionID: string): StoreRow[];
61
67
  /** Full retained source is needed to restore unarchived rows hidden by a host cut. */
@@ -1 +1 @@
1
- {"version":3,"file":"store-reader.d.ts","sourceRoot":"","sources":["../../src/v2/store-reader.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACrC,MAAM,CASR;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAW,EAClB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACrC,MAAM,CAGR;AAGD,MAAM,MAAM,WAAW,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,MAAM,GACN,WAAW,GACX,QAAQ,GACR,OAAO,GACP,OAAO,GACP,WAAW,GACX,YAAY,GACZ,MAAM,CAAC;AACb,MAAM,WAAW,WAAW;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1C,CAAC;IACF,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AACD,MAAM,WAAW,QAAS,SAAQ,WAAW;IACzC,OAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;CACnD;AACD,MAAM,WAAW,cAAe,SAAQ,WAAW;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,CAAC,SAAS,MAAM,GAAG,QAAQ,GAAG,CAAC,SAAS,YAAY,GAAG,cAAc,GAAG,WAAW,CAAC;CAC7F;AAmBD,0GAA0G;AAC1G,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;gBAClB,IAAI,EAAE,MAAM;IAGxB,KAAK,IAAI,IAAI;IAIb,kFAAkF;IAClF,IAAI,CACA,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,WAAW,CAAA;KAAO,GACrE;QAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAoBnD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,SAAS;IAQvE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE;IAG3D,8EAA8E;IAC9E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;IAMrC,sFAAsF;IACtF,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE;IAGtC,OAAO,CAAC,GAAG;CASd"}
1
+ {"version":3,"file":"store-reader.d.ts","sourceRoot":"","sources":["../../src/v2/store-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { V2TuiContext } from "./types";
2
+ type JsxFactory = (type: string, props: Record<string, unknown>) => unknown;
3
+ export declare function setupWithJsx(context: V2TuiContext, jsx: JsxFactory): Promise<() => void>;
4
+ export declare function setup(context: V2TuiContext): Promise<() => void>;
5
+ declare const _default: {
6
+ id: string;
7
+ setup: typeof setup;
8
+ };
9
+ export default _default;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v2/tui/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAoE5D,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;AAE5E,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAkL9F;AAED,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAEtE;;;;;AAED,wBAAuD"}
@@ -0,0 +1,80 @@
1
+ import type { SidebarSnapshot } from "../../shared/rpc-types";
2
+ export interface V2TuiLocation {
3
+ readonly directory: string;
4
+ }
5
+ export interface V2TuiRoute {
6
+ readonly type: string;
7
+ readonly sessionID?: string;
8
+ }
9
+ export interface V2TuiContext {
10
+ readonly location?: V2TuiLocation;
11
+ readonly renderer: {
12
+ requestRender(): void;
13
+ };
14
+ readonly data: {
15
+ readonly listen: (handler: (event: {
16
+ details: unknown;
17
+ }) => void) => () => void;
18
+ readonly location: {
19
+ default(): V2TuiLocation;
20
+ };
21
+ };
22
+ readonly keymap: {
23
+ readonly layer: (input: () => {
24
+ readonly mode?: string;
25
+ readonly commands: ReadonlyArray<{
26
+ readonly id: string;
27
+ readonly title: string;
28
+ readonly group: string;
29
+ readonly palette: true;
30
+ readonly slash: {
31
+ readonly name: string;
32
+ readonly arguments?: true;
33
+ };
34
+ readonly run: (input?: string) => void | Promise<void>;
35
+ }>;
36
+ }) => void;
37
+ };
38
+ readonly storage: {
39
+ readonly memory: <Value extends object>(key: string, options: {
40
+ readonly initial: Value;
41
+ }) => readonly [Value, (mutation: (draft: Value) => void) => void];
42
+ };
43
+ readonly ui: {
44
+ readonly router: {
45
+ current(): V2TuiRoute;
46
+ };
47
+ readonly slot: (claim: {
48
+ readonly append: "sidebar.content";
49
+ readonly render: (input: {
50
+ readonly sessionID: string;
51
+ }) => unknown;
52
+ }) => () => void;
53
+ readonly toast: {
54
+ show(options: {
55
+ readonly title?: string;
56
+ readonly message: string;
57
+ readonly variant?: "info" | "success" | "warning" | "error";
58
+ readonly duration?: number;
59
+ }): void;
60
+ };
61
+ readonly dialog: {
62
+ alert(options: {
63
+ readonly title: string;
64
+ readonly message: string;
65
+ }): Promise<void>;
66
+ confirm(options: {
67
+ readonly title: string;
68
+ readonly message: string;
69
+ readonly label?: {
70
+ readonly confirm?: string;
71
+ readonly cancel?: string;
72
+ };
73
+ }): Promise<boolean | undefined>;
74
+ };
75
+ };
76
+ }
77
+ export interface V2SidebarState {
78
+ snapshots: Record<string, SidebarSnapshot | undefined>;
79
+ }
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/v2/tui/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.42.4",
3
+ "version": "0.42.6",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -27,6 +27,7 @@
27
27
  "index.js",
28
28
  "src/tui",
29
29
  "src/tui-compiled",
30
+ "src/v2/tui",
30
31
  "src/shared",
31
32
  "src/config",
32
33
  "src/agents",
@@ -71,9 +72,9 @@
71
72
  "sharp": "^0.35.0"
72
73
  },
73
74
  "devDependencies": {
74
- "@opencode/plugin": "2.0.3",
75
- "@opencode/cli": "2.0.3",
76
- "@opencode/client": "2.0.3",
75
+ "@opencode/plugin": "2.0.5",
76
+ "@opencode/cli": "2.0.5",
77
+ "@opencode/client": "2.0.5",
77
78
  "effect": "4.0.0-rc.112",
78
79
  "@ai-sdk/anthropic": "3.0.82",
79
80
  "@huggingface/transformers": "^4.1.0",
@@ -74,7 +74,7 @@ function memoryGuidanceBlock(memoryEnabled: boolean): string {
74
74
  const BASE_INTRO = (
75
75
  memoryEnabled: boolean,
76
76
  ): string => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
77
- Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The newest token-mass window stays protected until displaced. Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
77
+ Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking QUEUES content for release. It stays fully visible to you until it is actually released, which may be the next turn or many turns later. Mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The newest token-mass window stays protected until displaced. Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
78
78
  Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
79
79
  ${CTX_NOTE_GUIDANCE}
80
80
  ${memoryGuidanceBlock(memoryEnabled)}Use \`ctx_search\` to search across project memories, indexed git commits, and this session's full conversation history (including compacted parts) from one query.
@@ -33,7 +33,11 @@ import {
33
33
  import { pruneNestedConfigLeaf } from "./prune-config-leaf";
34
34
  import { loadRawConfigFile } from "./raw-loader";
35
35
  import { stripRemovedAgentConfig } from "./removed-agent-config";
36
- import { type MagicContextConfig, MagicContextConfigSchema } from "./schema/magic-context";
36
+ import {
37
+ type MagicContextConfig,
38
+ MagicContextConfigSchema,
39
+ PROTECTED_TOKENS_MIN,
40
+ } from "./schema/magic-context";
37
41
  import { resolveTransformMode } from "./transform-mode";
38
42
  import { substituteConfigVariables } from "./variable";
39
43
 
@@ -323,6 +327,18 @@ function redactConfigValue(value: unknown): string {
323
327
 
324
328
  let warnedProtectedTagsDeprecation = false;
325
329
 
330
+ /**
331
+ * Specific warning for a protected_tokens value that is a number below the
332
+ * schema minimum. The generic "invalid value (number 20), using default
333
+ * undefined" message is true but unhelpful: it does not say the value is in the
334
+ * wrong unit (a leftover protected_tags tag count), and "using default
335
+ * undefined" reads like a bug. This branch fires ONLY for `number < min`;
336
+ * every other invalid value (wrong type, above max) keeps the generic message.
337
+ */
338
+ export function formatProtectedTokensBelowMinWarning(value: number): string {
339
+ return `protected_tokens is a token floor (minimum ${PROTECTED_TOKENS_MIN}, default derived from the context window); ${value} looks like the old protected_tags count. Remove the key to use the default, or set a token count such as 16000.`;
340
+ }
341
+
326
342
  export function resetProtectedTagsDeprecationWarningForTest(): void {
327
343
  warnedProtectedTagsDeprecation = false;
328
344
  }
@@ -483,6 +499,20 @@ export function parsePluginConfig(
483
499
  delete patched[key];
484
500
  const defaultVal = (defaults as unknown as Record<string, unknown>)[key];
485
501
  const reason = customMessagesByKey.get(key);
502
+ // A numeric protected_tokens below the schema minimum is almost always a
503
+ // leftover protected_tags tag count (10–30) renamed by hand. Replace the
504
+ // generic invalid-leaf message with one that names the unit mismatch.
505
+ // Scoped precisely to `number < min` so wrong-type and above-max values
506
+ // still get the generic message.
507
+ const invalidRawValue = rawConfig[key];
508
+ if (
509
+ key === "protected_tokens" &&
510
+ typeof invalidRawValue === "number" &&
511
+ invalidRawValue < PROTECTED_TOKENS_MIN
512
+ ) {
513
+ warnings.push(formatProtectedTokensBelowMinWarning(invalidRawValue));
514
+ continue;
515
+ }
486
516
  warnings.push(
487
517
  `"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.${reason ? ` ${reason}` : ""}`,
488
518
  );
@@ -188,6 +188,46 @@ describe("protected_tokens config and derivation", () => {
188
188
  });
189
189
  });
190
190
 
191
+ describe("protected_tokens below-minimum warning", () => {
192
+ it("emits the specific token-floor warning for a numeric value below the schema minimum", () => {
193
+ const recovered = parsePluginConfig({ protected_tokens: 20 });
194
+ const warnings = recovered.configWarnings ?? [];
195
+ expect(warnings.some((w) => w.includes("protected_tokens is a token floor"))).toBe(
196
+ true,
197
+ );
198
+ expect(warnings.some((w) => w.includes('"protected_tokens": invalid value'))).toBe(
199
+ false,
200
+ );
201
+ });
202
+
203
+ it("keeps the generic type message for a string value", () => {
204
+ const recovered = parsePluginConfig({ protected_tokens: "20" });
205
+ const warnings = recovered.configWarnings ?? [];
206
+ expect(warnings.some((w) => w.includes('"protected_tokens": invalid value'))).toBe(
207
+ true,
208
+ );
209
+ expect(warnings.some((w) => w.includes("protected_tokens is a token floor"))).toBe(
210
+ false,
211
+ );
212
+ });
213
+
214
+ it("keeps the generic above-max message for a value above the maximum", () => {
215
+ const recovered = parsePluginConfig({ protected_tokens: 2_000_000 });
216
+ const warnings = recovered.configWarnings ?? [];
217
+ expect(warnings.some((w) => w.includes('"protected_tokens": invalid value'))).toBe(
218
+ true,
219
+ );
220
+ expect(warnings.some((w) => w.includes("protected_tokens is a token floor"))).toBe(
221
+ false,
222
+ );
223
+ });
224
+
225
+ it("emits no warning when the key is absent", () => {
226
+ const recovered = parsePluginConfig({});
227
+ expect(recovered.configWarnings ?? []).toEqual([]);
228
+ });
229
+ });
230
+
191
231
  describe("protected_tags deprecation", () => {
192
232
  it("is parsed at any value (including 0 and 101) with parse succeeding and no numeric conversion", () => {
193
233
  resetProtectedTagsDeprecationWarningForTest();
@@ -18,6 +18,11 @@ export const EXECUTE_THRESHOLD_CAP_MESSAGE =
18
18
  export const DEFAULT_HISTORIAN_TIMEOUT_MS = 600_000;
19
19
  export const DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
20
20
 
21
+ // Minimum absolute token floor for protected_tokens. Kept as a named constant so
22
+ // the schema's `.min()` and the loader's below-minimum warning share ONE source
23
+ // of truth — the loader must not duplicate the literal 4000.
24
+ export const PROTECTED_TOKENS_MIN = 4000;
25
+
21
26
  export const DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
22
27
 
23
28
  // Re-exported from the (DB-free) task registry so the schema and the runtime
@@ -1107,10 +1112,10 @@ export const MagicContextConfigSchema = z
1107
1112
  .union([z.string(), z.object({ default: z.string() }).catchall(z.string())])
1108
1113
  .default("5m")
1109
1114
  .describe(
1110
- 'How long Magic Context assumes the provider\'s cached prefix stays valid. This is MC\'s own deferral gate — it does not change the provider\'s actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).',
1115
+ 'How long Magic Context assumes the provider\'s cached prefix stays valid. This is MC\'s own deferral gate — it does not change the provider\'s actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).',
1111
1116
  ),
1112
1117
  prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe(
1113
- "Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. 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).",
1118
+ "Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model.",
1114
1119
  ),
1115
1120
  output_reserve: z
1116
1121
  .union([
@@ -1160,7 +1165,7 @@ export const MagicContextConfigSchema = z
1160
1165
  protected_tokens: z
1161
1166
  .number()
1162
1167
  .int()
1163
- .min(4000)
1168
+ .min(PROTECTED_TOKENS_MIN)
1164
1169
  .max(1_000_000)
1165
1170
  .optional()
1166
1171
  .describe(
@@ -8,6 +8,8 @@
8
8
  * concurrently while memory-mutating tasks serialize. See lease.ts + the A+B spec.
9
9
  */
10
10
 
11
+ import type { CurateMemoryCategory } from "./curate-category-rotation";
12
+
11
13
  export const CANONICAL_DREAM_TASKS = [
12
14
  // map-memories runs BEFORE verify (it records the file mappings verify gates
13
15
  // on) and shares the memory lease, so it leads the canonical order.
@@ -52,6 +54,8 @@ export interface DreamTaskBacklog {
52
54
  pending: number;
53
55
  /** Total items in the task's candidate pool. */
54
56
  total: number;
57
+ /** Curate's one-category scope for this run/window. */
58
+ category?: CurateMemoryCategory;
55
59
  }
56
60
 
57
61
  /** Backlog counts keyed by canonical task name. */
@@ -66,6 +70,9 @@ export function formatDreamTaskBacklogs(
66
70
  .filter((task) => backlogs[task] !== undefined)
67
71
  .map((task) => {
68
72
  const backlog = backlogs[task];
73
+ if (task === "curate" && backlog?.category) {
74
+ return `- curate: ${backlog.category} (${backlog.pending})`;
75
+ }
69
76
  return `- ${task}: ${backlog?.pending ?? 0} pending / ${backlog?.total ?? 0} total`;
70
77
  })
71
78
  .join("\n");
@@ -77,6 +84,8 @@ export interface DreamTaskProgress {
77
84
  processed: number;
78
85
  total: number;
79
86
  startedAt: number;
87
+ /** Curate's one-category scope. */
88
+ category?: CurateMemoryCategory;
80
89
  /** Update/archive verdicts refused by host-side verification safety gates during the current run. */
81
90
  refused?: number;
82
91
  }
@@ -88,6 +97,7 @@ export interface DreamTaskRunBacklog {
88
97
  pendingAtEnd: number;
89
98
  totalAtEnd: number;
90
99
  processed: number;
100
+ category?: CurateMemoryCategory;
91
101
  }
92
102
 
93
103
  /** Use the decrease in the persisted backlog between the start and end snapshots as the per-run progress count, clamped to zero when the backlog does not decrease. */
@@ -0,0 +1,42 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+
3
+ export const AUTO_UPDATE_CHECK_STATE_FILENAME = "last-update-check.json";
4
+
5
+ export interface AutoUpdateCheckState {
6
+ lastCheckedMs?: number;
7
+ updaterPinnedSpec?: string;
8
+ updaterPinnedAt?: number;
9
+ }
10
+
11
+ export function readAutoUpdateCheckState(path: string): AutoUpdateCheckState | null {
12
+ if (!existsSync(path)) return null;
13
+ try {
14
+ const value = JSON.parse(readFileSync(path, "utf-8")) as unknown;
15
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
16
+ const raw = value as Record<string, unknown>;
17
+ const state: AutoUpdateCheckState = {};
18
+ if (typeof raw.lastCheckedMs === "number" && Number.isFinite(raw.lastCheckedMs)) {
19
+ state.lastCheckedMs = raw.lastCheckedMs;
20
+ }
21
+ if (typeof raw.updaterPinnedSpec === "string" && raw.updaterPinnedSpec.length > 0) {
22
+ state.updaterPinnedSpec = raw.updaterPinnedSpec;
23
+ }
24
+ if (typeof raw.updaterPinnedAt === "number" && Number.isFinite(raw.updaterPinnedAt)) {
25
+ state.updaterPinnedAt = raw.updaterPinnedAt;
26
+ }
27
+ return state;
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ export function isUpdaterPinnedSpec(
34
+ state: AutoUpdateCheckState | null,
35
+ configuredSpec: string,
36
+ ): boolean {
37
+ return (
38
+ state?.updaterPinnedSpec === configuredSpec &&
39
+ typeof state.updaterPinnedAt === "number" &&
40
+ Number.isFinite(state.updaterPinnedAt)
41
+ );
42
+ }
@@ -480,6 +480,59 @@ describe("detectConflicts", () => {
480
480
  });
481
481
  });
482
482
 
483
+ describe("OpenCode 2 compaction ownership", () => {
484
+ it("keeps MC enabled when host auto-compaction is on and never reads v1 prune", () => {
485
+ const previous = process.env.OPENCODE_DISABLE_AUTOCOMPACT;
486
+ delete process.env.OPENCODE_DISABLE_AUTOCOMPACT;
487
+ const resolved = {
488
+ auto: true,
489
+ get prune(): boolean {
490
+ throw new Error("v2 must not read compaction.prune");
491
+ },
492
+ keepTokens: 4_096,
493
+ buffer: 1_024,
494
+ };
495
+ const result = detectConflicts(projectDir, {
496
+ compactionEnabled: true,
497
+ hostGeneration: "v2",
498
+ resolvedCompaction: resolved,
499
+ });
500
+ expect(result.hasConflict).toBe(false);
501
+ expect(result.conflicts.compactionAuto).toBe(false);
502
+ expect(result.conflicts.compactionPrune).toBe(false);
503
+ expect(result.nativeCompaction).toEqual({ auto: true, prune: false });
504
+ if (previous === undefined) delete process.env.OPENCODE_DISABLE_AUTOCOMPACT;
505
+ else process.env.OPENCODE_DISABLE_AUTOCOMPACT = previous;
506
+ });
507
+
508
+ it("reads the GA v2 auto, keep.tokens, and buffer shape", async () => {
509
+ const result = await resolveCompactionForBoot(
510
+ {
511
+ config: {
512
+ get: async () => ({
513
+ data: {
514
+ compaction: {
515
+ auto: true,
516
+ keep: { tokens: 4_096 },
517
+ buffer: 1_024,
518
+ prune: true,
519
+ },
520
+ },
521
+ }),
522
+ },
523
+ },
524
+ 2_000,
525
+ "v2",
526
+ );
527
+ expect(result).toEqual({
528
+ auto: true,
529
+ prune: false,
530
+ keepTokens: 4_096,
531
+ buffer: 1_024,
532
+ });
533
+ });
534
+ });
535
+
483
536
  // --- Resolved-config arm (issue #309) ---
484
537
  // The plugin boot now consumes the host's RESOLVED config
485
538
  // (ctx.client.config.get()) instead of re-deriving compaction from files.