cinna-cli 0.5.2__tar.gz → 0.6.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.5.2 → cinna_cli-0.6.0}/PKG-INFO +44 -3
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/README.md +43 -2
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/README.md +11 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/account_workspace/account_workspace.md +10 -2
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/account_workspace/account_workspace_acceptance.md +7 -3
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/account_workspace/account_workspace_tech.md +3 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_addons/agent_addons.md +14 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_addons/agent_addons_acceptance.md +26 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_addons/agent_addons_tech.md +14 -2
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_management/agent_management.md +19 -2
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_management/agent_management_tech.md +7 -1
- cinna_cli-0.6.0/docs/features/artifacts/artifacts.md +138 -0
- cinna_cli-0.6.0/docs/features/artifacts/artifacts_acceptance.md +140 -0
- cinna_cli-0.6.0/docs/features/artifacts/artifacts_tech.md +124 -0
- cinna_cli-0.6.0/docs/features/dashboards/dashboards.md +224 -0
- cinna_cli-0.6.0/docs/features/dashboards/dashboards_acceptance.md +271 -0
- cinna_cli-0.6.0/docs/features/dashboards/dashboards_tech.md +239 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/delegation/delegation.md +2 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/live_sync/live_sync.md +13 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/live_sync/live_sync_acceptance.md +24 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/live_sync/live_sync_tech.md +21 -4
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/local_agent_import/local_agent_import.md +10 -3
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/local_agent_import/local_agent_import_tech.md +2 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_chat/remote_chat.md +13 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/pyproject.toml +1 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/account.py +210 -3
- cinna_cli-0.6.0/src/cinna/artifacts.py +971 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/chat.py +84 -4
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/client.py +315 -13
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/config.py +11 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/context.py +113 -0
- cinna_cli-0.6.0/src/cinna/dashboards.py +1648 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/errors.py +50 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/kit_contract.py +1 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/local_import.py +47 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/main.py +83 -3
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/sync_session.py +86 -2
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/templates/ACCOUNT_CLAUDE.md.template +26 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/templates/CLAUDE.md.template +16 -4
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_account.py +138 -3
- cinna_cli-0.6.0/tests/test_artifacts.py +645 -0
- cinna_cli-0.6.0/tests/test_dashboards.py +768 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_kit_contract.py +1 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_sync_session.py +85 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/uv.lock +1 -1
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/.claude/commands/cinna-cli.feature.doc.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/.github/workflows/publish.yml +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/.gitignore +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/LICENSE.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_api/agent_api.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_api/agent_api_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_api/agent_api_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_management/agent_management_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_schedules/agent_schedules.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_schedules/agent_schedules_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/agent_schedules/agent_schedules_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/bootstrap_onboarding/bootstrap_onboarding_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/delegation/delegation_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/delegation/delegation_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/doctor/doctor.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/doctor/doctor_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/doctor/doctor_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/git_versioning/git_versioning.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/git_versioning/git_versioning_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/git_versioning/git_versioning_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/improvement_requests/improvement_requests.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/improvement_requests/improvement_requests_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/improvement_requests/improvement_requests_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/local_agent_import/local_agent_import_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/mcp_integration/mcp_integration.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/mcp_integration/mcp_integration_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/mcp_integration/mcp_integration_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_chat/remote_chat_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_chat/remote_chat_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_exec/remote_exec.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_exec/remote_exec_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/remote_exec/remote_exec_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/team_library/team_library.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/team_library/team_library_acceptance.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/team_library/team_library_tech.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/interface.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/mutagen_capabilities.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/scripts/check_docs_references.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/__init__.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/auth.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/bootstrap.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/cli_version.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/console.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/delegation.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/doctor.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/git_versioning.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/improve.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/library.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/logging.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/mcp_proxy.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/mutagen_runtime.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/scenarios.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/sync.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/sync_ssh_shim.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/sync_tui.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/templates/CHAT_TESTING.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/templates/GIT_VERSIONING.md +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/src/cinna/templates/__init__.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/__init__.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/conftest.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_agent_api_access.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_auth.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_bootstrap.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_chat.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_cli_version.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_client.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_config.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_console.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_context.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_delegation.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_doctor.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_git_versioning.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_improve.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_library.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_local_import.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_main.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_mutagen_runtime.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_onboarding.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_scenarios.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_sync.py +0 -0
- {cinna_cli-0.5.2 → cinna_cli-0.6.0}/tests/test_sync_ssh_shim.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cinna-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.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
|
|
@@ -405,6 +405,8 @@ At a terminal that preview is shown and confirmed before the press; `--yes`, `--
|
|
|
405
405
|
|
|
406
406
|
A re-publish appends a revision to the same package, so `--package-id` (the reverse-DNS id, e.g. `com.acme.report`) is only for a first publish — a mismatch on a later one is refused rather than silently ignored. `--visibility` is likewise honoured on a first publish and on an explicit change; omitting it leaves the package as it is. `--grant` requires `--visibility users` and the CLI refuses the combination otherwise, before anything is written. The server would accept it — it stores the grant either way — but a package that is private or public never consults its grant list, so the publish would report success and share nothing, and a revision cannot be taken back. Within a `users` package `--grant` is strictly **additive**: it adds the addresses it names and never revokes the ones it omits (revoking is `cinna skills revoke`, so a stale publish cannot silently remove access), and an unknown address fails the whole publish rather than half-sharing it. On success the package id, revision and its version, visibility and catalog URL are printed, plus a line saying the version landed in `skills/<name>/SKILL.md` — and a warning instead when it could not be written there, because the header and the catalog have then diverged and the next publish continues from the catalog. A refusal is printed as the platform's own sentence with its code (`not_developer`, `foreign_install`, `no_environment`, `workspace_unavailable`, `package_id_immutable`, `skill_contains_secrets` — which also lists the offending files), and `--json` prints `{revision, package, catalog_url, skill_md_updated}` instead of the human block (`--dry-run --json` prints the preview payload).
|
|
407
407
|
|
|
408
|
+
**A publish from the CLI is never refused as stale.** It goes through the agent path, which records the package's latest revision as the new one's base (`cinna skills revisions` shows it under **Based on**), so another maintainer's newer version is built on, not checked against. Cinna Desktop's Share instead sends the base its folder holds, and core refuses that share (`stale_base`) when a co-maintainer has shared a newer version since; the CLI never makes that call.
|
|
409
|
+
|
|
408
410
|
### `cinna skills catalog [--search Q] [--mine] [--json]`
|
|
409
411
|
|
|
410
412
|
Browse the instance skills catalog: one row per package this account may see, with its reverse-DNS **package id**, display name, visibility and newest version. The package id — `com.acme.pdf-report`, not a UUID — is the reference every other package verb takes. A delisted package is marked as such beside its visibility.
|
|
@@ -417,7 +419,7 @@ One package in full: its display name, visibility, newest version and package UU
|
|
|
417
419
|
|
|
418
420
|
### `cinna skills revisions <package> [--json]`
|
|
419
421
|
|
|
420
|
-
A package's revisions, **newest first**: number, version, release date, size and the release notes given at publish time. A revision is immutable, so this is the question a publisher has before every publish — what is already out there — and the answer to it no longer requires `cinna api` and a UUID. Pair it with `cinna skills publish <agent> <name> --dry-run`, which says what the *next* one would be.
|
|
422
|
+
A package's revisions, **newest first**: number, version, release date, size, **Shared by** (who published it, `—` once that account is deleted), **Based on** (`Version N`, the revision the sharer's copy held; `—` for a first revision, a share from an older Cinna Desktop, and any revision published before core recorded it) and the release notes given at publish time. A server older than skill co-maintainers sends neither field and both columns read `—`. `--json` passes the server's `published_by` and `base_revision_number` through untouched. A revision is immutable, so this is the question a publisher has before every publish — what is already out there — and the answer to it no longer requires `cinna api` and a UUID. Pair it with `cinna skills publish <agent> <name> --dry-run`, which says what the *next* one would be.
|
|
421
423
|
|
|
422
424
|
### `cinna skills files <package> [--revision N] [--json]`
|
|
423
425
|
|
|
@@ -575,7 +577,7 @@ Hand work to a remote agent as a **durable delegation** — a platform task with
|
|
|
575
577
|
|
|
576
578
|
- `create --id KEY --target AGENT_UUID --title T --brief B [--execute]` — the identity is `--target` + `--id`: a retry with the same pair returns the original task (changed title/brief are ignored) and never launches execution twice (the backend deduplicates). Prints the backend **task id** the other commands take, and whether it executes. `--depth 2 --root ROOT` makes a sub-delegation (`--root` is required at depth 2, not allowed at depth 1); `--group` tags related work.
|
|
577
579
|
- `status TASK_ID` — one read: state, latest result, and any open question with its result id. A requester agent should end its turn and let Cinna Desktop deliver the result rather than poll.
|
|
578
|
-
- `report [TASK_ID] --status in_progress|blocked|done|failed --summary S` — `blocked` needs `--question`; `--audience user` when a human must decide (default `requester`). `--artifact` (repeatable) is a JSON object with non-empty `kind` (backend accepts `file` or `link`), `name` and an `http(s)` `ref` — upload local files separately. `--body` adds detail.
|
|
580
|
+
- `report [TASK_ID] --status in_progress|blocked|done|failed --summary S` — `blocked` needs `--question`; `--audience user` when a human must decide (default `requester`). `--artifact` (repeatable) is a JSON object with non-empty `kind` (backend accepts `file` or `link`), `name` and an `http(s)` `ref` — upload local files separately (`cinna artifacts publish` prints such a link). `--body` adds detail.
|
|
579
581
|
- **Inside a cloud task**, omit `TASK_ID`: the report goes to the current task using `AGENT_AUTH_TOKEN`, `BACKEND_URL`, `ENV_ID` and the session in `CINNA_SESSION_CONTEXT_PATH` (default `./session_context.json`); the backend checks the session belongs to this environment's agent and owner.
|
|
580
582
|
- `reply TASK_ID --result-id ID --message M` — answer a blocked question.
|
|
581
583
|
- `--json` (after the subcommand) prints `{"result": "ok", "delegation": {…}}`.
|
|
@@ -590,6 +592,45 @@ cinna delegation report --status done --summary 'Finished' # inside the clou
|
|
|
590
592
|
|
|
591
593
|
Inside cloud tasks, cinna-core's MCP task server also offers a `handover_report` tool for the same report.
|
|
592
594
|
|
|
595
|
+
### `cinna artifacts publish | list | show | open | download | share | link | delete`
|
|
596
|
+
|
|
597
|
+
Publish a folder or a file to Cinna as an **artifact** — a frozen, versioned copy people open on a Cinna page (a folder with `index.html` runs as a sandboxed static site; other files open in viewers). Run from the account workspace. Every verb first checks the server's artifacts capability and refuses with "This Cinna server does not support artifacts" when it is missing.
|
|
598
|
+
|
|
599
|
+
- `publish PATH [--title T] [--description D] [--entry index.html] [--note N]` — zips the path and prints the page link. `.git/`, `.env*`, `credentials/`, `app-data/`, `.claude/`, `.cinna/`, `node_modules/`, key files and symlinks are never uploaded; the command lists what it left out. Private until shared. Publishing the same path again adds a revision to the same artifact (same link) — the CLI remembers `path → id` in `.cinna/artifacts.json`; `--update ID` names the artifact, `--new` publishes a separate one.
|
|
600
|
+
- `list [--shared]` · `show ID` (revisions, people, links) · `open ID` (browser) · `download ID [--rev N] [-o DIR]` (default `artifacts/<short-id>/`). Ids may be shortened to a unique prefix.
|
|
601
|
+
- `share ID [--instance | --private] [--user EMAIL]… [--remove-user EMAIL]…` and `link create ID [--expires 7d|12h|2w|never] [--code] [--label L] [--rev N]` — **a person runs these, in a terminal**: they refuse under `--json`, `--no-input` or without a TTY (code `needs_person`), and the account workspace's `.claude/settings.json` denies them to Claude Code. `link create` prints the link (and code) once.
|
|
602
|
+
- `link revoke ID LINK` (link id or token prefix, from `show`) · `delete ID` — both confirm; `--yes` is required with `--json`.
|
|
603
|
+
- `--json` (after the subcommand): NDJSON progress lines, then `{"result": "ok", "artifact_id", "action", "revision", "url", "excluded", …}`.
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
cinna artifacts publish ./reports/q3 --title "Q3 churn"
|
|
607
|
+
cinna artifacts publish ./reports/q3 # revision 2, same link
|
|
608
|
+
cinna artifacts share 3fa85f64 --user bob@example.com
|
|
609
|
+
cinna artifacts link create 3fa85f64 --expires 7d --code
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
The printed page link is a valid `link` artifact for `cinna delegation report --artifact`.
|
|
613
|
+
|
|
614
|
+
### `cinna dashboards list | show | check | run | ref | boards | board create | add | tiles | tile …`
|
|
615
|
+
|
|
616
|
+
Build, check, run and place an agent's **dashboard components**: folders in the agent's `dashboards/<name>/` (`component.json` plus endpoint scripts or a page) that the owner keeps as live tiles on a dashboard. Run from the account workspace. `AGENT` is a name, slug, id, or `.` for the agent workspace you are in. Every verb first checks the server's dashboards capability. While an environment wakes, verbs retry for `--timeout` seconds (default 120). Verbs that read the agent's cloud copy push your pending local edits first (`--no-flush` skips that).
|
|
617
|
+
|
|
618
|
+
- `list AGENT` · `show AGENT NAME [--skill S]` (`--skill` names a component a skill ships, on every verb that takes `NAME`): the components as the environment sees them (checker findings, where each is placed, including "Cinna Desktop") and the **reference** line `cinna://component/bundle:<bundle_id>/<name>` that offers one.
|
|
619
|
+
- `check AGENT [NAME] [--run]`: the owner's card checks; `--run` also runs each source in the environment through `cinna exec` (never locally). Exits 1 on any error.
|
|
620
|
+
- `run AGENT NAME [--endpoint E] [--param k=v]… [--params @file.json]`: run it exactly as a tile would. `--json` prints `{result, value, params_resolved, notice, fetched_at}`, where `value` is exactly what a tile receives.
|
|
621
|
+
- `ref AGENT NAME [--check]`: print only the reference line; `--check` asks core whether it resolves.
|
|
622
|
+
- `boards` · `board create NAME` · `add AGENT NAME --board B [--new-board] [--size s|m|l|wide|tall] [--param k=v] [--title T] [--max-age 15m] [--every 5m|manual] [--after-turn]`: the owner's web dashboards; place a tile (refused for a component with errors or a full dashboard).
|
|
623
|
+
- `tiles BOARD` · `tile data|refresh|params|call|edit|remove BOARD TILE …`: read and drive tiles. `tile params --set/--clear/--reset` sends the whole set; `tile edit` changes title (`''` resets it), size and refresh overrides. Tiles on Cinna Desktop's dashboards are read-only here.
|
|
624
|
+
- `cinna chat --agent AGENT --board B [--focus TILE] [--context @file.json] [--new-chat] "…"`: talk in the agent's dashboard chat, where it has its tile tools.
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
cinna dashboards check crm-agent deals --run
|
|
628
|
+
cinna dashboards run crm-agent deals --param stage=won
|
|
629
|
+
cinna dashboards ref crm-agent deals --check
|
|
630
|
+
cinna dashboards add crm-agent deals --board Sales --size l
|
|
631
|
+
cinna chat --agent crm-agent --board Sales --focus deals "Show only won deals"
|
|
632
|
+
```
|
|
633
|
+
|
|
593
634
|
### `cinna dev`
|
|
594
635
|
|
|
595
636
|
Start a foreground dev session — creates / resumes the Mutagen sync session for this workspace and attaches the terminal to a two-tab TUI (status + raw Mutagen details). Ctrl-C terminates the session; sync does not outlive the TUI. To observe sync from another terminal without affecting it, use `cinna sync status`.
|
|
@@ -368,6 +368,8 @@ At a terminal that preview is shown and confirmed before the press; `--yes`, `--
|
|
|
368
368
|
|
|
369
369
|
A re-publish appends a revision to the same package, so `--package-id` (the reverse-DNS id, e.g. `com.acme.report`) is only for a first publish — a mismatch on a later one is refused rather than silently ignored. `--visibility` is likewise honoured on a first publish and on an explicit change; omitting it leaves the package as it is. `--grant` requires `--visibility users` and the CLI refuses the combination otherwise, before anything is written. The server would accept it — it stores the grant either way — but a package that is private or public never consults its grant list, so the publish would report success and share nothing, and a revision cannot be taken back. Within a `users` package `--grant` is strictly **additive**: it adds the addresses it names and never revokes the ones it omits (revoking is `cinna skills revoke`, so a stale publish cannot silently remove access), and an unknown address fails the whole publish rather than half-sharing it. On success the package id, revision and its version, visibility and catalog URL are printed, plus a line saying the version landed in `skills/<name>/SKILL.md` — and a warning instead when it could not be written there, because the header and the catalog have then diverged and the next publish continues from the catalog. A refusal is printed as the platform's own sentence with its code (`not_developer`, `foreign_install`, `no_environment`, `workspace_unavailable`, `package_id_immutable`, `skill_contains_secrets` — which also lists the offending files), and `--json` prints `{revision, package, catalog_url, skill_md_updated}` instead of the human block (`--dry-run --json` prints the preview payload).
|
|
370
370
|
|
|
371
|
+
**A publish from the CLI is never refused as stale.** It goes through the agent path, which records the package's latest revision as the new one's base (`cinna skills revisions` shows it under **Based on**), so another maintainer's newer version is built on, not checked against. Cinna Desktop's Share instead sends the base its folder holds, and core refuses that share (`stale_base`) when a co-maintainer has shared a newer version since; the CLI never makes that call.
|
|
372
|
+
|
|
371
373
|
### `cinna skills catalog [--search Q] [--mine] [--json]`
|
|
372
374
|
|
|
373
375
|
Browse the instance skills catalog: one row per package this account may see, with its reverse-DNS **package id**, display name, visibility and newest version. The package id — `com.acme.pdf-report`, not a UUID — is the reference every other package verb takes. A delisted package is marked as such beside its visibility.
|
|
@@ -380,7 +382,7 @@ One package in full: its display name, visibility, newest version and package UU
|
|
|
380
382
|
|
|
381
383
|
### `cinna skills revisions <package> [--json]`
|
|
382
384
|
|
|
383
|
-
A package's revisions, **newest first**: number, version, release date, size and the release notes given at publish time. A revision is immutable, so this is the question a publisher has before every publish — what is already out there — and the answer to it no longer requires `cinna api` and a UUID. Pair it with `cinna skills publish <agent> <name> --dry-run`, which says what the *next* one would be.
|
|
385
|
+
A package's revisions, **newest first**: number, version, release date, size, **Shared by** (who published it, `—` once that account is deleted), **Based on** (`Version N`, the revision the sharer's copy held; `—` for a first revision, a share from an older Cinna Desktop, and any revision published before core recorded it) and the release notes given at publish time. A server older than skill co-maintainers sends neither field and both columns read `—`. `--json` passes the server's `published_by` and `base_revision_number` through untouched. A revision is immutable, so this is the question a publisher has before every publish — what is already out there — and the answer to it no longer requires `cinna api` and a UUID. Pair it with `cinna skills publish <agent> <name> --dry-run`, which says what the *next* one would be.
|
|
384
386
|
|
|
385
387
|
### `cinna skills files <package> [--revision N] [--json]`
|
|
386
388
|
|
|
@@ -538,7 +540,7 @@ Hand work to a remote agent as a **durable delegation** — a platform task with
|
|
|
538
540
|
|
|
539
541
|
- `create --id KEY --target AGENT_UUID --title T --brief B [--execute]` — the identity is `--target` + `--id`: a retry with the same pair returns the original task (changed title/brief are ignored) and never launches execution twice (the backend deduplicates). Prints the backend **task id** the other commands take, and whether it executes. `--depth 2 --root ROOT` makes a sub-delegation (`--root` is required at depth 2, not allowed at depth 1); `--group` tags related work.
|
|
540
542
|
- `status TASK_ID` — one read: state, latest result, and any open question with its result id. A requester agent should end its turn and let Cinna Desktop deliver the result rather than poll.
|
|
541
|
-
- `report [TASK_ID] --status in_progress|blocked|done|failed --summary S` — `blocked` needs `--question`; `--audience user` when a human must decide (default `requester`). `--artifact` (repeatable) is a JSON object with non-empty `kind` (backend accepts `file` or `link`), `name` and an `http(s)` `ref` — upload local files separately. `--body` adds detail.
|
|
543
|
+
- `report [TASK_ID] --status in_progress|blocked|done|failed --summary S` — `blocked` needs `--question`; `--audience user` when a human must decide (default `requester`). `--artifact` (repeatable) is a JSON object with non-empty `kind` (backend accepts `file` or `link`), `name` and an `http(s)` `ref` — upload local files separately (`cinna artifacts publish` prints such a link). `--body` adds detail.
|
|
542
544
|
- **Inside a cloud task**, omit `TASK_ID`: the report goes to the current task using `AGENT_AUTH_TOKEN`, `BACKEND_URL`, `ENV_ID` and the session in `CINNA_SESSION_CONTEXT_PATH` (default `./session_context.json`); the backend checks the session belongs to this environment's agent and owner.
|
|
543
545
|
- `reply TASK_ID --result-id ID --message M` — answer a blocked question.
|
|
544
546
|
- `--json` (after the subcommand) prints `{"result": "ok", "delegation": {…}}`.
|
|
@@ -553,6 +555,45 @@ cinna delegation report --status done --summary 'Finished' # inside the clou
|
|
|
553
555
|
|
|
554
556
|
Inside cloud tasks, cinna-core's MCP task server also offers a `handover_report` tool for the same report.
|
|
555
557
|
|
|
558
|
+
### `cinna artifacts publish | list | show | open | download | share | link | delete`
|
|
559
|
+
|
|
560
|
+
Publish a folder or a file to Cinna as an **artifact** — a frozen, versioned copy people open on a Cinna page (a folder with `index.html` runs as a sandboxed static site; other files open in viewers). Run from the account workspace. Every verb first checks the server's artifacts capability and refuses with "This Cinna server does not support artifacts" when it is missing.
|
|
561
|
+
|
|
562
|
+
- `publish PATH [--title T] [--description D] [--entry index.html] [--note N]` — zips the path and prints the page link. `.git/`, `.env*`, `credentials/`, `app-data/`, `.claude/`, `.cinna/`, `node_modules/`, key files and symlinks are never uploaded; the command lists what it left out. Private until shared. Publishing the same path again adds a revision to the same artifact (same link) — the CLI remembers `path → id` in `.cinna/artifacts.json`; `--update ID` names the artifact, `--new` publishes a separate one.
|
|
563
|
+
- `list [--shared]` · `show ID` (revisions, people, links) · `open ID` (browser) · `download ID [--rev N] [-o DIR]` (default `artifacts/<short-id>/`). Ids may be shortened to a unique prefix.
|
|
564
|
+
- `share ID [--instance | --private] [--user EMAIL]… [--remove-user EMAIL]…` and `link create ID [--expires 7d|12h|2w|never] [--code] [--label L] [--rev N]` — **a person runs these, in a terminal**: they refuse under `--json`, `--no-input` or without a TTY (code `needs_person`), and the account workspace's `.claude/settings.json` denies them to Claude Code. `link create` prints the link (and code) once.
|
|
565
|
+
- `link revoke ID LINK` (link id or token prefix, from `show`) · `delete ID` — both confirm; `--yes` is required with `--json`.
|
|
566
|
+
- `--json` (after the subcommand): NDJSON progress lines, then `{"result": "ok", "artifact_id", "action", "revision", "url", "excluded", …}`.
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
cinna artifacts publish ./reports/q3 --title "Q3 churn"
|
|
570
|
+
cinna artifacts publish ./reports/q3 # revision 2, same link
|
|
571
|
+
cinna artifacts share 3fa85f64 --user bob@example.com
|
|
572
|
+
cinna artifacts link create 3fa85f64 --expires 7d --code
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
The printed page link is a valid `link` artifact for `cinna delegation report --artifact`.
|
|
576
|
+
|
|
577
|
+
### `cinna dashboards list | show | check | run | ref | boards | board create | add | tiles | tile …`
|
|
578
|
+
|
|
579
|
+
Build, check, run and place an agent's **dashboard components**: folders in the agent's `dashboards/<name>/` (`component.json` plus endpoint scripts or a page) that the owner keeps as live tiles on a dashboard. Run from the account workspace. `AGENT` is a name, slug, id, or `.` for the agent workspace you are in. Every verb first checks the server's dashboards capability. While an environment wakes, verbs retry for `--timeout` seconds (default 120). Verbs that read the agent's cloud copy push your pending local edits first (`--no-flush` skips that).
|
|
580
|
+
|
|
581
|
+
- `list AGENT` · `show AGENT NAME [--skill S]` (`--skill` names a component a skill ships, on every verb that takes `NAME`): the components as the environment sees them (checker findings, where each is placed, including "Cinna Desktop") and the **reference** line `cinna://component/bundle:<bundle_id>/<name>` that offers one.
|
|
582
|
+
- `check AGENT [NAME] [--run]`: the owner's card checks; `--run` also runs each source in the environment through `cinna exec` (never locally). Exits 1 on any error.
|
|
583
|
+
- `run AGENT NAME [--endpoint E] [--param k=v]… [--params @file.json]`: run it exactly as a tile would. `--json` prints `{result, value, params_resolved, notice, fetched_at}`, where `value` is exactly what a tile receives.
|
|
584
|
+
- `ref AGENT NAME [--check]`: print only the reference line; `--check` asks core whether it resolves.
|
|
585
|
+
- `boards` · `board create NAME` · `add AGENT NAME --board B [--new-board] [--size s|m|l|wide|tall] [--param k=v] [--title T] [--max-age 15m] [--every 5m|manual] [--after-turn]`: the owner's web dashboards; place a tile (refused for a component with errors or a full dashboard).
|
|
586
|
+
- `tiles BOARD` · `tile data|refresh|params|call|edit|remove BOARD TILE …`: read and drive tiles. `tile params --set/--clear/--reset` sends the whole set; `tile edit` changes title (`''` resets it), size and refresh overrides. Tiles on Cinna Desktop's dashboards are read-only here.
|
|
587
|
+
- `cinna chat --agent AGENT --board B [--focus TILE] [--context @file.json] [--new-chat] "…"`: talk in the agent's dashboard chat, where it has its tile tools.
|
|
588
|
+
|
|
589
|
+
```bash
|
|
590
|
+
cinna dashboards check crm-agent deals --run
|
|
591
|
+
cinna dashboards run crm-agent deals --param stage=won
|
|
592
|
+
cinna dashboards ref crm-agent deals --check
|
|
593
|
+
cinna dashboards add crm-agent deals --board Sales --size l
|
|
594
|
+
cinna chat --agent crm-agent --board Sales --focus deals "Show only won deals"
|
|
595
|
+
```
|
|
596
|
+
|
|
556
597
|
### `cinna dev`
|
|
557
598
|
|
|
558
599
|
Start a foreground dev session — creates / resumes the Mutagen sync session for this workspace and attaches the terminal to a two-tab TUI (status + raw Mutagen details). Ctrl-C terminates the session; sync does not outlive the TUI. To observe sync from another terminal without affecting it, use `cinna sync status`.
|
|
@@ -25,7 +25,8 @@ The platform also handles scheduling, triggers, email, A2A, MCP serving, and ses
|
|
|
25
25
|
- Testing credential integrations (keys and tokens stay on the platform, exercised by the remote env)
|
|
26
26
|
- Installing and validating Python / system packages
|
|
27
27
|
- Writing and iterating on prompt files
|
|
28
|
-
- Building webapp
|
|
28
|
+
- Building the agent's webapp and data endpoints
|
|
29
|
+
- Building dashboard components, checking and running them in the env, placing them as tiles
|
|
29
30
|
- Preparing output files and reports
|
|
30
31
|
|
|
31
32
|
### What stays in the cloud
|
|
@@ -56,6 +57,10 @@ The live-sync rewrite removes the local container entirely. Mutagen keeps the wo
|
|
|
56
57
|
|
|
57
58
|
A self-contained automation unit on the platform. Has a name, template, scripts, prompts, webapp, credentials, and a knowledge base. Identified by `agent_id`.
|
|
58
59
|
|
|
60
|
+
### Dashboard component
|
|
61
|
+
|
|
62
|
+
A live view an agent keeps in `dashboards/<name>/` (`component.json` plus endpoint scripts or a page). The owner places it as a **tile** on a dashboard (core's web dashboards, or Cinna Desktop); the agent offers it by printing its reference `cinna://component/bundle:<bundle_id>/<name>`. It runs only in the agent's environment. See [Dashboards](features/dashboards/dashboards.md).
|
|
63
|
+
|
|
59
64
|
### Environment
|
|
60
65
|
|
|
61
66
|
The runtime container configuration for an agent on the platform. Each agent has exactly one environment. Environments may be suspended when idle; opening a sync WebSocket auto-activates them.
|
|
@@ -297,6 +302,8 @@ authoring convention.
|
|
|
297
302
|
| **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) |
|
|
298
303
|
| **Git versioning** | `cinna git` (link, status, commit, push, pull, log, checkout, unlink) — external remotes with your own credentials, `cinna` remotes with the CLI token | [business](features/git_versioning/git_versioning.md) · [tech](features/git_versioning/git_versioning_tech.md) · [acceptance](features/git_versioning/git_versioning_acceptance.md) |
|
|
299
304
|
| **Durable delegation** | `cinna delegation` (create — idempotent per target + `--id`, status, report — owner side with a task id or from inside a cloud task, reply), gated on the backend capability version | [business](features/delegation/delegation.md) · [tech](features/delegation/delegation_tech.md) · [acceptance](features/delegation/delegation_acceptance.md) |
|
|
305
|
+
| **Artifacts** | `cinna artifacts` (publish — republishes a remembered path, `--new` / `--update`; list, show, open, download, share and link create — person-only, refused without a TTY; link revoke, delete), gated on the server's artifacts capability | [business](features/artifacts/artifacts.md) · [tech](features/artifacts/artifacts_tech.md) · [acceptance](features/artifacts/artifacts_acceptance.md) |
|
|
306
|
+
| **Dashboards** | `cinna dashboards` (list, show, check `[--run]`, run, ref `[--check]` — an agent's components as its environment sees them; boards, board create, add, tiles, tile data / refresh / params / call / edit / remove — tiles on the owner's web dashboards, desktop dashboards read-only) · `cinna chat --board [--focus] [--context] [--new-chat]` (dashboard chat with the tile tools); gated on the server's dashboards capability | [business](features/dashboards/dashboards.md) · [tech](features/dashboards/dashboards_tech.md) · [acceptance](features/dashboards/dashboards_acceptance.md) |
|
|
300
307
|
| **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) |
|
|
301
308
|
| **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) |
|
|
302
309
|
| **Team library** | `cinna library` (list, get, share, update, status, grants, suggest) — kit folders in `Local/<slug>/` shared through cinna-core-hosted git with the account token; `cinna agent import --from-library` | [business](features/team_library/team_library.md) · [tech](features/team_library/team_library_tech.md) · [acceptance](features/team_library/team_library_acceptance.md) |
|
|
@@ -525,6 +532,8 @@ The platform's send-message route (`POST /sessions/{id}/messages/stream`) return
|
|
|
525
532
|
3. Records the current message count as a cursor, then sends the message (`file_ids` carry the attachments).
|
|
526
533
|
4. **Polls** `GET /sessions/{id}/messages?offset=<cursor>` (messages are ordered ascending by `sequence_number`, so `offset` is the cursor) and `GET …/messages/streaming-status` (`{is_streaming}`) until the turn settles — `is_streaming` false with no message flagged `streaming_in_progress`. A start-grace window covers env wake / queueing before the turn begins; an overall `--timeout` bounds the wait.
|
|
527
534
|
|
|
535
|
+
With `--board`, the session is the agent's **dashboard chat** (`POST /dashboards/{id}/chat`), each message carries `dashboard_context`, and a `tiles` event before `done` reports tiles whose params the turn changed (see [Dashboards](features/dashboards/dashboards.md)).
|
|
536
|
+
|
|
528
537
|
Each finalized message is emitted as one NDJSON line (`session` / `upload` / `message` / `status` / `done`); the in-progress assistant message is held back (its content is still growing) and emitted once final. Every `message` also carries the agent's reasoning/tool trace under **`events`** — the normalized `streaming_events` (thinking blocks, `tool` calls with their full `tool_input` payloads, tool results), with the bookkeeping/`attachment` entries stripped (attachments are surfaced separately). The final coalesced text stays in `content`; the trace shows *how* the agent got there. `--no-events` drops the trace; `--pretty` swaps NDJSON for a Rich transcript. Ctrl-C calls `POST …/messages/interrupt` and exits 130.
|
|
529
538
|
|
|
530
539
|
### Attachments
|
|
@@ -625,6 +634,7 @@ When a CLI token expires (or is revoked) the normal remedy is `cinna set-token <
|
|
|
625
634
|
| POST | `/api/v1/cli/account/agents/{id}/mint` | Account token | Mint a per-agent CLI token (`cinna agent sync`, `cinna doctor` re-mint) |
|
|
626
635
|
| 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 |
|
|
627
636
|
| POST | `/api/v1/cli/account/files/upload` | Account token | Multipart upload for `cinna chat --file` (the proxy can't carry multipart) |
|
|
637
|
+
| (proxy) | `dashboards/capabilities`, `agents/{id}/dashboards/…`, `dashboards/…`, `dashboards/{id}/blocks/{block}/component/…`, `dashboards/{id}/chat`, `dashboards/component-refs/resolve` | Account token | `cinna dashboards` and `cinna chat --board`, all through the api-proxy; never the `…/frame` routes (core's proxy refuses them) |
|
|
628
638
|
| 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 |
|
|
629
639
|
|
|
630
640
|
`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`.
|
|
@@ -178,7 +178,13 @@ each with its own token, registry entry, and Mutagen session.
|
|
|
178
178
|
- `cinna account refresh-context` re-downloads `context/` and regenerates the
|
|
179
179
|
orchestrator `CLAUDE.md`, the MCP wiring, and every synced child's per-agent
|
|
180
180
|
`CLAUDE.md` from the bundled templates — so a CLI upgrade's new commands reach
|
|
181
|
-
existing workspaces without a re-setup.
|
|
181
|
+
existing workspaces without a re-setup. A child whose config predates the
|
|
182
|
+
`bundle_id` field gets it filled in first (best effort), so its guide's
|
|
183
|
+
Dashboard components section carries the agent's own reference prefix.
|
|
184
|
+
- The orchestrator `CLAUDE.md` has a **Dashboards** command table and a
|
|
185
|
+
"Which one?" note (webapp / dashboard component / artifact). The Artifacts
|
|
186
|
+
heading says "a frozen copy", and its starter points at
|
|
187
|
+
`artifact-sqlite-report/`. See [Dashboards](../dashboards/dashboards.md).
|
|
182
188
|
|
|
183
189
|
## Business rules / guardrails
|
|
184
190
|
|
|
@@ -219,7 +225,9 @@ each with its own token, registry entry, and Mutagen session.
|
|
|
219
225
|
orchestrator/child `CLAUDE.md` regeneration is offline and per-workspace, so one
|
|
220
226
|
unreadable child never aborts the rest.
|
|
221
227
|
- **User-edited config is preserved.** `.claude/settings.json` is create-if-absent
|
|
222
|
-
(never clobbered on refresh
|
|
228
|
+
(never clobbered on refresh; an existing file only gains the two `deny` rules
|
|
229
|
+
that keep `cinna artifacts share` / `link create` away from Claude Code — see
|
|
230
|
+
[Artifacts](../artifacts/artifacts.md)); `.mcp.json` / `opencode.json` and the generated
|
|
223
231
|
`CLAUDE.md` are auto-generated infra and are overwritten.
|
|
224
232
|
- **Child checkouts are standard.** A synced child is identical to a `cinna setup`
|
|
225
233
|
checkout — same Model-A layout, same auto-link when git-versioned, same
|
{cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/account_workspace/account_workspace_acceptance.md
RENAMED
|
@@ -53,7 +53,9 @@ the silent-secret and scope-drift bugs live.
|
|
|
53
53
|
`account_token` / `platform_url` / `frontend_url` / `machine_name`; an empty
|
|
54
54
|
`agents/` dir; an orchestrator `CLAUDE.md` (contains "Account Workspace");
|
|
55
55
|
`.claude/settings.json` with `permissions.allow == ["Bash(cinna:*)",
|
|
56
|
-
"mcp__platform-knowledge"]`
|
|
56
|
+
"mcp__platform-knowledge"]`, `permissions.deny == ["Bash(cinna artifacts
|
|
57
|
+
share:*)", "Bash(cinna artifacts link create:*)"]` and
|
|
58
|
+
`enableAllProjectMcpServers: true`; `.mcp.json`
|
|
57
59
|
+ `opencode.json` pointing the proxy at `.cinna/account.json` via
|
|
58
60
|
`CINNA_ACCOUNT_CONFIG`; a `context/` tree; and the next-step hints
|
|
59
61
|
(`cinna account agents`, `cinna agent sync`).
|
|
@@ -226,7 +228,8 @@ the silent-secret and scope-drift bugs live.
|
|
|
226
228
|
- **Expected:** `context/` is replaced (old-only files gone); the orchestrator
|
|
227
229
|
`CLAUDE.md`, `.mcp.json`/`opencode.json`, and **every** synced child's
|
|
228
230
|
per-agent `CLAUDE.md` are regenerated from the bundled templates; a
|
|
229
|
-
user-edited `.claude/settings.json`
|
|
231
|
+
user-edited `.claude/settings.json` keeps every entry and only gains the
|
|
232
|
+
artifact `deny` rules it lacks; the run reports how many
|
|
230
233
|
child workspaces were regenerated.
|
|
231
234
|
- **Watch for (non-destructive rule):** simulate a download failure (point at an
|
|
232
235
|
unreachable platform) and confirm the **old `context/` survives** and the
|
|
@@ -388,7 +391,8 @@ the silent-secret and scope-drift bugs live.
|
|
|
388
391
|
- **Single-use setup token is never burned on a doomed run** — guards precede the
|
|
389
392
|
exchange.
|
|
390
393
|
- **No silent clobber** — `refresh-context` removes the old `context/` only after
|
|
391
|
-
a successful download; user-edited `.claude/settings.json` is never overwritten
|
|
394
|
+
a successful download; user-edited `.claude/settings.json` is never overwritten
|
|
395
|
+
(only the missing artifact `deny` rules are merged in).
|
|
392
396
|
- **No state drift between commands** — a synced child is a standard per-agent
|
|
393
397
|
workspace (registry + config) indistinguishable from `cinna setup`; the active
|
|
394
398
|
user workspace is the single source for both the listing scope and the create
|
{cinna_cli-0.5.2 → cinna_cli-0.6.0}/docs/features/account_workspace/account_workspace_tech.md
RENAMED
|
@@ -344,7 +344,9 @@ All consumed by `src/cinna/client.py:AccountClient` with the account token
|
|
|
344
344
|
`CLAUDE.md` regeneration is independent of the download.
|
|
345
345
|
(`tests/test_account.py:test_refresh_context_failure_preserves_old_tree`)
|
|
346
346
|
- **Settings is create-if-absent** — `_write_account_claude_settings` never
|
|
347
|
-
clobbers a user-edited `.claude/settings.json
|
|
347
|
+
clobbers a user-edited `.claude/settings.json`; it only appends the missing
|
|
348
|
+
`artifacts.person_only_deny_rules()` to `permissions.deny`, and leaves a file
|
|
349
|
+
that is not a JSON object alone.
|
|
348
350
|
(`tests/test_account.py:test_refresh_context_preserves_user_claude_settings`)
|
|
349
351
|
- **Per-agent URL is rejected** — `parse_account_setup_input` must not silently
|
|
350
352
|
accept a `/cli-setup/<token>` (non-account) URL.
|
|
@@ -242,6 +242,20 @@ change without cutting a new one:
|
|
|
242
242
|
it never revokes (revoking is its own verb in the web UI, so a stale
|
|
243
243
|
invocation cannot silently remove access). An unknown address fails the whole
|
|
244
244
|
publish rather than half-sharing it.
|
|
245
|
+
- **A CLI publish is never refused as stale.** It goes through the agent path
|
|
246
|
+
(`POST /agents/{id}/skills/{name}/publish`), which records the package's
|
|
247
|
+
latest revision as the new revision's base, so a version a co-maintainer
|
|
248
|
+
shared in the meantime is built on rather than checked against. Cinna
|
|
249
|
+
Desktop's Share sends the base its folder holds instead, and core refuses
|
|
250
|
+
that share (`stale_base`) when a co-maintainer has shared a newer version
|
|
251
|
+
since. The CLI never calls the desktop upload, so it never sees
|
|
252
|
+
`stale_base` or `editable_package_exists`.
|
|
253
|
+
- **Each revision names who shared it and what it was based on.**
|
|
254
|
+
`cinna skills revisions` and `cinna skills show` print **Shared by** (the
|
|
255
|
+
publisher's display name, `—` once the account is deleted) and **Based on**
|
|
256
|
+
(`Version N`, the revision the sharer's copy held; `—` for a first revision,
|
|
257
|
+
a share from an older Cinna Desktop, and any revision published before core
|
|
258
|
+
recorded it). An older server sends neither field and both read `—`.
|
|
245
259
|
- **Publishing reads the cloud workspace.** The files come from the agent's
|
|
246
260
|
remote workspace on disk — which is why a suspended environment publishes
|
|
247
261
|
normally — so an unsynced local edit is simply not in the revision. Push
|
|
@@ -516,11 +516,36 @@ cinna skills revisions <PACKAGE_ID>
|
|
|
516
516
|
```
|
|
517
517
|
|
|
518
518
|
**Expected** — one row per revision, newest first, with number, version, release
|
|
519
|
-
date, size and the `release_notes` given at publish
|
|
519
|
+
date, size, **Shared by**, **Based on** and the `release_notes` given at publish
|
|
520
|
+
time.
|
|
520
521
|
|
|
521
522
|
**Watch for** — a permanently blank notes column (the field is `release_notes`,
|
|
522
523
|
not `notes`); ascending order, which buries the answer at the bottom.
|
|
523
524
|
|
|
525
|
+
### 20a. Each revision names who shared it and what it was based on
|
|
526
|
+
|
|
527
|
+
**Goal** — the revision table shows the sharer and the base core recorded, and a
|
|
528
|
+
CLI re-publish is recorded as built on the latest revision. Needs core
|
|
529
|
+
d08c10d8 and 465c43c2 (revisions carrying `published_by` and
|
|
530
|
+
`base_revision_number`).
|
|
531
|
+
|
|
532
|
+
**Steps** — after scenarios 4 and 5 have published `acceptance-demo` twice:
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
cinna skills revisions <PACKAGE_ID>
|
|
536
|
+
cinna skills revisions <PACKAGE_ID> --json
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Expected** — the table has **Shared by** and **Based on** columns. Revision 2
|
|
540
|
+
reads **Based on** `Version 1`; revision 1 reads `—` there (a first revision has
|
|
541
|
+
no base). Both rows name the publisher's display name under **Shared by**.
|
|
542
|
+
`--json` carries the server's `published_by` (`{user_id, display_name}`) and
|
|
543
|
+
`base_revision_number` (`1` on revision 2, `null` on revision 1) as sent.
|
|
544
|
+
|
|
545
|
+
**Watch for** — revision 2 with no base (the agent publish path did not record
|
|
546
|
+
one); a crash or a blank cell instead of `—` on a revision published before
|
|
547
|
+
core recorded these fields.
|
|
548
|
+
|
|
524
549
|
### 21. Sharing changes after the publish
|
|
525
550
|
|
|
526
551
|
**Steps**
|
|
@@ -139,6 +139,10 @@
|
|
|
139
139
|
- `src/cinna/account.py:_revision_rows()` — revisions sorted newest first. The
|
|
140
140
|
question this list answers is "what is the newest"; a payload that happened to
|
|
141
141
|
be ascending would put the answer at the bottom.
|
|
142
|
+
- `src/cinna/account.py:_revision_shared_by()` / `_revision_based_on()` — the
|
|
143
|
+
revision table's **Shared by** (`published_by.display_name`) and **Based on**
|
|
144
|
+
(`Version <base_revision_number>`) cells, each `—` when the field is null or
|
|
145
|
+
absent.
|
|
142
146
|
- `src/cinna/account.py:_addon_link()` — the row's `link` sub-object. Every
|
|
143
147
|
fact about an *install* rather than a package lives there: `id` (the link id
|
|
144
148
|
the plugin routes address), `installed_version`, `latest_version`,
|
|
@@ -242,11 +246,19 @@ hatch, `POST /api/v1/cli/account/api-proxy`:
|
|
|
242
246
|
`grant_emails`, `package_id`). Returns the new revision; consumed fields are
|
|
243
247
|
`package_id` (the package's UUID), `revision_number`, `version` and
|
|
244
248
|
`frontmatter` (the last one only to tell whether the version reached the
|
|
245
|
-
workspace's `SKILL.md`).
|
|
249
|
+
workspace's `SKILL.md`). Core records the package's previous latest revision
|
|
250
|
+
as the new one's `base_revision_number`; this route never answers
|
|
251
|
+
`stale_base` or `editable_package_exists` — those come only from the desktop
|
|
252
|
+
upload (`POST /skills/packages/publish`), which the CLI does not call.
|
|
246
253
|
- `GET /api/v1/skills/packages/{package_id}` — consumed fields are the
|
|
247
254
|
reverse-DNS `package_id` string, `display_name`, `visibility`,
|
|
248
255
|
`latest_version` and `revisions[]` (`revision_number`, `version`,
|
|
249
|
-
`created_at`, `release_notes` — **not** `notes` —
|
|
256
|
+
`created_at`, `release_notes` — **not** `notes` — `size_bytes`,
|
|
257
|
+
`published_by` `{user_id, display_name}` (null once the account is deleted)
|
|
258
|
+
and `base_revision_number` (int or null)). The last two are absent on a
|
|
259
|
+
server older than skill co-maintainers; `_revision_shared_by()` and
|
|
260
|
+
`_revision_based_on()` render a missing or null value as `—`, and `--json`
|
|
261
|
+
passes both through untouched.
|
|
250
262
|
- `POST /api/v1/agents/{agent_id}/skills/install` — `SkillInstallRequest`:
|
|
251
263
|
`package_id` (the package **UUID**), optional `revision_number`,
|
|
252
264
|
`conversation_mode`, `building_mode`. Answers `PluginSyncResponse`; 409
|
|
@@ -66,10 +66,14 @@ This doc covers the agent **lifecycle** verbs. The CRON automation subgroup
|
|
|
66
66
|
conflicts against untouched remote originals. A session that cannot start is a
|
|
67
67
|
warning naming `cinna sync push --agent <slug>` to run *before* editing — never
|
|
68
68
|
a failed sync.
|
|
69
|
-
3.
|
|
69
|
+
3. Sync also records the agent's **bundle id** and the environment's **platform
|
|
70
|
+
skills** in the workspace config. The per-agent `CLAUDE.md` uses them for its
|
|
71
|
+
Dashboard components section: the agent's own `cinna://component/bundle:<id>/`
|
|
72
|
+
prefix, and the path to the account's kit copy of the `cinna-dashboards` skill.
|
|
73
|
+
4. Re-running sync for an agent **already synced** in that folder is refused
|
|
70
74
|
(with a `cinna agent unsync` / `cinna set-token` hint) — it never silently
|
|
71
75
|
re-clones or duplicates.
|
|
72
|
-
|
|
76
|
+
5. The workspace lands at `agents/<slug>/<subdir>/` (the Model-A nested layout;
|
|
73
77
|
`<subdir>` is the slug unless the agent is git-versioned with another subdir) —
|
|
74
78
|
the command prints the exact path. Afterward `cd` there and `cinna dev`, or stay
|
|
75
79
|
at the account root and use `cinna sync push --agent <slug>` /
|
|
@@ -92,6 +96,12 @@ This doc covers the agent **lifecycle** verbs. The CRON automation subgroup
|
|
|
92
96
|
re-materializes the backend scaffold and can clobber local changes, so the
|
|
93
97
|
builder is told to `cinna sync push` first.
|
|
94
98
|
3. It blocks until the container is back, then prints the post-restart status.
|
|
99
|
+
4. If the agent is synced on this machine, it then **reconnects the sync
|
|
100
|
+
session** ("Sync session reconnected."). The old container took the remote
|
|
101
|
+
Mutagen agent with it, and without this the next `cinna sync push` failed
|
|
102
|
+
until Mutagen's own retry came round. A refused token is re-minted through
|
|
103
|
+
the account. A session that doesn't come back is a warning naming
|
|
104
|
+
`cinna sync push` / `cinna doctor`, never a failed restart.
|
|
95
105
|
|
|
96
106
|
### Rebuild an environment that predates a feature
|
|
97
107
|
1. `cinna agent rebuild-env <agent_ref> [--yes]` is **not** a louder restart.
|
|
@@ -120,6 +130,8 @@ This doc covers the agent **lifecycle** verbs. The CRON automation subgroup
|
|
|
120
130
|
row states; the server inside can still be starting, and a chat sent into that
|
|
121
131
|
window sat streaming with no reply. It ends with "ready to chat", or a warning
|
|
122
132
|
that the environment has not answered yet.
|
|
133
|
+
7. Like `restart-env`, it then reconnects this machine's sync session for the
|
|
134
|
+
agent (see [Live Sync](../live_sync/live_sync.md)).
|
|
123
135
|
|
|
124
136
|
### Inspect what's live
|
|
125
137
|
1. `cinna agent show <agent_ref>` prints the **effective prompts** (each under its
|
|
@@ -132,6 +144,11 @@ This doc covers the agent **lifecycle** verbs. The CRON automation subgroup
|
|
|
132
144
|
`credentials:` block names. A credential shared by someone else whose slot
|
|
133
145
|
this account cannot see reads `slot: unknown`, never `no slot`. When the
|
|
134
146
|
agent's credential listing cannot be read, it falls back to name + type.
|
|
147
|
+
- A **Dashboard components** section (count, errors, tiles) when the server
|
|
148
|
+
has dashboards. It is read only while the environment is running, because
|
|
149
|
+
listing components would wake a suspended one; otherwise a dim note says the
|
|
150
|
+
environment's state. It never fails `show`. See
|
|
151
|
+
[Dashboards](../dashboards/dashboards.md).
|
|
135
152
|
|
|
136
153
|
### Choose the model per mode
|
|
137
154
|
1. `cinna agent model show <agent_ref> [--json]` prints, for conversation and
|
|
@@ -66,7 +66,13 @@ The group/subgroup objects are `src/cinna/main.py:agent()` and
|
|
|
66
66
|
- `src/cinna/account.py:run_agent_restart_env()` — resolve the agent; if a local
|
|
67
67
|
child workspace exists (`resolve_child_workspace()`), read `sync_session.status()`
|
|
68
68
|
and warn+confirm when `pending_to_remote > 0` or `conflict_count > 0`; then
|
|
69
|
-
`AccountClient.restart_agent_env()` (blocking) and print status
|
|
69
|
+
`AccountClient.restart_agent_env()` (blocking) and print status, then
|
|
70
|
+
`_reconnect_sync_session()`.
|
|
71
|
+
- `src/cinna/account.py:_reconnect_sync_session()` — shared by restart and
|
|
72
|
+
rebuild: for the child workspace of this agent (`list_child_workspaces()`)
|
|
73
|
+
whose session exists, `sync_session.heal_session(child_cfg, child)` (a forced
|
|
74
|
+
reconnect, plus a token re-mint on a 401/403). It prints "Sync session
|
|
75
|
+
reconnected." or a warning, and never raises.
|
|
70
76
|
- `src/cinna/account.py:run_agent_rebuild_env()` — the same shape as
|
|
71
77
|
`run_agent_restart_env()` plus a second gate: the D2 unsynced-changes
|
|
72
78
|
warn+confirm, then a `Rebuild …?` confirmation (default No) that `--yes`
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Artifacts (`cinna artifacts`)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Publish a folder or a file from the user's machine to cinna-core as an
|
|
6
|
+
**artifact** — a frozen, versioned copy people open on a Cinna page — and get a
|
|
7
|
+
link back. The same command group lists, downloads, opens, shares and deletes
|
|
8
|
+
artifacts from a terminal.
|
|
9
|
+
|
|
10
|
+
## Mental model / core concepts
|
|
11
|
+
|
|
12
|
+
An artifact lives **in cinna-core**, not on the machine and not in an agent
|
|
13
|
+
environment. The CLI is a publisher and a remote control; once published, the
|
|
14
|
+
artifact outlives the folder, the agent and the session it came from.
|
|
15
|
+
|
|
16
|
+
- **Artifact** — a stable identity (title, who can see it, its page link) over a
|
|
17
|
+
sequence of immutable **revisions**. Core renders it: a folder with an
|
|
18
|
+
`index.html` runs as a small static site in a sandbox; anything else is a file
|
|
19
|
+
set with viewers (Markdown, CSV, PDF, images, code). Not to be confused with a
|
|
20
|
+
delegation's `--artifact` — a link attached to a task result (see Integration
|
|
21
|
+
points).
|
|
22
|
+
- **Revision** — one publish of the files. Republishing adds a revision; the
|
|
23
|
+
page link stays the same and shows the latest one, so a shared link never
|
|
24
|
+
breaks when a report is refreshed.
|
|
25
|
+
- **Path memory** — the CLI remembers which artifact each local path was
|
|
26
|
+
published as, per account workspace (`.cinna/artifacts.json`), and republishes
|
|
27
|
+
into it. Nothing is ever written into the published folder itself.
|
|
28
|
+
- **Exclusions** — what never leaves the machine: `.git/`, `.env*` and `*.env`,
|
|
29
|
+
`credentials/`, `credentials.json`, `app-data/`, `.claude/`, `.cinna/` (it
|
|
30
|
+
holds the account token), `node_modules/`, `__pycache__/`, key and token
|
|
31
|
+
files (`*.pem`, `*.key`, `*.p12`, `id_rsa*` and the other SSH key names,
|
|
32
|
+
`.netrc`, `.npmrc`, `.pypirc`), `.DS_Store`, and every symlink. Mandatory, not
|
|
33
|
+
advisory; core drops its own set again on its side.
|
|
34
|
+
- **Who can see it** — "Only you" (private, the default), plus named people,
|
|
35
|
+
plus "Everyone on the instance", plus **public links** (anyone holding the
|
|
36
|
+
link, signed out; optional expiry, optional 4-digit code, revocable,
|
|
37
|
+
optionally pinned to a revision). The CLI never says "public" for
|
|
38
|
+
instance-wide.
|
|
39
|
+
- **Agents publish, people share** — an agent in the account workspace may
|
|
40
|
+
publish (always private) and manage its artifacts, but widening who can see
|
|
41
|
+
one is the user's call: `share` and `link create` are person-only verbs.
|
|
42
|
+
|
|
43
|
+
## User flows
|
|
44
|
+
|
|
45
|
+
### Publish a report and get its link
|
|
46
|
+
1. `cinna artifacts publish ./reports/q3 --title "Q3 churn"` from the account
|
|
47
|
+
workspace (or any folder below it).
|
|
48
|
+
2. The CLI prints the file count and size, then what it left out
|
|
49
|
+
(`.git/`, `.env`, …), uploads, and prints the page link and the id.
|
|
50
|
+
3. The artifact is private; the user opens the link (or
|
|
51
|
+
`cinna artifacts open <id>`) to check it.
|
|
52
|
+
|
|
53
|
+
### Refresh it later, same link
|
|
54
|
+
4. Run the same `cinna artifacts publish ./reports/q3` again. The CLI says it
|
|
55
|
+
republished — revision 2, same link — because it remembered the path.
|
|
56
|
+
5. `--update <id>` republishes into a named artifact instead; `--new` publishes
|
|
57
|
+
a separate artifact even though the path is known (the path then points at
|
|
58
|
+
the new one).
|
|
59
|
+
|
|
60
|
+
### Share it with people
|
|
61
|
+
6. In their own terminal the user runs
|
|
62
|
+
`cinna artifacts share <id> --user bob@example.com` and/or `--instance`;
|
|
63
|
+
`--private` and `--remove-user` narrow it again. The CLI prints who can see
|
|
64
|
+
it afterwards.
|
|
65
|
+
7. For someone outside the instance:
|
|
66
|
+
`cinna artifacts link create <id> [--expires 7d] [--code] [--label …] [--rev N]`
|
|
67
|
+
prints the link (and code) **once**. `cinna artifacts show <id>` lists links
|
|
68
|
+
by id and prefix; `cinna artifacts link revoke <id> <link>` kills one.
|
|
69
|
+
|
|
70
|
+
### Find, fetch, remove
|
|
71
|
+
8. `cinna artifacts list` (yours) or `list --shared` (shared with you);
|
|
72
|
+
`show <id>` for revisions, people and links.
|
|
73
|
+
9. `cinna artifacts download <id> [--rev N] [-o DIR]` extracts the files
|
|
74
|
+
(default `artifacts/<short-id>/` under the account root).
|
|
75
|
+
10. `cinna artifacts delete <id>` asks first; the page and every link stop
|
|
76
|
+
working at once.
|
|
77
|
+
|
|
78
|
+
## Business rules
|
|
79
|
+
|
|
80
|
+
- **Server support first** — every verb asks core for its artifacts capability
|
|
81
|
+
before anything else; a server without it (or with another version) gets
|
|
82
|
+
"This Cinna server does not support artifacts" and nothing is uploaded.
|
|
83
|
+
- **A secret path named directly is refused** — publishing `.cinna/account.json`,
|
|
84
|
+
a `credentials/` folder or anything inside an excluded folder stops before
|
|
85
|
+
any request; the walk alone would only see paths below what was named.
|
|
86
|
+
- **Exclusions are listed, always** — the human output and the `--json` result
|
|
87
|
+
name every path left out, the CLI's and the server's together.
|
|
88
|
+
- **Refuse what core would refuse, before uploading** — over the file count,
|
|
89
|
+
per-file size or total size the server advertises, the CLI stops locally.
|
|
90
|
+
- **Republish keeps the title** — on a republish only the flags the user passes
|
|
91
|
+
change (`--title`, `--description`, `--entry`, `--note`).
|
|
92
|
+
- **A remembered artifact that was deleted** — the CLI says so and publishes a
|
|
93
|
+
new one; an explicit `--update <id>` that no longer exists fails instead.
|
|
94
|
+
- **Person-only verbs (A8)** — `share` and `link create` refuse under `--json`,
|
|
95
|
+
`--no-input` / `CINNA_NO_INPUT`, or when stdin is not a terminal, with code
|
|
96
|
+
`needs_person`. There is no `--yes` bypass: an agent can pass any flag. The
|
|
97
|
+
generated `.claude/settings.json` also denies `Bash(cinna artifacts share:*)`
|
|
98
|
+
and `Bash(cinna artifacts link create:*)` to Claude Code. The CLI cannot tell
|
|
99
|
+
an agent from a person — this is a speed bump; core enforces A8 on its
|
|
100
|
+
agent-token route.
|
|
101
|
+
- **A script cannot share either** — a script without a terminal is refused the
|
|
102
|
+
same way. Sharing from automation is deliberately not offered in v1; the web
|
|
103
|
+
page's Share dialog is the alternative.
|
|
104
|
+
- **Destructive verbs confirm** — `delete` and `link revoke` ask (default No);
|
|
105
|
+
under `--json` they need `--yes`, under `--no-input` without `--yes` they
|
|
106
|
+
abort.
|
|
107
|
+
- **The link token is shown once** — core returns it only on creation; the
|
|
108
|
+
api-proxy never relays it, and `show` lists links by prefix only.
|
|
109
|
+
- **Owner-only writes** — share, link and delete check ownership first and say
|
|
110
|
+
so plainly rather than relaying a 404.
|
|
111
|
+
|
|
112
|
+
## Architecture overview
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
cinna artifacts publish PATH
|
|
116
|
+
→ artifacts.py: walk + exclusions → temp zip (stored entries for very compressible files)
|
|
117
|
+
→ AccountClient → POST /cli/account/artifacts[/{id}/revisions] (multipart, account token)
|
|
118
|
+
→ .cinna/artifacts.json (path → artifact id)
|
|
119
|
+
|
|
120
|
+
cinna artifacts list|show|share|link revoke|delete
|
|
121
|
+
→ AccountClient → api-proxy → /api/v1/artifacts…, /users/search
|
|
122
|
+
|
|
123
|
+
cinna artifacts link create | download
|
|
124
|
+
→ AccountClient → /cli/account/artifacts/{id}/links | /download
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Integration points
|
|
128
|
+
|
|
129
|
+
- [Account workspace](../account_workspace/account_workspace.md) — the account
|
|
130
|
+
token, the active user workspace the artifact lands in, and the generated
|
|
131
|
+
`.claude/settings.json` that carries the deny rules.
|
|
132
|
+
- [Durable delegation](../delegation/delegation.md) — the page link a publish
|
|
133
|
+
prints is a valid `link` artifact for
|
|
134
|
+
`cinna delegation report --artifact '{"kind":"link","name":"…","ref":"<url>"}'`.
|
|
135
|
+
- `cinna api` — the generic api-proxy the JSON verbs ride; it refuses link
|
|
136
|
+
creation and blanks link codes, which is why `link create` has its own route.
|
|
137
|
+
- cinna-core's kit skill `cinna-artifacts` — how to build a folder that works
|
|
138
|
+
in the sandbox (bundle libraries, no `localStorage`, relative paths).
|