okf-catalog 0.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.
Files changed (107) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +10 -0
  4. package/README.md +87 -0
  5. package/dist/bundle/cat-file.js +94 -0
  6. package/dist/bundle/cat-file.js.map +1 -0
  7. package/dist/bundle/contract.js +60 -0
  8. package/dist/bundle/contract.js.map +1 -0
  9. package/dist/bundle/frontmatter.js +106 -0
  10. package/dist/bundle/frontmatter.js.map +1 -0
  11. package/dist/bundle/git-tree.js +109 -0
  12. package/dist/bundle/git-tree.js.map +1 -0
  13. package/dist/bundle/index-file.js +90 -0
  14. package/dist/bundle/index-file.js.map +1 -0
  15. package/dist/bundle/links.js +57 -0
  16. package/dist/bundle/links.js.map +1 -0
  17. package/dist/bundle/load.js +363 -0
  18. package/dist/bundle/load.js.map +1 -0
  19. package/dist/bundle/manifest.js +95 -0
  20. package/dist/bundle/manifest.js.map +1 -0
  21. package/dist/bundle/markdown.js +210 -0
  22. package/dist/bundle/markdown.js.map +1 -0
  23. package/dist/bundle/model.js +7 -0
  24. package/dist/bundle/model.js.map +1 -0
  25. package/dist/bundle/page.js +374 -0
  26. package/dist/bundle/page.js.map +1 -0
  27. package/dist/bundle/paths.js +36 -0
  28. package/dist/bundle/paths.js.map +1 -0
  29. package/dist/bundle/reserved.js +56 -0
  30. package/dist/bundle/reserved.js.map +1 -0
  31. package/dist/bundle/timestamp.js +49 -0
  32. package/dist/bundle/timestamp.js.map +1 -0
  33. package/dist/catalog/model.js +32 -0
  34. package/dist/catalog/model.js.map +1 -0
  35. package/dist/catalog/nearest.js +56 -0
  36. package/dist/catalog/nearest.js.map +1 -0
  37. package/dist/catalog/outputs.js +438 -0
  38. package/dist/catalog/outputs.js.map +1 -0
  39. package/dist/catalog/provenance.js +37 -0
  40. package/dist/catalog/provenance.js.map +1 -0
  41. package/dist/catalog/runtime.js +2 -0
  42. package/dist/catalog/runtime.js.map +1 -0
  43. package/dist/catalog/text.js +140 -0
  44. package/dist/catalog/text.js.map +1 -0
  45. package/dist/cli.js +81 -0
  46. package/dist/cli.js.map +1 -0
  47. package/dist/commands/check.js +155 -0
  48. package/dist/commands/check.js.map +1 -0
  49. package/dist/commands/pack.js +182 -0
  50. package/dist/commands/pack.js.map +1 -0
  51. package/dist/commands/serve.js +452 -0
  52. package/dist/commands/serve.js.map +1 -0
  53. package/dist/config/company-config.js +272 -0
  54. package/dist/config/company-config.js.map +1 -0
  55. package/dist/derive/derived-document.js +42 -0
  56. package/dist/derive/derived-document.js.map +1 -0
  57. package/dist/engine/qmd-render.js +54 -0
  58. package/dist/engine/qmd-render.js.map +1 -0
  59. package/dist/engine/qmd.js +241 -0
  60. package/dist/engine/qmd.js.map +1 -0
  61. package/dist/fs/cache-dir.js +140 -0
  62. package/dist/fs/cache-dir.js.map +1 -0
  63. package/dist/fs/company-lock.js +162 -0
  64. package/dist/fs/company-lock.js.map +1 -0
  65. package/dist/fs/walk.js +168 -0
  66. package/dist/fs/walk.js.map +1 -0
  67. package/dist/log.js +65 -0
  68. package/dist/log.js.map +1 -0
  69. package/dist/mcp/server.js +30 -0
  70. package/dist/mcp/server.js.map +1 -0
  71. package/dist/mcp/stdio.js +45 -0
  72. package/dist/mcp/stdio.js.map +1 -0
  73. package/dist/mcp/tools.js +249 -0
  74. package/dist/mcp/tools.js.map +1 -0
  75. package/dist/report/report.js +43 -0
  76. package/dist/report/report.js.map +1 -0
  77. package/dist/search/engine.js +2 -0
  78. package/dist/search/engine.js.map +1 -0
  79. package/dist/search/query.js +91 -0
  80. package/dist/search/query.js.map +1 -0
  81. package/dist/search/search.js +224 -0
  82. package/dist/search/search.js.map +1 -0
  83. package/dist/search/snippet.js +95 -0
  84. package/dist/search/snippet.js.map +1 -0
  85. package/dist/serve/poller.js +119 -0
  86. package/dist/serve/poller.js.map +1 -0
  87. package/dist/serve/runtime.js +390 -0
  88. package/dist/serve/runtime.js.map +1 -0
  89. package/dist/source/git-runner.js +232 -0
  90. package/dist/source/git-runner.js.map +1 -0
  91. package/dist/source/git.js +457 -0
  92. package/dist/source/git.js.map +1 -0
  93. package/dist/source/local.js +20 -0
  94. package/dist/source/local.js.map +1 -0
  95. package/dist/source/source.js +2 -0
  96. package/dist/source/source.js.map +1 -0
  97. package/npm-shrinkwrap.json +5482 -0
  98. package/package.json +80 -0
  99. package/plugin/claude-code/.claude-plugin/plugin.json +15 -0
  100. package/plugin/claude-code/.mcp.json +10 -0
  101. package/plugin/claude-code/skills/okf-catalog/SKILL.md +15 -0
  102. package/recipes/publish/README.md +32 -0
  103. package/recipes/publish/checkers.lock +435 -0
  104. package/recipes/publish/checkers.txt +5 -0
  105. package/recipes/publish/pack.sh +60 -0
  106. package/recipes/publish/publish.yml +88 -0
  107. package/recipes/publish/push.sh +63 -0
@@ -0,0 +1,438 @@
1
+ import { z } from "zod/v4";
2
+ import { byCodeUnit } from "../bundle/paths.js";
3
+ import { snippet } from "../search/snippet.js";
4
+ import { provenanceOf } from "./provenance.js";
5
+ import { DATA_SENTENCE, hitLine, MARKER, pageHeader, reservedHeader, safe, searchHeader, } from "./text.js";
6
+ /** Characters a result may carry before it is cut and told where to continue (Claude Code saves longer results to a file). */
7
+ export const RESULT_BUDGET = 40_000;
8
+ /** Entries a status list carries beside its count. */
9
+ export const STATUS_LIST_CAP = 50;
10
+ /** The most characters of a refusing text that reach the model, after escaping. */
11
+ export const REFUSING_CAP = 1_000;
12
+ /** A refusing text as the model may see it: made safe (one line, controls escaped) and cut at the cap. */
13
+ export function refusingText(text) {
14
+ const made = safe(text);
15
+ if (made.length <= REFUSING_CAP)
16
+ return made;
17
+ const end = isHighSurrogate(made, REFUSING_CAP - 1) ? REFUSING_CAP - 1 : REFUSING_CAP;
18
+ return `${made.slice(0, end)}…`;
19
+ }
20
+ const isHighSurrogate = (text, at) => {
21
+ const code = text.charCodeAt(at);
22
+ return code >= 0xd800 && code <= 0xdbff;
23
+ };
24
+ /** The text from `offset`, cut at a line boundary within `budget` when it does not fit, never inside a surrogate pair. */
25
+ export function cutText(text, offset, budget) {
26
+ const from = Math.max(0, Math.floor(offset));
27
+ if (from >= text.length)
28
+ return { slice: "", truncated: false };
29
+ const rest = text.slice(from);
30
+ const room = Math.max(1, budget);
31
+ if (rest.length <= room)
32
+ return { slice: rest, truncated: false };
33
+ const newline = rest.lastIndexOf("\n", room - 1);
34
+ let end = newline > 0 ? newline + 1 : room;
35
+ if (end > 1 && isHighSurrogate(rest, end - 1))
36
+ end -= 1;
37
+ return { slice: rest.slice(0, end), truncated: true, nextOffset: from + end };
38
+ }
39
+ /** Characters a provenance's frontmatter may take in a result before it is replaced by a note. */
40
+ export const FRONTMATTER_BUDGET = 8_000;
41
+ /** Characters of a catalog entry's description kept in a result. */
42
+ const ENTRY_DESCRIPTION_CAP = 200;
43
+ const Status = z.enum(["draft", "stable", "deprecated"]);
44
+ const Trust = z.enum(["unverified", "machine-confirmed", "human-reviewed"]);
45
+ const Rung = z.enum(["all-terms", "relaxed"]);
46
+ const Form = z.enum(["date", "datetime", "unparseable"]);
47
+ const Verification = z.strictObject({ by: z.string(), at: z.string().optional() });
48
+ const SourceSchema = z.strictObject({
49
+ resource: z.string(),
50
+ id: z.string().optional(),
51
+ title: z.string().optional(),
52
+ author: z.string().optional(),
53
+ usageCount: z.number().optional(),
54
+ lastModified: z.string().optional(),
55
+ usageWindow: z.strictObject({ from: z.string(), to: z.string() }).optional(),
56
+ });
57
+ export const ProvenanceSchema = z.strictObject({
58
+ path: z.string(),
59
+ title: z.string(),
60
+ type: z.string(),
61
+ status: Status,
62
+ trust: Trust,
63
+ generated: Verification.optional(),
64
+ verified: z.array(Verification),
65
+ latestVerification: Verification.optional(),
66
+ staleAfter: z.strictObject({ raw: z.string(), form: Form, overdue: z.boolean() }).optional(),
67
+ sources: z.array(SourceSchema),
68
+ resource: z.string().optional(),
69
+ replacement: z.string().optional(),
70
+ frontmatter: z.record(z.string(), z.unknown()),
71
+ });
72
+ export const SearchOutputSchema = z.strictObject({
73
+ hits: z.array(z.strictObject({
74
+ path: z.string(),
75
+ title: z.string(),
76
+ type: z.string(),
77
+ status: Status,
78
+ trust: Trust,
79
+ recheck: z.strictObject({
80
+ raw: z.string().nullable(),
81
+ form: Form.nullable(),
82
+ overdue: z.boolean(),
83
+ }),
84
+ replacement: z.string().nullable(),
85
+ sources: z.number(),
86
+ resource: z.string().nullable(),
87
+ rung: Rung,
88
+ termsMatched: z.number().nullable(),
89
+ snippet: z.string(),
90
+ citation: z.string(),
91
+ })),
92
+ summary: z.string(),
93
+ strategy: z.enum(["all-terms", "relaxed", "none"]),
94
+ terms: z.array(z.string()),
95
+ dropped: z.array(z.string()),
96
+ floored: z.array(z.string()),
97
+ considered: z.number(),
98
+ filteredOut: z.strictObject({
99
+ type: z.number(),
100
+ topic: z.number(),
101
+ stale: z.number(),
102
+ unknown: z.number(),
103
+ }),
104
+ topicExhausted: z.boolean(),
105
+ });
106
+ export const PageOutputSchema = z.strictObject({
107
+ path: z.string(),
108
+ kind: z.enum(["page", "index", "log"]),
109
+ source: z.enum(["file", "generated"]).optional(),
110
+ provenance: ProvenanceSchema.optional(),
111
+ citation: z.string(),
112
+ notice: z.string(),
113
+ body: z.string(),
114
+ truncated: z.boolean(),
115
+ nextOffset: z.number().optional(),
116
+ });
117
+ export const CatalogOutputSchema = z.strictObject({
118
+ folder: z.string(),
119
+ source: z.enum(["file", "generated"]),
120
+ entries: z.array(z.strictObject({ path: z.string(), title: z.string(), description: z.string().nullable() })),
121
+ notice: z.string(),
122
+ text: z.string(),
123
+ truncated: z.boolean(),
124
+ nextOffset: z.number().optional(),
125
+ });
126
+ const list = (item) => z.strictObject({ count: z.number(), first: z.array(item) });
127
+ export const StatusOutputSchema = z.strictObject({
128
+ company: z.string(),
129
+ source: z.string(),
130
+ commit: z.string().nullable(),
131
+ loadedAt: z.string(),
132
+ dev: z.boolean(),
133
+ integrity: z.enum(["checked", "skipped"]),
134
+ admitted: z.number(),
135
+ excludedByStatus: z.number(),
136
+ attachments: z.number(),
137
+ hidden: z.number(),
138
+ /** Served pages past their recheck date at the time of the call (intent §6). */
139
+ overdue: z.number(),
140
+ refusals: list(z.strictObject({ path: z.string(), rule: z.string(), detail: z.string() })),
141
+ degradations: list(z.strictObject({ path: z.string(), code: z.string(), field: z.string() })),
142
+ unknownTypes: list(z.string()),
143
+ unknownStatuses: list(z.strictObject({ path: z.string(), value: z.string() })),
144
+ brokenLinks: list(z.strictObject({ from: z.string(), raw: z.string() })),
145
+ linksToUnserved: list(z.strictObject({ from: z.string(), raw: z.string(), target: z.string() })),
146
+ foldersWithoutIndex: list(z.string()),
147
+ missingOnDisk: list(z.string()),
148
+ fatal: z.strictObject({ rule: z.string(), path: z.string(), detail: z.string() }).nullable(),
149
+ engine: z.strictObject({
150
+ documents: z.number(),
151
+ notIndexed: z.number(),
152
+ collisions: z.number(),
153
+ encodedFolders: list(z.string()),
154
+ resetOnOpen: z.string().nullable(),
155
+ }),
156
+ lock: z.enum(["exclusive", "private"]),
157
+ /** The process holding the company lock while this one runs in the private fallback. */
158
+ lockOwner: z
159
+ .strictObject({ pid: z.number(), startedAt: z.string(), alive: z.boolean() })
160
+ .nullable(),
161
+ /** The fetched commit of the published branch and when it was fetched; null for a local source. */
162
+ published: z.strictObject({ commit: z.string(), fetchedAt: z.string() }).nullable(),
163
+ poller: z
164
+ .strictObject({
165
+ intervalMs: z.number(),
166
+ lastTick: z.string().nullable(),
167
+ lastOutcome: z.enum(["unchanged", "refreshed", "failed", "gone", "skipped"]).nullable(),
168
+ })
169
+ .nullable(),
170
+ lastAttempt: z
171
+ .strictObject({ at: z.string(), outcome: z.enum(["swapped", "fatal", "failed"]) })
172
+ .nullable(),
173
+ /** The last load the loader refused: the commit when there is one, the rule, the path and the detail. */
174
+ lastRefusal: z
175
+ .strictObject({
176
+ commit: z.string().nullable(),
177
+ rule: z.string(),
178
+ path: z.string(),
179
+ detail: z.string(),
180
+ })
181
+ .nullable(),
182
+ refusing: z.string().nullable(),
183
+ });
184
+ export const NOTICE = `${MARKER} ${DATA_SENTENCE}`;
185
+ /** The search response as the tool returns it: every hit with its citation and snippet, the header as the summary. */
186
+ export function projectSearch(response, catalog, now, options) {
187
+ void now;
188
+ const hits = response.hits.map((hit) => {
189
+ const page = catalog.pages.get(hit.path);
190
+ const text = snippet(page ?? {}, response.terms);
191
+ return {
192
+ path: hit.path,
193
+ title: hit.title,
194
+ type: hit.type,
195
+ status: hit.status,
196
+ trust: hit.trust,
197
+ recheck: {
198
+ raw: hit.staleAfter ?? null,
199
+ form: page?.staleAfter?.form ?? null,
200
+ overdue: hit.overdue,
201
+ },
202
+ replacement: hit.replacement ?? null,
203
+ sources: hit.sources,
204
+ resource: hit.resource ?? null,
205
+ rung: hit.rung,
206
+ termsMatched: hit.termsMatched ?? null,
207
+ snippet: text,
208
+ citation: hitLine(hit, text, page?.staleAfter?.form),
209
+ };
210
+ });
211
+ return SearchOutputSchema.parse({
212
+ hits,
213
+ summary: searchHeader(response, options.dev),
214
+ strategy: response.strategy,
215
+ terms: response.terms,
216
+ dropped: response.dropped,
217
+ floored: response.floored,
218
+ considered: response.considered,
219
+ filteredOut: response.filteredOut,
220
+ topicExhausted: response.topicExhausted,
221
+ });
222
+ }
223
+ /** Room left for a body once the citation, the notice and a truncation tail are counted inside the budget. */
224
+ const bodyRoom = (budget, citation) => Math.max(1, budget - citation.length - NOTICE.length - 80);
225
+ export function projectPage(page, now, offset, budget) {
226
+ const citation = pageHeader(page, now);
227
+ const cut = cutText(page.body, offset, bodyRoom(budget, citation));
228
+ const provenance = provenanceOf(page, now);
229
+ if (JSON.stringify(provenance.frontmatter).length > FRONTMATTER_BUDGET) {
230
+ provenance.frontmatter = {
231
+ omitted: `the frontmatter is over ${FRONTMATTER_BUDGET} characters and is not returned here`,
232
+ };
233
+ }
234
+ const output = {
235
+ path: page.path,
236
+ kind: "page",
237
+ provenance,
238
+ citation,
239
+ notice: NOTICE,
240
+ body: cut.slice,
241
+ truncated: cut.truncated,
242
+ };
243
+ if (cut.nextOffset !== undefined)
244
+ output.nextOffset = cut.nextOffset;
245
+ return PageOutputSchema.parse(output);
246
+ }
247
+ export function projectReserved(file, source, offset, budget) {
248
+ const citation = reservedHeader(file.kind, source, file.folder);
249
+ const cut = cutText(file.body, offset, bodyRoom(budget, citation));
250
+ const output = {
251
+ path: file.path,
252
+ kind: file.kind,
253
+ source,
254
+ citation,
255
+ notice: NOTICE,
256
+ body: cut.slice,
257
+ truncated: cut.truncated,
258
+ };
259
+ if (cut.nextOffset !== undefined)
260
+ output.nextOffset = cut.nextOffset;
261
+ return PageOutputSchema.parse(output);
262
+ }
263
+ /**
264
+ * A folder's catalog: its entries from the catalog's own pages and the index text framed by the marker, the whole
265
+ * result held within the budget. `offset` counts entries first, then characters of the text: a cut result says
266
+ * where to continue, and the continuation carries the remaining entries, then the remaining text. Undefined for
267
+ * an unknown folder.
268
+ */
269
+ export function projectCatalog(catalog, folder, offset, budget) {
270
+ const entry = catalog.folders.get(folder);
271
+ if (entry === undefined)
272
+ return undefined;
273
+ const all = [...entry.pages].sort(byCodeUnit).map((path) => {
274
+ const page = catalog.pages.get(path);
275
+ const description = page?.description ?? null;
276
+ return {
277
+ path,
278
+ title: page?.title ?? path,
279
+ description: description !== null && description.length > ENTRY_DESCRIPTION_CAP
280
+ ? `${description.slice(0, ENTRY_DESCRIPTION_CAP)}…`
281
+ : description,
282
+ };
283
+ });
284
+ const from = Math.max(0, Math.floor(offset));
285
+ const base = {
286
+ folder,
287
+ source: entry.indexSource,
288
+ notice: NOTICE,
289
+ };
290
+ const frame = JSON.stringify({ ...base, entries: [], text: "", truncated: true, nextOffset: 0 }).length + 80;
291
+ const entries = [];
292
+ let used = frame;
293
+ let index = Math.min(from, all.length);
294
+ while (index < all.length) {
295
+ const item = all[index];
296
+ const cost = JSON.stringify(item).length + 1;
297
+ if (used + cost > budget && entries.length > 0)
298
+ break;
299
+ entries.push(item);
300
+ used += cost;
301
+ index += 1;
302
+ }
303
+ const fullText = `${MARKER}\n${entry.index?.body ?? ""}`;
304
+ // Text offsets start where the entries end: `all.length` entries consumed, then characters of the text.
305
+ const textFrom = Math.max(0, from - all.length);
306
+ const output = {
307
+ ...base,
308
+ entries,
309
+ text: "",
310
+ truncated: false,
311
+ };
312
+ if (index < all.length) {
313
+ // The entries alone filled the budget: the text comes with a later continuation.
314
+ output.truncated = true;
315
+ output.nextOffset = index;
316
+ return CatalogOutputSchema.parse(output);
317
+ }
318
+ const cut = cutText(fullText, textFrom, Math.max(1, budget - used));
319
+ output.text = cut.slice;
320
+ output.truncated = cut.truncated;
321
+ if (cut.nextOffset !== undefined)
322
+ output.nextOffset = all.length + cut.nextOffset;
323
+ return CatalogOutputSchema.parse(output);
324
+ }
325
+ const capped = (items) => ({
326
+ count: items.length,
327
+ first: items.slice(0, STATUS_LIST_CAP),
328
+ });
329
+ export function projectStatus(generation, runtime, options, now) {
330
+ const r = generation.report;
331
+ let overdue = 0;
332
+ for (const page of generation.catalog.pages.values()) {
333
+ if (page.staleAfter?.at !== undefined && now.getTime() >= page.staleAfter.at.getTime())
334
+ overdue += 1;
335
+ }
336
+ return StatusOutputSchema.parse({
337
+ company: options.company,
338
+ source: options.source,
339
+ commit: r.commit ?? null,
340
+ loadedAt: generation.loadedAt.toISOString(),
341
+ dev: generation.dev,
342
+ integrity: generation.integrity,
343
+ admitted: r.admitted,
344
+ excludedByStatus: r.excludedByStatus,
345
+ attachments: r.attachments,
346
+ hidden: r.hidden,
347
+ overdue,
348
+ refusals: capped(r.refusals.map((x) => ({ path: x.path, rule: x.rule, detail: x.detail }))),
349
+ degradations: capped(r.degradations.map((x) => ({ path: x.path, code: x.code, field: x.field }))),
350
+ unknownTypes: capped(r.unknownTypes),
351
+ unknownStatuses: capped(r.unknownStatuses),
352
+ brokenLinks: capped(r.brokenLinks),
353
+ linksToUnserved: capped(r.linksToUnserved),
354
+ foldersWithoutIndex: capped(r.foldersWithoutIndex),
355
+ missingOnDisk: capped(r.missingOnDisk),
356
+ fatal: r.fatal === undefined
357
+ ? null
358
+ : { rule: r.fatal.rule, path: r.fatal.path, detail: r.fatal.detail },
359
+ engine: {
360
+ documents: generation.index.documents,
361
+ notIndexed: generation.index.notIndexed.length,
362
+ collisions: generation.index.collisions.length,
363
+ encodedFolders: capped(generation.index.encodedFolders),
364
+ resetOnOpen: runtime.resetOnOpen === undefined ? null : safe(runtime.resetOnOpen),
365
+ },
366
+ lock: runtime.lock,
367
+ lockOwner: runtime.lockOwner === undefined || runtime.lockOwner === null
368
+ ? null
369
+ : {
370
+ pid: runtime.lockOwner.pid,
371
+ startedAt: safe(runtime.lockOwner.startedAt),
372
+ alive: runtime.lockOwner.alive,
373
+ },
374
+ published: generation.published === undefined
375
+ ? null
376
+ : {
377
+ commit: generation.published.commit,
378
+ fetchedAt: generation.published.fetchedAt.toISOString(),
379
+ },
380
+ poller: runtime.poller === undefined || runtime.poller === null
381
+ ? null
382
+ : {
383
+ intervalMs: runtime.poller.intervalMs,
384
+ lastTick: runtime.poller.lastTick?.toISOString() ?? null,
385
+ lastOutcome: runtime.poller.lastOutcome ?? null,
386
+ },
387
+ lastAttempt: runtime.lastAttempt === undefined
388
+ ? null
389
+ : { at: runtime.lastAttempt.at.toISOString(), outcome: runtime.lastAttempt.outcome },
390
+ lastRefusal: runtime.lastRefusal === undefined
391
+ ? null
392
+ : {
393
+ commit: runtime.lastRefusal.commit ?? null,
394
+ rule: safe(runtime.lastRefusal.rule),
395
+ path: safe(runtime.lastRefusal.path),
396
+ detail: safe(runtime.lastRefusal.detail),
397
+ },
398
+ refusing: runtime.refusing === undefined ? null : refusingText(runtime.refusing),
399
+ });
400
+ }
401
+ /** One line for the `status` text block: the counts, the engine, the lock, the last attempt, and the report's lists as counts. */
402
+ export function statusSummary(out) {
403
+ const n = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
404
+ const parts = [
405
+ `${out.company}: ${out.admitted} pages admitted, ${out.excludedByStatus} excluded by status, ${n(out.overdue, "overdue page")}, ${n(out.refusals.count, "refusal")}, ${n(out.degradations.count, "degradation")}`,
406
+ `integrity ${out.integrity}`,
407
+ `${out.engine.documents} documents indexed, ${out.engine.notIndexed} not indexed, ${n(out.engine.collisions, "collision")}`,
408
+ out.lock === "private"
409
+ ? out.lockOwner === null
410
+ ? "lock private (holder unreadable)"
411
+ : `lock private (held by pid ${out.lockOwner.pid} since ${out.lockOwner.startedAt}, ${out.lockOwner.alive ? "alive" : "not alive"})`
412
+ : `lock ${out.lock}`,
413
+ `loaded ${out.loadedAt}`,
414
+ ...(out.published === null
415
+ ? []
416
+ : [`published ${out.published.commit.slice(0, 12)} fetched ${out.published.fetchedAt}`]),
417
+ ...(out.poller === null
418
+ ? []
419
+ : [
420
+ `poller every ${Math.round(out.poller.intervalMs / 1000)} s${out.poller.lastTick === null ? ", no tick yet" : `, last tick ${out.poller.lastOutcome ?? "?"} at ${out.poller.lastTick}`}`,
421
+ ]),
422
+ ...(out.engine.resetOnOpen === null
423
+ ? []
424
+ : [`engine store rebuilt at open: ${out.engine.resetOnOpen}`]),
425
+ `${n(out.unknownTypes.count, "unknown type")}, ${n(out.unknownStatuses.count, "unknown status")}, ${n(out.brokenLinks.count, "broken link")}, ${n(out.linksToUnserved.count, "link to an unserved page")}, ${n(out.foldersWithoutIndex.count, "folder without an index")}, ${n(out.missingOnDisk.count, "manifest entry missing on disk")}`,
426
+ ];
427
+ if (out.lastAttempt !== null)
428
+ parts.push(`last attempt ${out.lastAttempt.outcome} at ${out.lastAttempt.at}`);
429
+ if (out.lastRefusal !== null)
430
+ parts.push(`last refusal ${out.lastRefusal.commit === null ? "" : `${out.lastRefusal.commit.slice(0, 12)} `}${out.lastRefusal.rule}${out.lastRefusal.path ? ` (${out.lastRefusal.path})` : ""}`);
431
+ if (out.fatal !== null) {
432
+ parts.push(`FATAL ${safe(out.fatal.rule)}${out.fatal.path ? ` (${safe(out.fatal.path)})` : ""}: ${safe(out.fatal.detail)}`);
433
+ }
434
+ if (out.refusing !== null)
435
+ parts.push(`refusing: ${safe(out.refusing)}`);
436
+ return parts.join("; ");
437
+ }
438
+ //# sourceMappingURL=outputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputs.js","sourceRoot":"","sources":["../../src/catalog/outputs.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod/v4\";\nimport type { Page, ReservedFile } from \"../bundle/model.js\";\nimport { byCodeUnit } from \"../bundle/paths.js\";\nimport type { SearchResponse } from \"../search/search.js\";\nimport { snippet } from \"../search/snippet.js\";\nimport type { Catalog } from \"./model.js\";\nimport { provenanceOf } from \"./provenance.js\";\nimport type { Generation, RuntimeStatus, ToolOptions } from \"./runtime.js\";\nimport {\n DATA_SENTENCE,\n hitLine,\n MARKER,\n pageHeader,\n reservedHeader,\n safe,\n searchHeader,\n} from \"./text.js\";\n\n/** Characters a result may carry before it is cut and told where to continue (Claude Code saves longer results to a file). */\nexport const RESULT_BUDGET = 40_000;\n/** Entries a status list carries beside its count. */\nexport const STATUS_LIST_CAP = 50;\n/** The most characters of a refusing text that reach the model, after escaping. */\nexport const REFUSING_CAP = 1_000;\n\n/** A refusing text as the model may see it: made safe (one line, controls escaped) and cut at the cap. */\nexport function refusingText(text: string): string {\n const made = safe(text);\n if (made.length <= REFUSING_CAP) return made;\n const end = isHighSurrogate(made, REFUSING_CAP - 1) ? REFUSING_CAP - 1 : REFUSING_CAP;\n return `${made.slice(0, end)}…`;\n}\n\nexport interface Cut {\n slice: string;\n truncated: boolean;\n nextOffset?: number;\n}\n\nconst isHighSurrogate = (text: string, at: number): boolean => {\n const code = text.charCodeAt(at);\n return code >= 0xd800 && code <= 0xdbff;\n};\n\n/** The text from `offset`, cut at a line boundary within `budget` when it does not fit, never inside a surrogate pair. */\nexport function cutText(text: string, offset: number, budget: number): Cut {\n const from = Math.max(0, Math.floor(offset));\n if (from >= text.length) return { slice: \"\", truncated: false };\n const rest = text.slice(from);\n const room = Math.max(1, budget);\n if (rest.length <= room) return { slice: rest, truncated: false };\n const newline = rest.lastIndexOf(\"\\n\", room - 1);\n let end = newline > 0 ? newline + 1 : room;\n if (end > 1 && isHighSurrogate(rest, end - 1)) end -= 1;\n return { slice: rest.slice(0, end), truncated: true, nextOffset: from + end };\n}\n\n/** Characters a provenance's frontmatter may take in a result before it is replaced by a note. */\nexport const FRONTMATTER_BUDGET = 8_000;\n/** Characters of a catalog entry's description kept in a result. */\nconst ENTRY_DESCRIPTION_CAP = 200;\n\nconst Status = z.enum([\"draft\", \"stable\", \"deprecated\"]);\nconst Trust = z.enum([\"unverified\", \"machine-confirmed\", \"human-reviewed\"]);\nconst Rung = z.enum([\"all-terms\", \"relaxed\"]);\nconst Form = z.enum([\"date\", \"datetime\", \"unparseable\"]);\nconst Verification = z.strictObject({ by: z.string(), at: z.string().optional() });\nconst SourceSchema = z.strictObject({\n resource: z.string(),\n id: z.string().optional(),\n title: z.string().optional(),\n author: z.string().optional(),\n usageCount: z.number().optional(),\n lastModified: z.string().optional(),\n usageWindow: z.strictObject({ from: z.string(), to: z.string() }).optional(),\n});\n\nexport const ProvenanceSchema = z.strictObject({\n path: z.string(),\n title: z.string(),\n type: z.string(),\n status: Status,\n trust: Trust,\n generated: Verification.optional(),\n verified: z.array(Verification),\n latestVerification: Verification.optional(),\n staleAfter: z.strictObject({ raw: z.string(), form: Form, overdue: z.boolean() }).optional(),\n sources: z.array(SourceSchema),\n resource: z.string().optional(),\n replacement: z.string().optional(),\n frontmatter: z.record(z.string(), z.unknown()),\n});\n\nexport const SearchOutputSchema = z.strictObject({\n hits: z.array(\n z.strictObject({\n path: z.string(),\n title: z.string(),\n type: z.string(),\n status: Status,\n trust: Trust,\n recheck: z.strictObject({\n raw: z.string().nullable(),\n form: Form.nullable(),\n overdue: z.boolean(),\n }),\n replacement: z.string().nullable(),\n sources: z.number(),\n resource: z.string().nullable(),\n rung: Rung,\n termsMatched: z.number().nullable(),\n snippet: z.string(),\n citation: z.string(),\n }),\n ),\n summary: z.string(),\n strategy: z.enum([\"all-terms\", \"relaxed\", \"none\"]),\n terms: z.array(z.string()),\n dropped: z.array(z.string()),\n floored: z.array(z.string()),\n considered: z.number(),\n filteredOut: z.strictObject({\n type: z.number(),\n topic: z.number(),\n stale: z.number(),\n unknown: z.number(),\n }),\n topicExhausted: z.boolean(),\n});\nexport type SearchOutput = z.infer<typeof SearchOutputSchema>;\n\nexport const PageOutputSchema = z.strictObject({\n path: z.string(),\n kind: z.enum([\"page\", \"index\", \"log\"]),\n source: z.enum([\"file\", \"generated\"]).optional(),\n provenance: ProvenanceSchema.optional(),\n citation: z.string(),\n notice: z.string(),\n body: z.string(),\n truncated: z.boolean(),\n nextOffset: z.number().optional(),\n});\nexport type PageOutput = z.infer<typeof PageOutputSchema>;\n\nexport const CatalogOutputSchema = z.strictObject({\n folder: z.string(),\n source: z.enum([\"file\", \"generated\"]),\n entries: z.array(\n z.strictObject({ path: z.string(), title: z.string(), description: z.string().nullable() }),\n ),\n notice: z.string(),\n text: z.string(),\n truncated: z.boolean(),\n nextOffset: z.number().optional(),\n});\nexport type CatalogOutput = z.infer<typeof CatalogOutputSchema>;\n\nconst list = <T extends z.ZodTypeAny>(item: T) =>\n z.strictObject({ count: z.number(), first: z.array(item) });\n\nexport const StatusOutputSchema = z.strictObject({\n company: z.string(),\n source: z.string(),\n commit: z.string().nullable(),\n loadedAt: z.string(),\n dev: z.boolean(),\n integrity: z.enum([\"checked\", \"skipped\"]),\n admitted: z.number(),\n excludedByStatus: z.number(),\n attachments: z.number(),\n hidden: z.number(),\n /** Served pages past their recheck date at the time of the call (intent §6). */\n overdue: z.number(),\n refusals: list(z.strictObject({ path: z.string(), rule: z.string(), detail: z.string() })),\n degradations: list(z.strictObject({ path: z.string(), code: z.string(), field: z.string() })),\n unknownTypes: list(z.string()),\n unknownStatuses: list(z.strictObject({ path: z.string(), value: z.string() })),\n brokenLinks: list(z.strictObject({ from: z.string(), raw: z.string() })),\n linksToUnserved: list(z.strictObject({ from: z.string(), raw: z.string(), target: z.string() })),\n foldersWithoutIndex: list(z.string()),\n missingOnDisk: list(z.string()),\n fatal: z.strictObject({ rule: z.string(), path: z.string(), detail: z.string() }).nullable(),\n engine: z.strictObject({\n documents: z.number(),\n notIndexed: z.number(),\n collisions: z.number(),\n encodedFolders: list(z.string()),\n resetOnOpen: z.string().nullable(),\n }),\n lock: z.enum([\"exclusive\", \"private\"]),\n /** The process holding the company lock while this one runs in the private fallback. */\n lockOwner: z\n .strictObject({ pid: z.number(), startedAt: z.string(), alive: z.boolean() })\n .nullable(),\n /** The fetched commit of the published branch and when it was fetched; null for a local source. */\n published: z.strictObject({ commit: z.string(), fetchedAt: z.string() }).nullable(),\n poller: z\n .strictObject({\n intervalMs: z.number(),\n lastTick: z.string().nullable(),\n lastOutcome: z.enum([\"unchanged\", \"refreshed\", \"failed\", \"gone\", \"skipped\"]).nullable(),\n })\n .nullable(),\n lastAttempt: z\n .strictObject({ at: z.string(), outcome: z.enum([\"swapped\", \"fatal\", \"failed\"]) })\n .nullable(),\n /** The last load the loader refused: the commit when there is one, the rule, the path and the detail. */\n lastRefusal: z\n .strictObject({\n commit: z.string().nullable(),\n rule: z.string(),\n path: z.string(),\n detail: z.string(),\n })\n .nullable(),\n refusing: z.string().nullable(),\n});\nexport type StatusOutput = z.infer<typeof StatusOutputSchema>;\n\nexport const NOTICE = `${MARKER} ${DATA_SENTENCE}`;\n\n/** The search response as the tool returns it: every hit with its citation and snippet, the header as the summary. */\nexport function projectSearch(\n response: SearchResponse,\n catalog: Catalog,\n now: Date,\n options: { dev: boolean },\n): SearchOutput {\n void now;\n const hits = response.hits.map((hit) => {\n const page = catalog.pages.get(hit.path);\n const text = snippet(page ?? {}, response.terms);\n return {\n path: hit.path,\n title: hit.title,\n type: hit.type,\n status: hit.status,\n trust: hit.trust,\n recheck: {\n raw: hit.staleAfter ?? null,\n form: page?.staleAfter?.form ?? null,\n overdue: hit.overdue,\n },\n replacement: hit.replacement ?? null,\n sources: hit.sources,\n resource: hit.resource ?? null,\n rung: hit.rung,\n termsMatched: hit.termsMatched ?? null,\n snippet: text,\n citation: hitLine(hit, text, page?.staleAfter?.form),\n };\n });\n return SearchOutputSchema.parse({\n hits,\n summary: searchHeader(response, options.dev),\n strategy: response.strategy,\n terms: response.terms,\n dropped: response.dropped,\n floored: response.floored,\n considered: response.considered,\n filteredOut: response.filteredOut,\n topicExhausted: response.topicExhausted,\n });\n}\n\n/** Room left for a body once the citation, the notice and a truncation tail are counted inside the budget. */\nconst bodyRoom = (budget: number, citation: string): number =>\n Math.max(1, budget - citation.length - NOTICE.length - 80);\n\nexport function projectPage(page: Page, now: Date, offset: number, budget: number): PageOutput {\n const citation = pageHeader(page, now);\n const cut = cutText(page.body, offset, bodyRoom(budget, citation));\n const provenance = provenanceOf(page, now);\n if (JSON.stringify(provenance.frontmatter).length > FRONTMATTER_BUDGET) {\n provenance.frontmatter = {\n omitted: `the frontmatter is over ${FRONTMATTER_BUDGET} characters and is not returned here`,\n };\n }\n const output: PageOutput = {\n path: page.path,\n kind: \"page\",\n provenance,\n citation,\n notice: NOTICE,\n body: cut.slice,\n truncated: cut.truncated,\n };\n if (cut.nextOffset !== undefined) output.nextOffset = cut.nextOffset;\n return PageOutputSchema.parse(output);\n}\n\nexport function projectReserved(\n file: ReservedFile,\n source: \"file\" | \"generated\",\n offset: number,\n budget: number,\n): PageOutput {\n const citation = reservedHeader(file.kind, source, file.folder);\n const cut = cutText(file.body, offset, bodyRoom(budget, citation));\n const output: PageOutput = {\n path: file.path,\n kind: file.kind,\n source,\n citation,\n notice: NOTICE,\n body: cut.slice,\n truncated: cut.truncated,\n };\n if (cut.nextOffset !== undefined) output.nextOffset = cut.nextOffset;\n return PageOutputSchema.parse(output);\n}\n\n/**\n * A folder's catalog: its entries from the catalog's own pages and the index text framed by the marker, the whole\n * result held within the budget. `offset` counts entries first, then characters of the text: a cut result says\n * where to continue, and the continuation carries the remaining entries, then the remaining text. Undefined for\n * an unknown folder.\n */\nexport function projectCatalog(\n catalog: Catalog,\n folder: string,\n offset: number,\n budget: number,\n): CatalogOutput | undefined {\n const entry = catalog.folders.get(folder);\n if (entry === undefined) return undefined;\n const all = [...entry.pages].sort(byCodeUnit).map((path) => {\n const page = catalog.pages.get(path);\n const description = page?.description ?? null;\n return {\n path,\n title: page?.title ?? path,\n description:\n description !== null && description.length > ENTRY_DESCRIPTION_CAP\n ? `${description.slice(0, ENTRY_DESCRIPTION_CAP)}…`\n : description,\n };\n });\n const from = Math.max(0, Math.floor(offset));\n const base: Omit<CatalogOutput, \"entries\" | \"text\" | \"truncated\"> = {\n folder,\n source: entry.indexSource,\n notice: NOTICE,\n };\n const frame =\n JSON.stringify({ ...base, entries: [], text: \"\", truncated: true, nextOffset: 0 }).length + 80;\n const entries: CatalogOutput[\"entries\"] = [];\n let used = frame;\n let index = Math.min(from, all.length);\n while (index < all.length) {\n const item = all[index] as CatalogOutput[\"entries\"][number];\n const cost = JSON.stringify(item).length + 1;\n if (used + cost > budget && entries.length > 0) break;\n entries.push(item);\n used += cost;\n index += 1;\n }\n const fullText = `${MARKER}\\n${entry.index?.body ?? \"\"}`;\n // Text offsets start where the entries end: `all.length` entries consumed, then characters of the text.\n const textFrom = Math.max(0, from - all.length);\n const output: CatalogOutput = {\n ...base,\n entries,\n text: \"\",\n truncated: false,\n };\n if (index < all.length) {\n // The entries alone filled the budget: the text comes with a later continuation.\n output.truncated = true;\n output.nextOffset = index;\n return CatalogOutputSchema.parse(output);\n }\n const cut = cutText(fullText, textFrom, Math.max(1, budget - used));\n output.text = cut.slice;\n output.truncated = cut.truncated;\n if (cut.nextOffset !== undefined) output.nextOffset = all.length + cut.nextOffset;\n return CatalogOutputSchema.parse(output);\n}\n\nconst capped = <T>(items: readonly T[]): { count: number; first: T[] } => ({\n count: items.length,\n first: items.slice(0, STATUS_LIST_CAP),\n});\n\nexport function projectStatus(\n generation: Generation,\n runtime: RuntimeStatus,\n options: ToolOptions,\n now: Date,\n): StatusOutput {\n const r = generation.report;\n let overdue = 0;\n for (const page of generation.catalog.pages.values()) {\n if (page.staleAfter?.at !== undefined && now.getTime() >= page.staleAfter.at.getTime())\n overdue += 1;\n }\n return StatusOutputSchema.parse({\n company: options.company,\n source: options.source,\n commit: r.commit ?? null,\n loadedAt: generation.loadedAt.toISOString(),\n dev: generation.dev,\n integrity: generation.integrity,\n admitted: r.admitted,\n excludedByStatus: r.excludedByStatus,\n attachments: r.attachments,\n hidden: r.hidden,\n overdue,\n refusals: capped(r.refusals.map((x) => ({ path: x.path, rule: x.rule, detail: x.detail }))),\n degradations: capped(\n r.degradations.map((x) => ({ path: x.path, code: x.code, field: x.field })),\n ),\n unknownTypes: capped(r.unknownTypes),\n unknownStatuses: capped(r.unknownStatuses),\n brokenLinks: capped(r.brokenLinks),\n linksToUnserved: capped(r.linksToUnserved),\n foldersWithoutIndex: capped(r.foldersWithoutIndex),\n missingOnDisk: capped(r.missingOnDisk),\n fatal:\n r.fatal === undefined\n ? null\n : { rule: r.fatal.rule, path: r.fatal.path, detail: r.fatal.detail },\n engine: {\n documents: generation.index.documents,\n notIndexed: generation.index.notIndexed.length,\n collisions: generation.index.collisions.length,\n encodedFolders: capped(generation.index.encodedFolders),\n resetOnOpen: runtime.resetOnOpen === undefined ? null : safe(runtime.resetOnOpen),\n },\n lock: runtime.lock,\n lockOwner:\n runtime.lockOwner === undefined || runtime.lockOwner === null\n ? null\n : {\n pid: runtime.lockOwner.pid,\n startedAt: safe(runtime.lockOwner.startedAt),\n alive: runtime.lockOwner.alive,\n },\n published:\n generation.published === undefined\n ? null\n : {\n commit: generation.published.commit,\n fetchedAt: generation.published.fetchedAt.toISOString(),\n },\n poller:\n runtime.poller === undefined || runtime.poller === null\n ? null\n : {\n intervalMs: runtime.poller.intervalMs,\n lastTick: runtime.poller.lastTick?.toISOString() ?? null,\n lastOutcome: runtime.poller.lastOutcome ?? null,\n },\n lastAttempt:\n runtime.lastAttempt === undefined\n ? null\n : { at: runtime.lastAttempt.at.toISOString(), outcome: runtime.lastAttempt.outcome },\n lastRefusal:\n runtime.lastRefusal === undefined\n ? null\n : {\n commit: runtime.lastRefusal.commit ?? null,\n rule: safe(runtime.lastRefusal.rule),\n path: safe(runtime.lastRefusal.path),\n detail: safe(runtime.lastRefusal.detail),\n },\n refusing: runtime.refusing === undefined ? null : refusingText(runtime.refusing),\n });\n}\n\n/** One line for the `status` text block: the counts, the engine, the lock, the last attempt, and the report's lists as counts. */\nexport function statusSummary(out: StatusOutput): string {\n const n = (count: number, word: string): string => `${count} ${word}${count === 1 ? \"\" : \"s\"}`;\n const parts = [\n `${out.company}: ${out.admitted} pages admitted, ${out.excludedByStatus} excluded by status, ${n(out.overdue, \"overdue page\")}, ${n(out.refusals.count, \"refusal\")}, ${n(out.degradations.count, \"degradation\")}`,\n `integrity ${out.integrity}`,\n `${out.engine.documents} documents indexed, ${out.engine.notIndexed} not indexed, ${n(out.engine.collisions, \"collision\")}`,\n out.lock === \"private\"\n ? out.lockOwner === null\n ? \"lock private (holder unreadable)\"\n : `lock private (held by pid ${out.lockOwner.pid} since ${out.lockOwner.startedAt}, ${out.lockOwner.alive ? \"alive\" : \"not alive\"})`\n : `lock ${out.lock}`,\n `loaded ${out.loadedAt}`,\n ...(out.published === null\n ? []\n : [`published ${out.published.commit.slice(0, 12)} fetched ${out.published.fetchedAt}`]),\n ...(out.poller === null\n ? []\n : [\n `poller every ${Math.round(out.poller.intervalMs / 1000)} s${out.poller.lastTick === null ? \", no tick yet\" : `, last tick ${out.poller.lastOutcome ?? \"?\"} at ${out.poller.lastTick}`}`,\n ]),\n ...(out.engine.resetOnOpen === null\n ? []\n : [`engine store rebuilt at open: ${out.engine.resetOnOpen}`]),\n `${n(out.unknownTypes.count, \"unknown type\")}, ${n(out.unknownStatuses.count, \"unknown status\")}, ${n(out.brokenLinks.count, \"broken link\")}, ${n(out.linksToUnserved.count, \"link to an unserved page\")}, ${n(out.foldersWithoutIndex.count, \"folder without an index\")}, ${n(out.missingOnDisk.count, \"manifest entry missing on disk\")}`,\n ];\n if (out.lastAttempt !== null)\n parts.push(`last attempt ${out.lastAttempt.outcome} at ${out.lastAttempt.at}`);\n if (out.lastRefusal !== null)\n parts.push(\n `last refusal ${out.lastRefusal.commit === null ? \"\" : `${out.lastRefusal.commit.slice(0, 12)} `}${out.lastRefusal.rule}${out.lastRefusal.path ? ` (${out.lastRefusal.path})` : \"\"}`,\n );\n if (out.fatal !== null) {\n parts.push(\n `FATAL ${safe(out.fatal.rule)}${out.fatal.path ? ` (${safe(out.fatal.path)})` : \"\"}: ${safe(out.fatal.detail)}`,\n );\n }\n if (out.refusing !== null) parts.push(`refusing: ${safe(out.refusing)}`);\n return parts.join(\"; \");\n}\n"]}
@@ -0,0 +1,37 @@
1
+ /** A page is overdue from its recheck instant: the start of the UTC day for a date, the instant itself for a datetime. */
2
+ export function isOverdue(staleAfter, now) {
3
+ if (staleAfter?.at === undefined)
4
+ return false;
5
+ return now.getTime() >= staleAfter.at.getTime();
6
+ }
7
+ const asWritten = (v) => v.at === undefined ? { by: v.by } : { by: v.by, at: v.at.raw };
8
+ /** The provenance view of a page. Returns copies, so a caller cannot change the catalog through it. */
9
+ export function provenanceOf(page, now) {
10
+ const provenance = {
11
+ path: page.path,
12
+ title: page.title,
13
+ type: page.type,
14
+ status: page.status,
15
+ trust: page.trust,
16
+ verified: page.verified.map(asWritten),
17
+ sources: page.sources.map((s) => ({ ...s })),
18
+ frontmatter: structuredClone(page.frontmatter),
19
+ };
20
+ if (page.generated !== undefined)
21
+ provenance.generated = asWritten(page.generated);
22
+ if (page.latestVerification !== undefined)
23
+ provenance.latestVerification = asWritten(page.latestVerification);
24
+ if (page.staleAfter !== undefined) {
25
+ provenance.staleAfter = {
26
+ raw: page.staleAfter.raw,
27
+ form: page.staleAfter.form,
28
+ overdue: isOverdue(page.staleAfter, now),
29
+ };
30
+ }
31
+ if (page.resource !== undefined)
32
+ provenance.resource = page.resource;
33
+ if (page.replacement !== undefined)
34
+ provenance.replacement = page.replacement;
35
+ return provenance;
36
+ }
37
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/catalog/provenance.ts"],"names":[],"mappings":"AAoBA,0HAA0H;AAC1H,MAAM,UAAU,SAAS,CAAC,UAAkC,EAAE,GAAS;IACrE,IAAI,UAAU,EAAE,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,GAAG,CAAC,OAAO,EAAE,IAAI,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,CAAuC,EAA+B,EAAE,CACzF,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;AAEjE,uGAAuG;AACvG,MAAM,UAAU,YAAY,CAAC,IAAU,EAAE,GAAS;IAChD,MAAM,UAAU,GAAe;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;QACtC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,WAAW,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC;KAC/C,CAAC;IACF,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnF,IAAI,IAAI,CAAC,kBAAkB,KAAK,SAAS;QACvC,UAAU,CAAC,kBAAkB,GAAG,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACrE,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,UAAU,CAAC,UAAU,GAAG;YACtB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG;YACxB,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;YAC1B,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC;SACzC,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IACrE,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IAC9E,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import type { Page, PagePath, Source, StaleAfter, Status, Trust } from \"../bundle/model.js\";\n\nexport interface Provenance {\n path: PagePath;\n title: string;\n type: string;\n status: Status;\n trust: Trust;\n generated?: { by: string; at?: string };\n verified: Array<{ by: string; at?: string }>;\n /** The verification with the latest instant, the one \"how recently\" means. */\n latestVerification?: { by: string; at?: string };\n staleAfter?: { raw: string; form: StaleAfter[\"form\"]; overdue: boolean };\n sources: Source[];\n resource?: string;\n replacement?: PagePath;\n /** A copy of the page's frontmatter in full, so nothing the page carries is lost. */\n frontmatter: Record<string, unknown>;\n}\n\n/** A page is overdue from its recheck instant: the start of the UTC day for a date, the instant itself for a datetime. */\nexport function isOverdue(staleAfter: StaleAfter | undefined, now: Date): boolean {\n if (staleAfter?.at === undefined) return false;\n return now.getTime() >= staleAfter.at.getTime();\n}\n\nconst asWritten = (v: { by: string; at?: { raw: string } }): { by: string; at?: string } =>\n v.at === undefined ? { by: v.by } : { by: v.by, at: v.at.raw };\n\n/** The provenance view of a page. Returns copies, so a caller cannot change the catalog through it. */\nexport function provenanceOf(page: Page, now: Date): Provenance {\n const provenance: Provenance = {\n path: page.path,\n title: page.title,\n type: page.type,\n status: page.status,\n trust: page.trust,\n verified: page.verified.map(asWritten),\n sources: page.sources.map((s) => ({ ...s })),\n frontmatter: structuredClone(page.frontmatter),\n };\n if (page.generated !== undefined) provenance.generated = asWritten(page.generated);\n if (page.latestVerification !== undefined)\n provenance.latestVerification = asWritten(page.latestVerification);\n if (page.staleAfter !== undefined) {\n provenance.staleAfter = {\n raw: page.staleAfter.raw,\n form: page.staleAfter.form,\n overdue: isOverdue(page.staleAfter, now),\n };\n }\n if (page.resource !== undefined) provenance.resource = page.resource;\n if (page.replacement !== undefined) provenance.replacement = page.replacement;\n return provenance;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/catalog/runtime.ts"],"names":[],"mappings":"","sourcesContent":["import type { Report } from \"../bundle/model.js\";\nimport type { Engine, IndexResult } from \"../search/engine.js\";\nimport type { Catalog } from \"./model.js\";\n\n/** One loaded and indexed state of the bundle: what every tool call reads, whole, for its duration. */\nexport interface PublishedInfo {\n /** The fetched commit of the published branch. */\n commit: string;\n /** When that fetch succeeded. */\n fetchedAt: Date;\n}\n\nexport interface LockOwnerStatus {\n pid: number;\n startedAt: string;\n /** Whether that process answers the signal-zero test when `status` runs. */\n alive: boolean;\n}\n\nexport type PollerOutcome = \"unchanged\" | \"refreshed\" | \"failed\" | \"gone\" | \"skipped\";\n\nexport interface PollerStatus {\n intervalMs: number;\n lastTick?: Date;\n lastOutcome?: PollerOutcome;\n}\n\nexport interface Generation {\n /** For a repository source: the commit this generation came from, and when it was fetched. */\n published?: PublishedInfo;\n catalog: Catalog;\n report: Report;\n index: IndexResult;\n loadedAt: Date;\n dev: boolean;\n integrity: \"checked\" | \"skipped\";\n}\n\nexport type RefreshOutcome =\n | { outcome: \"swapped\"; generation: Generation }\n /** The reloaded bundle was refused; the previous generation stays. */\n | { outcome: \"fatal\"; report: Report }\n /** Something threw; the previous generation stays. The index is re-aligned with it when that is possible; when it is not, the runtime refuses until a refresh succeeds. */\n | { outcome: \"failed\"; error: string };\n\nexport interface LastRefusal {\n /** The fetched commit, for a repository source. */\n commit?: string;\n rule: string;\n path: string;\n detail: string;\n}\n\nexport interface RuntimeStatus {\n lock: \"exclusive\" | \"private\";\n /** Whether a generation is published; false before the first load lands or while it keeps failing. */\n loaded: boolean;\n /** Whether the published generation is itself a refusal (D39), which a poller tick keeps retrying. */\n fatal?: boolean;\n /** The last commit or load the loader refused, and why; a fixed publish clears it. */\n lastRefusal?: LastRefusal;\n lastAttempt?: { at: Date; outcome: \"swapped\" | \"fatal\" | \"failed\" };\n /** The fixed sentence every tool answers with while the server cannot serve. */\n refusing?: string;\n /** Why the engine rebuilt its store at open, when it did (D48). */\n resetOnOpen?: string;\n /** The process holding the company lock, when this one runs in the private fallback; null when not applicable. */\n lockOwner?: LockOwnerStatus | null;\n /** The poller's state, for a repository source. */\n poller?: PollerStatus | null;\n}\n\n/** Plain values the tools need from the configuration, so the adapter never imports the configuration module. */\nexport interface ToolOptions {\n company: string;\n /** The source as written in the configuration, never a cache path. */\n source: string;\n dev: boolean;\n limitDefault: number;\n resultBudget: number;\n}\n\n/** The runtime as the MCP adapter sees it. The composition layer implements it.\n * Never call `refresh()` from inside a `lease` callback: a swap waits for the active leases and the lease would\n * wait for the swap.\n */\nexport interface Runtime {\n /** Begins the first load if it has not begun; idempotent. The adapter calls it when a connection completes `initialize`. */\n start?(): void;\n /** Resolves when the first generation is published; rejects when the server is refusing. */\n ready(): Promise<Generation>;\n /** Runs `fn` against the current generation and its engine, holding them for the call's duration. */\n lease<T>(fn: (generation: Generation, engine: Engine) => Promise<T>): Promise<T>;\n refresh(): Promise<RefreshOutcome>;\n status(): RuntimeStatus;\n shutdown(): Promise<void>;\n}\n"]}