@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.
- package/assets/agents/oat-reviewer.md +4 -3
- package/assets/agents/recon-worker.md +42 -8
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +3 -56
- package/assets/docs/cli-utilities/tool-packs.md +4 -4
- package/assets/docs/contributing/code.md +2 -2
- package/assets/docs/contributing/index.md +0 -1
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/reference/troubleshooting.md +17 -40
- package/assets/docs/workflows/projects/artifacts.md +16 -34
- package/assets/docs/workflows/projects/lifecycle.md +20 -19
- package/assets/docs/workflows/skills/explainer-kit.md +180 -440
- package/assets/docs/workflows/skills/index.md +1 -2
- package/assets/docs/workflows/skills/recon.md +114 -23
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/explainer-kit/SKILL.md +96 -171
- package/assets/skills/explainer-kit/recipes/engineer-tour.json +1 -22
- package/assets/skills/explainer-kit/recipes/program-recap.json +1 -29
- package/assets/skills/explainer-kit/recipes/project-explainer.json +1 -22
- package/assets/skills/explainer-kit/recipes/project-recap.v2.json +1 -43
- package/assets/skills/explainer-kit/references/fact-base-contract.md +76 -101
- package/assets/skills/explainer-kit/references/recap-authoring.md +99 -0
- package/assets/skills/explainer-kit/schemas/manifest.schema.json +13 -135
- package/assets/skills/explainer-kit/scripts/bundle.mjs +712 -0
- package/assets/skills/explainer-kit/scripts/lib/claim-subject.mjs +40 -0
- package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +113 -1504
- package/assets/skills/explainer-kit/scripts/lib/failure.mjs +13 -0
- package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +57 -403
- package/assets/skills/explainer-kit/scripts/lib/qa-result.mjs +168 -0
- package/assets/skills/explainer-kit/scripts/lib/qa.mjs +90 -488
- package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +28 -545
- package/assets/skills/explainer-kit/scripts/lib/run-package.mjs +120 -0
- package/assets/skills/explainer-kit/scripts/lib/sanitize.mjs +42 -0
- package/assets/skills/explainer-kit/scripts/record.mjs +335 -0
- package/assets/skills/explainer-kit/scripts/verify.mjs +648 -0
- package/assets/skills/oat-explainer-kit/SKILL.md +57 -117
- package/assets/skills/oat-explainer-kit/references/config-contract.md +20 -64
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +85 -237
- package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +18 -10
- package/assets/skills/oat-explainer-kit/scripts/check-core.mjs +1 -0
- package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +256 -21
- package/assets/skills/oat-explainer-kit/scripts/persist-intent.mjs +82 -3
- package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +0 -162
- package/assets/skills/oat-explainer-kit/scripts/resolve-intent.mjs +57 -123
- package/assets/skills/oat-project-autonomous/SKILL.md +14 -13
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +165 -165
- package/assets/skills/oat-project-complete/SKILL.md +168 -349
- package/assets/skills/oat-project-complete/scripts/consume-persisted-recap-intent.mjs +125 -0
- package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +0 -30
- package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +4 -37
- package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +17 -16
- package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +9 -174
- package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +1 -2
- package/assets/skills/oat-project-document/SKILL.md +1 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +165 -165
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +44 -56
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +165 -165
- package/assets/skills/oat-project-lite/SKILL.md +1 -1
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +165 -165
- package/assets/skills/oat-project-plan/SKILL.md +5 -6
- package/assets/skills/oat-project-pr-final/SKILL.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +165 -165
- package/assets/skills/oat-project-quick-start/SKILL.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +165 -165
- package/assets/skills/oat-project-review-receive/SKILL.md +14 -1
- package/assets/skills/oat-project-summary/SKILL.md +35 -25
- package/assets/skills/oat-wave-execute/SKILL.md +11 -36
- package/assets/skills/oat-wave-program/SKILL.md +13 -37
- package/assets/skills/recon/SKILL.md +103 -40
- package/assets/skills/recon/references/packet-contract.md +150 -67
- package/assets/skills/recon/references/profiles.md +38 -16
- package/assets/skills/recon/references/worker-contract.md +39 -8
- package/assets/skills/recon/scripts/lib/contracts.mjs +703 -55
- package/assets/skills/recon/scripts/lib/routing.mjs +588 -0
- package/assets/skills/recon/scripts/lib/validated-run.mjs +2 -0
- package/assets/skills/recon/scripts/prepare-routing.mjs +88 -0
- package/assets/skills/recon/scripts/render-packet.mjs +69 -1
- package/assets/skills/recon/scripts/validate-packet.mjs +473 -56
- package/assets/skills/subagent-orchestration/SKILL.md +18 -9
- package/assets/skills/subagent-orchestration/references/model-selection-principles.md +17 -8
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +9 -113
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +32 -184
- package/dist/commands/project/archive/explainer-package-coverage.d.ts +3 -8
- package/dist/commands/project/archive/explainer-package-coverage.d.ts.map +1 -1
- package/dist/commands/project/archive/explainer-package-coverage.js +1 -1
- package/dist/config/oat-config.d.ts +0 -11
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +0 -34
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +0 -8
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +2 -10
- package/dist/validation/project-state.d.ts.map +1 -1
- package/dist/validation/project-state.js +42 -3
- package/package.json +2 -2
- package/assets/docs/contributing/explainer-kit-verification.md +0 -133
- package/assets/docs/workflows/skills/explainer-kit-providers.md +0 -155
- package/assets/skills/explainer-kit/briefs/deep-dive.md +0 -35
- package/assets/skills/explainer-kit/briefs/project-page.md +0 -38
- package/assets/skills/explainer-kit/briefs/supporting-diagram.md +0 -28
- package/assets/skills/explainer-kit/briefs/walkthrough-deck.md +0 -35
- package/assets/skills/explainer-kit/examples/project-explainer/content.md +0 -31
- package/assets/skills/explainer-kit/examples/project-explainer/fact-base.md +0 -22
- package/assets/skills/explainer-kit/examples/project-recap/content.md +0 -77
- package/assets/skills/explainer-kit/examples/project-recap/fact-base.json +0 -104
- package/assets/skills/explainer-kit/examples/project-recap/fact-base.md +0 -44
- package/assets/skills/explainer-kit/examples/theme-bundle.json +0 -87
- package/assets/skills/explainer-kit/recipes/project-recap.v1.json +0 -93
- package/assets/skills/explainer-kit/references/contracts.md +0 -324
- package/assets/skills/explainer-kit/references/destination-contract.md +0 -210
- package/assets/skills/explainer-kit/references/extension-contract.md +0 -80
- package/assets/skills/explainer-kit/references/golden-conformance.md +0 -80
- package/assets/skills/explainer-kit/references/visual-review.md +0 -71
- package/assets/skills/explainer-kit/schemas/author-request.v2.schema.json +0 -212
- package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +0 -241
- package/assets/skills/explainer-kit/schemas/author-result.v2.schema.json +0 -52
- package/assets/skills/explainer-kit/schemas/build-record.schema.json +0 -98
- package/assets/skills/explainer-kit/schemas/durability-evidence.schema.json +0 -53
- package/assets/skills/explainer-kit/schemas/publish-receipt.v1.schema.json +0 -97
- package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +0 -215
- package/assets/skills/explainer-kit/schemas/publish-request.v1.schema.json +0 -32
- package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +0 -34
- package/assets/skills/explainer-kit/schemas/run-request.schema.json +0 -147
- package/assets/skills/explainer-kit/schemas/set-plan.v1.schema.json +0 -149
- package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +0 -81
- package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +0 -66
- package/assets/skills/explainer-kit/schemas/visual-review-request.v1.schema.json +0 -117
- package/assets/skills/explainer-kit/schemas/visual-review-result.v1.schema.json +0 -80
- package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +0 -349
- package/assets/skills/explainer-kit/scripts/lib/content-approval.mjs +0 -418
- package/assets/skills/explainer-kit/scripts/lib/diagram.mjs +0 -514
- package/assets/skills/explainer-kit/scripts/lib/durability.mjs +0 -643
- package/assets/skills/explainer-kit/scripts/lib/fact-base.mjs +0 -664
- package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +0 -538
- package/assets/skills/explainer-kit/scripts/lib/markdown.mjs +0 -414
- package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +0 -54
- package/assets/skills/explainer-kit/scripts/lib/records.mjs +0 -954
- package/assets/skills/explainer-kit/scripts/lib/render.mjs +0 -703
- package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +0 -353
- package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +0 -759
- package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +0 -209
- package/assets/skills/explainer-kit/scripts/lib/source-backlinks.mjs +0 -218
- package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +0 -157
- package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +0 -400
- package/assets/skills/explainer-kit/scripts/publish.mjs +0 -76
- package/assets/skills/explainer-kit/scripts/record-durability.mjs +0 -64
- package/assets/skills/explainer-kit/scripts/render-qa.mjs +0 -461
- package/assets/skills/explainer-kit/scripts/run.mjs +0 -3038
- package/assets/skills/explainer-kit/scripts/validate.mjs +0 -59
- package/assets/skills/oat-explainer-kit/references/author-callback.md +0 -53
- package/assets/skills/oat-explainer-kit/references/migration.md +0 -144
- package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +0 -83
- package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +0 -91
- package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +0 -531
- package/assets/skills/oat-explainer-kit/scripts/probe-recap-seams.mjs +0 -371
- package/assets/skills/oat-explainer-kit/scripts/run.mjs +0 -905
- package/dist/commands/project/archive/explainer-source-backlinks.d.ts +0 -18
- package/dist/commands/project/archive/explainer-source-backlinks.d.ts.map +0 -1
- package/dist/commands/project/archive/explainer-source-backlinks.js +0 -27
- package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +0 -29
- package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +0 -1
- package/dist/commands/project/archive/explainer-terminal-evidence.js +0 -37
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { readdir, realpath } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
|
|
5
|
+
import { readPersistedIntent } from '../../oat-explainer-kit/scripts/persist-intent.mjs';
|
|
6
|
+
|
|
7
|
+
function consumptionError(message) {
|
|
8
|
+
const error = new Error(message);
|
|
9
|
+
error.code = 'E_RECAP_CONSUMPTION';
|
|
10
|
+
return error;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function discoverManifestCandidates(explainersPath) {
|
|
14
|
+
let entries;
|
|
15
|
+
try {
|
|
16
|
+
entries = await readdir(explainersPath, { withFileTypes: true });
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error?.code === 'ENOENT') return [];
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const candidates = [];
|
|
23
|
+
for (const entry of entries.sort((left, right) =>
|
|
24
|
+
left.name.localeCompare(right.name),
|
|
25
|
+
)) {
|
|
26
|
+
if (!entry.isDirectory()) continue;
|
|
27
|
+
const runEntries = await readdir(join(explainersPath, entry.name), {
|
|
28
|
+
withFileTypes: true,
|
|
29
|
+
});
|
|
30
|
+
if (
|
|
31
|
+
runEntries.some(
|
|
32
|
+
(runEntry) => runEntry.isFile() && runEntry.name === 'manifest.json',
|
|
33
|
+
)
|
|
34
|
+
) {
|
|
35
|
+
candidates.push(`explainers/${entry.name}/manifest.json`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return candidates;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function resolveFailedAttemptEvidence(projectRoot, locator) {
|
|
42
|
+
try {
|
|
43
|
+
const { resolveProjectFailedAttemptEvidence } =
|
|
44
|
+
await import('../../oat-explainer-kit/scripts/check-terminal-outcome.mjs');
|
|
45
|
+
return await resolveProjectFailedAttemptEvidence({
|
|
46
|
+
projectPath: projectRoot,
|
|
47
|
+
locator,
|
|
48
|
+
});
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw consumptionError(
|
|
51
|
+
`Persisted failed-attempt evidence is invalid: ${error.message}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function consumePersistedRecapIntent({ projectPath }) {
|
|
57
|
+
const projectRoot = await realpath(projectPath);
|
|
58
|
+
const record = await readPersistedIntent({
|
|
59
|
+
statePath: join(projectRoot, 'state.md'),
|
|
60
|
+
product: 'projectRecap',
|
|
61
|
+
});
|
|
62
|
+
if (record === null) {
|
|
63
|
+
throw consumptionError(
|
|
64
|
+
'Completion recap intent must be persisted before consumption.',
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
if (record.decision === 'skip') {
|
|
68
|
+
const failedAttemptEvidence =
|
|
69
|
+
record.source === 'failed_attempt'
|
|
70
|
+
? await resolveFailedAttemptEvidence(
|
|
71
|
+
projectRoot,
|
|
72
|
+
record.failed_attempt_evidence,
|
|
73
|
+
)
|
|
74
|
+
: null;
|
|
75
|
+
return {
|
|
76
|
+
decision: 'skip',
|
|
77
|
+
source: record.source,
|
|
78
|
+
route: 'skip',
|
|
79
|
+
manifestDiscoveryPerformed: false,
|
|
80
|
+
manifestCandidates: [],
|
|
81
|
+
authoringPermitted: false,
|
|
82
|
+
failedAttemptEvidence,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (record.decision !== 'generate') {
|
|
86
|
+
throw consumptionError(
|
|
87
|
+
`Unsupported persisted recap decision: ${String(record.decision)}`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
const manifestCandidates = await discoverManifestCandidates(
|
|
91
|
+
join(projectRoot, 'explainers'),
|
|
92
|
+
);
|
|
93
|
+
return {
|
|
94
|
+
decision: 'generate',
|
|
95
|
+
source: record.source,
|
|
96
|
+
route: 'generate',
|
|
97
|
+
manifestDiscoveryPerformed: true,
|
|
98
|
+
manifestCandidates,
|
|
99
|
+
authoringPermitted: true,
|
|
100
|
+
failedAttemptEvidence: null,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function main(argv) {
|
|
105
|
+
if (argv.length !== 1) {
|
|
106
|
+
throw consumptionError(
|
|
107
|
+
'Usage: consume-persisted-recap-intent.mjs <project-path>',
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return consumePersistedRecapIntent({ projectPath: argv[0] });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
process.argv[1] &&
|
|
115
|
+
import.meta.url === pathToFileURL(process.argv[1]).href
|
|
116
|
+
) {
|
|
117
|
+
main(process.argv.slice(2))
|
|
118
|
+
.then((result) => process.stdout.write(`${JSON.stringify(result)}\n`))
|
|
119
|
+
.catch((error) => {
|
|
120
|
+
process.stderr.write(
|
|
121
|
+
`${JSON.stringify({ ok: false, code: error.code, message: error.message })}\n`,
|
|
122
|
+
);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
@@ -5,7 +5,6 @@ import { pathToFileURL } from 'node:url';
|
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
|
|
7
7
|
import { validateSyncedArchiveTerminalReport } from './finalize-synced-archive.mjs';
|
|
8
|
-
import { recoverArchivedRecapEvidenceReceipt } from './recover-completion-receipts.mjs';
|
|
9
8
|
import { resolveSyncedArchiveEntry } from './resolve-synced-archive-entry.mjs';
|
|
10
9
|
|
|
11
10
|
const execFile = promisify(execFileCallback);
|
|
@@ -20,13 +19,9 @@ async function buildPostArchiveContinuation(
|
|
|
20
19
|
archiveReport,
|
|
21
20
|
projectPath,
|
|
22
21
|
repoRoot,
|
|
23
|
-
recoverArchiveEvidence,
|
|
24
22
|
) {
|
|
25
23
|
let selectedProjectRecapRun = '';
|
|
26
24
|
let exportedManifestPath = '';
|
|
27
|
-
let exportedBuildRecordPath = '';
|
|
28
|
-
let evidenceCommit = '';
|
|
29
|
-
let evidencePushRequired = false;
|
|
30
25
|
if (archiveReport.projectRecapExport != null) {
|
|
31
26
|
const sourceRunRoot = archiveReport.projectRecapExport?.sourceRunRoot;
|
|
32
27
|
const exportRoot = archiveReport.projectRecapExport?.exportRoot;
|
|
@@ -66,19 +61,6 @@ async function buildPostArchiveContinuation(
|
|
|
66
61
|
);
|
|
67
62
|
}
|
|
68
63
|
exportedManifestPath = posix.join(exportRootRelative, manifestPath);
|
|
69
|
-
exportedBuildRecordPath = posix.join(
|
|
70
|
-
exportRootRelative,
|
|
71
|
-
'build-record.json',
|
|
72
|
-
);
|
|
73
|
-
const recoveredEvidence = await recoverArchiveEvidence({
|
|
74
|
-
repoRoot,
|
|
75
|
-
lifecycleCommit: archiveReport.lifecycleCommit,
|
|
76
|
-
evidencePaths: [exportedManifestPath, exportedBuildRecordPath],
|
|
77
|
-
});
|
|
78
|
-
if (recoveredEvidence.evidenceCommit !== null) {
|
|
79
|
-
evidenceCommit = recoveredEvidence.evidenceCommit;
|
|
80
|
-
evidencePushRequired = recoveredEvidence.evidencePushRequired;
|
|
81
|
-
}
|
|
82
64
|
}
|
|
83
65
|
return {
|
|
84
66
|
required: true,
|
|
@@ -90,9 +72,6 @@ async function buildPostArchiveContinuation(
|
|
|
90
72
|
selectedProjectRecapRun,
|
|
91
73
|
projectRecapExport: archiveReport.projectRecapExport ?? null,
|
|
92
74
|
exportedManifestPath,
|
|
93
|
-
exportedBuildRecordPath,
|
|
94
|
-
evidenceCommit,
|
|
95
|
-
evidencePushRequired,
|
|
96
75
|
};
|
|
97
76
|
}
|
|
98
77
|
|
|
@@ -100,7 +79,6 @@ export async function continueSyncedArchiveCompletion({
|
|
|
100
79
|
executionResult,
|
|
101
80
|
finalizeLinks,
|
|
102
81
|
refreshDashboard,
|
|
103
|
-
attestRecap,
|
|
104
82
|
pushBookkeeping,
|
|
105
83
|
closeoutPr,
|
|
106
84
|
clearPointer,
|
|
@@ -118,12 +96,6 @@ export async function continueSyncedArchiveCompletion({
|
|
|
118
96
|
}
|
|
119
97
|
await finalizeLinks(executionResult.continuation);
|
|
120
98
|
await refreshDashboard(executionResult.continuation);
|
|
121
|
-
if (
|
|
122
|
-
executionResult.continuation.projectRecapExport !== null &&
|
|
123
|
-
executionResult.continuation.evidenceCommit === ''
|
|
124
|
-
) {
|
|
125
|
-
await attestRecap(executionResult.continuation);
|
|
126
|
-
}
|
|
127
99
|
await pushBookkeeping(executionResult.continuation);
|
|
128
100
|
await closeoutPr(executionResult.continuation);
|
|
129
101
|
await clearPointer(executionResult.archiveReport);
|
|
@@ -145,7 +117,6 @@ export async function executeSyncedArchiveEntry({
|
|
|
145
117
|
runActiveWorkflowSteps,
|
|
146
118
|
archiveProject,
|
|
147
119
|
validateArchive,
|
|
148
|
-
recoverArchiveEvidence = recoverArchivedRecapEvidenceReceipt,
|
|
149
120
|
}) {
|
|
150
121
|
const entry = record
|
|
151
122
|
? await resolveSyncedArchiveEntry({
|
|
@@ -214,7 +185,6 @@ export async function executeSyncedArchiveEntry({
|
|
|
214
185
|
archiveReport,
|
|
215
186
|
projectPath,
|
|
216
187
|
repoRoot,
|
|
217
|
-
recoverArchiveEvidence,
|
|
218
188
|
),
|
|
219
189
|
};
|
|
220
190
|
}
|
|
@@ -141,8 +141,6 @@ export function parseCompletionRetryFields(input) {
|
|
|
141
141
|
|
|
142
142
|
requireExactKeys(value, [
|
|
143
143
|
'candidate',
|
|
144
|
-
'evidenceCommit',
|
|
145
|
-
'evidencePushRequired',
|
|
146
144
|
'localCommit',
|
|
147
145
|
'nextStep',
|
|
148
146
|
'prArtifactPath',
|
|
@@ -177,16 +175,6 @@ export function parseCompletionRetryFields(input) {
|
|
|
177
175
|
'Recovered completion retry receipts must use full commit SHAs.',
|
|
178
176
|
);
|
|
179
177
|
}
|
|
180
|
-
if (value.evidenceCommit !== null && !FULL_SHA.test(value.evidenceCommit)) {
|
|
181
|
-
throw completionRetryFieldsError(
|
|
182
|
-
'Recovered completion retry evidence receipt must be null or a full commit SHA.',
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
if (typeof value.evidencePushRequired !== 'boolean') {
|
|
186
|
-
throw completionRetryFieldsError(
|
|
187
|
-
'Recovered completion retry evidence push flag must be boolean.',
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
178
|
if (
|
|
191
179
|
typeof value.retainedRef !== 'string' ||
|
|
192
180
|
!RETAINED_REF.test(value.retainedRef)
|
|
@@ -203,31 +191,12 @@ export function parseCompletionRetryFields(input) {
|
|
|
203
191
|
'Recovered completion retry PR artifact path is malformed.',
|
|
204
192
|
);
|
|
205
193
|
}
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
value.localCommit !== value.projectRefCommit ||
|
|
210
|
-
value.remoteCommit !== value.projectRefCommit
|
|
211
|
-
) {
|
|
212
|
-
throw completionRetryFieldsError(
|
|
213
|
-
'Recovered completion retry receipts are contradictory without evidence.',
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
} else if (value.evidencePushRequired) {
|
|
217
|
-
if (
|
|
218
|
-
value.localCommit !== value.evidenceCommit ||
|
|
219
|
-
value.remoteCommit !== value.projectRefCommit
|
|
220
|
-
) {
|
|
221
|
-
throw completionRetryFieldsError(
|
|
222
|
-
'Recovered unpublished evidence receipts are contradictory.',
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
} else if (
|
|
226
|
-
value.localCommit !== value.evidenceCommit ||
|
|
227
|
-
value.remoteCommit !== value.evidenceCommit
|
|
194
|
+
if (
|
|
195
|
+
value.localCommit !== value.projectRefCommit ||
|
|
196
|
+
value.remoteCommit !== value.projectRefCommit
|
|
228
197
|
) {
|
|
229
198
|
throw completionRetryFieldsError(
|
|
230
|
-
'Recovered
|
|
199
|
+
'Recovered completion retry receipts are contradictory.',
|
|
231
200
|
);
|
|
232
201
|
}
|
|
233
202
|
|
|
@@ -235,8 +204,6 @@ export function parseCompletionRetryFields(input) {
|
|
|
235
204
|
'recovery',
|
|
236
205
|
value.projectLinksPinCommit,
|
|
237
206
|
value.projectRefCommit,
|
|
238
|
-
value.evidenceCommit ?? '-',
|
|
239
|
-
String(value.evidencePushRequired),
|
|
240
207
|
value.prArtifactPath,
|
|
241
208
|
].join('\t');
|
|
242
209
|
}
|
|
@@ -13,7 +13,22 @@ function shellQuote(value) {
|
|
|
13
13
|
export function parseSyncedArchiveResumeFields(result) {
|
|
14
14
|
const continuation = result?.continuation;
|
|
15
15
|
const hasRecapExport = continuation?.projectRecapExport !== null;
|
|
16
|
+
const allowedContinuationFields = new Set([
|
|
17
|
+
'required',
|
|
18
|
+
'rejoinStep',
|
|
19
|
+
'archivePath',
|
|
20
|
+
'summaryExportFile',
|
|
21
|
+
'lifecycleCommit',
|
|
22
|
+
's3Path',
|
|
23
|
+
'selectedProjectRecapRun',
|
|
24
|
+
'projectRecapExport',
|
|
25
|
+
'exportedManifestPath',
|
|
26
|
+
]);
|
|
16
27
|
if (
|
|
28
|
+
!continuation ||
|
|
29
|
+
Object.keys(continuation).some(
|
|
30
|
+
(field) => !allowedContinuationFields.has(field),
|
|
31
|
+
) ||
|
|
17
32
|
result?.status !== 'ok' ||
|
|
18
33
|
result?.route !== 'archive-resumed' ||
|
|
19
34
|
result?.terminal !== true ||
|
|
@@ -25,21 +40,10 @@ export function parseSyncedArchiveResumeFields(result) {
|
|
|
25
40
|
continuation.archivePath.length === 0 ||
|
|
26
41
|
typeof continuation.lifecycleCommit !== 'string' ||
|
|
27
42
|
!/^[0-9a-f]{40}$/.test(continuation.lifecycleCommit) ||
|
|
28
|
-
typeof continuation.evidenceCommit !== 'string' ||
|
|
29
|
-
(continuation.evidenceCommit !== '' &&
|
|
30
|
-
!/^[0-9a-f]{40}$/.test(continuation.evidenceCommit)) ||
|
|
31
|
-
typeof continuation.evidencePushRequired !== 'boolean' ||
|
|
32
|
-
(continuation.evidenceCommit === '' &&
|
|
33
|
-
continuation.evidencePushRequired !== false) ||
|
|
34
43
|
(hasRecapExport &&
|
|
35
44
|
(typeof continuation.exportedManifestPath !== 'string' ||
|
|
36
|
-
continuation.exportedManifestPath.length === 0 ||
|
|
37
|
-
|
|
38
|
-
continuation.exportedBuildRecordPath.length === 0)) ||
|
|
39
|
-
(!hasRecapExport &&
|
|
40
|
-
(continuation.exportedManifestPath !== '' ||
|
|
41
|
-
continuation.exportedBuildRecordPath !== '' ||
|
|
42
|
-
continuation.evidenceCommit !== ''))
|
|
45
|
+
continuation.exportedManifestPath.length === 0)) ||
|
|
46
|
+
(!hasRecapExport && continuation.exportedManifestPath !== '')
|
|
43
47
|
) {
|
|
44
48
|
throw fieldsError(
|
|
45
49
|
'Synced archive resume result has no verified post-archive continuation.',
|
|
@@ -59,10 +63,7 @@ export function parseSyncedArchiveResumeFields(result) {
|
|
|
59
63
|
PROJECT_RECAP_EXPORT_JSON: JSON.stringify(
|
|
60
64
|
continuation.projectRecapExport ?? null,
|
|
61
65
|
),
|
|
62
|
-
EVIDENCE_COMMIT: continuation.evidenceCommit,
|
|
63
|
-
EVIDENCE_PUSH_REQUIRED: String(continuation.evidencePushRequired),
|
|
64
66
|
EXPORTED_MANIFEST_PATH: continuation.exportedManifestPath,
|
|
65
|
-
EXPORTED_BUILD_RECORD_PATH: continuation.exportedBuildRecordPath,
|
|
66
67
|
PROJECT_REF_COMMIT: '',
|
|
67
68
|
SHOULD_OPEN_PR: 'false',
|
|
68
69
|
};
|
|
@@ -7,7 +7,6 @@ const execFileAsync = promisify(execFile);
|
|
|
7
7
|
|
|
8
8
|
const PIN_SOURCE_MESSAGE = 'chore(oat): finalize project lifecycle';
|
|
9
9
|
const FINAL_ARTIFACT_MESSAGE = 'chore(oat): publish final project links';
|
|
10
|
-
const EVIDENCE_MESSAGE = 'chore(oat): attest final project recap';
|
|
11
10
|
const LINKS_START = '<!-- oat:project-links:start -->';
|
|
12
11
|
const LINKS_END = '<!-- oat:project-links:end -->';
|
|
13
12
|
const FULL_SHA = /^[0-9a-f]{40}$/;
|
|
@@ -91,23 +90,6 @@ async function changedPaths(projectPath, commit) {
|
|
|
91
90
|
return output === '' ? [] : output.split('\n').sort();
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
async function isAncestor(projectPath, ancestor, descendant) {
|
|
95
|
-
try {
|
|
96
|
-
await execFileAsync(
|
|
97
|
-
'git',
|
|
98
|
-
['merge-base', '--is-ancestor', ancestor, descendant],
|
|
99
|
-
{ cwd: projectPath, encoding: 'utf8' },
|
|
100
|
-
);
|
|
101
|
-
return true;
|
|
102
|
-
} catch (error) {
|
|
103
|
-
if (error?.code === 1) return false;
|
|
104
|
-
const detail = error?.stderr?.trim() || error?.message || String(error);
|
|
105
|
-
throw completionReceiptError(
|
|
106
|
-
`git merge-base failed while recovering completion receipts: ${detail}`,
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
93
|
async function committedFile(projectPath, commit, path, label) {
|
|
112
94
|
const content = await git(projectPath, ['show', `${commit}:${path}`], {
|
|
113
95
|
allowFailure: true,
|
|
@@ -394,7 +376,7 @@ export async function detectCompletionReceiptCandidate({
|
|
|
394
376
|
'Retained ref must be a canonical OAT project ref.',
|
|
395
377
|
);
|
|
396
378
|
}
|
|
397
|
-
const receiptSubjects = new Set([FINAL_ARTIFACT_MESSAGE
|
|
379
|
+
const receiptSubjects = new Set([FINAL_ARTIFACT_MESSAGE]);
|
|
398
380
|
const head = await git(projectPath, ['rev-parse', 'HEAD']);
|
|
399
381
|
const retained = await git(
|
|
400
382
|
projectPath,
|
|
@@ -528,7 +510,6 @@ export async function recoverCompletionReceipts({
|
|
|
528
510
|
projectPath,
|
|
529
511
|
retainedRef,
|
|
530
512
|
prArtifactPath,
|
|
531
|
-
evidencePaths = [],
|
|
532
513
|
remote = 'origin',
|
|
533
514
|
}) {
|
|
534
515
|
if (typeof projectPath !== 'string' || projectPath.length === 0) {
|
|
@@ -552,13 +533,6 @@ export async function recoverCompletionReceipts({
|
|
|
552
533
|
`Project checkout basename must match retained project ${expectedSlug}.`,
|
|
553
534
|
);
|
|
554
535
|
}
|
|
555
|
-
const exactEvidencePaths = evidencePaths.map((path, index) =>
|
|
556
|
-
requireRelativeGitPath(path, `Evidence path ${index + 1}`),
|
|
557
|
-
);
|
|
558
|
-
if (new Set(exactEvidencePaths).size !== exactEvidencePaths.length) {
|
|
559
|
-
throw completionReceiptError('Evidence paths must be unique.');
|
|
560
|
-
}
|
|
561
|
-
|
|
562
536
|
const status = await git(projectPath, [
|
|
563
537
|
'status',
|
|
564
538
|
'--porcelain=v1',
|
|
@@ -594,60 +568,17 @@ export async function recoverCompletionReceipts({
|
|
|
594
568
|
const expectedRepository = parseGitHubRepository(remoteUrl);
|
|
595
569
|
const localSubject = await commitSubject(projectPath, localCommit);
|
|
596
570
|
|
|
597
|
-
|
|
598
|
-
let evidenceCommit = null;
|
|
599
|
-
let evidencePushRequired = false;
|
|
600
|
-
|
|
601
|
-
if (localSubject === FINAL_ARTIFACT_MESSAGE) {
|
|
602
|
-
if (
|
|
603
|
-
localCommit !== remoteCommit ||
|
|
604
|
-
localRetainedRefCommit !== localCommit
|
|
605
|
-
) {
|
|
606
|
-
throw completionReceiptError(
|
|
607
|
-
'Final-artifact receipt recovery requires equal checkout, local retained ref, and remote retained ref commits.',
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
finalArtifactCommit = localCommit;
|
|
611
|
-
} else if (localSubject === EVIDENCE_MESSAGE) {
|
|
612
|
-
if (exactEvidencePaths.length === 0) {
|
|
613
|
-
throw completionReceiptError(
|
|
614
|
-
'Recap-evidence receipt recovery requires exact evidence paths.',
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
evidenceCommit = localCommit;
|
|
618
|
-
requireExactPaths(
|
|
619
|
-
await changedPaths(projectPath, evidenceCommit),
|
|
620
|
-
exactEvidencePaths,
|
|
621
|
-
'Recap evidence commit',
|
|
622
|
-
);
|
|
623
|
-
finalArtifactCommit = await singleParent(
|
|
624
|
-
projectPath,
|
|
625
|
-
evidenceCommit,
|
|
626
|
-
'Recap evidence commit',
|
|
627
|
-
);
|
|
628
|
-
if (remoteCommit === finalArtifactCommit) {
|
|
629
|
-
if (localRetainedRefCommit !== finalArtifactCommit) {
|
|
630
|
-
throw completionReceiptError(
|
|
631
|
-
'Unpublished recap evidence requires the local retained ref to remain at the final-artifact parent.',
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
evidencePushRequired = true;
|
|
635
|
-
} else if (remoteCommit === evidenceCommit) {
|
|
636
|
-
if (localRetainedRefCommit !== evidenceCommit) {
|
|
637
|
-
throw completionReceiptError(
|
|
638
|
-
'Published recap evidence requires equal local and remote retained refs.',
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
} else {
|
|
642
|
-
throw completionReceiptError(
|
|
643
|
-
'Recap-evidence recovery requires the remote retained ref to equal either the evidence commit or its final-artifact parent.',
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
} else {
|
|
571
|
+
if (localSubject !== FINAL_ARTIFACT_MESSAGE) {
|
|
647
572
|
throw completionReceiptError(
|
|
648
573
|
`HEAD subject ${JSON.stringify(localSubject)} is not an exact completion receipt.`,
|
|
649
574
|
);
|
|
650
575
|
}
|
|
576
|
+
if (localCommit !== remoteCommit || localRetainedRefCommit !== localCommit) {
|
|
577
|
+
throw completionReceiptError(
|
|
578
|
+
'Final-artifact receipt recovery requires equal checkout, local retained ref, and remote retained ref commits.',
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
const finalArtifactCommit = localCommit;
|
|
651
582
|
|
|
652
583
|
if (
|
|
653
584
|
(await commitSubject(projectPath, finalArtifactCommit)) !==
|
|
@@ -710,101 +641,6 @@ export async function recoverCompletionReceipts({
|
|
|
710
641
|
remoteCommit,
|
|
711
642
|
projectLinksPinCommit,
|
|
712
643
|
projectRefCommit: finalArtifactCommit,
|
|
713
|
-
evidenceCommit,
|
|
714
|
-
evidencePushRequired,
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
export async function recoverArchivedRecapEvidenceReceipt({
|
|
719
|
-
repoRoot,
|
|
720
|
-
lifecycleCommit,
|
|
721
|
-
evidencePaths,
|
|
722
|
-
}) {
|
|
723
|
-
if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
|
|
724
|
-
throw completionReceiptError(
|
|
725
|
-
'Archived recap evidence recovery requires the repository root.',
|
|
726
|
-
);
|
|
727
|
-
}
|
|
728
|
-
if (!FULL_SHA.test(lifecycleCommit ?? '')) {
|
|
729
|
-
throw completionReceiptError(
|
|
730
|
-
'Archived recap evidence recovery requires a full lifecycle commit SHA.',
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
if (!Array.isArray(evidencePaths) || evidencePaths.length !== 2) {
|
|
734
|
-
throw completionReceiptError(
|
|
735
|
-
'Archived recap evidence recovery requires exactly two evidence paths.',
|
|
736
|
-
);
|
|
737
|
-
}
|
|
738
|
-
const exactEvidencePaths = evidencePaths.map((path, index) =>
|
|
739
|
-
requireRelativeGitPath(path, `Archived evidence path ${index + 1}`),
|
|
740
|
-
);
|
|
741
|
-
if (new Set(exactEvidencePaths).size !== exactEvidencePaths.length) {
|
|
742
|
-
throw completionReceiptError('Archived evidence paths must be unique.');
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
const resolvedLifecycle = await git(repoRoot, [
|
|
746
|
-
'rev-parse',
|
|
747
|
-
'--verify',
|
|
748
|
-
`${lifecycleCommit}^{commit}`,
|
|
749
|
-
]);
|
|
750
|
-
if (resolvedLifecycle !== lifecycleCommit) {
|
|
751
|
-
throw completionReceiptError(
|
|
752
|
-
'Archived recap lifecycle receipt does not resolve to the exact commit.',
|
|
753
|
-
);
|
|
754
|
-
}
|
|
755
|
-
const head = await git(repoRoot, ['rev-parse', 'HEAD']);
|
|
756
|
-
if (head === lifecycleCommit) {
|
|
757
|
-
return {
|
|
758
|
-
status: 'none',
|
|
759
|
-
evidenceCommit: null,
|
|
760
|
-
evidencePushRequired: false,
|
|
761
|
-
evidencePaths: exactEvidencePaths,
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
if ((await commitSubject(repoRoot, head)) !== EVIDENCE_MESSAGE) {
|
|
765
|
-
throw completionReceiptError(
|
|
766
|
-
'Archived recap retry HEAD is neither the lifecycle commit nor the exact evidence commit.',
|
|
767
|
-
);
|
|
768
|
-
}
|
|
769
|
-
if (
|
|
770
|
-
(await singleParent(repoRoot, head, 'Archived recap evidence commit')) !==
|
|
771
|
-
lifecycleCommit
|
|
772
|
-
) {
|
|
773
|
-
throw completionReceiptError(
|
|
774
|
-
'Archived recap evidence commit must be the immediate child of the lifecycle commit.',
|
|
775
|
-
);
|
|
776
|
-
}
|
|
777
|
-
requireExactPaths(
|
|
778
|
-
await changedPaths(repoRoot, head),
|
|
779
|
-
exactEvidencePaths,
|
|
780
|
-
'Archived recap evidence commit',
|
|
781
|
-
);
|
|
782
|
-
|
|
783
|
-
const upstream = await git(
|
|
784
|
-
repoRoot,
|
|
785
|
-
['rev-parse', '--verify', '@{u}^{commit}'],
|
|
786
|
-
{ allowFailure: true },
|
|
787
|
-
);
|
|
788
|
-
let evidencePushRequired;
|
|
789
|
-
if (upstream === head) {
|
|
790
|
-
evidencePushRequired = false;
|
|
791
|
-
} else if (
|
|
792
|
-
upstream === null ||
|
|
793
|
-
(FULL_SHA.test(upstream) &&
|
|
794
|
-
(await isAncestor(repoRoot, upstream, lifecycleCommit)))
|
|
795
|
-
) {
|
|
796
|
-
evidencePushRequired = true;
|
|
797
|
-
} else {
|
|
798
|
-
throw completionReceiptError(
|
|
799
|
-
'Archived recap evidence retry requires upstream to equal the evidence commit or remain an ancestor of its lifecycle parent.',
|
|
800
|
-
);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
return {
|
|
804
|
-
status: 'recovered',
|
|
805
|
-
evidenceCommit: head,
|
|
806
|
-
evidencePushRequired,
|
|
807
|
-
evidencePaths: exactEvidencePaths,
|
|
808
644
|
};
|
|
809
645
|
}
|
|
810
646
|
|
|
@@ -815,7 +651,7 @@ function parseBoolean(value, label) {
|
|
|
815
651
|
}
|
|
816
652
|
|
|
817
653
|
function parseArguments(argv) {
|
|
818
|
-
const result = {
|
|
654
|
+
const result = {};
|
|
819
655
|
for (let index = 0; index < argv.length; index += 2) {
|
|
820
656
|
const flag = argv[index];
|
|
821
657
|
const value = argv[index + 1];
|
|
@@ -825,7 +661,6 @@ function parseArguments(argv) {
|
|
|
825
661
|
if (flag === '--project-path') result.projectPath = value;
|
|
826
662
|
else if (flag === '--retained-ref') result.retainedRef = value;
|
|
827
663
|
else if (flag === '--pr-artifact') result.prArtifactPath = value;
|
|
828
|
-
else if (flag === '--evidence-path') result.evidencePaths.push(value);
|
|
829
664
|
else if (flag === '--remote') result.remote = value;
|
|
830
665
|
else if (flag === '--detect-candidate') {
|
|
831
666
|
result.detectCandidate = parseBoolean(value, flag);
|
|
@@ -23,7 +23,7 @@ function completionRetryError(message) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function parseArguments(argv) {
|
|
26
|
-
const result = {
|
|
26
|
+
const result = {};
|
|
27
27
|
for (let index = 0; index < argv.length; index += 2) {
|
|
28
28
|
const flag = argv[index];
|
|
29
29
|
const value = argv[index + 1];
|
|
@@ -33,7 +33,6 @@ function parseArguments(argv) {
|
|
|
33
33
|
if (flag === '--project-path') result.projectPath = value;
|
|
34
34
|
else if (flag === '--retained-ref') result.retainedRef = value;
|
|
35
35
|
else if (flag === '--pr-artifact') result.prArtifactPath = value;
|
|
36
|
-
else if (flag === '--evidence-path') result.evidencePaths.push(value);
|
|
37
36
|
else if (flag === '--remote') result.remote = value;
|
|
38
37
|
else throw completionRetryError(`Unsupported argument: ${flag}.`);
|
|
39
38
|
}
|
|
@@ -6,7 +6,7 @@ disable-model-invocation: false
|
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Write, Edit, Bash(git:*), Bash(jq:*), Bash(oat pjm:*), Bash(oat project push:*), Bash(oat project scope:*), Bash(oat tools:*), Glob, Grep, AskUserQuestion, Skill
|
|
8
8
|
metadata:
|
|
9
|
-
version: 1.8.
|
|
9
|
+
version: 1.8.4
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Project Documentation Sync
|