@cortexkit/aft-opencode 0.44.0 → 0.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +0 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/types.d.ts +0 -3
- package/dist/hooks/auto-update-checker/types.d.ts.map +1 -1
- package/dist/index.js +202 -86
- package/dist/lsp-github-table.d.ts +0 -8
- package/dist/lsp-github-table.d.ts.map +1 -1
- package/dist/notifications.d.ts +2 -9
- package/dist/notifications.d.ts.map +1 -1
- package/dist/tools/_shared.d.ts +0 -7
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tui.js +139 -19
- package/package.json +8 -8
|
@@ -20,14 +20,6 @@
|
|
|
20
20
|
*/
|
|
21
21
|
export type Platform = "darwin" | "linux" | "win32";
|
|
22
22
|
export type Arch = "x64" | "arm64";
|
|
23
|
-
/**
|
|
24
|
-
* Asset name template — receives platform/arch (already mapped to the
|
|
25
|
-
* project's naming convention) and the resolved version, returns the
|
|
26
|
-
* literal asset filename to look for in the release `assets[]`.
|
|
27
|
-
*
|
|
28
|
-
* Returns `null` when this platform/arch combo is unsupported.
|
|
29
|
-
*/
|
|
30
|
-
export type AssetTemplate = (platform: Platform, arch: Arch, version: string) => string | null;
|
|
31
23
|
export type ArchiveType = "tar.gz" | "tar.xz" | "zip";
|
|
32
24
|
export interface GithubServerSpec {
|
|
33
25
|
/** AFT server-kind id (matches `crates/aft/src/lsp/registry.rs::ServerKind::id_str`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lsp-github-table.d.ts","sourceRoot":"","sources":["../src/lsp-github-table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC;AAEnC
|
|
1
|
+
{"version":3,"file":"lsp-github-table.d.ts","sourceRoot":"","sources":["../src/lsp-github-table.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC;AAEnC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yFAAyF;IACzF,QAAQ,CAAC,YAAY,EAAE,CACrB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,KACZ;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,GAAG,IAAI,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3F;AA4HD,eAAO,MAAM,gBAAgB,EAAE,SAAS,gBAAgB,EAMvD,CAAC;AAEF,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE7E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAQ9E"}
|
package/dist/notifications.d.ts
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* Use cases:
|
|
9
9
|
* - Feature announcements (new version, new experimental features)
|
|
10
10
|
* - Warnings (ONNX Runtime not found, stale binary)
|
|
11
|
-
* - Status updates (semantic search ready, index built)
|
|
12
11
|
*
|
|
13
12
|
* Messages are identified by markers and cleaned up on subsequent startups
|
|
14
13
|
* when no longer relevant (Desktop only — TUI toasts are inherently transient).
|
|
@@ -30,8 +29,8 @@ type SdkMessage = {
|
|
|
30
29
|
export declare const SESSION_MESSAGES_LIMIT = 50;
|
|
31
30
|
/**
|
|
32
31
|
* @internal — exported only so tests can pin the bounded-call contract.
|
|
33
|
-
* Production callers go through `
|
|
34
|
-
*
|
|
32
|
+
* Production callers go through `cleanupWarnings`, which gates on a real
|
|
33
|
+
* `readDesktopState()` before reaching this helper.
|
|
35
34
|
*/
|
|
36
35
|
export declare function getSessionMessages(client: unknown, sessionId: string): Promise<SdkMessage[]>;
|
|
37
36
|
export interface NotificationOptions {
|
|
@@ -68,12 +67,6 @@ export interface ConfigureWarningOptions {
|
|
|
68
67
|
* TUI: toast with warning variant (inherently transient).
|
|
69
68
|
*/
|
|
70
69
|
export declare function sendWarning(opts: NotificationOptions, message: string): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
* Send a transient status notification.
|
|
73
|
-
* Desktop: ignored message when sessionId is explicit, auto-deletes after 3 seconds.
|
|
74
|
-
* TUI: toast with success variant, auto-dismissed by the TUI.
|
|
75
|
-
*/
|
|
76
|
-
export declare function sendStatus(opts: NotificationOptions, message: string): Promise<void>;
|
|
77
70
|
/**
|
|
78
71
|
* Send a feature announcement for a new version.
|
|
79
72
|
* Tracked via a version file in storageDir — only fires once per version across all sessions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EACL,KAAK,mBAAmB,EAGzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAwK7D,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAID,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAwBF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBvB;AAkHD,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EACA,yBAAyB,GACzB,uBAAuB,GACvB,oBAAoB,GACpB,qBAAqB,GACrB,oBAAoB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,yBAAyB,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe3F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAyLD,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,EAC7B,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9E"}
|
package/dist/tools/_shared.d.ts
CHANGED
|
@@ -137,11 +137,4 @@ export declare function callToolCall(ctx: PluginContext, runtime: ToolRuntime, n
|
|
|
137
137
|
* unrelated sibling requests.
|
|
138
138
|
*/
|
|
139
139
|
export declare function callBashBridge(ctx: PluginContext, runtime: ToolRuntime, command: string, params?: Record<string, unknown>, options?: BridgeRequestOptions): Promise<Record<string, unknown>>;
|
|
140
|
-
/**
|
|
141
|
-
* Eagerly warm the session-directory cache for a runtime. Safe to call from
|
|
142
|
-
* synchronous code — the lookup runs in the background and failures are
|
|
143
|
-
* logged. Useful in plugin lifecycle hooks (`chat.message`, etc.) where we
|
|
144
|
-
* want the cache filled before any tool call arrives.
|
|
145
|
-
*/
|
|
146
|
-
export declare function warmSessionDirectoryFromRuntime(ctx: PluginContext, runtime: ToolRuntime): void;
|
|
147
140
|
//# sourceMappingURL=_shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,GACR,CAAC;AAOhD,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAIhD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACZ,+BAA+B,EAC/B,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAW3D;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;2BAE2B;AAC3B,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,mBAAmB,CAMvF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgClC;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAyBzB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMlC"}
|
package/dist/tui.js
CHANGED
|
@@ -7790,10 +7790,10 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7790
7790
|
// src/tui/index.tsx
|
|
7791
7791
|
import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
|
|
7792
7792
|
// package.json
|
|
7793
|
-
var version = "0.
|
|
7793
|
+
var version = "0.45.1";
|
|
7794
7794
|
|
|
7795
7795
|
// src/shared/rpc-client.ts
|
|
7796
|
-
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
7796
|
+
import { existsSync, readdirSync, readFileSync as readFileSync2, unlinkSync } from "node:fs";
|
|
7797
7797
|
import { join as join3 } from "node:path";
|
|
7798
7798
|
|
|
7799
7799
|
// src/shared/rpc-utils.ts
|
|
@@ -7856,6 +7856,8 @@ function error(message, meta) {
|
|
|
7856
7856
|
}
|
|
7857
7857
|
// ../aft-bridge/dist/bridge.js
|
|
7858
7858
|
import { spawn } from "node:child_process";
|
|
7859
|
+
import { createHash } from "node:crypto";
|
|
7860
|
+
import { readFileSync } from "node:fs";
|
|
7859
7861
|
import { homedir } from "node:os";
|
|
7860
7862
|
import { join } from "node:path";
|
|
7861
7863
|
import { StringDecoder } from "node:string_decoder";
|
|
@@ -7912,6 +7914,22 @@ function bashTaskIdFrom(response) {
|
|
|
7912
7914
|
return camelCase;
|
|
7913
7915
|
return;
|
|
7914
7916
|
}
|
|
7917
|
+
function hashBinaryOnDisk(binaryPath) {
|
|
7918
|
+
try {
|
|
7919
|
+
return createHash("sha256").update(readFileSync(binaryPath)).digest("hex");
|
|
7920
|
+
} catch {
|
|
7921
|
+
return null;
|
|
7922
|
+
}
|
|
7923
|
+
}
|
|
7924
|
+
var binaryFingerprintReader = hashBinaryOnDisk;
|
|
7925
|
+
function readBinaryFingerprint(binaryPath) {
|
|
7926
|
+
try {
|
|
7927
|
+
const fingerprint = binaryFingerprintReader(binaryPath);
|
|
7928
|
+
return typeof fingerprint === "string" && fingerprint.length > 0 ? fingerprint : null;
|
|
7929
|
+
} catch {
|
|
7930
|
+
return null;
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7915
7933
|
function tagStderrLine(line) {
|
|
7916
7934
|
return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
|
|
7917
7935
|
}
|
|
@@ -8003,6 +8021,9 @@ class BinaryBridge {
|
|
|
8003
8021
|
binaryPath;
|
|
8004
8022
|
cwd;
|
|
8005
8023
|
process = null;
|
|
8024
|
+
spawnedBinaryFingerprint = null;
|
|
8025
|
+
lastBinaryFingerprintCheckAt = 0;
|
|
8026
|
+
_retiringDueToBinaryChange = false;
|
|
8006
8027
|
pending = new Map;
|
|
8007
8028
|
outstandingBackgroundTaskIds = new Set;
|
|
8008
8029
|
nextId = 1;
|
|
@@ -8122,6 +8143,24 @@ class BinaryBridge {
|
|
|
8122
8143
|
hasOutstandingBackgroundTasks() {
|
|
8123
8144
|
return this.outstandingBackgroundTaskIds.size > 0;
|
|
8124
8145
|
}
|
|
8146
|
+
maybeScheduleRespawnForUpdatedBinary(checkIntervalMs, now = Date.now()) {
|
|
8147
|
+
if (this._shuttingDown || this._retiringDueToBinaryChange || !this.isAlive())
|
|
8148
|
+
return false;
|
|
8149
|
+
if (this.pending.size > 0 || this.outstandingBackgroundTaskIds.size > 0)
|
|
8150
|
+
return false;
|
|
8151
|
+
if (now - this.lastBinaryFingerprintCheckAt < checkIntervalMs)
|
|
8152
|
+
return false;
|
|
8153
|
+
this.lastBinaryFingerprintCheckAt = now;
|
|
8154
|
+
const spawnedFingerprint = this.spawnedBinaryFingerprint;
|
|
8155
|
+
if (!spawnedFingerprint)
|
|
8156
|
+
return false;
|
|
8157
|
+
const currentFingerprint = readBinaryFingerprint(this.binaryPath);
|
|
8158
|
+
if (!currentFingerprint || currentFingerprint === spawnedFingerprint)
|
|
8159
|
+
return false;
|
|
8160
|
+
this._retiringDueToBinaryChange = true;
|
|
8161
|
+
this.logVia(`Binary contents changed on disk for ${this.binaryPath}; retiring this bridge so the next tool call respawns onto the updated binary.`);
|
|
8162
|
+
return true;
|
|
8163
|
+
}
|
|
8125
8164
|
getCwd() {
|
|
8126
8165
|
return this.cwd;
|
|
8127
8166
|
}
|
|
@@ -8154,6 +8193,9 @@ class BinaryBridge {
|
|
|
8154
8193
|
}
|
|
8155
8194
|
async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
|
|
8156
8195
|
try {
|
|
8196
|
+
if (this._retiringDueToBinaryChange) {
|
|
8197
|
+
throw new Error(`${this.errorPrefix} Bridge is retiring after the on-disk binary changed; retry to respawn on the updated binary`);
|
|
8198
|
+
}
|
|
8157
8199
|
if (this._shuttingDown) {
|
|
8158
8200
|
throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
|
|
8159
8201
|
}
|
|
@@ -8352,6 +8394,7 @@ class BinaryBridge {
|
|
|
8352
8394
|
}
|
|
8353
8395
|
async shutdown() {
|
|
8354
8396
|
this._shuttingDown = true;
|
|
8397
|
+
this.spawnedBinaryFingerprint = null;
|
|
8355
8398
|
this.clearRestartResetTimer();
|
|
8356
8399
|
this.configureWarningClients.clear();
|
|
8357
8400
|
this.rejectAllPending(new Error(`${this.errorPrefix} Bridge shutting down`));
|
|
@@ -8405,6 +8448,9 @@ class BinaryBridge {
|
|
|
8405
8448
|
async replaceCurrentBinary(newBinaryPath) {
|
|
8406
8449
|
this.binaryPath = newBinaryPath;
|
|
8407
8450
|
this.configured = false;
|
|
8451
|
+
this.spawnedBinaryFingerprint = null;
|
|
8452
|
+
this.lastBinaryFingerprintCheckAt = 0;
|
|
8453
|
+
this._retiringDueToBinaryChange = false;
|
|
8408
8454
|
this.clearRestartResetTimer();
|
|
8409
8455
|
this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
|
|
8410
8456
|
if (!this.process)
|
|
@@ -8430,6 +8476,7 @@ class BinaryBridge {
|
|
|
8430
8476
|
this.spawnProcess(triggeringSessionId);
|
|
8431
8477
|
}
|
|
8432
8478
|
spawnProcess(triggeringSessionId) {
|
|
8479
|
+
this._retiringDueToBinaryChange = false;
|
|
8433
8480
|
this.lastStatusBar = undefined;
|
|
8434
8481
|
if (triggeringSessionId) {
|
|
8435
8482
|
this.sessionLogVia(triggeringSessionId, `Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
|
|
@@ -8520,6 +8567,8 @@ class BinaryBridge {
|
|
|
8520
8567
|
this.handleCrash();
|
|
8521
8568
|
});
|
|
8522
8569
|
this.process = child;
|
|
8570
|
+
this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
|
|
8571
|
+
this.lastBinaryFingerprintCheckAt = Date.now();
|
|
8523
8572
|
this.stdoutBuffer = "";
|
|
8524
8573
|
this.stdoutReadOffset = 0;
|
|
8525
8574
|
this.stderrBuffer = "";
|
|
@@ -8698,6 +8747,7 @@ class BinaryBridge {
|
|
|
8698
8747
|
}
|
|
8699
8748
|
handleTimeout(triggeringSessionId) {
|
|
8700
8749
|
this.consecutiveRequestTimeouts = 0;
|
|
8750
|
+
this.spawnedBinaryFingerprint = null;
|
|
8701
8751
|
this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
|
|
8702
8752
|
this.outstandingBackgroundTaskIds.clear();
|
|
8703
8753
|
if (this.process) {
|
|
@@ -8724,6 +8774,7 @@ class BinaryBridge {
|
|
|
8724
8774
|
handleCrash(cause) {
|
|
8725
8775
|
const proc = this.process;
|
|
8726
8776
|
this.process = null;
|
|
8777
|
+
this.spawnedBinaryFingerprint = null;
|
|
8727
8778
|
if (proc && proc.exitCode === null && !proc.killed) {
|
|
8728
8779
|
proc.kill("SIGKILL");
|
|
8729
8780
|
}
|
|
@@ -8735,6 +8786,10 @@ class BinaryBridge {
|
|
|
8735
8786
|
this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
|
|
8736
8787
|
}
|
|
8737
8788
|
this.rejectAllPending(new Error(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`));
|
|
8789
|
+
if (this._retiringDueToBinaryChange) {
|
|
8790
|
+
this.logVia("Binary exited while retiring after an on-disk update; skipping auto-restart");
|
|
8791
|
+
return;
|
|
8792
|
+
}
|
|
8738
8793
|
if (this._restartCount < this.maxRestarts) {
|
|
8739
8794
|
const delay = 100 * 2 ** this._restartCount;
|
|
8740
8795
|
this._restartCount++;
|
|
@@ -8819,7 +8874,7 @@ var ORT_PLATFORM_MAP = {
|
|
|
8819
8874
|
}
|
|
8820
8875
|
};
|
|
8821
8876
|
// ../aft-bridge/dist/project-identity.js
|
|
8822
|
-
import { createHash } from "node:crypto";
|
|
8877
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
8823
8878
|
import { realpathSync } from "node:fs";
|
|
8824
8879
|
import { resolve } from "node:path";
|
|
8825
8880
|
function canonicalizeProjectRoot(dir) {
|
|
@@ -8850,7 +8905,7 @@ function normalizeWindowsRoot(p) {
|
|
|
8850
8905
|
return s;
|
|
8851
8906
|
}
|
|
8852
8907
|
function projectRootKeyHash(dir) {
|
|
8853
|
-
return
|
|
8908
|
+
return createHash2("sha256").update(canonicalizeProjectRoot(dir)).digest("hex").slice(0, 16);
|
|
8854
8909
|
}
|
|
8855
8910
|
|
|
8856
8911
|
// ../aft-bridge/dist/pool.js
|
|
@@ -8934,6 +8989,11 @@ class BridgePool {
|
|
|
8934
8989
|
for (const [dir, entry] of this.bridges) {
|
|
8935
8990
|
if (entry.bridge.hasPendingRequests() || entry.bridge.hasOutstandingBackgroundTasks())
|
|
8936
8991
|
continue;
|
|
8992
|
+
if (entry.bridge.maybeScheduleRespawnForUpdatedBinary(CLEANUP_INTERVAL_MS, now)) {
|
|
8993
|
+
this.staleBridges.add(entry.bridge);
|
|
8994
|
+
this.bridges.delete(dir);
|
|
8995
|
+
continue;
|
|
8996
|
+
}
|
|
8937
8997
|
if (now - entry.lastUsed > this.idleTimeoutMs) {
|
|
8938
8998
|
entry.bridge.shutdown().catch((err) => this.error("cleanup shutdown failed:", err));
|
|
8939
8999
|
this.bridges.delete(dir);
|
|
@@ -9030,10 +9090,11 @@ class BridgePool {
|
|
|
9030
9090
|
function normalizeKey(projectRoot) {
|
|
9031
9091
|
return canonicalizeProjectRoot(projectRoot);
|
|
9032
9092
|
}
|
|
9033
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9093
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
|
|
9034
9094
|
import { promises as fs2 } from "node:fs";
|
|
9095
|
+
import { debuglog } from "node:util";
|
|
9035
9096
|
|
|
9036
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9097
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/auth.ts
|
|
9037
9098
|
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
9038
9099
|
var NONCE_LEN = 32;
|
|
9039
9100
|
var MAX_AUTH_MESSAGE_LEN = 4096;
|
|
@@ -9097,7 +9158,7 @@ async function authenticateClient(sock, conn, deadlineMs) {
|
|
|
9097
9158
|
await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
|
|
9098
9159
|
}
|
|
9099
9160
|
|
|
9100
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9161
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/connection-file.ts
|
|
9101
9162
|
import { promises as fs } from "node:fs";
|
|
9102
9163
|
var SCHEMA_VERSION = 1;
|
|
9103
9164
|
var MIN_KEY_LEN = 32;
|
|
@@ -9166,7 +9227,7 @@ async function readConnectionFile(path) {
|
|
|
9166
9227
|
return info;
|
|
9167
9228
|
}
|
|
9168
9229
|
|
|
9169
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9230
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/envelope.ts
|
|
9170
9231
|
var PROTOCOL_VERSION = 1;
|
|
9171
9232
|
var HEADER_LEN = 17;
|
|
9172
9233
|
var FROZEN_PREFIX_LEN = 5;
|
|
@@ -9273,7 +9334,7 @@ function encodeFrame(frame) {
|
|
|
9273
9334
|
return out;
|
|
9274
9335
|
}
|
|
9275
9336
|
|
|
9276
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9337
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/socket.ts
|
|
9277
9338
|
import net from "node:net";
|
|
9278
9339
|
|
|
9279
9340
|
class SocketClosedError extends Error {
|
|
@@ -9304,6 +9365,9 @@ class SubcSocket {
|
|
|
9304
9365
|
buffered = 0;
|
|
9305
9366
|
waiter = null;
|
|
9306
9367
|
closedErr = null;
|
|
9368
|
+
bufferedBytes() {
|
|
9369
|
+
return this.buffered;
|
|
9370
|
+
}
|
|
9307
9371
|
constructor(sock) {
|
|
9308
9372
|
this.sock = sock;
|
|
9309
9373
|
sock.on("data", (chunk) => {
|
|
@@ -9462,9 +9526,14 @@ class SubcSocket {
|
|
|
9462
9526
|
}
|
|
9463
9527
|
}
|
|
9464
9528
|
|
|
9465
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
9529
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
|
|
9530
|
+
var debug = debuglog("subc-client");
|
|
9466
9531
|
var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
9467
9532
|
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
9533
|
+
var TIMEOUT_ARBITRATION_GRACE_MS = 50;
|
|
9534
|
+
var REQUEST_DEADLINE_MARKER = "request_deadline";
|
|
9535
|
+
var DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed";
|
|
9536
|
+
var ROUTE_OPEN_RETRY_DEADLINE_MS = 1e4;
|
|
9468
9537
|
var BODY_READ_TIMEOUT_MS = 30000;
|
|
9469
9538
|
var EMPTY_BODY = new Uint8Array(0);
|
|
9470
9539
|
var DEFAULT_MANAGED_TARGET_KIND = "management_surface";
|
|
@@ -9508,6 +9577,7 @@ class SubcClient {
|
|
|
9508
9577
|
closeStarted = false;
|
|
9509
9578
|
reconnecting = null;
|
|
9510
9579
|
generation = 1;
|
|
9580
|
+
readerActive = false;
|
|
9511
9581
|
constructor(sock, currentConn, opts) {
|
|
9512
9582
|
this.sock = sock;
|
|
9513
9583
|
this.currentConn = currentConn;
|
|
@@ -9566,7 +9636,7 @@ class SubcClient {
|
|
|
9566
9636
|
}
|
|
9567
9637
|
continue;
|
|
9568
9638
|
}
|
|
9569
|
-
if (err.kind === "outcome_unknown") {
|
|
9639
|
+
if (err.kind === "outcome_unknown" && err.code !== DEADLINE_NO_DROP_CODE) {
|
|
9570
9640
|
this.scheduleReconnectAfterDrop(err);
|
|
9571
9641
|
}
|
|
9572
9642
|
throw err;
|
|
@@ -9689,7 +9759,7 @@ class SubcClient {
|
|
|
9689
9759
|
timer: null
|
|
9690
9760
|
};
|
|
9691
9761
|
pending.timer = setTimeout(() => {
|
|
9692
|
-
this.
|
|
9762
|
+
this.arbitrateTimeout(key, pending, channel, corr, ms);
|
|
9693
9763
|
}, ms);
|
|
9694
9764
|
this.pending.set(key, pending);
|
|
9695
9765
|
this.sock.write(encodeFrame(frame), Date.now() + ms).catch((err) => {
|
|
@@ -9699,6 +9769,23 @@ class SubcClient {
|
|
|
9699
9769
|
});
|
|
9700
9770
|
});
|
|
9701
9771
|
}
|
|
9772
|
+
arbitrateTimeout(key, pending, channel, corr, ms) {
|
|
9773
|
+
const settleAsTimeout = () => {
|
|
9774
|
+
this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms), REQUEST_DEADLINE_MARKER));
|
|
9775
|
+
};
|
|
9776
|
+
const graceDeadline = Date.now() + this.opts.timeoutArbitrationGraceMs;
|
|
9777
|
+
const arbitrate = () => {
|
|
9778
|
+
if (this.pending.get(key) !== pending)
|
|
9779
|
+
return;
|
|
9780
|
+
const readerDraining = this.readerActive || this.sock.bufferedBytes() > 0;
|
|
9781
|
+
if (readerDraining && Date.now() < graceDeadline) {
|
|
9782
|
+
setImmediate(arbitrate);
|
|
9783
|
+
return;
|
|
9784
|
+
}
|
|
9785
|
+
settleAsTimeout();
|
|
9786
|
+
};
|
|
9787
|
+
setImmediate(arbitrate);
|
|
9788
|
+
}
|
|
9702
9789
|
async managedRequest(routeChannel, body, opts) {
|
|
9703
9790
|
const bytes = body instanceof Uint8Array ? body : this.encode(body);
|
|
9704
9791
|
const priority = opts.priority ?? 1 /* Interactive */;
|
|
@@ -9723,6 +9810,9 @@ class SubcClient {
|
|
|
9723
9810
|
if (!handedToSocket) {
|
|
9724
9811
|
return this.notSentCallError("request bytes were not queued to the subc socket", err);
|
|
9725
9812
|
}
|
|
9813
|
+
if (err instanceof SubcError && err.code === REQUEST_DEADLINE_MARKER) {
|
|
9814
|
+
return new SubcCallError("outcome_unknown", `managed call deadline exceeded after request bytes were queued to the local socket; no terminal response was observed; outcome unknown${causeMessage(err)}`, DEADLINE_NO_DROP_CODE, err);
|
|
9815
|
+
}
|
|
9726
9816
|
return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", err);
|
|
9727
9817
|
};
|
|
9728
9818
|
return new Promise((resolve2, reject) => {
|
|
@@ -9736,7 +9826,7 @@ class SubcClient {
|
|
|
9736
9826
|
classifyFailure
|
|
9737
9827
|
};
|
|
9738
9828
|
pending.timer = setTimeout(() => {
|
|
9739
|
-
this.
|
|
9829
|
+
this.arbitrateTimeout(key, pending, channel, corr, ms);
|
|
9740
9830
|
}, ms);
|
|
9741
9831
|
this.pending.set(key, pending);
|
|
9742
9832
|
const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
|
|
@@ -9781,6 +9871,9 @@ class SubcClient {
|
|
|
9781
9871
|
return cached.opening;
|
|
9782
9872
|
}
|
|
9783
9873
|
async openCachedRoute(cached) {
|
|
9874
|
+
const routeRetryDeadline = Date.now() + ROUTE_OPEN_RETRY_DEADLINE_MS;
|
|
9875
|
+
let routeRetryDelay = this.opts.reconnectBackoff.baseMs;
|
|
9876
|
+
let routeRetryAttempt = 0;
|
|
9784
9877
|
for (;; ) {
|
|
9785
9878
|
if (cached.closed)
|
|
9786
9879
|
throw this.routeClosedDuringOpen();
|
|
@@ -9814,6 +9907,15 @@ class SubcClient {
|
|
|
9814
9907
|
}
|
|
9815
9908
|
continue;
|
|
9816
9909
|
}
|
|
9910
|
+
if (!this.closeStarted && err instanceof SubcError && isRetryableRouteOpenCode(err.code)) {
|
|
9911
|
+
routeRetryAttempt += 1;
|
|
9912
|
+
if (routeRetryAttempt < this.opts.reconnectBackoff.maxAttempts && Date.now() < routeRetryDeadline) {
|
|
9913
|
+
await this.opts.sleep(routeRetryDelay);
|
|
9914
|
+
routeRetryDelay = Math.min(routeRetryDelay * 2, this.opts.reconnectBackoff.capMs);
|
|
9915
|
+
continue;
|
|
9916
|
+
}
|
|
9917
|
+
throw this.notSentCallError(`route.open failed for module ${cached.moduleId}: ${err.code} (retry budget exhausted)`, err);
|
|
9918
|
+
}
|
|
9817
9919
|
throw this.terminalCallError(`route.open failed for module ${cached.moduleId}`, err);
|
|
9818
9920
|
}
|
|
9819
9921
|
}
|
|
@@ -9907,9 +10009,16 @@ class SubcClient {
|
|
|
9907
10009
|
try {
|
|
9908
10010
|
for (;; ) {
|
|
9909
10011
|
const headerBytes = await sock.readExact(HEADER_LEN, Number.POSITIVE_INFINITY);
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
10012
|
+
this.readerActive = true;
|
|
10013
|
+
try {
|
|
10014
|
+
const header = decodeHeader(headerBytes);
|
|
10015
|
+
const body = header.len === 0 ? new Uint8Array(0) : await sock.readExact(header.len, Date.now() + BODY_READ_TIMEOUT_MS);
|
|
10016
|
+
if (this.sock === sock && this.generation === generation) {
|
|
10017
|
+
this.dispatch({ header, body });
|
|
10018
|
+
}
|
|
10019
|
+
} finally {
|
|
10020
|
+
this.readerActive = false;
|
|
10021
|
+
}
|
|
9913
10022
|
}
|
|
9914
10023
|
} catch (err) {
|
|
9915
10024
|
if (this.sock === sock && this.generation === generation) {
|
|
@@ -9941,13 +10050,20 @@ class SubcClient {
|
|
|
9941
10050
|
this.failChannel(frame.header.channel, new SubcError("route closed by subc (GOODBYE)"));
|
|
9942
10051
|
return;
|
|
9943
10052
|
}
|
|
10053
|
+
if (frame.header.ty === 1 /* Response */ || frame.header.ty === 5 /* Error */ || frame.header.ty === 4 /* StreamEnd */) {
|
|
10054
|
+
debug("dropped terminal frame with no waiter: type=%d channel=%d corr=%s port=%s", frame.header.ty, frame.header.channel, frame.header.corr, this.sock.localPort() ?? "?");
|
|
10055
|
+
return;
|
|
10056
|
+
}
|
|
9944
10057
|
}
|
|
9945
10058
|
settle(key, pending, run) {
|
|
10059
|
+
if (this.pending.get(key) !== pending)
|
|
10060
|
+
return false;
|
|
9946
10061
|
this.pending.delete(key);
|
|
9947
10062
|
if (pending.timer)
|
|
9948
10063
|
clearTimeout(pending.timer);
|
|
9949
10064
|
run();
|
|
9950
10065
|
pending.onSettle?.();
|
|
10066
|
+
return true;
|
|
9951
10067
|
}
|
|
9952
10068
|
rejectPending(key, pending, err) {
|
|
9953
10069
|
this.settle(key, pending, () => pending.reject(pending.classifyFailure?.(err) ?? err));
|
|
@@ -10011,6 +10127,9 @@ function isConsumerReconnectTransient(err) {
|
|
|
10011
10127
|
const code = errorCode(err);
|
|
10012
10128
|
return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
|
|
10013
10129
|
}
|
|
10130
|
+
function isRetryableRouteOpenCode(code) {
|
|
10131
|
+
return code === "unknown_module" || code === "module_reloading" || code === "target_unavailable" || code === "module_timeout";
|
|
10132
|
+
}
|
|
10014
10133
|
async function connectionFileExists(path) {
|
|
10015
10134
|
try {
|
|
10016
10135
|
await fs2.access(path);
|
|
@@ -10026,7 +10145,8 @@ function normalizeConnectOptions(opts) {
|
|
|
10026
10145
|
identity: opts.identity,
|
|
10027
10146
|
targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
|
|
10028
10147
|
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
10029
|
-
sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)))
|
|
10148
|
+
sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms))),
|
|
10149
|
+
timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
|
|
10030
10150
|
};
|
|
10031
10151
|
}
|
|
10032
10152
|
function routeCacheKey(target, identity, consumerIdentity) {
|
|
@@ -10055,7 +10175,7 @@ function causeMessage(cause) {
|
|
|
10055
10175
|
return "";
|
|
10056
10176
|
return `: ${cause instanceof Error ? cause.message : String(cause)}`;
|
|
10057
10177
|
}
|
|
10058
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.
|
|
10178
|
+
// ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/provider.ts
|
|
10059
10179
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
10060
10180
|
var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4;
|
|
10061
10181
|
var BODY_READ_TIMEOUT_MS2 = 30000;
|
|
@@ -11273,7 +11393,7 @@ class AftRpcClient {
|
|
|
11273
11393
|
}
|
|
11274
11394
|
parsePortFile(filePath) {
|
|
11275
11395
|
try {
|
|
11276
|
-
const content =
|
|
11396
|
+
const content = readFileSync2(filePath, "utf-8");
|
|
11277
11397
|
return parseRpcPortRecord(content);
|
|
11278
11398
|
} catch {
|
|
11279
11399
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@clack/prompts": "^1.6.0",
|
|
34
|
-
"@cortexkit/aft-bridge": "0.
|
|
34
|
+
"@cortexkit/aft-bridge": "0.45.1",
|
|
35
35
|
"@opentui/core": "^0.4.2",
|
|
36
36
|
"@opentui/solid": "^0.4.2",
|
|
37
37
|
"comment-json": "^4.6.2",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"zod": "^4.4.3"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
44
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
45
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
46
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
47
|
-
"@cortexkit/aft-win32-arm64": "0.
|
|
48
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
43
|
+
"@cortexkit/aft-darwin-arm64": "0.45.1",
|
|
44
|
+
"@cortexkit/aft-darwin-x64": "0.45.1",
|
|
45
|
+
"@cortexkit/aft-linux-arm64": "0.45.1",
|
|
46
|
+
"@cortexkit/aft-linux-x64": "0.45.1",
|
|
47
|
+
"@cortexkit/aft-win32-arm64": "0.45.1",
|
|
48
|
+
"@cortexkit/aft-win32-x64": "0.45.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@opencode-ai/plugin": "^1.17.11",
|