@dmthepm/commune 0.1.0 → 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 +95 -405
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,468 +1,158 @@
|
|
|
1
|
-
# Commune
|
|
1
|
+
# Commune
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A wiki engine for Astro, and a CLI that queries the wiki's link graph without running a build.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Write markdown. Link notes with `[[double brackets]]`. Get a static site where every link resolves both ways, every page has a plain-markdown twin, and the whole graph is one JSON file you can also query from a terminal.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## ✨ Features
|
|
10
|
-
|
|
11
|
-
- 🔗 **WikiLinks**: `[[Note Title]]` automatically converts to links
|
|
12
|
-
- 📑 **Sliding Panes**: Andy Matuschak-style cascading note navigation
|
|
13
|
-
- 👁️ **Hover Previews**: See note content on hover before clicking
|
|
14
|
-
- 🔄 **Backlinks**: Auto-generated bidirectional link graph
|
|
15
|
-
- 🎨 **Design System**: Custom CSS variables with light/dark mode
|
|
16
|
-
- 🔍 **Search**: Cmd-K palette with Pagefind static search
|
|
17
|
-
- 📝 **Markdown-First**: Git-backed content, version controlled
|
|
18
|
-
- 🚀 **Fast**: Static site generation (no runtime database)
|
|
19
|
-
- 🎯 **Zero Config**: Works out of the box, customize as needed
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 🎯 Who Is This For?
|
|
7
|
+
MIT. It runs [devon.md](https://devon.md).
|
|
24
8
|
|
|
25
|
-
|
|
26
|
-
- Researchers building interconnected notes (Zettelkasten/Evergreen Notes)
|
|
27
|
-
- Writers managing drafts, research, and published content
|
|
28
|
-
- Developers documenting code, decisions, and learnings
|
|
29
|
-
- Anyone tired of silo'd notes in proprietary apps
|
|
9
|
+
## Install
|
|
30
10
|
|
|
31
|
-
|
|
32
|
-
| Tool | Approach | Commune Wiki |
|
|
33
|
-
|------|----------|--------------|
|
|
34
|
-
| Obsidian | Desktop app, proprietary sync | Web-first, self-hosted, MIT |
|
|
35
|
-
| Notion | Cloud SaaS, vendor lock-in | Git-backed, own your data |
|
|
36
|
-
| Roam | SaaS, $15/mo | Free, open source, MIT |
|
|
37
|
-
| Logseq | Local-first, complex setup | Simple Astro build, deploy anywhere |
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 🚀 Quick Start
|
|
42
|
-
|
|
43
|
-
### Prerequisites
|
|
44
|
-
|
|
45
|
-
- Node.js 22.18+ and pnpm
|
|
46
|
-
|
|
47
|
-
### Install & Run
|
|
11
|
+
You need an Astro 7 project on Node 22.12 or newer.
|
|
48
12
|
|
|
49
13
|
```bash
|
|
50
|
-
|
|
51
|
-
git clone git@github.com:dmthepm/commune-wiki.git
|
|
52
|
-
cd commune-wiki
|
|
53
|
-
|
|
54
|
-
# Install dependencies
|
|
55
|
-
pnpm install
|
|
56
|
-
|
|
57
|
-
# Start dev server (http://localhost:4321)
|
|
58
|
-
pnpm dev
|
|
59
|
-
|
|
60
|
-
# Build for production
|
|
61
|
-
pnpm build
|
|
62
|
-
|
|
63
|
-
# Preview production build
|
|
64
|
-
pnpm preview
|
|
14
|
+
pnpm add @dmthepm/commune @astrojs/markdown-remark
|
|
65
15
|
```
|
|
66
16
|
|
|
67
|
-
|
|
17
|
+
Then three files, and your notes. `astro.config.mjs`, in full:
|
|
68
18
|
|
|
69
|
-
|
|
19
|
+
```js
|
|
20
|
+
import { defineConfig } from 'astro/config';
|
|
21
|
+
import commune from '@dmthepm/commune/astro';
|
|
22
|
+
import { communeMarkdown } from '@dmthepm/commune/markdown';
|
|
70
23
|
|
|
71
|
-
|
|
72
|
-
pnpm add @dmthepm/commune
|
|
73
|
-
```
|
|
24
|
+
const site = 'https://example.com';
|
|
74
25
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
`pnpm add github:dmthepm/commune-wiki#<tag>` — and pnpm consumers need one
|
|
81
|
-
extra line for it, because a git dependency arrives as source and compiles
|
|
82
|
-
itself in its `prepare` script. pnpm 10 refuses to run that unless your
|
|
83
|
-
project names the package, and without the entry the install fails with
|
|
84
|
-
`ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED`. The details are folded below; all
|
|
85
|
-
of it goes away on the first npm publish, which is what this footnote is
|
|
86
|
-
counting down to.
|
|
87
|
-
|
|
88
|
-
<details>
|
|
89
|
-
<summary>Installing from a git ref, in full</summary>
|
|
90
|
-
|
|
91
|
-
```jsonc
|
|
92
|
-
// your package.json
|
|
93
|
-
{
|
|
94
|
-
"dependencies": {
|
|
95
|
-
"@dmthepm/commune": "github:dmthepm/commune-wiki#<tag>"
|
|
96
|
-
},
|
|
97
|
-
"pnpm": {
|
|
98
|
-
"onlyBuiltDependencies": ["@dmthepm/commune@github:dmthepm/commune-wiki#<tag>"]
|
|
99
|
-
}
|
|
100
|
-
}
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
site,
|
|
28
|
+
markdown: { processor: communeMarkdown({ site }) },
|
|
29
|
+
integrations: [commune()],
|
|
30
|
+
});
|
|
101
31
|
```
|
|
102
32
|
|
|
103
|
-
|
|
104
|
-
package from the registry, and for a git dependency pnpm matches the whole
|
|
105
|
-
specifier, so a name on its own is silently not a match. It has to be the same
|
|
106
|
-
specifier you wrote in `dependencies`, which means it changes when you bump the
|
|
107
|
-
tag. The same entry works in `pnpm-workspace.yaml` if you keep pnpm settings
|
|
108
|
-
there.
|
|
109
|
-
|
|
110
|
-
**Older pnpm 10 wants the other spelling.** Around 10.19 the `name@spec` form is
|
|
111
|
-
rejected with `ERR_PNPM_INVALID_VERSION_UNION` ("Use exact versions only") and
|
|
112
|
-
the bare `"@dmthepm/commune"` is what works — those releases also approve a git
|
|
113
|
-
dependency's build scripts on their own, so you may need nothing at all. Do not
|
|
114
|
-
guess which side of the line you are on: run the install and read the error.
|
|
115
|
-
pnpm prints the exact entry your version expects.
|
|
33
|
+
Astro 7 renders markdown with Sätteri and no longer installs the unified pipeline, so `markdown.processor` is where the wikilink plugins have to go. `site` is a parameter because the engine has no host of its own — it decides what counts as an external link against your origin, which you already declare once.
|
|
116
34
|
|
|
117
|
-
|
|
118
|
-
asking.
|
|
35
|
+
Commune reads markdown off disk, but Astro will not render a page for it until the collection is registered and something routes it — so copy these two files. `src/content.config.ts`:
|
|
119
36
|
|
|
120
|
-
|
|
37
|
+
```ts
|
|
38
|
+
import { defineCollection, z } from 'astro:content';
|
|
39
|
+
import { glob } from 'astro/loaders';
|
|
121
40
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
summary: "My first note"
|
|
132
|
-
tags: [getting-started]
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
Welcome to your personal wiki!
|
|
136
|
-
|
|
137
|
-
Link to other notes with [[Note Title]] syntax.
|
|
138
|
-
MDEOF
|
|
139
|
-
|
|
140
|
-
# Start dev server and visit http://localhost:4321
|
|
141
|
-
pnpm dev
|
|
41
|
+
export const collections = {
|
|
42
|
+
notes: defineCollection({
|
|
43
|
+
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/notes' }),
|
|
44
|
+
schema: z.object({
|
|
45
|
+
title: z.string(),
|
|
46
|
+
visibility: z.enum(['public', 'private', 'draft']).default('private'),
|
|
47
|
+
}),
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
142
50
|
```
|
|
143
51
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
## 📁 Project Structure
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
commune-wiki/
|
|
150
|
-
├── src/
|
|
151
|
-
│ ├── content/
|
|
152
|
-
│ │ ├── config.ts # Content collection schemas
|
|
153
|
-
│ │ └── notes/ # Your markdown notes
|
|
154
|
-
│ ├── components/
|
|
155
|
-
│ │ ├── Header.astro # Site header
|
|
156
|
-
│ │ ├── SearchModal.astro
|
|
157
|
-
│ │ └── Backlinks.astro
|
|
158
|
-
│ ├── pages/
|
|
159
|
-
│ │ ├── index.astro # Homepage
|
|
160
|
-
│ │ └── notes/
|
|
161
|
-
│ │ └── [...slug].astro # Note pages + pane logic
|
|
162
|
-
│ └── styles/
|
|
163
|
-
│ ├── design-system.css # Custom CSS variables
|
|
164
|
-
│ └── notes.css # Note typography
|
|
165
|
-
├── public/
|
|
166
|
-
│ └── backlinks.json # Auto-generated backlinks graph
|
|
167
|
-
├── astro.config.mjs # Astro config + remark plugins
|
|
168
|
-
└── package.json
|
|
169
|
-
```
|
|
52
|
+
And `src/pages/notes/[...slug].astro`:
|
|
170
53
|
|
|
54
|
+
```astro
|
|
171
55
|
---
|
|
56
|
+
import { getCollection, render } from 'astro:content';
|
|
172
57
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
Every note requires frontmatter:
|
|
58
|
+
export async function getStaticPaths() {
|
|
59
|
+
const notes = await getCollection('notes', (note) => note.data.visibility === 'public');
|
|
60
|
+
return notes.map((note) => ({ params: { slug: note.id }, props: { note } }));
|
|
61
|
+
}
|
|
178
62
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
title: "Note Title"
|
|
182
|
-
visibility: "public" # public | private | draft
|
|
183
|
-
status: "evergreen" # seed | growing | evergreen
|
|
184
|
-
summary: "Brief description for previews"
|
|
185
|
-
tags: [tag1, tag2]
|
|
186
|
-
aliases: ["Short Name"]
|
|
187
|
-
updated: 2025-10-21
|
|
63
|
+
const { note } = Astro.props;
|
|
64
|
+
const { Content } = await render(note);
|
|
188
65
|
---
|
|
189
66
|
|
|
190
|
-
|
|
67
|
+
<html lang="en">
|
|
68
|
+
<head><meta charset="utf-8" /><title>{note.data.title}</title></head>
|
|
69
|
+
<body><h1>{note.data.title}</h1><Content /></body>
|
|
70
|
+
</html>
|
|
191
71
|
```
|
|
192
72
|
|
|
193
|
-
|
|
194
|
-
- `public` - Published to site (default: only public notes shown)
|
|
195
|
-
- `private` - Not published
|
|
196
|
-
- `draft` - Work in progress, not indexed
|
|
197
|
-
|
|
198
|
-
**Status**:
|
|
199
|
-
- `seed` - Early idea, needs development
|
|
200
|
-
- `growing` - Actively being refined
|
|
201
|
-
- `evergreen` - Well-developed, stable
|
|
73
|
+
Both are the smallest versions that work. [`tests/fixtures/consumer`](tests/fixtures/consumer) is the same project one step further along — it adds the `research` and `pages` collections and imports components off the package — and it is the reference to read when you want the fuller shape.
|
|
202
74
|
|
|
203
|
-
|
|
75
|
+
Notes go in `src/content/notes/`. Two frontmatter fields are load-bearing:
|
|
204
76
|
|
|
205
77
|
```markdown
|
|
206
|
-
[[Note Title]] → Links to note
|
|
207
|
-
[[Note Title|Display Text]] → Custom text
|
|
208
|
-
[[Multi-word Note]] → Normalized matching
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**How it works**:
|
|
212
|
-
1. Build-time plugin scans all notes
|
|
213
|
-
2. Creates title → slug lookup index
|
|
214
|
-
3. Transforms `[[Title]]` to `<a href="/notes/slug/">`
|
|
215
|
-
4. Broken links render as plain text (not clickable)
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## 🎨 Customization
|
|
220
|
-
|
|
221
|
-
### Design System
|
|
222
|
-
|
|
223
|
-
Edit `src/styles/design-system.css`:
|
|
224
|
-
|
|
225
|
-
```css
|
|
226
|
-
:root {
|
|
227
|
-
--c-bg: #0a0a0b;
|
|
228
|
-
--c-accent: #8b7bff;
|
|
229
|
-
--c-text: #e8e6e3;
|
|
230
|
-
/* ... customize colors ... */
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
[data-theme="light"] {
|
|
234
|
-
--c-bg: #fafaf9;
|
|
235
|
-
/* ... light mode overrides ... */
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Typography
|
|
240
|
-
|
|
241
|
-
Edit `src/styles/notes.css` for note-specific styling (headings, lists, code blocks).
|
|
242
|
-
|
|
243
|
-
### Pane Behavior
|
|
244
|
-
|
|
245
|
-
Pane logic in `src/pages/notes/[...slug].astro`:
|
|
246
|
-
|
|
247
|
-
```javascript
|
|
248
|
-
// Customize pane behavior:
|
|
249
|
-
setupPanes() // Initialize
|
|
250
|
-
openPane(url) // Open new pane
|
|
251
|
-
closePane(pane) // Remove pane
|
|
252
|
-
```
|
|
253
|
-
|
|
254
78
|
---
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
**Pagefind** generates a static search index at build time:
|
|
259
|
-
|
|
260
|
-
- No server required
|
|
261
|
-
- Instant client-side search
|
|
262
|
-
- Automatically indexes all public notes
|
|
263
|
-
- Cmd-K hotkey to open search modal
|
|
264
|
-
|
|
265
|
-
**Dev mode**: Falls back to backlinks.json when Pagefind not available.
|
|
266
|
-
|
|
267
|
-
---
|
|
268
|
-
|
|
269
|
-
## 📊 Backlinks
|
|
270
|
-
|
|
271
|
-
Backlinks are auto-generated at build time via the `src/integration.ts` integration:
|
|
272
|
-
|
|
273
|
-
1. Scans all notes for WikiLinks
|
|
274
|
-
2. Creates bidirectional graph
|
|
275
|
-
3. Outputs to `public/backlinks.json` and `<outDir>/backlinks.json`
|
|
276
|
-
4. Displayed in `Backlinks.astro` component ("Links to this note")
|
|
277
|
-
|
|
79
|
+
title: "Hello"
|
|
80
|
+
visibility: "public"
|
|
278
81
|
---
|
|
279
82
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
### Static Hosting (Recommended)
|
|
283
|
-
|
|
284
|
-
**Cloudflare Pages / Vercel / Netlify**:
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
# Build command
|
|
288
|
-
pnpm build
|
|
289
|
-
|
|
290
|
-
# Output directory
|
|
291
|
-
dist/
|
|
292
|
-
|
|
293
|
-
# Deploy
|
|
294
|
-
# Connect GitHub repo, auto-deploy on push
|
|
83
|
+
A link to [[World]], and one to [Astro](https://astro.build).
|
|
295
84
|
```
|
|
296
85
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
```yaml
|
|
300
|
-
# docker-compose.yml
|
|
301
|
-
caddy:
|
|
302
|
-
image: caddy:alpine
|
|
303
|
-
volumes:
|
|
304
|
-
- ./dist:/srv:ro
|
|
305
|
-
- ./Caddyfile:/etc/caddy/Caddyfile
|
|
306
|
-
ports:
|
|
307
|
-
- "80:80"
|
|
308
|
-
- "443:443"
|
|
309
|
-
```
|
|
86
|
+
`title` is what `[[Hello]]` matches on. `visibility` defaults to private, so only `public` is published. Build that, and the paragraph renders as:
|
|
310
87
|
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
root * /srv
|
|
315
|
-
file_server
|
|
316
|
-
try_files {path} {path}/ /index.html
|
|
317
|
-
encode gzip
|
|
318
|
-
}
|
|
88
|
+
```html
|
|
89
|
+
A link to <a href="/notes/world/" class="wikilink">World</a>, and one to
|
|
90
|
+
<a href="https://astro.build" target="_blank" rel="noopener noreferrer">Astro</a>.
|
|
319
91
|
```
|
|
320
92
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
```bash
|
|
324
|
-
# Install Railway CLI
|
|
325
|
-
npm install -g railway
|
|
326
|
-
|
|
327
|
-
# Deploy
|
|
328
|
-
railway init
|
|
329
|
-
railway up
|
|
330
|
-
```
|
|
93
|
+
That route is a starting point, not an interface. The package ships the mechanism and none of `src/pages/` — the markup, the layout and the URL shape are yours to change, and Commune keeps the links inside them working.
|
|
331
94
|
|
|
332
|
-
|
|
95
|
+
## What ships
|
|
333
96
|
|
|
334
|
-
|
|
97
|
+
- **WikiLinks.** `[[Title]]` and `[[Title|Display text]]` become real hrefs at build time, matched against titles and aliases. A link that resolves to nothing stays plain text instead of rendering a dead anchor.
|
|
98
|
+
- **Backlinks.** The build writes `backlinks.json` — every entry with its inbound and outbound edges — to `dist/` and `public/`. `Backlinks.astro` renders it on a page.
|
|
99
|
+
- **Markdown twins.** Every published content entry gets its source written beside it, so `/notes/hello/` also answers at `/notes/hello.md`. Entries in the content directories only — a hand-written route under `src/pages/` has no source file to twin. Agents and readers get the same document without scraping HTML.
|
|
100
|
+
- **External links.** Anything off your `site` origin gets `target="_blank" rel="noopener noreferrer"` without you marking it up.
|
|
101
|
+
- **The graph as a library.** `@dmthepm/commune/graph` exports the content loader, the link resolver and the graph builder. The Astro build and the CLI both call it. That is the point: one resolver, not two that drift.
|
|
102
|
+
- **Components and stylesheets.** `@dmthepm/commune/components/*.astro` and `@dmthepm/commune/styles/*.css`, shipped as source. These are the components off my own site rather than a theme system — take them as a starting point, not an API.
|
|
335
103
|
|
|
336
|
-
##
|
|
104
|
+
## The CLI
|
|
337
105
|
|
|
338
|
-
|
|
106
|
+
`commune` installs as a bin. It reads markdown off disk and answers without an Astro process running, which is what makes it useful while you are still writing.
|
|
339
107
|
|
|
340
108
|
```bash
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
109
|
+
commune check
|
|
110
|
+
commune graph query --collection notes --orphans
|
|
111
|
+
commune graph related src/content/notes/hello.md
|
|
112
|
+
echo "a rough dump that mentions World" | commune graph related -
|
|
113
|
+
commune gate
|
|
344
114
|
```
|
|
345
115
|
|
|
346
|
-
|
|
116
|
+
| Verb | What it answers |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `graph query` | Every entry with its edges. Filter with `--collection`, `--tag`, `--status`, `--orphans`, `--deadends`. |
|
|
119
|
+
| `graph related <path\|text\|->` | What this connects to. It takes stdin, so you can ask about a draft before it is a note. |
|
|
120
|
+
| `check` | Broken links, duplicate names, ambiguous targets, non-canonical titles. |
|
|
121
|
+
| `gate` | Run after a build, against the built site. |
|
|
347
122
|
|
|
348
|
-
|
|
349
|
-
# Run the test suite
|
|
350
|
-
pnpm test
|
|
123
|
+
Every verb takes `--json` and emits one document on stdout with everything else on stderr. The human-readable text is the fallback rendering; the JSON is the contract.
|
|
351
124
|
|
|
352
|
-
|
|
353
|
-
node bin/commune.mjs check --json
|
|
125
|
+
Exit codes report whether the command finished, never what it found — `0` finished, `1` could not finish, `2` invalid invocation. Findings live in the payload. A command that exits non-zero because it *found* something is indistinguishable, to a shell, from one that crashed. `gate` is the one deliberate exception: a gate's entire job is a yes/no and a build has to stop on it, so `gate` exits `1` when the build it checked is wrong.
|
|
354
126
|
|
|
355
|
-
|
|
356
|
-
pnpm preview
|
|
357
|
-
```
|
|
127
|
+
`commune --help` prints the full surface. `commune --version` prints the installed version, which is the honest way to know what you have.
|
|
358
128
|
|
|
359
|
-
|
|
129
|
+
## What it is not
|
|
360
130
|
|
|
361
|
-
|
|
131
|
+
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.
|
|
362
132
|
|
|
363
|
-
|
|
364
|
-
# Check cache consistency (should show same count each time)
|
|
365
|
-
pnpm build 2>&1 | grep "Lookup built with"
|
|
133
|
+
## Where this is going
|
|
366
134
|
|
|
367
|
-
|
|
368
|
-
pnpm build 2>&1 | grep "Broken link"
|
|
369
|
-
```
|
|
135
|
+
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.
|
|
370
136
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
## 📦 Tech Stack
|
|
137
|
+
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.
|
|
374
138
|
|
|
375
|
-
|
|
376
|
-
- **Tailwind CSS** - Utility-first styling
|
|
377
|
-
- **Pagefind** - Static search index
|
|
378
|
-
- **remark-wikilinks** - WikiLink transformation plugin (custom, `src/remark-wikilinks.ts`)
|
|
379
|
-
- **No framework dependencies** - Vanilla JS for interactivity
|
|
139
|
+
## Deploy
|
|
380
140
|
|
|
381
|
-
|
|
141
|
+
The build output is `dist/`, a static directory with no runtime, so any static host serves it — see [docs/hosting.md](docs/hosting.md).
|
|
382
142
|
|
|
383
|
-
##
|
|
143
|
+
## Working on Commune itself
|
|
384
144
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
**For Users**:
|
|
392
|
-
- This README covers installation and usage
|
|
393
|
-
- See [devonmeadows.com](https://devonmeadows.com) for live example
|
|
394
|
-
- Issues/questions: [GitHub Issues](https://github.com/dmthepm/commune-wiki/issues)
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## 🤝 Contributing
|
|
399
|
-
|
|
400
|
-
This is an open-source project under the MIT License. Contributions welcome!
|
|
401
|
-
|
|
402
|
-
**How to contribute**:
|
|
403
|
-
1. Fork the repository
|
|
404
|
-
2. Create a feature branch (`git checkout -b feature/your-feature`)
|
|
405
|
-
3. Make changes and test locally (`pnpm dev`)
|
|
406
|
-
4. Build to verify (`pnpm build`)
|
|
407
|
-
5. Commit with clear message
|
|
408
|
-
6. Push and create Pull Request
|
|
409
|
-
|
|
410
|
-
**Areas for contribution**:
|
|
411
|
-
- [ ] Automated tests (Puppeteer or Playwright)
|
|
412
|
-
- [ ] Additional themes/design systems
|
|
413
|
-
- [ ] Search improvements (fuzzy matching, ranking)
|
|
414
|
-
- [ ] Graph visualization of backlinks
|
|
415
|
-
- [ ] Mobile responsiveness improvements
|
|
416
|
-
- [ ] Performance optimizations
|
|
417
|
-
|
|
418
|
-
---
|
|
419
|
-
|
|
420
|
-
## 🐛 Known Issues
|
|
421
|
-
|
|
422
|
-
### WikiLink Cache Bug (FIXED)
|
|
423
|
-
|
|
424
|
-
**Symptom**: Links only work on last note built.
|
|
425
|
-
|
|
426
|
-
**Fix**: Ensure cache size check in `src/remark-wikilinks.ts`:
|
|
427
|
-
|
|
428
|
-
```typescript
|
|
429
|
-
if (notesCache && notesCache.size > 0) { // MUST check .size!
|
|
430
|
-
return buildFromCache();
|
|
431
|
-
}
|
|
145
|
+
```bash
|
|
146
|
+
pnpm install
|
|
147
|
+
pnpm dev # the engine's own wiki, for developing against
|
|
148
|
+
pnpm build # compile lib/, build the site, then gate it
|
|
149
|
+
pnpm test # node --test
|
|
432
150
|
```
|
|
433
151
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
**Symptom**: Panes don't stack correctly.
|
|
437
|
-
|
|
438
|
-
**Fix**: Use `<style is:global>` in `[...slug].astro` for dynamic panes.
|
|
439
|
-
|
|
440
|
-
---
|
|
441
|
-
|
|
442
|
-
## 📄 License
|
|
152
|
+
`pnpm test:consumer` installs `tests/fixtures/consumer` against the working tree and builds it. That fixture is a stranger's project in miniature, and it is the check that catches a package boundary this README describes wrongly.
|
|
443
153
|
|
|
444
|
-
|
|
154
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) has the rest. Issues and questions go to [the tracker](https://github.com/dmthepm/commune-wiki/issues).
|
|
445
155
|
|
|
446
|
-
|
|
447
|
-
- Free to use, modify, distribute, and sell
|
|
448
|
-
- Commercial use allowed, with no obligation to open-source your changes
|
|
449
|
-
- Keep the copyright notice; that's the whole obligation
|
|
450
|
-
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## 🔗 Related Projects
|
|
454
|
-
|
|
455
|
-
**Commune Ecosystem**:
|
|
456
|
-
- **Devon's Homelab** - Personal infrastructure (private, showcase only)
|
|
457
|
-
|
|
458
|
-
**Inspired by**:
|
|
459
|
-
- [Andy Matuschak's Notes](https://notes.andymatuschak.org/)
|
|
460
|
-
- [Maggie Appleton's Digital Garden](https://maggieappleton.com/garden)
|
|
461
|
-
- [Obsidian](https://obsidian.md/) (proprietary alternative)
|
|
462
|
-
- [Logseq](https://logseq.com/) (local-first alternative)
|
|
463
|
-
|
|
464
|
-
---
|
|
156
|
+
## License
|
|
465
157
|
|
|
466
|
-
|
|
467
|
-
**Repository**: [dmthepm/commune-wiki](https://github.com/dmthepm/commune-wiki)
|
|
468
|
-
**Support**: [GitHub Issues](https://github.com/dmthepm/commune-wiki/issues)
|
|
158
|
+
MIT — see [LICENSE](LICENSE). Use it, change it, sell it. Keep the copyright notice; that is the whole obligation.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dmthepm/commune",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.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": [
|
|
@@ -80,21 +80,20 @@
|
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"github-slugger": "^2.0.0",
|
|
83
|
-
"globby": "^
|
|
83
|
+
"globby": "^16.2.4",
|
|
84
84
|
"gray-matter": "^4.0.3",
|
|
85
|
-
"unist-util-visit": "^5.
|
|
85
|
+
"unist-util-visit": "^5.1.0"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@astrojs/check": "^0.9.
|
|
88
|
+
"@astrojs/check": "^0.9.10",
|
|
89
89
|
"@astrojs/markdown-remark": "^7.3.0",
|
|
90
90
|
"@astrojs/sitemap": "^3.7.4",
|
|
91
|
-
"@tailwindcss/typography": "^0.5.
|
|
91
|
+
"@tailwindcss/typography": "^0.5.20",
|
|
92
92
|
"@types/hast": "^3.0.5",
|
|
93
93
|
"@types/mdast": "^4.0.4",
|
|
94
94
|
"@types/node": "^22.20.1",
|
|
95
95
|
"astro": "^7.2.10",
|
|
96
|
-
"autoprefixer": "^10.4
|
|
97
|
-
"puppeteer": "^24.25.0",
|
|
96
|
+
"autoprefixer": "^10.5.4",
|
|
98
97
|
"tailwindcss": "^3.4.0",
|
|
99
98
|
"typescript": "^5.6.0"
|
|
100
99
|
}
|