refactor: move directories

This commit is contained in:
d-kimsuon
2025-10-17 20:18:28 +09:00
parent a5d81568bb
commit c745824dbe
78 changed files with 189 additions and 305 deletions

View File

@@ -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"]

View File

@@ -1,19 +1,19 @@
import { NodeContext } from "@effect/platform-node";
import { Effect } from "effect";
import { handle } from "hono/vercel";
import { ClaudeCodeLifeCycleService } from "../../../server/core/claude-code/services/ClaudeCodeLifeCycleService";
import { ClaudeCodePermissionService } from "../../../server/core/claude-code/services/ClaudeCodePermissionService";
import { ClaudeCodeSessionProcessService } from "../../../server/core/claude-code/services/ClaudeCodeSessionProcessService";
import { EventBus } from "../../../server/core/events/services/EventBus";
import { FileWatcherService } from "../../../server/core/events/services/fileWatcher";
import { ProjectRepository } from "../../../server/core/project/infrastructure/ProjectRepository";
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 { 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";
import { ClaudeCodeLifeCycleService } from "../../../server/service/claude-code/ClaudeCodeLifeCycleService";
import { ClaudeCodePermissionService } from "../../../server/service/claude-code/ClaudeCodePermissionService";
import { ClaudeCodeSessionProcessService } from "../../../server/service/claude-code/ClaudeCodeSessionProcessService";
import { EventBus } from "../../../server/service/events/EventBus";
import { FileWatcherService } from "../../../server/service/events/fileWatcher";
import { ProjectMetaService } from "../../../server/service/project/ProjectMetaService";
import { ProjectRepository } from "../../../server/service/project/ProjectRepository";
import { SessionMetaService } from "../../../server/service/session/SessionMetaService";
import { SessionRepository } from "../../../server/service/session/SessionRepository";
import { VirtualConversationDatabase } from "../../../server/service/session/VirtualConversationDatabase";
const program = routes(honoApp);

View File

@@ -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 { Config } from "../../server/lib/config/config";
export const useConfig = () => {
const queryClient = useQueryClient();

View File

@@ -1,4 +1,4 @@
import type { ParsedCommand } from "../../../../server/service/parseCommandXml";
import type { ParsedCommand } from "../../../../server/core/claude-code/functions/parseCommandXml";
export const firstCommandToTitle = (firstCommand: ParsedCommand) => {
switch (firstCommand.kind) {

View File

@@ -10,7 +10,7 @@ import {
} from "@/components/ui/collapsible";
import type { Conversation } from "@/lib/conversation-schema";
import type { ToolResultContent } from "@/lib/conversation-schema/content/ToolResultContentSchema";
import type { ErrorJsonl } from "../../../../../../../server/service/types";
import type { ErrorJsonl } from "../../../../../../../server/core/types";
import { useSidechain } from "../../hooks/useSidechain";
import { ConversationItem } from "./ConversationItem";

View File

@@ -3,7 +3,7 @@ import type { FC } from "react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { parseCommandXml } from "../../../../../../../server/service/parseCommandXml";
import { parseCommandXml } from "../../../../../../../server/core/claude-code/functions/parseCommandXml";
import { MarkdownContent } from "../../../../../../components/MarkdownContent";
export const UserTextContent: FC<{ text: string; id?: string }> = ({

View File

@@ -7,7 +7,7 @@ import type { FC } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { Session } from "../../../../../../../server/service/types";
import type { Session } from "../../../../../../../server/core/types";
import { NewChatModal } from "../../../../components/newChat/NewChatModal";
import { firstCommandToTitle } from "../../../../services/firstCommandToTitle";
import { sessionProcessesAtom } from "../../store/sessionProcessesAtom";

View File

@@ -1,5 +1,5 @@
import type { DirectoryListingResult } from "../../server/service/directory-browser/getDirectoryListing";
import type { FileCompletionResult } from "../../server/service/file-completion/getFileCompletion";
import type { DirectoryListingResult } from "../../server/core/directory-browser/functions/getDirectoryListing";
import type { FileCompletionResult } from "../../server/core/file-completion/functions/getFileCompletion";
import { honoClient } from "./client";
export const projectListQuery = {

View File

@@ -7,7 +7,7 @@ describe("computeClaudeProjectFilePath", () => {
beforeEach(async () => {
vi.resetModules();
vi.doMock("../../lib/env", () => ({
vi.doMock("../../../lib/env", () => ({
env: {
get: (key: string) => {
if (key === "GLOBAL_CLAUDE_DIR") {

View File

@@ -1,5 +1,5 @@
import path from "node:path";
import { claudeProjectsDirPath } from "../paths";
import { claudeProjectsDirPath } from "../../../lib/config/paths";
export function computeClaudeProjectFilePath(projectPath: string): string {
return path.join(

View File

@@ -1,5 +1,5 @@
import type { SDKMessage, SDKUserMessage } from "@anthropic-ai/claude-code";
import { controllablePromise } from "../../../lib/controllablePromise";
import { controllablePromise } from "../../../../lib/controllablePromise";
export type OnMessage = (message: SDKMessage) => void | Promise<void>;

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { ErrorJsonl } from "../../types";
import { parseJsonl } from "./parseJsonl";
import type { ErrorJsonl } from "./types";
describe("parseJsonl", () => {
describe("正常系: 有効なJSONLをパースできる", () => {

View File

@@ -1,5 +1,5 @@
import { ConversationSchema } from "../../lib/conversation-schema";
import type { ErrorJsonl } from "./types";
import { ConversationSchema } from "../../../../lib/conversation-schema";
import type { ErrorJsonl } from "../../types";
export const parseJsonl = (content: string) => {
const lines = content

View File

@@ -1,7 +1,7 @@
import { Effect } from "effect";
import type { UserEntry } from "../../../../lib/conversation-schema/entry/UserEntrySchema";
import * as ClaudeCode from "../ClaudeCode";
import type { InitMessageContext } from "../createMessageGenerator";
import type { InitMessageContext } from "../types";
import * as ClaudeCode from "./ClaudeCode";
import type * as CCTask from "./ClaudeCodeTask";
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";

View File

@@ -1,8 +1,8 @@
import { query as originalQuery } from "@anthropic-ai/claude-code";
import { Command, Path } from "@effect/platform";
import { Effect } from "effect";
import { env } from "../../lib/env";
import * as ClaudeCodeVersion from "./models/ClaudeCodeVersion";
import { env } from "../../../lib/env";
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";
type CCQuery = typeof originalQuery;
type CCQueryPrompt = Parameters<CCQuery>[0]["prompt"];

View File

@@ -3,18 +3,18 @@ import type { FileSystem, Path } from "@effect/platform";
import type { CommandExecutor } from "@effect/platform/CommandExecutor";
import { Context, Effect, Layer, Runtime } from "effect";
import { ulid } from "ulid";
import { controllablePromise } from "../../../lib/controllablePromise";
import type { Config } from "../../config/config";
import type { InferEffect } from "../../lib/effect/types";
import { EventBus } from "../events/EventBus";
import type { SessionMetaService } from "../session/SessionMetaService";
import { SessionRepository } from "../session/SessionRepository";
import { VirtualConversationDatabase } from "../session/VirtualConversationDatabase";
import * as ClaudeCode from "./ClaudeCode";
import { controllablePromise } from "../../../../lib/controllablePromise";
import type { Config } from "../../../lib/config/config";
import type { InferEffect } from "../../../lib/effect/types";
import { EventBus } from "../../events/services/EventBus";
import { SessionRepository } from "../../session/infrastructure/SessionRepository";
import { VirtualConversationDatabase } from "../../session/infrastructure/VirtualConversationDatabase";
import type { SessionMetaService } from "../../session/services/SessionMetaService";
import { createMessageGenerator } from "../functions/createMessageGenerator";
import * as CCSessionProcess from "../models/CCSessionProcess";
import * as ClaudeCode from "../models/ClaudeCode";
import { ClaudeCodePermissionService } from "./ClaudeCodePermissionService";
import { ClaudeCodeSessionProcessService } from "./ClaudeCodeSessionProcessService";
import { createMessageGenerator } from "./MessageGenerator";
import * as CCSessionProcess from "./models/CCSessionProcess";
export type MessageGenerator = () => AsyncGenerator<
SDKUserMessage,

View File

@@ -4,11 +4,11 @@ import { ulid } from "ulid";
import type {
PermissionRequest,
PermissionResponse,
} from "../../../types/permissions";
import type { Config } from "../../config/config";
import type { InferEffect } from "../../lib/effect/types";
import { EventBus } from "../events/EventBus";
import * as ClaudeCode from "./ClaudeCode";
} from "../../../../types/permissions";
import type { Config } from "../../../lib/config/config";
import type { InferEffect } from "../../../lib/effect/types";
import { EventBus } from "../../events/services/EventBus";
import * as ClaudeCode from "../models/ClaudeCode";
const LayerImpl = Effect.gen(function* () {
const pendingPermissionRequestsRef = yield* Ref.make<

View File

@@ -4,12 +4,12 @@ import type {
} from "@anthropic-ai/claude-code";
import { Effect, Layer } from "effect";
import { describe, expect, it } from "vitest";
import { EventBus } from "../events/EventBus";
import type { InternalEventDeclaration } from "../events/InternalEventDeclaration";
import { EventBus } from "../../events/services/EventBus";
import type { InternalEventDeclaration } from "../../events/types/InternalEventDeclaration";
import type * as CCSessionProcess from "../models/CCSessionProcess";
import type * as CCTask from "../models/ClaudeCodeTask";
import type { InitMessageContext } from "../types";
import { ClaudeCodeSessionProcessService } from "./ClaudeCodeSessionProcessService";
import type { InitMessageContext } from "./createMessageGenerator";
import type * as CCSessionProcess from "./models/CCSessionProcess";
import type * as CCTask from "./models/ClaudeCodeTask";
// Helper function to create mock session process definition
const createMockSessionProcessDef = (

View File

@@ -1,10 +1,10 @@
import type { SDKResultMessage } from "@anthropic-ai/claude-code";
import { Context, Data, Effect, Layer, Ref } from "effect";
import type { InferEffect } from "../../lib/effect/types";
import { EventBus } from "../events/EventBus";
import type { InitMessageContext } from "./createMessageGenerator";
import * as CCSessionProcess from "./models/CCSessionProcess";
import type * as CCTask from "./models/ClaudeCodeTask";
import type { InferEffect } from "../../../lib/effect/types";
import { EventBus } from "../../events/services/EventBus";
import * as CCSessionProcess from "../models/CCSessionProcess";
import type * as CCTask from "../models/ClaudeCodeTask";
import type { InitMessageContext } from "../types";
class SessionProcessNotFoundError extends Data.TaggedError(
"SessionProcessNotFoundError",

View File

@@ -0,0 +1,5 @@
import type { SDKSystemMessage } from "@anthropic-ai/claude-code";
export type InitMessageContext = {
initMessage: SDKSystemMessage;
};

View File

@@ -1,7 +1,7 @@
import { Effect } from "effect";
import type { SSEStreamingApi } from "hono/streaming";
import { describe, expect, it, vi } from "vitest";
import type { PermissionRequest } from "../../../types/permissions";
import type { PermissionRequest } from "../../../../types/permissions";
import { TypeSafeSSE } from "./typeSafeSSE";
describe("typeSafeSSE", () => {
@@ -153,7 +153,7 @@ describe("typeSafeSSE", () => {
const program = Effect.gen(function* () {
const typeSafeSSE = yield* TypeSafeSSE;
yield* typeSafeSSE.writeSSE("permission_requested", {
yield* typeSafeSSE.writeSSE("permissionRequested", {
permissionRequest: mockPermissionRequest,
});
@@ -170,10 +170,10 @@ describe("typeSafeSSE", () => {
if (!item) {
throw new Error("item is undefined");
}
expect(item.event).toBe("permission_requested");
expect(item.event).toBe("permissionRequested");
const data = JSON.parse(item.data);
expect(data.kind).toBe("permission_requested");
expect(data.kind).toBe("permissionRequested");
expect(data.permissionRequest.id).toBe("permission-1");
expect(data.timestamp).toBeDefined();
});

View File

@@ -1,7 +1,7 @@
import { Context, Effect, Layer } from "effect";
import type { SSEStreamingApi } from "hono/streaming";
import { ulid } from "ulid";
import type { SSEEventDeclaration } from "../../../types/sse";
import type { SSEEventDeclaration } from "../../../../types/sse";
interface TypeSafeSSEService {
readonly writeSSE: <EventName extends keyof SSEEventDeclaration>(

View File

@@ -1,10 +1,10 @@
import { Effect } from "effect";
import { describe, expect, it } from "vitest";
import type { PermissionRequest } from "../../../types/permissions";
import type { PublicSessionProcess } from "../../../types/session-process";
import type { CCSessionProcessState } from "../claude-code/models/CCSessionProcess";
import type { PermissionRequest } from "../../../../types/permissions";
import type { PublicSessionProcess } from "../../../../types/session-process";
import type { CCSessionProcessState } from "../../claude-code/models/CCSessionProcess";
import type { InternalEventDeclaration } from "../types/InternalEventDeclaration";
import { EventBus } from "./EventBus";
import type { InternalEventDeclaration } from "./InternalEventDeclaration";
describe("EventBus", () => {
describe("basic event processing", () => {

View File

@@ -1,5 +1,5 @@
import { Context, Effect, Layer } from "effect";
import type { InternalEventDeclaration } from "./InternalEventDeclaration";
import type { InternalEventDeclaration } from "../types/InternalEventDeclaration";
type Listener<T> = (data: T) => void | Promise<void>;

View File

@@ -1,8 +1,8 @@
import { Effect } from "effect";
import { describe, expect, it } from "vitest";
import type { InternalEventDeclaration } from "../types/InternalEventDeclaration";
import { EventBus } from "./EventBus";
import { FileWatcherService } from "./fileWatcher";
import type { InternalEventDeclaration } from "./InternalEventDeclaration";
describe("FileWatcherService", () => {
describe("startWatching", () => {

View File

@@ -2,8 +2,8 @@ import { type FSWatcher, watch } from "node:fs";
import { join } from "node:path";
import { Context, Effect, Layer, Ref } from "effect";
import z from "zod";
import { claudeProjectsDirPath } from "../paths";
import { encodeProjectIdFromSessionFilePath } from "../project/id";
import { claudeProjectsDirPath } from "../../../lib/config/paths";
import { encodeProjectIdFromSessionFilePath } from "../../project/functions/id";
import { EventBus } from "./EventBus";
const fileRegExp = /(?<projectId>.*?)\/(?<sessionId>.*?)\.jsonl/;

View File

@@ -1,6 +1,6 @@
import type { PermissionRequest } from "../../../types/permissions";
import type { PublicSessionProcess } from "../../../types/session-process";
import type * as CCSessionProcess from "../claude-code/models/CCSessionProcess";
import type { PermissionRequest } from "../../../../types/permissions";
import type { PublicSessionProcess } from "../../../../types/session-process";
import type * as CCSessionProcess from "../../claude-code/models/CCSessionProcess";
export type InternalEventDeclaration = {
// biome-ignore lint/complexity/noBannedTypes: correct type

View File

@@ -1,5 +1,5 @@
import type { GitBranch, GitResult } from "./types";
import { executeGitCommand, parseLines } from "./utils";
import { executeGitCommand, parseLines } from "../functions/utils";
import type { GitBranch, GitResult } from "../types";
/**
* Get all branches (local and remote) in the repository

View File

@@ -1,5 +1,5 @@
import type { GitCommit, GitResult } from "./types";
import { executeGitCommand, parseLines } from "./utils";
import { executeGitCommand, parseLines } from "../functions/utils";
import type { GitCommit, GitResult } from "../types";
/**
* Get the last 20 commits from the current branch

View File

@@ -4,6 +4,11 @@ import parseGitDiff, {
type AnyChunk,
type AnyFileChange,
} from "parse-git-diff";
import {
executeGitCommand,
parseLines,
stripAnsiColors,
} from "../functions/utils";
import type {
GitComparisonResult,
GitDiff,
@@ -11,8 +16,7 @@ import type {
GitDiffHunk,
GitDiffLine,
GitResult,
} from "./types";
import { executeGitCommand, parseLines, stripAnsiColors } from "./utils";
} from "../types";
/**
* Convert parse-git-diff file change to GitDiffFile

View File

@@ -1,10 +1,10 @@
import type { GitDiffFile, GitResult, GitStatus } from "./types";
import {
executeGitCommand,
getFileStatus,
parseLines,
parseStatusLine,
} from "./utils";
} from "../functions/utils";
import type { GitDiffFile, GitResult, GitStatus } from "../types";
/**
* Get git status information including staged, unstaged, and untracked files

View File

@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
import { resolve } from "node:path";
import { promisify } from "node:util";
import type { GitError, GitResult } from "./types";
import type { GitError, GitResult } from "../types";
const execFileAsync = promisify(execFile);

View File

@@ -1,5 +1,5 @@
import { execSync } from "node:child_process";
import { decodeProjectId } from "../project/id";
import { decodeProjectId } from "../../project/functions/id";
export interface McpServer {
name: string;

View File

@@ -1,9 +1,9 @@
import { FileSystem, Path } from "@effect/platform";
import { SystemError } from "@effect/platform/Error";
import { Effect, Layer, Option } from "effect";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
import type { ProjectMeta } from "../types";
import { ProjectMetaService } from "./ProjectMetaService";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import type { ProjectMeta } from "../../types";
import { ProjectMetaService } from "../services/ProjectMetaService";
import { ProjectRepository } from "./ProjectRepository";
/**

View File

@@ -1,11 +1,11 @@
import { resolve } from "node:path";
import { FileSystem } from "@effect/platform";
import { Context, Effect, Layer, Option } from "effect";
import type { InferEffect } from "../../lib/effect/types";
import { claudeProjectsDirPath } from "../paths";
import type { Project } from "../types";
import { decodeProjectId, encodeProjectId } from "./id";
import { ProjectMetaService } from "./ProjectMetaService";
import { claudeProjectsDirPath } from "../../../lib/config/paths";
import type { InferEffect } from "../../../lib/effect/types";
import type { Project } from "../../types";
import { decodeProjectId, encodeProjectId } from "../functions/id";
import { ProjectMetaService } from "../services/ProjectMetaService";
const LayerImpl = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem;

View File

@@ -0,0 +1,7 @@
import { z } from "zod";
export const projectMetaSchema = z.object({
projectName: z.string().nullable(),
projectPath: z.string().nullable(),
sessionCount: z.number(),
});

View File

@@ -1,7 +1,7 @@
import { FileSystem, Path } from "@effect/platform";
import { Effect, Layer, Option } from "effect";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
import { ProjectMetaService } from "./ProjectMetaService";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import { ProjectMetaService } from "../services/ProjectMetaService";
/**
* Helper function to create a FileSystem mock layer

View File

@@ -5,11 +5,11 @@ import { z } from "zod";
import {
FileCacheStorage,
makeFileCacheStorageLayer,
} from "../../lib/storage/FileCacheStorage";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
import { parseJsonl } from "../parseJsonl";
import type { ProjectMeta } from "../types";
import { decodeProjectId } from "./id";
} from "../../../lib/storage/FileCacheStorage";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
import type { ProjectMeta } from "../../types";
import { decodeProjectId } from "../functions/id";
const ProjectPathSchema = z.string().nullable();

View File

@@ -1,5 +1,5 @@
import { basename, extname, resolve } from "node:path";
import { decodeProjectId } from "../project/id";
import { decodeProjectId } from "../../project/functions/id";
export const encodeSessionId = (jsonlFilePath: string) => {
return basename(jsonlFilePath, extname(jsonlFilePath));

View File

@@ -1,13 +1,13 @@
import { FileSystem, Path } from "@effect/platform";
import { SystemError } from "@effect/platform/Error";
import { Effect, Layer, Option } from "effect";
import type { Conversation } from "../../../lib/conversation-schema";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
import { decodeProjectId } from "../project/id";
import type { ErrorJsonl, SessionDetail, SessionMeta } from "../types";
import { SessionMetaService } from "./SessionMetaService";
import { SessionRepository } from "./SessionRepository";
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
import type { Conversation } from "../../../../lib/conversation-schema";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import { decodeProjectId } from "../../project/functions/id";
import type { ErrorJsonl, SessionDetail, SessionMeta } from "../../types";
import { SessionRepository } from "../infrastructure/SessionRepository";
import { VirtualConversationDatabase } from "../infrastructure/VirtualConversationDatabase";
import { SessionMetaService } from "../services/SessionMetaService";
/**
* Helper function to create a FileSystem mock layer

View File

@@ -1,13 +1,13 @@
import { resolve } from "node:path";
import { FileSystem } from "@effect/platform";
import { Context, Effect, Layer, Option } from "effect";
import { parseCommandXml } from "../parseCommandXml";
import { parseJsonl } from "../parseJsonl";
import { decodeProjectId } from "../project/id";
import type { Session, SessionDetail } from "../types";
import { decodeSessionId, encodeSessionId } from "./id";
import { SessionMetaService } from "./SessionMetaService";
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
import { parseCommandXml } from "../../claude-code/functions/parseCommandXml";
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
import { decodeProjectId } from "../../project/functions/id";
import type { Session, SessionDetail } from "../../types";
import { decodeSessionId, encodeSessionId } from "../functions/id";
import { VirtualConversationDatabase } from "../infrastructure/VirtualConversationDatabase";
import { SessionMetaService } from "../services/SessionMetaService";
const getSession = (projectId: string, sessionId: string) =>
Effect.gen(function* () {

View File

@@ -1,6 +1,6 @@
import { Effect } from "effect";
import type { Conversation } from "../../../lib/conversation-schema";
import type { ErrorJsonl } from "../types";
import type { Conversation } from "../../../../lib/conversation-schema";
import type { ErrorJsonl } from "../../types";
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
describe("VirtualConversationDatabase", () => {

View File

@@ -1,6 +1,6 @@
import { Context, Effect, Layer, Ref } from "effect";
import type { Conversation } from "../../../lib/conversation-schema";
import type { ErrorJsonl } from "../types";
import type { Conversation } from "../../../../lib/conversation-schema";
import type { ErrorJsonl } from "../../types";
/**
* For interactively experience, handle sessions not already persisted to the filesystem.

View File

@@ -0,0 +1,7 @@
import { z } from "zod";
import { parsedCommandSchema } from "../claude-code/functions/parseCommandXml";
export const sessionMetaSchema = z.object({
messageCount: z.number(),
firstCommand: parsedCommandSchema.nullable(),
});

View File

@@ -1,7 +1,7 @@
import { FileSystem, Path } from "@effect/platform";
import { Effect, Layer } from "effect";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
import { SessionMetaService } from "./SessionMetaService";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import { SessionMetaService } from "../services/SessionMetaService";
/**
* Helper function to create a FileSystem mock layer

View File

@@ -3,16 +3,16 @@ import { Context, Effect, Layer, Ref } from "effect";
import {
FileCacheStorage,
makeFileCacheStorageLayer,
} from "../../lib/storage/FileCacheStorage";
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
} from "../../../lib/storage/FileCacheStorage";
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
import {
type ParsedCommand,
parseCommandXml,
parsedCommandSchema,
} from "../parseCommandXml";
import { parseJsonl } from "../parseJsonl";
import type { SessionMeta } from "../types";
import { decodeSessionId } from "./id";
} from "../../claude-code/functions/parseCommandXml";
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
import type { SessionMeta } from "../../types";
import { decodeSessionId } from "../functions/id";
const ignoreCommands = [
"/clear",

View File

@@ -1,6 +1,7 @@
import type { z } from "zod";
import type { Conversation } from "../../lib/conversation-schema";
import type { projectMetaSchema, sessionMetaSchema } from "./schema";
import type { projectMetaSchema } from "./project/schema";
import type { sessionMetaSchema } from "./session/schema";
export type Project = {
id: string;

View File

@@ -1,5 +1,5 @@
import { Hono } from "hono";
import type { Config } from "../config/config";
import type { Config } from "../lib/config/config";
export type HonoContext = {
Variables: {

View File

@@ -1,13 +1,13 @@
import { Effect, Layer, Ref } from "effect";
import { describe, expect, it, vi } from "vitest";
import { EventBus } from "../service/events/EventBus";
import { FileWatcherService } from "../service/events/fileWatcher";
import type { InternalEventDeclaration } from "../service/events/InternalEventDeclaration";
import { ProjectMetaService } from "../service/project/ProjectMetaService";
import { ProjectRepository } from "../service/project/ProjectRepository";
import { SessionMetaService } from "../service/session/SessionMetaService";
import { SessionRepository } from "../service/session/SessionRepository";
import { VirtualConversationDatabase } from "../service/session/VirtualConversationDatabase";
import { EventBus } from "../core/events/services/EventBus";
import { FileWatcherService } from "../core/events/services/fileWatcher";
import type { InternalEventDeclaration } from "../core/events/types/InternalEventDeclaration";
import { ProjectRepository } from "../core/project/infrastructure/ProjectRepository";
import { ProjectMetaService } from "../core/project/services/ProjectMetaService";
import { SessionRepository } from "../core/session/infrastructure/SessionRepository";
import { VirtualConversationDatabase } from "../core/session/infrastructure/VirtualConversationDatabase";
import { SessionMetaService } from "../core/session/services/SessionMetaService";
import { InitializeService } from "./initialize";
describe("InitializeService", () => {

View File

@@ -1,12 +1,12 @@
import { Context, Effect, Layer, Ref, Schedule } from "effect";
import { EventBus } from "../service/events/EventBus";
import { FileWatcherService } from "../service/events/fileWatcher";
import type { InternalEventDeclaration } from "../service/events/InternalEventDeclaration";
import { ProjectMetaService } from "../service/project/ProjectMetaService";
import { ProjectRepository } from "../service/project/ProjectRepository";
import { SessionMetaService } from "../service/session/SessionMetaService";
import { SessionRepository } from "../service/session/SessionRepository";
import { VirtualConversationDatabase } from "../service/session/VirtualConversationDatabase";
import { EventBus } from "../core/events/services/EventBus";
import { FileWatcherService } from "../core/events/services/fileWatcher";
import type { InternalEventDeclaration } from "../core/events/types/InternalEventDeclaration";
import { ProjectRepository } from "../core/project/infrastructure/ProjectRepository";
import { ProjectMetaService } from "../core/project/services/ProjectMetaService";
import { SessionRepository } from "../core/session/infrastructure/SessionRepository";
import { VirtualConversationDatabase } from "../core/session/infrastructure/VirtualConversationDatabase";
import { SessionMetaService } from "../core/session/services/SessionMetaService";
interface InitializeServiceInterface {
readonly startInitialization: () => Effect.Effect<void>;

View File

@@ -1,6 +1,6 @@
import { getCookie, setCookie } from "hono/cookie";
import { createMiddleware } from "hono/factory";
import { configSchema } from "../../config/config";
import { configSchema } from "../../lib/config/config";
import type { HonoContext } from "../app";
export const configMiddleware = createMiddleware<HonoContext>(

View File

@@ -9,28 +9,28 @@ import { streamSSE } from "hono/streaming";
import prexit from "prexit";
import { z } from "zod";
import type { PublicSessionProcess } from "../../types/session-process";
import { configSchema } from "../config/config";
import { computeClaudeProjectFilePath } from "../core/claude-code/functions/computeClaudeProjectFilePath";
import { ClaudeCodeLifeCycleService } from "../core/claude-code/services/ClaudeCodeLifeCycleService";
import { ClaudeCodePermissionService } from "../core/claude-code/services/ClaudeCodePermissionService";
import { getDirectoryListing } from "../core/directory-browser/functions/getDirectoryListing";
import { adaptInternalEventToSSE } from "../core/events/functions/adaptInternalEventToSSE";
import { TypeSafeSSE } from "../core/events/functions/typeSafeSSE";
import { EventBus } from "../core/events/services/EventBus";
import type { InternalEventDeclaration } from "../core/events/types/InternalEventDeclaration";
import { getFileCompletion } from "../core/file-completion/functions/getFileCompletion";
import { getBranches } from "../core/git/functions/getBranches";
import { getCommits } from "../core/git/functions/getCommits";
import { getDiff } from "../core/git/functions/getDiff";
import { getMcpList } from "../core/mcp/functions/getMcpList";
import { encodeProjectId } from "../core/project/functions/id";
import { ProjectRepository } from "../core/project/infrastructure/ProjectRepository";
import type { ProjectMetaService } from "../core/project/services/ProjectMetaService";
import { SessionRepository } from "../core/session/infrastructure/SessionRepository";
import type { VirtualConversationDatabase } from "../core/session/infrastructure/VirtualConversationDatabase";
import type { SessionMetaService } from "../core/session/services/SessionMetaService";
import { configSchema } from "../lib/config/config";
import { claudeCommandsDirPath } from "../lib/config/paths";
import { env } from "../lib/env";
import { ClaudeCodeLifeCycleService } from "../service/claude-code/ClaudeCodeLifeCycleService";
import { ClaudeCodePermissionService } from "../service/claude-code/ClaudeCodePermissionService";
import { computeClaudeProjectFilePath } from "../service/claude-code/computeClaudeProjectFilePath";
import { getDirectoryListing } from "../service/directory-browser/getDirectoryListing";
import { adaptInternalEventToSSE } from "../service/events/adaptInternalEventToSSE";
import { EventBus } from "../service/events/EventBus";
import type { InternalEventDeclaration } from "../service/events/InternalEventDeclaration";
import { TypeSafeSSE } from "../service/events/typeSafeSSE";
import { getFileCompletion } from "../service/file-completion/getFileCompletion";
import { getBranches } from "../service/git/getBranches";
import { getCommits } from "../service/git/getCommits";
import { getDiff } from "../service/git/getDiff";
import { getMcpList } from "../service/mcp/getMcpList";
import { claudeCommandsDirPath } from "../service/paths";
import { encodeProjectId } from "../service/project/id";
import type { ProjectMetaService } from "../service/project/ProjectMetaService";
import { ProjectRepository } from "../service/project/ProjectRepository";
import type { SessionMetaService } from "../service/session/SessionMetaService";
import { SessionRepository } from "../service/session/SessionRepository";
import type { VirtualConversationDatabase } from "../service/session/VirtualConversationDatabase";
import type { HonoAppType } from "./app";
import { InitializeService } from "./initialize";
import { configMiddleware } from "./middleware/config.middleware";

View File

@@ -1,6 +1,6 @@
import { homedir } from "node:os";
import { resolve } from "node:path";
import { env } from "../lib/env";
import { env } from "../env";
const GLOBAL_CLAUDE_DIR = env.get("GLOBAL_CLAUDE_DIR");

View File

@@ -2,7 +2,7 @@ import { resolve } from "node:path";
import { FileSystem } from "@effect/platform";
import { Context, Effect, Layer } from "effect";
import { z } from "zod";
import { claudeCodeViewerCacheDirPath } from "../../../service/paths";
import { claudeCodeViewerCacheDirPath } from "../../config/paths";
const saveSchema = z.array(z.tuple([z.string(), z.unknown()]));

View File

@@ -2,7 +2,7 @@ import { FileSystem } from "@effect/platform";
import { Effect, Layer, Ref } from "effect";
import { z } from "zod";
import { FileCacheStorage, makeFileCacheStorageLayer } from "./index";
import { PersistentService } from "./PersistantService";
import { PersistentService } from "./PersistentService";
// Schema for testing
const UserSchema = z.object({

View File

@@ -1,7 +1,7 @@
import type { FileSystem } from "@effect/platform";
import { Context, Effect, Layer, Ref, Runtime } from "effect";
import type { z } from "zod";
import { PersistentService } from "./PersistantService";
import { PersistentService } from "./PersistentService";
export interface FileCacheStorageService<T> {
readonly get: (key: string) => Effect.Effect<T | undefined>;

View File

@@ -1,95 +0,0 @@
import type {
SDKMessage,
SDKSystemMessage,
SDKUserMessage,
} from "@anthropic-ai/claude-code";
export type OnMessage = (message: SDKMessage) => void | Promise<void>;
export type MessageGenerator = () => AsyncGenerator<
SDKUserMessage,
void,
unknown
>;
const createPromise = <T>() => {
let promiseResolve: ((value: T) => void) | undefined;
let promiseReject: ((reason?: unknown) => void) | undefined;
const promise = new Promise<T>((resolve, reject) => {
promiseResolve = resolve;
promiseReject = reject;
});
if (!promiseResolve || !promiseReject) {
throw new Error("Illegal state: Promise not created");
}
return {
promise,
resolve: promiseResolve,
reject: promiseReject,
} as const;
};
export type InitMessageContext = {
initMessage: SDKSystemMessage;
};
export const createMessageGenerator = (
firstMessage: string,
): {
generateMessages: MessageGenerator;
setNextMessage: (message: string) => void;
setInitMessagePromise: () => void;
resolveInitMessage: (context: InitMessageContext) => void;
awaitInitMessage: (ctx: InitMessageContext) => Promise<void>;
} => {
let sendMessagePromise = createPromise<string>();
let receivedInitMessagePromise = createPromise<InitMessageContext>();
const createMessage = (message: string): SDKUserMessage => {
return {
type: "user",
message: {
role: "user",
content: message,
},
} as SDKUserMessage;
};
async function* generateMessages(): ReturnType<MessageGenerator> {
yield createMessage(firstMessage);
while (true) {
const message = await sendMessagePromise.promise;
sendMessagePromise = createPromise<string>();
yield createMessage(message);
}
}
const setNextMessage = (message: string) => {
sendMessagePromise.resolve(message);
};
const setInitMessagePromise = () => {
receivedInitMessagePromise = createPromise<InitMessageContext>();
};
const resolveInitMessage = (context: InitMessageContext) => {
receivedInitMessagePromise.resolve(context);
};
const awaitInitMessage = async () => {
await receivedInitMessagePromise.promise;
};
return {
generateMessages,
setNextMessage,
setInitMessagePromise,
resolveInitMessage,
awaitInitMessage,
};
};

View File

@@ -1,32 +0,0 @@
// Git service utilities for claude-code-viewer
// Provides comprehensive Git operations including branch management, diff generation, and status checking
export * from "./getBranches";
// Re-export main functions for convenience
export { branchExists, getBranches, getCurrentBranch } from "./getBranches";
export * from "./getCommits";
export { getCommits } from "./getCommits";
export * from "./getDiff";
export { compareBranches, getDiff } from "./getDiff";
export * from "./getStatus";
export {
getStatus,
getUncommittedChanges,
isWorkingDirectoryClean,
} from "./getStatus";
// Types re-export for convenience
export type {
GitBranch,
GitCommit,
GitComparisonResult,
GitDiff,
GitDiffFile,
GitDiffHunk,
GitDiffLine,
GitError,
GitResult,
GitStatus,
} from "./types";
export * from "./types";
export * from "./utils";
export { executeGitCommand, isGitRepository } from "./utils";

View File

@@ -1,13 +0,0 @@
import { z } from "zod";
import { parsedCommandSchema } from "./parseCommandXml";
export const projectMetaSchema = z.object({
projectName: z.string().nullable(),
projectPath: z.string().nullable(),
sessionCount: z.number(),
});
export const sessionMetaSchema = z.object({
messageCount: z.number(),
firstCommand: parsedCommandSchema.nullable(),
});