@magic-spells/constellation 0.1.0 → 0.2.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/README.md +41 -4
- package/dist/cli/index.js +62 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/update-check.d.ts +6 -0
- package/dist/cli/update-check.js +70 -0
- package/dist/cli/update-check.js.map +1 -0
- package/dist/{mcp → core}/git.d.ts +19 -0
- package/dist/{mcp → core}/git.js +59 -2
- package/dist/core/git.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/repos.d.ts +40 -0
- package/dist/core/repos.js +93 -0
- package/dist/core/repos.js.map +1 -0
- package/dist/core/resolve.js +10 -1
- package/dist/core/resolve.js.map +1 -1
- package/dist/core/scaffold.d.ts +16 -3
- package/dist/core/scaffold.js +30 -7
- package/dist/core/scaffold.js.map +1 -1
- package/dist/core/sync.d.ts +28 -0
- package/dist/core/sync.js +85 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/types.d.ts +12 -0
- package/dist/mcp/server.js +434 -38
- package/dist/mcp/server.js.map +1 -1
- package/dist/serve/server.js +28 -4
- package/dist/serve/server.js.map +1 -1
- package/docs/001-file-format.md +25 -0
- package/docs/002-mcp.md +56 -7
- package/examples/constellation/plan.md +1 -1
- package/package.json +3 -1
- package/schemas/plan.json +27 -0
- package/skill/SKILL.md +131 -1
- package/skill/methodology.md +228 -0
- package/skill/types/plan.md +19 -0
- package/viewer/dist/assets/{arc-Kj6pF3JI.js → arc-CMMRgIq9.js} +1 -1
- package/viewer/dist/assets/architecture-7EHR7CIX-Cbb-syEI.js +1 -0
- package/viewer/dist/assets/{architectureDiagram-3BPJPVTR-C5bZdErB.js → architectureDiagram-3BPJPVTR-CB5p_qlN.js} +1 -1
- package/viewer/dist/assets/{blockDiagram-GPEHLZMM-C1Q6l6fE.js → blockDiagram-GPEHLZMM-DpnMj_e6.js} +1 -1
- package/viewer/dist/assets/{c4Diagram-AAUBKEIU-BmM6Tmtq.js → c4Diagram-AAUBKEIU-f91ngVN8.js} +1 -1
- package/viewer/dist/assets/channel-C2bkEQHQ.js +1 -0
- package/viewer/dist/assets/{chunk-2J33WTMH-z09tLTpZ.js → chunk-2J33WTMH-y7Pz5tMO.js} +1 -1
- package/viewer/dist/assets/{chunk-3OPIFGDE-BynpXh1r.js → chunk-3OPIFGDE-Ir_ghIUQ.js} +1 -1
- package/viewer/dist/assets/{chunk-4BX2VUAB-CDOVuPyG.js → chunk-4BX2VUAB-BTPyM1ux.js} +1 -1
- package/viewer/dist/assets/{chunk-55IACEB6-nBwigOgn.js → chunk-55IACEB6-CtNd8e4Y.js} +1 -1
- package/viewer/dist/assets/{chunk-5ZQYHXKU-Bxe5xIy_.js → chunk-5ZQYHXKU-Dd3yz721.js} +1 -1
- package/viewer/dist/assets/{chunk-727SXJPM-DZmTgL68.js → chunk-727SXJPM-CAM8mGbv.js} +1 -1
- package/viewer/dist/assets/{chunk-AQP2D5EJ-B7wr_Owx.js → chunk-AQP2D5EJ-C3nW9Uve.js} +1 -1
- package/viewer/dist/assets/{chunk-BSJP7CBP-DbAKfVCK.js → chunk-BSJP7CBP-r6MRPvAH.js} +1 -1
- package/viewer/dist/assets/{chunk-CSCIHK7Q-C0rsBwqP.js → chunk-CSCIHK7Q-Cn-ZTxsS.js} +1 -1
- package/viewer/dist/assets/{chunk-FMBD7UC4-BAtzt0wv.js → chunk-FMBD7UC4-5axXeZJa.js} +1 -1
- package/viewer/dist/assets/{chunk-KSCS5N6A-CXXwf52I.js → chunk-KSCS5N6A-BwmNx0l0.js} +1 -1
- package/viewer/dist/assets/{chunk-L5ZTLDWV-DS4vRI1U.js → chunk-L5ZTLDWV-C2YNkUjB.js} +1 -1
- package/viewer/dist/assets/chunk-LZXEDZCA-CznuDgQD.js +2 -0
- package/viewer/dist/assets/{chunk-ND2GUHAM-CUSnPl8t.js → chunk-ND2GUHAM-CokDnghi.js} +1 -1
- package/viewer/dist/assets/{chunk-NZK2D7GU-Dh986nJk.js → chunk-NZK2D7GU-aaU0v4QE.js} +1 -1
- package/viewer/dist/assets/{chunk-O5CBEL6O-JAEZ_pS6.js → chunk-O5CBEL6O-ByfKhkZf.js} +1 -1
- package/viewer/dist/assets/chunk-QZHKN3VN-DJRjGeIo.js +1 -0
- package/viewer/dist/assets/chunk-WU5MYG2G-C63BVvr_.js +1 -0
- package/viewer/dist/assets/{chunk-XPW4576I-BwMZI0gv.js → chunk-XPW4576I-Amo3awtq.js} +1 -1
- package/viewer/dist/assets/classDiagram-4FO5ZUOK-z_bO1V-j.js +1 -0
- package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-z_bO1V-j.js +1 -0
- package/viewer/dist/assets/{cose-bilkent-S5V4N54A-NGC7gYHM.js → cose-bilkent-S5V4N54A-CO8yESCW.js} +1 -1
- package/viewer/dist/assets/{dagre-BM42HDAG-RD63uyvd.js → dagre-BM42HDAG-BnmNVNI2.js} +1 -1
- package/viewer/dist/assets/{diagram-2AECGRRQ-hwnqqCcb.js → diagram-2AECGRRQ-lcGXcbei.js} +1 -1
- package/viewer/dist/assets/{diagram-5GNKFQAL-q8EaoZSG.js → diagram-5GNKFQAL-Cj3-lPUt.js} +1 -1
- package/viewer/dist/assets/{diagram-KO2AKTUF-D4_5Qf-l.js → diagram-KO2AKTUF-CtXdRI4M.js} +1 -1
- package/viewer/dist/assets/{diagram-LMA3HP47-D8pwekFs.js → diagram-LMA3HP47-CIyLAzX7.js} +1 -1
- package/viewer/dist/assets/{diagram-OG6HWLK6-D9KinIWZ.js → diagram-OG6HWLK6-BwF4bQCv.js} +1 -1
- package/viewer/dist/assets/{dist-CFOOgrqc.js → dist-DzXuQd4N.js} +1 -1
- package/viewer/dist/assets/{erDiagram-TEJ5UH35-D0Wfq250.js → erDiagram-TEJ5UH35-DjwFw9yq.js} +1 -1
- package/viewer/dist/assets/eventmodeling-FCH6USID-BlKFmSzA.js +1 -0
- package/viewer/dist/assets/{flowDiagram-I6XJVG4X-Y2DY-Ze2.js → flowDiagram-I6XJVG4X-CzXbf7vQ.js} +1 -1
- package/viewer/dist/assets/{ganttDiagram-6RSMTGT7-BnqkeLVw.js → ganttDiagram-6RSMTGT7-BYcIhfmm.js} +1 -1
- package/viewer/dist/assets/{gitGraph-WXDBUCRP-Cft7usRT.js → gitGraph-WXDBUCRP-H8XeJ9QB.js} +1 -1
- package/viewer/dist/assets/{gitGraphDiagram-PVQCEYII-D-cYtraK.js → gitGraphDiagram-PVQCEYII-DtAPXKFK.js} +1 -1
- package/viewer/dist/assets/index-Bqs39Itl.css +2 -0
- package/viewer/dist/assets/index-DLPCG_Or.js +98 -0
- package/viewer/dist/assets/{info-J43DQDTF-Djc8Bx3F.js → info-J43DQDTF-BQScorZ0.js} +1 -1
- package/viewer/dist/assets/{infoDiagram-5YYISTIA-D-ehtyyJ.js → infoDiagram-5YYISTIA-Udl1omvH.js} +1 -1
- package/viewer/dist/assets/{ishikawaDiagram-YF4QCWOH-Ct3f6bH-.js → ishikawaDiagram-YF4QCWOH-VnfzT_hk.js} +1 -1
- package/viewer/dist/assets/{journeyDiagram-JHISSGLW-DXlULEmi.js → journeyDiagram-JHISSGLW-Btn4EVoD.js} +1 -1
- package/viewer/dist/assets/{kanban-definition-UN3LZRKU-3vE9h-R7.js → kanban-definition-UN3LZRKU-flOzWhPe.js} +1 -1
- package/viewer/dist/assets/{line-B8MygbLB.js → line-DJJ9BLuY.js} +1 -1
- package/viewer/dist/assets/{linear-CfMuM0B3.js → linear-C2SUy5ns.js} +1 -1
- package/viewer/dist/assets/{mermaid-parser.core-DzlZTbbh.js → mermaid-parser.core-xhSeYiZo.js} +2 -2
- package/viewer/dist/assets/{mermaid.core-IM-sPiyq.js → mermaid.core-DmeSIitY.js} +3 -3
- package/viewer/dist/assets/{mindmap-definition-RKZ34NQL-CMnpAq1T.js → mindmap-definition-RKZ34NQL-CCJcMKx1.js} +1 -1
- package/viewer/dist/assets/{packet-YPE3B663-D44AzgHh.js → packet-YPE3B663-DS8RscAk.js} +1 -1
- package/viewer/dist/assets/{pie-LRSECV5Y-DL8AVJH_.js → pie-LRSECV5Y-I2ZQhrNJ.js} +1 -1
- package/viewer/dist/assets/{pieDiagram-4H26LBE5-FvKK5jd7.js → pieDiagram-4H26LBE5-BS5HMs4j.js} +1 -1
- package/viewer/dist/assets/{quadrantDiagram-W4KKPZXB-CmjSkU8c.js → quadrantDiagram-W4KKPZXB-W4H8cw2_.js} +1 -1
- package/viewer/dist/assets/{radar-GUYGQ44K-BvfZTVyH.js → radar-GUYGQ44K-kf6QvSne.js} +1 -1
- package/viewer/dist/assets/{requirementDiagram-4Y6WPE33-BOjca3VH.js → requirementDiagram-4Y6WPE33-DSbuDQGQ.js} +1 -1
- package/viewer/dist/assets/{sankeyDiagram-5OEKKPKP-ANcjfNix.js → sankeyDiagram-5OEKKPKP-CH8Qr2vL.js} +1 -1
- package/viewer/dist/assets/{sequenceDiagram-3UESZ5HK-BLQ9AL7I.js → sequenceDiagram-3UESZ5HK-EugVcdad.js} +1 -1
- package/viewer/dist/assets/src-CM_9kdrU.js +1 -0
- package/viewer/dist/assets/{stateDiagram-AJRCARHV-D6CriBS6.js → stateDiagram-AJRCARHV-DiFl94Qy.js} +1 -1
- package/viewer/dist/assets/stateDiagram-v2-BHNVJYJU-BlJV8F13.js +1 -0
- package/viewer/dist/assets/{timeline-definition-PNZ67QCA-BNhWZ_DL.js → timeline-definition-PNZ67QCA-B0KW9GUN.js} +1 -1
- package/viewer/dist/assets/{treeView-BLDUP644-CY6Ph5Pu.js → treeView-BLDUP644-CAEY4mxq.js} +1 -1
- package/viewer/dist/assets/{treemap-LRROVOQU-DChSA_Qx.js → treemap-LRROVOQU-VVaEaTlU.js} +1 -1
- package/viewer/dist/assets/{vennDiagram-CIIHVFJN-C01WznAC.js → vennDiagram-CIIHVFJN-BSLGNfJd.js} +1 -1
- package/viewer/dist/assets/{wardley-L42UT6IY-BJ8uNoJu.js → wardley-L42UT6IY-C-5cXbAU.js} +1 -1
- package/viewer/dist/assets/{wardleyDiagram-YWT4CUSO-DwDEzlVm.js → wardleyDiagram-YWT4CUSO-COk4TVnQ.js} +1 -1
- package/viewer/dist/assets/{xychartDiagram-2RQKCTM6-BCvIDwU0.js → xychartDiagram-2RQKCTM6-CClGJLJp.js} +1 -1
- package/viewer/dist/index.html +3 -3
- package/dist/mcp/git.js.map +0 -1
- package/viewer/dist/assets/architecture-7EHR7CIX-CGfWeim3.js +0 -1
- package/viewer/dist/assets/channel-19IdUS_c.js +0 -1
- package/viewer/dist/assets/chunk-LZXEDZCA-CclT9MXr.js +0 -2
- package/viewer/dist/assets/chunk-QZHKN3VN-BKc_Kg2Z.js +0 -1
- package/viewer/dist/assets/chunk-WU5MYG2G-9ssTSMzt.js +0 -1
- package/viewer/dist/assets/classDiagram-4FO5ZUOK-DXv85WFd.js +0 -1
- package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-DXv85WFd.js +0 -1
- package/viewer/dist/assets/eventmodeling-FCH6USID-D3KRSuC1.js +0 -1
- package/viewer/dist/assets/index-CDR-riG2.css +0 -2
- package/viewer/dist/assets/index-DRPsTWe2.js +0 -98
- package/viewer/dist/assets/src-CAMdANUp.js +0 -1
- package/viewer/dist/assets/stateDiagram-v2-BHNVJYJU-DcTp66RQ.js +0 -1
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: constellation
|
|
3
|
-
description: Author and edit Constellation plan cards — markdown files in a constellation/ folder that model a project's architecture as a typed, connected graph. Use when creating, updating, or querying cards (API endpoints, data types, DB tables, flows, pages, etc.) in any repo with a constellation/ directory.
|
|
3
|
+
description: Author and edit Constellation plan cards — markdown files in a constellation/ folder that model a project's architecture as a typed, connected graph. Use when creating, updating, or querying cards (API endpoints, data types, DB tables, flows, pages, etc.) in any repo with a constellation/ directory, or when setting up a plan in a repo that has none yet.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Constellation cards
|
|
@@ -87,6 +87,136 @@ that's how you mark future work.
|
|
|
87
87
|
- Everything else: prose with `[[links]]`. Put relationship nuance in prose, not
|
|
88
88
|
in structure.
|
|
89
89
|
|
|
90
|
+
## Bootstrapping & auditing a plan
|
|
91
|
+
|
|
92
|
+
Act as a senior engineer and architect advising the user, not a scribe — don't assume they
|
|
93
|
+
know everything; bring expertise, flag risks, propose what's missing, and hold a high bar
|
|
94
|
+
with integrity (honest about built-vs-planned and verified-vs-assumed). But don't
|
|
95
|
+
over-engineer — there's elegance in simplicity: calibrate to the project's scope and
|
|
96
|
+
recommend the smallest change that most improves the plan. The goal is a plan they'd be
|
|
97
|
+
proud to ship — and the bar above all: if the code were deleted, the app could be rebuilt
|
|
98
|
+
from the plan alone (coverage, not volume).
|
|
99
|
+
|
|
100
|
+
No `constellation/` folder yet? Create one — `init_plan` (MCP) or `constellation init`
|
|
101
|
+
(CLI) — then build the plan from the code, working **macro→micro**:
|
|
102
|
+
|
|
103
|
+
1. **Orient** — manifest, routes, folder layout. Seed `PLAN-PROJECT` + one system `DIAGRAM`.
|
|
104
|
+
Propose a human-readable project name (folder `pyramid-server` → `Pyramid Server`) and
|
|
105
|
+
confirm it with the user — it's `plan.md`'s `name:` and the viewer's title; editable anytime.
|
|
106
|
+
2. **Follow the data** — `DB → DATATYPE → API → PAGE`; paths become `FLOW`, lifecycles `STATE`.
|
|
107
|
+
3. **Follow the user** — `ROLE` + auth `FLOW` first, then `PAGE`/`COMPONENT` and key journeys.
|
|
108
|
+
4. **Follow the edges** — `EXTERNAL`, `JOB`, `EVENT`.
|
|
109
|
+
5. **Zoom in** — detail only central or complex areas.
|
|
110
|
+
6. **Ask** — only for intent, priorities, and history the code can't reveal.
|
|
111
|
+
7. **Find gaps in the plan** — step back and hunt blind spots the user may not have
|
|
112
|
+
considered: missing unhappy paths/states, auth gaps, forgotten cross-cutting concerns
|
|
113
|
+
(security, privacy, observability, rate limits, pagination, migrations, testing). Plus a
|
|
114
|
+
quick mechanical sweep: `check_integrity` orphans, dangling refs, code-without-cards.
|
|
115
|
+
8. **Recommend** — a short, prioritized list, separating "you likely forgot this" from
|
|
116
|
+
"consider whether you need this"; speculative cards go in as `status: planned`.
|
|
117
|
+
|
|
118
|
+
Reverse-engineering shipped code: default cards to `built`, promote to `verified` only
|
|
119
|
+
after checking against the implementation. **The full method — what to read, what to ask,
|
|
120
|
+
how to find gaps and recommend tastefully — is in [`methodology.md`](./methodology.md),
|
|
121
|
+
which also backs the `bootstrap_plan` / `audit_plan` MCP prompts.** Read it before a large
|
|
122
|
+
pass.
|
|
123
|
+
|
|
124
|
+
**Orchestrate a large build.** For a non-trivial plan, after the macro pass act as the **orchestrator**: split the work into independent neighborhoods (the data, the user, the edges) and fan out a sub-agent per neighborhood in parallel — assign each card to exactly one agent (one handle = one file, so this also keeps writes to disjoint plan files and concurrent `update_card`s can't clobber), partition the research on area/file boundaries, and have them return card specs you write via batched `create_cards`/`add_connections`, then verify each agent's work and lint once. A single agent for a small plan — don't over-engineer.
|
|
125
|
+
|
|
126
|
+
## Changing code: plan-first
|
|
127
|
+
|
|
128
|
+
When the user asks to build a feature or change behavior in an area the plan covers, the
|
|
129
|
+
plan **is** the spec — so do **not** edit code first. The plan you make leads with
|
|
130
|
+
Constellation:
|
|
131
|
+
|
|
132
|
+
1. **Read the neighborhood** — `get_card` / `traverse` / `search` (`connected: "full"`) the
|
|
133
|
+
cards the change touches, so you work from the real architecture, not a guess.
|
|
134
|
+
2. **Express the end state in the plan** — add or update the cards (and `plan.md`) so they
|
|
135
|
+
describe what you're about to build, wiring every connection between the affected cards.
|
|
136
|
+
Work that doesn't exist yet is `status: planned` — honest intent, not a claim it's built.
|
|
137
|
+
3. **Get sign-off on the plan diff** — show the user that set of card changes as the
|
|
138
|
+
proposal (`git diff -- constellation/` is the diff). The plan is what they approve.
|
|
139
|
+
4. **Then bring the code up to match** — via the sync loop below.
|
|
140
|
+
5. **Reconcile at the end** — re-read the touched cards against the code, run
|
|
141
|
+
`check_integrity` to confirm no affected card is left an orphan and every intended
|
|
142
|
+
connection is set, bump `status` (`planned → building → built → verified`), commit, and
|
|
143
|
+
`set_sync_point`.
|
|
144
|
+
|
|
145
|
+
**In plan mode, read as much of the plan as you can.** The write tools are unavailable there
|
|
146
|
+
by design (the read tools — `get_card`, `list_cards`, `search`, `traverse`, `describe_type`,
|
|
147
|
+
`check_integrity`, `diff_plan`, `plan_log` — are marked read-only and stay available). Spend
|
|
148
|
+
plan mode pulling the relevant plan into context — `traverse` from the entry points with
|
|
149
|
+
`connected: "full"` — to build a strong model of the project fast, and fold the card edits
|
|
150
|
+
you intend into the plan you present. Execute those Constellation writes first, before any
|
|
151
|
+
code, once the user approves.
|
|
152
|
+
|
|
153
|
+
## Syncing the plan to code
|
|
154
|
+
|
|
155
|
+
The plan is the source of truth: you change behavior by editing the **plan first**, then
|
|
156
|
+
bringing the code up to match — never the reverse. When the user says "sync the plan" or
|
|
157
|
+
"sync the plan to the code," they mean this loop (not merely stamping the sync marker):
|
|
158
|
+
|
|
159
|
+
1. **Diff the plan** — `diff_plan` (base = the `.sync.json` marker, else `HEAD`) lists the
|
|
160
|
+
cards added / modified / removed since code was last reconciled, with the changed
|
|
161
|
+
frontmatter keys and bodies.
|
|
162
|
+
2. **Find the blast radius** — `traverse` the changed handles (`detail: "full"`) to pull in
|
|
163
|
+
every connected card the change touches: the `API` a `DATATYPE` feeds, the `PAGE`s a
|
|
164
|
+
`FLOW` crosses, the `DB` a migration implies.
|
|
165
|
+
3. **Update the code** to match those cards — contracts, schemas, routes, states, flows.
|
|
166
|
+
4. **Verify and mark** — run the project's build/tests, bump card `status` as code lands
|
|
167
|
+
(`planned → building → built`), then commit and `set_sync_point` to advance the marker.
|
|
168
|
+
|
|
169
|
+
**Orchestrate large syncs.** When the diff is large and the affected areas don't share
|
|
170
|
+
files, act as the **orchestrator** instead of editing everything yourself: partition the
|
|
171
|
+
blast radius into independent neighborhoods and hand each to a sub-agent working in
|
|
172
|
+
parallel, each given its hydrated cards and the files it owns. Split only along clean file
|
|
173
|
+
boundaries so two agents never edit the same file, **and assign each card to exactly one
|
|
174
|
+
agent** — two agents writing the same card (e.g. a shared `DATATYPE` both neighborhoods
|
|
175
|
+
touch) race, and the later `update_card` silently clobbers the earlier. Keep it to a single
|
|
176
|
+
agent when the change is small or the areas overlap. Delegating this way keeps your own context clean and lets you
|
|
177
|
+
hold the macro view of the whole change rather than drowning in file-level edits.
|
|
178
|
+
|
|
179
|
+
**Always verify the agents' work yourself once they have all finished** — re-read each
|
|
180
|
+
change against the cards it was meant to satisfy and run the project's build/tests; never
|
|
181
|
+
trust the sub-agents' reports alone. Only after that whole-plan verification passes do you
|
|
182
|
+
commit and `set_sync_point` (once, as the orchestrator).
|
|
183
|
+
|
|
184
|
+
## Connected repos (multi-repo work)
|
|
185
|
+
|
|
186
|
+
One change often spans several sibling repos (e.g. `pyramid-web`, `pyramid-server`,
|
|
187
|
+
`pyramid-mcp`). Constellation models this with **repo-level links**, not cross-repo card
|
|
188
|
+
connections: each project lists its siblings in `PLAN-PROJECT` frontmatter, and every plan
|
|
189
|
+
stays self-contained and lints on its own.
|
|
190
|
+
|
|
191
|
+
```yaml
|
|
192
|
+
# plan.md (PLAN-PROJECT) frontmatter
|
|
193
|
+
connected_repos:
|
|
194
|
+
- name: pyramid-server # the `repo` selector value (lowercase id)
|
|
195
|
+
path: ../pyramid-server # relative to this repo's root
|
|
196
|
+
description: Back-end API for Pyramid, written in Go.
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- **Declare** links with `add_connected_repo` (`reciprocate: true` also writes the reverse
|
|
200
|
+
link into the other repo — only with the user's OK, since it edits that repo). List them
|
|
201
|
+
with `list_connected_repos` or `constellation repos`; remove with `remove_connected_repo`.
|
|
202
|
+
Paths are local topology — a missing path is never a lint error, just "not reachable here."
|
|
203
|
+
- **Target** a connected repo by passing `repo: "<name>"` to any read or write tool
|
|
204
|
+
(`get_card`, `search`, `traverse`, `update_card`, `create_card`, `set_sync_point`, …); it
|
|
205
|
+
reads/writes THAT repo's plan. Omit `repo` for the current one — single-repo work is
|
|
206
|
+
unchanged.
|
|
207
|
+
- **Answer cross-repo questions two ways.** For "what does the back end's plan say," read it
|
|
208
|
+
in-process with `repo:`. For "how does the back end actually work" — real code, or the
|
|
209
|
+
connected plan can't answer — spawn a **sub-agent scoped to that repo's path** to
|
|
210
|
+
investigate and report back, and if its plan had the gap, have it fill the gap.
|
|
211
|
+
- **One change across repos:** examine each repo's affected area (`repo:` reads), write the
|
|
212
|
+
per-repo card updates with `repo:` set on **every** write (never omit it cross-repo, or the
|
|
213
|
+
write lands in the wrong repo), then fan out a per-repo implementer sub-agent — each runs
|
|
214
|
+
in plain single-repo mode inside its repo, blind to the others — and reconcile +
|
|
215
|
+
`set_sync_point` per repo.
|
|
216
|
+
|
|
217
|
+
Cards never connect across repos; the relationship between repos lives in the
|
|
218
|
+
`connected_repos` links and in your reasoning, not in card connections.
|
|
219
|
+
|
|
90
220
|
## Workflow
|
|
91
221
|
|
|
92
222
|
1. Before creating a card, check it doesn't exist: the filename is deterministic,
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Building & auditing a plan from a codebase
|
|
2
|
+
|
|
3
|
+
How to turn a repository — empty, half-built, or fully shipped — into a Constellation
|
|
4
|
+
plan, and how to keep that plan honest as the code changes. The method is the same in
|
|
5
|
+
every MCP client; in Claude Code it also backs the `bootstrap_plan` and `audit_plan`
|
|
6
|
+
prompts. Read this once before a large pass; the per-card mechanics live in `SKILL.md`
|
|
7
|
+
and `types/<type>.md`.
|
|
8
|
+
|
|
9
|
+
## The bar: rebuildable from the plan alone
|
|
10
|
+
|
|
11
|
+
Hold the plan to one standard above all others: **if every line of code were deleted, a
|
|
12
|
+
competent team could rebuild the whole application from the plan alone.** That is the
|
|
13
|
+
fidelity to aim for — every meaningful surface, data shape, contract, flow, state machine,
|
|
14
|
+
integration, and decision represented and connected, so the system's *shape* survives even
|
|
15
|
+
when the implementation doesn't. This is what makes the plan worth keeping.
|
|
16
|
+
|
|
17
|
+
It's a test of **coverage, not volume.** Rebuildable does not mean transcribing code into
|
|
18
|
+
markdown; it means capturing what someone would need to make the same decisions again — the
|
|
19
|
+
structure, the contracts, the *why*. If a reader couldn't reconstruct a part from its card
|
|
20
|
+
and connections, that's the gap to close (Step 7). The best plan is the *smallest* one that
|
|
21
|
+
still passes this test.
|
|
22
|
+
|
|
23
|
+
## Act as the architect
|
|
24
|
+
|
|
25
|
+
You are not a scribe taking dictation. Act as a senior engineer and architect advising the
|
|
26
|
+
user on their project. Assume they may *not* know everything — they're relying on you for
|
|
27
|
+
judgment, for options they haven't weighed, and for the experience to see what they can't.
|
|
28
|
+
So bring expertise proactively: name trade-offs, flag risks early, propose what's missing,
|
|
29
|
+
and recommend a path. Explain the *why* in a sentence so the user can actually decide —
|
|
30
|
+
teach, don't just execute. Be opinionated but not domineering: make the call you'd make,
|
|
31
|
+
show the reasoning, and leave the final decision to them. A plan that only records what the
|
|
32
|
+
user already said is a failure; a good plan is better than what either of you would have
|
|
33
|
+
produced alone.
|
|
34
|
+
|
|
35
|
+
And hold the bar high — with integrity. Do it right, not just fast. Be honest about what's
|
|
36
|
+
built versus planned and what you've *verified* versus *assumed*; surface uncertainty and
|
|
37
|
+
corner-cutting instead of papering over them. Don't mark a card `verified` you haven't
|
|
38
|
+
checked, don't invent structure to look complete, and say so when something is shaky. The
|
|
39
|
+
goal is a plan — and an app — you'd both be proud to ship.
|
|
40
|
+
|
|
41
|
+
But restraint is part of the craft. **Don't over-engineer — there's an elegance to
|
|
42
|
+
simplicity.** The best plan is the *smallest* one that still builds a real, well-built app:
|
|
43
|
+
fewer cards that capture the system beat a sprawl that documents every hypothetical.
|
|
44
|
+
Calibrate to the project — a weekend prototype and a production multi-tenant SaaS need very
|
|
45
|
+
different plans, so the gap checklist in Step 7 is a menu to weigh, not a mandate to apply.
|
|
46
|
+
Frame feedback as trade-offs, not rules; recommend the smallest change that most improves
|
|
47
|
+
the plan; and don't manufacture gaps to look thorough — confidence over coverage. Real
|
|
48
|
+
boundaries (auth, untrusted input, money, data loss) earn attention; imaginary edge cases
|
|
49
|
+
that can't happen don't.
|
|
50
|
+
|
|
51
|
+
## The governing idea: macro first, then micro
|
|
52
|
+
|
|
53
|
+
Zoom **out** before you zoom **in**. A plan that starts from a list of files is a pile;
|
|
54
|
+
a plan that starts from the system's *shape* is a map. Establish the few big structures
|
|
55
|
+
first (domains, surfaces, the data spine, the auth spine), then descend into detail only
|
|
56
|
+
where it earns its place. Breadth before depth — one shallow pass over the whole system
|
|
57
|
+
beats a deep pass over one corner.
|
|
58
|
+
|
|
59
|
+
Don't ask the user what the code can answer. Read first; ask only to resolve intent,
|
|
60
|
+
priorities, and history that the source cannot reveal. And read the *actual* code — open the
|
|
61
|
+
files and trace the data paths; never judge a system from filenames or folder structure alone.
|
|
62
|
+
|
|
63
|
+
## Step 0 — Orient and ensure a plan exists
|
|
64
|
+
|
|
65
|
+
- If tools return `NO_PLAN_FOUND`, call `init_plan` once (or `constellation init`).
|
|
66
|
+
- Skim the map of the repo before reading any single file: `package.json`/manifest,
|
|
67
|
+
README, the top-level folder layout, the router/route table, the build and deploy
|
|
68
|
+
config, the migrations or schema directory, the test layout.
|
|
69
|
+
- From that alone, name the **stack**, the **surfaces** (web app, public API, admin,
|
|
70
|
+
background workers, CLI), and the **domains** (the 3–8 nouns the product is about).
|
|
71
|
+
Write these into `PLAN-PROJECT` (`plan.md`) — *Current state* and *Conventions* — and
|
|
72
|
+
draft one system-level `DIAGRAM` whose mermaid node IDs are real handles so it joins
|
|
73
|
+
the graph.
|
|
74
|
+
- Give `PLAN-PROJECT` a human-readable `name:` (folder `pyramid-server` → `Pyramid Server`).
|
|
75
|
+
`init_plan` seeds a title-cased default; propose it, confirm with the user, and refine it.
|
|
76
|
+
It's the viewer's title and is editable anytime (`update_card` on `PLAN-PROJECT`).
|
|
77
|
+
- If this repo is one of several that change together, declare its siblings with
|
|
78
|
+
`add_connected_repo` — repo-level links, not cross-repo card connections. See *Connected
|
|
79
|
+
repos* in `SKILL.md` for the multi-repo workflow.
|
|
80
|
+
|
|
81
|
+
## Step 1 — Macro pass (zoom out)
|
|
82
|
+
|
|
83
|
+
Make one card per major thing, shallow, before detailing anything:
|
|
84
|
+
|
|
85
|
+
- Surfaces and domains → a `DIAGRAM` and the top handles you already know you'll need.
|
|
86
|
+
- Don't write bodies yet beyond a sentence. The goal is the skeleton and its connections,
|
|
87
|
+
not prose. Use `create_cards` + `add_connections` (batched — one lint pass, intra-batch
|
|
88
|
+
refs resolve) rather than many single writes.
|
|
89
|
+
|
|
90
|
+
Once the skeleton stands, **orchestrate the detail for a non-trivial plan.** The three axes ahead (Steps 2–4) are naturally independent neighborhoods — the data (`DB → DATATYPE → API → PAGE`), the user (`ROLE` + auth `FLOW` → `PAGE`/`COMPONENT`), the edges (`EXTERNAL`/`JOB`/`EVENT`) — so act as the **orchestrator** rather than walking all of them yourself: fan out one sub-agent per neighborhood, in parallel, each researching the *actual* code for its area and drafting its cards. This keeps your own context clean and holds the macro view while breadth gets covered fast. A few rules make the writes safe:
|
|
91
|
+
|
|
92
|
+
- **One owner per card.** Assign every handle to exactly one agent — and partition on area/file boundaries so the slices are disjoint. Two agents calling `update_card` on the same card race, and the later write silently clobbers the earlier (it rewrites the whole file from a stale snapshot, so even disjoint keys are lost). A shared card both neighborhoods touch (a common `DATATYPE`, say) belongs to one of them, not both.
|
|
93
|
+
- **Prefer return-specs over parallel writes.** Have each agent *return* its card specs (handle, name, kind, status, connections, body) as data; you, the orchestrator, write them via one batched `create_cards` (chunked under create_cards' 500-card cap and add_connections' 1000-connection cap, mutually-referencing cards in the same chunk). Concurrent reads never race; serializing the writes through one actor makes clobbering impossible. If you instead let agents write, give each a disjoint set of source files and never let two add connections onto the same source card.
|
|
94
|
+
- **Wire and verify once, centrally.** Connections are undirected — declare each on a single side. After all agents finish, you re-read each one's work against its intended cards, dedupe and add cross-neighborhood connections via a final batched `add_connections`, and run one whole-plan `check_integrity`. Never trust the agents' per-write issues as proof of final state.
|
|
95
|
+
|
|
96
|
+
Use a single agent — no fan-out — when the plan is small or the areas overlap; the coordination only pays off when neighborhoods are genuinely independent. Don't over-engineer the process either.
|
|
97
|
+
|
|
98
|
+
## Step 2 — Follow the data
|
|
99
|
+
|
|
100
|
+
Data is the backbone; most other cards hang off it.
|
|
101
|
+
|
|
102
|
+
- Database schema / migrations / ORM models → one `DB` card per table or collection.
|
|
103
|
+
- The shapes that cross boundaries (DTOs, API payloads, domain objects) → `DATATYPE`
|
|
104
|
+
cards. Connect `DB ↔ DATATYPE` where a table materializes a type.
|
|
105
|
+
- Trace the **write paths** and **read paths**: who creates, mutates, and reads each
|
|
106
|
+
entity. A multi-step path becomes a `FLOW`; a field that moves through a fixed set of
|
|
107
|
+
values (`draft → open → closed`) becomes a `STATE` card (a `stateDiagram-v2`).
|
|
108
|
+
- Wire `DB → DATATYPE → API → PAGE` so a reader can walk a value from storage to screen.
|
|
109
|
+
|
|
110
|
+
## Step 3 — Follow the user (auth-first)
|
|
111
|
+
|
|
112
|
+
The other backbone is what a person does, and authorization gates all of it.
|
|
113
|
+
|
|
114
|
+
- Start with identity: `ROLE` cards for each role/permission tier, and the **auth `FLOW`**
|
|
115
|
+
(sign-up, sign-in, session, password reset). Most access rules connect back here.
|
|
116
|
+
- Routes/screens → `PAGE` cards. Reusable UI building blocks → `COMPONENT` cards.
|
|
117
|
+
- The handful of journeys that define the product (onboarding, checkout, "create X")
|
|
118
|
+
→ `FLOW` cards, each linking the `PAGE`s, `API`s, and `DATATYPE`s it touches.
|
|
119
|
+
|
|
120
|
+
## Step 4 — Follow the edges
|
|
121
|
+
|
|
122
|
+
- Third-party services and APIs you call → `EXTERNAL`.
|
|
123
|
+
- Scheduled or background work → `JOB`. Domain events / webhooks / queue messages →
|
|
124
|
+
`EVENT`. Connect producers and consumers.
|
|
125
|
+
|
|
126
|
+
## Step 5 — Zoom in (micro)
|
|
127
|
+
|
|
128
|
+
Now, and only now, descend — and only into areas that are central, complex, or risky:
|
|
129
|
+
|
|
130
|
+
- Hydrate before you edit: `get_card` / `traverse` with `connected: "full"` so you see a
|
|
131
|
+
card with all its neighbors at once.
|
|
132
|
+
- Add the granular cards, the detailed `FLOW`s, the `STATE` machines, and the focused
|
|
133
|
+
`DIAGRAM`s for that neighborhood. Keep mermaid node IDs = handles.
|
|
134
|
+
- Resist detailing quiet, stable areas to the same depth. Detail is a cost; spend it where
|
|
135
|
+
it changes a reader's understanding.
|
|
136
|
+
|
|
137
|
+
## Step 6 — Interrogate (ask the user)
|
|
138
|
+
|
|
139
|
+
Ask targeted questions where the code is silent or ambiguous — never what you can read:
|
|
140
|
+
|
|
141
|
+
- **Intent**: why does this exist; what problem does it solve?
|
|
142
|
+
- **Priority & roadmap**: what's actively built vs. aspirational vs. deprecated?
|
|
143
|
+
- **Hidden rules**: business constraints, invariants, "never do X" rules not encoded in code.
|
|
144
|
+
- **Boundaries**: what's in scope for this plan, what's intentionally left out?
|
|
145
|
+
|
|
146
|
+
Fold the answers into card bodies and `PLAN-PROJECT` conventions. Prefer a few sharp
|
|
147
|
+
questions over a long interview; batch them.
|
|
148
|
+
|
|
149
|
+
## Step 7 — Find gaps in the plan
|
|
150
|
+
|
|
151
|
+
This is where you earn your keep. Step back from the individual cards and judge the plan
|
|
152
|
+
as an architecture for a *real, well-built* product. The user is relying on you to surface
|
|
153
|
+
**blind spots** — what they haven't considered, forgot, or don't know to ask about. Read
|
|
154
|
+
the plan the way a seasoned engineer reviews a design doc: assume something important is
|
|
155
|
+
missing, and go find it. This matters more than any single card you write.
|
|
156
|
+
|
|
157
|
+
**First, a quick hygiene sweep** (mechanical, cheap, not the point): `check_integrity` for
|
|
158
|
+
orphans, `list_cards connected:false` for islands, lint for dangling `[[links]]`/refs (W004)
|
|
159
|
+
and unresolved structured refs (E005), plus code with no card and `built` cards with no
|
|
160
|
+
code. Fix or note these and move on — they're table stakes.
|
|
161
|
+
|
|
162
|
+
**Then the real review.** Run these lenses across each area *and* the whole — but calibrate
|
|
163
|
+
to the project's stage and scope; a weekend prototype and a production system have very
|
|
164
|
+
different bars, so treat the list as a menu to *spot* what's missing, then raise only what
|
|
165
|
+
genuinely matters here:
|
|
166
|
+
|
|
167
|
+
- **Unhappy paths** — the plan almost always models the success case. Where are the errors,
|
|
168
|
+
empty states, validation failures, timeouts, retries, conflicts, partial failures, and
|
|
169
|
+
idempotency? Every `FLOW` needs its failure branches; every `STATE` its dead-ends.
|
|
170
|
+
- **Lifecycle completeness** — for each entity, not just create/read but edit, archive,
|
|
171
|
+
delete, restore — and the irreversible/money cases (refund, cancel, revoke, expire).
|
|
172
|
+
- **Auth & access** — is there a `ROLE`/permission answer for *every* `API` and `PAGE`?
|
|
173
|
+
Who must NOT be able to do each thing? Tenant/data isolation?
|
|
174
|
+
- **Cross-cutting concerns plans routinely forget** — security (authz on every endpoint,
|
|
175
|
+
input validation, secrets handling), privacy/PII and data retention/deletion, audit
|
|
176
|
+
logging, observability (logs, metrics, alerts), rate limiting and abuse, pagination and
|
|
177
|
+
filtering on every list, caching, migrations, backups/disaster recovery, notifications
|
|
178
|
+
and email, i18n/accessibility, a testing strategy, admin/moderation tooling,
|
|
179
|
+
onboarding/empty states, and billing edge cases wherever money is involved.
|
|
180
|
+
- **Scale & performance** — N+1s, hot paths, unbounded lists, synchronous work that should
|
|
181
|
+
be a `JOB`, `EVENT`s with no consumer, `EXTERNAL`s with no failure handling.
|
|
182
|
+
- **End-to-end coherence** — can a user actually *complete* each journey with the cards as
|
|
183
|
+
drawn? Do the flows connect, or are there islands and dead ends?
|
|
184
|
+
- **Rebuildability** — the master test: could someone rebuild this area from its cards and
|
|
185
|
+
connections alone? Whatever they'd have to guess or reverse-engineer is the gap.
|
|
186
|
+
- **Domain blind spots** — bring knowledge of the product's domain: what do well-built apps
|
|
187
|
+
of this kind reliably have that this plan doesn't?
|
|
188
|
+
|
|
189
|
+
For each likely gap, decide: an obvious omission → propose a `planned` card; a genuine
|
|
190
|
+
judgment call → ask the user, don't silently assume. The job is to turn unknown-unknowns
|
|
191
|
+
into decisions the user has actually made.
|
|
192
|
+
|
|
193
|
+
## Step 8 — Recommend, tastefully
|
|
194
|
+
|
|
195
|
+
Propose; don't impose. After a pass, give the user a short, prioritized list, and separate
|
|
196
|
+
the two kinds of finding:
|
|
197
|
+
|
|
198
|
+
- **"You likely forgot this"** — high-confidence omissions a production app needs.
|
|
199
|
+
- **"Consider whether you need this"** — judgment calls that depend on scope and intent.
|
|
200
|
+
|
|
201
|
+
Keep it to the few highest-value items, each with a one-line *why* and the card(s) it
|
|
202
|
+
implies. Capture confirmed gaps as `status: planned` cards — visible as intent, honest
|
|
203
|
+
about not existing yet. Suggest structural cleanups (split an overloaded card, add a
|
|
204
|
+
missing `STATE`, connect two islands) but leave the call to the user. Taste means proposing
|
|
205
|
+
the smallest set of changes that most improves the plan — not the most cards.
|
|
206
|
+
|
|
207
|
+
## Status & sync discipline
|
|
208
|
+
|
|
209
|
+
- `planned → building → built → verified`. Mark `built` when code exists; promote to
|
|
210
|
+
`verified` only after you've checked the card against the actual implementation.
|
|
211
|
+
- When reverse-engineering shipped code, default new cards to `built`, then verify in a
|
|
212
|
+
second pass — don't claim `verified` you haven't earned.
|
|
213
|
+
- After reconciling the plan with code, commit the plan, then `set_sync_point` to mark the
|
|
214
|
+
reconciliation. Change history is git (`diff_plan`, `plan_log`) — never stamp dirty
|
|
215
|
+
flags, changelogs, or timestamps into cards.
|
|
216
|
+
- The opposite direction — bringing **code** up to a changed **plan** ("sync the plan to
|
|
217
|
+
the code") — is its own loop, documented in *Syncing the plan to code* in `SKILL.md`:
|
|
218
|
+
`diff_plan` → `traverse` the blast radius → update code → verify → `set_sync_point`. For a
|
|
219
|
+
large diff, orchestrate it (a sub-agent per non-overlapping area — split on file boundaries
|
|
220
|
+
so no two agents edit the same file, and give each card to exactly one agent so concurrent
|
|
221
|
+
`update_card`s can't clobber each other) and always verify the agents' work yourself before
|
|
222
|
+
setting the marker.
|
|
223
|
+
- Building something new also goes **plan-first**: don't edit code first — read the affected
|
|
224
|
+
neighborhood, express the desired end state as cards (new work as `planned`) with their
|
|
225
|
+
connections wired, get sign-off on the plan diff, then run that same code-up-to-plan loop and
|
|
226
|
+
reconcile (`check_integrity` for orphans, status bumps, `set_sync_point`). In plan mode, where
|
|
227
|
+
writes are blocked, read the plan heavily to model the project fast and present the card edits
|
|
228
|
+
you'll make. Full steps in *Changing code: plan-first* in `SKILL.md`.
|
package/skill/types/plan.md
CHANGED
|
@@ -12,6 +12,25 @@ Keep it **short**. Three rules:
|
|
|
12
12
|
| Field | Type | Notes |
|
|
13
13
|
|---|---|---|
|
|
14
14
|
| `scope` | string | area for scoped plans, e.g. `frontend`; omit for `plan.md` |
|
|
15
|
+
| `connected_repos` | list | sibling repos this project coordinates with (on `PLAN-PROJECT` only) — see below |
|
|
16
|
+
|
|
17
|
+
## Connected repos (multi-repo)
|
|
18
|
+
|
|
19
|
+
When one change spans several sibling repos, declare them on `PLAN-PROJECT` so an agent can
|
|
20
|
+
reach each one with the MCP `repo:` selector. These are **repo-level links, not card
|
|
21
|
+
connections** — cards never reference another repo's cards, and each plan still lints alone.
|
|
22
|
+
Each entry has a lowercase `name` (the `repo:` selector value), a `path` relative to this
|
|
23
|
+
repo's root, and a one-line `description`. Paths are local topology — never lint-checked.
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
connected_repos:
|
|
27
|
+
- name: pyramid-server
|
|
28
|
+
path: ../pyramid-server
|
|
29
|
+
description: Back-end API for Pyramid, written in Go.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Manage these with `add_connected_repo` / `list_connected_repos` / `remove_connected_repo`
|
|
33
|
+
(MCP) or `constellation repos` (CLI), not by hand-editing unless you prefer to.
|
|
15
34
|
|
|
16
35
|
Example — `constellation/plan.md`:
|
|
17
36
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-DzXuQd4N.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-NNHCCRGN-DlpIbxXb.js";import{x as e}from"./mermaid-parser.core-xhSeYiZo.js";export{e as createArchitectureServices};
|