Commit Graph
184 Commits
Author SHA1 Message Date
David KayaandCopilot cb05148231 fix: require child_process in gitService
Use createRequire for node:child_process so Bun on macOS can load gitService without ESM export-shape issues.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
v0.0.1
2026-03-26 00:37:24 +01:00
David KayaandCopilot 66c129f8b9 fix: handle bun child_process interop
Resolve execFile from named or default child_process exports so macOS Bun can load gitService in tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:34:44 +01:00
David KayaandCopilot d9f3f5302a fix: resolve macos bun interop
Use Bun-safe Electron and child_process import patterns for macOS GitHub Actions tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:30:41 +01:00
David Kaya 40ef1c07b5 fix: failing macos test 2026-03-26 00:22:28 +01:00
David KayaandCopilot 88030eb48d refactor: finish Aryx rebrand sweep
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:17:14 +01:00
David KayaandCopilot 1edd3aed55 refactor: rename sidecar host to Aryx
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:14:12 +01:00
David KayaandCopilot 4e3c74497f feat: add macOS arm64 release build
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:06:07 +01:00
David KayaandCopilot 90cc32e737 fix: update macOS GitHub Actions runner
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:04:25 +01:00
David Kaya d02ccf22a2 feat: website changes 2026-03-26 00:01:32 +01:00
David KayaandCopilot d88d00df0d fix: make copilot CLI path resolution cross-platform
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 23:44:49 +01:00
David Kaya f94c3232b4 fix: screenshot 2026-03-25 23:36:50 +01:00
David KayaandCopilot 5ed2b8bcd4 feat: add product website for Cloudflare Pages
Single-page marketing site built with Astro 5 and Tailwind CSS v4.
Produces static HTML with zero client-side JS — ideal for Cloudflare
Pages deployment.

Sections: hero with screenshot placeholder, 6 feature cards,
5 orchestration patterns showcase, 4-step getting started guide,
tech banner, and footer.

Dark theme (zinc-950/indigo accents) matches the app aesthetic.
Responsive design with mobile navigation.

Build: cd website && bun install && bun run build
Output: website/dist/

To add a real screenshot, replace
website/public/images/screenshot-placeholder.svg with
website/public/images/screenshot.png and update the img src
in website/src/pages/index.astro.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:57:00 +01:00
David KayaandCopilot 968ae37279 feat: allow model selection in all single-agent sessions
Generalize the scratchpad-only model/reasoning-effort selector to work
in any session whose pattern has exactly one agent. This enables model
switching above the chat input for project 1-on-1 chats, not just
scratchpads.

- Rename ScratchpadSessionConfig -> SessionModelConfig across domain,
  contracts, IPC, preload, and renderer
- Replace isScratchpadProject guard with agents.length === 1 check in
  EryxAppService.updateSessionModelConfig and ChatPane pills gate
- Apply session model config in buildEffectivePattern whenever present,
  regardless of project type
- Seed sessionModelConfig on session creation for any single-agent
  pattern

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:41:46 +01:00
David Kaya 46b5de472e tests: some additional tests 2026-03-25 22:28:36 +01:00
David KayaandCopilot 628fdff29e fix: clear live agent status on cancel
Clear only active agent statuses when a session reaches idle, and keep the terminal cancelled/error run cleanup in place. Add regression coverage for idle cleanup after cancellation-like flows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:20:57 +01:00
David KayaandCopilot c9cc2fd8e7 fix: clear stale agent activity on cancel
Clear only still-active side-panel agent states when a run ends as cancelled or error, while preserving completed agent statuses. Add a renderer regression test for cancelled runs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:17:33 +01:00
David KayaandCopilot 82fdadb312 feat: add turn cancellation UI and main process wiring
Adds cancel-turn IPC channel, SidecarClient.cancelTurn(), TurnCancelledError,
EryxAppService.cancelSessionTurn(), finalizeCancelledTurn(), stop button in
ChatPane, and cancelled run status throughout the run timeline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:17:15 +01:00
David KayaandCopilot d84b3021f2 feat: add sidecar turn cancellation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:04:14 +01:00
David KayaandCopilot c8bb9d6f59 fix: align chat MCP tooling with session project
Resolve chat tooling from the selected session's project instead of the
separately tracked selectedProjectId so project-scoped discovered MCPs do
not appear for the wrong session. Also synchronize selectedProjectId when
a session is selected and add regression tests for both behaviors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:57:30 +01:00
David KayaandCopilot e5878ba9e8 feat: auto-discover MCP servers from project and user config files
Scan .vscode/mcp.json, .mcp.json, .copilot/mcp.json (project-level) and
~/.copilot/mcp.json (user-level) for MCP server definitions. Discovered
servers require explicit user acceptance before activation.

Backend:
- Add ConfigScannerRegistry with per-format scanners and  substitution
- Add discovered tooling domain model with fingerprint-based change detection
- Integrate scanning into workspace load, project add, and project selection
- Merge accepted discovered MCPs into effective runtime tooling
- Extend sidecar contracts with env/headers for real-world MCP configs
- Add IPC channels for accept/dismiss/rescan operations

Frontend:
- Add DiscoveredToolingModal for reviewing pending MCP servers
- Auto-show modal when pending discoveries exist on load or project switch
- Add amber badge on sidebar project headers for pending discoveries
- Add discovered MCP section in Settings panel with accept/dismiss/rescan
- Group InlinePills tool dropdown by Workspace MCP / User MCP / Project MCP
- Pass effective project tooling (including accepted discoveries) to ChatPane

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:54:06 +01:00
David KayaandCopilot 08a1132d86 refactor: inline tool auto-approval list into tool-call approval card
Move the Tool Auto-Approval Defaults section into the tool-call
ApprovalCheckpointRow card so the tool list appears directly under
the toggle instead of in a disconnected section below. Extend
ApprovalCheckpointRow with an optional children prop rendered
inside the card when the checkpoint is enabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:51:15 +01:00
David KayaandCopilot 2e3175934d feat: add troubleshooting settings with open app data and reset workspace
Add a Troubleshooting section under a Support nav group in Settings:

- Open App Data Folder: reveals the user-data directory in the OS file
  explorer via shell.openPath.
- Reset Local Workspace: destructive action that deletes workspace.json
  and scratchpad contents, clears the in-memory cache, and reseeds
  defaults. Auth secrets are preserved. Requires two-step confirmation.

New IPC channels, ElectronApi methods, and preload bridge added for
openAppDataFolder and resetLocalWorkspace. Existing electron mock in
tests updated to include shell.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:50:16 +01:00
David Kaya 5123f9163c docs: update agent guidelines 2026-03-25 21:41:04 +01:00
David Kaya 7957928fc7 fix: inline pills 2026-03-25 21:40:40 +01:00
David KayaandCopilot 29c054f47d fix: require tool approval by default
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:23:01 +01:00
David KayaandCopilot cc3c04b841 feat: enable scratchpad tooling frontend and instruction update
- Remove !isScratchpad gate on tooling/approval pills in ChatPane
- Update scratchpad agent guidance to permit tool/file usage
- Add EryxAppService scratchpad tooling integration tests
- Update ARCHITECTURE.md to reflect scratchpad tooling support

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:20:43 +01:00
David KayaandCopilot 4ecfa5bff6 feat: enable scratchpad tooling backend
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:14:19 +01:00
David KayaandCopilot ab4e217d74 refactor: rename app to aryx
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 21:11:36 +01:00
David Kaya cb7f216bc3 fix: styling 2026-03-25 20:43:04 +01:00
David KayaandCopilot 8d3c4f474e revert: replace plain CSS class with @theme text-pill token
Remove .pill-trigger CSS class and restore the idiomatic Tailwind v4
@theme approach: --text-pill in @theme generates the text-pill utility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:40:11 +01:00
David KayaandCopilot 4797c9b30c fix: use plain CSS class for pill font size instead of Tailwind token
The @theme --text-pill token and text-[8px] arbitrary value both
failed to apply at dev time due to @tailwindcss/vite not generating
the utility rule during HMR. Use a plain .pill-trigger CSS class
in styles.css instead, which is always available regardless of
Tailwind's JIT scanner behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:40:10 +01:00
David KayaandCopilot d6596efc11 fix: register pill font size as Tailwind v4 theme token
The arbitrary text-[8px] class was not being generated by the
Tailwind v4 Vite plugin at dev time. Register --text-pill in
@theme so text-pill becomes a first-class utility that is always
generated. Uses 0.5rem (8px) with line-height 1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:33:28 +01:00
David KayaandCopilot 0ed22adb03 style: add leading-none to pill text to ensure 8px font takes effect
Add explicit leading-none alongside text-[8px] so both font-size
and line-height shrink, making the size reduction visually apparent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:32:44 +01:00
David KayaandCopilot 689b853a8a style: set pill font to 8px and add breathing room around icons
Reduce font to text-[8px], restore icons to size-2.5 for legibility,
and bump padding to px-1.5 py-0.5 so icons aren't flush with the
pill border.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:28:43 +01:00
David KayaandCopilot 23c8a6bb9b style: further shrink inline pills to match surrounding text density
Reduce to text-[10px] (matching agent badges), px-1 py-px padding,
gap-0.5, size-2 icons, rounded (not rounded-md), and 100px model
name truncation. Pills now sit subtly alongside 13px chat text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:25:50 +01:00
David KayaandCopilot fa037859da style: reduce inline pill button size above chat composer
Shrink padding (px-2 py-1 → px-1.5 py-0.5), font (12px → 11px),
gap (1.5 → 1), icon size (3 → 2.5), and model name max-width
(140px → 120px) on all four pill trigger buttons. Dropdown popovers
remain unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:20:36 +01:00
David KayaandCopilot 1b1ebdb676 fix: move handleCreateScratchpad above early return to fix hooks order
The useCallback for handleCreateScratchpad was placed after the early
return for the loading state, causing React to see a different number
of hooks between the initial render (workspace undefined) and subsequent
renders. Move it before the guard and add a null check inside instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:16:44 +01:00
David KayaandCopilot 3218de3856 docs: strengthen backend agent guidelines
Clarify backend C# cleanliness, decomposition, contract safety, testing, and validation expectations for future agent changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:13:31 +01:00
David KayaandCopilot 0bc90be68e docs: add frontend conventions and validation checklist to agent guidelines
Add section 5 (Frontend conventions) covering:
- Feature-based component directory structure and placement rules
- Custom hooks location and patterns
- Lib utility boundary (pure logic vs React-aware hooks vs components)
- State/rendering guidance (useCallback, useMemo, lifting state)
- Accessibility requirements for modals, dropdowns, menus, toggles
- Import conventions and path alias usage

Add section 7 (Validation checklist) with the exact commands to run
before every commit: typecheck, test, build, and optionally sidecar:test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:12:51 +01:00
David KayaandCopilot fcfc5c9641 refactor: decompose large frontend components into focused modules
Split six monolithic component files into smaller, single-responsibility
modules organized by feature domain:

- ChatPane (1054→~250 lines): extract InlinePills, ApprovalBanner,
  ThinkingDots into chat/ directory
- SettingsPanel (1027→~280 lines): extract McpServerEditor,
  LspProfileEditor, ToolingEditorShell into settings/ directory;
  mutation helpers into lib/settingsHelpers.ts
- PatternEditor: use shared ToggleSwitch from ui/
- App.tsx: extract useTheme and useSidecarCapabilities into hooks/
- Sidebar: extracted accessibility improvements inline

New shared primitives:
- hooks/useClickOutside: replaces 5 duplicated click-outside listeners
- components/ui/: ToggleSwitch, PopoverToggleRow, FormField, TextInput,
  TextareaInput, SelectInput, InfoCallout

Accessibility improvements:
- NewSessionModal: role=dialog, aria-modal, Escape-to-close
- Pill dropdowns: aria-expanded, aria-haspopup, role=listbox/option
- Sidebar context menu: role=menu/menuitem, Escape-to-close
- SessionItem: Space key activation alongside Enter
- ToolbarButton: aria-pressed for toggle state
- ApprovalBanner: role=alert
- QueuedApprovalsList: aria-expanded on toggle
- ThinkingDots: aria-label

No behavioral changes. All 137 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:12:36 +01:00
David KayaandCopilot 1bd0fcba3e refactor: improve sidecar backend structure
Refactor sidecar command dispatch, approval handling, transcript projection, stream merging, and tooling helpers while preserving behavior and expanding backend regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:11:59 +01:00
David KayaandCopilot 4f202274db feat: replace PrismJS with highlight.js for code syntax highlighting
PrismJS's CJS global state is fundamentally incompatible with Vite's ESM
dev mode, causing missing language support (~40% of dropdown languages)
and fragile loading hacks (optimizeDeps, global assignment).

Replace the entire Prism integration with highlight.js/lib/common which
is ESM-native, has no global state, and covers all 22 dropdown languages
out of the box (~37 common languages included).

Implementation:
- Custom CodeHighlightPlugin using hljs.highlight() for tokenization
- HTML parser extracts flat tokens from hljs output (handles nested spans)
- Token type mapping from hljs scopes to Lexical codeHighlight theme keys
- Selection preservation via absolute character offset save/restore
- Re-entrancy guard prevents infinite transform loops
- Removed @lexical/code-prism import and Vite optimizeDeps workaround

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:08:14 +01:00
David KayaandCopilot 2338d7c44b fix: resolve Prism CJS loading crash in Vite dev mode
Remove the prismSetup module that imported prismjs directly — it
caused Vite to pre-bundle prismjs into a separate chunk from
@lexical/code-prism, breaking the CJS require chain.  Language
components tried to call Prism.languages.extend() before the base
grammars were available, crashing the app.

Instead, add optimizeDeps.include for prismjs and @lexical/code-prism
so Vite pre-bundles them together, preserving the correct CJS
evaluation order within a single chunk.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:03:57 +01:00
David KayaandCopilot 5dc86426b1 fix: move Prism global setup to entry-point module
The previous approach imported prismjs component files directly in
MarkdownComposer.tsx.  In Vite dev mode, each component is served
as a separate ESM module whose IIFE references a bare 'Prism' global
that doesn't exist yet, crashing the app.

Fix: create a dedicated prismSetup module that imports prismjs and
assigns globalThis.Prism, then import it from the renderer entry
point (main.tsx) before any component that loads @lexical/code-prism.
ESM evaluation order guarantees the global is set before the
tokenizer captures its reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 20:03:02 +01:00
David KayaandCopilot 860876172e feat: enable Prism syntax highlighting in code blocks
- Register CodeHighlightNode in the editor node set
- Add CodeHighlightPlugin that calls registerCodeHighlighting
- Map 20+ Prism token types to mc-tok-* CSS classes with dark theme colors
- Explicitly import prismjs + language components and set globalThis.Prism
  before @lexical/code-prism loads, fixing a Vite dev-mode race where
  the CJS shim could initialize the tokenizer before the global was set
- Added @types/prismjs for type checking

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:52:54 +01:00
David KayaandCopilot 8240468d1e feat: enable Prism-based syntax highlighting in code blocks
- Register CodeHighlightNode in the editor node set
- Add CodeHighlightPlugin that calls registerCodeHighlighting
- Map codeHighlight theme keys to mc-tok-* CSS classes
- Add dark-theme token colors for 20+ Prism token types

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:52:41 +01:00
David KayaandCopilot 38d7e339a2 fix: replace imperative DOM overlay with React-based positioning
The imperative approach inserted overlay elements directly into
Lexical-managed CodeNode DOM elements.  Lexical's MutationObserver
detected the foreign DOM nodes, reconciled them away, which triggered
update listeners that re-inserted them — causing an infinite loop
that froze the app.

The new approach renders overlay elements via React, positioned
absolutely in a pointer-events:none container that sits over the
content editable.  Overlay positions are computed from each code
element's bounding rect and updated via requestAnimationFrame on
editor updates and scroll events.  This avoids all Lexical DOM
mutation and eliminates the freeze.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:49:16 +01:00
David KayaandCopilot 9ef7150183 feat: move language selector onto code block, fix code block insertion
Language selector:
- Replaced toolbar dropdown with an imperative overlay rendered
  directly inside each code block's DOM element
- Overlay uses contentEditable='false' + position:absolute at the
  top-right of the code block, styled as a compact native select
- Plugin re-inserts overlays after each Lexical reconciliation to
  survive DOM diffing

Code block insertion:
- toggleCodeBlock now inserts a trailing paragraph after the code
  block when it would otherwise be the last element, so the user
  can always type regular text below a code block

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:42:58 +01:00
David KayaandCopilot 039b9037ee feat: add code block language selector to composer
When the cursor is inside a code block, the formatting toolbar shows
a language dropdown (22 languages). Selecting a language updates the
CodeNode, which the markdown serializer writes as the fenced code
block language tag (e.g. \\\	ypescript).

A CodeBlockLabelPlugin syncs a data-code-language attribute on each
code block element so CSS ::before shows the friendly language name
as a small label at the top of the block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:37:08 +01:00
David KayaandCopilot 1f9203e1da fix: send button clearance and code block display mode
- Increase editable min-height from 40px to 52px and padding from 8px
  to 10px so the send button (32px + 8px bottom offset) has 12px
  clearance from the toolbar border instead of 0px
- Add display: block to .mc-code-block — Lexical CodeNode renders as
  <code> which is inline by default, causing border/padding to split
  visually across lines instead of forming a proper block
- Revert empty code block to code.select() without synthetic TextNode

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 19:35:25 +01:00