reffy-cli 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,7 +33,8 @@ Command summary:
33
33
  - `reffy plan create`: generates proposal, task, design, and spec scaffolds from indexed Reffy artifacts.
34
34
  - `reffy plan validate|list|show|archive`: manages the planning lifecycle under `.reffy/reffyspec/`.
35
35
  - `reffy spec list|show`: inspects current spec state under `.reffy/reffyspec/`.
36
- - `reffy remote init|status|push|ls|cat`: links, publishes, and inspects a Paseo-backed remote `.reffy/` workspace.
36
+ - `reffy remote init|status|push|ls|cat|snapshot`: links, publishes, and inspects a Paseo-backed remote `.reffy/` workspace.
37
+ - `reffy remote workspace create|get` and `reffy remote project register|list`: control-plane operations against the workspace manager actor.
37
38
  - `reffy diagram render`: renders Mermaid diagrams as SVG or ASCII, including spec-aware generation from compatible `spec.md` files.
38
39
 
39
40
  Output modes:
@@ -67,70 +68,113 @@ reffy diagram render --input .reffy/reffyspec/specs/auth/spec.md --format svg --
67
68
 
68
69
  ## Remote Sync
69
70
 
70
- Reffy can publish the local `.reffy/` workspace to a Paseo-backed remote actor and inspect it later with native CLI commands.
71
+ Reffy can publish the local `.reffy/` workspace to a Paseo-backed remote workspace and inspect it later with native CLI commands.
72
+
73
+ The Paseo remote splits into two actor surfaces:
74
+
75
+ - `reffyWorkspaceManager.v1` is the **control plane**. It owns workspace lifecycle (create / get) and project registration.
76
+ - `reffyRemoteBackend.v2` is the **storage plane**. One actor instance represents one shared `workspace_id` and accepts contributions keyed by `project_id`.
77
+
78
+ Reffy stores manager identity once per linkage file and the workspace backend identity per `workspace_id`.
71
79
 
72
80
  The current remote flow is:
73
81
 
74
82
  1. Reffy reads `project_id` and `workspace_ids` from `.reffy/manifest.json`.
75
83
  2. You select one workspace projection to act on. Reffy infers the selection when `workspace_ids` has exactly one entry; otherwise pass `--workspace-id <id>`.
76
- 3. Reffy connects to Paseo using `PASEO_ENDPOINT` or `--endpoint`.
77
- 4. `reffy remote init --provision` creates a pod and a `reffyRemoteBackend.v2` actor for the selected workspace id when needed, then writes local linkage state to `.reffy/state/remote.json`.
78
- 5. `reffy remote push` publishes the full local `.reffy/` tree to the selected projection through `/workspaces/{workspace_id}/...` with `replace_missing=true` by default, scoped to that workspace id.
79
- 6. `reffy remote status|ls|cat` inspects the selected workspace projection using the saved linkage state unless you override it.
84
+ 3. Reffy connects to Paseo using `PASEO_ENDPOINT` or `--endpoint` and configured manager identity.
85
+ 4. `reffy remote init` resolves (or creates) the workspace through the manager, persists the workspace backend identity, and registers the local `project_id` for that workspace.
86
+ 5. `reffy remote push` registers the project if needed (idempotent on 409), then imports the full local `.reffy/` tree through `POST /workspace/projects/{project_id}/import` on the workspace backend actor with `replace_missing=true`.
87
+ 6. `reffy remote status|ls|cat|snapshot` inspects the selected workspace projection per project on the workspace backend actor.
80
88
 
81
- One backend actor can serve multiple workspace projections for the same source `project_id`: Reffy stores one target per `workspace_id` in `.reffy/state/remote.json`, and the backend isolates documents and locks by `(workspace_id, path)`.
89
+ ### Bearer-token authentication
82
90
 
83
- ### Minimal connection requirement
91
+ Every Paseo request from the CLI carries `Authorization: Bearer ${PASEO_TOKEN}`. The token is the only thing that grants access — manager / workspace-backend identifiers in `.reffy/state/remote.json` are inert without it.
84
92
 
85
- For the fresh-provision path, the only required connection value is:
93
+ Required env for any remote command:
94
+
95
+ ```bash
96
+ PASEO_ENDPOINT="https://your-paseo-endpoint.example"
97
+ PASEO_TOKEN="<bearer token issued by manager provisioning>"
98
+ ```
86
99
 
87
- - `PASEO_ENDPOINT`
100
+ Both must be present; the CLI fails fast and names the missing variable before issuing any network call. Endpoint is **never** persisted to `remote.json`. The token is **never** persisted anywhere by the CLI.
88
101
 
89
- Example `.env`:
102
+ ### First-time provisioning
90
103
 
91
104
  ```bash
92
- PASEO_ENDPOINT="https://your-paseo-endpoint.example"
105
+ PASEO_ENDPOINT="https://your-paseo-endpoint.example" reffy remote init --provision
93
106
  ```
94
107
 
95
- That is enough for:
108
+ `--provision` creates a fresh pod and `reffyWorkspaceManager.v1` actor. The manager mints a bearer token and the CLI prints it once with strong "save this now" guidance. Save it to your team secret store immediately — the CLI does not keep a copy.
109
+
110
+ After provisioning, export it for subsequent commands:
96
111
 
97
112
  ```bash
98
- reffy remote init --provision
113
+ export PASEO_TOKEN="<token from init output>"
114
+ reffy remote status
99
115
  ```
100
116
 
101
117
  Optional overrides:
102
118
 
103
- - `PASEO_POD_NAME` if you want to reuse an existing Paseo pod
104
- - `PASEO_ACTOR_ID` if you want to reuse an existing backend actor
105
- - `--workspace-id <id>` (or `PASEO_WORKSPACE_ID` for the helper script) when the manifest lists more than one `workspace_ids`
119
+ - `PASEO_MANAGER_POD` and `PASEO_MANAGER_ACTOR` (or `--manager-pod` / `--manager-actor`) to reuse an existing manager actor instead of provisioning one.
120
+ - `--workspace-id <id>` when the manifest lists more than one `workspace_ids`.
121
+ - `--create` or `--resolve` to force-create or force-resolve the workspace through the manager during init. The default is "resolve when present, create when absent."
122
+
123
+ ### Joining an existing manager from another repo
106
124
 
107
- Reffy does not require separate `REFFY_PROJECT_ID` values for the normal case because source identity comes from `.reffy/manifest.json`.
125
+ Drop the team's shared values into the new repo's `.env`:
126
+
127
+ ```bash
128
+ PASEO_ENDPOINT="..."
129
+ PASEO_TOKEN="..."
130
+ PASEO_MANAGER_POD="..."
131
+ PASEO_MANAGER_ACTOR="..."
132
+ ```
133
+
134
+ Then `reffy remote init --workspace-id <id>` resolves the workspace through the manager and registers the local project. No `--provision`, no new token issuance.
108
135
 
109
136
  ### Saved remote linkage
110
137
 
111
- After `reffy remote init`, Reffy stores the local pointer to the linked backend actor in:
138
+ After `reffy remote init`, Reffy stores manager and workspace-backend identifiers in:
112
139
 
113
140
  - `.reffy/state/remote.json`
114
141
 
115
- That file maps each selected `workspace_id` to the backend target Reffy should use for that projection:
116
-
117
142
  ```json
118
143
  {
119
- "version": 2,
144
+ "version": 4,
120
145
  "provider": "paseo",
121
- "endpoint": "https://paseo.example",
146
+ "manager": { "pod_name": "...", "actor_id": "..." },
122
147
  "targets": {
123
- "my-project": { "pod_name": "...", "actor_id": "...", "last_imported_at": "..." },
124
- "portfolio-alpha": { "pod_name": "...", "actor_id": "..." }
148
+ "my-project": {
149
+ "workspace_backend": { "pod_name": "...", "actor_id": "..." },
150
+ "last_imported_at": "..."
151
+ },
152
+ "portfolio-alpha": {
153
+ "workspace_backend": { "pod_name": "...", "actor_id": "..." }
154
+ }
125
155
  }
126
156
  }
127
157
  ```
128
158
 
129
- Multiple targets can share the same `pod_name` and `actor_id` the backend addresses each projection separately through `/workspaces/{workspace_id}/...`.
159
+ Each `workspace_id` is its own backend actor. Manager identity is shared across workspaces in this linkage file.
160
+
161
+ The file deliberately does **not** contain the Paseo endpoint URL or the bearer token. Both are sourced from environment configuration on every command. Without `PASEO_TOKEN`, the identifiers in this file grant nothing.
162
+
163
+ If `workspace_backend` for a workspace is missing or stale, Reffy automatically resolves it through the manager and refreshes the linkage file before continuing.
164
+
165
+ ### Control-plane subcommands
166
+
167
+ ```bash
168
+ reffy remote workspace create <workspace-id> [--label "Pretty name"]
169
+ reffy remote workspace get <workspace-id>
170
+ reffy remote workspace delete <workspace-id> --yes
171
+ reffy remote project register [--workspace-id <id>] [--project-id <id>]
172
+ reffy remote project list [--workspace-id <id>]
173
+ ```
130
174
 
131
- This file is local runtime state. It is not part of the synced remote workspace and is intentionally excluded from `reffy remote push`.
175
+ `workspace delete` is destructive (it removes the shared workspace and all of its contributions) and requires `--yes` to proceed. The CLI also drops the workspace entry from the local linkage file on success, and treats a `404` from the manager as an idempotent "already gone" outcome.
132
176
 
133
- The file can also record local sync metadata such as the last successful import timestamp. That metadata is for local diagnostics and does not become part of the remote workspace contract.
177
+ These talk directly to the manager actor and let you provision or inspect state without re-running `init`.
134
178
 
135
179
  ### Example flow
136
180
 
@@ -141,22 +185,22 @@ reffy remote status
141
185
  reffy remote push
142
186
  reffy remote ls
143
187
  reffy remote cat .reffy/manifest.json
188
+ reffy remote snapshot
144
189
  ```
145
190
 
146
- `reffy remote status` is the primary diagnostic command for this flow. It reports:
191
+ `reffy remote status` reports:
147
192
 
148
- - the saved linkage being used for the selected workspace id
193
+ - the saved manager and workspace backend linkage for the selected workspace id
149
194
  - the local manifest identity (source `project_id` and selected `workspace_id`)
150
- - the remote identity returned from v2 (`source.actor_type`, `source.version`, `source.project_id`, `workspace.workspace_id`)
151
- - remote document counts when reachable
195
+ - the remote workspace identity (`workspace.workspace_id`, `source.actor_type`, `source.version`)
196
+ - remote document counts and registered project counts when available
152
197
 
153
198
  `reffy remote push` reports:
154
199
 
200
+ - whether the project was newly registered or already registered
155
201
  - local document count
156
- - imported count
157
- - created count
158
- - updated count
159
- - deleted count
202
+ - imported / created / updated / deleted counts
203
+ - last imported timestamp
160
204
 
161
205
  That makes the default prune/import behavior auditable without dropping to direct backend API calls.
162
206