Cover the last 8 shots: real process-adapter runs + doc repoint

Close the remaining gap so every screenshot referenced in the docs is current.

seed.mjs — process-adapter "runner" agents (no LLM needed; the process adapter
executes a shell command):
- "Task Runner" runs `sh -c "echo ..."` → a real completed run with a STDOUT
  transcript (run-transcript-view, test-environment-success via the config
  Test button which now passes: command sh is executable)
- "Live Task" runs `sh -c "sleep 3600"` and is woken last, so it stays
  in-flight through the whole capture phase → genuine "running" agent status
  and an in-progress run row

routes.mjs — targets for run-transcript-view, run-history-in-progress,
agent-status-running, test-environment-success (click "Test" → wait for the
Passed result), approvals/revision-request-input (the detail note box),
adapters/health (the adapter rows), and onboarding/goal-field (wizard step 1).

dashboard.md — the dashboard image pointed at a hand-annotated PNG that can't
be auto-captured; repoint it to the freshly captured dashboard-overview.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Aron PrinsandClaude Opus 4.8 committed 2026-05-30 14:28:19 +02:00
1 parent b24671f98c
commit 59b4d4a4fe
3 files changed
+129 -13

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ The dashboard is your control centre. When your AI company is running, this is t
Think of it like the cockpit instruments on a plane. You don't need to read every dial every second, but you do want a clear signal when something is off. The dashboard gives you that signal.
![The Paperclip dashboard showing the current overview cards, charts, recent activity, and recent tasks](../../user-guides/screenshots/light/dashboard/dashboard-overview-annotated.png)
![The Paperclip dashboard showing the current overview cards, charts, recent activity, and recent tasks](../../user-guides/screenshots/light/dashboard/dashboard-overview.png)
---
+46 -12
View File
@@ -44,6 +44,9 @@ const ID_TOKENS = [
"strategyApprovalId", // a pending approve_ceo_strategy approval
"boardApprovalId", // a pending request_board_approval
"approvedApprovalId", // an already-approved approval
"runnerAgentId", // process agent with a completed run (transcript)
"runnerRunId", // that run's id
"longRunnerAgentId", // process agent left running during capture
];
/**
@@ -648,18 +651,49 @@ export const CAPTURE_TARGETS = [
{ name: "approvals/strategy-approval-detail", route: "/{prefix}/approvals/{strategyApprovalId}", dependsOn: ["ui/src/components/ApprovalPayload.tsx", "ui/src/pages/ApprovalDetail.tsx"] },
{ name: "approvals/approved-approval", route: "/{prefix}/approvals/{approvedApprovalId}?resolved=approved", dependsOn: ["ui/src/pages/ApprovalDetail.tsx"] },
// ── Real process-adapter runs (no LLM — the process adapter runs a shell cmd) ─
{ name: "agents/run-transcript-view", route: "/{prefix}/agents/{runnerAgentId}/runs/{runnerRunId}", dependsOn: ["ui/src/components/transcript/RunTranscriptView.tsx", "ui/src/pages/AgentDetail.tsx"], wait: 1500 },
{ name: "agents/run-history-in-progress", route: "/{prefix}/agents/{longRunnerAgentId}/runs", dependsOn: ["ui/src/pages/AgentDetail.tsx"], wait: 1500 },
{ name: "agents/agent-status-running", route: "/{prefix}/agents/{longRunnerAgentId}", dependsOn: ["ui/src/pages/AgentDetail.tsx"], wait: 1500 },
{
name: "agents/test-environment-success",
route: "/{prefix}/agents/{runnerAgentId}/configuration",
dependsOn: ["ui/src/components/AgentConfigForm.tsx"],
steps: [{ click: { role: "button", name: "Test" } }, { waitFor: { text: /Passed|pass|healthy|ok/i } }, { waitMs: 800 }],
wait: 1500,
},
// ── Approval revision (the detail page's note/comment box) ──────────────────
{
name: "approvals/revision-request-input",
route: "/{prefix}/approvals/{strategyApprovalId}",
dependsOn: ["ui/src/pages/ApprovalDetail.tsx"],
steps: [{ click: { css: "textarea" } }, { waitMs: 400 }],
},
// ── Adapter "health" — the adapter rows (type · package · N models) ─────────
{ name: "adapters/health", route: "/instance/settings/adapters", dependsOn: ["ui/src/pages/AdapterManager.tsx"] },
// ── Onboarding goal field (wizard step 1) ───────────────────────────────────
{
name: "onboarding/goal-field",
route: "/{prefix}/dashboard",
dependsOn: ["ui/src/components/OnboardingWizard.tsx"],
steps: [
{ click: { role: "button", name: /workspace switcher/i } },
{ waitMs: 400 },
{ click: { role: "menuitem", name: /Add company/i } },
{ waitMs: 900 },
{ fill: { placeholder: "Acme Corp" }, value: "Acme Robotics" },
{ waitMs: 400 },
],
},
// ── CLI auth & board claim ─────────────────────────────────────────────────
// These require dynamic IDs generated at demo time. The tokens are not in
// seed-ids.json (they are ephemeral CLI interactions) — capture is skipped
// when the IDs are absent from the seed file.
// These require dynamic IDs generated at demo time and are not in seed-ids.json
// (ephemeral CLI interactions) — capture is skipped when the IDs are absent.
//
// ── Inherently NOT auto-capturable in an offline instance (left manual) ─────
// agents/test-environment-success — needs a real adapter CLI binary on PATH
// agents/agent-status-running — needs a live in-flight run (LLM)
// agents/run-history-in-progress — needs a live in-flight run (LLM)
// agents/run-transcript-view — needs a completed real run transcript (LLM)
// approvals/revision-request-input — no such UI element exists in current code
// adapters/health — no such route/view exists in current code
// onboarding/goal-field — wizard step not reliably locatable
// dashboard/dashboard-overview-annotated — hand-annotated, must stay manual
// ── Left manual on purpose ──────────────────────────────────────────────────
// dashboard/dashboard-overview-annotated — hand-annotated; the doc page is
// re-pointed to the freshly captured dashboard/dashboard-overview instead.
];
+82
View File
@@ -693,6 +693,85 @@ export default async function seed({ baseUrl = BASE_URL } = {}) {
});
}
// 14g. Process-adapter "runner" agents — execute a real shell command (no LLM)
// so we get genuine run rows, a transcript, a running status, and a passing
// environment test. The process adapter runs `command` + `args` directly.
let runnerAgentId = null;
let runnerRunId = null;
let longRunnerAgentId = null;
await step("create + run a process agent (completed run → transcript)", async () => {
const existing = asList(await get(C("/agents"), baseUrl)).find((a) => a.name === "Task Runner");
let agent = existing;
if (!agent) {
agent = await post(
C("/agents"),
{
name: "Task Runner",
role: "engineer",
title: "Automation",
icon: "terminal",
adapterType: "process",
adapterConfig: {
command: "sh",
args: ["-c", "echo 'Analyzing repository...'; echo 'Applying changes to src/app.ts'; echo 'Running tests — 42 passed'; echo 'Done.'"],
timeoutSec: 30,
},
reportsTo: managerAgentId ?? undefined,
},
baseUrl,
);
}
runnerAgentId = agent.id;
if (!companyExisted) {
const run = await post(`/api/agents/${agent.id}/wakeup`, { source: "on_demand", triggerDetail: "manual" }, baseUrl);
runnerRunId = run?.id ?? run?.heartbeatRun?.id ?? run?.run?.id ?? null;
console.log(`[seed] Task Runner run → ${runnerRunId}`);
} else {
// Reuse the most recent completed run if present.
const runs = asList(await step("list runner runs", () => get(`/api/agents/${agent.id}/runs`, baseUrl), []));
runnerRunId = runs[0]?.id ?? null;
}
});
// Give the short run a moment to execute and complete before we capture it.
if (runnerRunId && !companyExisted) {
await new Promise((r) => setTimeout(r, 4000));
}
await step("create a long-running process agent (running status)", async () => {
const existing = asList(await get(C("/agents"), baseUrl)).find((a) => a.name === "Live Task");
let agent = existing;
if (!agent) {
agent = await post(
C("/agents"),
{
name: "Live Task",
role: "engineer",
title: "Long Job",
icon: "cpu",
adapterType: "process",
adapterConfig: {
// Long enough to outlast the full capture phase so the run is still
// in-flight (status "running", an in-progress run row) when capture
// reaches the run/status targets near the end of the list.
command: "sh",
args: ["-c", "echo 'Starting long task...'; sleep 3600; echo done"],
timeoutSec: 4200,
},
reportsTo: managerAgentId ?? undefined,
},
baseUrl,
);
}
longRunnerAgentId = agent.id;
// Kick it off LAST so it is still running throughout the capture phase.
if (!companyExisted) {
await post(`/api/agents/${agent.id}/wakeup`, { source: "on_demand", triggerDetail: "manual" }, baseUrl);
console.log("[seed] Live Task wakeup triggered (stays running during capture)");
}
});
// ── 15. Persist ids ─────────────────────────────────────────────────────────
const ids = {
companyPrefix,
@@ -707,6 +786,9 @@ export default async function seed({ baseUrl = BASE_URL } = {}) {
emptyPrefix,
httpAgentId,
skillId,
runnerAgentId,
runnerRunId,
longRunnerAgentId,
...budgetIds,
...approvalIds,
};