mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-02 13:39:41 +02:00
feat: Read My Mind phase 1, per-case intent profiles (capture + API + skill)
Per-case profiles of user intent (docs/readmymind-plan.md): user-stated goals plus the user's recently submitted prompts, captured from the Claude session transcript behind the new synced readMyMindEnabled setting (default OFF). - intent-store.ts: keyed by owner + realpath(workingDir), FIFO/size caps, consecutive-dupe collapse, atomic 0600 writes to ~/.codeman/intents.json - transcript-watcher.ts: new transcript:user_prompt event for typed user turns (tool_result-only entries stay silent); capture wiring in server.ts is claude-only and gated on the setting per event - readmymind-routes.ts: GET/PUT/DELETE /api/sessions/:id/intent, ownership via findSessionOrFail, strict Zod schema - agent skill: SKILL.md recipe + endpoints.md rows so agents can read and record intent (PUT replaces: read + merge; never delete unprompted) - groundwork for the phase-2 predictor button; nothing is ever auto-sent Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* - Tool execution state
|
||||
* - Error conditions
|
||||
* - Plan mode prompts
|
||||
* - User-authored prompts (`transcript:user_prompt`, Read My Mind intent capture)
|
||||
*
|
||||
* The transcript path is provided by Claude Code hooks in the `transcript_path` field.
|
||||
*/
|
||||
@@ -372,12 +373,23 @@ export class TranscriptWatcher extends EventEmitter {
|
||||
this.state.errorMessage = null;
|
||||
|
||||
const content = entry.message?.content;
|
||||
if (typeof content === 'string') {
|
||||
if (content.trim()) this.emit('transcript:user_prompt', content, entry.timestamp);
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(content)) return;
|
||||
let promptText = '';
|
||||
for (const block of content) {
|
||||
if (block.type === 'tool_result') {
|
||||
this.handleToolResult(block);
|
||||
} else if (block.type === 'text' && block.text) {
|
||||
promptText += (promptText ? ' ' : '') + block.text;
|
||||
}
|
||||
}
|
||||
// Text blocks mean a typed prompt; tool_result-only entries are Claude's own
|
||||
// tool plumbing, not intent. Filtering of command echo / system wrappers is
|
||||
// the intent store's job (`isCapturablePrompt`), not the watcher's.
|
||||
if (promptText.trim()) this.emit('transcript:user_prompt', promptText, entry.timestamp);
|
||||
}
|
||||
|
||||
private handleToolResult(block: TranscriptContentBlock): void {
|
||||
|
||||
Reference in New Issue
Block a user