@flydocs/cli 0.6.0-alpha.13 → 0.6.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +281 -256
- package/package.json +1 -1
- package/template/.claude/CLAUDE.md +62 -66
- package/template/.claude/agents/implementation-agent.md +1 -1
- package/template/.claude/agents/pm-agent.md +1 -1
- package/template/.claude/commands/activate.md +1 -1
- package/template/.claude/commands/attach.md +1 -1
- package/template/.claude/commands/block.md +2 -2
- package/template/.claude/commands/capture.md +1 -1
- package/template/.claude/commands/close.md +1 -1
- package/template/.claude/commands/flydocs-setup.md +261 -58
- package/template/.claude/commands/flydocs-upgrade.md +26 -27
- package/template/.claude/commands/implement.md +1 -1
- package/template/.claude/commands/new-project.md +1 -1
- package/template/.claude/commands/onboard.md +275 -0
- package/template/.claude/commands/project-update.md +1 -1
- package/template/.claude/commands/refine.md +1 -1
- package/template/.claude/commands/review.md +1 -1
- package/template/.claude/commands/start-session.md +1 -1
- package/template/.claude/commands/status.md +1 -1
- package/template/.claude/commands/validate.md +1 -1
- package/template/.claude/commands/wrap-session.md +1 -1
- package/template/.claude/hooks/auto-approve.py +132 -0
- package/template/.claude/hooks/post-pr-check.py +108 -0
- package/template/.claude/hooks/post-transition-check.py +94 -0
- package/template/{.flydocs → .claude}/hooks/prompt-submit.py +167 -17
- package/template/.claude/hooks/session-start.py +146 -0
- package/template/.claude/hooks/stop-gate.py +109 -0
- package/template/.claude/settings.json +41 -4
- package/template/.claude/skills/README.md +23 -25
- package/template/.claude/skills/flydocs-workflow/SKILL.md +121 -34
- package/template/.claude/skills/flydocs-workflow/cursor-rule.mdc +9 -8
- package/template/.claude/skills/flydocs-workflow/reference/golden-rules.md +28 -17
- package/template/.claude/skills/flydocs-workflow/reference/graph-schema.md +116 -0
- package/template/.claude/skills/flydocs-workflow/reference/pr-workflow.md +30 -15
- package/template/.claude/skills/flydocs-workflow/reference/priority-estimates.md +1 -1
- package/template/.claude/skills/flydocs-workflow/reference/service-descriptor-schema.md +251 -0
- package/template/.claude/skills/flydocs-workflow/reference/status-workflow.md +26 -26
- package/template/.claude/skills/flydocs-workflow/scripts/_local/__init__.py +0 -0
- package/template/.claude/skills/{flydocs-local/scripts/flydocs_api.py → flydocs-workflow/scripts/_local/file_store.py} +133 -46
- package/template/.claude/skills/flydocs-workflow/scripts/flydocs_api.py +693 -0
- package/template/{.flydocs → .claude/skills/flydocs-workflow}/scripts/generate_manifest.py +4 -4
- package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_build.py +132 -1
- package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_query.py +18 -5
- package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_session.py +1 -1
- package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_update.py +4 -4
- package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_utils.py +2 -1
- package/template/.claude/skills/flydocs-workflow/scripts/issues.py +489 -0
- package/template/.claude/skills/flydocs-workflow/scripts/projects.py +144 -0
- package/template/.claude/skills/flydocs-workflow/scripts/pull_services.py +128 -0
- package/template/.claude/skills/flydocs-workflow/scripts/push_service.py +132 -0
- package/template/.claude/skills/flydocs-workflow/scripts/session.py +54 -0
- package/template/.claude/skills/flydocs-workflow/scripts/workspace.py +860 -0
- package/template/.claude/skills/flydocs-workflow/session.md +16 -11
- package/template/.claude/skills/flydocs-workflow/stages/activate.md +13 -8
- package/template/.claude/skills/flydocs-workflow/stages/capture.md +4 -4
- package/template/.claude/skills/flydocs-workflow/stages/close.md +1 -1
- package/template/.claude/skills/flydocs-workflow/stages/implement.md +7 -7
- package/template/.claude/skills/flydocs-workflow/stages/refine.md +5 -5
- package/template/.claude/skills/flydocs-workflow/stages/review.md +2 -2
- package/template/.claude/skills/flydocs-workflow/stages/validate.md +3 -1
- package/template/.claude/skills/flydocs-workflow/templates/pr/default.md +33 -0
- package/template/.cursor/agents/implementation-agent.md +1 -1
- package/template/.cursor/agents/pm-agent.md +2 -2
- package/template/.cursor/hooks.json +10 -3
- package/template/.env.example +6 -6
- package/template/.flydocs/config.json +2 -1
- package/template/.flydocs/templates/README.md +13 -14
- package/template/.flydocs/templates/quick-capture.md +4 -8
- package/template/.flydocs/version +1 -1
- package/template/AGENTS.md +39 -32
- package/template/flydocs/README.md +1 -3
- package/template/flydocs/context/project.md +6 -3
- package/template/flydocs/design-system/README.md +3 -3
- package/template/manifest.json +17 -19
- package/template/.claude/skills/flydocs-cloud/SKILL.md +0 -138
- package/template/.claude/skills/flydocs-cloud/cursor-rule.mdc +0 -50
- package/template/.claude/skills/flydocs-cloud/scripts/assign.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/assign_cycle.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/assign_milestone.py +0 -22
- package/template/.claude/skills/flydocs-cloud/scripts/comment.py +0 -29
- package/template/.claude/skills/flydocs-cloud/scripts/create_issue.py +0 -83
- package/template/.claude/skills/flydocs-cloud/scripts/create_milestone.py +0 -35
- package/template/.claude/skills/flydocs-cloud/scripts/create_project.py +0 -33
- package/template/.claude/skills/flydocs-cloud/scripts/create_team.py +0 -39
- package/template/.claude/skills/flydocs-cloud/scripts/delete_milestone.py +0 -21
- package/template/.claude/skills/flydocs-cloud/scripts/estimate.py +0 -33
- package/template/.claude/skills/flydocs-cloud/scripts/flydocs_api.py +0 -241
- package/template/.claude/skills/flydocs-cloud/scripts/generate_config.py +0 -125
- package/template/.claude/skills/flydocs-cloud/scripts/get_estimate_scale.py +0 -23
- package/template/.claude/skills/flydocs-cloud/scripts/get_issue.py +0 -24
- package/template/.claude/skills/flydocs-cloud/scripts/get_me.py +0 -103
- package/template/.claude/skills/flydocs-cloud/scripts/link.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/list_cycles.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/list_issues.py +0 -44
- package/template/.claude/skills/flydocs-cloud/scripts/list_labels.py +0 -19
- package/template/.claude/skills/flydocs-cloud/scripts/list_milestones.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/list_projects.py +0 -31
- package/template/.claude/skills/flydocs-cloud/scripts/list_providers.py +0 -19
- package/template/.claude/skills/flydocs-cloud/scripts/list_statuses.py +0 -19
- package/template/.claude/skills/flydocs-cloud/scripts/list_teams.py +0 -19
- package/template/.claude/skills/flydocs-cloud/scripts/priority.py +0 -29
- package/template/.claude/skills/flydocs-cloud/scripts/project_update.py +0 -45
- package/template/.claude/skills/flydocs-cloud/scripts/refresh_labels.py +0 -87
- package/template/.claude/skills/flydocs-cloud/scripts/set_identity.py +0 -54
- package/template/.claude/skills/flydocs-cloud/scripts/set_labels.py +0 -54
- package/template/.claude/skills/flydocs-cloud/scripts/set_preferences.py +0 -49
- package/template/.claude/skills/flydocs-cloud/scripts/set_provider.py +0 -31
- package/template/.claude/skills/flydocs-cloud/scripts/set_status_mapping.py +0 -57
- package/template/.claude/skills/flydocs-cloud/scripts/set_team.py +0 -28
- package/template/.claude/skills/flydocs-cloud/scripts/transition.py +0 -26
- package/template/.claude/skills/flydocs-cloud/scripts/update_description.py +0 -36
- package/template/.claude/skills/flydocs-cloud/scripts/update_issue.py +0 -100
- package/template/.claude/skills/flydocs-cloud/scripts/update_milestone.py +0 -42
- package/template/.claude/skills/flydocs-cloud/scripts/validate_setup.py +0 -120
- package/template/.claude/skills/flydocs-context-graph/SKILL.md +0 -94
- package/template/.claude/skills/flydocs-context-graph/schema.md +0 -78
- package/template/.claude/skills/flydocs-context-graph/scripts/graph_context.py +0 -338
- package/template/.claude/skills/flydocs-context7/SKILL.md +0 -105
- package/template/.claude/skills/flydocs-context7/cursor-rule.mdc +0 -49
- package/template/.claude/skills/flydocs-context7/scripts/context7.py +0 -293
- package/template/.claude/skills/flydocs-estimates/SKILL.md +0 -384
- package/template/.claude/skills/flydocs-figma/SKILL.md +0 -377
- package/template/.claude/skills/flydocs-figma/references/PROMPTING.md +0 -108
- package/template/.claude/skills/flydocs-figma/references/TROUBLESHOOTING.md +0 -112
- package/template/.claude/skills/flydocs-local/SKILL.md +0 -103
- package/template/.claude/skills/flydocs-local/cursor-rule.mdc +0 -43
- package/template/.claude/skills/flydocs-local/scripts/assign.py +0 -29
- package/template/.claude/skills/flydocs-local/scripts/comment.py +0 -27
- package/template/.claude/skills/flydocs-local/scripts/create_issue.py +0 -44
- package/template/.claude/skills/flydocs-local/scripts/estimate.py +0 -37
- package/template/.claude/skills/flydocs-local/scripts/get_issue.py +0 -20
- package/template/.claude/skills/flydocs-local/scripts/link.py +0 -41
- package/template/.claude/skills/flydocs-local/scripts/list_issues.py +0 -50
- package/template/.claude/skills/flydocs-local/scripts/priority.py +0 -37
- package/template/.claude/skills/flydocs-local/scripts/project_update.py +0 -67
- package/template/.claude/skills/flydocs-local/scripts/status_summary.py +0 -16
- package/template/.claude/skills/flydocs-local/scripts/transition.py +0 -24
- package/template/.claude/skills/flydocs-local/scripts/update_description.py +0 -35
- package/template/.claude/skills/flydocs-local/scripts/update_issue.py +0 -84
- package/template/.flydocs/hooks/auto-approve.py +0 -71
- package/template/.flydocs/scripts/skill_manager.py +0 -541
- package/template/.flydocs/templates/bug.md +0 -166
- package/template/.flydocs/templates/chore.md +0 -110
- package/template/.flydocs/templates/feature.md +0 -173
- package/template/.flydocs/templates/idea.md +0 -122
- /package/template/{.flydocs → .claude}/hooks/post-edit.py +0 -0
- /package/template/.claude/skills/{flydocs-estimates/references → flydocs-workflow/reference}/provider-costs.md +0 -0
- /package/template/.claude/skills/flydocs-workflow/templates/{bug.md → issues/bug.md} +0 -0
- /package/template/.claude/skills/flydocs-workflow/templates/{chore.md → issues/chore.md} +0 -0
- /package/template/.claude/skills/flydocs-workflow/templates/{feature.md → issues/feature.md} +0 -0
- /package/template/.claude/skills/flydocs-workflow/templates/{idea.md → issues/idea.md} +0 -0
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
## What This Is
|
|
4
4
|
|
|
5
5
|
<!-- Fill during setup: 2-3 sentences describing the project -->
|
|
6
|
+
|
|
6
7
|
[Project name] — [what it does and who it's for].
|
|
7
8
|
|
|
8
9
|
## Stack
|
|
9
10
|
|
|
10
11
|
<!-- Fill during setup: auto-detected or manual -->
|
|
12
|
+
|
|
11
13
|
- **Framework**: [e.g., Next.js 14 / React 18]
|
|
12
14
|
- **Language**: [e.g., TypeScript 5.x]
|
|
13
15
|
- **Styling**: [e.g., Tailwind CSS]
|
|
@@ -20,8 +22,8 @@
|
|
|
20
22
|
Code standards are defined by installed community skills. Skills are installed
|
|
21
23
|
based on detected stack during setup or manually via `npx flydocs skills add`.
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
Installed community skills provide domain-specific patterns. List them with
|
|
26
|
+
`npx flydocs skills list`.
|
|
25
27
|
|
|
26
28
|
### Project-Specific Standards
|
|
27
29
|
|
|
@@ -36,6 +38,7 @@ Project notes: `flydocs/knowledge/notes/`
|
|
|
36
38
|
## Active Priorities
|
|
37
39
|
|
|
38
40
|
<!-- Updated by session-wrap or manually -->
|
|
41
|
+
|
|
39
42
|
1. [Current priority 1]
|
|
40
43
|
2. [Current priority 2]
|
|
41
44
|
3. [Current priority 3]
|
|
@@ -48,4 +51,4 @@ Project notes: `flydocs/knowledge/notes/`
|
|
|
48
51
|
|
|
49
52
|
---
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
_Last Updated: YYYY-MM-DD_
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
8
8
|
|
|
9
|
-
When using the
|
|
9
|
+
When using the workflow skill's Figma capabilities to extract designs, the AI needs to know:
|
|
10
10
|
|
|
11
11
|
1. **How Figma tokens map to code** (colors, spacing, typography)
|
|
12
12
|
2. **What component patterns exist** (and how to match them)
|
|
@@ -83,9 +83,9 @@ flydocs/design-system/
|
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
|
-
## Integration with
|
|
86
|
+
## Integration with Figma Workflow
|
|
87
87
|
|
|
88
|
-
The `flydocs-
|
|
88
|
+
The `flydocs-workflow` skill's Figma capabilities reference this directory:
|
|
89
89
|
|
|
90
90
|
1. **Before extraction** - Loads token-mapping.md for translation rules
|
|
91
91
|
2. **During extraction** - Matches Figma elements to documented patterns
|
package/template/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.6.0-alpha.
|
|
2
|
+
"version": "0.6.0-alpha.20",
|
|
3
3
|
"description": "FlyDocs Core - Manifest of all managed files",
|
|
4
4
|
"repository": "github.com/plastrlab/flydocs-core",
|
|
5
5
|
|
|
@@ -9,17 +9,10 @@
|
|
|
9
9
|
"owned_directories": {
|
|
10
10
|
"description": "Entire directories owned by FlyDocs - contents replaced on update",
|
|
11
11
|
"paths": [
|
|
12
|
-
".flydocs/hooks",
|
|
13
12
|
".flydocs/templates",
|
|
13
|
+
".claude/hooks",
|
|
14
14
|
".claude/agents",
|
|
15
15
|
".claude/skills/flydocs-workflow",
|
|
16
|
-
".claude/skills/flydocs-cloud",
|
|
17
|
-
".claude/skills/flydocs-local",
|
|
18
|
-
".claude/skills/flydocs-figma",
|
|
19
|
-
".claude/skills/flydocs-estimates",
|
|
20
|
-
".claude/skills/flydocs-context-graph",
|
|
21
|
-
".claude/skills/flydocs-context7",
|
|
22
|
-
".flydocs/scripts",
|
|
23
16
|
".cursor/agents"
|
|
24
17
|
]
|
|
25
18
|
},
|
|
@@ -46,6 +39,7 @@
|
|
|
46
39
|
".claude/commands/status.md",
|
|
47
40
|
".claude/commands/validate.md",
|
|
48
41
|
".claude/commands/knowledge.md",
|
|
42
|
+
".claude/commands/onboard.md",
|
|
49
43
|
".claude/commands/wrap-session.md",
|
|
50
44
|
".claude/skills/README.md",
|
|
51
45
|
".cursor/hooks.json",
|
|
@@ -81,6 +75,7 @@
|
|
|
81
75
|
"statusMapping",
|
|
82
76
|
"detectedStack",
|
|
83
77
|
"skills",
|
|
78
|
+
"topology",
|
|
84
79
|
"designSystem",
|
|
85
80
|
"aiLabor"
|
|
86
81
|
]
|
|
@@ -131,6 +126,7 @@
|
|
|
131
126
|
"implement.md",
|
|
132
127
|
"knowledge.md",
|
|
133
128
|
"new-project.md",
|
|
129
|
+
"onboard.md",
|
|
134
130
|
"project-update.md",
|
|
135
131
|
"refine.md",
|
|
136
132
|
"review.md",
|
|
@@ -139,6 +135,15 @@
|
|
|
139
135
|
"validate.md",
|
|
140
136
|
"wrap-session.md"
|
|
141
137
|
],
|
|
138
|
+
"hooks": [
|
|
139
|
+
"auto-approve.py",
|
|
140
|
+
"post-edit.py",
|
|
141
|
+
"post-pr-check.py",
|
|
142
|
+
"post-transition-check.py",
|
|
143
|
+
"prompt-submit.py",
|
|
144
|
+
"session-start.py",
|
|
145
|
+
"stop-gate.py"
|
|
146
|
+
],
|
|
142
147
|
"skills": {
|
|
143
148
|
"root": ["README.md"],
|
|
144
149
|
"flydocs-workflow": [
|
|
@@ -147,14 +152,9 @@
|
|
|
147
152
|
"cursor-rule.mdc",
|
|
148
153
|
"stages/",
|
|
149
154
|
"templates/",
|
|
150
|
-
"reference/"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"flydocs-local": ["SKILL.md", "cursor-rule.mdc", "scripts/"],
|
|
154
|
-
"flydocs-figma": ["SKILL.md", "references/"],
|
|
155
|
-
"flydocs-estimates": ["SKILL.md", "references/"],
|
|
156
|
-
"flydocs-context-graph": ["SKILL.md", "schema.md", "scripts/"],
|
|
157
|
-
"flydocs-context7": ["SKILL.md", "cursor-rule.mdc", "scripts/"]
|
|
155
|
+
"reference/",
|
|
156
|
+
"scripts/"
|
|
157
|
+
]
|
|
158
158
|
}
|
|
159
159
|
},
|
|
160
160
|
".cursor": {
|
|
@@ -168,8 +168,6 @@
|
|
|
168
168
|
},
|
|
169
169
|
".flydocs": {
|
|
170
170
|
"root": ["config.json", "version", "CHANGELOG.md"],
|
|
171
|
-
"scripts": ["generate_manifest.py", "skill_manager.py"],
|
|
172
|
-
"hooks": ["auto-approve.py", "post-edit.py", "prompt-submit.py"],
|
|
173
171
|
"templates": ["bug.md", "chore.md", "feature.md", "idea.md"]
|
|
174
172
|
},
|
|
175
173
|
"flydocs": {
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: flydocs-cloud
|
|
3
|
-
description: |
|
|
4
|
-
Connected issue management via FlyDocs Relay API.
|
|
5
|
-
Implements the FlyDocs mechanism contract with extended cloud operations.
|
|
6
|
-
All provider translation (Linear, Jira) happens server-side.
|
|
7
|
-
triggers:
|
|
8
|
-
- create issue
|
|
9
|
-
- transition
|
|
10
|
-
- comment
|
|
11
|
-
- list issues
|
|
12
|
-
- assign
|
|
13
|
-
- update description
|
|
14
|
-
- update issue
|
|
15
|
-
- project update
|
|
16
|
-
- cloud
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
# FlyDocs Cloud Mechanism
|
|
20
|
-
|
|
21
|
-
Issues managed via the FlyDocs Relay API. The relay handles provider translation server-side — scripts are thin REST wrappers.
|
|
22
|
-
|
|
23
|
-
Reads config from `.flydocs/config.json` and API key (`FLYDOCS_API_KEY`) from `.env`.
|
|
24
|
-
|
|
25
|
-
## Script Catalog
|
|
26
|
-
|
|
27
|
-
All scripts: `python3 .claude/skills/flydocs-cloud/scripts/<script>`
|
|
28
|
-
|
|
29
|
-
### Shared Contract Scripts
|
|
30
|
-
|
|
31
|
-
| Script | Usage | Output |
|
|
32
|
-
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
-
| `create_issue.py` | `--title "..." --type feature [--description "..."] [--description-file PATH] [--priority N] [--estimate N] [--assignee STR] [--project ID] [--labels "a,b"] [--milestone ID_OR_NAME] [--triage] \| stdin` | `{id, identifier, title, url}` |
|
|
34
|
-
| `transition.py` | `<ref> <STATUS> "<comment>"` | `{success, issue, previousStatus, newStatus}` |
|
|
35
|
-
| `comment.py` | `<ref> ["<comment>"] \| stdin` | `{success, commentId}` |
|
|
36
|
-
| `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}]` |
|
|
37
|
-
| `get_issue.py` | `<ref> [--fields basic\|full]` | `{id, identifier, title, description, status, assignee, priority, estimate, dueDate, milestone, milestoneId, project, projectId, comments[]}` |
|
|
38
|
-
| `assign.py` | `<ref> <assignee> \| --unassign` | `{success, issue, assignee}` |
|
|
39
|
-
| `update_description.py` | `<ref> --text "..." \| --file PATH \| stdin` | `{success, issue}` |
|
|
40
|
-
|
|
41
|
-
### Extended Scripts
|
|
42
|
-
|
|
43
|
-
| Script | Usage | Output |
|
|
44
|
-
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
45
|
-
| `update_issue.py` | `<ref> [--title "..."] [--priority N] [--estimate N] [--assignee STR] [--state STATUS] [--description "..."] [--description-file PATH] [--labels "a,b"] [--milestone ID_OR_NAME] [--comment "..."]` | `{success, issue, updated[]}` |
|
|
46
|
-
| `estimate.py` | `<ref> <points>` | `{success, issue, estimate}` — relay validates against provider scale |
|
|
47
|
-
| `priority.py` | `<ref> <0-4>` | `{success, issue, priority}` |
|
|
48
|
-
| `link.py` | `<ref> <related_ref> <type>` | `{success, type}` |
|
|
49
|
-
| `project_update.py` | `--health STATUS --body "..." [--body-file PATH]` | `{success, id}` |
|
|
50
|
-
| `list_projects.py` | `[--active] [--all]` | `[{id, name, state}]` — `--all` bypasses product scope |
|
|
51
|
-
| `create_project.py` | `--name "..." [--description "..."]` | `{id, name, url}` |
|
|
52
|
-
| `assign_cycle.py` | `<ref> [cycle_id]` | `{success, issue, cycle}` |
|
|
53
|
-
| `list_cycles.py` | `[--active]` | `[{id, name, number, startsAt, endsAt}]` |
|
|
54
|
-
| `list_milestones.py` | `[--all]` | `[{id, name, targetDate}]` |
|
|
55
|
-
| `create_milestone.py` | `--name "..." [--project ID] [--target-date DATE]` | `{id, name}` |
|
|
56
|
-
| `update_milestone.py` | `<milestone_id> [--name "..."] [--target-date DATE] [--description "..."]` | `{success, id, name}` |
|
|
57
|
-
| `delete_milestone.py` | `<milestone_id>` | `{success, id}` |
|
|
58
|
-
| `assign_milestone.py` | `<ref> <milestone_id>` | `{success, issue, milestone}` |
|
|
59
|
-
|
|
60
|
-
### Workspace Scripts
|
|
61
|
-
|
|
62
|
-
| Script | Usage | Output |
|
|
63
|
-
| ----------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
64
|
-
| `list_providers.py` | (no args) | `[{type, name, connected}]` |
|
|
65
|
-
| `set_provider.py` | `<provider_type>` (`linear` or `jira`) | `{success}` — updates relay routing (no local config write) |
|
|
66
|
-
| `list_teams.py` | (no args) | `[{id, name, key}]` — returns Linear teams or Jira projects (relay normalizes) |
|
|
67
|
-
| `create_team.py` | `--name "..." [--key KEY] [--description "..."] [--parent <team_id>]` | `{id, name, key}` — `--parent` is Linear-only (sub-teams) |
|
|
68
|
-
| `set_team.py` | `<team_id>` | `{success}` — updates relay preference (no local config write); for Jira, sets the active Jira project |
|
|
69
|
-
| `list_labels.py` | (no args) | `[{id, name, color}]` — requires team to be set first |
|
|
70
|
-
| `set_labels.py` | `--defaults '["a"]' --type-map '{"feature":["F"],...}' \| stdin` | `{success, validated, defaults, typeMap}` — stores label config on relay |
|
|
71
|
-
| `list_statuses.py` | (no args) | `{states, currentMapping, flydocsStatuses}` — provider workflow states and current mapping |
|
|
72
|
-
| `set_status_mapping.py` | `--auto \| --mapping '{"BACKLOG":"Backlog",...}' \| stdin` | `{success, mapping, matched, total}` — stores status mapping on relay |
|
|
73
|
-
| `set_identity.py` | `<provider> <provider-user-id>` | `{success, provider, providerId, meJson}` — binds provider user ID for `--mine` resolution; writes `.flydocs/me.json` |
|
|
74
|
-
| `set_preferences.py` | `[--workspace ID] [--assignee self\|ID] [--display JSON]` | `{success, preferences}` — no flags = GET current; with flags = POST update |
|
|
75
|
-
| `get_estimate_scale.py` | (no args) | `{scale, type}` — provider's valid estimate values (fixed or freeform) |
|
|
76
|
-
| `refresh_labels.py` | `[--fix]` | `{valid, stale, details}` — validates config label IDs against relay; `--fix` updates stale IDs |
|
|
77
|
-
| `generate_config.py` | `[--dry-run]` | `{success, configVersion, valid, missing[], warnings[]}` — pulls server config, merges with local, writes config.json |
|
|
78
|
-
| `get_me.py` | (no args) | `{success, displayName, email, provider, meJson}` — fetches user identity, writes `.flydocs/me.json` (no workspace) |
|
|
79
|
-
| `validate_setup.py` | (no args) | `{valid, checks, passed[], missing[], warnings[]}` — reads relay validation, caches result, sets setupComplete |
|
|
80
|
-
|
|
81
|
-
### Script Notes
|
|
82
|
-
|
|
83
|
-
- **How it works**: Scripts call the FlyDocs Relay REST API, which translates to the provider (Linear, Jira) server-side. Same interface and output as before — the transport changed from direct GraphQL to managed REST. For Jira, the relay handles Markdown-to-ADF (Atlassian Document Format) conversion automatically.
|
|
84
|
-
- **Config cascade**: Setup scripts (`set_provider`, `set_team`, `set_labels`, `set_status_mapping`) only POST to the relay — they do not write local config. After all setup steps, run `generate_config.py` to pull the canonical server config and merge with local-only fields. This eliminates ghost fields and ensures config.json stays in sync with the relay.
|
|
85
|
-
- **`list_issues.py --active`**: Returns all non-terminal issues (excludes Done, Archived, Canceled, Duplicate).
|
|
86
|
-
- **`list_issues.py --status`**: Accepts comma-separated statuses: `--status READY,IMPLEMENTING,BLOCKED`
|
|
87
|
-
- **`get_issue.py --fields basic`**: Skips comment fetch for faster responses.
|
|
88
|
-
- **`update_issue.py`**: Bulk update — sets multiple fields in a single API call. Prefer over separate scripts when updating more than one field.
|
|
89
|
-
- **Estimate validation**: The relay validates estimates server-side against the provider's scale. Use `get_estimate_scale.py` to discover valid values before setting. Linear uses a fixed scale `[0, 1, 2, 3, 5, 8, 13, 21]`; Jira accepts freeform values.
|
|
90
|
-
- **Label staleness**: Label IDs are team-scoped and can go stale when switching teams or projects. Use `refresh_labels.py` to validate config label IDs, and `refresh_labels.py --fix` to auto-update stale ones.
|
|
91
|
-
- **Shell-safe text input**: For text with special characters, pipe via stdin with a single-quoted heredoc:
|
|
92
|
-
```bash
|
|
93
|
-
python3 update_description.py ENG-123 <<'EOF'
|
|
94
|
-
Description with 'apostrophes', (parens), and "quotes"
|
|
95
|
-
EOF
|
|
96
|
-
```
|
|
97
|
-
Scripts supporting stdin: `update_description.py`, `comment.py`, `project_update.py`. For `update_issue.py` and `create_issue.py`, use `--description-file PATH` instead.
|
|
98
|
-
|
|
99
|
-
### Status Values
|
|
100
|
-
|
|
101
|
-
`BACKLOG`, `READY`, `IMPLEMENTING`, `BLOCKED`, `REVIEW`, `TESTING`, `COMPLETE`, `ARCHIVED`, `CANCELED`, `DUPLICATE`
|
|
102
|
-
|
|
103
|
-
### Issue Types
|
|
104
|
-
|
|
105
|
-
`feature`, `bug`, `chore`, `idea`
|
|
106
|
-
|
|
107
|
-
### Link Types
|
|
108
|
-
|
|
109
|
-
`blocks`, `related`, `duplicate`
|
|
110
|
-
|
|
111
|
-
### Issue Reference
|
|
112
|
-
|
|
113
|
-
`<ref>`: Provider identifier, e.g., `ENG-123`. Resolved server-side by the relay.
|
|
114
|
-
|
|
115
|
-
## Error Handling
|
|
116
|
-
|
|
117
|
-
Exit 0 = success (JSON on stdout). Exit 1 = error (message on stderr).
|
|
118
|
-
Network errors: exponential backoff, 3 retries, 2s base delay.
|
|
119
|
-
Relay errors include `code` and optional `provider_error` for debugging.
|
|
120
|
-
|
|
121
|
-
## Configuration
|
|
122
|
-
|
|
123
|
-
Reads from `.flydocs/config.json`: tier, workspaceId, relay URL override.
|
|
124
|
-
Reads `FLYDOCS_API_KEY` from environment or `.env` / `.env.local`.
|
|
125
|
-
|
|
126
|
-
Optional: `FLYDOCS_RELAY_URL` env var or `relay.url` in config to override the base URL (e.g., for local development).
|
|
127
|
-
|
|
128
|
-
### Header Contract
|
|
129
|
-
|
|
130
|
-
Every relay request includes:
|
|
131
|
-
|
|
132
|
-
| Header | Required | Source |
|
|
133
|
-
| --------------- | -------- | --------------------------------------------------- |
|
|
134
|
-
| `Authorization` | Yes | `Bearer fdk_...` from `FLYDOCS_API_KEY` |
|
|
135
|
-
| `X-Workspace` | Yes\* | `workspaceId` from `.flydocs/config.json` |
|
|
136
|
-
| `X-Repo` | No | Git remote slug (auto-detected, e.g., `owner/repo`) |
|
|
137
|
-
|
|
138
|
-
\*Required for all endpoints except `POST /auth/validate`.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Connected issue management via FlyDocs Relay API — 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 via FlyDocs Relay API. Reads config from `.flydocs/config.json` and API key (`FLYDOCS_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
|
|
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, relay URL override.
|
|
50
|
-
Reads `FLYDOCS_API_KEY` from environment or `.env` / `.env.local`.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Assign or unassign an issue via the FlyDocs Relay API."""
|
|
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.py <ref> <assignee> | assign.py <ref> --unassign")
|
|
12
|
-
|
|
13
|
-
ref = sys.argv[1]
|
|
14
|
-
unassign = "--unassign" in sys.argv
|
|
15
|
-
|
|
16
|
-
if not unassign and len(sys.argv) < 3:
|
|
17
|
-
fail("Usage: assign.py <ref> <assignee> | assign.py <ref> --unassign")
|
|
18
|
-
|
|
19
|
-
assignee = None if unassign else sys.argv[2]
|
|
20
|
-
client = get_client()
|
|
21
|
-
|
|
22
|
-
result = client.post(f"/issues/{ref}/assign", {"assignee": assignee})
|
|
23
|
-
|
|
24
|
-
output_json({
|
|
25
|
-
"success": result.get("success", True),
|
|
26
|
-
"issue": result.get("issue", ref),
|
|
27
|
-
"assignee": result.get("assignee", assignee),
|
|
28
|
-
})
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Assign a cycle to an issue via the FlyDocs Relay API."""
|
|
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
|
-
cycle_id = sys.argv[2] if len(sys.argv) >= 3 else None
|
|
15
|
-
|
|
16
|
-
client = get_client()
|
|
17
|
-
|
|
18
|
-
body: dict = {}
|
|
19
|
-
if cycle_id:
|
|
20
|
-
body["cycleId"] = cycle_id
|
|
21
|
-
|
|
22
|
-
result = client.put(f"/issues/{ref}/cycle", body)
|
|
23
|
-
|
|
24
|
-
output_json({
|
|
25
|
-
"success": result.get("success", True),
|
|
26
|
-
"issue": result.get("issue", ref),
|
|
27
|
-
"cycle": result.get("cycle", ""),
|
|
28
|
-
})
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Assign a milestone to an issue via the FlyDocs Relay API."""
|
|
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_milestone.py <ref> <milestone_id>")
|
|
12
|
-
|
|
13
|
-
ref, milestone_id = sys.argv[1], sys.argv[2]
|
|
14
|
-
client = get_client()
|
|
15
|
-
|
|
16
|
-
result = client.put(f"/issues/{ref}/milestone", {"milestoneId": milestone_id})
|
|
17
|
-
|
|
18
|
-
output_json({
|
|
19
|
-
"success": result.get("success", True),
|
|
20
|
-
"issue": result.get("issue", ref),
|
|
21
|
-
"milestone": result.get("milestone", ""),
|
|
22
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Add a comment to an issue via the FlyDocs Relay API."""
|
|
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] | stdin")
|
|
12
|
-
|
|
13
|
-
ref = sys.argv[1]
|
|
14
|
-
|
|
15
|
-
# Comment from arg > stdin
|
|
16
|
-
if len(sys.argv) >= 3:
|
|
17
|
-
body = sys.argv[2]
|
|
18
|
-
elif not sys.stdin.isatty():
|
|
19
|
-
body = sys.stdin.read().strip()
|
|
20
|
-
else:
|
|
21
|
-
fail("Provide comment as argument or via stdin")
|
|
22
|
-
|
|
23
|
-
client = get_client()
|
|
24
|
-
result = client.post(f"/issues/{ref}/comment", {"body": body})
|
|
25
|
-
|
|
26
|
-
output_json({
|
|
27
|
-
"success": result.get("success", True),
|
|
28
|
-
"commentId": result.get("commentId", ""),
|
|
29
|
-
})
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Create a new issue via the FlyDocs Relay API."""
|
|
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
|
-
|
|
12
|
-
def main():
|
|
13
|
-
parser = argparse.ArgumentParser(description="Create issue")
|
|
14
|
-
parser.add_argument("--title", required=True)
|
|
15
|
-
parser.add_argument("--type", required=True, choices=["feature", "bug", "chore", "idea"], dest="issue_type")
|
|
16
|
-
parser.add_argument("--description", default="")
|
|
17
|
-
parser.add_argument("--description-file", default="", dest="description_file")
|
|
18
|
-
parser.add_argument("--priority", type=int, default=3, help="Priority (0-4, relay translates per provider)")
|
|
19
|
-
parser.add_argument("--estimate", type=int, default=0, help="Estimate points (relay translates per provider)")
|
|
20
|
-
parser.add_argument("--assignee", default=None)
|
|
21
|
-
parser.add_argument("--project", default=None, help="Project ID")
|
|
22
|
-
parser.add_argument("--labels", default=None, help="Comma-separated ad-hoc label names")
|
|
23
|
-
parser.add_argument("--milestone", default=None, help="Milestone ID or name (resolved by name lookup)")
|
|
24
|
-
parser.add_argument("--triage", action="store_true")
|
|
25
|
-
args = parser.parse_args()
|
|
26
|
-
|
|
27
|
-
# Resolve description: --description-file > stdin > --description
|
|
28
|
-
description = args.description
|
|
29
|
-
if args.description_file:
|
|
30
|
-
try:
|
|
31
|
-
description = Path(args.description_file).read_text()
|
|
32
|
-
except FileNotFoundError:
|
|
33
|
-
fail(f"File not found: {args.description_file}")
|
|
34
|
-
elif not description and not sys.stdin.isatty():
|
|
35
|
-
description = sys.stdin.read().strip()
|
|
36
|
-
|
|
37
|
-
body: dict = {
|
|
38
|
-
"title": args.title,
|
|
39
|
-
"type": args.issue_type,
|
|
40
|
-
"priority": args.priority,
|
|
41
|
-
}
|
|
42
|
-
if description:
|
|
43
|
-
body["description"] = description
|
|
44
|
-
if args.estimate:
|
|
45
|
-
body["estimate"] = args.estimate
|
|
46
|
-
if args.assignee:
|
|
47
|
-
body["assignee"] = args.assignee
|
|
48
|
-
if args.project:
|
|
49
|
-
body["projectId"] = args.project
|
|
50
|
-
if args.labels:
|
|
51
|
-
body["labels"] = [l.strip() for l in args.labels.split(",") if l.strip()]
|
|
52
|
-
if args.triage:
|
|
53
|
-
body["triage"] = True
|
|
54
|
-
|
|
55
|
-
client = get_client()
|
|
56
|
-
|
|
57
|
-
if args.milestone:
|
|
58
|
-
milestone_id = args.milestone
|
|
59
|
-
# If it doesn't look like a UUID, resolve by name
|
|
60
|
-
if len(milestone_id) != 36 or "-" not in milestone_id:
|
|
61
|
-
milestones = client.get("/milestones")
|
|
62
|
-
match = None
|
|
63
|
-
for m in milestones:
|
|
64
|
-
if m["name"].lower() == milestone_id.lower():
|
|
65
|
-
match = m
|
|
66
|
-
break
|
|
67
|
-
if not match:
|
|
68
|
-
fail(f"Milestone not found: {milestone_id}")
|
|
69
|
-
milestone_id = match["id"]
|
|
70
|
-
body["milestoneId"] = milestone_id
|
|
71
|
-
|
|
72
|
-
result = client.post("/issues", body)
|
|
73
|
-
|
|
74
|
-
output_json({
|
|
75
|
-
"id": result["id"],
|
|
76
|
-
"identifier": result["identifier"],
|
|
77
|
-
"title": result["title"],
|
|
78
|
-
"url": result["url"],
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if __name__ == "__main__":
|
|
83
|
-
main()
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Create a milestone via the FlyDocs Relay API."""
|
|
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
|
-
|
|
12
|
-
def main():
|
|
13
|
-
parser = argparse.ArgumentParser(description="Create milestone")
|
|
14
|
-
parser.add_argument("--name", required=True)
|
|
15
|
-
parser.add_argument("--project", default=None, help="Project ID")
|
|
16
|
-
parser.add_argument("--target-date", default=None, dest="target_date")
|
|
17
|
-
args = parser.parse_args()
|
|
18
|
-
|
|
19
|
-
body: dict = {"name": args.name}
|
|
20
|
-
if args.project:
|
|
21
|
-
body["projectId"] = args.project
|
|
22
|
-
if args.target_date:
|
|
23
|
-
body["targetDate"] = args.target_date
|
|
24
|
-
|
|
25
|
-
client = get_client()
|
|
26
|
-
result = client.post("/milestones", body)
|
|
27
|
-
|
|
28
|
-
output_json({
|
|
29
|
-
"id": result["id"],
|
|
30
|
-
"name": result["name"],
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if __name__ == "__main__":
|
|
35
|
-
main()
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Create a project via the FlyDocs Relay API."""
|
|
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
|
-
|
|
12
|
-
def main():
|
|
13
|
-
parser = argparse.ArgumentParser(description="Create project")
|
|
14
|
-
parser.add_argument("--name", required=True)
|
|
15
|
-
parser.add_argument("--description", default=None)
|
|
16
|
-
args = parser.parse_args()
|
|
17
|
-
|
|
18
|
-
body: dict = {"name": args.name}
|
|
19
|
-
if args.description:
|
|
20
|
-
body["description"] = args.description
|
|
21
|
-
|
|
22
|
-
client = get_client()
|
|
23
|
-
result = client.post("/projects", body)
|
|
24
|
-
|
|
25
|
-
output_json({
|
|
26
|
-
"id": result["id"],
|
|
27
|
-
"name": result["name"],
|
|
28
|
-
"url": result.get("url", ""),
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if __name__ == "__main__":
|
|
33
|
-
main()
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Create a team/project via the FlyDocs Relay API."""
|
|
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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def main():
|
|
13
|
-
parser = argparse.ArgumentParser(description="Create team or project")
|
|
14
|
-
parser.add_argument("--name", required=True)
|
|
15
|
-
parser.add_argument("--key", default=None, help="Team key (e.g., PROD). Auto-generated if omitted.")
|
|
16
|
-
parser.add_argument("--description", default=None)
|
|
17
|
-
parser.add_argument("--parent", default=None, dest="parent_id", help="Parent team ID for sub-team (Linear only, ignored for Jira)")
|
|
18
|
-
args = parser.parse_args()
|
|
19
|
-
|
|
20
|
-
body: dict = {"name": args.name}
|
|
21
|
-
if args.key:
|
|
22
|
-
body["key"] = args.key
|
|
23
|
-
if args.description:
|
|
24
|
-
body["description"] = args.description
|
|
25
|
-
if args.parent_id:
|
|
26
|
-
body["parentId"] = args.parent_id
|
|
27
|
-
|
|
28
|
-
client = get_client()
|
|
29
|
-
result = client.post("/teams", body)
|
|
30
|
-
|
|
31
|
-
output_json({
|
|
32
|
-
"id": result["id"],
|
|
33
|
-
"name": result["name"],
|
|
34
|
-
"key": result.get("key", ""),
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if __name__ == "__main__":
|
|
39
|
-
main()
|