@creator-notes/cli 0.1.0 → 0.2.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/SKILL.md +410 -0
- package/dist/lib/auth-store.js +1 -1
- package/dist/lib/auth-store.js.map +1 -1
- package/package.json +3 -2
package/SKILL.md
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
You are operating PM Notes via the `cn` CLI (CreatorNotes CLI). Use the CLI to read, create, update, and organize notes, canvases, versions, and relationships.
|
|
2
|
+
|
|
3
|
+
## Task
|
|
4
|
+
|
|
5
|
+
$ARGUMENTS
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
The CLI is already installed and authenticated. The default server is `https://creatornotes.app`.
|
|
10
|
+
|
|
11
|
+
Before starting, confirm the active workspace:
|
|
12
|
+
```bash
|
|
13
|
+
cd /workspaces/pm-notes && npx cn workspace current
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
If no workspace is set, list available workspaces and select one:
|
|
17
|
+
```bash
|
|
18
|
+
npx cn workspace list
|
|
19
|
+
npx cn workspace select <id>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Command Reference
|
|
23
|
+
|
|
24
|
+
### Global Flags (apply to ALL commands)
|
|
25
|
+
```
|
|
26
|
+
--json Output raw JSON (best for piping / parsing)
|
|
27
|
+
-q, --quiet Minimal output (IDs only — useful for scripting)
|
|
28
|
+
-w, --workspace <id> Override active workspace
|
|
29
|
+
--server <url> Override server URL
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Notes (`cn notes` / `cn n`)
|
|
33
|
+
```bash
|
|
34
|
+
# List notes (default 20, excludes drafts)
|
|
35
|
+
npx cn notes list [--search <query>] [--type <type>] [--tags <csv>] [--pinned] [--limit <n>]
|
|
36
|
+
|
|
37
|
+
# Get a single note by display ID or Convex ID
|
|
38
|
+
npx cn notes get <id> [--all-versions]
|
|
39
|
+
|
|
40
|
+
# Create a note
|
|
41
|
+
npx cn notes create --markdown-file <path.md> [--title <title>] [--type <type>] [--tags <csv>] [--draft]
|
|
42
|
+
npx cn notes create --markdown "<content>" [--title <title>] [--type <type>] [--tags <csv>] [--draft] # inline (short content only)
|
|
43
|
+
npx cn notes create --content-file <path.json> # TipTap JSON from file
|
|
44
|
+
npx cn notes create --content-stdin # TipTap JSON from stdin
|
|
45
|
+
|
|
46
|
+
# Update metadata only (not content — use versions for that)
|
|
47
|
+
npx cn notes update <id> [--title <t>] [--type <t>] [--tags <csv>] [--archive] [--unarchive] [--pin] [--unpin]
|
|
48
|
+
|
|
49
|
+
# Delete (archive)
|
|
50
|
+
npx cn notes delete <id>
|
|
51
|
+
|
|
52
|
+
# Bulk archive/unarchive multiple notes at once
|
|
53
|
+
npx cn notes bulk-archive --ids '["MEETING-1","PRD-3","IDEA-7"]' [--unarchive]
|
|
54
|
+
|
|
55
|
+
# Bulk create interlinked notes in one atomic transaction
|
|
56
|
+
# Use @key placeholders for cross-references — resolved to real displayIds server-side
|
|
57
|
+
npx cn notes bulk-create --notes '[{"key":"A","title":"Note A","type":"Insight","markdownFile":"/tmp/a.md"},{"key":"B","title":"Note B","type":"Problem","markdownFile":"/tmp/b.md"}]' --json
|
|
58
|
+
|
|
59
|
+
# Text search
|
|
60
|
+
npx cn notes search <query> [--type <type>] [--limit <n>]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Versions (`cn versions` / `cn v`)
|
|
64
|
+
```bash
|
|
65
|
+
# List versions
|
|
66
|
+
npx cn versions list <noteId>
|
|
67
|
+
|
|
68
|
+
# Create a new version (updates note content)
|
|
69
|
+
npx cn versions create <noteId> --description "what changed" --markdown-file <path.md>
|
|
70
|
+
npx cn versions create <noteId> --description "what changed" --markdown "<short content>" # inline (short only)
|
|
71
|
+
npx cn versions create <noteId> --description "what changed" --content-file <path.json>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Canvas (`cn canvas` / `cn c`)
|
|
75
|
+
```bash
|
|
76
|
+
# List / get (archived canvases excluded by default)
|
|
77
|
+
npx cn canvas list [--include-archived]
|
|
78
|
+
npx cn canvas get <canvasId>
|
|
79
|
+
|
|
80
|
+
# AI digest (summary) of canvas
|
|
81
|
+
npx cn canvas digest <canvasId>
|
|
82
|
+
|
|
83
|
+
# Create / delete
|
|
84
|
+
npx cn canvas create "<name>"
|
|
85
|
+
npx cn canvas delete <canvasId>
|
|
86
|
+
npx cn canvas set-as-home <canvasId>
|
|
87
|
+
|
|
88
|
+
# Add nodes to canvas
|
|
89
|
+
npx cn canvas add-node <canvasId> --note <noteId> [--x <n>] [--y <n>]
|
|
90
|
+
npx cn canvas add-text <canvasId> --text "<content>" [--size heading|paragraph] [--x <n>] [--y <n>]
|
|
91
|
+
npx cn canvas add-list <canvasId> --name "<name>" --notes <id1,id2,...> [--view list|grid] [--x <n>] [--y <n>]
|
|
92
|
+
npx cn canvas add-link <canvasId> --target <otherCanvasId> [--x <n>] [--y <n>]
|
|
93
|
+
|
|
94
|
+
# Bulk add multiple notes at once (more efficient than repeated add-node)
|
|
95
|
+
npx cn canvas bulk-add <canvasId> --notes '[{"noteId":"NOTE-1","x":100,"y":100},{"noteId":"NOTE-2","x":400,"y":100}]'
|
|
96
|
+
|
|
97
|
+
# Move / remove nodes
|
|
98
|
+
npx cn canvas move-node <canvasId> --node <nodeId> --x <n> --y <n>
|
|
99
|
+
npx cn canvas remove-node <canvasId> --node <nodeId>
|
|
100
|
+
|
|
101
|
+
# Bulk remove multiple nodes at once
|
|
102
|
+
npx cn canvas bulk-remove <canvasId> --nodes '["nodeId1","nodeId2"]'
|
|
103
|
+
|
|
104
|
+
# Bulk move multiple nodes at once (more efficient than repeated move-node)
|
|
105
|
+
npx cn canvas bulk-move <canvasId> --moves '[{"nodeId":"abc","nodeType":"note","x":200,"y":300},{"nodeId":"def","nodeType":"text","x":500,"y":300}]'
|
|
106
|
+
# nodeType: note | text | list | canvas (defaults to "note")
|
|
107
|
+
|
|
108
|
+
# Connect nodes
|
|
109
|
+
npx cn canvas add-edge <canvasId> --source <nodeId> --target <nodeId> [--label "<text>"]
|
|
110
|
+
|
|
111
|
+
# Templates — create structured canvases from predefined layouts
|
|
112
|
+
npx cn canvas templates # List available templates
|
|
113
|
+
npx cn canvas from-template <templateId> [--title "<title>"] # Create empty skeleton
|
|
114
|
+
npx cn canvas from-template <templateId> --populate # Auto-populate zones with matching notes
|
|
115
|
+
# Templates: sprint-retrospective, swot-analysis, kanban-board, feature-prioritization, meeting-notes, product-roadmap
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Timeline (`cn timeline` / `cn tl`)
|
|
119
|
+
```bash
|
|
120
|
+
# Show recent changes (default: last 7 days)
|
|
121
|
+
npx cn timeline [--since <when>] [--until <when>] [--type <noteType>] [--note <filter>] [--limit <n>]
|
|
122
|
+
|
|
123
|
+
# Examples
|
|
124
|
+
npx cn timeline # last 7 days
|
|
125
|
+
npx cn timeline --since 30d # last 30 days
|
|
126
|
+
npx cn timeline --since 2w --type Meeting # meetings in last 2 weeks
|
|
127
|
+
npx cn timeline --since 7d --note standup # filter by note name
|
|
128
|
+
# Supported --since formats: relative (7d, 2w, 3h, 30m), ISO date (2026-03-21), unix ms
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Relationships (`cn relationships` / `cn rel`)
|
|
132
|
+
```bash
|
|
133
|
+
npx cn rel list [--note <displayId>]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Semantic Search (`cn search` / `cn s`)
|
|
137
|
+
```bash
|
|
138
|
+
npx cn search semantic "<query>" [--limit <n>] [--canvas <canvasId>]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Types (`cn types` / `cn t`)
|
|
142
|
+
```bash
|
|
143
|
+
# List all types (supertags) in the workspace
|
|
144
|
+
npx cn types list
|
|
145
|
+
|
|
146
|
+
# Create a new type
|
|
147
|
+
npx cn types create <name> [--prefix <PREFIX>] [--display-name <name>] [--description <text>] [--color <hex>]
|
|
148
|
+
|
|
149
|
+
# Update an existing type
|
|
150
|
+
npx cn types update <name> [--prefix <PREFIX>] [--display-name <name>] [--description <text>] [--color <hex>]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Memory (`cn memory` / `cn mem`)
|
|
154
|
+
```bash
|
|
155
|
+
# Search facts and entities by relevance
|
|
156
|
+
npx cn memory query "<query>" [--limit <n>] [--source <conversation|notes>]
|
|
157
|
+
|
|
158
|
+
# List all workspace facts (extracted from notes and conversations)
|
|
159
|
+
npx cn memory facts [--source <conversation|notes>]
|
|
160
|
+
|
|
161
|
+
# List all entities (people, topics, orgs) identified by Zep
|
|
162
|
+
npx cn memory entities [--source <conversation|notes>]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Auth & Config
|
|
166
|
+
```bash
|
|
167
|
+
npx cn auth login # Browser OAuth
|
|
168
|
+
npx cn auth login --token <key> # Direct API key
|
|
169
|
+
npx cn auth status
|
|
170
|
+
npx cn config get-server
|
|
171
|
+
npx cn config set-server <url>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Best Practices
|
|
175
|
+
|
|
176
|
+
### Note IDs
|
|
177
|
+
- Notes have **display IDs** like `MEETING-12`, `PRD-5`, `IDEA-3` — use these in commands.
|
|
178
|
+
- Convex IDs (e.g., `n17a43p7aenrxyr...`) also work but are less readable.
|
|
179
|
+
- When creating notes, capture the display ID from the output for subsequent commands.
|
|
180
|
+
|
|
181
|
+
### Note Types (IMPORTANT)
|
|
182
|
+
- The `--type` parameter must reference an **existing supertag** in the workspace. Free-text type strings are rejected.
|
|
183
|
+
- Before creating a note, check available types with `cn types list`.
|
|
184
|
+
- If the type you need doesn't exist, create it first: `cn types create "MyType" --prefix "MT"`
|
|
185
|
+
- Type names are **case-sensitive** and use PascalCase (e.g., `Update`, `PainPoint`, `Meeting`).
|
|
186
|
+
- The display ID prefix (e.g., `UPDATE-`, `PP-`) comes from the supertag's `prefix` field.
|
|
187
|
+
|
|
188
|
+
### Content via Markdown
|
|
189
|
+
- For multi-line content, **always use `--markdown-file`**: write content to a temp file first, then pass the path. This keeps the bash command on a single line so it doesn't trigger permission prompts.
|
|
190
|
+
```bash
|
|
191
|
+
# Write content to temp file, then create note with single-line command
|
|
192
|
+
npx cn notes create --markdown-file /tmp/note.md --title "My Note" --type "Note"
|
|
193
|
+
```
|
|
194
|
+
- Only use inline `--markdown "..."` for very short, single-line content.
|
|
195
|
+
- The server converts markdown to TipTap JSON automatically.
|
|
196
|
+
- **Relationship mentions in markdown**: Use `[NOTE-123](relationship:references)` or `[NOTE-123: Title](relationship:references)` syntax — plain text "NOTE-123" does NOT create clickable mentions.
|
|
197
|
+
- Supported relationship types: `depends-on`, `blocks`, `related-to`, `derived-from`, `references`, `extends`, `implements`, `invalidates`, `duplicates`
|
|
198
|
+
- Simple mention shorthand: `[NOTE-123]` or `[NOTE-123: Title]` (defaults to "references")
|
|
199
|
+
|
|
200
|
+
### Updating Content vs Metadata
|
|
201
|
+
- To change note **content**, create a new **version**: `cn versions create <id> --description "..." --markdown "..."`
|
|
202
|
+
- To change note **title/type/tags/pin/archive**, use: `cn notes update <id> --title "..."`
|
|
203
|
+
- These are separate operations by design.
|
|
204
|
+
|
|
205
|
+
### JSON Mode for Scripting
|
|
206
|
+
- Use `--json` to get raw JSON output for parsing with `jq` or piping between commands.
|
|
207
|
+
- Use `-q` (quiet) to get just the ID, useful for chaining:
|
|
208
|
+
```bash
|
|
209
|
+
NOTE_ID=$(npx cn notes create --markdown "..." -q)
|
|
210
|
+
npx cn canvas add-node <canvasId> --note "$NOTE_ID"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Canvas Layout Planning (IMPORTANT — Bulk-Add with Pre-Calculated Positions)
|
|
214
|
+
|
|
215
|
+
When adding 3+ notes to a canvas, **plan all positions upfront** and use `bulk-add` in a single call. Do NOT add notes one-by-one with `add-node`.
|
|
216
|
+
|
|
217
|
+
#### Layout Constants
|
|
218
|
+
|
|
219
|
+
| Item | Width (px) | Height (px) |
|
|
220
|
+
|------|-----------|-------------|
|
|
221
|
+
| Node (rendered) | 280 | 100 |
|
|
222
|
+
| Grid cell (node + padding) | 400 | 180 |
|
|
223
|
+
| Edge label | ~80 | ~14 |
|
|
224
|
+
| Label collision zone | 80 horizontal | 14 vertical |
|
|
225
|
+
|
|
226
|
+
Node center offset from top-left: `(+140, +50)`.
|
|
227
|
+
|
|
228
|
+
#### Text Node Sizing
|
|
229
|
+
|
|
230
|
+
Use `--size` to control text node font size (default: `heading`):
|
|
231
|
+
|
|
232
|
+
| Size | Font | Renders as | Use for |
|
|
233
|
+
|------|------|------------|---------|
|
|
234
|
+
| `heading` (default) | 32px | `text-3xl font-bold` | Section headers, zone titles, canvas labels |
|
|
235
|
+
| `paragraph` | 18px | `text-lg font-medium` | Descriptions, annotations, supporting context |
|
|
236
|
+
|
|
237
|
+
For reference, the UI default for double-click-created text nodes is 60px (`text-[4rem]`). The CLI sizes are intentionally smaller since CLI-created text is typically structural.
|
|
238
|
+
|
|
239
|
+
**Rule of thumb:** Use `heading` for structural/navigational text and `paragraph` for explanatory or secondary text. When a canvas has both titles and descriptions, mix sizes to create visual hierarchy.
|
|
240
|
+
|
|
241
|
+
#### Algorithm: Hierarchical Layout
|
|
242
|
+
|
|
243
|
+
Follow these steps **before making any API calls**.
|
|
244
|
+
|
|
245
|
+
**Step 1 — Build the graph.** List all notes and their edge relationships:
|
|
246
|
+
```
|
|
247
|
+
A -> B (label: "drives")
|
|
248
|
+
A -> C (label: "informs")
|
|
249
|
+
B -> D (label: "blocks")
|
|
250
|
+
C -> D (label: "requires")
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Step 2 — Assign ranks (top-down layers).**
|
|
254
|
+
- Rank 0: nodes with no incoming edges (roots)
|
|
255
|
+
- Rank N: `max(rank of all parents) + 1`
|
|
256
|
+
- If a cycle exists, place the node at the higher rank
|
|
257
|
+
|
|
258
|
+
Example:
|
|
259
|
+
```
|
|
260
|
+
Rank 0: A
|
|
261
|
+
Rank 1: B, C
|
|
262
|
+
Rank 2: D
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Step 3 — Calculate positions.**
|
|
266
|
+
- `Y = 100 + rank × 180`
|
|
267
|
+
- For each rank with N nodes: `totalWidth = N × 400 − 120`
|
|
268
|
+
- Find the widest rank's totalWidth (`maxWidth`)
|
|
269
|
+
- `startX = 100 + (maxWidth − totalWidth) / 2`
|
|
270
|
+
- Each node: `X = startX + index × 400`
|
|
271
|
+
|
|
272
|
+
Example (widest rank has 2 nodes → maxWidth = 680):
|
|
273
|
+
```
|
|
274
|
+
Rank 0 (1 node): startX = 100 + (680−280)/2 = 300 → A: (300, 100)
|
|
275
|
+
Rank 1 (2 nodes): startX = 100 + (680−680)/2 = 100 → B: (100, 280) C: (500, 280)
|
|
276
|
+
Rank 2 (1 node): startX = 300 → D: (300, 460)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Step 4 — Compute edge label midpoints.** For each edge, the label renders at the midpoint of source and target node centers:
|
|
280
|
+
- Node center = `(nodeX + 140, nodeY + 50)`
|
|
281
|
+
- Label position = `((srcCenterX + tgtCenterX) / 2, (srcCenterY + tgtCenterY) / 2)`
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
A(300,100)->B(100,280): centers (440,150)→(240,330) → label (340, 240)
|
|
285
|
+
A(300,100)->C(500,280): centers (440,150)→(640,330) → label (540, 240)
|
|
286
|
+
B(100,280)->D(300,460): centers (240,330)→(440,510) → label (340, 420)
|
|
287
|
+
C(500,280)->D(300,460): centers (640,330)→(440,510) → label (540, 420)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Step 5 — Check label collisions.** Two labels collide when `|dx| < 80 AND |dy| < 14`. Check every pair:
|
|
291
|
+
```
|
|
292
|
+
(340,240) vs (540,240): |dx|=200 > 80 → OK
|
|
293
|
+
(340,240) vs (340,420): |dy|=180 > 14 → OK
|
|
294
|
+
(340,420) vs (540,420): |dx|=200 > 80 → OK
|
|
295
|
+
... all other pairs also clear. No collisions.
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Step 6 — Fix collisions (if any).** When two labels collide:
|
|
299
|
+
1. Identify which edges share the collision
|
|
300
|
+
2. Pick the shared node between those edges. If none, pick the lower-rank node from either edge
|
|
301
|
+
3. Nudge that node horizontally by **+100px** (or −100px if it would go off-screen)
|
|
302
|
+
4. **Recalculate ALL label midpoints** (not just the pair that collided)
|
|
303
|
+
5. Re-check all pairs. Repeat up to **3 iterations**. If still colliding, accept it
|
|
304
|
+
|
|
305
|
+
**Step 7 — Execute.** One `bulk-add`, then all edges:
|
|
306
|
+
```bash
|
|
307
|
+
npx cn canvas bulk-add <canvasId> --notes '[{"noteId":"A-ID","x":300,"y":100},{"noteId":"B-ID","x":100,"y":280},{"noteId":"C-ID","x":500,"y":280},{"noteId":"D-ID","x":300,"y":460}]' --json
|
|
308
|
+
# Parse node IDs from --json output, then:
|
|
309
|
+
npx cn canvas add-edge <canvasId> --source <A-nodeId> --target <B-nodeId> --label "drives"
|
|
310
|
+
npx cn canvas add-edge <canvasId> --source <A-nodeId> --target <C-nodeId> --label "informs"
|
|
311
|
+
npx cn canvas add-edge <canvasId> --source <B-nodeId> --target <D-nodeId> --label "blocks"
|
|
312
|
+
npx cn canvas add-edge <canvasId> --source <C-nodeId> --target <D-nodeId> --label "requires"
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Quick Reference: Common Topologies
|
|
316
|
+
|
|
317
|
+
**Linear chain** (A→B→C→D): stack vertically at X=300, Y increments of 180.
|
|
318
|
+
```
|
|
319
|
+
A:(300,100) B:(300,280) C:(300,460) D:(300,640)
|
|
320
|
+
```
|
|
321
|
+
No label collisions (all labels share X=440 but different Y).
|
|
322
|
+
|
|
323
|
+
**Fan-out** (A→B, A→C, A→D): root on top, children spread horizontally at 400px intervals.
|
|
324
|
+
```
|
|
325
|
+
A:(500,100) B:(100,280) C:(500,280) D:(900,280)
|
|
326
|
+
```
|
|
327
|
+
Labels at distinct X positions — no collisions.
|
|
328
|
+
|
|
329
|
+
**Diamond** (A→B, A→C, B→D, C→D): the worked example above. 2-column layout.
|
|
330
|
+
|
|
331
|
+
**Wide fan** (5+ children): 400px spacing per child.
|
|
332
|
+
```
|
|
333
|
+
Root:(900,100) C1:(100,280) C2:(500,280) C3:(900,280) C4:(1300,280) C5:(1700,280)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### Layout Rules Summary
|
|
337
|
+
|
|
338
|
+
1. **Always plan the full graph before any API call.** List all notes, relationships, and compute positions first.
|
|
339
|
+
2. **Use `bulk-add` for 3+ notes, not repeated `add-node`.** One call, all positions.
|
|
340
|
+
3. **400px horizontal / 180px vertical** minimum spacing between node top-left origins.
|
|
341
|
+
4. **Check every pair of edge label midpoints.** Collision = `|dx| < 80 AND |dy| < 14`.
|
|
342
|
+
5. **Nudge horizontally by ±100px** to fix collisions. Recalculate all midpoints after each nudge. Max 3 iterations.
|
|
343
|
+
6. **Parse `bulk-add --json` output** to get node IDs for `add-edge` commands.
|
|
344
|
+
|
|
345
|
+
### Interlinking Notes (IMPORTANT)
|
|
346
|
+
When creating multiple notes that belong together (e.g., for a canvas, onboarding guide, or knowledge map), you MUST interlink them at two levels:
|
|
347
|
+
|
|
348
|
+
**1. Relationship mentions inside note content** — so notes are connected in the note graph:
|
|
349
|
+
- **Use `cn notes bulk-create`** to create all notes with cross-references in a single atomic call.
|
|
350
|
+
- Use `@key` placeholders to reference other notes in the batch: `[@B: The Problem](relationship:references)`
|
|
351
|
+
- The server resolves placeholders to real display IDs, creates all notes, and extracts relationships in one transaction.
|
|
352
|
+
- Workflow:
|
|
353
|
+
1. Write all markdown files to `/tmp/`, using `[@key: Title](relationship:type)` for cross-references
|
|
354
|
+
2. Run `cn notes bulk-create --notes '[{"key":"A",...,"markdownFile":"/tmp/a.md"},...]' --json`
|
|
355
|
+
3. Parse the JSON output for display IDs and Convex IDs
|
|
356
|
+
|
|
357
|
+
**2. Canvas edges between nodes** — so the visual canvas shows connections:
|
|
358
|
+
- After adding all nodes to a canvas, add labeled edges between related nodes.
|
|
359
|
+
- Use descriptive labels that explain the relationship (e.g., "triggers", "feeds data to", "depends on").
|
|
360
|
+
- `cn canvas add-edge <canvasId> --source <nodeId> --target <nodeId> --label "relationship"`
|
|
361
|
+
|
|
362
|
+
Both levels are needed: edges are visual-only (canvas), mentions are content-level (note graph). Skipping either leaves the knowledge disconnected.
|
|
363
|
+
|
|
364
|
+
#### Placeholder Syntax for `bulk-create`
|
|
365
|
+
|
|
366
|
+
Use `[@key: Title](relationship:type)` where `key` matches a note's `key` field in the `--notes` JSON:
|
|
367
|
+
```markdown
|
|
368
|
+
This builds on [@B: The Problem](relationship:references) and enables [@C: The Workflow](relationship:derived-from).
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
The `@` prefix distinguishes placeholders from real display IDs. If a placeholder key doesn't match any note in the batch, the entire operation fails (nothing gets created).
|
|
372
|
+
|
|
373
|
+
Supported relationship types: `depends-on`, `blocks`, `related-to`, `derived-from`, `references`, `extends`, `implements`, `invalidates`, `duplicates`
|
|
374
|
+
|
|
375
|
+
### Gathering Context with Memory (IMPORTANT)
|
|
376
|
+
Before creating or updating notes on a topic, **query Zep memory first** to understand what is already known. Use iterative traversal:
|
|
377
|
+
|
|
378
|
+
1. **Start broad:** `cn memory query "<topic>"` — get the top facts and entities.
|
|
379
|
+
2. **Follow interesting entities:** If the results mention related people, teams, initiatives, or dependencies, run follow-up queries on those (e.g., `cn memory query "Draft content team"`, `cn memory query "InfoTrack certificates"`).
|
|
380
|
+
3. **Check temporal validity:** Facts have `validAt`/`invalidAt` timestamps. Superseded facts (with `invalidAt` in the past) show what *was* true — prefer current facts for recommendations, but cite historical facts when explaining how something evolved.
|
|
381
|
+
4. **Synthesize across hops:** After 2-3 queries, combine the facts into a coherent summary before acting. This gives much richer context than a single query.
|
|
382
|
+
|
|
383
|
+
**When to use memory:**
|
|
384
|
+
- Before drafting a note on a topic the user has discussed before
|
|
385
|
+
- When the user asks "what do we know about X?" or "give me context on X"
|
|
386
|
+
- When creating a canvas or linking notes — memory reveals connections between topics
|
|
387
|
+
- When the user asks about people, teams, or initiatives — entities track these
|
|
388
|
+
|
|
389
|
+
**When NOT to use memory:**
|
|
390
|
+
- For simple CRUD operations (create a note, add a node) where the user gives explicit content
|
|
391
|
+
- When the user says they want a fresh take without prior context
|
|
392
|
+
|
|
393
|
+
### Error Handling
|
|
394
|
+
- If a command fails with auth errors, run `npx cn auth status` to verify credentials.
|
|
395
|
+
- If workspace-related errors occur, verify the workspace with `npx cn workspace current`.
|
|
396
|
+
|
|
397
|
+
## Rules
|
|
398
|
+
|
|
399
|
+
- **ALWAYS write each bash command as a single line.** Never split variable assignments and commands across multiple lines. Use inline env vars: `CANVAS=abc npx cn canvas get $CANVAS` — NOT separate lines. Multi-line commands trigger permission prompts.
|
|
400
|
+
- Always run commands from `/workspaces/pm-notes` directory so `npx cn` resolves correctly.
|
|
401
|
+
- Always use `--json` when you need to parse output programmatically.
|
|
402
|
+
- **NEVER leave multi-note work disconnected.** When creating 2+ related notes, use `cn notes bulk-create` with `@key` placeholders to create all notes with cross-references in one atomic call. Then add canvas edges if the notes are on a canvas. Both levels (content mentions + canvas edges) are mandatory.
|
|
403
|
+
- Do NOT use interactive mode flags — the CLI uses interactive prompts (select menus) in TTY mode which do not work in this environment. Always use `--json` or `-q` to bypass interactive prompts.
|
|
404
|
+
- Prefer semantic search (`cn search semantic`) over text search (`cn notes search`) when looking for conceptually related notes.
|
|
405
|
+
- **Clickable links after creation:** When you create a note or canvas, include a clickable link in your response so the user can open it directly in CreatorNotes. Use the server URL from `cn config get-server` (default `https://creatornotes.app`):
|
|
406
|
+
- **Note:** `[DISPLAY-ID: Title](https://creatornotes.app/ws/{workspaceId}?noteId={noteConvexId})`
|
|
407
|
+
- **Canvas:** `[Canvas Name](https://creatornotes.app/ws/{workspaceId}?canvasId={canvasId})`
|
|
408
|
+
- Always extract the IDs from the `--json` output of the create command.
|
|
409
|
+
- **Mention syntax in markdown must be standalone.** NEVER wrap `[NOTE-XXX: Title](relationship:references)` mentions inside bold `**...**` markers or other inline formatting — this causes the raw markdown text to render alongside the mention chip, producing duplicated/garbled output.
|
|
410
|
+
- **When adding 3+ notes to a canvas, ALWAYS use `bulk-add` with pre-calculated positions.** Never use repeated `add-node` calls. Follow the Canvas Layout Planning algorithm above to compute positions and avoid edge label overlap.
|
package/dist/lib/auth-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAclC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,SAAS,aAAa;IACpB,OAAO;QACL,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,EAAE;QACX,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAclC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AACpD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,SAAS,aAAa;IACpB,OAAO;QACL,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,EAAE;QACX,aAAa,EAAE,0BAA0B;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;QACjE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,kDAAkD;IAClD,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAe;IAChE,MAAM,SAAS,GAAG,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC;IACjD,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,MAAiB,EACjB,SAAiB,EACjB,YAA0B;IAE1B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC;IACzC,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,SAAiB;IACrE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAiB;IACnE,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAiB,EACjB,SAAiB,EACjB,WAAmB;IAEnB,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,WAAW,GAAG,WAAW,CAAC;QAC7B,UAAU,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creator-notes/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI for CreatorNotes — create notes, build canvases, search knowledge from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"cn-mcp": "./dist/mcp-server.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"dist"
|
|
11
|
+
"dist",
|
|
12
|
+
"SKILL.md"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"build": "tsc",
|