ushman-ledger 0.3.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -14
- package/README.md +8 -56
- package/dist/archive-journal.d.ts +29 -18
- package/dist/archive-journal.d.ts.map +1 -1
- package/dist/archive-journal.js +17 -17
- package/dist/builders.d.ts +52 -374
- package/dist/builders.d.ts.map +1 -1
- package/dist/builders.js +10 -60
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -14
- package/dist/handle.d.ts +2 -2
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +1 -14
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/lab-min.d.ts +7 -7
- package/dist/lab-min.d.ts.map +1 -1
- package/dist/lab-min.js +7 -9
- package/dist/list.d.ts +84 -325
- package/dist/list.d.ts.map +1 -1
- package/dist/read-index.d.ts +45 -57
- package/dist/read-index.d.ts.map +1 -1
- package/dist/read-index.js +16 -34
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +27 -114
- package/dist/recovery.d.ts +19 -8
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +13 -13
- package/dist/render/retro.d.ts.map +1 -1
- package/dist/render/retro.js +1 -4
- package/dist/schema/entry.d.ts +1365 -3291
- package/dist/schema/entry.d.ts.map +1 -1
- package/dist/schema/entry.js +184 -516
- package/dist/schema/manifest.d.ts +28 -41
- package/dist/schema/manifest.d.ts.map +1 -1
- package/dist/schema/manifest.js +20 -24
- package/dist/schema/note.d.ts +3 -9
- package/dist/schema/note.d.ts.map +1 -1
- package/dist/schema/note.js +2 -2
- package/dist/storage/filesystem.d.ts +0 -1
- package/dist/storage/filesystem.d.ts.map +1 -1
- package/dist/storage/filesystem.js +4 -4
- package/package.json +3 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [1.0.
|
|
4
|
-
|
|
5
|
-
- Added structured patch payloads with touched paths, diff hashes, line hunks, and before/after file hashes.
|
|
6
|
-
- Added UUIDv7-backed `validator-result` payload ids, structured `stage-transition` and `operator-decision` payloads, and the new first-class ledger kinds required by ushman v4.1 analytics.
|
|
7
|
-
- Added cached `render --to=analytics-summary` output, legacy-entry read migration markers, and write-side builder helpers for the structured record kinds.
|
|
3
|
+
## [1.0.1] - 2026-05-16
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
- Tightened the schema surface to the ledger primitives the v4 orchestrator actively uses.
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
- Stored `validator-result` entries now persist `payload.id`; helper-side synthesis is only a temporary migration convenience.
|
|
13
|
-
- Structured patch writes now enforce the machine-readable payload fields instead of accepting prose-only patch metadata.
|
|
14
|
-
|
|
15
|
-
## [0.2.0] - 2026-05-14
|
|
7
|
+
## [1.0.0] - 2026-05-14
|
|
16
8
|
|
|
17
|
-
-
|
|
18
|
-
- Made archive creation crash-recoverable with pending archive journals and post-create tar verification.
|
|
19
|
-
- Added archive recovery tests, read-index rebuild tests, and a manual scale benchmark harness.
|
|
9
|
+
- First stable release: structured `operator-decision`, `strip-decision-reverted`, and `validator-result` payloads; durable read-index sidecar with crash-recoverable archive creation.
|
|
20
10
|
|
|
21
11
|
## [0.1.0] - 2026-05-12
|
|
22
12
|
|
package/README.md
CHANGED
|
@@ -5,11 +5,10 @@ Append-only workspace ledger library and CLI for ushman v4 workspaces.
|
|
|
5
5
|
## What it owns
|
|
6
6
|
|
|
7
7
|
- Ledger entry schemas
|
|
8
|
-
- Structured patch / validator / stage payloads for analytics consumers
|
|
9
8
|
- Serialized manifest-safe entry writes
|
|
10
9
|
- Content-hash idempotency
|
|
11
10
|
- Patch blob storage
|
|
12
|
-
- Retro / JSONL / timeline rendering
|
|
11
|
+
- Retro / JSONL / timeline / dependency-graph rendering
|
|
13
12
|
- Archive integrity output
|
|
14
13
|
- Doctor and coverage helpers
|
|
15
14
|
|
|
@@ -59,7 +58,6 @@ await ledger.record(
|
|
|
59
58
|
);
|
|
60
59
|
|
|
61
60
|
await ledger.render({ to: 'retro' });
|
|
62
|
-
await ledger.render({ to: 'analytics-summary' });
|
|
63
61
|
await ledger.archive('/tmp/ledger.tgz');
|
|
64
62
|
```
|
|
65
63
|
|
|
@@ -74,20 +72,17 @@ ushman-ledger list --workspace=<ws> --json
|
|
|
74
72
|
ushman-ledger render --workspace=<ws> --to=retro
|
|
75
73
|
ushman-ledger render --workspace=<ws> --to=jsonl --out=/tmp/ledger.jsonl
|
|
76
74
|
ushman-ledger render --workspace=<ws> --to=dependency-graph --out=/tmp/ledger.mmd
|
|
77
|
-
ushman-ledger render --workspace=<ws> --to=analytics-summary
|
|
78
|
-
ushman-ledger render --workspace=<ws> --to=analytics-summary --fresh
|
|
79
|
-
ushman-ledger render --workspace=<ws> --to=analytics-summary --json
|
|
80
75
|
ushman-ledger archive --workspace=<ws> --out=/tmp/ledger.tgz
|
|
81
76
|
ushman-ledger doctor --workspace=<ws>
|
|
82
77
|
```
|
|
83
78
|
|
|
84
|
-
Valid record kinds: `tool-invocation`, `agent-patch`, `operator-patch`, `
|
|
79
|
+
Valid record kinds: `tool-invocation`, `agent-patch`, `operator-patch`, `operator-decision`, `validator-result`, `runtime-event`, `note`, `correction`, `strip-decision-reverted`
|
|
85
80
|
|
|
86
81
|
Valid phases: `capture`, `intake`, `seed`, `vendor-extract`, `cleanup`, `parity`, `characterize`, `equiv`, `analyze`, `recover`, `ship`, `migration`
|
|
87
82
|
|
|
88
83
|
Valid note subkinds: `regression`, `automation`, `retro`, `operator`, `tooling-gap`
|
|
89
84
|
|
|
90
|
-
Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph
|
|
85
|
+
Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`
|
|
91
86
|
|
|
92
87
|
## Workspace prerequisite
|
|
93
88
|
|
|
@@ -99,53 +94,12 @@ Valid render targets: `retro`, `jsonl`, `timeline-html`, `dependency-graph`, `an
|
|
|
99
94
|
- With `idempotencyKey`, the key is authoritative within a phase. Reusing the same key with different content in the same phase returns the first recorded entry unchanged.
|
|
100
95
|
- Stored entries copy the idempotency key into `links.idempotencyKey` for auditability.
|
|
101
96
|
|
|
102
|
-
##
|
|
103
|
-
|
|
104
|
-
- Patch entries (`agent-patch`, `operator-patch`) store `payload.touchedPaths`, `payload.fileSha256Before`, `payload.fileSha256After`, `payload.hunks`, `payload.diffSha256`, and `payload.diff`.
|
|
105
|
-
- Stored `validator-result` entries require a UUIDv7 `payload.id`. Callers should provide it in normal operation; the write helpers only synthesize one during the migration window when legacy callers omit it.
|
|
106
|
-
- `stage-transition` entries capture `{ stage, startedAt, endedAt, exitCode, doctorBaselineId? }` explicitly in the ledger.
|
|
107
|
-
- `operator-decision` entries capture `{ action, checkId?, rationale }` in `payload`.
|
|
108
|
-
- `rework.test_retired` is the structured way to retire a seed-emitted test from the pipeline corpus.
|
|
109
|
-
- Legacy on-disk entries still read successfully. The library normalizes them into the current shape and marks them with `_legacy: true`.
|
|
110
|
-
|
|
111
|
-
Example payloads:
|
|
112
|
-
|
|
113
|
-
```json
|
|
114
|
-
{
|
|
115
|
-
"kind": "stage-transition",
|
|
116
|
-
"payload": {
|
|
117
|
-
"stage": "cleanup",
|
|
118
|
-
"startedAt": "2026-05-14T12:00:00.000Z",
|
|
119
|
-
"endedAt": "2026-05-14T12:00:05.000Z",
|
|
120
|
-
"exitCode": 0
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
```json
|
|
126
|
-
{
|
|
127
|
-
"kind": "rework.test_retired",
|
|
128
|
-
"payload": {
|
|
129
|
-
"removedTestPath": "tests/pure/app.test.ts",
|
|
130
|
-
"removedTestSymbols": ["renderApp"],
|
|
131
|
-
"removedBy": "descope",
|
|
132
|
-
"sourceSymbolDeletedFrom": "src/app.ts"
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Migration guide
|
|
138
|
-
|
|
139
|
-
- Historical entries are not rewritten. Old on-disk entries continue to load through read-side normalization.
|
|
140
|
-
- Normalized legacy entries are marked with `_legacy: true` so analytics can distinguish migrated reads from fully structured writes.
|
|
141
|
-
- New writes are expected to use structured payloads. Temporary compatibility logic only remains for omitted `validator-result.payload.id` values.
|
|
142
|
-
|
|
143
|
-
## Analytics summary
|
|
97
|
+
## Payload shapes
|
|
144
98
|
|
|
145
|
-
- `
|
|
146
|
-
-
|
|
147
|
-
- `
|
|
148
|
-
- `
|
|
99
|
+
- `operator-decision` entries capture `{ action, checkId?, rationale }` in `payload`. `action` is one of `bypass-doctor`, `skip-check`, `override-strip-decision`, `override-ship-state`, `manual-parity-assertion`, `ledger-hand-edit`, `escalation`.
|
|
100
|
+
- `strip-decision-reverted` entries capture `{ stripDecisionId, rationale, invalidatedStages? }`.
|
|
101
|
+
- `correction` entries require `links.correctsLedgerId` pointing at the entry they correct.
|
|
102
|
+
- Patch entries (`agent-patch`, `operator-patch`) store a `diff` blob reference and a `rationale`. Patch text is stored once under `.lab/ledger/blobs/` and shared by hash.
|
|
149
103
|
|
|
150
104
|
## Links and coverage
|
|
151
105
|
|
|
@@ -176,7 +130,6 @@ Example payloads:
|
|
|
176
130
|
|
|
177
131
|
- `.lab/ledger/pending/` contains append journals that let the ledger recover incomplete writes after crashes. Do not edit these files by hand.
|
|
178
132
|
- If startup or `doctor` reports a pending commit mismatch, re-open the ledger or rerun the command first so reconciliation can replay or discard the journal safely.
|
|
179
|
-
- If `analytics-summary.json` is invalid or stale, rerun `ushman-ledger render --to=analytics-summary --fresh` to recompute it from the ledger tip.
|
|
180
133
|
- If `doctor` reports manifest or blob corruption, fix the underlying entry/blob mismatch first and rerun `doctor` before attempting `archive`.
|
|
181
134
|
|
|
182
135
|
## Scan behavior
|
|
@@ -205,7 +158,6 @@ Example payloads:
|
|
|
205
158
|
```text
|
|
206
159
|
<ws>/.lab/ledger/
|
|
207
160
|
.manifest.lock
|
|
208
|
-
analytics-summary.json
|
|
209
161
|
manifest.json
|
|
210
162
|
read-index.json
|
|
211
163
|
pending/
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as v from 'valibot';
|
|
2
2
|
import type { LedgerManifest } from './schema/manifest.ts';
|
|
3
|
-
export declare const ArchiveManifestSchema:
|
|
4
|
-
fileHashes:
|
|
5
|
-
path:
|
|
6
|
-
sha256:
|
|
7
|
-
},
|
|
8
|
-
integrityHash:
|
|
9
|
-
schemaVersion:
|
|
10
|
-
},
|
|
11
|
-
export type ArchiveManifest =
|
|
3
|
+
export declare const ArchiveManifestSchema: v.ObjectSchema<{
|
|
4
|
+
readonly fileHashes: v.ArraySchema<v.ObjectSchema<{
|
|
5
|
+
readonly path: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
6
|
+
readonly sha256: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 64, undefined>]>;
|
|
7
|
+
}, undefined>, undefined>;
|
|
8
|
+
readonly integrityHash: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 64, undefined>]>;
|
|
9
|
+
readonly schemaVersion: v.LiteralSchema<"ushman-ledger-archive-manifest/v1", undefined>;
|
|
10
|
+
}, undefined>;
|
|
11
|
+
export type ArchiveManifest = v.InferOutput<typeof ArchiveManifestSchema>;
|
|
12
12
|
export declare const collectFileHashes: (root: string, prefix?: string) => Promise<Array<{
|
|
13
13
|
path: string;
|
|
14
14
|
sha256: string;
|
|
@@ -40,7 +40,6 @@ export declare const reconcilePendingArchivesUnderLock: ({ manifest, workspaceRo
|
|
|
40
40
|
readonly manifest: LedgerManifest;
|
|
41
41
|
readonly workspaceRoot: string;
|
|
42
42
|
}) => Promise<{
|
|
43
|
-
[x: string]: unknown;
|
|
44
43
|
archives: {
|
|
45
44
|
createdAt: string;
|
|
46
45
|
integrityHash: string;
|
|
@@ -48,16 +47,28 @@ export declare const reconcilePendingArchivesUnderLock: ({ manifest, workspaceRo
|
|
|
48
47
|
}[];
|
|
49
48
|
createdAt: string;
|
|
50
49
|
entryCount: number;
|
|
51
|
-
entryLocations:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
entryLocations: {
|
|
51
|
+
[x: string]: {
|
|
52
|
+
phase: "capture" | "intake" | "seed" | "vendor-extract" | "cleanup" | "parity" | "characterize" | "equiv" | "analyze" | "recover" | "ship" | "migration";
|
|
53
|
+
sequence: number;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
idempotencyIndex: {
|
|
57
|
+
[x: string]: {
|
|
58
|
+
[x: string]: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
56
61
|
lastSequence: number;
|
|
57
|
-
perPhaseCounts:
|
|
58
|
-
|
|
62
|
+
perPhaseCounts: {
|
|
63
|
+
[x: string]: number;
|
|
64
|
+
};
|
|
65
|
+
perPhaseLatest: {
|
|
66
|
+
[x: string]: string;
|
|
67
|
+
};
|
|
59
68
|
schemaVersion: "ushman-ledger-manifest/v1";
|
|
60
69
|
updatedAt: string;
|
|
61
70
|
workspaceId: string;
|
|
71
|
+
} & {
|
|
72
|
+
[key: string]: unknown;
|
|
62
73
|
}>;
|
|
63
74
|
//# sourceMappingURL=archive-journal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-journal.d.ts","sourceRoot":"","sources":["../src/archive-journal.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-journal.d.ts","sourceRoot":"","sources":["../src/archive-journal.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAG7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAW3D,eAAO,MAAM,qBAAqB;;;;;;;aAIhC,CAAC;AASH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAyC1E,eAAO,MAAM,iBAAiB,GAC1B,MAAM,MAAM,EACZ,eAAW,KACZ,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAcjD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAU,YAAY,MAAM;;;;;;;EAO7D,CAAC;AA+DF,eAAO,MAAM,iBAAiB,GAAU,2CAGrC;IACC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,uBAAuB,EAAE,eAAe,CAAC;CACrD,kBA2BA,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,mCAG5C;IACC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAChC,kBAMA,CAAC;AA4CF,eAAO,MAAM,mBAAmB,GAAU,yDAKvC;IACC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC,oBAgBA,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,UAAU,MAAM,kBAE1D,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAAU,8BAGrD;IACC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CA,CAAC"}
|
package/dist/archive-journal.js
CHANGED
|
@@ -2,32 +2,32 @@ import { mkdtemp, readdir, readFile, rm, stat, writeFile } from 'node:fs/promise
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { extract as extractTar } from 'tar';
|
|
5
|
-
import
|
|
5
|
+
import * as v from 'valibot';
|
|
6
6
|
import { sha256File, sha256Hex, stableStringify } from "./json.js";
|
|
7
7
|
import { updateManifestForArchive } from "./manifest-update.js";
|
|
8
8
|
import { resolveLedgerPaths, saveManifest, writeAtomicJsonFile } from "./storage/filesystem.js";
|
|
9
9
|
const ARCHIVE_MANIFEST_SCHEMA_VERSION = 'ushman-ledger-archive-manifest/v1';
|
|
10
10
|
const PENDING_ARCHIVE_SCHEMA_VERSION = 'ushman-ledger-pending-archive/v1';
|
|
11
|
-
const ArchiveManifestFileHashSchema =
|
|
12
|
-
path:
|
|
13
|
-
sha256:
|
|
11
|
+
const ArchiveManifestFileHashSchema = v.object({
|
|
12
|
+
path: v.pipe(v.string(), v.minLength(1)),
|
|
13
|
+
sha256: v.pipe(v.string(), v.length(64)),
|
|
14
14
|
});
|
|
15
|
-
export const ArchiveManifestSchema =
|
|
16
|
-
fileHashes:
|
|
17
|
-
integrityHash:
|
|
18
|
-
schemaVersion:
|
|
15
|
+
export const ArchiveManifestSchema = v.object({
|
|
16
|
+
fileHashes: v.array(ArchiveManifestFileHashSchema),
|
|
17
|
+
integrityHash: v.pipe(v.string(), v.length(64)),
|
|
18
|
+
schemaVersion: v.literal(ARCHIVE_MANIFEST_SCHEMA_VERSION),
|
|
19
19
|
});
|
|
20
|
-
const PendingArchiveSchema =
|
|
20
|
+
const PendingArchiveSchema = v.object({
|
|
21
21
|
archiveManifest: ArchiveManifestSchema,
|
|
22
|
-
createdAt:
|
|
23
|
-
outPath:
|
|
24
|
-
schemaVersion:
|
|
22
|
+
createdAt: v.pipe(v.string(), v.isoTimestamp()),
|
|
23
|
+
outPath: v.pipe(v.string(), v.minLength(1)),
|
|
24
|
+
schemaVersion: v.literal(PENDING_ARCHIVE_SCHEMA_VERSION),
|
|
25
25
|
});
|
|
26
26
|
const formatPendingArchiveId = (createdAt, outPath) => `${createdAt.replaceAll(':', '-').replaceAll('.', '-')}-${sha256Hex(outPath).slice(0, 12)}`;
|
|
27
27
|
const buildPendingArchivePath = ({ createdAt, outPath, workspaceRoot, }) => path.join(resolveLedgerPaths(workspaceRoot).pendingArchivesDir, `${formatPendingArchiveId(createdAt, outPath)}.json`);
|
|
28
28
|
const parsePendingArchiveText = (filePath, text) => {
|
|
29
29
|
try {
|
|
30
|
-
return
|
|
30
|
+
return v.parse(PendingArchiveSchema, JSON.parse(text));
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
throw new Error(`Invalid pending archive at ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -35,7 +35,7 @@ const parsePendingArchiveText = (filePath, text) => {
|
|
|
35
35
|
};
|
|
36
36
|
const parseArchiveManifestText = (archivePath, text) => {
|
|
37
37
|
try {
|
|
38
|
-
return
|
|
38
|
+
return v.parse(ArchiveManifestSchema, JSON.parse(text));
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
throw new Error(`Invalid archive manifest inside ${archivePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -58,7 +58,7 @@ export const collectFileHashes = async (root, prefix = '') => {
|
|
|
58
58
|
};
|
|
59
59
|
export const createArchiveManifest = async (ledgerRoot) => {
|
|
60
60
|
const fileHashes = await collectFileHashes(ledgerRoot);
|
|
61
|
-
return
|
|
61
|
+
return v.parse(ArchiveManifestSchema, {
|
|
62
62
|
fileHashes,
|
|
63
63
|
integrityHash: sha256Hex(stableStringify(fileHashes)),
|
|
64
64
|
schemaVersion: ARCHIVE_MANIFEST_SCHEMA_VERSION,
|
|
@@ -125,7 +125,7 @@ export const verifyArchiveFile = async ({ archivePath, expectedArchiveManifest,
|
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
export const writeArchiveManifestFile = async ({ archiveManifest, stagingRoot, }) => {
|
|
128
|
-
await writeFile(path.join(stagingRoot, 'archive-manifest.json'), `${stableStringify(
|
|
128
|
+
await writeFile(path.join(stagingRoot, 'archive-manifest.json'), `${stableStringify(v.parse(ArchiveManifestSchema, archiveManifest), true)}\n`, 'utf8');
|
|
129
129
|
};
|
|
130
130
|
const readPendingArchive = async (filePath) => parsePendingArchiveText(filePath, await readFile(filePath, 'utf8'));
|
|
131
131
|
const readPendingArchives = async (workspaceRoot) => {
|
|
@@ -163,7 +163,7 @@ export const writePendingArchive = async ({ archiveManifest, createdAt, outPath,
|
|
|
163
163
|
outPath,
|
|
164
164
|
workspaceRoot,
|
|
165
165
|
});
|
|
166
|
-
await writeAtomicJsonFile(filePath,
|
|
166
|
+
await writeAtomicJsonFile(filePath, v.parse(PendingArchiveSchema, {
|
|
167
167
|
archiveManifest,
|
|
168
168
|
createdAt,
|
|
169
169
|
outPath,
|