@cortexkit/aft 0.34.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/version.d.ts +7 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +637 -315
- package/dist/lib/issue-body.d.ts +1 -0
- package/dist/lib/issue-body.d.ts.map +1 -1
- package/dist/lib/sessions.d.ts +18 -0
- package/dist/lib/sessions.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -46,11 +46,235 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __promiseAll = (args) => Promise.all(args);
|
|
48
48
|
|
|
49
|
-
// src/lib/
|
|
50
|
-
import {
|
|
49
|
+
// src/lib/paths.ts
|
|
50
|
+
import { homedir, tmpdir } from "node:os";
|
|
51
51
|
import { join } from "node:path";
|
|
52
|
+
function getAftBinaryCacheDir() {
|
|
53
|
+
if (process.env.AFT_CACHE_DIR) {
|
|
54
|
+
return join(process.env.AFT_CACHE_DIR, "bin");
|
|
55
|
+
}
|
|
56
|
+
if (process.platform === "win32") {
|
|
57
|
+
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
58
|
+
const base2 = localAppData || join(homedir(), "AppData", "Local");
|
|
59
|
+
return join(base2, "aft", "bin");
|
|
60
|
+
}
|
|
61
|
+
const base = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
|
|
62
|
+
return join(base, "aft", "bin");
|
|
63
|
+
}
|
|
64
|
+
function getAftBinaryName() {
|
|
65
|
+
return process.platform === "win32" ? "aft.exe" : "aft";
|
|
66
|
+
}
|
|
67
|
+
function getAftLspPackagesDir() {
|
|
68
|
+
if (process.env.AFT_CACHE_DIR) {
|
|
69
|
+
return join(process.env.AFT_CACHE_DIR, "lsp-packages");
|
|
70
|
+
}
|
|
71
|
+
if (process.platform === "win32") {
|
|
72
|
+
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
73
|
+
const base2 = localAppData || join(homedir(), "AppData", "Local");
|
|
74
|
+
return join(base2, "aft", "lsp-packages");
|
|
75
|
+
}
|
|
76
|
+
const base = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
|
|
77
|
+
return join(base, "aft", "lsp-packages");
|
|
78
|
+
}
|
|
79
|
+
function getAftLspBinariesDir() {
|
|
80
|
+
if (process.env.AFT_CACHE_DIR) {
|
|
81
|
+
return join(process.env.AFT_CACHE_DIR, "lsp-binaries");
|
|
82
|
+
}
|
|
83
|
+
if (process.platform === "win32") {
|
|
84
|
+
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
85
|
+
const base2 = localAppData || join(homedir(), "AppData", "Local");
|
|
86
|
+
return join(base2, "aft", "lsp-binaries");
|
|
87
|
+
}
|
|
88
|
+
const base = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
|
|
89
|
+
return join(base, "aft", "lsp-binaries");
|
|
90
|
+
}
|
|
91
|
+
function homeDir() {
|
|
92
|
+
if (process.platform === "win32")
|
|
93
|
+
return process.env.USERPROFILE || process.env.HOME || homedir();
|
|
94
|
+
return process.env.HOME || homedir();
|
|
95
|
+
}
|
|
96
|
+
function dataHome() {
|
|
97
|
+
if (process.env.XDG_DATA_HOME)
|
|
98
|
+
return process.env.XDG_DATA_HOME;
|
|
99
|
+
if (process.platform === "win32") {
|
|
100
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join(homeDir(), "AppData", "Local");
|
|
101
|
+
}
|
|
102
|
+
return join(homeDir(), ".local", "share");
|
|
103
|
+
}
|
|
104
|
+
function getCortexKitStorageRoot() {
|
|
105
|
+
return join(dataHome(), "cortexkit", "aft");
|
|
106
|
+
}
|
|
107
|
+
function getTmpLogPath(filename) {
|
|
108
|
+
return join(tmpdir(), filename);
|
|
109
|
+
}
|
|
110
|
+
var init_paths = () => {};
|
|
111
|
+
|
|
112
|
+
// src/lib/binary-probe.ts
|
|
113
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
114
|
+
import { existsSync } from "node:fs";
|
|
115
|
+
import { createRequire } from "node:module";
|
|
116
|
+
import { homedir as homedir2 } from "node:os";
|
|
117
|
+
import { join as join2 } from "node:path";
|
|
118
|
+
async function loadPluginVersion() {
|
|
119
|
+
try {
|
|
120
|
+
const bridgePackageName = "@cortexkit/aft-bridge";
|
|
121
|
+
const bridge = await import(bridgePackageName);
|
|
122
|
+
if (typeof bridge.PLUGIN_VERSION === "string" && bridge.PLUGIN_VERSION.length > 0) {
|
|
123
|
+
return bridge.PLUGIN_VERSION;
|
|
124
|
+
}
|
|
125
|
+
} catch {}
|
|
126
|
+
const require2 = createRequire(import.meta.url);
|
|
127
|
+
for (const relPath of [
|
|
128
|
+
"../../../aft-bridge/package.json",
|
|
129
|
+
"../../package.json",
|
|
130
|
+
"../package.json"
|
|
131
|
+
]) {
|
|
132
|
+
try {
|
|
133
|
+
const pkg = require2(relPath);
|
|
134
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0)
|
|
135
|
+
return pkg.version;
|
|
136
|
+
} catch {}
|
|
137
|
+
}
|
|
138
|
+
return "unknown";
|
|
139
|
+
}
|
|
140
|
+
function parseVersionOutput(output) {
|
|
141
|
+
for (const line of output.split(/\r?\n/)) {
|
|
142
|
+
const match = line.trim().match(VERSION_LINE);
|
|
143
|
+
if (match?.[1])
|
|
144
|
+
return match[1];
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function majorMinor(version) {
|
|
149
|
+
if (!version)
|
|
150
|
+
return null;
|
|
151
|
+
const match = version.trim().match(/^v?(\d+)\.(\d+)\.\d+(?:[-+][0-9A-Za-z.-]+)?$/);
|
|
152
|
+
if (!match)
|
|
153
|
+
return null;
|
|
154
|
+
return `${match[1]}.${match[2]}`;
|
|
155
|
+
}
|
|
156
|
+
function versionMatchesExpected(candidate, expectedVersion) {
|
|
157
|
+
const candidateMajorMinor = majorMinor(candidate);
|
|
158
|
+
const expectedMajorMinor = majorMinor(expectedVersion);
|
|
159
|
+
return candidateMajorMinor !== null && candidateMajorMinor === expectedMajorMinor;
|
|
160
|
+
}
|
|
161
|
+
function probeBinaryVersion(preferredVersion) {
|
|
162
|
+
return probeAftBinary(preferredVersion).version;
|
|
163
|
+
}
|
|
164
|
+
function probeAftBinary(preferredVersion) {
|
|
165
|
+
const expectedVersion = preferredVersion ?? PLUGIN_VERSION;
|
|
166
|
+
const expectedMajorMinor = majorMinor(expectedVersion);
|
|
167
|
+
const candidates = [];
|
|
168
|
+
for (const candidate of aftBinaryCandidates(preferredVersion)) {
|
|
169
|
+
try {
|
|
170
|
+
if (!existsSync(candidate))
|
|
171
|
+
continue;
|
|
172
|
+
const result = spawnSync(candidate, ["--version"], {
|
|
173
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
174
|
+
encoding: "utf-8",
|
|
175
|
+
timeout: 5000,
|
|
176
|
+
env: process.env
|
|
177
|
+
});
|
|
178
|
+
const output = `${result.stdout ?? ""}
|
|
179
|
+
${result.stderr ?? ""}`.trim();
|
|
180
|
+
if (result.error || result.status !== 0) {
|
|
181
|
+
candidates.push({
|
|
182
|
+
path: candidate,
|
|
183
|
+
status: "error",
|
|
184
|
+
version: null,
|
|
185
|
+
...output ? { output } : {},
|
|
186
|
+
error: result.error?.message ?? `exit status ${result.status ?? "unknown"}`
|
|
187
|
+
});
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const version = parseVersionOutput(output);
|
|
191
|
+
if (!version) {
|
|
192
|
+
candidates.push({ path: candidate, status: "invalid", version: null, output });
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (!versionMatchesExpected(version, expectedVersion)) {
|
|
196
|
+
candidates.push({ path: candidate, status: "unmatched", version, output });
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
candidates.push({ path: candidate, status: "matched", version, output });
|
|
200
|
+
return { version, path: candidate, expectedVersion, expectedMajorMinor, candidates };
|
|
201
|
+
} catch (error) {
|
|
202
|
+
candidates.push({
|
|
203
|
+
path: candidate,
|
|
204
|
+
status: "error",
|
|
205
|
+
version: null,
|
|
206
|
+
error: error instanceof Error ? error.message : String(error)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { version: null, path: null, expectedVersion, expectedMajorMinor, candidates };
|
|
211
|
+
}
|
|
212
|
+
function pushCandidate(candidates, candidate) {
|
|
213
|
+
if (!candidate)
|
|
214
|
+
return;
|
|
215
|
+
if (!candidates.includes(candidate))
|
|
216
|
+
candidates.push(candidate);
|
|
217
|
+
}
|
|
218
|
+
function firstExisting(candidates) {
|
|
219
|
+
for (const candidate of candidates) {
|
|
220
|
+
try {
|
|
221
|
+
if (!existsSync(candidate))
|
|
222
|
+
continue;
|
|
223
|
+
return candidate;
|
|
224
|
+
} catch {}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
function platformKey(platform = process.platform, arch = process.arch) {
|
|
229
|
+
const table = {
|
|
230
|
+
darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
|
|
231
|
+
linux: { arm64: "linux-arm64", x64: "linux-x64" },
|
|
232
|
+
win32: { x64: "win32-x64" }
|
|
233
|
+
};
|
|
234
|
+
return table[platform]?.[arch] ?? null;
|
|
235
|
+
}
|
|
236
|
+
function aftBinaryCandidates(preferredVersion) {
|
|
237
|
+
const candidates = [];
|
|
238
|
+
if (preferredVersion) {
|
|
239
|
+
const tag = preferredVersion.startsWith("v") ? preferredVersion : `v${preferredVersion}`;
|
|
240
|
+
pushCandidate(candidates, join2(getAftBinaryCacheDir(), tag, getAftBinaryName()));
|
|
241
|
+
}
|
|
242
|
+
const key = platformKey();
|
|
243
|
+
if (key) {
|
|
244
|
+
try {
|
|
245
|
+
const require2 = createRequire(import.meta.url);
|
|
246
|
+
pushCandidate(candidates, require2.resolve(`@cortexkit/aft-${key}/bin/${getAftBinaryName()}`));
|
|
247
|
+
} catch {}
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const lookup = process.platform === "win32" ? "where aft" : "which aft";
|
|
251
|
+
const resolved = execSync(lookup, {
|
|
252
|
+
stdio: "pipe",
|
|
253
|
+
encoding: "utf-8",
|
|
254
|
+
env: process.env
|
|
255
|
+
}).trim();
|
|
256
|
+
if (resolved) {
|
|
257
|
+
pushCandidate(candidates, resolved.split(/\r?\n/)[0]);
|
|
258
|
+
}
|
|
259
|
+
} catch {}
|
|
260
|
+
pushCandidate(candidates, join2(homedir2(), ".cargo", "bin", getAftBinaryName()));
|
|
261
|
+
return candidates;
|
|
262
|
+
}
|
|
263
|
+
function findAftBinary(preferredVersion) {
|
|
264
|
+
return firstExisting(aftBinaryCandidates(preferredVersion));
|
|
265
|
+
}
|
|
266
|
+
var PLUGIN_VERSION, VERSION_LINE;
|
|
267
|
+
var init_binary_probe = __esm(async () => {
|
|
268
|
+
init_paths();
|
|
269
|
+
PLUGIN_VERSION = await loadPluginVersion();
|
|
270
|
+
VERSION_LINE = /^(?:aft\s+)?v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/i;
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// src/lib/fs-util.ts
|
|
274
|
+
import { existsSync as existsSync2, readdirSync, statSync } from "node:fs";
|
|
275
|
+
import { join as join3 } from "node:path";
|
|
52
276
|
function dirSize(path) {
|
|
53
|
-
if (!
|
|
277
|
+
if (!existsSync2(path)) {
|
|
54
278
|
return 0;
|
|
55
279
|
}
|
|
56
280
|
const stat = statSync(path);
|
|
@@ -62,7 +286,7 @@ function dirSize(path) {
|
|
|
62
286
|
}
|
|
63
287
|
let total = 0;
|
|
64
288
|
for (const entry of readdirSync(path)) {
|
|
65
|
-
total += dirSize(
|
|
289
|
+
total += dirSize(join3(path, entry));
|
|
66
290
|
}
|
|
67
291
|
return total;
|
|
68
292
|
}
|
|
@@ -7685,10 +7909,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7685
7909
|
replacer = null;
|
|
7686
7910
|
indent = EMPTY;
|
|
7687
7911
|
};
|
|
7688
|
-
var
|
|
7912
|
+
var join4 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
7689
7913
|
var join_content = (inside, value, gap) => {
|
|
7690
7914
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
7691
|
-
return
|
|
7915
|
+
return join4(comment, inside, gap);
|
|
7692
7916
|
};
|
|
7693
7917
|
var stringify_string = (holder, key, value) => {
|
|
7694
7918
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -7710,13 +7934,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7710
7934
|
if (i !== 0) {
|
|
7711
7935
|
inside += COMMA;
|
|
7712
7936
|
}
|
|
7713
|
-
const before =
|
|
7937
|
+
const before = join4(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
7714
7938
|
inside += before || LF + deeper_gap;
|
|
7715
7939
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
7716
7940
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
7717
7941
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
7718
7942
|
}
|
|
7719
|
-
inside +=
|
|
7943
|
+
inside += join4(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7720
7944
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
7721
7945
|
};
|
|
7722
7946
|
var object_stringify = (value, gap) => {
|
|
@@ -7737,13 +7961,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7737
7961
|
inside += COMMA;
|
|
7738
7962
|
}
|
|
7739
7963
|
first = false;
|
|
7740
|
-
const before =
|
|
7964
|
+
const before = join4(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
7741
7965
|
inside += before || LF + deeper_gap;
|
|
7742
7966
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
7743
7967
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
7744
7968
|
};
|
|
7745
7969
|
keys.forEach(iteratee);
|
|
7746
|
-
inside +=
|
|
7970
|
+
inside += join4(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7747
7971
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
7748
7972
|
};
|
|
7749
7973
|
function stringify(key, holder, gap) {
|
|
@@ -7836,21 +8060,21 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7836
8060
|
});
|
|
7837
8061
|
|
|
7838
8062
|
// src/lib/jsonc.ts
|
|
7839
|
-
import { existsSync as
|
|
8063
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7840
8064
|
import { dirname } from "node:path";
|
|
7841
8065
|
function detectJsoncFile(configDir, baseName) {
|
|
7842
8066
|
const jsoncPath = `${configDir}/${baseName}.jsonc`;
|
|
7843
8067
|
const jsonPath = `${configDir}/${baseName}.json`;
|
|
7844
|
-
if (
|
|
8068
|
+
if (existsSync3(jsoncPath)) {
|
|
7845
8069
|
return { path: jsoncPath, format: "jsonc" };
|
|
7846
8070
|
}
|
|
7847
|
-
if (
|
|
8071
|
+
if (existsSync3(jsonPath)) {
|
|
7848
8072
|
return { path: jsonPath, format: "json" };
|
|
7849
8073
|
}
|
|
7850
8074
|
return { path: jsonPath, format: "none" };
|
|
7851
8075
|
}
|
|
7852
8076
|
function readJsoncFile(path) {
|
|
7853
|
-
if (!
|
|
8077
|
+
if (!existsSync3(path)) {
|
|
7854
8078
|
return { value: null };
|
|
7855
8079
|
}
|
|
7856
8080
|
try {
|
|
@@ -7871,7 +8095,7 @@ function writeJsoncFile(path, value, format = "json") {
|
|
|
7871
8095
|
`);
|
|
7872
8096
|
}
|
|
7873
8097
|
function ensureAftSchemaUrl(path, format) {
|
|
7874
|
-
const existed =
|
|
8098
|
+
const existed = existsSync3(path);
|
|
7875
8099
|
if (!existed) {
|
|
7876
8100
|
const writeFormat = format === "jsonc" ? "jsonc" : "json";
|
|
7877
8101
|
writeJsoncFile(path, { $schema: AFT_SCHEMA_URL }, writeFormat);
|
|
@@ -7906,73 +8130,10 @@ var init_jsonc = __esm(() => {
|
|
|
7906
8130
|
import_comment_json = __toESM(require_src2(), 1);
|
|
7907
8131
|
});
|
|
7908
8132
|
|
|
7909
|
-
// src/lib/paths.ts
|
|
7910
|
-
import { homedir, tmpdir } from "node:os";
|
|
7911
|
-
import { join as join2 } from "node:path";
|
|
7912
|
-
function getAftBinaryCacheDir() {
|
|
7913
|
-
if (process.env.AFT_CACHE_DIR) {
|
|
7914
|
-
return join2(process.env.AFT_CACHE_DIR, "bin");
|
|
7915
|
-
}
|
|
7916
|
-
if (process.platform === "win32") {
|
|
7917
|
-
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
7918
|
-
const base2 = localAppData || join2(homedir(), "AppData", "Local");
|
|
7919
|
-
return join2(base2, "aft", "bin");
|
|
7920
|
-
}
|
|
7921
|
-
const base = process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");
|
|
7922
|
-
return join2(base, "aft", "bin");
|
|
7923
|
-
}
|
|
7924
|
-
function getAftBinaryName() {
|
|
7925
|
-
return process.platform === "win32" ? "aft.exe" : "aft";
|
|
7926
|
-
}
|
|
7927
|
-
function getAftLspPackagesDir() {
|
|
7928
|
-
if (process.env.AFT_CACHE_DIR) {
|
|
7929
|
-
return join2(process.env.AFT_CACHE_DIR, "lsp-packages");
|
|
7930
|
-
}
|
|
7931
|
-
if (process.platform === "win32") {
|
|
7932
|
-
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
7933
|
-
const base2 = localAppData || join2(homedir(), "AppData", "Local");
|
|
7934
|
-
return join2(base2, "aft", "lsp-packages");
|
|
7935
|
-
}
|
|
7936
|
-
const base = process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");
|
|
7937
|
-
return join2(base, "aft", "lsp-packages");
|
|
7938
|
-
}
|
|
7939
|
-
function getAftLspBinariesDir() {
|
|
7940
|
-
if (process.env.AFT_CACHE_DIR) {
|
|
7941
|
-
return join2(process.env.AFT_CACHE_DIR, "lsp-binaries");
|
|
7942
|
-
}
|
|
7943
|
-
if (process.platform === "win32") {
|
|
7944
|
-
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
7945
|
-
const base2 = localAppData || join2(homedir(), "AppData", "Local");
|
|
7946
|
-
return join2(base2, "aft", "lsp-binaries");
|
|
7947
|
-
}
|
|
7948
|
-
const base = process.env.XDG_CACHE_HOME || join2(homedir(), ".cache");
|
|
7949
|
-
return join2(base, "aft", "lsp-binaries");
|
|
7950
|
-
}
|
|
7951
|
-
function homeDir() {
|
|
7952
|
-
if (process.platform === "win32")
|
|
7953
|
-
return process.env.USERPROFILE || process.env.HOME || homedir();
|
|
7954
|
-
return process.env.HOME || homedir();
|
|
7955
|
-
}
|
|
7956
|
-
function dataHome() {
|
|
7957
|
-
if (process.env.XDG_DATA_HOME)
|
|
7958
|
-
return process.env.XDG_DATA_HOME;
|
|
7959
|
-
if (process.platform === "win32") {
|
|
7960
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA || join2(homeDir(), "AppData", "Local");
|
|
7961
|
-
}
|
|
7962
|
-
return join2(homeDir(), ".local", "share");
|
|
7963
|
-
}
|
|
7964
|
-
function getCortexKitStorageRoot() {
|
|
7965
|
-
return join2(dataHome(), "cortexkit", "aft");
|
|
7966
|
-
}
|
|
7967
|
-
function getTmpLogPath(filename) {
|
|
7968
|
-
return join2(tmpdir(), filename);
|
|
7969
|
-
}
|
|
7970
|
-
var init_paths = () => {};
|
|
7971
|
-
|
|
7972
8133
|
// src/lib/self-version.ts
|
|
7973
|
-
import { createRequire } from "node:module";
|
|
8134
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
7974
8135
|
function getSelfVersion() {
|
|
7975
|
-
const require2 =
|
|
8136
|
+
const require2 = createRequire2(import.meta.url);
|
|
7976
8137
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
7977
8138
|
try {
|
|
7978
8139
|
const version = require2(relPath).version;
|
|
@@ -7986,27 +8147,27 @@ function getSelfVersion() {
|
|
|
7986
8147
|
var init_self_version = () => {};
|
|
7987
8148
|
|
|
7988
8149
|
// src/adapters/opencode.ts
|
|
7989
|
-
import { execSync } from "node:child_process";
|
|
7990
|
-
import { existsSync as
|
|
7991
|
-
import { homedir as
|
|
7992
|
-
import { dirname as dirname2, join as
|
|
8150
|
+
import { execSync as execSync2 } from "node:child_process";
|
|
8151
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, rmSync, statSync as statSync2 } from "node:fs";
|
|
8152
|
+
import { homedir as homedir3 } from "node:os";
|
|
8153
|
+
import { dirname as dirname2, join as join4, parse, resolve } from "node:path";
|
|
7993
8154
|
import { fileURLToPath } from "node:url";
|
|
7994
8155
|
function getOpenCodeConfigDir() {
|
|
7995
8156
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
7996
8157
|
if (envDir)
|
|
7997
8158
|
return resolve(envDir);
|
|
7998
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
7999
|
-
return
|
|
8159
|
+
const xdg = process.env.XDG_CONFIG_HOME || join4(homedir3(), ".config");
|
|
8160
|
+
return join4(xdg, "opencode");
|
|
8000
8161
|
}
|
|
8001
8162
|
function getOpenCodeCacheDir() {
|
|
8002
8163
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
8003
8164
|
if (xdg)
|
|
8004
|
-
return
|
|
8165
|
+
return join4(xdg, "opencode");
|
|
8005
8166
|
if (process.platform === "win32") {
|
|
8006
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
8007
|
-
return
|
|
8167
|
+
const localAppData = process.env.LOCALAPPDATA ?? join4(homedir3(), "AppData", "Local");
|
|
8168
|
+
return join4(localAppData, "opencode");
|
|
8008
8169
|
}
|
|
8009
|
-
return
|
|
8170
|
+
return join4(homedir3(), ".cache", "opencode");
|
|
8010
8171
|
}
|
|
8011
8172
|
function pathFromEntry(entry) {
|
|
8012
8173
|
if (entry.startsWith("file://")) {
|
|
@@ -8025,13 +8186,13 @@ function pathPointsToOurPlugin(entry) {
|
|
|
8025
8186
|
if (!fsPath)
|
|
8026
8187
|
return false;
|
|
8027
8188
|
try {
|
|
8028
|
-
if (!
|
|
8189
|
+
if (!existsSync4(fsPath))
|
|
8029
8190
|
return false;
|
|
8030
8191
|
let searchDir = statSync2(fsPath).isDirectory() ? fsPath : dirname2(fsPath);
|
|
8031
8192
|
let pkgJsonPath = null;
|
|
8032
8193
|
while (true) {
|
|
8033
|
-
const candidate =
|
|
8034
|
-
if (
|
|
8194
|
+
const candidate = join4(searchDir, "package.json");
|
|
8195
|
+
if (existsSync4(candidate)) {
|
|
8035
8196
|
pkgJsonPath = candidate;
|
|
8036
8197
|
break;
|
|
8037
8198
|
}
|
|
@@ -8063,7 +8224,7 @@ class OpenCodeAdapter {
|
|
|
8063
8224
|
pluginEntryWithVersion = PLUGIN_ENTRY;
|
|
8064
8225
|
isInstalled() {
|
|
8065
8226
|
try {
|
|
8066
|
-
|
|
8227
|
+
execSync2("opencode --version", { stdio: "ignore" });
|
|
8067
8228
|
return true;
|
|
8068
8229
|
} catch {
|
|
8069
8230
|
return false;
|
|
@@ -8071,7 +8232,7 @@ class OpenCodeAdapter {
|
|
|
8071
8232
|
}
|
|
8072
8233
|
getHostVersion() {
|
|
8073
8234
|
try {
|
|
8074
|
-
return
|
|
8235
|
+
return execSync2("opencode --version", { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
8075
8236
|
} catch {
|
|
8076
8237
|
return null;
|
|
8077
8238
|
}
|
|
@@ -8140,11 +8301,11 @@ class OpenCodeAdapter {
|
|
|
8140
8301
|
};
|
|
8141
8302
|
}
|
|
8142
8303
|
getPluginCacheInfo() {
|
|
8143
|
-
const path =
|
|
8304
|
+
const path = join4(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY);
|
|
8144
8305
|
let cached;
|
|
8145
8306
|
try {
|
|
8146
|
-
const installedPkgPath =
|
|
8147
|
-
if (
|
|
8307
|
+
const installedPkgPath = join4(path, "node_modules", "@cortexkit", "aft-opencode", "package.json");
|
|
8308
|
+
if (existsSync4(installedPkgPath)) {
|
|
8148
8309
|
const pkg = JSON.parse(readFileSync2(installedPkgPath, "utf-8"));
|
|
8149
8310
|
cached = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
8150
8311
|
}
|
|
@@ -8155,7 +8316,7 @@ class OpenCodeAdapter {
|
|
|
8155
8316
|
path,
|
|
8156
8317
|
cached,
|
|
8157
8318
|
latest: getSelfVersion(),
|
|
8158
|
-
exists:
|
|
8319
|
+
exists: existsSync4(path)
|
|
8159
8320
|
};
|
|
8160
8321
|
}
|
|
8161
8322
|
getStorageDir() {
|
|
@@ -8204,11 +8365,11 @@ class OpenCodeAdapter {
|
|
|
8204
8365
|
describeStorageSubtrees() {
|
|
8205
8366
|
const storage = this.getStorageDir();
|
|
8206
8367
|
return {
|
|
8207
|
-
index: dirSize(
|
|
8208
|
-
semantic: dirSize(
|
|
8209
|
-
backups: dirSize(
|
|
8210
|
-
url_cache: dirSize(
|
|
8211
|
-
onnxruntime: dirSize(
|
|
8368
|
+
index: dirSize(join4(storage, "index")),
|
|
8369
|
+
semantic: dirSize(join4(storage, "semantic")),
|
|
8370
|
+
backups: dirSize(join4(storage, "backups")),
|
|
8371
|
+
url_cache: dirSize(join4(storage, "url_cache")),
|
|
8372
|
+
onnxruntime: dirSize(join4(storage, "onnxruntime"))
|
|
8212
8373
|
};
|
|
8213
8374
|
}
|
|
8214
8375
|
}
|
|
@@ -8222,18 +8383,18 @@ var init_opencode = __esm(() => {
|
|
|
8222
8383
|
});
|
|
8223
8384
|
|
|
8224
8385
|
// src/adapters/pi.ts
|
|
8225
|
-
import { execSync as
|
|
8226
|
-
import { existsSync as
|
|
8227
|
-
import { homedir as
|
|
8228
|
-
import { join as
|
|
8229
|
-
function getPiAgentDir() {
|
|
8386
|
+
import { execSync as execSync3, spawnSync as spawnSync2 } from "node:child_process";
|
|
8387
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
8388
|
+
import { homedir as homedir4 } from "node:os";
|
|
8389
|
+
import { join as join5 } from "node:path";
|
|
8390
|
+
function getPiAgentDir() {
|
|
8230
8391
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
8231
|
-
const home = envHome && envHome.length > 0 ? envHome :
|
|
8232
|
-
return
|
|
8392
|
+
const home = envHome && envHome.length > 0 ? envHome : homedir4();
|
|
8393
|
+
return join5(home, ".pi", "agent");
|
|
8233
8394
|
}
|
|
8234
8395
|
function readPiExtensionIndex() {
|
|
8235
|
-
const settingsPath =
|
|
8236
|
-
if (
|
|
8396
|
+
const settingsPath = join5(getPiAgentDir(), "settings.json");
|
|
8397
|
+
if (existsSync5(settingsPath)) {
|
|
8237
8398
|
try {
|
|
8238
8399
|
const raw = readFileSync3(settingsPath, "utf-8");
|
|
8239
8400
|
const trimmed = raw.replace(/^\uFEFF/, "");
|
|
@@ -8246,13 +8407,13 @@ function readPiExtensionIndex() {
|
|
|
8246
8407
|
} catch {}
|
|
8247
8408
|
}
|
|
8248
8409
|
const candidates = [
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8410
|
+
join5(getPiAgentDir(), "extensions.json"),
|
|
8411
|
+
join5(getPiAgentDir(), "extensions.jsonc"),
|
|
8412
|
+
join5(getPiAgentDir(), "config.json"),
|
|
8413
|
+
join5(getPiAgentDir(), "config.jsonc")
|
|
8253
8414
|
];
|
|
8254
8415
|
for (const path of candidates) {
|
|
8255
|
-
if (!
|
|
8416
|
+
if (!existsSync5(path))
|
|
8256
8417
|
continue;
|
|
8257
8418
|
try {
|
|
8258
8419
|
const { value } = readJsoncFile(path);
|
|
@@ -8285,15 +8446,15 @@ function piEntryMatchesAft(entry) {
|
|
|
8285
8446
|
} else if (entry.startsWith("/")) {
|
|
8286
8447
|
resolved = entry;
|
|
8287
8448
|
} else if (entry.length > 0) {
|
|
8288
|
-
resolved =
|
|
8449
|
+
resolved = join5(getPiAgentDir(), entry);
|
|
8289
8450
|
}
|
|
8290
8451
|
if (!resolved)
|
|
8291
8452
|
return false;
|
|
8292
8453
|
try {
|
|
8293
|
-
if (!
|
|
8454
|
+
if (!existsSync5(resolved))
|
|
8294
8455
|
return false;
|
|
8295
|
-
const pkgPath =
|
|
8296
|
-
if (!
|
|
8456
|
+
const pkgPath = join5(resolved, "package.json");
|
|
8457
|
+
if (!existsSync5(pkgPath))
|
|
8297
8458
|
return false;
|
|
8298
8459
|
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
8299
8460
|
return pkg.name === PLUGIN_NAME2;
|
|
@@ -8313,7 +8474,7 @@ class PiAdapter {
|
|
|
8313
8474
|
pluginEntryWithVersion = PLUGIN_ENTRY2;
|
|
8314
8475
|
isInstalled() {
|
|
8315
8476
|
try {
|
|
8316
|
-
|
|
8477
|
+
execSync3("pi --version", { stdio: "ignore" });
|
|
8317
8478
|
return true;
|
|
8318
8479
|
} catch {
|
|
8319
8480
|
return false;
|
|
@@ -8321,7 +8482,7 @@ class PiAdapter {
|
|
|
8321
8482
|
}
|
|
8322
8483
|
getHostVersion() {
|
|
8323
8484
|
try {
|
|
8324
|
-
const result =
|
|
8485
|
+
const result = spawnSync2("pi", ["--version"], {
|
|
8325
8486
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8326
8487
|
encoding: "utf-8"
|
|
8327
8488
|
});
|
|
@@ -8342,7 +8503,7 @@ class PiAdapter {
|
|
|
8342
8503
|
const aft = detectJsoncFile(configDir, "aft");
|
|
8343
8504
|
return {
|
|
8344
8505
|
configDir,
|
|
8345
|
-
harnessConfig: index.path ??
|
|
8506
|
+
harnessConfig: index.path ?? join5(configDir, "extensions.json"),
|
|
8346
8507
|
harnessConfigFormat: index.path ? "json" : "none",
|
|
8347
8508
|
aftConfig: aft.path,
|
|
8348
8509
|
aftConfigFormat: aft.format
|
|
@@ -8369,7 +8530,7 @@ class PiAdapter {
|
|
|
8369
8530
|
};
|
|
8370
8531
|
}
|
|
8371
8532
|
try {
|
|
8372
|
-
|
|
8533
|
+
execSync3(`pi install ${PLUGIN_ENTRY2}`, { stdio: "inherit" });
|
|
8373
8534
|
return {
|
|
8374
8535
|
ok: true,
|
|
8375
8536
|
action: "added",
|
|
@@ -8387,11 +8548,11 @@ class PiAdapter {
|
|
|
8387
8548
|
}
|
|
8388
8549
|
getPluginCacheInfo() {
|
|
8389
8550
|
const candidates = [
|
|
8390
|
-
|
|
8391
|
-
|
|
8551
|
+
join5(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
|
|
8552
|
+
join5(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
|
|
8392
8553
|
];
|
|
8393
8554
|
for (const candidate of candidates) {
|
|
8394
|
-
if (!
|
|
8555
|
+
if (!existsSync5(candidate))
|
|
8395
8556
|
continue;
|
|
8396
8557
|
try {
|
|
8397
8558
|
const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
|
|
@@ -8405,7 +8566,7 @@ class PiAdapter {
|
|
|
8405
8566
|
} catch {}
|
|
8406
8567
|
}
|
|
8407
8568
|
return {
|
|
8408
|
-
path:
|
|
8569
|
+
path: join5(getPiAgentDir(), "extensions"),
|
|
8409
8570
|
exists: false
|
|
8410
8571
|
};
|
|
8411
8572
|
}
|
|
@@ -8427,11 +8588,11 @@ class PiAdapter {
|
|
|
8427
8588
|
describeStorageSubtrees() {
|
|
8428
8589
|
const storage = this.getStorageDir();
|
|
8429
8590
|
return {
|
|
8430
|
-
index: dirSize(
|
|
8431
|
-
semantic: dirSize(
|
|
8432
|
-
backups: dirSize(
|
|
8433
|
-
url_cache: dirSize(
|
|
8434
|
-
onnxruntime: dirSize(
|
|
8591
|
+
index: dirSize(join5(storage, "index")),
|
|
8592
|
+
semantic: dirSize(join5(storage, "semantic")),
|
|
8593
|
+
backups: dirSize(join5(storage, "backups")),
|
|
8594
|
+
url_cache: dirSize(join5(storage, "url_cache")),
|
|
8595
|
+
onnxruntime: dirSize(join5(storage, "onnxruntime"))
|
|
8435
8596
|
};
|
|
8436
8597
|
}
|
|
8437
8598
|
}
|
|
@@ -8444,6 +8605,9 @@ var init_pi = __esm(() => {
|
|
|
8444
8605
|
});
|
|
8445
8606
|
|
|
8446
8607
|
// src/adapters/index.ts
|
|
8608
|
+
function getAllAdapters() {
|
|
8609
|
+
return ALL;
|
|
8610
|
+
}
|
|
8447
8611
|
function getAdapter(kind) {
|
|
8448
8612
|
const found = ALL.find((a) => a.kind === kind);
|
|
8449
8613
|
if (!found)
|
|
@@ -9903,11 +10067,59 @@ async function resolveAdaptersForCommand(argv, options) {
|
|
|
9903
10067
|
})), installed.map((a) => a.kind));
|
|
9904
10068
|
return picks.map((kind) => getAdapter(kind));
|
|
9905
10069
|
}
|
|
10070
|
+
function getAllRegistryAdapters() {
|
|
10071
|
+
return getAllAdapters();
|
|
10072
|
+
}
|
|
9906
10073
|
var init_harness_select = __esm(() => {
|
|
9907
10074
|
init_adapters();
|
|
9908
10075
|
init_prompts();
|
|
9909
10076
|
});
|
|
9910
10077
|
|
|
10078
|
+
// src/commands/version.ts
|
|
10079
|
+
var exports_version = {};
|
|
10080
|
+
__export(exports_version, {
|
|
10081
|
+
runVersion: () => runVersion
|
|
10082
|
+
});
|
|
10083
|
+
function runVersion() {
|
|
10084
|
+
const cliVersion = getSelfVersion();
|
|
10085
|
+
const binaryVersion = probeBinaryVersion();
|
|
10086
|
+
const lines = [];
|
|
10087
|
+
lines.push("");
|
|
10088
|
+
lines.push(" AFT versions");
|
|
10089
|
+
lines.push("");
|
|
10090
|
+
lines.push(` @cortexkit/aft (this CLI) v${cliVersion}`);
|
|
10091
|
+
lines.push(` aft binary ${binaryVersion ?? "not installed"}`);
|
|
10092
|
+
lines.push("");
|
|
10093
|
+
const adapters = getAllRegistryAdapters();
|
|
10094
|
+
const labelWidth = Math.max(...adapters.map((adapter) => adapter.displayName.length));
|
|
10095
|
+
for (const adapter of adapters) {
|
|
10096
|
+
const label = adapter.displayName.padEnd(labelWidth);
|
|
10097
|
+
if (!adapter.isInstalled()) {
|
|
10098
|
+
lines.push(` ${label} host not installed`);
|
|
10099
|
+
continue;
|
|
10100
|
+
}
|
|
10101
|
+
const host = adapter.getHostVersion() ?? "unknown";
|
|
10102
|
+
const registered = adapter.hasPluginEntry();
|
|
10103
|
+
let pluginPart;
|
|
10104
|
+
if (!registered) {
|
|
10105
|
+
pluginPart = "plugin not registered";
|
|
10106
|
+
} else {
|
|
10107
|
+
const cached = adapter.getPluginCacheInfo().cached;
|
|
10108
|
+
pluginPart = cached ? `plugin ${cached}` : "plugin registered (version unknown)";
|
|
10109
|
+
}
|
|
10110
|
+
lines.push(` ${label} host ${host} · ${pluginPart}`);
|
|
10111
|
+
}
|
|
10112
|
+
lines.push("");
|
|
10113
|
+
console.log(lines.join(`
|
|
10114
|
+
`));
|
|
10115
|
+
return 0;
|
|
10116
|
+
}
|
|
10117
|
+
var init_version = __esm(async () => {
|
|
10118
|
+
init_harness_select();
|
|
10119
|
+
init_self_version();
|
|
10120
|
+
await init_binary_probe();
|
|
10121
|
+
});
|
|
10122
|
+
|
|
9911
10123
|
// src/commands/setup.ts
|
|
9912
10124
|
var exports_setup = {};
|
|
9913
10125
|
__export(exports_setup, {
|
|
@@ -10101,167 +10313,6 @@ ${stderrTrimmed}`);
|
|
|
10101
10313
|
var MAX_NOISE_LINES_IN_ERROR = 5;
|
|
10102
10314
|
var init_aft_bridge = () => {};
|
|
10103
10315
|
|
|
10104
|
-
// src/lib/binary-probe.ts
|
|
10105
|
-
import { execSync as execSync3, spawnSync as spawnSync2 } from "node:child_process";
|
|
10106
|
-
import { existsSync as existsSync5 } from "node:fs";
|
|
10107
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
10108
|
-
import { homedir as homedir4 } from "node:os";
|
|
10109
|
-
import { join as join5 } from "node:path";
|
|
10110
|
-
async function loadPluginVersion() {
|
|
10111
|
-
try {
|
|
10112
|
-
const bridgePackageName = "@cortexkit/aft-bridge";
|
|
10113
|
-
const bridge = await import(bridgePackageName);
|
|
10114
|
-
if (typeof bridge.PLUGIN_VERSION === "string" && bridge.PLUGIN_VERSION.length > 0) {
|
|
10115
|
-
return bridge.PLUGIN_VERSION;
|
|
10116
|
-
}
|
|
10117
|
-
} catch {}
|
|
10118
|
-
const require2 = createRequire2(import.meta.url);
|
|
10119
|
-
for (const relPath of [
|
|
10120
|
-
"../../../aft-bridge/package.json",
|
|
10121
|
-
"../../package.json",
|
|
10122
|
-
"../package.json"
|
|
10123
|
-
]) {
|
|
10124
|
-
try {
|
|
10125
|
-
const pkg = require2(relPath);
|
|
10126
|
-
if (typeof pkg.version === "string" && pkg.version.length > 0)
|
|
10127
|
-
return pkg.version;
|
|
10128
|
-
} catch {}
|
|
10129
|
-
}
|
|
10130
|
-
return "unknown";
|
|
10131
|
-
}
|
|
10132
|
-
function parseVersionOutput(output) {
|
|
10133
|
-
for (const line of output.split(/\r?\n/)) {
|
|
10134
|
-
const match = line.trim().match(VERSION_LINE);
|
|
10135
|
-
if (match?.[1])
|
|
10136
|
-
return match[1];
|
|
10137
|
-
}
|
|
10138
|
-
return null;
|
|
10139
|
-
}
|
|
10140
|
-
function majorMinor(version) {
|
|
10141
|
-
if (!version)
|
|
10142
|
-
return null;
|
|
10143
|
-
const match = version.trim().match(/^v?(\d+)\.(\d+)\.\d+(?:[-+][0-9A-Za-z.-]+)?$/);
|
|
10144
|
-
if (!match)
|
|
10145
|
-
return null;
|
|
10146
|
-
return `${match[1]}.${match[2]}`;
|
|
10147
|
-
}
|
|
10148
|
-
function versionMatchesExpected(candidate, expectedVersion) {
|
|
10149
|
-
const candidateMajorMinor = majorMinor(candidate);
|
|
10150
|
-
const expectedMajorMinor = majorMinor(expectedVersion);
|
|
10151
|
-
return candidateMajorMinor !== null && candidateMajorMinor === expectedMajorMinor;
|
|
10152
|
-
}
|
|
10153
|
-
function probeBinaryVersion(preferredVersion) {
|
|
10154
|
-
return probeAftBinary(preferredVersion).version;
|
|
10155
|
-
}
|
|
10156
|
-
function probeAftBinary(preferredVersion) {
|
|
10157
|
-
const expectedVersion = preferredVersion ?? PLUGIN_VERSION;
|
|
10158
|
-
const expectedMajorMinor = majorMinor(expectedVersion);
|
|
10159
|
-
const candidates = [];
|
|
10160
|
-
for (const candidate of aftBinaryCandidates(preferredVersion)) {
|
|
10161
|
-
try {
|
|
10162
|
-
if (!existsSync5(candidate))
|
|
10163
|
-
continue;
|
|
10164
|
-
const result = spawnSync2(candidate, ["--version"], {
|
|
10165
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
10166
|
-
encoding: "utf-8",
|
|
10167
|
-
timeout: 5000,
|
|
10168
|
-
env: process.env
|
|
10169
|
-
});
|
|
10170
|
-
const output = `${result.stdout ?? ""}
|
|
10171
|
-
${result.stderr ?? ""}`.trim();
|
|
10172
|
-
if (result.error || result.status !== 0) {
|
|
10173
|
-
candidates.push({
|
|
10174
|
-
path: candidate,
|
|
10175
|
-
status: "error",
|
|
10176
|
-
version: null,
|
|
10177
|
-
...output ? { output } : {},
|
|
10178
|
-
error: result.error?.message ?? `exit status ${result.status ?? "unknown"}`
|
|
10179
|
-
});
|
|
10180
|
-
continue;
|
|
10181
|
-
}
|
|
10182
|
-
const version = parseVersionOutput(output);
|
|
10183
|
-
if (!version) {
|
|
10184
|
-
candidates.push({ path: candidate, status: "invalid", version: null, output });
|
|
10185
|
-
continue;
|
|
10186
|
-
}
|
|
10187
|
-
if (!versionMatchesExpected(version, expectedVersion)) {
|
|
10188
|
-
candidates.push({ path: candidate, status: "unmatched", version, output });
|
|
10189
|
-
continue;
|
|
10190
|
-
}
|
|
10191
|
-
candidates.push({ path: candidate, status: "matched", version, output });
|
|
10192
|
-
return { version, path: candidate, expectedVersion, expectedMajorMinor, candidates };
|
|
10193
|
-
} catch (error) {
|
|
10194
|
-
candidates.push({
|
|
10195
|
-
path: candidate,
|
|
10196
|
-
status: "error",
|
|
10197
|
-
version: null,
|
|
10198
|
-
error: error instanceof Error ? error.message : String(error)
|
|
10199
|
-
});
|
|
10200
|
-
}
|
|
10201
|
-
}
|
|
10202
|
-
return { version: null, path: null, expectedVersion, expectedMajorMinor, candidates };
|
|
10203
|
-
}
|
|
10204
|
-
function pushCandidate(candidates, candidate) {
|
|
10205
|
-
if (!candidate)
|
|
10206
|
-
return;
|
|
10207
|
-
if (!candidates.includes(candidate))
|
|
10208
|
-
candidates.push(candidate);
|
|
10209
|
-
}
|
|
10210
|
-
function firstExisting(candidates) {
|
|
10211
|
-
for (const candidate of candidates) {
|
|
10212
|
-
try {
|
|
10213
|
-
if (!existsSync5(candidate))
|
|
10214
|
-
continue;
|
|
10215
|
-
return candidate;
|
|
10216
|
-
} catch {}
|
|
10217
|
-
}
|
|
10218
|
-
return null;
|
|
10219
|
-
}
|
|
10220
|
-
function platformKey(platform = process.platform, arch = process.arch) {
|
|
10221
|
-
const table = {
|
|
10222
|
-
darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
|
|
10223
|
-
linux: { arm64: "linux-arm64", x64: "linux-x64" },
|
|
10224
|
-
win32: { x64: "win32-x64" }
|
|
10225
|
-
};
|
|
10226
|
-
return table[platform]?.[arch] ?? null;
|
|
10227
|
-
}
|
|
10228
|
-
function aftBinaryCandidates(preferredVersion) {
|
|
10229
|
-
const candidates = [];
|
|
10230
|
-
if (preferredVersion) {
|
|
10231
|
-
const tag = preferredVersion.startsWith("v") ? preferredVersion : `v${preferredVersion}`;
|
|
10232
|
-
pushCandidate(candidates, join5(getAftBinaryCacheDir(), tag, getAftBinaryName()));
|
|
10233
|
-
}
|
|
10234
|
-
const key = platformKey();
|
|
10235
|
-
if (key) {
|
|
10236
|
-
try {
|
|
10237
|
-
const require2 = createRequire2(import.meta.url);
|
|
10238
|
-
pushCandidate(candidates, require2.resolve(`@cortexkit/aft-${key}/bin/${getAftBinaryName()}`));
|
|
10239
|
-
} catch {}
|
|
10240
|
-
}
|
|
10241
|
-
try {
|
|
10242
|
-
const lookup = process.platform === "win32" ? "where aft" : "which aft";
|
|
10243
|
-
const resolved = execSync3(lookup, {
|
|
10244
|
-
stdio: "pipe",
|
|
10245
|
-
encoding: "utf-8",
|
|
10246
|
-
env: process.env
|
|
10247
|
-
}).trim();
|
|
10248
|
-
if (resolved) {
|
|
10249
|
-
pushCandidate(candidates, resolved.split(/\r?\n/)[0]);
|
|
10250
|
-
}
|
|
10251
|
-
} catch {}
|
|
10252
|
-
pushCandidate(candidates, join5(homedir4(), ".cargo", "bin", getAftBinaryName()));
|
|
10253
|
-
return candidates;
|
|
10254
|
-
}
|
|
10255
|
-
function findAftBinary(preferredVersion) {
|
|
10256
|
-
return firstExisting(aftBinaryCandidates(preferredVersion));
|
|
10257
|
-
}
|
|
10258
|
-
var PLUGIN_VERSION, VERSION_LINE;
|
|
10259
|
-
var init_binary_probe = __esm(async () => {
|
|
10260
|
-
init_paths();
|
|
10261
|
-
PLUGIN_VERSION = await loadPluginVersion();
|
|
10262
|
-
VERSION_LINE = /^(?:aft\s+)?v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/i;
|
|
10263
|
-
});
|
|
10264
|
-
|
|
10265
10316
|
// src/commands/lsp.ts
|
|
10266
10317
|
var exports_lsp = {};
|
|
10267
10318
|
__export(exports_lsp, {
|
|
@@ -11552,6 +11603,12 @@ function createGitHubIssue(repo, title, body) {
|
|
|
11552
11603
|
var init_github = () => {};
|
|
11553
11604
|
|
|
11554
11605
|
// src/lib/issue-body.ts
|
|
11606
|
+
function filterLogToSession(logText, sessionId) {
|
|
11607
|
+
const bareId = sessionId.replace(/^ses_/, "");
|
|
11608
|
+
const keepTokens = [`[ses_${bareId}]`, `[${bareId}]`];
|
|
11609
|
+
return logText.split(/\r?\n/).filter((line) => !SESSION_TAG_PATTERN.test(line) || keepTokens.some((token) => line.includes(token))).join(`
|
|
11610
|
+
`);
|
|
11611
|
+
}
|
|
11555
11612
|
function isErrorLogLine(line) {
|
|
11556
11613
|
return ERROR_LOG_PATTERNS.some((rx) => rx.test(line));
|
|
11557
11614
|
}
|
|
@@ -11629,8 +11686,9 @@ function truncateToByteBudget(input, maxBytes) {
|
|
|
11629
11686
|
}
|
|
11630
11687
|
return buf.subarray(0, end).toString("utf8");
|
|
11631
11688
|
}
|
|
11632
|
-
var MAX_GITHUB_BODY_BYTES = 60000, ERROR_LOG_PATTERNS;
|
|
11689
|
+
var MAX_GITHUB_BODY_BYTES = 60000, SESSION_TAG_PATTERN, ERROR_LOG_PATTERNS;
|
|
11633
11690
|
var init_issue_body = __esm(() => {
|
|
11691
|
+
SESSION_TAG_PATTERN = /\[ses_[^\]\s]+\]|\[[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\]/;
|
|
11634
11692
|
ERROR_LOG_PATTERNS = [
|
|
11635
11693
|
/\bcrashed:/i,
|
|
11636
11694
|
/\bfailed:/i,
|
|
@@ -11726,6 +11784,189 @@ var init_onnx_fix = __esm(() => {
|
|
|
11726
11784
|
init_prompts();
|
|
11727
11785
|
});
|
|
11728
11786
|
|
|
11787
|
+
// src/lib/sessions.ts
|
|
11788
|
+
import { existsSync as existsSync13, readdirSync as readdirSync6, readFileSync as readFileSync4, statSync as statSync8 } from "node:fs";
|
|
11789
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
11790
|
+
import { homedir as homedir7 } from "node:os";
|
|
11791
|
+
import { basename as basename2, join as join11 } from "node:path";
|
|
11792
|
+
function listRecentSessions(adapter) {
|
|
11793
|
+
try {
|
|
11794
|
+
if (adapter.kind === "opencode")
|
|
11795
|
+
return listRecentOpenCodeSessions();
|
|
11796
|
+
if (adapter.kind === "pi")
|
|
11797
|
+
return listRecentPiSessions();
|
|
11798
|
+
return [];
|
|
11799
|
+
} catch {
|
|
11800
|
+
return [];
|
|
11801
|
+
}
|
|
11802
|
+
}
|
|
11803
|
+
function mapOpenCodeSessionRows(rows) {
|
|
11804
|
+
return rows.map((row) => {
|
|
11805
|
+
if (typeof row.id !== "string" || row.id.length === 0)
|
|
11806
|
+
return null;
|
|
11807
|
+
if (typeof row.title !== "string" || row.title.length === 0)
|
|
11808
|
+
return null;
|
|
11809
|
+
const lastActivity = typeof row.time_updated === "number" ? row.time_updated : Number(row.time_updated);
|
|
11810
|
+
if (!Number.isFinite(lastActivity))
|
|
11811
|
+
return null;
|
|
11812
|
+
return {
|
|
11813
|
+
id: row.id,
|
|
11814
|
+
title: row.title,
|
|
11815
|
+
lastActivity
|
|
11816
|
+
};
|
|
11817
|
+
}).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
|
|
11818
|
+
}
|
|
11819
|
+
function listRecentOpenCodeSessions() {
|
|
11820
|
+
const dbPath = join11(getXdgDataHome(), "opencode", "opencode.db");
|
|
11821
|
+
if (!existsSync13(dbPath))
|
|
11822
|
+
return [];
|
|
11823
|
+
let db = null;
|
|
11824
|
+
try {
|
|
11825
|
+
const require2 = createRequire3(import.meta.url);
|
|
11826
|
+
const sqlite = require2("node:sqlite");
|
|
11827
|
+
db = new sqlite.DatabaseSync(dbPath, { readOnly: true });
|
|
11828
|
+
const rows = db.prepare("SELECT id, title, time_updated FROM session ORDER BY time_updated DESC LIMIT 5").all();
|
|
11829
|
+
return mapOpenCodeSessionRows(rows);
|
|
11830
|
+
} catch {
|
|
11831
|
+
return [];
|
|
11832
|
+
} finally {
|
|
11833
|
+
try {
|
|
11834
|
+
db?.close();
|
|
11835
|
+
} catch {}
|
|
11836
|
+
}
|
|
11837
|
+
}
|
|
11838
|
+
function getXdgDataHome() {
|
|
11839
|
+
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
11840
|
+
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join11(homedir7(), ".local", "share");
|
|
11841
|
+
}
|
|
11842
|
+
function listRecentPiSessions() {
|
|
11843
|
+
return listPiSessionsFromDir(join11(getHomeDir(), ".pi", "agent", "sessions"));
|
|
11844
|
+
}
|
|
11845
|
+
function getHomeDir() {
|
|
11846
|
+
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
11847
|
+
return envHome && envHome.length > 0 ? envHome : homedir7();
|
|
11848
|
+
}
|
|
11849
|
+
function listPiSessionsFromDir(sessionsDir) {
|
|
11850
|
+
try {
|
|
11851
|
+
if (!existsSync13(sessionsDir))
|
|
11852
|
+
return [];
|
|
11853
|
+
const files = collectJsonlFiles(sessionsDir).map((filePath) => {
|
|
11854
|
+
try {
|
|
11855
|
+
const stats = statSync8(filePath);
|
|
11856
|
+
return { filePath, mtimeMs: stats.mtimeMs };
|
|
11857
|
+
} catch {
|
|
11858
|
+
return null;
|
|
11859
|
+
}
|
|
11860
|
+
}).filter((entry) => entry !== null).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
|
|
11861
|
+
const sessions = [];
|
|
11862
|
+
for (const file of files) {
|
|
11863
|
+
const parsed = parsePiSessionJsonl(readFileSync4(file.filePath, "utf8"), basename2(file.filePath));
|
|
11864
|
+
if (!parsed)
|
|
11865
|
+
continue;
|
|
11866
|
+
sessions.push({ ...parsed, lastActivity: file.mtimeMs });
|
|
11867
|
+
if (sessions.length >= MAX_RECENT_SESSIONS)
|
|
11868
|
+
break;
|
|
11869
|
+
}
|
|
11870
|
+
return sessions;
|
|
11871
|
+
} catch {
|
|
11872
|
+
return [];
|
|
11873
|
+
}
|
|
11874
|
+
}
|
|
11875
|
+
function collectJsonlFiles(root) {
|
|
11876
|
+
const files = [];
|
|
11877
|
+
const stack = [root];
|
|
11878
|
+
while (stack.length > 0) {
|
|
11879
|
+
const dir = stack.pop();
|
|
11880
|
+
if (!dir)
|
|
11881
|
+
continue;
|
|
11882
|
+
let entries;
|
|
11883
|
+
try {
|
|
11884
|
+
entries = readdirSync6(dir, { withFileTypes: true });
|
|
11885
|
+
} catch {
|
|
11886
|
+
continue;
|
|
11887
|
+
}
|
|
11888
|
+
for (const entry of entries) {
|
|
11889
|
+
const path = join11(dir, entry.name);
|
|
11890
|
+
if (entry.isDirectory()) {
|
|
11891
|
+
stack.push(path);
|
|
11892
|
+
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
11893
|
+
files.push(path);
|
|
11894
|
+
}
|
|
11895
|
+
}
|
|
11896
|
+
}
|
|
11897
|
+
return files;
|
|
11898
|
+
}
|
|
11899
|
+
function parsePiSessionJsonl(jsonl, fallbackFilename = "") {
|
|
11900
|
+
let id = extractUuidFromFilename(fallbackFilename);
|
|
11901
|
+
let title = null;
|
|
11902
|
+
for (const line of jsonl.split(/\r?\n/)) {
|
|
11903
|
+
const trimmed = line.trim();
|
|
11904
|
+
if (trimmed.length === 0)
|
|
11905
|
+
continue;
|
|
11906
|
+
let value;
|
|
11907
|
+
try {
|
|
11908
|
+
value = JSON.parse(trimmed);
|
|
11909
|
+
} catch {
|
|
11910
|
+
continue;
|
|
11911
|
+
}
|
|
11912
|
+
if (!value || typeof value !== "object")
|
|
11913
|
+
continue;
|
|
11914
|
+
const record = value;
|
|
11915
|
+
if (record.type === "session" && typeof record.id === "string" && record.id.length > 0) {
|
|
11916
|
+
id = record.id;
|
|
11917
|
+
}
|
|
11918
|
+
if (title === null) {
|
|
11919
|
+
const maybeTitle = extractPiUserMessageText(record);
|
|
11920
|
+
if (maybeTitle)
|
|
11921
|
+
title = truncateTitle(maybeTitle);
|
|
11922
|
+
}
|
|
11923
|
+
if (id && title)
|
|
11924
|
+
break;
|
|
11925
|
+
}
|
|
11926
|
+
if (!id)
|
|
11927
|
+
return null;
|
|
11928
|
+
return { id, title: title ?? id };
|
|
11929
|
+
}
|
|
11930
|
+
function extractPiUserMessageText(record) {
|
|
11931
|
+
if (record.type !== "message")
|
|
11932
|
+
return null;
|
|
11933
|
+
const message = record.message;
|
|
11934
|
+
if (!message || typeof message !== "object")
|
|
11935
|
+
return null;
|
|
11936
|
+
const messageRecord = message;
|
|
11937
|
+
if (messageRecord.role !== "user")
|
|
11938
|
+
return null;
|
|
11939
|
+
return extractTextFromContent(messageRecord.content);
|
|
11940
|
+
}
|
|
11941
|
+
function extractTextFromContent(content) {
|
|
11942
|
+
if (typeof content === "string")
|
|
11943
|
+
return content.trim() || null;
|
|
11944
|
+
if (!Array.isArray(content))
|
|
11945
|
+
return null;
|
|
11946
|
+
const parts = content.map((part) => {
|
|
11947
|
+
if (typeof part === "string")
|
|
11948
|
+
return part;
|
|
11949
|
+
if (!part || typeof part !== "object")
|
|
11950
|
+
return "";
|
|
11951
|
+
const partRecord = part;
|
|
11952
|
+
return partRecord.type === "text" && typeof partRecord.text === "string" ? partRecord.text : "";
|
|
11953
|
+
}).filter((text2) => text2.trim().length > 0);
|
|
11954
|
+
const joined = parts.join(" ").trim();
|
|
11955
|
+
return joined.length > 0 ? joined : null;
|
|
11956
|
+
}
|
|
11957
|
+
function extractUuidFromFilename(filename) {
|
|
11958
|
+
const match = filename.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i);
|
|
11959
|
+
return match?.[1] ?? null;
|
|
11960
|
+
}
|
|
11961
|
+
function truncateTitle(title, maxLength = 60) {
|
|
11962
|
+
const normalized = title.replace(/\s+/g, " ").trim();
|
|
11963
|
+
if (normalized.length <= maxLength)
|
|
11964
|
+
return normalized;
|
|
11965
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 1))}…`;
|
|
11966
|
+
}
|
|
11967
|
+
var MAX_RECENT_SESSIONS = 5;
|
|
11968
|
+
var init_sessions = () => {};
|
|
11969
|
+
|
|
11729
11970
|
// src/commands/doctor.ts
|
|
11730
11971
|
var exports_doctor = {};
|
|
11731
11972
|
__export(exports_doctor, {
|
|
@@ -11744,17 +11985,17 @@ __export(exports_doctor, {
|
|
|
11744
11985
|
});
|
|
11745
11986
|
import {
|
|
11746
11987
|
chmodSync,
|
|
11747
|
-
existsSync as
|
|
11988
|
+
existsSync as existsSync14,
|
|
11748
11989
|
mkdirSync as mkdirSync2,
|
|
11749
11990
|
mkdtempSync,
|
|
11750
|
-
readFileSync as
|
|
11991
|
+
readFileSync as readFileSync5,
|
|
11751
11992
|
realpathSync as realpathSync3,
|
|
11752
11993
|
rmSync as rmSync4,
|
|
11753
|
-
statSync as
|
|
11994
|
+
statSync as statSync9,
|
|
11754
11995
|
writeFileSync as writeFileSync2
|
|
11755
11996
|
} from "node:fs";
|
|
11756
11997
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
11757
|
-
import { join as
|
|
11998
|
+
import { join as join12 } from "node:path";
|
|
11758
11999
|
async function runDoctor(options) {
|
|
11759
12000
|
if (options.issue) {
|
|
11760
12001
|
return runIssueFlow(options.argv);
|
|
@@ -11767,7 +12008,7 @@ async function runDoctor(options) {
|
|
|
11767
12008
|
return runClearFlow(options.argv);
|
|
11768
12009
|
}
|
|
11769
12010
|
const adapters = await resolveAdaptersForCommand(options.argv, {
|
|
11770
|
-
allowMulti:
|
|
12011
|
+
allowMulti: false,
|
|
11771
12012
|
verb: "diagnose"
|
|
11772
12013
|
});
|
|
11773
12014
|
const report = await collectDiagnostics(adapters);
|
|
@@ -11798,6 +12039,10 @@ async function runDoctor(options) {
|
|
|
11798
12039
|
O2.info(` aft config: ${h.aftConfig.exists ? h.configPaths.aftConfig : "(not set)"}`);
|
|
11799
12040
|
if (h.aftConfig.parseError) {
|
|
11800
12041
|
O2.error(` aft config parse error: ${h.aftConfig.parseError}`);
|
|
12042
|
+
} else if (h.aftConfig.exists) {
|
|
12043
|
+
const { value } = readJsoncFile(h.configPaths.aftConfig);
|
|
12044
|
+
const schemaSet = value?.$schema === AFT_SCHEMA_URL;
|
|
12045
|
+
O2.info(` aft config $schema: ${schemaSet ? "set" : "not set — run `aft doctor --fix` for editor autocomplete"}`);
|
|
11801
12046
|
}
|
|
11802
12047
|
O2.info(` storage: ${formatDoctorStorageStatus(h)}`);
|
|
11803
12048
|
if (h.onnxRuntime.required) {
|
|
@@ -11904,7 +12149,7 @@ function clearOldBinaries() {
|
|
|
11904
12149
|
errors: [],
|
|
11905
12150
|
keptVersion: keepTag
|
|
11906
12151
|
};
|
|
11907
|
-
if (!
|
|
12152
|
+
if (!existsSync14(info.path)) {
|
|
11908
12153
|
O2.info(`Binary cache: nothing to clear at ${info.path}`);
|
|
11909
12154
|
return result;
|
|
11910
12155
|
}
|
|
@@ -11914,10 +12159,10 @@ function clearOldBinaries() {
|
|
|
11914
12159
|
return result;
|
|
11915
12160
|
}
|
|
11916
12161
|
for (const version of stale) {
|
|
11917
|
-
const dir =
|
|
12162
|
+
const dir = join12(info.path, version);
|
|
11918
12163
|
let bytes = 0;
|
|
11919
12164
|
try {
|
|
11920
|
-
bytes =
|
|
12165
|
+
bytes = statSync9(dir).isDirectory() ? dirSize(dir) : 0;
|
|
11921
12166
|
} catch {
|
|
11922
12167
|
bytes = 0;
|
|
11923
12168
|
}
|
|
@@ -11937,6 +12182,42 @@ function clearOldBinaries() {
|
|
|
11937
12182
|
}
|
|
11938
12183
|
return result;
|
|
11939
12184
|
}
|
|
12185
|
+
function findSchemaFixTargets(adapters) {
|
|
12186
|
+
const targets = [];
|
|
12187
|
+
for (const adapter of adapters) {
|
|
12188
|
+
if (!adapter.isInstalled())
|
|
12189
|
+
continue;
|
|
12190
|
+
let aftConfig;
|
|
12191
|
+
let aftConfigFormat;
|
|
12192
|
+
try {
|
|
12193
|
+
({ aftConfig, aftConfigFormat } = adapter.detectConfigPaths());
|
|
12194
|
+
} catch {
|
|
12195
|
+
continue;
|
|
12196
|
+
}
|
|
12197
|
+
const { value } = readJsoncFile(aftConfig);
|
|
12198
|
+
if (value?.$schema === AFT_SCHEMA_URL)
|
|
12199
|
+
continue;
|
|
12200
|
+
targets.push({ adapter, aftConfig, aftConfigFormat });
|
|
12201
|
+
}
|
|
12202
|
+
return targets;
|
|
12203
|
+
}
|
|
12204
|
+
function applySchemaFixes(targets) {
|
|
12205
|
+
let changed = 0;
|
|
12206
|
+
let errors = 0;
|
|
12207
|
+
for (const target of targets) {
|
|
12208
|
+
try {
|
|
12209
|
+
const result = ensureAftSchemaUrl(target.aftConfig, target.aftConfigFormat);
|
|
12210
|
+
if (result.action === "added" || result.action === "updated") {
|
|
12211
|
+
changed += 1;
|
|
12212
|
+
O2.success(`${target.adapter.displayName}: ${result.message}`);
|
|
12213
|
+
}
|
|
12214
|
+
} catch (error) {
|
|
12215
|
+
errors += 1;
|
|
12216
|
+
O2.warn(`${target.adapter.displayName}: could not set $schema on ${target.aftConfig}: ${error instanceof Error ? error.message : String(error)}`);
|
|
12217
|
+
}
|
|
12218
|
+
}
|
|
12219
|
+
return { changed, errors };
|
|
12220
|
+
}
|
|
11940
12221
|
function buildDoctorFixPlan(adapters, report) {
|
|
11941
12222
|
const items = [];
|
|
11942
12223
|
const adaptersByKind = new Map(adapters.map((adapter) => [adapter.kind, adapter]));
|
|
@@ -11984,6 +12265,12 @@ function buildDoctorFixPlan(adapters, report) {
|
|
|
11984
12265
|
});
|
|
11985
12266
|
}
|
|
11986
12267
|
}
|
|
12268
|
+
for (const target of findSchemaFixTargets(adapters)) {
|
|
12269
|
+
items.push({
|
|
12270
|
+
kind: "schema",
|
|
12271
|
+
message: `Will add the AFT config $schema URL to ${target.aftConfig} (editor autocomplete + validation)`
|
|
12272
|
+
});
|
|
12273
|
+
}
|
|
11987
12274
|
return items;
|
|
11988
12275
|
}
|
|
11989
12276
|
function shouldSkipDoctorFixConfirmation(argv) {
|
|
@@ -12022,7 +12309,7 @@ function logUnmatchedBinaryCandidates(expectedVersion) {
|
|
|
12022
12309
|
}
|
|
12023
12310
|
async function runFixFlow(argv) {
|
|
12024
12311
|
const adapters = await resolveAdaptersForCommand(argv, {
|
|
12025
|
-
allowMulti:
|
|
12312
|
+
allowMulti: false,
|
|
12026
12313
|
verb: "auto-fix issues for"
|
|
12027
12314
|
});
|
|
12028
12315
|
O2.info("Running diagnostics to identify auto-fixable issues…");
|
|
@@ -12044,6 +12331,7 @@ async function runFixFlow(argv) {
|
|
|
12044
12331
|
}
|
|
12045
12332
|
await fixPluginEntries(adapters);
|
|
12046
12333
|
const storageSummary = ensureStorageDirsForRegisteredPlugins(adapters);
|
|
12334
|
+
const schemaSummary = applySchemaFixes(findSchemaFixTargets(adapters));
|
|
12047
12335
|
let binaryDownloaded = false;
|
|
12048
12336
|
let binaryDownloadSkipped = false;
|
|
12049
12337
|
let binaryDownloadError = null;
|
|
@@ -12072,7 +12360,7 @@ async function runFixFlow(argv) {
|
|
|
12072
12360
|
}
|
|
12073
12361
|
}
|
|
12074
12362
|
const onnxResult = await runOnnxFix(adapters, report, { yes: true });
|
|
12075
|
-
if (onnxResult === null && !binaryDownloaded && !binaryDownloadSkipped && !binaryDownloadError && storageSummary.created === 0 && storageSummary.errors === 0) {
|
|
12363
|
+
if (onnxResult === null && !binaryDownloaded && !binaryDownloadSkipped && !binaryDownloadError && storageSummary.created === 0 && storageSummary.errors === 0 && schemaSummary.changed === 0 && schemaSummary.errors === 0) {
|
|
12076
12364
|
O2.info("No auto-fixable issues detected.");
|
|
12077
12365
|
wt("If you're still seeing 'Semantic Index: failed' in the TUI sidebar, run `aft doctor` (without --fix) for a full diagnostic dump.", "Tip");
|
|
12078
12366
|
const afterReport2 = await collectDiagnostics(adapters);
|
|
@@ -12080,7 +12368,7 @@ async function runFixFlow(argv) {
|
|
|
12080
12368
|
gt(stillHasProblems2 ? "Done — some issues remain." : "Done.");
|
|
12081
12369
|
return stillHasProblems2 ? 1 : 0;
|
|
12082
12370
|
}
|
|
12083
|
-
const hadErrors = (onnxResult?.errors.length ?? 0) > 0 || binaryDownloadError !== null || storageSummary.errors > 0;
|
|
12371
|
+
const hadErrors = (onnxResult?.errors.length ?? 0) > 0 || binaryDownloadError !== null || storageSummary.errors > 0 || schemaSummary.errors > 0;
|
|
12084
12372
|
const afterReport = await collectDiagnostics(adapters);
|
|
12085
12373
|
const stillHasProblems = hasDoctorProblems(afterReport);
|
|
12086
12374
|
gt(hadErrors ? "Done — some fixes failed." : stillHasProblems ? "Done — some issues remain." : "Done.");
|
|
@@ -12135,7 +12423,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
|
|
|
12135
12423
|
if (!adapter.isInstalled() || !adapter.hasPluginEntry())
|
|
12136
12424
|
continue;
|
|
12137
12425
|
const storageDir = adapter.getStorageDir();
|
|
12138
|
-
if (
|
|
12426
|
+
if (existsSync14(storageDir))
|
|
12139
12427
|
continue;
|
|
12140
12428
|
mkdirSync2(storageDir, { recursive: true });
|
|
12141
12429
|
summary.created += 1;
|
|
@@ -12238,11 +12526,11 @@ function deriveIssueTitleFromBody(body) {
|
|
|
12238
12526
|
function writeIssueReviewFile(body) {
|
|
12239
12527
|
let reviewDir = null;
|
|
12240
12528
|
try {
|
|
12241
|
-
reviewDir = mkdtempSync(
|
|
12529
|
+
reviewDir = mkdtempSync(join12(tmpdir2(), "aft-issue-"));
|
|
12242
12530
|
if (process.platform !== "win32") {
|
|
12243
12531
|
chmodSync(reviewDir, 448);
|
|
12244
12532
|
}
|
|
12245
|
-
const outPath =
|
|
12533
|
+
const outPath = join12(reviewDir, "issue.md");
|
|
12246
12534
|
writeFileSync2(outPath, `${body}
|
|
12247
12535
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
12248
12536
|
return { path: outPath, realPath: realpathSync3(outPath) };
|
|
@@ -12263,12 +12551,33 @@ function readReviewedIssueFile(reviewFile) {
|
|
|
12263
12551
|
O2.error(`Review file path changed before filing; refusing to read ${reviewFile.path}.`);
|
|
12264
12552
|
return null;
|
|
12265
12553
|
}
|
|
12266
|
-
return
|
|
12554
|
+
return readFileSync5(reviewFile.path, "utf8");
|
|
12267
12555
|
} catch (err) {
|
|
12268
12556
|
O2.error(`Failed to read reviewed issue report: ${err instanceof Error ? err.message : String(err)}`);
|
|
12269
12557
|
return null;
|
|
12270
12558
|
}
|
|
12271
12559
|
}
|
|
12560
|
+
async function promptForIssueSession(adapter) {
|
|
12561
|
+
const sessions = listRecentSessions(adapter);
|
|
12562
|
+
if (sessions.length === 0)
|
|
12563
|
+
return null;
|
|
12564
|
+
const allLogsValue = "__all__";
|
|
12565
|
+
const selected = await selectOne("Is this issue about a specific session?", [
|
|
12566
|
+
{ label: "General — not session-specific (include all logs)", value: allLogsValue },
|
|
12567
|
+
...sessions.map((session) => ({
|
|
12568
|
+
label: truncateTitle(session.title),
|
|
12569
|
+
value: session.id,
|
|
12570
|
+
hint: shortSessionId(session.id)
|
|
12571
|
+
}))
|
|
12572
|
+
]);
|
|
12573
|
+
if (selected === allLogsValue)
|
|
12574
|
+
return null;
|
|
12575
|
+
return sessions.find((session) => session.id === selected) ?? null;
|
|
12576
|
+
}
|
|
12577
|
+
function shortSessionId(id) {
|
|
12578
|
+
const bareId = id.replace(/^ses_/, "");
|
|
12579
|
+
return bareId.length <= 12 ? bareId : bareId.slice(0, 12);
|
|
12580
|
+
}
|
|
12272
12581
|
async function runIssueFlow(argv) {
|
|
12273
12582
|
mt("AFT doctor --issue");
|
|
12274
12583
|
if (!isInteractiveTerminal()) {
|
|
@@ -12277,28 +12586,33 @@ async function runIssueFlow(argv) {
|
|
|
12277
12586
|
return 0;
|
|
12278
12587
|
}
|
|
12279
12588
|
const adapters = await resolveAdaptersForCommand(argv, {
|
|
12280
|
-
allowMulti:
|
|
12589
|
+
allowMulti: false,
|
|
12281
12590
|
verb: "include in the issue"
|
|
12282
12591
|
});
|
|
12283
12592
|
const description = await text("Describe the problem you're running into:", {
|
|
12284
12593
|
placeholder: "What happened? What did you expect? Steps to reproduce…",
|
|
12285
12594
|
validate: (value) => value.trim().length === 0 ? "Please enter a short description." : undefined
|
|
12286
12595
|
});
|
|
12596
|
+
const selectedSession = await promptForIssueSession(adapters[0]);
|
|
12597
|
+
const selectedBareSessionId = selectedSession?.id.replace(/^ses_/, "") ?? null;
|
|
12287
12598
|
const report = await collectDiagnostics(adapters);
|
|
12288
12599
|
const logSections = adapters.map((adapter) => {
|
|
12289
12600
|
const path = adapter.getLogFile();
|
|
12290
12601
|
const tail = tailLogFile(path, 200);
|
|
12602
|
+
const scopedTail = selectedBareSessionId ? filterLogToSession(tail, selectedBareSessionId) : tail;
|
|
12291
12603
|
return `#### ${adapter.displayName} log (${path})
|
|
12292
12604
|
|
|
12293
12605
|
\`\`\`
|
|
12294
|
-
${
|
|
12606
|
+
${scopedTail || "<no log output>"}
|
|
12295
12607
|
\`\`\`
|
|
12296
12608
|
`;
|
|
12297
12609
|
}).join(`
|
|
12298
12610
|
`);
|
|
12299
12611
|
const errorScanWindow = adapters.map((adapter) => {
|
|
12300
12612
|
const path = adapter.getLogFile();
|
|
12301
|
-
|
|
12613
|
+
const tail = tailLogFile(path, 4000);
|
|
12614
|
+
const scopedTail = selectedBareSessionId ? filterLogToSession(tail, selectedBareSessionId) : tail;
|
|
12615
|
+
return sanitizeContent(scopedTail);
|
|
12302
12616
|
}).join(`
|
|
12303
12617
|
`);
|
|
12304
12618
|
const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
|
|
@@ -12314,6 +12628,7 @@ ${tail || "<no log output>"}
|
|
|
12314
12628
|
`- AFT binary: ${report.binaryVersion ?? "unknown"}`,
|
|
12315
12629
|
`- OS: ${report.platform} ${report.arch}`,
|
|
12316
12630
|
`- Node: ${report.nodeVersion}`,
|
|
12631
|
+
...selectedSession ? [`- Session: ses_${selectedBareSessionId} (${truncateTitle(selectedSession.title)})`] : [],
|
|
12317
12632
|
"",
|
|
12318
12633
|
"## Diagnostics",
|
|
12319
12634
|
renderDiagnosticsMarkdown(report),
|
|
@@ -12378,11 +12693,13 @@ var init_doctor = __esm(async () => {
|
|
|
12378
12693
|
init_github();
|
|
12379
12694
|
init_harness_select();
|
|
12380
12695
|
init_issue_body();
|
|
12696
|
+
init_jsonc();
|
|
12381
12697
|
init_lsp_cache();
|
|
12382
12698
|
init_onnx_fix();
|
|
12383
12699
|
init_prompts();
|
|
12384
12700
|
init_sanitize();
|
|
12385
12701
|
init_self_version();
|
|
12702
|
+
init_sessions();
|
|
12386
12703
|
await __promiseAll([
|
|
12387
12704
|
init_binary_probe(),
|
|
12388
12705
|
init_diagnostics()
|
|
@@ -12413,6 +12730,7 @@ function printHelp() {
|
|
|
12413
12730
|
console.log(" -------");
|
|
12414
12731
|
console.log("");
|
|
12415
12732
|
console.log(" Commands:");
|
|
12733
|
+
console.log(" --version Show CLI, binary, and per-harness plugin versions");
|
|
12416
12734
|
console.log(" setup Interactive setup wizard");
|
|
12417
12735
|
console.log(" doctor Check and fix configuration issues");
|
|
12418
12736
|
console.log(" doctor lsp <file> Inspect LSP setup for one file");
|
|
@@ -12434,6 +12752,10 @@ function printHelp() {
|
|
|
12434
12752
|
console.log("");
|
|
12435
12753
|
}
|
|
12436
12754
|
async function main() {
|
|
12755
|
+
if (command === "--version" || command === "-v" || command === "-V" || command === "version") {
|
|
12756
|
+
const { runVersion: runVersion2 } = await init_version().then(() => exports_version);
|
|
12757
|
+
return runVersion2();
|
|
12758
|
+
}
|
|
12437
12759
|
if (command === "setup") {
|
|
12438
12760
|
const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_setup(), exports_setup));
|
|
12439
12761
|
return runSetup2(args);
|