Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ src/
├── sidebar/ / settings/ / dialogs/ / ui/ / views/
└── UnifiedBar.tsx
src-tauri/src/lib.rs ← ALL Rust (PTY, project/task IO, settings, scripts, git, sandbox, proxy)
src-tauri/src/forge.rs ← GitHub/GitLab PR-MR integration via the gh / glab CLIs (detection, status, create)
src-tauri/src/forge.rs ← GitHub/GitLab/Azure DevOps PR-MR integration via the gh / glab / az CLIs (detection, status, create)
```

## Run / build
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,14 @@ no metered markup, no backend daemon. Here's what the window gives you on top:
(so a match ten pages back still comes up first), and **Compare**, every
path that differs between any ref and your working tree in one tree, with
mark-as-viewed and inline comments still live.
- **Pull requests.** Open a GitHub PR or GitLab MR from the task you built
it in, then watch it from the right panel: checks, review state, and
comments handed to the agent working in that worktree. Or start a task
FROM an issue, with the composed prompt dropped into the first-message box
for you to read before anything is sent. Self-hosted GitHub Enterprise and
GitLab work too, via `gh` / `glab`.
- **Pull requests.** Open a GitHub PR, GitLab MR, or Azure DevOps PR from
the task you built it in, then watch it from the right panel: checks,
review state, and comments handed to the agent working in that worktree.
Or start a task FROM an issue or Azure Boards work item, with the
composed prompt dropped into the first-message box for you to read
before anything is sent. Self-hosted GitHub Enterprise and GitLab work
too; Azure DevOps needs `az` with the `azure-devops` extension (cloud
only, not Server). All three ride their official CLI's login.
- **Agent races.** Fire one prompt at several agents at once, each in its own
fresh worktree, then compare their diffs N-up when they finish and adopt
the winner into your main checkout.
Expand Down
2 changes: 1 addition & 1 deletion docs/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Directories

Three directories, different owners:
- `~/Library/Application Support/termic/` — app-owned: `projects.json`, `tasks/`, `scratch/`, `settings.json`. With PROFILES (GH #280) those four are the ROOT profile's; every other profile keeps its own copy under `profiles/<slug>/`, and `profiles.json` (the registry) sits alongside them and is ABSENT until the first profile is created. `lib.rs#global_dir()` is the machine-wide root (tokens, docker, `servers/`, `backups/`, and the sandbox deny rule, which must cover every profile); `lib.rs#profile_dir(id)` is one profile's. See [profiles.md](profiles.md). Docker mode adds three more here: `docker/` (the editable Dockerfile + build metadata), `docker-agents/<agent>/` (one container config dir per agent, so a login survives `--rm`) and `docker-forge/{gh,glab}/` (the gh / glab login, SHARED by every agent and task, see [sandbox.md](sandbox.md)). Path via `dirs::data_local_dir().join("termic")` in `lib.rs#global_dir()` (renamed from `data_dir()` when profiles landed, so a caller that wants machine-wide state has to say so).
- `~/Library/Application Support/termic/` — app-owned: `projects.json`, `tasks/`, `scratch/`, `settings.json`. With PROFILES (GH #280) those four are the ROOT profile's; every other profile keeps its own copy under `profiles/<slug>/`, and `profiles.json` (the registry) sits alongside them and is ABSENT until the first profile is created. `lib.rs#global_dir()` is the machine-wide root (tokens, docker, `servers/`, `backups/`, and the sandbox deny rule, which must cover every profile); `lib.rs#profile_dir(id)` is one profile's. See [profiles.md](profiles.md). Docker mode adds three more here: `docker/` (the editable Dockerfile + build metadata), `docker-agents/<agent>/` (one container config dir per agent, so a login survives `--rm`) and `docker-forge/config/{gh,glab-cli}` + `docker-forge/azure/` (the gh / glab / az logins — the host layout mirrors each container path minus the leading dot, SHARED by every agent and task, see [sandbox.md](sandbox.md)). Path via `dirs::data_local_dir().join("termic")` in `lib.rs#global_dir()` (renamed from `data_dir()` when profiles landed, so a caller that wants machine-wide state has to say so).
- `$TMPDIR/termic-attachments/` — files handed to an agent as FILES rather than as text: `<task_id>/` for a staged drop, `clipboard/` for an image pasted into a terminal (`clipboard_image_save`, pruned after 7 days). Deliberately NOT under the app data dir, which the Seatbelt profile ends by denying outright (CLI token); `$TMPDIR` is on `builtin_runtime_paths` and is mounted read-only into every Docker container at the same absolute path. `lib.rs#attachments_dir()`.
- `~/Library/Application Support/com.simion.termic/` — tauri-plugin-window-state owned (window position/size). Path from `tauri.conf.json#identifier`.
- `~/.config/termic/themes/` — user-owned, hand-authored custom theme files ([docs/themes.md](themes.md)). `$XDG_CONFIG_HOME` respected; shared by release + dev builds (no `termic_dev` split). Path via `lib.rs#themes_dir_path()`.
Expand Down
2 changes: 1 addition & 1 deletion docs/e2e-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ until `make e2e` is green and this file reflects it.
| ✅ Clipboard image capture (ctrl+V) | `clipboard_image_capture` reads a real image off the macOS pasteboard (set by the spec, restored after), encodes it as PNG and returns a saved path; a text clipboard is refused so the caller can forward the keystroke | `agent.e2e.ts` |
| ✅ Image paste (Docker only) | `clipboard_image_save` persists pasted bytes and names the file for its REAL format (non-image bytes are refused, not written as a fake `.png`); the terminal's capture-phase listener leaves BOTH pastes alone in an ordinary task (native ⌘V still reaches the agent, which reads the Mac clipboard itself) and consumes only the image paste once the task is flipped to Docker | `agent.e2e.ts` |
| ✅ Dockerfile editor lifecycle | The Dockerfile section is collapsed by default and its CodeMirror instance exists only while open: expanding mounts it with the real content, collapsing destroys it, and a second expand brings it back (the init effect bails when a view already exists, so a destroy that did not clear the ref would leave an empty box) | `settings.e2e.ts` |
| ✅ Docker forge CLI login | The same preview proves the shared gh / glab config dir reaches the spawn argv: both container paths mounted, `GH_CONFIG_DIR`/`GLAB_CONFIG_DIR` set to match, host side under `docker-forge` (shared, not per-agent) and never the user's own `~/.config/gh` | `settings.e2e.ts` |
| ✅ Docker forge CLI login | The same preview proves the shared gh / glab / az config dirs reach the spawn argv: all three container paths mounted, `GH_CONFIG_DIR`/`GLAB_CONFIG_DIR`/`AZURE_CONFIG_DIR` set to match, host side under `docker-forge` (shared, not per-agent) and never the user's own `~/.config/gh` | `settings.e2e.ts` |
| ✅ Setup script | Configure + launch a Setup tab that spawns | `run.e2e.ts` |
| ✅ Sidebar layout | Sidebar width setter persists | `tabs-layout.e2e.ts` |
| ✅ Code editor | Open a .py file → CodeMirror renders with highlight tokens | `editor.e2e.ts` |
Expand Down
Loading
Loading