yadflow 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -2
- package/README.md +65 -22
- package/bin/yad.mjs +27 -1
- package/cli/docs.mjs +298 -0
- package/cli/doctor.mjs +1 -0
- package/cli/manifest.mjs +23 -2
- package/cli/ship.mjs +37 -0
- package/docs/index.html +44 -13
- package/package.json +2 -2
- package/skills/sdlc/config.yaml +26 -2
- package/skills/sdlc/install.sh +1 -1
- package/skills/sdlc/module-help.csv +11 -4
- package/skills/yad-checks/references/check-gates.md +58 -2
- package/skills/yad-checks/templates/checks/commit-message.sh +82 -0
- package/skills/yad-checks/templates/github/yad-checks.yml +27 -0
- package/skills/yad-checks/templates/github/yad-hub-checks.yml +36 -0
- package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +20 -0
- package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +39 -0
- package/skills/yad-commit/SKILL.md +66 -0
- package/skills/yad-connect-docs/SKILL.md +132 -0
- package/skills/yad-connect-docs/references/docs-registry.md +74 -0
- package/skills/yad-docs/SKILL.md +159 -0
- package/skills/yad-docs/references/data-mapping.md +75 -0
- package/skills/yad-docs/references/theme-map.md +69 -0
- package/skills/yad-docs/templates/app/README.md +31 -0
- package/skills/yad-docs/templates/app/eslint.config.js +23 -0
- package/skills/yad-docs/templates/app/index.html +17 -0
- package/skills/yad-docs/templates/app/package-lock.json +4030 -0
- package/skills/yad-docs/templates/app/package.json +35 -0
- package/skills/yad-docs/templates/app/public/favicon.svg +28 -0
- package/skills/yad-docs/templates/app/public/logo.svg +39 -0
- package/skills/yad-docs/templates/app/public/vite.svg +1 -0
- package/skills/yad-docs/templates/app/src/App.tsx +98 -0
- package/skills/yad-docs/templates/app/src/components/Auth/LoginPage.tsx +101 -0
- package/skills/yad-docs/templates/app/src/components/Canvas/AnimatedMessage.tsx +101 -0
- package/skills/yad-docs/templates/app/src/components/Canvas/ConnectionLine.tsx +90 -0
- package/skills/yad-docs/templates/app/src/components/Canvas/FlowCanvas.tsx +216 -0
- package/skills/yad-docs/templates/app/src/components/Canvas/SystemComponent.tsx +153 -0
- package/skills/yad-docs/templates/app/src/components/Controls/PlaybackBar.tsx +284 -0
- package/skills/yad-docs/templates/app/src/components/Controls/StepDetail.tsx +167 -0
- package/skills/yad-docs/templates/app/src/components/DetailPanel/HandlerLogicSnippet.tsx +41 -0
- package/skills/yad-docs/templates/app/src/components/DetailPanel/RequestPayloadPreview.tsx +46 -0
- package/skills/yad-docs/templates/app/src/components/DetailPanel/RightPanel.tsx +88 -0
- package/skills/yad-docs/templates/app/src/components/DetailPanel/StatusCard.tsx +76 -0
- package/skills/yad-docs/templates/app/src/components/DetailPanel/TriggerEventCard.tsx +45 -0
- package/skills/yad-docs/templates/app/src/components/DocLayout/DocPageShell.tsx +80 -0
- package/skills/yad-docs/templates/app/src/components/DocLayout/DocSectionCard.tsx +55 -0
- package/skills/yad-docs/templates/app/src/components/DocLayout/DocTableOfContents.tsx +79 -0
- package/skills/yad-docs/templates/app/src/components/DocLayout/RoleCard.tsx +67 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/ApiReferenceSection.tsx +108 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/CancelabilitySection.tsx +73 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/CriticalRunbookSection.tsx +177 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/DataMigrationSection.tsx +102 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/DbSchemaSection.tsx +98 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/DeploymentGuideSection.tsx +104 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/DriverIntegrationSection.tsx +127 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/ExecutiveSummarySection.tsx +69 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/FlowOverviewSection.tsx +73 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/FlowPathsChecklistSection.tsx +96 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/MiddlewareChainSection.tsx +107 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/MonitoringAlertingSection.tsx +106 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/NotificationLocalizationSection.tsx +102 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/PMRoadmapSection.tsx +133 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/PerformanceTestingSection.tsx +91 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/RiderIntegrationSection.tsx +99 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/SecuritySection.tsx +74 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/StatusMachineSection.tsx +90 -0
- package/skills/yad-docs/templates/app/src/components/DocSections/TestPlanSection.tsx +163 -0
- package/skills/yad-docs/templates/app/src/components/Logs/SystemLogsTerminal.tsx +126 -0
- package/skills/yad-docs/templates/app/src/components/Navigation/TopNavBar.tsx +90 -0
- package/skills/yad-docs/templates/app/src/components/Reference/BullMQJobsList.tsx +60 -0
- package/skills/yad-docs/templates/app/src/components/Reference/DecisionTreeView.tsx +49 -0
- package/skills/yad-docs/templates/app/src/components/Reference/DeeplinkActionsChips.tsx +69 -0
- package/skills/yad-docs/templates/app/src/components/Reference/DriverUIStatesTable.tsx +61 -0
- package/skills/yad-docs/templates/app/src/components/Reference/FeatureFlagMatrix.tsx +73 -0
- package/skills/yad-docs/templates/app/src/components/Reference/RiderUIStatesTable.tsx +61 -0
- package/skills/yad-docs/templates/app/src/components/Reference/RulesLegendPanel.tsx +217 -0
- package/skills/yad-docs/templates/app/src/components/Reference/StakeholderToggle.tsx +41 -0
- package/skills/yad-docs/templates/app/src/components/Reference/TroubleshootingSection.tsx +93 -0
- package/skills/yad-docs/templates/app/src/components/Sidebar/PathSelector.tsx +148 -0
- package/skills/yad-docs/templates/app/src/components/Sidebar/SidebarFooter.tsx +40 -0
- package/skills/yad-docs/templates/app/src/components/Sidebar/StepList.tsx +234 -0
- package/skills/yad-docs/templates/app/src/components/shared/Badge.tsx +28 -0
- package/skills/yad-docs/templates/app/src/components/shared/CommandPalette.tsx +213 -0
- package/skills/yad-docs/templates/app/src/components/shared/Icon.tsx +21 -0
- package/skills/yad-docs/templates/app/src/components/shared/Tooltip.tsx +42 -0
- package/skills/yad-docs/templates/app/src/data/components.ts +74 -0
- package/skills/yad-docs/templates/app/src/data/docSections.ts +231 -0
- package/skills/yad-docs/templates/app/src/data/paths.ts +2319 -0
- package/skills/yad-docs/templates/app/src/data/referenceData.ts +392 -0
- package/skills/yad-docs/templates/app/src/data/roles.ts +145 -0
- package/skills/yad-docs/templates/app/src/data/types.ts +79 -0
- package/skills/yad-docs/templates/app/src/hooks/useAnimationQueue.ts +41 -0
- package/skills/yad-docs/templates/app/src/hooks/usePlayback.ts +100 -0
- package/skills/yad-docs/templates/app/src/hooks/useStakeholderFilter.ts +10 -0
- package/skills/yad-docs/templates/app/src/index.css +121 -0
- package/skills/yad-docs/templates/app/src/main.tsx +13 -0
- package/skills/yad-docs/templates/app/src/pages/RoleSelectPage.tsx +34 -0
- package/skills/yad-docs/templates/app/src/pages/StakeholderDocPage.tsx +98 -0
- package/skills/yad-docs/templates/app/src/pages/SubPathDetailPage.tsx +282 -0
- package/skills/yad-docs/templates/app/src/store/useAuthStore.ts +42 -0
- package/skills/yad-docs/templates/app/src/store/useFlowStore.ts +197 -0
- package/skills/yad-docs/templates/app/src/utils/iconMap.ts +46 -0
- package/skills/yad-docs/templates/app/tsconfig.app.json +28 -0
- package/skills/yad-docs/templates/app/tsconfig.json +7 -0
- package/skills/yad-docs/templates/app/tsconfig.node.json +26 -0
- package/skills/yad-docs/templates/app/vite.config.ts +10 -0
- package/skills/yad-docs-overview/SKILL.md +129 -0
- package/skills/yad-docs-overview/references/pipeline-model.md +102 -0
- package/skills/yad-docs-sync/SKILL.md +99 -0
- package/skills/yad-docs-sync/references/staleness.md +81 -0
- package/skills/yad-engineer-review/SKILL.md +86 -0
- package/skills/{yad-ship → yad-engineer-review}/references/ship-and-record.md +2 -2
- package/skills/{yad-ship → yad-engineer-review}/templates/.coderabbit.yaml +1 -1
- package/skills/yad-epic/references/state-schema.md +1 -1
- package/skills/yad-implement/SKILL.md +1 -1
- package/skills/yad-implement/references/implement-conventions.md +1 -1
- package/skills/yad-open-pr/SKILL.md +72 -0
- package/skills/yad-pr-template/templates/checks/pr-template.sh +62 -0
- package/skills/yad-pr-template/templates/checks/pr-title.sh +51 -0
- package/skills/yad-run/SKILL.md +2 -2
- package/skills/yad-run/references/run-loop.md +4 -4
- package/skills/yad-ship/SKILL.md +44 -66
- package/skills/yad-spec/SKILL.md +1 -1
|
@@ -32,6 +32,33 @@ jobs:
|
|
|
32
32
|
with: { node-version: "20" }
|
|
33
33
|
- run: bash checks/build-test-lint.sh
|
|
34
34
|
|
|
35
|
+
# Pattern gates: commit subject + PR title + PR body all follow the convention (profile: code).
|
|
36
|
+
commit-message:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
with: { fetch-depth: 0 }
|
|
41
|
+
- run: bash checks/commit-message.sh --profile code "origin/${{ github.base_ref }}"
|
|
42
|
+
|
|
43
|
+
# Pass the title via env (never interpolate untrusted ${{ }} into a run line — injection-safe).
|
|
44
|
+
pr-title:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
env:
|
|
47
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
- run: bash checks/pr-title.sh --profile code "$PR_TITLE"
|
|
51
|
+
|
|
52
|
+
pr-template:
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
env:
|
|
55
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- run: |
|
|
59
|
+
body="$(mktemp)"; printf '%s' "$PR_BODY" > "$body"
|
|
60
|
+
bash checks/pr-template.sh --profile code "$body"
|
|
61
|
+
|
|
35
62
|
# No unverified commits from unverified users: platform-Verified signature + allowlisted author.
|
|
36
63
|
verified-commits:
|
|
37
64
|
runs-on: ubuntu-latest
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# yad-managed: yad-checks
|
|
2
|
+
# Pattern gates for the PRODUCT HUB: every PR (including the front-half review/EP-* PRs) must follow
|
|
3
|
+
# the hub conventions — Conventional-Commits commit subjects, a `review: <artifact> (EP-<slug>)` PR
|
|
4
|
+
# title, and a PR body that uses the hub artifact-review template. They run with `--profile hub`.
|
|
5
|
+
# Standalone workflow so it never collides with the code-repo yad-checks workflow.
|
|
6
|
+
name: yad-hub-checks
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: ["**"]
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
commit-message:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with: { fetch-depth: 0 }
|
|
17
|
+
- run: bash checks/commit-message.sh --profile hub "origin/${{ github.base_ref }}"
|
|
18
|
+
|
|
19
|
+
# Pass the title via env (never interpolate untrusted ${{ }} into a run line — injection-safe).
|
|
20
|
+
pr-title:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
env:
|
|
23
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- run: bash checks/pr-title.sh --profile hub "$PR_TITLE"
|
|
27
|
+
|
|
28
|
+
pr-template:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
env:
|
|
31
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- run: |
|
|
35
|
+
body="$(mktemp)"; printf '%s' "$PR_BODY" > "$body"
|
|
36
|
+
bash checks/pr-template.sh --profile hub "$body"
|
|
@@ -45,6 +45,26 @@ yad-build-test-lint:
|
|
|
45
45
|
script:
|
|
46
46
|
- bash checks/build-test-lint.sh
|
|
47
47
|
|
|
48
|
+
# Pattern gates: commit subject + MR title + MR body all follow the convention (profile: code).
|
|
49
|
+
yad-commit-message:
|
|
50
|
+
extends: .sdlc_mr_only
|
|
51
|
+
needs: []
|
|
52
|
+
script:
|
|
53
|
+
- bash checks/commit-message.sh --profile code "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
|
|
54
|
+
|
|
55
|
+
yad-pr-title:
|
|
56
|
+
extends: .sdlc_mr_only
|
|
57
|
+
needs: []
|
|
58
|
+
script:
|
|
59
|
+
- bash checks/pr-title.sh --profile code "$CI_MERGE_REQUEST_TITLE"
|
|
60
|
+
|
|
61
|
+
yad-pr-template:
|
|
62
|
+
extends: .sdlc_mr_only
|
|
63
|
+
needs: []
|
|
64
|
+
script:
|
|
65
|
+
- body="$(mktemp)"; printf '%s' "$CI_MERGE_REQUEST_DESCRIPTION" > "$body"
|
|
66
|
+
- bash checks/pr-template.sh --profile code "$body"
|
|
67
|
+
|
|
48
68
|
# No unverified commits from unverified users: platform-Verified signature + allowlisted author.
|
|
49
69
|
# Needs a CI/CD variable GITLAB_TOKEN (or SDLC_API_TOKEN) with read_api scope — CI_JOB_TOKEN cannot
|
|
50
70
|
# read the commit-signature API. Without it the job FAILS closed with guidance.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# yad-managed-include: yad-checks
|
|
2
|
+
# Pattern gates for the PRODUCT HUB, as an INCLUDABLE fragment. Pulled into the hub's root
|
|
3
|
+
# .gitlab-ci.yml via:
|
|
4
|
+
# include:
|
|
5
|
+
# - local: '.gitlab/ci/yad-hub-checks.yml'
|
|
6
|
+
# Every MR (including the front-half review/EP-* MRs) must follow the hub conventions — a
|
|
7
|
+
# Conventional-Commits commit subject, a `review: <artifact> (EP-<slug>)` MR title, and an MR body
|
|
8
|
+
# that uses the hub artifact-review template. They run with `--profile hub`.
|
|
9
|
+
# Job names are yad-hub-prefixed so they coexist with any code-repo fragment in one pipeline; jobs use
|
|
10
|
+
# `needs: []` and no `stage:` so a foreign `stages:` list can neither break nor reorder them.
|
|
11
|
+
default:
|
|
12
|
+
image: node:20
|
|
13
|
+
tags: [$YAD_RUNNER_TAGS]
|
|
14
|
+
|
|
15
|
+
.yad_hub_mr_only:
|
|
16
|
+
rules:
|
|
17
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
18
|
+
|
|
19
|
+
variables:
|
|
20
|
+
GIT_DEPTH: "0" # full history so the commit gate can diff against the target branch
|
|
21
|
+
|
|
22
|
+
yad-hub-commit-message:
|
|
23
|
+
extends: .yad_hub_mr_only
|
|
24
|
+
needs: []
|
|
25
|
+
script:
|
|
26
|
+
- bash checks/commit-message.sh --profile hub "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
|
|
27
|
+
|
|
28
|
+
yad-hub-pr-title:
|
|
29
|
+
extends: .yad_hub_mr_only
|
|
30
|
+
needs: []
|
|
31
|
+
script:
|
|
32
|
+
- bash checks/pr-title.sh --profile hub "$CI_MERGE_REQUEST_TITLE"
|
|
33
|
+
|
|
34
|
+
yad-hub-pr-template:
|
|
35
|
+
extends: .yad_hub_mr_only
|
|
36
|
+
needs: []
|
|
37
|
+
script:
|
|
38
|
+
- body="$(mktemp)"; printf '%s' "$CI_MERGE_REQUEST_DESCRIPTION" > "$body"
|
|
39
|
+
- bash checks/pr-template.sh --profile hub "$body"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-commit
|
|
3
|
+
description: 'Build-half helper of the gated SDLC. Commit ONE staged atomic change by the conventions — a Conventional-Commits subject, the fixed trailer block (Task → Contract-Change → Co-Authored-By), and an atomic-file guard (≤3 files). The human git author OWNS the commit; an assisting AI is recorded only as a Co-Authored-By footer, chosen per-commit with --ai (claude|copilot|cursor|coderabbit|none — default none, human-only). Drives the zero-dependency `yad commit` CLI; never auto-advances. Use when the user says "commit this", "commit by convention", or "make an atomic commit".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Commit by Convention (build-half helper)
|
|
7
|
+
|
|
8
|
+
**Goal:** Turn ONE staged atomic change into a single commit that satisfies the project conventions
|
|
9
|
+
(`CONTRIBUTING.md` / `config.yaml` `build`): a Conventional-Commits subject, the fixed trailer order
|
|
10
|
+
`Task → Contract-Change → Co-Authored-By`, and the atomic-file guard. This is the standalone commit
|
|
11
|
+
step — the same engine `yad-implement` and `yad-ship` use. It **never auto-advances**; it just commits.
|
|
12
|
+
|
|
13
|
+
## Conventions
|
|
14
|
+
|
|
15
|
+
- Run **inside the repo holding the staged change** — a code repo under
|
|
16
|
+
`{project-root}/demo-repos/<repo>/`, or the product hub itself. Use absolute paths.
|
|
17
|
+
- **Stage first.** Only the staged (`git add`) atomic change is committed. The guard refuses more than
|
|
18
|
+
`ATOMIC_FILE_LIMIT` (3) staged files unless `--force` — split the change instead.
|
|
19
|
+
- **Subject** — `<type>: <lowercase imperative description, no trailing period>`; types are
|
|
20
|
+
`feat|fix|docs|refactor|test|perf|build|ci|chore|revert`; proper nouns/acronyms keep their case.
|
|
21
|
+
- **Task trailer** — required on a code repo (anchors the `spec-link` + `commit-message` gates). Given
|
|
22
|
+
with `--task`, else derived from the branch (`feat/<story>-<task>-…`). Hub commits are not
|
|
23
|
+
task-scoped, so the trailer is optional there.
|
|
24
|
+
- **Contract-Change trailer** — `--contract-change` only when the diff touches the locked contract
|
|
25
|
+
surface; it routes the change back to the architecture gate.
|
|
26
|
+
- **AI co-author footer** — `--ai <id>` records the assisting tool as a `Co-Authored-By` trailer. The
|
|
27
|
+
human is always the author; `--ai none` (the default) is an explicit human-only commit.
|
|
28
|
+
|
|
29
|
+
## Inputs
|
|
30
|
+
|
|
31
|
+
- `type` — Conventional-Commits type (required).
|
|
32
|
+
- `message` — the subject text (required), `-m "<subject>"`.
|
|
33
|
+
- `ai` — co-author footer: `claude|copilot|cursor|coderabbit|none` (default `none`).
|
|
34
|
+
- `task` — Task trailer (optional; derived from the branch when omitted).
|
|
35
|
+
- `contractChange` — flag; mark the contract surface touched.
|
|
36
|
+
|
|
37
|
+
## On Activation
|
|
38
|
+
|
|
39
|
+
### Step 1 — Confirm the atomic stage
|
|
40
|
+
Confirm the change is staged and stays within the file boundary (≤3 files where possible). If more is
|
|
41
|
+
staged, split it into separate commits rather than passing `--force`.
|
|
42
|
+
|
|
43
|
+
### Step 2 — Commit by convention
|
|
44
|
+
Run the CLI from the repo root:
|
|
45
|
+
```
|
|
46
|
+
yad commit --type <type> -m "<subject>" [--ai <id>] [--task <id>] [--contract-change] [--dry-run]
|
|
47
|
+
```
|
|
48
|
+
Use `--dry-run` first to preview the exact message (subject + trailer block) without committing. The
|
|
49
|
+
CLI validates the type, rejects a trailing period, and emits the trailers in the fixed order.
|
|
50
|
+
|
|
51
|
+
### Step 3 — Stop (no auto-advance)
|
|
52
|
+
Report what was committed (files + Task). If `--contract-change` was set, note that it routes back to
|
|
53
|
+
the architecture gate. To also open the PR/MR in the same step, use `yad-ship`.
|
|
54
|
+
|
|
55
|
+
## Hard rules
|
|
56
|
+
|
|
57
|
+
- **One staged atomic change = one commit.** Never bundle; never exceed the file boundary silently.
|
|
58
|
+
- **The human author owns the commit.** The AI is only a `Co-Authored-By` footer, chosen per-commit.
|
|
59
|
+
- **Trailer order is fixed:** `Task → Contract-Change → Co-Authored-By`.
|
|
60
|
+
- **Never widen the contract here.** A contract touch is flagged (`--contract-change`), not hidden.
|
|
61
|
+
|
|
62
|
+
## Reference
|
|
63
|
+
- Branch/commit conventions + the file-boundary rule: `../yad-implement/references/implement-conventions.md`.
|
|
64
|
+
- The full convention text: `CONTRIBUTING.md`; the config: `skills/sdlc/config.yaml` `build`.
|
|
65
|
+
- The gate that enforces the subject pattern: `../yad-checks/references/check-gates.md` (`commit-message`).
|
|
66
|
+
- Open the PR/MR after committing: `../yad-open-pr/SKILL.md`; both at once: `../yad-ship/SKILL.md`.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-connect-docs
|
|
3
|
+
description: 'Connects a docs/Pages publishing target to the product hub so the interactive-docs steps can build and deploy the generated SPA — not just commit its source. Registers the target into the project-wide .sdlc/docs.json (GitHub Pages / GitLab Pages / build-only), auto-detecting the platform from .sdlc/hub.json and resolving the Vite base path, with local-user auth and no stored tokens. Detects whether gh/glab is present and degrades to build-only when absent. Run at setup or any time the publish target changes. Reusable, idempotent, refreshable. Use when the user says "connect docs", "connect Pages", "refresh the docs connection", or "list the docs connection".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Connect a Docs/Pages Target (make the docs steps publishable)
|
|
7
|
+
|
|
8
|
+
**Goal:** Let the interactive-docs steps (`yad-docs` per epic, `yad-docs-overview` project-wide)
|
|
9
|
+
**build and deploy** the generated React/Vite SPA to a real URL — a GitHub Pages or GitLab Pages site —
|
|
10
|
+
instead of only committing its source. This skill **connects** a publishing target to the product hub
|
|
11
|
+
and records *how* to reach it (the platform, the publish scope, the base path) — never a credential.
|
|
12
|
+
|
|
13
|
+
This is **setup/maintenance**, not a gated front state — it never touches `.sdlc/state.json` or any
|
|
14
|
+
epic's approvals. It only writes the project-wide docs registry. `yad-docs` / `yad-docs-overview`
|
|
15
|
+
consume it: when a target is connected, they theme + generate the site and drive `yad docs deploy`;
|
|
16
|
+
when nothing is connected (`target: "none"`), they still generate and **npm-build** the site but stop
|
|
17
|
+
at a local `dist/` — build-only, no publish, exactly as before.
|
|
18
|
+
|
|
19
|
+
## Conventions
|
|
20
|
+
|
|
21
|
+
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
22
|
+
- The target is **GitHub-Pages-first but pluggable** — a *publish adapter*, mirroring the GitHub/GitLab
|
|
23
|
+
platform adapter the hub already uses. `github-pages` and `gitlab-pages` are the providers; `none` →
|
|
24
|
+
build-only (deliberate, no error).
|
|
25
|
+
- The platform CLI (`gh` / `glab`) is a **subprocess**, used read/deploy-only via the user's own auth —
|
|
26
|
+
never installed by this skill, never given a token. Absent ⇒ degrade to build-only (`source:
|
|
27
|
+
"unavailable"`).
|
|
28
|
+
- Registry: `{project-root}/.sdlc/docs.json` (project-wide, shared across all epics + the overview —
|
|
29
|
+
NOT per-epic), the sibling of `.sdlc/hub.json`, `.sdlc/repos.json`, and `.sdlc/design.json`.
|
|
30
|
+
- Per-epic / overview build manifests (`docs-build.json`) are written later by `yad-docs` /
|
|
31
|
+
`yad-docs-overview`, not here. This skill describes the *connection*; it does not build.
|
|
32
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
33
|
+
|
|
34
|
+
## Inputs
|
|
35
|
+
|
|
36
|
+
- `action` — `connect` (default) | `refresh` | `list` | `disconnect`.
|
|
37
|
+
- `target` — `github-pages` | `gitlab-pages` | `none`. Default **auto-detected** from `.sdlc/hub.json`
|
|
38
|
+
`platform` (github → `github-pages`, gitlab → `gitlab-pages`, null/no hub → `none`).
|
|
39
|
+
- `scope` — `hub` (default) | `<repo-name>` | `dedicated`. Where the Pages site is published from (the
|
|
40
|
+
hub repo, one connected code repo, or a dedicated docs repo).
|
|
41
|
+
- `public` — `true` (default) | `false`. Whether the published site is public.
|
|
42
|
+
- `base_path` — optional explicit override of the Vite `base` (otherwise resolved, Step 2).
|
|
43
|
+
|
|
44
|
+
## On Activation
|
|
45
|
+
|
|
46
|
+
### Step 1 — Resolve the target + detect the platform (the publish adapter)
|
|
47
|
+
Determine the `target`. If not given, read `{project-root}/.sdlc/hub.json` `platform` and map it the same
|
|
48
|
+
way the hub bridge maps repos: `github` → `github-pages`, `gitlab` → `gitlab-pages`, `null`/no hub →
|
|
49
|
+
`none` (deliberate build-only). Reject a `target` value outside the three providers (fall back to the
|
|
50
|
+
detected default with a warning, the way `registerRepo` falls back on an unknown platform).
|
|
51
|
+
|
|
52
|
+
Then **probe the platform CLI** in the user's own session — `gh --version` / `gh auth status` for
|
|
53
|
+
GitHub, `glab --version` / `glab auth status` for GitLab. Record `source`:
|
|
54
|
+
- CLI present + authenticated → `source: "gh"` | `"glab"` (deploy can publish via the platform).
|
|
55
|
+
- CLI absent or unauthenticated → `source: "unavailable"` — record it and report that `yad-docs` will
|
|
56
|
+
**build-only** (npm build to a local `dist/`, no publish) until the CLI is available. No error — the
|
|
57
|
+
publish is purely additive, exactly like the `gh`/`glab` review bridge degrading.
|
|
58
|
+
|
|
59
|
+
**Auth is the local user's own** (`gh`/`glab`/git already on this device). The skill **stores no
|
|
60
|
+
tokens**; everything in the registry is a plain reference. Do **not** install a CLI as part of this step.
|
|
61
|
+
|
|
62
|
+
### Step 2 — Decide the publish scope + resolve the base path
|
|
63
|
+
Resolve `scope` → `publishRepo`:
|
|
64
|
+
- `hub` (default) → publish from the hub repo (read its name from `hub.json` `git_url`).
|
|
65
|
+
- `<repo-name>` → publish from that connected code repo (must exist in `.sdlc/repos.json`).
|
|
66
|
+
- `dedicated` → a dedicated docs repo the user names (recorded as `publishRepo`).
|
|
67
|
+
|
|
68
|
+
Resolve `basePath` (the Vite `base`) per the table in `references/docs-registry.md`:
|
|
69
|
+
- **GitHub *project* Pages** (a repo that is not `<user>.github.io`) serve under `/<repo>/` → `basePath =
|
|
70
|
+
"/<repo>/"`. Per-epic sites nest under `/<repo>/epics/EP-<slug>/`; the overview under `/<repo>/`.
|
|
71
|
+
- **GitHub user/org Pages** (`<user>.github.io`) and **GitLab Pages** serve at the domain root → `basePath
|
|
72
|
+
= "/"`.
|
|
73
|
+
- An explicit `base_path` input always wins (recorded verbatim, normalized to a leading + trailing `/`).
|
|
74
|
+
|
|
75
|
+
### Step 3 — Record the connection in the registry (idempotent)
|
|
76
|
+
Upsert into `{project-root}/.sdlc/docs.json` (create the file + parent `.sdlc/` if absent):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"target": "github-pages",
|
|
81
|
+
"scope": "hub",
|
|
82
|
+
"publishRepo": "<repo or hub name>",
|
|
83
|
+
"basePath": "/<repo>/",
|
|
84
|
+
"public": true,
|
|
85
|
+
"auth": "user",
|
|
86
|
+
"connectedAt": "<YYYY-MM-DD>",
|
|
87
|
+
"lastSyncedAt": "<YYYY-MM-DD>",
|
|
88
|
+
"source": "gh"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `target: "none"` records a deliberate build-only project: `{ "target": "none", "scope": "hub",
|
|
93
|
+
"publishRepo": null, "basePath": "/", "source": "unavailable", ... }`.
|
|
94
|
+
- `connect` is **idempotent** — re-running it overwrites the single connection in place (a project has
|
|
95
|
+
one docs target at a time; switching targets is just another `connect`).
|
|
96
|
+
|
|
97
|
+
### Step 4 — Report (never auto-advance)
|
|
98
|
+
Report the connected `target`, its `scope`/`publishRepo`, the resolved `basePath`, whether the platform
|
|
99
|
+
CLI is available (or that the docs steps will degrade to **build-only**), and that **`yad-docs` /
|
|
100
|
+
`yad-docs-overview` will now build + deploy here**. Nothing auto-advances; this is setup. **Do not build
|
|
101
|
+
the site here — `yad-docs` builds.**
|
|
102
|
+
|
|
103
|
+
## Other actions
|
|
104
|
+
|
|
105
|
+
- **`refresh`** — re-detect the platform CLI and re-resolve the base path (after the user authenticates a
|
|
106
|
+
session, renames the publish repo, or switches `scope`), updating `lastSyncedAt`. Same machinery as
|
|
107
|
+
`connect`. Re-detection may flip `source` between `gh`/`glab` and `unavailable` — report the change.
|
|
108
|
+
- **`list`** — print the current connection: `target`, `scope`/`publishRepo`, `basePath`, `public`, and a
|
|
109
|
+
**available/unavailable** flag for the platform CLI (best-effort, the user's own session). No target
|
|
110
|
+
connected ⇒ "build-only".
|
|
111
|
+
- **`disconnect`** — remove the registry file (or set `target: "none"`). The platform's own Pages site is
|
|
112
|
+
**never touched** — only the hub's record of it.
|
|
113
|
+
|
|
114
|
+
## Hard rules
|
|
115
|
+
|
|
116
|
+
- **Local-user auth only; store no tokens.** Connect through the user's own `gh`/`glab`/git; never embed a
|
|
117
|
+
PAT or any credential in the registry. Everything recorded is a plain reference.
|
|
118
|
+
- **Degrade gracefully.** No target / no platform CLI → the docs steps **build-only** (local `dist/`) with
|
|
119
|
+
no error. Publishing is additive, never a blocker — the same discipline as the `gh`/`glab` review bridge.
|
|
120
|
+
- **Setup, not a gate.** Never touch `.sdlc/state.json`, approvals, or the contract lock from here.
|
|
121
|
+
- **Idempotent + refreshable.** `connect`/`refresh` are safe to re-run; a project carries one docs
|
|
122
|
+
connection at a time.
|
|
123
|
+
- **Describe the connection; do not build here.** This skill records *how to reach* the target.
|
|
124
|
+
`yad-docs` / `yad-docs-overview` generate, build, and deploy the site.
|
|
125
|
+
|
|
126
|
+
## Reference
|
|
127
|
+
- Registry schema, the base-path resolution table, and the freshness/degrade rules:
|
|
128
|
+
`references/docs-registry.md`.
|
|
129
|
+
- The connect pattern this mirrors (design tool): `../yad-connect-design/SKILL.md`.
|
|
130
|
+
- The connect pattern this mirrors (code repos + hub detection): `../yad-connect-repos/SKILL.md`.
|
|
131
|
+
- The consumers — how `yad-docs` / `yad-docs-overview` build + deploy: `../yad-docs/SKILL.md`,
|
|
132
|
+
`../yad-docs-overview/SKILL.md`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# `.sdlc/docs.json` — the docs/Pages registry
|
|
2
|
+
|
|
3
|
+
Project-wide, shared across every epic's docs site **and** the project overview site (NOT per-epic).
|
|
4
|
+
The sibling of `.sdlc/hub.json`, `.sdlc/repos.json`, and `.sdlc/design.json`. Written by
|
|
5
|
+
`yad-connect-docs`; read by `yad-docs`, `yad-docs-overview`, `yad-docs-sync`, and the `yad docs` CLI.
|
|
6
|
+
Holds **no credentials** — every field is a plain reference. Auth is always the local user's own
|
|
7
|
+
`gh`/`glab`/git session.
|
|
8
|
+
|
|
9
|
+
## Schema
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"target": "github-pages | gitlab-pages | none",
|
|
14
|
+
"scope": "hub | <repo-name> | dedicated",
|
|
15
|
+
"publishRepo": "<repo or hub name>",
|
|
16
|
+
"basePath": "/<repo>/",
|
|
17
|
+
"public": true,
|
|
18
|
+
"auth": "user",
|
|
19
|
+
"connectedAt": "<YYYY-MM-DD>",
|
|
20
|
+
"lastSyncedAt": "<YYYY-MM-DD>",
|
|
21
|
+
"source": "gh | glab | unavailable"
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Field | Meaning |
|
|
26
|
+
|-------|---------|
|
|
27
|
+
| `target` | The publish adapter. `none` = deliberate build-only (no publish, no error). |
|
|
28
|
+
| `scope` | Where the Pages site publishes from: the `hub` repo, one connected `<repo-name>`, or a `dedicated` docs repo. |
|
|
29
|
+
| `publishRepo` | The concrete repo name resolved from `scope`. `null` when `target: "none"`. |
|
|
30
|
+
| `basePath` | The Vite `base` substituted into each generated site (resolution table below). Normalized to a leading + trailing `/`. |
|
|
31
|
+
| `public` | Whether the published site is public. |
|
|
32
|
+
| `auth` | Always `"user"` — local-user / platform-CLI session. No token is ever stored. |
|
|
33
|
+
| `connectedAt` / `lastSyncedAt` | ISO dates the connection was first written / last re-detected. |
|
|
34
|
+
| `source` | `gh`/`glab` when the platform CLI is present + authenticated (publish works); `unavailable` when absent (build-only). |
|
|
35
|
+
|
|
36
|
+
`target: "none"` records `{ "target": "none", "publishRepo": null, "basePath": "/", "source":
|
|
37
|
+
"unavailable", ... }`.
|
|
38
|
+
|
|
39
|
+
## Platform auto-detection (from `.sdlc/hub.json`)
|
|
40
|
+
|
|
41
|
+
When `target` is not given, map the hub's `platform` the same way `yad-connect-repos` maps a repo host:
|
|
42
|
+
|
|
43
|
+
| `hub.json` `platform` | default `target` |
|
|
44
|
+
|-----------------------|------------------|
|
|
45
|
+
| `github` | `github-pages` |
|
|
46
|
+
| `gitlab` | `gitlab-pages` |
|
|
47
|
+
| `null` / no hub.json | `none` (build-only) |
|
|
48
|
+
|
|
49
|
+
## Base-path resolution table
|
|
50
|
+
|
|
51
|
+
GitHub serves *project* Pages under a `/<repo>/` prefix, so Vite's `base` must match or every asset 404s.
|
|
52
|
+
User/org Pages and GitLab Pages serve at the domain root.
|
|
53
|
+
|
|
54
|
+
| Target + repo kind | `basePath` | Per-epic site URL | Overview site URL |
|
|
55
|
+
|--------------------|------------|-------------------|-------------------|
|
|
56
|
+
| GitHub **project** Pages (repo ≠ `<user>.github.io`) | `/<repo>/` | `/<repo>/epics/EP-<slug>/` | `/<repo>/` |
|
|
57
|
+
| GitHub **user/org** Pages (`<user>.github.io`) | `/` | `/epics/EP-<slug>/` | `/` |
|
|
58
|
+
| GitLab Pages | `/` | `/epics/EP-<slug>/` | `/` |
|
|
59
|
+
| explicit `base_path` input | as given (normalized) | nests `epics/EP-<slug>/` under it | the given base |
|
|
60
|
+
|
|
61
|
+
An explicit `base_path` input always wins. `yad-docs` substitutes `basePath` into the shell's Vite
|
|
62
|
+
config; per-epic sites append `epics/EP-<slug>/` so they nest under the overview without colliding.
|
|
63
|
+
|
|
64
|
+
## Freshness + degrade rules
|
|
65
|
+
|
|
66
|
+
- **Freshness** here is connection-level, not content-level: `lastSyncedAt` reflects the last `refresh`.
|
|
67
|
+
*Site* staleness (artifacts/repos moved, shell upgraded) is tracked separately in each site's
|
|
68
|
+
`docs-build.json` and reconciled by `yad-docs-sync` — not here.
|
|
69
|
+
- **`list`** flags the platform CLI **available/unavailable** by probing `gh auth status` / `glab auth
|
|
70
|
+
status` in the user's own session (best-effort). A flip to `unavailable` means the docs steps
|
|
71
|
+
degrade to build-only until the CLI is back.
|
|
72
|
+
- **Degrade is silent + non-blocking.** No target / no CLI ⇒ `yad-docs` still generates + npm-builds the
|
|
73
|
+
site to a local `dist/`; only the publish step is skipped. The same discipline as the design-tool MCP
|
|
74
|
+
and the `gh`/`glab` review bridge being absent.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-docs
|
|
3
|
+
description: 'Generates the per-epic interactive documentation site — a vendored React/Vite/Tailwind SPA with an animated flow canvas and role-based stakeholder doc pages — from the epic''s approved artifacts (epic, architecture, the locked contract, UI design, stories, code-context, test cases). Themes it from the design tokens, wires the docs.json base path, and drives `yad docs build/deploy` to publish to Pages (or build-only when no target). This is an OUTPUT ENRICHMENT, never a gated front state: it never mutates state.json steps, approvals, or the contract lock. Use when the user says "generate the docs site", "build the interactive docs", or "deploy the epic docs".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Author the Interactive Docs Site (per-epic, output enrichment)
|
|
7
|
+
|
|
8
|
+
**Goal:** Turn an epic's approved artifacts into a **living, interactive documentation site** — a
|
|
9
|
+
vendored React 19 + Vite 7 + Tailwind v4 SPA with an animated **flow canvas** (system components on a
|
|
10
|
+
canvas, animated messages, playback, a system-logs terminal, a right detail panel) and **role-based
|
|
11
|
+
stakeholder doc pages** (each lens → a set of doc sections). The shell is generic; the **content** is
|
|
12
|
+
generated entirely into `src/data/*.ts` and the theme into `src/index.css`.
|
|
13
|
+
|
|
14
|
+
This is an **output enrichment**, exactly like `design-links.json` / `test-links.json` — **NOT a gated
|
|
15
|
+
front state.** It **never** mutates `.sdlc/state.json` `steps[]`, `approvals.json`, or
|
|
16
|
+
`contract-lock.json`, and it never adds a `state.json` step. It reads the *approved* shape and renders
|
|
17
|
+
it; it never decides approval. When a docs target is connected (`yad-connect-docs` → `.sdlc/docs.json`)
|
|
18
|
+
the site is built + deployed; when none is, it is npm-built to a local `dist/` (build-only).
|
|
19
|
+
|
|
20
|
+
## Conventions
|
|
21
|
+
|
|
22
|
+
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
23
|
+
- Artifacts live under `{project-root}/epics/EP-<slug>/`. The generated site lives at
|
|
24
|
+
`epics/EP-<slug>/docs-site/`; its `dist/` and `node_modules/` are gitignored, the generated **source
|
|
25
|
+
is committed**.
|
|
26
|
+
- The shell template is `skills/yad-docs/templates/app/` — copied **verbatim**, never modified in place.
|
|
27
|
+
Generated data must satisfy the types in `src/data/types.ts`.
|
|
28
|
+
- The docs target is recorded in `{project-root}/.sdlc/docs.json` (`yad-connect-docs`). The per-epic
|
|
29
|
+
build manifest (the staleness baseline) is `epics/EP-<slug>/.sdlc/docs-build.json`.
|
|
30
|
+
- The actual data-file **generation** (reading artifacts → writing `src/data/*.ts`, theming
|
|
31
|
+
`index.css`) is the **AI step** inside this skill; the `yad docs` CLI only does the npm build +
|
|
32
|
+
platform deploy + staleness hashing.
|
|
33
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
34
|
+
|
|
35
|
+
## Inputs
|
|
36
|
+
|
|
37
|
+
- `epic` — `EP-<slug>` (ask if not provided).
|
|
38
|
+
- `action` — `generate` (default) | `refresh` | `deploy`.
|
|
39
|
+
- `login_gate` — `true` | `false` (default `false`). When on, the generated site gates behind a local
|
|
40
|
+
login screen (`useAuthStore`); default off (public docs).
|
|
41
|
+
|
|
42
|
+
## On Activation
|
|
43
|
+
|
|
44
|
+
### Step 1 — Resolve the epic + check the *shape* is approved (NOT the gate)
|
|
45
|
+
Resolve `EP-<slug>`. Read `.sdlc/state.json`. Require **at least** that the epic exists and its
|
|
46
|
+
`epic-review` step has `status == "done"` (so the docs never describe an *unapproved* shape) — but do
|
|
47
|
+
**NOT** require any specific `currentStep`. Docs are an enrichment that runs over whatever is approved
|
|
48
|
+
so far. **Never touch `approvals.json` or `contract-lock.json`.** If `epic-review` has not passed, stop
|
|
49
|
+
and point the user at the gate (`yad-review-gate`); do not render an unapproved epic.
|
|
50
|
+
|
|
51
|
+
### Step 1b — Open the authoring branch
|
|
52
|
+
Open the `docs/EP-<slug>` authoring branch per the shared procedure
|
|
53
|
+
(`../yad-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note if
|
|
54
|
+
`{project-root}` is not a git work tree), check out the branch if it exists, else create it from the
|
|
55
|
+
hub's default branch. Generate and commit the site source on it.
|
|
56
|
+
|
|
57
|
+
### Step 2 — Read the inputs (the data sources)
|
|
58
|
+
Load each artifact and note what it feeds (full table in `references/data-mapping.md`):
|
|
59
|
+
|
|
60
|
+
- `epic.md` → **ExecutiveSummary** + **PMRoadmap** sections.
|
|
61
|
+
- `architecture.md` → **system components** (`components.ts`) + **flow paths** + the **Deployment** and
|
|
62
|
+
**Security** doc sections.
|
|
63
|
+
- `contract.md` `CONTRACT-SURFACE` → **ApiReference** / **StatusMachine** / **DbSchema** — the
|
|
64
|
+
**authoritative** API source. The docs **cannot drift** from the locked contract; render the surface
|
|
65
|
+
exactly as locked (cross-check `contract-lock.json`'s hash matches, but never modify it).
|
|
66
|
+
- `ui-design.md` + `DESIGN.md` + `.sdlc/design-links.json` → flow-path **UI states**, the `index.css`
|
|
67
|
+
**theme**, and a **Screens** section (linking the design-tool frames when present).
|
|
68
|
+
- `stories/*.md` → **one FlowPath each** (acceptance criteria → animated `FlowStep` messages +
|
|
69
|
+
`sideEffects`).
|
|
70
|
+
- `.sdlc/repos.json` + `.sdlc/code-context/<repo>/code-map.md` (for each repo in `epic.repos`) → real
|
|
71
|
+
module/endpoint names that **enrich** the components. **Staleness:** if a repo's current HEAD ≠ its
|
|
72
|
+
registry `syncedHead`, **warn** and stamp `code-context: stale` in the manifest — suggest `yad repo
|
|
73
|
+
refresh <repo>` (a human decision); **never auto-refresh**.
|
|
74
|
+
- `test-cases.md` + `.sdlc/test-links.json` → the **TestPlan** section.
|
|
75
|
+
|
|
76
|
+
Greenfield-safe: any absent input (no design tool, no test cases, no repos) degrades that section to
|
|
77
|
+
empty/omitted with a note — never invent content.
|
|
78
|
+
|
|
79
|
+
### Step 3 — Generate the site into `epics/EP-<slug>/docs-site/`
|
|
80
|
+
Copy the shell from `templates/app/` **verbatim**, then:
|
|
81
|
+
|
|
82
|
+
1. **Generate `src/data/*.ts` deterministically** — `paths.ts`, `components.ts`, `roles.ts`,
|
|
83
|
+
`docSections.ts`, `referenceData.ts` (mapping in `references/data-mapping.md`). Sort by **stable
|
|
84
|
+
IDs** (story `S0N`, repo name, endpoint `method+path`), use a **fixed key order**, and write **NO
|
|
85
|
+
timestamps inside the data files** — so regenerating an unchanged input yields a byte-identical file
|
|
86
|
+
(the staleness hash depends on it). Data must satisfy `src/data/types.ts`
|
|
87
|
+
(`FlowPath`/`FlowStep`/`AnimatedMessage`/`SystemComponent`/`StakeholderView`, etc.).
|
|
88
|
+
2. **Derive stakeholder roles** (`roles.ts`) from the hub roster roles (`.sdlc/hub.json`) ∩ the yadflow
|
|
89
|
+
lens set (analyst / pm / architect / ux / dev / tester / reviewer / engineer) ∩ the stories' `repos:`
|
|
90
|
+
tags — each role → its relevant doc `sectionIds` + `relevantPathIds` (`references/data-mapping.md`).
|
|
91
|
+
3. **Theme the `:root` block of `src/index.css`** from the design tokens, by the 4-tier priority in
|
|
92
|
+
`references/theme-map.md`: **DESIGN.md → design.json/design-links.json palette → code-map tokens →
|
|
93
|
+
default theme** (stamp `theme: default` in the manifest when it falls through to the shell default).
|
|
94
|
+
Keep fonts Space Grotesk + Noto Sans and the `.glass-panel`/`.flow-grid`/`.code-block` utilities.
|
|
95
|
+
4. **Substitute the Vite base** from `.sdlc/docs.json` `basePath` (per-epic sites nest under
|
|
96
|
+
`/<repo>/epics/EP-<slug>/`). Read `docs.json` for the base path + target; if absent, default base
|
|
97
|
+
`/` and treat as build-only.
|
|
98
|
+
5. **Set the login-gate flag** (`login_gate`, default off).
|
|
99
|
+
|
|
100
|
+
### Step 4 — Write the build manifest (the staleness baseline)
|
|
101
|
+
Write `epics/EP-<slug>/.sdlc/docs-build.json` — the baseline `yad-docs-sync` compares against:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"builtAt": "<YYYY-MM-DD>",
|
|
106
|
+
"theme": "design.json | DESIGN.md | default",
|
|
107
|
+
"artifactHash": "<sha256 of epic.md + architecture.md + contract.md CONTRACT-SURFACE + ui-design.md + each story>",
|
|
108
|
+
"repoHeads": { "<repo>": "<HEAD sha>" },
|
|
109
|
+
"deployUrl": "<url or null>",
|
|
110
|
+
"templateVersion": "<shell template version>"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Do **NOT** add a `state.json` step — docs are an enrichment, exactly like `design-links.json`.
|
|
115
|
+
Optionally record a `docs:` line in a `DOCS.md` index under the epic.
|
|
116
|
+
|
|
117
|
+
### Step 5 — Build / deploy (`action`)
|
|
118
|
+
- `action: generate` (default) — generate the source + manifest; stop. The CLI may npm-build to verify,
|
|
119
|
+
but no publish.
|
|
120
|
+
- `action: deploy` — drive **`yad docs deploy --epic <id>`**: it npm-builds the site (`npm ci && npm run
|
|
121
|
+
build` as a subprocess, like `yad-spec` shelling `npx repomix`), ensures the Pages CI workflow is
|
|
122
|
+
present, and reports the deploy URL (publish happens via CI). **Degrades** to the local `dist/` path
|
|
123
|
+
when no platform CLI / `target: "none"` (build-only).
|
|
124
|
+
|
|
125
|
+
### Step 6 — Stop. Report (NEVER auto-advance)
|
|
126
|
+
Report: the site path (`epics/EP-<slug>/docs-site/`), the data files produced, the **theme source** (or
|
|
127
|
+
the default-theme degrade), the **deploy URL** or "build-only", and the **staleness baseline**
|
|
128
|
+
(`docs-build.json`). **NEVER auto-advance, NEVER record approval — this is not a gate.** Note any
|
|
129
|
+
`code-context: stale` warning so the human can refresh the repo cache.
|
|
130
|
+
|
|
131
|
+
## Hard rules
|
|
132
|
+
|
|
133
|
+
- **Output enrichment, never a gate.** This skill **MUST NEVER** mutate `.sdlc/state.json` `steps[]`,
|
|
134
|
+
`approvals.json`, or `contract-lock.json`, and never adds a state step — exactly how `yad-ui` writes
|
|
135
|
+
`design-links.json` without changing the locked step shape.
|
|
136
|
+
- **Docs cannot drift from the locked contract.** The contract surface is the authoritative API source;
|
|
137
|
+
render it as locked. Never edit `contract-lock.json` or the contract here.
|
|
138
|
+
- **Deterministic generation.** Stable-ID sort, fixed key order, no timestamps inside `src/data/*.ts` —
|
|
139
|
+
so an unchanged input regenerates byte-identically and the staleness hash is meaningful.
|
|
140
|
+
- **Never auto-refresh a stale repo.** HEAD ≠ `syncedHead` ⇒ warn + stamp `code-context: stale`; the
|
|
141
|
+
refresh is a human decision (`yad repo refresh`).
|
|
142
|
+
- **Degrade gracefully.** No docs target → build-only (local `dist/`). No design tokens → default theme.
|
|
143
|
+
Absent inputs → omitted sections. No error — the site is additive.
|
|
144
|
+
- **Copy the shell verbatim.** Generate only `src/data/*.ts`, the `:root` of `index.css`, and the Vite
|
|
145
|
+
base. Never hand-edit `templates/app/`.
|
|
146
|
+
|
|
147
|
+
## Reference
|
|
148
|
+
- The deterministic DESIGN-token → CSS-custom-property mapping + 4-tier priority + default fallback:
|
|
149
|
+
`references/theme-map.md`.
|
|
150
|
+
- The full artifact → data-structure table, determinism rules, and role derivation:
|
|
151
|
+
`references/data-mapping.md`.
|
|
152
|
+
- The connected docs target + base-path resolution: `../yad-connect-docs/SKILL.md`.
|
|
153
|
+
- The design tokens this themes from: `../yad-connect-design/SKILL.md`.
|
|
154
|
+
- The code-context the data enriches: `../yad-connect-repos/SKILL.md`.
|
|
155
|
+
- The authoring pattern (front-state author that writes link artifacts without gating):
|
|
156
|
+
`../yad-ui/SKILL.md`.
|
|
157
|
+
- State schema + the "Authoring branches" procedure: `../yad-epic/references/state-schema.md`.
|
|
158
|
+
- The project overview site + the staleness/CI reconciler: `../yad-docs-overview/SKILL.md`,
|
|
159
|
+
`../yad-docs-sync/SKILL.md`.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Data mapping — artifacts → `src/data/*.ts`
|
|
2
|
+
|
|
3
|
+
`yad-docs` copies the shell verbatim and **generates** the five data modules under `src/data/`. The
|
|
4
|
+
shell renders whatever these export, as long as it satisfies `src/data/types.ts`
|
|
5
|
+
(`FlowPath` / `FlowStep` / `AnimatedMessage` / `SystemComponent` / `StakeholderView` / `RoleConfig` /
|
|
6
|
+
`DocSectionConfig`). The generation is the AI step; it must be **deterministic** (rules at the bottom).
|
|
7
|
+
|
|
8
|
+
## Artifact → data-structure table
|
|
9
|
+
|
|
10
|
+
| Generated file | Exports | Fed by (artifact) | What maps |
|
|
11
|
+
|----------------|---------|-------------------|-----------|
|
|
12
|
+
| `components.ts` | `COMPONENTS: SystemComponent[]` | `architecture.md` system components + `code-map.md` module/endpoint names | each durable component → `{ id, label, icon, color, position, description }`; canvas `position` laid out deterministically; real module names from the code-map enrich `label`/`description`. |
|
|
13
|
+
| `paths.ts` | `FLOW_PATHS: FlowPath[]` | `stories/*.md` (one FlowPath each) + `architecture.md` flows | each story → one `FlowPath` (`id`, `label`, `icon`, `color`, `category`, `steps[]`); each acceptance criterion → a `FlowStep` whose `messages: AnimatedMessage[]` animate the request/response/event/job and whose `sideEffects` record jobs/notifications/pubsub. UI states (from `ui-design.md`) annotate each step. |
|
|
14
|
+
| `roles.ts` | `ROLES: RoleConfig[]` | hub roster (`.sdlc/hub.json`) + the yadflow lens set + stories' `repos:` tags | each stakeholder lens → `{ slug, label, shortLabel, icon, color, description, sectionIds, relevantPathIds }` (role derivation below). |
|
|
15
|
+
| `docSections.ts` | `DOC_SECTIONS: DocSectionConfig[]` | `epic.md`, `architecture.md`, `contract.md`, `ui-design.md`, `test-cases.md` | the ordered doc-section registry (`{ id, title, icon, iconColor, component }`); each section id is referenced from `roles.ts`. |
|
|
16
|
+
| `referenceData.ts` | the reference tables/payloads the doc-section components render | `contract.md` CONTRACT-SURFACE (authoritative) + `architecture.md` + `test-cases.md` | API reference rows, the status machine, the DB schema, feature flags, error codes, the test plan — the structured data behind the doc sections. |
|
|
17
|
+
|
|
18
|
+
## Section sources (the doc sections + their artifact)
|
|
19
|
+
|
|
20
|
+
| Doc section(s) | Artifact source |
|
|
21
|
+
|----------------|-----------------|
|
|
22
|
+
| ExecutiveSummary, PMRoadmap | `epic.md` |
|
|
23
|
+
| FlowOverview, system components, Deployment, Security | `architecture.md` |
|
|
24
|
+
| **ApiReference, StatusMachine, DbSchema** | `contract.md` **CONTRACT-SURFACE — authoritative, must not drift from `contract-lock.json`** |
|
|
25
|
+
| Rider/Driver/role UI states, Screens, the theme | `ui-design.md` + `DESIGN.md` + `design-links.json` |
|
|
26
|
+
| TestPlan, FlowPathsChecklist, ErrorCodes | `test-cases.md` + `test-links.json` |
|
|
27
|
+
|
|
28
|
+
Any absent input degrades its section to empty/omitted (greenfield-safe); never invent content. The
|
|
29
|
+
contract is rendered exactly as locked — the docs are a *view* of the locked surface, never a re-author.
|
|
30
|
+
|
|
31
|
+
## Role derivation (`roles.ts`)
|
|
32
|
+
|
|
33
|
+
A stakeholder role is generated for each lens that is **both** present in the hub roster **and** relevant
|
|
34
|
+
to this epic:
|
|
35
|
+
|
|
36
|
+
1. Start from the **yadflow lens set**: `analyst`, `pm`, `architect`, `ux`, `dev`, `tester`, `reviewer`,
|
|
37
|
+
`engineer`.
|
|
38
|
+
2. Intersect with the **hub roster** roles (`.sdlc/hub.json` `roster[].roles`) — only emit lenses the
|
|
39
|
+
team actually has (an unmapped lens is dropped, never invented).
|
|
40
|
+
3. For the `dev`/`engineer` lenses, **fan out per `repos:` tag** present across the epic's stories (e.g.
|
|
41
|
+
a `backend` dev role and a `mobile` dev role), so each repo audience gets its own integration view —
|
|
42
|
+
mirroring the reference site's per-app dev roles.
|
|
43
|
+
4. Each role maps to its relevant `sectionIds` (which doc sections it should see) + `relevantPathIds`
|
|
44
|
+
(which FlowPaths/stories touch it). Keep these stable: derive `relevantPathIds` from the stories
|
|
45
|
+
tagged with that role's repo, sorted by story id.
|
|
46
|
+
|
|
47
|
+
## Determinism rules (load-bearing — the data feeds `artifactHash`)
|
|
48
|
+
|
|
49
|
+
- **Sort by stable IDs:** stories by `S0N`, repos by name, endpoints by `method + path`, roles by lens
|
|
50
|
+
order above. Never sort by anything time- or order-of-discovery-dependent.
|
|
51
|
+
- **Fixed key order** in every emitted object (match the `types.ts` field order).
|
|
52
|
+
- **No timestamps inside `src/data/*.ts`.** Build/deploy times live only in `docs-build.json`.
|
|
53
|
+
- Colors/icons assigned to paths/components/roles come from the theme + a **fixed** lens→icon/color map
|
|
54
|
+
(Material Symbols names), not randomly — so regenerating an unchanged input yields a byte-identical
|
|
55
|
+
file, and the staleness hash only moves when an *artifact* actually moves.
|
|
56
|
+
- IDs are derived from the source IDs (story id → `FlowPath.id`, repo/module name → component `id`), never
|
|
57
|
+
freshly minted, so links stay stable across regenerations.
|
|
58
|
+
|
|
59
|
+
## The DocSection components are NOT purely data-driven — regenerate their content too
|
|
60
|
+
|
|
61
|
+
The vendored shell ships the reference app's `src/components/DocSections/*.tsx` **with hardcoded
|
|
62
|
+
booking-domain content inline** (e.g. `ApiReferenceSection.tsx` declares a literal `ENDPOINTS`
|
|
63
|
+
array). They are NOT yet wired to read everything from `referenceData.ts`. So generation has two
|
|
64
|
+
parts, both the AI step:
|
|
65
|
+
|
|
66
|
+
1. **Data files** — write `src/data/{paths,components,roles,docSections,referenceData}.ts` from the
|
|
67
|
+
artifacts (the table above).
|
|
68
|
+
2. **Section content** — for every section a role references, replace the inline constants inside the
|
|
69
|
+
matching `DocSections/<Name>Section.tsx` with this epic's content (or refactor the section to read
|
|
70
|
+
its rows from `referenceData.ts`). A section left with the reference's booking content is a bug —
|
|
71
|
+
the docs would describe the wrong system. The contract surface is the authoritative source for the
|
|
72
|
+
API/StatusMachine/DbSchema sections.
|
|
73
|
+
|
|
74
|
+
Keep both deterministic (sorted, fixed key order, no timestamps) so the build manifest hash only moves
|
|
75
|
+
when an artifact actually moves.
|