Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1cb210a
Add workspace Artifacts plan
claude Oct 19, 2026
1517c82
Add workspace artifact store, tool and IPC (Artifacts phase 1)
claude Oct 19, 2026
c548128
Harden workspace artifact commands and approvals (phase 1 review)
claude Oct 19, 2026
3dae518
Add the Artifacts tab to the Tools panel (Artifacts phase 2)
claude Oct 19, 2026
efc4da8
Fix Artifacts tab review findings (phase 2 review)
claude Oct 19, 2026
f5cdf81
Run artifact sources and buttons in the workspace (Artifacts phase 3)
claude Oct 19, 2026
d783dae
Artifacts: page buttons, chat hand-off and the aiden-artifacts skill
claude Oct 19, 2026
93ad688
Artifacts: phase 4 review fixes
claude Oct 19, 2026
65caaaa
Artifacts: docs, onboarding tile and workspace cleanup
claude Oct 19, 2026
85e2b95
Artifacts: keep generation exit order and one workspace removal path
claude Oct 19, 2026
8b7d557
Artifacts: phase 5 review fixes
claude Oct 19, 2026
e23845f
Artifacts: run nothing once cancelled, load files before approval, re…
claude Oct 19, 2026
9420a40
Artifacts: bind button values read-only so the confirmed value is the…
claude Oct 19, 2026
da609fd
Artifacts: second review fixes
claude Oct 19, 2026
9b93b15
Artifacts: refuse text only where bash reads it as arithmetic
claude Oct 19, 2026
d6d8822
Artifacts: check the whole command clause, and expansions per quote
claude Oct 19, 2026
23ce9ba
Artifacts: judge placeholders by their command's real name
claude Oct 19, 2026
4fdf4e2
Artifacts: find a placeholder's command from top-level separators only
claude Oct 19, 2026
6084142
Artifacts: read placeholders' commands as real shell words, and refus…
claude Oct 19, 2026
78df865
Artifacts: < and > compare inside (( )) and [[ ]], and git -c counts …
claude Oct 19, 2026
73d2588
Artifacts: find git's subcommand past its valued global options
claude Oct 19, 2026
69920fd
Artifacts: treat git's unknown global options as taking a value
claude Oct 19, 2026
aa36499
Artifacts: count git --no-literal-pathspecs as a flag
claude Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .memory/workspace-artifacts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Workspace artifacts (2026-10-19)

Built in PR #554 on `claude/project-thread-7xf9t3`. The user guide is `docs/workspace-artifacts.md`, and the decisions are in `docs/plans/workspace-artifacts-plan.md` ("As built").

Owner decisions:
- The Artifacts tab shows only once the workspace has a page.
- The workspace owns its pages, and the person deletes them from the tab or by asking Aiden.
- Access follows chat behavior.
- Desktop only (macOS and Linux) for v1: no CLI, Bots, Telegram, phones or Remote protocol change.

Invariants to keep:
- Main runs only commands saved with the artifact. The renderer sends an id, an action name, values and the page digest; main refuses a digest that changed.
- Under Ask, shell commands run only when `approvedDigest === workspaceArtifactDigest(sources, actions)`. File sources run under Ask without approval. None runs nothing.
- The tool's approval card records the digest per stream, and the tool consumes it.
- Action placeholders are standalone unquoted arguments, never the command itself, after a runner (eval/sudo/env/xargs, `RUNS_ARGUMENT`) or in an interpreter's code position (`CODE_ARGUMENTS`: `sh -c`, `python -c`, awk/sed program); text params never where bash reads names or arithmetic (`[[ ]]`, `(( ))`, let/read/declare/printf -v). The scan builds real shell words per top-level command (drops redirections, skips assignments and keywords), so the command name can't hide. A real-shell oracle test runs every accepted candidate with code-running values; extend it with each new bypass. The parser skips comments, tracks `$'…'`, refuses unbalanced quotes and any placeholder it didn't check. Values are bound to read-only `AIDEN_ARG_N` variables (not `set --`, which a template could reset), so the confirmed value is the one that runs. No leading `-`, no negative numbers, and no control or invisible characters.
- A shared refresh is keyed by digest, approval, permission and the resolved folder. A caller cancelling leaves the run going; the run aborts when the last caller leaves. Only the newest live run for a page saves, and results are never saved when the digest changed mid-run.
- The folder is re-verified with realpath before anything runs.
- The `aiden-artifacts` skill is a builtin in `main/services/workspace-artifacts/skill.ts`, not in `resources/aiden-help`, because the CLI copies that folder.
- Removing a workspace, including through the worktree path, removes its artifact files.

Tests: `npm run test:workspace-artifacts`. Each of the five build phases had an Opus medium review, and the blocking findings were fixed with behavioral tests.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ I don't come from a coding background. I'd been bouncing between the coding agen
- **Workspaces and managed worktrees** - use folders, scratch workspaces, or isolated managed worktrees with three access levels, workspace-scoped tools, Ask-mode approvals, guarded creation/deletion, and crash-aware cleanup.
- **Models and the Model Pad** - choose from Pi's native hosted-provider catalog, local Ollama or LM Studio models, and declarative compatible endpoints. Arrange a personal capability-and-pace map, optionally enrich hosted models with explicitly fetched Artificial Analysis scores through a benchmark-only OpenRouter key, and keep benchmark evidence visibly separate from runtime limits and availability.
- **Terminal, Git, and review** - keep a terminal drawer beside the conversation, inspect files and diffs in Environment, edit with dirty-file protection, compare branches, commit or push checked snapshots, and open the workspace in a discovered external editor.
- **Workspace artifacts** - ask Aiden for a page such as the open PRs or a release checklist and it keeps it in an **Artifacts** tab beside the chat, re-reading its data from commands or workspace files under the workspace's access setting, with buttons that ask Aiden, fill the composer, or run approved commands. Desktop only; see [workspace artifacts](docs/workspace-artifacts.md).
- **Rich responses and local diagnostics** - render sandboxed HTML, chart, math, and raster artifacts with recovery/export controls, and inspect or export bounded local diagnostics without an automatic upload path.
- **Desktop integration and appearance** - native menus, encrypted system credential storage, **Parakeet**, the dictation pill, semantic themes, high contrast, reduced motion, and consistent light/dark rendering. Apple **Foundation Models**, Accessibility auto-paste, and the signed **Rust** Computer Use broker remain macOS-only.
- **Shared browser and annotations** - browse beside the chat in Environment, preview workspace HTML/PDF files, use isolated profiles and responsive viewports, and share selected text, elements, drawings, and image crops with Aiden. Aiden's browser tools operate on those same tabs. See [browser behavior and controls](docs/environment-browser.md).
Expand Down
2 changes: 1 addition & 1 deletion docs/aiden-remote-api-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ Selection nonces are a separate type. Workspace creation atomically revalidates
- `GET /chats/{chatId}/tasks`: authoritative `ChatTaskProgress` snapshot for one chat. Requires `chat:read` and the negotiated `tasks:read` grant; a device without the grant fails closed with `capability_denied`. Available only when `/server.features` advertises `chat-tasks-v1`.
- `GET /chats/{chatId}/agents?turnId=...`: authoritative `ChatAgentRoster` snapshot for the chat's active or most recent public turn when `turnId` is omitted, or for the requested opaque public turn identity when supplied. The response's optional `previousTurns` list lets a reopened client discover bounded historical selectors and request each prior roster with the same query. Requires `chat:read` and the negotiated `agents:read` grant. Available only when `/server.features` advertises `chat-agents-v1`.
- `POST /chats/{chatId}/agents/{agentId}/interrupt`: stops one delegated agent in the chat's current public turn through the same Mac stop path as the desktop agent panel, then returns the refreshed current-turn `ChatAgentRoster`. `agentId` is the opaque public ID from that roster; the Mac resolves the private run internally and never echoes it. Requires `chat:write` plus the negotiated `agents:read` grant (and `bot:write` for a retained Bot chat), no request body, and no `Idempotency-Key`: stopping an agent that is already terminal is a `200` no-op that returns the current roster. An agent ID that is not in the current turn fails with `404 not_found`; an agent that belongs to a legacy or unbound run the Mac can no longer address fails with `409 operation_stale`. Archived chats reject it as `mutation_blocked`. Only the addressed child stops—the parent run and other agents continue. Available only when `/server.features` advertises both `chat-agents-v1` and `chat-agent-interrupt-v1`.
- `GET /chats/{chatId}/skills`: bounded invocable-skill catalog for one chat. Requires `chat:read` and the negotiated `skills:invoke` grant; a device without the grant fails closed with `capability_denied`. Available only when `/server.features` advertises `chat-skills-v1`. The response is `{ "skills": [...] }` with at most 500 entries of exact keys `invocationId`, `name` (≤80), `description` (≤240, may be empty), `source: configured|workspace|global`, `available`, and `unavailableReason` (≤160, present exactly when `available` is false). `invocationId` is an opaque short-lived lease in the `sk1_` format, bound to the workspace and skill-registry revision; Bot chats are narrowed to the Bot's currently admitted skill policy. Entries carry display metadata only—never skill paths, instructions, fingerprints, or registry internals.
- `GET /chats/{chatId}/skills`: bounded invocable-skill catalog for one chat. Requires `chat:read` and the negotiated `skills:invoke` grant; a device without the grant fails closed with `capability_denied`. Available only when `/server.features` advertises `chat-skills-v1`. The response is `{ "skills": [...] }` with at most 500 entries of exact keys `invocationId`, `name` (≤80), `description` (≤240, may be empty), `source: configured|workspace|global`, `available`, and `unavailableReason` (≤160, present exactly when `available` is false). `invocationId` is an opaque short-lived lease in the `sk1_` format, bound to the workspace and skill-registry revision; Bot chats are narrowed to the Bot's currently admitted skill policy, and desktop-only built-in skills (such as `aiden-artifacts`, whose tool phones never get) are left out. Entries carry display metadata only—never skill paths, instructions, fingerprints, or registry internals.
- `GET /chats/{chatId}/progress/events`: dedicated chat-scoped live snapshot channel for observing work started by any paired device or by desktop. The `streamId` is the chat ID. A subscription emits complete nonterminal `task_update`/`agents_update` projections filtered to the matching grants (`tasks:read` or `agents:read`); transport heartbeats are SSE comment frames and are not protocol events. `Last-Event-ID` and `after` remain accepted for client compatibility, but this channel has no durable replay journal: every connection hydrates current snapshots, and a reconnect/full snapshot resync supersedes any requested offset. A device needs `chat:read` plus at least one progress grant to open the channel.
- `GET /models`: configured provider/model projection without credentials.
- `GET /usage?range=7d|30d|90d|1y|all`: aggregate request, token, activity, and estimated-cost totals from the Mac's device-local usage store. Requires `server:read`; never returns content, chat/workspace identifiers, paths, raw usage records, or credentials.
Expand Down
3 changes: 2 additions & 1 deletion docs/linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ uncertain connection.
## Platform behavior

The workspace agent, providers, local models, MCP, skills, Web Search,
schedules, terminal, Git, file editor, generative UI artifacts, diagnostics,
schedules, terminal, Git, file editor, generative UI artifacts, workspace
artifacts, diagnostics,
Gemini voice transcription, remote access, notifications, profile, themes, and
native subagents use the same contracts as macOS. Linux-specific integrations include:

Expand Down
1 change: 1 addition & 0 deletions docs/plans/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Research addition 2026-10-03 against `main` at `3f86d41af` (0.52.0): [all-PR inv

| Plan | Status | Current state |
| -------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Workspace Artifacts](workspace-artifacts-plan.md) | In review | Plan written and built 2026-10-19 in PR #554 (all five phases, each reviewed); user guide in [docs/workspace-artifacts.md](../workspace-artifacts.md). Persistent, interactive Aiden UI pages owned by a workspace, shown in an **Artifacts** tab of the Environment panel (offered in the tools launcher) that appears only once an artifact exists. Built on the `render_ui` catalog, with host-run data sources (shell commands and workspace files) under the chat's own workspace permission, a `workspace_artifact` agent tool, and a built-in skill. Desktop (macOS and Linux) only for v1; no CLI, phone or Remote protocol change. |
| [Cache-first loading states](cache-first-loading-states-plan.md) | Active | Plan approved (2026-10-17) with desktop read snapshots, recent-chat prefetch and queued sends. iOS Home (I1) and cache-first chat open (part of I2) shipped in PR #516 (merged 2026-10-17). Audits every blank or text-only loading state on iOS, Android and the desktop renderer, and proposes one rule: saved data first, shaped skeletons only for a true first read, empty only when confirmed, quiet connection status. Starts with the iOS home screen, which hides cached Recents behind "Connecting to Aiden Agent…". No Remote protocol change. |
| [Aiden CLI](aiden-cli-plan.md) | Active | Merged to main in PR #121 (2026-09-26) and shipped in 0.50.0 on pinned Pi 0.87.1; now pinned to Pi 1.3.0 (PR #505, 0.58.0). Phases 0–6 implementation complete; macOS/Linux CLI (57 tests each), Linux native helpers, complete shared subagent suites, root TypeScript/lint, and Android client checks pass. Physical iPhone acceptance is pending an unlocked device. Phase 6 delivered QR remote pairing, scheduled-run notifications (mobile push + desktop), shared desktop memory, daemon autostart, and prebuilt binaries; see the [checklist](aiden-cli-parity-checklist.md). |
| [Simulator Devices](simulator-devices-plan.md) | Partial | Phases 0–7 merged in PR #252 (2026-09-26) and shipped in 0.50.0 behind `AIDEN_EXPERIMENTAL_DEVICES`; on by default on macOS from 0.55.0 (2026-10-07), with `AIDEN_EXPERIMENTAL_DEVICES=0` as the kill switch. Environment **Simulator** tab plus `device_*` agent tools, ported from T3 Code (MIT, `1c127066`). Consent-gated pinned `expo-device-hub@0.12.0` + `agent-device@0.21.12`; token-authenticated loopback proxy. Phases 0–3 done (spike, flagged tab shell, main-process toolchain/host/proxy/service/IPC, live stream viewer with controls and screenshot-to-chat; `test:devices` 96 pass; fake-hub Electron E2E; real-Mac acceptance passed). Phase 4 (agent `device_*` tools), Phase 5 (simulators on paired Macs over Aiden Remote; [plan](simulator-devices-phase-5-peers.md)) and Phase 6 (procedural 3D device frames; [plan](simulator-devices-phase-6-3d.md)) done. Phase 7 done: Settings → **Simulator** (consent switches, pinned/installed helper versions, prune, remove installed tools) and [`docs/devices.md`](../devices.md); onboarding coverage is a follow-up now that the flag defaults on. Agent guidance prefers `device_*`/`agent-device` for the watched device but allows shell `xcrun simctl`/`xcodebuild`/`adb` for builds, installs, logs, port forwarding, and diagnostics (T3 #13908; PR #263, 0.51.0). Remaining: real-Mac acceptance for Phases 4–6 (the flag was defaulted on before it). Android emulators and SSH hosts shipped with the [T3 parity upgrade](simulator-devices-t3-parity-plan.md) (PR #391, 0.55.0). |
Expand Down
Loading
Loading