Merge pull request #24 from d-kimuson/prepare/0.4.0

prepare/0.4.0
This commit is contained in:
きむそん
2025-10-21 22:46:01 +09:00
committed by GitHub
59 changed files with 362 additions and 348 deletions

View File

@@ -8,7 +8,7 @@
- This document is in English for context efficiency
**NEVER**:
- Use `as` type casting (explain the problem to the user instead)
- Use `as` type casting in ANY context including test code (explain the problem to the user instead)
- Use raw `fetch` or bypass TanStack Query for API calls
- Run `pnpm dev` or `pnpm start` (dev servers)
- Use `node:fs`, `node:path`, etc. directly (use Effect-TS equivalents)

View File

@@ -71,7 +71,7 @@ The application reads Claude Code conversation logs from:
### System Requirements
- **Node.js**: Version 20.18.1 or later
- **Node.js**: Version 20.19.0 or later
- **Operating Systems**: macOS and Linux (Windows is not supported)
### Claude Code Compatibility
@@ -89,7 +89,7 @@ Claude Code Viewer reads several reserved environment variables. All values are
| Key | Description |
| --- | --- |
| CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH | Path to Claude Code installation |
| CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH | Path to Claude Code installation. If not set, uses system PATH installation, or falls back to bundled version from dependencies |
| PORT | Port number for Claude Code Viewer to run on |
### User Settings

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -42,8 +42,8 @@
"lingui:compile": "lingui compile --typescript"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.22",
"@anthropic-ai/claude-code": "^2.0.22",
"@anthropic-ai/claude-agent-sdk": "^0.1.23",
"@anthropic-ai/claude-code": "^2.0.24",
"@effect/platform": "^0.92.1",
"@effect/platform-node": "^0.98.4",
"@hono/zod-validator": "^0.7.4",
@@ -70,7 +70,6 @@
"next": "15.5.6",
"next-themes": "^0.4.6",
"parse-git-diff": "^0.0.19",
"playwright": "^1.56.1",
"prexit": "^2.3.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
@@ -89,16 +88,17 @@
"@lingui/conf": "^5.5.1",
"@lingui/format-json": "^5.5.1",
"@lingui/loader": "^5.5.1",
"@tailwindcss/postcss": "^4.1.14",
"@tailwindcss/postcss": "^4.1.15",
"@tsconfig/strictest": "^2.0.6",
"@types/node": "^24.8.1",
"@types/node": "^24.9.1",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@types/react-syntax-highlighter": "^15.5.13",
"npm-run-all2": "^8.0.4",
"playwright": "^1.56.1",
"release-it": "^19.0.5",
"release-it-pnpm": "^4.6.6",
"tailwindcss": "^4.1.14",
"tailwindcss": "^4.1.15",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3",
"vitest": "^3.2.4"

592
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -223,7 +223,6 @@ export const DiffModal: FC<DiffModalProps> = ({
const initialSelection = new Map(
diffData.data.files.map((file) => [file.filePath, true]),
);
console.log("[DiffModal] Initializing file selection:", initialSelection);
setSelectedFiles(initialSelection);
}
}, [diffData]);

View File

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

View File

@@ -1,7 +1,7 @@
import { query as agentSdkQuery } from "@anthropic-ai/claude-agent-sdk";
import { query as claudeCodeQuery } from "@anthropic-ai/claude-code";
import { Command, Path } from "@effect/platform";
import { Effect } from "effect";
import { Data, Effect } from "effect";
import { EnvService } from "../../platform/services/EnvService";
import * as ClaudeCodeVersion from "./ClaudeCodeVersion";
@@ -19,25 +19,74 @@ type SharedOptions = Pick<
Extract<keyof AgentSdkQueryOptions, keyof CCQueryOptions>
>;
export const Config = Effect.gen(function* () {
class ClaudeCodePathNotFoundError extends Data.TaggedError(
"ClaudeCodePathNotFoundError",
)<{
message: string;
}> {}
const resolveClaudeCodePath = Effect.gen(function* () {
const path = yield* Path.Path;
const envService = yield* EnvService;
// 1. Environment variable (highest priority)
const specifiedExecutablePath = yield* envService.getEnv(
"CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH",
);
if (specifiedExecutablePath !== undefined) {
return path.resolve(specifiedExecutablePath);
}
const claudeCodeExecutablePath =
specifiedExecutablePath !== undefined
? path.resolve(specifiedExecutablePath)
: (yield* Command.string(
Command.make("which", "claude").pipe(
Command.env({
PATH: yield* envService.getEnv("PATH"),
}),
Command.runInShell(true),
),
)).trim();
// 2. System PATH lookup
const pathEnv = yield* envService.getEnv("PATH");
const whichClaude = yield* Command.string(
Command.make("which", "claude").pipe(
Command.env({
PATH: pathEnv,
}),
Command.runInShell(true),
),
).pipe(
Effect.map((output) => output.trim()),
Effect.map((output) => (output === "" ? null : output)), // 存在しない時、空文字になる模様
Effect.catchAll(() => Effect.succeed(null)),
);
if (whichClaude !== null) {
return whichClaude;
}
// 3. Project dependency @anthropic-ai/claude-code/cli.js (fallback)
const projectClaudeCode = yield* Effect.try(() => {
// Next.js では import.meta.resolve が使えない
// __dirname もバンドルされてしまうため、無理やりパスを組み立てる
const parts = __dirname.split("/");
const packagePath = parts
.slice(0, parts.indexOf("claude-code-viewer") + 1)
.join("/");
return path.join(
packagePath,
"node_modules",
"@anthropic-ai",
"claude-code",
"cli.js",
);
}).pipe(
Effect.catchAll(() => {
return Effect.fail(
new ClaudeCodePathNotFoundError({
message: "Claude Code CLI not found in any location",
}),
);
}),
);
return projectClaudeCode;
});
export const Config = Effect.gen(function* () {
const claudeCodeExecutablePath = yield* resolveClaudeCodePath;
const claudeCodeVersion = ClaudeCodeVersion.fromCLIString(
yield* Command.string(Command.make(claudeCodeExecutablePath, "--version")),

View File

@@ -1,4 +1,7 @@
import type { SDKMessage, SDKUserMessage } from "@anthropic-ai/claude-code";
import type {
SDKMessage,
SDKUserMessage,
} from "@anthropic-ai/claude-agent-sdk";
import type { FileSystem, Path } from "@effect/platform";
import type { CommandExecutor } from "@effect/platform/CommandExecutor";
import { Context, Effect, Layer, Runtime } from "effect";

View File

@@ -1,4 +1,4 @@
import type { CanUseTool } from "@anthropic-ai/claude-code";
import type { CanUseTool } from "@anthropic-ai/claude-agent-sdk";
import { Context, Effect, Layer, Ref } from "effect";
import { ulid } from "ulid";
import type {

View File

@@ -1,4 +1,4 @@
import type { SDKResultMessage } from "@anthropic-ai/claude-code";
import type { SDKResultMessage } from "@anthropic-ai/claude-agent-sdk";
import { Context, Data, Effect, Layer, Ref } from "effect";
import type { InferEffect } from "../../../lib/effect/types";
import { EventBus } from "../../events/services/EventBus";

View File

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

View File

@@ -125,12 +125,6 @@ const LayerImpl = Effect.gen(function* () {
Effect.gen(function* () {
const { projectId, files, message } = options;
console.log("[GitController.commitFiles] Request:", {
projectId,
files,
message,
});
const { project } = yield* projectRepository.getProject(projectId);
if (project.meta.projectPath === null) {
console.log("[GitController.commitFiles] Project path is null");

View File

@@ -120,9 +120,7 @@ const LayerImpl = Effect.gen(function* () {
);
}
console.log("[GitService.stageFiles] Staging files:", files, "in", cwd);
const result = yield* execGitCommand(["add", ...files], cwd);
console.log("[GitService.stageFiles] Stage result:", result);
return result;
});