@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.
Files changed (121) hide show
  1. package/README.md +41 -4
  2. package/dist/cli/index.js +62 -10
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/update-check.d.ts +6 -0
  5. package/dist/cli/update-check.js +70 -0
  6. package/dist/cli/update-check.js.map +1 -0
  7. package/dist/{mcp → core}/git.d.ts +19 -0
  8. package/dist/{mcp → core}/git.js +59 -2
  9. package/dist/core/git.js.map +1 -0
  10. package/dist/core/index.d.ts +1 -0
  11. package/dist/core/index.js +1 -0
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/repos.d.ts +40 -0
  14. package/dist/core/repos.js +93 -0
  15. package/dist/core/repos.js.map +1 -0
  16. package/dist/core/resolve.js +10 -1
  17. package/dist/core/resolve.js.map +1 -1
  18. package/dist/core/scaffold.d.ts +16 -3
  19. package/dist/core/scaffold.js +30 -7
  20. package/dist/core/scaffold.js.map +1 -1
  21. package/dist/core/sync.d.ts +28 -0
  22. package/dist/core/sync.js +85 -0
  23. package/dist/core/sync.js.map +1 -0
  24. package/dist/core/types.d.ts +12 -0
  25. package/dist/mcp/server.js +434 -38
  26. package/dist/mcp/server.js.map +1 -1
  27. package/dist/serve/server.js +28 -4
  28. package/dist/serve/server.js.map +1 -1
  29. package/docs/001-file-format.md +25 -0
  30. package/docs/002-mcp.md +56 -7
  31. package/examples/constellation/plan.md +1 -1
  32. package/package.json +3 -1
  33. package/schemas/plan.json +27 -0
  34. package/skill/SKILL.md +131 -1
  35. package/skill/methodology.md +228 -0
  36. package/skill/types/plan.md +19 -0
  37. package/viewer/dist/assets/{arc-Kj6pF3JI.js → arc-CMMRgIq9.js} +1 -1
  38. package/viewer/dist/assets/architecture-7EHR7CIX-Cbb-syEI.js +1 -0
  39. package/viewer/dist/assets/{architectureDiagram-3BPJPVTR-C5bZdErB.js → architectureDiagram-3BPJPVTR-CB5p_qlN.js} +1 -1
  40. package/viewer/dist/assets/{blockDiagram-GPEHLZMM-C1Q6l6fE.js → blockDiagram-GPEHLZMM-DpnMj_e6.js} +1 -1
  41. package/viewer/dist/assets/{c4Diagram-AAUBKEIU-BmM6Tmtq.js → c4Diagram-AAUBKEIU-f91ngVN8.js} +1 -1
  42. package/viewer/dist/assets/channel-C2bkEQHQ.js +1 -0
  43. package/viewer/dist/assets/{chunk-2J33WTMH-z09tLTpZ.js → chunk-2J33WTMH-y7Pz5tMO.js} +1 -1
  44. package/viewer/dist/assets/{chunk-3OPIFGDE-BynpXh1r.js → chunk-3OPIFGDE-Ir_ghIUQ.js} +1 -1
  45. package/viewer/dist/assets/{chunk-4BX2VUAB-CDOVuPyG.js → chunk-4BX2VUAB-BTPyM1ux.js} +1 -1
  46. package/viewer/dist/assets/{chunk-55IACEB6-nBwigOgn.js → chunk-55IACEB6-CtNd8e4Y.js} +1 -1
  47. package/viewer/dist/assets/{chunk-5ZQYHXKU-Bxe5xIy_.js → chunk-5ZQYHXKU-Dd3yz721.js} +1 -1
  48. package/viewer/dist/assets/{chunk-727SXJPM-DZmTgL68.js → chunk-727SXJPM-CAM8mGbv.js} +1 -1
  49. package/viewer/dist/assets/{chunk-AQP2D5EJ-B7wr_Owx.js → chunk-AQP2D5EJ-C3nW9Uve.js} +1 -1
  50. package/viewer/dist/assets/{chunk-BSJP7CBP-DbAKfVCK.js → chunk-BSJP7CBP-r6MRPvAH.js} +1 -1
  51. package/viewer/dist/assets/{chunk-CSCIHK7Q-C0rsBwqP.js → chunk-CSCIHK7Q-Cn-ZTxsS.js} +1 -1
  52. package/viewer/dist/assets/{chunk-FMBD7UC4-BAtzt0wv.js → chunk-FMBD7UC4-5axXeZJa.js} +1 -1
  53. package/viewer/dist/assets/{chunk-KSCS5N6A-CXXwf52I.js → chunk-KSCS5N6A-BwmNx0l0.js} +1 -1
  54. package/viewer/dist/assets/{chunk-L5ZTLDWV-DS4vRI1U.js → chunk-L5ZTLDWV-C2YNkUjB.js} +1 -1
  55. package/viewer/dist/assets/chunk-LZXEDZCA-CznuDgQD.js +2 -0
  56. package/viewer/dist/assets/{chunk-ND2GUHAM-CUSnPl8t.js → chunk-ND2GUHAM-CokDnghi.js} +1 -1
  57. package/viewer/dist/assets/{chunk-NZK2D7GU-Dh986nJk.js → chunk-NZK2D7GU-aaU0v4QE.js} +1 -1
  58. package/viewer/dist/assets/{chunk-O5CBEL6O-JAEZ_pS6.js → chunk-O5CBEL6O-ByfKhkZf.js} +1 -1
  59. package/viewer/dist/assets/chunk-QZHKN3VN-DJRjGeIo.js +1 -0
  60. package/viewer/dist/assets/chunk-WU5MYG2G-C63BVvr_.js +1 -0
  61. package/viewer/dist/assets/{chunk-XPW4576I-BwMZI0gv.js → chunk-XPW4576I-Amo3awtq.js} +1 -1
  62. package/viewer/dist/assets/classDiagram-4FO5ZUOK-z_bO1V-j.js +1 -0
  63. package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-z_bO1V-j.js +1 -0
  64. package/viewer/dist/assets/{cose-bilkent-S5V4N54A-NGC7gYHM.js → cose-bilkent-S5V4N54A-CO8yESCW.js} +1 -1
  65. package/viewer/dist/assets/{dagre-BM42HDAG-RD63uyvd.js → dagre-BM42HDAG-BnmNVNI2.js} +1 -1
  66. package/viewer/dist/assets/{diagram-2AECGRRQ-hwnqqCcb.js → diagram-2AECGRRQ-lcGXcbei.js} +1 -1
  67. package/viewer/dist/assets/{diagram-5GNKFQAL-q8EaoZSG.js → diagram-5GNKFQAL-Cj3-lPUt.js} +1 -1
  68. package/viewer/dist/assets/{diagram-KO2AKTUF-D4_5Qf-l.js → diagram-KO2AKTUF-CtXdRI4M.js} +1 -1
  69. package/viewer/dist/assets/{diagram-LMA3HP47-D8pwekFs.js → diagram-LMA3HP47-CIyLAzX7.js} +1 -1
  70. package/viewer/dist/assets/{diagram-OG6HWLK6-D9KinIWZ.js → diagram-OG6HWLK6-BwF4bQCv.js} +1 -1
  71. package/viewer/dist/assets/{dist-CFOOgrqc.js → dist-DzXuQd4N.js} +1 -1
  72. package/viewer/dist/assets/{erDiagram-TEJ5UH35-D0Wfq250.js → erDiagram-TEJ5UH35-DjwFw9yq.js} +1 -1
  73. package/viewer/dist/assets/eventmodeling-FCH6USID-BlKFmSzA.js +1 -0
  74. package/viewer/dist/assets/{flowDiagram-I6XJVG4X-Y2DY-Ze2.js → flowDiagram-I6XJVG4X-CzXbf7vQ.js} +1 -1
  75. package/viewer/dist/assets/{ganttDiagram-6RSMTGT7-BnqkeLVw.js → ganttDiagram-6RSMTGT7-BYcIhfmm.js} +1 -1
  76. package/viewer/dist/assets/{gitGraph-WXDBUCRP-Cft7usRT.js → gitGraph-WXDBUCRP-H8XeJ9QB.js} +1 -1
  77. package/viewer/dist/assets/{gitGraphDiagram-PVQCEYII-D-cYtraK.js → gitGraphDiagram-PVQCEYII-DtAPXKFK.js} +1 -1
  78. package/viewer/dist/assets/index-Bqs39Itl.css +2 -0
  79. package/viewer/dist/assets/index-DLPCG_Or.js +98 -0
  80. package/viewer/dist/assets/{info-J43DQDTF-Djc8Bx3F.js → info-J43DQDTF-BQScorZ0.js} +1 -1
  81. package/viewer/dist/assets/{infoDiagram-5YYISTIA-D-ehtyyJ.js → infoDiagram-5YYISTIA-Udl1omvH.js} +1 -1
  82. package/viewer/dist/assets/{ishikawaDiagram-YF4QCWOH-Ct3f6bH-.js → ishikawaDiagram-YF4QCWOH-VnfzT_hk.js} +1 -1
  83. package/viewer/dist/assets/{journeyDiagram-JHISSGLW-DXlULEmi.js → journeyDiagram-JHISSGLW-Btn4EVoD.js} +1 -1
  84. package/viewer/dist/assets/{kanban-definition-UN3LZRKU-3vE9h-R7.js → kanban-definition-UN3LZRKU-flOzWhPe.js} +1 -1
  85. package/viewer/dist/assets/{line-B8MygbLB.js → line-DJJ9BLuY.js} +1 -1
  86. package/viewer/dist/assets/{linear-CfMuM0B3.js → linear-C2SUy5ns.js} +1 -1
  87. package/viewer/dist/assets/{mermaid-parser.core-DzlZTbbh.js → mermaid-parser.core-xhSeYiZo.js} +2 -2
  88. package/viewer/dist/assets/{mermaid.core-IM-sPiyq.js → mermaid.core-DmeSIitY.js} +3 -3
  89. package/viewer/dist/assets/{mindmap-definition-RKZ34NQL-CMnpAq1T.js → mindmap-definition-RKZ34NQL-CCJcMKx1.js} +1 -1
  90. package/viewer/dist/assets/{packet-YPE3B663-D44AzgHh.js → packet-YPE3B663-DS8RscAk.js} +1 -1
  91. package/viewer/dist/assets/{pie-LRSECV5Y-DL8AVJH_.js → pie-LRSECV5Y-I2ZQhrNJ.js} +1 -1
  92. package/viewer/dist/assets/{pieDiagram-4H26LBE5-FvKK5jd7.js → pieDiagram-4H26LBE5-BS5HMs4j.js} +1 -1
  93. package/viewer/dist/assets/{quadrantDiagram-W4KKPZXB-CmjSkU8c.js → quadrantDiagram-W4KKPZXB-W4H8cw2_.js} +1 -1
  94. package/viewer/dist/assets/{radar-GUYGQ44K-BvfZTVyH.js → radar-GUYGQ44K-kf6QvSne.js} +1 -1
  95. package/viewer/dist/assets/{requirementDiagram-4Y6WPE33-BOjca3VH.js → requirementDiagram-4Y6WPE33-DSbuDQGQ.js} +1 -1
  96. package/viewer/dist/assets/{sankeyDiagram-5OEKKPKP-ANcjfNix.js → sankeyDiagram-5OEKKPKP-CH8Qr2vL.js} +1 -1
  97. package/viewer/dist/assets/{sequenceDiagram-3UESZ5HK-BLQ9AL7I.js → sequenceDiagram-3UESZ5HK-EugVcdad.js} +1 -1
  98. package/viewer/dist/assets/src-CM_9kdrU.js +1 -0
  99. package/viewer/dist/assets/{stateDiagram-AJRCARHV-D6CriBS6.js → stateDiagram-AJRCARHV-DiFl94Qy.js} +1 -1
  100. package/viewer/dist/assets/stateDiagram-v2-BHNVJYJU-BlJV8F13.js +1 -0
  101. package/viewer/dist/assets/{timeline-definition-PNZ67QCA-BNhWZ_DL.js → timeline-definition-PNZ67QCA-B0KW9GUN.js} +1 -1
  102. package/viewer/dist/assets/{treeView-BLDUP644-CY6Ph5Pu.js → treeView-BLDUP644-CAEY4mxq.js} +1 -1
  103. package/viewer/dist/assets/{treemap-LRROVOQU-DChSA_Qx.js → treemap-LRROVOQU-VVaEaTlU.js} +1 -1
  104. package/viewer/dist/assets/{vennDiagram-CIIHVFJN-C01WznAC.js → vennDiagram-CIIHVFJN-BSLGNfJd.js} +1 -1
  105. package/viewer/dist/assets/{wardley-L42UT6IY-BJ8uNoJu.js → wardley-L42UT6IY-C-5cXbAU.js} +1 -1
  106. package/viewer/dist/assets/{wardleyDiagram-YWT4CUSO-DwDEzlVm.js → wardleyDiagram-YWT4CUSO-COk4TVnQ.js} +1 -1
  107. package/viewer/dist/assets/{xychartDiagram-2RQKCTM6-BCvIDwU0.js → xychartDiagram-2RQKCTM6-CClGJLJp.js} +1 -1
  108. package/viewer/dist/index.html +3 -3
  109. package/dist/mcp/git.js.map +0 -1
  110. package/viewer/dist/assets/architecture-7EHR7CIX-CGfWeim3.js +0 -1
  111. package/viewer/dist/assets/channel-19IdUS_c.js +0 -1
  112. package/viewer/dist/assets/chunk-LZXEDZCA-CclT9MXr.js +0 -2
  113. package/viewer/dist/assets/chunk-QZHKN3VN-BKc_Kg2Z.js +0 -1
  114. package/viewer/dist/assets/chunk-WU5MYG2G-9ssTSMzt.js +0 -1
  115. package/viewer/dist/assets/classDiagram-4FO5ZUOK-DXv85WFd.js +0 -1
  116. package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-DXv85WFd.js +0 -1
  117. package/viewer/dist/assets/eventmodeling-FCH6USID-D3KRSuC1.js +0 -1
  118. package/viewer/dist/assets/index-CDR-riG2.css +0 -2
  119. package/viewer/dist/assets/index-DRPsTWe2.js +0 -98
  120. package/viewer/dist/assets/src-CAMdANUp.js +0 -1
  121. 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`.
@@ -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-CFOOgrqc.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};
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};