@agentproto/corpus 0.1.0-alpha.1 → 0.1.0-alpha.2
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/dist/chunk-3P23OX5X.mjs +93 -0
- package/dist/chunk-3P23OX5X.mjs.map +1 -0
- package/dist/fs.port-BHzctsoT.d.ts +60 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +3 -82
- package/dist/index.mjs.map +1 -1
- package/dist/ports/index.d.ts +3 -60
- package/dist/report/index.d.ts +526 -0
- package/dist/report/index.mjs +633 -0
- package/dist/report/index.mjs.map +1 -0
- package/package.json +10 -5
package/dist/ports/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { b as FsLockHandle, F as FsPort, a as FsStat } from '../fs.port-BHzctsoT.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* ClockPort — abstracted time source.
|
|
3
5
|
*
|
|
@@ -14,65 +16,6 @@ interface ClockPort {
|
|
|
14
16
|
/** Real-time implementation. The local CLI host wires this in. */
|
|
15
17
|
declare const systemClock: ClockPort;
|
|
16
18
|
|
|
17
|
-
/**
|
|
18
|
-
* FsPort — filesystem boundary the corpus kit consumes.
|
|
19
|
-
*
|
|
20
|
-
* Structural interface, NOT a nominal one — any object exposing this
|
|
21
|
-
* shape satisfies it. Matches the existing Guilde `WorkspaceFsLike`
|
|
22
|
-
* convention (projects/guilde/packages/core/src/services/role-source/
|
|
23
|
-
* workspace.ts:38-47) so cloud and local topologies share the same
|
|
24
|
-
* minimal contract.
|
|
25
|
-
*
|
|
26
|
-
* Paths are relative to the workspace root (no leading slash). The
|
|
27
|
-
* concrete implementation (MastraFilesystem in cloud, local-fs in CLI,
|
|
28
|
-
* mcp-filesystem for hybrid topologies) does the resolution.
|
|
29
|
-
*/
|
|
30
|
-
interface FsStat {
|
|
31
|
-
readonly kind: "file" | "directory";
|
|
32
|
-
readonly bytes?: number;
|
|
33
|
-
readonly modifiedAt?: Date;
|
|
34
|
-
}
|
|
35
|
-
interface FsPort {
|
|
36
|
-
/** True if a file or directory exists at `path`. */
|
|
37
|
-
exists(path: string): Promise<boolean>;
|
|
38
|
-
/** Read a file as UTF-8 text. Throws on missing path. */
|
|
39
|
-
readFile(path: string): Promise<string>;
|
|
40
|
-
/**
|
|
41
|
-
* Write a file atomically — caller assumes content is persisted on
|
|
42
|
-
* resolve. Implementations are expected to write to a temp file +
|
|
43
|
-
* rename so partial writes never become visible.
|
|
44
|
-
*/
|
|
45
|
-
writeFile(path: string, content: string): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Append to a file. MUST be atomic against concurrent appends to the
|
|
48
|
-
* same path — used by the event emitter for _log.md. If the file
|
|
49
|
-
* does not exist, create it.
|
|
50
|
-
*/
|
|
51
|
-
appendFile(path: string, content: string): Promise<void>;
|
|
52
|
-
/**
|
|
53
|
-
* List immediate children of a directory. Returns names only (NOT
|
|
54
|
-
* full paths). Throws if `path` is not a directory.
|
|
55
|
-
*/
|
|
56
|
-
readdir(path: string): Promise<readonly string[]>;
|
|
57
|
-
/**
|
|
58
|
-
* Recursive directory listing — returns workspace-relative paths of
|
|
59
|
-
* every file under `path`. Skips directories starting with `.`.
|
|
60
|
-
*/
|
|
61
|
-
walk(path: string): Promise<readonly string[]>;
|
|
62
|
-
/** File metadata. Returns null if the path doesn't exist. */
|
|
63
|
-
stat(path: string): Promise<FsStat | null>;
|
|
64
|
-
/**
|
|
65
|
-
* Acquire a cross-process advisory lock on `path`. Used by the
|
|
66
|
-
* writer for atomic multi-file transactions (entry write + _index
|
|
67
|
-
* regen + _log append). Implementations MAY no-op for single-process
|
|
68
|
-
* topologies (local CLI), but cloud hosts MUST enforce real locking.
|
|
69
|
-
*/
|
|
70
|
-
lock(path: string): Promise<FsLockHandle>;
|
|
71
|
-
}
|
|
72
|
-
interface FsLockHandle {
|
|
73
|
-
release(): Promise<void>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
19
|
/**
|
|
77
20
|
* IdentityPort — resolves who is currently acting on the corpus.
|
|
78
21
|
*
|
|
@@ -202,4 +145,4 @@ interface EvaluatorPort {
|
|
|
202
145
|
evaluate(input: EvalInputPort): Promise<EvalResultPort>;
|
|
203
146
|
}
|
|
204
147
|
|
|
205
|
-
export { type CallerIdentity, type ClockPort, type EvalContextPort, type EvalInputPort, type EvalResultPort, type EvalRubricPort, type EvaluatorPort, type FetchedSource, type FetchedSourceKind, type FetcherPort, type
|
|
148
|
+
export { type CallerIdentity, type ClockPort, type EvalContextPort, type EvalInputPort, type EvalResultPort, type EvalRubricPort, type EvaluatorPort, type FetchedSource, type FetchedSourceKind, type FetcherPort, type IdentityPort, systemClock };
|
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { F as FsPort } from '../fs.port-BHzctsoT.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ReportConfig — the single source of truth for a long-form report rendered
|
|
6
|
+
* from a corpus dataset. Superset of the two pre-existing shapes (the Claude
|
|
7
|
+
* bible toolkit's `bible.config.json` + the AIP `bibleConfigSchema`); the
|
|
8
|
+
* authoring reference is `.claude/skills/deep-research/bible/config.schema.md`.
|
|
9
|
+
*
|
|
10
|
+
* Validated with zod (NOT AJV — avoids corpus-cli's findSpecsRoot). Unknown
|
|
11
|
+
* keys pass through so presentation/render fields the engine doesn't read
|
|
12
|
+
* (covers, header/footer, parts) survive a parse round-trip untouched.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** A key/value fact rendered on a branded cover (`facts[]`). */
|
|
16
|
+
declare const reportCoverFactSchema: z.ZodObject<{
|
|
17
|
+
k: z.ZodString;
|
|
18
|
+
v: z.ZodString;
|
|
19
|
+
}, z.core.$loose>;
|
|
20
|
+
/** One extra full-bleed cover (front or back). Data → one shared template. */
|
|
21
|
+
declare const reportCoverPageSchema: z.ZodObject<{
|
|
22
|
+
kicker: z.ZodOptional<z.ZodString>;
|
|
23
|
+
title: z.ZodOptional<z.ZodString>;
|
|
24
|
+
meta: z.ZodOptional<z.ZodString>;
|
|
25
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
26
|
+
align: z.ZodOptional<z.ZodString>;
|
|
27
|
+
facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
28
|
+
k: z.ZodString;
|
|
29
|
+
v: z.ZodString;
|
|
30
|
+
}, z.core.$loose>>>;
|
|
31
|
+
}, z.core.$loose>;
|
|
32
|
+
/** The title cover (1re de couverture). */
|
|
33
|
+
declare const reportCoverSchema: z.ZodObject<{
|
|
34
|
+
brand: z.ZodOptional<z.ZodString>;
|
|
35
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
36
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
37
|
+
meta: z.ZodOptional<z.ZodString>;
|
|
38
|
+
brandLetterSpacing: z.ZodOptional<z.ZodString>;
|
|
39
|
+
brandFontSize: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$loose>;
|
|
41
|
+
/** A part grouping that drives stitch ordering. */
|
|
42
|
+
declare const reportPartSchema: z.ZodObject<{
|
|
43
|
+
heading: z.ZodString;
|
|
44
|
+
chapters: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
45
|
+
}, z.core.$loose>;
|
|
46
|
+
/**
|
|
47
|
+
* One report unit. Carries BOTH write fields (words/src/cover) and
|
|
48
|
+
* pack-routing fields (facets/kw/cap). `id` doubles as the view filename
|
|
49
|
+
* and the `<id>.md` chapter source.
|
|
50
|
+
*/
|
|
51
|
+
declare const reportChapterSchema: z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
title: z.ZodString;
|
|
54
|
+
words: z.ZodOptional<z.ZodString>;
|
|
55
|
+
src: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
56
|
+
cover: z.ZodOptional<z.ZodString>;
|
|
57
|
+
facets: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
58
|
+
kw: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
|
+
cap: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
}, z.core.$loose>;
|
|
61
|
+
declare const reportConfigSchema: z.ZodObject<{
|
|
62
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
63
|
+
dataset: z.ZodOptional<z.ZodString>;
|
|
64
|
+
corpora: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
65
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
66
|
+
bibMax: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
title: z.ZodOptional<z.ZodString>;
|
|
68
|
+
cover: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
brand: z.ZodOptional<z.ZodString>;
|
|
70
|
+
subtitle: z.ZodOptional<z.ZodString>;
|
|
71
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
72
|
+
meta: z.ZodOptional<z.ZodString>;
|
|
73
|
+
brandLetterSpacing: z.ZodOptional<z.ZodString>;
|
|
74
|
+
brandFontSize: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$loose>>;
|
|
76
|
+
frontCovers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
77
|
+
kicker: z.ZodOptional<z.ZodString>;
|
|
78
|
+
title: z.ZodOptional<z.ZodString>;
|
|
79
|
+
meta: z.ZodOptional<z.ZodString>;
|
|
80
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
81
|
+
align: z.ZodOptional<z.ZodString>;
|
|
82
|
+
facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
83
|
+
k: z.ZodString;
|
|
84
|
+
v: z.ZodString;
|
|
85
|
+
}, z.core.$loose>>>;
|
|
86
|
+
}, z.core.$loose>>>;
|
|
87
|
+
backCovers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
88
|
+
kicker: z.ZodOptional<z.ZodString>;
|
|
89
|
+
title: z.ZodOptional<z.ZodString>;
|
|
90
|
+
meta: z.ZodOptional<z.ZodString>;
|
|
91
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
92
|
+
align: z.ZodOptional<z.ZodString>;
|
|
93
|
+
facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
k: z.ZodString;
|
|
95
|
+
v: z.ZodString;
|
|
96
|
+
}, z.core.$loose>>>;
|
|
97
|
+
}, z.core.$loose>>>;
|
|
98
|
+
runningHeader: z.ZodOptional<z.ZodString>;
|
|
99
|
+
runningFooter: z.ZodOptional<z.ZodString>;
|
|
100
|
+
frontFile: z.ZodOptional<z.ZodString>;
|
|
101
|
+
annexesFile: z.ZodOptional<z.ZodString>;
|
|
102
|
+
parts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
103
|
+
heading: z.ZodString;
|
|
104
|
+
chapters: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
105
|
+
}, z.core.$loose>>>;
|
|
106
|
+
rulesText: z.ZodOptional<z.ZodString>;
|
|
107
|
+
factsText: z.ZodOptional<z.ZodString>;
|
|
108
|
+
briefText: z.ZodOptional<z.ZodString>;
|
|
109
|
+
chapters: z.ZodArray<z.ZodObject<{
|
|
110
|
+
id: z.ZodString;
|
|
111
|
+
title: z.ZodString;
|
|
112
|
+
words: z.ZodOptional<z.ZodString>;
|
|
113
|
+
src: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
114
|
+
cover: z.ZodOptional<z.ZodString>;
|
|
115
|
+
facets: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
116
|
+
kw: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
117
|
+
cap: z.ZodOptional<z.ZodNumber>;
|
|
118
|
+
}, z.core.$loose>>;
|
|
119
|
+
}, z.core.$loose>;
|
|
120
|
+
type ReportCoverFact = z.infer<typeof reportCoverFactSchema>;
|
|
121
|
+
type ReportCoverPage = z.infer<typeof reportCoverPageSchema>;
|
|
122
|
+
type ReportCover = z.infer<typeof reportCoverSchema>;
|
|
123
|
+
type ReportPart = z.infer<typeof reportPartSchema>;
|
|
124
|
+
type ReportChapter = z.infer<typeof reportChapterSchema>;
|
|
125
|
+
type ReportConfig = z.infer<typeof reportConfigSchema>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* buildPacks — materialize a corpus dataset into per-chapter knowledge views
|
|
129
|
+
* (the L2 "marts" of the pipeline) + a global citation bibliography.
|
|
130
|
+
*
|
|
131
|
+
* PURE: reads the dataset through an injected read-only `FsPort` and RETURNS
|
|
132
|
+
* the files to write — it never writes. The frontend (CLI / AIP tool) owns
|
|
133
|
+
* the report-rooted writer, so the dataset stays read-only to this module
|
|
134
|
+
* (invariant 1). This is the single source of truth that both the Claude
|
|
135
|
+
* `build-packs.mjs` and the AIP `corpus.report-packs` tool delegate to,
|
|
136
|
+
* porting the skill's semantics (the authoritative reference).
|
|
137
|
+
*
|
|
138
|
+
* Global [n] citation numbering: every source in the dataset gets one stable
|
|
139
|
+
* number (facet-ordered, then title); each distilled entry cites its sources
|
|
140
|
+
* by those numbers. Chapter routing = facet match + keyword needles + cap.
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
interface PackFile {
|
|
144
|
+
/** Path relative to the report root (e.g. `views/_bibliography.json`). */
|
|
145
|
+
readonly path: string;
|
|
146
|
+
readonly content: string;
|
|
147
|
+
}
|
|
148
|
+
interface BuildPacksResult {
|
|
149
|
+
/** All files to write under the report root, in deterministic order. */
|
|
150
|
+
readonly files: readonly PackFile[];
|
|
151
|
+
/** Number of sources in the global bibliography. */
|
|
152
|
+
readonly bibliography: number;
|
|
153
|
+
/** Per-chapter view summary. */
|
|
154
|
+
readonly chapters: ReadonlyArray<{
|
|
155
|
+
readonly id: string;
|
|
156
|
+
readonly title: string;
|
|
157
|
+
readonly entryCount: number;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
interface BuildPacksOptions {
|
|
161
|
+
/** Read-only view of the dataset (sources/ + entries/). */
|
|
162
|
+
readonly dataset: FsPort;
|
|
163
|
+
readonly config: ReportConfig;
|
|
164
|
+
/**
|
|
165
|
+
* Subdir under the report root for the views + bibliography. Default
|
|
166
|
+
* `views`; the parity path against the legacy on-disk corpora passes
|
|
167
|
+
* `packs`. Also embedded in each view's "Also read" pointer text.
|
|
168
|
+
*/
|
|
169
|
+
readonly viewsDir?: string;
|
|
170
|
+
}
|
|
171
|
+
declare function buildPacks(opts: BuildPacksOptions): Promise<BuildPacksResult>;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Citation helpers shared across the report glue. A citation is `[n]` or
|
|
175
|
+
* `[n, m, …]` referencing the global bibliography index.
|
|
176
|
+
*/
|
|
177
|
+
/** Every citation number referenced in a string (flattening `[a, b]`). */
|
|
178
|
+
declare function citesOf(s: string): number[];
|
|
179
|
+
/** Citation numbers in `s` outside the valid `[1, bibMax]` range. */
|
|
180
|
+
declare function outOfRangeCites(s: string, bibMax: number): number[];
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* assembleChapters — turn the write step's raw per-chapter drafts into clean
|
|
184
|
+
* chapter files. Pure: in-memory drafts → files to write (the caller owns the
|
|
185
|
+
* report-rooted writer). Mechanical only — strips agent preambles, normalizes
|
|
186
|
+
* `[a→b]` cross-refs to `[b]`, collapses blank runs; no model calls.
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
interface ChapterDraft {
|
|
190
|
+
/** Chapter id (= `<chaptersDir>/<ch>.md`). */
|
|
191
|
+
readonly ch: string;
|
|
192
|
+
readonly draft: string;
|
|
193
|
+
}
|
|
194
|
+
interface AssembleResult {
|
|
195
|
+
readonly files: readonly PackFile[];
|
|
196
|
+
readonly stats: {
|
|
197
|
+
readonly chapters: number;
|
|
198
|
+
readonly preamblesStripped: number;
|
|
199
|
+
readonly withOutOfRangeCites: number;
|
|
200
|
+
readonly outOfRange: ReadonlyArray<{
|
|
201
|
+
ch: string;
|
|
202
|
+
cites: number[];
|
|
203
|
+
}>;
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
interface AssembleOptions {
|
|
207
|
+
readonly chapters: readonly ChapterDraft[];
|
|
208
|
+
/** Highest valid citation [n]; cites above it are flagged (not dropped). */
|
|
209
|
+
readonly bibMax: number;
|
|
210
|
+
/** Subdir under the report root for chapter files. Default `chapters`. */
|
|
211
|
+
readonly chaptersDir?: string;
|
|
212
|
+
}
|
|
213
|
+
/** Drop any leading agent chatter before the first "## " and tidy whitespace. */
|
|
214
|
+
declare function cleanDraft(draft: string | undefined): string;
|
|
215
|
+
declare function assembleChapters(opts: AssembleOptions): AssembleResult;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* ReportContent — the ONE medium-agnostic shape of a finished report.
|
|
219
|
+
*
|
|
220
|
+
* `buildReportContent` reads the report root (config + chapters/ + the
|
|
221
|
+
* bibliography view) and RETURNS the structured content: an ordered list of
|
|
222
|
+
* sections (each raw markdown) plus the structured bibliography and document
|
|
223
|
+
* metadata. It is PURE and port-injected like the rest of the engine — it
|
|
224
|
+
* never touches the dataset and never renders HTML/PDF (no Chrome here).
|
|
225
|
+
*
|
|
226
|
+
* Every render medium is an AIP `render.*` tool whose input is a
|
|
227
|
+
* `ReportContent`; the canvakit driver (in `@canvakit/report`) is the only
|
|
228
|
+
* place HTML/PDF lives. The markdown medium is reconstructed losslessly by
|
|
229
|
+
* `reportContentToMarkdown` — which is exactly what `stitchReport` emits, so
|
|
230
|
+
* REPORT.md byte-parity is preserved (the two share `collectReportSections`).
|
|
231
|
+
*/
|
|
232
|
+
|
|
233
|
+
/** What role a section plays in the document. */
|
|
234
|
+
declare const reportSectionKindSchema: z.ZodEnum<{
|
|
235
|
+
sources: "sources";
|
|
236
|
+
front: "front";
|
|
237
|
+
part: "part";
|
|
238
|
+
chapter: "chapter";
|
|
239
|
+
annexes: "annexes";
|
|
240
|
+
}>;
|
|
241
|
+
/** One contiguous unit of a report (front, a part divider, a chapter, …). */
|
|
242
|
+
declare const reportSectionSchema: z.ZodObject<{
|
|
243
|
+
id: z.ZodString;
|
|
244
|
+
title: z.ZodString;
|
|
245
|
+
markdown: z.ZodString;
|
|
246
|
+
kind: z.ZodEnum<{
|
|
247
|
+
sources: "sources";
|
|
248
|
+
front: "front";
|
|
249
|
+
part: "part";
|
|
250
|
+
chapter: "chapter";
|
|
251
|
+
annexes: "annexes";
|
|
252
|
+
}>;
|
|
253
|
+
}, z.core.$strip>;
|
|
254
|
+
/** One global citation source (mirrors `views/_bibliography.json`). */
|
|
255
|
+
declare const bibEntrySchema: z.ZodObject<{
|
|
256
|
+
n: z.ZodNumber;
|
|
257
|
+
id: z.ZodString;
|
|
258
|
+
title: z.ZodString;
|
|
259
|
+
url: z.ZodString;
|
|
260
|
+
}, z.core.$strip>;
|
|
261
|
+
/**
|
|
262
|
+
* The medium-agnostic content a `render.*` tool consumes — the single source
|
|
263
|
+
* of truth for "what a report's content is". Zod so the render tool schemas
|
|
264
|
+
* can embed it directly (one definition across the engine and every renderer).
|
|
265
|
+
*/
|
|
266
|
+
declare const reportContentSchema: z.ZodObject<{
|
|
267
|
+
title: z.ZodString;
|
|
268
|
+
sections: z.ZodArray<z.ZodObject<{
|
|
269
|
+
id: z.ZodString;
|
|
270
|
+
title: z.ZodString;
|
|
271
|
+
markdown: z.ZodString;
|
|
272
|
+
kind: z.ZodEnum<{
|
|
273
|
+
sources: "sources";
|
|
274
|
+
front: "front";
|
|
275
|
+
part: "part";
|
|
276
|
+
chapter: "chapter";
|
|
277
|
+
annexes: "annexes";
|
|
278
|
+
}>;
|
|
279
|
+
}, z.core.$strip>>;
|
|
280
|
+
bibliography: z.ZodOptional<z.ZodObject<{
|
|
281
|
+
mode: z.ZodLiteral<"numbered">;
|
|
282
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
283
|
+
n: z.ZodNumber;
|
|
284
|
+
id: z.ZodString;
|
|
285
|
+
title: z.ZodString;
|
|
286
|
+
url: z.ZodString;
|
|
287
|
+
}, z.core.$strip>>;
|
|
288
|
+
}, z.core.$strip>>;
|
|
289
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
290
|
+
}, z.core.$strip>;
|
|
291
|
+
type ReportSection = z.infer<typeof reportSectionSchema>;
|
|
292
|
+
type BibEntry = z.infer<typeof bibEntrySchema>;
|
|
293
|
+
type ReportContent = z.infer<typeof reportContentSchema>;
|
|
294
|
+
interface CollectSectionsOptions {
|
|
295
|
+
readonly config: ReportConfig;
|
|
296
|
+
/** Read-side view of the report root (chapters/ + views/ + front/annexes). */
|
|
297
|
+
readonly report: FsPort;
|
|
298
|
+
/** Subdir holding the written chapter files. Default `chapters`. */
|
|
299
|
+
readonly chaptersDir?: string;
|
|
300
|
+
/** Subdir holding the bibliography. Default `views`. */
|
|
301
|
+
readonly viewsDir?: string;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Collect a report's ordered sections from the report root. This is the
|
|
305
|
+
* single read path shared by `stitchReport` (markdown medium) and
|
|
306
|
+
* `buildReportContent` (every other medium), so the section boundaries — and
|
|
307
|
+
* therefore REPORT.md — are identical regardless of the consumer.
|
|
308
|
+
*
|
|
309
|
+
* Order: front? · (parts ? part-heading + its chapters : chapters in config
|
|
310
|
+
* order) · annexes? · Sources (from the bibliography). Mirrors the legacy
|
|
311
|
+
* stitch exactly; all reads are report-side (the dataset is never touched).
|
|
312
|
+
*/
|
|
313
|
+
declare function collectReportSections(opts: CollectSectionsOptions): Promise<ReportSection[]>;
|
|
314
|
+
/**
|
|
315
|
+
* Reconstruct the canonical REPORT.md from collected sections. Byte-identical
|
|
316
|
+
* to the legacy stitch output (`out.join("\n\n") + "\n"`).
|
|
317
|
+
*/
|
|
318
|
+
declare function reportContentToMarkdown(sections: readonly ReportSection[]): string;
|
|
319
|
+
type BuildReportContentOptions = CollectSectionsOptions;
|
|
320
|
+
/**
|
|
321
|
+
* Build the medium-agnostic {@link ReportContent} for a report. Pure: reads
|
|
322
|
+
* the report root through the injected FsPort and returns structured content —
|
|
323
|
+
* the single input every `render.*` tool consumes.
|
|
324
|
+
*/
|
|
325
|
+
declare function buildReportContent(opts: BuildReportContentOptions): Promise<ReportContent>;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* stitchReport — assemble the final REPORT.md = front + part dividers +
|
|
329
|
+
* chapters + annexes + a Sources section (from the global bibliography), per
|
|
330
|
+
* the config's `parts[]`. Pure: reads report-side files through an injected
|
|
331
|
+
* FsPort and RETURNS the document string (the caller writes REPORT.md).
|
|
332
|
+
*
|
|
333
|
+
* It is the markdown render medium: `stitchReport === reportContentToMarkdown
|
|
334
|
+
* ∘ collectReportSections`. The shared section collection guarantees the
|
|
335
|
+
* markdown medium and every `render.*` tool see the exact same boundaries.
|
|
336
|
+
*
|
|
337
|
+
* All reads are report-side (chapters + views) — the dataset is not touched.
|
|
338
|
+
*/
|
|
339
|
+
|
|
340
|
+
type StitchOptions = CollectSectionsOptions;
|
|
341
|
+
interface StitchResult {
|
|
342
|
+
readonly content: string;
|
|
343
|
+
readonly wordCount: number;
|
|
344
|
+
}
|
|
345
|
+
declare function stitchReport(opts: StitchOptions): Promise<StitchResult>;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* applyEdits — apply {find, replace, reason} edits (from the fix step) to
|
|
349
|
+
* chapter files by EXACT match. An edit lands only if `find` occurs exactly
|
|
350
|
+
* once AND `replace` adds no out-of-range [n]; everything else is reported,
|
|
351
|
+
* not forced. A chapter is written only if at least one edit applied and the
|
|
352
|
+
* post-check passes (still starts at "## ", no out-of-range cites).
|
|
353
|
+
*
|
|
354
|
+
* Reads chapter files through an injected FsPort; RETURNS the writes + a
|
|
355
|
+
* human-readable apply report (the caller owns the writer).
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
interface ChapterEdit {
|
|
359
|
+
readonly find?: string;
|
|
360
|
+
readonly replace?: string;
|
|
361
|
+
readonly reason?: string;
|
|
362
|
+
}
|
|
363
|
+
interface ChapterEditSet {
|
|
364
|
+
readonly id: string;
|
|
365
|
+
readonly edits?: readonly ChapterEdit[];
|
|
366
|
+
}
|
|
367
|
+
interface ApplyEditsResult {
|
|
368
|
+
/** Chapter files to (over)write — already post-checked. */
|
|
369
|
+
readonly files: readonly PackFile[];
|
|
370
|
+
/** The fix-apply report markdown. */
|
|
371
|
+
readonly report: string;
|
|
372
|
+
readonly stats: {
|
|
373
|
+
readonly filesChanged: number;
|
|
374
|
+
readonly applied: number;
|
|
375
|
+
readonly skipped: number;
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
interface ApplyEditsOptions {
|
|
379
|
+
readonly results: readonly ChapterEditSet[];
|
|
380
|
+
readonly bibMax: number;
|
|
381
|
+
/** Read-side view of the report root. */
|
|
382
|
+
readonly report: FsPort;
|
|
383
|
+
/** Subdir holding chapter files. Default `chapters`. */
|
|
384
|
+
readonly chaptersDir?: string;
|
|
385
|
+
}
|
|
386
|
+
declare function applyEdits(opts: ApplyEditsOptions): Promise<ApplyEditsResult>;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* ReportModelPort — the minimal model seam the report's model steps consume.
|
|
390
|
+
*
|
|
391
|
+
* Structural, not nominal: the AIP `ModelPort` (`complete({system?, prompt}) →
|
|
392
|
+
* {result}`) satisfies it as-is, so the same engine runs under any registered
|
|
393
|
+
* model. The single-pass functions here ARE the "model driver" tier; the
|
|
394
|
+
* higher-fidelity claude-code path (Phase C) reuses the same prompt-builders
|
|
395
|
+
* but swaps the executor for file-reading sub-agents.
|
|
396
|
+
*/
|
|
397
|
+
interface ReportModelInput {
|
|
398
|
+
readonly system?: string;
|
|
399
|
+
readonly prompt: string;
|
|
400
|
+
}
|
|
401
|
+
interface ReportModelOutput {
|
|
402
|
+
/** Completion payload — string for text, or a structured object. */
|
|
403
|
+
readonly result: string | unknown;
|
|
404
|
+
}
|
|
405
|
+
interface ReportModelPort {
|
|
406
|
+
complete(input: ReportModelInput): Promise<ReportModelOutput>;
|
|
407
|
+
}
|
|
408
|
+
/** Run a prompt and coerce the completion to text. */
|
|
409
|
+
declare function runModel(model: ReportModelPort, input: ReportModelInput): Promise<string>;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* analyze — synthesize the distilled entries of each facet into a structured
|
|
413
|
+
* markdown analysis doc (`sources.<facet>.md`), the deeper context the chapter
|
|
414
|
+
* writer reads. A report-side step (invariant 3): it READS the dataset's
|
|
415
|
+
* entries and RETURNS report-rooted files; it never writes the dataset.
|
|
416
|
+
*/
|
|
417
|
+
|
|
418
|
+
interface AnalyzeFacetInput {
|
|
419
|
+
readonly facet: string;
|
|
420
|
+
/** Pre-rendered entries block (title/kind/confidence + body per entry). */
|
|
421
|
+
readonly entriesText: string;
|
|
422
|
+
}
|
|
423
|
+
/** The prompt for one facet's analysis doc — pure, driver-reusable. */
|
|
424
|
+
declare function buildFacetAnalysisPrompt(input: AnalyzeFacetInput): ReportModelInput;
|
|
425
|
+
interface AnalyzeDatasetOptions {
|
|
426
|
+
/** Read-only view of the dataset (entries/). */
|
|
427
|
+
readonly dataset: FsPort;
|
|
428
|
+
readonly facets: readonly string[];
|
|
429
|
+
readonly model: ReportModelPort;
|
|
430
|
+
}
|
|
431
|
+
interface AnalyzeDatasetResult {
|
|
432
|
+
/** `sources.<facet>.md` files to write at the report root. */
|
|
433
|
+
readonly files: readonly PackFile[];
|
|
434
|
+
readonly analyzed: number;
|
|
435
|
+
/** Facets skipped because they resolved to zero entries. */
|
|
436
|
+
readonly skipped: readonly string[];
|
|
437
|
+
}
|
|
438
|
+
declare function analyzeDataset(opts: AnalyzeDatasetOptions): Promise<AnalyzeDatasetResult>;
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* write — the single-pass chapter writer (the "model driver" tier). Given a
|
|
442
|
+
* chapter's view (distilled claims + [n] cites), the per-facet analysis, and
|
|
443
|
+
* the bibliography, produce a cited markdown draft.
|
|
444
|
+
*
|
|
445
|
+
* `buildChapterWritePrompt` is pure and exported so the higher-fidelity
|
|
446
|
+
* claude-code driver (Phase C) reuses the identical prompt while swapping the
|
|
447
|
+
* executor for a file-reading sub-agent. `writeChapter` is the model-driver
|
|
448
|
+
* executor. Output is a raw DRAFT — `assembleChapters` then cleans it.
|
|
449
|
+
*/
|
|
450
|
+
|
|
451
|
+
interface ChapterWriteContext {
|
|
452
|
+
readonly chapter: Pick<ReportChapter, "id" | "title" | "words">;
|
|
453
|
+
/** Report/document title for framing. */
|
|
454
|
+
readonly title: string;
|
|
455
|
+
/** The chapter's view content (distilled claims with [n]). */
|
|
456
|
+
readonly packContent: string;
|
|
457
|
+
/** Concatenated per-facet analysis docs (optional deeper context). */
|
|
458
|
+
readonly analysisContext?: string;
|
|
459
|
+
/** The global bibliography markdown (for citation verification). */
|
|
460
|
+
readonly bibliography?: string;
|
|
461
|
+
}
|
|
462
|
+
declare function buildChapterWritePrompt(ctx: ChapterWriteContext): ReportModelInput;
|
|
463
|
+
/** Single-pass chapter write → a `{ ch, draft }` ready for assembleChapters. */
|
|
464
|
+
declare function writeChapter(ctx: ChapterWriteContext, model: ReportModelPort): Promise<{
|
|
465
|
+
ch: string;
|
|
466
|
+
draft: string;
|
|
467
|
+
}>;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* review — the single-pass chapter reviewer (the "model driver" tier of the
|
|
471
|
+
* quality loop). Given a chapter's current prose, its per-facet analysis, and
|
|
472
|
+
* the bibliography, the model returns a set of EXACT-MATCH `{find, replace,
|
|
473
|
+
* reason}` edits that `applyEdits` can land verbatim (fact/citation fixes,
|
|
474
|
+
* overstatement trims). It never rewrites the chapter — only proposes targeted,
|
|
475
|
+
* verifiable edits, so the fix step stays deterministic.
|
|
476
|
+
*
|
|
477
|
+
* `buildReviewPrompt` is pure + exported so the claude-code driver reuses it.
|
|
478
|
+
*/
|
|
479
|
+
|
|
480
|
+
interface ChapterReviewContext {
|
|
481
|
+
readonly chapter: {
|
|
482
|
+
readonly id: string;
|
|
483
|
+
readonly title: string;
|
|
484
|
+
};
|
|
485
|
+
/** The chapter's current markdown (what gets reviewed). */
|
|
486
|
+
readonly chapterText: string;
|
|
487
|
+
/** Concatenated per-facet analysis docs (the ground truth to check against). */
|
|
488
|
+
readonly analysisContext?: string;
|
|
489
|
+
/** The global bibliography markdown (citation range + targets). */
|
|
490
|
+
readonly bibliography?: string;
|
|
491
|
+
/** Highest valid citation [n] — replacements must not exceed it. */
|
|
492
|
+
readonly bibMax: number;
|
|
493
|
+
}
|
|
494
|
+
declare function buildReviewPrompt(ctx: ChapterReviewContext): ReportModelInput;
|
|
495
|
+
/**
|
|
496
|
+
* Single-pass chapter review → a {@link ChapterEditSet} ready for
|
|
497
|
+
* `applyEdits`. Tolerant: a malformed completion yields no edits (the chapter
|
|
498
|
+
* is left untouched) rather than throwing — review is an enhancement, not a gate.
|
|
499
|
+
*/
|
|
500
|
+
declare function reviewChapter(ctx: ChapterReviewContext, model: ReportModelPort): Promise<ChapterEditSet>;
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* plan — the auto-outliner. Turns (brief + dataset facets + profile) into a
|
|
504
|
+
* chapter outline, so a report can run from a topic with NO hand-authored
|
|
505
|
+
* config. Model-driven; the returned chapters are zod-validated and carry the
|
|
506
|
+
* routing fields (facets/kw/cap) the pack builder needs.
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
interface PlanOutlineOptions {
|
|
510
|
+
/** The research brief / framing (what the report should cover). */
|
|
511
|
+
readonly brief: string;
|
|
512
|
+
/** Facets discovered in the dataset (the tags chapters route against). */
|
|
513
|
+
readonly facets: readonly string[];
|
|
514
|
+
/** Profile preset that shapes the unit (bible | brief | memo | deck). */
|
|
515
|
+
readonly profile?: string;
|
|
516
|
+
/** Target chapter count (a hint, not a hard cap). */
|
|
517
|
+
readonly targetChapters?: number;
|
|
518
|
+
readonly model: ReportModelPort;
|
|
519
|
+
}
|
|
520
|
+
interface PlanOutlineResult {
|
|
521
|
+
readonly title?: string;
|
|
522
|
+
readonly chapters: readonly ReportChapter[];
|
|
523
|
+
}
|
|
524
|
+
declare function planOutline(opts: PlanOutlineOptions): Promise<PlanOutlineResult>;
|
|
525
|
+
|
|
526
|
+
export { type AnalyzeDatasetOptions, type AnalyzeDatasetResult, type AnalyzeFacetInput, type ApplyEditsOptions, type ApplyEditsResult, type AssembleOptions, type AssembleResult, type BibEntry, type BuildPacksOptions, type BuildPacksResult, type BuildReportContentOptions, type ChapterDraft, type ChapterEdit, type ChapterEditSet, type ChapterReviewContext, type ChapterWriteContext, type CollectSectionsOptions, type PackFile, type PlanOutlineOptions, type PlanOutlineResult, type ReportChapter, type ReportConfig, type ReportContent, type ReportCover, type ReportCoverFact, type ReportCoverPage, type ReportModelInput, type ReportModelOutput, type ReportModelPort, type ReportPart, type ReportSection, type StitchOptions, type StitchResult, analyzeDataset, applyEdits, assembleChapters, bibEntrySchema, buildChapterWritePrompt, buildFacetAnalysisPrompt, buildPacks, buildReportContent, buildReviewPrompt, citesOf, cleanDraft, collectReportSections, outOfRangeCites, planOutline, reportChapterSchema, reportConfigSchema, reportContentSchema, reportContentToMarkdown, reportCoverFactSchema, reportCoverPageSchema, reportCoverSchema, reportPartSchema, reportSectionKindSchema, reportSectionSchema, reviewChapter, runModel, stitchReport, writeChapter };
|