@dmthepm/commune 0.4.0 → 0.5.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
@@ -265,6 +265,20 @@ Exit codes report whether the command finished, never what it found — `0` fini
265
265
 
266
266
  `commune --help` prints the full surface. `commune --version` prints the installed version, which is the honest way to know what you have.
267
267
 
268
+ ## Author with the skills
269
+
270
+ The loop above the CLI ships as four agent skills, in `skills/`, installed straight from this repository rather than from npm:
271
+
272
+ ```bash
273
+ npx skills add dmthepm/commune-wiki
274
+ ```
275
+
276
+ They install for Claude Code and Codex, globally or into one project, and they drive the `commune` your wiki already has — `node_modules/.bin/commune`, called by path, never downloaded — so the CLI a skill runs is the one your site builds with. They need 0.4.0 or newer, they check that first, and they install nothing themselves.
277
+
278
+ The loop is one dump, four files and two places it stops for you. `commune-dump` takes a dictated or pasted dump, writes it verbatim to `dumps/<date>-<slug>.md`, and asks the graph what it already touches — what it mentions, which of the target's links a rewrite would put at risk, which subjects have no note yet — into `dumps/<slug>.connect.md`. `commune-write` reads your `WRITING.md`, asks one short round of questions whose answers each change a file, stops while you answer them in `dumps/<slug>.answers.md`, then drafts into the real note and renders the original and the draft side by side as `dumps/<slug>.review.html`. `commune-ship` diffs `check` against the baseline, files the `updates` entry, builds, gates, greps `dist/` for every new href, commits and opens the PR — and never merges, because the last word is yours. `commune-setup` runs once per wiki and writes the `WRITING.md` the other three obey.
279
+
280
+ Status, honestly: the skills, their test and the `WRITING.md` template are here. The loop has been run once end to end by hand, before it was skills; it has not yet been run as skills on a real wiki. That run is [#10](https://github.com/dmthepm/commune-wiki/issues/10), and this paragraph changes when it lands.
281
+
268
282
  ## What it is not
269
283
 
270
284
  It is not a note-taking app and it is not trying to replace one. I write in Obsidian; Commune is what turns the vault into a site. There is no editor here, no sync, no account, no server. The graph is computed from files on disk at build time, and the files are yours whether or not you ever run this.
@@ -273,7 +287,7 @@ It is not a note-taking app and it is not trying to replace one. I write in Obsi
273
287
 
274
288
  Commune is the engine under a larger idea: own your canon. The wiki is one output surface, not the product. What I am building toward is an authoring loop — dictate a dump, have agents find what it already connects to, grill it, draft it, ship it — where the graph is what makes connection-finding possible *before* a draft exists. That is why the graph is a queryable library with a CLI on top instead of a build artifact, and why `graph related` reads stdin.
275
289
 
276
- None of that loop is in this package. `pnpm add @dmthepm/commune` gives you the engine and the CLI above, and nothing else. The authoring skills and the email destination are tracked in [the issues](https://github.com/dmthepm/commune-wiki/issues); when they ship, this section shrinks and the one above it grows.
290
+ The authoring half of that loop is here now, as the four skills above; `pnpm add @dmthepm/commune` still gives you the engine and the CLI and nothing else, which is what those skills drive. What is left — the email destination, the weekly intake from GitHub activity — is tracked in [the issues](https://github.com/dmthepm/commune-wiki/issues).
277
291
 
278
292
  ## Deploy
279
293
 
@@ -163,6 +163,14 @@ export declare function loadContentEntries(options?: GraphOptions): Promise<Cont
163
163
  * matters when two pieces of content claim the same name, and is a content bug
164
164
  * either way.
165
165
  */
166
+ /**
167
+ * The key a wikilink is looked up by. Case-folded, and typographic quotes
168
+ * folded to their ASCII forms: a title in frontmatter is written with a
169
+ * straight apostrophe, but by the time the remark plugin sees the link text
170
+ * smartypants has curled it, so `[[Andy's Notes]]` arrived as `Andy’s Notes`
171
+ * and rendered as plain text.
172
+ */
173
+ export declare function linkKey(name: string): string;
166
174
  export declare function buildLinkLookup(entries: ContentEntry[]): Map<string, LinkTarget>;
167
175
  /**
168
176
  * Build the url resolution table: canonical `urlPath` → target.
package/lib/lib/graph.js CHANGED
@@ -243,6 +243,20 @@ export async function loadContentEntries(options = {}) {
243
243
  * matters when two pieces of content claim the same name, and is a content bug
244
244
  * either way.
245
245
  */
246
+ /**
247
+ * The key a wikilink is looked up by. Case-folded, and typographic quotes
248
+ * folded to their ASCII forms: a title in frontmatter is written with a
249
+ * straight apostrophe, but by the time the remark plugin sees the link text
250
+ * smartypants has curled it, so `[[Andy's Notes]]` arrived as `Andy’s Notes`
251
+ * and rendered as plain text.
252
+ */
253
+ export function linkKey(name) {
254
+ return name
255
+ .trim()
256
+ .replace(/[\u2018\u2019\u02BC]/g, "'")
257
+ .replace(/[\u201C\u201D]/g, '"')
258
+ .toLowerCase();
259
+ }
246
260
  export function buildLinkLookup(entries) {
247
261
  const lookup = new Map();
248
262
  for (const entry of entries) {
@@ -252,9 +266,9 @@ export function buildLinkLookup(entries) {
252
266
  urlPath: entry.urlPath,
253
267
  };
254
268
  for (const alias of entry.aliases) {
255
- lookup.set(alias.toLowerCase(), target);
269
+ lookup.set(linkKey(alias), target);
256
270
  }
257
- lookup.set(entry.title.toLowerCase(), target);
271
+ lookup.set(linkKey(entry.title), target);
258
272
  }
259
273
  return lookup;
260
274
  }
@@ -10,7 +10,7 @@
10
10
  * graph core in `src/lib/graph.ts` — not here.
11
11
  */
12
12
  import { visit } from 'unist-util-visit';
13
- import { getLinkLookup } from "./lib/graph.js";
13
+ import { getLinkLookup, linkKey } from "./lib/graph.js";
14
14
  /**
15
15
  * Remark plugin function.
16
16
  *
@@ -49,8 +49,7 @@ export default function remarkWikiLinks({ root } = {}) {
49
49
  }
50
50
  // Resolve WikiLink to URL path
51
51
  const trimmedLinkText = linkText.trim();
52
- const lookupKey = trimmedLinkText.toLowerCase();
53
- const resolved = lookup.get(lookupKey);
52
+ const resolved = lookup.get(linkKey(trimmedLinkText));
54
53
  if (resolved) {
55
54
  // Create a proper link node with correct URL for collection
56
55
  // Add data-collection attribute to identify research links for styling
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dmthepm/commune",
3
3
  "type": "module",
4
- "version": "0.4.0",
4
+ "version": "0.5.1",
5
5
  "description": "An Astro wiki engine with WikiLinks, sliding panes, backlinks and static search, plus a commune CLI that queries the content graph and checks links",
6
6
  "license": "MIT",
7
7
  "keywords": [