@cortexkit/opencode-magic-context 0.21.5 → 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.
@@ -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"}
@@ -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;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAgClD,QAAA,MAAM,MAAM,EAAE,MAgWb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAsClD,QAAA,MAAM,MAAM,EAAE,MA2Yb,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -166440,6 +166440,32 @@ var init_tui_config = __esm(() => {
166440
166440
  import_comment_json4 = __toESM(require_src2(), 1);
166441
166441
  PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
166442
166442
  });
166443
+ // src/agents/permissions.ts
166444
+ function buildAllowOnlyPermission(allowedTools) {
166445
+ const permission = { "*": "deny" };
166446
+ for (const tool of allowedTools) {
166447
+ permission[tool] = "allow";
166448
+ }
166449
+ return permission;
166450
+ }
166451
+ var HISTORIAN_ALLOWED_TOOLS = ["read", "aft_outline", "aft_zoom"];
166452
+ var DREAMER_ALLOWED_TOOLS = [
166453
+ "read",
166454
+ "grep",
166455
+ "glob",
166456
+ "bash",
166457
+ "aft_outline",
166458
+ "aft_zoom",
166459
+ "ctx_memory",
166460
+ "ctx_search",
166461
+ "ctx_note"
166462
+ ];
166463
+ var SIDEKICK_ALLOWED_TOOLS = [
166464
+ "ctx_search",
166465
+ "ctx_memory",
166466
+ "aft_outline",
166467
+ "aft_zoom"
166468
+ ];
166443
166469
  // src/config/index.ts
166444
166470
  init_jsonc_parser();
166445
166471
  init_magic_context();
@@ -177241,7 +177267,7 @@ function resolveConfigValue(cfg, key, modelKey, defaultValue) {
177241
177267
  }
177242
177268
  return defaultValue;
177243
177269
  }
177244
- function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens) {
177270
+ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config2) {
177245
177271
  const empty = {
177246
177272
  sessionId,
177247
177273
  usagePercentage: 0,
@@ -177265,7 +177291,8 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
177265
177291
  memoryTokens: 0,
177266
177292
  conversationTokens: 0,
177267
177293
  toolCallTokens: 0,
177268
- toolDefinitionTokens: 0
177294
+ toolDefinitionTokens: 0,
177295
+ executeThreshold: 65
177269
177296
  };
177270
177297
  try {
177271
177298
  const projectIdentity = resolveProjectIdentity(directory);
@@ -177384,6 +177411,18 @@ ${c.content}
177384
177411
  }
177385
177412
  }
177386
177413
  const contextLimit = activeProviderID && activeModelID ? resolveContextLimit(activeProviderID, activeModelID, { db, sessionID: sessionId }) : 0;
177414
+ let executeThreshold = 65;
177415
+ if (config2) {
177416
+ const modelKey = activeProviderID && activeModelID ? `${activeProviderID}/${activeModelID}` : undefined;
177417
+ const pctCfg = config2.execute_threshold_percentage;
177418
+ const tokensCfg = config2.execute_threshold_tokens;
177419
+ const thresholdDetail = resolveExecuteThresholdDetail(pctCfg ?? 65, modelKey, 65, {
177420
+ tokensConfig: tokensCfg,
177421
+ contextLimit: contextLimit || undefined,
177422
+ sessionId
177423
+ });
177424
+ executeThreshold = thresholdDetail.percentage;
177425
+ }
177387
177426
  const calibration = resolveModelCalibration(activeProviderID, activeModelID);
177388
177427
  const calibrated = calibrateBuckets({
177389
177428
  inputTokens,
@@ -177419,7 +177458,8 @@ ${c.content}
177419
177458
  memoryTokens: calibrated.memoryTokens,
177420
177459
  conversationTokens: calibrated.conversationTokens,
177421
177460
  toolCallTokens: calibrated.toolCallTokens,
177422
- toolDefinitionTokens: calibrated.toolDefinitionTokens
177461
+ toolDefinitionTokens: calibrated.toolDefinitionTokens,
177462
+ executeThreshold
177423
177463
  };
177424
177464
  return applyStickySnapshotCache(sessionId, fresh);
177425
177465
  } catch (err) {
@@ -177428,7 +177468,7 @@ ${c.content}
177428
177468
  }
177429
177469
  }
177430
177470
  function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSessionState, injectionBudgetTokens) {
177431
- const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens);
177471
+ const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config2);
177432
177472
  const detail = {
177433
177473
  ...base,
177434
177474
  tagCounter: 0,
@@ -177541,7 +177581,7 @@ function registerRpcHandlers(rpcServer, args) {
177541
177581
  const db = getDb();
177542
177582
  if (!db || !sessionId)
177543
177583
  return { error: "unavailable" };
177544
- return buildSidebarSnapshot(db, sessionId, dir, liveSessionState, injectionBudgetTokens);
177584
+ return buildSidebarSnapshot(db, sessionId, dir, liveSessionState, injectionBudgetTokens, rawConfig);
177545
177585
  });
177546
177586
  rpcServer.handle("status-detail", async (params) => {
177547
177587
  const sessionId = String(params.sessionId ?? "");
@@ -178921,13 +178961,21 @@ var plugin = async (ctx) => {
178921
178961
  await hooks.magicContext?.["experimental.text.complete"]?.(input, output);
178922
178962
  },
178923
178963
  config: async (config2) => {
178924
- const buildHiddenAgentConfig = (agentId, prompt, overrides) => ({
178925
- prompt,
178926
- ...getAgentFallbackModels(agentId) ? { fallback_models: getAgentFallbackModels(agentId) } : {},
178927
- ...overrides ?? {},
178928
- mode: "subagent",
178929
- hidden: true
178930
- });
178964
+ const buildHiddenAgentConfig = (agentId, prompt, allowedTools, overrides) => {
178965
+ const { permission: overridePermission, ...restOverrides } = overrides ?? {};
178966
+ const basePermission = buildAllowOnlyPermission(allowedTools);
178967
+ return {
178968
+ prompt,
178969
+ ...getAgentFallbackModels(agentId) ? { fallback_models: getAgentFallbackModels(agentId) } : {},
178970
+ ...restOverrides,
178971
+ permission: {
178972
+ ...basePermission,
178973
+ ...overridePermission ?? {}
178974
+ },
178975
+ mode: "subagent",
178976
+ hidden: true
178977
+ };
178978
+ };
178931
178979
  const commandConfig = {
178932
178980
  ...config2.command ?? {},
178933
178981
  ...getMagicContextBuiltinCommands(),
@@ -178960,10 +179008,10 @@ var plugin = async (ctx) => {
178960
179008
  })() : undefined;
178961
179009
  config2.agent = {
178962
179010
  ...config2.agent ?? {},
178963
- [DREAMER_AGENT]: buildHiddenAgentConfig(DREAMER_AGENT, DREAMER_SYSTEM_PROMPT, dreamerAgentOverrides),
178964
- [HISTORIAN_AGENT]: buildHiddenAgentConfig(HISTORIAN_AGENT, pluginConfig.dreamer?.user_memories?.enabled ? COMPARTMENT_AGENT_SYSTEM_PROMPT + USER_OBSERVATIONS_APPENDIX : COMPARTMENT_AGENT_SYSTEM_PROMPT, historianAgentOverrides),
178965
- [HISTORIAN_EDITOR_AGENT]: buildHiddenAgentConfig(HISTORIAN_EDITOR_AGENT, HISTORIAN_EDITOR_SYSTEM_PROMPT, historianAgentOverrides),
178966
- [SIDEKICK_AGENT]: buildHiddenAgentConfig(SIDEKICK_AGENT, SIDEKICK_SYSTEM_PROMPT, sidekickAgentOverrides)
179011
+ [DREAMER_AGENT]: buildHiddenAgentConfig(DREAMER_AGENT, DREAMER_SYSTEM_PROMPT, DREAMER_ALLOWED_TOOLS, dreamerAgentOverrides),
179012
+ [HISTORIAN_AGENT]: buildHiddenAgentConfig(HISTORIAN_AGENT, pluginConfig.dreamer?.user_memories?.enabled ? COMPARTMENT_AGENT_SYSTEM_PROMPT + USER_OBSERVATIONS_APPENDIX : COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_ALLOWED_TOOLS, historianAgentOverrides),
179013
+ [HISTORIAN_EDITOR_AGENT]: buildHiddenAgentConfig(HISTORIAN_EDITOR_AGENT, HISTORIAN_EDITOR_SYSTEM_PROMPT, HISTORIAN_ALLOWED_TOOLS, historianAgentOverrides),
179014
+ [SIDEKICK_AGENT]: buildHiddenAgentConfig(SIDEKICK_AGENT, SIDEKICK_SYSTEM_PROMPT, SIDEKICK_ALLOWED_TOOLS, sidekickAgentOverrides)
178967
179015
  };
178968
179016
  }
178969
179017
  };
@@ -7,7 +7,7 @@ import { type ContextDatabase as Database } from "../features/magic-context/stor
7
7
  import type { LiveSessionState } from "../hooks/magic-context/live-session-state";
8
8
  import type { MagicContextRpcServer } from "../shared/rpc-server";
9
9
  import type { SidebarSnapshot, StatusDetail } from "../shared/rpc-types";
10
- export declare function buildSidebarSnapshot(db: Database, sessionId: string, directory: string, liveSessionState?: LiveSessionState, injectionBudgetTokens?: number): SidebarSnapshot;
10
+ export declare function buildSidebarSnapshot(db: Database, sessionId: string, directory: string, liveSessionState?: LiveSessionState, injectionBudgetTokens?: number, config?: Record<string, unknown>): SidebarSnapshot;
11
11
  export declare function buildStatusDetail(db: Database, sessionId: string, directory: string, modelKey?: string, config?: Record<string, unknown>, liveSessionState?: LiveSessionState, injectionBudgetTokens?: number): StatusDetail;
12
12
  /**
13
13
  * Register all RPC handlers on the server.
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAWnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AASlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,eAAe,CAgTjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CAsKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAuIN"}
1
+ {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAWnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AASlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA6UjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CAuKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAwIN"}
@@ -44,6 +44,16 @@ export interface SidebarSnapshot {
44
44
  * shows this as "Tool Definitions".
45
45
  */
46
46
  toolDefinitionTokens: number;
47
+ /**
48
+ * Effective execute-threshold percentage for this session's active model,
49
+ * after per-model resolution and the tokens→percentage conversion (when
50
+ * `execute_threshold_tokens` applies). Surfaces in the sidebar / status
51
+ * dialog header alongside `usagePercentage` so users can see how close
52
+ * the session is to triggering compaction. Defaults to `65` when no live
53
+ * model is known yet — matches the runtime fallback used by the
54
+ * scheduler and transform paths.
55
+ */
56
+ executeThreshold: number;
47
57
  }
48
58
  export interface StatusDetail extends SidebarSnapshot {
49
59
  tagCounter: number;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAI/B;AAuFD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBhE"}
1
+ {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAI/B;AAwFD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.21.5",
3
+ "version": "0.21.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",
@@ -45,6 +45,16 @@ export interface SidebarSnapshot {
45
45
  * shows this as "Tool Definitions".
46
46
  */
47
47
  toolDefinitionTokens: number;
48
+ /**
49
+ * Effective execute-threshold percentage for this session's active model,
50
+ * after per-model resolution and the tokens→percentage conversion (when
51
+ * `execute_threshold_tokens` applies). Surfaces in the sidebar / status
52
+ * dialog header alongside `usagePercentage` so users can see how close
53
+ * the session is to triggering compaction. Defaults to `65` when no live
54
+ * model is known yet — matches the runtime fallback used by the
55
+ * scheduler and transform paths.
56
+ */
57
+ executeThreshold: number;
48
58
  }
49
59
 
50
60
  export interface StatusDetail extends SidebarSnapshot {
@@ -58,6 +58,7 @@ const EMPTY_SNAPSHOT: SidebarSnapshot = {
58
58
  conversationTokens: 0,
59
59
  toolCallTokens: 0,
60
60
  toolDefinitionTokens: 0,
61
+ executeThreshold: 65,
61
62
  };
62
63
 
63
64
  /**
package/src/tui/index.tsx CHANGED
@@ -290,11 +290,16 @@ const StatusDialog = (props: { api: TuiPluginApi; s: StatusDetail }) => {
290
290
  <text fg={t().textMuted}>v{packageJson.version}</text>
291
291
  </box>
292
292
 
293
- {/* Context summary line */}
293
+ {/* Context summary line. Mirrors the sidebar header layout
294
+ ("47.5% / 65% 475K / 1.0M") so users can recognize the
295
+ same shape in the status dialog. The execute threshold tells
296
+ them how close they are to compaction triggering. */}
294
297
  <box flexDirection="row" justifyContent="space-between" width="100%">
295
- <text fg={t().text}>Context</text>
296
298
  <text fg={s().usagePercentage >= 80 ? t().error : s().usagePercentage >= 65 ? t().warning : t().accent}>
297
- <b>{s().usagePercentage.toFixed(1)}%</b> · {fmt(s().inputTokens)} / {contextLimit() > 0 ? fmt(contextLimit()) : "?"} tokens
299
+ <b>{s().usagePercentage.toFixed(1)}%</b> / {s().executeThreshold}%
300
+ </text>
301
+ <text fg={s().usagePercentage >= 80 ? t().error : s().usagePercentage >= 65 ? t().warning : t().accent}>
302
+ {fmt(s().inputTokens)} / {contextLimit() > 0 ? fmt(contextLimit()) : "?"} tokens
298
303
  </text>
299
304
  </box>
300
305
 
@@ -363,9 +363,21 @@ const SidebarContent = (props: {
363
363
  {s() && s()!.inputTokens > 0 && (
364
364
  <box marginTop={1} flexDirection="column">
365
365
  {(s()?.contextLimit ?? 0) > 0 && (
366
- <box width="100%" flexDirection="row" justifyContent="flex-end">
366
+ <box width="100%" flexDirection="row" justifyContent="space-between">
367
+ {/* Left: current usage vs the per-model execute
368
+ threshold (the value Magic Context compares
369
+ against when scheduling historian / drops).
370
+ "47.5% / 65%" tells the user how close they
371
+ are to the next compaction trigger. */}
367
372
  <text fg={contextSummaryColor()}>
368
- <b>{s()!.usagePercentage.toFixed(1)}%</b> · {compactTokens(s()!.inputTokens)} / {compactTokens(s()!.contextLimit)}
373
+ <b>{s()!.usagePercentage.toFixed(1)}%</b> / {s()!.executeThreshold}%
374
+ </text>
375
+ {/* Right: absolute token usage vs the model's
376
+ full context window (separate from the
377
+ execute threshold so users still know how
378
+ much headroom remains beyond compaction). */}
379
+ <text fg={contextSummaryColor()}>
380
+ {compactTokens(s()!.inputTokens)} / {compactTokens(s()!.contextLimit)}
369
381
  </text>
370
382
  </box>
371
383
  )}