@guided-context-ledger/core 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.
- package/LICENSE +202 -0
- package/NOTICE +10 -0
- package/README.md +24 -0
- package/dist/events.d.ts +430 -0
- package/dist/events.js +1159 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger.d.ts +111 -0
- package/dist/ledger.js +239 -0
- package/dist/ledger.js.map +1 -0
- package/dist/workspace.d.ts +55 -0
- package/dist/workspace.js +203 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +24 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
/**
|
|
5
|
+
* Raised when the workspace root itself is unusable (missing or not a directory).
|
|
6
|
+
* Distinct from a missing note: we never silently create the workspace root — the
|
|
7
|
+
* user points us at an existing folder (locked decision: no auto-created default).
|
|
8
|
+
*/
|
|
9
|
+
export class WorkspaceError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
detail;
|
|
12
|
+
constructor(message, code, detail) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.detail = detail;
|
|
16
|
+
this.name = "WorkspaceError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const LOCK_TIMEOUT_MS = 5_000;
|
|
20
|
+
const LOCK_STALE_MS = 4_000;
|
|
21
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
22
|
+
/**
|
|
23
|
+
* Workspace: all read/write operations against a single markdown workspace directory.
|
|
24
|
+
*
|
|
25
|
+
* Design rule (locked decision): the markdown files ARE the source of truth.
|
|
26
|
+
* Nothing here hides data in a database. Every operation is a plain file op,
|
|
27
|
+
* confined to the workspace root so an agent can never read or write outside it.
|
|
28
|
+
*/
|
|
29
|
+
export class Workspace {
|
|
30
|
+
root;
|
|
31
|
+
constructor(root) {
|
|
32
|
+
this.root = path.resolve(root);
|
|
33
|
+
}
|
|
34
|
+
/** Resolve a workspace-relative path and guarantee it stays inside the workspace. */
|
|
35
|
+
resolveInside(relPath) {
|
|
36
|
+
const full = path.resolve(this.root, relPath);
|
|
37
|
+
const rel = path.relative(this.root, full);
|
|
38
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
39
|
+
throw new Error(`Path escapes the workspace: ${relPath}`);
|
|
40
|
+
}
|
|
41
|
+
return full;
|
|
42
|
+
}
|
|
43
|
+
/** Does the workspace root exist, and is it a directory? Never throws. */
|
|
44
|
+
async rootStatus() {
|
|
45
|
+
try {
|
|
46
|
+
const s = await fs.stat(this.root);
|
|
47
|
+
return { exists: true, isDirectory: s.isDirectory() };
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return { exists: false, isDirectory: false };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Guarantee the workspace root is usable before a write. We create notes and
|
|
55
|
+
* sub-folders inside the workspace on demand, but never conjure the root itself —
|
|
56
|
+
* a missing root means a misconfigured workspace folder, which must be signaled,
|
|
57
|
+
* not silently created somewhere unexpected.
|
|
58
|
+
*/
|
|
59
|
+
async assertRootUsable() {
|
|
60
|
+
const { exists, isDirectory } = await this.rootStatus();
|
|
61
|
+
if (!exists) {
|
|
62
|
+
throw new WorkspaceError(`Workspace folder does not exist: ${this.root}`, "WORKSPACE_MISSING");
|
|
63
|
+
}
|
|
64
|
+
if (!isDirectory) {
|
|
65
|
+
throw new WorkspaceError(`Workspace path is not a folder: ${this.root}`, "WORKSPACE_NOT_DIR");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Cross-process exclusive lock (same approach as the event log) — used to make
|
|
69
|
+
// a compare-and-swap write atomic so two writers can't both pass the check.
|
|
70
|
+
async acquireLock(lock) {
|
|
71
|
+
const start = Date.now();
|
|
72
|
+
for (;;) {
|
|
73
|
+
try {
|
|
74
|
+
const fd = await fs.open(lock, "wx");
|
|
75
|
+
await fd.writeFile(`${process.pid}:${Date.now()}`);
|
|
76
|
+
await fd.close();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
// Windows can transiently surface EPERM/EACCES on concurrent exclusive
|
|
81
|
+
// opens while another handle settles — treat as busy, like EEXIST.
|
|
82
|
+
const lockBusy = e.code === "EEXIST" || e.code === "EPERM" || e.code === "EACCES";
|
|
83
|
+
if (!lockBusy)
|
|
84
|
+
throw e;
|
|
85
|
+
try {
|
|
86
|
+
const st = await fs.stat(lock);
|
|
87
|
+
if (Date.now() - st.mtimeMs > LOCK_STALE_MS) {
|
|
88
|
+
await fs.unlink(lock).catch(() => { });
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
if (e.code === "EEXIST")
|
|
94
|
+
continue; // lock vanished between checks
|
|
95
|
+
}
|
|
96
|
+
if (Date.now() - start > LOCK_TIMEOUT_MS) {
|
|
97
|
+
throw new WorkspaceError(`Could not acquire the write lock for this note (busy).`, "CONFLICT", { reason: "lock_timeout" });
|
|
98
|
+
}
|
|
99
|
+
await sleep(2 + Math.floor(Math.random() * 8));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async releaseLock(lock) {
|
|
104
|
+
await fs.unlink(lock).catch(() => { });
|
|
105
|
+
}
|
|
106
|
+
/** List every markdown note, optionally under a sub-folder. Returns workspace-relative paths. */
|
|
107
|
+
async list(subfolder = "") {
|
|
108
|
+
const start = this.resolveInside(subfolder);
|
|
109
|
+
const out = [];
|
|
110
|
+
const walk = async (dir) => {
|
|
111
|
+
let entries;
|
|
112
|
+
try {
|
|
113
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (const e of entries) {
|
|
119
|
+
if (e.name.startsWith("."))
|
|
120
|
+
continue;
|
|
121
|
+
const abs = path.join(dir, e.name);
|
|
122
|
+
if (e.isDirectory())
|
|
123
|
+
await walk(abs);
|
|
124
|
+
else if (e.isFile() && e.name.toLowerCase().endsWith(".md")) {
|
|
125
|
+
// Normalize to forward slashes so output is consistent cross-platform
|
|
126
|
+
// and matches what Obsidian/markdown expect (Windows path.relative yields "\\").
|
|
127
|
+
out.push(path.relative(this.root, abs).split(path.sep).join("/"));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
await walk(start);
|
|
132
|
+
return out.sort();
|
|
133
|
+
}
|
|
134
|
+
/** Read a single note's full contents. */
|
|
135
|
+
async read(relPath) {
|
|
136
|
+
return fs.readFile(this.resolveInside(relPath), "utf-8");
|
|
137
|
+
}
|
|
138
|
+
/** sha256 (hex) of a note's bytes, or "" if it does not exist. The CAS token. */
|
|
139
|
+
async hashOf(relPath) {
|
|
140
|
+
try {
|
|
141
|
+
const buf = await fs.readFile(this.resolveInside(relPath));
|
|
142
|
+
return createHash("sha256").update(buf).digest("hex");
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
if (e.code === "ENOENT")
|
|
146
|
+
return "";
|
|
147
|
+
throw e;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Full-text search across all notes. Returns matches with line numbers and context. */
|
|
151
|
+
async search(query, limit = 50) {
|
|
152
|
+
const q = query.toLowerCase();
|
|
153
|
+
const results = [];
|
|
154
|
+
for (const rel of await this.list()) {
|
|
155
|
+
const content = await this.read(rel);
|
|
156
|
+
const lines = content.split(/\r?\n/);
|
|
157
|
+
for (let i = 0; i < lines.length; i++) {
|
|
158
|
+
if (lines[i].toLowerCase().includes(q)) {
|
|
159
|
+
results.push({ path: rel, line: i + 1, text: lines[i].trim() });
|
|
160
|
+
if (results.length >= limit)
|
|
161
|
+
return results;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return results;
|
|
166
|
+
}
|
|
167
|
+
/** Create or overwrite a note. Parent folders are created as needed. */
|
|
168
|
+
async write(relPath, content, expectedHash) {
|
|
169
|
+
const full = this.resolveInside(relPath);
|
|
170
|
+
await this.assertRootUsable();
|
|
171
|
+
await fs.mkdir(path.dirname(full), { recursive: true });
|
|
172
|
+
const writeNow = async () => {
|
|
173
|
+
await fs.writeFile(full, content, "utf-8");
|
|
174
|
+
return { hash: createHash("sha256").update(content, "utf8").digest("hex") };
|
|
175
|
+
};
|
|
176
|
+
// No guard requested → unconditional overwrite (last-writer-wins).
|
|
177
|
+
if (expectedHash === undefined)
|
|
178
|
+
return writeNow();
|
|
179
|
+
// Compare-and-swap: the write is rejected unless the note still matches the
|
|
180
|
+
// hash the caller last read — flag-don't-clobber for documents. "" = expect-absent.
|
|
181
|
+
// Locked so the check + write is atomic across processes (no lost updates).
|
|
182
|
+
const lock = `${full}.lock`;
|
|
183
|
+
await this.acquireLock(lock);
|
|
184
|
+
try {
|
|
185
|
+
const current = await this.hashOf(relPath);
|
|
186
|
+
if (current !== expectedHash) {
|
|
187
|
+
throw new WorkspaceError(`Write conflict on ${relPath}: the note changed since you read it.`, "CONFLICT", { current_hash: current, expected_hash: expectedHash });
|
|
188
|
+
}
|
|
189
|
+
return await writeNow();
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
await this.releaseLock(lock);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/** Append to a note (creating it if absent). */
|
|
196
|
+
async append(relPath, content) {
|
|
197
|
+
const full = this.resolveInside(relPath);
|
|
198
|
+
await this.assertRootUsable();
|
|
199
|
+
await fs.mkdir(path.dirname(full), { recursive: true });
|
|
200
|
+
await fs.appendFile(full, content, "utf-8");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guided-context-ledger/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Transport-agnostic core runtime for the Guided Context Ledger (GCL): workspace I/O, the append-only event/coordination trail (claims, leases, orient/needs_me), and the content-addressed revision ledger (HEAD, CAS).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
|
|
10
|
+
"files": ["dist", "README.md", "LICENSE", "NOTICE"],
|
|
11
|
+
"publishConfig": { "access": "public" },
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"test": "node --import tsx --test test/*.test.ts",
|
|
15
|
+
"prepublishOnly": "npm run build && npm test"
|
|
16
|
+
},
|
|
17
|
+
"engines": { "node": ">=18" },
|
|
18
|
+
"repository": { "type": "git", "url": "https://github.com/guided-context-ledger/guided-context-ledger.git", "directory": "packages/core" },
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^22.0.0",
|
|
21
|
+
"tsx": "^4.19.0",
|
|
22
|
+
"typescript": "^5.6.0"
|
|
23
|
+
}
|
|
24
|
+
}
|