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

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flydocs/cli",
3
- "version": "0.6.0-alpha.1",
3
+ "version": "0.6.0-alpha.3",
4
4
  "type": "module",
5
5
  "description": "FlyDocs AI CLI — install, setup, and manage FlyDocs projects",
6
6
  "bin": {
@@ -301,7 +301,32 @@ FLYDOCS_API_KEY is not set. Run `flydocs connect` first to set up your API key.
301
301
 
302
302
  Do not proceed until the key is available.
303
303
 
304
- **Step 2: Select team.**
304
+ **Step 2: Detect or select provider.**
305
+
306
+ Query connected providers:
307
+
308
+ ```bash
309
+ python3 .claude/skills/flydocs-cloud/scripts/list_providers.py
310
+ ```
311
+
312
+ This returns `[{type, name, connected}]`. Handle based on results:
313
+
314
+ - **One connected provider** — auto-select it and confirm with the user.
315
+ - **Multiple connected providers** — present a numbered list, let the user
316
+ choose which to use for this project.
317
+ - **No connected providers** — error: "No providers connected. Connect Linear
318
+ or Jira at app.flydocs.ai before running setup."
319
+
320
+ After selection, store the preference:
321
+
322
+ ```bash
323
+ python3 .claude/skills/flydocs-cloud/scripts/set_provider.py <provider_type>
324
+ ```
325
+
326
+ This stores the provider type on the relay (for routing) and updates
327
+ `provider.type` in local config.
328
+
329
+ **Step 3: Select or create team.**
305
330
 
306
331
  If `provider.teamId` in config is null, discover available teams:
307
332
 
@@ -309,10 +334,23 @@ If `provider.teamId` in config is null, discover available teams:
309
334
  python3 .claude/skills/flydocs-cloud/scripts/list_teams.py
310
335
  ```
311
336
 
312
- Present the teams to the user as a numbered list showing name and key. Let
313
- them select. If only one team exists, confirm it.
337
+ Present the teams to the user as a numbered list showing name and key.
338
+ Add a final option: **"Create a new team"**. If only one team exists,
339
+ confirm it.
340
+
341
+ If the user selects **"Create a new team"**:
342
+
343
+ 1. Ask for team name (required) and key (optional — auto-generated if omitted)
344
+ 2. Ask if this should be a sub-team under an existing team (show the list
345
+ again for parent selection, or "None — top-level team")
346
+ 3. Create via:
347
+
348
+ ```bash
349
+ python3 .claude/skills/flydocs-cloud/scripts/create_team.py --name "Team Name" [--key KEY] [--parent <parent_team_id>]
350
+ ```
314
351
 
315
- After selection, store the preference on the relay and in local config:
352
+ After selection or creation, store the preference on the relay and in local
353
+ config:
316
354
 
317
355
  ```bash
318
356
  python3 .claude/skills/flydocs-cloud/scripts/set_team.py <team_id>
@@ -321,7 +359,7 @@ python3 .claude/skills/flydocs-cloud/scripts/set_team.py <team_id>
321
359
  This stores the team preference server-side (the relay uses it for all
322
360
  team-scoped operations) and updates `provider.teamId` in local config.
323
361
 
324
- **Step 3: Get or create project.**
362
+ **Step 4: Get or create project.**
325
363
 
326
364
  Query existing projects:
327
365
 
@@ -336,7 +374,7 @@ create a new project:
336
374
  python3 .claude/skills/flydocs-cloud/scripts/create_project.py --name "Project Name"
337
375
  ```
338
376
 
339
- **Step 4: Configure labels.**
377
+ **Step 5: Configure labels.**
340
378
 
341
379
  Fetch available labels from the provider:
342
380
 
@@ -371,7 +409,7 @@ python3 .claude/skills/flydocs-cloud/scripts/set_labels.py \
371
409
  If the relay returns `LABELS_NOT_FOUND`, show the invalid names and ask the
372
410
  user to correct them.
373
411
 
374
- **Step 5: Configure product identity.**
412
+ **Step 6: Configure product identity.**
375
413
 
376
414
  Ask about product metadata:
377
415
 
@@ -379,11 +417,11 @@ Ask about product metadata:
379
417
  from project.md)
380
418
  - **Icon and color** — optional, ask if they have preferences
381
419
 
382
- **Step 6: Save to config.**
420
+ **Step 7: Save to config.**
383
421
 
384
422
  Update `.flydocs/config.json`:
385
423
 
386
- - `provider.type` — `"linear"` (set by connect command)
424
+ - `provider.type` — set by `set_provider.py`
387
425
  - `provider.teamId` — selected team ID (set by `set_team.py`)
388
426
  - `labels.defaults` — default label names (set by `set_labels.py`)
389
427
  - `labels.typeMap` — type-to-label mapping (set by `set_labels.py`)
@@ -423,11 +461,11 @@ Let the user customize names, descriptions, and target dates.
423
461
 
424
462
  **Step 4: Create milestones.**
425
463
 
426
- For each approved milestone:
464
+ For each approved milestone, pass the project ID from Phase 2 Step 3:
427
465
 
428
466
  ```bash
429
467
  python3 .claude/skills/flydocs-cloud/scripts/create_milestone.py \
430
- --name "Phase 1: Foundation" --target-date YYYY-MM-DD
468
+ --name "Phase 1: Foundation" --project <project_id> --target-date YYYY-MM-DD
431
469
  ```
432
470
 
433
471
  Record the milestone IDs for use in Phase 4.
@@ -455,10 +493,11 @@ For each work item, follow the capture procedure from
455
493
  `.claude/skills/flydocs-workflow/stages/capture.md`:
456
494
 
457
495
  - Determine type (feature, bug, chore, idea)
458
- - Create via the mechanism script:
496
+ - Create via the mechanism script (cloud: pass `--project` from Phase 2):
459
497
  ```bash
460
498
  python3 .claude/skills/flydocs-{tier}/scripts/create_issue.py \
461
- --title "Issue title" --type feature --priority 3 --estimate 2
499
+ --title "Issue title" --type feature --priority 3 --estimate 2 \
500
+ --project <project_id>
462
501
  ```
463
502
  - For quick ideas, use `--triage` flag
464
503
 
@@ -65,7 +65,7 @@ Count totals by status and type.
65
65
 
66
66
  **Step 3: Check for API readiness.**
67
67
 
68
- Check if `FLYDOCS_RELAY_API_KEY` is set in the environment (from `.env` or
68
+ Check if `FLYDOCS_API_KEY` is set in the environment (from `.env` or
69
69
  `.env.local`). If not, warn the user they will need it for Phase 1.
70
70
 
71
71
  **Step 4: Present migration summary.**
@@ -100,27 +100,39 @@ Confirm with the user before continuing.
100
100
  ## Phase 1: Connect to Cloud
101
101
 
102
102
  Guide the user through connecting to the cloud provider. This swaps the
103
- mechanism skill from `flydocs-local` to `flydocs-cloud`.
103
+ tier, stores the API key, and prepares the cloud mechanism skill.
104
104
 
105
- **Step 1: Run flydocs connect.**
105
+ **Step 1: Get API key.**
106
106
 
107
- Instruct the user to run `flydocs connect --here` from their terminal
108
- (this is a CLI command, not an AI command). Explain what it does:
107
+ Ask the user for their FlyDocs API key (`fdk_...`). If `FLYDOCS_API_KEY`
108
+ is already set in the environment, confirm they want to use the existing
109
+ key or enter a new one.
110
+
111
+ If no key is available, instruct the user:
109
112
 
110
113
  ```
111
- Run this in your terminal:
112
- flydocs connect --here
113
-
114
- This will:
115
- - Prompt for your relay API key (from flydocs.ai account)
116
- - Update .flydocs/config.json to cloud tier
117
- - Swap mechanism skills (local -> cloud)
118
- - Verify the connection works
114
+ You'll need a FlyDocs API key (fdk_...) from your dashboard at app.flydocs.ai.
115
+
116
+ Option A: Run `flydocs connect --here` in your terminal (handles everything)
117
+ Option B: Add FLYDOCS_API_KEY=fdk_... to your .env or .env.local file
119
118
  ```
120
119
 
121
- **Step 2: Wait for completion.**
120
+ Wait for the user to confirm the key is set before proceeding.
121
+
122
+ **Step 2: Update config to cloud tier.**
123
+
124
+ Read `.flydocs/config.json`, update `tier` to `"cloud"`, and write it back.
125
+ Preserve all existing config values (detected stack, skills, etc.).
126
+
127
+ **Step 3: Swap mechanism skill.**
128
+
129
+ Instruct the user to run `flydocs connect --here` from their terminal if
130
+ they haven't already. This handles the mechanism skill swap (installs
131
+ `flydocs-cloud`, removes `flydocs-local`).
132
+
133
+ **Step 4: Verify connection.**
122
134
 
123
- After the user confirms they ran `flydocs connect`, verify:
135
+ After the user confirms the swap, verify:
124
136
 
125
137
  1. Read `.flydocs/config.json` — `tier` should now be `cloud`
126
138
  2. Check that `.claude/skills/flydocs-cloud/scripts/` exists
@@ -29,15 +29,15 @@ All scripts: `python3 .claude/skills/flydocs-cloud/scripts/<script>`
29
29
 
30
30
  ### Shared Contract Scripts
31
31
 
32
- | Script | Usage | Output |
33
- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
34
- | `create_issue.py` | `--title "..." --type feature [--description "..."] [--description-file PATH] [--priority 0-4] [--estimate 1-5] [--assignee STR] [--labels "a,b"] [--triage] \| stdin` | `{id, identifier, title, url}` |
35
- | `transition.py` | `<ref> <STATUS> "<comment>"` | `{success, issue, previousStatus, newStatus}` |
36
- | `comment.py` | `<ref> ["<comment>"] \| stdin` | `{success, commentId}` |
37
- | `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}]` |
38
- | `get_issue.py` | `<ref> [--fields basic\|full]` | `{id, identifier, title, description, status, assignee, priority, estimate, dueDate, milestone, milestoneId, project, projectId, comments[]}` |
39
- | `assign.py` | `<ref> <assignee>` | `{success, issue, assignee}` |
40
- | `update_description.py` | `<ref> --text "..." \| --file PATH \| stdin` | `{success, issue}` |
32
+ | Script | Usage | Output |
33
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
34
+ | `create_issue.py` | `--title "..." --type feature [--description "..."] [--description-file PATH] [--priority 0-4] [--estimate 1-5] [--assignee STR] [--project ID] [--labels "a,b"] [--triage] \| stdin` | `{id, identifier, title, url}` |
35
+ | `transition.py` | `<ref> <STATUS> "<comment>"` | `{success, issue, previousStatus, newStatus}` |
36
+ | `comment.py` | `<ref> ["<comment>"] \| stdin` | `{success, commentId}` |
37
+ | `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}]` |
38
+ | `get_issue.py` | `<ref> [--fields basic\|full]` | `{id, identifier, title, description, status, assignee, priority, estimate, dueDate, milestone, milestoneId, project, projectId, comments[]}` |
39
+ | `assign.py` | `<ref> <assignee>` | `{success, issue, assignee}` |
40
+ | `update_description.py` | `<ref> --text "..." \| --file PATH \| stdin` | `{success, issue}` |
41
41
 
42
42
  ### Extended Scripts
43
43
 
@@ -58,12 +58,15 @@ All scripts: `python3 .claude/skills/flydocs-cloud/scripts/<script>`
58
58
 
59
59
  ### Workspace Scripts
60
60
 
61
- | Script | Usage | Output |
62
- | ---------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------- |
63
- | `list_teams.py` | (no args) | `[{id, name, key}]` |
64
- | `set_team.py` | `<team_id>` | `{success}` — updates relay preference and local config `provider.teamId` |
65
- | `list_labels.py` | (no args) | `[{id, name, color}]` — requires team to be set first |
66
- | `set_labels.py` | `--defaults '["a"]' --type-map '{"feature":["F"],...}' \| stdin` | `{success, validated, defaults, typeMap}` — stores label config on relay |
61
+ | Script | Usage | Output |
62
+ | ------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------- |
63
+ | `list_providers.py` | (no args) | `[{type, name, connected}]` |
64
+ | `set_provider.py` | `<provider_type>` (`linear` or `jira`) | `{success}` — updates relay routing and local config `provider.type` |
65
+ | `list_teams.py` | (no args) | `[{id, name, key}]` |
66
+ | `create_team.py` | `--name "..." [--key KEY] [--description "..."] [--parent <team_id>]` | `{id, name, key}` — `--parent` creates a sub-team |
67
+ | `set_team.py` | `<team_id>` | `{success}` — updates relay preference and local config `provider.teamId` |
68
+ | `list_labels.py` | (no args) | `[{id, name, color}]` — requires team to be set first |
69
+ | `set_labels.py` | `--defaults '["a"]' --type-map '{"feature":["F"],...}' \| stdin` | `{success, validated, defaults, typeMap}` — stores label config on relay |
67
70
 
68
71
  ### Script Notes
69
72
 
@@ -18,6 +18,7 @@ def main():
18
18
  parser.add_argument("--priority", type=int, default=3, choices=range(5))
19
19
  parser.add_argument("--estimate", type=int, default=0, choices=[0, 1, 2, 3, 5])
20
20
  parser.add_argument("--assignee", default=None)
21
+ parser.add_argument("--project", default=None, help="Project ID")
21
22
  parser.add_argument("--labels", default=None, help="Comma-separated ad-hoc label names")
22
23
  parser.add_argument("--triage", action="store_true")
23
24
  args = parser.parse_args()
@@ -43,6 +44,8 @@ def main():
43
44
  body["estimate"] = args.estimate
44
45
  if args.assignee:
45
46
  body["assignee"] = args.assignee
47
+ if args.project:
48
+ body["projectId"] = args.project
46
49
  if args.labels:
47
50
  body["labels"] = [l.strip() for l in args.labels.split(",") if l.strip()]
48
51
  if args.triage:
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ """Create a team (or sub-team) 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")
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 to create a sub-team")
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()
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env python3
2
+ """List available providers 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
9
+
10
+
11
+ def main():
12
+ client = get_client()
13
+ result = client.get("/providers")
14
+
15
+ output_json(result)
16
+
17
+
18
+ if __name__ == "__main__":
19
+ main()
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env python3
2
+ """Set provider preference via the FlyDocs Relay API.
3
+
4
+ Stores the provider type on the relay (for server-side routing)
5
+ and updates the local config (for display/reference).
6
+ """
7
+
8
+ import argparse
9
+ import json
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ sys.path.insert(0, str(Path(__file__).parent))
14
+ from flydocs_api import get_client, output_json, fail
15
+
16
+
17
+ def main():
18
+ parser = argparse.ArgumentParser(description="Set provider preference")
19
+ parser.add_argument(
20
+ "provider_type",
21
+ choices=["linear", "jira"],
22
+ help="Provider type",
23
+ )
24
+ args = parser.parse_args()
25
+
26
+ client = get_client()
27
+ result = client.post("/auth/provider", {"providerType": args.provider_type})
28
+
29
+ # Update local config with provider type
30
+ config_path = client.config_path
31
+ if config_path.exists():
32
+ with open(config_path, "r") as f:
33
+ config = json.load(f)
34
+ if "provider" not in config:
35
+ config["provider"] = {"type": args.provider_type, "teamId": None}
36
+ else:
37
+ config["provider"]["type"] = args.provider_type
38
+ with open(config_path, "w") as f:
39
+ json.dump(config, f, indent=2)
40
+ f.write("\n")
41
+
42
+ output_json(result)
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.0-alpha.1",
2
+ "version": "0.6.0-alpha.3",
3
3
  "sourceRepo": "github.com/plastrlab/flydocs-core",
4
4
  "tier": "local",
5
5
  "setupComplete": false,
@@ -1 +1 @@
1
- 0.6.0-alpha.1
1
+ 0.6.0-alpha.3
@@ -7,6 +7,35 @@ Versioning: [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.6.0-alpha.3] — 2026-03-13
11
+
12
+ ### Added
13
+
14
+ - **Provider selection** — new `list_providers.py` and `set_provider.py`
15
+ scripts for multi-provider support (Linear + Jira). Setup flow detects
16
+ connected providers before team selection.
17
+ - **Inline API key prompt** — `flydocs install` now prompts for FlyDocs API
18
+ key when cloud tier is selected. No separate `flydocs connect` step needed.
19
+ - **Existing config detection** — install detects pre-existing `.claude/CLAUDE.md`,
20
+ `settings.json`, `hooks.json`, and `AGENTS.md`. Prompts user to overwrite
21
+ (with backup) or preserve.
22
+ - **`--project` flag** — `create_issue.py` accepts `--project <id>` to scope
23
+ issues to a specific project. Fixes milestone/project mismatch during setup.
24
+ - **Team creation** — `create_team.py` with `--parent` flag for sub-teams.
25
+
26
+ ### Changed
27
+
28
+ - **Setup flow restructured** — Phase 2 now starts with provider detection,
29
+ then team selection, project, labels. Milestones and issues pass `--project`.
30
+ - **Community skill output** — install shows one line per skill instead of
31
+ 4-5 verbose lines. "No triggers" warning suppressed for community skills.
32
+ - **`/flydocs-upgrade` streamlined** — Phase 1 inlines API key handling
33
+ instead of requiring a separate terminal step.
34
+ - **API key helpers extracted** — shared `api-key.ts` module used by both
35
+ `install` and `connect` commands.
36
+
37
+ ---
38
+
10
39
  ## [0.6.0-alpha.1] — 2026-03-12
11
40
 
12
41
  ### Added
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.6.0-alpha.1",
2
+ "version": "0.6.0-alpha.3",
3
3
  "description": "FlyDocs Core - Manifest of all managed files",
4
4
  "repository": "github.com/plastrlab/flydocs-core",
5
5