gitifact 0.8.6 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -36
- package/dist/browser/assets/{HgiRefresh-CnBE2KZ8.js → HgiRefresh-CmdxsKUC.js} +1 -1
- package/dist/browser/assets/{Markdown-75QVB57V.js → Markdown-BpWtY88p.js} +1 -1
- package/dist/browser/assets/{Selector-E8jyEKNB.js → Selector-Dji19JSe.js} +1 -1
- package/dist/browser/assets/{Tab-C-PhLRIZ.js → Tab-BY4IuGKn.js} +1 -1
- package/dist/browser/assets/{Table-Cr2jvka_.js → Table-Dm6wz2kf.js} +2 -2
- package/dist/browser/assets/{Token-BBk7tRek.js → Token-9hr7eTF1.js} +1 -1
- package/dist/browser/assets/about-C3KamVtV.js +3 -0
- package/dist/browser/assets/activity-timeline-BdRnSGAp.js +2 -0
- package/dist/browser/assets/changelog-C8_hi0cv.js +1 -0
- package/dist/browser/assets/commit-BWyvKMHI.js +4 -0
- package/dist/browser/assets/contributors-Bk_xjPNJ.js +1 -0
- package/dist/browser/assets/{contributors._email-CEcZZfAR.js → contributors._email-C8GGV2IN.js} +1 -1
- package/dist/browser/assets/{contributors.index-DNMBFxLb.js → contributors.index-BKMSdIFJ.js} +1 -1
- package/dist/browser/assets/dashboard.index-COyVOMnD.js +1 -0
- package/dist/browser/assets/{document-odLLdugz.js → document-BbL374wf.js} +4 -4
- package/dist/browser/assets/{document-Cmx0e6kz.css → document-DXzNxu17.css} +1 -1
- package/dist/browser/assets/document-Dtyl4_It.js +2 -0
- package/dist/browser/assets/features-B1FsIXwk.js +2 -0
- package/dist/browser/assets/{features._featureId-Cmg8-2ku.js → features._featureId-DT63dqjw.js} +1 -1
- package/dist/browser/assets/{features.index-CBz7BmRW.js → features.index-BGBefKJN.js} +1 -1
- package/dist/browser/assets/getting-started-CCqN7NFk.js +1 -0
- package/dist/browser/assets/git-CzKF2N75.js +1 -0
- package/dist/browser/assets/index-DsduXf6u.js +49 -0
- package/dist/browser/assets/{load-more-BVsXjzHC.js → load-more-COb87OhG.js} +1 -1
- package/dist/browser/assets/page-header-Cs2fqdqC.js +246 -0
- package/dist/browser/assets/{records._recordId-DF-NkdBL.js → records._recordId-DP2stdvW.js} +1 -1
- package/dist/browser/assets/{records.commits._commit-BBf_rxHJ.js → records.commits._commit-DQlC8mSd.js} +1 -1
- package/dist/browser/assets/{records.docs._docId-Diev5opj.js → records.docs._docId-C7snDAo3.js} +1 -1
- package/dist/browser/assets/{records.index-DPWv9blV.js → records.index-DRPp4IAb.js} +1 -1
- package/dist/browser/assets/{records.working-D5xv-dTD.js → records.working-Qv9R2KgB.js} +1 -1
- package/dist/browser/assets/{settings-N1hE7l-i.js → settings-DDEler3s.js} +1 -1
- package/dist/browser/assets/useInfiniteQuery-IoAmrFi4.js +1 -0
- package/dist/browser/assets/{useKeyboardHint-CGJ2GVT3.js → useKeyboardHint-Wwnf-tpi.js} +1 -1
- package/dist/browser/index.html +18 -24
- package/dist/i18n/en/block.md +7 -7
- package/dist/i18n/en/changelog.md +14 -0
- package/dist/i18n/en/docs/commit.md +1 -1
- package/dist/i18n/en/docs/design.md +3 -3
- package/dist/i18n/en/docs/migrate.md +31 -34
- package/dist/i18n/en/docs/records.md +2 -2
- package/dist/i18n/en/docs/spec.md +1 -1
- package/dist/i18n/en/docs/workflow.md +12 -12
- package/dist/i18n/en/docs/writing.md +4 -4
- package/dist/i18n/ko/block.md +7 -7
- package/dist/i18n/ko/changelog.md +14 -0
- package/dist/i18n/ko/docs/commit.md +1 -1
- package/dist/i18n/ko/docs/design.md +3 -3
- package/dist/i18n/ko/docs/migrate.md +30 -33
- package/dist/i18n/ko/docs/records.md +2 -2
- package/dist/i18n/ko/docs/spec.md +1 -1
- package/dist/i18n/ko/docs/workflow.md +12 -12
- package/dist/i18n/ko/docs/writing.md +4 -4
- package/dist/launcher/cli.mjs +77 -0
- package/dist/main.js +274 -586
- package/package.json +3 -3
- package/dist/browser/assets/MetadataListItem-BEwPg27H.js +0 -1
- package/dist/browser/assets/about-C3ewDfU2.js +0 -3
- package/dist/browser/assets/activity-timeline-B3s0viEt.js +0 -2
- package/dist/browser/assets/changelog-DkRd6I8J.js +0 -1
- package/dist/browser/assets/commit-BHwKZ7hK.js +0 -4
- package/dist/browser/assets/contributor-2mkEa2Wo.css +0 -1
- package/dist/browser/assets/contributor-CqqvzxLh.js +0 -1
- package/dist/browser/assets/contributors-CuMPZx6_.js +0 -1
- package/dist/browser/assets/dashboard.index-nV7KwM5H.js +0 -1
- package/dist/browser/assets/document-BnxE7Txb.js +0 -2
- package/dist/browser/assets/features-C0YzZiS-.js +0 -2
- package/dist/browser/assets/getting-started-CaOhGSBe.js +0 -1
- package/dist/browser/assets/git-DwAnKiiN.js +0 -1
- package/dist/browser/assets/index-BljzO9go.js +0 -49
- package/dist/browser/assets/instructions-2OUMP-vh.css +0 -1
- package/dist/browser/assets/instructions-DWS_nwe0.js +0 -1
- package/dist/browser/assets/instructions._instructionId-l7aWWvfx.js +0 -1
- package/dist/browser/assets/instructions.agents-t7hMe4Pv.js +0 -1
- package/dist/browser/assets/instructions.index-CHVCQBSH.js +0 -1
- package/dist/browser/assets/lazyRouteComponent-BZI8yQj_.js +0 -1
- package/dist/browser/assets/page-header-CRcXie4p.js +0 -248
- package/dist/browser/assets/project-instructions-DsWrw-nY.jpg +0 -0
- package/dist/browser/assets/useInfiniteQuery-CrEm5UW2.js +0 -1
- package/dist/i18n/en/docs/instructions.md +0 -94
- package/dist/i18n/ko/docs/instructions.md +0 -94
package/dist/main.js
CHANGED
|
@@ -3381,7 +3381,7 @@ var program = new Command();
|
|
|
3381
3381
|
import { createServer } from "node:http";
|
|
3382
3382
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
3383
3383
|
import { fileURLToPath } from "node:url";
|
|
3384
|
-
import { readFile as
|
|
3384
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
3385
3385
|
|
|
3386
3386
|
// ../../packages/core/dist/domain/repository-status.js
|
|
3387
3387
|
function summarizeChanges(changes2) {
|
|
@@ -3510,9 +3510,8 @@ var messages_default = {
|
|
|
3510
3510
|
"doc.DESIGN_OVERVIEW_REQUIRED": "\uC124\uACC4\uAC00 \uC788\uB294 \uAE30\uB2A5\uC5D0\uB294 design/overview.md\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4: {feature}",
|
|
3511
3511
|
"doc.FILE_TOO_LARGE": "\uBB38\uC11C \uD30C\uC77C\uC774 1MB\uB97C \uB118\uC5B4 \uC77D\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: {path}",
|
|
3512
3512
|
"doc.DOC_DRAFT": "new \uBA85\uB839\uC774 \uB9CC\uB4E0 \uCD08\uC548 \uD45C\uC2DC\uAC00 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4. \uBCF8\uBB38\uC744 \uB2E4 \uC4F4 \uB4A4 draft: true \uC904\uC744 \uC9C0\uC6B0\uC138\uC694: {path}",
|
|
3513
|
-
"doc.
|
|
3514
|
-
"doc.WIKI_REMOVED": "\uC704\uD0A4\uB294 0.8.0\uC5D0\uC11C \
|
|
3515
|
-
"doc.INSTRUCTION_SPEC_LINK": "\uC9C0\uCE68\uC740 \uBA85\uC138\uB97C \uAC00\uB9AC\uD0A4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uACC4\uAC00 sources\uB85C \uC9C0\uCE68\uC744 \uAC00\uB9AC\uD0B5\uB2C8\uB2E4: {path}: {link}",
|
|
3513
|
+
"doc.INSTRUCTION_MOVED": "0.9.0\uBD80\uD130 Gitifact\uB294 \uD504\uB85C\uC81D\uD2B8 \uC9C0\uCE68\uC744 \uAD00\uB9AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC774 \uC9C0\uCE68\uC744 \uC4F0\uB294 \uC5D0\uC774\uC804\uD2B8\uC758 \uC2A4\uD0AC \uD3F4\uB354\uB85C \uC62E\uAE30\uC138\uC694(gitifact guide show migrate): {path}",
|
|
3514
|
+
"doc.WIKI_REMOVED": "\uC704\uD0A4\uB294 0.8.0\uC5D0\uC11C \uC5C6\uC5B4\uC84C\uC2B5\uB2C8\uB2E4. \uC774 \uD398\uC774\uC9C0\uB97C \uC5D0\uC774\uC804\uD2B8\uC758 \uC2A4\uD0AC \uD3F4\uB354\uB098 \uB2E4\uB978 \uBB38\uC11C\uB85C \uC62E\uAE30\uC138\uC694(gitifact guide show migrate): {path}",
|
|
3516
3515
|
"warn.MISSING_LINK_TARGET": "\uB9C1\uD06C \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: {path}: {link}",
|
|
3517
3516
|
"warn.ASSET_SIZE": "\uC5D0\uC14B\uC774 \uAD8C\uC7A5 \uD06C\uAE30(1MB)\uB97C \uB118\uC2B5\uB2C8\uB2E4: {path} ({bytes}\uBC14\uC774\uD2B8)",
|
|
3518
3517
|
"warn.ASSET_EXTENSION": "\uBE0C\uB77C\uC6B0\uC800\uAC00 \uBBF8\uB9AC \uBCF4\uC5EC \uC8FC\uC9C0 \uC54A\uB294 \uD655\uC7A5\uC790\uB77C \uB0B4\uB824\uBC1B\uAE30\uB85C\uB9CC \uC5F4\uB9BD\uB2C8\uB2E4: {path}",
|
|
@@ -3636,9 +3635,8 @@ var messages_default2 = {
|
|
|
3636
3635
|
"doc.DESIGN_OVERVIEW_REQUIRED": "A feature with a design needs design/overview.md: {feature}",
|
|
3637
3636
|
"doc.FILE_TOO_LARGE": "The document file exceeds 1 MB and was not read: {path}",
|
|
3638
3637
|
"doc.DOC_DRAFT": "The draft mark a new command added is still there. Remove the draft: true line once the body is written: {path}",
|
|
3639
|
-
"doc.
|
|
3640
|
-
"doc.WIKI_REMOVED": "The wiki
|
|
3641
|
-
"doc.INSTRUCTION_SPEC_LINK": "An instruction does not point at specs; designs name the instructions they follow in sources: {path}: {link}",
|
|
3638
|
+
"doc.INSTRUCTION_MOVED": "Gitifact no longer keeps project instructions from 0.9.0. Move this instruction to the skills folder of the agent you use (gitifact guide show migrate): {path}",
|
|
3639
|
+
"doc.WIKI_REMOVED": "The wiki went in 0.8.0. Move this page to the agent's skills folder or another document (gitifact guide show migrate): {path}",
|
|
3642
3640
|
"warn.MISSING_LINK_TARGET": "The link target does not exist: {path}: {link}",
|
|
3643
3641
|
"warn.ASSET_SIZE": "The asset is over the recommended size (1 MB): {path} ({bytes} bytes)",
|
|
3644
3642
|
"warn.ASSET_EXTENSION": "The browser does not preview this extension and offers it only as a download: {path}",
|
|
@@ -3852,9 +3850,9 @@ function extractLinks(body2) {
|
|
|
3852
3850
|
fence = void 0;
|
|
3853
3851
|
continue;
|
|
3854
3852
|
}
|
|
3855
|
-
const
|
|
3856
|
-
if (
|
|
3857
|
-
fence = { char:
|
|
3853
|
+
const open5 = /^ {0,3}(`{3,}|~{3,})/.exec(line2);
|
|
3854
|
+
if (open5) {
|
|
3855
|
+
fence = { char: open5[1][0], size: open5[1].length };
|
|
3858
3856
|
continue;
|
|
3859
3857
|
}
|
|
3860
3858
|
for (const m of line2.replace(/`[^`]*`/g, "").matchAll(/!?\[[^\]]*\]\((?:<([^>]+)>|([^)\s]+))(?:\s+"[^"]*")?\)/g))
|
|
@@ -4002,9 +4000,9 @@ function parseDesign(source2, specId) {
|
|
|
4002
4000
|
fence = void 0;
|
|
4003
4001
|
return line2;
|
|
4004
4002
|
}
|
|
4005
|
-
const
|
|
4006
|
-
if (
|
|
4007
|
-
fence = { char:
|
|
4003
|
+
const open5 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line2);
|
|
4004
|
+
if (open5) {
|
|
4005
|
+
fence = { char: open5[1][0], size: open5[1].length };
|
|
4008
4006
|
return line2;
|
|
4009
4007
|
}
|
|
4010
4008
|
if (/^#\s/.test(line2))
|
|
@@ -4047,9 +4045,9 @@ function parseDocument(path3, source2) {
|
|
|
4047
4045
|
fence = void 0;
|
|
4048
4046
|
continue;
|
|
4049
4047
|
}
|
|
4050
|
-
const
|
|
4051
|
-
if (
|
|
4052
|
-
fence = { char:
|
|
4048
|
+
const open5 = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line2);
|
|
4049
|
+
if (open5) {
|
|
4050
|
+
fence = { char: open5[1][0], size: open5[1].length };
|
|
4053
4051
|
continue;
|
|
4054
4052
|
}
|
|
4055
4053
|
if (/^#\s/.test(line2))
|
|
@@ -4459,14 +4457,14 @@ function sections(raw, path3) {
|
|
|
4459
4457
|
found.at(-1)?.lines.push(line2);
|
|
4460
4458
|
continue;
|
|
4461
4459
|
}
|
|
4462
|
-
const
|
|
4463
|
-
if (
|
|
4464
|
-
fence = { char:
|
|
4460
|
+
const open5 = /^ {0,3}(`{3,}|~{3,})/.exec(line2);
|
|
4461
|
+
if (open5)
|
|
4462
|
+
fence = { char: open5[1][0], size: open5[1].length };
|
|
4465
4463
|
else if (/^#\s/.test(line2))
|
|
4466
4464
|
throw new DocumentError("BODY_HEADING", path3, t("doc.BODY_HEADING", { path: path3 }));
|
|
4467
4465
|
else if (/<!-- gitifact-/.test(line2))
|
|
4468
4466
|
throw new DocumentError("BODY_MARKER", path3, t("doc.BODY_MARKER", { path: path3 }));
|
|
4469
|
-
const heading = !
|
|
4467
|
+
const heading = !open5 && /^##\s+(.+?)\s*#*\s*$/.exec(line2);
|
|
4470
4468
|
if (heading) {
|
|
4471
4469
|
const key = sectionKeyOf(heading[1]);
|
|
4472
4470
|
if (!key || found.some((s) => s.key === key))
|
|
@@ -4550,6 +4548,8 @@ var HISTORY_PATH = ".gitifact/history.jsonl";
|
|
|
4550
4548
|
var name = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
4551
4549
|
var rootUpperName2 = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*\.md$/;
|
|
4552
4550
|
var isWikiPage = (path3) => path3.startsWith(WIKI_ROOT + "/") && path3.endsWith(".md");
|
|
4551
|
+
var isInstructionPath = (path3) => path3.startsWith(INSTRUCTIONS_ROOT + "/");
|
|
4552
|
+
var instructionFolderOf = (path3) => /^\.gitifact\/instructions\/[^/]+/.exec(path3)?.[0];
|
|
4553
4553
|
function classifyDocPath(path3) {
|
|
4554
4554
|
const unsupported = () => new DocumentError("PATH_UNSUPPORTED", path3, t("doc.PATH_UNSUPPORTED", { path: path3 }));
|
|
4555
4555
|
if (path3 === HISTORY_PATH)
|
|
@@ -4650,9 +4650,9 @@ function body(raw, path3) {
|
|
|
4650
4650
|
fence = void 0;
|
|
4651
4651
|
continue;
|
|
4652
4652
|
}
|
|
4653
|
-
const
|
|
4654
|
-
if (
|
|
4655
|
-
fence = { char:
|
|
4653
|
+
const open5 = /^ {0,3}(`{3,}|~{3,})/.exec(line2);
|
|
4654
|
+
if (open5) {
|
|
4655
|
+
fence = { char: open5[1][0], size: open5[1].length };
|
|
4656
4656
|
continue;
|
|
4657
4657
|
}
|
|
4658
4658
|
if (/^#\s/.test(line2))
|
|
@@ -4716,19 +4716,6 @@ function parseDocumentFile(path3, source2) {
|
|
|
4716
4716
|
}
|
|
4717
4717
|
return { kind: "design", feature: where.feature, order: order(), requirements: refs?.type === "list" ? refs.items : [], sources: sources(fields2, path3), ...common };
|
|
4718
4718
|
}
|
|
4719
|
-
var isInstructionReference = (path3) => path3.endsWith(".md");
|
|
4720
|
-
function parseInstructionFile(path3, source2) {
|
|
4721
|
-
if (source2.includes("\0") || /\r(?!\n)/.test(source2) || source2.charCodeAt(0) === 65279)
|
|
4722
|
-
throw new DocumentError("INVALID_CHARACTERS", path3, t("doc.INVALID_CHARACTERS", { path: path3 }));
|
|
4723
|
-
const { fields: fields2 } = parseFrontmatterBlock(source2.replace(/\r\n/g, "\n"), path3);
|
|
4724
|
-
for (const key of fields2.keys())
|
|
4725
|
-
if (key !== "title" && key !== "description")
|
|
4726
|
-
throw new DocumentError("FRONTMATTER_UNKNOWN_KEY", path3, t("doc.FRONTMATTER_UNKNOWN_KEY", { path: path3, key }));
|
|
4727
|
-
for (const key of ["title", "description"])
|
|
4728
|
-
if (!fields2.has(key))
|
|
4729
|
-
throw new DocumentError("FRONTMATTER_MISSING_KEY", path3, t("doc.FRONTMATTER_MISSING_KEY", { path: path3, key }));
|
|
4730
|
-
return { title: text(fields2, "title", path3, 200), description: text(fields2, "description", path3, 300) };
|
|
4731
|
-
}
|
|
4732
4719
|
function renderDocumentFile(doc) {
|
|
4733
4720
|
const front = renderFrontmatterBlock([
|
|
4734
4721
|
["id", doc.id],
|
|
@@ -4773,17 +4760,18 @@ function checkDocuments(files) {
|
|
|
4773
4760
|
const report = (code, path3, values = {}) => problems.push(docProblem(code, path3, values));
|
|
4774
4761
|
const features = /* @__PURE__ */ new Set();
|
|
4775
4762
|
const designFolders = /* @__PURE__ */ new Map();
|
|
4776
|
-
const instructionFolders = /* @__PURE__ */ new
|
|
4777
|
-
const specLinks = (path3, body2) => {
|
|
4778
|
-
for (const link3 of extractLinks(body2))
|
|
4779
|
-
if (resolveLink(path3, link3)?.startsWith(SPEC_ROOT + "/"))
|
|
4780
|
-
report("INSTRUCTION_SPEC_LINK", path3, { link: link3 });
|
|
4781
|
-
};
|
|
4763
|
+
const instructionFolders = /* @__PURE__ */ new Set();
|
|
4782
4764
|
for (const [path3, source2] of [...files].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
4783
4765
|
if (isWikiPage(path3)) {
|
|
4784
4766
|
report("WIKI_REMOVED", path3);
|
|
4785
4767
|
continue;
|
|
4786
4768
|
}
|
|
4769
|
+
if (isInstructionPath(path3)) {
|
|
4770
|
+
const folder = instructionFolderOf(path3);
|
|
4771
|
+
if (folder)
|
|
4772
|
+
instructionFolders.add(folder);
|
|
4773
|
+
continue;
|
|
4774
|
+
}
|
|
4787
4775
|
try {
|
|
4788
4776
|
const where = classifyDocPath(path3);
|
|
4789
4777
|
if (where.type === "ignored")
|
|
@@ -4796,16 +4784,8 @@ function checkDocuments(files) {
|
|
|
4796
4784
|
records2.push(parseRecordFile(path3, source2));
|
|
4797
4785
|
continue;
|
|
4798
4786
|
}
|
|
4799
|
-
if (where.type
|
|
4800
|
-
instructionFolders.set(where.name, instructionFolders.get(where.name) === true);
|
|
4801
|
-
if (isInstructionReference(path3)) {
|
|
4802
|
-
specLinks(path3, source2);
|
|
4803
|
-
parseInstructionFile(path3, source2);
|
|
4804
|
-
}
|
|
4787
|
+
if (where.type !== "doc")
|
|
4805
4788
|
continue;
|
|
4806
|
-
}
|
|
4807
|
-
if (where.kind === "instruction")
|
|
4808
|
-
instructionFolders.set(where.name, true);
|
|
4809
4789
|
if (where.kind === "requirement" || where.kind === "design")
|
|
4810
4790
|
features.add(where.feature);
|
|
4811
4791
|
if (where.kind === "design")
|
|
@@ -4821,9 +4801,6 @@ function checkDocuments(files) {
|
|
|
4821
4801
|
for (const doc of documents)
|
|
4822
4802
|
if (doc.draft)
|
|
4823
4803
|
report("DOC_DRAFT", doc.path);
|
|
4824
|
-
for (const doc of documents)
|
|
4825
|
-
if (doc.kind === "instruction")
|
|
4826
|
-
specLinks(doc.path, doc.body);
|
|
4827
4804
|
for (const doc of documents) {
|
|
4828
4805
|
const seen = byId.get(doc.id);
|
|
4829
4806
|
if (seen)
|
|
@@ -4871,9 +4848,8 @@ function checkDocuments(files) {
|
|
|
4871
4848
|
for (const [feature2, overview] of designFolders)
|
|
4872
4849
|
if (!overview)
|
|
4873
4850
|
report("DESIGN_OVERVIEW_REQUIRED", `.gitifact/spec/${feature2}/design/overview.md`, { feature: feature2 });
|
|
4874
|
-
for (const
|
|
4875
|
-
|
|
4876
|
-
report("INSTRUCTION_INDEX_REQUIRED", `${INSTRUCTIONS_ROOT}/${name2}/${INSTRUCTION_FILE}`);
|
|
4851
|
+
for (const folder of [...instructionFolders].sort())
|
|
4852
|
+
report("INSTRUCTION_MOVED", folder);
|
|
4877
4853
|
return { documents, records: records2, problems };
|
|
4878
4854
|
}
|
|
4879
4855
|
|
|
@@ -4889,12 +4865,11 @@ function arrangeDocuments(documents) {
|
|
|
4889
4865
|
return f;
|
|
4890
4866
|
};
|
|
4891
4867
|
const wiki = [];
|
|
4892
|
-
const instructions2 = [];
|
|
4893
4868
|
for (const doc of documents) {
|
|
4894
4869
|
if (doc.kind === "wiki")
|
|
4895
4870
|
wiki.push(doc);
|
|
4896
4871
|
else if (doc.kind === "instruction")
|
|
4897
|
-
|
|
4872
|
+
continue;
|
|
4898
4873
|
else if (doc.kind === "feature")
|
|
4899
4874
|
folder(doc.feature).index = doc;
|
|
4900
4875
|
else if (doc.kind === "requirement")
|
|
@@ -4911,7 +4886,7 @@ function arrangeDocuments(documents) {
|
|
|
4911
4886
|
}
|
|
4912
4887
|
features.push({ index: f.index, requirements: f.requirements.sort(byOrder), designs: f.designs.sort(byOrder) });
|
|
4913
4888
|
}
|
|
4914
|
-
return { features, wiki: wiki.sort(byPath),
|
|
4889
|
+
return { features, wiki: wiki.sort(byPath), orphans };
|
|
4915
4890
|
}
|
|
4916
4891
|
|
|
4917
4892
|
// ../../packages/core/dist/use-cases/compare-documents.js
|
|
@@ -4974,7 +4949,7 @@ function documentWarnings(documents, assets, existing) {
|
|
|
4974
4949
|
referenced.add(target);
|
|
4975
4950
|
continue;
|
|
4976
4951
|
}
|
|
4977
|
-
if (
|
|
4952
|
+
if (!target.startsWith(".gitifact/") && existing.has(target))
|
|
4978
4953
|
continue;
|
|
4979
4954
|
warnings.push(docWarning("MISSING_LINK_TARGET", from, { link: link3, target }));
|
|
4980
4955
|
}
|
|
@@ -25182,21 +25157,6 @@ var feature = external_exports.strictObject({
|
|
|
25182
25157
|
contributors: external_exports.array(contributor),
|
|
25183
25158
|
updatedAt: external_exports.string().nullable()
|
|
25184
25159
|
});
|
|
25185
|
-
var instructionFile = external_exports.strictObject({ path: external_exports.string(), size: external_exports.number().int().nonnegative(), title: external_exports.string().optional(), description: external_exports.string().optional() });
|
|
25186
|
-
var instruction = external_exports.strictObject({
|
|
25187
|
-
id: external_exports.string(),
|
|
25188
|
-
name: external_exports.string(),
|
|
25189
|
-
path: external_exports.string(),
|
|
25190
|
-
title: external_exports.string(),
|
|
25191
|
-
description: external_exports.string(),
|
|
25192
|
-
body: external_exports.string(),
|
|
25193
|
-
...standing,
|
|
25194
|
-
// Paths relative to the instruction folder, index.md left out; `limited` when the folder holds more than the list carries.
|
|
25195
|
-
files: external_exports.array(instructionFile),
|
|
25196
|
-
filesLimited: external_exports.boolean(),
|
|
25197
|
-
updatedAt: external_exports.string().nullable()
|
|
25198
|
-
});
|
|
25199
|
-
var agents = external_exports.strictObject({ path: external_exports.string(), body: external_exports.string(), updatedAt: external_exports.string().nullable() });
|
|
25200
25160
|
var problem = external_exports.strictObject({ code: external_exports.string(), path: external_exports.string(), message: external_exports.string() });
|
|
25201
25161
|
var oid2 = external_exports.string().regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/);
|
|
25202
25162
|
var indexFeature = external_exports.strictObject({
|
|
@@ -25207,17 +25167,16 @@ var indexFeature = external_exports.strictObject({
|
|
|
25207
25167
|
requirements: external_exports.array(external_exports.strictObject({ id: external_exports.string(), path: external_exports.string(), title: external_exports.string(), description: external_exports.string() })),
|
|
25208
25168
|
designs: external_exports.array(external_exports.strictObject({ id: external_exports.string(), path: external_exports.string(), title: external_exports.string() }))
|
|
25209
25169
|
});
|
|
25210
|
-
var
|
|
25211
|
-
var browserCheckoutV1 = external_exports.strictObject({
|
|
25170
|
+
var browserCheckoutV2 = external_exports.strictObject({
|
|
25212
25171
|
contract: external_exports.literal("browser-checkout"),
|
|
25213
|
-
version: external_exports.literal(
|
|
25172
|
+
version: external_exports.literal(2),
|
|
25214
25173
|
sessionId: external_exports.string(),
|
|
25215
25174
|
head: oid2.nullable(),
|
|
25216
25175
|
observedAt: external_exports.string(),
|
|
25217
25176
|
working: external_exports.boolean(),
|
|
25218
25177
|
stamp: external_exports.string(),
|
|
25219
25178
|
problems: external_exports.array(problem),
|
|
25220
|
-
index: external_exports.strictObject({ features: external_exports.array(indexFeature),
|
|
25179
|
+
index: external_exports.strictObject({ features: external_exports.array(indexFeature), people: external_exports.array(external_exports.strictObject({ name: external_exports.string(), email: external_exports.string() })) })
|
|
25221
25180
|
});
|
|
25222
25181
|
var featureRow = external_exports.strictObject({
|
|
25223
25182
|
id: external_exports.string(),
|
|
@@ -25245,13 +25204,6 @@ var browserFeaturesV1 = external_exports.strictObject({
|
|
|
25245
25204
|
features: external_exports.array(featureRow)
|
|
25246
25205
|
});
|
|
25247
25206
|
var browserFeatureV2 = external_exports.strictObject({ contract: external_exports.literal("browser-feature"), version: external_exports.literal(2), sessionId: external_exports.string(), feature });
|
|
25248
|
-
var browserInstructionsV1 = external_exports.strictObject({
|
|
25249
|
-
contract: external_exports.literal("browser-instructions"),
|
|
25250
|
-
version: external_exports.literal(1),
|
|
25251
|
-
sessionId: external_exports.string(),
|
|
25252
|
-
instructions: external_exports.array(instruction),
|
|
25253
|
-
agents: agents.nullable()
|
|
25254
|
-
});
|
|
25255
25207
|
var browserContributorsV1 = external_exports.strictObject({
|
|
25256
25208
|
contract: external_exports.literal("browser-contributors"),
|
|
25257
25209
|
version: external_exports.literal(1),
|
|
@@ -25334,20 +25286,20 @@ var browserHistorySummaryV5 = external_exports.strictObject({
|
|
|
25334
25286
|
// The newest commits: a few of their changes each and how many there are in all.
|
|
25335
25287
|
recent: external_exports.array(external_exports.strictObject({ commit: oid2, count: external_exports.number().int().positive(), events: external_exports.array(event) }))
|
|
25336
25288
|
});
|
|
25337
|
-
var searchKind = external_exports.enum(["feature", "requirement", "design", "
|
|
25289
|
+
var searchKind = external_exports.enum(["feature", "requirement", "design", "record", "commit"]);
|
|
25338
25290
|
var searchHit = external_exports.strictObject({
|
|
25339
25291
|
id: external_exports.string(),
|
|
25340
25292
|
kind: searchKind,
|
|
25341
25293
|
title: external_exports.string(),
|
|
25342
25294
|
where: external_exports.string(),
|
|
25343
25295
|
line: external_exports.string(),
|
|
25344
|
-
// What the hit opens: a feature (with the requirement or design tab),
|
|
25296
|
+
// What the hit opens: a feature (with the requirement or design tab), a record, or a commit.
|
|
25345
25297
|
featureId: external_exports.string().optional(),
|
|
25346
25298
|
commit: oid2.optional()
|
|
25347
25299
|
});
|
|
25348
|
-
var
|
|
25300
|
+
var browserSearchV4 = external_exports.strictObject({
|
|
25349
25301
|
contract: external_exports.literal("browser-search"),
|
|
25350
|
-
version: external_exports.literal(
|
|
25302
|
+
version: external_exports.literal(4),
|
|
25351
25303
|
sessionId: external_exports.string(),
|
|
25352
25304
|
query: external_exports.string(),
|
|
25353
25305
|
groups: external_exports.array(external_exports.strictObject({ group: external_exports.union([searchKind, external_exports.literal("recent")]), total: external_exports.number().int().nonnegative(), next: external_exports.string().nullable(), hits: external_exports.array(searchHit) }))
|
|
@@ -25379,14 +25331,13 @@ var browserFeaturesQueryV1 = external_exports.strictObject({
|
|
|
25379
25331
|
var browserFeatureQueryV1 = external_exports.strictObject({ id: featureId });
|
|
25380
25332
|
var browserContributorsQueryV1 = external_exports.strictObject({ q: external_exports.string().max(200).optional(), after: external_exports.string().min(1).max(320).optional(), limit: count(50).pipe(external_exports.number().min(1)).optional() });
|
|
25381
25333
|
var browserContributorQueryV1 = external_exports.strictObject({ email: external_exports.string().min(1).max(320) });
|
|
25382
|
-
var
|
|
25334
|
+
var browserSearchQueryV3 = external_exports.strictObject({
|
|
25383
25335
|
q: external_exports.string().max(200),
|
|
25384
25336
|
head: headQuery.optional(),
|
|
25385
25337
|
group: searchKind.optional(),
|
|
25386
25338
|
after: external_exports.string().min(1).max(200).optional(),
|
|
25387
25339
|
limit: count(50).pipe(external_exports.number().min(1)).optional()
|
|
25388
25340
|
});
|
|
25389
|
-
var browserInstructionFileQueryV1 = external_exports.strictObject({ id: external_exports.string().regex(/^I-[a-z2-7]{10}$/), path: external_exports.string().min(1).max(1e3) });
|
|
25390
25341
|
var changelogQueryV1 = external_exports.strictObject({ lang: external_exports.string().regex(/^[a-z]{2}(?:-[A-Z]{2})?$/).optional() });
|
|
25391
25342
|
var fileStatus = external_exports.enum(["added", "modified", "deleted", "renamed"]);
|
|
25392
25343
|
var commitFile = external_exports.strictObject({
|
|
@@ -25475,17 +25426,6 @@ var browserDocumentHistoryQueryV1 = external_exports.strictObject({
|
|
|
25475
25426
|
after: oid2.optional(),
|
|
25476
25427
|
limit: count(50).pipe(external_exports.number().min(1)).optional()
|
|
25477
25428
|
});
|
|
25478
|
-
var browserInstructionFileV1 = external_exports.strictObject({
|
|
25479
|
-
contract: external_exports.literal("browser-instruction-file"),
|
|
25480
|
-
version: external_exports.literal(1),
|
|
25481
|
-
sessionId: external_exports.string(),
|
|
25482
|
-
id: external_exports.string(),
|
|
25483
|
-
path: external_exports.string(),
|
|
25484
|
-
text: external_exports.string().nullable(),
|
|
25485
|
-
size: external_exports.number().int().nonnegative(),
|
|
25486
|
-
binary: external_exports.boolean(),
|
|
25487
|
-
tooLarge: external_exports.boolean()
|
|
25488
|
-
});
|
|
25489
25429
|
var workingChange = external_exports.strictObject({ id: external_exports.string(), kind, title: external_exports.string(), path: external_exports.string(), previousPath: external_exports.string().optional(), types: external_exports.array(changeType) });
|
|
25490
25430
|
var pendingRecord = external_exports.strictObject({ id: external_exports.string(), title: external_exports.string(), docs: external_exports.array(external_exports.string()), sections: external_exports.array(recordSection), draft: external_exports.boolean() });
|
|
25491
25431
|
var browserWorkingV1 = external_exports.strictObject({
|
|
@@ -25586,7 +25526,8 @@ var updateV6 = external_exports.discriminatedUnion("ok", [
|
|
|
25586
25526
|
// refreshed: blocks whose text differed were rewritten. current: every block already matched. kept: the project is on a
|
|
25587
25527
|
// release newer than this CLI, so its blocks were left as they are.
|
|
25588
25528
|
// not-initialized: no .gitifact config here, so only the version check ran. no-block: no file carries a block.
|
|
25589
|
-
// missing: files `gitifact init` would add and update does not create
|
|
25529
|
+
// missing: files `gitifact init` would add and update does not create. Always empty since 0.9.0, when init stopped adding
|
|
25530
|
+
// a CLAUDE.md that imports AGENTS.md.
|
|
25590
25531
|
agentDocs: external_exports.strictObject({ state: external_exports.enum(["refreshed", "current", "kept", "not-initialized", "no-block"]), paths: external_exports.array(external_exports.string()), missing: external_exports.array(external_exports.string()) }),
|
|
25591
25532
|
// written: .gitifact/config.json now names this release as `cli` and the block language. current: it already did.
|
|
25592
25533
|
// cli is the project's release afterwards; one newer than cliVersion was kept, since an older CLI does not lower it.
|
|
@@ -25767,7 +25708,6 @@ var messages_default3 = {
|
|
|
25767
25708
|
"server.recordNotFound": "\uC774 \uC774\uB825\uC5D0 \uADF8 \uACB0\uC815\uAE30\uB85D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
25768
25709
|
"server.documentNotFound": "\uC774 \uC774\uB825\uACFC \uC791\uC5C5 \uD3F4\uB354\uC5D0 \uADF8 \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
25769
25710
|
"server.commitFileNotFound": "\uADF8 \uCEE4\uBC0B\uC774 \uBC14\uAFBC \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
|
|
25770
|
-
"server.instructionFileNotFound": "\uC9C0\uCE68 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
25771
25711
|
"server.specsUnreadable": "\uBA85\uC138\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
25772
25712
|
"server.refreshOrigin": "\uC0C8\uB85C\uACE0\uCE68\uC5D0\uB294 \uAC19\uC740 \uCD9C\uCC98\uC758 Origin\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
25773
25713
|
"server.fileNotFound": "\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -25809,7 +25749,7 @@ var messages_default3 = {
|
|
|
25809
25749
|
"init.text.storage": "\uC800\uC7A5 \uADDC\uC57D",
|
|
25810
25750
|
"init.text.agentDocs": "\uC5D0\uC774\uC804\uD2B8 \uC9C0\uCE68",
|
|
25811
25751
|
"init.text.lineEndings": "\uC904\uBC14\uAFC8: {path}\uB85C \uBB38\uC11C\uB97C LF\uB85C \uACE0\uC815\uD588\uC2B5\uB2C8\uB2E4. \uC774\uBBF8 \uC788\uB358 \uBB38\uC11C\uAC00 \uBCC0\uACBD\uC73C\uB85C \uBCF4\uC774\uBA74 \uC904\uBC14\uAFC8\uB9CC \uBC14\uB010 \uAC83\uC774\uB2C8 \uADF8 \uBB38\uC11C\uB4E4\uC744 \uD55C \uBC88 \uCEE4\uBC0B\uD574 \uC815\uB9AC\uD558\uC138\uC694.",
|
|
25812
|
-
"init.text.updateAvailable": "\uC0C8 \uBC84\uC804 {version}\uC774 \uC788\uC2B5\uB2C8\uB2E4. {command}\uB85C \
|
|
25752
|
+
"init.text.updateAvailable": "\uC0C8 \uBC84\uC804 {version}\uC774 \uC788\uC2B5\uB2C8\uB2E4. {command}\uB85C \uD504\uB85C\uC81D\uD2B8\uB97C \uC0C8 \uBC84\uC804\uC5D0 \uB9DE\uCD94\uC138\uC694.",
|
|
25813
25753
|
"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.",
|
|
25814
25754
|
"config.storeNotDirectory": ".gitifact\uB294 \uB9C1\uD06C\uAC00 \uC544\uB2CC \uC77C\uBC18 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
|
|
25815
25755
|
"config.fileShape": "config.json\uC740 64 KiB \uC774\uD558\uC758 \uC77C\uBC18 \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
@@ -25844,14 +25784,13 @@ var messages_default3 = {
|
|
|
25844
25784
|
"update.text.upToDate": "\uCD5C\uC2E0 \uBC84\uC804\uC744 \uC0AC\uC6A9 \uC911\uC785\uB2C8\uB2E4.",
|
|
25845
25785
|
"update.text.disabled": "\uC0C8 \uBC84\uC804 \uD655\uC778\uC774 \uAEBC\uC838 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
25846
25786
|
"update.text.unavailable": "\uC0C8 \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uC138\uC694.",
|
|
25847
|
-
"update.text.install": "\
|
|
25848
|
-
"update.text.afterInstall": "\
|
|
25787
|
+
"update.text.install": "\uC5C5\uB370\uC774\uD2B8 \uBA85\uB839: {command}",
|
|
25788
|
+
"update.text.afterInstall": "\uC774 \uBA85\uB839\uC774 \uC0C8 \uBC84\uC804\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8 \uAE30\uC900\uACFC \uC9C0\uCE68 \uBE14\uB85D, \uC2E4\uD589\uAE30(.gitifact/bin/cli.mjs)\uB97C \uBC14\uAFC9\uB2C8\uB2E4. \uBE0C\uB77C\uC6B0\uC800\uB3C4 \uC0C8 \uBC84\uC804\uC73C\uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.",
|
|
25849
25789
|
"update.text.blockRefreshed": "\uC9C0\uCE68 \uBE14\uB85D \uAC31\uC2E0: {paths}",
|
|
25850
25790
|
"update.text.blockCurrent": "\uC9C0\uCE68 \uBE14\uB85D\uC740 \uC774\uBBF8 \uD604\uC7AC \uBC84\uC804\uC785\uB2C8\uB2E4: {paths}",
|
|
25851
25791
|
"update.text.noBlock": "GITIFACT \uBE14\uB85D\uC774 \uC788\uB294 \uC9C0\uCE68 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. gitifact init\uC73C\uB85C \uC124\uCE58\uD558\uC138\uC694.",
|
|
25852
25792
|
"update.text.notInitialized": "\uCD08\uAE30\uD654\uB41C \uD504\uB85C\uC81D\uD2B8\uAC00 \uC544\uB2C8\uC5B4\uC11C \uBC84\uC804\uB9CC \uD655\uC778\uD588\uC2B5\uB2C8\uB2E4.",
|
|
25853
|
-
"update.text.
|
|
25854
|
-
"update.text.migrationRequired": "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uBB38\uC11C\uB294 \uC544\uC9C1 0.7 \uC800\uC7A5 \uADDC\uC57D(schemaVersion 2)\uC785\uB2C8\uB2E4. \uC9C0\uCE68 \uBE14\uB85D\uC740 \uC0C8 \uBA85\uB839\uC744 \uC548\uB0B4\uD558\uC9C0\uB9CC \uC804\uD658 \uC804\uC5D0\uB294 specs\xB7instructions\xB7records\xB7check\xB7changes \uBA85\uB839\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. npx --yes gitifact@{version} guide show migrate\uC758 \uC808\uCC28\uB85C \uBB38\uC11C\uB97C \uC804\uD658\uD558\uC138\uC694.",
|
|
25793
|
+
"update.text.migrationRequired": "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uBB38\uC11C\uB294 \uC544\uC9C1 0.7 \uC800\uC7A5 \uADDC\uC57D(schemaVersion 2)\uC785\uB2C8\uB2E4. \uC9C0\uCE68 \uBE14\uB85D\uC740 \uC0C8 \uBA85\uB839\uC744 \uC548\uB0B4\uD558\uC9C0\uB9CC \uC804\uD658 \uC804\uC5D0\uB294 specs\xB7records\xB7check\xB7changes \uBA85\uB839\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. npx --yes gitifact@{version} guide show migrate\uC758 \uC808\uCC28\uB85C \uBB38\uC11C\uB97C \uC804\uD658\uD558\uC138\uC694.",
|
|
25855
25794
|
"update.text.committed": "\uC9C0\uCE68 \uBE14\uB85D \uCEE4\uBC0B: {commit} ({paths})",
|
|
25856
25795
|
"update.text.commitNothing": "\uCEE4\uBC0B\uD560 \uC9C0\uCE68 \uBE14\uB85D \uBCC0\uACBD\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
25857
25796
|
"update.text.commitSkipped.untracked": "\uCEE4\uBC0B\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. Git\uC774 \uCD94\uC801\uD558\uC9C0 \uC54A\uB294 \uC9C0\uCE68 \uD30C\uC77C\uC785\uB2C8\uB2E4: {paths}",
|
|
@@ -25871,7 +25810,7 @@ var messages_default3 = {
|
|
|
25871
25810
|
"help.guide": "\uC5D0\uC774\uC804\uD2B8\uC6A9 \uC791\uC131 \uC9C0\uCE68",
|
|
25872
25811
|
"help.guideList": "\uC9C0\uCE68 \uBAA9\uB85D (\uC81C\uBAA9\uACFC \uC124\uBA85)",
|
|
25873
25812
|
"help.guideShow": "\uC9C0\uCE68 \uD558\uB098\uB97C \uCD9C\uB825",
|
|
25874
|
-
"help.guideTopic": "workflow, spec, design,
|
|
25813
|
+
"help.guideTopic": "workflow, spec, design, records, writing, commit, migrate \uC911 \uD558\uB098",
|
|
25875
25814
|
"command.failed": "\uBA85\uB839\uC744 \uC2E4\uD589\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
|
|
25876
25815
|
"project.notInitialized": "\uBA3C\uC800 gitifact init\uC73C\uB85C \uCD08\uAE30\uD654\uD558\uC138\uC694.",
|
|
25877
25816
|
"input.file": "\uC785\uB825\uC740 1 MiB \uC774\uD558\uC758 JSON \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4.",
|
|
@@ -25893,17 +25832,14 @@ var messages_default3 = {
|
|
|
25893
25832
|
"docs.unknownDocument": "\uBB38\uC11C\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: {ids}",
|
|
25894
25833
|
"docs.references": "\uCC38\uC870",
|
|
25895
25834
|
"docs.referencedBy": "\uAC00\uB9AC\uD0A4\uB294 \uBB38\uC11C",
|
|
25896
|
-
"docs.files": "\uD30C\uC77C",
|
|
25897
25835
|
"docs.invalidPath": "{kind} \uBB38\uC11C\uC758 \uACBD\uB85C\uAC00 \uC544\uB2D9\uB2C8\uB2E4: {path}. \uC608: {example}",
|
|
25898
25836
|
"docs.pathExample.feature": "payment (.gitifact/spec/payment/index.md)",
|
|
25899
25837
|
"docs.pathExample.requirement": "payment/cancel (.gitifact/spec/payment/requirements/cancel.md)",
|
|
25900
25838
|
"docs.pathExample.design": "payment/api (.gitifact/spec/payment/design/api.md)",
|
|
25901
|
-
"docs.pathExample.instruction": "cli-architecture (.gitifact/instructions/cli-architecture/index.md)",
|
|
25902
25839
|
"docs.skeleton.feature": "(\uC774 \uAE30\uB2A5\uC774 \uBB34\uC5C7\uC774\uACE0 \uC5B4\uB514\uAE4C\uC9C0\uC778\uC9C0)",
|
|
25903
25840
|
"docs.skeleton.requirement": "(\uC0AC\uC6A9\uC790)\uB85C\uC11C, (\uBAA9\uC801)\uC744 \uC704\uD574 (\uB3D9\uC791)\uC744 \uD558\uACE0 \uC2F6\uB2E4.\n\n### \uBC94\uC704\uC640 \uC81C\uC57D\n\n- (\uCC38\xB7\uAC70\uC9D3\uC744 \uAC00\uB9B4 \uC218 \uC788\uB294 \uADDC\uCE59 \uD55C \uBB38\uC7A5. \uC5C6\uC73C\uBA74 \uC774 \uC808\uC744 \uC9C0\uC6B4\uB2E4)\n\n### \uC218\uC6A9 \uC870\uAC74\n\n1. \uC870\uAC74: (\uC0C1\uD669)\n \uAE30\uB300 \uB3D9\uC791: (\uACB0\uACFC)",
|
|
25904
25841
|
"docs.skeleton.requirementUsecase": "(\uC0AC\uC6A9\uC790)\uB85C\uC11C, (\uBAA9\uC801)\uC744 \uC704\uD574 (\uB3D9\uC791)\uC744 \uD558\uACE0 \uC2F6\uB2E4.\n\n### \uBC94\uC704\uC640 \uC81C\uC57D\n\n- (\uCC38\xB7\uAC70\uC9D3\uC744 \uAC00\uB9B4 \uC218 \uC788\uB294 \uADDC\uCE59 \uD55C \uBB38\uC7A5. \uC5C6\uC73C\uBA74 \uC774 \uC808\uC744 \uC9C0\uC6B4\uB2E4)\n\n### \uC0AC\uC804 \uC870\uAC74\n\n- (\uC2DC\uC791 \uC804\uC5D0 \uCC38\uC774\uC5B4\uC57C \uD558\uB294 \uAC83. \uC5C6\uC73C\uBA74 \uC774 \uC808\uC744 \uC9C0\uC6B4\uB2E4)\n\n### \uAE30\uBCF8 \uD750\uB984\n\n1. (\uD589\uC704\uC790)\uAC00 (\uB3D9\uC791)\uD55C\uB2E4.\n2. (\uC2DC\uC2A4\uD15C)\uC774 (\uACB0\uACFC)\uB97C \uBCF4\uC778\uB2E4.\n\n### \uB300\uCCB4 \uD750\uB984\n\n- **A1. (\uAC08\uB77C\uC9C0\uB294 \uC0C1\uD669)** (1\uB2E8\uACC4\uC5D0\uC11C)\n 1. (\uADF8\uB54C\uC758 \uB3D9\uC791)\n\n### \uC0AC\uD6C4 \uC870\uAC74\n\n- (\uB05D\uB09C \uB4A4 \uCC38\uC778 \uAC83. \uC5C6\uC73C\uBA74 \uC774 \uC808\uC744 \uC9C0\uC6B4\uB2E4)\n\n### \uC218\uC6A9 \uC870\uAC74\n\n1. \uACBD\uB85C: \uAE30\uBCF8 \uD750\uB984\n \uC870\uAC74: (\uC0C1\uD669)\n \uAE30\uB300 \uB3D9\uC791: (\uACB0\uACFC)\n2. \uACBD\uB85C: \uAE30\uBCF8 \uD750\uB984, A1\n \uC870\uAC74: (\uC0C1\uD669)\n \uAE30\uB300 \uB3D9\uC791: (\uACB0\uACFC)",
|
|
25905
25842
|
"docs.skeleton.design": "(\uC774 \uC124\uACC4\uAC00 \uB2E4\uB8E8\uB294 \uAD6C\uC870\uC640 \uCC98\uB9AC \uBC29\uC2DD)",
|
|
25906
|
-
"docs.skeleton.instruction": "(\uC774 \uC791\uC5C5\uC744 \uD560 \uB54C \uC9C0\uD0AC \uADDC\uCE59\uACFC \uC808\uCC28. \uC790\uC138\uD55C \uB0B4\uC6A9\uC740 references/ \uC544\uB798 \uD30C\uC77C\uB85C \uB098\uB204\uACE0 \uC5EC\uAE30\uC11C \uB9C1\uD06C\uD55C\uB2E4)",
|
|
25907
25843
|
"docs.exists": "\uC774\uBBF8 \uC788\uB294 \uD30C\uC77C\uC785\uB2C8\uB2E4: {path}",
|
|
25908
25844
|
"docs.notFolder": "\uD3F4\uB354 \uC790\uB9AC\uC5D0 \uC77C\uBC18 \uD3F4\uB354\uAC00 \uC544\uB2CC \uAC83\uC774 \uC788\uC2B5\uB2C8\uB2E4: {path}",
|
|
25909
25845
|
"docs.created": "\uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4: {path} ({id})",
|
|
@@ -25935,7 +25871,8 @@ var messages_default3 = {
|
|
|
25935
25871
|
"changes.recordAltered": "\uCEE4\uBC0B\uB41C \uACB0\uC815\uAE30\uB85D\uC774 \uBC14\uB00C\uAC70\uB098 \uC9C0\uC6CC\uC9D0(\uCEE4\uBC0B\uC774 \uAC70\uBD80\uB428): {paths}",
|
|
25936
25872
|
"commit.recordAltered": "\uC774\uBBF8 \uCEE4\uBC0B\uB41C \uACB0\uC815\uAE30\uB85D\uC740 \uACE0\uCE58\uAC70\uB098 \uC9C0\uC6B8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: {paths}. HEAD\uB300\uB85C \uB418\uB3CC\uB9AC\uACE0, \uBC14\uB010 \uACB0\uC815\uC740 \uC0C8 \uAE30\uB85D(records new)\uC73C\uB85C \uC4F0\uC138\uC694.",
|
|
25937
25873
|
"commit.selectMove": "\uC62E\uAE34 \uBB38\uC11C\uB294 \uC61B \uACBD\uB85C\uC640 \uC0C8 \uACBD\uB85C\uB97C \uD568\uAED8 \uC120\uD0DD\uD558\uC138\uC694: {ids}",
|
|
25938
|
-
"records.invalidDocs": "--docs\uC5D0 \uB300\uC0C1 \uBB38\uC11C ID(S-\xB7R-\xB7D
|
|
25874
|
+
"records.invalidDocs": "--docs\uC5D0 \uB300\uC0C1 \uBB38\uC11C ID(S-\xB7R-\xB7D-)\uB97C \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694.",
|
|
25875
|
+
"records.notDocIds": "--docs\uC5D0 \uBB38\uC11C ID(S-\xB7R-\xB7D-)\uAC00 \uC544\uB2CC \uAC12\uC774 \uC788\uC2B5\uB2C8\uB2E4: {ids}",
|
|
25939
25876
|
"records.skeleton": "(\uB0B4\uC6A9)",
|
|
25940
25877
|
"records.createdNext": "\uC139\uC158\uC744 \uCC44\uC6B0\uACE0 draft: true \uC904\uC744 \uC9C0\uC6B4 \uB4A4, \uCEE4\uBC0B\uD560 \uB54C \uC774 \uD30C\uC77C\uC744 paths\uC5D0 \uB123\uC73C\uC138\uC694.",
|
|
25941
25878
|
"records.unknown": "\uACB0\uC815\uAE30\uB85D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: {ids}",
|
|
@@ -25967,17 +25904,10 @@ var messages_default3 = {
|
|
|
25967
25904
|
"help.specsNewStyle": "\uC694\uAD6C\uC0AC\uD56D \uD615\uC2DD(usecase, default). \uC5C6\uC73C\uBA74 \uC124\uC815\uC758 requirementStyle\uC744 \uB530\uB978\uB2E4",
|
|
25968
25905
|
"help.newTitle": "\uBB38\uC11C \uC81C\uBAA9",
|
|
25969
25906
|
"help.newDescription": "\uD55C \uC904 \uC124\uBA85",
|
|
25970
|
-
"help.instructions": "\uD504\uB85C\uC81D\uD2B8 \uC9C0\uCE68\uC758 \uBAA9\uB85D\xB7\uC6D0\uBB38\xB7\uC0DD\uC131",
|
|
25971
|
-
"help.instructionsList": "AGENTS.md\uC640 \uC9C0\uCE68 \uBAA9\uB85D (\uC9C0\uCE68\uB9C8\uB2E4 \uB538\uB9B0 \uD30C\uC77C\uC758 \uC81C\uBAA9\uACFC \uC124\uBA85)",
|
|
25972
|
-
"help.instructionsShow": "\uC9C0\uCE68 index.md \uC6D0\uBB38, \uB530\uB974\uB294 \uC124\uACC4, \uD3F4\uB354 \uD30C\uC77C \uBAA9\uB85D",
|
|
25973
|
-
"help.instructionsShowTargets": "\uC9C0\uCE68 \uD3F4\uB354 \uC774\uB984\uC774\uB098 I- ID (\uC5EC\uB7EC \uAC1C \uAC00\uB2A5)",
|
|
25974
|
-
"help.instructionsShowFile": "\uC9C0\uCE68 \uD3F4\uB354 \uC548\uC758 \uD30C\uC77C \uD558\uB098\uB97C \uC77D\uC74C (\uC608: references/code-style.md)",
|
|
25975
|
-
"help.instructionsNew": "ID\uB97C \uBC1C\uAE09\uD558\uACE0 \uC9C0\uCE68 \uD3F4\uB354\uC640 index.md \uBF08\uB300 \uC0DD\uC131 (draft: true \uD45C\uC2DC)",
|
|
25976
|
-
"help.instructionsNewName": "\uC9C0\uCE68 \uD3F4\uB354 \uC774\uB984 (\uC608: code-review)",
|
|
25977
25907
|
"help.recordsList": "HEAD \uC774\uB825\uC758 \uACB0\uC815\uAE30\uB85D (\uCD5C\uC2E0\uC21C, \uCEE4\uBC0B \uC804 \uAE30\uB85D\uC774 \uBA3C\uC800)",
|
|
25978
25908
|
"help.recordsListDoc": "\uD55C \uBB38\uC11C\uC758 \uACB0\uC815 \uD750\uB984: \uADF8 \uBB38\uC11C\uAC00 \uBC14\uB010 \uCEE4\uBC0B\uB9C8\uB2E4 \uACB0\uC815\uAE30\uB85D",
|
|
25979
25909
|
"help.recordsListSince": "\uADF8 \uB0A0\uC9DC(YYYY-MM-DD)\uB098 \uCEE4\uBC0B \uB4A4\uC758 \uAC83\uB9CC",
|
|
25980
|
-
"help.check": "\uBA85\uC138\xB7\
|
|
25910
|
+
"help.check": "\uBA85\uC138\xB7\uCEE4\uBC0B \uC804 \uACB0\uC815\uAE30\uB85D \uC804\uCCB4\uC758 \uD615\uC2DD\xB7ID\xB7\uCC38\uC870\xB7\uCD08\uC548 \uD45C\uC2DC \uAC80\uC0AC (\uBB38\uC81C\uAC00 \uC788\uC73C\uBA74 \uC885\uB8CC \uCF54\uB4DC 1)",
|
|
25981
25911
|
"help.listQ": "\uC81C\uBAA9\xB7\uC124\uBA85\xB7\uBCF8\uBB38\uC5D0 \uC774 \uB9D0\uC774 \uC788\uB294 \uAC83\uB9CC",
|
|
25982
25912
|
"help.listAuthor": "\uC774 Git \uC791\uC131\uC790(\uC774\uB984\uC774\uB098 \uC774\uBA54\uC77C)\uAC00 \uBC14\uAFBC \uAC83\uB9CC",
|
|
25983
25913
|
"help.listSort": "\uC815\uB82C \uAE30\uC900",
|
|
@@ -25994,18 +25924,9 @@ var messages_default3 = {
|
|
|
25994
25924
|
"list.features": "\uAE30\uB2A5",
|
|
25995
25925
|
"list.commits": "\uCEE4\uBC0B",
|
|
25996
25926
|
"list.records": "\uACB0\uC815\uAE30\uB85D",
|
|
25997
|
-
"docs.otherResource": "\uC774 \uBA85\uB839\uC774 \uB2E4\uB8E8\uB294 \uBB38\uC11C\uAC00 \uC544\uB2D9\uB2C8\uB2E4: {ids}. {command}\uB85C \uC77D\uC73C\uC138\uC694.",
|
|
25998
25927
|
"docs.noMatch": "\uC870\uAC74\uC5D0 \uB9DE\uB294 \uAC83\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
25999
25928
|
"docs.requirement": "\uC694\uAD6C\uC0AC\uD56D",
|
|
26000
25929
|
"docs.design": "\uC124\uACC4",
|
|
26001
|
-
"instructions.agents": "AGENTS.md \u2014 \uBE14\uB85D \uBC16 \uC0C9\uC778\uC774 \uC5B4\uB5A4 \uC791\uC5C5\uC5D0 \uC5B4\uB290 \uC9C0\uCE68\uC744 \uC77D\uC744\uC9C0 \uC54C\uB9B0\uB2E4",
|
|
26002
|
-
"instructions.noAgents": "AGENTS.md \uC5C6\uC74C \u2014 \uC9C0\uCE68\uC744 \uC5B8\uC81C \uC77D\uC744\uC9C0 \uC54C\uB9AC\uB294 \uC0C9\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
26003
|
-
"instructions.filesLimited": "(\uD30C\uC77C\uC774 \uB354 \uC788\uC5B4 \uC55E {count}\uAC1C\uB9CC \uBCF4\uC785\uB2C8\uB2E4)",
|
|
26004
|
-
"instructions.empty": "\uC9C0\uCE68\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. instructions new\uB85C \uB9CC\uB4DC\uC138\uC694.",
|
|
26005
|
-
"instructions.fileWithOne": "--file\uC740 \uC9C0\uCE68 \uD558\uB098\uC640 \uD568\uAED8 \uC4F0\uBA70 --ref\uC640 \uD568\uAED8 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
26006
|
-
"instructions.unknownFile": "\uC9C0\uCE68 {name} \uD3F4\uB354\uC5D0 \uADF8 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: {path}",
|
|
26007
|
-
"instructions.fileTooLarge": "(\uD30C\uC77C\uC774 \uCEE4\uC11C \uC6D0\uBB38\uC744 \uBCF4\uC774\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {size}\uBC14\uC774\uD2B8)",
|
|
26008
|
-
"instructions.fileBinary": "(\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: {size}\uBC14\uC774\uD2B8)",
|
|
26009
25930
|
"records.empty": "\uACB0\uC815\uAE30\uB85D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
26010
25931
|
"records.moreDocs": "\uC678 {count}\uAC1C",
|
|
26011
25932
|
"help.feedback": "Gitifact \uC790\uCCB4\uC758 \uBC84\uADF8\xB7\uAC1C\uC120\uC744 Gitifact \uC800\uC7A5\uC18C \uC774\uC288\uB85C \uBCF4\uB0C4 (gh\uAC00 \uC5C6\uC73C\uBA74 \uC774\uC288 \uC791\uC131 \uC8FC\uC18C \uCD9C\uB825)",
|
|
@@ -26021,11 +25942,11 @@ var messages_default3 = {
|
|
|
26021
25942
|
"feedback.truncated": "\uBCF8\uBB38\uC774 \uAE38\uC5B4 \uC8FC\uC18C\uC5D0\uB294 \uC55E\uBD80\uBD84\uB9CC \uB2F4\uACBC\uC2B5\uB2C8\uB2E4. \uC544\uB798 \uC804\uCCB4 \uBCF8\uBB38\uC744 \uC791\uC131 \uD398\uC774\uC9C0\uC5D0 \uBD99\uC5EC \uB123\uC73C\uC138\uC694.",
|
|
26022
25943
|
"feedback.title": "\uC81C\uBAA9: {title}",
|
|
26023
25944
|
"update.text.projectWritten": "{path}\uC758 \uD504\uB85C\uC81D\uD2B8 \uAE30\uC900\uC744 gitifact {version}\uC73C\uB85C \uC801\uC5C8\uC2B5\uB2C8\uB2E4.",
|
|
26024
|
-
"update.text.projectAhead": "\uD504\uB85C\uC81D\uD2B8 \uAE30\uC900\uC740 gitifact {project}\uC785\uB2C8\uB2E4. \uC774 CLI({version})\uAC00 \uB354 \uC624\uB798\uB418\uC5B4 \uB0AE\uCD94\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
|
|
25945
|
+
"update.text.projectAhead": "\uD504\uB85C\uC81D\uD2B8 \uAE30\uC900\uC740 gitifact {project}\uC785\uB2C8\uB2E4. \uC774 CLI({version})\uAC00 \uB354 \uC624\uB798\uB418\uC5B4 \uB0AE\uCD94\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uD504\uB85C\uC81D\uD2B8\uC758 \uC2E4\uD589\uAE30 node .gitifact/bin/cli.mjs\uB85C \uC2E4\uD589\uD558\uC138\uC694.",
|
|
26025
25946
|
"update.later.postponed": "{latest} \uC548\uB0B4\uB97C {until}\uAE4C\uC9C0 \uC27D\uB2C8\uB2E4. \uB354 \uC0C8 \uBC84\uC804\uC774 \uB098\uC624\uBA74 \uBC14\uB85C \uB2E4\uC2DC \uC548\uB0B4\uD569\uB2C8\uB2E4.",
|
|
26026
25947
|
"update.later.nothing": "\uBBF8\uB8F0 \uC0C8 \uBC84\uC804 \uC548\uB0B4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(\uC9C0\uAE08 {version}).",
|
|
26027
|
-
"notice.release": "\uC0C8 \uBC84\uC804 {latest}\uAC00 \uC788\uC2B5\uB2C8\uB2E4(\uC9C0\uAE08 {version}). \uC5C5\uB370\uC774\uD2B8: {command} \
|
|
26028
|
-
"notice.projectNewer": "\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 gitifact {project} \uAE30\uC900\uC785\uB2C8\uB2E4(\uC2E4\uD589 \uC911 {version}).
|
|
25948
|
+
"notice.release": "\uC0C8 \uBC84\uC804 {latest}\uAC00 \uC788\uC2B5\uB2C8\uB2E4(\uC9C0\uAE08 {version}). \uC5C5\uB370\uC774\uD2B8: {command} \xB7 \uB098\uC911\uC5D0: gitifact update --later",
|
|
25949
|
+
"notice.projectNewer": "\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 gitifact {project} \uAE30\uC900\uC785\uB2C8\uB2E4(\uC2E4\uD589 \uC911 {version}). \uD504\uB85C\uC81D\uD2B8\uC758 \uC2E4\uD589\uAE30 node .gitifact/bin/cli.mjs\uB85C \uC2E4\uD589\uD558\uC138\uC694.",
|
|
26029
25950
|
"notice.projectOlder": "\uC774 CLI({version})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uAE30\uC900({project})\uBCF4\uB2E4 \uC0C8 \uBC84\uC804\uC785\uB2C8\uB2E4. gitifact update\uB85C \uD504\uB85C\uC81D\uD2B8 \uAE30\uC900\uC744 \uC62C\uB9B4 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
26030
25951
|
"help.updateLater": "\uC9C0\uAE08 \uC548\uB0B4\uB41C \uC0C8 \uBC84\uC804\uC744 24\uC2DC\uAC04 \uB3D9\uC548 \uC548\uB0B4\uD558\uC9C0 \uC54A\uC74C. \uB354 \uC0C8 \uBC84\uC804\uC740 \uBC14\uB85C \uC548\uB0B4",
|
|
26031
25952
|
"update.text.blockKept": "\uD504\uB85C\uC81D\uD2B8\uAC00 \uC774 CLI\uBCF4\uB2E4 \uC0C8 \uBC84\uC804 \uAE30\uC900\uC774\uB77C \uC9C0\uCE68 \uBE14\uB85D\uC744 \uADF8\uB300\uB85C \uB450\uC5C8\uC2B5\uB2C8\uB2E4: {paths}"
|
|
@@ -26086,7 +26007,6 @@ var messages_default4 = {
|
|
|
26086
26007
|
"server.recordNotFound": "This history has no such decision record.",
|
|
26087
26008
|
"server.documentNotFound": "Neither this history nor the working tree has that document.",
|
|
26088
26009
|
"server.commitFileNotFound": "That commit did not change this file.",
|
|
26089
|
-
"server.instructionFileNotFound": "The instruction file was not found.",
|
|
26090
26010
|
"server.specsUnreadable": "Could not read specifications.",
|
|
26091
26011
|
"server.refreshOrigin": "Refresh requires a same-origin Origin header.",
|
|
26092
26012
|
"server.fileNotFound": "File not found.",
|
|
@@ -26128,7 +26048,7 @@ var messages_default4 = {
|
|
|
26128
26048
|
"init.text.storage": "Storage convention",
|
|
26129
26049
|
"init.text.agentDocs": "Agent instructions",
|
|
26130
26050
|
"init.text.lineEndings": "Line endings: {path} keeps documents in LF. Documents that now show as changed differ only in line endings; commit them once to settle it.",
|
|
26131
|
-
"init.text.updateAvailable": "Version {version} is available.
|
|
26051
|
+
"init.text.updateAvailable": "Version {version} is available. Move the project to it with {command}.",
|
|
26132
26052
|
"init.failed": "Initialization failed. Check file permissions and the generated configuration and temporary files.",
|
|
26133
26053
|
"config.storeNotDirectory": ".gitifact must be a regular directory, not a link.",
|
|
26134
26054
|
"config.fileShape": "config.json must be a regular file no larger than 64 KiB.",
|
|
@@ -26163,14 +26083,13 @@ var messages_default4 = {
|
|
|
26163
26083
|
"update.text.upToDate": "You are using the latest version.",
|
|
26164
26084
|
"update.text.disabled": "Update checks are disabled.",
|
|
26165
26085
|
"update.text.unavailable": "Could not check for updates. Check your network connection.",
|
|
26166
|
-
"update.text.install": "
|
|
26167
|
-
"update.text.afterInstall": "
|
|
26086
|
+
"update.text.install": "Update command: {command}",
|
|
26087
|
+
"update.text.afterInstall": "It moves the project, its instruction blocks and the launcher (.gitifact/bin/cli.mjs) to the new version. Restart the browser with the new version too.",
|
|
26168
26088
|
"update.text.blockRefreshed": "Instruction blocks refreshed: {paths}",
|
|
26169
26089
|
"update.text.blockCurrent": "Instruction blocks are already current: {paths}",
|
|
26170
26090
|
"update.text.noBlock": "No instruction files contain a GITIFACT block. Run gitifact init to install one.",
|
|
26171
26091
|
"update.text.notInitialized": "Only the version was checked because this project is not initialized.",
|
|
26172
|
-
"update.text.
|
|
26173
|
-
"update.text.migrationRequired": "This project's documents still use the 0.7 storage convention (schemaVersion 2). The blocks describe the new commands, but the specs, instructions, records, check and changes commands refuse to run until the documents are moved. Follow npx --yes gitifact@{version} guide show migrate to move them.",
|
|
26092
|
+
"update.text.migrationRequired": "This project's documents still use the 0.7 storage convention (schemaVersion 2). The blocks describe the new commands, but the specs, records, check and changes commands refuse to run until the documents are moved. Follow npx --yes gitifact@{version} guide show migrate to move them.",
|
|
26174
26093
|
"update.text.committed": "Instruction blocks committed: {commit} ({paths})",
|
|
26175
26094
|
"update.text.commitNothing": "No instruction block changes to commit.",
|
|
26176
26095
|
"update.text.commitSkipped.untracked": "Not committed. Instruction files are untracked: {paths}",
|
|
@@ -26190,7 +26109,7 @@ var messages_default4 = {
|
|
|
26190
26109
|
"help.guide": "Writing guides for agents",
|
|
26191
26110
|
"help.guideList": "List guides (title and description)",
|
|
26192
26111
|
"help.guideShow": "Print one guide",
|
|
26193
|
-
"help.guideTopic": "One of workflow, spec, design,
|
|
26112
|
+
"help.guideTopic": "One of workflow, spec, design, records, writing, commit, migrate",
|
|
26194
26113
|
"command.failed": "The command failed.",
|
|
26195
26114
|
"project.notInitialized": "Initialize the project with gitifact init first.",
|
|
26196
26115
|
"input.file": "The input must be a JSON file of 1 MiB or less.",
|
|
@@ -26212,17 +26131,14 @@ var messages_default4 = {
|
|
|
26212
26131
|
"docs.unknownDocument": "Documents not found: {ids}",
|
|
26213
26132
|
"docs.references": "References",
|
|
26214
26133
|
"docs.referencedBy": "Referenced by",
|
|
26215
|
-
"docs.files": "Files",
|
|
26216
26134
|
"docs.invalidPath": "Not a path for a {kind} document: {path}. Example: {example}",
|
|
26217
26135
|
"docs.pathExample.feature": "payment (.gitifact/spec/payment/index.md)",
|
|
26218
26136
|
"docs.pathExample.requirement": "payment/cancel (.gitifact/spec/payment/requirements/cancel.md)",
|
|
26219
26137
|
"docs.pathExample.design": "payment/api (.gitifact/spec/payment/design/api.md)",
|
|
26220
|
-
"docs.pathExample.instruction": "cli-architecture (.gitifact/instructions/cli-architecture/index.md)",
|
|
26221
26138
|
"docs.skeleton.feature": "(What this feature is and where it ends)",
|
|
26222
26139
|
"docs.skeleton.requirement": "As (a user), I want to (act) so that (purpose).\n\n### Scope and constraints\n\n- (One rule that is either true or false. Remove this section if there is none)\n\n### Acceptance criteria\n\n1. Condition: (situation)\n Expected: (result)",
|
|
26223
26140
|
"docs.skeleton.requirementUsecase": "As (a user), I want to (act) so that (purpose).\n\n### Scope and constraints\n\n- (One rule that is either true or false. Remove this section if there is none)\n\n### Preconditions\n\n- (What holds before it starts. Remove this section if there is none)\n\n### Basic flow\n\n1. (The actor) (acts).\n2. (The system) shows (the result).\n\n### Alternative flows\n\n- **A1. (Where it branches)** (at step 1)\n 1. (What happens then)\n\n### Postconditions\n\n- (What holds when it ends. Remove this section if there is none)\n\n### Acceptance criteria\n\n1. Path: Basic flow\n Condition: (situation)\n Expected: (result)\n2. Path: Basic flow, A1\n Condition: (situation)\n Expected: (result)",
|
|
26224
26141
|
"docs.skeleton.design": "(The structure and processing this design covers)",
|
|
26225
|
-
"docs.skeleton.instruction": "(Rules and steps to follow for this kind of work. Put details in files under references/ and link them from here)",
|
|
26226
26142
|
"docs.exists": "The file already exists: {path}",
|
|
26227
26143
|
"docs.notFolder": "Something other than a plain folder stands where a folder is needed: {path}",
|
|
26228
26144
|
"docs.created": "Created {path} ({id})",
|
|
@@ -26254,7 +26170,8 @@ var messages_default4 = {
|
|
|
26254
26170
|
"changes.recordAltered": "Committed records edited or deleted (the commit is refused): {paths}",
|
|
26255
26171
|
"commit.recordAltered": "Committed records cannot be edited or deleted: {paths}. Restore them from HEAD and write a changed decision as a new record (records new).",
|
|
26256
26172
|
"commit.selectMove": "Select both the old and the new path of a moved document: {ids}",
|
|
26257
|
-
"records.invalidDocs": "Give at least one target document ID (S-, R-, D
|
|
26173
|
+
"records.invalidDocs": "Give at least one target document ID (S-, R-, D-) with --docs.",
|
|
26174
|
+
"records.notDocIds": "--docs has values that are not document IDs (S-, R-, D-): {ids}",
|
|
26258
26175
|
"records.skeleton": "(Content)",
|
|
26259
26176
|
"records.createdNext": "Fill in the sections, remove the draft: true line, and list this file in paths when you commit.",
|
|
26260
26177
|
"records.unknown": "No such record: {ids}",
|
|
@@ -26286,17 +26203,10 @@ var messages_default4 = {
|
|
|
26286
26203
|
"help.specsNewStyle": "Requirement shape (usecase, default). Defaults to the config requirementStyle",
|
|
26287
26204
|
"help.newTitle": "Document title",
|
|
26288
26205
|
"help.newDescription": "One-line description",
|
|
26289
|
-
"help.instructions": "List, read and create project instructions",
|
|
26290
|
-
"help.instructionsList": "AGENTS.md and the instructions (with the title and description of each file in their folders)",
|
|
26291
|
-
"help.instructionsShow": "An instruction's index.md as written, the designs that follow it and its folder's files",
|
|
26292
|
-
"help.instructionsShowTargets": "Instruction folder names or I- IDs (one or more)",
|
|
26293
|
-
"help.instructionsShowFile": "Read one file of the instruction folder (e.g. references/code-style.md)",
|
|
26294
|
-
"help.instructionsNew": "Create an instruction folder and index.md skeleton with an issued ID (marked draft: true)",
|
|
26295
|
-
"help.instructionsNewName": "Instruction folder name (e.g. code-review)",
|
|
26296
26206
|
"help.recordsList": "Decision records of HEAD's history (newest first, uncommitted ones first)",
|
|
26297
26207
|
"help.recordsListDoc": "One document's decision flow: the records of each commit that changed it",
|
|
26298
26208
|
"help.recordsListSince": "Only those after that date (YYYY-MM-DD) or commit",
|
|
26299
|
-
"help.check": "Check the format, IDs, references and draft marks of all specs
|
|
26209
|
+
"help.check": "Check the format, IDs, references and draft marks of all specs and uncommitted records (exit code 1 on problems)",
|
|
26300
26210
|
"help.listQ": "Only those whose title, description or text holds these words",
|
|
26301
26211
|
"help.listAuthor": "Only those this Git author (name or email) changed",
|
|
26302
26212
|
"help.listSort": "Sort key",
|
|
@@ -26313,18 +26223,9 @@ var messages_default4 = {
|
|
|
26313
26223
|
"list.features": "Features",
|
|
26314
26224
|
"list.commits": "Commits",
|
|
26315
26225
|
"list.records": "Records",
|
|
26316
|
-
"docs.otherResource": "Not a document this command reads: {ids}. Use {command}.",
|
|
26317
26226
|
"docs.noMatch": "Nothing matches.",
|
|
26318
26227
|
"docs.requirement": "requirement",
|
|
26319
26228
|
"docs.design": "design",
|
|
26320
|
-
"instructions.agents": "AGENTS.md \u2014 the index outside the block says which instruction to read for which work",
|
|
26321
|
-
"instructions.noAgents": "No AGENTS.md \u2014 nothing tells when to read which instruction",
|
|
26322
|
-
"instructions.filesLimited": "(the folder holds more; only the first {count} are shown)",
|
|
26323
|
-
"instructions.empty": "No instructions yet. Create one with instructions new.",
|
|
26324
|
-
"instructions.fileWithOne": "--file takes one instruction and does not go with --ref.",
|
|
26325
|
-
"instructions.unknownFile": "The folder of instruction {name} has no such file: {path}",
|
|
26326
|
-
"instructions.fileTooLarge": "(Too large to show: {size} bytes)",
|
|
26327
|
-
"instructions.fileBinary": "(Not a text file: {size} bytes)",
|
|
26328
26229
|
"records.empty": "No decision records yet.",
|
|
26329
26230
|
"records.moreDocs": "and {count} more",
|
|
26330
26231
|
"help.feedback": "Send a Gitifact bug or idea as an issue to Gitifact's repository (prints a new-issue address without gh)",
|
|
@@ -26340,11 +26241,11 @@ var messages_default4 = {
|
|
|
26340
26241
|
"feedback.truncated": "The body is long, so the address holds only its beginning. Paste the full body below into the page.",
|
|
26341
26242
|
"feedback.title": "Title: {title}",
|
|
26342
26243
|
"update.text.projectWritten": "Set the project to gitifact {version} in {path}.",
|
|
26343
|
-
"update.text.projectAhead": "The project is set to gitifact {project}. This CLI ({version}) is older, so it was not lowered.
|
|
26244
|
+
"update.text.projectAhead": "The project is set to gitifact {project}. This CLI ({version}) is older, so it was not lowered. Run it through the project's launcher, node .gitifact/bin/cli.mjs.",
|
|
26344
26245
|
"update.later.postponed": "The notice for {latest} is quiet until {until}. A newer release is announced right away.",
|
|
26345
26246
|
"update.later.nothing": "No newer release to postpone (running {version}).",
|
|
26346
|
-
"notice.release": "Version {latest} is available (running {version}). Update: {command}
|
|
26347
|
-
"notice.projectNewer": "This project is set to gitifact {project} (running {version}).
|
|
26247
|
+
"notice.release": "Version {latest} is available (running {version}). Update: {command} \xB7 Later: gitifact update --later",
|
|
26248
|
+
"notice.projectNewer": "This project is set to gitifact {project} (running {version}). Run it through the project's launcher, node .gitifact/bin/cli.mjs.",
|
|
26348
26249
|
"notice.projectOlder": "This CLI ({version}) is newer than the project ({project}). Run gitifact update to move the project to it.",
|
|
26349
26250
|
"help.updateLater": "Quiet the announced newer release for 24 hours; a release newer than it is announced right away",
|
|
26350
26251
|
"update.text.blockKept": "The project is set to a newer release than this CLI, so the instruction blocks were left as they are: {paths}"
|
|
@@ -26699,7 +26600,7 @@ function storeReader(cwd) {
|
|
|
26699
26600
|
import { DatabaseSync } from "node:sqlite";
|
|
26700
26601
|
import { lstat, mkdir, rm, writeFile } from "node:fs/promises";
|
|
26701
26602
|
import { join as join2 } from "node:path";
|
|
26702
|
-
var CACHE_FORMAT =
|
|
26603
|
+
var CACHE_FORMAT = 13;
|
|
26703
26604
|
var CACHE_DIR = ".gitifact/cache";
|
|
26704
26605
|
var SCHEMA = `
|
|
26705
26606
|
-- Working-tree files already read: the modification time and size decide whether a file is read again.
|
|
@@ -26885,6 +26786,7 @@ function createDocumentCache(root, database) {
|
|
|
26885
26786
|
async function read(path3, seen) {
|
|
26886
26787
|
try {
|
|
26887
26788
|
if (isWikiPage(path3)) return { problem: docProblem("WIKI_REMOVED", path3) };
|
|
26789
|
+
if (isInstructionPath(path3)) return path3.endsWith("/index.md") && classifyDocPath(path3).type === "doc" ? { problem: docProblem("INSTRUCTION_MOVED", instructionFolderOf(path3)) } : {};
|
|
26888
26790
|
if (classifyDocPath(path3).type !== "doc") return {};
|
|
26889
26791
|
if (seen.link) return { problem: docProblem("PATH_UNSUPPORTED", path3) };
|
|
26890
26792
|
if (seen.size > FILE_LIMIT) return { problem: docProblem("FILE_TOO_LARGE", path3) };
|
|
@@ -26959,13 +26861,6 @@ function createDocumentCache(root, database) {
|
|
|
26959
26861
|
return true;
|
|
26960
26862
|
}
|
|
26961
26863
|
};
|
|
26962
|
-
const instructionFile3 = (path3) => {
|
|
26963
|
-
try {
|
|
26964
|
-
return classifyDocPath(path3).type === "instruction-file";
|
|
26965
|
-
} catch {
|
|
26966
|
-
return false;
|
|
26967
|
-
}
|
|
26968
|
-
};
|
|
26969
26864
|
return {
|
|
26970
26865
|
sync,
|
|
26971
26866
|
/**
|
|
@@ -26982,7 +26877,7 @@ function createDocumentCache(root, database) {
|
|
|
26982
26877
|
if (history) seen.set(HISTORY_PATH, { mtime: history.mtimeMs, size: history.size, link: history.isSymbolicLink() || !history.isFile() });
|
|
26983
26878
|
const read2 = await Promise.all([...seen].map(async ([path3, s]) => {
|
|
26984
26879
|
if (!readable(path3)) return { path: path3 };
|
|
26985
|
-
if (
|
|
26880
|
+
if (isInstructionPath(path3) && !path3.endsWith(".md")) return { path: path3, text: "" };
|
|
26986
26881
|
if (s.link) return { path: path3, problem: docProblem("PATH_UNSUPPORTED", path3) };
|
|
26987
26882
|
if (s.size > (path3 === HISTORY_PATH ? 64 * FILE_LIMIT : FILE_LIMIT)) return { path: path3, problem: docProblem("FILE_TOO_LARGE", path3) };
|
|
26988
26883
|
try {
|
|
@@ -28079,88 +27974,6 @@ async function publishConfig(root, text4, recheck, beforePublish, replace = fals
|
|
|
28079
27974
|
}
|
|
28080
27975
|
}
|
|
28081
27976
|
|
|
28082
|
-
// src/adapters/filesystem/instruction-folder.ts
|
|
28083
|
-
import { lstat as lstat6, open as open3, readdir as readdir4, readFile as readFile5 } from "node:fs/promises";
|
|
28084
|
-
import { join as join7 } from "node:path";
|
|
28085
|
-
var INSTRUCTION_FILE_LIMIT = 500;
|
|
28086
|
-
var INSTRUCTION_TEXT_LIMIT = 512 * 1024;
|
|
28087
|
-
var folderOf3 = (root, instructionPath) => join7(root, ...instructionPath.split("/").slice(0, -1));
|
|
28088
|
-
async function listInstructionFiles(root, instructionPath) {
|
|
28089
|
-
const files = [];
|
|
28090
|
-
let limited = false;
|
|
28091
|
-
async function visit2(folder, prefix, depth) {
|
|
28092
|
-
if (depth > 10) return;
|
|
28093
|
-
const entries = await readdir4(folder, { withFileTypes: true }).catch(() => []);
|
|
28094
|
-
for (const entry2 of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
28095
|
-
if (files.length >= INSTRUCTION_FILE_LIMIT) {
|
|
28096
|
-
limited = true;
|
|
28097
|
-
return;
|
|
28098
|
-
}
|
|
28099
|
-
const path3 = prefix + entry2.name;
|
|
28100
|
-
if (entry2.isDirectory()) await visit2(join7(folder, entry2.name), path3 + "/", depth + 1);
|
|
28101
|
-
else if (entry2.isFile() && path3 !== INSTRUCTION_FILE) files.push({ path: path3, size: (await lstat6(join7(folder, entry2.name))).size });
|
|
28102
|
-
}
|
|
28103
|
-
}
|
|
28104
|
-
await visit2(folderOf3(root, instructionPath), "", 0);
|
|
28105
|
-
return { files, limited };
|
|
28106
|
-
}
|
|
28107
|
-
var FRONTMATTER_WINDOW = 8 * 1024;
|
|
28108
|
-
async function describeFiles(root, instructionPath, files) {
|
|
28109
|
-
const folder = folderOf3(root, instructionPath);
|
|
28110
|
-
return Promise.all(files.map(async (file2) => {
|
|
28111
|
-
if (!isInstructionReference(file2.path)) return file2;
|
|
28112
|
-
let handle;
|
|
28113
|
-
try {
|
|
28114
|
-
handle = await open3(join7(folder, ...file2.path.split("/")), "r");
|
|
28115
|
-
const buffer = Buffer.alloc(Math.min(FRONTMATTER_WINDOW, file2.size));
|
|
28116
|
-
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
28117
|
-
return { ...file2, ...parseInstructionFile(file2.path, buffer.subarray(0, bytesRead).toString("utf8")) };
|
|
28118
|
-
} catch {
|
|
28119
|
-
return file2;
|
|
28120
|
-
} finally {
|
|
28121
|
-
await handle?.close();
|
|
28122
|
-
}
|
|
28123
|
-
}));
|
|
28124
|
-
}
|
|
28125
|
-
async function readInstructionFiles(root, instructionPath) {
|
|
28126
|
-
const { files, limited } = await listInstructionFiles(root, instructionPath);
|
|
28127
|
-
return { files: await describeFiles(root, instructionPath, files), limited };
|
|
28128
|
-
}
|
|
28129
|
-
async function readInstructionFile(root, instructionPath, path3) {
|
|
28130
|
-
const parts = path3.split("/");
|
|
28131
|
-
if (parts.some((p) => !p || p === "." || p === ".." || /[\\:\0]/.test(p))) return void 0;
|
|
28132
|
-
let full = folderOf3(root, instructionPath);
|
|
28133
|
-
for (const [index, part] of parts.entries()) {
|
|
28134
|
-
full = join7(full, part);
|
|
28135
|
-
const info5 = await lstat6(full).catch(() => void 0);
|
|
28136
|
-
if (!info5 || info5.isSymbolicLink() || (index < parts.length - 1 ? !info5.isDirectory() : !info5.isFile())) return void 0;
|
|
28137
|
-
}
|
|
28138
|
-
const size = (await lstat6(full)).size;
|
|
28139
|
-
if (size > INSTRUCTION_TEXT_LIMIT) return { text: null, size, binary: false, tooLarge: true };
|
|
28140
|
-
const bytes = await readFile5(full);
|
|
28141
|
-
try {
|
|
28142
|
-
if (bytes.includes(0)) throw new TypeError("binary");
|
|
28143
|
-
return { text: new TextDecoder("utf-8", { fatal: true }).decode(bytes), size, binary: false, tooLarge: false };
|
|
28144
|
-
} catch {
|
|
28145
|
-
return { text: null, size, binary: true, tooLarge: false };
|
|
28146
|
-
}
|
|
28147
|
-
}
|
|
28148
|
-
|
|
28149
|
-
// src/adapters/filesystem/agents-file.ts
|
|
28150
|
-
import { lstat as lstat7, readFile as readFile6 } from "node:fs/promises";
|
|
28151
|
-
import { join as join8 } from "node:path";
|
|
28152
|
-
var LIMIT = 1024 * 1024;
|
|
28153
|
-
async function readAgentsFile(root) {
|
|
28154
|
-
const file2 = join8(root, "AGENTS.md");
|
|
28155
|
-
const info5 = await lstat7(file2).catch(() => void 0);
|
|
28156
|
-
if (!info5?.isFile() || info5.size > LIMIT) return null;
|
|
28157
|
-
try {
|
|
28158
|
-
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: false }).decode(await readFile6(file2));
|
|
28159
|
-
} catch {
|
|
28160
|
-
return null;
|
|
28161
|
-
}
|
|
28162
|
-
}
|
|
28163
|
-
|
|
28164
27977
|
// src/queries/document-states.ts
|
|
28165
27978
|
var isDocument = (path3) => {
|
|
28166
27979
|
try {
|
|
@@ -28229,8 +28042,8 @@ async function documentsAtHead(project, head, paths2) {
|
|
|
28229
28042
|
|
|
28230
28043
|
// src/server/checkout/stamp.ts
|
|
28231
28044
|
import { createHash as createHash2 } from "node:crypto";
|
|
28232
|
-
import { lstat as
|
|
28233
|
-
import { join as
|
|
28045
|
+
import { lstat as lstat6 } from "node:fs/promises";
|
|
28046
|
+
import { join as join7 } from "node:path";
|
|
28234
28047
|
function createStampReader(root, inherited = process.env) {
|
|
28235
28048
|
const runner = createGitRunner();
|
|
28236
28049
|
const env = { ...inherited, GIT_OPTIONAL_LOCKS: "0", GIT_NO_REPLACE_OBJECTS: "1", GIT_TERMINAL_PROMPT: "0", GIT_LITERAL_PATHSPECS: "0", LC_ALL: "C" };
|
|
@@ -28242,10 +28055,10 @@ function createStampReader(root, inherited = process.env) {
|
|
|
28242
28055
|
]);
|
|
28243
28056
|
const paths2 = status.split("\0").filter(Boolean).map((entry2) => entry2.slice(3)).filter((path3) => !path3.startsWith(".gitifact/cache/"));
|
|
28244
28057
|
const seen = await Promise.all(paths2.map(async (path3) => {
|
|
28245
|
-
const info5 = await
|
|
28058
|
+
const info5 = await lstat6(join7(root, ...path3.split("/"))).catch(() => void 0);
|
|
28246
28059
|
return path3 + " " + (info5 ? info5.mtimeMs + ":" + info5.size : "-");
|
|
28247
28060
|
}));
|
|
28248
|
-
const mailmap = await
|
|
28061
|
+
const mailmap = await lstat6(join7(root, ".mailmap")).catch(() => void 0);
|
|
28249
28062
|
seen.push(".mailmap " + (mailmap ? mailmap.mtimeMs + ":" + mailmap.size : "-"));
|
|
28250
28063
|
return createHash2("sha256").update(head.trim() + "\n" + seen.sort().join("\n")).digest("hex").slice(0, 20);
|
|
28251
28064
|
};
|
|
@@ -28258,7 +28071,7 @@ async function settled(reads) {
|
|
|
28258
28071
|
if (failure2) throw failure2.reason;
|
|
28259
28072
|
return results.map((r) => r.value);
|
|
28260
28073
|
}
|
|
28261
|
-
var
|
|
28074
|
+
var folderOf3 = (path3) => path3.split("/").slice(0, 3).join("/");
|
|
28262
28075
|
function checkoutDocuments(states, authors) {
|
|
28263
28076
|
const documents = states.documents;
|
|
28264
28077
|
const standing2 = (id) => {
|
|
@@ -28273,7 +28086,7 @@ function checkoutDocuments(states, authors) {
|
|
|
28273
28086
|
};
|
|
28274
28087
|
const arranged = arrangeDocuments(documents);
|
|
28275
28088
|
const features = arranged.features.map(({ index, requirements, designs }) => {
|
|
28276
|
-
const entry2 = authors.get(
|
|
28089
|
+
const entry2 = authors.get(folderOf3(index.path));
|
|
28277
28090
|
return {
|
|
28278
28091
|
id: index.id,
|
|
28279
28092
|
path: index.path,
|
|
@@ -28298,17 +28111,7 @@ function checkoutDocuments(states, authors) {
|
|
|
28298
28111
|
updatedAt: entry2?.latest ?? null
|
|
28299
28112
|
};
|
|
28300
28113
|
});
|
|
28301
|
-
|
|
28302
|
-
id: k.id,
|
|
28303
|
-
name: k.name,
|
|
28304
|
-
path: k.path,
|
|
28305
|
-
title: k.title,
|
|
28306
|
-
description: k.description,
|
|
28307
|
-
body: k.body,
|
|
28308
|
-
...standing2(k.id),
|
|
28309
|
-
updatedAt: authors.get(folderOf4(k.path))?.latest ?? null
|
|
28310
|
-
}));
|
|
28311
|
-
return { features, instructions: instructions2, orphans: arranged.orphans };
|
|
28114
|
+
return { features, orphans: arranged.orphans };
|
|
28312
28115
|
}
|
|
28313
28116
|
function createCheckoutReader(root, cache, inherited = process.env) {
|
|
28314
28117
|
const reader = storeReader(root);
|
|
@@ -28337,16 +28140,15 @@ function createCheckoutReader(root, cache, inherited = process.env) {
|
|
|
28337
28140
|
head ? cache.log.contributors(head) : Promise.resolve([])
|
|
28338
28141
|
]);
|
|
28339
28142
|
const states = await documentStates({ head: async () => head, reader }, current3.documents);
|
|
28340
|
-
const { features,
|
|
28143
|
+
const { features, orphans } = checkoutDocuments(states, authors);
|
|
28341
28144
|
const problems = [...current3.problems, ...orphans.map((feature2) => docProblem("FEATURE_INDEX_REQUIRED", `.gitifact/spec/${feature2}/index.md`, { feature: feature2 }))];
|
|
28342
28145
|
if (await readHead() !== head) throw new StoreError(t2("specReader.projectChanged"));
|
|
28343
28146
|
return {
|
|
28344
28147
|
head,
|
|
28345
28148
|
stamp,
|
|
28346
28149
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28347
|
-
working: head ? !!dirty.trim() : features.length > 0
|
|
28150
|
+
working: head ? !!dirty.trim() : features.length > 0,
|
|
28348
28151
|
features,
|
|
28349
|
-
instructions: instructions2,
|
|
28350
28152
|
problems,
|
|
28351
28153
|
people,
|
|
28352
28154
|
folders: authors
|
|
@@ -28369,19 +28171,7 @@ function createCheckoutReader(root, cache, inherited = process.env) {
|
|
|
28369
28171
|
}
|
|
28370
28172
|
return value;
|
|
28371
28173
|
};
|
|
28372
|
-
return {
|
|
28373
|
-
base,
|
|
28374
|
-
/** Every instruction by name with the other files of its folder, and AGENTS.md: few enough to read whole. */
|
|
28375
|
-
async instructions() {
|
|
28376
|
-
const checkout = await base();
|
|
28377
|
-
const instructions2 = await Promise.all([...checkout.instructions].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0).map(async (instruction2) => {
|
|
28378
|
-
const { files, limited } = instruction2.state === "deleted" ? { files: [], limited: false } : await readInstructionFiles(root, instruction2.path);
|
|
28379
|
-
return { ...instruction2, files, filesLimited: limited };
|
|
28380
|
-
}));
|
|
28381
|
-
const agentsText = await readAgentsFile(root);
|
|
28382
|
-
return { instructions: instructions2, agents: agentsText === null ? null : { path: "AGENTS.md", body: agentsText, updatedAt: checkout.folders.get("AGENTS.md")?.latest ?? null } };
|
|
28383
|
-
}
|
|
28384
|
-
};
|
|
28174
|
+
return { base };
|
|
28385
28175
|
}
|
|
28386
28176
|
|
|
28387
28177
|
// src/queries/paging.ts
|
|
@@ -28546,11 +28336,11 @@ async function workingChange2(source2, id) {
|
|
|
28546
28336
|
}
|
|
28547
28337
|
|
|
28548
28338
|
// src/queries/search.ts
|
|
28549
|
-
var SEARCH_GROUPS = ["feature", "requirement", "design", "
|
|
28339
|
+
var SEARCH_GROUPS = ["feature", "requirement", "design", "record", "commit"];
|
|
28550
28340
|
var FIRST = 5;
|
|
28551
28341
|
var RECENT = 6;
|
|
28552
28342
|
var place2 = (path3) => path3.replace(/^\.gitifact\//, "");
|
|
28553
|
-
var
|
|
28343
|
+
var folderOf4 = (path3) => path3.split("/").slice(0, 3).join("/");
|
|
28554
28344
|
async function searchRecords(source2, request) {
|
|
28555
28345
|
const head = request.head ?? await source2.head();
|
|
28556
28346
|
const query = request.q.trim().toLowerCase();
|
|
@@ -28567,14 +28357,7 @@ async function searchRecords(source2, request) {
|
|
|
28567
28357
|
var empty = () => ({ total: 0, next: null, hits: [] });
|
|
28568
28358
|
async function recent(source2, head) {
|
|
28569
28359
|
const [{ documents }, folders] = await Promise.all([source2.cache.documents.list(), head ? source2.cache.log.folders(head) : /* @__PURE__ */ new Map()]);
|
|
28570
|
-
const hits = documents.filter((d) => d.kind === "feature"
|
|
28571
|
-
id: doc.id,
|
|
28572
|
-
kind: doc.kind,
|
|
28573
|
-
title: doc.title,
|
|
28574
|
-
where: place2(doc.path),
|
|
28575
|
-
line: doc.description,
|
|
28576
|
-
...doc.kind === "feature" ? { featureId: doc.id } : {}
|
|
28577
|
-
}));
|
|
28360
|
+
const hits = documents.filter((d) => d.kind === "feature").map((d) => ({ doc: d, latest: folders.get(folderOf4(d.path))?.latest })).filter((d) => !!d.latest).sort((a, b) => Date.parse(b.latest) - Date.parse(a.latest) || a.doc.id.localeCompare(b.doc.id)).slice(0, RECENT).map(({ doc }) => ({ id: doc.id, kind: "feature", title: doc.title, where: place2(doc.path), line: doc.description, featureId: doc.id }));
|
|
28578
28361
|
return { group: "recent", total: hits.length, next: null, hits };
|
|
28579
28362
|
}
|
|
28580
28363
|
|
|
@@ -28609,7 +28392,6 @@ function checkoutIndex(base) {
|
|
|
28609
28392
|
requirements: f.requirements.map((r) => ({ id: r.id, path: r.path, title: r.title, description: r.description })),
|
|
28610
28393
|
designs: f.designs.map((d) => ({ id: d.id, path: d.path, title: d.title }))
|
|
28611
28394
|
})),
|
|
28612
|
-
instructions: base.instructions.map((k) => ({ id: k.id, name: k.name, path: k.path, title: k.title })),
|
|
28613
28395
|
people: base.people.map((p) => ({ name: p.name, email: p.email }))
|
|
28614
28396
|
};
|
|
28615
28397
|
}
|
|
@@ -28703,12 +28485,12 @@ function recordRoutes(root, sessionId, env) {
|
|
|
28703
28485
|
const cursorGone2 = () => new HttpError(404, "NOT_FOUND", t2("server.cursorNotFound"));
|
|
28704
28486
|
return [
|
|
28705
28487
|
// The checkout a part at a time, each shaped by the query layer (`queries/checkout.ts`): the frame every screen reads
|
|
28706
|
-
// first, the feature list and one feature,
|
|
28488
|
+
// first, the feature list and one feature, and the contributors.
|
|
28707
28489
|
route({ method: "GET", path: "/api/v1/checkout", session: true, unreadable: unreadable2, handle: async () => {
|
|
28708
28490
|
const base = await checkout.base();
|
|
28709
|
-
return ok(
|
|
28491
|
+
return ok(browserCheckoutV2.parse({
|
|
28710
28492
|
contract: "browser-checkout",
|
|
28711
|
-
version:
|
|
28493
|
+
version: 2,
|
|
28712
28494
|
sessionId,
|
|
28713
28495
|
head: base.head,
|
|
28714
28496
|
observedAt: base.observedAt,
|
|
@@ -28728,7 +28510,6 @@ function recordRoutes(root, sessionId, env) {
|
|
|
28728
28510
|
if (!feature2) throw new HttpError(404, "NOT_FOUND", t2("server.featureNotFound"));
|
|
28729
28511
|
return ok(browserFeatureV2.parse({ contract: "browser-feature", version: 2, sessionId, feature: feature2 }));
|
|
28730
28512
|
} }),
|
|
28731
|
-
route({ method: "GET", path: "/api/v1/instructions", session: true, unreadable: unreadable2, handle: async () => ok(browserInstructionsV1.parse({ contract: "browser-instructions", version: 1, sessionId, ...await checkout.instructions() })) }),
|
|
28732
28513
|
route({ method: "GET", path: "/api/v1/contributors", session: true, query: browserContributorsQueryV1, unreadable: unreadable2, handle: async ({ query }) => {
|
|
28733
28514
|
const page = listContributors(await checkout.base(), query.q, { after: query.after, limit: query.limit ?? PAGE });
|
|
28734
28515
|
if (!page) throw cursorGone2();
|
|
@@ -28821,35 +28602,28 @@ function recordRoutes(root, sessionId, env) {
|
|
|
28821
28602
|
if (!found) throw new HttpError(404, "NOT_FOUND", t2("server.commitFileNotFound"));
|
|
28822
28603
|
return ok(browserCommitFileV1.parse({ contract: "browser-commit-file", version: 1, sessionId, commit: query.commit, ...found }));
|
|
28823
28604
|
} }),
|
|
28824
|
-
// One file of an instruction folder, read from the working tree when the reader opens it; the checkout lists the files.
|
|
28825
|
-
route({ method: "GET", path: "/api/v1/instructions/file", session: true, query: browserInstructionFileQueryV1, unreadable: unreadable2, handle: async ({ query }) => {
|
|
28826
|
-
const instruction2 = (await cache.documents.list()).documents.find((d) => d.id === query.id && d.kind === "instruction");
|
|
28827
|
-
const found = instruction2 && await readInstructionFile(root, instruction2.path, query.path);
|
|
28828
|
-
if (!found) throw new HttpError(404, "NOT_FOUND", t2("server.instructionFileNotFound"));
|
|
28829
|
-
return ok(browserInstructionFileV1.parse({ contract: "browser-instruction-file", version: 1, sessionId, id: query.id, path: query.path, ...found }));
|
|
28830
|
-
} }),
|
|
28831
28605
|
// The search box's groups as the query layer works them out (`queries/search.ts`); the browser only draws them.
|
|
28832
|
-
route({ method: "GET", path: "/api/v1/search", session: true, query:
|
|
28606
|
+
route({ method: "GET", path: "/api/v1/search", session: true, query: browserSearchQueryV3, unreadable: unreadable2, handle: async ({ query }) => {
|
|
28833
28607
|
const groups = await searchRecords(source2, query);
|
|
28834
28608
|
if (!groups) throw cursorGone2();
|
|
28835
|
-
return ok(
|
|
28609
|
+
return ok(browserSearchV4.parse({ contract: "browser-search", version: 4, sessionId, query: query.q, groups }));
|
|
28836
28610
|
} })
|
|
28837
28611
|
];
|
|
28838
28612
|
}
|
|
28839
28613
|
|
|
28840
28614
|
// src/server/routes/asset-routes.ts
|
|
28841
|
-
import { lstat as
|
|
28842
|
-
import { join as
|
|
28615
|
+
import { lstat as lstat7, readFile as readFile5 } from "node:fs/promises";
|
|
28616
|
+
import { join as join8 } from "node:path";
|
|
28843
28617
|
function assetRoutes(root) {
|
|
28844
28618
|
return [
|
|
28845
28619
|
route({ method: "GET", path: "/api/v1/assets/*", session: false, handle: async ({ path: path3, response }) => {
|
|
28846
28620
|
const relative = path3.slice("/api/v1/assets/".length);
|
|
28847
28621
|
const assetPath = ASSETS_DIR + "/" + relative;
|
|
28848
28622
|
if (!isAssetPath(assetPath)) throw new HttpError(404, "NOT_FOUND", t2("server.assetNotFound"));
|
|
28849
|
-
const file2 =
|
|
28850
|
-
const stat3 = await
|
|
28623
|
+
const file2 = join8(root, ...assetPath.split("/"));
|
|
28624
|
+
const stat3 = await lstat7(file2).catch(() => void 0);
|
|
28851
28625
|
if (!stat3?.isFile() || stat3.isSymbolicLink() || stat3.size > 20 * 1024 * 1024) throw new HttpError(404, "NOT_FOUND", t2("server.assetNotFound"));
|
|
28852
|
-
const bytes = await
|
|
28626
|
+
const bytes = await readFile5(file2);
|
|
28853
28627
|
const extension = assetExtension(relative);
|
|
28854
28628
|
const inline = ["png", "jpg", "jpeg", "gif", "webp", "svg"].includes(extension);
|
|
28855
28629
|
response.writeHead(200, {
|
|
@@ -28866,7 +28640,7 @@ function assetRoutes(root) {
|
|
|
28866
28640
|
}
|
|
28867
28641
|
|
|
28868
28642
|
// src/server/browser-server.ts
|
|
28869
|
-
var readBundledChangelog = (language) =>
|
|
28643
|
+
var readBundledChangelog = (language) => readFile6(new URL("./i18n/" + language + "/changelog.md", import.meta.url), "utf8").catch((error62) => {
|
|
28870
28644
|
if (error62.code === "ENOENT") return null;
|
|
28871
28645
|
throw error62;
|
|
28872
28646
|
});
|
|
@@ -28996,14 +28770,14 @@ async function runBrowser(options, version2) {
|
|
|
28996
28770
|
}
|
|
28997
28771
|
|
|
28998
28772
|
// src/commands/spec-init.ts
|
|
28999
|
-
import { readdir as
|
|
29000
|
-
import { join as
|
|
28773
|
+
import { readdir as readdir4 } from "node:fs/promises";
|
|
28774
|
+
import { join as join13 } from "node:path";
|
|
29001
28775
|
|
|
29002
28776
|
// src/adapters/git/init-repository.ts
|
|
29003
28777
|
import { createHash as createHash3 } from "node:crypto";
|
|
29004
|
-
import { lstat as
|
|
29005
|
-
import { join as
|
|
29006
|
-
var markerPresent = (path3) =>
|
|
28778
|
+
import { lstat as lstat8, readFile as readFile7 } from "node:fs/promises";
|
|
28779
|
+
import { join as join9 } from "node:path";
|
|
28780
|
+
var markerPresent = (path3) => lstat8(path3).then(() => true, (error62) => {
|
|
29007
28781
|
if (error62.code === "ENOENT") return false;
|
|
29008
28782
|
throw error62;
|
|
29009
28783
|
});
|
|
@@ -29026,10 +28800,10 @@ function initRepository(cwd, inherited = process.env) {
|
|
|
29026
28800
|
const gitDir = locations.length === 2 ? locations[0] : decodeGitLine(await git(["rev-parse", "--absolute-git-dir"], root));
|
|
29027
28801
|
const indexPath = locations.length === 2 ? locations[1] : decodeGitLine(await git(["rev-parse", "--path-format=absolute", "--git-path", "index"], root));
|
|
29028
28802
|
for (const marker2 of ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply", "sequencer", "BISECT_START", "index.lock"]) {
|
|
29029
|
-
if (await markerPresent(
|
|
28803
|
+
if (await markerPresent(join9(gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
|
|
29030
28804
|
}
|
|
29031
28805
|
if (state2.changes.some((change2) => change2.kind === "unmerged")) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
|
|
29032
|
-
const index = await
|
|
28806
|
+
const index = await readFile7(indexPath).catch((error62) => {
|
|
29033
28807
|
if (error62.code === "ENOENT") return Buffer.alloc(0);
|
|
29034
28808
|
throw error62;
|
|
29035
28809
|
});
|
|
@@ -29064,14 +28838,14 @@ function initRepository(cwd, inherited = process.env) {
|
|
|
29064
28838
|
|
|
29065
28839
|
// src/adapters/filesystem/document-file.ts
|
|
29066
28840
|
import { randomBytes } from "node:crypto";
|
|
29067
|
-
import { lstat as
|
|
29068
|
-
import { join as
|
|
28841
|
+
import { lstat as lstat9, mkdir as mkdir3, writeFile as writeFile2 } from "node:fs/promises";
|
|
28842
|
+
import { join as join10 } from "node:path";
|
|
29069
28843
|
var generateId = (prefix) => prefix + "-" + [...randomBytes(10)].map((n) => "abcdefghijklmnopqrstuvwxyz234567"[n & 31]).join("");
|
|
29070
28844
|
async function createDocumentFile(root, path3, text4) {
|
|
29071
28845
|
const parts = path3.split("/");
|
|
29072
28846
|
for (let i = 1; i < parts.length; i++) {
|
|
29073
|
-
const folder =
|
|
29074
|
-
const info5 = await
|
|
28847
|
+
const folder = join10(root, ...parts.slice(0, i));
|
|
28848
|
+
const info5 = await lstat9(folder).catch((error62) => {
|
|
29075
28849
|
if (error62.code === "ENOENT") return void 0;
|
|
29076
28850
|
throw error62;
|
|
29077
28851
|
});
|
|
@@ -29081,7 +28855,7 @@ async function createDocumentFile(root, path3, text4) {
|
|
|
29081
28855
|
}
|
|
29082
28856
|
if (!info5.isDirectory() || info5.isSymbolicLink()) throw Object.assign(new Error(folder), { code: "ENOTDIR" });
|
|
29083
28857
|
}
|
|
29084
|
-
await writeFile2(
|
|
28858
|
+
await writeFile2(join10(root, ...parts), text4, { flag: "wx" });
|
|
29085
28859
|
}
|
|
29086
28860
|
var LINE_ENDINGS_PATH = ".gitifact/.gitattributes";
|
|
29087
28861
|
var LINE_ENDINGS = "# Written by gitifact init: documents keep LF on every OS, so what Git holds and the files read the same.\n* text=auto eol=lf\n";
|
|
@@ -29095,19 +28869,50 @@ async function writeLineEndings(root) {
|
|
|
29095
28869
|
}
|
|
29096
28870
|
}
|
|
29097
28871
|
|
|
28872
|
+
// src/adapters/filesystem/launcher-file.ts
|
|
28873
|
+
import { lstat as lstat10, mkdir as mkdir4, readFile as readFile8, writeFile as writeFile3 } from "node:fs/promises";
|
|
28874
|
+
import { join as join11 } from "node:path";
|
|
28875
|
+
var LAUNCHER_PATH = ".gitifact/bin/cli.mjs";
|
|
28876
|
+
var readBundledLauncher = () => readFile8(new URL("./launcher/cli.mjs", import.meta.url), "utf8").catch((error62) => {
|
|
28877
|
+
if (error62.code === "ENOENT") return void 0;
|
|
28878
|
+
throw error62;
|
|
28879
|
+
});
|
|
28880
|
+
async function refreshLauncher(root) {
|
|
28881
|
+
const text4 = await readBundledLauncher();
|
|
28882
|
+
return text4 === void 0 ? false : writeLauncher(root, text4.replace(/\r\n/g, "\n"));
|
|
28883
|
+
}
|
|
28884
|
+
async function writeLauncher(root, text4) {
|
|
28885
|
+
const folder = join11(root, ".gitifact", "bin");
|
|
28886
|
+
const file2 = join11(folder, "cli.mjs");
|
|
28887
|
+
const folderInfo = await lstat10(folder).catch((error62) => {
|
|
28888
|
+
if (error62.code === "ENOENT") return void 0;
|
|
28889
|
+
throw error62;
|
|
28890
|
+
});
|
|
28891
|
+
if (folderInfo && (!folderInfo.isDirectory() || folderInfo.isSymbolicLink())) throw Object.assign(new Error(folder), { code: "ENOTDIR" });
|
|
28892
|
+
if (!folderInfo) await mkdir4(folder);
|
|
28893
|
+
const info5 = await lstat10(file2).catch((error62) => {
|
|
28894
|
+
if (error62.code === "ENOENT") return void 0;
|
|
28895
|
+
throw error62;
|
|
28896
|
+
});
|
|
28897
|
+
if (info5 && (!info5.isFile() || info5.isSymbolicLink())) throw Object.assign(new Error(file2), { code: "ENOTDIR" });
|
|
28898
|
+
if (info5 && (await readFile8(file2, "utf8")).replace(/\r\n/g, "\n") === text4) return false;
|
|
28899
|
+
await writeFile3(file2, text4);
|
|
28900
|
+
return true;
|
|
28901
|
+
}
|
|
28902
|
+
|
|
29098
28903
|
// src/adapters/filesystem/managed-file.ts
|
|
29099
|
-
import { open as
|
|
29100
|
-
import { join as
|
|
28904
|
+
import { open as open3, readFile as readFile9, mkdir as mkdir5, realpath as realpath2, rename as rename2, link as link2, unlink as unlink2 } from "node:fs/promises";
|
|
28905
|
+
import { join as join12, dirname } from "node:path";
|
|
29101
28906
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
29102
28907
|
var DEFAULT_LIMIT = 1024 * 1024;
|
|
29103
28908
|
async function managedPath(root, path3, create = false) {
|
|
29104
28909
|
let full = root;
|
|
29105
28910
|
const parts = path3.split("/");
|
|
29106
28911
|
for (let i = 0; i < parts.length; i++) {
|
|
29107
|
-
full =
|
|
28912
|
+
full = join12(full, parts[i]);
|
|
29108
28913
|
let info5 = await fileInfo(full);
|
|
29109
28914
|
if (!info5 && create && i < parts.length - 1) {
|
|
29110
|
-
await
|
|
28915
|
+
await mkdir5(full).catch((error62) => {
|
|
29111
28916
|
if (error62.code !== "EEXIST") throw error62;
|
|
29112
28917
|
});
|
|
29113
28918
|
info5 = await fileInfo(full);
|
|
@@ -29123,7 +28928,7 @@ async function managedRead(root, path3, limit = DEFAULT_LIMIT) {
|
|
|
29123
28928
|
const before = await fileInfo(full);
|
|
29124
28929
|
if (!before) return null;
|
|
29125
28930
|
if (before.size > limit) throw new InitError("FILE_TOO_LARGE", t2("managedFile.tooLarge", { kib: limit / 1024, path: path3 }));
|
|
29126
|
-
const bytes = await
|
|
28931
|
+
const bytes = await readFile9(full);
|
|
29127
28932
|
await managedPath(root, path3);
|
|
29128
28933
|
const after = await fileInfo(full);
|
|
29129
28934
|
if (!after || before.ino !== after.ino || before.dev !== after.dev || before.mtimeMs !== after.mtimeMs || bytes.length > limit) {
|
|
@@ -29152,8 +28957,8 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
29152
28957
|
if (previous !== null) await unlink2(full);
|
|
29153
28958
|
return;
|
|
29154
28959
|
}
|
|
29155
|
-
const temp =
|
|
29156
|
-
const handle = await
|
|
28960
|
+
const temp = join12(directory, ".gitifact-managed-" + randomUUID4() + ".tmp");
|
|
28961
|
+
const handle = await open3(temp, "wx", 384);
|
|
29157
28962
|
const tempOwner = await handle.stat();
|
|
29158
28963
|
try {
|
|
29159
28964
|
try {
|
|
@@ -29164,7 +28969,7 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
29164
28969
|
}
|
|
29165
28970
|
await recheck();
|
|
29166
28971
|
await unchanged();
|
|
29167
|
-
if (await managedRead(root, path3) !== previous || await
|
|
28972
|
+
if (await managedRead(root, path3) !== previous || await readFile9(temp, "utf8") !== next) throw new InitError("INPUT_CHANGED", t2("managedFile.publishTargetChanged", { path: path3 }));
|
|
29168
28973
|
if (previous === null) await link2(temp, full);
|
|
29169
28974
|
else await rename2(temp, full);
|
|
29170
28975
|
} finally {
|
|
@@ -29175,10 +28980,10 @@ async function managedWrite(root, path3, previous, next, recheck) {
|
|
|
29175
28980
|
}
|
|
29176
28981
|
|
|
29177
28982
|
// src/commands/agent-block.ts
|
|
29178
|
-
import { readFile as
|
|
28983
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
29179
28984
|
|
|
29180
28985
|
// src/commands/guide.ts
|
|
29181
|
-
import { readFile as
|
|
28986
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
29182
28987
|
|
|
29183
28988
|
// src/commands/output.ts
|
|
29184
28989
|
var formats = ["text", "json"];
|
|
@@ -29213,9 +29018,9 @@ var section = (label, lines2, indent = " ") => lines2.length ? [label, ...lines
|
|
|
29213
29018
|
var text2 = (lines2) => lines2.join("\n") + "\n";
|
|
29214
29019
|
|
|
29215
29020
|
// src/commands/guide.ts
|
|
29216
|
-
var guideTopics = ["workflow", "spec", "design", "
|
|
29021
|
+
var guideTopics = ["workflow", "spec", "design", "records", "writing", "commit", "migrate"];
|
|
29217
29022
|
var isGuideTopic = (value) => guideTopics.includes(value);
|
|
29218
|
-
var readBundledGuide = (name2, lang) =>
|
|
29023
|
+
var readBundledGuide = (name2, lang) => readFile10(new URL("./i18n/" + lang + "/docs/" + name2 + ".md", import.meta.url), "utf8");
|
|
29219
29024
|
function guideSummary(source2) {
|
|
29220
29025
|
const { fields: fields2 } = parseFrontmatterBlock(source2.replace(/\r\n/g, "\n"), "guide");
|
|
29221
29026
|
const value = (key) => {
|
|
@@ -29256,7 +29061,7 @@ function boilerplateFor(path3) {
|
|
|
29256
29061
|
const name2 = path3 === "AGENTS.md" ? path3 : path3.split("/").pop().replace(/^\./, "").replace(/\.md$/, "");
|
|
29257
29062
|
return "# " + name2 + "\n\nProject-specific guidance for AI coding agents.\n";
|
|
29258
29063
|
}
|
|
29259
|
-
var readBundledBlock = (lang) =>
|
|
29064
|
+
var readBundledBlock = (lang) => readFile11(new URL("./i18n/" + lang + "/block.md", import.meta.url), "utf8");
|
|
29260
29065
|
async function renderAgentBlock(controls = {}, lang = getLanguage()) {
|
|
29261
29066
|
const body2 = await (controls.readBlock ?? readBundledBlock)(lang);
|
|
29262
29067
|
return AGENT_START + "\n" + body2.trimEnd().replace(/\{topics\}/g, guideTopics.join(", ")) + "\n" + AGENT_END;
|
|
@@ -29285,15 +29090,9 @@ function isWrapperFile(text4) {
|
|
|
29285
29090
|
return lines2.length > 0 && lines2.every((line2) => /^@(?:\.\/)?[^\s]+$/.test(line2) && candidatePaths.includes(line2.replace(/^@(?:\.\/)?/, "")));
|
|
29286
29091
|
}
|
|
29287
29092
|
var CLAUDE_WRAPPER_PATH = "CLAUDE.md";
|
|
29288
|
-
function claudeWrapperFor(agents2) {
|
|
29289
|
-
return "@AGENTS.md" + eolOf(agents2);
|
|
29290
|
-
}
|
|
29291
29093
|
function isGeneratedClaudeWrapper(text4) {
|
|
29292
29094
|
return text4.trim() === "@AGENTS.md";
|
|
29293
29095
|
}
|
|
29294
|
-
function lacksClaudeFile(existing) {
|
|
29295
|
-
return !existing.has("CLAUDE.md") && !existing.has(".claude/CLAUDE.md");
|
|
29296
|
-
}
|
|
29297
29096
|
function resolveAgentPaths(preset, existing) {
|
|
29298
29097
|
if (preset && preset !== "all") {
|
|
29299
29098
|
const order = agentPresets[preset];
|
|
@@ -29327,7 +29126,7 @@ function removeBlock(text4, boilerplate) {
|
|
|
29327
29126
|
}
|
|
29328
29127
|
|
|
29329
29128
|
// src/commands/agent-docs.ts
|
|
29330
|
-
var skippedAgentDocs = (language = explicitLanguage() ?? getLanguage()) => ({ mode: "skip", paths: [], writes: [],
|
|
29129
|
+
var skippedAgentDocs = (language = explicitLanguage() ?? getLanguage()) => ({ mode: "skip", paths: [], writes: [], language });
|
|
29331
29130
|
var blockOf = (text4) => {
|
|
29332
29131
|
try {
|
|
29333
29132
|
const found = findBlock(text4);
|
|
@@ -29362,7 +29161,7 @@ async function planAgentDocs(root, options) {
|
|
|
29362
29161
|
paths2.push(CLAUDE_WRAPPER_PATH);
|
|
29363
29162
|
writes.push({ path: CLAUDE_WRAPPER_PATH, previous: wrapper, next: null });
|
|
29364
29163
|
}
|
|
29365
|
-
return { mode: "remove", paths: paths2, writes,
|
|
29164
|
+
return { mode: "remove", paths: paths2, writes, language };
|
|
29366
29165
|
}
|
|
29367
29166
|
let block;
|
|
29368
29167
|
const blockFor = async () => block ??= await renderAgentBlock(options, language);
|
|
@@ -29377,19 +29176,11 @@ async function planAgentDocs(root, options) {
|
|
|
29377
29176
|
paths2.push(create);
|
|
29378
29177
|
writes.push({ path: create, previous: null, next: injectBlock(null, await blockFor(), boilerplateFor(create)) });
|
|
29379
29178
|
}
|
|
29380
|
-
const missing2 = [];
|
|
29381
|
-
if (paths2.includes("AGENTS.md") && lacksClaudeFile(existing)) {
|
|
29382
|
-
if (options.onlyExisting) missing2.push(CLAUDE_WRAPPER_PATH);
|
|
29383
|
-
else {
|
|
29384
|
-
paths2.push(CLAUDE_WRAPPER_PATH);
|
|
29385
|
-
writes.push({ path: CLAUDE_WRAPPER_PATH, previous: null, next: claudeWrapperFor(existing.get("AGENTS.md") ?? null) });
|
|
29386
|
-
}
|
|
29387
|
-
}
|
|
29388
29179
|
for (const [path3, text4] of existing) {
|
|
29389
29180
|
if (paths2.includes(path3) || !isWrapperFile(text4) || !findBlock(text4)) continue;
|
|
29390
29181
|
writes.push({ path: path3, previous: text4, next: removeBlock(text4, boilerplateFor(path3)) });
|
|
29391
29182
|
}
|
|
29392
|
-
return { mode: "install", paths: paths2, writes,
|
|
29183
|
+
return { mode: "install", paths: paths2, writes, language };
|
|
29393
29184
|
}
|
|
29394
29185
|
async function applyAgentDocs(root, plan, recheck) {
|
|
29395
29186
|
for (const write of plan.writes) await managedWrite(root, write.path, write.previous, write.next, recheck);
|
|
@@ -29498,6 +29289,7 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
|
|
|
29498
29289
|
current2 = next;
|
|
29499
29290
|
}
|
|
29500
29291
|
await applyAgentDocs(root, docsPlan, unchanged);
|
|
29292
|
+
if (agentDocs && !(config3.cli && isNewerRelease(config3.cli, agentDocs.version))) await refreshLauncher(root);
|
|
29501
29293
|
return result(settled2.config, "already-initialized", await writeLineEndings(root));
|
|
29502
29294
|
};
|
|
29503
29295
|
const base = { schemaVersion: SCHEMA_VERSION, baseline: first.state.head.commit ? { kind: "commit", objectFormat: first.state.repository.objectFormat, commit: first.state.head.commit } : { kind: "empty" } };
|
|
@@ -29509,13 +29301,14 @@ async function initializeSpecProject(cwd, dryRun = false, env = process.env, bef
|
|
|
29509
29301
|
};
|
|
29510
29302
|
await published();
|
|
29511
29303
|
await applyAgentDocs(root, docsPlan, published);
|
|
29304
|
+
if (agentDocs) await refreshLauncher(root);
|
|
29512
29305
|
return result(config2, outcome, await writeLineEndings(root));
|
|
29513
29306
|
};
|
|
29514
29307
|
const old = await readConfigFile(root);
|
|
29515
29308
|
if (old !== void 0) return existing(old);
|
|
29516
29309
|
if (first.trackedConfig) throw new InitError("CONFIG_DELETED", t2("init.configDeleted"));
|
|
29517
29310
|
const checkRecords = async () => {
|
|
29518
|
-
const entries = await
|
|
29311
|
+
const entries = await readdir4(join13(root, ".gitifact")).catch((e) => {
|
|
29519
29312
|
if (e.code === "ENOENT") return [];
|
|
29520
29313
|
throw e;
|
|
29521
29314
|
});
|
|
@@ -29553,22 +29346,22 @@ var fetchLatestVersion = async (signal) => {
|
|
|
29553
29346
|
};
|
|
29554
29347
|
|
|
29555
29348
|
// src/adapters/filesystem/user-cache.ts
|
|
29556
|
-
import { mkdir as
|
|
29349
|
+
import { mkdir as mkdir6, readFile as readFile12, rename as rename3, unlink as unlink3, writeFile as writeFile4 } from "node:fs/promises";
|
|
29557
29350
|
import { homedir } from "node:os";
|
|
29558
|
-
import { join as
|
|
29351
|
+
import { join as join14 } from "node:path";
|
|
29559
29352
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
29560
29353
|
function userCacheDirectory(env = process.env, platform = process.platform, home = homedir()) {
|
|
29561
29354
|
if (env.GITIFACT_CACHE_DIR) return env.GITIFACT_CACHE_DIR;
|
|
29562
|
-
if (platform === "win32") return
|
|
29563
|
-
if (platform === "darwin") return
|
|
29564
|
-
return
|
|
29355
|
+
if (platform === "win32") return join14(env.LOCALAPPDATA || join14(home, "AppData", "Local"), "gitifact");
|
|
29356
|
+
if (platform === "darwin") return join14(home, "Library", "Caches", "gitifact");
|
|
29357
|
+
return join14(env.XDG_CACHE_HOME || join14(home, ".cache"), "gitifact");
|
|
29565
29358
|
}
|
|
29566
|
-
var cacheFile = (env) =>
|
|
29359
|
+
var cacheFile = (env) => join14(userCacheDirectory(env), "update.json");
|
|
29567
29360
|
var isTime = (value) => typeof value === "string" && !Number.isNaN(Date.parse(value));
|
|
29568
29361
|
async function readUpdateCache(env = process.env) {
|
|
29569
29362
|
let value;
|
|
29570
29363
|
try {
|
|
29571
|
-
value = JSON.parse(await
|
|
29364
|
+
value = JSON.parse(await readFile12(cacheFile(env), "utf8"));
|
|
29572
29365
|
} catch {
|
|
29573
29366
|
return {};
|
|
29574
29367
|
}
|
|
@@ -29583,11 +29376,11 @@ async function readUpdateCache(env = process.env) {
|
|
|
29583
29376
|
}
|
|
29584
29377
|
async function changeUpdateCache(env, change2) {
|
|
29585
29378
|
const directory = userCacheDirectory(env);
|
|
29586
|
-
const temporary =
|
|
29379
|
+
const temporary = join14(directory, "update-" + randomUUID5() + ".tmp");
|
|
29587
29380
|
try {
|
|
29588
29381
|
const next = change2(await readUpdateCache(env));
|
|
29589
|
-
await
|
|
29590
|
-
await
|
|
29382
|
+
await mkdir6(directory, { recursive: true });
|
|
29383
|
+
await writeFile4(temporary, JSON.stringify(next) + "\n", "utf8");
|
|
29591
29384
|
await rename3(temporary, cacheFile(env));
|
|
29592
29385
|
} catch {
|
|
29593
29386
|
await unlink3(temporary).catch(() => {
|
|
@@ -29616,7 +29409,7 @@ async function runInit(options, version2) {
|
|
|
29616
29409
|
await recordUpdateCheck(process.env, dto.update);
|
|
29617
29410
|
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") + ")");
|
|
29618
29411
|
const lineEndings = dto.lineEndings.created ? t2("init.text.lineEndings", { path: dto.lineEndings.path }) + "\n" : "";
|
|
29619
|
-
const newer = dto.install ? t2("init.text.updateAvailable", { version: dto.update.latestVersion, command: dto.install.
|
|
29412
|
+
const newer = dto.install ? t2("init.text.updateAvailable", { version: dto.update.latestVersion, command: dto.install.npx }) + "\n" : "";
|
|
29620
29413
|
process.stdout.write(options.format === "text" ? `${dto.outcome}: ${dto.rootPath}/.gitifact/config.json
|
|
29621
29414
|
${t2("init.text.storage")}: schemaVersion ${dto.schemaVersion}
|
|
29622
29415
|
${t2("init.text.agentDocs")}: ${docs}
|
|
@@ -29631,17 +29424,17 @@ ${lineEndings}${newer}` : JSON.stringify(dto) + "\n");
|
|
|
29631
29424
|
}
|
|
29632
29425
|
|
|
29633
29426
|
// src/commands/documents.ts
|
|
29634
|
-
import { readFile as
|
|
29635
|
-
import { join as
|
|
29427
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
29428
|
+
import { join as join16 } from "node:path";
|
|
29636
29429
|
|
|
29637
29430
|
// src/commands/project.ts
|
|
29638
|
-
import { join as
|
|
29431
|
+
import { join as join15 } from "node:path";
|
|
29639
29432
|
var operations = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "rebase-merge", "rebase-apply", "sequencer", "BISECT_START", "index.lock"];
|
|
29640
29433
|
async function openProject(cwd, options = {}) {
|
|
29641
29434
|
const reader = storeReader(cwd);
|
|
29642
29435
|
const location = await reader.location();
|
|
29643
29436
|
if (options.writing) {
|
|
29644
|
-
for (const marker2 of operations) if (await fileInfo(
|
|
29437
|
+
for (const marker2 of operations) if (await fileInfo(join15(location.gitDir, marker2))) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.operationInProgress", { marker: marker2 }));
|
|
29645
29438
|
if (await reader.hasUnmerged()) throw new InitError("GIT_OPERATION_IN_PROGRESS", t2("git.resolveConflicts"));
|
|
29646
29439
|
}
|
|
29647
29440
|
const raw = await readConfigFile(location.root);
|
|
@@ -29800,12 +29593,11 @@ var stateLabel = {
|
|
|
29800
29593
|
};
|
|
29801
29594
|
var stateMark = (state2) => state2 === "committed" ? "" : " (" + stateLabel[state2]() + ")";
|
|
29802
29595
|
var line = (doc) => `${doc.id} ${doc.title}${draftMark(doc)} \u2014 ${doc.description}`;
|
|
29803
|
-
var fileLine = (f) => f.title ? `${f.path} ${f.title} \u2014 ${f.description}` : f.path;
|
|
29804
29596
|
async function working(project) {
|
|
29805
29597
|
const { documents } = await project.cache.documents.list();
|
|
29806
29598
|
return {
|
|
29807
29599
|
byId: new Map(documents.map((d) => [d.id, d])),
|
|
29808
|
-
read: (path3) =>
|
|
29600
|
+
read: (path3) => readFile13(join16(project.root, ...path3.split("/")), "utf8"),
|
|
29809
29601
|
referencing: async (id) => [...new Set((await project.cache.documents.referencing(id)).map((r) => r.from))]
|
|
29810
29602
|
};
|
|
29811
29603
|
}
|
|
@@ -29818,12 +29610,12 @@ async function committed(project, commit) {
|
|
|
29818
29610
|
referencing: async (id) => documents.filter((d) => d.kind === "design" && (d.requirements.includes(id) || d.sources.some((s) => "id" in s && s.id === id))).map((d) => d.id)
|
|
29819
29611
|
};
|
|
29820
29612
|
}
|
|
29821
|
-
async function showDocuments(project, ids, at, kinds
|
|
29613
|
+
async function showDocuments(project, ids, at, kinds) {
|
|
29822
29614
|
const view = at === void 0 ? await working(project) : await committed(project, at);
|
|
29823
29615
|
const unknown2 = ids.filter((id) => !view.byId.has(id));
|
|
29824
29616
|
if (unknown2.length) throw new CommandError("UNKNOWN_DOCUMENT", t2("docs.unknownDocument", { ids: unknown2.join(", ") }));
|
|
29825
29617
|
const other = ids.filter((id) => !kinds.includes(view.byId.get(id).kind));
|
|
29826
|
-
if (other.length) throw new CommandError("UNKNOWN_DOCUMENT", t2("docs.
|
|
29618
|
+
if (other.length) throw new CommandError("UNKNOWN_DOCUMENT", t2("docs.unknownDocument", { ids: other.join(", ") }));
|
|
29827
29619
|
const shown = await Promise.all([...new Set(ids)].map(async (id) => {
|
|
29828
29620
|
const doc = view.byId.get(id);
|
|
29829
29621
|
const references = doc.kind === "design" ? [
|
|
@@ -29831,34 +29623,30 @@ async function showDocuments(project, ids, at, kinds, otherResource) {
|
|
|
29831
29623
|
...doc.sources.map((s) => "id" in s ? { id: s.id, title: view.byId.get(s.id)?.title ?? null } : { title: s.title, url: s.url })
|
|
29832
29624
|
] : [];
|
|
29833
29625
|
const referencedBy = (await view.referencing(id)).map((from) => ({ id: from, title: view.byId.get(from)?.title ?? null }));
|
|
29834
|
-
|
|
29835
|
-
return { id, kind: doc.kind, path: doc.path, title: doc.title, text: await view.read(doc.path), references, referencedBy, ...files };
|
|
29626
|
+
return { id, kind: doc.kind, path: doc.path, title: doc.title, text: await view.read(doc.path), references, referencedBy };
|
|
29836
29627
|
}));
|
|
29837
29628
|
const named = (r) => r.id ? r.id + " " + (r.title ?? "(" + t2("docs.missing") + ")") : r.title + " <" + r.url + ">";
|
|
29838
29629
|
const blocks = shown.map((d) => [
|
|
29839
29630
|
`== ${d.id} ${d.path}${at ? " @ " + at.slice(0, 7) : ""}`,
|
|
29840
29631
|
d.text.replace(/\n$/, ""),
|
|
29841
29632
|
...section("-- " + t2("docs.references"), d.references.map(named)),
|
|
29842
|
-
...section("-- " + t2("docs.referencedBy"), d.referencedBy.map(named))
|
|
29843
|
-
...section("-- " + t2("docs.files"), (d.files ?? []).map(fileLine))
|
|
29633
|
+
...section("-- " + t2("docs.referencedBy"), d.referencedBy.map(named))
|
|
29844
29634
|
].join("\n"));
|
|
29845
29635
|
return { json: { ...at ? { commit: at } : {}, documents: shown }, text: blocks.join("\n\n") + "\n" };
|
|
29846
29636
|
}
|
|
29847
29637
|
var pathExample = {
|
|
29848
29638
|
feature: () => t2("docs.pathExample.feature"),
|
|
29849
29639
|
requirement: () => t2("docs.pathExample.requirement"),
|
|
29850
|
-
design: () => t2("docs.pathExample.design")
|
|
29851
|
-
instruction: () => t2("docs.pathExample.instruction")
|
|
29640
|
+
design: () => t2("docs.pathExample.design")
|
|
29852
29641
|
};
|
|
29853
29642
|
var skeleton = {
|
|
29854
29643
|
feature: () => t2("docs.skeleton.feature"),
|
|
29855
29644
|
requirement: () => t2("docs.skeleton.requirement"),
|
|
29856
|
-
design: () => t2("docs.skeleton.design")
|
|
29857
|
-
instruction: () => t2("docs.skeleton.instruction")
|
|
29645
|
+
design: () => t2("docs.skeleton.design")
|
|
29858
29646
|
};
|
|
29859
29647
|
function newPath(kind2, path3) {
|
|
29860
|
-
const target = kind2 === "feature" ? `${SPEC_ROOT}/${path3}/index.md` :
|
|
29861
|
-
const shape = kind2 === "feature"
|
|
29648
|
+
const target = kind2 === "feature" ? `${SPEC_ROOT}/${path3}/index.md` : `${SPEC_ROOT}/${path3.split("/")[0]}/${kind2 === "requirement" ? "requirements" : "design"}/${path3.split("/").slice(1).join("/")}.md`;
|
|
29649
|
+
const shape = kind2 === "feature" ? /^[^/]+$/ : /^[^/]+\/[^/]+$/;
|
|
29862
29650
|
let where;
|
|
29863
29651
|
try {
|
|
29864
29652
|
where = shape.test(path3) ? classifyDocPath(target) : void 0;
|
|
@@ -29881,7 +29669,7 @@ async function createDocument(project, kind2, path3, options) {
|
|
|
29881
29669
|
const taken = new Set(documents.map((d) => d.id));
|
|
29882
29670
|
let id;
|
|
29883
29671
|
do
|
|
29884
|
-
id = generateId({ feature: "S", requirement: "R", design: "D"
|
|
29672
|
+
id = generateId({ feature: "S", requirement: "R", design: "D" }[kind2]);
|
|
29885
29673
|
while (taken.has(id));
|
|
29886
29674
|
const folder = target.slice(0, target.lastIndexOf("/") + 1);
|
|
29887
29675
|
const siblings = documents.filter((d) => (d.kind === "requirement" || d.kind === "design") && d.path.startsWith(folder) && !d.path.slice(folder.length).includes("/"));
|
|
@@ -29889,7 +29677,7 @@ async function createDocument(project, kind2, path3, options) {
|
|
|
29889
29677
|
const body2 = style2 === "usecase" ? t2("docs.skeleton.requirementUsecase") : skeleton[kind2]();
|
|
29890
29678
|
const base = { id, path: target, title: options.title.trim(), description: options.description.trim(), body: body2, draft: true };
|
|
29891
29679
|
const feature2 = target.split("/")[2];
|
|
29892
|
-
const doc = kind2 === "feature" ? { kind: kind2, feature: feature2, ...base } : kind2 === "
|
|
29680
|
+
const doc = kind2 === "feature" ? { kind: kind2, feature: feature2, ...base } : kind2 === "requirement" ? { kind: kind2, feature: feature2, order, ...styleKey, ...base } : { kind: kind2, feature: feature2, order, requirements: [], sources: [], ...base };
|
|
29893
29681
|
const rendered = renderDocumentFile(doc);
|
|
29894
29682
|
parseDocumentFile(target, rendered);
|
|
29895
29683
|
try {
|
|
@@ -29912,11 +29700,11 @@ function parseLimit(value) {
|
|
|
29912
29700
|
if (!/^[1-9]\d{0,5}$/.test(value)) throw new InvalidArgumentError(t2("list.limit"));
|
|
29913
29701
|
return Number(value);
|
|
29914
29702
|
}
|
|
29915
|
-
var parseFields = (value) => value.split(
|
|
29916
|
-
function checkFields(fields2,
|
|
29703
|
+
var parseFields = (value) => value.split(/[\s,]+/).filter(Boolean);
|
|
29704
|
+
function checkFields(fields2, columns2) {
|
|
29917
29705
|
if (!fields2) return void 0;
|
|
29918
|
-
const unknown2 = fields2.filter((f) => !
|
|
29919
|
-
if (unknown2.length || !fields2.length) throw new CommandError("INVALID_VALUE", t2("list.unknownFields", { fields: unknown2.join(", "), columns:
|
|
29706
|
+
const unknown2 = fields2.filter((f) => !columns2.includes(f));
|
|
29707
|
+
if (unknown2.length || !fields2.length) throw new CommandError("INVALID_VALUE", t2("list.unknownFields", { fields: unknown2.join(", "), columns: columns2.join(", ") }));
|
|
29920
29708
|
return [...new Set(fields2)];
|
|
29921
29709
|
}
|
|
29922
29710
|
function cell(value) {
|
|
@@ -30004,120 +29792,14 @@ var runSpecsList = (options) => runCommand("specs", options.format, async () =>
|
|
|
30004
29792
|
var runSpecsShow = (ids, options) => runCommand("specs", options.format, async () => {
|
|
30005
29793
|
const project = await openProject(process.cwd());
|
|
30006
29794
|
const at = options.ref === void 0 ? void 0 : await project.reader.resolve(options.ref);
|
|
30007
|
-
return showDocuments(project, ids, at, specKinds, "
|
|
29795
|
+
return showDocuments(project, ids, at, at === void 0 ? specKinds : [...specKinds, "instruction"]);
|
|
30008
29796
|
});
|
|
30009
29797
|
var runSpecsNew = (kind2, path3, options) => runCommand("specs", options.format, async () => createDocument(await openProject(process.cwd()), kind2, path3, options));
|
|
30010
29798
|
|
|
30011
|
-
// src/queries/instructions.ts
|
|
30012
|
-
import { lstat as lstat12 } from "node:fs/promises";
|
|
30013
|
-
import { join as join18 } from "node:path";
|
|
30014
|
-
var AGENTS = "AGENTS.md";
|
|
30015
|
-
async function listInstructions(source2, options, request) {
|
|
30016
|
-
const listed3 = await source2.cache.documents.list();
|
|
30017
|
-
const problems = listed3.problems;
|
|
30018
|
-
const states = await documentStates(source2, listed3.documents);
|
|
30019
|
-
const documents = states.documents;
|
|
30020
|
-
const agents2 = { path: AGENTS, exists: !!(await lstat12(join18(source2.root, AGENTS)).catch(() => void 0))?.isFile() };
|
|
30021
|
-
const historyNeeded = options.sort === "updated" || options.author !== void 0 || !!options.withUpdated;
|
|
30022
|
-
const latest = /* @__PURE__ */ new Map();
|
|
30023
|
-
const newest = /* @__PURE__ */ new Map();
|
|
30024
|
-
let touched;
|
|
30025
|
-
if (historyNeeded) {
|
|
30026
|
-
const head = await source2.head();
|
|
30027
|
-
const changes2 = head ? await source2.cache.history.changesOf(head) : [];
|
|
30028
|
-
changes2.forEach((c, rank) => {
|
|
30029
|
-
if (!latest.has(c.id)) {
|
|
30030
|
-
latest.set(c.id, { commit: c.commit, date: c.date, author: c.author, email: c.email });
|
|
30031
|
-
newest.set(c.id, rank);
|
|
30032
|
-
}
|
|
30033
|
-
});
|
|
30034
|
-
if (options.author !== void 0) {
|
|
30035
|
-
const by = byAuthor(options.author);
|
|
30036
|
-
touched = new Set(changes2.filter(by).map((c) => c.id));
|
|
30037
|
-
}
|
|
30038
|
-
}
|
|
30039
|
-
const matched = options.q !== void 0 ? await source2.cache.documents.matching(options.q) : void 0;
|
|
30040
|
-
const instructions2 = documents.filter((d) => d.kind === "instruction").filter((d) => (!touched || touched.has(d.id)) && (!matched || matched.has(d.id))).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
30041
|
-
const rows = await Promise.all(instructions2.map(async (d) => {
|
|
30042
|
-
const state2 = states.state(d.id);
|
|
30043
|
-
const { files, limited } = state2 === "deleted" ? { files: [], limited: false } : await readInstructionFiles(source2.root, d.path);
|
|
30044
|
-
return {
|
|
30045
|
-
id: d.id,
|
|
30046
|
-
name: d.name,
|
|
30047
|
-
path: d.path,
|
|
30048
|
-
title: d.title,
|
|
30049
|
-
description: d.description,
|
|
30050
|
-
...d.draft ? { draft: true } : {},
|
|
30051
|
-
state: state2,
|
|
30052
|
-
...states.previousPath(d.id) ? { previousPath: states.previousPath(d.id) } : {},
|
|
30053
|
-
files,
|
|
30054
|
-
...limited ? { filesLimited: true } : {},
|
|
30055
|
-
...historyNeeded ? { updated: latest.get(d.id) ?? null } : {},
|
|
30056
|
-
...matched ? { line: matched.get(d.id) } : {}
|
|
30057
|
-
};
|
|
30058
|
-
}));
|
|
30059
|
-
if (options.sort === "updated") rows.sort((a, b) => (newest.get(a.id) ?? Infinity) - (newest.get(b.id) ?? Infinity));
|
|
30060
|
-
const page = pageOf(rows, (r) => r.id, request);
|
|
30061
|
-
if (!page) return void 0;
|
|
30062
|
-
return { agents: agents2, problems, page };
|
|
30063
|
-
}
|
|
30064
|
-
|
|
30065
|
-
// src/commands/instructions.ts
|
|
30066
|
-
var instructionSorts = ["name", "updated"];
|
|
30067
|
-
var columns2 = ["id", "name", "path", "title", "description", "draft", "state", "previousPath", "files", "updated", "line"];
|
|
30068
|
-
var runInstructionsList = (options) => runCommand("instructions", options.format, async () => {
|
|
30069
|
-
const fields2 = checkFields(options.fields, columns2);
|
|
30070
|
-
const project = await openProject(process.cwd());
|
|
30071
|
-
const listed3 = await listInstructions(project, { ...options, withUpdated: !!fields2?.includes("updated") }, options) ?? cursorGone(options);
|
|
30072
|
-
const { agents: agents2, problems, page } = listed3;
|
|
30073
|
-
const shown = page.rows;
|
|
30074
|
-
const paging = { total: page.total, next: page.next, unit: "instruction" };
|
|
30075
|
-
const unreadable2 = problems.filter((p) => p.path.startsWith(INSTRUCTIONS_ROOT + "/"));
|
|
30076
|
-
if (fields2) {
|
|
30077
|
-
const picked = selected(shown, fields2);
|
|
30078
|
-
return {
|
|
30079
|
-
json: { agents: agents2, instructions: picked.json, problems: unreadable2, page: paging },
|
|
30080
|
-
text: selected(shown.map((r) => ({ ...r, files: r.files.map((f) => f.path) })), fields2).text + aside(options.format, pageLine(page))
|
|
30081
|
-
};
|
|
30082
|
-
}
|
|
30083
|
-
const out = [agents2.exists ? t2("instructions.agents") : t2("instructions.noAgents")];
|
|
30084
|
-
for (const r of shown) {
|
|
30085
|
-
const when = r.updated ? ` \xB7 ${r.updated.date.slice(0, 10)} ${r.updated.author}` : "";
|
|
30086
|
-
out.push(`${r.id} ${r.title}${draftMark(r)}${stateMark(r.state)} (${r.name}) \u2014 ${r.description}${when}`, ...r.line ? [" " + r.line] : []);
|
|
30087
|
-
out.push(...r.files.map((f) => " " + fileLine(f)), ...r.filesLimited ? [" " + t2("instructions.filesLimited", { count: r.files.length })] : []);
|
|
30088
|
-
}
|
|
30089
|
-
if (!shown.length) out.push(options.q !== void 0 || options.author !== void 0 ? t2("docs.noMatch") : t2("instructions.empty"));
|
|
30090
|
-
out.push(...pageLine(page));
|
|
30091
|
-
if (unreadable2.length) out.push(t2("docs.unreadable", { count: unreadable2.length }));
|
|
30092
|
-
return { json: { agents: agents2, instructions: shown, problems: unreadable2, page: paging }, text: text2(out) };
|
|
30093
|
-
});
|
|
30094
|
-
async function resolveInstructions(project, targets, at) {
|
|
30095
|
-
const view = at === void 0 ? await working(project) : await committed(project, at);
|
|
30096
|
-
const byName = new Map([...view.byId.values()].filter((d) => d.kind === "instruction").map((d) => [d.name, d.id]));
|
|
30097
|
-
return targets.map((target) => byName.get(target) ?? target);
|
|
30098
|
-
}
|
|
30099
|
-
var runInstructionsShow = (targets, options) => runCommand("instructions", options.format, async () => {
|
|
30100
|
-
const project = await openProject(process.cwd());
|
|
30101
|
-
if (options.file !== void 0 && (targets.length !== 1 || options.ref !== void 0)) throw new CommandError("INVALID_VALUE", t2("instructions.fileWithOne"));
|
|
30102
|
-
const at = options.ref === void 0 ? void 0 : await project.reader.resolve(options.ref);
|
|
30103
|
-
const ids = await resolveInstructions(project, targets, at);
|
|
30104
|
-
if (options.file === void 0) return showDocuments(project, ids, at, ["instruction"], "specs show");
|
|
30105
|
-
const instruction2 = (await working(project)).byId.get(ids[0]);
|
|
30106
|
-
if (instruction2?.kind !== "instruction") throw new CommandError("UNKNOWN_DOCUMENT", t2("docs.unknownDocument", { ids: targets[0] }));
|
|
30107
|
-
const found = await readInstructionFile(project.root, instruction2.path, options.file);
|
|
30108
|
-
if (!found) throw new CommandError("UNKNOWN_FILE", t2("instructions.unknownFile", { path: options.file, name: instruction2.name }));
|
|
30109
|
-
const note = found.text !== null ? [] : [found.tooLarge ? t2("instructions.fileTooLarge", { size: found.size }) : t2("instructions.fileBinary", { size: found.size })];
|
|
30110
|
-
return {
|
|
30111
|
-
json: { id: instruction2.id, name: instruction2.name, file: { path: options.file, ...found } },
|
|
30112
|
-
text: text2([`== ${instruction2.id} ${instruction2.name}/${options.file}`, ...found.text !== null ? [found.text.replace(/\n$/, "")] : note])
|
|
30113
|
-
};
|
|
30114
|
-
});
|
|
30115
|
-
var runInstructionsNew = (name2, options) => runCommand("instructions", options.format, async () => createDocument(await openProject(process.cwd()), "instruction", name2, options));
|
|
30116
|
-
|
|
30117
29799
|
// src/adapters/filesystem/document-warnings.ts
|
|
30118
|
-
import { lstat as
|
|
30119
|
-
import { join as
|
|
30120
|
-
var info2 = async (path3) =>
|
|
29800
|
+
import { lstat as lstat11, readdir as readdir5 } from "node:fs/promises";
|
|
29801
|
+
import { join as join17 } from "node:path";
|
|
29802
|
+
var info2 = async (path3) => lstat11(path3).catch((e) => {
|
|
30121
29803
|
if (e.code === "ENOENT") return void 0;
|
|
30122
29804
|
throw e;
|
|
30123
29805
|
});
|
|
@@ -30125,20 +29807,20 @@ var posix = (path3) => path3.split("\\").join("/");
|
|
|
30125
29807
|
async function listAssets(root) {
|
|
30126
29808
|
const out = [];
|
|
30127
29809
|
async function visit2(relative, depth) {
|
|
30128
|
-
const stat3 = await info2(
|
|
29810
|
+
const stat3 = await info2(join17(root, relative));
|
|
30129
29811
|
if (!stat3 || stat3.isSymbolicLink()) return;
|
|
30130
29812
|
if (stat3.isDirectory()) {
|
|
30131
29813
|
if (depth > 8 || out.length > 4e3) return;
|
|
30132
|
-
for (const name2 of (await
|
|
29814
|
+
for (const name2 of (await readdir5(join17(root, relative))).sort()) await visit2(relative + "/" + name2, depth + 1);
|
|
30133
29815
|
} else if (stat3.isFile()) out.push({ path: posix(relative), bytes: stat3.size });
|
|
30134
29816
|
}
|
|
30135
29817
|
await visit2(ASSETS_DIR, 0);
|
|
30136
29818
|
return out;
|
|
30137
29819
|
}
|
|
30138
29820
|
async function readDocumentWarnings(root, documents) {
|
|
30139
|
-
const outside = [...new Set(documentBodyLinks(documents).map((l) => l.target).filter((t3) => !t3.startsWith(".gitifact/")
|
|
29821
|
+
const outside = [...new Set(documentBodyLinks(documents).map((l) => l.target).filter((t3) => !t3.startsWith(".gitifact/")))];
|
|
30140
29822
|
const existing = /* @__PURE__ */ new Set();
|
|
30141
|
-
for (const target of outside) if ((await info2(
|
|
29823
|
+
for (const target of outside) if ((await info2(join17(root, ...target.split("/"))))?.isFile()) existing.add(target);
|
|
30142
29824
|
return documentWarnings(documents, await listAssets(root), existing);
|
|
30143
29825
|
}
|
|
30144
29826
|
|
|
@@ -30162,31 +29844,31 @@ var runCheck = (options) => runCommand("check", options.format, async () => {
|
|
|
30162
29844
|
|
|
30163
29845
|
// src/commands/changes.ts
|
|
30164
29846
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
30165
|
-
import { mkdir as
|
|
30166
|
-
import { join as
|
|
29847
|
+
import { mkdir as mkdir8, open as open4, readFile as readFile16, rename as rename4, rmdir, unlink as unlink5, writeFile as writeFile6 } from "node:fs/promises";
|
|
29848
|
+
import { join as join20 } from "node:path";
|
|
30167
29849
|
|
|
30168
29850
|
// src/adapters/filesystem/agent-inputs.ts
|
|
30169
29851
|
import { createHash as createHash4, randomBytes as randomBytes2 } from "node:crypto";
|
|
30170
|
-
import { lstat as
|
|
29852
|
+
import { lstat as lstat12, mkdir as mkdir7, readdir as readdir6, realpath as realpath3, unlink as unlink4, writeFile as writeFile5 } from "node:fs/promises";
|
|
30171
29853
|
import { tmpdir } from "node:os";
|
|
30172
|
-
import { basename, dirname as dirname2, join as
|
|
29854
|
+
import { basename, dirname as dirname2, join as join18 } from "node:path";
|
|
30173
29855
|
var maxAge = 7 * 24 * 60 * 60 * 1e3;
|
|
30174
|
-
var info3 = (path3) =>
|
|
29856
|
+
var info3 = (path3) => lstat12(path3).catch((e) => {
|
|
30175
29857
|
if (e.code === "ENOENT") return void 0;
|
|
30176
29858
|
throw e;
|
|
30177
29859
|
});
|
|
30178
29860
|
var comparable = (path3) => process.platform === "win32" ? path3.toLowerCase() : path3;
|
|
30179
29861
|
async function candidates(root, controls) {
|
|
30180
29862
|
const key = createHash4("sha256").update(comparable(await realpath3(root))).digest("hex").slice(0, 16);
|
|
30181
|
-
return { system:
|
|
29863
|
+
return { system: join18((controls.tmpdir ?? tmpdir)(), "gitifact", key), project: join18(root, ".gitifact", "tmp") };
|
|
30182
29864
|
}
|
|
30183
29865
|
async function writable(directory) {
|
|
30184
29866
|
try {
|
|
30185
|
-
await
|
|
29867
|
+
await mkdir7(directory, { recursive: true });
|
|
30186
29868
|
const stat3 = await info3(directory);
|
|
30187
29869
|
if (!stat3?.isDirectory() || stat3.isSymbolicLink()) return false;
|
|
30188
|
-
const probe =
|
|
30189
|
-
await
|
|
29870
|
+
const probe = join18(directory, ".probe-" + randomBytes2(8).toString("hex"));
|
|
29871
|
+
await writeFile5(probe, "", { flag: "wx" });
|
|
30190
29872
|
await unlink4(probe);
|
|
30191
29873
|
return true;
|
|
30192
29874
|
} catch {
|
|
@@ -30199,18 +29881,18 @@ async function prepareAgentInputs(root, controls = {}) {
|
|
|
30199
29881
|
if (await writable(system)) directory = system;
|
|
30200
29882
|
else if (await writable(project)) {
|
|
30201
29883
|
directory = project;
|
|
30202
|
-
await
|
|
29884
|
+
await writeFile5(join18(project, ".gitignore"), "*\n", { flag: "wx" }).catch((e) => {
|
|
30203
29885
|
if (e.code !== "EEXIST") throw e;
|
|
30204
29886
|
});
|
|
30205
29887
|
}
|
|
30206
29888
|
if (!directory) return void 0;
|
|
30207
29889
|
const now = (controls.now ?? Date.now)();
|
|
30208
|
-
for (const name2 of await
|
|
29890
|
+
for (const name2 of await readdir6(directory).catch(() => [])) {
|
|
30209
29891
|
if (name2 === ".gitignore") continue;
|
|
30210
|
-
const stat3 = await info3(
|
|
30211
|
-
if (stat3?.isFile() && now - stat3.mtimeMs > maxAge) await unlink4(
|
|
29892
|
+
const stat3 = await info3(join18(directory, name2)).catch(() => void 0);
|
|
29893
|
+
if (stat3?.isFile() && now - stat3.mtimeMs > maxAge) await unlink4(join18(directory, name2)).catch(() => void 0);
|
|
30212
29894
|
}
|
|
30213
|
-
return { commit:
|
|
29895
|
+
return { commit: join18(directory, "commit.json") };
|
|
30214
29896
|
}
|
|
30215
29897
|
async function discardAgentInput(root, file2, controls = {}) {
|
|
30216
29898
|
try {
|
|
@@ -30232,17 +29914,17 @@ async function discardAgentInput(root, file2, controls = {}) {
|
|
|
30232
29914
|
|
|
30233
29915
|
// src/commands/commit-files.ts
|
|
30234
29916
|
import { createHash as createHash5 } from "node:crypto";
|
|
30235
|
-
import { lstat as
|
|
30236
|
-
import { join as
|
|
29917
|
+
import { lstat as lstat13, readFile as readFile14 } from "node:fs/promises";
|
|
29918
|
+
import { join as join19 } from "node:path";
|
|
30237
29919
|
var fail3 = (message) => {
|
|
30238
29920
|
throw new CommandError("INVALID_COMMIT", message);
|
|
30239
29921
|
};
|
|
30240
29922
|
var hash2 = (value) => createHash5("sha256").update(value).digest("hex");
|
|
30241
|
-
var optional2 = (path3) =>
|
|
29923
|
+
var optional2 = (path3) => readFile14(path3).catch((e) => {
|
|
30242
29924
|
if (e.code === "ENOENT") return null;
|
|
30243
29925
|
throw e;
|
|
30244
29926
|
});
|
|
30245
|
-
var info4 = (path3) =>
|
|
29927
|
+
var info4 = (path3) => lstat13(path3).catch((e) => {
|
|
30246
29928
|
if (e.code === "ENOENT") return void 0;
|
|
30247
29929
|
throw e;
|
|
30248
29930
|
});
|
|
@@ -30254,7 +29936,7 @@ var record3 = (path3) => {
|
|
|
30254
29936
|
return false;
|
|
30255
29937
|
}
|
|
30256
29938
|
};
|
|
30257
|
-
var
|
|
29939
|
+
var instructionFile = (path3) => {
|
|
30258
29940
|
try {
|
|
30259
29941
|
return classifyDocPath(path3).type === "instruction-file";
|
|
30260
29942
|
} catch {
|
|
@@ -30268,14 +29950,14 @@ async function fingerprint(root, path3) {
|
|
|
30268
29950
|
validPath2(path3);
|
|
30269
29951
|
const parts = path3.split("/");
|
|
30270
29952
|
for (let i = 1; i <= parts.length; i++) {
|
|
30271
|
-
const target =
|
|
29953
|
+
const target = join19(root, ...parts.slice(0, i));
|
|
30272
29954
|
const stat3 = await info4(target);
|
|
30273
29955
|
if (!stat3) return null;
|
|
30274
29956
|
if (stat3.isSymbolicLink() || (i < parts.length ? !stat3.isDirectory() : !stat3.isFile())) fail3(t2("commitFiles.linkOrDirectory"));
|
|
30275
|
-
if (i < parts.length && await info4(
|
|
29957
|
+
if (i < parts.length && await info4(join19(target, ".git"))) fail3(t2("commitFiles.nestedRepository"));
|
|
30276
29958
|
if (i === parts.length) {
|
|
30277
29959
|
if (stat3.nlink !== 1 || stat3.size > 16 * 1024 * 1024) fail3(t2("commitFiles.hardLinkOrSize"));
|
|
30278
|
-
return hash2(Buffer.concat([Buffer.from(String(stat3.mode & 73) + "\0"), await
|
|
29960
|
+
return hash2(Buffer.concat([Buffer.from(String(stat3.mode & 73) + "\0"), await readFile14(target)]));
|
|
30279
29961
|
}
|
|
30280
29962
|
}
|
|
30281
29963
|
return null;
|
|
@@ -30302,16 +29984,16 @@ function policyPaths(files) {
|
|
|
30302
29984
|
}
|
|
30303
29985
|
return [...all].sort();
|
|
30304
29986
|
}
|
|
30305
|
-
var storeFiles = /* @__PURE__ */ new Set([".gitifact/config.json", LINE_ENDINGS_PATH]);
|
|
29987
|
+
var storeFiles = /* @__PURE__ */ new Set([".gitifact/config.json", LINE_ENDINGS_PATH, LAUNCHER_PATH]);
|
|
30306
29988
|
function checkStoreSelection(selected2) {
|
|
30307
29989
|
for (const p of selected2.filter((p2) => p2.startsWith(".gitifact/") && !record3(p2) && !storeFiles.has(p2))) {
|
|
30308
|
-
if (!isAssetPath(p) && !
|
|
29990
|
+
if (!isAssetPath(p) && !instructionFile(p)) fail3(t2("commitFiles.notRecord", { path: p }));
|
|
30309
29991
|
}
|
|
30310
29992
|
}
|
|
30311
29993
|
|
|
30312
29994
|
// src/commands/input.ts
|
|
30313
|
-
import { readFile as
|
|
30314
|
-
var
|
|
29995
|
+
import { readFile as readFile15, stat as stat2 } from "node:fs/promises";
|
|
29996
|
+
var LIMIT = 1024 * 1024;
|
|
30315
29997
|
async function readJsonInput(file2, stdin = process.stdin) {
|
|
30316
29998
|
const bytes = file2 === "-" ? await readStdin(stdin) : await readInputFile(file2);
|
|
30317
29999
|
try {
|
|
@@ -30322,15 +30004,15 @@ async function readJsonInput(file2, stdin = process.stdin) {
|
|
|
30322
30004
|
}
|
|
30323
30005
|
async function readInputFile(path3) {
|
|
30324
30006
|
const source2 = await stat2(path3).catch(() => void 0);
|
|
30325
|
-
if (!source2?.isFile() || source2.size >
|
|
30326
|
-
return
|
|
30007
|
+
if (!source2?.isFile() || source2.size > LIMIT) throw new CommandError("INVALID_INPUT", t2("input.file"));
|
|
30008
|
+
return readFile15(path3);
|
|
30327
30009
|
}
|
|
30328
30010
|
async function readStdin(stream) {
|
|
30329
30011
|
const chunks = [];
|
|
30330
30012
|
let size = 0;
|
|
30331
30013
|
for await (const chunk of stream) {
|
|
30332
30014
|
size += chunk.length;
|
|
30333
|
-
if (size >
|
|
30015
|
+
if (size > LIMIT) throw new CommandError("INVALID_INPUT", t2("input.size"));
|
|
30334
30016
|
chunks.push(chunk);
|
|
30335
30017
|
}
|
|
30336
30018
|
return Buffer.concat(chunks);
|
|
@@ -30404,7 +30086,7 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30404
30086
|
if (Object.keys(authorization).sort().join(",") !== "basis,evidence" || !["user-request", "project-policy"].includes(String(authorization.basis))) fail3(t2("commit.authorizationRequired"));
|
|
30405
30087
|
text3(authorization.evidence, 2e3);
|
|
30406
30088
|
const message = text3(request.message, 4e3);
|
|
30407
|
-
if (
|
|
30089
|
+
if (/^[ \t]*Gitifact-[A-Za-z0-9-]+[ \t]*:/im.test(message)) fail3(t2("commit.trailerInMessage"));
|
|
30408
30090
|
if (request.migration !== void 0 && request.migration !== true) fail3(t2("commit.migrationFlag"));
|
|
30409
30091
|
const project = await openProject(cwd, { writing: true });
|
|
30410
30092
|
const { root, gitDir, indexPath, objectFormat } = project;
|
|
@@ -30430,7 +30112,7 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30430
30112
|
...stdin ? { input: stdin } : {}
|
|
30431
30113
|
});
|
|
30432
30114
|
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();
|
|
30433
|
-
const busy =
|
|
30115
|
+
const busy = join20(gitDir, "gitifact-changes-commit.lock");
|
|
30434
30116
|
if (await info4(busy)) fail3(t2("commit.busy", { path: busy }));
|
|
30435
30117
|
if ((await staged()).length) fail3(t2("commit.existingStaging"));
|
|
30436
30118
|
const indexHash = hash2(await optional2(indexPath) ?? Buffer.alloc(0));
|
|
@@ -30470,7 +30152,7 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30470
30152
|
if (!same2(base, await project.reader.baseline())) fail3(t2("commit.headChanged"));
|
|
30471
30153
|
return { outcome: "dry-run", committed: false, ...summary, commit: void 0 };
|
|
30472
30154
|
}
|
|
30473
|
-
const temporary =
|
|
30155
|
+
const temporary = join20(gitDir, "gitifact-commit-index-" + randomUUID6());
|
|
30474
30156
|
let owned = false;
|
|
30475
30157
|
let uncertain = false;
|
|
30476
30158
|
let commitStarted = false;
|
|
@@ -30478,20 +30160,20 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30478
30160
|
let committed2;
|
|
30479
30161
|
try {
|
|
30480
30162
|
try {
|
|
30481
|
-
await
|
|
30163
|
+
await mkdir8(busy);
|
|
30482
30164
|
owned = true;
|
|
30483
30165
|
} catch (e) {
|
|
30484
30166
|
if (e.code === "EEXIST") fail3(t2("commit.busy", { path: busy }));
|
|
30485
30167
|
throw e;
|
|
30486
30168
|
}
|
|
30487
|
-
const lock = indexLock = await
|
|
30169
|
+
const lock = indexLock = await open4(indexPath + ".lock", "wx", 384);
|
|
30488
30170
|
const original = await optional2(indexPath);
|
|
30489
30171
|
if (hash2(original ?? Buffer.alloc(0)) !== indexHash || (await staged()).length) fail3(t2("commit.indexChanged"));
|
|
30490
30172
|
const before = await hashes([...started.keys()]);
|
|
30491
30173
|
for (const [path3, value] of started) if (before.get(path3) !== value) fail3(t2("commit.fileChangedRunning", { path: path3 }));
|
|
30492
|
-
await
|
|
30174
|
+
await writeFile6(join20(busy, "recovery.json"), JSON.stringify({ before: base, originalIndex: original?.toString("base64") ?? null, temporary, paths: selected2, message }));
|
|
30493
30175
|
const locked = await hashes([.../* @__PURE__ */ new Set([...selected2, ...contextPaths])]);
|
|
30494
|
-
if (original) await
|
|
30176
|
+
if (original) await writeFile6(temporary, original, { flag: "wx" });
|
|
30495
30177
|
else await git(["read-tree", "--empty"], temporary);
|
|
30496
30178
|
await git(["add", "--pathspec-from-file=-", "--pathspec-file-nul"], temporary, Buffer.from(stageable.join("\0")));
|
|
30497
30179
|
const actual = await staged(temporary);
|
|
@@ -30506,14 +30188,14 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30506
30188
|
const size = Number(header[2]);
|
|
30507
30189
|
if (end < 0 || header[1] !== "blob" || !Number.isSafeInteger(size) || output2[end + 1 + size] !== 10) fail3(t2("commit.stagedUnreadable", { path: path3 }));
|
|
30508
30190
|
const blob = output2.subarray(end + 1, end + 1 + size);
|
|
30509
|
-
const file2 = await
|
|
30191
|
+
const file2 = await readFile16(join20(root, path3));
|
|
30510
30192
|
if (!blob.equals(file2) && !blob.equals(Buffer.from(file2.toString("latin1").replace(/\r\n/g, "\n"), "latin1"))) fail3(t2("commit.filterChanged"));
|
|
30511
30193
|
offset = end + size + 2;
|
|
30512
30194
|
}
|
|
30513
30195
|
}
|
|
30514
30196
|
const again = await hashes([...locked.keys()]);
|
|
30515
30197
|
for (const [path3, value] of locked) if (again.get(path3) !== value) fail3(t2("commit.fileChangedPreparing", { path: path3 }));
|
|
30516
|
-
for (const name2 of integration) if (await info4(
|
|
30198
|
+
for (const name2 of integration) if (await info4(join20(gitDir, name2))) fail3(t2("commit.integrationStarted"));
|
|
30517
30199
|
if (!same2(base, await project.reader.baseline())) fail3(t2("commit.headChanged"));
|
|
30518
30200
|
const tree = (await git(["write-tree"], temporary)).toString("utf8").trim();
|
|
30519
30201
|
commitStarted = true;
|
|
@@ -30528,7 +30210,7 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30528
30210
|
if (headers[0] !== "tree " + tree || after.branch !== base.branch || !same2(parents, base.head ? [base.head] : []) || trailers.some((line2) => !body2.split(/\r?\n/).includes(line2))) fail3(t2("commit.resultAltered"));
|
|
30529
30211
|
if (hash2(await optional2(indexPath) ?? Buffer.alloc(0)) !== indexHash) fail3(t2("commit.indexChangedAfter"));
|
|
30530
30212
|
if ((await git(["write-tree"], temporary)).toString("utf8").trim() !== tree) fail3(t2("commit.hookChangedStaging"));
|
|
30531
|
-
await lock.writeFile(await
|
|
30213
|
+
await lock.writeFile(await readFile16(temporary));
|
|
30532
30214
|
await lock.sync();
|
|
30533
30215
|
await lock.close();
|
|
30534
30216
|
await rename4(indexPath + ".lock", indexPath);
|
|
@@ -30553,7 +30235,7 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30553
30235
|
await unlink5(temporary).catch(() => {
|
|
30554
30236
|
});
|
|
30555
30237
|
if (owned) {
|
|
30556
|
-
await unlink5(
|
|
30238
|
+
await unlink5(join20(busy, "recovery.json")).catch(() => {
|
|
30557
30239
|
});
|
|
30558
30240
|
await rmdir(busy);
|
|
30559
30241
|
}
|
|
@@ -30563,12 +30245,14 @@ async function commitChanges(cwd, input2, dryRun) {
|
|
|
30563
30245
|
}
|
|
30564
30246
|
|
|
30565
30247
|
// src/commands/records.ts
|
|
30566
|
-
import { readFile as
|
|
30567
|
-
import { join as
|
|
30248
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
30249
|
+
import { join as join21 } from "node:path";
|
|
30568
30250
|
var runRecordsNew = (options) => runCommand("records", options.format, async () => {
|
|
30569
30251
|
if (/[\r\n]/.test(options.title)) throw new CommandError("INVALID_VALUE", t2("docs.singleLine", { field: "title" }));
|
|
30570
|
-
const docs = [...new Set(options.docs.flatMap((d) => d.split(
|
|
30571
|
-
if (!docs.length
|
|
30252
|
+
const docs = [...new Set(options.docs.flatMap((d) => d.split(/[\s,]+/)).filter(Boolean))];
|
|
30253
|
+
if (!docs.length) throw new CommandError("INVALID_VALUE", t2("records.invalidDocs"));
|
|
30254
|
+
const invalid2 = docs.filter((d) => !docIdPattern.test(d));
|
|
30255
|
+
if (invalid2.length) throw new CommandError("INVALID_VALUE", t2("records.notDocIds", { ids: invalid2.join(", ") }));
|
|
30572
30256
|
const project = await openProject(process.cwd());
|
|
30573
30257
|
let id;
|
|
30574
30258
|
do
|
|
@@ -30600,7 +30284,7 @@ var runRecordsShow = (ids, options) => runCommand("records", options.format, asy
|
|
|
30600
30284
|
const shown = await Promise.all([...new Set(ids)].map(async (id) => {
|
|
30601
30285
|
const path3 = await findRecord(project.root, id);
|
|
30602
30286
|
if (!path3) return { id, missing: true };
|
|
30603
|
-
const source2 = await
|
|
30287
|
+
const source2 = await readFile17(join21(project.root, ...path3.split("/")), "utf8");
|
|
30604
30288
|
const log = project.reader.decode(await project.reader.run(["log", "-1", "--diff-filter=A", "--format=%H%x00%aN%x00%aI", "--", path3])).trim();
|
|
30605
30289
|
const [commit, author, date5] = log.split("\0");
|
|
30606
30290
|
return { id, path: path3, text: source2, commit: commit ? { commit, author, date: date5 } : null };
|
|
@@ -30764,11 +30448,11 @@ function newIssueUrl(title, body2, marker2) {
|
|
|
30764
30448
|
}
|
|
30765
30449
|
|
|
30766
30450
|
// src/shared/project-config.ts
|
|
30767
|
-
import { readFile as
|
|
30768
|
-
import { dirname as dirname3, join as
|
|
30451
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
30452
|
+
import { dirname as dirname3, join as join22 } from "node:path";
|
|
30769
30453
|
async function findProjectConfig(from) {
|
|
30770
30454
|
for (let folder = from; ; folder = dirname3(folder)) {
|
|
30771
|
-
const text4 = await
|
|
30455
|
+
const text4 = await readFile18(join22(folder, ".gitifact", "config.json"), "utf8").catch(() => void 0);
|
|
30772
30456
|
if (text4 !== void 0) return { root: folder, text: text4 };
|
|
30773
30457
|
if (dirname3(folder) === folder) return void 0;
|
|
30774
30458
|
}
|
|
@@ -30830,8 +30514,8 @@ var runFeedback = (options, version2, run) => runCommand("feedback", options.for
|
|
|
30830
30514
|
});
|
|
30831
30515
|
|
|
30832
30516
|
// src/commands/update.ts
|
|
30833
|
-
import { readFile as
|
|
30834
|
-
import { join as
|
|
30517
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
30518
|
+
import { join as join23 } from "node:path";
|
|
30835
30519
|
import { isDeepStrictEqual } from "node:util";
|
|
30836
30520
|
|
|
30837
30521
|
// src/adapters/git/agent-docs-commit.ts
|
|
@@ -30855,6 +30539,10 @@ function agentDocsGit(root, inherited = process.env) {
|
|
|
30855
30539
|
async commitOnly(paths2, message) {
|
|
30856
30540
|
await git(["commit", "--only", "-m", message, "--", ...paths2]);
|
|
30857
30541
|
},
|
|
30542
|
+
// A file Git does not know yet (the launcher on its first update) is marked so `--only` can take it.
|
|
30543
|
+
async intendToAdd(paths2) {
|
|
30544
|
+
await git(["add", "--intent-to-add", "--", ...paths2]);
|
|
30545
|
+
},
|
|
30858
30546
|
async changedPaths(commit) {
|
|
30859
30547
|
return (await git(["diff-tree", "--no-commit-id", "--name-only", "--no-renames", "-r", "-z", "--root", commit])).toString("utf8").split("\0").filter(Boolean).sort();
|
|
30860
30548
|
},
|
|
@@ -30868,7 +30556,7 @@ function agentDocsGit(root, inherited = process.env) {
|
|
|
30868
30556
|
var CONFIG_PATH = ".gitifact/config.json";
|
|
30869
30557
|
var updateCommitMessage = (version2) => "chore(gitifact): update project to gitifact v" + version2;
|
|
30870
30558
|
var commitState = (state2, extra = {}) => ({ state: state2, commit: null, paths: [], message: null, reason: null, detail: null, ...extra });
|
|
30871
|
-
var notInitialized = { docs: { state: "not-initialized", paths: []
|
|
30559
|
+
var notInitialized = { docs: { state: "not-initialized", paths: [] }, project: { state: "not-initialized", cli: null } };
|
|
30872
30560
|
async function refreshProject(cwd, version2, env, controls) {
|
|
30873
30561
|
const repo = initRepository(cwd, env);
|
|
30874
30562
|
let first;
|
|
@@ -30884,13 +30572,12 @@ async function refreshProject(cwd, version2, env, controls) {
|
|
|
30884
30572
|
const root = first.state.repository.rootPath;
|
|
30885
30573
|
const parsed2 = needsMigration(config2) ? void 0 : parseManagedConfig(config2);
|
|
30886
30574
|
const plan = await planAgentDocs(root, { version: version2, onlyExisting: true, language: parsed2?.language, ...controls });
|
|
30887
|
-
|
|
30888
|
-
if (parsed2?.cli && isNewerRelease(parsed2.cli, version2)) return { docs: { state: "kept", paths: plan.paths, missing: missing2, root }, project: { state: "current", cli: parsed2.cli } };
|
|
30575
|
+
if (parsed2?.cli && isNewerRelease(parsed2.cli, version2)) return { docs: { state: "kept", paths: plan.paths, root }, project: { state: "current", cli: parsed2.cli } };
|
|
30889
30576
|
let current2 = config2;
|
|
30890
30577
|
const unchanged = async () => {
|
|
30891
30578
|
if ((await repo.inspect()).stamp !== first.stamp || await readConfigFile(root) !== current2) throw new InitError("INPUT_CHANGED", t2("init.inputChanged"));
|
|
30892
30579
|
};
|
|
30893
|
-
const docs = plan.paths.length === 0 ? { state: "no-block", paths: [],
|
|
30580
|
+
const docs = plan.paths.length === 0 ? { state: "no-block", paths: [], root } : plan.writes.length === 0 ? { state: "current", paths: plan.paths, root, candidates: plan.paths } : { state: "refreshed", paths: await applyAgentDocs(root, plan, unchanged), root, candidates: plan.paths };
|
|
30894
30581
|
if (!parsed2) return { docs, project: { state: "current", cli: null } };
|
|
30895
30582
|
const settled2 = settleConfig(parsed2, version2, plan.language);
|
|
30896
30583
|
if (settled2.changed) {
|
|
@@ -30898,6 +30585,7 @@ async function refreshProject(cwd, version2, env, controls) {
|
|
|
30898
30585
|
await publishConfig(root, next, unchanged, void 0, true);
|
|
30899
30586
|
current2 = next;
|
|
30900
30587
|
}
|
|
30588
|
+
await refreshLauncher(root);
|
|
30901
30589
|
return { docs: { ...docs, root }, project: { state: settled2.changed ? "written" : "current", cli: settled2.config.cli ?? null } };
|
|
30902
30590
|
}
|
|
30903
30591
|
function outsideBlock(text4) {
|
|
@@ -30932,7 +30620,7 @@ async function commitUpdate(docs, version2, env) {
|
|
|
30932
30620
|
if (before === null || before !== outsideBlock(working2)) return commitState("skipped", { paths: [path3], reason: "other-changes" });
|
|
30933
30621
|
changed.push(path3);
|
|
30934
30622
|
}
|
|
30935
|
-
const workingConfig = await
|
|
30623
|
+
const workingConfig = await readFile19(join23(docs.root, CONFIG_PATH), "utf8").catch(() => null);
|
|
30936
30624
|
const committedConfig = head ? await git.committed(head, CONFIG_PATH) : null;
|
|
30937
30625
|
if (workingConfig !== null && committedConfig?.replace(/\r\n/g, "\n") !== workingConfig.replace(/\r\n/g, "\n")) {
|
|
30938
30626
|
if (committedConfig === null) return commitState("skipped", { paths: [CONFIG_PATH], reason: "untracked" });
|
|
@@ -30940,10 +30628,14 @@ async function commitUpdate(docs, version2, env) {
|
|
|
30940
30628
|
if (before === null || !isDeepStrictEqual(before, withoutSettings(workingConfig))) return commitState("skipped", { paths: [CONFIG_PATH], reason: "other-changes" });
|
|
30941
30629
|
changed.push(CONFIG_PATH);
|
|
30942
30630
|
}
|
|
30631
|
+
const workingLauncher = await readFile19(join23(docs.root, ...LAUNCHER_PATH.split("/")), "utf8").catch(() => null);
|
|
30632
|
+
const committedLauncher = head ? await git.committed(head, LAUNCHER_PATH) : null;
|
|
30633
|
+
if (workingLauncher !== null && committedLauncher?.replace(/\r\n/g, "\n") !== workingLauncher.replace(/\r\n/g, "\n")) changed.push(LAUNCHER_PATH);
|
|
30943
30634
|
if (changed.length === 0) return commitState("nothing");
|
|
30944
30635
|
const message = updateCommitMessage(version2);
|
|
30945
30636
|
let failure2;
|
|
30946
30637
|
try {
|
|
30638
|
+
if (workingLauncher !== null && committedLauncher === null) await git.intendToAdd([LAUNCHER_PATH]);
|
|
30947
30639
|
await git.commitOnly(changed, message);
|
|
30948
30640
|
} catch (error62) {
|
|
30949
30641
|
failure2 = error62;
|
|
@@ -30970,7 +30662,8 @@ async function updateCommand(cwd, version2, env = process.env, controls = {}) {
|
|
|
30970
30662
|
cliVersion: version2,
|
|
30971
30663
|
update,
|
|
30972
30664
|
install: update.status === "available" ? { npmGlobal: npmGlobalInstall(update.latestVersion) } : null,
|
|
30973
|
-
|
|
30665
|
+
// missing stays in the v6 result but is always empty since 0.9.0: init no longer adds a CLAUDE.md.
|
|
30666
|
+
agentDocs: { state: docs.state, paths: docs.paths, missing: [] },
|
|
30974
30667
|
project,
|
|
30975
30668
|
commit,
|
|
30976
30669
|
migrationRequired: config2 !== void 0 && needsMigration(config2)
|
|
@@ -30986,11 +30679,10 @@ async function runUpdate(options, version2) {
|
|
|
30986
30679
|
}
|
|
30987
30680
|
const lines2 = [t2("update.text.current", { version: dto.cliVersion })];
|
|
30988
30681
|
lines2.push(dto.update.status === "available" ? t2("update.text.available", { version: dto.update.latestVersion }) : dto.update.status === "up-to-date" ? t2("update.text.upToDate") : dto.update.status === "disabled" ? t2("update.text.disabled") : t2("update.text.unavailable"));
|
|
30989
|
-
if (dto.install) lines2.push(t2("update.text.install", { command: dto.
|
|
30682
|
+
if (dto.install) lines2.push(t2("update.text.install", { command: npxUpdate(dto.update.latestVersion) }), t2("update.text.afterInstall"));
|
|
30990
30683
|
lines2.push(dto.agentDocs.state === "refreshed" ? t2("update.text.blockRefreshed", { paths: dto.agentDocs.paths.join(", ") }) : dto.agentDocs.state === "current" ? t2("update.text.blockCurrent", { paths: dto.agentDocs.paths.join(", ") }) : dto.agentDocs.state === "kept" ? t2("update.text.blockKept", { paths: dto.agentDocs.paths.join(", ") || "-" }) : dto.agentDocs.state === "no-block" ? t2("update.text.noBlock") : t2("update.text.notInitialized"));
|
|
30991
|
-
if (dto.agentDocs.missing.length) lines2.push(t2("update.text.missing", { paths: dto.agentDocs.missing.join(", ") }));
|
|
30992
30684
|
if (dto.project.state === "written") lines2.push(t2("update.text.projectWritten", { path: CONFIG_PATH, version: dto.project.cli ?? dto.cliVersion }));
|
|
30993
|
-
if (dto.project.cli && isNewerRelease(dto.project.cli, dto.cliVersion)) lines2.push(t2("update.text.projectAhead", { project: dto.project.cli, version: dto.cliVersion
|
|
30685
|
+
if (dto.project.cli && isNewerRelease(dto.project.cli, dto.cliVersion)) lines2.push(t2("update.text.projectAhead", { project: dto.project.cli, version: dto.cliVersion }));
|
|
30994
30686
|
if (dto.migrationRequired) lines2.push(t2("update.text.migrationRequired", { version: dto.cliVersion }));
|
|
30995
30687
|
const { commit } = dto;
|
|
30996
30688
|
if (commit.state === "committed") lines2.push(t2("update.text.committed", { commit: commit.commit.slice(0, 12), paths: commit.paths.join(", ") }));
|
|
@@ -31033,7 +30725,7 @@ async function runUpdateCheck(format2, version2) {
|
|
|
31033
30725
|
t2("update.text.current", { version: dto.cliVersion }),
|
|
31034
30726
|
state2.status === "available" ? t2("update.text.available", { version: state2.latestVersion }) : state2.status === "up-to-date" ? t2("update.text.upToDate") : state2.status === "disabled" ? t2("update.text.disabled") : t2("update.text.unavailable")
|
|
31035
30727
|
];
|
|
31036
|
-
if (state2.status === "available") lines2.push(t2("update.text.install", { command:
|
|
30728
|
+
if (state2.status === "available") lines2.push(t2("update.text.install", { command: npxUpdate(state2.latestVersion) }), t2("update.text.afterInstall"));
|
|
31037
30729
|
process.stdout.write(lines2.join("\n") + "\n");
|
|
31038
30730
|
}
|
|
31039
30731
|
|
|
@@ -31054,8 +30746,8 @@ function chooseNotice(running2, project, cache, now, scope = { release: true, pr
|
|
|
31054
30746
|
return null;
|
|
31055
30747
|
}
|
|
31056
30748
|
function noticeText(notice, running2) {
|
|
31057
|
-
if (notice.kind === "project-newer") return t2("notice.projectNewer", { project: notice.project, version: running2
|
|
31058
|
-
if (notice.kind === "release") return t2("notice.release", { latest: notice.latest, version: running2, command:
|
|
30749
|
+
if (notice.kind === "project-newer") return t2("notice.projectNewer", { project: notice.project, version: running2 });
|
|
30750
|
+
if (notice.kind === "release") return t2("notice.release", { latest: notice.latest, version: running2, command: npxUpdate(notice.latest) });
|
|
31059
30751
|
return t2("notice.projectOlder", { project: notice.project, version: running2 });
|
|
31060
30752
|
}
|
|
31061
30753
|
var needsRefresh = (cache, now) => !(cache.checkedAt && now - Date.parse(cache.checkedAt) < REFRESH_AFTER_MS) && !(cache.checkingSince && now - Date.parse(cache.checkingSince) < CHECKING_WINDOW_MS);
|
|
@@ -31109,17 +30801,17 @@ for (let i = 0; i < languageArgs.length; i++) {
|
|
|
31109
30801
|
if (value === "ko" || value === "en") selectedLanguage = value;
|
|
31110
30802
|
}
|
|
31111
30803
|
configureLanguage(selectedLanguage ?? environmentLanguage(), selectedLanguage);
|
|
31112
|
-
var program2 = new Command().name("gitifact").addOption(new Option("--lang <language>", t2("help.lang")).choices(["ko", "en"])).description(t2("help.program")).version("0.
|
|
30804
|
+
var program2 = new Command().name("gitifact").addOption(new Option("--lang <language>", t2("help.lang")).choices(["ko", "en"])).description(t2("help.program")).version("0.9.0").allowExcessArguments(false).addHelpText("after", "\n" + t2("help.notYet")).action(() => program2.outputHelp());
|
|
31113
30805
|
program2.hook("preAction", async (_program, action) => {
|
|
31114
30806
|
let top = action;
|
|
31115
30807
|
while (top.parent && top.parent !== program2) top = top.parent;
|
|
31116
|
-
if (top.name() !== REFRESH_COMMAND) await noticeVersion("0.
|
|
30808
|
+
if (top.name() !== REFRESH_COMMAND) await noticeVersion("0.9.0", top.name());
|
|
31117
30809
|
});
|
|
31118
|
-
program2.command(REFRESH_COMMAND, { hidden: true }).allowExcessArguments(false).action(() => refreshUpdateCache("0.
|
|
30810
|
+
program2.command(REFRESH_COMMAND, { hidden: true }).allowExcessArguments(false).action(() => refreshUpdateCache("0.9.0"));
|
|
31119
30811
|
var format = () => new Option("--format <format>", t2("help.format")).choices(formats).default("text");
|
|
31120
|
-
program2.command("browser").description(t2("help.browser")).allowExcessArguments(false).option("--port <port>", t2("help.browserPort"), parsePort, 0).option("--dev", t2("help.browserDev")).action((options) => runBrowser(options, "0.
|
|
31121
|
-
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.
|
|
31122
|
-
program2.command("update").description(t2("help.update")).allowExcessArguments(false).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).option("--commit", t2("help.updateCommit")).addOption(new Option("--check", t2("help.updateCheck")).conflicts("commit")).addOption(new Option("--later", t2("help.updateLater")).conflicts(["check", "commit"])).action((options) => options.later ? runUpdateLater(options.format, "0.
|
|
30812
|
+
program2.command("browser").description(t2("help.browser")).allowExcessArguments(false).option("--port <port>", t2("help.browserPort"), parsePort, 0).option("--dev", t2("help.browserDev")).action((options) => runBrowser(options, "0.9.0"));
|
|
30813
|
+
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.9.0"));
|
|
30814
|
+
program2.command("update").description(t2("help.update")).allowExcessArguments(false).addOption(new Option("--format <format>", t2("help.format")).choices(["json", "text"]).default("json")).option("--commit", t2("help.updateCommit")).addOption(new Option("--check", t2("help.updateCheck")).conflicts("commit")).addOption(new Option("--later", t2("help.updateLater")).conflicts(["check", "commit"])).action((options) => options.later ? runUpdateLater(options.format, "0.9.0") : options.check ? runUpdateCheck(options.format, "0.9.0") : runUpdate(options, "0.9.0"));
|
|
31123
30815
|
var listed2 = (command, sorts) => {
|
|
31124
30816
|
command.allowExcessArguments(false).option("--q <words>", t2("help.listQ")).option("--author <name>", t2("help.listAuthor"));
|
|
31125
30817
|
if (sorts) command.addOption(new Option("--sort <key>", t2("help.listSort")).choices([...sorts]).default(sorts[0]));
|
|
@@ -31129,10 +30821,6 @@ var specs = program2.command("specs").description(t2("help.specs"));
|
|
|
31129
30821
|
listed2(specs.command("list").description(t2("help.specsList")).addOption(new Option("--type <kind>", t2("help.specsListType")).choices([...specKinds])).option("--feature <folder>", t2("help.specsListFeature")).option("--without-design", t2("help.specsListWithoutDesign")).option("--uncovered", t2("help.specsListUncovered")).option("--draft", t2("help.specsListDraft")).option("--changed-since <date|commit>", t2("help.specsListChangedSince")), specSorts).action((o) => runSpecsList(o));
|
|
31130
30822
|
specs.command("show").description(t2("help.specsShow")).argument("<ids...>", t2("help.specsShowIds")).option("--ref <commit>", t2("help.showRef")).addOption(format()).action((ids, o) => runSpecsShow(ids, o));
|
|
31131
30823
|
specs.command("new").description(t2("help.specsNew")).allowExcessArguments(false).addArgument(new Argument("<kind>", t2("help.specsNewKind")).choices(specKinds)).argument("<path>", t2("help.specsNewPath")).requiredOption("--title <title>", t2("help.newTitle")).requiredOption("--description <text>", t2("help.newDescription")).addOption(new Option("--style <style>", t2("help.specsNewStyle")).choices(specStyles)).addOption(format()).action((kind2, path3, o) => runSpecsNew(kind2, path3, o));
|
|
31132
|
-
var instructions = program2.command("instructions").description(t2("help.instructions"));
|
|
31133
|
-
listed2(instructions.command("list").description(t2("help.instructionsList")), instructionSorts).action((o) => runInstructionsList(o));
|
|
31134
|
-
instructions.command("show").description(t2("help.instructionsShow")).argument("<targets...>", t2("help.instructionsShowTargets")).option("--ref <commit>", t2("help.showRef")).option("--file <path>", t2("help.instructionsShowFile")).addOption(format()).action((targets, o) => runInstructionsShow(targets, o));
|
|
31135
|
-
instructions.command("new").description(t2("help.instructionsNew")).allowExcessArguments(false).argument("<name>", t2("help.instructionsNewName")).requiredOption("--title <title>", t2("help.newTitle")).requiredOption("--description <text>", t2("help.newDescription")).addOption(format()).action((name2, o) => runInstructionsNew(name2, o));
|
|
31136
30824
|
var records = program2.command("records").description(t2("help.records"));
|
|
31137
30825
|
listed2(records.command("list").description(t2("help.recordsList")).option("--doc <id>", t2("help.recordsListDoc")).option("--since <date|commit>", t2("help.recordsListSince"))).action((o) => runRecordsList(o));
|
|
31138
30826
|
records.command("show").description(t2("help.recordsShow")).argument("<ids...>", t2("help.recordsShowId")).addOption(format()).action((ids, o) => runRecordsShow(ids, o));
|
|
@@ -31141,7 +30829,7 @@ program2.command("check").description(t2("help.check")).allowExcessArguments(fal
|
|
|
31141
30829
|
var changes = program2.command("changes").description(t2("help.changes"));
|
|
31142
30830
|
changes.command("list").description(t2("help.changesList")).allowExcessArguments(false).addOption(format()).action((o) => runChangesList(o));
|
|
31143
30831
|
changes.command("commit").description(t2("help.changesCommit")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.changesCommitFile")).option("--dry-run", t2("help.changesCommitDryRun")).addOption(format()).action((o) => runChangesCommit(o));
|
|
31144
|
-
program2.command("feedback").description(t2("help.feedback")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.feedbackFile")).option("--dry-run", t2("help.feedbackDryRun")).addOption(format()).action((o) => runFeedback(o, "0.
|
|
30832
|
+
program2.command("feedback").description(t2("help.feedback")).allowExcessArguments(false).requiredOption("--file <path>", t2("help.feedbackFile")).option("--dry-run", t2("help.feedbackDryRun")).addOption(format()).action((o) => runFeedback(o, "0.9.0"));
|
|
31145
30833
|
var guide = program2.command("guide").description(t2("help.guide"));
|
|
31146
30834
|
guide.command("list").description(t2("help.guideList")).allowExcessArguments(false).addOption(format()).action((o) => runGuideList(o));
|
|
31147
30835
|
guide.command("show").description(t2("help.guideShow")).argument("<topic>", t2("help.guideTopic")).allowExcessArguments(false).addOption(format()).action((topic, o) => runGuideShow(topic, o));
|