@cortexkit/aft-pi 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.d.ts +29 -35
- package/dist/config.d.ts.map +1 -1
- package/dist/index.js +837 -321
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/omp-approval.d.ts +18 -6
- package/dist/omp-approval.d.ts.map +1 -1
- package/dist/shared/status.d.ts +0 -4
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts +32 -0
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -7871,7 +7871,7 @@ var require_src2 = __commonJS(function(exports, module) {
|
|
|
7871
7871
|
});
|
|
7872
7872
|
|
|
7873
7873
|
// src/index.ts
|
|
7874
|
-
import { createRequire as
|
|
7874
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
7875
7875
|
|
|
7876
7876
|
// ../aft-bridge/dist/active-logger.js
|
|
7877
7877
|
var ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
|
|
@@ -8923,9 +8923,10 @@ var BASH_HOST_FALLBACK_BANNER = "[AFT host fallback - module transport down; no
|
|
|
8923
8923
|
var BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES = 100 * 1024;
|
|
8924
8924
|
var BASH_HOST_FALLBACK_MAX_TIMEOUT_MS = 10 * 60 * 1000;
|
|
8925
8925
|
var BASH_HOST_FALLBACK_REFUSAL = "AFT module connection is down";
|
|
8926
|
-
var
|
|
8927
|
-
var
|
|
8928
|
-
var
|
|
8926
|
+
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.";
|
|
8927
|
+
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}`;
|
|
8928
|
+
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.";
|
|
8929
|
+
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.';
|
|
8929
8930
|
function pathKeyForPlatform(env, platform) {
|
|
8930
8931
|
return platform === "win32" ? Object.keys(env).find((key) => key.toLowerCase() === "path") : "PATH";
|
|
8931
8932
|
}
|
|
@@ -9180,6 +9181,7 @@ function bashAcksConfirmed(response, targets) {
|
|
|
9180
9181
|
}
|
|
9181
9182
|
// ../aft-bridge/dist/bash-permissions.js
|
|
9182
9183
|
var BASH_PERMISSION_NOT_SETTLED = "bash permission not settled after {rounds} rounds: still asking for {kind} {path} (operation: {operation}; granted already: {granted})";
|
|
9184
|
+
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.";
|
|
9183
9185
|
|
|
9184
9186
|
class BashPermissionLoopError extends Error {
|
|
9185
9187
|
}
|
|
@@ -9197,6 +9199,10 @@ ${ask.command ?? ""}
|
|
|
9197
9199
|
Working directory:
|
|
9198
9200
|
${ask.cwd ?? ""}`;
|
|
9199
9201
|
}
|
|
9202
|
+
function permissionAskPath(ask) {
|
|
9203
|
+
const paths = ask.patterns?.length ? ask.patterns : bashPermissionRetryGrants(ask);
|
|
9204
|
+
return ask.kind === "escalation" && ask.command ? `${ask.command}${ask.cwd ? ` @ ${ask.cwd}` : ""}` : paths.length ? paths.join(", ") : "<no asks returned>";
|
|
9205
|
+
}
|
|
9200
9206
|
async function withBashPermissionLoop(options) {
|
|
9201
9207
|
const granted = new Set;
|
|
9202
9208
|
const alreadyGranted = (ask) => {
|
|
@@ -9218,20 +9224,22 @@ async function withBashPermissionLoop(options) {
|
|
|
9218
9224
|
already_granted: alreadyGranted(ask)
|
|
9219
9225
|
}))
|
|
9220
9226
|
});
|
|
9221
|
-
const unsettled = (
|
|
9227
|
+
const unsettled = () => {
|
|
9222
9228
|
const message = (asks.length ? asks : [{}]).map((ask) => {
|
|
9223
|
-
|
|
9224
|
-
const path = ask.kind === "escalation" && ask.command ? `${ask.command}${ask.cwd ? ` @ ${ask.cwd}` : ""}` : paths.length ? paths.join(", ") : "<no asks returned>";
|
|
9225
|
-
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);
|
|
9229
|
+
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));
|
|
9226
9230
|
}).join("; ");
|
|
9227
|
-
return new BashPermissionLoopError(
|
|
9231
|
+
return new BashPermissionLoopError(message);
|
|
9228
9232
|
};
|
|
9229
9233
|
if (asks.length === 0 || asks.every(alreadyGranted) || round >= 8)
|
|
9230
9234
|
throw unsettled();
|
|
9235
|
+
const pendingAsks = asks.filter((ask) => !alreadyGranted(ask));
|
|
9231
9236
|
try {
|
|
9232
|
-
await options.approve(
|
|
9237
|
+
await options.approve(pendingAsks);
|
|
9233
9238
|
} catch (error) {
|
|
9234
|
-
|
|
9239
|
+
const parts = pendingAsks.map(permissionAskPath).join(", ");
|
|
9240
|
+
const reason = error instanceof Error && error.message ? error.message.trim().replace(/\.$/, "") : "";
|
|
9241
|
+
const message = reason ? BASH_PERMISSION_DENIED.replace("{host reason}", () => reason) : BASH_PERMISSION_DENIED.replace(" ({host reason})", "");
|
|
9242
|
+
throw new BashPermissionLoopError(message.replace("{parts}", () => parts), { cause: error });
|
|
9235
9243
|
}
|
|
9236
9244
|
for (const ask of asks) {
|
|
9237
9245
|
for (const grant of bashPermissionRetryGrants(ask))
|
|
@@ -11309,15 +11317,57 @@ function hubSummaryLine(response, theme) {
|
|
|
11309
11317
|
const message = summary ? asString(summary.message) : undefined;
|
|
11310
11318
|
return message ? theme.fg("warning", message) : undefined;
|
|
11311
11319
|
}
|
|
11320
|
+
var ROOT_KINDS = ["main", "test", "attribute", "public_api", "no_caller_found"];
|
|
11321
|
+
var ROOT_LABELS = {
|
|
11322
|
+
main: "main",
|
|
11323
|
+
test: "test",
|
|
11324
|
+
attribute: "attribute",
|
|
11325
|
+
public_api: "public API",
|
|
11326
|
+
no_caller_found: "no caller found"
|
|
11327
|
+
};
|
|
11328
|
+
function rootCounted(kind, count) {
|
|
11329
|
+
const plural = count === 1 ? "" : "s";
|
|
11330
|
+
switch (kind) {
|
|
11331
|
+
case "main":
|
|
11332
|
+
return count === 1 ? "main" : `${count} main functions`;
|
|
11333
|
+
case "test":
|
|
11334
|
+
return `${count} test${plural}`;
|
|
11335
|
+
case "attribute":
|
|
11336
|
+
return `${count} function${plural} with an entry attribute`;
|
|
11337
|
+
case "public_api":
|
|
11338
|
+
return `${count} public API function${plural}`;
|
|
11339
|
+
default:
|
|
11340
|
+
return `${count} function${plural} with no caller found`;
|
|
11341
|
+
}
|
|
11342
|
+
}
|
|
11343
|
+
function rootSummary(record) {
|
|
11344
|
+
const counts = asRecord(record.root_counts);
|
|
11345
|
+
if (!counts)
|
|
11346
|
+
return;
|
|
11347
|
+
const parts = ROOT_KINDS.flatMap((kind) => {
|
|
11348
|
+
const count = asNumber(counts[kind]);
|
|
11349
|
+
return count && count > 0 ? [rootCounted(kind, count)] : [];
|
|
11350
|
+
});
|
|
11351
|
+
return parts.length > 0 ? parts.join(", ") : undefined;
|
|
11352
|
+
}
|
|
11353
|
+
function rootTag(record) {
|
|
11354
|
+
const kind = asString(record.root);
|
|
11355
|
+
const label = kind ? ROOT_LABELS[kind] : undefined;
|
|
11356
|
+
if (!kind || !label)
|
|
11357
|
+
return;
|
|
11358
|
+
const attribute = asString(record.attribute);
|
|
11359
|
+
return kind === "attribute" && attribute ? `[root: attribute ${attribute}]` : `[root: ${label}]`;
|
|
11360
|
+
}
|
|
11312
11361
|
function renderTracePath(path, index, lines, theme) {
|
|
11313
11362
|
lines.push(`Path ${index + 1}`);
|
|
11363
|
+
const root = rootTag(path);
|
|
11314
11364
|
asRecords(path.hops).forEach((hop, hopIndex) => {
|
|
11315
11365
|
const symbol = asString(hop.symbol) ?? "(unknown)";
|
|
11316
11366
|
const file = shortenHomePath(asString(hop.file) ?? "(unknown file)");
|
|
11317
11367
|
const line = asNumber(hop.line);
|
|
11318
|
-
const
|
|
11368
|
+
const tag = hopIndex === 0 ? root ? ` ${theme.fg("warning", root)}` : "" : hop.exported === true ? " [exported]" : "";
|
|
11319
11369
|
const nameMatch = nameMatchEdgeMarker(hop, theme);
|
|
11320
|
-
lines.push(treeLine(hopIndex + 1, `${symbol}${
|
|
11370
|
+
lines.push(treeLine(hopIndex + 1, `${symbol}${tag} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}${nameMatch}`));
|
|
11321
11371
|
});
|
|
11322
11372
|
}
|
|
11323
11373
|
function renderCallersGroupLines(group, theme, callbackLabel) {
|
|
@@ -11422,18 +11472,18 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME, op
|
|
|
11422
11472
|
const hubSummary = hubSummaryLine(record, theme);
|
|
11423
11473
|
const totalPaths = asNumber(record.total_paths) ?? paths.length;
|
|
11424
11474
|
const totalPathsIsLowerBound = asBoolean(record.total_paths_is_lower_bound) ?? false;
|
|
11425
|
-
const
|
|
11475
|
+
const roots = rootSummary(record);
|
|
11426
11476
|
const sections = [
|
|
11427
11477
|
joinNonEmpty([
|
|
11428
11478
|
theme.fg("success", `${totalPathsIsLowerBound ? "at least " : ""}${totalPaths} path${totalPaths === 1 ? "" : "s"}`),
|
|
11429
|
-
theme.fg("muted",
|
|
11479
|
+
roots ? theme.fg("muted", `roots: ${roots}`) : undefined,
|
|
11430
11480
|
warning
|
|
11431
11481
|
])
|
|
11432
11482
|
];
|
|
11433
11483
|
if (hubSummary)
|
|
11434
11484
|
sections.push(hubSummary);
|
|
11435
11485
|
if (paths.length === 0)
|
|
11436
|
-
sections.push(theme.fg("muted", "No
|
|
11486
|
+
sections.push(theme.fg("muted", "No paths found."));
|
|
11437
11487
|
paths.forEach((path, index) => {
|
|
11438
11488
|
const lines = [];
|
|
11439
11489
|
renderTracePath(path, index, lines, theme);
|
|
@@ -11466,13 +11516,17 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME, op
|
|
|
11466
11516
|
sections.unshift(theme.fg("warning", testFilterNote));
|
|
11467
11517
|
if (hubSummary)
|
|
11468
11518
|
sections.push(hubSummary);
|
|
11519
|
+
const roots = rootSummary(record);
|
|
11520
|
+
if (roots)
|
|
11521
|
+
sections.push(theme.fg("muted", `Reaches ${roots}`));
|
|
11469
11522
|
if (callers.length === 0)
|
|
11470
11523
|
sections.push(theme.fg("muted", "No impacted callers found."));
|
|
11471
11524
|
callers.forEach((caller) => {
|
|
11472
11525
|
const file = shortenHomePath(asString(caller.caller_file) ?? "(unknown file)");
|
|
11473
11526
|
const symbol = asString(caller.caller_symbol) ?? "(unknown)";
|
|
11474
11527
|
const line = asNumber(caller.line) ?? 0;
|
|
11475
|
-
const
|
|
11528
|
+
const root = rootTag(caller);
|
|
11529
|
+
const entry = root ? ` ${theme.fg("warning", root)}` : "";
|
|
11476
11530
|
const nameMatch = nameMatchEdgeMarker(caller, theme);
|
|
11477
11531
|
const reference = caller.relation === "callback_reference" ? asString(record.callback_reference_label) ?? "" : "";
|
|
11478
11532
|
const expression = asString(caller.call_expression);
|
|
@@ -11758,8 +11812,9 @@ function formatDroppedKeyWarnings(dropped) {
|
|
|
11758
11812
|
return dropped.map((item) => `Ignoring ${item.key} from ${item.tier} config (${item.reason})`);
|
|
11759
11813
|
}
|
|
11760
11814
|
// ../aft-bridge/dist/config-watch.js
|
|
11761
|
-
import {
|
|
11762
|
-
import {
|
|
11815
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
11816
|
+
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readFileSync as readFileSync3, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync3, watch } from "node:fs";
|
|
11817
|
+
import { basename, dirname as dirname2, resolve as resolve5 } from "node:path";
|
|
11763
11818
|
var CONFIG_WATCH_DEBOUNCE_MS = 150;
|
|
11764
11819
|
var CONFIG_LIVE_KEEP_NOTE = "AFT keeps using the last valid configuration until the file is fixed.";
|
|
11765
11820
|
function pathKey(name) {
|
|
@@ -11813,7 +11868,6 @@ function aftLiveConfigKeys(resolveBash) {
|
|
|
11813
11868
|
pathKey("restrict_to_project_root"),
|
|
11814
11869
|
pathKey("revision_reads"),
|
|
11815
11870
|
pathKey("inspect.diagnostics_timeout_ms"),
|
|
11816
|
-
pathKey("inspect.tier2_idle_minutes"),
|
|
11817
11871
|
pathKey("lsp.idle_minutes"),
|
|
11818
11872
|
...[
|
|
11819
11873
|
"diagnostics",
|
|
@@ -11885,6 +11939,29 @@ function readTextOrNull(path) {
|
|
|
11885
11939
|
var CONFIG_WATCH_REVALIDATE_MS = 2000;
|
|
11886
11940
|
var CONFIG_WATCH_REJECTED_RETRIES = 3;
|
|
11887
11941
|
var CONFIG_WATCH_MAX_DELAY_MS = 1000;
|
|
11942
|
+
var CONFIG_READ_LIMIT = 1024 * 1024;
|
|
11943
|
+
function contentFingerprint(path) {
|
|
11944
|
+
let fd;
|
|
11945
|
+
try {
|
|
11946
|
+
fd = openSync2(path, "r");
|
|
11947
|
+
const metadata = fstatSync(fd, { bigint: true });
|
|
11948
|
+
const bytes = Buffer.alloc(Math.min(Number(metadata.size), CONFIG_READ_LIMIT));
|
|
11949
|
+
let offset = 0;
|
|
11950
|
+
while (offset < bytes.length) {
|
|
11951
|
+
const read = readSync2(fd, bytes, offset, bytes.length - offset, null);
|
|
11952
|
+
if (read === 0)
|
|
11953
|
+
break;
|
|
11954
|
+
offset += read;
|
|
11955
|
+
}
|
|
11956
|
+
const hash = createHash2("sha256").update(bytes.subarray(0, offset)).digest("hex");
|
|
11957
|
+
return `${metadata.size}:${metadata.mtimeNs}:${hash}`;
|
|
11958
|
+
} catch {
|
|
11959
|
+
return null;
|
|
11960
|
+
} finally {
|
|
11961
|
+
if (fd !== undefined)
|
|
11962
|
+
closeSync2(fd);
|
|
11963
|
+
}
|
|
11964
|
+
}
|
|
11888
11965
|
function identityOf(dir) {
|
|
11889
11966
|
try {
|
|
11890
11967
|
const stat = statSync3(dir, { bigint: true });
|
|
@@ -11900,6 +11977,13 @@ function watchDirFor(file) {
|
|
|
11900
11977
|
dir = dirname2(dir);
|
|
11901
11978
|
return dir;
|
|
11902
11979
|
}
|
|
11980
|
+
function canonicalDirectory(dir) {
|
|
11981
|
+
try {
|
|
11982
|
+
return realpathSync2(dir);
|
|
11983
|
+
} catch {
|
|
11984
|
+
return resolve5(dir);
|
|
11985
|
+
}
|
|
11986
|
+
}
|
|
11903
11987
|
function watchAftConfigFiles(options) {
|
|
11904
11988
|
const debounceMs = options.debounceMs ?? CONFIG_WATCH_DEBOUNCE_MS;
|
|
11905
11989
|
const lastSeen = new Map;
|
|
@@ -11913,6 +11997,8 @@ function watchAftConfigFiles(options) {
|
|
|
11913
11997
|
let firstPendingAt = null;
|
|
11914
11998
|
let stopped = false;
|
|
11915
11999
|
const watchers = new Map;
|
|
12000
|
+
const targets = new Map;
|
|
12001
|
+
const fallbackSeen = new Map;
|
|
11916
12002
|
const watchImpl = options.watchImpl ?? watch;
|
|
11917
12003
|
let rejectedRetries = 0;
|
|
11918
12004
|
const check = () => {
|
|
@@ -11966,8 +12052,34 @@ function watchAftConfigFiles(options) {
|
|
|
11966
12052
|
timer.unref?.();
|
|
11967
12053
|
};
|
|
11968
12054
|
function revalidate() {
|
|
11969
|
-
const wanted = new Set
|
|
12055
|
+
const wanted = new Set;
|
|
12056
|
+
const wantedCanonical = new Set;
|
|
12057
|
+
const wantDirectory = (dir) => {
|
|
12058
|
+
const canonical = canonicalDirectory(dir);
|
|
12059
|
+
if (wantedCanonical.has(canonical))
|
|
12060
|
+
return;
|
|
12061
|
+
wantedCanonical.add(canonical);
|
|
12062
|
+
wanted.add(dir);
|
|
12063
|
+
};
|
|
12064
|
+
for (const path of options.paths)
|
|
12065
|
+
wantDirectory(watchDirFor(path));
|
|
11970
12066
|
let moved = false;
|
|
12067
|
+
for (const path of options.paths) {
|
|
12068
|
+
try {
|
|
12069
|
+
const resolved = realpathSync2(path);
|
|
12070
|
+
const target = resolved === resolve5(path) ? undefined : resolved;
|
|
12071
|
+
if (targets.get(path) !== target) {
|
|
12072
|
+
if (target)
|
|
12073
|
+
targets.set(path, target);
|
|
12074
|
+
else
|
|
12075
|
+
targets.delete(path);
|
|
12076
|
+
fallbackSeen.delete(path);
|
|
12077
|
+
moved = true;
|
|
12078
|
+
}
|
|
12079
|
+
} catch {}
|
|
12080
|
+
}
|
|
12081
|
+
for (const target of targets.values())
|
|
12082
|
+
wantDirectory(watchDirFor(target));
|
|
11971
12083
|
for (const [dir, entry] of watchers) {
|
|
11972
12084
|
if (!wanted.has(dir) || entry.stale || identityOf(dir) !== entry.identity) {
|
|
11973
12085
|
entry.watcher.close();
|
|
@@ -12006,6 +12118,17 @@ function watchAftConfigFiles(options) {
|
|
|
12006
12118
|
moved = true;
|
|
12007
12119
|
} catch {}
|
|
12008
12120
|
}
|
|
12121
|
+
const watchedCanonical = new Set(Array.from(watchers.keys(), canonicalDirectory));
|
|
12122
|
+
for (const [path, target] of targets) {
|
|
12123
|
+
if (watchedCanonical.has(canonicalDirectory(dirname2(target)))) {
|
|
12124
|
+
fallbackSeen.delete(path);
|
|
12125
|
+
continue;
|
|
12126
|
+
}
|
|
12127
|
+
const fingerprint = contentFingerprint(path);
|
|
12128
|
+
if (!fallbackSeen.has(path) || fallbackSeen.get(path) !== fingerprint)
|
|
12129
|
+
moved = true;
|
|
12130
|
+
fallbackSeen.set(path, fingerprint);
|
|
12131
|
+
}
|
|
12009
12132
|
return moved;
|
|
12010
12133
|
}
|
|
12011
12134
|
revalidate();
|
|
@@ -12162,8 +12285,8 @@ function startLiveConfigReload(options) {
|
|
|
12162
12285
|
return { reload, stop };
|
|
12163
12286
|
}
|
|
12164
12287
|
// ../aft-bridge/dist/downloader.js
|
|
12165
|
-
import { createHash as
|
|
12166
|
-
import { chmodSync, closeSync as
|
|
12288
|
+
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
12289
|
+
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";
|
|
12167
12290
|
import { hostname } from "node:os";
|
|
12168
12291
|
import { join as join8 } from "node:path";
|
|
12169
12292
|
import { Readable } from "node:stream";
|
|
@@ -12381,7 +12504,7 @@ async function downloadBinary(version) {
|
|
|
12381
12504
|
warn(`Checksum verification failed: checksums.sha256 found but no entry for ${assetName}. ` + "Binary download aborted for security reasons.");
|
|
12382
12505
|
return null;
|
|
12383
12506
|
}
|
|
12384
|
-
const hash =
|
|
12507
|
+
const hash = createHash3("sha256");
|
|
12385
12508
|
let bytesWritten = 0;
|
|
12386
12509
|
const guard = new TransformStream({
|
|
12387
12510
|
transform(chunk, controller) {
|
|
@@ -12548,11 +12671,11 @@ async function acquireDownloadLock(lockPath, timing = {}) {
|
|
|
12548
12671
|
while (true) {
|
|
12549
12672
|
try {
|
|
12550
12673
|
const owner = createDownloadLockOwner();
|
|
12551
|
-
const fd =
|
|
12674
|
+
const fd = openSync3(lockPath, "wx");
|
|
12552
12675
|
try {
|
|
12553
12676
|
writeSync(fd, owner);
|
|
12554
12677
|
} finally {
|
|
12555
|
-
|
|
12678
|
+
closeSync3(fd);
|
|
12556
12679
|
}
|
|
12557
12680
|
return () => {
|
|
12558
12681
|
try {
|
|
@@ -12623,8 +12746,8 @@ import { appendFile, lstat, mkdir, open, rename, rm, stat } from "node:fs/promis
|
|
|
12623
12746
|
import { dirname as dirname3 } from "node:path";
|
|
12624
12747
|
|
|
12625
12748
|
// ../aft-bridge/dist/private-storage.js
|
|
12626
|
-
import { closeSync as
|
|
12627
|
-
import { isAbsolute as isAbsolute4, join as join9, parse, relative as relative3, resolve as
|
|
12749
|
+
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";
|
|
12750
|
+
import { isAbsolute as isAbsolute4, join as join9, parse, relative as relative3, resolve as resolve6, sep } from "node:path";
|
|
12628
12751
|
var PRIVATE_FILE_MODE = 384;
|
|
12629
12752
|
var PRIVATE_DIRECTORY_MODE = 448;
|
|
12630
12753
|
function privateMkdirSync(path, recursive = true) {
|
|
@@ -12638,13 +12761,13 @@ function privateCopyFileSync(source, destination) {
|
|
|
12638
12761
|
copyFileSync2(source, destination);
|
|
12639
12762
|
return;
|
|
12640
12763
|
}
|
|
12641
|
-
const input =
|
|
12764
|
+
const input = openSync4(source, "r");
|
|
12642
12765
|
let output;
|
|
12643
12766
|
try {
|
|
12644
|
-
output =
|
|
12767
|
+
output = openSync4(destination, "wx", PRIVATE_FILE_MODE);
|
|
12645
12768
|
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
12646
12769
|
for (;; ) {
|
|
12647
|
-
const bytes =
|
|
12770
|
+
const bytes = readSync3(input, buffer);
|
|
12648
12771
|
if (bytes === 0)
|
|
12649
12772
|
break;
|
|
12650
12773
|
let offset = 0;
|
|
@@ -12652,18 +12775,18 @@ function privateCopyFileSync(source, destination) {
|
|
|
12652
12775
|
offset += writeSync2(output, buffer, offset, bytes - offset);
|
|
12653
12776
|
}
|
|
12654
12777
|
} finally {
|
|
12655
|
-
|
|
12778
|
+
closeSync4(input);
|
|
12656
12779
|
if (output !== undefined)
|
|
12657
|
-
|
|
12780
|
+
closeSync4(output);
|
|
12658
12781
|
}
|
|
12659
12782
|
}
|
|
12660
12783
|
var warned = new Set;
|
|
12661
12784
|
function openPrivateStorageDir(root, path = root) {
|
|
12662
|
-
const base =
|
|
12785
|
+
const base = resolve6(root);
|
|
12663
12786
|
if (!root || base === parse(base).root) {
|
|
12664
12787
|
throw new Error(`refusing filesystem root as private storage: ${base}`);
|
|
12665
12788
|
}
|
|
12666
|
-
const rel = relative3(base,
|
|
12789
|
+
const rel = relative3(base, resolve6(path));
|
|
12667
12790
|
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute4(rel))
|
|
12668
12791
|
return;
|
|
12669
12792
|
privateMkdirSync(path);
|
|
@@ -12676,8 +12799,8 @@ function openPrivateStorageDir(root, path = root) {
|
|
|
12676
12799
|
try {
|
|
12677
12800
|
if (lstatSync(current).isSymbolicLink())
|
|
12678
12801
|
return;
|
|
12679
|
-
fd =
|
|
12680
|
-
if ((
|
|
12802
|
+
fd = openSync4(current, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
12803
|
+
if ((fstatSync2(fd).mode & 63) !== 0)
|
|
12681
12804
|
fchmodSync(fd, PRIVATE_DIRECTORY_MODE);
|
|
12682
12805
|
} catch (error) {
|
|
12683
12806
|
if (!warned.has(current)) {
|
|
@@ -12688,7 +12811,7 @@ function openPrivateStorageDir(root, path = root) {
|
|
|
12688
12811
|
return;
|
|
12689
12812
|
} finally {
|
|
12690
12813
|
if (fd !== undefined)
|
|
12691
|
-
|
|
12814
|
+
closeSync4(fd);
|
|
12692
12815
|
}
|
|
12693
12816
|
}
|
|
12694
12817
|
}
|
|
@@ -13570,7 +13693,7 @@ async function readConnectionFileForUid(path, expectedUid) {
|
|
|
13570
13693
|
}
|
|
13571
13694
|
|
|
13572
13695
|
// ../../node_modules/.bun/@cortexkit+subc-client@0.21.2/node_modules/@cortexkit/subc-client/dist/launch-nonce.js
|
|
13573
|
-
import { closeSync as
|
|
13696
|
+
import { closeSync as closeSync5, fstatSync as fstatSync3, readSync as readSync4 } from "node:fs";
|
|
13574
13697
|
var SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE";
|
|
13575
13698
|
var SUBC_LAUNCH_NONCE_FD_ENV = "SUBC_LAUNCH_NONCE_FD";
|
|
13576
13699
|
class LaunchNonceError extends Error {
|
|
@@ -13617,7 +13740,7 @@ class LaunchNonceCell {
|
|
|
13617
13740
|
lookup;
|
|
13618
13741
|
platform;
|
|
13619
13742
|
stat;
|
|
13620
|
-
constructor(lookup, platform = process.platform, stat = (fd) =>
|
|
13743
|
+
constructor(lookup, platform = process.platform, stat = (fd) => fstatSync3(fd, { bigint: true })) {
|
|
13621
13744
|
this.lookup = lookup;
|
|
13622
13745
|
this.platform = platform;
|
|
13623
13746
|
this.stat = stat;
|
|
@@ -13665,7 +13788,7 @@ class LaunchNonceCell {
|
|
|
13665
13788
|
const chunk = Buffer.alloc(256);
|
|
13666
13789
|
let got;
|
|
13667
13790
|
try {
|
|
13668
|
-
got =
|
|
13791
|
+
got = readSync4(fd, chunk, 0, chunk.length, null);
|
|
13669
13792
|
} catch (error) {
|
|
13670
13793
|
if (isWouldBlock(error))
|
|
13671
13794
|
throw emptyError(fd);
|
|
@@ -13677,7 +13800,7 @@ class LaunchNonceCell {
|
|
|
13677
13800
|
const parts = [Buffer.from(chunk.subarray(0, got))];
|
|
13678
13801
|
try {
|
|
13679
13802
|
for (;; ) {
|
|
13680
|
-
const n =
|
|
13803
|
+
const n = readSync4(fd, chunk, 0, chunk.length, null);
|
|
13681
13804
|
if (n === 0)
|
|
13682
13805
|
break;
|
|
13683
13806
|
parts.push(Buffer.from(chunk.subarray(0, n)));
|
|
@@ -13754,7 +13877,7 @@ function errnoOf(error) {
|
|
|
13754
13877
|
}
|
|
13755
13878
|
function closeQuietly(fd) {
|
|
13756
13879
|
try {
|
|
13757
|
-
|
|
13880
|
+
closeSync5(fd);
|
|
13758
13881
|
} catch {}
|
|
13759
13882
|
}
|
|
13760
13883
|
|
|
@@ -15629,15 +15752,15 @@ function getLifecycleRegistry() {
|
|
|
15629
15752
|
}
|
|
15630
15753
|
|
|
15631
15754
|
// ../aft-bridge/dist/project-identity.js
|
|
15632
|
-
import { realpathSync as
|
|
15633
|
-
import { posix as posix2, resolve as
|
|
15755
|
+
import { realpathSync as realpathSync3 } from "node:fs";
|
|
15756
|
+
import { posix as posix2, resolve as resolve7, win32 as win322 } from "node:path";
|
|
15634
15757
|
function canonicalizeProjectRoot(dir) {
|
|
15635
15758
|
const trimmed = trimProjectRootSeparators(dir);
|
|
15636
15759
|
let canonical;
|
|
15637
15760
|
try {
|
|
15638
|
-
canonical =
|
|
15761
|
+
canonical = realpathSync3(trimmed);
|
|
15639
15762
|
} catch {
|
|
15640
|
-
canonical =
|
|
15763
|
+
canonical = resolve7(trimmed);
|
|
15641
15764
|
}
|
|
15642
15765
|
return normalizeWindowsRoot(canonical);
|
|
15643
15766
|
}
|
|
@@ -17617,7 +17740,9 @@ class SubcTransportPool {
|
|
|
17617
17740
|
});
|
|
17618
17741
|
retry = state.bindPending;
|
|
17619
17742
|
} else {
|
|
17620
|
-
retry = this.hostScope(client, record.identity)
|
|
17743
|
+
retry = this.hostScope(client, record.identity).finally(() => {
|
|
17744
|
+
this.scheduleHostScopeRetry(session, state);
|
|
17745
|
+
});
|
|
17621
17746
|
}
|
|
17622
17747
|
retry.catch((error) => {
|
|
17623
17748
|
warn(`subc head scope: session=${session} background retry failed code=${error instanceof Error ? error.name : "Error"}`);
|
|
@@ -17785,12 +17910,18 @@ class SubcTransportPool {
|
|
|
17785
17910
|
}
|
|
17786
17911
|
return this.openScopedHostToolRoute(client, identity, record, entry, channel);
|
|
17787
17912
|
}
|
|
17788
|
-
bindHostToolRoute(client, identity, channel, reason, scope) {
|
|
17913
|
+
async bindHostToolRoute(client, identity, channel, reason, scope) {
|
|
17789
17914
|
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}` : ""));
|
|
17790
|
-
|
|
17915
|
+
const route = await client.routeOpen({ kind: "tool_provider", module_id: AFT_MODULE_ID }, identity, {
|
|
17791
17916
|
consumerIdentity: this.consumerIdentity,
|
|
17792
17917
|
...scope ? { scope } : {}
|
|
17793
17918
|
});
|
|
17919
|
+
const state = this.hostScopeCache.get(identity.session);
|
|
17920
|
+
if (scope && state?.unscopedReason && state.answer?.result === "scope" && state.answer.scope === scope) {
|
|
17921
|
+
log(`subc head scope: session=${identity.session} route=upgraded from=unscoped ref=${scope.ref.slice(0, 8)} epoch=${scope.scopeEpoch}`);
|
|
17922
|
+
state.unscopedReason = undefined;
|
|
17923
|
+
}
|
|
17924
|
+
return route;
|
|
17794
17925
|
}
|
|
17795
17926
|
async openScopedHostToolRoute(client, identity, record, entry, channel = "tool") {
|
|
17796
17927
|
const decision = await this.hostScope(client, identity);
|
|
@@ -18422,7 +18553,8 @@ function taskIdFromError(error) {
|
|
|
18422
18553
|
return;
|
|
18423
18554
|
}
|
|
18424
18555
|
// ../aft-bridge/dist/feature-config.js
|
|
18425
|
-
import { createHash as
|
|
18556
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
18557
|
+
import { createRequire } from "node:module";
|
|
18426
18558
|
var CANONICAL_TOOLS = [
|
|
18427
18559
|
"aft_callgraph",
|
|
18428
18560
|
"aft_conflicts",
|
|
@@ -18472,23 +18604,114 @@ var REMOVED_OPENCODE_PATHS = [
|
|
|
18472
18604
|
"opencode.server_url",
|
|
18473
18605
|
"opencode.server_password_env"
|
|
18474
18606
|
];
|
|
18475
|
-
|
|
18607
|
+
var REMOVED_DATA_LAYER_PATHS = [
|
|
18608
|
+
"views.callgraph_copies",
|
|
18609
|
+
"views.enabled",
|
|
18610
|
+
"worktree.ram_overlay"
|
|
18611
|
+
];
|
|
18612
|
+
var RETIRED_IDLE_CHECKOUT_HOURS = [
|
|
18613
|
+
"views.idle_checkout_hours",
|
|
18614
|
+
"idle.checkout_hours"
|
|
18615
|
+
];
|
|
18616
|
+
var DATA_LAYER_KEYS_REFUSED_FROM = [0, 65];
|
|
18617
|
+
var DATA_LAYER_RETIRED_PATHS = [
|
|
18618
|
+
"views.callgraph_copies",
|
|
18619
|
+
"views.enabled",
|
|
18620
|
+
"views.idle_checkout_hours",
|
|
18621
|
+
"worktree.ram_overlay"
|
|
18622
|
+
];
|
|
18623
|
+
var IDLE_CHECKOUT_HOURS_DEFAULT = 168;
|
|
18624
|
+
var IDLE_CHECKOUT_HOURS_MIN = 1;
|
|
18625
|
+
var IDLE_CHECKOUT_HOURS_MAX = 24 * 365;
|
|
18626
|
+
function parseRelease(version) {
|
|
18627
|
+
const match = /^(\d+)\.(\d+)(?:\.|$)/.exec(version);
|
|
18628
|
+
return match ? [Number(match[1]), Number(match[2])] : undefined;
|
|
18629
|
+
}
|
|
18630
|
+
var AFT_PACKAGE_NAMES = new Set([
|
|
18631
|
+
"@cortexkit/aft-bridge",
|
|
18632
|
+
"@cortexkit/aft-opencode",
|
|
18633
|
+
"@cortexkit/aft-pi",
|
|
18634
|
+
"@cortexkit/aft"
|
|
18635
|
+
]);
|
|
18636
|
+
function readRunningRelease() {
|
|
18637
|
+
const req = createRequire(import.meta.url);
|
|
18638
|
+
for (const candidate of ["../package.json", "../../package.json", "../../../package.json"]) {
|
|
18639
|
+
try {
|
|
18640
|
+
const manifest = req(candidate);
|
|
18641
|
+
if (manifest.name && AFT_PACKAGE_NAMES.has(manifest.name) && manifest.version) {
|
|
18642
|
+
return parseRelease(manifest.version) ?? [0, 0];
|
|
18643
|
+
}
|
|
18644
|
+
} catch {}
|
|
18645
|
+
}
|
|
18646
|
+
return [0, 0];
|
|
18647
|
+
}
|
|
18648
|
+
var runningRelease;
|
|
18649
|
+
function getRunningRelease() {
|
|
18650
|
+
runningRelease ??= readRunningRelease();
|
|
18651
|
+
return runningRelease;
|
|
18652
|
+
}
|
|
18653
|
+
function releaseAtLeast(release, floor) {
|
|
18654
|
+
return release[0] !== floor[0] ? release[0] > floor[0] : release[1] >= floor[1];
|
|
18655
|
+
}
|
|
18656
|
+
function refusedFromVersion() {
|
|
18657
|
+
return `${DATA_LAYER_KEYS_REFUSED_FROM[0]}.${DATA_LAYER_KEYS_REFUSED_FROM[1]}.0`;
|
|
18658
|
+
}
|
|
18659
|
+
function removedConfigKeyErrors(value, release = getRunningRelease(), refuseRetired = true) {
|
|
18476
18660
|
if (!isRecord2(value))
|
|
18477
18661
|
return [];
|
|
18478
|
-
const errors =
|
|
18662
|
+
const errors = removedBlockKeyErrors(value, release, refuseRetired);
|
|
18479
18663
|
if (isRecord2(value.harnesses)) {
|
|
18480
18664
|
for (const [name, block] of Object.entries(value.harnesses)) {
|
|
18481
18665
|
if (!isRecord2(block))
|
|
18482
18666
|
continue;
|
|
18483
|
-
for (const error of
|
|
18667
|
+
for (const error of removedBlockKeyErrors(block, release, refuseRetired)) {
|
|
18484
18668
|
errors.push(error.replace("removed_config_key:", `removed_config_key:harnesses.${name}.`));
|
|
18485
18669
|
}
|
|
18486
18670
|
}
|
|
18487
18671
|
}
|
|
18488
18672
|
return errors;
|
|
18489
18673
|
}
|
|
18490
|
-
function
|
|
18491
|
-
|
|
18674
|
+
function removedBlockKeyErrors(value, release, refuseRetired) {
|
|
18675
|
+
const paths = REMOVED_OPENCODE_PATHS.filter((path) => hasPath(value, path));
|
|
18676
|
+
if (refuseRetired)
|
|
18677
|
+
paths.push(...refusedRetiredNames(value));
|
|
18678
|
+
if (releaseAtLeast(release, DATA_LAYER_KEYS_REFUSED_FROM))
|
|
18679
|
+
paths.push(...DATA_LAYER_RETIRED_PATHS.filter((path) => hasPath(value, path)));
|
|
18680
|
+
return paths.map((path) => `removed_config_key:${path}; run npx @cortexkit/aft doctor --fix`);
|
|
18681
|
+
}
|
|
18682
|
+
var REFUSED_RETIRED_PATHS = [
|
|
18683
|
+
"sandbox.enabled",
|
|
18684
|
+
"tool_surface",
|
|
18685
|
+
"hoist_builtin_tools",
|
|
18686
|
+
"enabled",
|
|
18687
|
+
"search_index",
|
|
18688
|
+
"experimental_search_index",
|
|
18689
|
+
"semantic_search",
|
|
18690
|
+
"experimental_semantic_search",
|
|
18691
|
+
"callgraph_store",
|
|
18692
|
+
"github.enabled",
|
|
18693
|
+
"gh_read",
|
|
18694
|
+
"gh_shim.enabled",
|
|
18695
|
+
"experimental_lsp_ty",
|
|
18696
|
+
"experimental_bash_rewrite",
|
|
18697
|
+
"experimental_bash_compress",
|
|
18698
|
+
"experimental_bash_background",
|
|
18699
|
+
"experimental.bash",
|
|
18700
|
+
"idle.lsp_ttl_minutes",
|
|
18701
|
+
"inspect.tier2_soft_deadline_ms",
|
|
18702
|
+
"inspect.max_drill_down_items"
|
|
18703
|
+
];
|
|
18704
|
+
function refusedRetiredNames(block) {
|
|
18705
|
+
const names = REFUSED_RETIRED_PATHS.filter((path) => hasPath(block, path));
|
|
18706
|
+
if (Array.isArray(block.disabled_tools)) {
|
|
18707
|
+
for (const name of block.disabled_tools) {
|
|
18708
|
+
if (typeof name !== "string" || !Object.hasOwn(LEGACY_TOOL_ALIASES, name))
|
|
18709
|
+
continue;
|
|
18710
|
+
if (!names.includes(name))
|
|
18711
|
+
names.push(name);
|
|
18712
|
+
}
|
|
18713
|
+
}
|
|
18714
|
+
return names;
|
|
18492
18715
|
}
|
|
18493
18716
|
var RETIRED_PATHS = [
|
|
18494
18717
|
["sandbox.enabled", "sandbox.profile"],
|
|
@@ -18643,7 +18866,10 @@ function translateInspectLspPaths(map, prefix, out) {
|
|
|
18643
18866
|
recordRetired(out, prefix, `inspect.${leaf}`);
|
|
18644
18867
|
}
|
|
18645
18868
|
}
|
|
18646
|
-
var REMOVED_NO_EFFECT_PATHS = [
|
|
18869
|
+
var REMOVED_NO_EFFECT_PATHS = [
|
|
18870
|
+
"bridge.hang_threshold",
|
|
18871
|
+
"inspect.tier2_idle_minutes"
|
|
18872
|
+
];
|
|
18647
18873
|
function dropNoEffectPaths(map, prefix, out) {
|
|
18648
18874
|
for (const path of REMOVED_NO_EFFECT_PATHS) {
|
|
18649
18875
|
const [container, leaf] = path.split(".");
|
|
@@ -18652,6 +18878,29 @@ function dropNoEffectPaths(map, prefix, out) {
|
|
|
18652
18878
|
}
|
|
18653
18879
|
}
|
|
18654
18880
|
}
|
|
18881
|
+
function retiredIdleCheckoutHours(value) {
|
|
18882
|
+
const raw = typeof value === "number" && Number.isSafeInteger(value) ? value : IDLE_CHECKOUT_HOURS_DEFAULT;
|
|
18883
|
+
return Math.min(IDLE_CHECKOUT_HOURS_MAX, Math.max(IDLE_CHECKOUT_HOURS_MIN, raw));
|
|
18884
|
+
}
|
|
18885
|
+
function translateDataLayerPaths(map, prefix, out) {
|
|
18886
|
+
const [retired, replacement] = RETIRED_IDLE_CHECKOUT_HOURS;
|
|
18887
|
+
const hours = takeNested(map, "views", "idle_checkout_hours");
|
|
18888
|
+
if (hours.found) {
|
|
18889
|
+
recordRetired(out, prefix, retired);
|
|
18890
|
+
if (isRecord2(map.idle) && map.idle.checkout_hours !== undefined) {
|
|
18891
|
+
superseded(out, `${prefix}${retired}`, `${retired} is ignored because ${replacement} is set`);
|
|
18892
|
+
} else {
|
|
18893
|
+
if (!Object.hasOwn(map, "idle"))
|
|
18894
|
+
map.idle = {};
|
|
18895
|
+
if (isRecord2(map.idle))
|
|
18896
|
+
map.idle.checkout_hours = retiredIdleCheckoutHours(hours.value);
|
|
18897
|
+
}
|
|
18898
|
+
}
|
|
18899
|
+
for (const path of REMOVED_DATA_LAYER_PATHS) {
|
|
18900
|
+
if (hasPath(map, path))
|
|
18901
|
+
out.removedKeys.push(`${prefix}${path}`);
|
|
18902
|
+
}
|
|
18903
|
+
}
|
|
18655
18904
|
function translateExperimentalPaths(map, prefix, out) {
|
|
18656
18905
|
for (const [oldKey, leaf] of [
|
|
18657
18906
|
["experimental_lsp_ty", "lsp_ty"],
|
|
@@ -18684,23 +18933,25 @@ function translateExperimentalPaths(map, prefix, out) {
|
|
|
18684
18933
|
const experimental = map.experimental;
|
|
18685
18934
|
const legacy = experimental.bash;
|
|
18686
18935
|
if (isRecord2(legacy)) {
|
|
18687
|
-
if (
|
|
18688
|
-
|
|
18936
|
+
if (Object.keys(legacy).length === 0)
|
|
18937
|
+
recordRetired(out, prefix, "experimental.bash");
|
|
18689
18938
|
for (const leaf of Object.keys(legacy))
|
|
18690
18939
|
recordRetired(out, prefix, `experimental.bash.${leaf}`);
|
|
18691
18940
|
if (Object.hasOwn(map, "bash")) {
|
|
18692
18941
|
superseded(out, "experimental.bash", 'experimental.bash is ignored because top-level "bash" is already set');
|
|
18693
18942
|
} else {
|
|
18694
|
-
const bash = {
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
|
|
18943
|
+
const bash = {};
|
|
18944
|
+
if (["rewrite", "compress", "background"].some((leaf) => Object.hasOwn(legacy, leaf))) {
|
|
18945
|
+
bash.rewrite = legacy.rewrite === true;
|
|
18946
|
+
bash.compress = legacy.compress === true;
|
|
18947
|
+
bash.background = legacy.background === true;
|
|
18948
|
+
}
|
|
18699
18949
|
for (const leaf of ["long_running_reminder_enabled", "long_running_reminder_interval_ms"]) {
|
|
18700
18950
|
if (Object.hasOwn(legacy, leaf))
|
|
18701
18951
|
bash[leaf] = legacy[leaf];
|
|
18702
18952
|
}
|
|
18703
|
-
|
|
18953
|
+
if (Object.keys(bash).length > 0)
|
|
18954
|
+
map.bash = bash;
|
|
18704
18955
|
}
|
|
18705
18956
|
} else {
|
|
18706
18957
|
recordRetired(out, prefix, "experimental.bash");
|
|
@@ -18713,6 +18964,7 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
18713
18964
|
const prefix = blockLabel === "base" ? "" : `${blockLabel}.`;
|
|
18714
18965
|
translateGithubAliases(map, prefix, out);
|
|
18715
18966
|
translateInspectLspPaths(map, prefix, out);
|
|
18967
|
+
translateDataLayerPaths(map, prefix, out);
|
|
18716
18968
|
dropNoEffectPaths(map, prefix, out);
|
|
18717
18969
|
translateExperimentalPaths(map, prefix, out);
|
|
18718
18970
|
if (isRecord2(map.sandbox) && Object.hasOwn(map.sandbox, "enabled")) {
|
|
@@ -18751,8 +19003,6 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
18751
19003
|
});
|
|
18752
19004
|
}
|
|
18753
19005
|
for (const [path] of RETIRED_PATHS) {
|
|
18754
|
-
if (path === "experimental.bash")
|
|
18755
|
-
continue;
|
|
18756
19006
|
if (hasPath(map, path))
|
|
18757
19007
|
recordRetired(out, prefix, path);
|
|
18758
19008
|
}
|
|
@@ -18888,13 +19138,57 @@ var NO_EFFECT_RETIRED_NOTES = [
|
|
|
18888
19138
|
"inspect.max_drill_down_items",
|
|
18889
19139
|
"inspect.max_drill_down_items never had an effect, so the setting can be removed."
|
|
18890
19140
|
],
|
|
19141
|
+
[
|
|
19142
|
+
"inspect.tier2_idle_minutes",
|
|
19143
|
+
"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."
|
|
19144
|
+
],
|
|
18891
19145
|
[
|
|
18892
19146
|
"inspect.tier2_soft_deadline_ms",
|
|
18893
19147
|
"inspect.tier2_soft_deadline_ms never had an effect, so the setting can be removed."
|
|
18894
19148
|
]
|
|
18895
19149
|
];
|
|
18896
19150
|
function noEffectNote(key) {
|
|
18897
|
-
return NO_EFFECT_RETIRED_NOTES.find(([path]) => key
|
|
19151
|
+
return NO_EFFECT_RETIRED_NOTES.find(([path]) => namesPath(key, path))?.[1];
|
|
19152
|
+
}
|
|
19153
|
+
function namesPath(key, path) {
|
|
19154
|
+
return key === path || key.endsWith(`.${path}`);
|
|
19155
|
+
}
|
|
19156
|
+
var REMOVED_DATA_LAYER_NOTES = [
|
|
19157
|
+
[
|
|
19158
|
+
"views.callgraph_copies",
|
|
19159
|
+
"views.callgraph_copies is gone because no checkout borrows another checkout's call graph any more."
|
|
19160
|
+
],
|
|
19161
|
+
[
|
|
19162
|
+
"views.enabled",
|
|
19163
|
+
"views.enabled is gone because AFT now keeps one index store per repository and always uses it."
|
|
19164
|
+
],
|
|
19165
|
+
[
|
|
19166
|
+
"worktree.ram_overlay",
|
|
19167
|
+
"worktree.ram_overlay is gone because every worktree now has its own index state, so there is no borrowed index to patch in memory."
|
|
19168
|
+
]
|
|
19169
|
+
];
|
|
19170
|
+
function retiredIdleCheckoutHoursNote() {
|
|
19171
|
+
const [retired, replacement] = RETIRED_IDLE_CHECKOUT_HOURS;
|
|
19172
|
+
return `${retired} is now ${replacement}; from ${refusedFromVersion()} AFT refuses a config file that still sets ${retired}.`;
|
|
19173
|
+
}
|
|
19174
|
+
function removedConfigKeysNoticeMessage(configPath, translation) {
|
|
19175
|
+
const removed = translation.removedKeys ?? [];
|
|
19176
|
+
if (removed.length === 0)
|
|
19177
|
+
return "";
|
|
19178
|
+
const parts = [
|
|
19179
|
+
`${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.`
|
|
19180
|
+
];
|
|
19181
|
+
for (const [path, note] of REMOVED_DATA_LAYER_NOTES) {
|
|
19182
|
+
if (removed.some((key) => namesPath(key, path)))
|
|
19183
|
+
parts.push(note);
|
|
19184
|
+
}
|
|
19185
|
+
return parts.join(" ");
|
|
19186
|
+
}
|
|
19187
|
+
function removedConfigKeysNoticeDigest(translation) {
|
|
19188
|
+
return noticeDigest({
|
|
19189
|
+
notice: "removed_data_layer_keys_v1",
|
|
19190
|
+
keys: sortedUnique(translation.removedKeys)
|
|
19191
|
+
});
|
|
18898
19192
|
}
|
|
18899
19193
|
function legacyConfigNoticeMessage(configPath, translation) {
|
|
18900
19194
|
const equivalents = translation.retiredKeys.filter((key) => noEffectNote(key) === undefined);
|
|
@@ -18904,11 +19198,17 @@ function legacyConfigNoticeMessage(configPath, translation) {
|
|
|
18904
19198
|
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.`);
|
|
18905
19199
|
if (translation.retiredEnabledFalse)
|
|
18906
19200
|
parts.push(RETIRED_ENABLED_FALSE_INDEXES_NOTE);
|
|
19201
|
+
if (equivalents.some((key) => namesPath(key, RETIRED_IDLE_CHECKOUT_HOURS[0]))) {
|
|
19202
|
+
parts.push(retiredIdleCheckoutHoursNote());
|
|
19203
|
+
}
|
|
18907
19204
|
}
|
|
18908
19205
|
for (const [, note] of NO_EFFECT_RETIRED_NOTES) {
|
|
18909
19206
|
if (noEffect.has(note))
|
|
18910
19207
|
parts.push(note);
|
|
18911
19208
|
}
|
|
19209
|
+
const removed = removedConfigKeysNoticeMessage(configPath, translation);
|
|
19210
|
+
if (removed)
|
|
19211
|
+
parts.push(removed);
|
|
18912
19212
|
return parts.join(" ");
|
|
18913
19213
|
}
|
|
18914
19214
|
function translateConfigDocument(map, tier) {
|
|
@@ -18916,6 +19216,7 @@ function translateConfigDocument(map, tier) {
|
|
|
18916
19216
|
warnings: [],
|
|
18917
19217
|
legacyInput: false,
|
|
18918
19218
|
retiredKeys: [],
|
|
19219
|
+
removedKeys: [],
|
|
18919
19220
|
retiredEnabledFalse: false
|
|
18920
19221
|
};
|
|
18921
19222
|
translateBlock(map, tier === "user", "base", out);
|
|
@@ -18926,6 +19227,7 @@ function translateConfigDocument(map, tier) {
|
|
|
18926
19227
|
}
|
|
18927
19228
|
}
|
|
18928
19229
|
out.retiredKeys = sortedUnique(out.retiredKeys);
|
|
19230
|
+
out.removedKeys = sortedUnique(out.removedKeys);
|
|
18929
19231
|
return out;
|
|
18930
19232
|
}
|
|
18931
19233
|
function unknownDisabledTools(disabled) {
|
|
@@ -18961,7 +19263,11 @@ function validateResolvedConfig(value) {
|
|
|
18961
19263
|
var ABSENT = { absent: true };
|
|
18962
19264
|
function projectBlock(block) {
|
|
18963
19265
|
const legacyPaths = {};
|
|
18964
|
-
for (const path of [
|
|
19266
|
+
for (const path of [
|
|
19267
|
+
...RETIRED_PATHS.map(([retired]) => retired),
|
|
19268
|
+
...REMOVED_NO_EFFECT_PATHS,
|
|
19269
|
+
...DATA_LAYER_RETIRED_PATHS
|
|
19270
|
+
]) {
|
|
18965
19271
|
const dot = path.indexOf(".");
|
|
18966
19272
|
if (dot < 0) {
|
|
18967
19273
|
if (Object.hasOwn(block, path))
|
|
@@ -19040,7 +19346,7 @@ function canonicalJson(value) {
|
|
|
19040
19346
|
return JSON.stringify(value);
|
|
19041
19347
|
}
|
|
19042
19348
|
function noticeDigest(projection) {
|
|
19043
|
-
return
|
|
19349
|
+
return createHash4("sha256").update(canonicalJson(projection), "utf8").digest("hex");
|
|
19044
19350
|
}
|
|
19045
19351
|
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.";
|
|
19046
19352
|
var SEMANTIC_COST_NOTICE_DIGEST = noticeDigest({ notice: "semantic_default_cost_v1" });
|
|
@@ -19913,9 +20219,9 @@ async function createConcreteAftTransportPool(opts) {
|
|
|
19913
20219
|
var LIFECYCLE_STATE = Symbol.for("@cortexkit/aft-bridge/location-lifecycle/v1");
|
|
19914
20220
|
var RELEASE_LOCATION = Symbol.for("@cortexkit/aft-bridge/location-release/v1");
|
|
19915
20221
|
// ../aft-bridge/dist/lsp-github-install.js
|
|
19916
|
-
import { createHash as
|
|
19917
|
-
import { closeSync as
|
|
19918
|
-
import { dirname as dirname4, join as join11, relative as relative4, resolve as
|
|
20222
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
20223
|
+
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";
|
|
20224
|
+
import { dirname as dirname4, join as join11, relative as relative4, resolve as resolve8 } from "node:path";
|
|
19919
20225
|
import { Readable as Readable2 } from "node:stream";
|
|
19920
20226
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
19921
20227
|
|
|
@@ -20312,7 +20618,7 @@ function createGithubInstaller(services) {
|
|
|
20312
20618
|
const MAX_EXTRACT_BYTES = 1024 * 1024 * 1024;
|
|
20313
20619
|
function sha256OfFile(path) {
|
|
20314
20620
|
return new Promise((resolve, reject) => {
|
|
20315
|
-
const hash =
|
|
20621
|
+
const hash = createHash5("sha256");
|
|
20316
20622
|
const stream = createReadStream2(path);
|
|
20317
20623
|
stream.on("error", reject);
|
|
20318
20624
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
@@ -20320,17 +20626,17 @@ function createGithubInstaller(services) {
|
|
|
20320
20626
|
});
|
|
20321
20627
|
}
|
|
20322
20628
|
function sha256OfFileSync(path) {
|
|
20323
|
-
const hash =
|
|
20324
|
-
const fd =
|
|
20629
|
+
const hash = createHash5("sha256");
|
|
20630
|
+
const fd = openSync5(path, "r");
|
|
20325
20631
|
try {
|
|
20326
20632
|
const buffer = Buffer.allocUnsafe(1024 * 1024);
|
|
20327
|
-
let read =
|
|
20633
|
+
let read = readSync5(fd, buffer, 0, buffer.length, null);
|
|
20328
20634
|
while (read > 0) {
|
|
20329
20635
|
hash.update(buffer.subarray(0, read));
|
|
20330
|
-
read =
|
|
20636
|
+
read = readSync5(fd, buffer, 0, buffer.length, null);
|
|
20331
20637
|
}
|
|
20332
20638
|
} finally {
|
|
20333
|
-
|
|
20639
|
+
closeSync6(fd);
|
|
20334
20640
|
}
|
|
20335
20641
|
return hash.digest("hex");
|
|
20336
20642
|
}
|
|
@@ -20538,7 +20844,7 @@ function createGithubInstaller(services) {
|
|
|
20538
20844
|
throw new Error(`too many redirects (>${maxRedirects})`);
|
|
20539
20845
|
}
|
|
20540
20846
|
function validateExtraction(stagingRoot) {
|
|
20541
|
-
const realStagingRoot =
|
|
20847
|
+
const realStagingRoot = realpathSync4(stagingRoot);
|
|
20542
20848
|
let totalBytes = 0;
|
|
20543
20849
|
const walk = (dir) => {
|
|
20544
20850
|
let entries;
|
|
@@ -20564,12 +20870,12 @@ function createGithubInstaller(services) {
|
|
|
20564
20870
|
}
|
|
20565
20871
|
let realFull;
|
|
20566
20872
|
try {
|
|
20567
|
-
realFull =
|
|
20873
|
+
realFull = realpathSync4(full);
|
|
20568
20874
|
} catch (err) {
|
|
20569
20875
|
throw new Error(`failed to realpath ${full}: ${err}`);
|
|
20570
20876
|
}
|
|
20571
20877
|
const rel = relative4(realStagingRoot, realFull);
|
|
20572
|
-
if (relativePathEscapesRoot(rel) ||
|
|
20878
|
+
if (relativePathEscapesRoot(rel) || resolve8(realStagingRoot, rel) !== realFull) {
|
|
20573
20879
|
throw new Error(`archive entry escapes staging root: ${full} → ${realFull} (zip-slip defense)`);
|
|
20574
20880
|
}
|
|
20575
20881
|
if (lst.isDirectory()) {
|
|
@@ -21332,6 +21638,21 @@ function resolveNpm(deps = defaultDeps()) {
|
|
|
21332
21638
|
}
|
|
21333
21639
|
return null;
|
|
21334
21640
|
}
|
|
21641
|
+
function npmCandidates(deps = defaultDeps()) {
|
|
21642
|
+
const name = npmBinaryName(deps.platform);
|
|
21643
|
+
const dirs = [
|
|
21644
|
+
...(deps.env.PATH ?? "").split(deps.platform === "win32" ? ";" : ":").filter(isAbsolute5),
|
|
21645
|
+
dirname5(deps.execPath),
|
|
21646
|
+
...wellKnownNpmDirs(deps)
|
|
21647
|
+
];
|
|
21648
|
+
return [...new Set(dirs)].flatMap((binDir) => {
|
|
21649
|
+
return [
|
|
21650
|
+
join12(binDir, name),
|
|
21651
|
+
join12(binDir, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
21652
|
+
join12(binDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
21653
|
+
].filter(isFile).map((command) => ({ command, binDir }));
|
|
21654
|
+
});
|
|
21655
|
+
}
|
|
21335
21656
|
function quoteCmdArgument(value) {
|
|
21336
21657
|
if (/[\0\r\n"%]/.test(value)) {
|
|
21337
21658
|
throw new Error(`npm argument cannot be represented safely for cmd.exe: ${JSON.stringify(value)}`);
|
|
@@ -21339,6 +21660,8 @@ function quoteCmdArgument(value) {
|
|
|
21339
21660
|
return `"${value}"`;
|
|
21340
21661
|
}
|
|
21341
21662
|
function npmInvocation(resolved, npmArgs, platform = process.platform, env = process.env) {
|
|
21663
|
+
if (resolved.cliPath)
|
|
21664
|
+
return { command: resolved.command, args: [resolved.cliPath, ...npmArgs] };
|
|
21342
21665
|
if (platform !== "win32" || !/\.(?:cmd|bat)$/i.test(resolved.command)) {
|
|
21343
21666
|
return { command: resolved.command, args: [...npmArgs] };
|
|
21344
21667
|
}
|
|
@@ -21591,10 +21914,11 @@ function probeNpmCutoffSupport(npm, clock) {
|
|
|
21591
21914
|
});
|
|
21592
21915
|
}
|
|
21593
21916
|
async function npmSupportsCutoff(npm, clock) {
|
|
21594
|
-
const
|
|
21917
|
+
const key = npm.cliPath ? `${npm.command}\x00${npm.cliPath}` : npm.command;
|
|
21918
|
+
const identity = await stat2(npm.cliPath ?? npm.command).then(({ size, mtimeMs }) => ({ size, mtimeMs })).catch(() => {
|
|
21595
21919
|
return;
|
|
21596
21920
|
});
|
|
21597
|
-
const existing = npmCutoffSupport.get(
|
|
21921
|
+
const existing = npmCutoffSupport.get(key);
|
|
21598
21922
|
const sameIdentity = existing && existing.identity?.size === identity?.size && existing.identity?.mtimeMs === identity?.mtimeMs;
|
|
21599
21923
|
if (existing && sameIdentity) {
|
|
21600
21924
|
if (!existing.settled || identity !== undefined && existing.settled.outcome !== "transient" || clock.now() < existing.settled.retryAt)
|
|
@@ -21605,7 +21929,7 @@ async function npmSupportsCutoff(npm, clock) {
|
|
|
21605
21929
|
return outcome;
|
|
21606
21930
|
});
|
|
21607
21931
|
const entry = { identity, pending };
|
|
21608
|
-
npmCutoffSupport.set(
|
|
21932
|
+
npmCutoffSupport.set(key, entry);
|
|
21609
21933
|
return pending;
|
|
21610
21934
|
}
|
|
21611
21935
|
function lspPublicationCutoff(graceDays, pinned, now = Date.now()) {
|
|
@@ -21623,6 +21947,79 @@ async function lspNpmInstallInvocation(npm, target, before, clock = SYSTEM_CLOCK
|
|
|
21623
21947
|
target
|
|
21624
21948
|
]);
|
|
21625
21949
|
}
|
|
21950
|
+
// ../aft-bridge/dist/lsp-npm-selection.js
|
|
21951
|
+
import { readFile, realpath, stat as stat3 } from "node:fs/promises";
|
|
21952
|
+
import { dirname as dirname6, join as join13, resolve as resolve9 } from "node:path";
|
|
21953
|
+
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.";
|
|
21954
|
+
function lspNpmRefusal(path, reason) {
|
|
21955
|
+
return LSP_NPM_REFUSAL.replace("<path>", path).replace("<reason>", reason);
|
|
21956
|
+
}
|
|
21957
|
+
async function genuineNpm(candidate) {
|
|
21958
|
+
let executable;
|
|
21959
|
+
try {
|
|
21960
|
+
executable = await realpath(candidate.command);
|
|
21961
|
+
} catch (error) {
|
|
21962
|
+
return { reason: `probe failed: ${String(error)}` };
|
|
21963
|
+
}
|
|
21964
|
+
const windowsShim = /\.(?:cmd|bat)$/i.test(executable);
|
|
21965
|
+
let current = dirname6(executable);
|
|
21966
|
+
if (windowsShim)
|
|
21967
|
+
current = join13(current, "node_modules", "npm");
|
|
21968
|
+
for (;; ) {
|
|
21969
|
+
try {
|
|
21970
|
+
const pkg = JSON.parse(await readFile(join13(current, "package.json"), "utf8"));
|
|
21971
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.npm;
|
|
21972
|
+
if (pkg.name === "npm" && typeof bin === "string") {
|
|
21973
|
+
const cli = await realpath(resolve9(current, bin));
|
|
21974
|
+
if (!windowsShim && cli !== executable)
|
|
21975
|
+
return { reason: "not npm: command is not npm's declared CLI" };
|
|
21976
|
+
const major = /^(\d+)\.\d+\.\d+$/.exec(pkg.version)?.[1];
|
|
21977
|
+
if (!major)
|
|
21978
|
+
return { reason: "probe failed: npm manifest has an unknown version" };
|
|
21979
|
+
if (Number(major) < 7)
|
|
21980
|
+
return { reason: `old npm: ${pkg.version} (requires npm 7 or newer)` };
|
|
21981
|
+
if (windowsShim || process.platform === "win32" && /\.[cm]?js$/i.test(cli)) {
|
|
21982
|
+
const node = join13(candidate.binDir ?? dirname6(executable), "node.exe");
|
|
21983
|
+
if (!(await stat3(node)).isFile())
|
|
21984
|
+
return { reason: "probe failed: adjacent Node is missing" };
|
|
21985
|
+
return { npm: { command: node, binDir: dirname6(node), cliPath: cli }, reason: "" };
|
|
21986
|
+
}
|
|
21987
|
+
return { npm: { command: cli, binDir: candidate.binDir }, reason: "" };
|
|
21988
|
+
}
|
|
21989
|
+
} catch {}
|
|
21990
|
+
const parent = dirname6(current);
|
|
21991
|
+
if (parent === current || windowsShim)
|
|
21992
|
+
break;
|
|
21993
|
+
current = parent;
|
|
21994
|
+
}
|
|
21995
|
+
return { reason: "not npm: no matching npm package manifest and CLI" };
|
|
21996
|
+
}
|
|
21997
|
+
async function selectLspNpm(preferred, candidates, signal) {
|
|
21998
|
+
const aborted = () => ({
|
|
21999
|
+
refusal: lspNpmRefusal(preferred.command, "probe failed: installation aborted")
|
|
22000
|
+
});
|
|
22001
|
+
if (signal?.aborted)
|
|
22002
|
+
return aborted();
|
|
22003
|
+
const first = await genuineNpm(preferred);
|
|
22004
|
+
if (signal?.aborted)
|
|
22005
|
+
return aborted();
|
|
22006
|
+
if (first.npm)
|
|
22007
|
+
return { npm: first.npm };
|
|
22008
|
+
const seen = new Set([preferred.command]);
|
|
22009
|
+
for (const candidate of candidates ?? npmCandidates()) {
|
|
22010
|
+
if (signal?.aborted)
|
|
22011
|
+
return aborted();
|
|
22012
|
+
if (seen.has(candidate.command))
|
|
22013
|
+
continue;
|
|
22014
|
+
seen.add(candidate.command);
|
|
22015
|
+
const result = await genuineNpm(candidate);
|
|
22016
|
+
if (signal?.aborted)
|
|
22017
|
+
return aborted();
|
|
22018
|
+
if (result.npm)
|
|
22019
|
+
return { npm: result.npm };
|
|
22020
|
+
}
|
|
22021
|
+
return { refusal: lspNpmRefusal(preferred.command, first.reason) };
|
|
22022
|
+
}
|
|
21626
22023
|
// ../aft-bridge/dist/message-detach.js
|
|
21627
22024
|
var BASH_WAIT_DETACH_MAGIC_KEYWORD = "&detach";
|
|
21628
22025
|
var STANDALONE_DETACH_KEYWORD_SOURCE = `(^|[^\\p{L}\\p{N}_])${BASH_WAIT_DETACH_MAGIC_KEYWORD}(?![\\p{L}\\p{N}_])`;
|
|
@@ -21672,14 +22069,14 @@ function shouldInterruptWaitsForMessage(detachOnUserMessage, operatorText) {
|
|
|
21672
22069
|
return detachOnUserMessage || containsStandaloneDetachKeyword(operatorText);
|
|
21673
22070
|
}
|
|
21674
22071
|
// ../aft-bridge/dist/migration.js
|
|
21675
|
-
import { closeSync as
|
|
22072
|
+
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";
|
|
21676
22073
|
import { homedir as homedir12, tmpdir as tmpdir3 } from "node:os";
|
|
21677
|
-
import { basename as basename2, dirname as
|
|
22074
|
+
import { basename as basename2, dirname as dirname9, join as join16, resolve as resolve11 } from "node:path";
|
|
21678
22075
|
|
|
21679
22076
|
// ../aft-bridge/dist/paths.js
|
|
21680
|
-
import { existsSync as existsSync7, readFileSync as readFileSync6, realpathSync as
|
|
22077
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, realpathSync as realpathSync5, renameSync as renameSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
21681
22078
|
import { homedir as homedir10 } from "node:os";
|
|
21682
|
-
import { dirname as
|
|
22079
|
+
import { dirname as dirname7, isAbsolute as isAbsolute6, join as join14, resolve as resolve10 } from "node:path";
|
|
21683
22080
|
function homeDir3() {
|
|
21684
22081
|
if (process.platform === "win32")
|
|
21685
22082
|
return process.env.USERPROFILE || process.env.HOME || homedir10();
|
|
@@ -21689,16 +22086,16 @@ function configHome() {
|
|
|
21689
22086
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
21690
22087
|
if (xdg && isAbsolute6(xdg))
|
|
21691
22088
|
return xdg;
|
|
21692
|
-
return
|
|
22089
|
+
return join14(homeDir3(), ".config");
|
|
21693
22090
|
}
|
|
21694
22091
|
function legacyOpenCodeConfigDir() {
|
|
21695
22092
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
21696
22093
|
if (envDir)
|
|
21697
|
-
return
|
|
21698
|
-
return
|
|
22094
|
+
return resolve10(envDir);
|
|
22095
|
+
return join14(configHome(), "opencode");
|
|
21699
22096
|
}
|
|
21700
22097
|
function legacyPiAgentDir() {
|
|
21701
|
-
return
|
|
22098
|
+
return join14(homeDir3(), ".pi", "agent");
|
|
21702
22099
|
}
|
|
21703
22100
|
function legacySources(basePath, label, harness) {
|
|
21704
22101
|
return [
|
|
@@ -21707,10 +22104,10 @@ function legacySources(basePath, label, harness) {
|
|
|
21707
22104
|
];
|
|
21708
22105
|
}
|
|
21709
22106
|
function resolveCortexKitUserConfigPath() {
|
|
21710
|
-
return
|
|
22107
|
+
return join14(configHome(), "cortexkit", "aft.jsonc");
|
|
21711
22108
|
}
|
|
21712
22109
|
function resolveCortexKitProjectConfigPath(projectDirectory) {
|
|
21713
|
-
return
|
|
22110
|
+
return join14(projectDirectory, ".cortexkit", "aft.jsonc");
|
|
21714
22111
|
}
|
|
21715
22112
|
function resolveProjectConfigReadPath(projectDirectory, operatingHarness) {
|
|
21716
22113
|
const canonical = resolveCortexKitProjectConfigPath(projectDirectory);
|
|
@@ -21737,14 +22134,14 @@ function resolveCortexKitConfigPaths(projectDirectory) {
|
|
|
21737
22134
|
}
|
|
21738
22135
|
function resolveLegacyAftConfigSources(projectDirectory) {
|
|
21739
22136
|
const project = [
|
|
21740
|
-
...legacySources(
|
|
21741
|
-
...legacySources(
|
|
22137
|
+
...legacySources(join14(projectDirectory, ".opencode", "aft"), "OpenCode project", "opencode"),
|
|
22138
|
+
...legacySources(join14(projectDirectory, ".pi", "aft"), "Pi project", "pi")
|
|
21742
22139
|
];
|
|
21743
22140
|
const identity = (path) => {
|
|
21744
22141
|
try {
|
|
21745
|
-
return
|
|
22142
|
+
return realpathSync5(path);
|
|
21746
22143
|
} catch {
|
|
21747
|
-
return
|
|
22144
|
+
return resolve10(path);
|
|
21748
22145
|
}
|
|
21749
22146
|
};
|
|
21750
22147
|
const protectedPaths = new Set([
|
|
@@ -21753,22 +22150,22 @@ function resolveLegacyAftConfigSources(projectDirectory) {
|
|
|
21753
22150
|
].map(identity));
|
|
21754
22151
|
return {
|
|
21755
22152
|
user: [
|
|
21756
|
-
...legacySources(
|
|
21757
|
-
...legacySources(
|
|
22153
|
+
...legacySources(join14(legacyOpenCodeConfigDir(), "aft"), "OpenCode user", "opencode"),
|
|
22154
|
+
...legacySources(join14(legacyPiAgentDir(), "aft"), "Pi user", "pi")
|
|
21758
22155
|
].filter((source) => !protectedPaths.has(identity(source.path))),
|
|
21759
22156
|
project
|
|
21760
22157
|
};
|
|
21761
22158
|
}
|
|
21762
22159
|
function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
|
|
21763
|
-
return
|
|
22160
|
+
return join14(storageRoot, harness, ...segments);
|
|
21764
22161
|
}
|
|
21765
22162
|
function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
21766
22163
|
const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
|
|
21767
|
-
const rootPath =
|
|
22164
|
+
const rootPath = join14(storageRoot, fileName);
|
|
21768
22165
|
if (existsSync7(harnessPath) || !existsSync7(rootPath))
|
|
21769
22166
|
return harnessPath;
|
|
21770
22167
|
try {
|
|
21771
|
-
openPrivateStorageDir(storageRoot,
|
|
22168
|
+
openPrivateStorageDir(storageRoot, dirname7(harnessPath));
|
|
21772
22169
|
renameSync4(rootPath, harnessPath);
|
|
21773
22170
|
} catch {}
|
|
21774
22171
|
return harnessPath;
|
|
@@ -21789,7 +22186,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
|
|
|
21789
22186
|
return false;
|
|
21790
22187
|
if (!lastVersion) {
|
|
21791
22188
|
try {
|
|
21792
|
-
openPrivateStorageDir(storageRoot,
|
|
22189
|
+
openPrivateStorageDir(storageRoot, dirname7(versionFile));
|
|
21793
22190
|
writeFileSync3(versionFile, currentVersion, { mode: PRIVATE_FILE_MODE });
|
|
21794
22191
|
} catch {}
|
|
21795
22192
|
return false;
|
|
@@ -21801,7 +22198,7 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
|
|
|
21801
22198
|
return;
|
|
21802
22199
|
const versionFile = repairRootScopedStorageFile(storageRoot, harness, "last_announced_version");
|
|
21803
22200
|
try {
|
|
21804
|
-
openPrivateStorageDir(storageRoot,
|
|
22201
|
+
openPrivateStorageDir(storageRoot, dirname7(versionFile));
|
|
21805
22202
|
writeFileSync3(versionFile, currentVersion, { mode: PRIVATE_FILE_MODE });
|
|
21806
22203
|
} catch {}
|
|
21807
22204
|
}
|
|
@@ -21850,18 +22247,18 @@ function decodeFileUrl(target) {
|
|
|
21850
22247
|
}
|
|
21851
22248
|
|
|
21852
22249
|
// ../aft-bridge/dist/resolver.js
|
|
21853
|
-
import { closeSync as
|
|
21854
|
-
import { createRequire } from "node:module";
|
|
22250
|
+
import { closeSync as closeSync7, existsSync as existsSync8, promises as fsPromises, openSync as openSync6, readFileSync as readFileSync7, readSync as readSync6 } from "node:fs";
|
|
22251
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
21855
22252
|
import { homedir as homedir11 } from "node:os";
|
|
21856
|
-
import { delimiter, dirname as
|
|
22253
|
+
import { delimiter, dirname as dirname8, isAbsolute as isAbsolute7, join as join15 } from "node:path";
|
|
21857
22254
|
var ensureBinaryForResolver = ensureBinary;
|
|
21858
22255
|
var npmPlatformPackageReader = null;
|
|
21859
22256
|
var cacheCopiesInFlight = new Map;
|
|
21860
22257
|
function copyToVersionedCache(npmBinaryPath, version) {
|
|
21861
22258
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
21862
22259
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
21863
|
-
const versionedDir =
|
|
21864
|
-
const cachedPath =
|
|
22260
|
+
const versionedDir = join15(getAftBinaryCacheDir(), tag);
|
|
22261
|
+
const cachedPath = join15(versionedDir, `aft${ext}`);
|
|
21865
22262
|
if (existsSync8(cachedPath) && isTrustedCachedBinary(cachedPath, version))
|
|
21866
22263
|
return { cachedPath };
|
|
21867
22264
|
const existing = cacheCopiesInFlight.get(cachedPath);
|
|
@@ -21907,7 +22304,7 @@ function homeDirFromEnv(env) {
|
|
|
21907
22304
|
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir11();
|
|
21908
22305
|
}
|
|
21909
22306
|
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
21910
|
-
const binaryPath =
|
|
22307
|
+
const binaryPath = join15(getAftBinaryCacheDir(env), version, `aft${ext}`);
|
|
21911
22308
|
return existsSync8(binaryPath) ? binaryPath : null;
|
|
21912
22309
|
}
|
|
21913
22310
|
async function probeBinaryCandidateOffThread(binaryPath, source, expectedVersion) {
|
|
@@ -21929,7 +22326,7 @@ function pathCandidates(env, ext) {
|
|
|
21929
22326
|
for (const dir of rawPath.split(delimiter)) {
|
|
21930
22327
|
if (!dir || !isAbsolute7(dir))
|
|
21931
22328
|
continue;
|
|
21932
|
-
const candidate =
|
|
22329
|
+
const candidate = join15(dir, `aft${ext}`);
|
|
21933
22330
|
if (seen.has(candidate))
|
|
21934
22331
|
continue;
|
|
21935
22332
|
seen.add(candidate);
|
|
@@ -21941,9 +22338,9 @@ function pathCandidates(env, ext) {
|
|
|
21941
22338
|
function isNativeExecutable(binaryPath) {
|
|
21942
22339
|
let fd = null;
|
|
21943
22340
|
try {
|
|
21944
|
-
fd =
|
|
22341
|
+
fd = openSync6(binaryPath, "r");
|
|
21945
22342
|
const buf = Buffer.alloc(4);
|
|
21946
|
-
const read =
|
|
22343
|
+
const read = readSync6(fd, buf, 0, 4, 0);
|
|
21947
22344
|
if (read < 2)
|
|
21948
22345
|
return false;
|
|
21949
22346
|
const b0 = buf[0];
|
|
@@ -21964,7 +22361,7 @@ function isNativeExecutable(binaryPath) {
|
|
|
21964
22361
|
} finally {
|
|
21965
22362
|
if (fd !== null) {
|
|
21966
22363
|
try {
|
|
21967
|
-
|
|
22364
|
+
closeSync7(fd);
|
|
21968
22365
|
} catch {}
|
|
21969
22366
|
}
|
|
21970
22367
|
}
|
|
@@ -21994,7 +22391,7 @@ function explicitBinaryOverride(env) {
|
|
|
21994
22391
|
}
|
|
21995
22392
|
function ownPackageVersion() {
|
|
21996
22393
|
try {
|
|
21997
|
-
const req =
|
|
22394
|
+
const req = createRequire2(import.meta.url);
|
|
21998
22395
|
return req("../package.json").version;
|
|
21999
22396
|
} catch {
|
|
22000
22397
|
return null;
|
|
@@ -22004,10 +22401,10 @@ function npmPlatformPackage(ext) {
|
|
|
22004
22401
|
if (npmPlatformPackageReader)
|
|
22005
22402
|
return npmPlatformPackageReader(ext);
|
|
22006
22403
|
try {
|
|
22007
|
-
const req =
|
|
22404
|
+
const req = createRequire2(import.meta.url);
|
|
22008
22405
|
const manifestPath = req.resolve(`@cortexkit/aft-${platformKey()}/package.json`);
|
|
22009
22406
|
const manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
|
|
22010
|
-
const binaryPath =
|
|
22407
|
+
const binaryPath = join15(dirname8(manifestPath), "bin", `aft${ext}`);
|
|
22011
22408
|
if (typeof manifest.version !== "string" || !existsSync8(binaryPath))
|
|
22012
22409
|
return null;
|
|
22013
22410
|
return { binaryPath, version: normalizeBareVersion(manifest.version) };
|
|
@@ -22074,7 +22471,7 @@ async function findProbedBinary(expectedVersion, env) {
|
|
|
22074
22471
|
if (usable)
|
|
22075
22472
|
return { path: usable, source: "PATH" };
|
|
22076
22473
|
}
|
|
22077
|
-
const cargoPath =
|
|
22474
|
+
const cargoPath = join15(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
22078
22475
|
if (existsSync8(cargoPath)) {
|
|
22079
22476
|
const usable = await probeBinaryCandidateOffThread(cargoPath, "cargo", pluginVersion);
|
|
22080
22477
|
if (usable)
|
|
@@ -22173,9 +22570,9 @@ function dataHome() {
|
|
|
22173
22570
|
if (process.env.XDG_DATA_HOME)
|
|
22174
22571
|
return process.env.XDG_DATA_HOME;
|
|
22175
22572
|
if (process.platform === "win32") {
|
|
22176
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
22573
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join16(homeDir4(), "AppData", "Local");
|
|
22177
22574
|
}
|
|
22178
|
-
return
|
|
22575
|
+
return join16(homeDir4(), ".local", "share");
|
|
22179
22576
|
}
|
|
22180
22577
|
function homeDir4() {
|
|
22181
22578
|
if (process.platform === "win32")
|
|
@@ -22184,8 +22581,8 @@ function homeDir4() {
|
|
|
22184
22581
|
}
|
|
22185
22582
|
function resolveLegacyStorageRoot(harness) {
|
|
22186
22583
|
if (harness === "pi")
|
|
22187
|
-
return
|
|
22188
|
-
return
|
|
22584
|
+
return join16(homeDir4(), ".pi", "agent", "aft");
|
|
22585
|
+
return join16(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
22189
22586
|
}
|
|
22190
22587
|
function stripJsoncForParse(input) {
|
|
22191
22588
|
let out = "";
|
|
@@ -22314,19 +22711,19 @@ function acquireConfigMigrationLock(lockDir) {
|
|
|
22314
22711
|
}
|
|
22315
22712
|
}
|
|
22316
22713
|
function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
22317
|
-
mkdirSync5(
|
|
22318
|
-
const tmpPath =
|
|
22714
|
+
mkdirSync5(dirname9(targetPath), { recursive: true });
|
|
22715
|
+
const tmpPath = join16(dirname9(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
22319
22716
|
let fd = null;
|
|
22320
22717
|
try {
|
|
22321
|
-
fd =
|
|
22718
|
+
fd = openSync7(tmpPath, "wx", 384);
|
|
22322
22719
|
writeFileSync4(fd, readFileSync8(sourcePath));
|
|
22323
|
-
|
|
22720
|
+
closeSync8(fd);
|
|
22324
22721
|
fd = null;
|
|
22325
22722
|
renameSync5(tmpPath, targetPath);
|
|
22326
22723
|
} catch (err) {
|
|
22327
22724
|
if (fd !== null) {
|
|
22328
22725
|
try {
|
|
22329
|
-
|
|
22726
|
+
closeSync8(fd);
|
|
22330
22727
|
} catch {}
|
|
22331
22728
|
}
|
|
22332
22729
|
try {
|
|
@@ -22336,19 +22733,19 @@ function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
|
22336
22733
|
}
|
|
22337
22734
|
}
|
|
22338
22735
|
function atomicWriteConfigFile(targetPath, content) {
|
|
22339
|
-
mkdirSync5(
|
|
22340
|
-
const tmpPath =
|
|
22736
|
+
mkdirSync5(dirname9(targetPath), { recursive: true });
|
|
22737
|
+
const tmpPath = join16(dirname9(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
22341
22738
|
let fd = null;
|
|
22342
22739
|
try {
|
|
22343
|
-
fd =
|
|
22740
|
+
fd = openSync7(tmpPath, "wx", 384);
|
|
22344
22741
|
writeFileSync4(fd, content);
|
|
22345
|
-
|
|
22742
|
+
closeSync8(fd);
|
|
22346
22743
|
fd = null;
|
|
22347
22744
|
renameSync5(tmpPath, targetPath);
|
|
22348
22745
|
} catch (err) {
|
|
22349
22746
|
if (fd !== null) {
|
|
22350
22747
|
try {
|
|
22351
|
-
|
|
22748
|
+
closeSync8(fd);
|
|
22352
22749
|
} catch {}
|
|
22353
22750
|
}
|
|
22354
22751
|
try {
|
|
@@ -22456,13 +22853,13 @@ function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
|
|
|
22456
22853
|
}
|
|
22457
22854
|
function migrateAftConfigFile(opts) {
|
|
22458
22855
|
const warnings = [];
|
|
22459
|
-
const resolvedTarget =
|
|
22460
|
-
const existingSources = opts.legacySources.filter((source) => existsSync9(source.path) &&
|
|
22856
|
+
const resolvedTarget = resolve11(opts.targetPath);
|
|
22857
|
+
const existingSources = opts.legacySources.filter((source) => existsSync9(source.path) && resolve11(source.path) !== resolvedTarget);
|
|
22461
22858
|
const info = opts.logger?.info ?? opts.logger?.log;
|
|
22462
22859
|
if (existingSources.length === 0) {
|
|
22463
22860
|
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
22464
22861
|
}
|
|
22465
|
-
mkdirSync5(
|
|
22862
|
+
mkdirSync5(dirname9(opts.targetPath), { recursive: true });
|
|
22466
22863
|
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
22467
22864
|
try {
|
|
22468
22865
|
const sources = existingSources.map((source) => ({
|
|
@@ -22519,13 +22916,13 @@ function spawnErrorLabel(error) {
|
|
|
22519
22916
|
return [code, error.message].filter(Boolean).join(": ");
|
|
22520
22917
|
}
|
|
22521
22918
|
function migrationLogPath(newRoot, harness, logger) {
|
|
22522
|
-
const desired =
|
|
22919
|
+
const desired = join16(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
22523
22920
|
try {
|
|
22524
|
-
mkdirSync5(
|
|
22921
|
+
mkdirSync5(dirname9(desired), { recursive: true });
|
|
22525
22922
|
return desired;
|
|
22526
22923
|
} catch (err) {
|
|
22527
|
-
const fallback =
|
|
22528
|
-
logger?.warn?.(`Failed to create AFT migration log directory ${
|
|
22924
|
+
const fallback = join16(tmpdir3(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
22925
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname9(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
22529
22926
|
return fallback;
|
|
22530
22927
|
}
|
|
22531
22928
|
}
|
|
@@ -22584,13 +22981,13 @@ async function ensureStorageMigrated(opts) {
|
|
|
22584
22981
|
// ../aft-bridge/dist/migration-notices.js
|
|
22585
22982
|
import { readFileSync as readFileSync9, renameSync as renameSync6, rmdirSync, statSync as statSync9, writeFileSync as writeFileSync5 } from "node:fs";
|
|
22586
22983
|
import { homedir as homedir13 } from "node:os";
|
|
22587
|
-
import { dirname as
|
|
22984
|
+
import { dirname as dirname10, join as join17, resolve as resolve12 } from "node:path";
|
|
22588
22985
|
function migrationNoticeStorePath(env = process.env) {
|
|
22589
|
-
const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME :
|
|
22590
|
-
return
|
|
22986
|
+
const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join17(homedir13(), ".local", "state");
|
|
22987
|
+
return join17(stateHome, "cortexkit", "aft", "migration-notices.json");
|
|
22591
22988
|
}
|
|
22592
22989
|
function noticeKey(configPath, digest) {
|
|
22593
|
-
return `${
|
|
22990
|
+
return `${resolve12(configPath)}|${MIGRATION_POLICY_ID}|${digest}`;
|
|
22594
22991
|
}
|
|
22595
22992
|
function readRecords(storePath) {
|
|
22596
22993
|
try {
|
|
@@ -22603,7 +23000,7 @@ function readRecords(storePath) {
|
|
|
22603
23000
|
var LOCK_STALE_MS = 1e4;
|
|
22604
23001
|
function withStoreLock(storePath, action) {
|
|
22605
23002
|
const lockPath = `${storePath}.lock`;
|
|
22606
|
-
openPrivateStorageDir(
|
|
23003
|
+
openPrivateStorageDir(dirname10(storePath));
|
|
22607
23004
|
const deadline = Date.now() + 2000;
|
|
22608
23005
|
for (;; ) {
|
|
22609
23006
|
try {
|
|
@@ -22657,7 +23054,7 @@ function deliverMigrationNoticeOnce(options) {
|
|
|
22657
23054
|
}
|
|
22658
23055
|
}
|
|
22659
23056
|
// ../aft-bridge/dist/onnx-probe.js
|
|
22660
|
-
import { closeSync as
|
|
23057
|
+
import { closeSync as closeSync9, existsSync as existsSync10, openSync as openSync8, readSync as readSync7, realpathSync as realpathSync6 } from "node:fs";
|
|
22661
23058
|
var MH_MAGIC = 4277009102;
|
|
22662
23059
|
var MH_MAGIC_64 = 4277009103;
|
|
22663
23060
|
var FAT_MAGIC = 3405691582;
|
|
@@ -22670,7 +23067,7 @@ var MAX_HEADER_BYTES = 4 * 1024 * 1024;
|
|
|
22670
23067
|
var UNCHECKED = { loadable: true, checked: false };
|
|
22671
23068
|
function readAt(fd, offset, length) {
|
|
22672
23069
|
const buffer = Buffer.alloc(length);
|
|
22673
|
-
const read =
|
|
23070
|
+
const read = readSync7(fd, buffer, 0, length, offset);
|
|
22674
23071
|
return buffer.subarray(0, read);
|
|
22675
23072
|
}
|
|
22676
23073
|
function cpuTypeForArch(arch) {
|
|
@@ -22744,7 +23141,7 @@ function isUncheckableDependency(path) {
|
|
|
22744
23141
|
function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
|
|
22745
23142
|
let fd;
|
|
22746
23143
|
try {
|
|
22747
|
-
fd =
|
|
23144
|
+
fd = openSync8(realpathSync6(libPath), "r");
|
|
22748
23145
|
} catch (err) {
|
|
22749
23146
|
return {
|
|
22750
23147
|
loadable: false,
|
|
@@ -22778,13 +23175,13 @@ function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
|
|
|
22778
23175
|
} catch {
|
|
22779
23176
|
return UNCHECKED;
|
|
22780
23177
|
} finally {
|
|
22781
|
-
|
|
23178
|
+
closeSync9(fd);
|
|
22782
23179
|
}
|
|
22783
23180
|
}
|
|
22784
23181
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
22785
23182
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
22786
|
-
import { chmodSync as chmodSync2, closeSync as
|
|
22787
|
-
import { basename as basename3, dirname as
|
|
23183
|
+
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";
|
|
23184
|
+
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";
|
|
22788
23185
|
import { Readable as Readable3 } from "node:stream";
|
|
22789
23186
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
22790
23187
|
var ORT_VERSION = "1.24.4";
|
|
@@ -22872,7 +23269,7 @@ function resolveOnnxRuntime(storageDir, seams) {
|
|
|
22872
23269
|
}
|
|
22873
23270
|
async function findCachedOnnxRuntime(ortVersionDir, libName) {
|
|
22874
23271
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
22875
|
-
const libPath =
|
|
23272
|
+
const libPath = join18(resolvedOrtDir, libName);
|
|
22876
23273
|
if (existsSync11(libPath)) {
|
|
22877
23274
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
22878
23275
|
if (meta?.sha256) {
|
|
@@ -22897,7 +23294,7 @@ async function findCachedOnnxRuntime(ortVersionDir, libName) {
|
|
|
22897
23294
|
}
|
|
22898
23295
|
async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
|
|
22899
23296
|
const info = seams.platformInfo !== undefined ? seams.platformInfo : getPlatformInfo();
|
|
22900
|
-
const ortVersionDir =
|
|
23297
|
+
const ortVersionDir = join18(storageDir, "onnxruntime", ORT_VERSION);
|
|
22901
23298
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
22902
23299
|
const cached = await findCachedOnnxRuntime(ortVersionDir, libName);
|
|
22903
23300
|
if (cached)
|
|
@@ -22911,9 +23308,9 @@ async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
|
|
|
22911
23308
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
22912
23309
|
return null;
|
|
22913
23310
|
}
|
|
22914
|
-
const onnxBaseDir =
|
|
23311
|
+
const onnxBaseDir = join18(storageDir, "onnxruntime");
|
|
22915
23312
|
openPrivateStorageDir(storageDir, onnxBaseDir);
|
|
22916
|
-
const lockPath =
|
|
23313
|
+
const lockPath = join18(onnxBaseDir, ONNX_LOCK_FILE);
|
|
22917
23314
|
const pollMs = seams.lockPollMs ?? LOCK_POLL_MS;
|
|
22918
23315
|
const deadline = Date.now() + LOCK_WAIT_MS;
|
|
22919
23316
|
let announcedWait = false;
|
|
@@ -22958,7 +23355,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
22958
23355
|
for (const entry of entries) {
|
|
22959
23356
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
22960
23357
|
continue;
|
|
22961
|
-
const stagingDir =
|
|
23358
|
+
const stagingDir = join18(onnxBaseDir, entry);
|
|
22962
23359
|
const parts = entry.split(".");
|
|
22963
23360
|
const pidStr = parts[parts.length - 2];
|
|
22964
23361
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -22995,7 +23392,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
22995
23392
|
}
|
|
22996
23393
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
22997
23394
|
try {
|
|
22998
|
-
if (existsSync11(ortDir) && !existsSync11(
|
|
23395
|
+
if (existsSync11(ortDir) && !existsSync11(join18(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
22999
23396
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
23000
23397
|
rmSync4(ortDir, { recursive: true, force: true });
|
|
23001
23398
|
}
|
|
@@ -23030,7 +23427,7 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
23030
23427
|
try {
|
|
23031
23428
|
const entries = readdirSync4(libDir);
|
|
23032
23429
|
try {
|
|
23033
|
-
const resolved = parseOnnxVersionFromPath(
|
|
23430
|
+
const resolved = parseOnnxVersionFromPath(realpathSync7(join18(libDir, libName)));
|
|
23034
23431
|
if (resolved && resolved !== INVALID_ORT_VERSION)
|
|
23035
23432
|
return resolved;
|
|
23036
23433
|
} catch {}
|
|
@@ -23044,10 +23441,10 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
23044
23441
|
if (version)
|
|
23045
23442
|
return version;
|
|
23046
23443
|
}
|
|
23047
|
-
const base =
|
|
23444
|
+
const base = join18(libDir, libName);
|
|
23048
23445
|
if (existsSync11(base)) {
|
|
23049
23446
|
try {
|
|
23050
|
-
const real =
|
|
23447
|
+
const real = realpathSync7(base);
|
|
23051
23448
|
const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
|
|
23052
23449
|
if (version)
|
|
23053
23450
|
return version;
|
|
@@ -23111,10 +23508,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
23111
23508
|
}
|
|
23112
23509
|
}
|
|
23113
23510
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
23114
|
-
if (existsSync11(
|
|
23511
|
+
if (existsSync11(join18(ortVersionDir, libName)))
|
|
23115
23512
|
return ortVersionDir;
|
|
23116
|
-
const libSubdir =
|
|
23117
|
-
if (existsSync11(
|
|
23513
|
+
const libSubdir = join18(ortVersionDir, "lib");
|
|
23514
|
+
if (existsSync11(join18(libSubdir, libName)))
|
|
23118
23515
|
return libSubdir;
|
|
23119
23516
|
return ortVersionDir;
|
|
23120
23517
|
}
|
|
@@ -23129,12 +23526,12 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23129
23526
|
} else if (process.platform === "win32") {
|
|
23130
23527
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
23131
23528
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
23132
|
-
searchPaths.push(
|
|
23529
|
+
searchPaths.push(join18(programFiles, "onnxruntime", "lib"), join18(programFiles, "Microsoft ONNX Runtime", "lib"), join18(programFiles, "Microsoft Machine Learning", "lib"), join18(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
23133
23530
|
const nugetPaths = [];
|
|
23134
23531
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
23135
23532
|
if (!userProfile)
|
|
23136
23533
|
return nugetPaths;
|
|
23137
|
-
const nugetPackageDir =
|
|
23534
|
+
const nugetPackageDir = join18(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
23138
23535
|
if (!existsSync11(nugetPackageDir))
|
|
23139
23536
|
return nugetPaths;
|
|
23140
23537
|
try {
|
|
@@ -23143,7 +23540,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23143
23540
|
continue;
|
|
23144
23541
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
23145
23542
|
continue;
|
|
23146
|
-
nugetPaths.push(
|
|
23543
|
+
nugetPaths.push(join18(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join18(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
23147
23544
|
}
|
|
23148
23545
|
} catch (err) {
|
|
23149
23546
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -23155,7 +23552,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23155
23552
|
const normalizeCase = process.platform === "win32" || process.platform === "darwin";
|
|
23156
23553
|
const seen = new Set;
|
|
23157
23554
|
const uniquePaths = searchPaths.filter((p) => {
|
|
23158
|
-
let key =
|
|
23555
|
+
let key = resolve13(p).replace(/[/\\]+$/, "");
|
|
23159
23556
|
if (normalizeCase)
|
|
23160
23557
|
key = key.toLowerCase();
|
|
23161
23558
|
if (seen.has(key))
|
|
@@ -23165,7 +23562,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
|
|
|
23165
23562
|
});
|
|
23166
23563
|
const unknownVersionPaths = [];
|
|
23167
23564
|
for (const dir of uniquePaths) {
|
|
23168
|
-
const libPath =
|
|
23565
|
+
const libPath = join18(dir, libName);
|
|
23169
23566
|
if (process.platform === "win32") {
|
|
23170
23567
|
if (!directoryContainsLibrary(dir, libName))
|
|
23171
23568
|
continue;
|
|
@@ -23212,7 +23609,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
23212
23609
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
23213
23610
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
23214
23611
|
}
|
|
23215
|
-
privateMkdirSync(
|
|
23612
|
+
privateMkdirSync(dirname11(destPath));
|
|
23216
23613
|
let bytesWritten = 0;
|
|
23217
23614
|
const guard = new TransformStream({
|
|
23218
23615
|
transform(chunk, transformController) {
|
|
@@ -23239,16 +23636,16 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
23239
23636
|
}
|
|
23240
23637
|
}
|
|
23241
23638
|
function validateExtractedTree(stagingRoot) {
|
|
23242
|
-
const realRoot =
|
|
23639
|
+
const realRoot = realpathSync7(stagingRoot);
|
|
23243
23640
|
let totalBytes = 0;
|
|
23244
23641
|
const walk = (dir) => {
|
|
23245
23642
|
const entries = readdirSync4(dir);
|
|
23246
23643
|
for (const entry of entries) {
|
|
23247
|
-
const fullPath =
|
|
23644
|
+
const fullPath = join18(dir, entry);
|
|
23248
23645
|
const lst = lstatSync3(fullPath);
|
|
23249
23646
|
if (lst.isSymbolicLink()) {
|
|
23250
23647
|
const linkTarget = readlinkSync2(fullPath);
|
|
23251
|
-
const resolvedTarget =
|
|
23648
|
+
const resolvedTarget = resolve13(dirname11(fullPath), linkTarget);
|
|
23252
23649
|
const rel = relative5(realRoot, resolvedTarget);
|
|
23253
23650
|
if (relativePathEscapesRoot(rel) || win323.isAbsolute(rel)) {
|
|
23254
23651
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -23281,11 +23678,11 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23281
23678
|
const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
|
|
23282
23679
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
23283
23680
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}${randomBytes3(4).toString("hex")}`;
|
|
23284
|
-
const extractionRoot =
|
|
23285
|
-
const stagedInstallDir =
|
|
23681
|
+
const extractionRoot = join18(tmpDir, "extract");
|
|
23682
|
+
const stagedInstallDir = join18(tmpDir, "install");
|
|
23286
23683
|
try {
|
|
23287
23684
|
privateMkdirSync(extractionRoot);
|
|
23288
|
-
const archivePath =
|
|
23685
|
+
const archivePath = join18(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
23289
23686
|
await downloadFileWithCap(url, archivePath);
|
|
23290
23687
|
const archiveSha256 = await sha256File(archivePath);
|
|
23291
23688
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -23298,7 +23695,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23298
23695
|
unlinkSync5(archivePath);
|
|
23299
23696
|
} catch {}
|
|
23300
23697
|
validateExtractedTree(extractionRoot);
|
|
23301
|
-
const extractedDir =
|
|
23698
|
+
const extractedDir = join18(extractionRoot, info.assetName, "lib");
|
|
23302
23699
|
if (!existsSync11(extractedDir)) {
|
|
23303
23700
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
23304
23701
|
}
|
|
@@ -23306,7 +23703,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23306
23703
|
const realFiles = [];
|
|
23307
23704
|
const symlinks = [];
|
|
23308
23705
|
for (const libFile of libFiles) {
|
|
23309
|
-
const src =
|
|
23706
|
+
const src = join18(extractedDir, libFile);
|
|
23310
23707
|
try {
|
|
23311
23708
|
const stat = lstatSync3(src);
|
|
23312
23709
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -23321,14 +23718,14 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
23321
23718
|
}
|
|
23322
23719
|
}
|
|
23323
23720
|
copyOnnxLibraries(info, extractedDir, stagedInstallDir, realFiles, symlinks);
|
|
23324
|
-
const libPath =
|
|
23721
|
+
const libPath = join18(stagedInstallDir, info.libName);
|
|
23325
23722
|
const libHash = await sha256File(libPath);
|
|
23326
23723
|
if (libHash !== info.librarySha256) {
|
|
23327
23724
|
throw new Error(`onnx runtime library hash mismatch at ${libPath}: sha256 ${libHash}, ` + `expected the pinned ${info.librarySha256} for ${info.assetName}`);
|
|
23328
23725
|
}
|
|
23329
23726
|
writeOnnxInstalledMeta(stagedInstallDir, ORT_VERSION, libHash, archiveSha256);
|
|
23330
23727
|
publishOnnxRuntime(stagedInstallDir, targetDir);
|
|
23331
|
-
writeStampedFileDigest(
|
|
23728
|
+
writeStampedFileDigest(join18(targetDir, info.libName), libHash);
|
|
23332
23729
|
rmSync4(tmpDir, { recursive: true, force: true });
|
|
23333
23730
|
log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
|
|
23334
23731
|
return targetDir;
|
|
@@ -23370,8 +23767,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23370
23767
|
const requiredLibs = new Set([info.libName]);
|
|
23371
23768
|
privateMkdirSync(targetDir);
|
|
23372
23769
|
for (const libFile of realFiles) {
|
|
23373
|
-
const src =
|
|
23374
|
-
const dst =
|
|
23770
|
+
const src = join18(extractedDir, libFile);
|
|
23771
|
+
const dst = join18(targetDir, libFile);
|
|
23375
23772
|
try {
|
|
23376
23773
|
if (copyFile === copyFileSync4)
|
|
23377
23774
|
privateCopyFileSync(src, dst);
|
|
@@ -23388,14 +23785,14 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23388
23785
|
log(`ORT extract: failed to copy optional ${libFile}: ${copyErr}`);
|
|
23389
23786
|
}
|
|
23390
23787
|
}
|
|
23391
|
-
const targetRoot =
|
|
23788
|
+
const targetRoot = realpathSync7(targetDir);
|
|
23392
23789
|
for (const link of symlinks) {
|
|
23393
|
-
const dst =
|
|
23790
|
+
const dst = join18(targetDir, link.name);
|
|
23394
23791
|
try {
|
|
23395
23792
|
unlinkSync5(dst);
|
|
23396
23793
|
} catch {}
|
|
23397
|
-
const dstForContainment =
|
|
23398
|
-
const resolvedTarget =
|
|
23794
|
+
const dstForContainment = join18(targetRoot, link.name);
|
|
23795
|
+
const resolvedTarget = resolve13(dirname11(dstForContainment), link.target);
|
|
23399
23796
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
23400
23797
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
23401
23798
|
if (requiredLibs.has(link.name)) {
|
|
@@ -23415,7 +23812,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
23415
23812
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
23416
23813
|
}
|
|
23417
23814
|
}
|
|
23418
|
-
const requiredPath =
|
|
23815
|
+
const requiredPath = join18(targetDir, info.libName);
|
|
23419
23816
|
if (!existsSync11(requiredPath)) {
|
|
23420
23817
|
rmSync4(targetDir, { recursive: true, force: true });
|
|
23421
23818
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
@@ -23443,7 +23840,7 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
23443
23840
|
...sha256 ? { sha256 } : {},
|
|
23444
23841
|
archiveSha256
|
|
23445
23842
|
};
|
|
23446
|
-
writeFileSync6(
|
|
23843
|
+
writeFileSync6(join18(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), {
|
|
23447
23844
|
encoding: "utf8",
|
|
23448
23845
|
mode: PRIVATE_FILE_MODE
|
|
23449
23846
|
});
|
|
@@ -23452,7 +23849,7 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
23452
23849
|
}
|
|
23453
23850
|
}
|
|
23454
23851
|
function readOnnxInstalledMeta(installDir) {
|
|
23455
|
-
const path =
|
|
23852
|
+
const path = join18(installDir, ONNX_INSTALLED_META_FILE);
|
|
23456
23853
|
try {
|
|
23457
23854
|
if (!statSync10(path).isFile())
|
|
23458
23855
|
return null;
|
|
@@ -23473,13 +23870,13 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
23473
23870
|
function acquireLock(lockPath) {
|
|
23474
23871
|
const tryClaim = () => {
|
|
23475
23872
|
try {
|
|
23476
|
-
const fd =
|
|
23873
|
+
const fd = openSync9(lockPath, "wx", PRIVATE_FILE_MODE);
|
|
23477
23874
|
try {
|
|
23478
23875
|
writeFileSync6(fd, `${process.pid}
|
|
23479
23876
|
${new Date().toISOString()}
|
|
23480
23877
|
`);
|
|
23481
23878
|
} finally {
|
|
23482
|
-
|
|
23879
|
+
closeSync10(fd);
|
|
23483
23880
|
}
|
|
23484
23881
|
return true;
|
|
23485
23882
|
} catch (err) {
|
|
@@ -25375,7 +25772,7 @@ import {
|
|
|
25375
25772
|
// package.json
|
|
25376
25773
|
var package_default = {
|
|
25377
25774
|
name: "@cortexkit/aft-pi",
|
|
25378
|
-
version: "0.
|
|
25775
|
+
version: "0.64.0",
|
|
25379
25776
|
type: "module",
|
|
25380
25777
|
description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
|
|
25381
25778
|
main: "dist/index.js",
|
|
@@ -25399,18 +25796,18 @@ var package_default = {
|
|
|
25399
25796
|
"test:e2e": "bun test src/__tests__/e2e/"
|
|
25400
25797
|
},
|
|
25401
25798
|
dependencies: {
|
|
25402
|
-
"@cortexkit/aft-bridge": "0.
|
|
25799
|
+
"@cortexkit/aft-bridge": "0.64.0",
|
|
25403
25800
|
"comment-json": "^5.0.0",
|
|
25404
25801
|
diff: "^8.0.4",
|
|
25405
25802
|
zod: "^4.4.3"
|
|
25406
25803
|
},
|
|
25407
25804
|
optionalDependencies: {
|
|
25408
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
25409
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
25410
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
25411
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
25412
|
-
"@cortexkit/aft-win32-arm64": "0.
|
|
25413
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
25805
|
+
"@cortexkit/aft-darwin-arm64": "0.64.0",
|
|
25806
|
+
"@cortexkit/aft-darwin-x64": "0.64.0",
|
|
25807
|
+
"@cortexkit/aft-linux-arm64": "0.64.0",
|
|
25808
|
+
"@cortexkit/aft-linux-x64": "0.64.0",
|
|
25809
|
+
"@cortexkit/aft-win32-arm64": "0.64.0",
|
|
25810
|
+
"@cortexkit/aft-win32-x64": "0.64.0"
|
|
25414
25811
|
},
|
|
25415
25812
|
devDependencies: {
|
|
25416
25813
|
"@earendil-works/pi-coding-agent": "^0.80.2",
|
|
@@ -25490,22 +25887,15 @@ function readStatusBar(value) {
|
|
|
25490
25887
|
const disabled = Array.isArray(bar.disabled_categories) ? bar.disabled_categories.filter((key) => typeof key === "string") : [];
|
|
25491
25888
|
const errors = readOptionalNumber(bar.errors);
|
|
25492
25889
|
const warnings = readOptionalNumber(bar.warnings);
|
|
25493
|
-
const deadCode = readOptionalNumber(bar.dead_code);
|
|
25494
|
-
const unusedExports = readOptionalNumber(bar.unused_exports);
|
|
25495
|
-
const duplicates = readOptionalNumber(bar.duplicates);
|
|
25496
25890
|
const todos = readOptionalNumber(bar.todos);
|
|
25497
|
-
if (errors === null && warnings === null &&
|
|
25891
|
+
if (errors === null && warnings === null && todos === null && disabled.length === 0) {
|
|
25498
25892
|
return;
|
|
25499
25893
|
}
|
|
25500
25894
|
return {
|
|
25501
25895
|
...disabled.length > 0 ? { disabled_categories: disabled } : {},
|
|
25502
25896
|
...errors !== null ? { errors } : {},
|
|
25503
25897
|
...warnings !== null ? { warnings } : {},
|
|
25504
|
-
...
|
|
25505
|
-
...unusedExports !== null ? { unused_exports: unusedExports } : {},
|
|
25506
|
-
...duplicates !== null ? { duplicates } : {},
|
|
25507
|
-
...todos !== null ? { todos } : {},
|
|
25508
|
-
...bar.tier2_stale === true ? { tier2_stale: true } : {}
|
|
25898
|
+
...todos !== null ? { todos } : {}
|
|
25509
25899
|
};
|
|
25510
25900
|
}
|
|
25511
25901
|
function formatFlag(enabled) {
|
|
@@ -25661,13 +26051,10 @@ function formatStatusDialogMessage(status) {
|
|
|
25661
26051
|
const rows = [
|
|
25662
26052
|
["errors", sb.errors],
|
|
25663
26053
|
["warnings", sb.warnings],
|
|
25664
|
-
["dead code", sb.dead_code],
|
|
25665
|
-
["unused exports", sb.unused_exports],
|
|
25666
|
-
["duplicates", sb.duplicates],
|
|
25667
26054
|
["todos", sb.todos]
|
|
25668
26055
|
].filter((row) => typeof row[1] === "number");
|
|
25669
26056
|
if (rows.length > 0) {
|
|
25670
|
-
lines.push("",
|
|
26057
|
+
lines.push("", "Code Health");
|
|
25671
26058
|
for (const [label, value] of rows)
|
|
25672
26059
|
lines.push(`- ${label}: ${formatCount(value)}`);
|
|
25673
26060
|
}
|
|
@@ -30505,9 +30892,8 @@ function clampBashWatchSyncMaxMs(value) {
|
|
|
30505
30892
|
}
|
|
30506
30893
|
function resolveBashConfig(config) {
|
|
30507
30894
|
const top = config.bash;
|
|
30508
|
-
const
|
|
30509
|
-
const
|
|
30510
|
-
const reminderInterval = (typeof top === "object" && top !== null ? top.long_running_reminder_interval_ms : undefined) ?? legacy?.long_running_reminder_interval_ms;
|
|
30895
|
+
const reminderEnabled = typeof top === "object" && top !== null ? top.long_running_reminder_enabled : undefined;
|
|
30896
|
+
const reminderInterval = typeof top === "object" && top !== null ? top.long_running_reminder_interval_ms : undefined;
|
|
30511
30897
|
const topDetachOnUserMessage = typeof top === "object" && top !== null ? top.detach_on_user_message ?? true : true;
|
|
30512
30898
|
const rawForegroundWait = typeof top === "object" && top !== null ? top.foreground_wait_window_ms : undefined;
|
|
30513
30899
|
const foregroundWaitWindowMs = Math.max(FOREGROUND_WAIT_WINDOW_MIN_MS, rawForegroundWait ?? FOREGROUND_WAIT_WINDOW_DEFAULT_MS);
|
|
@@ -30551,13 +30937,6 @@ function resolveBashConfig(config) {
|
|
|
30551
30937
|
detach_on_user_message: topDetachOnUserMessage
|
|
30552
30938
|
};
|
|
30553
30939
|
}
|
|
30554
|
-
const hasLegacyFeatureFlag = legacy && (legacy.rewrite !== undefined || legacy.compress !== undefined || legacy.background !== undefined);
|
|
30555
|
-
if (hasLegacyFeatureFlag) {
|
|
30556
|
-
const rewrite = legacy.rewrite === true;
|
|
30557
|
-
const compress = legacy.compress === true;
|
|
30558
|
-
const background = legacy.background === true;
|
|
30559
|
-
return { ...base, enabled: true, rewrite, compress, background };
|
|
30560
|
-
}
|
|
30561
30940
|
return { ...base, enabled: true, rewrite: true, compress: true, background: true };
|
|
30562
30941
|
}
|
|
30563
30942
|
var FormatterEnum = _enum([
|
|
@@ -30659,13 +31038,6 @@ var LspConfigSchema = object({
|
|
|
30659
31038
|
versions: record(string2().trim().min(1), string2().trim().min(1)).optional()
|
|
30660
31039
|
});
|
|
30661
31040
|
var ExperimentalConfigSchema = object({
|
|
30662
|
-
bash: object({
|
|
30663
|
-
rewrite: boolean2().optional(),
|
|
30664
|
-
compress: boolean2().optional(),
|
|
30665
|
-
background: boolean2().optional(),
|
|
30666
|
-
long_running_reminder_enabled: boolean2().optional(),
|
|
30667
|
-
long_running_reminder_interval_ms: number2().int().positive().optional()
|
|
30668
|
-
}).optional(),
|
|
30669
31041
|
lsp_ty: boolean2().optional()
|
|
30670
31042
|
});
|
|
30671
31043
|
var BashEnvSchema = record(string2(), string2()).superRefine((env, context) => {
|
|
@@ -30763,7 +31135,6 @@ var PiConfigSchema = object({
|
|
|
30763
31135
|
var InspectConfigSchema = object({
|
|
30764
31136
|
enabled: boolean2().optional(),
|
|
30765
31137
|
diagnostics_timeout_ms: number2().int().positive().optional().transform((value) => value === undefined ? undefined : clampInspectDiagnosticsTimeoutMs(value)),
|
|
30766
|
-
tier2_idle_minutes: number2().min(0).optional(),
|
|
30767
31138
|
tier2_pass_timeout_ms: number2().int().positive().optional(),
|
|
30768
31139
|
categories: object({
|
|
30769
31140
|
diagnostics: boolean2().optional(),
|
|
@@ -30781,11 +31152,16 @@ var InspectConfigSchema = object({
|
|
|
30781
31152
|
function clampIdleRootTtlMinutes(value) {
|
|
30782
31153
|
return Math.min(30, Math.max(5, value));
|
|
30783
31154
|
}
|
|
31155
|
+
function clampIdleCheckoutHours(value) {
|
|
31156
|
+
return Math.min(IDLE_CHECKOUT_HOURS_MAX, Math.max(IDLE_CHECKOUT_HOURS_MIN, value));
|
|
31157
|
+
}
|
|
30784
31158
|
var IdleConfigSchema = object({
|
|
30785
|
-
root_ttl_minutes: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleRootTtlMinutes(value))
|
|
31159
|
+
root_ttl_minutes: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleRootTtlMinutes(value)),
|
|
31160
|
+
checkout_hours: number2().int().optional().transform((value) => value === undefined ? undefined : clampIdleCheckoutHours(value))
|
|
30786
31161
|
});
|
|
30787
31162
|
var ViewsConfigSchema = object({
|
|
30788
|
-
enabled: boolean2().optional()
|
|
31163
|
+
enabled: boolean2().optional(),
|
|
31164
|
+
callgraph_copies: number2().int().optional()
|
|
30789
31165
|
});
|
|
30790
31166
|
var WorktreeConfigSchema = object({
|
|
30791
31167
|
ram_overlay: boolean2().optional()
|
|
@@ -30863,6 +31239,11 @@ function applyActiveHarnessOverride(config, trusted) {
|
|
|
30863
31239
|
delete merged.indexes;
|
|
30864
31240
|
else
|
|
30865
31241
|
merged.indexes = indexes;
|
|
31242
|
+
const idle = mergeIdleConfig(base.idle, override.idle);
|
|
31243
|
+
if (idle === undefined)
|
|
31244
|
+
delete merged.idle;
|
|
31245
|
+
else
|
|
31246
|
+
merged.idle = idle;
|
|
30866
31247
|
merged.sandbox = mergeSandboxConfig(base.sandbox, override.sandbox, true);
|
|
30867
31248
|
if (!trusted && override.sandbox?.write_allow !== undefined) {
|
|
30868
31249
|
merged.sandbox = { ...merged.sandbox, write_allow: override.sandbox.write_allow };
|
|
@@ -30965,7 +31346,7 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
30965
31346
|
recordConfigParseFailure(configPath, errorMsg);
|
|
30966
31347
|
throw new ConfigRejectedError(["invalid_config_document"], configPath);
|
|
30967
31348
|
}
|
|
30968
|
-
const removed = removedConfigKeyErrors(cleanConfig);
|
|
31349
|
+
const removed = removedConfigKeyErrors(cleanConfig, undefined, false);
|
|
30969
31350
|
if (removed.length) {
|
|
30970
31351
|
throw new ConfigRejectedError(removed);
|
|
30971
31352
|
}
|
|
@@ -30988,9 +31369,18 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
30988
31369
|
warn2(text);
|
|
30989
31370
|
}
|
|
30990
31371
|
}
|
|
30991
|
-
if (
|
|
30992
|
-
|
|
30993
|
-
|
|
31372
|
+
if (tier === "user") {
|
|
31373
|
+
if (translation.legacyInput) {
|
|
31374
|
+
log2(`Config ${configPath} uses retired keys (${translation.retiredKeys.join(", ")}); applied their current equivalents in memory`);
|
|
31375
|
+
}
|
|
31376
|
+
if (translation.removedKeys.length > 0) {
|
|
31377
|
+
configLoadNotices.push({
|
|
31378
|
+
configPath,
|
|
31379
|
+
digest: removedConfigKeysNoticeDigest(translation),
|
|
31380
|
+
message: removedConfigKeysNoticeMessage(configPath, translation)
|
|
31381
|
+
});
|
|
31382
|
+
}
|
|
31383
|
+
} else if (translation.legacyInput || translation.removedKeys.length > 0) {
|
|
30994
31384
|
configLoadNotices.push({
|
|
30995
31385
|
configPath,
|
|
30996
31386
|
digest: noticeDigest(projection),
|
|
@@ -31104,6 +31494,13 @@ function mergeWorktreeConfig(baseWorktree, overrideWorktree) {
|
|
|
31104
31494
|
return overrideWorktree;
|
|
31105
31495
|
return { ...baseWorktree, ...overrideWorktree };
|
|
31106
31496
|
}
|
|
31497
|
+
function mergeIdleConfig(baseIdle, overrideIdle) {
|
|
31498
|
+
const merged = {
|
|
31499
|
+
root_ttl_minutes: overrideIdle?.root_ttl_minutes ?? baseIdle?.root_ttl_minutes,
|
|
31500
|
+
checkout_hours: overrideIdle?.checkout_hours ?? baseIdle?.checkout_hours
|
|
31501
|
+
};
|
|
31502
|
+
return merged.root_ttl_minutes === undefined && merged.checkout_hours === undefined ? undefined : merged;
|
|
31503
|
+
}
|
|
31107
31504
|
function mergeInspectConfig(baseInspect, overrideInspect) {
|
|
31108
31505
|
const diagnosticsTimeoutConfigured = baseInspect?.diagnostics_timeout_ms !== undefined || overrideInspect?.diagnostics_timeout_ms !== undefined;
|
|
31109
31506
|
const diagnosticsTimeoutMs = Math.max(clampInspectDiagnosticsTimeoutMs(baseInspect?.diagnostics_timeout_ms ?? DEFAULT_INSPECT_DIAGNOSTICS_TIMEOUT_MS), clampInspectDiagnosticsTimeoutMs(overrideInspect?.diagnostics_timeout_ms ?? DEFAULT_INSPECT_DIAGNOSTICS_TIMEOUT_MS));
|
|
@@ -31182,19 +31579,10 @@ function mergeBashConfig(baseBash, overrideBash, mode = "tier") {
|
|
|
31182
31579
|
return merged;
|
|
31183
31580
|
}
|
|
31184
31581
|
function mergeExperimentalConfig(base, override) {
|
|
31185
|
-
const bash = {
|
|
31186
|
-
...base?.bash,
|
|
31187
|
-
...override?.bash
|
|
31188
|
-
};
|
|
31189
31582
|
const experimental = {
|
|
31190
31583
|
...base,
|
|
31191
31584
|
...override
|
|
31192
31585
|
};
|
|
31193
|
-
if (Object.values(bash).some((value) => value !== undefined)) {
|
|
31194
|
-
experimental.bash = bash;
|
|
31195
|
-
} else {
|
|
31196
|
-
delete experimental.bash;
|
|
31197
|
-
}
|
|
31198
31586
|
if (Object.values(experimental).every((value) => value === undefined))
|
|
31199
31587
|
return;
|
|
31200
31588
|
return Object.fromEntries(Object.entries(experimental).filter(([, value]) => value !== undefined));
|
|
@@ -31341,17 +31729,21 @@ function mergeConfigs(base, override) {
|
|
|
31341
31729
|
}
|
|
31342
31730
|
const inspect = mergeInspectConfig(base.inspect, override.inspect);
|
|
31343
31731
|
const worktree = mergeWorktreeConfig(base.worktree, override.worktree);
|
|
31732
|
+
const idle = mergeIdleConfig(base.idle, override.idle);
|
|
31344
31733
|
const sandbox = mergeSandboxConfig(base.sandbox, override.sandbox);
|
|
31345
31734
|
const remoteExec = mergeRemoteExecConfig(base.remote_exec, override.remote_exec);
|
|
31346
31735
|
const backup = mergeProjectBackupConfig(base.backup, override.backup);
|
|
31347
31736
|
const pi = mergePiConfig(base.pi, override.pi);
|
|
31737
|
+
const views = base.views !== undefined || override.views !== undefined ? { ...base.views, ...override.views } : undefined;
|
|
31348
31738
|
const bridge = base.bridge;
|
|
31349
31739
|
const safeOverride = pickProjectSafeFields(override);
|
|
31350
31740
|
delete safeOverride.indexes;
|
|
31351
31741
|
delete safeOverride.bash;
|
|
31352
31742
|
delete safeOverride.inspect;
|
|
31353
31743
|
delete safeOverride.worktree;
|
|
31744
|
+
delete safeOverride.idle;
|
|
31354
31745
|
delete safeOverride.pi;
|
|
31746
|
+
delete safeOverride.views;
|
|
31355
31747
|
return {
|
|
31356
31748
|
...base,
|
|
31357
31749
|
...safeOverride,
|
|
@@ -31361,10 +31753,12 @@ function mergeConfigs(base, override) {
|
|
|
31361
31753
|
...bash !== undefined ? { bash } : {},
|
|
31362
31754
|
...inspect !== undefined ? { inspect } : {},
|
|
31363
31755
|
...worktree !== undefined ? { worktree } : {},
|
|
31756
|
+
...idle !== undefined ? { idle } : {},
|
|
31364
31757
|
...sandbox !== undefined ? { sandbox } : {},
|
|
31365
31758
|
...remoteExec !== undefined ? { remote_exec: remoteExec } : {},
|
|
31366
31759
|
...backup !== undefined ? { backup } : {},
|
|
31367
31760
|
...pi !== undefined ? { pi } : {},
|
|
31761
|
+
...views !== undefined ? { views } : {},
|
|
31368
31762
|
experimental,
|
|
31369
31763
|
semantic,
|
|
31370
31764
|
search,
|
|
@@ -31680,9 +32074,9 @@ function detectPiHarness(api) {
|
|
|
31680
32074
|
}
|
|
31681
32075
|
|
|
31682
32076
|
// src/omp-approval.ts
|
|
31683
|
-
import { realpathSync as
|
|
32077
|
+
import { realpathSync as realpathSync8 } from "node:fs";
|
|
31684
32078
|
import { homedir as homedir15 } from "node:os";
|
|
31685
|
-
import { basename as basename4, dirname as
|
|
32079
|
+
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute10, join as join19, relative as relative6, resolve as resolve14, sep as sep2 } from "node:path";
|
|
31686
32080
|
var OMP_TOOL_TIERS = {
|
|
31687
32081
|
read: "read",
|
|
31688
32082
|
grep: "read",
|
|
@@ -31727,7 +32121,7 @@ function expandPath(value) {
|
|
|
31727
32121
|
if (decoded === "~")
|
|
31728
32122
|
return homedir15();
|
|
31729
32123
|
if (decoded.startsWith("~/") || decoded.startsWith(`~${sep2}`))
|
|
31730
|
-
return
|
|
32124
|
+
return resolve14(homedir15(), decoded.slice(2));
|
|
31731
32125
|
return decoded;
|
|
31732
32126
|
}
|
|
31733
32127
|
function realLocation(path) {
|
|
@@ -31735,12 +32129,12 @@ function realLocation(path) {
|
|
|
31735
32129
|
let current = path;
|
|
31736
32130
|
for (;; ) {
|
|
31737
32131
|
try {
|
|
31738
|
-
return missing.length > 0 ?
|
|
32132
|
+
return missing.length > 0 ? join19(realpathSync8(current), ...missing) : realpathSync8(current);
|
|
31739
32133
|
} catch (error) {
|
|
31740
32134
|
if (error.code !== "ENOENT")
|
|
31741
32135
|
throw error;
|
|
31742
32136
|
}
|
|
31743
|
-
const parent =
|
|
32137
|
+
const parent = dirname12(current);
|
|
31744
32138
|
if (parent === current)
|
|
31745
32139
|
return path;
|
|
31746
32140
|
missing.unshift(basename4(current));
|
|
@@ -31755,7 +32149,7 @@ function namesOutsidePath(root, value) {
|
|
|
31755
32149
|
const expanded = expandPath(value);
|
|
31756
32150
|
if (expanded.startsWith("file:"))
|
|
31757
32151
|
return false;
|
|
31758
|
-
const absolute = isAbsolute10(expanded) ? expanded :
|
|
32152
|
+
const absolute = isAbsolute10(expanded) ? expanded : resolve14(root, expanded);
|
|
31759
32153
|
if (relativePathEscapesRoot(relative6(root, absolute)))
|
|
31760
32154
|
return true;
|
|
31761
32155
|
try {
|
|
@@ -31791,11 +32185,10 @@ function unquote(value) {
|
|
|
31791
32185
|
const first = value[0];
|
|
31792
32186
|
return value.length >= 2 && (first === '"' || first === "'") && value.endsWith(first) ? value.slice(1, -1) : value;
|
|
31793
32187
|
}
|
|
31794
|
-
function
|
|
32188
|
+
function hashlinePatchSections(patch) {
|
|
31795
32189
|
if (patch.trim().length === 0)
|
|
31796
32190
|
return;
|
|
31797
|
-
const
|
|
31798
|
-
let sections = 0;
|
|
32191
|
+
const sections = [];
|
|
31799
32192
|
const rows = patch.split(`
|
|
31800
32193
|
`);
|
|
31801
32194
|
for (let index = 0;index < rows.length; index++) {
|
|
@@ -31811,28 +32204,31 @@ function hashlinePatchPaths(patch) {
|
|
|
31811
32204
|
const hash = inner.indexOf("#");
|
|
31812
32205
|
if (hash <= 0)
|
|
31813
32206
|
return;
|
|
31814
|
-
|
|
31815
|
-
sections++;
|
|
32207
|
+
sections.push({ path: inner.slice(0, hash), moves: [] });
|
|
31816
32208
|
continue;
|
|
31817
32209
|
}
|
|
31818
32210
|
const directive = /^(PUT|CUT|REM|MV)(?:\s|$)/.exec(line);
|
|
31819
32211
|
if (directive) {
|
|
31820
|
-
|
|
32212
|
+
const current = sections[sections.length - 1];
|
|
32213
|
+
if (current === undefined)
|
|
31821
32214
|
return;
|
|
31822
32215
|
if (directive[1] === "MV") {
|
|
31823
32216
|
const destination = line.slice(2).trim();
|
|
31824
32217
|
if (destination.length === 0 || /\s/.test(destination))
|
|
31825
32218
|
return;
|
|
31826
|
-
|
|
32219
|
+
current.moves.push(unquote(destination));
|
|
31827
32220
|
}
|
|
31828
32221
|
continue;
|
|
31829
32222
|
}
|
|
31830
|
-
if (trimmed.length === 0 && sections === 0)
|
|
32223
|
+
if (trimmed.length === 0 && sections.length === 0)
|
|
31831
32224
|
continue;
|
|
31832
|
-
if (sections === 0 || !line.startsWith("+"))
|
|
32225
|
+
if (sections.length === 0 || !line.startsWith("+"))
|
|
31833
32226
|
return;
|
|
31834
32227
|
}
|
|
31835
|
-
return sections > 0 ?
|
|
32228
|
+
return sections.length > 0 ? sections : undefined;
|
|
32229
|
+
}
|
|
32230
|
+
function hashlinePatchPaths(patch) {
|
|
32231
|
+
return hashlinePatchSections(patch)?.flatMap((section) => [section.path, ...section.moves]);
|
|
31836
32232
|
}
|
|
31837
32233
|
var APPLY_PATCH_TARGETS = [
|
|
31838
32234
|
"*** Add File:",
|
|
@@ -32492,14 +32888,14 @@ function registerStatusCommand(pi, ctx) {
|
|
|
32492
32888
|
|
|
32493
32889
|
// src/lsp-auto-install.ts
|
|
32494
32890
|
import { existsSync as existsSync15, mkdirSync as mkdirSync7, renameSync as renameSync10, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
32495
|
-
import { join as
|
|
32891
|
+
import { join as join22 } from "node:path";
|
|
32496
32892
|
|
|
32497
32893
|
// src/lsp-cache.ts
|
|
32498
32894
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
32499
32895
|
import {
|
|
32500
|
-
closeSync as
|
|
32896
|
+
closeSync as closeSync11,
|
|
32501
32897
|
mkdirSync as mkdirSync6,
|
|
32502
|
-
openSync as
|
|
32898
|
+
openSync as openSync10,
|
|
32503
32899
|
readFileSync as readFileSync12,
|
|
32504
32900
|
renameSync as renameSync9,
|
|
32505
32901
|
rmSync as rmSync6,
|
|
@@ -32507,7 +32903,7 @@ import {
|
|
|
32507
32903
|
unlinkSync as unlinkSync6,
|
|
32508
32904
|
writeFileSync as writeFileSync8
|
|
32509
32905
|
} from "node:fs";
|
|
32510
|
-
import { join as
|
|
32906
|
+
import { join as join20 } from "node:path";
|
|
32511
32907
|
|
|
32512
32908
|
// src/atomic-file.ts
|
|
32513
32909
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -32530,18 +32926,18 @@ function lspCacheRoot() {
|
|
|
32530
32926
|
return getAftLspPackagesDir();
|
|
32531
32927
|
}
|
|
32532
32928
|
function lspPackageDir(npmPackage) {
|
|
32533
|
-
return
|
|
32929
|
+
return join20(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
32534
32930
|
}
|
|
32535
32931
|
function lspBinaryPath(npmPackage, binary) {
|
|
32536
|
-
return
|
|
32932
|
+
return join20(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
32537
32933
|
}
|
|
32538
32934
|
function lspBinDir(npmPackage) {
|
|
32539
|
-
return
|
|
32935
|
+
return join20(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
32540
32936
|
}
|
|
32541
32937
|
function isInstalled(npmPackage, binary) {
|
|
32542
32938
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
32543
32939
|
try {
|
|
32544
|
-
if (statSync11(
|
|
32940
|
+
if (statSync11(join20(lspBinDir(npmPackage), candidate)).isFile())
|
|
32545
32941
|
return true;
|
|
32546
32942
|
} catch {}
|
|
32547
32943
|
}
|
|
@@ -32561,13 +32957,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
|
|
|
32561
32957
|
installedAt: new Date().toISOString(),
|
|
32562
32958
|
...sha256 ? { sha256 } : {}
|
|
32563
32959
|
};
|
|
32564
|
-
writeAtomicFile(
|
|
32960
|
+
writeAtomicFile(join20(installDir, INSTALLED_META_FILE), JSON.stringify(meta));
|
|
32565
32961
|
} catch (err) {
|
|
32566
32962
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
32567
32963
|
}
|
|
32568
32964
|
}
|
|
32569
32965
|
function readInstalledMetaIn(installDir) {
|
|
32570
|
-
const path =
|
|
32966
|
+
const path = join20(installDir, INSTALLED_META_FILE);
|
|
32571
32967
|
try {
|
|
32572
32968
|
if (!statSync11(path).isFile())
|
|
32573
32969
|
return null;
|
|
@@ -32591,7 +32987,7 @@ function readInstalledMeta(packageKey) {
|
|
|
32591
32987
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
32592
32988
|
}
|
|
32593
32989
|
function lockPath(npmPackage) {
|
|
32594
|
-
return
|
|
32990
|
+
return join20(lspPackageDir(npmPackage), ".aft-installing");
|
|
32595
32991
|
}
|
|
32596
32992
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
32597
32993
|
function acquireInstallLock(lockKey) {
|
|
@@ -32600,14 +32996,14 @@ function acquireInstallLock(lockKey) {
|
|
|
32600
32996
|
const token = randomUUID3();
|
|
32601
32997
|
const tryClaim = () => {
|
|
32602
32998
|
try {
|
|
32603
|
-
const fd =
|
|
32999
|
+
const fd = openSync10(lock, "wx");
|
|
32604
33000
|
try {
|
|
32605
33001
|
writeFileSync8(fd, `${process.pid}
|
|
32606
33002
|
${new Date().toISOString()}
|
|
32607
33003
|
${token}
|
|
32608
33004
|
`);
|
|
32609
33005
|
} finally {
|
|
32610
|
-
|
|
33006
|
+
closeSync11(fd);
|
|
32611
33007
|
}
|
|
32612
33008
|
let retained = false;
|
|
32613
33009
|
let released = false;
|
|
@@ -32722,7 +33118,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
|
|
|
32722
33118
|
var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
|
|
32723
33119
|
var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
|
|
32724
33120
|
function autoInstallStampPath() {
|
|
32725
|
-
return
|
|
33121
|
+
return join20(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
|
|
32726
33122
|
}
|
|
32727
33123
|
function hasRecentAutoInstallStamp(path) {
|
|
32728
33124
|
try {
|
|
@@ -32770,11 +33166,11 @@ function claimLspAutoInstallPass() {
|
|
|
32770
33166
|
};
|
|
32771
33167
|
const tryClaim = () => {
|
|
32772
33168
|
try {
|
|
32773
|
-
const fd =
|
|
33169
|
+
const fd = openSync10(lock, "wx");
|
|
32774
33170
|
try {
|
|
32775
33171
|
writeFileSync8(fd, JSON.stringify(owner));
|
|
32776
33172
|
} finally {
|
|
32777
|
-
|
|
33173
|
+
closeSync11(fd);
|
|
32778
33174
|
}
|
|
32779
33175
|
return true;
|
|
32780
33176
|
} catch (err) {
|
|
@@ -32823,7 +33219,7 @@ function claimLspAutoInstallPass() {
|
|
|
32823
33219
|
}
|
|
32824
33220
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
32825
33221
|
function readVersionCheck(npmPackage) {
|
|
32826
|
-
const file =
|
|
33222
|
+
const file = join20(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
32827
33223
|
try {
|
|
32828
33224
|
const raw = readFileSync12(file, "utf8");
|
|
32829
33225
|
const parsed = JSON.parse(raw);
|
|
@@ -32840,7 +33236,7 @@ function readVersionCheck(npmPackage) {
|
|
|
32840
33236
|
}
|
|
32841
33237
|
function writeVersionCheck(npmPackage, latest) {
|
|
32842
33238
|
mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
|
|
32843
|
-
const file =
|
|
33239
|
+
const file = join20(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
32844
33240
|
const record = {
|
|
32845
33241
|
last_checked: new Date().toISOString(),
|
|
32846
33242
|
latest_eligible: latest
|
|
@@ -32957,7 +33353,7 @@ function isVersionSupported(spec, version) {
|
|
|
32957
33353
|
|
|
32958
33354
|
// src/lsp-project-relevance.ts
|
|
32959
33355
|
import { existsSync as existsSync14, readdirSync as readdirSync5, readFileSync as readFileSync13 } from "node:fs";
|
|
32960
|
-
import { join as
|
|
33356
|
+
import { join as join21 } from "node:path";
|
|
32961
33357
|
var MAX_WALK_DIRS = 200;
|
|
32962
33358
|
var MAX_WALK_DEPTH = 4;
|
|
32963
33359
|
var NOISE_DIRS = new Set([
|
|
@@ -32974,7 +33370,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
32974
33370
|
if (!rootMarkers)
|
|
32975
33371
|
return false;
|
|
32976
33372
|
for (const marker of rootMarkers) {
|
|
32977
|
-
if (existsSync14(
|
|
33373
|
+
if (existsSync14(join21(projectRoot, marker)))
|
|
32978
33374
|
return true;
|
|
32979
33375
|
}
|
|
32980
33376
|
return false;
|
|
@@ -32998,7 +33394,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
32998
33394
|
}
|
|
32999
33395
|
function readPackageJson(projectRoot) {
|
|
33000
33396
|
try {
|
|
33001
|
-
const raw = readFileSync13(
|
|
33397
|
+
const raw = readFileSync13(join21(projectRoot, "package.json"), "utf8");
|
|
33002
33398
|
const parsed = JSON.parse(raw);
|
|
33003
33399
|
if (typeof parsed !== "object" || parsed === null)
|
|
33004
33400
|
return null;
|
|
@@ -33028,7 +33424,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
33028
33424
|
for (const entry of entries) {
|
|
33029
33425
|
if (entry.isDirectory()) {
|
|
33030
33426
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
33031
|
-
queue.push({ dir:
|
|
33427
|
+
queue.push({ dir: join21(current.dir, entry.name), depth: current.depth + 1 });
|
|
33032
33428
|
}
|
|
33033
33429
|
continue;
|
|
33034
33430
|
}
|
|
@@ -33161,7 +33557,7 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
|
|
|
33161
33557
|
}
|
|
33162
33558
|
function ensureInstallAnchor(cwd) {
|
|
33163
33559
|
try {
|
|
33164
|
-
const stub =
|
|
33560
|
+
const stub = join22(cwd, "package.json");
|
|
33165
33561
|
if (!existsSync15(stub)) {
|
|
33166
33562
|
writeFileSync9(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
33167
33563
|
`);
|
|
@@ -33178,18 +33574,26 @@ async function runInstall(spec, version, cwd, installLock, before, signal, deadl
|
|
|
33178
33574
|
warn2(`[lsp] install ${target} aborted before spawn`);
|
|
33179
33575
|
return false;
|
|
33180
33576
|
}
|
|
33181
|
-
const
|
|
33182
|
-
if (!
|
|
33577
|
+
const preferredNpm = resolveNpm();
|
|
33578
|
+
if (!preferredNpm) {
|
|
33183
33579
|
warn2(`[lsp] npm not found on PATH or known locations; cannot install ${target}`);
|
|
33184
33580
|
return false;
|
|
33185
33581
|
}
|
|
33582
|
+
const selected = await selectLspNpm(preferredNpm, undefined, signal);
|
|
33583
|
+
if (signal?.aborted)
|
|
33584
|
+
return false;
|
|
33585
|
+
if (!selected.npm) {
|
|
33586
|
+
warn2(`[lsp] ${selected.refusal}`);
|
|
33587
|
+
return false;
|
|
33588
|
+
}
|
|
33589
|
+
const npm = selected.npm;
|
|
33186
33590
|
const invocation = await lspNpmInstallInvocation(npm, target, before);
|
|
33187
33591
|
if (signal?.aborted) {
|
|
33188
33592
|
warn2(`[lsp] install ${target} aborted during npm capability probe`);
|
|
33189
33593
|
return false;
|
|
33190
33594
|
}
|
|
33191
33595
|
if (!invocation) {
|
|
33192
|
-
warn2(`[lsp] npm cannot
|
|
33596
|
+
warn2(`[lsp] ${lspNpmRefusal(npm.command, "probe failed: cannot verify publication-cutoff support")}`);
|
|
33193
33597
|
return false;
|
|
33194
33598
|
}
|
|
33195
33599
|
ensureInstallAnchor(cwd);
|
|
@@ -33271,6 +33675,9 @@ async function runInstall(spec, version, cwd, installLock, before, signal, deadl
|
|
|
33271
33675
|
log2(`[lsp] installed ${target}`);
|
|
33272
33676
|
finish(true);
|
|
33273
33677
|
} else {
|
|
33678
|
+
const rejectedOption = /--(?:no-save|before|ignore-scripts)\b/.exec(stderrBuf)?.[0];
|
|
33679
|
+
if (rejectedOption)
|
|
33680
|
+
warn2(`[lsp] ${lspNpmRefusal(npm.command, `rejected option: ${rejectedOption}`)}`);
|
|
33274
33681
|
error2(`[lsp] install ${target} exited with code ${code}; last stderr:
|
|
33275
33682
|
${stderrBuf.trim()}`);
|
|
33276
33683
|
finish(false);
|
|
@@ -33377,10 +33784,10 @@ function sha256OfFileSync(path) {
|
|
|
33377
33784
|
}
|
|
33378
33785
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
33379
33786
|
const packageDir = lspPackageDir(spec.npm);
|
|
33380
|
-
const dest =
|
|
33787
|
+
const dest = join22(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
33381
33788
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
33382
33789
|
try {
|
|
33383
|
-
mkdirSync7(
|
|
33790
|
+
mkdirSync7(join22(dest, ".."), { recursive: true });
|
|
33384
33791
|
rmSync7(dest, { recursive: true, force: true });
|
|
33385
33792
|
renameSync10(packageDir, dest);
|
|
33386
33793
|
} catch (err) {
|
|
@@ -34113,9 +34520,9 @@ import { StringEnum } from "@earendil-works/pi-ai";
|
|
|
34113
34520
|
import { Type as Type4 } from "typebox";
|
|
34114
34521
|
|
|
34115
34522
|
// src/tools/hoisted.ts
|
|
34116
|
-
import { stat as
|
|
34523
|
+
import { stat as stat4 } from "node:fs/promises";
|
|
34117
34524
|
import { homedir as homedir16 } from "node:os";
|
|
34118
|
-
import { isAbsolute as isAbsolute11, relative as relative7, resolve as
|
|
34525
|
+
import { isAbsolute as isAbsolute11, relative as relative7, resolve as resolve15, sep as sep3 } from "node:path";
|
|
34119
34526
|
import {
|
|
34120
34527
|
renderDiff as renderDiff2
|
|
34121
34528
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -34303,17 +34710,17 @@ function normalizePathInput(path) {
|
|
|
34303
34710
|
if (decoded === "~")
|
|
34304
34711
|
return homedir16();
|
|
34305
34712
|
if (decoded.startsWith(`~${sep3}`) || decoded.startsWith("~/")) {
|
|
34306
|
-
return
|
|
34713
|
+
return resolve15(homedir16(), decoded.slice(2));
|
|
34307
34714
|
}
|
|
34308
34715
|
return decoded;
|
|
34309
34716
|
}
|
|
34310
34717
|
function absoluteSearchPath(cwd, target) {
|
|
34311
34718
|
const expanded = normalizePathInput(target);
|
|
34312
|
-
return isAbsolute11(expanded) ? expanded :
|
|
34719
|
+
return isAbsolute11(expanded) ? expanded : resolve15(cwd, expanded);
|
|
34313
34720
|
}
|
|
34314
34721
|
async function searchPathExists(cwd, target) {
|
|
34315
34722
|
try {
|
|
34316
|
-
await
|
|
34723
|
+
await stat4(absoluteSearchPath(cwd, target));
|
|
34317
34724
|
return true;
|
|
34318
34725
|
} catch {
|
|
34319
34726
|
return false;
|
|
@@ -34365,7 +34772,7 @@ async function assertExternalDirectoryPermission(extCtx, target, options = {}) {
|
|
|
34365
34772
|
if (!target)
|
|
34366
34773
|
return;
|
|
34367
34774
|
const expanded = normalizePathInput(target);
|
|
34368
|
-
const absoluteTarget = isAbsolute11(expanded) ? expanded :
|
|
34775
|
+
const absoluteTarget = isAbsolute11(expanded) ? expanded : resolve15(extCtx.cwd, expanded);
|
|
34369
34776
|
if (containsPath(extCtx.cwd, absoluteTarget))
|
|
34370
34777
|
return;
|
|
34371
34778
|
if (options.restrictToProjectRoot === false)
|
|
@@ -34374,7 +34781,7 @@ async function assertExternalDirectoryPermission(extCtx, target, options = {}) {
|
|
|
34374
34781
|
}
|
|
34375
34782
|
async function assertExternalReadPermission(ctx, extCtx, target, restrictToProjectRoot = ctx.config.restrict_to_project_root ?? false) {
|
|
34376
34783
|
const expanded = normalizePathInput(target);
|
|
34377
|
-
const absoluteTarget = isAbsolute11(expanded) ? expanded :
|
|
34784
|
+
const absoluteTarget = isAbsolute11(expanded) ? expanded : resolve15(extCtx.cwd, expanded);
|
|
34378
34785
|
if (!restrictToProjectRoot || containsPath(extCtx.cwd, absoluteTarget))
|
|
34379
34786
|
return;
|
|
34380
34787
|
try {
|
|
@@ -34707,7 +35114,13 @@ PDFs aren't supported on the Pi harness yet.`, response);
|
|
|
34707
35114
|
const response = await callToolCallForSession(bridge, "edit", rawArgs, sessionId, extCtx);
|
|
34708
35115
|
if (response.success === false)
|
|
34709
35116
|
throw toolErrorFromResponse("edit", response);
|
|
34710
|
-
return
|
|
35117
|
+
return buildHashlineMutationResult(response);
|
|
35118
|
+
},
|
|
35119
|
+
renderCall(args, theme, context) {
|
|
35120
|
+
return renderHashlineEditCall(args, theme, context);
|
|
35121
|
+
},
|
|
35122
|
+
renderResult(result, options = { expanded: false, isPartial: false }, theme, context) {
|
|
35123
|
+
return renderMutationResult(result, theme, context, options);
|
|
34711
35124
|
}
|
|
34712
35125
|
});
|
|
34713
35126
|
}
|
|
@@ -34883,6 +35296,71 @@ ${formatDiagnosticsText(diagnostics)}`;
|
|
|
34883
35296
|
}
|
|
34884
35297
|
};
|
|
34885
35298
|
}
|
|
35299
|
+
function buildHashlineMutationResult(response) {
|
|
35300
|
+
const result = buildMutationResult(response);
|
|
35301
|
+
const rows = asRecords2(asRecord3(response.metadata)?.files);
|
|
35302
|
+
const files = rows.map(hashlineFileDetails);
|
|
35303
|
+
if (files.length === 0)
|
|
35304
|
+
return result;
|
|
35305
|
+
const changed = files.filter((file) => file.diff !== undefined);
|
|
35306
|
+
const diff = changed.length === 0 ? undefined : files.length === 1 ? files[0]?.diff : files.map((file) => file.diff === undefined ? mutationFileHeader(file) : `${mutationFileHeader(file)}
|
|
35307
|
+
${file.diff}`).join(`
|
|
35308
|
+
`);
|
|
35309
|
+
const firstChangedLine = rows.map((row) => firstChangedLineOfPatch(asString2(row.patch) ?? "")).find((line) => line !== undefined);
|
|
35310
|
+
return {
|
|
35311
|
+
...result,
|
|
35312
|
+
details: {
|
|
35313
|
+
...result.details,
|
|
35314
|
+
diff,
|
|
35315
|
+
firstChangedLine,
|
|
35316
|
+
additions: files.reduce((sum, file) => sum + file.additions, 0),
|
|
35317
|
+
deletions: files.reduce((sum, file) => sum + file.deletions, 0),
|
|
35318
|
+
files
|
|
35319
|
+
}
|
|
35320
|
+
};
|
|
35321
|
+
}
|
|
35322
|
+
function hashlineFileDetails(row) {
|
|
35323
|
+
const patch = asString2(row.patch) ?? "";
|
|
35324
|
+
const diff = formatUnifiedDiffForPi(patch);
|
|
35325
|
+
return {
|
|
35326
|
+
path: asString2(row.relativePath) ?? "",
|
|
35327
|
+
sourcePath: asString2(row.sourcePath) ?? asString2(row.movePath),
|
|
35328
|
+
diff: diff.length > 0 ? diff : undefined,
|
|
35329
|
+
additions: asNumber2(row.additions) ?? 0,
|
|
35330
|
+
deletions: asNumber2(row.deletions) ?? 0
|
|
35331
|
+
};
|
|
35332
|
+
}
|
|
35333
|
+
function firstChangedLineOfPatch(patch) {
|
|
35334
|
+
let newLine;
|
|
35335
|
+
for (const line of patch.split(`
|
|
35336
|
+
`)) {
|
|
35337
|
+
const hunk = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(line);
|
|
35338
|
+
if (hunk) {
|
|
35339
|
+
newLine = Number(hunk[1]);
|
|
35340
|
+
continue;
|
|
35341
|
+
}
|
|
35342
|
+
if (newLine === undefined)
|
|
35343
|
+
continue;
|
|
35344
|
+
if (line.startsWith("+") || line.startsWith("-"))
|
|
35345
|
+
return Math.max(1, newLine);
|
|
35346
|
+
if (line.startsWith(" "))
|
|
35347
|
+
newLine++;
|
|
35348
|
+
}
|
|
35349
|
+
return;
|
|
35350
|
+
}
|
|
35351
|
+
function mutationFileName(file) {
|
|
35352
|
+
return file.sourcePath ? `${shortenHomePath(file.sourcePath)} → ${shortenHomePath(file.path)}` : shortenHomePath(file.path);
|
|
35353
|
+
}
|
|
35354
|
+
function mutationFileHeader(file) {
|
|
35355
|
+
return `${mutationFileName(file)} (+${file.additions}/-${file.deletions})`;
|
|
35356
|
+
}
|
|
35357
|
+
function mutationFilesLabel(files) {
|
|
35358
|
+
const first = files?.[0];
|
|
35359
|
+
if (!first || !files)
|
|
35360
|
+
return;
|
|
35361
|
+
const name = mutationFileName(first);
|
|
35362
|
+
return files.length > 1 ? `${name} and ${files.length - 1} more` : name;
|
|
35363
|
+
}
|
|
34886
35364
|
function formatGlobSkipReasonsNote(reasons) {
|
|
34887
35365
|
if (!Array.isArray(reasons))
|
|
34888
35366
|
return;
|
|
@@ -34934,6 +35412,29 @@ function renderMutationCall(toolName, filePath, theme, context) {
|
|
|
34934
35412
|
text.setText(`${theme.fg("toolTitle", theme.bold(toolName))} ${pathDisplay}`);
|
|
34935
35413
|
return text;
|
|
34936
35414
|
}
|
|
35415
|
+
function renderHashlineEditCall(args, theme, context) {
|
|
35416
|
+
const text = reuseText2(context.lastComponent);
|
|
35417
|
+
const target = hashlinePatchTarget(asString2(asRecord3(args)?.patch));
|
|
35418
|
+
const targetDisplay = target ? `${theme.fg("accent", target.name)}${target.more > 0 ? theme.fg("muted", ` and ${target.more} more`) : ""}` : theme.fg("toolOutput", "...");
|
|
35419
|
+
text.setText(`${theme.fg("toolTitle", theme.bold("edit"))} ${targetDisplay}`);
|
|
35420
|
+
return text;
|
|
35421
|
+
}
|
|
35422
|
+
function hashlinePatchTarget(patch) {
|
|
35423
|
+
if (!patch)
|
|
35424
|
+
return;
|
|
35425
|
+
const sections = hashlinePatchSections(patch) ?? hashlinePatchSections(patch.slice(0, patch.lastIndexOf(`
|
|
35426
|
+
`) + 1));
|
|
35427
|
+
const first = sections?.[0];
|
|
35428
|
+
if (!sections || !first)
|
|
35429
|
+
return;
|
|
35430
|
+
const destination = first.moves[first.moves.length - 1];
|
|
35431
|
+
const name = destination ? `${shortenHomePath(first.path)} → ${shortenHomePath(destination)}` : shortenHomePath(first.path);
|
|
35432
|
+
const others = new Set(sections.flatMap((section) => [section.path, ...section.moves]));
|
|
35433
|
+
others.delete(first.path);
|
|
35434
|
+
if (destination)
|
|
35435
|
+
others.delete(destination);
|
|
35436
|
+
return { name, more: others.size };
|
|
35437
|
+
}
|
|
34937
35438
|
function renderMutationResult(result, theme, context, options = { expanded: true }) {
|
|
34938
35439
|
if (context.isError) {
|
|
34939
35440
|
const errorText = result.content.filter((c) => c.type === "text").map((c) => c.text ?? "").join(`
|
|
@@ -34969,15 +35470,21 @@ ${summary}${suffix}`);
|
|
|
34969
35470
|
const container = reuseContainer2(context.lastComponent);
|
|
34970
35471
|
container.clear();
|
|
34971
35472
|
container.addChild(new Spacer2(1));
|
|
34972
|
-
|
|
34973
|
-
|
|
34974
|
-
|
|
34975
|
-
|
|
34976
|
-
|
|
35473
|
+
const files = details?.files ?? [];
|
|
35474
|
+
if (files.length > 1) {
|
|
35475
|
+
for (const file of files) {
|
|
35476
|
+
const counts = theme.fg("muted", ` (+${file.additions}/-${file.deletions})`);
|
|
35477
|
+
container.addChild(new Text3(`${theme.fg("accent", mutationFileName(file))}${counts}`, 1, 0));
|
|
35478
|
+
if (file.diff !== undefined) {
|
|
35479
|
+
container.addChild(new Text3(renderTerminalDiff(file.diff), 1, 0));
|
|
35480
|
+
}
|
|
35481
|
+
}
|
|
35482
|
+
} else {
|
|
35483
|
+
container.addChild(new Text3(renderTerminalDiff(diff), 1, 0));
|
|
34977
35484
|
}
|
|
34978
|
-
container.addChild(new Text3(normalizeTerminalText(renderedDiff), 1, 0));
|
|
34979
35485
|
const rawPath = context.args && typeof context.args === "object" && typeof context.args.path === "string" ? context.args.path : undefined;
|
|
34980
|
-
const
|
|
35486
|
+
const summaryLabel = rawPath ? shortenHomePath(rawPath) : mutationFilesLabel(details?.files);
|
|
35487
|
+
const summaryPath = summaryLabel ? ` ${summaryLabel}` : "";
|
|
34981
35488
|
const summary = `edited${summaryPath} (+${details?.additions ?? 0}/-${details?.deletions ?? 0})`;
|
|
34982
35489
|
return collapsibleResult({
|
|
34983
35490
|
summary,
|
|
@@ -34986,11 +35493,20 @@ ${summary}${suffix}`);
|
|
|
34986
35493
|
context
|
|
34987
35494
|
});
|
|
34988
35495
|
}
|
|
35496
|
+
function renderTerminalDiff(diff) {
|
|
35497
|
+
let renderedDiff;
|
|
35498
|
+
try {
|
|
35499
|
+
renderedDiff = renderDiff2(diff);
|
|
35500
|
+
} catch {
|
|
35501
|
+
renderedDiff = diff;
|
|
35502
|
+
}
|
|
35503
|
+
return normalizeTerminalText(renderedDiff);
|
|
35504
|
+
}
|
|
34989
35505
|
async function resolvePathArg(cwd, path) {
|
|
34990
35506
|
const expanded = normalizePathInput(path);
|
|
34991
35507
|
const abs = absoluteSearchPath(cwd, path);
|
|
34992
35508
|
try {
|
|
34993
|
-
await
|
|
35509
|
+
await stat4(abs);
|
|
34994
35510
|
return abs;
|
|
34995
35511
|
} catch {
|
|
34996
35512
|
return expanded;
|
|
@@ -35565,7 +36081,7 @@ function getBashSpawnHook(pi) {
|
|
|
35565
36081
|
function backgroundWaitSentence(c) {
|
|
35566
36082
|
if (c.watch) {
|
|
35567
36083
|
const noPolling = c.status ? ", and never loop `bash_status` to wait" : "";
|
|
35568
|
-
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}.`;
|
|
36084
|
+
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}.`;
|
|
35569
36085
|
}
|
|
35570
36086
|
return c.status ? "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.";
|
|
35571
36087
|
}
|
|
@@ -35602,7 +36118,7 @@ function registerBashTool(pi, ctx, aftSearchRegistered = false, registeredName =
|
|
|
35602
36118
|
"PTY mode"
|
|
35603
36119
|
].join(", ") : bashCfg.compress ? "workdir and compressed output" : "workdir";
|
|
35604
36120
|
const detachSentence = bashCfg.detach_on_user_message ? "Any new message detaches this wait. Set `bash.detach_on_user_message: false` to keep it blocking; even then, a message containing the literal `&detach` forces detachment, and the token is stripped before delivery; the rest of the message is preserved, while a token-only message becomes `(requested background detach)`." : "Because `bash.detach_on_user_message` is false, a new message leaves this wait blocking; include the literal `&detach` anywhere to force detachment, and the token is stripped before delivery; the rest of the message is preserved, while a token-only message becomes `(requested background detach)`.";
|
|
35605
|
-
const tasksSentence = bashCfg.background ? ` 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); ${detachSentence} Use it when you need the result before doing anything else; keep it off otherwise so auto-promote can remind you while you work. Use \`background: true\` yourself ONLY when you have other
|
|
36121
|
+
const tasksSentence = bashCfg.background ? ` 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); ${detachSentence} Use it when you need the result before doing anything else; keep it off otherwise so auto-promote can remind you while you work. 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; ${backgroundWaitSentence(companions)} 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(companions)}.` : " Commands run in the foreground to completion; `timeout` is the hard kill cap (default 30 minutes).";
|
|
35606
36122
|
const remoteRuns = () => !isPowerShell && remoteRunsOffered(ctx.config);
|
|
35607
36123
|
pi.registerTool({
|
|
35608
36124
|
name: registeredName,
|
|
@@ -35833,7 +36349,7 @@ function createBashWatchTool(ctx) {
|
|
|
35833
36349
|
return {
|
|
35834
36350
|
name: "bash_watch",
|
|
35835
36351
|
label: "bash_watch",
|
|
35836
|
-
description: `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 end the turn
|
|
36352
|
+
description: `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. 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.${bashCompanionRegistered(ctx.config, "bash_status") ? " Never loop bash_status to wait." : ""}`,
|
|
35837
36353
|
promptSnippet: "Wait for or watch a background bash task",
|
|
35838
36354
|
parameters: BashWatchParams,
|
|
35839
36355
|
async execute(_toolCallId, params, signal, _onUpdate, extCtx) {
|
|
@@ -37244,7 +37760,7 @@ function registerNavigateTool(pi, ctx) {
|
|
|
37244
37760
|
const navigateTool = withPathAliasPreparation({
|
|
37245
37761
|
name: "aft_callgraph",
|
|
37246
37762
|
label: "callgraph",
|
|
37247
|
-
description: `Answer code-relationship questions from a real call graph — instead of grep + read chains. Reach for this whenever the question is about how symbols connect. ${zoomEnabled ? "Use aft_zoom with `callgraph:true` for one-level forward calls-out while reading source; use aft_callgraph only for reverse callers or multi-level traces so you do not double-fetch the same relationships." : "Use aft_callgraph call_tree (depth 1) for one-level forward calls-out; use it for reverse callers or multi-level traces."} All ops require both \`path\` and \`symbol\`. Use \`callers\` for call sites (before renaming/signature changes), \`impact\` for blast radius (what breaks if a symbol changes), \`call_tree\` for what a function calls, \`trace_to\` for how execution reaches a symbol
|
|
37763
|
+
description: `Answer code-relationship questions from a real call graph — instead of grep + read chains. Reach for this whenever the question is about how symbols connect. ${zoomEnabled ? "Use aft_zoom with `callgraph:true` for one-level forward calls-out while reading source; use aft_callgraph only for reverse callers or multi-level traces so you do not double-fetch the same relationships." : "Use aft_callgraph call_tree (depth 1) for one-level forward calls-out; use it for reverse callers or multi-level traces."} All ops require both \`path\` and \`symbol\`. Use \`callers\` for call sites (before renaming/signature changes), \`impact\` for blast radius (what breaks if a symbol changes), \`call_tree\` for what a function calls, \`trace_to\` for how execution reaches a symbol (each path runs back to a root labelled main, test, attribute, public API, or no caller found), \`trace_to_symbol\` for the shortest path from one symbol to another (requires \`toSymbol\`; if ambiguous, the error returns candidate files — retry with \`toPath\`), \`trace_data\` to follow a value across assignments/params. Markers: ~ = edge resolved by name only (may point at the wrong same-named symbol); [unresolved] = callee not resolved to a definition, so the location shown is the call site. Unmarked edges are resolved exactly. By default, unresolved external/stdlib leaf calls in call_tree are collapsed into one summary per parent; pass includeUnresolved=true to show every unresolved edge individually. When a list is cut, the reply ends with \`shown N of M <unit> (<reason>) · narrow: <knobs>\`; absence of that line means the list is complete.`,
|
|
37248
37764
|
parameters: navigateParamsSchema(),
|
|
37249
37765
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
37250
37766
|
if (isEmptyParam(params.path)) {
|
|
@@ -37882,7 +38398,7 @@ function registerSafetyTool(pi, ctx) {
|
|
|
37882
38398
|
|
|
37883
38399
|
// src/tools/semantic.ts
|
|
37884
38400
|
import { homedir as homedir17 } from "node:os";
|
|
37885
|
-
import { isAbsolute as isAbsolute12, resolve as
|
|
38401
|
+
import { isAbsolute as isAbsolute12, resolve as resolve16 } from "node:path";
|
|
37886
38402
|
import { Type as Type13 } from "typebox";
|
|
37887
38403
|
var FILESYSTEM_SCAN_STATUS = "answered by a filesystem scan";
|
|
37888
38404
|
function semanticHonestyNote(response, theme) {
|
|
@@ -37905,8 +38421,8 @@ function selectedProjectRoot(cwd, pathArg) {
|
|
|
37905
38421
|
const target = pathArg?.trim();
|
|
37906
38422
|
if (!target)
|
|
37907
38423
|
return canonicalizeProjectRoot(cwd);
|
|
37908
|
-
const expanded = target === "~" ? homedir17() : /^~[/\\]/u.test(target) ?
|
|
37909
|
-
return canonicalizeProjectRoot(isAbsolute12(expanded) ? expanded :
|
|
38424
|
+
const expanded = target === "~" ? homedir17() : /^~[/\\]/u.test(target) ? resolve16(homedir17(), target.slice(2)) : target;
|
|
38425
|
+
return canonicalizeProjectRoot(isAbsolute12(expanded) ? expanded : resolve16(cwd, expanded));
|
|
37910
38426
|
}
|
|
37911
38427
|
function continuityKey(projectRoot, query, includeTests, topK) {
|
|
37912
38428
|
return JSON.stringify([
|
|
@@ -38551,15 +39067,15 @@ function buildWorkflowHints(opts) {
|
|
|
38551
39067
|
`));
|
|
38552
39068
|
}
|
|
38553
39069
|
if (hasInspect) {
|
|
38554
|
-
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.
|
|
38555
|
-
sections.push("**AFT status bar**: tool results may end with a one-line health bar `[AFT E<errors> W<warnings> |
|
|
39070
|
+
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.");
|
|
39071
|
+
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.");
|
|
38556
39072
|
}
|
|
38557
39073
|
if (hasNavigate) {
|
|
38558
39074
|
sections.push([
|
|
38559
39075
|
"Use `aft_callgraph` for code-relationship questions instead of grep + read chains:",
|
|
38560
39076
|
"- `callers` — find all call sites before changing a function signature",
|
|
38561
39077
|
"- `impact` — blast radius (which functions/files will need updates)",
|
|
38562
|
-
"- `trace_to` — how execution reaches this code
|
|
39078
|
+
"- `trace_to` — how execution reaches this code; each path runs back to a root labelled main, test, attribute, public API, or no caller found",
|
|
38563
39079
|
"- `trace_to_symbol` — shortest call path from one symbol to another",
|
|
38564
39080
|
"- `trace_data` — follow a value through assignments and parameters across files"
|
|
38565
39081
|
].join(`
|
|
@@ -38694,18 +39210,18 @@ function createVersionMismatchHandler(getPool, ensureCompatibleBinary = ensureBi
|
|
|
38694
39210
|
}
|
|
38695
39211
|
var PLUGIN_VERSION = (() => {
|
|
38696
39212
|
try {
|
|
38697
|
-
const req =
|
|
39213
|
+
const req = createRequire3(import.meta.url);
|
|
38698
39214
|
return req("../package.json").version;
|
|
38699
39215
|
} catch {
|
|
38700
39216
|
return "0.0.0";
|
|
38701
39217
|
}
|
|
38702
39218
|
})();
|
|
38703
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
39219
|
+
var ANNOUNCEMENT_VERSION = "0.64.0";
|
|
38704
39220
|
var ANNOUNCEMENT_FEATURES = [
|
|
38705
|
-
"
|
|
38706
|
-
"
|
|
38707
|
-
"
|
|
38708
|
-
"
|
|
39221
|
+
"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.",
|
|
39222
|
+
"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.",
|
|
39223
|
+
"`trace_to` labels each root it reaches: main, test, attribute, public API, or no caller found.",
|
|
39224
|
+
"Dead code, unused exports, duplicates, cycles and complexity run only when `aft_inspect` is called; the status bar shows errors, warnings and TODOs."
|
|
38709
39225
|
];
|
|
38710
39226
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
38711
39227
|
var pendingEagerWarnings = new Map;
|