@cortexkit/aft-opencode 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/config.d.ts +67 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +371 -95
- package/dist/lsp-auto-install.d.ts +1 -1
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/lsp-npm-table.d.ts +14 -0
- package/dist/lsp-npm-table.d.ts.map +1 -1
- package/dist/lsp-project-relevance.d.ts +13 -0
- package/dist/lsp-project-relevance.d.ts.map +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tui.js +103 -90
- package/dist/workflow-hints.d.ts +5 -1
- package/dist/workflow-hints.d.ts.map +1 -1
- package/package.json +9 -7
- package/src/tui/index.tsx +21 -6
- package/src/tui/sidebar.tsx +92 -66
package/src/tui/sidebar.tsx
CHANGED
|
@@ -262,6 +262,15 @@ const SidebarContent = (props: {
|
|
|
262
262
|
|
|
263
263
|
const s = createMemo(() => status());
|
|
264
264
|
|
|
265
|
+
// Lazy-bridge: while AFT has no live bridge yet, the RPC server returns a
|
|
266
|
+
// synthetic snapshot with `cache_role === "not_initialized"`. In that state
|
|
267
|
+
// every metric is unknown by design — not "disabled" — so we hide the
|
|
268
|
+
// version line and the entire Search Index / Semantic Index / Compression
|
|
269
|
+
// grid until a first tool call warms the bridge. Users were reading the
|
|
270
|
+
// pre-init `vunknown` + `Status: unknown` rows as broken state instead of
|
|
271
|
+
// "AFT has not been used yet for this project".
|
|
272
|
+
const notInitialized = () => s()?.cache_role === "not_initialized";
|
|
273
|
+
|
|
265
274
|
// Pre-compute display values so the JSX stays readable. createMemo for
|
|
266
275
|
// each derived field would be overkill — these are cheap derivations.
|
|
267
276
|
const searchStatus = () => statusDisplay(s()?.search_index?.status ?? "disabled");
|
|
@@ -324,7 +333,9 @@ const SidebarContent = (props: {
|
|
|
324
333
|
</box>
|
|
325
334
|
)}
|
|
326
335
|
</box>
|
|
327
|
-
|
|
336
|
+
{!notInitialized() && (
|
|
337
|
+
<text fg={props.theme.textMuted}>v{s()?.version ?? props.pluginVersion}</text>
|
|
338
|
+
)}
|
|
328
339
|
</box>
|
|
329
340
|
|
|
330
341
|
{/* Degraded reason — explains why heavy tools (aft_search, aft_navigate)
|
|
@@ -343,90 +354,105 @@ const SidebarContent = (props: {
|
|
|
343
354
|
until the first tool call routes through `callBridge()` and warms
|
|
344
355
|
the bridge. Show the explanatory message instead of empty status
|
|
345
356
|
rows so users understand why metrics are blank. */}
|
|
346
|
-
{
|
|
357
|
+
{notInitialized() && (
|
|
347
358
|
<box marginTop={1} width="100%">
|
|
348
359
|
<text fg={props.theme.textMuted}>
|
|
349
|
-
{s()!.message ||
|
|
360
|
+
{s()!.message ||
|
|
361
|
+
"AFT bridge is now spawned lazily, information here will be populated after first tool call."}
|
|
350
362
|
</text>
|
|
351
363
|
</box>
|
|
352
364
|
)}
|
|
353
365
|
|
|
354
366
|
{/* Search index */}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
367
|
+
{!notInitialized() && (
|
|
368
|
+
<>
|
|
369
|
+
<SectionHeader theme={props.theme} title="Search Index" />
|
|
370
|
+
<StatRow
|
|
371
|
+
theme={props.theme}
|
|
372
|
+
label="Status"
|
|
373
|
+
value={searchStatus().label}
|
|
374
|
+
tone={searchStatus().tone}
|
|
375
|
+
/>
|
|
376
|
+
{(s()?.search_index?.files ?? null) != null && (
|
|
377
|
+
<StatRow
|
|
378
|
+
theme={props.theme}
|
|
379
|
+
label="Files"
|
|
380
|
+
value={formatCount(s()!.search_index.files)}
|
|
381
|
+
tone="muted"
|
|
382
|
+
/>
|
|
383
|
+
)}
|
|
384
|
+
<StatRow
|
|
385
|
+
theme={props.theme}
|
|
386
|
+
label="Disk"
|
|
387
|
+
value={formatBytes(trigramBytes())}
|
|
388
|
+
tone="muted"
|
|
389
|
+
/>
|
|
390
|
+
|
|
391
|
+
{/* Semantic index */}
|
|
392
|
+
<SectionHeader theme={props.theme} title="Semantic Index" />
|
|
393
|
+
<StatRow
|
|
394
|
+
theme={props.theme}
|
|
395
|
+
label="Status"
|
|
396
|
+
value={semanticStatus().label}
|
|
397
|
+
tone={semanticStatus().tone}
|
|
398
|
+
/>
|
|
399
|
+
{/* When loading, magic-context-style progress hint helps users see
|
|
381
400
|
background work is making progress instead of stuck. */}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
401
|
+
{s()?.semantic_index?.status === "loading" &&
|
|
402
|
+
s()?.semantic_index?.entries_total != null &&
|
|
403
|
+
s()!.semantic_index.entries_total! > 0 && (
|
|
404
|
+
<StatRow
|
|
405
|
+
theme={props.theme}
|
|
406
|
+
label="Progress"
|
|
407
|
+
value={`${formatCount(s()!.semantic_index.entries_done)} / ${formatCount(
|
|
408
|
+
s()!.semantic_index.entries_total,
|
|
409
|
+
)}`}
|
|
410
|
+
tone="warn"
|
|
411
|
+
/>
|
|
412
|
+
)}
|
|
413
|
+
{(s()?.semantic_index?.entries ?? null) != null && (
|
|
414
|
+
<StatRow
|
|
415
|
+
theme={props.theme}
|
|
416
|
+
label="Entries"
|
|
417
|
+
value={formatCount(s()!.semantic_index.entries)}
|
|
418
|
+
tone="muted"
|
|
419
|
+
/>
|
|
420
|
+
)}
|
|
385
421
|
<StatRow
|
|
386
422
|
theme={props.theme}
|
|
387
|
-
label="
|
|
388
|
-
value={
|
|
389
|
-
|
|
390
|
-
)}`}
|
|
391
|
-
tone="warn"
|
|
423
|
+
label="Disk"
|
|
424
|
+
value={formatBytes(semanticBytes())}
|
|
425
|
+
tone="muted"
|
|
392
426
|
/>
|
|
393
|
-
)}
|
|
394
|
-
{(s()?.semantic_index?.entries ?? null) != null && (
|
|
395
|
-
<StatRow
|
|
396
|
-
theme={props.theme}
|
|
397
|
-
label="Entries"
|
|
398
|
-
value={formatCount(s()!.semantic_index.entries)}
|
|
399
|
-
tone="muted"
|
|
400
|
-
/>
|
|
401
|
-
)}
|
|
402
|
-
<StatRow theme={props.theme} label="Disk" value={formatBytes(semanticBytes())} tone="muted" />
|
|
403
427
|
|
|
404
|
-
|
|
428
|
+
{/* Compression aggregates. Tabular layout matching Search/Semantic
|
|
405
429
|
Index above: each scope ("Session", "Project") renders as a
|
|
406
430
|
subheader followed by two StatRows (Tokens Saved, Compression
|
|
407
431
|
Ratio). Keeps numbers right-aligned in the value column instead
|
|
408
432
|
of jamming them after the label on the same line. */}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
433
|
+
{compressionRows().length > 0 && (
|
|
434
|
+
<>
|
|
435
|
+
<SectionHeader theme={props.theme} title="Compression" />
|
|
436
|
+
{compressionRows().map((row) =>
|
|
437
|
+
row.kind === "scope" ? (
|
|
438
|
+
<box width="100%">
|
|
439
|
+
<text fg={props.theme.text}>{row.label}</text>
|
|
440
|
+
</box>
|
|
441
|
+
) : (
|
|
442
|
+
<StatRow theme={props.theme} label={row.label} value={row.value} tone="muted" />
|
|
443
|
+
),
|
|
444
|
+
)}
|
|
445
|
+
</>
|
|
420
446
|
)}
|
|
421
|
-
</>
|
|
422
|
-
)}
|
|
423
447
|
|
|
424
|
-
|
|
448
|
+
{/* Surface failures clearly so users know to act (install ONNX,
|
|
425
449
|
fix config, etc.) rather than silently leaving the panel "off". */}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
450
|
+
{s()?.semantic_index?.status === "failed" && s()?.semantic_index?.error && (
|
|
451
|
+
<box marginTop={1} width="100%">
|
|
452
|
+
<text fg={props.theme.error}>⚠ {s()!.semantic_index.error}</text>
|
|
453
|
+
</box>
|
|
454
|
+
)}
|
|
455
|
+
</>
|
|
430
456
|
)}
|
|
431
457
|
</box>
|
|
432
458
|
);
|