gitifact 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/browser/assets/BottomSheet-CUR7U0gF.js +1 -0
- package/dist/browser/assets/IconButton-BqlnBu_N.js +4 -0
- package/dist/browser/assets/Markdown-C8BT0YZz.js +68 -0
- package/dist/browser/assets/{MenuBottomSheet-BKiLm4Gk.js → MenuBottomSheet-BkRC4_VW.js} +1 -1
- package/dist/browser/assets/ProgressBarMarkTooltip-BVcVKVq9.js +1 -0
- package/dist/browser/assets/Section-DQRr6JoK.js +1 -0
- package/dist/browser/assets/TimestampHoverCard-ClDQXGeS.js +1 -0
- package/dist/browser/assets/{Tooltip-CH5OxdmX.js → Tooltip-a2AGdnkC.js} +1 -1
- package/dist/browser/assets/about-DMFBT-sA.js +3 -0
- package/dist/browser/assets/about-Df__2EC8.css +1 -0
- package/dist/browser/assets/{contributors._email-BMqQlPdF.js → contributors._email-bq12TRAr.js} +1 -1
- package/dist/browser/assets/contributors.index-eTu4P306.js +1 -0
- package/dist/browser/assets/{features._featureId-zHnvA0Go.js → features._featureId-CGRWLMyZ.js} +1 -1
- package/dist/browser/assets/features.index-_wXeEia1.js +1 -0
- package/dist/browser/assets/git-CTULSVR7.js +1 -0
- package/dist/browser/assets/git-DF8OMSPX.css +1 -0
- package/dist/browser/assets/gitifact-logo-DPewkDQ4.svg +5 -0
- package/dist/browser/assets/{guides._documentId-jvtVZl4b.js → guides._documentId-D3RCTjtd.js} +1 -1
- package/dist/browser/assets/guides.index-CFMN9ggJ.js +1 -0
- package/dist/browser/assets/index-Cl1J8uRf.js +56 -0
- package/dist/browser/assets/page-header-CYf1yQV1.js +127 -0
- package/dist/browser/assets/product-BxZktNQM.js +8 -0
- package/dist/browser/assets/product-CV4EzacY.css +1 -0
- package/dist/browser/assets/product.index-AF24IXK3.js +1 -0
- package/dist/browser/assets/request-state-DzkYXwJR.js +1 -0
- package/dist/browser/assets/requirements-DpTMK_Uu.js +1 -0
- package/dist/browser/assets/routes-jgWFqeRv.js +1 -0
- package/dist/browser/assets/themeProps-MQSlTycI.js +1 -0
- package/dist/browser/assets/{useClipboard-D2fN4Nhs.js → useClipboard-B8Or2k0a.js} +1 -1
- package/dist/browser/assets/useDevWarning-CzR6rkf6.js +1 -0
- package/dist/browser/assets/useIsomorphicLayoutEffect-f8dYmyS2.js +1 -0
- package/dist/browser/assets/useMediaQuery-C_nG4b-e.js +1 -0
- package/dist/browser/assets/{useScrollLock-0d-ttB5Z.js → useScrollLock-CrQ0xkil.js} +1 -1
- package/dist/browser/index.html +15 -17
- package/dist/i18n/ko/block.md +30 -0
- package/dist/i18n/ko/changelog.md +41 -0
- package/dist/main.js +860 -524
- package/package.json +1 -1
- package/dist/browser/assets/BottomSheet-DFEd7qcJ.js +0 -1
- package/dist/browser/assets/IconButton-DQKowV1I.js +0 -3
- package/dist/browser/assets/Section-CXNZYeQ6.js +0 -1
- package/dist/browser/assets/Text-LX6541eF.js +0 -2
- package/dist/browser/assets/TimestampHoverCard-CEVz4ZE2.js +0 -1
- package/dist/browser/assets/about-Dbyd48t6.js +0 -1
- package/dist/browser/assets/contributors.index-Dk42HR-l.js +0 -1
- package/dist/browser/assets/features.index-xgyvTm5d.js +0 -1
- package/dist/browser/assets/git-D8SQ9LAI.js +0 -1
- package/dist/browser/assets/git-nj7fScNQ.css +0 -1
- package/dist/browser/assets/guides.index-DKNn9kCJ.js +0 -1
- package/dist/browser/assets/ime-u5HljzMu.js +0 -1
- package/dist/browser/assets/index-Cul6rpdA.js +0 -56
- package/dist/browser/assets/mergeProps-ptS-gIMz.js +0 -1
- package/dist/browser/assets/page-header-pnZFm0-7.js +0 -56
- package/dist/browser/assets/product-B_C25r7E.js +0 -75
- package/dist/browser/assets/product-DIl1IXZo.css +0 -1
- package/dist/browser/assets/product.index-IBLtgiMT.js +0 -1
- package/dist/browser/assets/request-state-q7VzEh1O.js +0 -3
- package/dist/browser/assets/requirements-BmW8BEdu.js +0 -1
- package/dist/browser/assets/routes-BDsb61_V.js +0 -1
- package/dist/browser/assets/themeProps-BV289t6M.js +0 -1
- package/dist/browser/assets/useDevWarning-CHuvA0bI.js +0 -1
- package/dist/browser/assets/useIsomorphicLayoutEffect-DPqcigQ0.js +0 -1
- package/dist/browser/assets/useMediaQuery-Bkz-2VBC.js +0 -1
- /package/dist/{docs → i18n/ko/docs}/commit.md +0 -0
- /package/dist/{docs → i18n/ko/docs}/design.md +0 -0
- /package/dist/{docs → i18n/ko/docs}/product.md +0 -0
- /package/dist/{docs → i18n/ko/docs}/spec.md +0 -0
- /package/dist/{docs → i18n/ko/docs}/workflow.md +0 -0
package/dist/main.js
CHANGED
|
@@ -488,9 +488,9 @@ var Help = class {
|
|
|
488
488
|
* @param {Help} helper
|
|
489
489
|
* @returns string[]
|
|
490
490
|
*/
|
|
491
|
-
formatItemList(heading,
|
|
492
|
-
if (
|
|
493
|
-
return [helper.styleTitle(heading), ...
|
|
491
|
+
formatItemList(heading, items2, helper) {
|
|
492
|
+
if (items2.length === 0) return [];
|
|
493
|
+
return [helper.styleTitle(heading), ...items2, ""];
|
|
494
494
|
}
|
|
495
495
|
/**
|
|
496
496
|
* Group items by their help group heading.
|
|
@@ -3398,23 +3398,129 @@ function summarizeChanges(changes) {
|
|
|
3398
3398
|
return result;
|
|
3399
3399
|
}
|
|
3400
3400
|
|
|
3401
|
-
// ../../packages/core/dist/
|
|
3402
|
-
var
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3401
|
+
// ../../packages/core/dist/shared/i18n/ko/messages.json
|
|
3402
|
+
var messages_default = {
|
|
3403
|
+
"config.jsonUnreadable": "\uC124\uC815 JSON\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uBB38\uC744 \uBCF4\uC874\uD558\uC138\uC694.",
|
|
3404
|
+
"config.unsupportedFormat": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD504\uB85C\uC81D\uD2B8 \uD615\uC2DD\uC785\uB2C8\uB2E4. \uD638\uD658 CLI\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
3405
|
+
"config.invalidFields": "\uD504\uB85C\uC81D\uD2B8 \uC124\uC815\uC758 \uD544\uB4DC\uB098 \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
3406
|
+
"config.jsonUnreadableShort": "\uC124\uC815 JSON\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3407
|
+
"config.schemaFields": "schemaVersion\uACFC baseline \uC124\uC815 \uD544\uB4DC\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
3408
|
+
"document.pathTooLong": "\uBB38\uC11C \uACBD\uB85C \uAE4A\uC774 \uB610\uB294 \uAE38\uC774 \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4: {path}",
|
|
3409
|
+
"document.fileName": "\uBB38\uC11C \uD30C\uC77C \uC774\uB984\uC740 \uC18C\uBB38\uC790\xB7\uC22B\uC790\xB7\uD558\uC774\uD508\uACFC .md\uC5EC\uC57C \uD569\uB2C8\uB2E4: {path}",
|
|
3410
|
+
"document.folderName": "\uBB38\uC11C \uD3F4\uB354 \uC774\uB984\uC740 \uC18C\uBB38\uC790\xB7\uC22B\uC790\xB7\uD558\uC774\uD508\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: {path}",
|
|
3411
|
+
"design.invalidCharacters": "\uC798\uBABB\uB41C \uC124\uACC4 \uBB38\uC790\uC785\uB2C8\uB2E4.",
|
|
3412
|
+
"design.idMismatch": "\uC124\uACC4\uC758 gitifact-design ID\uB294 \uAC19\uC740 \uAE30\uB2A5\uC758 S-ID\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
3413
|
+
"design.titleRequired": "\uC124\uACC4 \uC81C\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
3414
|
+
"design.bodyRequired": "\uC124\uACC4 \uBCF8\uBB38\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
3415
|
+
"design.singleTopHeading": "\uC124\uACC4 \uCD5C\uC0C1\uC704 \uC81C\uBAA9\uC740 \uD558\uB098\uB9CC \uC501\uB2C8\uB2E4.",
|
|
3416
|
+
"design.referenceFormat": "\uC124\uACC4\uC758 \uCC38\uC870 \uC8FC\uC11D \uD615\uC2DD\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
3417
|
+
"design.unclosedFence": "\uC124\uACC4 \uCF54\uB4DC \uBE14\uB85D\uC774 \uB2EB\uD788\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.",
|
|
3418
|
+
"document.unsupportedPath": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBB38\uC11C \uACBD\uB85C: {path}",
|
|
3419
|
+
"document.productOnly": "\uC81C\uD488 \uD3F4\uB354\uC5D0\uB294 PRODUCT.md \uD558\uB098\uB9CC \uB461\uB2C8\uB2E4: {path}",
|
|
3420
|
+
"document.invalidCharacters": "\uC798\uBABB\uB41C \uBB38\uC11C \uBB38\uC790: {path}",
|
|
3421
|
+
"document.idRequired": "\uCCAB \uC904\uC5D0 \uC720\uD6A8\uD55C gitifact-{kind} \uC8FC\uC11D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: {path}",
|
|
3422
|
+
"document.titleRequired": "\uBB38\uC11C \uC81C\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: {path}",
|
|
3423
|
+
"document.bodyRequired": "\uBB38\uC11C \uBCF8\uBB38\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: {path}",
|
|
3424
|
+
"document.singleTopHeading": "\uBB38\uC11C \uCD5C\uC0C1\uC704 \uC81C\uBAA9\uC740 \uD558\uB098\uB9CC \uC501\uB2C8\uB2E4: {path}",
|
|
3425
|
+
"document.noMarkerInBody": "\uBB38\uC11C \uBCF8\uBB38\uC5D0\uB294 gitifact \uC8FC\uC11D\uC744 \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {path}",
|
|
3426
|
+
"document.unclosedFence": "\uBB38\uC11C \uCF54\uB4DC \uBE14\uB85D\uC774 \uB2EB\uD788\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: {path}",
|
|
3427
|
+
"document.kindSet": "\uBB38\uC11C \uC885\uB958 \uC9D1\uD569\uC774 \uC798\uBABB\uB410\uC2B5\uB2C8\uB2E4.",
|
|
3428
|
+
"document.kindMismatch": "\uBB38\uC11C \uC885\uB958\uAC00 \uD3F4\uB354\uC640 \uB2E4\uB985\uB2C8\uB2E4: {path}",
|
|
3429
|
+
"document.duplicateId": "\uC800\uC7A5\uC18C \uB0B4 \uC911\uBCF5 \uBB38\uC11C ID: {id}",
|
|
3430
|
+
"document.caseOnlyPath": "\uB300\uC18C\uBB38\uC790\uB9CC \uB2E4\uB978 \uBB38\uC11C \uACBD\uB85C: {path}",
|
|
3431
|
+
"history.duplicateId": "\uC800\uC7A5\uC18C \uB0B4 \uC911\uBCF5 \uBCF4\uC870 \uAE30\uB85D ID: {id}",
|
|
3432
|
+
"spec.orphanFile": "\uC694\uAD6C\uC0AC\uD56D \uBB38\uC11C \uC5C6\uB294 \uC124\uACC4 \uB610\uB294 \uC774\uC720 \uD30C\uC77C: {path}",
|
|
3433
|
+
"spec.unsupportedPath": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBA85\uC138 \uACBD\uB85C: {path}",
|
|
3434
|
+
"spec.invalidCharacters": "\uC798\uBABB\uB41C \uBA85\uC138 \uBB38\uC790: {path}",
|
|
3435
|
+
"spec.idRequired": "\uCCAB \uC904\uC5D0 \uC720\uD6A8\uD55C gitifact-spec \uC8FC\uC11D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: {path}",
|
|
3436
|
+
"spec.requirementIdRequired": "\uC694\uAD6C\uC0AC\uD56D \uC81C\uBAA9 \uBC14\uB85C \uC544\uB798\uC5D0 \uC720\uD6A8\uD55C ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4: {path}",
|
|
3437
|
+
"spec.invalidFence": "\uC798\uBABB\uB41C \uCF54\uB4DC \uBE14\uB85D\uC785\uB2C8\uB2E4.",
|
|
3438
|
+
"spec.titleOnce": "\uBB38\uC11C \uC81C\uBAA9\uC740 \uCC98\uC74C\uC5D0 \uD55C \uBC88\uB9CC \uC501\uB2C8\uB2E4: {path}",
|
|
3439
|
+
"spec.emptyTitle": "\uBE48 \uBB38\uC11C \uC81C\uBAA9\uC785\uB2C8\uB2E4.",
|
|
3440
|
+
"spec.titleMissing": "\uBB38\uC11C \uC81C\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: {path}",
|
|
3441
|
+
"spec.emptyRequirementTitle": "\uBE48 \uC694\uAD6C\uC0AC\uD56D \uC81C\uBAA9\uC785\uB2C8\uB2E4.",
|
|
3442
|
+
"spec.commentPosition": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 HTML \uC8FC\uC11D \uC704\uCE58: {path}",
|
|
3443
|
+
"spec.atxOnly": "\uAC80\uD1A0 \uBB38\uBC95\uC740 \uC5F4 1\uC758 ATX \uC81C\uBAA9\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4: {path}",
|
|
3444
|
+
"spec.incomplete": "\uBBF8\uC644\uC131 \uBA85\uC138\uC785\uB2C8\uB2E4: {path}",
|
|
3445
|
+
"spec.emptyOrDuplicateRequirement": "\uBE48 \uBCF8\uBB38 \uB610\uB294 \uC911\uBCF5 \uC694\uAD6C\uC0AC\uD56D ID: {id}",
|
|
3446
|
+
"history.invalidJsonl": "\uBCF4\uC870 \uAE30\uB85D JSONL\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3447
|
+
"history.invalidRecord": "\uC798\uBABB\uB41C \uBCF4\uC870 \uAE30\uB85D\uC785\uB2C8\uB2E4.",
|
|
3448
|
+
"history.invalidFields": "\uBCF4\uC870 \uAE30\uB85D\uC758 \uD544\uB4DC\xB7ID\xB7\uB300\uC0C1\uC774 \uC798\uBABB\uB410\uC2B5\uB2C8\uB2E4.",
|
|
3449
|
+
"spec.duplicateId": "\uC911\uBCF5 \uBA85\uC138 ID: {id}",
|
|
3450
|
+
"spec.duplicateRequirementId": "\uC800\uC7A5\uC18C \uB0B4 \uC911\uBCF5 \uC694\uAD6C\uC0AC\uD56D ID: {id}",
|
|
3451
|
+
"history.changed": "\uAE30\uC874 \uBCF4\uC870 \uAE30\uB85D\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {id}",
|
|
3452
|
+
"history.unlinkedRequirement": "\uC0C8 \uBCF4\uC870 \uAE30\uB85D\uC774 \uC774\uBC88 \uC694\uAD6C\uC0AC\uD56D \uBCC0\uACBD\uACFC \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {id}",
|
|
3453
|
+
"history.unlinkedDocument": "\uC0C8 \uBCF4\uC870 \uAE30\uB85D\uC774 \uC774\uBC88 \uBB38\uC11C \uBCC0\uACBD\uACFC \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {id}",
|
|
3454
|
+
"edit.invalidFeatureName": "\uC798\uBABB\uB41C \uAE30\uB2A5 \uD3F4\uB354 \uC774\uB984\uC785\uB2C8\uB2E4.",
|
|
3455
|
+
"edit.operationCount": "operations\uB294 1~100\uAC1C\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
3456
|
+
"edit.idGenerated": "ID \uC0DD\uC131 \uACB0\uACFC\uAC00 \uC798\uBABB\uB410\uC2B5\uB2C8\uB2E4.",
|
|
3457
|
+
"edit.idUnavailable": "\uACE0\uC720 ID\uB97C \uBC1C\uAE09\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3458
|
+
"edit.invalidOperation": "\uC798\uBABB\uB41C \uD3B8\uC9D1 \uC785\uB825\uC785\uB2C8\uB2E4.",
|
|
3459
|
+
"edit.unsupportedField": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD3B8\uC9D1 \uD544\uB4DC\uC785\uB2C8\uB2E4.",
|
|
3460
|
+
"edit.emptyField": "\uBE48 \uD3B8\uC9D1 \uD544\uB4DC: {field}",
|
|
3461
|
+
"edit.invalidCharacters": "\uC798\uBABB\uB41C \uD3B8\uC9D1 \uBB38\uC790: {field}",
|
|
3462
|
+
"edit.specNotFound": "\uB300\uC0C1 \uBA85\uC138\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4: {path}",
|
|
3463
|
+
"edit.noProductToDelete": "\uC0AD\uC81C\uD560 \uC81C\uD488 \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3464
|
+
"edit.samePath": "\uC774\uBBF8 \uAC19\uC740 \uACBD\uB85C\uC785\uB2C8\uB2E4.",
|
|
3465
|
+
"edit.documentPathExists": "\uC774\uBBF8 \uC874\uC7AC\uD558\uB294 \uBB38\uC11C \uACBD\uB85C\uC785\uB2C8\uB2E4: {path}",
|
|
3466
|
+
"edit.guideIdNotFound": "\uC9C0\uCE68 \uBB38\uC11C ID\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4: {id}",
|
|
3467
|
+
"edit.featureExists": "\uC774\uBBF8 \uC874\uC7AC\uD558\uB294 \uAE30\uB2A5\uC785\uB2C8\uB2E4.",
|
|
3468
|
+
"edit.noDesignToDelete": "\uC0AD\uC81C\uD560 \uC124\uACC4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3469
|
+
"edit.specIdNotFound": "\uBA85\uC138 ID\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3470
|
+
"edit.requirementIdNotFound": "\uC694\uAD6C\uC0AC\uD56D ID\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3471
|
+
"edit.sameSpec": "\uC774\uBBF8 \uAC19\uC740 \uBA85\uC138\uC5D0 \uC18D\uD569\uB2C8\uB2E4.",
|
|
3472
|
+
"edit.bodyChangesSpecStructure": "\uBCF8\uBB38\uC774 \uBA85\uC138 \uAD6C\uC870\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4.",
|
|
3473
|
+
"edit.bodyChangesDocumentStructure": "\uBCF8\uBB38\uC774 \uBB38\uC11C \uAD6C\uC870\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4: {path}",
|
|
3474
|
+
"reason.keepEmptySpec": "\uAE30\uC874 \uC774\uC720\uB97C \uBCF4\uC874\uD560 \uBE48 \uBA85\uC138\uB97C \uB0A8\uACA8\uC8FC\uC138\uC694: {id}",
|
|
3475
|
+
"reason.committedImmutable": "\uCEE4\uBC0B\uB41C \uC774\uC720\uC758 \uC218\uC815\xB7\uC0AD\uC81C\xB7\uC7AC\uBC30\uCE58\uB294 \uD5C8\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {id}",
|
|
3476
|
+
"reason.committedDocumentImmutable": "\uCEE4\uBC0B\uB41C \uBB38\uC11C \uC774\uC720\uC758 \uC218\uC815\xB7\uC0AD\uC81C\xB7\uC7AC\uBC30\uCE58\uB294 \uD5C8\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {kind}",
|
|
3477
|
+
"reason.count": "reasons\uB294 \uCD5C\uB300 100\uAC1C\uC758 \uBC30\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
3478
|
+
"reason.idGenerated": "\uC798\uBABB\uB41C \uC774\uC720 ID \uC0DD\uC131 \uACB0\uACFC\uC785\uB2C8\uB2E4.",
|
|
3479
|
+
"reason.idUnavailable": "\uACE0\uC720 \uC774\uC720 ID\uB97C \uBC1C\uAE09\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3480
|
+
"reason.invalidInput": "\uC798\uBABB\uB41C \uC774\uC720 \uC785\uB825\uC785\uB2C8\uB2E4.",
|
|
3481
|
+
"reason.targetsRequired": "\uC774\uC720\uC640 \uB300\uC0C1 \uC694\uAD6C\uC0AC\uD56D\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
3482
|
+
"reason.documentWithRequirements": "\uBB38\uC11C \uC774\uC720\uC5D0\uB294 \uC694\uAD6C\uC0AC\uD56D\uC744 \uD568\uAED8 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
3483
|
+
"reason.documentTargetInvalid": "\uBB38\uC11C \uC774\uC720 \uB300\uC0C1\uC774 \uC798\uBABB\uB410\uAC70\uB098 \uC911\uBCF5\uB429\uB2C8\uB2E4.",
|
|
3484
|
+
"reason.documentUnchanged": "\uCD5C\uC885 \uBCC0\uACBD\uC774 \uC5C6\uB294 \uBB38\uC11C\uC5D0 \uC774\uC720\uB97C \uBD99\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: {id}",
|
|
3485
|
+
"reason.singleDocumentKind": "\uD55C \uC774\uC720\uB294 \uD55C \uC885\uB958\uC758 \uBB38\uC11C\uB9CC \uB300\uC0C1\uC73C\uB85C \uD569\uB2C8\uB2E4.",
|
|
3486
|
+
"reason.invalidTarget": "\uC798\uBABB\uB41C \uC774\uC720 \uB300\uC0C1\uC785\uB2C8\uB2E4.",
|
|
3487
|
+
"reason.targetKind": "\uC774\uC720 \uB300\uC0C1 \uC885\uB958\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
3488
|
+
"reason.targetInvalid": "\uC774\uC720 \uB300\uC0C1\uC774 \uC798\uBABB\uB410\uAC70\uB098 \uC911\uBCF5\uB429\uB2C8\uB2E4.",
|
|
3489
|
+
"reason.requirementUnchanged": "\uCD5C\uC885 \uBCC0\uACBD\uC774 \uC5C6\uB294 \uC694\uAD6C\uC0AC\uD56D\uC5D0 \uC774\uC720\uB97C \uBD99\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: {id}",
|
|
3490
|
+
"reason.keepDeletedSpec": "\uC0AD\uC81C \uC774\uC720\uB97C \uAE30\uB85D\uD560 \uC6D0\uB798 \uBA85\uC138\uB97C \uB0A8\uACA8\uC8FC\uC138\uC694.",
|
|
3491
|
+
"readError.GIT_NOT_FOUND": "Git \uC2E4\uD589 \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3492
|
+
"readError.GIT_CONTEXT_OVERRIDE": "\uD604\uC7AC checkout\uACFC \uB2E4\uB978 Git \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uC9C0\uC815\uD558\uB294 \uD658\uACBD\uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
3493
|
+
"readError.NOT_A_REPOSITORY": "\uD604\uC7AC \uC704\uCE58\uAC00 Git \uC791\uC5C5 \uD3F4\uB354\uC5D0 \uC18D\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
3494
|
+
"readError.UNSUPPORTED_REPOSITORY": "bare \uC800\uC7A5\uC18C \uB610\uB294 Git \uAD00\uB9AC \uB514\uB809\uD130\uB9AC\uC5D0\uC11C\uB294 \uC870\uD68C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3495
|
+
"readError.GIT_UNSUPPORTED": "\uD544\uC694\uD55C Git \uC635\uC158 \uB610\uB294 object format\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
3496
|
+
"readError.GIT_FAILED": "Git \uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC800\uC7A5\uC18C \uC811\uADFC \uAD8C\uD55C\uACFC Git \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
3497
|
+
"readError.INVALID_GIT_OUTPUT": "Git \uC0C1\uD0DC \uCD9C\uB825\uC774 \uC9C0\uC6D0\uD558\uB294 \uD615\uC2DD\uACFC \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
3498
|
+
"readError.UNSUPPORTED_PATH_ENCODING": "Git \uACBD\uB85C\uB97C UTF-8\uB85C \uC190\uC2E4 \uC5C6\uC774 \uD45C\uD604\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3499
|
+
"readError.REPOSITORY_CHANGED": "\uC870\uD68C \uC911 \uC800\uC7A5\uC18C \uC0C1\uD0DC\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC870\uD68C\uD558\uC138\uC694.",
|
|
3500
|
+
"readError.READ_LIMIT_EXCEEDED": "Git \uC870\uD68C\uC758 \uC2DC\uAC04 \uB610\uB294 \uCD9C\uB825 \uD06C\uAE30 \uC81C\uD55C\uC744 \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
3501
|
+
"changelog.atLine": "\uD328\uCE58\uB178\uD2B8 {line}\uD589: {reason}",
|
|
3502
|
+
"changelog.emptyVersion": "{version} \uBC84\uC804\uC5D0 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3503
|
+
"changelog.invalidDate": "\uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uB0A0\uC9DC\uC785\uB2C8\uB2E4: {text}",
|
|
3504
|
+
"changelog.order": "\uBC84\uC804\uC740 \uCD5C\uC2E0\uC774 \uC55E\uC5D0 \uC624\uB3C4\uB85D \uB0B4\uB9BC\uCC28\uC21C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: {version}",
|
|
3505
|
+
"changelog.sectionBeforeVersion": "\uBC84\uC804 \uC81C\uBAA9\uBCF4\uB2E4 \uC808 \uC81C\uBAA9\uC774 \uBA3C\uC800 \uB098\uC654\uC2B5\uB2C8\uB2E4.",
|
|
3506
|
+
"changelog.duplicateSection": "\uAC19\uC740 \uBC84\uC804\uC5D0 {section} \uC808\uC774 \uB450 \uBC88 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
3507
|
+
"changelog.itemOutsideSection": "\uC808 \uC81C\uBAA9(### Added|Changed|Removed|Fixed) \uC544\uB798\uC5D0\uB9CC \uD56D\uBAA9\uC744 \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
3508
|
+
"changelog.unknownLine": '\uC778\uC2DD\uD560 \uC218 \uC5C6\uB294 \uC904\uC785\uB2C8\uB2E4. \uBC84\uC804\uC740 "## X.Y.Z - YYYY-MM-DD", \uC808\uC740 "### Added|Changed|Removed|Fixed", \uD56D\uBAA9\uC740 "- "\uB85C \uC501\uB2C8\uB2E4: {text}',
|
|
3509
|
+
"changelog.noVersions": "\uBC84\uC804\uC774 \uD558\uB098\uB3C4 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
3413
3510
|
};
|
|
3511
|
+
|
|
3512
|
+
// ../../packages/core/dist/shared/i18n/index.js
|
|
3513
|
+
var defaultLanguage = "ko";
|
|
3514
|
+
var catalogs = { ko: messages_default };
|
|
3515
|
+
function t(key, values = {}, lang = defaultLanguage) {
|
|
3516
|
+
return catalogs[lang][key].replace(/\{(\w+)\}/g, (whole, name) => name in values ? String(values[name]) : whole);
|
|
3517
|
+
}
|
|
3518
|
+
|
|
3519
|
+
// ../../packages/core/dist/domain/read-error.js
|
|
3414
3520
|
var RepositoryReadError = class extends Error {
|
|
3415
3521
|
code;
|
|
3416
3522
|
constructor(code) {
|
|
3417
|
-
super(
|
|
3523
|
+
super(t(`readError.${code}`));
|
|
3418
3524
|
this.name = "RepositoryReadError";
|
|
3419
3525
|
this.code = code;
|
|
3420
3526
|
}
|
|
@@ -3451,12 +3557,12 @@ function parseProjectConfig(text2) {
|
|
|
3451
3557
|
try {
|
|
3452
3558
|
value = JSON.parse(text2);
|
|
3453
3559
|
} catch {
|
|
3454
|
-
throw new InitError("INVALID_CONFIG", "
|
|
3560
|
+
throw new InitError("INVALID_CONFIG", t("config.jsonUnreadable"));
|
|
3455
3561
|
}
|
|
3456
3562
|
if (object(value) && value.kind === "tryce-project" && typeof value.format === "string" && !["init-1", "prototype-1", "workflow-1"].includes(value.format)) {
|
|
3457
|
-
throw new InitError("UNSUPPORTED_FORMAT", "
|
|
3563
|
+
throw new InitError("UNSUPPORTED_FORMAT", t("config.unsupportedFormat"));
|
|
3458
3564
|
}
|
|
3459
|
-
const invalid2 = () => new InitError("INVALID_CONFIG", "
|
|
3565
|
+
const invalid2 = () => new InitError("INVALID_CONFIG", t("config.invalidFields"));
|
|
3460
3566
|
if (!object(value) || !keys(value, ["kind", "format", "mode", "baseline"]) || value.kind !== "tryce-project" || !["init-1", "prototype-1", "workflow-1"].includes(String(value.format)) || typeof value.format !== "string" || typeof value.mode !== "string" || !(value.format === "workflow-1" ? ["auto", "approval"] : ["normal", "prototype"]).includes(value.mode) || !object(value.baseline))
|
|
3461
3567
|
throw invalid2();
|
|
3462
3568
|
const b = value.baseline;
|
|
@@ -3477,13 +3583,13 @@ function parseManagedConfig(text2) {
|
|
|
3477
3583
|
try {
|
|
3478
3584
|
value = JSON.parse(text2);
|
|
3479
3585
|
} catch {
|
|
3480
|
-
throw new InitError("INVALID_CONFIG", "
|
|
3586
|
+
throw new InitError("INVALID_CONFIG", t("config.jsonUnreadableShort"));
|
|
3481
3587
|
}
|
|
3482
3588
|
if (!value || typeof value !== "object" || Array.isArray(value) || !("schemaVersion" in value))
|
|
3483
3589
|
return parseProjectConfig(text2);
|
|
3484
3590
|
const config2 = value;
|
|
3485
3591
|
if (Object.keys(config2).sort().join(",") !== "baseline,schemaVersion" || config2.schemaVersion !== 1)
|
|
3486
|
-
throw new InitError("INVALID_CONFIG", "
|
|
3592
|
+
throw new InitError("INVALID_CONFIG", t("config.schemaFields"));
|
|
3487
3593
|
const checked = parseProjectConfig(JSON.stringify({ kind: "tryce-project", format: "workflow-1", mode: "auto", baseline: config2.baseline }));
|
|
3488
3594
|
return { schemaVersion: 1, baseline: checked.baseline };
|
|
3489
3595
|
}
|
|
@@ -3514,13 +3620,13 @@ var nameToken = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
|
3514
3620
|
function validateDocumentRelativePath(relative) {
|
|
3515
3621
|
const parts = relative.split("/");
|
|
3516
3622
|
if (relative.length > 200 || parts.length > 8)
|
|
3517
|
-
fail("
|
|
3623
|
+
fail(t("document.pathTooLong", { path: relative }));
|
|
3518
3624
|
const file2 = parts.pop();
|
|
3519
3625
|
if (!file2.endsWith(".md") || !nameToken.test(file2.slice(0, -3)))
|
|
3520
|
-
fail("
|
|
3626
|
+
fail(t("document.fileName", { path: relative }));
|
|
3521
3627
|
for (const part of parts)
|
|
3522
3628
|
if (!nameToken.test(part) || part.length > 80)
|
|
3523
|
-
fail("
|
|
3629
|
+
fail(t("document.folderName", { path: relative }));
|
|
3524
3630
|
}
|
|
3525
3631
|
var storeRelative = (path3) => path3.replace(/^\.(?:gitifact|tryce)\//, "");
|
|
3526
3632
|
var reqId = new RegExp(`^R-${token}$`);
|
|
@@ -3538,19 +3644,19 @@ ${design.body}
|
|
|
3538
3644
|
}
|
|
3539
3645
|
function parseDesignPreview(source, specId) {
|
|
3540
3646
|
if (source.includes("\0") || /\r(?!\n)/.test(source))
|
|
3541
|
-
fail("
|
|
3647
|
+
fail(t("design.invalidCharacters"));
|
|
3542
3648
|
const lines = normalized(source).split("\n");
|
|
3543
3649
|
if (!new RegExp(`^<!-- ${marker}-design: ${specId} -->$`).test(lines.shift() ?? ""))
|
|
3544
|
-
fail("
|
|
3650
|
+
fail(t("design.idMismatch"));
|
|
3545
3651
|
while (lines[0] === "")
|
|
3546
3652
|
lines.shift();
|
|
3547
3653
|
const heading = lines.shift();
|
|
3548
3654
|
if (!heading?.startsWith("# ") || !heading.slice(2).trim())
|
|
3549
|
-
fail("
|
|
3655
|
+
fail(t("design.titleRequired"));
|
|
3550
3656
|
const title = heading.slice(2).trim();
|
|
3551
3657
|
const raw = normalized(lines.join("\n"));
|
|
3552
3658
|
if (!raw)
|
|
3553
|
-
fail("
|
|
3659
|
+
fail(t("design.bodyRequired"));
|
|
3554
3660
|
const references = /* @__PURE__ */ new Set();
|
|
3555
3661
|
let fence;
|
|
3556
3662
|
const body = raw.split("\n").map((line) => {
|
|
@@ -3565,11 +3671,11 @@ function parseDesignPreview(source, specId) {
|
|
|
3565
3671
|
return line;
|
|
3566
3672
|
}
|
|
3567
3673
|
if (/^#\s/.test(line))
|
|
3568
|
-
fail("
|
|
3674
|
+
fail(t("design.singleTopHeading"));
|
|
3569
3675
|
if (/<!-- (?:gitifact|tryce)-/.test(line)) {
|
|
3570
3676
|
const ref = /^<!-- (?:gitifact|tryce)-ref: (R-[a-z2-7]{10}(?:, R-[a-z2-7]{10})*) -->$/.exec(line);
|
|
3571
3677
|
if (!ref)
|
|
3572
|
-
fail("
|
|
3678
|
+
fail(t("design.referenceFormat"));
|
|
3573
3679
|
for (const id of ref[1].split(", "))
|
|
3574
3680
|
references.add(id);
|
|
3575
3681
|
return `<!-- gitifact-ref: ${ref[1]} -->`;
|
|
@@ -3577,7 +3683,7 @@ function parseDesignPreview(source, specId) {
|
|
|
3577
3683
|
return line;
|
|
3578
3684
|
}).join("\n");
|
|
3579
3685
|
if (fence)
|
|
3580
|
-
fail("
|
|
3686
|
+
fail(t("design.unclosedFence"));
|
|
3581
3687
|
return { title, body, requirements: [...references] };
|
|
3582
3688
|
}
|
|
3583
3689
|
function renderDocument(doc) {
|
|
@@ -3591,28 +3697,28 @@ ${doc.body}
|
|
|
3591
3697
|
function parseDocument(path3, source) {
|
|
3592
3698
|
const match = documentPathPattern.exec(path3);
|
|
3593
3699
|
if (!match)
|
|
3594
|
-
fail("
|
|
3700
|
+
fail(t("document.unsupportedPath", { path: path3 }));
|
|
3595
3701
|
const kind = kindOfDir(match[1]);
|
|
3596
3702
|
if (kind === "product") {
|
|
3597
3703
|
if (path3 !== PRODUCT_PATH)
|
|
3598
|
-
fail("
|
|
3704
|
+
fail(t("document.productOnly", { path: path3 }));
|
|
3599
3705
|
} else
|
|
3600
3706
|
validateDocumentRelativePath(match[2]);
|
|
3601
3707
|
if (source.includes("\0") || /\r(?!\n)/.test(source))
|
|
3602
|
-
fail("
|
|
3708
|
+
fail(t("document.invalidCharacters", { path: path3 }));
|
|
3603
3709
|
const lines = normalized(source).split("\n");
|
|
3604
3710
|
const id = new RegExp(`^<!-- gitifact-${kind}: ([PG]-${token}) -->$`).exec(lines.shift() ?? "")?.[1];
|
|
3605
3711
|
if (!id || id[0] !== (kind === "product" ? "P" : "G"))
|
|
3606
|
-
return fail(
|
|
3712
|
+
return fail(t("document.idRequired", { kind, path: path3 }));
|
|
3607
3713
|
while (lines[0] === "")
|
|
3608
3714
|
lines.shift();
|
|
3609
3715
|
const heading = lines.shift();
|
|
3610
3716
|
if (!heading?.startsWith("# ") || !heading.slice(2).trim())
|
|
3611
|
-
fail("
|
|
3717
|
+
fail(t("document.titleRequired", { path: path3 }));
|
|
3612
3718
|
const title = heading.slice(2).trim();
|
|
3613
3719
|
const body = normalized(lines.join("\n"));
|
|
3614
3720
|
if (!body)
|
|
3615
|
-
fail("
|
|
3721
|
+
fail(t("document.bodyRequired", { path: path3 }));
|
|
3616
3722
|
let fence;
|
|
3617
3723
|
for (const line of body.split("\n")) {
|
|
3618
3724
|
if (fence) {
|
|
@@ -3626,12 +3732,12 @@ function parseDocument(path3, source) {
|
|
|
3626
3732
|
continue;
|
|
3627
3733
|
}
|
|
3628
3734
|
if (/^#\s/.test(line))
|
|
3629
|
-
fail("
|
|
3735
|
+
fail(t("document.singleTopHeading", { path: path3 }));
|
|
3630
3736
|
if (/<!-- (?:gitifact|tryce)-/.test(line))
|
|
3631
|
-
fail("
|
|
3737
|
+
fail(t("document.noMarkerInBody", { path: path3 }));
|
|
3632
3738
|
}
|
|
3633
3739
|
if (fence)
|
|
3634
|
-
fail("
|
|
3740
|
+
fail(t("document.unclosedFence", { path: path3 }));
|
|
3635
3741
|
return { id, kind, path: path3, title, body };
|
|
3636
3742
|
}
|
|
3637
3743
|
function parseDocumentFiles(files) {
|
|
@@ -3652,22 +3758,22 @@ function validateDocumentSets(sets) {
|
|
|
3652
3758
|
const paths2 = /* @__PURE__ */ new Set();
|
|
3653
3759
|
const historyIds = /* @__PURE__ */ new Set();
|
|
3654
3760
|
if (sets.map((s) => s.kind).sort().join(",") !== "guide,product")
|
|
3655
|
-
fail("
|
|
3761
|
+
fail(t("document.kindSet"));
|
|
3656
3762
|
for (const set2 of sets) {
|
|
3657
3763
|
for (const d of set2.documents) {
|
|
3658
3764
|
if (d.kind !== set2.kind)
|
|
3659
|
-
fail("
|
|
3765
|
+
fail(t("document.kindMismatch", { path: d.path }));
|
|
3660
3766
|
if (ids.has(d.id))
|
|
3661
|
-
fail("
|
|
3767
|
+
fail(t("document.duplicateId", { id: d.id }));
|
|
3662
3768
|
ids.add(d.id);
|
|
3663
3769
|
const lower = d.path.toLowerCase();
|
|
3664
3770
|
if (paths2.has(lower))
|
|
3665
|
-
fail("
|
|
3771
|
+
fail(t("document.caseOnlyPath", { path: d.path }));
|
|
3666
3772
|
paths2.add(lower);
|
|
3667
3773
|
}
|
|
3668
3774
|
for (const h of set2.history) {
|
|
3669
3775
|
if (historyIds.has(h.id))
|
|
3670
|
-
fail("
|
|
3776
|
+
fail(t("history.duplicateId", { id: h.id }));
|
|
3671
3777
|
historyIds.add(h.id);
|
|
3672
3778
|
}
|
|
3673
3779
|
}
|
|
@@ -3685,7 +3791,7 @@ function validateBundle(bundle) {
|
|
|
3685
3791
|
const ids = /* @__PURE__ */ new Set();
|
|
3686
3792
|
for (const h of [...bundle.specs.flatMap((s) => s.history), ...bundle.documents.flatMap((d) => d.history)]) {
|
|
3687
3793
|
if (ids.has(h.id))
|
|
3688
|
-
fail("
|
|
3794
|
+
fail(t("history.duplicateId", { id: h.id }));
|
|
3689
3795
|
ids.add(h.id);
|
|
3690
3796
|
}
|
|
3691
3797
|
}
|
|
@@ -3701,20 +3807,20 @@ function parsePreviewFiles(files) {
|
|
|
3701
3807
|
if (path3.endsWith("/requirements.md")) {
|
|
3702
3808
|
specs.push(parseSpecPreview(path3, source, files.get(path3.replace(/requirements\.md$/, "history.jsonl")) ?? "", files.get(path3.replace(/requirements\.md$/, "design.md"))));
|
|
3703
3809
|
} else if (!files.has(path3.replace(/(?:history\.jsonl|design\.md)$/, "requirements.md")))
|
|
3704
|
-
fail("
|
|
3810
|
+
fail(t("spec.orphanFile", { path: path3 }));
|
|
3705
3811
|
}
|
|
3706
3812
|
validatePreviewSnapshot(specs);
|
|
3707
3813
|
return specs;
|
|
3708
3814
|
}
|
|
3709
3815
|
function parseSpecPreview(path3, source, history = "", designSource) {
|
|
3710
3816
|
if (!/^\.(?:gitifact|tryce)\/spec\/[^/]+\/requirements\.md$/.test(path3))
|
|
3711
|
-
fail("
|
|
3817
|
+
fail(t("spec.unsupportedPath", { path: path3 }));
|
|
3712
3818
|
if (source.includes("\0") || source.includes("\r") && /\r(?!\n)/.test(source))
|
|
3713
|
-
fail("
|
|
3819
|
+
fail(t("spec.invalidCharacters", { path: path3 }));
|
|
3714
3820
|
const lines = normalized(source).split("\n");
|
|
3715
3821
|
const specMatch = new RegExp(`^<!-- ${marker}-spec: (S-${token}) -->$`).exec(lines[0] ?? "");
|
|
3716
3822
|
if (!specMatch)
|
|
3717
|
-
fail("
|
|
3823
|
+
fail(t("spec.idRequired", { path: path3 }));
|
|
3718
3824
|
let title = "";
|
|
3719
3825
|
let description = "";
|
|
3720
3826
|
let current;
|
|
@@ -3732,7 +3838,7 @@ function parseSpecPreview(path3, source, history = "", designSource) {
|
|
|
3732
3838
|
if (waitingId) {
|
|
3733
3839
|
const match = new RegExp(`^<!-- ${marker}-req: (R-${token}) -->$`).exec(line);
|
|
3734
3840
|
if (!match || !current)
|
|
3735
|
-
fail("
|
|
3841
|
+
fail(t("spec.requirementIdRequired", { path: path3 }));
|
|
3736
3842
|
current.id = match[1];
|
|
3737
3843
|
waitingId = false;
|
|
3738
3844
|
continue;
|
|
@@ -3746,42 +3852,42 @@ function parseSpecPreview(path3, source, history = "", designSource) {
|
|
|
3746
3852
|
const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
|
|
3747
3853
|
if (opening) {
|
|
3748
3854
|
if (opening[1][0] === "`" && opening[2].includes("`"))
|
|
3749
|
-
fail("
|
|
3855
|
+
fail(t("spec.invalidFence"));
|
|
3750
3856
|
fence = { char: opening[1][0], size: opening[1].length };
|
|
3751
3857
|
append(line);
|
|
3752
3858
|
continue;
|
|
3753
3859
|
}
|
|
3754
3860
|
if (/^# /.test(line)) {
|
|
3755
3861
|
if (title || current || description.trim())
|
|
3756
|
-
fail("
|
|
3862
|
+
fail(t("spec.titleOnce", { path: path3 }));
|
|
3757
3863
|
title = line.slice(2).trim();
|
|
3758
3864
|
if (!title)
|
|
3759
|
-
fail("
|
|
3865
|
+
fail(t("spec.emptyTitle"));
|
|
3760
3866
|
continue;
|
|
3761
3867
|
}
|
|
3762
3868
|
if (/^## /.test(line)) {
|
|
3763
3869
|
if (!title)
|
|
3764
|
-
fail("
|
|
3870
|
+
fail(t("spec.titleMissing", { path: path3 }));
|
|
3765
3871
|
current = { id: "", title: line.slice(3).trim(), body: "" };
|
|
3766
3872
|
if (!current.title)
|
|
3767
|
-
fail("
|
|
3873
|
+
fail(t("spec.emptyRequirementTitle"));
|
|
3768
3874
|
requirements.push(current);
|
|
3769
3875
|
waitingId = true;
|
|
3770
3876
|
continue;
|
|
3771
3877
|
}
|
|
3772
3878
|
if (line.includes("<!--") || line.includes("-->"))
|
|
3773
|
-
fail("
|
|
3879
|
+
fail(t("spec.commentPosition", { path: path3 }));
|
|
3774
3880
|
if (/^ {1,3}#{1,2}\s|^#{1,2}\t|^\s*(?:===+|---+)\s*$/.test(line))
|
|
3775
|
-
fail("
|
|
3881
|
+
fail(t("spec.atxOnly", { path: path3 }));
|
|
3776
3882
|
append(line);
|
|
3777
3883
|
}
|
|
3778
3884
|
if (!title || waitingId || fence)
|
|
3779
|
-
fail("
|
|
3885
|
+
fail(t("spec.incomplete", { path: path3 }));
|
|
3780
3886
|
const ids = /* @__PURE__ */ new Set();
|
|
3781
3887
|
for (const r of requirements) {
|
|
3782
3888
|
r.body = normalized(r.body);
|
|
3783
3889
|
if (!r.body || ids.has(r.id))
|
|
3784
|
-
fail("
|
|
3890
|
+
fail(t("spec.emptyOrDuplicateRequirement", { id: r.id }));
|
|
3785
3891
|
ids.add(r.id);
|
|
3786
3892
|
}
|
|
3787
3893
|
return { id: specMatch[1], path: path3, title, description: normalized(description), requirements, history: parsePreviewHistory(history), ...designSource === void 0 ? {} : { design: parseDesignPreview(designSource, specMatch[1]) } };
|
|
@@ -3797,13 +3903,13 @@ function parsePreviewHistory(source, scope = "spec") {
|
|
|
3797
3903
|
try {
|
|
3798
3904
|
value = JSON.parse(line);
|
|
3799
3905
|
} catch {
|
|
3800
|
-
fail("
|
|
3906
|
+
fail(t("history.invalidJsonl"));
|
|
3801
3907
|
}
|
|
3802
3908
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3803
|
-
fail("
|
|
3909
|
+
fail(t("history.invalidRecord"));
|
|
3804
3910
|
const r = value;
|
|
3805
3911
|
if (!shapes.includes(Object.keys(r).sort().join(",")) || typeof r.id !== "string" || !new RegExp(`^H-${token}$`).test(r.id) || ids.has(r.id) || typeof r.reason !== "string" || !r.reason.trim() || !Array.isArray(r.requirements) || !r.requirements.length && !Array.isArray(r.designs) && !Array.isArray(r.documents) || r.documents !== void 0 && (r.requirements.length || !Array.isArray(r.documents) || !r.documents.length || r.documents.some((id) => typeof id !== "string" || !/^[PG]-[a-z2-7]{10}$/.test(id)) || new Set(r.documents).size !== r.documents.length) || r.designs !== void 0 && (!Array.isArray(r.designs) || !r.designs.length || r.designs.some((id) => typeof id !== "string" || !/^S-[a-z2-7]{10}$/.test(id)) || new Set(r.designs).size !== r.designs.length) || r.requirements.some((id) => typeof id !== "string" || !reqId.test(id)) || new Set(r.requirements).size !== r.requirements.length)
|
|
3806
|
-
fail("
|
|
3912
|
+
fail(t("history.invalidFields"));
|
|
3807
3913
|
ids.add(r.id);
|
|
3808
3914
|
records.push({ id: r.id, requirements: r.requirements, ...r.designs === void 0 ? {} : { designs: r.designs }, ...r.documents === void 0 ? {} : { documents: r.documents }, reason: r.reason });
|
|
3809
3915
|
}
|
|
@@ -3815,16 +3921,16 @@ function validatePreviewSnapshot(specs) {
|
|
|
3815
3921
|
const historyIds = /* @__PURE__ */ new Set();
|
|
3816
3922
|
for (const s of specs) {
|
|
3817
3923
|
if (specIds.has(s.id))
|
|
3818
|
-
fail("
|
|
3924
|
+
fail(t("spec.duplicateId", { id: s.id }));
|
|
3819
3925
|
specIds.add(s.id);
|
|
3820
3926
|
for (const r of s.requirements) {
|
|
3821
3927
|
if (reqIds.has(r.id))
|
|
3822
|
-
fail("
|
|
3928
|
+
fail(t("spec.duplicateRequirementId", { id: r.id }));
|
|
3823
3929
|
reqIds.add(r.id);
|
|
3824
3930
|
}
|
|
3825
3931
|
for (const h of s.history) {
|
|
3826
3932
|
if (historyIds.has(h.id))
|
|
3827
|
-
fail("
|
|
3933
|
+
fail(t("history.duplicateId", { id: h.id }));
|
|
3828
3934
|
historyIds.add(h.id);
|
|
3829
3935
|
}
|
|
3830
3936
|
}
|
|
@@ -3843,7 +3949,7 @@ function compareSpecPreviews(before, after) {
|
|
|
3843
3949
|
const reasons = after.flatMap((s) => s.history).filter((h) => {
|
|
3844
3950
|
const old = previousHistory.get(h.id);
|
|
3845
3951
|
if (old && JSON.stringify(old) !== JSON.stringify(h))
|
|
3846
|
-
fail("
|
|
3952
|
+
fail(t("history.changed", { id: h.id }));
|
|
3847
3953
|
return !old;
|
|
3848
3954
|
});
|
|
3849
3955
|
const changes = [.../* @__PURE__ */ new Set([...prev.keys(), ...next.keys()])].sort().flatMap((id) => {
|
|
@@ -3865,7 +3971,7 @@ function compareSpecPreviews(before, after) {
|
|
|
3865
3971
|
const changed = new Set(changes.map((c) => c.id));
|
|
3866
3972
|
for (const h of reasons)
|
|
3867
3973
|
if ([...h.requirements, ...h.designs ?? []].some((id) => !changed.has(id)))
|
|
3868
|
-
fail("
|
|
3974
|
+
fail(t("history.unlinkedRequirement", { id: h.id }));
|
|
3869
3975
|
const prevSpecs = new Map(before.map((s) => [s.id, s]));
|
|
3870
3976
|
const nextSpecs = new Map(after.map((s) => [s.id, s]));
|
|
3871
3977
|
const specChanges = [.../* @__PURE__ */ new Set([...prevSpecs.keys(), ...nextSpecs.keys()])].sort().flatMap((id) => {
|
|
@@ -3889,7 +3995,7 @@ function compareDocumentSets(before, after) {
|
|
|
3889
3995
|
const reasons = after.flatMap((s) => s.history).filter((h) => {
|
|
3890
3996
|
const old = previousHistory.get(h.id);
|
|
3891
3997
|
if (old && JSON.stringify(old) !== JSON.stringify(h))
|
|
3892
|
-
fail("
|
|
3998
|
+
fail(t("history.changed", { id: h.id }));
|
|
3893
3999
|
return !old;
|
|
3894
4000
|
});
|
|
3895
4001
|
const changes = [.../* @__PURE__ */ new Set([...prev.keys(), ...next.keys()])].sort().flatMap((id) => {
|
|
@@ -3912,7 +4018,7 @@ function compareDocumentSets(before, after) {
|
|
|
3912
4018
|
const changed = new Set(changes.map((c) => c.id));
|
|
3913
4019
|
for (const h of reasons)
|
|
3914
4020
|
if ((h.documents ?? []).some((id) => !changed.has(id)))
|
|
3915
|
-
fail("
|
|
4021
|
+
fail(t("history.unlinkedDocument", { id: h.id }));
|
|
3916
4022
|
return changes;
|
|
3917
4023
|
}
|
|
3918
4024
|
function comparePreviewBundles(before, after) {
|
|
@@ -3932,7 +4038,7 @@ var featurePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
|
3932
4038
|
var reserved = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/;
|
|
3933
4039
|
function previewPath(feature2) {
|
|
3934
4040
|
if (!featurePattern.test(feature2) || feature2.length > 80 || reserved.test(feature2))
|
|
3935
|
-
fail2("
|
|
4041
|
+
fail2(t("edit.invalidFeatureName"));
|
|
3936
4042
|
return `.gitifact/spec/${feature2}/requirements.md`;
|
|
3937
4043
|
}
|
|
3938
4044
|
function renderSpecPreview(spec2) {
|
|
@@ -3948,7 +4054,7 @@ ${r.body}
|
|
|
3948
4054
|
}
|
|
3949
4055
|
function editSpecPreview(original, input2, generate) {
|
|
3950
4056
|
if (!Array.isArray(input2) || !input2.length || input2.length > 100)
|
|
3951
|
-
fail2("
|
|
4057
|
+
fail2(t("edit.operationCount"));
|
|
3952
4058
|
const source = asBundle(original);
|
|
3953
4059
|
const specs = source.specs.map((s) => ({ ...s, requirements: s.requirements.map((r) => ({ ...r })), history: s.history.map((h) => ({ ...h, requirements: [...h.requirements] })) }));
|
|
3954
4060
|
const documents = source.documents.map((set2) => ({ ...set2, documents: set2.documents.map((d) => ({ ...d })), history: set2.history.map((h) => ({ ...h })) }));
|
|
@@ -3958,18 +4064,18 @@ function editSpecPreview(original, input2, generate) {
|
|
|
3958
4064
|
for (let attempt = 0; attempt < 100; attempt++) {
|
|
3959
4065
|
const id = generate(prefix);
|
|
3960
4066
|
if (!new RegExp(`^${prefix}-[a-z2-7]{10}$`).test(id))
|
|
3961
|
-
fail2("
|
|
4067
|
+
fail2(t("edit.idGenerated"));
|
|
3962
4068
|
if (!used.has(id)) {
|
|
3963
4069
|
used.add(id);
|
|
3964
4070
|
return id;
|
|
3965
4071
|
}
|
|
3966
4072
|
}
|
|
3967
|
-
return fail2("
|
|
4073
|
+
return fail2(t("edit.idUnavailable"));
|
|
3968
4074
|
};
|
|
3969
4075
|
const results = [];
|
|
3970
4076
|
for (const raw of input2) {
|
|
3971
4077
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3972
|
-
fail2("
|
|
4078
|
+
fail2(t("edit.invalidOperation"));
|
|
3973
4079
|
const op = raw;
|
|
3974
4080
|
const schemas = {
|
|
3975
4081
|
create: ["type", "feature", "title", "description"],
|
|
@@ -3989,27 +4095,27 @@ function editSpecPreview(original, input2, generate) {
|
|
|
3989
4095
|
const type = String(op.type);
|
|
3990
4096
|
const fields2 = schemas[type];
|
|
3991
4097
|
if (!fields2 || Object.keys(op).some((k) => !fields2.includes(k)))
|
|
3992
|
-
fail2("
|
|
4098
|
+
fail2(t("edit.unsupportedField"));
|
|
3993
4099
|
const str = (key, optional3 = false) => {
|
|
3994
4100
|
if (optional3 && op[key] === void 0)
|
|
3995
4101
|
return "";
|
|
3996
4102
|
if (typeof op[key] !== "string" || !op[key].trim())
|
|
3997
|
-
return fail2("
|
|
4103
|
+
return fail2(t("edit.emptyField", { field: key }));
|
|
3998
4104
|
const value = op[key].replace(/\r\n/g, "\n").trim();
|
|
3999
4105
|
if (value.includes("\0") || value.includes("\r") || key !== "body" && key !== "description" && /[\n]/.test(value))
|
|
4000
|
-
fail2("
|
|
4106
|
+
fail2(t("edit.invalidCharacters", { field: key }));
|
|
4001
4107
|
return value;
|
|
4002
4108
|
};
|
|
4003
4109
|
const target = () => {
|
|
4004
4110
|
const path3 = previewPath(str("feature"));
|
|
4005
|
-
return specs.find((s) => s.path === path3) ?? fail2("
|
|
4111
|
+
return specs.find((s) => s.path === path3) ?? fail2(t("edit.specNotFound", { path: path3 }));
|
|
4006
4112
|
};
|
|
4007
4113
|
if (type === "set-product" || type === "delete-product") {
|
|
4008
4114
|
const set2 = documents.find((s) => s.kind === "product");
|
|
4009
4115
|
const existing = set2.documents[0];
|
|
4010
4116
|
if (type === "delete-product") {
|
|
4011
4117
|
if (!existing)
|
|
4012
|
-
fail2("
|
|
4118
|
+
fail2(t("edit.noProductToDelete"));
|
|
4013
4119
|
set2.documents = [];
|
|
4014
4120
|
results.push({ type, id: existing.id });
|
|
4015
4121
|
} else {
|
|
@@ -4026,14 +4132,14 @@ function editSpecPreview(original, input2, generate) {
|
|
|
4026
4132
|
validateDocumentRelativePath(relative);
|
|
4027
4133
|
const path3 = `${DOCUMENT_DIRS[kind]}/${relative}`;
|
|
4028
4134
|
if (self && self.path === path3)
|
|
4029
|
-
fail2("
|
|
4135
|
+
fail2(t("edit.samePath"));
|
|
4030
4136
|
if (all().some((d) => d !== self && d.path.toLowerCase() === path3.toLowerCase()))
|
|
4031
|
-
fail2("
|
|
4137
|
+
fail2(t("edit.documentPathExists", { path: path3 }));
|
|
4032
4138
|
return path3;
|
|
4033
4139
|
};
|
|
4034
4140
|
const find = () => {
|
|
4035
4141
|
const id = str("id");
|
|
4036
|
-
return all().find((d) => d.id === id) ?? fail2("
|
|
4142
|
+
return all().find((d) => d.id === id) ?? fail2(t("edit.guideIdNotFound", { id }));
|
|
4037
4143
|
};
|
|
4038
4144
|
if (type === "create-doc") {
|
|
4039
4145
|
const kind = "guide";
|
|
@@ -4060,7 +4166,7 @@ function editSpecPreview(original, input2, generate) {
|
|
|
4060
4166
|
if (type === "create") {
|
|
4061
4167
|
const path3 = previewPath(str("feature"));
|
|
4062
4168
|
if (specs.some((s) => s.path.toLowerCase() === path3.toLowerCase()))
|
|
4063
|
-
fail2("
|
|
4169
|
+
fail2(t("edit.featureExists"));
|
|
4064
4170
|
const spec2 = { id: allocate("S"), path: path3, title: str("title"), description: str("description", true), requirements: [], history: [] };
|
|
4065
4171
|
specs.push(spec2);
|
|
4066
4172
|
results.push({ type, id: spec2.id });
|
|
@@ -4073,23 +4179,23 @@ function editSpecPreview(original, input2, generate) {
|
|
|
4073
4179
|
const spec2 = target();
|
|
4074
4180
|
if (type === "delete-design") {
|
|
4075
4181
|
if (!spec2.design)
|
|
4076
|
-
fail2("
|
|
4182
|
+
fail2(t("edit.noDesignToDelete"));
|
|
4077
4183
|
delete spec2.design;
|
|
4078
4184
|
} else
|
|
4079
4185
|
spec2.design = parseDesignPreview(renderDesignPreview(spec2.id, { title: str("title"), body: str("body") }), spec2.id);
|
|
4080
4186
|
results.push({ type, id: spec2.id });
|
|
4081
4187
|
} else if (type === "rename-spec") {
|
|
4082
|
-
const spec2 = specs.find((s) => s.id === str("id")) ?? fail2("
|
|
4188
|
+
const spec2 = specs.find((s) => s.id === str("id")) ?? fail2(t("edit.specIdNotFound"));
|
|
4083
4189
|
spec2.title = str("title");
|
|
4084
4190
|
results.push({ type, id: spec2.id });
|
|
4085
4191
|
} else {
|
|
4086
4192
|
const id = str("id");
|
|
4087
|
-
const source2 = specs.find((s) => s.requirements.some((r) => r.id === id)) ?? fail2("
|
|
4193
|
+
const source2 = specs.find((s) => s.requirements.some((r) => r.id === id)) ?? fail2(t("edit.requirementIdNotFound"));
|
|
4088
4194
|
const req = source2.requirements.find((r) => r.id === id);
|
|
4089
4195
|
if (type === "move") {
|
|
4090
4196
|
const destination = target();
|
|
4091
4197
|
if (source2 === destination)
|
|
4092
|
-
fail2("
|
|
4198
|
+
fail2(t("edit.sameSpec"));
|
|
4093
4199
|
source2.requirements = source2.requirements.filter((r) => r.id !== id);
|
|
4094
4200
|
destination.requirements.push(req);
|
|
4095
4201
|
} else {
|
|
@@ -4102,13 +4208,13 @@ function editSpecPreview(original, input2, generate) {
|
|
|
4102
4208
|
for (const spec2 of specs) {
|
|
4103
4209
|
const parsed = parseSpecPreview(spec2.path, renderSpecPreview(spec2), "", spec2.design ? renderDesignPreview(spec2.id, spec2.design) : void 0);
|
|
4104
4210
|
if (JSON.stringify({ ...parsed, history: spec2.history }) !== JSON.stringify(spec2))
|
|
4105
|
-
fail2("
|
|
4211
|
+
fail2(t("edit.bodyChangesSpecStructure"));
|
|
4106
4212
|
}
|
|
4107
4213
|
for (const set2 of documents) {
|
|
4108
4214
|
set2.documents.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
4109
4215
|
for (const doc of set2.documents)
|
|
4110
4216
|
if (JSON.stringify(parseDocument(doc.path, renderDocument(doc))) !== JSON.stringify(doc))
|
|
4111
|
-
fail2("
|
|
4217
|
+
fail2(t("edit.bodyChangesDocumentStructure", { path: doc.path }));
|
|
4112
4218
|
}
|
|
4113
4219
|
validateBundle({ specs, documents });
|
|
4114
4220
|
return { specs, documents, results };
|
|
@@ -4136,14 +4242,14 @@ function finalSpecPreviewChanges(beforeValue, currentValue) {
|
|
|
4136
4242
|
for (const previous of before.specs) {
|
|
4137
4243
|
const next = current.specs.find((s) => s.id === previous.id);
|
|
4138
4244
|
if (previous.history.length && !next)
|
|
4139
|
-
fail3("
|
|
4245
|
+
fail3(t("reason.keepEmptySpec", { id: previous.id }));
|
|
4140
4246
|
if (next && !equal(next.history.slice(0, previous.history.length), previous.history))
|
|
4141
|
-
fail3("
|
|
4247
|
+
fail3(t("reason.committedImmutable", { id: previous.id }));
|
|
4142
4248
|
}
|
|
4143
4249
|
for (const previous of before.documents) {
|
|
4144
4250
|
const next = current.documents.find((s) => s.kind === previous.kind);
|
|
4145
4251
|
if (!equal(next.history.slice(0, previous.history.length), previous.history))
|
|
4146
|
-
fail3("
|
|
4252
|
+
fail3(t("reason.committedDocumentImmutable", { kind: previous.kind }));
|
|
4147
4253
|
}
|
|
4148
4254
|
const clean = {
|
|
4149
4255
|
specs: current.specs.map((s) => ({ ...s, history: before.specs.find((p) => p.id === s.id)?.history ?? [] })),
|
|
@@ -4158,7 +4264,7 @@ function prepareSpecPreview(beforeValue, currentValue, baseFiles, currentFiles,
|
|
|
4158
4264
|
const current = currentBundle.specs;
|
|
4159
4265
|
const delta = finalSpecPreviewChanges(beforeBundle, currentBundle);
|
|
4160
4266
|
if (!Array.isArray(input2) || input2.length > 100)
|
|
4161
|
-
fail3("
|
|
4267
|
+
fail3(t("reason.count"));
|
|
4162
4268
|
const writes = /* @__PURE__ */ new Map();
|
|
4163
4269
|
const pending = /* @__PURE__ */ new Map();
|
|
4164
4270
|
const covered = /* @__PURE__ */ new Set();
|
|
@@ -4168,34 +4274,34 @@ function prepareSpecPreview(beforeValue, currentValue, baseFiles, currentFiles,
|
|
|
4168
4274
|
for (let attempt = 0; attempt < 100; attempt++) {
|
|
4169
4275
|
const id = generate();
|
|
4170
4276
|
if (!/^H-[a-z2-7]{10}$/.test(id))
|
|
4171
|
-
fail3("
|
|
4277
|
+
fail3(t("reason.idGenerated"));
|
|
4172
4278
|
if (!used.has(id)) {
|
|
4173
4279
|
used.add(id);
|
|
4174
4280
|
return id;
|
|
4175
4281
|
}
|
|
4176
4282
|
}
|
|
4177
|
-
return fail3("
|
|
4283
|
+
return fail3(t("reason.idUnavailable"));
|
|
4178
4284
|
};
|
|
4179
4285
|
for (const value of input2) {
|
|
4180
4286
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
4181
|
-
fail3("
|
|
4287
|
+
fail3(t("reason.invalidInput"));
|
|
4182
4288
|
const raw = value;
|
|
4183
4289
|
const shape = Object.keys(raw).sort().join(",");
|
|
4184
4290
|
if (!["reason,requirements", "designs,reason,requirements", "documents,reason,requirements"].includes(shape) || typeof raw.reason !== "string" || !raw.reason.trim() || raw.reason.includes("\0") || raw.reason.length > 16e3 || !Array.isArray(raw.requirements) || raw.designs !== void 0 && !Array.isArray(raw.designs) || raw.documents !== void 0 && !Array.isArray(raw.documents) || !(raw.requirements.length || raw.designs?.length || raw.documents?.length))
|
|
4185
|
-
fail3("
|
|
4291
|
+
fail3(t("reason.targetsRequired"));
|
|
4186
4292
|
const reason = raw.reason.trim();
|
|
4187
4293
|
const groups = /* @__PURE__ */ new Map();
|
|
4188
4294
|
if (raw.documents !== void 0) {
|
|
4189
4295
|
if (raw.requirements.length)
|
|
4190
|
-
fail3("
|
|
4296
|
+
fail3(t("reason.documentWithRequirements"));
|
|
4191
4297
|
const ids = raw.documents;
|
|
4192
4298
|
let kind;
|
|
4193
4299
|
for (const value2 of ids) {
|
|
4194
4300
|
if (typeof value2 !== "string" || !/^[PG]-[a-z2-7]{10}$/.test(value2) || covered.has(value2))
|
|
4195
|
-
return fail3("
|
|
4196
|
-
const change2 = delta.changes.find((c) => c.id === value2) ?? fail3("
|
|
4301
|
+
return fail3(t("reason.documentTargetInvalid"));
|
|
4302
|
+
const change2 = delta.changes.find((c) => c.id === value2) ?? fail3(t("reason.documentUnchanged", { id: value2 }));
|
|
4197
4303
|
if (kind && change2.kind !== kind)
|
|
4198
|
-
fail3("
|
|
4304
|
+
fail3(t("reason.singleDocumentKind"));
|
|
4199
4305
|
kind = change2.kind;
|
|
4200
4306
|
covered.add(value2);
|
|
4201
4307
|
}
|
|
@@ -4208,16 +4314,16 @@ function prepareSpecPreview(beforeValue, currentValue, baseFiles, currentFiles,
|
|
|
4208
4314
|
}
|
|
4209
4315
|
for (const value2 of [...raw.requirements, ...raw.designs ?? []]) {
|
|
4210
4316
|
if (typeof value2 !== "string")
|
|
4211
|
-
fail3("
|
|
4317
|
+
fail3(t("reason.invalidTarget"));
|
|
4212
4318
|
const id = value2;
|
|
4213
4319
|
if (raw.requirements.includes(id) ? !/^R-[a-z2-7]{10}$/.test(id) : !/^S-[a-z2-7]{10}$/.test(id))
|
|
4214
|
-
fail3("
|
|
4320
|
+
fail3(t("reason.targetKind"));
|
|
4215
4321
|
if (typeof id !== "string" || covered.has(id))
|
|
4216
|
-
fail3("
|
|
4217
|
-
const change2 = delta.changes.find((c) => c.id === id) ?? fail3("
|
|
4322
|
+
fail3(t("reason.targetInvalid"));
|
|
4323
|
+
const change2 = delta.changes.find((c) => c.id === id) ?? fail3(t("reason.requirementUnchanged", { id }));
|
|
4218
4324
|
const specId = (change2.after ?? change2.before).specId;
|
|
4219
4325
|
if (!current.some((s) => s.id === specId))
|
|
4220
|
-
fail3("
|
|
4326
|
+
fail3(t("reason.keepDeletedSpec"));
|
|
4221
4327
|
covered.add(id);
|
|
4222
4328
|
groups.set(specId, [...groups.get(specId) ?? [], id]);
|
|
4223
4329
|
}
|
|
@@ -4359,9 +4465,9 @@ function parsePorcelain(buffer, format) {
|
|
|
4359
4465
|
entries.sort((a, b) => Buffer.compare(Buffer.from(a.change.path), Buffer.from(b.change.path)));
|
|
4360
4466
|
return {
|
|
4361
4467
|
head,
|
|
4362
|
-
changes: entries.map((
|
|
4468
|
+
changes: entries.map((entry2) => entry2.change),
|
|
4363
4469
|
// Keep modes and object IDs: an unchanged count/XY is not an unchanged index.
|
|
4364
|
-
comparison: JSON.stringify([head, entries.map((
|
|
4470
|
+
comparison: JSON.stringify([head, entries.map((entry2) => entry2.raw)])
|
|
4365
4471
|
};
|
|
4366
4472
|
}
|
|
4367
4473
|
|
|
@@ -5406,8 +5512,8 @@ function numKeys(data) {
|
|
|
5406
5512
|
return keyCount;
|
|
5407
5513
|
}
|
|
5408
5514
|
var getParsedType = (data) => {
|
|
5409
|
-
const
|
|
5410
|
-
switch (
|
|
5515
|
+
const t3 = typeof data;
|
|
5516
|
+
switch (t3) {
|
|
5411
5517
|
case "undefined":
|
|
5412
5518
|
return "undefined";
|
|
5413
5519
|
case "string":
|
|
@@ -5446,7 +5552,7 @@ var getParsedType = (data) => {
|
|
|
5446
5552
|
}
|
|
5447
5553
|
return "object";
|
|
5448
5554
|
default:
|
|
5449
|
-
throw new Error(`Unknown data type: ${
|
|
5555
|
+
throw new Error(`Unknown data type: ${t3}`);
|
|
5450
5556
|
}
|
|
5451
5557
|
};
|
|
5452
5558
|
var propertyKeyTypes = /* @__PURE__ */ new Set(["string", "number", "symbol"]);
|
|
@@ -5734,8 +5840,8 @@ function getLengthableOrigin(input2) {
|
|
|
5734
5840
|
return "unknown";
|
|
5735
5841
|
}
|
|
5736
5842
|
function parsedType(data) {
|
|
5737
|
-
const
|
|
5738
|
-
switch (
|
|
5843
|
+
const t3 = typeof data;
|
|
5844
|
+
switch (t3) {
|
|
5739
5845
|
case "number": {
|
|
5740
5846
|
return Number.isNaN(data) ? "nan" : "number";
|
|
5741
5847
|
}
|
|
@@ -5752,7 +5858,7 @@ function parsedType(data) {
|
|
|
5752
5858
|
}
|
|
5753
5859
|
}
|
|
5754
5860
|
}
|
|
5755
|
-
return
|
|
5861
|
+
return t3;
|
|
5756
5862
|
}
|
|
5757
5863
|
function issue(...args) {
|
|
5758
5864
|
const [iss, input2, inst] = args;
|
|
@@ -7950,7 +8056,7 @@ function handleCatchall(proms, input2, payload, ctx, def, inst, abortEarly) {
|
|
|
7950
8056
|
const unrecognized = [];
|
|
7951
8057
|
const keySet = def.keySet;
|
|
7952
8058
|
const _catchall = def.catchall._zod;
|
|
7953
|
-
const
|
|
8059
|
+
const t3 = _catchall.def.type;
|
|
7954
8060
|
const optin = _catchall.optin;
|
|
7955
8061
|
const optout = _catchall.optout;
|
|
7956
8062
|
let seen = 0;
|
|
@@ -7963,11 +8069,11 @@ function handleCatchall(proms, input2, payload, ctx, def, inst, abortEarly) {
|
|
|
7963
8069
|
if (keySet.has(key))
|
|
7964
8070
|
continue;
|
|
7965
8071
|
if (key === "__proto__") {
|
|
7966
|
-
if (
|
|
8072
|
+
if (t3 === "never")
|
|
7967
8073
|
unrecognized.push(key);
|
|
7968
8074
|
continue;
|
|
7969
8075
|
}
|
|
7970
|
-
if (
|
|
8076
|
+
if (t3 === "never") {
|
|
7971
8077
|
unrecognized.push(key);
|
|
7972
8078
|
continue;
|
|
7973
8079
|
}
|
|
@@ -8533,7 +8639,7 @@ function handleIntersectionResults(result, left, right) {
|
|
|
8533
8639
|
}
|
|
8534
8640
|
var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
8535
8641
|
$ZodType.init(inst, def);
|
|
8536
|
-
const
|
|
8642
|
+
const items2 = def.items;
|
|
8537
8643
|
const memo2 = globalConfig.memoizer;
|
|
8538
8644
|
memo2?.attach(inst);
|
|
8539
8645
|
inst._zod.parse = (payload, ctx) => {
|
|
@@ -8549,8 +8655,8 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
8549
8655
|
}
|
|
8550
8656
|
payload.value = memo2 ? memo2.alloc(inst, payload, [], ctx) : [];
|
|
8551
8657
|
const proms = [];
|
|
8552
|
-
const optinStart = getTupleOptStart(
|
|
8553
|
-
const optoutStart = getTupleOptStart(
|
|
8658
|
+
const optinStart = getTupleOptStart(items2, "optin");
|
|
8659
|
+
const optoutStart = getTupleOptStart(items2, "optout");
|
|
8554
8660
|
if (!def.rest) {
|
|
8555
8661
|
if (input2.length < optinStart) {
|
|
8556
8662
|
payload.issues.push({
|
|
@@ -8563,10 +8669,10 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
8563
8669
|
});
|
|
8564
8670
|
return payload;
|
|
8565
8671
|
}
|
|
8566
|
-
if (input2.length >
|
|
8672
|
+
if (input2.length > items2.length) {
|
|
8567
8673
|
payload.issues.push({
|
|
8568
8674
|
code: "too_big",
|
|
8569
|
-
maximum:
|
|
8675
|
+
maximum: items2.length,
|
|
8570
8676
|
inclusive: true,
|
|
8571
8677
|
input: input2,
|
|
8572
8678
|
inst,
|
|
@@ -8574,11 +8680,11 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
8574
8680
|
});
|
|
8575
8681
|
}
|
|
8576
8682
|
}
|
|
8577
|
-
const itemResults = new Array(
|
|
8683
|
+
const itemResults = new Array(items2.length);
|
|
8578
8684
|
const abortEarly = def.rest ? ctx?.abortEarly : void 0;
|
|
8579
8685
|
let itemAborted = false;
|
|
8580
|
-
for (let i = 0; i <
|
|
8581
|
-
const r =
|
|
8686
|
+
for (let i = 0; i < items2.length; i++) {
|
|
8687
|
+
const r = items2[i]._zod.run({ value: input2[i], issues: [] }, ctx);
|
|
8582
8688
|
if (r instanceof Promise) {
|
|
8583
8689
|
proms.push(r.then((rr) => {
|
|
8584
8690
|
itemResults[i] = rr;
|
|
@@ -8590,8 +8696,8 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
8590
8696
|
}
|
|
8591
8697
|
}
|
|
8592
8698
|
if (def.rest && !itemAborted) {
|
|
8593
|
-
let i =
|
|
8594
|
-
const rest = input2.slice(
|
|
8699
|
+
let i = items2.length - 1;
|
|
8700
|
+
const rest = input2.slice(items2.length);
|
|
8595
8701
|
let seen = payload.issues.length;
|
|
8596
8702
|
for (const el of rest) {
|
|
8597
8703
|
if (abortEarly && payload.issues.length !== seen) {
|
|
@@ -8609,14 +8715,14 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
8609
8715
|
}
|
|
8610
8716
|
}
|
|
8611
8717
|
if (proms.length) {
|
|
8612
|
-
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload,
|
|
8718
|
+
return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items2, input2, optoutStart));
|
|
8613
8719
|
}
|
|
8614
|
-
return handleTupleResults(itemResults, payload,
|
|
8720
|
+
return handleTupleResults(itemResults, payload, items2, input2, optoutStart);
|
|
8615
8721
|
};
|
|
8616
8722
|
});
|
|
8617
|
-
function getTupleOptStart(
|
|
8618
|
-
for (let i =
|
|
8619
|
-
const omittable = key === "optin" ?
|
|
8723
|
+
function getTupleOptStart(items2, key) {
|
|
8724
|
+
for (let i = items2.length - 1; i >= 0; i--) {
|
|
8725
|
+
const omittable = key === "optin" ? items2[i]._zod.optin !== void 0 : items2[i]._zod.optout === "optional";
|
|
8620
8726
|
if (!omittable)
|
|
8621
8727
|
return i + 1;
|
|
8622
8728
|
}
|
|
@@ -8628,11 +8734,11 @@ function handleTupleResult(result, final, index) {
|
|
|
8628
8734
|
}
|
|
8629
8735
|
final.value[index] = result.value;
|
|
8630
8736
|
}
|
|
8631
|
-
function handleTupleResults(itemResults, final,
|
|
8632
|
-
for (let i = 0; i <
|
|
8737
|
+
function handleTupleResults(itemResults, final, items2, input2, optoutStart) {
|
|
8738
|
+
for (let i = 0; i < items2.length; i++) {
|
|
8633
8739
|
const r = itemResults[i];
|
|
8634
8740
|
const isPresent = i < input2.length;
|
|
8635
|
-
if (!isPresent && i >= optoutStart &&
|
|
8741
|
+
if (!isPresent && i >= optoutStart && items2[i]._zod.optin === "optional") {
|
|
8636
8742
|
final.value.length = i;
|
|
8637
8743
|
break;
|
|
8638
8744
|
}
|
|
@@ -8646,7 +8752,7 @@ function handleTupleResults(itemResults, final, items, input2, optoutStart) {
|
|
|
8646
8752
|
final.value[i] = r.value;
|
|
8647
8753
|
}
|
|
8648
8754
|
for (let i = final.value.length - 1; i >= input2.length; i--) {
|
|
8649
|
-
if (
|
|
8755
|
+
if (items2[i]._zod.optout === "optional" && final.value[i] === void 0) {
|
|
8650
8756
|
final.value.length = i;
|
|
8651
8757
|
} else {
|
|
8652
8758
|
break;
|
|
@@ -9685,9 +9791,9 @@ var memo = {
|
|
|
9685
9791
|
if (!bucket)
|
|
9686
9792
|
return empty;
|
|
9687
9793
|
handoff = void 0;
|
|
9688
|
-
const
|
|
9689
|
-
bucket.set(payload.value,
|
|
9690
|
-
open.push(
|
|
9794
|
+
const entry2 = { value: empty, issues: null };
|
|
9795
|
+
bucket.set(payload.value, entry2);
|
|
9796
|
+
open.push(entry2);
|
|
9691
9797
|
return empty;
|
|
9692
9798
|
},
|
|
9693
9799
|
guard(inst) {
|
|
@@ -9761,16 +9867,16 @@ var memo = {
|
|
|
9761
9867
|
const depth = open.length;
|
|
9762
9868
|
const result = base(payload, ctx);
|
|
9763
9869
|
handoff = void 0;
|
|
9764
|
-
const
|
|
9870
|
+
const entry2 = open.length > depth ? open.pop() : void 0;
|
|
9765
9871
|
if (result instanceof Promise) {
|
|
9766
9872
|
return result.then((r) => {
|
|
9767
|
-
if (
|
|
9768
|
-
|
|
9873
|
+
if (entry2)
|
|
9874
|
+
entry2.issues = r.issues.length ? cloneIssues(r.issues) : NO_ISSUES;
|
|
9769
9875
|
return r;
|
|
9770
9876
|
});
|
|
9771
9877
|
}
|
|
9772
|
-
if (
|
|
9773
|
-
|
|
9878
|
+
if (entry2)
|
|
9879
|
+
entry2.issues = result.issues.length ? cloneIssues(result.issues) : NO_ISSUES;
|
|
9774
9880
|
return result;
|
|
9775
9881
|
};
|
|
9776
9882
|
inst._zod.parse = wrapped;
|
|
@@ -12201,16 +12307,16 @@ var error20 = () => {
|
|
|
12201
12307
|
number: { unit: "", shortLabel: "\u05E7\u05D8\u05DF", longLabel: "\u05D2\u05D3\u05D5\u05DC" }
|
|
12202
12308
|
// no unit
|
|
12203
12309
|
};
|
|
12204
|
-
const typeEntry = (
|
|
12205
|
-
const typeLabel = (
|
|
12206
|
-
const e = typeEntry(
|
|
12310
|
+
const typeEntry = (t3) => t3 ? TypeNames[t3] : void 0;
|
|
12311
|
+
const typeLabel = (t3) => {
|
|
12312
|
+
const e = typeEntry(t3);
|
|
12207
12313
|
if (e)
|
|
12208
12314
|
return e.label;
|
|
12209
|
-
return
|
|
12315
|
+
return t3 ?? TypeNames.unknown.label;
|
|
12210
12316
|
};
|
|
12211
|
-
const withDefinite = (
|
|
12212
|
-
const verbFor = (
|
|
12213
|
-
const e = typeEntry(
|
|
12317
|
+
const withDefinite = (t3) => `\u05D4${typeLabel(t3)}`;
|
|
12318
|
+
const verbFor = (t3) => {
|
|
12319
|
+
const e = typeEntry(t3);
|
|
12214
12320
|
const gender = e?.gender ?? "m";
|
|
12215
12321
|
return gender === "f" ? "\u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05D9\u05D5\u05EA" : "\u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA";
|
|
12216
12322
|
};
|
|
@@ -18554,20 +18660,20 @@ function generateNonOptionalCheck(doc, ctx, schema, accessor) {
|
|
|
18554
18660
|
}
|
|
18555
18661
|
function generateTupleCheck(doc, ctx, schema, accessor) {
|
|
18556
18662
|
const def = schema._zod.def;
|
|
18557
|
-
const
|
|
18663
|
+
const items2 = def.items;
|
|
18558
18664
|
const rest = def.rest;
|
|
18559
18665
|
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
18560
|
-
const optinStart = getTupleOptStart2(
|
|
18561
|
-
const optoutStart = getTupleOptStart2(
|
|
18666
|
+
const optinStart = getTupleOptStart2(items2, "optin");
|
|
18667
|
+
const optoutStart = getTupleOptStart2(items2, "optout");
|
|
18562
18668
|
if (rest) {
|
|
18563
18669
|
doc.write(`if (${accessor}.length < ${optinStart}) return INVALID;`);
|
|
18564
18670
|
} else {
|
|
18565
|
-
doc.write(`if (${accessor}.length < ${optinStart} || ${accessor}.length > ${
|
|
18671
|
+
doc.write(`if (${accessor}.length < ${optinStart} || ${accessor}.length > ${items2.length}) return INVALID;`);
|
|
18566
18672
|
}
|
|
18567
18673
|
const outputVar = newVar(ctx);
|
|
18568
18674
|
doc.write(`const ${outputVar} = [];`);
|
|
18569
|
-
for (let i = 0; i <
|
|
18570
|
-
const itemSchema =
|
|
18675
|
+
for (let i = 0; i < items2.length; i++) {
|
|
18676
|
+
const itemSchema = items2[i];
|
|
18571
18677
|
if (i >= optoutStart) {
|
|
18572
18678
|
doc.write(`if (${outputVar}.length === ${i}) {`);
|
|
18573
18679
|
doc.indented((d) => {
|
|
@@ -18609,7 +18715,7 @@ function generateTupleCheck(doc, ctx, schema, accessor) {
|
|
|
18609
18715
|
if (rest) {
|
|
18610
18716
|
const iVar = newVar(ctx);
|
|
18611
18717
|
const elemVar = newVar(ctx);
|
|
18612
|
-
doc.write(`for (let ${iVar} = ${
|
|
18718
|
+
doc.write(`for (let ${iVar} = ${items2.length}; ${iVar} < ${accessor}.length; ${iVar}++) {`);
|
|
18613
18719
|
doc.indented((d) => {
|
|
18614
18720
|
d.write(`const ${elemVar} = ${accessor}[${iVar}];`);
|
|
18615
18721
|
const elemOutput = compileChild(d, ctx, rest, elemVar);
|
|
@@ -18619,9 +18725,9 @@ function generateTupleCheck(doc, ctx, schema, accessor) {
|
|
|
18619
18725
|
}
|
|
18620
18726
|
return outputVar;
|
|
18621
18727
|
}
|
|
18622
|
-
function getTupleOptStart2(
|
|
18623
|
-
for (let i =
|
|
18624
|
-
const omittable = key === "optin" ?
|
|
18728
|
+
function getTupleOptStart2(items2, key) {
|
|
18729
|
+
for (let i = items2.length - 1; i >= 0; i--) {
|
|
18730
|
+
const omittable = key === "optin" ? items2[i]._zod.optin !== void 0 : items2[i]._zod.optout === "optional";
|
|
18625
18731
|
if (!omittable)
|
|
18626
18732
|
return i + 1;
|
|
18627
18733
|
}
|
|
@@ -19755,13 +19861,13 @@ function _intersection(Class2, left, right) {
|
|
|
19755
19861
|
});
|
|
19756
19862
|
}
|
|
19757
19863
|
// @__NO_SIDE_EFFECTS__
|
|
19758
|
-
function _tuple(Class2,
|
|
19864
|
+
function _tuple(Class2, items2, _paramsOrRest, _params) {
|
|
19759
19865
|
const hasRest = _paramsOrRest instanceof $ZodType;
|
|
19760
19866
|
const params = hasRest ? _params : _paramsOrRest;
|
|
19761
19867
|
const rest = hasRest ? _paramsOrRest : null;
|
|
19762
19868
|
return new Class2({
|
|
19763
19869
|
type: "tuple",
|
|
19764
|
-
items,
|
|
19870
|
+
items: items2,
|
|
19765
19871
|
rest,
|
|
19766
19872
|
...normalizeParams(params)
|
|
19767
19873
|
});
|
|
@@ -20176,42 +20282,42 @@ function extractDefs(ctx, schema) {
|
|
|
20176
20282
|
if (ctx.external && ctx.sharedDefsExtractedFor === ctx.external)
|
|
20177
20283
|
return;
|
|
20178
20284
|
const idToSchema = /* @__PURE__ */ new Map();
|
|
20179
|
-
for (const
|
|
20180
|
-
const id = ctx.metadataRegistry.get(
|
|
20285
|
+
for (const entry2 of ctx.seen.entries()) {
|
|
20286
|
+
const id = ctx.metadataRegistry.get(entry2[0])?.id;
|
|
20181
20287
|
if (id) {
|
|
20182
20288
|
const existing = idToSchema.get(id);
|
|
20183
|
-
if (existing && existing !==
|
|
20289
|
+
if (existing && existing !== entry2[0]) {
|
|
20184
20290
|
throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
|
|
20185
20291
|
}
|
|
20186
|
-
idToSchema.set(id,
|
|
20292
|
+
idToSchema.set(id, entry2[0]);
|
|
20187
20293
|
}
|
|
20188
20294
|
}
|
|
20189
|
-
const makeURI = (
|
|
20295
|
+
const makeURI = (entry2) => {
|
|
20190
20296
|
const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
20191
20297
|
if (ctx.external) {
|
|
20192
|
-
const externalId = ctx.external.registry.get(
|
|
20298
|
+
const externalId = ctx.external.registry.get(entry2[0])?.id;
|
|
20193
20299
|
const uriGenerator = ctx.external.uri ?? ((id2) => id2);
|
|
20194
20300
|
if (externalId) {
|
|
20195
20301
|
return { ref: uriGenerator(externalId) };
|
|
20196
20302
|
}
|
|
20197
|
-
const id =
|
|
20198
|
-
|
|
20303
|
+
const id = entry2[1].defId ?? entry2[1].schema.id ?? `schema${ctx.counter++}`;
|
|
20304
|
+
entry2[1].defId = id;
|
|
20199
20305
|
return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id)}` };
|
|
20200
20306
|
}
|
|
20201
20307
|
const uriPrefix = `#`;
|
|
20202
20308
|
const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
|
|
20203
|
-
if (
|
|
20309
|
+
if (entry2[1] === root && !entry2[1].schema.id) {
|
|
20204
20310
|
return { ref: uriPrefix };
|
|
20205
20311
|
}
|
|
20206
|
-
const defId =
|
|
20312
|
+
const defId = entry2[1].schema.id ?? `__schema${ctx.counter++}`;
|
|
20207
20313
|
return { defId, ref: defUriPrefix + encodeJSONPointerSegment(defId) };
|
|
20208
20314
|
};
|
|
20209
|
-
const extractToDef = (
|
|
20210
|
-
if (
|
|
20315
|
+
const extractToDef = (entry2) => {
|
|
20316
|
+
if (entry2[1].schema.$ref) {
|
|
20211
20317
|
return;
|
|
20212
20318
|
}
|
|
20213
|
-
const seen =
|
|
20214
|
-
const { ref, defId } = makeURI(
|
|
20319
|
+
const seen = entry2[1];
|
|
20320
|
+
const { ref, defId } = makeURI(entry2);
|
|
20215
20321
|
seen.def = { ...seen.schema };
|
|
20216
20322
|
if (defId)
|
|
20217
20323
|
seen.defId = defId;
|
|
@@ -20222,8 +20328,8 @@ function extractDefs(ctx, schema) {
|
|
|
20222
20328
|
schema2.$ref = ref;
|
|
20223
20329
|
};
|
|
20224
20330
|
if (ctx.cycles === "throw") {
|
|
20225
|
-
for (const
|
|
20226
|
-
const seen =
|
|
20331
|
+
for (const entry2 of ctx.seen.entries()) {
|
|
20332
|
+
const seen = entry2[1];
|
|
20227
20333
|
if (seen.cycle) {
|
|
20228
20334
|
throw new Error(`Cycle detected: #/${seen.cycle?.join("/")}/<root>
|
|
20229
20335
|
|
|
@@ -20231,31 +20337,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
20231
20337
|
}
|
|
20232
20338
|
}
|
|
20233
20339
|
}
|
|
20234
|
-
for (const
|
|
20235
|
-
const seen =
|
|
20236
|
-
if (schema ===
|
|
20237
|
-
extractToDef(
|
|
20340
|
+
for (const entry2 of ctx.seen.entries()) {
|
|
20341
|
+
const seen = entry2[1];
|
|
20342
|
+
if (schema === entry2[0]) {
|
|
20343
|
+
extractToDef(entry2);
|
|
20238
20344
|
continue;
|
|
20239
20345
|
}
|
|
20240
20346
|
if (ctx.external) {
|
|
20241
|
-
const ext = ctx.external.registry.get(
|
|
20242
|
-
if (schema !==
|
|
20243
|
-
extractToDef(
|
|
20347
|
+
const ext = ctx.external.registry.get(entry2[0])?.id;
|
|
20348
|
+
if (schema !== entry2[0] && ext) {
|
|
20349
|
+
extractToDef(entry2);
|
|
20244
20350
|
continue;
|
|
20245
20351
|
}
|
|
20246
20352
|
}
|
|
20247
|
-
const id = ctx.metadataRegistry.get(
|
|
20353
|
+
const id = ctx.metadataRegistry.get(entry2[0])?.id;
|
|
20248
20354
|
if (id) {
|
|
20249
|
-
extractToDef(
|
|
20355
|
+
extractToDef(entry2);
|
|
20250
20356
|
continue;
|
|
20251
20357
|
}
|
|
20252
20358
|
if (seen.cycle) {
|
|
20253
|
-
extractToDef(
|
|
20359
|
+
extractToDef(entry2);
|
|
20254
20360
|
continue;
|
|
20255
20361
|
}
|
|
20256
20362
|
if (seen.count > 1) {
|
|
20257
20363
|
if (ctx.reused === "ref") {
|
|
20258
|
-
extractToDef(
|
|
20364
|
+
extractToDef(entry2);
|
|
20259
20365
|
}
|
|
20260
20366
|
}
|
|
20261
20367
|
}
|
|
@@ -20437,12 +20543,12 @@ function finalize(ctx, schema) {
|
|
|
20437
20543
|
});
|
|
20438
20544
|
};
|
|
20439
20545
|
if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) {
|
|
20440
|
-
for (const
|
|
20441
|
-
flattenRef(
|
|
20546
|
+
for (const entry2 of [...ctx.seen.entries()].reverse()) {
|
|
20547
|
+
flattenRef(entry2[0]);
|
|
20442
20548
|
}
|
|
20443
20549
|
if (ctx.target !== "openapi-3.0") {
|
|
20444
|
-
for (const
|
|
20445
|
-
compactTypeUnion(
|
|
20550
|
+
for (const entry2 of ctx.seen.entries()) {
|
|
20551
|
+
compactTypeUnion(entry2[1].def ?? entry2[1].schema);
|
|
20446
20552
|
}
|
|
20447
20553
|
}
|
|
20448
20554
|
for (const rewrite of ctx.deferred)
|
|
@@ -20489,8 +20595,8 @@ function finalize(ctx, schema) {
|
|
|
20489
20595
|
delete result.id;
|
|
20490
20596
|
const defs = ctx.external?.defs ?? {};
|
|
20491
20597
|
if (!ctx.external || ctx.sharedEmitDoneFor !== ctx.external) {
|
|
20492
|
-
for (const
|
|
20493
|
-
const seen =
|
|
20598
|
+
for (const entry2 of ctx.seen.entries()) {
|
|
20599
|
+
const seen = entry2[1];
|
|
20494
20600
|
if (seen.def && seen.defId) {
|
|
20495
20601
|
if (seen.def.id === seen.defId)
|
|
20496
20602
|
delete seen.def.id;
|
|
@@ -21083,7 +21189,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
21083
21189
|
json2 = { ...json2, [keyword]: mapped };
|
|
21084
21190
|
}
|
|
21085
21191
|
const types = Array.isArray(json2.type) ? json2.type : [json2.type];
|
|
21086
|
-
const numericType = !types.includes("string") && types.some((
|
|
21192
|
+
const numericType = !types.includes("string") && types.some((t3) => t3 === "number" || t3 === "integer");
|
|
21087
21193
|
const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
|
|
21088
21194
|
if (!numericType && !values?.some((v) => typeof v === "number"))
|
|
21089
21195
|
return json2;
|
|
@@ -21102,9 +21208,9 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
21102
21208
|
var pendingRecords = /* @__PURE__ */ new WeakMap();
|
|
21103
21209
|
function rewriteKeyNames(ctx) {
|
|
21104
21210
|
const bySchema = /* @__PURE__ */ new Map();
|
|
21105
|
-
for (const
|
|
21106
|
-
if (
|
|
21107
|
-
bySchema.set(
|
|
21211
|
+
for (const entry2 of ctx.seen.values()) {
|
|
21212
|
+
if (entry2.def && !bySchema.has(entry2.schema))
|
|
21213
|
+
bySchema.set(entry2.schema, entry2);
|
|
21108
21214
|
}
|
|
21109
21215
|
const rewrites = /* @__PURE__ */ new Map();
|
|
21110
21216
|
for (const record3 of pendingRecords.get(ctx) ?? []) {
|
|
@@ -21118,8 +21224,8 @@ function rewriteKeyNames(ctx) {
|
|
|
21118
21224
|
}
|
|
21119
21225
|
if (!rewrites.size)
|
|
21120
21226
|
return;
|
|
21121
|
-
for (const
|
|
21122
|
-
for (const carrier of [
|
|
21227
|
+
for (const entry2 of ctx.seen.values()) {
|
|
21228
|
+
for (const carrier of [entry2.schema, entry2.def]) {
|
|
21123
21229
|
const rewritten = carrier && rewrites.get(carrier.propertyNames);
|
|
21124
21230
|
if (rewritten)
|
|
21125
21231
|
carrier.propertyNames = rewritten;
|
|
@@ -21313,8 +21419,8 @@ function toJSONSchema(input2, params) {
|
|
|
21313
21419
|
const registry2 = input2;
|
|
21314
21420
|
const ctx2 = initializeContext({ ...params, processors: allProcessors });
|
|
21315
21421
|
const defs = {};
|
|
21316
|
-
for (const
|
|
21317
|
-
const [_, schema] =
|
|
21422
|
+
for (const entry2 of registry2._idmap.entries()) {
|
|
21423
|
+
const [_, schema] = entry2;
|
|
21318
21424
|
processSchema(schema, ctx2);
|
|
21319
21425
|
}
|
|
21320
21426
|
const schemas = {};
|
|
@@ -21324,8 +21430,8 @@ function toJSONSchema(input2, params) {
|
|
|
21324
21430
|
defs
|
|
21325
21431
|
};
|
|
21326
21432
|
ctx2.external = external;
|
|
21327
|
-
for (const
|
|
21328
|
-
const [key, schema] =
|
|
21433
|
+
for (const entry2 of registry2._idmap.entries()) {
|
|
21434
|
+
const [key, schema] = entry2;
|
|
21329
21435
|
extractDefs(ctx2, schema);
|
|
21330
21436
|
assignProp(schemas, key, finalize(ctx2, schema));
|
|
21331
21437
|
}
|
|
@@ -22659,13 +22765,13 @@ var ZodTuple = /* @__PURE__ */ $constructor("ZodTuple", (inst, def) => {
|
|
|
22659
22765
|
});
|
|
22660
22766
|
}
|
|
22661
22767
|
});
|
|
22662
|
-
function tuple(
|
|
22768
|
+
function tuple(items2, _paramsOrRest, _params) {
|
|
22663
22769
|
const hasRest = _paramsOrRest instanceof $ZodType;
|
|
22664
22770
|
const params = hasRest ? _params : _paramsOrRest;
|
|
22665
22771
|
const rest = hasRest ? _paramsOrRest : null;
|
|
22666
22772
|
return new ZodTuple({
|
|
22667
22773
|
type: "tuple",
|
|
22668
|
-
items,
|
|
22774
|
+
items: items2,
|
|
22669
22775
|
rest,
|
|
22670
22776
|
...util_exports.normalizeParams(params)
|
|
22671
22777
|
});
|
|
@@ -23306,8 +23412,8 @@ function detectVersion(schema, defaultTarget) {
|
|
|
23306
23412
|
}
|
|
23307
23413
|
return defaultTarget ?? "draft-2020-12";
|
|
23308
23414
|
}
|
|
23309
|
-
function applyMinItems(
|
|
23310
|
-
return
|
|
23415
|
+
function applyMinItems(items2, minItems) {
|
|
23416
|
+
return items2.map((item, index) => index < minItems ? item : item.optional());
|
|
23311
23417
|
}
|
|
23312
23418
|
function decodeJSONPointerSegment(segment) {
|
|
23313
23419
|
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
@@ -23461,13 +23567,13 @@ function plural(n) {
|
|
|
23461
23567
|
}
|
|
23462
23568
|
function checkArrayGuards(arraySchema, guards) {
|
|
23463
23569
|
const guard = z.transform((value) => value).check((payload) => {
|
|
23464
|
-
const
|
|
23465
|
-
if (!Array.isArray(
|
|
23570
|
+
const items2 = payload.value;
|
|
23571
|
+
if (!Array.isArray(items2))
|
|
23466
23572
|
return;
|
|
23467
23573
|
if (guards.uniqueItems === true) {
|
|
23468
23574
|
const firstSeen = /* @__PURE__ */ new Map();
|
|
23469
|
-
for (let i = 0; i <
|
|
23470
|
-
const key = canonicalKey(
|
|
23575
|
+
for (let i = 0; i < items2.length; i++) {
|
|
23576
|
+
const key = canonicalKey(items2[i], /* @__PURE__ */ new Set());
|
|
23471
23577
|
if (key === null)
|
|
23472
23578
|
continue;
|
|
23473
23579
|
const first = firstSeen.get(key);
|
|
@@ -23478,7 +23584,7 @@ function checkArrayGuards(arraySchema, guards) {
|
|
|
23478
23584
|
payload.issues.push({
|
|
23479
23585
|
code: "custom",
|
|
23480
23586
|
message: `Array items must be unique: element at index ${i} duplicates the one at index ${first}`,
|
|
23481
|
-
input:
|
|
23587
|
+
input: items2,
|
|
23482
23588
|
path: [i],
|
|
23483
23589
|
continue: true
|
|
23484
23590
|
});
|
|
@@ -23488,7 +23594,7 @@ function checkArrayGuards(arraySchema, guards) {
|
|
|
23488
23594
|
const minContains = guards.minContains ?? 1;
|
|
23489
23595
|
const ceiling = guards.maxContains !== void 0 ? guards.maxContains + 1 : Number.POSITIVE_INFINITY;
|
|
23490
23596
|
let matches = 0;
|
|
23491
|
-
for (const item of
|
|
23597
|
+
for (const item of items2) {
|
|
23492
23598
|
if (guards.containsSchema.safeParse(item).success && ++matches >= ceiling)
|
|
23493
23599
|
break;
|
|
23494
23600
|
}
|
|
@@ -23496,7 +23602,7 @@ function checkArrayGuards(arraySchema, guards) {
|
|
|
23496
23602
|
payload.issues.push({
|
|
23497
23603
|
code: "custom",
|
|
23498
23604
|
message: `Array must contain at least ${minContains} matching ${plural(minContains)}; found ${matches}`,
|
|
23499
|
-
input:
|
|
23605
|
+
input: items2,
|
|
23500
23606
|
continue: true
|
|
23501
23607
|
});
|
|
23502
23608
|
}
|
|
@@ -23504,7 +23610,7 @@ function checkArrayGuards(arraySchema, guards) {
|
|
|
23504
23610
|
payload.issues.push({
|
|
23505
23611
|
code: "custom",
|
|
23506
23612
|
message: `Array must contain at most ${guards.maxContains} matching ${plural(guards.maxContains)}`,
|
|
23507
|
-
input:
|
|
23613
|
+
input: items2,
|
|
23508
23614
|
continue: true
|
|
23509
23615
|
});
|
|
23510
23616
|
}
|
|
@@ -23586,8 +23692,8 @@ function convertBaseSchema(schema, ctx) {
|
|
|
23586
23692
|
}
|
|
23587
23693
|
const type = schema.type;
|
|
23588
23694
|
if (Array.isArray(type)) {
|
|
23589
|
-
const typeSchemas = type.map((
|
|
23590
|
-
const typeSchema = { ...schema, type:
|
|
23695
|
+
const typeSchemas = type.map((t3) => {
|
|
23696
|
+
const typeSchema = { ...schema, type: t3 };
|
|
23591
23697
|
return convertBaseSchema(typeSchema, ctx);
|
|
23592
23698
|
});
|
|
23593
23699
|
if (typeSchemas.length === 0) {
|
|
@@ -23790,12 +23896,12 @@ function convertBaseSchema(schema, ctx) {
|
|
|
23790
23896
|
}
|
|
23791
23897
|
case "array": {
|
|
23792
23898
|
const prefixItems = schema.prefixItems;
|
|
23793
|
-
const
|
|
23899
|
+
const items2 = schema.items;
|
|
23794
23900
|
if (prefixItems && Array.isArray(prefixItems)) {
|
|
23795
23901
|
const minItems = typeof schema.minItems === "number" ? schema.minItems : 0;
|
|
23796
23902
|
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
|
23797
23903
|
const positionalItems = applyMinItems(tupleItems, minItems);
|
|
23798
|
-
const rest = !Array.isArray(
|
|
23904
|
+
const rest = !Array.isArray(items2) ? getTupleRest(items2, ctx) : void 0;
|
|
23799
23905
|
const tupleSchema = z.tuple(positionalItems);
|
|
23800
23906
|
zodSchema = rest ? tupleSchema.rest(rest) : tupleSchema;
|
|
23801
23907
|
if (typeof schema.minItems === "number") {
|
|
@@ -23804,9 +23910,9 @@ function convertBaseSchema(schema, ctx) {
|
|
|
23804
23910
|
if (typeof schema.maxItems === "number") {
|
|
23805
23911
|
zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
|
|
23806
23912
|
}
|
|
23807
|
-
} else if (Array.isArray(
|
|
23913
|
+
} else if (Array.isArray(items2)) {
|
|
23808
23914
|
const minItems = typeof schema.minItems === "number" ? schema.minItems : 0;
|
|
23809
|
-
const tupleItems =
|
|
23915
|
+
const tupleItems = items2.map((item) => convertSchema(item, ctx));
|
|
23810
23916
|
const positionalItems = applyMinItems(tupleItems, minItems);
|
|
23811
23917
|
const rest = getTupleRest(schema.additionalItems, ctx);
|
|
23812
23918
|
const tupleSchema = z.tuple(positionalItems);
|
|
@@ -23817,8 +23923,8 @@ function convertBaseSchema(schema, ctx) {
|
|
|
23817
23923
|
if (typeof schema.maxItems === "number") {
|
|
23818
23924
|
zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
|
|
23819
23925
|
}
|
|
23820
|
-
} else if (
|
|
23821
|
-
const element = convertSchema(
|
|
23926
|
+
} else if (items2 !== void 0) {
|
|
23927
|
+
const element = convertSchema(items2, ctx);
|
|
23822
23928
|
let arraySchema = z.array(element);
|
|
23823
23929
|
if (typeof schema.minItems === "number") {
|
|
23824
23930
|
arraySchema = arraySchema.min(schema.minItems);
|
|
@@ -24358,6 +24464,269 @@ var browserSpecsV1 = external_exports.strictObject({
|
|
|
24358
24464
|
boundary: external_exports.boolean()
|
|
24359
24465
|
});
|
|
24360
24466
|
|
|
24467
|
+
// ../../packages/contracts/dist/versions/changelog-v1.js
|
|
24468
|
+
var items = external_exports.array(external_exports.string().min(1));
|
|
24469
|
+
var entry = external_exports.strictObject({
|
|
24470
|
+
version: external_exports.string().regex(/^\d+\.\d+\.\d+$/),
|
|
24471
|
+
date: external_exports.iso.date(),
|
|
24472
|
+
added: items,
|
|
24473
|
+
changed: items,
|
|
24474
|
+
removed: items,
|
|
24475
|
+
fixed: items
|
|
24476
|
+
}).refine((value) => value.added.length + value.changed.length + value.removed.length + value.fixed.length > 0, "A version must list at least one change.");
|
|
24477
|
+
var changelogV1 = external_exports.strictObject({
|
|
24478
|
+
contract: external_exports.literal("changelog"),
|
|
24479
|
+
version: external_exports.literal(1),
|
|
24480
|
+
language: external_exports.string().regex(/^[a-z]{2}(?:-[A-Z]{2})?$/),
|
|
24481
|
+
fallback: external_exports.boolean(),
|
|
24482
|
+
entries: external_exports.array(entry)
|
|
24483
|
+
}).superRefine((value, context2) => {
|
|
24484
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24485
|
+
for (const [index, item] of value.entries.entries()) {
|
|
24486
|
+
if (seen.has(item.version))
|
|
24487
|
+
context2.addIssue({ code: "custom", path: ["entries", index, "version"], message: "Duplicate version." });
|
|
24488
|
+
seen.add(item.version);
|
|
24489
|
+
}
|
|
24490
|
+
});
|
|
24491
|
+
|
|
24492
|
+
// src/shared/i18n/ko/messages.json
|
|
24493
|
+
var messages_default2 = {
|
|
24494
|
+
"help.program": "\uD504\uB85C\uC81D\uD2B8\uC758 \uC694\uAD6C\uC0AC\uD56D\uACFC \uACB0\uC815 \uC774\uB825\uC744 Git\uC5D0 \uB0A8\uAE30\uB294 \uB3C4\uAD6C",
|
|
24495
|
+
"help.notYet": "\uC804\uCCB4 \uC774\uB825 \uAC80\uC0AC\uC640 GUI \uC694\uAD6C\uC0AC\uD56D \uD3B8\uC9D1\uC740 \uC544\uC9C1 \uC81C\uACF5\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24496
|
+
"help.status": "\uD604\uC7AC checkout\uC758 Git \uC0C1\uD0DC \uC870\uD68C (gitifact \uAC80\uC0AC \uBBF8\uC2E4\uD589)",
|
|
24497
|
+
"help.format": "\uCD9C\uB825 \uD615\uC2DD",
|
|
24498
|
+
"help.browser": "\uD604\uC7AC checkout\uC758 Git \uC0C1\uD0DC\uB97C \uB85C\uCEEC \uBE0C\uB77C\uC6B0\uC800\uB85C \uC870\uD68C",
|
|
24499
|
+
"help.browserPort": "\uC218\uC2E0 \uD3EC\uD2B8 (0\uC740 \uC790\uB3D9 \uC120\uD0DD)",
|
|
24500
|
+
"help.browserDev": "Vite \uAC1C\uBC1C \uC11C\uBC84 Origin \uD5C8\uC6A9",
|
|
24501
|
+
"help.init": "\uD504\uB85C\uC81D\uD2B8 \uC124\uC815\xB7\uAE30\uC900\uC120 \uC0DD\uC131\uACFC \uC5D0\uC774\uC804\uD2B8 \uC9C0\uCE68 \uD30C\uC77C\uC758 GITIFACT \uBE14\uB85D \uC124\uCE58 (\uC7AC\uC2E4\uD589 \uC2DC \uBE14\uB85D \uAC31\uC2E0)",
|
|
24502
|
+
"help.initDryRun": "\uD30C\uC77C\uC744 \uB9CC\uB4E4\uC9C0 \uC54A\uACE0 \uCD08\uAE30\uD654 \uACC4\uD68D \uD655\uC778",
|
|
24503
|
+
"help.initAgent": "\uC9C0\uCE68 \uD30C\uC77C \uB300\uC0C1 (\uAE30\uBCF8: \uAE30\uC874 \uD30C\uC77C \uC804\uBD80, \uC5C6\uC73C\uBA74 AGENTS.md)",
|
|
24504
|
+
"help.initRemoveAgents": "GITIFACT \uBE14\uB85D\uC744 \uC81C\uAC70",
|
|
24505
|
+
"help.initSkipAgents": "\uC9C0\uCE68 \uD30C\uC77C\uC744 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uC74C",
|
|
24506
|
+
"help.docs": "\uC5D0\uC774\uC804\uD2B8\uC6A9 \uC791\uC5C5 \uC9C0\uCE68 \uCD9C\uB825 (\uC8FC\uC81C \uC5C6\uC774 \uC2E4\uD589\uD558\uBA74 \uBAA9\uB85D)",
|
|
24507
|
+
"help.docsTopic": "workflow, spec, design, product, commit \uC911 \uD558\uB098",
|
|
24508
|
+
"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)",
|
|
24509
|
+
"help.migrateDryRun": "\uD30C\uC77C\uC744 \uBC14\uAFB8\uC9C0 \uC54A\uACE0 \uC804\uD658 \uACC4\uD68D \uD655\uC778",
|
|
24510
|
+
"help.spec": "Markdown \uBA85\uC138 \uC791\uC131\xB7\uC870\uD68C\xB7Git \uAE30\uB85D",
|
|
24511
|
+
"help.deprecated": "Deprecated: 0.6.0\uC5D0\uC11C \uC81C\uAC70 \uC608\uC815. spec commit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
24512
|
+
"help.specCommit": "\uBCC0\uACBD \uC774\uC720 \uAE30\uB85D\uACFC \uAD00\uB828 \uD30C\uC77C \uCEE4\uBC0B\uC744 \uD55C \uBC88\uC5D0 \uC2E4\uD589",
|
|
24513
|
+
"help.specCommitFile": "reasons\xB7paths\xB7message\xB7authorization\uC744 \uB2F4\uC740 JSON \uD30C\uC77C",
|
|
24514
|
+
"help.specCommitDryRun": "\uD30C\uC77C\uC744 \uC4F0\uAC70\uB098 \uCEE4\uBC0B\uD558\uC9C0 \uC54A\uACE0 \uACB0\uACFC\uB9CC \uD655\uC778",
|
|
24515
|
+
"help.specCommitPlanFile": "\uCEE4\uBC0B \uC785\uB825 \uB610\uB294 \uACC4\uD68D JSON \uD30C\uC77C",
|
|
24516
|
+
"help.specPrepareFile": "expected\uC640 \uCD5C\uC885 reasons\uB97C \uB2F4\uC740 JSON \uD30C\uC77C",
|
|
24517
|
+
"help.specVerifyFile": "prepare\uC758 verification \uAC1D\uCCB4\uB97C \uB2F4\uC740 JSON \uD30C\uC77C",
|
|
24518
|
+
"help.specVerifyStaged": "index \uC6D0\uBB38\uB3C4 \uBE44\uAD50",
|
|
24519
|
+
"help.specSaveFile": "expected\uC640 operations\uB97C \uB2F4\uC740 UTF-8 JSON \uD30C\uC77C",
|
|
24520
|
+
"help.specReadRef": "\uC77D\uC744 \uCEE4\uBC0B",
|
|
24521
|
+
"help.specDiffFrom": "\uC774\uC804 \uCEE4\uBC0B",
|
|
24522
|
+
"help.specDiffTo": "\uC774\uD6C4 \uCEE4\uBC0B",
|
|
24523
|
+
"help.specChanges": "HEAD \uB300\uBE44 \uCD5C\uC885 \uBA85\uC138 \uCC28\uC774\uC640 \uBBF8\uCEE4\uBC0B \uC774\uC720 \uC870\uD68C",
|
|
24524
|
+
"help.specWorking": "\uD604\uC7AC \uBA85\uC138\xB7\uC81C\uD488\xB7\uC9C0\uCE68 \uC804\uCCB4\uC640 stamp \uC870\uD68C",
|
|
24525
|
+
"help.specSave": "\uC694\uAD6C\uC0AC\uD56D\xB7\uC124\uACC4\xB7\uBB38\uC11C \uC800\uC7A5",
|
|
24526
|
+
"help.specRead": "\uCEE4\uBC0B \uC2DC\uC810\uC758 \uBA85\uC138 \uC870\uD68C",
|
|
24527
|
+
"help.specDiff": "\uB450 \uCEE4\uBC0B \uC0AC\uC774\uC758 \uBA85\uC138 \uBCC0\uACBD \uC870\uD68C",
|
|
24528
|
+
"git.operationInProgress": "Git \uC791\uC5C5\uC774 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4: {marker}",
|
|
24529
|
+
"git.resolveConflicts": "Git \uCDA9\uB3CC\uC744 \uBA3C\uC800 \uD574\uACB0\uD558\uC138\uC694.",
|
|
24530
|
+
"migrate.locked": "\uC7A0\uAE08 \uB610\uB294 \uBCF5\uAD6C \uC790\uB8CC\uAC00 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24531
|
+
"migrate.alreadyMigrated": ".gitifact\uAC00 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4. .tryce\uAC00 \uB0A8\uC544 \uC788\uC73C\uBA74 \uB0B4\uC6A9\uC744 \uBE44\uAD50\uD55C \uB4A4 \uC9C1\uC811 \uC815\uB9AC\uD558\uC138\uC694.",
|
|
24532
|
+
"migrate.nothingToMigrate": ".tryce \uC800\uC7A5\uC18C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24533
|
+
"migrate.notDirectory": ".tryce\uB294 \uB9C1\uD06C\uAC00 \uC544\uB2CC \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
24534
|
+
"migrate.noConfig": ".tryce/config.json\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24535
|
+
"migrate.legacyJson": "\uAD6C\uD615 JSON \uD615\uC2DD\uC740 \uC804\uD658\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAE30\uB85D\uC744 \uBCF4\uC874\uD558\uACE0 \uBCC4\uB3C4 \uC808\uCC28\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24536
|
+
"migrate.extraEntries": ".tryce\uC5D0 config.json\xB7spec \uC678 \uD56D\uBAA9\uC774 \uC788\uC2B5\uB2C8\uB2E4. \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24537
|
+
"migrate.notSpecFolder": "\uBA85\uC138 \uD3F4\uB354\uAC00 \uC544\uB2D9\uB2C8\uB2E4: {feature}",
|
|
24538
|
+
"migrate.unsupportedFile": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBA85\uC138 \uD30C\uC77C\uC785\uB2C8\uB2E4: .tryce/spec/{feature}/{name}",
|
|
24539
|
+
"migrate.fileTooLarge": "\uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uAC70\uB098 1 MiB\uB97C \uB118\uC2B5\uB2C8\uB2E4: {name}",
|
|
24540
|
+
"migrate.nextCommit": "\uBCC0\uACBD\uC744 \uD655\uC778\uD55C \uB4A4 gitifact spec commit\uC73C\uB85C .tryce \uC0AD\uC81C\uC640 .gitifact \uCD94\uAC00\uB97C \uD568\uAED8 \uCEE4\uBC0B\uD558\uC138\uC694.",
|
|
24541
|
+
"migrate.nextLegacyJson": "\uAD6C\uD615 JSON \uBA85\uC138(tryce.json)\uB294 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB0B4\uC6A9\uC744 Markdown \uBA85\uC138\uB85C \uC62E\uAE34 \uB4A4 \uC0AD\uC81C\uB97C spec commit\uC5D0 \uC120\uD0DD\uD558\uC138\uC694.",
|
|
24542
|
+
"migrate.nextSkills": ".agents/skills/tryce-workflow\uC640 .claude \uBCF5\uC0AC\uBCF8\uC774 \uC788\uC73C\uBA74 \uC815\uB9AC\uD558\uACE0 gitifact init\uC744 \uB2E4\uC2DC \uC2E4\uD589\uD574 AGENTS.md \uB4F1\uC758 GITIFACT \uBE14\uB85D\uC744 \uAC31\uC2E0\uD558\uC138\uC694.",
|
|
24543
|
+
"migrate.nextRename": ".gitignore\xB7AGENTS.md\xB7CLAUDE.md\uC758 .tryce\xB7tryce-workflow \uC5B8\uAE09\uC744 \uC0C8 \uC774\uB984\uC73C\uB85C \uB9DE\uCD94\uC138\uC694.",
|
|
24544
|
+
"migrate.failed": "\uC804\uD658\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. .tryce\uC640 .gitifact\uC758 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24545
|
+
"preview.notInitialized": "\uBA3C\uC800 gitifact init\uC73C\uB85C \uCD08\uAE30\uD654\uD558\uC138\uC694.",
|
|
24546
|
+
"preview.legacyProject": "\uAE30\uC874 \uD504\uB85C\uC81D\uD2B8\uB294 \uBCC4\uB3C4 \uC804\uD658\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24547
|
+
"preview.inputFile": "\uC785\uB825\uC740 1 MiB \uC774\uD558\uC758 JSON \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
24548
|
+
"preview.inputSize": "\uC785\uB825 \uD06C\uAE30\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24549
|
+
"preview.inputJson": "\uC785\uB825 \uD30C\uC77C\uC740 UTF-8 JSON\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
24550
|
+
"preview.failed": "\uAC80\uD1A0 \uBA85\uC138 \uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24551
|
+
"initRepo.configIgnored": "\uC124\uC815\uC774 ignore \uADDC\uCE59\uC73C\uB85C \uC81C\uC678\uB429\uB2C8\uB2E4: {rule}",
|
|
24552
|
+
"initRepo.baselineMismatch": "\uAE30\uC900\uC120\uACFC \uD604\uC7AC \uC800\uC7A5\uC18C\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24553
|
+
"initRepo.baselineUnverified": "\uAE30\uC900\uC120 \uCEE4\uBC0B\uC758 \uC874\uC7AC\uC640 \uC870\uC0C1 \uAD00\uACC4\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uAE30\uC900\uC120\uC744 \uBCF4\uC874\uD558\uACE0 \uC774\uB825\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
24554
|
+
"commit.unknownField": "\uC54C \uC218 \uC5C6\uB294 \uCEE4\uBC0B \uC785\uB825 \uD544\uB4DC\uC785\uB2C8\uB2E4.",
|
|
24555
|
+
"commit.authorizationRequired": "\uC0AC\uC6A9\uC790 \uC694\uCCAD \uB610\uB294 \uBA85\uC2DC\uC801 \uC815\uCC45\uC5D0 \uB530\uB978 \uCEE4\uBC0B \uADFC\uAC70\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24556
|
+
"commit.trailerInMessage": "Gitifact \uD2B8\uB808\uC77C\uB7EC\uB294 requirements\uB85C \uC9C0\uC815\uD558\uC138\uC694.",
|
|
24557
|
+
"commit.invalidReferences": "\uC798\uBABB\uB41C \uC694\uAD6C\uC0AC\uD56D \uCC38\uC870\uC785\uB2C8\uB2E4.",
|
|
24558
|
+
"commit.busy": "\uC774\uC804 \uCEE4\uBC0B \uC791\uC5C5 \uB610\uB294 \uBCF5\uAD6C \uC790\uB8CC\uAC00 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24559
|
+
"commit.selectPending": "\uBCC0\uACBD\uB41C \uBA85\uC138\uC640 \uC774\uC720\uB97C \uD568\uAED8 \uC120\uD0DD\uD558\uC138\uC694. \uBBF8\uC120\uD0DD \uBA85\uC138\uB97C \uC790\uB3D9 \uD3EC\uD568\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24560
|
+
"commit.unknownRequirement": "\uC2E4\uC81C \uC694\uAD6C\uC0AC\uD56D ID\uB9CC \uCC38\uC870\uD558\uC138\uC694.",
|
|
24561
|
+
"commit.unexpectedFiles": "\uBE48 \uCEE4\uBC0B \uB610\uB294 \uC120\uD0DD \uBC16 \uD30C\uC77C\uC774 \uAC10\uC9C0\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24562
|
+
"commit.filterChanged": "Git \uD544\uD130\uAC00 \uBA85\uC138\xB7\uC774\uC720 \uC6D0\uBB38\uC744 \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24563
|
+
"commit.specsChangedPreparing": "\uCEE4\uBC0B \uC900\uBE44 \uC911 \uBA85\uC138 \uC9D1\uD569\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24564
|
+
"commit.integrationStarted": "Git \uD1B5\uD569 \uC791\uC5C5\uC774 \uC2DC\uC791\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24565
|
+
"commit.headChanged": "HEAD\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24566
|
+
"commit.resultAltered": "\uCEE4\uBC0B\uC740 \uC2E4\uD589\uB410\uC9C0\uB9CC \uD6C5\xB7\uB3D9\uC2DC \uC791\uC5C5\uC774 \uACB0\uACFC\uB97C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24567
|
+
"commit.indexChangedAfter": "\uCEE4\uBC0B \uD6C4 \uC6D0\uB798 index \uBCC0\uACBD\uC744 \uAC10\uC9C0\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24568
|
+
"commit.hookChangedStaging": "\uD6C5\uC774 \uCEE4\uBC0B \uD6C4 staging\uC744 \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24569
|
+
"commit.expectedType": "expected\uB294 changes\uAC00 \uBC18\uD658\uD55C \uBB38\uC790\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
24570
|
+
"commit.existingStaging": "\uAE30\uC874 staging\uC744 \uBCF4\uC874\uD569\uB2C8\uB2E4. \uC120\uD0DD \uBC94\uC704\uB97C \uC815\uB9AC\uD55C \uD6C4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24571
|
+
"commit.staleInput": "\uC785\uB825\uC774 \uC624\uB798\uB410\uC2B5\uB2C8\uB2E4. changes\uBD80\uD130 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
|
|
24572
|
+
"commit.newlinePath": "\uC904\uBC14\uAFC8\uC774 \uD3EC\uD568\uB41C \uBA85\uC138 \uACBD\uB85C\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24573
|
+
"commit.storedShape": "\uBA85\uC138 \uD30C\uC77C\uC758 Git \uC800\uC7A5 \uD615\uD0DC\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24574
|
+
"commit.indexChanged": "\uC2E4\uD589 \uC911 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24575
|
+
"commit.fileChangedRunning": "\uC2E4\uD589 \uC911 \uD30C\uC77C\xB7\uC815\uCC45\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24576
|
+
"commit.stagedUnreadable": "staging\uB41C \uBA85\uC138\xB7\uC774\uC720\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: {path}",
|
|
24577
|
+
"commit.fileChangedPreparing": "\uCEE4\uBC0B \uC900\uBE44 \uC911 \uD30C\uC77C\xB7\uC815\uCC45\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24578
|
+
"commit.resultUnknown": "\uCEE4\uBC0B \uACB0\uACFC\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24579
|
+
"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}",
|
|
24580
|
+
"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.",
|
|
24581
|
+
"commit.designUseSpecCommit": "\uC124\uACC4 \uBCC0\uACBD\uC740 spec commit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
24582
|
+
"commit.indexChangedPlanning": "\uACC4\uD68D \uC911 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24583
|
+
"commit.planCorrupted": "\uCEE4\uBC0B \uACC4\uD68D\uC774 \uC190\uC0C1\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uACC4\uD68D\uD558\uC138\uC694.",
|
|
24584
|
+
"commit.planScope": "\uACC4\uD68D\uC758 \uC800\uC7A5\uC18C \uB610\uB294 \uD30C\uC77C \uBC94\uC704\uAC00 \uB2E4\uB985\uB2C8\uB2E4.",
|
|
24585
|
+
"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.",
|
|
24586
|
+
"commit.indexChangedLocked": "\uC7A0\uAE08 \uC911 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24587
|
+
"store.legacyLock": "\uC774\uC804 Tryce \uC2E4\uD589\uC758 \uC7A0\uAE08 \uB610\uB294 \uBCF5\uAD6C \uC790\uB8CC\uAC00 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24588
|
+
"store.storeNotDirectory": ".gitifact\uB294 \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
24589
|
+
"store.migrateFirst": ".tryce \uC800\uC7A5\uC18C\uC785\uB2C8\uB2E4. gitifact migrate\uB85C .gitifact\uC5D0 \uC804\uD658\uD55C \uB4A4 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
24590
|
+
"store.legacyProject": "\uAE30\uC874 \uD504\uB85C\uC81D\uD2B8 \uD615\uC2DD\uC740 \uBCC4\uB3C4 \uC804\uD658\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24591
|
+
"store.linkOrSpecial": "\uB9C1\uD06C\xB7\uD2B9\uC218 \uD30C\uC77C\uC740 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {path}",
|
|
24592
|
+
"store.tooManyFiles": "\uBA85\uC138 \uD30C\uC77C \uC218 \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24593
|
+
"store.tooDeep": "\uC911\uCCA9 \uD3F4\uB354 \uAE4A\uC774 \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4: {path}",
|
|
24594
|
+
"store.legacyJson": "\uAE30\uC874 JSON \uD615\uC2DD\uC740 \uC804\uD658\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24595
|
+
"store.unsupportedPath": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBA85\uC138 \uACBD\uB85C\uC785\uB2C8\uB2E4: {path}",
|
|
24596
|
+
"store.hardLinkOrSize": "\uD558\uB4DC \uB9C1\uD06C \uB610\uB294 1 MiB \uD55C\uB3C4\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24597
|
+
"store.sizeLimit": "\uBA85\uC138 \uD06C\uAE30 \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24598
|
+
"store.locked": "\uBA85\uC138 \uC800\uC7A5 \uC7A0\uAE08 \uB610\uB294 \uBCF5\uAD6C \uC790\uB8CC\uAC00 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
24599
|
+
"store.changedWhileReading": "\uC870\uD68C \uC911 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC77D\uC73C\uC138\uC694.",
|
|
24600
|
+
"store.lockedWhileReading": "\uC870\uD68C \uC911 \uC800\uC7A5 \uC7A0\uAE08\uC774 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4.",
|
|
24601
|
+
"store.invalidInput": "\uC800\uC7A5 \uC785\uB825\uC774 \uC798\uBABB\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24602
|
+
"store.expectedOperations": "expected\uC640 operations\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24603
|
+
"store.notDirectory": "\uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4: {path}",
|
|
24604
|
+
"store.staleExpected": "\uC77D\uC740 \uB4A4 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. working\uC73C\uB85C \uB2E4\uC2DC \uC77D\uC73C\uC138\uC694.",
|
|
24605
|
+
"store.unsupportedSavePath": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC800\uC7A5 \uACBD\uB85C\uC785\uB2C8\uB2E4.",
|
|
24606
|
+
"store.fileSizeLimit": "\uBA85\uC138 1 MiB \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24607
|
+
"store.totalLimit": "\uBA85\uC138 \uC804\uCCB4 \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24608
|
+
"store.changedPreparing": "\uC800\uC7A5 \uC900\uBE44 \uC911 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24609
|
+
"store.changedBeforeWrite": "\uC800\uC7A5 \uC9C1\uC804 \uD30C\uC77C\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24610
|
+
"store.changedWhileWriting": "\uC800\uC7A5 \uC911 \uBA85\uC138 \uB610\uB294 \uC124\uC815\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24611
|
+
"store.recoveryIncomplete": "\uC790\uB3D9 \uBCF5\uAD6C\uB97C \uC644\uB8CC\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uB978 \uD3B8\uC9D1\uC744 \uBCF4\uC874\uD588\uC2B5\uB2C8\uB2E4. \uBCF5\uAD6C \uC790\uB8CC: {path}",
|
|
24612
|
+
"server.closing": "\uC11C\uBC84\uB97C \uC885\uB8CC\uD558\uACE0 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
24613
|
+
"server.forbiddenHost": "\uD5C8\uC6A9\uD558\uC9C0 \uC54A\uB294 Host\uC785\uB2C8\uB2E4.",
|
|
24614
|
+
"server.forbiddenOrigin": "\uD5C8\uC6A9\uD558\uC9C0 \uC54A\uB294 Origin\uC785\uB2C8\uB2E4.",
|
|
24615
|
+
"server.badPath": "\uC798\uBABB\uB41C \uACBD\uB85C\uC785\uB2C8\uB2E4.",
|
|
24616
|
+
"server.noBody": "\uC694\uCCAD \uBCF8\uBB38\uC744 \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24617
|
+
"server.crossSite": "\uC678\uBD80 \uD398\uC774\uC9C0\uC758 \uC694\uCCAD\uC744 \uD5C8\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24618
|
+
"server.noQuery": "\uC870\uD68C \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24619
|
+
"server.methodNotAllowed": "\uD5C8\uC6A9\uD558\uC9C0 \uC54A\uB294 \uBA54\uC11C\uB4DC\uC785\uB2C8\uB2E4.",
|
|
24620
|
+
"server.productImageNotFound": "\uC81C\uD488 \uC774\uBBF8\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24621
|
+
"server.apiNotFound": "API\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24622
|
+
"server.sessionChanged": "\uC11C\uBC84 \uC138\uC158\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC5F0\uACB0\uD558\uC138\uC694.",
|
|
24623
|
+
"server.badRange": "\uC870\uD68C \uBC94\uC704\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24624
|
+
"server.specsUnreadable": "\uBA85\uC138\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24625
|
+
"server.refreshOrigin": "\uC0C8\uB85C\uACE0\uCE68\uC5D0\uB294 \uAC19\uC740 \uCD9C\uCC98\uC758 Origin\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24626
|
+
"server.fileNotFound": "\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24627
|
+
"server.internal": "\uC694\uCCAD\uC744 \uCC98\uB9AC\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24628
|
+
"server.portInUse": "\uC694\uCCAD\uD55C \uD3EC\uD2B8\uAC00 \uC0AC\uC6A9 \uC911\uC785\uB2C8\uB2E4. \uB2E4\uB978 \uD3EC\uD2B8\uB97C \uC120\uD0DD\uD558\uC138\uC694.",
|
|
24629
|
+
"server.addressUnknown": "\uC11C\uBC84 \uC8FC\uC18C\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24630
|
+
"reader.gitContextOverride": "Git \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uB36E\uC5B4\uC4F0\uB294 \uD658\uACBD\uC5D0\uC11C\uB294 \uC870\uD68C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24631
|
+
"reader.notUtf8": "UTF-8 \uC6D0\uBB38\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
|
|
24632
|
+
"reader.invalidIndexEntry": "\uC798\uBABB\uB41C index \uD56D\uBAA9\uC785\uB2C8\uB2E4.",
|
|
24633
|
+
"reader.stagingConflictOrLink": "\uBA85\uC138 staging\uC5D0 \uCDA9\uB3CC \uB610\uB294 \uB9C1\uD06C\uAC00 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
24634
|
+
"reader.stagingUnsupported": "\uBA85\uC138 staging\uC5D0 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD30C\uC77C\uC774 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
24635
|
+
"reader.headUnknown": "HEAD\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24636
|
+
"reader.damagedHead": "\uC190\uC0C1\uB41C HEAD\uB97C \uBE48 \uC800\uC7A5\uC18C\uB85C \uCC98\uB9AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24637
|
+
"reader.objectFormat": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 Git \uAC1D\uCCB4 \uD615\uC2DD\uC785\uB2C8\uB2E4.",
|
|
24638
|
+
"reader.commitUnknown": "\uCEE4\uBC0B\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24639
|
+
"reader.invalidTree": "\uC798\uBABB\uB41C Git tree\uC785\uB2C8\uB2E4.",
|
|
24640
|
+
"reader.linkOrSubmodule": "\uBA85\uC138 \uC601\uC5ED\uC5D0 \uB9C1\uD06C \uB610\uB294 \uC11C\uBE0C\uBAA8\uB4C8\uC774 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24641
|
+
"reader.legacyJson": "\uAE30\uC874 JSON \uD615\uC2DD\uC740 req \uBA85\uB839\uC73C\uB85C \uC870\uD68C\uD558\uC138\uC694. \uC774 \uBA85\uB839\uC740 \uC804\uD658\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24642
|
+
"reader.unsupportedEntry": "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uACBD\uB85C \uB610\uB294 \uD30C\uC77C \uC885\uB958: {path}",
|
|
24643
|
+
"reader.mixedStores": "\uACFC\uAC70 \uCEE4\uBC0B\uC5D0 .gitifact\uC640 .tryce \uBA85\uC138\uAC00 \uD568\uAED8 \uC788\uC2B5\uB2C8\uB2E4. \uC804\uD658 \uCEE4\uBC0B\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
24644
|
+
"reader.mixedFormats": "\uACFC\uAC70 \uCEE4\uBC0B\uC5D0 \uC2E0\uAD6C \uBA85\uC138\uAC00 \uD63C\uD569\uB3FC \uC788\uC2B5\uB2C8\uB2E4.",
|
|
24645
|
+
"reader.fileLimit": "\uAC80\uD1A0 \uC870\uD68C \uD30C\uC77C \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24646
|
+
"reader.blobShape": "\uAC80\uD1A0 \uC870\uD68C blob \uD615\uC2DD \uB610\uB294 1 MiB \uD55C\uB3C4\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24647
|
+
"reader.totalLimit": "\uBA85\uC138 \uC804\uCCB4 \uC870\uD68C 16 MiB \uD55C\uB3C4\uB97C \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24648
|
+
"reader.blobBoundary": "Git blob \uC751\uB2F5 \uACBD\uACC4\uAC00 \uB2E4\uB985\uB2C8\uB2E4.",
|
|
24649
|
+
"prepare.integrationInProgress": "Git \uD1B5\uD569 \uC791\uC5C5 \uC911\uC5D0\uB294 \uC2E4\uD5D8\uC6A9 \uCEE4\uBC0B \uC900\uBE44\uB97C \uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24650
|
+
"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.",
|
|
24651
|
+
"prepare.invalidInput": "\uC798\uBABB\uB41C \uC900\uBE44 \uC785\uB825\uC785\uB2C8\uB2E4.",
|
|
24652
|
+
"prepare.expectedReasons": "expected\uC640 reasons\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24653
|
+
"prepare.staleInput": "\uC900\uBE44 \uC785\uB825\uC774 \uC624\uB798\uB410\uC2B5\uB2C8\uB2E4. changes\uBD80\uD130 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.",
|
|
24654
|
+
"prepare.invalidVerifyInput": "\uC798\uBABB\uB41C \uD655\uC778 \uC785\uB825\uC785\uB2C8\uB2E4.",
|
|
24655
|
+
"prepare.verificationRequired": "prepare\uAC00 \uBC18\uD658\uD55C verification \uAC1D\uCCB4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24656
|
+
"prepare.changedAfterPrepare": "\uC900\uBE44 \uB4A4 HEAD \uB610\uB294 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC900\uBE44\uD558\uC138\uC694.",
|
|
24657
|
+
"prepare.stagingScope": "staging\uC758 \uBA85\uC138 \uBC94\uC704\uAC00 \uC900\uBE44\uD55C \uC6D0\uBB38\uACFC \uB2E4\uB985\uB2C8\uB2E4.",
|
|
24658
|
+
"prepare.stagingContent": "staging \uC6D0\uBB38\uC774 \uC900\uBE44\uD55C \uD30C\uC77C\uACFC \uB2E4\uB985\uB2C8\uB2E4: {path}",
|
|
24659
|
+
"prepare.stagingChanged": "\uD655\uC778 \uC911 staging\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24660
|
+
"prepare.specsChanged": "\uD655\uC778 \uC911 \uBA85\uC138\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24661
|
+
"commitFiles.relativePath": "\uC800\uC7A5\uC18C \uC0C1\uB300 \uACBD\uB85C\uC758 \uBA85\uC138 \uB610\uB294 \uC77C\uBC18 \uD30C\uC77C\uB9CC \uC120\uD0DD\uD558\uC138\uC694.",
|
|
24662
|
+
"commitFiles.linkOrDirectory": "\uB9C1\uD06C\xB7\uB514\uB809\uD130\uB9AC\xB7\uD2B9\uC218 \uD30C\uC77C\uC740 \uC120\uD0DD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24663
|
+
"commitFiles.nestedRepository": "\uC911\uCCA9 \uC800\uC7A5\uC18C\uB294 \uC120\uD0DD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24664
|
+
"commitFiles.hardLinkOrSize": "\uD558\uB4DC \uB9C1\uD06C \uB610\uB294 \uD30C\uC77C \uD06C\uAE30 \uD55C\uB3C4\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24665
|
+
"commitFiles.invalidInput": "\uC798\uBABB\uB41C \uCEE4\uBC0B \uC785\uB825\uC785\uB2C8\uB2E4.",
|
|
24666
|
+
"commitFiles.emptyOrTooLong": "\uBE48 \uBB38\uC790\uC5F4 \uB610\uB294 \uC785\uB825 \uD55C\uB3C4 \uCD08\uACFC\uC785\uB2C8\uB2E4.",
|
|
24667
|
+
"commitFiles.invalidPaths": "\uD30C\uC77C \uBAA9\uB85D \uAC1C\uC218 \uB610\uB294 \uD615\uC2DD\uC774 \uC798\uBABB\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24668
|
+
"commitFiles.legacyDeleteOnly": ".gitifact\uC758 \uAD6C\uD615 \uAE30\uB85D\uC740 \uC0AD\uC81C\uB9CC \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24669
|
+
"commitFiles.tryceDeleteOnly": ".tryce\uC758 \uC774\uC804 \uAE30\uB85D\uC740 \uC804\uD658 \uC2DC \uC0AD\uC81C\uB9CC \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
24670
|
+
"init.migrationRequired": "\uAE30\uC874 \uD615\uC2DD\uC740 \uBCC4\uB3C4 \uC804\uD658\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC124\uC815\uACFC \uAE30\uB85D\uC744 \uBCF4\uC874\uD558\uC138\uC694.",
|
|
24671
|
+
"init.inputChanged": "\uCD08\uAE30\uD654 \uC870\uD68C \uC911 \uC785\uB825\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24672
|
+
"init.configDeleted": "\uAE30\uC874 \uC124\uC815\uC758 \uC0AD\uC81C\uB97C \uC2E0\uADDC \uB3C4\uC785\uC73C\uB85C \uCC98\uB9AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24673
|
+
"init.existingSpecs": "\uAE30\uC874 specs \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
24674
|
+
"init.orphanStore": "\uC124\uC815 \uC5C6\uB294 .gitifact \uC790\uB8CC\uB97C \uC790\uB3D9 \uCC44\uD0DD\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
24675
|
+
"init.headOrIndexChanged": "HEAD \uB610\uB294 index\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24676
|
+
"init.configAppeared": "\uB2E4\uB978 \uC2E4\uD589\uC774 \uC124\uC815\uC744 \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4.",
|
|
24677
|
+
"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.",
|
|
24678
|
+
"init.text.skipped": "\uAC74\uB108\uB700",
|
|
24679
|
+
"init.text.blockRemoved": "\uBE14\uB85D \uC81C\uAC70",
|
|
24680
|
+
"init.text.blockPlanned": "\uBE14\uB85D \uC124\uCE58 \uC608\uC815",
|
|
24681
|
+
"init.text.blockUpdated": "\uBE14\uB85D \uAC31\uC2E0",
|
|
24682
|
+
"init.text.storage": "\uC800\uC7A5 \uADDC\uC57D",
|
|
24683
|
+
"init.text.agentDocs": "\uC5D0\uC774\uC804\uD2B8 \uC9C0\uCE68",
|
|
24684
|
+
"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.",
|
|
24685
|
+
"config.storeNotDirectory": ".gitifact\uB294 \uB9C1\uD06C\uAC00 \uC544\uB2CC \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
24686
|
+
"config.migrateFirst": ".tryce \uC800\uC7A5\uC18C\uC785\uB2C8\uB2E4. gitifact migrate\uB85C .gitifact\uC5D0 \uC804\uD658\uD558\uC138\uC694.",
|
|
24687
|
+
"config.fileShape": "config.json\uC740 64 KiB \uC774\uD558\uC758 \uC77C\uBC18 \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
24688
|
+
"config.changedWhileReading": "\uC124\uC815 \uD30C\uC77C\uC774 \uC870\uD68C \uC911 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24689
|
+
"config.notUtf8Json": "\uC124\uC815\uC740 UTF-8 JSON\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
24690
|
+
"config.directoryChanged": "\uC124\uC815 \uB514\uB809\uD130\uB9AC\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4. \uC784\uC2DC \uD30C\uC77C\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
24691
|
+
"config.temporaryChanged": "\uC784\uC2DC \uC124\uC815\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4.",
|
|
24692
|
+
"managedFile.notRegularPath": "\uC77C\uBC18 \uACBD\uB85C\uAC00 \uC544\uB2D9\uB2C8\uB2E4: {path}",
|
|
24693
|
+
"managedFile.tooLarge": "{kib} KiB\uB97C \uCD08\uACFC\uD569\uB2C8\uB2E4: {path}",
|
|
24694
|
+
"managedFile.changedWhileReading": "\uC870\uD68C \uC911 \uD30C\uC77C\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24695
|
+
"managedFile.notUtf8": "UTF-8 \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: {path}",
|
|
24696
|
+
"managedFile.targetChanged": "\uB300\uC0C1 \uACBD\uB85C\uAC00 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24697
|
+
"managedFile.removeTargetChanged": "\uC81C\uAC70 \uB300\uC0C1\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24698
|
+
"managedFile.publishTargetChanged": "\uAC8C\uC2DC \uB300\uC0C1\uC774 \uBCC0\uACBD\uB410\uC2B5\uB2C8\uB2E4: {path}",
|
|
24699
|
+
"agentBlock.endWithoutStart": "\uC2DC\uC791 \uB9C8\uCEE4 \uC5C6\uC774 \uC885\uB8CC \uB9C8\uCEE4\uB9CC \uC788\uC2B5\uB2C8\uB2E4. \uBE14\uB85D\uC744 \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24700
|
+
"agentBlock.startWithoutEnd": "\uC885\uB8CC \uB9C8\uCEE4\uAC00 \uC5C6\uB294 GITIFACT \uBE14\uB85D\uC774 \uC788\uC2B5\uB2C8\uB2E4. \uBE14\uB85D\uC744 \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24701
|
+
"agentBlock.duplicateStart": "GITIFACT \uC2DC\uC791 \uB9C8\uCEE4\uAC00 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4. \uC911\uBCF5 \uBE14\uB85D\uC744 \uC815\uB9AC\uD55C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
24702
|
+
"specReader.headUnreadable": "HEAD\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24703
|
+
"specReader.schemaRequired": "\uC0C8 \uC2A4\uD0A4\uB9C8 \uD504\uB85C\uC81D\uD2B8\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
24704
|
+
"specReader.historyChanged": "\uC774\uB825\uC774 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uACE0\uCE68 \uD6C4 \uB2E4\uC2DC \uC870\uD68C\uD558\uC138\uC694.",
|
|
24705
|
+
"specReader.authorUnreadable": "Git \uC791\uC131\uC790\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24706
|
+
"specReader.historyUnreadable": "Git \uC774\uB825 \uD615\uC2DD\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24707
|
+
"specReader.projectChanged": "\uC870\uD68C \uC911 \uD504\uB85C\uC81D\uD2B8\uAC00 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uACE0\uCE68\uD558\uC138\uC694.",
|
|
24708
|
+
"docs.unknownTopic": "\uC54C \uC218 \uC5C6\uB294 \uC8FC\uC81C\uC785\uB2C8\uB2E4: {topic}. \uC0AC\uC6A9 \uAC00\uB2A5: {topics}",
|
|
24709
|
+
"status.text.repository": "\uC800\uC7A5\uC18C: {path}",
|
|
24710
|
+
"status.text.changes": "Git \uBCC0\uACBD \uACBD\uB85C {count}\uAC1C, gitifact \uAC80\uC0AC \uBBF8\uC2E4\uD589",
|
|
24711
|
+
"status.text.observed": "\uAD00\uCE21: {at} (best-effort, \uD30C\uC77C \uB0B4\uC6A9 \uC2A4\uB0C5\uC0F7 \uC544\uB2D8)",
|
|
24712
|
+
"browser.invalidPort": "\uD3EC\uD2B8\uB294 0\uBD80\uD130 65535 \uC0AC\uC774\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
24713
|
+
"browser.failed": "\uBE0C\uB77C\uC6B0\uC800 \uC11C\uBC84\uB97C \uC2E4\uD589\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
24714
|
+
"browser.assetSymlink": "\uBE0C\uB77C\uC6B0\uC800 \uC790\uC0B0\uC5D0 symlink\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
24715
|
+
"browser.assetsUnreadable": "\uBE0C\uB77C\uC6B0\uC800 \uBE4C\uB4DC \uC790\uC0B0\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. pnpm build\uB85C \uB2E4\uC2DC \uBE4C\uB4DC\uD558\uC138\uC694.",
|
|
24716
|
+
"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",
|
|
24717
|
+
"docs.summary.spec": "\uC0AC\uC6A9\uC790 \uC2A4\uD1A0\uB9AC\xB7\uC218\uC6A9 \uC870\uAC74 \uD615\uC2DD, ID \uADDC\uCE59, spec save \uC785\uB825",
|
|
24718
|
+
"docs.summary.design": "design.md \uBAA9\uCC28, \uCC38\uC870 \uC8FC\uC11D, \uAC1C\uC815 \uBC29\uC2DD",
|
|
24719
|
+
"docs.summary.product": "PRODUCT.md\uC640 guides \uBB38\uC11C\uC758 \uC5ED\uD560\uACFC \uC800\uC7A5 \uBA85\uB839",
|
|
24720
|
+
"docs.summary.commit": "spec commit \uC785\uB825, \uC774\uC720 \uAE30\uB85D, \uC2E4\uD328 \uD6C4 \uBCF5\uAD6C"
|
|
24721
|
+
};
|
|
24722
|
+
|
|
24723
|
+
// src/shared/i18n/index.ts
|
|
24724
|
+
var defaultLanguage2 = "ko";
|
|
24725
|
+
var catalogs2 = { ko: messages_default2 };
|
|
24726
|
+
function t2(key, values = {}, lang = defaultLanguage2) {
|
|
24727
|
+
return catalogs2[lang][key].replace(/\{(\w+)\}/g, (whole, name) => name in values ? String(values[name]) : whole);
|
|
24728
|
+
}
|
|
24729
|
+
|
|
24361
24730
|
// src/output/repository-status.ts
|
|
24362
24731
|
function statusDto(observation) {
|
|
24363
24732
|
return repositoryStatusSuccessV1.parse({
|
|
@@ -24390,11 +24759,11 @@ function escapeTerminal(value) {
|
|
|
24390
24759
|
function statusText(value) {
|
|
24391
24760
|
const { head, summary } = value;
|
|
24392
24761
|
const lines = [
|
|
24393
|
-
"
|
|
24762
|
+
t2("status.text.repository", { path: escapeTerminal(value.repository.rootPath) }),
|
|
24394
24763
|
"HEAD: " + head.state + (head.branch ? " " + escapeTerminal(head.branch) : "") + (head.commit ? " " + head.commit : ""),
|
|
24395
|
-
"
|
|
24764
|
+
t2("status.text.changes", { count: value.changes.length }),
|
|
24396
24765
|
"staged " + summary.staged + " / unstaged " + summary.unstaged + " / untracked " + summary.untracked + " / conflicted " + summary.conflicted,
|
|
24397
|
-
"
|
|
24766
|
+
t2("status.text.observed", { at: value.observation.completedAt })
|
|
24398
24767
|
];
|
|
24399
24768
|
for (const change2 of value.changes) {
|
|
24400
24769
|
let line = (change2.xy ?? "??") + " " + escapeTerminal(change2.path);
|
|
@@ -24433,18 +24802,18 @@ import { join } from "node:path";
|
|
|
24433
24802
|
async function loadBrowserAssets(directory) {
|
|
24434
24803
|
const assets = /* @__PURE__ */ new Map();
|
|
24435
24804
|
async function walk(current, prefix) {
|
|
24436
|
-
for (const
|
|
24437
|
-
if (
|
|
24438
|
-
const name = prefix +
|
|
24439
|
-
if (
|
|
24440
|
-
else if (
|
|
24805
|
+
for (const entry2 of await readdir(current, { withFileTypes: true })) {
|
|
24806
|
+
if (entry2.isSymbolicLink()) throw new Error(t2("browser.assetSymlink"));
|
|
24807
|
+
const name = prefix + entry2.name;
|
|
24808
|
+
if (entry2.isDirectory()) await walk(join(current, entry2.name), name + "/");
|
|
24809
|
+
else if (entry2.isFile()) assets.set("/" + name, await readFile(join(current, entry2.name)));
|
|
24441
24810
|
}
|
|
24442
24811
|
}
|
|
24443
24812
|
try {
|
|
24444
24813
|
await walk(directory, "");
|
|
24445
24814
|
if (!assets.has("/index.html")) throw new Error("missing index");
|
|
24446
24815
|
} catch {
|
|
24447
|
-
throw new Error("
|
|
24816
|
+
throw new Error(t2("browser.assetsUnreadable"));
|
|
24448
24817
|
}
|
|
24449
24818
|
return assets;
|
|
24450
24819
|
}
|
|
@@ -24519,9 +24888,11 @@ function commandScoped(key, load) {
|
|
|
24519
24888
|
|
|
24520
24889
|
// src/adapters/git/spec-preview-reader.ts
|
|
24521
24890
|
var RECORD_PATHSPECS = [...STORE_DIRS.map((d) => d + "/spec/"), ...Object.values(DOCUMENT_DIRS).map((d) => d + "/")];
|
|
24891
|
+
var LegacyBaselineError = class extends SpecPreviewError {
|
|
24892
|
+
};
|
|
24522
24893
|
function specPreviewReader(cwd) {
|
|
24523
24894
|
for (const key of Object.keys(process.env)) if (/^GIT_(DIR|WORK_TREE|COMMON_DIR|INDEX_FILE|OBJECT_DIRECTORY|ALTERNATE_OBJECT_DIRECTORIES|CONFIG_COUNT|CONFIG_PARAMETERS|CONFIG_KEY_\d+|CONFIG_VALUE_\d+)$/i.test(key)) {
|
|
24524
|
-
throw new SpecPreviewError("
|
|
24895
|
+
throw new SpecPreviewError(t2("reader.gitContextOverride"));
|
|
24525
24896
|
}
|
|
24526
24897
|
const runner = createGitRunner();
|
|
24527
24898
|
const env = { ...process.env, GIT_OPTIONAL_LOCKS: "0", GIT_NO_LAZY_FETCH: "1", GIT_NO_REPLACE_OBJECTS: "1", GIT_TERMINAL_PROMPT: "0", GIT_LITERAL_PATHSPECS: "0", GIT_GLOB_PATHSPECS: "0", GIT_NOGLOB_PATHSPECS: "0", GIT_ICASE_PATHSPECS: "0", LC_ALL: "C" };
|
|
@@ -24537,7 +24908,7 @@ function specPreviewReader(cwd) {
|
|
|
24537
24908
|
try {
|
|
24538
24909
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
24539
24910
|
} catch {
|
|
24540
|
-
throw new SpecPreviewError("
|
|
24911
|
+
throw new SpecPreviewError(t2("reader.notUtf8"));
|
|
24541
24912
|
}
|
|
24542
24913
|
};
|
|
24543
24914
|
return {
|
|
@@ -24546,12 +24917,12 @@ function specPreviewReader(cwd) {
|
|
|
24546
24917
|
const files = /* @__PURE__ */ new Map();
|
|
24547
24918
|
for (const row of output2.split("\0").filter(Boolean)) {
|
|
24548
24919
|
const match = /^(\d+) ([a-f0-9]+) ([0-3])\t([\s\S]+)$/.exec(row);
|
|
24549
|
-
if (!match) throw new SpecPreviewError("
|
|
24920
|
+
if (!match) throw new SpecPreviewError(t2("reader.invalidIndexEntry"));
|
|
24550
24921
|
const [, mode, oid2, stage, path3] = match;
|
|
24551
|
-
if (!["100644", "100755"].includes(mode) || stage !== "0") throw new SpecPreviewError("
|
|
24922
|
+
if (!["100644", "100755"].includes(mode) || stage !== "0") throw new SpecPreviewError(t2("reader.stagingConflictOrLink"));
|
|
24552
24923
|
if (!recordPathPattern.test(path3)) {
|
|
24553
24924
|
if (/^\.gitifact\/(?:product|guides)\//.test(path3)) continue;
|
|
24554
|
-
throw new SpecPreviewError("
|
|
24925
|
+
throw new SpecPreviewError(t2("reader.stagingUnsupported"));
|
|
24555
24926
|
}
|
|
24556
24927
|
files.set(path3, oid2);
|
|
24557
24928
|
}
|
|
@@ -24568,10 +24939,10 @@ function specPreviewReader(cwd) {
|
|
|
24568
24939
|
const head = decode5(headOutput).trim();
|
|
24569
24940
|
const branch = decode5(branchOutput).trim();
|
|
24570
24941
|
if (head) {
|
|
24571
|
-
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) throw new SpecPreviewError("
|
|
24942
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) throw new SpecPreviewError(t2("reader.headUnknown"));
|
|
24572
24943
|
return { head, branch: branch || null };
|
|
24573
24944
|
}
|
|
24574
|
-
if (!branch.startsWith("refs/heads/") || (await git(["for-each-ref", "--format=%(refname)", "--", branch])).length) throw new SpecPreviewError("
|
|
24945
|
+
if (!branch.startsWith("refs/heads/") || (await git(["for-each-ref", "--format=%(refname)", "--", branch])).length) throw new SpecPreviewError(t2("reader.damagedHead"));
|
|
24575
24946
|
return { head: null, branch };
|
|
24576
24947
|
},
|
|
24577
24948
|
location() {
|
|
@@ -24581,13 +24952,13 @@ function specPreviewReader(cwd) {
|
|
|
24581
24952
|
let values = line(await git(["rev-parse", "--path-format=absolute", ...fields2.flat()])).split("\n");
|
|
24582
24953
|
if (values.length !== fields2.length) values = await Promise.all(fields2.map(async (flags) => line(await git(["rev-parse", "--path-format=absolute", ...flags]))));
|
|
24583
24954
|
const [root, gitDir, indexPath, objectFormat] = values.map((value) => value.trim());
|
|
24584
|
-
if (objectFormat !== "sha1" && objectFormat !== "sha256") throw new SpecPreviewError("
|
|
24955
|
+
if (objectFormat !== "sha1" && objectFormat !== "sha256") throw new SpecPreviewError(t2("reader.objectFormat"));
|
|
24585
24956
|
return { root, gitDir, indexPath, objectFormat };
|
|
24586
24957
|
});
|
|
24587
24958
|
},
|
|
24588
24959
|
async resolve(ref) {
|
|
24589
24960
|
const oid2 = (await git(["rev-parse", "--verify", "--end-of-options", ref + "^{commit}"])).toString("ascii").trim();
|
|
24590
|
-
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(oid2)) throw new SpecPreviewError("
|
|
24961
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(oid2)) throw new SpecPreviewError(t2("reader.commitUnknown"));
|
|
24591
24962
|
return oid2;
|
|
24592
24963
|
},
|
|
24593
24964
|
async files(oid2, allowLegacyBaseline = false) {
|
|
@@ -24596,24 +24967,24 @@ function specPreviewReader(cwd) {
|
|
|
24596
24967
|
let legacy;
|
|
24597
24968
|
for (const row of entries.split("\0").filter(Boolean)) {
|
|
24598
24969
|
const match = /^(\d+) (\w+) ([a-f0-9]+)\t([\s\S]+)$/.exec(row);
|
|
24599
|
-
if (!match) throw new SpecPreviewError("
|
|
24970
|
+
if (!match) throw new SpecPreviewError(t2("reader.invalidTree"));
|
|
24600
24971
|
const [, mode, type, object4, path3] = match;
|
|
24601
|
-
if (!["100644", "100755"].includes(mode) || type !== "blob") throw new SpecPreviewError("
|
|
24972
|
+
if (!["100644", "100755"].includes(mode) || type !== "blob") throw new SpecPreviewError(t2("reader.linkOrSubmodule", { path: path3 }));
|
|
24602
24973
|
if (!recordPathPattern.test(path3) && !path3.endsWith("/tryce.json")) continue;
|
|
24603
24974
|
if (path3.endsWith("/tryce.json")) {
|
|
24604
|
-
if (!allowLegacyBaseline) throw new
|
|
24975
|
+
if (!allowLegacyBaseline) throw new LegacyBaselineError(t2("reader.legacyJson"));
|
|
24605
24976
|
legacy = path3.split("/")[0];
|
|
24606
24977
|
continue;
|
|
24607
24978
|
}
|
|
24608
|
-
if (!recordPathPattern.test(path3) || !["100644", "100755"].includes(mode) || type !== "blob") throw new SpecPreviewError("
|
|
24979
|
+
if (!recordPathPattern.test(path3) || !["100644", "100755"].includes(mode) || type !== "blob") throw new SpecPreviewError(t2("reader.unsupportedEntry", { path: path3 }));
|
|
24609
24980
|
files.set(path3, object4);
|
|
24610
24981
|
}
|
|
24611
|
-
if (new Set([...files.keys()].map((p) => p.split("/")[0])).size > 1) throw new SpecPreviewError("
|
|
24982
|
+
if (new Set([...files.keys()].map((p) => p.split("/")[0])).size > 1) throw new SpecPreviewError(t2("reader.mixedStores"));
|
|
24612
24983
|
if (legacy) {
|
|
24613
|
-
if (files.size) throw new SpecPreviewError("
|
|
24984
|
+
if (files.size) throw new SpecPreviewError(t2("reader.mixedFormats"));
|
|
24614
24985
|
parseProjectConfig(decode5(await git(["show", `${oid2}:${legacy}/config.json`])));
|
|
24615
24986
|
}
|
|
24616
|
-
if (files.size > 2e3) throw new SpecPreviewError("
|
|
24987
|
+
if (files.size > 2e3) throw new SpecPreviewError(t2("reader.fileLimit"));
|
|
24617
24988
|
const blobs = /* @__PURE__ */ new Map();
|
|
24618
24989
|
const ids = [...new Set(files.values())];
|
|
24619
24990
|
let totalBytes = 0;
|
|
@@ -24625,13 +24996,13 @@ function specPreviewReader(cwd) {
|
|
|
24625
24996
|
const end = output2.indexOf(10, offset);
|
|
24626
24997
|
const header = output2.subarray(offset, end).toString("ascii").split(" ");
|
|
24627
24998
|
const size = Number(header[2]);
|
|
24628
|
-
if (end < offset || header[0] !== id || header[1] !== "blob" || !Number.isSafeInteger(size) || size < 0 || size > 1024 * 1024 || output2[end + size + 1] !== 10) throw new SpecPreviewError("
|
|
24999
|
+
if (end < offset || header[0] !== id || header[1] !== "blob" || !Number.isSafeInteger(size) || size < 0 || size > 1024 * 1024 || output2[end + size + 1] !== 10) throw new SpecPreviewError(t2("reader.blobShape"));
|
|
24629
25000
|
totalBytes += size;
|
|
24630
|
-
if (totalBytes > 16 * 1024 * 1024) throw new SpecPreviewError("
|
|
25001
|
+
if (totalBytes > 16 * 1024 * 1024) throw new SpecPreviewError(t2("reader.totalLimit"));
|
|
24631
25002
|
blobs.set(id, decode5(output2.subarray(end + 1, end + size + 1)));
|
|
24632
25003
|
offset = end + size + 2;
|
|
24633
25004
|
}
|
|
24634
|
-
if (offset !== output2.length) throw new SpecPreviewError("
|
|
25005
|
+
if (offset !== output2.length) throw new SpecPreviewError(t2("reader.blobBoundary"));
|
|
24635
25006
|
}
|
|
24636
25007
|
return new Map([...files].map(([path3, id]) => [path3, blobs.get(id)]));
|
|
24637
25008
|
},
|
|
@@ -24662,7 +25033,7 @@ var fileInfo = (path3) => lstat(path3).catch((error62) => {
|
|
|
24662
25033
|
async function configDirectory(root) {
|
|
24663
25034
|
const path3 = join2(root, ".gitifact");
|
|
24664
25035
|
const info4 = await fileInfo(path3);
|
|
24665
|
-
if (info4 && (!info4.isDirectory() || info4.isSymbolicLink())) throw new InitError("PATH_CONFLICT", ".
|
|
25036
|
+
if (info4 && (!info4.isDirectory() || info4.isSymbolicLink())) throw new InitError("PATH_CONFLICT", t2("config.storeNotDirectory"));
|
|
24666
25037
|
return info4;
|
|
24667
25038
|
}
|
|
24668
25039
|
async function readConfigFile(root) {
|
|
@@ -24670,20 +25041,20 @@ async function readConfigFile(root) {
|
|
|
24670
25041
|
const path3 = join2(root, ".gitifact", "config.json");
|
|
24671
25042
|
const info4 = await fileInfo(path3);
|
|
24672
25043
|
if (!info4) {
|
|
24673
|
-
if (await fileInfo(join2(root, ".tryce", "config.json"))) throw new InitError("MIGRATION_REQUIRED", ".
|
|
25044
|
+
if (await fileInfo(join2(root, ".tryce", "config.json"))) throw new InitError("MIGRATION_REQUIRED", t2("config.migrateFirst"));
|
|
24674
25045
|
return void 0;
|
|
24675
25046
|
}
|
|
24676
|
-
if (!info4.isFile() || info4.isSymbolicLink() || info4.size > 65536) throw new InitError("PATH_CONFLICT", "config.
|
|
25047
|
+
if (!info4.isFile() || info4.isSymbolicLink() || info4.size > 65536) throw new InitError("PATH_CONFLICT", t2("config.fileShape"));
|
|
24677
25048
|
const bytes = await readFile2(path3);
|
|
24678
25049
|
const after = await fileInfo(path3);
|
|
24679
25050
|
await configDirectory(root);
|
|
24680
25051
|
if (!after || after.ino !== info4.ino || after.dev !== info4.dev || after.mtimeMs !== info4.mtimeMs || bytes.length > 65536) {
|
|
24681
|
-
throw new InitError("INPUT_CHANGED", "
|
|
25052
|
+
throw new InitError("INPUT_CHANGED", t2("config.changedWhileReading"));
|
|
24682
25053
|
}
|
|
24683
25054
|
try {
|
|
24684
25055
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
24685
25056
|
} catch {
|
|
24686
|
-
throw new InitError("INVALID_CONFIG", "
|
|
25057
|
+
throw new InitError("INVALID_CONFIG", t2("config.notUtf8Json"));
|
|
24687
25058
|
}
|
|
24688
25059
|
}
|
|
24689
25060
|
async function publishConfig(root, text2, recheck, beforePublish) {
|
|
@@ -24697,7 +25068,7 @@ async function publishConfig(root, text2, recheck, beforePublish) {
|
|
|
24697
25068
|
const unchanged = async () => {
|
|
24698
25069
|
const current = await configDirectory(root);
|
|
24699
25070
|
if (!owner || !current || current.ino !== owner.ino || current.dev !== owner.dev || await realpath(directory) !== canonical) {
|
|
24700
|
-
throw new InitError("INPUT_CHANGED", "
|
|
25071
|
+
throw new InitError("INPUT_CHANGED", t2("config.directoryChanged"));
|
|
24701
25072
|
}
|
|
24702
25073
|
};
|
|
24703
25074
|
const temporary = join2(directory, ".init-" + randomUUID3() + ".tmp");
|
|
@@ -24715,7 +25086,7 @@ async function publishConfig(root, text2, recheck, beforePublish) {
|
|
|
24715
25086
|
await recheck();
|
|
24716
25087
|
await unchanged();
|
|
24717
25088
|
const bytes = await readFile2(temporary, "utf8");
|
|
24718
|
-
if (bytes !== text2) throw new InitError("INPUT_CHANGED", "
|
|
25089
|
+
if (bytes !== text2) throw new InitError("INPUT_CHANGED", t2("config.temporaryChanged"));
|
|
24719
25090
|
parseManagedConfig(bytes);
|
|
24720
25091
|
await link(temporary, join2(directory, "config.json"));
|
|
24721
25092
|
} finally {
|
|
@@ -24736,7 +25107,7 @@ var info = async (path3) => lstat2(path3).catch((e) => {
|
|
|
24736
25107
|
var digest = (value) => createHash2("sha256").update(value).digest("hex");
|
|
24737
25108
|
var LEGACY_LOCKS = ["tryce-spec-preview.lock", "tryce-spec-commit.lock"];
|
|
24738
25109
|
async function failOnLegacyLock(gitDir) {
|
|
24739
|
-
for (const name of LEGACY_LOCKS) if (await info(join3(gitDir, name))) fail4("
|
|
25110
|
+
for (const name of LEGACY_LOCKS) if (await info(join3(gitDir, name))) fail4(t2("store.legacyLock", { path: join3(gitDir, name) }));
|
|
24740
25111
|
}
|
|
24741
25112
|
var decode3 = (bytes) => new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
24742
25113
|
var generatePreviewId = (prefix) => prefix + "-" + [...randomBytes(10)].map((n) => "abcdefghijklmnopqrstuvwxyz234567"[n & 31]).join("");
|
|
@@ -24747,26 +25118,26 @@ async function snapshot2(root) {
|
|
|
24747
25118
|
let count = 0;
|
|
24748
25119
|
let bytes = 0;
|
|
24749
25120
|
const parent = await info(join3(root, ".gitifact"));
|
|
24750
|
-
if (parent && (!parent.isDirectory() || parent.isSymbolicLink())) fail4(".
|
|
24751
|
-
if (!parent && await info(join3(root, ".tryce"))) fail4(".
|
|
25121
|
+
if (parent && (!parent.isDirectory() || parent.isSymbolicLink())) fail4(t2("store.storeNotDirectory"));
|
|
25122
|
+
if (!parent && await info(join3(root, ".tryce"))) fail4(t2("store.migrateFirst"));
|
|
24752
25123
|
const config2 = await readConfigFile(root);
|
|
24753
|
-
if (config2 !== void 0 && !("schemaVersion" in parseManagedConfig(config2)) || await info(join3(root, "specs"))) fail4("
|
|
25124
|
+
if (config2 !== void 0 && !("schemaVersion" in parseManagedConfig(config2)) || await info(join3(root, "specs"))) fail4(t2("store.legacyProject"));
|
|
24754
25125
|
async function visit2(path3, depth, documents) {
|
|
24755
25126
|
const stat3 = await info(join3(root, path3));
|
|
24756
25127
|
if (!stat3) return;
|
|
24757
|
-
if (stat3.isSymbolicLink() || !stat3.isDirectory() && !stat3.isFile()) fail4("
|
|
24758
|
-
if (++count > 4e3) fail4("
|
|
25128
|
+
if (stat3.isSymbolicLink() || !stat3.isDirectory() && !stat3.isFile()) fail4(t2("store.linkOrSpecial", { path: path3 }));
|
|
25129
|
+
if (++count > 4e3) fail4(t2("store.tooManyFiles"));
|
|
24759
25130
|
if (stat3.isDirectory()) {
|
|
24760
|
-
if (depth > (documents ? 8 : 1)) fail4("
|
|
25131
|
+
if (depth > (documents ? 8 : 1)) fail4(t2("store.tooDeep", { path: path3 }));
|
|
24761
25132
|
for (const name of (await readdir2(join3(root, path3))).sort()) await visit2(path3 + "/" + name, depth + 1, documents);
|
|
24762
25133
|
} else {
|
|
24763
|
-
if (path3.endsWith("/tryce.json")) fail4("
|
|
25134
|
+
if (path3.endsWith("/tryce.json")) fail4(t2("store.legacyJson"));
|
|
24764
25135
|
if (documents ? !(path3.endsWith(".md") || depth === 1 && path3.endsWith("/history.jsonl")) : !/\/(requirements\.md|design\.md|history\.jsonl)$/.test(path3)) return;
|
|
24765
|
-
if (!recordPathPattern.test(path3) || path3.startsWith(".tryce/")) fail4("
|
|
24766
|
-
if (stat3.nlink !== 1 || stat3.size > 1024 * 1024) fail4("
|
|
25136
|
+
if (!recordPathPattern.test(path3) || path3.startsWith(".tryce/")) fail4(t2("store.unsupportedPath", { path: path3 }));
|
|
25137
|
+
if (stat3.nlink !== 1 || stat3.size > 1024 * 1024) fail4(t2("store.hardLinkOrSize"));
|
|
24767
25138
|
const raw = await readFile3(join3(root, path3));
|
|
24768
25139
|
bytes += raw.length;
|
|
24769
|
-
if (raw.length > 1024 * 1024 || bytes > 16 * 1024 * 1024) fail4("
|
|
25140
|
+
if (raw.length > 1024 * 1024 || bytes > 16 * 1024 * 1024) fail4(t2("store.sizeLimit"));
|
|
24770
25141
|
files.set(path3, decode3(raw));
|
|
24771
25142
|
}
|
|
24772
25143
|
}
|
|
@@ -24778,11 +25149,11 @@ async function snapshot2(root) {
|
|
|
24778
25149
|
async function readWorkingPreviewState(cwd) {
|
|
24779
25150
|
const { root, gitDir } = await specPreviewReader(cwd).location();
|
|
24780
25151
|
await failOnLegacyLock(gitDir);
|
|
24781
|
-
if (await info(join3(gitDir, "gitifact-spec-preview.lock"))) fail4("
|
|
25152
|
+
if (await info(join3(gitDir, "gitifact-spec-preview.lock"))) fail4(t2("store.locked"));
|
|
24782
25153
|
const first = await snapshot2(root);
|
|
24783
25154
|
const second = await snapshot2(root);
|
|
24784
|
-
if (first.stamp !== second.stamp) fail4("
|
|
24785
|
-
if (await info(join3(gitDir, "gitifact-spec-preview.lock"))) fail4("
|
|
25155
|
+
if (first.stamp !== second.stamp) fail4(t2("store.changedWhileReading"));
|
|
25156
|
+
if (await info(join3(gitDir, "gitifact-spec-preview.lock"))) fail4(t2("store.lockedWhileReading"));
|
|
24786
25157
|
return first;
|
|
24787
25158
|
}
|
|
24788
25159
|
async function readWorkingPreview(cwd) {
|
|
@@ -24790,9 +25161,9 @@ async function readWorkingPreview(cwd) {
|
|
|
24790
25161
|
return { stamp, specs, documents, warnings: designReferenceWarnings(specs) };
|
|
24791
25162
|
}
|
|
24792
25163
|
async function saveWorkingPreview(cwd, input2, publish = rename) {
|
|
24793
|
-
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail4("
|
|
25164
|
+
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail4(t2("store.invalidInput"));
|
|
24794
25165
|
const request = input2;
|
|
24795
|
-
if (Object.keys(request).sort().join(",") !== "expected,operations" || typeof request.expected !== "string") fail4("
|
|
25166
|
+
if (Object.keys(request).sort().join(",") !== "expected,operations" || typeof request.expected !== "string") fail4(t2("store.expectedOperations"));
|
|
24796
25167
|
return previewTransaction(cwd, request.expected, async (before) => {
|
|
24797
25168
|
const result = editSpecPreview(before.bundle, request.operations, generatePreviewId);
|
|
24798
25169
|
const writes = /* @__PURE__ */ new Map();
|
|
@@ -24820,7 +25191,7 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24820
25191
|
try {
|
|
24821
25192
|
await mkdir2(lock);
|
|
24822
25193
|
} catch (e) {
|
|
24823
|
-
if (e.code === "EEXIST") fail4("
|
|
25194
|
+
if (e.code === "EEXIST") fail4(t2("store.locked"));
|
|
24824
25195
|
throw e;
|
|
24825
25196
|
}
|
|
24826
25197
|
const createdDirs = [];
|
|
@@ -24831,7 +25202,7 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24831
25202
|
async function directory(path3) {
|
|
24832
25203
|
const stat3 = await info(path3);
|
|
24833
25204
|
if (stat3) {
|
|
24834
|
-
if (!stat3.isDirectory() || stat3.isSymbolicLink()) fail4("
|
|
25205
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink()) fail4(t2("store.notDirectory", { path: path3 }));
|
|
24835
25206
|
return;
|
|
24836
25207
|
}
|
|
24837
25208
|
await directory(dirname(path3));
|
|
@@ -24840,11 +25211,11 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24840
25211
|
}
|
|
24841
25212
|
try {
|
|
24842
25213
|
const before = await snapshot2(root);
|
|
24843
|
-
if (before.stamp !== expected2) fail4("
|
|
25214
|
+
if (before.stamp !== expected2) fail4(t2("store.staleExpected"));
|
|
24844
25215
|
const result = await build(before);
|
|
24845
25216
|
for (const [path3, after2] of result.writes) {
|
|
24846
|
-
if (!recordPathPattern.test(path3) || path3.startsWith(".tryce/") || path3.split("/").some((p) => p === ".." || p === "." || /[\\:\0]/.test(p))) fail4("
|
|
24847
|
-
if (after2 !== null && Buffer.byteLength(after2) > 1024 * 1024) fail4("
|
|
25217
|
+
if (!recordPathPattern.test(path3) || path3.startsWith(".tryce/") || path3.split("/").some((p) => p === ".." || p === "." || /[\\:\0]/.test(p))) fail4(t2("store.unsupportedSavePath"));
|
|
25218
|
+
if (after2 !== null && Buffer.byteLength(after2) > 1024 * 1024) fail4(t2("store.fileSizeLimit"));
|
|
24848
25219
|
changed.push({ path: path3, before: before.files.get(path3) ?? null, after: after2 });
|
|
24849
25220
|
}
|
|
24850
25221
|
const finalFiles = new Map(before.files);
|
|
@@ -24852,7 +25223,7 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24852
25223
|
if (c.after === null) finalFiles.delete(c.path);
|
|
24853
25224
|
else finalFiles.set(c.path, c.after);
|
|
24854
25225
|
}
|
|
24855
|
-
if (finalFiles.size > 2e3 || [...finalFiles.values()].reduce((n, s) => n + Buffer.byteLength(s), 0) > 16 * 1024 * 1024) fail4("
|
|
25226
|
+
if (finalFiles.size > 2e3 || [...finalFiles.values()].reduce((n, s) => n + Buffer.byteLength(s), 0) > 16 * 1024 * 1024) fail4(t2("store.totalLimit"));
|
|
24856
25227
|
await writeFile(join3(lock, "recovery.json"), JSON.stringify({ root, changed }), { flag: "wx" });
|
|
24857
25228
|
for (const c of changed) {
|
|
24858
25229
|
if (c.after === null) {
|
|
@@ -24864,19 +25235,19 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24864
25235
|
await writeFile(temp, c.after, { flag: "wx" });
|
|
24865
25236
|
temporary.push(temp);
|
|
24866
25237
|
}
|
|
24867
|
-
if ((await snapshot2(root)).stamp !== before.stamp) fail4("
|
|
25238
|
+
if ((await snapshot2(root)).stamp !== before.stamp) fail4(t2("store.changedPreparing"));
|
|
24868
25239
|
await result.recheck?.();
|
|
24869
25240
|
for (let i = 0; i < changed.length; i++) {
|
|
24870
25241
|
const c = changed[i];
|
|
24871
25242
|
const path3 = join3(root, c.path);
|
|
24872
25243
|
const stat3 = await info(path3);
|
|
24873
|
-
if (stat3?.isSymbolicLink() || stat3 && !stat3.isFile() || (stat3 ? decode3(await readFile3(path3)) : null) !== c.before) fail4("
|
|
25244
|
+
if (stat3?.isSymbolicLink() || stat3 && !stat3.isFile() || (stat3 ? decode3(await readFile3(path3)) : null) !== c.before) fail4(t2("store.changedBeforeWrite"));
|
|
24874
25245
|
if (c.after === null) await unlink2(path3);
|
|
24875
25246
|
else await publish(temporary[i], path3);
|
|
24876
25247
|
published.push(c);
|
|
24877
25248
|
}
|
|
24878
25249
|
const after = await snapshot2(root);
|
|
24879
|
-
if (after.stamp !== digest(JSON.stringify([...finalFiles].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) + (before.config ?? ""))) fail4("
|
|
25250
|
+
if (after.stamp !== digest(JSON.stringify([...finalFiles].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) + (before.config ?? ""))) fail4(t2("store.changedWhileWriting"));
|
|
24880
25251
|
await result.recheck?.();
|
|
24881
25252
|
await afterPublish?.(after);
|
|
24882
25253
|
return { ...result.data, stamp: after.stamp, paths: changed.map((c) => c.path), specs: after.specs, documents: after.documents, warnings: designReferenceWarnings(after.specs) };
|
|
@@ -24904,7 +25275,7 @@ async function previewTransaction(cwd, expected2, build, publish = rename, after
|
|
|
24904
25275
|
keepRecovery = true;
|
|
24905
25276
|
}
|
|
24906
25277
|
}
|
|
24907
|
-
if (keepRecovery) fail4("
|
|
25278
|
+
if (keepRecovery) fail4(t2("store.recoveryIncomplete", { path: lock }));
|
|
24908
25279
|
throw error62;
|
|
24909
25280
|
} finally {
|
|
24910
25281
|
for (const path3 of temporary.filter(Boolean)) await unlink2(path3).catch((e) => {
|
|
@@ -24929,7 +25300,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
24929
25300
|
const git = async (args, acceptedExitCodes = [0]) => (await runner(["--no-optional-locks", ...args], { cwd: root, env, timeoutMs: 15e3, maxBytes: 16 * 1024 * 1024, acceptedExitCodes })).toString("utf8");
|
|
24930
25301
|
const readHead = async () => {
|
|
24931
25302
|
const head = (await git(["rev-parse", "--verify", "--quiet", "HEAD"], [0, 1])).trim();
|
|
24932
|
-
if (head && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) throw new SpecPreviewError("
|
|
25303
|
+
if (head && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) throw new SpecPreviewError(t2("specReader.headUnreadable"));
|
|
24933
25304
|
if (!head) await reader.baseline();
|
|
24934
25305
|
return head || null;
|
|
24935
25306
|
};
|
|
@@ -24950,9 +25321,9 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
24950
25321
|
const pending = /* @__PURE__ */ new Map();
|
|
24951
25322
|
async function read(cursor, expectedHead) {
|
|
24952
25323
|
const raw = await readConfigFile(root);
|
|
24953
|
-
if (!raw || !("schemaVersion" in parseManagedConfig(raw))) throw new SpecPreviewError("
|
|
25324
|
+
if (!raw || !("schemaVersion" in parseManagedConfig(raw))) throw new SpecPreviewError(t2("specReader.schemaRequired"));
|
|
24954
25325
|
const base = { head: await readHead() };
|
|
24955
|
-
if (cursor > 0 && expectedHead !== base.head) throw new SpecPreviewError("
|
|
25326
|
+
if (cursor > 0 && expectedHead !== base.head) throw new SpecPreviewError(t2("specReader.historyChanged"));
|
|
24956
25327
|
const current = await readWorkingPreviewState(root);
|
|
24957
25328
|
const bare = current.specs.map(({ history: _history, ...s }) => ({ ...s, contributors: [], updatedAt: null }));
|
|
24958
25329
|
const bareDocuments = current.documents.flatMap((set2) => set2.documents).map((d) => ({ ...d, updatedAt: null }));
|
|
@@ -24964,7 +25335,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
24964
25335
|
const people = /* @__PURE__ */ new Map();
|
|
24965
25336
|
for (const line of lines) {
|
|
24966
25337
|
const [name, email3, latest] = line.split("\0");
|
|
24967
|
-
if (!name || !email3 || !latest) throw new SpecPreviewError("
|
|
25338
|
+
if (!name || !email3 || !latest) throw new SpecPreviewError(t2("specReader.authorUnreadable"));
|
|
24968
25339
|
const person = people.get(email3);
|
|
24969
25340
|
if (person) person.commits++;
|
|
24970
25341
|
else people.set(email3, { name, email: email3, latest, commits: 1 });
|
|
@@ -24993,7 +25364,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
24993
25364
|
const lines = (await git(["log", "--format=%aN%x00%aE%x00%aI", "--max-count=10001", head])).trim().split("\n").filter(Boolean);
|
|
24994
25365
|
for (const line of lines.slice(0, 1e4)) {
|
|
24995
25366
|
const [name, email3, latest] = line.split("\0");
|
|
24996
|
-
if (!name || !email3 || !latest) throw new SpecPreviewError("
|
|
25367
|
+
if (!name || !email3 || !latest) throw new SpecPreviewError(t2("specReader.authorUnreadable"));
|
|
24997
25368
|
const person = people.get(email3);
|
|
24998
25369
|
if (person) person.commits++;
|
|
24999
25370
|
else people.set(email3, { name, email: email3, latest, commits: 1 });
|
|
@@ -25004,7 +25375,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
25004
25375
|
let boundary = false;
|
|
25005
25376
|
const groups = await Promise.all(commits.slice(0, 10).map(async (row) => {
|
|
25006
25377
|
const [commit, parents, author, email3, date5, committer, message] = row.split("\0");
|
|
25007
|
-
if (!commit || author === void 0 || email3 === void 0 || !date5 || committer === void 0 || message === void 0) throw new SpecPreviewError("
|
|
25378
|
+
if (!commit || author === void 0 || email3 === void 0 || !date5 || committer === void 0 || message === void 0) throw new SpecPreviewError(t2("specReader.historyUnreadable"));
|
|
25008
25379
|
const after = await snapshot3(commit);
|
|
25009
25380
|
let before = { specs: [], documents: [{ kind: "product", documents: [], history: [] }, { kind: "guide", documents: [], history: [] }] };
|
|
25010
25381
|
const parent = parents?.split(" ")[0];
|
|
@@ -25012,7 +25383,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
25012
25383
|
try {
|
|
25013
25384
|
before = await snapshot3(parent);
|
|
25014
25385
|
} catch (error62) {
|
|
25015
|
-
if (error62 instanceof
|
|
25386
|
+
if (error62 instanceof LegacyBaselineError) boundary = true;
|
|
25016
25387
|
else throw error62;
|
|
25017
25388
|
}
|
|
25018
25389
|
}
|
|
@@ -25032,7 +25403,7 @@ function createSpecBrowserReader(root, sessionId, inherited = process.env) {
|
|
|
25032
25403
|
reasons: c.reasons.map((r) => r.reason)
|
|
25033
25404
|
}));
|
|
25034
25405
|
}));
|
|
25035
|
-
if (await readHead() !== head || (await readWorkingPreviewState(root)).stamp !== current.stamp) throw new SpecPreviewError("
|
|
25406
|
+
if (await readHead() !== head || (await readWorkingPreviewState(root)).stamp !== current.stamp) throw new SpecPreviewError(t2("specReader.projectChanged"));
|
|
25036
25407
|
return browserSpecsV1.parse({
|
|
25037
25408
|
contract: "browser-specs",
|
|
25038
25409
|
version: 1,
|
|
@@ -25097,74 +25468,74 @@ async function startBrowserServer(options) {
|
|
|
25097
25468
|
response.setHeader("X-Frame-Options", "DENY");
|
|
25098
25469
|
response.setHeader("Referrer-Policy", "no-referrer");
|
|
25099
25470
|
response.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; base-uri 'none'; frame-ancestors 'none'");
|
|
25100
|
-
if (closing) return fail8(response, 503, "SERVER_CLOSING", "
|
|
25101
|
-
if (request.headers.host !== new URL(origin).host) return fail8(response, 403, "FORBIDDEN", "
|
|
25471
|
+
if (closing) return fail8(response, 503, "SERVER_CLOSING", t2("server.closing"));
|
|
25472
|
+
if (request.headers.host !== new URL(origin).host) return fail8(response, 403, "FORBIDDEN", t2("server.forbiddenHost"));
|
|
25102
25473
|
const requestOrigin = request.headers.origin;
|
|
25103
25474
|
const allowedOrigin = requestOrigin === origin || options.dev && requestOrigin === "http://127.0.0.1:5173";
|
|
25104
|
-
if (requestOrigin && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", "
|
|
25475
|
+
if (requestOrigin && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", t2("server.forbiddenOrigin"));
|
|
25105
25476
|
const raw = request.url ?? "/";
|
|
25106
|
-
if (!raw.startsWith("/") || raw.startsWith("//") || raw.includes("\\")) return fail8(response, 400, "BAD_REQUEST", "
|
|
25477
|
+
if (!raw.startsWith("/") || raw.startsWith("//") || raw.includes("\\")) return fail8(response, 400, "BAD_REQUEST", t2("server.badPath"));
|
|
25107
25478
|
let url2;
|
|
25108
25479
|
let path3;
|
|
25109
25480
|
try {
|
|
25110
25481
|
url2 = new URL(raw, origin);
|
|
25111
25482
|
path3 = decodeURIComponent(url2.pathname);
|
|
25112
25483
|
} catch {
|
|
25113
|
-
return fail8(response, 400, "BAD_REQUEST", "
|
|
25484
|
+
return fail8(response, 400, "BAD_REQUEST", t2("server.badPath"));
|
|
25114
25485
|
}
|
|
25115
25486
|
if (path3.includes("\0") || path3.includes("\\") || path3.split("/").some((part) => part === ".." || part === ".")) {
|
|
25116
|
-
return fail8(response, 400, "BAD_REQUEST", "
|
|
25487
|
+
return fail8(response, 400, "BAD_REQUEST", t2("server.badPath"));
|
|
25117
25488
|
}
|
|
25118
25489
|
if (request.headers["transfer-encoding"] || request.headers["content-length"] && request.headers["content-length"] !== "0") {
|
|
25119
25490
|
request.resume();
|
|
25120
|
-
return fail8(response, 400, "BAD_REQUEST", "
|
|
25491
|
+
return fail8(response, 400, "BAD_REQUEST", t2("server.noBody"));
|
|
25121
25492
|
}
|
|
25122
25493
|
const api = path3 === "/api" || path3.startsWith("/api/");
|
|
25123
25494
|
if (api) {
|
|
25124
|
-
if (request.headers["sec-fetch-site"] === "cross-site" && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", "
|
|
25125
|
-
if (url2.search && path3 !== "/api/v1/specs") return fail8(response, 400, "BAD_REQUEST", "
|
|
25495
|
+
if (request.headers["sec-fetch-site"] === "cross-site" && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", t2("server.crossSite"));
|
|
25496
|
+
if (url2.search && path3 !== "/api/v1/specs") return fail8(response, 400, "BAD_REQUEST", t2("server.noQuery"));
|
|
25126
25497
|
if (path3.startsWith("/api/v1/product/assets/")) {
|
|
25127
25498
|
const name = path3.slice("/api/v1/product/assets/".length);
|
|
25128
25499
|
if (request.method !== "GET") {
|
|
25129
25500
|
response.setHeader("Allow", "GET");
|
|
25130
|
-
return fail8(response, 405, "METHOD_NOT_ALLOWED", "
|
|
25501
|
+
return fail8(response, 405, "METHOD_NOT_ALLOWED", t2("server.methodNotAllowed"));
|
|
25131
25502
|
}
|
|
25132
|
-
if (!isProductAssetPath(".gitifact/product/" + name)) return fail8(response, 404, "NOT_FOUND", "
|
|
25503
|
+
if (!isProductAssetPath(".gitifact/product/" + name)) return fail8(response, 404, "NOT_FOUND", t2("server.productImageNotFound"));
|
|
25133
25504
|
const file2 = join4(initial.repository.rootPath, ".gitifact", "product", name);
|
|
25134
25505
|
const stat3 = await lstat3(file2).catch(() => void 0);
|
|
25135
|
-
if (!stat3?.isFile() || stat3.isSymbolicLink() || stat3.size > 5 * 1024 * 1024) return fail8(response, 404, "NOT_FOUND", "
|
|
25506
|
+
if (!stat3?.isFile() || stat3.isSymbolicLink() || stat3.size > 5 * 1024 * 1024) return fail8(response, 404, "NOT_FOUND", t2("server.productImageNotFound"));
|
|
25136
25507
|
const bytes = await readFile4(file2);
|
|
25137
25508
|
response.writeHead(200, { "Content-Type": contentType(name.toLowerCase()), "Cache-Control": "no-cache", "Content-Length": bytes.length });
|
|
25138
25509
|
response.end(bytes);
|
|
25139
25510
|
return;
|
|
25140
25511
|
}
|
|
25141
25512
|
const method = path3 === "/api/v1/status/refresh" ? "POST" : "GET";
|
|
25142
|
-
if (!["/api/v1/session", "/api/v1/status", "/api/v1/status/refresh", "/api/v1/specs"].includes(path3)) return fail8(response, 404, "NOT_FOUND", "
|
|
25513
|
+
if (!["/api/v1/session", "/api/v1/status", "/api/v1/status/refresh", "/api/v1/specs"].includes(path3)) return fail8(response, 404, "NOT_FOUND", t2("server.apiNotFound"));
|
|
25143
25514
|
if (request.method !== method) {
|
|
25144
25515
|
response.setHeader("Allow", method);
|
|
25145
|
-
return fail8(response, 405, "METHOD_NOT_ALLOWED", "
|
|
25516
|
+
return fail8(response, 405, "METHOD_NOT_ALLOWED", t2("server.methodNotAllowed"));
|
|
25146
25517
|
}
|
|
25147
25518
|
if (path3 === "/api/v1/session") return json2(response, 200, session);
|
|
25148
|
-
if (request.headers["x-gitifact-session"] !== session.sessionId) return fail8(response, 409, "SESSION_CHANGED", "
|
|
25519
|
+
if (request.headers["x-gitifact-session"] !== session.sessionId) return fail8(response, 409, "SESSION_CHANGED", t2("server.sessionChanged"));
|
|
25149
25520
|
if (path3 === "/api/v1/specs") {
|
|
25150
25521
|
const cursor = url2.searchParams.get("cursor") ?? "0";
|
|
25151
25522
|
const head = url2.searchParams.get("head");
|
|
25152
|
-
if ([...url2.searchParams.keys()].some((k) => !["cursor", "head"].includes(k)) || url2.searchParams.getAll("cursor").length > 1 || url2.searchParams.getAll("head").length > 1 || !/^(0|[1-9]\d{0,5})$/.test(cursor) || head !== null && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) return fail8(response, 400, "BAD_REQUEST", "
|
|
25523
|
+
if ([...url2.searchParams.keys()].some((k) => !["cursor", "head"].includes(k)) || url2.searchParams.getAll("cursor").length > 1 || url2.searchParams.getAll("head").length > 1 || !/^(0|[1-9]\d{0,5})$/.test(cursor) || head !== null && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head)) return fail8(response, 400, "BAD_REQUEST", t2("server.badRange"));
|
|
25153
25524
|
try {
|
|
25154
25525
|
json2(response, 200, await readSpecs(Number(cursor), head ?? void 0));
|
|
25155
25526
|
} catch (error62) {
|
|
25156
|
-
fail8(response, 503, "INTERNAL_ERROR", error62 instanceof Error ? error62.message : "
|
|
25527
|
+
fail8(response, 503, "INTERNAL_ERROR", error62 instanceof Error ? error62.message : t2("server.specsUnreadable"));
|
|
25157
25528
|
}
|
|
25158
25529
|
return;
|
|
25159
25530
|
}
|
|
25160
|
-
if (method === "POST" && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", "
|
|
25531
|
+
if (method === "POST" && !allowedOrigin) return fail8(response, 403, "FORBIDDEN", t2("server.refreshOrigin"));
|
|
25161
25532
|
const value = method === "POST" ? await store.refresh() : store.latest;
|
|
25162
25533
|
if (!response.destroyed) json2(response, value.ok ? 200 : 503, value);
|
|
25163
25534
|
return;
|
|
25164
25535
|
}
|
|
25165
25536
|
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
25166
25537
|
response.setHeader("Allow", "GET, HEAD");
|
|
25167
|
-
return fail8(response, 405, "METHOD_NOT_ALLOWED", "
|
|
25538
|
+
return fail8(response, 405, "METHOD_NOT_ALLOWED", t2("server.methodNotAllowed"));
|
|
25168
25539
|
}
|
|
25169
25540
|
let asset = assets.get(path3 === "/" ? "/index.html" : path3);
|
|
25170
25541
|
let assetPath = path3 === "/" ? "/index.html" : path3;
|
|
@@ -25172,13 +25543,13 @@ async function startBrowserServer(options) {
|
|
|
25172
25543
|
asset = assets.get("/index.html");
|
|
25173
25544
|
assetPath = "/index.html";
|
|
25174
25545
|
}
|
|
25175
|
-
if (!asset) return fail8(response, 404, "NOT_FOUND", "
|
|
25546
|
+
if (!asset) return fail8(response, 404, "NOT_FOUND", t2("server.fileNotFound"));
|
|
25176
25547
|
response.writeHead(200, { "Content-Type": contentType(assetPath), "Cache-Control": "no-cache", "Content-Length": asset.length });
|
|
25177
25548
|
response.end(request.method === "HEAD" ? void 0 : asset);
|
|
25178
25549
|
}
|
|
25179
25550
|
const server = createServer({ requestTimeout: 5e3, headersTimeout: 5e3, maxHeaderSize: 8192 }, (request, response) => {
|
|
25180
25551
|
void handle(request, response).catch(() => {
|
|
25181
|
-
if (!response.headersSent && !response.destroyed) fail8(response, 500, "INTERNAL_ERROR", "
|
|
25552
|
+
if (!response.headersSent && !response.destroyed) fail8(response, 500, "INTERNAL_ERROR", t2("server.internal"));
|
|
25182
25553
|
else response.destroy();
|
|
25183
25554
|
});
|
|
25184
25555
|
});
|
|
@@ -25196,11 +25567,11 @@ async function startBrowserServer(options) {
|
|
|
25196
25567
|
} catch (error62) {
|
|
25197
25568
|
options.signal?.removeEventListener("abort", onAbort);
|
|
25198
25569
|
controller.abort();
|
|
25199
|
-
if (error62.code === "EADDRINUSE") throw new Error("
|
|
25570
|
+
if (error62.code === "EADDRINUSE") throw new Error(t2("server.portInUse"));
|
|
25200
25571
|
throw error62;
|
|
25201
25572
|
}
|
|
25202
25573
|
const address = server.address();
|
|
25203
|
-
if (!address || typeof address === "string") throw new Error("
|
|
25574
|
+
if (!address || typeof address === "string") throw new Error(t2("server.addressUnknown"));
|
|
25204
25575
|
origin = "http://127.0.0.1:" + address.port;
|
|
25205
25576
|
let resolveClosed;
|
|
25206
25577
|
const closed = new Promise((resolve) => {
|
|
@@ -25233,7 +25604,7 @@ async function startBrowserServer(options) {
|
|
|
25233
25604
|
|
|
25234
25605
|
// src/commands/browser.ts
|
|
25235
25606
|
function parsePort(value) {
|
|
25236
|
-
if (!/^\d+$/.test(value) || Number(value) > 65535) throw new InvalidArgumentError("
|
|
25607
|
+
if (!/^\d+$/.test(value) || Number(value) > 65535) throw new InvalidArgumentError(t2("browser.invalidPort"));
|
|
25237
25608
|
return Number(value);
|
|
25238
25609
|
}
|
|
25239
25610
|
async function runBrowser(options) {
|
|
@@ -25252,7 +25623,7 @@ async function runBrowser(options) {
|
|
|
25252
25623
|
await server.closed;
|
|
25253
25624
|
} catch (error62) {
|
|
25254
25625
|
if (!controller.signal.aborted) {
|
|
25255
|
-
process.stderr.write((error62 instanceof Error ? error62.message : "
|
|
25626
|
+
process.stderr.write((error62 instanceof Error ? error62.message : t2("browser.failed")) + "\n");
|
|
25256
25627
|
process.exitCode = 1;
|
|
25257
25628
|
}
|
|
25258
25629
|
} finally {
|
|
@@ -25288,9 +25659,9 @@ function initRepository(cwd, inherited = process.env) {
|
|
|
25288
25659
|
const gitDir = locations.length === 2 ? locations[0] : decodeGitLine(await git(["rev-parse", "--absolute-git-dir"], root));
|
|
25289
25660
|
const indexPath = locations.length === 2 ? locations[1] : decodeGitLine(await git(["rev-parse", "--path-format=absolute", "--git-path", "index"], root));
|
|
25290
25661
|
for (const marker2 of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply", "sequencer", "BISECT_START", "index.lock"]) {
|
|
25291
|
-
if (await fileInfo(join5(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", "
|
|
25662
|
+
if (await fileInfo(join5(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
|
|
25292
25663
|
}
|
|
25293
|
-
if (state.changes.some((change2) => change2.kind === "unmerged")) throw new InitError("GIT_OPERATION_IN_PROGRESS", "
|
|
25664
|
+
if (state.changes.some((change2) => change2.kind === "unmerged")) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
|
|
25294
25665
|
const index = await readFile5(indexPath).catch((error62) => {
|
|
25295
25666
|
if (error62.code === "ENOENT") return Buffer.alloc(0);
|
|
25296
25667
|
throw error62;
|
|
@@ -25308,17 +25679,17 @@ function initRepository(cwd, inherited = process.env) {
|
|
|
25308
25679
|
async checkIgnore(root, path3 = ".gitifact/config.json") {
|
|
25309
25680
|
const output2 = (await git(["check-ignore", "--no-index", "-v", "-z", "--stdin"], root, [0, 1], Buffer.from(path3 + "\0"))).toString("utf8");
|
|
25310
25681
|
const fields2 = output2.split("\0");
|
|
25311
|
-
if (output2 && fields2[2] && !fields2[2].startsWith("!")) throw new InitError("CONFIG_IGNORED", "
|
|
25682
|
+
if (output2 && fields2[2] && !fields2[2].startsWith("!")) throw new InitError("CONFIG_IGNORED", t2("initRepo.configIgnored", { rule: fields2[0] + ":" + fields2[1] + " " + fields2[2] }));
|
|
25312
25683
|
},
|
|
25313
25684
|
async validateBaseline(config2, root, commit, format) {
|
|
25314
25685
|
if (config2.baseline.kind === "empty") return;
|
|
25315
25686
|
const baseline = config2.baseline;
|
|
25316
|
-
if (!commit || baseline.objectFormat !== format) throw new InitError("BASELINE_UNAVAILABLE", "
|
|
25687
|
+
if (!commit || baseline.objectFormat !== format) throw new InitError("BASELINE_UNAVAILABLE", t2("initRepo.baselineMismatch"));
|
|
25317
25688
|
try {
|
|
25318
25689
|
if (decodeGitLine(await git(["cat-file", "-t", baseline.commit], root)) !== "commit") throw new Error("not a commit");
|
|
25319
25690
|
await git(["merge-base", "--is-ancestor", baseline.commit, commit], root);
|
|
25320
25691
|
} catch {
|
|
25321
|
-
throw new InitError("BASELINE_UNAVAILABLE", "
|
|
25692
|
+
throw new InitError("BASELINE_UNAVAILABLE", t2("initRepo.baselineUnverified"));
|
|
25322
25693
|
}
|
|
25323
25694
|
}
|
|
25324
25695
|
};
|
|
@@ -25342,7 +25713,7 @@ async function managedPath(root, path3, create = false) {
|
|
|
25342
25713
|
info4 = await fileInfo(full);
|
|
25343
25714
|
}
|
|
25344
25715
|
if (info4 && (info4.isSymbolicLink() || (i < parts.length - 1 ? !info4.isDirectory() : !info4.isFile()))) {
|
|
25345
|
-
throw new InitError("PATH_CONFLICT", "
|
|
25716
|
+
throw new InitError("PATH_CONFLICT", t2("managedFile.notRegularPath", { path: path3 }));
|
|
25346
25717
|
}
|
|
25347
25718
|
}
|
|
25348
25719
|
return full;
|
|
@@ -25351,17 +25722,17 @@ async function managedRead(root, path3, limit = DEFAULT_LIMIT) {
|
|
|
25351
25722
|
const full = await managedPath(root, path3);
|
|
25352
25723
|
const before = await fileInfo(full);
|
|
25353
25724
|
if (!before) return null;
|
|
25354
|
-
if (before.size > limit) throw new InitError("FILE_TOO_LARGE", limit / 1024
|
|
25725
|
+
if (before.size > limit) throw new InitError("FILE_TOO_LARGE", t2("managedFile.tooLarge", { kib: limit / 1024, path: path3 }));
|
|
25355
25726
|
const bytes = await readFile6(full);
|
|
25356
25727
|
await managedPath(root, path3);
|
|
25357
25728
|
const after = await fileInfo(full);
|
|
25358
25729
|
if (!after || before.ino !== after.ino || before.dev !== after.dev || before.mtimeMs !== after.mtimeMs || bytes.length > limit) {
|
|
25359
|
-
throw new InitError("INPUT_CHANGED", "
|
|
25730
|
+
throw new InitError("INPUT_CHANGED", t2("managedFile.changedWhileReading", { path: path3 }));
|
|
25360
25731
|
}
|
|
25361
25732
|
try {
|
|
25362
25733
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
25363
25734
|
} catch {
|
|
25364
|
-
throw new InitError("INVALID_UTF8", "
|
|
25735
|
+
throw new InitError("INVALID_UTF8", t2("managedFile.notUtf8", { path: path3 }));
|
|
25365
25736
|
}
|
|
25366
25737
|
}
|
|
25367
25738
|
async function managedWrite(root, path3, previous, next, recheck) {
|
|
@@ -25372,12 +25743,12 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
25372
25743
|
const unchanged = async () => {
|
|
25373
25744
|
await managedPath(root, path3);
|
|
25374
25745
|
const now = await fileInfo(directory);
|
|
25375
|
-
if (now?.ino !== owner?.ino || now?.dev !== owner?.dev || await realpath2(directory) !== canonical) throw new InitError("INPUT_CHANGED", "
|
|
25746
|
+
if (now?.ino !== owner?.ino || now?.dev !== owner?.dev || await realpath2(directory) !== canonical) throw new InitError("INPUT_CHANGED", t2("managedFile.targetChanged", { path: path3 }));
|
|
25376
25747
|
};
|
|
25377
25748
|
if (next === null) {
|
|
25378
25749
|
await recheck();
|
|
25379
25750
|
await unchanged();
|
|
25380
|
-
if (await managedRead(root, path3) !== previous) throw new InitError("INPUT_CHANGED", "
|
|
25751
|
+
if (await managedRead(root, path3) !== previous) throw new InitError("INPUT_CHANGED", t2("managedFile.removeTargetChanged", { path: path3 }));
|
|
25381
25752
|
if (previous !== null) await unlink3(full);
|
|
25382
25753
|
return;
|
|
25383
25754
|
}
|
|
@@ -25393,7 +25764,7 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
25393
25764
|
}
|
|
25394
25765
|
await recheck();
|
|
25395
25766
|
await unchanged();
|
|
25396
|
-
if (await managedRead(root, path3) !== previous || await readFile6(temp, "utf8") !== next) throw new InitError("INPUT_CHANGED", "
|
|
25767
|
+
if (await managedRead(root, path3) !== previous || await readFile6(temp, "utf8") !== next) throw new InitError("INPUT_CHANGED", t2("managedFile.publishTargetChanged", { path: path3 }));
|
|
25397
25768
|
if (previous === null) await link2(temp, full);
|
|
25398
25769
|
else await rename2(temp, full);
|
|
25399
25770
|
} finally {
|
|
@@ -25403,21 +25774,17 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
25403
25774
|
}
|
|
25404
25775
|
}
|
|
25405
25776
|
|
|
25777
|
+
// src/commands/agent-block.ts
|
|
25778
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
25779
|
+
|
|
25406
25780
|
// src/commands/docs.ts
|
|
25407
25781
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
25408
25782
|
var docTopics = ["workflow", "spec", "design", "product", "commit"];
|
|
25409
|
-
var summaries = {
|
|
25410
|
-
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",
|
|
25411
|
-
spec: "\uC0AC\uC6A9\uC790 \uC2A4\uD1A0\uB9AC\xB7\uC218\uC6A9 \uC870\uAC74 \uD615\uC2DD, ID \uADDC\uCE59, spec save \uC785\uB825",
|
|
25412
|
-
design: "design.md \uBAA9\uCC28, \uCC38\uC870 \uC8FC\uC11D, \uAC1C\uC815 \uBC29\uC2DD",
|
|
25413
|
-
product: "PRODUCT.md\uC640 guides \uBB38\uC11C\uC758 \uC5ED\uD560\uACFC \uC800\uC7A5 \uBA85\uB839",
|
|
25414
|
-
commit: "spec commit \uC785\uB825, \uC774\uC720 \uAE30\uB85D, \uC2E4\uD328 \uD6C4 \uBCF5\uAD6C"
|
|
25415
|
-
};
|
|
25416
25783
|
var isDocTopic = (value) => docTopics.includes(value);
|
|
25417
|
-
var readBundled = (topic) => readFile7(new URL("./docs/" + topic + ".md", import.meta.url), "utf8");
|
|
25418
|
-
function listDocTopics() {
|
|
25784
|
+
var readBundled = (topic, lang) => readFile7(new URL("./i18n/" + lang + "/docs/" + topic + ".md", import.meta.url), "utf8");
|
|
25785
|
+
function listDocTopics(lang = defaultLanguage2) {
|
|
25419
25786
|
const width = Math.max(...docTopics.map((topic) => topic.length));
|
|
25420
|
-
return docTopics.map((topic) => topic.padEnd(width) + " " +
|
|
25787
|
+
return docTopics.map((topic) => topic.padEnd(width) + " " + t2(`docs.summary.${topic}`, {}, lang)).join("\n") + "\n";
|
|
25421
25788
|
}
|
|
25422
25789
|
async function runDocs(topic, controls = {}) {
|
|
25423
25790
|
if (topic === void 0) {
|
|
@@ -25425,12 +25792,12 @@ async function runDocs(topic, controls = {}) {
|
|
|
25425
25792
|
return;
|
|
25426
25793
|
}
|
|
25427
25794
|
if (!isDocTopic(topic)) {
|
|
25428
|
-
const failure2 = { contract: "docs", version: 1, ok: false, error: { code: "UNKNOWN_TOPIC", message: "
|
|
25795
|
+
const failure2 = { contract: "docs", version: 1, ok: false, error: { code: "UNKNOWN_TOPIC", message: t2("docs.unknownTopic", { topic, topics: docTopics.join(", ") }) } };
|
|
25429
25796
|
process.stderr.write(JSON.stringify(failure2) + "\n");
|
|
25430
25797
|
process.exitCode = 1;
|
|
25431
25798
|
return;
|
|
25432
25799
|
}
|
|
25433
|
-
process.stdout.write(await (controls.readDoc ?? readBundled)(topic));
|
|
25800
|
+
process.stdout.write(await (controls.readDoc ?? readBundled)(topic, defaultLanguage2));
|
|
25434
25801
|
}
|
|
25435
25802
|
|
|
25436
25803
|
// src/commands/agent-block.ts
|
|
@@ -25448,52 +25815,21 @@ function boilerplateFor(path3) {
|
|
|
25448
25815
|
const name = path3 === "AGENTS.md" ? path3 : path3.split("/").pop().replace(/^\./, "").replace(/\.md$/, "");
|
|
25449
25816
|
return "# " + name + "\n\nProject-specific guidance for AI coding agents.\n";
|
|
25450
25817
|
}
|
|
25451
|
-
|
|
25452
|
-
|
|
25453
|
-
|
|
25454
|
-
|
|
25455
|
-
|
|
25456
|
-
"",
|
|
25457
|
-
"\uC2DC\uC791\uD560 \uB54C:",
|
|
25458
|
-
"- `gitifact spec working`\uC73C\uB85C \uC81C\uD488 \uC124\uBA85\xB7\uC9C0\uCE68\xB7\uAE30\uB2A5 \uBA85\uC138\uB97C \uC77D\uACE0 git status\uC640 \uAE30\uC874 staging\uC744 \uD655\uC778\uD55C\uB2E4.",
|
|
25459
|
-
"- \uC774 \uBE14\uB85D\uC740 \uC694\uC57D\uC774\uB2E4. \uC0C1\uC138 \uD615\uC2DD\uC740 `gitifact docs <topic>`\uC73C\uB85C \uC77D\uACE0 \uAE30\uC5B5\uC73C\uB85C \uCC44\uC6B0\uC9C0 \uC54A\uB294\uB2E4.",
|
|
25460
|
-
"",
|
|
25461
|
-
"\uBB34\uC5C7\uC744 \uC694\uAD6C\uC0AC\uD56D\uC73C\uB85C \uB0A8\uAE30\uB294\uAC00 (\uC81C\uD488 \uB3D9\uC791\uACFC \uC720\uC9C0\uD560 \uC81C\uC57D\uB9CC):",
|
|
25462
|
-
"| \uC694\uCCAD | \uCC98\uB9AC |",
|
|
25463
|
-
"| --- | --- |",
|
|
25464
|
-
"| \uAC8C\uC2DC\uBB3C\uC744 \uC0AD\uC81C\uD560 \uC218 \uC788\uAC8C \uD574\uC8FC\uC138\uC694 | \uC694\uAD6C\uC0AC\uD56D\uC73C\uB85C \uC815\uB9AC\uD55C\uB2E4 |",
|
|
25465
|
-
"| \uC774 \uB0B4\uBD80 \uD568\uC218 \uC774\uB984\uC744 \uBC14\uAFD4\uC8FC\uC138\uC694 | \uC77C\uBC18 \uAD6C\uD604 \uBCC0\uACBD\uC774\uB2E4 |",
|
|
25466
|
-
"| \uC9C0\uAE08 \uD478\uC2DC\uD574\uC8FC\uC138\uC694 | \uC791\uC5C5 \uC9C0\uC2DC\uB2E4. \uB4F1\uB85D\uD558\uC9C0 \uC54A\uB294\uB2E4 |",
|
|
25467
|
-
"| \uC678\uBD80 \uC11C\uBE44\uC2A4 \uC5C6\uC774 \uB3D9\uC791\uD574\uC57C \uD569\uB2C8\uB2E4 | \uC81C\uD488 \uC81C\uC57D\uC73C\uB85C \uBA85\uC138\uC5D0 \uBC18\uC601\uD55C\uB2E4 |",
|
|
25468
|
-
"",
|
|
25469
|
-
"\uADDC\uCE59:",
|
|
25470
|
-
"- \uBA85\uC138\uB97C \uC800\uC7A5\uD558\uAE30 \uC804\uC5D0 `gitifact docs spec`\uC744 \uC77D\uB294\uB2E4. ID\uB294 CLI\uAC00 \uBC1C\uAE09\uD55C \uAC12\uB9CC \uC4F4\uB2E4.",
|
|
25471
|
-
"- \uC0C8 \uAE30\uB2A5\uC740 requirements.md\uC640 design.md\uB97C \uD568\uAED8 \uC815\uB9AC\uD55C\uB2E4(`gitifact docs design`). \uC694\uAD6C\uC0AC\uD56D\uB9CC \uC694\uCCAD\uBC1B\uC73C\uBA74 \uB530\uB978\uB2E4.",
|
|
25472
|
-
"- \uCEE4\uBC0B \uC694\uCCAD\uC744 \uBC1B\uC73C\uBA74 `gitifact docs commit`\uC744 \uC77D\uACE0 \uBA85\uC138\xB7\uC774\uC720\xB7\uCF54\uB4DC\xB7\uD14C\uC2A4\uD2B8\uB97C \uD568\uAED8 \uCEE4\uBC0B\uD55C\uB2E4.",
|
|
25473
|
-
"- \uC790\uB3D9 \uAE30\uB85D\uC740 \uCEE4\uBC0B \uAD8C\uD55C\uC774 \uC544\uB2C8\uB2E4. \uC0AC\uC6A9\uC790 \uC694\uCCAD\uC774\uB098 \uBA85\uC2DC\uC801 \uD504\uB85C\uC81D\uD2B8 \uC815\uCC45\uC774 \uC788\uC744 \uB54C\uB9CC \uCEE4\uBC0B\uD558\uACE0 \uD478\uC2DC\uB294 \uBCC4\uB3C4 \uC694\uCCAD\uC744 \uB530\uB978\uB2E4.",
|
|
25474
|
-
"- \uBD88\uBA85\uD655\uD55C \uC81C\uD488 \uB3D9\uC791\uB9CC \uC9C8\uBB38\uD558\uACE0 \uB3C5\uB9BD\uC801\uC778 \uC791\uC5C5\uC740 \uC9C4\uD589\uD55C\uB2E4. \uAE30\uC874 \uAE30\uB2A5 \uC804\uCCB4 \uB3C4\uCD9C\uC740 \uC694\uCCAD\uBC1B\uC558\uC744 \uB54C \uD55C\uB2E4.",
|
|
25475
|
-
"- SELF-CHECK: save\xB7commit \uC785\uB825\uC744 \uB9CC\uB4E4\uAE30 \uC804\uC5D0 \uD574\uB2F9 docs\uB97C \uB2E4\uC2DC \uC77D\uACE0 \uD615\uC2DD\uC744 \uB300\uC870\uD55C\uB2E4. \uD655\uC2E4\uD558\uC9C0 \uC54A\uC73C\uBA74 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 `gitifact docs <topic>`\uC744 \uC2E4\uD589\uD55C\uB2E4.",
|
|
25476
|
-
"",
|
|
25477
|
-
"MORE CLI:",
|
|
25478
|
-
" docs <topic> " + docTopics.join(", "),
|
|
25479
|
-
" spec working \uD604\uC7AC \uBA85\uC138\xB7\uC81C\uD488\xB7\uC9C0\uCE68 \uC804\uCCB4\uC640 stamp",
|
|
25480
|
-
" spec save --file <json>: \uC694\uAD6C\uC0AC\uD56D\xB7\uC124\uACC4\xB7\uBB38\uC11C \uC800\uC7A5",
|
|
25481
|
-
" spec commit --file <json>: \uBCC0\uACBD \uC774\uC720 \uAE30\uB85D\uACFC \uCEE4\uBC0B\uC744 \uD55C \uBC88\uC5D0",
|
|
25482
|
-
" browser \uC77D\uAE30 \uC804\uC6A9 \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30",
|
|
25483
|
-
" init \uB2E4\uC2DC \uC2E4\uD589\uD558\uBA74 \uC774 \uBE14\uB85D\uC744 \uAC31\uC2E0\uD55C\uB2E4",
|
|
25484
|
-
AGENT_END
|
|
25485
|
-
];
|
|
25486
|
-
return lines.join("\n");
|
|
25818
|
+
var readBundledBlock = (lang) => readFile8(new URL("./i18n/" + lang + "/block.md", import.meta.url), "utf8");
|
|
25819
|
+
async function renderAgentBlock(version2, controls = {}, lang = defaultLanguage2) {
|
|
25820
|
+
const body = await (controls.readBlock ?? readBundledBlock)(lang);
|
|
25821
|
+
const filled = body.trimEnd().replace(/\{(version|language|topics)\}/g, (_whole, name) => name === "version" ? version2 : name === "language" ? lang : docTopics.join(", "));
|
|
25822
|
+
return AGENT_START + "\n" + filled + "\n" + AGENT_END;
|
|
25487
25823
|
}
|
|
25488
25824
|
function findBlock(text2) {
|
|
25489
25825
|
const start = text2.indexOf(AGENT_START);
|
|
25490
25826
|
if (start === -1) {
|
|
25491
|
-
if (text2.includes(AGENT_END)) throw new InitError("AGENT_DOCS_MALFORMED", "
|
|
25827
|
+
if (text2.includes(AGENT_END)) throw new InitError("AGENT_DOCS_MALFORMED", t2("agentBlock.endWithoutStart"));
|
|
25492
25828
|
return null;
|
|
25493
25829
|
}
|
|
25494
25830
|
const end = text2.indexOf(AGENT_END, start + AGENT_START.length);
|
|
25495
|
-
if (end === -1) throw new InitError("AGENT_DOCS_MALFORMED", "
|
|
25496
|
-
if (text2.indexOf(AGENT_START, start + AGENT_START.length) !== -1) throw new InitError("AGENT_DOCS_MALFORMED", "
|
|
25831
|
+
if (end === -1) throw new InitError("AGENT_DOCS_MALFORMED", t2("agentBlock.startWithoutEnd"));
|
|
25832
|
+
if (text2.indexOf(AGENT_START, start + AGENT_START.length) !== -1) throw new InitError("AGENT_DOCS_MALFORMED", t2("agentBlock.duplicateStart"));
|
|
25497
25833
|
return { start, end: end + AGENT_END.length };
|
|
25498
25834
|
}
|
|
25499
25835
|
function isWrapperFile(text2) {
|
|
@@ -25555,7 +25891,7 @@ async function planAgentDocs(root, options) {
|
|
|
25555
25891
|
}
|
|
25556
25892
|
return { mode: "remove", paths: paths2, writes };
|
|
25557
25893
|
}
|
|
25558
|
-
const block = renderAgentBlock(options.version);
|
|
25894
|
+
const block = await renderAgentBlock(options.version, options);
|
|
25559
25895
|
const { inject, create } = resolveAgentPaths(options.agent, existing);
|
|
25560
25896
|
for (const path3 of inject) {
|
|
25561
25897
|
const previous = existing.get(path3);
|
|
@@ -25597,10 +25933,10 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
|
|
|
25597
25933
|
});
|
|
25598
25934
|
const existing = async (text3) => {
|
|
25599
25935
|
const config3 = parseManagedConfig(text3);
|
|
25600
|
-
if (!("schemaVersion" in config3)) throw new InitError("MIGRATION_REQUIRED", "
|
|
25936
|
+
if (!("schemaVersion" in config3)) throw new InitError("MIGRATION_REQUIRED", t2("init.migrationRequired"));
|
|
25601
25937
|
await repo.validateBaseline(config3, root, first.state.head.commit, first.state.repository.objectFormat);
|
|
25602
25938
|
const unchanged = async () => {
|
|
25603
|
-
if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text3) throw new InitError("INPUT_CHANGED", "
|
|
25939
|
+
if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text3) throw new InitError("INPUT_CHANGED", t2("init.inputChanged"));
|
|
25604
25940
|
};
|
|
25605
25941
|
await unchanged();
|
|
25606
25942
|
if (!dryRun) await applyAgentDocs(root, docsPlan, unchanged);
|
|
@@ -25608,22 +25944,22 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
|
|
|
25608
25944
|
};
|
|
25609
25945
|
const old = await readConfigFile(root);
|
|
25610
25946
|
if (old !== void 0) return existing(old);
|
|
25611
|
-
if (first.trackedConfig) throw new InitError("CONFIG_DELETED", "
|
|
25947
|
+
if (first.trackedConfig) throw new InitError("CONFIG_DELETED", t2("init.configDeleted"));
|
|
25612
25948
|
const checkRecords = async () => {
|
|
25613
|
-
if (await fileInfo(join7(root, "specs"))) throw new InitError("EXISTING_RECORDS", "
|
|
25949
|
+
if (await fileInfo(join7(root, "specs"))) throw new InitError("EXISTING_RECORDS", t2("init.existingSpecs"));
|
|
25614
25950
|
const entries = await readdir3(join7(root, ".gitifact")).catch((e) => {
|
|
25615
25951
|
if (e.code === "ENOENT") return [];
|
|
25616
25952
|
throw e;
|
|
25617
25953
|
});
|
|
25618
|
-
if (entries.some((name) => !/^\.init-[a-f0-9-]+\.tmp$/.test(name))) throw new InitError("EXISTING_RECORDS", "
|
|
25954
|
+
if (entries.some((name) => !/^\.init-[a-f0-9-]+\.tmp$/.test(name))) throw new InitError("EXISTING_RECORDS", t2("init.orphanStore"));
|
|
25619
25955
|
};
|
|
25620
25956
|
const config2 = { schemaVersion: 1, baseline: first.state.head.commit ? { kind: "commit", objectFormat: first.state.repository.objectFormat, commit: first.state.head.commit } : { kind: "empty" } };
|
|
25621
25957
|
const text2 = JSON.stringify(config2, null, 2) + "\n";
|
|
25622
25958
|
const recheck = async () => {
|
|
25623
25959
|
await checkRecords();
|
|
25624
25960
|
await repo.checkIgnore(root);
|
|
25625
|
-
if ((await repo.inspect()).stamp !== first.stamp) throw new InitError("INPUT_CHANGED", "
|
|
25626
|
-
if (await readConfigFile(root) !== void 0) throw new InitError("CONFIG_APPEARED", "
|
|
25961
|
+
if ((await repo.inspect()).stamp !== first.stamp) throw new InitError("INPUT_CHANGED", t2("init.headOrIndexChanged"));
|
|
25962
|
+
if (await readConfigFile(root) !== void 0) throw new InitError("CONFIG_APPEARED", t2("init.configAppeared"));
|
|
25627
25963
|
};
|
|
25628
25964
|
await recheck();
|
|
25629
25965
|
if (dryRun) return result(config2, "planned");
|
|
@@ -25637,7 +25973,7 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
|
|
|
25637
25973
|
throw error62;
|
|
25638
25974
|
}
|
|
25639
25975
|
const published = async () => {
|
|
25640
|
-
if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text2) throw new InitError("INPUT_CHANGED_AFTER_WRITE", "
|
|
25976
|
+
if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== text2) throw new InitError("INPUT_CHANGED_AFTER_WRITE", t2("init.changedAfterWrite"));
|
|
25641
25977
|
};
|
|
25642
25978
|
await published();
|
|
25643
25979
|
await applyAgentDocs(root, docsPlan, published);
|
|
@@ -25655,14 +25991,14 @@ async function runInit(options, version2) {
|
|
|
25655
25991
|
{ version: version2, agent: options.agent, remove: options.removeAgents, skip: options.skipAgents }
|
|
25656
25992
|
);
|
|
25657
25993
|
if (!dto.ok) throw new Error("unreachable");
|
|
25658
|
-
const docs = dto.agentDocs.mode === "skip" ? "
|
|
25994
|
+
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") + ")");
|
|
25659
25995
|
process.stdout.write(options.format === "text" ? `${dto.outcome}: ${dto.rootPath}/.gitifact/config.json
|
|
25660
|
-
|
|
25661
|
-
|
|
25996
|
+
${t2("init.text.storage")}: schemaVersion 1
|
|
25997
|
+
${t2("init.text.agentDocs")}: ${docs}
|
|
25662
25998
|
` : JSON.stringify(dto) + "\n");
|
|
25663
25999
|
} catch (error62) {
|
|
25664
26000
|
const known = error62 instanceof InitError || error62 instanceof RepositoryReadError;
|
|
25665
|
-
const failure2 = { code: known ? error62.code : "INIT_FAILED", message: known ? error62.message : "
|
|
26001
|
+
const failure2 = { code: known ? error62.code : "INIT_FAILED", message: known ? error62.message : t2("init.failed") };
|
|
25666
26002
|
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");
|
|
25667
26003
|
process.exitCode = 1;
|
|
25668
26004
|
}
|
|
@@ -25670,7 +26006,7 @@ async function runInit(options, version2) {
|
|
|
25670
26006
|
|
|
25671
26007
|
// src/commands/spec-preview.ts
|
|
25672
26008
|
import { join as join12 } from "node:path";
|
|
25673
|
-
import { readFile as
|
|
26009
|
+
import { readFile as readFile12, stat as stat2 } from "node:fs/promises";
|
|
25674
26010
|
|
|
25675
26011
|
// src/adapters/filesystem/spec-preview-prepare.ts
|
|
25676
26012
|
import { lstat as lstat4 } from "node:fs/promises";
|
|
@@ -25691,7 +26027,7 @@ async function readPreviewContext(cwd) {
|
|
|
25691
26027
|
if (e.code === "ENOENT") return void 0;
|
|
25692
26028
|
throw e;
|
|
25693
26029
|
});
|
|
25694
|
-
if (exists) fail5("
|
|
26030
|
+
if (exists) fail5(t2("prepare.integrationInProgress"));
|
|
25695
26031
|
}
|
|
25696
26032
|
};
|
|
25697
26033
|
await checkOperation();
|
|
@@ -25702,7 +26038,7 @@ async function readPreviewContext(cwd) {
|
|
|
25702
26038
|
const specs = bundle.specs;
|
|
25703
26039
|
const recheck = async () => {
|
|
25704
26040
|
await checkOperation();
|
|
25705
|
-
if (!same(base, await reader.baseline())) fail5("
|
|
26041
|
+
if (!same(base, await reader.baseline())) fail5(t2("prepare.headChanged"));
|
|
25706
26042
|
};
|
|
25707
26043
|
return { reader, base, files, specs, bundle, recheck, working };
|
|
25708
26044
|
}
|
|
@@ -25716,12 +26052,12 @@ async function readFinalPreviewChanges(cwd) {
|
|
|
25716
26052
|
return { base: c.base, expected: expected(c.base, current.stamp), stamp: current.stamp, pendingReasons, ...delta };
|
|
25717
26053
|
}
|
|
25718
26054
|
async function prepareWorkingPreview(cwd, input2, publish) {
|
|
25719
|
-
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5("
|
|
26055
|
+
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5(t2("prepare.invalidInput"));
|
|
25720
26056
|
const request = input2;
|
|
25721
|
-
if (Object.keys(request).sort().join(",") !== "expected,reasons" || typeof request.expected !== "string") fail5("
|
|
26057
|
+
if (Object.keys(request).sort().join(",") !== "expected,reasons" || typeof request.expected !== "string") fail5(t2("prepare.expectedReasons"));
|
|
25722
26058
|
const c = await context(cwd);
|
|
25723
26059
|
const current = await readWorkingPreviewState(cwd);
|
|
25724
|
-
if (request.expected !== expected(c.base, current.stamp)) fail5("
|
|
26060
|
+
if (request.expected !== expected(c.base, current.stamp)) fail5(t2("prepare.staleInput"));
|
|
25725
26061
|
const result = await previewTransaction(cwd, current.stamp, async (before) => {
|
|
25726
26062
|
await c.recheck();
|
|
25727
26063
|
const prepared = prepareSpecPreview(c.bundle, before.bundle, c.files, before.files, request.reasons, () => generatePreviewId("H"));
|
|
@@ -25730,44 +26066,44 @@ async function prepareWorkingPreview(cwd, input2, publish) {
|
|
|
25730
26066
|
return { ...result, base: c.base, expected: expected(c.base, result.stamp), verification: { base: c.base, stamp: result.stamp } };
|
|
25731
26067
|
}
|
|
25732
26068
|
async function verifyPreparedPreview(cwd, input2, staged) {
|
|
25733
|
-
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5("
|
|
26069
|
+
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) fail5(t2("prepare.invalidVerifyInput"));
|
|
25734
26070
|
const request = input2;
|
|
25735
|
-
if (Object.keys(request).sort().join(",") !== "base,stamp" || typeof request.stamp !== "string") fail5("prepare
|
|
26071
|
+
if (Object.keys(request).sort().join(",") !== "base,stamp" || typeof request.stamp !== "string") fail5(t2("prepare.verificationRequired"));
|
|
25736
26072
|
const c = await context(cwd);
|
|
25737
26073
|
const current = await readWorkingPreviewState(cwd);
|
|
25738
|
-
if (!same(request.base, c.base) || request.stamp !== current.stamp) fail5("
|
|
26074
|
+
if (!same(request.base, c.base) || request.stamp !== current.stamp) fail5(t2("prepare.changedAfterPrepare"));
|
|
25739
26075
|
finalSpecPreviewChanges(c.bundle, current.bundle);
|
|
25740
26076
|
comparePreviewBundles(c.bundle, current.bundle);
|
|
25741
26077
|
if (staged) {
|
|
25742
26078
|
const index = await c.reader.index();
|
|
25743
|
-
if (index.size !== current.files.size) fail5("
|
|
26079
|
+
if (index.size !== current.files.size) fail5(t2("prepare.stagingScope"));
|
|
25744
26080
|
for (const [path3, source] of current.files) {
|
|
25745
26081
|
const oid2 = index.get(path3);
|
|
25746
26082
|
const bytes = Buffer.from(source);
|
|
25747
26083
|
const hash3 = createHash4(oid2?.length === 64 ? "sha256" : "sha1").update(`blob ${bytes.length}\0`).update(bytes).digest("hex");
|
|
25748
|
-
if (oid2 !== hash3) fail5("
|
|
26084
|
+
if (oid2 !== hash3) fail5(t2("prepare.stagingContent", { path: path3 }));
|
|
25749
26085
|
}
|
|
25750
|
-
if (!same([...index], [...await c.reader.index()])) fail5("
|
|
26086
|
+
if (!same([...index], [...await c.reader.index()])) fail5(t2("prepare.stagingChanged"));
|
|
25751
26087
|
}
|
|
25752
|
-
if ((await readWorkingPreviewState(cwd)).stamp !== current.stamp) fail5("
|
|
26088
|
+
if ((await readWorkingPreviewState(cwd)).stamp !== current.stamp) fail5(t2("prepare.specsChanged"));
|
|
25753
26089
|
await c.recheck();
|
|
25754
26090
|
return { verified: true, scope: staged ? "staged" : "working", base: c.base, stamp: current.stamp };
|
|
25755
26091
|
}
|
|
25756
26092
|
|
|
25757
26093
|
// src/commands/spec-preview-commit.ts
|
|
25758
26094
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
25759
|
-
import { readFile as
|
|
26095
|
+
import { readFile as readFile10, mkdir as mkdir4, open as open4, rename as rename3, unlink as unlink4, rmdir as rmdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
25760
26096
|
import { join as join10 } from "node:path";
|
|
25761
26097
|
|
|
25762
26098
|
// src/commands/spec-commit-files.ts
|
|
25763
26099
|
import { createHash as createHash5 } from "node:crypto";
|
|
25764
|
-
import { lstat as lstat5, readFile as
|
|
26100
|
+
import { lstat as lstat5, readFile as readFile9 } from "node:fs/promises";
|
|
25765
26101
|
import { join as join9 } from "node:path";
|
|
25766
26102
|
var fail6 = (message) => {
|
|
25767
26103
|
throw new SpecPreviewError(message);
|
|
25768
26104
|
};
|
|
25769
26105
|
var hash2 = (value) => createHash5("sha256").update(value).digest("hex");
|
|
25770
|
-
var optional2 = (path3) =>
|
|
26106
|
+
var optional2 = (path3) => readFile9(path3).catch((e) => {
|
|
25771
26107
|
if (e.code === "ENOENT") return null;
|
|
25772
26108
|
throw e;
|
|
25773
26109
|
});
|
|
@@ -25777,7 +26113,7 @@ var info2 = (path3) => lstat5(path3).catch((e) => {
|
|
|
25777
26113
|
});
|
|
25778
26114
|
var record2 = (path3) => recordPathPattern.test(path3);
|
|
25779
26115
|
function validPath2(path3) {
|
|
25780
|
-
if (typeof path3 !== "string" || path3.length > 1e3 || /[\\:\x00-\x1f\x7f]/.test(path3) || path3.split("/").some((p) => !p || p === "." || p === ".." || p.toLowerCase() === ".git")) fail6("
|
|
26116
|
+
if (typeof path3 !== "string" || path3.length > 1e3 || /[\\:\x00-\x1f\x7f]/.test(path3) || path3.split("/").some((p) => !p || p === "." || p === ".." || p.toLowerCase() === ".git")) fail6(t2("commitFiles.relativePath"));
|
|
25781
26117
|
}
|
|
25782
26118
|
async function fingerprint(root, path3) {
|
|
25783
26119
|
validPath2(path3);
|
|
@@ -25786,25 +26122,25 @@ async function fingerprint(root, path3) {
|
|
|
25786
26122
|
const target = join9(root, ...parts.slice(0, i));
|
|
25787
26123
|
const stat3 = await info2(target);
|
|
25788
26124
|
if (!stat3) return null;
|
|
25789
|
-
if (stat3.isSymbolicLink() || (i < parts.length ? !stat3.isDirectory() : !stat3.isFile())) fail6("
|
|
25790
|
-
if (i < parts.length && await info2(join9(target, ".git"))) fail6("
|
|
26125
|
+
if (stat3.isSymbolicLink() || (i < parts.length ? !stat3.isDirectory() : !stat3.isFile())) fail6(t2("commitFiles.linkOrDirectory"));
|
|
26126
|
+
if (i < parts.length && await info2(join9(target, ".git"))) fail6(t2("commitFiles.nestedRepository"));
|
|
25791
26127
|
if (i === parts.length) {
|
|
25792
|
-
if (stat3.nlink !== 1 || stat3.size > 16 * 1024 * 1024) fail6("
|
|
25793
|
-
return hash2(Buffer.concat([Buffer.from(String(stat3.mode & 73) + "\0"), await
|
|
26128
|
+
if (stat3.nlink !== 1 || stat3.size > 16 * 1024 * 1024) fail6(t2("commitFiles.hardLinkOrSize"));
|
|
26129
|
+
return hash2(Buffer.concat([Buffer.from(String(stat3.mode & 73) + "\0"), await readFile9(target)]));
|
|
25794
26130
|
}
|
|
25795
26131
|
}
|
|
25796
26132
|
return null;
|
|
25797
26133
|
}
|
|
25798
26134
|
function object3(input2) {
|
|
25799
|
-
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) return fail6("
|
|
26135
|
+
if (!input2 || typeof input2 !== "object" || Array.isArray(input2)) return fail6(t2("commitFiles.invalidInput"));
|
|
25800
26136
|
return input2;
|
|
25801
26137
|
}
|
|
25802
26138
|
function text(value, limit) {
|
|
25803
|
-
if (typeof value !== "string" || !value.trim() || value.length > limit || value.includes("\0")) return fail6("
|
|
26139
|
+
if (typeof value !== "string" || !value.trim() || value.length > limit || value.includes("\0")) return fail6(t2("commitFiles.emptyOrTooLong"));
|
|
25804
26140
|
return value;
|
|
25805
26141
|
}
|
|
25806
26142
|
function paths(value, limit = 128) {
|
|
25807
|
-
if (!Array.isArray(value) || !value.length || value.length > limit || value.some((p) => typeof p !== "string")) return fail6("
|
|
26143
|
+
if (!Array.isArray(value) || !value.length || value.length > limit || value.some((p) => typeof p !== "string")) return fail6(t2("commitFiles.invalidPaths"));
|
|
25808
26144
|
const list = [...new Set(value)].sort();
|
|
25809
26145
|
list.forEach(validPath2);
|
|
25810
26146
|
return list;
|
|
@@ -25821,10 +26157,10 @@ async function checkLegacySelection(root, selected) {
|
|
|
25821
26157
|
const legacyJson = /^\.(?:gitifact|tryce)\/(?:spec\/[^/]+\/tryce\.json|notes\/N-[a-f0-9-]+\.json|mode-[a-f0-9-]+\.json|config\.(?:init-1|prototype-1)\.[a-f0-9]+\.json)$/;
|
|
25822
26158
|
for (const p of selected.filter((p2) => p2.startsWith(".gitifact/") && !record2(p2) && p2 !== ".gitifact/config.json")) {
|
|
25823
26159
|
if (isProductAssetPath(p)) continue;
|
|
25824
|
-
if (!legacyJson.test(p) || await fingerprint(root, p) !== null) fail6(".
|
|
26160
|
+
if (!legacyJson.test(p) || await fingerprint(root, p) !== null) fail6(t2("commitFiles.legacyDeleteOnly", { path: p }));
|
|
25825
26161
|
}
|
|
25826
26162
|
for (const p of selected.filter((p2) => p2.startsWith(".tryce/"))) {
|
|
25827
|
-
if (!(record2(p) || p === ".tryce/config.json" || legacyJson.test(p)) || await fingerprint(root, p) !== null) fail6(".
|
|
26163
|
+
if (!(record2(p) || p === ".tryce/config.json" || legacyJson.test(p)) || await fingerprint(root, p) !== null) fail6(t2("commitFiles.tryceDeleteOnly", { path: p }));
|
|
25828
26164
|
}
|
|
25829
26165
|
}
|
|
25830
26166
|
|
|
@@ -25854,30 +26190,30 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25854
26190
|
const indexPath = (await git(["rev-parse", "--path-format=absolute", "--git-path", "index"])).toString("utf8").trim();
|
|
25855
26191
|
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();
|
|
25856
26192
|
const busy = join10(gitDir, "gitifact-spec-commit.lock");
|
|
25857
|
-
if (await info2(busy)) fail6("
|
|
25858
|
-
if ((await staged()).length) fail6("
|
|
26193
|
+
if (await info2(busy)) fail6(t2("commit.busy", { path: busy }));
|
|
26194
|
+
if ((await staged()).length) fail6(t2("commit.existingStagingPlan"));
|
|
25859
26195
|
const request = object3(input2);
|
|
25860
26196
|
let plan;
|
|
25861
26197
|
if (action === "plan") {
|
|
25862
|
-
if (Object.keys(request).some((k) => !["verification", "paths", "message", "requirements", "authorization", "policyFiles"].includes(k))) fail6("
|
|
26198
|
+
if (Object.keys(request).some((k) => !["verification", "paths", "message", "requirements", "authorization", "policyFiles"].includes(k))) fail6(t2("commit.unknownField"));
|
|
25863
26199
|
await verifyPreparedPreview(cwd, request.verification, false);
|
|
25864
26200
|
const selected2 = paths(request.paths);
|
|
25865
26201
|
const authorization = object3(request.authorization);
|
|
25866
26202
|
await checkLegacySelection(root, selected2);
|
|
25867
|
-
if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail6("
|
|
26203
|
+
if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail6(t2("commit.authorizationRequired"));
|
|
25868
26204
|
const message = text(request.message, 4e3);
|
|
25869
|
-
if (/^\s*Gitifact-/im.test(message)) fail6("
|
|
26205
|
+
if (/^\s*Gitifact-/im.test(message)) fail6(t2("commit.trailerInMessage"));
|
|
25870
26206
|
const state = await readWorkingPreviewState(cwd);
|
|
25871
26207
|
const base = await reader.baseline();
|
|
25872
26208
|
const previous = base.head ? await reader.files(base.head, state.config !== void 0) : /* @__PURE__ */ new Map();
|
|
25873
26209
|
const pending = [.../* @__PURE__ */ new Set([...previous.keys(), ...state.files.keys()])].filter((p) => previous.get(p) !== state.files.get(p));
|
|
25874
|
-
if (pending.some((p) => !selected2.includes(p))) fail6("
|
|
26210
|
+
if (pending.some((p) => !selected2.includes(p))) fail6(t2("commit.selectPending"));
|
|
25875
26211
|
const delta = await readFinalPreviewChanges(cwd);
|
|
25876
26212
|
const references = request.requirements ?? [];
|
|
25877
|
-
if (!Array.isArray(references) || references.length > 1e3 || references.some((r) => typeof r !== "string")) fail6("
|
|
25878
|
-
if (delta.changes.some((c) => c.kind === "design")) fail6("
|
|
26213
|
+
if (!Array.isArray(references) || references.length > 1e3 || references.some((r) => typeof r !== "string")) fail6(t2("commit.invalidReferences"));
|
|
26214
|
+
if (delta.changes.some((c) => c.kind === "design")) fail6(t2("commit.designUseSpecCommit"));
|
|
25879
26215
|
const known = /* @__PURE__ */ new Set([...state.specs.flatMap((s) => s.requirements.map((r) => r.id)), ...delta.changes.map((c) => c.id)]);
|
|
25880
|
-
if (references.some((r) => !known.has(r))) fail6("
|
|
26216
|
+
if (references.some((r) => !known.has(r))) fail6(t2("commit.unknownRequirement"));
|
|
25881
26217
|
const extra = request.policyFiles === void 0 ? [] : paths(request.policyFiles, 1024);
|
|
25882
26218
|
const contents = async (list) => Promise.all(list.map(async (path3) => ({ path: path3, hash: await fingerprint(root, path3) })));
|
|
25883
26219
|
const data2 = {
|
|
@@ -25892,13 +26228,13 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25892
26228
|
authorization: { basis: String(authorization.basis), evidence: text(authorization.evidence, 2e3) }
|
|
25893
26229
|
};
|
|
25894
26230
|
await verifyPreparedPreview(cwd, request.verification, false);
|
|
25895
|
-
if (data2.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6("
|
|
26231
|
+
if (data2.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6(t2("commit.indexChangedPlanning"));
|
|
25896
26232
|
return { outcome: "planned", plan: { ...data2, digest: seal(data2) }, committed: false };
|
|
25897
26233
|
}
|
|
25898
26234
|
const { digest: digest2, ...data } = request;
|
|
25899
|
-
if (request.kind !== "spec-preview-commit" || typeof digest2 !== "string" || digest2 !== seal(data)) fail6("
|
|
26235
|
+
if (request.kind !== "spec-preview-commit" || typeof digest2 !== "string" || digest2 !== seal(data)) fail6(t2("commit.planCorrupted"));
|
|
25900
26236
|
plan = request;
|
|
25901
|
-
if (plan.root !== root || !Array.isArray(plan.files) || !Array.isArray(plan.context)) fail6("
|
|
26237
|
+
if (plan.root !== root || !Array.isArray(plan.files) || !Array.isArray(plan.context)) fail6(t2("commit.planScope"));
|
|
25902
26238
|
const selected = paths(plan.files.map((f) => f.path));
|
|
25903
26239
|
const refreshed = await previewCommit(cwd, "plan", {
|
|
25904
26240
|
verification: plan.verification,
|
|
@@ -25908,7 +26244,7 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25908
26244
|
authorization: plan.authorization,
|
|
25909
26245
|
policyFiles: plan.context.map((f) => f.path)
|
|
25910
26246
|
});
|
|
25911
|
-
if (!("plan" in refreshed) || refreshed.plan.digest !== plan.digest) fail6("
|
|
26247
|
+
if (!("plan" in refreshed) || refreshed.plan.digest !== plan.digest) fail6(t2("commit.planStale"));
|
|
25912
26248
|
const before = await reader.baseline();
|
|
25913
26249
|
const original = await optional2(indexPath);
|
|
25914
26250
|
await mkdir4(busy);
|
|
@@ -25919,28 +26255,28 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25919
26255
|
let commitStarted = false;
|
|
25920
26256
|
const temporary = join10(gitDir, "gitifact-commit-index-" + randomUUID6());
|
|
25921
26257
|
const checkFiles = async () => {
|
|
25922
|
-
for (const f of [...plan.files, ...plan.context]) if (f.hash !== await fingerprint(root, f.path)) fail6("
|
|
25923
|
-
if ((await readLockedPreviewState(root)).stamp !== object3(plan.verification).stamp) fail6("
|
|
25924
|
-
for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) if (await info2(join10(gitDir, name))) fail6("
|
|
26258
|
+
for (const f of [...plan.files, ...plan.context]) if (f.hash !== await fingerprint(root, f.path)) fail6(t2("commit.fileChangedPreparing", { path: f.path }));
|
|
26259
|
+
if ((await readLockedPreviewState(root)).stamp !== object3(plan.verification).stamp) fail6(t2("commit.specsChangedPreparing"));
|
|
26260
|
+
for (const name of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"]) if (await info2(join10(gitDir, name))) fail6(t2("commit.integrationStarted"));
|
|
25925
26261
|
};
|
|
25926
26262
|
try {
|
|
25927
26263
|
await verifyPreparedPreview(cwd, plan.verification, false);
|
|
25928
26264
|
await mkdir4(draftLock);
|
|
25929
26265
|
draftOwned = true;
|
|
25930
26266
|
indexLock = await open4(indexPath + ".lock", "wx", 384);
|
|
25931
|
-
if (plan.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6("
|
|
26267
|
+
if (plan.index !== hash2(await optional2(indexPath) ?? Buffer.alloc(0)) || (await staged()).length) fail6(t2("commit.indexChangedLocked"));
|
|
25932
26268
|
await writeFile2(join10(busy, "recovery.json"), JSON.stringify({ before, originalIndex: original?.toString("base64") ?? null, temporary, plan }));
|
|
25933
26269
|
if (original) await writeFile2(temporary, original, { flag: "wx" });
|
|
25934
26270
|
else await git(["read-tree", "--empty"], temporary);
|
|
25935
26271
|
await git(["add", "--", ...selected], temporary);
|
|
25936
26272
|
const actual = await staged(temporary);
|
|
25937
|
-
if (!actual.length || actual.some((p) => !selected.includes(p))) fail6("
|
|
26273
|
+
if (!actual.length || actual.some((p) => !selected.includes(p))) fail6(t2("commit.unexpectedFiles"));
|
|
25938
26274
|
for (const file2 of plan.files.filter((f) => record2(f.path) && f.hash !== null)) {
|
|
25939
26275
|
const stagedBytes = await git(["show", ":" + file2.path], temporary);
|
|
25940
|
-
if (!stagedBytes.equals(await
|
|
26276
|
+
if (!stagedBytes.equals(await readFile10(join10(root, file2.path)))) fail6(t2("commit.filterChanged"));
|
|
25941
26277
|
}
|
|
25942
26278
|
await checkFiles();
|
|
25943
|
-
if (JSON.stringify(before) !== JSON.stringify(await reader.baseline())) fail6("
|
|
26279
|
+
if (JSON.stringify(before) !== JSON.stringify(await reader.baseline())) fail6(t2("commit.headChanged"));
|
|
25944
26280
|
const tree = (await git(["write-tree"], temporary)).toString("utf8").trim();
|
|
25945
26281
|
const trailers = plan.requirements.map((id) => "Gitifact-Req: " + id);
|
|
25946
26282
|
commitStarted = true;
|
|
@@ -25949,10 +26285,10 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25949
26285
|
const actualTree = (await git(["rev-parse", "HEAD^{tree}"])).toString("utf8").trim();
|
|
25950
26286
|
const parents = (await git(["rev-list", "--parents", "-n", "1", "HEAD"])).toString("utf8").trim().split(" ").slice(1);
|
|
25951
26287
|
const message = (await git(["log", "-1", "--format=%B"])).toString("utf8");
|
|
25952
|
-
if (actualTree !== tree || after.branch !== before.branch || JSON.stringify(parents) !== JSON.stringify(before.head ? [before.head] : []) || trailers.some((
|
|
25953
|
-
if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== plan.index) fail6("
|
|
25954
|
-
if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6("
|
|
25955
|
-
await indexLock.writeFile(await
|
|
26288
|
+
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"));
|
|
26289
|
+
if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== plan.index) fail6(t2("commit.indexChangedAfter"));
|
|
26290
|
+
if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6(t2("commit.hookChangedStaging"));
|
|
26291
|
+
await indexLock.writeFile(await readFile10(temporary));
|
|
25956
26292
|
await indexLock.sync();
|
|
25957
26293
|
await indexLock.close();
|
|
25958
26294
|
await rename3(indexPath + ".lock", indexPath);
|
|
@@ -25966,7 +26302,7 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25966
26302
|
uncertain = true;
|
|
25967
26303
|
}
|
|
25968
26304
|
}
|
|
25969
|
-
if (uncertain) fail6("
|
|
26305
|
+
if (uncertain) fail6(t2("commit.uncertain", { path: busy }));
|
|
25970
26306
|
throw error62;
|
|
25971
26307
|
} finally {
|
|
25972
26308
|
await indexLock?.close().catch(() => {
|
|
@@ -25986,24 +26322,24 @@ async function previewCommit(cwd, action, input2) {
|
|
|
25986
26322
|
|
|
25987
26323
|
// src/commands/spec-commit.ts
|
|
25988
26324
|
import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
|
|
25989
|
-
import { mkdir as mkdir5, open as open5, readFile as
|
|
26325
|
+
import { mkdir as mkdir5, open as open5, readFile as readFile11, rename as rename4, rmdir as rmdir3, unlink as unlink5, writeFile as writeFile3 } from "node:fs/promises";
|
|
25990
26326
|
import { join as join11 } from "node:path";
|
|
25991
26327
|
var fields = ["reasons", "paths", "message", "authorization", "requirements", "policyFiles", "expected"];
|
|
25992
26328
|
var integration = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply"];
|
|
25993
26329
|
var same2 = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
25994
26330
|
async function specCommit(cwd, input2, dryRun) {
|
|
25995
26331
|
const request = object3(input2);
|
|
25996
|
-
if (Object.keys(request).some((k) => !fields.includes(k))) fail6("
|
|
26332
|
+
if (Object.keys(request).some((k) => !fields.includes(k))) fail6(t2("commit.unknownField"));
|
|
25997
26333
|
const selected = paths(request.paths);
|
|
25998
26334
|
const authorization = object3(request.authorization);
|
|
25999
|
-
if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail6("
|
|
26335
|
+
if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail6(t2("commit.authorizationRequired"));
|
|
26000
26336
|
text(authorization.evidence, 2e3);
|
|
26001
26337
|
const message = text(request.message, 4e3);
|
|
26002
|
-
if (/^\s*Gitifact-/im.test(message)) fail6("
|
|
26338
|
+
if (/^\s*Gitifact-/im.test(message)) fail6(t2("commit.trailerInMessage"));
|
|
26003
26339
|
const references = request.requirements ?? [];
|
|
26004
|
-
if (!Array.isArray(references) || references.length > 1e3 || references.some((r) => typeof r !== "string")) fail6("
|
|
26340
|
+
if (!Array.isArray(references) || references.length > 1e3 || references.some((r) => typeof r !== "string")) fail6(t2("commit.invalidReferences"));
|
|
26005
26341
|
const extra = request.policyFiles === void 0 ? [] : paths(request.policyFiles, 1024);
|
|
26006
|
-
if (request.expected !== void 0 && typeof request.expected !== "string") fail6("
|
|
26342
|
+
if (request.expected !== void 0 && typeof request.expected !== "string") fail6(t2("commit.expectedType"));
|
|
26007
26343
|
const c = await readPreviewContext(cwd);
|
|
26008
26344
|
const { root, gitDir, indexPath, objectFormat } = await c.reader.location();
|
|
26009
26345
|
const runner = createGitRunner();
|
|
@@ -26028,11 +26364,11 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26028
26364
|
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();
|
|
26029
26365
|
const busy = join11(gitDir, "gitifact-spec-commit.lock");
|
|
26030
26366
|
await failOnLegacyLock(gitDir);
|
|
26031
|
-
if (await info2(busy)) fail6("
|
|
26032
|
-
if ((await staged()).length) fail6("
|
|
26367
|
+
if (await info2(busy)) fail6(t2("commit.busy", { path: busy }));
|
|
26368
|
+
if ((await staged()).length) fail6(t2("commit.existingStaging"));
|
|
26033
26369
|
const indexHash = hash2(await optional2(indexPath) ?? Buffer.alloc(0));
|
|
26034
26370
|
const current = c.working;
|
|
26035
|
-
if (request.expected !== void 0 && request.expected !== previewExpected(c.base, current.stamp)) fail6("
|
|
26371
|
+
if (request.expected !== void 0 && request.expected !== previewExpected(c.base, current.stamp)) fail6(t2("commit.staleInput"));
|
|
26036
26372
|
const reasons = request.reasons ?? pendingPreviewReasons(c.bundle, current.bundle).map((h) => ({ requirements: h.requirements, ...h.designs ? { designs: h.designs } : {}, ...h.documents ? { documents: h.documents } : {}, reason: h.reason }));
|
|
26037
26373
|
const prepared = prepareSpecPreview(c.bundle, current.bundle, c.files, current.files, reasons, () => generatePreviewId("H"));
|
|
26038
26374
|
const blobId = (text2) => {
|
|
@@ -26040,14 +26376,14 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26040
26376
|
return createHash7(objectFormat).update(`blob ${bytes.length}\0`).update(bytes).digest("hex");
|
|
26041
26377
|
};
|
|
26042
26378
|
const present = [...current.files.keys()];
|
|
26043
|
-
if (present.some((p) => p.includes("\n"))) fail6("
|
|
26379
|
+
if (present.some((p) => p.includes("\n"))) fail6(t2("commit.newlinePath"));
|
|
26044
26380
|
const stored = present.length ? (await git(["hash-object", "--stdin-paths"], void 0, Buffer.from(present.join("\n") + "\n"))).toString("utf8").split("\n") : [""];
|
|
26045
|
-
if (stored.length !== present.length + 1) fail6("
|
|
26381
|
+
if (stored.length !== present.length + 1) fail6(t2("commit.storedShape"));
|
|
26046
26382
|
const workingIds = new Map(present.map((p, i) => [p, stored[i]]));
|
|
26047
26383
|
const writes = new Map([...prepared.writes].filter(([p, next]) => next === null || workingIds.get(p) !== blobId(next)));
|
|
26048
26384
|
const finalId = (p) => writes.has(p) ? writes.get(p) === null ? void 0 : blobId(writes.get(p)) : workingIds.get(p);
|
|
26049
26385
|
const pending = [.../* @__PURE__ */ new Set([...c.files.keys(), ...present, ...writes.keys()])].filter((p) => (c.files.has(p) ? blobId(c.files.get(p)) : void 0) !== finalId(p));
|
|
26050
|
-
if (pending.some((p) => !selected.includes(p))) fail6("
|
|
26386
|
+
if (pending.some((p) => !selected.includes(p))) fail6(t2("commit.selectPending"));
|
|
26051
26387
|
const finalFiles = new Map(current.files);
|
|
26052
26388
|
for (const [path3, next] of writes) {
|
|
26053
26389
|
if (next === null) finalFiles.delete(path3);
|
|
@@ -26056,7 +26392,7 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26056
26392
|
await checkLegacySelection(root, selected);
|
|
26057
26393
|
const stageable = selected.filter((p) => !record2(p) || finalFiles.has(p) || c.files.has(p));
|
|
26058
26394
|
const known = /* @__PURE__ */ new Set([...current.specs.flatMap((s) => s.requirements.map((r) => r.id)), ...prepared.changes.filter((x) => x.kind === "requirement").map((x) => x.id)]);
|
|
26059
|
-
if (references.some((r) => !known.has(r))) fail6("
|
|
26395
|
+
if (references.some((r) => !known.has(r))) fail6(t2("commit.unknownRequirement"));
|
|
26060
26396
|
const requirements = [.../* @__PURE__ */ new Set([...references, ...prepared.changes.filter((x) => x.kind === "requirement").map((x) => x.id)])].sort();
|
|
26061
26397
|
const contextPaths = [.../* @__PURE__ */ new Set([...policyPaths(selected), ...extra])].sort();
|
|
26062
26398
|
const hashes = async (list) => new Map(await Promise.all(list.map(async (p) => [p, await fingerprint(root, p)])));
|
|
@@ -26090,7 +26426,7 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26090
26426
|
await mkdir5(busy);
|
|
26091
26427
|
owned = true;
|
|
26092
26428
|
} catch (e) {
|
|
26093
|
-
if (e.code === "EEXIST") fail6("
|
|
26429
|
+
if (e.code === "EEXIST") fail6(t2("commit.busy", { path: busy }));
|
|
26094
26430
|
throw e;
|
|
26095
26431
|
}
|
|
26096
26432
|
await previewTransaction(cwd, current.stamp, async () => ({ writes, data: {}, recheck: c.recheck }), rename4, async (published) => {
|
|
@@ -26098,15 +26434,15 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26098
26434
|
try {
|
|
26099
26435
|
const lock = indexLock = await open5(indexPath + ".lock", "wx", 384);
|
|
26100
26436
|
const original = await optional2(indexPath);
|
|
26101
|
-
if (hash2(original ?? Buffer.alloc(0)) !== indexHash || (await staged()).length) fail6("
|
|
26437
|
+
if (hash2(original ?? Buffer.alloc(0)) !== indexHash || (await staged()).length) fail6(t2("commit.indexChanged"));
|
|
26102
26438
|
const locked = await hashes([.../* @__PURE__ */ new Set([...selected, ...contextPaths])]);
|
|
26103
|
-
for (const [path3, value] of started) if (locked.get(path3) !== value) fail6("
|
|
26439
|
+
for (const [path3, value] of started) if (locked.get(path3) !== value) fail6(t2("commit.fileChangedRunning", { path: path3 }));
|
|
26104
26440
|
await writeFile3(join11(busy, "recovery.json"), JSON.stringify({ before: c.base, originalIndex: original?.toString("base64") ?? null, temporary, paths: selected, message, requirements }));
|
|
26105
26441
|
if (original) await writeFile3(temporary, original, { flag: "wx" });
|
|
26106
26442
|
else await git(["read-tree", "--empty"], temporary);
|
|
26107
26443
|
await git(["add", "--", ...stageable], temporary);
|
|
26108
26444
|
const actual = await staged(temporary);
|
|
26109
|
-
if (!actual.length || actual.some((p) => !selected.includes(p))) fail6("
|
|
26445
|
+
if (!actual.length || actual.some((p) => !selected.includes(p))) fail6(t2("commit.unexpectedFiles"));
|
|
26110
26446
|
const records = selected.filter((p) => record2(p) && locked.get(p) !== null);
|
|
26111
26447
|
if (records.length) {
|
|
26112
26448
|
const output2 = await git(["cat-file", "--batch"], temporary, Buffer.from(records.map((p) => ":" + p).join("\n") + "\n"));
|
|
@@ -26115,32 +26451,32 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26115
26451
|
const end = output2.indexOf(10, offset);
|
|
26116
26452
|
const header = output2.subarray(offset, end).toString("utf8").split(" ");
|
|
26117
26453
|
const size = Number(header[2]);
|
|
26118
|
-
if (end < 0 || header[1] !== "blob" || !Number.isSafeInteger(size) || output2[end + 1 + size] !== 10) fail6("
|
|
26454
|
+
if (end < 0 || header[1] !== "blob" || !Number.isSafeInteger(size) || output2[end + 1 + size] !== 10) fail6(t2("commit.stagedUnreadable", { path: path3 }));
|
|
26119
26455
|
const staged2 = output2.subarray(end + 1, end + 1 + size);
|
|
26120
|
-
const file2 = await
|
|
26121
|
-
if (!staged2.equals(file2) && !staged2.equals(Buffer.from(file2.toString("latin1").replace(/\r\n/g, "\n"), "latin1"))) fail6("
|
|
26456
|
+
const file2 = await readFile11(join11(root, path3));
|
|
26457
|
+
if (!staged2.equals(file2) && !staged2.equals(Buffer.from(file2.toString("latin1").replace(/\r\n/g, "\n"), "latin1"))) fail6(t2("commit.filterChanged"));
|
|
26122
26458
|
offset = end + size + 2;
|
|
26123
26459
|
}
|
|
26124
26460
|
}
|
|
26125
26461
|
const again = await hashes([...locked.keys()]);
|
|
26126
|
-
for (const [path3, value] of locked) if (again.get(path3) !== value) fail6("
|
|
26127
|
-
if ((await readLockedPreviewState(root)).stamp !== published.stamp) fail6("
|
|
26128
|
-
for (const name of integration) if (await info2(join11(gitDir, name))) fail6("
|
|
26129
|
-
if (!same2(c.base, await c.reader.baseline())) fail6("
|
|
26462
|
+
for (const [path3, value] of locked) if (again.get(path3) !== value) fail6(t2("commit.fileChangedPreparing", { path: path3 }));
|
|
26463
|
+
if ((await readLockedPreviewState(root)).stamp !== published.stamp) fail6(t2("commit.specsChangedPreparing"));
|
|
26464
|
+
for (const name of integration) if (await info2(join11(gitDir, name))) fail6(t2("commit.integrationStarted"));
|
|
26465
|
+
if (!same2(c.base, await c.reader.baseline())) fail6(t2("commit.headChanged"));
|
|
26130
26466
|
const tree = (await git(["write-tree"], temporary)).toString("utf8").trim();
|
|
26131
26467
|
commitStarted = true;
|
|
26132
26468
|
await git(["commit", "-m", message.trim() + (trailers.length ? "\n\n" + trailers.join("\n") : "")], temporary);
|
|
26133
26469
|
const after = await c.reader.baseline();
|
|
26134
|
-
if (!after.head) return fail6("
|
|
26470
|
+
if (!after.head) return fail6(t2("commit.resultUnknown"));
|
|
26135
26471
|
const raw = (await git(["cat-file", "commit", after.head])).toString("utf8");
|
|
26136
26472
|
const split = raw.indexOf("\n\n");
|
|
26137
26473
|
const headers = raw.slice(0, split < 0 ? raw.length : split).split("\n");
|
|
26138
26474
|
const body = split < 0 ? "" : raw.slice(split + 2);
|
|
26139
26475
|
const parents = headers.filter((h) => h.startsWith("parent ")).map((h) => h.slice(7));
|
|
26140
|
-
if (headers[0] !== "tree " + tree || after.branch !== c.base.branch || !same2(parents, c.base.head ? [c.base.head] : []) || trailers.some((
|
|
26141
|
-
if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== indexHash) fail6("
|
|
26142
|
-
if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6("
|
|
26143
|
-
await lock.writeFile(await
|
|
26476
|
+
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"));
|
|
26477
|
+
if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== indexHash) fail6(t2("commit.indexChangedAfter"));
|
|
26478
|
+
if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail6(t2("commit.hookChangedStaging"));
|
|
26479
|
+
await lock.writeFile(await readFile11(temporary));
|
|
26144
26480
|
await lock.sync();
|
|
26145
26481
|
await lock.close();
|
|
26146
26482
|
await rename4(indexPath + ".lock", indexPath);
|
|
@@ -26154,7 +26490,7 @@ async function specCommit(cwd, input2, dryRun) {
|
|
|
26154
26490
|
uncertain = true;
|
|
26155
26491
|
}
|
|
26156
26492
|
}
|
|
26157
|
-
if (uncertain) throw new PreservedPreviewError("
|
|
26493
|
+
if (uncertain) throw new PreservedPreviewError(t2("commit.uncertain", { path: busy }));
|
|
26158
26494
|
throw error62;
|
|
26159
26495
|
}
|
|
26160
26496
|
});
|
|
@@ -26184,12 +26520,12 @@ async function execute(action, options) {
|
|
|
26184
26520
|
try {
|
|
26185
26521
|
const guard = specPreviewReader(process.cwd());
|
|
26186
26522
|
const { root, gitDir, objectFormat } = await guard.location();
|
|
26187
|
-
for (const marker2 of operations) if (await fileInfo(join12(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", "
|
|
26188
|
-
if (await guard.hasUnmerged()) throw new InitError("GIT_OPERATION_IN_PROGRESS", "
|
|
26523
|
+
for (const marker2 of operations) if (await fileInfo(join12(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
|
|
26524
|
+
if (await guard.hasUnmerged()) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
|
|
26189
26525
|
const raw = await readConfigFile(root);
|
|
26190
|
-
if (raw === void 0) throw new SpecPreviewError("
|
|
26526
|
+
if (raw === void 0) throw new SpecPreviewError(t2("preview.notInitialized"));
|
|
26191
26527
|
const config2 = parseManagedConfig(raw);
|
|
26192
|
-
if (!("schemaVersion" in config2)) throw new SpecPreviewError("
|
|
26528
|
+
if (!("schemaVersion" in config2)) throw new SpecPreviewError(t2("preview.legacyProject"));
|
|
26193
26529
|
await initRepository(root).validateBaseline(config2, root, "HEAD", objectFormat);
|
|
26194
26530
|
if (["working", "save", "changes", "prepare", "verify", "commit-plan", "commit-apply", "commit"].includes(action)) {
|
|
26195
26531
|
let result;
|
|
@@ -26197,14 +26533,14 @@ async function execute(action, options) {
|
|
|
26197
26533
|
else if (action === "changes") result = await readFinalPreviewChanges(process.cwd());
|
|
26198
26534
|
else {
|
|
26199
26535
|
const source = await stat2(options.file);
|
|
26200
|
-
if (!source.isFile() || source.size > 1024 * 1024) throw new SpecPreviewError("
|
|
26201
|
-
const bytes = await
|
|
26202
|
-
if (bytes.length > 1024 * 1024) throw new SpecPreviewError("
|
|
26536
|
+
if (!source.isFile() || source.size > 1024 * 1024) throw new SpecPreviewError(t2("preview.inputFile"));
|
|
26537
|
+
const bytes = await readFile12(options.file);
|
|
26538
|
+
if (bytes.length > 1024 * 1024) throw new SpecPreviewError(t2("preview.inputSize"));
|
|
26203
26539
|
let input2;
|
|
26204
26540
|
try {
|
|
26205
26541
|
input2 = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
26206
26542
|
} catch {
|
|
26207
|
-
throw new SpecPreviewError("
|
|
26543
|
+
throw new SpecPreviewError(t2("preview.inputJson"));
|
|
26208
26544
|
}
|
|
26209
26545
|
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);
|
|
26210
26546
|
}
|
|
@@ -26223,13 +26559,13 @@ async function execute(action, options) {
|
|
|
26223
26559
|
}
|
|
26224
26560
|
} catch (error62) {
|
|
26225
26561
|
const known = error62 instanceof SpecPreviewError || error62 instanceof RepositoryReadError || error62 instanceof InitError;
|
|
26226
|
-
process.stderr.write(JSON.stringify({ ...envelope, ok: false, error: { code: known ? error62.code : "SPEC_PREVIEW_FAILED", message: known ? error62.message : "
|
|
26562
|
+
process.stderr.write(JSON.stringify({ ...envelope, ok: false, error: { code: known ? error62.code : "SPEC_PREVIEW_FAILED", message: known ? error62.message : t2("preview.failed") } }) + "\n");
|
|
26227
26563
|
process.exitCode = 1;
|
|
26228
26564
|
}
|
|
26229
26565
|
}
|
|
26230
26566
|
|
|
26231
26567
|
// src/commands/migrate.ts
|
|
26232
|
-
import { lstat as lstat7, readdir as readdir4, readFile as
|
|
26568
|
+
import { lstat as lstat7, readdir as readdir4, readFile as readFile13, rename as rename5, writeFile as writeFile4, unlink as unlink6 } from "node:fs/promises";
|
|
26233
26569
|
import { join as join13 } from "node:path";
|
|
26234
26570
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
26235
26571
|
var operations2 = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply", "sequencer", "BISECT_START", "index.lock"];
|
|
@@ -26244,21 +26580,21 @@ var fail7 = (code, message) => {
|
|
|
26244
26580
|
async function migrateStore(cwd, dryRun = false) {
|
|
26245
26581
|
const reader = specPreviewReader(cwd);
|
|
26246
26582
|
const { root, gitDir } = await reader.location();
|
|
26247
|
-
for (const marker3 of operations2) if (await info3(join13(gitDir, marker3))) fail7("GIT_OPERATION_IN_PROGRESS", "
|
|
26248
|
-
if (await reader.hasUnmerged()) fail7("GIT_OPERATION_IN_PROGRESS", "
|
|
26249
|
-
for (const name of [...LEGACY_LOCKS, "gitifact-spec-preview.lock", "gitifact-spec-commit.lock"]) if (await info3(join13(gitDir, name))) fail7("LOCKED", "
|
|
26583
|
+
for (const marker3 of operations2) if (await info3(join13(gitDir, marker3))) fail7("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker3 }));
|
|
26584
|
+
if (await reader.hasUnmerged()) fail7("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
|
|
26585
|
+
for (const name of [...LEGACY_LOCKS, "gitifact-spec-preview.lock", "gitifact-spec-commit.lock"]) if (await info3(join13(gitDir, name))) fail7("LOCKED", t2("migrate.locked", { path: join13(gitDir, name) }));
|
|
26250
26586
|
const from = join13(root, ".tryce");
|
|
26251
26587
|
const to = join13(root, ".gitifact");
|
|
26252
26588
|
const fromInfo = await info3(from);
|
|
26253
|
-
if (await info3(to)) fail7("ALREADY_MIGRATED", ".
|
|
26254
|
-
if (!fromInfo) return fail7("NOTHING_TO_MIGRATE", ".
|
|
26255
|
-
if (!fromInfo.isDirectory() || fromInfo.isSymbolicLink()) fail7("PATH_CONFLICT", ".
|
|
26589
|
+
if (await info3(to)) fail7("ALREADY_MIGRATED", t2("migrate.alreadyMigrated"));
|
|
26590
|
+
if (!fromInfo) return fail7("NOTHING_TO_MIGRATE", t2("migrate.nothingToMigrate"));
|
|
26591
|
+
if (!fromInfo.isDirectory() || fromInfo.isSymbolicLink()) fail7("PATH_CONFLICT", t2("migrate.notDirectory"));
|
|
26256
26592
|
const configInfo = await info3(join13(from, "config.json"));
|
|
26257
|
-
if (!configInfo?.isFile() || configInfo.isSymbolicLink()) fail7("NOT_INITIALIZED", ".
|
|
26258
|
-
const config2 = parseManagedConfig(decode4(await
|
|
26259
|
-
if (!("schemaVersion" in config2)) fail7("UNSUPPORTED_FORMAT", "
|
|
26593
|
+
if (!configInfo?.isFile() || configInfo.isSymbolicLink()) fail7("NOT_INITIALIZED", t2("migrate.noConfig"));
|
|
26594
|
+
const config2 = parseManagedConfig(decode4(await readFile13(join13(from, "config.json"))));
|
|
26595
|
+
if (!("schemaVersion" in config2)) fail7("UNSUPPORTED_FORMAT", t2("migrate.legacyJson"));
|
|
26260
26596
|
const top = (await readdir4(from)).sort();
|
|
26261
|
-
if (top.some((name) => name !== "config.json" && name !== "spec")) fail7("UNSUPPORTED_FORMAT", ".
|
|
26597
|
+
if (top.some((name) => name !== "config.json" && name !== "spec")) fail7("UNSUPPORTED_FORMAT", t2("migrate.extraEntries"));
|
|
26262
26598
|
const files = /* @__PURE__ */ new Map();
|
|
26263
26599
|
const rewrites = [];
|
|
26264
26600
|
const legacyRecords = [];
|
|
@@ -26267,17 +26603,17 @@ async function migrateStore(cwd, dryRun = false) {
|
|
|
26267
26603
|
for (const feature2 of (await readdir4(join13(from, "spec"))).sort()) {
|
|
26268
26604
|
const dir = join13(from, "spec", feature2);
|
|
26269
26605
|
const stat3 = await info3(dir);
|
|
26270
|
-
if (!stat3?.isDirectory() || stat3.isSymbolicLink()) fail7("UNSUPPORTED_FORMAT", "
|
|
26606
|
+
if (!stat3?.isDirectory() || stat3.isSymbolicLink()) fail7("UNSUPPORTED_FORMAT", t2("migrate.notSpecFolder", { feature: feature2 }));
|
|
26271
26607
|
for (const name of (await readdir4(dir)).sort()) {
|
|
26272
|
-
if (!["requirements.md", "design.md", "history.jsonl", "tryce.json"].includes(name)) fail7("UNSUPPORTED_FORMAT", "
|
|
26608
|
+
if (!["requirements.md", "design.md", "history.jsonl", "tryce.json"].includes(name)) fail7("UNSUPPORTED_FORMAT", t2("migrate.unsupportedFile", { feature: feature2, name }));
|
|
26273
26609
|
const fileStat = await info3(join13(dir, name));
|
|
26274
|
-
if (!fileStat?.isFile() || fileStat.isSymbolicLink() || fileStat.nlink !== 1 || fileStat.size > 1024 * 1024) fail7("UNSUPPORTED_FORMAT", "
|
|
26610
|
+
if (!fileStat?.isFile() || fileStat.isSymbolicLink() || fileStat.nlink !== 1 || fileStat.size > 1024 * 1024) fail7("UNSUPPORTED_FORMAT", t2("migrate.fileTooLarge", { name }));
|
|
26275
26611
|
const newPath = `.gitifact/spec/${feature2}/${name}`;
|
|
26276
26612
|
if (name === "tryce.json") {
|
|
26277
26613
|
legacyRecords.push(newPath);
|
|
26278
26614
|
continue;
|
|
26279
26615
|
}
|
|
26280
|
-
const text2 = decode4(await
|
|
26616
|
+
const text2 = decode4(await readFile13(join13(dir, name)));
|
|
26281
26617
|
if (name === "history.jsonl") {
|
|
26282
26618
|
files.set(newPath, text2);
|
|
26283
26619
|
continue;
|
|
@@ -26313,10 +26649,10 @@ async function migrateStore(cwd, dryRun = false) {
|
|
|
26313
26649
|
rewritten: rewrites.map((r) => r.path),
|
|
26314
26650
|
legacyRecords,
|
|
26315
26651
|
next: [
|
|
26316
|
-
"
|
|
26317
|
-
...legacyRecords.length ? ["
|
|
26318
|
-
".
|
|
26319
|
-
".
|
|
26652
|
+
t2("migrate.nextCommit"),
|
|
26653
|
+
...legacyRecords.length ? [t2("migrate.nextLegacyJson")] : [],
|
|
26654
|
+
t2("migrate.nextSkills"),
|
|
26655
|
+
t2("migrate.nextRename")
|
|
26320
26656
|
]
|
|
26321
26657
|
});
|
|
26322
26658
|
if (dryRun) return result("planned");
|
|
@@ -26340,31 +26676,31 @@ async function runMigrate(options) {
|
|
|
26340
26676
|
process.stdout.write(JSON.stringify(dto) + "\n");
|
|
26341
26677
|
} catch (error62) {
|
|
26342
26678
|
const known = error62 instanceof InitError || error62 instanceof SpecPreviewError || error62 instanceof RepositoryReadError;
|
|
26343
|
-
process.stderr.write(JSON.stringify({ contract: "migrate", version: 1, ok: false, error: { code: known ? error62.code : "MIGRATE_FAILED", message: known ? error62.message : "
|
|
26679
|
+
process.stderr.write(JSON.stringify({ contract: "migrate", version: 1, ok: false, error: { code: known ? error62.code : "MIGRATE_FAILED", message: known ? error62.message : t2("migrate.failed") } }) + "\n");
|
|
26344
26680
|
process.exitCode = 1;
|
|
26345
26681
|
}
|
|
26346
26682
|
}
|
|
26347
26683
|
|
|
26348
26684
|
// src/main.ts
|
|
26349
|
-
var program2 = new Command().name("gitifact").description("
|
|
26350
|
-
program2.command("status").description(
|
|
26685
|
+
var program2 = new Command().name("gitifact").description(t2("help.program")).version("0.3.2").allowExcessArguments(false).addHelpText("after", "\n" + t2("help.notYet")).action(() => program2.outputHelp());
|
|
26686
|
+
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) => {
|
|
26351
26687
|
await runStatus(options.format);
|
|
26352
26688
|
});
|
|
26353
|
-
program2.command("browser").description("
|
|
26354
|
-
program2.command("init").description(
|
|
26355
|
-
program2.command("docs").description(
|
|
26689
|
+
program2.command("browser").description(t2("help.browser")).allowExcessArguments(false).option("--port <port>", t2("help.browserPort"), parsePort, 0).option("--dev", t2("help.browserDev")).action(runBrowser);
|
|
26690
|
+
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.3.2"));
|
|
26691
|
+
program2.command("docs").description(t2("help.docs")).argument("[topic]", t2("help.docsTopic")).allowExcessArguments(false).action(async (topic) => {
|
|
26356
26692
|
await runDocs(topic);
|
|
26357
26693
|
});
|
|
26358
|
-
program2.command("migrate").description(".
|
|
26359
|
-
var spec = program2.command("spec").description("
|
|
26360
|
-
var replaced = "
|
|
26361
|
-
spec.command("commit").description("
|
|
26362
|
-
for (const action of ["commit-plan", "commit-apply"]) spec.command(action).description(replaced).allowExcessArguments(false).requiredOption("--file <path>", "
|
|
26363
|
-
spec.command("changes").allowExcessArguments(false).action((o) => runSpecPreview("changes", o));
|
|
26364
|
-
spec.command("prepare").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", "
|
|
26365
|
-
spec.command("verify").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", "
|
|
26366
|
-
spec.command("working").allowExcessArguments(false).action((o) => runSpecPreview("working", o));
|
|
26367
|
-
spec.command("save").allowExcessArguments(false).requiredOption("--file <path>", "
|
|
26368
|
-
spec.command("read").allowExcessArguments(false).option("--ref <commit>", "
|
|
26369
|
-
spec.command("diff").allowExcessArguments(false).requiredOption("--from <commit>", "
|
|
26694
|
+
program2.command("migrate").description(t2("help.migrate")).allowExcessArguments(false).option("--dry-run", t2("help.migrateDryRun")).action(runMigrate);
|
|
26695
|
+
var spec = program2.command("spec").description(t2("help.spec"));
|
|
26696
|
+
var replaced = t2("help.deprecated");
|
|
26697
|
+
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));
|
|
26698
|
+
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));
|
|
26699
|
+
spec.command("changes").description(t2("help.specChanges")).allowExcessArguments(false).action((o) => runSpecPreview("changes", o));
|
|
26700
|
+
spec.command("prepare").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specPrepareFile")).action((o) => runSpecPreview("prepare", o));
|
|
26701
|
+
spec.command("verify").description(replaced).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specVerifyFile")).option("--staged", t2("help.specVerifyStaged")).action((o) => runSpecPreview("verify", o));
|
|
26702
|
+
spec.command("working").description(t2("help.specWorking")).allowExcessArguments(false).action((o) => runSpecPreview("working", o));
|
|
26703
|
+
spec.command("save").description(t2("help.specSave")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.specSaveFile")).action((o) => runSpecPreview("save", o));
|
|
26704
|
+
spec.command("read").description(t2("help.specRead")).allowExcessArguments(false).option("--ref <commit>", t2("help.specReadRef"), "HEAD").action((o) => runSpecPreview("read", o));
|
|
26705
|
+
spec.command("diff").description(t2("help.specDiff")).allowExcessArguments(false).requiredOption("--from <commit>", t2("help.specDiffFrom")).requiredOption("--to <commit>", t2("help.specDiffTo")).action((o) => runSpecPreview("diff", o));
|
|
26370
26706
|
await program2.parseAsync();
|