Skip to content
Draft
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
23 changes: 23 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ The above copyright notice and this permission notice shall be included in all c

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

## Ghostty / libghostty-vt

Aiden's in-app terminal uses a WebAssembly build of Ghostty's `libghostty-vt`
(`renderer/lib/ghostty-terminal/vendor/ghostty-vt.wasm`) plus a 112-byte PTY
callback trampoline. The browser host is adapted from T3 Code's MIT-licensed
`libghostty-vt` adapter.

Ghostty: Copyright (c) 2024-2026 Mitchell Hashimoto and Ghostty contributors
T3 Code adapter: Copyright (c) 2026 T3 Tools Inc.

MIT License. See `renderer/lib/ghostty-terminal/GHOSTTY-LICENSE` and
https://github.com/pingdotgg/t3code/blob/main/LICENSE

## Symbols Nerd Font Mono

Vendored as `renderer/lib/ghostty-terminal/fonts/SymbolsNerdFontMono-Regular.woff2`
for terminal prompt glyphs.

Copyright (c) 2014 Ryan L McIntyre

MIT License. See `renderer/lib/ghostty-terminal/fonts/LICENSE`


## Chart.js

Chart.js is vendored into `resources/generative-ui` for sandboxed Generative UI artifacts.
Expand Down
1 change: 1 addition & 0 deletions docs/plans/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This directory is the source of truth for Aiden's implementation plans. The engi
| [Dynamic Model Catalog](dynamic-model-catalog-plan.md) | Implemented | Validated pi.dev overlays, offline `0600` cache hydration, scoped setup refresh, four-hour launch refresh, force refresh, Pi metadata fallback, and Mac/iOS projection ship on pinned Pi 0.84.4. |
| [Generative UI Artifacts](generative-ui-artifacts-plan.md) | Active | Phases 0–6 shipped: chat-scoped `render_artifact`, strict sandboxed preview/export hosts, verified vendored Chart.js/Plotly/KaTeX, permission-aware `/visualize`, crash-recoverable authoritative storage/copies, descriptor-relative workspace reads, one-iframe handoff/expansion, visible failure states, and route-stable Responding/Visualizing activity. Three-agent PR review findings are remediated with focused regression coverage. |
| [Generation Progress Notes](generation-progress-notes-plan.md) | Planned | No implementation yet. |
| [Libghostty workspace terminal](libghostty-terminal-plan.md) | Implemented | The workspace drawer uses Ghostty's official `libghostty-vt` WASM (T3-style runtime, PTY trampoline, canvas surface); node-pty sessions are unchanged. Packaged Mac acceptance remains. |
| [Logging and Diagnostics Upgrade](logging-and-diagnostics-upgrade-plan.md) | Implemented | Phases 0–7 are implemented: bounded typed desktop journals, main-owned renderer evidence, local support export/delete, native categorical parity, and CI/release gates. Signed/notarized `v0.35.0` passed packaged diagnostics acceptance; physical-device termination receipts remain. |
| [Long-thread payload upgrades](long-thread-payload-upgrade-plan.md) | Partial | Investigation complete: T3’s O(N²) stdout store does not exist here. No-op `toolRunning` timeline republish is skipped; Remote gzip, stream-journal debounce, chat JSON/attachments, and transcript windowing remain planned. |
| [Model Insights](model-insights-plan.md) | Partial | A dedicated benchmark-only OpenRouter key, manual fetch, exact source-aware offline cache, metric-selectable collision-free capability suggestions, progressive canvas-first Pad UX, axis provenance, attribution, and direct-AA retirement ship; device-local pace signals remain. |
Expand Down
17 changes: 17 additions & 0 deletions docs/plans/libghostty-terminal-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Libghostty workspace terminal

Status: Implemented

Replace the workspace drawer's xterm.js emulator with Ghostty's official
`libghostty-vt` WebAssembly C ABI, following T3 Code's browser adapter:
runtime + write-pty trampoline, core snapshots, canvas renderer, and surface
input (IME, selection, scrollback, mouse reporting).

PTY spawn, `TERM=xterm-256color`, snapshot hydrate, and session limits stay in
`main/services/terminal.ts`.

## Remaining

- Packaged/physical drawer acceptance on a signed Mac build.
- Optional later native Metal embed if Ghostty publishes a stable headless
surface API.
4 changes: 2 additions & 2 deletions docs/plans/performance-stability-efficiency-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The first implementation milestone should therefore be **data safety and bounded
| P1 | Scheduled catch-up has per-task overlap protection but no global budget or battery/lock policy | `main/services/schedule-service-core.ts` | Multiple missed tasks can stampede after startup/resume |
| P2 | The closed model picker queries every provider and rebuilds/sorts catalog structures during parent renders | `renderer/components/model-picker.tsx`, `renderer/lib/queries.ts` | Stream-frame work scales with provider/model count |
| P2 | Startup waits for provider enumeration/auth state before the first React render | `renderer/main/index.tsx`, `main/services/provider-registry.ts` | A slow keychain/provider probe delays visible app chrome |
| P2 | Routes, settings, xterm, KaTeX, and full Highlight.js are in an eager startup graph | `renderer/main/router.tsx`, `renderer/main/settings-view.tsx`, `renderer/components/code-block.tsx` | Larger parse/compile/startup and update payload |
| P2 | Routes, settings, terminal, KaTeX, and full Highlight.js are in an eager startup graph | `renderer/main/router.tsx`, `renderer/main/settings-view.tsx`, `renderer/components/code-block.tsx` | Larger parse/compile/startup and update payload |
| P2 | Terminal output and LLM deltas cross IPC at source cadence; terminal buffers repeatedly copy large strings | `main/services/terminal.ts`, `main/services/llm-client.ts` | Excess wakeups, IPC allocations, and resize churn |
| P2 | Several realistic lists are unwindowed | files, review, chat/model palettes, transcript | Large workspaces and histories degrade nonlinearly |

Expand Down Expand Up @@ -239,7 +239,7 @@ Exit gate:
#### 4B. Render sooner and load optional code later

- Render the lightweight shell before provider enumeration. Show a truthful provider-hydration state and enable composer selection only after alias/identity migration is authoritative.
- Dynamically import Settings/Profile/Scheduled routes, individual heavy Settings sections, terminal/xterm on first open, and other secondary panels.
- Dynamically import Settings/Profile/Scheduled routes, individual heavy Settings sections, terminal/libghostty on first open, and other secondary panels.
- Keep ChatLayout, transcript shell, composer, selected-model trigger, and generation bridge in the initial graph. Optionally idle-preload the next likely surface after first input readiness.
- Use package-content allowlists. Bundle pure-JS main dependencies when safe; externalize/unpack only native/runtime-required modules.
- Disable packaged source maps or publish hidden maps outside the app artifact. Add a test that no `.map` is shipped.
Expand Down
2 changes: 1 addition & 1 deletion main-window.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; base-uri 'self'; object-src 'none'; frame-src 'self' aiden-genui:; script-src 'self' http://localhost:* http://127.0.0.1:*; style-src 'self' 'unsafe-inline' http://localhost:* http://127.0.0.1:*; img-src 'self' data: blob: file: https: http:; font-src 'self' data:; connect-src 'self' https: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*; media-src 'self' data: blob: file: https:; worker-src 'self' blob:"
content="default-src 'self'; base-uri 'self'; object-src 'none'; frame-src 'self' aiden-genui:; script-src 'self' 'wasm-unsafe-eval' http://localhost:* http://127.0.0.1:*; style-src 'self' 'unsafe-inline' http://localhost:* http://127.0.0.1:*; img-src 'self' data: blob: file: https: http:; font-src 'self' data:; connect-src 'self' https: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*; media-src 'self' data: blob: file: https:; worker-src 'self' blob:"
/>
<title>Aiden Agent</title>
</head>
Expand Down
2 changes: 1 addition & 1 deletion main/services/terminal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ test("persisted history seeds a reopened terminal buffer", async () => {

const session = await service.create("workspace-1", "/tmp", owner.owner);
// The restored history is available via snapshot, so the renderer can
// re-hydrate xterm with the prior session's output.
// re-hydrate the Ghostty surface with the prior session's output.
const snapshot = service.snapshot(session.id, owner.owner);
assert.equal(snapshot.buffer, "prior output\n");
await service.flushHistory();
Expand Down
2 changes: 1 addition & 1 deletion main/services/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class TerminalService {
throw new Error("The workspace changed before the terminal could start.");
}
// Restore the sanitized prior-session output so the terminal reopens with
// its history. The renderer writes this buffer to xterm on hydrate, so no
// its history. The renderer writes this buffer to the Ghostty surface on hydrate, so no
// renderer change is required for the seed.
const restoredHistory = await this.historyStore?.read(workspaceId);
if (ownerInvalidated()) {
Expand Down
17 changes: 0 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading