olakai-cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +211 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2183,11 +2183,17 @@ function registerActivityCommand(program2) {
|
|
|
2183
2183
|
}
|
|
2184
2184
|
|
|
2185
2185
|
// src/commands/monitor.ts
|
|
2186
|
-
import * as
|
|
2187
|
-
import * as
|
|
2186
|
+
import * as fs3 from "fs";
|
|
2187
|
+
import * as path3 from "path";
|
|
2188
2188
|
import * as readline from "readline";
|
|
2189
2189
|
|
|
2190
2190
|
// src/commands/monitor-transcript.ts
|
|
2191
|
+
var FILE_EDITING_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
2192
|
+
"Edit",
|
|
2193
|
+
"Write",
|
|
2194
|
+
"MultiEdit"
|
|
2195
|
+
]);
|
|
2196
|
+
var BASH_TOOL_NAME = "Bash";
|
|
2191
2197
|
var SKILL_REGEX = /^\/([\w-]+)(?:\s|$)/;
|
|
2192
2198
|
function detectSkill(userMessage) {
|
|
2193
2199
|
if (typeof userMessage !== "string") return void 0;
|
|
@@ -2230,12 +2236,16 @@ function parseTranscript(raw) {
|
|
|
2230
2236
|
inputTokens: 0,
|
|
2231
2237
|
outputTokens: 0,
|
|
2232
2238
|
modelName: null,
|
|
2233
|
-
numTurns: 0
|
|
2239
|
+
numTurns: 0,
|
|
2240
|
+
toolCallCount: 0,
|
|
2241
|
+
filesEditedCount: 0,
|
|
2242
|
+
bashCommandCount: 0
|
|
2234
2243
|
};
|
|
2235
2244
|
if (!raw) return empty;
|
|
2236
2245
|
const lines = raw.split("\n");
|
|
2237
2246
|
let lastUserText = "";
|
|
2238
2247
|
let lastUserTimestamp = NaN;
|
|
2248
|
+
let lastUserTimestampRaw;
|
|
2239
2249
|
let lastAssistantText = "";
|
|
2240
2250
|
let lastAssistantTimestamp = NaN;
|
|
2241
2251
|
let lastAssistantModel = null;
|
|
@@ -2243,6 +2253,9 @@ function parseTranscript(raw) {
|
|
|
2243
2253
|
let lastAssistantOutputTokens = 0;
|
|
2244
2254
|
let numTurns = 0;
|
|
2245
2255
|
let currentTurnUserTimestamp = NaN;
|
|
2256
|
+
let toolCallCount = 0;
|
|
2257
|
+
let bashCommandCount = 0;
|
|
2258
|
+
let editedFilePaths = /* @__PURE__ */ new Set();
|
|
2246
2259
|
for (const rawLine of lines) {
|
|
2247
2260
|
if (!rawLine) continue;
|
|
2248
2261
|
let parsed;
|
|
@@ -2259,6 +2272,10 @@ function parseTranscript(raw) {
|
|
|
2259
2272
|
lastUserText = text;
|
|
2260
2273
|
lastUserTimestamp = parseTimestamp(parsed.timestamp);
|
|
2261
2274
|
currentTurnUserTimestamp = lastUserTimestamp;
|
|
2275
|
+
toolCallCount = 0;
|
|
2276
|
+
bashCommandCount = 0;
|
|
2277
|
+
editedFilePaths = /* @__PURE__ */ new Set();
|
|
2278
|
+
lastUserTimestampRaw = typeof parsed.timestamp === "string" && parsed.timestamp ? parsed.timestamp : void 0;
|
|
2262
2279
|
} else if (parsed.type === "assistant" && parsed.message) {
|
|
2263
2280
|
const text = extractTextContent(parsed.message.content);
|
|
2264
2281
|
numTurns += 1;
|
|
@@ -2266,6 +2283,30 @@ function parseTranscript(raw) {
|
|
|
2266
2283
|
if (typeof parsed.message.model === "string") {
|
|
2267
2284
|
lastAssistantModel = parsed.message.model;
|
|
2268
2285
|
}
|
|
2286
|
+
const content = parsed.message.content;
|
|
2287
|
+
if (Array.isArray(content)) {
|
|
2288
|
+
for (const block of content) {
|
|
2289
|
+
try {
|
|
2290
|
+
if (!block || block.type !== "tool_use") continue;
|
|
2291
|
+
toolCallCount += 1;
|
|
2292
|
+
const name = typeof block.name === "string" ? block.name : "";
|
|
2293
|
+
if (name === BASH_TOOL_NAME) {
|
|
2294
|
+
bashCommandCount += 1;
|
|
2295
|
+
continue;
|
|
2296
|
+
}
|
|
2297
|
+
if (FILE_EDITING_TOOL_NAMES.has(name)) {
|
|
2298
|
+
const input = block.input;
|
|
2299
|
+
if (input !== null && typeof input === "object" && "file_path" in input) {
|
|
2300
|
+
const filePath = input.file_path;
|
|
2301
|
+
if (typeof filePath === "string" && filePath) {
|
|
2302
|
+
editedFilePaths.add(filePath);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
} catch {
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2269
2310
|
const usage = parsed.message.usage;
|
|
2270
2311
|
if (usage) {
|
|
2271
2312
|
const input = (usage.input_tokens ?? 0) + (usage.cache_creation_input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0);
|
|
@@ -2286,7 +2327,10 @@ function parseTranscript(raw) {
|
|
|
2286
2327
|
inputTokens: lastAssistantInputTokens,
|
|
2287
2328
|
outputTokens: lastAssistantOutputTokens,
|
|
2288
2329
|
modelName: lastAssistantModel,
|
|
2289
|
-
numTurns
|
|
2330
|
+
numTurns,
|
|
2331
|
+
toolCallCount,
|
|
2332
|
+
filesEditedCount: editedFilePaths.size,
|
|
2333
|
+
bashCommandCount
|
|
2290
2334
|
};
|
|
2291
2335
|
if (!Number.isNaN(currentTurnUserTimestamp) && !Number.isNaN(lastAssistantTimestamp) && lastAssistantTimestamp >= currentTurnUserTimestamp) {
|
|
2292
2336
|
result.latencyMs = Math.round(
|
|
@@ -2297,9 +2341,80 @@ function parseTranscript(raw) {
|
|
|
2297
2341
|
if (skill) {
|
|
2298
2342
|
result.skill = skill;
|
|
2299
2343
|
}
|
|
2344
|
+
if (lastUserTimestampRaw) {
|
|
2345
|
+
result.userTurnTimestamp = lastUserTimestampRaw;
|
|
2346
|
+
}
|
|
2300
2347
|
return result;
|
|
2301
2348
|
}
|
|
2302
2349
|
|
|
2350
|
+
// src/commands/monitor-state.ts
|
|
2351
|
+
import * as fs2 from "fs";
|
|
2352
|
+
import * as os2 from "os";
|
|
2353
|
+
import * as path2 from "path";
|
|
2354
|
+
var STATE_DIR_SEGMENTS = [".olakai", "monitor-state"];
|
|
2355
|
+
function getStateDir(homeDir) {
|
|
2356
|
+
return path2.join(homeDir, ...STATE_DIR_SEGMENTS);
|
|
2357
|
+
}
|
|
2358
|
+
function getStateFile(sessionId, homeDir) {
|
|
2359
|
+
return path2.join(getStateDir(homeDir), `${sessionId}.json`);
|
|
2360
|
+
}
|
|
2361
|
+
var debugLogger = null;
|
|
2362
|
+
function setDebugLogger(logger) {
|
|
2363
|
+
debugLogger = logger;
|
|
2364
|
+
}
|
|
2365
|
+
function log(label, data) {
|
|
2366
|
+
if (debugLogger) {
|
|
2367
|
+
try {
|
|
2368
|
+
debugLogger(label, data);
|
|
2369
|
+
} catch {
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
function loadSessionState(sessionId, homeDir = os2.homedir()) {
|
|
2374
|
+
if (!sessionId) return null;
|
|
2375
|
+
const filePath = getStateFile(sessionId, homeDir);
|
|
2376
|
+
try {
|
|
2377
|
+
if (!fs2.existsSync(filePath)) return null;
|
|
2378
|
+
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
2379
|
+
const parsed = JSON.parse(raw);
|
|
2380
|
+
if (typeof parsed?.lastUserTimestamp !== "string" || typeof parsed?.lastReportedAt !== "string" || typeof parsed?.numTurnsAtLastReport !== "number") {
|
|
2381
|
+
return null;
|
|
2382
|
+
}
|
|
2383
|
+
return {
|
|
2384
|
+
lastUserTimestamp: parsed.lastUserTimestamp,
|
|
2385
|
+
lastReportedAt: parsed.lastReportedAt,
|
|
2386
|
+
numTurnsAtLastReport: parsed.numTurnsAtLastReport
|
|
2387
|
+
};
|
|
2388
|
+
} catch (err) {
|
|
2389
|
+
log("state-load-failed", {
|
|
2390
|
+
sessionId,
|
|
2391
|
+
error: err.message
|
|
2392
|
+
});
|
|
2393
|
+
return null;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
function saveSessionState(sessionId, state, homeDir = os2.homedir()) {
|
|
2397
|
+
if (!sessionId) return;
|
|
2398
|
+
const dir = getStateDir(homeDir);
|
|
2399
|
+
const filePath = getStateFile(sessionId, homeDir);
|
|
2400
|
+
try {
|
|
2401
|
+
if (!fs2.existsSync(dir)) {
|
|
2402
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
2403
|
+
}
|
|
2404
|
+
fs2.writeFileSync(filePath, JSON.stringify(state, null, 2) + "\n", "utf-8");
|
|
2405
|
+
} catch (err) {
|
|
2406
|
+
log("state-save-failed", {
|
|
2407
|
+
sessionId,
|
|
2408
|
+
error: err.message
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
function shouldReportTurn(existing, currentUserTimestamp) {
|
|
2413
|
+
if (!currentUserTimestamp) return true;
|
|
2414
|
+
if (!existing) return true;
|
|
2415
|
+
return existing.lastUserTimestamp !== currentUserTimestamp;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2303
2418
|
// src/commands/monitor.ts
|
|
2304
2419
|
var CLAUDE_DIR = ".claude";
|
|
2305
2420
|
var SETTINGS_FILE = "settings.json";
|
|
@@ -2361,39 +2476,55 @@ function prompt(question) {
|
|
|
2361
2476
|
function findProjectRoot(startDir) {
|
|
2362
2477
|
let dir = startDir ?? process.cwd();
|
|
2363
2478
|
while (true) {
|
|
2364
|
-
if (
|
|
2479
|
+
if (fs3.existsSync(path3.join(dir, CLAUDE_DIR))) {
|
|
2365
2480
|
return dir;
|
|
2366
2481
|
}
|
|
2367
|
-
const parent =
|
|
2482
|
+
const parent = path3.dirname(dir);
|
|
2368
2483
|
if (parent === dir) break;
|
|
2369
2484
|
dir = parent;
|
|
2370
2485
|
}
|
|
2371
2486
|
return startDir ?? process.cwd();
|
|
2372
2487
|
}
|
|
2488
|
+
function findConfiguredProjectRoot(startDir) {
|
|
2489
|
+
let dir = startDir ?? process.cwd();
|
|
2490
|
+
while (true) {
|
|
2491
|
+
if (fs3.existsSync(path3.join(dir, CLAUDE_DIR, MONITOR_CONFIG_FILE))) {
|
|
2492
|
+
return dir;
|
|
2493
|
+
}
|
|
2494
|
+
const parent = path3.dirname(dir);
|
|
2495
|
+
if (parent === dir) break;
|
|
2496
|
+
dir = parent;
|
|
2497
|
+
}
|
|
2498
|
+
return null;
|
|
2499
|
+
}
|
|
2500
|
+
function resolveProjectRootFromPayload(eventData, fallbackCwd) {
|
|
2501
|
+
const payloadCwd = typeof eventData.cwd === "string" && eventData.cwd.trim() ? eventData.cwd : fallbackCwd;
|
|
2502
|
+
return findConfiguredProjectRoot(payloadCwd);
|
|
2503
|
+
}
|
|
2373
2504
|
function getClaudeDir(projectRoot) {
|
|
2374
|
-
return
|
|
2505
|
+
return path3.join(projectRoot, CLAUDE_DIR);
|
|
2375
2506
|
}
|
|
2376
2507
|
function getSettingsPath(projectRoot) {
|
|
2377
|
-
return
|
|
2508
|
+
return path3.join(getClaudeDir(projectRoot), SETTINGS_FILE);
|
|
2378
2509
|
}
|
|
2379
2510
|
function getMonitorConfigPath(projectRoot) {
|
|
2380
|
-
return
|
|
2511
|
+
return path3.join(getClaudeDir(projectRoot), MONITOR_CONFIG_FILE);
|
|
2381
2512
|
}
|
|
2382
2513
|
function readJsonFile(filePath) {
|
|
2383
2514
|
try {
|
|
2384
|
-
if (!
|
|
2385
|
-
const content =
|
|
2515
|
+
if (!fs3.existsSync(filePath)) return null;
|
|
2516
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
2386
2517
|
return JSON.parse(content);
|
|
2387
2518
|
} catch {
|
|
2388
2519
|
return null;
|
|
2389
2520
|
}
|
|
2390
2521
|
}
|
|
2391
2522
|
function writeJsonFile(filePath, data) {
|
|
2392
|
-
const dir =
|
|
2393
|
-
if (!
|
|
2394
|
-
|
|
2523
|
+
const dir = path3.dirname(filePath);
|
|
2524
|
+
if (!fs3.existsSync(dir)) {
|
|
2525
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2395
2526
|
}
|
|
2396
|
-
|
|
2527
|
+
fs3.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
2397
2528
|
}
|
|
2398
2529
|
function loadMonitorConfig(projectRoot) {
|
|
2399
2530
|
const root = projectRoot ?? findProjectRoot();
|
|
@@ -2433,7 +2564,7 @@ async function initCommand() {
|
|
|
2433
2564
|
}
|
|
2434
2565
|
console.log("Setting up Claude Code monitoring for this workspace...\n");
|
|
2435
2566
|
const projectRoot = process.cwd();
|
|
2436
|
-
const dirName =
|
|
2567
|
+
const dirName = path3.basename(projectRoot);
|
|
2437
2568
|
let agent;
|
|
2438
2569
|
const choice = await prompt(
|
|
2439
2570
|
"Create a new agent or use an existing one? (new/existing) [new]: "
|
|
@@ -2484,8 +2615,8 @@ Select agent (1-${agents.length}): `);
|
|
|
2484
2615
|
}
|
|
2485
2616
|
}
|
|
2486
2617
|
const claudeDir = getClaudeDir(projectRoot);
|
|
2487
|
-
if (!
|
|
2488
|
-
|
|
2618
|
+
if (!fs3.existsSync(claudeDir)) {
|
|
2619
|
+
fs3.mkdirSync(claudeDir, { recursive: true });
|
|
2489
2620
|
}
|
|
2490
2621
|
const settingsPath = getSettingsPath(projectRoot);
|
|
2491
2622
|
const existingSettings = readJsonFile(settingsPath) ?? {};
|
|
@@ -2506,7 +2637,7 @@ Select agent (1-${agents.length}): `);
|
|
|
2506
2637
|
};
|
|
2507
2638
|
const monitorConfigPath = getMonitorConfigPath(projectRoot);
|
|
2508
2639
|
writeJsonFile(monitorConfigPath, monitorConfig);
|
|
2509
|
-
|
|
2640
|
+
fs3.chmodSync(monitorConfigPath, 384);
|
|
2510
2641
|
console.log("");
|
|
2511
2642
|
console.log(`\u2713 Agent "${agent.name}" configured (ID: ${agent.id})`);
|
|
2512
2643
|
if (agent.apiKey?.key) {
|
|
@@ -2550,7 +2681,7 @@ function debugLog(label, data) {
|
|
|
2550
2681
|
const logPath = `/tmp/olakai-monitor-debug-${process.pid}.log`;
|
|
2551
2682
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${label}: ${typeof data === "string" ? data : JSON.stringify(data, null, 2)}
|
|
2552
2683
|
`;
|
|
2553
|
-
|
|
2684
|
+
fs3.appendFileSync(logPath, line, "utf-8");
|
|
2554
2685
|
} catch {
|
|
2555
2686
|
}
|
|
2556
2687
|
}
|
|
@@ -2562,12 +2693,15 @@ function extractFromTranscript(transcriptPath) {
|
|
|
2562
2693
|
inputTokens: 0,
|
|
2563
2694
|
outputTokens: 0,
|
|
2564
2695
|
modelName: null,
|
|
2565
|
-
numTurns: 0
|
|
2696
|
+
numTurns: 0,
|
|
2697
|
+
toolCallCount: 0,
|
|
2698
|
+
filesEditedCount: 0,
|
|
2699
|
+
bashCommandCount: 0
|
|
2566
2700
|
};
|
|
2567
2701
|
if (!transcriptPath) return empty;
|
|
2568
2702
|
let raw;
|
|
2569
2703
|
try {
|
|
2570
|
-
raw =
|
|
2704
|
+
raw = fs3.readFileSync(transcriptPath, "utf-8");
|
|
2571
2705
|
} catch (err) {
|
|
2572
2706
|
debugLog("transcript-read-failed", {
|
|
2573
2707
|
transcriptPath,
|
|
@@ -2592,11 +2726,8 @@ function extractSubagentName(event) {
|
|
|
2592
2726
|
return void 0;
|
|
2593
2727
|
}
|
|
2594
2728
|
async function hookCommand(event) {
|
|
2729
|
+
setDebugLogger(debugLog);
|
|
2595
2730
|
try {
|
|
2596
|
-
const config = loadMonitorConfig();
|
|
2597
|
-
if (!config) {
|
|
2598
|
-
return;
|
|
2599
|
-
}
|
|
2600
2731
|
const stdinData = await readStdin(3e3);
|
|
2601
2732
|
debugLog("stdin-raw", stdinData);
|
|
2602
2733
|
let eventData = {};
|
|
@@ -2605,15 +2736,42 @@ async function hookCommand(event) {
|
|
|
2605
2736
|
eventData = JSON.parse(stdinData);
|
|
2606
2737
|
} catch {
|
|
2607
2738
|
debugLog("stdin-parse-failed", stdinData);
|
|
2608
|
-
return;
|
|
2609
2739
|
}
|
|
2610
2740
|
}
|
|
2611
2741
|
debugLog("event-parsed", { event, eventData });
|
|
2742
|
+
const projectRoot = resolveProjectRootFromPayload(
|
|
2743
|
+
eventData,
|
|
2744
|
+
process.cwd()
|
|
2745
|
+
);
|
|
2746
|
+
if (!projectRoot) {
|
|
2747
|
+
debugLog("config-not-found", {
|
|
2748
|
+
startDir: typeof eventData.cwd === "string" && eventData.cwd.trim() ? eventData.cwd : process.cwd()
|
|
2749
|
+
});
|
|
2750
|
+
return;
|
|
2751
|
+
}
|
|
2752
|
+
const config = loadMonitorConfig(projectRoot);
|
|
2753
|
+
if (!config) {
|
|
2754
|
+
debugLog("config-load-failed", { projectRoot });
|
|
2755
|
+
return;
|
|
2756
|
+
}
|
|
2612
2757
|
const payload = buildPayload(event, eventData, config);
|
|
2613
2758
|
if (!payload) {
|
|
2614
2759
|
return;
|
|
2615
2760
|
}
|
|
2616
2761
|
debugLog("payload-built", payload);
|
|
2762
|
+
const sessionId = typeof eventData.session_id === "string" && eventData.session_id || void 0;
|
|
2763
|
+
const extracted = extractFromTranscript(eventData.transcript_path);
|
|
2764
|
+
const userTurnTimestamp = extracted.userTurnTimestamp;
|
|
2765
|
+
if (sessionId) {
|
|
2766
|
+
const existingState = loadSessionState(sessionId);
|
|
2767
|
+
if (!shouldReportTurn(existingState, userTurnTimestamp)) {
|
|
2768
|
+
debugLog("turn-dedup-skip", {
|
|
2769
|
+
sessionId,
|
|
2770
|
+
userTurnTimestamp
|
|
2771
|
+
});
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2617
2775
|
const controller = new AbortController();
|
|
2618
2776
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
2619
2777
|
try {
|
|
@@ -2633,6 +2791,18 @@ async function hookCommand(event) {
|
|
|
2633
2791
|
} finally {
|
|
2634
2792
|
clearTimeout(timeoutId);
|
|
2635
2793
|
}
|
|
2794
|
+
if (sessionId && userTurnTimestamp) {
|
|
2795
|
+
saveSessionState(sessionId, {
|
|
2796
|
+
lastUserTimestamp: userTurnTimestamp,
|
|
2797
|
+
lastReportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2798
|
+
numTurnsAtLastReport: extracted.numTurns
|
|
2799
|
+
});
|
|
2800
|
+
debugLog("state-saved", {
|
|
2801
|
+
sessionId,
|
|
2802
|
+
userTurnTimestamp,
|
|
2803
|
+
numTurns: extracted.numTurns
|
|
2804
|
+
});
|
|
2805
|
+
}
|
|
2636
2806
|
} catch (err) {
|
|
2637
2807
|
debugLog("hook-exception", err.message);
|
|
2638
2808
|
}
|
|
@@ -2652,7 +2822,15 @@ function buildPayload(event, eventData, config) {
|
|
|
2652
2822
|
stopHookActive: eventData.stop_hook_active ?? false,
|
|
2653
2823
|
inputTokens: extracted.inputTokens,
|
|
2654
2824
|
outputTokens: extracted.outputTokens,
|
|
2655
|
-
numTurns: extracted.numTurns
|
|
2825
|
+
numTurns: extracted.numTurns,
|
|
2826
|
+
// Per-turn work signals for the Claude Code classifier (D-027).
|
|
2827
|
+
// Always emitted as JSON numbers — the backend classifier and
|
|
2828
|
+
// future KPI formulas must see numeric 0, not missing keys or
|
|
2829
|
+
// strings. File paths and bash command strings are deliberately
|
|
2830
|
+
// NOT emitted; only the cardinality is privacy-safe to ship.
|
|
2831
|
+
toolCallCount: extracted.toolCallCount,
|
|
2832
|
+
filesEditedCount: extracted.filesEditedCount,
|
|
2833
|
+
bashCommandCount: extracted.bashCommandCount
|
|
2656
2834
|
};
|
|
2657
2835
|
if (typeof extracted.latencyMs === "number") {
|
|
2658
2836
|
customData.latencyMs = extracted.latencyMs;
|
|
@@ -2665,9 +2843,11 @@ function buildPayload(event, eventData, config) {
|
|
|
2665
2843
|
} else if (extracted.skill) {
|
|
2666
2844
|
customData.skill = extracted.skill;
|
|
2667
2845
|
}
|
|
2846
|
+
const payloadAssistant = eventData.last_assistant_message;
|
|
2847
|
+
const response = typeof payloadAssistant === "string" && payloadAssistant.trim() ? payloadAssistant : extracted.response;
|
|
2668
2848
|
return {
|
|
2669
2849
|
prompt: extracted.prompt,
|
|
2670
|
-
response
|
|
2850
|
+
response,
|
|
2671
2851
|
chatId: sessionId,
|
|
2672
2852
|
// Top-level source so the backend ExternalPromptRequestSchema
|
|
2673
2853
|
// picks it up (matches regex ^[a-z0-9_-]+$).
|
|
@@ -2774,8 +2954,8 @@ async function disableCommand(options) {
|
|
|
2774
2954
|
}
|
|
2775
2955
|
if (!options.keepConfig) {
|
|
2776
2956
|
const configPath = getMonitorConfigPath(projectRoot);
|
|
2777
|
-
if (
|
|
2778
|
-
|
|
2957
|
+
if (fs3.existsSync(configPath)) {
|
|
2958
|
+
fs3.unlinkSync(configPath);
|
|
2779
2959
|
console.log(`\u2713 Monitor config removed (${CLAUDE_DIR}/${MONITOR_CONFIG_FILE})`);
|
|
2780
2960
|
}
|
|
2781
2961
|
} else {
|