@flydocs/cli 0.6.0-alpha.3 → 0.6.0-alpha.31

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 (151) hide show
  1. package/dist/cli.js +2053 -469
  2. package/package.json +1 -1
  3. package/template/.claude/CLAUDE.md +43 -48
  4. package/template/.claude/agents/implementation-agent.md +1 -1
  5. package/template/.claude/agents/pm-agent.md +1 -1
  6. package/template/.claude/commands/activate.md +1 -1
  7. package/template/.claude/commands/attach.md +1 -1
  8. package/template/.claude/commands/block.md +2 -2
  9. package/template/.claude/commands/capture.md +1 -1
  10. package/template/.claude/commands/close.md +1 -1
  11. package/template/.claude/commands/flydocs-setup.md +359 -72
  12. package/template/.claude/commands/flydocs-upgrade.md +26 -27
  13. package/template/.claude/commands/implement.md +1 -1
  14. package/template/.claude/commands/knowledge.md +61 -0
  15. package/template/.claude/commands/new-project.md +1 -1
  16. package/template/.claude/commands/onboard.md +275 -0
  17. package/template/.claude/commands/project-update.md +1 -1
  18. package/template/.claude/commands/refine.md +1 -1
  19. package/template/.claude/commands/review.md +1 -1
  20. package/template/.claude/commands/start-session.md +1 -1
  21. package/template/.claude/commands/status.md +1 -1
  22. package/template/.claude/commands/validate.md +1 -1
  23. package/template/.claude/commands/wrap-session.md +1 -1
  24. package/template/.claude/hooks/auto-approve.py +212 -0
  25. package/template/.claude/hooks/post-pr-check.py +108 -0
  26. package/template/.claude/hooks/post-transition-check.py +281 -0
  27. package/template/.claude/hooks/prompt-submit.py +554 -0
  28. package/template/.claude/hooks/session-start.py +262 -0
  29. package/template/.claude/hooks/stop-gate.py +162 -0
  30. package/template/.claude/settings.json +41 -4
  31. package/template/.claude/skills/README.md +23 -25
  32. package/template/.claude/skills/flydocs-workflow/SKILL.md +134 -42
  33. package/template/.claude/skills/flydocs-workflow/cursor-rule.mdc +9 -8
  34. package/template/.claude/skills/flydocs-workflow/reference/comment-templates.md +1 -0
  35. package/template/.claude/skills/flydocs-workflow/reference/golden-rules.md +28 -17
  36. package/template/.claude/skills/flydocs-workflow/reference/graph-schema.md +116 -0
  37. package/template/.claude/skills/flydocs-workflow/reference/pr-workflow.md +120 -0
  38. package/template/.claude/skills/flydocs-workflow/reference/priority-estimates.md +37 -15
  39. package/template/.claude/skills/flydocs-workflow/reference/service-descriptor-schema.md +260 -0
  40. package/template/.claude/skills/flydocs-workflow/reference/status-workflow.md +26 -26
  41. package/template/.claude/skills/flydocs-workflow/scripts/_local/__init__.py +0 -0
  42. package/template/.claude/skills/{flydocs-local/scripts/flydocs_api.py → flydocs-workflow/scripts/_local/file_store.py} +137 -47
  43. package/template/.claude/skills/flydocs-workflow/scripts/flydocs_api.py +724 -0
  44. package/template/{.flydocs → .claude/skills/flydocs-workflow}/scripts/generate_manifest.py +4 -4
  45. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_build.py +132 -1
  46. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_query.py +18 -5
  47. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_session.py +1 -10
  48. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_update.py +4 -4
  49. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_utils.py +2 -1
  50. package/template/.claude/skills/flydocs-workflow/scripts/issues.py +738 -0
  51. package/template/.claude/skills/flydocs-workflow/scripts/projects.py +144 -0
  52. package/template/.claude/skills/flydocs-workflow/scripts/pull_services.py +128 -0
  53. package/template/.claude/skills/flydocs-workflow/scripts/push_service.py +132 -0
  54. package/template/.claude/skills/flydocs-workflow/scripts/session.py +54 -0
  55. package/template/.claude/skills/flydocs-workflow/scripts/test_enforcement.py +225 -0
  56. package/template/.claude/skills/flydocs-workflow/scripts/workspace.py +902 -0
  57. package/template/.claude/skills/flydocs-workflow/session.md +87 -29
  58. package/template/.claude/skills/flydocs-workflow/stages/activate.md +18 -7
  59. package/template/.claude/skills/flydocs-workflow/stages/capture.md +10 -5
  60. package/template/.claude/skills/flydocs-workflow/stages/close.md +4 -3
  61. package/template/.claude/skills/flydocs-workflow/stages/implement.md +33 -9
  62. package/template/.claude/skills/flydocs-workflow/stages/refine.md +22 -6
  63. package/template/.claude/skills/flydocs-workflow/stages/review.md +16 -4
  64. package/template/.claude/skills/flydocs-workflow/stages/validate.md +3 -1
  65. package/template/.claude/skills/flydocs-workflow/templates/pr/default.md +33 -0
  66. package/template/.cursor/agents/implementation-agent.md +1 -1
  67. package/template/.cursor/agents/pm-agent.md +2 -2
  68. package/template/.cursor/hooks.json +10 -3
  69. package/template/.env.example +6 -6
  70. package/template/.flydocs/config.json +5 -18
  71. package/template/.flydocs/templates/README.md +13 -14
  72. package/template/.flydocs/templates/bug.md +17 -153
  73. package/template/.flydocs/templates/chore.md +10 -98
  74. package/template/.flydocs/templates/feature.md +12 -158
  75. package/template/.flydocs/templates/idea.md +11 -111
  76. package/template/.flydocs/templates/quick-capture.md +4 -8
  77. package/template/.flydocs/version +1 -1
  78. package/template/AGENTS.md +44 -32
  79. package/template/CHANGELOG.md +37 -0
  80. package/template/flydocs/README.md +1 -3
  81. package/template/flydocs/context/project.md +6 -3
  82. package/template/flydocs/design-system/README.md +3 -3
  83. package/template/flydocs/knowledge/INDEX.md +38 -53
  84. package/template/flydocs/knowledge/README.md +60 -9
  85. package/template/flydocs/knowledge/templates/decision.md +47 -0
  86. package/template/flydocs/knowledge/templates/feature.md +35 -0
  87. package/template/flydocs/knowledge/templates/note.md +25 -0
  88. package/template/manifest.json +24 -20
  89. package/template/.claude/skills/flydocs-cloud/SKILL.md +0 -113
  90. package/template/.claude/skills/flydocs-cloud/cursor-rule.mdc +0 -50
  91. package/template/.claude/skills/flydocs-cloud/scripts/assign.py +0 -22
  92. package/template/.claude/skills/flydocs-cloud/scripts/assign_cycle.py +0 -28
  93. package/template/.claude/skills/flydocs-cloud/scripts/assign_milestone.py +0 -22
  94. package/template/.claude/skills/flydocs-cloud/scripts/comment.py +0 -29
  95. package/template/.claude/skills/flydocs-cloud/scripts/create_issue.py +0 -66
  96. package/template/.claude/skills/flydocs-cloud/scripts/create_milestone.py +0 -35
  97. package/template/.claude/skills/flydocs-cloud/scripts/create_project.py +0 -33
  98. package/template/.claude/skills/flydocs-cloud/scripts/create_team.py +0 -39
  99. package/template/.claude/skills/flydocs-cloud/scripts/estimate.py +0 -29
  100. package/template/.claude/skills/flydocs-cloud/scripts/flydocs_api.py +0 -210
  101. package/template/.claude/skills/flydocs-cloud/scripts/get_issue.py +0 -24
  102. package/template/.claude/skills/flydocs-cloud/scripts/link.py +0 -28
  103. package/template/.claude/skills/flydocs-cloud/scripts/list_cycles.py +0 -28
  104. package/template/.claude/skills/flydocs-cloud/scripts/list_issues.py +0 -44
  105. package/template/.claude/skills/flydocs-cloud/scripts/list_labels.py +0 -19
  106. package/template/.claude/skills/flydocs-cloud/scripts/list_milestones.py +0 -28
  107. package/template/.claude/skills/flydocs-cloud/scripts/list_projects.py +0 -31
  108. package/template/.claude/skills/flydocs-cloud/scripts/list_providers.py +0 -19
  109. package/template/.claude/skills/flydocs-cloud/scripts/list_teams.py +0 -19
  110. package/template/.claude/skills/flydocs-cloud/scripts/priority.py +0 -29
  111. package/template/.claude/skills/flydocs-cloud/scripts/project_update.py +0 -45
  112. package/template/.claude/skills/flydocs-cloud/scripts/set_labels.py +0 -68
  113. package/template/.claude/skills/flydocs-cloud/scripts/set_provider.py +0 -46
  114. package/template/.claude/skills/flydocs-cloud/scripts/set_team.py +0 -41
  115. package/template/.claude/skills/flydocs-cloud/scripts/transition.py +0 -26
  116. package/template/.claude/skills/flydocs-cloud/scripts/update_description.py +0 -36
  117. package/template/.claude/skills/flydocs-cloud/scripts/update_issue.py +0 -82
  118. package/template/.claude/skills/flydocs-context-graph/SKILL.md +0 -87
  119. package/template/.claude/skills/flydocs-context-graph/schema.md +0 -78
  120. package/template/.claude/skills/flydocs-context-graph/scripts/graph_context.py +0 -338
  121. package/template/.claude/skills/flydocs-context7/SKILL.md +0 -105
  122. package/template/.claude/skills/flydocs-context7/cursor-rule.mdc +0 -49
  123. package/template/.claude/skills/flydocs-context7/scripts/context7.py +0 -293
  124. package/template/.claude/skills/flydocs-estimates/SKILL.md +0 -384
  125. package/template/.claude/skills/flydocs-figma/SKILL.md +0 -377
  126. package/template/.claude/skills/flydocs-figma/references/PROMPTING.md +0 -108
  127. package/template/.claude/skills/flydocs-figma/references/TROUBLESHOOTING.md +0 -112
  128. package/template/.claude/skills/flydocs-local/SKILL.md +0 -103
  129. package/template/.claude/skills/flydocs-local/cursor-rule.mdc +0 -43
  130. package/template/.claude/skills/flydocs-local/scripts/assign.py +0 -20
  131. package/template/.claude/skills/flydocs-local/scripts/comment.py +0 -27
  132. package/template/.claude/skills/flydocs-local/scripts/create_issue.py +0 -44
  133. package/template/.claude/skills/flydocs-local/scripts/estimate.py +0 -37
  134. package/template/.claude/skills/flydocs-local/scripts/get_issue.py +0 -20
  135. package/template/.claude/skills/flydocs-local/scripts/link.py +0 -41
  136. package/template/.claude/skills/flydocs-local/scripts/list_issues.py +0 -34
  137. package/template/.claude/skills/flydocs-local/scripts/priority.py +0 -37
  138. package/template/.claude/skills/flydocs-local/scripts/project_update.py +0 -67
  139. package/template/.claude/skills/flydocs-local/scripts/status_summary.py +0 -16
  140. package/template/.claude/skills/flydocs-local/scripts/transition.py +0 -24
  141. package/template/.claude/skills/flydocs-local/scripts/update_description.py +0 -35
  142. package/template/.claude/skills/flydocs-local/scripts/update_issue.py +0 -84
  143. package/template/.flydocs/hooks/auto-approve.py +0 -71
  144. package/template/.flydocs/hooks/prompt-submit.py +0 -277
  145. package/template/.flydocs/scripts/skill_manager.py +0 -541
  146. /package/template/{.flydocs → .claude}/hooks/post-edit.py +0 -0
  147. /package/template/.claude/skills/{flydocs-estimates/references → flydocs-workflow/reference}/provider-costs.md +0 -0
  148. /package/template/.claude/skills/flydocs-workflow/templates/{bug.md → issues/bug.md} +0 -0
  149. /package/template/.claude/skills/flydocs-workflow/templates/{chore.md → issues/chore.md} +0 -0
  150. /package/template/.claude/skills/flydocs-workflow/templates/{feature.md → issues/feature.md} +0 -0
  151. /package/template/.claude/skills/flydocs-workflow/templates/{idea.md → issues/idea.md} +0 -0
@@ -1,338 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Assemble compressed graph context for the prime hook.
3
-
4
- Given an active issue and/or git branch, traverses the graph and returns
5
- a compact context block suitable for injection into the prompt-submit hook.
6
- Stays within a ~200-400 token budget.
7
-
8
- Usage:
9
- python3 .claude/skills/flydocs-context-graph/scripts/graph_context.py \
10
- [--issue FLY-56] [--branch feature/context-graph] [--root PATH]
11
-
12
- Output: Plain text context block (not JSON) for direct injection into hook output.
13
- Returns empty string if graph doesn't exist or no relevant context found.
14
- """
15
-
16
- import argparse
17
- import sys
18
- from datetime import date, timedelta
19
- from pathlib import Path
20
-
21
- sys.path.insert(0, str(Path(__file__).parent))
22
- from graph_utils import find_project_root, load_graph
23
-
24
-
25
- # Maximum lines in the context block to stay within token budget
26
- MAX_CONTEXT_LINES = 12
27
-
28
- # Session staleness policy
29
- SESSION_RETENTION_DAYS = 30
30
- SESSION_FRESH_DAYS = 7 # Full weight within this window
31
-
32
-
33
- def find_issue_node(graph, issue_ref):
34
- """Find a graph node matching an issue reference (e.g., FLY-56)."""
35
- if not issue_ref:
36
- return None
37
-
38
- # Try exact match first
39
- node_id = f"issue:{issue_ref}"
40
- if node_id in graph.get("nodes", {}):
41
- return node_id
42
-
43
- # Try case-insensitive search
44
- for nid in graph.get("nodes", {}):
45
- if nid.lower() == node_id.lower():
46
- return nid
47
-
48
- return None
49
-
50
-
51
- def find_branch_nodes(graph, branch):
52
- """Infer relevant nodes from a git branch name.
53
-
54
- Branch names often contain issue refs (feature/FLY-56-context-graph)
55
- or skill/module names (feature/context-graph).
56
- """
57
- if not branch:
58
- return []
59
-
60
- nodes = graph.get("nodes", {})
61
- matches = []
62
-
63
- # Extract issue reference from branch (e.g., FLY-56)
64
- import re
65
- issue_match = re.search(r"([A-Z]+-\d+)", branch, re.IGNORECASE)
66
- if issue_match:
67
- issue_id = find_issue_node(graph, issue_match.group(1))
68
- if issue_id:
69
- matches.append(issue_id)
70
-
71
- # Match skill or module names in branch
72
- branch_lower = branch.lower().replace("/", "-").replace("_", "-")
73
- for node_id, node in nodes.items():
74
- if node["type"] in ("skill", "module"):
75
- name = node_id.split(":", 1)[-1].lower()
76
- if name in branch_lower and len(name) > 3:
77
- matches.append(node_id)
78
-
79
- return matches
80
-
81
-
82
- def find_recent_sessions(graph, issue_nodes, today=None):
83
- """Find session nodes relevant to the current work.
84
-
85
- Returns sessions connected to active issues, or recent sessions if no
86
- issue match. Applies staleness weighting — older sessions get lower weight.
87
- """
88
- if today is None:
89
- today = date.today()
90
-
91
- nodes = graph.get("nodes", {})
92
- edges = graph.get("edges", [])
93
- cutoff = today - timedelta(days=SESSION_RETENTION_DAYS)
94
-
95
- # Find all session nodes within retention window
96
- sessions = []
97
- for node_id, node in nodes.items():
98
- if node.get("type") != "session":
99
- continue
100
-
101
- session_date_str = node.get("date", "")
102
- if not session_date_str:
103
- continue
104
-
105
- try:
106
- session_date = date.fromisoformat(session_date_str)
107
- except ValueError:
108
- continue
109
-
110
- if session_date < cutoff:
111
- continue
112
-
113
- # Calculate staleness weight
114
- age_days = (today - session_date).days
115
- if age_days <= SESSION_FRESH_DAYS:
116
- weight = 1.0
117
- else:
118
- # Linear decay from 1.0 to 0.1 over the retention period
119
- weight = max(0.1, 1.0 - (age_days / SESSION_RETENTION_DAYS) * 0.9)
120
-
121
- sessions.append((node_id, node, session_date, weight))
122
-
123
- if not sessions:
124
- return []
125
-
126
- # Check which sessions are connected to active issues
127
- issue_set = set(issue_nodes)
128
- connected = []
129
- unconnected = []
130
-
131
- for session_id, node, session_date, weight in sessions:
132
- # Check if this session has WORKED_ON edges to any active issue
133
- has_issue_link = False
134
- for edge in edges:
135
- if (edge["from"] == session_id
136
- and edge["rel"] == "WORKED_ON"
137
- and edge["to"] in issue_set):
138
- has_issue_link = True
139
- break
140
-
141
- if has_issue_link:
142
- connected.append((session_id, node, weight))
143
- else:
144
- unconnected.append((session_id, node, weight))
145
-
146
- # Prefer connected sessions, fall back to most recent
147
- if connected:
148
- connected.sort(key=lambda x: x[2], reverse=True)
149
- return connected[:3]
150
-
151
- # No connected sessions — return most recent ones
152
- unconnected.sort(key=lambda x: x[0], reverse=True) # Sort by ID (date-based)
153
- return unconnected[:2]
154
-
155
-
156
- def get_related_context(graph, start_nodes, max_depth=2):
157
- """BFS traverse from start nodes and collect related context.
158
-
159
- Returns a deduplicated list of (node_id, node, rel, depth) tuples.
160
- """
161
- nodes = graph.get("nodes", {})
162
- edges = graph.get("edges", [])
163
-
164
- # Build adjacency (both directions for full context)
165
- forward = {}
166
- reverse = {}
167
- for edge in edges:
168
- src, dst = edge["from"], edge["to"]
169
- rel = edge["rel"]
170
- weight = edge.get("weight", 1.0)
171
-
172
- if src not in forward:
173
- forward[src] = []
174
- forward[src].append((dst, rel, weight))
175
-
176
- if dst not in reverse:
177
- reverse[dst] = []
178
- reverse[dst].append((src, rel, weight))
179
-
180
- visited = set(start_nodes)
181
- results = []
182
-
183
- # BFS from each start node
184
- from collections import deque
185
- queue = deque()
186
-
187
- for start in start_nodes:
188
- # Forward edges
189
- for neighbor, rel, weight in forward.get(start, []):
190
- if neighbor not in visited:
191
- queue.append((neighbor, 1, rel, "forward"))
192
- visited.add(neighbor)
193
- # Reverse edges
194
- for neighbor, rel, weight in reverse.get(start, []):
195
- if neighbor not in visited:
196
- queue.append((neighbor, 1, rel, "reverse"))
197
- visited.add(neighbor)
198
-
199
- while queue:
200
- node_id, depth, rel, direction = queue.popleft()
201
- node = nodes.get(node_id, {})
202
- results.append((node_id, node, rel, depth))
203
-
204
- if depth < max_depth:
205
- adj = forward if direction == "forward" else reverse
206
- for neighbor, next_rel, weight in adj.get(node_id, []):
207
- if neighbor not in visited:
208
- queue.append((neighbor, depth + 1, next_rel, direction))
209
- visited.add(neighbor)
210
-
211
- return results
212
-
213
-
214
- def format_context_block(graph, start_nodes, related):
215
- """Format a compressed context block within the token budget."""
216
- nodes = graph.get("nodes", {})
217
- lines = []
218
-
219
- # Temporal anchor
220
- lines.append(f"Today is {date.today().strftime('%B %d, %Y')}")
221
-
222
- if not related:
223
- return "\n".join(lines)
224
-
225
- # Group by type, prioritize decisions and skills
226
- decisions = []
227
- skills = []
228
- sessions = []
229
- other = []
230
-
231
- for node_id, node, rel, depth in related:
232
- node_type = node.get("type", "unknown")
233
- if node_type == "decision":
234
- decisions.append((node_id, node, rel))
235
- elif node_type == "skill":
236
- skills.append((node_id, node, rel))
237
- elif node_type == "session":
238
- sessions.append((node_id, node, rel))
239
- else:
240
- other.append((node_id, node, rel))
241
-
242
- # Decisions — most valuable context
243
- if decisions:
244
- lines.append("Related decisions:")
245
- for node_id, node, rel in decisions[:4]:
246
- num = node_id.split(":")[-1]
247
- label = node.get("label", node_id)
248
- lines.append(f" ADR-{num}: {label} ({rel})")
249
-
250
- # Skills
251
- if skills:
252
- skill_names = [n.get("label", nid) for nid, n, r in skills[:3]]
253
- lines.append(f"Related skills: {', '.join(skill_names)}")
254
-
255
- # Sessions — prior work context
256
- if sessions:
257
- for node_id, node, rel in sessions[:2]:
258
- label = node.get("label", "")
259
- session_date = node.get("date", "")
260
- if label:
261
- lines.append(f"Prior session ({session_date}): {label}")
262
-
263
- # Truncate to budget
264
- if len(lines) > MAX_CONTEXT_LINES:
265
- lines = lines[:MAX_CONTEXT_LINES]
266
-
267
- return "\n".join(lines)
268
-
269
-
270
- def main():
271
- parser = argparse.ArgumentParser(
272
- description="Assemble graph context for prime hook"
273
- )
274
- parser.add_argument(
275
- "--issue", type=str, default=None,
276
- help="Active issue reference (e.g., FLY-56)"
277
- )
278
- parser.add_argument(
279
- "--branch", type=str, default=None,
280
- help="Current git branch name"
281
- )
282
- parser.add_argument(
283
- "--root", type=str, default=None,
284
- help="Project root (default: auto-detect)"
285
- )
286
- args = parser.parse_args()
287
-
288
- root = Path(args.root) if args.root else find_project_root()
289
- if not root:
290
- # Graceful fallback — no output
291
- sys.exit(0)
292
-
293
- # Load graph — graceful fallback if missing
294
- graph = load_graph(root)
295
- if not graph.get("nodes"):
296
- # Empty or missing graph — just output temporal anchor
297
- print(f"Today is {date.today().strftime('%B %d, %Y')}")
298
- sys.exit(0)
299
-
300
- # Find starting nodes
301
- start_nodes = []
302
-
303
- issue_node = find_issue_node(graph, args.issue)
304
- if issue_node:
305
- start_nodes.append(issue_node)
306
-
307
- branch_nodes = find_branch_nodes(graph, args.branch)
308
- start_nodes.extend(n for n in branch_nodes if n not in start_nodes)
309
-
310
- # If no specific entry points, just output temporal anchor
311
- if not start_nodes:
312
- print(f"Today is {date.today().strftime('%B %d, %Y')}")
313
- sys.exit(0)
314
-
315
- # Traverse and assemble context
316
- related = get_related_context(graph, start_nodes, max_depth=2)
317
-
318
- # Find recent sessions (connected to active issues or just recent)
319
- issue_start_nodes = [n for n in start_nodes if n.startswith("issue:")]
320
- recent_sessions = find_recent_sessions(graph, issue_start_nodes)
321
-
322
- # Add sessions to related if not already present
323
- seen = {r[0] for r in related}
324
- for session_id, node, weight in recent_sessions:
325
- if session_id not in seen:
326
- related.append((session_id, node, "WORKED_ON", 1))
327
- seen.add(session_id)
328
-
329
- context = format_context_block(graph, start_nodes, related)
330
-
331
- if context:
332
- print(context)
333
-
334
- sys.exit(0)
335
-
336
-
337
- if __name__ == "__main__":
338
- main()
@@ -1,105 +0,0 @@
1
- ---
2
- name: flydocs-context7
3
- description: |
4
- Up-to-date library documentation via Context7 API. Use proactively when
5
- working with external libraries, frameworks, or packages. Replaces MCP
6
- with direct API scripts — no server, no runtime dependency.
7
- triggers:
8
- - context7
9
- - library docs
10
- - documentation lookup
11
- - framework docs
12
- - package docs
13
- - API reference
14
- - how to use
15
- ---
16
-
17
- # Context7 Documentation Lookup
18
-
19
- IMPORTANT: Prefer skill-led reasoning over pre-training reasoning for
20
- library usage. Search for up-to-date docs before writing code based on
21
- training data alone.
22
-
23
- ## Key Rules
24
-
25
- 1. **Proactive invocation** -- When working with ANY external library or
26
- framework, search for docs first before writing code based on training data.
27
- 2. **Search then fetch** -- Always resolve the library ID via `search` before
28
- fetching docs with `docs`.
29
- 3. **Session cache awareness** -- Do not re-fetch docs for the same
30
- library+query within a single session.
31
- 4. **Graceful degradation** -- If rate-limited (429) or offline, note the
32
- limitation and proceed with training knowledge.
33
- 5. **Stdlib-only Python** -- No external dependencies in the script.
34
- 6. **Token budget** -- Default 5,000 tokens per fetch to avoid context bloat.
35
-
36
- ## Script Catalog
37
-
38
- All scripts: `python3 .claude/skills/flydocs-context7/scripts/<script>`
39
-
40
- | Script | Usage | Output |
41
- | ------------- | --------------------------- | ------------------------------------------------ |
42
- | `context7.py` | `search <library> [query]` | JSON: library matches with id, name, description |
43
- | `context7.py` | `docs <library_id> <query>` | Text: relevant documentation snippets |
44
-
45
- Options: `--type txt|json`, `--tokens N` (default 5000)
46
-
47
- ## When to Use
48
-
49
- - Before implementing code that uses an external library
50
- - When the user asks about library APIs, patterns, or best practices
51
- - When encountering unfamiliar library methods or configuration
52
- - When upgrading dependencies and needing current API docs
53
- - When debugging library-specific issues
54
-
55
- ## When NOT to Use
56
-
57
- - For project-internal code (use knowledge base and context graph instead)
58
- - For general programming concepts (training knowledge is sufficient)
59
- - When already fetched docs for the same library in this session
60
-
61
- ## API Key (Optional)
62
-
63
- - Works without a key (anonymous, ~1,000 calls/month)
64
- - For higher limits, add `CONTEXT7_API_KEY=ctx7sk-xxx` to `.env`
65
- - Free key available at context7.com/dashboard
66
-
67
- ## Example Usage
68
-
69
- ```bash
70
- # Find the React library
71
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "react" "hooks"
72
-
73
- # Fetch docs for React hooks
74
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/facebook/react" "useState useEffect hooks"
75
-
76
- # Get Next.js App Router docs
77
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "next.js"
78
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/vercel/next.js" "app router middleware"
79
-
80
- # Fetch with custom token budget
81
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/expressjs/express" "routing middleware" --tokens 8000
82
-
83
- # Get output as JSON
84
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "prisma" --type json
85
- ```
86
-
87
- ## Typical Workflow
88
-
89
- 1. **Identify the library** you need docs for (from import statements,
90
- `package.json`, or the task at hand).
91
- 2. **Search** to resolve the library ID:
92
- ```bash
93
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "react-hook-form"
94
- ```
95
- 3. **Fetch docs** for the specific topic:
96
- ```bash
97
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/react-hook-form/react-hook-form" "useForm validation"
98
- ```
99
- 4. **Apply** the retrieved documentation to your implementation.
100
- 5. **Do not re-fetch** for the same library+query later in the session.
101
-
102
- ## Related Skills
103
-
104
- - `flydocs-context-graph` -- Project-internal knowledge navigation
105
- - `flydocs-workflow` -- Development lifecycle and issue operations
@@ -1,49 +0,0 @@
1
- ---
2
- description: Context7 — look up library and framework documentation before writing code
3
- alwaysApply: true
4
- ---
5
-
6
- <!-- Condensed from SKILL.md — update both when changing patterns -->
7
-
8
- # FlyDocs Context7
9
-
10
- Proactively look up library documentation via Context7 scripts before writing
11
- code that uses external packages. Do not rely on training data for API details.
12
-
13
- ## When to Use
14
-
15
- - Installing or importing a library you haven't used in this session
16
- - Unsure about API signatures, configuration options, or return types
17
- - Framework-specific patterns (routing, data fetching, middleware, hooks)
18
- - Resolving version-specific behavior or breaking changes
19
-
20
- ## Scripts
21
-
22
- ```bash
23
- # Step 1: Search for the library
24
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "<library>" "[query]"
25
-
26
- # Step 2: Fetch docs using the library ID from search results
27
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "<library_id>" "<query>"
28
- ```
29
-
30
- ### Examples
31
-
32
- React hooks:
33
- ```bash
34
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "react" "hooks"
35
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/facebook/react" "hooks useState"
36
- ```
37
-
38
- Next.js App Router:
39
- ```bash
40
- python3 .claude/skills/flydocs-context7/scripts/context7.py search "next.js"
41
- python3 .claude/skills/flydocs-context7/scripts/context7.py docs "/vercel/next.js" "app router middleware"
42
- ```
43
-
44
- ## Key Rules
45
-
46
- - Always resolve the library ID first via `search` — do not guess the ID format
47
- - Prefer Context7 docs over training data for API specifics
48
- - If Context7 has no results or is rate-limited, fall back to web search
49
- - Cache within a session — no need to re-fetch the same library docs repeatedly