@loom-framework/backend 0.1.0-alpha.1
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/ai/engine.d.ts +37 -0
- package/dist/ai/engine.d.ts.map +1 -0
- package/dist/ai/engine.js +137 -0
- package/dist/ai/engine.js.map +1 -0
- package/dist/ai/index.d.ts +9 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +7 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/output-parser.d.ts +19 -0
- package/dist/ai/output-parser.d.ts.map +1 -0
- package/dist/ai/output-parser.js +154 -0
- package/dist/ai/output-parser.js.map +1 -0
- package/dist/ai/session-manager.d.ts +81 -0
- package/dist/ai/session-manager.d.ts.map +1 -0
- package/dist/ai/session-manager.js +193 -0
- package/dist/ai/session-manager.js.map +1 -0
- package/dist/bin.d.ts +12 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +75 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -0
- package/dist/observe/index.d.ts +6 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +5 -0
- package/dist/observe/index.js.map +1 -0
- package/dist/observe/logger.d.ts +28 -0
- package/dist/observe/logger.d.ts.map +1 -0
- package/dist/observe/logger.js +80 -0
- package/dist/observe/logger.js.map +1 -0
- package/dist/observe/types.d.ts +26 -0
- package/dist/observe/types.d.ts.map +1 -0
- package/dist/observe/types.js +7 -0
- package/dist/observe/types.js.map +1 -0
- package/dist/routes/data.d.ts +13 -0
- package/dist/routes/data.d.ts.map +1 -0
- package/dist/routes/data.js +95 -0
- package/dist/routes/data.js.map +1 -0
- package/dist/routes/health.d.ts +7 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +15 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +6 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +6 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/websocket/index.d.ts +32 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +320 -0
- package/dist/websocket/index.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/ai/session-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* loom-server CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* loom-server # Serve from current directory
|
|
7
|
+
* loom-server /path/to/project # Serve from specified directory
|
|
8
|
+
* loom-server --port 8080 # Custom port
|
|
9
|
+
* loom-server --host 127.0.0.1 # Custom host
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* loom-server CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* loom-server # Serve from current directory
|
|
7
|
+
* loom-server /path/to/project # Serve from specified directory
|
|
8
|
+
* loom-server --port 8080 # Custom port
|
|
9
|
+
* loom-server --host 127.0.0.1 # Custom host
|
|
10
|
+
*/
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
let projectRoot = process.cwd();
|
|
13
|
+
let port;
|
|
14
|
+
let host;
|
|
15
|
+
for (let i = 0; i < args.length; i++) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
switch (arg) {
|
|
18
|
+
case '--port':
|
|
19
|
+
case '-p':
|
|
20
|
+
port = parseInt(args[++i], 10);
|
|
21
|
+
break;
|
|
22
|
+
case '--host':
|
|
23
|
+
case '-h':
|
|
24
|
+
host = args[++i];
|
|
25
|
+
break;
|
|
26
|
+
case '--help':
|
|
27
|
+
console.log(`
|
|
28
|
+
loom-server - Start a Loom backend server
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
loom-server [project-root] [options]
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
--port, -p <number> Server port (default: 3000)
|
|
35
|
+
--host, -h <string> Server host (default: 0.0.0.0)
|
|
36
|
+
--help Show this help message
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
loom-server
|
|
40
|
+
loom-server ./my-project
|
|
41
|
+
loom-server --port 8080 --host 127.0.0.1
|
|
42
|
+
`);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
default:
|
|
45
|
+
// Treat as project root path
|
|
46
|
+
if (!arg.startsWith('-')) {
|
|
47
|
+
projectRoot = arg;
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const serverConfig = {};
|
|
53
|
+
if (port !== undefined)
|
|
54
|
+
serverConfig.port = port;
|
|
55
|
+
if (host !== undefined)
|
|
56
|
+
serverConfig.host = host;
|
|
57
|
+
try {
|
|
58
|
+
const { LoomServer } = await import('./index.js');
|
|
59
|
+
const server = new LoomServer({
|
|
60
|
+
projectRoot,
|
|
61
|
+
serverConfig,
|
|
62
|
+
});
|
|
63
|
+
await server.initialize();
|
|
64
|
+
await server.start();
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error instanceof Error && error.message.includes('No loom.config.ts found')) {
|
|
68
|
+
console.error(`Error: No loom.config.ts found in ${projectRoot}`);
|
|
69
|
+
console.error('Create one with: loom generate project');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAIH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAChC,IAAI,IAAwB,CAAC;AAC7B,IAAI,IAAwB,CAAC;AAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACjB,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAejB,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB;YACE,6BAA6B;YAC7B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,WAAW,GAAG,GAAG,CAAC;YACpB,CAAC;YACD,MAAM;IACV,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAA4B,EAAE,CAAC;AACjD,IAAI,IAAI,KAAK,SAAS;IAAE,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC;AACjD,IAAI,IAAI,KAAK,SAAS;IAAE,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC;AAEjD,IAAI,CAAC;IACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;QAC5B,WAAW;QACX,YAAY;KACb,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC1B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAChF,OAAO,CAAC,KAAK,CAAC,qCAAqC,WAAW,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @loom-framework/backend - Main Server
|
|
3
|
+
*
|
|
4
|
+
* Assembles Fastify server with:
|
|
5
|
+
* - WebSocket transparent proxy to AIEngine
|
|
6
|
+
* - REST routes for DataAdapter CRUD + health check
|
|
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 '@loom-framework/core';
|
|
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/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,sBAAsB,CAAC;AAU5F,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;IA2EjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @loom-framework/backend - Main Server
|
|
3
|
+
*
|
|
4
|
+
* Assembles Fastify server with:
|
|
5
|
+
* - WebSocket transparent proxy to AIEngine
|
|
6
|
+
* - REST routes for DataAdapter CRUD + health check
|
|
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 websocket from '@fastify/websocket';
|
|
13
|
+
import staticPlugin from '@fastify/static';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import { FileSystemAdapter, loadConfig } from '@loom-framework/core';
|
|
16
|
+
import { SQLiteAdapter } from '@loom-framework/core';
|
|
17
|
+
import { ClaudeCodeEngine } from './ai/engine.js';
|
|
18
|
+
import { SessionManager } from './ai/session-manager.js';
|
|
19
|
+
import { AIInteractionLogger } from './observe/index.js';
|
|
20
|
+
import { registerWebSocket } from './websocket/index.js';
|
|
21
|
+
import { registerDataRoutes, registerHealthRoute } from './routes/index.js';
|
|
22
|
+
export class LoomServer {
|
|
23
|
+
config;
|
|
24
|
+
engine;
|
|
25
|
+
adapter;
|
|
26
|
+
sessionManager;
|
|
27
|
+
interactionLogger;
|
|
28
|
+
fastify;
|
|
29
|
+
projectRoot;
|
|
30
|
+
options;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.projectRoot = options.projectRoot;
|
|
33
|
+
this.options = options;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Initialize server: load config, create engine/adapter, register routes
|
|
37
|
+
*/
|
|
38
|
+
async initialize() {
|
|
39
|
+
// Load config
|
|
40
|
+
this.config = await loadConfig(this.projectRoot);
|
|
41
|
+
const serverConfig = {
|
|
42
|
+
...this.config.server,
|
|
43
|
+
...this.options.serverConfig,
|
|
44
|
+
};
|
|
45
|
+
// Create Fastify instance
|
|
46
|
+
this.fastify = Fastify({
|
|
47
|
+
logger: {
|
|
48
|
+
level: this.options.logLevel || serverConfig.logLevel || 'info',
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
// Initialize DataAdapter based on config
|
|
52
|
+
this.adapter = this.options.adapter || this.createAdapter(this.config);
|
|
53
|
+
await this.adapter.initialize();
|
|
54
|
+
// Initialize AI Engine
|
|
55
|
+
this.engine = this.options.engine || new ClaudeCodeEngine({
|
|
56
|
+
config: this.config.ai?.claudeCode || {},
|
|
57
|
+
projectRoot: this.projectRoot,
|
|
58
|
+
});
|
|
59
|
+
// Initialize Session Manager
|
|
60
|
+
this.sessionManager = new SessionManager(this.projectRoot);
|
|
61
|
+
await this.sessionManager.initialize();
|
|
62
|
+
this.sessionManager.startCleanup();
|
|
63
|
+
// Initialize Interaction Logger
|
|
64
|
+
this.interactionLogger = new AIInteractionLogger(this.projectRoot);
|
|
65
|
+
await this.interactionLogger.initialize();
|
|
66
|
+
// Register plugins
|
|
67
|
+
if (serverConfig.cors !== false) {
|
|
68
|
+
await this.fastify.register(cors, { origin: true });
|
|
69
|
+
}
|
|
70
|
+
await this.fastify.register(websocket);
|
|
71
|
+
// Static file serving in production
|
|
72
|
+
if (serverConfig.staticDir) {
|
|
73
|
+
const staticDir = path.resolve(this.projectRoot, serverConfig.staticDir);
|
|
74
|
+
await this.fastify.register(staticPlugin, {
|
|
75
|
+
root: staticDir,
|
|
76
|
+
prefix: '/',
|
|
77
|
+
wildcard: false,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Register routes
|
|
81
|
+
registerHealthRoute(this.fastify, this.adapter);
|
|
82
|
+
registerDataRoutes(this.fastify, this.adapter);
|
|
83
|
+
registerWebSocket(this.fastify, {
|
|
84
|
+
engine: this.engine,
|
|
85
|
+
sessionManager: this.sessionManager,
|
|
86
|
+
config: this.config,
|
|
87
|
+
logger: this.interactionLogger,
|
|
88
|
+
});
|
|
89
|
+
// Graceful shutdown handlers
|
|
90
|
+
const cleanup = async () => {
|
|
91
|
+
this.sessionManager.stopCleanup();
|
|
92
|
+
if (this.engine instanceof ClaudeCodeEngine) {
|
|
93
|
+
this.engine.killAll();
|
|
94
|
+
}
|
|
95
|
+
await this.fastify.close();
|
|
96
|
+
};
|
|
97
|
+
process.on('SIGINT', cleanup);
|
|
98
|
+
process.on('SIGTERM', cleanup);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Start listening
|
|
102
|
+
*/
|
|
103
|
+
async start() {
|
|
104
|
+
const port = this.config.server?.port || 3000;
|
|
105
|
+
const host = this.config.server?.host || '0.0.0.0';
|
|
106
|
+
await this.fastify.listen({ port, host });
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Stop the server
|
|
110
|
+
*/
|
|
111
|
+
async stop() {
|
|
112
|
+
this.sessionManager.stopCleanup();
|
|
113
|
+
if (this.engine instanceof ClaudeCodeEngine) {
|
|
114
|
+
this.engine.killAll();
|
|
115
|
+
}
|
|
116
|
+
await this.fastify.close();
|
|
117
|
+
}
|
|
118
|
+
/** Expose Fastify instance for testing */
|
|
119
|
+
getFastify() {
|
|
120
|
+
return this.fastify;
|
|
121
|
+
}
|
|
122
|
+
/** Expose config for testing */
|
|
123
|
+
getConfig() {
|
|
124
|
+
return this.config;
|
|
125
|
+
}
|
|
126
|
+
/** Expose adapter for testing */
|
|
127
|
+
getAdapter() {
|
|
128
|
+
return this.adapter;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Create DataAdapter based on config.data.defaultAdapter
|
|
132
|
+
*/
|
|
133
|
+
createAdapter(config) {
|
|
134
|
+
if (config.data.defaultAdapter === 'sqlite') {
|
|
135
|
+
const dbPath = path.join(this.projectRoot, config.data.sqlite?.filename || 'data/loom.db');
|
|
136
|
+
return new SQLiteAdapter({ dbPath, config });
|
|
137
|
+
}
|
|
138
|
+
return new FileSystemAdapter({
|
|
139
|
+
dataDir: path.join(this.projectRoot, 'data'),
|
|
140
|
+
config,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create and start a LoomServer from a project root
|
|
146
|
+
*/
|
|
147
|
+
export async function startServer(projectRoot) {
|
|
148
|
+
const server = new LoomServer({ projectRoot });
|
|
149
|
+
await server.initialize();
|
|
150
|
+
await server.start();
|
|
151
|
+
return server;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIInteractionLogger
|
|
3
|
+
*
|
|
4
|
+
* Records each AI interaction to .loom/logs/ as JSON files.
|
|
5
|
+
* Each interaction is stored as a separate file: .loom/logs/{messageId}.json
|
|
6
|
+
*/
|
|
7
|
+
import type { AIInteractionLog, LogFilter } from './types.js';
|
|
8
|
+
export declare class AIInteractionLogger {
|
|
9
|
+
private logsDir;
|
|
10
|
+
constructor(projectRoot: string);
|
|
11
|
+
/**
|
|
12
|
+
* Ensure logs directory exists
|
|
13
|
+
*/
|
|
14
|
+
initialize(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Record an AI interaction log
|
|
17
|
+
*/
|
|
18
|
+
log(entry: AIInteractionLog): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Read all logs, optionally filtered
|
|
21
|
+
*/
|
|
22
|
+
readLogs(filter?: LogFilter): Promise<AIInteractionLog[]>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a duration string like '1h', '30m', '7d' into milliseconds
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseDuration(duration: string): number;
|
|
28
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/observe/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,WAAW,EAAE,MAAM;IAI/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD;;OAEG;IACG,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAgChE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBtD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIInteractionLogger
|
|
3
|
+
*
|
|
4
|
+
* Records each AI interaction to .loom/logs/ as JSON files.
|
|
5
|
+
* Each interaction is stored as a separate file: .loom/logs/{messageId}.json
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
export class AIInteractionLogger {
|
|
10
|
+
logsDir;
|
|
11
|
+
constructor(projectRoot) {
|
|
12
|
+
this.logsDir = path.join(projectRoot, '.loom', 'logs');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Ensure logs directory exists
|
|
16
|
+
*/
|
|
17
|
+
async initialize() {
|
|
18
|
+
await fs.mkdir(this.logsDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Record an AI interaction log
|
|
22
|
+
*/
|
|
23
|
+
async log(entry) {
|
|
24
|
+
const filePath = path.join(this.logsDir, `${entry.messageId}.json`);
|
|
25
|
+
await fs.writeFile(filePath, JSON.stringify(entry, null, 2), 'utf-8');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read all logs, optionally filtered
|
|
29
|
+
*/
|
|
30
|
+
async readLogs(filter) {
|
|
31
|
+
try {
|
|
32
|
+
const files = await fs.readdir(this.logsDir);
|
|
33
|
+
const logs = [];
|
|
34
|
+
for (const file of files) {
|
|
35
|
+
if (!file.endsWith('.json'))
|
|
36
|
+
continue;
|
|
37
|
+
try {
|
|
38
|
+
const content = await fs.readFile(path.join(this.logsDir, file), 'utf-8');
|
|
39
|
+
const entry = JSON.parse(content);
|
|
40
|
+
if (filter?.session && entry.sessionId !== filter.session)
|
|
41
|
+
continue;
|
|
42
|
+
if (filter?.last) {
|
|
43
|
+
const cutoff = Date.now() - parseDuration(filter.last);
|
|
44
|
+
if (new Date(entry.timestamp).getTime() < cutoff)
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
logs.push(entry);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Skip malformed files
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Sort by timestamp descending (most recent first)
|
|
54
|
+
logs.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
55
|
+
return logs;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a duration string like '1h', '30m', '7d' into milliseconds
|
|
64
|
+
*/
|
|
65
|
+
export function parseDuration(duration) {
|
|
66
|
+
const match = duration.match(/^(\d+)(s|m|h|d)$/);
|
|
67
|
+
if (!match) {
|
|
68
|
+
throw new Error(`Invalid duration format: ${duration}. Use format like '1h', '30m', '7d'`);
|
|
69
|
+
}
|
|
70
|
+
const value = parseInt(match[1], 10);
|
|
71
|
+
const unit = match[2];
|
|
72
|
+
switch (unit) {
|
|
73
|
+
case 's': return value * 1000;
|
|
74
|
+
case 'm': return value * 60 * 1000;
|
|
75
|
+
case 'h': return value * 60 * 60 * 1000;
|
|
76
|
+
case 'd': return value * 24 * 60 * 60 * 1000;
|
|
77
|
+
default: throw new Error(`Unknown duration unit: ${unit}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/observe/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Interaction Log Types
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure for observability logging of AI interactions.
|
|
5
|
+
*/
|
|
6
|
+
export interface AIInteractionLog {
|
|
7
|
+
sessionId: string;
|
|
8
|
+
messageId: string;
|
|
9
|
+
timestamp: string;
|
|
10
|
+
prompt: string;
|
|
11
|
+
response: string;
|
|
12
|
+
duration: number;
|
|
13
|
+
usage?: {
|
|
14
|
+
inputTokens: number;
|
|
15
|
+
outputTokens: number;
|
|
16
|
+
};
|
|
17
|
+
mcpCalls: string[];
|
|
18
|
+
cliCalls: string[];
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface LogFilter {
|
|
22
|
+
session?: string;
|
|
23
|
+
/** Duration string like '1h', '30m', '7d' */
|
|
24
|
+
last?: string;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/observe/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/observe/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data REST Routes - DataAdapter-driven CRUD
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/data/:model - List/query records
|
|
5
|
+
* GET /api/v1/data/:model/:id - Get single record
|
|
6
|
+
* POST /api/v1/data/:model - Create record
|
|
7
|
+
* PUT /api/v1/data/:model/:id - Update record
|
|
8
|
+
* DELETE /api/v1/data/:model/:id - Delete record
|
|
9
|
+
*/
|
|
10
|
+
import type { FastifyInstance } from 'fastify';
|
|
11
|
+
import type { DataAdapter } from '@loom-framework/core';
|
|
12
|
+
export declare function registerDataRoutes(fastify: FastifyInstance, adapter: DataAdapter): void;
|
|
13
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/routes/data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAsFvF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data REST Routes - DataAdapter-driven CRUD
|
|
3
|
+
*
|
|
4
|
+
* GET /api/v1/data/:model - List/query records
|
|
5
|
+
* GET /api/v1/data/:model/:id - Get single record
|
|
6
|
+
* POST /api/v1/data/:model - Create record
|
|
7
|
+
* PUT /api/v1/data/:model/:id - Update record
|
|
8
|
+
* DELETE /api/v1/data/:model/:id - Delete record
|
|
9
|
+
*/
|
|
10
|
+
export function registerDataRoutes(fastify, adapter) {
|
|
11
|
+
// List or query records
|
|
12
|
+
fastify.get('/api/v1/data/:model', async (req, reply) => {
|
|
13
|
+
const { model } = req.params;
|
|
14
|
+
const query = req.query;
|
|
15
|
+
const options = {};
|
|
16
|
+
if (query.filter) {
|
|
17
|
+
try {
|
|
18
|
+
options.filter = JSON.parse(query.filter);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
reply.code(400).send({ error: 'Invalid filter JSON' });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (query.limit)
|
|
26
|
+
options.limit = parseInt(query.limit, 10);
|
|
27
|
+
if (query.offset)
|
|
28
|
+
options.offset = parseInt(query.offset, 10);
|
|
29
|
+
try {
|
|
30
|
+
const result = await adapter.read(model, options);
|
|
31
|
+
reply.send({ data: result });
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : 'Read failed';
|
|
35
|
+
reply.code(400).send({ error: message });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// Get single record
|
|
39
|
+
fastify.get('/api/v1/data/:model/:id', async (req, reply) => {
|
|
40
|
+
const { model, id } = req.params;
|
|
41
|
+
try {
|
|
42
|
+
const result = await adapter.read(model, { id });
|
|
43
|
+
if (result === null || result === undefined) {
|
|
44
|
+
reply.code(404).send({ error: 'Record not found' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
reply.send({ data: result });
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const message = err instanceof Error ? err.message : 'Read failed';
|
|
51
|
+
reply.code(400).send({ error: message });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Create record
|
|
55
|
+
fastify.post('/api/v1/data/:model', async (req, reply) => {
|
|
56
|
+
const { model } = req.params;
|
|
57
|
+
const body = req.body;
|
|
58
|
+
try {
|
|
59
|
+
const result = await adapter.write(model, body);
|
|
60
|
+
reply.code(201).send({ data: result });
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : 'Write failed';
|
|
64
|
+
reply.code(400).send({ error: message });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Update record
|
|
68
|
+
fastify.put('/api/v1/data/:model/:id', async (req, reply) => {
|
|
69
|
+
const { model, id } = req.params;
|
|
70
|
+
const body = req.body;
|
|
71
|
+
try {
|
|
72
|
+
const result = await adapter.update(model, id, body);
|
|
73
|
+
reply.send({ data: result });
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const message = err instanceof Error ? err.message : 'Update failed';
|
|
77
|
+
const code = message.includes('not found') ? 404 : 400;
|
|
78
|
+
reply.code(code).send({ error: message });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
// Delete record
|
|
82
|
+
fastify.delete('/api/v1/data/:model/:id', async (req, reply) => {
|
|
83
|
+
const { model, id } = req.params;
|
|
84
|
+
try {
|
|
85
|
+
await adapter.delete(model, id);
|
|
86
|
+
reply.code(204).send();
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
const message = err instanceof Error ? err.message : 'Delete failed';
|
|
90
|
+
const code = message.includes('not found') ? 404 : 400;
|
|
91
|
+
reply.code(code).send({ error: message });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/routes/data.ts"],"names":[],"mappings":"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"}
|