cinna-cli 0.2.4__tar.gz → 0.2.6__tar.gz

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 (91) hide show
  1. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/PKG-INFO +37 -2
  2. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/README.md +35 -0
  3. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/README.md +3 -0
  4. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/account_workspace/account_workspace.md +8 -0
  5. cinna_cli-0.2.6/docs/features/improvement_requests/improvement_requests.md +140 -0
  6. cinna_cli-0.2.6/docs/features/improvement_requests/improvement_requests_acceptance.md +256 -0
  7. cinna_cli-0.2.6/docs/features/improvement_requests/improvement_requests_tech.md +141 -0
  8. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/pyproject.toml +1 -1
  9. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/account.py +82 -0
  10. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/chat.py +51 -1
  11. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/client.py +88 -0
  12. cinna_cli-0.2.6/src/cinna/improve.py +697 -0
  13. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/main.py +100 -0
  14. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/templates/ACCOUNT_CLAUDE.md.template +25 -2
  15. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_account.py +83 -0
  16. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_chat.py +106 -0
  17. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_client.py +40 -0
  18. cinna_cli-0.2.6/tests/test_improve.py +847 -0
  19. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/uv.lock +1 -1
  20. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/.claude/commands/cinna-cli.feature.doc.md +0 -0
  21. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/.github/workflows/publish.yml +0 -0
  22. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/.gitignore +0 -0
  23. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/LICENSE.md +0 -0
  24. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/account_workspace/account_workspace_acceptance.md +0 -0
  25. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/account_workspace/account_workspace_tech.md +0 -0
  26. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_api/agent_api.md +0 -0
  27. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_api/agent_api_acceptance.md +0 -0
  28. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_api/agent_api_tech.md +0 -0
  29. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_management/agent_management.md +0 -0
  30. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_management/agent_management_acceptance.md +0 -0
  31. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_management/agent_management_tech.md +0 -0
  32. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_schedules/agent_schedules.md +0 -0
  33. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_schedules/agent_schedules_acceptance.md +0 -0
  34. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/agent_schedules/agent_schedules_tech.md +0 -0
  35. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/bootstrap_onboarding/bootstrap_onboarding.md +0 -0
  36. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/bootstrap_onboarding/bootstrap_onboarding_acceptance.md +0 -0
  37. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/bootstrap_onboarding/bootstrap_onboarding_tech.md +0 -0
  38. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/doctor/doctor.md +0 -0
  39. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/doctor/doctor_acceptance.md +0 -0
  40. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/doctor/doctor_tech.md +0 -0
  41. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/git_versioning/git_versioning.md +0 -0
  42. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/git_versioning/git_versioning_acceptance.md +0 -0
  43. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/git_versioning/git_versioning_tech.md +0 -0
  44. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/live_sync/live_sync.md +0 -0
  45. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/live_sync/live_sync_acceptance.md +0 -0
  46. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/live_sync/live_sync_tech.md +0 -0
  47. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/mcp_integration/mcp_integration.md +0 -0
  48. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/mcp_integration/mcp_integration_acceptance.md +0 -0
  49. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/mcp_integration/mcp_integration_tech.md +0 -0
  50. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_chat/remote_chat.md +0 -0
  51. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_chat/remote_chat_acceptance.md +0 -0
  52. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_chat/remote_chat_tech.md +0 -0
  53. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_exec/remote_exec.md +0 -0
  54. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_exec/remote_exec_acceptance.md +0 -0
  55. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/features/remote_exec/remote_exec_tech.md +0 -0
  56. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/interface.md +0 -0
  57. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/docs/mutagen_capabilities.md +0 -0
  58. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/scripts/check_docs_references.py +0 -0
  59. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/__init__.py +0 -0
  60. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/auth.py +0 -0
  61. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/bootstrap.py +0 -0
  62. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/config.py +0 -0
  63. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/console.py +0 -0
  64. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/context.py +0 -0
  65. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/doctor.py +0 -0
  66. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/errors.py +0 -0
  67. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/git_versioning.py +0 -0
  68. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/logging.py +0 -0
  69. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/mcp_proxy.py +0 -0
  70. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/mutagen_runtime.py +0 -0
  71. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/sync.py +0 -0
  72. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/sync_session.py +0 -0
  73. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/sync_ssh_shim.py +0 -0
  74. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/sync_tui.py +0 -0
  75. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/templates/CHAT_TESTING.md +0 -0
  76. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/templates/CLAUDE.md.template +0 -0
  77. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/templates/GIT_VERSIONING.md +0 -0
  78. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/src/cinna/templates/__init__.py +0 -0
  79. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/__init__.py +0 -0
  80. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/conftest.py +0 -0
  81. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_auth.py +0 -0
  82. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_bootstrap.py +0 -0
  83. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_config.py +0 -0
  84. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_context.py +0 -0
  85. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_doctor.py +0 -0
  86. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_git_versioning.py +0 -0
  87. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_main.py +0 -0
  88. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_mutagen_runtime.py +0 -0
  89. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_sync.py +0 -0
  90. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_sync_session.py +0 -0
  91. {cinna_cli-0.2.4 → cinna_cli-0.2.6}/tests/test_sync_ssh_shim.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: cinna-cli
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Local development CLI for Cinna Core agents
5
5
  Project-URL: Homepage, https://github.com/opencinna/cinna-cli
6
6
  Project-URL: Repository, https://github.com/opencinna/cinna-cli
@@ -167,6 +167,8 @@ List the agents your account can access (run from inside the account workspace).
167
167
 
168
168
  One-shot summary of the account workspace: platform/frontend URLs, machine name, synced-agent count, and an account-token probe (`valid token` / `expired token` / `no connection`) — the account-level counterpart of `cinna status`.
169
169
 
170
+ Also reports the workspace's **context package version** against the platform's current one — the orchestrator guides ship in that tree, so a workspace set up before a guide existed silently lacks it. When it is behind, the command says so and points at `cinna account refresh-context`; `cinna improve list` prints the same nudge, since its playbook lives there.
171
+
170
172
  ### `cinna account refresh-context`
171
173
 
172
174
  Re-download the context package and replace the account workspace's `context/` tree (run from inside the account workspace). Use it when the platform ships updated docs or API reference. The existing tree is only removed after a successful download — a failed refresh warns and leaves the previous `context/` intact.
@@ -200,6 +202,39 @@ cinna account credentials delete <cred_id> --yes
200
202
 
201
203
  A new draft lands in the account's [active user workspace](#cinna-account-user-workspace-list--activate-nameid--clear). Deletes reuse the platform's blast-radius gate (a publisher-provided credential in a published bundle with active installs needs `--force`). All write verbs require the `agent-developer` role.
202
204
 
205
+ ### `cinna improve list | show | download | status`
206
+
207
+ Work the **improvement requests** users shared with you about your agents. When someone chatting with an agent hits a bad answer, they can hand the agent's owner a frozen snapshot of that one session — the transcript plus the runtime context that produced it (bundle id + installed version, environment, SDK engine, effective model) — from the session menu or with the `/session-improve` command. These verbs are the receiving half of that loop, and they run from an account workspace so one listing spans every agent you own.
208
+
209
+ ```bash
210
+ cinna improve list --status new # unhandled first, then newest
211
+ cinna improve list --agent crm-agent # narrow to one agent
212
+ cinna improve show 3f2504e0 # the report + the runtime context block
213
+ cinna improve download 3f2504e0 # → improvements/3f2504e0/
214
+ cinna improve status 3f2504e0 in_progress # claim it
215
+ cinna improve status 3f2504e0 completed --note "Fixed in v1.6 — no longer re-asks for the file."
216
+ ```
217
+
218
+ `<id>` is the short id printed by `cinna improve list` (or the full UUID). `download` saves and extracts the archive into `improvements/<short-id>/` under the account root (`--out DIR` to choose another target), using the same safe extractor as the workspace clone:
219
+
220
+ ```
221
+ improvements/3f2504e0/
222
+ ├── README.md # what was reported, by whom, which agent + bundle version, runtime table
223
+ ├── metadata.json # the request row
224
+ ├── context.json # structured runtime context of the install that misbehaved
225
+ ├── prompts/ # the install's live prompt docs (WORKFLOW_PROMPT.md, …) + a divergence README
226
+ ├── memory/ # the agent's captured personal memory, when it had any
227
+ └── session/
228
+ ├── messages.md # human-readable transcript
229
+ └── messages.json # the same transcript, structured
230
+ ```
231
+
232
+ `cinna improve show` renders the prompt block as a per-prompt **in sync / diverged** table against the installed bundle revision — the one thing a publisher cannot see from their own copy, since a consumer who owns their install can edit its prompts. A diverged prompt means the session was produced by text that is not yours; read `prompts/` in the archive before assuming otherwise.
233
+
234
+ The archive deliberately contains **no** container logs, **no** uploaded file contents (descriptors only), and no credential values (snapshot text is scrubbed server-side before it is stored). Statuses are `new` → `in_progress` → `completed` | `declined`; the `--note` on a closing transition is **shown to the requester**. `--json` on `list` / `show` prints the raw payload for scripting.
235
+
236
+ The archive is another person's conversation: don't copy it into an agent workspace, don't commit it, and delete the local copy when you're done. The end-to-end playbook a local coding agent should follow — including where a fix has to land for a bundle publisher install versus a standalone agent — ships in the account workspace's context package at `context/guides/handling-improvement-requests.md`.
237
+
203
238
  ### `cinna agent create <name> [--description TEXT]`
204
239
 
205
240
  Create a new agent on the platform from the account workspace — no UI interaction. Thin client: only the name (and optional description) is sent; the backend applies all defaults (default AI credentials, env template, environment creation) exactly as creating from the UI does. The agent is created in the account's [active user workspace](#cinna-account-user-workspace-list--activate-nameid--clear) (if one is set). Prints the created agent's ID and web UI link, plus a hint to attach a local workspace with `cinna agent sync <name>`. Requires the `agent-developer` role (403 otherwise). Template selection is not supported yet — agents always get the server default.
@@ -130,6 +130,8 @@ List the agents your account can access (run from inside the account workspace).
130
130
 
131
131
  One-shot summary of the account workspace: platform/frontend URLs, machine name, synced-agent count, and an account-token probe (`valid token` / `expired token` / `no connection`) — the account-level counterpart of `cinna status`.
132
132
 
133
+ Also reports the workspace's **context package version** against the platform's current one — the orchestrator guides ship in that tree, so a workspace set up before a guide existed silently lacks it. When it is behind, the command says so and points at `cinna account refresh-context`; `cinna improve list` prints the same nudge, since its playbook lives there.
134
+
133
135
  ### `cinna account refresh-context`
134
136
 
135
137
  Re-download the context package and replace the account workspace's `context/` tree (run from inside the account workspace). Use it when the platform ships updated docs or API reference. The existing tree is only removed after a successful download — a failed refresh warns and leaves the previous `context/` intact.
@@ -163,6 +165,39 @@ cinna account credentials delete <cred_id> --yes
163
165
 
164
166
  A new draft lands in the account's [active user workspace](#cinna-account-user-workspace-list--activate-nameid--clear). Deletes reuse the platform's blast-radius gate (a publisher-provided credential in a published bundle with active installs needs `--force`). All write verbs require the `agent-developer` role.
165
167
 
168
+ ### `cinna improve list | show | download | status`
169
+
170
+ Work the **improvement requests** users shared with you about your agents. When someone chatting with an agent hits a bad answer, they can hand the agent's owner a frozen snapshot of that one session — the transcript plus the runtime context that produced it (bundle id + installed version, environment, SDK engine, effective model) — from the session menu or with the `/session-improve` command. These verbs are the receiving half of that loop, and they run from an account workspace so one listing spans every agent you own.
171
+
172
+ ```bash
173
+ cinna improve list --status new # unhandled first, then newest
174
+ cinna improve list --agent crm-agent # narrow to one agent
175
+ cinna improve show 3f2504e0 # the report + the runtime context block
176
+ cinna improve download 3f2504e0 # → improvements/3f2504e0/
177
+ cinna improve status 3f2504e0 in_progress # claim it
178
+ cinna improve status 3f2504e0 completed --note "Fixed in v1.6 — no longer re-asks for the file."
179
+ ```
180
+
181
+ `<id>` is the short id printed by `cinna improve list` (or the full UUID). `download` saves and extracts the archive into `improvements/<short-id>/` under the account root (`--out DIR` to choose another target), using the same safe extractor as the workspace clone:
182
+
183
+ ```
184
+ improvements/3f2504e0/
185
+ ├── README.md # what was reported, by whom, which agent + bundle version, runtime table
186
+ ├── metadata.json # the request row
187
+ ├── context.json # structured runtime context of the install that misbehaved
188
+ ├── prompts/ # the install's live prompt docs (WORKFLOW_PROMPT.md, …) + a divergence README
189
+ ├── memory/ # the agent's captured personal memory, when it had any
190
+ └── session/
191
+ ├── messages.md # human-readable transcript
192
+ └── messages.json # the same transcript, structured
193
+ ```
194
+
195
+ `cinna improve show` renders the prompt block as a per-prompt **in sync / diverged** table against the installed bundle revision — the one thing a publisher cannot see from their own copy, since a consumer who owns their install can edit its prompts. A diverged prompt means the session was produced by text that is not yours; read `prompts/` in the archive before assuming otherwise.
196
+
197
+ The archive deliberately contains **no** container logs, **no** uploaded file contents (descriptors only), and no credential values (snapshot text is scrubbed server-side before it is stored). Statuses are `new` → `in_progress` → `completed` | `declined`; the `--note` on a closing transition is **shown to the requester**. `--json` on `list` / `show` prints the raw payload for scripting.
198
+
199
+ The archive is another person's conversation: don't copy it into an agent workspace, don't commit it, and delete the local copy when you're done. The end-to-end playbook a local coding agent should follow — including where a fix has to land for a bundle publisher install versus a standalone agent — ships in the account workspace's context package at `context/guides/handling-improvement-requests.md`.
200
+
166
201
  ### `cinna agent create <name> [--description TEXT]`
167
202
 
168
203
  Create a new agent on the platform from the account workspace — no UI interaction. Thin client: only the name (and optional description) is sent; the backend applies all defaults (default AI credentials, env template, environment creation) exactly as creating from the UI does. The agent is created in the account's [active user workspace](#cinna-account-user-workspace-list--activate-nameid--clear) (if one is set). Prints the created agent's ID and web UI link, plus a hint to attach a local workspace with `cinna agent sync <name>`. Requires the `agent-developer` role (403 otherwise). Template selection is not supported yet — agents always get the server default.
@@ -200,6 +200,7 @@ main.py (CLI commands — Click)
200
200
  ├── account.py — account workspace; `cinna login` (device auth), `cinna account`, `cinna agent`
201
201
  ├── doctor.py — `cinna doctor`: reconcile registry ↔ Mutagen, delete stalled / terminate active sessions, refresh tokens
202
202
  ├── chat.py — `cinna chat`: session-backed conversation testing (poll + NDJSON) over the api-proxy
203
+ ├── improve.py — `cinna improve`: improvement requests users shared about your agents (list/show/download/status)
203
204
  ├── config.py — .cinna/config.json: load/save/find
204
205
  ├── auth.py — JWT storage, Authorization headers
205
206
  ├── client.py — PlatformClient: HTTP + SSE stream_exec
@@ -287,6 +288,7 @@ authoring convention.
287
288
  | **Agent API** | `cinna agent-api` (enable, refresh, spec, call) · `cinna api` · `cinna connect agent-api` | [business](features/agent_api/agent_api.md) · [tech](features/agent_api/agent_api_tech.md) · [acceptance](features/agent_api/agent_api_acceptance.md) |
288
289
  | **MCP integration** | `cinna connect mcp` · `cinna mcp-proxy` (knowledge stdio server) | [business](features/mcp_integration/mcp_integration.md) · [tech](features/mcp_integration/mcp_integration_tech.md) · [acceptance](features/mcp_integration/mcp_integration_acceptance.md) |
289
290
  | **Git versioning** | `cinna git` (link, status, commit, push, pull, log, checkout, unlink) | [business](features/git_versioning/git_versioning.md) · [tech](features/git_versioning/git_versioning_tech.md) · [acceptance](features/git_versioning/git_versioning_acceptance.md) |
291
+ | **Improvement requests** | `cinna improve` (list, show, download, status) | [business](features/improvement_requests/improvement_requests.md) · [tech](features/improvement_requests/improvement_requests_tech.md) · [acceptance](features/improvement_requests/improvement_requests_acceptance.md) |
290
292
 
291
293
  The sections below (Git Versioning, Sync Transport, Remote Exec, Remote Chat,
292
294
  Bootstrap Flow) remain as in-README quick references and backend contracts; the
@@ -610,6 +612,7 @@ When a CLI token expires (or is revoked) the normal remedy is `cinna set-token <
610
612
  | POST | `/api/v1/cli/account/agents/{id}/mint` | Account token | Mint a per-agent CLI token (`cinna agent sync`, `cinna doctor` re-mint) |
611
613
  | POST | `/api/v1/cli/account/api-proxy` | Account token | Buffered JSON escape hatch — `cinna api`, and the transport for every `cinna chat` session/message call |
612
614
  | POST | `/api/v1/cli/account/files/upload` | Account token | Multipart upload for `cinna chat --file` (the proxy can't carry multipart) |
615
+ | GET/PATCH | `/api/v1/cli/account/improvement-requests[/{id}[/archive]]` | Account token | Improvement requests received on the agents the account owns (`cinna improve`); the `/archive` route returns a binary ZIP the JSON-only proxy can't carry |
613
616
 
614
617
  `cinna chat` reaches the conversation API **through** the api-proxy (so these are inner routes, not CLI routes): `POST /sessions/`, `GET /sessions/{id}`, `GET /sessions/{id}/messages`, `POST /sessions/{id}/messages/stream`, `GET /sessions/{id}/messages/streaming-status`, `POST /sessions/{id}/messages/interrupt`, and `GET /files/{id}/download`.
615
618
 
@@ -196,6 +196,14 @@ cinna account setup ────────────────────
196
196
  - **Remote Chat** — `cinna chat` runs through the account workspace's api-proxy
197
197
  (`AccountClient`), so it needs an account workspace; it is found by walking up
198
198
  from the cwd, exactly like the account verbs.
199
+ - **Context package freshness** — `cinna account status` reports the local
200
+ `context/VERSION` against the platform's current package version and nudges
201
+ when it is behind, since guides (not just docs) ship in that tree.
202
+ - **Improvement requests** — `cinna improve` runs on the account token from the
203
+ same root, so one queue spans every agent the account owns; the orchestrator
204
+ `CLAUDE.md` written here lists its verbs and `cinna account agents` supplies the
205
+ publisher-install flag its ownership step depends on. See
206
+ [improvement_requests](../improvement_requests/improvement_requests.md).
199
207
  - **Doctor / login** — `cinna doctor` re-mints expired per-agent tokens through
200
208
  the account token, and groups blocked agents under a single `cinna login` hint
201
209
  when the account token itself has expired.
@@ -0,0 +1,140 @@
1
+ # Improvement Requests (`cinna improve`)
2
+
3
+ ## Purpose
4
+
5
+ Lets an agent owner work, from the account workspace, the **improvement requests**
6
+ users shared with them: a frozen snapshot of one bad session plus the runtime
7
+ context that produced it. `cinna improve` lists what came in, shows one in full,
8
+ downloads the archive for a local coding agent to read, and closes the request
9
+ with a note the requester sees.
10
+
11
+ ## Mental model / core concepts
12
+
13
+ - **Improvement request** — a consent-gated, one-directional share created on the
14
+ platform by a *session owner* (from the session menu, or with the
15
+ `/session-improve` command). It carries a frozen transcript of that one session
16
+ plus the tuning-relevant runtime context. The CLI never creates one; it only
17
+ receives.
18
+ - **Frozen at consent** — the snapshot is a copy, not a live view. Continuing the
19
+ conversation afterwards, or deleting the session, does not change what the
20
+ archive contains. There is no "refresh" and no withdrawal.
21
+ - **Requester vs. recipient** — the requester is the person who shared the
22
+ session; the recipient is the owner of the agent it landed on (the bundle
23
+ publisher, or the owner themselves for a standalone agent). `cinna improve`
24
+ always speaks as the **recipient**: the listing spans every agent the account
25
+ owns and never shows requests the account user submitted elsewhere.
26
+ - **Source install vs. target agent** — the archive's `context.json` describes the
27
+ *requester's* install (the copy that misbehaved); the target agent named in
28
+ `cinna improve show` is the copy the recipient can actually change. For a
29
+ bundle they are different rows, which is why "where does the fix go?" is a
30
+ deliberate step in the workflow, not an assumption.
31
+ - **Account-scoped** — every verb runs against the account CLI token from an
32
+ account workspace. There is no per-agent-workspace variant: the point is one
33
+ cross-agent queue.
34
+ - **Short id** — the 8-character prefix printed in the listing (and offered for
35
+ copy in the web UI) is accepted anywhere a request id is taken, and names the
36
+ download folder.
37
+
38
+ ## User flows
39
+
40
+ 1. **Discover** — `cinna improve list --status new` prints the requests waiting on
41
+ every agent the account owns: short id, agent, source session, requester,
42
+ installed version + bundle id, the reported comment, submission date, status.
43
+ Requests captured from the *same session* are flagged in the Session column, so
44
+ a re-submitted report is obvious before anything is downloaded.
45
+ `--agent <name|slug|id>` narrows to one agent; `--limit` bounds the page;
46
+ `--json` emits the raw payload. When the workspace's context package is behind
47
+ the platform's, the listing ends with a one-line nudge to refresh — the queue's
48
+ playbook ships in that package.
49
+ 2. **Claim** — `cinna improve status <id> in_progress` marks it taken, so a
50
+ parallel session (or the owner watching the platform's Configuration tab)
51
+ doesn't pick up the same request.
52
+ 3. **Read** — `cinna improve show <id>` prints the request row, the reported
53
+ comment verbatim, and the frozen runtime-context block: bundle id, installed
54
+ vs. latest version, whether an update was pending, install kind, session mode,
55
+ SDK engine and effective model, environment name/version/instance, image
56
+ staleness, plugins, captured personal memory, how many secrets were scrubbed,
57
+ and who the recipient is. When the context carries a `prompts` block it also
58
+ prints a per-prompt **in sync / diverged / not compared** table against the
59
+ installed bundle revision — a consumer who owns their install can edit its prompts, so this is
60
+ the difference between "my agent misbehaved" and "their edit of my agent
61
+ misbehaved". Below the table it states **where a fix belongs** — the context
62
+ describes the requester's install, the request landed on the target agent, and
63
+ for a bundle those are opposite ownership, so the conclusion is printed rather
64
+ than left to be derived.
65
+ 4. **Download** — `cinna improve download <id>` fetches the ZIP and extracts it
66
+ into `improvements/<short-id>/` under the account root (`--out DIR` for another
67
+ target), printing every extracted file plus a reminder that this is another
68
+ person's conversation. The archive holds `README.md`, `metadata.json`,
69
+ `context.json`, `session/messages.{md,json}`, and — when the platform captured
70
+ them — `prompts/` (the install's live prompt docs, named after the workspace
71
+ files they mirror so they diff straight against the publisher's copy) and
72
+ `memory/`.
73
+ 5. **Fix** — outside this feature: the local coding agent follows the platform's
74
+ shipped playbook (`context/guides/handling-improvement-requests.md`, installed
75
+ by `cinna account setup` / `refresh-context`) to establish where the fix must
76
+ land and how much autonomy it has.
77
+ 6. **Close** — `cinna improve status <id> completed --note "…"` (or `declined`
78
+ with the reason). The note is shown to the requester.
79
+
80
+ ## Business rules
81
+
82
+ - **Recipient-only mutation.** `status` is refused server-side for anyone who is
83
+ not the receiving agent's owner (403 for a requester who is party to the row,
84
+ 404 for anyone else — ids the account is not party to never confirm existence).
85
+ The CLI surfaces the platform's status and message verbatim.
86
+ - **Status vocabulary** — `new` → `in_progress` → `completed` | `declined`. The
87
+ CLI normalizes case and dashes (`In-Progress` → `in_progress`) and refuses an
88
+ unknown value *before* the round-trip, naming the valid ones. The backend keeps
89
+ the vocabulary in a plain column, so a value added later still reaches it.
90
+ - **Short-id resolution is fail-loud.** A full UUID goes straight through. A
91
+ prefix is resolved against the listing: no match and an ambiguous match are both
92
+ errors naming the fix, never a silent "first match wins".
93
+ - **Archive extraction is the safe extractor** — the same one used for the
94
+ workspace clone and the context package: absolute paths, `..` traversal,
95
+ symlinks, and oversized members are skipped with a warning rather than written.
96
+ - **Re-downloading is idempotent** — extracting again into an existing folder
97
+ refreshes it in place and says so ("Refreshed" vs. "Extracted").
98
+ - **The archive is somebody else's data.** The download command states it: don't
99
+ copy it into an agent workspace, don't commit it, delete it when done. What it
100
+ contains is bounded server-side — descriptors instead of uploaded file contents,
101
+ no container logs, and credential values scrubbed before storage — so the CLI
102
+ never has to filter it.
103
+ - **An unchecked comparison is never reported as a match.** A prompt whose
104
+ divergence is `null` — platform-managed routing metadata, or a row with no
105
+ baseline — renders as *not compared* with the platform's reason, never as *in
106
+ sync*. Same rule for the rollup: no baseline prints "no baseline to compare
107
+ against".
108
+ - **Truncation is disclosed** — a snapshot that hit the platform's size cap
109
+ dropped its *oldest* messages; `show` flags it next to the message count so the
110
+ reader doesn't reason as if the whole session is present.
111
+ - **Account workspace required** — every verb resolves the account root first and
112
+ fails with the standard "Not in a cinna account workspace" error before any
113
+ network call.
114
+
115
+ ## Architecture overview
116
+
117
+ ```
118
+ cinna improve <verb>
119
+ → src/cinna/main.py (improve group)
120
+ → src/cinna/improve.py (resolve short id, render, extract)
121
+ → src/cinna/client.py AccountClient (account token)
122
+ → GET/PATCH /api/v1/cli/account/improvement-requests[/{id}[/archive]]
123
+ → improvements/<short-id>/ (download only; safe extraction)
124
+ ```
125
+
126
+ ## Integration points
127
+
128
+ - [Account workspace](../account_workspace/account_workspace.md) — supplies the
129
+ account root, the account token, and `_resolve_account_agent` for `--agent`.
130
+ The orchestrator `CLAUDE.md` written there lists these verbs and points at the
131
+ platform playbook; `cinna account agents` flags publisher installs, which is
132
+ the ownership signal the workflow depends on.
133
+ - [Agent management](../agent_management/agent_management.md) — a fix usually
134
+ continues in a synced per-agent workspace (`cinna agent sync`), then
135
+ [Live sync](../live_sync/live_sync.md) pushes it and
136
+ [Remote chat](../remote_chat/remote_chat.md) verifies the behavior actually
137
+ changed.
138
+ - [Agent API / escape hatch](../agent_api/agent_api.md) — the same JSON endpoints
139
+ are reachable through `cinna api`; the dedicated verbs exist for ergonomics and
140
+ because the binary archive cannot ride the JSON-only proxy.
@@ -0,0 +1,256 @@
1
+ # Improvement Requests — Acceptance Scenarios
2
+
3
+ Real-usage scenarios for `cinna improve`, run against a **live platform** with a
4
+ real account workspace. Unit tests (`tests/test_improve.py`) cover rendering and
5
+ transport; these scenarios cover what only a live backend can show: consent flow
6
+ end-to-end, recipient resolution for a bundle, authorization boundaries, and the
7
+ archive's actual contents.
8
+
9
+ ## Preconditions
10
+
11
+ - A live platform URL where the Agent Improvement Requests feature is deployed
12
+ (backend routes `/api/v1/cli/account/improvement-requests*`).
13
+ - An **editable install** of this repo: `which cinna` resolves into the repo's
14
+ `src/cinna`.
15
+ - An account workspace: `cinna login <domain>` (or `cinna account setup <token>`)
16
+ in an empty folder, then `cd` into it.
17
+ - **Agent A** — a standalone agent the account owns, with a conversation session
18
+ containing at least a couple of messages.
19
+ - **Agent B** *(for the bundle scenarios)* — a bundle published from this account
20
+ (the **publisher install**), plus a **consumer install** of that bundle owned by
21
+ a *second* user account, with a session on it.
22
+ - Browser access to the platform UI as both users, to submit requests and to check
23
+ the Configuration-tab card.
24
+
25
+ ## Scenario catalog
26
+
27
+ ### 1. Standalone agent — submit, list, show
28
+
29
+ **Goal** — the basic loop on an agent the account owns itself.
30
+ **Setup** — Agent A with a session that has ≥ 1 message.
31
+ **Steps**
32
+
33
+ ```bash
34
+ # In the platform UI, as the owner: open the session → ⋮ → Improve Agent,
35
+ # write a comment ("it answered with last month's numbers"), confirm.
36
+ cinna improve list
37
+ cinna improve list --status new
38
+ cinna improve show <short-id>
39
+ ```
40
+
41
+ **Expected** — the request appears with Agent A's name, the owner as requester,
42
+ `standalone` in the Version column, the comment text, and status `new`. `show`
43
+ prints the comment verbatim, the message count, and a runtime-context table
44
+ carrying session mode, engine, effective model, and the environment name.
45
+ **Watch for** — a self-targeted request that fails to resolve a recipient; a
46
+ context block that is empty or missing the effective model (the platform must use
47
+ its own resolver, not a re-implementation); a short id in the table that `show`
48
+ cannot resolve.
49
+
50
+ ### 2. Submission via the `/session-improve` command
51
+
52
+ **Goal** — the command entry point produces the same row as the menu.
53
+ **Setup** — a second session on Agent A.
54
+ **Steps**
55
+
56
+ ```bash
57
+ cinna chat --agent <agent-a> "give me the quarterly totals"
58
+ # In the platform UI, in that same session: /session-improve it used the wrong quarter
59
+ cinna improve list --agent <agent-a> --json
60
+ ```
61
+
62
+ **Expected** — a second row for Agent A whose `source` is `command` and whose
63
+ `comment` is the text typed after the slash command.
64
+ **Watch for** — `source` reported as `web_ui` for a command submission; the
65
+ command's confirmation naming the wrong recipient.
66
+
67
+ ### 3. Bundle install — the request lands on the publisher
68
+
69
+ **Goal** — the cross-user path: a consumer's session reaches the publisher.
70
+ **Setup** — the consumer account has an install of the published bundle and a
71
+ session on it.
72
+ **Steps**
73
+
74
+ ```bash
75
+ # As the CONSUMER, in the platform UI: session ⋮ → Improve Agent → confirm.
76
+ # The modal must name the publisher and the bundle version before the button.
77
+ # Then, as the PUBLISHER, in the account workspace:
78
+ cinna improve list --status new
79
+ cinna improve show <short-id>
80
+ ```
81
+
82
+ **Expected** — the row's target agent is the **publisher install**, the requester
83
+ is the consumer, and Version shows the installed version plus the bundle id.
84
+ `show` reports `consumer install`, the installed vs. latest version, and whether
85
+ an update was pending.
86
+ **Watch for** — the request landing on the consumer's own copy instead of the
87
+ publisher's; the publisher seeing the consumer's *other* sessions anywhere; a
88
+ `fallback_reason` set when the publisher install actually exists.
89
+
90
+ ### 4. Download, extract, and read the archive
91
+
92
+ **Goal** — the archive is a valid, complete, self-describing package.
93
+ **Steps**
94
+
95
+ ```bash
96
+ cinna improve download <short-id>
97
+ ls -R improvements/<short-id>/
98
+ head -40 improvements/<short-id>/README.md
99
+ python3 -c "import json;print(json.load(open('improvements/<short-id>/context.json'))['sdk'])"
100
+ ```
101
+
102
+ **Expected** — `README.md`, `metadata.json`, `context.json`, and
103
+ `session/messages.md` + `session/messages.json` land under
104
+ `improvements/<short-id>/`; the command lists each extracted file, prints the
105
+ "another person's conversation" warning, and `context.json` carries the bundle
106
+ version, installed/latest revision, session mode, SDK engine, and effective model.
107
+ `README.md` states that container logs and uploaded file contents are excluded.
108
+ **Watch for** — a truncated or unreadable ZIP; `session/messages.md` missing the
109
+ tool calls that explain the failure; any uploaded file's *contents* (rather than a
110
+ descriptor) appearing in the archive.
111
+
112
+ ### 5. The snapshot is frozen
113
+
114
+ **Goal** — post-consent conversation never leaks into an already-shared request.
115
+ **Steps**
116
+
117
+ ```bash
118
+ cinna improve download <short-id> --out /tmp/before-<short-id>
119
+ cinna chat --agent <agent-a> --resume <session_id> "and now add the discounts"
120
+ cinna improve download <short-id>
121
+ diff -r /tmp/before-<short-id> improvements/<short-id>/
122
+ ```
123
+
124
+ **Expected** — the two extractions are identical; the follow-up turn is absent
125
+ from both. The second run reports "Refreshed" rather than "Extracted".
126
+ **Watch for** — the archive growing after the session continues; a re-download
127
+ leaving a mix of old and new files behind.
128
+
129
+ ### 6. Status transitions and the requester-visible note
130
+
131
+ **Goal** — the loop closes and the requester sees the outcome.
132
+ **Steps**
133
+
134
+ ```bash
135
+ cinna improve status <short-id> in_progress
136
+ cinna improve list --status in_progress
137
+ cinna improve status <short-id> completed --note "Fixed in v1.6 — it no longer re-asks for an uploaded file."
138
+ cinna improve show <short-id>
139
+ ```
140
+
141
+ **Expected** — each transition is confirmed, `show` reports the new status, a
142
+ status-changed timestamp, and the resolution note; the requester sees the note on
143
+ their side in the platform UI.
144
+ **Watch for** — a note silently dropped; `status_changed_at` not moving; the
145
+ Configuration-tab card not updating live (its WebSocket event).
146
+
147
+ ### 7. Refusals — unknown status, unknown id, ambiguous id
148
+
149
+ **Goal** — fail-loud before the network, and never guess an id.
150
+ **Steps**
151
+
152
+ ```bash
153
+ cinna improve status <short-id> wontfix
154
+ cinna improve show deadbeef
155
+ cinna improve show <2-char-prefix-shared-by-two-requests>
156
+ ```
157
+
158
+ **Expected** — respectively: "Unknown status 'wontfix'" listing the four valid
159
+ values; "No improvement request matching 'deadbeef'" pointing at
160
+ `cinna improve list`; an "ambiguous" error listing the matching short ids. All
161
+ exit non-zero and change nothing.
162
+ **Watch for** — a prefix silently resolving to the first match; a bad status
163
+ reaching the backend as a 400/422 instead of a readable CLI error.
164
+
165
+ ### 8. Authorization boundary — a non-recipient sees nothing
166
+
167
+ **Goal** — ids the account is not party to do not confirm their own existence.
168
+ **Setup** — the consumer account's own account workspace, and a request id taken
169
+ from the publisher's listing.
170
+ **Steps**
171
+
172
+ ```bash
173
+ # As the CONSUMER (the requester, not the recipient):
174
+ cinna improve list
175
+ cinna improve status <publisher-request-id> completed
176
+ ```
177
+
178
+ **Expected** — the consumer's listing does **not** contain the request (that
179
+ surface is the recipient's queue); the `status` attempt fails with the platform's
180
+ 403 for a party requester, and with a 404 for a completely unrelated account.
181
+ **Watch for** — a 403 where a 404 is required for a stranger (existence leak); a
182
+ requester being able to mutate status or delete the row.
183
+
184
+ ### 9. `--agent` filter and cross-agent scope
185
+
186
+ **Goal** — one queue across every owned agent, narrowable to one.
187
+ **Steps**
188
+
189
+ ```bash
190
+ cinna improve list # both agents' requests
191
+ cinna improve list --agent <agent-a>
192
+ cinna improve list --agent "Nonexistent Agent"
193
+ ```
194
+
195
+ **Expected** — the unfiltered listing spans both agents; the filtered one shows
196
+ only Agent A's; an unknown reference fails with the accessible-agent list from
197
+ `cinna account agents`.
198
+ **Watch for** — the filter being applied client-side (it must reach the backend as
199
+ `agent_id`); an agent name resolving to the wrong id when two agents share a slug.
200
+
201
+ ### 10. Session deleted after submission
202
+
203
+ **Goal** — the payload is the row, not a pointer to a live session.
204
+ **Steps**
205
+
206
+ ```bash
207
+ # Delete the source session in the platform UI, then:
208
+ cinna improve show <short-id>
209
+ cinna improve download <short-id> --out /tmp/after-delete
210
+ ```
211
+
212
+ **Expected** — both still succeed with the same content; the request row survives
213
+ with its provenance link cleared.
214
+ **Watch for** — a 500 or an empty archive after the session is gone; the archive
215
+ degrading to a "snapshot unavailable" README when the snapshot is actually intact.
216
+
217
+ ### 11. Truncated snapshot is disclosed
218
+
219
+ **Goal** — a capped snapshot is never read as a complete one.
220
+ **Setup** — a session long enough to exceed the platform's snapshot cap.
221
+ **Steps**
222
+
223
+ ```bash
224
+ cinna improve show <short-id>
225
+ grep -i truncat improvements/<short-id>/README.md
226
+ ```
227
+
228
+ **Expected** — `show` flags the message count as truncated (oldest messages
229
+ dropped), and the archive's README says the same.
230
+ **Watch for** — truncation dropping the *newest* messages (defects cluster at the
231
+ end); the flag present in the row but absent from the README.
232
+
233
+ ## Cross-cutting invariants
234
+
235
+ - Every verb refuses to run outside an account workspace, before any network call.
236
+ - No verb ever creates a request — consent happens only in the platform UI or via
237
+ `/session-improve`, on the requester's own session.
238
+ - No credential value, container log, or uploaded file's contents appears in any
239
+ archive; scrubbing and exclusion are server-side and must stay that way.
240
+ - Extraction never writes outside the destination directory, whatever the archive
241
+ claims.
242
+ - Ids the account is not party to return 404, never 403 — no existence leak.
243
+ - Downloaded archives stay under `improvements/` (or `--out`) — never inside
244
+ `agents/<slug>/workspace/`, and never committed.
245
+ - The account token is the only credential involved; nothing is persisted to the
246
+ agent registry.
247
+
248
+ ## Cleanup
249
+
250
+ ```bash
251
+ rm -rf improvements/ /tmp/before-* /tmp/after-delete
252
+ ```
253
+
254
+ Close any request left `in_progress` (`cinna improve status <id> completed --note
255
+ "…"` or `declined`), delete the throwaway sessions in the platform UI, and — if
256
+ the scenarios created a test bundle install on the second account — uninstall it.