@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.
- package/dist/adapter-base.d.ts +29 -0
- package/dist/adapter-base.d.ts.map +1 -0
- package/dist/adapter-base.js +62 -0
- package/dist/adapter-base.js.map +1 -0
- package/dist/adapter-factory.d.ts +8 -0
- package/dist/adapter-factory.d.ts.map +1 -0
- package/dist/adapter-factory.js +25 -0
- package/dist/adapter-factory.js.map +1 -0
- package/dist/adapter-filesystem.d.ts +6 -11
- package/dist/adapter-filesystem.d.ts.map +1 -1
- package/dist/adapter-filesystem.js +17 -38
- package/dist/adapter-filesystem.js.map +1 -1
- package/dist/adapter-sqlite.d.ts +6 -23
- package/dist/adapter-sqlite.d.ts.map +1 -1
- package/dist/adapter-sqlite.js +45 -50
- package/dist/adapter-sqlite.js.map +1 -1
- package/dist/backend/ai/button-resolver.d.ts +18 -0
- package/dist/backend/ai/button-resolver.d.ts.map +1 -0
- package/dist/backend/ai/button-resolver.js +58 -0
- package/dist/backend/ai/button-resolver.js.map +1 -0
- package/dist/backend/ai/engine.d.ts +52 -0
- package/dist/backend/ai/engine.d.ts.map +1 -0
- package/dist/backend/ai/engine.js +189 -0
- package/dist/backend/ai/engine.js.map +1 -0
- package/dist/backend/ai/index.d.ts +11 -0
- package/dist/backend/ai/index.d.ts.map +1 -0
- package/dist/backend/ai/index.js +8 -0
- package/dist/backend/ai/index.js.map +1 -0
- package/dist/backend/ai/output-parser.d.ts +29 -0
- package/dist/backend/ai/output-parser.d.ts.map +1 -0
- package/dist/backend/ai/output-parser.js +247 -0
- package/dist/backend/ai/output-parser.js.map +1 -0
- package/dist/backend/ai/session-manager.d.ts +103 -0
- package/dist/backend/ai/session-manager.d.ts.map +1 -0
- package/dist/backend/ai/session-manager.js +298 -0
- package/dist/backend/ai/session-manager.js.map +1 -0
- package/dist/backend/index.d.ts +61 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +160 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/observe/index.d.ts +6 -0
- package/dist/backend/observe/index.d.ts.map +1 -0
- package/dist/backend/observe/index.js +5 -0
- package/dist/backend/observe/index.js.map +1 -0
- package/dist/backend/observe/logger.d.ts +28 -0
- package/dist/backend/observe/logger.d.ts.map +1 -0
- package/dist/backend/observe/logger.js +80 -0
- package/dist/backend/observe/logger.js.map +1 -0
- package/dist/backend/observe/types.d.ts +26 -0
- package/dist/backend/observe/types.d.ts.map +1 -0
- package/dist/backend/observe/types.js +7 -0
- package/dist/backend/observe/types.js.map +1 -0
- package/dist/backend/routes/chat.d.ts +31 -0
- package/dist/backend/routes/chat.d.ts.map +1 -0
- package/dist/backend/routes/chat.js +426 -0
- package/dist/backend/routes/chat.js.map +1 -0
- package/dist/backend/routes/data.d.ts +13 -0
- package/dist/backend/routes/data.d.ts.map +1 -0
- package/dist/backend/routes/data.js +129 -0
- package/dist/backend/routes/data.js.map +1 -0
- package/dist/backend/routes/health.d.ts +7 -0
- package/dist/backend/routes/health.d.ts.map +1 -0
- package/dist/backend/routes/health.js +15 -0
- package/dist/backend/routes/health.js.map +1 -0
- package/dist/backend/routes/index.d.ts +9 -0
- package/dist/backend/routes/index.d.ts.map +1 -0
- package/dist/backend/routes/index.js +8 -0
- package/dist/backend/routes/index.js.map +1 -0
- package/dist/backend/routes/upload.d.ts +24 -0
- package/dist/backend/routes/upload.d.ts.map +1 -0
- package/dist/backend/routes/upload.js +67 -0
- package/dist/backend/routes/upload.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +12 -0
- package/dist/bin.js.map +1 -0
- package/dist/capability-generator.d.ts +16 -6
- package/dist/capability-generator.d.ts.map +1 -1
- package/dist/capability-generator.js +160 -248
- package/dist/capability-generator.js.map +1 -1
- package/dist/cli/commands/build.d.ts +11 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +170 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/data.d.ts +12 -0
- package/dist/cli/commands/data.d.ts.map +1 -0
- package/dist/cli/commands/data.js +158 -0
- package/dist/cli/commands/data.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +9 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +114 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate-capabilities.d.ts +8 -0
- package/dist/cli/commands/generate-capabilities.d.ts.map +1 -0
- package/dist/cli/commands/generate-capabilities.js +40 -0
- package/dist/cli/commands/generate-capabilities.js.map +1 -0
- package/dist/cli/commands/generate-cli-command.d.ts +8 -0
- package/dist/cli/commands/generate-cli-command.d.ts.map +1 -0
- package/dist/cli/commands/generate-cli-command.js +64 -0
- package/dist/cli/commands/generate-cli-command.js.map +1 -0
- package/dist/cli/commands/generate-page.d.ts +9 -0
- package/dist/cli/commands/generate-page.d.ts.map +1 -0
- package/dist/cli/commands/generate-page.js +418 -0
- package/dist/cli/commands/generate-page.js.map +1 -0
- package/dist/cli/commands/generate-skill.d.ts +8 -0
- package/dist/cli/commands/generate-skill.d.ts.map +1 -0
- package/dist/cli/commands/generate-skill.js +75 -0
- package/dist/cli/commands/generate-skill.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +6 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +17 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +539 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/observe.d.ts +9 -0
- package/dist/cli/commands/observe.d.ts.map +1 -0
- package/dist/cli/commands/observe.js +142 -0
- package/dist/cli/commands/observe.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +9 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +186 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/helpers/duration.d.ts +5 -0
- package/dist/cli/helpers/duration.d.ts.map +1 -0
- package/dist/cli/helpers/duration.js +19 -0
- package/dist/cli/helpers/duration.js.map +1 -0
- package/dist/cli/helpers/field-template.d.ts +9 -0
- package/dist/cli/helpers/field-template.d.ts.map +1 -0
- package/dist/cli/helpers/field-template.js +92 -0
- package/dist/cli/helpers/field-template.js.map +1 -0
- package/dist/cli/helpers/naming.d.ts +12 -0
- package/dist/cli/helpers/naming.d.ts.map +1 -0
- package/dist/cli/helpers/naming.js +25 -0
- package/dist/cli/helpers/naming.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils.d.ts +10 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +31 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/config.d.ts +8 -33
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -7
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/server-bin.d.ts +12 -0
- package/dist/server-bin.d.ts.map +1 -0
- package/dist/server-bin.js +75 -0
- package/dist/server-bin.js.map +1 -0
- package/dist/types.d.ts +28 -18
- package/dist/types.d.ts.map +1 -1
- package/package.json +17 -4
- package/templates/skill/SKILL.md +140 -0
- package/templates/skill/references/README.md +128 -0
- 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
|