@open-agent-toolkit/cli 0.2.40 → 0.2.45
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-codebase-mapper.md +15 -3
- package/assets/agents/oat-phase-implementer.md +34 -9
- package/assets/agents/oat-reviewer.md +2 -2
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/configuration.md +11 -1
- package/assets/docs/cli-utilities/tool-packs.md +8 -0
- package/assets/docs/contributing/skills.md +67 -14
- package/assets/docs/quickstart.md +9 -0
- package/assets/docs/reference/cli-reference.md +56 -1
- package/assets/docs/reference/file-locations.md +18 -1
- package/assets/docs/reference/oat-directory-structure.md +20 -4
- package/assets/docs/workflows/projects/artifacts.md +27 -1
- package/assets/docs/workflows/projects/implementation-execution.md +22 -0
- package/assets/docs/workflows/projects/index.md +6 -0
- package/assets/docs/workflows/projects/lifecycle.md +19 -5
- package/assets/docs/workflows/projects/picking-up-projects.md +75 -0
- package/assets/docs/workflows/projects/pr-flow.md +22 -1
- package/assets/docs/workflows/projects/reviewing-oat-prs.md +60 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/analyze/SKILL.md +13 -5
- package/assets/skills/compare/SKILL.md +11 -2
- package/assets/skills/oat-brainstorm/SKILL.md +135 -32
- package/assets/skills/oat-brainstorm/references/destinations.md +9 -6
- package/assets/skills/oat-cursor-cloud-projects/SKILL.md +11 -1
- package/assets/skills/oat-dispatch-subagents/SKILL.md +19 -6
- package/assets/skills/oat-doctor/SKILL.md +8 -1
- package/assets/skills/oat-project-autonomous/SKILL.md +45 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +8 -8
- package/assets/skills/oat-project-capture/SKILL.md +29 -9
- package/assets/skills/oat-project-complete/SKILL.md +610 -38
- package/assets/skills/oat-project-complete/scripts/parse-completion-retry-fields.mjs +265 -0
- package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +764 -0
- package/assets/skills/oat-project-complete/scripts/resolve-completion-retry.mjs +134 -0
- package/assets/skills/oat-project-complete/scripts/validate-nonarchive-lifecycle-receipt.mjs +160 -0
- package/assets/skills/oat-project-design/SKILL.md +33 -9
- package/assets/skills/oat-project-discover/SKILL.md +16 -3
- package/assets/skills/oat-project-document/SKILL.md +10 -4
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +8 -8
- package/assets/skills/oat-project-implement/SKILL.md +14 -3
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +18 -6
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +8 -8
- package/assets/skills/oat-project-implement/references/phase-execution.md +9 -3
- package/assets/skills/oat-project-implement/references/plan-and-resume.md +3 -0
- package/assets/skills/oat-project-import-plan/SKILL.md +15 -9
- package/assets/skills/oat-project-new/SKILL.md +7 -5
- package/assets/skills/oat-project-next/SKILL.md +32 -10
- package/assets/skills/oat-project-plan/SKILL.md +18 -3
- package/assets/skills/oat-project-pr-final/SKILL.md +23 -2
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +8 -8
- package/assets/skills/oat-project-pr-progress/SKILL.md +23 -2
- package/assets/skills/oat-project-progress/SKILL.md +23 -9
- package/assets/skills/oat-project-promote-spec-driven/SKILL.md +20 -2
- package/assets/skills/oat-project-quick-start/SKILL.md +48 -18
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +8 -8
- package/assets/skills/oat-project-reconcile/SKILL.md +14 -10
- package/assets/skills/oat-project-retro/SKILL.md +3 -3
- package/assets/skills/oat-project-retro/references/apply-procedure.md +102 -6
- package/assets/skills/oat-project-retro-file/SKILL.md +57 -6
- package/assets/skills/oat-project-review-provide/SKILL.md +56 -6
- package/assets/skills/oat-project-review-receive/SKILL.md +16 -7
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +9 -3
- package/assets/skills/oat-project-revise/SKILL.md +12 -3
- package/assets/skills/oat-project-spec/SKILL.md +16 -3
- package/assets/skills/oat-project-summary/SKILL.md +113 -13
- package/assets/skills/oat-repo-improve/SKILL.md +18 -7
- package/assets/skills/oat-review-provide-remote/SKILL.md +11 -2
- package/assets/skills/oat-wave-execute/SKILL.md +34 -2
- package/assets/skills/oat-worktree-bootstrap/SKILL.md +13 -1
- package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +13 -1
- package/dist/commands/config/index.d.ts +1 -0
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +30 -2
- package/dist/commands/doctor/index.d.ts +2 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +27 -3
- package/dist/commands/doctor/synced-projects.d.ts +12 -0
- package/dist/commands/doctor/synced-projects.d.ts.map +1 -0
- package/dist/commands/doctor/synced-projects.js +208 -0
- package/dist/commands/init/gitattributes.d.ts +4 -0
- package/dist/commands/init/gitattributes.d.ts.map +1 -0
- package/dist/commands/init/gitattributes.js +12 -0
- package/dist/commands/init/gitignore.d.ts +8 -1
- package/dist/commands/init/gitignore.d.ts.map +1 -1
- package/dist/commands/init/gitignore.js +146 -41
- package/dist/commands/init/index.d.ts +2 -0
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +3 -0
- package/dist/commands/init/managed-block.d.ts +10 -0
- package/dist/commands/init/managed-block.d.ts.map +1 -0
- package/dist/commands/init/managed-block.js +40 -0
- package/dist/commands/init/tools/workflows/install-workflows.js +1 -1
- package/dist/commands/local/index.d.ts.map +1 -1
- package/dist/commands/local/index.js +5 -1
- package/dist/commands/local/sync.d.ts +4 -0
- package/dist/commands/local/sync.d.ts.map +1 -1
- package/dist/commands/local/sync.js +123 -2
- package/dist/commands/pjm/adoption.d.ts +2 -0
- package/dist/commands/pjm/adoption.d.ts.map +1 -1
- package/dist/commands/pjm/adoption.js +1 -1
- package/dist/commands/project/archive/archive-utils.d.ts +24 -0
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +349 -22
- package/dist/commands/project/archive/index.d.ts.map +1 -1
- package/dist/commands/project/archive/index.js +1 -0
- package/dist/commands/project/archive/push-runner.d.ts +5 -1
- package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
- package/dist/commands/project/archive/push-runner.js +33 -4
- package/dist/commands/project/complete-state/index.d.ts.map +1 -1
- package/dist/commands/project/complete-state/index.js +3 -1
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +12 -0
- package/dist/commands/project/links/compute.d.ts +9 -0
- package/dist/commands/project/links/compute.d.ts.map +1 -0
- package/dist/commands/project/links/compute.js +27 -0
- package/dist/commands/project/links/index.d.ts +17 -0
- package/dist/commands/project/links/index.d.ts.map +1 -0
- package/dist/commands/project/links/index.js +72 -0
- package/dist/commands/project/links/refresh.d.ts +26 -0
- package/dist/commands/project/links/refresh.d.ts.map +1 -0
- package/dist/commands/project/links/refresh.js +92 -0
- package/dist/commands/project/links/render.d.ts +24 -0
- package/dist/commands/project/links/render.d.ts.map +1 -0
- package/dist/commands/project/links/render.js +68 -0
- package/dist/commands/project/list.d.ts +5 -0
- package/dist/commands/project/list.d.ts.map +1 -1
- package/dist/commands/project/list.js +182 -9
- package/dist/commands/project/migrate/index.d.ts +22 -0
- package/dist/commands/project/migrate/index.d.ts.map +1 -0
- package/dist/commands/project/migrate/index.js +79 -0
- package/dist/commands/project/new/index.d.ts +2 -0
- package/dist/commands/project/new/index.d.ts.map +1 -1
- package/dist/commands/project/new/index.js +14 -2
- package/dist/commands/project/new/scaffold.d.ts +22 -1
- package/dist/commands/project/new/scaffold.d.ts.map +1 -1
- package/dist/commands/project/new/scaffold.js +287 -69
- package/dist/commands/project/open/index.d.ts +16 -0
- package/dist/commands/project/open/index.d.ts.map +1 -1
- package/dist/commands/project/open/index.js +151 -19
- package/dist/commands/project/pause/index.d.ts +8 -0
- package/dist/commands/project/pause/index.d.ts.map +1 -1
- package/dist/commands/project/pause/index.js +129 -19
- package/dist/commands/project/prune/index.d.ts +21 -0
- package/dist/commands/project/prune/index.d.ts.map +1 -0
- package/dist/commands/project/prune/index.js +95 -0
- package/dist/commands/project/pull/index.d.ts +28 -0
- package/dist/commands/project/pull/index.d.ts.map +1 -0
- package/dist/commands/project/pull/index.js +157 -0
- package/dist/commands/project/push/index.d.ts +22 -0
- package/dist/commands/project/push/index.d.ts.map +1 -0
- package/dist/commands/project/push/index.js +100 -0
- package/dist/commands/project/scope/index.d.ts +17 -0
- package/dist/commands/project/scope/index.d.ts.map +1 -0
- package/dist/commands/project/scope/index.js +107 -0
- package/dist/commands/project/split/run.d.ts +4 -0
- package/dist/commands/project/split/run.d.ts.map +1 -1
- package/dist/commands/project/split/run.js +48 -10
- package/dist/commands/project/sync/git.d.ts +18 -0
- package/dist/commands/project/sync/git.d.ts.map +1 -0
- package/dist/commands/project/sync/git.js +60 -0
- package/dist/commands/project/sync/record.d.ts +22 -0
- package/dist/commands/project/sync/record.d.ts.map +1 -0
- package/dist/commands/project/sync/record.js +133 -0
- package/dist/commands/project/sync/ref-sync.d.ts +120 -0
- package/dist/commands/project/sync/ref-sync.d.ts.map +1 -0
- package/dist/commands/project/sync/ref-sync.js +962 -0
- package/dist/commands/project/sync/resolve-target.d.ts +27 -0
- package/dist/commands/project/sync/resolve-target.d.ts.map +1 -0
- package/dist/commands/project/sync/resolve-target.js +159 -0
- package/dist/commands/shared/oat-paths.d.ts +4 -1
- package/dist/commands/shared/oat-paths.d.ts.map +1 -1
- package/dist/commands/shared/oat-paths.js +2 -2
- package/dist/commands/shared/project-scope.d.ts +23 -0
- package/dist/commands/shared/project-scope.d.ts.map +1 -0
- package/dist/commands/shared/project-scope.js +106 -0
- package/dist/commands/tools/migrate/index.js +1 -1
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-inventory.js +11 -0
- package/dist/commands/tools/shared/pack-lifecycle.js +1 -1
- package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-reconcile.js +4 -1
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +20 -10
- package/dist/commands/tools/update/update-tools.d.ts +2 -0
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/config/oat-config.d.ts +6 -3
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +41 -7
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +2 -1
- package/dist/fs/io.d.ts +2 -1
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +5 -2
- package/dist/projects/split/finalize.d.ts.map +1 -1
- package/dist/projects/split/finalize.js +55 -2
- package/dist/projects/split/resume.d.ts +3 -0
- package/dist/projects/split/resume.d.ts.map +1 -1
- package/dist/projects/split/resume.js +34 -7
- package/dist/projects/split/seed-children.d.ts.map +1 -1
- package/dist/projects/split/seed-children.js +6 -0
- package/dist/projects/split/write-parent.d.ts +7 -0
- package/dist/projects/split/write-parent.d.ts.map +1 -1
- package/dist/projects/split/write-parent.js +7 -4
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +1 -0
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +434 -0
- package/package.json +4 -4
- package/dist/__tests__/skills/split-flow-fixtures.d.ts +0 -50
- package/dist/__tests__/skills/split-flow-fixtures.d.ts.map +0 -1
- package/dist/__tests__/skills/split-flow-fixtures.js +0 -161
- package/dist/commands/__tests__/helpers.d.ts +0 -12
- package/dist/commands/__tests__/helpers.d.ts.map +0 -1
- package/dist/commands/__tests__/helpers.js +0 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-utils.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/archive-utils.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-utils.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/archive-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { execFile as execFileCallback } from 'node:child_process';
|
|
2
2
|
import { createHash, randomUUID } from 'node:crypto';
|
|
3
|
-
import { lstat, readFile, realpath, rename, rm, writeFile, } from 'node:fs/promises';
|
|
3
|
+
import { lstat, readFile, readdir, realpath, rename, rm, writeFile, } from 'node:fs/promises';
|
|
4
4
|
import { basename, dirname, isAbsolute, join, posix as path, relative, resolve, sep, } from 'node:path';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
|
+
import { defaultGitRunner } from '../../project/sync/git.js';
|
|
7
|
+
import { readSyncedRecord, writeSyncedRecord, } from '../../project/sync/record.js';
|
|
8
|
+
import { buildSyncTarget, commitRecordChange, preflightSyncedCheckout, removeSyncedCheckout, } from '../../project/sync/ref-sync.js';
|
|
9
|
+
import { canonicalizePath, resolveProjectScope, resolveScopeRoot, syncedRecordPath, } from '../../shared/project-scope.js';
|
|
6
10
|
import { CliError } from '../../../errors/cli-error.js';
|
|
7
11
|
import { copyDirectory, copySingleFile, dirExists, ensureDir, fileExists, } from '../../../fs/io.js';
|
|
8
12
|
import { loadExplainerPackageCoverage } from './explainer-package-coverage.js';
|
|
@@ -15,6 +19,19 @@ export const ARCHIVE_SNAPSHOT_METADATA_FILENAME = '.oat-archive-source.json';
|
|
|
15
19
|
* (reviews, PR descriptions) rather than project deliverables.
|
|
16
20
|
*/
|
|
17
21
|
export const S3_ARCHIVE_SYNC_EXCLUDES = ['reviews/*', 'pr/*'];
|
|
22
|
+
export function assertExactArchiveProjectRoot(options) {
|
|
23
|
+
const projectScope = resolveProjectScope(options.projectPath, resolveScopeRoot(options.repoRoot, options.projectsRoot, 'shared'), options.repoRoot);
|
|
24
|
+
if (!projectScope) {
|
|
25
|
+
throw new CliError(`Project path \`${options.projectPath}\` is outside the configured shared, local, and synced scope roots; refusing to archive without an originating scope.`, 1);
|
|
26
|
+
}
|
|
27
|
+
const scopeRoot = canonicalizePath(resolveScopeRoot(options.repoRoot, options.projectsRoot, projectScope));
|
|
28
|
+
const projectPath = canonicalizePath(options.projectPath);
|
|
29
|
+
if (dirname(projectPath) !== scopeRoot ||
|
|
30
|
+
basename(projectPath) !== options.projectName) {
|
|
31
|
+
throw new CliError(`Project path \`${options.projectPath}\` must identify the exact direct child \`${options.projectName}\` of the configured ${projectScope} project root; refusing to archive a descendant or mismatched project.`, 1);
|
|
32
|
+
}
|
|
33
|
+
return { canonicalProjectPath: projectPath, projectScope };
|
|
34
|
+
}
|
|
18
35
|
function normalizeS3Uri(s3Uri) {
|
|
19
36
|
return s3Uri.trim().replace(/\/+$/, '');
|
|
20
37
|
}
|
|
@@ -220,6 +237,47 @@ async function resolveUniqueArchivePath(archivePath, dependencies) {
|
|
|
220
237
|
const suffix = timestamp.replace(/[-:TZ.]/g, '').slice(0, 15);
|
|
221
238
|
return `${archivePath}-${suffix}`;
|
|
222
239
|
}
|
|
240
|
+
async function archiveMatchesSnapshot(archivePath, projectName, snapshotName, archiveScope, dependencies) {
|
|
241
|
+
const directoryExists = dependencies.dirExists ?? dirExists;
|
|
242
|
+
if (!(await directoryExists(archivePath))) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const metadata = JSON.parse(await readFile(join(archivePath, ARCHIVE_SNAPSHOT_METADATA_FILENAME), 'utf8'));
|
|
247
|
+
return (isRecord(metadata) &&
|
|
248
|
+
metadata.projectName === projectName &&
|
|
249
|
+
metadata.snapshotName === snapshotName &&
|
|
250
|
+
metadata.scope === archiveScope);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function resolvePersistedArchivePath(archiveBasePath, projectName, snapshotName, archiveScope, dependencies) {
|
|
257
|
+
const archiveRoot = dirname(archiveBasePath);
|
|
258
|
+
const candidates = [archiveBasePath];
|
|
259
|
+
try {
|
|
260
|
+
const entries = await readdir(archiveRoot, { withFileTypes: true });
|
|
261
|
+
candidates.push(...entries
|
|
262
|
+
.filter((entry) => entry.isDirectory())
|
|
263
|
+
.map((entry) => join(archiveRoot, entry.name))
|
|
264
|
+
.filter((candidate) => candidate !== archiveBasePath)
|
|
265
|
+
.sort());
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// The archive root can be absent before the first successful copy.
|
|
269
|
+
}
|
|
270
|
+
const matches = [];
|
|
271
|
+
for (const candidate of candidates) {
|
|
272
|
+
if (await archiveMatchesSnapshot(candidate, projectName, snapshotName, archiveScope, dependencies)) {
|
|
273
|
+
matches.push(candidate);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (matches.length > 1) {
|
|
277
|
+
throw new CliError(`Persisted archive snapshot \`${snapshotName}\` resolves to multiple local archives; refusing an ambiguous retry.`);
|
|
278
|
+
}
|
|
279
|
+
return matches[0] ?? join(archiveRoot, snapshotName);
|
|
280
|
+
}
|
|
223
281
|
function buildLocalOnlyArchiveWarning(projectName, archiveProjectPath, primaryRepoRoot) {
|
|
224
282
|
const primaryMessage = primaryRepoRoot
|
|
225
283
|
? `the primary checkout \`${primaryRepoRoot}\` is unavailable`
|
|
@@ -251,10 +309,19 @@ export async function resolveArchiveProjectTarget(options, dependencies = {}) {
|
|
|
251
309
|
}
|
|
252
310
|
}
|
|
253
311
|
const archiveBasePath = resolveCompletionArchivePath(archiveRepoRoot, archiveProjectPath);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
312
|
+
let archivePath;
|
|
313
|
+
if (options.archiveSnapshot) {
|
|
314
|
+
if (!options.archiveScope) {
|
|
315
|
+
throw new CliError(`Persisted archive snapshot \`${options.archiveSnapshot}\` is missing its originating project scope; refusing an unscoped retry.`);
|
|
316
|
+
}
|
|
317
|
+
archivePath = await resolvePersistedArchivePath(archiveBasePath, options.projectName, options.archiveSnapshot, options.archiveScope, dependencies);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
archivePath = await resolveUniqueArchivePath(archiveBasePath, {
|
|
321
|
+
dirExists: dependencies.dirExists,
|
|
322
|
+
timestamp: dependencies.timestamp,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
258
325
|
return {
|
|
259
326
|
archiveProjectPath,
|
|
260
327
|
archiveRepoRoot,
|
|
@@ -273,6 +340,22 @@ export function assertDurableArchiveProjectTarget(target) {
|
|
|
273
340
|
async function writeArchiveSnapshotMetadata(archivePath, metadata) {
|
|
274
341
|
await writeFile(join(archivePath, ARCHIVE_SNAPSHOT_METADATA_FILENAME), `${JSON.stringify(metadata, null, 2)}\n`, 'utf8');
|
|
275
342
|
}
|
|
343
|
+
async function verifyArchiveSnapshotMetadata(archivePath, expected) {
|
|
344
|
+
let actual;
|
|
345
|
+
try {
|
|
346
|
+
actual = JSON.parse(await readFile(join(archivePath, ARCHIVE_SNAPSHOT_METADATA_FILENAME), 'utf8'));
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
throw new CliError(`Existing archive \`${archivePath}\` cannot be verified for retry; restore or remove it before retrying.`);
|
|
350
|
+
}
|
|
351
|
+
if (!isRecord(actual) ||
|
|
352
|
+
actual.projectName !== expected.projectName ||
|
|
353
|
+
actual.snapshotName !== expected.snapshotName ||
|
|
354
|
+
actual.scope !== expected.scope ||
|
|
355
|
+
actual.sourceRefSha !== expected.sourceRefSha) {
|
|
356
|
+
throw new CliError(`Existing archive \`${archivePath}\` does not match persisted snapshot \`${expected.snapshotName}\`; refusing to overwrite it.`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
276
359
|
async function exportProjectSummary(archivePath, snapshotName, summaryExportPath, repoRoot, dependencies) {
|
|
277
360
|
const summarySource = join(archivePath, 'summary.md');
|
|
278
361
|
const exists = dependencies.fileExists ?? fileExists;
|
|
@@ -281,6 +364,16 @@ async function exportProjectSummary(archivePath, snapshotName, summaryExportPath
|
|
|
281
364
|
}
|
|
282
365
|
const summaryTarget = join(repoRoot, summaryExportPath, `${snapshotName}.md`);
|
|
283
366
|
const copySummary = dependencies.copySingleFile ?? copySingleFile;
|
|
367
|
+
if (await pathExists(summaryTarget)) {
|
|
368
|
+
const [sourceContents, targetContents] = await Promise.all([
|
|
369
|
+
readFile(summarySource),
|
|
370
|
+
readFile(summaryTarget),
|
|
371
|
+
]);
|
|
372
|
+
if (!sourceContents.equals(targetContents)) {
|
|
373
|
+
throw new CliError(`Existing summary export \`${summaryTarget}\` does not match persisted snapshot \`${snapshotName}\`; refusing to overwrite it.`);
|
|
374
|
+
}
|
|
375
|
+
return summaryTarget;
|
|
376
|
+
}
|
|
284
377
|
await copySummary(summarySource, summaryTarget);
|
|
285
378
|
return summaryTarget;
|
|
286
379
|
}
|
|
@@ -659,7 +752,37 @@ async function exportSelectedProjectRecap(options, snapshotName, dependencies) {
|
|
|
659
752
|
const { sourceRunRoot, manifestContents: sourceManifestContents, terminalEvidence: sourceTerminalEvidence, packagePaths, } = verified;
|
|
660
753
|
const exportRoot = join(options.repoRoot, '.oat', 'repo', 'reference', 'project-recaps', snapshotName);
|
|
661
754
|
if (await pathExists(exportRoot)) {
|
|
662
|
-
|
|
755
|
+
let exportedManifestContents;
|
|
756
|
+
try {
|
|
757
|
+
exportedManifestContents = await readFile(join(exportRoot, 'manifest.json'), 'utf8');
|
|
758
|
+
}
|
|
759
|
+
catch {
|
|
760
|
+
throw new CliError(`Project recap export destination \`${exportRoot}\` already exists and cannot be verified for retry.`);
|
|
761
|
+
}
|
|
762
|
+
if (exportedManifestContents !== sourceManifestContents) {
|
|
763
|
+
throw new CliError(`Existing project recap export \`${exportRoot}\` does not match persisted snapshot \`${snapshotName}\`.`);
|
|
764
|
+
}
|
|
765
|
+
const exportedManifest = await parseProjectRecapManifest(exportedManifestContents);
|
|
766
|
+
const verifiedArtifactCount = await verifyProjectRecapImmutableHashes(exportRoot, exportedManifest);
|
|
767
|
+
await verifyProjectRecapTerminalEvidence(exportRoot, exportedManifest, sourceTerminalEvidence ?? undefined);
|
|
768
|
+
const exactCoverage = (await loadExplainerPackageCoverage());
|
|
769
|
+
try {
|
|
770
|
+
await exactCoverage.enforceRunPackageInventory(exportRoot, exportedManifest, { includeTerminalEvidence: sourceTerminalEvidence !== null });
|
|
771
|
+
}
|
|
772
|
+
catch {
|
|
773
|
+
throw new CliError(`Existing project recap export \`${exportRoot}\` has invalid content.`);
|
|
774
|
+
}
|
|
775
|
+
return {
|
|
776
|
+
export: {
|
|
777
|
+
sourceRunRoot,
|
|
778
|
+
exportRoot,
|
|
779
|
+
manifest: {
|
|
780
|
+
relativePath: 'manifest.json',
|
|
781
|
+
verifiedArtifactCount,
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
createdByAttempt: false,
|
|
785
|
+
};
|
|
663
786
|
}
|
|
664
787
|
const temporaryRoot = `${exportRoot}.tmp-${randomUUID()}`;
|
|
665
788
|
const makeDir = dependencies.ensureDir ?? ensureDir;
|
|
@@ -692,12 +815,15 @@ async function exportSelectedProjectRecap(options, snapshotName, dependencies) {
|
|
|
692
815
|
}
|
|
693
816
|
await renamePath(temporaryRoot, exportRoot);
|
|
694
817
|
return {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
818
|
+
export: {
|
|
819
|
+
sourceRunRoot,
|
|
820
|
+
exportRoot,
|
|
821
|
+
manifest: {
|
|
822
|
+
relativePath: 'manifest.json',
|
|
823
|
+
verifiedArtifactCount,
|
|
824
|
+
},
|
|
700
825
|
},
|
|
826
|
+
createdByAttempt: true,
|
|
701
827
|
};
|
|
702
828
|
}
|
|
703
829
|
catch (error) {
|
|
@@ -714,26 +840,127 @@ export async function archiveProjectOnCompletion(options, dependencies = {}) {
|
|
|
714
840
|
const execFile = dependencies.execFile ?? execFileAsync;
|
|
715
841
|
const timestamp = dependencies.timestamp?.() ?? new Date().toISOString();
|
|
716
842
|
const snapshotName = buildArchiveSnapshotName(options.projectName, timestamp);
|
|
843
|
+
const syncedRoot = resolveScopeRoot(options.repoRoot, options.projectsRoot, 'synced');
|
|
844
|
+
const recordPath = syncedRecordPath(syncedRoot, options.projectName);
|
|
845
|
+
const readRecord = dependencies.readSyncedRecord ?? readSyncedRecord;
|
|
846
|
+
const writeRecord = dependencies.writeSyncedRecord ?? writeSyncedRecord;
|
|
847
|
+
const { canonicalProjectPath, projectScope } = assertExactArchiveProjectRoot(options);
|
|
848
|
+
const isSynced = projectScope === 'synced';
|
|
849
|
+
const record = isSynced ? await readRecord(recordPath) : null;
|
|
850
|
+
const syncTarget = isSynced
|
|
851
|
+
? buildSyncTarget(options.repoRoot, options.projectsRoot, options.projectName)
|
|
852
|
+
: null;
|
|
853
|
+
const git = dependencies.gitRunner ?? defaultGitRunner;
|
|
854
|
+
let activeRecord = record;
|
|
855
|
+
let sourceRefSha;
|
|
856
|
+
if (syncTarget) {
|
|
857
|
+
if (!activeRecord) {
|
|
858
|
+
throw new CliError(`Synced project ${options.projectName} is missing its discovery record; restore the record or run oat project pull ${options.projectName} from a clean checkout to adopt the project before archiving.`, 2);
|
|
859
|
+
}
|
|
860
|
+
const preflight = await (dependencies.preflightSyncedCheckout ?? preflightSyncedCheckout)(syncTarget, git);
|
|
861
|
+
if (preflight.status !== 'clean' &&
|
|
862
|
+
!(preflight.status === 'absent' && activeRecord.status === 'complete')) {
|
|
863
|
+
const recoveryCommand = preflight.status === 'absent'
|
|
864
|
+
? `oat project pull ${options.projectName}`
|
|
865
|
+
: `oat project push ${options.projectName}`;
|
|
866
|
+
throw new CliError(`Synced project ${options.projectName} is ${preflight.status}; run ${recoveryCommand} before archiving.`, 1);
|
|
867
|
+
}
|
|
868
|
+
sourceRefSha =
|
|
869
|
+
preflight.sha ??
|
|
870
|
+
(await git.run(['rev-parse', syncTarget.ref], { cwd: options.repoRoot }))
|
|
871
|
+
.stdout;
|
|
872
|
+
if (!/^[0-9a-f]{40}$/.test(sourceRefSha)) {
|
|
873
|
+
throw new CliError(`Unable to bind archive retry identity for ${options.projectName} to ${syncTarget.ref}.`, 2);
|
|
874
|
+
}
|
|
875
|
+
if (activeRecord.archiveSourceRefSha &&
|
|
876
|
+
activeRecord.archiveSourceRefSha !== sourceRefSha) {
|
|
877
|
+
throw new CliError(`Archive retry for ${options.projectName} is bound to source ref ${activeRecord.archiveSourceRefSha}, but ${syncTarget.ref} is now ${sourceRefSha}. Restore the retained ref to the recorded commit to finish this archive transaction, or preserve the existing snapshot and start a separately reviewed recovery; refusing to accept stale archive content.`, 1);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
717
880
|
const archiveTarget = await resolveArchiveProjectTarget({
|
|
718
881
|
repoRoot: options.repoRoot,
|
|
719
882
|
projectsRoot: options.projectsRoot,
|
|
720
883
|
projectName: options.projectName,
|
|
884
|
+
...(activeRecord?.archiveSnapshot
|
|
885
|
+
? {
|
|
886
|
+
archiveSnapshot: activeRecord.archiveSnapshot,
|
|
887
|
+
archiveScope: projectScope,
|
|
888
|
+
}
|
|
889
|
+
: {}),
|
|
721
890
|
}, dependencies);
|
|
722
891
|
assertDurableArchiveProjectTarget(archiveTarget);
|
|
892
|
+
// Reassert the identity immediately before the first durable mutation. The
|
|
893
|
+
// archive transaction must never bind a descendant source to a sibling
|
|
894
|
+
// record/ref that merely shares its basename.
|
|
895
|
+
if (assertExactArchiveProjectRoot(options).canonicalProjectPath !==
|
|
896
|
+
canonicalProjectPath) {
|
|
897
|
+
throw new CliError(`Project path \`${options.projectPath}\` changed identity during archive preflight; refusing to mutate archive state.`, 1);
|
|
898
|
+
}
|
|
899
|
+
if (syncTarget &&
|
|
900
|
+
canonicalProjectPath !== canonicalizePath(syncTarget.projectPath)) {
|
|
901
|
+
throw new CliError(`Synced archive identity for ${options.projectName} does not match its canonical checkout, record, and ref.`, 1);
|
|
902
|
+
}
|
|
723
903
|
const archivePath = archiveTarget.archivePath;
|
|
724
|
-
const
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
904
|
+
const exportIdentity = syncTarget
|
|
905
|
+
? (activeRecord?.archiveSnapshot ?? snapshotName)
|
|
906
|
+
: snapshotName;
|
|
907
|
+
const snapshotId = syncTarget ? exportIdentity : basename(archivePath);
|
|
908
|
+
const shouldPersistArchiveSnapshot = Boolean(syncTarget &&
|
|
909
|
+
activeRecord &&
|
|
910
|
+
(!activeRecord.archiveSnapshot || !activeRecord.archiveSourceRefSha));
|
|
911
|
+
if (shouldPersistArchiveSnapshot && activeRecord) {
|
|
912
|
+
activeRecord = {
|
|
913
|
+
...activeRecord,
|
|
914
|
+
archiveSnapshot: exportIdentity,
|
|
915
|
+
archiveSourceRefSha: sourceRefSha,
|
|
916
|
+
};
|
|
917
|
+
await writeRecord(recordPath, activeRecord);
|
|
918
|
+
}
|
|
919
|
+
const archiveExists = await (dependencies.dirExists ?? dirExists)(archivePath);
|
|
920
|
+
if (archiveExists) {
|
|
921
|
+
await verifyArchiveSnapshotMetadata(archivePath, {
|
|
729
922
|
projectName: options.projectName,
|
|
730
|
-
snapshotName,
|
|
923
|
+
snapshotName: exportIdentity,
|
|
924
|
+
scope: projectScope,
|
|
925
|
+
...(sourceRefSha ? { sourceRefSha } : {}),
|
|
731
926
|
});
|
|
732
|
-
|
|
927
|
+
}
|
|
928
|
+
const projectSourcePath = (await pathExists(options.projectPath))
|
|
929
|
+
? options.projectPath
|
|
930
|
+
: archivePath;
|
|
931
|
+
const attemptedProjectRecapExport = await exportSelectedProjectRecap({ ...options, projectPath: projectSourcePath }, exportIdentity, dependencies);
|
|
932
|
+
const projectRecapExport = attemptedProjectRecapExport?.export ?? null;
|
|
933
|
+
if (!archiveExists) {
|
|
934
|
+
try {
|
|
935
|
+
await makeDir(dirname(archivePath));
|
|
936
|
+
await copyProjectDirectory(options.projectPath, archivePath, (_sourcePath, relativePath) => relativePath !== 'reviews' &&
|
|
937
|
+
(!syncTarget || relativePath !== '.git'));
|
|
938
|
+
await writeArchiveSnapshotMetadata(archivePath, {
|
|
939
|
+
projectName: options.projectName,
|
|
940
|
+
snapshotName: exportIdentity,
|
|
941
|
+
scope: projectScope,
|
|
942
|
+
...(sourceRefSha ? { sourceRefSha } : {}),
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
catch (error) {
|
|
946
|
+
await removePath(archivePath, { recursive: true, force: true });
|
|
947
|
+
if (attemptedProjectRecapExport?.createdByAttempt) {
|
|
948
|
+
await removePath(attemptedProjectRecapExport.export.exportRoot, {
|
|
949
|
+
recursive: true,
|
|
950
|
+
force: true,
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
throw error;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
try {
|
|
957
|
+
if (!syncTarget) {
|
|
958
|
+
await removePath(options.projectPath, { recursive: true, force: true });
|
|
959
|
+
}
|
|
733
960
|
}
|
|
734
961
|
catch (error) {
|
|
735
|
-
if (
|
|
736
|
-
await removePath(
|
|
962
|
+
if (attemptedProjectRecapExport?.createdByAttempt) {
|
|
963
|
+
await removePath(attemptedProjectRecapExport.export.exportRoot, {
|
|
737
964
|
recursive: true,
|
|
738
965
|
force: true,
|
|
739
966
|
});
|
|
@@ -744,10 +971,19 @@ export async function archiveProjectOnCompletion(options, dependencies = {}) {
|
|
|
744
971
|
let summaryExportFile = null;
|
|
745
972
|
if (options.summaryExportPath) {
|
|
746
973
|
try {
|
|
747
|
-
summaryExportFile = await exportProjectSummary(archivePath,
|
|
974
|
+
summaryExportFile = await exportProjectSummary(archivePath, exportIdentity, options.summaryExportPath, options.repoRoot, dependencies);
|
|
748
975
|
}
|
|
749
976
|
catch (error) {
|
|
750
977
|
const message = error instanceof Error ? error.message : String(error);
|
|
978
|
+
if (syncTarget) {
|
|
979
|
+
if (attemptedProjectRecapExport?.createdByAttempt) {
|
|
980
|
+
await removePath(attemptedProjectRecapExport.export.exportRoot, {
|
|
981
|
+
recursive: true,
|
|
982
|
+
force: true,
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
throw new CliError(`Summary export to \`${options.summaryExportPath}\` failed: ${message}`, 1);
|
|
986
|
+
}
|
|
751
987
|
warnings.push(`Summary export to \`${options.summaryExportPath}\` failed: ${message}`);
|
|
752
988
|
}
|
|
753
989
|
}
|
|
@@ -766,7 +1002,7 @@ export async function archiveProjectOnCompletion(options, dependencies = {}) {
|
|
|
766
1002
|
warnings.push(...access.warnings);
|
|
767
1003
|
if (access.ok) {
|
|
768
1004
|
const remoteRepoRoot = await resolvePrimaryRepoRoot(options.repoRoot, dependencies);
|
|
769
|
-
s3Path = buildProjectArchiveS3Uri(options.s3Uri, remoteRepoRoot,
|
|
1005
|
+
s3Path = buildProjectArchiveS3Uri(options.s3Uri, remoteRepoRoot, exportIdentity);
|
|
770
1006
|
try {
|
|
771
1007
|
const syncArgs = ['s3', 'sync', archivePath, s3Path];
|
|
772
1008
|
for (const pattern of S3_ARCHIVE_SYNC_EXCLUDES) {
|
|
@@ -787,14 +1023,105 @@ export async function archiveProjectOnCompletion(options, dependencies = {}) {
|
|
|
787
1023
|
}
|
|
788
1024
|
}
|
|
789
1025
|
}
|
|
1026
|
+
let lifecycleCommit = null;
|
|
1027
|
+
let recapExportPaths = [];
|
|
1028
|
+
if (syncTarget) {
|
|
1029
|
+
if (!activeRecord) {
|
|
1030
|
+
throw new CliError(`Synced project ${options.projectName} is missing its discovery record.`, 2);
|
|
1031
|
+
}
|
|
1032
|
+
if (projectRecapExport) {
|
|
1033
|
+
recapExportPaths = (await listArchiveExportFiles(projectRecapExport.exportRoot)).filter((filePath) => basename(filePath) !== 'manifest.json' &&
|
|
1034
|
+
basename(filePath) !== 'build-record.json');
|
|
1035
|
+
}
|
|
1036
|
+
activeRecord = {
|
|
1037
|
+
...activeRecord,
|
|
1038
|
+
status: 'complete',
|
|
1039
|
+
completedAt: activeRecord.completedAt ?? timestamp,
|
|
1040
|
+
};
|
|
1041
|
+
await writeRecord(recordPath, activeRecord);
|
|
1042
|
+
if (options.commit !== false) {
|
|
1043
|
+
const pathspecs = [
|
|
1044
|
+
recordPath,
|
|
1045
|
+
...(summaryExportFile ? [summaryExportFile] : []),
|
|
1046
|
+
...recapExportPaths,
|
|
1047
|
+
];
|
|
1048
|
+
const committed = await (dependencies.commitRecordChange ?? commitRecordChange)(options.repoRoot, pathspecs, `chore(oat): complete synced project ${options.projectName}`, git, {
|
|
1049
|
+
summaryExportPath: options.summaryExportPath,
|
|
1050
|
+
projectRoots: syncTarget,
|
|
1051
|
+
recapExportRoot: projectRecapExport?.exportRoot,
|
|
1052
|
+
});
|
|
1053
|
+
lifecycleCommit =
|
|
1054
|
+
committed?.sha ??
|
|
1055
|
+
(await recoverSyncedLifecycleCommit(options.repoRoot, pathspecs, activeRecord, `chore(oat): complete synced project ${options.projectName}`, git));
|
|
1056
|
+
}
|
|
1057
|
+
const removed = await (dependencies.removeSyncedCheckout ?? removeSyncedCheckout)(syncTarget, git);
|
|
1058
|
+
if (removed.status !== 'removed' && removed.status !== 'absent') {
|
|
1059
|
+
throw new CliError(`Synced checkout became ${removed.status} during archive; run oat project push ${options.projectName} and retry.`, 1);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
790
1062
|
return {
|
|
791
1063
|
archivePath,
|
|
792
1064
|
s3Path,
|
|
793
1065
|
summaryExportFile,
|
|
794
1066
|
projectRecapExport,
|
|
795
1067
|
warnings,
|
|
1068
|
+
lifecycleCommit,
|
|
1069
|
+
recapExportPaths,
|
|
1070
|
+
snapshotId,
|
|
796
1071
|
};
|
|
797
1072
|
}
|
|
1073
|
+
async function recoverSyncedLifecycleCommit(repoRoot, pathspecs, record, expectedSubject, git) {
|
|
1074
|
+
const [recordPathspec] = pathspecs;
|
|
1075
|
+
if (!recordPathspec) {
|
|
1076
|
+
throw new CliError(`Unable to recover the prior lifecycle commit for ${record.slug}: no lifecycle paths were supplied.`, 2);
|
|
1077
|
+
}
|
|
1078
|
+
const recordPath = relative(resolve(repoRoot), resolve(recordPathspec))
|
|
1079
|
+
.split(sep)
|
|
1080
|
+
.join('/');
|
|
1081
|
+
const normalizedPathspecs = pathspecs
|
|
1082
|
+
.map((pathspec) => relative(resolve(repoRoot), resolve(pathspec)))
|
|
1083
|
+
.map((pathspec) => pathspec.split(sep).join('/'))
|
|
1084
|
+
.sort();
|
|
1085
|
+
const candidate = (await git.run(['log', '-1', '--format=%H', '--', recordPath], {
|
|
1086
|
+
cwd: repoRoot,
|
|
1087
|
+
})).stdout;
|
|
1088
|
+
if (!/^[0-9a-f]{40}$/.test(candidate)) {
|
|
1089
|
+
throw new CliError(`Unable to recover the prior lifecycle commit for ${record.slug}.`, 2);
|
|
1090
|
+
}
|
|
1091
|
+
const subject = (await git.run(['show', '-s', '--format=%s', candidate], { cwd: repoRoot })).stdout;
|
|
1092
|
+
const ancestor = await git.run(['merge-base', '--is-ancestor', candidate, 'HEAD'], { cwd: repoRoot, allowFailure: true });
|
|
1093
|
+
const changedPaths = (await git.run(['diff-tree', '--no-commit-id', '--name-only', '-r', candidate], { cwd: repoRoot })).stdout
|
|
1094
|
+
.split('\n')
|
|
1095
|
+
.filter(Boolean)
|
|
1096
|
+
.sort();
|
|
1097
|
+
const contentsMatch = await git.run(['diff', '--quiet', candidate, '--', ...normalizedPathspecs], { cwd: repoRoot, allowFailure: true });
|
|
1098
|
+
const committedRecord = await git.run(['show', `${candidate}:${recordPath}`], { cwd: repoRoot });
|
|
1099
|
+
let parsedRecord;
|
|
1100
|
+
try {
|
|
1101
|
+
parsedRecord = JSON.parse(committedRecord.stdout);
|
|
1102
|
+
}
|
|
1103
|
+
catch {
|
|
1104
|
+
parsedRecord = null;
|
|
1105
|
+
}
|
|
1106
|
+
if (subject !== expectedSubject ||
|
|
1107
|
+
ancestor.code !== 0 ||
|
|
1108
|
+
contentsMatch.code !== 0 ||
|
|
1109
|
+
JSON.stringify(changedPaths) !== JSON.stringify(normalizedPathspecs) ||
|
|
1110
|
+
JSON.stringify(parsedRecord) !== JSON.stringify(record)) {
|
|
1111
|
+
throw new CliError(`Unable to recover lifecycle commit ${candidate} for ${record.slug}: subject, path set, contents, or branch relationship did not match the completed archive transaction.`, 2);
|
|
1112
|
+
}
|
|
1113
|
+
return candidate;
|
|
1114
|
+
}
|
|
1115
|
+
async function listArchiveExportFiles(root, current = root) {
|
|
1116
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
1117
|
+
const files = await Promise.all(entries.map(async (entry) => {
|
|
1118
|
+
const entryPath = join(current, entry.name);
|
|
1119
|
+
return entry.isDirectory()
|
|
1120
|
+
? listArchiveExportFiles(root, entryPath)
|
|
1121
|
+
: [entryPath];
|
|
1122
|
+
}));
|
|
1123
|
+
return files.flat().sort();
|
|
1124
|
+
}
|
|
798
1125
|
export async function ensureS3ArchiveAccess(options, dependencies = {}) {
|
|
799
1126
|
if (!requiresRemoteAccess(options)) {
|
|
800
1127
|
return { ok: true, warnings: [] };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAIL,KAAK,qCAAqC,EAC3C,MAAM,eAAe,CAAC;AACvB,OAAO,EAIL,KAAK,iCAAiC,EACvC,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,kBAAkB,EAClB,iCAAiC,GAClC,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,kBAAkB,EAClB,qCAAqC,GACtC,MAAM,eAAe,CAAC;AAEvB,KAAK,0BAA0B,GAAG,iCAAiC,GACjE,qCAAqC,CAAC;AAKxC,wBAAgB,2BAA2B,CACzC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAIL,KAAK,qCAAqC,EAC3C,MAAM,eAAe,CAAC;AACvB,OAAO,EAIL,KAAK,iCAAiC,EACvC,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,kBAAkB,EAClB,iCAAiC,GAClC,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,kBAAkB,EAClB,qCAAqC,GACtC,MAAM,eAAe,CAAC;AAEvB,KAAK,0BAA0B,GAAG,iCAAiC,GACjE,qCAAqC,CAAC;AAKxC,wBAAgB,2BAA2B,CACzC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAiFT"}
|
|
@@ -13,6 +13,7 @@ export function createProjectArchiveCommand(overrides = {}) {
|
|
|
13
13
|
.description('Manage archived project data')
|
|
14
14
|
.argument('[project-path]', 'Project path to archive')
|
|
15
15
|
.option('--dry-run', 'Preview archive without moving files or syncing S3')
|
|
16
|
+
.option('--no-commit', 'Manual/library use only: omit the synced lifecycle commit receipt')
|
|
16
17
|
.option('--project-recap-run <path>', 'Export the selected project-relative recap run before archiving')
|
|
17
18
|
.addHelpText('afterAll', '\nPull archived project data with `oat repo archive sync [project-name]`; `oat project archive sync` is deprecated.')
|
|
18
19
|
.action(async (projectPath, options, command) => {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { buildCommandContext, type CommandContext } from '../../../app/command-context.js';
|
|
2
|
+
import { readSyncedRecord } from '../../project/sync/record.js';
|
|
2
3
|
import { type OatConfig, type OatLocalConfig } from '../../../config/oat-config.js';
|
|
3
|
-
import { resolveArchiveProjectTarget, resolvePrimaryRepoRoot, verifySelectedProjectRecapForArchive, type ArchiveProjectOnCompletionOptions, type ArchiveProjectOnCompletionResult } from './archive-utils.js';
|
|
4
|
+
import { assertExactArchiveProjectRoot, resolveArchiveProjectTarget, resolvePrimaryRepoRoot, verifySelectedProjectRecapForArchive, type ArchiveProjectOnCompletionOptions, type ArchiveProjectOnCompletionResult } from './archive-utils.js';
|
|
4
5
|
export interface ArchivePushOptions {
|
|
5
6
|
dryRun?: boolean;
|
|
6
7
|
projectRecapRun?: string;
|
|
8
|
+
commit?: boolean;
|
|
7
9
|
}
|
|
8
10
|
export interface ProjectArchivePushCommandDependencies {
|
|
9
11
|
buildCommandContext: (options: Parameters<typeof buildCommandContext>[0]) => CommandContext;
|
|
@@ -13,8 +15,10 @@ export interface ProjectArchivePushCommandDependencies {
|
|
|
13
15
|
resolveProjectsRoot: (repoRoot: string, env: NodeJS.ProcessEnv) => Promise<string>;
|
|
14
16
|
resolvePrimaryRepoRoot: typeof resolvePrimaryRepoRoot;
|
|
15
17
|
resolveArchiveProjectTarget: typeof resolveArchiveProjectTarget;
|
|
18
|
+
readSyncedRecord: typeof readSyncedRecord;
|
|
16
19
|
verifySelectedProjectRecapForArchive: typeof verifySelectedProjectRecapForArchive;
|
|
17
20
|
archiveProjectOnCompletion: (options: ArchiveProjectOnCompletionOptions) => Promise<ArchiveProjectOnCompletionResult>;
|
|
21
|
+
assertExactArchiveProjectRoot: typeof assertExactArchiveProjectRoot;
|
|
18
22
|
processEnv: NodeJS.ProcessEnv;
|
|
19
23
|
timestamp: () => string;
|
|
20
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-runner.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/push-runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"push-runner.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/archive/push-runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAOjE,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAEL,6BAA6B,EAI7B,2BAA2B,EAC3B,sBAAsB,EACtB,oCAAoC,EAEpC,KAAK,iCAAiC,EACtC,KAAK,gCAAgC,EAEtC,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qCAAqC;IACpD,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;IAChE,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,oCAAoC,EAAE,OAAO,oCAAoC,CAAC;IAClF,0BAA0B,EAAE,CAC1B,OAAO,EAAE,iCAAiC,KACvC,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAC/C,6BAA6B,EAAE,OAAO,6BAA6B,CAAC;IACpE,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;IAC9B,SAAS,EAAE,MAAM,MAAM,CAAC;CACzB;AAsBD,wBAAgB,4CAA4C,IAAI,qCAAqC,CAgBpG;AAuJD,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,qCAAqC,EACnD,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CAyGf"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { basename, isAbsolute, join } from 'node:path';
|
|
2
2
|
import { buildCommandContext } from '../../../app/command-context.js';
|
|
3
|
+
import { readSyncedRecord } from '../../project/sync/record.js';
|
|
3
4
|
import { resolveProjectsRoot } from '../../shared/oat-paths.js';
|
|
5
|
+
import { resolveScopeRoot, syncedRecordPath, } from '../../shared/project-scope.js';
|
|
4
6
|
import { readOatConfig, readOatLocalConfig, } from '../../../config/oat-config.js';
|
|
5
7
|
import { CliError } from '../../../errors/cli-error.js';
|
|
6
8
|
import { resolveProjectRoot } from '../../../fs/paths.js';
|
|
7
|
-
import { archiveProjectOnCompletion, assertDurableArchiveProjectTarget, buildArchiveSnapshotName, buildProjectArchiveS3Uri, resolveArchiveProjectTarget, resolvePrimaryRepoRoot, verifySelectedProjectRecapForArchive, } from './archive-utils.js';
|
|
9
|
+
import { archiveProjectOnCompletion, assertExactArchiveProjectRoot, assertDurableArchiveProjectTarget, buildArchiveSnapshotName, buildProjectArchiveS3Uri, resolveArchiveProjectTarget, resolvePrimaryRepoRoot, verifySelectedProjectRecapForArchive, } from './archive-utils.js';
|
|
8
10
|
export function defaultProjectArchivePushCommandDependencies() {
|
|
9
11
|
return {
|
|
10
12
|
buildCommandContext,
|
|
@@ -14,8 +16,10 @@ export function defaultProjectArchivePushCommandDependencies() {
|
|
|
14
16
|
resolveProjectsRoot,
|
|
15
17
|
resolvePrimaryRepoRoot,
|
|
16
18
|
resolveArchiveProjectTarget,
|
|
19
|
+
readSyncedRecord,
|
|
17
20
|
verifySelectedProjectRecapForArchive,
|
|
18
21
|
archiveProjectOnCompletion,
|
|
22
|
+
assertExactArchiveProjectRoot,
|
|
19
23
|
processEnv: process.env,
|
|
20
24
|
timestamp: () => new Date().toISOString(),
|
|
21
25
|
};
|
|
@@ -53,10 +57,10 @@ function buildArchiveOptions(repoRoot, config, projectsRoot, target, options) {
|
|
|
53
57
|
projectRecapRun: options.projectRecapRun,
|
|
54
58
|
awsProfile: config.archive?.awsProfile,
|
|
55
59
|
awsRegion: config.archive?.awsRegion,
|
|
60
|
+
...(options.commit === false ? { commit: false } : {}),
|
|
56
61
|
};
|
|
57
62
|
}
|
|
58
|
-
async function buildDryRunReport(dependencies, repoRoot, config, target, archiveTarget) {
|
|
59
|
-
const snapshotName = buildArchiveSnapshotName(target.projectName, dependencies.timestamp());
|
|
63
|
+
async function buildDryRunReport(dependencies, repoRoot, config, target, archiveTarget, snapshotName, projectScope) {
|
|
60
64
|
const remoteRepoRoot = await dependencies.resolvePrimaryRepoRoot(repoRoot);
|
|
61
65
|
const s3Path = config.archive?.s3Uri && config.archive.s3SyncOnComplete === true
|
|
62
66
|
? buildProjectArchiveS3Uri(config.archive.s3Uri, remoteRepoRoot, snapshotName)
|
|
@@ -73,6 +77,11 @@ async function buildDryRunReport(dependencies, repoRoot, config, target, archive
|
|
|
73
77
|
s3Path,
|
|
74
78
|
summaryExportFile,
|
|
75
79
|
warnings: [],
|
|
80
|
+
lifecycleCommit: null,
|
|
81
|
+
recapExportPaths: [],
|
|
82
|
+
snapshotId: projectScope === 'synced'
|
|
83
|
+
? snapshotName
|
|
84
|
+
: basename(archiveTarget.archivePath),
|
|
76
85
|
};
|
|
77
86
|
}
|
|
78
87
|
function emitArchivePushText(report, summaryExportPath, logger) {
|
|
@@ -113,10 +122,27 @@ export async function runArchivePushCommand(dependencies, projectPathArg, option
|
|
|
113
122
|
const config = await dependencies.readOatConfig(repoRoot);
|
|
114
123
|
const projectsRoot = await dependencies.resolveProjectsRoot(repoRoot, dependencies.processEnv);
|
|
115
124
|
const target = await resolveArchiveTarget(dependencies, repoRoot, projectPathArg);
|
|
125
|
+
const { projectScope } = dependencies.assertExactArchiveProjectRoot({
|
|
126
|
+
repoRoot,
|
|
127
|
+
projectPath: target.projectPath,
|
|
128
|
+
projectName: target.projectName,
|
|
129
|
+
projectsRoot,
|
|
130
|
+
});
|
|
131
|
+
const defaultSnapshotName = buildArchiveSnapshotName(target.projectName, dependencies.timestamp());
|
|
132
|
+
const syncedRecord = projectScope === 'synced'
|
|
133
|
+
? await dependencies.readSyncedRecord(syncedRecordPath(resolveScopeRoot(repoRoot, projectsRoot, 'synced'), target.projectName))
|
|
134
|
+
: null;
|
|
135
|
+
const snapshotName = syncedRecord?.archiveSnapshot ?? defaultSnapshotName;
|
|
116
136
|
const archiveTarget = await dependencies.resolveArchiveProjectTarget({
|
|
117
137
|
repoRoot,
|
|
118
138
|
projectsRoot,
|
|
119
139
|
projectName: target.projectName,
|
|
140
|
+
...(syncedRecord?.archiveSnapshot
|
|
141
|
+
? {
|
|
142
|
+
archiveSnapshot: syncedRecord.archiveSnapshot,
|
|
143
|
+
archiveScope: projectScope ?? undefined,
|
|
144
|
+
}
|
|
145
|
+
: {}),
|
|
120
146
|
}, {
|
|
121
147
|
env: dependencies.processEnv,
|
|
122
148
|
timestamp: dependencies.timestamp,
|
|
@@ -127,7 +153,7 @@ export async function runArchivePushCommand(dependencies, projectPathArg, option
|
|
|
127
153
|
}
|
|
128
154
|
const dryRun = options.dryRun === true || context.dryRun;
|
|
129
155
|
if (dryRun) {
|
|
130
|
-
const report = await buildDryRunReport(dependencies, repoRoot, config, target, archiveTarget);
|
|
156
|
+
const report = await buildDryRunReport(dependencies, repoRoot, config, target, archiveTarget, snapshotName, projectScope);
|
|
131
157
|
emitArchivePushReport(report, config.archive?.summaryExportPath, context);
|
|
132
158
|
process.exitCode = 0;
|
|
133
159
|
return;
|
|
@@ -145,6 +171,9 @@ export async function runArchivePushCommand(dependencies, projectPathArg, option
|
|
|
145
171
|
? { projectRecapExport: result.projectRecapExport }
|
|
146
172
|
: {}),
|
|
147
173
|
warnings: result.warnings,
|
|
174
|
+
lifecycleCommit: result.lifecycleCommit,
|
|
175
|
+
recapExportPaths: result.recapExportPaths,
|
|
176
|
+
snapshotId: result.snapshotId,
|
|
148
177
|
};
|
|
149
178
|
emitArchivePushReport(report, config.archive?.summaryExportPath, context);
|
|
150
179
|
process.exitCode = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/complete-state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,IAAI,eAAe,EAC3B,SAAS,IAAI,gBAAgB,EAC9B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,UAAU,gCAAgC;IACxC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,EAAE,OAAO,eAAe,CAAC;IACjC,SAAS,EAAE,OAAO,gBAAgB,CAAC;IACnC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/complete-state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,IAAI,eAAe,EAC3B,SAAS,IAAI,gBAAgB,EAC9B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,UAAU,gCAAgC;IACxC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,EAAE,OAAO,eAAe,CAAC;IACjC,SAAS,EAAE,OAAO,gBAAgB,CAAC;IACnC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AA4ED,wBAAgB,iCAAiC,CAC/C,SAAS,GAAE,OAAO,CAAC,gCAAgC,CAAM,GACxD,OAAO,CA2BT"}
|