@jungjaehoon/mama-core 1.1.2 → 1.1.3
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/config-loader.d.ts +61 -0
- package/dist/config-loader.js +187 -0
- package/dist/db-adapter/base-adapter.d.ts +76 -0
- package/dist/db-adapter/base-adapter.js +11 -0
- package/dist/db-adapter/index.d.ts +24 -0
- package/dist/db-adapter/index.js +29 -0
- package/dist/db-adapter/sqlite-adapter.d.ts +73 -0
- package/dist/db-adapter/sqlite-adapter.js +330 -0
- package/dist/db-adapter/statement.d.ts +119 -0
- package/dist/db-adapter/statement.js +113 -0
- package/dist/db-manager.d.ts +252 -0
- package/dist/db-manager.js +622 -0
- package/dist/debug-logger.d.ts +32 -0
- package/dist/debug-logger.js +83 -0
- package/dist/decision-formatter.d.ts +172 -0
- package/dist/decision-formatter.js +894 -0
- package/dist/decision-tracker.d.ts +218 -0
- package/dist/decision-tracker.js +531 -0
- package/dist/embedding-cache.d.ts +83 -0
- package/dist/embedding-cache.js +182 -0
- package/dist/embedding-client.d.ts +43 -0
- package/dist/embedding-client.js +132 -0
- package/dist/embedding-server/index.d.ts +65 -0
- package/dist/embedding-server/index.js +397 -0
- package/dist/embedding-server/mobile/auth.d.ts +53 -0
- package/dist/embedding-server/mobile/auth.js +140 -0
- package/dist/embedding-server/mobile/daemon.d.ts +128 -0
- package/dist/embedding-server/mobile/daemon.js +303 -0
- package/dist/embedding-server/mobile/output-parser.d.ts +115 -0
- package/dist/embedding-server/mobile/output-parser.js +241 -0
- package/dist/embedding-server/mobile/session-api.d.ts +57 -0
- package/dist/embedding-server/mobile/session-api.js +261 -0
- package/dist/embedding-server/mobile/session-manager.d.ts +135 -0
- package/dist/embedding-server/mobile/session-manager.js +333 -0
- package/dist/embedding-server/mobile/websocket-handler.d.ts +127 -0
- package/dist/embedding-server/mobile/websocket-handler.js +435 -0
- package/dist/embeddings.d.ts +75 -0
- package/dist/embeddings.js +262 -0
- package/dist/errors.d.ts +131 -0
- package/dist/errors.js +225 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +193 -0
- package/dist/mama-api.d.ts +954 -0
- package/dist/mama-api.js +2210 -0
- package/dist/memory-inject.d.ts +24 -0
- package/dist/memory-inject.js +116 -0
- package/dist/memory-store.d.ts +103 -0
- package/dist/memory-store.js +129 -0
- package/dist/notification-manager.d.ts +7 -0
- package/dist/notification-manager.js +12 -0
- package/dist/ollama-client.d.ts +51 -0
- package/dist/ollama-client.js +308 -0
- package/dist/outcome-tracker.d.ts +165 -0
- package/dist/outcome-tracker.js +315 -0
- package/dist/progress-indicator.d.ts +48 -0
- package/dist/progress-indicator.js +82 -0
- package/dist/query-intent.d.ts +27 -0
- package/dist/query-intent.js +144 -0
- package/dist/relevance-scorer.d.ts +124 -0
- package/dist/relevance-scorer.js +243 -0
- package/dist/test-utils.d.ts +66 -0
- package/dist/test-utils.js +166 -0
- package/dist/tier-validator.d.ts +55 -0
- package/dist/tier-validator.js +216 -0
- package/dist/time-formatter.d.ts +25 -0
- package/dist/time-formatter.js +93 -0
- package/package.json +3 -2
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Claude Code Daemon - stream-json based subprocess manager
|
|
3
|
+
* @module mobile/daemon
|
|
4
|
+
* @version 1.5.2
|
|
5
|
+
*
|
|
6
|
+
* Manages Claude Code as a subprocess using stream-json mode for
|
|
7
|
+
* bidirectional JSON communication.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { ClaudeDaemon } from './daemon';
|
|
11
|
+
* const daemon = new ClaudeDaemon('/path/to/project', 'session_123');
|
|
12
|
+
* await daemon.spawn();
|
|
13
|
+
* daemon.send('Hello Claude!');
|
|
14
|
+
* daemon.on('output', (data) => console.log(data));
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from 'events';
|
|
17
|
+
/**
|
|
18
|
+
* ANSI escape code regex pattern
|
|
19
|
+
*/
|
|
20
|
+
export declare const ANSI_REGEX: RegExp;
|
|
21
|
+
/**
|
|
22
|
+
* Output event data
|
|
23
|
+
*/
|
|
24
|
+
export interface OutputEvent {
|
|
25
|
+
type: 'stdout' | 'stderr';
|
|
26
|
+
text: string;
|
|
27
|
+
raw: string;
|
|
28
|
+
parsed?: unknown;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Error event data
|
|
33
|
+
*/
|
|
34
|
+
export interface ErrorEvent {
|
|
35
|
+
error: Error;
|
|
36
|
+
sessionId: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Exit event data
|
|
40
|
+
*/
|
|
41
|
+
export interface ExitEvent {
|
|
42
|
+
code: number | null;
|
|
43
|
+
signal: NodeJS.Signals | null;
|
|
44
|
+
sessionId: string;
|
|
45
|
+
manual?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Tool use event data
|
|
49
|
+
*/
|
|
50
|
+
export interface ToolUseEvent {
|
|
51
|
+
tool: string;
|
|
52
|
+
toolId: string;
|
|
53
|
+
input: unknown;
|
|
54
|
+
sessionId: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Tool complete event data
|
|
58
|
+
*/
|
|
59
|
+
export interface ToolCompleteEvent {
|
|
60
|
+
index: number;
|
|
61
|
+
sessionId: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Response complete event data
|
|
65
|
+
*/
|
|
66
|
+
export interface ResponseCompleteEvent {
|
|
67
|
+
sessionId: string;
|
|
68
|
+
result: unknown;
|
|
69
|
+
duration_ms?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* ClaudeDaemon class - manages Claude Code subprocess via stream-json
|
|
73
|
+
* @extends EventEmitter
|
|
74
|
+
*
|
|
75
|
+
* @fires ClaudeDaemon#output - When stdout data is received
|
|
76
|
+
* @fires ClaudeDaemon#error - When an error occurs
|
|
77
|
+
* @fires ClaudeDaemon#exit - When the process exits
|
|
78
|
+
*/
|
|
79
|
+
export declare class ClaudeDaemon extends EventEmitter {
|
|
80
|
+
private projectDir;
|
|
81
|
+
private sessionId;
|
|
82
|
+
private process;
|
|
83
|
+
private _pid;
|
|
84
|
+
private _isRunning;
|
|
85
|
+
private buffer;
|
|
86
|
+
/**
|
|
87
|
+
* Create a new ClaudeDaemon instance
|
|
88
|
+
* @param projectDir - Working directory for Claude Code
|
|
89
|
+
* @param sessionId - Unique session identifier
|
|
90
|
+
*/
|
|
91
|
+
constructor(projectDir: string, sessionId: string);
|
|
92
|
+
/**
|
|
93
|
+
* Check if the daemon is currently running
|
|
94
|
+
*/
|
|
95
|
+
get isRunning(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Get the process ID
|
|
98
|
+
*/
|
|
99
|
+
get pid(): number | null;
|
|
100
|
+
/**
|
|
101
|
+
* Spawn the Claude Code subprocess with stream-json mode
|
|
102
|
+
* @returns Promise that resolves when process is ready
|
|
103
|
+
* @throws Error if spawn fails or process is already running
|
|
104
|
+
*/
|
|
105
|
+
spawn(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Send a message to Claude via stdin (stream-json format)
|
|
108
|
+
* @param message - Message to send
|
|
109
|
+
* @throws Error if process is not running
|
|
110
|
+
*/
|
|
111
|
+
send(message: string): void;
|
|
112
|
+
/**
|
|
113
|
+
* Kill the Claude Code subprocess
|
|
114
|
+
* @param signal - Signal to send to process
|
|
115
|
+
*/
|
|
116
|
+
kill(signal?: NodeJS.Signals): void;
|
|
117
|
+
/**
|
|
118
|
+
* Check if the daemon is currently running
|
|
119
|
+
* @returns True if running
|
|
120
|
+
*/
|
|
121
|
+
isActive(): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Get the process ID
|
|
124
|
+
* @returns Process ID or null
|
|
125
|
+
*/
|
|
126
|
+
getPid(): number | null;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Claude Code Daemon - stream-json based subprocess manager
|
|
4
|
+
* @module mobile/daemon
|
|
5
|
+
* @version 1.5.2
|
|
6
|
+
*
|
|
7
|
+
* Manages Claude Code as a subprocess using stream-json mode for
|
|
8
|
+
* bidirectional JSON communication.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { ClaudeDaemon } from './daemon';
|
|
12
|
+
* const daemon = new ClaudeDaemon('/path/to/project', 'session_123');
|
|
13
|
+
* await daemon.spawn();
|
|
14
|
+
* daemon.send('Hello Claude!');
|
|
15
|
+
* daemon.on('output', (data) => console.log(data));
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ClaudeDaemon = exports.ANSI_REGEX = void 0;
|
|
19
|
+
const events_1 = require("events");
|
|
20
|
+
const child_process_1 = require("child_process");
|
|
21
|
+
/**
|
|
22
|
+
* ANSI escape code regex pattern
|
|
23
|
+
*/
|
|
24
|
+
// eslint-disable-next-line no-control-regex
|
|
25
|
+
exports.ANSI_REGEX = /\x1b\[[0-9;]*m/g;
|
|
26
|
+
/**
|
|
27
|
+
* ClaudeDaemon class - manages Claude Code subprocess via stream-json
|
|
28
|
+
* @extends EventEmitter
|
|
29
|
+
*
|
|
30
|
+
* @fires ClaudeDaemon#output - When stdout data is received
|
|
31
|
+
* @fires ClaudeDaemon#error - When an error occurs
|
|
32
|
+
* @fires ClaudeDaemon#exit - When the process exits
|
|
33
|
+
*/
|
|
34
|
+
class ClaudeDaemon extends events_1.EventEmitter {
|
|
35
|
+
projectDir;
|
|
36
|
+
sessionId;
|
|
37
|
+
process;
|
|
38
|
+
_pid;
|
|
39
|
+
_isRunning;
|
|
40
|
+
buffer;
|
|
41
|
+
/**
|
|
42
|
+
* Create a new ClaudeDaemon instance
|
|
43
|
+
* @param projectDir - Working directory for Claude Code
|
|
44
|
+
* @param sessionId - Unique session identifier
|
|
45
|
+
*/
|
|
46
|
+
constructor(projectDir, sessionId) {
|
|
47
|
+
super();
|
|
48
|
+
this.projectDir = projectDir;
|
|
49
|
+
this.sessionId = sessionId;
|
|
50
|
+
this.process = null;
|
|
51
|
+
this._pid = null;
|
|
52
|
+
this._isRunning = false;
|
|
53
|
+
this.buffer = '';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if the daemon is currently running
|
|
57
|
+
*/
|
|
58
|
+
get isRunning() {
|
|
59
|
+
return this._isRunning;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the process ID
|
|
63
|
+
*/
|
|
64
|
+
get pid() {
|
|
65
|
+
return this._pid;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Spawn the Claude Code subprocess with stream-json mode
|
|
69
|
+
* @returns Promise that resolves when process is ready
|
|
70
|
+
* @throws Error if spawn fails or process is already running
|
|
71
|
+
*/
|
|
72
|
+
async spawn() {
|
|
73
|
+
if (this._isRunning) {
|
|
74
|
+
throw new Error('Daemon is already running');
|
|
75
|
+
}
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
let settled = false;
|
|
78
|
+
try {
|
|
79
|
+
// Use stream-json mode for bidirectional JSON communication
|
|
80
|
+
const args = [
|
|
81
|
+
'--dangerously-skip-permissions',
|
|
82
|
+
'--input-format',
|
|
83
|
+
'stream-json',
|
|
84
|
+
'--output-format',
|
|
85
|
+
'stream-json',
|
|
86
|
+
];
|
|
87
|
+
// Spawn Claude Code CLI
|
|
88
|
+
this.process = (0, child_process_1.spawn)('claude', args, {
|
|
89
|
+
cwd: this.projectDir,
|
|
90
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
91
|
+
env: {
|
|
92
|
+
...process.env,
|
|
93
|
+
CLAUDE_CODE_ENTRY_POINT: 'cli',
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
// Store PID
|
|
97
|
+
this._pid = this.process.pid || null;
|
|
98
|
+
this._isRunning = true;
|
|
99
|
+
console.error(`[MobileDaemon] Session ${this.sessionId} spawned with PID ${this._pid} (stream-json mode)`);
|
|
100
|
+
// Handle stdout data (JSON stream)
|
|
101
|
+
this.process.stdout.on('data', (chunk) => {
|
|
102
|
+
this.buffer += chunk.toString();
|
|
103
|
+
// Try to parse complete JSON objects from buffer
|
|
104
|
+
let newlineIndex;
|
|
105
|
+
while ((newlineIndex = this.buffer.indexOf('\n')) !== -1) {
|
|
106
|
+
const line = this.buffer.slice(0, newlineIndex).trim();
|
|
107
|
+
this.buffer = this.buffer.slice(newlineIndex + 1);
|
|
108
|
+
if (line) {
|
|
109
|
+
try {
|
|
110
|
+
const parsed = JSON.parse(line);
|
|
111
|
+
console.error(`[MobileDaemon] Parsed JSON: ${JSON.stringify(parsed).substring(0, 100)}...`);
|
|
112
|
+
// Detect tool usage (content_block_start with tool_use type)
|
|
113
|
+
if (parsed.type === 'content_block_start' &&
|
|
114
|
+
parsed.content_block?.type === 'tool_use') {
|
|
115
|
+
const toolBlock = parsed.content_block;
|
|
116
|
+
console.error(`[MobileDaemon] Tool use detected: ${toolBlock.name}`);
|
|
117
|
+
this.emit('tool_use', {
|
|
118
|
+
tool: toolBlock.name,
|
|
119
|
+
toolId: toolBlock.id,
|
|
120
|
+
input: toolBlock.input,
|
|
121
|
+
sessionId: this.sessionId,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// Detect tool completion (content_block_stop after tool_use)
|
|
125
|
+
if (parsed.type === 'content_block_stop' && parsed.index !== undefined) {
|
|
126
|
+
console.error(`[MobileDaemon] Tool complete for block ${parsed.index}`);
|
|
127
|
+
this.emit('tool_complete', {
|
|
128
|
+
index: parsed.index,
|
|
129
|
+
sessionId: this.sessionId,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// Extract text content from various message types
|
|
133
|
+
let textContent = '';
|
|
134
|
+
if (parsed.type === 'assistant' && parsed.message?.content) {
|
|
135
|
+
// Assistant message with content blocks
|
|
136
|
+
for (const block of parsed.message.content) {
|
|
137
|
+
if (block.type === 'text') {
|
|
138
|
+
textContent += block.text || '';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (parsed.type === 'content_block_delta' && parsed.delta?.text) {
|
|
143
|
+
// Streaming delta
|
|
144
|
+
textContent = parsed.delta.text;
|
|
145
|
+
}
|
|
146
|
+
else if (parsed.result?.content) {
|
|
147
|
+
// Final result
|
|
148
|
+
textContent = parsed.result.content;
|
|
149
|
+
}
|
|
150
|
+
if (textContent) {
|
|
151
|
+
this.emit('output', {
|
|
152
|
+
type: 'stdout',
|
|
153
|
+
text: textContent,
|
|
154
|
+
raw: line,
|
|
155
|
+
parsed,
|
|
156
|
+
sessionId: this.sessionId,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Detect response completion (result message)
|
|
160
|
+
if (parsed.type === 'result') {
|
|
161
|
+
console.error(`[MobileDaemon] Response complete for session ${this.sessionId}`);
|
|
162
|
+
this.emit('response_complete', {
|
|
163
|
+
sessionId: this.sessionId,
|
|
164
|
+
result: parsed.result,
|
|
165
|
+
duration_ms: parsed.duration_ms,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Not valid JSON, emit as raw text
|
|
171
|
+
console.error(`[MobileDaemon] Raw output: ${line.substring(0, 100)}...`);
|
|
172
|
+
this.emit('output', {
|
|
173
|
+
type: 'stdout',
|
|
174
|
+
text: line,
|
|
175
|
+
raw: line,
|
|
176
|
+
sessionId: this.sessionId,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
// Handle stderr data
|
|
183
|
+
this.process.stderr.on('data', (chunk) => {
|
|
184
|
+
const text = chunk.toString();
|
|
185
|
+
console.error(`[MobileDaemon] stderr: ${text.substring(0, 200)}`);
|
|
186
|
+
this.emit('output', {
|
|
187
|
+
type: 'stderr',
|
|
188
|
+
text: text.replace(exports.ANSI_REGEX, ''),
|
|
189
|
+
raw: text,
|
|
190
|
+
sessionId: this.sessionId,
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
// Handle process errors
|
|
194
|
+
this.process.on('error', (err) => {
|
|
195
|
+
console.error(`[MobileDaemon] Error in session ${this.sessionId}:`, err.message);
|
|
196
|
+
this._isRunning = false;
|
|
197
|
+
this.emit('error', {
|
|
198
|
+
error: err,
|
|
199
|
+
sessionId: this.sessionId,
|
|
200
|
+
});
|
|
201
|
+
if (!settled) {
|
|
202
|
+
settled = true;
|
|
203
|
+
reject(err);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
// Handle process exit
|
|
207
|
+
this.process.on('exit', (code, signal) => {
|
|
208
|
+
console.error(`[MobileDaemon] Session ${this.sessionId} exited with code ${code}, signal ${signal}`);
|
|
209
|
+
this._isRunning = false;
|
|
210
|
+
this._pid = null;
|
|
211
|
+
this.emit('exit', {
|
|
212
|
+
code,
|
|
213
|
+
signal,
|
|
214
|
+
sessionId: this.sessionId,
|
|
215
|
+
});
|
|
216
|
+
// Reject if process exits before we resolve
|
|
217
|
+
if (!settled) {
|
|
218
|
+
settled = true;
|
|
219
|
+
reject(new Error(`Process exited with code ${code} before ready`));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
// Process should be ready immediately in stream-json mode
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
if (this._isRunning && !settled) {
|
|
225
|
+
settled = true;
|
|
226
|
+
resolve();
|
|
227
|
+
}
|
|
228
|
+
}, 100);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
232
|
+
console.error(`[MobileDaemon] Failed to spawn session ${this.sessionId}:`, error.message);
|
|
233
|
+
this._isRunning = false;
|
|
234
|
+
this.emit('error', {
|
|
235
|
+
error,
|
|
236
|
+
sessionId: this.sessionId,
|
|
237
|
+
});
|
|
238
|
+
reject(error);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Send a message to Claude via stdin (stream-json format)
|
|
244
|
+
* @param message - Message to send
|
|
245
|
+
* @throws Error if process is not running
|
|
246
|
+
*/
|
|
247
|
+
send(message) {
|
|
248
|
+
if (!this._isRunning || !this.process || !this.process.stdin) {
|
|
249
|
+
throw new Error('Daemon is not running');
|
|
250
|
+
}
|
|
251
|
+
// Send as JSON object with type "user" and nested message object
|
|
252
|
+
const jsonMessage = JSON.stringify({
|
|
253
|
+
type: 'user',
|
|
254
|
+
message: {
|
|
255
|
+
role: 'user',
|
|
256
|
+
content: message,
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
this.process.stdin.write(jsonMessage + '\n');
|
|
260
|
+
console.error(`[MobileDaemon] Sent JSON to session ${this.sessionId}: ${jsonMessage.substring(0, 100)}...`);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Kill the Claude Code subprocess
|
|
264
|
+
* @param signal - Signal to send to process
|
|
265
|
+
*/
|
|
266
|
+
kill(signal = 'SIGTERM') {
|
|
267
|
+
if (!this.process) {
|
|
268
|
+
console.error(`[MobileDaemon] No process to kill for session ${this.sessionId}`);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
console.error(`[MobileDaemon] Killing session ${this.sessionId} with signal ${signal}`);
|
|
273
|
+
this.process.kill(signal);
|
|
274
|
+
// Note: exit event will be emitted by process.on('exit') handler
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
278
|
+
console.error(`[MobileDaemon] Error killing session ${this.sessionId}:`, error.message);
|
|
279
|
+
// Ensure state is consistent even if kill fails
|
|
280
|
+
this._isRunning = false;
|
|
281
|
+
this.emit('error', {
|
|
282
|
+
error,
|
|
283
|
+
sessionId: this.sessionId,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Check if the daemon is currently running
|
|
289
|
+
* @returns True if running
|
|
290
|
+
*/
|
|
291
|
+
isActive() {
|
|
292
|
+
return this._isRunning && this.process !== null;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get the process ID
|
|
296
|
+
* @returns Process ID or null
|
|
297
|
+
*/
|
|
298
|
+
getPid() {
|
|
299
|
+
return this._pid;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
exports.ClaudeDaemon = ClaudeDaemon;
|
|
303
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Output Parser - parses Claude Code stdout into structured events
|
|
3
|
+
* @module mobile/output-parser
|
|
4
|
+
* @version 1.5.0
|
|
5
|
+
*
|
|
6
|
+
* Parses raw stdout from Claude Code CLI, identifying message types
|
|
7
|
+
* such as stream content, tool usage, completion, and errors.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { OutputParser } from './output-parser';
|
|
11
|
+
* const parser = new OutputParser();
|
|
12
|
+
* const events = parser.parse(chunk);
|
|
13
|
+
* // events: [{ type: 'stream', text: '...' }, { type: 'tool_use', tool: 'Read' }]
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Message types returned by the parser
|
|
17
|
+
*/
|
|
18
|
+
export type MessageType = 'stream' | 'tool_use' | 'tool_complete' | 'complete' | 'error';
|
|
19
|
+
/**
|
|
20
|
+
* Parsed output event
|
|
21
|
+
*/
|
|
22
|
+
export interface ParsedEvent {
|
|
23
|
+
type: MessageType;
|
|
24
|
+
text?: string;
|
|
25
|
+
tool?: string;
|
|
26
|
+
status?: string;
|
|
27
|
+
message?: string;
|
|
28
|
+
args?: string | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Tool detection result
|
|
32
|
+
*/
|
|
33
|
+
interface ToolDetectResult {
|
|
34
|
+
tool: string;
|
|
35
|
+
args: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Tool detection patterns
|
|
39
|
+
*/
|
|
40
|
+
export declare const TOOL_PATTERNS: RegExp[];
|
|
41
|
+
/**
|
|
42
|
+
* Error patterns
|
|
43
|
+
*/
|
|
44
|
+
export declare const ERROR_PATTERNS: RegExp[];
|
|
45
|
+
/**
|
|
46
|
+
* Completion/prompt patterns
|
|
47
|
+
*/
|
|
48
|
+
export declare const COMPLETE_PATTERNS: RegExp[];
|
|
49
|
+
/**
|
|
50
|
+
* ANSI escape code regex pattern
|
|
51
|
+
*/
|
|
52
|
+
export declare const ANSI_REGEX: RegExp;
|
|
53
|
+
/**
|
|
54
|
+
* OutputParser class - parses Claude Code stdout
|
|
55
|
+
*/
|
|
56
|
+
export declare class OutputParser {
|
|
57
|
+
private buffer;
|
|
58
|
+
private lastToolDetected;
|
|
59
|
+
/**
|
|
60
|
+
* Create a new OutputParser instance
|
|
61
|
+
*/
|
|
62
|
+
constructor();
|
|
63
|
+
/**
|
|
64
|
+
* Parse a stdout chunk into events
|
|
65
|
+
* @param chunk - Raw stdout data
|
|
66
|
+
* @returns Array of parsed events
|
|
67
|
+
*/
|
|
68
|
+
parse(chunk: string | Buffer): ParsedEvent[];
|
|
69
|
+
/**
|
|
70
|
+
* Remove ANSI escape codes from text
|
|
71
|
+
* @param text - Text with potential ANSI codes
|
|
72
|
+
* @returns Clean text
|
|
73
|
+
*/
|
|
74
|
+
stripAnsi(text: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Detect tool usage pattern in text
|
|
77
|
+
* @param text - Text to analyze
|
|
78
|
+
* @returns Tool info or null
|
|
79
|
+
*/
|
|
80
|
+
detectToolUse(text: string): ToolDetectResult | null;
|
|
81
|
+
/**
|
|
82
|
+
* Detect tool completion pattern in text
|
|
83
|
+
* @param text - Text to analyze
|
|
84
|
+
* @returns Tool name or null
|
|
85
|
+
*/
|
|
86
|
+
detectToolComplete(text: string): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Detect completion pattern in text
|
|
89
|
+
* @param text - Text to analyze
|
|
90
|
+
* @returns True if completion detected
|
|
91
|
+
*/
|
|
92
|
+
detectComplete(text: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Detect error pattern in text
|
|
95
|
+
* @param text - Text to analyze
|
|
96
|
+
* @returns Error message or null
|
|
97
|
+
*/
|
|
98
|
+
detectError(text: string): string | null;
|
|
99
|
+
/**
|
|
100
|
+
* Flush any remaining buffer content
|
|
101
|
+
* @returns Remaining events
|
|
102
|
+
*/
|
|
103
|
+
flush(): ParsedEvent[];
|
|
104
|
+
/**
|
|
105
|
+
* Reset the parser state
|
|
106
|
+
*/
|
|
107
|
+
reset(): void;
|
|
108
|
+
/**
|
|
109
|
+
* Get current buffer content
|
|
110
|
+
* @returns Buffer content
|
|
111
|
+
*/
|
|
112
|
+
getBuffer(): string;
|
|
113
|
+
}
|
|
114
|
+
export {};
|
|
115
|
+
//# sourceMappingURL=output-parser.d.ts.map
|