@cortexkit/opencode-magic-context 0.21.4 → 0.21.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 (40) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/permissions.d.ts +142 -0
  3. package/dist/agents/permissions.d.ts.map +1 -0
  4. package/dist/config/index.d.ts.map +1 -1
  5. package/dist/config/schema/agent-overrides.d.ts +12 -12
  6. package/dist/config/schema/magic-context.d.ts +87 -87
  7. package/dist/config/variable.d.ts +9 -7
  8. package/dist/config/variable.d.ts.map +1 -1
  9. package/dist/features/magic-context/key-files/project-key-files.d.ts.map +1 -1
  10. package/dist/features/magic-context/migrations.d.ts +18 -0
  11. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  12. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  13. package/dist/features/magic-context/storage-meta-persisted.d.ts +17 -0
  14. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  15. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  16. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  17. package/dist/features/magic-context/storage-notes.d.ts +6 -2
  18. package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
  19. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage.d.ts +1 -1
  21. package/dist/features/magic-context/storage.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/compartment-trigger.d.ts +2 -2
  23. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +186 -60
  27. package/dist/plugin/rpc-handlers.d.ts +1 -1
  28. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  29. package/dist/shared/jsonc-parser.d.ts +1 -0
  30. package/dist/shared/jsonc-parser.d.ts.map +1 -1
  31. package/dist/shared/rpc-types.d.ts +10 -0
  32. package/dist/shared/rpc-types.d.ts.map +1 -1
  33. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  34. package/dist/tui/data/context-db.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/src/shared/jsonc-parser.ts +1 -1
  37. package/src/shared/rpc-types.ts +10 -0
  38. package/src/tui/data/context-db.ts +1 -0
  39. package/src/tui/index.tsx +8 -3
  40. package/src/tui/slots/sidebar-content.tsx +14 -2
package/README.md CHANGED
@@ -386,7 +386,7 @@ On startup, Magic Context checks for common configuration problems — OpenCode'
386
386
  A companion desktop app for browsing and managing Magic Context state outside of OpenCode.
387
387
 
388
388
  <p align="center">
389
- <a href="https://github.com/cortexkit/magic-context/releases/tag/dashboard-v0.4.5"><strong>⬇️ Download for macOS · Windows · Linux</strong></a></p>
389
+ <a href="https://github.com/cortexkit/magic-context/releases/tag/dashboard-v0.4.6"><strong>⬇️ Download for macOS · Windows · Linux</strong></a></p>
390
390
 
391
391
  **Features:**
392
392
  - **Memory Browser** — search, filter, and edit project memories with category and project filtering
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Permission rulesets for Magic Context's hidden subagents.
3
+ *
4
+ * # Why this exists
5
+ *
6
+ * Hidden agents (`historian`, `historian-editor`, `dreamer`, `sidekick`) are
7
+ * registered with `mode: "subagent"` and `hidden: true`, but those flags
8
+ * only control visibility in the UI picker — they do NOT restrict which
9
+ * tools the spawned session can call. By default a registered subagent
10
+ * inherits the FULL primary-agent tool surface: `task`, `bash`, `edit`,
11
+ * `webfetch`, `websearch`, `read`, `grep`, `glob`, every MCP tool, etc.
12
+ *
13
+ * That default is wrong for our agents:
14
+ * - Historian should be a pure XML-emitting summarizer. It must not
15
+ * dispatch `task(subagent_type=explore)` to fan out, edit files,
16
+ * run bash, or fetch the web — its job is to read offloaded state
17
+ * files and emit `<compartment>` blocks.
18
+ * - The `task` permission only gets auto-denied when an agent is
19
+ * INVOKED via the parent's `task()` tool (see OpenCode's
20
+ * `deriveSubagentSessionPermission`). Our hidden agents are spawned
21
+ * directly via `client.session.prompt(...)` from the plugin
22
+ * runtime, so that auto-deny never fires — they get the same
23
+ * `task` permission as a primary `build` agent.
24
+ *
25
+ * # Design
26
+ *
27
+ * Each hidden agent's `permission` field starts with `{ "*": "deny" }`
28
+ * and adds explicit `allow` entries for ONLY the tool ids it needs.
29
+ * OpenCode's `Permission.fromConfig` converts this flat map into a
30
+ * `Rule[]` ruleset where later entries override earlier ones, so the
31
+ * named allows always win against the wildcard deny.
32
+ *
33
+ * This is the same pattern OpenCode's own `explore` subagent uses
34
+ * (see `packages/opencode/src/agent/agent.ts:179-201`).
35
+ *
36
+ * User-supplied agent overrides (`pluginConfig.historian.permission`,
37
+ * etc.) still merge on top via OpenCode's `Permission.merge`, so
38
+ * advanced users can extend the allow-list without us blocking them.
39
+ *
40
+ * # What each agent needs
41
+ *
42
+ * - **historian / historian-editor / compressor**: `read` plus the
43
+ * read-only AFT navigation tools `aft_outline` and `aft_zoom`.
44
+ * The runner offloads large existing-state XML to a temp file
45
+ * under `<project>/.opencode/magic-context/historian/` and the
46
+ * prompt instructs the model to read that file. AFT navigation
47
+ * is allowed so historian can verify a symbol or file structure
48
+ * when writing accurate compartment summaries.
49
+ *
50
+ * - **dreamer**: `read`, `grep`, `glob`, `bash`, the read-only AFT
51
+ * navigation tools `aft_outline` and `aft_zoom`, plus the Magic
52
+ * Context MCP tools `ctx_memory`, `ctx_search`, `ctx_note`.
53
+ * Dreamer task prompts in
54
+ * `features/magic-context/dreamer/task-prompts.ts` explicitly tell
55
+ * the model to grep schema files for defaults, read source to
56
+ * confirm claims, run `git log` / `gh` / `curl` for verify and
57
+ * smart-note evaluation, and use glob/find for directory
58
+ * inventory. Live DB shows >100 bash invocations across all
59
+ * dreamer task variants. `task` / `edit` / `write` / `webfetch` /
60
+ * `websearch` remain denied — dreamer must not spawn subagents
61
+ * or commit changes.
62
+ *
63
+ * - **sidekick**: `ctx_search`, `ctx_memory`, plus the read-only AFT
64
+ * navigation tools `aft_outline` and `aft_zoom`. Sidekick's job
65
+ * is augmenting user prompts via memory retrieval — see
66
+ * `features/magic-context/sidekick/agent.ts`. AFT navigation lets
67
+ * it pull symbol-scoped structural context for prompts that
68
+ * reference a specific file or symbol.
69
+ */
70
+ /**
71
+ * Build a `permission` map suitable for `AgentConfig.permission`. Starts
72
+ * with a wildcard deny, then layers in the named tool allows on top.
73
+ * OpenCode's `Permission.fromConfig` preserves insertion order and its
74
+ * `evaluate` uses `findLast`, so named allows defeat the wildcard deny.
75
+ *
76
+ * Returns `Record<string, "deny" | "allow">` which the SDK's
77
+ * `AgentConfig.permission` type accepts via its `[key: string]: unknown`
78
+ * index signature. The same pattern is used by OpenCode's built-in
79
+ * `explore`/`scout`/`general` agents and by Alfonso for its static
80
+ * agent profiles.
81
+ */
82
+ export declare function buildAllowOnlyPermission(allowedTools: readonly string[]): Record<string, "deny" | "allow">;
83
+ /**
84
+ * Tools the historian + historian-editor + compressor agents need.
85
+ *
86
+ * Historian runners offload large `<existing_state>` XML to disk and
87
+ * tell the model to `read` it before emitting the summary XML. The
88
+ * core need is `read`; we also allow the read-only AFT navigation
89
+ * tools `aft_outline` and `aft_zoom` so that if a historian/compressor
90
+ * ever needs to verify a symbol or skim a file's structure to write
91
+ * an accurate compartment summary, it can do so token-efficiently
92
+ * instead of pulling whole files via `read`.
93
+ *
94
+ * Still denied: bash, edit, write, task, grep/glob, webfetch/
95
+ * websearch. Historian's job is summarizing the input it was given,
96
+ * not exploring the repo.
97
+ */
98
+ export declare const HISTORIAN_ALLOWED_TOOLS: readonly ["read", "aft_outline", "aft_zoom"];
99
+ /**
100
+ * Tools the dreamer agent needs. This is the broadest hidden-agent
101
+ * surface because dreamer's tasks legitimately require local-repo
102
+ * exploration plus external command execution:
103
+ *
104
+ * - `ctx_memory` / `ctx_search` / `ctx_note` — the canonical memory
105
+ * CRUD and retrieval path for consolidate / verify / archive /
106
+ * improve and smart-note dismissal.
107
+ * - `read` / `grep` / `glob` — the verify task prompt
108
+ * (`task-prompts.ts`) explicitly tells the model to grep schema
109
+ * files for default values, read source to confirm claimed
110
+ * behavior, and use glob for project structure inventory.
111
+ * - `bash` — required for smart-note condition evaluation (the
112
+ * prompt explicitly mentions `gh` / `git` / `curl` / file reads),
113
+ * for the verify task's `git log --oneline --since=...` step, and
114
+ * for the improve task's `find` / `grep` directory inventory. The
115
+ * live OpenCode DB shows over 100 `bash` invocations across
116
+ * consolidate / verify / improve / archive-stale / smart-notes
117
+ * dreamer child sessions, so removing it would regress real,
118
+ * documented dreamer behavior.
119
+ *
120
+ * Deliberately NOT allowed:
121
+ * - `task` — no subagent fanout from dreamer
122
+ * - `edit` / `write` — dreamer must not modify project files;
123
+ * `task-prompts.ts` explicitly states "Do not commit changes"
124
+ * - `webfetch` / `websearch` — out of scope; smart-note URL fetches
125
+ * go through `bash` + `curl` instead
126
+ */
127
+ export declare const DREAMER_ALLOWED_TOOLS: readonly ["read", "grep", "glob", "bash", "aft_outline", "aft_zoom", "ctx_memory", "ctx_search", "ctx_note"];
128
+ /**
129
+ * Tools the sidekick agent needs. Sidekick is a read-only memory
130
+ * retriever for `/ctx-aug` — it queries the project's memory store
131
+ * via `ctx_search` and (rarely) reads specific memories with
132
+ * `ctx_memory(action="list")`.
133
+ *
134
+ * Also allow `aft_outline` and `aft_zoom` so sidekick can pull
135
+ * lightweight structural context about a file or symbol when the
136
+ * user's prompt references it directly — token-efficient navigation
137
+ * without dragging in whole files.
138
+ *
139
+ * Still denied: spawning subagents, edits, bash, web fetches.
140
+ */
141
+ export declare const SIDEKICK_ALLOWED_TOOLS: readonly ["ctx_search", "ctx_memory", "aft_outline", "aft_zoom"];
142
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/agents/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACpC,YAAY,EAAE,SAAS,MAAM,EAAE,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAMlC;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,8CAA+C,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,qBAAqB,8GAUxB,CAAC;AAEX;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,kEAKzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAA4B,MAAM,wBAAwB,CAAC;AAG3F,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAChE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CACZ,MAAM,EACN;QACI,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;KACrB,CACJ,CAAC;CACL;AAmBD,MAAM,MAAM,WAAW,GACjB,IAAI,GACJ,0BAA0B,GAC1B,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,CAAC;AAE7B,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,wBAAwB,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE;QACL,UAAU,EAAE,WAAW,CAAC;QACxB,aAAa,EAAE,WAAW,CAAC;KAC9B,CAAC;IACF,oBAAoB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9F,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACnC;AA0VD,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,MAAM,GAClB,wBAAwB,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA2E1D;AAgDD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAuE9E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAA4B,MAAM,wBAAwB,CAAC;AAG3F,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAChE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CACZ,MAAM,EACN;QACI,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;KACrB,CACJ,CAAC;CACL;AAmBD,MAAM,MAAM,WAAW,GACjB,IAAI,GACJ,0BAA0B,GAC1B,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,CAAC;AAE7B,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,wBAAwB,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE;QACL,UAAU,EAAE,WAAW,CAAC;QACxB,aAAa,EAAE,WAAW,CAAC;KAC9B,CAAC;IACF,oBAAoB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9F,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACnC;AAkWD,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,MAAM,GAClB,wBAAwB,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA2E1D;AAgDD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAuE9E"}
@@ -18,33 +18,33 @@ export declare const AgentOverrideConfigSchema: z.ZodObject<{
18
18
  maxSteps: z.ZodOptional<z.ZodNumber>;
19
19
  permission: z.ZodOptional<z.ZodObject<{
20
20
  edit: z.ZodOptional<z.ZodEnum<{
21
- ask: "ask";
22
- allow: "allow";
23
21
  deny: "deny";
22
+ allow: "allow";
23
+ ask: "ask";
24
24
  }>>;
25
25
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
26
- ask: "ask";
27
- allow: "allow";
28
26
  deny: "deny";
29
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
30
- ask: "ask";
31
27
  allow: "allow";
28
+ ask: "ask";
29
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
32
30
  deny: "deny";
31
+ allow: "allow";
32
+ ask: "ask";
33
33
  }>>]>>;
34
34
  webfetch: z.ZodOptional<z.ZodEnum<{
35
- ask: "ask";
36
- allow: "allow";
37
35
  deny: "deny";
36
+ allow: "allow";
37
+ ask: "ask";
38
38
  }>>;
39
39
  doom_loop: z.ZodOptional<z.ZodEnum<{
40
- ask: "ask";
41
- allow: "allow";
42
40
  deny: "deny";
41
+ allow: "allow";
42
+ ask: "ask";
43
43
  }>>;
44
44
  external_directory: z.ZodOptional<z.ZodEnum<{
45
- ask: "ask";
46
- allow: "allow";
47
45
  deny: "deny";
46
+ allow: "allow";
47
+ ask: "ask";
48
48
  }>>;
49
49
  }, z.core.$strip>>;
50
50
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -58,33 +58,33 @@ export declare const DreamerConfigSchema: z.ZodObject<{
58
58
  maxSteps: z.ZodOptional<z.ZodNumber>;
59
59
  permission: z.ZodOptional<z.ZodObject<{
60
60
  edit: z.ZodOptional<z.ZodEnum<{
61
- ask: "ask";
62
- allow: "allow";
63
61
  deny: "deny";
62
+ allow: "allow";
63
+ ask: "ask";
64
64
  }>>;
65
65
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
66
- ask: "ask";
67
- allow: "allow";
68
66
  deny: "deny";
69
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
70
- ask: "ask";
71
67
  allow: "allow";
68
+ ask: "ask";
69
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
72
70
  deny: "deny";
71
+ allow: "allow";
72
+ ask: "ask";
73
73
  }>>]>>;
74
74
  webfetch: z.ZodOptional<z.ZodEnum<{
75
- ask: "ask";
76
- allow: "allow";
77
75
  deny: "deny";
76
+ allow: "allow";
77
+ ask: "ask";
78
78
  }>>;
79
79
  doom_loop: z.ZodOptional<z.ZodEnum<{
80
- ask: "ask";
81
- allow: "allow";
82
80
  deny: "deny";
81
+ allow: "allow";
82
+ ask: "ask";
83
83
  }>>;
84
84
  external_directory: z.ZodOptional<z.ZodEnum<{
85
- ask: "ask";
86
- allow: "allow";
87
85
  deny: "deny";
86
+ allow: "allow";
87
+ ask: "ask";
88
88
  }>>;
89
89
  }, z.core.$strip>>;
90
90
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -138,33 +138,33 @@ export declare const SidekickConfigSchema: z.ZodOptional<z.ZodObject<{
138
138
  maxSteps: z.ZodOptional<z.ZodNumber>;
139
139
  permission: z.ZodOptional<z.ZodObject<{
140
140
  edit: z.ZodOptional<z.ZodEnum<{
141
- ask: "ask";
142
- allow: "allow";
143
141
  deny: "deny";
142
+ allow: "allow";
143
+ ask: "ask";
144
144
  }>>;
145
145
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
146
- ask: "ask";
147
- allow: "allow";
148
146
  deny: "deny";
149
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
150
- ask: "ask";
151
147
  allow: "allow";
148
+ ask: "ask";
149
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
152
150
  deny: "deny";
151
+ allow: "allow";
152
+ ask: "ask";
153
153
  }>>]>>;
154
154
  webfetch: z.ZodOptional<z.ZodEnum<{
155
- ask: "ask";
156
- allow: "allow";
157
155
  deny: "deny";
156
+ allow: "allow";
157
+ ask: "ask";
158
158
  }>>;
159
159
  doom_loop: z.ZodOptional<z.ZodEnum<{
160
- ask: "ask";
161
- allow: "allow";
162
160
  deny: "deny";
161
+ allow: "allow";
162
+ ask: "ask";
163
163
  }>>;
164
164
  external_directory: z.ZodOptional<z.ZodEnum<{
165
- ask: "ask";
166
- allow: "allow";
167
165
  deny: "deny";
166
+ allow: "allow";
167
+ ask: "ask";
168
168
  }>>;
169
169
  }, z.core.$strip>>;
170
170
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -205,33 +205,33 @@ export declare const HistorianConfigSchema: z.ZodOptional<z.ZodObject<{
205
205
  maxSteps: z.ZodOptional<z.ZodNumber>;
206
206
  permission: z.ZodOptional<z.ZodObject<{
207
207
  edit: z.ZodOptional<z.ZodEnum<{
208
- ask: "ask";
209
- allow: "allow";
210
208
  deny: "deny";
209
+ allow: "allow";
210
+ ask: "ask";
211
211
  }>>;
212
212
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
213
- ask: "ask";
214
- allow: "allow";
215
213
  deny: "deny";
216
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
217
- ask: "ask";
218
214
  allow: "allow";
215
+ ask: "ask";
216
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
219
217
  deny: "deny";
218
+ allow: "allow";
219
+ ask: "ask";
220
220
  }>>]>>;
221
221
  webfetch: z.ZodOptional<z.ZodEnum<{
222
- ask: "ask";
223
- allow: "allow";
224
222
  deny: "deny";
223
+ allow: "allow";
224
+ ask: "ask";
225
225
  }>>;
226
226
  doom_loop: z.ZodOptional<z.ZodEnum<{
227
- ask: "ask";
228
- allow: "allow";
229
227
  deny: "deny";
228
+ allow: "allow";
229
+ ask: "ask";
230
230
  }>>;
231
231
  external_directory: z.ZodOptional<z.ZodEnum<{
232
- ask: "ask";
233
- allow: "allow";
234
232
  deny: "deny";
233
+ allow: "allow";
234
+ ask: "ask";
235
235
  }>>;
236
236
  }, z.core.$strip>>;
237
237
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -416,33 +416,33 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
416
416
  maxSteps: z.ZodOptional<z.ZodNumber>;
417
417
  permission: z.ZodOptional<z.ZodObject<{
418
418
  edit: z.ZodOptional<z.ZodEnum<{
419
- ask: "ask";
420
- allow: "allow";
421
419
  deny: "deny";
420
+ allow: "allow";
421
+ ask: "ask";
422
422
  }>>;
423
423
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
424
- ask: "ask";
425
- allow: "allow";
426
424
  deny: "deny";
427
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
428
- ask: "ask";
429
425
  allow: "allow";
426
+ ask: "ask";
427
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
430
428
  deny: "deny";
429
+ allow: "allow";
430
+ ask: "ask";
431
431
  }>>]>>;
432
432
  webfetch: z.ZodOptional<z.ZodEnum<{
433
- ask: "ask";
434
- allow: "allow";
435
433
  deny: "deny";
434
+ allow: "allow";
435
+ ask: "ask";
436
436
  }>>;
437
437
  doom_loop: z.ZodOptional<z.ZodEnum<{
438
- ask: "ask";
439
- allow: "allow";
440
438
  deny: "deny";
439
+ allow: "allow";
440
+ ask: "ask";
441
441
  }>>;
442
442
  external_directory: z.ZodOptional<z.ZodEnum<{
443
- ask: "ask";
444
- allow: "allow";
445
443
  deny: "deny";
444
+ allow: "allow";
445
+ ask: "ask";
446
446
  }>>;
447
447
  }, z.core.$strip>>;
448
448
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -475,33 +475,33 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
475
475
  maxSteps: z.ZodOptional<z.ZodNumber>;
476
476
  permission: z.ZodOptional<z.ZodObject<{
477
477
  edit: z.ZodOptional<z.ZodEnum<{
478
- ask: "ask";
479
- allow: "allow";
480
478
  deny: "deny";
479
+ allow: "allow";
480
+ ask: "ask";
481
481
  }>>;
482
482
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
483
- ask: "ask";
484
- allow: "allow";
485
483
  deny: "deny";
486
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
487
- ask: "ask";
488
484
  allow: "allow";
485
+ ask: "ask";
486
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
489
487
  deny: "deny";
488
+ allow: "allow";
489
+ ask: "ask";
490
490
  }>>]>>;
491
491
  webfetch: z.ZodOptional<z.ZodEnum<{
492
- ask: "ask";
493
- allow: "allow";
494
492
  deny: "deny";
493
+ allow: "allow";
494
+ ask: "ask";
495
495
  }>>;
496
496
  doom_loop: z.ZodOptional<z.ZodEnum<{
497
- ask: "ask";
498
- allow: "allow";
499
497
  deny: "deny";
498
+ allow: "allow";
499
+ ask: "ask";
500
500
  }>>;
501
501
  external_directory: z.ZodOptional<z.ZodEnum<{
502
- ask: "ask";
503
- allow: "allow";
504
502
  deny: "deny";
503
+ allow: "allow";
504
+ ask: "ask";
505
505
  }>>;
506
506
  }, z.core.$strip>>;
507
507
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -636,33 +636,33 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
636
636
  maxSteps: z.ZodOptional<z.ZodNumber>;
637
637
  permission: z.ZodOptional<z.ZodObject<{
638
638
  edit: z.ZodOptional<z.ZodEnum<{
639
- ask: "ask";
640
- allow: "allow";
641
639
  deny: "deny";
640
+ allow: "allow";
641
+ ask: "ask";
642
642
  }>>;
643
643
  bash: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
644
- ask: "ask";
645
- allow: "allow";
646
644
  deny: "deny";
647
- }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
648
- ask: "ask";
649
645
  allow: "allow";
646
+ ask: "ask";
647
+ }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
650
648
  deny: "deny";
649
+ allow: "allow";
650
+ ask: "ask";
651
651
  }>>]>>;
652
652
  webfetch: z.ZodOptional<z.ZodEnum<{
653
- ask: "ask";
654
- allow: "allow";
655
653
  deny: "deny";
654
+ allow: "allow";
655
+ ask: "ask";
656
656
  }>>;
657
657
  doom_loop: z.ZodOptional<z.ZodEnum<{
658
- ask: "ask";
659
- allow: "allow";
660
658
  deny: "deny";
659
+ allow: "allow";
660
+ ask: "ask";
661
661
  }>>;
662
662
  external_directory: z.ZodOptional<z.ZodEnum<{
663
- ask: "ask";
664
- allow: "allow";
665
663
  deny: "deny";
664
+ allow: "allow";
665
+ ask: "ask";
666
666
  }>>;
667
667
  }, z.core.$strip>>;
668
668
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -763,11 +763,11 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
763
763
  color?: string | undefined;
764
764
  maxSteps?: number | undefined;
765
765
  permission?: {
766
- edit?: "ask" | "allow" | "deny" | undefined;
767
- bash?: "ask" | "allow" | "deny" | Record<string, "ask" | "allow" | "deny"> | undefined;
768
- webfetch?: "ask" | "allow" | "deny" | undefined;
769
- doom_loop?: "ask" | "allow" | "deny" | undefined;
770
- external_directory?: "ask" | "allow" | "deny" | undefined;
766
+ edit?: "deny" | "allow" | "ask" | undefined;
767
+ bash?: "deny" | "allow" | "ask" | Record<string, "deny" | "allow" | "ask"> | undefined;
768
+ webfetch?: "deny" | "allow" | "ask" | undefined;
769
+ doom_loop?: "deny" | "allow" | "ask" | undefined;
770
+ external_directory?: "deny" | "allow" | "ask" | undefined;
771
771
  } | undefined;
772
772
  maxTokens?: number | undefined;
773
773
  variant?: string | undefined;
@@ -801,11 +801,11 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
801
801
  color?: string | undefined;
802
802
  maxSteps?: number | undefined;
803
803
  permission?: {
804
- edit?: "ask" | "allow" | "deny" | undefined;
805
- bash?: "ask" | "allow" | "deny" | Record<string, "ask" | "allow" | "deny"> | undefined;
806
- webfetch?: "ask" | "allow" | "deny" | undefined;
807
- doom_loop?: "ask" | "allow" | "deny" | undefined;
808
- external_directory?: "ask" | "allow" | "deny" | undefined;
804
+ edit?: "deny" | "allow" | "ask" | undefined;
805
+ bash?: "deny" | "allow" | "ask" | Record<string, "deny" | "allow" | "ask"> | undefined;
806
+ webfetch?: "deny" | "allow" | "ask" | undefined;
807
+ doom_loop?: "deny" | "allow" | "ask" | undefined;
808
+ external_directory?: "deny" | "allow" | "ask" | undefined;
809
809
  } | undefined;
810
810
  maxTokens?: number | undefined;
811
811
  variant?: string | undefined;
@@ -831,11 +831,11 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
831
831
  color?: string | undefined;
832
832
  maxSteps?: number | undefined;
833
833
  permission?: {
834
- edit?: "ask" | "allow" | "deny" | undefined;
835
- bash?: "ask" | "allow" | "deny" | Record<string, "ask" | "allow" | "deny"> | undefined;
836
- webfetch?: "ask" | "allow" | "deny" | undefined;
837
- doom_loop?: "ask" | "allow" | "deny" | undefined;
838
- external_directory?: "ask" | "allow" | "deny" | undefined;
834
+ edit?: "deny" | "allow" | "ask" | undefined;
835
+ bash?: "deny" | "allow" | "ask" | Record<string, "deny" | "allow" | "ask"> | undefined;
836
+ webfetch?: "deny" | "allow" | "ask" | undefined;
837
+ doom_loop?: "deny" | "allow" | "ask" | undefined;
838
+ external_directory?: "deny" | "allow" | "ask" | undefined;
839
839
  } | undefined;
840
840
  maxTokens?: number | undefined;
841
841
  variant?: string | undefined;
@@ -9,6 +9,11 @@ export interface SubstituteInput {
9
9
  * so callers should prefer passing a real path when one exists.
10
10
  */
11
11
  configPath?: string;
12
+ /**
13
+ * Project-level config files are untrusted repository input. Do not expand
14
+ * secret-bearing tokens there; leave them literal and warn instead.
15
+ */
16
+ isProjectConfig?: boolean;
12
17
  }
13
18
  export interface SubstituteResult {
14
19
  /** Config text with all `{env:X}` and `{file:path}` tokens replaced. */
@@ -25,7 +30,7 @@ export interface SubstituteResult {
25
30
  *
26
31
  * Mirrors OpenCode's `ConfigVariable.substitute` semantics so users can share
27
32
  * the same patterns across `opencode.json(c)` and `magic-context.jsonc`:
28
- * - `{env:VAR}` → `process.env.VAR` (trimmed key), empty string when missing
33
+ * - `{env:VAR}` → `process.env.VAR` (trimmed key), JSON-escaped for safe inlining, empty string when missing
29
34
  * - `{file:~/path}` → contents of `~/path`, JSON-escaped for safe inlining
30
35
  * - `{file:./rel}` or `{file:rel}` → resolved against the config file's dir
31
36
  * - `{file:/abs}` → resolved as absolute
@@ -35,12 +40,9 @@ export interface SubstituteResult {
35
40
  * typo in an optional embedding key should not prevent the plugin from loading
36
41
  * with other (valid) settings.
37
42
  *
38
- * File content substitution is JSON-escaped (wrapped then unwrapped through
39
- * `JSON.stringify`) so line breaks, quotes, and backslashes in file contents
40
- * survive the subsequent JSONC parse. Env value substitution is NOT escaped,
41
- * matching OpenCode — env values are typically API keys without JSON-special
42
- * characters. Users who need to embed a value with quotes or newlines should
43
- * use `{file:...}`.
43
+ * File and env value substitution is JSON-escaped (wrapped then unwrapped
44
+ * through `JSON.stringify`) so line breaks, quotes, and backslashes survive
45
+ * the subsequent JSONC parse.
44
46
  */
45
47
  export declare function substituteConfigVariables(input: SubstituteInput): SubstituteResult;
46
48
  //# sourceMappingURL=variable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"variable.d.ts","sourceRoot":"","sources":["../../src/config/variable.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC7B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAKD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CA6ElF"}
1
+ {"version":3,"file":"variable.d.ts","sourceRoot":"","sources":["../../src/config/variable.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC7B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAqGlF"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-key-files.d.ts","sourceRoot":"","sources":["../../../../src/features/magic-context/key-files/project-key-files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC1C;AAED,QAAA,MAAM,oBAAoB,cAAc,CAAC;AAGzC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAO/E;AAiBD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAY1F;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQ7E;AAED,wBAAgB,kBAAkB,CAC9B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,aAAa,EAAE,GACvB,qBAAqB,EAAE,CAiBzB;AAED,wBAAgB,sBAAsB,CAClC,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,WAAW,SAAa,GACzB,MAAM,CAsCR;AAED,wBAAgB,sBAAsB,CAClC,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,qBAAqB,EAAE,EAC9B,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAC/B,oBAAoB,EAAE,MAAM,GAC7B,IAAI,CAoBN;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAa,GAAG,MAAM,CAyBlF;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAUxF;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"project-key-files.d.ts","sourceRoot":"","sources":["../../../../src/features/magic-context/key-files/project-key-files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC1C;AAED,QAAA,MAAM,oBAAoB,cAAc,CAAC;AAGzC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAO/E;AAiBD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAY1F;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQ7E;AAED,wBAAgB,kBAAkB,CAC9B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,aAAa,EAAE,GACvB,qBAAqB,EAAE,CAiBzB;AAED,wBAAgB,sBAAsB,CAClC,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,WAAW,SAAa,GACzB,MAAM,CAsCR;AAED,wBAAgB,sBAAsB,CAClC,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,qBAAqB,EAAE,EAC9B,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,EAC/B,oBAAoB,EAAE,MAAM,GAC7B,IAAI,CAoBN;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAa,GAAG,MAAM,CA6BlF;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAUxF;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,4 +1,22 @@
1
1
  import type { Database } from "../../shared/sqlite";
2
+ /**
3
+ * Detect the specific case where a sibling process already committed the
4
+ * same `schema_migrations` row we're about to insert. Two OpenCode/Pi
5
+ * instances starting concurrently can both read `MAX(version)=N` before
6
+ * either commits. The first commits v(N+1); the second's transaction body
7
+ * runs `migration.up()` (a no-op now that the schema change already
8
+ * landed), then hits PRIMARY KEY conflict on the
9
+ * `INSERT INTO schema_migrations` row.
10
+ *
11
+ * Without this guard the plugin fail-closes and the second instance
12
+ * refuses to start. With it, we recognize "sibling beat us to it",
13
+ * re-read the version, and continue from the next pending migration.
14
+ *
15
+ * Important: only PRIMARY KEY conflicts on `schema_migrations` are
16
+ * swallowed. Any other failure (CREATE TABLE, ALTER TABLE, data heal,
17
+ * etc.) surfaces normally and fail-closes per contract.
18
+ */
19
+ export declare function isSiblingMigrationConflict(db: Database, error: unknown, version: number): boolean;
2
20
  /**
3
21
  * Run all pending migrations sequentially.
4
22
  * Each migration runs in its own transaction — if it fails, only that migration rolls back.
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAyqBpD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAgEhD"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAspBpD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAkBjG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAgEhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage-db.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/storage-db.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAyE/C,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CA0arD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAIrD;AAgGD,wBAAgB,YAAY,CACxB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACnB,IAAI,CAqBN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CA4DvC;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAEzD;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAEvE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAUpC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"storage-db.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/storage-db.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAyE/C,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAmbrD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAIrD;AAgGD,wBAAgB,YAAY,CACxB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACnB,IAAI,CAqBN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CA4DvC;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAEzD;AAED,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAEvE;AAED,wBAAgB,aAAa,IAAI,IAAI,CAUpC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -206,6 +206,23 @@ export declare function setPendingCompactionMarkerState(db: Database, sessionId:
206
206
  * pending stays intact for B's own next consuming pass.
207
207
  */
208
208
  export declare function clearPendingCompactionMarkerStateIf(db: Database, sessionId: string, expected: PendingCompactionMarker): boolean;
209
+ /**
210
+ * Payload stored in `session_meta.pending_pi_compaction_marker_state` between
211
+ * a Pi historian/recomp publication and the next materializing Pi context pass.
212
+ * Stored with `stableStringify` so CAS clear can compare byte-for-byte.
213
+ */
214
+ export interface PendingPiCompactionMarker {
215
+ firstKeptEntryId: string;
216
+ endMessageId: string;
217
+ ordinal: number;
218
+ tokensBefore: number;
219
+ summary: string;
220
+ publishedAt: number;
221
+ }
222
+ export declare function getPendingPiCompactionMarkerState(db: Database, sessionId: string): PendingPiCompactionMarker | null;
223
+ export declare function setPendingPiCompactionMarkerState(db: Database, sessionId: string, state: PendingPiCompactionMarker | null): void;
224
+ export declare function clearPendingPiCompactionMarkerStateIf(db: Database, sessionId: string, expected: PendingPiCompactionMarker): boolean;
225
+ export declare function getSessionsWithPendingPiMarker(db: Database): string[];
209
226
  export declare function peekDeferredExecutePending(db: Database, sessionId: string): DeferredExecutePayload | null;
210
227
  export declare function setDeferredExecutePendingIfAbsent(db: Database, sessionId: string, payload: DeferredExecutePayload): boolean;
211
228
  export declare function clearDeferredExecutePendingIfMatches(db: Database, sessionId: string, expected: DeferredExecutePayload): boolean;