11/**
2- * `agentv studio ` / `agentv serve` — starts the AgentV Studio server, a React SPA for
2+ * `agentv dashboard ` / `agentv serve` — starts the AgentV Dashboard server, a React SPA for
33 * reviewing evaluation results.
44 *
55 * The server uses Hono for routing and @hono/node-server to listen.
6- * The Studio SPA is served from a pre-built dist directory.
6+ * The Dashboard SPA is served from a pre-built dist directory.
77 *
88 * API endpoints:
9- * - GET / — Studio SPA (React app)
9+ * - GET / — Dashboard SPA (React app)
1010 * - GET /api/runs — list available run workspaces with metadata
1111 * - GET /api/runs/:filename — load results from a specific run workspace
1212 * - GET /api/runs/:filename/log — stream the captured console.log for a run
@@ -386,13 +386,13 @@ async function handleRuns(c: C, { searchDir, agentvDir }: DataContext) {
386386 avgScore = records . reduce ( ( sum , r ) => sum + r . score , 0 ) / records . length ;
387387 } else {
388388 // Run is in-progress with 0 results written yet — fall back to the
389- // in-memory target stored when the Studio launched this run.
389+ // in-memory target stored when the Dashboard launched this run.
390390 target = getActiveRunTarget ( m . path ) ;
391391 }
392392 } catch {
393393 // ignore enrichment errors
394394 }
395- // Surface live status for Studio -launched runs that are still starting
395+ // Surface live status for Dashboard -launched runs that are still starting
396396 // or running so the RunList can render a spinner instead of the
397397 // pass/fail dot derived from a 0% pass rate.
398398 const liveStatus = getActiveRunStatus ( m . path ) ;
@@ -447,7 +447,7 @@ async function handleRunDetail(c: C, { searchDir }: DataContext) {
447447 try {
448448 const loaded = await loadManifestResultsForMeta ( searchDir , meta ) ;
449449 // Surface run_dir + suite_filter for local runs so the UI can launch a
450- // Studio -side resume against this exact run. Remote runs live in the
450+ // Dashboard -side resume against this exact run. Remote runs live in the
451451 // results-repo cache and cannot be resumed in place, so omit both fields.
452452 const resumeMeta = meta . source === 'local' ? deriveResumeMeta ( searchDir , meta . path ) : { } ;
453453 const liveStatus = meta . source === 'local' ? getActiveRunStatus ( meta . path ) : undefined ;
@@ -467,7 +467,7 @@ async function handleRunDetail(c: C, { searchDir }: DataContext) {
467467 * Compute `run_dir` (relative to cwd, snake_case) and `suite_filter` (the
468468 * eval file path stored in benchmark.json metadata) for a local run manifest.
469469 * Returns whatever fields could be resolved — both are best-effort and only
470- * needed by the Studio "Resume run" / "Rerun failed" actions.
470+ * needed by the Dashboard "Resume run" / "Rerun failed" actions.
471471 */
472472function deriveResumeMeta (
473473 cwd : string ,
@@ -1104,11 +1104,11 @@ export function createApp(
11041104 } ) ;
11051105 }
11061106
1107- // ── Studio configuration ──────────────────────────────────────────────
1107+ // ── Dashboard configuration ──────────────────────────────────────────────
11081108
11091109 app . post ( '/api/config' , async ( c ) => {
11101110 if ( readOnly ) {
1111- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1111+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
11121112 }
11131113 try {
11141114 const body = await c . req . json < Partial < StudioConfig > > ( ) ;
@@ -1174,7 +1174,7 @@ export function createApp(
11741174
11751175 app . post ( '/api/projects' , async ( c ) => {
11761176 if ( readOnly ) {
1177- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1177+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
11781178 }
11791179 try {
11801180 const body = await c . req . json < { path : string } > ( ) ;
@@ -1268,7 +1268,7 @@ export function createApp(
12681268
12691269 app . delete ( '/api/projects/:projectId' , ( c ) => {
12701270 if ( readOnly ) {
1271- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1271+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
12721272 }
12731273 const removed = removeProject ( c . req . param ( 'projectId' ) ?? '' ) ;
12741274 if ( ! removed ) return c . json ( { error : 'Project not found' } , 404 ) ;
@@ -1289,13 +1289,13 @@ export function createApp(
12891289 app . get ( '/api/runs' , ( c ) => handleRuns ( c , defaultCtx ) ) ;
12901290 app . put ( '/api/runs/:filename/tags' , ( c ) => {
12911291 if ( readOnly ) {
1292- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1292+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
12931293 }
12941294 return handleRunTagsPut ( c , defaultCtx ) ;
12951295 } ) ;
12961296 app . delete ( '/api/runs/:filename/tags' , ( c ) => {
12971297 if ( readOnly ) {
1298- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1298+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
12991299 }
13001300 return handleRunTagsDelete ( c , defaultCtx ) ;
13011301 } ) ;
@@ -1321,7 +1321,7 @@ export function createApp(
13211321
13221322 app . post ( '/api/feedback' , async ( c ) => {
13231323 if ( readOnly ) {
1324- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1324+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
13251325 }
13261326 let body : unknown ;
13271327 try {
@@ -1416,13 +1416,13 @@ export function createApp(
14161416 app . get ( '/api/projects/:projectId/runs' , ( c ) => withProject ( c , handleRuns ) ) ;
14171417 app . put ( '/api/projects/:projectId/runs/:filename/tags' , ( c ) => {
14181418 if ( readOnly ) {
1419- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1419+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
14201420 }
14211421 return withProject ( c , handleRunTagsPut ) ;
14221422 } ) ;
14231423 app . delete ( '/api/projects/:projectId/runs/:filename/tags' , ( c ) => {
14241424 if ( readOnly ) {
1425- return c . json ( { error : 'Studio is running in read-only mode' } , 403 ) ;
1425+ return c . json ( { error : 'Dashboard is running in read-only mode' } , 403 ) ;
14261426 }
14271427 return withProject ( c , handleRunTagsDelete ) ;
14281428 } ) ;
@@ -1465,11 +1465,13 @@ export function createApp(
14651465 { readOnly } ,
14661466 ) ;
14671467
1468- // ── Static file serving for Studio SPA ────────────────────────────────
1468+ // ── Static file serving for Dashboard SPA ────────────────────────────────
14691469
14701470 const studioDistPath = options ?. studioDir ?? resolveStudioDistDir ( ) ;
14711471 if ( ! studioDistPath || ! existsSync ( path . join ( studioDistPath , 'index.html' ) ) ) {
1472- throw new Error ( 'Studio dist not found. Run "bun run build" in apps/studio/ to build the SPA.' ) ;
1472+ throw new Error (
1473+ 'Dashboard dist not found. Run "bun run build" in apps/studio/ to build the SPA.' ,
1474+ ) ;
14731475 }
14741476
14751477 app . get ( '/' , ( c ) => {
@@ -1546,8 +1548,8 @@ function resolveStudioDistDir(): string | undefined {
15461548// ── CLI command ──────────────────────────────────────────────────────────
15471549
15481550export const resultsServeCommand = command ( {
1549- name : 'studio ' ,
1550- description : 'Start AgentV Studio — a local dashboard for reviewing evaluation results' ,
1551+ name : 'dashboard ' ,
1552+ description : 'Start AgentV Dashboard — a local dashboard for reviewing evaluation results' ,
15511553 args : {
15521554 source : positional ( {
15531555 type : optional ( string ) ,
@@ -1583,7 +1585,7 @@ export const resultsServeCommand = command({
15831585 } ) ,
15841586 readOnly : flag ( {
15851587 long : 'read-only' ,
1586- description : 'Disable write operations and launch Studio in read-only leaderboard mode' ,
1588+ description : 'Disable write operations and launch Dashboard in read-only leaderboard mode' ,
15871589 } ) ,
15881590 } ,
15891591 handler : async ( { source, port, dir, single, add, remove, readOnly } ) => {
@@ -1614,7 +1616,7 @@ export const resultsServeCommand = command({
16141616 }
16151617
16161618 // ── Version check ────────────────────────────────────────────────
1617- // Enforce `required_version` from .agentv/config.yaml so Studio /serve
1619+ // Enforce `required_version` from .agentv/config.yaml so Dashboard /serve
16181620 // match `agentv eval` behavior. Same prompt in TTY, warn+continue
16191621 // otherwise. Single-project scope only — when one agentv instance
16201622 // serves multiple repos with differing version requirements, a
0 commit comments