@cortexkit/aft-opencode 0.35.2 → 0.35.4
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/bg-notifications.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -126
- package/dist/lsp-auto-install.d.ts +30 -0
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/shared/status.d.ts +23 -0
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tools/_shared.d.ts +8 -0
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash_watch.d.ts.map +1 -1
- package/dist/tui.js +116 -1
- package/package.json +8 -8
- package/src/shared/status.ts +72 -0
- package/src/tui/index.tsx +51 -0
- package/src/tui/sidebar.tsx +98 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA4MlD;;;;;;;;;;;;;;;;;GAiBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AA80B5E,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11867,6 +11867,9 @@ class BinaryBridge {
|
|
|
11867
11867
|
hasPendingRequests() {
|
|
11868
11868
|
return this.pending.size > 0;
|
|
11869
11869
|
}
|
|
11870
|
+
getCwd() {
|
|
11871
|
+
return this.cwd;
|
|
11872
|
+
}
|
|
11870
11873
|
getCachedStatus() {
|
|
11871
11874
|
return this.cachedStatus;
|
|
11872
11875
|
}
|
|
@@ -12064,7 +12067,6 @@ class BinaryBridge {
|
|
|
12064
12067
|
if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot))
|
|
12065
12068
|
return;
|
|
12066
12069
|
this.cachedStatus = snapshot;
|
|
12067
|
-
this.logVia("Received status_changed push frame; cached AFT status snapshot");
|
|
12068
12070
|
for (const listener of this.statusListeners) {
|
|
12069
12071
|
this.deliverStatusSnapshot(listener, this.cachedStatus);
|
|
12070
12072
|
}
|
|
@@ -12211,6 +12213,7 @@ class BinaryBridge {
|
|
|
12211
12213
|
const remaining = stdoutDecoder.end();
|
|
12212
12214
|
if (remaining)
|
|
12213
12215
|
this.onStdoutData(remaining);
|
|
12216
|
+
this.flushStdoutBuffer();
|
|
12214
12217
|
});
|
|
12215
12218
|
const stderrDecoder = new StringDecoder("utf8");
|
|
12216
12219
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -12233,6 +12236,7 @@ class BinaryBridge {
|
|
|
12233
12236
|
return;
|
|
12234
12237
|
if (this._shuttingDown)
|
|
12235
12238
|
return;
|
|
12239
|
+
this.flushStdoutBuffer();
|
|
12236
12240
|
this.logVia(`Process exited: code=${code}, signal=${signal}`);
|
|
12237
12241
|
if (signal === "SIGTERM" || signal === "SIGKILL" || signal === "SIGHUP" || signal === "SIGINT") {
|
|
12238
12242
|
this.process = null;
|
|
@@ -12301,71 +12305,81 @@ class BinaryBridge {
|
|
|
12301
12305
|
this.stdoutBuffer = this.stdoutBuffer.slice(newlineIdx + 1);
|
|
12302
12306
|
if (!line)
|
|
12303
12307
|
continue;
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
this.onBashCompletion?.(response, this);
|
|
12332
|
-
continue;
|
|
12333
|
-
}
|
|
12334
|
-
if (response.type === "bash_long_running") {
|
|
12335
|
-
this.onBashLongRunning?.(response, this);
|
|
12336
|
-
continue;
|
|
12337
|
-
}
|
|
12338
|
-
if (response.type === "bash_pattern_match") {
|
|
12339
|
-
this.onBashPatternMatch?.(response, this);
|
|
12340
|
-
continue;
|
|
12341
|
-
}
|
|
12342
|
-
if (response.type === "configure_warnings") {
|
|
12343
|
-
this.handleConfigureWarningsFrame(response).catch((err) => {
|
|
12344
|
-
this.warnVia(`configure warning delivery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
12345
|
-
});
|
|
12346
|
-
continue;
|
|
12347
|
-
}
|
|
12348
|
-
if (response.type === "status_changed") {
|
|
12349
|
-
this.handleStatusChangedFrame(response);
|
|
12350
|
-
continue;
|
|
12351
|
-
}
|
|
12352
|
-
const id = response.id;
|
|
12353
|
-
if (id && this.pending.has(id)) {
|
|
12354
|
-
const entry = this.pending.get(id);
|
|
12355
|
-
if (!entry)
|
|
12356
|
-
continue;
|
|
12357
|
-
this.pending.delete(id);
|
|
12308
|
+
this.processStdoutLine(line);
|
|
12309
|
+
}
|
|
12310
|
+
}
|
|
12311
|
+
flushStdoutBuffer() {
|
|
12312
|
+
const line = this.stdoutBuffer.trim();
|
|
12313
|
+
this.stdoutBuffer = "";
|
|
12314
|
+
if (!line)
|
|
12315
|
+
return;
|
|
12316
|
+
this.processStdoutLine(line);
|
|
12317
|
+
}
|
|
12318
|
+
processStdoutLine(line) {
|
|
12319
|
+
try {
|
|
12320
|
+
const response = JSON.parse(line);
|
|
12321
|
+
this.lastChildActivityAt = Date.now();
|
|
12322
|
+
if (response.type === "progress") {
|
|
12323
|
+
const requestId = response.request_id;
|
|
12324
|
+
const entry = requestId ? this.pending.get(requestId) : undefined;
|
|
12325
|
+
const kind = response.kind === "stderr" ? "stderr" : "stdout";
|
|
12326
|
+
const text = typeof response.chunk === "string" ? response.chunk : "";
|
|
12327
|
+
entry?.onProgress?.({ kind, text });
|
|
12328
|
+
return;
|
|
12329
|
+
}
|
|
12330
|
+
if (response.type === "permission_ask") {
|
|
12331
|
+
const requestId = response.request_id;
|
|
12332
|
+
const entry = requestId ? this.pending.get(requestId) : undefined;
|
|
12333
|
+
if (requestId && entry) {
|
|
12334
|
+
this.pending.delete(requestId);
|
|
12358
12335
|
clearTimeout(entry.timer);
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12336
|
+
entry.resolve({
|
|
12337
|
+
success: false,
|
|
12338
|
+
code: "permission_required",
|
|
12339
|
+
message: "bash command requires permission",
|
|
12340
|
+
asks: response.asks
|
|
12341
|
+
});
|
|
12365
12342
|
}
|
|
12366
|
-
|
|
12367
|
-
|
|
12343
|
+
return;
|
|
12344
|
+
}
|
|
12345
|
+
if (response.type === "bash_completed") {
|
|
12346
|
+
this.onBashCompletion?.(response, this);
|
|
12347
|
+
return;
|
|
12348
|
+
}
|
|
12349
|
+
if (response.type === "bash_long_running") {
|
|
12350
|
+
this.onBashLongRunning?.(response, this);
|
|
12351
|
+
return;
|
|
12352
|
+
}
|
|
12353
|
+
if (response.type === "bash_pattern_match") {
|
|
12354
|
+
this.onBashPatternMatch?.(response, this);
|
|
12355
|
+
return;
|
|
12356
|
+
}
|
|
12357
|
+
if (response.type === "configure_warnings") {
|
|
12358
|
+
this.handleConfigureWarningsFrame(response).catch((err) => {
|
|
12359
|
+
this.warnVia(`configure warning delivery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
12360
|
+
});
|
|
12361
|
+
return;
|
|
12362
|
+
}
|
|
12363
|
+
if (response.type === "status_changed") {
|
|
12364
|
+
this.handleStatusChangedFrame(response);
|
|
12365
|
+
return;
|
|
12366
|
+
}
|
|
12367
|
+
const id = response.id;
|
|
12368
|
+
if (id && this.pending.has(id)) {
|
|
12369
|
+
const entry = this.pending.get(id);
|
|
12370
|
+
if (!entry)
|
|
12371
|
+
return;
|
|
12372
|
+
this.pending.delete(id);
|
|
12373
|
+
clearTimeout(entry.timer);
|
|
12374
|
+
this.consecutiveRequestTimeouts = 0;
|
|
12375
|
+
this.scheduleRestartCountReset();
|
|
12376
|
+
this.captureStatusBar(response);
|
|
12377
|
+
entry.resolve(response);
|
|
12378
|
+
} else if (typeof response.type === "string") {
|
|
12379
|
+
this.logVia(`Ignoring unknown stdout push frame type: ${response.type}`);
|
|
12368
12380
|
}
|
|
12381
|
+
} catch (_err) {
|
|
12382
|
+
this.warnVia(`Failed to parse stdout line: ${line}`);
|
|
12369
12383
|
}
|
|
12370
12384
|
}
|
|
12371
12385
|
captureStatusBar(response) {
|
|
@@ -14493,13 +14507,7 @@ function consumeBgCompletion(sessionID, taskId) {
|
|
|
14493
14507
|
state.consumedTaskIds.delete(evicted);
|
|
14494
14508
|
}
|
|
14495
14509
|
}
|
|
14496
|
-
|
|
14497
|
-
clearTimeout(state.debounceTimer);
|
|
14498
|
-
state.debounceTimer = null;
|
|
14499
|
-
state.firstCompletionAt = null;
|
|
14500
|
-
state.scheduledFireAt = null;
|
|
14501
|
-
state.scheduledCompletionCount = 0;
|
|
14502
|
-
}
|
|
14510
|
+
clearWakeTimerIfNoPending(state);
|
|
14503
14511
|
}
|
|
14504
14512
|
async function markBgCompletionDelivered(drainContext, taskId) {
|
|
14505
14513
|
await ackCompletions(drainContext, [
|
|
@@ -14670,16 +14678,11 @@ async function appendInTurnBgCompletions(drainContext, output) {
|
|
|
14670
14678
|
}
|
|
14671
14679
|
state.pendingLongRunning = [];
|
|
14672
14680
|
state.pendingPatternMatches = [];
|
|
14681
|
+
state.retryDelayMs = null;
|
|
14673
14682
|
state.wakeRetryAttempts = 0;
|
|
14674
14683
|
state.wakeHardStopped = false;
|
|
14675
14684
|
await ackCompletions(drainContext, completionAcks);
|
|
14676
|
-
|
|
14677
|
-
clearTimeout(state.debounceTimer);
|
|
14678
|
-
state.debounceTimer = null;
|
|
14679
|
-
state.firstCompletionAt = null;
|
|
14680
|
-
state.scheduledFireAt = null;
|
|
14681
|
-
state.scheduledCompletionCount = 0;
|
|
14682
|
-
}
|
|
14685
|
+
clearWakeTimerIfNoPending(state);
|
|
14683
14686
|
}
|
|
14684
14687
|
async function handleIdleBgCompletions(drainContext) {
|
|
14685
14688
|
stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
|
|
@@ -14921,13 +14924,18 @@ function wakeEligibleCompletions(state, includeDeferredCompletions) {
|
|
|
14921
14924
|
return state.pendingCompletions.filter((completion) => !state.wakeDeferredTaskIds.has(completion.task_id));
|
|
14922
14925
|
}
|
|
14923
14926
|
function clearWakeTimerIfNoPending(state) {
|
|
14924
|
-
if (state.pendingCompletions.length
|
|
14925
|
-
|
|
14926
|
-
state.debounceTimer = null;
|
|
14927
|
-
state.firstCompletionAt = null;
|
|
14928
|
-
state.scheduledFireAt = null;
|
|
14929
|
-
state.scheduledCompletionCount = 0;
|
|
14927
|
+
if (state.pendingCompletions.length > 0 || state.pendingLongRunning.length > 0 || state.pendingPatternMatches.length > 0) {
|
|
14928
|
+
return;
|
|
14930
14929
|
}
|
|
14930
|
+
if (state.debounceTimer)
|
|
14931
|
+
clearTimeout(state.debounceTimer);
|
|
14932
|
+
state.debounceTimer = null;
|
|
14933
|
+
state.firstCompletionAt = null;
|
|
14934
|
+
state.scheduledFireAt = null;
|
|
14935
|
+
state.scheduledCompletionCount = 0;
|
|
14936
|
+
state.retryDelayMs = null;
|
|
14937
|
+
state.wakeRetryAttempts = 0;
|
|
14938
|
+
state.wakeHardStopped = false;
|
|
14931
14939
|
}
|
|
14932
14940
|
function scheduleWake(state, sendWake, onSendFailure, sessionID, includeDeferredCompletions = true) {
|
|
14933
14941
|
if (state.wakeHardStopped)
|
|
@@ -30598,7 +30606,16 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
|
30598
30606
|
// src/lsp-auto-install.ts
|
|
30599
30607
|
import { spawn as spawn3 } from "node:child_process";
|
|
30600
30608
|
import { createHash as createHash4 } from "node:crypto";
|
|
30601
|
-
import {
|
|
30609
|
+
import {
|
|
30610
|
+
createReadStream,
|
|
30611
|
+
existsSync as existsSync12,
|
|
30612
|
+
mkdirSync as mkdirSync8,
|
|
30613
|
+
readFileSync as readFileSync11,
|
|
30614
|
+
renameSync as renameSync6,
|
|
30615
|
+
rmSync as rmSync5,
|
|
30616
|
+
statSync as statSync6,
|
|
30617
|
+
writeFileSync as writeFileSync8
|
|
30618
|
+
} from "node:fs";
|
|
30602
30619
|
import { join as join16 } from "node:path";
|
|
30603
30620
|
|
|
30604
30621
|
// src/lsp-cache.ts
|
|
@@ -31173,6 +31190,17 @@ async function resolveTargetVersion(spec, config2, fetchImpl = fetch) {
|
|
|
31173
31190
|
writeVersionCheck(spec.npm, probe.version);
|
|
31174
31191
|
return { version: probe.version, pinned: false, probe };
|
|
31175
31192
|
}
|
|
31193
|
+
function ensureInstallAnchor(cwd) {
|
|
31194
|
+
try {
|
|
31195
|
+
const stub = join16(cwd, "package.json");
|
|
31196
|
+
if (!existsSync12(stub)) {
|
|
31197
|
+
writeFileSync8(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
31198
|
+
`);
|
|
31199
|
+
}
|
|
31200
|
+
} catch (err) {
|
|
31201
|
+
warn2(`[lsp] could not write package.json stub in ${cwd}: ${err}`);
|
|
31202
|
+
}
|
|
31203
|
+
}
|
|
31176
31204
|
function runInstall(spec, version2, cwd, signal) {
|
|
31177
31205
|
return new Promise((resolve3) => {
|
|
31178
31206
|
const target = `${spec.npm}@${version2}`;
|
|
@@ -31188,6 +31216,7 @@ function runInstall(spec, version2, cwd, signal) {
|
|
|
31188
31216
|
resolve3(false);
|
|
31189
31217
|
return;
|
|
31190
31218
|
}
|
|
31219
|
+
ensureInstallAnchor(cwd);
|
|
31191
31220
|
const child = spawn3(npm.command, ["install", "--no-save", "--ignore-scripts", "--silent", target], {
|
|
31192
31221
|
stdio: ["ignore", "pipe", "pipe"],
|
|
31193
31222
|
cwd,
|
|
@@ -31441,7 +31470,7 @@ import {
|
|
|
31441
31470
|
copyFileSync as copyFileSync4,
|
|
31442
31471
|
createReadStream as createReadStream2,
|
|
31443
31472
|
createWriteStream as createWriteStream3,
|
|
31444
|
-
existsSync as
|
|
31473
|
+
existsSync as existsSync13,
|
|
31445
31474
|
lstatSync as lstatSync2,
|
|
31446
31475
|
mkdirSync as mkdirSync9,
|
|
31447
31476
|
readdirSync as readdirSync4,
|
|
@@ -31452,7 +31481,7 @@ import {
|
|
|
31452
31481
|
rmSync as rmSync6,
|
|
31453
31482
|
statSync as statSync7,
|
|
31454
31483
|
unlinkSync as unlinkSync6,
|
|
31455
|
-
writeFileSync as
|
|
31484
|
+
writeFileSync as writeFileSync9
|
|
31456
31485
|
} from "node:fs";
|
|
31457
31486
|
import { dirname as dirname8, join as join17, relative as relative2, resolve as resolve3 } from "node:path";
|
|
31458
31487
|
import { Readable as Readable3 } from "node:stream";
|
|
@@ -31603,7 +31632,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
31603
31632
|
binarySha256,
|
|
31604
31633
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
31605
31634
|
};
|
|
31606
|
-
|
|
31635
|
+
writeFileSync9(join17(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
31607
31636
|
} catch (err) {
|
|
31608
31637
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
31609
31638
|
}
|
|
@@ -32072,7 +32101,7 @@ async function downloadAndInstall(spec, tag, assets, platform3, arch, fetchImpl,
|
|
|
32072
32101
|
} catch {}
|
|
32073
32102
|
}
|
|
32074
32103
|
const innerBinaryPath = join17(extractDir, spec.binaryPathInArchive(platform3, arch, version2));
|
|
32075
|
-
if (!
|
|
32104
|
+
if (!existsSync13(innerBinaryPath)) {
|
|
32076
32105
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
32077
32106
|
return null;
|
|
32078
32107
|
}
|
|
@@ -32156,7 +32185,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl = fetch) {
|
|
|
32156
32185
|
if (!host) {
|
|
32157
32186
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
32158
32187
|
try {
|
|
32159
|
-
if (
|
|
32188
|
+
if (existsSync13(ghBinDir(spec))) {
|
|
32160
32189
|
cachedBinDirs.push(ghBinDir(spec));
|
|
32161
32190
|
}
|
|
32162
32191
|
} catch {}
|
|
@@ -32403,7 +32432,7 @@ function writeTerminal(terminal, data) {
|
|
|
32403
32432
|
|
|
32404
32433
|
// src/shared/rpc-server.ts
|
|
32405
32434
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
32406
|
-
import { mkdirSync as mkdirSync10, renameSync as renameSync8, unlinkSync as unlinkSync7, writeFileSync as
|
|
32435
|
+
import { mkdirSync as mkdirSync10, renameSync as renameSync8, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "node:fs";
|
|
32407
32436
|
import { createServer } from "node:http";
|
|
32408
32437
|
import { dirname as dirname9, join as join19 } from "node:path";
|
|
32409
32438
|
|
|
@@ -32456,7 +32485,7 @@ class AftRpcServer {
|
|
|
32456
32485
|
const dir = dirname9(this.portFilePath);
|
|
32457
32486
|
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
32458
32487
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
32459
|
-
|
|
32488
|
+
writeFileSync10(tmpPath, JSON.stringify({ port: this.port, token: this.token }), {
|
|
32460
32489
|
encoding: "utf-8",
|
|
32461
32490
|
mode: 384
|
|
32462
32491
|
});
|
|
@@ -32632,6 +32661,20 @@ function readCompression(value) {
|
|
|
32632
32661
|
session: readCompressionAggregate(compression.session)
|
|
32633
32662
|
};
|
|
32634
32663
|
}
|
|
32664
|
+
function readStatusBar(value) {
|
|
32665
|
+
if (typeof value !== "object" || value === null)
|
|
32666
|
+
return;
|
|
32667
|
+
const bar = asRecord(value);
|
|
32668
|
+
return {
|
|
32669
|
+
errors: readNumber(bar.errors),
|
|
32670
|
+
warnings: readNumber(bar.warnings),
|
|
32671
|
+
dead_code: readNumber(bar.dead_code),
|
|
32672
|
+
unused_exports: readNumber(bar.unused_exports),
|
|
32673
|
+
duplicates: readNumber(bar.duplicates),
|
|
32674
|
+
todos: readNumber(bar.todos),
|
|
32675
|
+
tier2_stale: readBoolean(bar.tier2_stale)
|
|
32676
|
+
};
|
|
32677
|
+
}
|
|
32635
32678
|
function formatFlag(enabled) {
|
|
32636
32679
|
return enabled ? "enabled" : "disabled";
|
|
32637
32680
|
}
|
|
@@ -32725,6 +32768,7 @@ function coerceAftStatus(response) {
|
|
|
32725
32768
|
checkpoints: readNumber(session.checkpoints)
|
|
32726
32769
|
},
|
|
32727
32770
|
compression: readCompression(response.compression),
|
|
32771
|
+
status_bar: readStatusBar(response.status_bar),
|
|
32728
32772
|
message: readString(response.message, "")
|
|
32729
32773
|
};
|
|
32730
32774
|
}
|
|
@@ -32780,6 +32824,10 @@ function formatStatusMarkdown(status) {
|
|
|
32780
32824
|
if (status.storage_dir ?? status.disk.storage_dir) {
|
|
32781
32825
|
lines.push(`- **Storage dir:** \`${status.storage_dir ?? status.disk.storage_dir}\``);
|
|
32782
32826
|
}
|
|
32827
|
+
if (status.status_bar) {
|
|
32828
|
+
const sb = status.status_bar;
|
|
32829
|
+
lines.push("", `### Code Health${sb.tier2_stale ? " (~ stale)" : ""}`, `- **Errors:** ${formatCount(sb.errors)}`, `- **Warnings:** ${formatCount(sb.warnings)}`, `- **Duplicates:** ${formatCount(sb.duplicates)}`, `- **TODOs:** ${formatCount(sb.todos)}`);
|
|
32830
|
+
}
|
|
32783
32831
|
lines.push("", "### Current session", `- **ID:** \`${status.session.id}\``, `- **Tracked files:** ${formatCount(status.session.tracked_files)}`, `- **Checkpoints:** ${formatCount(status.session.checkpoints)}`, `- **Project checkpoints (all sessions):** ${formatCount(status.checkpoints_total)}`);
|
|
32784
32832
|
return lines.join(`
|
|
32785
32833
|
`);
|
|
@@ -32787,7 +32835,7 @@ function formatStatusMarkdown(status) {
|
|
|
32787
32835
|
|
|
32788
32836
|
// src/shared/tui-config.ts
|
|
32789
32837
|
var import_comment_json4 = __toESM(require_src2(), 1);
|
|
32790
|
-
import { existsSync as
|
|
32838
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "node:fs";
|
|
32791
32839
|
import { dirname as dirname10, join as join21 } from "node:path";
|
|
32792
32840
|
|
|
32793
32841
|
// src/shared/opencode-config-dir.ts
|
|
@@ -32824,9 +32872,9 @@ function resolveTuiConfigPath() {
|
|
|
32824
32872
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
32825
32873
|
const jsoncPath = join21(configDir, "tui.jsonc");
|
|
32826
32874
|
const jsonPath = join21(configDir, "tui.json");
|
|
32827
|
-
if (
|
|
32875
|
+
if (existsSync14(jsoncPath))
|
|
32828
32876
|
return jsoncPath;
|
|
32829
|
-
if (
|
|
32877
|
+
if (existsSync14(jsonPath))
|
|
32830
32878
|
return jsonPath;
|
|
32831
32879
|
return jsonPath;
|
|
32832
32880
|
}
|
|
@@ -32834,7 +32882,7 @@ function ensureTuiPluginEntry() {
|
|
|
32834
32882
|
try {
|
|
32835
32883
|
const configPath = resolveTuiConfigPath();
|
|
32836
32884
|
let config2 = {};
|
|
32837
|
-
if (
|
|
32885
|
+
if (existsSync14(configPath)) {
|
|
32838
32886
|
config2 = import_comment_json4.parse(readFileSync13(configPath, "utf-8")) ?? {};
|
|
32839
32887
|
}
|
|
32840
32888
|
const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((value) => typeof value === "string") : [];
|
|
@@ -32844,7 +32892,7 @@ function ensureTuiPluginEntry() {
|
|
|
32844
32892
|
plugins.push(PLUGIN_ENTRY);
|
|
32845
32893
|
config2.plugin = plugins;
|
|
32846
32894
|
mkdirSync11(dirname10(configPath), { recursive: true });
|
|
32847
|
-
|
|
32895
|
+
writeFileSync11(configPath, `${import_comment_json4.stringify(config2, null, 2)}
|
|
32848
32896
|
`);
|
|
32849
32897
|
log2(`[aft-plugin] added TUI plugin entry to ${configPath}`);
|
|
32850
32898
|
return true;
|
|
@@ -32947,6 +32995,7 @@ function isEmptyParam(value) {
|
|
|
32947
32995
|
return Object.keys(value).length === 0;
|
|
32948
32996
|
return false;
|
|
32949
32997
|
}
|
|
32998
|
+
var BASH_TRANSPORT_TIMEOUT_MS = 30000;
|
|
32950
32999
|
var LONG_RUNNING_COMMAND_TIMEOUT_MS = {
|
|
32951
33000
|
callers: 60000,
|
|
32952
33001
|
trace_to: 60000,
|
|
@@ -33082,6 +33131,13 @@ async function callBridge(ctx, runtime, command, params = {}, options) {
|
|
|
33082
33131
|
ingestBgCompletions(runtime.sessionID, response.bg_completions);
|
|
33083
33132
|
return response;
|
|
33084
33133
|
}
|
|
33134
|
+
async function callBashBridge(ctx, runtime, command, params = {}, options) {
|
|
33135
|
+
return await callBridge(ctx, runtime, command, params, {
|
|
33136
|
+
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS,
|
|
33137
|
+
...options,
|
|
33138
|
+
keepBridgeOnTimeout: true
|
|
33139
|
+
});
|
|
33140
|
+
}
|
|
33085
33141
|
|
|
33086
33142
|
// src/tools/permissions.ts
|
|
33087
33143
|
import * as fs4 from "node:fs";
|
|
@@ -33907,7 +33963,6 @@ function setCache2(sessionId, isSubagent) {
|
|
|
33907
33963
|
var z5 = tool5.schema;
|
|
33908
33964
|
var METADATA_PREVIEW_LIMIT = 30 * 1024;
|
|
33909
33965
|
var FOREGROUND_POLL_INTERVAL_MS = 100;
|
|
33910
|
-
var BASH_TRANSPORT_TIMEOUT_MS = 30000;
|
|
33911
33966
|
var DEFAULT_HARD_TIMEOUT_MS = 30 * 60 * 1000;
|
|
33912
33967
|
var BASH_DESCRIPTION = `Hoisted bash tool with output compression, command rewriting to AFT tools, optional background execution, and PTY mode for interactive programs. By default, output is compressed; pass compressed: false for raw output. Pass background: true to spawn in the background and get a taskId for bash_status/bash_kill. Pass pty: true for interactive REPLs and drive them with bash_status({ outputMode: "screen" }) plus bash_write (pty implies background automatically). Use bash_watch to block on or register for pattern matches and exit events.`;
|
|
33913
33968
|
async function withPermissionLoop(ctx, runtime, params, bridgeCall, options) {
|
|
@@ -33979,9 +34034,7 @@ function createBashTool(ctx) {
|
|
|
33979
34034
|
pty_rows: args.ptyRows,
|
|
33980
34035
|
pty_cols: args.ptyCols,
|
|
33981
34036
|
permissions_requested: true
|
|
33982
|
-
},
|
|
33983
|
-
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS,
|
|
33984
|
-
keepBridgeOnTimeout: true,
|
|
34037
|
+
}, callBashBridge, {
|
|
33985
34038
|
onProgress: ({ text }) => {
|
|
33986
34039
|
accumulatedOutput = preview(accumulatedOutput + text);
|
|
33987
34040
|
metadata?.({ output: accumulatedOutput, description });
|
|
@@ -34013,7 +34066,7 @@ function createBashTool(ctx) {
|
|
|
34013
34066
|
const waitTimeoutMs = subagentForcedForeground ? argTimeout ?? DEFAULT_HARD_TIMEOUT_MS : argTimeout !== undefined ? Math.min(argTimeout, foregroundWaitMs) : foregroundWaitMs;
|
|
34014
34067
|
const startedAt = Date.now();
|
|
34015
34068
|
while (true) {
|
|
34016
|
-
const status = await
|
|
34069
|
+
const status = await callBashBridge(ctx, context, "bash_status", { task_id: taskId });
|
|
34017
34070
|
if (status.success === false) {
|
|
34018
34071
|
throw new Error(status.message ?? "bash_status failed");
|
|
34019
34072
|
}
|
|
@@ -34034,7 +34087,9 @@ function createBashTool(ctx) {
|
|
|
34034
34087
|
await sleep(FOREGROUND_POLL_INTERVAL_MS);
|
|
34035
34088
|
continue;
|
|
34036
34089
|
}
|
|
34037
|
-
const promoted = await
|
|
34090
|
+
const promoted = await callBashBridge(ctx, context, "bash_promote", {
|
|
34091
|
+
task_id: taskId
|
|
34092
|
+
});
|
|
34038
34093
|
if (promoted.success === false) {
|
|
34039
34094
|
throw new Error(promoted.message ?? "bash_promote failed");
|
|
34040
34095
|
}
|
|
@@ -34115,7 +34170,7 @@ function createBashKillTool(ctx) {
|
|
|
34115
34170
|
taskId: z5.string().describe("Background task ID returned by bash({ background: true }), e.g. bash-6b454047.")
|
|
34116
34171
|
},
|
|
34117
34172
|
execute: async (args, context) => {
|
|
34118
|
-
const data = await
|
|
34173
|
+
const data = await callBashBridge(ctx, context, "bash_kill", {
|
|
34119
34174
|
task_id: args.taskId
|
|
34120
34175
|
});
|
|
34121
34176
|
if (data.success === false) {
|
|
@@ -34130,7 +34185,7 @@ function createBashKillTool(ctx) {
|
|
|
34130
34185
|
};
|
|
34131
34186
|
}
|
|
34132
34187
|
async function bashStatusSnapshot(ctx, runtime, taskId, outputMode, options) {
|
|
34133
|
-
const data = await
|
|
34188
|
+
const data = await callBashBridge(ctx, runtime, "bash_status", { task_id: taskId, output_mode: outputMode }, options);
|
|
34134
34189
|
if (data.success === false) {
|
|
34135
34190
|
throw new Error(data.message ?? "bash_status failed");
|
|
34136
34191
|
}
|
|
@@ -34268,7 +34323,6 @@ var z6 = tool6.schema;
|
|
|
34268
34323
|
var BASH_WAIT_POLL_INTERVAL_MS = 100;
|
|
34269
34324
|
var DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS = 30000;
|
|
34270
34325
|
var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 300000;
|
|
34271
|
-
var BASH_TRANSPORT_TIMEOUT_MS2 = 30000;
|
|
34272
34326
|
var REGEX_WAIT_SCAN_WINDOW_BYTES = 64 * 1024;
|
|
34273
34327
|
function createBashWatchTool(ctx) {
|
|
34274
34328
|
return {
|
|
@@ -34303,7 +34357,7 @@ function createBashWatchTool(ctx) {
|
|
|
34303
34357
|
markExplicitControl(context.sessionID, taskId, false);
|
|
34304
34358
|
let registered;
|
|
34305
34359
|
try {
|
|
34306
|
-
registered = await
|
|
34360
|
+
registered = await callBashBridge(ctx, context, "bash_notify", notifyParams);
|
|
34307
34361
|
} catch (err) {
|
|
34308
34362
|
unmarkExplicitControl(context.sessionID, taskId);
|
|
34309
34363
|
throw err;
|
|
@@ -34316,7 +34370,6 @@ function createBashWatchTool(ctx) {
|
|
|
34316
34370
|
throw new Error(`invalid_request: ${message}`);
|
|
34317
34371
|
throw new Error(`${code}: ${message}`);
|
|
34318
34372
|
}
|
|
34319
|
-
markExplicitControl(context.sessionID, taskId);
|
|
34320
34373
|
const metadata2 = context.metadata;
|
|
34321
34374
|
metadata2?.({ taskId, registered: true, watchId: registered.watch_id });
|
|
34322
34375
|
return `Watch registered: ${registered.watch_id} on task ${taskId}
|
|
@@ -34359,7 +34412,7 @@ ${preview2.slice(0, 2000)}`;
|
|
|
34359
34412
|
return text;
|
|
34360
34413
|
}
|
|
34361
34414
|
async function bashStatusSnapshot2(ctx, runtime, taskId, outputMode, options) {
|
|
34362
|
-
const data = await
|
|
34415
|
+
const data = await callBashBridge(ctx, runtime, "bash_status", { task_id: taskId, output_mode: outputMode }, options);
|
|
34363
34416
|
if (data.success === false)
|
|
34364
34417
|
throw new Error(data.message ?? "bash_status failed");
|
|
34365
34418
|
return data;
|
|
@@ -34370,10 +34423,7 @@ async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effe
|
|
|
34370
34423
|
let spillCursor = { output: 0, stderr: 0, combined: 0 };
|
|
34371
34424
|
let scanText = "";
|
|
34372
34425
|
let scanBaseOffset = 0;
|
|
34373
|
-
const bridgeOptions = {
|
|
34374
|
-
keepBridgeOnTimeout: true,
|
|
34375
|
-
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS2
|
|
34376
|
-
};
|
|
34426
|
+
const bridgeOptions = {};
|
|
34377
34427
|
markTaskWaiting(runtime.sessionID, taskId);
|
|
34378
34428
|
let sawTerminal = false;
|
|
34379
34429
|
try {
|
|
@@ -34559,7 +34609,7 @@ function createBashWriteTool(ctx) {
|
|
|
34559
34609
|
]).describe("Either a string of verbatim bytes (e.g. 'print(1)\\n') OR an array mixing strings " + "and { key: '<name>' } objects for atomic text+key sequences. " + "Example: [ 'iHello', { key: 'esc' }, ':wq', { key: 'enter' } ].")
|
|
34560
34610
|
},
|
|
34561
34611
|
execute: async (args, context) => {
|
|
34562
|
-
const data = await
|
|
34612
|
+
const data = await callBashBridge(ctx, context, "bash_write", {
|
|
34563
34613
|
task_id: args.taskId,
|
|
34564
34614
|
input: args.input
|
|
34565
34615
|
});
|
|
@@ -37272,14 +37322,12 @@ var PLUGIN_VERSION = (() => {
|
|
|
37272
37322
|
return "0.0.0";
|
|
37273
37323
|
}
|
|
37274
37324
|
})();
|
|
37275
|
-
var ANNOUNCEMENT_VERSION = "0.35.
|
|
37325
|
+
var ANNOUNCEMENT_VERSION = "0.35.3";
|
|
37276
37326
|
var ANNOUNCEMENT_FEATURES = [
|
|
37277
|
-
"
|
|
37278
|
-
"
|
|
37279
|
-
"
|
|
37280
|
-
"
|
|
37281
|
-
"`npx @cortexkit/aft --version` reports CLI, binary, and per-harness versions; `doctor --issue` can scope its report to a single session.",
|
|
37282
|
-
"New SCSS support and `.inc` files parsed as PHP."
|
|
37327
|
+
"Code Health in the TUI sidebar and `/aft-status`: live LSP errors and warnings plus duplicate and TODO counts, shown as at-a-glance traffic lights when the sidebar is collapsed.",
|
|
37328
|
+
"The semantic index now recovers on its own from a transient embedding-backend blip (a restarted local server, or a model still loading) instead of getting stuck on `failed`.",
|
|
37329
|
+
"Fixed a background codebase-scan crash on very deep or minified files.",
|
|
37330
|
+
"More reliable LSP auto-install when a parent directory has its own `package.json`."
|
|
37283
37331
|
];
|
|
37284
37332
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
37285
37333
|
var plugin = async (input) => initializePluginForDirectory(input);
|
|
@@ -37428,8 +37476,8 @@ ${lines}
|
|
|
37428
37476
|
delivery: projectConfig.configure_warnings_delivery ?? "toast"
|
|
37429
37477
|
});
|
|
37430
37478
|
},
|
|
37431
|
-
onBashCompletion: (completion) => {
|
|
37432
|
-
const sessionDir =
|
|
37479
|
+
onBashCompletion: (completion, bridge) => {
|
|
37480
|
+
const sessionDir = bridge.getCwd();
|
|
37433
37481
|
handlePushedBgCompletion({
|
|
37434
37482
|
ctx,
|
|
37435
37483
|
directory: sessionDir,
|
|
@@ -37438,8 +37486,8 @@ ${lines}
|
|
|
37438
37486
|
serverUrl: input.serverUrl?.toString()
|
|
37439
37487
|
}, completion);
|
|
37440
37488
|
},
|
|
37441
|
-
onBashLongRunning: (reminder) => {
|
|
37442
|
-
const sessionDir =
|
|
37489
|
+
onBashLongRunning: (reminder, bridge) => {
|
|
37490
|
+
const sessionDir = bridge.getCwd();
|
|
37443
37491
|
handlePushedBgLongRunning({
|
|
37444
37492
|
ctx,
|
|
37445
37493
|
directory: sessionDir,
|
|
@@ -37448,8 +37496,8 @@ ${lines}
|
|
|
37448
37496
|
serverUrl: input.serverUrl?.toString()
|
|
37449
37497
|
}, reminder);
|
|
37450
37498
|
},
|
|
37451
|
-
onBashPatternMatch: (frame) => {
|
|
37452
|
-
const sessionDir =
|
|
37499
|
+
onBashPatternMatch: (frame, bridge) => {
|
|
37500
|
+
const sessionDir = bridge.getCwd();
|
|
37453
37501
|
handlePushedPatternMatch({
|
|
37454
37502
|
ctx,
|
|
37455
37503
|
directory: sessionDir,
|
|
@@ -71,6 +71,36 @@ export interface AutoInstallResult {
|
|
|
71
71
|
installsComplete: Promise<void>;
|
|
72
72
|
}
|
|
73
73
|
export declare function abortInFlightAutoInstalls(): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Spawn `npm install --no-save <pkg>@<version>` in the cache dir.
|
|
76
|
+
*
|
|
77
|
+
* Uses `--ignore-scripts` to neutralize lifecycle hooks (the v0.16 audit
|
|
78
|
+
* hardening). Output goes to plugin log.
|
|
79
|
+
*
|
|
80
|
+
* Previously this used `bun add`, but OpenCode runs under whichever runtime
|
|
81
|
+
* the user has installed (Node 22 is common), and bun is not guaranteed to
|
|
82
|
+
* be on PATH. Every install would fail silently with ENOENT, so users
|
|
83
|
+
* without bun saw recurring `lsp_binary_missing` warnings for newer servers
|
|
84
|
+
* like `@vue/language-server` even though `lsp.auto_install` was true.
|
|
85
|
+
* GitHub #46 reported this exact symptom against v0.27.0.
|
|
86
|
+
*
|
|
87
|
+
* npm is guaranteed to be present whenever the plugin runs through OpenCode's
|
|
88
|
+
* normal CLI distribution path, matches Pi's auto-install behavior, and is
|
|
89
|
+
* what OpenCode itself uses for its built-in LSP auto-install.
|
|
90
|
+
*/
|
|
91
|
+
/**
|
|
92
|
+
* Anchor an `npm install --no-save` to `cwd` by writing a minimal package.json.
|
|
93
|
+
*
|
|
94
|
+
* Without a package.json in `cwd`, npm walks UP the directory tree; if any
|
|
95
|
+
* ancestor (e.g. ~/package.json) has one, npm installs into THAT package's
|
|
96
|
+
* node_modules instead, leaving our cache dir's node_modules/<server> missing
|
|
97
|
+
* while still exiting 0. The result is a silent install failure and a recurring
|
|
98
|
+
* lsp_binary_missing warning. The old `bun add` flow created this package.json
|
|
99
|
+
* implicitly; npm needs it written explicitly. GitHub #92.
|
|
100
|
+
*
|
|
101
|
+
* Idempotent: only writes when absent. Failures are non-fatal (logged).
|
|
102
|
+
*/
|
|
103
|
+
export declare function ensureInstallAnchor(cwd: string): void;
|
|
74
104
|
/**
|
|
75
105
|
* Top-level entry point. Returns the list of bin directories that already
|
|
76
106
|
* have an installed binary AND kicks off background installs for missing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lsp-auto-install.d.ts","sourceRoot":"","sources":["../src/lsp-auto-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;
|
|
1
|
+
{"version":3,"file":"lsp-auto-install.d.ts","sourceRoot":"","sources":["../src/lsp-auto-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAsCH,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,kGAAkG;IAClG,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C;;;;;;;;;OASG;IACH,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AA8DD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM/D;AA4DD;;;;;;;;;;;;;;;;GAgBG;AACH;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAYrD;AA8TD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,iBAAiB,EACzB,SAAS,GAAE,OAAO,KAAa,GAC9B,iBAAiB,CAwEnB"}
|
package/dist/shared/status.d.ts
CHANGED
|
@@ -8,6 +8,23 @@ export interface StatusCompression {
|
|
|
8
8
|
project: StatusCompressionAggregate;
|
|
9
9
|
session: StatusCompressionAggregate;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The agent status-bar glance — `[AFT E· W· | D· U· C· | T·]`. `errors`/
|
|
13
|
+
* `warnings` are live LSP diagnostics for files touched this session; the
|
|
14
|
+
* Tier-2 trio (`dead_code`/`unused_exports`/`duplicates`) plus `todos` come
|
|
15
|
+
* from the last completed background scan. `tier2_stale` marks those Tier-2
|
|
16
|
+
* counts as predating the latest edit. Null in the snapshot until the Tier-2
|
|
17
|
+
* cache is populated at least once (no fabricated zeros).
|
|
18
|
+
*/
|
|
19
|
+
export interface StatusBar {
|
|
20
|
+
errors: number;
|
|
21
|
+
warnings: number;
|
|
22
|
+
dead_code: number;
|
|
23
|
+
unused_exports: number;
|
|
24
|
+
duplicates: number;
|
|
25
|
+
todos: number;
|
|
26
|
+
tier2_stale: boolean;
|
|
27
|
+
}
|
|
11
28
|
export interface AftStatusSnapshot {
|
|
12
29
|
version: string;
|
|
13
30
|
project_root: string | null;
|
|
@@ -70,6 +87,12 @@ export interface AftStatusSnapshot {
|
|
|
70
87
|
};
|
|
71
88
|
/** Compression aggregate passthrough; rendering is added separately. */
|
|
72
89
|
compression?: StatusCompression;
|
|
90
|
+
/**
|
|
91
|
+
* Agent status-bar counts (E/W/D/U/C/T). Undefined until the Tier-2 cache
|
|
92
|
+
* is populated at least once — the sidebar hides the Code Health section
|
|
93
|
+
* until then so it never shows fabricated zeros.
|
|
94
|
+
*/
|
|
95
|
+
status_bar?: StatusBar;
|
|
73
96
|
/**
|
|
74
97
|
* Human-readable explanation for a synthetic snapshot (e.g.
|
|
75
98
|
* `cache_role === "not_initialized"`). When the plugin returns a placeholder
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,0BAA0B,CAAC;IACpC,OAAO,EAAE,0BAA0B,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,gBAAgB,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,wEAAwE;IACxE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/_shared.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export declare function isEmptyParam(value: unknown): boolean;
|
|
|
77
77
|
* file tree or wait on external I/O (embedding API, index build). The
|
|
78
78
|
* goal is to absorb slow first-call spikes without masking real hangs.
|
|
79
79
|
*/
|
|
80
|
+
export declare const BASH_TRANSPORT_TIMEOUT_MS = 30000;
|
|
80
81
|
export declare const LONG_RUNNING_COMMAND_TIMEOUT_MS: Record<string, number>;
|
|
81
82
|
/** Returns the per-command timeout override, or undefined to use the bridge default. */
|
|
82
83
|
export declare function timeoutForCommand(command: string): number | undefined;
|
|
@@ -160,6 +161,13 @@ export declare function bridgeFor(ctx: PluginContext, runtime: ToolRuntime): Bin
|
|
|
160
161
|
* session identifier still work — they just share undo/checkpoint state.
|
|
161
162
|
*/
|
|
162
163
|
export declare function callBridge(ctx: PluginContext, runtime: ToolRuntime, command: string, params?: Record<string, unknown>, options?: BridgeRequestOptions): Promise<Record<string, unknown>>;
|
|
164
|
+
/**
|
|
165
|
+
* Send a bash-family command without restarting the shared bridge on transport
|
|
166
|
+
* timeout. Bash has its own child-process timeout/watchdog handling; a late
|
|
167
|
+
* transport response must not sacrifice the warm shared bridge and reject
|
|
168
|
+
* unrelated sibling requests.
|
|
169
|
+
*/
|
|
170
|
+
export declare function callBashBridge(ctx: PluginContext, runtime: ToolRuntime, command: string, params?: Record<string, unknown>, options?: BridgeRequestOptions): Promise<Record<string, unknown>>;
|
|
163
171
|
/**
|
|
164
172
|
* Eagerly warm the session-directory cache for a runtime. Safe to call from
|
|
165
173
|
* synchronous code — the lookup runs in the background and failures are
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,GACR,CAAC;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMpD;AAED;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmEjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAuQjE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAyBvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAuBrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash_watch.d.ts","sourceRoot":"","sources":["../../src/tools/bash_watch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"bash_watch.d.ts","sourceRoot":"","sources":["../../src/tools/bash_watch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACrD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAGlF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAwFtE;AAiDD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,kBAAkB,CAAC,CA4D7B;AA6DD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAK5E;AA4DD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAEtC"}
|
package/dist/tui.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/tui/index.tsx
|
|
2
2
|
import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
|
|
3
3
|
// package.json
|
|
4
|
-
var version = "0.35.
|
|
4
|
+
var version = "0.35.4";
|
|
5
5
|
|
|
6
6
|
// src/shared/rpc-client.ts
|
|
7
7
|
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
@@ -343,6 +343,20 @@ function readCompression(value) {
|
|
|
343
343
|
session: readCompressionAggregate(compression.session)
|
|
344
344
|
};
|
|
345
345
|
}
|
|
346
|
+
function readStatusBar(value) {
|
|
347
|
+
if (typeof value !== "object" || value === null)
|
|
348
|
+
return;
|
|
349
|
+
const bar = asRecord(value);
|
|
350
|
+
return {
|
|
351
|
+
errors: readNumber(bar.errors),
|
|
352
|
+
warnings: readNumber(bar.warnings),
|
|
353
|
+
dead_code: readNumber(bar.dead_code),
|
|
354
|
+
unused_exports: readNumber(bar.unused_exports),
|
|
355
|
+
duplicates: readNumber(bar.duplicates),
|
|
356
|
+
todos: readNumber(bar.todos),
|
|
357
|
+
tier2_stale: readBoolean(bar.tier2_stale)
|
|
358
|
+
};
|
|
359
|
+
}
|
|
346
360
|
function formatSemanticIndexStatus(status, stage) {
|
|
347
361
|
if ((status === "loading" || status === "building") && stage === "fingerprint_change") {
|
|
348
362
|
return "Rebuilding (model changed)";
|
|
@@ -430,6 +444,7 @@ function coerceAftStatus(response) {
|
|
|
430
444
|
checkpoints: readNumber(session.checkpoints)
|
|
431
445
|
},
|
|
432
446
|
compression: readCompression(response.compression),
|
|
447
|
+
status_bar: readStatusBar(response.status_bar),
|
|
433
448
|
message: readString(response.message, "")
|
|
434
449
|
};
|
|
435
450
|
}
|
|
@@ -591,6 +606,14 @@ function collapsedCompressionValue(compression) {
|
|
|
591
606
|
const pct = original_tokens > 0 ? Math.round(savings_tokens / original_tokens * 100) : 0;
|
|
592
607
|
return `${formatCount(savings_tokens)} / ${pct}%`;
|
|
593
608
|
}
|
|
609
|
+
function collapsedHealthLights(statusBar) {
|
|
610
|
+
if (!statusBar)
|
|
611
|
+
return null;
|
|
612
|
+
const diagnostics = statusBar.errors > 0 ? "err" : statusBar.warnings > 0 ? "warn" : "ok";
|
|
613
|
+
const code = statusBar.duplicates > 0 ? "warn" : "ok";
|
|
614
|
+
const todos = statusBar.todos > 0 ? "warn" : "ok";
|
|
615
|
+
return { diagnostics, code, todos };
|
|
616
|
+
}
|
|
594
617
|
function resolveTuiStorageDir() {
|
|
595
618
|
return resolveCortexKitStorageRoot();
|
|
596
619
|
}
|
|
@@ -755,6 +778,7 @@ var SidebarContent = (props) => {
|
|
|
755
778
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
756
779
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
757
780
|
const compressionRows = () => formatCompressionSidebarRows(s()?.compression);
|
|
781
|
+
const statusBar = () => s()?.status_bar;
|
|
758
782
|
const degradedReasonLabel = (reason) => {
|
|
759
783
|
if (reason === "home_root") {
|
|
760
784
|
return "project root is your home directory";
|
|
@@ -873,6 +897,28 @@ var SidebarContent = (props) => {
|
|
|
873
897
|
children: "●"
|
|
874
898
|
}, undefined, false, undefined, this)
|
|
875
899
|
}, undefined, false, undefined, this),
|
|
900
|
+
collapsedHealthLights(statusBar()) && /* @__PURE__ */ jsxDEV(CollapsedRow, {
|
|
901
|
+
theme: props.theme,
|
|
902
|
+
label: "Code Health",
|
|
903
|
+
children: /* @__PURE__ */ jsxDEV("box", {
|
|
904
|
+
flexDirection: "row",
|
|
905
|
+
gap: 1,
|
|
906
|
+
children: [
|
|
907
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
908
|
+
fg: toneColor(props.theme, collapsedHealthLights(statusBar()).diagnostics),
|
|
909
|
+
children: "●"
|
|
910
|
+
}, undefined, false, undefined, this),
|
|
911
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
912
|
+
fg: toneColor(props.theme, collapsedHealthLights(statusBar()).code),
|
|
913
|
+
children: "●"
|
|
914
|
+
}, undefined, false, undefined, this),
|
|
915
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
916
|
+
fg: toneColor(props.theme, collapsedHealthLights(statusBar()).todos),
|
|
917
|
+
children: "●"
|
|
918
|
+
}, undefined, false, undefined, this)
|
|
919
|
+
]
|
|
920
|
+
}, undefined, true, undefined, this)
|
|
921
|
+
}, undefined, false, undefined, this),
|
|
876
922
|
collapsedCompressionValue(s()?.compression) && /* @__PURE__ */ jsxDEV(CollapsedRow, {
|
|
877
923
|
theme: props.theme,
|
|
878
924
|
label: "Compression",
|
|
@@ -944,6 +990,38 @@ var SidebarContent = (props) => {
|
|
|
944
990
|
value: formatBytes2(semanticBytes()),
|
|
945
991
|
tone: "muted"
|
|
946
992
|
}, undefined, false, undefined, this),
|
|
993
|
+
statusBar() && /* @__PURE__ */ jsxDEV(Fragment, {
|
|
994
|
+
children: [
|
|
995
|
+
/* @__PURE__ */ jsxDEV(SectionHeader, {
|
|
996
|
+
theme: props.theme,
|
|
997
|
+
title: statusBar().tier2_stale ? "Code Health ~" : "Code Health"
|
|
998
|
+
}, undefined, false, undefined, this),
|
|
999
|
+
/* @__PURE__ */ jsxDEV(StatRow, {
|
|
1000
|
+
theme: props.theme,
|
|
1001
|
+
label: "Errors",
|
|
1002
|
+
value: formatCount(statusBar().errors),
|
|
1003
|
+
tone: statusBar().errors > 0 ? "err" : "muted"
|
|
1004
|
+
}, undefined, false, undefined, this),
|
|
1005
|
+
/* @__PURE__ */ jsxDEV(StatRow, {
|
|
1006
|
+
theme: props.theme,
|
|
1007
|
+
label: "Warnings",
|
|
1008
|
+
value: formatCount(statusBar().warnings),
|
|
1009
|
+
tone: statusBar().warnings > 0 ? "warn" : "muted"
|
|
1010
|
+
}, undefined, false, undefined, this),
|
|
1011
|
+
/* @__PURE__ */ jsxDEV(StatRow, {
|
|
1012
|
+
theme: props.theme,
|
|
1013
|
+
label: "Duplicates",
|
|
1014
|
+
value: formatCount(statusBar().duplicates),
|
|
1015
|
+
tone: "muted"
|
|
1016
|
+
}, undefined, false, undefined, this),
|
|
1017
|
+
/* @__PURE__ */ jsxDEV(StatRow, {
|
|
1018
|
+
theme: props.theme,
|
|
1019
|
+
label: "TODOs",
|
|
1020
|
+
value: formatCount(statusBar().todos),
|
|
1021
|
+
tone: "muted"
|
|
1022
|
+
}, undefined, false, undefined, this)
|
|
1023
|
+
]
|
|
1024
|
+
}, undefined, true, undefined, this),
|
|
947
1025
|
compressionRows().length > 0 && /* @__PURE__ */ jsxDEV(Fragment, {
|
|
948
1026
|
children: [
|
|
949
1027
|
/* @__PURE__ */ jsxDEV(SectionHeader, {
|
|
@@ -1433,6 +1511,43 @@ var StatusDialog = (props) => {
|
|
|
1433
1511
|
}, undefined, false, undefined, this))
|
|
1434
1512
|
]
|
|
1435
1513
|
}, undefined, true, undefined, this) : null,
|
|
1514
|
+
status()?.status_bar ? /* @__PURE__ */ jsxDEV2("box", {
|
|
1515
|
+
flexDirection: "column",
|
|
1516
|
+
width: "100%",
|
|
1517
|
+
marginTop: 1,
|
|
1518
|
+
children: [
|
|
1519
|
+
/* @__PURE__ */ jsxDEV2("text", {
|
|
1520
|
+
fg: t().text,
|
|
1521
|
+
children: /* @__PURE__ */ jsxDEV2("b", {
|
|
1522
|
+
children: status().status_bar.tier2_stale ? "Code Health ~" : "Code Health"
|
|
1523
|
+
}, undefined, false, undefined, this)
|
|
1524
|
+
}, undefined, false, undefined, this),
|
|
1525
|
+
/* @__PURE__ */ jsxDEV2(R, {
|
|
1526
|
+
theme: t(),
|
|
1527
|
+
label: "Errors",
|
|
1528
|
+
value: formatCountShort(status().status_bar.errors),
|
|
1529
|
+
tone: status().status_bar.errors > 0 ? "err" : "muted"
|
|
1530
|
+
}, undefined, false, undefined, this),
|
|
1531
|
+
/* @__PURE__ */ jsxDEV2(R, {
|
|
1532
|
+
theme: t(),
|
|
1533
|
+
label: "Warnings",
|
|
1534
|
+
value: formatCountShort(status().status_bar.warnings),
|
|
1535
|
+
tone: status().status_bar.warnings > 0 ? "warn" : "muted"
|
|
1536
|
+
}, undefined, false, undefined, this),
|
|
1537
|
+
/* @__PURE__ */ jsxDEV2(R, {
|
|
1538
|
+
theme: t(),
|
|
1539
|
+
label: "Duplicates",
|
|
1540
|
+
value: formatCountShort(status().status_bar.duplicates),
|
|
1541
|
+
tone: "muted"
|
|
1542
|
+
}, undefined, false, undefined, this),
|
|
1543
|
+
/* @__PURE__ */ jsxDEV2(R, {
|
|
1544
|
+
theme: t(),
|
|
1545
|
+
label: "TODOs",
|
|
1546
|
+
value: formatCountShort(status().status_bar.todos),
|
|
1547
|
+
tone: "muted"
|
|
1548
|
+
}, undefined, false, undefined, this)
|
|
1549
|
+
]
|
|
1550
|
+
}, undefined, true, undefined, this) : null,
|
|
1436
1551
|
/* @__PURE__ */ jsxDEV2("box", {
|
|
1437
1552
|
marginTop: 1,
|
|
1438
1553
|
justifyContent: "flex-end",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.4",
|
|
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",
|
|
@@ -30,19 +30,19 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.2.0",
|
|
33
|
-
"@cortexkit/aft-bridge": "0.35.
|
|
33
|
+
"@cortexkit/aft-bridge": "0.35.4",
|
|
34
34
|
"@xterm/headless": "^5.5.0",
|
|
35
35
|
"comment-json": "^4.6.2",
|
|
36
36
|
"undici": "^7.25.0",
|
|
37
37
|
"zod": "^4.1.8"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@cortexkit/aft-darwin-arm64": "0.35.
|
|
41
|
-
"@cortexkit/aft-darwin-x64": "0.35.
|
|
42
|
-
"@cortexkit/aft-linux-arm64": "0.35.
|
|
43
|
-
"@cortexkit/aft-linux-x64": "0.35.
|
|
44
|
-
"@cortexkit/aft-win32-arm64": "0.35.
|
|
45
|
-
"@cortexkit/aft-win32-x64": "0.35.
|
|
40
|
+
"@cortexkit/aft-darwin-arm64": "0.35.4",
|
|
41
|
+
"@cortexkit/aft-darwin-x64": "0.35.4",
|
|
42
|
+
"@cortexkit/aft-linux-arm64": "0.35.4",
|
|
43
|
+
"@cortexkit/aft-linux-x64": "0.35.4",
|
|
44
|
+
"@cortexkit/aft-win32-arm64": "0.35.4",
|
|
45
|
+
"@cortexkit/aft-win32-x64": "0.35.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@opencode-ai/plugin": "^1.15.11",
|
package/src/shared/status.ts
CHANGED
|
@@ -10,6 +10,24 @@ export interface StatusCompression {
|
|
|
10
10
|
session: StatusCompressionAggregate;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The agent status-bar glance — `[AFT E· W· | D· U· C· | T·]`. `errors`/
|
|
15
|
+
* `warnings` are live LSP diagnostics for files touched this session; the
|
|
16
|
+
* Tier-2 trio (`dead_code`/`unused_exports`/`duplicates`) plus `todos` come
|
|
17
|
+
* from the last completed background scan. `tier2_stale` marks those Tier-2
|
|
18
|
+
* counts as predating the latest edit. Null in the snapshot until the Tier-2
|
|
19
|
+
* cache is populated at least once (no fabricated zeros).
|
|
20
|
+
*/
|
|
21
|
+
export interface StatusBar {
|
|
22
|
+
errors: number;
|
|
23
|
+
warnings: number;
|
|
24
|
+
dead_code: number;
|
|
25
|
+
unused_exports: number;
|
|
26
|
+
duplicates: number;
|
|
27
|
+
todos: number;
|
|
28
|
+
tier2_stale: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
export interface AftStatusSnapshot {
|
|
14
32
|
version: string;
|
|
15
33
|
project_root: string | null;
|
|
@@ -72,6 +90,12 @@ export interface AftStatusSnapshot {
|
|
|
72
90
|
};
|
|
73
91
|
/** Compression aggregate passthrough; rendering is added separately. */
|
|
74
92
|
compression?: StatusCompression;
|
|
93
|
+
/**
|
|
94
|
+
* Agent status-bar counts (E/W/D/U/C/T). Undefined until the Tier-2 cache
|
|
95
|
+
* is populated at least once — the sidebar hides the Code Health section
|
|
96
|
+
* until then so it never shows fabricated zeros.
|
|
97
|
+
*/
|
|
98
|
+
status_bar?: StatusBar;
|
|
75
99
|
/**
|
|
76
100
|
* Human-readable explanation for a synthetic snapshot (e.g.
|
|
77
101
|
* `cache_role === "not_initialized"`). When the plugin returns a placeholder
|
|
@@ -125,6 +149,23 @@ function readCompression(value: unknown): StatusCompression | undefined {
|
|
|
125
149
|
};
|
|
126
150
|
}
|
|
127
151
|
|
|
152
|
+
function readStatusBar(value: unknown): StatusBar | undefined {
|
|
153
|
+
// Null until Tier-2 is populated — the Rust snapshot emits JSON null, which
|
|
154
|
+
// is not an object, so this returns undefined and the sidebar hides the
|
|
155
|
+
// Code Health section (no fabricated zeros).
|
|
156
|
+
if (typeof value !== "object" || value === null) return undefined;
|
|
157
|
+
const bar = asRecord(value);
|
|
158
|
+
return {
|
|
159
|
+
errors: readNumber(bar.errors),
|
|
160
|
+
warnings: readNumber(bar.warnings),
|
|
161
|
+
dead_code: readNumber(bar.dead_code),
|
|
162
|
+
unused_exports: readNumber(bar.unused_exports),
|
|
163
|
+
duplicates: readNumber(bar.duplicates),
|
|
164
|
+
todos: readNumber(bar.todos),
|
|
165
|
+
tier2_stale: readBoolean(bar.tier2_stale),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
128
169
|
function formatFlag(enabled: boolean): string {
|
|
129
170
|
return enabled ? "enabled" : "disabled";
|
|
130
171
|
}
|
|
@@ -227,6 +268,7 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
|
|
|
227
268
|
checkpoints: readNumber(session.checkpoints),
|
|
228
269
|
},
|
|
229
270
|
compression: readCompression(response.compression),
|
|
271
|
+
status_bar: readStatusBar(response.status_bar),
|
|
230
272
|
message: readString(response.message, ""),
|
|
231
273
|
};
|
|
232
274
|
}
|
|
@@ -288,6 +330,21 @@ export function formatStatusDialogMessage(status: AftStatusSnapshot): string {
|
|
|
288
330
|
lines.push(`- storage dir: ${status.storage_dir ?? status.disk.storage_dir}`);
|
|
289
331
|
}
|
|
290
332
|
|
|
333
|
+
if (status.status_bar) {
|
|
334
|
+
const sb = status.status_bar;
|
|
335
|
+
lines.push(
|
|
336
|
+
"",
|
|
337
|
+
`Code Health${sb.tier2_stale ? " (~ stale)" : ""}`,
|
|
338
|
+
`- errors: ${formatCount(sb.errors)}`,
|
|
339
|
+
`- warnings: ${formatCount(sb.warnings)}`,
|
|
340
|
+
// dead code / unused exports hidden until oxc resolver lands (restore both)
|
|
341
|
+
// `- dead code: ${formatCount(sb.dead_code)}`,
|
|
342
|
+
// `- unused exports: ${formatCount(sb.unused_exports)}`,
|
|
343
|
+
`- duplicates: ${formatCount(sb.duplicates)}`,
|
|
344
|
+
`- todos: ${formatCount(sb.todos)}`,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
291
348
|
lines.push(
|
|
292
349
|
"",
|
|
293
350
|
"Current session",
|
|
@@ -383,6 +440,21 @@ export function formatStatusMarkdown(status: AftStatusSnapshot): string {
|
|
|
383
440
|
lines.push(`- **Storage dir:** \`${status.storage_dir ?? status.disk.storage_dir}\``);
|
|
384
441
|
}
|
|
385
442
|
|
|
443
|
+
if (status.status_bar) {
|
|
444
|
+
const sb = status.status_bar;
|
|
445
|
+
lines.push(
|
|
446
|
+
"",
|
|
447
|
+
`### Code Health${sb.tier2_stale ? " (~ stale)" : ""}`,
|
|
448
|
+
`- **Errors:** ${formatCount(sb.errors)}`,
|
|
449
|
+
`- **Warnings:** ${formatCount(sb.warnings)}`,
|
|
450
|
+
// dead code / unused exports hidden until oxc resolver lands (restore both)
|
|
451
|
+
// `- **Dead code:** ${formatCount(sb.dead_code)}`,
|
|
452
|
+
// `- **Unused exports:** ${formatCount(sb.unused_exports)}`,
|
|
453
|
+
`- **Duplicates:** ${formatCount(sb.duplicates)}`,
|
|
454
|
+
`- **TODOs:** ${formatCount(sb.todos)}`,
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
386
458
|
lines.push(
|
|
387
459
|
"",
|
|
388
460
|
"### Current session",
|
package/src/tui/index.tsx
CHANGED
|
@@ -466,6 +466,57 @@ const StatusDialog = (props: StatusDialogProps) => {
|
|
|
466
466
|
</box>
|
|
467
467
|
) : null}
|
|
468
468
|
|
|
469
|
+
{/* Code Health — the agent status-bar glance (E/W/D/U/C/T), surfaced so
|
|
470
|
+
users see the same view agents get. Hidden until the Tier-2 cache is
|
|
471
|
+
populated (status_bar undefined) so it never shows fabricated zeros.
|
|
472
|
+
A `~` on the header flags the Tier-2 counts as predating the latest
|
|
473
|
+
edit. */}
|
|
474
|
+
{status()?.status_bar ? (
|
|
475
|
+
<box flexDirection="column" width="100%" marginTop={1}>
|
|
476
|
+
<text fg={t().text}>
|
|
477
|
+
<b>{status()!.status_bar!.tier2_stale ? "Code Health ~" : "Code Health"}</b>
|
|
478
|
+
</text>
|
|
479
|
+
<R
|
|
480
|
+
theme={t()}
|
|
481
|
+
label="Errors"
|
|
482
|
+
value={formatCountShort(status()!.status_bar!.errors)}
|
|
483
|
+
tone={status()!.status_bar!.errors > 0 ? "err" : "muted"}
|
|
484
|
+
/>
|
|
485
|
+
<R
|
|
486
|
+
theme={t()}
|
|
487
|
+
label="Warnings"
|
|
488
|
+
value={formatCountShort(status()!.status_bar!.warnings)}
|
|
489
|
+
tone={status()!.status_bar!.warnings > 0 ? "warn" : "muted"}
|
|
490
|
+
/>
|
|
491
|
+
{/* Dead Code / Unused Exports hidden until the oxc resolver lands
|
|
492
|
+
(current scanner over-reports on barrel re-exports). Restore both. */}
|
|
493
|
+
{/* <R
|
|
494
|
+
theme={t()}
|
|
495
|
+
label="Dead Code"
|
|
496
|
+
value={formatCountShort(status()!.status_bar!.dead_code)}
|
|
497
|
+
tone="muted"
|
|
498
|
+
/>
|
|
499
|
+
<R
|
|
500
|
+
theme={t()}
|
|
501
|
+
label="Unused Exports"
|
|
502
|
+
value={formatCountShort(status()!.status_bar!.unused_exports)}
|
|
503
|
+
tone="muted"
|
|
504
|
+
/> */}
|
|
505
|
+
<R
|
|
506
|
+
theme={t()}
|
|
507
|
+
label="Duplicates"
|
|
508
|
+
value={formatCountShort(status()!.status_bar!.duplicates)}
|
|
509
|
+
tone="muted"
|
|
510
|
+
/>
|
|
511
|
+
<R
|
|
512
|
+
theme={t()}
|
|
513
|
+
label="TODOs"
|
|
514
|
+
value={formatCountShort(status()!.status_bar!.todos)}
|
|
515
|
+
tone="muted"
|
|
516
|
+
/>
|
|
517
|
+
</box>
|
|
518
|
+
) : null}
|
|
519
|
+
|
|
469
520
|
{/* Footer */}
|
|
470
521
|
<box marginTop={1} justifyContent="flex-end" width="100%">
|
|
471
522
|
<text fg={t().textMuted}>Enter or Esc to close</text>
|
package/src/tui/sidebar.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
coerceAftStatus,
|
|
17
17
|
formatSemanticIndexStatus,
|
|
18
18
|
formatSemanticRefreshing,
|
|
19
|
+
type StatusBar,
|
|
19
20
|
type StatusCompression,
|
|
20
21
|
} from "../shared/status";
|
|
21
22
|
import { resolveCortexKitStorageRoot } from "../shared/storage-paths";
|
|
@@ -179,6 +180,34 @@ export function collapsedCompressionValue(
|
|
|
179
180
|
return `${formatCount(savings_tokens)} / ${pct}%`;
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
export type HealthLightTone = "ok" | "warn" | "err";
|
|
184
|
+
|
|
185
|
+
export interface HealthLights {
|
|
186
|
+
// Diagnostics: red if any errors, yellow if any warnings, else green.
|
|
187
|
+
diagnostics: HealthLightTone;
|
|
188
|
+
// Code cruft: yellow if there is any duplicate, green when zero. Never red —
|
|
189
|
+
// cruft is not a build failure. NOTE: dead_code / unused_exports are
|
|
190
|
+
// temporarily excluded from this signal (and the expanded rows below) until
|
|
191
|
+
// the oxc-based resolver lands and makes those counts trustworthy on real
|
|
192
|
+
// TS/JS codebases. Restore them here when that engine ships.
|
|
193
|
+
code: HealthLightTone;
|
|
194
|
+
// TODOs: yellow if any, else green.
|
|
195
|
+
todos: HealthLightTone;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Three traffic lights for the collapsed view, replacing the cramped
|
|
199
|
+
// `E· W· | D· U· C· | T·` string. Returns null until populated.
|
|
200
|
+
export function collapsedHealthLights(statusBar: StatusBar | undefined): HealthLights | null {
|
|
201
|
+
if (!statusBar) return null;
|
|
202
|
+
const diagnostics: HealthLightTone =
|
|
203
|
+
statusBar.errors > 0 ? "err" : statusBar.warnings > 0 ? "warn" : "ok";
|
|
204
|
+
const code: HealthLightTone =
|
|
205
|
+
// statusBar.dead_code > 0 || statusBar.unused_exports > 0 || // restore with oxc engine
|
|
206
|
+
statusBar.duplicates > 0 ? "warn" : "ok";
|
|
207
|
+
const todos: HealthLightTone = statusBar.todos > 0 ? "warn" : "ok";
|
|
208
|
+
return { diagnostics, code, todos };
|
|
209
|
+
}
|
|
210
|
+
|
|
182
211
|
// v0.27 moved AFT storage to the CortexKit root. TUI code must use a
|
|
183
212
|
// lightweight local path helper rather than the shared bridge barrel, which
|
|
184
213
|
// also exports URL-fetch helpers unsuitable for Bun's TUI runtime.
|
|
@@ -426,6 +455,7 @@ const SidebarContent = (props: {
|
|
|
426
455
|
const trigramBytes = () => s()?.disk?.trigram_disk_bytes ?? 0;
|
|
427
456
|
const semanticBytes = () => s()?.disk?.semantic_disk_bytes ?? 0;
|
|
428
457
|
const compressionRows = () => formatCompressionSidebarRows(s()?.compression);
|
|
458
|
+
const statusBar = () => s()?.status_bar;
|
|
429
459
|
|
|
430
460
|
// Degraded-mode reason → human-readable hint. Distinct strings per reason
|
|
431
461
|
// because the UX direction is different: "home_root" tells the user to
|
|
@@ -537,6 +567,19 @@ const SidebarContent = (props: {
|
|
|
537
567
|
<CollapsedRow theme={props.theme} label="Semantic Index">
|
|
538
568
|
<text fg={toneColor(props.theme, semanticStatus().tone)}>●</text>
|
|
539
569
|
</CollapsedRow>
|
|
570
|
+
{collapsedHealthLights(statusBar()) && (
|
|
571
|
+
<CollapsedRow theme={props.theme} label="Code Health">
|
|
572
|
+
<box flexDirection="row" gap={1}>
|
|
573
|
+
<text fg={toneColor(props.theme, collapsedHealthLights(statusBar())!.diagnostics)}>
|
|
574
|
+
●
|
|
575
|
+
</text>
|
|
576
|
+
<text fg={toneColor(props.theme, collapsedHealthLights(statusBar())!.code)}>●</text>
|
|
577
|
+
<text fg={toneColor(props.theme, collapsedHealthLights(statusBar())!.todos)}>
|
|
578
|
+
●
|
|
579
|
+
</text>
|
|
580
|
+
</box>
|
|
581
|
+
</CollapsedRow>
|
|
582
|
+
)}
|
|
540
583
|
{collapsedCompressionValue(s()?.compression) && (
|
|
541
584
|
<CollapsedRow theme={props.theme} label="Compression">
|
|
542
585
|
<text fg={props.theme.textMuted}>
|
|
@@ -614,6 +657,61 @@ const SidebarContent = (props: {
|
|
|
614
657
|
tone="muted"
|
|
615
658
|
/>
|
|
616
659
|
|
|
660
|
+
{/* Code Health — the agent status-bar glance, surfaced for users.
|
|
661
|
+
Hidden until the Tier-2 cache is populated (status_bar undefined),
|
|
662
|
+
so it never shows fabricated zeros. Errors/warnings are live LSP
|
|
663
|
+
diagnostics; D/U/C/T come from the last background scan. A `~` on
|
|
664
|
+
the section header flags the Tier-2 counts as predating the latest
|
|
665
|
+
edit. */}
|
|
666
|
+
{statusBar() && (
|
|
667
|
+
<>
|
|
668
|
+
<SectionHeader
|
|
669
|
+
theme={props.theme}
|
|
670
|
+
title={statusBar()!.tier2_stale ? "Code Health ~" : "Code Health"}
|
|
671
|
+
/>
|
|
672
|
+
<StatRow
|
|
673
|
+
theme={props.theme}
|
|
674
|
+
label="Errors"
|
|
675
|
+
value={formatCount(statusBar()!.errors)}
|
|
676
|
+
tone={statusBar()!.errors > 0 ? "err" : "muted"}
|
|
677
|
+
/>
|
|
678
|
+
<StatRow
|
|
679
|
+
theme={props.theme}
|
|
680
|
+
label="Warnings"
|
|
681
|
+
value={formatCount(statusBar()!.warnings)}
|
|
682
|
+
tone={statusBar()!.warnings > 0 ? "warn" : "muted"}
|
|
683
|
+
/>
|
|
684
|
+
{/* Dead Code / Unused Exports temporarily hidden until the
|
|
685
|
+
oxc-based resolver lands and makes these trustworthy on real
|
|
686
|
+
TS/JS codebases (current tree-sitter scanner over-reports via
|
|
687
|
+
barrel re-export gaps). Restore both rows when that ships. */}
|
|
688
|
+
{/* <StatRow
|
|
689
|
+
theme={props.theme}
|
|
690
|
+
label="Dead Code"
|
|
691
|
+
value={formatCount(statusBar()!.dead_code)}
|
|
692
|
+
tone="muted"
|
|
693
|
+
/>
|
|
694
|
+
<StatRow
|
|
695
|
+
theme={props.theme}
|
|
696
|
+
label="Unused Exports"
|
|
697
|
+
value={formatCount(statusBar()!.unused_exports)}
|
|
698
|
+
tone="muted"
|
|
699
|
+
/> */}
|
|
700
|
+
<StatRow
|
|
701
|
+
theme={props.theme}
|
|
702
|
+
label="Duplicates"
|
|
703
|
+
value={formatCount(statusBar()!.duplicates)}
|
|
704
|
+
tone="muted"
|
|
705
|
+
/>
|
|
706
|
+
<StatRow
|
|
707
|
+
theme={props.theme}
|
|
708
|
+
label="TODOs"
|
|
709
|
+
value={formatCount(statusBar()!.todos)}
|
|
710
|
+
tone="muted"
|
|
711
|
+
/>
|
|
712
|
+
</>
|
|
713
|
+
)}
|
|
714
|
+
|
|
617
715
|
{/* Compression aggregates. Tabular layout matching Search/Semantic
|
|
618
716
|
Index above: each scope ("Session", "Project") renders as a
|
|
619
717
|
subheader followed by two StatRows (Tokens Saved, Compression
|