New extensions shipping with Agent JAE: - jae-rules: Per-project .jae/rules.md injection - cost-tracker: Token/cost tracking with budget limits - project-dna: Auto-analyze project fingerprint - teach-mode: Pedagogical explanation mode - bookmarks: File bookmark management - replay: Session recording and asciicast export - checkpoints: Git-based undo/time-travel - pr-review: Autonomous PR diff review - auto-docs: Auto-generate README and docs - screenshot-context: Vision analysis for screenshots - deploy: One-command deploy (Docker/Vercel/rsync/static) - pair-programming: Real-time file watching with feedback - dashboard: Terminal HUD with live stats - swarm: Multi-agent parallel task execution - skill-marketplace: Search/install/publish skills - widget-api-demo: TUI widget API demonstration
109 lines
3.2 KiB
TypeScript
109 lines
3.2 KiB
TypeScript
import type { ExtensionAPI } from "@jaeswift/jae-coding-agent";
|
|
|
|
interface DashboardState {
|
|
gitBranch: string;
|
|
modelName: string;
|
|
sessionTokens: number;
|
|
filesModified: Set<string>;
|
|
toolCalls: number;
|
|
startTime: number;
|
|
}
|
|
|
|
export default function (pi: ExtensionAPI) {
|
|
const state: DashboardState = {
|
|
gitBranch: "",
|
|
modelName: "",
|
|
sessionTokens: 0,
|
|
filesModified: new Set(),
|
|
toolCalls: 0,
|
|
startTime: Date.now(),
|
|
};
|
|
|
|
function formatUptime(): string {
|
|
const elapsed = Math.floor((Date.now() - state.startTime) / 1000);
|
|
const mins = Math.floor(elapsed / 60);
|
|
const secs = elapsed % 60;
|
|
return mins > 0 ? `${mins}m${secs}s` : `${secs}s`;
|
|
}
|
|
|
|
function updateDashboard(ctx: any): void {
|
|
const tokens = (state.sessionTokens / 1000).toFixed(1);
|
|
const branch = state.gitBranch || "n/a";
|
|
const model = state.modelName || "unknown";
|
|
const files = state.filesModified.size;
|
|
const tools = state.toolCalls;
|
|
const uptime = formatUptime();
|
|
|
|
ctx.ui.setFooter(
|
|
"dashboard",
|
|
`\u{1F4CA} ${model} | \u{1F333} ${branch} | ${tokens}k tok | ${files} files | ${tools} tools | ${uptime}`,
|
|
);
|
|
}
|
|
|
|
pi.on("session_start", async (_event, ctx) => {
|
|
state.startTime = Date.now();
|
|
|
|
// Detect git branch
|
|
try {
|
|
const result = await pi.exec("git", ["branch", "--show-current"], { cwd: ctx.cwd });
|
|
if (result.code === 0 && result.stdout.trim()) {
|
|
state.gitBranch = result.stdout.trim();
|
|
}
|
|
} catch { /* not a git repo */ }
|
|
|
|
// Get model name
|
|
if (ctx.model) {
|
|
state.modelName = ctx.model.name || ctx.model.id || "unknown";
|
|
}
|
|
|
|
updateDashboard(ctx);
|
|
});
|
|
|
|
pi.on("message_end", async (event, ctx) => {
|
|
if (event.message?.usage) {
|
|
const u = event.message.usage;
|
|
state.sessionTokens += (u.inputTokens || 0) + (u.outputTokens || 0);
|
|
}
|
|
if (ctx.model) {
|
|
state.modelName = ctx.model.name || ctx.model.id || state.modelName;
|
|
}
|
|
updateDashboard(ctx);
|
|
});
|
|
|
|
pi.on("tool_execution_end", async (event, ctx) => {
|
|
state.toolCalls++;
|
|
|
|
// Track file modifications
|
|
if (["write", "edit", "write_file", "edit_file"].includes(event.toolName)) {
|
|
const filePath = (event.input as any)?.path || (event.input as any)?.file_path || "";
|
|
if (filePath) state.filesModified.add(filePath);
|
|
}
|
|
|
|
// Refresh git branch (might have changed)
|
|
try {
|
|
const result = await pi.exec("git", ["branch", "--show-current"], { cwd: ctx.cwd });
|
|
if (result.code === 0 && result.stdout.trim()) {
|
|
state.gitBranch = result.stdout.trim();
|
|
}
|
|
} catch { /* ignore */ }
|
|
|
|
updateDashboard(ctx);
|
|
});
|
|
|
|
pi.registerCommand("dashboard", {
|
|
description: "Show session dashboard stats",
|
|
handler: async (_args, ctx) => {
|
|
const uptime = formatUptime();
|
|
ctx.ui.notify(
|
|
`\u{1F4CA} Session Dashboard:
|
|
Model: ${state.modelName || "unknown"}
|
|
Git Branch: ${state.gitBranch || "n/a"}
|
|
Session Tokens: ${state.sessionTokens.toLocaleString()}
|
|
Files Modified: ${state.filesModified.size} (${Array.from(state.filesModified).slice(0, 5).join(", ")}${state.filesModified.size > 5 ? "..." : ""})
|
|
Tool Calls: ${state.toolCalls}
|
|
Uptime: ${uptime}`,
|
|
"info",
|
|
);
|
|
},
|
|
});
|
|
}
|