cinna-cli 0.2.5__tar.gz → 0.3.0__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.
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/.gitignore +1 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/PKG-INFO +56 -2
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/README.md +54 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/README.md +8 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/account_workspace/account_workspace.md +8 -0
- cinna_cli-0.3.0/docs/features/improvement_requests/improvement_requests.md +140 -0
- cinna_cli-0.3.0/docs/features/improvement_requests/improvement_requests_acceptance.md +256 -0
- cinna_cli-0.3.0/docs/features/improvement_requests/improvement_requests_tech.md +141 -0
- cinna_cli-0.3.0/docs/features/local_agent_import/local_agent_import.md +181 -0
- cinna_cli-0.3.0/docs/features/local_agent_import/local_agent_import_acceptance.md +264 -0
- cinna_cli-0.3.0/docs/features/local_agent_import/local_agent_import_tech.md +389 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/pyproject.toml +1 -1
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/account.py +82 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/client.py +102 -0
- cinna_cli-0.3.0/src/cinna/improve.py +697 -0
- cinna_cli-0.3.0/src/cinna/kit_contract.py +857 -0
- cinna_cli-0.3.0/src/cinna/local_import.py +1131 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/main.py +160 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/sync.py +20 -1
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/templates/ACCOUNT_CLAUDE.md.template +29 -2
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_account.py +83 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_client.py +40 -0
- cinna_cli-0.3.0/tests/test_improve.py +847 -0
- cinna_cli-0.3.0/tests/test_kit_contract.py +433 -0
- cinna_cli-0.3.0/tests/test_local_import.py +1238 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_sync.py +42 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/uv.lock +1 -1
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/.claude/commands/cinna-cli.feature.doc.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/.github/workflows/publish.yml +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/LICENSE.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/account_workspace/account_workspace_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/account_workspace/account_workspace_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_api/agent_api.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_api/agent_api_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_api/agent_api_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_management/agent_management.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_management/agent_management_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_management/agent_management_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_schedules/agent_schedules.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_schedules/agent_schedules_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/agent_schedules/agent_schedules_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/doctor/doctor.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/doctor/doctor_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/doctor/doctor_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/git_versioning/git_versioning.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/git_versioning/git_versioning_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/git_versioning/git_versioning_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/live_sync/live_sync.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/live_sync/live_sync_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/live_sync/live_sync_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/mcp_integration/mcp_integration.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/mcp_integration/mcp_integration_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/mcp_integration/mcp_integration_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_chat/remote_chat.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_chat/remote_chat_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_chat/remote_chat_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_exec/remote_exec.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_exec/remote_exec_acceptance.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/features/remote_exec/remote_exec_tech.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/interface.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/docs/mutagen_capabilities.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/scripts/check_docs_references.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/__init__.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/auth.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/bootstrap.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/chat.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/config.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/console.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/context.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/doctor.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/errors.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/git_versioning.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/logging.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/mcp_proxy.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/mutagen_runtime.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/sync_session.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/sync_ssh_shim.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/sync_tui.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/templates/CHAT_TESTING.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/templates/CLAUDE.md.template +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/templates/GIT_VERSIONING.md +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/src/cinna/templates/__init__.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/__init__.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/conftest.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_auth.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_bootstrap.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_chat.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_config.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_context.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_doctor.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_git_versioning.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_main.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_mutagen_runtime.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_sync_session.py +0 -0
- {cinna_cli-0.2.5 → cinna_cli-0.3.0}/tests/test_sync_ssh_shim.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: cinna-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
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.
|
|
@@ -224,6 +259,25 @@ works exactly as for a manually set-up agent. Synced agents also appear in `cinn
|
|
|
224
259
|
|
|
225
260
|
Detach a synced workspace: stop its sync session, revoke the minted CLI token server-side (via the account-scoped revoke endpoint, authenticated with the account token; idempotent), then perform the equivalent of `cinna disconnect`: remove `.cinna/`, generated files, and the registry entry. Workspace files under `agents/<slug>/workspace/` are preserved. The revoke degrades gracefully — if it fails (no connection, or a workspace synced before token-id tracking), a warning is printed and the local teardown still completes; the token then expires on its own or can be revoked from the agent's Integrations tab.
|
|
226
261
|
|
|
262
|
+
### `cinna agent import <path> [--name TEXT] [--workspace REF] [--update] [--dry-run] [--no-push] [--yes]`
|
|
263
|
+
|
|
264
|
+
Import an agent that was built **locally** with the [Local Agent Kit](docs/features/local_agent_import/local_agent_import.md) — a folder holding a `cinna-agent.json` manifest, typically `../Local/<slug>` next to this account workspace. Run it from the account workspace root (or any folder inside it).
|
|
265
|
+
|
|
266
|
+
Nine idempotent steps, each printed as `[n/9]`: read and validate the manifest → create (or resolve) the cloud agent → write its description, router trigger, example prompts and the three document prompts in one bulk write, plus the status refresh command → attach a local workspace (`cinna agent sync`) → copy the tree into `agents/<slug>/workspace/` honouring the contract's exclude list and secret rules, generating `workspace_requirements.txt` from `pyproject.toml` when the agent doesn't ship one → `cinna sync push` → create the credential drafts and attach them → create the schedules → record the publication in `publications.json` and print the summary.
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
cinna agent import ../Local/invoice-watcher --dry-run # see the plan, touch nothing
|
|
270
|
+
cinna agent import ../Local/invoice-watcher --yes
|
|
271
|
+
cinna chat --agent invoice-watcher "check invoices from last week"
|
|
272
|
+
|
|
273
|
+
# after more local work:
|
|
274
|
+
cinna agent import ../Local/invoice-watcher --update --yes
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
The folder rules come from the kit's versioned contract, `.cinna-kit/layout.json` — the same file Cinna Desktop reads — so a correction published there reaches this command on the next kit refresh rather than waiting for a new cinna-cli. `credentials/` and `app-data/` are **never** copied, not even if the contract drops them, and on top of the exclude list the contract's `secret_files` rules withhold every dotenv shape (`.env`, `.env.prod`, `staging.env`) wherever it sits, while `.env.example` still travels. No secret value is ever read, sent, or printed: credentials are created as empty drafts and the command prints the URLs the user opens to fill them in the browser.
|
|
278
|
+
|
|
279
|
+
Where the folder has been published is recorded in `publications.json`, a **sibling** of `cinna-agent.json` holding one entry per Cinna instance — it cannot live inside the manifest, because each entry records a hash of the exported tree and the manifest is part of that tree. Every step is idempotent (agent by the entry whose `platform_url` matches the instance you are logged into, credentials by name, schedules by name), so a partial import is resumed with `--update` instead of duplicating anything. The publication is recorded **only after the push settled** — `--no-push`, a failed flush, or remaining conflicts leave it unrecorded, and the next run is a plain `--update`. A legacy `cloud` block is migrated into the ledger on the first write and is still read until then, so an older folder's `--update` never creates a second agent. `--dry-run` makes no platform call and writes nothing.
|
|
280
|
+
|
|
227
281
|
### `cinna connect agent-api --producer <agent> --consumer <agent> [--label TEXT] [--read-only]`
|
|
228
282
|
|
|
229
283
|
Wire one agent to another's REST API from the account workspace. Resolves both agents (name, slug, or ID), mints a producer API token, and attaches it to the consumer as a credential — which rides the consumer's normal credential sync into its remote environment, so no key ever touches your machine. Prints the credential ID, token prefix, base URL, and spec URL. `--read-only` restricts the consumer to read-only access; `--label` names the credential. Backend errors surface verbatim: 400 if the producer's REST API is disabled, 403/404 for ownership violations.
|
|
@@ -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.
|
|
@@ -187,6 +222,25 @@ works exactly as for a manually set-up agent. Synced agents also appear in `cinn
|
|
|
187
222
|
|
|
188
223
|
Detach a synced workspace: stop its sync session, revoke the minted CLI token server-side (via the account-scoped revoke endpoint, authenticated with the account token; idempotent), then perform the equivalent of `cinna disconnect`: remove `.cinna/`, generated files, and the registry entry. Workspace files under `agents/<slug>/workspace/` are preserved. The revoke degrades gracefully — if it fails (no connection, or a workspace synced before token-id tracking), a warning is printed and the local teardown still completes; the token then expires on its own or can be revoked from the agent's Integrations tab.
|
|
189
224
|
|
|
225
|
+
### `cinna agent import <path> [--name TEXT] [--workspace REF] [--update] [--dry-run] [--no-push] [--yes]`
|
|
226
|
+
|
|
227
|
+
Import an agent that was built **locally** with the [Local Agent Kit](docs/features/local_agent_import/local_agent_import.md) — a folder holding a `cinna-agent.json` manifest, typically `../Local/<slug>` next to this account workspace. Run it from the account workspace root (or any folder inside it).
|
|
228
|
+
|
|
229
|
+
Nine idempotent steps, each printed as `[n/9]`: read and validate the manifest → create (or resolve) the cloud agent → write its description, router trigger, example prompts and the three document prompts in one bulk write, plus the status refresh command → attach a local workspace (`cinna agent sync`) → copy the tree into `agents/<slug>/workspace/` honouring the contract's exclude list and secret rules, generating `workspace_requirements.txt` from `pyproject.toml` when the agent doesn't ship one → `cinna sync push` → create the credential drafts and attach them → create the schedules → record the publication in `publications.json` and print the summary.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
cinna agent import ../Local/invoice-watcher --dry-run # see the plan, touch nothing
|
|
233
|
+
cinna agent import ../Local/invoice-watcher --yes
|
|
234
|
+
cinna chat --agent invoice-watcher "check invoices from last week"
|
|
235
|
+
|
|
236
|
+
# after more local work:
|
|
237
|
+
cinna agent import ../Local/invoice-watcher --update --yes
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The folder rules come from the kit's versioned contract, `.cinna-kit/layout.json` — the same file Cinna Desktop reads — so a correction published there reaches this command on the next kit refresh rather than waiting for a new cinna-cli. `credentials/` and `app-data/` are **never** copied, not even if the contract drops them, and on top of the exclude list the contract's `secret_files` rules withhold every dotenv shape (`.env`, `.env.prod`, `staging.env`) wherever it sits, while `.env.example` still travels. No secret value is ever read, sent, or printed: credentials are created as empty drafts and the command prints the URLs the user opens to fill them in the browser.
|
|
241
|
+
|
|
242
|
+
Where the folder has been published is recorded in `publications.json`, a **sibling** of `cinna-agent.json` holding one entry per Cinna instance — it cannot live inside the manifest, because each entry records a hash of the exported tree and the manifest is part of that tree. Every step is idempotent (agent by the entry whose `platform_url` matches the instance you are logged into, credentials by name, schedules by name), so a partial import is resumed with `--update` instead of duplicating anything. The publication is recorded **only after the push settled** — `--no-push`, a failed flush, or remaining conflicts leave it unrecorded, and the next run is a plain `--update`. A legacy `cloud` block is migrated into the ledger on the first write and is still read until then, so an older folder's `--update` never creates a second agent. `--dry-run` makes no platform call and writes nothing.
|
|
243
|
+
|
|
190
244
|
### `cinna connect agent-api --producer <agent> --consumer <agent> [--label TEXT] [--read-only]`
|
|
191
245
|
|
|
192
246
|
Wire one agent to another's REST API from the account workspace. Resolves both agents (name, slug, or ID), mints a producer API token, and attaches it to the consumer as a credential — which rides the consumer's normal credential sync into its remote environment, so no key ever touches your machine. Prints the credential ID, token prefix, base URL, and spec URL. `--read-only` restricts the consumer to read-only access; `--label` names the credential. Backend errors surface verbatim: 400 if the producer's REST API is disabled, 403/404 for ownership violations.
|
|
@@ -200,6 +200,11 @@ 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)
|
|
204
|
+
├── local_import.py — `cinna agent import`: the Local Agent Kit go-cloud step
|
|
205
|
+
├── kit_contract.py — the Local Agent Kit contract as data (`.cinna-kit/layout.json`):
|
|
206
|
+
│ exclude patterns, secret-file rules, export walk, content_hash,
|
|
207
|
+
│ publications.json ledger, contract-version gate
|
|
203
208
|
├── config.py — .cinna/config.json: load/save/find
|
|
204
209
|
├── auth.py — JWT storage, Authorization headers
|
|
205
210
|
├── client.py — PlatformClient: HTTP + SSE stream_exec
|
|
@@ -287,6 +292,8 @@ authoring convention.
|
|
|
287
292
|
| **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
293
|
| **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
294
|
| **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) |
|
|
295
|
+
| **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) |
|
|
296
|
+
| **Local agent import** | `cinna agent import` (Local Agent Kit → cloud agent), incl. the versioned folder contract (`.cinna-kit/layout.json`), `publications.json` and `content_hash` | [business](features/local_agent_import/local_agent_import.md) · [tech](features/local_agent_import/local_agent_import_tech.md) · [acceptance](features/local_agent_import/local_agent_import_acceptance.md) |
|
|
290
297
|
|
|
291
298
|
The sections below (Git Versioning, Sync Transport, Remote Exec, Remote Chat,
|
|
292
299
|
Bootstrap Flow) remain as in-README quick references and backend contracts; the
|
|
@@ -610,6 +617,7 @@ When a CLI token expires (or is revoked) the normal remedy is `cinna set-token <
|
|
|
610
617
|
| POST | `/api/v1/cli/account/agents/{id}/mint` | Account token | Mint a per-agent CLI token (`cinna agent sync`, `cinna doctor` re-mint) |
|
|
611
618
|
| 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
619
|
| POST | `/api/v1/cli/account/files/upload` | Account token | Multipart upload for `cinna chat --file` (the proxy can't carry multipart) |
|
|
620
|
+
| 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
621
|
|
|
614
622
|
`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
623
|
|
|
@@ -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.
|