@loom-framework/core 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/adapter-filesystem.d.ts +32 -0
- package/dist/adapter-filesystem.d.ts.map +1 -0
- package/dist/adapter-filesystem.js +141 -0
- package/dist/adapter-filesystem.js.map +1 -0
- package/dist/adapter-sqlite.d.ts +51 -0
- package/dist/adapter-sqlite.d.ts.map +1 -0
- package/dist/adapter-sqlite.js +225 -0
- package/dist/adapter-sqlite.js.map +1 -0
- package/dist/capability-generator.d.ts +20 -0
- package/dist/capability-generator.d.ts.map +1 -0
- package/dist/capability-generator.js +288 -0
- package/dist/capability-generator.js.map +1 -0
- package/dist/commands.d.ts +32 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +40 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +483 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +179 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +198 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Generator
|
|
3
|
+
*
|
|
4
|
+
* Core innovation: One schema definition → MCP Server + CLI commands
|
|
5
|
+
*
|
|
6
|
+
* From loom.config.ts model definitions, generates:
|
|
7
|
+
* 1. MCP Server (.loom/mcp-server/) - structured data CRUD tools
|
|
8
|
+
* 2. CLI data commands (cli/commands/data/) - dev/debug data access
|
|
9
|
+
* 3. MCP config (.loom/mcp.json) - Claude Code MCP registration
|
|
10
|
+
*/
|
|
11
|
+
import { promises as fs } from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
// ── MCP Tool Generation ──
|
|
14
|
+
/**
|
|
15
|
+
* Generate MCP server code from model schemas
|
|
16
|
+
*/
|
|
17
|
+
function generateMcpToolForModel(model) {
|
|
18
|
+
const modelName = model.name;
|
|
19
|
+
const capitalName = modelName.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
|
20
|
+
const readParams = generateMcpParams(model, 'read');
|
|
21
|
+
const writeParams = generateMcpParams(model, 'write');
|
|
22
|
+
return `// Auto-generated by loom generate capabilities
|
|
23
|
+
// Model: ${modelName}
|
|
24
|
+
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
import type { DataAdapter } from '@loom-framework/core';
|
|
27
|
+
|
|
28
|
+
const ${modelName}Schema = z.object({
|
|
29
|
+
${model.fields.map(f => ` ${f.name}: ${fieldToZod(f)},`).join('\n')}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export function register${capitalName}Tools(
|
|
33
|
+
server: { tool: (name: string, description: string, schema: z.ZodObject<any>, handler: (params: any) => Promise<{ content: Array<{ type: string; text: string }> }>) => void },
|
|
34
|
+
adapter: DataAdapter
|
|
35
|
+
) {
|
|
36
|
+
// read_${modelName}
|
|
37
|
+
server.tool(
|
|
38
|
+
'read_${modelName}',
|
|
39
|
+
'Read ${modelName} records${model.description ? ': ' + model.description : ''}',
|
|
40
|
+
z.object({
|
|
41
|
+
id: z.string().optional().describe('Record ID for single lookup'),
|
|
42
|
+
filter: z.record(z.unknown()).optional().describe('Filter conditions'),
|
|
43
|
+
limit: z.number().optional().describe('Max records to return'),
|
|
44
|
+
}),
|
|
45
|
+
async (params) => {
|
|
46
|
+
const result = await adapter.read('${modelName}', params);
|
|
47
|
+
return {
|
|
48
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// write_${modelName}
|
|
54
|
+
server.tool(
|
|
55
|
+
'write_${modelName}',
|
|
56
|
+
'Create a new ${modelName} record',
|
|
57
|
+
${modelName}Schema,
|
|
58
|
+
async (params) => {
|
|
59
|
+
const result = await adapter.write('${modelName}', params);
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// update_${modelName}
|
|
67
|
+
server.tool(
|
|
68
|
+
'update_${modelName}',
|
|
69
|
+
'Update an existing ${modelName} record',
|
|
70
|
+
z.object({
|
|
71
|
+
id: z.string().describe('Record ID to update'),
|
|
72
|
+
data: ${modelName}Schema.partial().describe('Fields to update'),
|
|
73
|
+
}),
|
|
74
|
+
async (params) => {
|
|
75
|
+
const result = await adapter.update('${modelName}', params.id, params.data);
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// delete_${modelName}
|
|
83
|
+
server.tool(
|
|
84
|
+
'delete_${modelName}',
|
|
85
|
+
'Delete a ${modelName} record',
|
|
86
|
+
z.object({
|
|
87
|
+
id: z.string().describe('Record ID to delete'),
|
|
88
|
+
}),
|
|
89
|
+
async (params) => {
|
|
90
|
+
await adapter.delete('${modelName}', params.id);
|
|
91
|
+
return {
|
|
92
|
+
content: [{ type: 'text', text: \`Deleted ${modelName} record: \${params.id}\` }],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}`;
|
|
97
|
+
}
|
|
98
|
+
function fieldToZod(field) {
|
|
99
|
+
const base = (() => {
|
|
100
|
+
switch (field.type) {
|
|
101
|
+
case 'string': return 'z.string()';
|
|
102
|
+
case 'number': return 'z.number()';
|
|
103
|
+
case 'boolean': return 'z.boolean()';
|
|
104
|
+
case 'date': return 'z.string().describe("ISO date string")';
|
|
105
|
+
case 'string[]': return 'z.array(z.string())';
|
|
106
|
+
case 'number[]': return 'z.array(z.number())';
|
|
107
|
+
case 'json': return 'z.unknown()';
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
110
|
+
const withDesc = field.description ? `${base}.describe("${field.description}")` : base;
|
|
111
|
+
const withEnum = field.enum ? `z.enum([${field.enum.map(e => `"${e}"`).join(', ')}])` : withDesc;
|
|
112
|
+
const withRequired = field.required ? withEnum : `${withEnum}.optional()`;
|
|
113
|
+
return withRequired;
|
|
114
|
+
}
|
|
115
|
+
function generateMcpParams(model, operation) {
|
|
116
|
+
if (operation === 'read') {
|
|
117
|
+
return `{ id?: string, filter?: Record<string, unknown>, limit?: number }`;
|
|
118
|
+
}
|
|
119
|
+
return `{\n${model.fields.map(f => ` ${f.name}: ${f.type}${f.required ? '' : '?'},`).join('\n')}\n}`;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Generate MCP Server index.ts
|
|
123
|
+
*/
|
|
124
|
+
function generateMcpServerIndex(models) {
|
|
125
|
+
const imports = models.map(m => {
|
|
126
|
+
const capitalName = m.name.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
|
127
|
+
return `import { register${capitalName}Tools } from './tools/${m.name}.js';`;
|
|
128
|
+
}).join('\n');
|
|
129
|
+
const registrations = models.map(m => {
|
|
130
|
+
const capitalName = m.name.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
|
131
|
+
return ` register${capitalName}Tools(server, adapter);`;
|
|
132
|
+
}).join('\n');
|
|
133
|
+
return `// Auto-generated by loom generate capabilities
|
|
134
|
+
// Loom MCP Server - Data Access Layer
|
|
135
|
+
|
|
136
|
+
import path from 'path';
|
|
137
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
138
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
139
|
+
import { FileSystemAdapter } from '@loom-framework/core';
|
|
140
|
+
import { loadConfig } from '@loom-framework/core';
|
|
141
|
+
${imports}
|
|
142
|
+
|
|
143
|
+
async function main() {
|
|
144
|
+
const projectRoot = process.env.LOOM_PROJECT_ROOT || process.cwd();
|
|
145
|
+
const config = await loadConfig(projectRoot);
|
|
146
|
+
const adapter = new FileSystemAdapter({
|
|
147
|
+
dataDir: process.env.LOOM_DATA_DIR || path.join(projectRoot, 'data'),
|
|
148
|
+
config,
|
|
149
|
+
});
|
|
150
|
+
await adapter.initialize();
|
|
151
|
+
|
|
152
|
+
const server = new McpServer({
|
|
153
|
+
name: 'loom-data',
|
|
154
|
+
version: '1.0.0',
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
${registrations}
|
|
158
|
+
|
|
159
|
+
const transport = new StdioServerTransport();
|
|
160
|
+
await server.connect(transport);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
main().catch(console.error);
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Generate .loom/mcp.json
|
|
168
|
+
*/
|
|
169
|
+
function generateMcpJson(projectRoot) {
|
|
170
|
+
return JSON.stringify({
|
|
171
|
+
mcpServers: {
|
|
172
|
+
'loom-data': {
|
|
173
|
+
command: 'npx',
|
|
174
|
+
args: ['tsx', '.loom/mcp-server/index.ts'],
|
|
175
|
+
env: {
|
|
176
|
+
LOOM_PROJECT_ROOT: projectRoot,
|
|
177
|
+
LOOM_DATA_DIR: './data',
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
}, null, 2);
|
|
182
|
+
}
|
|
183
|
+
// ── CLI Command Generation ──
|
|
184
|
+
/**
|
|
185
|
+
* Generate CLI data command for a model
|
|
186
|
+
*/
|
|
187
|
+
function generateCliDataCommand(model) {
|
|
188
|
+
const modelName = model.name;
|
|
189
|
+
return `// Auto-generated by loom generate capabilities
|
|
190
|
+
// Model: ${modelName}
|
|
191
|
+
|
|
192
|
+
import { defineCommand } from '@loom-framework/core';
|
|
193
|
+
|
|
194
|
+
export default defineCommand({
|
|
195
|
+
name: 'data:read:${modelName}',
|
|
196
|
+
description: 'Read ${modelName} records${model.description ? ' - ' + model.description : ''}',
|
|
197
|
+
options: {
|
|
198
|
+
id: { type: 'string', description: 'Record ID for single lookup' },
|
|
199
|
+
filter: { type: 'json', description: 'Filter conditions as JSON' },
|
|
200
|
+
limit: { type: 'number', description: 'Max records to return' },
|
|
201
|
+
},
|
|
202
|
+
async execute(args, context) {
|
|
203
|
+
const adapter = context.getDataAdapter();
|
|
204
|
+
const result = await adapter.read('${modelName}', {
|
|
205
|
+
id: args.id as string | undefined,
|
|
206
|
+
filter: args.filter as Record<string, unknown> | undefined,
|
|
207
|
+
limit: args.limit as number | undefined,
|
|
208
|
+
});
|
|
209
|
+
return JSON.stringify(result, null, 2);
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
`;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Generate all capabilities from config
|
|
216
|
+
*/
|
|
217
|
+
export async function generateCapabilities(projectRoot, config) {
|
|
218
|
+
const loomDir = path.join(projectRoot, '.loom');
|
|
219
|
+
const mcpServerDir = path.join(loomDir, 'mcp-server');
|
|
220
|
+
const mcpToolsDir = path.join(mcpServerDir, 'tools');
|
|
221
|
+
const cliDataDir = path.join(projectRoot, 'cli', 'src', 'commands', 'data');
|
|
222
|
+
const filesWritten = [];
|
|
223
|
+
// Clean and create directories
|
|
224
|
+
await fs.mkdir(mcpToolsDir, { recursive: true });
|
|
225
|
+
await fs.mkdir(cliDataDir, { recursive: true });
|
|
226
|
+
// Generate MCP tools for each model
|
|
227
|
+
for (const model of config.data.models) {
|
|
228
|
+
// MCP tool file
|
|
229
|
+
const mcpToolPath = path.join(mcpToolsDir, `${model.name}.ts`);
|
|
230
|
+
await fs.writeFile(mcpToolPath, generateMcpToolForModel(model), 'utf-8');
|
|
231
|
+
filesWritten.push(mcpToolPath);
|
|
232
|
+
// CLI data command
|
|
233
|
+
const cliCmdPath = path.join(cliDataDir, `${model.name}.ts`);
|
|
234
|
+
await fs.writeFile(cliCmdPath, generateCliDataCommand(model), 'utf-8');
|
|
235
|
+
filesWritten.push(cliCmdPath);
|
|
236
|
+
}
|
|
237
|
+
// Generate MCP Server index
|
|
238
|
+
const indexPath = path.join(mcpServerDir, 'index.ts');
|
|
239
|
+
await fs.writeFile(indexPath, generateMcpServerIndex(config.data.models), 'utf-8');
|
|
240
|
+
filesWritten.push(indexPath);
|
|
241
|
+
// Generate MCP Server package.json
|
|
242
|
+
// Note: @loom-framework/core is resolved from parent project's node_modules at runtime (via tsx)
|
|
243
|
+
const mcpPkgPath = path.join(mcpServerDir, 'package.json');
|
|
244
|
+
await fs.writeFile(mcpPkgPath, JSON.stringify({
|
|
245
|
+
name: 'loom-mcp-server',
|
|
246
|
+
version: '1.0.0',
|
|
247
|
+
type: 'module',
|
|
248
|
+
main: 'index.js',
|
|
249
|
+
dependencies: {
|
|
250
|
+
'@modelcontextprotocol/sdk': '^1.12.0',
|
|
251
|
+
'@loom-framework/core': '^0.1.0',
|
|
252
|
+
'zod': '^3.23.0',
|
|
253
|
+
},
|
|
254
|
+
devDependencies: {
|
|
255
|
+
'@types/node': '^22.0.0',
|
|
256
|
+
'tsx': '^4.7.0',
|
|
257
|
+
'typescript': '^5.6.0',
|
|
258
|
+
},
|
|
259
|
+
}, null, 2), 'utf-8');
|
|
260
|
+
filesWritten.push(mcpPkgPath);
|
|
261
|
+
// Generate MCP Server tsconfig (self-contained, no external extends)
|
|
262
|
+
const mcpTsconfigPath = path.join(mcpServerDir, 'tsconfig.json');
|
|
263
|
+
await fs.writeFile(mcpTsconfigPath, JSON.stringify({
|
|
264
|
+
compilerOptions: {
|
|
265
|
+
target: 'ES2022',
|
|
266
|
+
module: 'Node16',
|
|
267
|
+
moduleResolution: 'Node16',
|
|
268
|
+
lib: ['ES2022'],
|
|
269
|
+
strict: true,
|
|
270
|
+
esModuleInterop: true,
|
|
271
|
+
skipLibCheck: true,
|
|
272
|
+
forceConsistentCasingInFileNames: true,
|
|
273
|
+
resolveJsonModule: true,
|
|
274
|
+
declaration: true,
|
|
275
|
+
sourceMap: true,
|
|
276
|
+
outDir: '.',
|
|
277
|
+
rootDir: '.',
|
|
278
|
+
},
|
|
279
|
+
include: ['*.ts', 'tools/*.ts'],
|
|
280
|
+
}, null, 2), 'utf-8');
|
|
281
|
+
filesWritten.push(mcpTsconfigPath);
|
|
282
|
+
// Generate mcp.json
|
|
283
|
+
const mcpJsonPath = path.join(loomDir, 'mcp.json');
|
|
284
|
+
await fs.writeFile(mcpJsonPath, generateMcpJson(projectRoot), 'utf-8');
|
|
285
|
+
filesWritten.push(mcpJsonPath);
|
|
286
|
+
return { mcpServerDir, filesWritten };
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=capability-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-generator.js","sourceRoot":"","sources":["../src/capability-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Command Framework
|
|
3
|
+
*
|
|
4
|
+
* defineCommand() - Type-safe command registration
|
|
5
|
+
* Auto-discovery from cli/commands/ directory
|
|
6
|
+
*/
|
|
7
|
+
import type { CommandDefinition, CommandContext, LoomConfig, DataAdapter } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Define a CLI command with type safety
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* export default defineCommand({
|
|
14
|
+
* name: 'data:read:users',
|
|
15
|
+
* description: 'Read user records',
|
|
16
|
+
* options: {
|
|
17
|
+
* id: { type: 'string', description: 'User ID' },
|
|
18
|
+
* },
|
|
19
|
+
* async execute(args, context) {
|
|
20
|
+
* const adapter = context.getDataAdapter();
|
|
21
|
+
* const result = await adapter.read('users', { id: args.id as string });
|
|
22
|
+
* return JSON.stringify(result, null, 2);
|
|
23
|
+
* },
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function defineCommand(command: CommandDefinition): CommandDefinition;
|
|
28
|
+
/**
|
|
29
|
+
* Context factory for command execution
|
|
30
|
+
*/
|
|
31
|
+
export declare function createCommandContext(config: LoomConfig, configPath: string, projectRoot: string, dataAdapter: DataAdapter): CommandContext;
|
|
32
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAE3E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,GACvB,cAAc,CAOhB"}
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Command Framework
|
|
3
|
+
*
|
|
4
|
+
* defineCommand() - Type-safe command registration
|
|
5
|
+
* Auto-discovery from cli/commands/ directory
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Define a CLI command with type safety
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* export default defineCommand({
|
|
13
|
+
* name: 'data:read:users',
|
|
14
|
+
* description: 'Read user records',
|
|
15
|
+
* options: {
|
|
16
|
+
* id: { type: 'string', description: 'User ID' },
|
|
17
|
+
* },
|
|
18
|
+
* async execute(args, context) {
|
|
19
|
+
* const adapter = context.getDataAdapter();
|
|
20
|
+
* const result = await adapter.read('users', { id: args.id as string });
|
|
21
|
+
* return JSON.stringify(result, null, 2);
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function defineCommand(command) {
|
|
27
|
+
return command;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Context factory for command execution
|
|
31
|
+
*/
|
|
32
|
+
export function createCommandContext(config, configPath, projectRoot, dataAdapter) {
|
|
33
|
+
return {
|
|
34
|
+
config,
|
|
35
|
+
configPath,
|
|
36
|
+
projectRoot,
|
|
37
|
+
getDataAdapter: () => dataAdapter,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkB,EAClB,UAAkB,EAClB,WAAmB,EACnB,WAAwB;IAExB,OAAO;QACL,MAAM;QACN,UAAU;QACV,WAAW;QACX,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW;KAClC,CAAC;AACJ,CAAC"}
|