@loom-framework/core 0.1.0-alpha.6 → 0.1.0-alpha.61

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 (162) hide show
  1. package/dist/adapter-base.d.ts +29 -0
  2. package/dist/adapter-base.d.ts.map +1 -0
  3. package/dist/adapter-base.js +62 -0
  4. package/dist/adapter-base.js.map +1 -0
  5. package/dist/adapter-factory.d.ts +8 -0
  6. package/dist/adapter-factory.d.ts.map +1 -0
  7. package/dist/adapter-factory.js +25 -0
  8. package/dist/adapter-factory.js.map +1 -0
  9. package/dist/adapter-filesystem.d.ts +6 -11
  10. package/dist/adapter-filesystem.d.ts.map +1 -1
  11. package/dist/adapter-filesystem.js +17 -38
  12. package/dist/adapter-filesystem.js.map +1 -1
  13. package/dist/adapter-sqlite.d.ts +6 -23
  14. package/dist/adapter-sqlite.d.ts.map +1 -1
  15. package/dist/adapter-sqlite.js +45 -50
  16. package/dist/adapter-sqlite.js.map +1 -1
  17. package/dist/backend/ai/button-resolver.d.ts +18 -0
  18. package/dist/backend/ai/button-resolver.d.ts.map +1 -0
  19. package/dist/backend/ai/button-resolver.js +58 -0
  20. package/dist/backend/ai/button-resolver.js.map +1 -0
  21. package/dist/backend/ai/engine.d.ts +52 -0
  22. package/dist/backend/ai/engine.d.ts.map +1 -0
  23. package/dist/backend/ai/engine.js +189 -0
  24. package/dist/backend/ai/engine.js.map +1 -0
  25. package/dist/backend/ai/index.d.ts +11 -0
  26. package/dist/backend/ai/index.d.ts.map +1 -0
  27. package/dist/backend/ai/index.js +8 -0
  28. package/dist/backend/ai/index.js.map +1 -0
  29. package/dist/backend/ai/output-parser.d.ts +29 -0
  30. package/dist/backend/ai/output-parser.d.ts.map +1 -0
  31. package/dist/backend/ai/output-parser.js +247 -0
  32. package/dist/backend/ai/output-parser.js.map +1 -0
  33. package/dist/backend/ai/session-manager.d.ts +103 -0
  34. package/dist/backend/ai/session-manager.d.ts.map +1 -0
  35. package/dist/backend/ai/session-manager.js +298 -0
  36. package/dist/backend/ai/session-manager.js.map +1 -0
  37. package/dist/backend/index.d.ts +61 -0
  38. package/dist/backend/index.d.ts.map +1 -0
  39. package/dist/backend/index.js +160 -0
  40. package/dist/backend/index.js.map +1 -0
  41. package/dist/backend/observe/index.d.ts +6 -0
  42. package/dist/backend/observe/index.d.ts.map +1 -0
  43. package/dist/backend/observe/index.js +5 -0
  44. package/dist/backend/observe/index.js.map +1 -0
  45. package/dist/backend/observe/logger.d.ts +28 -0
  46. package/dist/backend/observe/logger.d.ts.map +1 -0
  47. package/dist/backend/observe/logger.js +80 -0
  48. package/dist/backend/observe/logger.js.map +1 -0
  49. package/dist/backend/observe/types.d.ts +26 -0
  50. package/dist/backend/observe/types.d.ts.map +1 -0
  51. package/dist/backend/observe/types.js +7 -0
  52. package/dist/backend/observe/types.js.map +1 -0
  53. package/dist/backend/routes/chat.d.ts +31 -0
  54. package/dist/backend/routes/chat.d.ts.map +1 -0
  55. package/dist/backend/routes/chat.js +426 -0
  56. package/dist/backend/routes/chat.js.map +1 -0
  57. package/dist/backend/routes/data.d.ts +13 -0
  58. package/dist/backend/routes/data.d.ts.map +1 -0
  59. package/dist/backend/routes/data.js +129 -0
  60. package/dist/backend/routes/data.js.map +1 -0
  61. package/dist/backend/routes/health.d.ts +7 -0
  62. package/dist/backend/routes/health.d.ts.map +1 -0
  63. package/dist/backend/routes/health.js +15 -0
  64. package/dist/backend/routes/health.js.map +1 -0
  65. package/dist/backend/routes/index.d.ts +9 -0
  66. package/dist/backend/routes/index.d.ts.map +1 -0
  67. package/dist/backend/routes/index.js +8 -0
  68. package/dist/backend/routes/index.js.map +1 -0
  69. package/dist/backend/routes/upload.d.ts +24 -0
  70. package/dist/backend/routes/upload.d.ts.map +1 -0
  71. package/dist/backend/routes/upload.js +67 -0
  72. package/dist/backend/routes/upload.js.map +1 -0
  73. package/dist/bin.d.ts +8 -0
  74. package/dist/bin.d.ts.map +1 -0
  75. package/dist/bin.js +12 -0
  76. package/dist/bin.js.map +1 -0
  77. package/dist/capability-generator.d.ts +16 -6
  78. package/dist/capability-generator.d.ts.map +1 -1
  79. package/dist/capability-generator.js +160 -248
  80. package/dist/capability-generator.js.map +1 -1
  81. package/dist/cli/commands/build.d.ts +11 -0
  82. package/dist/cli/commands/build.d.ts.map +1 -0
  83. package/dist/cli/commands/build.js +170 -0
  84. package/dist/cli/commands/build.js.map +1 -0
  85. package/dist/cli/commands/data.d.ts +12 -0
  86. package/dist/cli/commands/data.d.ts.map +1 -0
  87. package/dist/cli/commands/data.js +158 -0
  88. package/dist/cli/commands/data.js.map +1 -0
  89. package/dist/cli/commands/dev.d.ts +9 -0
  90. package/dist/cli/commands/dev.d.ts.map +1 -0
  91. package/dist/cli/commands/dev.js +114 -0
  92. package/dist/cli/commands/dev.js.map +1 -0
  93. package/dist/cli/commands/generate-capabilities.d.ts +8 -0
  94. package/dist/cli/commands/generate-capabilities.d.ts.map +1 -0
  95. package/dist/cli/commands/generate-capabilities.js +40 -0
  96. package/dist/cli/commands/generate-capabilities.js.map +1 -0
  97. package/dist/cli/commands/generate-cli-command.d.ts +8 -0
  98. package/dist/cli/commands/generate-cli-command.d.ts.map +1 -0
  99. package/dist/cli/commands/generate-cli-command.js +64 -0
  100. package/dist/cli/commands/generate-cli-command.js.map +1 -0
  101. package/dist/cli/commands/generate-page.d.ts +9 -0
  102. package/dist/cli/commands/generate-page.d.ts.map +1 -0
  103. package/dist/cli/commands/generate-page.js +418 -0
  104. package/dist/cli/commands/generate-page.js.map +1 -0
  105. package/dist/cli/commands/generate-skill.d.ts +8 -0
  106. package/dist/cli/commands/generate-skill.d.ts.map +1 -0
  107. package/dist/cli/commands/generate-skill.js +75 -0
  108. package/dist/cli/commands/generate-skill.js.map +1 -0
  109. package/dist/cli/commands/generate.d.ts +6 -0
  110. package/dist/cli/commands/generate.d.ts.map +1 -0
  111. package/dist/cli/commands/generate.js +17 -0
  112. package/dist/cli/commands/generate.js.map +1 -0
  113. package/dist/cli/commands/init.d.ts +8 -0
  114. package/dist/cli/commands/init.d.ts.map +1 -0
  115. package/dist/cli/commands/init.js +539 -0
  116. package/dist/cli/commands/init.js.map +1 -0
  117. package/dist/cli/commands/observe.d.ts +9 -0
  118. package/dist/cli/commands/observe.d.ts.map +1 -0
  119. package/dist/cli/commands/observe.js +142 -0
  120. package/dist/cli/commands/observe.js.map +1 -0
  121. package/dist/cli/commands/skill.d.ts +9 -0
  122. package/dist/cli/commands/skill.d.ts.map +1 -0
  123. package/dist/cli/commands/skill.js +186 -0
  124. package/dist/cli/commands/skill.js.map +1 -0
  125. package/dist/cli/helpers/duration.d.ts +5 -0
  126. package/dist/cli/helpers/duration.d.ts.map +1 -0
  127. package/dist/cli/helpers/duration.js +19 -0
  128. package/dist/cli/helpers/duration.js.map +1 -0
  129. package/dist/cli/helpers/field-template.d.ts +9 -0
  130. package/dist/cli/helpers/field-template.d.ts.map +1 -0
  131. package/dist/cli/helpers/field-template.js +92 -0
  132. package/dist/cli/helpers/field-template.js.map +1 -0
  133. package/dist/cli/helpers/naming.d.ts +12 -0
  134. package/dist/cli/helpers/naming.d.ts.map +1 -0
  135. package/dist/cli/helpers/naming.js +25 -0
  136. package/dist/cli/helpers/naming.js.map +1 -0
  137. package/dist/cli/index.d.ts +9 -0
  138. package/dist/cli/index.d.ts.map +1 -0
  139. package/dist/cli/index.js +33 -0
  140. package/dist/cli/index.js.map +1 -0
  141. package/dist/cli/utils.d.ts +10 -0
  142. package/dist/cli/utils.d.ts.map +1 -0
  143. package/dist/cli/utils.js +31 -0
  144. package/dist/cli/utils.js.map +1 -0
  145. package/dist/config.d.ts +8 -33
  146. package/dist/config.d.ts.map +1 -1
  147. package/dist/config.js +6 -7
  148. package/dist/config.js.map +1 -1
  149. package/dist/index.d.ts +6 -1
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +6 -0
  152. package/dist/index.js.map +1 -1
  153. package/dist/server-bin.d.ts +12 -0
  154. package/dist/server-bin.d.ts.map +1 -0
  155. package/dist/server-bin.js +75 -0
  156. package/dist/server-bin.js.map +1 -0
  157. package/dist/types.d.ts +28 -18
  158. package/dist/types.d.ts.map +1 -1
  159. package/package.json +17 -4
  160. package/templates/skill/SKILL.md +140 -0
  161. package/templates/skill/references/README.md +128 -0
  162. package/templates/skill/references/data-model.md +78 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../../../src/backend/ai/output-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Session Manager
3
+ *
4
+ * Manages AI sessions with lazy creation.
5
+ * Sessions are persisted to .loom/sessions/ as JSON files.
6
+ */
7
+ import type { AIUsage } from '../../index.js';
8
+ /** On-disk session record */
9
+ export interface SessionRecord {
10
+ id: string;
11
+ claudeSessionId?: string;
12
+ title: string;
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ messages: SessionMessage[];
16
+ usage?: AIUsage;
17
+ }
18
+ export interface ContentBlock {
19
+ type: 'thinking' | 'content' | 'tool_call';
20
+ thinking?: string;
21
+ content?: string;
22
+ tool?: string;
23
+ toolUseId?: string;
24
+ toolInput?: unknown;
25
+ result?: unknown;
26
+ status?: 'started' | 'completed' | 'error';
27
+ error?: string;
28
+ }
29
+ export interface SessionMessage {
30
+ id: string;
31
+ role: 'user' | 'assistant';
32
+ content: string;
33
+ timestamp: string;
34
+ files?: SessionFileRef[];
35
+ contentBlocks?: ContentBlock[];
36
+ }
37
+ export interface SessionFileRef {
38
+ uid: string;
39
+ name: string;
40
+ size: number;
41
+ type: string;
42
+ url?: string;
43
+ }
44
+ export declare class SessionManager {
45
+ private sessionsDir;
46
+ /** In-memory session index for fast listing */
47
+ private sessionIndex;
48
+ /** Per-session mutex locks to prevent read-modify-write race conditions */
49
+ private locks;
50
+ constructor(projectRoot: string);
51
+ /**
52
+ * Acquire a per-key mutex lock. Prevents concurrent read-modify-write on the same session.
53
+ */
54
+ private withLock;
55
+ /**
56
+ * Ensure sessions directory exists and load index
57
+ */
58
+ initialize(): Promise<void>;
59
+ /**
60
+ * Create a new session on demand (lazy, no pre-allocation)
61
+ * Safe against race conditions: checks if session already exists before creating.
62
+ */
63
+ createSession(id?: string): Promise<SessionRecord>;
64
+ /**
65
+ * Read a session by ID
66
+ */
67
+ readSession(id: string): Promise<SessionRecord | null>;
68
+ /**
69
+ * Add messages to a session and update claudeSessionId
70
+ */
71
+ addMessages(id: string, messages: SessionMessage[], claudeSessionId?: string, usage?: AIUsage): Promise<SessionRecord>;
72
+ /**
73
+ * List all sessions sorted by most recent first (from index, O(1))
74
+ */
75
+ listSessions(): Promise<SessionRecord[]>;
76
+ /**
77
+ * List full session records from files (fallback, used during initialization)
78
+ */
79
+ private listSessionsFromFiles;
80
+ /**
81
+ * Delete a single message from a session
82
+ */
83
+ deleteMessage(sessionId: string, messageId: string): Promise<SessionRecord | null>;
84
+ /**
85
+ * Truncate all messages from a given message index onward (inclusive).
86
+ * Returns the updated session, or null if session not found.
87
+ */
88
+ truncateMessagesFromIndex(sessionId: string, fromIndex: number): Promise<SessionRecord | null>;
89
+ /**
90
+ * Delete a session
91
+ */
92
+ deleteSession(id: string): Promise<boolean>;
93
+ /**
94
+ * Get or create a session by ID
95
+ */
96
+ getOrCreate(id: string): Promise<SessionRecord>;
97
+ private getSessionPath;
98
+ private writeSessionFile;
99
+ private getIndexFilePath;
100
+ private loadIndex;
101
+ private saveIndex;
102
+ }
103
+ //# sourceMappingURL=session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../src/backend/ai/session-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Session Manager
3
+ *
4
+ * Manages AI sessions with lazy creation.
5
+ * Sessions are persisted to .loom/sessions/ as JSON files.
6
+ */
7
+ import { promises as fs } from 'fs';
8
+ import path from 'path';
9
+ export class SessionManager {
10
+ sessionsDir;
11
+ /** In-memory session index for fast listing */
12
+ sessionIndex = { sessions: [], lastUpdated: '' };
13
+ /** Per-session mutex locks to prevent read-modify-write race conditions */
14
+ locks = new Map();
15
+ constructor(projectRoot) {
16
+ this.sessionsDir = path.join(projectRoot, '.loom', 'sessions');
17
+ }
18
+ /**
19
+ * Acquire a per-key mutex lock. Prevents concurrent read-modify-write on the same session.
20
+ */
21
+ async withLock(key, fn) {
22
+ // Wait for any existing lock to release
23
+ while (this.locks.has(key)) {
24
+ await this.locks.get(key);
25
+ }
26
+ // Acquire lock
27
+ let resolve;
28
+ const promise = new Promise((r) => { resolve = r; });
29
+ this.locks.set(key, promise);
30
+ try {
31
+ return await fn();
32
+ }
33
+ finally {
34
+ this.locks.delete(key);
35
+ resolve();
36
+ }
37
+ }
38
+ /**
39
+ * Ensure sessions directory exists and load index
40
+ */
41
+ async initialize() {
42
+ await fs.mkdir(this.sessionsDir, { recursive: true });
43
+ // Try to load index from disk
44
+ const indexLoaded = await this.loadIndex();
45
+ if (!indexLoaded) {
46
+ // Fallback: rebuild index from session files
47
+ const sessions = await this.listSessionsFromFiles();
48
+ this.sessionIndex = {
49
+ sessions: sessions.map((s) => ({
50
+ id: s.id,
51
+ title: s.title,
52
+ updatedAt: s.updatedAt,
53
+ createdAt: s.createdAt,
54
+ })),
55
+ lastUpdated: new Date().toISOString(),
56
+ };
57
+ await this.saveIndex();
58
+ }
59
+ }
60
+ /**
61
+ * Create a new session on demand (lazy, no pre-allocation)
62
+ * Safe against race conditions: checks if session already exists before creating.
63
+ */
64
+ async createSession(id) {
65
+ const sessionId = id || generateSessionId();
66
+ return this.withLock(sessionId, async () => {
67
+ // Check if session already exists (handles getOrCreate race condition)
68
+ const existing = await this.readSession(sessionId);
69
+ if (existing)
70
+ return existing;
71
+ const now = new Date().toISOString();
72
+ const session = {
73
+ id: sessionId,
74
+ title: 'New Session',
75
+ createdAt: now,
76
+ updatedAt: now,
77
+ messages: [],
78
+ };
79
+ await this.writeSessionFile(session);
80
+ // Update index (avoid duplicates)
81
+ if (!this.sessionIndex.sessions.some(e => e.id === sessionId)) {
82
+ this.sessionIndex.sessions.push({
83
+ id: sessionId,
84
+ title: session.title,
85
+ updatedAt: session.updatedAt,
86
+ createdAt: session.createdAt,
87
+ });
88
+ this.sessionIndex.lastUpdated = new Date().toISOString();
89
+ await this.saveIndex();
90
+ }
91
+ return session;
92
+ });
93
+ }
94
+ /**
95
+ * Read a session by ID
96
+ */
97
+ async readSession(id) {
98
+ const filePath = this.getSessionPath(id);
99
+ try {
100
+ const content = await fs.readFile(filePath, 'utf-8');
101
+ return JSON.parse(content);
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ /**
108
+ * Add messages to a session and update claudeSessionId
109
+ */
110
+ async addMessages(id, messages, claudeSessionId, usage) {
111
+ return this.withLock(id, async () => {
112
+ const session = await this.readSession(id);
113
+ if (!session) {
114
+ throw new Error(`Session not found: ${id}`);
115
+ }
116
+ session.messages.push(...messages);
117
+ session.updatedAt = new Date().toISOString();
118
+ if (claudeSessionId) {
119
+ session.claudeSessionId = claudeSessionId;
120
+ }
121
+ if (usage) {
122
+ session.usage = usage;
123
+ }
124
+ // Auto-title from first user message
125
+ if (session.title === 'New Session' && session.messages.length > 0) {
126
+ const firstUser = session.messages.find((m) => m.role === 'user');
127
+ if (firstUser) {
128
+ session.title = firstUser.content.slice(0, 80) + (firstUser.content.length > 80 ? '...' : '');
129
+ }
130
+ }
131
+ await this.writeSessionFile(session);
132
+ // Sync index entry (title may have changed)
133
+ const idxEntry = this.sessionIndex.sessions.find((e) => e.id === id);
134
+ if (idxEntry) {
135
+ idxEntry.title = session.title;
136
+ idxEntry.updatedAt = session.updatedAt;
137
+ }
138
+ this.sessionIndex.lastUpdated = new Date().toISOString();
139
+ await this.saveIndex();
140
+ return session;
141
+ });
142
+ }
143
+ /**
144
+ * List all sessions sorted by most recent first (from index, O(1))
145
+ */
146
+ async listSessions() {
147
+ // Use index for fast path: only return summary data
148
+ // For full records, callers should use readSession(id)
149
+ const entries = [...this.sessionIndex.sessions];
150
+ entries.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
151
+ // Map index entries to minimal SessionRecord shape
152
+ return entries.map((e) => ({
153
+ id: e.id,
154
+ title: e.title,
155
+ createdAt: e.createdAt,
156
+ updatedAt: e.updatedAt,
157
+ messages: [],
158
+ }));
159
+ }
160
+ /**
161
+ * List full session records from files (fallback, used during initialization)
162
+ */
163
+ async listSessionsFromFiles() {
164
+ try {
165
+ const files = await fs.readdir(this.sessionsDir);
166
+ const sessions = [];
167
+ for (const file of files) {
168
+ if (file === 'index.json')
169
+ continue;
170
+ if (!file.endsWith('.json'))
171
+ continue;
172
+ const filePath = path.join(this.sessionsDir, file);
173
+ try {
174
+ const content = await fs.readFile(filePath, 'utf-8');
175
+ sessions.push(JSON.parse(content));
176
+ }
177
+ catch {
178
+ // Skip malformed files
179
+ }
180
+ }
181
+ sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
182
+ return sessions;
183
+ }
184
+ catch {
185
+ return [];
186
+ }
187
+ }
188
+ /**
189
+ * Delete a single message from a session
190
+ */
191
+ async deleteMessage(sessionId, messageId) {
192
+ return this.withLock(sessionId, async () => {
193
+ const session = await this.readSession(sessionId);
194
+ if (!session)
195
+ return null;
196
+ const originalLen = session.messages.length;
197
+ session.messages = session.messages.filter((m) => m.id !== messageId);
198
+ if (session.messages.length === originalLen)
199
+ return null; // message not found
200
+ session.updatedAt = new Date().toISOString();
201
+ await this.writeSessionFile(session);
202
+ // Sync index
203
+ const idxEntry = this.sessionIndex.sessions.find((e) => e.id === sessionId);
204
+ if (idxEntry) {
205
+ idxEntry.updatedAt = session.updatedAt;
206
+ }
207
+ this.sessionIndex.lastUpdated = new Date().toISOString();
208
+ await this.saveIndex();
209
+ return session;
210
+ });
211
+ }
212
+ /**
213
+ * Truncate all messages from a given message index onward (inclusive).
214
+ * Returns the updated session, or null if session not found.
215
+ */
216
+ async truncateMessagesFromIndex(sessionId, fromIndex) {
217
+ return this.withLock(sessionId, async () => {
218
+ const session = await this.readSession(sessionId);
219
+ if (!session)
220
+ return null;
221
+ if (fromIndex < 0 || fromIndex >= session.messages.length)
222
+ return null;
223
+ session.messages = session.messages.slice(0, fromIndex);
224
+ session.updatedAt = new Date().toISOString();
225
+ await this.writeSessionFile(session);
226
+ // Sync index
227
+ const idxEntry = this.sessionIndex.sessions.find((e) => e.id === sessionId);
228
+ if (idxEntry) {
229
+ idxEntry.updatedAt = session.updatedAt;
230
+ }
231
+ this.sessionIndex.lastUpdated = new Date().toISOString();
232
+ await this.saveIndex();
233
+ return session;
234
+ });
235
+ }
236
+ /**
237
+ * Delete a session
238
+ */
239
+ async deleteSession(id) {
240
+ return this.withLock(id, async () => {
241
+ const filePath = this.getSessionPath(id);
242
+ try {
243
+ await fs.unlink(filePath);
244
+ // Sync index
245
+ this.sessionIndex.sessions = this.sessionIndex.sessions.filter((e) => e.id !== id);
246
+ this.sessionIndex.lastUpdated = new Date().toISOString();
247
+ await this.saveIndex();
248
+ return true;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ });
254
+ }
255
+ /**
256
+ * Get or create a session by ID
257
+ */
258
+ async getOrCreate(id) {
259
+ const existing = await this.readSession(id);
260
+ if (existing)
261
+ return existing;
262
+ return this.createSession(id);
263
+ }
264
+ getSessionPath(id) {
265
+ return path.join(this.sessionsDir, `${id}.json`);
266
+ }
267
+ async writeSessionFile(session) {
268
+ const filePath = this.getSessionPath(session.id);
269
+ await fs.mkdir(this.sessionsDir, { recursive: true });
270
+ await fs.writeFile(filePath, JSON.stringify(session, null, 2), 'utf-8');
271
+ }
272
+ getIndexFilePath() {
273
+ return path.join(this.sessionsDir, 'index.json');
274
+ }
275
+ async loadIndex() {
276
+ try {
277
+ const content = await fs.readFile(this.getIndexFilePath(), 'utf-8');
278
+ this.sessionIndex = JSON.parse(content);
279
+ return true;
280
+ }
281
+ catch {
282
+ return false;
283
+ }
284
+ }
285
+ async saveIndex() {
286
+ try {
287
+ await fs.mkdir(this.sessionsDir, { recursive: true });
288
+ await fs.writeFile(this.getIndexFilePath(), JSON.stringify(this.sessionIndex, null, 2), 'utf-8');
289
+ }
290
+ catch {
291
+ // Non-critical: index is in-memory, will rebuild on next init
292
+ }
293
+ }
294
+ }
295
+ function generateSessionId() {
296
+ return `session_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
297
+ }
298
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../src/backend/ai/session-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @loom-framework/backend - Main Server
3
+ *
4
+ * Assembles Fastify server with:
5
+ * - HTTP SSE chat route (Ant Design X compatible)
6
+ * - REST routes for DataAdapter CRUD + health check + sessions
7
+ * - Static file serving for production mode
8
+ * - Configuration from loom.config.ts
9
+ */
10
+ import Fastify from 'fastify';
11
+ import type { LoomConfig, AIEngine, DataAdapter, ServerConfig } from '../index.js';
12
+ export interface LoomServerOptions {
13
+ /** Project root directory containing loom.config.ts */
14
+ projectRoot: string;
15
+ /** Override server config (merges over config file) */
16
+ serverConfig?: Partial<ServerConfig>;
17
+ /** Custom AI engine (defaults to ClaudeCodeEngine from config) */
18
+ engine?: AIEngine;
19
+ /** Custom DataAdapter (defaults to FileSystemAdapter from config) */
20
+ adapter?: DataAdapter;
21
+ /** Logger level */
22
+ logLevel?: string;
23
+ }
24
+ export declare class LoomServer {
25
+ private config;
26
+ private engine;
27
+ private adapter;
28
+ private sessionManager;
29
+ private interactionLogger;
30
+ private fastify;
31
+ private projectRoot;
32
+ private options;
33
+ constructor(options: LoomServerOptions);
34
+ /**
35
+ * Initialize server: load config, create engine/adapter, register routes
36
+ */
37
+ initialize(): Promise<void>;
38
+ /**
39
+ * Start listening
40
+ */
41
+ start(): Promise<void>;
42
+ /**
43
+ * Stop the server
44
+ */
45
+ stop(): Promise<void>;
46
+ /** Expose Fastify instance for testing */
47
+ getFastify(): ReturnType<typeof Fastify>;
48
+ /** Expose config for testing */
49
+ getConfig(): LoomConfig;
50
+ /** Expose adapter for testing */
51
+ getAdapter(): DataAdapter;
52
+ /**
53
+ * Create DataAdapter based on config.data.defaultAdapter
54
+ */
55
+ private createAdapter;
56
+ }
57
+ /**
58
+ * Create and start a LoomServer from a project root
59
+ */
60
+ export declare function startServer(projectRoot: string): Promise<LoomServer>;
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQnF,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAoB;gBAEvB,OAAO,EAAE,iBAAiB;IAKtC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsFjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,0CAA0C;IAC1C,UAAU,IAAI,UAAU,CAAC,OAAO,OAAO,CAAC;IAIxC,gCAAgC;IAChC,SAAS,IAAI,UAAU;IAIvB,iCAAiC;IACjC,UAAU,IAAI,WAAW;IAIzB;;OAEG;IACH,OAAO,CAAC,aAAa;CAUtB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAK1E"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * @loom-framework/backend - Main Server
3
+ *
4
+ * Assembles Fastify server with:
5
+ * - HTTP SSE chat route (Ant Design X compatible)
6
+ * - REST routes for DataAdapter CRUD + health check + sessions
7
+ * - Static file serving for production mode
8
+ * - Configuration from loom.config.ts
9
+ */
10
+ import Fastify from 'fastify';
11
+ import cors from '@fastify/cors';
12
+ import staticPlugin from '@fastify/static';
13
+ import path from 'path';
14
+ import { FileSystemAdapter, loadConfig, SQLiteAdapter } from '../index.js';
15
+ import { ClaudeCodeEngine } from './ai/engine.js';
16
+ import { SessionManager } from './ai/session-manager.js';
17
+ import { AIInteractionLogger } from './observe/index.js';
18
+ import { registerDataRoutes, registerHealthRoute, registerUploadRoutes, registerChatRoutes } from './routes/index.js';
19
+ export class LoomServer {
20
+ config;
21
+ engine;
22
+ adapter;
23
+ sessionManager;
24
+ interactionLogger;
25
+ fastify;
26
+ projectRoot;
27
+ options;
28
+ constructor(options) {
29
+ this.projectRoot = options.projectRoot;
30
+ this.options = options;
31
+ }
32
+ /**
33
+ * Initialize server: load config, create engine/adapter, register routes
34
+ */
35
+ async initialize() {
36
+ // Load config
37
+ this.config = await loadConfig(this.projectRoot);
38
+ const serverConfig = {
39
+ ...this.config.server,
40
+ ...this.options.serverConfig,
41
+ };
42
+ // Create Fastify instance
43
+ this.fastify = Fastify({
44
+ logger: {
45
+ level: this.options.logLevel || serverConfig.logLevel || 'info',
46
+ },
47
+ });
48
+ // Global error handler - provides structured error responses
49
+ this.fastify.setErrorHandler((error, _request, reply) => {
50
+ if (error.validation) {
51
+ reply.status(400).send({ error: 'Validation error', details: error.validation });
52
+ return;
53
+ }
54
+ this.fastify.log.error(error);
55
+ const statusCode = error.statusCode || 500;
56
+ reply.status(statusCode).send({
57
+ error: statusCode === 500 ? 'Internal server error' : error.message,
58
+ });
59
+ });
60
+ // Initialize DataAdapter based on config
61
+ this.adapter = this.options.adapter || this.createAdapter(this.config);
62
+ await this.adapter.initialize();
63
+ // Initialize AI Engine
64
+ this.engine = this.options.engine || new ClaudeCodeEngine({
65
+ config: this.config.ai?.claudeCode || {},
66
+ projectRoot: this.projectRoot,
67
+ });
68
+ // Initialize Session Manager
69
+ this.sessionManager = new SessionManager(this.projectRoot);
70
+ await this.sessionManager.initialize();
71
+ // Initialize Interaction Logger
72
+ this.interactionLogger = new AIInteractionLogger(this.projectRoot);
73
+ await this.interactionLogger.initialize();
74
+ // Register plugins
75
+ if (serverConfig.cors !== false) {
76
+ await this.fastify.register(cors, { origin: true });
77
+ }
78
+ // Static file serving in production
79
+ if (serverConfig.staticDir) {
80
+ const staticDir = path.resolve(this.projectRoot, serverConfig.staticDir);
81
+ await this.fastify.register(staticPlugin, {
82
+ root: staticDir,
83
+ prefix: '/',
84
+ wildcard: false,
85
+ });
86
+ }
87
+ // Register routes
88
+ registerHealthRoute(this.fastify, this.adapter);
89
+ registerDataRoutes(this.fastify, this.adapter);
90
+ registerUploadRoutes(this.fastify, { projectRoot: this.projectRoot });
91
+ registerChatRoutes(this.fastify, {
92
+ engine: this.engine,
93
+ sessionManager: this.sessionManager,
94
+ config: this.config,
95
+ logger: this.interactionLogger,
96
+ projectRoot: this.projectRoot,
97
+ });
98
+ // Graceful shutdown handlers
99
+ const cleanup = async () => {
100
+ if (this.engine instanceof ClaudeCodeEngine) {
101
+ this.engine.killAll();
102
+ }
103
+ await this.fastify.close();
104
+ };
105
+ process.on('SIGINT', cleanup);
106
+ process.on('SIGTERM', cleanup);
107
+ }
108
+ /**
109
+ * Start listening
110
+ */
111
+ async start() {
112
+ const port = this.config.server?.port || 3000;
113
+ const host = this.config.server?.host || '0.0.0.0';
114
+ await this.fastify.listen({ port, host });
115
+ }
116
+ /**
117
+ * Stop the server
118
+ */
119
+ async stop() {
120
+ if (this.engine instanceof ClaudeCodeEngine) {
121
+ this.engine.killAll();
122
+ }
123
+ await this.fastify.close();
124
+ }
125
+ /** Expose Fastify instance for testing */
126
+ getFastify() {
127
+ return this.fastify;
128
+ }
129
+ /** Expose config for testing */
130
+ getConfig() {
131
+ return this.config;
132
+ }
133
+ /** Expose adapter for testing */
134
+ getAdapter() {
135
+ return this.adapter;
136
+ }
137
+ /**
138
+ * Create DataAdapter based on config.data.defaultAdapter
139
+ */
140
+ createAdapter(config) {
141
+ if (config.data.defaultAdapter === 'sqlite') {
142
+ const dbPath = path.join(this.projectRoot, config.data.sqlite?.filename || 'data/loom.db');
143
+ return new SQLiteAdapter({ dbPath, config });
144
+ }
145
+ return new FileSystemAdapter({
146
+ dataDir: path.join(this.projectRoot, 'data'),
147
+ config,
148
+ });
149
+ }
150
+ }
151
+ /**
152
+ * Create and start a LoomServer from a project root
153
+ */
154
+ export async function startServer(projectRoot) {
155
+ const server = new LoomServer({ projectRoot });
156
+ await server.initialize();
157
+ await server.start();
158
+ return server;
159
+ }
160
+ //# sourceMappingURL=index.js.map