@k-l-lambda/portolan 0.0.0-stage → 0.1.1

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/README.md CHANGED
@@ -1,3 +1,105 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <img src="web/public/favicon.svg" alt="Portolan logo: a compass rose with a red north point" width="96" height="96">
3
+ </p>
4
+
5
+ <h1 align="center">Portolan</h1>
6
+
7
+ Portolan is a shared map of work for humans and AI agents. It is a mind map that is also a TODO list and a task log, showing the relations, progress and plans across an agent's whole workflow.
8
+
9
+ ## Why
10
+
11
+ Agents now do long, branching work: surveys, experiments, refactors that split into sub-tasks and depend on each other. Logs and diaries record what happened, but not the shape of the work. Chat history is linear. It is hard to see what is done, what is blocked and what comes next.
12
+
13
+ Existing tools cover pieces of this. Agent task trackers keep a task graph, mind-map UIs draw trees, plan-annotation tools let you comment on an agent's plan. None of them gives one shared map that is human-readable, git-friendly, and edited by both the human and the agent.
14
+
15
+ ## Core ideas
16
+
17
+ - The map holds structure only: work items, status, hierarchy and relations. Details stay in the diary, and the map links into it.
18
+ - The map is plain text in the Rhumb DSL (`.rhumb`). It is designed to be easy for LLMs to write: it borrows GFM task lists, YAML and Markdown links, and adds only a small sentence syntax for edges.
19
+ - It is designed to diff well in git: one change is one line.
20
+ - Annotations live in a sidecar file next to the map, so humans and agents can discuss a node in a thread without cluttering the map.
21
+
22
+ ## The name
23
+
24
+ A portolan chart was a nautical map drawn from sailors' logbooks, with rhumb lines connecting the ports. It is a map that grows out of logs, which is what this project tries to be. Rhumb is the name of the DSL; its edges are the rhumb lines between work items.
25
+
26
+ ## What a map looks like
27
+
28
+ ```rhumb
29
+ ---
30
+ rhumb: 0.1
31
+ title: Portolan
32
+ ---
33
+
34
+ - [/] Portolan ^portolan
35
+ - [x] Prior-art survey ^survey
36
+ - Closest pieces: [Backlog.md](https://github.com/MrLesk/Backlog.md), Beads, Plannotator
37
+ - [/] Rhumb DSL {owner: claude} ^rhumb
38
+ - [x] Spec 0.1 ^rhumb-spec
39
+ - [x] Parser ^rhumb-parser
40
+ - [ ] Visual frontend ^ui
41
+ - [?] Agent loop for threads ^threads-agent
42
+
43
+ %% relations
44
+ rhumb-parser needs rhumb-spec
45
+ ui needs rhumb-parser: needs a stable AST
46
+ threads-agent relates ui
47
+ ```
48
+
49
+ Each `- [ ]` item is a node with a status (`[ ]` todo, `[/]` doing, `[x]` done, `[-]` dropped, `[!]` blocked, `[?]` idea) and a stable `^id`. Items without a checkbox are notes. Links are anchors into the diary or elsewhere. Lines like `a needs b` are edges. Progress and readiness are derived by the tools, never stored in the file.
50
+
51
+ ## Status
52
+
53
+ Portolan is experimental and changing quickly. What exists today:
54
+
55
+ - Rhumb 0.1 spec and a Peggy-based parser with tests
56
+ - `check` (parse errors, consistency, anchor resolution) and a first `fmt` (assigns missing IDs, normalizes status aliases)
57
+ - An edit API (set status, add or delete nodes, rename IDs, add or remove edges) that keeps untouched lines intact
58
+ - A thread store for annotations in an append-only `.threads.jsonl` sidecar
59
+ - A local server that serves the map, derived values and threads, and pushes file changes live
60
+ - A first web view, with a mind map and a diary panel, still being built
61
+
62
+ The server has no authentication and binds to `127.0.0.1` only. Do not expose it.
63
+
64
+ Next:
65
+
66
+ - Annotation UI in the web view
67
+ - An agent loop that delivers human comments in threads to the agent and writes replies back
68
+ - A fuller formatter
69
+
70
+ ## Install
71
+
72
+ ```sh
73
+ npm install -g @k-l-lambda/portolan # or: npx @k-l-lambda/portolan serve <dir>
74
+ portolan serve path/to/maps # then open http://127.0.0.1:4310
75
+ rhumb check path/to/plan.rhumb
76
+ ```
77
+
78
+ The package ships the compiled CLI, the library API (`import { parse } from "@k-l-lambda/portolan"`) and the built web app. It needs Node 22.12 or newer.
79
+
80
+ ## Quick start
81
+
82
+ pnpm is required. `npm install` crashes with npm 10.9 on this dependency set.
83
+
84
+ ```sh
85
+ pnpm install
86
+ pnpm test
87
+ pnpm build:web
88
+
89
+ node src/cli.ts check examples/portolan.rhumb
90
+ node src/cli.ts serve examples
91
+ ```
92
+
93
+ Then open http://127.0.0.1:4310.
94
+
95
+ ## Docs
96
+
97
+ - [docs/rhumb-spec.md](docs/rhumb-spec.md): the Rhumb 0.1 syntax specification
98
+ - [docs/skill.md](docs/skill.md): guide for agents that maintain a Rhumb map
99
+
100
+ ## Releasing
101
+
102
+ Bump `version` in `package.json` and push to `main`. The [publish workflow](.github/workflows/publish.yml) publishes that version to npm if it is not there yet, using npm Trusted Publishing (no token secret; provenance is added automatically).
103
+
104
+ The very first release has to be published by hand (`npm publish --access public`), because a trusted publisher can only be configured on a package that already exists. After that, on npmjs.com open the package settings, add a Trusted Publisher for GitHub Actions with user `k-l-lambda`, repository `portolan` and workflow `publish.yml`.
2
105
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ // rhumb check <file> parse + derived + anchor diagnostics; exit 1 on errors
3
+ // rhumb fmt <file> assign missing IDs and normalize status aliases in place
4
+ // portolan serve <dir|file> [--port N] web UI + API for every .rhumb under dir (127.0.0.1 only)
5
+ import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import { derive } from "./derive.js";
8
+ import { format } from "./format.js";
9
+ import { parse } from "./parse.js";
10
+ import { checkAnchors, contextFor } from "./resolve.js";
11
+ import { createRhumbServer } from "./server.js";
12
+ const [cmd, file, ...rest] = process.argv.slice(2);
13
+ if (!cmd || !file || !["check", "fmt", "serve"].includes(cmd)) {
14
+ console.error("usage: portolan <check|fmt> <file.rhumb>\n portolan serve <dir|file.rhumb> [--port N]");
15
+ process.exit(2);
16
+ }
17
+ const path = resolve(file);
18
+ const source = cmd === "serve" ? "" : readFileSync(path, "utf8");
19
+ if (cmd === "check") {
20
+ const doc = parse(source, { fileName: path });
21
+ const read = (p) => (existsSync(p) && statSync(p).isFile() ? readFileSync(p, "utf8") : null);
22
+ const diags = [...doc.diagnostics, ...derive(doc).diagnostics, ...checkAnchors(doc, contextFor(path, doc, read))]
23
+ .sort((a, b) => a.line - b.line);
24
+ for (const d of diags)
25
+ console.log(`${file}:${d.line}: ${d.level} ${d.code} ${d.message}`);
26
+ process.exit(diags.some((d) => d.level === "error") ? 1 : 0);
27
+ }
28
+ if (cmd === "fmt") {
29
+ const out = format(source);
30
+ if (out.source !== source)
31
+ writeFileSync(path, out.source);
32
+ for (const a of out.assigned)
33
+ console.log(`${file}:${a.line}: assigned ^${a.id}`);
34
+ }
35
+ if (cmd === "serve") {
36
+ const i = rest.indexOf("--port");
37
+ const port = i >= 0 ? Number(rest[i + 1]) : 4310;
38
+ createRhumbServer({ root: path }).listen(port, "127.0.0.1", () => {
39
+ console.log(`portolan: serving ${path} at http://127.0.0.1:${port} (no auth, loopback only)`);
40
+ });
41
+ }
42
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Diagnostic, RhumbDocument } from "./types.ts";
2
+ export interface NodeState {
3
+ line: number;
4
+ id: string | null;
5
+ /** Done leaves / committed leaves in the subtree; null when nothing is committed. */
6
+ progress: {
7
+ done: number;
8
+ total: number;
9
+ } | null;
10
+ /** todo, and every dependency is done (or dropped, see W006). */
11
+ ready: boolean;
12
+ }
13
+ export interface Derived {
14
+ nodes: NodeState[];
15
+ diagnostics: Diagnostic[];
16
+ }
17
+ export declare function derive(doc: RhumbDocument): Derived;
package/dist/derive.js ADDED
@@ -0,0 +1,67 @@
1
+ // Derived semantics (spec section 6): computed from the AST, never written to the file.
2
+ import { diagnostic } from "./parse.js";
3
+ const OPEN = new Set(["todo", "doing", "blocked"]);
4
+ export function derive(doc) {
5
+ const all = [];
6
+ const walk = (nodes) => nodes.forEach((n) => (all.push(n), walk(n.children)));
7
+ walk(doc.nodes);
8
+ const byId = new Map();
9
+ for (const n of all)
10
+ if (n.id !== null && !byId.has(n.id))
11
+ byId.set(n.id, n);
12
+ // Dependencies as x needs y, with the edge line for diagnostics.
13
+ const needs = new Map();
14
+ for (const e of doc.edges) {
15
+ if (e.kind !== "needs" && e.kind !== "blocks")
16
+ continue;
17
+ const [x, y] = e.kind === "needs" ? [byId.get(e.from), byId.get(e.to)] : [byId.get(e.to), byId.get(e.from)];
18
+ if (!x || !y)
19
+ continue;
20
+ if (!needs.has(x))
21
+ needs.set(x, []);
22
+ needs.get(x).push({ target: y, line: e.line });
23
+ }
24
+ const diagnostics = [];
25
+ const progress = new Map();
26
+ const count = (n) => {
27
+ let r;
28
+ if (n.children.length === 0) {
29
+ const committed = n.status !== "dropped" && n.status !== "idea";
30
+ r = { done: committed && n.status === "done" ? 1 : 0, total: committed ? 1 : 0 };
31
+ }
32
+ else {
33
+ r = n.children.map(count).reduce((a, b) => ({ done: a.done + b.done, total: a.total + b.total }));
34
+ }
35
+ progress.set(n, r);
36
+ return r;
37
+ };
38
+ doc.nodes.forEach(count);
39
+ const hasOpenDescendant = (n) => n.children.some((c) => OPEN.has(c.status ?? "") || hasOpenDescendant(c));
40
+ const nodes = all.map((n) => {
41
+ const deps = needs.get(n) ?? [];
42
+ for (const d of deps) {
43
+ if (d.target.status === "dropped") {
44
+ diagnostics.push(diagnostic("W006", d.line, `"${n.id}" depends on dropped node "${d.target.id}"`));
45
+ }
46
+ else if ((n.status === "doing" || n.status === "done") && d.target.status !== "done") {
47
+ diagnostics.push(diagnostic("W008", n.line, `"${n.id}" is ${n.status} but "${d.target.id}" is not done`));
48
+ }
49
+ }
50
+ if (n.status === "done" && hasOpenDescendant(n)) {
51
+ diagnostics.push(diagnostic("W007", n.line, "Node is done but its subtree still has open work"));
52
+ }
53
+ if (n.status === "todo" && n.children.some((c) => c.status === "doing" || c.status === "done")) {
54
+ diagnostics.push(diagnostic("I003", n.line, "Children have started; consider marking this node doing"));
55
+ }
56
+ const p = progress.get(n);
57
+ return {
58
+ line: n.line,
59
+ id: n.id,
60
+ progress: p.total > 0 ? p : null,
61
+ ready: n.status === "todo" && deps.every((d) => d.target.status === "done" || d.target.status === "dropped"),
62
+ };
63
+ });
64
+ diagnostics.sort((a, b) => a.line - b.line);
65
+ return { nodes, diagnostics };
66
+ }
67
+ //# sourceMappingURL=derive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"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"}
package/dist/edit.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import type { EdgeKind, Status } from "./types.ts";
2
+ export type EditOp = {
3
+ op: "set-status";
4
+ id: string;
5
+ status: Status;
6
+ } | {
7
+ op: "set-title";
8
+ id: string;
9
+ title: string;
10
+ }
11
+ /** Sets one attribute; `null` (and `false` for `star`) removes the key. */
12
+ | {
13
+ op: "set-attr";
14
+ id: string;
15
+ key: string;
16
+ value: AttrValue | null;
17
+ } | {
18
+ op: "add-node";
19
+ parent: string | null;
20
+ title: string;
21
+ status?: Status;
22
+ id?: string;
23
+ } | {
24
+ op: "remove-node";
25
+ id: string;
26
+ recursive?: boolean;
27
+ } | {
28
+ op: "rename-id";
29
+ id: string;
30
+ to: string;
31
+ } | {
32
+ op: "add-edge";
33
+ from: string;
34
+ kind: EdgeKind;
35
+ to: string;
36
+ label?: string;
37
+ } | {
38
+ op: "remove-edge";
39
+ from: string;
40
+ kind: EdgeKind;
41
+ to: string;
42
+ }
43
+ /** Reserved: moving a subtree needs re-indentation of notes and children. Not implemented in 0.1. */
44
+ | {
45
+ op: "move-node";
46
+ id: string;
47
+ parent: string | null;
48
+ };
49
+ export interface EditResult {
50
+ source: string;
51
+ /** ID of the node an add-node created. */
52
+ id?: string;
53
+ /** Old → new IDs from rename-id, so callers can retarget sidecar data (threads). */
54
+ renamed?: {
55
+ from: string;
56
+ to: string;
57
+ };
58
+ /** IDs removed by remove-node (the node and its descendants). */
59
+ removed?: string[];
60
+ }
61
+ export declare class EditError extends Error {
62
+ }
63
+ export type AttrValue = string | number | boolean | (string | number | boolean)[];
64
+ export declare function applyEdit(source: string, edit: EditOp): EditResult;
65
+ export declare function formatAttrs(attrs: Record<string, unknown>): string;
66
+ /** `_` + 6 random base32 characters, unique among `taken`. */
67
+ export declare function generateId(taken: {
68
+ has(id: string): boolean;
69
+ }): string;
package/dist/edit.js ADDED
@@ -0,0 +1,302 @@
1
+ // Line-level edit operations shared by the CLI, agents and the UI.
2
+ //
3
+ // Every operation rewrites only the lines it touches, so comments, blank lines and
4
+ // formatting elsewhere survive and a single change stays a small diff. After each
5
+ // edit the result is re-parsed; an edit that introduces new errors is rejected.
6
+ import { randomBytes } from "node:crypto";
7
+ import { parse as parseLine } from "./generated/line-parser.js";
8
+ import { EDGE_KINDS, GEN_ID, HAND_ID, parse, splitIndent } from "./parse.js";
9
+ export class EditError extends Error {
10
+ }
11
+ const ATTR_KEY = /^[a-z][a-z0-9_-]{0,31}$/;
12
+ const SYMBOL = {
13
+ todo: " ", doing: "/", done: "x", dropped: "-", blocked: "!", idea: "?",
14
+ };
15
+ export function applyEdit(source, edit) {
16
+ const doc = parse(source);
17
+ if (doc.diagnostics.some((d) => d.code === "E012")) {
18
+ throw new EditError("Front matter is invalid; fix it before editing");
19
+ }
20
+ const eol = source.includes("\r\n") ? "\r\n" : "\n";
21
+ const lines = source.replace(/\r\n?/g, "\n").split("\n");
22
+ const trailingNewline = lines[lines.length - 1] === "";
23
+ if (trailingNewline)
24
+ lines.pop();
25
+ const result = run(doc, lines, edit);
26
+ const out = lines.join(eol) + (trailingNewline || lines.length > 0 ? eol : "");
27
+ const errorsBefore = countErrors(doc);
28
+ const after = parse(out);
29
+ if (countErrors(after) > errorsBefore) {
30
+ const added = after.diagnostics.find((d) => d.level === "error");
31
+ throw new EditError(`Edit would introduce ${added.code}: ${added.message}`);
32
+ }
33
+ return { ...result, source: out };
34
+ }
35
+ function run(doc, lines, edit) {
36
+ const index = indexNodes(doc);
37
+ const find = (id) => {
38
+ const node = index.byId.get(id);
39
+ if (!node)
40
+ throw new EditError(`Unknown node "${id}"`);
41
+ return node;
42
+ };
43
+ switch (edit.op) {
44
+ case "set-status": {
45
+ const node = find(edit.id);
46
+ const i = node.line - 1;
47
+ lines[i] = lines[i].replace(/^(\s*[-*]\s+\[)[^\]](\])/, `$1${SYMBOL[edit.status]}$2`);
48
+ return {};
49
+ }
50
+ case "set-title": {
51
+ const node = find(edit.id);
52
+ checkTitle(edit.title);
53
+ lines[node.line - 1] = rewriteNode(lines[node.line - 1], edit.title, node.attrs, node.id);
54
+ return {};
55
+ }
56
+ case "set-attr": {
57
+ const node = find(edit.id);
58
+ if (!ATTR_KEY.test(edit.key))
59
+ throw new EditError(`Invalid attribute key "${edit.key}"`);
60
+ const scalar = (v) => typeof v === "string" || typeof v === "boolean" || (typeof v === "number" && Number.isFinite(v));
61
+ const v = edit.value;
62
+ if (v !== null && !scalar(v) && !(Array.isArray(v) && v.every(scalar))) {
63
+ throw new EditError("Attribute value must be a string, number, boolean or list of those");
64
+ }
65
+ if (typeof v === "string" && /[\r\n]/.test(v))
66
+ throw new EditError("Attribute value must be a single line");
67
+ if (edit.key === "star" && v !== null && typeof v !== "boolean")
68
+ throw new EditError("star must be true or false");
69
+ // Key order is kept; a new key goes last. Unstarring removes the key instead of writing false.
70
+ const attrs = { ...node.attrs };
71
+ if (v === null || (edit.key === "star" && v === false))
72
+ delete attrs[edit.key];
73
+ else
74
+ attrs[edit.key] = v;
75
+ lines[node.line - 1] = rewriteNode(lines[node.line - 1], node.title, attrs, node.id);
76
+ return {};
77
+ }
78
+ case "add-node": {
79
+ checkTitle(edit.title);
80
+ const parent = edit.parent === null ? null : find(edit.parent);
81
+ const id = edit.id ?? uniqueId(slug(edit.title), index.byId);
82
+ if (!HAND_ID.test(id) && !GEN_ID.test(id))
83
+ throw new EditError(`Invalid ID "${id}"`);
84
+ if (index.byId.has(id))
85
+ throw new EditError(`ID "${id}" already exists`);
86
+ const siblings = parent ? parent.children : doc.nodes;
87
+ const indent = siblings.length > 0
88
+ ? splitIndent(lines[siblings[0].line - 1]).indent
89
+ : parent ? splitIndent(lines[parent.line - 1]).indent + 2 : 0;
90
+ // Insert after the last line of the parent's subtree (or of the last root).
91
+ const anchor = parent ?? doc.nodes[doc.nodes.length - 1];
92
+ const at = anchor ? lastLine(anchor) : bodyStart(lines);
93
+ lines.splice(at, 0, nodeLine(indent, SYMBOL[edit.status ?? "todo"], edit.title, {}, id));
94
+ return { id };
95
+ }
96
+ case "remove-node": {
97
+ const node = find(edit.id);
98
+ if (node.children.length > 0 && !edit.recursive) {
99
+ throw new EditError(`Node "${edit.id}" has children; pass recursive to remove the subtree`);
100
+ }
101
+ const removed = subtree(node).map((n) => n.id).filter((id) => id !== null);
102
+ const gone = new Set(removed);
103
+ lines.splice(node.line - 1, lastLine(node) - node.line + 1);
104
+ // rewriteEdges re-reads lines, so it is safe after the splice shifted them.
105
+ rewriteEdges(lines, (from, _kind, to) => (gone.has(from) ? [] : to.filter((t) => !gone.has(t))));
106
+ return { removed };
107
+ }
108
+ case "rename-id": {
109
+ const node = find(edit.id);
110
+ if (!HAND_ID.test(edit.to))
111
+ throw new EditError(`Invalid ID "${edit.to}"`);
112
+ if (index.byId.has(edit.to))
113
+ throw new EditError(`ID "${edit.to}" already exists`);
114
+ const i = node.line - 1;
115
+ lines[i] = lines[i].replace(new RegExp(`\\^${escapeRe(edit.id)}\\s*$`), `^${edit.to}`);
116
+ rewriteEdges(lines, (_from, _kind, to) => to.map((t) => (t === edit.id ? edit.to : t)), (from) => from === edit.id ? edit.to : from);
117
+ return { renamed: { from: edit.id, to: edit.to } };
118
+ }
119
+ case "add-edge": {
120
+ find(edit.from);
121
+ find(edit.to);
122
+ if (!EDGE_KINDS.has(edit.kind))
123
+ throw new EditError(`Unknown edge kind "${edit.kind}"`);
124
+ const label = edit.label ?? null;
125
+ if (doc.edges.some((e) => e.kind === edit.kind && e.label === label
126
+ && ((e.from === edit.from && e.to === edit.to)
127
+ || (edit.kind === "relates" && !label && e.from === edit.to && e.to === edit.from)))) {
128
+ throw new EditError("Edge already exists");
129
+ }
130
+ const hasEdges = lines.some((l) => isEdgeLine(l));
131
+ if (!hasEdges && lines.length > 0 && lines[lines.length - 1].trim() !== "")
132
+ lines.push("");
133
+ lines.push(edgeLine(edit.from, edit.kind, [edit.to], edit.label ?? null));
134
+ return {};
135
+ }
136
+ case "remove-edge": {
137
+ let hit = false;
138
+ rewriteEdges(lines, (from, kind, to) => {
139
+ if (from !== edit.from || kind !== edit.kind)
140
+ return to;
141
+ const kept = to.filter((t) => t !== edit.to);
142
+ hit ||= kept.length !== to.length;
143
+ return kept;
144
+ });
145
+ if (!hit)
146
+ throw new EditError("Edge not found");
147
+ return {};
148
+ }
149
+ case "move-node":
150
+ throw new EditError("move-node is not implemented yet");
151
+ }
152
+ }
153
+ function indexNodes(doc) {
154
+ const byId = new Map();
155
+ const walk = (nodes) => {
156
+ for (const n of nodes) {
157
+ if (n.id !== null && !byId.has(n.id))
158
+ byId.set(n.id, n);
159
+ walk(n.children);
160
+ }
161
+ };
162
+ walk(doc.nodes);
163
+ return { byId };
164
+ }
165
+ function subtree(node) {
166
+ return [node, ...node.children.flatMap(subtree)];
167
+ }
168
+ /** Last 1-based line that belongs to the node: itself, its notes and its descendants. */
169
+ function lastLine(node) {
170
+ let last = node.line;
171
+ for (const n of node.notes)
172
+ last = Math.max(last, n.line);
173
+ for (const c of node.children)
174
+ last = Math.max(last, lastLine(c));
175
+ return last;
176
+ }
177
+ function bodyStart(lines) {
178
+ if (lines[0]?.trimEnd() !== "---")
179
+ return 0;
180
+ const end = lines.findIndex((l, i) => i > 0 && l.trimEnd() === "---");
181
+ return end + 1;
182
+ }
183
+ function countErrors(doc) {
184
+ return doc.diagnostics.filter((d) => d.level === "error").length;
185
+ }
186
+ function checkTitle(title) {
187
+ if (title.trim() === "")
188
+ throw new EditError("Title must not be empty");
189
+ if (/[\r\n]/.test(title))
190
+ throw new EditError("Title must be a single line");
191
+ }
192
+ /** Rebuilds a node line, keeping its indentation, list marker and status symbol as written. */
193
+ function rewriteNode(line, title, attrs, id) {
194
+ const prefix = /^(\s*[-*]\s+\[[^\]]\])/.exec(line)?.[1];
195
+ if (!prefix)
196
+ throw new EditError("Not a node line");
197
+ let text = `${prefix} ${escapeTitle(title)}`;
198
+ if (Object.keys(attrs).length > 0)
199
+ text += ` ${formatAttrs(attrs)}`;
200
+ if (id)
201
+ text += ` ^${id}`;
202
+ return text;
203
+ }
204
+ function nodeLine(indent, symbol, title, attrs, id) {
205
+ let text = `${" ".repeat(indent)}- [${symbol}] ${escapeTitle(title)}`;
206
+ if (Object.keys(attrs).length > 0)
207
+ text += ` ${formatAttrs(attrs)}`;
208
+ if (id)
209
+ text += ` ^${id}`;
210
+ return text;
211
+ }
212
+ /** Escape only what the parser would otherwise strip as a trailing `^id` or `{attrs}`. */
213
+ function escapeTitle(title) {
214
+ let t = title.trim();
215
+ t = t.replace(/(^|\s)\^(\S+)$/, "$1\\^$2");
216
+ if (t.endsWith("}")) {
217
+ const open = t.lastIndexOf("{");
218
+ if (open >= 0 && (open === 0 || /\s/.test(t[open - 1])))
219
+ t = t.slice(0, open) + "\\" + t.slice(open);
220
+ }
221
+ return t;
222
+ }
223
+ export function formatAttrs(attrs) {
224
+ const value = (v) => {
225
+ if (Array.isArray(v))
226
+ return `[${v.map(value).join(", ")}]`;
227
+ if (typeof v === "string") {
228
+ // Plain only when YAML would read it back as the same string.
229
+ const plain = /^[\w./@-][\w ./@-]*$/.test(v) && v.trim() === v
230
+ && !/^(true|false|null|~|yes|no|on|off|[-+]?(\d[\d_]*)?\.?\d+([eE][-+]?\d+)?|0x[\da-f]+|0o[0-7]+)$/i.test(v);
231
+ return plain ? v : JSON.stringify(v);
232
+ }
233
+ return JSON.stringify(v);
234
+ };
235
+ return `{${Object.entries(attrs).map(([k, v]) => `${k}: ${value(v)}`).join(", ")}}`;
236
+ }
237
+ function edgeLine(from, kind, to, label) {
238
+ return `${from} ${kind} ${to.join(", ")}${label ? `: ${label}` : ""}`;
239
+ }
240
+ function isEdgeLine(line) {
241
+ if (/^\s/.test(line))
242
+ return false;
243
+ try {
244
+ return parseLine(line.trimEnd(), { startRule: "Line" }).type === "edge";
245
+ }
246
+ catch {
247
+ return false;
248
+ }
249
+ }
250
+ /**
251
+ * Rewrites every edge statement. `targets` returns the new target list (empty deletes the
252
+ * line); `source` optionally renames the source ID. Lines that do not change are left as is.
253
+ */
254
+ function rewriteEdges(lines, targets, source = (f) => f) {
255
+ for (let i = lines.length - 1; i >= bodyStart(lines); i--) {
256
+ const line = lines[i];
257
+ if (!isEdgeLine(line))
258
+ continue;
259
+ const e = parseLine(line.trimEnd(), { startRule: "Line" });
260
+ if (e.from.file !== null || e.to.some((t) => t.file !== null))
261
+ continue;
262
+ const oldTo = e.to.map((t) => t.id);
263
+ const newTo = targets(e.from.id, e.kind, oldTo);
264
+ const newFrom = source(e.from.id);
265
+ if (newTo.length === 0) {
266
+ lines.splice(i, 1);
267
+ }
268
+ else if (newFrom !== e.from.id || newTo.join(",") !== oldTo.join(",")) {
269
+ lines[i] = edgeLine(newFrom, e.kind, newTo, e.label);
270
+ }
271
+ }
272
+ }
273
+ function slug(title) {
274
+ return title
275
+ .toLowerCase()
276
+ .replace(/[^a-z0-9]+/g, "-")
277
+ .replace(/^-+|-+$/g, "")
278
+ .slice(0, 40)
279
+ .replace(/-+$/, "");
280
+ }
281
+ function uniqueId(base, taken) {
282
+ if (base === "")
283
+ return generateId(taken);
284
+ if (!taken.has(base))
285
+ return base;
286
+ for (let n = 2;; n++)
287
+ if (!taken.has(`${base}-${n}`))
288
+ return `${base}-${n}`;
289
+ }
290
+ const BASE32 = "abcdefghijklmnopqrstuvwxyz234567";
291
+ /** `_` + 6 random base32 characters, unique among `taken`. */
292
+ export function generateId(taken) {
293
+ for (;;) {
294
+ const id = "_" + [...randomBytes(6)].map((b) => BASE32[b % 32]).join("");
295
+ if (!taken.has(id))
296
+ return id;
297
+ }
298
+ }
299
+ function escapeRe(s) {
300
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
301
+ }
302
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../src/edit.ts"],"names":[],"mappings":"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"}