@loom-framework/core 0.1.0-alpha.7 → 0.1.0-alpha.71
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 +56 -39
- 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 +65 -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 +186 -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 +161 -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 +134 -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 +11 -0
- package/dist/backend/routes/index.d.ts.map +1 -0
- package/dist/backend/routes/index.js +9 -0
- package/dist/backend/routes/index.js.map +1 -0
- package/dist/backend/routes/skills.d.ts +16 -0
- package/dist/backend/routes/skills.d.ts.map +1 -0
- package/dist/backend/routes/skills.js +365 -0
- package/dist/backend/routes/skills.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 +21 -6
- package/dist/capability-generator.d.ts.map +1 -1
- package/dist/capability-generator.js +88 -261
- 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 +578 -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 +10 -0
- package/dist/cli/helpers/field-template.d.ts.map +1 -0
- package/dist/cli/helpers/field-template.js +100 -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 -40
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -8
- 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 +33 -20
- package/dist/types.d.ts.map +1 -1
- package/package.json +24 -11
- package/templates/app-skill/SKILL.md +27 -0
- package/templates/app-skill/references/data-semantics.md +44 -0
- package/templates/app-skill/references/models.md +31 -0
- package/templates/loom-skill/SKILL.md +140 -0
- package/templates/loom-skill/references/README.md +128 -0
- package/templates/loom-skill/references/data-model.md +78 -0
|
@@ -1,288 +1,115 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Capability Generator
|
|
3
3
|
*
|
|
4
|
-
* Core innovation: One schema definition →
|
|
4
|
+
* Core innovation: One schema definition → Skill + CLI data access
|
|
5
5
|
*
|
|
6
6
|
* From loom.config.ts model definitions, generates:
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
* 3.
|
|
7
|
+
* 1. SKILL.md — guided instructions for AI to write natural language (only on first run, never overwritten)
|
|
8
|
+
* 2. references/models.md — auto-generated structural content (always overwritten on generate)
|
|
9
|
+
* 3. references/data-semantics.md — AI-driven semantic guidance (always overwritten on generate)
|
|
10
|
+
*
|
|
11
|
+
* Template files live in templates/app-skill/ — static content is defined there,
|
|
12
|
+
* dynamic content (model tables, AI buttons) is filled in by code.
|
|
10
13
|
*/
|
|
11
14
|
import { promises as fs } from 'fs';
|
|
12
15
|
import path from 'path';
|
|
13
|
-
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
// From dist/ → go up to package root → templates/app-skill/
|
|
19
|
+
const TEMPLATES_DIR = path.resolve(__dirname, '../templates/app-skill');
|
|
20
|
+
// ── Template Loading ──
|
|
21
|
+
async function loadTemplate(relativePath) {
|
|
22
|
+
return fs.readFile(path.join(TEMPLATES_DIR, relativePath), 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
// ── Dynamic Content Builders ──
|
|
14
25
|
/**
|
|
15
|
-
*
|
|
26
|
+
* Build a markdown table row for a model field
|
|
16
27
|
*/
|
|
17
|
-
function
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
return
|
|
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}`;
|
|
28
|
+
function fieldTableRow(f) {
|
|
29
|
+
const req = f.required ? 'yes' : 'no';
|
|
30
|
+
const enums = f.enum ? ` (${f.enum.join('/')})` : '';
|
|
31
|
+
const def = f.default !== undefined ? ` [default: ${JSON.stringify(f.default)}]` : '';
|
|
32
|
+
const desc = (f.description || '') + enums + def;
|
|
33
|
+
return `| ${f.name} | ${f.type} | ${req} | ${desc} |`;
|
|
120
34
|
}
|
|
121
35
|
/**
|
|
122
|
-
*
|
|
36
|
+
* Build the Data Models section content
|
|
123
37
|
*/
|
|
124
|
-
function
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
`;
|
|
38
|
+
function buildDataModelsSection(models) {
|
|
39
|
+
return models.map(model => {
|
|
40
|
+
const header = `### ${model.name}${model.description ? ` — ${model.description}` : ''}`;
|
|
41
|
+
const tableHeader = '| Field | Type | Required | Description |';
|
|
42
|
+
const tableSep = '|-------|------|----------|-------------|';
|
|
43
|
+
const tableRows = model.fields.map(fieldTableRow).join('\n');
|
|
44
|
+
return `${header}\n\n${tableHeader}\n${tableSep}\n${tableRows}`;
|
|
45
|
+
}).join('\n\n');
|
|
165
46
|
}
|
|
166
47
|
/**
|
|
167
|
-
*
|
|
48
|
+
* Build the AI Buttons section content (or empty string if none)
|
|
168
49
|
*/
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
LOOM_PROJECT_ROOT: projectRoot,
|
|
177
|
-
LOOM_DATA_DIR: './data',
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
}, null, 2);
|
|
50
|
+
function buildAiButtonsSection(aiButtons) {
|
|
51
|
+
if (!aiButtons || aiButtons.length === 0)
|
|
52
|
+
return '';
|
|
53
|
+
return `## AI Buttons\n\n${aiButtons.map(btn => {
|
|
54
|
+
const placement = btn.placement ? ` (available on: ${btn.placement})` : ' (available on all pages)';
|
|
55
|
+
return `- **${btn.id}** ("${btn.label}"): \`${btn.prompt}\`${placement}`;
|
|
56
|
+
}).join('\n')}`;
|
|
182
57
|
}
|
|
183
|
-
// ── CLI Command Generation ──
|
|
184
58
|
/**
|
|
185
|
-
*
|
|
59
|
+
* Build the model names line for data-semantics.md (or empty string if only one model)
|
|
186
60
|
*/
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
`;
|
|
61
|
+
function buildModelNamesLine(models) {
|
|
62
|
+
if (models.length <= 1)
|
|
63
|
+
return '';
|
|
64
|
+
return `\nModels in this project: ${models.map(m => `\`${m.name}\``).join(', ')}.`;
|
|
213
65
|
}
|
|
214
66
|
/**
|
|
215
|
-
* Generate all capabilities from config
|
|
67
|
+
* Generate all capabilities from config.
|
|
68
|
+
*
|
|
69
|
+
* Three-file strategy:
|
|
70
|
+
* - SKILL.md: natural language content (only created if not exists, never overwritten)
|
|
71
|
+
* - references/models.md: structural content (always regenerated)
|
|
72
|
+
* - references/data-semantics.md: semantic guidance (always regenerated)
|
|
216
73
|
*/
|
|
217
74
|
export async function generateCapabilities(projectRoot, config) {
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
const
|
|
75
|
+
const projectName = config.project.name;
|
|
76
|
+
const models = config.data.models;
|
|
77
|
+
const skillDir = path.join(projectRoot, '.claude', 'skills', projectName);
|
|
78
|
+
const skillPromptFile = path.join(skillDir, 'SKILL.md');
|
|
79
|
+
const referencesDir = path.join(skillDir, 'references');
|
|
80
|
+
const modelsFile = path.join(referencesDir, 'models.md');
|
|
81
|
+
const dataSemanticsFile = path.join(referencesDir, 'data-semantics.md');
|
|
222
82
|
const filesWritten = [];
|
|
223
|
-
//
|
|
224
|
-
await fs.mkdir(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
83
|
+
// Create skill directory structure
|
|
84
|
+
await fs.mkdir(referencesDir, { recursive: true });
|
|
85
|
+
// Load templates in parallel
|
|
86
|
+
const [skillTemplate, modelsTemplate, semanticsTemplate] = await Promise.all([
|
|
87
|
+
loadTemplate('SKILL.md'),
|
|
88
|
+
loadTemplate('references/models.md'),
|
|
89
|
+
loadTemplate('references/data-semantics.md'),
|
|
90
|
+
]);
|
|
91
|
+
// SKILL.md: apply variable substitution, only write if not exists
|
|
92
|
+
const skillExists = await fs.access(skillPromptFile).then(() => true, () => false);
|
|
93
|
+
if (!skillExists) {
|
|
94
|
+
const skillContent = skillTemplate
|
|
95
|
+
.replace(/\{\{projectName\}\}/g, projectName);
|
|
96
|
+
await fs.writeFile(skillPromptFile, skillContent, 'utf-8');
|
|
97
|
+
filesWritten.push(skillPromptFile);
|
|
236
98
|
}
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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 };
|
|
99
|
+
// references/models.md: fill dynamic sections into template
|
|
100
|
+
const dataModelsSection = buildDataModelsSection(models);
|
|
101
|
+
const aiButtonsSection = buildAiButtonsSection(config.aiButtons);
|
|
102
|
+
const modelsContent = modelsTemplate
|
|
103
|
+
.replace('<!-- DATA_MODELS -->', dataModelsSection)
|
|
104
|
+
.replace('<!-- AI_BUTTONS -->', aiButtonsSection ? '\n' + aiButtonsSection + '\n' : '');
|
|
105
|
+
await fs.writeFile(modelsFile, modelsContent, 'utf-8');
|
|
106
|
+
filesWritten.push(modelsFile);
|
|
107
|
+
// references/data-semantics.md: fill model names line into template
|
|
108
|
+
const modelNamesLine = buildModelNamesLine(models);
|
|
109
|
+
const semanticsContent = semanticsTemplate
|
|
110
|
+
.replace('<!-- MODEL_NAMES -->', modelNamesLine);
|
|
111
|
+
await fs.writeFile(dataSemanticsFile, semanticsContent, 'utf-8');
|
|
112
|
+
filesWritten.push(dataSemanticsFile);
|
|
113
|
+
return { skillDir, skillPromptFile, modelsFile, dataSemanticsFile, filesWritten };
|
|
287
114
|
}
|
|
288
115
|
//# sourceMappingURL=capability-generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-generator.js","sourceRoot":"","sources":["../src/capability-generator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"capability-generator.js","sourceRoot":"","sources":["../src/capability-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loom build
|
|
3
|
+
*
|
|
4
|
+
* Build a Loom project for production:
|
|
5
|
+
* 1. Frontend (vite build) → dist/frontend/
|
|
6
|
+
* 2. Backend (tsc) → dist/backend/
|
|
7
|
+
* 3. MCP Server (copy source, runs via tsx) → dist/mcp-server/
|
|
8
|
+
*/
|
|
9
|
+
import type { Command } from 'commander';
|
|
10
|
+
export declare function registerBuildCommand(program: Command): void;
|
|
11
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8D3D"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loom build
|
|
3
|
+
*
|
|
4
|
+
* Build a Loom project for production:
|
|
5
|
+
* 1. Frontend (vite build) → dist/frontend/
|
|
6
|
+
* 2. Backend (tsc) → dist/backend/
|
|
7
|
+
* 3. MCP Server (copy source, runs via tsx) → dist/mcp-server/
|
|
8
|
+
*/
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import ora from 'ora';
|
|
11
|
+
import { spawn } from 'child_process';
|
|
12
|
+
import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync } from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { resolveProjectRoot } from '../utils.js';
|
|
15
|
+
export function registerBuildCommand(program) {
|
|
16
|
+
program
|
|
17
|
+
.command('build')
|
|
18
|
+
.description('Build project for production (frontend + backend + MCP server)')
|
|
19
|
+
.option('--frontend', 'Build only frontend')
|
|
20
|
+
.option('--backend', 'Build only backend')
|
|
21
|
+
.option('--mcp', 'Build only MCP server')
|
|
22
|
+
.action(async (options) => {
|
|
23
|
+
try {
|
|
24
|
+
const projectRoot = await resolveProjectRoot();
|
|
25
|
+
const steps = resolveBuildSteps(projectRoot, options);
|
|
26
|
+
const copySteps = resolveCopySteps(projectRoot, options);
|
|
27
|
+
if (steps.length === 0 && copySteps.length === 0) {
|
|
28
|
+
console.error(chalk.red('No buildable components found.'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
console.log(chalk.bold('Building project for production...'));
|
|
32
|
+
console.log(chalk.dim(` Project: ${projectRoot}`));
|
|
33
|
+
console.log();
|
|
34
|
+
// Ensure dist/ directory exists
|
|
35
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
36
|
+
if (!existsSync(distDir)) {
|
|
37
|
+
mkdirSync(distDir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
// Run spawn-based build steps
|
|
40
|
+
for (const step of steps) {
|
|
41
|
+
const spinner = ora(`Building ${chalk.cyan(step.label)}...`).start();
|
|
42
|
+
const exitCode = await runCommand(step.command, step.args, step.cwd);
|
|
43
|
+
if (exitCode === 0) {
|
|
44
|
+
spinner.succeed(chalk.green(`${step.label} built successfully`));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
spinner.fail(chalk.red(`${step.label} build failed (exit code ${exitCode})`));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Run copy-based steps (MCP Server, etc.)
|
|
52
|
+
for (const step of copySteps) {
|
|
53
|
+
const spinner = ora(`Copying ${chalk.cyan(step.label)}...`).start();
|
|
54
|
+
try {
|
|
55
|
+
copyDirRecursive(step.srcDir, step.destDir, step.exclude);
|
|
56
|
+
spinner.succeed(chalk.green(`${step.label} copied successfully`));
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
spinner.fail(chalk.red(`${step.label} copy failed: ${err}`));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.log();
|
|
64
|
+
console.log(chalk.green.bold('Build complete!'));
|
|
65
|
+
console.log(chalk.dim(' Output: dist/'));
|
|
66
|
+
console.log(chalk.dim(' Start: node dist/backend/src/index.js'));
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
70
|
+
console.error(chalk.red('Build failed:'), message);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function resolveBuildSteps(projectRoot, options) {
|
|
76
|
+
const hasFilter = options.frontend || options.backend || options.mcp;
|
|
77
|
+
const steps = [];
|
|
78
|
+
// Frontend: vite build → dist/frontend/
|
|
79
|
+
if (!hasFilter || options.frontend) {
|
|
80
|
+
const frontendDir = path.join(projectRoot, 'frontend');
|
|
81
|
+
if (existsSync(frontendDir)) {
|
|
82
|
+
steps.push({
|
|
83
|
+
name: 'frontend',
|
|
84
|
+
label: 'Frontend (vite build)',
|
|
85
|
+
command: 'npx',
|
|
86
|
+
args: ['vite', 'build', '--outDir', '../dist/frontend'],
|
|
87
|
+
cwd: frontendDir,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Backend: tsc → dist/backend/
|
|
92
|
+
if (!hasFilter || options.backend) {
|
|
93
|
+
const backendDir = path.join(projectRoot, 'backend');
|
|
94
|
+
if (existsSync(backendDir)) {
|
|
95
|
+
steps.push({
|
|
96
|
+
name: 'backend',
|
|
97
|
+
label: 'Backend (tsc)',
|
|
98
|
+
command: 'npx',
|
|
99
|
+
args: ['tsc', '--outDir', '../dist/backend'],
|
|
100
|
+
cwd: backendDir,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return steps;
|
|
105
|
+
}
|
|
106
|
+
function resolveCopySteps(projectRoot, options) {
|
|
107
|
+
const hasFilter = options.frontend || options.backend || options.mcp;
|
|
108
|
+
const steps = [];
|
|
109
|
+
// MCP Server: copy source to dist (runs via tsx, no compilation needed)
|
|
110
|
+
if (!hasFilter || options.mcp) {
|
|
111
|
+
const mcpDir = path.join(projectRoot, '.loom', 'mcp-server');
|
|
112
|
+
if (existsSync(mcpDir)) {
|
|
113
|
+
steps.push({
|
|
114
|
+
name: 'mcp-server',
|
|
115
|
+
label: 'MCP Server',
|
|
116
|
+
srcDir: mcpDir,
|
|
117
|
+
destDir: path.join(projectRoot, 'dist', 'mcp-server'),
|
|
118
|
+
exclude: ['node_modules', 'package-lock.json'],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return steps;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Recursively copy a directory, excluding specified entries.
|
|
126
|
+
*/
|
|
127
|
+
function copyDirRecursive(src, dest, exclude) {
|
|
128
|
+
if (!existsSync(dest)) {
|
|
129
|
+
mkdirSync(dest, { recursive: true });
|
|
130
|
+
}
|
|
131
|
+
const entries = readdirSync(src);
|
|
132
|
+
for (const entry of entries) {
|
|
133
|
+
if (exclude.includes(entry))
|
|
134
|
+
continue;
|
|
135
|
+
const srcPath = path.join(src, entry);
|
|
136
|
+
const destPath = path.join(dest, entry);
|
|
137
|
+
const stat = statSync(srcPath);
|
|
138
|
+
if (stat.isDirectory()) {
|
|
139
|
+
copyDirRecursive(srcPath, destPath, exclude);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
copyFileSync(srcPath, destPath);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function runCommand(command, args, cwd) {
|
|
147
|
+
return new Promise((resolve) => {
|
|
148
|
+
const proc = spawn(command, args, {
|
|
149
|
+
cwd,
|
|
150
|
+
stdio: 'pipe',
|
|
151
|
+
shell: true,
|
|
152
|
+
});
|
|
153
|
+
proc.stdout?.on('data', (data) => {
|
|
154
|
+
const lines = data.toString().trim().split('\n');
|
|
155
|
+
for (const line of lines) {
|
|
156
|
+
console.log(chalk.gray(' >'), line);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
proc.stderr?.on('data', (data) => {
|
|
160
|
+
const lines = data.toString().trim().split('\n');
|
|
161
|
+
for (const line of lines) {
|
|
162
|
+
console.error(chalk.gray(' >'), chalk.yellow(line));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
proc.on('close', (code) => {
|
|
166
|
+
resolve(code ?? 1);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loom data - Data operations via DataAdapter
|
|
3
|
+
*
|
|
4
|
+
* loom data read <model> [--filter] [--id]
|
|
5
|
+
* loom data write <model> --data <json>
|
|
6
|
+
* loom data update <model> --id <id> --data <json>
|
|
7
|
+
* loom data delete <model> --id <id>
|
|
8
|
+
* loom data schema [model]
|
|
9
|
+
*/
|
|
10
|
+
import type { Command } from 'commander';
|
|
11
|
+
export declare function registerDataCommand(program: Command): void;
|
|
12
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8H1D"}
|