@cortexkit/aft 0.63.5 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/opencode.d.ts +7 -5
- package/dist/adapters/opencode.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +12 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/commands/cache.d.ts +2 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/doctor/opencode.d.ts +1 -0
- package/dist/doctor/opencode.d.ts.map +1 -1
- package/dist/index.js +637 -317
- package/dist/lib/config-migration.d.ts +5 -1
- package/dist/lib/config-migration.d.ts.map +1 -1
- package/dist/lib/diagnostics.d.ts +1 -0
- package/dist/lib/diagnostics.d.ts.map +1 -1
- package/dist/lib/doctor-labels.d.ts +4 -0
- package/dist/lib/doctor-labels.d.ts.map +1 -0
- package/dist/lib/opencode-plugin-cache.d.ts +9 -0
- package/dist/lib/opencode-plugin-cache.d.ts.map +1 -0
- package/dist/lib/semver.d.ts +3 -0
- package/dist/lib/semver.d.ts.map +1 -0
- package/dist/setup/opencode-config.d.ts +12 -4
- package/dist/setup/opencode-config.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -498,12 +498,13 @@ function resolvePluginLogPath(context = {}) {
|
|
|
498
498
|
var init_storage_paths = () => {};
|
|
499
499
|
|
|
500
500
|
// ../aft-bridge/dist/bash-host-fallback.js
|
|
501
|
-
var BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES, BASH_HOST_FALLBACK_MAX_TIMEOUT_MS;
|
|
501
|
+
var BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES, BASH_HOST_FALLBACK_MAX_TIMEOUT_MS, BASH_RUNON_MEMORY_DESCRIPTION = "On Linux, add `,Ngb` to ask for N GiB of memory, for example `linux,2c,16gb` for a Rust build.", BASH_RUNON_DESCRIPTION;
|
|
502
502
|
var init_bash_host_fallback = __esm(() => {
|
|
503
503
|
init_child_process();
|
|
504
504
|
init_storage_paths();
|
|
505
505
|
BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES = 100 * 1024;
|
|
506
506
|
BASH_HOST_FALLBACK_MAX_TIMEOUT_MS = 10 * 60 * 1000;
|
|
507
|
+
BASH_RUNON_DESCRIPTION = 'Run on a remote build server: `linux` (2 vCPUs), or `linux,Nc` for N vCPUs such as `linux,8c`; add ",net" for outbound internet (offline by default). `windows` runs the command in Git Bash on a Windows build machine (no vCPU or network options). `macos` sends the command to a macOS machine for builds and tests that need macOS (no vCPU or network options).' + ` ${BASH_RUNON_MEMORY_DESCRIPTION}`;
|
|
507
508
|
});
|
|
508
509
|
// ../aft-bridge/dist/bash-permissions.js
|
|
509
510
|
var init_bash_permissions = __esm(() => {
|
|
@@ -2289,7 +2290,10 @@ function readConfigTiers(opts) {
|
|
|
2289
2290
|
var init_config_tiers = () => {};
|
|
2290
2291
|
|
|
2291
2292
|
// ../aft-bridge/dist/config-watch.js
|
|
2292
|
-
var
|
|
2293
|
+
var CONFIG_READ_LIMIT;
|
|
2294
|
+
var init_config_watch = __esm(() => {
|
|
2295
|
+
CONFIG_READ_LIMIT = 1024 * 1024;
|
|
2296
|
+
});
|
|
2293
2297
|
|
|
2294
2298
|
// ../aft-bridge/dist/platform.js
|
|
2295
2299
|
var PLATFORM_ARCH_MAP, PLATFORM_ASSET_MAP;
|
|
@@ -3539,6 +3543,44 @@ function dropNoEffectPaths(map, prefix, out) {
|
|
|
3539
3543
|
}
|
|
3540
3544
|
}
|
|
3541
3545
|
}
|
|
3546
|
+
function retiredIdleCheckoutHours(value) {
|
|
3547
|
+
const raw = typeof value === "number" && Number.isSafeInteger(value) ? value : IDLE_CHECKOUT_HOURS_DEFAULT;
|
|
3548
|
+
return Math.min(IDLE_CHECKOUT_HOURS_MAX, Math.max(IDLE_CHECKOUT_HOURS_MIN, raw));
|
|
3549
|
+
}
|
|
3550
|
+
function translateDataLayerPaths(map, prefix, out) {
|
|
3551
|
+
const [retired, replacement] = RETIRED_IDLE_CHECKOUT_HOURS;
|
|
3552
|
+
const hours = takeNested(map, "views", "idle_checkout_hours");
|
|
3553
|
+
if (hours.found) {
|
|
3554
|
+
recordRetired(out, prefix, retired);
|
|
3555
|
+
if (isRecord(map.idle) && map.idle.checkout_hours !== undefined) {
|
|
3556
|
+
superseded(out, `${prefix}${retired}`, `${retired} is ignored because ${replacement} is set`);
|
|
3557
|
+
} else {
|
|
3558
|
+
if (!Object.hasOwn(map, "idle"))
|
|
3559
|
+
map.idle = {};
|
|
3560
|
+
if (isRecord(map.idle))
|
|
3561
|
+
map.idle.checkout_hours = retiredIdleCheckoutHours(hours.value);
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
for (const path of REMOVED_DATA_LAYER_PATHS) {
|
|
3565
|
+
if (hasPath(map, path))
|
|
3566
|
+
out.removedKeys.push(`${prefix}${path}`);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
function dropRemovedDataLayerKeys(map) {
|
|
3570
|
+
const blocks = [map];
|
|
3571
|
+
if (isRecord(map.harnesses)) {
|
|
3572
|
+
for (const block of Object.values(map.harnesses))
|
|
3573
|
+
if (isRecord(block))
|
|
3574
|
+
blocks.push(block);
|
|
3575
|
+
}
|
|
3576
|
+
for (const block of blocks) {
|
|
3577
|
+
for (const path of REMOVED_DATA_LAYER_PATHS) {
|
|
3578
|
+
const [container, leaf] = path.split(".");
|
|
3579
|
+
if (container && leaf)
|
|
3580
|
+
takeNested(block, container, leaf);
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3542
3584
|
function translateExperimentalPaths(map, prefix, out) {
|
|
3543
3585
|
for (const [oldKey, leaf] of [
|
|
3544
3586
|
["experimental_lsp_ty", "lsp_ty"],
|
|
@@ -3571,23 +3613,25 @@ function translateExperimentalPaths(map, prefix, out) {
|
|
|
3571
3613
|
const experimental = map.experimental;
|
|
3572
3614
|
const legacy = experimental.bash;
|
|
3573
3615
|
if (isRecord(legacy)) {
|
|
3574
|
-
if (
|
|
3575
|
-
|
|
3616
|
+
if (Object.keys(legacy).length === 0)
|
|
3617
|
+
recordRetired(out, prefix, "experimental.bash");
|
|
3576
3618
|
for (const leaf of Object.keys(legacy))
|
|
3577
3619
|
recordRetired(out, prefix, `experimental.bash.${leaf}`);
|
|
3578
3620
|
if (Object.hasOwn(map, "bash")) {
|
|
3579
3621
|
superseded(out, "experimental.bash", 'experimental.bash is ignored because top-level "bash" is already set');
|
|
3580
3622
|
} else {
|
|
3581
|
-
const bash = {
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3623
|
+
const bash = {};
|
|
3624
|
+
if (["rewrite", "compress", "background"].some((leaf) => Object.hasOwn(legacy, leaf))) {
|
|
3625
|
+
bash.rewrite = legacy.rewrite === true;
|
|
3626
|
+
bash.compress = legacy.compress === true;
|
|
3627
|
+
bash.background = legacy.background === true;
|
|
3628
|
+
}
|
|
3586
3629
|
for (const leaf of ["long_running_reminder_enabled", "long_running_reminder_interval_ms"]) {
|
|
3587
3630
|
if (Object.hasOwn(legacy, leaf))
|
|
3588
3631
|
bash[leaf] = legacy[leaf];
|
|
3589
3632
|
}
|
|
3590
|
-
|
|
3633
|
+
if (Object.keys(bash).length > 0)
|
|
3634
|
+
map.bash = bash;
|
|
3591
3635
|
}
|
|
3592
3636
|
} else {
|
|
3593
3637
|
recordRetired(out, prefix, "experimental.bash");
|
|
@@ -3600,6 +3644,7 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
3600
3644
|
const prefix = blockLabel === "base" ? "" : `${blockLabel}.`;
|
|
3601
3645
|
translateGithubAliases(map, prefix, out);
|
|
3602
3646
|
translateInspectLspPaths(map, prefix, out);
|
|
3647
|
+
translateDataLayerPaths(map, prefix, out);
|
|
3603
3648
|
dropNoEffectPaths(map, prefix, out);
|
|
3604
3649
|
translateExperimentalPaths(map, prefix, out);
|
|
3605
3650
|
if (isRecord(map.sandbox) && Object.hasOwn(map.sandbox, "enabled")) {
|
|
@@ -3638,8 +3683,6 @@ function translateBlock(map, userBase, blockLabel, out) {
|
|
|
3638
3683
|
});
|
|
3639
3684
|
}
|
|
3640
3685
|
for (const [path] of RETIRED_PATHS) {
|
|
3641
|
-
if (path === "experimental.bash")
|
|
3642
|
-
continue;
|
|
3643
3686
|
if (hasPath(map, path))
|
|
3644
3687
|
recordRetired(out, prefix, path);
|
|
3645
3688
|
}
|
|
@@ -3772,6 +3815,7 @@ function translateConfigDocument(map, tier) {
|
|
|
3772
3815
|
warnings: [],
|
|
3773
3816
|
legacyInput: false,
|
|
3774
3817
|
retiredKeys: [],
|
|
3818
|
+
removedKeys: [],
|
|
3775
3819
|
retiredEnabledFalse: false
|
|
3776
3820
|
};
|
|
3777
3821
|
translateBlock(map, tier === "user", "base", out);
|
|
@@ -3782,6 +3826,7 @@ function translateConfigDocument(map, tier) {
|
|
|
3782
3826
|
}
|
|
3783
3827
|
}
|
|
3784
3828
|
out.retiredKeys = sortedUnique(out.retiredKeys);
|
|
3829
|
+
out.removedKeys = sortedUnique(out.removedKeys);
|
|
3785
3830
|
return out;
|
|
3786
3831
|
}
|
|
3787
3832
|
function canonicalJson(value) {
|
|
@@ -3808,7 +3853,7 @@ function mergeIndexes(base, override, restricted) {
|
|
|
3808
3853
|
}
|
|
3809
3854
|
return merged;
|
|
3810
3855
|
}
|
|
3811
|
-
var CANONICAL_TOOLS, HOST_TOOL_NAMES, DEFAULT_DISABLED_TOOLS, LEGACY_TOOL_ALIASES, RETIRED_PATHS, INDEX_INPUTS, LSP_IDLE_MINUTES_DEFAULT = 60, LSP_IDLE_MINUTES_MIN = 5, LSP_IDLE_MINUTES_MAX = 1440, REMOVED_NO_EFFECT_PATHS, RETIRED_ENABLED_FALSE_INDEXES_NOTE = "enabled: false no longer turns AFT off: it is translated to disabling every tool, but the trigram, semantic and callgraph indexes still build. To keep AFT from indexing this repository, also set indexes.trigram, indexes.semantic and indexes.callgraph to false.", SEMANTIC_COST_NOTICE_DIGEST, SECURITY_CONFIG_SECTIONS;
|
|
3856
|
+
var CANONICAL_TOOLS, HOST_TOOL_NAMES, DEFAULT_DISABLED_TOOLS, LEGACY_TOOL_ALIASES, REMOVED_DATA_LAYER_PATHS, RETIRED_IDLE_CHECKOUT_HOURS, IDLE_CHECKOUT_HOURS_DEFAULT = 168, IDLE_CHECKOUT_HOURS_MIN = 1, IDLE_CHECKOUT_HOURS_MAX, AFT_PACKAGE_NAMES, RETIRED_PATHS, INDEX_INPUTS, LSP_IDLE_MINUTES_DEFAULT = 60, LSP_IDLE_MINUTES_MIN = 5, LSP_IDLE_MINUTES_MAX = 1440, REMOVED_NO_EFFECT_PATHS, RETIRED_ENABLED_FALSE_INDEXES_NOTE = "enabled: false no longer turns AFT off: it is translated to disabling every tool, but the trigram, semantic and callgraph indexes still build. To keep AFT from indexing this repository, also set indexes.trigram, indexes.semantic and indexes.callgraph to false.", SEMANTIC_COST_NOTICE_DIGEST, SECURITY_CONFIG_SECTIONS;
|
|
3812
3857
|
var init_feature_config = __esm(() => {
|
|
3813
3858
|
CANONICAL_TOOLS = [
|
|
3814
3859
|
"aft_callgraph",
|
|
@@ -3854,6 +3899,22 @@ var init_feature_config = __esm(() => {
|
|
|
3854
3899
|
aft_glob: "glob",
|
|
3855
3900
|
aft_bash: "bash"
|
|
3856
3901
|
};
|
|
3902
|
+
REMOVED_DATA_LAYER_PATHS = [
|
|
3903
|
+
"views.callgraph_copies",
|
|
3904
|
+
"views.enabled",
|
|
3905
|
+
"worktree.ram_overlay"
|
|
3906
|
+
];
|
|
3907
|
+
RETIRED_IDLE_CHECKOUT_HOURS = [
|
|
3908
|
+
"views.idle_checkout_hours",
|
|
3909
|
+
"idle.checkout_hours"
|
|
3910
|
+
];
|
|
3911
|
+
IDLE_CHECKOUT_HOURS_MAX = 24 * 365;
|
|
3912
|
+
AFT_PACKAGE_NAMES = new Set([
|
|
3913
|
+
"@cortexkit/aft-bridge",
|
|
3914
|
+
"@cortexkit/aft-opencode",
|
|
3915
|
+
"@cortexkit/aft-pi",
|
|
3916
|
+
"@cortexkit/aft"
|
|
3917
|
+
]);
|
|
3857
3918
|
RETIRED_PATHS = [
|
|
3858
3919
|
["sandbox.enabled", "sandbox.profile"],
|
|
3859
3920
|
["tool_surface", "disabled_tools"],
|
|
@@ -3876,7 +3937,10 @@ var init_feature_config = __esm(() => {
|
|
|
3876
3937
|
["semantic", "semantic_search", "experimental_semantic_search"],
|
|
3877
3938
|
["callgraph", "callgraph_store", undefined]
|
|
3878
3939
|
];
|
|
3879
|
-
REMOVED_NO_EFFECT_PATHS = [
|
|
3940
|
+
REMOVED_NO_EFFECT_PATHS = [
|
|
3941
|
+
"bridge.hang_threshold",
|
|
3942
|
+
"inspect.tier2_idle_minutes"
|
|
3943
|
+
];
|
|
3880
3944
|
SEMANTIC_COST_NOTICE_DIGEST = noticeDigest({ notice: "semantic_default_cost_v1" });
|
|
3881
3945
|
SECURITY_CONFIG_SECTIONS = new Set([
|
|
3882
3946
|
"restrict_to_project_root",
|
|
@@ -4127,6 +4191,8 @@ function quoteCmdArgument(value) {
|
|
|
4127
4191
|
return `"${value}"`;
|
|
4128
4192
|
}
|
|
4129
4193
|
function npmInvocation(resolved, npmArgs, platform = process.platform, env = process.env) {
|
|
4194
|
+
if (resolved.cliPath)
|
|
4195
|
+
return { command: resolved.command, args: [resolved.cliPath, ...npmArgs] };
|
|
4130
4196
|
if (platform !== "win32" || !/\.(?:cmd|bat)$/i.test(resolved.command)) {
|
|
4131
4197
|
return { command: resolved.command, args: [...npmArgs] };
|
|
4132
4198
|
}
|
|
@@ -4319,6 +4385,12 @@ var init_lsp_npm_policy = __esm(() => {
|
|
|
4319
4385
|
NPM_PROBE_RETRY_MS = 5 * 60000;
|
|
4320
4386
|
});
|
|
4321
4387
|
|
|
4388
|
+
// ../aft-bridge/dist/lsp-npm-selection.js
|
|
4389
|
+
var init_lsp_npm_selection = __esm(() => {
|
|
4390
|
+
init_lsp_npm_policy();
|
|
4391
|
+
init_npm_resolver();
|
|
4392
|
+
});
|
|
4393
|
+
|
|
4322
4394
|
// ../aft-bridge/dist/message-detach.js
|
|
4323
4395
|
var BASH_WAIT_DETACH_MAGIC_KEYWORD = "&detach", STANDALONE_DETACH_KEYWORD_SOURCE, STANDALONE_DETACH_KEYWORD_PATTERN, STANDALONE_DETACH_KEYWORDS_PATTERN;
|
|
4324
4396
|
var init_message_detach = __esm(() => {
|
|
@@ -5489,6 +5561,7 @@ var init_dist2 = __esm(() => {
|
|
|
5489
5561
|
init_lsp_github_probe();
|
|
5490
5562
|
init_lsp_github_table();
|
|
5491
5563
|
init_lsp_npm_policy();
|
|
5564
|
+
init_lsp_npm_selection();
|
|
5492
5565
|
init_message_detach();
|
|
5493
5566
|
init_migration();
|
|
5494
5567
|
init_migration_notices();
|
|
@@ -14177,27 +14250,54 @@ var init_jsonc = __esm(() => {
|
|
|
14177
14250
|
import_comment_json = __toESM(require_src2(), 1);
|
|
14178
14251
|
});
|
|
14179
14252
|
|
|
14180
|
-
// src/lib/self-version.ts
|
|
14181
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
14182
|
-
function getSelfVersion() {
|
|
14183
|
-
const require2 = createRequire2(import.meta.url);
|
|
14184
|
-
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
14185
|
-
try {
|
|
14186
|
-
const version = require2(relPath).version;
|
|
14187
|
-
if (typeof version === "string" && version.length > 0) {
|
|
14188
|
-
return version;
|
|
14189
|
-
}
|
|
14190
|
-
} catch {}
|
|
14191
|
-
}
|
|
14192
|
-
return "unknown";
|
|
14193
|
-
}
|
|
14194
|
-
var init_self_version = () => {};
|
|
14195
|
-
|
|
14196
14253
|
// ../../.github/opencode-version.txt
|
|
14197
14254
|
var opencode_version_default = `1.19.3
|
|
14198
14255
|
`;
|
|
14199
14256
|
var init_opencode_version = () => {};
|
|
14200
14257
|
|
|
14258
|
+
// src/lib/semver.ts
|
|
14259
|
+
function parse2(version) {
|
|
14260
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.exec(version);
|
|
14261
|
+
if (!match)
|
|
14262
|
+
return;
|
|
14263
|
+
const prerelease = match[4]?.split(".") ?? [];
|
|
14264
|
+
if (prerelease.some((part) => /^\d+$/.test(part) && part.length > 1 && part[0] === "0")) {
|
|
14265
|
+
return;
|
|
14266
|
+
}
|
|
14267
|
+
return { core: match.slice(1, 4).map(BigInt), prerelease };
|
|
14268
|
+
}
|
|
14269
|
+
function compareSemver2(left, right) {
|
|
14270
|
+
const a = parse2(left);
|
|
14271
|
+
const b = parse2(right);
|
|
14272
|
+
if (!a || !b)
|
|
14273
|
+
return;
|
|
14274
|
+
for (let i = 0;i < 3; i++) {
|
|
14275
|
+
if (a.core[i] !== b.core[i])
|
|
14276
|
+
return a.core[i] > b.core[i] ? 1 : -1;
|
|
14277
|
+
}
|
|
14278
|
+
if (!a.prerelease.length || !b.prerelease.length) {
|
|
14279
|
+
return a.prerelease.length === b.prerelease.length ? 0 : a.prerelease.length ? -1 : 1;
|
|
14280
|
+
}
|
|
14281
|
+
for (let i = 0;i < Math.max(a.prerelease.length, b.prerelease.length); i++) {
|
|
14282
|
+
const x = a.prerelease[i];
|
|
14283
|
+
const y = b.prerelease[i];
|
|
14284
|
+
if (x === y)
|
|
14285
|
+
continue;
|
|
14286
|
+
if (x === undefined)
|
|
14287
|
+
return -1;
|
|
14288
|
+
if (y === undefined)
|
|
14289
|
+
return 1;
|
|
14290
|
+
const xn = /^\d+$/.test(x);
|
|
14291
|
+
const yn = /^\d+$/.test(y);
|
|
14292
|
+
if (xn && yn)
|
|
14293
|
+
return BigInt(x) > BigInt(y) ? 1 : -1;
|
|
14294
|
+
if (xn !== yn)
|
|
14295
|
+
return xn ? -1 : 1;
|
|
14296
|
+
return x > y ? 1 : -1;
|
|
14297
|
+
}
|
|
14298
|
+
return 0;
|
|
14299
|
+
}
|
|
14300
|
+
|
|
14201
14301
|
// src/setup/opencode-config.ts
|
|
14202
14302
|
function openCodePluginKey(generation) {
|
|
14203
14303
|
return generation === "v2" ? "plugins" : "plugin";
|
|
@@ -14215,6 +14315,24 @@ function openCodePluginReadKeys(generation) {
|
|
|
14215
14315
|
function pinnedPluginEntry(version) {
|
|
14216
14316
|
return `${AFT_OPENCODE_PACKAGE}@${version}`;
|
|
14217
14317
|
}
|
|
14318
|
+
function preserveDoctorPluginEntry(cli, entry, installed) {
|
|
14319
|
+
const configured = entry ? exactPinnedVersion(entry) : null;
|
|
14320
|
+
const configuredOrder = configured ? compareSemver2(configured, cli) : undefined;
|
|
14321
|
+
const installedOrder = installed ? compareSemver2(installed, cli) : undefined;
|
|
14322
|
+
if (installed && (installedOrder === undefined || installedOrder > 0))
|
|
14323
|
+
return true;
|
|
14324
|
+
if (configured && (configuredOrder === undefined || configuredOrder > 0))
|
|
14325
|
+
return true;
|
|
14326
|
+
if (entry === AFT_OPENCODE_PACKAGE)
|
|
14327
|
+
return false;
|
|
14328
|
+
return Boolean(entry && configuredOrder === undefined && installedOrder === undefined);
|
|
14329
|
+
}
|
|
14330
|
+
function doctorNoDowngradeMessage(cli, entry, installed) {
|
|
14331
|
+
const configured = entry ? exactPinnedVersion(entry) : null;
|
|
14332
|
+
const newerInstalled = installed && (compareSemver2(installed, cli) ?? 1) > 0;
|
|
14333
|
+
const plugin = newerInstalled ? installed : (configured ?? entry?.slice(AFT_OPENCODE_PACKAGE.length + 1)) || "unknown";
|
|
14334
|
+
return DOCTOR_NO_DOWNGRADE.replace("<cli>", cli).replace("<plugin>", plugin);
|
|
14335
|
+
}
|
|
14218
14336
|
function describePluginEntry(entry) {
|
|
14219
14337
|
if (entry === AFT_OPENCODE_PACKAGE) {
|
|
14220
14338
|
return "has no version, so OpenCode may load any release of the plugin";
|
|
@@ -14287,8 +14405,8 @@ function findLocalAftEntry(list, hasLocalAftEntry) {
|
|
|
14287
14405
|
}
|
|
14288
14406
|
return null;
|
|
14289
14407
|
}
|
|
14290
|
-
function ensurePinnedPluginConfig(value, version, hasLocalAftEntry = () => false, generation = "unknown") {
|
|
14291
|
-
const entry = pinnedPluginEntry(version);
|
|
14408
|
+
function ensurePinnedPluginConfig(value, version, hasLocalAftEntry = () => false, generation = "unknown", policy = {}) {
|
|
14409
|
+
const entry = policy.fallbackEntry ?? pinnedPluginEntry(version);
|
|
14292
14410
|
const key = openCodePluginKey(generation);
|
|
14293
14411
|
const hadKey = Array.isArray(value[key]);
|
|
14294
14412
|
const list = hadKey ? value[key] : [];
|
|
@@ -14302,6 +14420,21 @@ function ensurePinnedPluginConfig(value, version, hasLocalAftEntry = () => false
|
|
|
14302
14420
|
}
|
|
14303
14421
|
if (npmIndexes.length > 0) {
|
|
14304
14422
|
const firstIndex = npmIndexes[0];
|
|
14423
|
+
if (policy.doctor && npmIndexes.some((index) => preserveDoctorPluginEntry(version, pluginEntryPackage(list[index]) ?? undefined, policy.installedVersion))) {
|
|
14424
|
+
let changed = false;
|
|
14425
|
+
for (const index of npmIndexes) {
|
|
14426
|
+
const spec = pluginEntryPackage(list[index]);
|
|
14427
|
+
const shaped = shapePluginEntry(key, spec, pluginEntryOptions(list[index]));
|
|
14428
|
+
changed ||= !sameEntry(list[index], shaped);
|
|
14429
|
+
list[index] = shaped;
|
|
14430
|
+
}
|
|
14431
|
+
return {
|
|
14432
|
+
action: changed ? "updated" : "already_present",
|
|
14433
|
+
changed,
|
|
14434
|
+
entry: pluginEntryPackage(list[firstIndex]),
|
|
14435
|
+
key
|
|
14436
|
+
};
|
|
14437
|
+
}
|
|
14305
14438
|
const shaped = shapePluginEntry(key, entry, pluginEntryOptions(list[firstIndex]));
|
|
14306
14439
|
const wasExact = sameEntry(list[firstIndex], shaped);
|
|
14307
14440
|
list[firstIndex] = shaped;
|
|
@@ -14320,13 +14453,24 @@ function ensurePinnedPluginConfig(value, version, hasLocalAftEntry = () => false
|
|
|
14320
14453
|
}
|
|
14321
14454
|
const sibling = value[otherOpenCodePluginKey(key)];
|
|
14322
14455
|
const siblingList = Array.isArray(sibling) ? sibling : null;
|
|
14456
|
+
if (policy.doctor && siblingList) {
|
|
14457
|
+
const preserved = siblingList.find((candidate) => {
|
|
14458
|
+
const spec = pluginEntryPackage(candidate);
|
|
14459
|
+
return spec !== null && isAftNpmEntry(spec) && preserveDoctorPluginEntry(version, spec, policy.installedVersion);
|
|
14460
|
+
});
|
|
14461
|
+
const spec = pluginEntryPackage(preserved);
|
|
14462
|
+
if (spec) {
|
|
14463
|
+
list.push(shapePluginEntry(key, spec, pluginEntryOptions(preserved)));
|
|
14464
|
+
return { action: "added", changed: true, entry: spec, key };
|
|
14465
|
+
}
|
|
14466
|
+
}
|
|
14323
14467
|
const carried = siblingList ? findLocalAftEntry(siblingList, hasLocalAftEntry) : null;
|
|
14324
14468
|
list.push(carried ? shapePluginEntry(key, carried.packageSpec, carried.options) : entry);
|
|
14325
14469
|
if (carried && siblingList)
|
|
14326
14470
|
siblingList.splice(carried.index, 1);
|
|
14327
14471
|
return { action: "added", changed: true, entry, key };
|
|
14328
14472
|
}
|
|
14329
|
-
function pluginConfigNeedsUpdate(value, version, hasLocalAftEntry = () => false, generation = "unknown") {
|
|
14473
|
+
function pluginConfigNeedsUpdate(value, version, hasLocalAftEntry = () => false, generation = "unknown", policy = {}) {
|
|
14330
14474
|
const key = openCodePluginKey(generation);
|
|
14331
14475
|
const list = value[key];
|
|
14332
14476
|
if (!Array.isArray(list))
|
|
@@ -14336,7 +14480,9 @@ function pluginConfigNeedsUpdate(value, version, hasLocalAftEntry = () => false,
|
|
|
14336
14480
|
return packageSpec !== null && isAftNpmEntry(packageSpec);
|
|
14337
14481
|
});
|
|
14338
14482
|
if (npmEntries.length > 0) {
|
|
14339
|
-
|
|
14483
|
+
if (policy.doctor && npmEntries.some((candidate) => preserveDoctorPluginEntry(version, pluginEntryPackage(candidate) ?? undefined, policy.installedVersion)))
|
|
14484
|
+
return npmEntries.some((candidate) => !pluginEntryFitsKey(candidate, key));
|
|
14485
|
+
return npmEntries.length !== 1 || pluginEntryPackage(npmEntries[0]) !== (policy.fallbackEntry ?? pinnedPluginEntry(version)) || !pluginEntryFitsKey(npmEntries[0], key);
|
|
14340
14486
|
}
|
|
14341
14487
|
const local = findLocalAftEntry(list, hasLocalAftEntry);
|
|
14342
14488
|
if (local)
|
|
@@ -14386,7 +14532,7 @@ function aftHostReplacementEnabled(userConfig, hostTool) {
|
|
|
14386
14532
|
}
|
|
14387
14533
|
return true;
|
|
14388
14534
|
}
|
|
14389
|
-
var AFT_OPENCODE_PACKAGE = "@cortexkit/aft-opencode", MODERN_V1_VERSION, EXACT_VERSION, OPENCODE_HOST_SHELL_DISABLE_ENTRY = "-opencode.tool.shell", OPENCODE_HOST_PATCH_DISABLE_ENTRY = "-opencode.tool.patch", OPENCODE_HOST_TOOLS, OPENCODE_HOST_TOOL_NAMES;
|
|
14535
|
+
var AFT_OPENCODE_PACKAGE = "@cortexkit/aft-opencode", MODERN_V1_VERSION, DOCTOR_NO_DOWNGRADE = "This doctor is AFT <cli>; OpenCode is configured for AFT plugin <plugin>. Doctor will not downgrade that entry. Run doctor with a matching or newer CLI.", EXACT_VERSION, OPENCODE_HOST_SHELL_DISABLE_ENTRY = "-opencode.tool.shell", OPENCODE_HOST_PATCH_DISABLE_ENTRY = "-opencode.tool.patch", OPENCODE_HOST_TOOLS, OPENCODE_HOST_TOOL_NAMES;
|
|
14390
14536
|
var init_opencode_config = __esm(() => {
|
|
14391
14537
|
init_opencode_version();
|
|
14392
14538
|
MODERN_V1_VERSION = opencode_version_default.trim();
|
|
@@ -14398,29 +14544,138 @@ var init_opencode_config = __esm(() => {
|
|
|
14398
14544
|
OPENCODE_HOST_TOOL_NAMES = Object.keys(OPENCODE_HOST_TOOLS);
|
|
14399
14545
|
});
|
|
14400
14546
|
|
|
14547
|
+
// src/lib/opencode-plugin-cache.ts
|
|
14548
|
+
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync10 } from "node:fs";
|
|
14549
|
+
import { dirname as dirname8, join as join18 } from "node:path";
|
|
14550
|
+
function discoverLocalOpenCodePlugin(path, cliVersion) {
|
|
14551
|
+
let current = path;
|
|
14552
|
+
for (;; ) {
|
|
14553
|
+
const manifestPath = join18(current, "package.json");
|
|
14554
|
+
try {
|
|
14555
|
+
const pkg = JSON.parse(readFileSync10(manifestPath, "utf8"));
|
|
14556
|
+
if (pkg.name === AFT_OPENCODE_PACKAGE && typeof pkg.version === "string") {
|
|
14557
|
+
return {
|
|
14558
|
+
path: current,
|
|
14559
|
+
manifestPath,
|
|
14560
|
+
cached: pkg.version,
|
|
14561
|
+
version: pkg.version,
|
|
14562
|
+
versionSource: "installed",
|
|
14563
|
+
exists: true,
|
|
14564
|
+
cliVersion,
|
|
14565
|
+
local: true
|
|
14566
|
+
};
|
|
14567
|
+
}
|
|
14568
|
+
} catch {}
|
|
14569
|
+
const parent = dirname8(current);
|
|
14570
|
+
if (parent === current)
|
|
14571
|
+
return;
|
|
14572
|
+
current = parent;
|
|
14573
|
+
}
|
|
14574
|
+
}
|
|
14575
|
+
function discoverOpenCodePluginCache(root, entry, generation, cliVersion, configuredEntry) {
|
|
14576
|
+
const v1 = join18(root, "packages", entry);
|
|
14577
|
+
const v2 = join18(root, "npm", entry === AFT_OPENCODE_PACKAGE ? `${entry}@latest` : entry);
|
|
14578
|
+
const paths = [];
|
|
14579
|
+
if (generation !== "v1") {
|
|
14580
|
+
try {
|
|
14581
|
+
const timestamps = readdirSync6(v2).filter((name) => /^\d+$/.test(name));
|
|
14582
|
+
timestamps.sort((a, b) => BigInt(a) > BigInt(b) ? -1 : BigInt(a) < BigInt(b) ? 1 : 0);
|
|
14583
|
+
if (timestamps[0])
|
|
14584
|
+
paths.push(join18(v2, timestamps[0]));
|
|
14585
|
+
} catch {}
|
|
14586
|
+
}
|
|
14587
|
+
if (generation === "v1" || generation !== "v2" && paths.length === 0)
|
|
14588
|
+
paths.push(v1);
|
|
14589
|
+
let readError;
|
|
14590
|
+
for (const path of paths) {
|
|
14591
|
+
const manifestPath = join18(path, "node_modules", AFT_OPENCODE_PACKAGE, "package.json");
|
|
14592
|
+
try {
|
|
14593
|
+
const pkg = JSON.parse(readFileSync10(manifestPath, "utf8"));
|
|
14594
|
+
if (pkg.name !== AFT_OPENCODE_PACKAGE || typeof pkg.version !== "string" || compareSemver2(pkg.version, pkg.version) !== 0) {
|
|
14595
|
+
readError = `Invalid plugin identity or version at ${manifestPath}`;
|
|
14596
|
+
continue;
|
|
14597
|
+
}
|
|
14598
|
+
if (typeof pkg.main === "string" && !existsSync14(join18(path, "node_modules", AFT_OPENCODE_PACKAGE, pkg.main))) {
|
|
14599
|
+
readError = `Incomplete plugin installation at ${manifestPath}`;
|
|
14600
|
+
continue;
|
|
14601
|
+
}
|
|
14602
|
+
return {
|
|
14603
|
+
path,
|
|
14604
|
+
manifestPath,
|
|
14605
|
+
cached: pkg.version,
|
|
14606
|
+
version: pkg.version,
|
|
14607
|
+
versionSource: "installed",
|
|
14608
|
+
configuredEntry,
|
|
14609
|
+
exists: true,
|
|
14610
|
+
cliVersion
|
|
14611
|
+
};
|
|
14612
|
+
} catch (error) {
|
|
14613
|
+
if (error.code !== "ENOENT" || existsSync14(path))
|
|
14614
|
+
readError = String(error);
|
|
14615
|
+
}
|
|
14616
|
+
}
|
|
14617
|
+
return {
|
|
14618
|
+
path: paths[0] ?? (generation === "v2" ? v2 : v1),
|
|
14619
|
+
cached: undefined,
|
|
14620
|
+
version: configuredEntry ? exactPinnedVersion(configuredEntry) ?? undefined : undefined,
|
|
14621
|
+
versionSource: configuredEntry && exactPinnedVersion(configuredEntry) ? "configured" : "unknown",
|
|
14622
|
+
readError,
|
|
14623
|
+
exists: false,
|
|
14624
|
+
configuredEntry,
|
|
14625
|
+
cliVersion
|
|
14626
|
+
};
|
|
14627
|
+
}
|
|
14628
|
+
function doctorInstalledVersion(cache) {
|
|
14629
|
+
return cache.cached ?? (cache.readError ? "unknown" : undefined);
|
|
14630
|
+
}
|
|
14631
|
+
function describePluginVersion(cache) {
|
|
14632
|
+
const version = cache.version ?? cache.cached;
|
|
14633
|
+
const source = cache.versionSource ?? (cache.cached ? "installed" : "unknown");
|
|
14634
|
+
return `${version ?? "unknown"} (${source}${cache.manifestPath ? `: ${cache.manifestPath}` : source === "configured" && cache.configuredEntry ? `: ${cache.configuredEntry}` : ""})`;
|
|
14635
|
+
}
|
|
14636
|
+
var init_opencode_plugin_cache = __esm(() => {
|
|
14637
|
+
init_opencode_config();
|
|
14638
|
+
});
|
|
14639
|
+
|
|
14640
|
+
// src/lib/self-version.ts
|
|
14641
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
14642
|
+
function getSelfVersion() {
|
|
14643
|
+
const require2 = createRequire2(import.meta.url);
|
|
14644
|
+
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
14645
|
+
try {
|
|
14646
|
+
const version = require2(relPath).version;
|
|
14647
|
+
if (typeof version === "string" && version.length > 0) {
|
|
14648
|
+
return version;
|
|
14649
|
+
}
|
|
14650
|
+
} catch {}
|
|
14651
|
+
}
|
|
14652
|
+
return "unknown";
|
|
14653
|
+
}
|
|
14654
|
+
var init_self_version = () => {};
|
|
14655
|
+
|
|
14401
14656
|
// src/setup/host-generation.ts
|
|
14402
14657
|
import { createHash as createHash4 } from "node:crypto";
|
|
14403
14658
|
import {
|
|
14404
14659
|
closeSync as closeSync7,
|
|
14405
|
-
existsSync as
|
|
14660
|
+
existsSync as existsSync15,
|
|
14406
14661
|
mkdirSync as mkdirSync5,
|
|
14407
14662
|
mkdtempSync,
|
|
14408
14663
|
openSync as openSync7,
|
|
14409
|
-
readdirSync as
|
|
14410
|
-
readFileSync as
|
|
14664
|
+
readdirSync as readdirSync7,
|
|
14665
|
+
readFileSync as readFileSync11,
|
|
14411
14666
|
readSync as readSync5,
|
|
14412
14667
|
realpathSync as realpathSync5,
|
|
14413
14668
|
rmSync as rmSync4,
|
|
14414
14669
|
statSync as statSync10
|
|
14415
14670
|
} from "node:fs";
|
|
14416
14671
|
import { homedir as homedir14, tmpdir as tmpdir3 } from "node:os";
|
|
14417
|
-
import { dirname as
|
|
14672
|
+
import { dirname as dirname9, join as join19, parse as parse3 } from "node:path";
|
|
14418
14673
|
function findExecutableOnPath2(name, pathValue = process.env.PATH ?? "", platform = process.platform) {
|
|
14419
14674
|
return findExecutableOnPath(name, { pathValue, platform });
|
|
14420
14675
|
}
|
|
14421
14676
|
function packageMetadataAt(path, expectedName) {
|
|
14422
14677
|
try {
|
|
14423
|
-
const metadata = JSON.parse(
|
|
14678
|
+
const metadata = JSON.parse(readFileSync11(path, "utf8"));
|
|
14424
14679
|
return metadata.name === expectedName ? metadata : null;
|
|
14425
14680
|
} catch {
|
|
14426
14681
|
return null;
|
|
@@ -14429,16 +14684,16 @@ function packageMetadataAt(path, expectedName) {
|
|
|
14429
14684
|
function packageMetadataNearExecutable(executable, expectedName) {
|
|
14430
14685
|
let current;
|
|
14431
14686
|
try {
|
|
14432
|
-
current =
|
|
14687
|
+
current = dirname9(realpathSync5(executable));
|
|
14433
14688
|
} catch {
|
|
14434
|
-
current =
|
|
14689
|
+
current = dirname9(executable);
|
|
14435
14690
|
}
|
|
14436
14691
|
while (true) {
|
|
14437
|
-
const direct = packageMetadataAt(
|
|
14692
|
+
const direct = packageMetadataAt(join19(current, "package.json"), expectedName);
|
|
14438
14693
|
if (direct)
|
|
14439
14694
|
return direct;
|
|
14440
|
-
const parent =
|
|
14441
|
-
if (parent === current || current ===
|
|
14695
|
+
const parent = dirname9(current);
|
|
14696
|
+
if (parent === current || current === parse3(current).root)
|
|
14442
14697
|
return null;
|
|
14443
14698
|
current = parent;
|
|
14444
14699
|
}
|
|
@@ -14448,7 +14703,7 @@ function npmLauncherTarget(launcher) {
|
|
|
14448
14703
|
try {
|
|
14449
14704
|
if (statSync10(launcher).size > LAUNCHER_MAX_BYTES)
|
|
14450
14705
|
return null;
|
|
14451
|
-
source =
|
|
14706
|
+
source = readFileSync11(launcher, "utf8");
|
|
14452
14707
|
} catch {
|
|
14453
14708
|
return null;
|
|
14454
14709
|
}
|
|
@@ -14458,7 +14713,7 @@ function npmLauncherTarget(launcher) {
|
|
|
14458
14713
|
const relativeTarget = operands.at(-1)?.[1];
|
|
14459
14714
|
if (!relativeTarget)
|
|
14460
14715
|
return null;
|
|
14461
|
-
const target =
|
|
14716
|
+
const target = join19(dirname9(launcher), ...relativeTarget.split(/[\\/]+/).filter(Boolean));
|
|
14462
14717
|
try {
|
|
14463
14718
|
return statSync10(target).isFile() ? target : null;
|
|
14464
14719
|
} catch {
|
|
@@ -14504,7 +14759,7 @@ function hashFileBytes(hash, path, size) {
|
|
|
14504
14759
|
}
|
|
14505
14760
|
}
|
|
14506
14761
|
function snapshotTree(path) {
|
|
14507
|
-
if (!
|
|
14762
|
+
if (!existsSync15(path))
|
|
14508
14763
|
return "missing";
|
|
14509
14764
|
const hash = createHash4("sha256");
|
|
14510
14765
|
const visit = (current, relativePath) => {
|
|
@@ -14517,8 +14772,8 @@ function snapshotTree(path) {
|
|
|
14517
14772
|
}
|
|
14518
14773
|
hash.update(`${relativePath}\x00${info.mode}\x00${info.size}\x00${info.mtimeMs}\x00`);
|
|
14519
14774
|
if (info.isDirectory()) {
|
|
14520
|
-
for (const entry of
|
|
14521
|
-
visit(
|
|
14775
|
+
for (const entry of readdirSync7(current).sort()) {
|
|
14776
|
+
visit(join19(current, entry), join19(relativePath, entry));
|
|
14522
14777
|
}
|
|
14523
14778
|
return;
|
|
14524
14779
|
}
|
|
@@ -14534,19 +14789,19 @@ function snapshotTree(path) {
|
|
|
14534
14789
|
return hash.digest("hex");
|
|
14535
14790
|
}
|
|
14536
14791
|
function snapshotOperatorState(operatorHome) {
|
|
14537
|
-
const database =
|
|
14792
|
+
const database = join19(operatorHome, ".local", "share", "opencode", "opencode.db");
|
|
14538
14793
|
return JSON.stringify({
|
|
14539
14794
|
database: snapshotTree(database),
|
|
14540
14795
|
databaseWal: snapshotTree(`${database}-wal`),
|
|
14541
14796
|
databaseShm: snapshotTree(`${database}-shm`),
|
|
14542
|
-
logs: snapshotTree(
|
|
14797
|
+
logs: snapshotTree(join19(operatorHome, ".local", "share", "opencode", "log"))
|
|
14543
14798
|
});
|
|
14544
14799
|
}
|
|
14545
14800
|
function probeCreatedIsolatedState(dataRoot, stateRoot) {
|
|
14546
14801
|
return [dataRoot, stateRoot].some((root) => {
|
|
14547
|
-
const opencodeRoot =
|
|
14548
|
-
const database =
|
|
14549
|
-
return [database, `${database}-wal`, `${database}-shm`,
|
|
14802
|
+
const opencodeRoot = join19(root, "opencode");
|
|
14803
|
+
const database = join19(opencodeRoot, "opencode.db");
|
|
14804
|
+
return [database, `${database}-wal`, `${database}-shm`, join19(opencodeRoot, "log")].some(existsSync15);
|
|
14550
14805
|
});
|
|
14551
14806
|
}
|
|
14552
14807
|
function probeOpenCodeV1Version(executable, options = {}) {
|
|
@@ -14555,13 +14810,13 @@ function probeOpenCodeV1Version(executable, options = {}) {
|
|
|
14555
14810
|
return null;
|
|
14556
14811
|
const operatorHome = options.operatorHome ?? homedir14();
|
|
14557
14812
|
const before = snapshotOperatorState(operatorHome);
|
|
14558
|
-
const root = mkdtempSync(
|
|
14559
|
-
const home =
|
|
14560
|
-
const config =
|
|
14561
|
-
const data =
|
|
14562
|
-
const state =
|
|
14563
|
-
const cache =
|
|
14564
|
-
const project =
|
|
14813
|
+
const root = mkdtempSync(join19(options.tempParent ?? tmpdir3(), "aft-opencode-probe-"));
|
|
14814
|
+
const home = join19(root, "home");
|
|
14815
|
+
const config = join19(root, "config");
|
|
14816
|
+
const data = join19(root, "data");
|
|
14817
|
+
const state = join19(root, "state");
|
|
14818
|
+
const cache = join19(root, "cache");
|
|
14819
|
+
const project = join19(root, "project");
|
|
14565
14820
|
for (const directory of [home, config, data, state, cache, project]) {
|
|
14566
14821
|
mkdirSync5(directory, { recursive: true });
|
|
14567
14822
|
}
|
|
@@ -14572,7 +14827,7 @@ function probeOpenCodeV1Version(executable, options = {}) {
|
|
|
14572
14827
|
XDG_DATA_HOME: data,
|
|
14573
14828
|
XDG_STATE_HOME: state,
|
|
14574
14829
|
XDG_CACHE_HOME: cache,
|
|
14575
|
-
TMPDIR:
|
|
14830
|
+
TMPDIR: join19(root, "tmp")
|
|
14576
14831
|
};
|
|
14577
14832
|
mkdirSync5(env.TMPDIR, { recursive: true });
|
|
14578
14833
|
delete env.OPENCODE_CONFIG;
|
|
@@ -14713,9 +14968,9 @@ var init_host_generation = __esm(() => {
|
|
|
14713
14968
|
});
|
|
14714
14969
|
|
|
14715
14970
|
// src/adapters/opencode.ts
|
|
14716
|
-
import { existsSync as
|
|
14971
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12, rmSync as rmSync5, statSync as statSync11 } from "node:fs";
|
|
14717
14972
|
import { homedir as homedir15 } from "node:os";
|
|
14718
|
-
import { dirname as
|
|
14973
|
+
import { dirname as dirname10, join as join20, parse as parse4, resolve as resolve12 } from "node:path";
|
|
14719
14974
|
import { fileURLToPath } from "node:url";
|
|
14720
14975
|
function getOpenCodeConfigDir() {
|
|
14721
14976
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
@@ -14726,13 +14981,13 @@ function getOpenCodeConfigDir() {
|
|
|
14726
14981
|
function getLegacyOpenCodePluginCachePath(primaryPath) {
|
|
14727
14982
|
if (process.platform !== "win32")
|
|
14728
14983
|
return null;
|
|
14729
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
14730
|
-
const legacyPath =
|
|
14984
|
+
const localAppData = process.env.LOCALAPPDATA ?? join20(homedir15(), "AppData", "Local");
|
|
14985
|
+
const legacyPath = join20(localAppData, "opencode", "packages", LEGACY_PLUGIN_ENTRY);
|
|
14731
14986
|
return resolve12(legacyPath) === resolve12(primaryPath) ? null : legacyPath;
|
|
14732
14987
|
}
|
|
14733
14988
|
function clearLegacyOpenCodePluginCache(primaryPath) {
|
|
14734
14989
|
const legacyPath = getLegacyOpenCodePluginCachePath(primaryPath);
|
|
14735
|
-
if (!legacyPath || !
|
|
14990
|
+
if (!legacyPath || !existsSync16(legacyPath))
|
|
14736
14991
|
return { clearedPath: null };
|
|
14737
14992
|
try {
|
|
14738
14993
|
rmSync5(legacyPath, { recursive: true, force: true });
|
|
@@ -14750,16 +15005,16 @@ function hasOpenCodeCli() {
|
|
|
14750
15005
|
function openCodeDesktopAppExists() {
|
|
14751
15006
|
const candidates = [];
|
|
14752
15007
|
if (process.platform === "darwin") {
|
|
14753
|
-
candidates.push("/Applications/OpenCode.app", "/Applications/OpenCode Beta.app",
|
|
15008
|
+
candidates.push("/Applications/OpenCode.app", "/Applications/OpenCode Beta.app", join20(homedir15(), "Applications", "OpenCode.app"), join20(homedir15(), "Applications", "OpenCode Beta.app"));
|
|
14754
15009
|
} else if (process.platform === "win32") {
|
|
14755
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
14756
|
-
candidates.push(
|
|
15010
|
+
const localAppData = process.env.LOCALAPPDATA ?? join20(homedir15(), "AppData", "Local");
|
|
15011
|
+
candidates.push(join20(localAppData, "Programs", "opencode"), join20(localAppData, "opencode"));
|
|
14757
15012
|
} else {
|
|
14758
|
-
candidates.push("/opt/OpenCode", "/usr/lib/opencode",
|
|
15013
|
+
candidates.push("/opt/OpenCode", "/usr/lib/opencode", join20(homedir15(), ".local", "share", "applications", "opencode.desktop"));
|
|
14759
15014
|
}
|
|
14760
15015
|
return candidates.some((p) => {
|
|
14761
15016
|
try {
|
|
14762
|
-
return
|
|
15017
|
+
return existsSync16(p);
|
|
14763
15018
|
} catch {
|
|
14764
15019
|
return false;
|
|
14765
15020
|
}
|
|
@@ -14782,24 +15037,24 @@ function pathPointsToOurPlugin(entry) {
|
|
|
14782
15037
|
if (!fsPath)
|
|
14783
15038
|
return false;
|
|
14784
15039
|
try {
|
|
14785
|
-
if (!
|
|
15040
|
+
if (!existsSync16(fsPath))
|
|
14786
15041
|
return false;
|
|
14787
|
-
let searchDir = statSync11(fsPath).isDirectory() ? fsPath :
|
|
15042
|
+
let searchDir = statSync11(fsPath).isDirectory() ? fsPath : dirname10(fsPath);
|
|
14788
15043
|
let pkgJsonPath = null;
|
|
14789
15044
|
while (true) {
|
|
14790
|
-
const candidate =
|
|
14791
|
-
if (
|
|
15045
|
+
const candidate = join20(searchDir, "package.json");
|
|
15046
|
+
if (existsSync16(candidate)) {
|
|
14792
15047
|
pkgJsonPath = candidate;
|
|
14793
15048
|
break;
|
|
14794
15049
|
}
|
|
14795
|
-
const parent =
|
|
14796
|
-
if (parent === searchDir || searchDir ===
|
|
15050
|
+
const parent = dirname10(searchDir);
|
|
15051
|
+
if (parent === searchDir || searchDir === parse4(searchDir).root)
|
|
14797
15052
|
break;
|
|
14798
15053
|
searchDir = parent;
|
|
14799
15054
|
}
|
|
14800
15055
|
if (!pkgJsonPath)
|
|
14801
15056
|
return false;
|
|
14802
|
-
const parsed = JSON.parse(
|
|
15057
|
+
const parsed = JSON.parse(readFileSync12(pkgJsonPath, "utf-8"));
|
|
14803
15058
|
return parsed.name === PLUGIN_NAME;
|
|
14804
15059
|
} catch {
|
|
14805
15060
|
return false;
|
|
@@ -14833,7 +15088,7 @@ class OpenCodeAdapter {
|
|
|
14833
15088
|
pluginEntryWithVersion = PLUGIN_ENTRY;
|
|
14834
15089
|
hostDetection;
|
|
14835
15090
|
isInstalled() {
|
|
14836
|
-
if (
|
|
15091
|
+
if (existsSync16(getOpenCodeConfigDir()))
|
|
14837
15092
|
return true;
|
|
14838
15093
|
if (openCodeDesktopAppExists())
|
|
14839
15094
|
return true;
|
|
@@ -14857,7 +15112,7 @@ class OpenCodeAdapter {
|
|
|
14857
15112
|
const configDir = getOpenCodeConfigDir();
|
|
14858
15113
|
const harness = detectJsoncFile(configDir, "opencode");
|
|
14859
15114
|
const aftConfigPath = resolveCortexKitUserConfigPath();
|
|
14860
|
-
const aftConfigExists =
|
|
15115
|
+
const aftConfigExists = existsSync16(aftConfigPath);
|
|
14861
15116
|
const tui = detectJsoncFile(configDir, "tui");
|
|
14862
15117
|
return {
|
|
14863
15118
|
configDir,
|
|
@@ -14874,13 +15129,32 @@ class OpenCodeAdapter {
|
|
|
14874
15129
|
const { value } = readJsoncFile(paths.harnessConfig);
|
|
14875
15130
|
return configRegistersAft(value, this.configGeneration());
|
|
14876
15131
|
}
|
|
14877
|
-
async ensurePluginEntry() {
|
|
15132
|
+
async ensurePluginEntry(options = {}) {
|
|
14878
15133
|
const paths = this.detectConfigPaths();
|
|
14879
|
-
return this.ensureConfigEntry(paths.harnessConfig, paths.harnessConfigFormat, "server config");
|
|
15134
|
+
return this.ensureConfigEntry(paths.harnessConfig, paths.harnessConfigFormat, "server config", options);
|
|
14880
15135
|
}
|
|
14881
|
-
needsPluginEntryUpdate() {
|
|
15136
|
+
needsPluginEntryUpdate(options = {}) {
|
|
14882
15137
|
const paths = this.detectConfigPaths();
|
|
14883
|
-
return this.configEntryNeedsUpdate(paths.harnessConfig, paths.harnessConfigFormat);
|
|
15138
|
+
return this.configEntryNeedsUpdate(paths.harnessConfig, paths.harnessConfigFormat, options);
|
|
15139
|
+
}
|
|
15140
|
+
doctorPluginEntry(tui = false) {
|
|
15141
|
+
const paths = this.detectConfigPaths();
|
|
15142
|
+
const path = tui ? paths.tuiConfig : paths.harnessConfig;
|
|
15143
|
+
const value = path ? readJsoncFile(path).value : null;
|
|
15144
|
+
const policy = this.doctorVersionPolicy({ doctor: true });
|
|
15145
|
+
if (!value)
|
|
15146
|
+
return policy.fallbackEntry ?? PLUGIN_ENTRY;
|
|
15147
|
+
return ensurePinnedPluginConfig(JSON.parse(JSON.stringify(value)), getSelfVersion(), pathPointsToOurPlugin, this.configGeneration(), policy).entry;
|
|
15148
|
+
}
|
|
15149
|
+
doctorVersionPolicy(policy) {
|
|
15150
|
+
if (!policy.doctor)
|
|
15151
|
+
return policy;
|
|
15152
|
+
const cache = this.getPluginCacheInfo();
|
|
15153
|
+
const installedVersion = doctorInstalledVersion(cache);
|
|
15154
|
+
const configuredVersion = cache.configuredEntry ? exactPinnedVersion(cache.configuredEntry) : null;
|
|
15155
|
+
const newer = configuredVersion && (compareSemver2(configuredVersion, getSelfVersion()) ?? 0) > 0 || cache.cached && (compareSemver2(cache.cached, getSelfVersion()) ?? 0) > 0;
|
|
15156
|
+
const fallbackEntry = newer ? cache.configuredEntry ?? (cache.cached ? pinnedPluginEntry(cache.cached) : undefined) : undefined;
|
|
15157
|
+
return { ...policy, installedVersion, fallbackEntry };
|
|
14884
15158
|
}
|
|
14885
15159
|
hasTuiPluginEntry() {
|
|
14886
15160
|
const paths = this.detectConfigPaths();
|
|
@@ -14889,7 +15163,7 @@ class OpenCodeAdapter {
|
|
|
14889
15163
|
const { value } = readJsoncFile(paths.tuiConfig);
|
|
14890
15164
|
return configRegistersAft(value, this.configGeneration());
|
|
14891
15165
|
}
|
|
14892
|
-
async ensureTuiPluginEntry() {
|
|
15166
|
+
async ensureTuiPluginEntry(options = {}) {
|
|
14893
15167
|
const paths = this.detectConfigPaths();
|
|
14894
15168
|
if (this.configGeneration() === "v2") {
|
|
14895
15169
|
return {
|
|
@@ -14907,28 +15181,30 @@ class OpenCodeAdapter {
|
|
|
14907
15181
|
configPath: paths.configDir
|
|
14908
15182
|
};
|
|
14909
15183
|
}
|
|
14910
|
-
return this.ensureConfigEntry(paths.tuiConfig, paths.tuiConfigFormat ?? "none", "TUI config");
|
|
15184
|
+
return this.ensureConfigEntry(paths.tuiConfig, paths.tuiConfigFormat ?? "none", "TUI config", options);
|
|
14911
15185
|
}
|
|
14912
15186
|
tuiPluginEntryApplies() {
|
|
14913
15187
|
return this.configGeneration() !== "v2";
|
|
14914
15188
|
}
|
|
14915
|
-
needsTuiPluginEntryUpdate() {
|
|
15189
|
+
needsTuiPluginEntryUpdate(options = {}) {
|
|
14916
15190
|
if (this.configGeneration() === "v2")
|
|
14917
15191
|
return false;
|
|
14918
15192
|
const paths = this.detectConfigPaths();
|
|
14919
|
-
return paths.tuiConfig ? this.configEntryNeedsUpdate(paths.tuiConfig, paths.tuiConfigFormat ?? "none") : true;
|
|
15193
|
+
return paths.tuiConfig ? this.configEntryNeedsUpdate(paths.tuiConfig, paths.tuiConfigFormat ?? "none", options) : true;
|
|
14920
15194
|
}
|
|
14921
|
-
ensureConfigEntry(configPath, format, label) {
|
|
15195
|
+
ensureConfigEntry(configPath, format, label, policy = {}) {
|
|
14922
15196
|
const generation = this.configGeneration();
|
|
14923
15197
|
const key = openCodePluginKey(generation);
|
|
15198
|
+
policy = this.doctorVersionPolicy(policy);
|
|
15199
|
+
const initialEntry = policy.fallbackEntry ?? PLUGIN_ENTRY;
|
|
14924
15200
|
if (format === "none") {
|
|
14925
|
-
const failed = this.tryWrite(configPath, () => writeJsoncFile(configPath, { [key]: [
|
|
15201
|
+
const failed = this.tryWrite(configPath, () => writeJsoncFile(configPath, { [key]: [initialEntry] }, "json"));
|
|
14926
15202
|
if (failed)
|
|
14927
15203
|
return failed;
|
|
14928
15204
|
return {
|
|
14929
15205
|
ok: true,
|
|
14930
15206
|
action: "added",
|
|
14931
|
-
message: `Created ${configPath} and added ${
|
|
15207
|
+
message: `Created ${configPath} and added ${initialEntry} under \`${key}\` (${label})`,
|
|
14932
15208
|
configPath
|
|
14933
15209
|
};
|
|
14934
15210
|
}
|
|
@@ -14941,12 +15217,14 @@ class OpenCodeAdapter {
|
|
|
14941
15217
|
configPath
|
|
14942
15218
|
};
|
|
14943
15219
|
}
|
|
14944
|
-
const update = ensurePinnedPluginConfig(value, getSelfVersion(), pathPointsToOurPlugin, generation);
|
|
15220
|
+
const update = ensurePinnedPluginConfig(value, getSelfVersion(), pathPointsToOurPlugin, generation, policy);
|
|
15221
|
+
const preserved = policy.doctor && preserveDoctorPluginEntry(getSelfVersion(), update.entry, doctorInstalledVersion(this.getPluginCacheInfo()));
|
|
15222
|
+
const notice = preserved ? doctorNoDowngradeMessage(getSelfVersion(), update.entry, doctorInstalledVersion(this.getPluginCacheInfo())) : "";
|
|
14945
15223
|
if (!update.changed) {
|
|
14946
15224
|
return {
|
|
14947
15225
|
ok: true,
|
|
14948
15226
|
action: "already_present",
|
|
14949
|
-
message: `${
|
|
15227
|
+
message: notice || `${update.entry} is already registered under \`${update.key}\` in ${configPath}`,
|
|
14950
15228
|
configPath
|
|
14951
15229
|
};
|
|
14952
15230
|
}
|
|
@@ -14956,7 +15234,7 @@ class OpenCodeAdapter {
|
|
|
14956
15234
|
return {
|
|
14957
15235
|
ok: true,
|
|
14958
15236
|
action: update.action,
|
|
14959
|
-
message: `${update.action === "added" ? "Added" : "Updated"} ${
|
|
15237
|
+
message: `${update.action === "added" ? "Added" : "Updated"} ${update.entry} under \`${update.key}\` in ${configPath} (${label})${notice ? `. ${notice}` : ""}`,
|
|
14960
15238
|
configPath
|
|
14961
15239
|
};
|
|
14962
15240
|
}
|
|
@@ -15041,38 +15319,27 @@ class OpenCodeAdapter {
|
|
|
15041
15319
|
return { ok: false, action: "error", message: formatFsError(error, configPath), configPath };
|
|
15042
15320
|
}
|
|
15043
15321
|
}
|
|
15044
|
-
configEntryNeedsUpdate(configPath, format) {
|
|
15322
|
+
configEntryNeedsUpdate(configPath, format, policy = {}) {
|
|
15045
15323
|
if (format === "none")
|
|
15046
15324
|
return true;
|
|
15047
15325
|
const { value, error } = readJsoncFile(configPath);
|
|
15048
15326
|
if (error || !value)
|
|
15049
15327
|
return false;
|
|
15050
|
-
return pluginConfigNeedsUpdate(value, getSelfVersion(), pathPointsToOurPlugin, this.configGeneration());
|
|
15328
|
+
return pluginConfigNeedsUpdate(value, getSelfVersion(), pathPointsToOurPlugin, this.configGeneration(), this.doctorVersionPolicy(policy));
|
|
15051
15329
|
}
|
|
15052
15330
|
getPluginCacheInfo() {
|
|
15053
15331
|
const configPath = this.detectConfigPaths().harnessConfig;
|
|
15054
15332
|
const { value } = readJsoncFile(configPath);
|
|
15055
|
-
const
|
|
15056
|
-
const
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
const
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
} catch (error) {
|
|
15064
|
-
if (error.code !== "ENOENT") {
|
|
15065
|
-
readError = error instanceof Error ? error.message : String(error);
|
|
15066
|
-
}
|
|
15333
|
+
const entries = openCodePluginReadKeys(this.configGeneration()).flatMap((key) => Array.isArray(value?.[key]) ? value[key] : []).map(pluginEntryPackage);
|
|
15334
|
+
const configuredEntry = entries.find(isAftNpmEntry);
|
|
15335
|
+
if (!configuredEntry) {
|
|
15336
|
+
const localEntry = entries.find((entry) => entry !== null && pathPointsToOurPlugin(entry));
|
|
15337
|
+
const localPath = localEntry ? pathFromEntry(localEntry) : null;
|
|
15338
|
+
const local = localPath ? discoverLocalOpenCodePlugin(localPath, getSelfVersion()) : undefined;
|
|
15339
|
+
if (local)
|
|
15340
|
+
return local;
|
|
15067
15341
|
}
|
|
15068
|
-
return
|
|
15069
|
-
path,
|
|
15070
|
-
cached,
|
|
15071
|
-
readError,
|
|
15072
|
-
latest: getSelfVersion(),
|
|
15073
|
-
exists: existsSync15(path),
|
|
15074
|
-
configuredEntry
|
|
15075
|
-
};
|
|
15342
|
+
return discoverOpenCodePluginCache(getOpenCodeCacheDir(), configuredEntry ?? PLUGIN_ENTRY, this.configGeneration(), getSelfVersion(), configuredEntry);
|
|
15076
15343
|
}
|
|
15077
15344
|
getStorageDir() {
|
|
15078
15345
|
return getCortexKitStorageRoot();
|
|
@@ -15085,6 +15352,8 @@ class OpenCodeAdapter {
|
|
|
15085
15352
|
}
|
|
15086
15353
|
async clearPluginCache(force) {
|
|
15087
15354
|
const info = this.getPluginCacheInfo();
|
|
15355
|
+
if (info.local)
|
|
15356
|
+
return { action: "not_applicable", path: info.path };
|
|
15088
15357
|
const clearLegacy = force ? clearLegacyOpenCodePluginCache(info.path) : { clearedPath: null };
|
|
15089
15358
|
if (clearLegacy.error) {
|
|
15090
15359
|
return {
|
|
@@ -15101,12 +15370,12 @@ class OpenCodeAdapter {
|
|
|
15101
15370
|
legacy_path_cleared: clearLegacy.clearedPath
|
|
15102
15371
|
} : { action: "not_found", path: info.path };
|
|
15103
15372
|
}
|
|
15104
|
-
if (!force && info.cached && info.cached === info.
|
|
15373
|
+
if (!force && info.cached && info.cached === info.cliVersion) {
|
|
15105
15374
|
return {
|
|
15106
15375
|
action: "up_to_date",
|
|
15107
15376
|
path: info.path,
|
|
15108
15377
|
cached: info.cached,
|
|
15109
|
-
latest: info.
|
|
15378
|
+
latest: info.cliVersion
|
|
15110
15379
|
};
|
|
15111
15380
|
}
|
|
15112
15381
|
try {
|
|
@@ -15115,7 +15384,7 @@ class OpenCodeAdapter {
|
|
|
15115
15384
|
action: "cleared",
|
|
15116
15385
|
path: info.path,
|
|
15117
15386
|
cached: info.cached,
|
|
15118
|
-
latest: info.
|
|
15387
|
+
latest: info.cliVersion,
|
|
15119
15388
|
...clearLegacy.clearedPath ? { legacy_path_cleared: clearLegacy.clearedPath } : {}
|
|
15120
15389
|
};
|
|
15121
15390
|
} catch (error) {
|
|
@@ -15123,7 +15392,7 @@ class OpenCodeAdapter {
|
|
|
15123
15392
|
action: "error",
|
|
15124
15393
|
path: info.path,
|
|
15125
15394
|
cached: info.cached,
|
|
15126
|
-
latest: info.
|
|
15395
|
+
latest: info.cliVersion,
|
|
15127
15396
|
error: error instanceof Error ? error.message : String(error)
|
|
15128
15397
|
};
|
|
15129
15398
|
}
|
|
@@ -15134,12 +15403,12 @@ class OpenCodeAdapter {
|
|
|
15134
15403
|
describeStorageSubtrees() {
|
|
15135
15404
|
const storage = this.getStorageDir();
|
|
15136
15405
|
return {
|
|
15137
|
-
index: dirSize(
|
|
15138
|
-
semantic: dirSize(
|
|
15139
|
-
backups: dirSize(
|
|
15140
|
-
url_cache: dirSize(
|
|
15141
|
-
onnxruntime: dirSize(
|
|
15142
|
-
logs: dirSize(
|
|
15406
|
+
index: dirSize(join20(storage, "index")),
|
|
15407
|
+
semantic: dirSize(join20(storage, "semantic")),
|
|
15408
|
+
backups: dirSize(join20(storage, "backups")),
|
|
15409
|
+
url_cache: dirSize(join20(storage, "url_cache")),
|
|
15410
|
+
onnxruntime: dirSize(join20(storage, "onnxruntime")),
|
|
15411
|
+
logs: dirSize(join20(storage, "logs"))
|
|
15143
15412
|
};
|
|
15144
15413
|
}
|
|
15145
15414
|
}
|
|
@@ -15149,6 +15418,7 @@ var init_opencode = __esm(() => {
|
|
|
15149
15418
|
init_fs_errors();
|
|
15150
15419
|
init_fs_util();
|
|
15151
15420
|
init_jsonc();
|
|
15421
|
+
init_opencode_plugin_cache();
|
|
15152
15422
|
init_paths2();
|
|
15153
15423
|
init_self_version();
|
|
15154
15424
|
init_host_generation();
|
|
@@ -15159,9 +15429,9 @@ var init_opencode = __esm(() => {
|
|
|
15159
15429
|
});
|
|
15160
15430
|
|
|
15161
15431
|
// src/adapters/pi.ts
|
|
15162
|
-
import { existsSync as
|
|
15432
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13 } from "node:fs";
|
|
15163
15433
|
import { homedir as homedir16 } from "node:os";
|
|
15164
|
-
import { isAbsolute as isAbsolute7, join as
|
|
15434
|
+
import { isAbsolute as isAbsolute7, join as join21, resolve as resolve13 } from "node:path";
|
|
15165
15435
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
15166
15436
|
function getPiAgentDir() {
|
|
15167
15437
|
const configuredDir = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
@@ -15169,13 +15439,13 @@ function getPiAgentDir() {
|
|
|
15169
15439
|
return resolve13(configuredDir);
|
|
15170
15440
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
15171
15441
|
const home = envHome && envHome.length > 0 ? envHome : homedir16();
|
|
15172
|
-
return
|
|
15442
|
+
return join21(home, ".pi", "agent");
|
|
15173
15443
|
}
|
|
15174
15444
|
function readPiExtensionIndex() {
|
|
15175
|
-
const settingsPath =
|
|
15176
|
-
if (
|
|
15445
|
+
const settingsPath = join21(getPiAgentDir(), "settings.json");
|
|
15446
|
+
if (existsSync17(settingsPath)) {
|
|
15177
15447
|
try {
|
|
15178
|
-
const raw =
|
|
15448
|
+
const raw = readFileSync13(settingsPath, "utf-8");
|
|
15179
15449
|
const trimmed = raw.replace(/^\uFEFF/, "");
|
|
15180
15450
|
const value = JSON.parse(trimmed);
|
|
15181
15451
|
const packages = value.packages;
|
|
@@ -15193,13 +15463,13 @@ function readPiExtensionIndex() {
|
|
|
15193
15463
|
} catch {}
|
|
15194
15464
|
}
|
|
15195
15465
|
const candidates = [
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15466
|
+
join21(getPiAgentDir(), "extensions.json"),
|
|
15467
|
+
join21(getPiAgentDir(), "extensions.jsonc"),
|
|
15468
|
+
join21(getPiAgentDir(), "config.json"),
|
|
15469
|
+
join21(getPiAgentDir(), "config.jsonc")
|
|
15200
15470
|
];
|
|
15201
15471
|
for (const path of candidates) {
|
|
15202
|
-
if (!
|
|
15472
|
+
if (!existsSync17(path))
|
|
15203
15473
|
continue;
|
|
15204
15474
|
try {
|
|
15205
15475
|
const { value } = readJsoncFile(path);
|
|
@@ -15231,17 +15501,17 @@ function piEntryMatchesAft(entry) {
|
|
|
15231
15501
|
} else if (isAbsolute7(entry)) {
|
|
15232
15502
|
resolved = entry;
|
|
15233
15503
|
} else if (entry.length > 0) {
|
|
15234
|
-
resolved =
|
|
15504
|
+
resolved = join21(getPiAgentDir(), entry);
|
|
15235
15505
|
}
|
|
15236
15506
|
if (!resolved)
|
|
15237
15507
|
return false;
|
|
15238
15508
|
try {
|
|
15239
|
-
if (!
|
|
15509
|
+
if (!existsSync17(resolved))
|
|
15240
15510
|
return false;
|
|
15241
|
-
const pkgPath =
|
|
15242
|
-
if (!
|
|
15511
|
+
const pkgPath = join21(resolved, "package.json");
|
|
15512
|
+
if (!existsSync17(pkgPath))
|
|
15243
15513
|
return false;
|
|
15244
|
-
const pkg = JSON.parse(
|
|
15514
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
15245
15515
|
return pkg.name === PLUGIN_NAME2;
|
|
15246
15516
|
} catch {
|
|
15247
15517
|
return false;
|
|
@@ -15287,10 +15557,10 @@ class PiAdapter {
|
|
|
15287
15557
|
const configDir = getPiAgentDir();
|
|
15288
15558
|
const index = readPiExtensionIndex();
|
|
15289
15559
|
const aftConfigPath = resolveCortexKitUserConfigPath();
|
|
15290
|
-
const aftConfigExists =
|
|
15560
|
+
const aftConfigExists = existsSync17(aftConfigPath);
|
|
15291
15561
|
return {
|
|
15292
15562
|
configDir,
|
|
15293
|
-
harnessConfig: index.path ??
|
|
15563
|
+
harnessConfig: index.path ?? join21(configDir, "extensions.json"),
|
|
15294
15564
|
harnessConfigFormat: index.path ? "json" : "none",
|
|
15295
15565
|
aftConfig: aftConfigPath,
|
|
15296
15566
|
aftConfigFormat: aftConfigExists ? "jsonc" : "none"
|
|
@@ -15338,14 +15608,14 @@ class PiAdapter {
|
|
|
15338
15608
|
}
|
|
15339
15609
|
getPluginCacheInfo() {
|
|
15340
15610
|
const candidates = [
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15611
|
+
join21(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
|
|
15612
|
+
join21(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
|
|
15613
|
+
join21(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
|
|
15344
15614
|
];
|
|
15345
15615
|
let readError;
|
|
15346
15616
|
for (const candidate of candidates) {
|
|
15347
15617
|
try {
|
|
15348
|
-
const pkg = JSON.parse(
|
|
15618
|
+
const pkg = JSON.parse(readFileSync13(candidate, "utf-8"));
|
|
15349
15619
|
const cached = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
15350
15620
|
return {
|
|
15351
15621
|
path: candidate,
|
|
@@ -15361,7 +15631,7 @@ class PiAdapter {
|
|
|
15361
15631
|
}
|
|
15362
15632
|
}
|
|
15363
15633
|
return {
|
|
15364
|
-
path:
|
|
15634
|
+
path: join21(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
|
|
15365
15635
|
exists: readError !== undefined,
|
|
15366
15636
|
readError
|
|
15367
15637
|
};
|
|
@@ -15384,12 +15654,12 @@ class PiAdapter {
|
|
|
15384
15654
|
describeStorageSubtrees() {
|
|
15385
15655
|
const storage = this.getStorageDir();
|
|
15386
15656
|
return {
|
|
15387
|
-
index: dirSize(
|
|
15388
|
-
semantic: dirSize(
|
|
15389
|
-
backups: dirSize(
|
|
15390
|
-
url_cache: dirSize(
|
|
15391
|
-
onnxruntime: dirSize(
|
|
15392
|
-
logs: dirSize(
|
|
15657
|
+
index: dirSize(join21(storage, "index")),
|
|
15658
|
+
semantic: dirSize(join21(storage, "semantic")),
|
|
15659
|
+
backups: dirSize(join21(storage, "backups")),
|
|
15660
|
+
url_cache: dirSize(join21(storage, "url_cache")),
|
|
15661
|
+
onnxruntime: dirSize(join21(storage, "onnxruntime")),
|
|
15662
|
+
logs: dirSize(join21(storage, "logs"))
|
|
15393
15663
|
};
|
|
15394
15664
|
}
|
|
15395
15665
|
}
|
|
@@ -16811,10 +17081,10 @@ var init_version = __esm(async () => {
|
|
|
16811
17081
|
// src/lib/cli-logger.ts
|
|
16812
17082
|
import { appendFileSync, mkdirSync as mkdirSync6 } from "node:fs";
|
|
16813
17083
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
16814
|
-
import { dirname as
|
|
17084
|
+
import { dirname as dirname11, join as join22 } from "node:path";
|
|
16815
17085
|
function cliLogPath() {
|
|
16816
17086
|
if (isTestEnvironment())
|
|
16817
|
-
return
|
|
17087
|
+
return join22(tmpdir4(), "aft-cli-test.log");
|
|
16818
17088
|
return resolveAftLogPath("aft-cli.log");
|
|
16819
17089
|
}
|
|
16820
17090
|
function write(level, message) {
|
|
@@ -16829,7 +17099,7 @@ function write(level, message) {
|
|
|
16829
17099
|
}
|
|
16830
17100
|
try {
|
|
16831
17101
|
const path = cliLogPath();
|
|
16832
|
-
mkdirSync6(
|
|
17102
|
+
mkdirSync6(dirname11(path), { recursive: true });
|
|
16833
17103
|
appendFileSync(path, `${new Date().toISOString()} ${level.toUpperCase()} ${message}
|
|
16834
17104
|
`);
|
|
16835
17105
|
} catch {}
|
|
@@ -16866,13 +17136,13 @@ var init_cli_logger = __esm(() => {
|
|
|
16866
17136
|
});
|
|
16867
17137
|
|
|
16868
17138
|
// src/lib/binary-install.ts
|
|
16869
|
-
import { existsSync as
|
|
16870
|
-
import { join as
|
|
17139
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
17140
|
+
import { join as join23 } from "node:path";
|
|
16871
17141
|
function cachedBinaryFor(version) {
|
|
16872
17142
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
16873
|
-
const path =
|
|
17143
|
+
const path = join23(getAftBinaryCacheDir(), tag, getAftBinaryName());
|
|
16874
17144
|
try {
|
|
16875
|
-
return
|
|
17145
|
+
return existsSync18(path) ? path : null;
|
|
16876
17146
|
} catch {
|
|
16877
17147
|
return null;
|
|
16878
17148
|
}
|
|
@@ -17818,8 +18088,8 @@ var init_features = __esm(() => {
|
|
|
17818
18088
|
});
|
|
17819
18089
|
|
|
17820
18090
|
// src/doctor/opencode.ts
|
|
17821
|
-
import { existsSync as
|
|
17822
|
-
import { dirname as
|
|
18091
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "node:fs";
|
|
18092
|
+
import { dirname as dirname12, join as join24 } from "node:path";
|
|
17823
18093
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17824
18094
|
function isLoadPath(value) {
|
|
17825
18095
|
return OPENCODE_LOAD_PATHS.includes(value);
|
|
@@ -17882,7 +18152,7 @@ function configuredVersion(entry) {
|
|
|
17882
18152
|
}
|
|
17883
18153
|
function readManifest(path) {
|
|
17884
18154
|
try {
|
|
17885
|
-
const parsed = JSON.parse(
|
|
18155
|
+
const parsed = JSON.parse(readFileSync14(path, "utf8"));
|
|
17886
18156
|
return parsed.name === AFT_OPENCODE_PACKAGE ? parsed : null;
|
|
17887
18157
|
} catch {
|
|
17888
18158
|
return null;
|
|
@@ -17890,13 +18160,13 @@ function readManifest(path) {
|
|
|
17890
18160
|
}
|
|
17891
18161
|
function manifestFromLocalPath(path) {
|
|
17892
18162
|
let current = path;
|
|
17893
|
-
if (!
|
|
17894
|
-
current =
|
|
18163
|
+
if (!existsSync19(join24(current, "package.json")))
|
|
18164
|
+
current = dirname12(current);
|
|
17895
18165
|
while (true) {
|
|
17896
|
-
const manifest = readManifest(
|
|
18166
|
+
const manifest = readManifest(join24(current, "package.json"));
|
|
17897
18167
|
if (manifest)
|
|
17898
18168
|
return manifest;
|
|
17899
|
-
const parent =
|
|
18169
|
+
const parent = dirname12(current);
|
|
17900
18170
|
if (parent === current)
|
|
17901
18171
|
return null;
|
|
17902
18172
|
current = parent;
|
|
@@ -17906,16 +18176,16 @@ function pluginManifest(entry, cachePath) {
|
|
|
17906
18176
|
const localRoot = localPluginRoot(entry);
|
|
17907
18177
|
if (localRoot)
|
|
17908
18178
|
return manifestFromLocalPath(localRoot);
|
|
17909
|
-
return readManifest(
|
|
18179
|
+
return readManifest(join24(cachePath, "node_modules", "@cortexkit", "aft-opencode", "package.json"));
|
|
17910
18180
|
}
|
|
17911
18181
|
function pinProblem(entry, pinned) {
|
|
17912
18182
|
return `the plugin entry ${entry} ${describePluginEntry(entry)}; run \`${CLI} doctor --fix\` to pin it to ${pinned}`;
|
|
17913
18183
|
}
|
|
17914
18184
|
function latestLoggedLoadPath(logPath) {
|
|
17915
|
-
if (!
|
|
18185
|
+
if (!existsSync19(logPath))
|
|
17916
18186
|
return null;
|
|
17917
18187
|
try {
|
|
17918
|
-
const text =
|
|
18188
|
+
const text = readFileSync14(logPath, "utf8");
|
|
17919
18189
|
const pattern = /(?:load path|load_path)\s*[:=]\s*(root-default|export-server-effect-bun|export-server-effect-node)/gi;
|
|
17920
18190
|
let latest = null;
|
|
17921
18191
|
for (const match of text.matchAll(pattern)) {
|
|
@@ -17955,7 +18225,12 @@ function diagnoseOpenCodeLoad(input) {
|
|
|
17955
18225
|
const pluginVersion = (typeof manifest?.version === "string" ? manifest.version : null) ?? input.cachedPluginVersion ?? configuredVersion(entry) ?? null;
|
|
17956
18226
|
const problems = [...describePluginKeyProblems(config, generation)];
|
|
17957
18227
|
let entryPinProblem = null;
|
|
17958
|
-
|
|
18228
|
+
let versionNotice;
|
|
18229
|
+
const cli = input.expectedPluginEntry ? exactPinnedVersion(input.expectedPluginEntry) : null;
|
|
18230
|
+
const installed = input.cachedPluginVersion ?? (typeof manifest?.version === "string" ? manifest.version : undefined);
|
|
18231
|
+
if (cli && entry && isAftNpmEntry(entry) && preserveDoctorPluginEntry(cli, entry, installed)) {
|
|
18232
|
+
versionNotice = doctorNoDowngradeMessage(cli, entry, installed);
|
|
18233
|
+
} else if (entry && isAftNpmEntry(entry) && input.expectedPluginEntry && entry !== input.expectedPluginEntry && !(input.acceptExplicitPluginVersion && acceptV1Entry(entry))) {
|
|
17959
18234
|
entryPinProblem = pinProblem(entry, input.expectedPluginEntry);
|
|
17960
18235
|
problems.push(entryPinProblem);
|
|
17961
18236
|
}
|
|
@@ -17967,7 +18242,14 @@ function diagnoseOpenCodeLoad(input) {
|
|
|
17967
18242
|
if (expectedLoadPath && takenLoadPath && expectedLoadPath !== takenLoadPath) {
|
|
17968
18243
|
problems.push(`load path ${takenLoadPath} does not match ${expectedLoadPath} expected for the detected host`);
|
|
17969
18244
|
}
|
|
17970
|
-
return {
|
|
18245
|
+
return {
|
|
18246
|
+
expectedLoadPath,
|
|
18247
|
+
takenLoadPath,
|
|
18248
|
+
pluginVersion,
|
|
18249
|
+
problems,
|
|
18250
|
+
pinProblem: entryPinProblem,
|
|
18251
|
+
versionNotice
|
|
18252
|
+
};
|
|
17971
18253
|
}
|
|
17972
18254
|
function describePluginKeyProblems(config, generation) {
|
|
17973
18255
|
if (!config || generation === "ambiguous" || generation === "unknown")
|
|
@@ -18167,11 +18449,11 @@ var init_aft_bridge = __esm(() => {
|
|
|
18167
18449
|
});
|
|
18168
18450
|
|
|
18169
18451
|
// src/lib/binary-cache.ts
|
|
18170
|
-
import { existsSync as
|
|
18171
|
-
import { join as
|
|
18452
|
+
import { existsSync as existsSync20, readdirSync as readdirSync8, statSync as statSync12 } from "node:fs";
|
|
18453
|
+
import { join as join25 } from "node:path";
|
|
18172
18454
|
function getBinaryCacheInfo(activeVersion) {
|
|
18173
18455
|
const path = getAftBinaryCacheDir();
|
|
18174
|
-
if (!
|
|
18456
|
+
if (!existsSync20(path)) {
|
|
18175
18457
|
return {
|
|
18176
18458
|
versions: [],
|
|
18177
18459
|
activeVersion: null,
|
|
@@ -18179,9 +18461,9 @@ function getBinaryCacheInfo(activeVersion) {
|
|
|
18179
18461
|
path
|
|
18180
18462
|
};
|
|
18181
18463
|
}
|
|
18182
|
-
const versions =
|
|
18464
|
+
const versions = readdirSync8(path).filter((entry) => {
|
|
18183
18465
|
try {
|
|
18184
|
-
return statSync12(
|
|
18466
|
+
return statSync12(join25(path, entry)).isDirectory();
|
|
18185
18467
|
} catch {
|
|
18186
18468
|
return false;
|
|
18187
18469
|
}
|
|
@@ -18291,12 +18573,12 @@ var init_sanitize = __esm(() => {
|
|
|
18291
18573
|
});
|
|
18292
18574
|
|
|
18293
18575
|
// src/lib/bridge-tool-failures.ts
|
|
18294
|
-
import { closeSync as closeSync8, existsSync as
|
|
18576
|
+
import { closeSync as closeSync8, existsSync as existsSync21, openSync as openSync8, readSync as readSync6, statSync as statSync13 } from "node:fs";
|
|
18295
18577
|
function resolveBridgePluginLogPath() {
|
|
18296
18578
|
return resolvePluginLogPath();
|
|
18297
18579
|
}
|
|
18298
18580
|
function tailLogFileBytes(path, maxBytes) {
|
|
18299
|
-
if (!
|
|
18581
|
+
if (!existsSync21(path) || maxBytes <= 0)
|
|
18300
18582
|
return "";
|
|
18301
18583
|
let fd = null;
|
|
18302
18584
|
try {
|
|
@@ -18432,9 +18714,9 @@ var init_bridge_tool_failures = __esm(() => {
|
|
|
18432
18714
|
});
|
|
18433
18715
|
|
|
18434
18716
|
// src/lib/build-breaker.ts
|
|
18435
|
-
import { existsSync as
|
|
18717
|
+
import { existsSync as existsSync22, readdirSync as readdirSync9 } from "node:fs";
|
|
18436
18718
|
import { createRequire as createRequire3 } from "node:module";
|
|
18437
|
-
import { join as
|
|
18719
|
+
import { join as join26 } from "node:path";
|
|
18438
18720
|
function loadDatabaseSync() {
|
|
18439
18721
|
const require2 = createRequire3(import.meta.url);
|
|
18440
18722
|
try {
|
|
@@ -18448,11 +18730,11 @@ function loadDatabaseSync() {
|
|
|
18448
18730
|
}
|
|
18449
18731
|
}
|
|
18450
18732
|
function buildBreakerDatabases(storageRoot) {
|
|
18451
|
-
const callgraphRoot =
|
|
18452
|
-
if (!
|
|
18733
|
+
const callgraphRoot = join26(storageRoot, "callgraph");
|
|
18734
|
+
if (!existsSync22(callgraphRoot))
|
|
18453
18735
|
return [];
|
|
18454
18736
|
try {
|
|
18455
|
-
return
|
|
18737
|
+
return readdirSync9(callgraphRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join26(callgraphRoot, entry.name, "build-breaker.sqlite")).filter((path) => existsSync22(path));
|
|
18456
18738
|
} catch {
|
|
18457
18739
|
return [];
|
|
18458
18740
|
}
|
|
@@ -18528,15 +18810,15 @@ var init_build_breaker = __esm(() => {
|
|
|
18528
18810
|
});
|
|
18529
18811
|
|
|
18530
18812
|
// src/lib/config-migration.ts
|
|
18531
|
-
import { existsSync as
|
|
18813
|
+
import { existsSync as existsSync23, readFileSync as readFileSync15 } from "node:fs";
|
|
18532
18814
|
function isRecord2(value) {
|
|
18533
18815
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18534
18816
|
}
|
|
18535
18817
|
function readPlainConfig(path) {
|
|
18536
|
-
if (!
|
|
18818
|
+
if (!existsSync23(path))
|
|
18537
18819
|
return null;
|
|
18538
18820
|
try {
|
|
18539
|
-
const plain = JSON.parse(JSON.stringify(import_comment_json2.parse(
|
|
18821
|
+
const plain = JSON.parse(JSON.stringify(import_comment_json2.parse(readFileSync15(path, "utf8"))));
|
|
18540
18822
|
return isRecord2(plain) ? plain : null;
|
|
18541
18823
|
} catch {
|
|
18542
18824
|
return null;
|
|
@@ -18544,10 +18826,10 @@ function readPlainConfig(path) {
|
|
|
18544
18826
|
}
|
|
18545
18827
|
function configMigrationTargets(userConfigPath, cwd = process.cwd()) {
|
|
18546
18828
|
const targets = [];
|
|
18547
|
-
if (
|
|
18829
|
+
if (existsSync23(userConfigPath))
|
|
18548
18830
|
targets.push({ path: userConfigPath, tier: "user" });
|
|
18549
18831
|
const project = resolveCortexKitProjectConfigPath(cwd);
|
|
18550
|
-
if (project !== userConfigPath &&
|
|
18832
|
+
if (project !== userConfigPath && existsSync23(project)) {
|
|
18551
18833
|
targets.push({ path: project, tier: "project" });
|
|
18552
18834
|
}
|
|
18553
18835
|
return targets;
|
|
@@ -18589,8 +18871,9 @@ function previewConfigMigration(targets) {
|
|
|
18589
18871
|
continue;
|
|
18590
18872
|
const translated = structuredClone(raw);
|
|
18591
18873
|
const translation = translateConfigDocument(translated, target.tier);
|
|
18592
|
-
if (!translation.legacyInput)
|
|
18874
|
+
if (!translation.legacyInput && translation.removedKeys.length === 0)
|
|
18593
18875
|
continue;
|
|
18876
|
+
dropRemovedDataLayerKeys(translated);
|
|
18594
18877
|
const changes = diffConfig(raw, translated);
|
|
18595
18878
|
previews.push({ ...target, changes });
|
|
18596
18879
|
}
|
|
@@ -18612,21 +18895,27 @@ var init_config_migration = __esm(() => {
|
|
|
18612
18895
|
import_comment_json2 = __toESM(require_src2(), 1);
|
|
18613
18896
|
});
|
|
18614
18897
|
|
|
18898
|
+
// src/lib/doctor-labels.ts
|
|
18899
|
+
function describeCliBinary(version, path) {
|
|
18900
|
+
return CLI_BINARY_LABEL.replace("<version>", version ?? "unknown").replace("<path>", path ?? "unknown");
|
|
18901
|
+
}
|
|
18902
|
+
var CLI_BINARY_LABEL = "AFT binary this CLI found: <version> at <path> (the plugin may run a different one)", CLI_VERSION_CACHED_LABEL = "Cached binary for this CLI";
|
|
18903
|
+
|
|
18615
18904
|
// src/lib/legacy-storage.ts
|
|
18616
|
-
import { existsSync as
|
|
18617
|
-
import { join as
|
|
18905
|
+
import { existsSync as existsSync24, readdirSync as readdirSync10, statSync as statSync14 } from "node:fs";
|
|
18906
|
+
import { join as join27 } from "node:path";
|
|
18618
18907
|
function summarizeLegacyPartitionDuplication(storageRoot) {
|
|
18619
|
-
if (!
|
|
18908
|
+
if (!existsSync24(storageRoot)) {
|
|
18620
18909
|
return { totalPartitions: 0, totalBytes: 0, byHarness: [] };
|
|
18621
18910
|
}
|
|
18622
18911
|
const byHarness = [];
|
|
18623
18912
|
for (const harness of safeReadDir(storageRoot)) {
|
|
18624
|
-
const harnessPath =
|
|
18913
|
+
const harnessPath = join27(storageRoot, harness);
|
|
18625
18914
|
if (!isDirectory(harnessPath))
|
|
18626
18915
|
continue;
|
|
18627
18916
|
const partitions = new Map;
|
|
18628
|
-
collectCallgraphPartitions(
|
|
18629
|
-
collectInspectPartitions(
|
|
18917
|
+
collectCallgraphPartitions(join27(harnessPath, "callgraph"), partitions);
|
|
18918
|
+
collectInspectPartitions(join27(harnessPath, "inspect"), partitions);
|
|
18630
18919
|
if (partitions.size === 0)
|
|
18631
18920
|
continue;
|
|
18632
18921
|
let bytes = 0;
|
|
@@ -18645,7 +18934,7 @@ function collectCallgraphPartitions(domainPath, partitions) {
|
|
|
18645
18934
|
if (!isDirectory(domainPath))
|
|
18646
18935
|
return;
|
|
18647
18936
|
for (const name of safeReadDir(domainPath)) {
|
|
18648
|
-
const path =
|
|
18937
|
+
const path = join27(domainPath, name);
|
|
18649
18938
|
if (isDirectory(path)) {
|
|
18650
18939
|
if (!looksLikePartitionKey(name))
|
|
18651
18940
|
continue;
|
|
@@ -18662,7 +18951,7 @@ function collectInspectPartitions(domainPath, partitions) {
|
|
|
18662
18951
|
if (!isDirectory(domainPath))
|
|
18663
18952
|
return;
|
|
18664
18953
|
for (const name of safeReadDir(domainPath)) {
|
|
18665
|
-
const path =
|
|
18954
|
+
const path = join27(domainPath, name);
|
|
18666
18955
|
if (isDirectory(path)) {
|
|
18667
18956
|
if (!looksLikePartitionKey(name))
|
|
18668
18957
|
continue;
|
|
@@ -18711,7 +19000,7 @@ function looksLikePartitionKey(value) {
|
|
|
18711
19000
|
}
|
|
18712
19001
|
function safeReadDir(path) {
|
|
18713
19002
|
try {
|
|
18714
|
-
return
|
|
19003
|
+
return readdirSync10(path).sort((left, right) => left.localeCompare(right));
|
|
18715
19004
|
} catch {
|
|
18716
19005
|
return [];
|
|
18717
19006
|
}
|
|
@@ -18737,22 +19026,22 @@ var init_legacy_storage = __esm(() => {
|
|
|
18737
19026
|
});
|
|
18738
19027
|
|
|
18739
19028
|
// src/lib/lsp-cache.ts
|
|
18740
|
-
import { existsSync as
|
|
18741
|
-
import { join as
|
|
19029
|
+
import { existsSync as existsSync25, readdirSync as readdirSync11, rmSync as rmSync6, statSync as statSync15 } from "node:fs";
|
|
19030
|
+
import { join as join28 } from "node:path";
|
|
18742
19031
|
function inspectDir(path) {
|
|
18743
|
-
if (!
|
|
19032
|
+
if (!existsSync25(path)) {
|
|
18744
19033
|
return { entries: [], totalSize: 0 };
|
|
18745
19034
|
}
|
|
18746
19035
|
const entries = [];
|
|
18747
19036
|
let totalSize = 0;
|
|
18748
19037
|
let names;
|
|
18749
19038
|
try {
|
|
18750
|
-
names =
|
|
19039
|
+
names = readdirSync11(path);
|
|
18751
19040
|
} catch {
|
|
18752
19041
|
return { entries: [], totalSize: 0 };
|
|
18753
19042
|
}
|
|
18754
19043
|
for (const name of names) {
|
|
18755
|
-
const full =
|
|
19044
|
+
const full = join28(path, name);
|
|
18756
19045
|
try {
|
|
18757
19046
|
if (!statSync15(full).isDirectory())
|
|
18758
19047
|
continue;
|
|
@@ -18814,8 +19103,8 @@ var init_lsp_cache = __esm(() => {
|
|
|
18814
19103
|
});
|
|
18815
19104
|
|
|
18816
19105
|
// src/lib/onnx.ts
|
|
18817
|
-
import { existsSync as
|
|
18818
|
-
import { basename as basename2, isAbsolute as isAbsolute8, join as
|
|
19106
|
+
import { existsSync as existsSync26, readdirSync as readdirSync12, readlinkSync as readlinkSync2, realpathSync as realpathSync7 } from "node:fs";
|
|
19107
|
+
import { basename as basename2, isAbsolute as isAbsolute8, join as join29, resolve as resolve14, win32 as win323 } from "node:path";
|
|
18819
19108
|
function getOnnxLibraryName() {
|
|
18820
19109
|
if (process.platform === "darwin")
|
|
18821
19110
|
return "libonnxruntime.dylib";
|
|
@@ -18867,7 +19156,7 @@ function isWindowsSystem32Directory2(dir) {
|
|
|
18867
19156
|
}
|
|
18868
19157
|
function directoryContainsLibrary2(dir, libName) {
|
|
18869
19158
|
try {
|
|
18870
|
-
const entries =
|
|
19159
|
+
const entries = readdirSync12(dir);
|
|
18871
19160
|
if (process.platform === "win32") {
|
|
18872
19161
|
const expected = libName.toLowerCase();
|
|
18873
19162
|
return entries.some((entry) => entry.toLowerCase() === expected);
|
|
@@ -18885,7 +19174,7 @@ function findIgnoredWindowsSystemOnnxRuntime() {
|
|
|
18885
19174
|
for (const root of windowsRoots) {
|
|
18886
19175
|
if (!root)
|
|
18887
19176
|
continue;
|
|
18888
|
-
const systemDir =
|
|
19177
|
+
const systemDir = join29(root, "System32");
|
|
18889
19178
|
const key = win323.resolve(systemDir).toLowerCase();
|
|
18890
19179
|
if (seen.has(key))
|
|
18891
19180
|
continue;
|
|
@@ -18907,21 +19196,21 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
|
|
|
18907
19196
|
searchPaths.push(...pathEntriesForPlatform2());
|
|
18908
19197
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
18909
19198
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
18910
|
-
searchPaths.push(
|
|
19199
|
+
searchPaths.push(join29(programFiles, "onnxruntime", "lib"), join29(programFiles, "Microsoft ONNX Runtime", "lib"), join29(programFiles, "Microsoft Machine Learning", "lib"), join29(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
18911
19200
|
const nugetPaths = [];
|
|
18912
19201
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
18913
19202
|
if (!userProfile)
|
|
18914
19203
|
return nugetPaths;
|
|
18915
|
-
const nugetPackageDir =
|
|
18916
|
-
if (!
|
|
19204
|
+
const nugetPackageDir = join29(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
19205
|
+
if (!existsSync26(nugetPackageDir))
|
|
18917
19206
|
return nugetPaths;
|
|
18918
19207
|
try {
|
|
18919
|
-
for (const entry of
|
|
19208
|
+
for (const entry of readdirSync12(nugetPackageDir, { withFileTypes: true })) {
|
|
18920
19209
|
if (!entry.isDirectory())
|
|
18921
19210
|
continue;
|
|
18922
19211
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
18923
19212
|
continue;
|
|
18924
|
-
nugetPaths.push(
|
|
19213
|
+
nugetPaths.push(join29(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join29(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
18925
19214
|
}
|
|
18926
19215
|
} catch {}
|
|
18927
19216
|
return nugetPaths;
|
|
@@ -18940,7 +19229,7 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
|
|
|
18940
19229
|
if (!directoryContainsLibrary2(dir, libName))
|
|
18941
19230
|
continue;
|
|
18942
19231
|
if (process.platform !== "win32") {
|
|
18943
|
-
const probe = probeOnnxRuntimeLoadable(
|
|
19232
|
+
const probe = probeOnnxRuntimeLoadable(join29(dir, libName));
|
|
18944
19233
|
if (!probe.loadable) {
|
|
18945
19234
|
ignored ??= { path: dir, reason: `unloadable: ${probe.reason} — ignored` };
|
|
18946
19235
|
continue;
|
|
@@ -18960,12 +19249,12 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
|
|
|
18960
19249
|
return { path: unknownVersionPaths[0] ?? null, ignored };
|
|
18961
19250
|
}
|
|
18962
19251
|
function findCachedOnnxRuntime2(storageDir) {
|
|
18963
|
-
const ortDir =
|
|
19252
|
+
const ortDir = join29(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
|
|
18964
19253
|
const libName = getOnnxLibraryName();
|
|
18965
|
-
if (
|
|
19254
|
+
if (existsSync26(join29(ortDir, libName)))
|
|
18966
19255
|
return ortDir;
|
|
18967
|
-
const libSubdir =
|
|
18968
|
-
if (
|
|
19256
|
+
const libSubdir = join29(ortDir, "lib");
|
|
19257
|
+
if (existsSync26(join29(libSubdir, libName)))
|
|
18969
19258
|
return libSubdir;
|
|
18970
19259
|
return null;
|
|
18971
19260
|
}
|
|
@@ -18986,16 +19275,16 @@ function parseOrtVersionFromDirectoryPath(value) {
|
|
|
18986
19275
|
return null;
|
|
18987
19276
|
}
|
|
18988
19277
|
function detectOrtVersion(libDir) {
|
|
18989
|
-
if (!
|
|
19278
|
+
if (!existsSync26(libDir))
|
|
18990
19279
|
return null;
|
|
18991
19280
|
const libName = getOnnxLibraryName();
|
|
18992
19281
|
try {
|
|
18993
|
-
const resolved = parseOrtVersionFromPath(realpathSync7(
|
|
19282
|
+
const resolved = parseOrtVersionFromPath(realpathSync7(join29(libDir, libName)));
|
|
18994
19283
|
if (resolved && resolved !== INVALID_ORT_VERSION2)
|
|
18995
19284
|
return resolved;
|
|
18996
19285
|
} catch {}
|
|
18997
19286
|
try {
|
|
18998
|
-
const entries =
|
|
19287
|
+
const entries = readdirSync12(libDir);
|
|
18999
19288
|
const barePrefix = libName.replace(/\.(so|dylib|dll)$/, "");
|
|
19000
19289
|
const expectedPrefix = process.platform === "win32" ? barePrefix.toLowerCase() : barePrefix;
|
|
19001
19290
|
for (const entry of entries) {
|
|
@@ -19006,8 +19295,8 @@ function detectOrtVersion(libDir) {
|
|
|
19006
19295
|
if (version)
|
|
19007
19296
|
return version;
|
|
19008
19297
|
}
|
|
19009
|
-
const base =
|
|
19010
|
-
if (
|
|
19298
|
+
const base = join29(libDir, libName);
|
|
19299
|
+
if (existsSync26(base)) {
|
|
19011
19300
|
try {
|
|
19012
19301
|
const real = realpathSync7(base);
|
|
19013
19302
|
const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
|
|
@@ -19040,17 +19329,17 @@ var init_onnx = __esm(() => {
|
|
|
19040
19329
|
});
|
|
19041
19330
|
|
|
19042
19331
|
// src/lib/plugin-load.ts
|
|
19043
|
-
import { existsSync as
|
|
19332
|
+
import { existsSync as existsSync27, readFileSync as readFileSync16 } from "node:fs";
|
|
19044
19333
|
import { homedir as homedir18 } from "node:os";
|
|
19045
|
-
import { isAbsolute as isAbsolute9, join as
|
|
19334
|
+
import { isAbsolute as isAbsolute9, join as join30, normalize } from "node:path";
|
|
19046
19335
|
function isRecord3(value) {
|
|
19047
19336
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19048
19337
|
}
|
|
19049
19338
|
function readConfig(path) {
|
|
19050
|
-
if (!
|
|
19339
|
+
if (!existsSync27(path))
|
|
19051
19340
|
return { value: null, error: null };
|
|
19052
19341
|
try {
|
|
19053
|
-
const parsed = import_comment_json3.parse(
|
|
19342
|
+
const parsed = import_comment_json3.parse(readFileSync16(path, "utf8"));
|
|
19054
19343
|
const plain = JSON.parse(JSON.stringify(parsed));
|
|
19055
19344
|
return isRecord3(plain) ? { value: plain, error: null } : { value: null, error: "the file is not a JSON object" };
|
|
19056
19345
|
} catch (error) {
|
|
@@ -19106,7 +19395,7 @@ function evaluatePluginLoad(input) {
|
|
|
19106
19395
|
const raw = typeof subc?.connection_file === "string" ? subc.connection_file.trim() : "";
|
|
19107
19396
|
if (raw.length > 0) {
|
|
19108
19397
|
const resolved = resolveSubcConnectionPath(raw, input.home);
|
|
19109
|
-
if (!
|
|
19398
|
+
if (!existsSync27(resolved)) {
|
|
19110
19399
|
const toolCallError = formatConfigErrorMessage(formatSubcConnectionMissingMessage(raw, resolved));
|
|
19111
19400
|
blockers.push({
|
|
19112
19401
|
code: "subc_connection_missing",
|
|
@@ -19125,7 +19414,7 @@ function evaluatePluginLoad(input) {
|
|
|
19125
19414
|
const storage = loaded.user && isRecord3(loaded.user.storage) ? loaded.user.storage : null;
|
|
19126
19415
|
const requested = typeof storage?.cache_dir === "string" ? storage.cache_dir : "";
|
|
19127
19416
|
const home = input.home ?? homedir18();
|
|
19128
|
-
const expanded = requested === "~" ? home : requested.startsWith("~/") || requested.startsWith("~\\") ?
|
|
19417
|
+
const expanded = requested === "~" ? home : requested.startsWith("~/") || requested.startsWith("~\\") ? join30(home, requested.slice(2)) : requested;
|
|
19129
19418
|
return {
|
|
19130
19419
|
...isAbsolute9(expanded) ? { cacheDir: normalize(expanded) } : {},
|
|
19131
19420
|
blockers,
|
|
@@ -19145,15 +19434,16 @@ import {
|
|
|
19145
19434
|
accessSync as accessSync3,
|
|
19146
19435
|
closeSync as closeSync9,
|
|
19147
19436
|
constants as constants5,
|
|
19148
|
-
existsSync as
|
|
19437
|
+
existsSync as existsSync28,
|
|
19149
19438
|
openSync as openSync9,
|
|
19150
19439
|
readSync as readSync7,
|
|
19151
19440
|
statSync as statSync16
|
|
19152
19441
|
} from "node:fs";
|
|
19153
|
-
import { join as
|
|
19442
|
+
import { join as join31 } from "node:path";
|
|
19154
19443
|
async function collectDiagnostics(adapters) {
|
|
19155
19444
|
const cliVersion = getSelfVersion();
|
|
19156
|
-
const
|
|
19445
|
+
const binaryProbe = probeAftBinary(cliVersion);
|
|
19446
|
+
const binaryVersion = binaryProbe.version;
|
|
19157
19447
|
const harnesses = [];
|
|
19158
19448
|
for (const adapter of adapters) {
|
|
19159
19449
|
harnesses.push(await diagnoseHarness(adapter));
|
|
@@ -19165,6 +19455,7 @@ async function collectDiagnostics(adapters) {
|
|
|
19165
19455
|
nodeVersion: process.version,
|
|
19166
19456
|
cliVersion,
|
|
19167
19457
|
binaryVersion,
|
|
19458
|
+
binaryPath: binaryProbe.path,
|
|
19168
19459
|
harnesses,
|
|
19169
19460
|
binaryCache: getBinaryCacheInfo(cliVersion),
|
|
19170
19461
|
lspCache: getLspCacheReport(),
|
|
@@ -19185,7 +19476,7 @@ async function diagnoseHarness(adapter) {
|
|
|
19185
19476
|
const logPath = adapter.getLogFile();
|
|
19186
19477
|
const pluginCache = adapter.getPluginCacheInfo();
|
|
19187
19478
|
const storageAccessible = (() => {
|
|
19188
|
-
if (!
|
|
19479
|
+
if (!existsSync28(storage))
|
|
19189
19480
|
return false;
|
|
19190
19481
|
try {
|
|
19191
19482
|
accessSync3(storage, constants5.R_OK | constants5.W_OK);
|
|
@@ -19220,7 +19511,7 @@ async function diagnoseHarness(adapter) {
|
|
|
19220
19511
|
pluginRegistered: adapter.hasPluginEntry(),
|
|
19221
19512
|
configPaths,
|
|
19222
19513
|
aftConfig: {
|
|
19223
|
-
exists:
|
|
19514
|
+
exists: existsSync28(configPaths.aftConfig),
|
|
19224
19515
|
...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
|
|
19225
19516
|
enabled: aftEnabled,
|
|
19226
19517
|
...aftEnabledSource ? { enabledSource: aftEnabledSource } : {},
|
|
@@ -19229,10 +19520,10 @@ async function diagnoseHarness(adapter) {
|
|
|
19229
19520
|
pluginCache,
|
|
19230
19521
|
storageDir: {
|
|
19231
19522
|
path: storage,
|
|
19232
|
-
exists:
|
|
19523
|
+
exists: existsSync28(storage),
|
|
19233
19524
|
accessible: storageAccessible,
|
|
19234
19525
|
sizesByKey: describeStorage,
|
|
19235
|
-
...pluginLoad.cacheDir ? { cacheRoot:
|
|
19526
|
+
...pluginLoad.cacheDir ? { cacheRoot: join31(pluginLoad.cacheDir, "aft") } : {},
|
|
19236
19527
|
...legacyDuplication.totalPartitions > 0 ? { legacyDuplication } : {}
|
|
19237
19528
|
},
|
|
19238
19529
|
onnxRuntime: {
|
|
@@ -19252,8 +19543,8 @@ async function diagnoseHarness(adapter) {
|
|
|
19252
19543
|
},
|
|
19253
19544
|
logFile: {
|
|
19254
19545
|
path: logPath,
|
|
19255
|
-
exists:
|
|
19256
|
-
sizeKb:
|
|
19546
|
+
exists: existsSync28(logPath),
|
|
19547
|
+
sizeKb: existsSync28(logPath) ? Math.round(statSync16(logPath).size / 1024) : 0
|
|
19257
19548
|
},
|
|
19258
19549
|
pluginLoad
|
|
19259
19550
|
};
|
|
@@ -19262,7 +19553,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
19262
19553
|
const lines = [];
|
|
19263
19554
|
lines.push(`- Timestamp: ${report.timestamp}`);
|
|
19264
19555
|
lines.push(`- AFT CLI: v${report.cliVersion}`);
|
|
19265
|
-
lines.push(`-
|
|
19556
|
+
lines.push(`- ${describeCliBinary(report.binaryVersion, report.binaryPath)}`);
|
|
19266
19557
|
lines.push(`- OS: ${report.platform} ${report.arch}`);
|
|
19267
19558
|
lines.push(`- Node: ${report.nodeVersion}`);
|
|
19268
19559
|
const issues = collectDiagnosticIssues(report);
|
|
@@ -19279,7 +19570,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
19279
19570
|
lines.push(`- Host installed: ${h.hostInstalled}`);
|
|
19280
19571
|
lines.push(`- Host version: ${h.hostVersion ?? "unknown"}`);
|
|
19281
19572
|
lines.push(`- Plugin registered: ${h.pluginRegistered}`);
|
|
19282
|
-
lines.push(`- Plugin version: ${h.pluginCache
|
|
19573
|
+
lines.push(`- Plugin version: ${describePluginVersion(h.pluginCache)}`);
|
|
19283
19574
|
lines.push(`- AFT enabled: ${h.aftConfig.enabled}${h.aftConfig.enabledSource ? ` (from ${h.aftConfig.enabledSource})` : ""}`);
|
|
19284
19575
|
lines.push(`- AFT config parse error: ${h.aftConfig.parseError ?? "none"}`);
|
|
19285
19576
|
lines.push("");
|
|
@@ -19314,7 +19605,8 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
19314
19605
|
lines.push("");
|
|
19315
19606
|
lines.push("### Binary cache");
|
|
19316
19607
|
lines.push("```json");
|
|
19317
|
-
|
|
19608
|
+
const { activeVersion, ...cacheInventory } = report.binaryCache;
|
|
19609
|
+
lines.push(JSON.stringify({ ...cacheInventory, [CLI_VERSION_CACHED_LABEL]: activeVersion }, null, 2));
|
|
19318
19610
|
lines.push("```");
|
|
19319
19611
|
lines.push("");
|
|
19320
19612
|
lines.push("### LSP cache");
|
|
@@ -19347,6 +19639,8 @@ function openCodeEntryToPin(harness, cliVersion) {
|
|
|
19347
19639
|
if (harness.kind !== "opencode")
|
|
19348
19640
|
return null;
|
|
19349
19641
|
const entry = harness.pluginCache.configuredEntry;
|
|
19642
|
+
if (preserveDoctorPluginEntry(normalizeVersion(cliVersion), entry, doctorInstalledVersion(harness.pluginCache)))
|
|
19643
|
+
return null;
|
|
19350
19644
|
return entry && entry !== pinnedPluginEntry(normalizeVersion(cliVersion)) ? entry : null;
|
|
19351
19645
|
}
|
|
19352
19646
|
function pluginVersionSkewRemediation(harness, cliVersion, older) {
|
|
@@ -19362,12 +19656,23 @@ function pluginVersionSkewRemediation(harness, cliVersion, older) {
|
|
|
19362
19656
|
return entry ? `Run \`${CLI} doctor --fix\` to pin the plugin entry to ${pinnedPluginEntry(version)} and ${change}.` : `Run \`${CLI} doctor --fix\` to ${change}.`;
|
|
19363
19657
|
}
|
|
19364
19658
|
function pluginVersionSkewIssue(harness, cliVersion) {
|
|
19659
|
+
if (harness.pluginCache.local)
|
|
19660
|
+
return null;
|
|
19661
|
+
if (harness.kind === "opencode" && preserveDoctorPluginEntry(normalizeVersion(cliVersion), harness.pluginCache.configuredEntry, doctorInstalledVersion(harness.pluginCache))) {
|
|
19662
|
+
return {
|
|
19663
|
+
code: "plugin_cli_version_skew",
|
|
19664
|
+
severity: "info",
|
|
19665
|
+
scope: harness.displayName,
|
|
19666
|
+
message: doctorNoDowngradeMessage(normalizeVersion(cliVersion), harness.pluginCache.configuredEntry, doctorInstalledVersion(harness.pluginCache)),
|
|
19667
|
+
remediation: ""
|
|
19668
|
+
};
|
|
19669
|
+
}
|
|
19365
19670
|
const pluginVersion = harness.pluginCache.cached;
|
|
19366
19671
|
if (!pluginVersion)
|
|
19367
19672
|
return null;
|
|
19368
19673
|
if (normalizeVersion(pluginVersion) === normalizeVersion(cliVersion))
|
|
19369
19674
|
return null;
|
|
19370
|
-
const older = compareLooseSemver(pluginVersion, cliVersion) < 0;
|
|
19675
|
+
const older = (compareSemver2(normalizeVersion(pluginVersion), normalizeVersion(cliVersion)) ?? compareLooseSemver(pluginVersion, cliVersion)) < 0;
|
|
19371
19676
|
const skew = older ? `Plugin version (${pluginVersion}) is older than CLI (${cliVersion}). New binary cache won't be used until you update the plugin.` : `Plugin version (${pluginVersion}) does not match CLI (${cliVersion}). New binary cache may not be used until the plugin and CLI match.`;
|
|
19372
19677
|
const entry = openCodeEntryToPin(harness, cliVersion);
|
|
19373
19678
|
return {
|
|
@@ -19484,7 +19789,7 @@ function formatDiagnosticIssuesSection(report) {
|
|
|
19484
19789
|
return lines;
|
|
19485
19790
|
}
|
|
19486
19791
|
function tailLogFile(path, lines) {
|
|
19487
|
-
if (!
|
|
19792
|
+
if (!existsSync28(path))
|
|
19488
19793
|
return "";
|
|
19489
19794
|
if (lines <= 0)
|
|
19490
19795
|
return "";
|
|
@@ -19529,6 +19834,7 @@ var init_diagnostics = __esm(async () => {
|
|
|
19529
19834
|
init_legacy_storage();
|
|
19530
19835
|
init_lsp_cache();
|
|
19531
19836
|
init_onnx();
|
|
19837
|
+
init_opencode_plugin_cache();
|
|
19532
19838
|
init_plugin_load();
|
|
19533
19839
|
init_sanitize();
|
|
19534
19840
|
init_self_version();
|
|
@@ -19684,14 +19990,14 @@ var init_issue_body = __esm(() => {
|
|
|
19684
19990
|
|
|
19685
19991
|
// src/lib/onnx-fix.ts
|
|
19686
19992
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
19687
|
-
import { existsSync as
|
|
19688
|
-
import { isAbsolute as isAbsolute10, join as
|
|
19993
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync7, renameSync as renameSync6, rmSync as rmSync7 } from "node:fs";
|
|
19994
|
+
import { isAbsolute as isAbsolute10, join as join32, relative as relative4 } from "node:path";
|
|
19689
19995
|
function findOnnxFixCandidates(report) {
|
|
19690
19996
|
const candidates = [];
|
|
19691
19997
|
for (const harness of report.harnesses) {
|
|
19692
19998
|
if (!harness.onnxRuntime.required)
|
|
19693
19999
|
continue;
|
|
19694
|
-
const storageOnnxDir =
|
|
20000
|
+
const storageOnnxDir = join32(harness.storageDir.path, "onnxruntime");
|
|
19695
20001
|
const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
|
|
19696
20002
|
const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
|
|
19697
20003
|
const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
|
|
@@ -19700,7 +20006,7 @@ function findOnnxFixCandidates(report) {
|
|
|
19700
20006
|
harness,
|
|
19701
20007
|
reason: `cached ONNX Runtime at ${harness.onnxRuntime.cachedPath} is v${harness.onnxRuntime.cachedVersion}, but AFT requires ${harness.onnxRuntime.requirement}. AFT will stage and verify a managed replacement before removing it.`,
|
|
19702
20008
|
storageOnnxDir,
|
|
19703
|
-
storageOnnxBytes:
|
|
20009
|
+
storageOnnxBytes: existsSync29(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
19704
20010
|
});
|
|
19705
20011
|
continue;
|
|
19706
20012
|
}
|
|
@@ -19709,7 +20015,7 @@ function findOnnxFixCandidates(report) {
|
|
|
19709
20015
|
harness,
|
|
19710
20016
|
reason: `system ONNX Runtime at ${harness.onnxRuntime.systemPath} is v${harness.onnxRuntime.systemVersion}, but AFT requires ${harness.onnxRuntime.requirement}, and no AFT-managed install is present. AFT will leave the system copy untouched and download v1.24 into managed storage.`,
|
|
19711
20017
|
storageOnnxDir,
|
|
19712
|
-
storageOnnxBytes:
|
|
20018
|
+
storageOnnxBytes: existsSync29(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
19713
20019
|
});
|
|
19714
20020
|
continue;
|
|
19715
20021
|
}
|
|
@@ -19721,7 +20027,7 @@ function findOnnxFixCandidates(report) {
|
|
|
19721
20027
|
harness,
|
|
19722
20028
|
reason: `no compatible ONNX Runtime is installed.${ignoredCopy} AFT will download v1.24 into managed storage.`,
|
|
19723
20029
|
storageOnnxDir,
|
|
19724
|
-
storageOnnxBytes:
|
|
20030
|
+
storageOnnxBytes: existsSync29(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
19725
20031
|
});
|
|
19726
20032
|
}
|
|
19727
20033
|
}
|
|
@@ -19730,11 +20036,11 @@ function findOnnxFixCandidates(report) {
|
|
|
19730
20036
|
async function installManagedReplacement(candidate, ensureFn, rmFn) {
|
|
19731
20037
|
const suffix = `${process.pid}.${Date.now().toString(36)}.${randomBytes2(6).toString("hex")}`;
|
|
19732
20038
|
const stagingStorageDir = `${candidate.harness.storageDir.path}.onnx-fix.tmp.${suffix}`;
|
|
19733
|
-
const stagedOnnxDir =
|
|
20039
|
+
const stagedOnnxDir = join32(stagingStorageDir, "onnxruntime");
|
|
19734
20040
|
const backupDir = `${candidate.storageOnnxDir}.backup.${suffix}`;
|
|
19735
20041
|
try {
|
|
19736
20042
|
const stagedInstalledPath = await ensureFn(stagingStorageDir);
|
|
19737
|
-
if (!stagedInstalledPath || !
|
|
20043
|
+
if (!stagedInstalledPath || !existsSync29(stagedInstalledPath)) {
|
|
19738
20044
|
throw new Error("managed ONNX Runtime download was unavailable");
|
|
19739
20045
|
}
|
|
19740
20046
|
const installedRelativePath = relative4(stagedOnnxDir, stagedInstalledPath);
|
|
@@ -19742,7 +20048,7 @@ async function installManagedReplacement(candidate, ensureFn, rmFn) {
|
|
|
19742
20048
|
throw new Error(`managed ONNX Runtime was installed outside staging: ${stagedInstalledPath}`);
|
|
19743
20049
|
}
|
|
19744
20050
|
mkdirSync7(candidate.harness.storageDir.path, { recursive: true });
|
|
19745
|
-
const hadPrevious =
|
|
20051
|
+
const hadPrevious = existsSync29(candidate.storageOnnxDir);
|
|
19746
20052
|
if (hadPrevious)
|
|
19747
20053
|
renameSync6(candidate.storageOnnxDir, backupDir);
|
|
19748
20054
|
try {
|
|
@@ -19766,7 +20072,7 @@ async function installManagedReplacement(candidate, ensureFn, rmFn) {
|
|
|
19766
20072
|
}
|
|
19767
20073
|
}
|
|
19768
20074
|
return {
|
|
19769
|
-
installedPath:
|
|
20075
|
+
installedPath: join32(candidate.storageOnnxDir, installedRelativePath),
|
|
19770
20076
|
clearedPrevious: hadPrevious && cleanupError === undefined,
|
|
19771
20077
|
cleanupError
|
|
19772
20078
|
};
|
|
@@ -19915,10 +20221,10 @@ var init_session_log = __esm(() => {
|
|
|
19915
20221
|
});
|
|
19916
20222
|
|
|
19917
20223
|
// src/lib/sessions.ts
|
|
19918
|
-
import { existsSync as
|
|
20224
|
+
import { existsSync as existsSync30, readdirSync as readdirSync13, readFileSync as readFileSync17, statSync as statSync18 } from "node:fs";
|
|
19919
20225
|
import { createRequire as createRequire4 } from "node:module";
|
|
19920
20226
|
import { homedir as homedir19 } from "node:os";
|
|
19921
|
-
import { basename as basename3, join as
|
|
20227
|
+
import { basename as basename3, join as join33 } from "node:path";
|
|
19922
20228
|
function listRecentSessions(adapter) {
|
|
19923
20229
|
try {
|
|
19924
20230
|
if (adapter.kind === "opencode")
|
|
@@ -19952,8 +20258,8 @@ function mapOpenCodeSessionRows(rows) {
|
|
|
19952
20258
|
}).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
|
|
19953
20259
|
}
|
|
19954
20260
|
function listRecentOpenCodeSessions() {
|
|
19955
|
-
const dbPath =
|
|
19956
|
-
if (!
|
|
20261
|
+
const dbPath = join33(getXdgDataHome(), "opencode", "opencode.db");
|
|
20262
|
+
if (!existsSync30(dbPath))
|
|
19957
20263
|
return [];
|
|
19958
20264
|
let db = null;
|
|
19959
20265
|
try {
|
|
@@ -19972,10 +20278,10 @@ function listRecentOpenCodeSessions() {
|
|
|
19972
20278
|
}
|
|
19973
20279
|
function getXdgDataHome() {
|
|
19974
20280
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
19975
|
-
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome :
|
|
20281
|
+
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join33(homedir19(), ".local", "share");
|
|
19976
20282
|
}
|
|
19977
20283
|
function listRecentPiSessions() {
|
|
19978
|
-
return listPiSessionsFromDir(
|
|
20284
|
+
return listPiSessionsFromDir(join33(getHomeDir(), ".pi", "agent", "sessions"));
|
|
19979
20285
|
}
|
|
19980
20286
|
function getHomeDir() {
|
|
19981
20287
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
@@ -19983,7 +20289,7 @@ function getHomeDir() {
|
|
|
19983
20289
|
}
|
|
19984
20290
|
function listPiSessionsFromDir(sessionsDir) {
|
|
19985
20291
|
try {
|
|
19986
|
-
if (!
|
|
20292
|
+
if (!existsSync30(sessionsDir))
|
|
19987
20293
|
return [];
|
|
19988
20294
|
const files = collectJsonlFiles(sessionsDir).map((filePath) => {
|
|
19989
20295
|
try {
|
|
@@ -19995,7 +20301,7 @@ function listPiSessionsFromDir(sessionsDir) {
|
|
|
19995
20301
|
}).filter((entry) => entry !== null).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
|
|
19996
20302
|
const sessions = [];
|
|
19997
20303
|
for (const file of files) {
|
|
19998
|
-
const parsed = parsePiSessionJsonl(
|
|
20304
|
+
const parsed = parsePiSessionJsonl(readFileSync17(file.filePath, "utf8"), basename3(file.filePath));
|
|
19999
20305
|
if (!parsed)
|
|
20000
20306
|
continue;
|
|
20001
20307
|
sessions.push({ ...parsed, lastActivity: file.mtimeMs });
|
|
@@ -20016,12 +20322,12 @@ function collectJsonlFiles(root) {
|
|
|
20016
20322
|
continue;
|
|
20017
20323
|
let entries;
|
|
20018
20324
|
try {
|
|
20019
|
-
entries =
|
|
20325
|
+
entries = readdirSync13(dir, { withFileTypes: true });
|
|
20020
20326
|
} catch {
|
|
20021
20327
|
continue;
|
|
20022
20328
|
}
|
|
20023
20329
|
for (const entry of entries) {
|
|
20024
|
-
const path =
|
|
20330
|
+
const path = join33(dir, entry.name);
|
|
20025
20331
|
if (entry.isDirectory()) {
|
|
20026
20332
|
stack.push(path);
|
|
20027
20333
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
@@ -20122,19 +20428,19 @@ var init_sessions = __esm(() => {
|
|
|
20122
20428
|
// src/commands/doctor.ts
|
|
20123
20429
|
import {
|
|
20124
20430
|
chmodSync as chmodSync4,
|
|
20125
|
-
existsSync as
|
|
20431
|
+
existsSync as existsSync31,
|
|
20126
20432
|
lstatSync as lstatSync5,
|
|
20127
20433
|
mkdirSync as mkdirSync8,
|
|
20128
20434
|
mkdtempSync as mkdtempSync2,
|
|
20129
|
-
readdirSync as
|
|
20130
|
-
readFileSync as
|
|
20435
|
+
readdirSync as readdirSync14,
|
|
20436
|
+
readFileSync as readFileSync18,
|
|
20131
20437
|
realpathSync as realpathSync8,
|
|
20132
20438
|
rmSync as rmSync8,
|
|
20133
20439
|
statSync as statSync19,
|
|
20134
20440
|
writeFileSync as writeFileSync5
|
|
20135
20441
|
} from "node:fs";
|
|
20136
20442
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
20137
|
-
import { dirname as
|
|
20443
|
+
import { dirname as dirname13, join as join34 } from "node:path";
|
|
20138
20444
|
function openCodeAdapter(adapters) {
|
|
20139
20445
|
return adapters.find((adapter) => adapter.kind === "opencode");
|
|
20140
20446
|
}
|
|
@@ -20157,7 +20463,7 @@ function refuseAmbiguousOpenCodeWrites(detection) {
|
|
|
20157
20463
|
function adapterConfigNeedsUpdate(adapter, tui = false) {
|
|
20158
20464
|
const method = tui ? "needsTuiPluginEntryUpdate" : "needsPluginEntryUpdate";
|
|
20159
20465
|
const candidate = adapter;
|
|
20160
|
-
return candidate[method]?.() ?? false;
|
|
20466
|
+
return candidate[method]?.({ doctor: true }) ?? false;
|
|
20161
20467
|
}
|
|
20162
20468
|
function buildDoctorProfileArgs(argv) {
|
|
20163
20469
|
const profileIndex = argv.indexOf("--profile");
|
|
@@ -20214,12 +20520,12 @@ async function runDoctor(options) {
|
|
|
20214
20520
|
configPath: opencodeHarness.configPaths.harnessConfig,
|
|
20215
20521
|
logPath: opencodeHarness.logFile.path,
|
|
20216
20522
|
pluginCachePath: opencodeHarness.pluginCache.path,
|
|
20217
|
-
cachedPluginVersion: opencodeHarness.pluginCache
|
|
20523
|
+
cachedPluginVersion: doctorInstalledVersion(opencodeHarness.pluginCache),
|
|
20218
20524
|
expectedPluginEntry: opencodeAdapter.pluginEntryWithVersion,
|
|
20219
20525
|
acceptExplicitPluginVersion: hostDetection.status === "v1"
|
|
20220
20526
|
}) : null;
|
|
20221
20527
|
const opencodeSkew = opencodeHarness ? pluginVersionSkewFor(report, opencodeHarness) : null;
|
|
20222
|
-
log2.info(`AFT CLI v${report.cliVersion},
|
|
20528
|
+
log2.info(`AFT CLI v${report.cliVersion}, ${describeCliBinary(report.binaryVersion, report.binaryPath)}`);
|
|
20223
20529
|
if (!report.binaryVersion) {
|
|
20224
20530
|
const hasEnabledRegisteredHarness = report.harnesses.some((h) => h.pluginRegistered && h.aftConfig.enabled);
|
|
20225
20531
|
const hasRegisteredHarness = report.harnesses.some((h) => h.pluginRegistered);
|
|
@@ -20235,7 +20541,7 @@ async function runDoctor(options) {
|
|
|
20235
20541
|
}
|
|
20236
20542
|
logUnmatchedBinaryCandidates(report.cliVersion);
|
|
20237
20543
|
}
|
|
20238
|
-
log2.info(`Binary cache: ${report.binaryCache.versions.length} version(s), ${formatBytes(report.binaryCache.totalSize)} at ${report.binaryCache.path}`);
|
|
20544
|
+
log2.info(`Binary cache: ${report.binaryCache.versions.length} version(s), ${formatBytes(report.binaryCache.totalSize)} at ${report.binaryCache.path}; ${CLI_VERSION_CACHED_LABEL}: ${report.binaryCache.activeVersion ?? "no"}`);
|
|
20239
20545
|
logBuildBreakerSuspensions(report);
|
|
20240
20546
|
const features = logFeatureStatus(options.argv, options.runNative, {
|
|
20241
20547
|
checkGh: options.checkGh ?? checkGhStatus,
|
|
@@ -20274,6 +20580,8 @@ async function runDoctor(options) {
|
|
|
20274
20580
|
}
|
|
20275
20581
|
if (opencodeSkew)
|
|
20276
20582
|
log2.error(` ${opencodeSkew.message} ${opencodeSkew.remediation}`);
|
|
20583
|
+
else if (opencodeDoctor?.versionNotice)
|
|
20584
|
+
log2.info(` ${opencodeDoctor.versionNotice}`);
|
|
20277
20585
|
for (const hostTool of OPENCODE_HOST_TOOL_NAMES) {
|
|
20278
20586
|
const line = hostToolDoctorLine(opencodeAdapter, hostTool);
|
|
20279
20587
|
if (line)
|
|
@@ -20286,7 +20594,7 @@ async function runDoctor(options) {
|
|
|
20286
20594
|
} else {
|
|
20287
20595
|
log2.info(` plugin registered: ${h.pluginRegistered ? "yes" : "no"}`);
|
|
20288
20596
|
}
|
|
20289
|
-
log2.info(` plugin version: ${h.
|
|
20597
|
+
log2.info(` plugin version: ${describePluginVersion(h.pluginCache)}`);
|
|
20290
20598
|
if (!h.aftConfig.enabled) {
|
|
20291
20599
|
log2.info(` AFT disabled by config${h.aftConfig.enabledSource ? ` (${h.aftConfig.enabledSource})` : ""}; plugin will stay inert`);
|
|
20292
20600
|
}
|
|
@@ -20545,7 +20853,7 @@ function clearOldBinaries(cliVersion = getSelfVersion(), plugins = getAllAdapter
|
|
|
20545
20853
|
errors: [],
|
|
20546
20854
|
keptVersion: keepTag
|
|
20547
20855
|
};
|
|
20548
|
-
if (!
|
|
20856
|
+
if (!existsSync31(info.path)) {
|
|
20549
20857
|
log2.info(`Binary cache: nothing to clear at ${info.path}`);
|
|
20550
20858
|
return result;
|
|
20551
20859
|
}
|
|
@@ -20576,7 +20884,7 @@ function clearOldBinaries(cliVersion = getSelfVersion(), plugins = getAllAdapter
|
|
|
20576
20884
|
return result;
|
|
20577
20885
|
}
|
|
20578
20886
|
for (const version of stale) {
|
|
20579
|
-
const dir =
|
|
20887
|
+
const dir = join34(info.path, version);
|
|
20580
20888
|
let bytes = 0;
|
|
20581
20889
|
try {
|
|
20582
20890
|
bytes = statSync19(dir).isDirectory() ? dirSize(dir) : 0;
|
|
@@ -20640,9 +20948,14 @@ function findPluginUpdateTargets(adapters, report) {
|
|
|
20640
20948
|
if (!harness.hostInstalled || !harness.pluginRegistered)
|
|
20641
20949
|
continue;
|
|
20642
20950
|
const cache = harness.pluginCache;
|
|
20643
|
-
if (
|
|
20951
|
+
if (cache.local)
|
|
20952
|
+
continue;
|
|
20953
|
+
const cliVersion = cache.cliVersion ?? cache.latest ?? report.cliVersion;
|
|
20954
|
+
if (!cache?.exists || !cache.cached)
|
|
20644
20955
|
continue;
|
|
20645
|
-
if (cache.
|
|
20956
|
+
if (preserveDoctorPluginEntry(cliVersion, cache.configuredEntry, doctorInstalledVersion(cache)))
|
|
20957
|
+
continue;
|
|
20958
|
+
if ((compareSemver2(cache.cached, cliVersion) ?? 0) >= 0)
|
|
20646
20959
|
continue;
|
|
20647
20960
|
const adapter = adaptersByKind.get(harness.kind);
|
|
20648
20961
|
if (!adapter)
|
|
@@ -20652,8 +20965,8 @@ function findPluginUpdateTargets(adapters, report) {
|
|
|
20652
20965
|
adapter,
|
|
20653
20966
|
installDir: cache.path,
|
|
20654
20967
|
cached: cache.cached,
|
|
20655
|
-
latest:
|
|
20656
|
-
oldPin: pin !== null && pin !==
|
|
20968
|
+
latest: cliVersion,
|
|
20969
|
+
oldPin: pin !== null && pin !== cliVersion ? pin : null
|
|
20657
20970
|
});
|
|
20658
20971
|
}
|
|
20659
20972
|
return targets;
|
|
@@ -20736,9 +21049,9 @@ async function runDoctorNpmInstall(npm, installDir) {
|
|
|
20736
21049
|
});
|
|
20737
21050
|
}
|
|
20738
21051
|
function installedPluginVersion(installDir) {
|
|
20739
|
-
const manifest =
|
|
21052
|
+
const manifest = join34(installDir, "node_modules", ...AFT_OPENCODE_PACKAGE.split("/"), "package.json");
|
|
20740
21053
|
try {
|
|
20741
|
-
const pkg = JSON.parse(
|
|
21054
|
+
const pkg = JSON.parse(readFileSync18(manifest, "utf-8"));
|
|
20742
21055
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
20743
21056
|
} catch {
|
|
20744
21057
|
return null;
|
|
@@ -20838,7 +21151,7 @@ function buildDoctorFixPlan(adapters, report) {
|
|
|
20838
21151
|
} else {
|
|
20839
21152
|
items.push({
|
|
20840
21153
|
kind: "plugin",
|
|
20841
|
-
message: `Will ${harness.pluginRegistered ? "update" : "add"} ${adapter.pluginEntryWithVersion} ${harness.pluginRegistered ? "in" : "to"} ${harness.configPaths.harnessConfig}`
|
|
21154
|
+
message: `Will ${harness.pluginRegistered ? "update" : "add"} ${adapter instanceof OpenCodeAdapter ? adapter.doctorPluginEntry() : adapter.pluginEntryWithVersion} ${harness.pluginRegistered ? "in" : "to"} ${harness.configPaths.harnessConfig}`
|
|
20842
21155
|
});
|
|
20843
21156
|
}
|
|
20844
21157
|
}
|
|
@@ -20855,7 +21168,7 @@ function buildDoctorFixPlan(adapters, report) {
|
|
|
20855
21168
|
continue;
|
|
20856
21169
|
items.push({
|
|
20857
21170
|
kind: "plugin",
|
|
20858
|
-
message: `Will ${hasTuiEntry ? "update" : "add"} ${adapter.pluginEntryWithVersion} ${hasTuiEntry ? "in" : "to"} ${harness.configPaths.tuiConfig} (TUI sidebar)`
|
|
21171
|
+
message: `Will ${hasTuiEntry ? "update" : "add"} ${adapter instanceof OpenCodeAdapter ? adapter.doctorPluginEntry(true) : adapter.pluginEntryWithVersion} ${hasTuiEntry ? "in" : "to"} ${harness.configPaths.tuiConfig} (TUI sidebar)`
|
|
20859
21172
|
});
|
|
20860
21173
|
}
|
|
20861
21174
|
for (const { adapter, hostTool } of hostToolFixTargets(adapters)) {
|
|
@@ -20994,6 +21307,12 @@ async function runFixFlow(argv, detectOpenCodeHost, resolveAdapters = resolveAda
|
|
|
20994
21307
|
}
|
|
20995
21308
|
log2.info("Running diagnostics to identify auto-fixable issues…");
|
|
20996
21309
|
const report = await collect(adapters);
|
|
21310
|
+
for (const harness of report.harnesses) {
|
|
21311
|
+
const cache = harness.pluginCache;
|
|
21312
|
+
if (harness.kind === "opencode" && preserveDoctorPluginEntry(report.cliVersion, cache.configuredEntry, doctorInstalledVersion(cache))) {
|
|
21313
|
+
log2.info(doctorNoDowngradeMessage(report.cliVersion, cache.configuredEntry, doctorInstalledVersion(cache)));
|
|
21314
|
+
}
|
|
21315
|
+
}
|
|
20997
21316
|
if (!report.binaryVersion) {
|
|
20998
21317
|
logUnmatchedBinaryCandidates(report.cliVersion);
|
|
20999
21318
|
}
|
|
@@ -21197,14 +21516,14 @@ function formatDoctorStorageStatus(h) {
|
|
|
21197
21516
|
let cacheWarning = "";
|
|
21198
21517
|
if (h.storageDir.cacheRoot) {
|
|
21199
21518
|
try {
|
|
21200
|
-
const parent = realpathSync8(
|
|
21519
|
+
const parent = realpathSync8(dirname13(h.storageDir.cacheRoot));
|
|
21201
21520
|
let durable = h.storageDir.path;
|
|
21202
|
-
while (!
|
|
21203
|
-
durable =
|
|
21521
|
+
while (!existsSync31(durable) && dirname13(durable) !== durable)
|
|
21522
|
+
durable = dirname13(durable);
|
|
21204
21523
|
let registered = false;
|
|
21205
|
-
const history =
|
|
21206
|
-
if (
|
|
21207
|
-
const saved = JSON.parse(
|
|
21524
|
+
const history = join34(h.storageDir.path, "retention/cache-parents.json");
|
|
21525
|
+
if (existsSync31(history)) {
|
|
21526
|
+
const saved = JSON.parse(readFileSync18(history, "utf8"));
|
|
21208
21527
|
registered = saved.parents?.some((entry) => entry.path === parent) === true;
|
|
21209
21528
|
}
|
|
21210
21529
|
if (!registered && statSync19(parent).dev === statSync19(durable).dev) {
|
|
@@ -21246,7 +21565,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
|
|
|
21246
21565
|
if (!adapter.isInstalled() || !adapter.hasPluginEntry())
|
|
21247
21566
|
continue;
|
|
21248
21567
|
storageDir = adapter.getStorageDir();
|
|
21249
|
-
if (
|
|
21568
|
+
if (existsSync31(storageDir))
|
|
21250
21569
|
continue;
|
|
21251
21570
|
mkdirSync8(storageDir, { recursive: true });
|
|
21252
21571
|
summary.created += 1;
|
|
@@ -21309,7 +21628,7 @@ async function maybeFixPlugin(adapter) {
|
|
|
21309
21628
|
return summary;
|
|
21310
21629
|
if (!adapter.hasPluginEntry() || adapterConfigNeedsUpdate(adapter)) {
|
|
21311
21630
|
log2.info(`${adapter.displayName}: attempting to register or update plugin config…`);
|
|
21312
|
-
const result = await adapter.ensurePluginEntry();
|
|
21631
|
+
const result = await adapter.ensurePluginEntry({ doctor: true });
|
|
21313
21632
|
if (result.ok) {
|
|
21314
21633
|
if (result.action === "added" || result.action === "updated")
|
|
21315
21634
|
summary.changed += 1;
|
|
@@ -21322,7 +21641,7 @@ async function maybeFixPlugin(adapter) {
|
|
|
21322
21641
|
if (adapter.ensureTuiPluginEntry && adapter.hasTuiPluginEntry && adapter.tuiPluginEntryApplies?.() !== false) {
|
|
21323
21642
|
const hasTuiEntry = adapter.hasTuiPluginEntry();
|
|
21324
21643
|
if (!hasTuiEntry || adapterConfigNeedsUpdate(adapter, true)) {
|
|
21325
|
-
const result = await adapter.ensureTuiPluginEntry();
|
|
21644
|
+
const result = await adapter.ensureTuiPluginEntry({ doctor: true });
|
|
21326
21645
|
if (result.ok && (result.action === "added" || result.action === "updated")) {
|
|
21327
21646
|
summary.changed += 1;
|
|
21328
21647
|
log2.success(`${adapter.displayName}: ${result.message}`);
|
|
@@ -21407,11 +21726,11 @@ function deriveIssueTitleFromBody(body) {
|
|
|
21407
21726
|
function writeIssueReviewFile(body) {
|
|
21408
21727
|
let reviewDir = null;
|
|
21409
21728
|
try {
|
|
21410
|
-
reviewDir = mkdtempSync2(
|
|
21729
|
+
reviewDir = mkdtempSync2(join34(tmpdir5(), "aft-issue-"));
|
|
21411
21730
|
if (process.platform !== "win32") {
|
|
21412
21731
|
chmodSync4(reviewDir, 448);
|
|
21413
21732
|
}
|
|
21414
|
-
const outPath =
|
|
21733
|
+
const outPath = join34(reviewDir, "issue.md");
|
|
21415
21734
|
writeFileSync5(outPath, `${body}
|
|
21416
21735
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
21417
21736
|
return { path: outPath, realPath: realpathSync8(outPath) };
|
|
@@ -21432,7 +21751,7 @@ function readReviewedIssueFile(reviewFile) {
|
|
|
21432
21751
|
log2.error(`Review file path changed before filing; refusing to read ${reviewFile.path}.`);
|
|
21433
21752
|
return null;
|
|
21434
21753
|
}
|
|
21435
|
-
return
|
|
21754
|
+
return readFileSync18(reviewFile.path, "utf8");
|
|
21436
21755
|
} catch (err) {
|
|
21437
21756
|
log2.error(`Failed to read reviewed issue report: ${err instanceof Error ? err.message : String(err)}`);
|
|
21438
21757
|
return null;
|
|
@@ -21477,14 +21796,14 @@ function collectIssueLog(path, selectedSession) {
|
|
|
21477
21796
|
};
|
|
21478
21797
|
}
|
|
21479
21798
|
function collectIssueEngineLog(path, selectedSession) {
|
|
21480
|
-
const directory =
|
|
21799
|
+
const directory = dirname13(path);
|
|
21481
21800
|
const files = [];
|
|
21482
21801
|
try {
|
|
21483
|
-
for (const name of
|
|
21802
|
+
for (const name of readdirSync14(directory)) {
|
|
21484
21803
|
if (!/^aft-\d+\.log(?:\.1)?$/.test(name))
|
|
21485
21804
|
continue;
|
|
21486
21805
|
try {
|
|
21487
|
-
const candidate =
|
|
21806
|
+
const candidate = join34(directory, name);
|
|
21488
21807
|
const stat = lstatSync5(candidate);
|
|
21489
21808
|
if (stat.isFile())
|
|
21490
21809
|
files.push({ path: candidate, modified: stat.mtimeMs });
|
|
@@ -21535,7 +21854,7 @@ ${logText || "<no log output>"}
|
|
|
21535
21854
|
errors
|
|
21536
21855
|
},
|
|
21537
21856
|
{
|
|
21538
|
-
section: `#### Engine logs (${
|
|
21857
|
+
section: `#### Engine logs (${dirname13(path)})
|
|
21539
21858
|
|
|
21540
21859
|
${engine.notice}
|
|
21541
21860
|
\`\`\`
|
|
@@ -21645,6 +21964,7 @@ var init_doctor = __esm(async () => {
|
|
|
21645
21964
|
init_jsonc();
|
|
21646
21965
|
init_lsp_cache();
|
|
21647
21966
|
init_onnx_fix();
|
|
21967
|
+
init_opencode_plugin_cache();
|
|
21648
21968
|
init_paths2();
|
|
21649
21969
|
init_prompts();
|
|
21650
21970
|
init_sanitize();
|
|
@@ -21677,24 +21997,24 @@ var init_doctor = __esm(async () => {
|
|
|
21677
21997
|
});
|
|
21678
21998
|
|
|
21679
21999
|
// src/commands/lsp.ts
|
|
21680
|
-
import { existsSync as
|
|
22000
|
+
import { existsSync as existsSync32, readdirSync as readdirSync15, statSync as statSync20 } from "node:fs";
|
|
21681
22001
|
import { createRequire as createRequire5 } from "node:module";
|
|
21682
|
-
import { dirname as
|
|
22002
|
+
import { dirname as dirname14, join as join35, resolve as resolve15 } from "node:path";
|
|
21683
22003
|
function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
|
|
21684
22004
|
const resolvedFile = resolve15(fallbackCwd, filePath);
|
|
21685
|
-
let dir =
|
|
22005
|
+
let dir = dirname14(resolvedFile);
|
|
21686
22006
|
try {
|
|
21687
|
-
if (
|
|
22007
|
+
if (existsSync32(resolvedFile) && statSync20(resolvedFile).isDirectory()) {
|
|
21688
22008
|
dir = resolvedFile;
|
|
21689
22009
|
}
|
|
21690
22010
|
} catch {
|
|
21691
|
-
dir =
|
|
22011
|
+
dir = dirname14(resolvedFile);
|
|
21692
22012
|
}
|
|
21693
22013
|
while (true) {
|
|
21694
|
-
if (PROJECT_ROOT_MARKERS.some((marker) =>
|
|
22014
|
+
if (PROJECT_ROOT_MARKERS.some((marker) => existsSync32(join35(dir, marker)))) {
|
|
21695
22015
|
return dir;
|
|
21696
22016
|
}
|
|
21697
|
-
const parent =
|
|
22017
|
+
const parent = dirname14(dir);
|
|
21698
22018
|
if (parent === dir)
|
|
21699
22019
|
return resolve15(fallbackCwd);
|
|
21700
22020
|
dir = parent;
|
|
@@ -21840,18 +22160,18 @@ function buildConfigureParams(adapter, projectRoot) {
|
|
|
21840
22160
|
function inferLspPathsExtra(_lsp) {
|
|
21841
22161
|
const paths = new Set;
|
|
21842
22162
|
for (const entry of childDirs(getAftLspPackagesDir())) {
|
|
21843
|
-
paths.add(
|
|
22163
|
+
paths.add(join35(entry, "node_modules", ".bin"));
|
|
21844
22164
|
}
|
|
21845
22165
|
for (const entry of childDirs(getAftLspBinariesDir())) {
|
|
21846
|
-
paths.add(
|
|
22166
|
+
paths.add(join35(entry, "bin"));
|
|
21847
22167
|
}
|
|
21848
22168
|
return [...paths];
|
|
21849
22169
|
}
|
|
21850
22170
|
function childDirs(path) {
|
|
21851
|
-
if (!
|
|
22171
|
+
if (!existsSync32(path))
|
|
21852
22172
|
return [];
|
|
21853
22173
|
try {
|
|
21854
|
-
return
|
|
22174
|
+
return readdirSync15(path).map((entry) => join35(path, entry)).filter((entry) => {
|
|
21855
22175
|
try {
|
|
21856
22176
|
return statSync20(entry).isDirectory();
|
|
21857
22177
|
} catch {
|
|
@@ -21895,7 +22215,7 @@ function typescriptPackageWarning(response) {
|
|
|
21895
22215
|
if (!typescriptServerSpawned || !response.project_root || diagnosticsCount > 0)
|
|
21896
22216
|
return null;
|
|
21897
22217
|
try {
|
|
21898
|
-
createRequire5(
|
|
22218
|
+
createRequire5(join35(response.project_root, "package.json")).resolve("typescript");
|
|
21899
22219
|
return null;
|
|
21900
22220
|
} catch {
|
|
21901
22221
|
return "typescript package not resolvable from project — server will produce no diagnostics";
|
|
@@ -21935,7 +22255,7 @@ var init_lsp = __esm(async () => {
|
|
|
21935
22255
|
});
|
|
21936
22256
|
|
|
21937
22257
|
// src/commands/doctor-filters.ts
|
|
21938
|
-
import { existsSync as
|
|
22258
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
21939
22259
|
import { relative as relative5, resolve as resolve16 } from "node:path";
|
|
21940
22260
|
function printDoctorFiltersHelp() {
|
|
21941
22261
|
console.log(`Usage: ${CLI} doctor filters [--show <name>] [trust|untrust]`);
|
|
@@ -21977,7 +22297,7 @@ async function runDoctorFilters(options) {
|
|
|
21977
22297
|
log2.error(list.message ?? list.code ?? "list_filters failed");
|
|
21978
22298
|
return 1;
|
|
21979
22299
|
}
|
|
21980
|
-
list.project_dir_exists = list.project_dir ?
|
|
22300
|
+
list.project_dir_exists = list.project_dir ? existsSync33(list.project_dir) : false;
|
|
21981
22301
|
if (mode.kind === "list") {
|
|
21982
22302
|
console.log(renderFilterList(list, projectRoot));
|
|
21983
22303
|
return 0;
|
|
@@ -22191,7 +22511,7 @@ function printHelp() {
|
|
|
22191
22511
|
console.log(" setup --answers <file> Save feature choices from an answers file");
|
|
22192
22512
|
console.log(" index Build one configured index snapshot (no scheduler)");
|
|
22193
22513
|
console.log(" backups purge Remove undo backups by --path and/or --session (dry run unless --yes)");
|
|
22194
|
-
console.log(" cache prune-legacy Delete
|
|
22514
|
+
console.log(" cache prune-legacy Delete the index folders AFT used before 0.64 (dry run unless --yes)");
|
|
22195
22515
|
console.log(" doctor Check and fix configuration issues");
|
|
22196
22516
|
console.log(" doctor --profile [seconds] Profile a running AFT daemon");
|
|
22197
22517
|
console.log(" doctor lsp <file> Inspect LSP setup for one file");
|