@dotit/core 1.0.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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +229 -0
  3. package/dist/aliases.d.ts +1 -0
  4. package/dist/aliases.js +8 -0
  5. package/dist/ask.d.ts +7 -0
  6. package/dist/ask.js +55 -0
  7. package/dist/browser.d.ts +12 -0
  8. package/dist/browser.js +32 -0
  9. package/dist/diff.d.ts +17 -0
  10. package/dist/diff.js +179 -0
  11. package/dist/document-css.d.ts +1 -0
  12. package/dist/document-css.js +290 -0
  13. package/dist/executor.d.ts +40 -0
  14. package/dist/executor.js +501 -0
  15. package/dist/history.d.ts +10 -0
  16. package/dist/history.js +297 -0
  17. package/dist/html-to-it.d.ts +1 -0
  18. package/dist/html-to-it.js +288 -0
  19. package/dist/index-builder.d.ts +62 -0
  20. package/dist/index-builder.js +228 -0
  21. package/dist/index.d.ts +39 -0
  22. package/dist/index.js +94 -0
  23. package/dist/language-registry.d.ts +39 -0
  24. package/dist/language-registry.js +530 -0
  25. package/dist/markdown.d.ts +1 -0
  26. package/dist/markdown.js +123 -0
  27. package/dist/merge.d.ts +6 -0
  28. package/dist/merge.js +255 -0
  29. package/dist/parser.d.ts +29 -0
  30. package/dist/parser.js +1562 -0
  31. package/dist/query.d.ts +32 -0
  32. package/dist/query.js +293 -0
  33. package/dist/renderer.d.ts +16 -0
  34. package/dist/renderer.js +1286 -0
  35. package/dist/schema.d.ts +47 -0
  36. package/dist/schema.js +574 -0
  37. package/dist/source.d.ts +3 -0
  38. package/dist/source.js +223 -0
  39. package/dist/theme.d.ts +49 -0
  40. package/dist/theme.js +113 -0
  41. package/dist/themes/corporate.json +86 -0
  42. package/dist/themes/dark.json +64 -0
  43. package/dist/themes/editorial.json +54 -0
  44. package/dist/themes/legal.json +57 -0
  45. package/dist/themes/minimal.json +50 -0
  46. package/dist/themes/print.json +54 -0
  47. package/dist/themes/technical.json +59 -0
  48. package/dist/themes/warm.json +53 -0
  49. package/dist/trust.d.ts +66 -0
  50. package/dist/trust.js +200 -0
  51. package/dist/types.d.ts +234 -0
  52. package/dist/types.js +19 -0
  53. package/dist/utils.d.ts +2 -0
  54. package/dist/utils.js +13 -0
  55. package/dist/validate.d.ts +13 -0
  56. package/dist/validate.js +711 -0
  57. package/dist/workflow.d.ts +18 -0
  58. package/dist/workflow.js +160 -0
  59. package/package.json +51 -0
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseHistorySection = parseHistorySection;
4
+ exports.updateHistory = updateHistory;
5
+ const trust_1 = require("./trust");
6
+ const parser_1 = require("./parser");
7
+ function parseHistorySection(raw) {
8
+ const lines = raw
9
+ .split("\n")
10
+ .filter((l) => l.trim() && !l.trim().startsWith("//"));
11
+ const registry = [];
12
+ const revisions = [];
13
+ let registryIntact = true;
14
+ for (const line of lines) {
15
+ const trimmed = line.trim();
16
+ if (trimmed.startsWith("revision:")) {
17
+ revisions.push(parseRevisionLine(trimmed));
18
+ }
19
+ else if (/^[a-z0-9]{5}\s*\|/.test(trimmed)) {
20
+ const parts = trimmed.split("|").map((p) => p.trim());
21
+ if (parts.length >= 4) {
22
+ registry.push({
23
+ id: parts[0],
24
+ blockType: parts[1],
25
+ section: parts[2],
26
+ fingerprint: parts[3],
27
+ dead: parts[4] === "dead" || undefined,
28
+ });
29
+ }
30
+ else {
31
+ registryIntact = false;
32
+ }
33
+ }
34
+ }
35
+ return { registry, revisions, registryIntact };
36
+ }
37
+ function parseRevisionLine(line) {
38
+ const content = line.replace(/^revision:\s*\|?\s*/, "");
39
+ const props = {};
40
+ const segments = content.split(" | ");
41
+ for (const seg of segments) {
42
+ const colonIdx = seg.indexOf(":");
43
+ if (colonIdx > -1) {
44
+ props[seg.slice(0, colonIdx).trim()] = seg.slice(colonIdx + 1).trim();
45
+ }
46
+ }
47
+ return {
48
+ version: props.version || "",
49
+ at: props.at || "",
50
+ by: props.by || "",
51
+ change: (props.change || "added"),
52
+ id: props.id || "",
53
+ block: props.block || "",
54
+ section: props.section,
55
+ was: props.was,
56
+ now: props.now,
57
+ wasSection: props["was-section"],
58
+ nowSection: props["now-section"],
59
+ };
60
+ }
61
+ function updateHistory(previousSource, currentSource, options) {
62
+ const prevDoc = (0, parser_1.parseIntentText)(previousSource);
63
+ const currDoc = (0, parser_1.parseIntentText)(currentSource);
64
+ if (prevDoc.metadata?.freeze) {
65
+ throw new Error("Document is sealed and frozen. Cannot save modifications. " +
66
+ "Use --force to override (this will void the seal).");
67
+ }
68
+ const prevBoundaryPos = (0, trust_1.findHistoryBoundaryInSource)(previousSource);
69
+ let historyRaw = prevBoundaryPos === -1 ? "" : previousSource.slice(prevBoundaryPos);
70
+ const currBoundaryPos = (0, trust_1.findHistoryBoundaryInSource)(currentSource);
71
+ const docContent = currBoundaryPos === -1
72
+ ? currentSource
73
+ : currentSource.slice(0, currBoundaryPos);
74
+ const { registry, revisions, registryIntact } = historyRaw === ""
75
+ ? {
76
+ registry: [],
77
+ revisions: [],
78
+ registryIntact: true,
79
+ }
80
+ : parseHistorySection(historyRaw);
81
+ if (!registryIntact) {
82
+ revisions.push({
83
+ version: "warn",
84
+ at: new Date().toISOString(),
85
+ by: "system",
86
+ change: "modified",
87
+ id: "system",
88
+ block: "system",
89
+ now: "Registry integrity broken — tracking reset from this point",
90
+ });
91
+ }
92
+ const currentVersion = currDoc.metadata?.tracking?.version ||
93
+ (revisions.length > 0 ? revisions[revisions.length - 1].version : "1.0");
94
+ const prevSnapshots = buildSnapshots(prevDoc.blocks, registry);
95
+ const currentBlockInfos = buildBlockInfos(currDoc.blocks);
96
+ const matchMap = (0, trust_1.matchBlocksToRegistry)(currentBlockInfos, registry);
97
+ const currSnapshots = [];
98
+ let currSection = "root";
99
+ function walkCurr(blockList) {
100
+ for (const b of blockList) {
101
+ if (b.type === "section")
102
+ currSection = b.content;
103
+ if (b.type !== "title" && b.type !== "summary") {
104
+ const flatIdx = currentBlockInfos.findIndex((info) => info.type === b.type &&
105
+ info.content === b.content &&
106
+ info.section === currSection);
107
+ const existingId = flatIdx !== -1 ? matchMap.get(flatIdx) : undefined;
108
+ const id = existingId || (0, trust_1.generateBlockId)();
109
+ currSnapshots.push({
110
+ id,
111
+ type: b.type,
112
+ content: b.content,
113
+ section: currSection,
114
+ properties: Object.fromEntries(Object.entries(b.properties || {}).map(([k, v]) => [k, String(v)])),
115
+ });
116
+ }
117
+ if (b.children)
118
+ walkCurr(b.children);
119
+ }
120
+ }
121
+ walkCurr(currDoc.blocks);
122
+ const diff = (0, trust_1.computeTrustDiff)(prevSnapshots, currSnapshots);
123
+ const newRevisions = [];
124
+ let newVersion = currentVersion;
125
+ const hasSignificantChanges = diff.added.some((b) => b.type === "section") ||
126
+ diff.removed.some((b) => b.type === "section");
127
+ if (diff.added.length ||
128
+ diff.removed.length ||
129
+ diff.modified.length ||
130
+ diff.moved.length) {
131
+ newVersion = (0, trust_1.incrementVersion)(currentVersion, hasSignificantChanges ? "major" : "minor");
132
+ }
133
+ const at = new Date().toISOString();
134
+ for (const block of diff.added) {
135
+ newRevisions.push({
136
+ version: newVersion,
137
+ at,
138
+ by: options.by,
139
+ change: "added",
140
+ id: block.id,
141
+ block: block.type,
142
+ section: block.section,
143
+ now: block.content,
144
+ });
145
+ }
146
+ for (const block of diff.removed) {
147
+ newRevisions.push({
148
+ version: newVersion,
149
+ at,
150
+ by: options.by,
151
+ change: "removed",
152
+ id: block.id,
153
+ block: block.type,
154
+ section: block.section,
155
+ was: block.content,
156
+ });
157
+ }
158
+ for (const { id, was, now } of diff.modified) {
159
+ newRevisions.push({
160
+ version: newVersion,
161
+ at,
162
+ by: options.by,
163
+ change: "modified",
164
+ id,
165
+ block: now.type,
166
+ section: now.section,
167
+ was: was.content,
168
+ now: now.content,
169
+ });
170
+ }
171
+ for (const { id, wasSection, nowSection, block } of diff.moved) {
172
+ newRevisions.push({
173
+ version: newVersion,
174
+ at,
175
+ by: options.by,
176
+ change: "moved",
177
+ id,
178
+ block: block.type,
179
+ wasSection,
180
+ nowSection,
181
+ });
182
+ }
183
+ const updatedRegistry = buildUpdatedRegistry(registry, currSnapshots, diff);
184
+ const newHistorySection = buildHistorySection(updatedRegistry, [
185
+ ...revisions,
186
+ ...newRevisions,
187
+ ]);
188
+ const cleanDoc = docContent.endsWith("\n") ? docContent : docContent + "\n";
189
+ return cleanDoc + newHistorySection;
190
+ }
191
+ function buildHistorySection(registry, revisions) {
192
+ const lines = [
193
+ "history:",
194
+ "",
195
+ "// registry",
196
+ ...registry.map((r) => `${r.id} | ${r.blockType} | ${r.section} | ${r.fingerprint}${r.dead ? " | dead" : ""}`),
197
+ "",
198
+ "// revisions",
199
+ ...revisions.map((r) => revisionToLine(r)),
200
+ ];
201
+ return lines.join("\n") + "\n";
202
+ }
203
+ function revisionToLine(r) {
204
+ const parts = [
205
+ "revision:",
206
+ `version: ${r.version}`,
207
+ `at: ${r.at}`,
208
+ `by: ${r.by}`,
209
+ `change: ${r.change}`,
210
+ `id: ${r.id}`,
211
+ `block: ${r.block}`,
212
+ ];
213
+ if (r.section)
214
+ parts.push(`section: ${r.section}`);
215
+ if (r.was)
216
+ parts.push(`was: ${r.was}`);
217
+ if (r.now)
218
+ parts.push(`now: ${r.now}`);
219
+ if (r.wasSection)
220
+ parts.push(`was-section: ${r.wasSection}`);
221
+ if (r.nowSection)
222
+ parts.push(`now-section: ${r.nowSection}`);
223
+ return parts.join(" | ");
224
+ }
225
+ function buildBlockInfos(blocks) {
226
+ let currentSection = "root";
227
+ const result = [];
228
+ function walk(blockList) {
229
+ for (const b of blockList) {
230
+ if (b.type === "section")
231
+ currentSection = b.content;
232
+ if (b.type !== "title" && b.type !== "summary") {
233
+ result.push({
234
+ type: b.type,
235
+ content: b.content,
236
+ section: currentSection,
237
+ });
238
+ }
239
+ if (b.children)
240
+ walk(b.children);
241
+ }
242
+ }
243
+ walk(blocks);
244
+ return result;
245
+ }
246
+ function buildSnapshots(blocks, registry) {
247
+ let currentSection = "root";
248
+ const result = [];
249
+ function walk(blockList) {
250
+ for (const b of blockList) {
251
+ if (b.type === "section")
252
+ currentSection = b.content;
253
+ if (b.type !== "title" && b.type !== "summary") {
254
+ const fp = (0, trust_1.blockFingerprint)(b.content);
255
+ const reg = registry.find((r) => r.fingerprint === fp && r.blockType === b.type && !r.dead);
256
+ result.push({
257
+ id: reg?.id || `unknown-${result.length}`,
258
+ type: b.type,
259
+ content: b.content,
260
+ section: currentSection,
261
+ properties: Object.fromEntries(Object.entries(b.properties || {}).map(([k, v]) => [k, String(v)])),
262
+ });
263
+ }
264
+ if (b.children)
265
+ walk(b.children);
266
+ }
267
+ }
268
+ walk(blocks);
269
+ return result;
270
+ }
271
+ function buildUpdatedRegistry(existing, current, diff) {
272
+ const result = existing.map((r) => ({ ...r }));
273
+ const currentIds = new Set(current.map((b) => b.id));
274
+ for (const r of result) {
275
+ if (!currentIds.has(r.id) && !r.dead) {
276
+ r.dead = true;
277
+ }
278
+ }
279
+ for (const block of diff.added) {
280
+ if (!result.find((r) => r.id === block.id)) {
281
+ result.push({
282
+ id: block.id,
283
+ blockType: block.type,
284
+ section: block.section,
285
+ fingerprint: (0, trust_1.blockFingerprint)(block.content),
286
+ });
287
+ }
288
+ }
289
+ for (const { id, now } of diff.modified) {
290
+ const entry = result.find((r) => r.id === id);
291
+ if (entry) {
292
+ entry.fingerprint = (0, trust_1.blockFingerprint)(now.content);
293
+ entry.section = now.section;
294
+ }
295
+ }
296
+ return result;
297
+ }
@@ -0,0 +1 @@
1
+ export declare function convertHtmlToIntentText(html: string): string;
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertHtmlToIntentText = convertHtmlToIntentText;
4
+ const STRIP_TAGS = new Set([
5
+ "script",
6
+ "style",
7
+ "meta",
8
+ "link",
9
+ "noscript",
10
+ "head",
11
+ ]);
12
+ const TRANSPARENT_TAGS = new Set([
13
+ "div",
14
+ "span",
15
+ "main",
16
+ "article",
17
+ "header",
18
+ "footer",
19
+ "nav",
20
+ "aside",
21
+ "section",
22
+ "figure",
23
+ "figcaption",
24
+ "details",
25
+ "summary",
26
+ "body",
27
+ "html",
28
+ ]);
29
+ function parseHtml(html) {
30
+ const { parse } = require("node-html-parser");
31
+ return parse(html, { comment: false });
32
+ }
33
+ function convertHtmlToIntentText(html) {
34
+ if (typeof html !== "string" || html.length === 0)
35
+ return "";
36
+ const root = parseHtml(html);
37
+ const lines = [];
38
+ processChildren(root, lines);
39
+ const cleaned = [];
40
+ let blankCount = 0;
41
+ for (const line of lines) {
42
+ if (line === "") {
43
+ blankCount++;
44
+ if (blankCount <= 1)
45
+ cleaned.push("");
46
+ }
47
+ else {
48
+ blankCount = 0;
49
+ cleaned.push(line);
50
+ }
51
+ }
52
+ while (cleaned.length > 0 && cleaned[cleaned.length - 1] === "") {
53
+ cleaned.pop();
54
+ }
55
+ return cleaned.join("\n");
56
+ }
57
+ function processChildren(node, lines) {
58
+ for (const child of node.childNodes) {
59
+ processNode(child, lines);
60
+ }
61
+ }
62
+ function processNode(node, lines) {
63
+ if (node.nodeType === 3) {
64
+ const text = (node.text || "").trim();
65
+ if (text) {
66
+ lines.push(`note: ${text}`);
67
+ }
68
+ return;
69
+ }
70
+ if (node.nodeType !== 1)
71
+ return;
72
+ const tag = (node.tagName || "").toLowerCase();
73
+ if (STRIP_TAGS.has(tag))
74
+ return;
75
+ if (TRANSPARENT_TAGS.has(tag)) {
76
+ processChildren(node, lines);
77
+ return;
78
+ }
79
+ switch (tag) {
80
+ case "h1":
81
+ lines.push(`title: ${getInlineText(node)}`);
82
+ lines.push("");
83
+ break;
84
+ case "h2":
85
+ lines.push(`section: ${getInlineText(node)}`);
86
+ lines.push("");
87
+ break;
88
+ case "h3":
89
+ case "h4":
90
+ case "h5":
91
+ case "h6":
92
+ lines.push(`sub: ${getInlineText(node)}`);
93
+ lines.push("");
94
+ break;
95
+ case "p":
96
+ handleParagraph(node, lines);
97
+ lines.push("");
98
+ break;
99
+ case "ul":
100
+ processListItems(node, lines, "unordered");
101
+ lines.push("");
102
+ break;
103
+ case "ol":
104
+ processListItems(node, lines, "ordered");
105
+ lines.push("");
106
+ break;
107
+ case "blockquote":
108
+ lines.push(`quote: ${getInlineText(node)}`);
109
+ lines.push("");
110
+ break;
111
+ case "pre":
112
+ processCodeBlock(node, lines);
113
+ lines.push("");
114
+ break;
115
+ case "table":
116
+ processTable(node, lines);
117
+ lines.push("");
118
+ break;
119
+ case "img":
120
+ processImage(node, lines);
121
+ break;
122
+ case "a":
123
+ processBlockLink(node, lines);
124
+ break;
125
+ case "hr":
126
+ lines.push("---");
127
+ lines.push("");
128
+ break;
129
+ case "br":
130
+ break;
131
+ default:
132
+ processChildren(node, lines);
133
+ break;
134
+ }
135
+ }
136
+ function handleParagraph(node, lines) {
137
+ const children = node.childNodes.filter((c) => c.nodeType === 1 || (c.nodeType === 3 && (c.text || "").trim()));
138
+ if (children.length === 1 &&
139
+ children[0].nodeType === 1 &&
140
+ (children[0].tagName || "").toLowerCase() === "img") {
141
+ processImage(children[0], lines);
142
+ return;
143
+ }
144
+ if (children.length === 1 &&
145
+ children[0].nodeType === 1 &&
146
+ (children[0].tagName || "").toLowerCase() === "a") {
147
+ processBlockLink(children[0], lines);
148
+ return;
149
+ }
150
+ const text = getInlineText(node);
151
+ if (text) {
152
+ lines.push(`note: ${text}`);
153
+ }
154
+ }
155
+ function getInlineText(node) {
156
+ if (node.nodeType === 3)
157
+ return node.text || "";
158
+ if (node.nodeType !== 1)
159
+ return "";
160
+ const tag = (node.tagName || "").toLowerCase();
161
+ const inner = node.childNodes.map(getInlineText).join("");
162
+ switch (tag) {
163
+ case "strong":
164
+ case "b":
165
+ return `*${inner.trim()}*`;
166
+ case "em":
167
+ case "i":
168
+ return `_${inner.trim()}_`;
169
+ case "del":
170
+ case "s":
171
+ case "strike":
172
+ return `~${inner.trim()}~`;
173
+ case "code":
174
+ return `\`\`\`${inner}\`\`\``;
175
+ case "a": {
176
+ const href = node.getAttribute("href") || "";
177
+ if (!href || href.startsWith("javascript:") || href.startsWith("data:")) {
178
+ return inner;
179
+ }
180
+ return `[${inner.trim()}](${href})`;
181
+ }
182
+ case "br":
183
+ return "\n";
184
+ case "img": {
185
+ const alt = node.getAttribute("alt") || "";
186
+ return alt;
187
+ }
188
+ default:
189
+ return inner;
190
+ }
191
+ }
192
+ function processListItems(node, lines, type) {
193
+ let index = 1;
194
+ for (const child of node.childNodes) {
195
+ if (child.nodeType !== 1)
196
+ continue;
197
+ const childTag = (child.tagName || "").toLowerCase();
198
+ if (childTag !== "li")
199
+ continue;
200
+ const checkbox = child.querySelectorAll("input");
201
+ const cb = checkbox.length > 0 &&
202
+ (checkbox[0].getAttribute("type") || "").toLowerCase() === "checkbox"
203
+ ? checkbox[0]
204
+ : null;
205
+ if (cb) {
206
+ const checked = cb.getAttribute("checked") !== undefined;
207
+ const text = getInlineText(child)
208
+ .replace(/^\s*\[.\]\s*/, "")
209
+ .trim();
210
+ if (checked) {
211
+ lines.push(`done: ${text}`);
212
+ }
213
+ else {
214
+ lines.push(`task: ${text}`);
215
+ }
216
+ }
217
+ else {
218
+ const text = getInlineText(child).trim();
219
+ if (type === "ordered") {
220
+ lines.push(`${index}. ${text}`);
221
+ index++;
222
+ }
223
+ else {
224
+ lines.push(`- ${text}`);
225
+ }
226
+ }
227
+ }
228
+ }
229
+ function processCodeBlock(node, lines) {
230
+ let content = node.text || "";
231
+ content = content.replace(/^<code[^>]*>/i, "").replace(/<\/code>$/i, "");
232
+ lines.push("```");
233
+ const codeLines = content.split("\n");
234
+ if (codeLines.length > 0 && codeLines[codeLines.length - 1].trim() === "") {
235
+ codeLines.pop();
236
+ }
237
+ if (codeLines.length > 0 && codeLines[0].trim() === "") {
238
+ codeLines.shift();
239
+ }
240
+ lines.push(...codeLines);
241
+ lines.push("```");
242
+ }
243
+ function processTable(node, lines) {
244
+ const rows = node.querySelectorAll("tr");
245
+ let isFirstRow = true;
246
+ for (const row of rows) {
247
+ const thCells = row.querySelectorAll("th");
248
+ const tdCells = row.querySelectorAll("td");
249
+ const cells = thCells.length > 0 ? thCells : tdCells;
250
+ const values = cells.map((c) => getInlineText(c).trim());
251
+ if (values.length === 0)
252
+ continue;
253
+ if (isFirstRow && thCells.length > 0) {
254
+ lines.push(`| ${values.join(" | ")} |`);
255
+ isFirstRow = false;
256
+ }
257
+ else if (isFirstRow) {
258
+ lines.push(`| ${values.join(" | ")} |`);
259
+ isFirstRow = false;
260
+ }
261
+ else {
262
+ lines.push(`| ${values.join(" | ")} |`);
263
+ }
264
+ }
265
+ }
266
+ function processImage(node, lines) {
267
+ const alt = node.getAttribute("alt") || "";
268
+ const src = node.getAttribute("src") || "";
269
+ const caption = node.getAttribute("title") || "";
270
+ if (!src)
271
+ return;
272
+ let line = `image: ${alt || "image"} | src: ${src}`;
273
+ if (caption) {
274
+ line += ` | caption: ${caption}`;
275
+ }
276
+ lines.push(line);
277
+ }
278
+ function processBlockLink(node, lines) {
279
+ const href = node.getAttribute("href") || "";
280
+ const text = getInlineText(node).trim();
281
+ if (!href || href.startsWith("javascript:") || href.startsWith("data:")) {
282
+ if (text)
283
+ lines.push(`note: ${text}`);
284
+ return;
285
+ }
286
+ const cleanText = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
287
+ lines.push(`link: ${cleanText || href} | to: ${href}`);
288
+ }
@@ -0,0 +1,62 @@
1
+ import { IntentDocument } from "./types";
2
+ export interface IndexFileEntry {
3
+ hash: string;
4
+ modified_at: string;
5
+ metadata: {
6
+ title?: string;
7
+ type?: string;
8
+ domain?: string;
9
+ track?: Record<string, string>;
10
+ [key: string]: unknown;
11
+ };
12
+ blocks: IndexBlockEntry[];
13
+ }
14
+ export interface IndexBlockEntry {
15
+ type: string;
16
+ content: string;
17
+ section?: string;
18
+ properties: Record<string, string | number>;
19
+ }
20
+ export interface ItIndex {
21
+ version: "1";
22
+ scope: "shallow";
23
+ folder: string;
24
+ built_at: string;
25
+ core_version: string;
26
+ files: Record<string, IndexFileEntry>;
27
+ }
28
+ export interface ComposedResult {
29
+ file: string;
30
+ block: IndexBlockEntry;
31
+ }
32
+ export declare function buildIndexEntry(doc: IntentDocument, source: string, modifiedAt: string): IndexFileEntry;
33
+ export declare function buildShallowIndex(folder: string, files: Record<string, {
34
+ source: string;
35
+ doc: IntentDocument;
36
+ modifiedAt: string;
37
+ }>, coreVersion: string): ItIndex;
38
+ export declare function checkStaleness(existingIndex: ItIndex, currentFiles: Record<string, {
39
+ source: string;
40
+ modifiedAt: string;
41
+ }>): {
42
+ stale: string[];
43
+ added: string[];
44
+ removed: string[];
45
+ unchanged: string[];
46
+ };
47
+ export declare function updateIndex(existingIndex: ItIndex, updates: Record<string, {
48
+ source: string;
49
+ doc: IntentDocument;
50
+ modifiedAt: string;
51
+ }>, removedFiles: string[]): ItIndex;
52
+ export declare function composeIndexes(indexes: ItIndex[], rootFolder: string): ComposedResult[];
53
+ export declare function queryComposed(results: ComposedResult[], filters: {
54
+ type?: string;
55
+ content?: string;
56
+ by?: string;
57
+ status?: string;
58
+ section?: string;
59
+ }): ComposedResult[];
60
+ export declare function formatTable(results: ComposedResult[]): string;
61
+ export declare function formatJSON(results: ComposedResult[]): string;
62
+ export declare function formatCSV(results: ComposedResult[]): string;