@maycombhq/atticus 0.0.0-stage → 2.0.0-beta.2
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/LICENSE +177 -0
- package/README.md +17 -2
- package/THIRD-PARTY-LICENSES.txt +2607 -0
- package/dist/bin.js +47 -0
- package/dist/chunk-23W7VWKR.js +2609 -0
- package/dist/chunk-27NKUS3X.js +4330 -0
- package/dist/chunk-2ANOROX3.js +2522 -0
- package/dist/chunk-2BF2EYJV.js +174 -0
- package/dist/chunk-2BFCZ3RK.js +315 -0
- package/dist/chunk-2DIQQJCB.js +378 -0
- package/dist/chunk-2RMYG36Q.js +1227 -0
- package/dist/chunk-2VHF7OXM.js +55 -0
- package/dist/chunk-3ALD2W2A.js +95 -0
- package/dist/chunk-3C7EYRFZ.js +41 -0
- package/dist/chunk-3G4YI4ZU.js +16 -0
- package/dist/chunk-3HI6Z55Y.js +5949 -0
- package/dist/chunk-3USYZGRF.js +324 -0
- package/dist/chunk-42EVSKME.js +37 -0
- package/dist/chunk-4AK7IBVP.js +915 -0
- package/dist/chunk-4BKGMUIK.js +53 -0
- package/dist/chunk-4BN53TG3.js +343 -0
- package/dist/chunk-4NDAAFQT.js +103 -0
- package/dist/chunk-4Q3NN7VF.js +32 -0
- package/dist/chunk-4RS5KZQD.js +25 -0
- package/dist/chunk-4SKZDI62.js +22 -0
- package/dist/chunk-4WBVUHXN.js +69 -0
- package/dist/chunk-5GDRCDQB.js +32 -0
- package/dist/chunk-5GGOLAKC.js +856 -0
- package/dist/chunk-5KLGBXG5.js +48 -0
- package/dist/chunk-5WG5YP4T.js +34 -0
- package/dist/chunk-64EQYWCA.js +180 -0
- package/dist/chunk-652QWTLZ.js +242 -0
- package/dist/chunk-65NYPGRC.js +766 -0
- package/dist/chunk-66YVAGGM.js +46 -0
- package/dist/chunk-6BNC6EQ4.js +41 -0
- package/dist/chunk-6BVONWJ7.js +50 -0
- package/dist/chunk-6D2CQ5II.js +41 -0
- package/dist/chunk-6IU67AEK.js +325 -0
- package/dist/chunk-6J5OKA4Y.js +49 -0
- package/dist/chunk-6JCPI55B.js +92 -0
- package/dist/chunk-6JUBZBMW.js +56 -0
- package/dist/chunk-6M5NK3K3.js +415 -0
- package/dist/chunk-6QSERWXH.js +53 -0
- package/dist/chunk-6TACQN3N.js +41 -0
- package/dist/chunk-76WKMA4J.js +14 -0
- package/dist/chunk-7AVHLZGD.js +45 -0
- package/dist/chunk-7EFILTCI.js +67 -0
- package/dist/chunk-7EKXJZ2Y.js +2902 -0
- package/dist/chunk-7EOBHUMC.js +133 -0
- package/dist/chunk-7FBGJFEE.js +66 -0
- package/dist/chunk-7JUKDRSZ.js +1726 -0
- package/dist/chunk-7SW2QWLU.js +212 -0
- package/dist/chunk-7WD63HU2.js +143 -0
- package/dist/chunk-7ZUIMTOU.js +108 -0
- package/dist/chunk-A3GY6SOA.js +95 -0
- package/dist/chunk-A7UPUQFY.js +2356 -0
- package/dist/chunk-AA6YULYB.js +376 -0
- package/dist/chunk-ABWHYWNI.js +101 -0
- package/dist/chunk-AIOQPLA5.js +540 -0
- package/dist/chunk-AVJDSJ2F.js +18 -0
- package/dist/chunk-B2WLAWNJ.js +374 -0
- package/dist/chunk-BKVWTZ6A.js +211 -0
- package/dist/chunk-BOHJZTEQ.js +1991 -0
- package/dist/chunk-BWZ77RQT.js +25 -0
- package/dist/chunk-C6EKFH7J.js +169 -0
- package/dist/chunk-CAQZUNOH.js +1150 -0
- package/dist/chunk-CEXSU4S6.js +1217 -0
- package/dist/chunk-CKSITVS4.js +16101 -0
- package/dist/chunk-CNUKCS2T.js +2741 -0
- package/dist/chunk-CPA6HPVR.js +3206 -0
- package/dist/chunk-CR3MTH32.js +207 -0
- package/dist/chunk-CSZ4C5N6.js +307 -0
- package/dist/chunk-D3PO4DOZ.js +261 -0
- package/dist/chunk-D46WUV3T.js +33 -0
- package/dist/chunk-DE76JROX.js +80 -0
- package/dist/chunk-DFBCSHVT.js +69 -0
- package/dist/chunk-DHPACDG7.js +104 -0
- package/dist/chunk-DKJA76CJ.js +113 -0
- package/dist/chunk-DPUYDDQG.js +164 -0
- package/dist/chunk-DPZHZQKE.js +285 -0
- package/dist/chunk-E36QOJMD.js +47 -0
- package/dist/chunk-EADP3PEN.js +450 -0
- package/dist/chunk-EBEW3XXQ.js +166 -0
- package/dist/chunk-EDS2L2LD.js +106 -0
- package/dist/chunk-EFHQ3TWP.js +637 -0
- package/dist/chunk-EPTBZ3GP.js +101 -0
- package/dist/chunk-EYWIDJFU.js +130 -0
- package/dist/chunk-F7HYOUFF.js +287 -0
- package/dist/chunk-FHH4I4ZV.js +128 -0
- package/dist/chunk-FITWGOJ2.js +131 -0
- package/dist/chunk-FQXYPF7E.js +147 -0
- package/dist/chunk-G2B4ZQGH.js +240 -0
- package/dist/chunk-GBRFVT63.js +45 -0
- package/dist/chunk-GDLULHTC.js +2919 -0
- package/dist/chunk-GLUX4EEP.js +583 -0
- package/dist/chunk-GQ4N4WKF.js +1142 -0
- package/dist/chunk-GT4I4ZWM.js +38 -0
- package/dist/chunk-HFQCFSJR.js +60 -0
- package/dist/chunk-HITVBIJS.js +1247 -0
- package/dist/chunk-HLJAXMM4.js +233 -0
- package/dist/chunk-HVUPKCGJ.js +162 -0
- package/dist/chunk-I3E7CX4H.js +155 -0
- package/dist/chunk-I4JRCD6M.js +184 -0
- package/dist/chunk-ICY36XCH.js +34 -0
- package/dist/chunk-IHMLFRVV.js +228 -0
- package/dist/chunk-IPKHE5D6.js +1963 -0
- package/dist/chunk-J4K3KVLD.js +131 -0
- package/dist/chunk-JBTK5OP2.js +55 -0
- package/dist/chunk-JCZIKA4C.js +163 -0
- package/dist/chunk-JGZCG5VM.js +189 -0
- package/dist/chunk-JIITQXFB.js +4087 -0
- package/dist/chunk-JMSCMUCA.js +271 -0
- package/dist/chunk-JZU3H6UQ.js +54 -0
- package/dist/chunk-K65BJIMT.js +49 -0
- package/dist/chunk-KEM4SDDP.js +3898 -0
- package/dist/chunk-KQDZXGNR.js +14 -0
- package/dist/chunk-L24C55VN.js +7923 -0
- package/dist/chunk-L6SGQIR3.js +471 -0
- package/dist/chunk-LR3R6Z2A.js +400 -0
- package/dist/chunk-M766ZJ6W.js +119 -0
- package/dist/chunk-MC3H7736.js +19910 -0
- package/dist/chunk-MGYZM27B.js +205 -0
- package/dist/chunk-MMOSZPWJ.js +273 -0
- package/dist/chunk-MVZVGYXH.js +1611 -0
- package/dist/chunk-N7IXEHK3.js +549 -0
- package/dist/chunk-NE2W3OO7.js +230 -0
- package/dist/chunk-NN2ZQEB4.js +38 -0
- package/dist/chunk-NXFPS2LR.js +182 -0
- package/dist/chunk-O3WI5KWW.js +31 -0
- package/dist/chunk-OLQJTJJU.js +76 -0
- package/dist/chunk-ONLS5QA5.js +102 -0
- package/dist/chunk-OT2O76OS.js +1496 -0
- package/dist/chunk-PAMPPUR6.js +4500 -0
- package/dist/chunk-PCOCACY3.js +385 -0
- package/dist/chunk-PCVDV3UZ.js +430 -0
- package/dist/chunk-PRPPGYZG.js +104 -0
- package/dist/chunk-Q4D5X7QB.js +264 -0
- package/dist/chunk-Q5AMFEWD.js +119 -0
- package/dist/chunk-QRAOANID.js +214 -0
- package/dist/chunk-QSXK2RGH.js +688 -0
- package/dist/chunk-QZSX3F7C.js +389 -0
- package/dist/chunk-R6RY4Q5T.js +51 -0
- package/dist/chunk-R6XF6UR3.js +149 -0
- package/dist/chunk-R77KLRB3.js +166 -0
- package/dist/chunk-RRTKKSLQ.js +251 -0
- package/dist/chunk-RTEYOSJY.js +29 -0
- package/dist/chunk-RUVFXE2L.js +666 -0
- package/dist/chunk-RVH5SUW5.js +69 -0
- package/dist/chunk-RZPYKDWS.js +26 -0
- package/dist/chunk-S2A7YC3Q.js +41433 -0
- package/dist/chunk-S3QNRWYR.js +25 -0
- package/dist/chunk-SJRGMG6A.js +174 -0
- package/dist/chunk-SP2I63OO.js +252 -0
- package/dist/chunk-T2UYZSCQ.js +545 -0
- package/dist/chunk-T6AIP7H5.js +3851 -0
- package/dist/chunk-T6XQL73F.js +94 -0
- package/dist/chunk-TANFV3MZ.js +531 -0
- package/dist/chunk-TDD55CJH.js +119 -0
- package/dist/chunk-TV45EUGM.js +51 -0
- package/dist/chunk-TXLH6WHQ.js +2078 -0
- package/dist/chunk-TYAID7B7.js +408 -0
- package/dist/chunk-UBBC2XSG.js +873 -0
- package/dist/chunk-UGLN7QHV.js +27 -0
- package/dist/chunk-UNM6ZOKP.js +878 -0
- package/dist/chunk-V2YTAIQO.js +1075 -0
- package/dist/chunk-VN3DP4LQ.js +43 -0
- package/dist/chunk-VOGCSYOI.js +16 -0
- package/dist/chunk-VYDBJ73M.js +32 -0
- package/dist/chunk-W3BQAZ3Q.js +34 -0
- package/dist/chunk-W5BVQF44.js +36 -0
- package/dist/chunk-WVPJSRRJ.js +52 -0
- package/dist/chunk-WY6PP6AA.js +53 -0
- package/dist/chunk-XAKWMCXI.js +285 -0
- package/dist/chunk-XPCM366L.js +70 -0
- package/dist/chunk-XPTOBS2D.js +48 -0
- package/dist/chunk-XY3P7JW7.js +3479 -0
- package/dist/chunk-XZRON6IV.js +131 -0
- package/dist/chunk-YEDDOYSC.js +27809 -0
- package/dist/chunk-YISXLPHN.js +496 -0
- package/dist/chunk-YMZ3TNYB.js +18 -0
- package/dist/chunk-YY6ZQQBP.js +203 -0
- package/dist/chunk-YYQN46FY.js +334 -0
- package/dist/chunk-Z6LF7HQN.js +22 -0
- package/dist/chunk-ZCJDOK2S.js +116 -0
- package/dist/chunk-ZDPAS56H.js +76 -0
- package/dist/chunk-ZMAINWBW.js +18 -0
- package/dist/chunk-ZMFPW66A.js +22 -0
- package/dist/chunk-ZNCEKR4J.js +296 -0
- package/dist/chunk-ZVM6AKKM.js +47 -0
- package/dist/files.json +1888 -0
- package/dist/fixtures/forge/README.md +19 -0
- package/dist/fixtures/forge/expected/discrepancies.yaml +54 -0
- package/dist/fixtures/forge/expected/inputs.yaml +38 -0
- package/dist/fixtures/forge/expected/scan.yaml +342 -0
- package/dist/fixtures/forge/inputs/diagrams/forge-context.drawio +23 -0
- package/dist/fixtures/forge/inputs/partner-specs/northwind-pay-openapi.yaml +11 -0
- package/dist/fixtures/forge/inputs/tickets/ado-stories.json +4 -0
- package/dist/fixtures/forge/inputs/tickets/closed-service-requests.json +5 -0
- package/dist/fixtures/forge/inputs/wiki/integration-patterns.md +11 -0
- package/dist/fixtures/forge/inputs/wiki/ledger-solution-spec.md +9 -0
- package/dist/fixtures/forge/inputs/wiki/snow-firewall-request.md +4 -0
- package/dist/fixtures/forge/metarepo/judgments/reaches/84af5b6af24f7ca8c23013f3.yaml +17 -0
- package/dist/fixtures/forge/metarepo/judgments/reaches/c3917555edebddce8cecb647.yaml +17 -0
- package/dist/fixtures/forge/metarepo/judgments/reaches/c5fafd6601f8ca9e34e0bbd0.yaml +17 -0
- package/dist/fixtures/forge/metarepo/org-pack/agents/architecture-critic.yaml +9 -0
- package/dist/fixtures/forge/metarepo/org-pack/agents/story-writer.yaml +10 -0
- package/dist/fixtures/forge/metarepo/org-pack/checklists/architecture.yaml +115 -0
- package/dist/fixtures/forge/metarepo/org-pack/dialects/forge.yaml +111 -0
- package/dist/fixtures/forge/metarepo/org-pack/gates.yaml +22 -0
- package/dist/fixtures/forge/metarepo/org-pack/pack.yaml +11 -0
- package/dist/fixtures/forge/metarepo/org-pack/patterns/A.EB.PUB.yaml +12 -0
- package/dist/fixtures/forge/metarepo/org-pack/patterns/D.JDBC.yaml +12 -0
- package/dist/fixtures/forge/metarepo/org-pack/patterns/S.DIR.BFF.yaml +12 -0
- package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.SOR.yaml +13 -0
- package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.VND.yaml +14 -0
- package/dist/fixtures/forge/metarepo/org-pack/process/change-templates/feature.md +37 -0
- package/dist/fixtures/forge/metarepo/org-pack/process/skills/add-forge-endpoint/SKILL.md +17 -0
- package/dist/fixtures/forge/metarepo/org-pack/process/snow/firewall-rule.yaml +14 -0
- package/dist/fixtures/forge/metarepo/org-pack/process/snow/gateway-route.yaml +13 -0
- package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/profile.yaml +12 -0
- package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/repos.manifest.yaml +44 -0
- package/dist/fixtures/forge/metarepo/org-pack/roles.yaml +14 -0
- package/dist/fixtures/forge/metarepo/org-pack/runtime.yaml +14 -0
- package/dist/fixtures/forge/metarepo/org-pack/sources.yaml +3 -0
- package/dist/fixtures/forge/repos/forge-events/topics/payments.initiated.yaml +4 -0
- package/dist/fixtures/forge/repos/forge-events/topics/transfers.completed.yaml +4 -0
- package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/ledger-v1.xml +3 -0
- package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/SpikeArrest.xml +3 -0
- package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/VerifyOAuth.xml +4 -0
- package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/proxies/default.xml +14 -0
- package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/targets/ledger.xml +5 -0
- package/dist/fixtures/forge/repos/forge-infra/alerts/ledger-api.yaml +5 -0
- package/dist/fixtures/forge/repos/forge-infra/k8s/ledger-api.yaml +15 -0
- package/dist/fixtures/forge/repos/forge-infra/k8s/portal-bff.yaml +7 -0
- package/dist/fixtures/forge/repos/forge-infra/terraform/ledger-db.tf +9 -0
- package/dist/fixtures/forge/repos/forge-ledger/api/ledger-openapi.yaml +31 -0
- package/dist/fixtures/forge/repos/forge-ledger/forge.yaml +4 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEndpoints.java +13 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEvents.java +11 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/NorthwindClient.java +10 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/application.yml +3 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V1__create_account.sql +5 -0
- package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V2__create_entry.sql +7 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/pom.xml +1 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/AuditPublisher.java +12 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/BalanceController.java +16 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/LedgerClient.java +13 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/PaymentEvents.java +13 -0
- package/dist/fixtures/forge/repos/forge-portal-bff/src/main/resources/application.yml +8 -0
- package/dist/fixtures/forge/repos/forge-portal-ui/package.json +1 -0
- package/dist/fixtures/forge/repos/forge-portal-ui/src/api/balance.ts +5 -0
- package/dist/fixtures/forge/repos/forge-reports-job/src/main/java/forge/reports/DailyEntriesJob.java +19 -0
- package/dist/fixtures/forge/repos/forge-reports-job/src/main/resources/application.yml +3 -0
- package/dist/fixtures/forge-change/README.md +41 -0
- package/dist/fixtures/forge-change/expected/findings.yaml +301 -0
- package/dist/fixtures/forge-change/expected/stories.yaml +101 -0
- package/dist/fixtures/forge-change/judgments/personal-data/0b5f3dbf5257a22275d8c74b.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/2759a66770134c417440bf2d.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/31b1ea2f14d0737f1aca79fd.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/49afd70c08228e65ad6ca1ed.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/761cabcb8a39f5e5866d2dd6.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/adae902b90cc8ffa0c765145.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/ba11bb933105ec9493e065dd.yaml +18 -0
- package/dist/fixtures/forge-change/judgments/personal-data/bdbcd1cdac3021c68063c3e7.yaml +18 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/brief.md +35 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/change.yaml +120 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/data.md +18 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/design.md +29 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/interfaces.md +17 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/mappings.md +26 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/proposal.md +35 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/snow.md +12 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/specs/transfer-limits/spec.md +19 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s1-refuse-over-limit.md +17 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s2-show-remaining.md +16 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s3-audit-refusals.md +18 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s4-velocity-check.md +16 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories.md +8 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/tasks.md +12 -0
- package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/ux.md +7 -0
- package/dist/fixtures/forge-change/org-pack/agents/code-and-test-critic.yaml +13 -0
- package/dist/fixtures/forge-change/org-pack/agents/complete-critic.yaml +12 -0
- package/dist/fixtures/forge-change/org-pack/agents/safe-critic.yaml +12 -0
- package/dist/fixtures/forge-change/org-pack/agents/ship-critic.yaml +11 -0
- package/dist/fixtures/forge-change/org-pack/agents/true-critic.yaml +11 -0
- package/dist/fixtures/forge-change/org-pack/checklists/review.yaml +54 -0
- package/dist/fixtures/forge-change/org-pack/gates.yaml +25 -0
- package/dist/fixtures/forge-change/org-pack/teams/team-ledger/checklists/ledger-team.yaml +227 -0
- package/dist/fixtures/forge-change/recordings/complete-critic/2ad84f84bf39c1d5412697e69fe23034d6983ec45a00314bf0975e627589a3c5.json +12 -0
- package/dist/fixtures/forge-change/recordings/complete-critic/417c98d8e54a4387d0fd93441c49f44c2868958739070d855c1dce0c41e24db3.json +12 -0
- package/dist/fixtures/forge-change/recordings/complete-critic/50203ee22e9cb3ef047295edb6538fe7d5695e1e4b139f3c929013dc6ce47021.json +12 -0
- package/dist/fixtures/forge-change/recordings/complete-critic/89f18d67f5d9c325bf35e2a9e020f9ddb6ee13b8523315037f0905cc57c040b1.json +12 -0
- package/dist/fixtures/forge-change/recordings/complete-critic/b4097867d26ae8eadc8b9efa8cdd86897013358035f0b40086c299a59c4ba121.json +12 -0
- package/dist/fixtures/forge-change/recordings/safe-critic/302d06f49664dd67ad2e21ab9cf74c1b0f7d3f750709c6ed8eff2b70983274e2.json +12 -0
- package/dist/fixtures/forge-change/recordings/safe-critic/32f1049c9a5ab4a759543290db4644ec6e221cc45fdfdcf06193837c6a8ce0b9.json +12 -0
- package/dist/fixtures/forge-change/recordings/safe-critic/4e4a84bfc04b9f26ca4250319a879901ff7a1c081c71e46a117675fee05026b0.json +12 -0
- package/dist/fixtures/forge-change/recordings/safe-critic/604af0fcdd6df6b76208fa88305fdc15c37606c2a4d1ae816477e46ac8c2dd04.json +12 -0
- package/dist/fixtures/forge-change/recordings/safe-critic/f0bf50af11f14c50d07904f0dffe1c8c20fb0cd89770645a8824c1d30a443955.json +12 -0
- package/dist/fixtures/forge-change/recordings/ship-critic/350954b58833b2c04880c67db45a1b328b7fd541d9f0d943b63905b8875488a6.json +12 -0
- package/dist/fixtures/forge-change/recordings/ship-critic/4af95c6c96a206777cec9de1f9c2d8c55a36ddc9b8db2f81d6eb83217b835efa.json +12 -0
- package/dist/fixtures/forge-change/recordings/ship-critic/76c34522a49cf7587a4e5689a5030d384603fa780b8aba97d27815cbc829683e.json +12 -0
- package/dist/fixtures/forge-change/recordings/ship-critic/a3b2cd1ace48587e5994333db03b34c3a0f9dec4f1932f1730ddfb687f6918c8.json +12 -0
- package/dist/fixtures/forge-change/recordings/ship-critic/de288a4fa64d0fc20890f9a787080ce6eac5203b7b9b72d884df11e8cf111835.json +12 -0
- package/dist/fixtures/forge-change/recordings/story-writer/1ddb00eac2aaf91a5ec5d9dfd220116be9f75aec6546a4a3a3b050ed89af2864.json +12 -0
- package/dist/packages/assistant-kit/frameworks-kit/README.md +86 -0
- package/dist/packages/assistant-kit/frameworks-kit/checklist.md +11 -0
- package/dist/packages/assistant-kit/frameworks-kit/examples/tide-lantern.yaml +56 -0
- package/dist/packages/assistant-kit/frameworks-kit/examples/tide-platform.yaml +43 -0
- package/dist/packages/assistant-kit/frameworks-kit/prompts/write-framework-model.md +12 -0
- package/dist/packages/assistant-kit/kit/README.md +98 -0
- package/dist/packages/assistant-kit/kit/c2-reference.md +334 -0
- package/dist/packages/assistant-kit/kit/checklist.md +39 -0
- package/dist/packages/assistant-kit/kit/examples/house-http-client.yaml +102 -0
- package/dist/packages/assistant-kit/kit/examples/tide-apigee.yaml +56 -0
- package/dist/packages/assistant-kit/kit/examples/tide-apim.yaml +32 -0
- package/dist/packages/assistant-kit/kit/examples/tide-kong.yaml +44 -0
- package/dist/packages/assistant-kit/kit/prompts/write-dialect.md +34 -0
- package/dist/packages/assistant-kit/kit/worked-example.md +198 -0
- package/dist/packages/conformance/sample/README.md +4 -0
- package/dist/packages/conformance/sample/inputs/notes.md +3 -0
- package/dist/packages/conformance/sample/inputs/systems.csv +3 -0
- package/dist/packages/conformance/sample/repo/api/greeter.proto +6 -0
- package/dist/packages/conformance/sample/repo/api/openapi.yaml +10 -0
- package/dist/packages/conformance/sample/repo/api/schema.graphql +3 -0
- package/dist/packages/conformance/sample/repo/db/V1__create_greeting.sql +4 -0
- package/dist/packages/conformance/sample/repo/package.json +7 -0
- package/dist/packages/conformance/sample/repo/src/main/java/sample/HelloController.java +10 -0
- package/dist/packages/conformance/sample/repo/web/app.ts +4 -0
- package/dist/packages/evals/datasets/critic-lenses.yaml +62 -0
- package/dist/packages/evals/datasets/dialect-writer.yaml +14 -0
- package/dist/packages/evals/datasets/feature-namer.yaml +34 -0
- package/dist/packages/evals/datasets/glossary-definer.yaml +25 -0
- package/dist/packages/evals/datasets/story-writer.yaml +13 -0
- package/dist/packages/evals/datasets/template-writer.yaml +16 -0
- package/dist/packages/evals/datasets/test-writer.yaml +18 -0
- package/dist/packages/executors/reference/reference-executor.mjs +233 -0
- package/dist/packages/extractors/dialects/argocd.yaml +45 -0
- package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AccountResource.java +47 -0
- package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AuditClient.java +12 -0
- package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/LedgerClient.java +17 -0
- package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/LedgerClient.java +14 -0
- package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/RatesClient.java +11 -0
- package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/StatementController.java +36 -0
- package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/resources/application.yml +7 -0
- package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/java/forge/fraud/FraudScorer.java +27 -0
- package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/resources/application.properties +4 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/api.tf +38 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/main.tf +95 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/terraform.tfvars +1 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/variables.tf +4 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-azure/forge-azure-infra/main.tf +102 -0
- package/dist/packages/extractors/dialects/fixtures/terraform-gcp/forge-gcp-infra/main.tf +51 -0
- package/dist/packages/extractors/dialects/harness.yaml +101 -0
- package/dist/packages/extractors/dialects/jaxrs.yaml +155 -0
- package/dist/packages/extractors/dialects/micronaut.yaml +207 -0
- package/dist/packages/extractors/dialects/quarkus-reactive-messaging.yaml +158 -0
- package/dist/packages/extractors/dialects/tekton.yaml +71 -0
- package/dist/packages/extractors/dialects/terraform-aws.yaml +267 -0
- package/dist/packages/extractors/dialects/terraform-azure.yaml +212 -0
- package/dist/packages/extractors/dialects/terraform-gcp.yaml +109 -0
- package/dist/packages/extractors/grammars/README.md +11 -0
- package/dist/packages/extractors/grammars/tree-sitter-groovy.LICENSE +21 -0
- package/dist/packages/extractors/grammars/tree-sitter-groovy.wasm +0 -0
- package/dist/packages/extractors/grammars/vendored.json +11 -0
- package/dist/packages/learn/lessons/architect-diagrams-and-code.yaml +69 -0
- package/dist/packages/learn/lessons/business-analyst-story-bar.yaml +94 -0
- package/dist/packages/learn/lessons/delivery-lead-release-readiness.yaml +44 -0
- package/dist/packages/learn/lessons/designer-features-in-user-words.yaml +57 -0
- package/dist/packages/learn/lessons/developer-find-your-way.yaml +60 -0
- package/dist/packages/learn/lessons/everyone-first-hour.yaml +74 -0
- package/dist/packages/learn/lessons/platform-lead-coverage-and-defences.yaml +58 -0
- package/dist/packages/learn/lessons/product-owner-first-change.yaml +167 -0
- package/dist/packages/learn/lessons/qa-tests-and-trace.yaml +53 -0
- package/dist/packages/learn/lessons/team-lead-initiative.yaml +146 -0
- package/dist/packages/naysayer/constitution/constitution.yaml +286 -0
- package/dist/packages/naysayer/starter/review.yaml +256 -0
- package/dist/packages/sdk/npm/index.js +8892 -0
- package/dist/packages/speckit/rules/drift.yaml +78 -0
- package/dist/packages/taskrun/rules/conform.yaml +38 -0
- package/dist/packages/testgen/rules/trace.yaml +49 -0
- package/dist/packages/ui/dist/assets/elk-api-tma0MCuh.js +2 -0
- package/dist/packages/ui/dist/assets/elk-worker.min--dAJroGl.js +6401 -0
- package/dist/packages/ui/dist/assets/elk-worker.min-DdYmS5kP.js +2 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
- package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
- package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +29 -0
- package/dist/packages/ui/dist/assets/index-DD_hufQz.css +1 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-BtY48IV_.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-DhS7ScYx.woff2 +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-BQQOj9BB.woff2 +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-DBRwWuxA.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-CXCVEoA9.woff2 +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-Dx02qI2_.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-BPDUZo87.woff2 +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-e0Uj8ZlN.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-BleIgkPp.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-C9ZjJQAt.woff2 +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-BPaQ7tlD.woff +0 -0
- package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-S6aYESQK.woff2 +0 -0
- package/dist/packages/ui/dist/favicon.svg +1 -0
- package/dist/packages/ui/dist/index.html +15 -0
- package/dist/third-party.json +575 -0
- package/dist/vendor/@fission-ai/openspec/bin/openspec.js +85986 -0
- package/dist/vendor/@fission-ai/openspec/package.json +82 -0
- package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/schema.yaml +248 -0
- package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/design.md +21 -0
- package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/proposal.md +34 -0
- package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/spec.md +13 -0
- package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/tasks.md +11 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-c_sharp.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-go.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-java.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-javascript.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-kotlin.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-php.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-python.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-ruby.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-rust.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-scala.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-tsx.wasm +0 -0
- package/dist/vendor/tree-sitter-wasms/out/tree-sitter-typescript.wasm +0 -0
- package/dist/vendor/web-tree-sitter/tree-sitter.wasm +0 -0
- package/package.json +36 -3
|
@@ -0,0 +1,915 @@
|
|
|
1
|
+
import { createRequire as __atticusCreateRequire } from "node:module";
|
|
2
|
+
import { fileURLToPath as __atticusFileURLToPath } from "node:url";
|
|
3
|
+
var require = __atticusCreateRequire(import.meta.url);
|
|
4
|
+
var __atticusUrl = (p) => new URL("./" + p, import.meta.url).href;
|
|
5
|
+
var __atticusPath = (p) => __atticusFileURLToPath(__atticusUrl(p));
|
|
6
|
+
import {
|
|
7
|
+
external_exports,
|
|
8
|
+
require_dist
|
|
9
|
+
} from "./chunk-S2A7YC3Q.js";
|
|
10
|
+
import {
|
|
11
|
+
__toESM
|
|
12
|
+
} from "./chunk-TV45EUGM.js";
|
|
13
|
+
|
|
14
|
+
// packages/openspec-adapter/dist/adapter.js
|
|
15
|
+
import { execFile } from "node:child_process";
|
|
16
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
|
+
import { dirname, join, resolve } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
|
|
21
|
+
// packages/openspec-adapter/dist/results.js
|
|
22
|
+
var OpenSpecRoot = external_exports.looseObject({ path: external_exports.string(), source: external_exports.string() });
|
|
23
|
+
var StatusMessage = external_exports.looseObject({
|
|
24
|
+
severity: external_exports.string(),
|
|
25
|
+
code: external_exports.string(),
|
|
26
|
+
message: external_exports.string(),
|
|
27
|
+
fix: external_exports.string().optional()
|
|
28
|
+
});
|
|
29
|
+
var ErrorEnvelope = external_exports.looseObject({ status: external_exports.array(StatusMessage).min(1) });
|
|
30
|
+
var NewChangeResult = external_exports.looseObject({
|
|
31
|
+
change: external_exports.looseObject({ id: external_exports.string(), path: external_exports.string(), schema: external_exports.string() }),
|
|
32
|
+
root: OpenSpecRoot
|
|
33
|
+
});
|
|
34
|
+
var ArtifactStatus = external_exports.looseObject({
|
|
35
|
+
id: external_exports.string(),
|
|
36
|
+
outputPath: external_exports.string(),
|
|
37
|
+
/** done, ready (all requirements met) or blocked. */
|
|
38
|
+
status: external_exports.string(),
|
|
39
|
+
requires: external_exports.array(external_exports.string()),
|
|
40
|
+
missingDeps: external_exports.array(external_exports.string()).optional()
|
|
41
|
+
});
|
|
42
|
+
var ChangeStatus = external_exports.looseObject({
|
|
43
|
+
changeName: external_exports.string(),
|
|
44
|
+
schemaName: external_exports.string(),
|
|
45
|
+
isComplete: external_exports.boolean(),
|
|
46
|
+
applyRequires: external_exports.array(external_exports.string()),
|
|
47
|
+
artifacts: external_exports.array(ArtifactStatus),
|
|
48
|
+
root: OpenSpecRoot
|
|
49
|
+
});
|
|
50
|
+
var ArtifactInstructions = external_exports.looseObject({
|
|
51
|
+
changeName: external_exports.string(),
|
|
52
|
+
artifactId: external_exports.string(),
|
|
53
|
+
schemaName: external_exports.string(),
|
|
54
|
+
outputPath: external_exports.string(),
|
|
55
|
+
description: external_exports.string(),
|
|
56
|
+
instruction: external_exports.string().optional(),
|
|
57
|
+
template: external_exports.string(),
|
|
58
|
+
dependencies: external_exports.array(external_exports.unknown()),
|
|
59
|
+
unlocks: external_exports.array(external_exports.string()),
|
|
60
|
+
/** openspec/config.yaml's context, for every artifact (OpenSpec 1.13+). */
|
|
61
|
+
context: external_exports.string().optional(),
|
|
62
|
+
/** openspec/config.yaml's rules for this artifact. */
|
|
63
|
+
rules: external_exports.array(external_exports.string()).optional()
|
|
64
|
+
});
|
|
65
|
+
var ApplyTask = external_exports.looseObject({
|
|
66
|
+
id: external_exports.string(),
|
|
67
|
+
description: external_exports.string(),
|
|
68
|
+
done: external_exports.boolean(),
|
|
69
|
+
line: external_exports.number().optional()
|
|
70
|
+
});
|
|
71
|
+
var ApplyInstructions = external_exports.looseObject({
|
|
72
|
+
changeName: external_exports.string(),
|
|
73
|
+
schemaName: external_exports.string(),
|
|
74
|
+
progress: external_exports.looseObject({ total: external_exports.number(), complete: external_exports.number(), remaining: external_exports.number() }),
|
|
75
|
+
tasks: external_exports.array(ApplyTask)
|
|
76
|
+
});
|
|
77
|
+
var ValidationIssue = external_exports.looseObject({
|
|
78
|
+
level: external_exports.enum(["ERROR", "WARNING", "INFO"]),
|
|
79
|
+
path: external_exports.string(),
|
|
80
|
+
message: external_exports.string()
|
|
81
|
+
});
|
|
82
|
+
var ValidationItem = external_exports.looseObject({
|
|
83
|
+
id: external_exports.string(),
|
|
84
|
+
type: external_exports.enum(["change", "spec"]),
|
|
85
|
+
valid: external_exports.boolean(),
|
|
86
|
+
issues: external_exports.array(ValidationIssue)
|
|
87
|
+
});
|
|
88
|
+
var ValidationReport = external_exports.looseObject({
|
|
89
|
+
items: external_exports.array(ValidationItem),
|
|
90
|
+
summary: external_exports.looseObject({
|
|
91
|
+
totals: external_exports.looseObject({ items: external_exports.number(), passed: external_exports.number(), failed: external_exports.number() })
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
var ChangeSummary = external_exports.looseObject({
|
|
95
|
+
name: external_exports.string(),
|
|
96
|
+
completedTasks: external_exports.number(),
|
|
97
|
+
totalTasks: external_exports.number(),
|
|
98
|
+
lastModified: external_exports.string(),
|
|
99
|
+
status: external_exports.string()
|
|
100
|
+
});
|
|
101
|
+
var ChangeList = external_exports.looseObject({ changes: external_exports.array(ChangeSummary) });
|
|
102
|
+
var SpecSummary = external_exports.looseObject({ id: external_exports.string(), requirementCount: external_exports.number() });
|
|
103
|
+
var SpecList = external_exports.looseObject({ specs: external_exports.array(SpecSummary) });
|
|
104
|
+
var Scenario = external_exports.looseObject({ name: external_exports.string(), rawText: external_exports.string() });
|
|
105
|
+
var Requirement = external_exports.looseObject({
|
|
106
|
+
name: external_exports.string(),
|
|
107
|
+
text: external_exports.string(),
|
|
108
|
+
scenarios: external_exports.array(Scenario)
|
|
109
|
+
});
|
|
110
|
+
var Delta = external_exports.looseObject({
|
|
111
|
+
spec: external_exports.string(),
|
|
112
|
+
operation: external_exports.enum(["ADDED", "MODIFIED", "REMOVED", "RENAMED"]),
|
|
113
|
+
description: external_exports.string(),
|
|
114
|
+
requirements: external_exports.array(Requirement).optional()
|
|
115
|
+
});
|
|
116
|
+
var ChangeDetail = external_exports.looseObject({
|
|
117
|
+
id: external_exports.string(),
|
|
118
|
+
title: external_exports.string(),
|
|
119
|
+
deltaCount: external_exports.number(),
|
|
120
|
+
deltas: external_exports.array(Delta)
|
|
121
|
+
});
|
|
122
|
+
var SpecDetail = external_exports.looseObject({
|
|
123
|
+
id: external_exports.string(),
|
|
124
|
+
title: external_exports.string(),
|
|
125
|
+
overview: external_exports.string(),
|
|
126
|
+
requirementCount: external_exports.number(),
|
|
127
|
+
requirements: external_exports.array(Requirement)
|
|
128
|
+
});
|
|
129
|
+
var ArchiveResult = external_exports.looseObject({
|
|
130
|
+
archive: external_exports.looseObject({
|
|
131
|
+
change: external_exports.string(),
|
|
132
|
+
archivedAs: external_exports.string(),
|
|
133
|
+
path: external_exports.string(),
|
|
134
|
+
specsUpdated: external_exports.boolean()
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
var SchemaInfo = external_exports.looseObject({
|
|
138
|
+
name: external_exports.string(),
|
|
139
|
+
description: external_exports.string().optional(),
|
|
140
|
+
artifacts: external_exports.array(external_exports.string()),
|
|
141
|
+
source: external_exports.string()
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// packages/openspec-adapter/dist/adapter.js
|
|
145
|
+
var __atticus_import_meta_url = __atticusUrl("packages/openspec-adapter/dist/adapter.js");
|
|
146
|
+
var OPENSPEC_PINNED = "1.14.0";
|
|
147
|
+
var OPENSPEC_SUPPORTED = { min: "1.13.0", maxExclusive: "2.0.0" };
|
|
148
|
+
function openspecEnv(base = process.env) {
|
|
149
|
+
return {
|
|
150
|
+
...base,
|
|
151
|
+
DO_NOT_TRACK: "1",
|
|
152
|
+
OPENSPEC_TELEMETRY: "0",
|
|
153
|
+
OPENSPEC_NO_UPDATE_CHECK: "1",
|
|
154
|
+
OPENSPEC_NO_AUTO_CONFIG: "1",
|
|
155
|
+
OPENSPEC_NO_COMPLETIONS: "1",
|
|
156
|
+
OPENSPEC_NO_ANIMATION: "1",
|
|
157
|
+
OPEN_SPEC_INTERACTIVE: "0",
|
|
158
|
+
NO_COLOR: "1",
|
|
159
|
+
FORCE_COLOR: "0",
|
|
160
|
+
CI: "1"
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function bundledOpenSpecBin(here = __atticus_import_meta_url) {
|
|
164
|
+
const other = process.env.ATTICUS_OPENSPEC_BIN?.trim();
|
|
165
|
+
if (other)
|
|
166
|
+
return other;
|
|
167
|
+
const shipped = fileURLToPath(new URL("../../../vendor/@fission-ai/openspec/bin/openspec.js", here));
|
|
168
|
+
if (existsSync(shipped))
|
|
169
|
+
return shipped;
|
|
170
|
+
const require2 = createRequire(__atticus_import_meta_url);
|
|
171
|
+
const entry = require2.resolve("@fission-ai/openspec");
|
|
172
|
+
return join(dirname(dirname(entry)), "bin", "openspec.js");
|
|
173
|
+
}
|
|
174
|
+
async function runOpenSpecRaw(args, o) {
|
|
175
|
+
const bin = o.bin ?? bundledOpenSpecBin();
|
|
176
|
+
return new Promise((done, reject) => {
|
|
177
|
+
execFile(process.execPath, [bin, ...args], {
|
|
178
|
+
cwd: resolve(o.root),
|
|
179
|
+
env: openspecEnv(o.env),
|
|
180
|
+
timeout: o.timeoutMs ?? 6e4,
|
|
181
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
182
|
+
windowsHide: true,
|
|
183
|
+
encoding: "utf8"
|
|
184
|
+
}, (err, stdout, stderr) => {
|
|
185
|
+
if (err && err.code === "ENOENT") {
|
|
186
|
+
reject(new OpenSpecError(`OpenSpec could not be started: ${err.message}`, "not_installed", args, null, stderr));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
done({
|
|
190
|
+
stdout,
|
|
191
|
+
stderr,
|
|
192
|
+
exitCode: err ? typeof err.code === "number" ? err.code : 1 : 0
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
var OpenSpecError = class extends Error {
|
|
198
|
+
code;
|
|
199
|
+
args;
|
|
200
|
+
exitCode;
|
|
201
|
+
stderr;
|
|
202
|
+
constructor(message, code, args, exitCode, stderr = "") {
|
|
203
|
+
super(message);
|
|
204
|
+
this.code = code;
|
|
205
|
+
this.args = args;
|
|
206
|
+
this.exitCode = exitCode;
|
|
207
|
+
this.stderr = stderr;
|
|
208
|
+
this.name = "OpenSpecError";
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
function compareVersions(a, b) {
|
|
212
|
+
const split = (v) => {
|
|
213
|
+
const [core = "", pre] = v.trim().replace(/^v/, "").split("-", 2);
|
|
214
|
+
return { nums: core.split(".").map((n) => Number.parseInt(n, 10) || 0), pre };
|
|
215
|
+
};
|
|
216
|
+
const x = split(a);
|
|
217
|
+
const y = split(b);
|
|
218
|
+
for (let i = 0; i < 3; i++) {
|
|
219
|
+
const d = (x.nums[i] ?? 0) - (y.nums[i] ?? 0);
|
|
220
|
+
if (d !== 0)
|
|
221
|
+
return d < 0 ? -1 : 1;
|
|
222
|
+
}
|
|
223
|
+
if (x.pre && !y.pre)
|
|
224
|
+
return -1;
|
|
225
|
+
if (!x.pre && y.pre)
|
|
226
|
+
return 1;
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
function isSupportedVersion(v) {
|
|
230
|
+
return /^v?\d+\.\d+\.\d+$/.test(v.trim()) && compareVersions(v, OPENSPEC_SUPPORTED.min) >= 0 && compareVersions(v, OPENSPEC_SUPPORTED.maxExclusive) < 0;
|
|
231
|
+
}
|
|
232
|
+
function extractJson(stdout) {
|
|
233
|
+
const text = stdout.trim();
|
|
234
|
+
try {
|
|
235
|
+
return JSON.parse(text);
|
|
236
|
+
} catch {
|
|
237
|
+
const lines = text.split(/\r?\n/);
|
|
238
|
+
const start = lines.findIndex((l) => l.startsWith("{") || l.startsWith("["));
|
|
239
|
+
if (start === -1)
|
|
240
|
+
throw new Error("no JSON in OpenSpec output");
|
|
241
|
+
return JSON.parse(lines.slice(start).join("\n"));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
var ID = /^[a-z0-9][a-z0-9._-]*$/;
|
|
245
|
+
function checkId(what, id) {
|
|
246
|
+
if (!ID.test(id) || id.length > 120) {
|
|
247
|
+
throw new OpenSpecError(`${what} "${id}" must be a lowercase slug`, "bad_id", [], null);
|
|
248
|
+
}
|
|
249
|
+
return id;
|
|
250
|
+
}
|
|
251
|
+
function samePath(a, b) {
|
|
252
|
+
const real = (p) => {
|
|
253
|
+
try {
|
|
254
|
+
return realpathSync.native(p);
|
|
255
|
+
} catch {
|
|
256
|
+
return resolve(p);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const x = real(a);
|
|
260
|
+
const y = real(b);
|
|
261
|
+
return process.platform === "win32" ? x.toLowerCase() === y.toLowerCase() : x === y;
|
|
262
|
+
}
|
|
263
|
+
function createOpenSpec(options) {
|
|
264
|
+
const root = resolve(options.root);
|
|
265
|
+
const bin = options.bin ?? bundledOpenSpecBin();
|
|
266
|
+
const timeout = options.timeoutMs ?? 6e4;
|
|
267
|
+
const env = openspecEnv(options.env);
|
|
268
|
+
const run = (args) => new Promise((resolvePromise, reject) => {
|
|
269
|
+
execFile(process.execPath, [bin, ...args], {
|
|
270
|
+
cwd: root,
|
|
271
|
+
env,
|
|
272
|
+
timeout,
|
|
273
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
274
|
+
windowsHide: true,
|
|
275
|
+
encoding: "utf8"
|
|
276
|
+
}, (err, stdout, stderr) => {
|
|
277
|
+
if (err && err.code === "ENOENT") {
|
|
278
|
+
reject(new OpenSpecError(`OpenSpec could not be started: ${err.message}`, "not_installed", args, null, stderr));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (err && err.killed) {
|
|
282
|
+
reject(new OpenSpecError(`OpenSpec timed out after ${timeout} ms`, "timeout", args, null, stderr));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const exitCode = err ? typeof err.code === "number" ? err.code : 1 : 0;
|
|
286
|
+
resolvePromise({ stdout, stderr, exitCode });
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
async function json(args, schema, allowFailure = false) {
|
|
290
|
+
const full = [...args, "--json"];
|
|
291
|
+
const r = await run(full);
|
|
292
|
+
let data;
|
|
293
|
+
try {
|
|
294
|
+
data = extractJson(r.stdout);
|
|
295
|
+
} catch {
|
|
296
|
+
throw new OpenSpecError(`OpenSpec printed no JSON (exit ${r.exitCode}): ${(r.stderr || r.stdout).trim().slice(0, 500)}`, "bad_output", full, r.exitCode, r.stderr);
|
|
297
|
+
}
|
|
298
|
+
const parsed = schema.safeParse(data);
|
|
299
|
+
if (r.exitCode === 0 || allowFailure && parsed.success) {
|
|
300
|
+
if (!parsed.success) {
|
|
301
|
+
throw new OpenSpecError(`OpenSpec output did not match the adapter contract: ${parsed.error.message}`, "contract_mismatch", full, r.exitCode, r.stderr);
|
|
302
|
+
}
|
|
303
|
+
checkRoot(data, full);
|
|
304
|
+
return parsed.data;
|
|
305
|
+
}
|
|
306
|
+
const envelope = ErrorEnvelope.safeParse(data);
|
|
307
|
+
if (envelope.success) {
|
|
308
|
+
const first = envelope.data.status[0];
|
|
309
|
+
throw new OpenSpecError(first.message, first.code, full, r.exitCode, r.stderr);
|
|
310
|
+
}
|
|
311
|
+
throw new OpenSpecError(`OpenSpec failed (exit ${r.exitCode})`, "failed", full, r.exitCode, r.stderr);
|
|
312
|
+
}
|
|
313
|
+
function checkRoot(data, args) {
|
|
314
|
+
const reported = data?.root?.path;
|
|
315
|
+
if (typeof reported === "string" && !samePath(reported, root)) {
|
|
316
|
+
throw new OpenSpecError(`OpenSpec used ${reported} instead of ${root}; run init in the metarepo first`, "root_mismatch", args, 0);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
const api = {
|
|
320
|
+
root,
|
|
321
|
+
async version() {
|
|
322
|
+
const r = await run(["--version"]);
|
|
323
|
+
if (r.exitCode !== 0)
|
|
324
|
+
throw new OpenSpecError("could not read OpenSpec version", "failed", ["--version"], r.exitCode, r.stderr);
|
|
325
|
+
return r.stdout.trim();
|
|
326
|
+
},
|
|
327
|
+
async assertSupported() {
|
|
328
|
+
const v = await api.version();
|
|
329
|
+
if (!isSupportedVersion(v)) {
|
|
330
|
+
throw new OpenSpecError(`OpenSpec ${v} is not supported; Atticus needs >=${OPENSPEC_SUPPORTED.min} <${OPENSPEC_SUPPORTED.maxExclusive} (tested with ${OPENSPEC_PINNED})`, "unsupported_version", ["--version"], 0);
|
|
331
|
+
}
|
|
332
|
+
return v;
|
|
333
|
+
},
|
|
334
|
+
async init() {
|
|
335
|
+
const args = ["init", "--tools", "none", "--no-animation", "--no-copilot-cloud", "."];
|
|
336
|
+
const r = await run(args);
|
|
337
|
+
if (r.exitCode !== 0) {
|
|
338
|
+
throw new OpenSpecError(`openspec init failed: ${(r.stderr || r.stdout).trim().slice(0, 500)}`, "failed", args, r.exitCode, r.stderr);
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
async newChange(id, opts = {}) {
|
|
342
|
+
const args = ["new", "change", checkId("change id", id)];
|
|
343
|
+
if (opts.description)
|
|
344
|
+
args.push("--description", opts.description);
|
|
345
|
+
if (opts.schema)
|
|
346
|
+
args.push("--schema", checkId("schema", opts.schema));
|
|
347
|
+
const r = await json(args, NewChangeResult);
|
|
348
|
+
return { id: r.change.id, path: r.change.path, schema: r.change.schema };
|
|
349
|
+
},
|
|
350
|
+
status: async (change) => json(["status", "--change", checkId("change id", change)], ChangeStatus),
|
|
351
|
+
instructions: async (artifact, change) => json(["instructions", checkId("artifact", artifact), "--change", checkId("change id", change)], ArtifactInstructions),
|
|
352
|
+
applyInstructions: async (change) => json(["instructions", "apply", "--change", checkId("change id", change)], ApplyInstructions),
|
|
353
|
+
async validate(opts = {}) {
|
|
354
|
+
const args = ["validate"];
|
|
355
|
+
if (opts.item)
|
|
356
|
+
args.push(checkId("item", opts.item));
|
|
357
|
+
else
|
|
358
|
+
args.push("--all");
|
|
359
|
+
if (opts.type)
|
|
360
|
+
args.push("--type", opts.type);
|
|
361
|
+
if (opts.strict)
|
|
362
|
+
args.push("--strict");
|
|
363
|
+
args.push("--no-interactive");
|
|
364
|
+
return json(args, ValidationReport, true);
|
|
365
|
+
},
|
|
366
|
+
async listChanges() {
|
|
367
|
+
return (await json(["list"], ChangeList)).changes;
|
|
368
|
+
},
|
|
369
|
+
async listSpecs() {
|
|
370
|
+
return (await json(["list", "--specs"], SpecList)).specs;
|
|
371
|
+
},
|
|
372
|
+
showChange: async (id) => json(["show", checkId("change id", id), "--type", "change"], ChangeDetail),
|
|
373
|
+
showSpec: async (id) => json(["show", checkId("spec id", id), "--type", "spec"], SpecDetail),
|
|
374
|
+
async archive(id, opts = {}) {
|
|
375
|
+
checkId("change id", id);
|
|
376
|
+
if (opts.requireTasksComplete !== false) {
|
|
377
|
+
const change = (await api.listChanges()).find((c) => c.name === id);
|
|
378
|
+
if (!change)
|
|
379
|
+
throw new OpenSpecError(`Change '${id}' not found`, "change_error", ["list"], 1);
|
|
380
|
+
if (change.completedTasks < change.totalTasks) {
|
|
381
|
+
throw new OpenSpecError(`Change '${id}' has ${change.totalTasks - change.completedTasks} unfinished task(s); finish or remove them before archiving`, "tasks_incomplete", ["archive", id], null);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const args = ["archive", id, "--yes"];
|
|
385
|
+
if (opts.skipSpecs)
|
|
386
|
+
args.push("--skip-specs");
|
|
387
|
+
return (await json(args, ArchiveResult)).archive;
|
|
388
|
+
},
|
|
389
|
+
async schemas() {
|
|
390
|
+
return json(["schemas"], external_exports.array(SchemaInfo));
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
return api;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// packages/openspec-adapter/dist/org-flow.js
|
|
397
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
398
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
399
|
+
import { join as join2 } from "node:path";
|
|
400
|
+
var ORG_FLOW = "org-flow";
|
|
401
|
+
var ORG_FLOW_VERSION = 2;
|
|
402
|
+
var ARTIFACTS = [
|
|
403
|
+
{
|
|
404
|
+
id: "proposal",
|
|
405
|
+
generates: "proposal.md",
|
|
406
|
+
description: "Why the change is needed and what it changes: the brief placed against the estate",
|
|
407
|
+
requires: [],
|
|
408
|
+
stage: "feature",
|
|
409
|
+
instruction: `Generated by the feature stage (atticus change feature) from brief.md and feature.yaml;
|
|
410
|
+
edit feature.yaml and run the stage again, never proposal.md. brief.md is the product owner's source:
|
|
411
|
+
add no scope it does not ask for, and raise anything unclear as a question to its owner.
|
|
412
|
+
|
|
413
|
+
- Why: the problem in the brief, in one or two sentences.
|
|
414
|
+
- What Changes: the feature in plain words, each flow it changes, and each new flow.
|
|
415
|
+
- Capabilities: the flows the change adds or changes; each becomes specs/<capability>/spec.md.
|
|
416
|
+
- Impact: the repos and systems the flows run in, and the gaps that need decisions.
|
|
417
|
+
- Open questions: what the brief leaves undecided.`,
|
|
418
|
+
template: `# Proposal
|
|
419
|
+
|
|
420
|
+
## Why
|
|
421
|
+
|
|
422
|
+
<!-- The problem or opportunity, and why now. -->
|
|
423
|
+
|
|
424
|
+
## What Changes
|
|
425
|
+
|
|
426
|
+
- <!-- Specific change. Mark breaking changes with **BREAKING**. -->
|
|
427
|
+
|
|
428
|
+
## Capabilities
|
|
429
|
+
|
|
430
|
+
### New Capabilities
|
|
431
|
+
- \`<capability>\`: <!-- what it covers -->
|
|
432
|
+
|
|
433
|
+
### Modified Capabilities
|
|
434
|
+
- \`<existing-capability>\`: <!-- what requirement changes -->
|
|
435
|
+
|
|
436
|
+
## Impact
|
|
437
|
+
|
|
438
|
+
<!-- Repos, systems, APIs, data, consumers. -->
|
|
439
|
+
|
|
440
|
+
## Open questions
|
|
441
|
+
|
|
442
|
+
- <!-- Question \u2014 who should answer -->
|
|
443
|
+
`
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
id: "design",
|
|
447
|
+
generates: "design.md",
|
|
448
|
+
description: "How the change is built: target flows, interface and data changes, deploy order, rollout and rollback",
|
|
449
|
+
requires: ["proposal"],
|
|
450
|
+
stage: "architecture",
|
|
451
|
+
instruction: `Generated by the architecture stage (atticus change architecture) from target-flows/;
|
|
452
|
+
edit the target flows and run the stage again. Every step of a target flow is placed in the code it
|
|
453
|
+
changes (at), the new file it creates (new) or the code it calls (uses), cited from verified facts.
|
|
454
|
+
|
|
455
|
+
design.md covers: each target flow and what it changes; the flows read unchanged; interface changes
|
|
456
|
+
with their consumers; data changes with their migrations; the deploy order across repos; and Rollout
|
|
457
|
+
and rollback: how each store write and migration is undone, or why it needs no undo (an expand-only
|
|
458
|
+
migration), and what happens to rows written in between.`,
|
|
459
|
+
template: `# Design
|
|
460
|
+
|
|
461
|
+
## Target flows
|
|
462
|
+
|
|
463
|
+
## Interface changes
|
|
464
|
+
|
|
465
|
+
## Data changes
|
|
466
|
+
|
|
467
|
+
## Deploy order
|
|
468
|
+
|
|
469
|
+
## Rollout and rollback
|
|
470
|
+
|
|
471
|
+
| Store or migration | How it is undone | Rows written in between |
|
|
472
|
+
| --- | --- | --- |
|
|
473
|
+
| | | |
|
|
474
|
+
`
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
id: "stories",
|
|
478
|
+
generates: "stories.md",
|
|
479
|
+
description: "Index of user stories; each story lives in stories/<story-id>.md",
|
|
480
|
+
requires: ["design"],
|
|
481
|
+
stage: "stories",
|
|
482
|
+
instruction: `Generated by the stories stage (atticus plan stories): one story per target flow, at
|
|
483
|
+
stories/<story-id>.md, and stories.md as the index. A story says who wants what and why, its tasks
|
|
484
|
+
(each once: where the code goes, the files, the criteria that accept it), its acceptance criteria in
|
|
485
|
+
Given/When/Then form, its interface and data changes, non-functional needs, tests, dependencies and
|
|
486
|
+
definition of done. Each task's prompt for Copilot or Claude Code is a file of its own,
|
|
487
|
+
tasks/<story>.<task>.prompt.md. A story without acceptance criteria is not ready.`,
|
|
488
|
+
template: `# Stories
|
|
489
|
+
|
|
490
|
+
| Story | Title | Repos | Depends on |
|
|
491
|
+
| --- | --- | --- | --- |
|
|
492
|
+
| <!-- s1 --> | | | |
|
|
493
|
+
`
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
id: "specs",
|
|
497
|
+
generates: "specs/**/*.md",
|
|
498
|
+
description: "Behaviour the change adds, modifies or removes, as OpenSpec delta specs generated from the stories",
|
|
499
|
+
requires: ["stories"],
|
|
500
|
+
stage: "stories",
|
|
501
|
+
instruction: `Generated by the stories stage from the stories' acceptance criteria, with no model
|
|
502
|
+
call: one capability per flow (specs/<capability>/spec.md), a requirement per story with SHALL
|
|
503
|
+
wording, and a scenario per criterion (WHEN/THEN). A capability already in openspec/specs is
|
|
504
|
+
MODIFIED, carrying its archived scenarios; a removed flow's requirements are REMOVED. The stage
|
|
505
|
+
runs openspec validate --strict on them; edit the stories, never the specs.`,
|
|
506
|
+
template: `## ADDED Requirements
|
|
507
|
+
|
|
508
|
+
### Requirement: <!-- name -->
|
|
509
|
+
The system SHALL <!-- behaviour -->.
|
|
510
|
+
|
|
511
|
+
#### Scenario: <!-- name -->
|
|
512
|
+
- **WHEN** <!-- condition -->
|
|
513
|
+
- **THEN** <!-- outcome -->
|
|
514
|
+
`
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
id: "tasks",
|
|
518
|
+
generates: "tasks.md",
|
|
519
|
+
description: "Implementation checklist grouped by repo, numbered per story",
|
|
520
|
+
requires: ["stories"],
|
|
521
|
+
stage: "stories",
|
|
522
|
+
instruction: `Generated by the stories stage: one "## <repo-id>" heading per repo, and under it a
|
|
523
|
+
checkbox "- [ ] <story>.<task> <title> (story <story-id>)" per task, numbered per story without gaps,
|
|
524
|
+
each small enough for one pull request. Tick a task when its tests pass; openspec counts the boxes.`,
|
|
525
|
+
template: `# Tasks
|
|
526
|
+
|
|
527
|
+
## <!-- repo-id -->
|
|
528
|
+
|
|
529
|
+
- [ ] 1.1 <!-- task (story s1) -->
|
|
530
|
+
`
|
|
531
|
+
}
|
|
532
|
+
];
|
|
533
|
+
function orgFlowSchema() {
|
|
534
|
+
return {
|
|
535
|
+
name: ORG_FLOW,
|
|
536
|
+
version: ORG_FLOW_VERSION,
|
|
537
|
+
description: "Atticus 2 change flow - proposal (feature) \u2192 design (architecture) \u2192 stories \u2192 specs, tasks",
|
|
538
|
+
artifacts: ARTIFACTS.map((a) => ({
|
|
539
|
+
id: a.id,
|
|
540
|
+
generates: a.generates,
|
|
541
|
+
description: a.description,
|
|
542
|
+
template: `${a.id}.md`,
|
|
543
|
+
instruction: a.instruction + "\n",
|
|
544
|
+
requires: a.requires
|
|
545
|
+
})),
|
|
546
|
+
apply: {
|
|
547
|
+
requires: ["tasks"],
|
|
548
|
+
tracks: "tasks.md",
|
|
549
|
+
instruction: "Run one task at a time with atticus task <change> <task>, in the change's worktrees, in task order. Tick each task in tasks.md when its tests pass. Stop and ask when a task conflicts with the specs or design.\n"
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
var ORG_FLOW_ARTIFACTS = ARTIFACTS.map((a) => a.id);
|
|
554
|
+
var ARTIFACT_STAGE = Object.fromEntries(ARTIFACTS.map((a) => [a.id, a.stage]));
|
|
555
|
+
var artifactsOfStage = (stage) => ARTIFACTS.filter((a) => a.stage === stage).map((a) => a.id);
|
|
556
|
+
var ORG_FLOW_V1_ONLY = ["interfaces", "mappings", "data", "snow"];
|
|
557
|
+
async function orgFlowVersionOf(root) {
|
|
558
|
+
const text = await readFile(join2(root, "openspec", "schemas", ORG_FLOW, "schema.yaml"), "utf8").catch(() => void 0);
|
|
559
|
+
if (text === void 0)
|
|
560
|
+
return void 0;
|
|
561
|
+
try {
|
|
562
|
+
const v = (0, import_yaml.parse)(text)?.version;
|
|
563
|
+
return typeof v === "number" ? v : 1;
|
|
564
|
+
} catch {
|
|
565
|
+
return 1;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
async function writeOrgFlowSchema(root) {
|
|
569
|
+
const dir = join2(root, "openspec", "schemas", ORG_FLOW);
|
|
570
|
+
await mkdir(join2(dir, "templates"), { recursive: true });
|
|
571
|
+
const header = "# Generated by Atticus from the org pack. Do not edit; change org-pack/process and regenerate.\n";
|
|
572
|
+
await writeFile(join2(dir, "schema.yaml"), header + (0, import_yaml.stringify)(orgFlowSchema(), { lineWidth: 0 }), "utf8");
|
|
573
|
+
for (const a of ARTIFACTS) {
|
|
574
|
+
await writeFile(join2(dir, "templates", `${a.id}.md`), a.template, "utf8");
|
|
575
|
+
}
|
|
576
|
+
for (const id of ORG_FLOW_V1_ONLY)
|
|
577
|
+
await rm(join2(dir, "templates", `${id}.md`), { force: true });
|
|
578
|
+
return dir;
|
|
579
|
+
}
|
|
580
|
+
async function setDefaultSchema(root, schema) {
|
|
581
|
+
const path = join2(root, "openspec", "config.yaml");
|
|
582
|
+
let text = "";
|
|
583
|
+
try {
|
|
584
|
+
text = await readFile(path, "utf8");
|
|
585
|
+
} catch {
|
|
586
|
+
}
|
|
587
|
+
const doc = (0, import_yaml.parseDocument)(text);
|
|
588
|
+
doc.set("schema", schema);
|
|
589
|
+
await writeFile(path, doc.toString({ lineWidth: 0 }), "utf8");
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// packages/openspec-adapter/dist/stores.js
|
|
593
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
594
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
595
|
+
import { mkdir as mkdir2, readdir, readFile as readFile2, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
596
|
+
import { join as join3 } from "node:path";
|
|
597
|
+
var STORE_MARKER_DIR = ".openspec-store";
|
|
598
|
+
var STORE_MARKER = `${STORE_MARKER_DIR}/store.yaml`;
|
|
599
|
+
var STORE_MARKER_VERSION = 1;
|
|
600
|
+
var KEBAB = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
601
|
+
function storeIdOf(name) {
|
|
602
|
+
const id = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
603
|
+
return id && KEBAB.test(id) ? id : void 0;
|
|
604
|
+
}
|
|
605
|
+
function storeMarkerText(m) {
|
|
606
|
+
if (!KEBAB.test(m.id))
|
|
607
|
+
throw new Error(`"${m.id}" can't be an OpenSpec store id: it must be kebab-case (lowercase letters, numbers, single hyphens)`);
|
|
608
|
+
return (0, import_yaml2.stringify)({
|
|
609
|
+
version: STORE_MARKER_VERSION,
|
|
610
|
+
id: m.id,
|
|
611
|
+
...m.remote ? { remote: m.remote } : {}
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
function parseStoreMarker(text) {
|
|
615
|
+
let raw;
|
|
616
|
+
try {
|
|
617
|
+
raw = (0, import_yaml2.parse)(text);
|
|
618
|
+
} catch (e) {
|
|
619
|
+
return { notes: [`store.yaml isn't YAML: ${e.message.split("\n")[0]}`] };
|
|
620
|
+
}
|
|
621
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
622
|
+
return { notes: ["store.yaml isn't a mapping"] };
|
|
623
|
+
const o = raw;
|
|
624
|
+
const notes = [];
|
|
625
|
+
if (o.version !== STORE_MARKER_VERSION)
|
|
626
|
+
notes.push(`store.yaml is version ${String(o.version ?? "(none)")}, newer than the version ${STORE_MARKER_VERSION} Atticus knows; read its id and remote only (the store format is beta)`);
|
|
627
|
+
if (typeof o.id !== "string" || !o.id)
|
|
628
|
+
return { notes: [...notes, "store.yaml has no id"] };
|
|
629
|
+
return {
|
|
630
|
+
marker: {
|
|
631
|
+
id: o.id,
|
|
632
|
+
...typeof o.remote === "string" && o.remote ? { remote: o.remote } : {}
|
|
633
|
+
},
|
|
634
|
+
notes
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
async function readStoreMarker(dir) {
|
|
638
|
+
let text;
|
|
639
|
+
try {
|
|
640
|
+
text = await readFile2(join3(dir, STORE_MARKER_DIR, "store.yaml"), "utf8");
|
|
641
|
+
} catch {
|
|
642
|
+
return { missing: true, notes: [] };
|
|
643
|
+
}
|
|
644
|
+
return { ...parseStoreMarker(text), missing: false };
|
|
645
|
+
}
|
|
646
|
+
async function writeStoreMarker(dir, m) {
|
|
647
|
+
const text = storeMarkerText(m);
|
|
648
|
+
const have = await readStoreMarker(dir);
|
|
649
|
+
if (!have.missing)
|
|
650
|
+
return {
|
|
651
|
+
action: have.marker?.id === m.id ? "present" : "differs",
|
|
652
|
+
...have.marker ? { marker: have.marker } : {}
|
|
653
|
+
};
|
|
654
|
+
await mkdir2(join3(dir, STORE_MARKER_DIR), { recursive: true });
|
|
655
|
+
await writeFile2(join3(dir, STORE_MARKER_DIR, "store.yaml"), text, {
|
|
656
|
+
encoding: "utf8",
|
|
657
|
+
flag: "wx"
|
|
658
|
+
});
|
|
659
|
+
return { action: "created", marker: { id: m.id, ...m.remote ? { remote: m.remote } : {} } };
|
|
660
|
+
}
|
|
661
|
+
function addStoreReference(text, ref) {
|
|
662
|
+
const parsed = (0, import_yaml2.parseDocument)(text);
|
|
663
|
+
if (parsed.errors.length)
|
|
664
|
+
return {
|
|
665
|
+
problem: `openspec/config.yaml isn't YAML: ${parsed.errors[0].message.split("\n")[0]}`
|
|
666
|
+
};
|
|
667
|
+
const doc = parsed;
|
|
668
|
+
if (doc.contents === null || doc.contents === void 0)
|
|
669
|
+
doc.contents = doc.createNode({});
|
|
670
|
+
if (!(0, import_yaml2.isMap)(doc.contents))
|
|
671
|
+
return { problem: "openspec/config.yaml isn't a mapping; left as it is" };
|
|
672
|
+
const entry = ref.remote ? { id: ref.id, remote: ref.remote } : ref.id;
|
|
673
|
+
const list = doc.get("references", true);
|
|
674
|
+
if (list === void 0 || list === null || (0, import_yaml2.isScalar)(list) && list.value === null) {
|
|
675
|
+
doc.set("references", doc.createNode([entry]));
|
|
676
|
+
return { text: doc.toString(), action: "added" };
|
|
677
|
+
}
|
|
678
|
+
if (!(0, import_yaml2.isSeq)(list))
|
|
679
|
+
return { problem: "references: in openspec/config.yaml isn't a list; left as it is" };
|
|
680
|
+
const idOf = (item) => (0, import_yaml2.isScalar)(item) ? item.value : (0, import_yaml2.isMap)(item) ? item.get("id") : void 0;
|
|
681
|
+
if (list.items.some((i) => idOf(i) === ref.id))
|
|
682
|
+
return { text, action: "present" };
|
|
683
|
+
list.add(doc.createNode(entry));
|
|
684
|
+
return { text: doc.toString(), action: "added" };
|
|
685
|
+
}
|
|
686
|
+
var isDir = (p) => stat(p).then((s) => s.isDirectory(), () => false);
|
|
687
|
+
async function subdirs(dir) {
|
|
688
|
+
try {
|
|
689
|
+
return (await readdir(dir, { withFileTypes: true })).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
|
|
690
|
+
} catch {
|
|
691
|
+
return [];
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
function purposeLine(markdown) {
|
|
695
|
+
let fence;
|
|
696
|
+
let inPurpose = false;
|
|
697
|
+
for (const line of markdown.split(/\r?\n/)) {
|
|
698
|
+
const f = /^\s*(```|~~~)/.exec(line);
|
|
699
|
+
if (f) {
|
|
700
|
+
if (fence === void 0)
|
|
701
|
+
fence = f[1];
|
|
702
|
+
else if (f[1] === fence)
|
|
703
|
+
fence = void 0;
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
if (fence !== void 0)
|
|
707
|
+
continue;
|
|
708
|
+
const h = /^#{1,6}\s+(.*?)(?:\s+#+)?\s*$/.exec(line);
|
|
709
|
+
if (h) {
|
|
710
|
+
if (inPurpose)
|
|
711
|
+
return void 0;
|
|
712
|
+
inPurpose = h[1].trim().toLowerCase() === "purpose";
|
|
713
|
+
continue;
|
|
714
|
+
}
|
|
715
|
+
if (inPurpose && line.trim())
|
|
716
|
+
return line.trim();
|
|
717
|
+
}
|
|
718
|
+
return void 0;
|
|
719
|
+
}
|
|
720
|
+
async function readStore(dir) {
|
|
721
|
+
const view = { dir, changes: [], specs: [], notes: [] };
|
|
722
|
+
if (!await isDir(dir)) {
|
|
723
|
+
view.notes.push(`${dir} isn't there`);
|
|
724
|
+
return view;
|
|
725
|
+
}
|
|
726
|
+
const m = await readStoreMarker(dir);
|
|
727
|
+
if (m.missing)
|
|
728
|
+
view.notes.push(`no ${STORE_MARKER}: read as a plain OpenSpec folder`);
|
|
729
|
+
view.notes.push(...m.notes);
|
|
730
|
+
if (m.marker) {
|
|
731
|
+
view.id = m.marker.id;
|
|
732
|
+
if (m.marker.remote)
|
|
733
|
+
view.remote = m.marker.remote;
|
|
734
|
+
}
|
|
735
|
+
const os = join3(dir, "openspec");
|
|
736
|
+
if (!await isDir(os)) {
|
|
737
|
+
view.notes.push("no openspec/ folder: nothing to read");
|
|
738
|
+
return view;
|
|
739
|
+
}
|
|
740
|
+
for (const id of await subdirs(join3(os, "changes"))) {
|
|
741
|
+
if (id === "archive")
|
|
742
|
+
continue;
|
|
743
|
+
const cdir = join3(os, "changes", id);
|
|
744
|
+
const proposal = await readFile2(join3(cdir, "proposal.md"), "utf8").catch(() => "");
|
|
745
|
+
const title = /^#\s+(.+?)\s*#*\s*$/m.exec(proposal)?.[1];
|
|
746
|
+
const tasks = await readFile2(join3(cdir, "tasks.md"), "utf8").catch(() => void 0);
|
|
747
|
+
const boxes = tasks ? [...tasks.matchAll(/^\s*[-*]\s+\[([ xX])\]/gm)].map((x) => x[1]) : [];
|
|
748
|
+
view.changes.push({
|
|
749
|
+
id,
|
|
750
|
+
...title ? { title } : {},
|
|
751
|
+
...boxes.length ? { tasks: { done: boxes.filter((b) => b !== " ").length, total: boxes.length } } : {},
|
|
752
|
+
dir: cdir
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
for (const id of await subdirs(join3(os, "specs"))) {
|
|
756
|
+
const file = join3(os, "specs", id, "spec.md");
|
|
757
|
+
const text = await readFile2(file, "utf8").catch(() => void 0);
|
|
758
|
+
if (text === void 0)
|
|
759
|
+
continue;
|
|
760
|
+
const purpose = purposeLine(text);
|
|
761
|
+
view.specs.push({ id, ...purpose ? { purpose } : {}, file });
|
|
762
|
+
}
|
|
763
|
+
return view;
|
|
764
|
+
}
|
|
765
|
+
function openspecHasStores(o = {}) {
|
|
766
|
+
return new Promise((done) => {
|
|
767
|
+
let bin;
|
|
768
|
+
try {
|
|
769
|
+
bin = o.bin ?? bundledOpenSpecBin();
|
|
770
|
+
} catch {
|
|
771
|
+
done(false);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
execFile2(process.execPath, [bin, "store", "--help"], {
|
|
775
|
+
env: openspecEnv(o.env),
|
|
776
|
+
timeout: o.timeoutMs ?? 3e4,
|
|
777
|
+
windowsHide: true,
|
|
778
|
+
encoding: "utf8"
|
|
779
|
+
}, (err, stdout) => done(!err && /\bregister\b/.test(stdout)));
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// packages/openspec-adapter/dist/features.js
|
|
784
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
785
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
786
|
+
import { join as join4 } from "node:path";
|
|
787
|
+
var BETA_FEATURES = [
|
|
788
|
+
"store",
|
|
789
|
+
"store list",
|
|
790
|
+
"store doctor",
|
|
791
|
+
"workset",
|
|
792
|
+
"context",
|
|
793
|
+
"doctor",
|
|
794
|
+
"schema",
|
|
795
|
+
"schemas"
|
|
796
|
+
];
|
|
797
|
+
var cache = /* @__PURE__ */ new Map();
|
|
798
|
+
function help(bin, args, env) {
|
|
799
|
+
return new Promise((done) => {
|
|
800
|
+
execFile3(process.execPath, [bin, ...args, "--help"], { env: openspecEnv(env), timeout: 3e4, windowsHide: true, encoding: "utf8" }, (err, stdout) => done(err ? "" : stdout));
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function commandsIn(text) {
|
|
804
|
+
const at = text.search(/^Commands:\s*$/m);
|
|
805
|
+
if (at < 0)
|
|
806
|
+
return [];
|
|
807
|
+
const out = [];
|
|
808
|
+
for (const l of text.slice(at).split(/\r?\n/).slice(1)) {
|
|
809
|
+
const m = /^ {2}([a-z][a-z0-9-]*)(?:\|[a-z0-9-]+)?\b/.exec(l);
|
|
810
|
+
if (m)
|
|
811
|
+
out.push(m[1]);
|
|
812
|
+
}
|
|
813
|
+
return out;
|
|
814
|
+
}
|
|
815
|
+
function openspecFeatures(o = {}) {
|
|
816
|
+
const bin = o.bin ?? bundledOpenSpecBin();
|
|
817
|
+
const had = cache.get(bin);
|
|
818
|
+
if (had)
|
|
819
|
+
return had;
|
|
820
|
+
const p = (async () => {
|
|
821
|
+
const top = commandsIn(await help(bin, [], o.env));
|
|
822
|
+
const has = (c) => top.includes(c);
|
|
823
|
+
const sub = async (c) => has(c) ? await help(bin, [c], o.env) : "";
|
|
824
|
+
const [store, ctx, doctor, workset] = await Promise.all([
|
|
825
|
+
sub("store"),
|
|
826
|
+
sub("context"),
|
|
827
|
+
sub("doctor"),
|
|
828
|
+
sub("workset")
|
|
829
|
+
]);
|
|
830
|
+
const storeCmds = commandsIn(store);
|
|
831
|
+
const storeList = storeCmds.includes("list") ? await help(bin, ["store", "list"], o.env) : "";
|
|
832
|
+
const storeDoctor = storeCmds.includes("doctor") ? await help(bin, ["store", "doctor"], o.env) : "";
|
|
833
|
+
const json = (t) => /--json\b/.test(t);
|
|
834
|
+
const beta = {
|
|
835
|
+
store: { present: has("store"), json: false },
|
|
836
|
+
"store list": { present: storeCmds.includes("list"), json: json(storeList) },
|
|
837
|
+
"store doctor": { present: storeCmds.includes("doctor"), json: json(storeDoctor) },
|
|
838
|
+
workset: { present: has("workset"), json: json(workset) },
|
|
839
|
+
context: { present: has("context"), json: json(ctx) },
|
|
840
|
+
doctor: { present: has("doctor"), json: json(doctor) },
|
|
841
|
+
schema: { present: has("schema"), json: false },
|
|
842
|
+
schemas: { present: has("schemas"), json: true }
|
|
843
|
+
};
|
|
844
|
+
return { commands: top, beta };
|
|
845
|
+
})();
|
|
846
|
+
cache.set(bin, p);
|
|
847
|
+
return p;
|
|
848
|
+
}
|
|
849
|
+
async function readStoreVia(dir, o = {}) {
|
|
850
|
+
const files = await readStore(dir);
|
|
851
|
+
if (!existsSync2(join4(dir, "openspec")))
|
|
852
|
+
return { ...files, via: "files" };
|
|
853
|
+
try {
|
|
854
|
+
const os = createOpenSpec({
|
|
855
|
+
root: dir,
|
|
856
|
+
...o.bin ? { bin: o.bin } : {},
|
|
857
|
+
...o.env ? { env: o.env } : {}
|
|
858
|
+
});
|
|
859
|
+
const changes = await os.listChanges();
|
|
860
|
+
const specs = await os.listSpecs();
|
|
861
|
+
return {
|
|
862
|
+
...files,
|
|
863
|
+
changes: await Promise.all(changes.map(async (c) => {
|
|
864
|
+
const title = await os.showChange(c.name).then((d) => d.title).catch(() => void 0);
|
|
865
|
+
return {
|
|
866
|
+
id: c.name,
|
|
867
|
+
...title && title !== c.name ? { title } : {},
|
|
868
|
+
...c.totalTasks ? { tasks: { done: c.completedTasks, total: c.totalTasks } } : {},
|
|
869
|
+
dir: files.changes.find((x) => x.id === c.name)?.dir ?? join4(dir, "openspec", "changes", c.name)
|
|
870
|
+
};
|
|
871
|
+
})),
|
|
872
|
+
specs: specs.map((s) => {
|
|
873
|
+
const f = files.specs.find((x) => x.id === s.id);
|
|
874
|
+
return {
|
|
875
|
+
id: s.id,
|
|
876
|
+
...f?.purpose ? { purpose: f.purpose } : {},
|
|
877
|
+
file: f?.file ?? join4(dir, "openspec", "specs", s.id, "spec.md")
|
|
878
|
+
};
|
|
879
|
+
}),
|
|
880
|
+
via: "openspec"
|
|
881
|
+
};
|
|
882
|
+
} catch (e) {
|
|
883
|
+
return {
|
|
884
|
+
...files,
|
|
885
|
+
notes: [
|
|
886
|
+
...files.notes,
|
|
887
|
+
`read from its files: openspec list couldn't run (${e.message.split("\n")[0]})`
|
|
888
|
+
],
|
|
889
|
+
via: "files"
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export {
|
|
895
|
+
OPENSPEC_PINNED,
|
|
896
|
+
runOpenSpecRaw,
|
|
897
|
+
isSupportedVersion,
|
|
898
|
+
createOpenSpec,
|
|
899
|
+
ORG_FLOW,
|
|
900
|
+
ORG_FLOW_VERSION,
|
|
901
|
+
ARTIFACT_STAGE,
|
|
902
|
+
artifactsOfStage,
|
|
903
|
+
orgFlowVersionOf,
|
|
904
|
+
writeOrgFlowSchema,
|
|
905
|
+
setDefaultSchema,
|
|
906
|
+
STORE_MARKER,
|
|
907
|
+
storeIdOf,
|
|
908
|
+
readStoreMarker,
|
|
909
|
+
writeStoreMarker,
|
|
910
|
+
addStoreReference,
|
|
911
|
+
openspecHasStores,
|
|
912
|
+
BETA_FEATURES,
|
|
913
|
+
openspecFeatures,
|
|
914
|
+
readStoreVia
|
|
915
|
+
};
|