mirror of
https://github.com/aljazceru/claude-code-viewer.git
synced 2025-12-19 06:14:19 +01:00
refactor: move directories
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
import { resolve } from "node:path";
|
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
|
// biome-ignore lint/complexity/useLiteralKeys: env var
|
||||||
export const globalClaudeDirectoryPath = process.env["GLOBAL_CLAUDE_DIR"]
|
export const globalClaudeDirectoryPath = process.env["GLOBAL_CLAUDE_DIR"]
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { NodeContext } from "@effect/platform-node";
|
import { NodeContext } from "@effect/platform-node";
|
||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import { handle } from "hono/vercel";
|
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 { honoApp } from "../../../server/hono/app";
|
||||||
import { InitializeService } from "../../../server/hono/initialize";
|
import { InitializeService } from "../../../server/hono/initialize";
|
||||||
import { routes } from "../../../server/hono/route";
|
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);
|
const program = routes(honoApp);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { honoClient } from "../../lib/api/client";
|
import { honoClient } from "../../lib/api/client";
|
||||||
import { configQuery } from "../../lib/api/queries";
|
import { configQuery } from "../../lib/api/queries";
|
||||||
import type { Config } from "../../server/config/config";
|
import type { Config } from "../../server/lib/config/config";
|
||||||
|
|
||||||
export const useConfig = () => {
|
export const useConfig = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|||||||
@@ -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) => {
|
export const firstCommandToTitle = (firstCommand: ParsedCommand) => {
|
||||||
switch (firstCommand.kind) {
|
switch (firstCommand.kind) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
} from "@/components/ui/collapsible";
|
} from "@/components/ui/collapsible";
|
||||||
import type { Conversation } from "@/lib/conversation-schema";
|
import type { Conversation } from "@/lib/conversation-schema";
|
||||||
import type { ToolResultContent } from "@/lib/conversation-schema/content/ToolResultContentSchema";
|
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 { useSidechain } from "../../hooks/useSidechain";
|
||||||
import { ConversationItem } from "./ConversationItem";
|
import { ConversationItem } from "./ConversationItem";
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { FC } from "react";
|
|||||||
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
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";
|
import { MarkdownContent } from "../../../../../../components/MarkdownContent";
|
||||||
|
|
||||||
export const UserTextContent: FC<{ text: string; id?: string }> = ({
|
export const UserTextContent: FC<{ text: string; id?: string }> = ({
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type { FC } from "react";
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { cn } from "@/lib/utils";
|
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 { NewChatModal } from "../../../../components/newChat/NewChatModal";
|
||||||
import { firstCommandToTitle } from "../../../../services/firstCommandToTitle";
|
import { firstCommandToTitle } from "../../../../services/firstCommandToTitle";
|
||||||
import { sessionProcessesAtom } from "../../store/sessionProcessesAtom";
|
import { sessionProcessesAtom } from "../../store/sessionProcessesAtom";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { DirectoryListingResult } from "../../server/service/directory-browser/getDirectoryListing";
|
import type { DirectoryListingResult } from "../../server/core/directory-browser/functions/getDirectoryListing";
|
||||||
import type { FileCompletionResult } from "../../server/service/file-completion/getFileCompletion";
|
import type { FileCompletionResult } from "../../server/core/file-completion/functions/getFileCompletion";
|
||||||
import { honoClient } from "./client";
|
import { honoClient } from "./client";
|
||||||
|
|
||||||
export const projectListQuery = {
|
export const projectListQuery = {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ describe("computeClaudeProjectFilePath", () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
vi.resetModules();
|
vi.resetModules();
|
||||||
vi.doMock("../../lib/env", () => ({
|
vi.doMock("../../../lib/env", () => ({
|
||||||
env: {
|
env: {
|
||||||
get: (key: string) => {
|
get: (key: string) => {
|
||||||
if (key === "GLOBAL_CLAUDE_DIR") {
|
if (key === "GLOBAL_CLAUDE_DIR") {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { claudeProjectsDirPath } from "../paths";
|
import { claudeProjectsDirPath } from "../../../lib/config/paths";
|
||||||
|
|
||||||
export function computeClaudeProjectFilePath(projectPath: string): string {
|
export function computeClaudeProjectFilePath(projectPath: string): string {
|
||||||
return path.join(
|
return path.join(
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { SDKMessage, SDKUserMessage } from "@anthropic-ai/claude-code";
|
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>;
|
export type OnMessage = (message: SDKMessage) => void | Promise<void>;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
import type { ErrorJsonl } from "../../types";
|
||||||
import { parseJsonl } from "./parseJsonl";
|
import { parseJsonl } from "./parseJsonl";
|
||||||
import type { ErrorJsonl } from "./types";
|
|
||||||
|
|
||||||
describe("parseJsonl", () => {
|
describe("parseJsonl", () => {
|
||||||
describe("正常系: 有効なJSONLをパースできる", () => {
|
describe("正常系: 有効なJSONLをパースできる", () => {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ConversationSchema } from "../../lib/conversation-schema";
|
import { ConversationSchema } from "../../../../lib/conversation-schema";
|
||||||
import type { ErrorJsonl } from "./types";
|
import type { ErrorJsonl } from "../../types";
|
||||||
|
|
||||||
export const parseJsonl = (content: string) => {
|
export const parseJsonl = (content: string) => {
|
||||||
const lines = content
|
const lines = content
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import type { UserEntry } from "../../../../lib/conversation-schema/entry/UserEntrySchema";
|
import type { UserEntry } from "../../../../lib/conversation-schema/entry/UserEntrySchema";
|
||||||
import * as ClaudeCode from "../ClaudeCode";
|
import type { InitMessageContext } from "../types";
|
||||||
import type { InitMessageContext } from "../createMessageGenerator";
|
import * as ClaudeCode from "./ClaudeCode";
|
||||||
import type * as CCTask from "./ClaudeCodeTask";
|
import type * as CCTask from "./ClaudeCodeTask";
|
||||||
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";
|
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { query as originalQuery } from "@anthropic-ai/claude-code";
|
import { query as originalQuery } from "@anthropic-ai/claude-code";
|
||||||
import { Command, Path } from "@effect/platform";
|
import { Command, Path } from "@effect/platform";
|
||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import { env } from "../../lib/env";
|
import { env } from "../../../lib/env";
|
||||||
import * as ClaudeCodeVersion from "./models/ClaudeCodeVersion";
|
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";
|
||||||
|
|
||||||
type CCQuery = typeof originalQuery;
|
type CCQuery = typeof originalQuery;
|
||||||
type CCQueryPrompt = Parameters<CCQuery>[0]["prompt"];
|
type CCQueryPrompt = Parameters<CCQuery>[0]["prompt"];
|
||||||
@@ -3,18 +3,18 @@ import type { FileSystem, Path } from "@effect/platform";
|
|||||||
import type { CommandExecutor } from "@effect/platform/CommandExecutor";
|
import type { CommandExecutor } from "@effect/platform/CommandExecutor";
|
||||||
import { Context, Effect, Layer, Runtime } from "effect";
|
import { Context, Effect, Layer, Runtime } from "effect";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import { controllablePromise } from "../../../lib/controllablePromise";
|
import { controllablePromise } from "../../../../lib/controllablePromise";
|
||||||
import type { Config } from "../../config/config";
|
import type { Config } from "../../../lib/config/config";
|
||||||
import type { InferEffect } from "../../lib/effect/types";
|
import type { InferEffect } from "../../../lib/effect/types";
|
||||||
import { EventBus } from "../events/EventBus";
|
import { EventBus } from "../../events/services/EventBus";
|
||||||
import type { SessionMetaService } from "../session/SessionMetaService";
|
import { SessionRepository } from "../../session/infrastructure/SessionRepository";
|
||||||
import { SessionRepository } from "../session/SessionRepository";
|
import { VirtualConversationDatabase } from "../../session/infrastructure/VirtualConversationDatabase";
|
||||||
import { VirtualConversationDatabase } from "../session/VirtualConversationDatabase";
|
import type { SessionMetaService } from "../../session/services/SessionMetaService";
|
||||||
import * as ClaudeCode from "./ClaudeCode";
|
import { createMessageGenerator } from "../functions/createMessageGenerator";
|
||||||
|
import * as CCSessionProcess from "../models/CCSessionProcess";
|
||||||
|
import * as ClaudeCode from "../models/ClaudeCode";
|
||||||
import { ClaudeCodePermissionService } from "./ClaudeCodePermissionService";
|
import { ClaudeCodePermissionService } from "./ClaudeCodePermissionService";
|
||||||
import { ClaudeCodeSessionProcessService } from "./ClaudeCodeSessionProcessService";
|
import { ClaudeCodeSessionProcessService } from "./ClaudeCodeSessionProcessService";
|
||||||
import { createMessageGenerator } from "./MessageGenerator";
|
|
||||||
import * as CCSessionProcess from "./models/CCSessionProcess";
|
|
||||||
|
|
||||||
export type MessageGenerator = () => AsyncGenerator<
|
export type MessageGenerator = () => AsyncGenerator<
|
||||||
SDKUserMessage,
|
SDKUserMessage,
|
||||||
@@ -4,11 +4,11 @@ import { ulid } from "ulid";
|
|||||||
import type {
|
import type {
|
||||||
PermissionRequest,
|
PermissionRequest,
|
||||||
PermissionResponse,
|
PermissionResponse,
|
||||||
} from "../../../types/permissions";
|
} from "../../../../types/permissions";
|
||||||
import type { Config } from "../../config/config";
|
import type { Config } from "../../../lib/config/config";
|
||||||
import type { InferEffect } from "../../lib/effect/types";
|
import type { InferEffect } from "../../../lib/effect/types";
|
||||||
import { EventBus } from "../events/EventBus";
|
import { EventBus } from "../../events/services/EventBus";
|
||||||
import * as ClaudeCode from "./ClaudeCode";
|
import * as ClaudeCode from "../models/ClaudeCode";
|
||||||
|
|
||||||
const LayerImpl = Effect.gen(function* () {
|
const LayerImpl = Effect.gen(function* () {
|
||||||
const pendingPermissionRequestsRef = yield* Ref.make<
|
const pendingPermissionRequestsRef = yield* Ref.make<
|
||||||
@@ -4,12 +4,12 @@ import type {
|
|||||||
} from "@anthropic-ai/claude-code";
|
} from "@anthropic-ai/claude-code";
|
||||||
import { Effect, Layer } from "effect";
|
import { Effect, Layer } from "effect";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { EventBus } from "../events/EventBus";
|
import { EventBus } from "../../events/services/EventBus";
|
||||||
import type { InternalEventDeclaration } from "../events/InternalEventDeclaration";
|
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 { 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
|
// Helper function to create mock session process definition
|
||||||
const createMockSessionProcessDef = (
|
const createMockSessionProcessDef = (
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { SDKResultMessage } from "@anthropic-ai/claude-code";
|
import type { SDKResultMessage } from "@anthropic-ai/claude-code";
|
||||||
import { Context, Data, Effect, Layer, Ref } from "effect";
|
import { Context, Data, Effect, Layer, Ref } from "effect";
|
||||||
import type { InferEffect } from "../../lib/effect/types";
|
import type { InferEffect } from "../../../lib/effect/types";
|
||||||
import { EventBus } from "../events/EventBus";
|
import { EventBus } from "../../events/services/EventBus";
|
||||||
import type { InitMessageContext } from "./createMessageGenerator";
|
import * as CCSessionProcess from "../models/CCSessionProcess";
|
||||||
import * as CCSessionProcess from "./models/CCSessionProcess";
|
import type * as CCTask from "../models/ClaudeCodeTask";
|
||||||
import type * as CCTask from "./models/ClaudeCodeTask";
|
import type { InitMessageContext } from "../types";
|
||||||
|
|
||||||
class SessionProcessNotFoundError extends Data.TaggedError(
|
class SessionProcessNotFoundError extends Data.TaggedError(
|
||||||
"SessionProcessNotFoundError",
|
"SessionProcessNotFoundError",
|
||||||
5
src/server/core/claude-code/types.ts
Normal file
5
src/server/core/claude-code/types.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import type { SDKSystemMessage } from "@anthropic-ai/claude-code";
|
||||||
|
|
||||||
|
export type InitMessageContext = {
|
||||||
|
initMessage: SDKSystemMessage;
|
||||||
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import type { SSEStreamingApi } from "hono/streaming";
|
import type { SSEStreamingApi } from "hono/streaming";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import type { PermissionRequest } from "../../../types/permissions";
|
import type { PermissionRequest } from "../../../../types/permissions";
|
||||||
import { TypeSafeSSE } from "./typeSafeSSE";
|
import { TypeSafeSSE } from "./typeSafeSSE";
|
||||||
|
|
||||||
describe("typeSafeSSE", () => {
|
describe("typeSafeSSE", () => {
|
||||||
@@ -153,7 +153,7 @@ describe("typeSafeSSE", () => {
|
|||||||
const program = Effect.gen(function* () {
|
const program = Effect.gen(function* () {
|
||||||
const typeSafeSSE = yield* TypeSafeSSE;
|
const typeSafeSSE = yield* TypeSafeSSE;
|
||||||
|
|
||||||
yield* typeSafeSSE.writeSSE("permission_requested", {
|
yield* typeSafeSSE.writeSSE("permissionRequested", {
|
||||||
permissionRequest: mockPermissionRequest,
|
permissionRequest: mockPermissionRequest,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -170,10 +170,10 @@ describe("typeSafeSSE", () => {
|
|||||||
if (!item) {
|
if (!item) {
|
||||||
throw new Error("item is undefined");
|
throw new Error("item is undefined");
|
||||||
}
|
}
|
||||||
expect(item.event).toBe("permission_requested");
|
expect(item.event).toBe("permissionRequested");
|
||||||
|
|
||||||
const data = JSON.parse(item.data);
|
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.permissionRequest.id).toBe("permission-1");
|
||||||
expect(data.timestamp).toBeDefined();
|
expect(data.timestamp).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Context, Effect, Layer } from "effect";
|
import { Context, Effect, Layer } from "effect";
|
||||||
import type { SSEStreamingApi } from "hono/streaming";
|
import type { SSEStreamingApi } from "hono/streaming";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import type { SSEEventDeclaration } from "../../../types/sse";
|
import type { SSEEventDeclaration } from "../../../../types/sse";
|
||||||
|
|
||||||
interface TypeSafeSSEService {
|
interface TypeSafeSSEService {
|
||||||
readonly writeSSE: <EventName extends keyof SSEEventDeclaration>(
|
readonly writeSSE: <EventName extends keyof SSEEventDeclaration>(
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import type { PermissionRequest } from "../../../types/permissions";
|
import type { PermissionRequest } from "../../../../types/permissions";
|
||||||
import type { PublicSessionProcess } from "../../../types/session-process";
|
import type { PublicSessionProcess } from "../../../../types/session-process";
|
||||||
import type { CCSessionProcessState } from "../claude-code/models/CCSessionProcess";
|
import type { CCSessionProcessState } from "../../claude-code/models/CCSessionProcess";
|
||||||
|
import type { InternalEventDeclaration } from "../types/InternalEventDeclaration";
|
||||||
import { EventBus } from "./EventBus";
|
import { EventBus } from "./EventBus";
|
||||||
import type { InternalEventDeclaration } from "./InternalEventDeclaration";
|
|
||||||
|
|
||||||
describe("EventBus", () => {
|
describe("EventBus", () => {
|
||||||
describe("basic event processing", () => {
|
describe("basic event processing", () => {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Context, Effect, Layer } from "effect";
|
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>;
|
type Listener<T> = (data: T) => void | Promise<void>;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
import type { InternalEventDeclaration } from "../types/InternalEventDeclaration";
|
||||||
import { EventBus } from "./EventBus";
|
import { EventBus } from "./EventBus";
|
||||||
import { FileWatcherService } from "./fileWatcher";
|
import { FileWatcherService } from "./fileWatcher";
|
||||||
import type { InternalEventDeclaration } from "./InternalEventDeclaration";
|
|
||||||
|
|
||||||
describe("FileWatcherService", () => {
|
describe("FileWatcherService", () => {
|
||||||
describe("startWatching", () => {
|
describe("startWatching", () => {
|
||||||
@@ -2,8 +2,8 @@ import { type FSWatcher, watch } from "node:fs";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { Context, Effect, Layer, Ref } from "effect";
|
import { Context, Effect, Layer, Ref } from "effect";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { claudeProjectsDirPath } from "../paths";
|
import { claudeProjectsDirPath } from "../../../lib/config/paths";
|
||||||
import { encodeProjectIdFromSessionFilePath } from "../project/id";
|
import { encodeProjectIdFromSessionFilePath } from "../../project/functions/id";
|
||||||
import { EventBus } from "./EventBus";
|
import { EventBus } from "./EventBus";
|
||||||
|
|
||||||
const fileRegExp = /(?<projectId>.*?)\/(?<sessionId>.*?)\.jsonl/;
|
const fileRegExp = /(?<projectId>.*?)\/(?<sessionId>.*?)\.jsonl/;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { PermissionRequest } from "../../../types/permissions";
|
import type { PermissionRequest } from "../../../../types/permissions";
|
||||||
import type { PublicSessionProcess } from "../../../types/session-process";
|
import type { PublicSessionProcess } from "../../../../types/session-process";
|
||||||
import type * as CCSessionProcess from "../claude-code/models/CCSessionProcess";
|
import type * as CCSessionProcess from "../../claude-code/models/CCSessionProcess";
|
||||||
|
|
||||||
export type InternalEventDeclaration = {
|
export type InternalEventDeclaration = {
|
||||||
// biome-ignore lint/complexity/noBannedTypes: correct type
|
// biome-ignore lint/complexity/noBannedTypes: correct type
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { GitBranch, GitResult } from "./types";
|
import { executeGitCommand, parseLines } from "../functions/utils";
|
||||||
import { executeGitCommand, parseLines } from "./utils";
|
import type { GitBranch, GitResult } from "../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all branches (local and remote) in the repository
|
* Get all branches (local and remote) in the repository
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { GitCommit, GitResult } from "./types";
|
import { executeGitCommand, parseLines } from "../functions/utils";
|
||||||
import { executeGitCommand, parseLines } from "./utils";
|
import type { GitCommit, GitResult } from "../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the last 20 commits from the current branch
|
* Get the last 20 commits from the current branch
|
||||||
@@ -4,6 +4,11 @@ import parseGitDiff, {
|
|||||||
type AnyChunk,
|
type AnyChunk,
|
||||||
type AnyFileChange,
|
type AnyFileChange,
|
||||||
} from "parse-git-diff";
|
} from "parse-git-diff";
|
||||||
|
import {
|
||||||
|
executeGitCommand,
|
||||||
|
parseLines,
|
||||||
|
stripAnsiColors,
|
||||||
|
} from "../functions/utils";
|
||||||
import type {
|
import type {
|
||||||
GitComparisonResult,
|
GitComparisonResult,
|
||||||
GitDiff,
|
GitDiff,
|
||||||
@@ -11,8 +16,7 @@ import type {
|
|||||||
GitDiffHunk,
|
GitDiffHunk,
|
||||||
GitDiffLine,
|
GitDiffLine,
|
||||||
GitResult,
|
GitResult,
|
||||||
} from "./types";
|
} from "../types";
|
||||||
import { executeGitCommand, parseLines, stripAnsiColors } from "./utils";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert parse-git-diff file change to GitDiffFile
|
* Convert parse-git-diff file change to GitDiffFile
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { GitDiffFile, GitResult, GitStatus } from "./types";
|
|
||||||
import {
|
import {
|
||||||
executeGitCommand,
|
executeGitCommand,
|
||||||
getFileStatus,
|
getFileStatus,
|
||||||
parseLines,
|
parseLines,
|
||||||
parseStatusLine,
|
parseStatusLine,
|
||||||
} from "./utils";
|
} from "../functions/utils";
|
||||||
|
import type { GitDiffFile, GitResult, GitStatus } from "../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get git status information including staged, unstaged, and untracked files
|
* Get git status information including staged, unstaged, and untracked files
|
||||||
@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
|
|||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import { promisify } from "node:util";
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
import type { GitError, GitResult } from "./types";
|
import type { GitError, GitResult } from "../types";
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { execSync } from "node:child_process";
|
import { execSync } from "node:child_process";
|
||||||
import { decodeProjectId } from "../project/id";
|
import { decodeProjectId } from "../../project/functions/id";
|
||||||
|
|
||||||
export interface McpServer {
|
export interface McpServer {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { FileSystem, Path } from "@effect/platform";
|
import { FileSystem, Path } from "@effect/platform";
|
||||||
import { SystemError } from "@effect/platform/Error";
|
import { SystemError } from "@effect/platform/Error";
|
||||||
import { Effect, Layer, Option } from "effect";
|
import { Effect, Layer, Option } from "effect";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import type { ProjectMeta } from "../types";
|
import type { ProjectMeta } from "../../types";
|
||||||
import { ProjectMetaService } from "./ProjectMetaService";
|
import { ProjectMetaService } from "../services/ProjectMetaService";
|
||||||
import { ProjectRepository } from "./ProjectRepository";
|
import { ProjectRepository } from "./ProjectRepository";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import { FileSystem } from "@effect/platform";
|
import { FileSystem } from "@effect/platform";
|
||||||
import { Context, Effect, Layer, Option } from "effect";
|
import { Context, Effect, Layer, Option } from "effect";
|
||||||
import type { InferEffect } from "../../lib/effect/types";
|
import { claudeProjectsDirPath } from "../../../lib/config/paths";
|
||||||
import { claudeProjectsDirPath } from "../paths";
|
import type { InferEffect } from "../../../lib/effect/types";
|
||||||
import type { Project } from "../types";
|
import type { Project } from "../../types";
|
||||||
import { decodeProjectId, encodeProjectId } from "./id";
|
import { decodeProjectId, encodeProjectId } from "../functions/id";
|
||||||
import { ProjectMetaService } from "./ProjectMetaService";
|
import { ProjectMetaService } from "../services/ProjectMetaService";
|
||||||
|
|
||||||
const LayerImpl = Effect.gen(function* () {
|
const LayerImpl = Effect.gen(function* () {
|
||||||
const fs = yield* FileSystem.FileSystem;
|
const fs = yield* FileSystem.FileSystem;
|
||||||
7
src/server/core/project/schema.ts
Normal file
7
src/server/core/project/schema.ts
Normal 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(),
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FileSystem, Path } from "@effect/platform";
|
import { FileSystem, Path } from "@effect/platform";
|
||||||
import { Effect, Layer, Option } from "effect";
|
import { Effect, Layer, Option } from "effect";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import { ProjectMetaService } from "./ProjectMetaService";
|
import { ProjectMetaService } from "../services/ProjectMetaService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to create a FileSystem mock layer
|
* Helper function to create a FileSystem mock layer
|
||||||
@@ -5,11 +5,11 @@ import { z } from "zod";
|
|||||||
import {
|
import {
|
||||||
FileCacheStorage,
|
FileCacheStorage,
|
||||||
makeFileCacheStorageLayer,
|
makeFileCacheStorageLayer,
|
||||||
} from "../../lib/storage/FileCacheStorage";
|
} from "../../../lib/storage/FileCacheStorage";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import { parseJsonl } from "../parseJsonl";
|
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
|
||||||
import type { ProjectMeta } from "../types";
|
import type { ProjectMeta } from "../../types";
|
||||||
import { decodeProjectId } from "./id";
|
import { decodeProjectId } from "../functions/id";
|
||||||
|
|
||||||
const ProjectPathSchema = z.string().nullable();
|
const ProjectPathSchema = z.string().nullable();
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basename, extname, resolve } from "node:path";
|
import { basename, extname, resolve } from "node:path";
|
||||||
import { decodeProjectId } from "../project/id";
|
import { decodeProjectId } from "../../project/functions/id";
|
||||||
|
|
||||||
export const encodeSessionId = (jsonlFilePath: string) => {
|
export const encodeSessionId = (jsonlFilePath: string) => {
|
||||||
return basename(jsonlFilePath, extname(jsonlFilePath));
|
return basename(jsonlFilePath, extname(jsonlFilePath));
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { FileSystem, Path } from "@effect/platform";
|
import { FileSystem, Path } from "@effect/platform";
|
||||||
import { SystemError } from "@effect/platform/Error";
|
import { SystemError } from "@effect/platform/Error";
|
||||||
import { Effect, Layer, Option } from "effect";
|
import { Effect, Layer, Option } from "effect";
|
||||||
import type { Conversation } from "../../../lib/conversation-schema";
|
import type { Conversation } from "../../../../lib/conversation-schema";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import { decodeProjectId } from "../project/id";
|
import { decodeProjectId } from "../../project/functions/id";
|
||||||
import type { ErrorJsonl, SessionDetail, SessionMeta } from "../types";
|
import type { ErrorJsonl, SessionDetail, SessionMeta } from "../../types";
|
||||||
import { SessionMetaService } from "./SessionMetaService";
|
import { SessionRepository } from "../infrastructure/SessionRepository";
|
||||||
import { SessionRepository } from "./SessionRepository";
|
import { VirtualConversationDatabase } from "../infrastructure/VirtualConversationDatabase";
|
||||||
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
|
import { SessionMetaService } from "../services/SessionMetaService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to create a FileSystem mock layer
|
* Helper function to create a FileSystem mock layer
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import { FileSystem } from "@effect/platform";
|
import { FileSystem } from "@effect/platform";
|
||||||
import { Context, Effect, Layer, Option } from "effect";
|
import { Context, Effect, Layer, Option } from "effect";
|
||||||
import { parseCommandXml } from "../parseCommandXml";
|
import { parseCommandXml } from "../../claude-code/functions/parseCommandXml";
|
||||||
import { parseJsonl } from "../parseJsonl";
|
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
|
||||||
import { decodeProjectId } from "../project/id";
|
import { decodeProjectId } from "../../project/functions/id";
|
||||||
import type { Session, SessionDetail } from "../types";
|
import type { Session, SessionDetail } from "../../types";
|
||||||
import { decodeSessionId, encodeSessionId } from "./id";
|
import { decodeSessionId, encodeSessionId } from "../functions/id";
|
||||||
import { SessionMetaService } from "./SessionMetaService";
|
import { VirtualConversationDatabase } from "../infrastructure/VirtualConversationDatabase";
|
||||||
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
|
import { SessionMetaService } from "../services/SessionMetaService";
|
||||||
|
|
||||||
const getSession = (projectId: string, sessionId: string) =>
|
const getSession = (projectId: string, sessionId: string) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Effect } from "effect";
|
import { Effect } from "effect";
|
||||||
import type { Conversation } from "../../../lib/conversation-schema";
|
import type { Conversation } from "../../../../lib/conversation-schema";
|
||||||
import type { ErrorJsonl } from "../types";
|
import type { ErrorJsonl } from "../../types";
|
||||||
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
|
import { VirtualConversationDatabase } from "./VirtualConversationDatabase";
|
||||||
|
|
||||||
describe("VirtualConversationDatabase", () => {
|
describe("VirtualConversationDatabase", () => {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Context, Effect, Layer, Ref } from "effect";
|
import { Context, Effect, Layer, Ref } from "effect";
|
||||||
import type { Conversation } from "../../../lib/conversation-schema";
|
import type { Conversation } from "../../../../lib/conversation-schema";
|
||||||
import type { ErrorJsonl } from "../types";
|
import type { ErrorJsonl } from "../../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For interactively experience, handle sessions not already persisted to the filesystem.
|
* For interactively experience, handle sessions not already persisted to the filesystem.
|
||||||
7
src/server/core/session/schema.ts
Normal file
7
src/server/core/session/schema.ts
Normal 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(),
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { FileSystem, Path } from "@effect/platform";
|
import { FileSystem, Path } from "@effect/platform";
|
||||||
import { Effect, Layer } from "effect";
|
import { Effect, Layer } from "effect";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import { SessionMetaService } from "./SessionMetaService";
|
import { SessionMetaService } from "../services/SessionMetaService";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to create a FileSystem mock layer
|
* Helper function to create a FileSystem mock layer
|
||||||
@@ -3,16 +3,16 @@ import { Context, Effect, Layer, Ref } from "effect";
|
|||||||
import {
|
import {
|
||||||
FileCacheStorage,
|
FileCacheStorage,
|
||||||
makeFileCacheStorageLayer,
|
makeFileCacheStorageLayer,
|
||||||
} from "../../lib/storage/FileCacheStorage";
|
} from "../../../lib/storage/FileCacheStorage";
|
||||||
import { PersistentService } from "../../lib/storage/FileCacheStorage/PersistantService";
|
import { PersistentService } from "../../../lib/storage/FileCacheStorage/PersistentService";
|
||||||
import {
|
import {
|
||||||
type ParsedCommand,
|
type ParsedCommand,
|
||||||
parseCommandXml,
|
parseCommandXml,
|
||||||
parsedCommandSchema,
|
parsedCommandSchema,
|
||||||
} from "../parseCommandXml";
|
} from "../../claude-code/functions/parseCommandXml";
|
||||||
import { parseJsonl } from "../parseJsonl";
|
import { parseJsonl } from "../../claude-code/functions/parseJsonl";
|
||||||
import type { SessionMeta } from "../types";
|
import type { SessionMeta } from "../../types";
|
||||||
import { decodeSessionId } from "./id";
|
import { decodeSessionId } from "../functions/id";
|
||||||
|
|
||||||
const ignoreCommands = [
|
const ignoreCommands = [
|
||||||
"/clear",
|
"/clear",
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
import type { Conversation } from "../../lib/conversation-schema";
|
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 = {
|
export type Project = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import type { Config } from "../config/config";
|
import type { Config } from "../lib/config/config";
|
||||||
|
|
||||||
export type HonoContext = {
|
export type HonoContext = {
|
||||||
Variables: {
|
Variables: {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Effect, Layer, Ref } from "effect";
|
import { Effect, Layer, Ref } from "effect";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { EventBus } from "../service/events/EventBus";
|
import { EventBus } from "../core/events/services/EventBus";
|
||||||
import { FileWatcherService } from "../service/events/fileWatcher";
|
import { FileWatcherService } from "../core/events/services/fileWatcher";
|
||||||
import type { InternalEventDeclaration } from "../service/events/InternalEventDeclaration";
|
import type { InternalEventDeclaration } from "../core/events/types/InternalEventDeclaration";
|
||||||
import { ProjectMetaService } from "../service/project/ProjectMetaService";
|
import { ProjectRepository } from "../core/project/infrastructure/ProjectRepository";
|
||||||
import { ProjectRepository } from "../service/project/ProjectRepository";
|
import { ProjectMetaService } from "../core/project/services/ProjectMetaService";
|
||||||
import { SessionMetaService } from "../service/session/SessionMetaService";
|
import { SessionRepository } from "../core/session/infrastructure/SessionRepository";
|
||||||
import { SessionRepository } from "../service/session/SessionRepository";
|
import { VirtualConversationDatabase } from "../core/session/infrastructure/VirtualConversationDatabase";
|
||||||
import { VirtualConversationDatabase } from "../service/session/VirtualConversationDatabase";
|
import { SessionMetaService } from "../core/session/services/SessionMetaService";
|
||||||
import { InitializeService } from "./initialize";
|
import { InitializeService } from "./initialize";
|
||||||
|
|
||||||
describe("InitializeService", () => {
|
describe("InitializeService", () => {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Context, Effect, Layer, Ref, Schedule } from "effect";
|
import { Context, Effect, Layer, Ref, Schedule } from "effect";
|
||||||
import { EventBus } from "../service/events/EventBus";
|
import { EventBus } from "../core/events/services/EventBus";
|
||||||
import { FileWatcherService } from "../service/events/fileWatcher";
|
import { FileWatcherService } from "../core/events/services/fileWatcher";
|
||||||
import type { InternalEventDeclaration } from "../service/events/InternalEventDeclaration";
|
import type { InternalEventDeclaration } from "../core/events/types/InternalEventDeclaration";
|
||||||
import { ProjectMetaService } from "../service/project/ProjectMetaService";
|
import { ProjectRepository } from "../core/project/infrastructure/ProjectRepository";
|
||||||
import { ProjectRepository } from "../service/project/ProjectRepository";
|
import { ProjectMetaService } from "../core/project/services/ProjectMetaService";
|
||||||
import { SessionMetaService } from "../service/session/SessionMetaService";
|
import { SessionRepository } from "../core/session/infrastructure/SessionRepository";
|
||||||
import { SessionRepository } from "../service/session/SessionRepository";
|
import { VirtualConversationDatabase } from "../core/session/infrastructure/VirtualConversationDatabase";
|
||||||
import { VirtualConversationDatabase } from "../service/session/VirtualConversationDatabase";
|
import { SessionMetaService } from "../core/session/services/SessionMetaService";
|
||||||
|
|
||||||
interface InitializeServiceInterface {
|
interface InitializeServiceInterface {
|
||||||
readonly startInitialization: () => Effect.Effect<void>;
|
readonly startInitialization: () => Effect.Effect<void>;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { getCookie, setCookie } from "hono/cookie";
|
import { getCookie, setCookie } from "hono/cookie";
|
||||||
import { createMiddleware } from "hono/factory";
|
import { createMiddleware } from "hono/factory";
|
||||||
import { configSchema } from "../../config/config";
|
import { configSchema } from "../../lib/config/config";
|
||||||
import type { HonoContext } from "../app";
|
import type { HonoContext } from "../app";
|
||||||
|
|
||||||
export const configMiddleware = createMiddleware<HonoContext>(
|
export const configMiddleware = createMiddleware<HonoContext>(
|
||||||
|
|||||||
@@ -9,28 +9,28 @@ import { streamSSE } from "hono/streaming";
|
|||||||
import prexit from "prexit";
|
import prexit from "prexit";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import type { PublicSessionProcess } from "../../types/session-process";
|
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 { 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 type { HonoAppType } from "./app";
|
||||||
import { InitializeService } from "./initialize";
|
import { InitializeService } from "./initialize";
|
||||||
import { configMiddleware } from "./middleware/config.middleware";
|
import { configMiddleware } from "./middleware/config.middleware";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import { env } from "../lib/env";
|
import { env } from "../env";
|
||||||
|
|
||||||
const GLOBAL_CLAUDE_DIR = env.get("GLOBAL_CLAUDE_DIR");
|
const GLOBAL_CLAUDE_DIR = env.get("GLOBAL_CLAUDE_DIR");
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ import { resolve } from "node:path";
|
|||||||
import { FileSystem } from "@effect/platform";
|
import { FileSystem } from "@effect/platform";
|
||||||
import { Context, Effect, Layer } from "effect";
|
import { Context, Effect, Layer } from "effect";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { claudeCodeViewerCacheDirPath } from "../../../service/paths";
|
import { claudeCodeViewerCacheDirPath } from "../../config/paths";
|
||||||
|
|
||||||
const saveSchema = z.array(z.tuple([z.string(), z.unknown()]));
|
const saveSchema = z.array(z.tuple([z.string(), z.unknown()]));
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ import { FileSystem } from "@effect/platform";
|
|||||||
import { Effect, Layer, Ref } from "effect";
|
import { Effect, Layer, Ref } from "effect";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { FileCacheStorage, makeFileCacheStorageLayer } from "./index";
|
import { FileCacheStorage, makeFileCacheStorageLayer } from "./index";
|
||||||
import { PersistentService } from "./PersistantService";
|
import { PersistentService } from "./PersistentService";
|
||||||
|
|
||||||
// Schema for testing
|
// Schema for testing
|
||||||
const UserSchema = z.object({
|
const UserSchema = z.object({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { FileSystem } from "@effect/platform";
|
import type { FileSystem } from "@effect/platform";
|
||||||
import { Context, Effect, Layer, Ref, Runtime } from "effect";
|
import { Context, Effect, Layer, Ref, Runtime } from "effect";
|
||||||
import type { z } from "zod";
|
import type { z } from "zod";
|
||||||
import { PersistentService } from "./PersistantService";
|
import { PersistentService } from "./PersistentService";
|
||||||
|
|
||||||
export interface FileCacheStorageService<T> {
|
export interface FileCacheStorageService<T> {
|
||||||
readonly get: (key: string) => Effect.Effect<T | undefined>;
|
readonly get: (key: string) => Effect.Effect<T | undefined>;
|
||||||
|
|||||||
@@ -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,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -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";
|
|
||||||
@@ -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(),
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user