From 1b9cb25dc8c82433acaac3adfaab087b551fbd05 Mon Sep 17 00:00:00 2001 From: "Yifeng[Terry] Yu" <125581657+xiaojiou176@users.noreply.github.com> Date: Sun, 12 Apr 2026 23:09:35 -0700 Subject: [PATCH 1/6] feat: switch public shell to OpenVibeCoding --- README.md | 81 +++-- apps/dashboard/app/command-tower/page.tsx | 4 +- apps/dashboard/app/contracts/page.tsx | 289 ++++++++++++++---- apps/dashboard/app/layout.tsx | 4 +- apps/dashboard/app/page.tsx | 88 +++++- apps/dashboard/app/runs/page.tsx | 48 +-- apps/dashboard/app/workflows/[id]/page.tsx | 6 +- apps/dashboard/app/workflows/page.tsx | 5 +- .../components/DashboardHomeStorySections.tsx | 216 +++++++++++-- ...command_tower_page_ssr_query_repro.test.ts | 2 +- .../dashboard/tests/command_tower_ui.test.tsx | 2 +- apps/dashboard/tests/home_page.test.tsx | 21 +- .../tests/workflow_detail_page.test.tsx | 4 +- .../tests/workflows_queue_page.test.tsx | 2 +- apps/desktop/index.html | 2 +- apps/desktop/src/App.test.tsx | 20 +- .../src/components/layout/AppSidebar.tsx | 11 +- .../src/features/pm-shell/desktopPages.tsx | 6 +- apps/desktop/src/pages/AgentsPage.test.tsx | 4 +- apps/desktop/src/pages/AgentsPage.tsx | 123 +++++++- apps/desktop/src/pages/CommandTowerPage.tsx | 8 +- apps/desktop/src/pages/ContractsPage.test.tsx | 20 +- apps/desktop/src/pages/ContractsPage.tsx | 200 +++++++++++- apps/desktop/src/pages/OverviewPage.tsx | 65 +++- apps/desktop/src/pages/WorkflowDetailPage.tsx | 56 ++-- .../pages/desktop_p0_misc_controls.test.tsx | 4 +- .../src/pages/desktop_p1_controls.test.tsx | 6 +- .../pages/overview_policies_branch.test.tsx | 14 +- docs/README.md | 8 +- docs/agent-starters/index.html | 28 +- docs/ai-surfaces/index.html | 28 +- docs/api/index.html | 24 +- docs/builders/index.html | 16 +- docs/compatibility/index.html | 40 +-- docs/distribution/index.html | 20 +- docs/ecosystem/index.html | 30 +- docs/index.html | 54 ++-- docs/integrations/index.html | 68 ++--- docs/mcp/index.html | 24 +- docs/skills/index.html | 44 +-- docs/use-cases/index.html | 14 +- packages/frontend-shared/uiCopy.js | 84 ++--- packages/frontend-shared/uiCopy.ts | 114 +++---- 43 files changed, 1350 insertions(+), 557 deletions(-) diff --git a/README.md b/README.md index 9126d8c..6bba766 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,30 @@ -# CortexPilot +# OpenVibeCoding -The command tower for AI engineering. +The open command tower for AI engineering. -Stop babysitting AI coding work. CortexPilot helps teams plan, delegate, track, -resume, and prove long-running engineering work across Codex and Claude Code -instead of juggling scattered chats, local scripts, and after-the-fact logs. +Stop babysitting AI coding work. + +AI coding does not lack models. It lacks a command tower. + +OpenVibeCoding is the public shell for the CortexPilot repo and runtime +compatibility layer. It helps teams plan / delegate / track / resume / prove +long-running engineering work across Codex and Claude Code instead of +juggling scattered chats, local scripts, and after-the-fact logs. CortexPilot is a contract-first multi-agent orchestration repository. +The underlying repository, runtime, package, and compatibility names remain +`CortexPilot` where that internal surface is the truthful identifier. + The public story is intentionally narrower than the full monorepo: - **See one proven workflow first** - **Choose the right adoption path second** - **Open MCP / API / builder / skills surfaces only after the real job is clear** -Current public boundary: CortexPilot is a repo-backed AI engineering command -tower, not a hosted product, and the shipped MCP surface remains **read-only**. +Current public boundary: OpenVibeCoding is a repo-backed public shell over the +CortexPilot runtime, not a hosted product, and the shipped MCP surface remains +**read-only**. Current lane order is deliberate: @@ -31,7 +40,14 @@ Current lane order is deliberate: The shortest truthful answer today is: -> CortexPilot officially ships a public repo, a public Pages front door, a repo-local read-only MCP surface, a published PyPI package, a live Official MCP Registry entry, and a live ClawHub skill. The adoption-router skill is the secondary public lane. Local coding-agent starters and bundle examples remain companion/example materials, not the canonical public root. OpenHands/extensions and MCP.so external receipts exist, while hosted service, write-capable MCP, Docker distribution, and standalone npm releases remain deferred. +> OpenVibeCoding currently ships through the public CortexPilot repo, a public +> Pages front door, a repo-local read-only MCP surface, a published PyPI +> package, a live Official MCP Registry entry, and a live ClawHub skill. The +> adoption-router skill is the secondary public lane. Local coding-agent +> starters and bundle examples remain companion/example materials, not the +> canonical public root. OpenHands/extensions and MCP.so external receipts +> exist, while hosted service, write-capable MCP, Docker distribution, and +> standalone npm releases remain deferred. Use these buckets: @@ -99,11 +115,11 @@ release, new task templates, and storefront updates. If you need contributor setup instead of product evaluation, jump to the [30-minute onboarding guide](docs/runbooks/onboarding-30min.md). -## Why CortexPilot Exists +## Why OpenVibeCoding Exists -Most agent demos stop at "the model replied." CortexPilot is built for the next -question: **can we inspect what happened, review what changed, classify the -workflow case, and rerun it without guessing?** +Most agent demos stop at "the model replied." OpenVibeCoding is built for the +next question: **can we inspect what happened, review what changed, classify +the workflow case, and rerun it without guessing?** The deeper product claim is straightforward: @@ -119,7 +135,7 @@ The engineering philosophy underneath that loop is equally explicit: - **Context Engineering**: keep the right material in the right head, and treat explicit handoff as a fallback rather than the default loop. - **Harness Engineering**: move work through contracts, runtime bindings, approvals, and proof surfaces so the system can keep operating safely. -This repository combines: +The CortexPilot runtime underneath that public shell combines: - **Command Tower**: one operator surface for governed AI work, live run visibility, queue posture, and L0-style oversight - **Workflow Cases**: one stable operating record that ties request, verdict, proof, and linked runs together @@ -189,7 +205,7 @@ If the first success path fails, go here next: ## The First Loop -The clearest way to understand CortexPilot is: +The clearest way to understand OpenVibeCoding is: 1. **PM**: describe the task and acceptance target 2. **Workflow Case**: confirm the case identity, queue state, and operating verdict @@ -214,9 +230,10 @@ repository should be judged on. `Switchyard /v1/runtime/invoke` for intake/operator-style chat paths, but MCP tool execution still needs a tool-capable provider path and therefore fails closed instead of pretending Switchyard already has tool parity -- CortexPilot is still **not** a hosted operator service; `cortexpilot.ai` - should be treated as a marketing/holding domain until the public contract, - support boundary, and live surface materially change +- the CortexPilot runtime under OpenVibeCoding is still **not** a hosted + operator service; `cortexpilot.ai` should be treated as a marketing/holding + domain until the public contract, support boundary, and live surface + materially change ## Public CI Safety Model @@ -322,7 +339,7 @@ release-proven until they have their own healthy proof and benchmark artifacts. Use these names as ecosystem anchors, not as co-brands or partnership claims. -- **Codex**: primary workflow audience; CortexPilot is built for governed +- **Codex**: primary workflow audience; OpenVibeCoding is built for governed Codex-style coding runs that need cases, approvals, and replayable proof. - **Claude Code**: primary workflow audience alongside Codex; the same Command Tower / Workflow Case / Proof & Replay spine applies. @@ -340,7 +357,7 @@ Use these names as ecosystem anchors, not as co-brands or partnership claims. ## Official Ecosystem Anchors When a team asks "what is real on their side?", start from the native surfaces -below before you explain where CortexPilot fits: +below before you explain where OpenVibeCoding fits: - **Codex**: - repo: [openai/codex](https://github.com/openai/codex) @@ -359,21 +376,21 @@ below before you explain where CortexPilot fits: - skills docs: [docs.openclaw.ai/tools/skills](https://docs.openclaw.ai/tools/skills) - registry/catalog: [openclaw/clawhub](https://github.com/openclaw/clawhub) -These anchors matter because CortexPilot should fit around the real ecosystem +These anchors matter because OpenVibeCoding should fit around the real ecosystem surfaces that already exist: - **Codex**: Codex now has real plugin surfaces of its own, including local - marketplace installs and a curated official directory. CortexPilot should sit + marketplace installs and a curated official directory. OpenVibeCoding should sit around Codex workflows with command tower, proof, replay, read-only MCP, and repo-owned skills or local bundle examples until a real published listing exists. - **Claude Code**: Claude Code's current native surfaces include plugins, MCP, - hooks, subagents, and project configuration. CortexPilot should wrap those + hooks, subagents, and project configuration. OpenVibeCoding should wrap those governed workflows with command tower, proof, replay, read-only MCP, and - repo-owned starter kits rather than pretending a published CortexPilot + repo-owned starter kits rather than pretending a published OpenVibeCoding marketplace listing already exists. - **OpenClaw**: adjacent integration layer with real skills and plugin/catalog - surfaces on its side, while CortexPilot stays on the review/proof/read-only + surfaces on its side, while OpenVibeCoding stays on the review/proof/read-only integration side unless a mapped native path is explicitly shipped and tested. @@ -387,13 +404,13 @@ The strongest public loop is now: 3. Reuse the Workflow Case as a **share-ready recap asset** instead of keeping it trapped inside a single operator page. -That turns CortexPilot from “a repo you can run” into “a repo you can show, +That turns OpenVibeCoding from “a repo you can run” into “a repo you can show, review, and hand off.” ## Builder Entry Points These are the current public-facing entry points for teams that want to build -around CortexPilot without pretending a full SDK platform already exists: +around OpenVibeCoding without pretending a full SDK platform already exists: - [packages/frontend-api-client/README.md](packages/frontend-api-client/README.md): thin JavaScript/TypeScript client entry points for dashboard, desktop, and web surfaces, including the repo-owned `createControlPlaneStarter(...)` bootstrap path for overview + agents + contracts + role-config integration. - [packages/frontend-api-contract/docs/README.md](packages/frontend-api-contract/docs/README.md): human-readable contract package guide for generated frontend-safe route/query/type imports. @@ -413,7 +430,7 @@ If your team needs starter assets instead of only wording, open: ## Shortest Cross-Ecosystem Adoption Order -If you are integrating CortexPilot into a coding-agent workflow, the shortest +If you are integrating OpenVibeCoding into a coding-agent workflow, the shortest truthful order is: 1. Confirm the native ecosystem surface first: @@ -421,8 +438,8 @@ truthful order is: - Claude Code overview / MCP - OpenClaw repo / skills / ClawHub 2. Use the public [compatibility matrix](https://xiaojiou176-open.github.io/CortexPilot-public/compatibility/) - to choose the right CortexPilot entrypoint. -3. Pick the first CortexPilot lane based on the job: + to choose the right OpenVibeCoding entrypoint. +3. Pick the first OpenVibeCoding lane based on the job: - [read-only MCP](https://xiaojiou176-open.github.io/CortexPilot-public/mcp/) for protocol inspection - [skills quickstart](https://xiaojiou176-open.github.io/CortexPilot-public/skills/) @@ -445,7 +462,7 @@ truthful order is: ## Best Fit -CortexPilot is a strong fit if you are building or evaluating: +OpenVibeCoding is a strong fit if you are building or evaluating: - agent workflows that need **reviewable evidence** - orchestration systems that need **replay / re-exec** @@ -454,7 +471,7 @@ CortexPilot is a strong fit if you are building or evaluating: ## Not A Fit -CortexPilot is not the right choice if you want: +OpenVibeCoding is not the right choice if you want: - a polished hosted SaaS product - write-capable agent control-plane mutations through MCP today @@ -488,7 +505,7 @@ The current stage freeze keeps two high-risk directions explicitly constrained: - **Hosted operator surface** remains **No-Go**. - `cortexpilot.ai` is still a weak marketing/holding domain, not a production front door. -- The current public contract still describes CortexPilot as source code plus +- The current public contract still describes OpenVibeCoding as source code plus operator/demo surfaces, not as a hosted service. - Reopen hosted only if the public boundary, support contract, privacy/security wording, and live front door materially change together. diff --git a/apps/dashboard/app/command-tower/page.tsx b/apps/dashboard/app/command-tower/page.tsx index 63fbea0..33acb8b 100644 --- a/apps/dashboard/app/command-tower/page.tsx +++ b/apps/dashboard/app/command-tower/page.tsx @@ -12,9 +12,9 @@ import type { CommandTowerOverviewPayload, PmSessionSummary } from "../../lib/ty import type { UiLocale } from "@cortexpilot/frontend-shared/uiCopy"; export const metadata: Metadata = { - title: "Command Tower | CortexPilot", + title: "Command Tower | OpenVibeCoding", description: - "Monitor live operator visibility, PM sessions, and governed coding-agent work from the CortexPilot Command Tower with linked Workflow Cases.", + "Monitor live operator visibility, linked Workflow Cases, blockers, and next operator actions from the OpenVibeCoding command tower cockpit.", }; async function CommandTowerHomeSection({ locale }: { locale: UiLocale }) { diff --git a/apps/dashboard/app/contracts/page.tsx b/apps/dashboard/app/contracts/page.tsx index 58d1567..ba14fe2 100644 --- a/apps/dashboard/app/contracts/page.tsx +++ b/apps/dashboard/app/contracts/page.tsx @@ -1,4 +1,5 @@ import { cookies } from "next/headers"; +import Link from "next/link"; import { getUiCopy } from "@cortexpilot/frontend-shared/uiCopy"; import { normalizeUiLocale, UI_LOCALE_STORAGE_KEY } from "@cortexpilot/frontend-shared/uiLocale"; import { Badge } from "../../components/ui/badge"; @@ -39,6 +40,64 @@ export default async function ContractsPage({ }) { const locale = await resolveDashboardLocale(); const contractsPageCopy = getUiCopy(locale).dashboard.contractsPage; + const shellCopy = + locale === "zh-CN" + ? { + actionTitle: "先做哪一步", + actionSubtitle: "先确认哪份 contract 真能继续,哪份应该转去 Proof、Role 或 Workflow 再处理。", + commandTowerAction: "打开 Command Tower", + workflowAction: "打开 Workflow Cases", + proofAction: "打开 Proof & Replay", + riskTitle: "需要先处理的 contract", + riskHint: "缺执行权、缺关联 run、或缺验收测试的 contract 优先处理。", + proofLinkedTitle: "已绑定 Proof & Replay", + proofLinkedHint: "已经能直接回到 run / proof room 的 contract 数量。", + authorityTitle: "已发布执行权", + authorityHint: "execution authority 已经明确对外可读的 contract 数量。", + nextActionTitle: "下一步", + openProofRoom: "打开关联证明室", + inspectRoleDesk: "查看角色桌", + inspectWorkflowDesk: "查看 Workflow desk", + nextActionHintWithRun: "先回到 run / proof,确认这份 contract 当前是否真能继续。", + nextActionHintWithoutRun: + "这份 contract 还没有稳定的 run 下钻口,先回到 workflow 或 role desk 看 owner、authority 和 blocker。", + } + : { + actionTitle: "Start with the next action", + actionSubtitle: + "Confirm which contracts can continue, which need proof review, and which should send you back to Workflow Cases or the role desk.", + commandTowerAction: "Open Command Tower", + workflowAction: "Open Workflow Cases", + proofAction: "Open Proof & Replay", + riskTitle: "Contracts needing triage", + riskHint: "Prioritise contracts missing execution authority, linked runs, or acceptance tests.", + proofLinkedTitle: "Contracts linked to proof", + proofLinkedHint: "Contracts that already point straight back to a run / proof room.", + authorityTitle: "Published execution authority", + authorityHint: "Contracts whose execution authority is already explicit on the first screen.", + nextActionTitle: "Next action", + triageDeskTitle: "Contract triage queue", + triageDeskSubtitle: + "Start from the contract that is missing authority, run linkage, or acceptance evidence, then open proof or the role desk from there.", + triageHeaders: { + contract: "Contract", + role: "Role", + blocker: "Next blocker", + action: "Next action", + }, + blockerReady: "Ready for proof review", + blockerMissingAuthority: "Missing execution authority", + blockerMissingRun: "Missing linked run", + blockerMissingTests: "Missing acceptance tests", + openProofRoom: "Open related proof room", + inspectRoleDesk: "Inspect role desk", + inspectWorkflowDesk: "Inspect workflow desk", + nextActionHintWithRun: + "Return to the related run first, then decide whether this contract is truly ready to continue.", + nextActionHintWithoutRun: + "This contract still needs workflow or role triage before you trust it to continue.", + secondaryDetailsSummary: "Execution details", + }; const { data: contracts, warning } = await safeLoad(fetchContracts, [] as ContractRecord[], "Contract list"); const resolvedSearchParams = (await searchParams) || {}; const query = String(resolvedSearchParams.q || "").trim().toLowerCase(); @@ -53,6 +112,12 @@ export default async function ContractsPage({ }); const visibleContracts = filteredContracts.slice(0, limit); const canApplyFilter = Boolean(query); + const contractsNeedingTriage = filteredContracts.filter((contract) => { + const acceptanceTests = Array.isArray(contract.acceptance_tests) ? contract.acceptance_tests : []; + return !contract.execution_authority || !contract.run_id || acceptanceTests.length === 0; + }).length; + const contractsWithRuns = filteredContracts.filter((contract) => Boolean(contract.run_id)).length; + const contractsWithAuthority = filteredContracts.filter((contract) => Boolean(contract.execution_authority)).length; return (
@@ -63,6 +128,42 @@ export default async function ContractsPage({ {contractsPageCopy.countsBadge(contracts.length)} +
+
+

{shellCopy.actionTitle}

+

{shellCopy.actionSubtitle}

+
+ +
+
+
+

{shellCopy.riskTitle}

+

0 ? "metric-value--warning" : "metric-value--success"}`}> + {contractsNeedingTriage} +

+

{shellCopy.riskHint}

+
+
+

{shellCopy.proofLinkedTitle}

+

{contractsWithRuns}

+

{shellCopy.proofLinkedHint}

+
+
+

{shellCopy.authorityTitle}

+

{contractsWithAuthority}

+

{shellCopy.authorityHint}

+
+
@@ -87,6 +188,65 @@ export default async function ContractsPage({ ) : null} + {visibleContracts.length > 0 ? ( + +
+
+

{shellCopy.triageDeskTitle}

+

{shellCopy.triageDeskSubtitle}

+
+
+ + + + + + + + + + + {visibleContracts.map((contract, index) => { + const acceptanceTests = Array.isArray(contract.acceptance_tests) ? contract.acceptance_tests : []; + const blockers = [ + !contract.execution_authority ? shellCopy.blockerMissingAuthority : "", + !contract.run_id ? shellCopy.blockerMissingRun : "", + acceptanceTests.length === 0 ? shellCopy.blockerMissingTests : "", + ].filter(Boolean); + const proofHref = contract.run_id ? `/runs/${contract.run_id}` : "/runs"; + const roleDeskHref = contract.assigned_role + ? `/agents?role=${encodeURIComponent(String(contract.assigned_role))}` + : "/agents"; + return ( + + + + + + + ); + })} + +
{shellCopy.triageHeaders.contract}{shellCopy.triageHeaders.role}{shellCopy.triageHeaders.blocker}{shellCopy.triageHeaders.action}
+ + {contract.task_id || contract.path || contractsPageCopy.fallbackValues.unknownContract} + + {contract.assigned_role || contractsPageCopy.fallbackValues.notAssigned} + 0 ? "warning" : "success"}> + {blockers.length > 0 ? blockers.join(" / ") : shellCopy.blockerReady} + + +
+ + +
+
+
+ ) : null} {filteredContracts.length === 0 ? (
@@ -104,6 +264,10 @@ export default async function ContractsPage({ const toolPermissions = contract.tool_permissions || {}; const permissionSummary = summarizeToolPermissions(toolPermissions); const roleBinding = contract.role_binding_read_model; + const proofHref = contract.run_id ? `/runs/${contract.run_id}` : "/runs"; + const roleDeskHref = contract.assigned_role + ? `/agents?role=${encodeURIComponent(String(contract.assigned_role))}` + : "/agents"; return ( @@ -142,44 +306,6 @@ export default async function ContractsPage({ )}
-
- {contractsPageCopy.fieldLabels.skillsBundle} - - {roleBinding - ? formatBindingReadModelLabel(roleBinding.skills_bundle_ref) - : contractsPageCopy.fallbackValues.notDerived} - -
-
- {contractsPageCopy.fieldLabels.mcpBundle} - - {roleBinding - ? formatBindingReadModelLabel(roleBinding.mcp_bundle_ref) - : contractsPageCopy.fallbackValues.notDerived} - -
-
- {contractsPageCopy.fieldLabels.runtimeBinding} - - {roleBinding - ? formatRoleBindingRuntimeSummary(roleBinding) - : contractsPageCopy.fallbackValues.notDerived} - -
-
- {contractsPageCopy.fieldLabels.runtimeCapability} - - {roleBinding?.runtime_binding?.capability?.lane || contractsPageCopy.fallbackValues.notDerived} - -
-
- {contractsPageCopy.fieldLabels.toolExecution} - - {roleBinding - ? formatRoleBindingRuntimeCapabilitySummary(roleBinding) - : contractsPageCopy.fallbackValues.notDerived} - -
{contractsPageCopy.fieldLabels.allowedPaths} @@ -208,25 +334,82 @@ export default async function ContractsPage({ )}
-
- {contractsPageCopy.fieldLabels.toolPermissions} - - {permissionSummary.length > 0 ? ( - - {permissionSummary.map((entry) => ( - {entry} - ))} - - ) : ( - {contractsPageCopy.fallbackValues.defaultPermissions} - )} - -
+
+ + + {!contract.run_id ? ( + + ) : null} +
+

+ {contract.run_id ? shellCopy.nextActionHintWithRun : shellCopy.nextActionHintWithoutRun} +

- {contractsPageCopy.fullJsonSummary} + {shellCopy.secondaryDetailsSummary}
+
+
+ {contractsPageCopy.fieldLabels.skillsBundle} + + {roleBinding + ? formatBindingReadModelLabel(roleBinding.skills_bundle_ref) + : contractsPageCopy.fallbackValues.notDerived} + +
+
+ {contractsPageCopy.fieldLabels.mcpBundle} + + {roleBinding + ? formatBindingReadModelLabel(roleBinding.mcp_bundle_ref) + : contractsPageCopy.fallbackValues.notDerived} + +
+
+ {contractsPageCopy.fieldLabels.runtimeBinding} + + {roleBinding + ? formatRoleBindingRuntimeSummary(roleBinding) + : contractsPageCopy.fallbackValues.notDerived} + +
+
+ {contractsPageCopy.fieldLabels.runtimeCapability} + + {roleBinding?.runtime_binding?.capability?.lane || contractsPageCopy.fallbackValues.notDerived} + +
+
+ {contractsPageCopy.fieldLabels.toolExecution} + + {roleBinding + ? formatRoleBindingRuntimeCapabilitySummary(roleBinding) + : contractsPageCopy.fallbackValues.notDerived} + +
+
+ {contractsPageCopy.fieldLabels.toolPermissions} + + {permissionSummary.length > 0 ? ( + + {permissionSummary.map((entry) => ( + {entry} + ))} + + ) : ( + {contractsPageCopy.fallbackValues.defaultPermissions} + )} + +
+
+

{contractsPageCopy.fullJsonSummary}

{JSON.stringify(payload || { raw_preview: contract.raw_preview }, null, 2)}
diff --git a/apps/dashboard/app/layout.tsx b/apps/dashboard/app/layout.tsx index 9350e76..4c866fe 100644 --- a/apps/dashboard/app/layout.tsx +++ b/apps/dashboard/app/layout.tsx @@ -4,9 +4,9 @@ import WebVitalsBridge from "../components/WebVitalsBridge"; import "./globals.css"; export const metadata = { - title: "CortexPilot | The command tower for AI engineering", + title: "OpenVibeCoding | The open command tower for AI engineering", description: - "Stop babysitting AI coding work. CortexPilot plans, delegates, tracks, resumes, and proves long-running engineering work across Codex and Claude Code with Workflow Cases, read-only MCP truth, and replayable proof.", + "Stop babysitting AI coding work. AI coding does not lack models. It lacks a command tower. OpenVibeCoding is the public shell for the CortexPilot runtime across Codex, Claude Code, Workflow Cases, and replayable proof.", }; export const dynamic = "force-dynamic"; diff --git a/apps/dashboard/app/page.tsx b/apps/dashboard/app/page.tsx index cac8e8f..98483f4 100644 --- a/apps/dashboard/app/page.tsx +++ b/apps/dashboard/app/page.tsx @@ -261,6 +261,18 @@ export default async function Home() { : "metric-value--success"; const warningText = firstEnglishText(warning) || "The run list is temporarily unavailable. Try again soon."; + const commandDeckTitle = + locale === "zh-CN" ? "先打开实时指挥面" : "Open the live command deck first"; + const commandDeckDescription = + locale === "zh-CN" + ? "首页先把 Command Tower、Workflow Cases 和 Proof & Replay 顶到第一层。采用路线、生态入口和 package 说明留在后面,不再抢走首屏主语义。" + : "Put Command Tower, Workflow Cases, and Proof & Replay in the first operator read. Adoption routes, ecosystem ladders, and package surfaces come after the command deck, not before it."; + const governanceDeckTitle = + locale === "zh-CN" ? "治理桌与放行控制" : "Governance desks and release controls"; + const governanceDeckDescription = + locale === "zh-CN" + ? "这些页面承接审批、contract、role 和治理控制,但它们不再定义首页第一印象。" + : "These rooms handle approvals, contracts, role posture, and release controls, but they no longer define the homepage first impression."; return (
@@ -279,9 +291,61 @@ export default async function Home() { hasRunHistory={hasRunHistory} latestFailureGovernanceHref={latestFailureGovernanceHref} locale={locale} + runningCount={runningCount} showFirstTaskGuide={!hasRunHistory} /> +
+
+
+

+ {commandDeckTitle} +

+

{commandDeckDescription}

+
+ +
+
+ + {locale === "zh-CN" ? "Live cockpit" : "Live cockpit"} + Command Tower + + {locale === "zh-CN" + ? "先看系统现在在干嘛、风险在哪、下一步该去哪。" + : "See what is moving now, what is risky, and where the next operator action belongs."} + + + + {locale === "zh-CN" ? "Durable case record" : "Durable case record"} + Workflow Cases + + {locale === "zh-CN" + ? "把 request、queue、verdict、linked runs 和 next action 绑在同一张案例桌上。" + : "Keep request, queue posture, verdict, linked runs, and the next action on one durable case desk."} + + + + {locale === "zh-CN" ? "Truth room" : "Truth room"} + Proof & Replay + + {locale === "zh-CN" + ? "先核证据、compare 和 replay,再决定是否信任或放行结果。" + : "Inspect evidence, compare posture, and replay state before you trust or promote the result."} + + +
+
+
@@ -476,27 +540,27 @@ export default async function Home() {

- Advanced / Operator + {governanceDeckTitle}

-

These entry points keep the original governance power, but they now live in an advanced zone instead of defining the public first impression.

+

{governanceDeckDescription}

- - Advanced - Command Tower - Watch sessions, alerts, and pipeline health. - - - Operator - Proof & Replay - Inspect run details, compare reruns, replay evidence, and review governed actions. - Governance Approvals and release control Enter manual approval only when a review item requires it. + + Authority + Contract desk + Inspect execution authority, bundle posture, and contract blockers before a run continues. + + + Role posture + Role desk + Check execution seats, runtime bindings, and scheduler posture without turning the homepage into a registry dump. +
diff --git a/apps/dashboard/app/runs/page.tsx b/apps/dashboard/app/runs/page.tsx index 4e21b53..ee10de8 100644 --- a/apps/dashboard/app/runs/page.tsx +++ b/apps/dashboard/app/runs/page.tsx @@ -1,5 +1,6 @@ import { cookies } from "next/headers"; import Link from "next/link"; +import type { Metadata } from "next"; import { getUiCopy } from "@cortexpilot/frontend-shared/uiCopy"; import { normalizeUiLocale, UI_LOCALE_STORAGE_KEY } from "@cortexpilot/frontend-shared/uiLocale"; @@ -15,6 +16,12 @@ type RunsPageProps = { searchParams?: Promise>; }; +export const metadata: Metadata = { + title: "Proof & Replay | OpenVibeCoding", + description: + "Inspect latest outcomes, replay posture, failure clues, and next operator actions from the OpenVibeCoding proof and replay surface.", +}; + function queryValue(value: string | string[] | undefined): string { return Array.isArray(value) ? String(value[0] || "").trim() : String(value || "").trim(); } @@ -77,6 +84,7 @@ export default async function RunsPage({ searchParams }: RunsPageProps) {
+

OpenVibeCoding / proof and replay

{runsPageCopy.title}

{runsPageCopy.subtitle}

@@ -94,26 +102,6 @@ export default async function RunsPage({ searchParams }: RunsPageProps) {

{operatorDeskNote}

-
- - - - -
- {runs.length > visibleRuns.length ? ( -

- {runsPageCopy.firstScreenLimit(visibleRuns.length)} -

- ) : null} -
@@ -147,6 +135,26 @@ export default async function RunsPage({ searchParams }: RunsPageProps) {
+
+ + + + +
+ {runs.length > visibleRuns.length ? ( +

+ {runsPageCopy.firstScreenLimit(visibleRuns.length)} +

+ ) : null} +
); diff --git a/apps/dashboard/app/workflows/[id]/page.tsx b/apps/dashboard/app/workflows/[id]/page.tsx index 3834bdc..57309a2 100644 --- a/apps/dashboard/app/workflows/[id]/page.tsx +++ b/apps/dashboard/app/workflows/[id]/page.tsx @@ -84,9 +84,9 @@ export async function generateMetadata({ const workflowId = safeDecodeParam(id); const titleSuffix = workflowId ? ` · ${workflowId}` : ""; return { - title: `Workflow Case detail${titleSuffix} | CortexPilot`, + title: `Workflow Case detail${titleSuffix} | OpenVibeCoding`, description: - "Inspect one Workflow Case across risk, queue posture, linked runs, event timeline, and the next operator action inside CortexPilot.", + "Inspect one Workflow Case across risk, queue posture, linked runs, event timeline, and the next operator action inside the OpenVibeCoding command tower.", }; } @@ -143,6 +143,7 @@ export default async function WorkflowDetailPage({
+

OpenVibeCoding / workflow case detail

{workflowDetailPageCopy.title}

{workflowDetailPageCopy.subtitle}

@@ -212,6 +213,7 @@ export default async function WorkflowDetailPage({
+

OpenVibeCoding / workflow case detail

{workflowDetailPageCopy.title}

{workflowDetailPageCopy.subtitle}

diff --git a/apps/dashboard/app/workflows/page.tsx b/apps/dashboard/app/workflows/page.tsx index 4cf44a0..0d09527 100644 --- a/apps/dashboard/app/workflows/page.tsx +++ b/apps/dashboard/app/workflows/page.tsx @@ -19,9 +19,9 @@ import { import WorkflowQueueMutationControls from "./WorkflowQueueMutationControls"; export const metadata: Metadata = { - title: "Workflow Cases | CortexPilot", + title: "Workflow Cases | OpenVibeCoding", description: - "Review Workflow Cases, queue posture, linked runs, and next operator actions inside the CortexPilot Command Tower.", + "Review Workflow Cases, queue posture, linked runs, and next operator actions inside the OpenVibeCoding command tower.", }; function statusBadgeVariant(status: string | undefined): BadgeVariant { @@ -174,6 +174,7 @@ export default async function WorkflowsPage() {
+

OpenVibeCoding / workflow desk

{workflowListPageCopy.title}

{workflowListPageCopy.subtitle}

diff --git a/apps/dashboard/components/DashboardHomeStorySections.tsx b/apps/dashboard/components/DashboardHomeStorySections.tsx index 121ccad..c34f940 100644 --- a/apps/dashboard/components/DashboardHomeStorySections.tsx +++ b/apps/dashboard/components/DashboardHomeStorySections.tsx @@ -13,6 +13,7 @@ type DashboardHomeStorySectionsProps = { hasRunHistory: boolean; latestFailureGovernanceHref: string; locale: UiLocale; + runningCount: number; showFirstTaskGuide: boolean; }; @@ -22,6 +23,7 @@ export default function DashboardHomeStorySections({ hasRunHistory, latestFailureGovernanceHref, locale, + runningCount, showFirstTaskGuide, }: DashboardHomeStorySectionsProps) { const { locale: dashboardLocale, uiCopy } = useDashboardLocale(); @@ -29,6 +31,52 @@ export default function DashboardHomeStorySections({ dashboardLocale === DEFAULT_UI_LOCALE && locale !== DEFAULT_UI_LOCALE ? getUiCopy(locale) : uiCopy; const homePhase2Copy = resolvedUiCopy.dashboard.homePhase2; const resolveHomeHref = (href: string) => resolveDashboardPublicDocsHref(href); + const shellCopy = + locale === "zh-CN" + ? { + eyebrow: "OpenVibeCoding / 指挥塔入口", + heroTitle: homePhase2Copy.heroTitle, + heroSubtitle: homePhase2Copy.heroSubtitle, + primaryAction: hasRunHistory ? "打开 Command Tower" : homePhase2Copy.startFirstTaskLabel, + secondaryAction: hasRunHistory ? homePhase2Copy.startNewTaskLabel : homePhase2Copy.viewLatestRunsLabel, + deskTitle: "第一屏控制台", + deskDescription: + "把最重要的操作面放到第一排,不再让首页像等权链接目录。", + loopTitle: "Operator loop", + loopDescription: + "先 plan,再 delegate,然后 track、resume、prove。首页应该像飞行前简报,不是站内导航页。", + methodTitle: "方法层,不抢第一屏", + methodDescription: + "Prompt / Context / Harness 仍然重要,但它们应该在 command tower 语义之后出现。", + templatesTitle: "任务包与起步模版", + templatesDescription: + "这些是起步工具,不是首页主角。先看 cockpit,再决定拿哪套模版。", + adoptionTitle: "延伸入口", + adoptionDescription: + "公共文档与生态入口保留在后排,避免抢走 command tower 的第一印象。", + } + : { + eyebrow: "OpenVibeCoding / command tower entry", + heroTitle: homePhase2Copy.heroTitle, + heroSubtitle: homePhase2Copy.heroSubtitle, + primaryAction: hasRunHistory ? "Open command tower" : homePhase2Copy.startFirstTaskLabel, + secondaryAction: hasRunHistory ? homePhase2Copy.startNewTaskLabel : homePhase2Copy.viewLatestRunsLabel, + deskTitle: "First-screen control desk", + deskDescription: + "Put the highest-leverage surfaces in the front row so the page reads like a cockpit, not a catalog of equal-weight links.", + loopTitle: "Operator loop", + loopDescription: + "Plan, delegate, track, resume, and prove. The home page should behave like a pre-flight briefing, not a router-heavy portal.", + methodTitle: "Method layer, not the hero", + methodDescription: + "Prompt / Context / Harness still matters, but it belongs below the control loop instead of competing with it.", + templatesTitle: "Task packs and launch templates", + templatesDescription: + "Templates stay available, but they should not outrank the command tower on the first screen.", + adoptionTitle: "Extended surfaces", + adoptionDescription: + "Public docs and ecosystem entry points stay in the second layer so the command tower remains the first impression.", + }; const adoptionCards = [ homePhase2Copy.integrationCards[0], homePhase2Copy.builderCards[0], @@ -36,10 +84,109 @@ export default function DashboardHomeStorySections({ homePhase2Copy.integrationCards[2], homePhase2Copy.builderCards[1], ]; + const controlDeskCards = [ + { + href: "/command-tower", + badge: locale === "zh-CN" ? "Where am I" : "Where am I", + title: locale === "zh-CN" ? "实时 Command Tower" : "Live command tower", + desc: hasRunHistory + ? locale === "zh-CN" + ? `当前有 ${runningCount} 条 live run 正在推进,先从 tower 看全局。` + : `${runningCount} live runs are moving right now. Start in the tower before drilling into lists.` + : locale === "zh-CN" + ? "第一条 run 出现后,tower 会成为你的主驾驶舱。" + : "The tower becomes the main cockpit as soon as the first delegated run exists.", + }, + { + href: failedCount > 0 ? latestFailureGovernanceHref : "/workflows", + badge: locale === "zh-CN" ? "What is blocked" : "What is blocked", + title: + failedCount > 0 + ? locale === "zh-CN" + ? "风险与堵点" + : "Risk and blockers" + : locale === "zh-CN" + ? "Workflow posture" + : "Workflow posture", + desc: + failedCount > 0 + ? locale === "zh-CN" + ? `目前有 ${failedCount} 条失败或高风险 run,先处理堵点,再决定是否继续放行。` + : `${failedCount} failed or high-risk runs need triage before you promote anything else.` + : locale === "zh-CN" + ? "当前没有明显失败面,直接从 Workflow Cases 看 owner、queue 和 next step。" + : "No obvious failure lane is dominating. Open Workflow Cases to inspect owner, queue, and next action.", + }, + { + href: "/pm", + badge: locale === "zh-CN" ? "What next" : "What next", + title: + hasRunHistory + ? locale === "zh-CN" + ? "继续派发下一项任务" + : "Queue the next task" + : locale === "zh-CN" + ? "开始第一项任务" + : "Start the first task", + desc: + hasRunHistory + ? locale === "zh-CN" + ? "确认 tower 状态后,回到 PM 入口继续派发新任务。" + : "After you scan the tower, return to PM intake to dispatch the next piece of work." + : locale === "zh-CN" + ? "先把第一条任务送进系统,再回来用 tower 观察它。" + : "Start from PM intake, then come back here to watch the first task move through the tower.", + }, + ]; + const operatorLoopCards = [ + { + href: "/pm", + badge: "1", + title: "Plan", + desc: + locale === "zh-CN" + ? "从 PM 入口写清目标、约束和验收口径。" + : "Define the objective, constraints, and acceptance bar from PM intake.", + }, + { + href: "/pm", + badge: "2", + title: "Delegate", + desc: + locale === "zh-CN" + ? "把计划变成真实队列任务,不要停在说明文档里。" + : "Turn the plan into queued work instead of leaving it as a note.", + }, + { + href: "/command-tower", + badge: "3", + title: "Track", + desc: + locale === "zh-CN" + ? "用 live tower 先看现在到底在发生什么。" + : "Use the live tower to see what is happening right now.", + }, + { + href: "/workflows", + badge: "4", + title: "Resume", + desc: + locale === "zh-CN" + ? "回到 Workflow Case,沿 durable state 继续推进。" + : "Use Workflow Cases as the durable operating record.", + }, + { + href: "/runs", + badge: "5", + title: "Prove", + desc: + locale === "zh-CN" + ? "用 run 结果、失败线索和 replay 证据收口。" + : "Use run results, failure clues, and replayable evidence to close the loop.", + }, + ]; - const primaryActionLabel = hasRunHistory - ? homePhase2Copy.startNewTaskLabel - : homePhase2Copy.startFirstTaskLabel; + const primaryActionHref = hasRunHistory ? "/command-tower" : "/pm"; const topSecondaryAction = failedCount > 0 ? { href: failureRate >= 0.5 ? "/events" : latestFailureGovernanceHref, @@ -51,8 +198,8 @@ export default function DashboardHomeStorySections({ } : hasRunHistory ? { - href: "/runs", - label: homePhase2Copy.viewLatestRunsLabel, + href: "/pm", + label: shellCopy.secondaryAction, variant: "secondary" as ButtonVariant, } : null; @@ -62,36 +209,63 @@ export default function DashboardHomeStorySections({
+

{shellCopy.eyebrow}

- {homePhase2Copy.heroTitle} + {shellCopy.heroTitle}

-

{homePhase2Copy.heroSubtitle}

+

{shellCopy.heroSubtitle}

+

+ {locale === "zh-CN" + ? "首页第一屏先回答四件事:你现在在哪、系统正在发生什么、哪里堵住了、下一步该进哪条操作路径。" + : "The first screen should answer four questions immediately: where you are, what is happening now, what is blocked, and which surface to open next."} +

-
+
-

- {homePhase2Copy.productSpineTitle} +

+ {shellCopy.deskTitle}

-

{homePhase2Copy.productSpineDescription}

+

{shellCopy.deskDescription}

- {homePhase2Copy.productSpineCards.map((item) => ( - + {controlDeskCards.map((item) => ( + + {item.badge} + {item.title} + {item.desc} + + ))} +
+
+ +
+
+
+

+ {shellCopy.loopTitle} +

+

{shellCopy.loopDescription}

+
+
+
+ {operatorLoopCards.map((item) => ( + + {item.badge} {item.title} {item.desc} @@ -103,9 +277,9 @@ export default function DashboardHomeStorySections({

- {homePhase2Copy.publicAdvantagesTitle} + {shellCopy.methodTitle}

-

{homePhase2Copy.publicAdvantagesDescription}

+

{shellCopy.methodDescription}

@@ -122,9 +296,9 @@ export default function DashboardHomeStorySections({

- {homePhase2Copy.publicTemplatesTitle} + {shellCopy.templatesTitle}

-

{homePhase2Copy.publicTemplatesDescription}

+

{shellCopy.templatesDescription}

- {/* Current progress */} -
-

{overviewCopy.currentProgressTitle}

-
- {progressCards.map((card) => ( -
-

{card.title}

-

{card.value}

-

{card.hint}

-
- ))} -
-
- {/* Recent Runs */}
diff --git a/apps/desktop/src/pages/WorkflowDetailPage.tsx b/apps/desktop/src/pages/WorkflowDetailPage.tsx index 0684ab4..adafab9 100644 --- a/apps/desktop/src/pages/WorkflowDetailPage.tsx +++ b/apps/desktop/src/pages/WorkflowDetailPage.tsx @@ -128,6 +128,35 @@ export function WorkflowDetailPage({ workflowId, onBack, onNavigateToRun, locale

{workflowData.workflow.workflow_id}

{statusLabelDesktop(workflowData.workflow.status, locale)}
+
+ + + {workflowDetailCopy.nextOperatorActionTitle} + + +
+
{recommendedAction}
+
{workflowDetailCopy.nextOperatorActionHint}
+
+
+
+ + + {workflowDetailCopy.summaryTitle} + + +
+
{workflowDetailCopy.summaryLabels.status}: {statusLabelDesktop(workflowData.workflow.status || "-", locale)}
+
{workflowDetailCopy.summaryLabels.objective}: {workflowData.workflow.objective || "-"}
+
{workflowDetailCopy.summaryLabels.owner}: {workflowData.workflow.owner_pm || "-"}
+
{workflowDetailCopy.summaryLabels.project}: {workflowData.workflow.project_key || "-"}
+
{workflowDetailCopy.summaryLabels.verdict}: {workflowData.workflow.verdict || "-"}
+
{workflowDetailCopy.summaryLabels.pmSessions}: {(workflowData.workflow.pm_session_ids || []).join(", ") || "-"}
+
{workflowDetailCopy.summaryLabels.summary}: {workflowData.workflow.summary || "-"}
+
+
+
+
- - - {workflowDetailCopy.nextOperatorActionTitle} - - -
-
{recommendedAction}
-
{workflowDetailCopy.nextOperatorActionHint}
-
-
-
- - - {workflowDetailCopy.summaryTitle} - - -
-
{workflowDetailCopy.summaryLabels.status}: {statusLabelDesktop(workflowData.workflow.status || "-", locale)}
-
{workflowDetailCopy.summaryLabels.objective}: {workflowData.workflow.objective || "-"}
-
{workflowDetailCopy.summaryLabels.owner}: {workflowData.workflow.owner_pm || "-"}
-
{workflowDetailCopy.summaryLabels.project}: {workflowData.workflow.project_key || "-"}
-
{workflowDetailCopy.summaryLabels.verdict}: {workflowData.workflow.verdict || "-"}
-
{workflowDetailCopy.summaryLabels.pmSessions}: {(workflowData.workflow.pm_session_ids || []).join(", ") || "-"}
-
{workflowDetailCopy.summaryLabels.summary}: {workflowData.workflow.summary || "-"}
-
-
-
{workflowDetailCopy.readModelTitle} diff --git a/apps/desktop/src/pages/desktop_p0_misc_controls.test.tsx b/apps/desktop/src/pages/desktop_p0_misc_controls.test.tsx index 898a37a..26a878a 100644 --- a/apps/desktop/src/pages/desktop_p0_misc_controls.test.tsx +++ b/apps/desktop/src/pages/desktop_p0_misc_controls.test.tsx @@ -166,8 +166,8 @@ describe("desktop p0 misc controls", () => { const onNavigateToRun = vi.fn(); const overview = render(); - expect(await screen.findByRole("heading", { name: /新手起步|Operator overview/ })).toBeInTheDocument(); - expect(screen.getByText(/首次使用建议先走一遍单主流程|follow the primary path/i)).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: /指挥面总览|Command deck overview|新手起步|Operator overview/ })).toBeInTheDocument(); + expect(screen.getByText(/OpenVibeCoding 的第一条主循环是|OpenVibeCoding starts with one loop/i)).toBeInTheDocument(); expect(screen.getByRole("button", { name: /主步骤 1 · 发需求|Step 1 · Brief PM/ })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /主步骤 2 · 看进度|Step 2 · Watch progress/ })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /主步骤 3 · 看案例|Step 3 · Review Workflow Cases/ })).toBeInTheDocument(); diff --git a/apps/desktop/src/pages/desktop_p1_controls.test.tsx b/apps/desktop/src/pages/desktop_p1_controls.test.tsx index 03a4abd..e198f42 100644 --- a/apps/desktop/src/pages/desktop_p1_controls.test.tsx +++ b/apps/desktop/src/pages/desktop_p1_controls.test.tsx @@ -456,7 +456,7 @@ describe("desktop p1 controls", () => { const onNavigate = vi.fn(); const agents = render(); - expect(await screen.findByRole("heading", { name: /代理|Agents/ })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: /角色桌|Role desk|代理|Agents/ })).toBeInTheDocument(); fireEvent.click(screen.getByRole("button", { name: /刷新|Refresh/ })); await waitFor(() => expect(fetchAgents).toHaveBeenCalledTimes(2)); agents.unmount(); @@ -468,7 +468,7 @@ describe("desktop p1 controls", () => { changeGates.unmount(); const contracts = render(); - expect(await screen.findByRole("heading", { name: /合约|Contracts/ })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: /合约桌|Contract desk|合约|Contracts/ })).toBeInTheDocument(); fireEvent.click(screen.getByRole("button", { name: /刷新|Refresh/ })); await waitFor(() => expect(fetchContracts).toHaveBeenCalledTimes(2)); contracts.unmount(); @@ -492,7 +492,7 @@ describe("desktop p1 controls", () => { locks.unmount(); const overview = render(); - expect(await screen.findByRole("heading", { name: /新手起步|Operator overview/ })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: /指挥面总览|Command deck overview|新手起步|Operator overview/ })).toBeInTheDocument(); const recentExceptionsSection = screen.getByRole("region", { name: /最近异常|Recent exceptions/ }); fireEvent.click(within(recentExceptionsSection).getByRole("button", { name: /查看全部异常|View all exceptions/ })); expect(onNavigate).toHaveBeenCalledWith("events"); diff --git a/apps/desktop/src/pages/overview_policies_branch.test.tsx b/apps/desktop/src/pages/overview_policies_branch.test.tsx index 7677e07..c4f01f7 100644 --- a/apps/desktop/src/pages/overview_policies_branch.test.tsx +++ b/apps/desktop/src/pages/overview_policies_branch.test.tsx @@ -45,7 +45,7 @@ describe("overview + policies low-branch coverage", () => { render(); - expect(await screen.findByRole("heading", { name: "Operator overview" })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "Command deck overview" })).toBeInTheDocument(); const failedRatio = await screen.findByText("22.0%"); expect(failedRatio.className).toContain("metric-value--danger"); const failedRunLink = await screen.findByRole("button", { name: /run-failed-/ }); @@ -75,7 +75,7 @@ describe("overview + policies low-branch coverage", () => { vi.mocked(fetchAllEvents).mockRejectedValue(new Error("events failed")); render(); - expect(await screen.findByRole("heading", { name: "Operator overview" })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "Command deck overview" })).toBeInTheDocument(); expect(await screen.findByText("Total sessions")).toBeInTheDocument(); expect(screen.getAllByText("No runs yet. Start your first request from the PM entrypoint.").length).toBeGreaterThanOrEqual(2); @@ -100,7 +100,7 @@ describe("overview + policies low-branch coverage", () => { ] as any); render(); - expect(await screen.findByRole("heading", { name: "Operator overview" })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "Command deck overview" })).toBeInTheDocument(); const failedRatio = await screen.findByText("5.0%"); expect(failedRatio.className).toContain("metric-value--success"); @@ -130,9 +130,9 @@ describe("overview + policies low-branch coverage", () => { render(); - expect(await screen.findByRole("heading", { name: "新手起步" })).toBeInTheDocument(); - expect(screen.getByText("主步骤")).toBeInTheDocument(); - expect(screen.getByText("当前进展")).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "指挥面总览" })).toBeInTheDocument(); + expect(await screen.findByText("主步骤")).toBeInTheDocument(); + expect(await screen.findByText("先看这四件事")).toBeInTheDocument(); expect(screen.getAllByText("运行中").length).toBeGreaterThan(0); expect(screen.getByText("最近异常")).toBeInTheDocument(); expect(screen.getByText("任务 task-zh 需要关注")).toBeInTheDocument(); @@ -158,7 +158,7 @@ describe("overview + policies low-branch coverage", () => { render(); - expect(await screen.findByRole("heading", { name: "新手起步" })).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "指挥面总览" })).toBeInTheDocument(); expect(screen.getByText("运行中")).toBeInTheDocument(); expect(screen.getByText("任务 task-zh 需要关注")).toBeInTheDocument(); expect(screen.getByText(/级别 WARN · Run evt-run-zh/)).toBeInTheDocument(); diff --git a/docs/README.md b/docs/README.md index 573e452..b970e43 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,6 +2,9 @@ This repository keeps its public documentation intentionally small. +The public route pages now speak as **OpenVibeCoding**, the public shell for +the CortexPilot runtime and repo surfaces. + The product spine stays stable across the docs entrypoints: - **Command Tower** for live operator visibility @@ -9,8 +12,9 @@ The product spine stays stable across the docs entrypoints: - **Proof & Replay** for evidence, compare, and replay review `docs/index.html` is the current tracked GitHub Pages landing source for the -public docs surface. `docs/README.md` remains the repo-side documentation -summary for contributors and maintainers. +OpenVibeCoding public shell. `docs/README.md` remains the repo-side +documentation summary for contributors and maintainers who still need the +CortexPilot runtime inventory. `configs/docs_nav_registry.json` is the machine source of truth for the active docs inventory. This file is the human-readable summary of that registry. diff --git a/docs/agent-starters/index.html b/docs/agent-starters/index.html index 8bf106f..47780b2 100644 --- a/docs/agent-starters/index.html +++ b/docs/agent-starters/index.html @@ -3,38 +3,38 @@ - CortexPilot | Agent starter kits for Codex, Claude Code, and OpenClaw + OpenVibeCoding | Agent starter kits for Codex, Claude Code, and OpenClaw - + - +