gitifact 0.5.0 → 0.6.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 (183) hide show
  1. package/README.md +2 -2
  2. package/dist/THIRD_PARTY_NOTICES.txt +3495 -191
  3. package/dist/browser/assets/BottomSheet-BFoM6syr.js +1 -0
  4. package/dist/browser/assets/Grid-C9rNT-fL.js +1 -0
  5. package/dist/browser/assets/Icon-DPaLmsmh.js +4 -0
  6. package/dist/browser/assets/IconButton-Br-4XhQr.js +1 -0
  7. package/dist/browser/assets/Markdown-Bc6pMi97.js +68 -0
  8. package/dist/browser/assets/{MenuBottomSheet-CQA7HL9k.js → MenuBottomSheet-Dgz4h1S7.js} +1 -1
  9. package/dist/browser/assets/MetadataListItem-BjA4nmg3.js +1 -0
  10. package/dist/browser/assets/ProgressBarMarkTooltip-BxGSd9KS.js +1 -0
  11. package/dist/browser/assets/Section-Z2PuhE6c.js +1 -0
  12. package/dist/browser/assets/Table-DodMTw3P.js +3 -0
  13. package/dist/browser/assets/TimestampHoverCard-BJShn6bb.js +1 -0
  14. package/dist/browser/assets/Tooltip-MoU3alsv.js +1 -0
  15. package/dist/browser/assets/abnfDiagram-VCTEODGH-DmAlk-TR.js +1 -0
  16. package/dist/browser/assets/{about-D6bBZN8p.js → about-CmwTK0Rl.js} +1 -1
  17. package/dist/browser/assets/activity-BF4_xkCU.js +1 -0
  18. package/dist/browser/assets/appearance-pAOSjMU4.js +1 -0
  19. package/dist/browser/assets/arc-Pry-7G1_.js +1 -0
  20. package/dist/browser/assets/architecture-7GRP2DOG-BuddTnfb.js +1 -0
  21. package/dist/browser/assets/architectureDiagram-5GKGNRK7-VwuVv8aO.js +36 -0
  22. package/dist/browser/assets/array-BifhSqXX.js +1 -0
  23. package/dist/browser/assets/blockDiagram-I7D4REHJ-BY92gQgN.js +129 -0
  24. package/dist/browser/assets/c4Diagram-7LVT6UL2-D5TNBYXh.js +38 -0
  25. package/dist/browser/assets/changelog-Dm-wCZt4.js +2 -0
  26. package/dist/browser/assets/channel-NEbtzeVB.js +1 -0
  27. package/dist/browser/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  28. package/dist/browser/assets/chunk-4HAMMTFA-DBbX-wzu.js +62 -0
  29. package/dist/browser/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  30. package/dist/browser/assets/chunk-75Z2AOVW-962-yyBD.js +2 -0
  31. package/dist/browser/assets/chunk-DU6HZSFF-CHHMX1CR.js +127 -0
  32. package/dist/browser/assets/chunk-F27PBJKO-BOnYAGjZ.js +1 -0
  33. package/dist/browser/assets/chunk-FOHPRMQF-DzxwRta7.js +161 -0
  34. package/dist/browser/assets/chunk-GMAD6QVW-DQF31PdR.js +72 -0
  35. package/dist/browser/assets/chunk-GVQU2GXP-rruJzn36.js +1 -0
  36. package/dist/browser/assets/chunk-IMKFNOWR-CZ8ptS4j.js +231 -0
  37. package/dist/browser/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  38. package/dist/browser/assets/chunk-L3NEJ4N5-USlKRxmU.js +1 -0
  39. package/dist/browser/assets/chunk-OSK3NFVY-DYQeYWNP.js +10 -0
  40. package/dist/browser/assets/chunk-P2QGCYS3-SDkZ9hQX.js +1 -0
  41. package/dist/browser/assets/chunk-POPQ4Y6H-bdnFdIMc.js +1 -0
  42. package/dist/browser/assets/chunk-PWAF6VOD-DuKrEmQw.js +1 -0
  43. package/dist/browser/assets/chunk-SHT3W25Y-IggbHeog.js +168 -0
  44. package/dist/browser/assets/chunk-SVP7TREG-BxYPjkqU.js +88 -0
  45. package/dist/browser/assets/chunk-TICWLB2K-DMrY9ez0.js +206 -0
  46. package/dist/browser/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  47. package/dist/browser/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  48. package/dist/browser/assets/classDiagram-ZZMXUADV-BwE_Hs5R.js +1 -0
  49. package/dist/browser/assets/classDiagram-v2-VYDZK3BY-BwE_Hs5R.js +1 -0
  50. package/dist/browser/assets/{container.stylex-oPimSCGl.js → container.stylex-rwI38dw9.js} +1 -1
  51. package/dist/browser/assets/{contributors._email-BZevZqRL.js → contributors._email-C99eiup4.js} +1 -1
  52. package/dist/browser/assets/contributors.index-BzPuT_XG.js +1 -0
  53. package/dist/browser/assets/cose-bilkent-JH36ORCC-BEpcWcmK.js +1 -0
  54. package/dist/browser/assets/cynefin-OW5HDTMX-C4N2LLi1.js +1 -0
  55. package/dist/browser/assets/cynefinDiagram-5FMLGOSQ-C3KE8asf.js +62 -0
  56. package/dist/browser/assets/cytoscape.esm-Yq6u8L66.js +321 -0
  57. package/dist/browser/assets/dagre-C-rnJpZF.js +1 -0
  58. package/dist/browser/assets/dagre-GXQ25YYZ-C20xAaTE.js +4 -0
  59. package/dist/browser/assets/defaultLocale-BFoDCU3G.js +1 -0
  60. package/dist/browser/assets/diagram-S7CK7UJ4-6wtbgLIX.js +30 -0
  61. package/dist/browser/assets/diagram-UQ7AKVKN-BA02zKbd.js +41 -0
  62. package/dist/browser/assets/diagram-VSXAHHWV-Bl0Bun2O.js +3 -0
  63. package/dist/browser/assets/diagram-VX7I27RA-ChsRTsfS.js +24 -0
  64. package/dist/browser/assets/diagram-Z3DM3KII-B3Mxficd.js +24 -0
  65. package/dist/browser/assets/dist-v5Q1xZ2K.js +1 -0
  66. package/dist/browser/assets/document-CaUvlKcm.css +1 -0
  67. package/dist/browser/assets/document-DcPjYojg.js +11 -0
  68. package/dist/browser/assets/ebnfDiagram-PWID7BFC-Cs_89QgY.js +1 -0
  69. package/dist/browser/assets/erDiagram-RLTQ6QDP-BefkilYT.js +99 -0
  70. package/dist/browser/assets/eventmodeling-NTZA5JFV-OyiymXqZ.js +1 -0
  71. package/dist/browser/assets/{features._featureId-BBYORTqC.js → features._featureId-BVMBUbIc.js} +1 -1
  72. package/dist/browser/assets/features.index-DAF_MoVe.js +1 -0
  73. package/dist/browser/assets/flowDiagram-HODETNUW-BGkl5kD6.js +1 -0
  74. package/dist/browser/assets/ganttDiagram-EL5Y4UJY-B_Y3HJTL.js +292 -0
  75. package/dist/browser/assets/git-CuBxy8Rl.js +1 -0
  76. package/dist/browser/assets/gitGraph-4MIJSDKK-CPDeR11I.js +1 -0
  77. package/dist/browser/assets/gitGraphDiagram-WWUBYQGX-B89zUhQY.js +106 -0
  78. package/dist/browser/assets/graphlib-DS17s2tU.js +1 -0
  79. package/dist/browser/assets/index-w5oyNndb.js +48 -0
  80. package/dist/browser/assets/info-A6RAGUB7-DlEdyaYJ.js +1 -0
  81. package/dist/browser/assets/infoDiagram-27XIBGKW-T8vu4pEW.js +2 -0
  82. package/dist/browser/assets/init-C-OQMol4.js +1 -0
  83. package/dist/browser/assets/ishikawaDiagram-5VMMS53U-B4C53CII.js +70 -0
  84. package/dist/browser/assets/journeyDiagram-3NMN7TZE-DemWKqD6.js +139 -0
  85. package/dist/browser/assets/kanban-definition-UXKFOSKX-xMvrIZPT.js +89 -0
  86. package/dist/browser/assets/katex-ZlcWpGUi.js +257 -0
  87. package/dist/browser/assets/line-CfCBYCoS.js +1 -0
  88. package/dist/browser/assets/linear-SzVmGSw4.js +1 -0
  89. package/dist/browser/assets/mermaid-parser.core-DCp4gVZn.js +7 -0
  90. package/dist/browser/assets/mermaid.core-ny8BaDSG.js +44 -0
  91. package/dist/browser/assets/mindmap-definition-YA3MSWOX-CNWF3H17.js +96 -0
  92. package/dist/browser/assets/ordinal-BDEzSJ7C.js +1 -0
  93. package/dist/browser/assets/packet-AYTQ26CC-DgNRIjqj.js +1 -0
  94. package/dist/browser/assets/page-header-DPWfThZo.js +124 -0
  95. package/dist/browser/assets/page-header-DZvVAckA.css +1 -0
  96. package/dist/browser/assets/path-fybaL0A-.js +1 -0
  97. package/dist/browser/assets/pegDiagram-XKGWAZYB-BPEzoUlc.js +1 -0
  98. package/dist/browser/assets/pie-WAS4IAKB-D85SGg9H.js +1 -0
  99. package/dist/browser/assets/pieDiagram-E7YTZNPT-L5HtHPrJ.js +39 -0
  100. package/dist/browser/assets/preload-helper-BZ1Pz5am.js +1 -0
  101. package/dist/browser/assets/product-BR5KVGuJ.css +1 -0
  102. package/dist/browser/assets/product-BmoIKtGm.js +8 -0
  103. package/dist/browser/assets/product.index-Fb5sQw1w.js +1 -0
  104. package/dist/browser/assets/quadrantDiagram-AXDQQJYC-BFek-axl.js +7 -0
  105. package/dist/browser/assets/radar-RG4KPBEZ-BwPngHhh.js +1 -0
  106. package/dist/browser/assets/railroad-74A4TZTK-Bf5cESw-.js +1 -0
  107. package/dist/browser/assets/railroad-abnf-HS5TGJTU-QtVzwDRk.js +1 -0
  108. package/dist/browser/assets/railroad-ebnf-LZEXJU2U-CCcgn2jt.js +1 -0
  109. package/dist/browser/assets/railroad-peg-WCYAUIDC-DWRNBkSL.js +1 -0
  110. package/dist/browser/assets/railroadDiagram-O6MQD6OU-0D-Z1mj1.js +1 -0
  111. package/dist/browser/assets/request-state-B7pKmdbJ.js +1 -0
  112. package/dist/browser/assets/requirementDiagram-BXWQKSXE-8pNButqN.js +84 -0
  113. package/dist/browser/assets/requirements-DGx4_rNJ.js +1 -0
  114. package/dist/browser/assets/rolldown-runtime-hePW80VL.js +1 -0
  115. package/dist/browser/assets/rough.esm-Dy-Kn_BL.js +1 -0
  116. package/dist/browser/assets/sankeyDiagram-P5KCCOFB-BOWaOPXp.js +40 -0
  117. package/dist/browser/assets/sequenceDiagram-WJ2MYXX4-BA3_JPLh.js +162 -0
  118. package/dist/browser/assets/settings-5JQQOYMj.js +1 -0
  119. package/dist/browser/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  120. package/dist/browser/assets/src-B6xuSHsQ.js +1 -0
  121. package/dist/browser/assets/stateDiagram-D77RDMKH-YYcbi5Z-.js +1 -0
  122. package/dist/browser/assets/stateDiagram-v2-MP3YSRHH-BEg6dLDA.js +1 -0
  123. package/dist/browser/assets/swimlanes-42K2YHIH-B_Eh1oqP.js +1 -0
  124. package/dist/browser/assets/swimlanesDiagram-VR7AAH4N-Bckt0ZyW.js +8 -0
  125. package/dist/browser/assets/themeProps-CkLe5zXY.js +1 -0
  126. package/dist/browser/assets/timeline-definition-24CTP7MA-DfFHHbdC.js +120 -0
  127. package/dist/browser/assets/treeView-Q6P3EWNA-CaZRyAuW.js +1 -0
  128. package/dist/browser/assets/treemap-WGGIJYW6-DI2-Ryxd.js +1 -0
  129. package/dist/browser/assets/useClipboard-Cqx6Upy7.js +1 -0
  130. package/dist/browser/assets/useDevWarning-Dudfg3qF.js +1 -0
  131. package/dist/browser/assets/useIsomorphicLayoutEffect-BiEJxDg_.js +1 -0
  132. package/dist/browser/assets/useMediaQuery-twbHF0pO.js +1 -0
  133. package/dist/browser/assets/useScrollLock-D-Y-zHSV.js +1 -0
  134. package/dist/browser/assets/vennDiagram-4TSXK5OY-QXok2k3u.js +34 -0
  135. package/dist/browser/assets/wardley-WFR3VGLG-BiXQYqiJ.js +1 -0
  136. package/dist/browser/assets/wardleyDiagram-VM6X3IG4-BZBhm2Zm.js +78 -0
  137. package/dist/browser/assets/{wiki-DkAnuzON.js → wiki-k4dXogJF.js} +1 -1
  138. package/dist/browser/assets/xychartDiagram-S5SC5T6Z-qrzzwM55.js +7 -0
  139. package/dist/browser/index.html +26 -25
  140. package/dist/i18n/ko/block.md +1 -0
  141. package/dist/i18n/ko/changelog.md +23 -0
  142. package/dist/i18n/ko/docs/commit.md +0 -1
  143. package/dist/i18n/ko/docs/design.md +2 -0
  144. package/dist/i18n/ko/docs/spec.md +2 -0
  145. package/dist/i18n/ko/docs/wiki.md +2 -0
  146. package/dist/i18n/ko/docs/writing.md +54 -0
  147. package/dist/main.js +233 -394
  148. package/package.json +3 -3
  149. package/dist/browser/assets/BottomSheet-F2BUQwSi.js +0 -1
  150. package/dist/browser/assets/Grid-kXvDaAvk.js +0 -1
  151. package/dist/browser/assets/IconButton-CkA9oftf.js +0 -1
  152. package/dist/browser/assets/Markdown-C8C4nHPG.js +0 -68
  153. package/dist/browser/assets/MetadataListItem-CcPRe-aG.js +0 -1
  154. package/dist/browser/assets/ProgressBarMarkTooltip-BVcVKVq9.js +0 -1
  155. package/dist/browser/assets/Section-zmL2D3WL.js +0 -1
  156. package/dist/browser/assets/Table-B_rvjexw.js +0 -3
  157. package/dist/browser/assets/TimestampHoverCard-DOWpOAzA.js +0 -1
  158. package/dist/browser/assets/Tooltip-a2AGdnkC.js +0 -1
  159. package/dist/browser/assets/activity-B7x648pR.js +0 -1
  160. package/dist/browser/assets/changelog-DaxXahXm.js +0 -2
  161. package/dist/browser/assets/composeEventHandlers-CHIontwB.js +0 -1
  162. package/dist/browser/assets/contributors.index-BgA9LkC0.js +0 -1
  163. package/dist/browser/assets/devWarning-BZMSgwyk.js +0 -1
  164. package/dist/browser/assets/document-CFtIdIPN.js +0 -9
  165. package/dist/browser/assets/document-QMuypGH5.css +0 -1
  166. package/dist/browser/assets/features.index-DuwIen6d.js +0 -1
  167. package/dist/browser/assets/git-DVoIz_Mx.js +0 -1
  168. package/dist/browser/assets/index-BP3PrawI.js +0 -48
  169. package/dist/browser/assets/page-header-9-i3H9WR.css +0 -1
  170. package/dist/browser/assets/page-header-Zwbd52Q5.js +0 -124
  171. package/dist/browser/assets/product-DNlxFjU7.css +0 -1
  172. package/dist/browser/assets/product-euizlTTB.js +0 -8
  173. package/dist/browser/assets/product.index-B4D5SxOO.js +0 -1
  174. package/dist/browser/assets/request-state-Dz-oeAkg.js +0 -1
  175. package/dist/browser/assets/requirements-wk9Joy7M.js +0 -1
  176. package/dist/browser/assets/settings-DwA6H4Ax.js +0 -1
  177. package/dist/browser/assets/themeProps-MQSlTycI.js +0 -1
  178. package/dist/browser/assets/useClipboard-B8Or2k0a.js +0 -1
  179. package/dist/browser/assets/useDevWarning-Xg7kPMHJ.js +0 -1
  180. package/dist/browser/assets/useIsomorphicLayoutEffect-f8dYmyS2.js +0 -1
  181. package/dist/browser/assets/useMediaQuery-DFlnKIlp.js +0 -1
  182. package/dist/browser/assets/useScrollLock-CrQ0xkil.js +0 -1
  183. package/dist/browser/assets/useTranslator-DY2HN18N.js +0 -4
package/dist/main.js CHANGED
@@ -1537,16 +1537,16 @@ var Command = class _Command extends EventEmitter {
1537
1537
  * @param {Function} listener
1538
1538
  * @return {Command} `this` command for chaining
1539
1539
  */
1540
- hook(event, listener) {
1540
+ hook(event2, listener) {
1541
1541
  const allowedValues = ["preSubcommand", "preAction", "postAction"];
1542
- if (!allowedValues.includes(event)) {
1543
- throw new Error(`Unexpected value for event passed to hook : '${event}'.
1542
+ if (!allowedValues.includes(event2)) {
1543
+ throw new Error(`Unexpected value for event passed to hook : '${event2}'.
1544
1544
  Expecting one of '${allowedValues.join("', '")}'`);
1545
1545
  }
1546
- if (this._lifeCycleHooks[event]) {
1547
- this._lifeCycleHooks[event].push(listener);
1546
+ if (this._lifeCycleHooks[event2]) {
1547
+ this._lifeCycleHooks[event2].push(listener);
1548
1548
  } else {
1549
- this._lifeCycleHooks[event] = [listener];
1549
+ this._lifeCycleHooks[event2] = [listener];
1550
1550
  }
1551
1551
  return this;
1552
1552
  }
@@ -2383,15 +2383,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
2383
2383
  * @return {(Promise|undefined)}
2384
2384
  * @private
2385
2385
  */
2386
- _chainOrCallHooks(promise2, event) {
2386
+ _chainOrCallHooks(promise2, event2) {
2387
2387
  let result = promise2;
2388
2388
  const hooks = [];
2389
- this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
2390
- hookedCommand._lifeCycleHooks[event].forEach((callback) => {
2389
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event2] !== void 0).forEach((hookedCommand) => {
2390
+ hookedCommand._lifeCycleHooks[event2].forEach((callback) => {
2391
2391
  hooks.push({ hookedCommand, callback });
2392
2392
  });
2393
2393
  });
2394
- if (event === "postAction") {
2394
+ if (event2 === "postAction") {
2395
2395
  hooks.reverse();
2396
2396
  }
2397
2397
  hooks.forEach((hookDetail) => {
@@ -2409,10 +2409,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2409
2409
  * @return {(Promise|undefined)}
2410
2410
  * @private
2411
2411
  */
2412
- _chainOrCallSubCommandHook(promise2, subCommand, event) {
2412
+ _chainOrCallSubCommandHook(promise2, subCommand, event2) {
2413
2413
  let result = promise2;
2414
- if (this._lifeCycleHooks[event] !== void 0) {
2415
- this._lifeCycleHooks[event].forEach((hook) => {
2414
+ if (this._lifeCycleHooks[event2] !== void 0) {
2415
+ this._lifeCycleHooks[event2].forEach((hook) => {
2416
2416
  result = this._chainOrCall(result, () => {
2417
2417
  return hook(this, subCommand);
2418
2418
  });
@@ -3510,7 +3510,8 @@ var messages_default = {
3510
3510
  "source.path": "\uCC38\uACE0 \uBB38\uC11C path\uB294 .md\uB85C \uB05D\uB098\uB294 \uC0C1\uB300 \uACBD\uB85C\uC5EC\uC57C \uD569\uB2C8\uB2E4: {path}",
3511
3511
  "edit.documentIdNotFound": "\uC704\uD0A4 \uD398\uC774\uC9C0 ID\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4: {id}",
3512
3512
  "edit.invalidSources": "sources\uB294 \uCD5C\uB300 50\uAC1C\uC758 \uBC30\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
3513
- "config.unsupportedSchema": "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uC800\uC7A5 \uADDC\uC57D(schemaVersion {version})\uC740 \uC774 CLI\uAC00 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC815\uC2DD \uBC84\uC804 \uC804 \uADDC\uC57D\uC740 \uC804\uD658\uD558\uC9C0 \uC54A\uC73C\uBA70 \uC0C8\uB85C init \uD569\uB2C8\uB2E4."
3513
+ "config.unsupportedSchema": "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uC800\uC7A5 \uADDC\uC57D(schemaVersion {version})\uC740 \uC774\uC804 \uBC84\uC804\uC758 \uAC83\uC774\uB77C \uC774 CLI\uAC00 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC815\uC2DD \uBC84\uC804 \uC804 \uADDC\uC57D\uC740 \uC804\uD658\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. .gitifact\uC5D0 config.json\uB9CC \uC788\uC73C\uBA74 gitifact init\uC774 \uC0C8 \uADDC\uC57D\uC73C\uB85C \uBC14\uAFC9\uB2C8\uB2E4.",
3514
+ "config.newerSchema": "\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 \uB354 \uC0C8\uB85C\uC6B4 \uC800\uC7A5 \uADDC\uC57D(schemaVersion {version})\uC744 \uC501\uB2C8\uB2E4. npm install -g gitifact@latest\uB85C CLI\uB97C \uC62C\uB9B0 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694."
3514
3515
  };
3515
3516
 
3516
3517
  // ../../packages/core/dist/shared/i18n/index.js
@@ -3595,8 +3596,11 @@ function parseManagedConfig(text2) {
3595
3596
  const config2 = value;
3596
3597
  if (Object.keys(config2).sort().join(",") !== "baseline,schemaVersion")
3597
3598
  throw new InitError("INVALID_CONFIG", t("config.schemaFields"));
3598
- if (config2.schemaVersion !== SCHEMA_VERSION)
3599
- throw new InitError("UNSUPPORTED_SCHEMA", t("config.unsupportedSchema", { version: String(config2.schemaVersion) }));
3599
+ if (config2.schemaVersion !== SCHEMA_VERSION) {
3600
+ const found = config2.schemaVersion;
3601
+ const newer = typeof found === "number" && found > SCHEMA_VERSION;
3602
+ throw new InitError("UNSUPPORTED_SCHEMA", newer ? t("config.newerSchema", { version: String(found) }) : t("config.unsupportedSchema", { version: String(found) }));
3603
+ }
3600
3604
  const checked = parseProjectConfig(JSON.stringify({ kind: "tryce-project", format: "workflow-1", mode: "auto", baseline: config2.baseline }));
3601
3605
  return { schemaVersion: SCHEMA_VERSION, baseline: checked.baseline };
3602
3606
  }
@@ -3775,9 +3779,9 @@ function parseDesignPreview(source2, specId) {
3775
3779
  fence = void 0;
3776
3780
  return line;
3777
3781
  }
3778
- const open6 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
3779
- if (open6) {
3780
- fence = { char: open6[1][0], size: open6[1].length };
3782
+ const open5 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
3783
+ if (open5) {
3784
+ fence = { char: open5[1][0], size: open5[1].length };
3781
3785
  return line;
3782
3786
  }
3783
3787
  if (/^#\s/.test(line))
@@ -3828,9 +3832,9 @@ function parseDocument(path3, source2) {
3828
3832
  fence = void 0;
3829
3833
  continue;
3830
3834
  }
3831
- const open6 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
3832
- if (open6) {
3833
- fence = { char: open6[1][0], size: open6[1].length };
3835
+ const open5 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
3836
+ if (open5) {
3837
+ fence = { char: open5[1][0], size: open5[1].length };
3834
3838
  continue;
3835
3839
  }
3836
3840
  if (/^#\s/.test(line))
@@ -3928,9 +3932,9 @@ function extractLinks(body) {
3928
3932
  fence = void 0;
3929
3933
  continue;
3930
3934
  }
3931
- const open6 = /^ {0,3}(`{3,}|~{3,})/.exec(line);
3932
- if (open6) {
3933
- fence = { char: open6[1][0], size: open6[1].length };
3935
+ const open5 = /^ {0,3}(`{3,}|~{3,})/.exec(line);
3936
+ if (open5) {
3937
+ fence = { char: open5[1][0], size: open5[1].length };
3934
3938
  continue;
3935
3939
  }
3936
3940
  for (const m of line.replace(/`[^`]*`/g, "").matchAll(/!?\[[^\]]*\]\((?:<([^>]+)>|([^)\s]+))(?:\s+"[^"]*")?\)/g))
@@ -24586,13 +24590,32 @@ var browserHttpErrorV1 = external_exports.strictObject({
24586
24590
  })
24587
24591
  });
24588
24592
 
24589
- // ../../packages/contracts/dist/versions/project-init-v4.js
24590
- var projectInitV4 = external_exports.discriminatedUnion("ok", [
24593
+ // ../../packages/contracts/dist/versions/browser-session-v2.js
24594
+ var release = external_exports.string().regex(/^\d+\.\d+\.\d+$/);
24595
+ var updateStateV1 = external_exports.strictObject({
24596
+ status: external_exports.enum(["checking", "available", "up-to-date", "unavailable", "disabled"]),
24597
+ latestVersion: release.nullable()
24598
+ }).refine((value) => (value.status === "available" || value.status === "up-to-date") === (value.latestVersion !== null), "latestVersion is set exactly when the check produced a result.");
24599
+ var browserSessionV2 = external_exports.strictObject({
24600
+ contract: external_exports.literal("browser-session"),
24601
+ version: external_exports.literal(2),
24602
+ sessionId: external_exports.uuid(),
24603
+ repository: external_exports.strictObject({
24604
+ key: external_exports.string().regex(/^repo:[0-9a-f]{64}$/),
24605
+ worktreeKey: external_exports.string().regex(/^worktree:[0-9a-f]{64}$/)
24606
+ }),
24607
+ // The running CLI, the same value as `gitifact --version`. A development build may carry a pre-release suffix.
24608
+ cliVersion: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/),
24609
+ update: updateStateV1
24610
+ });
24611
+
24612
+ // ../../packages/contracts/dist/versions/project-init-v5.js
24613
+ var projectInitV5 = external_exports.discriminatedUnion("ok", [
24591
24614
  external_exports.strictObject({
24592
24615
  contract: external_exports.literal("project-init"),
24593
- version: external_exports.literal(4),
24616
+ version: external_exports.literal(5),
24594
24617
  ok: external_exports.literal(true),
24595
- outcome: external_exports.enum(["planned", "created", "already-initialized"]),
24618
+ outcome: external_exports.enum(["planned", "created", "replaced", "already-initialized"]),
24596
24619
  rootPath: external_exports.string(),
24597
24620
  configPath: external_exports.literal(".gitifact/config.json"),
24598
24621
  schemaVersion: external_exports.literal(2),
@@ -24600,12 +24623,15 @@ var projectInitV4 = external_exports.discriminatedUnion("ok", [
24600
24623
  external_exports.strictObject({ kind: external_exports.literal("empty") }),
24601
24624
  external_exports.strictObject({ kind: external_exports.literal("commit"), objectFormat: external_exports.enum(["sha1", "sha256"]), commit: external_exports.string() })
24602
24625
  ]),
24603
- agentDocs: external_exports.strictObject({ mode: external_exports.enum(["install", "remove", "skip"]), paths: external_exports.array(external_exports.string()) })
24626
+ agentDocs: external_exports.strictObject({ mode: external_exports.enum(["install", "remove", "skip"]), paths: external_exports.array(external_exports.string()) }),
24627
+ update: updateStateV1,
24628
+ // Present only when a newer release exists. The command is for npm global installs; other installs differ.
24629
+ install: external_exports.strictObject({ npmGlobal: external_exports.string().min(1) }).nullable()
24604
24630
  }),
24605
- external_exports.strictObject({ contract: external_exports.literal("project-init"), version: external_exports.literal(4), ok: external_exports.literal(false), error: external_exports.strictObject({ code: external_exports.string(), message: external_exports.string() }) })
24631
+ external_exports.strictObject({ contract: external_exports.literal("project-init"), version: external_exports.literal(5), ok: external_exports.literal(false), error: external_exports.strictObject({ code: external_exports.string(), message: external_exports.string() }) })
24606
24632
  ]);
24607
24633
 
24608
- // ../../packages/contracts/dist/versions/browser-specs-v2.js
24634
+ // ../../packages/contracts/dist/versions/browser-specs-v3.js
24609
24635
  var requirement = external_exports.strictObject({ id: external_exports.string(), title: external_exports.string(), body: external_exports.string() });
24610
24636
  var contributor = external_exports.strictObject({ email: external_exports.string(), name: external_exports.string(), commits: external_exports.number().int().nonnegative(), latest: external_exports.string() });
24611
24637
  var source = external_exports.strictObject({ title: external_exports.string(), path: external_exports.string().optional(), url: external_exports.string().optional(), note: external_exports.string().optional() });
@@ -24622,34 +24648,42 @@ var feature = external_exports.strictObject({
24622
24648
  });
24623
24649
  var snapshot = requirement.extend({ specId: external_exports.string(), path: external_exports.string(), sources: external_exports.array(source).optional() }).nullable();
24624
24650
  var document = external_exports.strictObject({ id: external_exports.string(), path: external_exports.string(), title: external_exports.string(), body: external_exports.string(), updatedAt: external_exports.string().nullable() });
24625
- var browserSpecsV2 = external_exports.strictObject({
24651
+ var event = external_exports.strictObject({
24652
+ key: external_exports.string(),
24653
+ commit: external_exports.string(),
24654
+ date: external_exports.string(),
24655
+ author: external_exports.string(),
24656
+ email: external_exports.string(),
24657
+ committer: external_exports.string(),
24658
+ message: external_exports.string(),
24659
+ id: external_exports.string(),
24660
+ kind: external_exports.enum(["requirement", "design", "wiki"]).optional(),
24661
+ types: external_exports.array(external_exports.enum(["created", "modified", "moved", "deleted"])),
24662
+ before: snapshot,
24663
+ after: snapshot,
24664
+ reasons: external_exports.array(external_exports.string())
24665
+ });
24666
+ var browserSpecsV3 = external_exports.strictObject({
24626
24667
  contract: external_exports.literal("browser-specs"),
24627
- version: external_exports.literal(2),
24668
+ version: external_exports.literal(3),
24628
24669
  sessionId: external_exports.string(),
24629
24670
  head: external_exports.string().nullable(),
24630
24671
  observedAt: external_exports.string(),
24631
- working: external_exports.boolean(),
24632
- features: external_exports.array(feature),
24633
- documents: external_exports.array(document).default([]),
24634
- events: external_exports.array(external_exports.strictObject({
24635
- key: external_exports.string(),
24636
- commit: external_exports.string(),
24637
- date: external_exports.string(),
24638
- author: external_exports.string(),
24639
- email: external_exports.string(),
24640
- committer: external_exports.string(),
24641
- message: external_exports.string(),
24642
- id: external_exports.string(),
24643
- kind: external_exports.enum(["requirement", "design", "wiki"]).optional(),
24644
- types: external_exports.array(external_exports.enum(["created", "modified", "moved", "deleted"])),
24645
- before: snapshot,
24646
- after: snapshot,
24647
- reasons: external_exports.array(external_exports.string())
24648
- })),
24649
- contributors: external_exports.array(contributor),
24650
- contributorsLimited: external_exports.boolean(),
24672
+ events: external_exports.array(event),
24651
24673
  nextCursor: external_exports.number().int().nonnegative().nullable(),
24652
- boundary: external_exports.boolean()
24674
+ boundary: external_exports.boolean(),
24675
+ working: external_exports.boolean().optional(),
24676
+ features: external_exports.array(feature).optional(),
24677
+ documents: external_exports.array(document).optional(),
24678
+ contributors: external_exports.array(contributor).optional(),
24679
+ contributorsLimited: external_exports.boolean().optional()
24680
+ });
24681
+ var browserSpecsFirstV3 = browserSpecsV3.required({
24682
+ working: true,
24683
+ features: true,
24684
+ documents: true,
24685
+ contributors: true,
24686
+ contributorsLimited: true
24653
24687
  });
24654
24688
 
24655
24689
  // ../../packages/contracts/dist/versions/changelog-v1.js
@@ -24677,25 +24711,6 @@ var changelogV1 = external_exports.strictObject({
24677
24711
  }
24678
24712
  });
24679
24713
 
24680
- // ../../packages/contracts/dist/versions/browser-session-v2.js
24681
- var release = external_exports.string().regex(/^\d+\.\d+\.\d+$/);
24682
- var updateStateV1 = external_exports.strictObject({
24683
- status: external_exports.enum(["checking", "available", "up-to-date", "unavailable", "disabled"]),
24684
- latestVersion: release.nullable()
24685
- }).refine((value) => (value.status === "available" || value.status === "up-to-date") === (value.latestVersion !== null), "latestVersion is set exactly when the check produced a result.");
24686
- var browserSessionV2 = external_exports.strictObject({
24687
- contract: external_exports.literal("browser-session"),
24688
- version: external_exports.literal(2),
24689
- sessionId: external_exports.uuid(),
24690
- repository: external_exports.strictObject({
24691
- key: external_exports.string().regex(/^repo:[0-9a-f]{64}$/),
24692
- worktreeKey: external_exports.string().regex(/^worktree:[0-9a-f]{64}$/)
24693
- }),
24694
- // The running CLI, the same value as `gitifact --version`. A development build may carry a pre-release suffix.
24695
- cliVersion: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/),
24696
- update: updateStateV1
24697
- });
24698
-
24699
24714
  // ../../packages/contracts/dist/versions/update-v3.js
24700
24715
  var commitReason = external_exports.enum(["untracked", "other-changes", "commit-failed"]);
24701
24716
  var agentDocsCommit = external_exports.strictObject({
@@ -24743,14 +24758,9 @@ var messages_default2 = {
24743
24758
  "help.migrate": ".tryce \uC800\uC7A5\uC18C\uB97C .gitifact\uB85C \uC804\uD658 (\uACBD\uB85C\uC640 \uB9C8\uCEE4\uB9CC \uBC14\uAFB8\uACE0 ID\xB7\uC774\uC720\xB7\uC774\uB825\uC740 \uBCF4\uC874)",
24744
24759
  "help.migrateDryRun": "\uD30C\uC77C\uC744 \uBC14\uAFB8\uC9C0 \uC54A\uACE0 \uC804\uD658 \uACC4\uD68D \uD655\uC778",
24745
24760
  "help.spec": "Markdown \uBA85\uC138 \uC791\uC131\xB7\uC870\uD68C\xB7Git \uAE30\uB85D",
24746
- "help.deprecated": "Deprecated: 0.6.0\uC5D0\uC11C \uC81C\uAC70 \uC608\uC815. spec commit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
24747
24761
  "help.specCommit": "\uBCC0\uACBD \uC774\uC720 \uAE30\uB85D\uACFC \uAD00\uB828 \uD30C\uC77C \uCEE4\uBC0B\uC744 \uD55C \uBC88\uC5D0 \uC2E4\uD589",
24748
24762
  "help.specCommitFile": "reasons\xB7paths\xB7message\xB7authorization\uC744 \uB2F4\uC740 JSON \uD30C\uC77C (-\uB294 \uD45C\uC900 \uC785\uB825)",
24749
24763
  "help.specCommitDryRun": "\uD30C\uC77C\uC744 \uC4F0\uAC70\uB098 \uCEE4\uBC0B\uD558\uC9C0 \uC54A\uACE0 \uACB0\uACFC\uB9CC \uD655\uC778",
24750
- "help.specCommitPlanFile": "\uCEE4\uBC0B \uC785\uB825 \uB610\uB294 \uACC4\uD68D JSON \uD30C\uC77C",
24751
- "help.specPrepareFile": "expected\uC640 \uCD5C\uC885 reasons\uB97C \uB2F4\uC740 JSON \uD30C\uC77C",
24752
- "help.specVerifyFile": "prepare\uC758 verification \uAC1D\uCCB4\uB97C \uB2F4\uC740 JSON \uD30C\uC77C",
24753
- "help.specVerifyStaged": "index \uC6D0\uBB38\uB3C4 \uBE44\uAD50",
24754
24764
  "help.specSaveFile": "expected\uC640 operations\uB97C \uB2F4\uC740 UTF-8 JSON \uD30C\uC77C (-\uB294 \uD45C\uC900 \uC785\uB825)",
24755
24765
  "help.specReadRef": "\uC77D\uC744 \uCEE4\uBC0B",
24756
24766
  "help.specDiffFrom": "\uC774\uC804 \uCEE4\uBC0B",
@@ -24816,13 +24826,6 @@ var messages_default2 = {
24816
24826
  "commit.fileChangedPreparing": "\uCEE4\uBC0B \uC900\uBE44 \uC911 \uD30C\uC77C\xB7\uC815\uCC45\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
24817
24827
  "commit.resultUnknown": "\uCEE4\uBC0B \uACB0\uACFC\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
24818
24828
  "commit.uncertain": "Git \uC2E4\uD589 \uACB0\uACFC\uB97C \uD655\uC778\uD574\uC57C \uD569\uB2C8\uB2E4. \uC7AC\uC2DC\uB3C4\uD558\uC9C0 \uB9D0\uACE0 HEAD\uC640 \uBCF5\uAD6C \uC790\uB8CC\uB97C \uD655\uC778\uD558\uC138\uC694: {path}",
24819
- "commit.existingStagingPlan": "\uAE30\uC874 staging\uC744 \uBCF4\uC874\uD569\uB2C8\uB2E4. \uC120\uD0DD \uBC94\uC704\uB97C \uC815\uB9AC\uD55C \uD6C4 \uB2E4\uC2DC \uACC4\uD68D\uD558\uC138\uC694.",
24820
- "commit.designUseSpecCommit": "\uC124\uACC4 \uBCC0\uACBD\uC740 spec commit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
24821
- "commit.indexChangedPlanning": "\uACC4\uD68D \uC911 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
24822
- "commit.planCorrupted": "\uCEE4\uBC0B \uACC4\uD68D\uC774 \uC190\uC0C1\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uACC4\uD68D\uD558\uC138\uC694.",
24823
- "commit.planScope": "\uACC4\uD68D\uC758 \uC800\uC7A5\uC18C \uB610\uB294 \uD30C\uC77C \uBC94\uC704\uAC00 \uB2E4\uB985\uB2C8\uB2E4.",
24824
- "commit.planStale": "\uACC4\uD68D \uC774\uD6C4 \uD30C\uC77C\xB7\uC815\uCC45\xB7index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uACC4\uD68D\uD558\uC138\uC694.",
24825
- "commit.indexChangedLocked": "\uC7A0\uAE08 \uC911 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
24826
24829
  "store.legacyLock": "\uC774\uC804 Tryce \uC2E4\uD589\uC758 \uC7A0\uAE08 \uB610\uB294 \uBCF5\uAD6C \uC790\uB8CC\uAC00 \uC788\uC2B5\uB2C8\uB2E4: {path}",
24827
24830
  "store.storeNotDirectory": ".gitifact\uB294 \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
24828
24831
  "store.migrateFirst": ".tryce \uC800\uC7A5\uC18C\uC785\uB2C8\uB2E4. gitifact migrate\uB85C .gitifact\uC5D0 \uC804\uD658\uD55C \uB4A4 \uC0AC\uC6A9\uD558\uC138\uC694.",
@@ -24884,18 +24887,8 @@ var messages_default2 = {
24884
24887
  "reader.blobShape": "\uAC80\uD1A0 \uC870\uD68C blob \uD615\uC2DD \uB610\uB294 1 MiB \uD55C\uB3C4\uB97C \uD655\uC778\uD558\uC138\uC694.",
24885
24888
  "reader.totalLimit": "\uBA85\uC138 \uC804\uCCB4 \uC870\uD68C 16 MiB \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
24886
24889
  "reader.blobBoundary": "Git blob \uC751\uB2F5 \uACBD\uACC4\uAC00 \uB2E4\uB985\uB2C8\uB2E4.",
24887
- "prepare.integrationInProgress": "Git \uD1B5\uD569 \uC791\uC5C5 \uC911\uC5D0\uB294 \uC2E4\uD5D8\uC6A9 \uCEE4\uBC0B \uC900\uBE44\uB97C \uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
24890
+ "prepare.integrationInProgress": "Git \uD1B5\uD569 \uC791\uC5C5 \uC911\uC5D0\uB294 \uBA85\uC138\uB97C \uC77D\uC5B4 \uCEE4\uBC0B\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
24888
24891
  "prepare.headChanged": "HEAD \uB610\uB294 \uBE0C\uB79C\uCE58\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. changes\uBD80\uD130 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
24889
- "prepare.invalidInput": "\uC798\uBABB\uB41C \uC900\uBE44 \uC785\uB825\uC785\uB2C8\uB2E4.",
24890
- "prepare.expectedReasons": "expected\uC640 reasons\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
24891
- "prepare.staleInput": "\uC900\uBE44 \uC785\uB825\uC774 \uC624\uB798\uB410\uC2B5\uB2C8\uB2E4. changes\uBD80\uD130 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
24892
- "prepare.invalidVerifyInput": "\uC798\uBABB\uB41C \uD655\uC778 \uC785\uB825\uC785\uB2C8\uB2E4.",
24893
- "prepare.verificationRequired": "prepare\uAC00 \uBC18\uD658\uD55C verification \uAC1D\uCCB4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
24894
- "prepare.changedAfterPrepare": "\uC900\uBE44 \uB4A4 HEAD \uB610\uB294 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC900\uBE44\uD558\uC138\uC694.",
24895
- "prepare.stagingScope": "staging\uC758 \uBA85\uC138 \uBC94\uC704\uAC00 \uC900\uBE44\uD55C \uC6D0\uBB38\uACFC \uB2E4\uB985\uB2C8\uB2E4.",
24896
- "prepare.stagingContent": "staging \uC6D0\uBB38\uC774 \uC900\uBE44\uD55C \uD30C\uC77C\uACFC \uB2E4\uB985\uB2C8\uB2E4: {path}",
24897
- "prepare.stagingChanged": "\uD655\uC778 \uC911 staging\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
24898
- "prepare.specsChanged": "\uD655\uC778 \uC911 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
24899
24892
  "commitFiles.relativePath": "\uC800\uC7A5\uC18C \uC0C1\uB300 \uACBD\uB85C\uC758 \uBA85\uC138 \uB610\uB294 \uC77C\uBC18 \uD30C\uC77C\uB9CC \uC120\uD0DD\uD558\uC138\uC694.",
24900
24893
  "commitFiles.linkOrDirectory": "\uB9C1\uD06C\xB7\uB514\uB809\uD130\uB9AC\xB7\uD2B9\uC218 \uD30C\uC77C\uC740 \uC120\uD0DD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
24901
24894
  "commitFiles.nestedRepository": "\uC911\uCCA9 \uC800\uC7A5\uC18C\uB294 \uC120\uD0DD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -24910,6 +24903,7 @@ var messages_default2 = {
24910
24903
  "init.configDeleted": "\uAE30\uC874 \uC124\uC815\uC758 \uC0AD\uC81C\uB97C \uC2E0\uADDC \uB3C4\uC785\uC73C\uB85C \uCC98\uB9AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
24911
24904
  "init.existingSpecs": "\uAE30\uC874 specs \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.",
24912
24905
  "init.orphanStore": "\uC124\uC815 \uC5C6\uB294 .gitifact \uC790\uB8CC\uB97C \uC790\uB3D9 \uCC44\uD0DD\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
24906
+ "init.legacyRecords": "\uC774 \uD504\uB85C\uC81D\uD2B8\uC5D0\uB294 \uC774\uC804 \uC800\uC7A5 \uADDC\uC57D(schemaVersion {version})\uC73C\uB85C \uC4F4 \uBA85\uC138\uB098 \uAE30\uB85D\uC774 \uC788\uC5B4 \uC124\uC815\uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC774 CLI\uB294 \uC774\uC804 \uADDC\uC57D\uC744 \uC804\uD658\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAE30\uB85D\uC744 \uB2E4\uB978 \uACF3\uC5D0 \uBCF4\uAD00\uD558\uACE0 .gitifact\uC5D0 config.json\uB9CC \uB0A8\uAE34 \uB4A4 \uB2E4\uC2DC init \uD558\uC138\uC694.",
24913
24907
  "init.headOrIndexChanged": "HEAD \uB610\uB294 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
24914
24908
  "init.configAppeared": "\uB2E4\uB978 \uC2E4\uD589\uC774 \uC124\uC815\uC744 \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4.",
24915
24909
  "init.changedAfterWrite": "\uC124\uC815 \uC0DD\uC131 \uD6C4 \uC785\uB825\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C\uC744 \uD655\uC778\uD558\uC138\uC694.",
@@ -24919,6 +24913,7 @@ var messages_default2 = {
24919
24913
  "init.text.blockUpdated": "\uBE14\uB85D \uAC31\uC2E0",
24920
24914
  "init.text.storage": "\uC800\uC7A5 \uADDC\uC57D",
24921
24915
  "init.text.agentDocs": "\uC5D0\uC774\uC804\uD2B8 \uC9C0\uCE68",
24916
+ "init.text.updateAvailable": "\uC0C8 \uBC84\uC804 {version}\uC774 \uC788\uC2B5\uB2C8\uB2E4. {command}\uB85C \uC124\uCE58\uD55C \uB4A4 gitifact init\uC744 \uB2E4\uC2DC \uC2E4\uD589\uD558\uBA74 \uC9C0\uCE68 \uBE14\uB85D\uC774 \uC0C8 \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uB429\uB2C8\uB2E4.",
24922
24917
  "init.failed": "\uCD08\uAE30\uD654\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uD30C\uC77C \uC811\uADFC \uAD8C\uD55C\uACFC \uC0DD\uC131\uB41C \uC124\uC815\xB7\uC784\uC2DC \uD30C\uC77C\uC744 \uD655\uC778\uD558\uC138\uC694.",
24923
24918
  "config.storeNotDirectory": ".gitifact\uB294 \uB9C1\uD06C\uAC00 \uC544\uB2CC \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
24924
24919
  "config.migrateFirst": ".tryce \uC800\uC7A5\uC18C\uC785\uB2C8\uB2E4. gitifact migrate\uB85C .gitifact\uC5D0 \uC804\uD658\uD558\uC138\uC694.",
@@ -24954,6 +24949,7 @@ var messages_default2 = {
24954
24949
  "docs.summary.workflow": "\uC2DC\uC791 \uC2DC \uD655\uC778\uD560 \uAC83, \uC694\uAD6C\uC0AC\uD56D\uC73C\uB85C \uB0A8\uAE38 \uC694\uCCAD\uC758 \uAD6C\uBD84, \uB9C8\uBB34\uB9AC \uBCF4\uACE0",
24955
24950
  "docs.summary.spec": "\uC0AC\uC6A9\uC790 \uC2A4\uD1A0\uB9AC\xB7\uC218\uC6A9 \uC870\uAC74 \uD615\uC2DD, ID \uADDC\uCE59, spec save \uC785\uB825",
24956
24951
  "docs.summary.design": "design.md \uBAA9\uCC28, \uCC38\uC870 \uC8FC\uC11D\uACFC \uCC38\uACE0 \uBB38\uC11C, \uAC1C\uC815 \uBC29\uC2DD",
24952
+ "docs.summary.writing": "\uC704\uD0A4\xB7\uC694\uAD6C\uC0AC\uD56D\xB7\uC124\uACC4\uC5D0 \uACF5\uD1B5\uC73C\uB85C \uC801\uC6A9\uD558\uB294 \uBB38\uCCB4, \uC778\uC6A9\uACFC Alert, AI \uC2AC\uB86D \uC81C\uAC70",
24957
24953
  "docs.summary.commit": "spec commit \uC785\uB825, \uC774\uC720 \uAE30\uB85D, \uC2E4\uD328 \uD6C4 \uBCF5\uAD6C",
24958
24954
  "help.browserNoUpdateCheck": "\uC0C8 \uBC84\uC804 \uD655\uC778\uC744 \uC704\uD55C npm \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC870\uD68C\uB97C \uB054 (GITIFACT_NO_UPDATE_CHECK\uC640 \uAC19\uC74C)",
24959
24955
  "help.updateCommit": "\uAC31\uC2E0\uD55C GITIFACT \uBE14\uB85D\uC774 HEAD\uC640 \uBE14\uB85D \uC548\uC5D0\uC11C\uB9CC \uB2E4\uB974\uBA74 \uADF8 \uD30C\uC77C\uB9CC \uACE0\uC815 \uBA54\uC2DC\uC9C0\uB85C \uCEE4\uBC0B",
@@ -25331,7 +25327,7 @@ function specPreviewReader(cwd) {
25331
25327
  }
25332
25328
 
25333
25329
  // src/adapters/filesystem/spec-preview-store.ts
25334
- import { lstat as lstat3, readdir as readdir3, readFile as readFile3, mkdir as mkdir2, writeFile, rename, unlink as unlink2, rmdir } from "node:fs/promises";
25330
+ import { lstat as lstat3, readdir as readdir3, readFile as readFile3, mkdir as mkdir2, writeFile, rename as rename2, unlink as unlink2, rmdir } from "node:fs/promises";
25335
25331
  import { join as join4, dirname } from "node:path";
25336
25332
  import { createHash as createHash2, randomBytes } from "node:crypto";
25337
25333
 
@@ -25383,7 +25379,7 @@ async function workingWarnings(root, bundle) {
25383
25379
  }
25384
25380
 
25385
25381
  // src/adapters/filesystem/config-file.ts
25386
- import { lstat as lstat2, readFile as readFile2, realpath, mkdir, open as open2, link, unlink } from "node:fs/promises";
25382
+ import { lstat as lstat2, readFile as readFile2, realpath, mkdir, open as open2, link, rename, unlink } from "node:fs/promises";
25387
25383
  import { join as join3 } from "node:path";
25388
25384
  import { randomUUID as randomUUID3 } from "node:crypto";
25389
25385
  var missing = (error62) => error62.code === "ENOENT";
@@ -25418,7 +25414,7 @@ async function readConfigFile(root) {
25418
25414
  throw new InitError("INVALID_CONFIG", t2("config.notUtf8Json"));
25419
25415
  }
25420
25416
  }
25421
- async function publishConfig(root, text2, recheck, beforePublish) {
25417
+ async function publishConfig(root, text2, recheck, beforePublish, replace = false) {
25422
25418
  const directory = join3(root, ".gitifact");
25423
25419
  await configDirectory(root);
25424
25420
  await mkdir(directory).catch((error62) => {
@@ -25449,7 +25445,8 @@ async function publishConfig(root, text2, recheck, beforePublish) {
25449
25445
  const bytes = await readFile2(temporary, "utf8");
25450
25446
  if (bytes !== text2) throw new InitError("INPUT_CHANGED", t2("config.temporaryChanged"));
25451
25447
  parseManagedConfig(bytes);
25452
- await link(temporary, join3(directory, "config.json"));
25448
+ if (replace) await rename(temporary, join3(directory, "config.json"));
25449
+ else await link(temporary, join3(directory, "config.json"));
25453
25450
  } finally {
25454
25451
  await unchanged();
25455
25452
  const current = await fileInfo(temporary);
@@ -25521,7 +25518,7 @@ async function readWorkingPreview(cwd) {
25521
25518
  const { root, stamp, specs, wiki, bundle } = await readWorkingPreviewState(cwd);
25522
25519
  return { stamp, specs, wiki, warnings: await workingWarnings(root, bundle) };
25523
25520
  }
25524
- async function saveWorkingPreview(cwd, input2, publish = rename) {
25521
+ async function saveWorkingPreview(cwd, input2, publish = rename2) {
25525
25522
  if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail4(t2("store.invalidInput"));
25526
25523
  const request = input2;
25527
25524
  if (Object.keys(request).sort().join(",") !== "expected,operations" || typeof request.expected !== "string") fail4(t2("store.expectedOperations"));
@@ -25545,7 +25542,7 @@ async function saveWorkingPreview(cwd, input2, publish = rename) {
25545
25542
  }, publish);
25546
25543
  }
25547
25544
  var readLockedPreviewState = (root) => snapshot2(root);
25548
- async function previewTransaction(cwd, expected2, build, publish = rename, afterPublish) {
25545
+ async function previewTransaction(cwd, expected2, build, publish = rename2, afterPublish) {
25549
25546
  const { root, gitDir } = await specPreviewReader(cwd).location();
25550
25547
  await failOnLegacyLock(gitDir);
25551
25548
  const lock = join4(gitDir, "gitifact-spec-preview.lock");
@@ -25630,7 +25627,7 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
25630
25627
  const temp = join4(dirname(path3), ".gitifact-restore-" + randomBytes(12).toString("hex"));
25631
25628
  temporary.push(temp);
25632
25629
  await writeFile(temp, c.before, { flag: "wx" });
25633
- await rename(temp, path3);
25630
+ await rename2(temp, path3);
25634
25631
  }
25635
25632
  } catch {
25636
25633
  keepRecovery = true;
@@ -25688,9 +25685,10 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
25688
25685
  const current = await readWorkingPreviewState(root);
25689
25686
  const bare = current.specs.map(({ history: _history, ...s }) => ({ ...s, contributors: [], updatedAt: null }));
25690
25687
  const bareDocuments = current.wiki.documents.map((d) => ({ ...d, updatedAt: null }));
25691
- if (!base.head) return browserSpecsV2.parse({ contract: "browser-specs", version: 2, sessionId, head: null, observedAt: (/* @__PURE__ */ new Date()).toISOString(), working: bare.length > 0 || bareDocuments.length > 0, features: bare, documents: bareDocuments, events: [], contributors: [], contributorsLimited: false, nextCursor: null, boundary: false });
25688
+ if (!base.head) return browserSpecsV3.parse({ contract: "browser-specs", version: 3, sessionId, head: null, observedAt: (/* @__PURE__ */ new Date()).toISOString(), working: bare.length > 0 || bareDocuments.length > 0, features: bare, documents: bareDocuments, events: [], contributors: [], contributorsLimited: false, nextCursor: null, boundary: false });
25692
25689
  const head = base.head;
25693
- const features = await Promise.all(bare.map(async (feature2) => {
25690
+ const first = cursor === 0;
25691
+ const features = !first ? void 0 : await Promise.all(bare.map(async (feature2) => {
25694
25692
  const folder = feature2.path.replace(/^\.(?:gitifact|tryce)\/(spec\/[^/]+)\/requirements\.md$/, "$1");
25695
25693
  const lines = (await git(["log", "--format=%aN%x00%aE%x00%aI", "--max-count=2000", head, "--", `.gitifact/${folder}`, `.tryce/${folder}`])).trim().split("\n").filter(Boolean);
25696
25694
  const people = /* @__PURE__ */ new Map();
@@ -25703,7 +25701,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
25703
25701
  }
25704
25702
  return { ...feature2, contributors: [...people.values()].sort((a, b) => b.commits - a.commits), updatedAt: lines[0]?.split("\0")[2] ?? null };
25705
25703
  }));
25706
- const documents = await Promise.all(bareDocuments.map(async (doc) => ({ ...doc, updatedAt: (await git(["log", "--format=%aI", "--max-count=1", head, "--", doc.path])).trim() || null })));
25704
+ const documents = !first ? void 0 : await Promise.all(bareDocuments.map(async (doc) => ({ ...doc, updatedAt: (await git(["log", "--format=%aI", "--max-count=1", head, "--", doc.path])).trim() || null })));
25707
25705
  const documentDirs = [WIKI_DIR];
25708
25706
  const [rows, dirty] = await Promise.all([
25709
25707
  git([
@@ -25718,9 +25716,9 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
25718
25716
  ...[".gitifact", ".tryce"].flatMap((d) => [`:(glob)${d}/spec/*/requirements.md`, `:(glob)${d}/spec/*/design.md`, `:(glob)${d}/spec/*/history.jsonl`]),
25719
25717
  ...documentDirs.flatMap((d) => [`:(glob)${d}/**/*.md`, `:(glob)${d}/history.jsonl`])
25720
25718
  ]),
25721
- git(["status", "--porcelain=v1", "--", ".gitifact/spec", ...documentDirs])
25719
+ first ? git(["status", "--porcelain=v1", "--", ".gitifact/spec", ...documentDirs]) : Promise.resolve("")
25722
25720
  ]);
25723
- {
25721
+ if (first) {
25724
25722
  const people = /* @__PURE__ */ new Map();
25725
25723
  const lines = (await git(["log", "--format=%aN%x00%aE%x00%aI", "--max-count=10001", head])).trim().split("\n").filter(Boolean);
25726
25724
  for (const line of lines.slice(0, 1e4)) {
@@ -25765,20 +25763,16 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
25765
25763
  }));
25766
25764
  }));
25767
25765
  if (await readHead() !== head || (await readWorkingPreviewState(root)).stamp !== current.stamp) throw new SpecPreviewError(t2("specReader.projectChanged"));
25768
- return browserSpecsV2.parse({
25766
+ return browserSpecsV3.parse({
25769
25767
  contract: "browser-specs",
25770
- version: 2,
25768
+ version: 3,
25771
25769
  sessionId,
25772
25770
  head,
25773
25771
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
25774
- working: !!dirty.trim(),
25775
- features,
25776
- documents,
25777
25772
  events: groups.flat(),
25778
- contributors: peopleCache.data,
25779
- contributorsLimited: peopleCache.limited,
25780
25773
  nextCursor: commits.length > 10 ? cursor + 10 : null,
25781
- boundary
25774
+ boundary,
25775
+ ...first ? { working: !!dirty.trim(), features, documents, contributors: peopleCache?.data ?? [], contributorsLimited: peopleCache?.limited ?? false } : {}
25782
25776
  });
25783
25777
  }
25784
25778
  return (cursor = 0, head) => {
@@ -26108,7 +26102,7 @@ function initRepository(cwd, inherited = process.env) {
26108
26102
  }
26109
26103
 
26110
26104
  // src/adapters/filesystem/managed-file.ts
26111
- import { open as open3, readFile as readFile6, mkdir as mkdir3, realpath as realpath2, rename as rename2, link as link2, unlink as unlink3 } from "node:fs/promises";
26105
+ import { open as open3, readFile as readFile6, mkdir as mkdir3, realpath as realpath2, rename as rename3, link as link2, unlink as unlink3 } from "node:fs/promises";
26112
26106
  import { join as join7, dirname as dirname2 } from "node:path";
26113
26107
  import { randomUUID as randomUUID5 } from "node:crypto";
26114
26108
  var DEFAULT_LIMIT = 1024 * 1024;
@@ -26178,7 +26172,7 @@ async function managedWrite(root, path3, previous, next, recheck) {
26178
26172
  await unchanged();
26179
26173
  if (await managedRead(root, path3) !== previous || await readFile6(temp, "utf8") !== next) throw new InitError("INPUT_CHANGED", t2("managedFile.publishTargetChanged", { path: path3 }));
26180
26174
  if (previous === null) await link2(temp, full);
26181
- else await rename2(temp, full);
26175
+ else await rename3(temp, full);
26182
26176
  } finally {
26183
26177
  await unchanged();
26184
26178
  const now = await fileInfo(temp);
@@ -26192,7 +26186,7 @@ import { readFile as readFile8 } from "node:fs/promises";
26192
26186
  // src/commands/docs.ts
26193
26187
  import { lstat as lstat5, readFile as readFile7 } from "node:fs/promises";
26194
26188
  import { dirname as dirname3, join as join8 } from "node:path";
26195
- var docTopics = ["workflow", "spec", "design", "wiki", "commit"];
26189
+ var docTopics = ["workflow", "spec", "design", "wiki", "writing", "commit"];
26196
26190
  var isDocTopic = (value) => docTopics.includes(value);
26197
26191
  var readBundledDoc = (name, lang) => readFile7(new URL("./i18n/" + lang + "/docs/" + name + ".md", import.meta.url), "utf8");
26198
26192
  var info3 = (path3) => lstat5(path3).catch((e) => {
@@ -26389,22 +26383,27 @@ async function applyAgentDocs(root, plan, recheck) {
26389
26383
  }
26390
26384
 
26391
26385
  // src/commands/spec-init.ts
26392
- async function initializeSpecProject(cwd, dryRun = false, env = process.env, beforePublish, agentDocs, readDoc = (name) => readBundledDoc(name, defaultLanguage2)) {
26386
+ async function initializeSpecProject(cwd, dryRun = false, env = process.env, beforePublish, agentDocs, readDoc = (name) => readBundledDoc(name, defaultLanguage2), update = disabledUpdate) {
26393
26387
  const repo = initRepository(cwd, env);
26394
26388
  const first = await repo.inspect();
26395
26389
  const root = first.state.repository.rootPath;
26396
26390
  const docsPlan = agentDocs ? await planAgentDocs(root, agentDocs) : skippedAgentDocs;
26397
- const result = (config3, outcome) => projectInitV4.parse({
26398
- contract: "project-init",
26399
- version: 4,
26400
- ok: true,
26401
- outcome,
26402
- rootPath: root,
26403
- configPath: ".gitifact/config.json",
26404
- schemaVersion: config3.schemaVersion,
26405
- baseline: config3.baseline,
26406
- agentDocs: { mode: docsPlan.mode, paths: docsPlan.paths }
26407
- });
26391
+ const result = async (config3, outcome) => {
26392
+ const checked = await update;
26393
+ return projectInitV5.parse({
26394
+ contract: "project-init",
26395
+ version: 5,
26396
+ ok: true,
26397
+ outcome,
26398
+ rootPath: root,
26399
+ configPath: ".gitifact/config.json",
26400
+ schemaVersion: config3.schemaVersion,
26401
+ baseline: config3.baseline,
26402
+ agentDocs: { mode: docsPlan.mode, paths: docsPlan.paths },
26403
+ update: checked,
26404
+ install: checked.status === "available" ? { npmGlobal: npmGlobalInstall(checked.latestVersion) } : null
26405
+ });
26406
+ };
26408
26407
  const existing = async (text3) => {
26409
26408
  const config3 = parseManagedConfig(text3);
26410
26409
  if (!("schemaVersion" in config3)) throw new InitError("MIGRATION_REQUIRED", t2("init.migrationRequired"));
@@ -26416,8 +26415,40 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
26416
26415
  if (!dryRun) await applyAgentDocs(root, docsPlan, unchanged);
26417
26416
  return result(config3, "already-initialized");
26418
26417
  };
26418
+ const config2 = { schemaVersion: SCHEMA_VERSION, baseline: first.state.head.commit ? { kind: "commit", objectFormat: first.state.repository.objectFormat, commit: first.state.head.commit } : { kind: "empty" } };
26419
+ const text2 = JSON.stringify(config2, null, 2) + "\n";
26420
+ const replaceLegacy = async (before, version2) => {
26421
+ const onlyConfig = async () => {
26422
+ const entries = await readdir4(join9(root, ".gitifact"));
26423
+ if (await fileInfo(join9(root, "specs")) || entries.some((name) => name !== "config.json" && !/^\.init-[a-f0-9-]+\.tmp$/.test(name))) {
26424
+ throw new InitError("UNSUPPORTED_SCHEMA", t2("init.legacyRecords", { version: String(version2) }));
26425
+ }
26426
+ };
26427
+ const recheck2 = async () => {
26428
+ await onlyConfig();
26429
+ await repo.checkIgnore(root);
26430
+ if ((await repo.inspect()).stamp !== first.stamp) throw new InitError("INPUT_CHANGED", t2("init.headOrIndexChanged"));
26431
+ if (await readConfigFile(root) !== before) throw new InitError("INPUT_CHANGED", t2("init.inputChanged"));
26432
+ };
26433
+ await recheck2();
26434
+ if (dryRun) return result(config2, "planned");
26435
+ await publishConfig(root, text2, recheck2, beforePublish, true);
26436
+ return finish("replaced");
26437
+ };
26438
+ const finish = async (outcome) => {
26439
+ const published = async () => {
26440
+ if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text2) throw new InitError("INPUT_CHANGED_AFTER_WRITE", t2("init.changedAfterWrite"));
26441
+ };
26442
+ await published();
26443
+ await applyAgentDocs(root, docsPlan, published);
26444
+ await writeWikiPolicy(root, readDoc);
26445
+ return result(config2, outcome);
26446
+ };
26419
26447
  const old = await readConfigFile(root);
26420
- if (old !== void 0) return existing(old);
26448
+ if (old !== void 0) {
26449
+ const legacy = legacySchemaVersion(old);
26450
+ return legacy === void 0 ? existing(old) : replaceLegacy(old, legacy);
26451
+ }
26421
26452
  if (first.trackedConfig) throw new InitError("CONFIG_DELETED", t2("init.configDeleted"));
26422
26453
  const checkRecords = async () => {
26423
26454
  if (await fileInfo(join9(root, "specs"))) throw new InitError("EXISTING_RECORDS", t2("init.existingSpecs"));
@@ -26427,8 +26458,6 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
26427
26458
  });
26428
26459
  if (entries.some((name) => !/^\.init-[a-f0-9-]+\.tmp$/.test(name))) throw new InitError("EXISTING_RECORDS", t2("init.orphanStore"));
26429
26460
  };
26430
- const config2 = { schemaVersion: SCHEMA_VERSION, baseline: first.state.head.commit ? { kind: "commit", objectFormat: first.state.repository.objectFormat, commit: first.state.head.commit } : { kind: "empty" } };
26431
- const text2 = JSON.stringify(config2, null, 2) + "\n";
26432
26461
  const recheck = async () => {
26433
26462
  await checkRecords();
26434
26463
  await repo.checkIgnore(root);
@@ -26446,13 +26475,18 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
26446
26475
  }
26447
26476
  throw error62;
26448
26477
  }
26449
- const published = async () => {
26450
- if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text2) throw new InitError("INPUT_CHANGED_AFTER_WRITE", t2("init.changedAfterWrite"));
26451
- };
26452
- await published();
26453
- await applyAgentDocs(root, docsPlan, published);
26454
- await writeWikiPolicy(root, readDoc);
26455
- return result(config2, "created");
26478
+ return finish("created");
26479
+ }
26480
+ function legacySchemaVersion(text2) {
26481
+ let value;
26482
+ try {
26483
+ value = JSON.parse(text2);
26484
+ } catch {
26485
+ return void 0;
26486
+ }
26487
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
26488
+ const version2 = value.schemaVersion;
26489
+ return Number.isInteger(version2) && version2 < SCHEMA_VERSION ? version2 : void 0;
26456
26490
  }
26457
26491
  async function writeWikiPolicy(root, readDoc) {
26458
26492
  if (await fileInfo(join9(root, ...WIKI_DIR.split("/")))) return;
@@ -26470,24 +26504,30 @@ async function writeWikiPolicy(root, readDoc) {
26470
26504
 
26471
26505
  // src/commands/init.ts
26472
26506
  async function runInit(options, version2) {
26507
+ const cancel = new AbortController();
26508
+ const update = updateCheckDisabled(process.env) ? disabledUpdate : resolveUpdate(version2, fetchLatestVersion, cancel.signal);
26473
26509
  try {
26474
26510
  const dto = await initializeSpecProject(
26475
26511
  process.cwd(),
26476
26512
  options.dryRun,
26477
26513
  process.env,
26478
26514
  void 0,
26479
- { version: version2, agent: options.agent, remove: options.removeAgents, skip: options.skipAgents }
26515
+ { version: version2, agent: options.agent, remove: options.removeAgents, skip: options.skipAgents },
26516
+ void 0,
26517
+ update
26480
26518
  );
26481
26519
  if (!dto.ok) throw new Error("unreachable");
26482
26520
  const docs = dto.agentDocs.mode === "skip" ? t2("init.text.skipped") : dto.agentDocs.paths.join(", ") + (dto.agentDocs.mode === "remove" ? " (" + t2("init.text.blockRemoved") + ")" : dto.outcome === "planned" ? " (" + t2("init.text.blockPlanned") + ")" : " (" + t2("init.text.blockUpdated") + ")");
26521
+ const newer = dto.install ? t2("init.text.updateAvailable", { version: dto.update.latestVersion, command: dto.install.npmGlobal }) + "\n" : "";
26483
26522
  process.stdout.write(options.format === "text" ? `${dto.outcome}: ${dto.rootPath}/.gitifact/config.json
26484
26523
  ${t2("init.text.storage")}: schemaVersion ${dto.schemaVersion}
26485
26524
  ${t2("init.text.agentDocs")}: ${docs}
26486
- ` : JSON.stringify(dto) + "\n");
26525
+ ${newer}` : JSON.stringify(dto) + "\n");
26487
26526
  } catch (error62) {
26527
+ cancel.abort();
26488
26528
  const known = error62 instanceof InitError || error62 instanceof RepositoryReadError;
26489
26529
  const failure2 = { code: known ? error62.code : "INIT_FAILED", message: known ? error62.message : t2("init.failed") };
26490
- process.stderr.write(options.format === "text" ? failure2.code + ": " + failure2.message + "\n" : JSON.stringify(projectInitV4.parse({ contract: "project-init", version: 4, ok: false, error: failure2 })) + "\n");
26530
+ process.stderr.write(options.format === "text" ? failure2.code + ": " + failure2.message + "\n" : JSON.stringify(projectInitV5.parse({ contract: "project-init", version: 5, ok: false, error: failure2 })) + "\n");
26491
26531
  process.exitCode = 1;
26492
26532
  }
26493
26533
  }
@@ -26634,10 +26674,10 @@ async function runUpdate(options, version2) {
26634
26674
  }
26635
26675
 
26636
26676
  // src/commands/spec-preview.ts
26637
- import { join as join15 } from "node:path";
26638
- import { readFile as readFile12, stat as stat2 } from "node:fs/promises";
26677
+ import { join as join14 } from "node:path";
26678
+ import { readFile as readFile11, stat as stat2 } from "node:fs/promises";
26639
26679
 
26640
- // src/adapters/filesystem/spec-preview-prepare.ts
26680
+ // src/adapters/filesystem/spec-preview-context.ts
26641
26681
  import { lstat as lstat6 } from "node:fs/promises";
26642
26682
  import { join as join10 } from "node:path";
26643
26683
  import { createHash as createHash4 } from "node:crypto";
@@ -26680,44 +26720,6 @@ async function readFinalPreviewChanges(cwd) {
26680
26720
  const pendingReasons = pendingPreviewReasons(c.bundle, current.bundle);
26681
26721
  return { base: c.base, expected: expected(c.base, current.stamp), stamp: current.stamp, pendingReasons, ...delta };
26682
26722
  }
26683
- async function prepareWorkingPreview(cwd, input2, publish) {
26684
- if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5(t2("prepare.invalidInput"));
26685
- const request = input2;
26686
- if (Object.keys(request).sort().join(",") !== "expected,reasons" || typeof request.expected !== "string") fail5(t2("prepare.expectedReasons"));
26687
- const c = await context(cwd);
26688
- const current = await readWorkingPreviewState(cwd);
26689
- if (request.expected !== expected(c.base, current.stamp)) fail5(t2("prepare.staleInput"));
26690
- const result = await previewTransaction(cwd, current.stamp, async (before) => {
26691
- await c.recheck();
26692
- const prepared = prepareSpecPreview(c.bundle, before.bundle, c.files, before.files, request.reasons, () => generatePreviewId("H"));
26693
- return { writes: prepared.writes, data: { changes: prepared.changes, specChanges: prepared.specChanges, reasons: prepared.reasons, withoutReason: prepared.withoutReason }, recheck: c.recheck };
26694
- }, publish);
26695
- return { ...result, base: c.base, expected: expected(c.base, result.stamp), verification: { base: c.base, stamp: result.stamp } };
26696
- }
26697
- async function verifyPreparedPreview(cwd, input2, staged) {
26698
- if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5(t2("prepare.invalidVerifyInput"));
26699
- const request = input2;
26700
- if (Object.keys(request).sort().join(",") !== "base,stamp" || typeof request.stamp !== "string") fail5(t2("prepare.verificationRequired"));
26701
- const c = await context(cwd);
26702
- const current = await readWorkingPreviewState(cwd);
26703
- if (!same(request.base, c.base) || request.stamp !== current.stamp) fail5(t2("prepare.changedAfterPrepare"));
26704
- finalSpecPreviewChanges(c.bundle, current.bundle);
26705
- comparePreviewBundles(c.bundle, current.bundle);
26706
- if (staged) {
26707
- const index = await c.reader.index();
26708
- if (index.size !== current.files.size) fail5(t2("prepare.stagingScope"));
26709
- for (const [path3, source2] of current.files) {
26710
- const oid2 = index.get(path3);
26711
- const bytes = Buffer.from(source2);
26712
- const hash3 = createHash4(oid2?.length === 64 ? "sha256" : "sha1").update(`blob ${bytes.length}\0`).update(bytes).digest("hex");
26713
- if (oid2 !== hash3) fail5(t2("prepare.stagingContent", { path: path3 }));
26714
- }
26715
- if (!same([...index], [...await c.reader.index()])) fail5(t2("prepare.stagingChanged"));
26716
- }
26717
- if ((await readWorkingPreviewState(cwd)).stamp !== current.stamp) fail5(t2("prepare.specsChanged"));
26718
- await c.recheck();
26719
- return { verified: true, scope: staged ? "staged" : "working", base: c.base, stamp: current.stamp };
26720
- }
26721
26723
 
26722
26724
  // src/adapters/filesystem/agent-inputs.ts
26723
26725
  import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
@@ -26784,9 +26786,9 @@ async function discardAgentInput(root, file2, controls = {}) {
26784
26786
  }
26785
26787
  }
26786
26788
 
26787
- // src/commands/spec-preview-commit.ts
26788
- import { randomUUID as randomUUID6 } from "node:crypto";
26789
- import { readFile as readFile10, mkdir as mkdir6, open as open4, rename as rename3, unlink as unlink5, rmdir as rmdir2, writeFile as writeFile4 } from "node:fs/promises";
26789
+ // src/commands/spec-commit.ts
26790
+ import { createHash as createHash7, randomUUID as randomUUID6 } from "node:crypto";
26791
+ import { mkdir as mkdir6, open as open4, readFile as readFile10, rename as rename4, rmdir as rmdir2, unlink as unlink5, writeFile as writeFile4 } from "node:fs/promises";
26790
26792
  import { join as join13 } from "node:path";
26791
26793
 
26792
26794
  // src/commands/spec-commit-files.ts
@@ -26858,166 +26860,7 @@ async function checkLegacySelection(root, selected) {
26858
26860
  }
26859
26861
  }
26860
26862
 
26861
- // src/commands/spec-preview-commit.ts
26862
- var seal = (p) => hash2(JSON.stringify(p));
26863
- async function previewCommit(cwd, action, input2) {
26864
- const reader = specPreviewReader(cwd);
26865
- const { root, gitDir } = await reader.location();
26866
- const runner = createGitRunner();
26867
- const git = (args, index) => runner(["-c", "core.fsmonitor=false", ...args], {
26868
- cwd: root,
26869
- env: {
26870
- ...process.env,
26871
- GIT_LITERAL_PATHSPECS: "1",
26872
- GIT_GLOB_PATHSPECS: "0",
26873
- GIT_NOGLOB_PATHSPECS: "0",
26874
- GIT_ICASE_PATHSPECS: "0",
26875
- GIT_OPTIONAL_LOCKS: "0",
26876
- GIT_NO_LAZY_FETCH: "1",
26877
- GIT_NO_REPLACE_OBJECTS: "1",
26878
- GIT_TERMINAL_PROMPT: "0",
26879
- ...index ? { GIT_INDEX_FILE: index } : {}
26880
- },
26881
- timeoutMs: 12e4,
26882
- maxBytes: 32 * 1024 * 1024
26883
- });
26884
- const indexPath = (await git(["rev-parse", "--path-format=absolute", "--git-path", "index"])).toString("utf8").trim();
26885
- const staged = async (index) => (await git(["diff", "--cached", "--ita-visible-in-index", "--name-only", "--no-renames", "-z"], index)).toString("utf8").split("\0").filter(Boolean).sort();
26886
- const busy = join13(gitDir, "gitifact-spec-commit.lock");
26887
- if (await info5(busy)) fail6(t2("commit.busy", { path: busy }));
26888
- if ((await staged()).length) fail6(t2("commit.existingStagingPlan"));
26889
- const request = object3(input2);
26890
- let plan;
26891
- if (action === "plan") {
26892
- if (Object.keys(request).some((k) => !["verification", "paths", "message", "requirements", "authorization", "policyFiles"].includes(k))) fail6(t2("commit.unknownField"));
26893
- await verifyPreparedPreview(cwd, request.verification, false);
26894
- const selected2 = paths(request.paths);
26895
- const authorization = object3(request.authorization);
26896
- await checkLegacySelection(root, selected2);
26897
- if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail6(t2("commit.authorizationRequired"));
26898
- const message = text(request.message, 4e3);
26899
- if (/^\s*Gitifact-/im.test(message)) fail6(t2("commit.trailerInMessage"));
26900
- const state = await readWorkingPreviewState(cwd);
26901
- const base = await reader.baseline();
26902
- const previous = base.head ? await reader.files(base.head, state.config !== void 0) : /* @__PURE__ */ new Map();
26903
- const pending = [.../* @__PURE__ */ new Set([...previous.keys(), ...state.files.keys()])].filter((p) => previous.get(p) !== state.files.get(p));
26904
- if (pending.some((p) => !selected2.includes(p))) fail6(t2("commit.selectPending"));
26905
- const delta = await readFinalPreviewChanges(cwd);
26906
- const references = request.requirements ?? [];
26907
- if (!Array.isArray(references) || references.length > 1e3 || references.some((r) => typeof r !== "string")) fail6(t2("commit.invalidReferences"));
26908
- if (delta.changes.some((c) => c.kind === "design")) fail6(t2("commit.designUseSpecCommit"));
26909
- const known = /* @__PURE__ */ new Set([...state.specs.flatMap((s) => s.requirements.map((r) => r.id)), ...delta.changes.map((c) => c.id)]);
26910
- if (references.some((r) => !known.has(r))) fail6(t2("commit.unknownRequirement"));
26911
- const extra = request.policyFiles === void 0 ? [] : paths(request.policyFiles, 1024);
26912
- const contents = async (list) => Promise.all(list.map(async (path3) => ({ path: path3, hash: await fingerprint(root, path3) })));
26913
- const data2 = {
26914
- kind: "spec-preview-commit",
26915
- root,
26916
- verification: request.verification,
26917
- index: hash2(await optional2(indexPath) ?? Buffer.alloc(0)),
26918
- files: await contents(selected2),
26919
- context: await contents([.../* @__PURE__ */ new Set([...policyPaths(selected2), ...extra])].sort()),
26920
- message,
26921
- requirements: [.../* @__PURE__ */ new Set([...references, ...delta.changes.map((c) => c.id)])].sort(),
26922
- authorization: { basis: String(authorization.basis), evidence: text(authorization.evidence, 2e3) }
26923
- };
26924
- await verifyPreparedPreview(cwd, request.verification, false);
26925
- if (data2.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6(t2("commit.indexChangedPlanning"));
26926
- return { outcome: "planned", plan: { ...data2, digest: seal(data2) }, committed: false };
26927
- }
26928
- const { digest: digest2, ...data } = request;
26929
- if (request.kind !== "spec-preview-commit" || typeof digest2 !== "string" || digest2 !== seal(data)) fail6(t2("commit.planCorrupted"));
26930
- plan = request;
26931
- if (plan.root !== root || !Array.isArray(plan.files) || !Array.isArray(plan.context)) fail6(t2("commit.planScope"));
26932
- const selected = paths(plan.files.map((f) => f.path));
26933
- const refreshed = await previewCommit(cwd, "plan", {
26934
- verification: plan.verification,
26935
- paths: selected,
26936
- message: plan.message,
26937
- requirements: plan.requirements,
26938
- authorization: plan.authorization,
26939
- policyFiles: plan.context.map((f) => f.path)
26940
- });
26941
- if (!("plan" in refreshed) || refreshed.plan.digest !== plan.digest) fail6(t2("commit.planStale"));
26942
- const before = await reader.baseline();
26943
- const original = await optional2(indexPath);
26944
- await mkdir6(busy);
26945
- const draftLock = join13(gitDir, "gitifact-spec-preview.lock");
26946
- let draftOwned = false;
26947
- let indexLock;
26948
- let uncertain = false;
26949
- let commitStarted = false;
26950
- const temporary = join13(gitDir, "gitifact-commit-index-" + randomUUID6());
26951
- const checkFiles = async () => {
26952
- for (const f of [...plan.files, ...plan.context]) if (f.hash !== await fingerprint(root, f.path)) fail6(t2("commit.fileChangedPreparing", { path: f.path }));
26953
- if ((await readLockedPreviewState(root)).stamp !== object3(plan.verification).stamp) fail6(t2("commit.specsChangedPreparing"));
26954
- for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) if (await info5(join13(gitDir, name))) fail6(t2("commit.integrationStarted"));
26955
- };
26956
- try {
26957
- await verifyPreparedPreview(cwd, plan.verification, false);
26958
- await mkdir6(draftLock);
26959
- draftOwned = true;
26960
- indexLock = await open4(indexPath + ".lock", "wx", 384);
26961
- if (plan.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6(t2("commit.indexChangedLocked"));
26962
- await writeFile4(join13(busy, "recovery.json"), JSON.stringify({ before, originalIndex: original?.toString("base64") ?? null, temporary, plan }));
26963
- if (original) await writeFile4(temporary, original, { flag: "wx" });
26964
- else await git(["read-tree", "--empty"], temporary);
26965
- await git(["add", "--", ...selected], temporary);
26966
- const actual = await staged(temporary);
26967
- if (!actual.length || actual.some((p) => !selected.includes(p))) fail6(t2("commit.unexpectedFiles"));
26968
- for (const file2 of plan.files.filter((f) => record2(f.path) && f.hash !== null)) {
26969
- const stagedBytes = await git(["show", ":" + file2.path], temporary);
26970
- if (!stagedBytes.equals(await readFile10(join13(root, file2.path)))) fail6(t2("commit.filterChanged"));
26971
- }
26972
- await checkFiles();
26973
- if (JSON.stringify(before) !== JSON.stringify(await reader.baseline())) fail6(t2("commit.headChanged"));
26974
- const tree = (await git(["write-tree"], temporary)).toString("utf8").trim();
26975
- const trailers = plan.requirements.map((id) => "Gitifact-Req: " + id);
26976
- commitStarted = true;
26977
- await git(["commit", "-m", plan.message.trim() + (trailers.length ? "\n\n" + trailers.join("\n") : "")], temporary);
26978
- const after = await reader.baseline();
26979
- const actualTree = (await git(["rev-parse", "HEAD^{tree}"])).toString("utf8").trim();
26980
- const parents = (await git(["rev-list", "--parents", "-n", "1", "HEAD"])).toString("utf8").trim().split(" ").slice(1);
26981
- const message = (await git(["log", "-1", "--format=%B"])).toString("utf8");
26982
- if (actualTree !== tree || after.branch !== before.branch || JSON.stringify(parents) !== JSON.stringify(before.head ? [before.head] : []) || trailers.some((t3) => !message.split(/\r?\n/).includes(t3))) fail6(t2("commit.resultAltered"));
26983
- if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== plan.index) fail6(t2("commit.indexChangedAfter"));
26984
- if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6(t2("commit.hookChangedStaging"));
26985
- await indexLock.writeFile(await readFile10(temporary));
26986
- await indexLock.sync();
26987
- await indexLock.close();
26988
- await rename3(indexPath + ".lock", indexPath);
26989
- indexLock = void 0;
26990
- return { outcome: "committed", commit: after.head, paths: actual, requirements: plan.requirements, pushed: false };
26991
- } catch (error62) {
26992
- if (commitStarted) {
26993
- try {
26994
- uncertain = JSON.stringify(before) !== JSON.stringify(await reader.baseline());
26995
- } catch {
26996
- uncertain = true;
26997
- }
26998
- }
26999
- if (uncertain) fail6(t2("commit.uncertain", { path: busy }));
27000
- throw error62;
27001
- } finally {
27002
- await indexLock?.close().catch(() => {
27003
- });
27004
- if (!uncertain) {
27005
- if (indexLock) await unlink5(indexPath + ".lock").catch(() => {
27006
- });
27007
- await unlink5(temporary).catch(() => {
27008
- });
27009
- await unlink5(join13(busy, "recovery.json")).catch(() => {
27010
- });
27011
- await rmdir2(busy);
27012
- if (draftOwned) await rmdir2(draftLock);
27013
- }
27014
- }
27015
- }
27016
-
27017
26863
  // src/commands/spec-commit.ts
27018
- import { createHash as createHash8, randomUUID as randomUUID7 } from "node:crypto";
27019
- import { mkdir as mkdir7, open as open5, readFile as readFile11, rename as rename4, rmdir as rmdir3, unlink as unlink6, writeFile as writeFile5 } from "node:fs/promises";
27020
- import { join as join14 } from "node:path";
27021
26864
  var fields = ["reasons", "paths", "message", "authorization", "requirements", "policyFiles", "expected"];
27022
26865
  var integration = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"];
27023
26866
  var same2 = (a, b) => JSON.stringify(a) === JSON.stringify(b);
@@ -27056,7 +26899,7 @@ async function specCommit(cwd, input2, dryRun) {
27056
26899
  ...stdin ? { input: stdin } : {}
27057
26900
  });
27058
26901
  const staged = async (index) => (await git(["diff", "--cached", "--ita-visible-in-index", "--name-only", "--no-renames", "-z"], index)).toString("utf8").split("\0").filter(Boolean).sort();
27059
- const busy = join14(gitDir, "gitifact-spec-commit.lock");
26902
+ const busy = join13(gitDir, "gitifact-spec-commit.lock");
27060
26903
  await failOnLegacyLock(gitDir);
27061
26904
  if (await info5(busy)) fail6(t2("commit.busy", { path: busy }));
27062
26905
  if ((await staged()).length) fail6(t2("commit.existingStaging"));
@@ -27067,7 +26910,7 @@ async function specCommit(cwd, input2, dryRun) {
27067
26910
  const prepared = prepareSpecPreview(c.bundle, current.bundle, c.files, current.files, reasons, () => generatePreviewId("H"));
27068
26911
  const blobId = (text2) => {
27069
26912
  const bytes = Buffer.from(text2);
27070
- return createHash8(objectFormat).update(`blob ${bytes.length}\0`).update(bytes).digest("hex");
26913
+ return createHash7(objectFormat).update(`blob ${bytes.length}\0`).update(bytes).digest("hex");
27071
26914
  };
27072
26915
  const present = [...current.files.keys()];
27073
26916
  if (present.some((p) => p.includes("\n"))) fail6(t2("commit.newlinePath"));
@@ -27110,14 +26953,14 @@ async function specCommit(cwd, input2, dryRun) {
27110
26953
  ...prepared.changes.filter((c2) => c2.kind === "design").map((c2) => "Gitifact-Design: " + c2.id),
27111
26954
  ...prepared.changes.filter((c2) => c2.kind === "wiki").map((c2) => "Gitifact-Doc: " + c2.id)
27112
26955
  ];
27113
- const temporary = join14(gitDir, "gitifact-commit-index-" + randomUUID7());
26956
+ const temporary = join13(gitDir, "gitifact-commit-index-" + randomUUID6());
27114
26957
  let owned = false;
27115
26958
  let uncertain = false;
27116
26959
  let indexLock;
27117
26960
  let committed;
27118
26961
  try {
27119
26962
  try {
27120
- await mkdir7(busy);
26963
+ await mkdir6(busy);
27121
26964
  owned = true;
27122
26965
  } catch (e) {
27123
26966
  if (e.code === "EEXIST") fail6(t2("commit.busy", { path: busy }));
@@ -27126,13 +26969,13 @@ async function specCommit(cwd, input2, dryRun) {
27126
26969
  await previewTransaction(cwd, current.stamp, async () => ({ writes, data: {}, recheck: c.recheck }), rename4, async (published) => {
27127
26970
  let commitStarted = false;
27128
26971
  try {
27129
- const lock = indexLock = await open5(indexPath + ".lock", "wx", 384);
26972
+ const lock = indexLock = await open4(indexPath + ".lock", "wx", 384);
27130
26973
  const original = await optional2(indexPath);
27131
26974
  if (hash2(original ?? Buffer.alloc(0)) !== indexHash || (await staged()).length) fail6(t2("commit.indexChanged"));
27132
26975
  const locked = await hashes([.../* @__PURE__ */ new Set([...selected, ...contextPaths])]);
27133
26976
  for (const [path3, value] of started) if (locked.get(path3) !== value) fail6(t2("commit.fileChangedRunning", { path: path3 }));
27134
- await writeFile5(join14(busy, "recovery.json"), JSON.stringify({ before: c.base, originalIndex: original?.toString("base64") ?? null, temporary, paths: selected, message, requirements }));
27135
- if (original) await writeFile5(temporary, original, { flag: "wx" });
26977
+ await writeFile4(join13(busy, "recovery.json"), JSON.stringify({ before: c.base, originalIndex: original?.toString("base64") ?? null, temporary, paths: selected, message, requirements }));
26978
+ if (original) await writeFile4(temporary, original, { flag: "wx" });
27136
26979
  else await git(["read-tree", "--empty"], temporary);
27137
26980
  await git(["add", "--", ...stageable], temporary);
27138
26981
  const actual = await staged(temporary);
@@ -27147,7 +26990,7 @@ async function specCommit(cwd, input2, dryRun) {
27147
26990
  const size = Number(header[2]);
27148
26991
  if (end < 0 || header[1] !== "blob" || !Number.isSafeInteger(size) || output2[end + 1 + size] !== 10) fail6(t2("commit.stagedUnreadable", { path: path3 }));
27149
26992
  const staged2 = output2.subarray(end + 1, end + 1 + size);
27150
- const file2 = await readFile11(join14(root, path3));
26993
+ const file2 = await readFile10(join13(root, path3));
27151
26994
  if (!staged2.equals(file2) && !staged2.equals(Buffer.from(file2.toString("latin1").replace(/\r\n/g, "\n"), "latin1"))) fail6(t2("commit.filterChanged"));
27152
26995
  offset = end + size + 2;
27153
26996
  }
@@ -27155,7 +26998,7 @@ async function specCommit(cwd, input2, dryRun) {
27155
26998
  const again = await hashes([...locked.keys()]);
27156
26999
  for (const [path3, value] of locked) if (again.get(path3) !== value) fail6(t2("commit.fileChangedPreparing", { path: path3 }));
27157
27000
  if ((await readLockedPreviewState(root)).stamp !== published.stamp) fail6(t2("commit.specsChangedPreparing"));
27158
- for (const name of integration) if (await info5(join14(gitDir, name))) fail6(t2("commit.integrationStarted"));
27001
+ for (const name of integration) if (await info5(join13(gitDir, name))) fail6(t2("commit.integrationStarted"));
27159
27002
  if (!same2(c.base, await c.reader.baseline())) fail6(t2("commit.headChanged"));
27160
27003
  const tree = (await git(["write-tree"], temporary)).toString("utf8").trim();
27161
27004
  commitStarted = true;
@@ -27170,7 +27013,7 @@ async function specCommit(cwd, input2, dryRun) {
27170
27013
  if (headers[0] !== "tree " + tree || after.branch !== c.base.branch || !same2(parents, c.base.head ? [c.base.head] : []) || trailers.some((t3) => !body.split(/\r?\n/).includes(t3))) fail6(t2("commit.resultAltered"));
27171
27014
  if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== indexHash) fail6(t2("commit.indexChangedAfter"));
27172
27015
  if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6(t2("commit.hookChangedStaging"));
27173
- await lock.writeFile(await readFile11(temporary));
27016
+ await lock.writeFile(await readFile10(temporary));
27174
27017
  await lock.sync();
27175
27018
  await lock.close();
27176
27019
  await rename4(indexPath + ".lock", indexPath);
@@ -27192,14 +27035,14 @@ async function specCommit(cwd, input2, dryRun) {
27192
27035
  await indexLock?.close().catch(() => {
27193
27036
  });
27194
27037
  if (!uncertain) {
27195
- if (indexLock) await unlink6(indexPath + ".lock").catch(() => {
27038
+ if (indexLock) await unlink5(indexPath + ".lock").catch(() => {
27196
27039
  });
27197
- await unlink6(temporary).catch(() => {
27040
+ await unlink5(temporary).catch(() => {
27198
27041
  });
27199
27042
  if (owned) {
27200
- await unlink6(join14(busy, "recovery.json")).catch(() => {
27043
+ await unlink5(join13(busy, "recovery.json")).catch(() => {
27201
27044
  });
27202
- await rmdir3(busy);
27045
+ await rmdir2(busy);
27203
27046
  }
27204
27047
  }
27205
27048
  }
@@ -27214,14 +27057,14 @@ async function execute(action, options, controls) {
27214
27057
  try {
27215
27058
  const guard = specPreviewReader(process.cwd());
27216
27059
  const { root, gitDir, objectFormat } = await guard.location();
27217
- for (const marker2 of operations) if (await fileInfo(join15(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
27060
+ for (const marker2 of operations) if (await fileInfo(join14(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
27218
27061
  if (await guard.hasUnmerged()) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
27219
27062
  const raw = await readConfigFile(root);
27220
27063
  if (raw === void 0) throw new SpecPreviewError(t2("preview.notInitialized"));
27221
27064
  const config2 = parseManagedConfig(raw);
27222
27065
  if (!("schemaVersion" in config2)) throw new SpecPreviewError(t2("preview.legacyProject"));
27223
27066
  await initRepository(root).validateBaseline(config2, root, "HEAD", objectFormat);
27224
- if (["working", "save", "changes", "prepare", "verify", "commit-plan", "commit-apply", "commit"].includes(action)) {
27067
+ if (["working", "save", "changes", "commit"].includes(action)) {
27225
27068
  let result;
27226
27069
  const inputs = () => prepareAgentInputs(root, controls).catch(() => void 0);
27227
27070
  if (action === "working") result = narrowWorking(await readWorkingPreview(process.cwd()), options, await inputs());
@@ -27235,7 +27078,7 @@ async function execute(action, options, controls) {
27235
27078
  } catch {
27236
27079
  throw new SpecPreviewError(t2("preview.inputJson"));
27237
27080
  }
27238
- result = action === "commit" ? await specCommit(process.cwd(), input2, !!options.dryRun) : action === "commit-plan" || action === "commit-apply" ? await previewCommit(process.cwd(), action === "commit-plan" ? "plan" : "apply", input2) : action === "prepare" ? await prepareWorkingPreview(process.cwd(), input2) : action === "verify" ? await verifyPreparedPreview(process.cwd(), input2, !!options.staged) : await saveWorkingPreview(process.cwd(), input2);
27081
+ result = action === "commit" ? await specCommit(process.cwd(), input2, !!options.dryRun) : await saveWorkingPreview(process.cwd(), input2);
27239
27082
  const consumed = action === "save" || action === "commit" && result.outcome === "committed";
27240
27083
  if (consumed && options.file !== "-") result = { ...result, inputRemoved: await discardAgentInput(root, options.file, controls) };
27241
27084
  }
@@ -27261,7 +27104,7 @@ async function execute(action, options, controls) {
27261
27104
  async function readInputFile(path3) {
27262
27105
  const source2 = await stat2(path3);
27263
27106
  if (!source2.isFile() || source2.size > 1024 * 1024) throw new SpecPreviewError(t2("preview.inputFile"));
27264
- return readFile12(path3);
27107
+ return readFile11(path3);
27265
27108
  }
27266
27109
  async function readStdin(stream) {
27267
27110
  const chunks = [];
@@ -27293,11 +27136,11 @@ function narrowWorking(working, options, inputs) {
27293
27136
  }
27294
27137
 
27295
27138
  // src/commands/migrate.ts
27296
- import { lstat as lstat10, readdir as readdir6, readFile as readFile13, rename as rename5, writeFile as writeFile6, unlink as unlink7 } from "node:fs/promises";
27297
- import { join as join16 } from "node:path";
27139
+ import { lstat as lstat9, readdir as readdir6, readFile as readFile12, rename as rename5, writeFile as writeFile5, unlink as unlink6 } from "node:fs/promises";
27140
+ import { join as join15 } from "node:path";
27298
27141
  import { randomBytes as randomBytes3 } from "node:crypto";
27299
27142
  var operations2 = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply", "sequencer", "BISECT_START", "index.lock"];
27300
- var info6 = (path3) => lstat10(path3).catch((e) => {
27143
+ var info6 = (path3) => lstat9(path3).catch((e) => {
27301
27144
  if (e.code === "ENOENT") return void 0;
27302
27145
  throw e;
27303
27146
  });
@@ -27308,18 +27151,18 @@ var fail7 = (code, message) => {
27308
27151
  async function migrateStore(cwd, dryRun = false) {
27309
27152
  const reader = specPreviewReader(cwd);
27310
27153
  const { root, gitDir } = await reader.location();
27311
- for (const marker3 of operations2) if (await info6(join16(gitDir, marker3))) fail7("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker3 }));
27154
+ for (const marker3 of operations2) if (await info6(join15(gitDir, marker3))) fail7("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker3 }));
27312
27155
  if (await reader.hasUnmerged()) fail7("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
27313
- for (const name of [...LEGACY_LOCKS, "gitifact-spec-preview.lock", "gitifact-spec-commit.lock"]) if (await info6(join16(gitDir, name))) fail7("LOCKED", t2("migrate.locked", { path: join16(gitDir, name) }));
27314
- const from = join16(root, ".tryce");
27315
- const to = join16(root, ".gitifact");
27156
+ for (const name of [...LEGACY_LOCKS, "gitifact-spec-preview.lock", "gitifact-spec-commit.lock"]) if (await info6(join15(gitDir, name))) fail7("LOCKED", t2("migrate.locked", { path: join15(gitDir, name) }));
27157
+ const from = join15(root, ".tryce");
27158
+ const to = join15(root, ".gitifact");
27316
27159
  const fromInfo = await info6(from);
27317
27160
  if (await info6(to)) fail7("ALREADY_MIGRATED", t2("migrate.alreadyMigrated"));
27318
27161
  if (!fromInfo) return fail7("NOTHING_TO_MIGRATE", t2("migrate.nothingToMigrate"));
27319
27162
  if (!fromInfo.isDirectory() || fromInfo.isSymbolicLink()) fail7("PATH_CONFLICT", t2("migrate.notDirectory"));
27320
- const configInfo = await info6(join16(from, "config.json"));
27163
+ const configInfo = await info6(join15(from, "config.json"));
27321
27164
  if (!configInfo?.isFile() || configInfo.isSymbolicLink()) fail7("NOT_INITIALIZED", t2("migrate.noConfig"));
27322
- const config2 = parseManagedConfig(decode4(await readFile13(join16(from, "config.json"))));
27165
+ const config2 = parseManagedConfig(decode4(await readFile12(join15(from, "config.json"))));
27323
27166
  if (!("schemaVersion" in config2)) fail7("UNSUPPORTED_FORMAT", t2("migrate.legacyJson"));
27324
27167
  const top = (await readdir6(from)).sort();
27325
27168
  if (top.some((name) => name !== "config.json" && name !== "spec")) fail7("UNSUPPORTED_FORMAT", t2("migrate.extraEntries"));
@@ -27328,20 +27171,20 @@ async function migrateStore(cwd, dryRun = false) {
27328
27171
  const legacyRecords = [];
27329
27172
  const marker2 = /^<!-- tryce-(spec|req|design|ref): /;
27330
27173
  if (top.includes("spec")) {
27331
- for (const feature2 of (await readdir6(join16(from, "spec"))).sort()) {
27332
- const dir = join16(from, "spec", feature2);
27174
+ for (const feature2 of (await readdir6(join15(from, "spec"))).sort()) {
27175
+ const dir = join15(from, "spec", feature2);
27333
27176
  const stat3 = await info6(dir);
27334
27177
  if (!stat3?.isDirectory() || stat3.isSymbolicLink()) fail7("UNSUPPORTED_FORMAT", t2("migrate.notSpecFolder", { feature: feature2 }));
27335
27178
  for (const name of (await readdir6(dir)).sort()) {
27336
27179
  if (!["requirements.md", "design.md", "history.jsonl", "tryce.json"].includes(name)) fail7("UNSUPPORTED_FORMAT", t2("migrate.unsupportedFile", { feature: feature2, name }));
27337
- const fileStat = await info6(join16(dir, name));
27180
+ const fileStat = await info6(join15(dir, name));
27338
27181
  if (!fileStat?.isFile() || fileStat.isSymbolicLink() || fileStat.nlink !== 1 || fileStat.size > 1024 * 1024) fail7("UNSUPPORTED_FORMAT", t2("migrate.fileTooLarge", { name }));
27339
27182
  const newPath = `.gitifact/spec/${feature2}/${name}`;
27340
27183
  if (name === "tryce.json") {
27341
27184
  legacyRecords.push(newPath);
27342
27185
  continue;
27343
27186
  }
27344
- const text2 = decode4(await readFile13(join16(dir, name)));
27187
+ const text2 = decode4(await readFile12(join15(dir, name)));
27345
27188
  if (name === "history.jsonl") {
27346
27189
  files.set(newPath, text2);
27347
27190
  continue;
@@ -27352,9 +27195,9 @@ async function migrateStore(cwd, dryRun = false) {
27352
27195
  if (new RegExp(`^ {0,3}${fence.char}{${fence.size},}\\s*$`).test(line)) fence = void 0;
27353
27196
  return line;
27354
27197
  }
27355
- const open6 = /^ {0,3}(`{3,}|~{3,})/.exec(line);
27356
- if (open6) {
27357
- fence = { char: open6[1][0], size: open6[1].length };
27198
+ const open5 = /^ {0,3}(`{3,}|~{3,})/.exec(line);
27199
+ if (open5) {
27200
+ fence = { char: open5[1][0], size: open5[1].length };
27358
27201
  return line;
27359
27202
  }
27360
27203
  return marker2.test(line) ? line.replace(/^<!-- tryce-/, "<!-- gitifact-") : line;
@@ -27386,13 +27229,13 @@ async function migrateStore(cwd, dryRun = false) {
27386
27229
  if (dryRun) return result("planned");
27387
27230
  await rename5(from, to);
27388
27231
  for (const r of rewrites) {
27389
- const full = join16(root, r.path);
27390
- const temp = join16(root, ".gitifact", "spec", ".gitifact-migrate-" + randomBytes3(8).toString("hex"));
27391
- await writeFile6(temp, r.content, { flag: "wx" });
27232
+ const full = join15(root, r.path);
27233
+ const temp = join15(root, ".gitifact", "spec", ".gitifact-migrate-" + randomBytes3(8).toString("hex"));
27234
+ await writeFile5(temp, r.content, { flag: "wx" });
27392
27235
  try {
27393
27236
  await rename5(temp, full);
27394
27237
  } finally {
27395
- await unlink7(temp).catch(() => {
27238
+ await unlink6(temp).catch(() => {
27396
27239
  });
27397
27240
  }
27398
27241
  }
@@ -27410,24 +27253,20 @@ async function runMigrate(options) {
27410
27253
  }
27411
27254
 
27412
27255
  // src/main.ts
27413
- var program2 = new Command().name("gitifact").description(t2("help.program")).version("0.5.0").allowExcessArguments(false).addHelpText("after", "\n" + t2("help.notYet")).action(() => program2.outputHelp());
27256
+ var program2 = new Command().name("gitifact").description(t2("help.program")).version("0.6.0").allowExcessArguments(false).addHelpText("after", "\n" + t2("help.notYet")).action(() => program2.outputHelp());
27414
27257
  program2.command("status").description(t2("help.status")).allowExcessArguments(false).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).action(async (options) => {
27415
27258
  await runStatus(options.format);
27416
27259
  });
27417
- program2.command("browser").description(t2("help.browser")).allowExcessArguments(false).option("--port <port>", t2("help.browserPort"), parsePort, 0).option("--dev", t2("help.browserDev")).option("--no-update-check", t2("help.browserNoUpdateCheck")).action((options) => runBrowser(options, "0.5.0"));
27418
- program2.command("init").description(t2("help.init")).allowExcessArguments(false).option("--dry-run", t2("help.initDryRun")).addOption(new Option("--agent <agent>", t2("help.initAgent")).choices([...agentPresetNames])).addOption(new Option("--remove-agents", t2("help.initRemoveAgents")).conflicts("skipAgents")).option("--skip-agents", t2("help.initSkipAgents")).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).action((options) => runInit(options, "0.5.0"));
27260
+ program2.command("browser").description(t2("help.browser")).allowExcessArguments(false).option("--port <port>", t2("help.browserPort"), parsePort, 0).option("--dev", t2("help.browserDev")).option("--no-update-check", t2("help.browserNoUpdateCheck")).action((options) => runBrowser(options, "0.6.0"));
27261
+ program2.command("init").description(t2("help.init")).allowExcessArguments(false).option("--dry-run", t2("help.initDryRun")).addOption(new Option("--agent <agent>", t2("help.initAgent")).choices([...agentPresetNames])).addOption(new Option("--remove-agents", t2("help.initRemoveAgents")).conflicts("skipAgents")).option("--skip-agents", t2("help.initSkipAgents")).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).action((options) => runInit(options, "0.6.0"));
27419
27262
  program2.command("docs").description(t2("help.docs")).argument("[topic]", t2("help.docsTopic")).allowExcessArguments(false).action(async (topic) => {
27420
27263
  await runDocs(topic);
27421
27264
  });
27422
- program2.command("update").description(t2("help.update")).allowExcessArguments(false).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).option("--commit", t2("help.updateCommit")).action((options) => runUpdate(options, "0.5.0"));
27265
+ program2.command("update").description(t2("help.update")).allowExcessArguments(false).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).option("--commit", t2("help.updateCommit")).action((options) => runUpdate(options, "0.6.0"));
27423
27266
  program2.command("migrate").description(t2("help.migrate")).allowExcessArguments(false).option("--dry-run", t2("help.migrateDryRun")).action(runMigrate);
27424
27267
  var spec = program2.command("spec").description(t2("help.spec"));
27425
- var replaced = t2("help.deprecated");
27426
27268
  spec.command("commit").description(t2("help.specCommit")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specCommitFile")).option("--dry-run", t2("help.specCommitDryRun")).action((o) => runSpecPreview("commit", o));
27427
- for (const action of ["commit-plan", "commit-apply"]) spec.command(action).description(replaced).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specCommitPlanFile")).action((o) => runSpecPreview(action, o));
27428
27269
  spec.command("changes").description(t2("help.specChanges")).allowExcessArguments(false).action((o) => runSpecPreview("changes", o));
27429
- spec.command("prepare").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specPrepareFile")).action((o) => runSpecPreview("prepare", o));
27430
- spec.command("verify").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specVerifyFile")).option("--staged", t2("help.specVerifyStaged")).action((o) => runSpecPreview("verify", o));
27431
27270
  spec.command("working").description(t2("help.specWorking")).allowExcessArguments(false).addOption(new Option("--stamp", t2("help.specWorkingStamp")).conflicts(["feature", "ids"])).option("--feature <name>", t2("help.specWorkingFeature")).option("--ids", t2("help.specWorkingIds")).action((o) => runSpecPreview("working", o));
27432
27271
  spec.command("save").description(t2("help.specSave")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specSaveFile")).action((o) => runSpecPreview("save", o));
27433
27272
  spec.command("read").description(t2("help.specRead")).allowExcessArguments(false).option("--ref <commit>", t2("help.specReadRef"), "HEAD").action((o) => runSpecPreview("read", o));