From 6ae5c22a4e790b465e50dca5c2752070c62a6915 Mon Sep 17 00:00:00 2001 From: Jonathanchang31 <55106972+jonathanchang31@users.noreply.github.com> Date: Tue, 9 Jun 2026 18:23:45 +0200 Subject: [PATCH 1/2] feat:turn registration readiness --- .../site/app-panels/owner-panel.tsx | 109 +++++++++++++++++- .../src/lib/registration-workspace.ts | 2 +- apps/gittensory-ui/src/routes/app.owner.tsx | 2 +- test/unit/owner-panel-source.test.ts | 22 ++++ test/unit/registration-workspace-ui.test.ts | 6 +- 5 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 test/unit/owner-panel-source.test.ts diff --git a/apps/gittensory-ui/src/components/site/app-panels/owner-panel.tsx b/apps/gittensory-ui/src/components/site/app-panels/owner-panel.tsx index f293dc090f..73a3318b6e 100644 --- a/apps/gittensory-ui/src/components/site/app-panels/owner-panel.tsx +++ b/apps/gittensory-ui/src/components/site/app-panels/owner-panel.tsx @@ -12,6 +12,7 @@ import { useApiResource } from "@/lib/api/use-api-resource"; import { buildRegistrationWorkspaceView, splitRepoFullName, + type OwnerWorkflowState, type GittensorConfigRecommendationPayload, type RegistrationReadinessPayload, type RegistrationWorkspaceView, @@ -32,6 +33,12 @@ const FRESHNESS_STATUS_MAP: Record = { + accepted: "ready", + needs_cleanup: "warn", + not_ready: "blocked", +}; + export function OwnerPanel() { const [repo, setRepo] = useState("entrius/gittensor"); const parts = splitRepoFullName(repo.trim()); @@ -119,7 +126,7 @@ export function OwnerPanel() { ); } -function RegistrationWorkspace({ +export function RegistrationWorkspace({ workspace, generatedLabel, }: { @@ -136,6 +143,9 @@ function RegistrationWorkspace({ {workspace.summary.ready ? "Ready" : "Not ready"} + + {formatWorkflowState(workspace.workflow.overallState)} + {workspace.freshness.status} @@ -163,11 +173,50 @@ function RegistrationWorkspace({ -
- - - - +
+
+
+

Guided owner workflow

+

+ {workspace.workflow.overallHeadline} +

+
+ + {formatWorkflowState(workspace.workflow.overallState)} + +
+ + {workspace.workflow.nextSteps.length > 0 ? ( +
+

Next owner actions

+
    + {workspace.workflow.nextSteps.map((step) => ( +
  • {step}
  • + ))} +
+
+ ) : null} + +
+ {workspace.workflow.buckets.map((bucket) => ( + + ))} +
+
+ +
+
+

Supporting readiness signals

+

+ Detailed lane tradeoffs and operational signals behind the guided workflow. +

+
+
+ + + + +
@@ -252,6 +301,50 @@ function WorkspaceSectionCard({ ); } +function OwnerWorkflowBucketCard({ + bucket, +}: { + bucket: RegistrationWorkspaceView["workflow"]["buckets"][number]; +}) { + return ( +
+
+
+

{bucket.title}

+

{bucket.summary}

+
+ + {formatWorkflowState(bucket.state)} + +
+ + {bucket.items.length > 0 ? ( +
    + {bucket.items.map((item) => ( +
  • +
    + {item.title} + + {formatWorkflowState(item.state)} + +
    +

    {item.summary}

    +

    + + {item.remediationKind === "manual" ? "Manual follow-up" : "Action"} + {" "} + {item.remediation} +

    +
  • + ))} +
+ ) : ( +

No follow-up needed.

+ )} +
+ ); +} + function Metric({ label, value }: { label: string; value: string }) { return (
@@ -268,3 +361,7 @@ function formatGeneratedAt(value: string) { if (!Number.isFinite(parsed)) return value; return new Date(parsed).toLocaleString(); } + +function formatWorkflowState(state: OwnerWorkflowState) { + return state.replace(/_/g, " "); +} diff --git a/apps/gittensory-ui/src/lib/registration-workspace.ts b/apps/gittensory-ui/src/lib/registration-workspace.ts index 044a303ba1..6bc7db145b 100644 --- a/apps/gittensory-ui/src/lib/registration-workspace.ts +++ b/apps/gittensory-ui/src/lib/registration-workspace.ts @@ -457,7 +457,7 @@ export function buildRegistrationOwnerWorkflow( docsItems.push({ id: "docs-crawl", title: "Onboarding docs", - state: "needs_cleanup", + state: "accepted", summary: docs.note, remediation: "Manually verify CONTRIBUTING.md, README onboarding steps, and issue templates in GitHub; remote doc crawling is not enabled in this signal yet.", diff --git a/apps/gittensory-ui/src/routes/app.owner.tsx b/apps/gittensory-ui/src/routes/app.owner.tsx index 04f4ed4955..a9a1d2b971 100644 --- a/apps/gittensory-ui/src/routes/app.owner.tsx +++ b/apps/gittensory-ui/src/routes/app.owner.tsx @@ -13,7 +13,7 @@ function OwnerRoute() {
diff --git a/test/unit/owner-panel-source.test.ts b/test/unit/owner-panel-source.test.ts new file mode 100644 index 0000000000..10521cc7de --- /dev/null +++ b/test/unit/owner-panel-source.test.ts @@ -0,0 +1,22 @@ +import { readFileSync } from "node:fs"; + +import { describe, expect, it } from "vitest"; + +const ownerPanelSource = readFileSync( + "apps/gittensory-ui/src/components/site/app-panels/owner-panel.tsx", + "utf8", +); + +describe("owner panel workflow surface", () => { + it("renders the guided owner workflow as the primary section", () => { + expect(ownerPanelSource).toContain("Guided owner workflow"); + expect(ownerPanelSource).toContain("Next owner actions"); + expect(ownerPanelSource).toContain("Supporting readiness signals"); + }); + + it("shows workflow bucket state pills and remediation labels", () => { + expect(ownerPanelSource).toContain("formatWorkflowState"); + expect(ownerPanelSource).toContain("Manual follow-up"); + expect(ownerPanelSource).toContain('item.remediationKind === "manual" ? "Manual follow-up" : "Action"'); + }); +}); diff --git a/test/unit/registration-workspace-ui.test.ts b/test/unit/registration-workspace-ui.test.ts index 2f39cdc323..ef51d91515 100644 --- a/test/unit/registration-workspace-ui.test.ts +++ b/test/unit/registration-workspace-ui.test.ts @@ -164,10 +164,10 @@ describe("registration workspace UI helpers", () => { "maintainer_capacity", ]); const docs = workflow.buckets.find((bucket) => bucket.id === "docs_onboarding"); - expect(docs?.state).toBe("needs_cleanup"); + expect(docs?.state).toBe("accepted"); expect(docs?.items[0]?.remediationKind).toBe("manual"); - expect(workflow.overallState).toBe("needs_cleanup"); - expect(workflow.nextSteps.length).toBeGreaterThan(0); + expect(workflow.overallState).toBe("accepted"); + expect(workflow.nextSteps).toEqual([]); }); it("blocked readiness maps workflow to not ready with concrete blocker remediation", () => { From a7fa793e6093e06e4660235af59600357b89ee66 Mon Sep 17 00:00:00 2001 From: Jonathanchang31 <55106972+jonathanchang31@users.noreply.github.com> Date: Wed, 10 Jun 2026 15:57:03 +0200 Subject: [PATCH 2/2] fix(tests): keep approved PR fixtures recent --- test/unit/contributor-open-pr-monitor.test.ts | 7 +++++-- test/unit/pending-pr-scenarios.test.ts | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/unit/contributor-open-pr-monitor.test.ts b/test/unit/contributor-open-pr-monitor.test.ts index 81ba03fb3b..205197512c 100644 --- a/test/unit/contributor-open-pr-monitor.test.ts +++ b/test/unit/contributor-open-pr-monitor.test.ts @@ -34,7 +34,10 @@ const maintainerRole: RoleContext = { guidance: "maintainer", }; +const recentDate = () => new Date(Date.now() - 2 * 86_400_000).toISOString(); + function pr(overrides: Partial & Pick): PullRequestRecord { + const recent = recentDate(); return { repoFullName: "entrius/allways-ui", title: `PR #${overrides.number}`, @@ -42,8 +45,8 @@ function pr(overrides: Partial & Pick new Date(Date.now() - 2 * 86_400_000).toISOString(); + function pr(overrides: Partial & Pick): PullRequestRecord { + const recent = recentDate(); return { repoFullName: "entrius/allways-ui", title: `PR #${overrides.number}`, @@ -42,8 +45,8 @@ function pr(overrides: Partial & Pick