@paradigma-inc/flywheel 0.1.82 → 0.1.85

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 (45) hide show
  1. package/README.md +32 -4
  2. package/package.json +1 -1
  3. package/skills/flywheel/references/INTERFACES.md +9 -0
  4. package/skills/flywheel/references/flywheel-cli-tool-map.md +3 -1
  5. package/skills/flywheel/references/flywheel-mcp-tool-map.md +3 -1
  6. package/skills/flywheel/usage-and-workflows/what-to-do-with-flywheel.md +2 -2
  7. package/skills/flywheel-auto/references/INTERFACES.md +9 -0
  8. package/skills/flywheel-auto/references/flywheel-cli-tool-map.md +3 -1
  9. package/skills/flywheel-auto/references/flywheel-mcp-tool-map.md +3 -1
  10. package/skills/flywheel-lookahead/references/INTERFACES.md +9 -0
  11. package/skills/flywheel-lookahead/references/flywheel-cli-tool-map.md +3 -1
  12. package/skills/flywheel-lookahead/references/flywheel-mcp-tool-map.md +3 -1
  13. package/skills/flywheel-reproduce/references/INTERFACES.md +9 -0
  14. package/skills/flywheel-reproduce/references/flywheel-cli-tool-map.md +3 -1
  15. package/skills/flywheel-reproduce/references/flywheel-mcp-tool-map.md +3 -1
  16. package/skills/flywheel-to-graph/references/INTERFACES.md +9 -0
  17. package/skills/flywheel-to-graph/references/flywheel-cli-tool-map.md +3 -1
  18. package/skills/flywheel-to-graph/references/flywheel-mcp-tool-map.md +3 -1
  19. package/src/cli.mjs +119 -3
  20. package/src/completion-install.mjs +680 -0
  21. package/src/public-command-metadata.mjs +257 -40
  22. package/src/runtime/required-runtime-commands.json +2 -0
  23. package/src/runtime/vendor/flywheel-cli-dist/commands/graph-get.js +6 -0
  24. package/src/runtime/vendor/flywheel-cli-dist/commands/graph-get.js.map +1 -1
  25. package/src/runtime/vendor/flywheel-cli-dist/commands/help-metadata.d.ts +5 -1
  26. package/src/runtime/vendor/flywheel-cli-dist/commands/help-metadata.js +2 -0
  27. package/src/runtime/vendor/flywheel-cli-dist/commands/help-metadata.js.map +1 -1
  28. package/src/runtime/vendor/flywheel-cli-dist/commands/index.d.ts +4 -1
  29. package/src/runtime/vendor/flywheel-cli-dist/commands/index.js +5 -1
  30. package/src/runtime/vendor/flywheel-cli-dist/commands/index.js.map +1 -1
  31. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-children.d.ts +2 -0
  32. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-children.js +8 -0
  33. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-children.js.map +1 -0
  34. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-parents.d.ts +2 -0
  35. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-parents.js +8 -0
  36. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-parents.js.map +1 -0
  37. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/graph.js +10 -0
  38. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/graph.js.map +1 -1
  39. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js +81 -3
  40. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js.map +1 -1
  41. package/src/runtime/vendor/flywheel-cli-dist/commands/usage-spec.d.ts +1 -1
  42. package/src/runtime/vendor/flywheel-cli-dist/commands/usage-spec.js +188 -146
  43. package/src/runtime/vendor/flywheel-cli-dist/commands/usage-spec.js.map +1 -1
  44. package/src/runtime/vendor/manifest.json +7 -1
  45. package/src/unified-cli.mjs +31 -4
package/README.md CHANGED
@@ -71,8 +71,34 @@ cargo binstall usage-cli
71
71
  pacman -S usage
72
72
  ```
73
73
 
74
- Generate the script for your shell and redirect it wherever your shell setup
75
- loads completions:
74
+ Install generated completions into user-level locations:
75
+
76
+ ```bash
77
+ flywheel completion install bash
78
+ flywheel completion install zsh --update-profile --yes
79
+ flywheel completion install fish
80
+ flywheel completion install powershell --update-profile --yes
81
+ flywheel completion install nu
82
+ flywheel completion install nushell
83
+ ```
84
+
85
+ Remove Flywheel-managed completion files and profile blocks with the matching
86
+ uninstall command:
87
+
88
+ ```bash
89
+ flywheel completion uninstall bash
90
+ flywheel completion uninstall zsh --update-profile --yes
91
+ flywheel completion uninstall fish
92
+ flywheel completion uninstall powershell --update-profile --yes
93
+ flywheel completion uninstall nu
94
+ ```
95
+
96
+ Profile/startup file edits are opt-in. Without `--update-profile`, installation
97
+ writes only the generated completion file. Use `--dry-run` to inspect planned
98
+ changes, `--dir <path>` to choose a destination directory, and `--force` only
99
+ when replacing an existing unmarked completion file.
100
+
101
+ You can also generate the script for your shell and redirect it yourself:
76
102
 
77
103
  ```bash
78
104
  flywheel completion bash --include-bash-completion-lib > ~/.local/share/bash-completion/completions/flywheel
@@ -83,8 +109,10 @@ flywheel completion nu > ~/.config/nushell/autoload/flywheel.nu
83
109
  flywheel completion nushell > ~/.config/nushell/autoload/flywheel.nu
84
110
  ```
85
111
 
86
- This command generates scripts only. It does not install completions. It does
87
- nothing to shell startup files and does not edit shell profiles.
112
+ `flywheel completion <shell>` generates scripts only. It does not install
113
+ completions, touch shell startup files, or edit shell profiles. `flywheel setup`
114
+ also does not install completions; completion installation remains an explicit
115
+ `flywheel completion install <shell>` action.
88
116
 
89
117
  ## Uninstall
90
118
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paradigma-inc/flywheel",
3
- "version": "0.1.82",
3
+ "version": "0.1.85",
4
4
  "description": "One-command setup for Flywheel MCP hosts",
5
5
  "type": "module",
6
6
  "files": [
@@ -26,6 +26,13 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
26
26
  - Approval sessions and compute grants are distinct entities; approvals are session-scoped bindings.
27
27
  - Campaign projections are derived from root config and attempt submission JSON artifacts.
28
28
 
29
+ Node detail reads are cardinality-safe: `flywheel_get_node` / `GET /nodes/{node_id}`
30
+ return node fields plus `has_children` / `has_parents` presence booleans, but do
31
+ not guarantee complete `incoming_ids` or `outgoing_ids` arrays. Use
32
+ `flywheel_get_node_children` / `GET /nodes/{node_id}/children` and
33
+ `flywheel_get_node_parents` / `GET /nodes/{node_id}/parents` for complete
34
+ direct-neighbor traversal.
35
+
29
36
  ## MCP Tool Surface
30
37
 
31
38
  ### Discovery and sharing
@@ -42,6 +49,8 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
42
49
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; full-surface only; binding: `operation`)
43
50
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; full-surface only; binding: `operation`)
44
51
  - `flywheel_get_node` (read; scopes: `read`; core surface; binding: `operation`)
52
+ - `flywheel_get_node_children` (read; scopes: `read`; core surface; binding: `operation`)
53
+ - `flywheel_get_node_parents` (read; scopes: `read`; core surface; binding: `operation`)
45
54
  - `flywheel_create_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
46
55
  - `flywheel_update_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
47
56
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
@@ -35,7 +35,9 @@ The families below mirror `flywheel-mcp-tool-map.md` and list the canonical CLI
35
35
  - `flywheel nodes:sharing:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node_sharing`): Get sharing (access policy) for a node.
36
36
  - `flywheel nodes:sharing:set` (mutating; scopes: `write`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_set_sharing_for_node`): Replace sharing (access policy) for a node.
37
37
  - `flywheel nodes:sharing:set-bulk` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; MCP equivalent: `flywheel_set_sharing_for_nodes`): Apply one sharing policy to multiple nodes.
38
- - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier.
38
+ - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier. Relationship arrays are not guaranteed complete; use relationship paging commands for traversal.
39
+ - `flywheel nodes:children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; MCP equivalent: `flywheel_get_node_children`): Page direct visible children with `--first`, `--after`, and `--projection`.
40
+ - `flywheel nodes:parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; MCP equivalent: `flywheel_get_node_parents`): Page direct visible parents with `--first`, `--after`, and `--projection`.
39
41
  - `flywheel tags:create` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; MCP equivalent: `flywheel_create_node_tag`): Create a reusable tag on a graph root.
40
42
  - `flywheel tags:update` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_update_node_tag`): Update a tag definition.
41
43
  - `flywheel tags:delete` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_delete_node_tag`): Delete a tag definition from the graph.
@@ -39,7 +39,9 @@ Flywheel is a graph-based system for tracking research work, decisions, and evid
39
39
  - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `tool-mediated`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
40
40
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `tool-mediated`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
41
41
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
42
- - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id.
42
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id. Relationship arrays are not guaranteed complete; use relationship paging tools for traversal.
43
+ - `flywheel_get_node_children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; core surface): Page direct visible children with `first`, `after`, and `projection`.
44
+ - `flywheel_get_node_parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; core surface): Page direct visible parents with `first`, `after`, and `projection`.
43
45
  - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node. `track_history` is effective only when `one_only=true`; when `one_only=false`, the effective track_history=false.
44
46
  - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
45
47
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
@@ -42,9 +42,9 @@ Hooks are event-driven automations:
42
42
  `artifact.finalized` and `node.published`.
43
43
  - **Hook**: a durable rule configured on a node (trigger + scope + action).
44
44
  - **Run**: one execution record when a hook reacts to an event.
45
- - Hooks are dispatched by `worker-projection` and executed by ephemeral Fly Machines runners.
45
+ - Hooks are dispatched by `worker-hooks` and executed by ephemeral Fly Machines runners.
46
46
  - Each hook run launches `python -m server.run_hook_runner` in the same Fly app (`FLYWHEEL_HOOK_RUNNER_FLY_APP`).
47
- - Deployments roll out `worker-projection`; runner launches require `FLYWHEEL_HOOK_RUNNER_FLY_API_TOKEN` and `FLYWHEEL_HOOK_RUNNER_FLY_APP`.
47
+ - Deployments roll out `worker-hooks` before `worker-projection`; runner launches require `FLYWHEEL_HOOK_RUNNER_FLY_API_TOKEN` and `FLYWHEEL_HOOK_RUNNER_FLY_APP`.
48
48
 
49
49
  Typical setup:
50
50
 
@@ -26,6 +26,13 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
26
26
  - Approval sessions and compute grants are distinct entities; approvals are session-scoped bindings.
27
27
  - Campaign projections are derived from root config and attempt submission JSON artifacts.
28
28
 
29
+ Node detail reads are cardinality-safe: `flywheel_get_node` / `GET /nodes/{node_id}`
30
+ return node fields plus `has_children` / `has_parents` presence booleans, but do
31
+ not guarantee complete `incoming_ids` or `outgoing_ids` arrays. Use
32
+ `flywheel_get_node_children` / `GET /nodes/{node_id}/children` and
33
+ `flywheel_get_node_parents` / `GET /nodes/{node_id}/parents` for complete
34
+ direct-neighbor traversal.
35
+
29
36
  ## MCP Tool Surface
30
37
 
31
38
  ### Discovery and sharing
@@ -42,6 +49,8 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
42
49
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; full-surface only; binding: `operation`)
43
50
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; full-surface only; binding: `operation`)
44
51
  - `flywheel_get_node` (read; scopes: `read`; core surface; binding: `operation`)
52
+ - `flywheel_get_node_children` (read; scopes: `read`; core surface; binding: `operation`)
53
+ - `flywheel_get_node_parents` (read; scopes: `read`; core surface; binding: `operation`)
45
54
  - `flywheel_create_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
46
55
  - `flywheel_update_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
47
56
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
@@ -34,7 +34,9 @@ The families below mirror `flywheel-mcp-tool-map.md` and list the canonical CLI
34
34
  - `flywheel nodes:sharing:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node_sharing`): Get sharing (access policy) for a node.
35
35
  - `flywheel nodes:sharing:set` (mutating; scopes: `write`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_set_sharing_for_node`): Replace sharing (access policy) for a node.
36
36
  - `flywheel nodes:sharing:set-bulk` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; MCP equivalent: `flywheel_set_sharing_for_nodes`): Apply one sharing policy to multiple nodes.
37
- - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier.
37
+ - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier. Relationship arrays are not guaranteed complete; use relationship paging commands for traversal.
38
+ - `flywheel nodes:children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; MCP equivalent: `flywheel_get_node_children`): Page direct visible children with `--first`, `--after`, and `--projection`.
39
+ - `flywheel nodes:parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; MCP equivalent: `flywheel_get_node_parents`): Page direct visible parents with `--first`, `--after`, and `--projection`.
38
40
  - `flywheel tags:create` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; MCP equivalent: `flywheel_create_node_tag`): Create a reusable tag on a graph root.
39
41
  - `flywheel tags:update` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_update_node_tag`): Update a tag definition.
40
42
  - `flywheel tags:delete` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_delete_node_tag`): Delete a tag definition from the graph.
@@ -38,7 +38,9 @@ Flywheel is a graph-based system for tracking research work, decisions, and evid
38
38
  - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `tool-mediated`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
39
39
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `tool-mediated`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
40
40
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
41
- - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id.
41
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id. Relationship arrays are not guaranteed complete; use relationship paging tools for traversal.
42
+ - `flywheel_get_node_children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; core surface): Page direct visible children with `first`, `after`, and `projection`.
43
+ - `flywheel_get_node_parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; core surface): Page direct visible parents with `first`, `after`, and `projection`.
42
44
  - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node. `track_history` is effective only when `one_only=true`; when `one_only=false`, the effective track_history=false.
43
45
  - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
44
46
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
@@ -26,6 +26,13 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
26
26
  - Approval sessions and compute grants are distinct entities; approvals are session-scoped bindings.
27
27
  - Campaign projections are derived from root config and attempt submission JSON artifacts.
28
28
 
29
+ Node detail reads are cardinality-safe: `flywheel_get_node` / `GET /nodes/{node_id}`
30
+ return node fields plus `has_children` / `has_parents` presence booleans, but do
31
+ not guarantee complete `incoming_ids` or `outgoing_ids` arrays. Use
32
+ `flywheel_get_node_children` / `GET /nodes/{node_id}/children` and
33
+ `flywheel_get_node_parents` / `GET /nodes/{node_id}/parents` for complete
34
+ direct-neighbor traversal.
35
+
29
36
  ## MCP Tool Surface
30
37
 
31
38
  ### Discovery and sharing
@@ -42,6 +49,8 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
42
49
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; full-surface only; binding: `operation`)
43
50
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; full-surface only; binding: `operation`)
44
51
  - `flywheel_get_node` (read; scopes: `read`; core surface; binding: `operation`)
52
+ - `flywheel_get_node_children` (read; scopes: `read`; core surface; binding: `operation`)
53
+ - `flywheel_get_node_parents` (read; scopes: `read`; core surface; binding: `operation`)
45
54
  - `flywheel_create_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
46
55
  - `flywheel_update_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
47
56
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
@@ -34,7 +34,9 @@ The families below mirror `flywheel-mcp-tool-map.md` and list the canonical CLI
34
34
  - `flywheel nodes:sharing:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node_sharing`): Get sharing (access policy) for a node.
35
35
  - `flywheel nodes:sharing:set` (mutating; scopes: `write`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_set_sharing_for_node`): Replace sharing (access policy) for a node.
36
36
  - `flywheel nodes:sharing:set-bulk` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; MCP equivalent: `flywheel_set_sharing_for_nodes`): Apply one sharing policy to multiple nodes.
37
- - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier.
37
+ - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier. Relationship arrays are not guaranteed complete; use relationship paging commands for traversal.
38
+ - `flywheel nodes:children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; MCP equivalent: `flywheel_get_node_children`): Page direct visible children with `--first`, `--after`, and `--projection`.
39
+ - `flywheel nodes:parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; MCP equivalent: `flywheel_get_node_parents`): Page direct visible parents with `--first`, `--after`, and `--projection`.
38
40
  - `flywheel tags:create` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; MCP equivalent: `flywheel_create_node_tag`): Create a reusable tag on a graph root.
39
41
  - `flywheel tags:update` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_update_node_tag`): Update a tag definition.
40
42
  - `flywheel tags:delete` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_delete_node_tag`): Delete a tag definition from the graph.
@@ -38,7 +38,9 @@ Flywheel is a graph-based system for tracking research work, decisions, and evid
38
38
  - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `tool-mediated`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
39
39
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `tool-mediated`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
40
40
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
41
- - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id.
41
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id. Relationship arrays are not guaranteed complete; use relationship paging tools for traversal.
42
+ - `flywheel_get_node_children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; core surface): Page direct visible children with `first`, `after`, and `projection`.
43
+ - `flywheel_get_node_parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; core surface): Page direct visible parents with `first`, `after`, and `projection`.
42
44
  - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node. `track_history` is effective only when `one_only=true`; when `one_only=false`, the effective track_history=false.
43
45
  - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
44
46
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
@@ -26,6 +26,13 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
26
26
  - Approval sessions and compute grants are distinct entities; approvals are session-scoped bindings.
27
27
  - Campaign projections are derived from root config and attempt submission JSON artifacts.
28
28
 
29
+ Node detail reads are cardinality-safe: `flywheel_get_node` / `GET /nodes/{node_id}`
30
+ return node fields plus `has_children` / `has_parents` presence booleans, but do
31
+ not guarantee complete `incoming_ids` or `outgoing_ids` arrays. Use
32
+ `flywheel_get_node_children` / `GET /nodes/{node_id}/children` and
33
+ `flywheel_get_node_parents` / `GET /nodes/{node_id}/parents` for complete
34
+ direct-neighbor traversal.
35
+
29
36
  ## MCP Tool Surface
30
37
 
31
38
  ### Discovery and sharing
@@ -42,6 +49,8 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
42
49
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; full-surface only; binding: `operation`)
43
50
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; full-surface only; binding: `operation`)
44
51
  - `flywheel_get_node` (read; scopes: `read`; core surface; binding: `operation`)
52
+ - `flywheel_get_node_children` (read; scopes: `read`; core surface; binding: `operation`)
53
+ - `flywheel_get_node_parents` (read; scopes: `read`; core surface; binding: `operation`)
45
54
  - `flywheel_create_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
46
55
  - `flywheel_update_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
47
56
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
@@ -34,7 +34,9 @@ The families below mirror `flywheel-mcp-tool-map.md` and list the canonical CLI
34
34
  - `flywheel nodes:sharing:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node_sharing`): Get sharing (access policy) for a node.
35
35
  - `flywheel nodes:sharing:set` (mutating; scopes: `write`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_set_sharing_for_node`): Replace sharing (access policy) for a node.
36
36
  - `flywheel nodes:sharing:set-bulk` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; MCP equivalent: `flywheel_set_sharing_for_nodes`): Apply one sharing policy to multiple nodes.
37
- - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier.
37
+ - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier. Relationship arrays are not guaranteed complete; use relationship paging commands for traversal.
38
+ - `flywheel nodes:children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; MCP equivalent: `flywheel_get_node_children`): Page direct visible children with `--first`, `--after`, and `--projection`.
39
+ - `flywheel nodes:parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; MCP equivalent: `flywheel_get_node_parents`): Page direct visible parents with `--first`, `--after`, and `--projection`.
38
40
  - `flywheel tags:create` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; MCP equivalent: `flywheel_create_node_tag`): Create a reusable tag on a graph root.
39
41
  - `flywheel tags:update` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_update_node_tag`): Update a tag definition.
40
42
  - `flywheel tags:delete` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_delete_node_tag`): Delete a tag definition from the graph.
@@ -38,7 +38,9 @@ Flywheel is a graph-based system for tracking research work, decisions, and evid
38
38
  - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `tool-mediated`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
39
39
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `tool-mediated`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
40
40
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
41
- - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id.
41
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id. Relationship arrays are not guaranteed complete; use relationship paging tools for traversal.
42
+ - `flywheel_get_node_children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; core surface): Page direct visible children with `first`, `after`, and `projection`.
43
+ - `flywheel_get_node_parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; core surface): Page direct visible parents with `first`, `after`, and `projection`.
42
44
  - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node. `track_history` is effective only when `one_only=true`; when `one_only=false`, the effective track_history=false.
43
45
  - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
44
46
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
@@ -26,6 +26,13 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
26
26
  - Approval sessions and compute grants are distinct entities; approvals are session-scoped bindings.
27
27
  - Campaign projections are derived from root config and attempt submission JSON artifacts.
28
28
 
29
+ Node detail reads are cardinality-safe: `flywheel_get_node` / `GET /nodes/{node_id}`
30
+ return node fields plus `has_children` / `has_parents` presence booleans, but do
31
+ not guarantee complete `incoming_ids` or `outgoing_ids` arrays. Use
32
+ `flywheel_get_node_children` / `GET /nodes/{node_id}/children` and
33
+ `flywheel_get_node_parents` / `GET /nodes/{node_id}/parents` for complete
34
+ direct-neighbor traversal.
35
+
29
36
  ## MCP Tool Surface
30
37
 
31
38
  ### Discovery and sharing
@@ -42,6 +49,8 @@ Canonical reference for Flywheel MCP public interfaces and contract pointers.
42
49
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; full-surface only; binding: `operation`)
43
50
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; full-surface only; binding: `operation`)
44
51
  - `flywheel_get_node` (read; scopes: `read`; core surface; binding: `operation`)
52
+ - `flywheel_get_node_children` (read; scopes: `read`; core surface; binding: `operation`)
53
+ - `flywheel_get_node_parents` (read; scopes: `read`; core surface; binding: `operation`)
45
54
  - `flywheel_create_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
46
55
  - `flywheel_update_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
47
56
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; full-surface only; binding: `operation`)
@@ -34,7 +34,9 @@ The families below mirror `flywheel-mcp-tool-map.md` and list the canonical CLI
34
34
  - `flywheel nodes:sharing:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node_sharing`): Get sharing (access policy) for a node.
35
35
  - `flywheel nodes:sharing:set` (mutating; scopes: `write`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_set_sharing_for_node`): Replace sharing (access policy) for a node.
36
36
  - `flywheel nodes:sharing:set-bulk` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; MCP equivalent: `flywheel_set_sharing_for_nodes`): Apply one sharing policy to multiple nodes.
37
- - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier.
37
+ - `flywheel nodes:get` (read; scopes: `read`; HTTP: `tool-mediated`; MCP equivalent: `flywheel_get_node`): Fetch one node by identifier. Relationship arrays are not guaranteed complete; use relationship paging commands for traversal.
38
+ - `flywheel nodes:children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; MCP equivalent: `flywheel_get_node_children`): Page direct visible children with `--first`, `--after`, and `--projection`.
39
+ - `flywheel nodes:parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; MCP equivalent: `flywheel_get_node_parents`): Page direct visible parents with `--first`, `--after`, and `--projection`.
38
40
  - `flywheel tags:create` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; MCP equivalent: `flywheel_create_node_tag`): Create a reusable tag on a graph root.
39
41
  - `flywheel tags:update` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_update_node_tag`): Update a tag definition.
40
42
  - `flywheel tags:delete` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; MCP equivalent: `flywheel_delete_node_tag`): Delete a tag definition from the graph.
@@ -38,7 +38,9 @@ Flywheel is a graph-based system for tracking research work, decisions, and evid
38
38
  - `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `tool-mediated`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
39
39
  - `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `tool-mediated`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
40
40
  - `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /nodes/access-policy/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
41
- - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id.
41
+ - `flywheel_get_node` (read; scopes: `read`; HTTP: `tool-mediated`; core surface): Get one node by node_id. Relationship arrays are not guaranteed complete; use relationship paging tools for traversal.
42
+ - `flywheel_get_node_children` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/children`; core surface): Page direct visible children with `first`, `after`, and `projection`.
43
+ - `flywheel_get_node_parents` (read; scopes: `read`; HTTP: `GET /nodes/{node_id}/parents`; core surface): Page direct visible parents with `first`, `after`, and `projection`.
42
44
  - `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node. `track_history` is effective only when `one_only=true`; when `one_only=false`, the effective track_history=false.
43
45
  - `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
44
46
  - `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
package/src/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { checkbox, select } from "@inquirer/prompts";
2
+ import { checkbox, confirm, select } from "@inquirer/prompts";
3
3
  import ora from "ora";
4
4
  import pc from "picocolors";
5
5
  import { access, readFile, rm } from "node:fs/promises";
@@ -16,6 +16,10 @@ import {
16
16
  normalizeHosts,
17
17
  } from "./agents.mjs";
18
18
  import { generateCompletionScript } from "./completion.mjs";
19
+ import {
20
+ installCompletion,
21
+ uninstallCompletion,
22
+ } from "./completion-install.mjs";
19
23
  import {
20
24
  readEntryServerUrl,
21
25
  readNamedConfigEntry,
@@ -491,6 +495,52 @@ async function runCompletionCommand(shell, options) {
491
495
  }
492
496
  }
493
497
 
498
+ async function runCompletionInstallCommand(shell, options) {
499
+ try {
500
+ await installCompletion({
501
+ shell,
502
+ dir: options.dir,
503
+ force: options.force === true,
504
+ dryRun: options.dryRun === true,
505
+ updateProfile: options.updateProfile === true,
506
+ yes: options.yes === true,
507
+ isInteractive:
508
+ process.stdin.isTTY === true && process.stdout.isTTY === true,
509
+ stdout: (chunk) => process.stdout.write(chunk),
510
+ stderr: (chunk) => process.stderr.write(chunk),
511
+ confirmProfileUpdate: async ({ message, default: defaultValue }) =>
512
+ await confirm({ message, default: defaultValue }),
513
+ generateCompletionScript,
514
+ });
515
+ } catch (error) {
516
+ const message = error instanceof Error ? error.message : String(error);
517
+ process.stderr.write(`${message}\n`);
518
+ process.exitCode = 1;
519
+ }
520
+ }
521
+
522
+ async function runCompletionUninstallCommand(shell, options) {
523
+ try {
524
+ await uninstallCompletion({
525
+ shell,
526
+ dir: options.dir,
527
+ dryRun: options.dryRun === true,
528
+ updateProfile: options.updateProfile === true,
529
+ yes: options.yes === true,
530
+ isInteractive:
531
+ process.stdin.isTTY === true && process.stdout.isTTY === true,
532
+ stdout: (chunk) => process.stdout.write(chunk),
533
+ stderr: (chunk) => process.stderr.write(chunk),
534
+ confirmProfileUpdate: async ({ message, default: defaultValue }) =>
535
+ await confirm({ message, default: defaultValue }),
536
+ });
537
+ } catch (error) {
538
+ const message = error instanceof Error ? error.message : String(error);
539
+ process.stderr.write(`${message}\n`);
540
+ process.exitCode = 1;
541
+ }
542
+ }
543
+
494
544
  function parseUninstallScope(value) {
495
545
  const normalized = String(value || "")
496
546
  .trim()
@@ -1162,9 +1212,10 @@ Examples:
1162
1212
  `,
1163
1213
  );
1164
1214
 
1165
- program
1166
- .command("completion <shell>")
1215
+ const completionCommand = program
1216
+ .command("completion")
1167
1217
  .description("Generate a shell completion script")
1218
+ .argument("[shell]", "Shell to generate completions for")
1168
1219
  .addHelpText(
1169
1220
  "before",
1170
1221
  `${pc.bold(pc.cyan("✻ Flywheel Completion"))}
@@ -1198,9 +1249,74 @@ Examples:
1198
1249
  `,
1199
1250
  )
1200
1251
  .action(async (shell, options) => {
1252
+ if (!shell) {
1253
+ completionCommand.help();
1254
+ return;
1255
+ }
1201
1256
  await runCompletionCommand(shell, options);
1202
1257
  });
1203
1258
 
1259
+ completionCommand
1260
+ .command("install <shell>")
1261
+ .description("Install generated shell completion scripts")
1262
+ .option("--dir <path>", "Override completion script destination directory")
1263
+ .option("--force", "Replace an existing unmarked destination file")
1264
+ .option("--dry-run", "Print planned changes without writing files")
1265
+ .option("--update-profile", "Allow shell startup/profile file updates")
1266
+ .option("-y, --yes", "Skip confirmation prompts")
1267
+ .addHelpText(
1268
+ "before",
1269
+ `${pc.bold(pc.cyan("✻ Flywheel Completion Install"))}
1270
+
1271
+ Install generated Flywheel shell completions to user-level locations.
1272
+ Supported shells: ${COMPLETION_SHELL_CHOICES.join(", ")}.
1273
+ `,
1274
+ )
1275
+ .addHelpText(
1276
+ "after",
1277
+ `
1278
+ Examples:
1279
+ ${pc.green("flywheel completion install bash")}
1280
+ ${pc.green("flywheel completion install zsh --update-profile --yes")}
1281
+ ${pc.green("flywheel completion install fish")}
1282
+ ${pc.green("flywheel completion install powershell --update-profile --yes")}
1283
+ ${pc.green("flywheel completion install nu")}
1284
+ `,
1285
+ )
1286
+ .action(async (shell, options) => {
1287
+ await runCompletionInstallCommand(shell, options);
1288
+ });
1289
+
1290
+ completionCommand
1291
+ .command("uninstall <shell>")
1292
+ .description("Uninstall Flywheel-managed shell completion scripts")
1293
+ .option("--dir <path>", "Override completion script destination directory")
1294
+ .option("--dry-run", "Print planned removals without writing files")
1295
+ .option("--update-profile", "Allow shell startup/profile file updates")
1296
+ .option("-y, --yes", "Skip confirmation prompts")
1297
+ .addHelpText(
1298
+ "before",
1299
+ `${pc.bold(pc.cyan("✻ Flywheel Completion Uninstall"))}
1300
+
1301
+ Remove only Flywheel-managed shell completion files and profile blocks.
1302
+ Supported shells: ${COMPLETION_SHELL_CHOICES.join(", ")}.
1303
+ `,
1304
+ )
1305
+ .addHelpText(
1306
+ "after",
1307
+ `
1308
+ Examples:
1309
+ ${pc.green("flywheel completion uninstall bash")}
1310
+ ${pc.green("flywheel completion uninstall zsh --update-profile --yes")}
1311
+ ${pc.green("flywheel completion uninstall fish")}
1312
+ ${pc.green("flywheel completion uninstall powershell --update-profile --yes")}
1313
+ ${pc.green("flywheel completion uninstall nu")}
1314
+ `,
1315
+ )
1316
+ .action(async (shell, options) => {
1317
+ await runCompletionUninstallCommand(shell, options);
1318
+ });
1319
+
1204
1320
  program
1205
1321
  .command("setup")
1206
1322
  .description("Set up Flywheel for your AI coding host")