Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
2.4 kB · 88 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889/** * Rainbow Editor - highlights "ultrathink" with animated shine effect * * Usage: pi --extension ./examples/extensions/rainbow-editor.ts */
import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
// Base colors (coral → yellow → green → teal → blue → purple → pink)const COLORS: [number, number, number][] = [ [233, 137, 115], // coral [228, 186, 103], // yellow [141, 192, 122], // green [102, 194, 179], // teal [121, 157, 207], // blue [157, 134, 195], // purple [206, 130, 172], // pink];const RESET = "\x1b[0m";
function brighten(rgb: [number, number, number], factor: number): string { const [r, g, b] = rgb.map((c) => Math.round(c + (255 - c) * factor)); return `\x1b[38;2;${r};${g};${b}m`;}
function colorize(text: string, shinePos: number): string { return ( [...text] .map((c, i) => { const baseColor = COLORS[i % COLORS.length]!; // 3-letter shine: center bright, adjacent dimmer let factor = 0; if (shinePos >= 0) { const dist = Math.abs(i - shinePos); if (dist === 0) factor = 0.7; else if (dist === 1) factor = 0.35; } return `${brighten(baseColor, factor)}${c}`; }) .join("") + RESET );}
class RainbowEditor extends CustomEditor { private animationTimer?: ReturnType<typeof setInterval>; private frame = 0;
private hasUltrathink(): boolean { return /ultrathink/i.test(this.getText()); }
private startAnimation(): void { if (this.animationTimer) return; this.animationTimer = setInterval(() => { this.frame++; this.tui.requestRender(); }, 60); }
private stopAnimation(): void { if (this.animationTimer) { clearInterval(this.animationTimer); this.animationTimer = undefined; } }
handleInput(data: string): void { super.handleInput(data); if (this.hasUltrathink()) { this.startAnimation(); } else { this.stopAnimation(); } }
render(width: number): string[] { // Cycle: 10 shine positions + 10 pause frames const cycle = this.frame % 20; const shinePos = cycle < 10 ? cycle : -1; // -1 means no shine (pause) return super.render(width).map((line) => line.replace(/ultrathink/gi, (m) => colorize(m, shinePos))); }}
export default function (pi: ExtensionAPI) { pi.on("session_start", (_event, ctx) => { ctx.ui.setEditorComponent((tui, theme, kb) => new RainbowEditor(tui, theme, kb)); });}