wiki-spaces 0.1.0__tar.gz

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.
Files changed (44) hide show
  1. wiki_spaces-0.1.0/.gitignore +11 -0
  2. wiki_spaces-0.1.0/AGENTS.md +66 -0
  3. wiki_spaces-0.1.0/CONVENTIONS.md +359 -0
  4. wiki_spaces-0.1.0/LICENSE +21 -0
  5. wiki_spaces-0.1.0/PKG-INFO +166 -0
  6. wiki_spaces-0.1.0/README.md +136 -0
  7. wiki_spaces-0.1.0/bridges/cursor/wiki-spaces.mdc +19 -0
  8. wiki_spaces-0.1.0/bridges/index.md +14 -0
  9. wiki_spaces-0.1.0/bridges/windsurf/wiki-spaces.md +18 -0
  10. wiki_spaces-0.1.0/index.md +22 -0
  11. wiki_spaces-0.1.0/pyproject.toml +67 -0
  12. wiki_spaces-0.1.0/references/EXAMPLES.md +140 -0
  13. wiki_spaces-0.1.0/references/HARNESS_INTEGRATION.md +51 -0
  14. wiki_spaces-0.1.0/references/MOUNT.md +58 -0
  15. wiki_spaces-0.1.0/references/SETUP.md +112 -0
  16. wiki_spaces-0.1.0/references/index.md +14 -0
  17. wiki_spaces-0.1.0/scripts/doctor.py +19 -0
  18. wiki_spaces-0.1.0/scripts/index.md +22 -0
  19. wiki_spaces-0.1.0/scripts/init_wiki.py +19 -0
  20. wiki_spaces-0.1.0/scripts/install.py +19 -0
  21. wiki_spaces-0.1.0/scripts/update.py +19 -0
  22. wiki_spaces-0.1.0/scripts/vendor_kepano.py +19 -0
  23. wiki_spaces-0.1.0/skills/index.md +11 -0
  24. wiki_spaces-0.1.0/skills/wiki-search/SKILL.md +47 -0
  25. wiki_spaces-0.1.0/skills/wiki-tend/SKILL.md +56 -0
  26. wiki_spaces-0.1.0/skills/wiki-update/SKILL.md +88 -0
  27. wiki_spaces-0.1.0/src/wiki_spaces/__init__.py +8 -0
  28. wiki_spaces-0.1.0/src/wiki_spaces/__main__.py +7 -0
  29. wiki_spaces-0.1.0/src/wiki_spaces/_common.py +251 -0
  30. wiki_spaces-0.1.0/src/wiki_spaces/cli.py +62 -0
  31. wiki_spaces-0.1.0/src/wiki_spaces/doctor.py +141 -0
  32. wiki_spaces-0.1.0/src/wiki_spaces/init_wiki.py +221 -0
  33. wiki_spaces-0.1.0/src/wiki_spaces/install.py +193 -0
  34. wiki_spaces-0.1.0/src/wiki_spaces/update.py +47 -0
  35. wiki_spaces-0.1.0/src/wiki_spaces/vendor_kepano.py +91 -0
  36. wiki_spaces-0.1.0/vendor/index.md +11 -0
  37. wiki_spaces-0.1.0/vendor/kepano/COMMIT +3 -0
  38. wiki_spaces-0.1.0/vendor/kepano/index.md +13 -0
  39. wiki_spaces-0.1.0/vendor/kepano/obsidian-bases/SKILL.md +497 -0
  40. wiki_spaces-0.1.0/vendor/kepano/obsidian-bases/references/FUNCTIONS_REFERENCE.md +173 -0
  41. wiki_spaces-0.1.0/vendor/kepano/obsidian-markdown/SKILL.md +196 -0
  42. wiki_spaces-0.1.0/vendor/kepano/obsidian-markdown/references/CALLOUTS.md +58 -0
  43. wiki_spaces-0.1.0/vendor/kepano/obsidian-markdown/references/EMBEDS.md +63 -0
  44. wiki_spaces-0.1.0/vendor/kepano/obsidian-markdown/references/PROPERTIES.md +61 -0
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ .uv-cache/
6
+ dist/
7
+ build/
8
+ .DS_Store
9
+ *.swp
10
+ .idea/
11
+ .vscode/
@@ -0,0 +1,66 @@
1
+ # AGENTS.md
2
+
3
+ The wiki-spaces spec. Vocabulary, structure, and the operating contract for an LLM working in a wiki-spaces wiki.
4
+
5
+ ## What a wiki is
6
+
7
+ A wiki is a folder with `index.md`. That's it.
8
+
9
+ You can stop here — a folder, an `index.md`, and whatever files you want is a complete wiki. The rest of this doc describes what's *possible* on top of that, not what's required.
10
+
11
+ ## Vocabulary
12
+
13
+ A **space** is a folder with `index.md`. The unit, the building block.
14
+
15
+ A **wiki** is a space — the one at the top of your tree, the one that's yours. From your perspective, it's "the wiki." Embedded in someone else's wiki via clone / submodule / symlink, it's just a space inside theirs. The word changes with position; the thing doesn't.
16
+
17
+ Inside a space, three kinds of inhabitant:
18
+
19
+ - **Files** — leaf content (markdown, images, data, anything).
20
+ - **Folders** — plain folders (no `index.md`), used for grouping without first-class status (assets, drafts, attachments, raw payloads).
21
+ - **Spaces** — folders that themselves have `index.md`, recursively.
22
+
23
+ Zero contained spaces is a fine wiki. Deep nesting is a fine wiki. Your shape is your call.
24
+
25
+ ## Tiers
26
+
27
+ Three tiers of opt-in. Each tier adds capability and the small contract tools rely on *at that tier*. A wiki opts in by adding the marker; tools detect the tier from what's present and degrade where it isn't. Pick the highest tier that fits your needs.
28
+
29
+ ### Tier 1 — Valid
30
+
31
+ A folder with `index.md`. Tools can find the wiki, read its `index.md`, and operate on the files within. No structural promises beyond "I'm a wiki." Search uses filesystem globs since there's no curated map.
32
+
33
+ ### Tier 2 — Navigable
34
+
35
+ `index.md` grows three sections so the wiki maps itself:
36
+
37
+ - **`## What this space is`** — opening paragraph in plain prose. The space's own description.
38
+ - **`## Items`** — curated list of files (and plain folders) worth surfacing. Not exhaustive; tools that need every file glob the filesystem.
39
+ - **`## Spaces`** — every space directly inside this one, listed once. **Contract:** this list is exhaustive. Adding a space inside means adding it here in the same change; removing a space means removing the entry. Tools traverse via this list and rely on it being complete.
40
+
41
+ The opt-in marker is the presence of `## Spaces`. When the marker is present, the contract holds: tools enforce exhaustiveness on writes (add/remove entries automatically) and flag missing entries on audit. When the marker is absent, the wiki is still valid — tools just don't navigate beyond the root `index.md`.
42
+
43
+ Each space chooses its own tier independently. A wiki at Tier 2 may contain a space at Tier 1 and another at Tier 3.
44
+
45
+ Cross-space references go horizontal: `[label](relative/path.md)` or `[[wikilink]]` if surrounding tooling supports it. `index.md` handles parent ↔ child navigation only.
46
+
47
+ ### Tier 3 — Managed
48
+
49
+ Adopts the conventions catalog ([`CONVENTIONS.md`](CONVENTIONS.md)): `log.md`, `_meta/taxonomy.md`, `.manifest.json`, frontmatter schema, the categorical layout, optional `_template.md` and `hot.md`. The three reference skills (`wiki-search`, `wiki-update`, `wiki-tend`) can then fully exercise audit, normalize, cross-link, sync, log, and graph operations.
50
+
51
+ Each marker is independent — adopt only what you want. `CONVENTIONS.md` describes what each one enables.
52
+
53
+ ## Sharing & nesting
54
+
55
+ Sharing a wiki is sharing its folder. The receiver mounts it however they prefer — subdir, symlink, git submodule, clone, any filesystem mechanism. From their perspective, your wiki becomes a space inside theirs. The same applies at any level: a single space can be extracted and shared, and it lands in the receiver's tree as a space.
56
+
57
+ **Trust scope.** Tools distinguish *owned* spaces (the wiki itself and spaces the user created inside it) from *external* spaces (mounts the user doesn't own — by convention, anything under `<wiki>/shared/`, any git submodule pointing at a foreign origin, or any symlink whose realpath resolves outside the wiki tree).
58
+
59
+ - **Read operations** (search, audit, status) cross owned spaces by default. External spaces are visited only when the user explicitly names one or asks to include all.
60
+ - **Write operations** stay within the targeted space by default. Other spaces — owned or external — are written to only with explicit instruction.
61
+
62
+ This makes "audit my wiki" reach project knowledge in `projects/<name>/` automatically (those are yours), while leaving a teammate's wiki at `shared/team-foo/` untouched until you ask for it explicitly.
63
+
64
+ ## Outside the spec
65
+
66
+ No frontmatter, no required tags, no fixed top-level categories, no required content schema, no special files beyond `index.md`. Folder names come from your domain — `clients/`, `papers/`, `projects/`, `recipes/`, `drafts/`, `journal/`, whatever fits. The spec doesn't care what your wiki is for. Anything else you see is convention or tooling, layered on top — see [`CONVENTIONS.md`](CONVENTIONS.md).
@@ -0,0 +1,359 @@
1
+ # Conventions
2
+
3
+ This is the opt-in catalog. Every section is independent. The [spec](AGENTS.md) defines three tiers — Valid (just `index.md`), Navigable (adds `## Items` and `## Spaces`), and Managed (everything below). This catalog is the Managed tier: the markers tools detect by file presence to enable each convention. Adopt only what you want; tools degrade where a marker is absent.
4
+
5
+ Wiki-syntax facts (wikilinks, frontmatter parsing, callouts, embeds, base views) are NOT redocumented here. They live in [`vendor/kepano/obsidian-markdown`](vendor/kepano/obsidian-markdown/SKILL.md) and [`vendor/kepano/obsidian-bases`](vendor/kepano/obsidian-bases/SKILL.md). Cite those skills, never restate their contents.
6
+
7
+ ---
8
+
9
+ ## Recommended Standard Pack
10
+
11
+ A new wiki only needs `index.md` (per spec) to be valid. Beyond that, the "Standard Pack" varies by use case — it's whatever set of opt-in markers makes the reference skills useful for your wiki. Example packs:
12
+
13
+ | Use case | Pack |
14
+ |---|---|
15
+ | Developer notebook | `log.md` + `_meta/taxonomy.md` + `.manifest.json` |
16
+ | Research wiki | `log.md` + `_meta/taxonomy.md` |
17
+ | Writing project | `hot.md` |
18
+ | Recipe collection | (none — pure content) |
19
+ | Personal knowledge | (none — pure content) |
20
+ | Team reference | `log.md` + `_meta/taxonomy.md` |
21
+
22
+ Each opt-in is independent — adopt any combination. Frontmatter (see § Frontmatter schema) is per-page rather than a pack file; mixed adoption is permitted. The catalog below explains what each marker enables; skip any of them and the corresponding tooling step degrades. The scaffold command takes any subset: `wiki-spaces init <path> --with log.md _meta/taxonomy.md` (prefix with `uvx` for no-install runs).
23
+
24
+ ---
25
+
26
+ ## Discovery via config
27
+
28
+ Skills locate the user's canonical wiki by reading `${XDG_CONFIG_HOME:-~/.config}/wiki-spaces/config`. Plain text, key = value, blank lines ignored; whole-line comments start with `#`. Inline `#` is not a comment marker — paths may legitimately contain `#`, so keep comments on their own lines:
29
+
30
+ ```
31
+ # wiki-spaces config
32
+ # wiki: canonical wiki path (must contain index.md)
33
+ # repo: path to wiki-spaces install (share dir from `wiki-spaces install`, or source checkout)
34
+ wiki = /home/you/Wiki
35
+ repo = /home/you/.local/share/wiki-spaces
36
+ ```
37
+
38
+ Both keys are absolute paths. `wiki` points to a folder containing `index.md`; `repo` points to the wiki-spaces install — the share dir written by `wiki-spaces install` (PyPI users) or a source checkout (dev users) — so skills can fetch `AGENTS.md`, `CONVENTIONS.md`, and `references/` on demand. If either path doesn't resolve, skills fail soft and tell the user what's missing.
39
+
40
+ **One canonical wiki per user.** wiki-spaces is built around a single wiki you call yours; the tooling assumes that. Users who want to switch between multiple wikis can swap configs manually. The single-wiki model is what makes global capture, cross-linking, and "open in Obsidian" all work coherently.
41
+
42
+ Bootstrap: `wiki-spaces install` writes the `repo` key automatically; `wiki-spaces init` writes the `wiki` key when scaffolding (unless `--no-config`). If the config is missing or `wiki` is unset:
43
+ - `wiki-update` runs the Initialization flow (see `wiki-update/SKILL.md` § Initialization, which mirrors `references/SETUP.md`).
44
+ - `wiki-search` and `wiki-tend` fail soft: tell the user setup is needed and point them at `references/SETUP.md` (use the raw GitHub URL if the `repo` path is also unknown).
45
+
46
+ CWD is a placement *hint*, never the discovery mechanism. The agent uses CWD and conversation context to decide *where in the wiki* a write goes (e.g., a project space vs global concepts), but the wiki itself is always the one in the config.
47
+
48
+ ## Per-space convention auto-detection
49
+
50
+ Each space is autonomous: optional conventions (frontmatter, `_meta/taxonomy.md`, `log.md`, etc.) are detected by file presence *within that space*. Parent conventions do not propagate to children. Each space picks its own tier independently — a Tier 3 root may contain a Tier 1 space and vice versa.
51
+
52
+ **Scope-root operations.** When a tool operates on a specific space (the wiki, or a space the user named), every convention check happens at *that scope's root* — not at an ancestor. The `log.md` appended to is the one at the scope being operated on. The taxonomy enforced is the one at that scope. The `.manifest.json` consulted is that scope's. Skip the marker at that scope and the corresponding step degrades for that scope only.
53
+
54
+ ## Owned vs external
55
+
56
+ Per [`AGENTS.md / Sharing & nesting`](AGENTS.md#sharing--nesting), tools distinguish *owned* spaces (yours) from *external* spaces (mounts you don't own). Detection heuristic, in order:
57
+
58
+ 1. Path is under `<wiki>/shared/` → external.
59
+ 2. Path is a git submodule (in `.gitmodules`) whose origin URL doesn't match the wiki's own origin → external.
60
+ 3. Path is a symlink whose realpath resolves outside the wiki tree → external.
61
+ 4. Otherwise → owned.
62
+
63
+ **Read operations** (search, status, audit) cross owned spaces by default. External spaces are visited only when the user explicitly names one or asks to include all.
64
+
65
+ **Write operations** stay within the targeted space. Other spaces — owned or external — are written to only with explicit instruction.
66
+
67
+ **Traversal safeguards** (when crossing into other spaces):
68
+ - Track visited realpaths (resolve symlinks) to break cycles.
69
+ - Skip broken symlinks and uninitialized git submodules with a one-line notice; don't error out on them.
70
+ - Refuse `..` traversal above the wiki root. External spaces reached through a legitimate `## Spaces` entry ARE in scope when the user opts in — the prohibition is on ascending lexically, not on cross-mount realpaths.
71
+
72
+ ---
73
+
74
+ ## Sharing & permissions
75
+
76
+ For shared or collaborative spaces, the recommended mechanism is **git repositories**. Each shared space is its own git repo; embed it in a parent via git submodule, clone, or symlink (see [`AGENTS.md` / Sharing & nesting](AGENTS.md#sharing--nesting) — all FS mechanisms remain valid; this section recommends one).
77
+
78
+ **Two-gate write protection.** Tools should avoid accidental out-of-scope writes; sharing-aware tools should preflight ownership before mutating git-backed spaces they don't own.
79
+
80
+ 1. **First gate (always on).** The trust scope clause in [`AGENTS.md`](AGENTS.md#sharing--nesting) defaults *write operations* to the targeted space only. Other spaces — owned or external — are written to only when the user's request explicitly includes them (naming a space, asking for all, or any clear instruction). Read operations follow their own rule: they cross owned spaces by default; external spaces require opt-in. Both rules are scope-based, not ownership-based — and together form the primary safety net.
81
+
82
+ 2. **Second gate (only if backed by git).** Push access on the remote is the de facto upstream-publication permission. Without push access, local commits succeed but `git push` fails — changes never reach collaborators. This is a publication backstop, not a write-time check.
83
+
84
+ **Honest caveat.** Push-as-permissions is a *late* check: local commits succeed; only the push fails. For agent-driven workflows this can surprise the user hours later. Always rely on the trust scope (gate #1) as the primary protection; treat push permissions as the safety net.
85
+
86
+ **For local-only or private wikis,** git is not required. A folder with `index.md` is a complete wiki. Add git when you decide to share or back up.
87
+
88
+ **Submodules.** When nesting shared spaces as git submodules:
89
+ - Cloners need `git clone --recursive` (or `git submodule update --init` after a plain clone). Mention this in your wiki's `index.md` if you use them.
90
+ - Submodules pin a SHA; the parent sees the pinned version until `git submodule update --remote` advances the working tree.
91
+ - After advancing, the new SHA is only local until you commit the parent repo's updated submodule pointer (gitlink) and push.
92
+ - GitHub release ZIPs do NOT include submodule contents.
93
+
94
+ ---
95
+
96
+ ## `index.md`
97
+
98
+ **If present:** This folder is a space (per the [spec](AGENTS.md)). `index.md` typically grows three sections as the space grows:
99
+
100
+ - **`## What this space is`** — opening paragraph, plain prose. The space's own description; preserved across regenerations.
101
+ - **`## Items`** — curated human navigation. A hand-picked list of files and plain folders worth surfacing — not exhaustive. Tools that need every file glob the filesystem.
102
+ - **`## Spaces`** — the navigation map: every space directly inside this one, listed once. The convention: the parent owns the link entry, the child owns its content. Adding a space inside means adding an entry here in the same change; removing a space means removing the entry. Tools rely on `## Spaces` being complete to traverse the tree.
103
+
104
+ Entries in `## Items` and `## Spaces` are markdown bullet lists, one per line. Order is the author's choice (typically navigational, not alphabetical):
105
+
106
+ - `## Items` — `[label](relative/path)` or `[[wikilink]]`, with an optional ` — short description`. Files and plain folders (folders without their own `index.md`) both belong here when worth surfacing. Hidden control files (`.manifest.json`, `_meta/...`, `_template.md`) are conventionally omitted unless a human reader needs to navigate to them.
107
+ - `## Spaces` — `[label](sub-folder/index.md)`, with an optional ` — short description`.
108
+
109
+ `## Items` is curated, so tools don't auto-add entries (only remove ones pointing to deleted files). `## Spaces` is meant to be exhaustive, so tools may flag sub-folders with `index.md` that aren't listed.
110
+
111
+ Skip any of these sections and `index.md` still marks the folder as a wiki. Tools that lean on the convention degrade where it isn't followed — your wiki is still your wiki.
112
+
113
+ **If absent:** This folder is not a wiki. Tools refuse to operate.
114
+
115
+ ---
116
+
117
+ ## `log.md`
118
+
119
+ **If present:** Tools append one line per operation. Format:
120
+
121
+ ```
122
+ - [TIMESTAMP] OPERATION key=value key=value
123
+ ```
124
+
125
+ `TIMESTAMP` is UTC ISO-8601. `OPERATION` is uppercase verb (`SEARCH`, `UPDATE`, `TEND`). Keys are operation-specific.
126
+
127
+ **If absent:** Tools skip logging. No log file is created automatically; create it (or run `wiki-spaces init <path> --with log.md`) to opt in.
128
+
129
+ ---
130
+
131
+ ## `hot.md`
132
+
133
+ **If present:** Free-form scratchpad for current active work. Tools may read it for context (e.g., `wiki-search` may surface its mentions) but never rewrite it. Users own its content.
134
+
135
+ **If absent:** Tools ignore. No proxy file is created.
136
+
137
+ ---
138
+
139
+ ## `.manifest.json`
140
+
141
+ **If present:** Project sync state. Schema:
142
+
143
+ ```json
144
+ {
145
+ "projects": {
146
+ "<project-slug>": {
147
+ "source_cwd": "/abs/path/to/source/repo",
148
+ "last_synced": "2026-05-14T10:30:00Z",
149
+ "last_commit_synced": "abc123",
150
+ "pages_in_vault": 12
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ `last_commit_synced` is `null` when the source has no git. `wiki-update` reads it to skip unchanged sources and writes it after each sync.
157
+
158
+ **If malformed:** Tools warn once, treat the file as absent for this run, and refuse to overwrite it until the user repairs or removes it.
159
+
160
+ **If absent:** `wiki-update` performs a full scan on every sync. No project tracking.
161
+
162
+ ---
163
+
164
+ ## `_meta/taxonomy.md`
165
+
166
+ **If present:** Canonical tag vocabulary. Applies to YAML frontmatter `tags:` fields. `wiki-tend` normalizes those to the canonical list, suggests adding genuinely new tags that appear on 2+ pages, and rejects unknown one-off tags with a closest-match suggestion. `wiki-update` consults it before assigning tags. Inline `#tag` syntax outside frontmatter is not normalized.
167
+
168
+ Document shape:
169
+
170
+ ```markdown
171
+ # Tag Taxonomy
172
+
173
+ Constraints: max 5 tags per page, lowercase/hyphenated.
174
+
175
+ ## Domain Tags
176
+
177
+ | Tag | Purpose | Aliases |
178
+ |---|---|---|
179
+ | `python` | Python language, ecosystem | |
180
+ ...
181
+
182
+ ## Type Tags
183
+
184
+ | Tag | Purpose |
185
+ |---|---|
186
+ | `how-to` | Step-by-step procedure |
187
+ ...
188
+ ```
189
+
190
+ Aliases are mappings the normalizer uses to rewrite non-canonical tags to canonical form.
191
+
192
+ **If absent:** Tags are free-form. `wiki-tend` skips tag normalization with a notice; `wiki-update` does not enforce a vocabulary.
193
+
194
+ ---
195
+
196
+ ## `_template.md`
197
+
198
+ **If present in any folder:** New pages created by `wiki-update` in that folder use this file as their boilerplate (frontmatter + body skeleton). The closest ancestor `_template.md` wins.
199
+
200
+ **If absent:** New pages are created from the section "Page template" below if frontmatter is in use, otherwise as bare markdown.
201
+
202
+ ---
203
+
204
+ ## Frontmatter schema
205
+
206
+ **If used (any content page in the wiki has YAML frontmatter):** The opt-in schema is:
207
+
208
+ ```yaml
209
+ ---
210
+ title: >-
211
+ Page Title
212
+ category: <one of your categorical layout values>
213
+ tags: [tag1, tag2]
214
+ aliases: [alternate-name] # optional
215
+ sources: [project-name, url]
216
+ summary: >-
217
+ ≤200 chars; enough to decide whether to open the page.
218
+ created: 2026-05-14T00:00:00Z
219
+ updated: 2026-05-14T00:00:00Z
220
+ ---
221
+ ```
222
+
223
+ Timestamps are UTC ISO-8601. `>-` folded scalar avoids YAML quoting issues for `title` and `summary`. Frontmatter syntax is owned by [obsidian-markdown](vendor/kepano/obsidian-markdown/SKILL.md).
224
+
225
+ **Mixed adoption is allowed.** A wiki may have some content pages with frontmatter and some without; the convention is per-page, not per-wiki. `wiki-tend` audits required-field completeness only on pages that already have frontmatter — it never flags a page as "missing frontmatter." Special files (`index.md`, `log.md`, `hot.md`, `.manifest.json`, `_meta/taxonomy.md`, `_template.md`) are exempt.
226
+
227
+ **If absent (no page in the wiki has frontmatter):** `wiki-tend` skips frontmatter checks. `wiki-update` writes plain markdown pages.
228
+
229
+ ---
230
+
231
+ ## Page template
232
+
233
+ **If used:** Body structure for content pages:
234
+
235
+ ```markdown
236
+ # Page Title
237
+
238
+ One-paragraph summary.
239
+
240
+ ## Key Ideas
241
+
242
+ - A fact explicitly stated by the source or codebase.
243
+ - A generalization drawn from the source. ^[inferred]
244
+ - A claim where sources disagree. ^[ambiguous]
245
+
246
+ ## Open Questions
247
+
248
+ Unresolved items.
249
+ ```
250
+
251
+ **If absent:** Pages are free-form.
252
+
253
+ ---
254
+
255
+ ## Provenance markers
256
+
257
+ **If used:** Inline markers attached to claims indicate epistemic status.
258
+
259
+ | State | Marker | Meaning |
260
+ |---|---|---|
261
+ | Extracted | *(no marker)* | Stated directly by source, docs, or code |
262
+ | Inferred | `^[inferred]` | Synthesized or implied — not stated directly |
263
+ | Ambiguous | `^[ambiguous]` | Sources disagree or evidence is unclear |
264
+
265
+ Unmarked claims carry no enforced provenance — the convention treats them as extracted by default, but nothing in the tooling verifies the distinction. `wiki-update` applies markers when capturing; `wiki-tend` does not enforce them.
266
+
267
+ **If absent:** No provenance is tracked; all claims are unmarked.
268
+
269
+ ---
270
+
271
+ ## Categorical layout
272
+
273
+ **If used:** A folder convention for placing pages by kind. There's no canonical shape — your wiki's layout comes from what it's for. Pick what fits, mix shapes, or invent your own.
274
+
275
+ A few example shapes:
276
+
277
+ | Use case | Common top-level folders |
278
+ |---|---|
279
+ | **Developer notebook** | `concepts/`, `entities/`, `skills/`, `projects/<name>/` |
280
+ | **Research wiki** | `papers/`, `topics/`, `methods/`, `datasets/`, `projects/<name>/` |
281
+ | **Writing project** | `drafts/`, `characters/`, `worldbuilding/`, `notes/`, `archive/` |
282
+ | **Recipe collection** | `recipes/`, `ingredients/`, `techniques/`, `meal-plans/` |
283
+ | **Personal knowledge** | `journal/`, `learning/`, `contacts/`, `places/`, `interests/` |
284
+ | **Team reference** | `runbooks/`, `decisions/`, `services/`, `people/`, `clients/` |
285
+
286
+ Project-scoped content nests inside the wiki's project-grouping folder (commonly `projects/<name>/<sub-folder>/`, but `clients/<name>/` or `work/<name>/` follow the same pattern). Shared / external content typically lives under `shared/<name>/` (per `## Sharing & permissions`). `_archives/` is a conventional name for retired content / snapshots.
287
+
288
+ Slugs for new pages are lowercase, hyphen-separated, ≤50 chars, descriptive.
289
+
290
+ **Self-documenting layouts.** Each top-level folder gets a one-line "what goes here" description in `index.md` — under `## Spaces` if the folder is itself a space (has its own `index.md`), or under `## Items` if it's a plain folder you want surfaced. `wiki-update` reads those descriptions when classifying new content; without descriptions, the bare folder name is the only signal — name folders concretely (`recipes/` not `stuff/`) and routing still works, descriptions just make it more precise.
291
+
292
+ `wiki-update`'s classification follows folder-name semantics first, then descriptions: a "sourdough recipe" matches `recipes/`, a "character bio" matches `characters/`, a "Python typing pattern" matches `concepts/` (or `notes/`, or whatever your wiki uses). When two folders are equally plausible the skill surfaces both options before writing; when none fit it asks, optionally creating a new folder for content that represents a recurring kind. Project-scoped content (identified by the user's intent — CWD is only a hint that disambiguates *which* project, never the trigger for project-vs-global) lands under whichever folder the wiki uses to group per-project content (`projects/`, `clients/`, `work/`, etc.).
293
+
294
+ **If absent (no top-level folders at the wiki root other than `_meta/`, `_archives/`, `.git/`, or hidden directories):** `wiki-update` writes pages flat at the wiki root or asks the user where to place. `wiki-tend`'s cross-category scoring is skipped.
295
+
296
+ ---
297
+
298
+ ## Retrieval primitives
299
+
300
+ Cost-tiered lookup table for `wiki-search`. Use the cheapest primitive that answers the question; escalate only when it cannot.
301
+
302
+ | Need | Primitive | Cost |
303
+ |---|---|---|
304
+ | Page exists? Title/tags? | `index.md` scan or grep frontmatter | Cheapest |
305
+ | 1–2 sentence preview | `summary:` frontmatter field | Cheap |
306
+ | Specific claim or section | `grep -A 10 -B 2 "<term>" <file>` (or your harness's grep tool) | Medium |
307
+ | Full page content | read the file | Expensive |
308
+
309
+ Grep-style search is preferred over full reads. Full reads are capped at 3 candidates per query.
310
+
311
+ ---
312
+
313
+ ## Linking rules
314
+
315
+ Wikilink and markdown-link syntax: see [obsidian-markdown](vendor/kepano/obsidian-markdown/SKILL.md). This section covers usage convention, not syntax.
316
+
317
+ - Add up to 2 relevant wikilinks per page; never force irrelevant links.
318
+ - Link the first natural mention only. Skip mentions inside code blocks or frontmatter.
319
+ - Use the shortest link that resolves unambiguously.
320
+ - `wiki-tend`'s cross-link pass scores candidates: exact name match (+4), shared tags ≥2 (+2), same project (+2), cross-category (+2), partial match (+1). Apply links only with score ≥3.
321
+
322
+ ---
323
+
324
+ ## Noise filter
325
+
326
+ A heuristic for **knowledge-capture use cases** (research notes, technical wikis, developer notebooks) where the goal is "store what was hard to derive." Before writing a page, apply:
327
+
328
+ - **Code answers it?** Skip — wiki the reasoning, not what code says.
329
+ - **10-second search answers it?** Skip — wiki what took 30 minutes.
330
+ - **Needed in 3 months?** If you'd have to re-research, wiki it.
331
+ - **Already there?** Check `index.md`. Merge, don't duplicate.
332
+
333
+ **Skip this filter** for content-store use cases where every entry is intentional regardless of derivation cost — recipe collections, personal journals, contact lists, team runbooks, etc. The "would you re-derive this?" test doesn't apply when the wiki *is* the source of truth, not a memory aid.
334
+
335
+ ---
336
+
337
+ ## `.git`
338
+
339
+ Detection: a `.git` entry at the wiki root, whether a directory (regular repo) or a file (git submodule, worktree). Tools that need an authoritative answer should run `git -C <wiki-root> rev-parse --is-inside-work-tree`.
340
+
341
+ **If present:** The wiki is also a git repository. Tools may surface git context (current branch, uncommitted changes, ahead/behind upstream) in their reports when relevant. Tools NEVER auto-commit or auto-push; all git operations are user-driven. See [`Sharing & permissions`](#sharing--permissions) for the recommended sharing pattern.
342
+
343
+ **If absent:** No git context surfaced. Tools operate on the filesystem directly.
344
+
345
+ ---
346
+
347
+ ## `.obsidian/` integration
348
+
349
+ **If present:** The wiki is intended to be opened in Obsidian. `wiki-tend`'s colorize step writes graph color groups into `.obsidian/graph.json` (only the `colorGroups` key; everything else preserved; backup written).
350
+
351
+ Default colorize mode is `by-tag` (top 10 tags by usage, default palette below). `by-category` colors the categorical layout folders. `custom` honors user-provided mappings.
352
+
353
+ Default palette (RGB ints) — tools may override:
354
+ ```
355
+ [5142951, 15896107, 14767961, 7780786, 5873999,
356
+ 15583048, 11565217, 16751527, 10253663, 12234924]
357
+ ```
358
+
359
+ **If absent:** Colorize step is skipped. The wiki is treated as a plain markdown directory.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 anfreire
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: wiki-spaces
3
+ Version: 0.1.0
4
+ Summary: Minimal nestable wiki — a folder + index.md, for any use case (notes, research, recipes, writing, team docs). Spec, conventions catalog, and reference skills.
5
+ Project-URL: Homepage, https://github.com/anfreire/wiki-spaces
6
+ Project-URL: Repository, https://github.com/anfreire/wiki-spaces
7
+ Project-URL: Issues, https://github.com/anfreire/wiki-spaces/issues
8
+ Author-email: André Ferreira <anfreire.dev@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai-agents,knowledge-base,markdown,notes,obsidian,personal-wiki,wiki
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Intended Audience :: Information Technology
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Documentation
26
+ Classifier: Topic :: Software Development :: Documentation
27
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
28
+ Requires-Python: >=3.11
29
+ Description-Content-Type: text/markdown
30
+
31
+ # wiki-spaces
32
+
33
+ A wiki is a folder with `index.md`. That's the spec. Inside, anything goes: files, plain folders, or other spaces (folders that themselves carry `index.md`) — recursively. Zero contained spaces is a fine wiki. Deep nesting is too. Your shape is your call.
34
+
35
+ Use it for whatever you want — research notes, writing drafts, recipes, project knowledge, a personal life wiki, a team reference. The spec is shape-agnostic; conventions are opt-in. `wiki-update` places new content by reading `index.md`'s `## Spaces` / `## Items` entries; `wiki-search` and `wiki-tend` operate against whatever shape the wiki has, with filesystem-glob fallbacks when the curated map is absent — see [`CONVENTIONS.md / Categorical layout`](CONVENTIONS.md#categorical-layout).
36
+
37
+ Three tiers of opt-in: stop at the floor (`index.md` only), grow into navigable (`## Items` + `## Spaces` so the wiki maps itself), or fully managed (the `CONVENTIONS.md` catalog — taxonomy, logging, frontmatter, etc.). Each tier adds capability and a small contract; tools degrade gracefully where you haven't opted in.
38
+
39
+ wiki-spaces ships:
40
+
41
+ - The **spec** ([`AGENTS.md`](AGENTS.md)) — what counts as a wiki.
42
+ - The **conventions catalog** ([`CONVENTIONS.md`](CONVENTIONS.md)) — opt-in markers tools detect.
43
+ - Three **reference skills** AI agents use to work with your wiki:
44
+ - `wiki-search` — find content
45
+ - `wiki-update` — capture / save / sync new content
46
+ - `wiki-tend` — audit, normalize tags, cross-link, colorize
47
+
48
+ One canonical wiki per user, located via `~/.config/wiki-spaces/config`. Plain markdown, Obsidian-flavored, version-controllable.
49
+
50
+ ## Just start (no install)
51
+
52
+ The spec is a folder + `index.md`. If you don't need the reference skills yet, that's the whole setup:
53
+
54
+ ```sh
55
+ mkdir -p ~/Wiki
56
+ echo "# My Wiki" > ~/Wiki/index.md
57
+ mkdir -p ~/.config/wiki-spaces
58
+ printf 'wiki = %s/Wiki\n' "$HOME" > ~/.config/wiki-spaces/config
59
+ ```
60
+
61
+ Start adding files. You now have a Tier 1 wiki. Install the skills later (steps below); they'll discover the wiki via the config you just wrote.
62
+
63
+ ## Setup (with the reference skills)
64
+
65
+ ### Paste this to your AI agent (recommended)
66
+
67
+ ```
68
+ Install and set up wiki-spaces for me by following the instructions here:
69
+ https://raw.githubusercontent.com/anfreire/wiki-spaces/main/references/SETUP.md
70
+ ```
71
+
72
+ The agent fetches the briefing, asks what your wiki is for, picks tailored defaults, runs the install / scaffold / config writes, and confirms when done.
73
+
74
+ ### For LLM agents (non-interactive)
75
+
76
+ ```bash
77
+ curl -s https://raw.githubusercontent.com/anfreire/wiki-spaces/main/references/SETUP.md
78
+ ```
79
+
80
+ ### For humans (manual)
81
+
82
+ [`uv`](https://docs.astral.sh/uv/) is strongly recommended (handles Python provisioning + on-demand runs). Run on demand with no install:
83
+
84
+ ```bash
85
+ uvx wiki-spaces install # detected harnesses; add --all to cover every supported one
86
+ uvx wiki-spaces init ~/Wiki --git # bare wiki at ~/Wiki; --with adds files, --folders adds dirs (see below)
87
+ uvx wiki-spaces doctor --no-net
88
+ ```
89
+
90
+ Or install permanently and drop the `uvx` prefix:
91
+
92
+ ```bash
93
+ uv tool install wiki-spaces
94
+ wiki-spaces install
95
+ wiki-spaces init ~/Wiki --git # bare wiki; --with / --folders see below
96
+ wiki-spaces doctor --no-net
97
+ ```
98
+
99
+ No `uv`? Plain `pip` works too:
100
+
101
+ ```bash
102
+ pip install --user wiki-spaces # or pipx install wiki-spaces
103
+ wiki-spaces install
104
+ wiki-spaces init ~/Wiki --git # bare wiki; --with / --folders see below
105
+ wiki-spaces doctor --no-net
106
+ ```
107
+
108
+ `init --with` accepts `log.md`, `_meta/taxonomy.md`, `.manifest.json`, `_template.md`, `hot.md` — opt-in conventions from `CONVENTIONS.md`. `--folders <names...>` creates top-level categorical directories — `--folders concepts entities projects` for a developer notebook, `--folders recipes ingredients techniques` for a recipe collection, `--folders drafts characters worldbuilding` for a writing project, and so on (see [`references/EXAMPLES.md`](references/EXAMPLES.md) for full shape examples). For nothing extra, leave both flags off; `index.md` is the only required file.
109
+
110
+ After setup, your skills know everything via `${XDG_CONFIG_HOME:-~/.config}/wiki-spaces/config` (two keys: `wiki` and `repo`). Invoke `wiki-search`, `wiki-update`, `wiki-tend` from anywhere.
111
+
112
+ For Cursor / Windsurf / GitHub Copilot / Aider (no skills concept), see [`references/HARNESS_INTEGRATION.md`](references/HARNESS_INTEGRATION.md).
113
+
114
+ ### Working from a source checkout (dev)
115
+
116
+ ```bash
117
+ git clone https://github.com/anfreire/wiki-spaces.git ~/src/wiki-spaces
118
+ ~/src/wiki-spaces/scripts/install.py # same as `wiki-spaces install` but reads from the checkout
119
+ ~/src/wiki-spaces/scripts/init_wiki.py ~/Wiki --git
120
+ ~/src/wiki-spaces/scripts/doctor.py --no-net
121
+ ```
122
+
123
+ The `scripts/*.py` shims are PEP 723 entries that forward to the `wiki_spaces` package — same code path as `uvx wiki-spaces`, just sourced from the local clone instead of PyPI.
124
+
125
+ ## How it works
126
+
127
+ | | |
128
+ |---|---|
129
+ | **Discovery** | Skills read `~/.config/wiki-spaces/config` for the `wiki` path. CWD is a placement hint, never the discovery mechanism. |
130
+ | **Conventions** | Obsidian-flavored: wikilinks, frontmatter, tags, Bases, `.obsidian/` graph integration. All optional per space; presence-detected. |
131
+ | **Spaces** | Recursive (folders with their own `index.md`). Each is autonomous: own log, own taxonomy, own conventions. Shared/team spaces typically mount as git submodules under `shared/`. |
132
+ | **Trust scope** | Tools distinguish *owned* spaces (yours) from *external* mounts (under `shared/`, foreign submodules, out-of-tree symlinks). Reads cross owned spaces by default; writes stay in the targeted space; external mounts require explicit opt-in. |
133
+
134
+ ## Read more
135
+
136
+ - [`AGENTS.md`](AGENTS.md) — the spec. One page.
137
+ - [`CONVENTIONS.md`](CONVENTIONS.md) — opt-in conventions catalog.
138
+ - [`references/`](references/) — agent-facing setup, examples, and mounting playbooks.
139
+ - [`skills/`](skills/) — the three reference skills.
140
+
141
+ ## Dependencies
142
+
143
+ - **Python `>=3.11`** — the package's only hard runtime dep.
144
+ - [`uv`](https://docs.astral.sh/uv/) — strongly recommended. Runs `uvx wiki-spaces` ephemerally, `uv tool install wiki-spaces` permanently, and provisions Python automatically. Plain `pip install wiki-spaces` (or `pipx`) works as a fallback if you can't / won't use uv.
145
+ - `git` — optional. Recommended for backing up / sharing your wiki and for the dev-from-source flow.
146
+ - [`kepano/obsidian-skills`](https://github.com/kepano/obsidian-skills) — `obsidian-markdown` and `obsidian-bases` are vendored under [`vendor/kepano/`](vendor/kepano/) (shallow clone + sparse copy, pinned by SHA) and ship inside the wheel. The reference skills defer to `obsidian-markdown` for wikilink / frontmatter / callout / embed syntax. `obsidian-bases` is vendored for future `.base` view tooling; no current procedure uses it.
147
+
148
+ ## Sharing wikis
149
+
150
+ Shared / collaborative spaces are best handled as git repositories embedded in your canonical wiki via submodules. Push access on the remote is the de facto write-permission layer. See [`CONVENTIONS.md` / Sharing & permissions](CONVENTIONS.md#sharing--permissions) and [`references/MOUNT.md`](references/MOUNT.md).
151
+
152
+ For local-only or private use, no git needed.
153
+
154
+ ## Prior art
155
+
156
+ This project stands on three pieces of earlier work:
157
+
158
+ - **Andrej Karpathy's "LLM Wiki" gist** ([gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)) — the original idea: compile knowledge once into interconnected markdown files maintained by an LLM, instead of re-asking or re-RAG-ing.
159
+ - **[Ar9av/obsidian-wiki](https://github.com/Ar9av/obsidian-wiki)** — a broader framework implementing the LLM Wiki pattern with ~30 skills across many AI coding harnesses. wiki-spaces extracts a smaller spec, commits to a single canonical wiki, and adds nestability for shared content.
160
+ - **[kepano](https://github.com/kepano)** — Obsidian's lead designer, whose [`obsidian-skills`](https://github.com/kepano/obsidian-skills) are vendored as the syntax base.
161
+
162
+ The [AGENTS.md](https://agents.md/) standard is used for the root agent-instruction file, with symlinks for harnesses that prefer their own filename.
163
+
164
+ ## License
165
+
166
+ MIT. See [`LICENSE`](LICENSE).