@wrenautomation/knowledge 0.0.0-stage → 0.59.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.
@@ -0,0 +1,247 @@
1
+ /**
2
+ * The index: what a repo holds at one commit, in Postgres (or PGlite). Never the truth: rebuilt from
3
+ * git at will. A sync applies the diff from the last indexed commit to HEAD and the new head in one
4
+ * transaction, so a replay is safe and a crash leaves the old state. Rows carry `repo`: one index can
5
+ * hold many repos (a client each) for an admin view.
6
+ */
7
+ import { and, desc, eq, ilike, inArray, or, sql } from "drizzle-orm";
8
+ import { integer, jsonb, pgTable, primaryKey, text } from "drizzle-orm/pg-core";
9
+ import { diff, head, isAncestor, tryGit } from "./git.js";
10
+ import { edgesOf } from "./records.js";
11
+ import { loadAt, RECORD_DIRS, readPathsAt } from "./repo.js";
12
+ // bump when a table changes: the index drops and rebuilds itself from git
13
+ const SCHEMA = "2";
14
+ export const metaT = pgTable("knowledge_meta", { repo: text().notNull(), key: text().notNull(), value: text().notNull() }, (t) => [primaryKey({ columns: [t.repo, t.key] })]);
15
+ export const recordsT = pgTable("knowledge_records", {
16
+ repo: text().notNull(),
17
+ id: text().notNull(),
18
+ type: text().notNull(),
19
+ title: text().notNull(),
20
+ status: text().notNull(),
21
+ version: integer().notNull(),
22
+ by: text().notNull(),
23
+ why: text().notNull(),
24
+ path: text().notNull(),
25
+ topic: text(),
26
+ source: text(),
27
+ body: text().notNull(),
28
+ data: jsonb().notNull(),
29
+ created: text().notNull(),
30
+ updated: text().notNull(),
31
+ }, (t) => [primaryKey({ columns: [t.repo, t.id] })]);
32
+ export const citesT = pgTable("knowledge_cites", { repo: text().notNull(), from: text().notNull(), to: text().notNull() }, (t) => [primaryKey({ columns: [t.repo, t.from, t.to] })]);
33
+ const DDL = [
34
+ `create table if not exists knowledge_meta (repo text not null, key text not null, value text not null, primary key (repo, key))`,
35
+ `create table if not exists knowledge_records (repo text not null, id text not null, type text not null, title text not null, status text not null, version integer not null, "by" text not null, why text not null, path text not null, topic text, source text, body text not null, data jsonb not null, created text not null, updated text not null, primary key (repo, id))`,
36
+ `create index if not exists knowledge_records_path on knowledge_records (repo, path)`,
37
+ `create table if not exists knowledge_cites (repo text not null, "from" text not null, "to" text not null, primary key (repo, "from", "to"))`,
38
+ `create index if not exists knowledge_cites_to on knowledge_cites (repo, "to")`,
39
+ ];
40
+ const DROP = [
41
+ "drop table if exists knowledge_cites",
42
+ "drop table if exists knowledge_records",
43
+ "drop table if exists knowledge_meta",
44
+ ];
45
+ export class RecordIndex {
46
+ db;
47
+ close_;
48
+ ready = false;
49
+ constructor(db, close_ = async () => { }) {
50
+ this.db = db;
51
+ this.close_ = close_;
52
+ }
53
+ close() {
54
+ return this.close_();
55
+ }
56
+ /** Create the tables; a schema change drops and rebuilds them. */
57
+ async init() {
58
+ if (this.ready)
59
+ return;
60
+ for (const q of DDL)
61
+ await this.db.execute(sql.raw(q));
62
+ const [v] = await this.db
63
+ .select()
64
+ .from(metaT)
65
+ .where(and(eq(metaT.repo, "*"), eq(metaT.key, "schema")));
66
+ if (v?.value !== SCHEMA) {
67
+ for (const q of DROP)
68
+ await this.db.execute(sql.raw(q));
69
+ for (const q of DDL)
70
+ await this.db.execute(sql.raw(q));
71
+ await this.db.insert(metaT).values({ repo: "*", key: "schema", value: SCHEMA });
72
+ }
73
+ this.ready = true;
74
+ }
75
+ async indexedHead(repo) {
76
+ await this.init();
77
+ const [r] = await this.db
78
+ .select()
79
+ .from(metaT)
80
+ .where(and(eq(metaT.repo, repo), eq(metaT.key, "head")));
81
+ return r?.value ?? null;
82
+ }
83
+ /** Bring `repo` up to the checkout's HEAD. `full` rebuilds it from the files. */
84
+ async sync(root, repo, opts = {}) {
85
+ await this.init();
86
+ const h = head(root);
87
+ const last = opts.full ? null : await this.indexedHead(repo);
88
+ if (!h)
89
+ return { repo, head: null, mode: "none", upserted: 0, deleted: 0, broken: [] };
90
+ if (last === h)
91
+ return { repo, head: h, mode: "none", upserted: 0, deleted: 0, broken: [] };
92
+ const known = last && tryGit(root, ["cat-file", "-e", `${last}^{commit}`]).ok;
93
+ const incremental = !!(last && known && isAncestor(root, last, h));
94
+ let gone = [];
95
+ let removed = 0;
96
+ let tree;
97
+ if (incremental) {
98
+ const d = diff(root, last, h, RECORD_DIRS);
99
+ tree = readPathsAt(root, h, d.changed);
100
+ gone = [...d.deleted, ...d.changed];
101
+ removed = d.deleted.length;
102
+ }
103
+ else
104
+ tree = loadAt(root, h);
105
+ await this.db.transaction(async (tx) => {
106
+ if (!incremental) {
107
+ await tx.delete(citesT).where(eq(citesT.repo, repo));
108
+ removed = (await tx.delete(recordsT).where(eq(recordsT.repo, repo)).returning({ id: recordsT.id })).length;
109
+ }
110
+ else if (gone.length) {
111
+ const old = await tx
112
+ .delete(recordsT)
113
+ .where(and(eq(recordsT.repo, repo), inArray(recordsT.path, gone)))
114
+ .returning({ id: recordsT.id });
115
+ const ids = old.map((o) => o.id);
116
+ if (ids.length)
117
+ await tx.delete(citesT).where(and(eq(citesT.repo, repo), inArray(citesT.from, ids)));
118
+ }
119
+ for (const { path, doc } of tree.docs) {
120
+ const row = toRow(repo, path, doc.fm, doc.body);
121
+ await tx
122
+ .insert(recordsT)
123
+ .values(row)
124
+ .onConflictDoUpdate({ target: [recordsT.repo, recordsT.id], set: row });
125
+ await tx.delete(citesT).where(and(eq(citesT.repo, repo), eq(citesT.from, doc.fm.id)));
126
+ const edges = edgesOf(doc.fm).map((to) => ({ repo, from: doc.fm.id, to }));
127
+ if (edges.length)
128
+ await tx.insert(citesT).values(edges).onConflictDoNothing();
129
+ }
130
+ await tx
131
+ .insert(metaT)
132
+ .values({ repo, key: "head", value: h })
133
+ .onConflictDoUpdate({ target: [metaT.repo, metaT.key], set: { value: h } });
134
+ });
135
+ return {
136
+ repo,
137
+ head: h,
138
+ mode: incremental ? "diff" : "full",
139
+ upserted: tree.docs.length,
140
+ deleted: removed,
141
+ broken: tree.broken,
142
+ };
143
+ }
144
+ async get(repo, id) {
145
+ await this.init();
146
+ const [r] = await this.db
147
+ .select()
148
+ .from(recordsT)
149
+ .where(and(eq(recordsT.repo, repo), eq(recordsT.id, id)));
150
+ if (!r)
151
+ return null;
152
+ const cites = await this.linked(repo, id, "to");
153
+ const citedBy = await this.linked(repo, id, "from");
154
+ return { record: r, cites, citedBy };
155
+ }
156
+ /** other = "to": what `id` cites; "from": what cites `id`. */
157
+ async linked(repo, id, other) {
158
+ const col = other === "to" ? citesT.from : citesT.to;
159
+ const rows = await this.db
160
+ .select({
161
+ id: citesT[other],
162
+ type: recordsT.type,
163
+ title: recordsT.title,
164
+ status: recordsT.status,
165
+ })
166
+ .from(citesT)
167
+ .leftJoin(recordsT, and(eq(recordsT.repo, citesT.repo), eq(recordsT.id, citesT[other])))
168
+ .where(and(eq(citesT.repo, repo), eq(col, id)));
169
+ return rows.map((r) => ({
170
+ id: r.id,
171
+ type: r.type,
172
+ title: r.title,
173
+ status: r.status ?? "missing",
174
+ }));
175
+ }
176
+ async find(repo, f = {}) {
177
+ await this.init();
178
+ const where = [];
179
+ if (repo)
180
+ where.push(eq(recordsT.repo, repo));
181
+ if (f.type)
182
+ where.push(eq(recordsT.type, f.type));
183
+ if (f.topic)
184
+ where.push(eq(recordsT.topic, f.topic));
185
+ if (f.status)
186
+ where.push(eq(recordsT.status, f.status));
187
+ for (const w of (f.q ?? "").split(/\s+/).filter(Boolean)) {
188
+ const like = `%${w.replace(/[%_\\]/g, (c) => `\\${c}`)}%`;
189
+ where.push(or(ilike(recordsT.title, like), ilike(recordsT.body, like), ilike(recordsT.id, like)));
190
+ }
191
+ return this.db
192
+ .select()
193
+ .from(recordsT)
194
+ .where(where.length ? and(...where) : undefined)
195
+ .orderBy(desc(recordsT.updated))
196
+ .limit(f.limit ?? 50);
197
+ }
198
+ /** Live records whose evidence is missing, retired, or changed after them. */
199
+ async stale(repo) {
200
+ await this.init();
201
+ const res = await this.db.execute(sql `
202
+ select r.id, r.type, r.title, c."to" as cites, t.status as cited_status,
203
+ case when t.id is null then 'missing' when t.status = 'retired' then 'retired' else 'changed' end as why
204
+ from knowledge_cites c
205
+ join knowledge_records r on r.repo = c.repo and r.id = c."from"
206
+ left join knowledge_records t on t.repo = c.repo and t.id = c."to"
207
+ where c.repo = ${repo} and r.status = 'live'
208
+ and (t.id is null or t.status = 'retired' or t.updated > r.updated)
209
+ order by r.id`);
210
+ return rowsOf(res);
211
+ }
212
+ }
213
+ function toRow(repo, path, fm, body) {
214
+ return {
215
+ repo,
216
+ id: fm.id,
217
+ type: fm.type,
218
+ title: fm.title,
219
+ status: fm.status,
220
+ version: fm.version,
221
+ by: fm.by,
222
+ why: fm.why,
223
+ path,
224
+ topic: fm.type === "rule" || fm.type === "guide" ? fm.topic : null,
225
+ source: fm.type === "finding" ? fm.source : null,
226
+ body,
227
+ data: fm,
228
+ created: fm.created,
229
+ updated: fm.updated,
230
+ };
231
+ }
232
+ // PGlite answers { rows }, postgres-js an array
233
+ const rowsOf = (r) => Array.isArray(r) ? r : (r.rows ?? []);
234
+ /** PGlite in a folder (a checkout's own), or Postgres when a URL is given. */
235
+ export async function openIndex(opts) {
236
+ if (opts.url) {
237
+ const { default: postgres } = await import("postgres");
238
+ const { drizzle } = await import("drizzle-orm/postgres-js");
239
+ const client = postgres(opts.url, { max: 2, onnotice: () => { } });
240
+ return new RecordIndex(drizzle(client), () => client.end());
241
+ }
242
+ const { PGlite } = await import("@electric-sql/pglite");
243
+ const { drizzle } = await import("drizzle-orm/pglite");
244
+ const client = opts.dir ? new PGlite(opts.dir) : new PGlite();
245
+ return new RecordIndex(drizzle(client), () => client.close());
246
+ }
247
+ //# sourceMappingURL=record-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-index.js","sourceRoot":"","sources":["../src/record-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,263 @@
1
+ import { z } from "zod";
2
+ export declare const TYPES: readonly ["source", "finding", "verdict", "rule", "guide"];
3
+ export type RecordType = (typeof TYPES)[number];
4
+ export declare const DIRS: Record<RecordType, string>;
5
+ export declare const Id: z.ZodString;
6
+ export declare const SOURCE_KINDS: readonly ["site", "page", "video", "reel", "post", "person", "tool", "doc", "paper", "feed", "repo", "list", "other"];
7
+ export declare const Source: z.ZodObject<{
8
+ type: z.ZodLiteral<"source">;
9
+ kind: z.ZodEnum<{
10
+ site: "site";
11
+ page: "page";
12
+ video: "video";
13
+ reel: "reel";
14
+ post: "post";
15
+ person: "person";
16
+ tool: "tool";
17
+ doc: "doc";
18
+ paper: "paper";
19
+ feed: "feed";
20
+ repo: "repo";
21
+ list: "list";
22
+ other: "other";
23
+ }>;
24
+ url: z.ZodOptional<z.ZodURL>;
25
+ handle: z.ZodOptional<z.ZodString>;
26
+ priority: z.ZodOptional<z.ZodNumber>;
27
+ media: z.ZodOptional<z.ZodObject<{
28
+ sha256: z.ZodString;
29
+ type: z.ZodString;
30
+ }, z.core.$strip>>;
31
+ id: z.ZodString;
32
+ title: z.ZodString;
33
+ status: z.ZodEnum<{
34
+ live: "live";
35
+ retired: "retired";
36
+ }>;
37
+ version: z.ZodNumber;
38
+ by: z.ZodString;
39
+ why: z.ZodString;
40
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
41
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
42
+ created: z.ZodPreprocess<z.ZodString, unknown>;
43
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
44
+ }, z.core.$loose>;
45
+ export declare const Finding: z.ZodObject<{
46
+ type: z.ZodLiteral<"finding">;
47
+ source: z.ZodString;
48
+ quote: z.ZodOptional<z.ZodString>;
49
+ page: z.ZodOptional<z.ZodURL>;
50
+ at: z.ZodOptional<z.ZodPreprocess<z.ZodString, unknown>>;
51
+ run: z.ZodOptional<z.ZodString>;
52
+ id: z.ZodString;
53
+ title: z.ZodString;
54
+ status: z.ZodEnum<{
55
+ live: "live";
56
+ retired: "retired";
57
+ }>;
58
+ version: z.ZodNumber;
59
+ by: z.ZodString;
60
+ why: z.ZodString;
61
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
62
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
63
+ created: z.ZodPreprocess<z.ZodString, unknown>;
64
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
65
+ }, z.core.$loose>;
66
+ export declare const Verdict: z.ZodObject<{
67
+ type: z.ZodLiteral<"verdict">;
68
+ from: z.ZodEnum<{
69
+ other: "other";
70
+ vireo: "vireo";
71
+ orrery: "orrery";
72
+ owner: "owner";
73
+ }>;
74
+ ref: z.ZodString;
75
+ score: z.ZodOptional<z.ZodNumber>;
76
+ id: z.ZodString;
77
+ title: z.ZodString;
78
+ status: z.ZodEnum<{
79
+ live: "live";
80
+ retired: "retired";
81
+ }>;
82
+ version: z.ZodNumber;
83
+ by: z.ZodString;
84
+ why: z.ZodString;
85
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
86
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
87
+ created: z.ZodPreprocess<z.ZodString, unknown>;
88
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
89
+ }, z.core.$loose>;
90
+ export declare const Rule: z.ZodObject<{
91
+ type: z.ZodLiteral<"rule">;
92
+ topic: z.ZodString;
93
+ order: z.ZodOptional<z.ZodNumber>;
94
+ id: z.ZodString;
95
+ title: z.ZodString;
96
+ status: z.ZodEnum<{
97
+ live: "live";
98
+ retired: "retired";
99
+ }>;
100
+ version: z.ZodNumber;
101
+ by: z.ZodString;
102
+ why: z.ZodString;
103
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
104
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
105
+ created: z.ZodPreprocess<z.ZodString, unknown>;
106
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
107
+ }, z.core.$loose>;
108
+ export declare const Guide: z.ZodObject<{
109
+ type: z.ZodLiteral<"guide">;
110
+ topic: z.ZodString;
111
+ description: z.ZodOptional<z.ZodString>;
112
+ id: z.ZodString;
113
+ title: z.ZodString;
114
+ status: z.ZodEnum<{
115
+ live: "live";
116
+ retired: "retired";
117
+ }>;
118
+ version: z.ZodNumber;
119
+ by: z.ZodString;
120
+ why: z.ZodString;
121
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
122
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
123
+ created: z.ZodPreprocess<z.ZodString, unknown>;
124
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
125
+ }, z.core.$loose>;
126
+ export declare const Frontmatter: z.ZodDiscriminatedUnion<[z.ZodObject<{
127
+ type: z.ZodLiteral<"source">;
128
+ kind: z.ZodEnum<{
129
+ site: "site";
130
+ page: "page";
131
+ video: "video";
132
+ reel: "reel";
133
+ post: "post";
134
+ person: "person";
135
+ tool: "tool";
136
+ doc: "doc";
137
+ paper: "paper";
138
+ feed: "feed";
139
+ repo: "repo";
140
+ list: "list";
141
+ other: "other";
142
+ }>;
143
+ url: z.ZodOptional<z.ZodURL>;
144
+ handle: z.ZodOptional<z.ZodString>;
145
+ priority: z.ZodOptional<z.ZodNumber>;
146
+ media: z.ZodOptional<z.ZodObject<{
147
+ sha256: z.ZodString;
148
+ type: z.ZodString;
149
+ }, z.core.$strip>>;
150
+ id: z.ZodString;
151
+ title: z.ZodString;
152
+ status: z.ZodEnum<{
153
+ live: "live";
154
+ retired: "retired";
155
+ }>;
156
+ version: z.ZodNumber;
157
+ by: z.ZodString;
158
+ why: z.ZodString;
159
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
160
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
161
+ created: z.ZodPreprocess<z.ZodString, unknown>;
162
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
163
+ }, z.core.$loose>, z.ZodObject<{
164
+ type: z.ZodLiteral<"finding">;
165
+ source: z.ZodString;
166
+ quote: z.ZodOptional<z.ZodString>;
167
+ page: z.ZodOptional<z.ZodURL>;
168
+ at: z.ZodOptional<z.ZodPreprocess<z.ZodString, unknown>>;
169
+ run: z.ZodOptional<z.ZodString>;
170
+ id: z.ZodString;
171
+ title: z.ZodString;
172
+ status: z.ZodEnum<{
173
+ live: "live";
174
+ retired: "retired";
175
+ }>;
176
+ version: z.ZodNumber;
177
+ by: z.ZodString;
178
+ why: z.ZodString;
179
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
180
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
181
+ created: z.ZodPreprocess<z.ZodString, unknown>;
182
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
183
+ }, z.core.$loose>, z.ZodObject<{
184
+ type: z.ZodLiteral<"verdict">;
185
+ from: z.ZodEnum<{
186
+ other: "other";
187
+ vireo: "vireo";
188
+ orrery: "orrery";
189
+ owner: "owner";
190
+ }>;
191
+ ref: z.ZodString;
192
+ score: z.ZodOptional<z.ZodNumber>;
193
+ id: z.ZodString;
194
+ title: z.ZodString;
195
+ status: z.ZodEnum<{
196
+ live: "live";
197
+ retired: "retired";
198
+ }>;
199
+ version: z.ZodNumber;
200
+ by: z.ZodString;
201
+ why: z.ZodString;
202
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
203
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
204
+ created: z.ZodPreprocess<z.ZodString, unknown>;
205
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
206
+ }, z.core.$loose>, z.ZodObject<{
207
+ type: z.ZodLiteral<"rule">;
208
+ topic: z.ZodString;
209
+ order: z.ZodOptional<z.ZodNumber>;
210
+ id: z.ZodString;
211
+ title: z.ZodString;
212
+ status: z.ZodEnum<{
213
+ live: "live";
214
+ retired: "retired";
215
+ }>;
216
+ version: z.ZodNumber;
217
+ by: z.ZodString;
218
+ why: z.ZodString;
219
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
220
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
221
+ created: z.ZodPreprocess<z.ZodString, unknown>;
222
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
223
+ }, z.core.$loose>, z.ZodObject<{
224
+ type: z.ZodLiteral<"guide">;
225
+ topic: z.ZodString;
226
+ description: z.ZodOptional<z.ZodString>;
227
+ id: z.ZodString;
228
+ title: z.ZodString;
229
+ status: z.ZodEnum<{
230
+ live: "live";
231
+ retired: "retired";
232
+ }>;
233
+ version: z.ZodNumber;
234
+ by: z.ZodString;
235
+ why: z.ZodString;
236
+ cites: z.ZodDefault<z.ZodArray<z.ZodString>>;
237
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
238
+ created: z.ZodPreprocess<z.ZodString, unknown>;
239
+ updated: z.ZodPreprocess<z.ZodString, unknown>;
240
+ }, z.core.$loose>], "type">;
241
+ export type Frontmatter = z.infer<typeof Frontmatter>;
242
+ export interface Doc {
243
+ fm: Frontmatter;
244
+ body: string;
245
+ }
246
+ /** Where a record lives in the repo. A rule sits under its topic. */
247
+ export declare function pathOf(fm: Pick<Frontmatter, "type" | "id"> & {
248
+ topic?: unknown;
249
+ }): string;
250
+ /** `[n]` and `[n 0:16]` in a guide's body: n is the place in its cites. */
251
+ export declare const CITE_NUMBER: RegExp;
252
+ /** The ids a record leans on: its cites, and a finding's source. */
253
+ export declare function edgesOf(fm: Frontmatter): string[];
254
+ export declare function newId(title: string): string;
255
+ export type Parsed = {
256
+ ok: true;
257
+ doc: Doc;
258
+ } | {
259
+ ok: false;
260
+ error: string;
261
+ };
262
+ export declare function parse(text: string): Parsed;
263
+ export declare function serialize(doc: Doc): string;