diff --git a/dashboard/README.md b/dashboard/README.md index f3df6d9..0bf3157 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -21,7 +21,8 @@ Queueing a scan from the dashboard creates a Postgres job through `POST /api/job Process the queued job from the repo root: ```bash -DATABASE_URL="postgresql://..." uv run --extra db agent-permit runner --once +set -a; source .env; set +a +uv run --extra db --extra deep-agent agent-permit runner --once --deep-agent auto ``` Refresh the dashboard data snapshot from repo-local `.agent-permit` artifacts: diff --git a/dashboard/src/components/proof-pack-viewer/FindingQueueTable.tsx b/dashboard/src/components/proof-pack-viewer/FindingQueueTable.tsx index 6e809fb..8b8cb72 100644 --- a/dashboard/src/components/proof-pack-viewer/FindingQueueTable.tsx +++ b/dashboard/src/components/proof-pack-viewer/FindingQueueTable.tsx @@ -55,7 +55,7 @@ export function FindingQueueTable({ showAddRepository, }: FindingQueueTableProps) { const activeJobs = jobs.filter((job) => - ["queued", "running", "failed"].includes(job.status), + ["queued", "running"].includes(job.status), ) return ( diff --git a/dashboard/src/components/proof-pack-viewer/ProofPackHeader.tsx b/dashboard/src/components/proof-pack-viewer/ProofPackHeader.tsx index 4fd918e..936ea92 100644 --- a/dashboard/src/components/proof-pack-viewer/ProofPackHeader.tsx +++ b/dashboard/src/components/proof-pack-viewer/ProofPackHeader.tsx @@ -19,14 +19,14 @@ export function ProofPackHeader({
diff --git a/dashboard/src/components/proof-pack-viewer/QueueStatusPanels.tsx b/dashboard/src/components/proof-pack-viewer/QueueStatusPanels.tsx index ec8871e..c96456c 100644 --- a/dashboard/src/components/proof-pack-viewer/QueueStatusPanels.tsx +++ b/dashboard/src/components/proof-pack-viewer/QueueStatusPanels.tsx @@ -8,6 +8,9 @@ import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import type { ApiStatus, QueueScanInput, RunEvent, ScanJob } from "@/data/liveApi" +const RUNNER_COMMAND = + "set -a; source .env; set +a; uv run --extra db --extra deep-agent agent-permit runner --once --deep-agent auto" + export function LiveStatusStrip({ apiStatus, error, @@ -68,9 +71,10 @@ export function AddRepositoryPanel({
-

Queue a repository scan

+

Queue a local repository

- Add an absolute local repository path. The local runner claims it from Postgres. + This creates a Postgres job. The scan starts when you run the local CLI + runner on this machine.

@@ -146,11 +152,29 @@ function QueueSubmitButton({ disabled={localPath.trim().length === 0 || isQueueing} type="submit" > - {isQueueing ? "Queueing" : "Queue scan"} + {isQueueing ? "Queueing" : "Queue scan job"} ) } +function RunnerInstructions() { + return ( +
+
After queueing, run this from the repo root:
+ + {RUNNER_COMMAND} + +

+ The hosted dashboard cannot read your local filesystem. The local runner + claims the queued job, scans the path, writes artifacts, and updates this view. +

+
+ ) +} + function QueueErrorMessage({ queueError }: { queueError: string | null }) { if (!queueError) return null @@ -166,11 +190,8 @@ function RecentJobNotice({ recentJob }: { recentJob: ScanJob | null }) { return (
- Queued {recentJob.repositoryLabel}. Run{" "} - - agent-permit runner --once - {" "} - to process it locally. + Job queued for {recentJob.repositoryLabel}. Run the local runner command above + to start the scan.
) } @@ -218,7 +239,7 @@ export function QueueProgressPanel({
) : (
- No runner events yet. + No runner events yet. Start the local CLI runner to process this job.
)} diff --git a/dashboard/tests/e2e/proof-pack-viewer.e2e.ts b/dashboard/tests/e2e/proof-pack-viewer.e2e.ts index f10a723..a21d0ea 100644 --- a/dashboard/tests/e2e/proof-pack-viewer.e2e.ts +++ b/dashboard/tests/e2e/proof-pack-viewer.e2e.ts @@ -8,8 +8,11 @@ test("queue screen supports scan form, search, drilldown, back, and theme cycle" await expect(page.getByRole("heading", { name: "Repository findings" })).toBeVisible() await expect(page.getByTestId("finding-row")).toHaveCount(5) - await page.getByRole("button", { name: "Stage a repository scan" }).click() + await page.getByRole("button", { name: "Add repository to scan queue" }).click() await expect(page.getByTestId("queue-scan-form")).toBeVisible() + await expect(page.getByTestId("runner-command")).toContainText( + "agent-permit runner --once", + ) await expect(page.getByTestId("queue-scan-submit")).toBeDisabled() await page.getByTestId("queue-scan-path").fill("/tmp/example-repo") await expect(page.getByTestId("queue-scan-submit")).toBeEnabled() diff --git a/docs-site/content/docs/cloudflare-neon-deployment.mdx b/docs-site/content/docs/cloudflare-neon-deployment.mdx index 63a102f..6a3a0e9 100644 --- a/docs-site/content/docs/cloudflare-neon-deployment.mdx +++ b/docs-site/content/docs/cloudflare-neon-deployment.mdx @@ -37,6 +37,15 @@ uv run --extra db agent-permit scan tests/fixtures/risky-ci-agent --ci --run-id uv run --extra db agent-permit scan tests/fixtures/risky-mcp-agent --ci --run-id neon-seed-risky-mcp-agent || true ``` +Process a dashboard-queued repository scan from the local repo root: + +```bash +set -a; source .env; set +a +uv run --extra db --extra deep-agent agent-permit runner --once --deep-agent auto +``` + +The Worker only creates the queue record. The local runner claims the job from Neon, reads the local repository path, runs the scanner, writes artifacts, and updates the shared database. + Check the Worker: ```bash