crumbs-spec 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.ko.md +139 -101
  2. package/README.md +159 -121
  3. package/dist/src/check.js +7 -5
  4. package/dist/src/check.js.map +1 -1
  5. package/dist/src/cli.js +2 -0
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/config.js +16 -1
  8. package/dist/src/config.js.map +1 -1
  9. package/dist/src/dates.js +7 -0
  10. package/dist/src/dates.js.map +1 -1
  11. package/dist/src/graph.js +81 -14
  12. package/dist/src/graph.js.map +1 -1
  13. package/dist/src/init.js +24 -8
  14. package/dist/src/init.js.map +1 -1
  15. package/dist/src/markdown.js +155 -25
  16. package/dist/src/markdown.js.map +1 -1
  17. package/dist/src/messages.js +40 -15
  18. package/dist/src/messages.js.map +1 -1
  19. package/dist/src/model.js +2 -3
  20. package/dist/src/model.js.map +1 -1
  21. package/dist/src/report.js +1 -1
  22. package/dist/src/report.js.map +1 -1
  23. package/dist/src/rules/broken-link.js +4 -1
  24. package/dist/src/rules/broken-link.js.map +1 -1
  25. package/dist/src/rules/duplicate-policy.js +11 -2
  26. package/dist/src/rules/duplicate-policy.js.map +1 -1
  27. package/dist/src/rules/log-body.js +3 -3
  28. package/dist/src/rules/log-body.js.map +1 -1
  29. package/dist/src/rules/log-format.js +6 -0
  30. package/dist/src/rules/log-format.js.map +1 -1
  31. package/dist/src/rules/missing-backlink.js +4 -1
  32. package/dist/src/rules/missing-backlink.js.map +1 -1
  33. package/dist/src/rules/missing-section.js +14 -2
  34. package/dist/src/rules/missing-section.js.map +1 -1
  35. package/dist/src/rules/unreachable.js +1 -1
  36. package/dist/src/rules/unreachable.js.map +1 -1
  37. package/dist/src/rules/unterminated-comment.js +13 -0
  38. package/dist/src/rules/unterminated-comment.js.map +1 -0
  39. package/dist/src/skills.js +12 -1
  40. package/dist/src/skills.js.map +1 -1
  41. package/dist/src/templates/agents.js +2 -2
  42. package/dist/src/templates/agents.js.map +1 -1
  43. package/dist/src/templates/en.js +5 -5
  44. package/dist/src/templates/en.js.map +1 -1
  45. package/dist/src/templates/ko.js +1 -1
  46. package/dist/src/templates/ko.js.map +1 -1
  47. package/dist/src/templates/skills-en.js +16 -15
  48. package/dist/src/templates/skills-en.js.map +1 -1
  49. package/dist/src/templates/skills-ko.js +10 -9
  50. package/dist/src/templates/skills-ko.js.map +1 -1
  51. package/dist/src/version.js +7 -0
  52. package/dist/src/version.js.map +1 -0
  53. package/package.json +3 -2
@@ -4,22 +4,26 @@ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})/;
4
4
  const FENCE_CLOSE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/;
5
5
  const ATX = /^ {0,3}(#{1,6})[ \t]+(.*?)(?:[ \t]+#+)?[ \t]*$/;
6
6
  const CODE_SPAN = /`([^`\n]+)`/g;
7
- const LINK = /(?<!!)\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
8
7
  const SCHEME = /^[a-z][a-z0-9+.-]*:/i;
9
- // 표 구분선(| --- | --- |)과 불릿 줄. 흐름 신호(7.3)를 셀 때만 쓴다.
8
+ // 참조 정의 줄: [라벨]: 대상 "제목". 줄 전체가 정의일 때만 맞는다.
9
+ const REF_DEF = /^ {0,3}\[([^\]]+)\]:[ \t]*(<[^>\n]*>|\S+)(?:[ \t]+"[^"]*")?[ \t]*$/;
10
+ // 표 구분선(| --- | --- |), 불릿 줄, 번호 목록 줄. 흐름 신호(7.3)를 셀 때만 쓴다.
10
11
  const TABLE_RULE = /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/;
11
12
  const BULLET = /^\s*[-*+]\s+/;
13
+ const ORDERED = /^\s*\d+[.)]\s+/;
14
+ // 근거 경로 뒤의 줄 범위 접미사: :N, :N-M, :N:C, :12-48,60-70
15
+ const LINE_RANGE = /(?::\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*)+$/;
12
16
  // 비교용 정규화: NFC, 앞뒤 공백 제거, 내부 공백 압축, 소문자화.
13
17
  export function normTitle(text) {
14
18
  return text.normalize('NFC').trim().replace(/\s+/g, ' ').toLowerCase();
15
19
  }
16
- // GitHub 방식 슬러그. 유니코드 문자·숫자·결합 기호·_·-만 남긴다.
20
+ // GitHub(github-slugger) 방식 슬러그. 소문자화 후 문자·숫자·결합 기호·공백·_·-만 남기고, 공백 하나마다 -를 붙인다(압축하지 않는다).
17
21
  export function slugify(text) {
18
22
  return text
19
23
  .trim()
20
24
  .toLowerCase()
21
- .replace(/[^\p{L}\p{N}\p{M}\s_-]/gu, '')
22
- .replace(/\s+/g, '-');
25
+ .replace(/[^\p{L}\p{N}\p{M} _-]/gu, '')
26
+ .replace(/ /g, '-');
23
27
  }
24
28
  function uniqueSlug(base, used) {
25
29
  if (!used.has(base)) {
@@ -33,18 +37,103 @@ function uniqueSlug(base, used) {
33
37
  used.add(slug);
34
38
  return slug;
35
39
  }
36
- // 제목 텍스트에서 인라인 표기를 걷어 낸다: 코드 스팬, 링크, 강조 기호.
40
+ // 제목 텍스트에서 인라인 표기를 걷어 낸다: 코드 스팬, 링크, 강조 기호. _는 짝을 이룬 강조일 때만 지운다.
37
41
  function cleanInline(text) {
38
42
  return text
39
43
  .replace(/`([^`\n]+)`/g, '$1')
40
44
  .replace(/\[([^\]]*)\]\([^)\s]*(?:\s+"[^"]*")?\)/g, '$1')
41
45
  .replace(/\*+/g, '')
42
- .replace(/(?<![\p{L}\p{N}])_+|_+(?![\p{L}\p{N}])/gu, '')
46
+ .replace(/(?<![\p{L}\p{N}_])(_{1,2})([^_\n]+?)\1(?![\p{L}\p{N}_])/gu, '$2')
43
47
  .trim();
44
48
  }
45
49
  function stripAngles(target) {
46
50
  return target.startsWith('<') && target.endsWith('>') ? target.slice(1, -1) : target;
47
51
  }
52
+ // 참조 라벨 비교용 정규화: 앞뒤 공백 제거, 내부 공백 압축, 소문자화.
53
+ function normLabel(label) {
54
+ return label.trim().replace(/\s+/g, ' ').toLowerCase();
55
+ }
56
+ // s[start]부터 인라인 링크의 대상과 선택적 제목을 읽는다. 대상은 <…>(공백 허용) 또는 괄호가 균형 잡힌 맨 대상이다.
57
+ // 닫는 ')'의 위치를 돌려주고, 형식이 맞지 않으면 undefined를 준다.
58
+ function readInlineDest(s, start) {
59
+ let p = start;
60
+ while (s[p] === ' ' || s[p] === '\t')
61
+ p++;
62
+ let target;
63
+ if (s[p] === '<') {
64
+ const angle = /^<([^>\n]*)>/.exec(s.slice(p));
65
+ if (!angle)
66
+ return undefined;
67
+ target = angle[1];
68
+ p += angle[0].length;
69
+ }
70
+ else {
71
+ // 맨 대상은 공백이나 짝 없는 ')'에서 멈춘다.
72
+ const begin = p;
73
+ let depth = 0;
74
+ while (p < s.length) {
75
+ const c = s[p];
76
+ if (c === ' ' || c === '\t')
77
+ break;
78
+ if (c === '(')
79
+ depth++;
80
+ else if (c === ')') {
81
+ if (depth === 0)
82
+ break;
83
+ depth--;
84
+ }
85
+ p++;
86
+ }
87
+ target = s.slice(begin, p);
88
+ }
89
+ while (s[p] === ' ' || s[p] === '\t')
90
+ p++;
91
+ // 제목은 "…", '…', (…) 중 하나다.
92
+ if (s[p] === '"' || s[p] === "'" || s[p] === '(') {
93
+ const close = s.indexOf(s[p] === '(' ? ')' : s[p], p + 1);
94
+ if (close < 0)
95
+ return undefined;
96
+ p = close + 1;
97
+ while (s[p] === ' ' || s[p] === '\t')
98
+ p++;
99
+ }
100
+ if (s[p] !== ')')
101
+ return undefined;
102
+ return { target, end: p };
103
+ }
104
+ // 가려진(코드 스팬 제외) 한 줄에서 링크 사용을 찾는다. 이미지(![)와 빈 인라인 대상은 건너뛴다.
105
+ // 참조 사용은 [text][label]과 [label][]만 받는다. 단독 [label]은 링크가 아니다.
106
+ function extractLinkUses(masked) {
107
+ const out = [];
108
+ for (let i = 0; i < masked.length; i++) {
109
+ if (masked[i] !== '[')
110
+ continue;
111
+ const close = masked.indexOf(']', i + 1);
112
+ if (close < 0)
113
+ break;
114
+ const text = masked.slice(i + 1, close);
115
+ if (text.includes('['))
116
+ continue;
117
+ const image = i > 0 && masked[i - 1] === '!';
118
+ if (masked[close + 1] === '(') {
119
+ const dest = readInlineDest(masked, close + 2);
120
+ if (dest === undefined)
121
+ continue;
122
+ if (!image && dest.target !== '')
123
+ out.push({ kind: 'inline', text, rawTarget: dest.target });
124
+ i = dest.end;
125
+ }
126
+ else if (masked[close + 1] === '[') {
127
+ const end = masked.indexOf(']', close + 2);
128
+ if (end < 0)
129
+ continue;
130
+ if (!image)
131
+ out.push({ kind: 'ref', text, label: masked.slice(close + 2, end) || text });
132
+ i = end;
133
+ }
134
+ }
135
+ return out;
136
+ }
48
137
  function safeDecode(text) {
49
138
  try {
50
139
  return decodeURIComponent(text);
@@ -61,12 +150,16 @@ export function scanMarkdown(input) {
61
150
  const links = [];
62
151
  const codeSpans = [];
63
152
  const markerLines = [];
64
- let mermaidFences = 0;
65
- let tableRows = 0;
153
+ const mermaidFenceLines = [];
154
+ const tableRuleLines = [];
66
155
  const bulletLines = [];
156
+ // 참조 정의는 파일 어디에 있어도 쓸 수 있으므로 모든 줄을 읽은 뒤 사용처와 맞춘다.
157
+ const refDefs = new Map();
158
+ const refUses = [];
67
159
  const usedSlugs = new Set();
68
160
  let fence;
69
161
  let inComment = false;
162
+ let commentStart;
70
163
  for (let index = 0; index < lines.length; index++) {
71
164
  const raw = lines[index];
72
165
  const line = index + 1;
@@ -83,30 +176,35 @@ export function scanMarkdown(input) {
83
176
  fence = { ch: open[1][0], len: open[1].length };
84
177
  // 정보 문자열은 펜스 문자 뒤의 텍스트를 trim하고 소문자로 바꾼 값이다.
85
178
  if (raw.slice(open[0].length).trim().toLowerCase().startsWith('mermaid'))
86
- mermaidFences++;
179
+ mermaidFenceLines.push(line);
87
180
  continue;
88
181
  }
89
182
  }
90
183
  // 주석 밖 텍스트만 남긴다. 주석은 여러 줄에 걸칠 수 있다.
184
+ // 주석 시작(<!--)은 코드 스팬을 가린 줄에서 찾아, `<!--` 같은 코드 스팬이 주석을 열지 못하게 한다.
185
+ // 가려도 길이가 같으므로 위치는 원문과 그대로 맞는다. 주석 끝(-->)은 주석 안이므로 원문에서 찾는다.
186
+ const commentView = raw.replace(CODE_SPAN, (match) => ' '.repeat(match.length));
91
187
  let visible = '';
92
- let rest = raw;
188
+ let cursor = 0;
93
189
  for (;;) {
94
190
  if (inComment) {
95
- const end = rest.indexOf('-->');
191
+ const end = raw.indexOf('-->', cursor);
96
192
  if (end < 0)
97
193
  break;
98
- rest = rest.slice(end + 3);
194
+ cursor = end + 3;
99
195
  inComment = false;
196
+ commentStart = undefined;
100
197
  }
101
198
  else {
102
- const start = rest.indexOf('<!--');
199
+ const start = commentView.indexOf('<!--', cursor);
103
200
  if (start < 0) {
104
- visible += rest;
201
+ visible += raw.slice(cursor);
105
202
  break;
106
203
  }
107
- visible += rest.slice(0, start);
108
- rest = rest.slice(start + 4);
204
+ visible += raw.slice(cursor, start);
205
+ cursor = start + 4;
109
206
  inComment = true;
207
+ commentStart = line;
110
208
  }
111
209
  }
112
210
  for (const marker of MARKERS) {
@@ -115,16 +213,25 @@ export function scanMarkdown(input) {
115
213
  }
116
214
  }
117
215
  if (TABLE_RULE.test(visible))
118
- tableRows++;
119
- if (BULLET.test(visible))
216
+ tableRuleLines.push(line);
217
+ if (BULLET.test(visible) || ORDERED.test(visible))
120
218
  bulletLines.push(line);
219
+ const def = REF_DEF.exec(visible);
220
+ if (def && !refDefs.has(normLabel(def[1])))
221
+ refDefs.set(normLabel(def[1]), stripAngles(def[2]));
121
222
  // 코드 스팬은 기록한 뒤 같은 길이의 공백으로 가려서 링크 추출에서 뺀다.
122
223
  const masked = visible.replace(CODE_SPAN, (match, content) => {
123
224
  codeSpans.push({ line, content });
124
225
  return ' '.repeat(match.length);
125
226
  });
126
- for (const m of masked.matchAll(LINK)) {
127
- links.push({ line, text: m[1], rawTarget: stripAngles(m[2]) });
227
+ // 참조 정의 줄은 링크를 만들지 않는다.
228
+ if (def === null) {
229
+ for (const use of extractLinkUses(masked)) {
230
+ if (use.kind === 'inline')
231
+ links.push({ line, text: use.text, rawTarget: use.rawTarget });
232
+ else
233
+ refUses.push({ line, text: use.text, label: normLabel(use.label) });
234
+ }
128
235
  }
129
236
  const atx = ATX.exec(visible);
130
237
  if (atx) {
@@ -132,7 +239,25 @@ export function scanMarkdown(input) {
132
239
  headings.push({ level: atx[1].length, text, slug: uniqueSlug(slugify(text), usedSlugs), line });
133
240
  }
134
241
  }
135
- return { lineCount: lines.length, headings, links, codeSpans, markerLines, mermaidFences, tableRows, bulletLines };
242
+ // 정의가 있는 참조 사용만 링크가 된다. 정의가 없으면 아무것도 만들지 않는다.
243
+ for (const use of refUses) {
244
+ const target = refDefs.get(use.label);
245
+ if (target !== undefined)
246
+ links.push({ line: use.line, text: use.text, rawTarget: target });
247
+ }
248
+ // 줄 순서를 유지한다. 정렬은 안정적이라 같은 줄 안의 순서는 그대로 남는다.
249
+ links.sort((a, b) => a.line - b.line);
250
+ return {
251
+ lineCount: lines.length,
252
+ headings,
253
+ links,
254
+ codeSpans,
255
+ markerLines,
256
+ mermaidFenceLines,
257
+ tableRuleLines,
258
+ bulletLines,
259
+ unterminatedComment: inComment ? commentStart : undefined,
260
+ };
136
261
  }
137
262
  // 링크 대상을 문서 기준으로 해석한다. 외부 스킴은 검사하지 않는다.
138
263
  export function classifyTarget(rawTarget, docAbs, root) {
@@ -168,11 +293,16 @@ export function buildSections(scan, vocab) {
168
293
  return { key: findVocabKey(heading.text, vocab), heading, startLine: heading.line, endLine, children };
169
294
  });
170
295
  }
171
- // 근거 경로 후보. 공백이 없고, http로 시작하지 않고, / 또는 .을 포함해야 하며, :N 또는 :N-M 접미사는 뗀다.
296
+ // 근거 경로 후보. 줄 범위 접미사(:N, :N-M, :N:C, :12-48,60-70)를 먼저 떼고, 남은 값이 다음을 모두 만족해야 한다.
297
+ // 공백이 없고, URL 스킴(scheme://)이나 mailto:가 아니며, /를 포함한다. 파일 이름만 있는 값은 후보가 아니다.
298
+ // 저장소 루트의 파일은 ./package.json처럼 적는다.
172
299
  export function evidenceCandidate(content) {
173
- if (/\s/.test(content) || content.startsWith('http') || !/[/.]/.test(content))
300
+ const path = content.replace(LINE_RANGE, '');
301
+ if (/\s/.test(path) || /^[a-z][a-z0-9+.-]*:\/\//i.test(path) || path.startsWith('mailto:'))
302
+ return undefined;
303
+ if (!path.includes('/'))
174
304
  return undefined;
175
- return content.replace(/:\d+(-\d+)?$/, '');
305
+ return path;
176
306
  }
177
307
  // 근거 절 안에 있는 코드 스팬 중 후보만 모은다.
178
308
  export function evidenceCandidates(scan, sections) {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAiB,MAAM,eAAe,CAAC;AAGnE,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAC1C,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAClD,MAAM,GAAG,GAAG,gDAAgD,CAAC;AAC7D,MAAM,SAAS,GAAG,cAAc,CAAC;AACjC,MAAM,MAAM,GAAG,sBAAsB,CAAC;AACtC,4CAA4C;AAC5C,MAAM,OAAO,GAAG,oEAAoE,CAAC;AACrF,4DAA4D;AAC5D,MAAM,UAAU,GAAG,mDAAmD,CAAC;AACvE,MAAM,MAAM,GAAG,cAAc,CAAC;AAC9B,MAAM,OAAO,GAAG,gBAAgB,CAAC;AACjC,kDAAkD;AAClD,MAAM,UAAU,GAAG,uCAAuC,CAAC;AAoC3D,0CAA0C;AAC1C,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACzE,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC;SACtC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,IAAiB;IACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QAAE,CAAC,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iEAAiE;AACjE,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI;SACR,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC;SAC7B,OAAO,CAAC,yCAAyC,EAAE,IAAI,CAAC;SACxD,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,OAAO,CAAC,2DAA2D,EAAE,IAAI,CAAC;SAC1E,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACvF,CAAC;AAKD,2CAA2C;AAC3C,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACzD,CAAC;AAED,0EAA0E;AAC1E,8CAA8C;AAC9C,SAAS,cAAc,CAAC,CAAS,EAAE,KAAa;IAC9C,IAAI,CAAC,GAAG,KAAK,CAAC;IACd,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,CAAC,EAAE,CAAC;IAC1C,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,6BAA6B;QAC7B,MAAM,KAAK,GAAG,CAAC,CAAC;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAM;YACnC,IAAI,CAAC,KAAK,GAAG;gBAAE,KAAK,EAAE,CAAC;iBAClB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACnB,IAAI,KAAK,KAAK,CAAC;oBAAE,MAAM;gBACvB,KAAK,EAAE,CAAC;YACV,CAAC;YACD,CAAC,EAAE,CAAC;QACN,CAAC;QACD,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,CAAC,EAAE,CAAC;IAC1C,2BAA2B;IAC3B,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAChC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,SAAS,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED,2DAA2D;AAC3D,6DAA6D;AAC7D,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,SAAS;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;QAC7C,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC/C,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7F,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC3C,IAAI,GAAG,GAAG,CAAC;gBAAE,SAAS;YACtB,IAAI,CAAC,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACzF,CAAC,GAAG,GAAG,CAAC;QACV,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,sCAAsC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3F,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,kDAAkD;IAClD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,OAAO,GAAoD,EAAE,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,KAA8C,CAAC;IACnD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,YAAgC,CAAC;IAErC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QAEvB,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACtE,KAAK,GAAG,SAAS,CAAC;YACpB,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBAChD,4CAA4C;gBAC5C,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;oBAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvG,SAAS;YACX,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,iEAAiE;QACjE,6DAA6D;QAC7D,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACxF,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,SAAS,CAAC;YACR,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACvC,IAAI,GAAG,GAAG,CAAC;oBAAE,MAAM;gBACnB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;gBACjB,SAAS,GAAG,KAAK,CAAC;gBAClB,YAAY,GAAG,SAAS,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAClD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC7B,MAAM;gBACR,CAAC;gBACD,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBACpC,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC;gBACnB,SAAS,GAAG,IAAI,CAAC;gBACjB,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,KAAK,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhG,2CAA2C;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,KAAa,EAAE,OAAe,EAAE,EAAE;YAC3E,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAClC,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,wBAAwB;QACxB,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;;oBACrF,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,6CAA6C;IAC7C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAEtC,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,QAAQ;QACR,KAAK;QACL,SAAS;QACT,WAAW;QACX,iBAAiB;QACjB,cAAc;QACd,WAAW;QACX,mBAAmB,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;KAC1D,CAAC;AACJ,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,MAAc,EAAE,IAAY;IAC5E,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,IAAY,CAAC;IACjB,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpB,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;AACnH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAA+B;IACxE,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;AACxE,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,KAA+B;IACvE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;IACtD,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC;QACzG,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACzG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,2EAA2E;AAC3E,oCAAoC;AACpC,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7G,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,kBAAkB,CAAC,IAAU,EAAE,QAAmB;IAChE,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,KAAK,UAAU;YAAE,SAAS;QACzC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,OAAO;gBAAE,SAAS;YAC3E,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,IAAI,KAAK,SAAS;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,3 +1,8 @@
1
+ import { VOCAB_KEYS } from './headings.js';
2
+ // 사용자에게 보이는 문자열 모음(12.2). 한국어 문구는 1단계 출력과 바이트 단위로 같다.
3
+ // 명령·옵션 이름·규칙 id·파일 경로·식별자는 두 언어 모두 원문 그대로 둔다.
4
+ // 영어 수 표기: 1이면 단수, 그 밖이면 복수다.
5
+ const counted = (n, word) => `${n} ${word}${n === 1 ? '' : 's'}`;
1
6
  export const MESSAGES = {
2
7
  en: {
3
8
  usage: 'usage: crumbs <init|check|log add> [options] (details: crumbs --help)',
@@ -21,6 +26,7 @@ init options
21
26
  check options
22
27
  --format <text|json> output format (default: text)
23
28
  --config <path> config file path (default: <root>/crumbs.json)
29
+ exclude entries in crumbs.json are paths relative to the spec root; an entry ending in "/" excludes a directory
24
30
 
25
31
  log add options
26
32
  --kind <ingest|query|lint|drift|change|decision> entry kind (required)
@@ -42,14 +48,16 @@ Example
42
48
  titleEmpty: 'title is empty',
43
49
  titleLineBreak: 'title cannot contain a line break',
44
50
  bodyHeading: 'body cannot contain a heading line (#)',
51
+ commentForbidden: 'title and body cannot contain "<!--"',
45
52
  configKept: (option) => `note: crumbs.json already exists, so its settings are used (${option} ignored)`,
46
53
  skipped: (path) => `skipped: ${path} (already exists)`,
47
54
  created: (path) => `created: ${path}`,
48
55
  updated: (path) => `updated: ${path}`,
49
- next: 'next: crumbs check',
50
- claudeGuide: 'guide: add "@AGENTS.md" to CLAUDE.md so Claude Code reads the crumbs rules',
56
+ next: 'next: npx crumbs-spec check',
57
+ claudeGuide: (file) => `guide: Claude Code reads ${file} instead of AGENTS.md; add "@AGENTS.md" to ${file} so it reads the crumbs rules`,
51
58
  agentsMarkers: 'AGENTS.md: crumbs markers are not paired',
52
- fileMissing: (where) => `crumbs.json not found in ${where}. Run "crumbs init" first.`,
59
+ rootMissing: (root) => `root directory not found: ${root}`,
60
+ fileMissing: (where) => `crumbs.json not found in ${where}. Run "npx crumbs-spec init" first.`,
53
61
  configNotObject: 'crumbs.json: must be an object',
54
62
  unknownKey: (key) => `crumbs.json: unknown key "${key}"`,
55
63
  invalid: (key, reason) => `crumbs.json: "${key}" has an invalid value: ${reason}`,
@@ -60,12 +68,15 @@ Example
60
68
  reasonOne: 'only 1 is allowed',
61
69
  reasonDot: '"." or an empty value is not allowed',
62
70
  reasonObject: 'must be an object',
63
- reasonUnknownHeading: (name) => `unknown heading key "${name}"`,
71
+ reasonUnknownHeading: (name) => `unknown heading key "${name}" (valid: ${VOCAB_KEYS.join(', ')})`,
64
72
  reasonStringArray: 'must be an array of strings',
65
73
  reasonInsideSpec: 'cannot be inside specDir',
66
- logDocMissing: (path) => `log document not found: ${path}. Run "crumbs init" first.`,
74
+ reasonInsideRoot: 'must stay inside the repository root',
75
+ reasonRelativePath: 'must be a path relative to the spec root',
76
+ logDocMissing: (path) => `log document not found: ${path}. Run "npx crumbs-spec init" first.`,
67
77
  logAdded: (path, heading) => `added: ${path} — ${heading}`,
68
- summary: (documents, errors, warnings) => `crumbs check: ${documents} documents, ${errors} errors, ${warnings} warnings`,
78
+ logDateFuture: (date) => `date is in the future: ${date}`,
79
+ summary: (documents, errors, warnings) => `crumbs check: ${counted(documents, 'document')}, ${counted(errors, 'error')}, ${counted(warnings, 'warning')}`,
69
80
  h1Title: 'first heading must be an H1',
70
81
  indexMissing: (path) => `index document not found: ${path}`,
71
82
  linkMissing: (rawTarget) => `link target not found: ${rawTarget}`,
@@ -76,12 +87,16 @@ Example
76
87
  backlinkOneWay: (sourcePath) => `linked from ${sourcePath} but no link back`,
77
88
  codePathMissing: (raw) => `code path not found: ${raw}`,
78
89
  duplicatePolicy: (name, others) => `duplicate policy "${name}": also in ${others}`,
79
- openQuestions: (count) => `${count} open question marker(s)`,
90
+ duplicatePolicyInDoc: (name, line) => `duplicate policy "${name}": already defined in this document at line ${line}`,
91
+ noSpecSections: (target) => `no spec sections found; if this is not a crumbs document, add "${target}" to "exclude" in crumbs.json`,
92
+ unterminatedComment: 'HTML comment opened here is never closed; everything after it is invisible to check',
93
+ spellingMismatch: (rawTarget, actual) => `link spelling differs from the file on disk: ${rawTarget} (file: ${actual})`,
94
+ openQuestions: (count) => `${count} open question(s)`,
80
95
  logHeadingFormat: (text) => `log entry heading must be "## [YYYY-MM-DD] kind | title": "${text}"`,
81
96
  logKindUnknown: (kind, kinds) => `unknown kind "${kind}" (one of ${kinds})`,
82
97
  logDateInvalid: (date) => `date is not valid: ${date}`,
83
98
  logOrder: (previous, date) => `log entries are out of date order: ${date} is before ${previous}`,
84
- decisionLink: 'decision entry has no document link',
99
+ decisionLink: 'decision entry has no document link (expected: Document: [policy](domain/file.md#anchor))',
85
100
  flowMissing: (steps) => `current behavior has ${steps} steps but no flow diagram or table`,
86
101
  sectionFirst: (title) => `section order differs from the template: first section must be "## ${title}"`,
87
102
  sectionLast: (title) => `section order differs from the template: last section must be "## ${title}"`,
@@ -109,6 +124,7 @@ init 옵션
109
124
  check 옵션
110
125
  --format <text|json> 출력 형식 (기본값: text)
111
126
  --config <path> 설정 파일 경로 (기본값: <root>/crumbs.json)
127
+ crumbs.json의 exclude 항목은 스펙 루트 기준 경로이며, "/"로 끝나면 디렉터리를 제외한다
112
128
 
113
129
  log add 옵션
114
130
  --kind <ingest|query|lint|drift|change|decision> 항목 종류 (필수)
@@ -130,14 +146,16 @@ log add 옵션
130
146
  titleEmpty: '제목이 비어 있음',
131
147
  titleLineBreak: '제목에 줄바꿈을 넣을 수 없음',
132
148
  bodyHeading: '본문에 제목 줄(#)을 넣을 수 없음',
149
+ commentForbidden: '제목과 본문에 "<!--"를 넣을 수 없음',
133
150
  configKept: (option) => `참고: crumbs.json이 이미 있어 그 설정을 사용함 (${option} 무시)`,
134
151
  skipped: (path) => `이미 있음, 건너뜀: ${path}`,
135
152
  created: (path) => `생성: ${path}`,
136
153
  updated: (path) => `갱신: ${path}`,
137
- next: '다음: crumbs check',
138
- claudeGuide: '안내: Claude Code가 crumbs 규칙을 읽도록 CLAUDE.md에 "@AGENTS.md"를 추가하세요',
154
+ next: '다음: npx crumbs-spec check',
155
+ claudeGuide: (file) => `안내: Claude Code는 ${file} 파일이 있으면 AGENTS.md를 읽지 않으니, ${file}에 "@AGENTS.md"를 추가하세요`,
139
156
  agentsMarkers: 'AGENTS.md: crumbs 표시가 짝이 맞지 않음',
140
- fileMissing: (where) => `${where}에 crumbs.json이 없음. 먼저 "crumbs init"을 실행하세요.`,
157
+ rootMissing: (root) => `저장소 루트 디렉터리를 찾을 수 없음: ${root}`,
158
+ fileMissing: (where) => `${where}에 crumbs.json이 없음. 먼저 "npx crumbs-spec init"을 실행하세요.`,
141
159
  configNotObject: 'crumbs.json: 타입이 객체이어야 함',
142
160
  unknownKey: (key) => `crumbs.json: 알 수 없는 키 "${key}"`,
143
161
  invalid: (key, reason) => `crumbs.json: "${key}" 값이 잘못됨: ${reason}`,
@@ -147,11 +165,14 @@ log add 옵션
147
165
  reasonOne: '1만 허용',
148
166
  reasonDot: '"."이나 빈 값은 안 됨',
149
167
  reasonObject: '타입이 객체이어야 함',
150
- reasonUnknownHeading: (name) => `알 수 없는 어휘 키 "${name}"`,
168
+ reasonUnknownHeading: (name) => `알 수 없는 어휘 키 "${name}" (가능한 키: ${VOCAB_KEYS.join(', ')})`,
151
169
  reasonStringArray: '타입이 문자열 배열이어야 함',
152
170
  reasonInsideSpec: 'specDir 안에 둘 수 없음',
153
- logDocMissing: (path) => `로그 문서가 없음: ${path}. 먼저 "crumbs init"을 실행하세요.`,
171
+ reasonInsideRoot: '저장소 루트 밖을 가리킬 수 없음',
172
+ reasonRelativePath: '스펙 루트 기준 상대 경로여야 함',
173
+ logDocMissing: (path) => `로그 문서가 없음: ${path}. 먼저 "npx crumbs-spec init"을 실행하세요.`,
154
174
  logAdded: (path, heading) => `추가: ${path} — ${heading}`,
175
+ logDateFuture: (date) => `날짜가 미래임: ${date}`,
155
176
  summary: (documents, errors, warnings) => `crumbs check: 문서 ${documents}개, 오류 ${errors}개, 경고 ${warnings}개`,
156
177
  h1Title: '첫 제목은 H1이어야 함',
157
178
  indexMissing: (path) => `인덱스 문서가 없음: ${path}`,
@@ -163,12 +184,16 @@ log add 옵션
163
184
  backlinkOneWay: (sourcePath) => `${sourcePath}에서 링크했지만 되돌아가는 링크가 없음`,
164
185
  codePathMissing: (raw) => `코드 경로가 없음: ${raw}`,
165
186
  duplicatePolicy: (name, others) => `중복 정책 "${name}": ${others}에도 있음`,
166
- openQuestions: (count) => `미해결 질문 표시 ${count}개`,
187
+ duplicatePolicyInDoc: (name, line) => `중복 정책 "${name}": 이 문서의 ${line}줄에 이미 있음`,
188
+ noSpecSections: (target) => `스펙 절이 하나도 없음. crumbs 문서가 아니면 crumbs.json의 "exclude"에 "${target}"를 추가하세요`,
189
+ unterminatedComment: '여기서 연 HTML 주석이 닫히지 않음: 이후 내용은 check가 볼 수 없음',
190
+ spellingMismatch: (rawTarget, actual) => `링크 철자가 디스크의 파일과 다름: ${rawTarget} (파일: ${actual})`,
191
+ openQuestions: (count) => `미해결 질문 ${count}개`,
167
192
  logHeadingFormat: (text) => `로그 항목 제목 형식이 틀림: "${text}" (형식: [YYYY-MM-DD] kind | 제목)`,
168
193
  logKindUnknown: (kind, kinds) => `알 수 없는 kind "${kind}" (${kinds} 중 하나)`,
169
194
  logDateInvalid: (date) => `날짜가 유효하지 않음: ${date}`,
170
195
  logOrder: (previous, date) => `이전 항목(${previous})보다 날짜가 앞섬: ${date}`,
171
- decisionLink: '결정 항목에 문서 링크가 없음',
196
+ decisionLink: '결정 항목에 문서 링크가 없음 (형식: 문서: [정책](domain/file.md#앵커))',
172
197
  flowMissing: (steps) => `현재 동작이 ${steps}단계인데 흐름 도식이나 표가 없음`,
173
198
  sectionFirst: (title) => `첫 절은 "## ${title}"이어야 함`,
174
199
  sectionLast: (title) => `마지막 절은 "## ${title}"이어야 함`,
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/messages.ts"],"names":[],"mappings":"AA0EA,MAAM,CAAC,MAAM,QAAQ,GAA2B;IAC9C,EAAE,EAAE;QACF,KAAK,EAAE,wEAAwE;QAC/E,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BT;QACG,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,IAAI,GAAG;QACnD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,IAAI,wBAAwB;QAC9D,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,IAAI,eAAe;QACxD,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,oBAAoB,IAAI,GAAG;QACrD,SAAS,EAAE,kBAAkB;QAC7B,YAAY,EAAE,+BAA+B;QAC7C,YAAY,EAAE,kBAAkB;QAChC,UAAU,EAAE,4CAA4C;QACxD,UAAU,EAAE,gBAAgB;QAC5B,cAAc,EAAE,mCAAmC;QACnD,WAAW,EAAE,wCAAwC;QAErD,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,+DAA+D,MAAM,WAAW;QACxG,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,IAAI,mBAAmB;QACtD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,IAAI,EAAE;QACrC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,IAAI,EAAE;QACrC,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,4EAA4E;QACzF,aAAa,EAAE,0CAA0C;QAEzD,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,4BAA4B,KAAK,4BAA4B;QACrF,eAAe,EAAE,gCAAgC;QACjD,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,6BAA6B,GAAG,GAAG;QACxD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,iBAAiB,GAAG,2BAA2B,MAAM,EAAE;QACjF,+DAA+D;QAC/D,WAAW,EAAE,0CAA0C;QACvD,YAAY,EAAE,kBAAkB;QAChC,YAAY,EAAE,kBAAkB;QAChC,SAAS,EAAE,mBAAmB;QAC9B,SAAS,EAAE,sCAAsC;QACjD,YAAY,EAAE,mBAAmB;QACjC,oBAAoB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,IAAI,GAAG;QAC/D,iBAAiB,EAAE,6BAA6B;QAChD,gBAAgB,EAAE,0BAA0B;QAE5C,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,2BAA2B,IAAI,4BAA4B;QACpF,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,IAAI,MAAM,OAAO,EAAE;QAE1D,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CACvC,iBAAiB,SAAS,eAAe,MAAM,YAAY,QAAQ,WAAW;QAEhF,OAAO,EAAE,6BAA6B;QACtC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,6BAA6B,IAAI,EAAE;QAC3D,WAAW,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,0BAA0B,SAAS,EAAE;QACjE,aAAa,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,qBAAqB,SAAS,EAAE;QAC9D,WAAW,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,oBAAoB,SAAS,EAAE;QAC3D,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,sBAAsB;QAC7D,eAAe,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,mBAAmB,UAAU,EAAE;QAChE,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,eAAe,UAAU,mBAAmB;QAC5E,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,wBAAwB,GAAG,EAAE;QACvD,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,qBAAqB,IAAI,cAAc,MAAM,EAAE;QAClF,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,0BAA0B;QAC5D,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,8DAA8D,IAAI,GAAG;QACjG,cAAc,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,IAAI,aAAa,KAAK,GAAG;QAC3E,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,sBAAsB,IAAI,EAAE;QACtD,QAAQ,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,sCAAsC,IAAI,cAAc,QAAQ,EAAE;QAChG,YAAY,EAAE,qCAAqC;QACnD,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,wBAAwB,KAAK,qCAAqC;QAC1F,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,sEAAsE,KAAK,GAAG;QACvG,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,qEAAqE,KAAK,GAAG;QACrG,YAAY,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAC9B,gDAAgD,MAAM,0BAA0B,KAAK,GAAG;KAC3F;IAED,EAAE,EAAE;QACF,KAAK,EAAE,6DAA6D;QACpE,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BT;QACG,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,GAAG;QAC9C,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,WAAW;QAC7C,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,OAAO;QAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,GAAG;QAC/C,SAAS,EAAE,QAAQ;QACnB,YAAY,EAAE,qBAAqB;QACnC,YAAY,EAAE,QAAQ;QACtB,UAAU,EAAE,wBAAwB;QACpC,UAAU,EAAE,WAAW;QACvB,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,sBAAsB;QAEnC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,qCAAqC,MAAM,MAAM;QACzE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,EAAE;QACxC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE;QAChC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE;QAChC,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,gEAAgE;QAC7E,aAAa,EAAE,gCAAgC;QAE/C,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,6CAA6C;QAC7E,eAAe,EAAE,0BAA0B;QAC3C,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,0BAA0B,GAAG,GAAG;QACrD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,iBAAiB,GAAG,aAAa,MAAM,EAAE;QACnE,WAAW,EAAE,0CAA0C;QACvD,YAAY,EAAE,cAAc;QAC5B,YAAY,EAAE,aAAa;QAC3B,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,gBAAgB;QAC3B,YAAY,EAAE,aAAa;QAC3B,oBAAoB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,IAAI,GAAG;QACvD,iBAAiB,EAAE,iBAAiB;QACpC,gBAAgB,EAAE,mBAAmB;QAErC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,4BAA4B;QACvE,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,MAAM,OAAO,EAAE;QAEvD,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,oBAAoB,SAAS,SAAS,MAAM,SAAS,QAAQ,GAAG;QAE1G,OAAO,EAAE,eAAe;QACxB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,EAAE;QAC7C,WAAW,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,cAAc,SAAS,EAAE;QACrD,aAAa,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,WAAW,SAAS,EAAE;QACpD,WAAW,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,SAAS,aAAa;QACrD,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS;QAChD,eAAe,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,UAAU,eAAe;QAC7D,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,UAAU,uBAAuB;QACpE,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,GAAG,EAAE;QAC7C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,IAAI,MAAM,MAAM,OAAO;QACpE,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,KAAK,GAAG;QAC/C,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,IAAI,gCAAgC;QACrF,cAAc,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,IAAI,MAAM,KAAK,QAAQ;QACxE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,IAAI,EAAE;QAChD,QAAQ,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,SAAS,QAAQ,eAAe,IAAI,EAAE;QACpE,YAAY,EAAE,kBAAkB;QAChC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,KAAK,oBAAoB;QAC3D,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,KAAK,QAAQ;QAClD,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,KAAK,QAAQ;QACnD,YAAY,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,MAAM,YAAY,KAAK,WAAW;KAC3E;CACF,CAAC"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/messages.ts"],"names":[],"mappings":"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"}
package/dist/src/model.js CHANGED
@@ -1,5 +1,4 @@
1
- // line이 없는 발견은 line 키 자체를 두지 않아 JSON에서도 빠진다.
2
- export function finding(rule, severity, file, message, line) {
3
- return line === undefined ? { rule, severity, file, message } : { rule, severity, file, line, message };
1
+ export function finding(rule, severity, file, message, line = 1) {
2
+ return { rule, severity, file, line, message };
4
3
  }
5
4
  //# sourceMappingURL=model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AAoFA,6CAA6C;AAC7C,MAAM,UAAU,OAAO,CACrB,IAAY,EACZ,QAA6B,EAC7B,IAAY,EACZ,OAAe,EACf,IAAa;IAEb,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC1G,CAAC"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AAyFA,MAAM,UAAU,OAAO,CACrB,IAAY,EACZ,QAA6B,EAC7B,IAAY,EACZ,OAAe,EACf,IAAI,GAAG,CAAC;IAER,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { MESSAGES } from './messages.js';
2
2
  // 발견마다 한 줄, 발견이 있으면 빈 줄 하나, 그다음 요약 한 줄.
3
3
  export function formatText(report, lang) {
4
- const lines = report.findings.map((finding) => `${finding.file}${finding.line === undefined ? '' : `:${finding.line}`} ${finding.severity} ${finding.rule}: ${finding.message}`);
4
+ const lines = report.findings.map((finding) => `${finding.file}:${finding.line} ${finding.severity} ${finding.rule}: ${finding.message}`);
5
5
  if (lines.length > 0)
6
6
  lines.push('');
7
7
  const { documents, errors, warnings } = report.summary;
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/report.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wCAAwC;AACxC,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,IAAU;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC,OAAO,EAAE,EAAE,CACV,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CACnI,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/report.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wCAAwC;AACxC,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,IAAU;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC/B,CAAC,OAAO,EAAE,EAAE,CACV,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAC5F,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
@@ -8,7 +8,10 @@ export function brokenLink(graph) {
8
8
  for (const link of doc.links) {
9
9
  if (link.kind !== 'internal' || link.path === undefined)
10
10
  continue;
11
- if (!isFile(link.path)) {
11
+ if (link.spellingMismatch !== undefined) {
12
+ out.push(finding('broken-link', 'error', doc.file, MESSAGES[graph.lang].spellingMismatch(link.rawTarget, link.spellingMismatch), link.line));
13
+ }
14
+ else if (!isFile(link.path)) {
12
15
  out.push(finding('broken-link', 'error', doc.file, MESSAGES[graph.lang].linkMissing(link.rawTarget), link.line));
13
16
  }
14
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"broken-link.js","sourceRoot":"","sources":["../../../src/rules/broken-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAgB,MAAM,aAAa,CAAC;AAEpD,mEAAmE;AACnE,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS;YAClE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"broken-link.js","sourceRoot":"","sources":["../../../src/rules/broken-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAgB,MAAM,aAAa,CAAC;AAEpD,mEAAmE;AACnE,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS;YAClE,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACxC,GAAG,CAAC,IAAI,CACN,OAAO,CACL,aAAa,EACb,OAAO,EACP,GAAG,CAAC,IAAI,EACR,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAC5E,IAAI,CAAC,IAAI,CACV,CACF,CAAC;YACJ,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,19 +1,28 @@
1
1
  import { MESSAGES } from '../messages.js';
2
2
  import { finding } from '../model.js';
3
3
  // 정책 이름은 문서 하나만 소유한다. 로그 문서는 면제다.
4
- // 같은 정규화 이름이 서로 다른 두 문서 이상에 있으면, 관련 문서마다 발견 하나를 낸다.
4
+ // 같은 정규화 이름이 한 문서 안에 두 번 이상 있으면, 두 번째부터의 제목마다 발견 하나를 낸다.
5
+ // 같은 이름이 서로 다른 두 문서 이상에 있으면, 관련 문서마다 발견 하나를 낸다.
5
6
  export function duplicatePolicy(graph) {
7
+ const out = [];
6
8
  const groups = new Map();
7
9
  for (const doc of graph.docs) {
8
10
  if (doc.role === 'log')
9
11
  continue;
12
+ const firstInDoc = new Map();
10
13
  for (const policy of doc.policies) {
14
+ const earlier = firstInDoc.get(policy.normalized);
15
+ if (earlier === undefined) {
16
+ firstInDoc.set(policy.normalized, policy.heading);
17
+ }
18
+ else {
19
+ out.push(finding('duplicate-policy', 'error', doc.file, MESSAGES[graph.lang].duplicatePolicyInDoc(policy.heading.text, earlier.line), policy.heading.line));
20
+ }
11
21
  const entries = groups.get(policy.normalized) ?? [];
12
22
  entries.push({ doc, heading: policy.heading });
13
23
  groups.set(policy.normalized, entries);
14
24
  }
15
25
  }
16
- const out = [];
17
26
  for (const entries of groups.values()) {
18
27
  const docs = [];
19
28
  for (const entry of entries) {
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate-policy.js","sourceRoot":"","sources":["../../../src/rules/duplicate-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAA4C,MAAM,aAAa,CAAC;AAEhF,kCAAkC;AAClC,oDAAoD;AACpD,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgD,CAAC;IACvE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QACjC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YACzD,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,MAAM,MAAM,GAAG,IAAI;iBAChB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC;iBAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;iBAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CACN,OAAO,CACL,kBAAkB,EAClB,OAAO,EACP,GAAG,CAAC,IAAI,EACR,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAChE,KAAK,CAAC,OAAO,CAAC,IAAI,CACnB,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"duplicate-policy.js","sourceRoot":"","sources":["../../../src/rules/duplicate-policy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAA4C,MAAM,aAAa,CAAC;AAEhF,kCAAkC;AAClC,yDAAyD;AACzD,gDAAgD;AAChD,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgD,CAAC;IACvE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QACjC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;QAC9C,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CACN,OAAO,CACL,kBAAkB,EAClB,OAAO,EACP,GAAG,CAAC,IAAI,EACR,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAC5E,MAAM,CAAC,OAAO,CAAC,IAAI,CACpB,CACF,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YACzD,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,MAAM,MAAM,GAAG,IAAI;iBAChB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC;iBAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;iBAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CACN,OAAO,CACL,kBAAkB,EAClB,OAAO,EACP,GAAG,CAAC,IAAI,EACR,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAChE,KAAK,CAAC,OAAO,CAAC,IAAI,CACnB,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { parseLogHeading } from '../log.js';
2
2
  import { MESSAGES } from '../messages.js';
3
3
  import { finding } from '../model.js';
4
- // kind가 decision인 항목은 본문(제목 줄 다음부터 다음 H2 직전까지)에 내부 링크가 하나 이상 있어야 한다. 없으면 제목 줄마다 경고 하나다.
5
- // 링크는 파싱된 doc.links를 쓰고, 항목 경계는 H2 제목 줄로 정한다.
4
+ // kind가 decision인 항목은 본문(제목 줄 다음부터 다음 H2 직전까지)에 다른 문서로 가는 내부 링크가 하나 이상 있어야 한다. 없으면 제목 줄마다 경고 하나다.
5
+ // 같은 로그 안을 가리키는 #앵커 링크는 문서 링크로 세지 않는다. 링크는 파싱된 doc.links를 쓰고, 항목 경계는 H2 제목 줄로 정한다.
6
6
  export function logBody(graph) {
7
7
  const log = graph.docs.find((doc) => doc.role === 'log');
8
8
  if (log === undefined)
@@ -14,7 +14,7 @@ export function logBody(graph) {
14
14
  if (!parsed.ok || parsed.kind !== 'decision')
15
15
  return;
16
16
  const end = entries[index + 1]?.line ?? Number.MAX_SAFE_INTEGER;
17
- const linked = log.links.some((link) => link.kind === 'internal' && link.line > heading.line && link.line < end);
17
+ const linked = log.links.some((link) => link.kind === 'internal' && link.path !== log.abs && link.line > heading.line && link.line < end);
18
18
  if (!linked)
19
19
  out.push(finding('log-body', 'warning', log.file, MESSAGES[graph.lang].decisionLink, heading.line));
20
20
  });