@wrenautomation/knowledge 0.0.0-stage → 0.58.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.
package/dist/repo.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import { type Doc } from "./records.js";
3
+ export declare const CONFIG = "knowledge.json";
4
+ export declare const RECORD_DIRS: string[];
5
+ export declare const Config: z.ZodObject<{
6
+ owner: z.ZodDefault<z.ZodString>;
7
+ push: z.ZodDefault<z.ZodBoolean>;
8
+ remote: z.ZodDefault<z.ZodString>;
9
+ }, z.core.$loose>;
10
+ export type Config = z.infer<typeof Config>;
11
+ /** The repo root: `dir`, else the nearest folder up from cwd with a knowledge.json. */
12
+ export declare function findRoot(dir?: string): string;
13
+ export declare function loadConfig(root: string): Config;
14
+ export interface Loaded {
15
+ path: string;
16
+ doc: Doc;
17
+ }
18
+ export interface Broken {
19
+ path: string;
20
+ error: string;
21
+ }
22
+ export interface Tree {
23
+ docs: Loaded[];
24
+ broken: Broken[];
25
+ }
26
+ /** The working tree's records (uncommitted edits included). */
27
+ export declare function loadWorking(root: string): Tree;
28
+ /** The records at a commit: what the index and a server hook see. */
29
+ export declare function loadAt(root: string, rev: string): Tree;
30
+ export declare function readPathsAt(root: string, rev: string, paths: string[]): Tree;
package/dist/repo.js ADDED
@@ -0,0 +1,75 @@
1
+ /** A repo's records, read from the working tree or from a commit, and its config. */
2
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
3
+ import { dirname, join, relative, resolve } from "node:path";
4
+ import { z } from "zod";
5
+ import { lsTree, readAt } from "./git.js";
6
+ import { DIRS, parse } from "./records.js";
7
+ export const CONFIG = "knowledge.json";
8
+ export const RECORD_DIRS = Object.values(DIRS);
9
+ export const Config = z.looseObject({
10
+ // who may write a rule with no cites: the person whose own word is the evidence
11
+ owner: z.string().default("owner"),
12
+ // write commands push after their commit
13
+ push: z.boolean().default(false),
14
+ remote: z.string().default("origin"),
15
+ });
16
+ /** The repo root: `dir`, else the nearest folder up from cwd with a knowledge.json. */
17
+ export function findRoot(dir) {
18
+ if (dir)
19
+ return resolve(dir);
20
+ let at = process.cwd();
21
+ for (;;) {
22
+ if (existsSync(join(at, CONFIG)))
23
+ return at;
24
+ const up = dirname(at);
25
+ if (up === at)
26
+ throw new Error(`no ${CONFIG} here or above; pass --repo or set KNOWLEDGE_DIR`);
27
+ at = up;
28
+ }
29
+ }
30
+ export function loadConfig(root) {
31
+ const p = join(root, CONFIG);
32
+ return Config.parse(existsSync(p) ? JSON.parse(readFileSync(p, "utf8")) : {});
33
+ }
34
+ function collect(files) {
35
+ const docs = [];
36
+ const broken = [];
37
+ for (const [path, text] of files) {
38
+ const r = parse(text);
39
+ if (r.ok)
40
+ docs.push({ path, doc: r.doc });
41
+ else
42
+ broken.push({ path, error: r.error });
43
+ }
44
+ return { docs, broken };
45
+ }
46
+ const isRecord = (p) => p.endsWith(".md") && !p.split("/").pop()?.startsWith("_");
47
+ /** The working tree's records (uncommitted edits included). */
48
+ export function loadWorking(root) {
49
+ const files = new Map();
50
+ const walk = (dir) => {
51
+ if (!existsSync(dir))
52
+ return;
53
+ for (const e of readdirSync(dir, { withFileTypes: true })) {
54
+ const full = join(dir, e.name);
55
+ if (e.isDirectory())
56
+ walk(full);
57
+ else {
58
+ const rel = relative(root, full);
59
+ if (isRecord(rel))
60
+ files.set(rel, readFileSync(full, "utf8"));
61
+ }
62
+ }
63
+ };
64
+ for (const d of RECORD_DIRS)
65
+ walk(join(root, d));
66
+ return collect(files);
67
+ }
68
+ /** The records at a commit: what the index and a server hook see. */
69
+ export function loadAt(root, rev) {
70
+ return collect(readAt(root, rev, lsTree(root, rev, RECORD_DIRS).filter(isRecord)));
71
+ }
72
+ export function readPathsAt(root, rev, paths) {
73
+ return collect(readAt(root, rev, paths.filter(isRecord)));
74
+ }
75
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../src/repo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type Problem } from "./lint.js";
2
+ import { type RecordType } from "./records.js";
3
+ import { type Loaded } from "./repo.js";
4
+ export type Change = {
5
+ op: "add";
6
+ type: RecordType;
7
+ title: string;
8
+ body?: string;
9
+ id?: string;
10
+ [k: string]: unknown;
11
+ } | {
12
+ op: "edit";
13
+ id: string;
14
+ body?: string;
15
+ [k: string]: unknown;
16
+ } | {
17
+ op: "retire";
18
+ id: string;
19
+ };
20
+ export interface Who {
21
+ by: string;
22
+ why: string;
23
+ }
24
+ export declare class LintError extends Error {
25
+ readonly problems: Problem[];
26
+ name: string;
27
+ constructor(problems: Problem[]);
28
+ }
29
+ /** Serialize work on one checkout: writes, syncs, and reads of a PGlite index. */
30
+ export declare function withLock<T>(root: string, fn: () => Promise<T>): Promise<T>;
31
+ export interface Written {
32
+ commit: string;
33
+ records: {
34
+ id: string;
35
+ type: RecordType;
36
+ path: string;
37
+ version: number;
38
+ op: Change["op"];
39
+ }[];
40
+ warnings: Problem[];
41
+ }
42
+ export declare function apply(docs: Loaded[], changes: Change[], who: Who, now?: Date): {
43
+ next: Loaded[];
44
+ touched: {
45
+ id: string;
46
+ op: Change["op"];
47
+ from?: string;
48
+ }[];
49
+ };
50
+ /** Apply, lint, write, commit. Throws LintError (nothing written) or the commit's error (files restored). */
51
+ export declare function write(root: string, changes: Change[], who: Who): Promise<Written>;
package/dist/write.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * One write = one commit. Changes apply to the tree in memory, the whole tree is linted, then the files
3
+ * land and commit together; a failed commit puts every file back. A lock serializes writers in one
4
+ * checkout; across checkouts, push is the compare-and-swap (push.ts).
5
+ */
6
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
+ import lockfile from "proper-lockfile";
9
+ import { git, head } from "./git.js";
10
+ import { errors, lint } from "./lint.js";
11
+ import { Frontmatter, newId, pathOf, serialize } from "./records.js";
12
+ import { loadConfig, loadWorking } from "./repo.js";
13
+ export class LintError extends Error {
14
+ problems;
15
+ name = "LintError";
16
+ constructor(problems) {
17
+ super(problems.map((p) => `${p.path}: ${p.msg}`).join("\n"));
18
+ this.problems = problems;
19
+ }
20
+ }
21
+ // fields the store owns: a change never sets them
22
+ const OWNED = new Set(["op", "type", "version", "created", "updated", "by", "why", "status"]);
23
+ /** Serialize work on one checkout: writes, syncs, and reads of a PGlite index. */
24
+ export async function withLock(root, fn) {
25
+ const gitDir = join(root, git(root, ["rev-parse", "--git-dir"]));
26
+ const release = await lockfile.lock(root, {
27
+ lockfilePath: join(gitDir, "knowledge.lock"),
28
+ retries: { retries: 120, minTimeout: 50, maxTimeout: 1000 },
29
+ stale: 60_000,
30
+ });
31
+ try {
32
+ return await fn();
33
+ }
34
+ finally {
35
+ await release();
36
+ }
37
+ }
38
+ export function apply(docs, changes, who, now = new Date()) {
39
+ const stamp = now.toISOString();
40
+ const byId = new Map(docs.map((l) => [l.doc.fm.id, l]));
41
+ const touched = [];
42
+ for (const c of changes) {
43
+ if (c.op === "add") {
44
+ const { op: _op, body, ...rest } = c;
45
+ const id = c.id ?? newId(c.title);
46
+ if (byId.has(id))
47
+ throw new Error(`add: ${id} is already in the repo`);
48
+ const fields = Object.fromEntries(Object.entries(rest).filter(([k]) => !OWNED.has(k)));
49
+ const fm = Frontmatter.parse({
50
+ ...fields,
51
+ id,
52
+ type: c.type,
53
+ status: "live",
54
+ version: 1,
55
+ by: who.by,
56
+ why: rest.why ?? who.why,
57
+ created: stamp,
58
+ updated: stamp,
59
+ });
60
+ byId.set(id, { path: pathOf(fm), doc: { fm, body: (body ?? "").trim() } });
61
+ touched.push({ id, op: "add" });
62
+ continue;
63
+ }
64
+ const cur = byId.get(c.id);
65
+ if (!cur)
66
+ throw new Error(`${c.op}: no record ${c.id}`);
67
+ const old = cur.doc.fm;
68
+ let fm;
69
+ let body = cur.doc.body;
70
+ if (c.op === "retire") {
71
+ if (old.status === "retired")
72
+ throw new Error(`retire: ${c.id} is already retired`);
73
+ fm = Frontmatter.parse({ ...old, status: "retired" });
74
+ }
75
+ else {
76
+ const { op: _op, id: _id, body: b, ...patch } = c;
77
+ for (const k of Object.keys(patch))
78
+ if (OWNED.has(k) || k === "id")
79
+ throw new Error(`edit: ${k} is set by the store`);
80
+ // null drops an optional field
81
+ const merged = { ...old, ...patch };
82
+ for (const [k, v] of Object.entries(merged))
83
+ if (v === null)
84
+ delete merged[k];
85
+ fm = Frontmatter.parse(merged);
86
+ if (typeof b === "string")
87
+ body = b.trim();
88
+ }
89
+ fm.version = old.version + 1;
90
+ fm.updated = stamp;
91
+ fm.by = who.by;
92
+ fm.why = who.why;
93
+ byId.set(c.id, { path: pathOf(fm), doc: { fm, body } });
94
+ touched.push({ id: c.id, op: c.op, from: cur.path });
95
+ }
96
+ return { next: [...byId.values()], touched };
97
+ }
98
+ function message(changes, touched, who) {
99
+ const first = touched[0];
100
+ const subject = touched.length === 1 && first
101
+ ? `knowledge: ${first.op} ${first.id}`
102
+ : `knowledge: ${touched.length} changes (${[...new Set(changes.map((c) => c.op))].join(", ")})`;
103
+ const lines = touched.length > 1 ? `\n${touched.map((t) => `- ${t.op} ${t.id}`).join("\n")}\n` : "";
104
+ return `${subject}\n\n${who.why}\n${lines}\nKnowledge-By: ${who.by}`;
105
+ }
106
+ /** Apply, lint, write, commit. Throws LintError (nothing written) or the commit's error (files restored). */
107
+ export async function write(root, changes, who) {
108
+ if (!changes.length)
109
+ throw new Error("no changes");
110
+ if (!who.by.trim() || !who.why.trim())
111
+ throw new Error("--by and --why are required");
112
+ return withLock(root, async () => {
113
+ const tree = loadWorking(root);
114
+ const { next, touched } = apply(tree.docs, changes, who);
115
+ const problems = lint({ docs: next, broken: tree.broken }, loadConfig(root).owner);
116
+ // a fault already elsewhere in the tree does not block this write; one in a record it touches does
117
+ const mine = new Set(touched.map((t) => t.id));
118
+ const blocking = errors(problems).filter((p) => p.id && mine.has(p.id));
119
+ if (blocking.length)
120
+ throw new LintError(blocking);
121
+ const byId = new Map(next.map((l) => [l.doc.fm.id, l]));
122
+ const paths = new Set();
123
+ const backup = new Map();
124
+ const keep = (p) => {
125
+ if (backup.has(p))
126
+ return;
127
+ const full = join(root, p);
128
+ backup.set(p, existsSync(full) ? readFileSync(full, "utf8") : null);
129
+ paths.add(p);
130
+ };
131
+ for (const t of touched) {
132
+ const l = byId.get(t.id);
133
+ if (!l)
134
+ continue;
135
+ if (t.from && t.from !== l.path) {
136
+ keep(t.from);
137
+ rmSync(join(root, t.from), { force: true });
138
+ }
139
+ keep(l.path);
140
+ mkdirSync(dirname(join(root, l.path)), { recursive: true });
141
+ writeFileSync(join(root, l.path), serialize(l.doc));
142
+ }
143
+ try {
144
+ const list = [...paths];
145
+ git(root, ["add", "-A", "--", ...list]);
146
+ git(root, ["commit", "-q", "-m", message(changes, touched, who), "--", ...list]);
147
+ }
148
+ catch (e) {
149
+ for (const [p, text] of backup) {
150
+ const full = join(root, p);
151
+ if (text === null)
152
+ rmSync(full, { force: true });
153
+ else {
154
+ mkdirSync(dirname(full), { recursive: true });
155
+ writeFileSync(full, text);
156
+ }
157
+ }
158
+ try {
159
+ git(root, ["reset", "-q", "--", ...paths]);
160
+ }
161
+ catch { }
162
+ throw e;
163
+ }
164
+ const commit = head(root);
165
+ return {
166
+ commit,
167
+ records: touched.map((t) => {
168
+ const l = byId.get(t.id);
169
+ return { id: t.id, type: l.doc.fm.type, path: l.path, version: l.doc.fm.version, op: t.op };
170
+ }),
171
+ warnings: problems.filter((p) => p.level === "warn" && (!p.id || mine.has(p.id))),
172
+ };
173
+ });
174
+ }
175
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,49 @@
1
1
  {
2
2
  "name": "@wrenautomation/knowledge",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.58.0",
4
+ "description": "Knowledge as files: sources, findings, verdicts and rules as markdown records in a git repo, each linked to its evidence. One commit is one transaction; a lint guards every write; a Postgres (or PGlite) index built from the commits answers queries, backlinks and stale marks.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/wrenautomation/engine.git",
8
+ "directory": "packages/knowledge"
9
+ },
10
+ "license": "PolyForm-Strict-1.0.0",
11
+ "files": [
12
+ "dist",
13
+ "!dist/**/*.test.*",
14
+ "README.md",
15
+ "LICENSE.md"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "type": "module",
21
+ "bin": {
22
+ "knowledge": "dist/cli.js"
23
+ },
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js"
28
+ }
29
+ },
30
+ "engines": {
31
+ "node": ">=24"
32
+ },
33
+ "dependencies": {
34
+ "@electric-sql/pglite": "0.5.11",
35
+ "commander": "15.0.0",
36
+ "drizzle-orm": "0.45.4",
37
+ "gray-matter": "4.0.3",
38
+ "postgres": "3.4.9",
39
+ "proper-lockfile": "4.1.2",
40
+ "zod": "4.6.5"
41
+ },
42
+ "devDependencies": {
43
+ "@types/proper-lockfile": "4.1.4"
44
+ },
45
+ "scripts": {
46
+ "typecheck": "tsc --noEmit",
47
+ "build": "sh ../../scripts/build.sh cli.js"
48
+ }
6
49
  }