@open-agent-toolkit/cli 0.3.10 → 0.3.11
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 +2 -1
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/meta.json +13 -0
- package/assets/docs/cli-utilities/tool-packs.md +8 -2
- package/assets/docs/cli-utilities/workflow-gates.md +13 -0
- package/assets/docs/contributing/code.md +8 -2
- package/assets/docs/contributing/documentation.md +7 -1
- package/assets/docs/contributing/meta.json +15 -0
- package/assets/docs/docs-tooling/add-docs-to-a-repo.md +14 -5
- package/assets/docs/docs-tooling/commands.md +26 -8
- package/assets/docs/docs-tooling/meta.json +4 -0
- package/assets/docs/docs-tooling/workflows.md +2 -2
- package/assets/docs/guide/meta.json +4 -0
- package/assets/docs/meta.json +14 -0
- package/assets/docs/provider-sync/instruction-sync.md +8 -0
- package/assets/docs/provider-sync/meta.json +11 -0
- package/assets/docs/provider-sync/scope-and-surface.md +3 -4
- package/assets/docs/reference/cli-reference.md +5 -2
- package/assets/docs/reference/docs-index-contract.md +22 -6
- package/assets/docs/reference/file-locations.md +7 -2
- package/assets/docs/reference/index.md +1 -1
- package/assets/docs/reference/meta.json +10 -0
- package/assets/docs/reference/troubleshooting.md +41 -6
- package/assets/docs/workflows/ideas/meta.json +4 -0
- package/assets/docs/workflows/meta.json +4 -0
- package/assets/docs/workflows/projects/cursor-cloud.md +8 -3
- package/assets/docs/workflows/projects/evidence-layers.md +6 -8
- package/assets/docs/workflows/projects/implementation-execution.md +30 -4
- package/assets/docs/workflows/projects/lifecycle.md +7 -1
- package/assets/docs/workflows/projects/meta.json +25 -0
- package/assets/docs/workflows/projects/orchestration-model.md +5 -6
- package/assets/docs/workflows/skills/meta.json +10 -0
- package/assets/docs/workflows/skills/recon.md +28 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-cursor-cloud-projects/SKILL.md +30 -16
- package/assets/skills/oat-dispatch-subagents/SKILL.md +4 -12
- package/assets/skills/oat-dispatch-subagents/references/managed-claude-example.json +1 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-codex.md +51 -0
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +8 -7
- package/assets/skills/oat-docs-analyze/SKILL.md +28 -3
- package/assets/skills/oat-docs-apply/SKILL.md +3 -3
- package/assets/skills/oat-docs-authoring/SKILL.md +1 -1
- package/assets/skills/oat-docs-authoring/references/oat-fumadocs-contract.md +5 -2
- package/assets/skills/oat-docs-bootstrap/SKILL.md +4 -3
- package/assets/skills/oat-docs-bootstrap/assets/AGENTS.md.template +3 -3
- package/assets/skills/oat-pjm-decision/SKILL.md +3 -2
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +4 -4
- package/assets/skills/oat-project-complete/SKILL.md +47 -2
- package/assets/skills/oat-project-design/SKILL.md +10 -6
- package/assets/skills/oat-project-discover/SKILL.md +3 -3
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +3 -10
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +135 -3
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +7 -9
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/references/plan-and-resume.md +1 -1
- package/assets/skills/oat-project-import-plan/SKILL.md +3 -3
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-new/SKILL.md +3 -3
- package/assets/skills/oat-project-next/SKILL.md +50 -7
- package/assets/skills/oat-project-plan/SKILL.md +4 -4
- package/assets/skills/oat-project-plan-writing/SKILL.md +2 -2
- package/assets/skills/oat-project-pr-final/SKILL.md +11 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-promote-spec-driven/SKILL.md +2 -2
- package/assets/skills/oat-project-quick-start/SKILL.md +12 -8
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-retro/SKILL.md +6 -3
- package/assets/skills/oat-project-review-provide/SKILL.md +2 -2
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +2 -2
- package/assets/skills/oat-project-spec/SKILL.md +3 -3
- package/assets/skills/oat-project-summary/SKILL.md +22 -3
- package/assets/skills/oat-repo-improve/SKILL.md +2 -2
- package/assets/skills/recon/SKILL.md +24 -3
- package/assets/skills/recon/references/packet-contract.md +36 -6
- package/assets/skills/recon/references/profiles.md +3 -0
- package/assets/skills/recon/references/worker-contract.md +16 -3
- package/assets/skills/recon/scripts/create-review-brief.mjs +17 -86
- package/assets/skills/recon/scripts/lib/contracts.mjs +158 -41
- package/assets/skills/recon/scripts/lib/review-binding.mjs +123 -0
- package/assets/skills/recon/scripts/lib/routing.mjs +5 -2
- package/assets/skills/recon/scripts/reconcile-ledger.mjs +18 -7
- package/assets/skills/recon/scripts/render-packet.mjs +93 -1
- package/assets/skills/recon/scripts/validate-packet.mjs +119 -88
- package/assets/templates/state.md +1 -0
- package/dist/commands/backlog/new.d.ts +2 -2
- package/dist/commands/backlog/new.d.ts.map +1 -1
- package/dist/commands/backlog/new.js +2 -2
- package/dist/commands/decision/new.d.ts +2 -2
- package/dist/commands/decision/new.d.ts.map +1 -1
- package/dist/commands/decision/new.js +2 -2
- package/dist/commands/docs/nav/contents.d.ts +9 -0
- package/dist/commands/docs/nav/contents.d.ts.map +1 -1
- package/dist/commands/docs/nav/contents.js +7 -2
- package/dist/commands/docs/nav/fumadocs.d.ts +51 -0
- package/dist/commands/docs/nav/fumadocs.d.ts.map +1 -0
- package/dist/commands/docs/nav/fumadocs.js +301 -0
- package/dist/commands/docs/nav/sync.d.ts +31 -1
- package/dist/commands/docs/nav/sync.d.ts.map +1 -1
- package/dist/commands/docs/nav/sync.js +163 -6
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/instructions/instructions.utils.d.ts +19 -0
- package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
- package/dist/commands/instructions/instructions.utils.js +89 -17
- package/dist/commands/instructions/sync/sync.d.ts.map +1 -1
- package/dist/commands/instructions/sync/sync.js +49 -2
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +2 -2
- package/dist/commands/project/closeout-check/closeout-invariant.d.ts +97 -0
- package/dist/commands/project/closeout-check/closeout-invariant.d.ts.map +1 -0
- package/dist/commands/project/closeout-check/closeout-invariant.js +301 -0
- package/dist/commands/project/closeout-check/index.d.ts +38 -0
- package/dist/commands/project/closeout-check/index.d.ts.map +1 -0
- package/dist/commands/project/closeout-check/index.js +117 -0
- package/dist/commands/project/complete-state/index.d.ts +4 -0
- package/dist/commands/project/complete-state/index.d.ts.map +1 -1
- package/dist/commands/project/complete-state/index.js +11 -13
- package/dist/commands/project/dispatch/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch/index.js +6 -30
- package/dist/commands/project/dispatch/record.d.ts +9 -18
- package/dist/commands/project/dispatch/record.d.ts.map +1 -1
- package/dist/commands/project/dispatch/record.js +15 -212
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +2 -0
- package/dist/commands/project/new/scaffold.d.ts +0 -1
- package/dist/commands/project/new/scaffold.d.ts.map +1 -1
- package/dist/commands/project/new/scaffold.js +19 -20
- package/dist/commands/project/promote/promote.d.ts +2 -2
- package/dist/commands/project/promote/promote.d.ts.map +1 -1
- package/dist/commands/project/promote/promote.js +13 -11
- package/dist/commands/shared/frontmatter.d.ts +21 -0
- package/dist/commands/shared/frontmatter.d.ts.map +1 -1
- package/dist/commands/shared/frontmatter.js +70 -4
- package/dist/commands/shared/template-source.d.ts +29 -0
- package/dist/commands/shared/template-source.d.ts.map +1 -0
- package/dist/commands/{pjm → shared}/template-source.js +24 -7
- package/dist/commands/state/generate.js +2 -2
- package/dist/commands/template/index.d.ts +10 -0
- package/dist/commands/template/index.d.ts.map +1 -0
- package/dist/commands/template/index.js +87 -0
- package/dist/commands/template/resolve.d.ts +31 -0
- package/dist/commands/template/resolve.d.ts.map +1 -0
- package/dist/commands/template/resolve.js +86 -0
- package/dist/fs/io.d.ts +0 -41
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +2 -414
- package/dist/providers/identity/absolute-paths.d.ts +4 -13
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -1
- package/dist/providers/identity/absolute-paths.js +4 -17
- package/dist/providers/identity/generic-dispatch-record.d.ts +1 -1
- package/dist/providers/identity/generic-dispatch-record.js +2 -2
- package/dist/providers/identity/oat-dispatch-record.d.ts +4 -357
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -1
- package/dist/providers/identity/oat-dispatch-record.js +4 -236
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +12 -4
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +32 -6
- package/package.json +2 -2
- package/dist/commands/pjm/template-source.d.ts +0 -14
- package/dist/commands/pjm/template-source.d.ts.map +0 -1
|
@@ -6,6 +6,12 @@ import { join, resolve } from 'node:path';
|
|
|
6
6
|
|
|
7
7
|
import { hashFile } from './lib/canonical-json.mjs';
|
|
8
8
|
import { isDirectExecution } from './lib/cli-entry.mjs';
|
|
9
|
+
import {
|
|
10
|
+
affirmingDispositionByReviewKind,
|
|
11
|
+
classifyUnresolvedIssue,
|
|
12
|
+
requiredReviewKinds,
|
|
13
|
+
unresolvedIssuesBlockClaim,
|
|
14
|
+
} from './lib/contracts.mjs';
|
|
9
15
|
import {
|
|
10
16
|
assertSafeExistingPath,
|
|
11
17
|
assertSafeOutputPath,
|
|
@@ -99,7 +105,7 @@ function intendedRoutingSection(manifest, routing) {
|
|
|
99
105
|
'',
|
|
100
106
|
`- **Manifest routing version:** ${routing.sourceSchemaVersion}`,
|
|
101
107
|
`- **Approved authority:** ${escapeInline(routing.authority)}`,
|
|
102
|
-
`- **Approved limits:** ${routing.waves.length} waves; ${routing.waves.reduce((count, wave) => count + wave.lanes.length, 0)} lanes; concurrency ${routing.maxConcurrency}; deadline ${routing.deadlineSeconds}s; retries ${routing.retryLimit}`,
|
|
108
|
+
`- **Approved limits:** ${routing.waves.length} waves; ${routing.waves.reduce((count, wave) => count + wave.lanes.length, 0)} lanes; concurrency ${routing.maxConcurrency}; deadline ${routing.deadlineSeconds}s; pre-acceptance admission retries per lane ${routing.retryLimit}`,
|
|
103
109
|
'- **Evidence boundary:** These are normalized approved intended targets and root-recorded condition dispositions. They are not launcher receipts or observations of native runtime identity, usage, cost, or conclusion correctness.',
|
|
104
110
|
'',
|
|
105
111
|
'### Waves',
|
|
@@ -115,6 +121,88 @@ function intendedRoutingSection(manifest, routing) {
|
|
|
115
121
|
];
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
// The required reviews that gave `claimId` no disposition at all. Such a
|
|
125
|
+
// claim stays below `verified`, like an uncertain one, and is listed as not
|
|
126
|
+
// reviewed.
|
|
127
|
+
function omittedReviews(claimId, reviews) {
|
|
128
|
+
return requiredReviewKinds
|
|
129
|
+
.map((kind) => reviews.find((review) => review.reviewKind === kind))
|
|
130
|
+
.filter(
|
|
131
|
+
(review) =>
|
|
132
|
+
review &&
|
|
133
|
+
!(review.dispositions ?? []).some((item) => item.claimId === claimId),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function issueText(entry) {
|
|
138
|
+
return typeof entry === 'string' ? entry : (entry?.text ?? '');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Every claim an incorporated review kept below `verified` (an unresolved
|
|
142
|
+
// issue that applies to it, a coverage finding that names it, a
|
|
143
|
+
// non-affirming disposition, or a required review that left it without a
|
|
144
|
+
// disposition), with the review's own words. Key-claim status
|
|
145
|
+
// alone would let a `complete` packet hide a downgraded non-key claim.
|
|
146
|
+
function reviewDowngradeLines(validatedRun) {
|
|
147
|
+
const { ledger, artifacts, assuranceReviewIds } = validatedRun;
|
|
148
|
+
const assurance = new Set(assuranceReviewIds);
|
|
149
|
+
const reviews = artifacts
|
|
150
|
+
.map(({ value }) => value)
|
|
151
|
+
.filter(
|
|
152
|
+
(value) =>
|
|
153
|
+
value.kind === 'recon.review-result' && assurance.has(value.id),
|
|
154
|
+
);
|
|
155
|
+
const lines = [];
|
|
156
|
+
for (const claim of ledger.claims) {
|
|
157
|
+
if (claim.status === 'verified') continue;
|
|
158
|
+
const reasons = [];
|
|
159
|
+
for (const review of reviews) {
|
|
160
|
+
const disposition = (review.dispositions ?? []).find(
|
|
161
|
+
(item) => item.claimId === claim.id,
|
|
162
|
+
);
|
|
163
|
+
if (!disposition) continue;
|
|
164
|
+
if (
|
|
165
|
+
disposition.disposition !==
|
|
166
|
+
affirmingDispositionByReviewKind[review.reviewKind]
|
|
167
|
+
) {
|
|
168
|
+
reasons.push(`${review.reviewKind} review: ${disposition.disposition}`);
|
|
169
|
+
}
|
|
170
|
+
if (unresolvedIssuesBlockClaim(review, claim.id)) {
|
|
171
|
+
for (const entry of review.unresolvedIssues) {
|
|
172
|
+
const classification = classifyUnresolvedIssue(entry);
|
|
173
|
+
if (
|
|
174
|
+
classification.scope === 'claims' &&
|
|
175
|
+
!classification.claimIds.includes(claim.id)
|
|
176
|
+
) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const scope =
|
|
180
|
+
classification.scope === 'claims' ? 'issue' : 'global issue';
|
|
181
|
+
reasons.push(`${review.reviewKind} ${scope}: ${issueText(entry)}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
for (const review of omittedReviews(claim.id, reviews)) {
|
|
186
|
+
reasons.push(
|
|
187
|
+
`${review.reviewKind} review: not reviewed (no disposition)`,
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
for (const review of reviews) {
|
|
191
|
+
for (const finding of review.coverageFindings ?? []) {
|
|
192
|
+
if (!finding.claimIds.includes(claim.id)) continue;
|
|
193
|
+
reasons.push(
|
|
194
|
+
`${finding.material ? 'material ' : ''}coverage finding ${finding.code}: ${finding.message}`,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (reasons.length === 0) continue;
|
|
199
|
+
lines.push(
|
|
200
|
+
`**${escapeInline(claim.id)}** (${escapeInline(claim.status)}): ${escapeInline(claim.statement)} — ${reasons.map(escapeInline).join('; ')}`,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return lines;
|
|
204
|
+
}
|
|
205
|
+
|
|
118
206
|
export function renderPacketDocument(validatedRun) {
|
|
119
207
|
const { manifest, ledger, routing } = assertValidatedRun(validatedRun);
|
|
120
208
|
const evidenceById = new Map(
|
|
@@ -186,6 +274,10 @@ export function renderPacketDocument(validatedRun) {
|
|
|
186
274
|
),
|
|
187
275
|
),
|
|
188
276
|
'',
|
|
277
|
+
'## Review Downgrades',
|
|
278
|
+
'',
|
|
279
|
+
...bulletLines(reviewDowngradeLines(validatedRun)),
|
|
280
|
+
'',
|
|
189
281
|
'## Unresolved Questions',
|
|
190
282
|
'',
|
|
191
283
|
...bulletLines(
|
|
@@ -3,15 +3,20 @@
|
|
|
3
3
|
import { readFile, rm } from 'node:fs/promises';
|
|
4
4
|
import { join, resolve } from 'node:path';
|
|
5
5
|
|
|
6
|
+
import { createReviewBrief } from './create-review-brief.mjs';
|
|
6
7
|
import { hashCanonicalJson, hashFile, sha256 } from './lib/canonical-json.mjs';
|
|
7
8
|
import { isDirectExecution } from './lib/cli-entry.mjs';
|
|
8
9
|
import {
|
|
10
|
+
affirmingDispositionByReviewKind,
|
|
9
11
|
isDigest,
|
|
10
12
|
isObject,
|
|
11
13
|
issue,
|
|
12
14
|
profiles,
|
|
15
|
+
requiredReviewKinds,
|
|
16
|
+
unresolvedIssuesBlockClaim,
|
|
13
17
|
validateArtifactShape,
|
|
14
18
|
} from './lib/contracts.mjs';
|
|
19
|
+
import { reviewBriefEntries } from './lib/review-binding.mjs';
|
|
15
20
|
import { normalizeManifestRouting } from './lib/routing.mjs';
|
|
16
21
|
import {
|
|
17
22
|
assertCanonicalRoot,
|
|
@@ -1318,44 +1323,69 @@ function resolveTerminalReconciliation(
|
|
|
1318
1323
|
};
|
|
1319
1324
|
}
|
|
1320
1325
|
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
const evidenceById = new Map(ledger.evidence.map((item) => [item.id, item]));
|
|
1334
|
-
const expectedEvidence = claim.evidence.map((link) => {
|
|
1335
|
-
const evidence = evidenceById.get(link.evidenceId);
|
|
1336
|
-
return evidence
|
|
1337
|
-
? {
|
|
1338
|
-
id: evidence.id,
|
|
1339
|
-
sourceId: evidence.sourceId,
|
|
1340
|
-
displayExcerpt: evidence.displayExcerpt,
|
|
1341
|
-
locator: evidence.locator,
|
|
1342
|
-
}
|
|
1343
|
-
: null;
|
|
1344
|
-
});
|
|
1345
|
-
if (
|
|
1346
|
-
expectedEvidence.some((item) => !item) ||
|
|
1347
|
-
hashCanonicalJson(projected.evidence) !==
|
|
1348
|
-
hashCanonicalJson(expectedEvidence)
|
|
1349
|
-
) {
|
|
1350
|
-
return false;
|
|
1351
|
-
}
|
|
1352
|
-
const sourceIds = new Set(expectedEvidence.map((item) => item.sourceId));
|
|
1353
|
-
const expectedSources = manifest.sources.filter((source) =>
|
|
1354
|
-
sourceIds.has(source.id),
|
|
1355
|
-
);
|
|
1356
|
-
return (
|
|
1357
|
-
hashCanonicalJson(brief.sources) === hashCanonicalJson(expectedSources)
|
|
1326
|
+
// Brief integrity is one check: rebuild the brief with the production
|
|
1327
|
+
// generator from the prior ledger and the manifest, for the claim IDs it
|
|
1328
|
+
// lists, and require identical canonical JSON. Any edited, injected,
|
|
1329
|
+
// duplicated, or unprojected field differs, so no field-by-field binding is
|
|
1330
|
+
// needed. Briefs stay blind because the generator is the only projection.
|
|
1331
|
+
function checkReviewBrief(
|
|
1332
|
+
brief,
|
|
1333
|
+
reviewKind,
|
|
1334
|
+
{ manifest, ledger, rebuildReviewBrief = createReviewBrief },
|
|
1335
|
+
) {
|
|
1336
|
+
const entryIds = reviewBriefEntries(brief, reviewKind).map(
|
|
1337
|
+
(entry) => entry?.id,
|
|
1358
1338
|
);
|
|
1339
|
+
let rebuilt;
|
|
1340
|
+
try {
|
|
1341
|
+
rebuilt = rebuildReviewBrief({
|
|
1342
|
+
id: brief.id,
|
|
1343
|
+
mode: brief.mode,
|
|
1344
|
+
createdAt: brief.createdAt,
|
|
1345
|
+
manifest,
|
|
1346
|
+
ledger,
|
|
1347
|
+
claimIds: entryIds,
|
|
1348
|
+
});
|
|
1349
|
+
} catch (error) {
|
|
1350
|
+
return {
|
|
1351
|
+
ok: false,
|
|
1352
|
+
entryIds,
|
|
1353
|
+
reason: `rebuild failed: ${error instanceof Error ? error.message : error}`,
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
if (hashCanonicalJson(rebuilt) === hashCanonicalJson(brief)) {
|
|
1357
|
+
return { ok: true, entryIds };
|
|
1358
|
+
}
|
|
1359
|
+
const keys = [...new Set([...Object.keys(brief), ...Object.keys(rebuilt)])]
|
|
1360
|
+
.sort()
|
|
1361
|
+
.filter(
|
|
1362
|
+
(key) =>
|
|
1363
|
+
!Object.hasOwn(brief, key) ||
|
|
1364
|
+
!Object.hasOwn(rebuilt, key) ||
|
|
1365
|
+
hashCanonicalJson(brief[key]) !== hashCanonicalJson(rebuilt[key]),
|
|
1366
|
+
);
|
|
1367
|
+
return { ok: false, entryIds, reason: `differs at ${keys[0]}` };
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
// One rebuild per distinct brief per validation pass. The key is the exact
|
|
1371
|
+
// artifact reference (path and digest) plus the review kind that selects the
|
|
1372
|
+
// brief's entries; the cache lives only as long as this pass's checker.
|
|
1373
|
+
function createBriefChecker({ manifest, ledger, rebuildReviewBrief }) {
|
|
1374
|
+
const results = new Map();
|
|
1375
|
+
return (briefEntry, reviewKind) => {
|
|
1376
|
+
const key = `${briefEntry.reference?.path}\u0000${briefEntry.reference?.digest}\u0000${reviewKind}`;
|
|
1377
|
+
if (!results.has(key)) {
|
|
1378
|
+
results.set(
|
|
1379
|
+
key,
|
|
1380
|
+
checkReviewBrief(briefEntry.value, reviewKind, {
|
|
1381
|
+
manifest,
|
|
1382
|
+
ledger,
|
|
1383
|
+
rebuildReviewBrief,
|
|
1384
|
+
}),
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
return results.get(key);
|
|
1388
|
+
};
|
|
1359
1389
|
}
|
|
1360
1390
|
|
|
1361
1391
|
function validateReviewBindings(
|
|
@@ -1365,6 +1395,7 @@ function validateReviewBindings(
|
|
|
1365
1395
|
artifactsByPath,
|
|
1366
1396
|
reconciliationContext,
|
|
1367
1397
|
errors,
|
|
1398
|
+
checkBrief,
|
|
1368
1399
|
) {
|
|
1369
1400
|
const claims = new Map(ledger.claims.map((claim) => [claim.id, claim]));
|
|
1370
1401
|
const priorLedger = reconciliationContext.priorLedger;
|
|
@@ -1378,11 +1409,12 @@ function validateReviewBindings(
|
|
|
1378
1409
|
) {
|
|
1379
1410
|
continue;
|
|
1380
1411
|
}
|
|
1381
|
-
const
|
|
1412
|
+
const briefEntry = [...artifactsByPath.values()].find(
|
|
1382
1413
|
({ reference, value }) =>
|
|
1383
1414
|
sameReference(reference, result.brief) &&
|
|
1384
1415
|
value.kind === 'recon.review-brief',
|
|
1385
|
-
)
|
|
1416
|
+
);
|
|
1417
|
+
const brief = briefEntry?.value;
|
|
1386
1418
|
const expectedMode =
|
|
1387
1419
|
result.reviewKind === 'semantic' ||
|
|
1388
1420
|
result.reviewKind === 'redundant-verification'
|
|
@@ -1401,27 +1433,26 @@ function validateReviewBindings(
|
|
|
1401
1433
|
);
|
|
1402
1434
|
continue;
|
|
1403
1435
|
}
|
|
1436
|
+
const check = checkBrief(briefEntry, result.reviewKind);
|
|
1437
|
+
if (!check.ok) {
|
|
1438
|
+
errors.push(
|
|
1439
|
+
issue(
|
|
1440
|
+
'REVIEW_BRIEF_MISMATCH',
|
|
1441
|
+
`Review ${result.id} brief is not the production brief rebuilt from the prior ledger and manifest (${check.reason})`,
|
|
1442
|
+
result.id,
|
|
1443
|
+
),
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1404
1446
|
const seen = new Set();
|
|
1405
1447
|
for (const disposition of result.dispositions) {
|
|
1406
|
-
const currentClaim = claims.get(disposition.claimId);
|
|
1407
|
-
const priorClaim = priorClaims.get(disposition.claimId);
|
|
1408
|
-
const claim = priorClaim ?? currentClaim;
|
|
1409
|
-
const bindingLedger = priorClaim ? priorLedger : ledger;
|
|
1410
1448
|
if (
|
|
1411
|
-
!claim ||
|
|
1412
1449
|
seen.has(disposition.claimId) ||
|
|
1413
|
-
!
|
|
1414
|
-
brief,
|
|
1415
|
-
result.reviewKind,
|
|
1416
|
-
claim,
|
|
1417
|
-
bindingLedger,
|
|
1418
|
-
manifest,
|
|
1419
|
-
)
|
|
1450
|
+
!check.entryIds.includes(disposition.claimId)
|
|
1420
1451
|
) {
|
|
1421
1452
|
errors.push(
|
|
1422
1453
|
issue(
|
|
1423
1454
|
'REVIEW_BRIEF_MISMATCH',
|
|
1424
|
-
`Review ${result.id} dispositions must
|
|
1455
|
+
`Review ${result.id} dispositions must be unique members of its brief's claims`,
|
|
1425
1456
|
result.id,
|
|
1426
1457
|
),
|
|
1427
1458
|
);
|
|
@@ -1869,16 +1900,13 @@ function validateReconciliation(
|
|
|
1869
1900
|
);
|
|
1870
1901
|
}
|
|
1871
1902
|
if (disposition?.disposition === 'accepted-gap') {
|
|
1903
|
+
// A material finding forces every named claim below `verified`, the
|
|
1904
|
+
// same downgrade the reconciler applies. The reviewer's per-statement
|
|
1905
|
+
// disposition may stay `covered`: a question omission is not a
|
|
1906
|
+
// statement defect.
|
|
1872
1907
|
for (const claimId of finding.claimIds) {
|
|
1873
1908
|
const claim = currentClaims.get(claimId);
|
|
1874
|
-
|
|
1875
|
-
(item) => item.claimId === claimId,
|
|
1876
|
-
);
|
|
1877
|
-
if (
|
|
1878
|
-
finding.material === true &&
|
|
1879
|
-
(claim?.status === 'verified' ||
|
|
1880
|
-
coverageDisposition?.disposition !== 'gap')
|
|
1881
|
-
) {
|
|
1909
|
+
if (finding.material === true && claim?.status === 'verified') {
|
|
1882
1910
|
errors.push(
|
|
1883
1911
|
issue(
|
|
1884
1912
|
'MATERIAL_COVERAGE_ASSURANCE_EXCEEDED',
|
|
@@ -1969,7 +1997,7 @@ function validateDerivedSourceGaps(manifest, ledger, errors) {
|
|
|
1969
1997
|
}
|
|
1970
1998
|
}
|
|
1971
1999
|
|
|
1972
|
-
function validateAssurance(validatedRun, errors) {
|
|
2000
|
+
function validateAssurance(validatedRun, errors, checkBrief) {
|
|
1973
2001
|
const { manifest, ledger, achievedProfile } = validatedRun;
|
|
1974
2002
|
const exactEvidence = new Set(validatedRun.exactEvidenceIds);
|
|
1975
2003
|
const assuranceReviewIds = new Set(validatedRun.assuranceReviewIds);
|
|
@@ -1979,9 +2007,6 @@ function validateAssurance(validatedRun, errors) {
|
|
|
1979
2007
|
const evidenceById = new Map(
|
|
1980
2008
|
(ledger.evidence ?? []).map((item) => [item.id, item]),
|
|
1981
2009
|
);
|
|
1982
|
-
const priorClaims = new Map(
|
|
1983
|
-
(validatedRun.priorLedger?.claims ?? []).map((claim) => [claim.id, claim]),
|
|
1984
|
-
);
|
|
1985
2010
|
const claimIds = new Set((ledger.claims ?? []).map((claim) => claim.id));
|
|
1986
2011
|
for (const claimId of ledger.synthesis?.keyClaimIds ?? []) {
|
|
1987
2012
|
if (!claimIds.has(claimId)) {
|
|
@@ -2056,14 +2081,12 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2056
2081
|
),
|
|
2057
2082
|
);
|
|
2058
2083
|
}
|
|
2059
|
-
const required = new Map(
|
|
2060
|
-
[
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
required.set('redundant-verification', 'affirmed');
|
|
2066
|
-
}
|
|
2084
|
+
const required = new Map(
|
|
2085
|
+
[
|
|
2086
|
+
...requiredReviewKinds,
|
|
2087
|
+
...(achievedProfile === 'thorough' ? ['redundant-verification'] : []),
|
|
2088
|
+
].map((kind) => [kind, affirmingDispositionByReviewKind[kind]]),
|
|
2089
|
+
);
|
|
2067
2090
|
const satisfied = new Set();
|
|
2068
2091
|
const reviewerLanes = new Set();
|
|
2069
2092
|
for (const reviewId of new Set(claim.reviewIds ?? [])) {
|
|
@@ -2128,11 +2151,12 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2128
2151
|
);
|
|
2129
2152
|
}
|
|
2130
2153
|
reviewerLanes.add(artifact.reviewerLane);
|
|
2131
|
-
const
|
|
2154
|
+
const briefEntry = [...artifactsById.values()].find(
|
|
2132
2155
|
({ reference, value }) =>
|
|
2133
2156
|
sameReference(reference, artifact.brief) &&
|
|
2134
2157
|
value.kind === 'recon.review-brief',
|
|
2135
|
-
)
|
|
2158
|
+
);
|
|
2159
|
+
const brief = briefEntry?.value;
|
|
2136
2160
|
const expectedMode =
|
|
2137
2161
|
artifact.reviewKind === 'semantic' ||
|
|
2138
2162
|
artifact.reviewKind === 'redundant-verification'
|
|
@@ -2141,17 +2165,15 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2141
2165
|
artifact.reviewKind === 'contradiction-resolution'
|
|
2142
2166
|
? 'adversary'
|
|
2143
2167
|
: 'coverage';
|
|
2168
|
+
const briefCheck = brief
|
|
2169
|
+
? checkBrief(briefEntry, artifact.reviewKind)
|
|
2170
|
+
: null;
|
|
2144
2171
|
if (
|
|
2145
2172
|
!brief ||
|
|
2146
2173
|
brief.runId !== ledger.runId ||
|
|
2147
2174
|
brief.mode !== expectedMode ||
|
|
2148
|
-
!
|
|
2149
|
-
|
|
2150
|
-
artifact.reviewKind,
|
|
2151
|
-
priorClaims.get(claim.id) ?? claim,
|
|
2152
|
-
priorClaims.has(claim.id) ? validatedRun.priorLedger : ledger,
|
|
2153
|
-
manifest,
|
|
2154
|
-
) ||
|
|
2175
|
+
!briefCheck.ok ||
|
|
2176
|
+
!briefCheck.entryIds.includes(claim.id) ||
|
|
2155
2177
|
!artifact.permittedInputs?.some((reference) =>
|
|
2156
2178
|
sameReference(reference, artifact.brief),
|
|
2157
2179
|
)
|
|
@@ -2168,9 +2190,7 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2168
2190
|
(item) => item.claimId === claim.id,
|
|
2169
2191
|
);
|
|
2170
2192
|
const expectedDisposition =
|
|
2171
|
-
artifact.reviewKind
|
|
2172
|
-
? 'resolved'
|
|
2173
|
-
: required.get(artifact.reviewKind);
|
|
2193
|
+
affirmingDispositionByReviewKind[artifact.reviewKind];
|
|
2174
2194
|
if (
|
|
2175
2195
|
dispositions.length !== 1 ||
|
|
2176
2196
|
dispositions[0].disposition !== expectedDisposition
|
|
@@ -2183,11 +2203,11 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2183
2203
|
),
|
|
2184
2204
|
);
|
|
2185
2205
|
}
|
|
2186
|
-
if ((artifact
|
|
2206
|
+
if (unresolvedIssuesBlockClaim(artifact, claim.id)) {
|
|
2187
2207
|
errors.push(
|
|
2188
2208
|
issue(
|
|
2189
2209
|
'REVIEW_DISPOSITION_MISMATCH',
|
|
2190
|
-
`Review ${reviewId} retains unresolved
|
|
2210
|
+
`Review ${reviewId} retains an unresolved issue that applies to this claim`,
|
|
2191
2211
|
claim.id,
|
|
2192
2212
|
),
|
|
2193
2213
|
);
|
|
@@ -2280,7 +2300,12 @@ function validateAssurance(validatedRun, errors) {
|
|
|
2280
2300
|
}
|
|
2281
2301
|
}
|
|
2282
2302
|
|
|
2283
|
-
|
|
2303
|
+
// `rebuildReviewBrief` is a test seam for counting brief rebuilds; production
|
|
2304
|
+
// callers use the default generator.
|
|
2305
|
+
export async function compileValidatedRun(
|
|
2306
|
+
packetDirectory,
|
|
2307
|
+
{ rebuildReviewBrief = createReviewBrief } = {},
|
|
2308
|
+
) {
|
|
2284
2309
|
const packetRoot = resolve(packetDirectory);
|
|
2285
2310
|
const errors = [];
|
|
2286
2311
|
const warnings = [];
|
|
@@ -2532,6 +2557,11 @@ export async function compileValidatedRun(packetDirectory) {
|
|
|
2532
2557
|
errors,
|
|
2533
2558
|
);
|
|
2534
2559
|
}
|
|
2560
|
+
const checkBrief = createBriefChecker({
|
|
2561
|
+
manifest,
|
|
2562
|
+
ledger: reconciliationContext.priorLedger ?? ledger,
|
|
2563
|
+
rebuildReviewBrief,
|
|
2564
|
+
});
|
|
2535
2565
|
validateReviewBindings(
|
|
2536
2566
|
manifest,
|
|
2537
2567
|
ledger,
|
|
@@ -2539,6 +2569,7 @@ export async function compileValidatedRun(packetDirectory) {
|
|
|
2539
2569
|
artifactsByPath,
|
|
2540
2570
|
reconciliationContext,
|
|
2541
2571
|
errors,
|
|
2572
|
+
checkBrief,
|
|
2542
2573
|
);
|
|
2543
2574
|
validateReconciliation(
|
|
2544
2575
|
manifest,
|
|
@@ -2586,7 +2617,7 @@ export async function compileValidatedRun(packetDirectory) {
|
|
|
2586
2617
|
assuranceReviewIds,
|
|
2587
2618
|
reconciliationContext,
|
|
2588
2619
|
});
|
|
2589
|
-
validateAssurance(validatedRun, errors);
|
|
2620
|
+
validateAssurance(validatedRun, errors, checkBrief);
|
|
2590
2621
|
}
|
|
2591
2622
|
|
|
2592
2623
|
const valid = errors.length === 0;
|
|
@@ -54,6 +54,7 @@ oat_workflow_origin: native # native | imported
|
|
|
54
54
|
# implementation_fingerprint: null # new generations use sha256:effective-delta-v2:<digest>; stored v1 values keep v1 semantics
|
|
55
55
|
# freshness_head: null # rolling accepted tree checkpoint
|
|
56
56
|
# freshness_fingerprint: null # full effective delta at freshness_head
|
|
57
|
+
# waivers: [] # append-only operator waivers {waived_by, reason, from_commit, to_commit, covered_fingerprint, waived_at}; never self-issued, never under OAT_AUTONOMOUS=1
|
|
57
58
|
# launch_state: not_started # not_started | intent_persisted | accepted | result_persisted | not_accepted
|
|
58
59
|
# launch_attempt_id: null
|
|
59
60
|
# launch_started_at: null
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type TemplateTier } from '../shared/template-source.js';
|
|
2
2
|
import { initializeBacklog } from './init.js';
|
|
3
3
|
import { regenerateBacklogIndex, type RegenerateBacklogIndexResult } from './regenerate-index.js';
|
|
4
4
|
export interface CreateBacklogItemOptions {
|
|
@@ -20,7 +20,7 @@ export interface CreateBacklogItemResult {
|
|
|
20
20
|
backlogRoot: string;
|
|
21
21
|
filePath: string;
|
|
22
22
|
templatePath: string;
|
|
23
|
-
templateTier:
|
|
23
|
+
templateTier: TemplateTier;
|
|
24
24
|
index: RegenerateBacklogIndexResult;
|
|
25
25
|
}
|
|
26
26
|
export interface CreateBacklogItemDependencies {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/new.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/new.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,EAClC,MAAM,oBAAoB,CAAC;AAS5B,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,KAAK,EAAE,4BAA4B,CAAC;CACrC;AAED,MAAM,WAAW,6BAA6B;IAC5C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;CACvD;AAgKD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,SAAS,GAAE,OAAO,CAAC,6BAA6B,CAAM,GACrD,OAAO,CAAC,uBAAuB,CAAC,CAwDlC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { access, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { parseAssociatedIssues, serializeAssociatedIssues, } from '../pjm/remote/association.js';
|
|
4
|
-
import { resolvePjmTemplate, } from '../pjm/template-source.js';
|
|
5
4
|
import { stripTemplateFrontmatter } from '../shared/strip-template-frontmatter.js';
|
|
5
|
+
import { resolveTemplate, } from '../shared/template-source.js';
|
|
6
6
|
import YAML from 'yaml';
|
|
7
7
|
import { initializeBacklog } from './init.js';
|
|
8
8
|
import { regenerateBacklogIndex, } from './regenerate-index.js';
|
|
@@ -106,7 +106,7 @@ export async function createBacklogItem(options, overrides = {}) {
|
|
|
106
106
|
if ((await pathExists(filePath)) || (await pathExists(archivedPath))) {
|
|
107
107
|
throw new Error(`Backlog item ${id} already exists. Use a more specific title to disambiguate.`);
|
|
108
108
|
}
|
|
109
|
-
const template = await
|
|
109
|
+
const template = await resolveTemplate({
|
|
110
110
|
name: 'backlog-item.md',
|
|
111
111
|
assetsRoot: options.assetsRoot,
|
|
112
112
|
templatesRoot: options.templatesRoot,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type TemplateTier } from '../shared/template-source.js';
|
|
2
2
|
export interface CreateDecisionRecordOptions {
|
|
3
3
|
decisionsRoot: string;
|
|
4
4
|
assetsRoot: string;
|
|
@@ -16,7 +16,7 @@ export interface CreateDecisionRecordResult {
|
|
|
16
16
|
decisionsRoot: string;
|
|
17
17
|
filePath: string;
|
|
18
18
|
templatePath: string;
|
|
19
|
-
templateTier:
|
|
19
|
+
templateTier: TemplateTier;
|
|
20
20
|
}
|
|
21
21
|
export declare function createDecisionRecord(options: CreateDecisionRecordOptions): Promise<CreateDecisionRecordResult>;
|
|
22
22
|
//# sourceMappingURL=new.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/decision/new.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/commands/decision/new.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,kCAAkC,CAAC;AAS1C,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAkFD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CAoDrC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
|
-
import { resolvePjmTemplate, } from '../pjm/template-source.js';
|
|
4
3
|
import { stripTemplateFrontmatter } from '../shared/strip-template-frontmatter.js';
|
|
4
|
+
import { resolveTemplate, } from '../shared/template-source.js';
|
|
5
5
|
import YAML from 'yaml';
|
|
6
6
|
import { assertDecisionIndexScaffold, regenerateDecisionIndex, } from './regenerate-index.js';
|
|
7
7
|
import { generateDecisionId } from './shared/generate-id.js';
|
|
@@ -62,7 +62,7 @@ export async function createDecisionRecord(options) {
|
|
|
62
62
|
if (await pathExists(filePath)) {
|
|
63
63
|
throw new Error(`Decision record ${id} already exists. Use a more specific title to disambiguate.`);
|
|
64
64
|
}
|
|
65
|
-
const template = await
|
|
65
|
+
const template = await resolveTemplate({
|
|
66
66
|
name: 'decision.md',
|
|
67
67
|
assetsRoot: options.assetsRoot,
|
|
68
68
|
templatesRoot: options.templatesRoot,
|
|
@@ -9,6 +9,15 @@ interface BuildDocsNavTreeOptions {
|
|
|
9
9
|
dirRelativePath?: string;
|
|
10
10
|
visitedDirectories?: Set<string>;
|
|
11
11
|
}
|
|
12
|
+
export declare function resolveEntryTarget(docsRoot: string, directoryPath: string, dirRelativePath: string, entry: DocsContentsEntry,
|
|
13
|
+
/**
|
|
14
|
+
* Page extensions a Contents link may target. MkDocs renders only `.md`;
|
|
15
|
+
* Fumadocs also renders `.mdx` pages.
|
|
16
|
+
*/
|
|
17
|
+
pageExtensions?: readonly string[]): Promise<{
|
|
18
|
+
kind: 'page' | 'section';
|
|
19
|
+
path: string;
|
|
20
|
+
}>;
|
|
12
21
|
export declare function buildDocsNavTree(options: BuildDocsNavTreeOptions): Promise<DocsNavTree>;
|
|
13
22
|
export {};
|
|
14
23
|
//# sourceMappingURL=contents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contents.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/nav/contents.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,SAAa,GACtB,iBAAiB,EAAE,CAqCrB;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAE/E,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"contents.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/nav/contents.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,SAAa,GACtB,iBAAiB,EAAE,CAqCrB;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAE/E,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAMD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,iBAAiB;AACxB;;;GAGG;AACH,cAAc,GAAE,SAAS,MAAM,EAAY,GAC1C,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAmErD;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CA8DtB"}
|
|
@@ -30,7 +30,12 @@ export function parseIndexContents(markdown, sourcePath = 'index.md') {
|
|
|
30
30
|
function toPosixPath(path) {
|
|
31
31
|
return path.replaceAll('\\', '/');
|
|
32
32
|
}
|
|
33
|
-
async function resolveEntryTarget(docsRoot, directoryPath, dirRelativePath, entry
|
|
33
|
+
export async function resolveEntryTarget(docsRoot, directoryPath, dirRelativePath, entry,
|
|
34
|
+
/**
|
|
35
|
+
* Page extensions a Contents link may target. MkDocs renders only `.md`;
|
|
36
|
+
* Fumadocs also renders `.mdx` pages.
|
|
37
|
+
*/
|
|
38
|
+
pageExtensions = ['.md']) {
|
|
34
39
|
const href = entry.href.split('#', 1)[0]?.trim() ?? '';
|
|
35
40
|
if (!href) {
|
|
36
41
|
throw new Error(`Invalid contents link "${entry.href}" in ${join(docsRoot, dirRelativePath, 'index.md')}`);
|
|
@@ -51,7 +56,7 @@ async function resolveEntryTarget(docsRoot, directoryPath, dirRelativePath, entr
|
|
|
51
56
|
if (!(await fileExists(targetPath))) {
|
|
52
57
|
throw new Error(`Contents link "${entry.href}" in ${join(docsRoot, dirRelativePath, 'index.md')} does not resolve to a Markdown file`);
|
|
53
58
|
}
|
|
54
|
-
if (extname(targetPath)
|
|
59
|
+
if (!pageExtensions.includes(extname(targetPath))) {
|
|
55
60
|
throw new Error(`Contents link "${entry.href}" in ${join(docsRoot, dirRelativePath, 'index.md')} must point to a Markdown file or directory index`);
|
|
56
61
|
}
|
|
57
62
|
if (basename(targetPath) === 'index.md') {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `meta.json` keys nav sync owns. Every other key (`icon`, `defaultOpen`,
|
|
3
|
+
* `description`, ...) is left as the author wrote it.
|
|
4
|
+
*/
|
|
5
|
+
export interface FumadocsMeta {
|
|
6
|
+
title?: string;
|
|
7
|
+
pages: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface FumadocsMetaFile {
|
|
10
|
+
/** Docs-relative POSIX path of the `meta.json` file. */
|
|
11
|
+
path: string;
|
|
12
|
+
meta: FumadocsMeta;
|
|
13
|
+
changed: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface SyncFumadocsNavigationResult {
|
|
16
|
+
metaFiles: FumadocsMetaFile[];
|
|
17
|
+
/** Docs-relative paths of the `meta.json` files this run wrote. */
|
|
18
|
+
written: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Docs-relative paths of the `meta.json` files that were missing or differed
|
|
21
|
+
* by meaning before this run. Equal to `written` unless `check` was set.
|
|
22
|
+
*/
|
|
23
|
+
stale: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Docs-relative paths no Contents map places in the page tree. A folder is
|
|
26
|
+
* reported once as `folder/` instead of once per page inside it.
|
|
27
|
+
*/
|
|
28
|
+
unlisted: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Reduce a Markdown heading to the plain text a sidebar shows: images and
|
|
32
|
+
* links keep their text, code spans keep their content, and emphasis and
|
|
33
|
+
* strikethrough markers are dropped.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stripInlineMarkdown(text: string): string;
|
|
36
|
+
/** Folder title: frontmatter `title`, else the first H1 outside code fences. */
|
|
37
|
+
export declare function resolveFolderTitle(markdown: string): string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Write one strict `meta.json` per docs directory that has an index.md,
|
|
40
|
+
* derived from that index's Contents map, and report every page the
|
|
41
|
+
* resulting page tree leaves out.
|
|
42
|
+
*
|
|
43
|
+
* Existing files are compared by meaning (parsed and deep-equal), so a run
|
|
44
|
+
* with no doc changes writes nothing even after a formatter rewrites them.
|
|
45
|
+
*/
|
|
46
|
+
export declare function syncFumadocsNavigation(options: {
|
|
47
|
+
docsRoot: string;
|
|
48
|
+
/** Compute and compare only; never write. */
|
|
49
|
+
check?: boolean;
|
|
50
|
+
}): Promise<SyncFumadocsNavigationResult>;
|
|
51
|
+
//# sourceMappingURL=fumadocs.d.ts.map
|