@cortexkit/opencode-magic-context 0.12.0 → 0.13.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/README.md +3 -1
- package/dist/agents/historian.d.ts +1 -0
- package/dist/agents/historian.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/prompts.d.ts.map +1 -1
- package/dist/cli.js +362 -83
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +103 -2
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config/variable.d.ts +46 -0
- package/dist/config/variable.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-storage.d.ts +27 -1
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/compression-depth-storage.d.ts +7 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-probe.d.ts +69 -0
- package/dist/features/magic-context/memory/embedding-probe.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman.d.ts +35 -0
- package/dist/hooks/magic-context/caveman.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +23 -1
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +8 -3
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +46 -0
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +10 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +9 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +5 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +31 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +9 -4
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +11 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +13 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +7 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/temporal-awareness.d.ts +73 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +10 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +14 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2415 -1064
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/shared/model-requirements.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/model-requirements.ts +3 -1
- package/src/shared/models-dev-cache.ts +11 -1
package/dist/cli.js
CHANGED
|
@@ -7851,16 +7851,183 @@ var require_src3 = __commonJS((exports, module) => {
|
|
|
7851
7851
|
// src/cli/doctor.ts
|
|
7852
7852
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
7853
7853
|
import { execSync as execSync2, spawnSync } from "node:child_process";
|
|
7854
|
-
import { existsSync as
|
|
7854
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync6, rmSync, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
7855
7855
|
import { createRequire as createRequire3 } from "node:module";
|
|
7856
|
-
import { homedir as
|
|
7856
|
+
import { homedir as homedir6, platform, tmpdir as tmpdir3 } from "node:os";
|
|
7857
7857
|
import { join as join9 } from "node:path";
|
|
7858
7858
|
|
|
7859
|
+
// src/config/variable.ts
|
|
7860
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7861
|
+
import { homedir } from "node:os";
|
|
7862
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
7863
|
+
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
7864
|
+
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
7865
|
+
function substituteConfigVariables(input) {
|
|
7866
|
+
const warnings = [];
|
|
7867
|
+
let text = input.text;
|
|
7868
|
+
text = text.replace(ENV_PATTERN, (_, rawName) => {
|
|
7869
|
+
const varName = rawName.trim();
|
|
7870
|
+
const value = varName ? process.env[varName] : undefined;
|
|
7871
|
+
if (value === undefined || value === "") {
|
|
7872
|
+
warnings.push(`Environment variable ${varName} is not set (referenced via {env:${varName}}); using empty string`);
|
|
7873
|
+
return "";
|
|
7874
|
+
}
|
|
7875
|
+
return value;
|
|
7876
|
+
});
|
|
7877
|
+
const fileMatches = Array.from(text.matchAll(FILE_PATTERN));
|
|
7878
|
+
if (fileMatches.length === 0) {
|
|
7879
|
+
return { text, warnings };
|
|
7880
|
+
}
|
|
7881
|
+
const configDir = input.configPath ? dirname(input.configPath) : process.cwd();
|
|
7882
|
+
let output = "";
|
|
7883
|
+
let cursor = 0;
|
|
7884
|
+
for (const match of fileMatches) {
|
|
7885
|
+
const token = match[0];
|
|
7886
|
+
const rawPath = match[1] ?? "";
|
|
7887
|
+
const index = match.index ?? 0;
|
|
7888
|
+
output += text.slice(cursor, index);
|
|
7889
|
+
cursor = index + token.length;
|
|
7890
|
+
const lineStart = text.lastIndexOf(`
|
|
7891
|
+
`, index - 1) + 1;
|
|
7892
|
+
const prefix = text.slice(lineStart, index).trimStart();
|
|
7893
|
+
if (prefix.startsWith("//")) {
|
|
7894
|
+
output += token;
|
|
7895
|
+
continue;
|
|
7896
|
+
}
|
|
7897
|
+
let filePath = rawPath.trim();
|
|
7898
|
+
if (filePath.startsWith("~/")) {
|
|
7899
|
+
filePath = resolve(homedir(), filePath.slice(2));
|
|
7900
|
+
} else if (!isAbsolute(filePath)) {
|
|
7901
|
+
filePath = resolve(configDir, filePath);
|
|
7902
|
+
}
|
|
7903
|
+
if (!existsSync(filePath)) {
|
|
7904
|
+
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
7905
|
+
continue;
|
|
7906
|
+
}
|
|
7907
|
+
let contents;
|
|
7908
|
+
try {
|
|
7909
|
+
contents = readFileSync(filePath, "utf-8").trim();
|
|
7910
|
+
} catch (error) {
|
|
7911
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7912
|
+
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
7913
|
+
continue;
|
|
7914
|
+
}
|
|
7915
|
+
output += JSON.stringify(contents).slice(1, -1);
|
|
7916
|
+
}
|
|
7917
|
+
output += text.slice(cursor);
|
|
7918
|
+
return { text: output, warnings };
|
|
7919
|
+
}
|
|
7920
|
+
|
|
7921
|
+
// src/features/magic-context/memory/embedding-probe.ts
|
|
7922
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
7923
|
+
var MAX_PREVIEW_CHARS = 240;
|
|
7924
|
+
async function probeEmbeddingEndpoint(options) {
|
|
7925
|
+
const endpoint = options.endpoint.trim().replace(/\/+$/, "");
|
|
7926
|
+
if (!endpoint) {
|
|
7927
|
+
return { kind: "invalid_scheme", endpoint: options.endpoint };
|
|
7928
|
+
}
|
|
7929
|
+
if (!endpoint.startsWith("https://") && !endpoint.startsWith("http://")) {
|
|
7930
|
+
return { kind: "invalid_scheme", endpoint: options.endpoint };
|
|
7931
|
+
}
|
|
7932
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
7933
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
7934
|
+
const url = `${endpoint}/embeddings`;
|
|
7935
|
+
const apiKey = options.apiKey?.trim();
|
|
7936
|
+
const headers = { "content-type": "application/json" };
|
|
7937
|
+
if (apiKey) {
|
|
7938
|
+
headers.authorization = `Bearer ${apiKey}`;
|
|
7939
|
+
}
|
|
7940
|
+
const body = JSON.stringify({ model: options.model, input: "magic-context probe" });
|
|
7941
|
+
let response;
|
|
7942
|
+
try {
|
|
7943
|
+
response = await fetchImpl(url, {
|
|
7944
|
+
method: "POST",
|
|
7945
|
+
headers,
|
|
7946
|
+
body,
|
|
7947
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
7948
|
+
});
|
|
7949
|
+
} catch (error) {
|
|
7950
|
+
if (error instanceof Error && error.name === "TimeoutError") {
|
|
7951
|
+
return { kind: "timeout", timeoutMs };
|
|
7952
|
+
}
|
|
7953
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
7954
|
+
return { kind: "timeout", timeoutMs };
|
|
7955
|
+
}
|
|
7956
|
+
return {
|
|
7957
|
+
kind: "network_error",
|
|
7958
|
+
message: error instanceof Error ? error.message : String(error)
|
|
7959
|
+
};
|
|
7960
|
+
}
|
|
7961
|
+
const status = response.status;
|
|
7962
|
+
if (response.ok) {
|
|
7963
|
+
let parsed = null;
|
|
7964
|
+
try {
|
|
7965
|
+
parsed = await response.json();
|
|
7966
|
+
} catch {
|
|
7967
|
+
return { kind: "endpoint_unsupported", status, preview: "" };
|
|
7968
|
+
}
|
|
7969
|
+
const dimensions = extractDimensions(parsed);
|
|
7970
|
+
if (dimensions === null) {
|
|
7971
|
+
return {
|
|
7972
|
+
kind: "endpoint_unsupported",
|
|
7973
|
+
status,
|
|
7974
|
+
preview: await readPreview(parsed)
|
|
7975
|
+
};
|
|
7976
|
+
}
|
|
7977
|
+
return { kind: "ok", status, dimensions };
|
|
7978
|
+
}
|
|
7979
|
+
const preview = await previewErrorBody(response);
|
|
7980
|
+
if (status === 401 || status === 403) {
|
|
7981
|
+
return { kind: "auth_failed", status, preview };
|
|
7982
|
+
}
|
|
7983
|
+
if (status === 404 || status === 405) {
|
|
7984
|
+
return { kind: "endpoint_unsupported", status, preview };
|
|
7985
|
+
}
|
|
7986
|
+
return { kind: "http_error", status, preview };
|
|
7987
|
+
}
|
|
7988
|
+
function extractDimensions(body) {
|
|
7989
|
+
if (!body || typeof body !== "object")
|
|
7990
|
+
return null;
|
|
7991
|
+
const data = body.data;
|
|
7992
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
7993
|
+
return null;
|
|
7994
|
+
const first = data[0];
|
|
7995
|
+
if (!first || typeof first !== "object")
|
|
7996
|
+
return null;
|
|
7997
|
+
const embedding = first.embedding;
|
|
7998
|
+
if (!Array.isArray(embedding) || embedding.length === 0)
|
|
7999
|
+
return null;
|
|
8000
|
+
const sample = embedding[0];
|
|
8001
|
+
if (typeof sample !== "number" || !Number.isFinite(sample))
|
|
8002
|
+
return null;
|
|
8003
|
+
return embedding.length;
|
|
8004
|
+
}
|
|
8005
|
+
async function previewErrorBody(response) {
|
|
8006
|
+
try {
|
|
8007
|
+
const text = await response.text();
|
|
8008
|
+
return truncate(text);
|
|
8009
|
+
} catch {
|
|
8010
|
+
return "";
|
|
8011
|
+
}
|
|
8012
|
+
}
|
|
8013
|
+
async function readPreview(parsed) {
|
|
8014
|
+
try {
|
|
8015
|
+
return truncate(JSON.stringify(parsed));
|
|
8016
|
+
} catch {
|
|
8017
|
+
return "";
|
|
8018
|
+
}
|
|
8019
|
+
}
|
|
8020
|
+
function truncate(text) {
|
|
8021
|
+
if (text.length <= MAX_PREVIEW_CHARS)
|
|
8022
|
+
return text;
|
|
8023
|
+
return `${text.slice(0, MAX_PREVIEW_CHARS)}…`;
|
|
8024
|
+
}
|
|
8025
|
+
|
|
7859
8026
|
// src/shared/conflict-detector.ts
|
|
7860
8027
|
import { join as join2 } from "node:path";
|
|
7861
8028
|
|
|
7862
8029
|
// src/shared/jsonc-parser.ts
|
|
7863
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
8030
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
7864
8031
|
function stripJsonComments(content) {
|
|
7865
8032
|
let result = "";
|
|
7866
8033
|
let inString = false;
|
|
@@ -7957,24 +8124,24 @@ function parseJsonc(content) {
|
|
|
7957
8124
|
}
|
|
7958
8125
|
function readJsoncFile(filePath) {
|
|
7959
8126
|
try {
|
|
7960
|
-
return parseJsonc(
|
|
8127
|
+
return parseJsonc(readFileSync2(filePath, "utf-8"));
|
|
7961
8128
|
} catch (_error) {
|
|
7962
8129
|
return null;
|
|
7963
8130
|
}
|
|
7964
8131
|
}
|
|
7965
8132
|
|
|
7966
8133
|
// src/shared/opencode-config-dir.ts
|
|
7967
|
-
import { homedir } from "node:os";
|
|
7968
|
-
import { join, resolve } from "node:path";
|
|
8134
|
+
import { homedir as homedir2 } from "node:os";
|
|
8135
|
+
import { join, resolve as resolve2 } from "node:path";
|
|
7969
8136
|
function getCliConfigDir() {
|
|
7970
8137
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
7971
8138
|
if (envConfigDir) {
|
|
7972
|
-
return
|
|
8139
|
+
return resolve2(envConfigDir);
|
|
7973
8140
|
}
|
|
7974
8141
|
if (process.platform === "win32") {
|
|
7975
|
-
return join(
|
|
8142
|
+
return join(homedir2(), ".config", "opencode");
|
|
7976
8143
|
}
|
|
7977
|
-
return join(process.env.XDG_CONFIG_HOME || join(
|
|
8144
|
+
return join(process.env.XDG_CONFIG_HOME || join(homedir2(), ".config"), "opencode");
|
|
7978
8145
|
}
|
|
7979
8146
|
function getOpenCodeConfigDir(_options) {
|
|
7980
8147
|
return getCliConfigDir();
|
|
@@ -8156,8 +8323,8 @@ function readOmoDisabledHooks(directory) {
|
|
|
8156
8323
|
}
|
|
8157
8324
|
|
|
8158
8325
|
// src/shared/conflict-fixer.ts
|
|
8159
|
-
import { existsSync as
|
|
8160
|
-
import { dirname, join as join3 } from "node:path";
|
|
8326
|
+
import { existsSync as existsSync3, mkdirSync, writeFileSync } from "node:fs";
|
|
8327
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
8161
8328
|
var CONFLICTING_OMO_HOOKS = [
|
|
8162
8329
|
"context-window-monitor",
|
|
8163
8330
|
"preemptive-compaction",
|
|
@@ -8170,7 +8337,7 @@ var OMO_CONFIG_NAMES = [
|
|
|
8170
8337
|
"oh-my-opencode.json"
|
|
8171
8338
|
];
|
|
8172
8339
|
function ensureParentDir(filePath) {
|
|
8173
|
-
mkdirSync(
|
|
8340
|
+
mkdirSync(dirname2(filePath), { recursive: true });
|
|
8174
8341
|
}
|
|
8175
8342
|
function isRecord(value) {
|
|
8176
8343
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8179,7 +8346,7 @@ function asStringArray(value) {
|
|
|
8179
8346
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
8180
8347
|
}
|
|
8181
8348
|
function readConfig(filePath) {
|
|
8182
|
-
if (!
|
|
8349
|
+
if (!existsSync3(filePath)) {
|
|
8183
8350
|
return {};
|
|
8184
8351
|
}
|
|
8185
8352
|
return readJsoncFile(filePath);
|
|
@@ -8191,7 +8358,7 @@ function writeConfig(filePath, config) {
|
|
|
8191
8358
|
}
|
|
8192
8359
|
function resolveUserOpenCodeConfigPath() {
|
|
8193
8360
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
8194
|
-
if (
|
|
8361
|
+
if (existsSync3(paths.configJsonc))
|
|
8195
8362
|
return paths.configJsonc;
|
|
8196
8363
|
return paths.configJson;
|
|
8197
8364
|
}
|
|
@@ -8205,7 +8372,7 @@ function collectOpenCodeConfigPaths(directory) {
|
|
|
8205
8372
|
join3(directory, "opencode.jsonc"),
|
|
8206
8373
|
join3(directory, "opencode.json")
|
|
8207
8374
|
]) {
|
|
8208
|
-
if (
|
|
8375
|
+
if (existsSync3(filePath)) {
|
|
8209
8376
|
paths.add(filePath);
|
|
8210
8377
|
}
|
|
8211
8378
|
}
|
|
@@ -8217,10 +8384,10 @@ function collectOmoConfigPaths(directory) {
|
|
|
8217
8384
|
for (const fileName of OMO_CONFIG_NAMES) {
|
|
8218
8385
|
const userPath = join3(configDir, fileName);
|
|
8219
8386
|
const projectPath = join3(directory, fileName);
|
|
8220
|
-
if (
|
|
8387
|
+
if (existsSync3(userPath)) {
|
|
8221
8388
|
paths.add(userPath);
|
|
8222
8389
|
}
|
|
8223
|
-
if (
|
|
8390
|
+
if (existsSync3(projectPath)) {
|
|
8224
8391
|
paths.add(projectPath);
|
|
8225
8392
|
}
|
|
8226
8393
|
}
|
|
@@ -8317,8 +8484,8 @@ function fixConflicts(directory, conflicts) {
|
|
|
8317
8484
|
|
|
8318
8485
|
// src/shared/tui-config.ts
|
|
8319
8486
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
8320
|
-
import { existsSync as
|
|
8321
|
-
import { dirname as
|
|
8487
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8488
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
8322
8489
|
|
|
8323
8490
|
// src/shared/logger.ts
|
|
8324
8491
|
import * as fs from "node:fs";
|
|
@@ -8378,9 +8545,9 @@ function resolveTuiConfigPath() {
|
|
|
8378
8545
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
8379
8546
|
const jsoncPath = join5(configDir, "tui.jsonc");
|
|
8380
8547
|
const jsonPath = join5(configDir, "tui.json");
|
|
8381
|
-
if (
|
|
8548
|
+
if (existsSync4(jsoncPath))
|
|
8382
8549
|
return jsoncPath;
|
|
8383
|
-
if (
|
|
8550
|
+
if (existsSync4(jsonPath))
|
|
8384
8551
|
return jsonPath;
|
|
8385
8552
|
return jsonPath;
|
|
8386
8553
|
}
|
|
@@ -8388,8 +8555,8 @@ function ensureTuiPluginEntry() {
|
|
|
8388
8555
|
try {
|
|
8389
8556
|
const configPath = resolveTuiConfigPath();
|
|
8390
8557
|
let config = {};
|
|
8391
|
-
if (
|
|
8392
|
-
const raw =
|
|
8558
|
+
if (existsSync4(configPath)) {
|
|
8559
|
+
const raw = readFileSync3(configPath, "utf-8");
|
|
8393
8560
|
config = import_comment_json.parse(raw) ?? {};
|
|
8394
8561
|
}
|
|
8395
8562
|
const plugins = Array.isArray(config.plugin) ? config.plugin.filter((p) => typeof p === "string") : [];
|
|
@@ -8408,7 +8575,7 @@ function ensureTuiPluginEntry() {
|
|
|
8408
8575
|
plugins.push(PLUGIN_ENTRY);
|
|
8409
8576
|
}
|
|
8410
8577
|
config.plugin = plugins;
|
|
8411
|
-
mkdirSync2(
|
|
8578
|
+
mkdirSync2(dirname3(configPath), { recursive: true });
|
|
8412
8579
|
writeFileSync2(configPath, `${import_comment_json.stringify(config, null, 2)}
|
|
8413
8580
|
`);
|
|
8414
8581
|
log(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
@@ -8420,17 +8587,17 @@ function ensureTuiPluginEntry() {
|
|
|
8420
8587
|
}
|
|
8421
8588
|
|
|
8422
8589
|
// src/cli/config-paths.ts
|
|
8423
|
-
import { existsSync as
|
|
8424
|
-
import { homedir as
|
|
8590
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
8591
|
+
import { homedir as homedir3 } from "node:os";
|
|
8425
8592
|
import { join as join6 } from "node:path";
|
|
8426
8593
|
function getConfigDir() {
|
|
8427
8594
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
8428
8595
|
if (envDir)
|
|
8429
8596
|
return envDir;
|
|
8430
8597
|
if (process.platform === "win32") {
|
|
8431
|
-
return join6(
|
|
8598
|
+
return join6(homedir3(), ".config", "opencode");
|
|
8432
8599
|
}
|
|
8433
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME || join6(
|
|
8600
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join6(homedir3(), ".config");
|
|
8434
8601
|
return join6(xdgConfig, "opencode");
|
|
8435
8602
|
}
|
|
8436
8603
|
function findOmoConfig(configDir) {
|
|
@@ -8441,7 +8608,7 @@ function findOmoConfig(configDir) {
|
|
|
8441
8608
|
join6(configDir, "oh-my-opencode.json")
|
|
8442
8609
|
];
|
|
8443
8610
|
for (const loc of locations) {
|
|
8444
|
-
if (
|
|
8611
|
+
if (existsSync5(loc))
|
|
8445
8612
|
return loc;
|
|
8446
8613
|
}
|
|
8447
8614
|
return null;
|
|
@@ -8454,10 +8621,10 @@ function detectConfigPaths() {
|
|
|
8454
8621
|
let tuiConfigFormat;
|
|
8455
8622
|
const jsoncPath = join6(configDir, "opencode.jsonc");
|
|
8456
8623
|
const jsonPath = join6(configDir, "opencode.json");
|
|
8457
|
-
if (
|
|
8624
|
+
if (existsSync5(jsoncPath)) {
|
|
8458
8625
|
opencodeConfig = jsoncPath;
|
|
8459
8626
|
opencodeConfigFormat = "jsonc";
|
|
8460
|
-
} else if (
|
|
8627
|
+
} else if (existsSync5(jsonPath)) {
|
|
8461
8628
|
opencodeConfig = jsonPath;
|
|
8462
8629
|
opencodeConfigFormat = "json";
|
|
8463
8630
|
} else {
|
|
@@ -8466,10 +8633,10 @@ function detectConfigPaths() {
|
|
|
8466
8633
|
}
|
|
8467
8634
|
const tuiJsoncPath = join6(configDir, "tui.jsonc");
|
|
8468
8635
|
const tuiJsonPath = join6(configDir, "tui.json");
|
|
8469
|
-
if (
|
|
8636
|
+
if (existsSync5(tuiJsoncPath)) {
|
|
8470
8637
|
tuiConfig = tuiJsoncPath;
|
|
8471
8638
|
tuiConfigFormat = "jsonc";
|
|
8472
|
-
} else if (
|
|
8639
|
+
} else if (existsSync5(tuiJsonPath)) {
|
|
8473
8640
|
tuiConfig = tuiJsonPath;
|
|
8474
8641
|
tuiConfigFormat = "json";
|
|
8475
8642
|
} else {
|
|
@@ -8489,9 +8656,9 @@ function detectConfigPaths() {
|
|
|
8489
8656
|
|
|
8490
8657
|
// src/cli/diagnostics.ts
|
|
8491
8658
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
8492
|
-
import { existsSync as
|
|
8659
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync4, statSync } from "node:fs";
|
|
8493
8660
|
import { createRequire as createRequire2 } from "node:module";
|
|
8494
|
-
import { homedir as
|
|
8661
|
+
import { homedir as homedir4, tmpdir as tmpdir2, userInfo } from "node:os";
|
|
8495
8662
|
import { join as join7 } from "node:path";
|
|
8496
8663
|
|
|
8497
8664
|
// src/cli/opencode-helpers.ts
|
|
@@ -8590,18 +8757,18 @@ function getOpenCodeCacheDir() {
|
|
|
8590
8757
|
if (xdgCache)
|
|
8591
8758
|
return join7(xdgCache, "opencode");
|
|
8592
8759
|
if (process.platform === "win32") {
|
|
8593
|
-
const localAppData = process.env.LOCALAPPDATA ?? join7(
|
|
8760
|
+
const localAppData = process.env.LOCALAPPDATA ?? join7(homedir4(), "AppData", "Local");
|
|
8594
8761
|
return join7(localAppData, "opencode");
|
|
8595
8762
|
}
|
|
8596
|
-
return join7(
|
|
8763
|
+
return join7(homedir4(), ".cache", "opencode");
|
|
8597
8764
|
}
|
|
8598
8765
|
function getPluginCacheInfo() {
|
|
8599
8766
|
const path2 = join7(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
|
|
8600
8767
|
let cached;
|
|
8601
8768
|
try {
|
|
8602
8769
|
const installedPkgPath = join7(path2, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
8603
|
-
if (
|
|
8604
|
-
const pkg = JSON.parse(
|
|
8770
|
+
if (existsSync6(installedPkgPath)) {
|
|
8771
|
+
const pkg = JSON.parse(readFileSync4(installedPkgPath, "utf-8"));
|
|
8605
8772
|
cached = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
8606
8773
|
}
|
|
8607
8774
|
} catch {
|
|
@@ -8610,12 +8777,12 @@ function getPluginCacheInfo() {
|
|
|
8610
8777
|
return { path: path2, cached, latest: getSelfVersion() };
|
|
8611
8778
|
}
|
|
8612
8779
|
function getStorageDir() {
|
|
8613
|
-
const dataHome = process.env.XDG_DATA_HOME || join7(
|
|
8780
|
+
const dataHome = process.env.XDG_DATA_HOME || join7(homedir4(), ".local", "share");
|
|
8614
8781
|
return join7(dataHome, "opencode", "storage", "plugin", "magic-context");
|
|
8615
8782
|
}
|
|
8616
8783
|
function fileSize(path2) {
|
|
8617
8784
|
try {
|
|
8618
|
-
return
|
|
8785
|
+
return existsSync6(path2) ? statSync(path2).size : 0;
|
|
8619
8786
|
} catch {
|
|
8620
8787
|
return 0;
|
|
8621
8788
|
}
|
|
@@ -8624,7 +8791,7 @@ function escapeRegex(value) {
|
|
|
8624
8791
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8625
8792
|
}
|
|
8626
8793
|
function sanitizeString(value) {
|
|
8627
|
-
const home =
|
|
8794
|
+
const home = homedir4();
|
|
8628
8795
|
const username = userInfo().username;
|
|
8629
8796
|
let sanitized = value;
|
|
8630
8797
|
if (home) {
|
|
@@ -8649,10 +8816,10 @@ function sanitizeValue(value) {
|
|
|
8649
8816
|
return value;
|
|
8650
8817
|
}
|
|
8651
8818
|
function readConfig2(path2) {
|
|
8652
|
-
if (!
|
|
8819
|
+
if (!existsSync6(path2))
|
|
8653
8820
|
return { value: null };
|
|
8654
8821
|
try {
|
|
8655
|
-
const raw =
|
|
8822
|
+
const raw = readFileSync4(path2, "utf-8");
|
|
8656
8823
|
const value = import_comment_json2.parse(raw);
|
|
8657
8824
|
return { value };
|
|
8658
8825
|
} catch (error) {
|
|
@@ -8675,7 +8842,7 @@ function configHasPluginEntry(config) {
|
|
|
8675
8842
|
}
|
|
8676
8843
|
function collectHistorianDumps() {
|
|
8677
8844
|
const dir = join7(tmpdir2(), "magic-context-historian");
|
|
8678
|
-
if (!
|
|
8845
|
+
if (!existsSync6(dir)) {
|
|
8679
8846
|
return { dir, count: 0, recent: [] };
|
|
8680
8847
|
}
|
|
8681
8848
|
try {
|
|
@@ -8707,7 +8874,7 @@ async function collectDiagnostics() {
|
|
|
8707
8874
|
const storageDirPath = getStorageDir();
|
|
8708
8875
|
const contextDbPath = join7(storageDirPath, "context.db");
|
|
8709
8876
|
const logPath = join7(tmpdir2(), "magic-context.log");
|
|
8710
|
-
const logFileSize =
|
|
8877
|
+
const logFileSize = existsSync6(logPath) ? statSync(logPath).size : 0;
|
|
8711
8878
|
const conflictResult = detectConflicts(process.cwd());
|
|
8712
8879
|
return {
|
|
8713
8880
|
timestamp: new Date().toISOString(),
|
|
@@ -8721,14 +8888,14 @@ async function collectDiagnostics() {
|
|
|
8721
8888
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
8722
8889
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
8723
8890
|
magicContextConfig: {
|
|
8724
|
-
exists:
|
|
8891
|
+
exists: existsSync6(configPaths.magicContextConfig),
|
|
8725
8892
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
8726
8893
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
8727
8894
|
},
|
|
8728
8895
|
pluginCache: getPluginCacheInfo(),
|
|
8729
8896
|
storageDir: {
|
|
8730
8897
|
path: storageDirPath,
|
|
8731
|
-
exists:
|
|
8898
|
+
exists: existsSync6(storageDirPath),
|
|
8732
8899
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
8733
8900
|
},
|
|
8734
8901
|
conflicts: {
|
|
@@ -8737,7 +8904,7 @@ async function collectDiagnostics() {
|
|
|
8737
8904
|
},
|
|
8738
8905
|
logFile: {
|
|
8739
8906
|
path: logPath,
|
|
8740
|
-
exists:
|
|
8907
|
+
exists: existsSync6(logPath),
|
|
8741
8908
|
sizeKb: Math.round(logFileSize / 1024)
|
|
8742
8909
|
},
|
|
8743
8910
|
historianDumps: collectHistorianDumps()
|
|
@@ -8822,14 +8989,14 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
8822
8989
|
}
|
|
8823
8990
|
|
|
8824
8991
|
// src/cli/logs.ts
|
|
8825
|
-
import { readFileSync as
|
|
8826
|
-
import { homedir as
|
|
8992
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
8993
|
+
import { homedir as homedir5, userInfo as userInfo2 } from "node:os";
|
|
8827
8994
|
import { join as join8 } from "node:path";
|
|
8828
8995
|
function escapeRegex2(value) {
|
|
8829
8996
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8830
8997
|
}
|
|
8831
8998
|
function sanitizeLogContent(content) {
|
|
8832
|
-
const home =
|
|
8999
|
+
const home = homedir5();
|
|
8833
9000
|
const username = userInfo2().username;
|
|
8834
9001
|
let sanitized = content;
|
|
8835
9002
|
if (home) {
|
|
@@ -8857,11 +9024,11 @@ function formatTimestamp(date) {
|
|
|
8857
9024
|
}
|
|
8858
9025
|
async function bundleIssueReport(report, description, _title) {
|
|
8859
9026
|
const LOG_TAIL_LINES = 200;
|
|
8860
|
-
const logLines = report.logFile.exists ?
|
|
9027
|
+
const logLines = report.logFile.exists ? readFileSync5(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
8861
9028
|
const recentLog = sanitizeLogContent(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
8862
9029
|
`)).trim();
|
|
8863
9030
|
const configBody = JSON.stringify(report.magicContextConfig.flags, null, 2);
|
|
8864
|
-
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(
|
|
9031
|
+
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(homedir5(), "~");
|
|
8865
9032
|
const bodyMarkdown = [
|
|
8866
9033
|
"## Description",
|
|
8867
9034
|
description,
|
|
@@ -10011,22 +10178,22 @@ function getOpenCodeCacheDir2() {
|
|
|
10011
10178
|
return join9(xdgCache, "opencode");
|
|
10012
10179
|
const os2 = platform();
|
|
10013
10180
|
if (os2 === "win32") {
|
|
10014
|
-
const localAppData = process.env.LOCALAPPDATA ?? join9(
|
|
10181
|
+
const localAppData = process.env.LOCALAPPDATA ?? join9(homedir6(), "AppData", "Local");
|
|
10015
10182
|
return join9(localAppData, "opencode");
|
|
10016
10183
|
}
|
|
10017
|
-
return join9(
|
|
10184
|
+
return join9(homedir6(), ".cache", "opencode");
|
|
10018
10185
|
}
|
|
10019
10186
|
async function clearPluginCache(force = false) {
|
|
10020
10187
|
const cacheDir = getOpenCodeCacheDir2();
|
|
10021
10188
|
const pluginCacheDir = join9(cacheDir, "packages", PLUGIN_ENTRY_WITH_VERSION2);
|
|
10022
|
-
if (!
|
|
10189
|
+
if (!existsSync7(pluginCacheDir)) {
|
|
10023
10190
|
return { action: "not_found", path: pluginCacheDir };
|
|
10024
10191
|
}
|
|
10025
10192
|
let cachedVersion;
|
|
10026
10193
|
try {
|
|
10027
10194
|
const installedPkgPath = join9(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
10028
|
-
if (
|
|
10029
|
-
const pkg = JSON.parse(
|
|
10195
|
+
if (existsSync7(installedPkgPath)) {
|
|
10196
|
+
const pkg = JSON.parse(readFileSync6(installedPkgPath, "utf-8"));
|
|
10030
10197
|
if (typeof pkg?.version === "string") {
|
|
10031
10198
|
cachedVersion = pkg.version;
|
|
10032
10199
|
}
|
|
@@ -10137,6 +10304,116 @@ async function runIssueFlow() {
|
|
|
10137
10304
|
return 1;
|
|
10138
10305
|
}
|
|
10139
10306
|
}
|
|
10307
|
+
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
10308
|
+
if (!existsSync7(magicContextConfigPath)) {
|
|
10309
|
+
return { issues: 0 };
|
|
10310
|
+
}
|
|
10311
|
+
let rawText;
|
|
10312
|
+
try {
|
|
10313
|
+
rawText = readFileSync6(magicContextConfigPath, "utf-8");
|
|
10314
|
+
} catch {
|
|
10315
|
+
R2.warn("Could not read magic-context.jsonc for embedding check");
|
|
10316
|
+
return { issues: 1 };
|
|
10317
|
+
}
|
|
10318
|
+
const substituted = substituteConfigVariables({
|
|
10319
|
+
text: rawText,
|
|
10320
|
+
configPath: magicContextConfigPath
|
|
10321
|
+
});
|
|
10322
|
+
let parsedConfig;
|
|
10323
|
+
try {
|
|
10324
|
+
parsedConfig = import_comment_json3.parse(substituted.text);
|
|
10325
|
+
} catch (error) {
|
|
10326
|
+
R2.warn(`Embedding check skipped — could not parse magic-context.jsonc: ${error instanceof Error ? error.message : String(error)}`);
|
|
10327
|
+
return { issues: 1 };
|
|
10328
|
+
}
|
|
10329
|
+
const embedding = parsedConfig?.embedding;
|
|
10330
|
+
const provider = embedding?.provider;
|
|
10331
|
+
if (provider === "off") {
|
|
10332
|
+
R2.info("Embedding provider disabled — semantic memory search is off");
|
|
10333
|
+
return { issues: 0 };
|
|
10334
|
+
}
|
|
10335
|
+
if (provider === undefined || provider === "local") {
|
|
10336
|
+
R2.success("Embedding provider: local (Xenova/all-MiniLM-L6-v2 bundled)");
|
|
10337
|
+
return { issues: 0 };
|
|
10338
|
+
}
|
|
10339
|
+
if (provider !== "openai-compatible") {
|
|
10340
|
+
R2.warn(`Unknown embedding provider: ${String(provider)} (expected local | openai-compatible | off)`);
|
|
10341
|
+
return { issues: 1 };
|
|
10342
|
+
}
|
|
10343
|
+
const endpoint = typeof embedding?.endpoint === "string" ? embedding.endpoint.trim() : "";
|
|
10344
|
+
const model = typeof embedding?.model === "string" ? embedding.model.trim() : "";
|
|
10345
|
+
const apiKey = typeof embedding?.api_key === "string" ? embedding.api_key : undefined;
|
|
10346
|
+
let localIssues = 0;
|
|
10347
|
+
if (!endpoint) {
|
|
10348
|
+
R2.error("Embedding provider is openai-compatible but 'endpoint' is missing");
|
|
10349
|
+
return { issues: 1 };
|
|
10350
|
+
}
|
|
10351
|
+
if (!model) {
|
|
10352
|
+
R2.error("Embedding provider is openai-compatible but 'model' is missing");
|
|
10353
|
+
return { issues: 1 };
|
|
10354
|
+
}
|
|
10355
|
+
if (apiKey && /\{env:[^}]+\}/.test(apiKey)) {
|
|
10356
|
+
R2.warn("api_key still contains {env:...} after substitution — the referenced environment variable is not set in this shell");
|
|
10357
|
+
R2.info(` Raw value: ${apiKey}`);
|
|
10358
|
+
R2.info(" Export the variable before launching OpenCode (e.g. in ~/.zshrc, ~/.bashrc, or a shell profile)");
|
|
10359
|
+
localIssues++;
|
|
10360
|
+
}
|
|
10361
|
+
if (substituted.warnings.length > 0) {
|
|
10362
|
+
for (const w of substituted.warnings.slice(0, 3)) {
|
|
10363
|
+
R2.info(` ${w}`);
|
|
10364
|
+
}
|
|
10365
|
+
if (substituted.warnings.length > 3) {
|
|
10366
|
+
R2.info(` ... and ${substituted.warnings.length - 3} more`);
|
|
10367
|
+
}
|
|
10368
|
+
}
|
|
10369
|
+
const probeSpinner = be();
|
|
10370
|
+
probeSpinner.start(`Testing embedding endpoint ${endpoint} (model: ${model})`);
|
|
10371
|
+
let outcome;
|
|
10372
|
+
try {
|
|
10373
|
+
outcome = await probeEmbeddingEndpoint({
|
|
10374
|
+
endpoint,
|
|
10375
|
+
model,
|
|
10376
|
+
apiKey,
|
|
10377
|
+
timeoutMs: 1e4
|
|
10378
|
+
});
|
|
10379
|
+
} catch (error) {
|
|
10380
|
+
probeSpinner.stop("Embedding probe failed unexpectedly");
|
|
10381
|
+
R2.error(`Probe threw: ${error instanceof Error ? error.message : String(error)}`);
|
|
10382
|
+
return { issues: localIssues + 1 };
|
|
10383
|
+
}
|
|
10384
|
+
probeSpinner.stop("Embedding endpoint probed");
|
|
10385
|
+
switch (outcome.kind) {
|
|
10386
|
+
case "ok":
|
|
10387
|
+
R2.success(`Embedding endpoint OK (${outcome.status}, ${outcome.dimensions ?? "?"}-dim vectors)`);
|
|
10388
|
+
return { issues: localIssues };
|
|
10389
|
+
case "auth_failed":
|
|
10390
|
+
R2.error(`Embedding endpoint rejected credentials (${outcome.status}) — check api_key / env var`);
|
|
10391
|
+
if (outcome.preview)
|
|
10392
|
+
R2.info(` ${outcome.preview}`);
|
|
10393
|
+
return { issues: localIssues + 1 };
|
|
10394
|
+
case "endpoint_unsupported":
|
|
10395
|
+
R2.error(`Embedding endpoint does not support embeddings (${outcome.status})`);
|
|
10396
|
+
if (outcome.preview)
|
|
10397
|
+
R2.info(` ${outcome.preview}`);
|
|
10398
|
+
R2.info(" Common causes: endpoint points at a chat-completion route (should be the provider base, e.g. '.../v1'), or the provider doesn't offer an embeddings API");
|
|
10399
|
+
R2.info(" Known non-embedding providers: OpenRouter (chat proxy), Anthropic (no embeddings endpoint). Use OpenAI, Voyage, Together, or a local provider instead.");
|
|
10400
|
+
return { issues: localIssues + 1 };
|
|
10401
|
+
case "http_error":
|
|
10402
|
+
R2.error(`Embedding endpoint returned ${outcome.status}`);
|
|
10403
|
+
if (outcome.preview)
|
|
10404
|
+
R2.info(` ${outcome.preview}`);
|
|
10405
|
+
return { issues: localIssues + 1 };
|
|
10406
|
+
case "timeout":
|
|
10407
|
+
R2.warn(`Embedding endpoint did not respond within ${outcome.timeoutMs}ms — check endpoint URL and network`);
|
|
10408
|
+
return { issues: localIssues + 1 };
|
|
10409
|
+
case "network_error":
|
|
10410
|
+
R2.error(`Could not reach embedding endpoint: ${outcome.message}`);
|
|
10411
|
+
return { issues: localIssues + 1 };
|
|
10412
|
+
case "invalid_scheme":
|
|
10413
|
+
R2.error(`Embedding endpoint must start with http:// or https://: ${outcome.endpoint}`);
|
|
10414
|
+
return { issues: localIssues + 1 };
|
|
10415
|
+
}
|
|
10416
|
+
}
|
|
10140
10417
|
async function runDoctor(options = {}) {
|
|
10141
10418
|
if (options.issue) {
|
|
10142
10419
|
return runIssueFlow();
|
|
@@ -10157,15 +10434,15 @@ async function runDoctor(options = {}) {
|
|
|
10157
10434
|
} else {
|
|
10158
10435
|
R2.success(`OpenCode config: ${paths.opencodeConfig}`);
|
|
10159
10436
|
}
|
|
10160
|
-
if (
|
|
10437
|
+
if (existsSync7(paths.magicContextConfig)) {
|
|
10161
10438
|
R2.success(`Magic Context config: ${paths.magicContextConfig}`);
|
|
10162
10439
|
} else {
|
|
10163
10440
|
R2.warn(`No magic-context.jsonc found — using defaults`);
|
|
10164
10441
|
R2.info(" Run 'setup' to create one with model recommendations");
|
|
10165
10442
|
}
|
|
10166
|
-
if (
|
|
10443
|
+
if (existsSync7(paths.magicContextConfig)) {
|
|
10167
10444
|
try {
|
|
10168
|
-
const mcRaw =
|
|
10445
|
+
const mcRaw = readFileSync6(paths.magicContextConfig, "utf-8");
|
|
10169
10446
|
const mcConfig = import_comment_json3.parse(mcRaw);
|
|
10170
10447
|
let mcChanged = false;
|
|
10171
10448
|
const experimental = mcConfig.experimental;
|
|
@@ -10194,7 +10471,7 @@ async function runDoctor(options = {}) {
|
|
|
10194
10471
|
}
|
|
10195
10472
|
if (paths.opencodeConfigFormat !== "none") {
|
|
10196
10473
|
try {
|
|
10197
|
-
const raw =
|
|
10474
|
+
const raw = readFileSync6(paths.opencodeConfig, "utf-8");
|
|
10198
10475
|
const config = import_comment_json3.parse(raw);
|
|
10199
10476
|
const plugins = Array.isArray(config?.plugin) ? config.plugin : [];
|
|
10200
10477
|
const pluginList = plugins.filter((p) => typeof p === "string");
|
|
@@ -10250,9 +10527,9 @@ async function runDoctor(options = {}) {
|
|
|
10250
10527
|
R2.success("Added TUI sidebar plugin to tui.json");
|
|
10251
10528
|
R2.warn("Restart OpenCode to see the sidebar");
|
|
10252
10529
|
fixed++;
|
|
10253
|
-
} else if (
|
|
10530
|
+
} else if (existsSync7(paths.tuiConfig)) {
|
|
10254
10531
|
try {
|
|
10255
|
-
const tuiRaw =
|
|
10532
|
+
const tuiRaw = readFileSync6(paths.tuiConfig, "utf-8");
|
|
10256
10533
|
const tuiConfig = import_comment_json3.parse(tuiRaw);
|
|
10257
10534
|
const tuiPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin.filter((p) => typeof p === "string") : [];
|
|
10258
10535
|
const tuiIdx = tuiPlugins.findIndex((p) => p === PLUGIN_NAME3 || p.startsWith(`${PLUGIN_NAME3}@`));
|
|
@@ -10280,9 +10557,9 @@ async function runDoctor(options = {}) {
|
|
|
10280
10557
|
} else {
|
|
10281
10558
|
R2.success("TUI sidebar plugin configured (tui.json created)");
|
|
10282
10559
|
}
|
|
10283
|
-
if (
|
|
10560
|
+
if (existsSync7(paths.magicContextConfig)) {
|
|
10284
10561
|
try {
|
|
10285
|
-
const mcRaw =
|
|
10562
|
+
const mcRaw = readFileSync6(paths.magicContextConfig, "utf-8");
|
|
10286
10563
|
const mcConfig = import_comment_json3.parse(mcRaw);
|
|
10287
10564
|
const userMemObj = mcConfig?.experimental?.user_memories;
|
|
10288
10565
|
const userMemEnabled = userMemObj?.enabled === true;
|
|
@@ -10294,6 +10571,8 @@ async function runDoctor(options = {}) {
|
|
|
10294
10571
|
}
|
|
10295
10572
|
} catch {}
|
|
10296
10573
|
}
|
|
10574
|
+
const embeddingCheck = await checkEmbeddingConfig(paths.magicContextConfig);
|
|
10575
|
+
issues += embeddingCheck.issues;
|
|
10297
10576
|
const cacheResult = await clearPluginCache(options.force);
|
|
10298
10577
|
if (cacheResult.action === "cleared") {
|
|
10299
10578
|
const versionInfo = cacheResult.cached ? ` (cached: ${cacheResult.cached}${cacheResult.latest ? `, latest: ${cacheResult.latest}` : ""})` : "";
|
|
@@ -10311,10 +10590,10 @@ async function runDoctor(options = {}) {
|
|
|
10311
10590
|
}
|
|
10312
10591
|
{
|
|
10313
10592
|
const ageWarnings = [];
|
|
10314
|
-
const npmrcPath = join9(
|
|
10315
|
-
if (
|
|
10593
|
+
const npmrcPath = join9(homedir6(), ".npmrc");
|
|
10594
|
+
if (existsSync7(npmrcPath)) {
|
|
10316
10595
|
try {
|
|
10317
|
-
const npmrc =
|
|
10596
|
+
const npmrc = readFileSync6(npmrcPath, "utf-8");
|
|
10318
10597
|
for (const line of npmrc.split(`
|
|
10319
10598
|
`)) {
|
|
10320
10599
|
const trimmed = line.trim();
|
|
@@ -10327,10 +10606,10 @@ async function runDoctor(options = {}) {
|
|
|
10327
10606
|
}
|
|
10328
10607
|
} catch {}
|
|
10329
10608
|
}
|
|
10330
|
-
const bunfigPath = join9(
|
|
10331
|
-
if (
|
|
10609
|
+
const bunfigPath = join9(homedir6(), ".bunfig.toml");
|
|
10610
|
+
if (existsSync7(bunfigPath)) {
|
|
10332
10611
|
try {
|
|
10333
|
-
const bunfig =
|
|
10612
|
+
const bunfig = readFileSync6(bunfigPath, "utf-8");
|
|
10334
10613
|
for (const line of bunfig.split(`
|
|
10335
10614
|
`)) {
|
|
10336
10615
|
const trimmed = line.trim();
|
|
@@ -10353,7 +10632,7 @@ async function runDoctor(options = {}) {
|
|
|
10353
10632
|
}
|
|
10354
10633
|
}
|
|
10355
10634
|
const logPath = join9(tmpdir3(), "magic-context.log");
|
|
10356
|
-
if (
|
|
10635
|
+
if (existsSync7(logPath)) {
|
|
10357
10636
|
const logStat = statSync2(logPath);
|
|
10358
10637
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
10359
10638
|
R2.info(`Log file: ${logPath} (${sizeKb} KB)`);
|
|
@@ -10361,7 +10640,7 @@ async function runDoctor(options = {}) {
|
|
|
10361
10640
|
R2.info(`Log file: ${logPath} (not yet created)`);
|
|
10362
10641
|
}
|
|
10363
10642
|
const historianDumpDir = join9(tmpdir3(), "magic-context-historian");
|
|
10364
|
-
if (
|
|
10643
|
+
if (existsSync7(historianDumpDir)) {
|
|
10365
10644
|
try {
|
|
10366
10645
|
const dumps = readdirSync2(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({
|
|
10367
10646
|
name: f,
|
|
@@ -10399,17 +10678,17 @@ async function runDoctor(options = {}) {
|
|
|
10399
10678
|
|
|
10400
10679
|
// src/cli/setup.ts
|
|
10401
10680
|
var import_comment_json4 = __toESM(require_src2(), 1);
|
|
10402
|
-
import { existsSync as
|
|
10403
|
-
import { dirname as
|
|
10681
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
10682
|
+
import { dirname as dirname4 } from "node:path";
|
|
10404
10683
|
var PLUGIN_NAME4 = "@cortexkit/opencode-magic-context";
|
|
10405
10684
|
var PLUGIN_ENTRY2 = "@cortexkit/opencode-magic-context@latest";
|
|
10406
10685
|
function ensureDir(dir) {
|
|
10407
|
-
if (!
|
|
10686
|
+
if (!existsSync8(dir)) {
|
|
10408
10687
|
mkdirSync3(dir, { recursive: true });
|
|
10409
10688
|
}
|
|
10410
10689
|
}
|
|
10411
10690
|
function readJsonc(path2) {
|
|
10412
|
-
const content =
|
|
10691
|
+
const content = readFileSync7(path2, "utf-8");
|
|
10413
10692
|
try {
|
|
10414
10693
|
return import_comment_json4.parse(content);
|
|
10415
10694
|
} catch (err) {
|
|
@@ -10418,7 +10697,7 @@ function readJsonc(path2) {
|
|
|
10418
10697
|
}
|
|
10419
10698
|
}
|
|
10420
10699
|
function addPluginToOpenCodeConfig(configPath, format) {
|
|
10421
|
-
ensureDir(
|
|
10700
|
+
ensureDir(dirname4(configPath));
|
|
10422
10701
|
if (format === "none") {
|
|
10423
10702
|
const config = {
|
|
10424
10703
|
plugin: [PLUGIN_ENTRY2],
|
|
@@ -10447,7 +10726,7 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
10447
10726
|
`);
|
|
10448
10727
|
}
|
|
10449
10728
|
function addPluginToTuiConfig(configPath, format) {
|
|
10450
|
-
ensureDir(
|
|
10729
|
+
ensureDir(dirname4(configPath));
|
|
10451
10730
|
if (format === "none") {
|
|
10452
10731
|
writeFileSync5(configPath, `${import_comment_json4.stringify({ plugin: [PLUGIN_ENTRY2] }, null, 2)}
|
|
10453
10732
|
`);
|
|
@@ -10468,7 +10747,7 @@ function addPluginToTuiConfig(configPath, format) {
|
|
|
10468
10747
|
`);
|
|
10469
10748
|
}
|
|
10470
10749
|
function writeMagicContextConfig(configPath, options) {
|
|
10471
|
-
const config = (
|
|
10750
|
+
const config = (existsSync8(configPath) ? readJsonc(configPath) : null) ?? {};
|
|
10472
10751
|
if (!config.$schema) {
|
|
10473
10752
|
config.$schema = "https://raw.githubusercontent.com/cortexkit/opencode-magic-context/master/assets/magic-context.schema.json";
|
|
10474
10753
|
}
|
|
@@ -10534,7 +10813,7 @@ async function runSetup() {
|
|
|
10534
10813
|
R2.warn("You can configure models manually in magic-context.jsonc later");
|
|
10535
10814
|
}
|
|
10536
10815
|
const paths = detectConfigPaths();
|
|
10537
|
-
const hadExistingSetup = paths.opencodeConfigFormat !== "none" ||
|
|
10816
|
+
const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync8(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
|
|
10538
10817
|
addPluginToOpenCodeConfig(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
10539
10818
|
R2.success(`Plugin added to ${paths.opencodeConfig}`);
|
|
10540
10819
|
R2.info("Disabled built-in compaction (auto=false, prune=false)");
|