@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.
Files changed (67) hide show
  1. package/dist/config-loader.d.ts +61 -0
  2. package/dist/config-loader.js +187 -0
  3. package/dist/db-adapter/base-adapter.d.ts +76 -0
  4. package/dist/db-adapter/base-adapter.js +11 -0
  5. package/dist/db-adapter/index.d.ts +24 -0
  6. package/dist/db-adapter/index.js +29 -0
  7. package/dist/db-adapter/sqlite-adapter.d.ts +73 -0
  8. package/dist/db-adapter/sqlite-adapter.js +330 -0
  9. package/dist/db-adapter/statement.d.ts +119 -0
  10. package/dist/db-adapter/statement.js +113 -0
  11. package/dist/db-manager.d.ts +252 -0
  12. package/dist/db-manager.js +622 -0
  13. package/dist/debug-logger.d.ts +32 -0
  14. package/dist/debug-logger.js +83 -0
  15. package/dist/decision-formatter.d.ts +172 -0
  16. package/dist/decision-formatter.js +894 -0
  17. package/dist/decision-tracker.d.ts +218 -0
  18. package/dist/decision-tracker.js +531 -0
  19. package/dist/embedding-cache.d.ts +83 -0
  20. package/dist/embedding-cache.js +182 -0
  21. package/dist/embedding-client.d.ts +43 -0
  22. package/dist/embedding-client.js +132 -0
  23. package/dist/embedding-server/index.d.ts +65 -0
  24. package/dist/embedding-server/index.js +397 -0
  25. package/dist/embedding-server/mobile/auth.d.ts +53 -0
  26. package/dist/embedding-server/mobile/auth.js +140 -0
  27. package/dist/embedding-server/mobile/daemon.d.ts +128 -0
  28. package/dist/embedding-server/mobile/daemon.js +303 -0
  29. package/dist/embedding-server/mobile/output-parser.d.ts +115 -0
  30. package/dist/embedding-server/mobile/output-parser.js +241 -0
  31. package/dist/embedding-server/mobile/session-api.d.ts +57 -0
  32. package/dist/embedding-server/mobile/session-api.js +261 -0
  33. package/dist/embedding-server/mobile/session-manager.d.ts +135 -0
  34. package/dist/embedding-server/mobile/session-manager.js +333 -0
  35. package/dist/embedding-server/mobile/websocket-handler.d.ts +127 -0
  36. package/dist/embedding-server/mobile/websocket-handler.js +435 -0
  37. package/dist/embeddings.d.ts +75 -0
  38. package/dist/embeddings.js +262 -0
  39. package/dist/errors.d.ts +131 -0
  40. package/dist/errors.js +225 -0
  41. package/dist/index.d.ts +32 -0
  42. package/dist/index.js +193 -0
  43. package/dist/mama-api.d.ts +954 -0
  44. package/dist/mama-api.js +2210 -0
  45. package/dist/memory-inject.d.ts +24 -0
  46. package/dist/memory-inject.js +116 -0
  47. package/dist/memory-store.d.ts +103 -0
  48. package/dist/memory-store.js +129 -0
  49. package/dist/notification-manager.d.ts +7 -0
  50. package/dist/notification-manager.js +12 -0
  51. package/dist/ollama-client.d.ts +51 -0
  52. package/dist/ollama-client.js +308 -0
  53. package/dist/outcome-tracker.d.ts +165 -0
  54. package/dist/outcome-tracker.js +315 -0
  55. package/dist/progress-indicator.d.ts +48 -0
  56. package/dist/progress-indicator.js +82 -0
  57. package/dist/query-intent.d.ts +27 -0
  58. package/dist/query-intent.js +144 -0
  59. package/dist/relevance-scorer.d.ts +124 -0
  60. package/dist/relevance-scorer.js +243 -0
  61. package/dist/test-utils.d.ts +66 -0
  62. package/dist/test-utils.js +166 -0
  63. package/dist/tier-validator.d.ts +55 -0
  64. package/dist/tier-validator.js +216 -0
  65. package/dist/time-formatter.d.ts +25 -0
  66. package/dist/time-formatter.js +93 -0
  67. 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