@unified-product-graph/cli 0.6.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +247 -0
  4. package/dist/cli.cjs +141010 -0
  5. package/package.json +65 -0
  6. package/skills/README.md +10 -0
  7. package/skills/upg/SKILL.md +245 -0
  8. package/skills/upg-analytics/SKILL.md +135 -0
  9. package/skills/upg-capture/SKILL.md +274 -0
  10. package/skills/upg-connect/SKILL.md +167 -0
  11. package/skills/upg-context/SKILL.md +506 -0
  12. package/skills/upg-context-intelligence/SKILL.md +227 -0
  13. package/skills/upg-design-system/SKILL.md +265 -0
  14. package/skills/upg-diff/SKILL.md +150 -0
  15. package/skills/upg-discover/SKILL.md +290 -0
  16. package/skills/upg-explore/SKILL-DETAIL.md +481 -0
  17. package/skills/upg-explore/SKILL.md +297 -0
  18. package/skills/upg-export/SKILL.md +385 -0
  19. package/skills/upg-feedback/SKILL.md +141 -0
  20. package/skills/upg-gaps/SKILL.md +376 -0
  21. package/skills/upg-hypothesis/SKILL.md +190 -0
  22. package/skills/upg-impact/SKILL.md +229 -0
  23. package/skills/upg-import/SKILL.md +189 -0
  24. package/skills/upg-init/SKILL.md +410 -0
  25. package/skills/upg-inspect/SKILL.md +167 -0
  26. package/skills/upg-journey/SKILL.md +207 -0
  27. package/skills/upg-launch/SKILL-DETAIL.md +392 -0
  28. package/skills/upg-launch/SKILL.md +141 -0
  29. package/skills/upg-migrate/SKILL.md +146 -0
  30. package/skills/upg-okr/SKILL-DETAIL.md +351 -0
  31. package/skills/upg-okr/SKILL.md +88 -0
  32. package/skills/upg-persona/SKILL.md +230 -0
  33. package/skills/upg-prioritise/SKILL.md +195 -0
  34. package/skills/upg-pull/SKILL-DETAIL.md +398 -0
  35. package/skills/upg-pull/SKILL.md +57 -0
  36. package/skills/upg-push/SKILL-DETAIL.md +385 -0
  37. package/skills/upg-push/SKILL.md +113 -0
  38. package/skills/upg-reflect/SKILL.md +201 -0
  39. package/skills/upg-research/SKILL.md +336 -0
  40. package/skills/upg-rollback/SKILL.md +163 -0
  41. package/skills/upg-run/SKILL.md +126 -0
  42. package/skills/upg-schema-changelog/SKILL.md +231 -0
  43. package/skills/upg-schema-consolidate/SKILL.md +243 -0
  44. package/skills/upg-schema-edges/SKILL.md +287 -0
  45. package/skills/upg-schema-evolve/SKILL.md +313 -0
  46. package/skills/upg-schema-health/SKILL.md +279 -0
  47. package/skills/upg-schema-update/SKILL.md +206 -0
  48. package/skills/upg-snapshot/SKILL.md +108 -0
  49. package/skills/upg-status/SKILL.md +340 -0
  50. package/skills/upg-strategy/SKILL.md +334 -0
  51. package/skills/upg-template/SKILL.md +145 -0
  52. package/skills/upg-trace/SKILL.md +197 -0
  53. package/skills/upg-tree/SKILL.md +233 -0
  54. package/skills/upg-verify/SKILL.md +223 -0
  55. package/skills/upg-workspace/SKILL.md +103 -0
@@ -0,0 +1,398 @@
1
+ ---
2
+ name: upg-pull-detail
3
+ description: "Detailed pull flow, merge logic, incremental sync"
4
+ ---
5
+
6
+ # /upg-pull — Pull Flow Detail
7
+
8
+ ## Pull Flow
9
+
10
+ ### Step 1: Connect to Cloud
11
+
12
+ ```
13
+ mcp__upg-cloud__list_products()
14
+ ```
15
+
16
+ If this fails (auth error):
17
+ ```
18
+ To pull from The Product Creator, you need an API key configured.
19
+
20
+ 1. Log in at cloud.unifiedproductgraph.org
21
+ 2. Go to Settings → API Keys → Create New Key
22
+ 3. Add to your .mcp.json config
23
+
24
+ Once configured, run /upg-pull again.
25
+ ```
26
+
27
+ ### Step 2: Select Product
28
+
29
+ If the user specified a product name, search for it. Otherwise, list all products:
30
+
31
+ ```
32
+ Your products on The Product Creator:
33
+
34
+ 1. My SaaS App (42 entities, 38 edges)
35
+ 2. Side Project (12 entities, 8 edges)
36
+ 3. Client Engagement (67 entities, 55 edges)
37
+
38
+ Which one do you want to pull down? (number or name)
39
+ ```
40
+
41
+ ### Step 3: Determine Sync Mode
42
+
43
+ Once the user selects a product, check the local state to determine which pull flow to use:
44
+
45
+ 1. **Read the `.upg-sync` file** from the current directory using the Read tool.
46
+ 2. **Read the `.upg` file** if it exists.
47
+
48
+ **Decision matrix:**
49
+
50
+ | .upg-sync exists? | Matches selected product_id? | .upg exists? | Flow |
51
+ |---|---|---|---|
52
+ | No | — | No | **First-time pull** (Step 4A) |
53
+ | No | — | Yes | **Overwrite warning** (Step 4B) |
54
+ | Yes | Yes | Yes | **Incremental pull** (Step 4C) |
55
+ | Yes | No | Yes | **Different product warning** (Step 4B) |
56
+ | Yes | Yes | No | **First-time pull** — sync file is stale, treat as fresh (Step 4A) |
57
+
58
+ ---
59
+
60
+ ### Step 4A: First-Time Pull (Full)
61
+
62
+ No sync file exists and no local `.upg` file, or the sync file is stale. This is a clean pull.
63
+
64
+ #### Fetch the full graph:
65
+
66
+ ```
67
+ mcp__upg-cloud__get_product_graph({
68
+ product_id: "<selected_product_id>"
69
+ })
70
+ ```
71
+
72
+ #### Transform to .upg format:
73
+
74
+ For each cloud node, generate a local `n_xxx` ID (nanoid-style short ID). For each cloud edge, generate a local `e_xxx` ID. Build the ID maps as you go.
75
+
76
+ ```json
77
+ {
78
+ "upg_version": "0.1.0",
79
+ "exported_at": "<current ISO 8601 timestamp>",
80
+ "source": {
81
+ "tool": "upg-cloud-cloud",
82
+ "tool_version": "1.0.0"
83
+ },
84
+ "product": {
85
+ "id": "p_<nanoid>",
86
+ "title": "<product title>",
87
+ "description": "<product description>",
88
+ "stage": "<stage if available>"
89
+ },
90
+ "nodes": [
91
+ {
92
+ "id": "n_<nanoid>",
93
+ "type": "<entity type>",
94
+ "title": "<title>",
95
+ "description": "<description>",
96
+ "tags": [],
97
+ "status": "<status>",
98
+ "properties": { ... }
99
+ }
100
+ ],
101
+ "edges": [
102
+ {
103
+ "id": "e_<nanoid>",
104
+ "source": "n_<source local id>",
105
+ "target": "n_<target local id>",
106
+ "type": "<edge type>"
107
+ }
108
+ ]
109
+ }
110
+ ```
111
+
112
+ **Important:** Edge source/target must reference the LOCAL IDs you generated, not the cloud UUIDs. Use the node_id_map you're building to translate.
113
+
114
+ #### Write both files:
115
+
116
+ 1. Write the `.upg` file using the Write tool.
117
+ 2. **Create the `.upg-sync` file** with the full ID mapping:
118
+
119
+ ```json
120
+ {
121
+ "cloud_endpoint": "https://cloud.unifiedproductgraph.org",
122
+ "product_id": "<cloud-product-uuid>",
123
+ "last_synced_at": "<current ISO 8601 timestamp>",
124
+ "node_id_map": {
125
+ "n_local1": "cloud-uuid-1",
126
+ "n_local2": "cloud-uuid-2"
127
+ },
128
+ "edge_id_map": {
129
+ "e_local1": "cloud-uuid-1",
130
+ "e_local2": "cloud-uuid-2"
131
+ },
132
+ "last_snapshot_hash": "<sha256 of the cloud graph JSON>"
133
+ }
134
+ ```
135
+
136
+ To compute `last_snapshot_hash`: take the cloud graph response (nodes + edges, sorted by ID for determinism), JSON-stringify it, and compute a SHA-256 hash via Bash:
137
+ ```bash
138
+ echo -n '<sorted-json-string>' | shasum -a 256 | cut -d' ' -f1
139
+ ```
140
+
141
+ #### Confirm:
142
+
143
+ ```
144
+ ## Pull Complete
145
+
146
+ Pulled "<Product Name>" from The Product Creator cloud.
147
+
148
+ File: product.upg
149
+ Sync: .upg-sync (ID mapping + sync state created)
150
+ Entities: <N> (<breakdown by type>)
151
+ Connections: <N>
152
+ Domains: <N> covered
153
+
154
+ Your graph is now local. It's a .upg file — portable, git-friendly, yours.
155
+ ```
156
+
157
+ Then show the "What You Can Do Now" section (Step 6).
158
+
159
+ ---
160
+
161
+ ### Step 4B: Overwrite Warning
162
+
163
+ A local `.upg` file exists but there's no matching sync file (either no sync file at all, or the sync file points to a different product).
164
+
165
+ ```
166
+ A local .upg file already exists: product.upg (<N> entities)
167
+ ```
168
+
169
+ If no sync file:
170
+ ```
171
+ There's no sync file (.upg-sync), so I can't merge incrementally.
172
+ Pulling will overwrite your local graph with the cloud version.
173
+
174
+ Want to proceed? (This is not reversible unless you have a git commit)
175
+ ```
176
+
177
+ If sync file points to different product:
178
+ ```
179
+ Your sync file is linked to a different cloud product ("<other product name>").
180
+ Pulling "<selected product name>" will replace your local graph and sync state.
181
+
182
+ Want to proceed?
183
+ ```
184
+
185
+ If user confirms, proceed with Step 4A (full pull, overwriting both files).
186
+ If user declines, suggest:
187
+ ```
188
+ You can:
189
+ - Save your current .upg file first: cp product.upg product-backup.upg
190
+ - Or commit it to git: git add product.upg && git commit -m "Backup before pull"
191
+ - Then run /upg-pull again
192
+ ```
193
+
194
+ ---
195
+
196
+ ### Step 4C: Incremental Pull (Sync File Exists and Matches)
197
+
198
+ This is the core incremental sync flow. The sync file exists, matches the selected product, and a local `.upg` file is present.
199
+
200
+ #### 1. Read current state
201
+
202
+ Read three things:
203
+ - The local `.upg` file (via Read tool)
204
+ - The `.upg-sync` file (via Read tool)
205
+ - The cloud graph (via `mcp__upg-cloud__get_product_graph()`)
206
+
207
+ #### 2. Compute the cloud snapshot hash
208
+
209
+ Hash the cloud graph response the same way as during full pull. Compare against `last_snapshot_hash` from the sync file.
210
+
211
+ **If hashes match:**
212
+ ```
213
+ Your local graph is up to date with the cloud.
214
+
215
+ No changes detected on The Product Creator since your last sync
216
+ (<last_synced_at formatted nicely>).
217
+ ```
218
+ Stop here. No changes needed.
219
+
220
+ **If hashes differ:** Continue to compute the changeset.
221
+
222
+ #### 3. Compute changeset
223
+
224
+ Compare the current cloud graph against what was synced last time. Use the `node_id_map` and `edge_id_map` from the sync file to correlate cloud and local entities.
225
+
226
+ **Cloud nodes — categorise each one:**
227
+
228
+ - **New on cloud:** Cloud node ID is NOT in any value of `node_id_map` — this entity was created on the cloud since last sync.
229
+ - **Updated on cloud:** Cloud node ID IS in `node_id_map`, and the node's content (title, description, type, properties, status, tags) differs from the corresponding local node.
230
+ - **Deleted on cloud:** A cloud ID exists in `node_id_map` values, but that cloud node no longer exists in the cloud graph response — it was deleted on the cloud since last sync.
231
+ - **Unchanged:** Cloud node ID is in `node_id_map` and content matches local. No action needed.
232
+
233
+ Do the same for edges using `edge_id_map`.
234
+
235
+ #### 4. Detect conflicts
236
+
237
+ Check if any node that is "updated on cloud" was ALSO modified locally since last sync. To detect local modifications:
238
+
239
+ - Compare the current local `.upg` file against the state that was synced (you can infer this from the sync file's hash — if the local file has diverged from what was pulled, there may be local changes).
240
+ - A pragmatic v1 approach: if a node appears in the "updated on cloud" set, check if the local version of that same node (via ID map) differs from what the cloud had at last sync time. If you can't determine the exact last-synced local state, assume any local node that differs from the incoming cloud version is a conflict.
241
+
242
+ **Conflict resolution (v1 — last write wins, cloud takes precedence):**
243
+ - Apply the cloud version.
244
+ - But track and report the conflict count to the user.
245
+
246
+ #### 5. Show summary and ask for confirmation
247
+
248
+ ```
249
+ ## Incoming Changes from Cloud
250
+
251
+ Pulling "<Product Name>" — changes since <last_synced_at>:
252
+
253
+ + <N> new entities (<breakdown>)
254
+ ~ <N> updated entities
255
+ - <N> deleted entities
256
+ + <N> new connections
257
+ ~ <N> updated connections
258
+ - <N> deleted connections
259
+ ```
260
+
261
+ If there are conflicts:
262
+ ```
263
+ !! <N> entities were modified both locally and on the cloud.
264
+ Cloud version will be kept (last-write-wins).
265
+ ```
266
+
267
+ ```
268
+ Apply these changes to your local graph? (y/n)
269
+ ```
270
+
271
+ If no changes in any category:
272
+ ```
273
+ Your local graph is up to date with the cloud.
274
+ ```
275
+
276
+ #### 6. Apply changes to local .upg file
277
+
278
+ Read the current `.upg` file, then apply each change:
279
+
280
+ **New cloud nodes:**
281
+ - Generate a new local `n_xxx` ID for each
282
+ - Add the node to the `.upg` nodes array
283
+ - Add the mapping to `node_id_map`
284
+
285
+ **Updated cloud nodes:**
286
+ - Find the local node via `node_id_map` (reverse lookup: find the local ID whose mapped cloud ID matches)
287
+ - Update its title, description, type, properties, status, tags from the cloud version
288
+
289
+ **Deleted cloud nodes:**
290
+ - Find the local node via `node_id_map`
291
+ - Remove it from the `.upg` nodes array
292
+ - Remove the mapping from `node_id_map`
293
+ - Remove any edges that reference the deleted node
294
+
295
+ **New cloud edges:**
296
+ - Generate a new local `e_xxx` ID
297
+ - Translate source/target from cloud IDs to local IDs via `node_id_map`
298
+ - Add to the `.upg` edges array
299
+ - Add the mapping to `edge_id_map`
300
+
301
+ **Updated cloud edges:**
302
+ - Find the local edge via `edge_id_map`
303
+ - Update its source, target, type (translating cloud IDs to local IDs)
304
+
305
+ **Deleted cloud edges:**
306
+ - Find the local edge via `edge_id_map`
307
+ - Remove from `.upg` edges array
308
+ - Remove from `edge_id_map`
309
+
310
+ #### 7. Write updated files
311
+
312
+ 1. Write the updated `.upg` file
313
+ 2. Update the `.upg-sync` file:
314
+ - `last_synced_at` → current timestamp
315
+ - `node_id_map` → updated with new/removed mappings
316
+ - `edge_id_map` → updated with new/removed mappings
317
+ - `last_snapshot_hash` → hash of the current cloud graph
318
+
319
+ #### 8. Report results
320
+
321
+ ```
322
+ ## Pull Complete — Incremental Sync
323
+
324
+ Merged cloud changes into "<Product Name>".
325
+
326
+ + <N> entities added
327
+ ~ <N> entities updated
328
+ - <N> entities removed
329
+ + <N> connections added
330
+ ~ <N> connections updated
331
+ - <N> connections removed
332
+
333
+ Local graph: <total N> entities, <total N> connections
334
+ Synced at: <timestamp>
335
+ ```
336
+
337
+ If there were conflicts:
338
+ ```
339
+ !! <N> conflicts resolved (cloud version kept)
340
+ Future: /upg-resolve will let you review conflicts manually.
341
+ ```
342
+
343
+ Then show the "What You Can Do Now" section (Step 6 below).
344
+
345
+ ---
346
+
347
+ ### Step 5: Handle Edge Cases
348
+
349
+ **Cloud graph is empty:**
350
+ ```
351
+ "<Product Name>" has no entities in the cloud yet.
352
+ Build it locally with /upg-init, then /upg-push when ready.
353
+ ```
354
+
355
+ **Very large graph (200+ entities):**
356
+ ```
357
+ This is a large graph (<N> entities). The pull may take a moment...
358
+ ```
359
+ Use pagination if needed from the cloud API.
360
+
361
+ **Node type mapping:**
362
+ Cloud uses the same entity types as local (`@unified-product-graph/core` shared ontology), so types map directly. Cloud stores type-specific data in a `data` JSONB column — map this to `properties` in the `.upg` format.
363
+
364
+ ---
365
+
366
+ ### Step 6: What You Can Do Now
367
+
368
+ Show this section after every successful pull (full or incremental):
369
+
370
+ ```
371
+ ### What You Can Do Now
372
+
373
+ /upg-status — See your graph health dashboard
374
+ /upg-tree — View through framework lenses (ost, user, validation...)
375
+ /upg-gaps — Find strategic gaps and get action plans
376
+ /upg-explore — Add new entities locally
377
+ /upg-discover — Run a guided discovery session
378
+ /upg-push — Push local changes back to the cloud
379
+
380
+ ### Version Control
381
+
382
+ git add product.upg
383
+ git commit -m "Pull <product name> graph from cloud"
384
+
385
+ Now you have full git history of your product thinking.
386
+ Branch, diff, review — your graph is just data.
387
+
388
+ ### Stay in Sync
389
+
390
+ Edit locally, then /upg-push to sync back to the cloud.
391
+ Pull again with /upg-pull to get the latest from your team.
392
+ The .upg file is your source of truth for local work.
393
+
394
+ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
395
+ Your .upg file is yours — open standard, portable, git-friendly.
396
+ unifiedproductgraph.org
397
+ ```
398
+
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: upg-pull
3
+ description: "Pull a cloud graph down to a local .upg file"
4
+ user-invocable: true
5
+ argument-hint: "[product-name]"
6
+ category: tooling
7
+ ---
8
+
9
+ # /upg-pull — Pull Cloud Graph to Local
10
+
11
+ You are a Unified Product Graph sync engine. Your job is to pull a product graph from The Product Creator cloud into a local `.upg` file, enabling offline work, git version control, and CLI-based graph operations. You support both full pulls and incremental sync.
12
+
13
+ **Before producing any output, read the design system:** /upg-context for emoji mappings, score dots, bar styles, and formatting rules.
14
+
15
+ ## Tools
16
+
17
+ Use `mcp__upg-cloud__*` tools to read from the cloud graph.
18
+ Use Bash/Read/Write tools to read and write the `.upg` and `.upg-sync` files on disk.
19
+ The upg-local MCP server will auto-detect file changes via file watching — no restart needed.
20
+
21
+ ## The .upg-sync File
22
+
23
+ The `.upg-sync` file tracks the sync state between local and cloud. It lives next to the `.upg` file.
24
+
25
+ ```json
26
+ {
27
+ "cloud_endpoint": "https://cloud.unifiedproductgraph.org",
28
+ "product_id": "<cloud-uuid>",
29
+ "last_synced_at": "2026-03-24T15:00:00Z",
30
+ "node_id_map": {
31
+ "n_local1": "cloud-uuid-1",
32
+ "n_local2": "cloud-uuid-2"
33
+ },
34
+ "edge_id_map": {
35
+ "e_local1": "cloud-uuid-1",
36
+ "e_local2": "cloud-uuid-2"
37
+ },
38
+ "last_snapshot_hash": "sha256-of-cloud-graph-at-last-sync"
39
+ }
40
+ ```
41
+
42
+ - `node_id_map`: maps local `n_xxx` IDs to cloud UUIDs
43
+ - `edge_id_map`: maps local `e_xxx` IDs to cloud UUIDs
44
+ - `last_snapshot_hash`: SHA-256 hash of the cloud graph data at the time of last sync (used to detect cloud changes)
45
+
46
+
47
+ **Detailed pull flow, merge logic, and incremental sync are in `SKILL-DETAIL.md`.** Read it when executing the pull.
48
+
49
+ ## Key Principles
50
+
51
+ - **Cloud to local, not cloud to local lock-in.** The `.upg` file is the user's — portable, open, git-tracked.
52
+ - **Preserve fidelity.** Every entity, every edge, every property should survive the round-trip.
53
+ - **Incremental by default.** If a sync file exists, merge changes instead of overwriting.
54
+ - **Handle conflicts transparently.** v1 uses last-write-wins (cloud takes precedence), but always tell the user when it happens.
55
+ - **Suggest git.** Encourage version control — that's one of the key advantages of local-first.
56
+ - **The `.upg` file auto-reloads.** The upg-local MCP server watches the file — no restart needed.
57
+ - **The `.upg-sync` file is infrastructure.** It should be gitignored (it contains cloud-specific state). Suggest adding it to `.gitignore` if not already there.