@cortexkit/magic-context 0.23.1 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +736 -414
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8265,9 +8265,6 @@ import { execFileSync, spawnSync } from "node:child_process";
|
|
|
8265
8265
|
import { existsSync as existsSync4 } from "node:fs";
|
|
8266
8266
|
import { homedir as homedir4 } from "node:os";
|
|
8267
8267
|
import { join as join5 } from "node:path";
|
|
8268
|
-
function getStaticModels() {
|
|
8269
|
-
return [...STATIC_MODELS];
|
|
8270
|
-
}
|
|
8271
8268
|
function detectPiBinary() {
|
|
8272
8269
|
const fromPath = findOnPath("pi");
|
|
8273
8270
|
if (fromPath)
|
|
@@ -8314,17 +8311,26 @@ function parseModelListOutput(output) {
|
|
|
8314
8311
|
const line = rawLine.trim().replace(/^[•*-]\s*/, "");
|
|
8315
8312
|
if (!line || line.toLowerCase().includes("usage:"))
|
|
8316
8313
|
continue;
|
|
8317
|
-
const
|
|
8318
|
-
|
|
8314
|
+
const cols = line.split(/\s+/);
|
|
8315
|
+
const first = cols[0]?.replace(/,$/, "") ?? "";
|
|
8316
|
+
if (first.includes("/")) {
|
|
8317
|
+
if (!/^https?:\/\//.test(first))
|
|
8318
|
+
models.add(first);
|
|
8319
8319
|
continue;
|
|
8320
|
-
|
|
8320
|
+
}
|
|
8321
|
+
const provider = first;
|
|
8322
|
+
const model = cols[1]?.replace(/,$/, "") ?? "";
|
|
8323
|
+
if (provider.toLowerCase() === "provider" && model.toLowerCase() === "model") {
|
|
8321
8324
|
continue;
|
|
8322
|
-
|
|
8325
|
+
}
|
|
8326
|
+
if (PROVIDER_TOKEN.test(provider) && MODEL_TOKEN.test(model)) {
|
|
8327
|
+
models.add(`${provider}/${model}`);
|
|
8328
|
+
}
|
|
8323
8329
|
}
|
|
8324
8330
|
return [...models];
|
|
8325
8331
|
}
|
|
8326
8332
|
function getAvailableModels(piPath) {
|
|
8327
|
-
const outputs = [runPi(piPath, ["models"
|
|
8333
|
+
const outputs = [runPi(piPath, ["--list-models"]), runPi(piPath, ["models", "list"])];
|
|
8328
8334
|
for (const output of outputs) {
|
|
8329
8335
|
if (!output)
|
|
8330
8336
|
continue;
|
|
@@ -8332,95 +8338,13 @@ function getAvailableModels(piPath) {
|
|
|
8332
8338
|
if (models.length > 0)
|
|
8333
8339
|
return models;
|
|
8334
8340
|
}
|
|
8335
|
-
return
|
|
8341
|
+
return [];
|
|
8336
8342
|
}
|
|
8337
|
-
|
|
8338
|
-
const result = [];
|
|
8339
|
-
const added = new Set;
|
|
8340
|
-
const addIfAvailable = (pattern, hint) => {
|
|
8341
|
-
const matches = allModels.filter((m) => m === pattern || m.endsWith(`/${pattern}`));
|
|
8342
|
-
for (const model of matches) {
|
|
8343
|
-
if (added.has(model))
|
|
8344
|
-
continue;
|
|
8345
|
-
added.add(model);
|
|
8346
|
-
result.push({
|
|
8347
|
-
label: hint ? `${model} — ${hint}` : model,
|
|
8348
|
-
value: model,
|
|
8349
|
-
recommended: result.length === 0
|
|
8350
|
-
});
|
|
8351
|
-
}
|
|
8352
|
-
};
|
|
8353
|
-
if (role === "historian") {
|
|
8354
|
-
addIfAvailable("anthropic/claude-haiku-4-5", "fast/cheap default");
|
|
8355
|
-
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
8356
|
-
addIfAvailable("anthropic/claude-sonnet-4-6");
|
|
8357
|
-
addIfAvailable("github-copilot/gpt-5.4", "per-request billing");
|
|
8358
|
-
addIfAvailable("openai/gpt-5.4");
|
|
8359
|
-
addIfAvailable("opencode-go/minimax-m2.7");
|
|
8360
|
-
addIfAvailable("opencode-go/glm-5");
|
|
8361
|
-
} else if (role === "dreamer") {
|
|
8362
|
-
for (const model of allModels.filter((m) => m.startsWith("ollama/"))) {
|
|
8363
|
-
if (added.has(model))
|
|
8364
|
-
continue;
|
|
8365
|
-
added.add(model);
|
|
8366
|
-
result.push({
|
|
8367
|
-
label: `${model} — local`,
|
|
8368
|
-
value: model,
|
|
8369
|
-
recommended: result.length === 0
|
|
8370
|
-
});
|
|
8371
|
-
}
|
|
8372
|
-
addIfAvailable("anthropic/claude-sonnet-4-6", "recommended quality default");
|
|
8373
|
-
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
8374
|
-
addIfAvailable("github-copilot/gemini-3-flash-preview", "fast/cheap");
|
|
8375
|
-
addIfAvailable("opencode-go/glm-5");
|
|
8376
|
-
addIfAvailable("opencode-go/minimax-m2.7");
|
|
8377
|
-
} else {
|
|
8378
|
-
for (const model of allModels.filter((m) => m.startsWith("cerebras/"))) {
|
|
8379
|
-
if (added.has(model))
|
|
8380
|
-
continue;
|
|
8381
|
-
added.add(model);
|
|
8382
|
-
result.push({
|
|
8383
|
-
label: `${model} — fast`,
|
|
8384
|
-
value: model,
|
|
8385
|
-
recommended: result.length === 0
|
|
8386
|
-
});
|
|
8387
|
-
}
|
|
8388
|
-
addIfAvailable("github-copilot/gemini-3-flash-preview", "fast");
|
|
8389
|
-
addIfAvailable("github-copilot/gpt-5-mini", "fast");
|
|
8390
|
-
addIfAvailable("openai/gpt-5.4-mini", "fast");
|
|
8391
|
-
addIfAvailable("anthropic/claude-haiku-4-5", "fast");
|
|
8392
|
-
}
|
|
8393
|
-
for (const model of allModels) {
|
|
8394
|
-
if (result.length >= 30)
|
|
8395
|
-
break;
|
|
8396
|
-
if (added.has(model))
|
|
8397
|
-
continue;
|
|
8398
|
-
added.add(model);
|
|
8399
|
-
result.push({
|
|
8400
|
-
label: model,
|
|
8401
|
-
value: model,
|
|
8402
|
-
recommended: result.length === 0
|
|
8403
|
-
});
|
|
8404
|
-
}
|
|
8405
|
-
return result;
|
|
8406
|
-
}
|
|
8407
|
-
var PI_PACKAGE_SOURCE = "npm:@cortexkit/pi-magic-context", STATIC_MODELS;
|
|
8343
|
+
var PI_PACKAGE_SOURCE = "npm:@cortexkit/pi-magic-context", PROVIDER_TOKEN, MODEL_TOKEN;
|
|
8408
8344
|
var init_pi_helpers = __esm(() => {
|
|
8409
8345
|
init_find_on_path();
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
"anthropic/claude-sonnet-4-6",
|
|
8413
|
-
"github-copilot/claude-sonnet-4.6",
|
|
8414
|
-
"github-copilot/gpt-5.4",
|
|
8415
|
-
"github-copilot/gpt-5-mini",
|
|
8416
|
-
"github-copilot/gemini-3-flash-preview",
|
|
8417
|
-
"openai/gpt-5.4",
|
|
8418
|
-
"openai/gpt-5.4-mini",
|
|
8419
|
-
"opencode-go/glm-5",
|
|
8420
|
-
"opencode-go/minimax-m2.7",
|
|
8421
|
-
"ollama/qwen2.5-coder:7b",
|
|
8422
|
-
"cerebras/llama3.1-8b"
|
|
8423
|
-
];
|
|
8346
|
+
PROVIDER_TOKEN = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
8347
|
+
MODEL_TOKEN = /^[a-z0-9][a-z0-9._:-]*$/i;
|
|
8424
8348
|
});
|
|
8425
8349
|
|
|
8426
8350
|
// src/adapters/pi.ts
|
|
@@ -9741,6 +9665,21 @@ import j2 from "node:process";
|
|
|
9741
9665
|
function te() {
|
|
9742
9666
|
return j2.platform !== "win32" ? j2.env.TERM !== "linux" : !!j2.env.CI || !!j2.env.WT_SESSION || !!j2.env.TERMINUS_SUBLIME || j2.env.ConEmuTask === "{cmd::Cmder}" || j2.env.TERM_PROGRAM === "Terminus-Sublime" || j2.env.TERM_PROGRAM === "vscode" || j2.env.TERM === "xterm-256color" || j2.env.TERM === "alacritty" || j2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
9743
9667
|
}
|
|
9668
|
+
function Mt(t) {
|
|
9669
|
+
return t.label ?? String(t.value ?? "");
|
|
9670
|
+
}
|
|
9671
|
+
function Rt(t, r) {
|
|
9672
|
+
if (!t)
|
|
9673
|
+
return true;
|
|
9674
|
+
const s = (r.label ?? String(r.value ?? "")).toLowerCase(), i = (r.hint ?? "").toLowerCase(), u = String(r.value).toLowerCase(), n = t.toLowerCase();
|
|
9675
|
+
return s.includes(n) || i.includes(n) || u.includes(n);
|
|
9676
|
+
}
|
|
9677
|
+
function se(t, r) {
|
|
9678
|
+
const s = [];
|
|
9679
|
+
for (const i of r)
|
|
9680
|
+
t.includes(i.value) && s.push(i);
|
|
9681
|
+
return s;
|
|
9682
|
+
}
|
|
9744
9683
|
var import_sisteransi2, tt2, at2 = () => process.env.CI === "true", w2 = (t, r) => tt2 ? t : r, _t, ot2, ut2, F2, lt, $2, E2, It, Et, z2, H2, et2, U2, J2, Gt, st2, ct, xt, $t, dt, Ot, ht2, pt, mt, gt, M = (t) => {
|
|
9745
9684
|
switch (t) {
|
|
9746
9685
|
case "initial":
|
|
@@ -9798,7 +9737,47 @@ var import_sisteransi2, tt2, at2 = () => process.env.CI === "true", w2 = (t, r)
|
|
|
9798
9737
|
for (const G2 of b2)
|
|
9799
9738
|
C2.push(G2);
|
|
9800
9739
|
return g && C2.push(l), C2;
|
|
9801
|
-
},
|
|
9740
|
+
}, At = (t) => new Q({ options: t.options, initialValue: t.initialValue ? [t.initialValue] : undefined, initialUserInput: t.initialUserInput, placeholder: t.placeholder, filter: t.filter ?? ((r, s) => Rt(r, s)), signal: t.signal, input: t.input, output: t.output, validate: t.validate, render() {
|
|
9741
|
+
const r = t.withGuide ?? h.withGuide, s = r ? [`${e("gray", $2)}`, `${M(this.state)} ${t.message}`] : [`${M(this.state)} ${t.message}`], i = this.userInput, u = this.options, n = t.placeholder, o = i === "" && n !== undefined, c2 = (a, l) => {
|
|
9742
|
+
const d2 = Mt(a), y = a.hint && a.value === this.focusedValue ? e("dim", ` (${a.hint})`) : "";
|
|
9743
|
+
switch (l) {
|
|
9744
|
+
case "active":
|
|
9745
|
+
return `${e("green", z2)} ${d2}${y}`;
|
|
9746
|
+
case "inactive":
|
|
9747
|
+
return `${e("dim", H2)} ${e("dim", d2)}`;
|
|
9748
|
+
case "disabled":
|
|
9749
|
+
return `${e("gray", H2)} ${e(["strikethrough", "gray"], d2)}`;
|
|
9750
|
+
}
|
|
9751
|
+
};
|
|
9752
|
+
switch (this.state) {
|
|
9753
|
+
case "submit": {
|
|
9754
|
+
const a = se(this.selectedValues, u), l = a.length > 0 ? ` ${e("dim", a.map(Mt).join(", "))}` : "", d2 = r ? e("gray", $2) : "";
|
|
9755
|
+
return `${s.join(`
|
|
9756
|
+
`)}
|
|
9757
|
+
${d2}${l}`;
|
|
9758
|
+
}
|
|
9759
|
+
case "cancel": {
|
|
9760
|
+
const a = i ? ` ${e(["strikethrough", "dim"], i)}` : "", l = r ? e("gray", $2) : "";
|
|
9761
|
+
return `${s.join(`
|
|
9762
|
+
`)}
|
|
9763
|
+
${l}${a}`;
|
|
9764
|
+
}
|
|
9765
|
+
default: {
|
|
9766
|
+
const a = this.state === "error" ? "yellow" : "cyan", l = r ? `${e(a, $2)} ` : "", d2 = r ? e(a, E2) : "";
|
|
9767
|
+
let y = "";
|
|
9768
|
+
if (this.isNavigating || o) {
|
|
9769
|
+
const v2 = o ? n : i;
|
|
9770
|
+
y = v2 !== "" ? ` ${e("dim", v2)}` : "";
|
|
9771
|
+
} else
|
|
9772
|
+
y = ` ${this.userInputWithCursor}`;
|
|
9773
|
+
const p2 = this.filteredOptions.length !== u.length ? e("dim", ` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? "" : "es"})`) : "", m = this.filteredOptions.length === 0 && i ? [`${l}${e("yellow", "No matches found")}`] : [], g = this.state === "error" ? [`${l}${e("yellow", this.error)}`] : [];
|
|
9774
|
+
r && s.push(`${l.trimEnd()}`), s.push(`${l}${e("dim", "Search:")}${y}${p2}`, ...m, ...g);
|
|
9775
|
+
const S2 = [`${e("dim", "↑/↓")} to select`, `${e("dim", "Enter:")} confirm`, `${e("dim", "Type:")} to search`], h2 = [`${l}${S2.join(" • ")}`, d2], f = this.filteredOptions.length === 0 ? [] : Y2({ cursor: this.cursor, options: this.filteredOptions, columnPadding: r ? 3 : 0, rowPadding: s.length + h2.length, style: (v2, T) => c2(v2, v2.disabled ? "disabled" : T ? "active" : "inactive"), maxItems: t.maxItems, output: t.output });
|
|
9776
|
+
return [...s, ...f.map((v2) => `${l}${v2}`), ...h2].join(`
|
|
9777
|
+
`);
|
|
9778
|
+
}
|
|
9779
|
+
}
|
|
9780
|
+
} }).prompt(), ue = (t) => {
|
|
9802
9781
|
const r = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
9803
9782
|
return new X({ active: r, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
|
|
9804
9783
|
const i = t.withGuide ?? h.withGuide, u = `${M(this.state)} `, n = i ? `${e("gray", $2)} ` : "", o = W(t.output, t.message, n, u), c2 = `${i ? `${e("gray", $2)}
|
|
@@ -10108,6 +10087,7 @@ __export(exports_prompts, {
|
|
|
10108
10087
|
spinner: () => spinner,
|
|
10109
10088
|
selectOne: () => selectOne,
|
|
10110
10089
|
selectMany: () => selectMany,
|
|
10090
|
+
selectAutocomplete: () => selectAutocomplete,
|
|
10111
10091
|
promptIO: () => promptIO,
|
|
10112
10092
|
outro: () => outro,
|
|
10113
10093
|
note: () => note,
|
|
@@ -10187,6 +10167,16 @@ async function selectMany(message, options, initial) {
|
|
|
10187
10167
|
handleCancel(result);
|
|
10188
10168
|
return result;
|
|
10189
10169
|
}
|
|
10170
|
+
async function selectAutocomplete(message, options, opts = {}) {
|
|
10171
|
+
const result = await At({
|
|
10172
|
+
message,
|
|
10173
|
+
options: options.map(toClackOption),
|
|
10174
|
+
placeholder: opts.placeholder,
|
|
10175
|
+
maxItems: opts.maxItems ?? 10
|
|
10176
|
+
});
|
|
10177
|
+
handleCancel(result);
|
|
10178
|
+
return result;
|
|
10179
|
+
}
|
|
10190
10180
|
var log, promptIO;
|
|
10191
10181
|
var init_prompts = __esm(() => {
|
|
10192
10182
|
init_dist4();
|
|
@@ -10219,7 +10209,8 @@ var init_prompts = __esm(() => {
|
|
|
10219
10209
|
confirm,
|
|
10220
10210
|
text,
|
|
10221
10211
|
selectOne,
|
|
10222
|
-
selectMany
|
|
10212
|
+
selectMany,
|
|
10213
|
+
selectAutocomplete
|
|
10223
10214
|
};
|
|
10224
10215
|
});
|
|
10225
10216
|
|
|
@@ -10785,6 +10776,58 @@ var init_conflict_fixer = __esm(() => {
|
|
|
10785
10776
|
];
|
|
10786
10777
|
});
|
|
10787
10778
|
|
|
10779
|
+
// src/lib/model-picker.ts
|
|
10780
|
+
function sortModelsForPicker(models) {
|
|
10781
|
+
return [...new Set(models)].sort((a, b2) => a.localeCompare(b2));
|
|
10782
|
+
}
|
|
10783
|
+
function modelOptions(models) {
|
|
10784
|
+
return sortModelsForPicker(models).map((model) => ({ label: model, value: model }));
|
|
10785
|
+
}
|
|
10786
|
+
async function pickModel(prompts, allModels, role) {
|
|
10787
|
+
const copy = ROLE_COPY[role];
|
|
10788
|
+
prompts.note(copy.blurb, copy.title);
|
|
10789
|
+
const options = modelOptions(allModels);
|
|
10790
|
+
if (options.length === 0) {
|
|
10791
|
+
return (await prompts.text(`${copy.pickMessage} (type a provider/model id)`, {
|
|
10792
|
+
placeholder: "e.g. anthropic/claude-haiku-4-5",
|
|
10793
|
+
validate: (value) => value.trim().length === 0 ? "A model id is required" : undefined
|
|
10794
|
+
})).trim();
|
|
10795
|
+
}
|
|
10796
|
+
return prompts.selectAutocomplete(copy.pickMessage, options, {
|
|
10797
|
+
placeholder: copy.placeholder
|
|
10798
|
+
});
|
|
10799
|
+
}
|
|
10800
|
+
var ROLE_COPY;
|
|
10801
|
+
var init_model_picker = __esm(() => {
|
|
10802
|
+
ROLE_COPY = {
|
|
10803
|
+
historian: {
|
|
10804
|
+
title: "Historian",
|
|
10805
|
+
blurb: `The historian runs in the background and condenses older conversation into
|
|
10806
|
+
` + `compact summaries, so your context never overflows. It works on one bounded
|
|
10807
|
+
` + `chunk at a time and runs often — it does NOT need a frontier model. A smaller,
|
|
10808
|
+
` + `cheaper, faster model (a mini / flash / haiku tier) works well here and keeps
|
|
10809
|
+
` + "your costs down.",
|
|
10810
|
+
pickMessage: "Select a model for the historian",
|
|
10811
|
+
placeholder: "type to filter (e.g. haiku, flash, mini)…"
|
|
10812
|
+
},
|
|
10813
|
+
dreamer: {
|
|
10814
|
+
title: "Dreamer",
|
|
10815
|
+
blurb: `The dreamer runs periodically (typically overnight) to consolidate and maintain
|
|
10816
|
+
` + `your project memories. It is not on the hot path and does NOT need a frontier
|
|
10817
|
+
` + "model — a cheaper or local model is a good fit here.",
|
|
10818
|
+
pickMessage: "Select a model for the dreamer",
|
|
10819
|
+
placeholder: "type to filter (e.g. flash, local, glm)…"
|
|
10820
|
+
},
|
|
10821
|
+
sidekick: {
|
|
10822
|
+
title: "Sidekick",
|
|
10823
|
+
blurb: `The sidekick augments your prompt with relevant project context when you run
|
|
10824
|
+
` + "/ctx-aug. Fast models are preferred here.",
|
|
10825
|
+
pickMessage: "Select a model for the sidekick",
|
|
10826
|
+
placeholder: "type to filter…"
|
|
10827
|
+
}
|
|
10828
|
+
};
|
|
10829
|
+
});
|
|
10830
|
+
|
|
10788
10831
|
// src/lib/opencode-helpers.ts
|
|
10789
10832
|
import { execSync } from "node:child_process";
|
|
10790
10833
|
function isOpenCodeInstalled() {
|
|
@@ -10811,55 +10854,6 @@ function getAvailableModels2() {
|
|
|
10811
10854
|
return [];
|
|
10812
10855
|
}
|
|
10813
10856
|
}
|
|
10814
|
-
function buildModelSelection2(allModels, role) {
|
|
10815
|
-
const result = [];
|
|
10816
|
-
const added = new Set;
|
|
10817
|
-
const addIfAvailable = (pattern, hint) => {
|
|
10818
|
-
const matches = allModels.filter((m) => m === pattern || m.endsWith(`/${pattern}`));
|
|
10819
|
-
for (const m of matches) {
|
|
10820
|
-
if (!added.has(m)) {
|
|
10821
|
-
added.add(m);
|
|
10822
|
-
result.push({
|
|
10823
|
-
label: hint ? `${m} — ${hint}` : m,
|
|
10824
|
-
value: m,
|
|
10825
|
-
recommended: result.length === 0
|
|
10826
|
-
});
|
|
10827
|
-
}
|
|
10828
|
-
}
|
|
10829
|
-
};
|
|
10830
|
-
if (role === "historian") {
|
|
10831
|
-
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
10832
|
-
addIfAvailable("anthropic/claude-sonnet-4-6");
|
|
10833
|
-
addIfAvailable("github-copilot/gpt-5.4", "per-request billing");
|
|
10834
|
-
addIfAvailable("openai/gpt-5.4");
|
|
10835
|
-
addIfAvailable("github-copilot/gemini-3.1-pro-preview", "per-request billing");
|
|
10836
|
-
addIfAvailable("opencode-go/minimax-m2.7");
|
|
10837
|
-
addIfAvailable("opencode-go/glm-5");
|
|
10838
|
-
} else if (role === "dreamer") {
|
|
10839
|
-
for (const m of allModels.filter((m2) => m2.startsWith("ollama/"))) {
|
|
10840
|
-
if (!added.has(m)) {
|
|
10841
|
-
added.add(m);
|
|
10842
|
-
result.push({ label: `${m} — local`, value: m, recommended: result.length === 0 });
|
|
10843
|
-
}
|
|
10844
|
-
}
|
|
10845
|
-
addIfAvailable("github-copilot/claude-sonnet-4.6", "per-request billing");
|
|
10846
|
-
addIfAvailable("anthropic/claude-sonnet-4-6");
|
|
10847
|
-
addIfAvailable("github-copilot/gemini-3-flash-preview", "per-request billing");
|
|
10848
|
-
addIfAvailable("opencode-go/glm-5");
|
|
10849
|
-
addIfAvailable("opencode-go/minimax-m2.7");
|
|
10850
|
-
} else if (role === "sidekick") {
|
|
10851
|
-
for (const m of allModels.filter((m2) => m2.startsWith("cerebras/"))) {
|
|
10852
|
-
if (!added.has(m)) {
|
|
10853
|
-
added.add(m);
|
|
10854
|
-
result.push({ label: m, value: m, recommended: result.length === 0 });
|
|
10855
|
-
}
|
|
10856
|
-
}
|
|
10857
|
-
addIfAvailable("opencode/gpt-5-nano");
|
|
10858
|
-
addIfAvailable("github-copilot/gemini-3-flash-preview");
|
|
10859
|
-
addIfAvailable("github-copilot/gpt-5-mini");
|
|
10860
|
-
}
|
|
10861
|
-
return result;
|
|
10862
|
-
}
|
|
10863
10857
|
var init_opencode_helpers = () => {};
|
|
10864
10858
|
|
|
10865
10859
|
// src/commands/setup-opencode.ts
|
|
@@ -11008,8 +11002,11 @@ function writeMagicContextConfig(configPath, options) {
|
|
|
11008
11002
|
writeFileSync4(configPath, `${import_comment_json4.stringify(config, null, 2)}
|
|
11009
11003
|
`);
|
|
11010
11004
|
}
|
|
11011
|
-
async function runSetup() {
|
|
11005
|
+
async function runSetup(dryRun = false) {
|
|
11012
11006
|
intro("Magic Context — Setup");
|
|
11007
|
+
if (dryRun) {
|
|
11008
|
+
log.warn("Dry run — no files will be written and no config will be changed.");
|
|
11009
|
+
}
|
|
11013
11010
|
const s = spinner();
|
|
11014
11011
|
s.start("Checking OpenCode installation");
|
|
11015
11012
|
const installed = isOpenCodeInstalled();
|
|
@@ -11035,11 +11032,17 @@ async function runSetup() {
|
|
|
11035
11032
|
}
|
|
11036
11033
|
const paths = detectConfigPaths();
|
|
11037
11034
|
const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync8(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
|
|
11038
|
-
|
|
11039
|
-
|
|
11040
|
-
|
|
11041
|
-
|
|
11042
|
-
|
|
11035
|
+
if (!dryRun) {
|
|
11036
|
+
await resolveDcpConflictBeforeSetup(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
11037
|
+
}
|
|
11038
|
+
if (dryRun) {
|
|
11039
|
+
log.message(`[dry-run] would add the plugin to ${paths.opencodeConfig} and disable compaction`);
|
|
11040
|
+
} else {
|
|
11041
|
+
addPluginToOpenCodeConfig(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
11042
|
+
log.success(`Plugin added to ${paths.opencodeConfig}`);
|
|
11043
|
+
log.info("Disabled built-in compaction (auto=false, prune=false)");
|
|
11044
|
+
log.message("Magic Context handles context management — built-in compaction would interfere");
|
|
11045
|
+
}
|
|
11043
11046
|
if (hadExistingSetup) {
|
|
11044
11047
|
const conflicts = detectConflicts(process.cwd());
|
|
11045
11048
|
if (conflicts.hasConflict) {
|
|
@@ -11047,60 +11050,38 @@ async function runSetup() {
|
|
|
11047
11050
|
for (const reason of conflicts.reasons) {
|
|
11048
11051
|
log.message(` • ${reason}`);
|
|
11049
11052
|
}
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11053
|
+
if (dryRun) {
|
|
11054
|
+
log.message("[dry-run] would offer to apply automatic conflict fixes");
|
|
11055
|
+
} else {
|
|
11056
|
+
const shouldFixConflicts = await confirm("Apply automatic conflict fixes to your OpenCode and OMO config files?", true);
|
|
11057
|
+
if (shouldFixConflicts) {
|
|
11058
|
+
const actions = fixConflicts(process.cwd(), conflicts.conflicts);
|
|
11059
|
+
if (actions.length > 0) {
|
|
11060
|
+
for (const action of actions) {
|
|
11061
|
+
log.success(action);
|
|
11062
|
+
}
|
|
11063
|
+
} else {
|
|
11064
|
+
log.info("No additional conflict changes were needed");
|
|
11056
11065
|
}
|
|
11057
11066
|
} else {
|
|
11058
|
-
log.
|
|
11067
|
+
log.warn("Skipped automatic conflict fixes — Magic Context may remain disabled");
|
|
11059
11068
|
}
|
|
11060
|
-
} else {
|
|
11061
|
-
log.warn("Skipped automatic conflict fixes — Magic Context may remain disabled");
|
|
11062
11069
|
}
|
|
11063
11070
|
}
|
|
11064
11071
|
}
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
const historianOptions = buildModelSelection2(allModels, "historian");
|
|
11068
|
-
if (historianOptions.length > 0) {
|
|
11069
|
-
historianModel = await selectOne("Select a model for historian (background context compressor)", historianOptions);
|
|
11070
|
-
log.success(`Historian: ${historianModel}`);
|
|
11071
|
-
} else {
|
|
11072
|
-
log.info("No suitable historian models found — using built-in fallback chain");
|
|
11073
|
-
}
|
|
11074
|
-
} else {
|
|
11075
|
-
log.info("Skipping model selection — using built-in fallback chain");
|
|
11076
|
-
}
|
|
11077
|
-
log.message("The dreamer runs overnight to consolidate and maintain project memories.");
|
|
11072
|
+
const historianModel = await pickModel(promptIO, allModels, "historian");
|
|
11073
|
+
log.success(`Historian: ${historianModel}`);
|
|
11078
11074
|
const dreamerEnabled = await confirm("Enable dreamer?", true);
|
|
11079
11075
|
let dreamerModel = null;
|
|
11080
|
-
if (dreamerEnabled
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
dreamerModel = await selectOne("Select a model for dreamer (runs in background, local LLMs ideal)", dreamerOptions);
|
|
11084
|
-
log.success(`Dreamer: ${dreamerModel}`);
|
|
11085
|
-
} else {
|
|
11086
|
-
log.info("No suitable dreamer models — using built-in fallback chain");
|
|
11087
|
-
}
|
|
11088
|
-
} else if (dreamerEnabled) {
|
|
11089
|
-
log.info("Using built-in fallback chain for dreamer");
|
|
11076
|
+
if (dreamerEnabled) {
|
|
11077
|
+
dreamerModel = await pickModel(promptIO, allModels, "dreamer");
|
|
11078
|
+
log.success(`Dreamer: ${dreamerModel}`);
|
|
11090
11079
|
}
|
|
11091
|
-
log.message("Sidekick augments prompts with project context via /ctx-aug command.");
|
|
11092
11080
|
const sidekickEnabled = await confirm("Enable sidekick?", false);
|
|
11093
11081
|
let sidekickModel = null;
|
|
11094
|
-
if (sidekickEnabled
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
sidekickModel = await selectOne("Select a model for sidekick (fast models preferred)", sidekickOptions);
|
|
11098
|
-
log.success(`Sidekick: ${sidekickModel}`);
|
|
11099
|
-
} else {
|
|
11100
|
-
log.info("No suitable sidekick models — using built-in fallback chain");
|
|
11101
|
-
}
|
|
11102
|
-
} else if (sidekickEnabled) {
|
|
11103
|
-
log.info("Using built-in fallback chain for sidekick");
|
|
11082
|
+
if (sidekickEnabled) {
|
|
11083
|
+
sidekickModel = await pickModel(promptIO, allModels, "sidekick");
|
|
11084
|
+
log.success(`Sidekick: ${sidekickModel}`);
|
|
11104
11085
|
}
|
|
11105
11086
|
const hasAnthropic = allModels.some((m) => m.startsWith("anthropic/"));
|
|
11106
11087
|
let claudeMax = false;
|
|
@@ -11112,24 +11093,32 @@ async function runSetup() {
|
|
|
11112
11093
|
log.success("Cache TTL set to 59m for Anthropic models");
|
|
11113
11094
|
}
|
|
11114
11095
|
}
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11096
|
+
if (dryRun) {
|
|
11097
|
+
log.message(`[dry-run] would write Magic Context config to ${paths.magicContextConfig}`);
|
|
11098
|
+
log.message("[dry-run] would add the TUI sidebar plugin to tui.json");
|
|
11099
|
+
} else {
|
|
11100
|
+
writeMagicContextConfig(paths.magicContextConfig, {
|
|
11101
|
+
historianModel,
|
|
11102
|
+
dreamerEnabled,
|
|
11103
|
+
dreamerModel,
|
|
11104
|
+
sidekickEnabled,
|
|
11105
|
+
sidekickModel,
|
|
11106
|
+
claudeMax
|
|
11107
|
+
});
|
|
11108
|
+
log.success(`Config written to ${paths.magicContextConfig}`);
|
|
11109
|
+
addPluginToTuiConfig(paths.tuiConfig, paths.tuiConfigFormat);
|
|
11110
|
+
log.success("TUI sidebar plugin added to tui.json");
|
|
11111
|
+
}
|
|
11126
11112
|
if (paths.omoConfig && !hadExistingSetup) {
|
|
11127
11113
|
log.warn(`Found oh-my-opencode config: ${paths.omoConfig}`);
|
|
11128
11114
|
log.message(`These hooks may conflict:
|
|
11129
11115
|
` + ` • context-window-monitor
|
|
11130
11116
|
` + ` • preemptive-compaction
|
|
11131
11117
|
` + " • anthropic-context-window-limit-recovery");
|
|
11132
|
-
const shouldDisable = await confirm("Disable these hooks in oh-my-opencode?", true);
|
|
11118
|
+
const shouldDisable = dryRun ? false : await confirm("Disable these hooks in oh-my-opencode?", true);
|
|
11119
|
+
if (dryRun) {
|
|
11120
|
+
log.message("[dry-run] would offer to disable conflicting oh-my-opencode hooks");
|
|
11121
|
+
}
|
|
11133
11122
|
if (shouldDisable) {
|
|
11134
11123
|
const actions = fixConflicts(process.cwd(), {
|
|
11135
11124
|
compactionAuto: false,
|
|
@@ -11154,7 +11143,11 @@ async function runSetup() {
|
|
|
11154
11143
|
sidekickEnabled ? `Sidekick: enabled${sidekickModel ? ` (${sidekickModel})` : ""}` : "Sidekick: disabled"
|
|
11155
11144
|
].join(`
|
|
11156
11145
|
`);
|
|
11157
|
-
note(summary, "Configuration");
|
|
11146
|
+
note(summary, dryRun ? "Configuration (dry run — not written)" : "Configuration");
|
|
11147
|
+
if (dryRun) {
|
|
11148
|
+
outro("Dry run complete — nothing was written.");
|
|
11149
|
+
return 0;
|
|
11150
|
+
}
|
|
11158
11151
|
const shouldStar = await confirm("★ Star the repo on GitHub?", true);
|
|
11159
11152
|
if (shouldStar) {
|
|
11160
11153
|
try {
|
|
@@ -11177,6 +11170,7 @@ var init_setup_opencode = __esm(() => {
|
|
|
11177
11170
|
init_conflict_detector();
|
|
11178
11171
|
init_conflict_fixer();
|
|
11179
11172
|
init_opencode();
|
|
11173
|
+
init_model_picker();
|
|
11180
11174
|
init_opencode_helpers();
|
|
11181
11175
|
init_paths();
|
|
11182
11176
|
init_prompts();
|
|
@@ -11319,10 +11313,6 @@ function writeMagicContextConfig2(configPath, options) {
|
|
|
11319
11313
|
writeFileSync5(configPath, `${import_comment_json5.stringify(config, null, 2)}
|
|
11320
11314
|
`);
|
|
11321
11315
|
}
|
|
11322
|
-
async function chooseModel(prompts, allModels, role, message) {
|
|
11323
|
-
const options = buildModelSelection(allModels, role);
|
|
11324
|
-
return prompts.selectOne(message, options);
|
|
11325
|
-
}
|
|
11326
11316
|
async function chooseEmbedding(prompts) {
|
|
11327
11317
|
const provider = await prompts.selectOne("Select embedding provider", [
|
|
11328
11318
|
{
|
|
@@ -11383,18 +11373,25 @@ Run \`pi update --self\` (or \`npm install -g @earendil-works/pi-coding-agent@la
|
|
|
11383
11373
|
spinner2.start("Fetching available Pi models");
|
|
11384
11374
|
const allModels = env.getAvailableModels(pi.path);
|
|
11385
11375
|
spinner2.stop(`Found ${allModels.length} model choices`);
|
|
11376
|
+
const dryRun = options.dryRun === true;
|
|
11377
|
+
if (dryRun) {
|
|
11378
|
+
prompts.log.warn("Dry run — no files will be written and no package will be registered.");
|
|
11379
|
+
}
|
|
11386
11380
|
const settingsPath = env.paths.getPiUserExtensionsPath();
|
|
11387
11381
|
const configPath = env.paths.getPiUserConfigPath();
|
|
11388
11382
|
const configurePi = await prompts.confirm("Configure Pi to load Magic Context?", true);
|
|
11389
|
-
let packageAdded = false;
|
|
11390
11383
|
if (configurePi) {
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11384
|
+
if (dryRun) {
|
|
11385
|
+
prompts.log.message(`[dry-run] would add ${PI_PACKAGE_SOURCE} to ${settingsPath}`);
|
|
11386
|
+
} else {
|
|
11387
|
+
const packageAdded = writePiSettingsPackage(settingsPath);
|
|
11388
|
+
prompts.log.success(packageAdded ? `Added ${PI_PACKAGE_SOURCE} to ${settingsPath}` : `Magic Context package already present in ${settingsPath}`);
|
|
11389
|
+
prompts.log.message("This mirrors `pi install npm:@cortexkit/pi-magic-context` without running installs during setup verification.");
|
|
11390
|
+
}
|
|
11394
11391
|
} else {
|
|
11395
11392
|
prompts.log.warn("Skipped Pi package registration; install manually with `pi install npm:@cortexkit/pi-magic-context`.");
|
|
11396
11393
|
}
|
|
11397
|
-
const historianModel = await
|
|
11394
|
+
const historianModel = await pickModel(prompts, allModels, "historian");
|
|
11398
11395
|
let historianThinkingLevel;
|
|
11399
11396
|
if (historianModel.startsWith("github-copilot/")) {
|
|
11400
11397
|
prompts.log.warn(`GitHub Copilot reasoning models require an explicit thinking level.
|
|
@@ -11414,36 +11411,41 @@ Run \`pi update --self\` (or \`npm install -g @earendil-works/pi-coding-agent@la
|
|
|
11414
11411
|
]);
|
|
11415
11412
|
}
|
|
11416
11413
|
const dreamerEnabled = await prompts.confirm("Enable dreamer for overnight memory maintenance?", true);
|
|
11417
|
-
const dreamerModel = await
|
|
11414
|
+
const dreamerModel = dreamerEnabled ? await pickModel(prompts, allModels, "dreamer") : undefined;
|
|
11418
11415
|
const sidekickEnabled = await prompts.confirm("Enable sidekick for /ctx-aug?", false);
|
|
11419
|
-
const sidekickModel = sidekickEnabled ? await
|
|
11416
|
+
const sidekickModel = sidekickEnabled ? await pickModel(prompts, allModels, "sidekick") : undefined;
|
|
11420
11417
|
const embedding = await chooseEmbedding(prompts);
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11418
|
+
if (dryRun) {
|
|
11419
|
+
prompts.log.message(`[dry-run] would write Magic Context config to ${configPath}`);
|
|
11420
|
+
} else {
|
|
11421
|
+
writeMagicContextConfig2(configPath, {
|
|
11422
|
+
historianModel,
|
|
11423
|
+
historianThinkingLevel,
|
|
11424
|
+
dreamerEnabled,
|
|
11425
|
+
dreamerModel,
|
|
11426
|
+
sidekickEnabled,
|
|
11427
|
+
sidekickModel,
|
|
11428
|
+
embedding
|
|
11429
|
+
});
|
|
11430
|
+
prompts.log.success(`Config written to ${configPath}`);
|
|
11431
|
+
}
|
|
11431
11432
|
const thinkingLevelSuffix = historianThinkingLevel ? ` (thinking: ${historianThinkingLevel})` : "";
|
|
11432
11433
|
const summary = [
|
|
11433
11434
|
`Pi settings: ${configurePi ? settingsPath : "skipped"}`,
|
|
11434
11435
|
`Magic Context config: ${configPath}`,
|
|
11435
11436
|
`Historian: ${historianModel}${thinkingLevelSuffix}`,
|
|
11436
|
-
`Dreamer: ${
|
|
11437
|
+
`Dreamer: ${dreamerEnabled ? dreamerModel : "disabled"}`,
|
|
11437
11438
|
sidekickEnabled ? `Sidekick: ${sidekickModel}` : "Sidekick: disabled",
|
|
11438
11439
|
`Embedding: ${embedding.provider}${"model" in embedding ? ` (${embedding.model})` : ""}`
|
|
11439
11440
|
].join(`
|
|
11440
11441
|
`);
|
|
11441
|
-
prompts.note(summary, "Configuration");
|
|
11442
|
-
prompts.outro("Start a Pi session and try /ctx-aug");
|
|
11442
|
+
prompts.note(summary, dryRun ? "Configuration (dry run — not written)" : "Configuration");
|
|
11443
|
+
prompts.outro(dryRun ? "Dry run complete — nothing was written." : "Start a Pi session and try /ctx-aug");
|
|
11443
11444
|
return 0;
|
|
11444
11445
|
}
|
|
11445
11446
|
var import_comment_json5, DEFAULT_ENV;
|
|
11446
11447
|
var init_setup_pi = __esm(() => {
|
|
11448
|
+
init_model_picker();
|
|
11447
11449
|
init_paths();
|
|
11448
11450
|
init_pi_helpers();
|
|
11449
11451
|
init_pi_package_entry();
|
|
@@ -11466,7 +11468,8 @@ __export(exports_setup, {
|
|
|
11466
11468
|
runSetup: () => runSetup3
|
|
11467
11469
|
});
|
|
11468
11470
|
async function runSetup3(argv) {
|
|
11469
|
-
|
|
11471
|
+
const dryRun = argv.includes("--dry-run");
|
|
11472
|
+
intro(dryRun ? "Magic Context setup (dry run)" : "Magic Context setup");
|
|
11470
11473
|
const adapters = await resolveAdaptersForCommand(argv, {
|
|
11471
11474
|
allowMulti: true,
|
|
11472
11475
|
verb: "setup"
|
|
@@ -11483,24 +11486,25 @@ async function runSetup3(argv) {
|
|
|
11483
11486
|
anyFailure = true;
|
|
11484
11487
|
continue;
|
|
11485
11488
|
}
|
|
11486
|
-
const code = await dispatchSetup(adapter);
|
|
11489
|
+
const code = await dispatchSetup(adapter, dryRun);
|
|
11487
11490
|
if (code !== 0)
|
|
11488
11491
|
anyFailure = true;
|
|
11489
|
-
|
|
11492
|
+
if (!dryRun)
|
|
11493
|
+
printNextSteps(adapter);
|
|
11490
11494
|
}
|
|
11491
11495
|
if (anyFailure) {
|
|
11492
11496
|
outro("Setup finished with warnings — see above.");
|
|
11493
11497
|
return 1;
|
|
11494
11498
|
}
|
|
11495
|
-
outro("Done.");
|
|
11499
|
+
outro(dryRun ? "Dry run done — no changes were made." : "Done.");
|
|
11496
11500
|
return 0;
|
|
11497
11501
|
}
|
|
11498
|
-
async function dispatchSetup(adapter) {
|
|
11502
|
+
async function dispatchSetup(adapter, dryRun) {
|
|
11499
11503
|
switch (adapter.kind) {
|
|
11500
11504
|
case "opencode":
|
|
11501
|
-
return runSetup();
|
|
11505
|
+
return runSetup(dryRun);
|
|
11502
11506
|
case "pi":
|
|
11503
|
-
return runSetup2();
|
|
11507
|
+
return runSetup2({ dryRun });
|
|
11504
11508
|
}
|
|
11505
11509
|
}
|
|
11506
11510
|
function printNextSteps(adapter) {
|
|
@@ -12224,6 +12228,7 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
12224
12228
|
"cachedM0Bytes",
|
|
12225
12229
|
"cachedM1Bytes",
|
|
12226
12230
|
"cachedM0ProjectMemoryEpoch",
|
|
12231
|
+
"cachedM0WorkspaceFingerprint",
|
|
12227
12232
|
"cachedM0ProjectUserProfileVersion",
|
|
12228
12233
|
"cachedM0MaxCompartmentSeq",
|
|
12229
12234
|
"cachedM0MaxMemoryId",
|
|
@@ -145370,6 +145375,35 @@ function initializeDatabase(db) {
|
|
|
145370
145375
|
);
|
|
145371
145376
|
CREATE INDEX IF NOT EXISTS idx_compartments_session ON compartments(session_id);
|
|
145372
145377
|
|
|
145378
|
+
CREATE TABLE IF NOT EXISTS compartment_chunk_embeddings (
|
|
145379
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145380
|
+
compartment_id INTEGER NOT NULL REFERENCES compartments(id) ON DELETE CASCADE,
|
|
145381
|
+
session_id TEXT NOT NULL,
|
|
145382
|
+
project_path TEXT NOT NULL,
|
|
145383
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
145384
|
+
window_index INTEGER NOT NULL DEFAULT 0,
|
|
145385
|
+
start_ordinal INTEGER NOT NULL,
|
|
145386
|
+
end_ordinal INTEGER NOT NULL,
|
|
145387
|
+
chunk_hash TEXT NOT NULL,
|
|
145388
|
+
model_id TEXT NOT NULL,
|
|
145389
|
+
dims INTEGER NOT NULL,
|
|
145390
|
+
vector BLOB NOT NULL,
|
|
145391
|
+
created_at INTEGER NOT NULL,
|
|
145392
|
+
UNIQUE(compartment_id, window_index)
|
|
145393
|
+
);
|
|
145394
|
+
CREATE INDEX IF NOT EXISTS idx_cce_session ON compartment_chunk_embeddings(session_id);
|
|
145395
|
+
CREATE INDEX IF NOT EXISTS idx_cce_project_model ON compartment_chunk_embeddings(project_path, model_id);
|
|
145396
|
+
|
|
145397
|
+
CREATE TABLE IF NOT EXISTS session_projects (
|
|
145398
|
+
session_id TEXT NOT NULL,
|
|
145399
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
145400
|
+
project_path TEXT NOT NULL,
|
|
145401
|
+
updated_at INTEGER NOT NULL,
|
|
145402
|
+
PRIMARY KEY(session_id, harness)
|
|
145403
|
+
);
|
|
145404
|
+
CREATE INDEX IF NOT EXISTS idx_session_projects_project
|
|
145405
|
+
ON session_projects(project_path);
|
|
145406
|
+
|
|
145373
145407
|
CREATE TABLE IF NOT EXISTS compartment_events (
|
|
145374
145408
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145375
145409
|
session_id TEXT NOT NULL,
|
|
@@ -145555,6 +145589,25 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145555
145589
|
rekeyed_at INTEGER NOT NULL
|
|
145556
145590
|
);
|
|
145557
145591
|
|
|
145592
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
145593
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145594
|
+
name TEXT NOT NULL UNIQUE,
|
|
145595
|
+
created_at INTEGER NOT NULL,
|
|
145596
|
+
updated_at INTEGER NOT NULL,
|
|
145597
|
+
share_categories TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'
|
|
145598
|
+
);
|
|
145599
|
+
|
|
145600
|
+
CREATE TABLE IF NOT EXISTS workspace_members (
|
|
145601
|
+
workspace_id INTEGER NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
145602
|
+
project_path TEXT NOT NULL,
|
|
145603
|
+
display_name TEXT NOT NULL,
|
|
145604
|
+
display_path TEXT NOT NULL,
|
|
145605
|
+
added_at INTEGER NOT NULL,
|
|
145606
|
+
PRIMARY KEY (workspace_id, project_path)
|
|
145607
|
+
);
|
|
145608
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_unique ON workspace_members(project_path);
|
|
145609
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_name ON workspace_members(workspace_id, display_name);
|
|
145610
|
+
|
|
145558
145611
|
CREATE TABLE IF NOT EXISTS v22_backfill_failures (
|
|
145559
145612
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145560
145613
|
table_name TEXT NOT NULL,
|
|
@@ -145666,6 +145719,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145666
145719
|
deferred_execute_state TEXT,
|
|
145667
145720
|
cached_m0_bytes BLOB,
|
|
145668
145721
|
cached_m0_project_memory_epoch INTEGER,
|
|
145722
|
+
cached_m0_workspace_fingerprint TEXT,
|
|
145669
145723
|
cached_m0_project_user_profile_version INTEGER,
|
|
145670
145724
|
cached_m0_max_compartment_seq INTEGER,
|
|
145671
145725
|
cached_m0_max_memory_id INTEGER,
|
|
@@ -145824,6 +145878,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145824
145878
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
145825
145879
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
145826
145880
|
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
145881
|
+
ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
|
|
145827
145882
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
145828
145883
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
145829
145884
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -145877,6 +145932,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145877
145932
|
ensureColumn(db, "memories", "importance", "INTEGER");
|
|
145878
145933
|
ensureColumn(db, "session_meta", "cached_m0_bytes", "BLOB");
|
|
145879
145934
|
ensureColumn(db, "session_meta", "cached_m0_project_memory_epoch", "INTEGER");
|
|
145935
|
+
ensureColumn(db, "session_meta", "cached_m0_workspace_fingerprint", "TEXT");
|
|
145880
145936
|
ensureColumn(db, "session_meta", "cached_m0_project_user_profile_version", "INTEGER");
|
|
145881
145937
|
ensureColumn(db, "session_meta", "cached_m0_max_compartment_seq", "INTEGER");
|
|
145882
145938
|
ensureColumn(db, "session_meta", "cached_m0_max_memory_id", "INTEGER");
|
|
@@ -145908,6 +145964,15 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145908
145964
|
project_user_profile_version INTEGER NOT NULL DEFAULT 0,
|
|
145909
145965
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
145910
145966
|
);
|
|
145967
|
+
CREATE TABLE IF NOT EXISTS session_projects (
|
|
145968
|
+
session_id TEXT NOT NULL,
|
|
145969
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
145970
|
+
project_path TEXT NOT NULL,
|
|
145971
|
+
updated_at INTEGER NOT NULL,
|
|
145972
|
+
PRIMARY KEY(session_id, harness)
|
|
145973
|
+
);
|
|
145974
|
+
CREATE INDEX IF NOT EXISTS idx_session_projects_project
|
|
145975
|
+
ON session_projects(project_path);
|
|
145911
145976
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
145912
145977
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145913
145978
|
session_id TEXT NOT NULL,
|
|
@@ -145935,6 +146000,23 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145935
146000
|
new_project_path TEXT NOT NULL,
|
|
145936
146001
|
rekeyed_at INTEGER NOT NULL
|
|
145937
146002
|
);
|
|
146003
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
146004
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
146005
|
+
name TEXT NOT NULL UNIQUE,
|
|
146006
|
+
created_at INTEGER NOT NULL,
|
|
146007
|
+
updated_at INTEGER NOT NULL,
|
|
146008
|
+
share_categories TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'
|
|
146009
|
+
);
|
|
146010
|
+
CREATE TABLE IF NOT EXISTS workspace_members (
|
|
146011
|
+
workspace_id INTEGER NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
146012
|
+
project_path TEXT NOT NULL,
|
|
146013
|
+
display_name TEXT NOT NULL,
|
|
146014
|
+
display_path TEXT NOT NULL,
|
|
146015
|
+
added_at INTEGER NOT NULL,
|
|
146016
|
+
PRIMARY KEY (workspace_id, project_path)
|
|
146017
|
+
);
|
|
146018
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_unique ON workspace_members(project_path);
|
|
146019
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_name ON workspace_members(workspace_id, display_name);
|
|
145938
146020
|
CREATE TABLE IF NOT EXISTS v22_backfill_failures (
|
|
145939
146021
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145940
146022
|
table_name TEXT NOT NULL,
|
|
@@ -145956,6 +146038,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145956
146038
|
ensureColumn(db, "recomp_compartments", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
145957
146039
|
ensureColumn(db, "recomp_facts", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
145958
146040
|
ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
146041
|
+
ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
|
|
145959
146042
|
}
|
|
145960
146043
|
function healAllNullColumns(db) {
|
|
145961
146044
|
healNullTextColumns(db);
|
|
@@ -145993,6 +146076,7 @@ function healNullTextColumns(db) {
|
|
|
145993
146076
|
["system_prompt_hash", ""],
|
|
145994
146077
|
["stripped_placeholder_ids", ""],
|
|
145995
146078
|
["stale_reduce_stripped_ids", ""],
|
|
146079
|
+
["processed_image_stripped_ids", ""],
|
|
145996
146080
|
["memory_block_cache", ""],
|
|
145997
146081
|
["memory_block_ids", ""],
|
|
145998
146082
|
["compaction_marker_state", ""],
|
|
@@ -146037,7 +146121,7 @@ function healNullIntegerColumns(db) {
|
|
|
146037
146121
|
}
|
|
146038
146122
|
}
|
|
146039
146123
|
function ensureColumn(db, table, column, definition) {
|
|
146040
|
-
if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_'(),[\]\s]+$/i.test(definition)) {
|
|
146124
|
+
if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_"'(),[\]\s]+$/i.test(definition)) {
|
|
146041
146125
|
throw new Error(`Unsafe schema identifier: ${table}.${column} ${definition}`);
|
|
146042
146126
|
}
|
|
146043
146127
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
@@ -146129,7 +146213,7 @@ function closeDatabase() {
|
|
|
146129
146213
|
}
|
|
146130
146214
|
}
|
|
146131
146215
|
}
|
|
146132
|
-
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION =
|
|
146216
|
+
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 36, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS = 120000;
|
|
146133
146217
|
var init_storage_db = __esm(async () => {
|
|
146134
146218
|
init_data_path();
|
|
146135
146219
|
init_logger();
|
|
@@ -146149,10 +146233,263 @@ var init_storage_db = __esm(async () => {
|
|
|
146149
146233
|
};
|
|
146150
146234
|
});
|
|
146151
146235
|
|
|
146236
|
+
// ../plugin/src/features/magic-context/memory/constants.ts
|
|
146237
|
+
var V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, MEMORY_CATEGORY_ORDER_UNKNOWN = 99, MEMORY_CATEGORY_ORDER_PRIORITY, MEMORY_CATEGORY_ORDER_SQL, CATEGORY_DEFAULT_TTL;
|
|
146238
|
+
var init_constants = __esm(() => {
|
|
146239
|
+
V2_MEMORY_CATEGORIES = [
|
|
146240
|
+
"PROJECT_RULES",
|
|
146241
|
+
"ARCHITECTURE",
|
|
146242
|
+
"CONSTRAINTS",
|
|
146243
|
+
"CONFIG_VALUES",
|
|
146244
|
+
"NAMING"
|
|
146245
|
+
];
|
|
146246
|
+
CATEGORY_PRIORITY = [
|
|
146247
|
+
"PROJECT_RULES",
|
|
146248
|
+
"ARCHITECTURE",
|
|
146249
|
+
"CONSTRAINTS",
|
|
146250
|
+
"CONFIG_VALUES",
|
|
146251
|
+
"NAMING",
|
|
146252
|
+
"USER_DIRECTIVES",
|
|
146253
|
+
"USER_PREFERENCES",
|
|
146254
|
+
"CONFIG_DEFAULTS",
|
|
146255
|
+
"ARCHITECTURE_DECISIONS",
|
|
146256
|
+
"ENVIRONMENT",
|
|
146257
|
+
"WORKFLOW_RULES",
|
|
146258
|
+
"KNOWN_ISSUES"
|
|
146259
|
+
];
|
|
146260
|
+
MEMORY_CATEGORY_ORDER_PRIORITY = CATEGORY_PRIORITY.reduce((acc, category, index) => {
|
|
146261
|
+
acc[category] = index;
|
|
146262
|
+
return acc;
|
|
146263
|
+
}, {});
|
|
146264
|
+
MEMORY_CATEGORY_ORDER_SQL = `CASE category ${CATEGORY_PRIORITY.map((category, index) => `WHEN '${category}' THEN ${index}`).join(" ")} ELSE ${MEMORY_CATEGORY_ORDER_UNKNOWN} END`;
|
|
146265
|
+
CATEGORY_DEFAULT_TTL = {
|
|
146266
|
+
WORKFLOW_RULES: 90 * 24 * 60 * 60 * 1000,
|
|
146267
|
+
KNOWN_ISSUES: 30 * 24 * 60 * 60 * 1000
|
|
146268
|
+
};
|
|
146269
|
+
});
|
|
146270
|
+
|
|
146271
|
+
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
146272
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
146273
|
+
import { createHash } from "node:crypto";
|
|
146274
|
+
import { statSync as statSync3 } from "node:fs";
|
|
146275
|
+
import path3 from "node:path";
|
|
146276
|
+
function asError(error) {
|
|
146277
|
+
return error instanceof Error ? error : undefined;
|
|
146278
|
+
}
|
|
146279
|
+
function getErrorCode(error) {
|
|
146280
|
+
if (error === null || typeof error !== "object" || !("code" in error)) {
|
|
146281
|
+
return;
|
|
146282
|
+
}
|
|
146283
|
+
const code = error.code;
|
|
146284
|
+
return typeof code === "string" ? code : undefined;
|
|
146285
|
+
}
|
|
146286
|
+
function getErrorSignal(error) {
|
|
146287
|
+
if (error === null || typeof error !== "object" || !("signal" in error)) {
|
|
146288
|
+
return;
|
|
146289
|
+
}
|
|
146290
|
+
const signal = error.signal;
|
|
146291
|
+
return typeof signal === "string" ? signal : undefined;
|
|
146292
|
+
}
|
|
146293
|
+
function getErrorKilled(error) {
|
|
146294
|
+
if (error === null || typeof error !== "object" || !("killed" in error)) {
|
|
146295
|
+
return false;
|
|
146296
|
+
}
|
|
146297
|
+
return error.killed === true;
|
|
146298
|
+
}
|
|
146299
|
+
function getErrorStderr(error) {
|
|
146300
|
+
if (error === null || typeof error !== "object" || !("stderr" in error)) {
|
|
146301
|
+
return "";
|
|
146302
|
+
}
|
|
146303
|
+
const stderr = error.stderr;
|
|
146304
|
+
if (typeof stderr === "string") {
|
|
146305
|
+
return stderr;
|
|
146306
|
+
}
|
|
146307
|
+
if (Buffer.isBuffer(stderr)) {
|
|
146308
|
+
return stderr.toString("utf8");
|
|
146309
|
+
}
|
|
146310
|
+
return "";
|
|
146311
|
+
}
|
|
146312
|
+
function directoryFallback(directory) {
|
|
146313
|
+
const canonical = path3.resolve(directory);
|
|
146314
|
+
const hash = createHash("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
|
|
146315
|
+
return `dir:${hash}`;
|
|
146316
|
+
}
|
|
146317
|
+
function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
|
|
146318
|
+
try {
|
|
146319
|
+
const stat = statSync3(canonicalDirectory);
|
|
146320
|
+
if (!stat.isDirectory()) {
|
|
146321
|
+
throw new ProjectIdentityError("unknown", rawDirectory, `Project path is not a directory: ${canonicalDirectory}`);
|
|
146322
|
+
}
|
|
146323
|
+
} catch (error) {
|
|
146324
|
+
if (error instanceof ProjectIdentityError) {
|
|
146325
|
+
throw error;
|
|
146326
|
+
}
|
|
146327
|
+
const code = getErrorCode(error);
|
|
146328
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
146329
|
+
throw new ProjectIdentityError("permission_denied", rawDirectory, `Permission denied while accessing project directory: ${canonicalDirectory}`, asError(error));
|
|
146330
|
+
}
|
|
146331
|
+
throw new ProjectIdentityError("unknown", rawDirectory, `Unable to access project directory: ${canonicalDirectory}`, asError(error));
|
|
146332
|
+
}
|
|
146333
|
+
}
|
|
146334
|
+
function isGitTimeoutError(error) {
|
|
146335
|
+
const code = getErrorCode(error);
|
|
146336
|
+
const signal = getErrorSignal(error);
|
|
146337
|
+
return code === "ETIMEDOUT" || signal === "SIGTERM" || signal === "SIGKILL" || getErrorKilled(error);
|
|
146338
|
+
}
|
|
146339
|
+
function classifyGitError(error, rawDirectory) {
|
|
146340
|
+
if (isGitTimeoutError(error)) {
|
|
146341
|
+
return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${GIT_TIMEOUT_MS}ms`, asError(error));
|
|
146342
|
+
}
|
|
146343
|
+
const code = getErrorCode(error);
|
|
146344
|
+
if (code === "ENOENT") {
|
|
146345
|
+
return new ProjectIdentityError("git_missing", rawDirectory, "git binary is not available in PATH", asError(error));
|
|
146346
|
+
}
|
|
146347
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
146348
|
+
return new ProjectIdentityError("permission_denied", rawDirectory, "Permission denied while spawning git", asError(error));
|
|
146349
|
+
}
|
|
146350
|
+
const stderr = getErrorStderr(error).toLowerCase();
|
|
146351
|
+
if (stderr.includes("not a git repository") || stderr.includes("does not have any commits yet") || stderr.includes("ambiguous argument 'head'") || stderr.includes("unknown revision or path")) {
|
|
146352
|
+
return new ProjectIdentityError("not_git_repo", rawDirectory, "Directory has no git root commit; caller may use directory fallback", asError(error));
|
|
146353
|
+
}
|
|
146354
|
+
return new ProjectIdentityError("unknown", rawDirectory, "git rev-list failed while resolving project identity", asError(error));
|
|
146355
|
+
}
|
|
146356
|
+
function resolveProjectIdentityStrict(directory) {
|
|
146357
|
+
const canonical = path3.resolve(directory);
|
|
146358
|
+
const cached = identityCache.get(canonical);
|
|
146359
|
+
if (cached !== undefined) {
|
|
146360
|
+
return cached;
|
|
146361
|
+
}
|
|
146362
|
+
assertDirectoryUsable(canonical, directory);
|
|
146363
|
+
let output;
|
|
146364
|
+
try {
|
|
146365
|
+
output = execFileSync3("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
146366
|
+
cwd: canonical,
|
|
146367
|
+
encoding: "utf8",
|
|
146368
|
+
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
146369
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
146370
|
+
timeout: GIT_TIMEOUT_MS
|
|
146371
|
+
});
|
|
146372
|
+
} catch (error) {
|
|
146373
|
+
throw classifyGitError(error, directory);
|
|
146374
|
+
}
|
|
146375
|
+
const firstLine = output.split(`
|
|
146376
|
+
`)[0]?.trim() ?? "";
|
|
146377
|
+
const rootCommit = firstLine.slice(0, 64);
|
|
146378
|
+
if (rootCommit.length < 7) {
|
|
146379
|
+
throw new ProjectIdentityError("unknown", directory, "git rev-list returned no valid root commit hash");
|
|
146380
|
+
}
|
|
146381
|
+
const identity = `git:${rootCommit}`;
|
|
146382
|
+
identityCache.set(canonical, identity);
|
|
146383
|
+
return identity;
|
|
146384
|
+
}
|
|
146385
|
+
function shouldUseDirectoryFallback(error) {
|
|
146386
|
+
return error.errorClass === "not_git_repo" || error.errorClass === "unknown" && error.message.startsWith("Unable to access project directory:");
|
|
146387
|
+
}
|
|
146388
|
+
function resolveProjectIdentity(directory) {
|
|
146389
|
+
const canonical = path3.resolve(directory);
|
|
146390
|
+
const cachedFallback = directoryFallbackCache.get(canonical);
|
|
146391
|
+
if (cachedFallback !== undefined) {
|
|
146392
|
+
if (!hasGitDir(canonical)) {
|
|
146393
|
+
return cachedFallback;
|
|
146394
|
+
}
|
|
146395
|
+
directoryFallbackCache.delete(canonical);
|
|
146396
|
+
}
|
|
146397
|
+
try {
|
|
146398
|
+
return resolveProjectIdentityStrict(directory);
|
|
146399
|
+
} catch (error) {
|
|
146400
|
+
if (error instanceof ProjectIdentityError && shouldUseDirectoryFallback(error)) {
|
|
146401
|
+
const fallback = directoryFallback(canonical);
|
|
146402
|
+
if (!hasGitDir(canonical)) {
|
|
146403
|
+
directoryFallbackCache.set(canonical, fallback);
|
|
146404
|
+
}
|
|
146405
|
+
return fallback;
|
|
146406
|
+
}
|
|
146407
|
+
throw error;
|
|
146408
|
+
}
|
|
146409
|
+
}
|
|
146410
|
+
function hasGitDir(canonical) {
|
|
146411
|
+
try {
|
|
146412
|
+
statSync3(path3.join(canonical, ".git"));
|
|
146413
|
+
return true;
|
|
146414
|
+
} catch {
|
|
146415
|
+
return false;
|
|
146416
|
+
}
|
|
146417
|
+
}
|
|
146418
|
+
var GIT_TIMEOUT_MS = 5000, identityCache, directoryFallbackCache, ProjectIdentityError;
|
|
146419
|
+
var init_project_identity = __esm(() => {
|
|
146420
|
+
identityCache = new Map;
|
|
146421
|
+
directoryFallbackCache = new Map;
|
|
146422
|
+
ProjectIdentityError = class ProjectIdentityError extends Error {
|
|
146423
|
+
errorClass;
|
|
146424
|
+
rawDirectory;
|
|
146425
|
+
constructor(errorClass, rawDirectory, message, cause) {
|
|
146426
|
+
super(message);
|
|
146427
|
+
this.name = "ProjectIdentityError";
|
|
146428
|
+
this.errorClass = errorClass;
|
|
146429
|
+
this.rawDirectory = rawDirectory;
|
|
146430
|
+
if (cause) {
|
|
146431
|
+
this.cause = cause;
|
|
146432
|
+
}
|
|
146433
|
+
}
|
|
146434
|
+
};
|
|
146435
|
+
});
|
|
146436
|
+
|
|
146437
|
+
// ../plugin/src/features/magic-context/project-identity.ts
|
|
146438
|
+
var init_project_identity2 = __esm(() => {
|
|
146439
|
+
init_project_identity();
|
|
146440
|
+
});
|
|
146441
|
+
|
|
146442
|
+
// ../plugin/src/features/magic-context/workspaces.ts
|
|
146443
|
+
function uniqueSorted(values) {
|
|
146444
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
146445
|
+
}
|
|
146446
|
+
function isInTransaction(db) {
|
|
146447
|
+
const candidate = db;
|
|
146448
|
+
return candidate.inTransaction === true || candidate.isTransaction === true;
|
|
146449
|
+
}
|
|
146450
|
+
function bumpEpochRows(db, identities, now) {
|
|
146451
|
+
const stmt2 = db.prepare(`INSERT INTO project_state
|
|
146452
|
+
(project_path, project_memory_epoch, project_user_profile_version, updated_at)
|
|
146453
|
+
VALUES (?, 1, 0, ?)
|
|
146454
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
146455
|
+
project_memory_epoch = project_memory_epoch + 1,
|
|
146456
|
+
updated_at = excluded.updated_at`);
|
|
146457
|
+
for (const identity of uniqueSorted(identities)) {
|
|
146458
|
+
stmt2.run(identity, now);
|
|
146459
|
+
}
|
|
146460
|
+
}
|
|
146461
|
+
function bumpEpochsForWorkspaceMemberSet(db, identities, now = Date.now()) {
|
|
146462
|
+
const run = () => bumpEpochRows(db, identities, now);
|
|
146463
|
+
if (isInTransaction(db)) {
|
|
146464
|
+
run();
|
|
146465
|
+
return;
|
|
146466
|
+
}
|
|
146467
|
+
db.exec("BEGIN IMMEDIATE");
|
|
146468
|
+
try {
|
|
146469
|
+
run();
|
|
146470
|
+
db.exec("COMMIT");
|
|
146471
|
+
} catch (error) {
|
|
146472
|
+
try {
|
|
146473
|
+
db.exec("ROLLBACK");
|
|
146474
|
+
} catch {}
|
|
146475
|
+
throw error;
|
|
146476
|
+
}
|
|
146477
|
+
}
|
|
146478
|
+
var VALID_SHARE_CATEGORIES;
|
|
146479
|
+
var init_workspaces = __esm(() => {
|
|
146480
|
+
init_constants();
|
|
146481
|
+
init_project_identity2();
|
|
146482
|
+
VALID_SHARE_CATEGORIES = new Set(V2_MEMORY_CATEGORIES);
|
|
146483
|
+
});
|
|
146484
|
+
|
|
146152
146485
|
// ../plugin/src/features/magic-context/migrations.ts
|
|
146153
146486
|
function tableExists(db, name2) {
|
|
146154
146487
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name2));
|
|
146155
146488
|
}
|
|
146489
|
+
function columnExists(db, table, column) {
|
|
146490
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
146491
|
+
return rows.some((row) => row.name === column);
|
|
146492
|
+
}
|
|
146156
146493
|
function ensureMigrationsTable(db) {
|
|
146157
146494
|
db.exec(`
|
|
146158
146495
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
@@ -146221,6 +146558,7 @@ function runMigrations(db) {
|
|
|
146221
146558
|
var MIGRATIONS, LATEST_MIGRATION_VERSION;
|
|
146222
146559
|
var init_migrations = __esm(async () => {
|
|
146223
146560
|
init_logger();
|
|
146561
|
+
init_workspaces();
|
|
146224
146562
|
await init_storage_db();
|
|
146225
146563
|
MIGRATIONS = [
|
|
146226
146564
|
{
|
|
@@ -147018,6 +147356,156 @@ var init_migrations = __esm(async () => {
|
|
|
147018
147356
|
db.prepare("UPDATE session_meta SET force_emergency_bypass_used = 0 WHERE force_emergency_bypass_used IS NULL").run();
|
|
147019
147357
|
db.prepare("UPDATE session_meta SET last_usage_context_limit = 0 WHERE last_usage_context_limit IS NULL").run();
|
|
147020
147358
|
}
|
|
147359
|
+
},
|
|
147360
|
+
{
|
|
147361
|
+
version: 33,
|
|
147362
|
+
description: "Compartment chunk embeddings for semantic message-history search",
|
|
147363
|
+
up: (db) => {
|
|
147364
|
+
db.exec(`
|
|
147365
|
+
CREATE TABLE IF NOT EXISTS compartment_chunk_embeddings (
|
|
147366
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
147367
|
+
compartment_id INTEGER NOT NULL REFERENCES compartments(id) ON DELETE CASCADE,
|
|
147368
|
+
session_id TEXT NOT NULL,
|
|
147369
|
+
project_path TEXT NOT NULL,
|
|
147370
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
147371
|
+
window_index INTEGER NOT NULL DEFAULT 0,
|
|
147372
|
+
start_ordinal INTEGER NOT NULL,
|
|
147373
|
+
end_ordinal INTEGER NOT NULL,
|
|
147374
|
+
chunk_hash TEXT NOT NULL,
|
|
147375
|
+
model_id TEXT NOT NULL,
|
|
147376
|
+
dims INTEGER NOT NULL,
|
|
147377
|
+
vector BLOB NOT NULL,
|
|
147378
|
+
created_at INTEGER NOT NULL,
|
|
147379
|
+
UNIQUE(compartment_id, window_index)
|
|
147380
|
+
);
|
|
147381
|
+
CREATE INDEX IF NOT EXISTS idx_cce_session
|
|
147382
|
+
ON compartment_chunk_embeddings(session_id);
|
|
147383
|
+
CREATE INDEX IF NOT EXISTS idx_cce_project_model
|
|
147384
|
+
ON compartment_chunk_embeddings(project_path, model_id);
|
|
147385
|
+
`);
|
|
147386
|
+
}
|
|
147387
|
+
},
|
|
147388
|
+
{
|
|
147389
|
+
version: 34,
|
|
147390
|
+
description: "workspace tables and m[0] workspace fingerprint cache reset",
|
|
147391
|
+
up: (db) => {
|
|
147392
|
+
db.exec(`
|
|
147393
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
147394
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
147395
|
+
name TEXT NOT NULL UNIQUE,
|
|
147396
|
+
created_at INTEGER NOT NULL,
|
|
147397
|
+
updated_at INTEGER NOT NULL
|
|
147398
|
+
);
|
|
147399
|
+
CREATE TABLE IF NOT EXISTS workspace_members (
|
|
147400
|
+
workspace_id INTEGER NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
147401
|
+
project_path TEXT NOT NULL,
|
|
147402
|
+
display_name TEXT NOT NULL,
|
|
147403
|
+
display_path TEXT NOT NULL,
|
|
147404
|
+
added_at INTEGER NOT NULL,
|
|
147405
|
+
PRIMARY KEY (workspace_id, project_path)
|
|
147406
|
+
);
|
|
147407
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_unique
|
|
147408
|
+
ON workspace_members(project_path);
|
|
147409
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_member_name
|
|
147410
|
+
ON workspace_members(workspace_id, display_name);
|
|
147411
|
+
`);
|
|
147412
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
147413
|
+
if (!hasSessionMeta)
|
|
147414
|
+
return;
|
|
147415
|
+
ensureColumn(db, "session_meta", "cached_m0_workspace_fingerprint", "TEXT");
|
|
147416
|
+
const columns = new Set(db.prepare("PRAGMA table_info(session_meta)").all().map((column) => column.name));
|
|
147417
|
+
const clears = [
|
|
147418
|
+
["cached_m0_bytes", null],
|
|
147419
|
+
["cached_m1_bytes", null],
|
|
147420
|
+
["cached_m0_project_memory_epoch", null],
|
|
147421
|
+
["cached_m0_workspace_fingerprint", null],
|
|
147422
|
+
["cached_m0_project_user_profile_version", null],
|
|
147423
|
+
["cached_m0_max_compartment_seq", null],
|
|
147424
|
+
["cached_m0_max_memory_id", null],
|
|
147425
|
+
["cached_m0_max_mutation_id", null],
|
|
147426
|
+
["cached_m0_max_memory_mutation_id", null],
|
|
147427
|
+
["cached_m0_project_docs_hash", null],
|
|
147428
|
+
["cached_m0_materialized_at", null],
|
|
147429
|
+
["cached_m0_session_facts_version", null],
|
|
147430
|
+
["cached_m0_upgrade_state", null],
|
|
147431
|
+
["cached_m0_system_hash", null],
|
|
147432
|
+
["cached_m0_tool_set_hash", null],
|
|
147433
|
+
["cached_m0_model_key", null],
|
|
147434
|
+
["cached_m0_last_baseline_end_message_id", null],
|
|
147435
|
+
["memory_block_cache", ""],
|
|
147436
|
+
["memory_block_ids", ""],
|
|
147437
|
+
["memory_block_count", 0]
|
|
147438
|
+
];
|
|
147439
|
+
const setClauses = [];
|
|
147440
|
+
const values = [];
|
|
147441
|
+
for (const [column, value] of clears) {
|
|
147442
|
+
if (!columns.has(column))
|
|
147443
|
+
continue;
|
|
147444
|
+
setClauses.push(`${column} = ?`);
|
|
147445
|
+
values.push(value);
|
|
147446
|
+
}
|
|
147447
|
+
if (setClauses.length > 0) {
|
|
147448
|
+
db.prepare(`UPDATE session_meta SET ${setClauses.join(", ")}`).run(...values);
|
|
147449
|
+
}
|
|
147450
|
+
}
|
|
147451
|
+
},
|
|
147452
|
+
{
|
|
147453
|
+
version: 35,
|
|
147454
|
+
description: "workspace per-category share defaults and epoch refresh",
|
|
147455
|
+
up: (db) => {
|
|
147456
|
+
db.exec(`
|
|
147457
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
147458
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
147459
|
+
name TEXT NOT NULL UNIQUE,
|
|
147460
|
+
created_at INTEGER NOT NULL,
|
|
147461
|
+
updated_at INTEGER NOT NULL,
|
|
147462
|
+
share_categories TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'
|
|
147463
|
+
);
|
|
147464
|
+
`);
|
|
147465
|
+
if (!columnExists(db, "workspaces", "share_categories")) {
|
|
147466
|
+
db.exec(`ALTER TABLE workspaces ADD COLUMN share_categories TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
|
|
147467
|
+
}
|
|
147468
|
+
db.prepare(`UPDATE workspaces
|
|
147469
|
+
SET share_categories = '["CONSTRAINTS"]'
|
|
147470
|
+
WHERE share_categories IS NULL OR share_categories = ''`).run();
|
|
147471
|
+
if (!tableExists(db, "workspace_members"))
|
|
147472
|
+
return;
|
|
147473
|
+
const rows = db.prepare(`SELECT DISTINCT project_path AS identity
|
|
147474
|
+
FROM workspace_members
|
|
147475
|
+
WHERE project_path IS NOT NULL AND project_path <> ''
|
|
147476
|
+
ORDER BY project_path ASC`).all();
|
|
147477
|
+
const identities = rows.map((row) => typeof row.identity === "string" ? row.identity : "").filter((identity) => identity.length > 0);
|
|
147478
|
+
if (identities.length > 0) {
|
|
147479
|
+
bumpEpochsForWorkspaceMemberSet(db, identities, Date.now());
|
|
147480
|
+
}
|
|
147481
|
+
}
|
|
147482
|
+
},
|
|
147483
|
+
{
|
|
147484
|
+
version: 36,
|
|
147485
|
+
description: "session project ownership map for compartment chunk backfill scoping",
|
|
147486
|
+
up: (db) => {
|
|
147487
|
+
db.exec(`
|
|
147488
|
+
CREATE TABLE IF NOT EXISTS session_projects (
|
|
147489
|
+
session_id TEXT NOT NULL,
|
|
147490
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
147491
|
+
project_path TEXT NOT NULL,
|
|
147492
|
+
updated_at INTEGER NOT NULL,
|
|
147493
|
+
PRIMARY KEY(session_id, harness)
|
|
147494
|
+
);
|
|
147495
|
+
CREATE INDEX IF NOT EXISTS idx_session_projects_project
|
|
147496
|
+
ON session_projects(project_path);
|
|
147497
|
+
`);
|
|
147498
|
+
const hasChunkTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='compartment_chunk_embeddings'").get();
|
|
147499
|
+
if (hasChunkTable) {
|
|
147500
|
+
db.exec(`
|
|
147501
|
+
INSERT OR IGNORE INTO session_projects (session_id, harness, project_path, updated_at)
|
|
147502
|
+
SELECT session_id, harness, MIN(project_path), 0
|
|
147503
|
+
FROM compartment_chunk_embeddings
|
|
147504
|
+
GROUP BY session_id, harness
|
|
147505
|
+
HAVING COUNT(DISTINCT project_path) = 1;
|
|
147506
|
+
`);
|
|
147507
|
+
}
|
|
147508
|
+
}
|
|
147021
147509
|
}
|
|
147022
147510
|
];
|
|
147023
147511
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -147030,177 +147518,6 @@ var init_project_docs_hash = __esm(() => {
|
|
|
147030
147518
|
MAX_PROJECT_DOC_BYTES = 256 * 1024;
|
|
147031
147519
|
docsCache = new Map;
|
|
147032
147520
|
});
|
|
147033
|
-
|
|
147034
|
-
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
147035
|
-
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
147036
|
-
import { createHash } from "node:crypto";
|
|
147037
|
-
import { statSync as statSync3 } from "node:fs";
|
|
147038
|
-
import path3 from "node:path";
|
|
147039
|
-
function asError(error) {
|
|
147040
|
-
return error instanceof Error ? error : undefined;
|
|
147041
|
-
}
|
|
147042
|
-
function getErrorCode(error) {
|
|
147043
|
-
if (error === null || typeof error !== "object" || !("code" in error)) {
|
|
147044
|
-
return;
|
|
147045
|
-
}
|
|
147046
|
-
const code = error.code;
|
|
147047
|
-
return typeof code === "string" ? code : undefined;
|
|
147048
|
-
}
|
|
147049
|
-
function getErrorSignal(error) {
|
|
147050
|
-
if (error === null || typeof error !== "object" || !("signal" in error)) {
|
|
147051
|
-
return;
|
|
147052
|
-
}
|
|
147053
|
-
const signal = error.signal;
|
|
147054
|
-
return typeof signal === "string" ? signal : undefined;
|
|
147055
|
-
}
|
|
147056
|
-
function getErrorKilled(error) {
|
|
147057
|
-
if (error === null || typeof error !== "object" || !("killed" in error)) {
|
|
147058
|
-
return false;
|
|
147059
|
-
}
|
|
147060
|
-
return error.killed === true;
|
|
147061
|
-
}
|
|
147062
|
-
function getErrorStderr(error) {
|
|
147063
|
-
if (error === null || typeof error !== "object" || !("stderr" in error)) {
|
|
147064
|
-
return "";
|
|
147065
|
-
}
|
|
147066
|
-
const stderr = error.stderr;
|
|
147067
|
-
if (typeof stderr === "string") {
|
|
147068
|
-
return stderr;
|
|
147069
|
-
}
|
|
147070
|
-
if (Buffer.isBuffer(stderr)) {
|
|
147071
|
-
return stderr.toString("utf8");
|
|
147072
|
-
}
|
|
147073
|
-
return "";
|
|
147074
|
-
}
|
|
147075
|
-
function directoryFallback(directory) {
|
|
147076
|
-
const canonical = path3.resolve(directory);
|
|
147077
|
-
const hash = createHash("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
|
|
147078
|
-
return `dir:${hash}`;
|
|
147079
|
-
}
|
|
147080
|
-
function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
|
|
147081
|
-
try {
|
|
147082
|
-
const stat = statSync3(canonicalDirectory);
|
|
147083
|
-
if (!stat.isDirectory()) {
|
|
147084
|
-
throw new ProjectIdentityError("unknown", rawDirectory, `Project path is not a directory: ${canonicalDirectory}`);
|
|
147085
|
-
}
|
|
147086
|
-
} catch (error) {
|
|
147087
|
-
if (error instanceof ProjectIdentityError) {
|
|
147088
|
-
throw error;
|
|
147089
|
-
}
|
|
147090
|
-
const code = getErrorCode(error);
|
|
147091
|
-
if (code === "EACCES" || code === "EPERM") {
|
|
147092
|
-
throw new ProjectIdentityError("permission_denied", rawDirectory, `Permission denied while accessing project directory: ${canonicalDirectory}`, asError(error));
|
|
147093
|
-
}
|
|
147094
|
-
throw new ProjectIdentityError("unknown", rawDirectory, `Unable to access project directory: ${canonicalDirectory}`, asError(error));
|
|
147095
|
-
}
|
|
147096
|
-
}
|
|
147097
|
-
function isGitTimeoutError(error) {
|
|
147098
|
-
const code = getErrorCode(error);
|
|
147099
|
-
const signal = getErrorSignal(error);
|
|
147100
|
-
return code === "ETIMEDOUT" || signal === "SIGTERM" || signal === "SIGKILL" || getErrorKilled(error);
|
|
147101
|
-
}
|
|
147102
|
-
function classifyGitError(error, rawDirectory) {
|
|
147103
|
-
if (isGitTimeoutError(error)) {
|
|
147104
|
-
return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${GIT_TIMEOUT_MS}ms`, asError(error));
|
|
147105
|
-
}
|
|
147106
|
-
const code = getErrorCode(error);
|
|
147107
|
-
if (code === "ENOENT") {
|
|
147108
|
-
return new ProjectIdentityError("git_missing", rawDirectory, "git binary is not available in PATH", asError(error));
|
|
147109
|
-
}
|
|
147110
|
-
if (code === "EACCES" || code === "EPERM") {
|
|
147111
|
-
return new ProjectIdentityError("permission_denied", rawDirectory, "Permission denied while spawning git", asError(error));
|
|
147112
|
-
}
|
|
147113
|
-
const stderr = getErrorStderr(error).toLowerCase();
|
|
147114
|
-
if (stderr.includes("not a git repository") || stderr.includes("does not have any commits yet") || stderr.includes("ambiguous argument 'head'") || stderr.includes("unknown revision or path")) {
|
|
147115
|
-
return new ProjectIdentityError("not_git_repo", rawDirectory, "Directory has no git root commit; caller may use directory fallback", asError(error));
|
|
147116
|
-
}
|
|
147117
|
-
return new ProjectIdentityError("unknown", rawDirectory, "git rev-list failed while resolving project identity", asError(error));
|
|
147118
|
-
}
|
|
147119
|
-
function resolveProjectIdentityStrict(directory) {
|
|
147120
|
-
const canonical = path3.resolve(directory);
|
|
147121
|
-
const cached = identityCache.get(canonical);
|
|
147122
|
-
if (cached !== undefined) {
|
|
147123
|
-
return cached;
|
|
147124
|
-
}
|
|
147125
|
-
assertDirectoryUsable(canonical, directory);
|
|
147126
|
-
let output;
|
|
147127
|
-
try {
|
|
147128
|
-
output = execFileSync3("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
147129
|
-
cwd: canonical,
|
|
147130
|
-
encoding: "utf8",
|
|
147131
|
-
env: { ...process.env, LC_ALL: "C", LANG: "C" },
|
|
147132
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
147133
|
-
timeout: GIT_TIMEOUT_MS
|
|
147134
|
-
});
|
|
147135
|
-
} catch (error) {
|
|
147136
|
-
throw classifyGitError(error, directory);
|
|
147137
|
-
}
|
|
147138
|
-
const firstLine = output.split(`
|
|
147139
|
-
`)[0]?.trim() ?? "";
|
|
147140
|
-
const rootCommit = firstLine.slice(0, 64);
|
|
147141
|
-
if (rootCommit.length < 7) {
|
|
147142
|
-
throw new ProjectIdentityError("unknown", directory, "git rev-list returned no valid root commit hash");
|
|
147143
|
-
}
|
|
147144
|
-
const identity = `git:${rootCommit}`;
|
|
147145
|
-
identityCache.set(canonical, identity);
|
|
147146
|
-
return identity;
|
|
147147
|
-
}
|
|
147148
|
-
function shouldUseDirectoryFallback(error) {
|
|
147149
|
-
return error.errorClass === "not_git_repo" || error.errorClass === "unknown" && error.message.startsWith("Unable to access project directory:");
|
|
147150
|
-
}
|
|
147151
|
-
function resolveProjectIdentity(directory) {
|
|
147152
|
-
const canonical = path3.resolve(directory);
|
|
147153
|
-
const cachedFallback = directoryFallbackCache.get(canonical);
|
|
147154
|
-
if (cachedFallback !== undefined) {
|
|
147155
|
-
if (!hasGitDir(canonical)) {
|
|
147156
|
-
return cachedFallback;
|
|
147157
|
-
}
|
|
147158
|
-
directoryFallbackCache.delete(canonical);
|
|
147159
|
-
}
|
|
147160
|
-
try {
|
|
147161
|
-
return resolveProjectIdentityStrict(directory);
|
|
147162
|
-
} catch (error) {
|
|
147163
|
-
if (error instanceof ProjectIdentityError && shouldUseDirectoryFallback(error)) {
|
|
147164
|
-
const fallback = directoryFallback(canonical);
|
|
147165
|
-
if (!hasGitDir(canonical)) {
|
|
147166
|
-
directoryFallbackCache.set(canonical, fallback);
|
|
147167
|
-
}
|
|
147168
|
-
return fallback;
|
|
147169
|
-
}
|
|
147170
|
-
throw error;
|
|
147171
|
-
}
|
|
147172
|
-
}
|
|
147173
|
-
function hasGitDir(canonical) {
|
|
147174
|
-
try {
|
|
147175
|
-
statSync3(path3.join(canonical, ".git"));
|
|
147176
|
-
return true;
|
|
147177
|
-
} catch {
|
|
147178
|
-
return false;
|
|
147179
|
-
}
|
|
147180
|
-
}
|
|
147181
|
-
var GIT_TIMEOUT_MS = 5000, identityCache, directoryFallbackCache, ProjectIdentityError;
|
|
147182
|
-
var init_project_identity = __esm(() => {
|
|
147183
|
-
identityCache = new Map;
|
|
147184
|
-
directoryFallbackCache = new Map;
|
|
147185
|
-
ProjectIdentityError = class ProjectIdentityError extends Error {
|
|
147186
|
-
errorClass;
|
|
147187
|
-
rawDirectory;
|
|
147188
|
-
constructor(errorClass, rawDirectory, message, cause) {
|
|
147189
|
-
super(message);
|
|
147190
|
-
this.name = "ProjectIdentityError";
|
|
147191
|
-
this.errorClass = errorClass;
|
|
147192
|
-
this.rawDirectory = rawDirectory;
|
|
147193
|
-
if (cause) {
|
|
147194
|
-
this.cause = cause;
|
|
147195
|
-
}
|
|
147196
|
-
}
|
|
147197
|
-
};
|
|
147198
|
-
});
|
|
147199
|
-
|
|
147200
|
-
// ../plugin/src/features/magic-context/project-identity.ts
|
|
147201
|
-
var init_project_identity2 = __esm(() => {
|
|
147202
|
-
init_project_identity();
|
|
147203
|
-
});
|
|
147204
147521
|
// ../plugin/src/features/magic-context/storage-m0-mutation-log.ts
|
|
147205
147522
|
var M0_MUTATION_TYPES;
|
|
147206
147523
|
var init_storage_m0_mutation_log = __esm(() => {
|
|
@@ -147328,6 +147645,7 @@ var init_storage = __esm(async () => {
|
|
|
147328
147645
|
init_storage_source();
|
|
147329
147646
|
init_storage_tags();
|
|
147330
147647
|
init_storage_v22_backfill_failures();
|
|
147648
|
+
init_workspaces();
|
|
147331
147649
|
await __promiseAll([
|
|
147332
147650
|
init_message_index(),
|
|
147333
147651
|
init_migrations(),
|
|
@@ -162515,7 +162833,8 @@ var init_magic_context = __esm(() => {
|
|
|
162515
162833
|
endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
|
|
162516
162834
|
api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
|
|
162517
162835
|
input_type: exports_external.string().optional().describe("Optional input_type sent in the embedding request body. Required by some openai-compatible providers (e.g. NVIDIA NIM expects 'query' or 'passage'). Omitted from the request when unset."),
|
|
162518
|
-
truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset.")
|
|
162836
|
+
truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset."),
|
|
162837
|
+
max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted.")
|
|
162519
162838
|
}).superRefine((data, ctx) => {
|
|
162520
162839
|
if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
|
|
162521
162840
|
ctx.addIssue({
|
|
@@ -162536,7 +162855,8 @@ var init_magic_context = __esm(() => {
|
|
|
162536
162855
|
if (data.provider === "local") {
|
|
162537
162856
|
return {
|
|
162538
162857
|
provider: "local",
|
|
162539
|
-
model: data.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
162858
|
+
model: data.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
162859
|
+
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
|
|
162540
162860
|
};
|
|
162541
162861
|
}
|
|
162542
162862
|
if (data.provider === "openai-compatible") {
|
|
@@ -162549,7 +162869,8 @@ var init_magic_context = __esm(() => {
|
|
|
162549
162869
|
endpoint: data.endpoint?.trim() ?? "",
|
|
162550
162870
|
...apiKey ? { api_key: apiKey } : {},
|
|
162551
162871
|
...inputType ? { input_type: inputType } : {},
|
|
162552
|
-
...truncate ? { truncate } : {}
|
|
162872
|
+
...truncate ? { truncate } : {},
|
|
162873
|
+
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
|
|
162553
162874
|
};
|
|
162554
162875
|
}
|
|
162555
162876
|
return { provider: "off" };
|
|
@@ -166500,6 +166821,7 @@ function printUsage() {
|
|
|
166500
166821
|
console.log("");
|
|
166501
166822
|
console.log(" Usage:");
|
|
166502
166823
|
console.log(" npx @cortexkit/magic-context@latest setup");
|
|
166824
|
+
console.log(" # add --dry-run to preview the wizard without writing any files");
|
|
166503
166825
|
console.log(" npx @cortexkit/magic-context@latest doctor");
|
|
166504
166826
|
console.log(" npx @cortexkit/magic-context@latest doctor --issue");
|
|
166505
166827
|
console.log(" npx @cortexkit/magic-context@latest doctor migrate \\");
|