diff --git a/.vscode/settings.json b/.vscode/settings.json index 4e0d5b7..c3b651b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,27 @@ "biome.enabled": true, // autofix "editor.formatOnSave": false, - "[typescript][typescriptreact][javascript][javascriptreact][json][jsonc][json][yaml]": { + "[typescript]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascript]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { "editor.formatOnSave": true, "editor.defaultFormatter": "biomejs.biome" }, diff --git a/e2e/captureSnapshot/index.ts b/e2e/captureSnapshot/index.ts index ed39879..f32776d 100644 --- a/e2e/captureSnapshot/index.ts +++ b/e2e/captureSnapshot/index.ts @@ -1,7 +1,6 @@ import { TaskExecutor } from "../utils/TaskExecutor"; import { errorPagesCapture } from "./error-pages"; import { homeCapture } from "./home"; -import { projectDetailCapture } from "./project-detail"; import { projectsCapture } from "./projects"; import { sessionDetailCapture } from "./session-detail"; @@ -17,7 +16,6 @@ const tasks = [ ...homeCapture.tasks, ...errorPagesCapture.tasks, ...projectsCapture.tasks, - ...projectDetailCapture.tasks, ...sessionDetailCapture.tasks, ]; diff --git a/e2e/captureSnapshot/project-detail.ts b/e2e/captureSnapshot/project-detail.ts deleted file mode 100644 index 1c04429..0000000 --- a/e2e/captureSnapshot/project-detail.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { projectIds } from "../config"; -import { defineCapture } from "../utils/defineCapture"; - -export const projectDetailCapture = defineCapture({ - href: `projects/${projectIds.sampleProject}`, - cases: [ - { - name: "filters-expanded", - setup: async (page) => { - const filterToggle = page.locator( - '[data-testid="expand-filter-settings-button"]', - ); - if (await filterToggle.isVisible()) { - await filterToggle.click(); - await page.waitForTimeout(300); - } else { - throw new Error("Filter settings button not found"); - } - }, - }, - { - name: "new-chat-modal", - setup: async (page) => { - const newChatButton = page.locator('[data-testid="new-chat"]'); - if (await newChatButton.isVisible()) { - await newChatButton.click(); - await page.waitForTimeout(300); - } - }, - }, - ], -}); diff --git a/e2e/config.ts b/e2e/config.ts index 17f75f4..48c7e67 100644 --- a/e2e/config.ts +++ b/e2e/config.ts @@ -1,6 +1,6 @@ import { homedir } from "node:os"; import { resolve } from "node:path"; -import { encodeProjectId } from "../src/server/service/project/id"; +import { encodeProjectId } from "../src/server/core/project/functions/id"; // biome-ignore lint/complexity/useLiteralKeys: env var export const globalClaudeDirectoryPath = process.env["GLOBAL_CLAUDE_DIR"] diff --git a/e2e/snapshots/desktop.png b/e2e/snapshots/desktop.png index 7b5f500..5e4e0ad 100644 Binary files a/e2e/snapshots/desktop.png and b/e2e/snapshots/desktop.png differ diff --git a/e2e/snapshots/mobile.png b/e2e/snapshots/mobile.png index a908afb..82952b4 100644 Binary files a/e2e/snapshots/mobile.png and b/e2e/snapshots/mobile.png differ diff --git a/e2e/snapshots/non-existent-page/desktop.png b/e2e/snapshots/non-existent-page/desktop.png index dba5e0c..0c0e38d 100644 Binary files a/e2e/snapshots/non-existent-page/desktop.png and b/e2e/snapshots/non-existent-page/desktop.png differ diff --git a/e2e/snapshots/non-existent-page/mobile.png b/e2e/snapshots/non-existent-page/mobile.png index 9a11c15..2f38696 100644 Binary files a/e2e/snapshots/non-existent-page/mobile.png and b/e2e/snapshots/non-existent-page/mobile.png differ diff --git a/e2e/snapshots/non-existent-page/tablet.png b/e2e/snapshots/non-existent-page/tablet.png index 26f5cea..9f0b9cc 100644 Binary files a/e2e/snapshots/non-existent-page/tablet.png and b/e2e/snapshots/non-existent-page/tablet.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/desktop.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/desktop.png index 8e096ba..efbb4f3 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/desktop.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/desktop.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/mobile.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/mobile.png index 24b7106..6703f54 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/mobile.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/mobile.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/desktop.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/desktop.png index edb96c7..b35b02c 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/desktop.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/desktop.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/mobile.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/mobile.png index 24b7106..6703f54 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/mobile.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/mobile.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/tablet.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/tablet.png index 5e9d959..a9c49e1 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/tablet.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/settings-tab/tablet.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/desktop.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/desktop.png index 8e096ba..0feec0e 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/desktop.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/desktop.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/mobile.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/mobile.png index 24b7106..6703f54 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/mobile.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/mobile.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/tablet.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/tablet.png index 5e9d959..a9c49e1 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/tablet.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/sidebar-closed/tablet.png differ diff --git a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/tablet.png b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/tablet.png index 5e9d959..a9c49e1 100644 Binary files a/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/tablet.png and b/e2e/snapshots/projects/L2hvbWUvcnVubmVyL3dvcmsvY2xhdWRlLWNvZGUtdmlld2VyL2NsYXVkZS1jb2RlLXZpZXdlci9tb2NrLWdsb2JhbC1jbGF1ZGUtZGlyL3Byb2plY3RzL3NhbXBsZS1wcm9qZWN0/sessions/fe5e1c67-53e7-4862-81ae-d0e013e3270b/tablet.png differ diff --git a/e2e/snapshots/projects/desktop.png b/e2e/snapshots/projects/desktop.png index 7b5f500..5e4e0ad 100644 Binary files a/e2e/snapshots/projects/desktop.png and b/e2e/snapshots/projects/desktop.png differ diff --git a/e2e/snapshots/projects/mobile.png b/e2e/snapshots/projects/mobile.png index a908afb..82952b4 100644 Binary files a/e2e/snapshots/projects/mobile.png and b/e2e/snapshots/projects/mobile.png differ diff --git a/e2e/snapshots/projects/tablet.png b/e2e/snapshots/projects/tablet.png index 2584345..393768d 100644 Binary files a/e2e/snapshots/projects/tablet.png and b/e2e/snapshots/projects/tablet.png differ diff --git a/e2e/snapshots/tablet.png b/e2e/snapshots/tablet.png index 2584345..393768d 100644 Binary files a/e2e/snapshots/tablet.png and b/e2e/snapshots/tablet.png differ diff --git a/package.json b/package.json index bd2edac..c99fdd3 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,8 @@ }, "dependencies": { "@anthropic-ai/claude-code": "^1.0.98", + "@effect/platform": "^0.92.1", + "@effect/platform-node": "^0.98.3", "@hono/zod-validator": "^0.7.2", "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.3", @@ -48,9 +50,12 @@ "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-query": "^5.85.5", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "effect": "^3.18.4", + "es-toolkit": "^1.40.0", "hono": "^4.9.5", "jotai": "^2.13.1", "lucide-react": "^0.542.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6faec8f..0bf25bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: '@anthropic-ai/claude-code': specifier: ^1.0.98 version: 1.0.128 + '@effect/platform': + specifier: ^0.92.1 + version: 0.92.1(effect@3.18.4) + '@effect/platform-node': + specifier: ^0.98.3 + version: 0.98.3(@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) '@hono/zod-validator': specifier: ^0.7.2 version: 0.7.2(hono@4.9.5)(zod@4.1.5) @@ -38,6 +44,9 @@ importers: '@radix-ui/react-tabs': specifier: ^1.1.13 version: 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-tooltip': + specifier: ^1.2.8 + version: 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@tanstack/react-query': specifier: ^5.85.5 version: 5.85.5(react@19.1.1) @@ -47,6 +56,12 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + effect: + specifier: ^3.18.4 + version: 3.18.4 + es-toolkit: + specifier: ^1.40.0 + version: 1.40.0 hono: specifier: ^4.9.5 version: 4.9.5 @@ -225,6 +240,71 @@ packages: conventional-commits-parser: optional: true + '@effect/cluster@0.50.4': + resolution: {integrity: sha512-9uS2pRN4BCguAGqFCLFlQkReXG993UFj/TLtiwaXsacytKhdlGBU5zDDI/TckbM0wUv4g2nZPRRywqU8qnrvjQ==} + peerDependencies: + '@effect/platform': ^0.92.1 + '@effect/rpc': ^0.71.0 + '@effect/sql': ^0.46.0 + '@effect/workflow': ^0.11.3 + effect: ^3.18.4 + + '@effect/experimental@0.56.0': + resolution: {integrity: sha512-ZT9wTUVyDptzdkW4Tfvz5fNzygW9vt5jWcFmKI9SlhZMu9unVJgsBhxWCNYCyfPnxw3n/Z6SEKsqgt8iKQc4MA==} + peerDependencies: + '@effect/platform': ^0.92.0 + effect: ^3.18.0 + ioredis: ^5 + lmdb: ^3 + peerDependenciesMeta: + ioredis: + optional: true + lmdb: + optional: true + + '@effect/platform-node-shared@0.51.4': + resolution: {integrity: sha512-xElU9+cNPa1BnUHAZ3sVVanuuKof8oWQhK7rbyHNqgWM7CZTjv7x9VMDs0X05+1OcTQnnW3E+SrZKIPCfcYlDQ==} + peerDependencies: + '@effect/cluster': ^0.50.3 + '@effect/platform': ^0.92.1 + '@effect/rpc': ^0.71.0 + '@effect/sql': ^0.46.0 + effect: ^3.18.2 + + '@effect/platform-node@0.98.3': + resolution: {integrity: sha512-90eMWmFSVHrUEreICCd2qLPiw7qcaAv9XTx9OJ+LLv7igQgt4qkisRSK0oxAr5hqU9TdUrsgFDohqe7q7h3ZRg==} + peerDependencies: + '@effect/cluster': ^0.50.3 + '@effect/platform': ^0.92.1 + '@effect/rpc': ^0.71.0 + '@effect/sql': ^0.46.0 + effect: ^3.18.1 + + '@effect/platform@0.92.1': + resolution: {integrity: sha512-XXWCBVwyhaKZISN7aM1fv/3fWDGyxr84ObywnUrL8aHvJLoIeskWFAP/fqw3c5MFCrJ3ZV97RWLbv6JiBQugdg==} + peerDependencies: + effect: ^3.18.1 + + '@effect/rpc@0.71.0': + resolution: {integrity: sha512-m6mFX0ShdA+fnYAyamz7SRKF4FepaDB/ZhBri6iue26tBF2LrOFJUWewbwv8/LdLSedkO4eukhsHXuEYortL/w==} + peerDependencies: + '@effect/platform': ^0.92.0 + effect: ^3.18.0 + + '@effect/sql@0.46.0': + resolution: {integrity: sha512-nm9TuTTG7gLmJlIPkf71wA5lXArSvkpm1oYoIF+rhf01wef+1ujz9Mv1SfuzYbzsk7W9+OXUIRMxz/nSlKkiGQ==} + peerDependencies: + '@effect/experimental': ^0.56.0 + '@effect/platform': ^0.92.0 + effect: ^3.18.0 + + '@effect/workflow@0.11.3': + resolution: {integrity: sha512-3uyj0yOc2QRtQVOw6NEJVEMOhN/F7khhnf3QSU+2T3wvuDag9iBUzJFvSls8PgNCO3j/GgeaWzbcXwxqpFQYOQ==} + peerDependencies: + '@effect/platform': ^0.92.1 + '@effect/rpc': ^0.71.0 + effect: ^3.18.1 + '@emnapi/runtime@1.5.0': resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} @@ -741,6 +821,36 @@ packages: '@jridgewell/trace-mapping@0.3.30': resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] + '@next/env@15.5.2': resolution: {integrity: sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==} @@ -853,6 +963,88 @@ packages: '@octokit/types@14.1.0': resolution: {integrity: sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==} + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + '@phun-ky/typeof@1.2.8': resolution: {integrity: sha512-7J6ca1tK0duM2BgVB+CuFMh3idlIVASOP2QvOCbNWDc6JnvjtKa9nufPoJQQ4xrwBonwgT1TIhRRcEtzdVgWsA==} engines: {node: ^20.9.0 || >=22.0.0, npm: '>=10.8.2'} @@ -1130,6 +1322,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-use-callback-ref@1.1.1': resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: @@ -1342,6 +1547,9 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -1862,6 +2070,11 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} @@ -1884,6 +2097,9 @@ packages: resolution: {integrity: sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==} engines: {node: '>=12'} + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + emoji-regex@10.5.0: resolution: {integrity: sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==} @@ -1897,6 +2113,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-toolkit@1.40.0: + resolution: {integrity: sha512-8o6w0KFmU0CiIl0/Q/BCEOabF2IJaELM1T2PWj6e8KqzHv1gdx+7JtFnDwOx1kJH/isJ5NwlDG1nCr1HrRF94Q==} + esbuild@0.25.9: resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} @@ -1956,6 +2175,10 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + fast-content-type-parse@2.0.1: resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} @@ -1979,6 +2202,9 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-my-way-ts@0.1.6: + resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} + format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} @@ -2498,6 +2724,10 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} @@ -2506,6 +2736,11 @@ packages: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -2554,6 +2789,16 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + hasBin: true + + msgpackr@1.11.5: + resolution: {integrity: sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==} + + multipasta@0.2.7: + resolution: {integrity: sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==} + mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2598,9 +2843,16 @@ packages: sass: optional: true + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2785,6 +3037,9 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} @@ -3132,6 +3387,10 @@ packages: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + engines: {node: '>=20.18.1'} + unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} @@ -3186,6 +3445,10 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -3291,6 +3554,18 @@ packages: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + wsl-utils@0.1.0: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} @@ -3393,6 +3668,75 @@ snapshots: conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.2.0 + '@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/platform': 0.92.1(effect@3.18.4) + '@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@effect/sql': 0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@effect/workflow': 0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) + effect: 3.18.4 + + '@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/platform': 0.92.1(effect@3.18.4) + effect: 3.18.4 + uuid: 11.1.0 + + '@effect/platform-node-shared@0.51.4(@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/cluster': 0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) + '@effect/platform': 0.92.1(effect@3.18.4) + '@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@effect/sql': 0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@parcel/watcher': 2.5.1 + effect: 3.18.4 + multipasta: 0.2.7 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/platform-node@0.98.3(@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/cluster': 0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) + '@effect/platform': 0.92.1(effect@3.18.4) + '@effect/platform-node-shared': 0.51.4(@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) + '@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@effect/sql': 0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + effect: 3.18.4 + mime: 3.0.0 + undici: 7.16.0 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/platform@0.92.1(effect@3.18.4)': + dependencies: + effect: 3.18.4 + find-my-way-ts: 0.1.6 + msgpackr: 1.11.5 + multipasta: 0.2.7 + + '@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/platform': 0.92.1(effect@3.18.4) + effect: 3.18.4 + msgpackr: 1.11.5 + + '@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/experimental': 0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + '@effect/platform': 0.92.1(effect@3.18.4) + effect: 3.18.4 + uuid: 11.1.0 + + '@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4)': + dependencies: + '@effect/platform': 0.92.1(effect@3.18.4) + '@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) + effect: 3.18.4 + '@emnapi/runtime@1.5.0': dependencies: tslib: 2.8.1 @@ -3779,6 +4123,24 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + '@next/env@15.5.2': {} '@next/swc-darwin-arm64@15.5.2': @@ -3877,6 +4239,66 @@ snapshots: dependencies: '@octokit/openapi-types': 25.1.0 + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + '@phun-ky/typeof@1.2.8': {} '@playwright/test@1.55.0': @@ -4164,6 +4586,26 @@ snapshots: '@types/react': 19.1.12 '@types/react-dom': 19.1.9(@types/react@19.1.12) + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.12)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.12)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.12)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.12)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.12)(react@19.1.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.12 + '@types/react-dom': 19.1.9(@types/react@19.1.12) + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.12)(react@19.1.1)': dependencies: react: 19.1.1 @@ -4309,6 +4751,8 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@standard-schema/spec@1.0.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -4831,6 +5275,8 @@ snapshots: destr@2.0.5: {} + detect-libc@1.0.3: {} + detect-libc@2.0.4: {} detect-node-es@1.1.0: {} @@ -4847,6 +5293,11 @@ snapshots: dotenv@17.2.1: {} + effect@3.18.4: + dependencies: + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 + emoji-regex@10.5.0: {} emoji-regex@8.0.0: {} @@ -4858,6 +5309,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-toolkit@1.40.0: {} + esbuild@0.25.9: optionalDependencies: '@esbuild/aix-ppc64': 0.25.9 @@ -4946,6 +5399,10 @@ snapshots: extend@3.0.2: {} + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + fast-content-type-parse@2.0.1: {} fault@1.0.4: @@ -4964,6 +5421,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-my-way-ts@0.1.6: {} + format@0.2.2: {} fs-minipass@2.1.0: @@ -5642,12 +6101,19 @@ snapshots: transitivePeerDependencies: - supports-color + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.54.0: {} mime-types@3.0.1: dependencies: mime-db: 1.54.0 + mime@3.0.0: {} + mimic-fn@4.0.0: {} mimic-function@5.0.1: {} @@ -5684,6 +6150,24 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.5: + optionalDependencies: + msgpackr-extract: 3.0.3 + + multipasta@0.2.7: {} + mute-stream@2.0.0: {} nanoid@3.3.11: {} @@ -5723,8 +6207,15 @@ snapshots: - '@babel/core' - babel-plugin-macros + node-addon-api@7.1.1: {} + node-fetch-native@1.6.7: {} + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.0.4 + optional: true + normalize-path@3.0.0: {} npm-normalize-package-bin@4.0.0: {} @@ -5945,6 +6436,8 @@ snapshots: proxy-from-env@1.1.0: {} + pure-rand@6.1.0: {} + rc9@2.1.2: dependencies: defu: 6.1.4 @@ -6370,6 +6863,8 @@ snapshots: undici@6.21.3: {} + undici@7.16.0: {} + unicorn-magic@0.3.0: {} unified@11.0.5: @@ -6428,6 +6923,8 @@ snapshots: dependencies: react: 19.1.1 + uuid@11.1.0: {} + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -6542,6 +7039,8 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + ws@8.18.3: {} + wsl-utils@0.1.0: dependencies: is-wsl: 3.1.0 diff --git a/scripts/build.sh b/scripts/build.sh index bf1ace9..1dd13e1 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -6,6 +6,10 @@ if [ -d "dist/.next" ]; then rm -rf dist/.next fi +if [ -d "dist/standalone" ]; then + rm -rf dist/standalone +fi + pnpm exec next build cp -r public .next/standalone/ cp -r .next/static .next/standalone/.next/ diff --git a/src/app/api/[[...route]]/route.ts b/src/app/api/[[...route]]/route.ts index 63e2ac0..c7c062f 100644 --- a/src/app/api/[[...route]]/route.ts +++ b/src/app/api/[[...route]]/route.ts @@ -1,8 +1,79 @@ +import { NodeContext } from "@effect/platform-node"; +import { Effect } from "effect"; import { handle } from "hono/vercel"; +import { ClaudeCodeController } from "../../../server/core/claude-code/presentation/ClaudeCodeController"; +import { ClaudeCodePermissionController } from "../../../server/core/claude-code/presentation/ClaudeCodePermissionController"; +import { ClaudeCodeSessionProcessController } from "../../../server/core/claude-code/presentation/ClaudeCodeSessionProcessController"; +import { ClaudeCodeLifeCycleService } from "../../../server/core/claude-code/services/ClaudeCodeLifeCycleService"; +import { ClaudeCodePermissionService } from "../../../server/core/claude-code/services/ClaudeCodePermissionService"; +import { ClaudeCodeService } from "../../../server/core/claude-code/services/ClaudeCodeService"; +import { ClaudeCodeSessionProcessService } from "../../../server/core/claude-code/services/ClaudeCodeSessionProcessService"; +import { SSEController } from "../../../server/core/events/presentation/SSEController"; +import { EventBus } from "../../../server/core/events/services/EventBus"; +import { FileWatcherService } from "../../../server/core/events/services/fileWatcher"; +import { FileSystemController } from "../../../server/core/file-system/presentation/FileSystemController"; +import { GitController } from "../../../server/core/git/presentation/GitController"; +import { GitService } from "../../../server/core/git/services/GitService"; +import { ApplicationContext } from "../../../server/core/platform/services/ApplicationContext"; +import { EnvService } from "../../../server/core/platform/services/EnvService"; +import { UserConfigService } from "../../../server/core/platform/services/UserConfigService"; +import { ProjectRepository } from "../../../server/core/project/infrastructure/ProjectRepository"; +import { ProjectController } from "../../../server/core/project/presentation/ProjectController"; +import { ProjectMetaService } from "../../../server/core/project/services/ProjectMetaService"; +import { SessionRepository } from "../../../server/core/session/infrastructure/SessionRepository"; +import { VirtualConversationDatabase } from "../../../server/core/session/infrastructure/VirtualConversationDatabase"; +import { SessionController } from "../../../server/core/session/presentation/SessionController"; +import { SessionMetaService } from "../../../server/core/session/services/SessionMetaService"; import { honoApp } from "../../../server/hono/app"; +import { InitializeService } from "../../../server/hono/initialize"; import { routes } from "../../../server/hono/route"; -routes(honoApp); +const program = routes(honoApp); + +await Effect.runPromise( + program + // 依存の浅い順にコンテナに pipe する必要がある + .pipe( + /** Presentation */ + Effect.provide(ProjectController.Live), + Effect.provide(SessionController.Live), + Effect.provide(GitController.Live), + Effect.provide(ClaudeCodeController.Live), + Effect.provide(ClaudeCodeSessionProcessController.Live), + Effect.provide(ClaudeCodePermissionController.Live), + Effect.provide(FileSystemController.Live), + Effect.provide(SSEController.Live), + ) + .pipe( + /** Application */ + Effect.provide(InitializeService.Live), + Effect.provide(FileWatcherService.Live), + ) + .pipe( + /** Domain */ + Effect.provide(ClaudeCodeLifeCycleService.Live), + Effect.provide(ClaudeCodePermissionService.Live), + Effect.provide(ClaudeCodeSessionProcessService.Live), + Effect.provide(ClaudeCodeService.Live), + Effect.provide(GitService.Live), + ) + .pipe( + /** Infrastructure */ + Effect.provide(ProjectRepository.Live), + Effect.provide(SessionRepository.Live), + Effect.provide(ProjectMetaService.Live), + Effect.provide(SessionMetaService.Live), + Effect.provide(VirtualConversationDatabase.Live), + ) + .pipe( + /** Platform */ + Effect.provide(ApplicationContext.Live), + Effect.provide(UserConfigService.Live), + Effect.provide(EventBus.Live), + Effect.provide(EnvService.Live), + Effect.provide(NodeContext.layer), + ), +); export const GET = handle(honoApp); export const POST = handle(honoApp); diff --git a/src/app/components/MarkdownContent.tsx b/src/app/components/MarkdownContent.tsx index e5acb61..faa038d 100644 --- a/src/app/components/MarkdownContent.tsx +++ b/src/app/components/MarkdownContent.tsx @@ -1,9 +1,13 @@ "use client"; +import { useTheme } from "next-themes"; import type { FC } from "react"; import Markdown from "react-markdown"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism"; +import { + oneDark, + oneLight, +} from "react-syntax-highlighter/dist/esm/styles/prism"; import remarkGfm from "remark-gfm"; interface MarkdownContentProps { @@ -15,6 +19,9 @@ export const MarkdownContent: FC = ({ content, className = "", }) => { + const { resolvedTheme } = useTheme(); + const syntaxTheme = resolvedTheme === "dark" ? oneDark : oneLight; + return (
= ({
= ({ return ( diff --git a/src/app/components/RootErrorBoundary.tsx b/src/app/components/RootErrorBoundary.tsx index fe68a7a..f18c9ac 100644 --- a/src/app/components/RootErrorBoundary.tsx +++ b/src/app/components/RootErrorBoundary.tsx @@ -1,15 +1,62 @@ "use client"; +import { AlertCircle, Home, RefreshCw } from "lucide-react"; import type { FC, PropsWithChildren } from "react"; import { ErrorBoundary } from "react-error-boundary"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; + export const RootErrorBoundary: FC = ({ children }) => { return ( ( -
-

Error

-

{error.message}

+ FallbackComponent={({ error, resetErrorBoundary }) => ( +
+ + +
+ +
+ Something went wrong + + An unexpected error occurred in the application + +
+
+
+ + + + Error Details + + {error.message} + + + +
+ + +
+
+
)} > diff --git a/src/app/components/SSEEventListeners.tsx b/src/app/components/SSEEventListeners.tsx index a80be14..0d0b0c3 100644 --- a/src/app/components/SSEEventListeners.tsx +++ b/src/app/components/SSEEventListeners.tsx @@ -5,33 +5,26 @@ import { useSetAtom } from "jotai"; import type { FC, PropsWithChildren } from "react"; import { projectDetailQuery, sessionDetailQuery } from "../../lib/api/queries"; import { useServerEventListener } from "../../lib/sse/hook/useServerEventListener"; -import { aliveTasksAtom } from "../projects/[projectId]/sessions/[sessionId]/store/aliveTasksAtom"; +import { sessionProcessesAtom } from "../projects/[projectId]/sessions/[sessionId]/store/sessionProcessesAtom"; export const SSEEventListeners: FC = ({ children }) => { const queryClient = useQueryClient(); - const setAliveTasks = useSetAtom(aliveTasksAtom); + const setSessionProcesses = useSetAtom(sessionProcessesAtom); useServerEventListener("sessionListChanged", async (event) => { - // invalidate session list await queryClient.invalidateQueries({ queryKey: projectDetailQuery(event.projectId).queryKey, }); }); useServerEventListener("sessionChanged", async (event) => { - // invalidate session detail await queryClient.invalidateQueries({ queryKey: sessionDetailQuery(event.projectId, event.sessionId).queryKey, }); }); - useServerEventListener("taskChanged", async ({ aliveTasks, changed }) => { - setAliveTasks(aliveTasks); - - await queryClient.invalidateQueries({ - queryKey: sessionDetailQuery(changed.projectId, changed.sessionId) - .queryKey, - }); + useServerEventListener("sessionProcessChanged", async ({ processes }) => { + setSessionProcesses(processes); }); return <>{children}; diff --git a/src/app/components/SyncSessionProcess.tsx b/src/app/components/SyncSessionProcess.tsx new file mode 100644 index 0000000..e0ff79a --- /dev/null +++ b/src/app/components/SyncSessionProcess.tsx @@ -0,0 +1,18 @@ +"use client"; + +import { useSetAtom } from "jotai"; +import { type FC, type PropsWithChildren, useEffect } from "react"; +import type { PublicSessionProcess } from "../../types/session-process"; +import { sessionProcessesAtom } from "../projects/[projectId]/sessions/[sessionId]/store/sessionProcessesAtom"; + +export const SyncSessionProcess: FC< + PropsWithChildren<{ initProcesses: PublicSessionProcess[] }> +> = ({ children, initProcesses }) => { + const setSessionProcesses = useSetAtom(sessionProcessesAtom); + + useEffect(() => { + setSessionProcesses(initProcesses); + }, [initProcesses, setSessionProcesses]); + + return <>{children}; +}; diff --git a/src/app/error.tsx b/src/app/error.tsx new file mode 100644 index 0000000..b52733a --- /dev/null +++ b/src/app/error.tsx @@ -0,0 +1,69 @@ +"use client"; + +import { AlertCircle, Home, RefreshCw } from "lucide-react"; + +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; + +export default function ErrorPage({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ( +
+ + +
+ +
+ Something went wrong + + An unexpected error occurred in the application + +
+
+
+ + + + Error Details + + {error.message} + {error.digest && ( +
+ Error ID: {error.digest} +
+ )} +
+
+ +
+ + +
+
+
+
+ ); +} diff --git a/src/app/hooks/useConfig.ts b/src/app/hooks/useConfig.ts index 72b535a..47ad420 100644 --- a/src/app/hooks/useConfig.ts +++ b/src/app/hooks/useConfig.ts @@ -6,7 +6,7 @@ import { import { useCallback } from "react"; import { honoClient } from "../../lib/api/client"; import { configQuery } from "../../lib/api/queries"; -import type { Config } from "../../server/config/config"; +import type { UserConfig } from "../../server/lib/config/config"; export const useConfig = () => { const queryClient = useQueryClient(); @@ -16,7 +16,7 @@ export const useConfig = () => { queryFn: configQuery.queryFn, }); const updateConfigMutation = useMutation({ - mutationFn: async (config: Config) => { + mutationFn: async (config: UserConfig) => { const response = await honoClient.api.config.$put({ json: config, }); @@ -32,7 +32,7 @@ export const useConfig = () => { return { config: data?.config, updateConfig: useCallback( - (config: Config) => { + (config: UserConfig) => { updateConfigMutation.mutate(config); }, [updateConfigMutation], diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 030d292..66e7d12 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,6 @@ import { QueryClient } from "@tanstack/react-query"; import { Geist, Geist_Mono } from "next/font/google"; +import { ThemeProvider } from "next-themes"; import { Toaster } from "../components/ui/sonner"; import { QueryClientProviderWrapper } from "../lib/api/QueryClientProviderWrapper"; @@ -7,8 +8,10 @@ import { SSEProvider } from "../lib/sse/components/SSEProvider"; import { RootErrorBoundary } from "./components/RootErrorBoundary"; import "./globals.css"; +import { honoClient } from "../lib/api/client"; import { configQuery } from "../lib/api/queries"; import { SSEEventListeners } from "./components/SSEEventListeners"; +import { SyncSessionProcess } from "./components/SyncSessionProcess"; export const dynamic = "force-dynamic"; export const fetchCache = "force-no-store"; @@ -40,19 +43,31 @@ export default async function RootLayout({ queryFn: configQuery.queryFn, }); + const initSessionProcesses = await honoClient.api.cc["session-processes"] + .$get({}) + .then((response) => response.json()); + return ( - + - - - - {children} - - - - + + + + + + + {children} + + + + + + + ); diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 0000000..79097e7 --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,41 @@ +import { FileQuestion, Home } from "lucide-react"; +import Link from "next/link"; + +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; + +export default function NotFoundPage() { + return ( +
+ + +
+ +
+ Page Not Found + + The page you are looking for does not exist + +
+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/src/app/projects/[projectId]/components/ProjectPage.tsx b/src/app/projects/[projectId]/components/ProjectPage.tsx deleted file mode 100644 index 53a90de..0000000 --- a/src/app/projects/[projectId]/components/ProjectPage.tsx +++ /dev/null @@ -1,202 +0,0 @@ -"use client"; - -import { useQueryClient } from "@tanstack/react-query"; -import { - ArrowLeftIcon, - ChevronDownIcon, - FolderIcon, - MessageSquareIcon, - PlusIcon, - SettingsIcon, -} from "lucide-react"; -import Link from "next/link"; -import { useEffect, useState } from "react"; -import { SettingsControls } from "@/components/SettingsControls"; -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "@/components/ui/collapsible"; -import { projectDetailQuery } from "../../../../lib/api/queries"; -import { useConfig } from "../../../hooks/useConfig"; -import { useProject } from "../hooks/useProject"; -import { firstCommandToTitle } from "../services/firstCommandToTitle"; -import { NewChatModal } from "./newChat/NewChatModal"; - -export const ProjectPageContent = ({ projectId }: { projectId: string }) => { - const { - data: { project, sessions }, - } = useProject(projectId); - const { config } = useConfig(); - const queryClient = useQueryClient(); - const [isSettingsOpen, setIsSettingsOpen] = useState(false); - - // biome-ignore lint/correctness/useExhaustiveDependencies: invalidate when config changed - useEffect(() => { - void queryClient.invalidateQueries({ - queryKey: projectDetailQuery(projectId).queryKey, - }); - }, [config.hideNoUserMessageSession, config.unifySameTitleSession]); - - return ( -
-
- - -
-
- -

- {project.meta.projectPath ?? project.claudeProjectPath} -

-
-
- - - Start New Chat - New Chat - - } - /> -
-
-

- History File: {project.claudeProjectPath ?? "unknown"} -

-
- -
-
-

- Conversation Sessions{" "} - {sessions.length > 0 ? `(${sessions.length})` : ""} -

- - {/* Filter Controls */} - -
- - - - -
- -
-
-
-
- - {sessions.length === 0 ? ( - - - -

No sessions found

-

- No conversation sessions found for this project. Start a - conversation with Claude Code in this project to create - sessions. -

- - - Start First Chat - - } - /> -
-
- ) : ( -
- {sessions.map((session) => ( - - - - - {session.meta.firstCommand !== null - ? firstCommandToTitle(session.meta.firstCommand) - : session.id} - - - - {session.id} - - - -

- {session.meta.messageCount} messages -

-

- Last modified:{" "} - {session.meta.lastModifiedAt - ? new Date( - session.meta.lastModifiedAt, - ).toLocaleDateString() - : ""} -

-

- {session.jsonlFilePath} -

-
- - - -
- ))} -
- )} -
-
-
- ); -}; diff --git a/src/app/projects/[projectId]/components/chatForm/ChatInput.tsx b/src/app/projects/[projectId]/components/chatForm/ChatInput.tsx index e707fd4..ffc2dfb 100644 --- a/src/app/projects/[projectId]/components/chatForm/ChatInput.tsx +++ b/src/app/projects/[projectId]/components/chatForm/ChatInput.tsx @@ -1,4 +1,9 @@ -import { AlertCircleIcon, LoaderIcon, SendIcon } from "lucide-react"; +import { + AlertCircleIcon, + LoaderIcon, + SendIcon, + SparklesIcon, +} from "lucide-react"; import { type FC, useCallback, useId, useRef, useState } from "react"; import { Button } from "../../../../../components/ui/button"; import { Textarea } from "../../../../../components/ui/textarea"; @@ -62,16 +67,28 @@ export const ChatInput: FC = ({ // IMEで変換中の場合は送信しない if (e.key === "Enter" && !e.nativeEvent.isComposing) { - const isEnterSend = config?.enterKeyBehavior === "enter-send"; + const enterKeyBehavior = config?.enterKeyBehavior; - if (isEnterSend && !e.shiftKey) { + if (enterKeyBehavior === "enter-send" && !e.shiftKey && !e.metaKey) { // Enter: Send mode e.preventDefault(); handleSubmit(); - } else if (!isEnterSend && e.shiftKey) { + } else if ( + enterKeyBehavior === "shift-enter-send" && + e.shiftKey && + !e.metaKey + ) { // Shift+Enter: Send mode (default) e.preventDefault(); handleSubmit(); + } else if ( + enterKeyBehavior === "command-enter-send" && + e.metaKey && + !e.shiftKey + ) { + // Command+Enter: Send mode (Mac) + e.preventDefault(); + handleSubmit(); } } }; @@ -148,78 +165,98 @@ export const ChatInput: FC = ({ return (
{error && ( -
- - Failed to send message. Please try again. +
+ + + Failed to send message. Please try again. +
)} -
-
-