@cortexkit/opencode-magic-context 0.38.1 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/profiles.d.ts +22 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/project-security.d.ts +14 -6
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/raw-loader.d.ts +42 -0
- package/dist/config/raw-loader.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +966 -531
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts +3 -2
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +9 -2
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +4 -2
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts +21 -5
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts +3 -2
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts +2 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +0 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +3 -2
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts +5 -2
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts +6 -3
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts +11 -1
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-failure.d.ts +11 -0
- package/dist/features/magic-context/memory/embedding-failure.d.ts.map +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts +5 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-provider.d.ts +3 -0
- package/dist/features/magic-context/memory/embedding-provider.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts +3 -2
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +2 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +3 -2
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +2 -0
- package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +2 -2
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -2
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +1 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +10 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +11 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +3 -2
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +3 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +4 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +4 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +4 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +14 -2
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +7 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-failure.d.ts +3 -0
- package/dist/hooks/magic-context/format-embed-failure.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +13 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +14 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts +13 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +1 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +12 -0
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +4 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +6 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +12 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +5 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +9 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-2y0ybv5x.js → index-3dkzzh0t.js} +15 -17
- package/dist/{index-5znjkjws.js → index-axpym70t.js} +879 -170
- package/dist/index-ehpzdy0v.js +126 -0
- package/dist/{index-22mw8km4.js → index-rw0qrkvq.js} +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18466 -16177
- package/dist/model-resolution-r9jbcz86.js +15 -0
- package/dist/plugin/dream-timer.d.ts +3 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +2 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +14 -6
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-p030kxtc.js → recomp-orchestrator-dmyvqekw.js} +2 -3
- package/dist/shared/jsonc-edit.d.ts +6 -1
- package/dist/shared/jsonc-edit.d.ts.map +1 -1
- package/dist/shared/model-resolution.d.ts +53 -0
- package/dist/shared/model-resolution.d.ts.map +1 -0
- package/dist/shared/model-suggestion-retry.d.ts +4 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/resolve-fallbacks.d.ts +5 -1
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +2 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +12 -1
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts +4 -0
- package/dist/shared/status-detail-text.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +2 -1
- package/dist/shared/subagent-runner.d.ts.map +1 -1
- package/dist/{storage-meta-session-2306t3j7.js → storage-meta-session-yvtbaw7c.js} +1 -1
- package/dist/{task-config-at3adc59.js → task-config-a1qmj9bx.js} +2 -2
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/config/index.test.ts +434 -19
- package/src/config/index.ts +67 -33
- package/src/config/profiles.ts +106 -0
- package/src/config/project-security.hostile-matrix.test.ts +480 -0
- package/src/config/project-security.test.ts +43 -5
- package/src/config/project-security.ts +151 -22
- package/src/config/raw-loader.test.ts +424 -0
- package/src/config/raw-loader.ts +490 -0
- package/src/config/schema/magic-context.test.ts +272 -2
- package/src/config/schema/magic-context.ts +342 -49
- package/src/shared/jsonc-edit.ts +74 -1
- package/src/shared/model-resolution.test.ts +170 -0
- package/src/shared/model-resolution.ts +227 -0
- package/src/shared/model-suggestion-retry.test.ts +27 -0
- package/src/shared/model-suggestion-retry.ts +19 -10
- package/src/shared/resolve-fallbacks.test.ts +13 -1
- package/src/shared/resolve-fallbacks.ts +19 -4
- package/src/shared/rpc-types.ts +2 -0
- package/src/shared/rpc-utils.test.ts +32 -0
- package/src/shared/rpc-utils.ts +38 -13
- package/src/shared/status-detail-text.test.ts +82 -0
- package/src/shared/status-detail-text.ts +57 -0
- package/src/shared/subagent-runner.ts +3 -1
- package/src/tui/data/context-db.ts +1 -0
- package/src/tui-compiled/data/context-db.ts +1 -0
- package/dist/index-td9depx5.js +0 -46
- package/dist/resolve-fallbacks-qf0ekmz9.js +0 -11
|
@@ -104,6 +104,286 @@ export const PromptSurfaceConfigSchema = z
|
|
|
104
104
|
);
|
|
105
105
|
export type PromptSurfaceConfig = z.infer<typeof PromptSurfaceConfigSchema>;
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* The flat model-resolution fields are the only fields that move into harness
|
|
109
|
+
* blocks. Keeping this inventory next to the schema gives the loader migration
|
|
110
|
+
* an exhaustive contract instead of a catch-all rule.
|
|
111
|
+
*/
|
|
112
|
+
export const PER_HARNESS_MIGRATION_INVENTORY = {
|
|
113
|
+
historian: {
|
|
114
|
+
retained: [
|
|
115
|
+
"temperature",
|
|
116
|
+
"top_p",
|
|
117
|
+
"prompt",
|
|
118
|
+
"tools",
|
|
119
|
+
"disable",
|
|
120
|
+
"description",
|
|
121
|
+
"mode",
|
|
122
|
+
"color",
|
|
123
|
+
"maxSteps",
|
|
124
|
+
"permission",
|
|
125
|
+
"maxTokens",
|
|
126
|
+
"two_pass",
|
|
127
|
+
"disallowed_tools",
|
|
128
|
+
],
|
|
129
|
+
migrated_execution: ["model", "fallback_models", "variant", "thinking_level"],
|
|
130
|
+
},
|
|
131
|
+
dreamer: {
|
|
132
|
+
retained: [
|
|
133
|
+
"temperature",
|
|
134
|
+
"top_p",
|
|
135
|
+
"prompt",
|
|
136
|
+
"tools",
|
|
137
|
+
"disable",
|
|
138
|
+
"description",
|
|
139
|
+
"mode",
|
|
140
|
+
"color",
|
|
141
|
+
"maxSteps",
|
|
142
|
+
"permission",
|
|
143
|
+
"maxTokens",
|
|
144
|
+
"inject_docs",
|
|
145
|
+
],
|
|
146
|
+
migrated_execution: ["model", "fallback_models", "variant", "thinking_level"],
|
|
147
|
+
},
|
|
148
|
+
task: {
|
|
149
|
+
retained: ["schedule", "promotion_threshold"],
|
|
150
|
+
migrated_execution: [
|
|
151
|
+
"model",
|
|
152
|
+
"fallback_models",
|
|
153
|
+
"variant",
|
|
154
|
+
"thinking_level",
|
|
155
|
+
"timeout_minutes",
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
} as const;
|
|
159
|
+
|
|
160
|
+
/** OpenCode entry objects permit `variant` and reject Pi-only `thinking_level`. */
|
|
161
|
+
const OcEntryObjectSchema = z
|
|
162
|
+
.object({
|
|
163
|
+
model: z.string().describe("OpenCode model ID (for example, provider/model)."),
|
|
164
|
+
variant: z.string().optional().describe("OpenCode reasoning variant for this entry."),
|
|
165
|
+
})
|
|
166
|
+
.strict();
|
|
167
|
+
export const OcEntrySchema = z.union([z.string(), OcEntryObjectSchema]);
|
|
168
|
+
export type OcEntry = z.infer<typeof OcEntrySchema>;
|
|
169
|
+
|
|
170
|
+
/** Pi entry objects permit `thinking_level` and reject OpenCode-only `variant`. */
|
|
171
|
+
const PiEntryObjectSchema = z
|
|
172
|
+
.object({
|
|
173
|
+
model: z.string().describe("Pi model ID (for example, provider/model)."),
|
|
174
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi thinking level for this entry."),
|
|
175
|
+
})
|
|
176
|
+
.strict();
|
|
177
|
+
export const PiEntrySchema = z.union([z.string(), PiEntryObjectSchema]);
|
|
178
|
+
export type PiEntry = z.infer<typeof PiEntrySchema>;
|
|
179
|
+
|
|
180
|
+
/** Strict model-resolution block used by historian.opencode. */
|
|
181
|
+
export const OpenCodeHarnessBlockSchema = z
|
|
182
|
+
.object({
|
|
183
|
+
model: OcEntrySchema.optional().describe("Primary OpenCode model entry."),
|
|
184
|
+
fallback_models: z
|
|
185
|
+
.array(OcEntrySchema)
|
|
186
|
+
.optional()
|
|
187
|
+
.describe(
|
|
188
|
+
"Ordered fallback OpenCode entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array.",
|
|
189
|
+
),
|
|
190
|
+
variant: z
|
|
191
|
+
.string()
|
|
192
|
+
.optional()
|
|
193
|
+
.describe(
|
|
194
|
+
"OpenCode reasoning variant for the primary entry when it declares none. Fallback entries declare variants per-entry.",
|
|
195
|
+
),
|
|
196
|
+
})
|
|
197
|
+
.strict()
|
|
198
|
+
.describe("Strict OpenCode model-resolution block. It accepts no Pi vocabulary.");
|
|
199
|
+
export type OpenCodeHarnessBlock = z.infer<typeof OpenCodeHarnessBlockSchema>;
|
|
200
|
+
|
|
201
|
+
/** Strict model-resolution block used by historian.pi. */
|
|
202
|
+
export const PiHarnessBlockSchema = z
|
|
203
|
+
.object({
|
|
204
|
+
model: PiEntrySchema.optional().describe("Primary Pi model entry."),
|
|
205
|
+
fallback_models: z
|
|
206
|
+
.array(PiEntrySchema)
|
|
207
|
+
.optional()
|
|
208
|
+
.describe(
|
|
209
|
+
"Ordered fallback Pi entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array.",
|
|
210
|
+
),
|
|
211
|
+
thinking_level: PiThinkingLevelSchema.describe(
|
|
212
|
+
"Pi thinking level for the primary entry when it declares none. Fallback entries declare thinking levels per-entry.",
|
|
213
|
+
),
|
|
214
|
+
})
|
|
215
|
+
.strict()
|
|
216
|
+
.describe("Strict Pi model-resolution block. It accepts no OpenCode vocabulary.");
|
|
217
|
+
export type PiHarnessBlock = z.infer<typeof PiHarnessBlockSchema>;
|
|
218
|
+
|
|
219
|
+
/** Strict OpenCode-only execution override for one dreamer task. */
|
|
220
|
+
export const OpenCodeTaskExecutionSchema = z
|
|
221
|
+
.object({
|
|
222
|
+
model: OcEntrySchema.optional().describe("OpenCode model entry for this task."),
|
|
223
|
+
fallback_models: z
|
|
224
|
+
.array(OcEntrySchema)
|
|
225
|
+
.optional()
|
|
226
|
+
.describe("Ordered OpenCode fallback entries for this task."),
|
|
227
|
+
variant: z
|
|
228
|
+
.string()
|
|
229
|
+
.optional()
|
|
230
|
+
.describe(
|
|
231
|
+
"OpenCode reasoning variant for this task's primary entry when it declares none. Fallback entries declare variants per-entry.",
|
|
232
|
+
),
|
|
233
|
+
timeout_minutes: z
|
|
234
|
+
.number()
|
|
235
|
+
.min(5)
|
|
236
|
+
.optional()
|
|
237
|
+
.describe("Minutes allowed for this task before it is aborted."),
|
|
238
|
+
})
|
|
239
|
+
.strict();
|
|
240
|
+
export type OpenCodeTaskExecution = z.infer<typeof OpenCodeTaskExecutionSchema>;
|
|
241
|
+
|
|
242
|
+
/** Strict Pi-only execution override for one dreamer task. */
|
|
243
|
+
export const PiTaskExecutionSchema = z
|
|
244
|
+
.object({
|
|
245
|
+
model: PiEntrySchema.optional().describe("Pi model entry for this task."),
|
|
246
|
+
fallback_models: z
|
|
247
|
+
.array(PiEntrySchema)
|
|
248
|
+
.optional()
|
|
249
|
+
.describe("Ordered Pi fallback entries for this task."),
|
|
250
|
+
thinking_level: PiThinkingLevelSchema.describe(
|
|
251
|
+
"Pi thinking level for this task's primary entry when it declares none. Fallback entries declare thinking levels per-entry.",
|
|
252
|
+
),
|
|
253
|
+
timeout_minutes: z
|
|
254
|
+
.number()
|
|
255
|
+
.min(5)
|
|
256
|
+
.optional()
|
|
257
|
+
.describe("Minutes allowed for this task before it is aborted."),
|
|
258
|
+
})
|
|
259
|
+
.strict();
|
|
260
|
+
export type PiTaskExecution = z.infer<typeof PiTaskExecutionSchema>;
|
|
261
|
+
|
|
262
|
+
/** Strict OpenCode harness block for dreamer execution and task overrides. */
|
|
263
|
+
export const DreamerOpenCodeHarnessBlockSchema = z
|
|
264
|
+
.object({
|
|
265
|
+
model: OcEntrySchema.optional().describe("Primary OpenCode model entry."),
|
|
266
|
+
fallback_models: z
|
|
267
|
+
.array(OcEntrySchema)
|
|
268
|
+
.optional()
|
|
269
|
+
.describe(
|
|
270
|
+
"Ordered fallback OpenCode entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array.",
|
|
271
|
+
),
|
|
272
|
+
variant: z
|
|
273
|
+
.string()
|
|
274
|
+
.optional()
|
|
275
|
+
.describe(
|
|
276
|
+
"OpenCode reasoning variant for the primary entry when it declares none. Fallback entries declare variants per-entry.",
|
|
277
|
+
),
|
|
278
|
+
tasks: z
|
|
279
|
+
.record(z.string(), OpenCodeTaskExecutionSchema)
|
|
280
|
+
.optional()
|
|
281
|
+
.describe(
|
|
282
|
+
"OpenCode task execution overrides. Each named task accepts only model, fallback_models, variant, and timeout_minutes.",
|
|
283
|
+
),
|
|
284
|
+
})
|
|
285
|
+
.strict()
|
|
286
|
+
.describe("Strict OpenCode dreamer model-resolution block. It accepts no Pi vocabulary.");
|
|
287
|
+
export type DreamerOpenCodeHarnessBlock = z.infer<typeof DreamerOpenCodeHarnessBlockSchema>;
|
|
288
|
+
|
|
289
|
+
/** Strict Pi harness block for dreamer execution and task overrides. */
|
|
290
|
+
export const DreamerPiHarnessBlockSchema = z
|
|
291
|
+
.object({
|
|
292
|
+
model: PiEntrySchema.optional().describe("Primary Pi model entry."),
|
|
293
|
+
fallback_models: z
|
|
294
|
+
.array(PiEntrySchema)
|
|
295
|
+
.optional()
|
|
296
|
+
.describe(
|
|
297
|
+
"Ordered fallback Pi entries. New-shape configuration requires an array; legacy singleton values migrate to a one-element array.",
|
|
298
|
+
),
|
|
299
|
+
thinking_level: PiThinkingLevelSchema.describe(
|
|
300
|
+
"Pi thinking level for the primary entry when it declares none. Fallback entries declare thinking levels per-entry.",
|
|
301
|
+
),
|
|
302
|
+
tasks: z
|
|
303
|
+
.record(z.string(), PiTaskExecutionSchema)
|
|
304
|
+
.optional()
|
|
305
|
+
.describe(
|
|
306
|
+
"Pi task execution overrides. Each named task accepts only model, fallback_models, thinking_level, and timeout_minutes.",
|
|
307
|
+
),
|
|
308
|
+
})
|
|
309
|
+
.strict()
|
|
310
|
+
.describe("Strict Pi dreamer model-resolution block. It accepts no OpenCode vocabulary.");
|
|
311
|
+
export type DreamerPiHarnessBlock = z.infer<typeof DreamerPiHarnessBlockSchema>;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* A profile may select models but must not alter execution policy. Keep this
|
|
315
|
+
* separate from the full harness schemas, whose dreamer blocks also admit task
|
|
316
|
+
* overrides such as timeout_minutes.
|
|
317
|
+
*/
|
|
318
|
+
const ProfileOpenCodeModelBlockSchema = z
|
|
319
|
+
.object({
|
|
320
|
+
model: OcEntrySchema.optional().describe("Primary OpenCode model entry."),
|
|
321
|
+
fallback_models: z
|
|
322
|
+
.array(OcEntrySchema)
|
|
323
|
+
.optional()
|
|
324
|
+
.describe("Ordered fallback OpenCode model entries."),
|
|
325
|
+
variant: z
|
|
326
|
+
.string()
|
|
327
|
+
.optional()
|
|
328
|
+
.describe("OpenCode reasoning variant for the primary model entry."),
|
|
329
|
+
})
|
|
330
|
+
.strict()
|
|
331
|
+
.describe("Strict profile-only OpenCode model-selection block.");
|
|
332
|
+
const ProfilePiModelBlockSchema = z
|
|
333
|
+
.object({
|
|
334
|
+
model: PiEntrySchema.optional().describe("Primary Pi model entry."),
|
|
335
|
+
fallback_models: z
|
|
336
|
+
.array(PiEntrySchema)
|
|
337
|
+
.optional()
|
|
338
|
+
.describe("Ordered fallback Pi model entries."),
|
|
339
|
+
thinking_level: PiThinkingLevelSchema.describe(
|
|
340
|
+
"Pi thinking level for the primary model entry.",
|
|
341
|
+
),
|
|
342
|
+
})
|
|
343
|
+
.strict()
|
|
344
|
+
.describe("Strict profile-only Pi model-selection block.");
|
|
345
|
+
const ProfileHistorianSchema = z
|
|
346
|
+
.object({
|
|
347
|
+
opencode: ProfileOpenCodeModelBlockSchema.optional(),
|
|
348
|
+
pi: ProfilePiModelBlockSchema.optional(),
|
|
349
|
+
})
|
|
350
|
+
.strict();
|
|
351
|
+
const ProfileDreamerSchema = z
|
|
352
|
+
.object({
|
|
353
|
+
opencode: ProfileOpenCodeModelBlockSchema.optional(),
|
|
354
|
+
pi: ProfilePiModelBlockSchema.optional(),
|
|
355
|
+
})
|
|
356
|
+
.strict();
|
|
357
|
+
const ProfileSidekickSchema = AgentOverrideConfigSchema.pick({
|
|
358
|
+
model: true,
|
|
359
|
+
fallback_models: true,
|
|
360
|
+
variant: true,
|
|
361
|
+
})
|
|
362
|
+
.extend({
|
|
363
|
+
thinking_level: PiThinkingLevelSchema.describe(
|
|
364
|
+
"Pi thinking level for the sidekick model selection.",
|
|
365
|
+
),
|
|
366
|
+
})
|
|
367
|
+
.strict();
|
|
368
|
+
|
|
369
|
+
export const ConfigProfileSchema = z
|
|
370
|
+
.object({
|
|
371
|
+
historian: ProfileHistorianSchema.optional(),
|
|
372
|
+
dreamer: ProfileDreamerSchema.optional(),
|
|
373
|
+
sidekick: ProfileSidekickSchema.optional(),
|
|
374
|
+
})
|
|
375
|
+
.strict()
|
|
376
|
+
.describe(
|
|
377
|
+
"User-owned model-selection overlay. Only historian/dreamer harness model blocks and sidekick model-selection fields are allowed.",
|
|
378
|
+
);
|
|
379
|
+
export type ConfigProfile = z.infer<typeof ConfigProfileSchema>;
|
|
380
|
+
|
|
381
|
+
export const ConfigProfilesSchema = z.record(
|
|
382
|
+
z.string().trim().min(1, "Profile names must not be empty or whitespace-only."),
|
|
383
|
+
ConfigProfileSchema,
|
|
384
|
+
);
|
|
385
|
+
export type ConfigProfiles = z.infer<typeof ConfigProfilesSchema>;
|
|
386
|
+
|
|
107
387
|
/** A 5-field cron expression, or "" to disable the task. */
|
|
108
388
|
const CronScheduleSchema = z
|
|
109
389
|
.string()
|
|
@@ -113,23 +393,15 @@ const CronScheduleSchema = z
|
|
|
113
393
|
})
|
|
114
394
|
.describe('5-field cron schedule (e.g. "0 3 * * *"), or "" to disable this task.');
|
|
115
395
|
|
|
116
|
-
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
.describe("Per-task fallback chain (inherits dreamer.fallback_models)"),
|
|
126
|
-
thinking_level: PiThinkingLevelSchema.describe("Pi only: per-task thinking level"),
|
|
127
|
-
timeout_minutes: z
|
|
128
|
-
.number()
|
|
129
|
-
.min(5)
|
|
130
|
-
.default(20)
|
|
131
|
-
.describe("Minutes allowed for this task before it is aborted"),
|
|
132
|
-
});
|
|
396
|
+
/**
|
|
397
|
+
* Harness-independent task metadata. These fields stay at dreamer.tasks.<task>
|
|
398
|
+
* during per-harness migration; model execution fields are deliberately absent.
|
|
399
|
+
*/
|
|
400
|
+
const DreamTaskBaseConfigSchema = z
|
|
401
|
+
.object({
|
|
402
|
+
schedule: CronScheduleSchema.default(""),
|
|
403
|
+
})
|
|
404
|
+
.strict();
|
|
133
405
|
|
|
134
406
|
const PromotionThresholdSchema = z
|
|
135
407
|
.number()
|
|
@@ -188,11 +460,8 @@ function defaultTaskConfig(task: DreamTaskName): z.input<typeof DreamTaskConfigS
|
|
|
188
460
|
return base;
|
|
189
461
|
}
|
|
190
462
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
/** The `tasks` record: one entry per canonical task, each defaulting to its
|
|
194
|
-
* v1-behavior-preserving schedule. Written explicitly (not via fromEntries) so
|
|
195
|
-
* the inferred type stays a precise per-key object. */
|
|
463
|
+
/** The harness-independent task metadata record. Schedule remains the only
|
|
464
|
+
* disable control; runtime gates are not configuration fields. */
|
|
196
465
|
export const DreamTasksSchema = z
|
|
197
466
|
.object({
|
|
198
467
|
"map-memories": DreamTaskBaseConfigSchema.default(() =>
|
|
@@ -233,50 +502,59 @@ export const DreamTasksSchema = z
|
|
|
233
502
|
),
|
|
234
503
|
})
|
|
235
504
|
.describe(
|
|
236
|
-
"
|
|
505
|
+
"Harness-independent task metadata. schedule, promotion_threshold, and other task metadata remain here; execution settings live under dreamer.opencode.tasks or dreamer.pi.tasks.",
|
|
237
506
|
);
|
|
238
507
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
508
|
+
const AgentMetadataSchema = AgentOverrideConfigSchema.pick({
|
|
509
|
+
temperature: true,
|
|
510
|
+
top_p: true,
|
|
511
|
+
prompt: true,
|
|
512
|
+
tools: true,
|
|
513
|
+
disable: true,
|
|
514
|
+
description: true,
|
|
515
|
+
mode: true,
|
|
516
|
+
color: true,
|
|
517
|
+
maxSteps: true,
|
|
518
|
+
permission: true,
|
|
519
|
+
maxTokens: true,
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
/** Combined dreamer metadata plus two independent strict execution blocks. */
|
|
523
|
+
export const DreamerConfigSchema = AgentMetadataSchema.extend({
|
|
524
|
+
opencode: DreamerOpenCodeHarnessBlockSchema.optional(),
|
|
525
|
+
pi: DreamerPiHarnessBlockSchema.optional(),
|
|
526
|
+
tasks: DreamTasksSchema.default(() => DreamTasksSchema.parse({})),
|
|
527
|
+
inject_docs: z
|
|
528
|
+
.boolean()
|
|
529
|
+
.default(true)
|
|
530
|
+
.describe(
|
|
531
|
+
"Inject ARCHITECTURE.md and STRUCTURE.md into the m[0] `<project-docs>` block (default true)",
|
|
251
532
|
),
|
|
252
|
-
|
|
253
|
-
);
|
|
533
|
+
});
|
|
254
534
|
export type DreamerConfig = z.infer<typeof DreamerConfigSchema>;
|
|
255
535
|
|
|
256
536
|
export const SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
257
537
|
timeout_ms: z.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
|
|
258
538
|
system_prompt: z.string().optional().describe("Custom system prompt for sidekick"),
|
|
259
539
|
thinking_level: PiThinkingLevelSchema.describe(
|
|
260
|
-
"Pi only: explicit thinking level for sidekick subagent invocations. See historian.thinking_level.",
|
|
540
|
+
"Pi only: explicit thinking level for sidekick subagent invocations. See historian.pi.thinking_level.",
|
|
261
541
|
),
|
|
262
542
|
}).optional();
|
|
263
543
|
export type SidekickConfig = NonNullable<z.infer<typeof SidekickConfigSchema>>;
|
|
264
544
|
|
|
265
|
-
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
545
|
+
/**
|
|
546
|
+
* Historian metadata remains harness-independent. Only model resolution moves to
|
|
547
|
+
* the strict opencode and pi blocks; two_pass and disallowed_tools stay here.
|
|
548
|
+
*/
|
|
549
|
+
export const HistorianConfigSchema = AgentMetadataSchema.extend({
|
|
550
|
+
opencode: OpenCodeHarnessBlockSchema.optional(),
|
|
551
|
+
pi: PiHarnessBlockSchema.optional(),
|
|
271
552
|
two_pass: z
|
|
272
553
|
.boolean()
|
|
273
554
|
.default(false)
|
|
274
555
|
.describe(
|
|
275
556
|
"Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)",
|
|
276
557
|
),
|
|
277
|
-
thinking_level: PiThinkingLevelSchema.describe(
|
|
278
|
-
"Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh | max",
|
|
279
|
-
),
|
|
280
558
|
disallowed_tools: z
|
|
281
559
|
.array(z.enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"]))
|
|
282
560
|
.default([])
|
|
@@ -468,6 +746,10 @@ export interface MagicContextConfig {
|
|
|
468
746
|
auto_update?: boolean;
|
|
469
747
|
/** Output language for generated Magic Context prose. USER config only. */
|
|
470
748
|
language?: string;
|
|
749
|
+
/** Active user-owned model profile after user/project resolution. */
|
|
750
|
+
profile?: string;
|
|
751
|
+
/** Named user-owned model profiles. Declarations are consumed during resolution. */
|
|
752
|
+
profiles?: ConfigProfiles;
|
|
471
753
|
historian?: HistorianConfig;
|
|
472
754
|
dreamer?: DreamerConfig;
|
|
473
755
|
smart_notes: {
|
|
@@ -688,11 +970,22 @@ export const MagicContextConfigSchema = z
|
|
|
688
970
|
"triggers one cache re-materialization; existing compartments/memories keep their " +
|
|
689
971
|
"original language until naturally rewritten.",
|
|
690
972
|
),
|
|
973
|
+
profile: z
|
|
974
|
+
.string()
|
|
975
|
+
.trim()
|
|
976
|
+
.min(1)
|
|
977
|
+
.optional()
|
|
978
|
+
.describe(
|
|
979
|
+
"Select a named user-owned model profile. A valid project name overrides this user default; an empty string, null, or other non-string project value is ignored with a warning so the user selection still applies. Unknown names warn and use the base configuration.",
|
|
980
|
+
),
|
|
981
|
+
profiles: ConfigProfilesSchema.optional().describe(
|
|
982
|
+
"User-level named model profiles. A profile may contain only historian/dreamer model, fallback_models, OpenCode variant, and Pi thinking_level fields plus sidekick model-selection fields; task execution policy (including timeout_minutes) is excluded. Project configs may select a name but cannot define profiles.",
|
|
983
|
+
),
|
|
691
984
|
historian: HistorianConfigSchema.describe(
|
|
692
|
-
"Historian
|
|
985
|
+
"Historian metadata plus independent strict OpenCode and Pi execution blocks. Retained metadata stays at historian; model, fallback_models, variant, and thinking_level belong only in historian.opencode or historian.pi.",
|
|
693
986
|
),
|
|
694
987
|
dreamer: DreamerConfigSchema.optional().describe(
|
|
695
|
-
"Dreamer
|
|
988
|
+
"Dreamer metadata and scheduling plus independent strict OpenCode and Pi execution blocks. schedule and promotion_threshold stay at dreamer.tasks; model, fallback_models, variant, thinking_level, and timeout_minutes belong only in the matching harness block.",
|
|
696
989
|
),
|
|
697
990
|
smart_notes: z
|
|
698
991
|
.object({
|
package/src/shared/jsonc-edit.ts
CHANGED
|
@@ -8,7 +8,14 @@ import {
|
|
|
8
8
|
type Node,
|
|
9
9
|
type ParseError,
|
|
10
10
|
parseTree,
|
|
11
|
-
} from "jsonc-parser";
|
|
11
|
+
} from "jsonc-parser/lib/esm/main.js";
|
|
12
|
+
|
|
13
|
+
// ^ Deep ESM import on purpose. jsonc-parser has no "exports" map, and its
|
|
14
|
+
// "main" points at a UMD build whose runtime-relative requires (./impl/format
|
|
15
|
+
// etc.) survive bundling verbatim and then fail to resolve from inside a
|
|
16
|
+
// bundled chunk. When this module became reachable from the plugin entry (the
|
|
17
|
+
// config raw-loader), that broken require made the ENTIRE plugin bundle fail
|
|
18
|
+
// to load at boot. The ESM build bundles statically and safely.
|
|
12
19
|
|
|
13
20
|
interface TokenLocation {
|
|
14
21
|
offset: number;
|
|
@@ -252,6 +259,72 @@ export function setJsoncValue(text: string, path: JSONPath, value: unknown): str
|
|
|
252
259
|
return applyEdits(text, modify(text, path, value, {}));
|
|
253
260
|
}
|
|
254
261
|
|
|
262
|
+
function removeObjectProperty(text: string, object: Node, key: string): string {
|
|
263
|
+
const properties = object.children ?? [];
|
|
264
|
+
const index = properties.findIndex((property) => {
|
|
265
|
+
const propertyKey = property.children?.[0];
|
|
266
|
+
return propertyKey !== undefined && getNodeValue(propertyKey) === key;
|
|
267
|
+
});
|
|
268
|
+
if (index === -1) return text;
|
|
269
|
+
|
|
270
|
+
const property = properties[index];
|
|
271
|
+
if (!property) return text;
|
|
272
|
+
const closingBrace = object.offset + object.length - 1;
|
|
273
|
+
const next = properties[index + 1];
|
|
274
|
+
if (next) {
|
|
275
|
+
const followingComma = findComma(text, property.offset + property.length, next.offset);
|
|
276
|
+
if (!followingComma) return text;
|
|
277
|
+
// Leading and trailing comments remain in their original positions. A
|
|
278
|
+
// comment previously adjacent to a migrated field therefore survives as
|
|
279
|
+
// standalone JSONC rather than being discarded with the old key.
|
|
280
|
+
return (
|
|
281
|
+
text.slice(0, property.offset) +
|
|
282
|
+
text.slice(followingComma.offset + followingComma.length)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const previous = properties[index - 1];
|
|
287
|
+
const trailingComma = findComma(text, property.offset + property.length, closingBrace);
|
|
288
|
+
if (!previous) {
|
|
289
|
+
const afterProperty = property.offset + property.length;
|
|
290
|
+
if (!trailingComma) return text.slice(0, property.offset) + text.slice(afterProperty);
|
|
291
|
+
return (
|
|
292
|
+
text.slice(0, property.offset) +
|
|
293
|
+
text.slice(afterProperty, trailingComma.offset) +
|
|
294
|
+
text.slice(trailingComma.offset + trailingComma.length)
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const precedingComma = findComma(text, previous.offset + previous.length, property.offset);
|
|
299
|
+
if (!precedingComma) return text;
|
|
300
|
+
const afterProperty = property.offset + property.length;
|
|
301
|
+
const withoutProperty =
|
|
302
|
+
text.slice(0, precedingComma.offset) +
|
|
303
|
+
text.slice(precedingComma.offset + precedingComma.length, property.offset) +
|
|
304
|
+
text.slice(afterProperty);
|
|
305
|
+
if (!trailingComma) return withoutProperty;
|
|
306
|
+
|
|
307
|
+
// The trailing comma position is measured in the original string. Removing
|
|
308
|
+
// only one character before it (the preceding comma) shifts it left by one.
|
|
309
|
+
const shiftedTrailingComma = trailingComma.offset - 1;
|
|
310
|
+
return (
|
|
311
|
+
withoutProperty.slice(0, shiftedTrailingComma) +
|
|
312
|
+
withoutProperty.slice(shiftedTrailingComma + trailingComma.length)
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Delete an object property without reserializing sibling fields. Comments are
|
|
318
|
+
* retained as JSONC trivia so key migrations do not erase a user's notes.
|
|
319
|
+
*/
|
|
320
|
+
export function removeJsoncValue(text: string, path: JSONPath): string {
|
|
321
|
+
const key = path.at(-1);
|
|
322
|
+
if (typeof key !== "string") return text;
|
|
323
|
+
const parent = findNode(text, path.slice(0, -1));
|
|
324
|
+
if (parent?.type !== "object") return text;
|
|
325
|
+
return removeObjectProperty(text, parent, key);
|
|
326
|
+
}
|
|
327
|
+
|
|
255
328
|
/**
|
|
256
329
|
* Remove matching array entries while retaining the exact bytes for survivor
|
|
257
330
|
* comments and surrounding JSONC regions.
|