@bismawy/pi-arnative 0.3.9 → 0.4.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/CHANGELOG.md +32 -0
- package/README.md +52 -46
- package/extensions/animations.ts +213 -0
- package/extensions/arnative.ts +410 -98
- package/extensions/footer.ts +334 -49
- package/extensions/section-headers.ts +11 -6
- package/extensions/timestamps.ts +1 -1
- package/extensions/tools.ts +19 -2
- package/extensions/ui-render-tweaks.ts +2 -1
- package/extensions/usage.ts +468 -78
- package/lib/ansi.ts +50 -0
- package/lib/box.ts +90 -5
- package/lib/shortcuts.ts +62 -13
- package/lib/spinner.ts +270 -0
- package/lib/usage-store.ts +96 -4
- package/package.json +4 -3
package/extensions/tools.ts
CHANGED
|
@@ -49,7 +49,16 @@ type TCtx = { isError?: boolean; toolCallId?: string; args?: any; state?: Record
|
|
|
49
49
|
type Res = (r: TResult, th: Theme, soft: (s: string) => string, isErr: boolean, expanded: boolean) => string;
|
|
50
50
|
|
|
51
51
|
const cwd = process.cwd();
|
|
52
|
-
const
|
|
52
|
+
const MAX_TIMINGS = 200;
|
|
53
|
+
const TIMINGS = new Map<string, number>();
|
|
54
|
+
|
|
55
|
+
export function recordTiming(toolCallId: string, durationMs: number): void {
|
|
56
|
+
if (TIMINGS.size >= MAX_TIMINGS) {
|
|
57
|
+
const oldest = TIMINGS.keys().next().value;
|
|
58
|
+
if (oldest !== undefined) TIMINGS.delete(oldest);
|
|
59
|
+
}
|
|
60
|
+
TIMINGS.set(toolCallId, durationMs);
|
|
61
|
+
}
|
|
53
62
|
|
|
54
63
|
// Running icon : 500ms spin frames from a ticker that only runs while
|
|
55
64
|
// a tool is active (idle = no wasteful re-renders).
|
|
@@ -586,7 +595,7 @@ function minimal(
|
|
|
586
595
|
try {
|
|
587
596
|
return await tool.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
588
597
|
} finally {
|
|
589
|
-
|
|
598
|
+
recordTiming(toolCallId, Math.round(performance.now() - start));
|
|
590
599
|
ACTIVE--;
|
|
591
600
|
syncTicker();
|
|
592
601
|
}
|
|
@@ -659,6 +668,7 @@ function arnativeTools(pi: ExtensionAPI) {
|
|
|
659
668
|
|
|
660
669
|
// Re-render source for the spinner + ticker cleanup when the session closes
|
|
661
670
|
pi.on("session_start", async (_event, ctx) => {
|
|
671
|
+
TIMINGS.clear();
|
|
662
672
|
requestRenderFn = () => {
|
|
663
673
|
try {
|
|
664
674
|
(ctx.ui as { requestRender?: () => void }).requestRender?.();
|
|
@@ -668,6 +678,7 @@ function arnativeTools(pi: ExtensionAPI) {
|
|
|
668
678
|
};
|
|
669
679
|
});
|
|
670
680
|
pi.on("session_shutdown", async () => {
|
|
681
|
+
TIMINGS.clear();
|
|
671
682
|
if (TICK) {
|
|
672
683
|
clearInterval(TICK);
|
|
673
684
|
TICK = null;
|
|
@@ -1369,5 +1380,11 @@ if (isMain(import.meta.url)) {
|
|
|
1369
1380
|
assert(cdpExpanded.some((l) => l.includes('"pageId": "p1"')), "chrome-devtools: expanded shows the full tool output");
|
|
1370
1381
|
assert(cdpCollapsed.some((l) => l.includes("navigated") && l.includes("to expand")), "chrome-devtools: collapsed shows the first line + hint");
|
|
1371
1382
|
assert([...cdpCollapsed, ...cdpExpanded].every((l) => visibleWidth(l) === 74), "chrome-devtools: box fills the given width");
|
|
1383
|
+
// Capped timings map self-check
|
|
1384
|
+
for (let i = 0; i < 250; i++) recordTiming(`call_${i}`, i);
|
|
1385
|
+
assert(TIMINGS.size === MAX_TIMINGS, `TIMINGS size is bounded to ${MAX_TIMINGS}`);
|
|
1386
|
+
assert(!TIMINGS.has("call_0") && TIMINGS.has("call_249"), "TIMINGS evicts oldest entries");
|
|
1387
|
+
TIMINGS.clear();
|
|
1388
|
+
|
|
1372
1389
|
console.log("OK");
|
|
1373
1390
|
}
|
|
@@ -57,8 +57,9 @@ const RELOAD_TEXT = "Reloading keybindings, extensions, skills, prompts, themes,
|
|
|
57
57
|
* whole chat the moment a transcript line mentioned the phrase.
|
|
58
58
|
*/
|
|
59
59
|
export function shouldHideReloadBox(lines: readonly string[]): boolean {
|
|
60
|
+
if (!lines.some((l) => l.includes("Reloading keybindings"))) return false;
|
|
60
61
|
const rows = lines.map((l) => stripAnsi(l).trim());
|
|
61
|
-
return rows.
|
|
62
|
+
return rows.every((r) => r === "" || /^[─-]+$/.test(r) || RELOAD_TEXT.includes(r));
|
|
62
63
|
}
|
|
63
64
|
const RELOAD_BOX_KEY = Symbol.for("pi-arnative.reloadBoxHidden");
|
|
64
65
|
if (UserMessageComponent?.prototype && !(globalThis as Record<symbol, boolean>)[RELOAD_BOX_KEY]) {
|