ushman-ledger 1.1.0 → 1.2.1
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/AGENTS.md +11 -7
- package/CHANGELOG.md +6 -0
- package/README.md +79 -8
- package/dist/blobs.js +3 -3
- package/dist/builders.d.ts +44 -2
- package/dist/builders.d.ts.map +1 -1
- package/dist/builders.js +7 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +346 -62
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +104 -4
- package/dist/handle.d.ts +28 -6
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +105 -11
- package/dist/helpers.d.ts +7 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +38 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/list.d.ts +44 -2
- package/dist/list.d.ts.map +1 -1
- package/dist/list.js +7 -5
- package/dist/note.d.ts +27 -0
- package/dist/note.d.ts.map +1 -1
- package/dist/note.js +11 -0
- package/dist/patch-resolver.d.ts +39 -0
- package/dist/patch-resolver.d.ts.map +1 -0
- package/dist/patch-resolver.js +196 -0
- package/dist/read-index.d.ts +7 -7
- package/dist/read-index.d.ts.map +1 -1
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +15 -40
- package/dist/render/migration-log.d.ts +10 -0
- package/dist/render/migration-log.d.ts.map +1 -0
- package/dist/render/migration-log.js +79 -0
- package/dist/render/retro.d.ts.map +1 -1
- package/dist/render/retro.js +34 -21
- package/dist/render/workspace-narrative.d.ts +12 -0
- package/dist/render/workspace-narrative.d.ts.map +1 -0
- package/dist/render/workspace-narrative.js +137 -0
- package/dist/schema/entry-core.d.ts +110 -0
- package/dist/schema/entry-core.d.ts.map +1 -0
- package/dist/schema/entry-core.js +143 -0
- package/dist/schema/entry-migrations.d.ts +3 -0
- package/dist/schema/entry-migrations.d.ts.map +1 -0
- package/dist/schema/entry-migrations.js +48 -0
- package/dist/schema/entry-read.d.ts +694 -0
- package/dist/schema/entry-read.d.ts.map +1 -0
- package/dist/schema/entry-read.js +92 -0
- package/dist/schema/entry-write.d.ts +865 -0
- package/dist/schema/entry-write.d.ts.map +1 -0
- package/dist/schema/entry-write.js +105 -0
- package/dist/schema/entry.d.ts +6 -1369
- package/dist/schema/entry.d.ts.map +1 -1
- package/dist/schema/entry.js +9 -286
- package/dist/schema/note.d.ts +1 -1
- package/dist/schema/note.d.ts.map +1 -1
- package/dist/schema/note.js +12 -1
- package/dist/storage/filesystem.d.ts +9 -0
- package/dist/storage/filesystem.d.ts.map +1 -1
- package/dist/storage/filesystem.js +82 -5
- package/dist/storage/lock-reclaimer.d.ts +2 -0
- package/dist/storage/lock-reclaimer.d.ts.map +1 -0
- package/dist/storage/lock-reclaimer.js +45 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/dist/doctor.js
CHANGED
|
@@ -7,7 +7,9 @@ import { isReadIndexCurrent, readReadIndex } from "./read-index.js";
|
|
|
7
7
|
import { loadLedgerState } from "./recovery.js";
|
|
8
8
|
import { readManifest } from "./storage/filesystem.js";
|
|
9
9
|
const BLOB_HASH_CONCURRENCY = 16;
|
|
10
|
+
const CHECKPOINT_MAX_AGE_MS = 24 * 60 * 60 * 1_000;
|
|
10
11
|
const ENTRY_READ_BATCH_SIZE = 32;
|
|
12
|
+
const OPEN_ISSUE_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1_000;
|
|
11
13
|
const checkPrevChain = (entry, previousByPhase, issues) => {
|
|
12
14
|
const expectedPrev = previousByPhase.get(entry.phase) ?? null;
|
|
13
15
|
if (entry.prevEntryId !== expectedPrev) {
|
|
@@ -66,13 +68,51 @@ const buildReadFailure = (error) => ({
|
|
|
66
68
|
issues: [`Failed to read ledger state: ${error instanceof Error ? (error.message ?? error.name) : String(error)}.`],
|
|
67
69
|
ok: false,
|
|
68
70
|
});
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
const isChangeLogEntry = (entry) => entry.kind === 'change-log';
|
|
72
|
+
const isOpenIssueNote = (entry) => entry.kind === 'note' && entry.subkind === 'open-issue';
|
|
73
|
+
const trackResolutionLinks = (entry, resolvedLedgerIds) => {
|
|
74
|
+
if (entry.links.correctsLedgerId) {
|
|
75
|
+
resolvedLedgerIds.add(entry.links.correctsLedgerId);
|
|
76
|
+
}
|
|
77
|
+
if (entry.links.supersedesLedgerId) {
|
|
78
|
+
resolvedLedgerIds.add(entry.links.supersedesLedgerId);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const trackIdempotencyEntry = (entry, entriesByIdempotencyKey) => {
|
|
82
|
+
const idempotencyKey = entry.links.idempotencyKey;
|
|
83
|
+
if (!idempotencyKey) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const existingEntries = entriesByIdempotencyKey.get(idempotencyKey) ?? [];
|
|
87
|
+
existingEntries.push({ id: entry.id, ts: entry.ts });
|
|
88
|
+
entriesByIdempotencyKey.set(idempotencyKey, existingEntries);
|
|
89
|
+
};
|
|
90
|
+
const checkChangeLogWarnings = ({ checkpointEntries, entriesByIdempotencyKey, issues, nowMs, openIssueEntries, resolvedLedgerIds, }) => {
|
|
91
|
+
for (const checkpointEntry of checkpointEntries) {
|
|
92
|
+
const ageMs = nowMs - Date.parse(checkpointEntry.ts);
|
|
93
|
+
if (ageMs <= CHECKPOINT_MAX_AGE_MS) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const idempotencyKey = checkpointEntry.links.idempotencyKey;
|
|
97
|
+
const hasFollowUp = typeof idempotencyKey === 'string' &&
|
|
98
|
+
(entriesByIdempotencyKey.get(idempotencyKey) ?? []).some((candidate) => candidate.id !== checkpointEntry.id && candidate.ts >= checkpointEntry.ts);
|
|
99
|
+
if (!hasFollowUp) {
|
|
100
|
+
issues.push(`Pre-change checkpoint ${checkpointEntry.id} is older than 24h and has no follow-up entry with matching idempotencyKey.`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const openIssueEntry of openIssueEntries) {
|
|
104
|
+
const ageMs = nowMs - Date.parse(openIssueEntry.ts);
|
|
105
|
+
if (ageMs <= OPEN_ISSUE_MAX_AGE_MS || resolvedLedgerIds.has(openIssueEntry.id)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
issues.push(`Open issue note ${openIssueEntry.id} is older than 30 days and has no resolution link.`);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const inspectManifestLocation = ({ entry, issues, latestByPhase, manifest, }) => {
|
|
72
112
|
const manifestLocation = manifest.entryLocations[entry.id];
|
|
73
113
|
if (!manifestLocation) {
|
|
74
114
|
issues.push(`Manifest is missing entry location for ${entry.id}.`);
|
|
75
|
-
return;
|
|
115
|
+
return null;
|
|
76
116
|
}
|
|
77
117
|
if (manifestLocation.phase !== entry.phase) {
|
|
78
118
|
issues.push(`Manifest phase mismatch for ${entry.id}: expected ${entry.phase}, found ${manifestLocation.phase}.`);
|
|
@@ -81,6 +121,25 @@ const inspectDoctorEntry = ({ blobChecks, entry, issues, latestByPhase, manifest
|
|
|
81
121
|
if (!currentLatest || manifestLocation.sequence > currentLatest.sequence) {
|
|
82
122
|
latestByPhase.set(entry.phase, { entryId: entry.id, sequence: manifestLocation.sequence });
|
|
83
123
|
}
|
|
124
|
+
return manifestLocation;
|
|
125
|
+
};
|
|
126
|
+
const inspectNarrativeEntry = ({ checkpointEntries, entry, issues, openIssueEntries, }) => {
|
|
127
|
+
if (isChangeLogEntry(entry)) {
|
|
128
|
+
if (entry.subkind === 'pre-change-checkpoint') {
|
|
129
|
+
checkpointEntries.push(entry);
|
|
130
|
+
}
|
|
131
|
+
if (entry.smokeResult === 'fail' && !entry.rollbackPlan) {
|
|
132
|
+
issues.push(`Change-log entry ${entry.id} has smokeResult=fail but no rollbackPlan.`);
|
|
133
|
+
}
|
|
134
|
+
if (entry.subkind === 'rollback' && !entry.rollsBack) {
|
|
135
|
+
issues.push(`Change-log rollback entry ${entry.id} is missing rollsBack.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (isOpenIssueNote(entry)) {
|
|
139
|
+
openIssueEntries.push(entry);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const inspectPatchEntry = ({ blobChecks, entry, }) => {
|
|
84
143
|
if (entry.kind !== 'agent-patch' && entry.kind !== 'operator-patch') {
|
|
85
144
|
return;
|
|
86
145
|
}
|
|
@@ -88,13 +147,42 @@ const inspectDoctorEntry = ({ blobChecks, entry, issues, latestByPhase, manifest
|
|
|
88
147
|
blobChecks.push({ blobHash, entryId: entry.id });
|
|
89
148
|
}
|
|
90
149
|
};
|
|
150
|
+
const inspectDoctorEntry = ({ blobChecks, checkpointEntries, entry, entriesByIdempotencyKey, issues, latestByPhase, manifest, openIssueEntries, previousByPhase, resolvedLedgerIds, unseenManifestEntryIds, }) => {
|
|
151
|
+
unseenManifestEntryIds.delete(entry.id);
|
|
152
|
+
checkPrevChain(entry, previousByPhase, issues);
|
|
153
|
+
trackIdempotencyEntry(entry, entriesByIdempotencyKey);
|
|
154
|
+
trackResolutionLinks(entry, resolvedLedgerIds);
|
|
155
|
+
if (!inspectManifestLocation({
|
|
156
|
+
entry,
|
|
157
|
+
issues,
|
|
158
|
+
latestByPhase,
|
|
159
|
+
manifest,
|
|
160
|
+
})) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
inspectNarrativeEntry({
|
|
164
|
+
checkpointEntries,
|
|
165
|
+
entry,
|
|
166
|
+
issues,
|
|
167
|
+
openIssueEntries,
|
|
168
|
+
});
|
|
169
|
+
inspectPatchEntry({
|
|
170
|
+
blobChecks,
|
|
171
|
+
entry,
|
|
172
|
+
});
|
|
173
|
+
};
|
|
91
174
|
const collectDoctorState = async (workspaceRoot, manifest, readIndex) => {
|
|
92
175
|
const issues = [];
|
|
93
176
|
const previousByPhase = new Map();
|
|
94
177
|
const latestByPhase = new Map();
|
|
95
178
|
const unseenManifestEntryIds = new Set(Object.keys(manifest.entryLocations));
|
|
96
179
|
const blobChecks = [];
|
|
180
|
+
const checkpointEntries = [];
|
|
181
|
+
const entriesByIdempotencyKey = new Map();
|
|
182
|
+
const openIssueEntries = [];
|
|
183
|
+
const resolvedLedgerIds = new Set();
|
|
97
184
|
let entryCount = 0;
|
|
185
|
+
const nowMs = Date.now();
|
|
98
186
|
const orderedEntries = getOrderedEntryLocations(manifest, readIndex, {});
|
|
99
187
|
checkManifestSequenceOrder(orderedEntries, issues);
|
|
100
188
|
for (let index = 0; index < orderedEntries.length; index += ENTRY_READ_BATCH_SIZE) {
|
|
@@ -111,15 +199,27 @@ const collectDoctorState = async (workspaceRoot, manifest, readIndex) => {
|
|
|
111
199
|
entryCount += 1;
|
|
112
200
|
inspectDoctorEntry({
|
|
113
201
|
blobChecks,
|
|
202
|
+
checkpointEntries,
|
|
203
|
+
entriesByIdempotencyKey,
|
|
114
204
|
entry: resolvedEntry.entry,
|
|
115
205
|
issues,
|
|
116
206
|
latestByPhase,
|
|
117
207
|
manifest,
|
|
208
|
+
openIssueEntries,
|
|
118
209
|
previousByPhase,
|
|
210
|
+
resolvedLedgerIds,
|
|
119
211
|
unseenManifestEntryIds,
|
|
120
212
|
});
|
|
121
213
|
}
|
|
122
214
|
}
|
|
215
|
+
checkChangeLogWarnings({
|
|
216
|
+
checkpointEntries,
|
|
217
|
+
entriesByIdempotencyKey,
|
|
218
|
+
issues,
|
|
219
|
+
nowMs,
|
|
220
|
+
openIssueEntries,
|
|
221
|
+
resolvedLedgerIds,
|
|
222
|
+
});
|
|
123
223
|
return {
|
|
124
224
|
blobChecks,
|
|
125
225
|
entryCount,
|
package/dist/handle.d.ts
CHANGED
|
@@ -3,7 +3,31 @@ import { runLedgerDoctor } from './doctor.ts';
|
|
|
3
3
|
import { type LedgerFilter } from './list.ts';
|
|
4
4
|
import { appendNote, type NoteBody } from './note.ts';
|
|
5
5
|
import type { LedgerEntry, LedgerPhase } from './schema/entry.ts';
|
|
6
|
-
export type RenderTarget = 'dependency-graph' | 'jsonl' | 'retro' | 'timeline-html';
|
|
6
|
+
export type RenderTarget = 'dependency-graph' | 'jsonl' | 'migration-log-md' | 'retro' | 'timeline-html' | 'workspace-narrative-md';
|
|
7
|
+
/**
|
|
8
|
+
* Chunk writer used by `renderTo()` for bounded render emission.
|
|
9
|
+
*
|
|
10
|
+
* Writers may complete synchronously or asynchronously. Throwing rejects the render and causes any in-progress
|
|
11
|
+
* atomic output file to be aborted.
|
|
12
|
+
*/
|
|
13
|
+
export type RenderWriter = (chunk: string) => Promise<void> | void;
|
|
14
|
+
/** Options for `render()`, which returns the rendered text and optionally mirrors it to disk. */
|
|
15
|
+
export type LedgerRenderOptions = {
|
|
16
|
+
readonly limit?: number;
|
|
17
|
+
readonly out?: string;
|
|
18
|
+
readonly phase?: LedgerPhase;
|
|
19
|
+
readonly since?: string;
|
|
20
|
+
readonly to: RenderTarget;
|
|
21
|
+
};
|
|
22
|
+
/** Options for `renderTo()`, which writes to a callback and/or canonical render file without buffering the full output. */
|
|
23
|
+
export type LedgerRenderToOptions = {
|
|
24
|
+
readonly limit?: number;
|
|
25
|
+
readonly out?: string;
|
|
26
|
+
readonly phase?: LedgerPhase;
|
|
27
|
+
readonly since?: string;
|
|
28
|
+
readonly to: RenderTarget;
|
|
29
|
+
readonly write?: RenderWriter;
|
|
30
|
+
};
|
|
7
31
|
export type LedgerHandle = {
|
|
8
32
|
readonly archive: (outPath: string) => Promise<{
|
|
9
33
|
integrityHash: string;
|
|
@@ -17,12 +41,10 @@ export type LedgerHandle = {
|
|
|
17
41
|
readonly record: (entry: unknown) => Promise<{
|
|
18
42
|
id: string;
|
|
19
43
|
}>;
|
|
20
|
-
readonly render: (options:
|
|
21
|
-
|
|
22
|
-
phase?: LedgerPhase;
|
|
23
|
-
to: RenderTarget;
|
|
24
|
-
}) => Promise<string>;
|
|
44
|
+
readonly render: (options: LedgerRenderOptions) => Promise<string>;
|
|
45
|
+
readonly renderTo: (options: LedgerRenderToOptions) => Promise<void>;
|
|
25
46
|
readonly show: (entryId: string) => Promise<LedgerEntry | null>;
|
|
26
47
|
};
|
|
48
|
+
/** Open a workspace ledger handle after reconciling any pending crash-recovery state. */
|
|
27
49
|
export declare const openLedger: (workspaceRoot: string) => Promise<LedgerHandle>;
|
|
28
50
|
//# sourceMappingURL=handle.d.ts.map
|
package/dist/handle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../src/handle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../src/handle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAA8B,KAAK,YAAY,EAAe,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAStD,OAAO,KAAK,EAAE,WAAW,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG9E,MAAM,MAAM,YAAY,GAClB,kBAAkB,GAClB,OAAO,GACP,kBAAkB,GAClB,OAAO,GACP,eAAe,GACf,wBAAwB,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEnE,iGAAiG;AACjG,MAAM,MAAM,mBAAmB,GAAG;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,2HAA2H;AAC3H,MAAM,MAAM,qBAAqB,GAAG;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CACjC,CAAC;AA4GF,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IACrF,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5E,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,aAAa,CAAC,WAAW,CAAC,CAAC;IACrE,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtG,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACnE,CAAC;AAEF,yFAAyF;AACzF,eAAO,MAAM,UAAU,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,YAAY,CAyF5E,CAAC"}
|
package/dist/handle.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { archiveLedger } from "./archive.js";
|
|
2
3
|
import { computeCoverage } from "./coverage.js";
|
|
3
4
|
import { runLedgerDoctor } from "./doctor.js";
|
|
@@ -8,23 +9,62 @@ import { appendRecord, readEntryById } from "./record.js";
|
|
|
8
9
|
import { loadLedgerState, prepareLedgerState } from "./recovery.js";
|
|
9
10
|
import { renderDependencyGraph } from "./render/dependency-graph.js";
|
|
10
11
|
import { renderJsonl } from "./render/jsonl.js";
|
|
12
|
+
import { renderMigrationLogMarkdown } from "./render/migration-log.js";
|
|
11
13
|
import { renderRetroMarkdown } from "./render/retro.js";
|
|
12
14
|
import { renderTimelineHtml } from "./render/timeline-html.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
import { renderWorkspaceNarrativeMarkdown } from "./render/workspace-narrative.js";
|
|
16
|
+
import { createAtomicTextFileWriter, resolveLedgerPaths, writeAtomicTextFile } from "./storage/filesystem.js";
|
|
17
|
+
const createEntryIteratorFactory = ({ filter, state, workspaceRoot, }) => {
|
|
18
|
+
return (entryOptions = {}) => iterateEntriesFromManifest(workspaceRoot, state.manifest, state.readIndex, {
|
|
19
|
+
kind: entryOptions.kind,
|
|
20
|
+
limit: filter.limit,
|
|
21
|
+
phase: filter.phase,
|
|
22
|
+
since: filter.since,
|
|
23
|
+
}, entryOptions.direction);
|
|
24
|
+
};
|
|
25
|
+
const collectRenderedText = async (emit) => {
|
|
26
|
+
const chunks = [];
|
|
27
|
+
await emit((chunk) => {
|
|
28
|
+
chunks.push(chunk);
|
|
29
|
+
});
|
|
30
|
+
return chunks.join('');
|
|
31
|
+
};
|
|
32
|
+
const emitRenderedTarget = async ({ createEntries, manifest, target, write, workspaceName, }) => {
|
|
16
33
|
switch (target) {
|
|
17
34
|
case 'dependency-graph':
|
|
18
|
-
|
|
35
|
+
await write(await renderDependencyGraph(createEntries()));
|
|
36
|
+
return;
|
|
19
37
|
case 'jsonl':
|
|
20
|
-
|
|
38
|
+
await write(await renderJsonl(createEntries()));
|
|
39
|
+
return;
|
|
40
|
+
case 'migration-log-md':
|
|
41
|
+
await renderMigrationLogMarkdown({
|
|
42
|
+
entries: createEntries({
|
|
43
|
+
direction: 'desc',
|
|
44
|
+
kind: 'change-log',
|
|
45
|
+
}),
|
|
46
|
+
write,
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
21
49
|
case 'timeline-html':
|
|
22
|
-
|
|
50
|
+
await write(await renderTimelineHtml(createEntries()));
|
|
51
|
+
return;
|
|
23
52
|
case 'retro':
|
|
24
|
-
|
|
25
|
-
entries:
|
|
53
|
+
await write(await renderRetroMarkdown({
|
|
54
|
+
entries: createEntries(),
|
|
26
55
|
manifest,
|
|
56
|
+
}));
|
|
57
|
+
return;
|
|
58
|
+
case 'workspace-narrative-md':
|
|
59
|
+
await renderWorkspaceNarrativeMarkdown({
|
|
60
|
+
entries: createEntries({
|
|
61
|
+
direction: 'desc',
|
|
62
|
+
kind: 'note',
|
|
63
|
+
}),
|
|
64
|
+
workspaceName,
|
|
65
|
+
write,
|
|
27
66
|
});
|
|
67
|
+
return;
|
|
28
68
|
}
|
|
29
69
|
};
|
|
30
70
|
const resolveRenderOutputPath = (workspaceRoot, target) => {
|
|
@@ -32,12 +72,17 @@ const resolveRenderOutputPath = (workspaceRoot, target) => {
|
|
|
32
72
|
switch (target) {
|
|
33
73
|
case 'retro':
|
|
34
74
|
return paths.renderFile;
|
|
75
|
+
case 'migration-log-md':
|
|
76
|
+
return paths.renderMigrationLogFile;
|
|
35
77
|
case 'timeline-html':
|
|
36
78
|
return paths.renderTimelineFile;
|
|
79
|
+
case 'workspace-narrative-md':
|
|
80
|
+
return paths.renderWorkspaceNarrativeFile;
|
|
37
81
|
default:
|
|
38
82
|
return null;
|
|
39
83
|
}
|
|
40
84
|
};
|
|
85
|
+
/** Open a workspace ledger handle after reconciling any pending crash-recovery state. */
|
|
41
86
|
export const openLedger = async (workspaceRoot) => {
|
|
42
87
|
await readLabManifestMin(workspaceRoot);
|
|
43
88
|
await prepareLedgerState(workspaceRoot);
|
|
@@ -55,17 +100,66 @@ export const openLedger = async (workspaceRoot) => {
|
|
|
55
100
|
return { id: result.id };
|
|
56
101
|
},
|
|
57
102
|
render: async (options) => {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
103
|
+
const state = await loadLedgerState(workspaceRoot);
|
|
104
|
+
const createEntries = createEntryIteratorFactory({
|
|
105
|
+
filter: options,
|
|
106
|
+
state,
|
|
61
107
|
workspaceRoot,
|
|
62
108
|
});
|
|
109
|
+
const content = await collectRenderedText((write) => emitRenderedTarget({
|
|
110
|
+
createEntries,
|
|
111
|
+
manifest: state.manifest,
|
|
112
|
+
target: options.to,
|
|
113
|
+
workspaceName: path.basename(workspaceRoot),
|
|
114
|
+
write,
|
|
115
|
+
}));
|
|
63
116
|
const outputPath = options.out ?? resolveRenderOutputPath(workspaceRoot, options.to);
|
|
64
117
|
if (outputPath) {
|
|
65
118
|
await writeAtomicTextFile(outputPath, `${content}${content.endsWith('\n') ? '' : '\n'}`);
|
|
66
119
|
}
|
|
67
120
|
return content;
|
|
68
121
|
},
|
|
122
|
+
renderTo: async (options) => {
|
|
123
|
+
const state = await loadLedgerState(workspaceRoot);
|
|
124
|
+
const createEntries = createEntryIteratorFactory({
|
|
125
|
+
filter: options,
|
|
126
|
+
state,
|
|
127
|
+
workspaceRoot,
|
|
128
|
+
});
|
|
129
|
+
const outputPath = options.out ?? resolveRenderOutputPath(workspaceRoot, options.to);
|
|
130
|
+
const atomicWriter = outputPath ? await createAtomicTextFileWriter(outputPath) : null;
|
|
131
|
+
const writer = options.write;
|
|
132
|
+
let hasWrittenContent = false;
|
|
133
|
+
let endsWithNewline = false;
|
|
134
|
+
if (!atomicWriter && !writer) {
|
|
135
|
+
throw new Error(`Render target ${options.to} requires either a writer callback or an output path.`);
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
await emitRenderedTarget({
|
|
139
|
+
createEntries,
|
|
140
|
+
manifest: state.manifest,
|
|
141
|
+
target: options.to,
|
|
142
|
+
workspaceName: path.basename(workspaceRoot),
|
|
143
|
+
write: async (chunk) => {
|
|
144
|
+
if (chunk.length > 0) {
|
|
145
|
+
hasWrittenContent = true;
|
|
146
|
+
endsWithNewline = chunk.endsWith('\n');
|
|
147
|
+
}
|
|
148
|
+
await writer?.(chunk);
|
|
149
|
+
await atomicWriter?.write(chunk);
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
if (!hasWrittenContent || !endsWithNewline) {
|
|
153
|
+
await writer?.('\n');
|
|
154
|
+
await atomicWriter?.write('\n');
|
|
155
|
+
}
|
|
156
|
+
await atomicWriter?.close();
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
await atomicWriter?.abort();
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
},
|
|
69
163
|
show: async (entryId) => {
|
|
70
164
|
const { manifest } = await loadLedgerState(workspaceRoot);
|
|
71
165
|
if (!manifest.entryLocations[entryId]) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const createWorkspaceFixture: () => Promise<{
|
|
2
|
+
cleanup: () => Promise<void>;
|
|
3
|
+
workspaceRoot: string;
|
|
4
|
+
}>;
|
|
5
|
+
export declare const ageFile: (filePath: string, ageMs?: number) => Promise<void>;
|
|
6
|
+
export declare const waitForFile: (filePath: string, timeoutMs?: number) => Promise<void>;
|
|
7
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB;;;EAuBlC,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,UAAU,MAAM,EAAE,cAAc,kBAG7D,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,EAAE,kBAAiB,kBAcpE,CAAC"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, rm, stat, utimes, writeFile } from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export const createWorkspaceFixture = async () => {
|
|
5
|
+
const workspaceRoot = await mkdtemp(path.join(os.tmpdir(), 'ushman-ledger-'));
|
|
6
|
+
await mkdir(path.join(workspaceRoot, '.lab'), { recursive: true });
|
|
7
|
+
await mkdir(path.join(workspaceRoot, 'src'), { recursive: true });
|
|
8
|
+
await writeFile(path.join(workspaceRoot, '.lab', 'lab.json'), `${JSON.stringify({
|
|
9
|
+
schemaVersion: 'ushman-lab/v4.0',
|
|
10
|
+
workspaceId: '3d71d4fb-dca0-4d63-9ad6-69d59a2395f4',
|
|
11
|
+
}, null, 2)}\n`, 'utf8');
|
|
12
|
+
return {
|
|
13
|
+
cleanup: async () => {
|
|
14
|
+
await rm(workspaceRoot, { force: true, recursive: true });
|
|
15
|
+
},
|
|
16
|
+
workspaceRoot,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export const ageFile = async (filePath, ageMs = 61_000) => {
|
|
20
|
+
const staleTime = new Date(Date.now() - ageMs);
|
|
21
|
+
await utimes(filePath, staleTime, staleTime);
|
|
22
|
+
};
|
|
23
|
+
export const waitForFile = async (filePath, timeoutMs = 1_000) => {
|
|
24
|
+
const deadline = Date.now() + timeoutMs;
|
|
25
|
+
while (Date.now() <= deadline) {
|
|
26
|
+
try {
|
|
27
|
+
await stat(filePath);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error.code !== 'ENOENT') {
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`Timed out waiting for file: ${filePath}`);
|
|
38
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export { buildCorrectionRecord, buildOperatorDecisionRecord, buildStripDecisionRevertedRecord, buildValidatorResultRecord, } from './builders.ts';
|
|
1
|
+
export { type BuildRecordInput, buildChangeLogRecord, buildCorrectionRecord, buildOperatorDecisionRecord, buildStripDecisionRevertedRecord, buildValidatorResultRecord, } from './builders.ts';
|
|
2
2
|
export { runLedgerCli } from './cli.ts';
|
|
3
3
|
export { type CoverageReport, computeCoverage } from './coverage.ts';
|
|
4
|
-
export { type LedgerHandle, type
|
|
4
|
+
export { type LedgerHandle, type LedgerRenderOptions, type LedgerRenderToOptions, openLedger, type RenderTarget, type RenderWriter, } from './handle.ts';
|
|
5
5
|
export type { LedgerFilter } from './list.ts';
|
|
6
|
-
export {
|
|
6
|
+
export { appendCleanupWaveNote, appendDecompositionWaveNote, appendNote, appendOpenIssueNote, appendSemanticCleanupSummaryNote, appendVerifiedFlowNote, type NoteBody, } from './note.ts';
|
|
7
|
+
export { deriveFilesChangedFromPatch } from './patch-resolver.ts';
|
|
8
|
+
export { type AgentPatchDiff, AgentPatchDiffSchema, AgentPatchEntrySchema, AgentPatchRecordSchema, type ChangeLogEntry, ChangeLogEntrySchema, type ChangeLogFileChange, ChangeLogFileChangeSchema, type ChangeLogParityStatus, ChangeLogParityStatusSchema, type ChangeLogRecord, ChangeLogRecordSchema, type ChangeLogSmokeResult, ChangeLogSmokeResultSchema, type ChangeLogSubkind, ChangeLogSubkindSchema, CorrectionEntrySchema, CorrectionRecordSchema, EmitterSchema, type LedgerEntry, LedgerEntrySchema, type LedgerKind, type LedgerLinks, LedgerLinksSchema, type LedgerPhase, LedgerPhaseSchema, type LedgerRecord, LedgerRecordSchema, type NoteEntry, NoteEntrySchema, type OperatorDecisionAction, OperatorDecisionActionSchema, OperatorDecisionEntrySchema, type OperatorDecisionPayload, OperatorDecisionPayloadSchema, OperatorDecisionRecordSchema, OperatorPatchEntrySchema, OperatorPatchRecordSchema, parseLedgerEntry, parseLedgerRecord, RuntimeEventEntrySchema, StripDecisionRevertedEntrySchema, type StripDecisionRevertedPayload, StripDecisionRevertedPayloadSchema, StripDecisionRevertedRecordSchema, ToolInvocationEntrySchema, ToolInvocationRecordSchema, ValidatorResultEntrySchema, ValidatorResultRecordSchema, } from './schema/entry.ts';
|
|
7
9
|
export { type NoteSubkind, NoteSubkindSchema } from './schema/note.ts';
|
|
8
10
|
export { resolveLedgerPaths } from './storage/filesystem.ts';
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,qBAAqB,EACrB,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,GAC7B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,GAC7B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,UAAU,EACV,KAAK,YAAY,EACjB,KAAK,YAAY,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACH,qBAAqB,EACrB,2BAA2B,EAC3B,UAAU,EACV,mBAAmB,EACnB,gCAAgC,EAChC,sBAAsB,EACtB,KAAK,QAAQ,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACH,KAAK,cAAc,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,cAAc,EACnB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,2BAA2B,EAC3B,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,0BAA0B,EAC1B,KAAK,gBAAgB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,YAAY,EACjB,kBAAkB,EAClB,KAAK,SAAS,EACd,eAAe,EACf,KAAK,sBAAsB,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,KAAK,uBAAuB,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,gCAAgC,EAChC,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,iCAAiC,EACjC,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export { buildCorrectionRecord, buildOperatorDecisionRecord, buildStripDecisionRevertedRecord, buildValidatorResultRecord, } from "./builders.js";
|
|
1
|
+
export { buildChangeLogRecord, buildCorrectionRecord, buildOperatorDecisionRecord, buildStripDecisionRevertedRecord, buildValidatorResultRecord, } from "./builders.js";
|
|
2
2
|
export { runLedgerCli } from "./cli.js";
|
|
3
3
|
export { computeCoverage } from "./coverage.js";
|
|
4
|
-
export { openLedger } from "./handle.js";
|
|
5
|
-
export {
|
|
4
|
+
export { openLedger, } from "./handle.js";
|
|
5
|
+
export { appendCleanupWaveNote, appendDecompositionWaveNote, appendNote, appendOpenIssueNote, appendSemanticCleanupSummaryNote, appendVerifiedFlowNote, } from "./note.js";
|
|
6
|
+
export { deriveFilesChangedFromPatch } from "./patch-resolver.js";
|
|
7
|
+
export { AgentPatchDiffSchema, AgentPatchEntrySchema, AgentPatchRecordSchema, ChangeLogEntrySchema, ChangeLogFileChangeSchema, ChangeLogParityStatusSchema, ChangeLogRecordSchema, ChangeLogSmokeResultSchema, ChangeLogSubkindSchema, CorrectionEntrySchema, CorrectionRecordSchema, EmitterSchema, LedgerEntrySchema, LedgerLinksSchema, LedgerPhaseSchema, LedgerRecordSchema, NoteEntrySchema, OperatorDecisionActionSchema, OperatorDecisionEntrySchema, OperatorDecisionPayloadSchema, OperatorDecisionRecordSchema, OperatorPatchEntrySchema, OperatorPatchRecordSchema, parseLedgerEntry, parseLedgerRecord, RuntimeEventEntrySchema, StripDecisionRevertedEntrySchema, StripDecisionRevertedPayloadSchema, StripDecisionRevertedRecordSchema, ToolInvocationEntrySchema, ToolInvocationRecordSchema, ValidatorResultEntrySchema, ValidatorResultRecordSchema, } from "./schema/entry.js";
|
|
6
8
|
export { NoteSubkindSchema } from "./schema/note.js";
|
|
7
9
|
export { resolveLedgerPaths } from "./storage/filesystem.js";
|
package/dist/list.d.ts
CHANGED
|
@@ -259,7 +259,7 @@ export declare const readManifestEntryBatch: ({ allowMissing, entryLocations, wo
|
|
|
259
259
|
} | {
|
|
260
260
|
body: string;
|
|
261
261
|
kind: "note";
|
|
262
|
-
subkind: "regression" | "automation" | "retro" | "operator" | "tooling-gap";
|
|
262
|
+
subkind: "regression" | "automation" | "retro" | "operator" | "tooling-gap" | "cleanup-wave" | "verified-flow" | "open-issue" | "decomposition-wave" | "semantic-cleanup-summary";
|
|
263
263
|
details?: {
|
|
264
264
|
[x: string]: unknown;
|
|
265
265
|
} | undefined;
|
|
@@ -321,6 +321,48 @@ export declare const readManifestEntryBatch: ({ allowMissing, entryLocations, wo
|
|
|
321
321
|
schemaVersion: "ushman-ledger-entry/v1";
|
|
322
322
|
summary: string;
|
|
323
323
|
ts: string;
|
|
324
|
+
} | {
|
|
325
|
+
commandsRun?: string[] | undefined;
|
|
326
|
+
filesChanged: {
|
|
327
|
+
added?: number | undefined;
|
|
328
|
+
path: string;
|
|
329
|
+
removed?: number | undefined;
|
|
330
|
+
}[];
|
|
331
|
+
hypothesis?: string | undefined;
|
|
332
|
+
kind: "change-log";
|
|
333
|
+
parityStatus?: "not-run" | "green" | "yellow" | "red" | undefined;
|
|
334
|
+
rollbackPlan?: string | undefined;
|
|
335
|
+
rollsBack?: string | undefined;
|
|
336
|
+
smokeNotes?: string | undefined;
|
|
337
|
+
smokeResult?: "pass" | "fail" | "partial" | "not-run" | undefined;
|
|
338
|
+
subkind: "vendor-extract" | "pre-change-checkpoint" | "semantic-cleanup" | "decomposition" | "rollback" | "hotfix" | "smoke";
|
|
339
|
+
details?: {
|
|
340
|
+
[x: string]: unknown;
|
|
341
|
+
} | undefined;
|
|
342
|
+
emitter: {
|
|
343
|
+
tool: string;
|
|
344
|
+
user?: string | undefined;
|
|
345
|
+
version: string;
|
|
346
|
+
};
|
|
347
|
+
id: string;
|
|
348
|
+
links: {
|
|
349
|
+
affectedFiles?: string[] | undefined;
|
|
350
|
+
blobs?: string[] | undefined;
|
|
351
|
+
briefId?: string | undefined;
|
|
352
|
+
correctsLedgerId?: string | undefined;
|
|
353
|
+
gitRef?: string | undefined;
|
|
354
|
+
idempotencyKey?: string | undefined;
|
|
355
|
+
stripDecisionId?: string | undefined;
|
|
356
|
+
supersedesLedgerId?: string | undefined;
|
|
357
|
+
validatorVerdictId?: string | undefined;
|
|
358
|
+
} & {
|
|
359
|
+
[key: string]: unknown;
|
|
360
|
+
};
|
|
361
|
+
phase: "capture" | "intake" | "seed" | "vendor-extract" | "cleanup" | "parity" | "characterize" | "equiv" | "analyze" | "recover" | "ship" | "migration";
|
|
362
|
+
prevEntryId: string | null;
|
|
363
|
+
schemaVersion: "ushman-ledger-entry/v1";
|
|
364
|
+
summary: string;
|
|
365
|
+
ts: string;
|
|
324
366
|
};
|
|
325
367
|
entryId: string;
|
|
326
368
|
location: {
|
|
@@ -335,7 +377,7 @@ export declare const readManifestEntryBatch: ({ allowMissing, entryLocations, wo
|
|
|
335
377
|
sequence: number;
|
|
336
378
|
};
|
|
337
379
|
})[]>;
|
|
338
|
-
export declare const iterateEntriesFromManifest: (workspaceRoot: string, manifest: LedgerManifest, readIndex: LedgerReadIndex, filter?: LedgerFilter) => AsyncIterable<LedgerEntry>;
|
|
380
|
+
export declare const iterateEntriesFromManifest: (workspaceRoot: string, manifest: LedgerManifest, readIndex: LedgerReadIndex, filter?: LedgerFilter, direction?: "asc" | "desc") => AsyncIterable<LedgerEntry>;
|
|
339
381
|
export declare const listEntries: (workspaceRoot: string, filter?: LedgerFilter) => AsyncIterable<LedgerEntry>;
|
|
340
382
|
export declare const readAllEntries: (workspaceRoot: string, filter?: LedgerFilter) => Promise<LedgerEntry[]>;
|
|
341
383
|
//# sourceMappingURL=list.d.ts.map
|
package/dist/list.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAG7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAC1G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAmDF,eAAO,MAAM,wBAAwB,GACjC,UAAU,cAAc,EACxB,WAAW,eAAe,EAC1B,QAAQ,YAAY,EACpB,YAAW,KAAK,GAAG,MAAc,4BAgBpC,CAAC;AAgCF,eAAO,MAAM,sBAAsB,GAAU,kDAI1C;IACC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAG7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAC1G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAmDF,eAAO,MAAM,wBAAwB,GACjC,UAAU,cAAc,EACxB,WAAW,eAAe,EAC1B,QAAQ,YAAY,EACpB,YAAW,KAAK,GAAG,MAAc,4BAgBpC,CAAC;AAgCF,eAAO,MAAM,sBAAsB,GAAU,kDAI1C;IACC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAQI,CAAC;AAiDN,eAAO,MAAM,0BAA0B,GACnC,eAAe,MAAM,EACrB,UAAU,cAAc,EACxB,WAAW,eAAe,EAC1B,SAAQ,YAAiB,EACzB,YAAW,KAAK,GAAG,MAAc,KAClC,aAAa,CAAC,WAAW,CAwB3B,CAAC;AAEF,eAAO,MAAM,WAAW,GACpB,eAAe,MAAM,EACrB,SAAQ,YAAiB,KAC1B,aAAa,CAAC,WAAW,CAG3B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,eAAe,MAAM,EAAE,SAAQ,YAAiB,KAAG,OAAO,CAAC,WAAW,EAAE,CAM5G,CAAC"}
|
package/dist/list.js
CHANGED
|
@@ -77,7 +77,7 @@ export const readManifestEntryBatch = async ({ allowMissing = false, entryLocati
|
|
|
77
77
|
location,
|
|
78
78
|
workspaceRoot,
|
|
79
79
|
}));
|
|
80
|
-
const collectLimitedEntries = async ({ filter, manifest, readIndex, workspaceRoot, }) => {
|
|
80
|
+
const collectLimitedEntries = async ({ direction, filter, manifest, readIndex, workspaceRoot, }) => {
|
|
81
81
|
const collectedEntries = [];
|
|
82
82
|
const orderedEntries = getOrderedEntryLocations(manifest, readIndex, filter, 'desc');
|
|
83
83
|
const limit = filter.limit ?? 0;
|
|
@@ -99,17 +99,19 @@ const collectLimitedEntries = async ({ filter, manifest, readIndex, workspaceRoo
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
if (direction === 'asc') {
|
|
103
|
+
collectedEntries.reverse();
|
|
104
|
+
}
|
|
103
105
|
return collectedEntries;
|
|
104
106
|
};
|
|
105
|
-
export const iterateEntriesFromManifest = async function* (workspaceRoot, manifest, readIndex, filter = {}) {
|
|
107
|
+
export const iterateEntriesFromManifest = async function* (workspaceRoot, manifest, readIndex, filter = {}, direction = 'asc') {
|
|
106
108
|
if (filter.limit) {
|
|
107
|
-
for (const entry of await collectLimitedEntries({ filter, manifest, readIndex, workspaceRoot })) {
|
|
109
|
+
for (const entry of await collectLimitedEntries({ direction, filter, manifest, readIndex, workspaceRoot })) {
|
|
108
110
|
yield entry;
|
|
109
111
|
}
|
|
110
112
|
return;
|
|
111
113
|
}
|
|
112
|
-
const orderedEntries = getOrderedEntryLocations(manifest, readIndex, filter);
|
|
114
|
+
const orderedEntries = getOrderedEntryLocations(manifest, readIndex, filter, direction);
|
|
113
115
|
for (let index = 0; index < orderedEntries.length; index += ENTRY_READ_BATCH_SIZE) {
|
|
114
116
|
const batch = orderedEntries.slice(index, index + ENTRY_READ_BATCH_SIZE);
|
|
115
117
|
const resolvedEntries = await readManifestEntryBatch({
|
package/dist/note.d.ts
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
import { appendRecord } from './record.ts';
|
|
2
2
|
import type { LedgerPhase } from './schema/entry.ts';
|
|
3
3
|
import type { NoteSubkind } from './schema/note.ts';
|
|
4
|
+
/** Input shared by the narrative and note helper wrappers. */
|
|
4
5
|
export type NoteBody = {
|
|
5
6
|
readonly body: string;
|
|
6
7
|
readonly phase: LedgerPhase;
|
|
7
8
|
readonly summary: string;
|
|
8
9
|
};
|
|
10
|
+
/** Append a typed note entry using the library emitter metadata. */
|
|
9
11
|
export declare const appendNote: (workspaceRoot: string, subkind: NoteSubkind, noteBody: NoteBody) => Promise<{
|
|
10
12
|
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
11
13
|
id: string;
|
|
12
14
|
}>;
|
|
15
|
+
/** Append a `cleanup-wave` narrative note. */
|
|
16
|
+
export declare const appendCleanupWaveNote: (workspaceRoot: string, noteBody: NoteBody) => Promise<{
|
|
17
|
+
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
18
|
+
id: string;
|
|
19
|
+
}>;
|
|
20
|
+
/** Append a `verified-flow` narrative note. */
|
|
21
|
+
export declare const appendVerifiedFlowNote: (workspaceRoot: string, noteBody: NoteBody) => Promise<{
|
|
22
|
+
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
23
|
+
id: string;
|
|
24
|
+
}>;
|
|
25
|
+
/** Append an `open-issue` narrative note. */
|
|
26
|
+
export declare const appendOpenIssueNote: (workspaceRoot: string, noteBody: NoteBody) => Promise<{
|
|
27
|
+
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
28
|
+
id: string;
|
|
29
|
+
}>;
|
|
30
|
+
/** Append a `decomposition-wave` narrative note. */
|
|
31
|
+
export declare const appendDecompositionWaveNote: (workspaceRoot: string, noteBody: NoteBody) => Promise<{
|
|
32
|
+
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
/** Append the current `semantic-cleanup-summary` note for workspace narrative rendering. */
|
|
36
|
+
export declare const appendSemanticCleanupSummaryNote: (workspaceRoot: string, noteBody: NoteBody) => Promise<{
|
|
37
|
+
entry: Awaited<ReturnType<typeof appendRecord>>["entry"];
|
|
38
|
+
id: string;
|
|
39
|
+
}>;
|
|
13
40
|
//# sourceMappingURL=note.d.ts.map
|
package/dist/note.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../src/note.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,MAAM,QAAQ,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,UAAU,GACnB,eAAe,MAAM,EACrB,SAAS,WAAW,EACpB,UAAU,QAAQ,KACnB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAYlF,CAAC"}
|
|
1
|
+
{"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../src/note.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,8DAA8D;AAC9D,MAAM,MAAM,QAAQ,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,UAAU,GACnB,eAAe,MAAM,EACrB,SAAS,WAAW,EACpB,UAAU,QAAQ,KACnB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAYlF,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,EAAE,UAAU,QAAQ;WAf3D,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAAM,MAAM;EAgB1B,CAAC;AAExD,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,GAAI,eAAe,MAAM,EAAE,UAAU,QAAQ;WAnB5D,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAAM,MAAM;EAoBzB,CAAC;AAEzD,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,GAAI,eAAe,MAAM,EAAE,UAAU,QAAQ;WAvBzD,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAAM,MAAM;EAwB5B,CAAC;AAEtD,oDAAoD;AACpD,eAAO,MAAM,2BAA2B,GAAI,eAAe,MAAM,EAAE,UAAU,QAAQ;WA3BjE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAAM,MAAM;EA4BpB,CAAC;AAE9D,4FAA4F;AAC5F,eAAO,MAAM,gCAAgC,GAAI,eAAe,MAAM,EAAE,UAAU,QAAQ;WA/BtE,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAAM,MAAM;EAgCd,CAAC"}
|