@paradigma-inc/flywheel 0.2.32 → 0.2.45
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 +1 -1
- package/skills/flywheel/SKILL.md +2 -0
- package/skills/flywheel/references/flywheel-cli-tool-map.md +7 -6
- package/skills/flywheel-auto/references/flywheel-cli-tool-map.md +6 -5
- package/skills/flywheel-llm-proof-paper/scripts/check_paper.py +1 -1
- package/skills/flywheel-lookahead/references/flywheel-cli-tool-map.md +6 -5
- package/skills/flywheel-prove/assets/pipeline_template/src/tproof/cli.py +11 -6
- package/skills/flywheel-prove/scripts/scaffold_pipeline.py +0 -1
- package/skills/flywheel-repo/SKILL.md +47 -0
- package/skills/flywheel-repo/references/repository-commands.md +104 -0
- package/skills/flywheel-reproduce/references/flywheel-cli-tool-map.md +6 -5
- package/skills/flywheel-to-graph/references/flywheel-cli-tool-map.md +6 -5
- package/skills/flywheel-tree/scripts/render_tree.py +23 -24
- package/skills/flywheel-tree/scripts/render_tree_via_mcp.py +29 -28
- package/src/runtime/required-runtime-commands.json +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/graph-operation.js +4 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/graph-operation.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-repository-snapshot.js +10 -4
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-repository-snapshot.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js +65 -10
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js +69 -26
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-operation.js +10 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-operation.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-refusal-hints.js +20 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-refusal-hints.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/types.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/adapter.js +40 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/adapter.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/errors.js +10 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/errors.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/invariants.js +3 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/invariants.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/commits.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/constants.js +6 -4
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/constants.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/operation-identity.js +28 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/operation-identity.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/operations.js +61 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/models/operations.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/conflicts.js +22 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/conflicts.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/context.js +5 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/context.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/pull.js +40 -5
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/pull.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/replay.js +17 -9
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/rebase/replay.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/commit.js +3 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/commit.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/projection.js +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/projection.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/revert.js +3 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/service/revert.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/sync/local-pull.js +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/domain/sync/local-pull.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/projection.js +11 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/projection.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/recover-departed.js +371 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/recover-departed.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/pull.js +4 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/pull.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/push.js +13 -3
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/push.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/transport.js +15 -8
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/remote/transport.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/snapshot-diff.js +19 -4
- package/src/runtime/vendor/flywheel-cli-dist/local/runtime/snapshot-diff.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/apply.js +3 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/store/apply.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/contract.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/diagnostics.js +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/diagnostics.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/steps.js +29 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/steps.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/versions.js +2 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migration/versions.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations/008_boundaries_departures_and_author.sql +59 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations.js +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/store/migrations.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/pending.js +3 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/pending.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/nodes.js +7 -4
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/nodes.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/relations.js +8 -4
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/relations.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/rules.js +15 -6
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/rules.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/tags.js +36 -17
- package/src/runtime/vendor/flywheel-cli-dist/local/store/projection/tags.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/hosted.js +20 -6
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/hosted.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/replace.js +20 -3
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/replace.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/schema.js +2 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/store/snapshot/schema.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/schema.js +5 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/schema.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/store.js +41 -0
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sqlite/store.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sync.js +35 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/store/sync.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/main.js +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/main.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/src/runtime/vendor/flywheel-cli-dist/prebuilds/darwin-x64/node.napi.node +0 -0
- package/src/runtime/vendor/manifest.json +4 -7
package/package.json
CHANGED
package/skills/flywheel/SKILL.md
CHANGED
|
@@ -17,6 +17,7 @@ Use this skill when the conversation is about any of the following:
|
|
|
17
17
|
- setting up, updating, authenticating, or troubleshooting Flywheel MCP
|
|
18
18
|
- configuring hooks, hook secrets, and hook-run monitoring
|
|
19
19
|
- managed compute, local hardware, campaigns, or Flywheel Web UI navigation
|
|
20
|
+
- working in a local Flywheel repository (`repo:*` commands, `.flywheel/`, history, pull, conflicts, push) or administering a hosted repository: hand off to the `flywheel-repo` skill
|
|
20
21
|
|
|
21
22
|
If the request is ambiguous, default to experiment-design guidance before platform mechanics.
|
|
22
23
|
|
|
@@ -50,6 +51,7 @@ Choose one primary file first, then add at most one supporting file only if need
|
|
|
50
51
|
|
|
51
52
|
- `references/experiment-design-protocol.md` for structured experiment design and readiness checks
|
|
52
53
|
- `references/flywheel-mcp-tool-map.md` (MCP) or `references/flywheel-cli-tool-map.md` (CLI) for exact tool surface and contract behavior in the matching install mode
|
|
54
|
+
- the `flywheel-repo` skill for local-repository work (`repo:*`) and hosted repository ownership or membership (`hosted:repository:*`); this skill stays background only
|
|
53
55
|
- `getting-started/flywheel-tutorial-overview.md` for orientation and learning path
|
|
54
56
|
- `getting-started/flywheel-quickstart.md` for fastest first-use setup and auth recovery
|
|
55
57
|
- `setting-up-flywheel/` for host-specific installation and update procedures
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Contract-aligned routing guide for the Flywheel runtime CLI.
|
|
4
4
|
|
|
5
|
-
The Flywheel CLI (`flywheel <command>`) is the runtime command surface shipped by `@paradigma-inc/flywheel`.
|
|
5
|
+
The Flywheel CLI (`flywheel <command>`) is the runtime command surface shipped by `@paradigma-inc/flywheel`. `hosted:` and most other commands call the Flywheel HTTP API and are the parallel surface to Flywheel MCP; `repo:` commands work on a local repository on disk and touch the network only for `repo:clone`, `repo:pull`, `repo:push`, `repo:purge`, and `repo:artifact:download` (which fetches remote-only objects). Use this map when the host install is `--mode cli` (skills installed without an MCP server entry) or whenever scripted / direct-API workflows are preferable to MCP tool calls.
|
|
6
6
|
|
|
7
7
|
For MCP routing, see `flywheel-mcp-tool-map.md`. The families below group related capabilities; CLI repository commands and MCP tools do not share the same staging or commit workflow.
|
|
8
8
|
|
|
@@ -17,6 +17,7 @@ Follow `flywheel-mcp-tool-map.md` for MCP-specific payload and lease workflows.
|
|
|
17
17
|
- `repo:` and `hosted:` commands default to human output. Pass `--format=json` explicitly for scripts; other available formats are listed by command help.
|
|
18
18
|
- Attach an artifact with `flywheel hosted:artifact:attach node <owner-id> --repository-id <uuid> --file <path> --metadata-file artifact.json --format=json`; the CLI prepares the upload, sends raw bytes, and commits the attachment.
|
|
19
19
|
- Mutating commands are subject to per-user write limits: 120 node creates per minute, 2,000 node creates per 24 hours, and 120 graph writes per minute. Graph writes include existing-node commits, edge changes, deletes, merges, tags, sharing, artifact finalization, artifact deletion, and artifact-note updates. On `429`, honor `Retry-After` and retry the same idempotent command after waiting.
|
|
20
|
+
- A `426 client_version_unsupported` or `repository_snapshot_format_unsupported` response means the installed client is incompatible. Run `flywheel update --yes`, retry the original command, and do not discard local state.
|
|
20
21
|
- Run `flywheel help <command>` for canonical per-command flags, types, defaults, examples, and related commands.
|
|
21
22
|
|
|
22
23
|
## CLI Families and Related MCP Operations
|
|
@@ -49,15 +50,15 @@ The families below group CLI capabilities alongside related MCP tools. A related
|
|
|
49
50
|
|
|
50
51
|
### Hosted graph mutations and stage leases
|
|
51
52
|
|
|
52
|
-
- `flywheel hosted:node:create` (mutating; scopes: `write`; MCP equivalent: `flywheel_commit_new_node`): Create a node in
|
|
53
|
+
- `flywheel hosted:node:create` (mutating; scopes: `write`; MCP equivalent: `flywheel_commit_new_node`): Create a node in the hosted repository named by `--repository-id`; this never selects a default workspace or creates another repository.
|
|
53
54
|
- `flywheel nodes:stage:lease:acquire` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/acquire`; MCP equivalent: `flywheel_acquire_stage_lease`): Acquire a session-scoped edit lease for an existing-node MCP staged-payload workflow, not local CLI `repo:` authoring or direct `hosted:` mutations.
|
|
54
55
|
- `flywheel nodes:stage:lease:heartbeat` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/heartbeat`; MCP equivalent: `flywheel_heartbeat_stage_lease`): Heartbeat an active node stage lease.
|
|
55
56
|
- `flywheel nodes:stage:lease:release` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/release`; MCP equivalent: `flywheel_release_stage_lease`): Release a node stage lease.
|
|
56
57
|
- `flywheel hosted:node:set` (mutating; scopes: `write`; MCP equivalent: `flywheel_commit_node`): Set one node field in one hosted commit.
|
|
57
|
-
- `flywheel hosted:node:branch` (mutating; scopes: `write`; MCP equivalent: `flywheel_branch_node`): Create a child branch in
|
|
58
|
-
- `flywheel hosted:node:merge` (mutating; scopes: `write`; MCP equivalent: `flywheel_merge_nodes`): Merge repeated `--source` nodes into one node in
|
|
59
|
-
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; MCP equivalent: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit.
|
|
60
|
-
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; MCP equivalent: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit.
|
|
58
|
+
- `flywheel hosted:node:branch` (mutating; scopes: `write`; MCP equivalent: `flywheel_branch_node`): Create a child branch in the hosted repository named by `--repository-id`. Pass `--expected-head` when the caller must reject concurrent hosted changes.
|
|
59
|
+
- `flywheel hosted:node:merge` (mutating; scopes: `write`; MCP equivalent: `flywheel_merge_nodes`): Merge repeated `--source` nodes into one node in the hosted repository named by `--repository-id`.
|
|
60
|
+
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; MCP equivalent: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit; include `--parent-repository-id` when the parent lives across a repository boundary.
|
|
61
|
+
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; MCP equivalent: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit; include `--parent-repository-id` for a cross-repository parent.
|
|
61
62
|
- `flywheel hosted:node:tombstone` (mutating; scopes: `write`; MCP equivalent: `flywheel_delete_node`): Tombstone one node in one hosted commit.
|
|
62
63
|
- There is no hosted bulk-tombstone command; run `flywheel hosted:node:tombstone` once per node.
|
|
63
64
|
|
|
@@ -18,6 +18,7 @@ The CLI has its own destination and commit lifecycle:
|
|
|
18
18
|
- Every hosted graph mutation requires `--repository-id <uuid>`. For an associated local workspace, read `repository_id` from `flywheel repo:status --repo <path> --format=json`.
|
|
19
19
|
- Node values, tag definitions, edge content, and artifact metadata use the file flags documented by each graph command.
|
|
20
20
|
- `repo:` and `hosted:` commands default to human output. Pass `--format=json` explicitly for scripts; other available formats are listed by command help.
|
|
21
|
+
- A `426 client_version_unsupported` or `repository_snapshot_format_unsupported` response means the installed client is incompatible. Run `flywheel update --yes`, retry the original command, and do not discard local state.
|
|
21
22
|
- Run `flywheel help <command>` for canonical per-command flags, types, defaults, examples, and related commands.
|
|
22
23
|
|
|
23
24
|
## Related MCP Operations
|
|
@@ -50,15 +51,15 @@ The families below identify related MCP operations for discovery and terminology
|
|
|
50
51
|
|
|
51
52
|
### Hosted graph mutations and stage leases
|
|
52
53
|
|
|
53
|
-
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in
|
|
54
|
+
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in the hosted repository named by `--repository-id`; this never selects a default workspace or creates another repository.
|
|
54
55
|
- `flywheel nodes:stage:lease:acquire` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/acquire`; related MCP operation: `flywheel_acquire_stage_lease`): Acquire a session-scoped edit lease for an existing MCP node workflow.
|
|
55
56
|
- `flywheel nodes:stage:lease:heartbeat` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/heartbeat`; related MCP operation: `flywheel_heartbeat_stage_lease`): Heartbeat an active node stage lease.
|
|
56
57
|
- `flywheel nodes:stage:lease:release` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/release`; related MCP operation: `flywheel_release_stage_lease`): Release a node stage lease.
|
|
57
58
|
- `flywheel hosted:node:set` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_node`): Set one node field in one hosted repository commit; it is not an MCP staged-payload commit.
|
|
58
|
-
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in
|
|
59
|
-
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes
|
|
60
|
-
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted repository
|
|
61
|
-
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted repository
|
|
59
|
+
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in the hosted repository named by `--repository-id`. Pass `--expected-head` when the caller must reject concurrent hosted changes.
|
|
60
|
+
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes in the hosted repository named by `--repository-id`.
|
|
61
|
+
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit; include `--parent-repository-id` when the parent lives across a repository boundary.
|
|
62
|
+
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit; include `--parent-repository-id` for a cross-repository parent.
|
|
62
63
|
- `flywheel hosted:node:tombstone` (mutating; scopes: `write`; related MCP operation: `flywheel_delete_node`): Tombstone one node in one hosted repository commit.
|
|
63
64
|
- There is no hosted bulk-tombstone command; run `flywheel hosted:node:tombstone` once per node.
|
|
64
65
|
|
|
@@ -206,7 +206,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
206
206
|
args = parser.parse_args(argv)
|
|
207
207
|
try:
|
|
208
208
|
report = run_check(Path(args.project).expanduser().resolve(), args)
|
|
209
|
-
except
|
|
209
|
+
except (OSError, RuntimeError, ValueError, ET.ParseError) as exc:
|
|
210
210
|
print(f"paper-llm-proof could not complete: {exc}", file=sys.stderr)
|
|
211
211
|
return 3
|
|
212
212
|
|
|
@@ -18,6 +18,7 @@ The CLI has its own destination and commit lifecycle:
|
|
|
18
18
|
- Every hosted graph mutation requires `--repository-id <uuid>`. For an associated local workspace, read `repository_id` from `flywheel repo:status --repo <path> --format=json`.
|
|
19
19
|
- Node values, tag definitions, edge content, and artifact metadata use the file flags documented by each graph command.
|
|
20
20
|
- `repo:` and `hosted:` commands default to human output. Pass `--format=json` explicitly for scripts; other available formats are listed by command help.
|
|
21
|
+
- A `426 client_version_unsupported` or `repository_snapshot_format_unsupported` response means the installed client is incompatible. Run `flywheel update --yes`, retry the original command, and do not discard local state.
|
|
21
22
|
- Run `flywheel help <command>` for canonical per-command flags, types, defaults, examples, and related commands.
|
|
22
23
|
|
|
23
24
|
## Related MCP Operations
|
|
@@ -50,15 +51,15 @@ The families below identify related MCP operations for discovery and terminology
|
|
|
50
51
|
|
|
51
52
|
### Hosted graph mutations and stage leases
|
|
52
53
|
|
|
53
|
-
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in
|
|
54
|
+
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in the hosted repository named by `--repository-id`; this never selects a default workspace or creates another repository.
|
|
54
55
|
- `flywheel nodes:stage:lease:acquire` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/acquire`; related MCP operation: `flywheel_acquire_stage_lease`): Acquire a session-scoped edit lease for an existing MCP node workflow.
|
|
55
56
|
- `flywheel nodes:stage:lease:heartbeat` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/heartbeat`; related MCP operation: `flywheel_heartbeat_stage_lease`): Heartbeat an active node stage lease.
|
|
56
57
|
- `flywheel nodes:stage:lease:release` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/release`; related MCP operation: `flywheel_release_stage_lease`): Release a node stage lease.
|
|
57
58
|
- `flywheel hosted:node:set` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_node`): Set one node field in one hosted repository commit; it is not an MCP staged-payload commit.
|
|
58
|
-
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in
|
|
59
|
-
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes
|
|
60
|
-
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted repository
|
|
61
|
-
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted repository
|
|
59
|
+
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in the hosted repository named by `--repository-id`. Pass `--expected-head` when the caller must reject concurrent hosted changes.
|
|
60
|
+
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes in the hosted repository named by `--repository-id`.
|
|
61
|
+
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit; include `--parent-repository-id` when the parent lives across a repository boundary.
|
|
62
|
+
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit; include `--parent-repository-id` for a cross-repository parent.
|
|
62
63
|
- `flywheel hosted:node:tombstone` (mutating; scopes: `write`; related MCP operation: `flywheel_delete_node`): Tombstone one node in one hosted repository commit.
|
|
63
64
|
- There is no hosted bulk-tombstone command; run `flywheel hosted:node:tombstone` once per node.
|
|
64
65
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import shutil
|
|
2
2
|
from datetime import datetime, timezone
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
4
5
|
|
|
5
6
|
import typer
|
|
6
7
|
from rich import print as rprint
|
|
@@ -137,7 +138,9 @@ def init(build: bool = typer.Option(True, "--build/--no-build")) -> None:
|
|
|
137
138
|
|
|
138
139
|
|
|
139
140
|
@app.command("reindex")
|
|
140
|
-
def reindex(
|
|
141
|
+
def reindex(
|
|
142
|
+
project_dir: Annotated[Path | None, typer.Option("--project-dir")] = None,
|
|
143
|
+
) -> None:
|
|
141
144
|
paths = _paths()
|
|
142
145
|
target = project_dir or paths.lean_project_dir
|
|
143
146
|
all_proofs_path = reindex_allproofs(target)
|
|
@@ -146,10 +149,10 @@ def reindex(project_dir: Path | None = typer.Option(None, "--project-dir")) -> N
|
|
|
146
149
|
|
|
147
150
|
@app.command("start-run")
|
|
148
151
|
def start_run(
|
|
149
|
-
prompt_file: Path | None
|
|
150
|
-
prompt_text: str | None
|
|
151
|
-
run_label: str | None
|
|
152
|
-
context_file: Path | None
|
|
152
|
+
prompt_file: Annotated[Path | None, typer.Option("--prompt-file")] = None,
|
|
153
|
+
prompt_text: Annotated[str | None, typer.Option("--prompt-text")] = None,
|
|
154
|
+
run_label: Annotated[str | None, typer.Option("--run-label")] = None,
|
|
155
|
+
context_file: Annotated[Path | None, typer.Option("--context-file")] = None,
|
|
153
156
|
) -> None:
|
|
154
157
|
paths = _paths()
|
|
155
158
|
task_prompt = read_task_prompt(prompt_file=prompt_file, prompt_text=prompt_text)
|
|
@@ -220,7 +223,9 @@ def set_status(
|
|
|
220
223
|
|
|
221
224
|
|
|
222
225
|
@app.command("verify")
|
|
223
|
-
def verify(
|
|
226
|
+
def verify(
|
|
227
|
+
project_dir: Annotated[Path | None, typer.Option("--project-dir")] = None,
|
|
228
|
+
) -> None:
|
|
224
229
|
paths = _paths()
|
|
225
230
|
target = project_dir or paths.lean_project_dir
|
|
226
231
|
code, output = lake_build(target)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flywheel-repo
|
|
3
|
+
description: "Work in a local Flywheel repository with the flywheel CLI: create or clone, stage, diff, commit, inspect history, pull, resolve conflicts, and, only when asked, push; plus hosted repository ownership and membership. Use for repo:* and hosted:repository:* tasks; use the flywheel skill for direct hosted repository writes, MCP, and setup."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Flywheel Repository Skill
|
|
7
|
+
|
|
8
|
+
A repository is one user's Flywheel project workspace: a graph of nodes with history. A local repository is the on-disk copy of that repository, rooted at a `.flywheel/` directory, with its own staging area and commit log; `repo:` commands operate on it. A hosted repository is the server-side copy that collaborators read through the web app, API, CLI, or MCP; `hosted:` commands change it directly. A staged change is a pending operation that a `repo:` mutation command saved in the local repository but that is not yet part of history. A local commit is the result of `repo:commit`: the staged changes become one entry in the local commit log, and nothing leaves the machine. A hosted commit is one entry in the hosted repository's history; `repo:push` turns local commits into hosted commits, and each `hosted:` mutation posts one hosted commit immediately.
|
|
9
|
+
|
|
10
|
+
## Precondition
|
|
11
|
+
|
|
12
|
+
Run `flywheel --help` first. If `flywheel` is not on `PATH`, use `npx --yes @paradigma-inc/flywheel` in place of `flywheel` for every command in this skill. If neither runs, stop and tell the user the CLI is not available; do not fall back to MCP tools or `hosted:` commands for local-repository work.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- the user wants to create, clone, inspect, edit, commit, back up, or repair a local Flywheel repository
|
|
17
|
+
- the user asks about local history, staged work, a failed pull, a rebase, or conflicts
|
|
18
|
+
- the user asks to publish local commits, or to list, transfer, retire, or change members of a hosted repository
|
|
19
|
+
|
|
20
|
+
Not for: direct hosted node edits (`hosted:node:*`, `hosted:tag:*`, and every other `hosted:*` family except `hosted:repository:*`), MCP tools, setup, or authentication. Use the `flywheel` skill for those.
|
|
21
|
+
|
|
22
|
+
## Rules
|
|
23
|
+
|
|
24
|
+
- Flags are never listed here. Before running any command, run `flywheel help <command>`; use `flywheel help <command> --format=json` when you need to parse the output.
|
|
25
|
+
- Select the local repository explicitly: a `--repo <path>` repository, an explicitly requested `--personal` repository, or a repository found from the current directory. If none is selected, stop and ask; never switch to `hosted:` commands instead.
|
|
26
|
+
- Never run `flywheel repo:push` (with or without `--create-remote`) unless the user asked for or approved publication in this conversation. Staging and `repo:commit` never leave the machine.
|
|
27
|
+
- A 426 `client_version_unsupported` or `repository_snapshot_format_unsupported` response is a client compatibility refusal, not a repository conflict. Run `flywheel update --yes`, retry the original command (snapshot-format negotiation applies only to clone and pull), and never discard local state to work around it.
|
|
28
|
+
- `hosted:repository:transfer`, `hosted:repository:retire`, `hosted:repository:member:set`, and `hosted:repository:member:remove` change who owns or who can read a repository. Run one only on the user's explicit instruction for that exact change, and ask one direct confirmation question naming the repository and the change before running it. Never run one as a side effect of another task. `retire` is irreversible: every node in the repository stops being readable.
|
|
29
|
+
- `repo:purge` and `repo:staging:discard` destroy data. State what will be lost and get the user's confirmation first.
|
|
30
|
+
|
|
31
|
+
## Workflow
|
|
32
|
+
|
|
33
|
+
Each phase names its commands only; look up flags with `flywheel help <command>`.
|
|
34
|
+
|
|
35
|
+
1. Obtain a local repository: `repo:init` creates or adopts only the selected local repository, `repo:clone` reads an existing hosted projection v4 repository, and `repo:restore` reads a backup archive. Then run `repo:status` to confirm the repository is selected and healthy.
|
|
36
|
+
2. Read before writing: `repo:node:get`, `repo:lineage:list`, `repo:tag:list`, `repo:edge:list`, `repo:edge:get`, `repo:containment:list`, `repo:containment:get`, and the artifact reads (`repo:artifact:get`, `repo:artifact:download`, `repo:node-artifact:list`, `repo:edge-artifact:list`). These default to committed local state; the staged option described in each command's help shows pending work instead. Lineage rows name `parent_repository_id`; `boundary:true` means the parent remains in another repository and is not a missing local node.
|
|
37
|
+
3. Stage changes with the node, tag, relation, and artifact commands listed in the reference file. Every `repo:` mutation stages in the selected local repository; nothing is committed or placed in a different repository.
|
|
38
|
+
4. Review with `repo:diff` (its staged option shows the complete pending result). Discard with `repo:staging:discard` only on request.
|
|
39
|
+
5. Commit with `repo:commit`; the commit keeps its immutable author if another principal later pushes it. Inspect history with `repo:log`; undo a commit with `repo:revert`, which stages inverse operations for the reversible changes of that commit.
|
|
40
|
+
6. Sync: `repo:pull` applies hosted history and atomically removes nodes that departed to a reported target repository. On ordinary conflicts, use `repo:conflicts:list`, `repo:conflicts:show`, and `repo:conflicts:resolve`, then `repo:rebase:continue` or `repo:rebase:abort`. Publish with `repo:push` only when requested; its create-remote option is for the first publication only, when the hosted repository does not exist yet (there is no `hosted:repository:create`). If a push fails with `repository_node_departed`, run `repo:recover-departed <current_repository_id> <directory> --repo <source-checkout>` to clone the current repository and replay the unpublished commits there; never redirect the old repository-bound push.
|
|
41
|
+
7. Maintain: `repo:backup` before risky work, `repo:doctor` to diagnose availability or interrupted-sync problems, `repo:gc` to reclaim unreferenced artifact objects; `repo:purge` only on explicit request.
|
|
42
|
+
8. Hosted repository administration: `hosted:repository:list`, `hosted:repository:head`, and `hosted:repository:members` are reads. `hosted:repository:member:set`, `hosted:repository:member:remove`, `hosted:repository:transfer`, and `hosted:repository:retire` follow the confirmation rule above.
|
|
43
|
+
|
|
44
|
+
## Reference
|
|
45
|
+
|
|
46
|
+
- [references/repository-commands.md](references/repository-commands.md): every `repo:*` and `hosted:repository:*` command with its summary, grouped by the phases above.
|
|
47
|
+
- `flywheel help <command>`: flags, positionals, examples, and related commands.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Flywheel Repository Commands
|
|
2
|
+
|
|
3
|
+
Each line names a command and its summary; run `flywheel help <command>` (add `--format=json` for machine-readable output) for flags, positionals, examples, and related commands.
|
|
4
|
+
|
|
5
|
+
## Commands by lifecycle phase
|
|
6
|
+
|
|
7
|
+
### Create or obtain a local repository
|
|
8
|
+
|
|
9
|
+
- `flywheel repo:init`: Initialize or adopt the selected local repository at a directory; this command does not choose a hosted default workspace or fork.
|
|
10
|
+
- `flywheel repo:clone`: Clone a projection v4 hosted repository, including boundary-parent and cross-repository tag-scope identities, into a new local directory. If the server requires a newer client, run `flywheel update --yes` and retry.
|
|
11
|
+
- `flywheel repo:restore`: Restore a verified backup archive into an empty directory.
|
|
12
|
+
|
|
13
|
+
### Inspect state
|
|
14
|
+
|
|
15
|
+
- `flywheel repo:status`: Show local repository status, including interrupted push or pull (interrupted_sync) and an unpublished hosted remote (stranded_remote). Rerun an interrupted command with the same --idempotency-key; stranded_remote names the existing repo:push recovery flow.
|
|
16
|
+
- `flywheel repo:doctor`: Report local object availability disagreements and interrupted push or pull operations (interrupted_sync). Confirmed availability repair changes records only and refuses pending work.
|
|
17
|
+
|
|
18
|
+
### Read committed or staged content
|
|
19
|
+
|
|
20
|
+
- `flywheel repo:node:get`: Read one node and its comparison digests. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
21
|
+
- `flywheel repo:tag:list`: List tags and holder digests. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
22
|
+
- `flywheel repo:lineage:list`: List lineage relations with `parent_repository_id` and boundary status. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
23
|
+
- `flywheel repo:node-artifact:list`: List node artifact references. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
24
|
+
- `flywheel repo:edge-artifact:list`: List edge artifact references. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
25
|
+
- `flywheel repo:artifact:get`: Read one artifact and its references. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
26
|
+
- `flywheel repo:artifact:download`: Download current-head artifact bytes, fetching and caching a remote-only object when needed; requires --out.
|
|
27
|
+
- `flywheel repo:containment:get`: Read active containment for one child. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
28
|
+
- `flywheel repo:containment:list`: List active contained nodes. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
29
|
+
- `flywheel repo:edge:list`: List semantic edges in one graph. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
30
|
+
- `flywheel repo:edge:get`: Read one semantic edge. Defaults to committed local state; use --staged to inspect saved pending work.
|
|
31
|
+
|
|
32
|
+
### Stage changes (nodes)
|
|
33
|
+
|
|
34
|
+
- `flywheel repo:node:create`: Stage a root node in the selected local repository from --title or the full six-field JSON values file; this command never creates or selects another repository.
|
|
35
|
+
- `flywheel repo:node:set`: Stage a new value for one field of a node.
|
|
36
|
+
- `flywheel repo:node:tombstone`: Stage the removal of a node; its history stays in the repository.
|
|
37
|
+
- `flywheel repo:node:restore`: Stage the restoration of a tombstoned node.
|
|
38
|
+
- `flywheel repo:node:branch`: Stage one branched node in the selected local repository and one lineage relation copying the source's title.
|
|
39
|
+
- `flywheel repo:node:merge`: Stage one merged node in the selected local repository and one lineage relation from each supplied source, in argument order.
|
|
40
|
+
|
|
41
|
+
### Stage changes (tags)
|
|
42
|
+
|
|
43
|
+
- `flywheel repo:tag:define`: Stage a new tag definition under a scope node.
|
|
44
|
+
- `flywheel repo:tag:update`: Stage a changed tag definition.
|
|
45
|
+
- `flywheel repo:tag:retire`: Stage the retirement of a tag definition.
|
|
46
|
+
- `flywheel repo:node-tag:assign`: Stage assigning a tag to a node.
|
|
47
|
+
- `flywheel repo:node-tag:remove`: Stage removing a tag from a node.
|
|
48
|
+
|
|
49
|
+
### Stage changes (relations)
|
|
50
|
+
|
|
51
|
+
- `flywheel repo:lineage:add`: Stage a parent-child lineage relation between two nodes.
|
|
52
|
+
- `flywheel repo:lineage:remove`: Stage the removal of a lineage relation.
|
|
53
|
+
- `flywheel repo:containment:assign`: Stage placing a node inside a container node.
|
|
54
|
+
- `flywheel repo:containment:remove`: Stage the removal of a containment relation.
|
|
55
|
+
- `flywheel repo:edge:add`: Stage an edge between distinct descendants of a graph in this repository.
|
|
56
|
+
- `flywheel repo:edge:set-content`: Stage new content for a semantic edge.
|
|
57
|
+
- `flywheel repo:edge:remove`: Stage the removal of a semantic edge.
|
|
58
|
+
|
|
59
|
+
### Stage changes (artifacts)
|
|
60
|
+
|
|
61
|
+
- `flywheel repo:artifact:attach`: Stage an artifact attachment from --metadata-file or the inline --name/--media-type/--notes/--tags flags.
|
|
62
|
+
- `flywheel repo:artifact:detach`: Stage detaching an artifact from its node or edge.
|
|
63
|
+
- `flywheel repo:artifact:set-metadata`: Stage a replacement for exactly one artifact metadata field from --metadata-file or one inline flag.
|
|
64
|
+
|
|
65
|
+
### Review and discard staged work
|
|
66
|
+
|
|
67
|
+
- `flywheel repo:diff`: Show committed-history differences or the complete pending staged result.
|
|
68
|
+
- `flywheel repo:staging:discard`: Discard all saved pending operations and associated values from only the selected local repository. Uncommitted work is not recoverable through graph history. Optional repo:backup preserves the batch, but restoring it does not repair invalid staging. No backup is required or created automatically; no export or network transfer occurs. Discard is never implicit in reads, edits, validation, failed commit, pull, push, revert, startup, migration, or upgrade.
|
|
69
|
+
|
|
70
|
+
### Commit and history
|
|
71
|
+
|
|
72
|
+
- `flywheel repo:commit`: Commit the exact current staging digest with its immutable author principal.
|
|
73
|
+
- `flywheel repo:log`: List commits reachable from the local head, newest first.
|
|
74
|
+
- `flywheel repo:revert`: Append inverse operations for a target commit's supported reversible changes; node/edge latest-value fields and the legacy artifact.metadata.set.v1 operation are not reversible and are skipped.
|
|
75
|
+
|
|
76
|
+
### Sync with the hosted repository
|
|
77
|
+
|
|
78
|
+
- `flywheel repo:pull`: Pull and atomically apply hosted history, preserving boundary references and removing departed nodes while reporting each `target_repository_id`. If the server requires a newer client, run `flywheel update --yes` and retry.
|
|
79
|
+
- `flywheel repo:conflicts:list`: List structured rebase conflicts.
|
|
80
|
+
- `flywheel repo:conflicts:show`: Show one structured conflict.
|
|
81
|
+
- `flywheel repo:conflicts:resolve`: Resolve one structured conflict.
|
|
82
|
+
- `flywheel repo:rebase:continue`: Continue one exact rebase.
|
|
83
|
+
- `flywheel repo:rebase:abort`: Abort one exact rebase.
|
|
84
|
+
- `flywheel repo:push`: Publish local commits to the hosted repository (use --create-remote for the first publication). `repository_node_departed` names `current_repository_id`; the push is never redirected.
|
|
85
|
+
- `flywheel repo:recover-departed`: Clone `current_repository_id` and atomically replay the selected source checkout's unpublished commits there in one client-side follow-up.
|
|
86
|
+
|
|
87
|
+
### Maintenance
|
|
88
|
+
|
|
89
|
+
- `flywheel repo:backup`: Create and verify a local repository backup.
|
|
90
|
+
- `flywheel repo:gc`: Delete local artifact objects that no commit, staging entry, or backup still references.
|
|
91
|
+
- `flywheel repo:purge`: Permanently remove one node from the hosted repository and local history (irreversible; requires --confirm).
|
|
92
|
+
|
|
93
|
+
### Hosted repository administration (reads)
|
|
94
|
+
|
|
95
|
+
- `flywheel hosted:repository:list`: List hosted repositories where you hold a role.
|
|
96
|
+
- `flywheel hosted:repository:head`: Show the published head of a hosted repository.
|
|
97
|
+
- `flywheel hosted:repository:members`: List the collaborators of a hosted repository with their roles (owner or admin only).
|
|
98
|
+
|
|
99
|
+
### Hosted repository administration (writes)
|
|
100
|
+
|
|
101
|
+
- `flywheel hosted:repository:member:set`: Add a collaborator or change their role.
|
|
102
|
+
- `flywheel hosted:repository:member:remove`: Remove a collaborator from a hosted repository.
|
|
103
|
+
- `flywheel hosted:repository:transfer`: Transfer ownership of a hosted repository to another member; you remain admin.
|
|
104
|
+
- `flywheel hosted:repository:retire`: Permanently retire a hosted repository (irreversible; the ID can never be reused). Local clones keep working offline but can no longer sync; publishing the graph again needs repo:init in a new directory plus a re-import under a new identity.
|
|
@@ -19,6 +19,7 @@ The CLI has its own destination and commit lifecycle:
|
|
|
19
19
|
- Every hosted graph mutation requires `--repository-id <uuid>`. For an associated local workspace, read `repository_id` from `flywheel repo:status --repo <path> --format=json`.
|
|
20
20
|
- Node values, tag definitions, edge content, and artifact metadata use the file flags documented by each graph command.
|
|
21
21
|
- `repo:` and `hosted:` commands default to human output. Pass `--format=json` explicitly for scripts; other available formats are listed by command help.
|
|
22
|
+
- A `426 client_version_unsupported` or `repository_snapshot_format_unsupported` response means the installed client is incompatible. Run `flywheel update --yes`, retry the original command, and do not discard local state.
|
|
22
23
|
- Run `flywheel help <command>` for canonical per-command flags, types, defaults, examples, and related commands.
|
|
23
24
|
|
|
24
25
|
## Related MCP Operations
|
|
@@ -51,15 +52,15 @@ The families below identify related MCP operations for discovery and terminology
|
|
|
51
52
|
|
|
52
53
|
### Hosted graph mutations and stage leases
|
|
53
54
|
|
|
54
|
-
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in
|
|
55
|
+
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in the hosted repository named by `--repository-id`; this never selects a default workspace or creates another repository.
|
|
55
56
|
- `flywheel nodes:stage:lease:acquire` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/acquire`; related MCP operation: `flywheel_acquire_stage_lease`): Acquire a session-scoped edit lease for an existing MCP node workflow.
|
|
56
57
|
- `flywheel nodes:stage:lease:heartbeat` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/heartbeat`; related MCP operation: `flywheel_heartbeat_stage_lease`): Heartbeat an active node stage lease.
|
|
57
58
|
- `flywheel nodes:stage:lease:release` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/release`; related MCP operation: `flywheel_release_stage_lease`): Release a node stage lease.
|
|
58
59
|
- `flywheel hosted:node:set` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_node`): Set one node field in one hosted repository commit; it is not an MCP staged-payload commit.
|
|
59
|
-
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in
|
|
60
|
-
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes
|
|
61
|
-
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted repository
|
|
62
|
-
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted repository
|
|
60
|
+
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in the hosted repository named by `--repository-id`. Pass `--expected-head` when the caller must reject concurrent hosted changes.
|
|
61
|
+
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes in the hosted repository named by `--repository-id`.
|
|
62
|
+
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit; include `--parent-repository-id` when the parent lives across a repository boundary.
|
|
63
|
+
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit; include `--parent-repository-id` for a cross-repository parent.
|
|
63
64
|
- `flywheel hosted:node:tombstone` (mutating; scopes: `write`; related MCP operation: `flywheel_delete_node`): Tombstone one node in one hosted repository commit.
|
|
64
65
|
- There is no hosted bulk-tombstone command; run `flywheel hosted:node:tombstone` once per node.
|
|
65
66
|
|
|
@@ -19,6 +19,7 @@ The CLI has its own destination and commit lifecycle:
|
|
|
19
19
|
- Every hosted graph mutation requires `--repository-id <uuid>`. For an associated local workspace, read `repository_id` from `flywheel repo:status --repo <path> --format=json`.
|
|
20
20
|
- Node values, tag definitions, edge content, and artifact metadata use the file flags documented by each graph command.
|
|
21
21
|
- `repo:` and `hosted:` commands default to human output. Pass `--format=json` explicitly for scripts; other available formats are listed by command help.
|
|
22
|
+
- A `426 client_version_unsupported` or `repository_snapshot_format_unsupported` response means the installed client is incompatible. Run `flywheel update --yes`, retry the original command, and do not discard local state.
|
|
22
23
|
- Run `flywheel help <command>` for canonical per-command flags, types, defaults, examples, and related commands.
|
|
23
24
|
|
|
24
25
|
## Related MCP Operations
|
|
@@ -51,15 +52,15 @@ The families below identify related MCP operations for discovery and terminology
|
|
|
51
52
|
|
|
52
53
|
### Hosted graph mutations and stage leases
|
|
53
54
|
|
|
54
|
-
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in
|
|
55
|
+
- `flywheel hosted:node:create` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_new_node`): Create a node in the hosted repository named by `--repository-id`; this never selects a default workspace or creates another repository.
|
|
55
56
|
- `flywheel nodes:stage:lease:acquire` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/acquire`; related MCP operation: `flywheel_acquire_stage_lease`): Acquire a session-scoped edit lease for an existing MCP node workflow.
|
|
56
57
|
- `flywheel nodes:stage:lease:heartbeat` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/heartbeat`; related MCP operation: `flywheel_heartbeat_stage_lease`): Heartbeat an active node stage lease.
|
|
57
58
|
- `flywheel nodes:stage:lease:release` (mutating; scopes: `write`; HTTP: `POST /nodes/{node_id}/stage/lease/release`; related MCP operation: `flywheel_release_stage_lease`): Release a node stage lease.
|
|
58
59
|
- `flywheel hosted:node:set` (mutating; scopes: `write`; related MCP operation: `flywheel_commit_node`): Set one node field in one hosted repository commit; it is not an MCP staged-payload commit.
|
|
59
|
-
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in
|
|
60
|
-
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes
|
|
61
|
-
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted repository
|
|
62
|
-
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted repository
|
|
60
|
+
- `flywheel hosted:node:branch` (mutating; scopes: `write`; related MCP operation: `flywheel_branch_node`): Create a child branch in the hosted repository named by `--repository-id`. Pass `--expected-head` when the caller must reject concurrent hosted changes.
|
|
61
|
+
- `flywheel hosted:node:merge` (mutating; scopes: `write`; related MCP operation: `flywheel_merge_nodes`): Merge repeated `--source` nodes in the hosted repository named by `--repository-id`.
|
|
62
|
+
- `flywheel hosted:lineage:add` (mutating; scopes: `write`; related MCP operation: `flywheel_add_parent`): Add a parent-child lineage relation in one hosted commit; include `--parent-repository-id` when the parent lives across a repository boundary.
|
|
63
|
+
- `flywheel hosted:lineage:remove` (mutating; scopes: `write`; related MCP operation: `flywheel_remove_parent`): Remove a parent-child lineage relation in one hosted commit; include `--parent-repository-id` for a cross-repository parent.
|
|
63
64
|
- `flywheel hosted:node:tombstone` (mutating; scopes: `write`; related MCP operation: `flywheel_delete_node`): Tombstone one node in one hosted repository commit.
|
|
64
65
|
- There is no hosted bulk-tombstone command; run `flywheel hosted:node:tombstone` once per node.
|
|
65
66
|
|
|
@@ -13,10 +13,12 @@ Output:
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
15
|
import argparse
|
|
16
|
+
import io
|
|
16
17
|
import json
|
|
17
18
|
import sys
|
|
19
|
+
from collections.abc import Iterable, Iterator
|
|
18
20
|
from pathlib import Path
|
|
19
|
-
from typing import Any,
|
|
21
|
+
from typing import Any, NamedTuple
|
|
20
22
|
|
|
21
23
|
DEFAULT_COLORS = [
|
|
22
24
|
"\u001b[94m",
|
|
@@ -52,8 +54,8 @@ BOX_SPACE = " "
|
|
|
52
54
|
class Node(NamedTuple):
|
|
53
55
|
title: str
|
|
54
56
|
slug_name: str
|
|
55
|
-
parent_ids:
|
|
56
|
-
child_ids:
|
|
57
|
+
parent_ids: tuple[str, ...]
|
|
58
|
+
child_ids: tuple[str, ...]
|
|
57
59
|
|
|
58
60
|
|
|
59
61
|
def _normalize_ansi(value: str) -> str:
|
|
@@ -92,7 +94,7 @@ def _read_json_from_path(path: str) -> dict:
|
|
|
92
94
|
return _extract_tree_payload(payload)
|
|
93
95
|
|
|
94
96
|
|
|
95
|
-
def _load_palette(asset_path: Path) -> tuple[
|
|
97
|
+
def _load_palette(asset_path: Path) -> tuple[list[str], str]:
|
|
96
98
|
if not asset_path.exists():
|
|
97
99
|
return DEFAULT_COLORS, DEFAULT_RESET
|
|
98
100
|
|
|
@@ -123,8 +125,8 @@ def _clean_text(value: Any) -> str:
|
|
|
123
125
|
return value.strip() if isinstance(value, str) else ""
|
|
124
126
|
|
|
125
127
|
|
|
126
|
-
def _build_node_map(nodes_payload: Iterable[dict]) ->
|
|
127
|
-
node_map:
|
|
128
|
+
def _build_node_map(nodes_payload: Iterable[dict]) -> dict[str, Node]:
|
|
129
|
+
node_map: dict[str, Node] = {}
|
|
128
130
|
|
|
129
131
|
for raw in nodes_payload:
|
|
130
132
|
if not isinstance(raw, dict):
|
|
@@ -159,11 +161,11 @@ def _build_node_map(nodes_payload: Iterable[dict]) -> Dict[str, Node]:
|
|
|
159
161
|
|
|
160
162
|
|
|
161
163
|
def _collect_descendants(
|
|
162
|
-
anchor_node_id: str, node_map:
|
|
163
|
-
) -> tuple[
|
|
164
|
-
descendants:
|
|
165
|
-
order:
|
|
166
|
-
stack:
|
|
164
|
+
anchor_node_id: str, node_map: dict[str, Node]
|
|
165
|
+
) -> tuple[set[str], list[str]]:
|
|
166
|
+
descendants: set[str] = set()
|
|
167
|
+
order: list[str] = []
|
|
168
|
+
stack: list[str] = [anchor_node_id]
|
|
167
169
|
|
|
168
170
|
while stack:
|
|
169
171
|
current = stack.pop()
|
|
@@ -176,8 +178,7 @@ def _collect_descendants(
|
|
|
176
178
|
|
|
177
179
|
descendants.add(current)
|
|
178
180
|
order.append(current)
|
|
179
|
-
|
|
180
|
-
stack.append(child_id)
|
|
181
|
+
stack.extend(reversed(node.child_ids))
|
|
181
182
|
|
|
182
183
|
return descendants, order
|
|
183
184
|
|
|
@@ -218,8 +219,8 @@ def _iter_render_lines(
|
|
|
218
219
|
if anchor not in descendants:
|
|
219
220
|
raise ValueError(f"Could not build descendant subgraph for anchor '{anchor}'.")
|
|
220
221
|
|
|
221
|
-
retained_children:
|
|
222
|
-
multi_parent_nodes:
|
|
222
|
+
retained_children: dict[str, tuple[str, ...]] = {}
|
|
223
|
+
multi_parent_nodes: list[str] = []
|
|
223
224
|
|
|
224
225
|
for node_id in ordered_descendants:
|
|
225
226
|
node = node_map[node_id]
|
|
@@ -239,13 +240,13 @@ def _iter_render_lines(
|
|
|
239
240
|
_load_palette(palette_path) if palette_path else (DEFAULT_COLORS, DEFAULT_RESET)
|
|
240
241
|
)
|
|
241
242
|
|
|
242
|
-
multi_parent_color:
|
|
243
|
+
multi_parent_color: dict[str, str] = {}
|
|
243
244
|
for idx, node_id in enumerate(multi_parent_nodes):
|
|
244
245
|
multi_parent_color[node_id] = colors[idx % len(colors)]
|
|
245
246
|
|
|
246
|
-
seen_multi_parent:
|
|
247
|
-
ancestry:
|
|
248
|
-
expanded_nodes:
|
|
247
|
+
seen_multi_parent: dict[str, int] = {node_id: 0 for node_id in multi_parent_nodes}
|
|
248
|
+
ancestry: set[str] = set()
|
|
249
|
+
expanded_nodes: set[str] = set()
|
|
249
250
|
|
|
250
251
|
def line_for(node_id: str) -> str:
|
|
251
252
|
node = node_map[node_id]
|
|
@@ -274,7 +275,7 @@ def _iter_render_lines(
|
|
|
274
275
|
return rendered
|
|
275
276
|
|
|
276
277
|
# Iterative DFS avoids RecursionError on very deep trees.
|
|
277
|
-
stack:
|
|
278
|
+
stack: list[tuple[Any, ...]] = [("enter", anchor, "", True, True)]
|
|
278
279
|
|
|
279
280
|
while stack:
|
|
280
281
|
frame = stack.pop()
|
|
@@ -365,10 +366,8 @@ def main() -> int:
|
|
|
365
366
|
print(f"render_tree.py error: {exc}", file=sys.stderr)
|
|
366
367
|
return 1
|
|
367
368
|
|
|
368
|
-
|
|
369
|
-
sys.stdout.reconfigure(encoding="utf-8")
|
|
370
|
-
except Exception: # noqa: BLE001
|
|
371
|
-
pass
|
|
369
|
+
if isinstance(sys.stdout, io.TextIOWrapper):
|
|
370
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
372
371
|
|
|
373
372
|
wrote_any = False
|
|
374
373
|
for line in rendered_lines:
|