@cortexkit/aft-opencode 0.58.0 → 0.58.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridge-bootstrap.d.ts +8 -0
- package/dist/bridge-bootstrap.d.ts.map +1 -1
- package/dist/config-live-reload.d.ts +315 -0
- package/dist/config-live-reload.d.ts.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/entry/server.js +1068 -278
- package/dist/hooks/auto-update-checker/checker.d.ts +1 -0
- package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1044 -266
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/lsp-npm-table.d.ts +1 -1
- package/dist/lsp-npm-table.d.ts.map +1 -1
- package/dist/shared/read-vision.d.ts +10 -0
- package/dist/shared/read-vision.d.ts.map +1 -0
- package/dist/tool-perf.d.ts +1 -0
- package/dist/tool-perf.d.ts.map +1 -1
- package/dist/tools/bash_watch.d.ts +3 -0
- package/dist/tools/bash_watch.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/permissions.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/entry/server-runtime.mjs +16 -1
- package/src/shared/read-vision.ts +100 -0
package/dist/entry/server.js
CHANGED
|
@@ -9574,6 +9574,9 @@ function isTerminalStatus(status) {
|
|
|
9574
9574
|
function sleep(ms) {
|
|
9575
9575
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9576
9576
|
}
|
|
9577
|
+
function monotonicNowMs() {
|
|
9578
|
+
return performance.now();
|
|
9579
|
+
}
|
|
9577
9580
|
// ../aft-bridge/dist/bash-hints.js
|
|
9578
9581
|
import * as fs from "node:fs";
|
|
9579
9582
|
import * as os from "node:os";
|
|
@@ -9584,6 +9587,10 @@ function resolveWatchTimeoutMs(requestedMs, role, capMs) {
|
|
|
9584
9587
|
const fallback = role === "worker" ? capMs : DEFAULT_PRIMARY_WATCH_TIMEOUT_MS;
|
|
9585
9588
|
return Math.min(requestedMs ?? fallback, capMs);
|
|
9586
9589
|
}
|
|
9590
|
+
function formatWatchWaited(elapsedMs, limitMs, capMs) {
|
|
9591
|
+
const limit = limitMs >= capMs ? `limit ${limitMs}ms, the bash.watch_sync_max_ms cap` : `limit ${limitMs}ms`;
|
|
9592
|
+
return `Waited ${Math.round(elapsedMs)}ms (${limit})`;
|
|
9593
|
+
}
|
|
9587
9594
|
function watchTimeoutSteer(role, capMs, timeoutParam = "timeoutMs") {
|
|
9588
9595
|
if (role === "worker") {
|
|
9589
9596
|
return `The command is still running; this is not a failure. Watch again (${timeoutParam} up to ${capMs}) and don't report a result until it finishes.`;
|
|
@@ -9970,7 +9977,7 @@ import { existsSync } from "node:fs";
|
|
|
9970
9977
|
import { join as join3 } from "node:path";
|
|
9971
9978
|
|
|
9972
9979
|
// ../aft-bridge/dist/child-process.js
|
|
9973
|
-
import { execFileSync as nodeExecFileSync, execSync as nodeExecSync, spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "node:child_process";
|
|
9980
|
+
import { execFile as nodeExecFile, execFileSync as nodeExecFileSync, execSync as nodeExecSync, spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "node:child_process";
|
|
9974
9981
|
var HIDDEN = { windowsHide: true };
|
|
9975
9982
|
function withWindowsHidden(args, takesArgv) {
|
|
9976
9983
|
const out = [...args];
|
|
@@ -9992,6 +9999,7 @@ function hidden(resolve, takesArgv) {
|
|
|
9992
9999
|
}
|
|
9993
10000
|
var spawn = hidden(() => nodeSpawn, true);
|
|
9994
10001
|
var spawnSync = hidden(() => nodeSpawnSync, true);
|
|
10002
|
+
var execFile = hidden(() => nodeExecFile, true);
|
|
9995
10003
|
var execFileSync = hidden(() => nodeExecFileSync, true);
|
|
9996
10004
|
var execSync = hidden(() => nodeExecSync, false);
|
|
9997
10005
|
|
|
@@ -11318,17 +11326,30 @@ class BinaryBridge {
|
|
|
11318
11326
|
}
|
|
11319
11327
|
}
|
|
11320
11328
|
onStderrData(data) {
|
|
11321
|
-
|
|
11322
|
-
let
|
|
11323
|
-
while (
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11329
|
+
const partialLimit = 64 * 1024;
|
|
11330
|
+
let offset = 0;
|
|
11331
|
+
while (offset < data.length) {
|
|
11332
|
+
const newline = data.indexOf(`
|
|
11333
|
+
`, offset);
|
|
11334
|
+
const end = newline < 0 ? data.length : newline;
|
|
11335
|
+
while (offset < end) {
|
|
11336
|
+
const count = Math.min(partialLimit - this.stderrBuffer.length, end - offset);
|
|
11337
|
+
this.stderrBuffer += data.slice(offset, offset + count);
|
|
11338
|
+
offset += count;
|
|
11339
|
+
if (this.stderrBuffer.length === partialLimit) {
|
|
11340
|
+
const last = this.stderrBuffer.charCodeAt(this.stderrBuffer.length - 1);
|
|
11341
|
+
const carry = last >= 55296 && last <= 56319 ? this.stderrBuffer.slice(-1) : "";
|
|
11342
|
+
const fragment = carry ? this.stderrBuffer.slice(0, -1) : this.stderrBuffer;
|
|
11343
|
+
const tagged = tagStderrLine(`${fragment} [stderr record truncated into bounded fragments; ${Buffer.byteLength(fragment)} bytes shown, continuation follows]`);
|
|
11344
|
+
this.stderrBuffer = carry;
|
|
11345
|
+
this.logVia(tagged);
|
|
11346
|
+
this.pushStderrLine(tagged);
|
|
11347
|
+
}
|
|
11348
|
+
}
|
|
11349
|
+
if (newline < 0)
|
|
11350
|
+
break;
|
|
11351
|
+
this.flushStderrBuffer();
|
|
11352
|
+
offset = newline + 1;
|
|
11332
11353
|
}
|
|
11333
11354
|
}
|
|
11334
11355
|
flushStderrBuffer() {
|
|
@@ -11817,9 +11838,366 @@ function formatDroppedKeyWarnings(dropped) {
|
|
|
11817
11838
|
}
|
|
11818
11839
|
return dropped.map((item) => `Ignoring ${item.key} from ${item.tier} config (${item.reason})`);
|
|
11819
11840
|
}
|
|
11841
|
+
// ../aft-bridge/dist/config-watch.js
|
|
11842
|
+
import { readFileSync as readFileSync3, statSync as statSync3, watch } from "node:fs";
|
|
11843
|
+
import { basename, dirname } from "node:path";
|
|
11844
|
+
var CONFIG_WATCH_DEBOUNCE_MS = 150;
|
|
11845
|
+
var CONFIG_LIVE_KEEP_NOTE = "AFT keeps using the last valid configuration until the file is fixed.";
|
|
11846
|
+
function pathKey(name) {
|
|
11847
|
+
const segments = name.split(".");
|
|
11848
|
+
return {
|
|
11849
|
+
name,
|
|
11850
|
+
read(config) {
|
|
11851
|
+
let value = config;
|
|
11852
|
+
for (const segment of segments) {
|
|
11853
|
+
if (value === null || typeof value !== "object")
|
|
11854
|
+
return;
|
|
11855
|
+
value = value[segment];
|
|
11856
|
+
}
|
|
11857
|
+
return value;
|
|
11858
|
+
},
|
|
11859
|
+
write(config, value) {
|
|
11860
|
+
const set = (target, index) => {
|
|
11861
|
+
const copy = target !== null && typeof target === "object" && !Array.isArray(target) ? { ...target } : {};
|
|
11862
|
+
const segment = segments[index];
|
|
11863
|
+
if (index === segments.length - 1) {
|
|
11864
|
+
if (value === undefined)
|
|
11865
|
+
delete copy[segment];
|
|
11866
|
+
else
|
|
11867
|
+
copy[segment] = value;
|
|
11868
|
+
} else {
|
|
11869
|
+
copy[segment] = set(copy[segment], index + 1);
|
|
11870
|
+
}
|
|
11871
|
+
return copy;
|
|
11872
|
+
};
|
|
11873
|
+
return set(config, 0);
|
|
11874
|
+
}
|
|
11875
|
+
};
|
|
11876
|
+
}
|
|
11877
|
+
function bashKey(name, resolveBash) {
|
|
11878
|
+
return {
|
|
11879
|
+
name: `bash.${name}`,
|
|
11880
|
+
read: (config) => resolveBash(config)[name],
|
|
11881
|
+
write(config, value) {
|
|
11882
|
+
const resolved = { ...resolveBash(config), [name]: value };
|
|
11883
|
+
for (const key of Object.keys(resolved)) {
|
|
11884
|
+
if (resolved[key] === undefined)
|
|
11885
|
+
delete resolved[key];
|
|
11886
|
+
}
|
|
11887
|
+
return { ...config, bash: resolved };
|
|
11888
|
+
}
|
|
11889
|
+
};
|
|
11890
|
+
}
|
|
11891
|
+
function aftLiveConfigKeys(resolveBash) {
|
|
11892
|
+
return [
|
|
11893
|
+
pathKey("configure_warnings_delivery"),
|
|
11894
|
+
pathKey("restrict_to_project_root"),
|
|
11895
|
+
pathKey("inspect.diagnostics_timeout_ms"),
|
|
11896
|
+
pathKey("inspect.tier2_idle_minutes"),
|
|
11897
|
+
bashKey("foreground_wait_window_ms", resolveBash),
|
|
11898
|
+
bashKey("host_fallback", resolveBash),
|
|
11899
|
+
bashKey("subagent_background", resolveBash),
|
|
11900
|
+
bashKey("watch_sync_max_ms", resolveBash)
|
|
11901
|
+
];
|
|
11902
|
+
}
|
|
11903
|
+
function sameValue(a, b) {
|
|
11904
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
11905
|
+
}
|
|
11906
|
+
function flattenLeaves(value, prefix, out) {
|
|
11907
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
11908
|
+
const entries = Object.entries(value);
|
|
11909
|
+
if (entries.length === 0 && prefix)
|
|
11910
|
+
out.set(prefix, "{}");
|
|
11911
|
+
for (const [key, child] of entries) {
|
|
11912
|
+
flattenLeaves(child, prefix ? `${prefix}.${key}` : key, out);
|
|
11913
|
+
}
|
|
11914
|
+
return;
|
|
11915
|
+
}
|
|
11916
|
+
if (prefix)
|
|
11917
|
+
out.set(prefix, JSON.stringify(value));
|
|
11918
|
+
}
|
|
11919
|
+
function applyLiveConfigKeys(current, next, keys, baseline = current) {
|
|
11920
|
+
let config = current;
|
|
11921
|
+
const applied = [];
|
|
11922
|
+
for (const key of keys) {
|
|
11923
|
+
const value = key.read(next);
|
|
11924
|
+
if (sameValue(key.read(current), value))
|
|
11925
|
+
continue;
|
|
11926
|
+
config = key.write(config, value);
|
|
11927
|
+
applied.push(key.name);
|
|
11928
|
+
}
|
|
11929
|
+
const before = new Map;
|
|
11930
|
+
const after = new Map;
|
|
11931
|
+
flattenLeaves(baseline, "", before);
|
|
11932
|
+
flattenLeaves(next, "", after);
|
|
11933
|
+
const liveNames = keys.map((key) => key.name);
|
|
11934
|
+
const isLive = (leaf) => liveNames.some((name) => leaf === name || leaf.startsWith(`${name}.`));
|
|
11935
|
+
const deferred = new Set;
|
|
11936
|
+
for (const leaf of new Set([...before.keys(), ...after.keys()])) {
|
|
11937
|
+
if (before.get(leaf) === after.get(leaf) || isLive(leaf))
|
|
11938
|
+
continue;
|
|
11939
|
+
deferred.add(leaf);
|
|
11940
|
+
}
|
|
11941
|
+
return { config, applied, deferred: [...deferred].sort() };
|
|
11942
|
+
}
|
|
11943
|
+
function readTextOrNull(path) {
|
|
11944
|
+
try {
|
|
11945
|
+
return readFileSync3(path, "utf8");
|
|
11946
|
+
} catch {
|
|
11947
|
+
return null;
|
|
11948
|
+
}
|
|
11949
|
+
}
|
|
11950
|
+
var CONFIG_WATCH_REVALIDATE_MS = 2000;
|
|
11951
|
+
var CONFIG_WATCH_REJECTED_RETRIES = 3;
|
|
11952
|
+
var CONFIG_WATCH_MAX_DELAY_MS = 1000;
|
|
11953
|
+
function identityOf(dir) {
|
|
11954
|
+
try {
|
|
11955
|
+
const stat = statSync3(dir, { bigint: true });
|
|
11956
|
+
const base = `${stat.dev}:${stat.ino}`;
|
|
11957
|
+
return process.platform === "win32" ? base : `${base}:${stat.birthtimeNs}`;
|
|
11958
|
+
} catch {
|
|
11959
|
+
return null;
|
|
11960
|
+
}
|
|
11961
|
+
}
|
|
11962
|
+
function watchDirFor(file) {
|
|
11963
|
+
let dir = dirname(file);
|
|
11964
|
+
while (dir !== dirname(dir) && identityOf(dir) === null)
|
|
11965
|
+
dir = dirname(dir);
|
|
11966
|
+
return dir;
|
|
11967
|
+
}
|
|
11968
|
+
function watchAftConfigFiles(options) {
|
|
11969
|
+
const debounceMs = options.debounceMs ?? CONFIG_WATCH_DEBOUNCE_MS;
|
|
11970
|
+
const lastSeen = new Map;
|
|
11971
|
+
for (const path of options.paths) {
|
|
11972
|
+
if (options.initialTexts)
|
|
11973
|
+
lastSeen.set(path, options.initialTexts[path] ?? null);
|
|
11974
|
+
else
|
|
11975
|
+
lastSeen.set(path, options.checkAtStart ? undefined : readTextOrNull(path));
|
|
11976
|
+
}
|
|
11977
|
+
let timer = null;
|
|
11978
|
+
let firstPendingAt = null;
|
|
11979
|
+
let stopped = false;
|
|
11980
|
+
const watchers = new Map;
|
|
11981
|
+
const watchImpl = options.watchImpl ?? watch;
|
|
11982
|
+
let rejectedRetries = 0;
|
|
11983
|
+
const check = () => {
|
|
11984
|
+
timer = null;
|
|
11985
|
+
firstPendingAt = null;
|
|
11986
|
+
if (stopped)
|
|
11987
|
+
return;
|
|
11988
|
+
revalidate();
|
|
11989
|
+
const seen = new Map;
|
|
11990
|
+
for (const path of options.paths) {
|
|
11991
|
+
const text = readTextOrNull(path);
|
|
11992
|
+
if (text !== lastSeen.get(path))
|
|
11993
|
+
seen.set(path, text);
|
|
11994
|
+
}
|
|
11995
|
+
if (seen.size === 0)
|
|
11996
|
+
return;
|
|
11997
|
+
const outcome = options.onChange();
|
|
11998
|
+
if (outcome === false) {
|
|
11999
|
+
if (rejectedRetries < CONFIG_WATCH_REJECTED_RETRIES) {
|
|
12000
|
+
rejectedRetries += 1;
|
|
12001
|
+
retryTimer = setTimeout(check, CONFIG_WATCH_MAX_DELAY_MS);
|
|
12002
|
+
retryTimer.unref?.();
|
|
12003
|
+
}
|
|
12004
|
+
return;
|
|
12005
|
+
}
|
|
12006
|
+
rejectedRetries = 0;
|
|
12007
|
+
if (outcome instanceof Map) {
|
|
12008
|
+
for (const path of options.paths)
|
|
12009
|
+
lastSeen.set(path, outcome.get(path) ?? null);
|
|
12010
|
+
} else {
|
|
12011
|
+
for (const [path, text] of seen)
|
|
12012
|
+
lastSeen.set(path, text);
|
|
12013
|
+
}
|
|
12014
|
+
};
|
|
12015
|
+
let retryTimer = null;
|
|
12016
|
+
const schedule = () => {
|
|
12017
|
+
if (stopped)
|
|
12018
|
+
return;
|
|
12019
|
+
const now = Date.now();
|
|
12020
|
+
firstPendingAt ??= now;
|
|
12021
|
+
if (timer)
|
|
12022
|
+
clearTimeout(timer);
|
|
12023
|
+
const delay = Math.max(0, Math.min(debounceMs, firstPendingAt + CONFIG_WATCH_MAX_DELAY_MS - now));
|
|
12024
|
+
timer = setTimeout(check, delay);
|
|
12025
|
+
timer.unref?.();
|
|
12026
|
+
};
|
|
12027
|
+
function revalidate() {
|
|
12028
|
+
const wanted = new Set(options.paths.map(watchDirFor));
|
|
12029
|
+
let moved = false;
|
|
12030
|
+
for (const [dir, entry] of watchers) {
|
|
12031
|
+
if (!wanted.has(dir) || entry.stale || identityOf(dir) !== entry.identity) {
|
|
12032
|
+
entry.watcher.close();
|
|
12033
|
+
watchers.delete(dir);
|
|
12034
|
+
moved = true;
|
|
12035
|
+
}
|
|
12036
|
+
}
|
|
12037
|
+
for (const dir of wanted) {
|
|
12038
|
+
if (watchers.has(dir))
|
|
12039
|
+
continue;
|
|
12040
|
+
try {
|
|
12041
|
+
const identity = identityOf(dir);
|
|
12042
|
+
options.beforeWatchForTest?.(dir);
|
|
12043
|
+
const name = basename(dir);
|
|
12044
|
+
const watcher = watchImpl(dir, { persistent: false }, (event, filename) => {
|
|
12045
|
+
if (event === "rename" && filename === name) {
|
|
12046
|
+
const current = watchers.get(dir);
|
|
12047
|
+
if (current && current.watcher === watcher)
|
|
12048
|
+
current.stale = true;
|
|
12049
|
+
}
|
|
12050
|
+
schedule();
|
|
12051
|
+
});
|
|
12052
|
+
if (identityOf(dir) !== identity) {
|
|
12053
|
+
watcher.close();
|
|
12054
|
+
moved = true;
|
|
12055
|
+
continue;
|
|
12056
|
+
}
|
|
12057
|
+
const entry = { watcher, identity, stale: false };
|
|
12058
|
+
entry.watcher.on("error", () => {
|
|
12059
|
+
entry.watcher.close();
|
|
12060
|
+
if (watchers.get(dir) === entry)
|
|
12061
|
+
watchers.delete(dir);
|
|
12062
|
+
schedule();
|
|
12063
|
+
});
|
|
12064
|
+
watchers.set(dir, entry);
|
|
12065
|
+
moved = true;
|
|
12066
|
+
} catch {}
|
|
12067
|
+
}
|
|
12068
|
+
return moved;
|
|
12069
|
+
}
|
|
12070
|
+
revalidate();
|
|
12071
|
+
if (options.checkAtStart)
|
|
12072
|
+
check();
|
|
12073
|
+
const revalidateTimer = setInterval(() => {
|
|
12074
|
+
if (!stopped && revalidate())
|
|
12075
|
+
schedule();
|
|
12076
|
+
}, CONFIG_WATCH_REVALIDATE_MS);
|
|
12077
|
+
revalidateTimer.unref?.();
|
|
12078
|
+
return () => {
|
|
12079
|
+
stopped = true;
|
|
12080
|
+
if (timer)
|
|
12081
|
+
clearTimeout(timer);
|
|
12082
|
+
if (retryTimer)
|
|
12083
|
+
clearTimeout(retryTimer);
|
|
12084
|
+
clearInterval(revalidateTimer);
|
|
12085
|
+
for (const entry of watchers.values())
|
|
12086
|
+
entry.watcher.close();
|
|
12087
|
+
watchers.clear();
|
|
12088
|
+
};
|
|
12089
|
+
}
|
|
12090
|
+
function aftLiveSecurityKeys(keys) {
|
|
12091
|
+
const byName = new Map(keys.map((key) => [key.name, key]));
|
|
12092
|
+
const pick = (name) => {
|
|
12093
|
+
const key = byName.get(name);
|
|
12094
|
+
if (!key)
|
|
12095
|
+
throw new Error(`unknown live config key ${name}`);
|
|
12096
|
+
return key;
|
|
12097
|
+
};
|
|
12098
|
+
return [
|
|
12099
|
+
{
|
|
12100
|
+
key: pick("restrict_to_project_root"),
|
|
12101
|
+
loosens: (current, next) => current === true && next !== true
|
|
12102
|
+
},
|
|
12103
|
+
{
|
|
12104
|
+
key: pick("bash.host_fallback"),
|
|
12105
|
+
loosens: (current, next) => current !== true && next === true
|
|
12106
|
+
}
|
|
12107
|
+
];
|
|
12108
|
+
}
|
|
12109
|
+
function liveConfigReloadLogLine(applied, deferred) {
|
|
12110
|
+
let line = "config reload";
|
|
12111
|
+
if (applied.length > 0)
|
|
12112
|
+
line += ` applied=[${applied.join(",")}]`;
|
|
12113
|
+
if (deferred.length > 0) {
|
|
12114
|
+
line += ` deferred=[${deferred.join(",")}] (deferred keys apply on next connect/restart)`;
|
|
12115
|
+
}
|
|
12116
|
+
return line;
|
|
12117
|
+
}
|
|
12118
|
+
function startLiveConfigReload(options) {
|
|
12119
|
+
const baseline = options.getConfig();
|
|
12120
|
+
let lastError = null;
|
|
12121
|
+
let acceptedSources = new Set(options.initialSources);
|
|
12122
|
+
let acceptedProjectText = options.initialProjectText ?? null;
|
|
12123
|
+
let acceptedTexts;
|
|
12124
|
+
const reload = () => {
|
|
12125
|
+
let loaded = options.load();
|
|
12126
|
+
if (loaded.ok) {
|
|
12127
|
+
const read = new Set(loaded.sources);
|
|
12128
|
+
const deleted = [...acceptedSources].find((path) => !read.has(path));
|
|
12129
|
+
if (deleted !== undefined) {
|
|
12130
|
+
loaded = { ok: false, message: `AFT config at ${deleted} was deleted` };
|
|
12131
|
+
} else {
|
|
12132
|
+
acceptedSources = read;
|
|
12133
|
+
}
|
|
12134
|
+
}
|
|
12135
|
+
if (!loaded.ok) {
|
|
12136
|
+
const message = `${loaded.message.trim().replace(/[.!?]?$/, ".")} ${CONFIG_LIVE_KEEP_NOTE}`;
|
|
12137
|
+
if (message !== lastError) {
|
|
12138
|
+
lastError = message;
|
|
12139
|
+
options.reportError(message);
|
|
12140
|
+
}
|
|
12141
|
+
return null;
|
|
12142
|
+
}
|
|
12143
|
+
lastError = null;
|
|
12144
|
+
acceptedTexts = loaded.texts;
|
|
12145
|
+
const current = options.getConfig();
|
|
12146
|
+
let next = loaded.config;
|
|
12147
|
+
const held = [];
|
|
12148
|
+
const projectText = loaded.projectText ?? null;
|
|
12149
|
+
if (loaded.projectText !== undefined && projectText !== acceptedProjectText) {
|
|
12150
|
+
for (const security of options.securityKeys ?? []) {
|
|
12151
|
+
const now = security.key.read(current);
|
|
12152
|
+
if (security.loosens(now, security.key.read(next))) {
|
|
12153
|
+
next = security.key.write(next, now);
|
|
12154
|
+
held.push(security.key.name);
|
|
12155
|
+
}
|
|
12156
|
+
}
|
|
12157
|
+
if (held.length === 0)
|
|
12158
|
+
acceptedProjectText = projectText;
|
|
12159
|
+
}
|
|
12160
|
+
const result = applyLiveConfigKeys(current, next, options.keys, baseline);
|
|
12161
|
+
if (result.applied.length > 0)
|
|
12162
|
+
options.setConfig(result.config);
|
|
12163
|
+
if (result.applied.length > 0 || result.deferred.length > 0 || held.length > 0) {
|
|
12164
|
+
let line = liveConfigReloadLogLine(result.applied, result.deferred);
|
|
12165
|
+
if (held.length > 0) {
|
|
12166
|
+
line += ` held=[${held.join(",")}] (not loosened while the project file differs from the one the published values came from; the next restart applies them)`;
|
|
12167
|
+
}
|
|
12168
|
+
options.log(line);
|
|
12169
|
+
}
|
|
12170
|
+
return { ...result, held };
|
|
12171
|
+
};
|
|
12172
|
+
const safeReload = () => {
|
|
12173
|
+
try {
|
|
12174
|
+
acceptedTexts = undefined;
|
|
12175
|
+
if (reload() === null)
|
|
12176
|
+
return false;
|
|
12177
|
+
const texts = acceptedTexts;
|
|
12178
|
+
if (!texts)
|
|
12179
|
+
return true;
|
|
12180
|
+
return new Map(options.paths.map((path) => [path, texts[path] ?? null]));
|
|
12181
|
+
} catch (err) {
|
|
12182
|
+
options.reportError(`AFT config reload failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
12183
|
+
return false;
|
|
12184
|
+
}
|
|
12185
|
+
};
|
|
12186
|
+
if (options.watch === false) {
|
|
12187
|
+
return { reload, stop: () => {} };
|
|
12188
|
+
}
|
|
12189
|
+
const stop = watchAftConfigFiles({
|
|
12190
|
+
paths: options.paths,
|
|
12191
|
+
debounceMs: options.debounceMs,
|
|
12192
|
+
onChange: safeReload,
|
|
12193
|
+
initialTexts: options.initialTexts,
|
|
12194
|
+
checkAtStart: true
|
|
12195
|
+
});
|
|
12196
|
+
return { reload, stop };
|
|
12197
|
+
}
|
|
11820
12198
|
// ../aft-bridge/dist/downloader.js
|
|
11821
12199
|
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
11822
|
-
import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync3, mkdirSync, openSync, readdirSync, readFileSync as
|
|
12200
|
+
import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync3, mkdirSync, openSync, readdirSync, readFileSync as readFileSync4, renameSync as renameSync2, rmSync, statSync as statSync4, unlinkSync as unlinkSync2, writeSync } from "node:fs";
|
|
11823
12201
|
import { hostname } from "node:os";
|
|
11824
12202
|
import { join as join7 } from "node:path";
|
|
11825
12203
|
import { Readable } from "node:stream";
|
|
@@ -12171,7 +12549,7 @@ function isReclaimableDownloadLock(owner, ageMs, staleMs) {
|
|
|
12171
12549
|
}
|
|
12172
12550
|
function reclaimDownloadLock(lockPath, expectedOwner) {
|
|
12173
12551
|
try {
|
|
12174
|
-
if (
|
|
12552
|
+
if (readFileSync4(lockPath, "utf-8") !== expectedOwner)
|
|
12175
12553
|
return false;
|
|
12176
12554
|
rmSync(lockPath, { force: true });
|
|
12177
12555
|
return true;
|
|
@@ -12189,7 +12567,7 @@ function sweepStaleDownloadTemps(versionedCacheDir, binaryName) {
|
|
|
12189
12567
|
continue;
|
|
12190
12568
|
}
|
|
12191
12569
|
const tempPath = join7(versionedCacheDir, entry.name);
|
|
12192
|
-
const ageMs = Date.now() -
|
|
12570
|
+
const ageMs = Date.now() - statSync4(tempPath).mtimeMs;
|
|
12193
12571
|
if (Math.abs(ageMs) > DOWNLOAD_LOCK_STALE_MS)
|
|
12194
12572
|
unlinkSync2(tempPath);
|
|
12195
12573
|
}
|
|
@@ -12211,7 +12589,7 @@ async function acquireDownloadLock(lockPath, timing = {}) {
|
|
|
12211
12589
|
}
|
|
12212
12590
|
return () => {
|
|
12213
12591
|
try {
|
|
12214
|
-
if (
|
|
12592
|
+
if (readFileSync4(lockPath, "utf-8") === owner) {
|
|
12215
12593
|
rmSync(lockPath, { force: true });
|
|
12216
12594
|
}
|
|
12217
12595
|
} catch {}
|
|
@@ -12223,8 +12601,8 @@ async function acquireDownloadLock(lockPath, timing = {}) {
|
|
|
12223
12601
|
let existingOwner;
|
|
12224
12602
|
let ageMs;
|
|
12225
12603
|
try {
|
|
12226
|
-
existingOwner =
|
|
12227
|
-
ageMs = Date.now() -
|
|
12604
|
+
existingOwner = readFileSync4(lockPath, "utf-8");
|
|
12605
|
+
ageMs = Date.now() - statSync4(lockPath).mtimeMs;
|
|
12228
12606
|
} catch (readErr) {
|
|
12229
12607
|
if (readErr.code === "ENOENT")
|
|
12230
12608
|
continue;
|
|
@@ -12274,7 +12652,7 @@ async function fetchLatestTag() {
|
|
|
12274
12652
|
}
|
|
12275
12653
|
// ../aft-bridge/dist/durable-log.js
|
|
12276
12654
|
import { appendFile, chmod, mkdir, rename, rm, stat } from "node:fs/promises";
|
|
12277
|
-
import { dirname } from "node:path";
|
|
12655
|
+
import { dirname as dirname2 } from "node:path";
|
|
12278
12656
|
var DEFAULT_LOG_BYTES = 32 * 1024 * 1024;
|
|
12279
12657
|
var DEFAULT_LOG_GENERATIONS = 1;
|
|
12280
12658
|
var LOG_DIR_MODE = 448;
|
|
@@ -12287,6 +12665,10 @@ class RotatingLogSink {
|
|
|
12287
12665
|
queue = Promise.resolve();
|
|
12288
12666
|
disabled = false;
|
|
12289
12667
|
failureReported = false;
|
|
12668
|
+
queuedBytes = 0;
|
|
12669
|
+
queuedRecords = 0;
|
|
12670
|
+
droppedBytes = 0;
|
|
12671
|
+
overflowQueued = false;
|
|
12290
12672
|
constructor(path, options = {}) {
|
|
12291
12673
|
this.path = path;
|
|
12292
12674
|
this.maxBytes = options.maxBytes ?? DEFAULT_LOG_BYTES;
|
|
@@ -12295,7 +12677,34 @@ class RotatingLogSink {
|
|
|
12295
12677
|
append(data) {
|
|
12296
12678
|
if (this.disabled || data.length === 0)
|
|
12297
12679
|
return;
|
|
12298
|
-
|
|
12680
|
+
const bytes = Buffer.byteLength(data);
|
|
12681
|
+
const overflow = this.queuedBytes + bytes > 1024 * 1024 || this.queuedRecords >= 4096;
|
|
12682
|
+
if (overflow) {
|
|
12683
|
+
this.droppedBytes += bytes;
|
|
12684
|
+
if (this.overflowQueued)
|
|
12685
|
+
return;
|
|
12686
|
+
this.overflowQueued = true;
|
|
12687
|
+
data = "";
|
|
12688
|
+
} else {
|
|
12689
|
+
this.queuedBytes += bytes;
|
|
12690
|
+
this.queuedRecords += 1;
|
|
12691
|
+
}
|
|
12692
|
+
this.queue = this.queue.then(async () => {
|
|
12693
|
+
if (overflow) {
|
|
12694
|
+
const dropped = this.droppedBytes;
|
|
12695
|
+
this.droppedBytes = 0;
|
|
12696
|
+
this.overflowQueued = false;
|
|
12697
|
+
await this.write(`[aft-plugin] durable log queue overflow: dropped ${dropped} bytes (1MiB/4096-record pending limit); reduce diagnostic volume.
|
|
12698
|
+
`);
|
|
12699
|
+
} else {
|
|
12700
|
+
try {
|
|
12701
|
+
await this.write(data);
|
|
12702
|
+
} finally {
|
|
12703
|
+
this.queuedBytes -= bytes;
|
|
12704
|
+
this.queuedRecords -= 1;
|
|
12705
|
+
}
|
|
12706
|
+
}
|
|
12707
|
+
}).catch((error) => {
|
|
12299
12708
|
this.disabled = true;
|
|
12300
12709
|
if (!this.failureReported) {
|
|
12301
12710
|
this.failureReported = true;
|
|
@@ -12310,8 +12719,8 @@ class RotatingLogSink {
|
|
|
12310
12719
|
await this.queue;
|
|
12311
12720
|
}
|
|
12312
12721
|
async write(data) {
|
|
12313
|
-
const dir =
|
|
12314
|
-
await mkdir(
|
|
12722
|
+
const dir = dirname2(this.path);
|
|
12723
|
+
await mkdir(dirname2(dir), { recursive: true });
|
|
12315
12724
|
try {
|
|
12316
12725
|
await mkdir(dir, { mode: LOG_DIR_MODE });
|
|
12317
12726
|
} catch (error) {
|
|
@@ -14099,7 +14508,7 @@ function reverseRequestMethod(body) {
|
|
|
14099
14508
|
}
|
|
14100
14509
|
}
|
|
14101
14510
|
// ../aft-bridge/dist/subc-transport.js
|
|
14102
|
-
import { existsSync as existsSync4, statSync as
|
|
14511
|
+
import { existsSync as existsSync4, statSync as statSync5 } from "node:fs";
|
|
14103
14512
|
|
|
14104
14513
|
// ../aft-bridge/dist/lifecycle-registry.js
|
|
14105
14514
|
import { lstat } from "node:fs/promises";
|
|
@@ -14626,6 +15035,7 @@ var RECONNECT_RETRY_FLOOR_MS = 100;
|
|
|
14626
15035
|
var RECONNECT_RETRY_CAP_MS = 2000;
|
|
14627
15036
|
var SUBC_DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
14628
15037
|
var ROUTE_OPEN_RELOAD_WAIT_CEILING_MS = 45000;
|
|
15038
|
+
var CALL_DEADLINE_EXPIRED = Symbol("call deadline expired");
|
|
14629
15039
|
function reloadWaitExhaustedSuffix(callDeadlineMs) {
|
|
14630
15040
|
if (callDeadlineMs > ROUTE_OPEN_RELOAD_WAIT_CEILING_MS) {
|
|
14631
15041
|
const ceilingSeconds = ROUTE_OPEN_RELOAD_WAIT_CEILING_MS / 1000;
|
|
@@ -14978,7 +15388,16 @@ function absentRootError(root) {
|
|
|
14978
15388
|
return new SubcError(`invalid route project root: project root does not exist: ${root}`, "config_divergence");
|
|
14979
15389
|
}
|
|
14980
15390
|
function reloadWindowExhaustedError(error, callDeadlineMs) {
|
|
14981
|
-
|
|
15391
|
+
return withDeadlineSuffix(error, reloadWaitExhaustedSuffix(callDeadlineMs));
|
|
15392
|
+
}
|
|
15393
|
+
function callDeadlinePassedError(lastError, callDeadlineMs) {
|
|
15394
|
+
const seconds = Math.round(callDeadlineMs / 100) / 10;
|
|
15395
|
+
const suffix = ` The AFT daemon module did not return within this call's ${seconds}s deadline.`;
|
|
15396
|
+
if (lastError !== undefined)
|
|
15397
|
+
return withDeadlineSuffix(lastError, suffix);
|
|
15398
|
+
return new SubcError(`route to module '${AFT_MODULE_ID}' was not ready before the call ran out of time.${suffix}`, REQUEST_DEADLINE_CODE);
|
|
15399
|
+
}
|
|
15400
|
+
function withDeadlineSuffix(error, suffix) {
|
|
14982
15401
|
if (error instanceof Error) {
|
|
14983
15402
|
try {
|
|
14984
15403
|
error.message += suffix;
|
|
@@ -15217,7 +15636,7 @@ class SubcTransportPool {
|
|
|
15217
15636
|
rootCanAttach(root) {
|
|
15218
15637
|
let directoryExists = false;
|
|
15219
15638
|
try {
|
|
15220
|
-
directoryExists =
|
|
15639
|
+
directoryExists = statSync5(root).isDirectory();
|
|
15221
15640
|
} catch {}
|
|
15222
15641
|
if (directoryExists) {
|
|
15223
15642
|
this.dormantRoots.delete(root);
|
|
@@ -15557,6 +15976,7 @@ class SubcTransportPool {
|
|
|
15557
15976
|
return this.rootReapedError(record);
|
|
15558
15977
|
}
|
|
15559
15978
|
async routeRequest(identity, body, timeoutMs, onProgress, expectedGeneration, abortSignal) {
|
|
15979
|
+
const callStartedAt = performance.now();
|
|
15560
15980
|
const root = asCanonicalRootPath(identity.project_root);
|
|
15561
15981
|
let generation = expectedGeneration;
|
|
15562
15982
|
if (this.lifecycleEnabled()) {
|
|
@@ -15609,19 +16029,41 @@ class SubcTransportPool {
|
|
|
15609
16029
|
};
|
|
15610
16030
|
const callDeadlineMs = timeoutMs ?? SUBC_DEFAULT_REQUEST_TIMEOUT_MS;
|
|
15611
16031
|
const reloadWaitBudgetMs = Math.min(callDeadlineMs, ROUTE_OPEN_RELOAD_WAIT_CEILING_MS);
|
|
15612
|
-
let
|
|
16032
|
+
let scheduledDelayMs = 0;
|
|
16033
|
+
let lastRefusal;
|
|
16034
|
+
const spentMs = () => Math.max(performance.now() - callStartedAt, scheduledDelayMs);
|
|
16035
|
+
const remainingMs = () => callDeadlineMs - spentMs();
|
|
16036
|
+
const openRouteWithinDeadline = async () => {
|
|
16037
|
+
const remaining = remainingMs();
|
|
16038
|
+
if (remaining <= 0)
|
|
16039
|
+
throw callDeadlinePassedError(lastRefusal, callDeadlineMs);
|
|
16040
|
+
let timer;
|
|
16041
|
+
const expired = new Promise((resolve) => {
|
|
16042
|
+
timer = setTimeout(() => resolve(CALL_DEADLINE_EXPIRED), remaining);
|
|
16043
|
+
});
|
|
16044
|
+
try {
|
|
16045
|
+
const opened = await Promise.race([openRoute(), expired]);
|
|
16046
|
+
if (opened === CALL_DEADLINE_EXPIRED) {
|
|
16047
|
+
throw callDeadlinePassedError(lastRefusal, callDeadlineMs);
|
|
16048
|
+
}
|
|
16049
|
+
return opened;
|
|
16050
|
+
} finally {
|
|
16051
|
+
clearTimeout(timer);
|
|
16052
|
+
}
|
|
16053
|
+
};
|
|
15613
16054
|
const openRouteAfterReloadWindow = async () => {
|
|
15614
16055
|
while (true) {
|
|
15615
16056
|
try {
|
|
15616
|
-
return await
|
|
16057
|
+
return await openRouteWithinDeadline();
|
|
15617
16058
|
} catch (error) {
|
|
15618
16059
|
if (!isRouteOpenReloadWindowError(error))
|
|
15619
16060
|
throw error;
|
|
15620
|
-
|
|
16061
|
+
lastRefusal = error;
|
|
16062
|
+
if (spentMs() + this.nextRouteReopenDelayMs() >= reloadWaitBudgetMs) {
|
|
15621
16063
|
throw reloadWindowExhaustedError(error, callDeadlineMs);
|
|
15622
16064
|
}
|
|
15623
16065
|
const { delayMs, wait } = this.waitForRouteReopenBackoff();
|
|
15624
|
-
|
|
16066
|
+
scheduledDelayMs = spentMs() + delayMs;
|
|
15625
16067
|
await wait;
|
|
15626
16068
|
}
|
|
15627
16069
|
}
|
|
@@ -15657,7 +16099,7 @@ class SubcTransportPool {
|
|
|
15657
16099
|
route: routeLabel(entry.handle)
|
|
15658
16100
|
});
|
|
15659
16101
|
};
|
|
15660
|
-
const requestOnRoute = async (route, entry) => {
|
|
16102
|
+
const requestOnRoute = async (route, entry, requestTimeoutMs) => {
|
|
15661
16103
|
this.assertRecordLive(record);
|
|
15662
16104
|
if (abortSignal?.aborted) {
|
|
15663
16105
|
clearRouteEntry(entry);
|
|
@@ -15673,8 +16115,10 @@ class SubcTransportPool {
|
|
|
15673
16115
|
};
|
|
15674
16116
|
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
15675
16117
|
try {
|
|
15676
|
-
const
|
|
15677
|
-
|
|
16118
|
+
const request = client.request(route, body, {
|
|
16119
|
+
timeoutMs: Math.ceil(requestTimeoutMs),
|
|
16120
|
+
onProgress
|
|
16121
|
+
});
|
|
15678
16122
|
const reply = abortSignal ? await Promise.race([request, aborted]) : await request;
|
|
15679
16123
|
if (!this.isCurrentSession(key, record)) {
|
|
15680
16124
|
if (this.isReapInduced(record))
|
|
@@ -15695,8 +16139,11 @@ class SubcTransportPool {
|
|
|
15695
16139
|
let reopened = false;
|
|
15696
16140
|
let retriedAbsentRoute = false;
|
|
15697
16141
|
while (true) {
|
|
16142
|
+
const requestTimeoutMs = remainingMs();
|
|
16143
|
+
if (requestTimeoutMs <= 0)
|
|
16144
|
+
throw callDeadlinePassedError(lastRefusal, callDeadlineMs);
|
|
15698
16145
|
try {
|
|
15699
|
-
const reply = await requestOnRoute(routeAndEntry.route, routeAndEntry.entry);
|
|
16146
|
+
const reply = await requestOnRoute(routeAndEntry.route, routeAndEntry.entry, requestTimeoutMs);
|
|
15700
16147
|
if (reopened)
|
|
15701
16148
|
this.resetRouteReopenBackoff();
|
|
15702
16149
|
return reply;
|
|
@@ -15706,11 +16153,12 @@ class SubcTransportPool {
|
|
|
15706
16153
|
const ownsRoute = this.isCurrentSession(key, record) && this.client === client;
|
|
15707
16154
|
if (ownsRoute && isRouteRequestReloadRefusal(error)) {
|
|
15708
16155
|
clearRouteEntry(routeAndEntry.entry);
|
|
15709
|
-
|
|
16156
|
+
lastRefusal = error;
|
|
16157
|
+
if (spentMs() + this.nextRouteReopenDelayMs() >= reloadWaitBudgetMs) {
|
|
15710
16158
|
throw reloadWindowExhaustedError(error, callDeadlineMs);
|
|
15711
16159
|
}
|
|
15712
16160
|
const { delayMs, wait } = this.waitForRouteReopenBackoff();
|
|
15713
|
-
|
|
16161
|
+
scheduledDelayMs = spentMs() + delayMs;
|
|
15714
16162
|
await wait;
|
|
15715
16163
|
routeAndEntry = await openRouteAfterReloadWindow();
|
|
15716
16164
|
reopened = true;
|
|
@@ -15719,7 +16167,12 @@ class SubcTransportPool {
|
|
|
15719
16167
|
if (ownsRoute && !retriedAbsentRoute && isRouteProvenAbsentError(error)) {
|
|
15720
16168
|
retriedAbsentRoute = true;
|
|
15721
16169
|
clearRouteEntry(routeAndEntry.entry);
|
|
15722
|
-
|
|
16170
|
+
if (spentMs() + this.nextRouteReopenDelayMs() >= callDeadlineMs) {
|
|
16171
|
+
throw callDeadlinePassedError(error, callDeadlineMs);
|
|
16172
|
+
}
|
|
16173
|
+
const { delayMs, wait } = this.waitForRouteReopenBackoff();
|
|
16174
|
+
scheduledDelayMs = spentMs() + delayMs;
|
|
16175
|
+
await wait;
|
|
15723
16176
|
routeAndEntry = await openRouteAfterReloadWindow();
|
|
15724
16177
|
reopened = true;
|
|
15725
16178
|
continue;
|
|
@@ -17542,14 +17995,14 @@ function shouldInterruptWaitsForMessage(detachOnUserMessage, operatorText) {
|
|
|
17542
17995
|
return detachOnUserMessage || containsStandaloneDetachKeyword(operatorText);
|
|
17543
17996
|
}
|
|
17544
17997
|
// ../aft-bridge/dist/migration.js
|
|
17545
|
-
import { closeSync as closeSync3, existsSync as existsSync8, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as
|
|
17998
|
+
import { closeSync as closeSync3, existsSync as existsSync8, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
17546
17999
|
import { homedir as homedir8, tmpdir as tmpdir2 } from "node:os";
|
|
17547
|
-
import { basename, dirname as
|
|
18000
|
+
import { basename as basename2, dirname as dirname5, join as join10, resolve as resolve6 } from "node:path";
|
|
17548
18001
|
|
|
17549
18002
|
// ../aft-bridge/dist/paths.js
|
|
17550
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as
|
|
18003
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync5, renameSync as renameSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
17551
18004
|
import { homedir as homedir6 } from "node:os";
|
|
17552
|
-
import { dirname as
|
|
18005
|
+
import { dirname as dirname3, isAbsolute as isAbsolute3, join as join8, resolve as resolve5 } from "node:path";
|
|
17553
18006
|
function homeDir3() {
|
|
17554
18007
|
if (process.platform === "win32")
|
|
17555
18008
|
return process.env.USERPROFILE || process.env.HOME || homedir6();
|
|
@@ -17609,7 +18062,7 @@ function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
|
17609
18062
|
if (existsSync6(harnessPath) || !existsSync6(rootPath))
|
|
17610
18063
|
return harnessPath;
|
|
17611
18064
|
try {
|
|
17612
|
-
mkdirSync2(
|
|
18065
|
+
mkdirSync2(dirname3(harnessPath), { recursive: true });
|
|
17613
18066
|
renameSync3(rootPath, harnessPath);
|
|
17614
18067
|
} catch {}
|
|
17615
18068
|
return harnessPath;
|
|
@@ -17621,7 +18074,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
|
|
|
17621
18074
|
let lastVersion = "";
|
|
17622
18075
|
try {
|
|
17623
18076
|
if (existsSync6(versionFile)) {
|
|
17624
|
-
lastVersion =
|
|
18077
|
+
lastVersion = readFileSync5(versionFile, "utf-8").trim();
|
|
17625
18078
|
}
|
|
17626
18079
|
} catch {
|
|
17627
18080
|
return false;
|
|
@@ -17630,7 +18083,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
|
|
|
17630
18083
|
return false;
|
|
17631
18084
|
if (!lastVersion) {
|
|
17632
18085
|
try {
|
|
17633
|
-
mkdirSync2(
|
|
18086
|
+
mkdirSync2(dirname3(versionFile), { recursive: true });
|
|
17634
18087
|
writeFileSync2(versionFile, currentVersion);
|
|
17635
18088
|
} catch {}
|
|
17636
18089
|
return false;
|
|
@@ -17642,7 +18095,7 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
|
|
|
17642
18095
|
return;
|
|
17643
18096
|
const versionFile = repairRootScopedStorageFile(storageRoot, harness, "last_announced_version");
|
|
17644
18097
|
try {
|
|
17645
|
-
mkdirSync2(
|
|
18098
|
+
mkdirSync2(dirname3(versionFile), { recursive: true });
|
|
17646
18099
|
writeFileSync2(versionFile, currentVersion);
|
|
17647
18100
|
} catch {}
|
|
17648
18101
|
}
|
|
@@ -17691,10 +18144,10 @@ function decodeFileUrl(target) {
|
|
|
17691
18144
|
}
|
|
17692
18145
|
|
|
17693
18146
|
// ../aft-bridge/dist/resolver.js
|
|
17694
|
-
import { closeSync as closeSync2, existsSync as existsSync7, promises as fsPromises, openSync as openSync2, readFileSync as
|
|
18147
|
+
import { closeSync as closeSync2, existsSync as existsSync7, promises as fsPromises, openSync as openSync2, readFileSync as readFileSync6, readSync } from "node:fs";
|
|
17695
18148
|
import { createRequire } from "node:module";
|
|
17696
18149
|
import { homedir as homedir7 } from "node:os";
|
|
17697
|
-
import { delimiter, dirname as
|
|
18150
|
+
import { delimiter, dirname as dirname4, isAbsolute as isAbsolute4, join as join9 } from "node:path";
|
|
17698
18151
|
var ensureBinaryForResolver = ensureBinary;
|
|
17699
18152
|
var npmPlatformPackageReader = null;
|
|
17700
18153
|
var cacheCopiesInFlight = new Map;
|
|
@@ -17847,8 +18300,8 @@ function npmPlatformPackage(ext) {
|
|
|
17847
18300
|
try {
|
|
17848
18301
|
const req = createRequire(import.meta.url);
|
|
17849
18302
|
const manifestPath = req.resolve(`@cortexkit/aft-${platformKey()}/package.json`);
|
|
17850
|
-
const manifest = JSON.parse(
|
|
17851
|
-
const binaryPath = join9(
|
|
18303
|
+
const manifest = JSON.parse(readFileSync6(manifestPath, "utf8"));
|
|
18304
|
+
const binaryPath = join9(dirname4(manifestPath), "bin", `aft${ext}`);
|
|
17852
18305
|
if (typeof manifest.version !== "string" || !existsSync7(binaryPath))
|
|
17853
18306
|
return null;
|
|
17854
18307
|
return { binaryPath, version: normalizeBareVersion(manifest.version) };
|
|
@@ -18102,7 +18555,7 @@ function acquireConfigMigrationLock(lockDir) {
|
|
|
18102
18555
|
if (code !== "EEXIST")
|
|
18103
18556
|
throw err;
|
|
18104
18557
|
try {
|
|
18105
|
-
const ageMs = Date.now() -
|
|
18558
|
+
const ageMs = Date.now() - statSync6(lockDir).mtimeMs;
|
|
18106
18559
|
if (ageMs > 60000) {
|
|
18107
18560
|
rmSync2(lockDir, { recursive: true, force: true });
|
|
18108
18561
|
continue;
|
|
@@ -18116,12 +18569,12 @@ function acquireConfigMigrationLock(lockDir) {
|
|
|
18116
18569
|
}
|
|
18117
18570
|
}
|
|
18118
18571
|
function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
18119
|
-
mkdirSync3(
|
|
18120
|
-
const tmpPath = join10(
|
|
18572
|
+
mkdirSync3(dirname5(targetPath), { recursive: true });
|
|
18573
|
+
const tmpPath = join10(dirname5(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
18121
18574
|
let fd = null;
|
|
18122
18575
|
try {
|
|
18123
18576
|
fd = openSync3(tmpPath, "wx", 384);
|
|
18124
|
-
writeFileSync3(fd,
|
|
18577
|
+
writeFileSync3(fd, readFileSync7(sourcePath));
|
|
18125
18578
|
closeSync3(fd);
|
|
18126
18579
|
fd = null;
|
|
18127
18580
|
renameSync4(tmpPath, targetPath);
|
|
@@ -18138,8 +18591,8 @@ function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
|
18138
18591
|
}
|
|
18139
18592
|
}
|
|
18140
18593
|
function atomicWriteConfigFile(targetPath, content) {
|
|
18141
|
-
mkdirSync3(
|
|
18142
|
-
const tmpPath = join10(
|
|
18594
|
+
mkdirSync3(dirname5(targetPath), { recursive: true });
|
|
18595
|
+
const tmpPath = join10(dirname5(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
18143
18596
|
let fd = null;
|
|
18144
18597
|
try {
|
|
18145
18598
|
fd = openSync3(tmpPath, "wx", 384);
|
|
@@ -18200,11 +18653,11 @@ function markLegacySourcesMovedAside(sources, targetPath, logger) {
|
|
|
18200
18653
|
const desiredMarkerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
|
|
18201
18654
|
const markerPath = nonClobberingSidecarPath(desiredMarkerPath);
|
|
18202
18655
|
try {
|
|
18203
|
-
const original =
|
|
18656
|
+
const original = readFileSync7(source.path, "utf-8");
|
|
18204
18657
|
if (markerPath !== desiredMarkerPath) {
|
|
18205
18658
|
logger?.warn?.(`Preserving existing legacy AFT marker ${desiredMarkerPath}; writing new marker to ${markerPath}`);
|
|
18206
18659
|
}
|
|
18207
|
-
atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath,
|
|
18660
|
+
atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename2(source.path), original));
|
|
18208
18661
|
unlinkSync3(source.path);
|
|
18209
18662
|
info?.(`Moved legacy AFT config ${source.path} aside to ${markerPath}; AFT now reads ${targetPath}`);
|
|
18210
18663
|
} catch (err) {
|
|
@@ -18264,15 +18717,15 @@ function migrateAftConfigFile(opts) {
|
|
|
18264
18717
|
if (existingSources.length === 0) {
|
|
18265
18718
|
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
18266
18719
|
}
|
|
18267
|
-
mkdirSync3(
|
|
18720
|
+
mkdirSync3(dirname5(opts.targetPath), { recursive: true });
|
|
18268
18721
|
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
18269
18722
|
try {
|
|
18270
18723
|
const sources = existingSources.map((source) => ({
|
|
18271
18724
|
...source,
|
|
18272
|
-
content:
|
|
18725
|
+
content: readFileSync7(source.path, "utf-8")
|
|
18273
18726
|
}));
|
|
18274
18727
|
if (existsSync8(opts.targetPath)) {
|
|
18275
|
-
const targetContent =
|
|
18728
|
+
const targetContent = readFileSync7(opts.targetPath, "utf-8");
|
|
18276
18729
|
for (const source of sources) {
|
|
18277
18730
|
if (fileSemanticsMatch(source.content, targetContent))
|
|
18278
18731
|
continue;
|
|
@@ -18323,11 +18776,11 @@ function spawnErrorLabel(error) {
|
|
|
18323
18776
|
function migrationLogPath(newRoot, harness, logger) {
|
|
18324
18777
|
const desired = join10(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
18325
18778
|
try {
|
|
18326
|
-
mkdirSync3(
|
|
18779
|
+
mkdirSync3(dirname5(desired), { recursive: true });
|
|
18327
18780
|
return desired;
|
|
18328
18781
|
} catch (err) {
|
|
18329
18782
|
const fallback = join10(tmpdir2(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
18330
|
-
logger?.warn?.(`Failed to create AFT migration log directory ${
|
|
18783
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname5(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
18331
18784
|
return fallback;
|
|
18332
18785
|
}
|
|
18333
18786
|
}
|
|
@@ -18388,9 +18841,9 @@ async function ensureStorageMigrated(opts) {
|
|
|
18388
18841
|
throw new Error(`AFT storage migration failed (${detail}). ` + `Harness: ${opts.harness}. Legacy: ${legacyRoot}. Target: ${newRoot}. ` + `See log: ${logPath}. ` + `Plugin load aborted to prevent legacy/new state divergence.` + (stderrTail ? ` Stderr tail: ${stderrTail}` : "") + (stdoutTail ? ` Stdout tail: ${stdoutTail}` : ""));
|
|
18389
18842
|
}
|
|
18390
18843
|
// ../aft-bridge/dist/migration-notices.js
|
|
18391
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
18844
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync as renameSync5, rmdirSync, statSync as statSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
18392
18845
|
import { homedir as homedir9 } from "node:os";
|
|
18393
|
-
import { dirname as
|
|
18846
|
+
import { dirname as dirname6, join as join11, resolve as resolve7 } from "node:path";
|
|
18394
18847
|
function migrationNoticeStorePath(env = process.env) {
|
|
18395
18848
|
const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join11(homedir9(), ".local", "state");
|
|
18396
18849
|
return join11(stateHome, "cortexkit", "aft", "migration-notices.json");
|
|
@@ -18400,7 +18853,7 @@ function noticeKey(configPath, digest) {
|
|
|
18400
18853
|
}
|
|
18401
18854
|
function readRecords(storePath) {
|
|
18402
18855
|
try {
|
|
18403
|
-
const parsed = JSON.parse(
|
|
18856
|
+
const parsed = JSON.parse(readFileSync8(storePath, "utf8"));
|
|
18404
18857
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
18405
18858
|
} catch {
|
|
18406
18859
|
return {};
|
|
@@ -18409,7 +18862,7 @@ function readRecords(storePath) {
|
|
|
18409
18862
|
var LOCK_STALE_MS = 1e4;
|
|
18410
18863
|
function withStoreLock(storePath, action) {
|
|
18411
18864
|
const lockPath = `${storePath}.lock`;
|
|
18412
|
-
mkdirSync4(
|
|
18865
|
+
mkdirSync4(dirname6(storePath), { recursive: true });
|
|
18413
18866
|
const deadline = Date.now() + 2000;
|
|
18414
18867
|
for (;; ) {
|
|
18415
18868
|
try {
|
|
@@ -18419,7 +18872,7 @@ function withStoreLock(storePath, action) {
|
|
|
18419
18872
|
if (error.code !== "EEXIST")
|
|
18420
18873
|
throw error;
|
|
18421
18874
|
try {
|
|
18422
|
-
if (Date.now() -
|
|
18875
|
+
if (Date.now() - statSync7(lockPath).mtimeMs > LOCK_STALE_MS)
|
|
18423
18876
|
rmdirSync(lockPath);
|
|
18424
18877
|
} catch {}
|
|
18425
18878
|
if (Date.now() > deadline)
|
|
@@ -18460,9 +18913,9 @@ function deliverMigrationNoticeOnce(options) {
|
|
|
18460
18913
|
}
|
|
18461
18914
|
}
|
|
18462
18915
|
// ../aft-bridge/dist/npm-resolver.js
|
|
18463
|
-
import { readdirSync as readdirSync2, statSync as
|
|
18916
|
+
import { readdirSync as readdirSync2, statSync as statSync8 } from "node:fs";
|
|
18464
18917
|
import { homedir as homedir10 } from "node:os";
|
|
18465
|
-
import { dirname as
|
|
18918
|
+
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join12 } from "node:path";
|
|
18466
18919
|
function defaultDeps() {
|
|
18467
18920
|
return {
|
|
18468
18921
|
platform: process.platform,
|
|
@@ -18476,7 +18929,7 @@ function npmBinaryName(platform) {
|
|
|
18476
18929
|
}
|
|
18477
18930
|
function isFile(p) {
|
|
18478
18931
|
try {
|
|
18479
|
-
return
|
|
18932
|
+
return statSync8(p).isFile();
|
|
18480
18933
|
} catch {
|
|
18481
18934
|
return false;
|
|
18482
18935
|
}
|
|
@@ -18497,7 +18950,7 @@ function npmFromPath(deps) {
|
|
|
18497
18950
|
return null;
|
|
18498
18951
|
}
|
|
18499
18952
|
function npmAdjacentToNode(deps) {
|
|
18500
|
-
const dir =
|
|
18953
|
+
const dir = dirname7(deps.execPath);
|
|
18501
18954
|
return isFile(join12(dir, npmBinaryName(deps.platform))) ? dir : null;
|
|
18502
18955
|
}
|
|
18503
18956
|
function highestVersionedNodeBin(installsDir, name) {
|
|
@@ -18885,8 +19338,8 @@ function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
|
|
|
18885
19338
|
}
|
|
18886
19339
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
18887
19340
|
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
18888
|
-
import { chmodSync as chmodSync2, closeSync as closeSync5, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync11, lstatSync, mkdirSync as mkdirSync5, openSync as openSync5, readdirSync as readdirSync3, readFileSync as
|
|
18889
|
-
import { basename as
|
|
19341
|
+
import { chmodSync as chmodSync2, closeSync as closeSync5, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync11, lstatSync, mkdirSync as mkdirSync5, openSync as openSync5, readdirSync as readdirSync3, readFileSync as readFileSync9, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync6, rmSync as rmSync3, statSync as statSync9, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync5 } from "node:fs";
|
|
19342
|
+
import { basename as basename3, dirname as dirname8, isAbsolute as isAbsolute6, join as join14, relative as relative2, resolve as resolve8, win32 } from "node:path";
|
|
18890
19343
|
import { Readable as Readable2 } from "node:stream";
|
|
18891
19344
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
18892
19345
|
|
|
@@ -19093,7 +19546,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
19093
19546
|
abandoned = true;
|
|
19094
19547
|
} else {
|
|
19095
19548
|
try {
|
|
19096
|
-
const ageMs = Date.now() -
|
|
19549
|
+
const ageMs = Date.now() - statSync9(stagingDir).mtimeMs;
|
|
19097
19550
|
abandoned = ageMs > STALE_LOCK_MS;
|
|
19098
19551
|
} catch {
|
|
19099
19552
|
abandoned = true;
|
|
@@ -19130,7 +19583,7 @@ var REQUIRED_ORT_MAJOR = 1;
|
|
|
19130
19583
|
var REQUIRED_ORT_MIN_MINOR = 20;
|
|
19131
19584
|
var INVALID_ORT_VERSION = "<invalid>";
|
|
19132
19585
|
function parseOnnxVersionFromPath(value) {
|
|
19133
|
-
const name =
|
|
19586
|
+
const name = basename3(value);
|
|
19134
19587
|
const semverish = name.match(/(?:^|[._-])(\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?)(?:\.(?:dylib|dll))?$/);
|
|
19135
19588
|
if (semverish)
|
|
19136
19589
|
return semverish[1].split(/[-+]/, 1)[0];
|
|
@@ -19335,7 +19788,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
19335
19788
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
19336
19789
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
19337
19790
|
}
|
|
19338
|
-
mkdirSync5(
|
|
19791
|
+
mkdirSync5(dirname8(destPath), { recursive: true });
|
|
19339
19792
|
let bytesWritten = 0;
|
|
19340
19793
|
const guard = new TransformStream({
|
|
19341
19794
|
transform(chunk, transformController) {
|
|
@@ -19369,7 +19822,7 @@ function validateExtractedTree(stagingRoot) {
|
|
|
19369
19822
|
const lst = lstatSync(fullPath);
|
|
19370
19823
|
if (lst.isSymbolicLink()) {
|
|
19371
19824
|
const linkTarget = readlinkSync(fullPath);
|
|
19372
|
-
const resolvedTarget = resolve8(
|
|
19825
|
+
const resolvedTarget = resolve8(dirname8(fullPath), linkTarget);
|
|
19373
19826
|
const rel = relative2(realRoot, resolvedTarget);
|
|
19374
19827
|
if (rel.startsWith("..") || isAbsolute6(rel) || win32.isAbsolute(rel)) {
|
|
19375
19828
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -19505,7 +19958,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
19505
19958
|
unlinkSync4(dst);
|
|
19506
19959
|
} catch {}
|
|
19507
19960
|
const dstForContainment = join14(targetRoot, link.name);
|
|
19508
|
-
const resolvedTarget = resolve8(
|
|
19961
|
+
const resolvedTarget = resolve8(dirname8(dstForContainment), link.target);
|
|
19509
19962
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
19510
19963
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
19511
19964
|
if (requiredLibs.has(link.name)) {
|
|
@@ -19557,9 +20010,9 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
19557
20010
|
function readOnnxInstalledMeta(installDir) {
|
|
19558
20011
|
const path = join14(installDir, ONNX_INSTALLED_META_FILE);
|
|
19559
20012
|
try {
|
|
19560
|
-
if (!
|
|
20013
|
+
if (!statSync9(path).isFile())
|
|
19561
20014
|
return null;
|
|
19562
|
-
const raw =
|
|
20015
|
+
const raw = readFileSync9(path, "utf8");
|
|
19563
20016
|
const parsed = JSON.parse(raw);
|
|
19564
20017
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
19565
20018
|
return null;
|
|
@@ -19575,7 +20028,7 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
19575
20028
|
}
|
|
19576
20029
|
function sha256File2(path) {
|
|
19577
20030
|
const hash = createHash5("sha256");
|
|
19578
|
-
hash.update(
|
|
20031
|
+
hash.update(readFileSync9(path));
|
|
19579
20032
|
return hash.digest("hex");
|
|
19580
20033
|
}
|
|
19581
20034
|
function acquireLock(lockPath) {
|
|
@@ -19603,12 +20056,12 @@ ${new Date().toISOString()}
|
|
|
19603
20056
|
let owningPid = null;
|
|
19604
20057
|
let lockMtimeMs = 0;
|
|
19605
20058
|
try {
|
|
19606
|
-
const raw =
|
|
20059
|
+
const raw = readFileSync9(lockPath, "utf8");
|
|
19607
20060
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
19608
20061
|
const parsed = Number.parseInt(firstLine, 10);
|
|
19609
20062
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
19610
20063
|
owningPid = parsed;
|
|
19611
|
-
lockMtimeMs =
|
|
20064
|
+
lockMtimeMs = statSync9(lockPath).mtimeMs;
|
|
19612
20065
|
} catch {
|
|
19613
20066
|
return tryClaim();
|
|
19614
20067
|
}
|
|
@@ -19628,7 +20081,7 @@ function releaseLock(lockPath) {
|
|
|
19628
20081
|
try {
|
|
19629
20082
|
let owningPid = null;
|
|
19630
20083
|
try {
|
|
19631
|
-
const raw =
|
|
20084
|
+
const raw = readFileSync9(lockPath, "utf8");
|
|
19632
20085
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
19633
20086
|
const parsed = Number.parseInt(firstLine, 10);
|
|
19634
20087
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -20319,7 +20772,7 @@ function formatSemanticIndexStatus(status, stage, error, backend) {
|
|
|
20319
20772
|
return status;
|
|
20320
20773
|
}
|
|
20321
20774
|
// src/config.ts
|
|
20322
|
-
import { existsSync as existsSync12, readFileSync as
|
|
20775
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
20323
20776
|
import { homedir as homedir11 } from "node:os";
|
|
20324
20777
|
import { isAbsolute as isAbsolute7, parse as parsePath, resolve as resolvePath } from "node:path";
|
|
20325
20778
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
@@ -25162,6 +25615,17 @@ var SemanticConfigSchema = object({
|
|
|
25162
25615
|
max_input_tokens: number2().int().positive().optional(),
|
|
25163
25616
|
max_files: number2().int().positive().optional()
|
|
25164
25617
|
});
|
|
25618
|
+
var RerankConfigSchema = object({
|
|
25619
|
+
backend: _enum(["off", "onnx", "remote", "synapse"]).optional(),
|
|
25620
|
+
model: string2().trim().min(1).optional(),
|
|
25621
|
+
endpoint: string2().trim().min(1).optional(),
|
|
25622
|
+
api_key_env: string2().trim().min(1).optional(),
|
|
25623
|
+
top_n: number2().int().positive().optional(),
|
|
25624
|
+
timeout_ms: number2().int().positive().optional()
|
|
25625
|
+
});
|
|
25626
|
+
var SearchConfigSchema = object({
|
|
25627
|
+
rerank: RerankConfigSchema.optional()
|
|
25628
|
+
});
|
|
25165
25629
|
var LspExtensionSchema = string2().trim().min(1).refine((value) => value.replace(/^\.+/, "").length > 0, {
|
|
25166
25630
|
message: "Extension must include characters other than leading dots"
|
|
25167
25631
|
});
|
|
@@ -25307,6 +25771,7 @@ var AftConfigFieldsSchema = object({
|
|
|
25307
25771
|
lsp: LspConfigSchema.optional(),
|
|
25308
25772
|
url_fetch_allow_private: boolean2().optional(),
|
|
25309
25773
|
semantic: SemanticConfigSchema.optional(),
|
|
25774
|
+
search: SearchConfigSchema.optional(),
|
|
25310
25775
|
auto_update: boolean2().optional(),
|
|
25311
25776
|
bridge: BridgeConfigSchema.optional(),
|
|
25312
25777
|
subc: SubcConfigSchema.optional(),
|
|
@@ -25551,7 +26016,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
|
|
|
25551
26016
|
let tmpPath = null;
|
|
25552
26017
|
let oldKeys = [];
|
|
25553
26018
|
try {
|
|
25554
|
-
const content =
|
|
26019
|
+
const content = readFileSync10(configPath, "utf-8");
|
|
25555
26020
|
const rawConfig = import_comment_json.parse(content);
|
|
25556
26021
|
if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
|
|
25557
26022
|
return { migrated: false, oldKeys: [] };
|
|
@@ -25618,6 +26083,18 @@ function parseConfigPartially(rawConfig) {
|
|
|
25618
26083
|
return partialConfig;
|
|
25619
26084
|
}
|
|
25620
26085
|
var configLoadErrors = [];
|
|
26086
|
+
var configValidationErrors = [];
|
|
26087
|
+
var configLoadSources = [];
|
|
26088
|
+
var configLoadTexts = new Map;
|
|
26089
|
+
function getConfigLoadSources() {
|
|
26090
|
+
return configLoadSources;
|
|
26091
|
+
}
|
|
26092
|
+
function getConfigLoadTexts() {
|
|
26093
|
+
return configLoadTexts;
|
|
26094
|
+
}
|
|
26095
|
+
function getConfigValidationErrors() {
|
|
26096
|
+
return configValidationErrors;
|
|
26097
|
+
}
|
|
25621
26098
|
function getConfigLoadErrors() {
|
|
25622
26099
|
return configLoadErrors;
|
|
25623
26100
|
}
|
|
@@ -25650,7 +26127,9 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
25650
26127
|
if (!existsSync12(configPath)) {
|
|
25651
26128
|
return null;
|
|
25652
26129
|
}
|
|
25653
|
-
const content =
|
|
26130
|
+
const content = readFileSync10(configPath, "utf-8");
|
|
26131
|
+
configLoadSources.push(configPath);
|
|
26132
|
+
configLoadTexts.set(configPath, content);
|
|
25654
26133
|
const rawConfig = import_comment_json.parse(content);
|
|
25655
26134
|
migrateRawConfig(rawConfig, configPath, { log: log2, warn: warn2 });
|
|
25656
26135
|
cleanConfig = stripJsoncSymbols(rawConfig);
|
|
@@ -25695,6 +26174,7 @@ function loadConfigFromPath(configPath, tier) {
|
|
|
25695
26174
|
} else {
|
|
25696
26175
|
const errorMsg = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ");
|
|
25697
26176
|
warn2(`Config validation error in ${configPath}: ${errorMsg}`);
|
|
26177
|
+
configValidationErrors.push({ path: configPath, message: errorMsg });
|
|
25698
26178
|
parsed = parseConfigPartially(cleanConfig);
|
|
25699
26179
|
}
|
|
25700
26180
|
if (!parsed)
|
|
@@ -25891,14 +26371,33 @@ function getStrippedTopLevelKeys(override) {
|
|
|
25891
26371
|
for (const tool of partitionProjectDisables(override.disabled_tools).ignored) {
|
|
25892
26372
|
stripped.push(`disabled_tools.${tool}`);
|
|
25893
26373
|
}
|
|
26374
|
+
stripped.push(...projectRerankStrippedKeys(override.search?.rerank));
|
|
26375
|
+
return stripped;
|
|
26376
|
+
}
|
|
26377
|
+
function projectRerankStrippedKeys(rerank) {
|
|
26378
|
+
if (rerank === undefined)
|
|
26379
|
+
return [];
|
|
26380
|
+
const stripped = [];
|
|
26381
|
+
if (rerank.backend !== undefined && rerank.backend !== "off")
|
|
26382
|
+
stripped.push("search.rerank.backend");
|
|
26383
|
+
for (const key of ["model", "endpoint", "api_key_env", "top_n", "timeout_ms"]) {
|
|
26384
|
+
if (rerank[key] !== undefined)
|
|
26385
|
+
stripped.push(`search.rerank.${key}`);
|
|
26386
|
+
}
|
|
25894
26387
|
return stripped;
|
|
25895
26388
|
}
|
|
26389
|
+
function mergeProjectSearchConfig(base, project) {
|
|
26390
|
+
if (project?.rerank?.backend !== "off")
|
|
26391
|
+
return base;
|
|
26392
|
+
return { ...base, rerank: { ...base?.rerank, backend: "off" } };
|
|
26393
|
+
}
|
|
25896
26394
|
function mergeConfigs(base, override) {
|
|
25897
26395
|
const disabledTools = unionDisabledTools(base.disabled_tools, partitionProjectDisables(override.disabled_tools).accepted);
|
|
25898
26396
|
const indexes = mergeIndexes(base.indexes, override.indexes, true);
|
|
25899
26397
|
const formatter = { ...base.formatter, ...override.formatter };
|
|
25900
26398
|
const checker = { ...base.checker, ...override.checker };
|
|
25901
26399
|
const semantic = mergeSemanticConfig(base.semantic, override.semantic);
|
|
26400
|
+
const search = mergeProjectSearchConfig(base.search, override.search);
|
|
25902
26401
|
const lsp = mergeLspConfig(base.lsp, override.lsp);
|
|
25903
26402
|
const experimental = mergeExperimentalConfig(base.experimental, override.experimental);
|
|
25904
26403
|
const bash = mergeBashConfig(base.bash, override.bash);
|
|
@@ -25928,6 +26427,7 @@ function mergeConfigs(base, override) {
|
|
|
25928
26427
|
...pi !== undefined ? { pi } : {},
|
|
25929
26428
|
experimental,
|
|
25930
26429
|
semantic,
|
|
26430
|
+
search,
|
|
25931
26431
|
...bridge !== undefined ? { bridge } : {},
|
|
25932
26432
|
...indexes !== undefined ? { indexes } : {},
|
|
25933
26433
|
...disabledTools !== undefined ? { disabled_tools: disabledTools } : {}
|
|
@@ -25992,6 +26492,9 @@ function buildConfigTierConfigureParams(projectDirectory, processState = {}) {
|
|
|
25992
26492
|
}
|
|
25993
26493
|
function loadAftConfig(projectDirectory) {
|
|
25994
26494
|
configLoadErrors = [];
|
|
26495
|
+
configValidationErrors = [];
|
|
26496
|
+
configLoadSources = [];
|
|
26497
|
+
configLoadTexts = new Map;
|
|
25995
26498
|
configLoadNotices = [];
|
|
25996
26499
|
semanticInputSupplied = false;
|
|
25997
26500
|
const { userConfigPath, projectConfigPath } = resolveAftConfigPaths(projectDirectory);
|
|
@@ -39824,16 +40327,29 @@ function markBridgeEnd() {
|
|
|
39824
40327
|
slot.bridgeEnd = performance.now();
|
|
39825
40328
|
}
|
|
39826
40329
|
}
|
|
40330
|
+
async function measurePreStage(stage, operation) {
|
|
40331
|
+
const start = performance.now();
|
|
40332
|
+
try {
|
|
40333
|
+
return await operation();
|
|
40334
|
+
} finally {
|
|
40335
|
+
const slot = perfStore.getStore();
|
|
40336
|
+
if (slot) {
|
|
40337
|
+
slot.stages ??= {};
|
|
40338
|
+
slot.stages[stage] = (slot.stages[stage] ?? 0) + performance.now() - start;
|
|
40339
|
+
}
|
|
40340
|
+
}
|
|
40341
|
+
}
|
|
39827
40342
|
function emit(slot) {
|
|
40343
|
+
const stages = slot.stages ? ` directory=${Math.round(slot.stages.directory ?? 0)}ms permission=${Math.round(slot.stages.permission ?? 0)}ms capability=${Math.round(slot.stages.capability ?? 0)}ms` : "";
|
|
39828
40344
|
const t3 = performance.now();
|
|
39829
40345
|
const total = Math.round(t3 - slot.t0);
|
|
39830
40346
|
if (slot.bridgeStart !== undefined && slot.bridgeEnd !== undefined) {
|
|
39831
40347
|
const pre = Math.round(slot.bridgeStart - slot.t0);
|
|
39832
40348
|
const bridge = Math.round(slot.bridgeEnd - slot.bridgeStart);
|
|
39833
40349
|
const post = Math.round(t3 - slot.bridgeEnd);
|
|
39834
|
-
sessionLog(slot.sessionID, `perf tool=${slot.tool} total=${total}ms pre=${pre}ms bridge=${bridge}ms post=${post}ms`);
|
|
40350
|
+
sessionLog(slot.sessionID, `perf tool=${slot.tool} total=${total}ms pre=${pre}ms bridge=${bridge}ms post=${post}ms${stages}`);
|
|
39835
40351
|
} else {
|
|
39836
|
-
sessionLog(slot.sessionID, `perf tool=${slot.tool} total=${total}ms (no bridge call)`);
|
|
40352
|
+
sessionLog(slot.sessionID, `perf tool=${slot.tool} total=${total}ms (no bridge call)${stages}`);
|
|
39837
40353
|
}
|
|
39838
40354
|
}
|
|
39839
40355
|
function instrumentToolMap(tools) {
|
|
@@ -40063,10 +40579,10 @@ import {
|
|
|
40063
40579
|
createReadStream as createReadStream2,
|
|
40064
40580
|
existsSync as existsSync15,
|
|
40065
40581
|
mkdirSync as mkdirSync7,
|
|
40066
|
-
readFileSync as
|
|
40582
|
+
readFileSync as readFileSync13,
|
|
40067
40583
|
renameSync as renameSync9,
|
|
40068
40584
|
rmSync as rmSync5,
|
|
40069
|
-
statSync as
|
|
40585
|
+
statSync as statSync11,
|
|
40070
40586
|
writeFileSync as writeFileSync8
|
|
40071
40587
|
} from "node:fs";
|
|
40072
40588
|
import { join as join17 } from "node:path";
|
|
@@ -40077,10 +40593,10 @@ import {
|
|
|
40077
40593
|
closeSync as closeSync6,
|
|
40078
40594
|
mkdirSync as mkdirSync6,
|
|
40079
40595
|
openSync as openSync6,
|
|
40080
|
-
readFileSync as
|
|
40596
|
+
readFileSync as readFileSync11,
|
|
40081
40597
|
renameSync as renameSync8,
|
|
40082
40598
|
rmSync as rmSync4,
|
|
40083
|
-
statSync as
|
|
40599
|
+
statSync as statSync10,
|
|
40084
40600
|
unlinkSync as unlinkSync6,
|
|
40085
40601
|
writeFileSync as writeFileSync7
|
|
40086
40602
|
} from "node:fs";
|
|
@@ -40103,7 +40619,7 @@ function lspBinDir(npmPackage) {
|
|
|
40103
40619
|
function isInstalled(npmPackage, binary) {
|
|
40104
40620
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
40105
40621
|
try {
|
|
40106
|
-
if (
|
|
40622
|
+
if (statSync10(join15(lspBinDir(npmPackage), candidate)).isFile())
|
|
40107
40623
|
return true;
|
|
40108
40624
|
} catch {}
|
|
40109
40625
|
}
|
|
@@ -40131,9 +40647,9 @@ function writeInstalledMetaIn(installDir, version, sha256) {
|
|
|
40131
40647
|
function readInstalledMetaIn(installDir) {
|
|
40132
40648
|
const path = join15(installDir, INSTALLED_META_FILE);
|
|
40133
40649
|
try {
|
|
40134
|
-
if (!
|
|
40650
|
+
if (!statSync10(path).isFile())
|
|
40135
40651
|
return null;
|
|
40136
|
-
const raw =
|
|
40652
|
+
const raw = readFileSync11(path, "utf8");
|
|
40137
40653
|
const parsed = JSON.parse(raw);
|
|
40138
40654
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
40139
40655
|
return null;
|
|
@@ -40202,12 +40718,12 @@ ${token}
|
|
|
40202
40718
|
let owningPid = null;
|
|
40203
40719
|
let lockMtimeMs = 0;
|
|
40204
40720
|
try {
|
|
40205
|
-
const raw =
|
|
40721
|
+
const raw = readFileSync11(lock, "utf8");
|
|
40206
40722
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
40207
40723
|
const parsed = Number.parseInt(firstLine, 10);
|
|
40208
40724
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
40209
40725
|
owningPid = parsed;
|
|
40210
|
-
lockMtimeMs =
|
|
40726
|
+
lockMtimeMs = statSync10(lock).mtimeMs;
|
|
40211
40727
|
} catch {
|
|
40212
40728
|
return tryClaim();
|
|
40213
40729
|
}
|
|
@@ -40241,7 +40757,7 @@ function releaseInstallLock(lockKey, acquisitionToken) {
|
|
|
40241
40757
|
let owningPid = null;
|
|
40242
40758
|
let owningToken = "";
|
|
40243
40759
|
try {
|
|
40244
|
-
const raw =
|
|
40760
|
+
const raw = readFileSync11(lock, "utf8");
|
|
40245
40761
|
const lines = raw.split(/\r?\n/);
|
|
40246
40762
|
const parsed = Number.parseInt(lines[0]?.trim() ?? "", 10);
|
|
40247
40763
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -40288,7 +40804,7 @@ function autoInstallStampPath() {
|
|
|
40288
40804
|
}
|
|
40289
40805
|
function hasRecentAutoInstallStamp(path) {
|
|
40290
40806
|
try {
|
|
40291
|
-
const parsed = JSON.parse(
|
|
40807
|
+
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
40292
40808
|
return typeof parsed.lastRunMs === "number" && Number.isFinite(parsed.lastRunMs) && Math.abs(Date.now() - parsed.lastRunMs) < AUTO_INSTALL_WINDOW_MS;
|
|
40293
40809
|
} catch {
|
|
40294
40810
|
return false;
|
|
@@ -40296,7 +40812,7 @@ function hasRecentAutoInstallStamp(path) {
|
|
|
40296
40812
|
}
|
|
40297
40813
|
function readAutoInstallLockOwner(path) {
|
|
40298
40814
|
try {
|
|
40299
|
-
const parsed = JSON.parse(
|
|
40815
|
+
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
40300
40816
|
if (typeof parsed.pid !== "number" || typeof parsed.startedMs !== "number" || typeof parsed.token !== "string") {
|
|
40301
40817
|
return null;
|
|
40302
40818
|
}
|
|
@@ -40309,7 +40825,7 @@ function autoInstallLockIsStale(path) {
|
|
|
40309
40825
|
const owner = readAutoInstallLockOwner(path);
|
|
40310
40826
|
let age = Number.POSITIVE_INFINITY;
|
|
40311
40827
|
try {
|
|
40312
|
-
age = Math.abs(Date.now() -
|
|
40828
|
+
age = Math.abs(Date.now() - statSync10(path).mtimeMs);
|
|
40313
40829
|
} catch {
|
|
40314
40830
|
return true;
|
|
40315
40831
|
}
|
|
@@ -40387,7 +40903,7 @@ var VERSION_CHECK_FILE = ".aft-version-check";
|
|
|
40387
40903
|
function readVersionCheck(npmPackage) {
|
|
40388
40904
|
const file = join15(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
40389
40905
|
try {
|
|
40390
|
-
const raw =
|
|
40906
|
+
const raw = readFileSync11(file, "utf8");
|
|
40391
40907
|
const parsed = JSON.parse(raw);
|
|
40392
40908
|
if (typeof parsed.last_checked === "string") {
|
|
40393
40909
|
return {
|
|
@@ -40490,6 +41006,13 @@ var NPM_LSP_TABLE = [
|
|
|
40490
41006
|
extensions: ["ts", "tsx", "js", "jsx", "mjs", "cjs", "mts", "cts"],
|
|
40491
41007
|
rootMarkers: ["tsconfig.json", "jsconfig.json", "package.json"]
|
|
40492
41008
|
},
|
|
41009
|
+
{
|
|
41010
|
+
id: "typescript-sdk",
|
|
41011
|
+
npm: "typescript",
|
|
41012
|
+
binary: "tsserver",
|
|
41013
|
+
extensions: ["ts", "tsx", "js", "jsx", "mjs", "cjs", "mts", "cts"],
|
|
41014
|
+
rootMarkers: ["tsconfig.json", "jsconfig.json", "package.json"]
|
|
41015
|
+
},
|
|
40493
41016
|
{
|
|
40494
41017
|
id: "python",
|
|
40495
41018
|
npm: "pyright",
|
|
@@ -40564,7 +41087,7 @@ var NPM_LSP_TABLE = [
|
|
|
40564
41087
|
];
|
|
40565
41088
|
|
|
40566
41089
|
// src/lsp-project-relevance.ts
|
|
40567
|
-
import { existsSync as existsSync14, readdirSync as readdirSync4, readFileSync as
|
|
41090
|
+
import { existsSync as existsSync14, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "node:fs";
|
|
40568
41091
|
import { join as join16 } from "node:path";
|
|
40569
41092
|
var MAX_WALK_DIRS = 200;
|
|
40570
41093
|
var MAX_WALK_DEPTH = 4;
|
|
@@ -40606,7 +41129,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
40606
41129
|
}
|
|
40607
41130
|
function readPackageJson(projectRoot) {
|
|
40608
41131
|
try {
|
|
40609
|
-
const raw =
|
|
41132
|
+
const raw = readFileSync12(join16(projectRoot, "package.json"), "utf8");
|
|
40610
41133
|
const parsed = JSON.parse(raw);
|
|
40611
41134
|
if (typeof parsed !== "object" || parsed === null)
|
|
40612
41135
|
return null;
|
|
@@ -40954,7 +41477,7 @@ function hashInstalledBinary(spec) {
|
|
|
40954
41477
|
let pathToHash = null;
|
|
40955
41478
|
for (const p of candidates) {
|
|
40956
41479
|
try {
|
|
40957
|
-
if (
|
|
41480
|
+
if (statSync11(p).isFile()) {
|
|
40958
41481
|
pathToHash = p;
|
|
40959
41482
|
break;
|
|
40960
41483
|
}
|
|
@@ -40980,14 +41503,14 @@ function installedBinaryPath(spec) {
|
|
|
40980
41503
|
] : [lspBinaryPath(spec.npm, spec.binary)];
|
|
40981
41504
|
for (const candidate of candidates) {
|
|
40982
41505
|
try {
|
|
40983
|
-
if (
|
|
41506
|
+
if (statSync11(candidate).isFile())
|
|
40984
41507
|
return candidate;
|
|
40985
41508
|
} catch {}
|
|
40986
41509
|
}
|
|
40987
41510
|
return null;
|
|
40988
41511
|
}
|
|
40989
41512
|
function sha256OfFileSync(path) {
|
|
40990
|
-
return createHash7("sha256").update(
|
|
41513
|
+
return createHash7("sha256").update(readFileSync13(path)).digest("hex");
|
|
40991
41514
|
}
|
|
40992
41515
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
40993
41516
|
const packageDir = lspPackageDir(spec.npm);
|
|
@@ -41030,7 +41553,7 @@ function runAutoInstall(projectRoot, config, fetchImpl = fetch) {
|
|
|
41030
41553
|
if (isInstalled(spec.npm, spec.binary) && validateCachedNpmInstall(spec)) {
|
|
41031
41554
|
cachedBinDirs.push(lspBinDir(spec.npm));
|
|
41032
41555
|
}
|
|
41033
|
-
if (config.disabled.has(spec.id)) {
|
|
41556
|
+
if (config.disabled.has(spec.id) || spec.id === "typescript-sdk" && config.disabled.has("typescript")) {
|
|
41034
41557
|
skipped.push({ id: spec.id, reason: "disabled by config" });
|
|
41035
41558
|
continue;
|
|
41036
41559
|
}
|
|
@@ -41086,16 +41609,16 @@ import {
|
|
|
41086
41609
|
lstatSync as lstatSync2,
|
|
41087
41610
|
mkdirSync as mkdirSync8,
|
|
41088
41611
|
readdirSync as readdirSync5,
|
|
41089
|
-
readFileSync as
|
|
41612
|
+
readFileSync as readFileSync14,
|
|
41090
41613
|
readlinkSync as readlinkSync2,
|
|
41091
41614
|
realpathSync as realpathSync4,
|
|
41092
41615
|
renameSync as renameSync10,
|
|
41093
41616
|
rmSync as rmSync6,
|
|
41094
|
-
statSync as
|
|
41617
|
+
statSync as statSync12,
|
|
41095
41618
|
unlinkSync as unlinkSync7,
|
|
41096
41619
|
writeFileSync as writeFileSync9
|
|
41097
41620
|
} from "node:fs";
|
|
41098
|
-
import { dirname as
|
|
41621
|
+
import { dirname as dirname9, join as join18, relative as relative3, resolve as resolve10 } from "node:path";
|
|
41099
41622
|
import { Readable as Readable3 } from "node:stream";
|
|
41100
41623
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
41101
41624
|
|
|
@@ -41204,7 +41727,7 @@ function installFailureMarkerPath(spec) {
|
|
|
41204
41727
|
}
|
|
41205
41728
|
function readInstallFailureMarker(spec) {
|
|
41206
41729
|
try {
|
|
41207
|
-
const marker = JSON.parse(
|
|
41730
|
+
const marker = JSON.parse(readFileSync14(installFailureMarkerPath(spec), "utf8"));
|
|
41208
41731
|
if (typeof marker.release !== "string" || typeof marker.sha256 !== "string" || typeof marker.error !== "string" || typeof marker.at !== "string" || !Number.isFinite(Date.parse(marker.at))) {
|
|
41209
41732
|
return null;
|
|
41210
41733
|
}
|
|
@@ -41218,7 +41741,7 @@ function writeInstallFailureMarker(spec, release, sha256, installError) {
|
|
|
41218
41741
|
const markerError = installError.replace(/\s+/g, " ").trim();
|
|
41219
41742
|
const tempPath = `${path}.tmp-${process.pid}-${randomBytes4(6).toString("hex")}`;
|
|
41220
41743
|
try {
|
|
41221
|
-
mkdirSync8(
|
|
41744
|
+
mkdirSync8(dirname9(path), { recursive: true });
|
|
41222
41745
|
writeFileSync9(tempPath, `${JSON.stringify({ release, sha256, error: markerError, at: new Date().toISOString() })}
|
|
41223
41746
|
`, { encoding: "utf8", mode: 384 });
|
|
41224
41747
|
renameSync10(tempPath, path);
|
|
@@ -41247,7 +41770,7 @@ function ghBinaryPath(spec, platform) {
|
|
|
41247
41770
|
function isGithubInstalled(spec, platform) {
|
|
41248
41771
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
41249
41772
|
try {
|
|
41250
|
-
if (
|
|
41773
|
+
if (statSync12(join18(ghBinDir(spec), candidate)).isFile())
|
|
41251
41774
|
return true;
|
|
41252
41775
|
} catch {}
|
|
41253
41776
|
}
|
|
@@ -41261,9 +41784,9 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
41261
41784
|
function readGithubInstalledMetaIn(installDir) {
|
|
41262
41785
|
try {
|
|
41263
41786
|
const path = join18(installDir, INSTALLED_META_FILE2);
|
|
41264
|
-
if (!
|
|
41787
|
+
if (!statSync12(path).isFile())
|
|
41265
41788
|
return null;
|
|
41266
|
-
const parsed = JSON.parse(
|
|
41789
|
+
const parsed = JSON.parse(readFileSync14(path, "utf8"));
|
|
41267
41790
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
41268
41791
|
return null;
|
|
41269
41792
|
return {
|
|
@@ -41304,7 +41827,7 @@ function sha256OfFile(path) {
|
|
|
41304
41827
|
});
|
|
41305
41828
|
}
|
|
41306
41829
|
function sha256OfFileSync2(path) {
|
|
41307
|
-
return createHash8("sha256").update(
|
|
41830
|
+
return createHash8("sha256").update(readFileSync14(path)).digest("hex");
|
|
41308
41831
|
}
|
|
41309
41832
|
async function fetchReleaseByTag(githubRepo, tag, fetchImpl, signal) {
|
|
41310
41833
|
const candidates = [];
|
|
@@ -41480,7 +42003,7 @@ async function downloadFile(url, destPath, fetchImpl, assetSize, signal) {
|
|
|
41480
42003
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
|
|
41481
42004
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
|
|
41482
42005
|
}
|
|
41483
|
-
mkdirSync8(
|
|
42006
|
+
mkdirSync8(dirname9(destPath), { recursive: true });
|
|
41484
42007
|
let bytesWritten = 0;
|
|
41485
42008
|
const guard = new TransformStream({
|
|
41486
42009
|
transform(chunk, controller) {
|
|
@@ -41650,7 +42173,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
41650
42173
|
const dest = join18(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
41651
42174
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
41652
42175
|
try {
|
|
41653
|
-
mkdirSync8(
|
|
42176
|
+
mkdirSync8(dirname9(dest), { recursive: true });
|
|
41654
42177
|
rmSync6(dest, { recursive: true, force: true });
|
|
41655
42178
|
renameSync10(packageDir, dest);
|
|
41656
42179
|
} catch (err) {
|
|
@@ -41662,7 +42185,7 @@ function validateCachedGithubInstall(spec, platform) {
|
|
|
41662
42185
|
const meta = readGithubInstalledMetaIn(packageDir);
|
|
41663
42186
|
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join18(ghBinDir(spec), candidate)).find((candidate) => {
|
|
41664
42187
|
try {
|
|
41665
|
-
return
|
|
42188
|
+
return statSync12(candidate).isFile();
|
|
41666
42189
|
} catch {
|
|
41667
42190
|
return false;
|
|
41668
42191
|
}
|
|
@@ -41780,7 +42303,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
41780
42303
|
return { ok: false, sha256: archiveSha256, error: message };
|
|
41781
42304
|
}
|
|
41782
42305
|
const targetBinary = ghBinaryPath(spec, platform);
|
|
41783
|
-
mkdirSync8(
|
|
42306
|
+
mkdirSync8(dirname9(targetBinary), { recursive: true });
|
|
41784
42307
|
try {
|
|
41785
42308
|
copyFileSync3(innerBinaryPath, targetBinary);
|
|
41786
42309
|
if (platform !== "win32") {
|
|
@@ -42309,14 +42832,16 @@ async function assertExternalDirectoryPermission(ctx, context, target, options)
|
|
|
42309
42832
|
const directory = root ? normalizePath(root) : root;
|
|
42310
42833
|
const rawWorktree = context.worktree;
|
|
42311
42834
|
const worktree = rawWorktree && rawWorktree !== "/" ? normalizePath(rawWorktree) : rawWorktree;
|
|
42835
|
+
const restrictToProjectRoot = ctx.config.restrict_to_project_root === true;
|
|
42312
42836
|
if (directory && containsPath(directory, absoluteTarget))
|
|
42313
42837
|
return;
|
|
42314
|
-
if (worktree && worktree !== "/" && worktree !== directory && containsPath(worktree, absoluteTarget)) {
|
|
42838
|
+
if (!restrictToProjectRoot && worktree && worktree !== "/" && worktree !== directory && containsPath(worktree, absoluteTarget)) {
|
|
42315
42839
|
return;
|
|
42316
42840
|
}
|
|
42317
|
-
if (
|
|
42318
|
-
if (options?.serverValidatedRead === true)
|
|
42841
|
+
if (restrictToProjectRoot) {
|
|
42842
|
+
if (options?.serverValidatedRead === true && await isSessionOwnedBashArtifact(ctx, context, absoluteTarget)) {
|
|
42319
42843
|
return;
|
|
42844
|
+
}
|
|
42320
42845
|
notifyRestrictBlocked(ctx, context, absoluteTarget);
|
|
42321
42846
|
return restrictDenialMessage(absoluteTarget);
|
|
42322
42847
|
}
|
|
@@ -42846,8 +43371,87 @@ function projectV2Tool(name, definition, location, consumers = {}) {
|
|
|
42846
43371
|
}
|
|
42847
43372
|
|
|
42848
43373
|
// src/tools/hoisted.ts
|
|
43374
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
42849
43375
|
import * as path4 from "node:path";
|
|
42850
43376
|
|
|
43377
|
+
// src/shared/read-vision.ts
|
|
43378
|
+
var VISION_HOST_TIMEOUT_MS = 1500;
|
|
43379
|
+
var states = new WeakMap;
|
|
43380
|
+
function stateFor2(client) {
|
|
43381
|
+
let state = states.get(client);
|
|
43382
|
+
if (!state) {
|
|
43383
|
+
state = { models: new Map, history: new Map, capabilities: new Map };
|
|
43384
|
+
states.set(client, state);
|
|
43385
|
+
}
|
|
43386
|
+
return state;
|
|
43387
|
+
}
|
|
43388
|
+
function rememberReadModel(client, sessionID, model) {
|
|
43389
|
+
stateFor2(client).models.set(sessionID, model);
|
|
43390
|
+
}
|
|
43391
|
+
async function bounded(call) {
|
|
43392
|
+
let timer;
|
|
43393
|
+
try {
|
|
43394
|
+
return await Promise.race([
|
|
43395
|
+
Promise.resolve().then(call),
|
|
43396
|
+
new Promise((resolve) => {
|
|
43397
|
+
timer = setTimeout(() => resolve(undefined), VISION_HOST_TIMEOUT_MS);
|
|
43398
|
+
})
|
|
43399
|
+
]);
|
|
43400
|
+
} catch {
|
|
43401
|
+
return;
|
|
43402
|
+
} finally {
|
|
43403
|
+
clearTimeout(timer);
|
|
43404
|
+
}
|
|
43405
|
+
}
|
|
43406
|
+
function record3(value) {
|
|
43407
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
43408
|
+
}
|
|
43409
|
+
async function currentSessionVisionCapability(client, sessionID) {
|
|
43410
|
+
if (!sessionID)
|
|
43411
|
+
return;
|
|
43412
|
+
const state = stateFor2(client);
|
|
43413
|
+
let model = state.models.get(sessionID);
|
|
43414
|
+
if (!model) {
|
|
43415
|
+
let pending = state.history.get(sessionID);
|
|
43416
|
+
if (!pending) {
|
|
43417
|
+
pending = bounded(() => resolvePromptContext(client, sessionID)).then((context) => context?.model);
|
|
43418
|
+
state.history.set(sessionID, pending);
|
|
43419
|
+
pending.finally(() => state.history.delete(sessionID));
|
|
43420
|
+
}
|
|
43421
|
+
const historical = await pending;
|
|
43422
|
+
model = state.models.get(sessionID) ?? historical;
|
|
43423
|
+
}
|
|
43424
|
+
if (!model)
|
|
43425
|
+
return;
|
|
43426
|
+
const currentModel = model;
|
|
43427
|
+
const key = JSON.stringify([model.providerID, model.modelID]);
|
|
43428
|
+
let capability = state.capabilities.get(key);
|
|
43429
|
+
if (!capability) {
|
|
43430
|
+
capability = (async () => {
|
|
43431
|
+
const api = client.provider;
|
|
43432
|
+
if (!api?.list)
|
|
43433
|
+
return;
|
|
43434
|
+
const list = api.list.bind(api);
|
|
43435
|
+
const listed = record3(await bounded(list));
|
|
43436
|
+
const catalog = record3(listed?.data) ?? listed;
|
|
43437
|
+
const providers = catalog?.all ?? catalog?.providers;
|
|
43438
|
+
if (!Array.isArray(providers))
|
|
43439
|
+
return;
|
|
43440
|
+
const provider = providers.map(record3).find((entry) => entry?.id === currentModel.providerID);
|
|
43441
|
+
const models = provider?.models;
|
|
43442
|
+
const entry = record3(Array.isArray(models) ? models.find((entry) => record3(entry)?.id === currentModel.modelID) : record3(models)?.[currentModel.modelID]);
|
|
43443
|
+
const inputs = record3(entry?.modalities)?.input;
|
|
43444
|
+
return Array.isArray(inputs) ? inputs.includes("image") : typeof entry?.attachment === "boolean" ? entry.attachment : undefined;
|
|
43445
|
+
})();
|
|
43446
|
+
state.capabilities.set(key, capability);
|
|
43447
|
+
capability.then((value) => {
|
|
43448
|
+
if (value === undefined)
|
|
43449
|
+
state.capabilities.delete(key);
|
|
43450
|
+
});
|
|
43451
|
+
}
|
|
43452
|
+
return capability;
|
|
43453
|
+
}
|
|
43454
|
+
|
|
42851
43455
|
// src/shared/subagent-detect.ts
|
|
42852
43456
|
import { Effect as Effect2 } from "effect";
|
|
42853
43457
|
var CACHE_MAX_ENTRIES2 = 200;
|
|
@@ -43434,7 +44038,7 @@ A notification will fire when the pattern matches or the task exits.`;
|
|
|
43434
44038
|
const data = await waitForBashStatus(ctx, context, taskId, undefined, waitFor, effectiveWaitMs);
|
|
43435
44039
|
const waited = data.waited;
|
|
43436
44040
|
if (waited?.reason === "user_message") {
|
|
43437
|
-
const convertedText = await convertToAsyncWatchOnAbort(ctx, context, taskId, waitFor, coerceBoolean(args.once, true));
|
|
44041
|
+
const convertedText = await convertToAsyncWatchOnAbort(ctx, context, taskId, waitFor, coerceBoolean(args.once, true), waited.elapsed_ms);
|
|
43438
44042
|
const metadata = context.metadata;
|
|
43439
44043
|
metadata?.({ taskId, status: data.status, waited, convertedToAsync: true });
|
|
43440
44044
|
return convertedText;
|
|
@@ -43446,9 +44050,10 @@ A notification will fire when the pattern matches or the task exits.`;
|
|
|
43446
44050
|
}
|
|
43447
44051
|
};
|
|
43448
44052
|
}
|
|
43449
|
-
async function convertToAsyncWatchOnAbort(ctx, context, taskId, waitFor, once) {
|
|
44053
|
+
async function convertToAsyncWatchOnAbort(ctx, context, taskId, waitFor, once, elapsedMs) {
|
|
44054
|
+
const interrupted = `Sync watch for task ${taskId} was interrupted because you sent a message after ${elapsedMs}ms of waiting. `;
|
|
43450
44055
|
if (!waitFor) {
|
|
43451
|
-
return
|
|
44056
|
+
return interrupted + `The task is still running in the background. A completion reminder will be ` + `delivered automatically when the task exits; don't poll bash_status.`;
|
|
43452
44057
|
}
|
|
43453
44058
|
const notifyParams = {
|
|
43454
44059
|
task_id: taskId,
|
|
@@ -43463,12 +44068,12 @@ async function convertToAsyncWatchOnAbort(ctx, context, taskId, waitFor, once) {
|
|
|
43463
44068
|
const registered = await callBashBridge(ctx, context, "bash_notify", notifyParams);
|
|
43464
44069
|
if (registered.success === false) {
|
|
43465
44070
|
unmarkExplicitControl(context.sessionID, taskId);
|
|
43466
|
-
return
|
|
44071
|
+
return interrupted + `Auto-registering an async watch failed (${String(registered.message ?? "unknown error")}). ` + `The task is still running in the background. A completion reminder will be ` + `delivered automatically when the task exits.`;
|
|
43467
44072
|
}
|
|
43468
|
-
return
|
|
44073
|
+
return interrupted + `The wait has been converted to an async watch (${registered.watch_id}). ` + `A notification will fire when the pattern matches or the task exits.`;
|
|
43469
44074
|
} catch (err) {
|
|
43470
44075
|
unmarkExplicitControl(context.sessionID, taskId);
|
|
43471
|
-
return
|
|
44076
|
+
return interrupted + `Auto-registering an async watch failed (${err instanceof Error ? err.message : String(err)}). ` + `The task is still running in the background. A completion reminder will be ` + `delivered automatically when the task exits.`;
|
|
43472
44077
|
}
|
|
43473
44078
|
}
|
|
43474
44079
|
function formatWatchResultText(taskId, data, waited, role, syncWaitCap) {
|
|
@@ -43477,21 +44082,22 @@ function formatWatchResultText(taskId, data, waited, role, syncWaitCap) {
|
|
|
43477
44082
|
const dur = typeof data.duration_ms === "number" ? ` ${Math.round(data.duration_ms / 1000)}s` : "";
|
|
43478
44083
|
let text = `Task ${taskId}: ${status}${exit}${dur}`;
|
|
43479
44084
|
if (waited) {
|
|
44085
|
+
const waitedText = formatWatchWaited(waited.elapsed_ms, waited.limit_ms, syncWaitCap);
|
|
43480
44086
|
if (waited.reason === "matched") {
|
|
43481
44087
|
const stream = waited.match_stream ? ` in ${waited.match_stream}` : "";
|
|
43482
44088
|
text += `
|
|
43483
|
-
|
|
44089
|
+
${waitedText}; matched ${JSON.stringify(waited.match ?? "")}${stream} at offset ${waited.match_offset ?? 0}.`;
|
|
43484
44090
|
} else if (waited.reason === "timeout") {
|
|
43485
44091
|
text += `
|
|
43486
|
-
|
|
44092
|
+
${waitedText}; timeout reached without match. ${watchTimeoutSteer(role, syncWaitCap)}`;
|
|
43487
44093
|
} else if (waited.reason === "unavailable") {
|
|
43488
44094
|
text += `
|
|
43489
|
-
|
|
44095
|
+
${waitedText}; the bridge was busy, so task state is unknown. Do not poll; let the task's completion notification wake the session, or use one bash_status snapshot on the next normal tool call.`;
|
|
43490
44096
|
} else {
|
|
43491
44097
|
const stat = String(data.status ?? "unknown");
|
|
43492
44098
|
const e = typeof data.exit_code === "number" ? `, exit ${data.exit_code}` : "";
|
|
43493
44099
|
text += `
|
|
43494
|
-
|
|
44100
|
+
${waitedText}; task exited (${stat}${e}).`;
|
|
43495
44101
|
}
|
|
43496
44102
|
}
|
|
43497
44103
|
const preview = data.output_preview;
|
|
@@ -43513,8 +44119,9 @@ async function bashStatusSnapshot2(ctx, runtime, taskId, outputMode, cursor, opt
|
|
|
43513
44119
|
return data;
|
|
43514
44120
|
}
|
|
43515
44121
|
async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effectiveWaitMs) {
|
|
43516
|
-
const startedAt =
|
|
44122
|
+
const startedAt = monotonicNowMs();
|
|
43517
44123
|
const deadline = startedAt + effectiveWaitMs;
|
|
44124
|
+
const elapsedMs = () => Math.round(monotonicNowMs() - startedAt);
|
|
43518
44125
|
let spillCursor = { output: 0, stderr: 0 };
|
|
43519
44126
|
const scanState = {
|
|
43520
44127
|
output: { text: "", baseOffset: 0 },
|
|
@@ -43539,16 +44146,18 @@ async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effe
|
|
|
43539
44146
|
if (isSyncWatchAborted(runtime.sessionID)) {
|
|
43540
44147
|
return withWaited(lastData ?? unavailableSnapshot(), {
|
|
43541
44148
|
reason: "user_message",
|
|
43542
|
-
elapsed_ms:
|
|
44149
|
+
elapsed_ms: elapsedMs(),
|
|
44150
|
+
limit_ms: effectiveWaitMs
|
|
43543
44151
|
});
|
|
43544
44152
|
}
|
|
43545
|
-
if (
|
|
44153
|
+
if (monotonicNowMs() >= deadline) {
|
|
43546
44154
|
return withWaited(lastData ?? unavailableSnapshot(), {
|
|
43547
44155
|
reason: "unavailable",
|
|
43548
|
-
elapsed_ms:
|
|
44156
|
+
elapsed_ms: elapsedMs(),
|
|
44157
|
+
limit_ms: effectiveWaitMs
|
|
43549
44158
|
});
|
|
43550
44159
|
}
|
|
43551
|
-
await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline -
|
|
44160
|
+
await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline - monotonicNowMs())));
|
|
43552
44161
|
continue;
|
|
43553
44162
|
}
|
|
43554
44163
|
lastData = data;
|
|
@@ -43577,7 +44186,8 @@ async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effe
|
|
|
43577
44186
|
const matchStream = data.mode === "pty" ? undefined : chunk.stream === "output" ? "stdout" : "stderr";
|
|
43578
44187
|
return withWaited(data, {
|
|
43579
44188
|
reason: "matched",
|
|
43580
|
-
elapsed_ms:
|
|
44189
|
+
elapsed_ms: elapsedMs(),
|
|
44190
|
+
limit_ms: effectiveWaitMs,
|
|
43581
44191
|
match: match.text,
|
|
43582
44192
|
match_offset: state.baseOffset + match.byteOffset,
|
|
43583
44193
|
match_stream: matchStream
|
|
@@ -43595,15 +44205,27 @@ async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effe
|
|
|
43595
44205
|
sawTerminal = true;
|
|
43596
44206
|
consumeBgCompletion(runtime.sessionID, taskId);
|
|
43597
44207
|
await markBgCompletionDelivered({ ctx, directory: projectRootFor(runtime), sessionID: runtime.sessionID }, taskId);
|
|
43598
|
-
return withWaited(data, {
|
|
44208
|
+
return withWaited(data, {
|
|
44209
|
+
reason: "exited",
|
|
44210
|
+
elapsed_ms: elapsedMs(),
|
|
44211
|
+
limit_ms: effectiveWaitMs
|
|
44212
|
+
});
|
|
43599
44213
|
}
|
|
43600
44214
|
if (isSyncWatchAborted(runtime.sessionID)) {
|
|
43601
|
-
return withWaited(data, {
|
|
44215
|
+
return withWaited(data, {
|
|
44216
|
+
reason: "user_message",
|
|
44217
|
+
elapsed_ms: elapsedMs(),
|
|
44218
|
+
limit_ms: effectiveWaitMs
|
|
44219
|
+
});
|
|
43602
44220
|
}
|
|
43603
|
-
if (
|
|
43604
|
-
return withWaited(data, {
|
|
44221
|
+
if (monotonicNowMs() >= deadline) {
|
|
44222
|
+
return withWaited(data, {
|
|
44223
|
+
reason: "timeout",
|
|
44224
|
+
elapsed_ms: elapsedMs(),
|
|
44225
|
+
limit_ms: effectiveWaitMs
|
|
44226
|
+
});
|
|
43605
44227
|
}
|
|
43606
|
-
await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline -
|
|
44228
|
+
await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline - monotonicNowMs())));
|
|
43607
44229
|
}
|
|
43608
44230
|
} finally {
|
|
43609
44231
|
if (!sawTerminal)
|
|
@@ -43751,47 +44373,6 @@ var ISSUE_AND_PR_READ_DESCRIPTION = "GitHub issues and pull requests can be read
|
|
|
43751
44373
|
function whenGhReadEnabled(enabled, description) {
|
|
43752
44374
|
return enabled ? description : "";
|
|
43753
44375
|
}
|
|
43754
|
-
function asRecord(value) {
|
|
43755
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
43756
|
-
}
|
|
43757
|
-
function visionCapabilityForOpenCodeModel(model) {
|
|
43758
|
-
const entry = model;
|
|
43759
|
-
if (Array.isArray(entry?.modalities?.input)) {
|
|
43760
|
-
return entry.modalities.input.includes("image");
|
|
43761
|
-
}
|
|
43762
|
-
return typeof entry?.attachment === "boolean" ? entry.attachment : undefined;
|
|
43763
|
-
}
|
|
43764
|
-
function modelFromOpenCodeProvider(provider, modelID) {
|
|
43765
|
-
const models = provider.models;
|
|
43766
|
-
if (Array.isArray(models)) {
|
|
43767
|
-
return models.find((model) => asRecord(model)?.id === modelID);
|
|
43768
|
-
}
|
|
43769
|
-
return asRecord(models)?.[modelID];
|
|
43770
|
-
}
|
|
43771
|
-
async function currentSessionVisionCapability(client, sessionID) {
|
|
43772
|
-
if (!sessionID)
|
|
43773
|
-
return;
|
|
43774
|
-
const promptContext = await resolvePromptContext(client, sessionID);
|
|
43775
|
-
const currentModel = promptContext?.model;
|
|
43776
|
-
if (!currentModel)
|
|
43777
|
-
return;
|
|
43778
|
-
const providerApi = client.provider;
|
|
43779
|
-
if (typeof providerApi?.list !== "function")
|
|
43780
|
-
return;
|
|
43781
|
-
let listed;
|
|
43782
|
-
try {
|
|
43783
|
-
listed = await providerApi.list();
|
|
43784
|
-
} catch {
|
|
43785
|
-
return;
|
|
43786
|
-
}
|
|
43787
|
-
const result = asRecord(listed);
|
|
43788
|
-
const catalog = asRecord(result?.data) ?? result;
|
|
43789
|
-
const providers = Array.isArray(catalog?.all) ? catalog.all : Array.isArray(catalog?.providers) ? catalog.providers : [];
|
|
43790
|
-
const provider = providers.map(asRecord).find((entry) => entry?.id === currentModel.providerID);
|
|
43791
|
-
if (!provider)
|
|
43792
|
-
return;
|
|
43793
|
-
return visionCapabilityForOpenCodeModel(modelFromOpenCodeProvider(provider, currentModel.modelID));
|
|
43794
|
-
}
|
|
43795
44376
|
function persistFilePathAlias(args, context) {
|
|
43796
44377
|
if (typeof args.path === "string" && !Object.hasOwn(args, "filePath")) {
|
|
43797
44378
|
args.filePath = args.path;
|
|
@@ -43963,7 +44544,7 @@ function inferBeforeStart(ops, from, beforeLen) {
|
|
|
43963
44544
|
var z7 = tool.schema;
|
|
43964
44545
|
var READ_DESCRIPTION = `Read file contents or list directory entries.
|
|
43965
44546
|
|
|
43966
|
-
Use either startLine/endLine OR offset/limit to read a section of a file.
|
|
44547
|
+
Use either startLine/endLine OR offset/limit to read a section of a file or sorted directory listing.
|
|
43967
44548
|
|
|
43968
44549
|
Behavior:
|
|
43969
44550
|
- Returns line-numbered content (e.g., "1: const x = 1")
|
|
@@ -43971,7 +44552,7 @@ Behavior:
|
|
|
43971
44552
|
- Output capped at 50KB
|
|
43972
44553
|
- Binary files are auto-detected and return a size-only message
|
|
43973
44554
|
- Supported images (PNG, JPEG, GIF, WebP) and PDFs are returned as tool attachments; range arguments are ignored for media
|
|
43974
|
-
- Directories return sorted entries with trailing / for subdirectories
|
|
44555
|
+
- Directories return sorted entries with trailing / for subdirectories; offset is 1-based, limit defaults to and is capped at 1000 entries. Enumeration stops at 10,000 entries; partial listings carry a shown/total trailer.
|
|
43975
44556
|
|
|
43976
44557
|
Examples:
|
|
43977
44558
|
Read full file: { "path": "src/app.ts" }
|
|
@@ -43995,30 +44576,30 @@ function createReadTool(ctx) {
|
|
|
43995
44576
|
description: readDescription(resolveGithubConfig(ctx.config).read),
|
|
43996
44577
|
args: {
|
|
43997
44578
|
filePath: z7.string().describe("Path to file or directory (absolute or relative to project root)"),
|
|
43998
|
-
startLine: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line to start reading from"),
|
|
43999
|
-
endLine: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line to stop reading at (inclusive)"),
|
|
44000
|
-
limit: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("Max lines
|
|
44001
|
-
offset: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line
|
|
44579
|
+
startLine: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line or directory entry to start reading from"),
|
|
44580
|
+
endLine: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line or directory entry to stop reading at (inclusive)"),
|
|
44581
|
+
limit: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("Max lines (default: 2000) or directory entries (default and cap: 1000) to return"),
|
|
44582
|
+
offset: optionalInt(1, Number.MAX_SAFE_INTEGER).describe("1-based line or directory entry to start reading from (use with limit). Ignored if startLine is provided")
|
|
44002
44583
|
},
|
|
44003
44584
|
execute: async (args, context) => {
|
|
44004
44585
|
const file = args.path;
|
|
44005
|
-
const projectRoot = await resolveProjectRoot(ctx, context);
|
|
44586
|
+
const projectRoot = await measurePreStage("directory", () => resolveProjectRoot(ctx, context));
|
|
44006
44587
|
const filePath = resolvePathFromProjectRoot(projectRoot, file);
|
|
44007
44588
|
persistFilePathAlias(args, context);
|
|
44008
44589
|
{
|
|
44009
|
-
const denial = await assertExternalDirectoryPermission(ctx, context, filePath, {
|
|
44590
|
+
const denial = await measurePreStage("permission", () => assertExternalDirectoryPermission(ctx, context, filePath, {
|
|
44010
44591
|
serverValidatedRead: true
|
|
44011
|
-
});
|
|
44592
|
+
}));
|
|
44012
44593
|
if (denial)
|
|
44013
44594
|
return permissionDeniedResponse(denial);
|
|
44014
44595
|
}
|
|
44015
44596
|
try {
|
|
44016
|
-
await runAsk(context.ask({
|
|
44597
|
+
await measurePreStage("permission", () => runAsk(context.ask({
|
|
44017
44598
|
permission: "read",
|
|
44018
44599
|
patterns: [permissionPath(context, filePath)],
|
|
44019
44600
|
always: ["*"],
|
|
44020
44601
|
metadata: {}
|
|
44021
|
-
}));
|
|
44602
|
+
})));
|
|
44022
44603
|
} catch (error) {
|
|
44023
44604
|
const failure = classifyPermissionError(error);
|
|
44024
44605
|
return permissionDeniedResponse(failure.kind === "rule_denied" ? permissionRuleDenial("read") : failure.message);
|
|
@@ -44042,7 +44623,8 @@ function createReadTool(ctx) {
|
|
|
44042
44623
|
rawArgs.endLine = endLine;
|
|
44043
44624
|
if (rawLimit !== undefined && rawOffset === undefined)
|
|
44044
44625
|
rawArgs.limit = rawLimit;
|
|
44045
|
-
const
|
|
44626
|
+
const mediaCandidate = isGithubResourcePath(file) || /\.(png|jpe?g|gif|webp|pdf)$/i.test(filePath) && await stat2(filePath).then((info) => info.isFile(), () => false);
|
|
44627
|
+
const visionCapability = mediaCandidate ? await measurePreStage("capability", () => currentSessionVisionCapability(ctx.client, context.sessionID)) : undefined;
|
|
44046
44628
|
if (visionCapability !== undefined)
|
|
44047
44629
|
rawArgs.vision_capability = visionCapability;
|
|
44048
44630
|
const response = await callToolCall(ctx, context, "read", rawArgs);
|
|
@@ -44486,7 +45068,7 @@ function createApplyPatchTool(ctx) {
|
|
|
44486
45068
|
};
|
|
44487
45069
|
}
|
|
44488
45070
|
function deleteDescription(ctx) {
|
|
44489
|
-
const backupText = ctx.config.backup?.enabled === false ? "Backup capture is disabled by user config, so this tool does not create undo snapshots. " : "Each file is backed up before deletion — use aft_safety undo to recover any of them.
|
|
45071
|
+
const backupText = ctx.config.backup?.enabled === false ? "Backup capture is disabled by user config, so this tool does not create undo snapshots. A directory tree containing a mount point of another filesystem is still refused. " : "Each file is backed up before deletion — use aft_safety undo to recover any of them. A recursive delete backs up the whole tree: directories (empty ones too, with their permissions), file contents, hard links (relinked by undo) and symlinks (the link itself, never its target; restored exactly, even when dangling). Sockets are deleted but undo does not restore them, and a file hard-linked to paths outside the tree comes back as an independent copy; both are reported as warnings. Refused before anything is deleted: mount points of another filesystem, named pipes, device nodes, and symlinks undo cannot recreate exactly (non-UTF-8 target, or on Windows). Paths under the system temp directory are never backed up, so only mount points are refused there. The deleted file's contents stay in the undo store until its retention expires. A recursive delete whose backup would record more than 2,000 entries (files, directories and links) or copy 100 MiB in one call is refused before anything is deleted; delete such a tree in smaller pieces, or use bash `rm -rf` when no undo is needed. ";
|
|
44490
45072
|
return `Delete one or more files (or directories).
|
|
44491
45073
|
|
|
44492
45074
|
` + backupText + `Directory deletion requires recursive: true. Without it, passing a directory returns an error.
|
|
@@ -44702,7 +45284,7 @@ async function resolveAndGateScope(ctx, context, scope) {
|
|
|
44702
45284
|
}
|
|
44703
45285
|
return { scope: Array.isArray(scope) ? resolved : resolved[0] };
|
|
44704
45286
|
}
|
|
44705
|
-
function
|
|
45287
|
+
function asRecord(value) {
|
|
44706
45288
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
44707
45289
|
}
|
|
44708
45290
|
function asString(value) {
|
|
@@ -44710,7 +45292,7 @@ function asString(value) {
|
|
|
44710
45292
|
}
|
|
44711
45293
|
function firstRecord(...values) {
|
|
44712
45294
|
for (const value of values) {
|
|
44713
|
-
const record =
|
|
45295
|
+
const record = asRecord(value);
|
|
44714
45296
|
if (record)
|
|
44715
45297
|
return record;
|
|
44716
45298
|
}
|
|
@@ -44745,7 +45327,7 @@ function parseInspectPhaseEntries(value) {
|
|
|
44745
45327
|
if (!Array.isArray(value))
|
|
44746
45328
|
return [];
|
|
44747
45329
|
return value.flatMap((candidate) => {
|
|
44748
|
-
const entry =
|
|
45330
|
+
const entry = asRecord(candidate);
|
|
44749
45331
|
const id = asString(entry?.id);
|
|
44750
45332
|
if (!id)
|
|
44751
45333
|
return [];
|
|
@@ -44761,7 +45343,7 @@ function parseInspectPhaseEntries(value) {
|
|
|
44761
45343
|
});
|
|
44762
45344
|
}
|
|
44763
45345
|
function parseInspectTerminal(payload) {
|
|
44764
|
-
const response =
|
|
45346
|
+
const response = asRecord(payload);
|
|
44765
45347
|
if (!response)
|
|
44766
45348
|
return;
|
|
44767
45349
|
const kind = terminalKind(response);
|
|
@@ -44776,7 +45358,7 @@ function parseInspectTerminal(payload) {
|
|
|
44776
45358
|
waitStampText: kind === "FRESH" ? firstString(waitStamp?.text, waitStamp?.human_text) : undefined
|
|
44777
45359
|
};
|
|
44778
45360
|
}
|
|
44779
|
-
const failedPhaseRecord =
|
|
45361
|
+
const failedPhaseRecord = asRecord(response.failed_phase);
|
|
44780
45362
|
const failedPhaseId = firstString(failedPhaseRecord?.id, response.failed_phase);
|
|
44781
45363
|
const failedPhase = failedPhaseId ? parseInspectPhaseEntries([
|
|
44782
45364
|
{
|
|
@@ -45549,7 +46131,7 @@ function hasMeaningfulProjectSearchFallback(query, pathArg, externalRoot) {
|
|
|
45549
46131
|
return trimmedQuery.length > 0 && trimmedQuery !== pathArg && trimmedQuery !== externalRoot;
|
|
45550
46132
|
}
|
|
45551
46133
|
var GENERATION_CHANGED_DISCLOSURE = "index changed - order re-derived";
|
|
45552
|
-
function
|
|
46134
|
+
function asRecord2(value) {
|
|
45553
46135
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
45554
46136
|
}
|
|
45555
46137
|
function normalizeContinuityQuery(query) {
|
|
@@ -45564,14 +46146,14 @@ function continuityKey(projectRoot, query, includeTests, topK) {
|
|
|
45564
46146
|
]);
|
|
45565
46147
|
}
|
|
45566
46148
|
function responseGeneration(response) {
|
|
45567
|
-
const envelope =
|
|
45568
|
-
const structured =
|
|
45569
|
-
const plan =
|
|
46149
|
+
const envelope = asRecord2(response);
|
|
46150
|
+
const structured = asRecord2(envelope?.structuredContent) ?? asRecord2(envelope?.structured_content);
|
|
46151
|
+
const plan = asRecord2(envelope?.plan) ?? asRecord2(structured?.plan);
|
|
45570
46152
|
const generation = plan?.snapshot_generation ?? envelope?.snapshot_generation;
|
|
45571
46153
|
return typeof generation === "string" ? generation : undefined;
|
|
45572
46154
|
}
|
|
45573
46155
|
function surfaceSearchText(response, continuity, sessionId, key) {
|
|
45574
|
-
const envelope =
|
|
46156
|
+
const envelope = asRecord2(response);
|
|
45575
46157
|
const text = typeof envelope?.text === "string" ? envelope.text : "";
|
|
45576
46158
|
const generation = responseGeneration(response);
|
|
45577
46159
|
if (generation === undefined)
|
|
@@ -45849,6 +46431,8 @@ var defaultBridgeBootstrapDependencies = {
|
|
|
45849
46431
|
loadConfig: loadAftConfig,
|
|
45850
46432
|
deliverLoadNotices: (notify) => deliverConfigLoadNotices(notify, getConfigLoadNotices()),
|
|
45851
46433
|
configLoadErrors: getConfigLoadErrors,
|
|
46434
|
+
configLoadSources: getConfigLoadSources,
|
|
46435
|
+
configLoadTexts: getConfigLoadTexts,
|
|
45852
46436
|
subcConnectionFileError,
|
|
45853
46437
|
migrateConfigLocations: (directory) => migrateAftConfigLocations(directory, bridgeLogger).flatMap((result) => result.warnings),
|
|
45854
46438
|
resolveBinary: resolveBinaryWithWarmup,
|
|
@@ -45890,8 +46474,12 @@ function loadBootstrapConfig(directory, notify, dependencies = defaultBridgeBoot
|
|
|
45890
46474
|
const failure = parseFailure(dependencies);
|
|
45891
46475
|
if (failure)
|
|
45892
46476
|
return configErrorState(failure, notify);
|
|
46477
|
+
const provenance = dependencies.configLoadSources ? {
|
|
46478
|
+
sources: [...dependencies.configLoadSources()],
|
|
46479
|
+
sourceTexts: Object.fromEntries(dependencies.configLoadTexts?.() ?? [])
|
|
46480
|
+
} : {};
|
|
45893
46481
|
dependencies.deliverLoadNotices?.(notify);
|
|
45894
|
-
return { ok: true, config };
|
|
46482
|
+
return { ok: true, config, ...provenance };
|
|
45895
46483
|
} catch (err) {
|
|
45896
46484
|
return configErrorState(err instanceof Error ? err.message : String(err), notify);
|
|
45897
46485
|
}
|
|
@@ -46083,8 +46671,60 @@ function buildConfigErrorToolMap(config, message, client, buildToolMap = buildAf
|
|
|
46083
46671
|
return failEveryToolCall(buildToolMap(ctx, config), message);
|
|
46084
46672
|
}
|
|
46085
46673
|
|
|
46674
|
+
// src/config-live-reload.ts
|
|
46675
|
+
var OPENCODE_LIVE_CONFIG_KEYS = aftLiveConfigKeys((config) => resolveBashConfig(config));
|
|
46676
|
+
function projectTextOf(directory) {
|
|
46677
|
+
const { projectConfigPath } = resolveCortexKitConfigPaths(directory);
|
|
46678
|
+
return getConfigLoadTexts().get(projectConfigPath) ?? null;
|
|
46679
|
+
}
|
|
46680
|
+
function loadOpenCodeConfigForLiveReload(directory) {
|
|
46681
|
+
try {
|
|
46682
|
+
const config = loadAftConfig(directory);
|
|
46683
|
+
const [failure] = getConfigLoadErrors();
|
|
46684
|
+
if (failure) {
|
|
46685
|
+
return { ok: false, message: formatConfigParseErrorMessage(failure.path, failure.message) };
|
|
46686
|
+
}
|
|
46687
|
+
const [invalid] = getConfigValidationErrors();
|
|
46688
|
+
if (invalid) {
|
|
46689
|
+
return {
|
|
46690
|
+
ok: false,
|
|
46691
|
+
message: `AFT config at ${invalid.path} has an invalid setting: ${invalid.message}`
|
|
46692
|
+
};
|
|
46693
|
+
}
|
|
46694
|
+
return {
|
|
46695
|
+
ok: true,
|
|
46696
|
+
config,
|
|
46697
|
+
sources: [...getConfigLoadSources()],
|
|
46698
|
+
projectText: projectTextOf(directory),
|
|
46699
|
+
texts: Object.fromEntries(getConfigLoadTexts())
|
|
46700
|
+
};
|
|
46701
|
+
} catch (err) {
|
|
46702
|
+
return { ok: false, message: err instanceof Error ? err.message : String(err) };
|
|
46703
|
+
}
|
|
46704
|
+
}
|
|
46705
|
+
function startOpenCodeLiveConfigReload(options) {
|
|
46706
|
+
const { userConfigPath, projectConfigPath } = resolveCortexKitConfigPaths(options.directory);
|
|
46707
|
+
return startLiveConfigReload({
|
|
46708
|
+
paths: [userConfigPath, projectConfigPath],
|
|
46709
|
+
load: () => loadOpenCodeConfigForLiveReload(options.directory),
|
|
46710
|
+
initialSources: options.initialSources,
|
|
46711
|
+
initialProjectText: options.initialSourceTexts?.[projectConfigPath] ?? null,
|
|
46712
|
+
initialTexts: options.initialSourceTexts,
|
|
46713
|
+
securityKeys: aftLiveSecurityKeys(OPENCODE_LIVE_CONFIG_KEYS),
|
|
46714
|
+
keys: OPENCODE_LIVE_CONFIG_KEYS,
|
|
46715
|
+
getConfig: options.getConfig,
|
|
46716
|
+
setConfig: options.setConfig,
|
|
46717
|
+
log: (message) => log2(`${message} (${options.directory})`),
|
|
46718
|
+
reportError: (message) => {
|
|
46719
|
+
error2(message);
|
|
46720
|
+
options.notify(message);
|
|
46721
|
+
},
|
|
46722
|
+
watch: options.watch
|
|
46723
|
+
});
|
|
46724
|
+
}
|
|
46725
|
+
|
|
46086
46726
|
// src/notifications.ts
|
|
46087
|
-
import { existsSync as existsSync18, readFileSync as
|
|
46727
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "node:fs";
|
|
46088
46728
|
import { homedir as homedir13, platform } from "node:os";
|
|
46089
46729
|
import { join as join20 } from "node:path";
|
|
46090
46730
|
function isTuiMode() {
|
|
@@ -46126,7 +46766,7 @@ function readDesktopState() {
|
|
|
46126
46766
|
return { serverUrl: null };
|
|
46127
46767
|
}
|
|
46128
46768
|
try {
|
|
46129
|
-
const raw =
|
|
46769
|
+
const raw = readFileSync15(statePath, "utf-8");
|
|
46130
46770
|
const state = JSON.parse(raw);
|
|
46131
46771
|
let serverUrl = null;
|
|
46132
46772
|
const serverStr = state.server;
|
|
@@ -46625,23 +47265,25 @@ import {
|
|
|
46625
47265
|
existsSync as existsSync21,
|
|
46626
47266
|
mkdirSync as mkdirSync9,
|
|
46627
47267
|
openSync as openSync7,
|
|
46628
|
-
readFileSync as
|
|
47268
|
+
readFileSync as readFileSync18,
|
|
46629
47269
|
renameSync as renameSync11,
|
|
46630
47270
|
rmSync as rmSync8,
|
|
46631
|
-
statSync as
|
|
47271
|
+
statSync as statSync15,
|
|
46632
47272
|
writeFileSync as writeFileSync12
|
|
46633
47273
|
} from "node:fs";
|
|
46634
|
-
import { dirname as
|
|
47274
|
+
import { dirname as dirname15 } from "node:path";
|
|
46635
47275
|
|
|
46636
47276
|
// src/hooks/auto-update-checker/cache.ts
|
|
46637
|
-
import { cpSync, existsSync as existsSync20, mkdtempSync, readFileSync as
|
|
47277
|
+
import { cpSync, existsSync as existsSync20, mkdtempSync, readFileSync as readFileSync17, rmSync as rmSync7, writeFileSync as writeFileSync11 } from "node:fs";
|
|
46638
47278
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
46639
|
-
import { basename as
|
|
47279
|
+
import { basename as basename6, dirname as dirname14, join as join23 } from "node:path";
|
|
46640
47280
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
46641
47281
|
|
|
46642
47282
|
// src/hooks/auto-update-checker/checker.ts
|
|
46643
|
-
import { existsSync as existsSync19, readFileSync as
|
|
46644
|
-
import {
|
|
47283
|
+
import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as statSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
47284
|
+
import { readFile } from "node:fs/promises";
|
|
47285
|
+
import { homedir as homedir14 } from "node:os";
|
|
47286
|
+
import { dirname as dirname13, isAbsolute as isAbsolute11, join as join22, resolve as resolve13 } from "node:path";
|
|
46645
47287
|
import { fileURLToPath } from "node:url";
|
|
46646
47288
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
46647
47289
|
|
|
@@ -46732,14 +47374,14 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
46732
47374
|
}
|
|
46733
47375
|
if (isAbsolute11(spec) || /^[A-Za-z]:[\\/]/.test(spec))
|
|
46734
47376
|
return spec;
|
|
46735
|
-
return resolve13(
|
|
47377
|
+
return resolve13(dirname13(configPath), spec);
|
|
46736
47378
|
}
|
|
46737
47379
|
function getLocalDevPath(directory) {
|
|
46738
47380
|
for (const configPath of getConfigPaths(directory)) {
|
|
46739
47381
|
try {
|
|
46740
47382
|
if (!existsSync19(configPath))
|
|
46741
47383
|
continue;
|
|
46742
|
-
const rawConfig = parseJsonConfig(
|
|
47384
|
+
const rawConfig = parseJsonConfig(readFileSync16(configPath, "utf-8"));
|
|
46743
47385
|
const plugins = getPluginEntries(rawConfig);
|
|
46744
47386
|
for (const entry of plugins) {
|
|
46745
47387
|
if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
|
|
@@ -46749,7 +47391,7 @@ function getLocalDevPath(directory) {
|
|
|
46749
47391
|
const pkgPath = findPackageJsonUp(localPath);
|
|
46750
47392
|
if (!pkgPath)
|
|
46751
47393
|
continue;
|
|
46752
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
47394
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync16(pkgPath, "utf-8")));
|
|
46753
47395
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
46754
47396
|
return localPath;
|
|
46755
47397
|
}
|
|
@@ -46760,18 +47402,18 @@ function getLocalDevPath(directory) {
|
|
|
46760
47402
|
}
|
|
46761
47403
|
function findPackageJsonUp(startPath) {
|
|
46762
47404
|
try {
|
|
46763
|
-
const stat =
|
|
46764
|
-
let dir = stat.isDirectory() ? startPath :
|
|
47405
|
+
const stat = statSync14(startPath);
|
|
47406
|
+
let dir = stat.isDirectory() ? startPath : dirname13(startPath);
|
|
46765
47407
|
for (let i = 0;i < 10; i++) {
|
|
46766
47408
|
const pkgPath = join22(dir, "package.json");
|
|
46767
47409
|
if (existsSync19(pkgPath)) {
|
|
46768
47410
|
try {
|
|
46769
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
47411
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync16(pkgPath, "utf-8")));
|
|
46770
47412
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
46771
47413
|
return pkgPath;
|
|
46772
47414
|
} catch {}
|
|
46773
47415
|
}
|
|
46774
|
-
const parent =
|
|
47416
|
+
const parent = dirname13(dir);
|
|
46775
47417
|
if (parent === dir)
|
|
46776
47418
|
break;
|
|
46777
47419
|
dir = parent;
|
|
@@ -46787,7 +47429,7 @@ function getLocalDevVersion(directory) {
|
|
|
46787
47429
|
const pkgPath = findPackageJsonUp(localPath);
|
|
46788
47430
|
if (!pkgPath)
|
|
46789
47431
|
return null;
|
|
46790
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
47432
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync16(pkgPath, "utf-8")));
|
|
46791
47433
|
return pkg.success ? pkg.data.version ?? null : null;
|
|
46792
47434
|
} catch {
|
|
46793
47435
|
return null;
|
|
@@ -46795,7 +47437,7 @@ function getLocalDevVersion(directory) {
|
|
|
46795
47437
|
}
|
|
46796
47438
|
function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
46797
47439
|
try {
|
|
46798
|
-
return findPackageJsonUp(
|
|
47440
|
+
return findPackageJsonUp(dirname13(fileURLToPath(currentModuleUrl)));
|
|
46799
47441
|
} catch (err) {
|
|
46800
47442
|
warn2(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
|
|
46801
47443
|
return null;
|
|
@@ -46806,7 +47448,7 @@ function findPluginEntry(directory) {
|
|
|
46806
47448
|
try {
|
|
46807
47449
|
if (!existsSync19(configPath))
|
|
46808
47450
|
continue;
|
|
46809
|
-
const rawConfig = parseJsonConfig(
|
|
47451
|
+
const rawConfig = parseJsonConfig(readFileSync16(configPath, "utf-8"));
|
|
46810
47452
|
const plugins = getPluginEntries(rawConfig);
|
|
46811
47453
|
for (const entry of plugins) {
|
|
46812
47454
|
if (entry === PACKAGE_NAME) {
|
|
@@ -46839,7 +47481,7 @@ function getCachedVersion(spec) {
|
|
|
46839
47481
|
try {
|
|
46840
47482
|
if (!existsSync19(packageJsonPath))
|
|
46841
47483
|
continue;
|
|
46842
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
47484
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync16(packageJsonPath, "utf-8")));
|
|
46843
47485
|
if (pkg.success && pkg.data.version) {
|
|
46844
47486
|
if (!spec)
|
|
46845
47487
|
cachedPackageVersion = pkg.data.version;
|
|
@@ -46849,6 +47491,117 @@ function getCachedVersion(spec) {
|
|
|
46849
47491
|
}
|
|
46850
47492
|
return null;
|
|
46851
47493
|
}
|
|
47494
|
+
var registryCache = new Map;
|
|
47495
|
+
function npmConfigGet(key, directory) {
|
|
47496
|
+
return new Promise((resolve, reject) => {
|
|
47497
|
+
execFile(process.platform === "win32" ? "npm.cmd" : "npm", ["config", "get", key], {
|
|
47498
|
+
cwd: directory,
|
|
47499
|
+
timeout: NPM_FETCH_TIMEOUT,
|
|
47500
|
+
windowsHide: true,
|
|
47501
|
+
shell: process.platform === "win32"
|
|
47502
|
+
}, (error, stdout) => {
|
|
47503
|
+
if (error)
|
|
47504
|
+
reject(error);
|
|
47505
|
+
else
|
|
47506
|
+
resolve(stdout.trim());
|
|
47507
|
+
});
|
|
47508
|
+
});
|
|
47509
|
+
}
|
|
47510
|
+
function configuredRegistry(value) {
|
|
47511
|
+
return value && value !== "undefined" && value !== "null" ? value : undefined;
|
|
47512
|
+
}
|
|
47513
|
+
async function readRegistrySettings(path, required = false) {
|
|
47514
|
+
let text;
|
|
47515
|
+
try {
|
|
47516
|
+
text = await readFile(path, "utf8");
|
|
47517
|
+
} catch (error) {
|
|
47518
|
+
if (!required && error.code === "ENOENT")
|
|
47519
|
+
return {};
|
|
47520
|
+
throw error;
|
|
47521
|
+
}
|
|
47522
|
+
const settings = {};
|
|
47523
|
+
for (const line of text.split(/\r?\n/)) {
|
|
47524
|
+
const trimmed = line.trim();
|
|
47525
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith(";"))
|
|
47526
|
+
continue;
|
|
47527
|
+
const separator = trimmed.indexOf("=");
|
|
47528
|
+
if (separator < 0)
|
|
47529
|
+
continue;
|
|
47530
|
+
const key = trimmed.slice(0, separator).trim();
|
|
47531
|
+
if (key === "registry" || key === "@cortexkit:registry") {
|
|
47532
|
+
settings[key] = configuredRegistry(trimmed.slice(separator + 1).trim());
|
|
47533
|
+
}
|
|
47534
|
+
}
|
|
47535
|
+
return settings;
|
|
47536
|
+
}
|
|
47537
|
+
function registryEnvironment(key) {
|
|
47538
|
+
const variable = `npm_config_${key}`;
|
|
47539
|
+
const value = process.env[variable] ?? Object.entries(process.env).find(([name]) => name.toLowerCase() === variable)?.[1];
|
|
47540
|
+
return configuredRegistry(value ?? "");
|
|
47541
|
+
}
|
|
47542
|
+
async function registryWithoutNpm(directory) {
|
|
47543
|
+
let scoped = registryEnvironment("@cortexkit:registry");
|
|
47544
|
+
let registry = registryEnvironment("registry");
|
|
47545
|
+
const visited = new Set;
|
|
47546
|
+
for (let current = directory;; current = dirname13(current)) {
|
|
47547
|
+
if (scoped)
|
|
47548
|
+
break;
|
|
47549
|
+
const path = join22(current, ".npmrc");
|
|
47550
|
+
visited.add(path);
|
|
47551
|
+
const settings = await readRegistrySettings(path);
|
|
47552
|
+
scoped ??= settings["@cortexkit:registry"];
|
|
47553
|
+
registry ??= settings.registry;
|
|
47554
|
+
if (dirname13(current) === current)
|
|
47555
|
+
break;
|
|
47556
|
+
}
|
|
47557
|
+
const explicitUserConfig = process.env.npm_config_userconfig ?? process.env.NPM_CONFIG_USERCONFIG;
|
|
47558
|
+
const home = (process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME) ?? homedir14();
|
|
47559
|
+
const userConfig = explicitUserConfig ?? join22(home, ".npmrc");
|
|
47560
|
+
if (!scoped && !visited.has(userConfig)) {
|
|
47561
|
+
const settings = await readRegistrySettings(userConfig, explicitUserConfig !== undefined);
|
|
47562
|
+
scoped = settings["@cortexkit:registry"];
|
|
47563
|
+
registry ??= settings.registry;
|
|
47564
|
+
}
|
|
47565
|
+
const selected = scoped ?? registry ?? NPM_REGISTRY_URL;
|
|
47566
|
+
return selected.replace(/\$\{([^}]+)\}/g, (_match, name) => {
|
|
47567
|
+
const value = process.env[name];
|
|
47568
|
+
if (value === undefined)
|
|
47569
|
+
throw new Error("Unresolved registry environment variable");
|
|
47570
|
+
return value;
|
|
47571
|
+
});
|
|
47572
|
+
}
|
|
47573
|
+
function validateRegistry(registry) {
|
|
47574
|
+
const url = new URL(registry);
|
|
47575
|
+
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
47576
|
+
throw new Error("Unsupported registry protocol");
|
|
47577
|
+
return registry;
|
|
47578
|
+
}
|
|
47579
|
+
var reportedRegistryFailures = new Set;
|
|
47580
|
+
function reportRegistryFailure(directory) {
|
|
47581
|
+
const key = resolve13(directory);
|
|
47582
|
+
if (reportedRegistryFailures.has(key))
|
|
47583
|
+
return;
|
|
47584
|
+
reportedRegistryFailures.add(key);
|
|
47585
|
+
debug2("[auto-update-checker] Configured npm registry could not be resolved or used; skipping update check.");
|
|
47586
|
+
}
|
|
47587
|
+
function resolveRegistry(directory) {
|
|
47588
|
+
const key = resolve13(directory);
|
|
47589
|
+
let pending = registryCache.get(key);
|
|
47590
|
+
if (!pending) {
|
|
47591
|
+
pending = (async () => {
|
|
47592
|
+
let registry;
|
|
47593
|
+
try {
|
|
47594
|
+
const scoped = configuredRegistry(await npmConfigGet("@cortexkit:registry", key));
|
|
47595
|
+
registry = scoped ?? configuredRegistry(await npmConfigGet("registry", key)) ?? NPM_REGISTRY_URL;
|
|
47596
|
+
} catch {
|
|
47597
|
+
registry = await registryWithoutNpm(key);
|
|
47598
|
+
}
|
|
47599
|
+
return validateRegistry(registry);
|
|
47600
|
+
})();
|
|
47601
|
+
registryCache.set(key, pending);
|
|
47602
|
+
}
|
|
47603
|
+
return pending;
|
|
47604
|
+
}
|
|
46852
47605
|
function buildRegistryUrl(registryUrl) {
|
|
46853
47606
|
return `${registryUrl.replace(/\/+$/, "")}/${encodeURIComponent(PACKAGE_NAME).replace("%2F", "/")}`;
|
|
46854
47607
|
}
|
|
@@ -46860,17 +47613,24 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
46860
47613
|
try {
|
|
46861
47614
|
if (options.signal?.aborted)
|
|
46862
47615
|
return null;
|
|
46863
|
-
const
|
|
47616
|
+
const registry = validateRegistry(options.registryUrl ?? await resolveRegistry(options.directory ?? process.cwd()));
|
|
47617
|
+
if (controller.signal.aborted)
|
|
47618
|
+
return null;
|
|
47619
|
+
const response = await fetch(buildRegistryUrl(registry), {
|
|
46864
47620
|
signal: controller.signal,
|
|
46865
47621
|
headers: { Accept: "application/json" }
|
|
46866
47622
|
});
|
|
46867
|
-
if (!response.ok)
|
|
47623
|
+
if (!response.ok) {
|
|
47624
|
+
reportRegistryFailure(options.directory ?? process.cwd());
|
|
46868
47625
|
return null;
|
|
47626
|
+
}
|
|
46869
47627
|
const data = NpmPackageEnvelopeSchema.safeParse(await response.json());
|
|
46870
47628
|
if (!data.success)
|
|
46871
47629
|
return null;
|
|
46872
47630
|
return data.data["dist-tags"][channel] ?? data.data["dist-tags"].latest ?? null;
|
|
46873
47631
|
} catch {
|
|
47632
|
+
if (!controller.signal.aborted)
|
|
47633
|
+
reportRegistryFailure(options.directory ?? process.cwd());
|
|
46874
47634
|
return null;
|
|
46875
47635
|
} finally {
|
|
46876
47636
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
@@ -46890,9 +47650,9 @@ function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
|
|
|
46890
47650
|
cpSync(packageDir, stagedPackageDir, { recursive: true });
|
|
46891
47651
|
return {
|
|
46892
47652
|
packageJsonPath,
|
|
46893
|
-
packageJson: existsSync20(packageJsonPath) ?
|
|
47653
|
+
packageJson: existsSync20(packageJsonPath) ? readFileSync17(packageJsonPath, "utf-8") : null,
|
|
46894
47654
|
lockfilePath,
|
|
46895
|
-
lockfile: existsSync20(lockfilePath) ?
|
|
47655
|
+
lockfile: existsSync20(lockfilePath) ? readFileSync17(lockfilePath, "utf-8") : null,
|
|
46896
47656
|
packageDir,
|
|
46897
47657
|
stagedPackageDir,
|
|
46898
47658
|
tempDir
|
|
@@ -46919,9 +47679,9 @@ function restoreAutoUpdateSnapshot(snapshot) {
|
|
|
46919
47679
|
function stripPackageNameFromPath(pathValue, packageName) {
|
|
46920
47680
|
let current = pathValue;
|
|
46921
47681
|
for (const segment of [...packageName.split("/")].reverse()) {
|
|
46922
|
-
if (
|
|
47682
|
+
if (basename6(current) !== segment)
|
|
46923
47683
|
return null;
|
|
46924
|
-
current =
|
|
47684
|
+
current = dirname14(current);
|
|
46925
47685
|
}
|
|
46926
47686
|
return current;
|
|
46927
47687
|
}
|
|
@@ -46930,7 +47690,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
46930
47690
|
if (!existsSync20(lockPath))
|
|
46931
47691
|
return false;
|
|
46932
47692
|
try {
|
|
46933
|
-
const lock = import_comment_json3.parse(
|
|
47693
|
+
const lock = import_comment_json3.parse(readFileSync17(lockPath, "utf-8"));
|
|
46934
47694
|
let modified = false;
|
|
46935
47695
|
if (lock.packages) {
|
|
46936
47696
|
const key = `node_modules/${packageName}`;
|
|
@@ -46956,7 +47716,7 @@ function ensureDependencyVersion(packageJsonPath, packageName, version) {
|
|
|
46956
47716
|
if (!existsSync20(packageJsonPath))
|
|
46957
47717
|
return false;
|
|
46958
47718
|
try {
|
|
46959
|
-
const raw = import_comment_json3.parse(
|
|
47719
|
+
const raw = import_comment_json3.parse(readFileSync17(packageJsonPath, "utf-8"));
|
|
46960
47720
|
const pkgJson = PackageJsonSchema.safeParse(raw);
|
|
46961
47721
|
if (!pkgJson.success)
|
|
46962
47722
|
return false;
|
|
@@ -46991,17 +47751,17 @@ function removeInstalledPackage(installDir, packageName) {
|
|
|
46991
47751
|
}
|
|
46992
47752
|
function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackageJsonPath()) {
|
|
46993
47753
|
if (runtimePackageJsonPath) {
|
|
46994
|
-
const packageDir =
|
|
47754
|
+
const packageDir = dirname14(runtimePackageJsonPath);
|
|
46995
47755
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
46996
|
-
if (nodeModulesDir &&
|
|
46997
|
-
const installDir =
|
|
47756
|
+
if (nodeModulesDir && basename6(nodeModulesDir) === "node_modules") {
|
|
47757
|
+
const installDir = dirname14(nodeModulesDir);
|
|
46998
47758
|
const packageJsonPath = join23(installDir, "package.json");
|
|
46999
47759
|
if (existsSync20(packageJsonPath))
|
|
47000
47760
|
return { installDir, packageJsonPath };
|
|
47001
47761
|
}
|
|
47002
47762
|
return null;
|
|
47003
47763
|
}
|
|
47004
|
-
const cacheRoot =
|
|
47764
|
+
const cacheRoot = dirname14(cacheDir());
|
|
47005
47765
|
const legacyPackageJsonPath = join23(cacheRoot, "package.json");
|
|
47006
47766
|
if (existsSync20(legacyPackageJsonPath)) {
|
|
47007
47767
|
return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
|
|
@@ -47204,7 +47964,7 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
47204
47964
|
try {
|
|
47205
47965
|
if (hasRecentCheckTimestamp(file, intervalMs))
|
|
47206
47966
|
return null;
|
|
47207
|
-
mkdirSync9(
|
|
47967
|
+
mkdirSync9(dirname15(file), { recursive: true });
|
|
47208
47968
|
const lockPath = `${file}.lock`;
|
|
47209
47969
|
const owner = { pid: process.pid, startedMs: Date.now() };
|
|
47210
47970
|
let lockFd = null;
|
|
@@ -47275,9 +48035,9 @@ function isOrphanedCheckLock(lockPath) {
|
|
|
47275
48035
|
}
|
|
47276
48036
|
}
|
|
47277
48037
|
function readCheckLockState(lockPath) {
|
|
47278
|
-
const fallbackStartedMs =
|
|
48038
|
+
const fallbackStartedMs = statSync15(lockPath).mtimeMs;
|
|
47279
48039
|
try {
|
|
47280
|
-
const parsed = JSON.parse(
|
|
48040
|
+
const parsed = JSON.parse(readFileSync18(lockPath, "utf-8"));
|
|
47281
48041
|
const pid = Number.isSafeInteger(parsed.pid) && (parsed.pid ?? 0) > 0 ? parsed.pid ?? null : null;
|
|
47282
48042
|
const startedMs = typeof parsed.startedMs === "number" && Number.isFinite(parsed.startedMs) ? parsed.startedMs : fallbackStartedMs;
|
|
47283
48043
|
return { pid, startedMs };
|
|
@@ -47287,7 +48047,7 @@ function readCheckLockState(lockPath) {
|
|
|
47287
48047
|
}
|
|
47288
48048
|
function checkLockIsOwnedBy(lockPath, owner) {
|
|
47289
48049
|
try {
|
|
47290
|
-
const parsed = JSON.parse(
|
|
48050
|
+
const parsed = JSON.parse(readFileSync18(lockPath, "utf-8"));
|
|
47291
48051
|
return parsed.pid === owner.pid && parsed.startedMs === owner.startedMs;
|
|
47292
48052
|
} catch {
|
|
47293
48053
|
return false;
|
|
@@ -47297,7 +48057,7 @@ function hasRecentCheckTimestamp(file, intervalMs) {
|
|
|
47297
48057
|
if (!existsSync21(file))
|
|
47298
48058
|
return false;
|
|
47299
48059
|
try {
|
|
47300
|
-
const raw = JSON.parse(
|
|
48060
|
+
const raw = JSON.parse(readFileSync18(file, "utf-8"));
|
|
47301
48061
|
const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
|
|
47302
48062
|
return Number.isFinite(last) && Date.now() - last < intervalMs;
|
|
47303
48063
|
} catch {
|
|
@@ -47353,6 +48113,7 @@ async function runBackgroundUpdateCheck(ctx, options) {
|
|
|
47353
48113
|
const channel = extractChannel(pluginInfo.pinnedVersion ?? currentVersion);
|
|
47354
48114
|
const latestVersion = await getLatestVersion(channel, {
|
|
47355
48115
|
registryUrl: options.npmRegistryUrl,
|
|
48116
|
+
directory: ctx.directory,
|
|
47356
48117
|
timeoutMs: options.fetchTimeoutMs,
|
|
47357
48118
|
signal: options.signal
|
|
47358
48119
|
});
|
|
@@ -47493,13 +48254,13 @@ import {
|
|
|
47493
48254
|
existsSync as existsSync22,
|
|
47494
48255
|
mkdirSync as mkdirSync10,
|
|
47495
48256
|
readdirSync as readdirSync6,
|
|
47496
|
-
readFileSync as
|
|
48257
|
+
readFileSync as readFileSync19,
|
|
47497
48258
|
renameSync as renameSync12,
|
|
47498
48259
|
unlinkSync as unlinkSync8,
|
|
47499
48260
|
writeFileSync as writeFileSync13
|
|
47500
48261
|
} from "node:fs";
|
|
47501
48262
|
import { createServer } from "node:http";
|
|
47502
|
-
import { dirname as
|
|
48263
|
+
import { dirname as dirname16, join as join25 } from "node:path";
|
|
47503
48264
|
|
|
47504
48265
|
// src/shared/rpc-utils.ts
|
|
47505
48266
|
import { join as join24 } from "node:path";
|
|
@@ -47649,7 +48410,7 @@ class AftRpcServer {
|
|
|
47649
48410
|
}
|
|
47650
48411
|
}
|
|
47651
48412
|
writePortFile() {
|
|
47652
|
-
const dir =
|
|
48413
|
+
const dir = dirname16(this.portFilePath);
|
|
47653
48414
|
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
47654
48415
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
47655
48416
|
writeFileSync13(tmpPath, JSON.stringify({
|
|
@@ -47674,7 +48435,7 @@ class AftRpcServer {
|
|
|
47674
48435
|
if (filePath === this.portFilePath)
|
|
47675
48436
|
continue;
|
|
47676
48437
|
try {
|
|
47677
|
-
const record = parseRpcPortRecord(
|
|
48438
|
+
const record = parseRpcPortRecord(readFileSync19(filePath, "utf-8"));
|
|
47678
48439
|
if (record === null) {
|
|
47679
48440
|
unlinkSync8(filePath);
|
|
47680
48441
|
continue;
|
|
@@ -47889,7 +48650,7 @@ function formatSemanticIndexLabel(semantic) {
|
|
|
47889
48650
|
backendUrl: semantic.backend_url
|
|
47890
48651
|
});
|
|
47891
48652
|
}
|
|
47892
|
-
function
|
|
48653
|
+
function asRecord3(value) {
|
|
47893
48654
|
return typeof value === "object" && value !== null ? value : {};
|
|
47894
48655
|
}
|
|
47895
48656
|
function readString(value, fallback = "") {
|
|
@@ -47908,7 +48669,7 @@ function readOptionalNumber(value) {
|
|
|
47908
48669
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
47909
48670
|
}
|
|
47910
48671
|
function readCompressionAggregate(value) {
|
|
47911
|
-
const aggregate =
|
|
48672
|
+
const aggregate = asRecord3(value);
|
|
47912
48673
|
return {
|
|
47913
48674
|
events: readNumber(aggregate.events),
|
|
47914
48675
|
original_tokens: readNumber(aggregate.original_tokens),
|
|
@@ -47919,7 +48680,7 @@ function readCompressionAggregate(value) {
|
|
|
47919
48680
|
function readCompression(value) {
|
|
47920
48681
|
if (typeof value !== "object" || value === null)
|
|
47921
48682
|
return;
|
|
47922
|
-
const compression =
|
|
48683
|
+
const compression = asRecord3(value);
|
|
47923
48684
|
return {
|
|
47924
48685
|
project: readCompressionAggregate(compression.project),
|
|
47925
48686
|
session: readCompressionAggregate(compression.session)
|
|
@@ -47928,7 +48689,7 @@ function readCompression(value) {
|
|
|
47928
48689
|
function readStatusBar(value) {
|
|
47929
48690
|
if (typeof value !== "object" || value === null)
|
|
47930
48691
|
return;
|
|
47931
|
-
const bar =
|
|
48692
|
+
const bar = asRecord3(value);
|
|
47932
48693
|
const errors = readOptionalNumber(bar.errors);
|
|
47933
48694
|
const warnings = readOptionalNumber(bar.warnings);
|
|
47934
48695
|
const deadCode = readOptionalNumber(bar.dead_code);
|
|
@@ -47986,17 +48747,17 @@ function formatBytes(bytes) {
|
|
|
47986
48747
|
return `${value.toFixed(decimals)} ${units[unitIndex]}`;
|
|
47987
48748
|
}
|
|
47988
48749
|
function coerceAftStatus(response) {
|
|
47989
|
-
const features =
|
|
47990
|
-
const searchIndex =
|
|
47991
|
-
const semanticIndex =
|
|
48750
|
+
const features = asRecord3(response.features);
|
|
48751
|
+
const searchIndex = asRecord3(response.search_index);
|
|
48752
|
+
const semanticIndex = asRecord3(response.semantic_index);
|
|
47992
48753
|
const semanticConfig = {
|
|
47993
|
-
...
|
|
47994
|
-
...
|
|
48754
|
+
...asRecord3(response.semantic),
|
|
48755
|
+
...asRecord3(response.semantic_config)
|
|
47995
48756
|
};
|
|
47996
|
-
const disk =
|
|
47997
|
-
const symbolCache =
|
|
47998
|
-
const runtime =
|
|
47999
|
-
const session =
|
|
48757
|
+
const disk = asRecord3(response.disk);
|
|
48758
|
+
const symbolCache = asRecord3(response.symbol_cache);
|
|
48759
|
+
const runtime = asRecord3(response.runtime);
|
|
48760
|
+
const session = asRecord3(response.session);
|
|
48000
48761
|
return {
|
|
48001
48762
|
version: readString(response.version, "unknown"),
|
|
48002
48763
|
project_root: readNullableString(response.project_root),
|
|
@@ -48537,6 +49298,16 @@ async function initializePluginForDirectory(input) {
|
|
|
48537
49298
|
storageDir: configOverrides.storage_dir,
|
|
48538
49299
|
isProjectEnabled
|
|
48539
49300
|
};
|
|
49301
|
+
const liveConfigReload = startOpenCodeLiveConfigReload({
|
|
49302
|
+
directory: registrationRoot,
|
|
49303
|
+
initialSources: bootstrap.sources ?? [],
|
|
49304
|
+
initialSourceTexts: bootstrap.sourceTexts,
|
|
49305
|
+
getConfig: () => ctx.config,
|
|
49306
|
+
setConfig: (config) => {
|
|
49307
|
+
ctx.config = config;
|
|
49308
|
+
},
|
|
49309
|
+
notify: (message) => deliverConfigMigrationWarnings(registrationRoot, [message])
|
|
49310
|
+
});
|
|
48540
49311
|
const statusSubscribedBridges = new WeakSet;
|
|
48541
49312
|
const statusUnsubscribes = new Set;
|
|
48542
49313
|
const subscribeBridgeStatus = (bridge) => {
|
|
@@ -48574,6 +49345,7 @@ async function initializePluginForDirectory(input) {
|
|
|
48574
49345
|
let clearInspectTier2Idle = () => {};
|
|
48575
49346
|
const shutdownCleanup = registerShutdownCleanup(async (reason) => {
|
|
48576
49347
|
autoUpdateAbort.abort();
|
|
49348
|
+
liveConfigReload.stop();
|
|
48577
49349
|
clearInspectTier2Idle();
|
|
48578
49350
|
for (const unsubscribe of statusUnsubscribes) {
|
|
48579
49351
|
try {
|
|
@@ -48732,7 +49504,7 @@ Install: ${getManualInstallHint()}`);
|
|
|
48732
49504
|
}
|
|
48733
49505
|
const inspectTier2Idle = createInspectTier2IdleScheduler({
|
|
48734
49506
|
isEnabled: () => registeredTools.has("aft_inspect"),
|
|
48735
|
-
idleMinutes: () =>
|
|
49507
|
+
idleMinutes: () => ctx.config.inspect?.tier2_idle_minutes,
|
|
48736
49508
|
warn: warn2,
|
|
48737
49509
|
run: async (sessionID) => {
|
|
48738
49510
|
const sessionDir = await getSessionDirectory(input.client, sessionID, input.directory) ?? input.directory;
|
|
@@ -48790,11 +49562,17 @@ Install: ${getManualInstallHint()}`);
|
|
|
48790
49562
|
storageDir: configOverrides.storage_dir,
|
|
48791
49563
|
pluginVersion: PLUGIN_VERSION,
|
|
48792
49564
|
serverUrl: input.serverUrl?.toString(),
|
|
48793
|
-
delivery:
|
|
49565
|
+
delivery: ctx.config.configure_warnings_delivery ?? "toast"
|
|
48794
49566
|
});
|
|
48795
49567
|
}
|
|
48796
49568
|
await flushConfigureWarningsOnIdle(sessionID);
|
|
48797
49569
|
},
|
|
49570
|
+
"chat.params": async (params) => {
|
|
49571
|
+
rememberReadModel(input.client, params.sessionID, {
|
|
49572
|
+
providerID: params.model.providerID,
|
|
49573
|
+
modelID: params.model.id
|
|
49574
|
+
});
|
|
49575
|
+
},
|
|
48798
49576
|
"chat.message": async (messageInput, messageOutput) => {
|
|
48799
49577
|
const sid = messageInput.sessionID ?? messageInput.sessionId ?? messageInput.id;
|
|
48800
49578
|
warmSessionDirectory(input.client, sid, input.directory);
|
|
@@ -48904,7 +49682,7 @@ var AftRpc = Rpc.define({
|
|
|
48904
49682
|
}
|
|
48905
49683
|
});
|
|
48906
49684
|
// src/rpc/register.ts
|
|
48907
|
-
function
|
|
49685
|
+
function asRecord4(value) {
|
|
48908
49686
|
return typeof value === "object" && value !== null ? value : undefined;
|
|
48909
49687
|
}
|
|
48910
49688
|
function finiteNumber(value) {
|
|
@@ -48914,12 +49692,12 @@ function nonEmptyString(value) {
|
|
|
48914
49692
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
48915
49693
|
}
|
|
48916
49694
|
function sessionFromSnapshot(snapshot) {
|
|
48917
|
-
return nonEmptyString(
|
|
49695
|
+
return nonEmptyString(asRecord4(snapshot.session)?.id);
|
|
48918
49696
|
}
|
|
48919
49697
|
function indexProgressFromStatus(snapshot) {
|
|
48920
49698
|
const sessionID = sessionFromSnapshot(snapshot);
|
|
48921
49699
|
const progress = [];
|
|
48922
|
-
const search =
|
|
49700
|
+
const search = asRecord4(snapshot.search_index);
|
|
48923
49701
|
if (search && typeof search.status === "string") {
|
|
48924
49702
|
progress.push({
|
|
48925
49703
|
index: "search",
|
|
@@ -48928,7 +49706,7 @@ function indexProgressFromStatus(snapshot) {
|
|
|
48928
49706
|
...finiteNumber(search.files) === undefined ? {} : { completed: finiteNumber(search.files) }
|
|
48929
49707
|
});
|
|
48930
49708
|
}
|
|
48931
|
-
const semantic =
|
|
49709
|
+
const semantic = asRecord4(snapshot.semantic_index);
|
|
48932
49710
|
if (semantic && typeof semantic.status === "string") {
|
|
48933
49711
|
const stage = semantic.stage === null ? null : nonEmptyString(semantic.stage);
|
|
48934
49712
|
const completed = finiteNumber(semantic.entries_done);
|
|
@@ -49428,7 +50206,7 @@ function matchesVersion2(version, options) {
|
|
|
49428
50206
|
|
|
49429
50207
|
// ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-rg0h87gt.js
|
|
49430
50208
|
init_service_9rqn6x4v();
|
|
49431
|
-
import { readFile, rename as rename2, rm as rm2, writeFile } from "node:fs/promises";
|
|
50209
|
+
import { readFile as readFile2, rename as rename2, rm as rm2, writeFile } from "node:fs/promises";
|
|
49432
50210
|
var exports_pty_handoff = {};
|
|
49433
50211
|
__export2(exports_pty_handoff, {
|
|
49434
50212
|
PtyHandoff: () => exports_pty_handoff,
|
|
@@ -49485,7 +50263,7 @@ async function publish(file, info, handoff) {
|
|
|
49485
50263
|
}
|
|
49486
50264
|
async function environment2(file, env) {
|
|
49487
50265
|
const record = await read(file);
|
|
49488
|
-
const current = await
|
|
50266
|
+
const current = await readFile2(file, "utf8").then((text) => JSON.parse(text)).catch(() => {
|
|
49489
50267
|
return;
|
|
49490
50268
|
});
|
|
49491
50269
|
const handoff = record !== undefined && record.expiresAt > Date.now() && (current === undefined || same(record.source, current)) ? record.handoff : undefined;
|
|
@@ -49500,7 +50278,7 @@ async function clear2(file) {
|
|
|
49500
50278
|
await rm2(file + ".pty-handoff", { force: true });
|
|
49501
50279
|
}
|
|
49502
50280
|
async function read(file) {
|
|
49503
|
-
const value = await
|
|
50281
|
+
const value = await readFile2(file + ".pty-handoff", "utf8").then((text) => JSON.parse(text)).catch(() => {
|
|
49504
50282
|
return;
|
|
49505
50283
|
});
|
|
49506
50284
|
if (typeof value !== "object" || value === null || !("source" in value) || !("handoff" in value))
|
|
@@ -49534,8 +50312,8 @@ function isHandoff(value) {
|
|
|
49534
50312
|
return typeof value === "object" && value !== null && "directory" in value && typeof value.directory === "string" && "instanceID" in value && typeof value.instanceID === "string" && "ticket" in value && typeof value.ticket === "string" && "expiresAt" in value && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt);
|
|
49535
50313
|
}
|
|
49536
50314
|
// ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/promise/service.js
|
|
49537
|
-
import { readFile as
|
|
49538
|
-
import { homedir as
|
|
50315
|
+
import { readFile as readFile3, rm as rm3 } from "node:fs/promises";
|
|
50316
|
+
import { homedir as homedir15 } from "node:os";
|
|
49539
50317
|
import { join as join26 } from "node:path";
|
|
49540
50318
|
async function discover(options = {}) {
|
|
49541
50319
|
const found = (await registered(options.file)).service;
|
|
@@ -49548,7 +50326,7 @@ async function discover(options = {}) {
|
|
|
49548
50326
|
return found.endpoint;
|
|
49549
50327
|
}
|
|
49550
50328
|
function fallback() {
|
|
49551
|
-
return join26(process.env["XDG_STATE_HOME"] ?? join26(
|
|
50329
|
+
return join26(process.env["XDG_STATE_HOME"] ?? join26(homedir15(), ".local", "state"), "opencode", "service.json");
|
|
49552
50330
|
}
|
|
49553
50331
|
function headers(endpoint) {
|
|
49554
50332
|
if (endpoint.auth === undefined)
|
|
@@ -49558,7 +50336,7 @@ function headers(endpoint) {
|
|
|
49558
50336
|
};
|
|
49559
50337
|
}
|
|
49560
50338
|
async function read2(file) {
|
|
49561
|
-
const text = await
|
|
50339
|
+
const text = await readFile3(file ?? fallback(), "utf8").catch(() => {
|
|
49562
50340
|
return;
|
|
49563
50341
|
});
|
|
49564
50342
|
if (text === undefined)
|
|
@@ -49867,6 +50645,7 @@ var defaults = {
|
|
|
49867
50645
|
}),
|
|
49868
50646
|
acquireBridge,
|
|
49869
50647
|
releaseBridge,
|
|
50648
|
+
startLiveConfigReload: startOpenCodeLiveConfigReload,
|
|
49870
50649
|
resolvePoolOptions: resolveBridgePoolTransportOptions,
|
|
49871
50650
|
resolveVersion: () => resolvePluginVersion(import.meta.url)
|
|
49872
50651
|
};
|
|
@@ -49920,7 +50699,17 @@ async function bootLocation(context, location, dependencies) {
|
|
|
49920
50699
|
const { hashlineEditRegistered } = applyToolSurfaceOverrides(pool, config, registeredTools);
|
|
49921
50700
|
reportHashlineDowngrade(config, registeredTools, notify);
|
|
49922
50701
|
toolContext.hashlineEffective = hashlineEditRegistered;
|
|
49923
|
-
|
|
50702
|
+
const liveConfigReload = dependencies.startLiveConfigReload({
|
|
50703
|
+
directory,
|
|
50704
|
+
initialSources: bootstrap.sources ?? [],
|
|
50705
|
+
initialSourceTexts: bootstrap.sourceTexts,
|
|
50706
|
+
getConfig: () => toolContext.config,
|
|
50707
|
+
setConfig: (next) => {
|
|
50708
|
+
toolContext.config = next;
|
|
50709
|
+
},
|
|
50710
|
+
notify
|
|
50711
|
+
});
|
|
50712
|
+
return { consumers, pool, tools, liveConfigReload };
|
|
49924
50713
|
}
|
|
49925
50714
|
var runningByDirectory = new Map;
|
|
49926
50715
|
var startsInProcess = 0;
|
|
@@ -49962,6 +50751,7 @@ function makeServerEffect(overrides = {}) {
|
|
|
49962
50751
|
return;
|
|
49963
50752
|
}
|
|
49964
50753
|
yield* Effect7.addFinalizer(() => Effect7.promise(async () => {
|
|
50754
|
+
runtime.liveConfigReload?.stop();
|
|
49965
50755
|
runtime.consumers.dispose?.();
|
|
49966
50756
|
await dependencies.releaseBridge(runtime.pool);
|
|
49967
50757
|
}));
|