@cortexkit/aft-opencode 0.63.4 → 0.64.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/config-live-reload.d.ts +4 -16
- package/dist/config-live-reload.d.ts.map +1 -1
- package/dist/config.d.ts +11 -28
- package/dist/config.d.ts.map +1 -1
- package/dist/entry/server.js +774 -410
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +774 -410
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/shared/session-directory.d.ts +4 -2
- package/dist/shared/session-directory.d.ts.map +1 -1
- package/dist/shared/status.d.ts +0 -4
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/subc-tool-schemas.d.ts +4 -3
- package/dist/subc-tool-schemas.d.ts.map +1 -1
- package/dist/tools/_shared.d.ts +11 -17
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tools/bash_watch.d.ts +6 -3
- package/dist/tools/bash_watch.d.ts.map +1 -1
- package/dist/tools/definitions/v2.d.ts +25 -0
- package/dist/tools/definitions/v2.d.ts.map +1 -1
- package/dist/tools/inspect.d.ts +0 -15
- package/dist/tools/inspect.d.ts.map +1 -1
- package/dist/tui/preferences.d.ts +1 -1
- package/dist/tui/v2-status.d.ts +3 -2
- package/dist/tui/v2-status.d.ts.map +1 -1
- package/dist/v2-session-lifecycle.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/shared/session-directory.ts +10 -5
- package/src/shared/status.ts +2 -22
- package/src/tui/index.tsx +1 -25
- package/src/tui/preferences.ts +1 -1
- package/src/tui/sidebar-view.tsx +2 -39
- package/src/tui/v2-status.ts +5 -14
- package/src/tui-compiled/index.tsx +2 -41
- package/src/tui-compiled/preferences.ts +1 -1
- package/src/tui-compiled/sidebar-view.tsx +34 -72
- package/src/tui-compiled/v2-status.ts +5 -14
package/dist/index.js
CHANGED
|
@@ -9542,9 +9542,10 @@ var BASH_HOST_FALLBACK_BANNER = "[AFT host fallback - module transport down; no
|
|
|
9542
9542
|
var BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES = 100 * 1024;
|
|
9543
9543
|
var BASH_HOST_FALLBACK_MAX_TIMEOUT_MS = 10 * 60 * 1000;
|
|
9544
9544
|
var BASH_HOST_FALLBACK_REFUSAL = "AFT module connection is down";
|
|
9545
|
-
var
|
|
9546
|
-
var
|
|
9547
|
-
var
|
|
9545
|
+
var BASH_RUNON_MEMORY_DESCRIPTION = "On Linux, add `,Ngb` to ask for N GiB of memory, for example `linux,2c,16gb` for a Rust build.";
|
|
9546
|
+
var BASH_RUNON_DESCRIPTION = 'Run on a remote build server: `linux` (2 vCPUs), or `linux,Nc` for N vCPUs such as `linux,8c`; add ",net" for outbound internet (offline by default). `windows` runs the command in Git Bash on a Windows build machine (no vCPU or network options). `macos` sends the command to a macOS machine for builds and tests that need macOS (no vCPU or network options).' + ` ${BASH_RUNON_MEMORY_DESCRIPTION}`;
|
|
9547
|
+
var BASH_RETURN_PATHS_DESCRIPTION = "With runon: up to 64 files to copy back from the build server after the command, as paths relative to workdir inside the project (up to 128 MiB in total). Each verified file replaces the local file at the same path; the result lists every path as returned or not returned, with the reason.";
|
|
9548
|
+
var BASH_RUNON_GUIDANCE = 'When remote runs are available, put `runon: "linux"` on build and test lines (cargo, bun test), including chains and pipes. A runon job\'s file changes are not copied back; only output, the exit code and return_paths files return. Edit locally first; name a file in return_paths to regenerate it remotely. Keep git, gh, interactive and file-editing commands local, and keep a line local if it needs this machine\'s own operating system or hardware (its sandbox, code signing, service manager, permission prompts or GUI frameworks) or runs a binary that already exists on this machine; a build or test that needs only macOS (its sandbox, code signing or file watching) can use runon: "macos" instead; building and testing still go remote, and a remote build leaves no binaries or target/ output in the local worktree. Add `,Nc` to request N vCPUs (`linux,4c`); without it the job gets 2 vCPUs. The job sees exactly the CPUs it gets, so ask for what the command uses: 2c (the default) for a single test binary or script, 4c for `cargo check`/clippy on one crate, 8c for a workspace test suite, and 16c for a large release build.';
|
|
9548
9549
|
function pathKeyForPlatform(env, platform) {
|
|
9549
9550
|
return platform === "win32" ? Object.keys(env).find((key) => key.toLowerCase() === "path") : "PATH";
|
|
9550
9551
|
}
|
|
@@ -9799,6 +9800,7 @@ function bashAcksConfirmed(response, targets) {
|
|
|
9799
9800
|
}
|
|
9800
9801
|
// ../aft-bridge/dist/bash-permissions.js
|
|
9801
9802
|
var BASH_PERMISSION_NOT_SETTLED = "bash permission not settled after {rounds} rounds: still asking for {kind} {path} (operation: {operation}; granted already: {granted})";
|
|
9803
|
+
var BASH_PERMISSION_DENIED = "Permission denied for this shell command: {parts} ({host reason}). The parts are checked together, so one denied part denies the whole command; run the allowed parts in a separate call.";
|
|
9802
9804
|
|
|
9803
9805
|
class BashPermissionLoopError extends Error {
|
|
9804
9806
|
}
|
|
@@ -9833,6 +9835,10 @@ ${ask.command ?? ""}
|
|
|
9833
9835
|
Working directory:
|
|
9834
9836
|
${ask.cwd ?? ""}`;
|
|
9835
9837
|
}
|
|
9838
|
+
function permissionAskPath(ask) {
|
|
9839
|
+
const paths = ask.patterns?.length ? ask.patterns : bashPermissionRetryGrants(ask);
|
|
9840
|
+
return ask.kind === "escalation" && ask.command ? `${ask.command}${ask.cwd ? ` @ ${ask.cwd}` : ""}` : paths.length ? paths.join(", ") : "<no asks returned>";
|
|
9841
|
+
}
|
|
9836
9842
|
async function withBashPermissionLoop(options) {
|
|
9837
9843
|
const granted = new Set;
|
|
9838
9844
|
const alreadyGranted = (ask) => {
|
|
@@ -9854,20 +9860,22 @@ async function withBashPermissionLoop(options) {
|
|
|
9854
9860
|
already_granted: alreadyGranted(ask)
|
|
9855
9861
|
}))
|
|
9856
9862
|
});
|
|
9857
|
-
const unsettled = (
|
|
9863
|
+
const unsettled = () => {
|
|
9858
9864
|
const message = (asks.length ? asks : [{}]).map((ask) => {
|
|
9859
|
-
|
|
9860
|
-
const path = ask.kind === "escalation" && ask.command ? `${ask.command}${ask.cwd ? ` @ ${ask.cwd}` : ""}` : paths.length ? paths.join(", ") : "<no asks returned>";
|
|
9861
|
-
return BASH_PERMISSION_NOT_SETTLED.replace("{rounds}", String(round)).replace("{kind}", ask.kind ?? "unknown").replace("{operation}", ask.operation ?? options.operation ?? "bash").replace("{granted}", alreadyGranted(ask) ? "yes" : "no").replace("{path}", () => path);
|
|
9865
|
+
return BASH_PERMISSION_NOT_SETTLED.replace("{rounds}", String(round)).replace("{kind}", ask.kind ?? "unknown").replace("{operation}", ask.operation ?? options.operation ?? "bash").replace("{granted}", alreadyGranted(ask) ? "yes" : "no").replace("{path}", () => permissionAskPath(ask));
|
|
9862
9866
|
}).join("; ");
|
|
9863
|
-
return new BashPermissionLoopError(
|
|
9867
|
+
return new BashPermissionLoopError(message);
|
|
9864
9868
|
};
|
|
9865
9869
|
if (asks.length === 0 || asks.every(alreadyGranted) || round >= 8)
|
|
9866
9870
|
throw unsettled();
|
|
9871
|
+
const pendingAsks = asks.filter((ask) => !alreadyGranted(ask));
|
|
9867
9872
|
try {
|
|
9868
|
-
await options.approve(
|
|
9873
|
+
await options.approve(pendingAsks);
|
|
9869
9874
|
} catch (error) {
|
|
9870
|
-
|
|
9875
|
+
const parts = pendingAsks.map(permissionAskPath).join(", ");
|
|
9876
|
+
const reason = error instanceof Error && error.message ? error.message.trim().replace(/\.$/, "") : "";
|
|
9877
|
+
const message = reason ? BASH_PERMISSION_DENIED.replace("{host reason}", () => reason) : BASH_PERMISSION_DENIED.replace(" ({host reason})", "");
|
|
9878
|
+
throw new BashPermissionLoopError(message.replace("{parts}", () => parts), { cause: error });
|
|
9871
9879
|
}
|
|
9872
9880
|
for (const ask of asks) {
|
|
9873
9881
|
for (const grant of bashPermissionRetryGrants(ask))
|
|
@@ -12111,8 +12119,9 @@ function formatDroppedKeyWarnings(dropped) {
|
|
|
12111
12119
|
return dropped.map((item) => `Ignoring ${item.key} from ${item.tier} config (${item.reason})`);
|
|
12112
12120
|
}
|
|
12113
12121
|
// ../aft-bridge/dist/config-watch.js
|
|
12114
|
-
import {
|
|
12115
|
-
import {
|
|
12122
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
12123
|
+
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readFileSync as readFileSync3, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync3, watch } from "node:fs";
|
|
12124
|
+
import { basename, dirname as dirname2, resolve as resolve5 } from "node:path";
|
|
12116
12125
|
var CONFIG_WATCH_DEBOUNCE_MS = 150;
|
|
12117
12126
|
var CONFIG_LIVE_KEEP_NOTE = "AFT keeps using the last valid configuration until the file is fixed.";
|
|
12118
12127
|
function pathKey(name) {
|
|
@@ -12166,7 +12175,6 @@ function aftLiveConfigKeys(resolveBash) {
|
|
|
12166
12175
|
pathKey("restrict_to_project_root"),
|
|
12167
12176
|
pathKey("revision_reads"),
|
|
12168
12177
|
pathKey("inspect.diagnostics_timeout_ms"),
|
|
12169
|
-
pathKey("inspect.tier2_idle_minutes"),
|
|
12170
12178
|
pathKey("lsp.idle_minutes"),
|
|
12171
12179
|
...[
|
|
12172
12180
|
"diagnostics",
|
|
@@ -12238,6 +12246,29 @@ function readTextOrNull(path) {
|
|
|
12238
12246
|
var CONFIG_WATCH_REVALIDATE_MS = 2000;
|
|
12239
12247
|
var CONFIG_WATCH_REJECTED_RETRIES = 3;
|
|
12240
12248
|
var CONFIG_WATCH_MAX_DELAY_MS = 1000;
|
|
12249
|
+
var CONFIG_READ_LIMIT = 1024 * 1024;
|
|
12250
|
+
function contentFingerprint(path) {
|
|
12251
|
+
let fd;
|
|
12252
|
+
try {
|
|
12253
|
+
fd = openSync2(path, "r");
|
|
12254
|
+
const metadata = fstatSync(fd, { bigint: true });
|
|
12255
|
+
const bytes = Buffer.alloc(Math.min(Number(metadata.size), CONFIG_READ_LIMIT));
|
|
12256
|
+
let offset = 0;
|
|
12257
|
+
while (offset < bytes.length) {
|
|
12258
|
+
const read = readSync2(fd, bytes, offset, bytes.length - offset, null);
|
|
12259
|
+
if (read === 0)
|
|
12260
|
+
break;
|
|
12261
|
+
offset += read;
|
|
12262
|
+
}
|
|
12263
|
+
const hash = createHash2("sha256").update(bytes.subarray(0, offset)).digest("hex");
|
|
12264
|
+
return `${metadata.size}:${metadata.mtimeNs}:${hash}`;
|
|
12265
|
+
} catch {
|
|
12266
|
+
return null;
|
|
12267
|
+
} finally {
|
|
12268
|
+
if (fd !== undefined)
|
|
12269
|
+
closeSync2(fd);
|
|
12270
|
+
}
|
|
12271
|
+
}
|
|
12241
12272
|
function identityOf(dir) {
|
|
12242
12273
|
try {
|
|
12243
12274
|
const stat = statSync3(dir, { bigint: true });
|
|
@@ -12253,6 +12284,13 @@ function watchDirFor(file) {
|
|
|
12253
12284
|
dir = dirname2(dir);
|
|
12254
12285
|
return dir;
|
|
12255
12286
|
}
|
|
12287
|
+
function canonicalDirectory(dir) {
|
|
12288
|
+
try {
|
|
12289
|
+
return realpathSync2(dir);
|
|
12290
|
+
} catch {
|
|
12291
|
+
return resolve5(dir);
|
|
12292
|
+
}
|
|
12293
|
+
}
|
|
12256
12294
|
function watchAftConfigFiles(options) {
|
|
12257
12295
|
const debounceMs = options.debounceMs ?? CONFIG_WATCH_DEBOUNCE_MS;
|
|
12258
12296
|
const lastSeen = new Map;
|
|
@@ -12266,6 +12304,8 @@ function watchAftConfigFiles(options) {
|
|
|
12266
12304
|
let firstPendingAt = null;
|
|
12267
12305
|
let stopped = false;
|
|
12268
12306
|
const watchers = new Map;
|
|
12307
|
+
const targets = new Map;
|
|
12308
|
+
const fallbackSeen = new Map;
|
|
12269
12309
|
const watchImpl = options.watchImpl ?? watch;
|
|
12270
12310
|
let rejectedRetries = 0;
|
|
12271
12311
|
const check = () => {
|
|
@@ -12319,8 +12359,34 @@ function watchAftConfigFiles(options) {
|
|
|
12319
12359
|
timer.unref?.();
|
|
12320
12360
|
};
|
|
12321
12361
|
function revalidate() {
|
|
12322
|
-
const wanted = new Set
|
|
12362
|
+
const wanted = new Set;
|
|
12363
|
+
const wantedCanonical = new Set;
|
|
12364
|
+
const wantDirectory = (dir) => {
|
|
12365
|
+
const canonical = canonicalDirectory(dir);
|
|
12366
|
+
if (wantedCanonical.has(canonical))
|
|
12367
|
+
return;
|
|
12368
|
+
wantedCanonical.add(canonical);
|
|
12369
|
+
wanted.add(dir);
|
|
12370
|
+
};
|
|
12371
|
+
for (const path of options.paths)
|
|
12372
|
+
wantDirectory(watchDirFor(path));
|
|
12323
12373
|
let moved = false;
|
|
12374
|
+
for (const path of options.paths) {
|
|
12375
|
+
try {
|
|
12376
|
+
const resolved = realpathSync2(path);
|
|
12377
|
+
const target = resolved === resolve5(path) ? undefined : resolved;
|
|
12378
|
+
if (targets.get(path) !== target) {
|
|
12379
|
+
if (target)
|
|
12380
|
+
targets.set(path, target);
|
|
12381
|
+
else
|
|
12382
|
+
targets.delete(path);
|
|
12383
|
+
fallbackSeen.delete(path);
|
|
12384
|
+
moved = true;
|
|
12385
|
+
}
|
|
12386
|
+
} catch {}
|
|
12387
|
+
}
|
|
12388
|
+
for (const target of targets.values())
|
|
12389
|
+
wantDirectory(watchDirFor(target));
|
|
12324
12390
|
for (const [dir, entry] of watchers) {
|
|
12325
12391
|
if (!wanted.has(dir) || entry.stale || identityOf(dir) !== entry.identity) {
|
|
12326
12392
|
entry.watcher.close();
|
|
@@ -12359,6 +12425,17 @@ function watchAftConfigFiles(options) {
|
|
|
12359
12425
|
moved = true;
|
|
12360
12426
|
} catch {}
|
|
12361
12427
|
}
|
|
12428
|
+
const watchedCanonical = new Set(Array.from(watchers.keys(), canonicalDirectory));
|
|
12429
|
+
for (const [path, target] of targets) {
|
|
12430
|
+
if (watchedCanonical.has(canonicalDirectory(dirname2(target)))) {
|
|
12431
|
+
fallbackSeen.delete(path);
|
|
12432
|
+
continue;
|
|
12433
|
+
}
|
|
12434
|
+
const fingerprint = contentFingerprint(path);
|
|
12435
|
+
if (!fallbackSeen.has(path) || fallbackSeen.get(path) !== fingerprint)
|
|
12436
|
+
moved = true;
|
|
12437
|
+
fallbackSeen.set(path, fingerprint);
|
|
12438
|
+
}
|
|
12362
12439
|
return moved;
|
|
12363
12440
|
}
|
|
12364
12441
|
revalidate();
|
|
@@ -12515,8 +12592,8 @@ function startLiveConfigReload(options) {
|
|
|
12515
12592
|
return { reload, stop };
|
|
12516
12593
|
}
|
|
12517
12594
|
// ../aft-bridge/dist/downloader.js
|
|
12518
|
-
import { createHash as
|
|
12519
|
-
import { chmodSync, closeSync as
|
|
12595
|
+
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
12596
|
+
import { chmodSync, closeSync as closeSync3, copyFileSync, createWriteStream, existsSync as existsSync3, mkdirSync as mkdirSync2, openSync as openSync3, readdirSync, readFileSync as readFileSync4, renameSync as renameSync2, rmSync, statSync as statSync4, unlinkSync as unlinkSync2, writeSync } from "node:fs";
|
|
12520
12597
|
import { hostname } from "node:os";
|
|
12521
12598
|
import { join as join8 } from "node:path";
|
|
12522
12599
|
import { Readable } from "node:stream";
|
|
@@ -12734,7 +12811,7 @@ async function downloadBinary(version) {
|
|
|
12734
12811
|
warn(`Checksum verification failed: checksums.sha256 found but no entry for ${assetName}. ` + "Binary download aborted for security reasons.");
|
|
12735
12812
|
return null;
|
|
12736
12813
|
}
|
|
12737
|
-
const hash =
|
|
12814
|
+
const hash = createHash3("sha256");
|
|
12738
12815
|
let bytesWritten = 0;
|
|
12739
12816
|
const guard = new TransformStream({
|
|
12740
12817
|
transform(chunk, controller) {
|
|
@@ -12901,11 +12978,11 @@ async function acquireDownloadLock(lockPath, timing = {}) {
|
|
|
12901
12978
|
while (true) {
|
|
12902
12979
|
try {
|
|
12903
12980
|
const owner = createDownloadLockOwner();
|
|
12904
|
-
const fd =
|
|
12981
|
+
const fd = openSync3(lockPath, "wx");
|
|
12905
12982
|
try {
|
|
12906
12983
|
writeSync(fd, owner);
|
|
12907
12984
|
} finally {
|
|
12908
|
-
|
|
12985
|
+
closeSync3(fd);
|
|
12909
12986
|
}
|
|
12910
12987
|
return () => {
|
|
12911
12988
|
try {
|
|
@@ -12976,8 +13053,8 @@ import { appendFile, lstat, mkdir, open, rename, rm, stat } from "node:fs/promis
|
|
|
12976
13053
|
import { dirname as dirname3 } from "node:path";
|
|
12977
13054
|
|
|
12978
13055
|
// ../aft-bridge/dist/private-storage.js
|
|
12979
|
-
import { closeSync as
|
|
12980
|
-
import { isAbsolute as isAbsolute4, join as join9, parse, relative as relative3, resolve as
|
|
13056
|
+
import { closeSync as closeSync4, constants, copyFileSync as copyFileSync2, fchmodSync, fstatSync as fstatSync2, lstatSync, mkdirSync as mkdirSync3, openSync as openSync4, readSync as readSync3, writeSync as writeSync2 } from "node:fs";
|
|
13057
|
+
import { isAbsolute as isAbsolute4, join as join9, parse, relative as relative3, resolve as resolve6, sep } from "node:path";
|
|
12981
13058
|
var PRIVATE_FILE_MODE = 384;
|
|
12982
13059
|
var PRIVATE_DIRECTORY_MODE = 448;
|
|
12983
13060
|
function privateMkdirSync(path, recursive = true) {
|
|
@@ -12991,13 +13068,13 @@ function privateCopyFileSync(source, destination) {
|
|
|
12991
13068
|
copyFileSync2(source, destination);
|
|
12992
13069
|
return;
|
|
12993
13070
|
}
|
|
12994
|
-
const input =
|
|
13071
|
+
const input = openSync4(source, "r");
|
|
12995
13072
|
let output;
|
|
12996
13073
|
try {
|
|
12997
|
-
output =
|
|
13074
|
+
output = openSync4(destination, "wx", PRIVATE_FILE_MODE);
|
|
12998
13075
|
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
12999
13076
|
for (;; ) {
|
|
13000
|
-
const bytes =
|
|
13077
|
+
const bytes = readSync3(input, buffer);
|
|
13001
13078
|
if (bytes === 0)
|
|
13002
13079
|
break;
|
|
13003
13080
|
let offset = 0;
|
|
@@ -13005,18 +13082,18 @@ function privateCopyFileSync(source, destination) {
|
|
|
13005
13082
|
offset += writeSync2(output, buffer, offset, bytes - offset);
|
|
13006
13083
|
}
|
|
13007
13084
|
} finally {
|
|
13008
|
-
|
|
13085
|
+
closeSync4(input);
|
|
13009
13086
|
if (output !== undefined)
|
|
13010
|
-
|
|
13087
|
+
closeSync4(output);
|
|
13011
13088
|
}
|
|
13012
13089
|
}
|
|
13013
13090
|
var warned = new Set;
|
|
13014
13091
|
function openPrivateStorageDir(root, path = root) {
|
|
13015
|
-
const base =
|
|
13092
|
+
const base = resolve6(root);
|
|
13016
13093
|
if (!root || base === parse(base).root) {
|
|
13017
13094
|
throw new Error(`refusing filesystem root as private storage: ${base}`);
|
|
13018
13095
|
}
|
|
13019
|
-
const rel = relative3(base,
|
|
13096
|
+
const rel = relative3(base, resolve6(path));
|
|
13020
13097
|
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute4(rel))
|
|
13021
13098
|
return;
|
|
13022
13099
|
privateMkdirSync(path);
|
|
@@ -13029,8 +13106,8 @@ function openPrivateStorageDir(root, path = root) {
|
|
|
13029
13106
|
try {
|
|
13030
13107
|
if (lstatSync(current).isSymbolicLink())
|
|
13031
13108
|
return;
|
|
13032
|
-
fd =
|
|
13033
|
-
if ((
|
|
13109
|
+
fd = openSync4(current, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
13110
|
+
if ((fstatSync2(fd).mode & 63) !== 0)
|
|
13034
13111
|
fchmodSync(fd, PRIVATE_DIRECTORY_MODE);
|
|
13035
13112
|
} catch (error) {
|
|
13036
13113
|
if (!warned.has(current)) {
|
|
@@ -13041,7 +13118,7 @@ function openPrivateStorageDir(root, path = root) {
|
|
|
13041
13118
|
return;
|
|
13042
13119
|
} finally {
|
|
13043
13120
|
if (fd !== undefined)
|
|
13044
|
-
|
|
13121
|
+
closeSync4(fd);
|
|
13045
13122
|
}
|
|
13046
13123
|
}
|
|
13047
13124
|
}
|
|
@@ -13864,7 +13941,7 @@ async function readConnectionFileForUid(path, expectedUid) {
|
|
|
13864
13941
|
}
|
|
13865
13942
|
|
|
13866
13943
|
// ../../node_modules/.bun/@cortexkit+subc-client@0.21.2/node_modules/@cortexkit/subc-client/dist/launch-nonce.js
|
|
13867
|
-
import { closeSync as
|
|
13944
|
+
import { closeSync as closeSync5, fstatSync as fstatSync3, readSync as readSync4 } from "node:fs";
|
|
13868
13945
|
var SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE";
|
|
13869
13946
|
var SUBC_LAUNCH_NONCE_FD_ENV = "SUBC_LAUNCH_NONCE_FD";
|
|
13870
13947
|
class LaunchNonceError extends Error {
|
|
@@ -13911,7 +13988,7 @@ class LaunchNonceCell {
|
|
|
13911
13988
|
lookup;
|
|
13912
13989
|
platform;
|
|
13913
13990
|
stat;
|
|
13914
|
-
constructor(lookup, platform = process.platform, stat = (fd) =>
|
|
13991
|
+
constructor(lookup, platform = process.platform, stat = (fd) => fstatSync3(fd, { bigint: true })) {
|
|
13915
13992
|
this.lookup = lookup;
|
|
13916
13993
|
this.platform = platform;
|
|
13917
13994
|
this.stat = stat;
|
|
@@ -13959,7 +14036,7 @@ class LaunchNonceCell {
|
|
|
13959
14036
|
const chunk = Buffer.alloc(256);
|
|
13960
14037
|
let got;
|
|
13961
14038
|
try {
|
|
13962
|
-
got =
|
|
14039
|
+
got = readSync4(fd, chunk, 0, chunk.length, null);
|
|
13963
14040
|
} catch (error) {
|
|
13964
14041
|
if (isWouldBlock(error))
|
|
13965
14042
|
throw emptyError(fd);
|
|
@@ -13971,7 +14048,7 @@ class LaunchNonceCell {
|
|
|
13971
14048
|
const parts = [Buffer.from(chunk.subarray(0, got))];
|
|
13972
14049
|
try {
|
|
13973
14050
|
for (;; ) {
|
|
13974
|
-
const n =
|
|
14051
|
+
const n = readSync4(fd, chunk, 0, chunk.length, null);
|
|
13975
14052
|
if (n === 0)
|
|
13976
14053
|
break;
|
|
13977
14054
|
parts.push(Buffer.from(chunk.subarray(0, n)));
|
|
@@ -14048,7 +14125,7 @@ function errnoOf(error) {
|
|
|
14048
14125
|
}
|
|
14049
14126
|
function closeQuietly(fd) {
|
|
14050
14127
|
try {
|
|
14051
|
-
|
|
14128
|
+
closeSync5(fd);
|
|
14052
14129
|
} catch {}
|
|
14053
14130
|
}
|
|
14054
14131
|
|
|
@@ -15923,16 +16000,16 @@ function getLifecycleRegistry() {
|
|
|
15923
16000
|
}
|
|
15924
16001
|
|
|
15925
16002
|
// ../aft-bridge/dist/project-identity.js
|
|
15926
|
-
import { createHash as
|
|
15927
|
-
import { realpathSync as
|
|
15928
|
-
import { posix as posix2, resolve as
|
|
16003
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
16004
|
+
import { realpathSync as realpathSync3 } from "node:fs";
|
|
16005
|
+
import { posix as posix2, resolve as resolve7, win32 as win322 } from "node:path";
|
|
15929
16006
|
function canonicalizeProjectRoot(dir) {
|
|
15930
16007
|
const trimmed = trimProjectRootSeparators(dir);
|
|
15931
16008
|
let canonical;
|
|
15932
16009
|
try {
|
|
15933
|
-
canonical =
|
|
16010
|
+
canonical = realpathSync3(trimmed);
|
|
15934
16011
|
} catch {
|
|
15935
|
-
canonical =
|
|
16012
|
+
canonical = resolve7(trimmed);
|
|
15936
16013
|
}
|
|
15937
16014
|
return normalizeWindowsRoot(canonical);
|
|
15938
16015
|
}
|
|
@@ -15972,7 +16049,7 @@ function hasDotComponent(path) {
|
|
|
15972
16049
|
return path.split(/[\\/]/).some((component) => component === "." || component === "..");
|
|
15973
16050
|
}
|
|
15974
16051
|
function projectRootKeyHash(dir) {
|
|
15975
|
-
return
|
|
16052
|
+
return createHash4("sha256").update(canonicalizeProjectRoot(dir)).digest("hex").slice(0, 16);
|
|
15976
16053
|
}
|
|
15977
16054
|
|
|
15978
16055
|
// ../aft-bridge/dist/subc-transport.js
|
|
@@ -17915,7 +17992,9 @@ class SubcTransportPool {
|
|
|
17915
17992
|
});
|
|
17916
17993
|
retry = state.bindPending;
|
|
17917
17994
|
} else {
|
|
17918
|
-
retry = this.hostScope(client, record.identity)
|
|
17995
|
+
retry = this.hostScope(client, record.identity).finally(() => {
|
|
17996
|
+
this.scheduleHostScopeRetry(session, state);
|
|
17997
|
+
});
|
|
17919
17998
|
}
|
|
17920
17999
|
retry.catch((error) => {
|
|
17921
18000
|
warn(`subc head scope: session=${session} background retry failed code=${error instanceof Error ? error.name : "Error"}`);
|
|
@@ -18083,12 +18162,18 @@ class SubcTransportPool {
|
|
|
18083
18162
|
}
|
|
18084
18163
|
return this.openScopedHostToolRoute(client, identity, record, entry, channel);
|
|
18085
18164
|
}
|
|
18086
|
-
bindHostToolRoute(client, identity, channel, reason, scope) {
|
|
18165
|
+
async bindHostToolRoute(client, identity, channel, reason, scope) {
|
|
18087
18166
|
log(`subc head scope: session=${identity.session} bind=${scope ? "scoped" : "unscoped"} channel=${channel} root=${identity.project_root} reason=${reason}` + (scope ? ` ref=${scope.ref.slice(0, 8)} epoch=${scope.scopeEpoch}` : ""));
|
|
18088
|
-
|
|
18167
|
+
const route = await client.routeOpen({ kind: "tool_provider", module_id: AFT_MODULE_ID }, identity, {
|
|
18089
18168
|
consumerIdentity: this.consumerIdentity,
|
|
18090
18169
|
...scope ? { scope } : {}
|
|
18091
18170
|
});
|
|
18171
|
+
const state = this.hostScopeCache.get(identity.session);
|
|
18172
|
+
if (scope && state?.unscopedReason && state.answer?.result === "scope" && state.answer.scope === scope) {
|
|
18173
|
+
log(`subc head scope: session=${identity.session} route=upgraded from=unscoped ref=${scope.ref.slice(0, 8)} epoch=${scope.scopeEpoch}`);
|
|
18174
|
+
state.unscopedReason = undefined;
|
|
18175
|
+
}
|
|
18176
|
+
return route;
|
|
18092
18177
|
}
|
|
18093
18178
|
async openScopedHostToolRoute(client, identity, record, entry, channel = "tool") {
|
|
18094
18179
|
const decision = await this.hostScope(client, identity);
|
|
@@ -18720,7 +18805,8 @@ function taskIdFromError(error) {
|
|
|
18720
18805
|
return;
|
|
18721
18806
|
}
|
|
18722
18807
|
// ../aft-bridge/dist/feature-config.js
|
|
18723
|
-
import { createHash as
|
|
18808
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
18809
|
+
import { createRequire } from "node:module";
|
|
18724
18810
|
var CANONICAL_TOOLS = [
|
|
18725
18811
|
"aft_callgraph",
|
|
18726
18812
|
"aft_conflicts",
|
|
@@ -18770,23 +18856,114 @@ var REMOVED_OPENCODE_PATHS = [
|
|
|
18770
18856
|
"opencode.server_url",
|
|
18771
18857
|
"opencode.server_password_env"
|
|
18772
18858
|
];
|
|
18773
|
-
|
|
18859
|
+
var REMOVED_DATA_LAYER_PATHS = [
|
|
18860
|
+
"views.callgraph_copies",
|
|
18861
|
+
"views.enabled",
|
|
18862
|
+
"worktree.ram_overlay"
|
|
18863
|
+
];
|
|
18864
|
+
var RETIRED_IDLE_CHECKOUT_HOURS = [
|
|
18865
|
+
"views.idle_checkout_hours",
|
|
18866
|
+
"idle.checkout_hours"
|
|
18867
|
+
];
|
|
18868
|
+
var DATA_LAYER_KEYS_REFUSED_FROM = [0, 65];
|
|
18869
|
+
var DATA_LAYER_RETIRED_PATHS = [
|
|
18870
|
+
"views.callgraph_copies",
|
|
18871
|
+
"views.enabled",
|
|
18872
|
+
"views.idle_checkout_hours",
|
|
18873
|
+
"worktree.ram_overlay"
|
|
18874
|
+
];
|
|
18875
|
+
var IDLE_CHECKOUT_HOURS_DEFAULT = 168;
|
|
18876
|
+
var IDLE_CHECKOUT_HOURS_MIN = 1;
|
|
18877
|
+
var IDLE_CHECKOUT_HOURS_MAX = 24 * 365;
|
|
18878
|
+
function parseRelease(version) {
|
|
18879
|
+
const match = /^(\d+)\.(\d+)(?:\.|$)/.exec(version);
|
|
18880
|
+
return match ? [Number(match[1]), Number(match[2])] : undefined;
|
|
18881
|
+
}
|
|
18882
|
+
var AFT_PACKAGE_NAMES = new Set([
|
|
18883
|
+
"@cortexkit/aft-bridge",
|
|
18884
|
+
"@cortexkit/aft-opencode",
|
|
18885
|
+
"@cortexkit/aft-pi",
|
|
18886
|
+
"@cortexkit/aft"
|
|
18887
|
+
]);
|
|
18888
|
+
function readRunningRelease() {
|
|
18889
|
+
const req = createRequire(import.meta.url);
|
|
18890
|
+
for (const candidate of ["../package.json", "../../package.json", "../../../package.json"]) {
|
|
18891
|
+
try {
|
|
18892
|
+
const manifest = req(candidate);
|
|
18893
|
+
if (manifest.name && AFT_PACKAGE_NAMES.has(manifest.name) && manifest.version) {
|
|
18894
|
+
return parseRelease(manifest.version) ?? [0, 0];
|
|
18895
|
+
}
|
|
18896
|
+
} catch {}
|
|
18897
|
+
}
|
|
18898
|
+
return [0, 0];
|
|
18899
|
+
}
|
|
18900
|
+
var runningRelease;
|
|
18901
|
+
function getRunningRelease() {
|
|
18902
|
+
runningRelease ??= readRunningRelease();
|
|
18903
|
+
return runningRelease;
|
|
18904
|
+
}
|
|
18905
|
+
function releaseAtLeast(release, floor) {
|
|
18906
|
+
return release[0] !== floor[0] ? release[0] > floor[0] : release[1] >= floor[1];
|
|
18907
|
+
}
|
|
18908
|
+
function refusedFromVersion() {
|
|
18909
|
+
return `${DATA_LAYER_KEYS_REFUSED_FROM[0]}.${DATA_LAYER_KEYS_REFUSED_FROM[1]}.0`;
|
|
18910
|
+
}
|
|
18911
|
+
function removedConfigKeyErrors(value, release = getRunningRelease(), refuseRetired = true) {
|
|
18774
18912
|
if (!isRecord2(value))
|
|
18775
18913
|
return [];
|
|
18776
|
-
const errors =
|
|
18914
|
+
const errors = removedBlockKeyErrors(value, release, refuseRetired);
|
|
18777
18915
|
if (isRecord2(value.harnesses)) {
|
|
18778
18916
|
for (const [name, block] of Object.entries(value.harnesses)) {
|
|
18779
18917
|
if (!isRecord2(block))
|
|
18780
18918
|
continue;
|
|
18781
|
-
for (const error of
|
|
18919
|
+
for (const error of removedBlockKeyErrors(block, release, refuseRetired)) {
|
|
18782
18920
|
errors.push(error.replace("removed_config_key:", `removed_config_key:harnesses.${name}.`));
|
|
18783
18921
|
}
|
|
18784
18922
|
}
|
|
18785
18923
|
}
|
|
18786
18924
|
return errors;
|
|
18787
18925
|
}
|
|
18788
|
-
function
|
|
18789
|
-
|
|
18926
|
+
function removedBlockKeyErrors(value, release, refuseRetired) {
|
|
18927
|
+
const paths = REMOVED_OPENCODE_PATHS.filter((path) => hasPath(value, path));
|
|
18928
|
+
if (refuseRetired)
|
|
18929
|
+
paths.push(...refusedRetiredNames(value));
|
|
18930
|
+
if (releaseAtLeast(release, DATA_LAYER_KEYS_REFUSED_FROM))
|
|
18931
|
+
paths.push(...DATA_LAYER_RETIRED_PATHS.filter((path) => hasPath(value, path)));
|
|
18932
|
+
return paths.map((path) => `removed_config_key:${path}; run npx @cortexkit/aft doctor --fix`);
|
|
18933
|
+
}
|
|
18934
|
+
var REFUSED_RETIRED_PATHS = [
|
|
18935
|
+
"sandbox.enabled",
|
|
18936
|
+
"tool_surface",
|
|
18937
|
+
"hoist_builtin_tools",
|
|
18938
|
+
"enabled",
|
|
18939
|
+
"search_index",
|
|
18940
|
+
"experimental_search_index",
|
|
18941
|
+
"semantic_search",
|
|
18942
|
+
"experimental_semantic_search",
|
|
18943
|
+
"callgraph_store",
|
|
18944
|
+
"github.enabled",
|
|
18945
|
+
"gh_read",
|
|
18946
|
+
"gh_shim.enabled",
|
|
18947
|
+
"experimental_lsp_ty",
|
|
18948
|
+
"experimental_bash_rewrite",
|
|
18949
|
+
"experimental_bash_compress",
|
|
18950
|
+
"experimental_bash_background",
|
|
18951
|
+
"experimental.bash",
|
|
18952
|
+
"idle.lsp_ttl_minutes",
|
|
18953
|
+
"inspect.tier2_soft_deadline_ms",
|
|
18954
|
+
"inspect.max_drill_down_items"
|
|
18955
|
+
];
|
|
18956
|
+
function refusedRetiredNames(block) {
|
|
18957
|
+
const names = REFUSED_RETIRED_PATHS.filter((path) => hasPath(block, path));
|
|
18958
|
+
if (Array.isArray(block.disabled_tools)) {
|
|
18959
|
+
for (const name of block.disabled_tools) {
|
|
18960
|
+
if (typeof name !== "string" || !Object.hasOwn(LEGACY_TOOL_ALIASES, name))
|
|
18961
|
+
continue;
|
|
18962
|
+
if (!names.includes(name))
|
|
18963
|
+
names.push(name);
|
|
18964
|
+
}
|
|
18965
|
+
}
|
|
18966
|
+
return names;
|
|
18790
18967
|
}
|
|
18791
18968
|
var RETIRED_PATHS = [
|
|
18792
18969
|
["sandbox.enabled", "sandbox.profile"],
|
|
@@ -18935,7 +19112,10 @@ function translateInspectLspPaths(map, prefix, out) {
|
|
|
18935
19112
|
recordRetired(out, prefix, `inspect.${leaf}`);
|
|
18936
19113
|
}
|
|
18937
19114
|
}
|
|
18938
|
-
var REMOVED_NO_EFFECT_PATHS = [
|
|
19115
|
+
var REMOVED_NO_EFFECT_PATHS = [
|
|
19116
|
+
"bridge.hang_threshold",
|
|
19117
|
+
"inspect.tier2_idle_minutes"
|
|
19118
|
+
];
|
|
18939
19119
|
function dropNoEffectPaths(map, prefix, out) {
|
|
18940
19120
|
for (const path of REMOVED_NO_EFFECT_PATHS) {
|
|
18941
19121
|
const [container, leaf] = path.split(".");
|
|
@@ -18944,6 +19124,29 @@ function dropNoEffectPaths(map, prefix, out) {
|
|
|
18944
19124
|
}
|
|
18945
19125
|
}
|
|
18946
19126
|
}
|
|
19127
|
+
function retiredIdleCheckoutHours(value) {
|
|
19128
|
+
const raw = typeof value === "number" && Number.isSafeInteger(value) ? value : IDLE_CHECKOUT_HOURS_DEFAULT;
|
|
19129
|
+
return Math.min(IDLE_CHECKOUT_HOURS_MAX, Math.max(IDLE_CHECKOUT_HOURS_MIN, raw));
|
|
19130
|
+
}
|
|
19131
|
+
function translateDataLayerPaths(map, prefix, out) {
|
|
19132
|
+
const [retired, replacement] = RETIRED_IDLE_CHECKOUT_HOURS;
|
|
19133
|
+
const hours = takeNested(map, "views", "idle_checkout_hours");
|
|
19134
|
+
if (hours.found) {
|
|
19135
|
+
recordRetired(out, prefix, retired);
|
|
19136
|
+
if (isRecord2(map.idle) && map.idle.checkout_hours !== undefined) {
|
|
19137
|
+
superseded(out, `${prefix}${retired}`, `${retired} is ignored because ${replacement} is set`);
|
|
19138
|
+
} else {
|
|
19139
|
+
if (!Object.hasOwn(map, "idle"))
|
|
19140
|
+
map.idle = {};
|
|
19141
|
+
if (isRecord2(map.idle))
|
|
19142
|
+
map.idle.checkout_hours = retiredIdleCheckoutHours(hours.value);
|
|
19143
|
+
}
|
|
19144
|
+
}
|
|
19145
|
+
for (const path of REMOVED_DATA_LAYER_PATHS) {
|
|
19146
|
+
if (hasPath(map, path))
|
|
19147
|
+
out.removedKeys.push(`${prefix}${path}`);
|
|
19148
|
+
}
|
|
19149
|
+
}
|
|
18947
19150
|
function translateExperimentalPaths(map, prefix, out) {
|
|
18948
19151
|
for (const [oldKey, leaf] of [
|
|
18949
19152
|
["experimental_lsp_ty", "lsp_ty"],
|
|
@@ -18976,23 +19179,25 @@ function translateExperimentalPaths(map, prefix, out) {
|
|
|
18976
19179
|
const experimental = map.experimental;
|
|
18977
19180
|
const legacy = experimental.bash;
|
|
18978
19181
|
if (isRecord2(legacy)) {
|
|
18979
|
-
if (
|
|
18980
|
-
|
|
19182
|
+
if (Object.keys(legacy).length === 0)
|
|
19183
|
+
recordRetired(out, prefix, "experimental.bash");
|
|
18981
19184
|
for (const leaf of Object.keys(legacy))
|
|
18982
19185
|
recordRetired(out, prefix, `experimental.bash.${leaf}`);
|
|
18983
19186
|
if (Object.hasOwn(map, "bash")) {
|
|
18984
19187
|
superseded(out, "experimental.bash", 'experimental.bash is ignored because top-level "bash" is already set');
|
|
18985
19188
|
} else {
|
|
18986
|
-
const bash = {
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
19189
|
+
const bash = {};
|
|
19190
|
+
if (["rewrite", "compress", "background"].some((leaf) => Object.hasOwn(legacy, leaf))) {
|
|
19191
|
+
bash.rewrite = legacy.rewrite === true;
|
|
19192
|
+
bash.compress = legacy.compress === true;
|
|
19193
|
+
bash.background = legacy.background === true;
|
|
19194
|
+
}
|
|
18991
19195
|
for (const leaf of ["long_running_reminder_enabled", "long_running_reminder_interval_ms"]) {
|
|
18992
19196
|
if (Object.hasOwn(legacy, leaf))
|
|
18993
19197
|
bash[leaf] = legacy[leaf];
|
|
18994
19198
|
}
|
|
18995
|
-
|
|
19199
|
+
if (Object.keys(bash).length > 0)
|
|
19200
|
+
map.bash = bash;
|
|
18996
19201
|
}
|
|
18997
19202
|
} else {
|
|
18998
19203
|
recordRetired(out, prefix, "experimental.bash");
|
|
@@ -19005,6 +19210,7 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
19005
19210
|
const prefix = blockLabel === "base" ? "" : `${blockLabel}.`;
|
|
19006
19211
|
translateGithubAliases(map, prefix, out);
|
|
19007
19212
|
translateInspectLspPaths(map, prefix, out);
|
|
19213
|
+
translateDataLayerPaths(map, prefix, out);
|
|
19008
19214
|
dropNoEffectPaths(map, prefix, out);
|
|
19009
19215
|
translateExperimentalPaths(map, prefix, out);
|
|
19010
19216
|
if (isRecord2(map.sandbox) && Object.hasOwn(map.sandbox, "enabled")) {
|
|
@@ -19043,8 +19249,6 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
19043
19249
|
});
|
|
19044
19250
|
}
|
|
19045
19251
|
for (const [path] of RETIRED_PATHS) {
|
|
19046
|
-
if (path === "experimental.bash")
|
|
19047
|
-
continue;
|
|
19048
19252
|
if (hasPath(map, path))
|
|
19049
19253
|
recordRetired(out, prefix, path);
|
|
19050
19254
|
}
|
|
@@ -19180,13 +19384,57 @@ var NO_EFFECT_RETIRED_NOTES = [
|
|
|
19180
19384
|
"inspect.max_drill_down_items",
|
|
19181
19385
|
"inspect.max_drill_down_items never had an effect, so the setting can be removed."
|
|
19182
19386
|
],
|
|
19387
|
+
[
|
|
19388
|
+
"inspect.tier2_idle_minutes",
|
|
19389
|
+
"inspect.tier2_idle_minutes no longer does anything: AFT runs whole-repository analyses only when aft_inspect is called, so the setting can be removed."
|
|
19390
|
+
],
|
|
19183
19391
|
[
|
|
19184
19392
|
"inspect.tier2_soft_deadline_ms",
|
|
19185
19393
|
"inspect.tier2_soft_deadline_ms never had an effect, so the setting can be removed."
|
|
19186
19394
|
]
|
|
19187
19395
|
];
|
|
19188
19396
|
function noEffectNote(key) {
|
|
19189
|
-
return NO_EFFECT_RETIRED_NOTES.find(([path]) => key
|
|
19397
|
+
return NO_EFFECT_RETIRED_NOTES.find(([path]) => namesPath(key, path))?.[1];
|
|
19398
|
+
}
|
|
19399
|
+
function namesPath(key, path) {
|
|
19400
|
+
return key === path || key.endsWith(`.${path}`);
|
|
19401
|
+
}
|
|
19402
|
+
var REMOVED_DATA_LAYER_NOTES = [
|
|
19403
|
+
[
|
|
19404
|
+
"views.callgraph_copies",
|
|
19405
|
+
"views.callgraph_copies is gone because no checkout borrows another checkout's call graph any more."
|
|
19406
|
+
],
|
|
19407
|
+
[
|
|
19408
|
+
"views.enabled",
|
|
19409
|
+
"views.enabled is gone because AFT now keeps one index store per repository and always uses it."
|
|
19410
|
+
],
|
|
19411
|
+
[
|
|
19412
|
+
"worktree.ram_overlay",
|
|
19413
|
+
"worktree.ram_overlay is gone because every worktree now has its own index state, so there is no borrowed index to patch in memory."
|
|
19414
|
+
]
|
|
19415
|
+
];
|
|
19416
|
+
function retiredIdleCheckoutHoursNote() {
|
|
19417
|
+
const [retired, replacement] = RETIRED_IDLE_CHECKOUT_HOURS;
|
|
19418
|
+
return `${retired} is now ${replacement}; from ${refusedFromVersion()} AFT refuses a config file that still sets ${retired}.`;
|
|
19419
|
+
}
|
|
19420
|
+
function removedConfigKeysNoticeMessage(configPath, translation) {
|
|
19421
|
+
const removed = translation.removedKeys ?? [];
|
|
19422
|
+
if (removed.length === 0)
|
|
19423
|
+
return "";
|
|
19424
|
+
const parts = [
|
|
19425
|
+
`${configPath} sets removed keys (${removed.join(", ")}); AFT ignores them, and from ${refusedFromVersion()} it refuses a config file that sets them. Run \`npx @cortexkit/aft doctor --fix\` to remove them.`
|
|
19426
|
+
];
|
|
19427
|
+
for (const [path, note] of REMOVED_DATA_LAYER_NOTES) {
|
|
19428
|
+
if (removed.some((key) => namesPath(key, path)))
|
|
19429
|
+
parts.push(note);
|
|
19430
|
+
}
|
|
19431
|
+
return parts.join(" ");
|
|
19432
|
+
}
|
|
19433
|
+
function removedConfigKeysNoticeDigest(translation) {
|
|
19434
|
+
return noticeDigest({
|
|
19435
|
+
notice: "removed_data_layer_keys_v1",
|
|
19436
|
+
keys: sortedUnique(translation.removedKeys)
|
|
19437
|
+
});
|
|
19190
19438
|
}
|
|
19191
19439
|
function legacyConfigNoticeMessage(configPath, translation) {
|
|
19192
19440
|
const equivalents = translation.retiredKeys.filter((key) => noEffectNote(key) === undefined);
|
|
@@ -19196,11 +19444,17 @@ function legacyConfigNoticeMessage(configPath, translation) {
|
|
|
19196
19444
|
parts.push(`${configPath} uses retired keys (${equivalents.join(", ")}); AFT applied their current equivalents, with the same limits a project config has for those keys. Run \`npx @cortexkit/aft doctor --fix\` to update the file.`);
|
|
19197
19445
|
if (translation.retiredEnabledFalse)
|
|
19198
19446
|
parts.push(RETIRED_ENABLED_FALSE_INDEXES_NOTE);
|
|
19447
|
+
if (equivalents.some((key) => namesPath(key, RETIRED_IDLE_CHECKOUT_HOURS[0]))) {
|
|
19448
|
+
parts.push(retiredIdleCheckoutHoursNote());
|
|
19449
|
+
}
|
|
19199
19450
|
}
|
|
19200
19451
|
for (const [, note] of NO_EFFECT_RETIRED_NOTES) {
|
|
19201
19452
|
if (noEffect.has(note))
|
|
19202
19453
|
parts.push(note);
|
|
19203
19454
|
}
|
|
19455
|
+
const removed = removedConfigKeysNoticeMessage(configPath, translation);
|
|
19456
|
+
if (removed)
|
|
19457
|
+
parts.push(removed);
|
|
19204
19458
|
return parts.join(" ");
|
|
19205
19459
|
}
|
|
19206
19460
|
function translateConfigDocument(map, tier) {
|
|
@@ -19208,6 +19462,7 @@ function translateConfigDocument(map, tier) {
|
|
|
19208
19462
|
warnings: [],
|
|
19209
19463
|
legacyInput: false,
|
|
19210
19464
|
retiredKeys: [],
|
|
19465
|
+
removedKeys: [],
|
|
19211
19466
|
retiredEnabledFalse: false
|
|
19212
19467
|
};
|
|
19213
19468
|
translateBlock(map, tier === "user", "base", out);
|
|
@@ -19218,6 +19473,7 @@ function translateConfigDocument(map, tier) {
|
|
|
19218
19473
|
}
|
|
19219
19474
|
}
|
|
19220
19475
|
out.retiredKeys = sortedUnique(out.retiredKeys);
|
|
19476
|
+
out.removedKeys = sortedUnique(out.removedKeys);
|
|
19221
19477
|
return out;
|
|
19222
19478
|
}
|
|
19223
19479
|
function unknownDisabledTools(disabled) {
|
|
@@ -19253,7 +19509,11 @@ function validateResolvedConfig(value) {
|
|
|
19253
19509
|
var ABSENT = { absent: true };
|
|
19254
19510
|
function projectBlock(block) {
|
|
19255
19511
|
const legacyPaths = {};
|
|
19256
|
-
for (const path of [
|
|
19512
|
+
for (const path of [
|
|
19513
|
+
...RETIRED_PATHS.map(([retired]) => retired),
|
|
19514
|
+
...REMOVED_NO_EFFECT_PATHS,
|
|
19515
|
+
...DATA_LAYER_RETIRED_PATHS
|
|
19516
|
+
]) {
|
|
19257
19517
|
const dot = path.indexOf(".");
|
|
19258
19518
|
if (dot < 0) {
|
|
19259
19519
|
if (Object.hasOwn(block, path))
|
|
@@ -19332,7 +19592,7 @@ function canonicalJson(value) {
|
|
|
19332
19592
|
return JSON.stringify(value);
|
|
19333
19593
|
}
|
|
19334
19594
|
function noticeDigest(projection) {
|
|
19335
|
-
return
|
|
19595
|
+
return createHash5("sha256").update(canonicalJson(projection), "utf8").digest("hex");
|
|
19336
19596
|
}
|
|
19337
19597
|
var SEMANTIC_COST_NOTICE = "AFT indexes now default on; the local semantic backend may download an ONNX runtime and model and use CPU. Run npx @cortexkit/aft setup to change indexes.semantic.";
|
|
19338
19598
|
var SEMANTIC_COST_NOTICE_DIGEST = noticeDigest({ notice: "semantic_default_cost_v1" });
|
|
@@ -20370,9 +20630,9 @@ async function releaseBridge(pool) {
|
|
|
20370
20630
|
await pool.shutdown();
|
|
20371
20631
|
}
|
|
20372
20632
|
// ../aft-bridge/dist/lsp-github-install.js
|
|
20373
|
-
import { createHash as
|
|
20374
|
-
import { closeSync as
|
|
20375
|
-
import { dirname as dirname4, join as join11, relative as relative4, resolve as
|
|
20633
|
+
import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
|
|
20634
|
+
import { closeSync as closeSync6, copyFileSync as copyFileSync3, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync as lstatSync2, mkdirSync as mkdirSync4, openSync as openSync5, readdirSync as readdirSync2, readFileSync as readFileSync5, readlinkSync, readSync as readSync5, realpathSync as realpathSync4, renameSync as renameSync3, rmSync as rmSync2, statSync as statSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
20635
|
+
import { dirname as dirname4, join as join11, relative as relative4, resolve as resolve8 } from "node:path";
|
|
20376
20636
|
import { Readable as Readable2 } from "node:stream";
|
|
20377
20637
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
20378
20638
|
|
|
@@ -20769,7 +21029,7 @@ function createGithubInstaller(services) {
|
|
|
20769
21029
|
const MAX_EXTRACT_BYTES = 1024 * 1024 * 1024;
|
|
20770
21030
|
function sha256OfFile(path) {
|
|
20771
21031
|
return new Promise((resolve, reject) => {
|
|
20772
|
-
const hash =
|
|
21032
|
+
const hash = createHash6("sha256");
|
|
20773
21033
|
const stream = createReadStream2(path);
|
|
20774
21034
|
stream.on("error", reject);
|
|
20775
21035
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
@@ -20777,17 +21037,17 @@ function createGithubInstaller(services) {
|
|
|
20777
21037
|
});
|
|
20778
21038
|
}
|
|
20779
21039
|
function sha256OfFileSync(path) {
|
|
20780
|
-
const hash =
|
|
20781
|
-
const fd =
|
|
21040
|
+
const hash = createHash6("sha256");
|
|
21041
|
+
const fd = openSync5(path, "r");
|
|
20782
21042
|
try {
|
|
20783
21043
|
const buffer = Buffer.allocUnsafe(1024 * 1024);
|
|
20784
|
-
let read =
|
|
21044
|
+
let read = readSync5(fd, buffer, 0, buffer.length, null);
|
|
20785
21045
|
while (read > 0) {
|
|
20786
21046
|
hash.update(buffer.subarray(0, read));
|
|
20787
|
-
read =
|
|
21047
|
+
read = readSync5(fd, buffer, 0, buffer.length, null);
|
|
20788
21048
|
}
|
|
20789
21049
|
} finally {
|
|
20790
|
-
|
|
21050
|
+
closeSync6(fd);
|
|
20791
21051
|
}
|
|
20792
21052
|
return hash.digest("hex");
|
|
20793
21053
|
}
|
|
@@ -20995,7 +21255,7 @@ function createGithubInstaller(services) {
|
|
|
20995
21255
|
throw new Error(`too many redirects (>${maxRedirects})`);
|
|
20996
21256
|
}
|
|
20997
21257
|
function validateExtraction(stagingRoot) {
|
|
20998
|
-
const realStagingRoot =
|
|
21258
|
+
const realStagingRoot = realpathSync4(stagingRoot);
|
|
20999
21259
|
let totalBytes = 0;
|
|
21000
21260
|
const walk = (dir) => {
|
|
21001
21261
|
let entries;
|
|
@@ -21021,12 +21281,12 @@ function createGithubInstaller(services) {
|
|
|
21021
21281
|
}
|
|
21022
21282
|
let realFull;
|
|
21023
21283
|
try {
|
|
21024
|
-
realFull =
|
|
21284
|
+
realFull = realpathSync4(full);
|
|
21025
21285
|
} catch (err) {
|
|
21026
21286
|
throw new Error(`failed to realpath ${full}: ${err}`);
|
|
21027
21287
|
}
|
|
21028
21288
|
const rel = relative4(realStagingRoot, realFull);
|
|
21029
|
-
if (relativePathEscapesRoot(rel) ||
|
|
21289
|
+
if (relativePathEscapesRoot(rel) || resolve8(realStagingRoot, rel) !== realFull) {
|
|
21030
21290
|
throw new Error(`archive entry escapes staging root: ${full} → ${realFull} (zip-slip defense)`);
|
|
21031
21291
|
}
|
|
21032
21292
|
if (lst.isDirectory()) {
|
|
@@ -21789,6 +22049,21 @@ function resolveNpm(deps = defaultDeps()) {
|
|
|
21789
22049
|
}
|
|
21790
22050
|
return null;
|
|
21791
22051
|
}
|
|
22052
|
+
function npmCandidates(deps = defaultDeps()) {
|
|
22053
|
+
const name = npmBinaryName(deps.platform);
|
|
22054
|
+
const dirs = [
|
|
22055
|
+
...(deps.env.PATH ?? "").split(deps.platform === "win32" ? ";" : ":").filter(isAbsolute5),
|
|
22056
|
+
dirname5(deps.execPath),
|
|
22057
|
+
...wellKnownNpmDirs(deps)
|
|
22058
|
+
];
|
|
22059
|
+
return [...new Set(dirs)].flatMap((binDir) => {
|
|
22060
|
+
return [
|
|
22061
|
+
join12(binDir, name),
|
|
22062
|
+
join12(binDir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
22063
|
+
join12(binDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
22064
|
+
].filter(isFile).map((command) => ({ command, binDir }));
|
|
22065
|
+
});
|
|
22066
|
+
}
|
|
21792
22067
|
function quoteCmdArgument(value) {
|
|
21793
22068
|
if (/[\0\r\n"%]/.test(value)) {
|
|
21794
22069
|
throw new Error(`npm argument cannot be represented safely for cmd.exe: ${JSON.stringify(value)}`);
|
|
@@ -21796,6 +22071,8 @@ function quoteCmdArgument(value) {
|
|
|
21796
22071
|
return `"${value}"`;
|
|
21797
22072
|
}
|
|
21798
22073
|
function npmInvocation(resolved, npmArgs, platform = process.platform, env = process.env) {
|
|
22074
|
+
if (resolved.cliPath)
|
|
22075
|
+
return { command: resolved.command, args: [resolved.cliPath, ...npmArgs] };
|
|
21799
22076
|
if (platform !== "win32" || !/\.(?:cmd|bat)$/i.test(resolved.command)) {
|
|
21800
22077
|
return { command: resolved.command, args: [...npmArgs] };
|
|
21801
22078
|
}
|
|
@@ -22051,10 +22328,11 @@ function probeNpmCutoffSupport(npm, clock) {
|
|
|
22051
22328
|
});
|
|
22052
22329
|
}
|
|
22053
22330
|
async function npmSupportsCutoff(npm, clock) {
|
|
22054
|
-
const
|
|
22331
|
+
const key = npm.cliPath ? `${npm.command}\x00${npm.cliPath}` : npm.command;
|
|
22332
|
+
const identity = await stat2(npm.cliPath ?? npm.command).then(({ size, mtimeMs }) => ({ size, mtimeMs })).catch(() => {
|
|
22055
22333
|
return;
|
|
22056
22334
|
});
|
|
22057
|
-
const existing = npmCutoffSupport.get(
|
|
22335
|
+
const existing = npmCutoffSupport.get(key);
|
|
22058
22336
|
const sameIdentity = existing && existing.identity?.size === identity?.size && existing.identity?.mtimeMs === identity?.mtimeMs;
|
|
22059
22337
|
if (existing && sameIdentity) {
|
|
22060
22338
|
if (!existing.settled || identity !== undefined && existing.settled.outcome !== "transient" || clock.now() < existing.settled.retryAt)
|
|
@@ -22065,7 +22343,7 @@ async function npmSupportsCutoff(npm, clock) {
|
|
|
22065
22343
|
return outcome;
|
|
22066
22344
|
});
|
|
22067
22345
|
const entry = { identity, pending };
|
|
22068
|
-
npmCutoffSupport.set(
|
|
22346
|
+
npmCutoffSupport.set(key, entry);
|
|
22069
22347
|
return pending;
|
|
22070
22348
|
}
|
|
22071
22349
|
function lspPublicationCutoff(graceDays, pinned, now = Date.now()) {
|
|
@@ -22083,6 +22361,79 @@ async function lspNpmInstallInvocation(npm, target, before, clock = SYSTEM_CLOCK
|
|
|
22083
22361
|
target
|
|
22084
22362
|
]);
|
|
22085
22363
|
}
|
|
22364
|
+
// ../aft-bridge/dist/lsp-npm-selection.js
|
|
22365
|
+
import { readFile, realpath, stat as stat3 } from "node:fs/promises";
|
|
22366
|
+
import { dirname as dirname6, join as join13, resolve as resolve9 } from "node:path";
|
|
22367
|
+
var LSP_NPM_REFUSAL = "AFT can't install language servers with the npm at <path> (<reason>). Put a real npm 7 or newer first on PATH; pinning a server version won't help.";
|
|
22368
|
+
function lspNpmRefusal(path, reason) {
|
|
22369
|
+
return LSP_NPM_REFUSAL.replace("<path>", path).replace("<reason>", reason);
|
|
22370
|
+
}
|
|
22371
|
+
async function genuineNpm(candidate) {
|
|
22372
|
+
let executable;
|
|
22373
|
+
try {
|
|
22374
|
+
executable = await realpath(candidate.command);
|
|
22375
|
+
} catch (error) {
|
|
22376
|
+
return { reason: `probe failed: ${String(error)}` };
|
|
22377
|
+
}
|
|
22378
|
+
const windowsShim = /\.(?:cmd|bat)$/i.test(executable);
|
|
22379
|
+
let current = dirname6(executable);
|
|
22380
|
+
if (windowsShim)
|
|
22381
|
+
current = join13(current, "node_modules", "npm");
|
|
22382
|
+
for (;; ) {
|
|
22383
|
+
try {
|
|
22384
|
+
const pkg = JSON.parse(await readFile(join13(current, "package.json"), "utf8"));
|
|
22385
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.npm;
|
|
22386
|
+
if (pkg.name === "npm" && typeof bin === "string") {
|
|
22387
|
+
const cli = await realpath(resolve9(current, bin));
|
|
22388
|
+
if (!windowsShim && cli !== executable)
|
|
22389
|
+
return { reason: "not npm: command is not npm's declared CLI" };
|
|
22390
|
+
const major = /^(\d+)\.\d+\.\d+$/.exec(pkg.version)?.[1];
|
|
22391
|
+
if (!major)
|
|
22392
|
+
return { reason: "probe failed: npm manifest has an unknown version" };
|
|
22393
|
+
if (Number(major) < 7)
|
|
22394
|
+
return { reason: `old npm: ${pkg.version} (requires npm 7 or newer)` };
|
|
22395
|
+
if (windowsShim || process.platform === "win32" && /\.[cm]?js$/i.test(cli)) {
|
|
22396
|
+
const node = join13(candidate.binDir ?? dirname6(executable), "node.exe");
|
|
22397
|
+
if (!(await stat3(node)).isFile())
|
|
22398
|
+
return { reason: "probe failed: adjacent Node is missing" };
|
|
22399
|
+
return { npm: { command: node, binDir: dirname6(node), cliPath: cli }, reason: "" };
|
|
22400
|
+
}
|
|
22401
|
+
return { npm: { command: cli, binDir: candidate.binDir }, reason: "" };
|
|
22402
|
+
}
|
|
22403
|
+
} catch {}
|
|
22404
|
+
const parent = dirname6(current);
|
|
22405
|
+
if (parent === current || windowsShim)
|
|
22406
|
+
break;
|
|
22407
|
+
current = parent;
|
|
22408
|
+
}
|
|
22409
|
+
return { reason: "not npm: no matching npm package manifest and CLI" };
|
|
22410
|
+
}
|
|
22411
|
+
async function selectLspNpm(preferred, candidates, signal) {
|
|
22412
|
+
const aborted = () => ({
|
|
22413
|
+
refusal: lspNpmRefusal(preferred.command, "probe failed: installation aborted")
|
|
22414
|
+
});
|
|
22415
|
+
if (signal?.aborted)
|
|
22416
|
+
return aborted();
|
|
22417
|
+
const first = await genuineNpm(preferred);
|
|
22418
|
+
if (signal?.aborted)
|
|
22419
|
+
return aborted();
|
|
22420
|
+
if (first.npm)
|
|
22421
|
+
return { npm: first.npm };
|
|
22422
|
+
const seen = new Set([preferred.command]);
|
|
22423
|
+
for (const candidate of candidates ?? npmCandidates()) {
|
|
22424
|
+
if (signal?.aborted)
|
|
22425
|
+
return aborted();
|
|
22426
|
+
if (seen.has(candidate.command))
|
|
22427
|
+
continue;
|
|
22428
|
+
seen.add(candidate.command);
|
|
22429
|
+
const result = await genuineNpm(candidate);
|
|
22430
|
+
if (signal?.aborted)
|
|
22431
|
+
return aborted();
|
|
22432
|
+
if (result.npm)
|
|
22433
|
+
return { npm: result.npm };
|
|
22434
|
+
}
|
|
22435
|
+
return { refusal: lspNpmRefusal(preferred.command, first.reason) };
|
|
22436
|
+
}
|
|
22086
22437
|
// ../aft-bridge/dist/message-detach.js
|
|
22087
22438
|
var BASH_WAIT_DETACH_MAGIC_KEYWORD = "&detach";
|
|
22088
22439
|
var STANDALONE_DETACH_KEYWORD_SOURCE = `(^|[^\\p{L}\\p{N}_])${BASH_WAIT_DETACH_MAGIC_KEYWORD}(?![\\p{L}\\p{N}_])`;
|
|
@@ -22132,14 +22483,14 @@ function shouldInterruptWaitsForMessage(detachOnUserMessage, operatorText) {
|
|
|
22132
22483
|
return detachOnUserMessage || containsStandaloneDetachKeyword(operatorText);
|
|
22133
22484
|
}
|
|
22134
22485
|
// ../aft-bridge/dist/migration.js
|
|
22135
|
-
import { closeSync as
|
|
22486
|
+
import { closeSync as closeSync8, existsSync as existsSync9, mkdirSync as mkdirSync5, openSync as openSync7, readFileSync as readFileSync8, renameSync as renameSync5, rmSync as rmSync3, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
22136
22487
|
import { homedir as homedir10, tmpdir as tmpdir3 } from "node:os";
|
|
22137
|
-
import { basename as basename2, dirname as
|
|
22488
|
+
import { basename as basename2, dirname as dirname9, join as join16, resolve as resolve11 } from "node:path";
|
|
22138
22489
|
|
|
22139
22490
|
// ../aft-bridge/dist/paths.js
|
|
22140
|
-
import { existsSync as existsSync7, readFileSync as readFileSync6, realpathSync as
|
|
22491
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, realpathSync as realpathSync5, renameSync as renameSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
22141
22492
|
import { homedir as homedir8 } from "node:os";
|
|
22142
|
-
import { dirname as
|
|
22493
|
+
import { dirname as dirname7, isAbsolute as isAbsolute6, join as join14, resolve as resolve10 } from "node:path";
|
|
22143
22494
|
function homeDir3() {
|
|
22144
22495
|
if (process.platform === "win32")
|
|
22145
22496
|
return process.env.USERPROFILE || process.env.HOME || homedir8();
|
|
@@ -22149,16 +22500,16 @@ function configHome() {
|
|
|
22149
22500
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
22150
22501
|
if (xdg && isAbsolute6(xdg))
|
|
22151
22502
|
return xdg;
|
|
22152
|
-
return
|
|
22503
|
+
return join14(homeDir3(), ".config");
|
|
22153
22504
|
}
|
|
22154
22505
|
function legacyOpenCodeConfigDir() {
|
|
22155
22506
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
22156
22507
|
if (envDir)
|
|
22157
|
-
return
|
|
22158
|
-
return
|
|
22508
|
+
return resolve10(envDir);
|
|
22509
|
+
return join14(configHome(), "opencode");
|
|
22159
22510
|
}
|
|
22160
22511
|
function legacyPiAgentDir() {
|
|
22161
|
-
return
|
|
22512
|
+
return join14(homeDir3(), ".pi", "agent");
|
|
22162
22513
|
}
|
|
22163
22514
|
function legacySources(basePath, label, harness) {
|
|
22164
22515
|
return [
|
|
@@ -22167,10 +22518,10 @@ function legacySources(basePath, label, harness) {
|
|
|
22167
22518
|
];
|
|
22168
22519
|
}
|
|
22169
22520
|
function resolveCortexKitUserConfigPath() {
|
|
22170
|
-
return
|
|
22521
|
+
return join14(configHome(), "cortexkit", "aft.jsonc");
|
|
22171
22522
|
}
|
|
22172
22523
|
function resolveCortexKitProjectConfigPath(projectDirectory) {
|
|
22173
|
-
return
|
|
22524
|
+
return join14(projectDirectory, ".cortexkit", "aft.jsonc");
|
|
22174
22525
|
}
|
|
22175
22526
|
function resolveProjectConfigReadPath(projectDirectory, operatingHarness) {
|
|
22176
22527
|
const canonical = resolveCortexKitProjectConfigPath(projectDirectory);
|
|
@@ -22197,14 +22548,14 @@ function resolveCortexKitConfigPaths(projectDirectory) {
|
|
|
22197
22548
|
}
|
|
22198
22549
|
function resolveLegacyAftConfigSources(projectDirectory) {
|
|
22199
22550
|
const project = [
|
|
22200
|
-
...legacySources(
|
|
22201
|
-
...legacySources(
|
|
22551
|
+
...legacySources(join14(projectDirectory, ".opencode", "aft"), "OpenCode project", "opencode"),
|
|
22552
|
+
...legacySources(join14(projectDirectory, ".pi", "aft"), "Pi project", "pi")
|
|
22202
22553
|
];
|
|
22203
22554
|
const identity = (path) => {
|
|
22204
22555
|
try {
|
|
22205
|
-
return
|
|
22556
|
+
return realpathSync5(path);
|
|
22206
22557
|
} catch {
|
|
22207
|
-
return
|
|
22558
|
+
return resolve10(path);
|
|
22208
22559
|
}
|
|
22209
22560
|
};
|
|
22210
22561
|
const protectedPaths = new Set([
|
|
@@ -22213,22 +22564,22 @@ function resolveLegacyAftConfigSources(projectDirectory) {
|
|
|
22213
22564
|
].map(identity));
|
|
22214
22565
|
return {
|
|
22215
22566
|
user: [
|
|
22216
|
-
...legacySources(
|
|
22217
|
-
...legacySources(
|
|
22567
|
+
...legacySources(join14(legacyOpenCodeConfigDir(), "aft"), "OpenCode user", "opencode"),
|
|
22568
|
+
...legacySources(join14(legacyPiAgentDir(), "aft"), "Pi user", "pi")
|
|
22218
22569
|
].filter((source) => !protectedPaths.has(identity(source.path))),
|
|
22219
22570
|
project
|
|
22220
22571
|
};
|
|
22221
22572
|
}
|
|
22222
22573
|
function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
|
|
22223
|
-
return
|
|
22574
|
+
return join14(storageRoot, harness, ...segments);
|
|
22224
22575
|
}
|
|
22225
22576
|
function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
22226
22577
|
const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
|
|
22227
|
-
const rootPath =
|
|
22578
|
+
const rootPath = join14(storageRoot, fileName);
|
|
22228
22579
|
if (existsSync7(harnessPath) || !existsSync7(rootPath))
|
|
22229
22580
|
return harnessPath;
|
|
22230
22581
|
try {
|
|
22231
|
-
openPrivateStorageDir(storageRoot,
|
|
22582
|
+
openPrivateStorageDir(storageRoot, dirname7(harnessPath));
|
|
22232
22583
|
renameSync4(rootPath, harnessPath);
|
|
22233
22584
|
} catch {}
|
|
22234
22585
|
return harnessPath;
|
|
@@ -22249,7 +22600,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
|
|
|
22249
22600
|
return false;
|
|
22250
22601
|
if (!lastVersion) {
|
|
22251
22602
|
try {
|
|
22252
|
-
openPrivateStorageDir(storageRoot,
|
|
22603
|
+
openPrivateStorageDir(storageRoot, dirname7(versionFile));
|
|
22253
22604
|
writeFileSync3(versionFile, currentVersion, { mode: PRIVATE_FILE_MODE });
|
|
22254
22605
|
} catch {}
|
|
22255
22606
|
return false;
|
|
@@ -22261,7 +22612,7 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
|
|
|
22261
22612
|
return;
|
|
22262
22613
|
const versionFile = repairRootScopedStorageFile(storageRoot, harness, "last_announced_version");
|
|
22263
22614
|
try {
|
|
22264
|
-
openPrivateStorageDir(storageRoot,
|
|
22615
|
+
openPrivateStorageDir(storageRoot, dirname7(versionFile));
|
|
22265
22616
|
writeFileSync3(versionFile, currentVersion, { mode: PRIVATE_FILE_MODE });
|
|
22266
22617
|
} catch {}
|
|
22267
22618
|
}
|
|
@@ -22310,18 +22661,18 @@ function decodeFileUrl(target) {
|
|
|
22310
22661
|
}
|
|
22311
22662
|
|
|
22312
22663
|
// ../aft-bridge/dist/resolver.js
|
|
22313
|
-
import { closeSync as
|
|
22314
|
-
import { createRequire } from "node:module";
|
|
22664
|
+
import { closeSync as closeSync7, existsSync as existsSync8, promises as fsPromises, openSync as openSync6, readFileSync as readFileSync7, readSync as readSync6 } from "node:fs";
|
|
22665
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
22315
22666
|
import { homedir as homedir9 } from "node:os";
|
|
22316
|
-
import { delimiter, dirname as
|
|
22667
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute7, join as join15 } from "node:path";
|
|
22317
22668
|
var ensureBinaryForResolver = ensureBinary;
|
|
22318
22669
|
var npmPlatformPackageReader = null;
|
|
22319
22670
|
var cacheCopiesInFlight = new Map;
|
|
22320
22671
|
function copyToVersionedCache(npmBinaryPath, version) {
|
|
22321
22672
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
22322
22673
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
22323
|
-
const versionedDir =
|
|
22324
|
-
const cachedPath =
|
|
22674
|
+
const versionedDir = join15(getAftBinaryCacheDir(), tag);
|
|
22675
|
+
const cachedPath = join15(versionedDir, `aft${ext}`);
|
|
22325
22676
|
if (existsSync8(cachedPath) && isTrustedCachedBinary(cachedPath, version))
|
|
22326
22677
|
return { cachedPath };
|
|
22327
22678
|
const existing = cacheCopiesInFlight.get(cachedPath);
|
|
@@ -22367,7 +22718,7 @@ function homeDirFromEnv(env) {
|
|
|
22367
22718
|
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir9();
|
|
22368
22719
|
}
|
|
22369
22720
|
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
22370
|
-
const binaryPath =
|
|
22721
|
+
const binaryPath = join15(getAftBinaryCacheDir(env), version, `aft${ext}`);
|
|
22371
22722
|
return existsSync8(binaryPath) ? binaryPath : null;
|
|
22372
22723
|
}
|
|
22373
22724
|
async function probeBinaryCandidateOffThread(binaryPath, source, expectedVersion) {
|
|
@@ -22389,7 +22740,7 @@ function pathCandidates(env, ext) {
|
|
|
22389
22740
|
for (const dir of rawPath.split(delimiter)) {
|
|
22390
22741
|
if (!dir || !isAbsolute7(dir))
|
|
22391
22742
|
continue;
|
|
22392
|
-
const candidate =
|
|
22743
|
+
const candidate = join15(dir, `aft${ext}`);
|
|
22393
22744
|
if (seen.has(candidate))
|
|
22394
22745
|
continue;
|
|
22395
22746
|
seen.add(candidate);
|
|
@@ -22401,9 +22752,9 @@ function pathCandidates(env, ext) {
|
|
|
22401
22752
|
function isNativeExecutable(binaryPath) {
|
|
22402
22753
|
let fd = null;
|
|
22403
22754
|
try {
|
|
22404
|
-
fd =
|
|
22755
|
+
fd = openSync6(binaryPath, "r");
|
|
22405
22756
|
const buf = Buffer.alloc(4);
|
|
22406
|
-
const read =
|
|
22757
|
+
const read = readSync6(fd, buf, 0, 4, 0);
|
|
22407
22758
|
if (read < 2)
|
|
22408
22759
|
return false;
|
|
22409
22760
|
const b0 = buf[0];
|
|
@@ -22424,7 +22775,7 @@ function isNativeExecutable(binaryPath) {
|
|
|
22424
22775
|
} finally {
|
|
22425
22776
|
if (fd !== null) {
|
|
22426
22777
|
try {
|
|
22427
|
-
|
|
22778
|
+
closeSync7(fd);
|
|
22428
22779
|
} catch {}
|
|
22429
22780
|
}
|
|
22430
22781
|
}
|
|
@@ -22454,7 +22805,7 @@ function explicitBinaryOverride(env) {
|
|
|
22454
22805
|
}
|
|
22455
22806
|
function ownPackageVersion() {
|
|
22456
22807
|
try {
|
|
22457
|
-
const req =
|
|
22808
|
+
const req = createRequire2(import.meta.url);
|
|
22458
22809
|
return req("../package.json").version;
|
|
22459
22810
|
} catch {
|
|
22460
22811
|
return null;
|
|
@@ -22464,10 +22815,10 @@ function npmPlatformPackage(ext) {
|
|
|
22464
22815
|
if (npmPlatformPackageReader)
|
|
22465
22816
|
return npmPlatformPackageReader(ext);
|
|
22466
22817
|
try {
|
|
22467
|
-
const req =
|
|
22818
|
+
const req = createRequire2(import.meta.url);
|
|
22468
22819
|
const manifestPath = req.resolve(`@cortexkit/aft-${platformKey()}/package.json`);
|
|
22469
22820
|
const manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
|
|
22470
|
-
const binaryPath =
|
|
22821
|
+
const binaryPath = join15(dirname8(manifestPath), "bin", `aft${ext}`);
|
|
22471
22822
|
if (typeof manifest.version !== "string" || !existsSync8(binaryPath))
|
|
22472
22823
|
return null;
|
|
22473
22824
|
return { binaryPath, version: normalizeBareVersion(manifest.version) };
|
|
@@ -22534,7 +22885,7 @@ async function findProbedBinary(expectedVersion, env) {
|
|
|
22534
22885
|
if (usable)
|
|
22535
22886
|
return { path: usable, source: "PATH" };
|
|
22536
22887
|
}
|
|
22537
|
-
const cargoPath =
|
|
22888
|
+
const cargoPath = join15(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
22538
22889
|
if (existsSync8(cargoPath)) {
|
|
22539
22890
|
const usable = await probeBinaryCandidateOffThread(cargoPath, "cargo", pluginVersion);
|
|
22540
22891
|
if (usable)
|
|
@@ -22633,9 +22984,9 @@ function dataHome() {
|
|
|
22633
22984
|
if (process.env.XDG_DATA_HOME)
|
|
22634
22985
|
return process.env.XDG_DATA_HOME;
|
|
22635
22986
|
if (process.platform === "win32") {
|
|
22636
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
22987
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join16(homeDir4(), "AppData", "Local");
|
|
22637
22988
|
}
|
|
22638
|
-
return
|
|
22989
|
+
return join16(homeDir4(), ".local", "share");
|
|
22639
22990
|
}
|
|
22640
22991
|
function homeDir4() {
|
|
22641
22992
|
if (process.platform === "win32")
|
|
@@ -22644,8 +22995,8 @@ function homeDir4() {
|
|
|
22644
22995
|
}
|
|
22645
22996
|
function resolveLegacyStorageRoot(harness) {
|
|
22646
22997
|
if (harness === "pi")
|
|
22647
|
-
return
|
|
22648
|
-
return
|
|
22998
|
+
return join16(homeDir4(), ".pi", "agent", "aft");
|
|
22999
|
+
return join16(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
22649
23000
|
}
|
|
22650
23001
|
function stripJsoncForParse(input) {
|
|
22651
23002
|
let out = "";
|
|
@@ -22774,19 +23125,19 @@ function acquireConfigMigrationLock(lockDir) {
|
|
|
22774
23125
|
}
|
|
22775
23126
|
}
|
|
22776
23127
|
function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
22777
|
-
mkdirSync5(
|
|
22778
|
-
const tmpPath =
|
|
23128
|
+
mkdirSync5(dirname9(targetPath), { recursive: true });
|
|
23129
|
+
const tmpPath = join16(dirname9(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
22779
23130
|
let fd = null;
|
|
22780
23131
|
try {
|
|
22781
|
-
fd =
|
|
23132
|
+
fd = openSync7(tmpPath, "wx", 384);
|
|
22782
23133
|
writeFileSync4(fd, readFileSync8(sourcePath));
|
|
22783
|
-
|
|
23134
|
+
closeSync8(fd);
|
|
22784
23135
|
fd = null;
|
|
22785
23136
|
renameSync5(tmpPath, targetPath);
|
|
22786
23137
|
} catch (err) {
|
|
22787
23138
|
if (fd !== null) {
|
|
22788
23139
|
try {
|
|
22789
|
-
|
|
23140
|
+
closeSync8(fd);
|
|
22790
23141
|
} catch {}
|
|
22791
23142
|
}
|
|
22792
23143
|
try {
|
|
@@ -22796,19 +23147,19 @@ function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
|
22796
23147
|
}
|
|
22797
23148
|
}
|
|
22798
23149
|
function atomicWriteConfigFile(targetPath, content) {
|
|
22799
|
-
mkdirSync5(
|
|
22800
|
-
const tmpPath =
|
|
23150
|
+
mkdirSync5(dirname9(targetPath), { recursive: true });
|
|
23151
|
+
const tmpPath = join16(dirname9(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
22801
23152
|
let fd = null;
|
|
22802
23153
|
try {
|
|
22803
|
-
fd =
|
|
23154
|
+
fd = openSync7(tmpPath, "wx", 384);
|
|
22804
23155
|
writeFileSync4(fd, content);
|
|
22805
|
-
|
|
23156
|
+
closeSync8(fd);
|
|
22806
23157
|
fd = null;
|
|
22807
23158
|
renameSync5(tmpPath, targetPath);
|
|
22808
23159
|
} catch (err) {
|
|
22809
23160
|
if (fd !== null) {
|
|
22810
23161
|
try {
|
|
22811
|
-
|
|
23162
|
+
closeSync8(fd);
|
|
22812
23163
|
} catch {}
|
|
22813
23164
|
}
|
|
22814
23165
|
try {
|
|
@@ -22916,13 +23267,13 @@ function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
|
|
|
22916
23267
|
}
|
|
22917
23268
|
function migrateAftConfigFile(opts) {
|
|
22918
23269
|
const warnings = [];
|
|
22919
|
-
const resolvedTarget =
|
|
22920
|
-
const existingSources = opts.legacySources.filter((source) => existsSync9(source.path) &&
|
|
23270
|
+
const resolvedTarget = resolve11(opts.targetPath);
|
|
23271
|
+
const existingSources = opts.legacySources.filter((source) => existsSync9(source.path) && resolve11(source.path) !== resolvedTarget);
|
|
22921
23272
|
const info = opts.logger?.info ?? opts.logger?.log;
|
|
22922
23273
|
if (existingSources.length === 0) {
|
|
22923
23274
|
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
22924
23275
|
}
|
|
22925
|
-
mkdirSync5(
|
|
23276
|
+
mkdirSync5(dirname9(opts.targetPath), { recursive: true });
|
|
22926
23277
|
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
22927
23278
|
try {
|
|
22928
23279
|
const sources = existingSources.map((source) => ({
|
|
@@ -22979,13 +23330,13 @@ function spawnErrorLabel(error) {
|
|
|
22979
23330
|
return [code, error.message].filter(Boolean).join(": ");
|
|
22980
23331
|
}
|
|
22981
23332
|
function migrationLogPath(newRoot, harness, logger) {
|
|
22982
|
-
const desired =
|
|
23333
|
+
const desired = join16(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
22983
23334
|
try {
|
|
22984
|
-
mkdirSync5(
|
|
23335
|
+
mkdirSync5(dirname9(desired), { recursive: true });
|
|
22985
23336
|
return desired;
|
|
22986
23337
|
} catch (err) {
|
|
22987
|
-
const fallback =
|
|
22988
|
-
logger?.warn?.(`Failed to create AFT migration log directory ${
|
|
23338
|
+
const fallback = join16(tmpdir3(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
23339
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname9(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
22989
23340
|
return fallback;
|
|
22990
23341
|
}
|
|
22991
23342
|
}
|
|
@@ -23044,13 +23395,13 @@ async function ensureStorageMigrated(opts) {
|
|
|
23044
23395
|
// ../aft-bridge/dist/migration-notices.js
|
|
23045
23396
|
import { readFileSync as readFileSync9, renameSync as renameSync6, rmdirSync, statSync as statSync9, writeFileSync as writeFileSync5 } from "node:fs";
|
|
23046
23397
|
import { homedir as homedir11 } from "node:os";
|
|
23047
|
-
import { dirname as
|
|
23398
|
+
import { dirname as dirname10, join as join17, resolve as resolve12 } from "node:path";
|
|
23048
23399
|
function migrationNoticeStorePath(env = process.env) {
|
|
23049
|
-
const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME :
|
|
23050
|
-
return
|
|
23400
|
+
const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join17(homedir11(), ".local", "state");
|
|
23401
|
+
return join17(stateHome, "cortexkit", "aft", "migration-notices.json");
|
|
23051
23402
|
}
|
|
23052
23403
|
function noticeKey(configPath, digest) {
|
|
23053
|
-
return `${
|
|
23404
|
+
return `${resolve12(configPath)}|${MIGRATION_POLICY_ID}|${digest}`;
|
|
23054
23405
|
}
|
|
23055
23406
|
function readRecords(storePath) {
|
|
23056
23407
|
try {
|
|
@@ -23063,7 +23414,7 @@ function readRecords(storePath) {
|
|
|
23063
23414
|
var LOCK_STALE_MS = 1e4;
|
|
23064
23415
|
function withStoreLock(storePath, action) {
|
|
23065
23416
|
const lockPath = `${storePath}.lock`;
|
|
23066
|
-
openPrivateStorageDir(
|
|
23417
|
+
openPrivateStorageDir(dirname10(storePath));
|
|
23067
23418
|
const deadline = Date.now() + 2000;
|
|
23068
23419
|
for (;; ) {
|
|
23069
23420
|
try {
|
|
@@ -23117,7 +23468,7 @@ function deliverMigrationNoticeOnce(options) {
|
|
|
23117
23468
|
}
|
|
23118
23469
|
}
|
|
23119
23470
|
// ../aft-bridge/dist/onnx-probe.js
|
|
23120
|
-
import { closeSync as
|
|
23471
|
+
import { closeSync as closeSync9, existsSync as existsSync10, openSync as openSync8, readSync as readSync7, realpathSync as realpathSync6 } from "node:fs";
|
|
23121
23472
|
var MH_MAGIC = 4277009102;
|
|
23122
23473
|
var MH_MAGIC_64 = 4277009103;
|
|
23123
23474
|
var FAT_MAGIC = 3405691582;
|
|
@@ -23130,7 +23481,7 @@ var MAX_HEADER_BYTES = 4 * 1024 * 1024;
|
|
|
23130
23481
|
var UNCHECKED = { loadable: true, checked: false };
|
|
23131
23482
|
function readAt(fd, offset, length) {
|
|
23132
23483
|
const buffer = Buffer.alloc(length);
|
|
23133
|
-
const read =
|
|
23484
|
+
const read = readSync7(fd, buffer, 0, length, offset);
|
|
23134
23485
|
return buffer.subarray(0, read);
|
|
23135
23486
|
}
|
|
23136
23487
|
function cpuTypeForArch(arch) {
|
|
@@ -23204,7 +23555,7 @@ function isUncheckableDependency(path) {
|
|
|
23204
23555
|
function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
|
|
23205
23556
|
let fd;
|
|
23206
23557
|
try {
|
|
23207
|
-
fd =
|
|
23558
|
+
fd = openSync8(realpathSync6(libPath), "r");
|
|
23208
23559
|
} catch (err) {
|
|
23209
23560
|
return {
|
|
23210
23561
|
loadable: false,
|
|
@@ -23238,13 +23589,13 @@ function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
|
|
|
23238
23589
|
} catch {
|
|
23239
23590
|
return UNCHECKED;
|
|
23240
23591
|
} finally {
|
|
23241
|
-
|
|
23592
|
+
closeSync9(fd);
|
|
23242
23593
|
}
|
|
23243
23594
|
}
|
|
23244
23595
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
23245
23596
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
23246
|
-
import { chmodSync as chmodSync2, closeSync as
|
|
23247
|
-
import { basename as basename3, dirname as
|
|
23597
|
+
import { chmodSync as chmodSync2, closeSync as closeSync10, copyFileSync as copyFileSync4, createWriteStream as createWriteStream3, existsSync as existsSync11, lstatSync as lstatSync3, openSync as openSync9, readdirSync as readdirSync4, readFileSync as readFileSync10, readlinkSync as readlinkSync2, realpathSync as realpathSync7, renameSync as renameSync7, rmSync as rmSync4, statSync as statSync10, symlinkSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
23598
|
+
import { basename as basename3, dirname as dirname11, isAbsolute as isAbsolute8, join as join18, relative as relative5, resolve as resolve13, win32 as win323 } from "node:path";
|
|
23248
23599
|
import { Readable as Readable3 } from "node:stream";
|
|
23249
23600
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
23250
23601
|
var ORT_VERSION = "1.24.4";
|
|
@@ -23335,7 +23686,7 @@ function resolveOnnxRuntime(storageDir, seams) {
|
|
|
23335
23686
|
}
|
|
23336
23687
|
async function findCachedOnnxRuntime(ortVersionDir, libName) {
|
|
23337
23688
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
23338
|
-
const libPath =
|
|
23689
|
+
const libPath = join18(resolvedOrtDir, libName);
|
|
23339
23690
|
if (existsSync11(libPath)) {
|
|
23340
23691
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
23341
23692
|
if (meta?.sha256) {
|
|
@@ -23360,7 +23711,7 @@ async function findCachedOnnxRuntime(ortVersionDir, libName) {
|
|
|
23360
23711
|
}
|
|
23361
23712
|
async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
|
|
23362
23713
|
const info = seams.platformInfo !== undefined ? seams.platformInfo : getPlatformInfo();
|
|
23363
|
-
const ortVersionDir =
|
|
23714
|
+
const ortVersionDir = join18(storageDir, "onnxruntime", ORT_VERSION);
|
|
23364
23715
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
23365
23716
|
const cached = await findCachedOnnxRuntime(ortVersionDir, libName);
|
|
23366
23717
|
if (cached)
|
|
@@ -23374,9 +23725,9 @@ async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
|
|
|
23374
23725
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
23375
23726
|
return null;
|
|
23376
23727
|
}
|
|
23377
|
-
const onnxBaseDir =
|
|
23728
|
+
const onnxBaseDir = join18(storageDir, "onnxruntime");
|
|
23378
23729
|
openPrivateStorageDir(storageDir, onnxBaseDir);
|
|
23379
|
-
const lockPath =
|
|
23730
|
+
const lockPath = join18(onnxBaseDir, ONNX_LOCK_FILE);
|
|
23380
23731
|
const pollMs = seams.lockPollMs ?? LOCK_POLL_MS;
|
|
23381
23732
|
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
23382
23733
|
let announcedWait = false;
|
|
@@ -23421,7 +23772,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
23421
23772
|
for (const entry of entries) {
|
|
23422
23773
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
23423
23774
|
continue;
|
|
23424
|
-
const stagingDir =
|
|
23775
|
+
const stagingDir = join18(onnxBaseDir, entry);
|
|
23425
23776
|
const parts = entry.split(".");
|
|
23426
23777
|
const pidStr = parts[parts.length - 2];
|
|
23427
23778
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -23458,7 +23809,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
23458
23809
|
}
|
|
23459
23810
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
23460
23811
|
try {
|
|
23461
|
-
if (existsSync11(ortDir) && !existsSync11(
|
|
23812
|
+
if (existsSync11(ortDir) && !existsSync11(join18(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
23462
23813
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
23463
23814
|
rmSync4(ortDir, { recursive: true, force: true });
|
|
23464
23815
|
}
|
|
@@ -23493,7 +23844,7 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
23493
23844
|
try {
|
|
23494
23845
|
const entries = readdirSync4(libDir);
|
|
23495
23846
|
try {
|
|
23496
|
-
const resolved = parseOnnxVersionFromPath(
|
|
23847
|
+
const resolved = parseOnnxVersionFromPath(realpathSync7(join18(libDir, libName)));
|
|
23497
23848
|
if (resolved && resolved !== INVALID_ORT_VERSION)
|
|
23498
23849
|
return resolved;
|
|
23499
23850
|
} catch {}
|
|
@@ -23507,10 +23858,10 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
23507
23858
|
if (version)
|
|
23508
23859
|
return version;
|
|
23509
23860
|
}
|
|
23510
|
-
const base =
|
|
23861
|
+
const base = join18(libDir, libName);
|
|
23511
23862
|
if (existsSync11(base)) {
|
|
23512
23863
|
try {
|
|
23513
|
-
const real =
|
|
23864
|
+
const real = realpathSync7(base);
|
|
23514
23865
|
const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
|
|
23515
23866
|
if (version)
|
|
23516
23867
|
return version;
|
|
@@ -23574,10 +23925,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
23574
23925
|
}
|
|
23575
23926
|
}
|
|
23576
23927
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
23577
|
-
if (existsSync11(
|
|
23928
|
+
if (existsSync11(join18(ortVersionDir, libName)))
|
|
23578
23929
|
return ortVersionDir;
|
|
23579
|
-
const libSubdir =
|
|
23580
|
-
if (existsSync11(
|
|
23930
|
+
const libSubdir = join18(ortVersionDir, "lib");
|
|
23931
|
+
if (existsSync11(join18(libSubdir, libName)))
|
|
23581
23932
|
return libSubdir;
|
|
23582
23933
|
return ortVersionDir;
|
|
23583
23934
|
}
|
|
@@ -23592,12 +23943,12 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23592
23943
|
} else if (process.platform === "win32") {
|
|
23593
23944
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
23594
23945
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
23595
|
-
searchPaths.push(
|
|
23946
|
+
searchPaths.push(join18(programFiles, "onnxruntime", "lib"), join18(programFiles, "Microsoft ONNX Runtime", "lib"), join18(programFiles, "Microsoft Machine Learning", "lib"), join18(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
23596
23947
|
const nugetPaths = [];
|
|
23597
23948
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
23598
23949
|
if (!userProfile)
|
|
23599
23950
|
return nugetPaths;
|
|
23600
|
-
const nugetPackageDir =
|
|
23951
|
+
const nugetPackageDir = join18(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
23601
23952
|
if (!existsSync11(nugetPackageDir))
|
|
23602
23953
|
return nugetPaths;
|
|
23603
23954
|
try {
|
|
@@ -23606,7 +23957,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23606
23957
|
continue;
|
|
23607
23958
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
23608
23959
|
continue;
|
|
23609
|
-
nugetPaths.push(
|
|
23960
|
+
nugetPaths.push(join18(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join18(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
23610
23961
|
}
|
|
23611
23962
|
} catch (err) {
|
|
23612
23963
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -23618,7 +23969,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23618
23969
|
const normalizeCase = process.platform === "win32" || process.platform === "darwin";
|
|
23619
23970
|
const seen = new Set;
|
|
23620
23971
|
const uniquePaths = searchPaths.filter((p) => {
|
|
23621
|
-
let key =
|
|
23972
|
+
let key = resolve13(p).replace(/[/\\]+$/, "");
|
|
23622
23973
|
if (normalizeCase)
|
|
23623
23974
|
key = key.toLowerCase();
|
|
23624
23975
|
if (seen.has(key))
|
|
@@ -23628,7 +23979,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23628
23979
|
});
|
|
23629
23980
|
const unknownVersionPaths = [];
|
|
23630
23981
|
for (const dir of uniquePaths) {
|
|
23631
|
-
const libPath =
|
|
23982
|
+
const libPath = join18(dir, libName);
|
|
23632
23983
|
if (process.platform === "win32") {
|
|
23633
23984
|
if (!directoryContainsLibrary(dir, libName))
|
|
23634
23985
|
continue;
|
|
@@ -23675,7 +24026,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
23675
24026
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
23676
24027
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
23677
24028
|
}
|
|
23678
|
-
privateMkdirSync(
|
|
24029
|
+
privateMkdirSync(dirname11(destPath));
|
|
23679
24030
|
let bytesWritten = 0;
|
|
23680
24031
|
const guard = new TransformStream({
|
|
23681
24032
|
transform(chunk, transformController) {
|
|
@@ -23702,16 +24053,16 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
23702
24053
|
}
|
|
23703
24054
|
}
|
|
23704
24055
|
function validateExtractedTree(stagingRoot) {
|
|
23705
|
-
const realRoot =
|
|
24056
|
+
const realRoot = realpathSync7(stagingRoot);
|
|
23706
24057
|
let totalBytes = 0;
|
|
23707
24058
|
const walk = (dir) => {
|
|
23708
24059
|
const entries = readdirSync4(dir);
|
|
23709
24060
|
for (const entry of entries) {
|
|
23710
|
-
const fullPath =
|
|
24061
|
+
const fullPath = join18(dir, entry);
|
|
23711
24062
|
const lst = lstatSync3(fullPath);
|
|
23712
24063
|
if (lst.isSymbolicLink()) {
|
|
23713
24064
|
const linkTarget = readlinkSync2(fullPath);
|
|
23714
|
-
const resolvedTarget =
|
|
24065
|
+
const resolvedTarget = resolve13(dirname11(fullPath), linkTarget);
|
|
23715
24066
|
const rel = relative5(realRoot, resolvedTarget);
|
|
23716
24067
|
if (relativePathEscapesRoot(rel) || win323.isAbsolute(rel)) {
|
|
23717
24068
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -23744,11 +24095,11 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23744
24095
|
const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
|
|
23745
24096
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
23746
24097
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}${randomBytes3(4).toString("hex")}`;
|
|
23747
|
-
const extractionRoot =
|
|
23748
|
-
const stagedInstallDir =
|
|
24098
|
+
const extractionRoot = join18(tmpDir, "extract");
|
|
24099
|
+
const stagedInstallDir = join18(tmpDir, "install");
|
|
23749
24100
|
try {
|
|
23750
24101
|
privateMkdirSync(extractionRoot);
|
|
23751
|
-
const archivePath =
|
|
24102
|
+
const archivePath = join18(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
23752
24103
|
await downloadFileWithCap(url, archivePath);
|
|
23753
24104
|
const archiveSha256 = await sha256File(archivePath);
|
|
23754
24105
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -23761,7 +24112,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23761
24112
|
unlinkSync5(archivePath);
|
|
23762
24113
|
} catch {}
|
|
23763
24114
|
validateExtractedTree(extractionRoot);
|
|
23764
|
-
const extractedDir =
|
|
24115
|
+
const extractedDir = join18(extractionRoot, info.assetName, "lib");
|
|
23765
24116
|
if (!existsSync11(extractedDir)) {
|
|
23766
24117
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
23767
24118
|
}
|
|
@@ -23769,7 +24120,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23769
24120
|
const realFiles = [];
|
|
23770
24121
|
const symlinks = [];
|
|
23771
24122
|
for (const libFile of libFiles) {
|
|
23772
|
-
const src =
|
|
24123
|
+
const src = join18(extractedDir, libFile);
|
|
23773
24124
|
try {
|
|
23774
24125
|
const stat = lstatSync3(src);
|
|
23775
24126
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -23784,14 +24135,14 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23784
24135
|
}
|
|
23785
24136
|
}
|
|
23786
24137
|
copyOnnxLibraries(info, extractedDir, stagedInstallDir, realFiles, symlinks);
|
|
23787
|
-
const libPath =
|
|
24138
|
+
const libPath = join18(stagedInstallDir, info.libName);
|
|
23788
24139
|
const libHash = await sha256File(libPath);
|
|
23789
24140
|
if (libHash !== info.librarySha256) {
|
|
23790
24141
|
throw new Error(`onnx runtime library hash mismatch at ${libPath}: sha256 ${libHash}, ` + `expected the pinned ${info.librarySha256} for ${info.assetName}`);
|
|
23791
24142
|
}
|
|
23792
24143
|
writeOnnxInstalledMeta(stagedInstallDir, ORT_VERSION, libHash, archiveSha256);
|
|
23793
24144
|
publishOnnxRuntime(stagedInstallDir, targetDir);
|
|
23794
|
-
writeStampedFileDigest(
|
|
24145
|
+
writeStampedFileDigest(join18(targetDir, info.libName), libHash);
|
|
23795
24146
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
23796
24147
|
log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
|
|
23797
24148
|
return targetDir;
|
|
@@ -23833,8 +24184,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23833
24184
|
const requiredLibs = new Set([info.libName]);
|
|
23834
24185
|
privateMkdirSync(targetDir);
|
|
23835
24186
|
for (const libFile of realFiles) {
|
|
23836
|
-
const src =
|
|
23837
|
-
const dst =
|
|
24187
|
+
const src = join18(extractedDir, libFile);
|
|
24188
|
+
const dst = join18(targetDir, libFile);
|
|
23838
24189
|
try {
|
|
23839
24190
|
if (copyFile === copyFileSync4)
|
|
23840
24191
|
privateCopyFileSync(src, dst);
|
|
@@ -23851,14 +24202,14 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23851
24202
|
log(`ORT extract: failed to copy optional ${libFile}: ${copyErr}`);
|
|
23852
24203
|
}
|
|
23853
24204
|
}
|
|
23854
|
-
const targetRoot =
|
|
24205
|
+
const targetRoot = realpathSync7(targetDir);
|
|
23855
24206
|
for (const link of symlinks) {
|
|
23856
|
-
const dst =
|
|
24207
|
+
const dst = join18(targetDir, link.name);
|
|
23857
24208
|
try {
|
|
23858
24209
|
unlinkSync5(dst);
|
|
23859
24210
|
} catch {}
|
|
23860
|
-
const dstForContainment =
|
|
23861
|
-
const resolvedTarget =
|
|
24211
|
+
const dstForContainment = join18(targetRoot, link.name);
|
|
24212
|
+
const resolvedTarget = resolve13(dirname11(dstForContainment), link.target);
|
|
23862
24213
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
23863
24214
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
23864
24215
|
if (requiredLibs.has(link.name)) {
|
|
@@ -23878,7 +24229,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23878
24229
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
23879
24230
|
}
|
|
23880
24231
|
}
|
|
23881
|
-
const requiredPath =
|
|
24232
|
+
const requiredPath = join18(targetDir, info.libName);
|
|
23882
24233
|
if (!existsSync11(requiredPath)) {
|
|
23883
24234
|
rmSync4(targetDir, { recursive: true, force: true });
|
|
23884
24235
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
@@ -23906,7 +24257,7 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
23906
24257
|
...sha256 ? { sha256 } : {},
|
|
23907
24258
|
archiveSha256
|
|
23908
24259
|
};
|
|
23909
|
-
writeFileSync6(
|
|
24260
|
+
writeFileSync6(join18(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), {
|
|
23910
24261
|
encoding: "utf8",
|
|
23911
24262
|
mode: PRIVATE_FILE_MODE
|
|
23912
24263
|
});
|
|
@@ -23915,7 +24266,7 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
23915
24266
|
}
|
|
23916
24267
|
}
|
|
23917
24268
|
function readOnnxInstalledMeta(installDir) {
|
|
23918
|
-
const path =
|
|
24269
|
+
const path = join18(installDir, ONNX_INSTALLED_META_FILE);
|
|
23919
24270
|
try {
|
|
23920
24271
|
if (!statSync10(path).isFile())
|
|
23921
24272
|
return null;
|
|
@@ -23936,13 +24287,13 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
23936
24287
|
function acquireLock(lockPath) {
|
|
23937
24288
|
const tryClaim = () => {
|
|
23938
24289
|
try {
|
|
23939
|
-
const fd =
|
|
24290
|
+
const fd = openSync9(lockPath, "wx", PRIVATE_FILE_MODE);
|
|
23940
24291
|
try {
|
|
23941
24292
|
writeFileSync6(fd, `${process.pid}
|
|
23942
24293
|
${new Date().toISOString()}
|
|
23943
24294
|
`);
|
|
23944
24295
|
} finally {
|
|
23945
|
-
|
|
24296
|
+
closeSync10(fd);
|
|
23946
24297
|
}
|
|
23947
24298
|
return true;
|
|
23948
24299
|
} catch (err) {
|
|
@@ -29678,13 +30029,6 @@ var LspConfigSchema = object({
|
|
|
29678
30029
|
versions: record(string2().trim().min(1), string2().trim().min(1)).optional()
|
|
29679
30030
|
});
|
|
29680
30031
|
var ExperimentalConfigSchema = object({
|
|
29681
|
-
bash: object({
|
|
29682
|
-
rewrite: boolean2().optional(),
|
|
29683
|
-
compress: boolean2().optional(),
|
|
29684
|
-
background: boolean2().optional(),
|
|
29685
|
-
long_running_reminder_enabled: boolean2().optional(),
|
|
29686
|
-
long_running_reminder_interval_ms: number2().int().positive().optional()
|
|
29687
|
-
}).optional(),
|
|
29688
30032
|
lsp_ty: boolean2().optional()
|
|
29689
30033
|
});
|
|
29690
30034
|
var BashEnvSchema = record(string2(), string2()).superRefine((env, context) => {
|
|
@@ -29784,7 +30128,6 @@ function clampInspectDiagnosticsTimeoutMs(value) {
|
|
|
29784
30128
|
var InspectConfigSchema = object({
|
|
29785
30129
|
enabled: boolean2().optional(),
|
|
29786
30130
|
diagnostics_timeout_ms: number2().int().positive().optional().transform((value) => value === undefined ? undefined : clampInspectDiagnosticsTimeoutMs(value)),
|
|
29787
|
-
tier2_idle_minutes: number2().min(0).optional(),
|
|
29788
30131
|
tier2_pass_timeout_ms: number2().int().positive().optional(),
|
|
29789
30132
|
categories: object({
|
|
29790
30133
|
diagnostics: boolean2().optional(),
|
|
@@ -29802,11 +30145,16 @@ var InspectConfigSchema = object({
|
|
|
29802
30145
|
function clampIdleRootTtlMinutes(value) {
|
|
29803
30146
|
return Math.min(30, Math.max(5, value));
|
|
29804
30147
|
}
|
|
30148
|
+
function clampIdleCheckoutHours(value) {
|
|
30149
|
+
return Math.min(IDLE_CHECKOUT_HOURS_MAX, Math.max(IDLE_CHECKOUT_HOURS_MIN, value));
|
|
30150
|
+
}
|
|
29805
30151
|
var IdleConfigSchema = object({
|
|
29806
|
-
root_ttl_minutes: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleRootTtlMinutes(value))
|
|
30152
|
+
root_ttl_minutes: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleRootTtlMinutes(value)),
|
|
30153
|
+
checkout_hours: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleCheckoutHours(value))
|
|
29807
30154
|
});
|
|
29808
30155
|
var ViewsConfigSchema = object({
|
|
29809
|
-
enabled: boolean2().optional()
|
|
30156
|
+
enabled: boolean2().optional(),
|
|
30157
|
+
callgraph_copies: number2().int().optional()
|
|
29810
30158
|
});
|
|
29811
30159
|
var WorktreeConfigSchema = object({
|
|
29812
30160
|
ram_overlay: boolean2().optional()
|
|
@@ -29910,6 +30258,11 @@ function applyActiveHarnessOverride(config, trusted) {
|
|
|
29910
30258
|
delete merged.indexes;
|
|
29911
30259
|
else
|
|
29912
30260
|
merged.indexes = indexes;
|
|
30261
|
+
const idle = mergeIdleConfig(base.idle, override.idle);
|
|
30262
|
+
if (idle === undefined)
|
|
30263
|
+
delete merged.idle;
|
|
30264
|
+
else
|
|
30265
|
+
merged.idle = idle;
|
|
29913
30266
|
merged.sandbox = mergeSandboxConfig(base.sandbox, override.sandbox, true);
|
|
29914
30267
|
if (!trusted && override.sandbox?.write_allow !== undefined) {
|
|
29915
30268
|
merged.sandbox = { ...merged.sandbox, write_allow: override.sandbox.write_allow };
|
|
@@ -29934,9 +30287,8 @@ function clampBashWatchSyncMaxMs(value) {
|
|
|
29934
30287
|
}
|
|
29935
30288
|
function resolveBashConfig(config) {
|
|
29936
30289
|
const top = config.bash;
|
|
29937
|
-
const
|
|
29938
|
-
const
|
|
29939
|
-
const reminderInterval = (typeof top === "object" && top !== null ? top.long_running_reminder_interval_ms : undefined) ?? legacy?.long_running_reminder_interval_ms;
|
|
30290
|
+
const reminderEnabled = typeof top === "object" && top !== null ? top.long_running_reminder_enabled : undefined;
|
|
30291
|
+
const reminderInterval = typeof top === "object" && top !== null ? top.long_running_reminder_interval_ms : undefined;
|
|
29940
30292
|
const topSubagentBg = typeof top === "object" && top !== null ? top.subagent_background !== false : true;
|
|
29941
30293
|
const topDetachOnUserMessage = typeof top === "object" && top !== null ? top.detach_on_user_message ?? true : true;
|
|
29942
30294
|
const rawForegroundWait = typeof top === "object" && top !== null ? top.foreground_wait_window_ms : undefined;
|
|
@@ -29983,19 +30335,6 @@ function resolveBashConfig(config) {
|
|
|
29983
30335
|
powershell_tool: top.powershell_tool ?? false
|
|
29984
30336
|
};
|
|
29985
30337
|
}
|
|
29986
|
-
const hasLegacyFeatureFlag = legacy && (legacy.rewrite !== undefined || legacy.compress !== undefined || legacy.background !== undefined);
|
|
29987
|
-
if (hasLegacyFeatureFlag) {
|
|
29988
|
-
const rewrite = legacy.rewrite === true;
|
|
29989
|
-
const compress = legacy.compress === true;
|
|
29990
|
-
const background = legacy.background === true;
|
|
29991
|
-
return {
|
|
29992
|
-
...base,
|
|
29993
|
-
enabled: true,
|
|
29994
|
-
rewrite,
|
|
29995
|
-
compress,
|
|
29996
|
-
background
|
|
29997
|
-
};
|
|
29998
|
-
}
|
|
29999
30338
|
return { ...base, enabled: true, rewrite: true, compress: true, background: true };
|
|
30000
30339
|
}
|
|
30001
30340
|
function parseConfigPartially(rawConfig) {
|
|
@@ -30132,7 +30471,7 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
30132
30471
|
recordConfigParseFailure(configPath, errorMsg);
|
|
30133
30472
|
throw new ConfigRejectedError(["invalid_config_document"], configPath);
|
|
30134
30473
|
}
|
|
30135
|
-
const removed = removedConfigKeyErrors(cleanConfig);
|
|
30474
|
+
const removed = removedConfigKeyErrors(cleanConfig, undefined, false);
|
|
30136
30475
|
if (removed.length) {
|
|
30137
30476
|
throw new ConfigRejectedError(removed);
|
|
30138
30477
|
}
|
|
@@ -30155,9 +30494,18 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
30155
30494
|
warn2(text);
|
|
30156
30495
|
}
|
|
30157
30496
|
}
|
|
30158
|
-
if (
|
|
30159
|
-
|
|
30160
|
-
|
|
30497
|
+
if (tier === "user") {
|
|
30498
|
+
if (translation.legacyInput) {
|
|
30499
|
+
log2(`Config ${configPath} uses retired keys (${translation.retiredKeys.join(", ")}); applied their current equivalents in memory`);
|
|
30500
|
+
}
|
|
30501
|
+
if (translation.removedKeys.length > 0) {
|
|
30502
|
+
configLoadNotices.push({
|
|
30503
|
+
configPath,
|
|
30504
|
+
digest: removedConfigKeysNoticeDigest(translation),
|
|
30505
|
+
message: removedConfigKeysNoticeMessage(configPath, translation)
|
|
30506
|
+
});
|
|
30507
|
+
}
|
|
30508
|
+
} else if (translation.legacyInput || translation.removedKeys.length > 0) {
|
|
30161
30509
|
configLoadNotices.push({
|
|
30162
30510
|
configPath,
|
|
30163
30511
|
digest: noticeDigest(projection),
|
|
@@ -30242,6 +30590,13 @@ function mergeWorktreeConfig(baseWorktree, overrideWorktree) {
|
|
|
30242
30590
|
return overrideWorktree;
|
|
30243
30591
|
return { ...baseWorktree, ...overrideWorktree };
|
|
30244
30592
|
}
|
|
30593
|
+
function mergeIdleConfig(baseIdle, overrideIdle) {
|
|
30594
|
+
const merged = {
|
|
30595
|
+
root_ttl_minutes: overrideIdle?.root_ttl_minutes ?? baseIdle?.root_ttl_minutes,
|
|
30596
|
+
checkout_hours: overrideIdle?.checkout_hours ?? baseIdle?.checkout_hours
|
|
30597
|
+
};
|
|
30598
|
+
return merged.root_ttl_minutes === undefined && merged.checkout_hours === undefined ? undefined : merged;
|
|
30599
|
+
}
|
|
30245
30600
|
function mergeInspectConfig(baseInspect, overrideInspect) {
|
|
30246
30601
|
const diagnosticsTimeoutConfigured = baseInspect?.diagnostics_timeout_ms !== undefined || overrideInspect?.diagnostics_timeout_ms !== undefined;
|
|
30247
30602
|
const diagnosticsTimeoutMs = Math.max(clampInspectDiagnosticsTimeoutMs(baseInspect?.diagnostics_timeout_ms ?? DEFAULT_INSPECT_DIAGNOSTICS_TIMEOUT_MS), clampInspectDiagnosticsTimeoutMs(overrideInspect?.diagnostics_timeout_ms ?? DEFAULT_INSPECT_DIAGNOSTICS_TIMEOUT_MS));
|
|
@@ -30339,19 +30694,10 @@ function mergeBashEnvMaps(base, override) {
|
|
|
30339
30694
|
return Object.fromEntries(merged.values());
|
|
30340
30695
|
}
|
|
30341
30696
|
function mergeExperimentalConfig(baseExperimental, overrideExperimental) {
|
|
30342
|
-
const bash = {
|
|
30343
|
-
...baseExperimental?.bash,
|
|
30344
|
-
...overrideExperimental?.bash
|
|
30345
|
-
};
|
|
30346
30697
|
const experimental = {
|
|
30347
30698
|
...baseExperimental,
|
|
30348
30699
|
...overrideExperimental
|
|
30349
30700
|
};
|
|
30350
|
-
if (Object.values(bash).some((value) => value !== undefined)) {
|
|
30351
|
-
experimental.bash = bash;
|
|
30352
|
-
} else {
|
|
30353
|
-
delete experimental.bash;
|
|
30354
|
-
}
|
|
30355
30701
|
if (Object.values(experimental).every((value) => value === undefined)) {
|
|
30356
30702
|
return;
|
|
30357
30703
|
}
|
|
@@ -30502,17 +30848,21 @@ function mergeConfigs(base, override) {
|
|
|
30502
30848
|
}
|
|
30503
30849
|
const inspect = mergeInspectConfig(base.inspect, override.inspect);
|
|
30504
30850
|
const worktree = mergeWorktreeConfig(base.worktree, override.worktree);
|
|
30851
|
+
const idle = mergeIdleConfig(base.idle, override.idle);
|
|
30505
30852
|
const sandbox = mergeSandboxConfig(base.sandbox, override.sandbox);
|
|
30506
30853
|
const remoteExec = mergeRemoteExecConfig(base.remote_exec, override.remote_exec);
|
|
30507
30854
|
const backup = mergeProjectBackupConfig(base.backup, override.backup);
|
|
30508
30855
|
const pi = mergePiConfig(base.pi, override.pi);
|
|
30856
|
+
const views = base.views !== undefined || override.views !== undefined ? { ...base.views, ...override.views } : undefined;
|
|
30509
30857
|
const bridge = base.bridge;
|
|
30510
30858
|
const safeOverride = pickProjectSafeFields(override);
|
|
30511
30859
|
delete safeOverride.indexes;
|
|
30512
30860
|
delete safeOverride.bash;
|
|
30513
30861
|
delete safeOverride.inspect;
|
|
30514
30862
|
delete safeOverride.worktree;
|
|
30863
|
+
delete safeOverride.idle;
|
|
30515
30864
|
delete safeOverride.pi;
|
|
30865
|
+
delete safeOverride.views;
|
|
30516
30866
|
return {
|
|
30517
30867
|
...base,
|
|
30518
30868
|
...safeOverride,
|
|
@@ -30522,10 +30872,12 @@ function mergeConfigs(base, override) {
|
|
|
30522
30872
|
...bash !== undefined ? { bash } : {},
|
|
30523
30873
|
...inspect !== undefined ? { inspect } : {},
|
|
30524
30874
|
...worktree !== undefined ? { worktree } : {},
|
|
30875
|
+
...idle !== undefined ? { idle } : {},
|
|
30525
30876
|
...sandbox !== undefined ? { sandbox } : {},
|
|
30526
30877
|
...remoteExec !== undefined ? { remote_exec: remoteExec } : {},
|
|
30527
30878
|
...backup !== undefined ? { backup } : {},
|
|
30528
30879
|
...pi !== undefined ? { pi } : {},
|
|
30880
|
+
...views !== undefined ? { views } : {},
|
|
30529
30881
|
experimental,
|
|
30530
30882
|
semantic,
|
|
30531
30883
|
search,
|
|
@@ -30929,7 +31281,7 @@ async function signalActiveBridges(pool, projectRoot, sessionID, request) {
|
|
|
30929
31281
|
}
|
|
30930
31282
|
|
|
30931
31283
|
// src/bg-notifications.ts
|
|
30932
|
-
import { createHash as
|
|
31284
|
+
import { createHash as createHash7, randomBytes as randomBytes4, randomUUID as randomUUID2 } from "node:crypto";
|
|
30933
31285
|
|
|
30934
31286
|
// src/shared/last-assistant-model.ts
|
|
30935
31287
|
function isRecord3(value) {
|
|
@@ -31253,7 +31605,7 @@ async function awaitWakeAdmission(options) {
|
|
|
31253
31605
|
|
|
31254
31606
|
// src/bg-notifications.ts
|
|
31255
31607
|
function hashReminder(text) {
|
|
31256
|
-
return
|
|
31608
|
+
return createHash7("sha256").update(text).digest("hex").slice(0, 16);
|
|
31257
31609
|
}
|
|
31258
31610
|
var CONSUMED_TASKIDS_CAP = 256;
|
|
31259
31611
|
var DELIVERED_AWAITING_ACK_CAP = 4096;
|
|
@@ -32809,14 +33161,14 @@ async function runDetachedBgHandler(work, onError) {
|
|
|
32809
33161
|
|
|
32810
33162
|
// src/lsp-auto-install.ts
|
|
32811
33163
|
import { existsSync as existsSync14, mkdirSync as mkdirSync7, renameSync as renameSync9, rmSync as rmSync6, statSync as statSync13, writeFileSync as writeFileSync8 } from "node:fs";
|
|
32812
|
-
import { join as
|
|
33164
|
+
import { join as join21 } from "node:path";
|
|
32813
33165
|
|
|
32814
33166
|
// src/lsp-cache.ts
|
|
32815
33167
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
32816
33168
|
import {
|
|
32817
|
-
closeSync as
|
|
33169
|
+
closeSync as closeSync11,
|
|
32818
33170
|
mkdirSync as mkdirSync6,
|
|
32819
|
-
openSync as
|
|
33171
|
+
openSync as openSync10,
|
|
32820
33172
|
readFileSync as readFileSync12,
|
|
32821
33173
|
renameSync as renameSync8,
|
|
32822
33174
|
rmSync as rmSync5,
|
|
@@ -32824,7 +33176,7 @@ import {
|
|
|
32824
33176
|
unlinkSync as unlinkSync6,
|
|
32825
33177
|
writeFileSync as writeFileSync7
|
|
32826
33178
|
} from "node:fs";
|
|
32827
|
-
import { join as
|
|
33179
|
+
import { join as join19 } from "node:path";
|
|
32828
33180
|
function aftCacheBase() {
|
|
32829
33181
|
return getAftCacheRoot();
|
|
32830
33182
|
}
|
|
@@ -32832,18 +33184,18 @@ function lspCacheRoot() {
|
|
|
32832
33184
|
return getAftLspPackagesDir();
|
|
32833
33185
|
}
|
|
32834
33186
|
function lspPackageDir(npmPackage) {
|
|
32835
|
-
return
|
|
33187
|
+
return join19(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
32836
33188
|
}
|
|
32837
33189
|
function lspBinaryPath(npmPackage, binary) {
|
|
32838
|
-
return
|
|
33190
|
+
return join19(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
32839
33191
|
}
|
|
32840
33192
|
function lspBinDir(npmPackage) {
|
|
32841
|
-
return
|
|
33193
|
+
return join19(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
32842
33194
|
}
|
|
32843
33195
|
function isInstalled(npmPackage, binary) {
|
|
32844
33196
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
32845
33197
|
try {
|
|
32846
|
-
if (statSync12(
|
|
33198
|
+
if (statSync12(join19(lspBinDir(npmPackage), candidate)).isFile())
|
|
32847
33199
|
return true;
|
|
32848
33200
|
} catch {}
|
|
32849
33201
|
}
|
|
@@ -32863,13 +33215,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
|
|
|
32863
33215
|
installedAt: new Date().toISOString(),
|
|
32864
33216
|
...sha256 ? { sha256 } : {}
|
|
32865
33217
|
};
|
|
32866
|
-
writeFileSync7(
|
|
33218
|
+
writeFileSync7(join19(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
32867
33219
|
} catch (err) {
|
|
32868
33220
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
32869
33221
|
}
|
|
32870
33222
|
}
|
|
32871
33223
|
function readInstalledMetaIn(installDir) {
|
|
32872
|
-
const path =
|
|
33224
|
+
const path = join19(installDir, INSTALLED_META_FILE);
|
|
32873
33225
|
try {
|
|
32874
33226
|
if (!statSync12(path).isFile())
|
|
32875
33227
|
return null;
|
|
@@ -32893,7 +33245,7 @@ function readInstalledMeta(packageKey) {
|
|
|
32893
33245
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
32894
33246
|
}
|
|
32895
33247
|
function lockPath(npmPackage) {
|
|
32896
|
-
return
|
|
33248
|
+
return join19(lspPackageDir(npmPackage), ".aft-installing");
|
|
32897
33249
|
}
|
|
32898
33250
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
32899
33251
|
function acquireInstallLock(lockKey) {
|
|
@@ -32902,14 +33254,14 @@ function acquireInstallLock(lockKey) {
|
|
|
32902
33254
|
const token = randomUUID3();
|
|
32903
33255
|
const tryClaim = () => {
|
|
32904
33256
|
try {
|
|
32905
|
-
const fd =
|
|
33257
|
+
const fd = openSync10(lock, "wx");
|
|
32906
33258
|
try {
|
|
32907
33259
|
writeFileSync7(fd, `${process.pid}
|
|
32908
33260
|
${new Date().toISOString()}
|
|
32909
33261
|
${token}
|
|
32910
33262
|
`);
|
|
32911
33263
|
} finally {
|
|
32912
|
-
|
|
33264
|
+
closeSync11(fd);
|
|
32913
33265
|
}
|
|
32914
33266
|
let retained = false;
|
|
32915
33267
|
let released = false;
|
|
@@ -33024,7 +33376,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
|
|
|
33024
33376
|
var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
|
|
33025
33377
|
var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
|
|
33026
33378
|
function autoInstallStampPath() {
|
|
33027
|
-
return
|
|
33379
|
+
return join19(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
|
|
33028
33380
|
}
|
|
33029
33381
|
function hasRecentAutoInstallStamp(path) {
|
|
33030
33382
|
try {
|
|
@@ -33072,11 +33424,11 @@ function claimLspAutoInstallPass() {
|
|
|
33072
33424
|
};
|
|
33073
33425
|
const tryClaim = () => {
|
|
33074
33426
|
try {
|
|
33075
|
-
const fd =
|
|
33427
|
+
const fd = openSync10(lock, "wx");
|
|
33076
33428
|
try {
|
|
33077
33429
|
writeFileSync7(fd, JSON.stringify(owner));
|
|
33078
33430
|
} finally {
|
|
33079
|
-
|
|
33431
|
+
closeSync11(fd);
|
|
33080
33432
|
}
|
|
33081
33433
|
return true;
|
|
33082
33434
|
} catch (err) {
|
|
@@ -33125,7 +33477,7 @@ function claimLspAutoInstallPass() {
|
|
|
33125
33477
|
}
|
|
33126
33478
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
33127
33479
|
function readVersionCheck(npmPackage) {
|
|
33128
|
-
const file =
|
|
33480
|
+
const file = join19(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
33129
33481
|
try {
|
|
33130
33482
|
const raw = readFileSync12(file, "utf8");
|
|
33131
33483
|
const parsed = JSON.parse(raw);
|
|
@@ -33142,7 +33494,7 @@ function readVersionCheck(npmPackage) {
|
|
|
33142
33494
|
}
|
|
33143
33495
|
function writeVersionCheck(npmPackage, latest) {
|
|
33144
33496
|
mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
|
|
33145
|
-
const file =
|
|
33497
|
+
const file = join19(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
33146
33498
|
const record = {
|
|
33147
33499
|
last_checked: new Date().toISOString(),
|
|
33148
33500
|
latest_eligible: latest
|
|
@@ -33259,7 +33611,7 @@ function isVersionSupported(spec, version) {
|
|
|
33259
33611
|
|
|
33260
33612
|
// src/lsp-project-relevance.ts
|
|
33261
33613
|
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync13 } from "node:fs";
|
|
33262
|
-
import { join as
|
|
33614
|
+
import { join as join20 } from "node:path";
|
|
33263
33615
|
var MAX_WALK_DIRS = 200;
|
|
33264
33616
|
var MAX_WALK_DEPTH = 4;
|
|
33265
33617
|
var NOISE_DIRS = new Set([
|
|
@@ -33276,7 +33628,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
33276
33628
|
if (!rootMarkers)
|
|
33277
33629
|
return false;
|
|
33278
33630
|
for (const marker of rootMarkers) {
|
|
33279
|
-
if (existsSync13(
|
|
33631
|
+
if (existsSync13(join20(projectRoot, marker)))
|
|
33280
33632
|
return true;
|
|
33281
33633
|
}
|
|
33282
33634
|
return false;
|
|
@@ -33300,7 +33652,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
33300
33652
|
}
|
|
33301
33653
|
function readPackageJson(projectRoot) {
|
|
33302
33654
|
try {
|
|
33303
|
-
const raw = readFileSync13(
|
|
33655
|
+
const raw = readFileSync13(join20(projectRoot, "package.json"), "utf8");
|
|
33304
33656
|
const parsed = JSON.parse(raw);
|
|
33305
33657
|
if (typeof parsed !== "object" || parsed === null)
|
|
33306
33658
|
return null;
|
|
@@ -33330,7 +33682,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
33330
33682
|
for (const entry of entries) {
|
|
33331
33683
|
if (entry.isDirectory()) {
|
|
33332
33684
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
33333
|
-
queue.push({ dir:
|
|
33685
|
+
queue.push({ dir: join20(current.dir, entry.name), depth: current.depth + 1 });
|
|
33334
33686
|
}
|
|
33335
33687
|
continue;
|
|
33336
33688
|
}
|
|
@@ -33463,7 +33815,7 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
|
|
|
33463
33815
|
}
|
|
33464
33816
|
function ensureInstallAnchor(cwd) {
|
|
33465
33817
|
try {
|
|
33466
|
-
const stub =
|
|
33818
|
+
const stub = join21(cwd, "package.json");
|
|
33467
33819
|
if (!existsSync14(stub)) {
|
|
33468
33820
|
writeFileSync8(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
33469
33821
|
`);
|
|
@@ -33479,18 +33831,26 @@ async function runInstall(spec, version, cwd, installLock, before, signal) {
|
|
|
33479
33831
|
warn2(`[lsp] install ${target} aborted before spawn`);
|
|
33480
33832
|
return false;
|
|
33481
33833
|
}
|
|
33482
|
-
const
|
|
33483
|
-
if (!
|
|
33834
|
+
const preferredNpm = resolveNpm();
|
|
33835
|
+
if (!preferredNpm) {
|
|
33484
33836
|
warn2(`[lsp] npm not found on PATH or known locations; cannot install ${target}`);
|
|
33485
33837
|
return false;
|
|
33486
33838
|
}
|
|
33839
|
+
const selected = await selectLspNpm(preferredNpm, undefined, signal);
|
|
33840
|
+
if (signal?.aborted)
|
|
33841
|
+
return false;
|
|
33842
|
+
if (!selected.npm) {
|
|
33843
|
+
warn2(`[lsp] ${selected.refusal}`);
|
|
33844
|
+
return false;
|
|
33845
|
+
}
|
|
33846
|
+
const npm = selected.npm;
|
|
33487
33847
|
const invocation = await lspNpmInstallInvocation(npm, target, before);
|
|
33488
33848
|
if (signal?.aborted) {
|
|
33489
33849
|
warn2(`[lsp] install ${target} aborted during npm capability probe`);
|
|
33490
33850
|
return false;
|
|
33491
33851
|
}
|
|
33492
33852
|
if (!invocation) {
|
|
33493
|
-
warn2(`[lsp] npm cannot
|
|
33853
|
+
warn2(`[lsp] ${lspNpmRefusal(npm.command, "probe failed: cannot verify publication-cutoff support")}`);
|
|
33494
33854
|
return false;
|
|
33495
33855
|
}
|
|
33496
33856
|
ensureInstallAnchor(cwd);
|
|
@@ -33567,6 +33927,9 @@ async function runInstall(spec, version, cwd, installLock, before, signal) {
|
|
|
33567
33927
|
log2(`[lsp] installed ${target}`);
|
|
33568
33928
|
finish(true);
|
|
33569
33929
|
} else {
|
|
33930
|
+
const rejectedOption = /--(?:no-save|before|ignore-scripts)\b/.exec(stderrBuf)?.[0];
|
|
33931
|
+
if (rejectedOption)
|
|
33932
|
+
warn2(`[lsp] ${lspNpmRefusal(npm.command, `rejected option: ${rejectedOption}`)}`);
|
|
33570
33933
|
error2(`[lsp] install ${target} exited with code ${code}; last stderr:
|
|
33571
33934
|
${stderrBuf.trim()}`);
|
|
33572
33935
|
finish(false);
|
|
@@ -33673,10 +34036,10 @@ function sha256OfFileSync(path) {
|
|
|
33673
34036
|
}
|
|
33674
34037
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
33675
34038
|
const packageDir = lspPackageDir(spec.npm);
|
|
33676
|
-
const dest =
|
|
34039
|
+
const dest = join21(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
33677
34040
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
33678
34041
|
try {
|
|
33679
|
-
mkdirSync7(
|
|
34042
|
+
mkdirSync7(join21(dest, ".."), { recursive: true });
|
|
33680
34043
|
rmSync6(dest, { recursive: true, force: true });
|
|
33681
34044
|
renameSync9(packageDir, dest);
|
|
33682
34045
|
} catch (err) {
|
|
@@ -45690,13 +46053,16 @@ async function boundedVerification(client, sessionId) {
|
|
|
45690
46053
|
setCache(sessionId, dir);
|
|
45691
46054
|
return dir;
|
|
45692
46055
|
}
|
|
46056
|
+
function clearSessionDirectory(sessionId) {
|
|
46057
|
+
cache.delete(sessionId);
|
|
46058
|
+
lookupGenerations.delete(sessionId);
|
|
46059
|
+
verifyCache.delete(sessionId);
|
|
46060
|
+
}
|
|
45693
46061
|
async function closeDeletedSessionRoutes(pool, sessionId, fallbackDirectory) {
|
|
45694
46062
|
const roots = new Set(pool.activeBridges().map((bridge) => bridge.getCwd()));
|
|
45695
46063
|
roots.add(getSessionDirectoryCached(sessionId) ?? fallbackDirectory);
|
|
45696
46064
|
await Promise.allSettled([...roots].map((root) => pool.closeSession(root, sessionId)));
|
|
45697
|
-
|
|
45698
|
-
lookupGenerations.delete(sessionId);
|
|
45699
|
-
verifyCache.delete(sessionId);
|
|
46065
|
+
clearSessionDirectory(sessionId);
|
|
45700
46066
|
}
|
|
45701
46067
|
|
|
45702
46068
|
// src/shared/subagent-detect.ts
|
|
@@ -46515,6 +46881,9 @@ function canonicalizeDirectory(dir) {
|
|
|
46515
46881
|
return canonicalizeProjectRoot(dir);
|
|
46516
46882
|
}
|
|
46517
46883
|
function projectRootFor(runtime) {
|
|
46884
|
+
if (runtime.directoryIsSessionRoot && runtime.directory) {
|
|
46885
|
+
return canonicalizeDirectory(runtime.directory);
|
|
46886
|
+
}
|
|
46518
46887
|
const cached = getSessionDirectoryCached(runtime.sessionID);
|
|
46519
46888
|
if (typeof cached === "string" && cached.length > 0) {
|
|
46520
46889
|
return canonicalizeDirectory(cached);
|
|
@@ -46965,6 +47334,10 @@ function registerV2SessionLifecycle(context, ctx) {
|
|
|
46965
47334
|
const sessionID = event.data.sessionID;
|
|
46966
47335
|
if (!sessionID)
|
|
46967
47336
|
return;
|
|
47337
|
+
if (event.type === "session.moved") {
|
|
47338
|
+
clearSessionDirectory(sessionID);
|
|
47339
|
+
return;
|
|
47340
|
+
}
|
|
46968
47341
|
if (event.type === "session.deleted") {
|
|
46969
47342
|
const state = sessions.get(sessionID);
|
|
46970
47343
|
const kills = killStoppedBackgroundTasks(context, sessionID, ctx);
|
|
@@ -47162,7 +47535,7 @@ function backgroundWaitDescription(watchToolRegistered, statusRegistered, role =
|
|
|
47162
47535
|
}
|
|
47163
47536
|
if (watchToolRegistered) {
|
|
47164
47537
|
const noPolling = statusRegistered ? ", and never loop bash_status to wait" : "";
|
|
47165
|
-
return `then bash_watch handles only a short remaining wait (in a main session a watch defaults to 30s, max bash.watch_sync_max_ms, 120s by default; in a delegated session a watch without a timeout waits up to the worker wait limit, bash.worker_wait_max_ms, 30 minutes by default, then reports it is still running; watch again to keep waiting); for anything longer end the turn and let the completion reminder wake you, or use bash({wait:true}) when the result is needed before anything else — never background a command and immediately bash_watch it (that wastes a turn for what foreground returns in one)${noPolling}.`;
|
|
47538
|
+
return `then bash_watch handles only a short remaining wait (in a main session a watch defaults to 30s, max bash.watch_sync_max_ms, 120s by default; in a delegated session a watch without a timeout waits up to the worker wait limit, bash.worker_wait_max_ms, 30 minutes by default, then reports it is still running; watch again to keep waiting); for anything longer, first do the work that doesn't need this result, end the turn only when everything left needs it, and let the completion reminder wake you, or use bash({wait:true}) when the result is needed before anything else — never background a command and immediately bash_watch it (that wastes a turn for what foreground returns in one)${noPolling}.`;
|
|
47166
47539
|
}
|
|
47167
47540
|
return statusRegistered ? "the task keeps running after the call returns, a completion reminder arrives when it exits, and bash_status reports its state and output. Use bash({wait:true}) instead when the result is needed before anything else." : "the task keeps running after the call returns and a completion reminder arrives when it exits. Use bash({wait:true}) instead when the result is needed before anything else.";
|
|
47168
47541
|
}
|
|
@@ -47189,7 +47562,7 @@ function bashToolDescription(aftSearchRegistered, compressionOn, backgroundOn, d
|
|
|
47189
47562
|
].join(", ");
|
|
47190
47563
|
const searchSteer = `use ${steerTools}${zoomEnabled ? ", or aft_zoom" : ""} instead`;
|
|
47191
47564
|
const compression = compressionOn ? " Output is compressed by default; pass compressed: false for raw output. Piped commands run verbatim and show the pipeline's output; for AFT's test/build summary, run the runner without | head, | tail, or | grep. Pipeline-failure notes cover single top-level pipelines only; multi-statement commands (`a; b | c; d`) are not instrumented, so masked failures inside them still need explicit exit-code checks." : "";
|
|
47192
|
-
const tasks = backgroundOn ? ` Commands run in the foreground and return inline; wait: true blocks until a long command finishes instead of auto-promoting (it blocks up to bash.worker_wait_max_ms, 30 minutes by default, then reports the command is still running; watch again to keep waiting); ${userMessageDetachDescription(detachOnUserMessage)} Use it when you need the result before doing anything else; ${autoPromote}. Use background: true yourself ONLY when you have other
|
|
47565
|
+
const tasks = backgroundOn ? ` Commands run in the foreground and return inline; wait: true blocks until a long command finishes instead of auto-promoting (it blocks up to bash.worker_wait_max_ms, 30 minutes by default, then reports the command is still running; watch again to keep waiting); ${userMessageDetachDescription(detachOnUserMessage)} Use it when you need the result before doing anything else; ${autoPromote}. Use background: true yourself ONLY when you have other work to do while it runs, and any work that doesn't need this command's result counts; ${backgroundWaitDescription(watchToolRegistered, status, role)} Do not change or delete files a background command uses until it finishes. A \`nohup … &\` launch still holds the call if the child keeps stdout/stderr; redirect both or use background:true. pty: true runs interactive programs (REPLs, TUIs), implies background${ptyDriveClause(status, write)}.` : " Commands run in the foreground to completion; timeout is the hard kill cap (default 30 minutes).";
|
|
47193
47566
|
const outputRules = backgroundOn ? " Finished output expires after the task is 24 hours old and its completion has been delivered; under project-root restrictions, only the starting session can read output outside the project—copy cited lines into your report." : "";
|
|
47194
47567
|
const timeoutRules = " `timeout` starts after spawn and kills the Unix process group (exit 124; Windows uses taskkill /T /F); processes that leave the group survive.";
|
|
47195
47568
|
const remoteRuns = surface.remoteRuns ? ` ${BASH_RUNON_GUIDANCE}` : "";
|
|
@@ -47665,6 +48038,55 @@ function failure(error) {
|
|
|
47665
48038
|
})();
|
|
47666
48039
|
return new Error(`V2 tool execution rejected with a non-Error value: ${detail}`);
|
|
47667
48040
|
}
|
|
48041
|
+
function tagOf(value) {
|
|
48042
|
+
return typeof value === "object" && value !== null ? value._tag : undefined;
|
|
48043
|
+
}
|
|
48044
|
+
function hostPermissionRefusal(error) {
|
|
48045
|
+
if (!(error instanceof BashPermissionLoopError) || !error.message)
|
|
48046
|
+
return error;
|
|
48047
|
+
const hostError = error.cause;
|
|
48048
|
+
if (!(hostError instanceof Error) || tagOf(hostError) !== "Tool.Error")
|
|
48049
|
+
return error;
|
|
48050
|
+
const inner = hostError.error;
|
|
48051
|
+
if (!(inner instanceof Error))
|
|
48052
|
+
return error;
|
|
48053
|
+
const text = error.message;
|
|
48054
|
+
try {
|
|
48055
|
+
const InnerClass = inner.constructor;
|
|
48056
|
+
let rebuilt;
|
|
48057
|
+
let shown;
|
|
48058
|
+
switch (tagOf(inner)) {
|
|
48059
|
+
case "Permission.BlockedError": {
|
|
48060
|
+
const { rules, permission, resources } = inner;
|
|
48061
|
+
rebuilt = new InnerClass({ rules, permission, resources, reason: text });
|
|
48062
|
+
shown = rebuilt.message;
|
|
48063
|
+
break;
|
|
48064
|
+
}
|
|
48065
|
+
case "Permission.CorrectedError":
|
|
48066
|
+
rebuilt = new InnerClass({ feedback: text });
|
|
48067
|
+
shown = rebuilt.feedback;
|
|
48068
|
+
break;
|
|
48069
|
+
default:
|
|
48070
|
+
return error;
|
|
48071
|
+
}
|
|
48072
|
+
if (!(rebuilt instanceof InnerClass) || tagOf(rebuilt) !== tagOf(inner) || shown !== text) {
|
|
48073
|
+
return error;
|
|
48074
|
+
}
|
|
48075
|
+
const ToolErrorClass = hostError.constructor;
|
|
48076
|
+
const metadata = hostError.metadata;
|
|
48077
|
+
const refusal = new ToolErrorClass({
|
|
48078
|
+
message: text,
|
|
48079
|
+
error: rebuilt,
|
|
48080
|
+
...metadata === undefined ? {} : { metadata }
|
|
48081
|
+
});
|
|
48082
|
+
if (!(refusal instanceof ToolErrorClass) || tagOf(refusal) !== "Tool.Error" || refusal.message !== text || refusal.error !== rebuilt) {
|
|
48083
|
+
return error;
|
|
48084
|
+
}
|
|
48085
|
+
return refusal;
|
|
48086
|
+
} catch {
|
|
48087
|
+
return error;
|
|
48088
|
+
}
|
|
48089
|
+
}
|
|
47668
48090
|
function isPlainObject3(value) {
|
|
47669
48091
|
if (typeof value !== "object" || value === null)
|
|
47670
48092
|
return false;
|
|
@@ -47875,7 +48297,7 @@ function projectV2Tool(name, definition, location, consumers = {}) {
|
|
|
47875
48297
|
} catch (error) {
|
|
47876
48298
|
if (stepAbort)
|
|
47877
48299
|
throw new PermissionStepAbort(stepAbort.error);
|
|
47878
|
-
throw error;
|
|
48300
|
+
throw hostPermissionRefusal(error);
|
|
47879
48301
|
} finally {
|
|
47880
48302
|
signal.removeEventListener("abort", onAbort);
|
|
47881
48303
|
}
|
|
@@ -47886,7 +48308,7 @@ function projectV2Tool(name, definition, location, consumers = {}) {
|
|
|
47886
48308
|
}
|
|
47887
48309
|
|
|
47888
48310
|
// src/tools/hoisted.ts
|
|
47889
|
-
import { stat as
|
|
48311
|
+
import { stat as stat4 } from "node:fs/promises";
|
|
47890
48312
|
import * as path4 from "node:path";
|
|
47891
48313
|
|
|
47892
48314
|
// src/hashline-tag-sources.ts
|
|
@@ -48005,19 +48427,22 @@ function coerceConfiguredWatchTimeout(value, role, cap) {
|
|
|
48005
48427
|
throw new Error(`${message} (bash.watch_sync_max_ms)`);
|
|
48006
48428
|
}
|
|
48007
48429
|
}
|
|
48008
|
-
|
|
48430
|
+
var PRIMARY_ASYNC_WATCH_SENTENCES = " The user can interrupt anytime; the wait auto-converts to an async notification. Async (background:true, requires pattern) registers a non-blocking notification and returns immediately — use when you have parallel work or want to end your turn.";
|
|
48431
|
+
function bashWatchDescription(role, statusRegistered, asyncWatches = true) {
|
|
48009
48432
|
const noPolling = statusRegistered ? " Never loop bash_status to wait." : "";
|
|
48010
48433
|
if (role === "worker") {
|
|
48011
48434
|
return `Watch a background bash task and wait until it exits or prints a pattern. ${WATCH_SYNC_DEFAULTS_DESCRIPTION}. A background task never wakes you, so wait on it before you report a result. ${WORKER_KEEP_WAITING}${noPolling}`;
|
|
48012
48435
|
}
|
|
48013
|
-
|
|
48436
|
+
const asyncSentences = asyncWatches ? PRIMARY_ASYNC_WATCH_SENTENCES : "";
|
|
48437
|
+
return `Watch a background bash task. ${WATCH_SYNC_DEFAULTS_DESCRIPTION}. In a main session sync waits are for a short remaining wait on a task; for anything longer, first do the work that doesn't need the result, end the turn only when everything left needs it, and let the completion reminder wake you, or use \`bash({wait:true})\` when the result is needed before anything else.${asyncSentences}${noPolling}`;
|
|
48014
48438
|
}
|
|
48439
|
+
var WATCH_PATTERN_MODES_SENTENCE = " Optional in sync mode; required with background:true.";
|
|
48015
48440
|
function createBashWatchTool(ctx) {
|
|
48016
48441
|
return {
|
|
48017
48442
|
description: bashWatchDescription("primary", bashCompanionRegistered(ctx.config, "bash_status")),
|
|
48018
48443
|
args: {
|
|
48019
48444
|
taskId: z5.string().describe("Background task ID returned by bash({ background: true })."),
|
|
48020
|
-
pattern: z5.union([z5.string(), z5.object({ regex: z5.string() })]).optional().describe(
|
|
48445
|
+
pattern: z5.union([z5.string(), z5.object({ regex: z5.string() })]).optional().describe(`Substring or regex pattern.${WATCH_PATTERN_MODES_SENTENCE} Sync substring watches keep only the overlap tail needed for boundary matches; sync regex watches use a 64 KB rolling output window.`),
|
|
48021
48446
|
background: z5.boolean().optional().describe("When true, register an async watch and return immediately. Defaults to false (sync wait)."),
|
|
48022
48447
|
timeoutMs: optionalInt(1, 1800000).describe(WATCH_TIMEOUT_PARAM_DESCRIPTION),
|
|
48023
48448
|
deliver: z5.literal("each_line").optional().describe("Async-only: batch every matching complete line, fold consecutive duplicates, and report cap drops with byte offsets."),
|
|
@@ -48900,7 +49325,7 @@ function createReadTool(ctx) {
|
|
|
48900
49325
|
const ref = revisionRefArg(args.ref);
|
|
48901
49326
|
if (ref !== undefined)
|
|
48902
49327
|
rawArgs.ref = ref;
|
|
48903
|
-
const mediaCandidate = isGithubResourcePath(file) || /\.(png|jpe?g|gif|webp|pdf)$/i.test(filePath) && await
|
|
49328
|
+
const mediaCandidate = isGithubResourcePath(file) || /\.(png|jpe?g|gif|webp|pdf)$/i.test(filePath) && await stat4(filePath).then((info) => info.isFile(), () => false);
|
|
48904
49329
|
const visionCapability = mediaCandidate ? await measurePreStage("capability", () => currentSessionVisionCapability(ctx.client, context.sessionID)) : undefined;
|
|
48905
49330
|
if (visionCapability !== undefined)
|
|
48906
49331
|
rawArgs.vision_capability = visionCapability;
|
|
@@ -49571,7 +49996,7 @@ function importTools(ctx) {
|
|
|
49571
49996
|
}
|
|
49572
49997
|
|
|
49573
49998
|
// src/tools/inspect.ts
|
|
49574
|
-
import { stat as
|
|
49999
|
+
import { stat as stat5 } from "node:fs/promises";
|
|
49575
50000
|
var z9 = tool.schema;
|
|
49576
50001
|
var INSPECT_TRANSPORT_HEADROOM_MS = 30000;
|
|
49577
50002
|
function arg(schema) {
|
|
@@ -49595,7 +50020,7 @@ async function resolveAndGateScope(ctx, context, scope) {
|
|
|
49595
50020
|
});
|
|
49596
50021
|
if (denial)
|
|
49597
50022
|
return { scope: undefined, denial };
|
|
49598
|
-
if (!await
|
|
50023
|
+
if (!await stat5(target).then((entry) => entry.isDirectory(), () => false)) {
|
|
49599
50024
|
const readDenial = await assertV2ReadPermission(context, target);
|
|
49600
50025
|
if (readDenial)
|
|
49601
50026
|
return { scope: undefined, denial: readDenial };
|
|
@@ -49732,39 +50157,6 @@ function compactTerminalField(value, fallback) {
|
|
|
49732
50157
|
compact = compact?.replaceAll(internal, plain);
|
|
49733
50158
|
return compact || fallback;
|
|
49734
50159
|
}
|
|
49735
|
-
function createInspectTier2IdleScheduler(options) {
|
|
49736
|
-
const timers = new Map;
|
|
49737
|
-
const setTimer = options.setTimer ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
49738
|
-
const clearTimer = options.clearTimer ?? ((timer) => clearTimeout(timer));
|
|
49739
|
-
const clear = (sessionID) => {
|
|
49740
|
-
const timer = timers.get(sessionID);
|
|
49741
|
-
if (!timer)
|
|
49742
|
-
return;
|
|
49743
|
-
clearTimer(timer);
|
|
49744
|
-
timers.delete(sessionID);
|
|
49745
|
-
};
|
|
49746
|
-
const clearAll = () => {
|
|
49747
|
-
for (const timer of timers.values())
|
|
49748
|
-
clearTimer(timer);
|
|
49749
|
-
timers.clear();
|
|
49750
|
-
};
|
|
49751
|
-
const schedule = (sessionID) => {
|
|
49752
|
-
if (!options.isEnabled())
|
|
49753
|
-
return;
|
|
49754
|
-
clear(sessionID);
|
|
49755
|
-
const idleMinutes = options.idleMinutes() ?? 4;
|
|
49756
|
-
const delayMs = Math.max(0, idleMinutes * 60 * 1000);
|
|
49757
|
-
const timer = setTimer(() => {
|
|
49758
|
-
timers.delete(sessionID);
|
|
49759
|
-
options.run(sessionID).catch((err) => {
|
|
49760
|
-
options.warn?.(`inspect_tier2_run failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
49761
|
-
});
|
|
49762
|
-
}, delayMs);
|
|
49763
|
-
timer.unref?.();
|
|
49764
|
-
timers.set(sessionID, timer);
|
|
49765
|
-
};
|
|
49766
|
-
return { schedule, clear, clearAll };
|
|
49767
|
-
}
|
|
49768
50160
|
function inspectTools(ctx) {
|
|
49769
50161
|
const inspectTool = {
|
|
49770
50162
|
description: "Codebase health inspection that waits for current analysis. FRESH means the reported analysis is current. PARTIAL means some diagnostics are unknown; the header names the analyzer, reason, and retry guidance. INTERRUPTED means the request stopped without a fresh snapshot; retry aft_inspect. PHASE-FAILED means inspection could not finish; address the reported reason and retry, or narrow the scope. `sections` selects drill-down detail. Scoped requests collect diagnostics when sections is omitted or includes 'diagnostics' or 'all'; sections that leave diagnostics out skip diagnostics work. Unscoped requests keep warm diagnostics. Categories switched off in `inspect.categories` are not computed or refreshed, render as off, and never make the header PARTIAL.\n\n" + "Use `scope=` to narrow all findings, counts, and examples to those paths. Cross-boundary duplicates are labeled as groups touching the scope. Scope also limits Rust analyzer startup to the Cargo workspaces owning those paths when diagnostics are requested. Files without an authoritative diagnostic report remain named gaps (complete: false), not a clean result.\n\n" + `Use when: starting work on unfamiliar code, after multi-edit batches to check diagnostics, before a refactor, before review, or to verify cleanup completeness.
|
|
@@ -49819,7 +50211,7 @@ function navigationTools(ctx) {
|
|
|
49819
50211
|
` + `- 'callers': Find all call sites of a symbol. Use before renaming or changing a function's signature.
|
|
49820
50212
|
` + `- 'impact': What breaks if a symbol changes — affected callers with signatures and entry-point status (blast radius). Use before a risky edit.
|
|
49821
50213
|
` + `- 'call_tree': What a function calls (forward traversal). Use to understand a function's dependencies before modifying it.
|
|
49822
|
-
` + `- 'trace_to': How execution reaches a function
|
|
50214
|
+
` + `- 'trace_to': How execution reaches a function: each path of callers runs back to a root, labelled main, test, attribute, public API, or no caller found. Use to understand context around deeply-nested code.
|
|
49823
50215
|
` + `- 'trace_to_symbol': Shortest call path from one symbol to another. Requires 'toSymbol'. If multiple targets match, the error returns candidate files; retry with 'toPath' to disambiguate.
|
|
49824
50216
|
` + `- 'trace_data': Follow a value through variable assignments and function parameters across files. Requires 'symbol' (scope to trace from) and 'expression'.
|
|
49825
50217
|
|
|
@@ -51280,7 +51672,7 @@ function startOpenCodeLiveConfigReload(options) {
|
|
|
51280
51672
|
// src/notifications.ts
|
|
51281
51673
|
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "node:fs";
|
|
51282
51674
|
import { homedir as homedir14, platform } from "node:os";
|
|
51283
|
-
import { join as
|
|
51675
|
+
import { join as join24 } from "node:path";
|
|
51284
51676
|
function isTuiMode() {
|
|
51285
51677
|
return process.env.OPENCODE_CLIENT === "cli";
|
|
51286
51678
|
}
|
|
@@ -51302,15 +51694,15 @@ function getDesktopStatePath() {
|
|
|
51302
51694
|
const os = platform();
|
|
51303
51695
|
const home = homedir14();
|
|
51304
51696
|
if (os === "darwin") {
|
|
51305
|
-
return
|
|
51697
|
+
return join24(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
|
|
51306
51698
|
}
|
|
51307
51699
|
if (os === "linux") {
|
|
51308
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
51309
|
-
return
|
|
51700
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join24(home, ".config");
|
|
51701
|
+
return join24(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
|
|
51310
51702
|
}
|
|
51311
51703
|
if (os === "win32") {
|
|
51312
|
-
const appData = process.env.APPDATA ||
|
|
51313
|
-
return
|
|
51704
|
+
const appData = process.env.APPDATA || join24(home, "AppData", "Roaming");
|
|
51705
|
+
return join24(appData, "ai.opencode.desktop", "opencode.global.dat");
|
|
51314
51706
|
}
|
|
51315
51707
|
return null;
|
|
51316
51708
|
}
|
|
@@ -51822,47 +52214,47 @@ async function flushConfigureWarningsOnIdle(sessionId) {
|
|
|
51822
52214
|
// src/hooks/auto-update-checker/index.ts
|
|
51823
52215
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
51824
52216
|
import {
|
|
51825
|
-
closeSync as
|
|
52217
|
+
closeSync as closeSync13,
|
|
51826
52218
|
existsSync as existsSync20,
|
|
51827
|
-
fstatSync as
|
|
52219
|
+
fstatSync as fstatSync4,
|
|
51828
52220
|
linkSync,
|
|
51829
52221
|
mkdirSync as mkdirSync8,
|
|
51830
|
-
openSync as
|
|
52222
|
+
openSync as openSync12,
|
|
51831
52223
|
readFileSync as readFileSync17,
|
|
51832
52224
|
renameSync as renameSync10,
|
|
51833
52225
|
rmSync as rmSync8,
|
|
51834
52226
|
statSync as statSync17,
|
|
51835
52227
|
writeFileSync as writeFileSync11
|
|
51836
52228
|
} from "node:fs";
|
|
51837
|
-
import { dirname as
|
|
52229
|
+
import { dirname as dirname16 } from "node:path";
|
|
51838
52230
|
|
|
51839
52231
|
// src/hooks/auto-update-checker/cache.ts
|
|
51840
52232
|
import { cpSync, existsSync as existsSync19, mkdtempSync, readFileSync as readFileSync16, rmSync as rmSync7, writeFileSync as writeFileSync10 } from "node:fs";
|
|
51841
52233
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
51842
|
-
import { basename as basename5, dirname as
|
|
52234
|
+
import { basename as basename5, dirname as dirname15, join as join27 } from "node:path";
|
|
51843
52235
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
51844
52236
|
|
|
51845
52237
|
// src/hooks/auto-update-checker/checker.ts
|
|
51846
52238
|
import { existsSync as existsSync18, readFileSync as readFileSync15, statSync as statSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
51847
|
-
import { readFile } from "node:fs/promises";
|
|
52239
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
51848
52240
|
import { homedir as homedir15 } from "node:os";
|
|
51849
|
-
import { dirname as
|
|
52241
|
+
import { dirname as dirname14, isAbsolute as isAbsolute14, join as join26, resolve as resolve17 } from "node:path";
|
|
51850
52242
|
import { fileURLToPath } from "node:url";
|
|
51851
52243
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
51852
52244
|
|
|
51853
52245
|
// src/hooks/auto-update-checker/constants.ts
|
|
51854
|
-
import { join as
|
|
52246
|
+
import { join as join25 } from "node:path";
|
|
51855
52247
|
var PACKAGE_NAME = "@cortexkit/aft-opencode";
|
|
51856
52248
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
51857
52249
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
51858
52250
|
function cacheDir() {
|
|
51859
|
-
return
|
|
52251
|
+
return join25(getOpenCodeCacheRoot(), "packages");
|
|
51860
52252
|
}
|
|
51861
52253
|
function userOpenCodeConfig() {
|
|
51862
|
-
return
|
|
52254
|
+
return join25(getOpenCodeConfigRoot(), "opencode.json");
|
|
51863
52255
|
}
|
|
51864
52256
|
function userOpenCodeConfigJsonc() {
|
|
51865
|
-
return
|
|
52257
|
+
return join25(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
51866
52258
|
}
|
|
51867
52259
|
|
|
51868
52260
|
// src/hooks/auto-update-checker/types.ts
|
|
@@ -51921,8 +52313,8 @@ function extractChannel(version) {
|
|
|
51921
52313
|
}
|
|
51922
52314
|
function getConfigPaths(directory) {
|
|
51923
52315
|
return [
|
|
51924
|
-
|
|
51925
|
-
|
|
52316
|
+
join26(directory, ".opencode", "opencode.json"),
|
|
52317
|
+
join26(directory, ".opencode", "opencode.jsonc"),
|
|
51926
52318
|
userOpenCodeConfig(),
|
|
51927
52319
|
userOpenCodeConfigJsonc()
|
|
51928
52320
|
];
|
|
@@ -51937,7 +52329,7 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
51937
52329
|
}
|
|
51938
52330
|
if (isAbsolute14(spec) || /^[A-Za-z]:[\\/]/.test(spec))
|
|
51939
52331
|
return spec;
|
|
51940
|
-
return
|
|
52332
|
+
return resolve17(dirname14(configPath), spec);
|
|
51941
52333
|
}
|
|
51942
52334
|
function getLocalDevPath(directory) {
|
|
51943
52335
|
for (const configPath of getConfigPaths(directory)) {
|
|
@@ -51966,9 +52358,9 @@ function getLocalDevPath(directory) {
|
|
|
51966
52358
|
function findPackageJsonUp(startPath) {
|
|
51967
52359
|
try {
|
|
51968
52360
|
const stat = statSync16(startPath);
|
|
51969
|
-
let dir = stat.isDirectory() ? startPath :
|
|
52361
|
+
let dir = stat.isDirectory() ? startPath : dirname14(startPath);
|
|
51970
52362
|
for (let i = 0;i < 10; i++) {
|
|
51971
|
-
const pkgPath =
|
|
52363
|
+
const pkgPath = join26(dir, "package.json");
|
|
51972
52364
|
if (existsSync18(pkgPath)) {
|
|
51973
52365
|
try {
|
|
51974
52366
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync15(pkgPath, "utf-8")));
|
|
@@ -51976,7 +52368,7 @@ function findPackageJsonUp(startPath) {
|
|
|
51976
52368
|
return pkgPath;
|
|
51977
52369
|
} catch {}
|
|
51978
52370
|
}
|
|
51979
|
-
const parent =
|
|
52371
|
+
const parent = dirname14(dir);
|
|
51980
52372
|
if (parent === dir)
|
|
51981
52373
|
break;
|
|
51982
52374
|
dir = parent;
|
|
@@ -52000,7 +52392,7 @@ function getLocalDevVersion(directory) {
|
|
|
52000
52392
|
}
|
|
52001
52393
|
function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
52002
52394
|
try {
|
|
52003
|
-
return findPackageJsonUp(
|
|
52395
|
+
return findPackageJsonUp(dirname14(fileURLToPath(currentModuleUrl)));
|
|
52004
52396
|
} catch (err) {
|
|
52005
52397
|
warn2(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
|
|
52006
52398
|
return null;
|
|
@@ -52034,7 +52426,7 @@ function findPluginEntry(directory) {
|
|
|
52034
52426
|
}
|
|
52035
52427
|
var cachedPackageVersion = null;
|
|
52036
52428
|
function getSpecCachePackageJsonPath(spec) {
|
|
52037
|
-
return
|
|
52429
|
+
return join26(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
52038
52430
|
}
|
|
52039
52431
|
function getCachedVersion(spec) {
|
|
52040
52432
|
if (!spec && cachedPackageVersion)
|
|
@@ -52043,7 +52435,7 @@ function getCachedVersion(spec) {
|
|
|
52043
52435
|
getCurrentRuntimePackageJsonPath(),
|
|
52044
52436
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
52045
52437
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
52046
|
-
|
|
52438
|
+
join26(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
|
|
52047
52439
|
].filter(isString);
|
|
52048
52440
|
for (const packageJsonPath of candidates) {
|
|
52049
52441
|
try {
|
|
@@ -52081,7 +52473,7 @@ function configuredRegistry(value) {
|
|
|
52081
52473
|
async function readRegistrySettings(path, required = false) {
|
|
52082
52474
|
let text;
|
|
52083
52475
|
try {
|
|
52084
|
-
text = await
|
|
52476
|
+
text = await readFile2(path, "utf8");
|
|
52085
52477
|
} catch (error) {
|
|
52086
52478
|
if (!required && error.code === "ENOENT")
|
|
52087
52479
|
return {};
|
|
@@ -52111,20 +52503,20 @@ async function registryWithoutNpm(directory) {
|
|
|
52111
52503
|
let scoped = registryEnvironment("@cortexkit:registry");
|
|
52112
52504
|
let registry = registryEnvironment("registry");
|
|
52113
52505
|
const visited = new Set;
|
|
52114
|
-
for (let current = directory;; current =
|
|
52506
|
+
for (let current = directory;; current = dirname14(current)) {
|
|
52115
52507
|
if (scoped)
|
|
52116
52508
|
break;
|
|
52117
|
-
const path =
|
|
52509
|
+
const path = join26(current, ".npmrc");
|
|
52118
52510
|
visited.add(path);
|
|
52119
52511
|
const settings = await readRegistrySettings(path);
|
|
52120
52512
|
scoped ??= settings["@cortexkit:registry"];
|
|
52121
52513
|
registry ??= settings.registry;
|
|
52122
|
-
if (
|
|
52514
|
+
if (dirname14(current) === current)
|
|
52123
52515
|
break;
|
|
52124
52516
|
}
|
|
52125
52517
|
const explicitUserConfig = process.env.npm_config_userconfig ?? process.env.NPM_CONFIG_USERCONFIG;
|
|
52126
52518
|
const home = (process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME) ?? homedir15();
|
|
52127
|
-
const userConfig = explicitUserConfig ??
|
|
52519
|
+
const userConfig = explicitUserConfig ?? join26(home, ".npmrc");
|
|
52128
52520
|
if (!scoped && !visited.has(userConfig)) {
|
|
52129
52521
|
const settings = await readRegistrySettings(userConfig, explicitUserConfig !== undefined);
|
|
52130
52522
|
scoped = settings["@cortexkit:registry"];
|
|
@@ -52146,14 +52538,14 @@ function validateRegistry(registry) {
|
|
|
52146
52538
|
}
|
|
52147
52539
|
var reportedRegistryFailures = new Set;
|
|
52148
52540
|
function reportRegistryFailure(directory) {
|
|
52149
|
-
const key =
|
|
52541
|
+
const key = resolve17(directory);
|
|
52150
52542
|
if (reportedRegistryFailures.has(key))
|
|
52151
52543
|
return;
|
|
52152
52544
|
reportedRegistryFailures.add(key);
|
|
52153
52545
|
debug2("[auto-update-checker] Configured npm registry could not be resolved or used; skipping update check.");
|
|
52154
52546
|
}
|
|
52155
52547
|
function resolveRegistry(directory) {
|
|
52156
|
-
const key =
|
|
52548
|
+
const key = resolve17(directory);
|
|
52157
52549
|
let pending = registryCache.get(key);
|
|
52158
52550
|
if (!pending) {
|
|
52159
52551
|
pending = (async () => {
|
|
@@ -52210,10 +52602,10 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
52210
52602
|
var pendingSnapshots = new Map;
|
|
52211
52603
|
var quarantinedInstallDirs = new Set;
|
|
52212
52604
|
function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
|
|
52213
|
-
const packageDir =
|
|
52214
|
-
const lockfilePath =
|
|
52215
|
-
const tempDir = mkdtempSync(
|
|
52216
|
-
const stagedPackageDir = existsSync19(packageDir) ?
|
|
52605
|
+
const packageDir = join27(installDir, "node_modules", packageName);
|
|
52606
|
+
const lockfilePath = join27(installDir, "package-lock.json");
|
|
52607
|
+
const tempDir = mkdtempSync(join27(tmpdir4(), "aft-auto-update-"));
|
|
52608
|
+
const stagedPackageDir = existsSync19(packageDir) ? join27(tempDir, "package") : null;
|
|
52217
52609
|
if (stagedPackageDir)
|
|
52218
52610
|
cpSync(packageDir, stagedPackageDir, { recursive: true });
|
|
52219
52611
|
return {
|
|
@@ -52249,12 +52641,12 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
52249
52641
|
for (const segment of [...packageName.split("/")].reverse()) {
|
|
52250
52642
|
if (basename5(current) !== segment)
|
|
52251
52643
|
return null;
|
|
52252
|
-
current =
|
|
52644
|
+
current = dirname15(current);
|
|
52253
52645
|
}
|
|
52254
52646
|
return current;
|
|
52255
52647
|
}
|
|
52256
52648
|
function removeFromPackageLock(installDir, packageName) {
|
|
52257
|
-
const lockPath =
|
|
52649
|
+
const lockPath = join27(installDir, "package-lock.json");
|
|
52258
52650
|
if (!existsSync19(lockPath))
|
|
52259
52651
|
return false;
|
|
52260
52652
|
try {
|
|
@@ -52310,7 +52702,7 @@ function restorePendingSnapshot(installDir) {
|
|
|
52310
52702
|
restoreAutoUpdateSnapshot(snapshot);
|
|
52311
52703
|
}
|
|
52312
52704
|
function removeInstalledPackage(installDir, packageName) {
|
|
52313
|
-
const packageDir =
|
|
52705
|
+
const packageDir = join27(installDir, "node_modules", packageName);
|
|
52314
52706
|
if (!existsSync19(packageDir))
|
|
52315
52707
|
return false;
|
|
52316
52708
|
rmSync7(packageDir, { recursive: true, force: true });
|
|
@@ -52319,18 +52711,18 @@ function removeInstalledPackage(installDir, packageName) {
|
|
|
52319
52711
|
}
|
|
52320
52712
|
function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackageJsonPath()) {
|
|
52321
52713
|
if (runtimePackageJsonPath) {
|
|
52322
|
-
const packageDir =
|
|
52714
|
+
const packageDir = dirname15(runtimePackageJsonPath);
|
|
52323
52715
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
52324
52716
|
if (nodeModulesDir && basename5(nodeModulesDir) === "node_modules") {
|
|
52325
|
-
const installDir =
|
|
52326
|
-
const packageJsonPath =
|
|
52717
|
+
const installDir = dirname15(nodeModulesDir);
|
|
52718
|
+
const packageJsonPath = join27(installDir, "package.json");
|
|
52327
52719
|
if (existsSync19(packageJsonPath))
|
|
52328
52720
|
return { installDir, packageJsonPath };
|
|
52329
52721
|
}
|
|
52330
52722
|
return null;
|
|
52331
52723
|
}
|
|
52332
|
-
const cacheRoot =
|
|
52333
|
-
const legacyPackageJsonPath =
|
|
52724
|
+
const cacheRoot = dirname15(cacheDir());
|
|
52725
|
+
const legacyPackageJsonPath = join27(cacheRoot, "package.json");
|
|
52334
52726
|
if (existsSync19(legacyPackageJsonPath)) {
|
|
52335
52727
|
return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
|
|
52336
52728
|
}
|
|
@@ -52532,19 +52924,19 @@ function claimCheckSlot(storageDir, intervalMs, testHooks = {}) {
|
|
|
52532
52924
|
try {
|
|
52533
52925
|
if (hasRecentCheckTimestamp(file, intervalMs))
|
|
52534
52926
|
return null;
|
|
52535
|
-
mkdirSync8(
|
|
52927
|
+
mkdirSync8(dirname16(file), { recursive: true });
|
|
52536
52928
|
const lockPath = `${file}.lock`;
|
|
52537
52929
|
const owner = { pid: process.pid, startedMs: Date.now(), token: randomUUID4() };
|
|
52538
52930
|
let lockFd = null;
|
|
52539
52931
|
try {
|
|
52540
|
-
lockFd =
|
|
52932
|
+
lockFd = openSync12(lockPath, "wx");
|
|
52541
52933
|
writeFileSync11(lockFd, JSON.stringify(owner));
|
|
52542
|
-
|
|
52934
|
+
closeSync13(lockFd);
|
|
52543
52935
|
lockFd = null;
|
|
52544
52936
|
} catch (err) {
|
|
52545
52937
|
if (lockFd !== null) {
|
|
52546
52938
|
try {
|
|
52547
|
-
|
|
52939
|
+
closeSync13(lockFd);
|
|
52548
52940
|
} catch {}
|
|
52549
52941
|
}
|
|
52550
52942
|
if (err.code !== "EEXIST")
|
|
@@ -52562,7 +52954,7 @@ function claimCheckSlot(storageDir, intervalMs, testHooks = {}) {
|
|
|
52562
52954
|
return null;
|
|
52563
52955
|
}
|
|
52564
52956
|
try {
|
|
52565
|
-
lockFd =
|
|
52957
|
+
lockFd = openSync12(lockPath, "wx");
|
|
52566
52958
|
} catch (claimError) {
|
|
52567
52959
|
if (claimError.code === "EEXIST")
|
|
52568
52960
|
return null;
|
|
@@ -52571,11 +52963,11 @@ function claimCheckSlot(storageDir, intervalMs, testHooks = {}) {
|
|
|
52571
52963
|
try {
|
|
52572
52964
|
writeFileSync11(lockFd, JSON.stringify(owner));
|
|
52573
52965
|
} finally {
|
|
52574
|
-
|
|
52966
|
+
closeSync13(lockFd);
|
|
52575
52967
|
lockFd = null;
|
|
52576
52968
|
}
|
|
52577
52969
|
} finally {
|
|
52578
|
-
|
|
52970
|
+
closeSync13(reclaimFd);
|
|
52579
52971
|
releaseCheckLock(reclaimPath, owner);
|
|
52580
52972
|
}
|
|
52581
52973
|
}
|
|
@@ -52658,12 +53050,12 @@ function claimObservedCheckLock(lockPath, observed, testHooks = {}) {
|
|
|
52658
53050
|
return true;
|
|
52659
53051
|
}
|
|
52660
53052
|
function writeReclaimGuard(reclaimPath, owner) {
|
|
52661
|
-
const fd =
|
|
53053
|
+
const fd = openSync12(reclaimPath, "wx");
|
|
52662
53054
|
try {
|
|
52663
53055
|
writeFileSync11(fd, JSON.stringify(owner));
|
|
52664
53056
|
return fd;
|
|
52665
53057
|
} catch (error) {
|
|
52666
|
-
|
|
53058
|
+
closeSync13(fd);
|
|
52667
53059
|
throw error;
|
|
52668
53060
|
}
|
|
52669
53061
|
}
|
|
@@ -52690,14 +53082,14 @@ function readCheckLockState(lockPath) {
|
|
|
52690
53082
|
let content;
|
|
52691
53083
|
try {
|
|
52692
53084
|
const observed = statSync17(lockPath, { bigint: true });
|
|
52693
|
-
const fd =
|
|
53085
|
+
const fd = openSync12(lockPath, "r");
|
|
52694
53086
|
try {
|
|
52695
|
-
info =
|
|
53087
|
+
info = fstatSync4(fd, { bigint: true });
|
|
52696
53088
|
if (info.dev !== observed.dev || info.ino !== observed.ino)
|
|
52697
53089
|
return null;
|
|
52698
53090
|
content = readFileSync17(fd, "utf-8");
|
|
52699
53091
|
} finally {
|
|
52700
|
-
|
|
53092
|
+
closeSync13(fd);
|
|
52701
53093
|
}
|
|
52702
53094
|
} catch (error) {
|
|
52703
53095
|
if (error.code === "ENOENT")
|
|
@@ -52847,10 +53239,10 @@ function showToast(ctx, title, message, variant = "info", duration = 3000) {
|
|
|
52847
53239
|
}
|
|
52848
53240
|
|
|
52849
53241
|
// src/plugin-version.ts
|
|
52850
|
-
import { createRequire as
|
|
53242
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
52851
53243
|
var PLUGIN_PACKAGE_NAME = "@cortexkit/aft-opencode";
|
|
52852
53244
|
function resolvePluginVersion(importMetaUrl) {
|
|
52853
|
-
const req =
|
|
53245
|
+
const req = createRequire3(importMetaUrl);
|
|
52854
53246
|
for (const candidate of ["../package.json", "../../package.json", "../../../package.json"]) {
|
|
52855
53247
|
try {
|
|
52856
53248
|
const manifest = req(candidate);
|
|
@@ -52956,16 +53348,16 @@ import {
|
|
|
52956
53348
|
writeFileSync as writeFileSync12
|
|
52957
53349
|
} from "node:fs";
|
|
52958
53350
|
import { createServer } from "node:http";
|
|
52959
|
-
import { dirname as
|
|
53351
|
+
import { dirname as dirname17, join as join29 } from "node:path";
|
|
52960
53352
|
|
|
52961
53353
|
// src/shared/rpc-utils.ts
|
|
52962
|
-
import { join as
|
|
53354
|
+
import { join as join28 } from "node:path";
|
|
52963
53355
|
function projectHash(directory) {
|
|
52964
53356
|
return projectRootKeyHash(directory);
|
|
52965
53357
|
}
|
|
52966
53358
|
function rpcPortFileDir(storageDir, directory) {
|
|
52967
53359
|
const hash = projectHash(directory);
|
|
52968
|
-
return
|
|
53360
|
+
return join28(storageDir, "rpc", hash, "ports");
|
|
52969
53361
|
}
|
|
52970
53362
|
function isPidAlive(pid) {
|
|
52971
53363
|
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
|
|
@@ -53042,7 +53434,7 @@ class AftRpcServer {
|
|
|
53042
53434
|
constructor(storageDir, directory) {
|
|
53043
53435
|
this.portsDir = rpcPortFileDir(storageDir, directory);
|
|
53044
53436
|
this.instanceId = randomBytes5(8).toString("hex");
|
|
53045
|
-
this.portFilePath =
|
|
53437
|
+
this.portFilePath = join29(this.portsDir, `${this.instanceId}.json`);
|
|
53046
53438
|
}
|
|
53047
53439
|
handle(method, handler) {
|
|
53048
53440
|
this.handlers.set(method, handler);
|
|
@@ -53119,7 +53511,7 @@ class AftRpcServer {
|
|
|
53119
53511
|
}
|
|
53120
53512
|
}
|
|
53121
53513
|
writePortFile() {
|
|
53122
|
-
const dir =
|
|
53514
|
+
const dir = dirname17(this.portFilePath);
|
|
53123
53515
|
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
53124
53516
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
53125
53517
|
writeFileSync12(tmpPath, JSON.stringify({
|
|
@@ -53141,13 +53533,13 @@ class AftRpcServer {
|
|
|
53141
53533
|
const temporary = entry.endsWith(".json.tmp");
|
|
53142
53534
|
if (!temporary && !entry.endsWith(".json"))
|
|
53143
53535
|
continue;
|
|
53144
|
-
const filePath =
|
|
53536
|
+
const filePath = join29(this.portsDir, entry);
|
|
53145
53537
|
if (filePath === this.portFilePath)
|
|
53146
53538
|
continue;
|
|
53147
53539
|
try {
|
|
53148
53540
|
const record = parseRpcPortRecord(readFileSync18(filePath, "utf-8"));
|
|
53149
53541
|
if (record === null) {
|
|
53150
|
-
if (!temporary || Date.now() - statSync18(
|
|
53542
|
+
if (!temporary || Date.now() - statSync18(join29(this.portsDir, entry)).mtimeMs >= UNREADABLE_TMP_MAX_AGE_MS) {
|
|
53151
53543
|
unlinkSync7(filePath);
|
|
53152
53544
|
}
|
|
53153
53545
|
continue;
|
|
@@ -53455,9 +53847,6 @@ function readStatusBar(value) {
|
|
|
53455
53847
|
const disabled = Array.isArray(bar.disabled_categories) ? bar.disabled_categories.filter((key) => typeof key === "string") : [];
|
|
53456
53848
|
const errors = readOptionalNumber(bar.errors);
|
|
53457
53849
|
const warnings = readOptionalNumber(bar.warnings);
|
|
53458
|
-
const deadCode = readOptionalNumber(bar.dead_code);
|
|
53459
|
-
const unusedExports = readOptionalNumber(bar.unused_exports);
|
|
53460
|
-
const duplicates = readOptionalNumber(bar.duplicates);
|
|
53461
53850
|
const todos = readOptionalNumber(bar.todos);
|
|
53462
53851
|
const noLanguageServer = bar.diagnostics === "no_language_server";
|
|
53463
53852
|
const producerMissing = bar.diagnostics === "producer_missing";
|
|
@@ -53466,18 +53855,14 @@ function readStatusBar(value) {
|
|
|
53466
53855
|
producer: gap.producer,
|
|
53467
53856
|
root: gap.root
|
|
53468
53857
|
})) : [];
|
|
53469
|
-
if (errors === null && warnings === null &&
|
|
53858
|
+
if (errors === null && warnings === null && todos === null && !noLanguageServer && !producerMissing && disabled.length === 0) {
|
|
53470
53859
|
return;
|
|
53471
53860
|
}
|
|
53472
53861
|
return {
|
|
53473
53862
|
...disabled.length > 0 ? { disabled_categories: disabled } : {},
|
|
53474
53863
|
...errors !== null ? { errors } : {},
|
|
53475
53864
|
...warnings !== null ? { warnings } : {},
|
|
53476
|
-
...deadCode !== null ? { dead_code: deadCode } : {},
|
|
53477
|
-
...unusedExports !== null ? { unused_exports: unusedExports } : {},
|
|
53478
|
-
...duplicates !== null ? { duplicates } : {},
|
|
53479
53865
|
...todos !== null ? { todos } : {},
|
|
53480
|
-
...bar.tier2_stale === true ? { tier2_stale: true } : {},
|
|
53481
53866
|
...noLanguageServer ? { diagnostics: "no_language_server" } : {},
|
|
53482
53867
|
...producerMissing ? { diagnostics: "producer_missing", diagnostics_gaps: diagnosticsGaps } : {}
|
|
53483
53868
|
};
|
|
@@ -53671,13 +54056,10 @@ function formatStatusMarkdown(status) {
|
|
|
53671
54056
|
const rows = [
|
|
53672
54057
|
["Errors", sb.errors],
|
|
53673
54058
|
["Warnings", sb.warnings],
|
|
53674
|
-
["Dead code", sb.dead_code],
|
|
53675
|
-
["Unused exports", sb.unused_exports],
|
|
53676
|
-
["Duplicates", sb.duplicates],
|
|
53677
54059
|
["TODOs", sb.todos]
|
|
53678
54060
|
].filter((row) => typeof row[1] === "number");
|
|
53679
54061
|
if (rows.length > 0) {
|
|
53680
|
-
lines.push("",
|
|
54062
|
+
lines.push("", "### Code Health");
|
|
53681
54063
|
for (const [label, value] of rows)
|
|
53682
54064
|
lines.push(`- **${label}:** ${formatCount(value)}`);
|
|
53683
54065
|
}
|
|
@@ -53848,15 +54230,15 @@ function buildWorkflowHints(opts) {
|
|
|
53848
54230
|
`));
|
|
53849
54231
|
}
|
|
53850
54232
|
if (hasInspect) {
|
|
53851
|
-
sections.push("**Codebase health & diagnostics**: AFT does not surface compile/type errors automatically after edits — pull them with `aft_inspect`. Run it after a batch of edits and before you run tests or commit, when starting in unfamiliar code, or before a refactor/review. One call summarizes diagnostics (compile/type errors), TODOs, metrics, dead code, unused exports, and duplicates; pass `sections` for focused drill-down and `scope` to actively pull diagnostics for a specific file or directory. Its diagnostics are a fast checkpoint, not the authority — a clean `tsc` / `cargo check` / `pyright` run is the real gate.
|
|
53852
|
-
sections.push("**AFT status bar**: tool results may end with a one-line health bar `[AFT E<errors> W<warnings> |
|
|
54233
|
+
sections.push("**Codebase health & diagnostics**: AFT does not surface compile/type errors automatically after edits — pull them with `aft_inspect`. Run it after a batch of edits and before you run tests or commit, when starting in unfamiliar code, or before a refactor/review. One call summarizes diagnostics (compile/type errors), TODOs, metrics, dead code, unused exports, and duplicates; pass `sections` for focused drill-down and `scope` to actively pull diagnostics for a specific file or directory. Its diagnostics are a fast checkpoint, not the authority — a clean `tsc` / `cargo check` / `pyright` run is the real gate. Dead code, unused exports, duplicates, cycles and complexity are computed only when you call aft_inspect, and the call waits until they are current; nothing refreshes them in the background, so run it again after further edits instead of polling.");
|
|
54234
|
+
sections.push("**AFT status bar**: tool results may end with a one-line health bar `[AFT E<errors> W<warnings> | T<todos>]` — an IDE-style glance that appears when a count changes. `E`/`W` are live LSP diagnostics for files touched this session (your universal compile-error signal across every language with an LSP). Dead code, unused exports and duplicates are not on the bar; run `aft_inspect` for them. A `?` in place of a number means that count has no value yet (not zero). When `E>0`, you likely just introduced errors; investigate before moving on.");
|
|
53853
54235
|
}
|
|
53854
54236
|
if (hasNavigate) {
|
|
53855
54237
|
sections.push([
|
|
53856
54238
|
"Use `aft_callgraph` for code-relationship questions instead of grep + read chains:",
|
|
53857
54239
|
"- `callers` — find all call sites before changing a function signature",
|
|
53858
54240
|
"- `impact` — blast radius (which functions/files will need updates)",
|
|
53859
|
-
"- `trace_to` — how execution reaches this code
|
|
54241
|
+
"- `trace_to` — how execution reaches this code; each path runs back to a root labelled main, test, attribute, public API, or no caller found",
|
|
53860
54242
|
"- `trace_to_symbol` — shortest call path from one symbol to another",
|
|
53861
54243
|
"- `trace_data` — follow a value through assignments and parameters across files"
|
|
53862
54244
|
].join(`
|
|
@@ -53948,12 +54330,12 @@ function throwSentinel(command) {
|
|
|
53948
54330
|
throw sentinel;
|
|
53949
54331
|
}
|
|
53950
54332
|
var PLUGIN_VERSION = resolvePluginVersion(import.meta.url);
|
|
53951
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
54333
|
+
var ANNOUNCEMENT_VERSION = "0.64.0";
|
|
53952
54334
|
var ANNOUNCEMENT_FEATURES = [
|
|
53953
|
-
"
|
|
53954
|
-
"
|
|
53955
|
-
"
|
|
53956
|
-
"
|
|
54335
|
+
"A new index store makes AFT much faster: call graphs build 26x faster, edits reach the call graph about 9x faster, dead-code checks run 4x faster, and the index takes 4x less disk and 3x less memory.",
|
|
54336
|
+
"All worktrees of a repository share one index, so a new worktree is ready in under a second. `npx @cortexkit/aft cache prune-legacy` lists the old index folders and can remove them.",
|
|
54337
|
+
"`trace_to` labels each root it reaches: main, test, attribute, public API, or no caller found.",
|
|
54338
|
+
"Dead code, unused exports, duplicates, cycles and complexity run only when `aft_inspect` is called; the status bar shows errors, warnings and TODOs."
|
|
53957
54339
|
];
|
|
53958
54340
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
53959
54341
|
var plugin = async (input) => initializePluginForDirectory(input);
|
|
@@ -54164,13 +54546,11 @@ async function initializePluginForDirectory(input) {
|
|
|
54164
54546
|
return result;
|
|
54165
54547
|
};
|
|
54166
54548
|
const rpcServer = new AftRpcServer(configOverrides.storage_dir, input.directory);
|
|
54167
|
-
let clearInspectTier2Idle = () => {};
|
|
54168
54549
|
let clearAnnouncementTimer = () => {};
|
|
54169
54550
|
const shutdownCleanup = registerShutdownCleanup(async (reason) => {
|
|
54170
54551
|
cancelPendingWakesForContext(ctx);
|
|
54171
54552
|
autoUpdateAbort.abort();
|
|
54172
54553
|
liveConfigReload.stop();
|
|
54173
|
-
clearInspectTier2Idle();
|
|
54174
54554
|
clearAnnouncementTimer();
|
|
54175
54555
|
for (const unsubscribe of statusUnsubscribes) {
|
|
54176
54556
|
try {
|
|
@@ -54304,22 +54684,6 @@ Install: ${getManualInstallHint()}`);
|
|
|
54304
54684
|
if (hintsBlock) {
|
|
54305
54685
|
log2(`Workflow hints injected (${hintsBlock.length} chars)`);
|
|
54306
54686
|
}
|
|
54307
|
-
const inspectTier2Idle = createInspectTier2IdleScheduler({
|
|
54308
|
-
isEnabled: () => registeredTools.has("aft_inspect"),
|
|
54309
|
-
idleMinutes: () => ctx.config.inspect?.tier2_idle_minutes,
|
|
54310
|
-
warn: warn2,
|
|
54311
|
-
run: async (sessionID) => {
|
|
54312
|
-
const sessionDir = await getSessionDirectory(input.client, sessionID, input.directory) ?? input.directory;
|
|
54313
|
-
if (!isProjectEnabled(sessionDir))
|
|
54314
|
-
return;
|
|
54315
|
-
const bridge = ctx.pool.getActiveBridgeForRoot(sessionDir) ?? ctx.pool.getBridge(sessionDir);
|
|
54316
|
-
const response = await bridge.send("inspect_tier2_run", { session_id: sessionID });
|
|
54317
|
-
if (response.success === false) {
|
|
54318
|
-
warn2(response.message || "inspect_tier2_run failed");
|
|
54319
|
-
}
|
|
54320
|
-
}
|
|
54321
|
-
});
|
|
54322
|
-
clearInspectTier2Idle = () => inspectTier2Idle.clearAll();
|
|
54323
54687
|
return {
|
|
54324
54688
|
tool: allTools,
|
|
54325
54689
|
"experimental.chat.system.transform": async (systemInput, output) => {
|
|
@@ -54343,13 +54707,16 @@ Install: ${getManualInstallHint()}`);
|
|
|
54343
54707
|
const eventType = eventInput.event.type;
|
|
54344
54708
|
observeOpenCodeBgNotificationEvent(eventInput.event);
|
|
54345
54709
|
const sessionID = extractSessionID(eventInput.event.properties);
|
|
54710
|
+
if (eventType === "session.moved" && sessionID) {
|
|
54711
|
+
clearSessionDirectory(sessionID);
|
|
54712
|
+
return;
|
|
54713
|
+
}
|
|
54346
54714
|
if (eventType === "session.created" && sessionID) {
|
|
54347
54715
|
const sessionDir = await getSessionDirectory(input.client, sessionID, input.directory) ?? input.directory;
|
|
54348
54716
|
observeFreshSessionStart(pool, sessionDir, sessionID, "new");
|
|
54349
54717
|
}
|
|
54350
54718
|
if (eventType === "session.deleted" && sessionID) {
|
|
54351
54719
|
releaseSessionState(sessionID);
|
|
54352
|
-
inspectTier2Idle.clear(sessionID);
|
|
54353
54720
|
closeDeletedSessionRoutes(pool, sessionID, input.worktree ?? input.directory).catch(() => {});
|
|
54354
54721
|
return;
|
|
54355
54722
|
}
|
|
@@ -54357,7 +54724,6 @@ Install: ${getManualInstallHint()}`);
|
|
|
54357
54724
|
return;
|
|
54358
54725
|
if (!sessionID)
|
|
54359
54726
|
return;
|
|
54360
|
-
inspectTier2Idle.schedule(sessionID);
|
|
54361
54727
|
const sessionDir = await getSessionDirectory(input.client, sessionID, input.directory) ?? input.directory;
|
|
54362
54728
|
if (!isProjectEnabled(sessionDir))
|
|
54363
54729
|
return;
|
|
@@ -54405,8 +54771,6 @@ Install: ${getManualInstallHint()}`);
|
|
|
54405
54771
|
output.args = prepareOpenCodeArguments(toolInput.tool, output.args, {
|
|
54406
54772
|
hashlineEffective: ctx.hashlineEffective
|
|
54407
54773
|
});
|
|
54408
|
-
if (toolInput.sessionID)
|
|
54409
|
-
inspectTier2Idle.clear(toolInput.sessionID);
|
|
54410
54774
|
},
|
|
54411
54775
|
"command.execute.before": async (commandInput, _output) => {
|
|
54412
54776
|
if (commandInput.command !== STATUS_COMMAND) {
|