Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,10 @@ When functionally testing changes to the AgentV CLI, **NEVER** use `agentv` dire

**Prefer running from source** (`src/cli.ts`) during development. The dist build can silently serve stale code if you forget to rebuild after changes. After pulling changes that touch `packages/core/`, always run `bun run build` before CLI testing.

**Studio frontend exception — rebuild `apps/studio/dist/` before UAT.** Running `agentv studio` from source (`bun apps/cli/src/cli.ts studio ...`) only reloads the CLI and backend routes from source. The Studio web UI (React/Tailwind bundle) is served as static assets from `apps/studio/dist/`, which is build output and does **not** recompile on change. If you are testing Studio UI changes — especially post-merge on `main` or after pulling — rebuild the frontend first:
**Studio frontend exception — rebuild `apps/dashboard/dist/` before UAT.** Running `agentv studio` from source (`bun apps/cli/src/cli.ts studio ...`) only reloads the CLI and backend routes from source. The Studio web UI (React/Tailwind bundle) is served as static assets from `apps/dashboard/dist/`, which is build output and does **not** recompile on change. If you are testing Studio UI changes — especially post-merge on `main` or after pulling — rebuild the frontend first:

```bash
cd apps/studio && bun run build
cd apps/dashboard && bun run build
```

Skipping this step silently serves the previous bundle, so you'll see the old UI even though your source edits and the backend API are live. This has burned at least one post-merge UAT; always rebuild before screenshotting or driving Studio with `agent-browser`.
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ COPY package.json bun.lock ./
COPY packages/core/package.json packages/core/
COPY packages/eval/package.json packages/eval/
COPY apps/cli/package.json apps/cli/
COPY apps/studio/package.json apps/studio/
COPY apps/dashboard/package.json apps/dashboard/
COPY apps/web/package.json apps/web/
RUN bun install --frozen-lockfile
COPY . .
Expand Down Expand Up @@ -62,7 +62,7 @@ COPY --from=build /app/packages/eval/package.json ./packages/eval/
COPY --from=build /app/apps/cli/dist ./apps/cli/dist
COPY --from=build /app/apps/cli/package.json ./apps/cli/
COPY --from=build /app/apps/cli/node_modules ./apps/cli/node_modules
COPY --from=build /app/apps/studio/dist ./apps/studio/dist
COPY --from=build /app/apps/dashboard/dist ./apps/dashboard/dist

USER agentv
ENV PORT=3117
Expand Down
20 changes: 10 additions & 10 deletions apps/cli/src/commands/results/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ export function createApp(
const studioDistPath = options?.studioDir ?? resolveStudioDistDir();
if (!studioDistPath || !existsSync(path.join(studioDistPath, 'index.html'))) {
throw new Error(
'Dashboard dist not found. Run "bun run build" in apps/studio/ to build the SPA.',
'Dashboard dist not found. Run "bun run build" in apps/dashboard/ to build the SPA.',
);
}

Expand Down Expand Up @@ -1517,25 +1517,25 @@ export function createApp(
}

/**
* Resolve the path to the studio dist directory.
* Resolve the path to the dashboard dist directory.
*
* Searches several candidate locations covering:
* - Running from TypeScript source (`bun apps/cli/src/cli.ts`)
* - Running from built dist (`bun apps/cli/dist/cli.js`)
* - Published npm package (studio bundled inside `dist/studio/`)
* - Published npm package (dashboard bundled inside `dist/dashboard/`)
*/
function resolveStudioDistDir(): string | undefined {
const currentDir =
typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
const candidates = [
// From src/commands/results/ → sibling apps/studio/dist
path.resolve(currentDir, '../../../../studio/dist'),
// From dist/ → sibling apps/studio/dist (monorepo dev)
path.resolve(currentDir, '../../studio/dist'),
// Bundled inside CLI dist (published package: dist/studio/)
path.resolve(currentDir, 'studio'),
// From src/commands/results/ → sibling apps/dashboard/dist
path.resolve(currentDir, '../../../../dashboard/dist'),
// From dist/ → sibling apps/dashboard/dist (monorepo dev)
path.resolve(currentDir, '../../dashboard/dist'),
// Bundled inside CLI dist (published package: dist/dashboard/)
path.resolve(currentDir, 'dashboard'),
// From dist/ in monorepo root context
path.resolve(currentDir, '../../../apps/studio/dist'),
path.resolve(currentDir, '../../../apps/dashboard/dist'),
];
for (const candidate of candidates) {
if (existsSync(candidate) && existsSync(path.join(candidate, 'index.html'))) {
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/test/unit/studio-navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
runPath,
runsHomePath,
suitePath,
} from '../../../studio/src/lib/navigation.ts';
} from '../../../dashboard/src/lib/navigation.ts';

describe('studio navigation helpers', () => {
it('redirects when the preferred project id matches a registered project', () => {
Expand Down
8 changes: 4 additions & 4 deletions apps/cli/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ export default defineConfig({
console.log('⚠ Skills source not found at', srcSkillsDir, '— skipping');
}

// Copy dashboard SPA dist if available (built by apps/studio)
const studioDistDir = path.resolve('..', 'studio', 'dist');
const cliStudioDir = path.join('dist', 'studio');
// Copy dashboard SPA dist if available (built by apps/dashboard)
const studioDistDir = path.resolve('..', 'dashboard', 'dist');
const cliStudioDir = path.join('dist', 'dashboard');
if (existsSync(studioDistDir)) {
rmSync(cliStudioDir, { recursive: true, force: true });
cpSync(studioDistDir, cliStudioDir, { recursive: true });
console.log('✓ Dashboard dist copied to dist/studio');
console.log('✓ Dashboard dist copied to dist/dashboard');
} else {
console.log('⚠ Dashboard dist not found at', studioDistDir, '— skipping');
}
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion apps/studio/package.json → apps/dashboard/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@agentv/studio",
"name": "@agentv/dashboard",
"version": "0.0.1",
"private": true,
"type": "module",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions docs/plans/1222-stop-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ AbortSignal threading.
- No status mutation here; close handler does it.

### Studio Stop button
- `apps/studio/src/components/StopRunButton.tsx` — *new*. Renders a
- `apps/dashboard/src/components/StopRunButton.tsx` — *new*. Renders a
neutral-styled (gray, not red) Stop button when `status` is
non-terminal; calls POST with the benchmark-scoped path when
`benchmarkId` is set; sets local `stopping=true` state to flip the
label optimistically.
- `apps/studio/src/components/stop-run-helpers.ts` — *new*. Pure
- `apps/dashboard/src/components/stop-run-helpers.ts` — *new*. Pure
`shouldShowStopButton(status, isReadOnly)` for unit testing.
- `apps/studio/src/lib/api.ts` — add `stopEvalRun(id, benchmarkId?)`.
- `apps/studio/src/routes/jobs/$runId.tsx` — wire `<StopRunButton />` into
- `apps/dashboard/src/lib/api.ts` — add `stopEvalRun(id, benchmarkId?)`.
- `apps/dashboard/src/routes/jobs/$runId.tsx` — wire `<StopRunButton />` into
the header.

### Resume — planned_test_count
Expand All @@ -76,22 +76,22 @@ AbortSignal threading.
- `apps/cli/src/commands/results/serve.ts` — `deriveResumeMeta` already
reads `metadata.eval_file`; extend to also surface
`planned_test_count`. Run-detail response gains `planned_test_count`.
- `apps/studio/src/lib/types.ts` — add optional
- `apps/dashboard/src/lib/types.ts` — add optional
`planned_test_count?: number` to the run-detail response type.
- `apps/studio/src/components/resume-run-helpers.ts` — extend
- `apps/dashboard/src/components/resume-run-helpers.ts` — extend
`shouldShowResumeActions` to also return true when
`plannedTestCount && results.length < plannedTestCount`.
- `apps/studio/src/components/ResumeRunActions.tsx` and the two run
- `apps/dashboard/src/components/ResumeRunActions.tsx` and the two run
detail routes — pass `plannedTestCount` through.

### Tests (narrow)
- `apps/cli/test/commands/results/serve.test.ts` (or co-located) — stop
endpoint: 404 unknown, 403 read-only, base + benchmark-scoped paths.
Happy path SIGTERM is covered by manual UAT (race-prone in unit tests).
- `apps/studio/src/components/resume-run-helpers.test.ts` — case where
- `apps/dashboard/src/components/resume-run-helpers.test.ts` — case where
every result is `ok` but `results.length < plannedTestCount` → button
visible.
- `apps/studio/src/components/stop-run-helpers.test.ts` — visibility
- `apps/dashboard/src/components/stop-run-helpers.test.ts` — visibility
matrix.
- Skip: integration test that signals a real eval. Manual UAT is enough.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"packageManager": "bun@1.3.3",
"workspaces": ["apps/*", "packages/*"],
"scripts": {
"build": "bun --filter @agentv/core build && bun --filter @agentv/eval build && bun --filter @agentv/studio build && bun --filter agentv build",
"build": "bun --filter @agentv/core build && bun --filter @agentv/eval build && bun --filter @agentv/dashboard build && bun --filter agentv build",
"verify": "bun run build && bun run typecheck && bun run lint && bun run test",
"typecheck": "bun --filter @agentv/core typecheck && bun --filter agentv typecheck",
"typecheck:workspace": "tsc -b tsconfig.build.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ import myDetail from '../../../../assets/screenshots/my-detail.png';
```bash
# Feature branch: UI changes
cd /path/to/worktree
git add apps/studio/...
git add apps/dashboard/...
git commit -m "fix(studio): ..."

# Main repo: docs changes
Expand Down
Loading