Skip to content

Save rendered Card instances as independent Files - #133

Open
Lancetnik wants to merge 3 commits into
feat/cards-settingsfrom
feat/card-instances
Open

Lancetnik wants to merge 3 commits into
feat/cards-settingsfrom
feat/card-instances

Conversation

@Lancetnik

Copy link
Copy Markdown
Member

Why are these changes needed?

A useful rendered Card could only be revisited through its Chat. Add an explicit Save instance action that captures the complete displayed layout and current local values into an independent .card-instance.yaml file, after the user confirms its filename and Directory. Save definition remains a separate action.

FilesTree opens saved instances with the shared Card renderer in passive mode. Inputs and nested actions are disabled; the existing source editor retains its ETag conflict and unsaved-change flows. Saved copies remain readable after restart, Chat deletion, or catalog changes, and can be edited, moved or copied with ordinary Files controls.

The profile-scoped API validates self-contained primitive layouts and confines paths to Files. Creation is atomic and never overwrites a destination. Stable request receipts preserve retries across restarts, edits and ordinary file copies. A typed save event records confirmation once; if recording fails after the file is created, the UI reports that state and retries the same frozen request.

Stack: #129 → #130 → #132 → this PR. Base: feat/cards-settings at 122eb90983e6144e873acac52b073512f27c8a93. The diff contains only the instance feature and its supporting tests/docs.

Related issue number

Related to #86; implements the revised independent-copy model in ADR 0043. The original issue's automatic exports and live Chat/file relationship were replaced by the agreed specification.

Checks

  • I ran ruff check ., ruff format --check ., and pytest -m "not integration" locally and they pass.
  • If I changed anything under web/, I rebuilt and committed the SPA bundle (npm --prefix web run build).
  • I've included any doc changes needed for this change.
  • I've added or updated tests corresponding to the changes (if relevant).

Validation: 2378 Python tests passed (2 skipped), 548 SPA tests passed, mypy passed, and Svelte check reported no errors or warnings. After review fixes, the affected API/feedback tests and final SPA checks passed. A live Google Chrome pass verified cancellation, Save as, local and repeated-row values, FilesTree opening, passive controls, reload, source edits, Chat independence, and identical retry payloads through moved-file conflicts. DevTools console/network monitoring found no runtime errors, unexpected failed requests or preview-triggered actions. Standards and Spec reviews have no remaining findings.

AI assistance

Significant implementation, tests, documentation and PR drafting assistance from Codex. Two separate agents reviewed Standards and Spec; their findings were fixed and rechecked. The checks below reflect the agent's review and validation, not a claim of the maintainer's personal review.

  • I understand the changes in this PR and can explain them in my own words.
  • I have verified that this description accurately reflects the actual diff.
  • If AI assistance was used, I reviewed, tested, and validated the generated code/text before submitting.

@Lancetnik
Lancetnik added this pull request to stack #131 October 6, 2026 19:37
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

Branch coverage

Name Stmts Miss Branch BrPart Cover
src/assistant/a2ui.py 269 22 80 14 89%
src/assistant/a2ui_skill.py 121 9 34 7 90%
src/assistant/acp/approvals.py 58 1 8 2 95%
src/assistant/acp/chats.py 251 22 56 12 89%
src/assistant/acp/listeners.py 28 1 10 1 95%
src/assistant/acp/serve.py 66 16 4 2 74%
src/assistant/acp/serve_ws.py 103 0 24 3 98%
src/assistant/agent.py 271 31 78 8 88%
src/assistant/attachments.py 57 2 20 0 97%
src/assistant/card_author.py 55 13 14 3 68%
src/assistant/card_drafts.py 157 21 60 16 83%
src/assistant/card_instances.py 201 22 76 17 84%
src/assistant/cards/__init__.py 295 23 134 19 90%
src/assistant/cards/layout.py 35 1 14 1 96%
src/assistant/channels/__init__.py 15 7 6 0 38%
src/assistant/channels/base.py 40 3 4 1 91%
src/assistant/channels/discord.py 136 73 44 1 42%
src/assistant/channels/formatting.py 121 2 32 3 97%
src/assistant/channels/router.py 544 15 186 14 96%
src/assistant/channels/slack.py 165 95 52 1 39%
src/assistant/channels/telegram.py 284 51 96 18 79%
src/assistant/cli.py 498 252 92 8 46%
src/assistant/codex_auth.py 241 67 54 5 71%
src/assistant/coding/bridge_client.py 44 7 4 1 83%
src/assistant/coding/bridge_server.py 115 30 22 4 74%
src/assistant/coding/diff.py 98 13 36 6 84%
src/assistant/coding/model_catalog.py 101 6 30 4 92%
src/assistant/coding/session.py 92 7 18 2 92%
src/assistant/config.py 203 22 58 7 89%
src/assistant/connections.py 264 18 78 14 91%
src/assistant/feedback.py 39 5 4 1 86%
src/assistant/filesearch.py 96 12 48 6 88%
src/assistant/folders.py 264 13 82 4 95%
src/assistant/gateway/app.py 442 175 120 17 57%
src/assistant/gateway/core.py 852 102 230 39 85%
src/assistant/gateway/openapi_schema.py 26 0 6 1 97%
src/assistant/gateway/profile_manager.py 408 43 118 23 87%
src/assistant/gateway/repair.py 66 3 26 1 96%
src/assistant/gateway/routes/card.py 122 14 28 6 87%
src/assistant/gateway/routes/card_instance.py 43 3 4 0 94%
src/assistant/gateway/routes/common.py 39 1 16 1 96%
src/assistant/gateway/routes/connection.py 167 2 42 2 98%
src/assistant/gateway/routes/file.py 194 4 72 6 96%
src/assistant/gateway/routes/folder.py 87 7 8 1 92%
src/assistant/gateway/routes/llm.py 245 17 54 6 92%
src/assistant/gateway/routes/permission.py 55 2 12 2 94%
src/assistant/gateway/routes/profile.py 73 4 8 0 95%
src/assistant/gateway/routes/secret.py 66 5 6 1 92%
src/assistant/gateway/routes/settings.py 190 18 26 8 88%
src/assistant/gateway/routes/skill.py 222 9 30 1 96%
src/assistant/gateway/routes/system.py 239 26 42 4 89%
src/assistant/gateway/routes/task.py 104 7 18 5 90%
src/assistant/gateway/stream_bridge.py 37 0 6 1 98%
src/assistant/gateway/tasks_service.py 407 50 130 17 86%
src/assistant/gateway/wire.py 19 3 2 0 86%
src/assistant/hitl/channel.py 21 2 4 2 84%
src/assistant/hitl/desktop.py 133 12 26 5 89%
src/assistant/hitl/gateway.py 22 4 2 1 79%
src/assistant/hitl/inquiry.py 168 6 36 5 95%
src/assistant/integrations/google_auth.py 136 67 24 0 49%
src/assistant/live_configs.py 116 9 40 13 86%
src/assistant/llm_configs.py 220 5 86 1 98%
src/assistant/memory.py 134 11 44 5 89%
src/assistant/middleware.py 81 2 12 2 96%
src/assistant/observability.py 69 5 10 0 94%
src/assistant/observers.py 97 0 24 1 99%
src/assistant/onboarding.py 64 2 26 0 98%
src/assistant/pairing.py 145 2 46 3 97%
src/assistant/peers.py 150 1 40 3 98%
src/assistant/permissions.py 300 21 106 8 93%
src/assistant/profiles.py 186 2 46 4 97%
src/assistant/provider_catalog.py 94 5 38 5 92%
src/assistant/resources.py 210 6 46 8 95%
src/assistant/scheduler_lock.py 33 0 4 1 97%
src/assistant/secrets.py 262 4 78 2 98%
src/assistant/self_tools.py 78 21 18 4 70%
src/assistant/settings.py 175 9 52 7 93%
src/assistant/skills.py 54 3 14 0 96%
src/assistant/skills_install.py 167 19 56 12 86%
src/assistant/state_store.py 163 12 50 6 92%
src/assistant/storage.py 36 4 0 0 89%
src/assistant/system_tools.py 152 45 50 13 66%
src/assistant/tasks/scheduling.py 99 6 30 4 92%
src/assistant/tasks/store.py 168 20 56 7 88%
src/assistant/tasks/summary.py 38 1 2 1 95%
src/assistant/tools/__init__.py 88 5 38 3 94%
src/assistant/tools/_mcp_compat.py 25 3 2 1 85%
src/assistant/tools/approval.py 12 6 4 0 38%
src/assistant/tools/ask.py 14 6 2 0 50%
src/assistant/tools/coding.py 30 7 2 1 75%
src/assistant/tools/docker_sandbox.py 68 20 10 1 68%
src/assistant/tools/files.py 70 18 24 6 74%
src/assistant/tools/finance.py 117 44 48 1 61%
src/assistant/tools/google.py 186 132 36 2 28%
src/assistant/tools/image_gen.py 92 38 28 2 55%
src/assistant/tools/mcp.py 195 14 42 9 89%
src/assistant/tools/weather.py 119 19 34 6 82%
src/assistant/tools/web_fetch.py 30 4 10 3 82%
src/assistant/usage.py 74 7 14 0 85%
src/assistant/voice.py 60 19 12 2 65%
src/assistant/voice_providers.py 72 26 4 0 63%
src/assistant/workspace.py 271 25 88 3 92%
TOTAL 15695 2076 4132 510 85%

44 files skipped due to complete coverage.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant