slimwiki 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENT.md ADDED
@@ -0,0 +1,316 @@
1
+ # SlimWiki CLI — Agent Reference
2
+
3
+ You are operating the `slimwiki` CLI. This file is the contract — every
4
+ flag, output shape, and Tiptap-doc rule you need is here. If a behavior
5
+ isn't documented below, run `slimwiki <subcommand> --help` first; don't
6
+ guess.
7
+
8
+ ## Output contract
9
+
10
+ - **Default output is JSON** on stdout. One JSON value per command.
11
+ - **Errors** print `{"error":"<message>"}` on stderr and exit non-zero.
12
+ - `--human` switches to a tabular format. Don't use it from an agent —
13
+ it's for human shell users and is not stable to parse.
14
+
15
+ Always check the exit code. On non-zero, read stderr for the JSON error
16
+ and decide whether to retry, re-authenticate, or surface to the user.
17
+
18
+ ## Authentication
19
+
20
+ The CLI must be authenticated before any non-`auth` command. Three ways:
21
+
22
+ 1. `slimwiki auth login` — opens a browser. Interactive only.
23
+ 2. `SLIMWIKI_TOKEN=<bearer-token>` env var — for headless/CI/agent-runner
24
+ environments. Optional `SLIMWIKI_API_BASE=<url>` if not prod.
25
+ 3. A previously written `credentials.json` from a prior `auth login`.
26
+
27
+ To check: `slimwiki auth status` returns `{"authenticated": true|false, ...}`.
28
+ If `false`, ask the user to run `slimwiki auth login` — never try to
29
+ prompt for credentials yourself.
30
+
31
+ ## Account / wiki selection
32
+
33
+ Most commands accept `--account <slug>` and `--wiki <slug>`. Resolution
34
+ order:
35
+
36
+ 1. Explicit flag.
37
+ 2. `SLIMWIKI_ACCOUNT_SLUG` / `SLIMWIKI_WIKI_SLUG` env vars.
38
+ 3. The slugs cached during `auth login`.
39
+ 4. Live `/users/me` lookup (primary account + default wiki).
40
+
41
+ If the user belongs to one account, omit the flags. If multiple, list
42
+ them with `slimwiki account list` and pass `--account <slug>` explicitly.
43
+
44
+ ## Commands
45
+
46
+ ### Discovery
47
+
48
+ ```
49
+ slimwiki account list # → [{slug, name}]
50
+ slimwiki wiki list [--account <slug>] # → [{slug, name}]
51
+ ```
52
+
53
+ ### Reading pages
54
+
55
+ ```
56
+ slimwiki page list [--account <slug>] [--wiki <slug>] \
57
+ [--search <query>] \
58
+ [--archived] \
59
+ [--limit <n>] [--offset <n>]
60
+ # → { "rows": [{title, slug, pageHash, updatedAt}, ...], "total": <int> }
61
+ ```
62
+
63
+ `--search <q>` matches both title and content (ILIKE). Title hits rank
64
+ above content-only hits. Output is metadata only — no `content` blob.
65
+
66
+ ```
67
+ slimwiki page get <slug-or-pageHash-or-id> [--wiki <slug>] [--account <slug>]
68
+ # → { id, title, slug, pageHash, content, archived, wikiId, updatedAt, ... }
69
+ ```
70
+
71
+ `page get` returns the full Tiptap doc in `content`. Use this when you
72
+ need to read existing content (e.g. to summarise or to base a new page
73
+ on existing structure).
74
+
75
+ ### Creating pages
76
+
77
+ ```
78
+ slimwiki page create --title "<title>" \
79
+ (--file <path> | --content '<json>' | --stdin) \
80
+ [--parent <slug-or-pageHash-or-id>] \
81
+ [--wiki <slug>] [--account <slug>]
82
+ # → the created page row including {id, slug, pageHash, ...}
83
+ ```
84
+
85
+ Pass exactly one content source. The body MUST be a valid Tiptap doc
86
+ (see contract below). The CLI validates locally before any network call;
87
+ on a schema error you get a non-zero exit with a `path` to the failing
88
+ node so you can fix and retry without a server round-trip.
89
+
90
+ `--parent` accepts a UUID, 12-char `pageHash`, or slug. The new page is
91
+ attached to the parent in the navigation tree.
92
+
93
+ ## Tiptap document contract
94
+
95
+ Every `page create` body must be:
96
+
97
+ ```json
98
+ { "type": "doc", "content": [ ...block-nodes ] }
99
+ ```
100
+
101
+ Recognised node types — anything else will be rejected:
102
+
103
+ | Type | Required attrs | Notes |
104
+ |------------------|----------------------------------------|-------------------------------------------------|
105
+ | `paragraph` | — | Body content |
106
+ | `heading` | `level: 1 \| 2 \| 3` | No h4+ |
107
+ | `bulletList` | — | Wraps `listItem` nodes |
108
+ | `orderedList` | `start?: number` | Wraps `listItem` nodes |
109
+ | `listItem` | — | Inside `bulletList`/`orderedList` |
110
+ | `taskList` | — | Wraps `taskItem` nodes |
111
+ | `taskItem` | `checked?: boolean` | Inside `taskList` |
112
+ | `blockquote` | — | Wraps block nodes |
113
+ | `codeBlock` | `language?: string` | Children are `text` only |
114
+ | `horizontalRule` | — | Self-closing |
115
+ | `image` | `src: string`, `alt?`, `title?` | URL must be reachable from the SlimWiki frontend|
116
+ | `video` | `src: string` | Same as image |
117
+ | `attachment` | `src?`, `name?` | |
118
+ | `math` | `latex: string` | Inline node — must live inside a paragraph |
119
+ | `pageMention` | `pageId: string` | Link to another SlimWiki page |
120
+ | `table` | — | Wraps `tableRow` |
121
+ | `tableRow` | — | Wraps `tableCell` / `tableHeader` |
122
+ | `tableCell` | — | Children = block nodes (usually `paragraph`) |
123
+ | `tableHeader` | — | Same as tableCell, used in the first row |
124
+
125
+ Inline / leaf nodes:
126
+
127
+ - `text` with `text: string` and optional `marks`.
128
+ - `hardBreak` (line break inside a paragraph).
129
+
130
+ Marks (apply via `text.marks: [{ type: "<mark>", attrs?: ... }]`):
131
+
132
+ - `bold`, `italic`, `underline`, `strike`, `code`, `highlight`
133
+ - `link` — requires `attrs.href`
134
+ - `textStyle` — optional `attrs.color` (CSS color)
135
+
136
+ ### Minimal valid doc
137
+
138
+ ```json
139
+ {
140
+ "type": "doc",
141
+ "content": [
142
+ { "type": "paragraph",
143
+ "content": [{ "type": "text", "text": "Hello." }] }
144
+ ]
145
+ }
146
+ ```
147
+
148
+ ### Idiomatic patterns
149
+
150
+ **Heading + paragraph**
151
+
152
+ ```json
153
+ { "type": "heading", "attrs": { "level": 1 },
154
+ "content": [{ "type": "text", "text": "Quarterly roadmap" }] }
155
+ { "type": "paragraph",
156
+ "content": [{ "type": "text", "text": "Owner: " },
157
+ { "type": "text", "text": "@jamie", "marks": [{ "type": "bold" }] }] }
158
+ ```
159
+
160
+ **Bullet list**
161
+
162
+ ```json
163
+ { "type": "bulletList", "content": [
164
+ { "type": "listItem", "content": [
165
+ { "type": "paragraph", "content": [{ "type": "text", "text": "First item" }] }
166
+ ]}
167
+ ]}
168
+ ```
169
+
170
+ **Table** (every cell wraps a `paragraph`)
171
+
172
+ ```json
173
+ { "type": "table", "content": [
174
+ { "type": "tableRow", "content": [
175
+ { "type": "tableHeader", "content": [
176
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Name" }] }
177
+ ]},
178
+ { "type": "tableHeader", "content": [
179
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Color" }] }
180
+ ]}
181
+ ]},
182
+ { "type": "tableRow", "content": [
183
+ { "type": "tableCell", "content": [
184
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Granny Smith" }] }
185
+ ]},
186
+ { "type": "tableCell", "content": [
187
+ { "type": "paragraph", "content": [{ "type": "text", "text": "Green" }] }
188
+ ]}
189
+ ]}
190
+ ]}
191
+ ```
192
+
193
+ **Code block**
194
+
195
+ ```json
196
+ { "type": "codeBlock", "attrs": { "language": "ts" },
197
+ "content": [{ "type": "text", "text": "const x: number = 1;" }] }
198
+ ```
199
+
200
+ **Math** (inline only — wrap in a paragraph)
201
+
202
+ ```json
203
+ { "type": "paragraph", "content": [
204
+ { "type": "text", "text": "Einstein: " },
205
+ { "type": "math", "attrs": { "latex": "E = mc^2" } }
206
+ ]}
207
+ ```
208
+
209
+ **Link**
210
+
211
+ ```json
212
+ { "type": "paragraph", "content": [
213
+ { "type": "text", "text": "See ", "marks": [] },
214
+ { "type": "text", "text": "the docs",
215
+ "marks": [{ "type": "link", "attrs": { "href": "https://example.com" } }] }
216
+ ]}
217
+ ```
218
+
219
+ ## Recipe library
220
+
221
+ ### "Create a page about X with a table of Y vs Z"
222
+
223
+ ```sh
224
+ slimwiki page create --title "Apple varieties" --stdin <<'JSON'
225
+ {
226
+ "type": "doc",
227
+ "content": [
228
+ { "type": "heading", "attrs": { "level": 1 },
229
+ "content": [{ "type": "text", "text": "Apple varieties" }] },
230
+ { "type": "paragraph",
231
+ "content": [{ "type": "text", "text": "Common cultivars and their colors." }] },
232
+ { "type": "table", "content": [
233
+ { "type": "tableRow", "content": [
234
+ { "type": "tableHeader", "content": [{ "type": "paragraph",
235
+ "content": [{ "type": "text", "text": "Name" }] }] },
236
+ { "type": "tableHeader", "content": [{ "type": "paragraph",
237
+ "content": [{ "type": "text", "text": "Color" }] }] }
238
+ ]},
239
+ { "type": "tableRow", "content": [
240
+ { "type": "tableCell", "content": [{ "type": "paragraph",
241
+ "content": [{ "type": "text", "text": "Granny Smith" }] }] },
242
+ { "type": "tableCell", "content": [{ "type": "paragraph",
243
+ "content": [{ "type": "text", "text": "Green" }] }] }
244
+ ]}
245
+ ]}
246
+ ]
247
+ }
248
+ JSON
249
+ ```
250
+
251
+ ### "Find pages containing 'SpaceX'"
252
+
253
+ ```sh
254
+ slimwiki page list --search SpaceX
255
+ # Parse the .rows array; .total tells you how many matches across the wiki.
256
+ ```
257
+
258
+ ### "How many pages mention rockets?"
259
+
260
+ ```sh
261
+ slimwiki page list --search rockets | jq '.total'
262
+ ```
263
+
264
+ ### "Read the page about HR benefits and summarise it"
265
+
266
+ ```sh
267
+ # 1. Find the slug
268
+ slimwiki page list --search "HR benefits" --limit 3
269
+
270
+ # 2. Fetch the full doc (use the slug from step 1)
271
+ slimwiki page get <slug>
272
+ # .content is a full Tiptap doc — walk it to extract text.
273
+ ```
274
+
275
+ ### "Create a child page under an existing parent"
276
+
277
+ ```sh
278
+ slimwiki page create --title "Q3 Plan" \
279
+ --parent quarterly-roadmap \
280
+ --file q3.json
281
+ ```
282
+
283
+ ### "List archived pages"
284
+
285
+ ```sh
286
+ slimwiki page list --archived --limit 100
287
+ ```
288
+
289
+ ## Failure modes you will hit
290
+
291
+ - **`Not authenticated`** — credentials missing or expired. Ask the user
292
+ to `slimwiki auth login` (or set `SLIMWIKI_TOKEN`). Do not loop on it.
293
+ - **`Tiptap doc validation failed at <path>`** — your JSON didn't match
294
+ the schema. The path tells you which node. Fix locally and retry; no
295
+ network call was made.
296
+ - **`Account not found for slug "..."`** / **`Wiki not found for slug
297
+ "..."`** — bad `--account`/`--wiki`. Run `slimwiki account list` /
298
+ `slimwiki wiki list` to discover the right slug.
299
+ - **`Parent page not found`** — `--parent` value didn't match any slug,
300
+ pageHash, or UUID in the wiki. Search first.
301
+ - **HTTP 4xx/5xx** — network or server error. The error body is
302
+ forwarded verbatim. Surface to the user; don't keep retrying.
303
+
304
+ ## Hard rules
305
+
306
+ - **Don't use `--human`.** Always parse JSON.
307
+ - **Don't ask the user to paste their token into a prompt.** Use
308
+ `auth login` (browser) or `SLIMWIKI_TOKEN`.
309
+ - **Don't fabricate node types.** If a block doesn't exist in the table
310
+ above, don't emit it. The schema will reject and abort.
311
+ - **Don't transform the user's content before posting.** If they
312
+ describe content in markdown, convert it directly to Tiptap JSON
313
+ yourself — don't shell out to a markdown→tiptap converter.
314
+ - **Don't set `slug` or `pageHash` on create.** The server generates them.
315
+ - **Don't post empty pages.** A doc with at least one paragraph is the
316
+ minimum the editor will render cleanly.
package/LICENSE.md ADDED
@@ -0,0 +1,65 @@
1
+ # SlimWiki CLI License
2
+
3
+ Copyright (c) 2026 SlimWiki Pte. Ltd. All rights reserved.
4
+
5
+ This software ("the SlimWiki CLI", or "the Software") is the
6
+ proprietary property of SlimWiki Pte. Ltd. ("SlimWiki"). It is licensed,
7
+ not sold.
8
+
9
+ ## 1. Permitted use
10
+
11
+ Subject to the restrictions below, SlimWiki grants you a non-exclusive,
12
+ non-transferable, royalty-free licence to:
13
+
14
+ - Install the Software on devices you own or operate.
15
+ - Run the Software to interact with a SlimWiki workspace you are
16
+ authorised to access.
17
+ - Distribute unmodified copies of the official npm-published artefact
18
+ to other users for the same purpose.
19
+
20
+ ## 2. Restrictions
21
+
22
+ You may NOT, without prior written permission from SlimWiki:
23
+
24
+ - Modify, adapt, translate, reverse-engineer, decompile, or disassemble
25
+ the Software, or create derivative works based on it, except to the
26
+ minimum extent expressly permitted by applicable law.
27
+ - Redistribute modified copies of the Software, or republish it under a
28
+ different name or organisation.
29
+ - Use the Software to build, train, or operate a product or service that
30
+ competes with SlimWiki.
31
+ - Remove or alter any copyright, trademark, or attribution notices.
32
+
33
+ ## 3. No transfer of rights
34
+
35
+ All right, title, and interest in and to the Software (including all
36
+ intellectual property rights) remain with SlimWiki. No rights are
37
+ granted by implication, estoppel, or otherwise except as expressly set
38
+ out in this licence.
39
+
40
+ ## 4. Trademarks
41
+
42
+ "SlimWiki" and the SlimWiki logo are trademarks of SlimWiki Pte. Ltd.
43
+ This licence does not grant you any rights to use those trademarks.
44
+
45
+ ## 5. Disclaimer of warranty
46
+
47
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
48
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
50
+
51
+ ## 6. Limitation of liability
52
+
53
+ IN NO EVENT SHALL SLIMWIKI BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
54
+ LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR
55
+ ITS USE.
56
+
57
+ ## 7. Termination
58
+
59
+ This licence terminates automatically if you breach any of its terms.
60
+ On termination, you must cease all use of the Software and destroy any
61
+ copies in your possession.
62
+
63
+ ## 8. Contact
64
+
65
+ For licensing inquiries, please contact: support@slimwiki.com