@flydocs/cli 0.5.0-beta.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 (134) hide show
  1. package/README.md +96 -0
  2. package/dist/cli.js +2666 -0
  3. package/package.json +32 -0
  4. package/template/.claude/CLAUDE.md +90 -0
  5. package/template/.claude/agents/README.md +19 -0
  6. package/template/.claude/agents/implementation-agent.md +29 -0
  7. package/template/.claude/agents/pm-agent.md +29 -0
  8. package/template/.claude/agents/research-agent.md +25 -0
  9. package/template/.claude/agents/review-agent.md +29 -0
  10. package/template/.claude/commands/activate.md +10 -0
  11. package/template/.claude/commands/attach.md +9 -0
  12. package/template/.claude/commands/block.md +10 -0
  13. package/template/.claude/commands/capture.md +10 -0
  14. package/template/.claude/commands/close.md +10 -0
  15. package/template/.claude/commands/flydocs-setup.md +598 -0
  16. package/template/.claude/commands/flydocs-update.md +27 -0
  17. package/template/.claude/commands/implement.md +10 -0
  18. package/template/.claude/commands/new-project.md +11 -0
  19. package/template/.claude/commands/project-update.md +10 -0
  20. package/template/.claude/commands/refine.md +10 -0
  21. package/template/.claude/commands/review.md +10 -0
  22. package/template/.claude/commands/start-session.md +10 -0
  23. package/template/.claude/commands/status.md +10 -0
  24. package/template/.claude/commands/validate.md +10 -0
  25. package/template/.claude/commands/wrap-session.md +10 -0
  26. package/template/.claude/settings.json +49 -0
  27. package/template/.claude/skills/README.md +293 -0
  28. package/template/.claude/skills/flydocs-cloud/SKILL.md +96 -0
  29. package/template/.claude/skills/flydocs-cloud/cursor-rule.mdc +50 -0
  30. package/template/.claude/skills/flydocs-cloud/scripts/assign.py +38 -0
  31. package/template/.claude/skills/flydocs-cloud/scripts/assign_cycle.py +44 -0
  32. package/template/.claude/skills/flydocs-cloud/scripts/assign_milestone.py +44 -0
  33. package/template/.claude/skills/flydocs-cloud/scripts/comment.py +39 -0
  34. package/template/.claude/skills/flydocs-cloud/scripts/create_issue.py +100 -0
  35. package/template/.claude/skills/flydocs-cloud/scripts/create_milestone.py +46 -0
  36. package/template/.claude/skills/flydocs-cloud/scripts/create_project.py +40 -0
  37. package/template/.claude/skills/flydocs-cloud/scripts/estimate.py +38 -0
  38. package/template/.claude/skills/flydocs-cloud/scripts/flydocs_api.py +277 -0
  39. package/template/.claude/skills/flydocs-cloud/scripts/get_issue.py +77 -0
  40. package/template/.claude/skills/flydocs-cloud/scripts/link.py +47 -0
  41. package/template/.claude/skills/flydocs-cloud/scripts/list_cycles.py +35 -0
  42. package/template/.claude/skills/flydocs-cloud/scripts/list_issues.py +105 -0
  43. package/template/.claude/skills/flydocs-cloud/scripts/list_milestones.py +40 -0
  44. package/template/.claude/skills/flydocs-cloud/scripts/list_projects.py +45 -0
  45. package/template/.claude/skills/flydocs-cloud/scripts/priority.py +38 -0
  46. package/template/.claude/skills/flydocs-cloud/scripts/project_update.py +59 -0
  47. package/template/.claude/skills/flydocs-cloud/scripts/transition.py +67 -0
  48. package/template/.claude/skills/flydocs-cloud/scripts/update_description.py +47 -0
  49. package/template/.claude/skills/flydocs-cloud/scripts/update_issue.py +111 -0
  50. package/template/.claude/skills/flydocs-context-graph/SKILL.md +87 -0
  51. package/template/.claude/skills/flydocs-context-graph/schema.md +78 -0
  52. package/template/.claude/skills/flydocs-context-graph/scripts/graph_build.py +299 -0
  53. package/template/.claude/skills/flydocs-context-graph/scripts/graph_context.py +338 -0
  54. package/template/.claude/skills/flydocs-context-graph/scripts/graph_query.py +191 -0
  55. package/template/.claude/skills/flydocs-context-graph/scripts/graph_session.py +161 -0
  56. package/template/.claude/skills/flydocs-context-graph/scripts/graph_update.py +194 -0
  57. package/template/.claude/skills/flydocs-context-graph/scripts/graph_utils.py +118 -0
  58. package/template/.claude/skills/flydocs-estimates/SKILL.md +384 -0
  59. package/template/.claude/skills/flydocs-estimates/references/provider-costs.md +152 -0
  60. package/template/.claude/skills/flydocs-figma/SKILL.md +377 -0
  61. package/template/.claude/skills/flydocs-figma/references/PROMPTING.md +108 -0
  62. package/template/.claude/skills/flydocs-figma/references/TROUBLESHOOTING.md +112 -0
  63. package/template/.claude/skills/flydocs-local/SKILL.md +103 -0
  64. package/template/.claude/skills/flydocs-local/cursor-rule.mdc +43 -0
  65. package/template/.claude/skills/flydocs-local/scripts/assign.py +20 -0
  66. package/template/.claude/skills/flydocs-local/scripts/comment.py +27 -0
  67. package/template/.claude/skills/flydocs-local/scripts/create_issue.py +44 -0
  68. package/template/.claude/skills/flydocs-local/scripts/estimate.py +37 -0
  69. package/template/.claude/skills/flydocs-local/scripts/flydocs_api.py +272 -0
  70. package/template/.claude/skills/flydocs-local/scripts/get_issue.py +20 -0
  71. package/template/.claude/skills/flydocs-local/scripts/link.py +41 -0
  72. package/template/.claude/skills/flydocs-local/scripts/list_issues.py +34 -0
  73. package/template/.claude/skills/flydocs-local/scripts/priority.py +37 -0
  74. package/template/.claude/skills/flydocs-local/scripts/project_update.py +67 -0
  75. package/template/.claude/skills/flydocs-local/scripts/status_summary.py +16 -0
  76. package/template/.claude/skills/flydocs-local/scripts/transition.py +24 -0
  77. package/template/.claude/skills/flydocs-local/scripts/update_description.py +35 -0
  78. package/template/.claude/skills/flydocs-local/scripts/update_issue.py +84 -0
  79. package/template/.claude/skills/flydocs-workflow/SKILL.md +85 -0
  80. package/template/.claude/skills/flydocs-workflow/cursor-rule.mdc +53 -0
  81. package/template/.claude/skills/flydocs-workflow/reference/comment-templates.md +131 -0
  82. package/template/.claude/skills/flydocs-workflow/reference/golden-rules.md +76 -0
  83. package/template/.claude/skills/flydocs-workflow/reference/priority-estimates.md +28 -0
  84. package/template/.claude/skills/flydocs-workflow/reference/status-workflow.md +50 -0
  85. package/template/.claude/skills/flydocs-workflow/session.md +128 -0
  86. package/template/.claude/skills/flydocs-workflow/stages/activate.md +46 -0
  87. package/template/.claude/skills/flydocs-workflow/stages/capture.md +50 -0
  88. package/template/.claude/skills/flydocs-workflow/stages/close.md +32 -0
  89. package/template/.claude/skills/flydocs-workflow/stages/implement.md +124 -0
  90. package/template/.claude/skills/flydocs-workflow/stages/refine.md +51 -0
  91. package/template/.claude/skills/flydocs-workflow/stages/review.md +86 -0
  92. package/template/.claude/skills/flydocs-workflow/stages/validate.md +90 -0
  93. package/template/.claude/skills/flydocs-workflow/templates/bug.md +95 -0
  94. package/template/.claude/skills/flydocs-workflow/templates/chore.md +75 -0
  95. package/template/.claude/skills/flydocs-workflow/templates/feature.md +93 -0
  96. package/template/.claude/skills/flydocs-workflow/templates/idea.md +84 -0
  97. package/template/.cursor/agents/implementation-agent.md +28 -0
  98. package/template/.cursor/agents/pm-agent.md +27 -0
  99. package/template/.cursor/agents/research-agent.md +23 -0
  100. package/template/.cursor/agents/review-agent.md +27 -0
  101. package/template/.cursor/hooks.json +29 -0
  102. package/template/.cursor/mcp.json +16 -0
  103. package/template/.env.example +44 -0
  104. package/template/.flydocs/config.json +104 -0
  105. package/template/.flydocs/hooks/auto-approve.py +71 -0
  106. package/template/.flydocs/hooks/post-edit.py +72 -0
  107. package/template/.flydocs/hooks/prefer-scripts.py +89 -0
  108. package/template/.flydocs/hooks/prompt-submit.py +277 -0
  109. package/template/.flydocs/scripts/generate_manifest.py +287 -0
  110. package/template/.flydocs/scripts/skill_manager.py +541 -0
  111. package/template/.flydocs/templates/README.md +46 -0
  112. package/template/.flydocs/templates/bug.md +166 -0
  113. package/template/.flydocs/templates/chore.md +110 -0
  114. package/template/.flydocs/templates/design-system/README.md +27 -0
  115. package/template/.flydocs/templates/design-system/component-patterns.md +92 -0
  116. package/template/.flydocs/templates/design-system/token-mapping.md +168 -0
  117. package/template/.flydocs/templates/feature.md +173 -0
  118. package/template/.flydocs/templates/idea.md +122 -0
  119. package/template/.flydocs/templates/instructions.md +228 -0
  120. package/template/.flydocs/templates/quick-capture.md +35 -0
  121. package/template/.flydocs/templates/scripts/check-design-system.template.mjs +179 -0
  122. package/template/.flydocs/version +1 -0
  123. package/template/AGENTS.md +95 -0
  124. package/template/CHANGELOG.md +271 -0
  125. package/template/flydocs/README.md +186 -0
  126. package/template/flydocs/context/project.md +51 -0
  127. package/template/flydocs/design-system/README.md +126 -0
  128. package/template/flydocs/design-system/component-patterns.md +173 -0
  129. package/template/flydocs/design-system/token-mapping.md +114 -0
  130. package/template/flydocs/knowledge/INDEX.md +100 -0
  131. package/template/flydocs/knowledge/README.md +62 -0
  132. package/template/flydocs/knowledge/product/personas.md +79 -0
  133. package/template/flydocs/knowledge/product/user-flows.md +88 -0
  134. package/template/manifest.json +221 -0
@@ -0,0 +1,10 @@
1
+ # Status (All Agents)
2
+
3
+ Quick status dashboard — issue counts by status for active projects.
4
+
5
+ Read `.claude/skills/flydocs-workflow/session.md` for dashboard format.
6
+ Use `list_issues.py --active` from the active mechanism skill and group results by status.
7
+
8
+ Triggers: "status", "where are we", "what's the status"
9
+
10
+ $ARGUMENTS
@@ -0,0 +1,10 @@
1
+ # Validate (QE/Validation Agent)
2
+
3
+ Present the implementation for user acceptance testing.
4
+
5
+ Read `.claude/skills/flydocs-workflow/stages/validate.md` and follow the procedure.
6
+ Read the active mechanism skill's `SKILL.md` for script calling conventions.
7
+
8
+ Triggers: "validate", "test this", "QA", "looks good", "approve"
9
+
10
+ $ARGUMENTS
@@ -0,0 +1,10 @@
1
+ # Wrap Session (PM/Planning Agent)
2
+
3
+ End a work session — summarize progress, update issues, post project health update.
4
+
5
+ Read `.claude/skills/flydocs-workflow/session.md` and follow the session wrap procedure.
6
+ Read the active mechanism skill's `SKILL.md` for script calling conventions.
7
+
8
+ Triggers: "wrap up", "end session", "that's it for today", "let's wrap"
9
+
10
+ $ARGUMENTS
@@ -0,0 +1,49 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Bash",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.flydocs/hooks/auto-approve.py",
10
+ "timeout": 5
11
+ }
12
+ ]
13
+ },
14
+ {
15
+ "matcher": "mcp__linear.*",
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.flydocs/hooks/prefer-scripts.py",
20
+ "timeout": 5
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "PostToolUse": [
26
+ {
27
+ "matcher": "Edit|Write",
28
+ "hooks": [
29
+ {
30
+ "type": "command",
31
+ "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.flydocs/hooks/post-edit.py",
32
+ "timeout": 30
33
+ }
34
+ ]
35
+ }
36
+ ],
37
+ "UserPromptSubmit": [
38
+ {
39
+ "hooks": [
40
+ {
41
+ "type": "command",
42
+ "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.flydocs/hooks/prompt-submit.py",
43
+ "timeout": 10
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
49
+ }
@@ -0,0 +1,293 @@
1
+ # FlyDocs Skills
2
+
3
+ > Authoritative guide for skill architecture, authoring, and structure.
4
+
5
+ ---
6
+
7
+ ## Skill Categories
8
+
9
+ ### `flydocs-*` — Platform Skills
10
+
11
+ Owned and maintained by FlyDocs. May include executable scripts and premium
12
+ functionality gated via API relay.
13
+
14
+ | Skill | Category | Purpose |
15
+ |-------|----------|---------|
16
+ | `flydocs-workflow` | Core | Lifecycle stages, session management, comment templates |
17
+ | `flydocs-local` | Mechanism (free) | File-based issue management |
18
+ | `flydocs-cloud` | Mechanism (paid) | Linear/provider issue management via API |
19
+ | `flydocs-figma` | Premium | Design extraction from Figma |
20
+ | `flydocs-estimates` | Premium | AI token/labor cost estimation |
21
+
22
+ Only one mechanism skill is active at a time. Determined by `tier` in `.flydocs/config.json`.
23
+
24
+ Supporting workflow skills (bundled, invoked via commands):
25
+
26
+ | Skill | Purpose | Trigger |
27
+ |-------|---------|---------|
28
+ | `implementation-flow` | Implementation procedure | `/implement` |
29
+ | `review-workflow` | Code review analysis | `/review` |
30
+ | `spec-templates` | Issue specification templates | `/capture`, `/refine` |
31
+
32
+ ### Unprefixed — Community Skills
33
+
34
+ Stack-detected or manually installed. Pure guidance (markdown only, no scripts).
35
+ Portable across projects and AI coding tools.
36
+
37
+ ```bash
38
+ flydocs skills search typescript
39
+ flydocs skills add <repo>
40
+ flydocs skills list
41
+ ```
42
+
43
+ Examples: `typescript-strict`, `testing-patterns`, `accessibility-patterns`,
44
+ `react-best-practices`, `convex-patterns`
45
+
46
+ Browse: [skills.sh](https://skills.sh/)
47
+
48
+ ---
49
+
50
+ ## Skill Authoring Standard
51
+
52
+ ### Directory Structure
53
+
54
+ ```
55
+ .claude/skills/{skill-name}/
56
+ ├── SKILL.md # Required — main skill file
57
+ ├── cursor-rule.mdc # Optional — condensed Cursor rule
58
+ ├── scripts/ # Platform skills only — executable scripts
59
+ └── reference/ # Optional — supporting detail files
60
+ ```
61
+
62
+ - **`skill-name`** uses kebab-case. Platform skills use the `flydocs-` prefix.
63
+ - **`SKILL.md`** is the entry point. Agents read this first.
64
+ - **`cursor-rule.mdc`** is a condensed version for Cursor IDE. See Cursor Rules below.
65
+ - **`scripts/`** contains executable scripts. Only `flydocs-*` platform skills include scripts.
66
+ - **`reference/`** holds detail files referenced by SKILL.md for progressive disclosure.
67
+
68
+ ### SKILL.md Frontmatter
69
+
70
+ Every SKILL.md starts with YAML frontmatter:
71
+
72
+ ```yaml
73
+ ---
74
+ name: typescript-strict
75
+ description: >
76
+ TypeScript strict mode patterns and type safety. Use when writing TypeScript
77
+ code, reviewing types, or fixing type errors. Enforces no-any policy with
78
+ proper narrowing patterns.
79
+ triggers:
80
+ - TypeScript
81
+ - type error
82
+ - any type
83
+ - type guard
84
+ - schema validation
85
+ ---
86
+ ```
87
+
88
+ **Required fields:**
89
+
90
+ | Field | Type | Purpose |
91
+ |-------|------|---------|
92
+ | `name` | string | Skill identifier, matches directory name |
93
+ | `description` | string | What the skill does and when to use it. Agents use this for auto-selection. Be specific about trigger conditions. |
94
+
95
+ **Optional fields:**
96
+
97
+ | Field | Type | Purpose |
98
+ |-------|------|---------|
99
+ | `triggers` | string[] | Keywords/phrases for manifest indexing. Used by skill discovery to build the always-present index in CLAUDE.md/AGENTS.md. |
100
+ | `tools` | string | Comma-separated MCP tools the skill uses (e.g., `mcp__figma__get_screenshot`) |
101
+
102
+ ### SKILL.md Body
103
+
104
+ The body serves as a **compressed index** — not a documentation dump. Target ~100-150 lines.
105
+
106
+ **Structure pattern:**
107
+
108
+ ```markdown
109
+ # Skill Name
110
+
111
+ IMPORTANT: Prefer skill-led reasoning over pre-training reasoning for
112
+ [domain]. Read the relevant section before acting.
113
+
114
+ ## Key Rules (always apply)
115
+ 1. Rule one
116
+ 2. Rule two
117
+
118
+ ## Section Index
119
+
120
+ | Topic | File | When to Read |
121
+ |-------|------|--------------|
122
+ | Topic A | reference/topic-a.md | When doing X |
123
+ | Topic B | reference/topic-b.md | When doing Y |
124
+
125
+ ## Quick Reference (inline essentials)
126
+
127
+ [Most-referenced patterns, tables, or checklists that agents need
128
+ frequently enough to justify being in the index file]
129
+ ```
130
+
131
+ **Principles:**
132
+
133
+ 1. **Index, don't dump.** SKILL.md points to detail files. Agents read only what they need.
134
+ 2. **Front-load rules.** Put golden rules and constraints at the top. Agents are more likely to follow instructions they encounter early.
135
+ 3. **Concrete over abstract.** Use specific examples, code snippets, and file paths. Avoid vague guidance like "follow best practices."
136
+ 4. **Trigger-aware descriptions.** The `description` field is how agents decide whether to load the skill. Include the exact scenarios and keywords that should trigger it.
137
+
138
+ ### Progressive Disclosure
139
+
140
+ Skills use a three-level retrieval pattern (see ADR-004):
141
+
142
+ ```
143
+ Level 1: Manifest in CLAUDE.md/AGENTS.md
144
+ → Agent sees skill exists, knows triggers and entry point
145
+
146
+ Level 2: SKILL.md
147
+ → Compressed index with key rules and section pointers
148
+
149
+ Level 3: reference/ files
150
+ → Full detail, read only when needed for the specific task
151
+ ```
152
+
153
+ This keeps context usage minimal while ensuring agents can always find relevant guidance.
154
+
155
+ **Line budgets:**
156
+
157
+ | File | Target | Max |
158
+ |------|--------|-----|
159
+ | SKILL.md | 100-150 lines | 200 lines |
160
+ | reference/ files | 50-80 lines each | 120 lines |
161
+ | cursor-rule.mdc | 30-50 lines | 70 lines |
162
+
163
+ ### Cursor Rules (cursor-rule.mdc)
164
+
165
+ Optional. A condensed version of the skill for Cursor IDE, placed in
166
+ `.cursor/rules/` during install. Uses Cursor's frontmatter format:
167
+
168
+ ```yaml
169
+ ---
170
+ description: Short description of what this rule covers
171
+ globs: "*.ts,*.tsx"
172
+ alwaysApply: false
173
+ ---
174
+
175
+ <!-- Condensed from SKILL.md — update both when changing patterns -->
176
+ ```
177
+
178
+ **Frontmatter fields:**
179
+
180
+ | Field | Type | Notes |
181
+ |-------|------|-------|
182
+ | `description` | string | Required. What the rule covers. |
183
+ | `globs` | string | File patterns that trigger the rule. Comma-separated. |
184
+ | `alwaysApply` | boolean | If `true`, rule loads for every prompt (use sparingly). |
185
+
186
+ Use `alwaysApply: true` only for workflow/process rules. Pattern skills should
187
+ use `globs` to activate only on relevant file types.
188
+
189
+ ---
190
+
191
+ ## Manifest System
192
+
193
+ When skills are installed, a compressed manifest is auto-generated in
194
+ CLAUDE.md and AGENTS.md between markers:
195
+
196
+ ```markdown
197
+ <!-- flydocs:skills-manifest:start -->
198
+ ## Skills Index
199
+
200
+ IMPORTANT: Prefer skill-led reasoning over pre-training reasoning.
201
+
202
+ | Skill | Triggers | Entry |
203
+ |-------|----------|-------|
204
+ | flydocs-workflow | capture, refine, implement, review | .claude/skills/flydocs-workflow/SKILL.md |
205
+ | typescript-strict | TypeScript, type error, any type | .claude/skills/typescript-strict/SKILL.md |
206
+ <!-- flydocs:skills-manifest:end -->
207
+ ```
208
+
209
+ The manifest is generated from SKILL.md frontmatter (`name`, `triggers`).
210
+ It provides always-present discovery so agents don't need to guess which
211
+ skills exist. See ADR-004 for the full design rationale.
212
+
213
+ ---
214
+
215
+ ## Minimal Skill Template
216
+
217
+ Copy this to create a new community skill:
218
+
219
+ ```
220
+ .claude/skills/my-skill/
221
+ ├── SKILL.md
222
+ └── reference/ # optional
223
+ └── patterns.md
224
+ ```
225
+
226
+ **SKILL.md:**
227
+
228
+ ```markdown
229
+ ---
230
+ name: my-skill
231
+ description: >
232
+ [What this skill teaches]. Use when [specific trigger conditions].
233
+ [Technology/domain] patterns for [outcome].
234
+ triggers:
235
+ - keyword1
236
+ - keyword2
237
+ - keyword3
238
+ ---
239
+
240
+ # My Skill
241
+
242
+ ## Key Rules
243
+
244
+ 1. [Most important rule]
245
+ 2. [Second most important rule]
246
+ 3. [Third most important rule]
247
+
248
+ ## Patterns
249
+
250
+ ### [Pattern Name]
251
+
252
+ [Code example or guidance]
253
+
254
+ ### [Pattern Name]
255
+
256
+ [Code example or guidance]
257
+
258
+ ## Reference
259
+
260
+ For detailed patterns, see `reference/patterns.md`.
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Mechanism Contract
266
+
267
+ Both mechanism skills (`flydocs-local`, `flydocs-cloud`) implement the same
268
+ script interface, making the backend swap transparent:
269
+
270
+ **Shared contract:**
271
+ `create_issue.py`, `transition.py`, `comment.py`, `list_issues.py`,
272
+ `get_issue.py`, `assign.py`, `update_description.py`
273
+
274
+ **Cloud-only extensions:**
275
+ `update_issue.py`, `project_update.py`, `estimate.py`, `priority.py`, `link.py`, cycle/milestone management.
276
+
277
+ ---
278
+
279
+ ## Platform Support
280
+
281
+ | Platform | Skill Location | Notes |
282
+ |----------|---------------|-------|
283
+ | Claude Code | `.claude/skills/` | Native support |
284
+ | Cursor | `.cursor/rules/*.mdc` | Generated from `cursor-rule.mdc` |
285
+ | Codex / Others | `AGENTS.md` | Universal layer via manifest |
286
+
287
+ ---
288
+
289
+ ## Resources
290
+
291
+ - **Skills ecosystem:** [skills.sh](https://skills.sh/)
292
+ - **Agent Skills spec:** [agentskills.io](https://agentskills.io)
293
+ - **Discovery design:** `flydocs/knowledge/decisions/004-skill-discovery-and-indexing.md`
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: flydocs-cloud
3
+ description: |
4
+ Connected issue management via Linear GraphQL API.
5
+ Implements the FlyDocs mechanism contract with extended cloud-only operations.
6
+ triggers:
7
+ - create issue
8
+ - transition
9
+ - comment
10
+ - list issues
11
+ - assign
12
+ - update description
13
+ - update issue
14
+ - project update
15
+ - Linear
16
+ - cloud
17
+ ---
18
+
19
+ # FlyDocs Cloud Mechanism
20
+
21
+ Issues managed in Linear. Reads config from `.flydocs/config.json` and API key from `.env`.
22
+
23
+ ## Script Catalog
24
+
25
+ All scripts: `python3 .claude/skills/flydocs-cloud/scripts/<script>`
26
+
27
+ ### Shared Contract Scripts
28
+
29
+ | Script | Usage | Output |
30
+ |--------|-------|--------|
31
+ | `create_issue.py` | `--title "..." --type feature [--description "..."] [--description-file PATH] [--priority 0-4] [--estimate 1-5] [--assignee STR] [--triage] \| stdin` | `{id, identifier, title, url}` |
32
+ | `transition.py` | `<ref> <STATUS> "<comment>"` | `{success, issue, previousStatus, newStatus}` |
33
+ | `comment.py` | `<ref> ["<comment>"] \| stdin` | `{success, commentId}` |
34
+ | `list_issues.py` | `[--status STATUS[,STATUS]] [--active] [--project ID] [--milestone ID] [--assignee STR] [--mine] [--limit N]` | `[{id, identifier, title, status, assignee, priority, dueDate, milestone, milestoneId, milestoneSortOrder, project, projectId}]` |
35
+ | `get_issue.py` | `<ref> [--fields basic\|full]` | `{id, identifier, title, description, status, assignee, priority, estimate, dueDate, milestone, milestoneId, project, projectId, comments[]}` |
36
+ | `assign.py` | `<ref> <assignee>` | `{success, issue, assignee}` |
37
+ | `update_description.py` | `<ref> --text "..." \| --file PATH \| stdin` | `{success, issue}` |
38
+
39
+ ### Extended Scripts (cloud-only)
40
+
41
+ | Script | Usage | Output |
42
+ |--------|-------|--------|
43
+ | `update_issue.py` | `<ref> [--title "..."] [--priority 0-4] [--estimate 1-5] [--assignee STR] [--state STATUS] [--description "..."] [--description-file PATH] [--comment "..."]` | `{success, issue, updated[]}` |
44
+ | `estimate.py` | `<ref> <1-5>` | `{success, issue, estimate}` |
45
+ | `priority.py` | `<ref> <0-4>` | `{success, issue, priority}` |
46
+ | `link.py` | `<ref> <related_ref> <type>` | `{success, type}` |
47
+ | `project_update.py` | `--health STATUS --body "..." [--body-file PATH]` | `{success, id}` |
48
+ | `list_projects.py` | `[--active] [--all]` | `[{id, name, state}]` — `--all` bypasses product scope |
49
+ | `create_project.py` | `--name "..." [--description "..."]` | `{id, name, url}` |
50
+ | `assign_cycle.py` | `<ref> [cycle_id]` | `{success, issue, cycle}` |
51
+ | `list_cycles.py` | `[--active]` | `[{id, name, number, startsAt, endsAt}]` |
52
+ | `list_milestones.py` | `[--all]` | `[{id, name, targetDate}]` |
53
+ | `create_milestone.py` | `--name "..." [--project ID] [--target-date DATE]` | `{id, name}` — defaults to first activeProject |
54
+ | `assign_milestone.py` | `<ref> <milestone_id>` | `{success, issue, milestone}` |
55
+
56
+ ### Script Notes
57
+
58
+ - **`list_issues.py` product scope**: Automatically scopes results using config cascade — `activeProjects` → `product.labelIds` → team-wide. Explicit `--project` overrides. All flags (`--active`, `--status`, `--mine`, `--assignee`) filter within the scoped results.
59
+ - **`list_issues.py --active`**: Returns all non-terminal issues (excludes Done, Archived, Canceled, Duplicate). Replaces `status_summary.py` — group results by status field instead.
60
+ - **`list_issues.py --milestone`**: Filter issues by project milestone ID. Get IDs from `list_milestones.py`.
61
+ - **`list_issues.py --status`**: Accepts comma-separated statuses: `--status READY,IMPLEMENTING,BLOCKED`
62
+ - **`get_issue.py --fields basic`**: Skips comment fetch for faster responses when comments aren't needed.
63
+ - **`update_issue.py`**: Bulk update — sets multiple fields in a single API call. Prefer over separate `estimate.py`/`priority.py`/`assign.py` calls when updating more than one field.
64
+ - **Shell-safe text input**: For descriptions, comments, or any text with special characters (apostrophes, quotes, parentheses), pipe via stdin with a single-quoted heredoc instead of `--text`:
65
+ ```bash
66
+ python3 update_description.py ENG-123 <<'EOF'
67
+ Description with 'apostrophes', (parens), and "quotes"
68
+ EOF
69
+ ```
70
+ Scripts supporting stdin: `update_description.py`, `comment.py`, `project_update.py`. For `update_issue.py` and `create_issue.py`, use `--description-file PATH` instead.
71
+
72
+ ### Status Values
73
+
74
+ `BACKLOG`, `READY`, `IMPLEMENTING`, `BLOCKED`, `REVIEW`, `TESTING`, `COMPLETE`, `ARCHIVED`, `CANCELED`, `DUPLICATE`
75
+
76
+ ### Issue Types
77
+
78
+ `feature`, `bug`, `chore`, `idea`
79
+
80
+ ### Link Types
81
+
82
+ `blocks`, `related`, `duplicate`
83
+
84
+ ### Issue Reference
85
+
86
+ `<ref>`: Provider identifier, e.g., `ENG-123`. Resolved via Linear search API.
87
+
88
+ ## Error Handling
89
+
90
+ Exit 0 = success (JSON on stdout). Exit 1 = error (message on stderr).
91
+ Network errors: exponential backoff, 3 retries, 2s base delay.
92
+
93
+ ## Configuration
94
+
95
+ Reads from `.flydocs/config.json`: tier, provider.teamId, statusMapping, issueLabels.
96
+ Reads `LINEAR_API_KEY` from environment or `.env` / `.env.local`.
@@ -0,0 +1,50 @@
1
+ ---
2
+ description: Connected issue management via Linear — cloud mechanism for FlyDocs
3
+ alwaysApply: true
4
+ ---
5
+
6
+ <!-- Condensed from SKILL.md — update both when changing patterns -->
7
+
8
+ # FlyDocs Cloud Mechanism
9
+
10
+ Issues managed in Linear. Reads config from `.flydocs/config.json` and API key from `.env`.
11
+
12
+ ## Shared Contract Scripts
13
+
14
+ All scripts: `python3 .claude/skills/flydocs-cloud/scripts/<script>`
15
+
16
+ | Script | Key Arguments |
17
+ |--------|---------------|
18
+ | `create_issue.py` | `--title "..." --type feature [--priority 0-4] [--estimate 1-5] [--assignee STR] [--triage]` |
19
+ | `transition.py` | `<ref> <STATUS> "<comment>"` |
20
+ | `comment.py` | `<ref> "<comment>"` |
21
+ | `list_issues.py` | `[--status STATUS[,STATUS]] [--active] [--mine] [--limit N]` |
22
+ | `get_issue.py` | `<ref> [--fields basic\|full]` |
23
+ | `assign.py` | `<ref> <assignee>` |
24
+ | `update_description.py` | `<ref> --text "..." \| --file PATH` |
25
+
26
+ ## Extended Scripts (cloud-only)
27
+
28
+ | Script | Key Arguments |
29
+ |--------|---------------|
30
+ | `update_issue.py` | `<ref> [--priority 0-4] [--estimate 1-5] [--assignee STR] [--state STATUS] [--comment "..."]` |
31
+ | `project_update.py` | `--health STATUS --body "..."` |
32
+ | `estimate.py` / `priority.py` | `<ref> <value>` |
33
+ | `link.py` | `<ref> <related_ref> <type>` |
34
+ | `list_projects.py` / `create_project.py` | Project management |
35
+ | `assign_cycle.py` / `list_cycles.py` | Cycle management |
36
+ | `assign_milestone.py` / `list_milestones.py` / `create_milestone.py` | Milestone management |
37
+
38
+ ## Status Values
39
+
40
+ `BACKLOG`, `READY`, `IMPLEMENTING`, `BLOCKED`, `REVIEW`, `TESTING`, `COMPLETE`, `ARCHIVED`, `CANCELED`, `DUPLICATE`
41
+
42
+ ## Error Handling
43
+
44
+ Exit 0 = success (JSON on stdout). Exit 1 = error (message on stderr).
45
+ Network errors: exponential backoff, 3 retries, 2s base delay.
46
+
47
+ ## Configuration
48
+
49
+ Reads from `.flydocs/config.json`: tier, provider.teamId, statusMapping, issueLabels.
50
+ Reads `LINEAR_API_KEY` from environment or `.env` / `.env.local`.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env python3
2
+ """Assign an issue to a person."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).parent))
8
+ from flydocs_api import get_client, output_json, fail
9
+
10
+ if len(sys.argv) < 3:
11
+ fail("Usage: assign.py <ref> <assignee>")
12
+
13
+ ref, assignee_query = sys.argv[1], sys.argv[2]
14
+ client = get_client()
15
+
16
+ issue_uuid = client.resolve_issue_id(ref)
17
+ if not issue_uuid:
18
+ fail(f"Issue not found: {ref}")
19
+
20
+ user_id, user_name = client.resolve_user_id(assignee_query)
21
+ if not user_id:
22
+ fail(f"User not found: {assignee_query}")
23
+
24
+ result = client.query(
25
+ """mutation($id: String!, $assigneeId: String!) {
26
+ issueUpdate(id: $id, input: { assigneeId: $assigneeId }) {
27
+ success
28
+ issue { identifier }
29
+ }
30
+ }""",
31
+ {"id": issue_uuid, "assigneeId": user_id},
32
+ )
33
+
34
+ if not result.get("data", {}).get("issueUpdate", {}).get("success"):
35
+ fail(f"Failed to assign: {result}")
36
+
37
+ issue = result["data"]["issueUpdate"]["issue"]
38
+ output_json({"success": True, "issue": issue["identifier"], "assignee": user_name})
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python3
2
+ """Assign an issue to a cycle (sprint)."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).parent))
8
+ from flydocs_api import get_client, output_json, fail
9
+
10
+ if len(sys.argv) < 2:
11
+ fail("Usage: assign_cycle.py <ref> [cycle_id]")
12
+
13
+ ref = sys.argv[1]
14
+ client = get_client()
15
+
16
+ issue_uuid = client.resolve_issue_id(ref)
17
+ if not issue_uuid:
18
+ fail(f"Issue not found: {ref}")
19
+
20
+ # Use specified cycle or active cycle
21
+ cycle_id = sys.argv[2] if len(sys.argv) > 2 else None
22
+ cycle_name = cycle_id or ""
23
+ if not cycle_id:
24
+ cycle = client.get_active_cycle()
25
+ if not cycle:
26
+ fail("No active cycle found")
27
+ cycle_id = cycle["id"]
28
+ cycle_name = cycle["name"]
29
+
30
+ result = client.query(
31
+ """mutation($id: String!, $cycleId: String!) {
32
+ issueUpdate(id: $id, input: { cycleId: $cycleId }) {
33
+ success
34
+ issue { identifier }
35
+ }
36
+ }""",
37
+ {"id": issue_uuid, "cycleId": cycle_id},
38
+ )
39
+
40
+ if not result.get("data", {}).get("issueUpdate", {}).get("success"):
41
+ fail(f"Failed to assign cycle: {result}")
42
+
43
+ issue = result["data"]["issueUpdate"]["issue"]
44
+ output_json({"success": True, "issue": issue["identifier"], "cycle": cycle_name})
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python3
2
+ """Assign an issue to a milestone."""
3
+
4
+ import argparse
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ sys.path.insert(0, str(Path(__file__).parent))
9
+ from flydocs_api import get_client, output_json, fail
10
+
11
+ parser = argparse.ArgumentParser(description="Assign issue to milestone")
12
+ parser.add_argument("ref", help="Issue reference (e.g., ENG-123)")
13
+ parser.add_argument("milestone_id", nargs="?", default=None,
14
+ help="Milestone UUID (positional)")
15
+ parser.add_argument("--milestone", dest="milestone_flag", default=None,
16
+ help="Milestone UUID (flag)")
17
+ args = parser.parse_args()
18
+
19
+ milestone_id = args.milestone_flag or args.milestone_id
20
+ if not milestone_id:
21
+ fail("Milestone ID required. Usage: assign_milestone.py <ref> <milestone_id> or --milestone <id>")
22
+
23
+ client = get_client()
24
+
25
+ issue_uuid = client.resolve_issue_id(args.ref)
26
+ if not issue_uuid:
27
+ fail(f"Issue not found: {args.ref}")
28
+
29
+ result = client.query(
30
+ """mutation($id: String!, $milestoneId: String!) {
31
+ issueUpdate(id: $id, input: { projectMilestoneId: $milestoneId }) {
32
+ success
33
+ issue { identifier }
34
+ }
35
+ }""",
36
+ {"id": issue_uuid, "milestoneId": milestone_id},
37
+ )
38
+
39
+ update = result.get("data", {}).get("issueUpdate", {})
40
+ if not update.get("success"):
41
+ fail(f"Failed to assign milestone: {result}")
42
+
43
+ issue = update.get("issue", {})
44
+ output_json({"success": True, "issue": issue.get("identifier", args.ref), "milestone": milestone_id})
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ """Add a comment to an issue."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).parent))
8
+ from flydocs_api import get_client, output_json, fail
9
+
10
+ if len(sys.argv) < 2:
11
+ fail("Usage: comment.py <ref> [<comment>] (or pipe via stdin)")
12
+
13
+ ref = sys.argv[1]
14
+ body = sys.argv[2] if len(sys.argv) > 2 else ""
15
+ if not body and not sys.stdin.isatty():
16
+ body = sys.stdin.read().strip()
17
+ if not body:
18
+ fail("Provide comment as argument or pipe via stdin")
19
+ client = get_client()
20
+
21
+ issue_uuid = client.resolve_issue_id(ref)
22
+ if not issue_uuid:
23
+ fail(f"Issue not found: {ref}")
24
+
25
+ result = client.query(
26
+ """mutation($id: String!, $body: String!) {
27
+ commentCreate(input: { issueId: $id, body: $body }) {
28
+ success
29
+ comment { id }
30
+ }
31
+ }""",
32
+ {"id": issue_uuid, "body": body},
33
+ )
34
+
35
+ data = result.get("data", {}).get("commentCreate", {})
36
+ if not data.get("success"):
37
+ fail(f"Failed to add comment: {result}")
38
+
39
+ output_json({"success": True, "commentId": data.get("comment", {}).get("id", "")})