aboutsummaryrefslogtreecommitdiffstats
path: root/dist/main/claude/index.js
blob: 42a96522f72d1e20424137aa5a31bc2033d80f3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendMessage = sendMessage;
exports.interruptSession = interruptSession;
exports.triggerReview = triggerReview;
exports.advancePhase = advancePhase;
exports.readArtifact = readArtifact;
exports.writeArtifact = writeArtifact;
exports.getPhaseInitialMessage = getPhaseInitialMessage;
const claude_agent_sdk_1 = require("@anthropic-ai/claude-agent-sdk");
const phases_1 = require("./phases");
const projects_1 = require("../db/projects");
const sessions_1 = require("../db/sessions");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
// Track active queries by session ID
const activeQueries = new Map();
function ensureArtifactDir(projectPath) {
    const dir = node_path_1.default.join(projectPath, ".claude-flow");
    if (!node_fs_1.default.existsSync(dir)) {
        node_fs_1.default.mkdirSync(dir, { recursive: true });
    }
}
async function sendMessage({ session, message, onMessage, }) {
    const project = (0, projects_1.getProject)(session.project_id);
    if (!project)
        throw new Error("Project not found");
    ensureArtifactDir(project.path);
    const phaseConfig = (0, phases_1.getPhaseConfig)(session.phase, session.permission_mode);
    const q = (0, claude_agent_sdk_1.query)({
        prompt: message,
        options: {
            cwd: project.path,
            resume: session.claude_session_id ?? undefined,
            tools: phaseConfig.tools,
            permissionMode: phaseConfig.permissionMode,
            systemPrompt: phaseConfig.systemPrompt,
        },
    });
    activeQueries.set(session.id, q);
    try {
        for await (const msg of q) {
            // Capture session ID from init message
            if (msg.type === "system" && msg.subtype === "init") {
                if (!session.claude_session_id) {
                    (0, sessions_1.updateSession)(session.id, { claude_session_id: msg.session_id });
                }
            }
            onMessage(msg);
        }
    }
    finally {
        activeQueries.delete(session.id);
    }
}
function interruptSession(sessionId) {
    const q = activeQueries.get(sessionId);
    if (q) {
        q.close();
        activeQueries.delete(sessionId);
    }
}
/**
 * Trigger a review: Claude reads the document and addresses user annotations
 */
async function triggerReview(session, onMessage) {
    const docName = (0, phases_1.getArtifactFilename)(session.phase);
    const message = `I've updated .claude-flow/${docName} with annotations. Read the file, find all my inline notes (marked with // REVIEW:, // NOTE:, TODO:, or similar), address each one, and update the document accordingly. Do not implement anything yet.`;
    await sendMessage({ session, message, onMessage });
}
/**
 * Advance to the next phase
 */
function advancePhase(session) {
    const nextPhase = (0, phases_1.getNextPhase)(session.phase);
    if (nextPhase) {
        (0, sessions_1.updateSession)(session.id, { phase: nextPhase });
    }
    return nextPhase;
}
/**
 * Read an artifact file from the project's .claude-flow directory
 */
function readArtifact(projectPath, filename) {
    const filePath = node_path_1.default.join(projectPath, ".claude-flow", filename);
    if (node_fs_1.default.existsSync(filePath)) {
        return node_fs_1.default.readFileSync(filePath, "utf-8");
    }
    return null;
}
/**
 * Write an artifact file to the project's .claude-flow directory
 */
function writeArtifact(projectPath, filename, content) {
    const dir = node_path_1.default.join(projectPath, ".claude-flow");
    if (!node_fs_1.default.existsSync(dir)) {
        node_fs_1.default.mkdirSync(dir, { recursive: true });
    }
    node_fs_1.default.writeFileSync(node_path_1.default.join(dir, filename), content, "utf-8");
}
/**
 * Get the initial message for a phase
 */
function getPhaseInitialMessage(phase) {
    return (0, phases_1.getPhaseConfig)(phase).initialMessage;
}