@open-agent-toolkit/cli 0.2.72 → 0.2.74

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 (165) hide show
  1. package/assets/agents/oat-reviewer.md +4 -3
  2. package/assets/agents/recon-worker.md +42 -8
  3. package/assets/bundle-metadata.json +1 -1
  4. package/assets/docs/cli-utilities/configuration.md +3 -56
  5. package/assets/docs/cli-utilities/tool-packs.md +4 -4
  6. package/assets/docs/contributing/code.md +2 -2
  7. package/assets/docs/contributing/index.md +0 -1
  8. package/assets/docs/reference/cli-reference.md +1 -1
  9. package/assets/docs/reference/troubleshooting.md +17 -40
  10. package/assets/docs/workflows/projects/artifacts.md +16 -34
  11. package/assets/docs/workflows/projects/lifecycle.md +20 -19
  12. package/assets/docs/workflows/skills/explainer-kit.md +180 -440
  13. package/assets/docs/workflows/skills/index.md +1 -2
  14. package/assets/docs/workflows/skills/recon.md +114 -23
  15. package/assets/public-package-versions.json +4 -4
  16. package/assets/skills/explainer-kit/SKILL.md +96 -171
  17. package/assets/skills/explainer-kit/recipes/engineer-tour.json +1 -22
  18. package/assets/skills/explainer-kit/recipes/program-recap.json +1 -29
  19. package/assets/skills/explainer-kit/recipes/project-explainer.json +1 -22
  20. package/assets/skills/explainer-kit/recipes/project-recap.v2.json +1 -43
  21. package/assets/skills/explainer-kit/references/fact-base-contract.md +76 -101
  22. package/assets/skills/explainer-kit/references/recap-authoring.md +99 -0
  23. package/assets/skills/explainer-kit/schemas/manifest.schema.json +13 -135
  24. package/assets/skills/explainer-kit/scripts/bundle.mjs +712 -0
  25. package/assets/skills/explainer-kit/scripts/lib/claim-subject.mjs +40 -0
  26. package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +113 -1504
  27. package/assets/skills/explainer-kit/scripts/lib/failure.mjs +13 -0
  28. package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +57 -403
  29. package/assets/skills/explainer-kit/scripts/lib/qa-result.mjs +168 -0
  30. package/assets/skills/explainer-kit/scripts/lib/qa.mjs +90 -488
  31. package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +28 -545
  32. package/assets/skills/explainer-kit/scripts/lib/run-package.mjs +120 -0
  33. package/assets/skills/explainer-kit/scripts/lib/sanitize.mjs +42 -0
  34. package/assets/skills/explainer-kit/scripts/record.mjs +335 -0
  35. package/assets/skills/explainer-kit/scripts/verify.mjs +648 -0
  36. package/assets/skills/oat-explainer-kit/SKILL.md +57 -117
  37. package/assets/skills/oat-explainer-kit/references/config-contract.md +20 -64
  38. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +85 -237
  39. package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +18 -10
  40. package/assets/skills/oat-explainer-kit/scripts/check-core.mjs +1 -0
  41. package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +256 -21
  42. package/assets/skills/oat-explainer-kit/scripts/persist-intent.mjs +82 -3
  43. package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +0 -162
  44. package/assets/skills/oat-explainer-kit/scripts/resolve-intent.mjs +57 -123
  45. package/assets/skills/oat-project-autonomous/SKILL.md +14 -13
  46. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +165 -165
  47. package/assets/skills/oat-project-complete/SKILL.md +168 -349
  48. package/assets/skills/oat-project-complete/scripts/consume-persisted-recap-intent.mjs +125 -0
  49. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +0 -30
  50. package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +4 -37
  51. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +17 -16
  52. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +9 -174
  53. package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +1 -2
  54. package/assets/skills/oat-project-document/SKILL.md +1 -1
  55. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +165 -165
  56. package/assets/skills/oat-project-implement/SKILL.md +1 -1
  57. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +44 -56
  58. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +165 -165
  59. package/assets/skills/oat-project-lite/SKILL.md +1 -1
  60. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +165 -165
  61. package/assets/skills/oat-project-plan/SKILL.md +5 -6
  62. package/assets/skills/oat-project-pr-final/SKILL.md +1 -1
  63. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +165 -165
  64. package/assets/skills/oat-project-quick-start/SKILL.md +1 -1
  65. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +165 -165
  66. package/assets/skills/oat-project-review-receive/SKILL.md +14 -1
  67. package/assets/skills/oat-project-summary/SKILL.md +35 -25
  68. package/assets/skills/oat-wave-execute/SKILL.md +11 -36
  69. package/assets/skills/oat-wave-program/SKILL.md +13 -37
  70. package/assets/skills/recon/SKILL.md +103 -40
  71. package/assets/skills/recon/references/packet-contract.md +150 -67
  72. package/assets/skills/recon/references/profiles.md +38 -16
  73. package/assets/skills/recon/references/worker-contract.md +39 -8
  74. package/assets/skills/recon/scripts/lib/contracts.mjs +703 -55
  75. package/assets/skills/recon/scripts/lib/routing.mjs +588 -0
  76. package/assets/skills/recon/scripts/lib/validated-run.mjs +2 -0
  77. package/assets/skills/recon/scripts/prepare-routing.mjs +88 -0
  78. package/assets/skills/recon/scripts/render-packet.mjs +69 -1
  79. package/assets/skills/recon/scripts/validate-packet.mjs +473 -56
  80. package/assets/skills/subagent-orchestration/SKILL.md +18 -9
  81. package/assets/skills/subagent-orchestration/references/model-selection-principles.md +17 -8
  82. package/dist/commands/config/index.d.ts.map +1 -1
  83. package/dist/commands/config/index.js +9 -113
  84. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  85. package/dist/commands/project/archive/archive-utils.js +32 -184
  86. package/dist/commands/project/archive/explainer-package-coverage.d.ts +3 -8
  87. package/dist/commands/project/archive/explainer-package-coverage.d.ts.map +1 -1
  88. package/dist/commands/project/archive/explainer-package-coverage.js +1 -1
  89. package/dist/config/oat-config.d.ts +0 -11
  90. package/dist/config/oat-config.d.ts.map +1 -1
  91. package/dist/config/oat-config.js +0 -34
  92. package/dist/config/resolve.d.ts.map +1 -1
  93. package/dist/config/resolve.js +0 -8
  94. package/dist/release/public-package-contract.d.ts.map +1 -1
  95. package/dist/release/public-package-contract.js +2 -10
  96. package/dist/validation/project-state.d.ts.map +1 -1
  97. package/dist/validation/project-state.js +42 -3
  98. package/package.json +2 -2
  99. package/assets/docs/contributing/explainer-kit-verification.md +0 -133
  100. package/assets/docs/workflows/skills/explainer-kit-providers.md +0 -155
  101. package/assets/skills/explainer-kit/briefs/deep-dive.md +0 -35
  102. package/assets/skills/explainer-kit/briefs/project-page.md +0 -38
  103. package/assets/skills/explainer-kit/briefs/supporting-diagram.md +0 -28
  104. package/assets/skills/explainer-kit/briefs/walkthrough-deck.md +0 -35
  105. package/assets/skills/explainer-kit/examples/project-explainer/content.md +0 -31
  106. package/assets/skills/explainer-kit/examples/project-explainer/fact-base.md +0 -22
  107. package/assets/skills/explainer-kit/examples/project-recap/content.md +0 -77
  108. package/assets/skills/explainer-kit/examples/project-recap/fact-base.json +0 -104
  109. package/assets/skills/explainer-kit/examples/project-recap/fact-base.md +0 -44
  110. package/assets/skills/explainer-kit/examples/theme-bundle.json +0 -87
  111. package/assets/skills/explainer-kit/recipes/project-recap.v1.json +0 -93
  112. package/assets/skills/explainer-kit/references/contracts.md +0 -324
  113. package/assets/skills/explainer-kit/references/destination-contract.md +0 -210
  114. package/assets/skills/explainer-kit/references/extension-contract.md +0 -80
  115. package/assets/skills/explainer-kit/references/golden-conformance.md +0 -80
  116. package/assets/skills/explainer-kit/references/visual-review.md +0 -71
  117. package/assets/skills/explainer-kit/schemas/author-request.v2.schema.json +0 -212
  118. package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +0 -241
  119. package/assets/skills/explainer-kit/schemas/author-result.v2.schema.json +0 -52
  120. package/assets/skills/explainer-kit/schemas/build-record.schema.json +0 -98
  121. package/assets/skills/explainer-kit/schemas/durability-evidence.schema.json +0 -53
  122. package/assets/skills/explainer-kit/schemas/publish-receipt.v1.schema.json +0 -97
  123. package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +0 -215
  124. package/assets/skills/explainer-kit/schemas/publish-request.v1.schema.json +0 -32
  125. package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +0 -34
  126. package/assets/skills/explainer-kit/schemas/run-request.schema.json +0 -147
  127. package/assets/skills/explainer-kit/schemas/set-plan.v1.schema.json +0 -149
  128. package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +0 -81
  129. package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +0 -66
  130. package/assets/skills/explainer-kit/schemas/visual-review-request.v1.schema.json +0 -117
  131. package/assets/skills/explainer-kit/schemas/visual-review-result.v1.schema.json +0 -80
  132. package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +0 -349
  133. package/assets/skills/explainer-kit/scripts/lib/content-approval.mjs +0 -418
  134. package/assets/skills/explainer-kit/scripts/lib/diagram.mjs +0 -514
  135. package/assets/skills/explainer-kit/scripts/lib/durability.mjs +0 -643
  136. package/assets/skills/explainer-kit/scripts/lib/fact-base.mjs +0 -664
  137. package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +0 -538
  138. package/assets/skills/explainer-kit/scripts/lib/markdown.mjs +0 -414
  139. package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +0 -54
  140. package/assets/skills/explainer-kit/scripts/lib/records.mjs +0 -954
  141. package/assets/skills/explainer-kit/scripts/lib/render.mjs +0 -703
  142. package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +0 -353
  143. package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +0 -759
  144. package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +0 -209
  145. package/assets/skills/explainer-kit/scripts/lib/source-backlinks.mjs +0 -218
  146. package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +0 -157
  147. package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +0 -400
  148. package/assets/skills/explainer-kit/scripts/publish.mjs +0 -76
  149. package/assets/skills/explainer-kit/scripts/record-durability.mjs +0 -64
  150. package/assets/skills/explainer-kit/scripts/render-qa.mjs +0 -461
  151. package/assets/skills/explainer-kit/scripts/run.mjs +0 -3038
  152. package/assets/skills/explainer-kit/scripts/validate.mjs +0 -59
  153. package/assets/skills/oat-explainer-kit/references/author-callback.md +0 -53
  154. package/assets/skills/oat-explainer-kit/references/migration.md +0 -144
  155. package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +0 -83
  156. package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +0 -91
  157. package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +0 -531
  158. package/assets/skills/oat-explainer-kit/scripts/probe-recap-seams.mjs +0 -371
  159. package/assets/skills/oat-explainer-kit/scripts/run.mjs +0 -905
  160. package/dist/commands/project/archive/explainer-source-backlinks.d.ts +0 -18
  161. package/dist/commands/project/archive/explainer-source-backlinks.d.ts.map +0 -1
  162. package/dist/commands/project/archive/explainer-source-backlinks.js +0 -27
  163. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +0 -29
  164. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +0 -1
  165. package/dist/commands/project/archive/explainer-terminal-evidence.js +0 -37
@@ -1,414 +0,0 @@
1
- const CALLOUT_TYPES = new Set([
2
- 'NOTE',
3
- 'TIP',
4
- 'IMPORTANT',
5
- 'WARNING',
6
- 'CAUTION',
7
- ]);
8
- const SAFE_NODE_TYPES = new Set([
9
- 'blockquote',
10
- 'callout',
11
- 'code',
12
- 'delete',
13
- 'diagram',
14
- 'document',
15
- 'emphasis',
16
- 'figure',
17
- 'heading',
18
- 'inlineCode',
19
- 'link',
20
- 'list',
21
- 'listItem',
22
- 'paragraph',
23
- 'strong',
24
- 'table',
25
- 'text',
26
- 'timeline',
27
- ]);
28
- const RAW_HTML_PATTERN =
29
- /<\/?[a-z][^>]*>|<!--[\s\S]*?-->|<\?[\s\S]*?\?>|<![A-Z][^>]*>/i;
30
-
31
- export class MarkdownSafetyError extends Error {
32
- constructor(message) {
33
- super(message);
34
- this.name = 'MarkdownSafetyError';
35
- }
36
- }
37
-
38
- export function parseMarkdown(markdown) {
39
- if (typeof markdown !== 'string') {
40
- throw new TypeError('Markdown source must be a string.');
41
- }
42
- return {
43
- type: 'document',
44
- children: parseBlocks(markdown.replaceAll('\r\n', '\n').split('\n')),
45
- };
46
- }
47
-
48
- export function parseMarkdownDocument(markdown) {
49
- const ast = parseMarkdown(markdown);
50
- return { ast, warnings: validateMarkdownAst(ast) };
51
- }
52
-
53
- export function validateMarkdownAst(ast) {
54
- const warnings = [];
55
- let previousHeadingDepth = 0;
56
-
57
- visit(ast, (node) => {
58
- if (!SAFE_NODE_TYPES.has(node.type)) {
59
- throw new MarkdownSafetyError(
60
- `Unsafe markdown node type: ${String(node.type)}.`,
61
- );
62
- }
63
- if (node.type === 'html') {
64
- throw new MarkdownSafetyError('Raw HTML is not allowed in markdown.');
65
- }
66
- if (node.type === 'link' || node.type === 'figure') {
67
- assertSafeDestination(node.url);
68
- }
69
- if (node.type === 'heading') {
70
- if (previousHeadingDepth > 0 && node.depth > previousHeadingDepth + 1) {
71
- warnings.push({
72
- code: 'heading-depth-jump',
73
- message: `Heading depth jumps from ${previousHeadingDepth} to ${node.depth}.`,
74
- });
75
- }
76
- previousHeadingDepth = node.depth;
77
- }
78
- if (node.type === 'timeline') {
79
- for (const entry of node.entries) {
80
- if (!entry.date || !entry.label) {
81
- warnings.push({
82
- code: 'timeline-entry-shape',
83
- message: 'Timeline entries should use “date — label”.',
84
- });
85
- }
86
- }
87
- }
88
- });
89
-
90
- return warnings;
91
- }
92
-
93
- function parseBlocks(lines) {
94
- const blocks = [];
95
- let index = 0;
96
-
97
- while (index < lines.length) {
98
- if (!lines[index].trim()) {
99
- index += 1;
100
- continue;
101
- }
102
-
103
- const fence = lines[index].match(/^ {0,3}```\s*([^\s`]*)\s*$/);
104
- if (fence) {
105
- const language = fence[1].toLowerCase();
106
- const source = [];
107
- index += 1;
108
- while (index < lines.length && !/^ {0,3}```\s*$/.test(lines[index])) {
109
- source.push(lines[index]);
110
- index += 1;
111
- }
112
- if (index < lines.length) index += 1;
113
- blocks.push(fencedNode(language, source.join('\n')));
114
- continue;
115
- }
116
-
117
- const heading = lines[index].match(/^ {0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);
118
- if (heading) {
119
- blocks.push({
120
- type: 'heading',
121
- depth: heading[1].length,
122
- children: parseInline(heading[2]),
123
- });
124
- index += 1;
125
- continue;
126
- }
127
-
128
- const callout = lines[index].match(
129
- /^ {0,3}>\s*\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)$/i,
130
- );
131
- if (callout) {
132
- const content = [callout[2]];
133
- index += 1;
134
- while (index < lines.length) {
135
- const continuation = lines[index].match(/^ {0,3}>\s?(.*)$/);
136
- if (!continuation) break;
137
- content.push(continuation[1]);
138
- index += 1;
139
- }
140
- const kind = callout[1].toUpperCase();
141
- blocks.push({
142
- type: 'callout',
143
- kind: CALLOUT_TYPES.has(kind) ? kind.toLowerCase() : 'note',
144
- children: parseBlocks(content),
145
- });
146
- continue;
147
- }
148
-
149
- if (/^ {0,3}>/.test(lines[index])) {
150
- const content = [];
151
- while (index < lines.length) {
152
- const quote = lines[index].match(/^ {0,3}>\s?(.*)$/);
153
- if (!quote) break;
154
- content.push(quote[1]);
155
- index += 1;
156
- }
157
- blocks.push({ type: 'blockquote', children: parseBlocks(content) });
158
- continue;
159
- }
160
-
161
- if (isTableStart(lines, index)) {
162
- const header = splitTableRow(lines[index]).map(parseInline);
163
- index += 2;
164
- const rows = [];
165
- while (index < lines.length && isTableRow(lines[index])) {
166
- rows.push(splitTableRow(lines[index]).map(parseInline));
167
- index += 1;
168
- }
169
- blocks.push({ type: 'table', header, rows });
170
- continue;
171
- }
172
-
173
- const listMarker = matchListItem(lines[index]);
174
- if (listMarker) {
175
- const ordered = listMarker.ordered;
176
- const items = [];
177
- while (index < lines.length) {
178
- const item = matchListItem(lines[index]);
179
- if (!item || item.ordered !== ordered) break;
180
- const content = [item.content];
181
- index += 1;
182
- while (index < lines.length && !startsBlock(lines, index)) {
183
- content.push(lines[index].trim());
184
- index += 1;
185
- }
186
- const text = content.join(' ');
187
- const task = text.match(/^\[([ xX])\]\s+(.*)$/);
188
- items.push({
189
- type: 'listItem',
190
- checked: task ? task[1].toLowerCase() === 'x' : null,
191
- children: [
192
- {
193
- type: 'paragraph',
194
- children: parseInline(task?.[2] ?? text),
195
- },
196
- ],
197
- });
198
- }
199
- blocks.push({
200
- type: 'list',
201
- ordered,
202
- start: ordered ? listMarker.start : null,
203
- task: items.some((item) => item.checked !== null),
204
- children: items,
205
- });
206
- continue;
207
- }
208
-
209
- if (RAW_HTML_PATTERN.test(lines[index].trim())) {
210
- blocks.push({ type: 'html', value: lines[index] });
211
- index += 1;
212
- continue;
213
- }
214
-
215
- const paragraph = [lines[index].trim()];
216
- index += 1;
217
- while (index < lines.length && !startsBlock(lines, index)) {
218
- paragraph.push(lines[index].trim());
219
- index += 1;
220
- }
221
- blocks.push({
222
- type: 'paragraph',
223
- children: parseInline(paragraph.join(' ')),
224
- });
225
- }
226
-
227
- return blocks;
228
- }
229
-
230
- function fencedNode(language, value) {
231
- if (language === 'diagram') return { type: 'diagram', source: value };
232
- if (language === 'timeline') {
233
- return {
234
- type: 'timeline',
235
- entries: value.split('\n').map((line) => {
236
- const separator = line.indexOf(' — ');
237
- return separator < 0
238
- ? { date: '', label: line.trim() }
239
- : {
240
- date: line.slice(0, separator).trim(),
241
- label: line.slice(separator + 3).trim(),
242
- };
243
- }),
244
- };
245
- }
246
- return { type: 'code', language: language || null, value };
247
- }
248
-
249
- function parseInline(value) {
250
- const nodes = [];
251
- let remaining = value;
252
-
253
- while (remaining) {
254
- const token = nextInlineToken(remaining);
255
- if (!token) {
256
- nodes.push({ type: 'text', value: remaining });
257
- break;
258
- }
259
- if (token.index > 0) {
260
- nodes.push({ type: 'text', value: remaining.slice(0, token.index) });
261
- }
262
- nodes.push(token.node);
263
- remaining = remaining.slice(token.index + token.length);
264
- }
265
-
266
- return nodes;
267
- }
268
-
269
- function nextInlineToken(value) {
270
- const candidates = [
271
- matchDelimited(value, /`([^`\n]+)`/, (match) => ({
272
- type: 'inlineCode',
273
- value: match[1],
274
- })),
275
- matchDelimited(value, /~~(.+?)~~/, (match) => ({
276
- type: 'delete',
277
- children: parseInline(match[1]),
278
- })),
279
- matchDelimited(value, /\*\*(.+?)\*\*/, (match) => ({
280
- type: 'strong',
281
- children: parseInline(match[1]),
282
- })),
283
- matchDelimited(value, /(?<!\*)\*([^*\n]+)\*/, (match) => ({
284
- type: 'emphasis',
285
- children: parseInline(match[1]),
286
- })),
287
- matchDelimited(
288
- value,
289
- /!\[([^\]]*)\]\((\S+?)(?:\s+["']([^"']*)["'])?\)/,
290
- (match) => ({
291
- type: 'figure',
292
- alt: match[1],
293
- url: match[2],
294
- title: match[3] ?? null,
295
- }),
296
- ),
297
- matchDelimited(
298
- value,
299
- /\[([^\]]+)\]\((\S+?)(?:\s+["']([^"']*)["'])?\)/,
300
- (match) => ({
301
- type: 'link',
302
- url: match[2],
303
- title: match[3] ?? null,
304
- children: parseInline(match[1]),
305
- }),
306
- ),
307
- ].filter(Boolean);
308
-
309
- if (RAW_HTML_PATTERN.test(value)) {
310
- const match = value.match(RAW_HTML_PATTERN);
311
- candidates.push({
312
- index: match.index,
313
- length: match[0].length,
314
- node: { type: 'html', value: match[0] },
315
- });
316
- }
317
-
318
- return candidates.sort((left, right) => left.index - right.index)[0];
319
- }
320
-
321
- function matchDelimited(value, pattern, createNode) {
322
- const match = value.match(pattern);
323
- return match
324
- ? {
325
- index: match.index,
326
- length: match[0].length,
327
- node: createNode(match),
328
- }
329
- : null;
330
- }
331
-
332
- function visit(node, callback) {
333
- if (!node || typeof node !== 'object' || Array.isArray(node)) {
334
- throw new MarkdownSafetyError('Markdown AST contains an invalid node.');
335
- }
336
- callback(node);
337
- if (Array.isArray(node.children)) {
338
- for (const child of node.children) visit(child, callback);
339
- }
340
- if (node.type === 'table') {
341
- for (const cell of [...node.header, ...node.rows.flat()]) {
342
- for (const child of cell) visit(child, callback);
343
- }
344
- }
345
- }
346
-
347
- function assertSafeDestination(value) {
348
- if (typeof value !== 'string' || !value) {
349
- throw new MarkdownSafetyError('Markdown links require a destination.');
350
- }
351
- if (
352
- value.startsWith('/') ||
353
- value.startsWith('//') ||
354
- /^(?:javascript|data|file):/i.test(value)
355
- ) {
356
- throw new MarkdownSafetyError(
357
- `Unsafe markdown link destination: ${value}.`,
358
- );
359
- }
360
- if (/^[a-z][a-z\d+.-]*:/i.test(value) && !/^https:/i.test(value)) {
361
- throw new MarkdownSafetyError(
362
- `Absolute markdown links must use HTTPS: ${value}.`,
363
- );
364
- }
365
- }
366
-
367
- function isTableStart(lines, index) {
368
- return (
369
- index + 1 < lines.length &&
370
- isTableRow(lines[index]) &&
371
- /^\s*\|?\s*:?-{3,}:?\s*(?:\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(lines[index + 1])
372
- );
373
- }
374
-
375
- function isTableRow(line) {
376
- return line.includes('|') && line.trim() !== '';
377
- }
378
-
379
- function splitTableRow(line) {
380
- return line
381
- .trim()
382
- .replace(/^\|/, '')
383
- .replace(/\|$/, '')
384
- .split('|')
385
- .map((cell) => cell.trim());
386
- }
387
-
388
- function matchListItem(line) {
389
- const unordered = line.match(/^ {0,3}[-+*]\s+(.+)$/);
390
- if (unordered) {
391
- return { ordered: false, start: null, content: unordered[1] };
392
- }
393
- const ordered = line.match(/^ {0,3}(\d+)[.)]\s+(.+)$/);
394
- return ordered
395
- ? {
396
- ordered: true,
397
- start: Number.parseInt(ordered[1], 10),
398
- content: ordered[2],
399
- }
400
- : null;
401
- }
402
-
403
- function startsBlock(lines, index) {
404
- const line = lines[index];
405
- return (
406
- !line.trim() ||
407
- /^ {0,3}```/.test(line) ||
408
- /^ {0,3}#{1,6}\s/.test(line) ||
409
- /^ {0,3}>/.test(line) ||
410
- Boolean(matchListItem(line)) ||
411
- isTableStart(lines, index) ||
412
- RAW_HTML_PATTERN.test(line.trim())
413
- );
414
- }
@@ -1,54 +0,0 @@
1
- const SUCCESSFUL_STAGE_STATUSES = new Set(['passed', 'warned', 'skipped']);
2
-
3
- export function assertManifestPublishable(manifest, { buildRecord } = {}) {
4
- const outcome = manifest?.outcome;
5
- const reviewFlagged = (manifest?.warnings ?? []).some((warning) =>
6
- String(warning).startsWith('visual-review-required:'),
7
- );
8
- const durableClean = outcome === 'built-durable' && !reviewFlagged;
9
- const inFlightClean =
10
- outcome === 'incomplete' &&
11
- !reviewFlagged &&
12
- isCleanPublicationTransition(buildRecord);
13
-
14
- if (!durableClean && !inFlightClean) {
15
- throw publicationOutcomeError(
16
- `Manifest outcome ${String(outcome ?? 'missing')} is not eligible for publication.`,
17
- );
18
- }
19
- return manifest;
20
- }
21
-
22
- function isCleanPublicationTransition(buildRecord) {
23
- if (
24
- !buildRecord ||
25
- buildRecord.outcome !== 'incomplete' ||
26
- !Array.isArray(buildRecord.stages)
27
- ) {
28
- return false;
29
- }
30
- const publishIndex = buildRecord.stages.findIndex(
31
- ({ id }) => id === 'publish',
32
- );
33
- if (
34
- publishIndex < 0 ||
35
- buildRecord.stages[publishIndex]?.status !== 'running'
36
- ) {
37
- return false;
38
- }
39
- return buildRecord.stages
40
- .slice(0, publishIndex)
41
- .every(
42
- ({ status, warnings = [] }) =>
43
- SUCCESSFUL_STAGE_STATUSES.has(status) &&
44
- !warnings.some((warning) =>
45
- String(warning).startsWith('visual-review-required:'),
46
- ),
47
- );
48
- }
49
-
50
- function publicationOutcomeError(message) {
51
- const error = new Error(message);
52
- error.code = 'E_PUBLISH_OUTCOME';
53
- return error;
54
- }