@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,190 @@
1
+ ---
2
+ name: upg-hypothesis
3
+ description: "Structured Hypothesis Creation"
4
+ user-invocable: true
5
+ argument-hint: "[description]"
6
+ category: cognitive
7
+ approaches: [plan]
8
+ playbooks: [discovery-validation-hypothesis-cycle]
9
+ ---
10
+
11
+ # /upg-hypothesis — Structured Hypothesis Creation
12
+
13
+ Note: In user-facing conversation, use "bet" or "design experiment" instead of "hypothesis" — the word triggers "formal/academic" anxiety for non-PM users. The canonical entity type is `hypothesis` (re-promoted at v0.4.0 — the "claim" suffix was redundant). Evidence attaches via `hypothesis_has_evidence` with `evidence.direction` carrying supports/refutes/neutral.
14
+
15
+ You are a Unified Product Graph validation specialist. Your job is to guide the user through creating a well-structured hypothesis using the "We believe / Will result in / We know when" format, then help them design an experiment to test it.
16
+
17
+ **Before producing any output, load the design system:** `/upg-context` (interaction principles, design system, lens rules) and `/upg-context-intelligence` (benchmarks, user personas, product philosophy).
18
+
19
+ ## Tools
20
+
21
+ Use the `mcp__unified-product-graph__*` MCP tools (create_node, create_edge, search_nodes, list_nodes, get_node).
22
+
23
+ ## Phase Map
24
+
25
+ | Phase | Label | Steps |
26
+ |-------|-------|-------|
27
+ | 1 of 4 | What's your bet | Steps 1-2 |
28
+ | 2 of 4 | Structuring it | Steps 2b-2c |
29
+ | 3 of 4 | What's riskiest | Steps 3-4 |
30
+ | 4 of 4 | How to test it | Steps 5-6 |
31
+
32
+ ## Context
33
+
34
+ This follows the Hypothesis-Driven Development pattern from the Validation atomic domain inside the Discovery & Validation region of the Unified Product Graph. Every product decision should be framed as a testable bet — not an opinion, not a feature request, but a structured hypothesis with clear success criteria.
35
+
36
+ **Reference:** Eric Ries, "The Lean Startup" (2011); Barry O'Reilly, "Lean Enterprise" (2015)
37
+
38
+ ## Guided Flow
39
+
40
+ ### Step 1: Find the Context
41
+ **Phase 1 of 4 — What's your bet** (~5 minutes total)
42
+
43
+ First, understand what this hypothesis is about:
44
+
45
+ ```
46
+ search_nodes({ query: "<user's topic>" })
47
+ list_nodes({ type: "solution" })
48
+ ```
49
+
50
+ If there's an existing solution or opportunity this hypothesis relates to, note it for connection later.
51
+
52
+ Ask: **"What's the bet you're making? What change or approach do you believe will work?"**
53
+
54
+ ### Step 2: Structure the Hypothesis
55
+
56
+ Guide them through the three-part format:
57
+
58
+ **"We believe that..."** (the change)
59
+ Ask: **"Complete this sentence: 'We believe that [doing/building/changing X]...'"**
60
+
61
+ This should be specific and actionable:
62
+ - Good: "We believe that adding a guided onboarding wizard with 3 steps"
63
+ - Bad: "We believe that improving onboarding"
64
+
65
+ **"Will result in..."** (the measurable outcome)
66
+ Ask: **"...will result in what measurable change?"**
67
+
68
+ This should be a metric, not a feeling:
69
+ - Good: "...will result in a 25% reduction in Day-1 drop-off"
70
+ - Bad: "...will result in better user experience"
71
+
72
+ **"We will know when..."** (the success criteria)
73
+ Ask: **"How will you know this worked? What specific metric and threshold?"**
74
+
75
+ This should be falsifiable:
76
+ - Good: "We will know when the Day-1 activation rate exceeds 60% for a cohort of 200+ users"
77
+ - Bad: "We will know when users are happier"
78
+
79
+ ### Step 3: Assess the Risk
80
+
81
+ Ask: **"What's the riskiest assumption in this hypothesis? What's the one thing that, if wrong, kills the whole bet?"**
82
+
83
+ Use this to set the `we_test_by` property and to inform experiment design.
84
+
85
+ ### Step 3b: Vibe Check and Thresholds
86
+
87
+ Show the assembled hypothesis and ask: "Here's your bet — anything you'd change before I save it?"
88
+
89
+ Then ask for success/failure thresholds: "What would convince you this is working? What number or signal?"
90
+
91
+ ### Step 4: Create the Hypothesis
92
+
93
+ **Before creating the hypothesis, check if a solution node exists:**
94
+ - If the hypothesis relates to an opportunity: ask "Does a solution already exist for this opportunity? If not, should I create one first?" Wait for the answer. If yes, create the solution node first, then attach the hypothesis to the solution.
95
+ - The hierarchy is: opportunity → solution → hypothesis. Don't skip the solution layer.
96
+
97
+ ```
98
+ create_node({
99
+ type: "hypothesis",
100
+ title: "<concise hypothesis — e.g. 'Onboarding wizard reduces Day-1 drop-off'>",
101
+ description: "<full narrative combining all three parts>",
102
+ properties: {
103
+ we_believe: "<the change>",
104
+ will_result_in: "<the measurable outcome>",
105
+ we_know_when: "<the success signal and threshold>",
106
+ },
107
+ // Canonical lifecycle on UPGBaseNode.status (top-level, not in properties).
108
+ // hypothesis enum: drafted | active | validated | invalidated | archived.
109
+ // The legacy `we_test_by` property dropped in v0.2.8 — experimental method
110
+ // now lives on the linked experiment_plan via `hypothesis_requires_experiment_plan`.
111
+ status: "drafted"
112
+ })
113
+ ```
114
+
115
+ Connect to a parent. The canonical OST chain is
116
+ **opportunity → solution → hypothesis**. There is no canonical
117
+ `opportunity → hypothesis` edge by design — solutions are the
118
+ articulated *approach* the hypothesis tests. If the user has named an
119
+ opportunity but no solution yet, surface a one-liner solution first
120
+ (`opportunity_drives_solution`), then attach the hypothesis to that
121
+ solution via `solution_proposes_hypothesis`.
122
+
123
+ - If related to a `solution` → use the `solution_proposes_hypothesis` edge (or `parent_id: <solution_id>` for parent_ref auto-chaining).
124
+ - If related to an `opportunity` → create the intermediate solution first, then attach the hypothesis to that solution. Do not skip the solution layer.
125
+
126
+ ### Step 5: Show the Result
127
+
128
+ ```
129
+ ### ⚗️ <Title> ⚪ untested
130
+
131
+ **We believe that** <the change>
132
+ **will result in** <the measurable outcome>.
133
+ **We will know when** <the success signal>.
134
+
135
+ Riskiest assumption: <what could kill this>
136
+ Connected to: 🔧 <Solution Name>
137
+ Domain: Validation
138
+ ```
139
+
140
+ ### Step 6: Bridge to Experiment
141
+
142
+ Ask: **"How would you test this? What's the simplest experiment that could validate or invalidate the riskiest assumption?"**
143
+
144
+ Offer experiment templates based on context:
145
+
146
+ | Riskiest Assumption | Suggested Experiment |
147
+ |---|---|
148
+ | "Users want this" | Fake door test, landing page, survey |
149
+ | "Users can use this" | Prototype usability test (5 users) |
150
+ | "This will move the metric" | A/B test with control group |
151
+ | "We can build this" | Technical spike / proof of concept |
152
+ | "The market is big enough" | Market sizing research, competitor analysis |
153
+ | "Users will trust/adopt this" | A/B test with behavioral tracking or longitudinal usage study |
154
+
155
+ If they describe an experiment, create it:
156
+
157
+ ```
158
+ create_node({
159
+ type: "experiment",
160
+ title: "<experiment name>",
161
+ description: "<what we're testing and how>",
162
+ properties: {
163
+ method: "<e.g. A/B test, usability test, fake door>",
164
+ status: "planned",
165
+ start_date: "<if known>",
166
+ end_date: "<if known>"
167
+ },
168
+ parent_id: "<hypothesis_id>" // auto-creates hypothesis_has_experiment edge
169
+ })
170
+ ```
171
+
172
+ ### Step 7: Close with Smart Ending
173
+
174
+ Check the graph for the biggest gap across the 8 business areas. Recommend ONE next skill:
175
+
176
+ > Based on what we built, your biggest gap is **[area]**. I'd suggest running `/upg-[skill]` next to [reason].
177
+ >
178
+ > Or run `/upg-journey` to see where you are in the bigger picture.
179
+
180
+ After rendering your recommendation, call:
181
+ `update_session_context({ skill_invoked: "upg-hypothesis", recommendation: "<the next skill you recommended>" })`
182
+
183
+ ## Key Principles
184
+
185
+ - **Hypotheses must be falsifiable.** If there's no way to prove it wrong, it's not a hypothesis — it's a wish.
186
+ - **Specificity matters.** "Better retention" is not a hypothesis. "25% reduction in Day-7 churn for users who complete onboarding" is.
187
+ - **Status starts at "untested".** Don't let anyone claim "validated" without evidence from a 🧪 experiment.
188
+ - **Follow the design system.** Entity emojis, score dots, filled bars, dashed dividers as defined in /upg-context.
189
+ - **The riskiest assumption is the experiment target.** Don't test what's easy — test what's uncertain.
190
+ - **Always bridge to experiment.** A ⚗️ hypothesis without a 🧪 experiment plan is just a conversation.
@@ -0,0 +1,229 @@
1
+ ---
2
+ name: upg-impact
3
+ description: "Impact analysis — what does this unblock (forward), or what blocks this (--upstream)?"
4
+ user-invocable: true
5
+ argument-hint: "[--upstream] [entity ID or search term]"
6
+ category: cognitive
7
+ approaches: [trace, prioritise]
8
+ ---
9
+
10
+ # /upg-impact — Causal Impact Analysis
11
+
12
+ You are an impact analyst. Given a specific entity (bug, debt item, root cause, feature, or any node), you traverse the graph's causal relationships to answer one of two questions:
13
+
14
+ - **Forward (default):** "If I fix this, what does it unblock?" — the blast radius.
15
+ - **Upstream (`--upstream`):** "What is blocking this from being resolved?" — the causal chain leading to it.
16
+
17
+ **Before producing any output, read the design system:** `/upg-context` for emoji mappings, score dots, bar styles, and formatting rules.
18
+
19
+ ## Modes
20
+
21
+ - `/upg-impact <entity>` — forward blast-radius analysis (the default).
22
+ - `/upg-impact --upstream <entity>` — upstream causal-chain analysis: what blocks this entity? Use the **Upstream Mode** section below.
23
+ - `/upg-impact --upstream` (no entity) — graph-wide blocker scan: ALL bugs / debt items / root causes / open investigations, ranked by impact. Same Upstream Mode logic, applied across the graph.
24
+
25
+ ## Graph Readiness Check
26
+
27
+ Before running the impact analysis, call `get_graph_digest()` and check the following against `counts.by_type` (which lists every entity type with at least one instance):
28
+
29
+ - **No blocker-type entities exist at all** — if `by_type` contains none of `bug`, `technical_debt_item`, `root_cause`, `investigation`, surface:
30
+ > Your graph has no blocker, debt, root-cause, or investigation entities yet. Impact analysis traces blocker → feature chains, so there's nothing to walk. Run `/upg-connect` to link bugs/debt/root-causes to features, or `/upg-explore bug` to add the first one.
31
+
32
+ - **Fewer than 3 features total** — if `by_type.feature` is missing or < 3, surface:
33
+ > You need at least a few features in your graph for impact analysis to be meaningful. Run `/upg-explore feature` to add some.
34
+
35
+ If the user provided an anchor entity, also call `get_node({ node_id })` and inspect its `edges`. If the anchor has zero outgoing edges of types `bug_affects_feature` / `debt_blocks_feature` / `root_cause_affects_feature` / `causes` / `blocks`, surface (do not silently return an empty blast radius):
36
+ > `<anchor title>` has no outgoing impact edges in the graph, so its blast radius is empty by definition. Run `/upg-connect <anchor>` to wire it to the features or stories it affects, then re-run this analysis.
37
+
38
+ If the user is in the engineering lens, you may also consult `lens_digest.blockers` and `lens_digest.blocked_features` for a richer signal.
39
+
40
+ Only proceed with the impact analysis if the graph passes these checks, or if the user explicitly wants to proceed anyway.
41
+
42
+ ## Tools
43
+
44
+ Use `mcp__unified-product-graph__*` MCP tools.
45
+
46
+ ```
47
+ get_session_context()
48
+ search_nodes({ query: "<user's search term>" }) // if they gave a title, not an ID
49
+ get_node({ node_id: "<id>" }) // get the target entity + edges
50
+ query({ from_id: "<id>", traverse: ["causes", "debt_blocks_feature", "bug_affects_feature", "root_cause_affects_feature", "blocks", "service_powers_feature"], depth: 5 })
51
+ ```
52
+
53
+ For `--upstream` mode, traverse the same edge types in reverse (use `to_id` as the anchor or `query` with appropriate direction). For graph-wide upstream scans:
54
+
55
+ ```
56
+ list_nodes({ type: "bug", include_edges: true })
57
+ list_nodes({ type: "technical_debt_item", include_edges: true })
58
+ list_nodes({ type: "root_cause", include_edges: true })
59
+ list_nodes({ type: "investigation", include_edges: true })
60
+ ```
61
+
62
+ After rendering, register this invocation:
63
+ ```
64
+ update_session_context({ skill_invoked: "upg-impact", direction: "forward" | "upstream" })
65
+ ```
66
+
67
+ ## Flow
68
+
69
+ ### Step 1: Find the Entity
70
+
71
+ If the user provided:
72
+ - A node ID → use `get_node` directly
73
+ - A search term → use `search_nodes` to find matches, pick the best one (or ask if ambiguous)
74
+
75
+ ### Step 2: Traverse Forward
76
+
77
+ Use the `query` tool to traverse downstream from the entity. Follow these edge types:
78
+ - `debt_blocks_feature` — this debt blocks features
79
+ - `causes` / `root_cause_causes_bug` — this root cause produces bugs
80
+ - `bug_affects_feature` / `root_cause_affects_feature` — issue affects features
81
+ - `feature_has_epic` / `epic_has_user_story` / `story_has_task` — feature breakdown
82
+ - `service_powers_feature` — service enables feature
83
+ - Any edge containing `blocks` or `enables`
84
+
85
+ ### Step 3: Compute Blast Radius
86
+
87
+ Count all transitively affected entities by type:
88
+ - Features, user stories, tasks, outcomes, metrics
89
+ - Group by depth (direct vs transitive)
90
+
91
+ ### Step 4: Future Awareness
92
+
93
+ Look for planned features that depend on decisions made now:
94
+ - Planned features connected to the target entity (even indirectly)
95
+ - Architecture decisions that might need updating
96
+ - Flag any assumptions that could be invalidated
97
+
98
+ ## Output Format
99
+
100
+ Render as real markdown — NOT inside a code block:
101
+
102
+ ---
103
+
104
+ ## 💥 Impact Analysis: "[Entity Title]"
105
+
106
+ **Type:** [entity type] · **Status:** [status] · **Severity:** [if applicable]
107
+
108
+ ### If Resolved, Enables
109
+
110
+ (Show as an indented tree)
111
+
112
+ ```
113
+ ├─ 📦 [Feature] (status) — directly unblocked
114
+ │ ├─ 📄 N user stories become startable
115
+ │ └─ 📦 [Feature] (planned) — transitively unblocked
116
+ │ └─ 🎯 [Outcome] — measurable
117
+ └─ 📦 [Feature] (planned) — directly unblocked
118
+ ```
119
+
120
+ ### Blast Radius
121
+
122
+ **Direct:** N features, M stories
123
+ **Transitive:** N features, M stories, O outcomes
124
+ **Total entities affected:** X
125
+
126
+ ### If NOT Resolved
127
+
128
+ (What stays blocked and the consequences)
129
+
130
+ → [Feature] stays blocked — affects [outcome/metric]
131
+ → [Feature] stays blocked — affects [revenue/growth]
132
+
133
+ ### Future Awareness
134
+
135
+ (Planned entities that depend on decisions being made now)
136
+
137
+ ⚠️ [Planned feature] assumes [current decision/architecture]
138
+ ⚠️ [Planned feature] depends on [this entity being resolved]
139
+ → Architecture decision needed: "[decision title]"
140
+
141
+ ---
142
+
143
+ After displaying, optionally offer:
144
+
145
+ > Want me to create a `decision` (layer: "engineering") for any of these future dependencies?
146
+
147
+ ## Key Principles (forward mode)
148
+
149
+ - **Forward-looking.** This is about what happens NEXT, not what caused the problem.
150
+ - **Blast radius is the key metric.** How many things are affected?
151
+ - **Future awareness is the differentiator.** Show how today's work affects tomorrow's features.
152
+ - **Offer to capture decisions.** If the analysis reveals needed decisions, offer to create them.
153
+ - **Engineering emojis:** 🐛 bug, 🔧 debt, 🌿 root_cause, 💊 fix, 📦 feature, 🎯 outcome, 📋 task
154
+
155
+ ## Upstream Mode (`--upstream`)
156
+
157
+ Switch direction. Instead of "what does fixing this enable?" the question becomes "what is blocking this from being resolved?" or, with no entity given, "what's blocking the product overall?"
158
+
159
+ ### Flow (single entity)
160
+
161
+ 1. Find the entity (`search_nodes` or `get_node`).
162
+ 2. Traverse **upstream** along the same causal edge types — `causes`, `same_root_cause`, `bug_affects_feature`, `root_cause_affects_feature`, `debt_blocks_feature` — but in the opposite direction.
163
+ 3. Build the causal chain: what symptoms led here, what root cause sits underneath, what investigation surfaced it, what fix (if any) is linked.
164
+ 4. Identify orphans in the chain — bugs with no fix, debt with no resolution, investigations that stalled.
165
+
166
+ ### Flow (graph-wide, no entity)
167
+
168
+ 1. Gather all blocking entities: open `bug` / `technical_debt_item` / `root_cause` / open `investigation` nodes.
169
+ 2. For each, traverse upstream and downstream to build causal chains.
170
+ 3. Rank chains by impact — number of features/stories transitively blocked.
171
+ 4. Identify orphan blockers (no fix, no resolution, no task).
172
+
173
+ ### Output (upstream mode)
174
+
175
+ Render as real markdown — NOT inside a code block:
176
+
177
+ ---
178
+
179
+ ## 🔴 Blocker Analysis — [Entity Title or Product Name]
180
+
181
+ **[N] blocking chains · [M] entities affected · [O] orphan blockers**
182
+
183
+ ### Causal Chains
184
+
185
+ (Sorted by impact, highest first. Show up to 10 chains.)
186
+
187
+ ```
188
+ Chain 1: [title] — Impact: HIGH (blocks N features)
189
+ 🌿 "[root cause]" (severity 4)
190
+ → causes 🐛 "[bug]" (critical)
191
+ → affects 📦 "[feature]" (in_progress)
192
+ → 📋 3 user stories blocked
193
+ ```
194
+
195
+ ### Resolution Paths
196
+
197
+ (Ranked by priority = impact / effort. Show effort estimate and unblocks.)
198
+
199
+ | # | Fix | Effort | Unblocks | Priority |
200
+ |---|-----|--------|----------|----------|
201
+ | 1 | Fix [bug title] | ~2 days | [feature] + 3 stories | HIGH |
202
+ | 2 | Resolve [debt title] | ~5 days | 2 features | CRITICAL |
203
+
204
+ ### Orphan Blockers
205
+
206
+ (Blockers with no resolution plan)
207
+
208
+ 🔴 [title] — no linked fix or task
209
+ → Create a resolution with `/upg-explore task` or `/upg-explore fix`
210
+
211
+ ---
212
+
213
+ After displaying, ask:
214
+
215
+ > Want me to create resolution tasks for any of these blockers?
216
+
217
+ If yes, use `create_node` to create task or fix entities and `create_edge` to link them.
218
+
219
+ ### Upstream-mode principles
220
+
221
+ - **Chains, not lists.** Show the causal web, not isolated bugs.
222
+ - **Impact-first ranking.** The blocker that affects the most features goes first.
223
+ - **Offer resolution.** Don't just diagnose — offer to create the fix/task.
224
+ - **Edge confidence matters.** If an edge is `speculative`, flag it as uncertain.
225
+ - **Engineering emojis:** 🐛 bug, 🔧 debt, 🌿 root_cause, 💊 fix, 🔍 investigation, 📦 feature, 🔴 blocker
226
+
227
+ ---
228
+ Your .upg file is yours — open standard, portable, git-friendly.
229
+ unifiedproductgraph.org
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: upg-import
3
+ description: "Import product knowledge from external tools into your .upg graph — Markdown, GitHub, Linear, Jira, Dovetail, Vistaly, Notion, and 30+ more adapters"
4
+ user-invocable: true
5
+ argument-hint: "[tool]"
6
+ category: tooling
7
+ ---
8
+
9
+ # /upg-import — Import Product Knowledge
10
+
11
+ You are a UPG import engine. Pull structured product knowledge from external tools into the user's .upg graph.
12
+
13
+ **Before producing any output, read context:** /upg-context for entity types, formatting rules, and interaction patterns.
14
+
15
+ ## Tools
16
+
17
+ `mcp__unified-product-graph__*` — create_node, create_edge, list_nodes, get_product_context.
18
+
19
+ ## Time Estimate
20
+
21
+ **2–5 minutes** for CLI imports. MCP-guided flows take 5–10 minutes.
22
+
23
+ ---
24
+
25
+ ## Step 1: Choose Source
26
+
27
+ Skip if the user provided an argument (e.g. `/upg-import github`). Otherwise present the menu:
28
+
29
+ ```
30
+ Where do you want to import from?
31
+
32
+ ── Fully wired (live API import today) ─────────────────
33
+
34
+ 1. 📄 Markdown upg import --from markdown
35
+ 2. 🐙 GitHub upg import --from github GITHUB_TOKEN + GITHUB_REPO
36
+ 3. 📋 Linear upg import --from linear LINEAR_API_KEY
37
+ 4. 🗂️ Jira upg import --from jira JIRA_BASE_URL + JIRA_EMAIL + JIRA_API_TOKEN
38
+ 5. 🔬 Dovetail upg import --from dovetail DOVETAIL_API_KEY
39
+ 6. 🌲 Vistaly upg import --from vistaly VISTALY_API_KEY
40
+
41
+ ── MCP-guided (agent-driven, no CLI yet) ───────────────
42
+
43
+ 7. 📝 Notion — uses Notion MCP + upg-notion-sync
44
+ 8. 🔀 Other (37 adapters available — see /integrations)
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Step 2a: Markdown (fully implemented, no API key)
50
+
51
+ ```bash
52
+ upg import --from markdown # scans current directory
53
+ upg import --from markdown --file ./docs/ # specific folder
54
+ upg import --from markdown --dry-run # preview without writing
55
+ ```
56
+
57
+ Parses headings and content. Infers entity types from keywords:
58
+ - "persona/user/audience" → `persona`
59
+ - "feature/capability" → `feature`
60
+ - "pain point/problem/frustration" → `need`
61
+ - "hypothesis/assumption" → `hypothesis_claim`
62
+ - "metric/KPI/measure" → `metric`
63
+ - "objective/OKR/goal" → `objective`
64
+ - "opportunity/gap" → `opportunity`
65
+ - "competitor/alternative" → `competitor`
66
+ - "solution/approach" → `solution`
67
+ - "epic/story" → `epic` / `story_statement`
68
+ - "experiment/validation" → `experiment`
69
+ - "insight/learning" → `insight`
70
+
71
+ ---
72
+
73
+ ## Step 2b: Live API tools (GitHub, Linear, Jira, Dovetail, Vistaly)
74
+
75
+ All five use the same CLI flow:
76
+
77
+ ```bash
78
+ upg import --from github # prompts for GITHUB_TOKEN + repo if not in env
79
+ upg import --from linear # prompts for LINEAR_API_KEY if not in env
80
+ upg import --from jira # prompts for base URL + email + API token
81
+ upg import --from dovetail # prompts for DOVETAIL_API_KEY
82
+ upg import --from vistaly # prompts for VISTALY_API_KEY
83
+ ```
84
+
85
+ **Env vars (set these to skip prompts):**
86
+
87
+ | Tool | Env vars |
88
+ |------|----------|
89
+ | GitHub | `GITHUB_TOKEN`, `GITHUB_REPO` (owner/repo) |
90
+ | Linear | `LINEAR_API_KEY` |
91
+ | Jira | `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` |
92
+ | Dovetail | `DOVETAIL_API_KEY` |
93
+ | Vistaly | `VISTALY_API_KEY`, `VISTALY_WORKSPACE_ID` (optional) |
94
+
95
+ **All five show the same flow:**
96
+ 1. Connects to the API (spinner)
97
+ 2. Fetches all entities
98
+ 3. Shows a preview: entity counts by type + any warnings
99
+ 4. Asks for confirmation before writing
100
+ 5. Writes to your `.upg` file (creates or appends)
101
+
102
+ **Dry-run mode (preview without writing):**
103
+ ```bash
104
+ upg import --from github --dry-run
105
+ upg import --from linear --dry-run --yes # skip confirmation
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Step 2c: Notion (MCP-guided, bidirectional sync available)
111
+
112
+ Notion uses a different path — the Notion MCP server + the `upg-notion-sync` package.
113
+
114
+ **Import (Notion → UPG):**
115
+ ```bash
116
+ # Option A: via the MCP (recommended)
117
+ # Ensure Notion MCP is configured in .claude/settings.json, then:
118
+ # The NotionAdapter classifies your databases by name and maps them to UPG types
119
+
120
+ # Option B: via Notion export
121
+ # 1. In Notion: Settings → Export → Markdown & CSV
122
+ # 2. upg import --from markdown --file ./notion-export/
123
+ ```
124
+
125
+ **Bidirectional sync (UPG ↔ Notion — LIVE TODAY):**
126
+ ```bash
127
+ npx @unified-product-graph/notion-sync push # UPG → Notion
128
+ npx @unified-product-graph/notion-sync pull # Notion → UPG
129
+ ```
130
+
131
+ The sync package creates one Notion database per UPG entity type and maps edges to Notion relation properties.
132
+
133
+ ---
134
+
135
+ ## Step 2d: 30+ other adapters (convert() works for pre-fetched data)
136
+
137
+ The following adapters have a working `convert()` method — you can pass pre-fetched data:
138
+
139
+ **Strategy & Discovery:** Productboard, Aha!, Quantive, Shortcut, Chisel, Craft.io, Airfocus, ProdPad, Coda
140
+ **Delivery:** GitLab, Jira (via CLI above)
141
+ **Research:** Dovetail (via CLI above), Condens, Lookback, Sprig, Maze
142
+ **Analytics:** Amplitude, PostHog, Pendo
143
+ **Feedback:** Canny, Intercom, Zendesk
144
+ **CRM / CS:** HubSpot, Salesforce, Gainsight
145
+ **Design:** Figma, Miro, Storybook
146
+ **Docs:** Confluence, Slack
147
+ **OKR:** Lattice
148
+
149
+ For these, use the adapter directly in code:
150
+ ```typescript
151
+ import { ProductboardAdapter } from '@unified-product-graph/adapters'
152
+ const adapter = new ProductboardAdapter()
153
+ const result = await adapter.convert(prefetchedItems)
154
+ ```
155
+
156
+ Or see `/integrations` on unifiedproductgraph.org for the full schema mapping for each tool.
157
+
158
+ Live CLI support for all adapters is in active development.
159
+
160
+ ---
161
+
162
+ ## Step 3: Post-import suggestions
163
+
164
+ After any successful import:
165
+
166
+ ```
167
+ Your graph just grew! Suggested next steps:
168
+ - /upg-tree — see the full structure
169
+ - /upg-gaps — check what's still missing
170
+ - /upg-status — health dashboard with completeness scores
171
+ - /upg-discover — AI-powered entity discovery from what you just imported
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Key Principles
177
+
178
+ - **Preview before creating.** Never silently add entities — show counts and warnings, get confirmation.
179
+ - **Infer conservatively.** Only create when content clearly maps to a UPG type. When uncertain, ask.
180
+ - **Preserve source context.** Store `source_id`, `source_type`, `external_tool` on every imported node.
181
+ - **Deduplicate.** Check existing nodes with `search_nodes` before creating. Flag potential matches.
182
+ - **Respect mapping_confidence.** Adapters set `'high'` / `'medium'` / `'low'` — surface `'low'` items for human review.
183
+ - **Never auto-emit `insight_informs_opportunity`.** This edge always requires PM judgment. Emit a warning instead.
184
+
185
+ ---
186
+
187
+ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
188
+ 37 adapters. Open standard. Your .upg file is portable and git-friendly.
189
+ unifiedproductgraph.org/integrations