feat(claude): Add raw hook capture and Claude agent configuration#56
Open
ivke995 wants to merge 18 commits into
Open
feat(claude): Add raw hook capture and Claude agent configuration#56ivke995 wants to merge 18 commits into
ivke995 wants to merge 18 commits into
Conversation
53d3ae6 to
a73ccfa
Compare
Implement hidden `sce hooks claude-capture` subcommand for raw Claude hook JSON intake with PostToolUse model enrichment from transcript. Add Pkl-generated Claude project settings with capture hook config, and Claude agent/skill/command definitions for the SCE workflow. - Add ClaudeCapture subcommand to hooks CLI surface (hidden) - Add ClaudeCaptureEvent enum: SessionStart, UserPromptSubmit, PostToolUse, Stop - Implement PostToolUse model enrichment via claude_transcript JSONL transcript model extraction helper - Refactor trace persistence into reusable building blocks (persist_serialized_trace_payload_at, persist_trace_payload_with_retries) - Add RepoPaths::claude_capture_tmp_dir() for canonical path ownership of context/tmp/claude/ - Add Pkl-generated config/.claude/settings.json registering capture hooks for all four event types - Add Claude agent, command, and skill definitions under .claude/ enabling SCE workflow in Claude Code - Update context documentation for new Claude capture surface Co-authored-by: SCE <sce@crocoder.dev>
… intake Remove the `sce hooks claude-capture` hidden CLI route, `ClaudeCaptureEvent` enum variant, `claude_transcript.rs` enrichment module, and `RepoPaths::claude_capture_tmp_dir()` — the raw JSON diagnostic path that wrote Claude hook payloads under `context/tmp/claude/` without DB persistence or cross-editor reuse. Add `sce hooks session-model` STDIN intake for normalized model attribution upsert into the new AgentTraceDb `session_models` table (migration 008). `diff-trace` now accepts optional `model_id` and resolves it from `session_models` when absent, enabling cross-editor reuse: OpenCode sends `model_id` directly, Claude relies on DB resolution. Generate a Claude TypeScript event-adapter runtime at `.claude/plugins/sce-agent-trace.ts` that emits normalized `session-model` and `diff-trace` payloads to the shared Rust intake. Update the generated-config pipeline (Pkl renderers, OpenCode plugin registration, settings) and build fileset to include the new agent-trace-plugin source tree. Update `context/` docs to reflect the removed raw capture route, the new session-model command routing, and the cross-editor shared boundary at `sce hooks diff-trace`. Co-authored-by: SCE <sce@crocoder.dev>
Remove the unused CLI dev-dependency from Cargo.toml and Cargo.lock, leaving the crate without declared dev-dependencies. Update the documented CLI dependency and styling baseline to reflect the current manifest state. Co-authored-by: SCE <sce@crocoder.dev>
Claude sends model attribution via `session-model` at SessionStart rather than including model_id in every diff-trace payload. The parser previously required model_id, rejecting all Claude diff traces. - Change DiffTraceInsert.model_id from &str to Option<&str> - Change DiffTracePayload.model_id from String to Option<String> - Add optional_string_field helper for JSON parsing - Wire resolve_model closure for DB lookup when model_id absent - Thread resolved model_id through persistence functions Co-authored-by: SCE <sce@crocoder.dev>
Add checked-in diff_creation fixtures for Claude Write/Edit PostToolUse payloads and test deriveClaudeDiffTracePayload through the exported derivation seam. Cover create and edit scenarios with exact expected patch comparisons, and update Agent Trace and patch-service context to document the fixture coverage. Co-authored-by: SCE <sce@crocoder.dev>
Delete unused input.json sidecars from the Claude diff-creation fixture suite. The active golden tests consume claude-post-tool-use.json and expected.patch, so the patch-service context now documents that fixture contract directly. Co-authored-by: SCE <sce@crocoder.dev>
d8df734 to
01a6359
Compare
| try { | ||
| const parseResult = parseClaudeHookPayloadJson(rawJson); | ||
| if (parseResult.status !== "ok") { | ||
| return; |
Contributor
There was a problem hiding this comment.
We could handle this parsing failure better.
| ["hooks", "session-model"], | ||
| `${JSON.stringify({ | ||
| sessionID: sessionId, | ||
| time: currentTimeMs(context.now), |
Contributor
There was a problem hiding this comment.
Why not just Date.now()?
Comment on lines
+434
to
+436
| payload.tool_version, | ||
| payload.claude_version, | ||
| payload.version, |
Contributor
There was a problem hiding this comment.
We expect claude to have different properties for version?
| } | ||
|
|
||
| try { | ||
| const parseResult = parseClaudeHookPayloadJson(rawJson); |
Contributor
There was a problem hiding this comment.
You could parse hook payload at the top of the function and send parsed result to handlers.
Comment on lines
+448
to
+458
| if (value === undefined) { | ||
| return undefined; | ||
| } | ||
|
|
||
| if (value === null) { | ||
| return null; | ||
| } | ||
|
|
||
| if (typeof value !== "string") { | ||
| return null; | ||
| } |
Contributor
There was a problem hiding this comment.
Function could be simplified
function normalizeOptionalVersion(value: unknown): string | null {
if (!value || typeof value !== "string") {
return null;
}
const normalized = value.trim();
return normalized.length === 0 ? null : normalized;
}
Comment on lines
+183
to
+184
| "originalFile", | ||
| "original_file", |
Contributor
There was a problem hiding this comment.
Do we expect this property in different formats?
Share payload-kind-aware validation helpers across diff-trace and session-model hook payload parsing while preserving each command's user-facing error prefix. Co-authored-by: SCE <sce@crocoder.dev>
Run config-lib Bun and Biome checks from config/lib inside a copied repo-shaped source tree, including the shared CLI diff_creation fixtures needed by agent-trace golden tests. Records the source-layout contract for config-lib checks. Co-authored-by: SCE <sce@crocoder.dev>
Co-authored-by: SCE <sce@crocoder.dev>
Introduce cli/src/services/structured_patch.rs to convert Claude PostToolUse structured payloads into canonical ParsedPatch values. Supports Write create and Edit structured patch tools with deterministic skip reasons for unsupported events, tools, or payload shapes. Register the module in services/mod.rs. Co-authored-by: SCE <sce@crocoder.dev>
Migrate the Claude PostToolUse diff-creation golden fixture coverage from TypeScript to Rust. Co-authored-by: SCE <sce@crocoder.dev>
Introduce migration 009_add_diff_traces_payload_type to add a payload_type column (TEXT NOT NULL DEFAULT 'patch') to the diff_traces table. This enables generic storage of source payloads with explicit type discrimination: patch for OpenCode unified-diff payloads and structured for Claude PostToolUse structured payloads. Update typed insert and query structs (DiffTraceInsert, DiffTracePatchRow, ParsedDiffTracePatch) to carry payload_type, and add PAYLOAD_TYPE_PATCH and PAYLOAD_TYPE_STRUCTURED constants. Wire PAYLOAD_TYPE_PATCH through the existing sce hooks diff-trace hook runtime to preserve current OpenCode behavior. Update recent-diff-trace query SQL, row parsing, and tests to include the new column. Co-authored-by: SCE <sce@crocoder.dev>
…trace hook Extend `sce hooks diff-trace` STDIN intake to classify and persist Claude structured `PostToolUse` payloads without converting them to unified-diff text at insert time. Co-authored-by: SCE <sce@crocoder.dev>
…ocessing Update AgentTraceDb::recent_diff_trace_patches to dispatch on payload_type: patch rows continue through existing unified-diff parsing, while structured rows parse stored JSON and derive ParsedPatch via structured_patch::derive_claude_structured_patch at read time. Co-authored-by: SCE <sce@crocoder.dev>
Replace Bun/TypeScript Claude hook invocations with direct `sce hooks` commands. Claude settings now pipe raw hook event JSON on STDIN: `SessionStart` → `sce hooks session-model`, matched `PostToolUse` → `sce hooks diff-trace`. The Rust `session-model` intake detects Claude payloads via `hook_event_name` and extracts session_id / model_id / time / tool_version from the raw Claude event format, normalizing model_id with a `claude/` prefix. The diff-trace intake already handled Claude structured-patch derivation. Co-authored-by: SCE <sce@crocoder.dev>
Claude diff-trace and session-model hooks are now handled by the Rust CLI via `sce hooks` subcommands (completed in T06). This removes the obsolete TypeScript Bun plugin runtime. Co-authored-by: SCE <sce@crocoder.dev>
…ation Remove stale references to the Claude TypeScript agent-trace runtime and outdated "until T05" qualifiers across overview, architecture, glossary, and SCE context files. Reflect the current direct `sce hooks` boundary where Rust handles extraction, validation, and persistence without a TypeScript intermediary. Update the claude-rust-diff-trace plan status to mark T08 and T09 complete and append the final validation report with concrete success-criteria evidence. Co-authored-by: SCE <sce@crocoder.dev>
…orts Update Claude Code settings to use single command strings instead of separate command/args arrays for hook invocations. Co-authored-by: SCE <sce@crocoder.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.