refactor: rename Kopaya to Eryx

Rename the product, runtime surfaces, sidecar projects, docs, tests, and packaging outputs from Kopaya to Eryx across the repository.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-23 22:01:23 +01:00
co-authored by Copilot
parent fd120b6f60
commit 50a8e5dfbe
50 changed files with 157 additions and 157 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ interface ProjectGitContext {
Files:
- `src/main/git/gitService.ts`
- `src/main/KopayaAppService.ts`
- `src/main/EryxAppService.ts`
Behavior:
+14 -14
View File
@@ -1,21 +1,21 @@
<p align="center">
<img src="assets/icons/icon.png" alt="Kopaya logo" width="180" />
<img src="assets/icons/icon.png" alt="Eryx logo" width="180" />
</p>
<h1 align="center">Kopaya</h1>
<h1 align="center">Eryx</h1>
<p align="center">
A desktop workspace for Copilot-powered work across real projects.
</p>
Kopaya is built for people who want more than a generic AI chat window. It gives you a place to ask quick questions, connect real projects, run reusable agent patterns, and keep ongoing work organized in one app.
Eryx is built for people who want more than a generic AI chat window. It gives you a place to ask quick questions, connect real projects, run reusable agent patterns, and keep ongoing work organized in one app.
It works especially well when you want AI help that stays grounded in an actual codebase: your folders, your repository state, your current branch, and your active work.
## Why use Kopaya?
## Why use Eryx?
- **Start fast** with a scratchpad conversation for quick questions and ad-hoc work.
- **Work against real projects** by attaching local folders and letting Kopaya stay aware of repository context.
- **Work against real projects** by attaching local folders and letting Eryx stay aware of repository context.
- **Go beyond one assistant** with orchestration patterns such as single-agent, sequential, concurrent, handoff, and group-chat flows.
- **See what is happening** with live activity for each agent while a run is in progress.
- **Stay organized** with persistent sessions you can rename, pin, archive, and return to later.
@@ -29,11 +29,11 @@ If you just want to think through an idea, draft something, or ask for help with
### Connect a real project
Add a local folder when you want help that is grounded in your work. Kopaya is designed to feel strongest when it is attached to a real project instead of acting like a general-purpose chatbot.
Add a local folder when you want help that is grounded in your work. Eryx is designed to feel strongest when it is attached to a real project instead of acting like a general-purpose chatbot.
### Choose how agents collaborate
Kopaya supports several ways of working:
Eryx supports several ways of working:
- **Single** for direct one-agent help
- **Sequential** for step-by-step specialist workflows
@@ -51,18 +51,18 @@ Sessions are persistent, so you can return to ongoing work instead of starting f
## Before you start
To use Kopaya comfortably, make sure you have:
To use Eryx comfortably, make sure you have:
- a **Windows machine**
- **GitHub Copilot CLI** installed and available as `copilot`
- an active **GitHub Copilot sign-in**
- a local folder or git repository ready to connect if you want project-aware help
Kopaya includes connection status in the app so you can quickly tell whether Copilot is ready before you start a session.
Eryx includes connection status in the app so you can quickly tell whether Copilot is ready before you start a session.
## Getting started
1. **Open Kopaya**
1. **Open Eryx**
Launch the app and head to settings if you want to confirm your Copilot connection first.
2. **Check that Copilot is ready**
@@ -77,9 +77,9 @@ Kopaya includes connection status in the app so you can quickly tell whether Cop
5. **Start working**
Ask a question, describe a task, or explore a project. As the run progresses, you can watch the participating agents and keep the session for later.
## When Kopaya feels most useful
## When Eryx feels most useful
Kopaya shines when you want to:
Eryx shines when you want to:
- move from quick chat to deeper multi-step work without leaving the app
- keep AI conversations tied to actual projects instead of isolated prompts
@@ -89,6 +89,6 @@ Kopaya shines when you want to:
## Current focus
Kopaya is focused on local, project-based work with your GitHub Copilot account. It already covers the essentials for working with projects, sessions, and reusable orchestration patterns, and it is growing toward a fuller AI workstation experience over time.
Eryx is focused on local, project-based work with your GitHub Copilot account. It already covers the essentials for working with projects, sessions, and reusable orchestration patterns, and it is growing toward a fuller AI workstation experience over time.
If you want an AI app that feels closer to a control room for real work than a blank chat box, Kopaya is built for that.
If you want an AI app that feels closer to a control room for real work than a blank chat box, Eryx is built for that.
+26 -26
View File
@@ -1,33 +1,33 @@
# Kopaya Roadmap
# Eryx Roadmap
Last updated: 2026-03-23
## Product direction
Kopaya already has the foundation of a serious AI workstation: local projects, persistent sessions, reusable orchestration patterns, live streaming, per-agent activity, and a sidecar runtime that can evolve independently of the desktop app.
Eryx already has the foundation of a serious AI workstation: local projects, persistent sessions, reusable orchestration patterns, live streaming, per-agent activity, and a sidecar runtime that can evolve independently of the desktop app.
The next step should not be "add random AI features." It should be to turn Kopaya into the best control room for AI work on real projects:
The next step should not be "add random AI features." It should be to turn Eryx into the best control room for AI work on real projects:
- chat when the user wants speed
- orchestrate when the user wants depth or quality
- inspect when the user needs trust
- automate when the user wants leverage
Modern AI chat apps set a clear baseline for user expectations: projects, memory, attachments, branching, search, export, collaboration, and task automation. Kopaya should meet that baseline, then go further on orchestration, observability, and reproducibility.
Modern AI chat apps set a clear baseline for user expectations: projects, memory, attachments, branching, search, export, collaboration, and task automation. Eryx should meet that baseline, then go further on orchestration, observability, and reproducibility.
## Current baseline
Based on the current codebase, Kopaya already has:
Based on the current codebase, Eryx already has:
- [x] persistent local workspace state for projects, patterns, and sessions in `src/main/persistence/workspaceRepository.ts`
- [x] built-in orchestration modes in `src/shared/domain/pattern.ts`: `single`, `sequential`, `concurrent`, `handoff`, `group-chat`, with `magentic` reserved for future support
- [x] a dynamic model catalog with provider metadata and reasoning-effort support in `src/shared/domain/models.ts`
- [x] scratchpad-specific in-chat model overrides in `src/main/KopayaAppService.ts`
- [x] real-time turn streaming and agent activity events in `src/shared/contracts/sidecar.ts`, `src/shared/domain/event.ts`, and `sidecar/src/Kopaya.AgentHost/Services/CopilotWorkflowRunner.cs`
- [x] scratchpad-specific in-chat model overrides in `src/main/EryxAppService.ts`
- [x] real-time turn streaming and agent activity events in `src/shared/contracts/sidecar.ts`, `src/shared/domain/event.ts`, and `sidecar/src/Eryx.AgentHost/Services/CopilotWorkflowRunner.cs`
- [x] a right-side activity panel that already surfaces per-agent state, model, and effort in `src/renderer/components/ActivityPanel.tsx`
- [x] a pattern editor and settings flow in `src/renderer/components/SettingsPanel.tsx`
- [x] Copilot CLI-backed runtime access via the system-installed `copilot` command, with Kopaya sanitizing inherited runtime env vars before spawning the sidecar
- [x] refreshable Copilot connection diagnostics and settings UI for `ready`, `copilot-cli-missing`, `copilot-auth-required`, and `copilot-error` states in `src/renderer/components/CopilotStatusCard.tsx`, `src/renderer/components/SettingsPanel.tsx`, `src/main/KopayaAppService.ts`, and `sidecar/src/Kopaya.AgentHost/Services/SidecarProtocolHost.cs`
- [x] Copilot CLI-backed runtime access via the system-installed `copilot` command, with Eryx sanitizing inherited runtime env vars before spawning the sidecar
- [x] refreshable Copilot connection diagnostics and settings UI for `ready`, `copilot-cli-missing`, `copilot-auth-required`, and `copilot-error` states in `src/renderer/components/CopilotStatusCard.tsx`, `src/renderer/components/SettingsPanel.tsx`, `src/main/EryxAppService.ts`, and `sidecar/src/Eryx.AgentHost/Services/SidecarProtocolHost.cs`
- [x] an OS secret store wrapper in `src/main/secrets/secretStore.ts` that can support future non-Copilot secrets and integrations
That is a strong base. The biggest gaps are not around "can it run agents?" but around:
@@ -41,7 +41,7 @@ That is a strong base. The biggest gaps are not around "can it run agents?" but
## Guiding principles
1. Match core AI chat expectations first.
If Kopaya is missing search, attachments, export, branching, or memory controls, users will feel friction before they ever appreciate orchestration.
If Eryx is missing search, attachments, export, branching, or memory controls, users will feel friction before they ever appreciate orchestration.
2. Make orchestration legible.
Multi-agent systems are only valuable if users can see what happened, why it happened, and what each agent contributed.
@@ -53,7 +53,7 @@ That is a strong base. The biggest gaps are not around "can it run agents?" but
A useful orchestration product should let users compare runs, pin configurations, inspect versions, and understand why outcomes changed.
5. Build around real project work.
Kopaya should feel strongest when attached to a codebase or working directory, not just as a generic chatbot.
Eryx should feel strongest when attached to a codebase or working directory, not just as a generic chatbot.
## Roadmap themes
@@ -87,11 +87,11 @@ Still worth adding:
- [x] active GitHub account or organization context when available
- [ ] clear model availability explanation when a model is unavailable
- [ ] reconnect and troubleshooting actions beyond refresh
- [ ] optional per-project or per-pattern account selection later if Kopaya supports multiple Copilot identities
- [ ] optional per-project or per-pattern account selection later if Eryx supports multiple Copilot identities
Because Kopaya currently appears to authenticate through the system-installed Copilot CLI rather than owning provider secrets directly, this should be treated as a connection/account-state UX problem first, not a raw credential-storage problem.
Because Eryx currently appears to authenticate through the system-installed Copilot CLI rather than owning provider secrets directly, this should be treated as a connection/account-state UX problem first, not a raw credential-storage problem.
If Kopaya later adds direct OpenAI, Anthropic, Google, MCP, or team-managed secrets, broader credential management becomes a separate roadmap item. The existing `src/main/secrets/secretStore.ts` gives the product a natural place to grow when that happens.
If Eryx later adds direct OpenAI, Anthropic, Google, MCP, or team-managed secrets, broader credential management becomes a separate roadmap item. The existing `src/main/secrets/secretStore.ts` gives the product a natural place to grow when that happens.
#### Conversation organization and search
@@ -135,7 +135,7 @@ The shared/backend query layer supports these filters, but the dedicated filter
## 2. Project-aware coding improvements
Kopaya should feel much smarter about the project it is attached to.
Eryx should feel much smarter about the project it is attached to.
| Priority | Initiative | Why it matters | Likely layers |
| -------- | -------------------------------- | --------------------------------------------------------------------------------- | ------------------------------ |
@@ -154,11 +154,11 @@ Kopaya should feel much smarter about the project it is attached to.
- [ ] project summary card: architecture snapshot, detected stack, test commands, important entry points
- [ ] saved session context packs, such as "frontend only", "API layer", or "build pipeline"
This is where Kopaya can beat generic chat apps: not just talking about a project, but acting like a focused control surface for that project.
This is where Eryx can beat generic chat apps: not just talking about a project, but acting like a focused control surface for that project.
## 3. Orchestration control plane
This is the highest-leverage product area. If done well, it becomes Kopaya's signature advantage.
This is the highest-leverage product area. If done well, it becomes Eryx's signature advantage.
| Priority | Initiative | Why users need it | Likely layers |
| -------- | ------------------------------ | ---------------------------------------------------------------------------------------- | ------------------------------ |
@@ -224,7 +224,7 @@ This would be a major differentiator. Most chat apps show outputs; very few make
## 4. Advanced orchestration capabilities
Once the control plane is solid, Kopaya should move from multi-agent chat to true workflow orchestration.
Once the control plane is solid, Eryx should move from multi-agent chat to true workflow orchestration.
| Priority | Initiative | Why it matters | Likely layers |
| -------- | --------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------- |
@@ -277,7 +277,7 @@ Examples:
### Memory layers
Kopaya should eventually distinguish between:
Eryx should eventually distinguish between:
- [ ] session memory: just this thread
- [ ] project memory: facts about a specific repository
@@ -321,7 +321,7 @@ Single-user desktop value is important, but long-term adoption will benefit from
## 6. Evaluation and continuous improvement
If Kopaya is going to orchestrate important work, it needs a way to measure quality.
If Eryx is going to orchestrate important work, it needs a way to measure quality.
| Priority | Initiative | Why it matters | Likely layers |
| -------- | -------------------------------- | -------------------------------------------------------------------- | ------------------------------ |
@@ -338,11 +338,11 @@ If Kopaya is going to orchestrate important work, it needs a way to measure qual
- "Which prompts or projects frequently fail and why?"
- "Should this workflow stay sequential or become concurrent?"
This is where Kopaya can become an engineering tool, not just a conversation shell.
This is where Eryx can become an engineering tool, not just a conversation shell.
## 7. Signature bets that could make Kopaya stand out
## 7. Signature bets that could make Eryx stand out
These are the ideas with the best chance of making Kopaya feel distinct rather than merely competitive.
These are the ideas with the best chance of making Eryx feel distinct rather than merely competitive.
### 1. Orchestration debugger
@@ -378,11 +378,11 @@ Instead of just comparing model outputs, compare:
- [ ] high-effort vs medium-effort
- [ ] guarded vs unguarded runs
Kopaya should become the easiest place to answer, "which setup is actually better for this task?"
Eryx should become the easiest place to answer, "which setup is actually better for this task?"
### 4. Human checkpoints as a first-class orchestration feature
Most agent tools either automate too much or stop at chat. Kopaya can own the middle ground:
Most agent tools either automate too much or stop at chat. Eryx can own the middle ground:
- [ ] route to human review at key points
- [ ] require approval before tool execution or publishing
@@ -473,7 +473,7 @@ These may still be valuable, but they are less urgent than the items above:
## Final takeaway
Kopaya does not need to become "another AI chat app."
Eryx does not need to become "another AI chat app."
It should become:
+8 -8
View File
@@ -1,5 +1,5 @@
{
"name": "kopaya",
"name": "eryx",
"version": "1.0.0",
"description": "Electron orchestrator for Copilot-powered agent workflows across multiple projects.",
"private": true,
@@ -13,22 +13,22 @@
"lsp:typescript": "typescript-language-server --stdio",
"typecheck": "tsc --noEmit -p tsconfig.json",
"test": "bun run typecheck && bun test",
"sidecar:restore": "powershell -NoProfile -Command \"dotnet restore 'sidecar\\\\Kopaya.AgentHost.slnx'\"",
"sidecar:build": "powershell -NoProfile -Command \"dotnet build 'sidecar\\\\Kopaya.AgentHost.slnx'\"",
"sidecar:publish": "powershell -NoProfile -Command \"if (Test-Path 'dist-sidecar\\\\win-x64') { Remove-Item 'dist-sidecar\\\\win-x64' -Recurse -Force }; dotnet publish 'sidecar\\\\src\\\\Kopaya.AgentHost\\\\Kopaya.AgentHost.csproj' -c Release -r win-x64 --self-contained true -p:DebugType=None -p:DebugSymbols=false -o 'dist-sidecar\\\\win-x64'\"",
"sidecar:test": "powershell -NoProfile -Command \"dotnet test 'sidecar\\\\Kopaya.AgentHost.slnx'\""
"sidecar:restore": "powershell -NoProfile -Command \"dotnet restore 'sidecar\\\\Eryx.AgentHost.slnx'\"",
"sidecar:build": "powershell -NoProfile -Command \"dotnet build 'sidecar\\\\Eryx.AgentHost.slnx'\"",
"sidecar:publish": "powershell -NoProfile -Command \"if (Test-Path 'dist-sidecar\\\\win-x64') { Remove-Item 'dist-sidecar\\\\win-x64' -Recurse -Force }; dotnet publish 'sidecar\\\\src\\\\Eryx.AgentHost\\\\Eryx.AgentHost.csproj' -c Release -r win-x64 --self-contained true -p:DebugType=None -p:DebugSymbols=false -o 'dist-sidecar\\\\win-x64'\"",
"sidecar:test": "powershell -NoProfile -Command \"dotnet test 'sidecar\\\\Eryx.AgentHost.slnx'\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/davidkaya/kopaya.git"
"url": "git+https://github.com/davidkaya/eryx.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/davidkaya/kopaya/issues"
"url": "https://github.com/davidkaya/eryx/issues"
},
"homepage": "https://github.com/davidkaya/kopaya#readme",
"homepage": "https://github.com/davidkaya/eryx#readme",
"packageManager": "bun@1.3.6",
"devDependencies": {
"@tailwindcss/vite": "^4.2.2",
+1 -1
View File
@@ -4,7 +4,7 @@ import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { rcedit } from 'rcedit';
const productName = 'Kopaya';
const productName = 'Eryx';
const sidecarRuntime = 'win-x64';
const outputDirectoryName = 'win-unpacked';
+8
View File
@@ -0,0 +1,8 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/Eryx.AgentHost/Eryx.AgentHost.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Eryx.AgentHost.Tests/Eryx.AgentHost.Tests.csproj" />
</Folder>
</Solution>
-8
View File
@@ -1,8 +0,0 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/Kopaya.AgentHost/Kopaya.AgentHost.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/Kopaya.AgentHost.Tests/Kopaya.AgentHost.Tests.csproj" />
</Folder>
</Solution>
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Eryx.AgentHost.Tests")]
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace Kopaya.AgentHost.Contracts;
namespace Eryx.AgentHost.Contracts;
public sealed class PatternAgentDefinitionDto
{
@@ -1,8 +1,8 @@
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Services;
if (!args.Contains("--stdio", StringComparer.Ordinal))
{
Console.Error.WriteLine("Kopaya.AgentHost expects the --stdio flag.");
Console.Error.WriteLine("Eryx.AgentHost expects the --stdio flag.");
return;
}
@@ -1,7 +1,7 @@
using System.Text;
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal readonly record struct AgentIdentity(string AgentId, string AgentName);
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal static class AgentInstructionComposer
{
@@ -1,7 +1,7 @@
using System.Collections;
using GitHub.Copilot.SDK;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal static class CopilotCliPathResolver
{
@@ -25,7 +25,7 @@ internal static class CopilotCliPathResolver
if (string.IsNullOrWhiteSpace(cliPath))
{
throw new InvalidOperationException(
"Kopaya requires the system-installed 'copilot' command on PATH. Install the GitHub Copilot CLI and ensure it is available in the current environment.");
"Eryx requires the system-installed 'copilot' command on PATH. Install the GitHub Copilot CLI and ensure it is available in the current environment.");
}
CopilotCliLaunch launch = ResolveCliLaunch(
@@ -2,9 +2,9 @@ using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using GitHub.Copilot.SDK;
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal static partial class CopilotConnectionMetadataResolver
{
@@ -156,7 +156,7 @@ internal static partial class CopilotConnectionMetadataResolver
}
catch (Exception exception)
{
Console.Error.WriteLine($"[kopaya sidecar] Failed to inspect Copilot auth status: {exception.Message}");
Console.Error.WriteLine($"[eryx sidecar] Failed to inspect Copilot auth status: {exception.Message}");
return null;
}
}
@@ -1,13 +1,13 @@
using System.Text;
using GitHub.Copilot.SDK;
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.GitHub.Copilot;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Specialized;
using Microsoft.Extensions.AI;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
public sealed class CopilotWorkflowRunner : ITurnWorkflowRunner
{
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal static class HandoffWorkflowGuidance
{
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
public interface ITurnWorkflowRunner
{
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
public sealed class PatternValidator
{
@@ -2,9 +2,9 @@ using System.Collections.Concurrent;
using System.Text.Json;
using System.Text.Json.Serialization;
using GitHub.Copilot.SDK;
using Kopaya.AgentHost.Contracts;
using Eryx.AgentHost.Contracts;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
public sealed class SidecarProtocolHost
{
@@ -189,7 +189,7 @@ public sealed class SidecarProtocolHost
catch (Exception exception)
{
connection = CreateMissingCliDiagnostics(exception);
Console.Error.WriteLine($"[kopaya sidecar] {connection.Summary} {exception.Message}");
Console.Error.WriteLine($"[eryx sidecar] {connection.Summary} {exception.Message}");
return new SidecarCapabilitiesDto
{
@@ -224,7 +224,7 @@ public sealed class SidecarProtocolHost
{
cliVersion = await cliVersionTask.ConfigureAwait(false);
connection = CreateFailureConnectionDiagnostics(cliContext.CliPath, exception, cliVersion, account);
Console.Error.WriteLine($"[kopaya sidecar] Failed to list available Copilot models: {exception.Message}");
Console.Error.WriteLine($"[eryx sidecar] Failed to list available Copilot models: {exception.Message}");
}
return new SidecarCapabilitiesDto
@@ -323,8 +323,8 @@ public sealed class SidecarProtocolHost
{
string status = ClassifyConnectionStatus(exception);
string summary = status == "copilot-auth-required"
? "GitHub Copilot requires authentication before Kopaya can load models."
: "GitHub Copilot was found, but Kopaya could not load its model list.";
? "GitHub Copilot requires authentication before Eryx can load models."
: "GitHub Copilot was found, but Eryx could not load its model list.";
return new SidecarConnectionDiagnosticsDto
{
@@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
namespace Kopaya.AgentHost.Services;
namespace Eryx.AgentHost.Services;
internal static partial class StreamingTextMerger
{
@@ -1,3 +0,0 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Kopaya.AgentHost.Tests")]
@@ -1,7 +1,7 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class AgentIdentityResolverTests
{
@@ -1,7 +1,7 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class AgentInstructionComposerTests
{
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class CopilotCliPathResolverTests
{
@@ -1,7 +1,7 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class CopilotConnectionMetadataResolverTests
{
@@ -1,8 +1,8 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
using Microsoft.Extensions.AI;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class CopilotWorkflowRunnerTests
{
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
@@ -19,7 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Kopaya.AgentHost\Kopaya.AgentHost.csproj" />
<ProjectReference Include="..\..\src\Eryx.AgentHost\Eryx.AgentHost.csproj" />
</ItemGroup>
</Project>
@@ -1,7 +1,7 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class HandoffWorkflowGuidanceTests
{
@@ -1,8 +1,8 @@
using System.Text.Json;
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class SidecarProtocolHostTests
{
@@ -1,6 +1,6 @@
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class StreamingTextMergerTests
{
@@ -1,7 +1,7 @@
using Kopaya.AgentHost.Contracts;
using Kopaya.AgentHost.Services;
using Eryx.AgentHost.Contracts;
using Eryx.AgentHost.Services;
namespace Kopaya.AgentHost.Tests;
namespace Eryx.AgentHost.Tests;
public sealed class PatternValidatorTests
{
@@ -54,7 +54,7 @@ function isBuiltinPattern(patternId: string): boolean {
return patternId.startsWith('pattern-');
}
export class KopayaAppService extends EventEmitter<AppServiceEvents> {
export class EryxAppService extends EventEmitter<AppServiceEvents> {
private readonly workspaceRepository = new WorkspaceRepository();
private readonly sidecar = new SidecarClient();
private readonly secretStore = new SecretStore();
@@ -79,7 +79,7 @@ export class KopayaAppService extends EventEmitter<AppServiceEvents> {
if (!this.didScheduleInitialProjectGitRefresh) {
this.didScheduleInitialProjectGitRefresh = true;
void this.refreshProjectGitContext().catch((error) => {
console.error('[kopaya git]', error);
console.error('[eryx git]', error);
});
}
+3 -3
View File
@@ -1,14 +1,14 @@
import { app, BrowserWindow } from 'electron';
import { registerIpcHandlers } from '@main/ipc/registerIpcHandlers';
import { KopayaAppService } from '@main/KopayaAppService';
import { EryxAppService } from '@main/EryxAppService';
import { createMainWindow } from '@main/windows/createMainWindow';
let mainWindow: BrowserWindow | undefined;
let appService: KopayaAppService | undefined;
let appService: EryxAppService | undefined;
async function bootstrap(): Promise<void> {
appService = new KopayaAppService();
appService = new EryxAppService();
mainWindow = createMainWindow();
registerIpcHandlers(mainWindow, appService);
+2 -2
View File
@@ -14,9 +14,9 @@ import type {
} from '@shared/contracts/ipc';
import type { QuerySessionsInput } from '@shared/domain/sessionLibrary';
import { KopayaAppService } from '@main/KopayaAppService';
import { EryxAppService } from '@main/EryxAppService';
export function registerIpcHandlers(window: BrowserWindow, service: KopayaAppService): void {
export function registerIpcHandlers(window: BrowserWindow, service: EryxAppService): void {
ipcMain.handle(ipcChannels.describeSidecarCapabilities, () => service.describeSidecarCapabilities());
ipcMain.handle(ipcChannels.refreshSidecarCapabilities, () => service.refreshSidecarCapabilities());
ipcMain.handle(ipcChannels.loadWorkspace, () => service.loadWorkspace());
+1 -1
View File
@@ -1,6 +1,6 @@
import keytar from 'keytar';
const serviceName = 'kopaya';
const serviceName = 'eryx';
export class SecretStore {
async get(account: string): Promise<string | null> {
+1 -1
View File
@@ -98,7 +98,7 @@ export class SidecarClient {
childProcess.stderr.setEncoding('utf8');
childProcess.stderr.on('data', (chunk: string) => {
console.error('[kopaya sidecar]', chunk.trim());
console.error('[eryx sidecar]', chunk.trim());
});
childProcess.on('exit', (code) => {
+2 -2
View File
@@ -18,7 +18,7 @@ function getPathModule(platform: NodeJS.Platform) {
}
function getBundledSidecarExecutableName(platform: NodeJS.Platform): string {
return platform === 'win32' ? 'Kopaya.AgentHost.exe' : 'Kopaya.AgentHost';
return platform === 'win32' ? 'Eryx.AgentHost.exe' : 'Eryx.AgentHost';
}
export function resolveSidecarProcess(context: SidecarRuntimeContext): ResolvedSidecarProcess {
@@ -39,7 +39,7 @@ export function resolveSidecarProcess(context: SidecarRuntimeContext): ResolvedS
args: [
'run',
'--project',
pathModule.join(context.appPath, 'sidecar', 'src', 'Kopaya.AgentHost', 'Kopaya.AgentHost.csproj'),
pathModule.join(context.appPath, 'sidecar', 'src', 'Eryx.AgentHost', 'Eryx.AgentHost.csproj'),
'--',
'--stdio',
],
+1 -1
View File
@@ -11,7 +11,7 @@ export function createMainWindow(): BrowserWindow {
height: 960,
minWidth: 1120,
minHeight: 720,
title: 'kopaya',
title: 'eryx',
icon: resolveWindowIconPath({
appPath: app.getAppPath(),
platform: process.platform,
+1 -1
View File
@@ -41,4 +41,4 @@ const api: ElectronApi = {
},
};
contextBridge.exposeInMainWorld('kopayaApi', api);
contextBridge.exposeInMainWorld('eryxApi', api);
+1 -1
View File
@@ -186,7 +186,7 @@ function ConnectionSection({
<div className="mb-1">
<h3 className="text-sm font-semibold text-zinc-200">GitHub Copilot</h3>
<p className="mt-0.5 text-[12px] text-zinc-500">
Kopaya uses your installed GitHub Copilot CLI for AI capabilities
Eryx uses your installed GitHub Copilot CLI for AI capabilities
</p>
</div>
<div className="mt-4 rounded-xl border border-[var(--color-border)] bg-zinc-900/30 p-4">
+1 -1
View File
@@ -499,7 +499,7 @@ export function Sidebar({
<Sparkles className="size-4" />
</div>
<div>
<span className="text-sm font-semibold text-zinc-100">kopaya</span>
<span className="text-sm font-semibold text-zinc-100">eryx</span>
<span className="ml-1.5 rounded bg-zinc-800 px-1 py-0.5 text-[9px] font-medium text-zinc-500">
BETA
</span>
+1 -1
View File
@@ -21,7 +21,7 @@ export function WelcomePane({
</div>
<div>
<h1 className="text-xl font-semibold text-zinc-100">Welcome to kopaya</h1>
<h1 className="text-xl font-semibold text-zinc-100">Welcome to eryx</h1>
<p className="mt-2 max-w-md text-sm leading-relaxed text-zinc-500">
Start a scratchpad conversation for ad-hoc questions or connect a project to work with
repo-aware Copilot agents.
+1 -1
View File
@@ -2,7 +2,7 @@ import type { ElectronApi } from '@shared/contracts/ipc';
declare global {
interface Window {
kopayaApi: ElectronApi;
eryxApi: ElectronApi;
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>kopaya</title>
<title>eryx</title>
</head>
<body class="bg-slate-950 text-slate-100">
<div id="root"></div>
+2 -2
View File
@@ -1,7 +1,7 @@
export function getElectronApi() {
if (!window.kopayaApi) {
if (!window.eryxApi) {
throw new Error('The Electron preload API is unavailable.');
}
return window.kopayaApi;
return window.eryxApi;
}
+1 -1
View File
@@ -24,7 +24,7 @@ export function applySessionEventActivity(
if (event.kind === 'agent-activity') {
const agentKey = resolveAgentKey(event);
if (!agentKey) {
console.warn('[kopaya activity] Dropping agent-activity event without agentId/agentName.', event);
console.warn('[eryx activity] Dropping agent-activity event without agentId/agentName.', event);
return current;
}
+6 -6
View File
@@ -6,27 +6,27 @@ describe('resolveWindowIconPath', () => {
test('uses the Windows ico asset from the platform-specific icon directory', () => {
expect(
resolveWindowIconPath({
appPath: 'C:\\workspace\\personal\\repositories\\kopaya',
appPath: 'C:\\workspace\\personal\\repositories\\eryx',
platform: 'win32',
}),
).toBe('C:\\workspace\\personal\\repositories\\kopaya\\assets\\icons\\windows\\icon.ico');
).toBe('C:\\workspace\\personal\\repositories\\eryx\\assets\\icons\\windows\\icon.ico');
});
test('uses the macOS icns asset on Darwin', () => {
expect(
resolveWindowIconPath({
appPath: '/Applications/Kopaya.app/Contents/Resources/app',
appPath: '/Applications/Eryx.app/Contents/Resources/app',
platform: 'darwin',
}),
).toBe('/Applications/Kopaya.app/Contents/Resources/app/assets/icons/macos/icon.icns');
).toBe('/Applications/Eryx.app/Contents/Resources/app/assets/icons/macos/icon.icns');
});
test('uses the Linux 512px PNG asset on Linux', () => {
expect(
resolveWindowIconPath({
appPath: '/opt/kopaya/resources/app',
appPath: '/opt/eryx/resources/app',
platform: 'linux',
}),
).toBe('/opt/kopaya/resources/app/assets/icons/linux/icons/512x512.png');
).toBe('/opt/eryx/resources/app/assets/icons/linux/icons/512x512.png');
});
});
+12 -12
View File
@@ -7,8 +7,8 @@ describe('resolveSidecarProcess', () => {
expect(
resolveSidecarProcess({
isPackaged: false,
appPath: 'C:\\workspace\\personal\\repositories\\kopaya',
resourcesPath: 'C:\\workspace\\personal\\repositories\\kopaya\\resources',
appPath: 'C:\\workspace\\personal\\repositories\\eryx',
resourcesPath: 'C:\\workspace\\personal\\repositories\\eryx\\resources',
platform: 'win32',
}),
).toEqual({
@@ -16,11 +16,11 @@ describe('resolveSidecarProcess', () => {
args: [
'run',
'--project',
'C:\\workspace\\personal\\repositories\\kopaya\\sidecar\\src\\Kopaya.AgentHost\\Kopaya.AgentHost.csproj',
'C:\\workspace\\personal\\repositories\\eryx\\sidecar\\src\\Eryx.AgentHost\\Eryx.AgentHost.csproj',
'--',
'--stdio',
],
cwd: 'C:\\workspace\\personal\\repositories\\kopaya',
cwd: 'C:\\workspace\\personal\\repositories\\eryx',
});
});
@@ -28,14 +28,14 @@ describe('resolveSidecarProcess', () => {
expect(
resolveSidecarProcess({
isPackaged: true,
appPath: 'C:\\workspace\\personal\\repositories\\kopaya\\release\\win-unpacked\\resources\\app',
resourcesPath: 'C:\\workspace\\personal\\repositories\\kopaya\\release\\win-unpacked\\resources',
appPath: 'C:\\workspace\\personal\\repositories\\eryx\\release\\win-unpacked\\resources\\app',
resourcesPath: 'C:\\workspace\\personal\\repositories\\eryx\\release\\win-unpacked\\resources',
platform: 'win32',
}),
).toEqual({
command: 'C:\\workspace\\personal\\repositories\\kopaya\\release\\win-unpacked\\resources\\sidecar\\Kopaya.AgentHost.exe',
command: 'C:\\workspace\\personal\\repositories\\eryx\\release\\win-unpacked\\resources\\sidecar\\Eryx.AgentHost.exe',
args: ['--stdio'],
cwd: 'C:\\workspace\\personal\\repositories\\kopaya\\release\\win-unpacked\\resources\\sidecar',
cwd: 'C:\\workspace\\personal\\repositories\\eryx\\release\\win-unpacked\\resources\\sidecar',
});
});
@@ -43,14 +43,14 @@ describe('resolveSidecarProcess', () => {
expect(
resolveSidecarProcess({
isPackaged: true,
appPath: '/Applications/Kopaya.app/Contents/Resources/app',
resourcesPath: '/Applications/Kopaya.app/Contents/Resources',
appPath: '/Applications/Eryx.app/Contents/Resources/app',
resourcesPath: '/Applications/Eryx.app/Contents/Resources',
platform: 'darwin',
}),
).toEqual({
command: '/Applications/Kopaya.app/Contents/Resources/sidecar/Kopaya.AgentHost',
command: '/Applications/Eryx.app/Contents/Resources/sidecar/Eryx.AgentHost',
args: ['--stdio'],
cwd: '/Applications/Kopaya.app/Contents/Resources/sidecar',
cwd: '/Applications/Eryx.app/Contents/Resources/sidecar',
});
});
});
+3 -3
View File
@@ -10,7 +10,7 @@ import {
describe('scratchpad project helpers', () => {
test('creates a stable built-in scratchpad project', () => {
const project = createScratchpadProject('C:\\Users\\me\\AppData\\Roaming\\kopaya\\scratchpad');
const project = createScratchpadProject('C:\\Users\\me\\AppData\\Roaming\\eryx\\scratchpad');
expect(project.id).toBe(SCRATCHPAD_PROJECT_ID);
expect(project.name).toBe(SCRATCHPAD_PROJECT_NAME);
@@ -38,7 +38,7 @@ describe('scratchpad project helpers', () => {
addedAt: '2026-03-23T00:00:00.000Z',
},
],
'C:\\Users\\me\\AppData\\Roaming\\kopaya\\scratchpad',
'C:\\Users\\me\\AppData\\Roaming\\eryx\\scratchpad',
);
expect(merged[0].id).toBe(SCRATCHPAD_PROJECT_ID);
@@ -69,7 +69,7 @@ describe('scratchpad project helpers', () => {
},
},
],
'C:\\Users\\me\\AppData\\Roaming\\kopaya\\scratchpad',
'C:\\Users\\me\\AppData\\Roaming\\eryx\\scratchpad',
);
expect(merged[0].git).toBeUndefined();