@loom-framework/core 0.1.0-alpha.39 → 0.1.0-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/backend/ai/button-resolver.d.ts +17 -0
  2. package/dist/backend/ai/button-resolver.d.ts.map +1 -0
  3. package/dist/backend/ai/button-resolver.js +40 -0
  4. package/dist/backend/ai/button-resolver.js.map +1 -0
  5. package/dist/backend/ai/engine.d.ts +51 -0
  6. package/dist/backend/ai/engine.d.ts.map +1 -0
  7. package/dist/backend/ai/engine.js +188 -0
  8. package/dist/backend/ai/engine.js.map +1 -0
  9. package/dist/backend/ai/index.d.ts +11 -0
  10. package/dist/backend/ai/index.d.ts.map +1 -0
  11. package/dist/backend/ai/index.js +8 -0
  12. package/dist/backend/ai/index.js.map +1 -0
  13. package/dist/backend/ai/output-parser.d.ts +29 -0
  14. package/dist/backend/ai/output-parser.d.ts.map +1 -0
  15. package/dist/backend/ai/output-parser.js +247 -0
  16. package/dist/backend/ai/output-parser.js.map +1 -0
  17. package/dist/backend/ai/session-manager.d.ts +102 -0
  18. package/dist/backend/ai/session-manager.d.ts.map +1 -0
  19. package/dist/backend/ai/session-manager.js +291 -0
  20. package/dist/backend/ai/session-manager.js.map +1 -0
  21. package/dist/backend/index.d.ts +61 -0
  22. package/dist/backend/index.d.ts.map +1 -0
  23. package/dist/backend/index.js +160 -0
  24. package/dist/backend/index.js.map +1 -0
  25. package/dist/backend/observe/index.d.ts +6 -0
  26. package/dist/backend/observe/index.d.ts.map +1 -0
  27. package/dist/backend/observe/index.js +5 -0
  28. package/dist/backend/observe/index.js.map +1 -0
  29. package/dist/backend/observe/logger.d.ts +28 -0
  30. package/dist/backend/observe/logger.d.ts.map +1 -0
  31. package/dist/backend/observe/logger.js +80 -0
  32. package/dist/backend/observe/logger.js.map +1 -0
  33. package/dist/backend/observe/types.d.ts +26 -0
  34. package/dist/backend/observe/types.d.ts.map +1 -0
  35. package/dist/backend/observe/types.js +7 -0
  36. package/dist/backend/observe/types.js.map +1 -0
  37. package/dist/backend/routes/chat.d.ts +31 -0
  38. package/dist/backend/routes/chat.d.ts.map +1 -0
  39. package/dist/backend/routes/chat.js +426 -0
  40. package/dist/backend/routes/chat.js.map +1 -0
  41. package/dist/backend/routes/data.d.ts +13 -0
  42. package/dist/backend/routes/data.d.ts.map +1 -0
  43. package/dist/backend/routes/data.js +129 -0
  44. package/dist/backend/routes/data.js.map +1 -0
  45. package/dist/backend/routes/health.d.ts +7 -0
  46. package/dist/backend/routes/health.d.ts.map +1 -0
  47. package/dist/backend/routes/health.js +15 -0
  48. package/dist/backend/routes/health.js.map +1 -0
  49. package/dist/backend/routes/index.d.ts +9 -0
  50. package/dist/backend/routes/index.d.ts.map +1 -0
  51. package/dist/backend/routes/index.js +8 -0
  52. package/dist/backend/routes/index.js.map +1 -0
  53. package/dist/backend/routes/upload.d.ts +24 -0
  54. package/dist/backend/routes/upload.d.ts.map +1 -0
  55. package/dist/backend/routes/upload.js +67 -0
  56. package/dist/backend/routes/upload.js.map +1 -0
  57. package/dist/bin.d.ts +8 -0
  58. package/dist/bin.d.ts.map +1 -0
  59. package/dist/bin.js +12 -0
  60. package/dist/bin.js.map +1 -0
  61. package/dist/cli/commands/build.d.ts +11 -0
  62. package/dist/cli/commands/build.d.ts.map +1 -0
  63. package/dist/cli/commands/build.js +170 -0
  64. package/dist/cli/commands/build.js.map +1 -0
  65. package/dist/cli/commands/data.d.ts +11 -0
  66. package/dist/cli/commands/data.d.ts.map +1 -0
  67. package/dist/cli/commands/data.js +137 -0
  68. package/dist/cli/commands/data.js.map +1 -0
  69. package/dist/cli/commands/dev.d.ts +9 -0
  70. package/dist/cli/commands/dev.d.ts.map +1 -0
  71. package/dist/cli/commands/dev.js +114 -0
  72. package/dist/cli/commands/dev.js.map +1 -0
  73. package/dist/cli/commands/generate-capabilities.d.ts +8 -0
  74. package/dist/cli/commands/generate-capabilities.d.ts.map +1 -0
  75. package/dist/cli/commands/generate-capabilities.js +40 -0
  76. package/dist/cli/commands/generate-capabilities.js.map +1 -0
  77. package/dist/cli/commands/generate-cli-command.d.ts +8 -0
  78. package/dist/cli/commands/generate-cli-command.d.ts.map +1 -0
  79. package/dist/cli/commands/generate-cli-command.js +64 -0
  80. package/dist/cli/commands/generate-cli-command.js.map +1 -0
  81. package/dist/cli/commands/generate-page.d.ts +9 -0
  82. package/dist/cli/commands/generate-page.d.ts.map +1 -0
  83. package/dist/cli/commands/generate-page.js +325 -0
  84. package/dist/cli/commands/generate-page.js.map +1 -0
  85. package/dist/cli/commands/generate-skill.d.ts +8 -0
  86. package/dist/cli/commands/generate-skill.d.ts.map +1 -0
  87. package/dist/cli/commands/generate-skill.js +75 -0
  88. package/dist/cli/commands/generate-skill.js.map +1 -0
  89. package/dist/cli/commands/generate.d.ts +6 -0
  90. package/dist/cli/commands/generate.d.ts.map +1 -0
  91. package/dist/cli/commands/generate.js +17 -0
  92. package/dist/cli/commands/generate.js.map +1 -0
  93. package/dist/cli/commands/init.d.ts +8 -0
  94. package/dist/cli/commands/init.d.ts.map +1 -0
  95. package/dist/cli/commands/init.js +400 -0
  96. package/dist/cli/commands/init.js.map +1 -0
  97. package/dist/cli/commands/observe.d.ts +9 -0
  98. package/dist/cli/commands/observe.d.ts.map +1 -0
  99. package/dist/cli/commands/observe.js +142 -0
  100. package/dist/cli/commands/observe.js.map +1 -0
  101. package/dist/cli/commands/skill.d.ts +9 -0
  102. package/dist/cli/commands/skill.d.ts.map +1 -0
  103. package/dist/cli/commands/skill.js +186 -0
  104. package/dist/cli/commands/skill.js.map +1 -0
  105. package/dist/cli/helpers/duration.d.ts +5 -0
  106. package/dist/cli/helpers/duration.d.ts.map +1 -0
  107. package/dist/cli/helpers/duration.js +19 -0
  108. package/dist/cli/helpers/duration.js.map +1 -0
  109. package/dist/cli/helpers/field-template.d.ts +9 -0
  110. package/dist/cli/helpers/field-template.d.ts.map +1 -0
  111. package/dist/cli/helpers/field-template.js +59 -0
  112. package/dist/cli/helpers/field-template.js.map +1 -0
  113. package/dist/cli/helpers/naming.d.ts +6 -0
  114. package/dist/cli/helpers/naming.d.ts.map +1 -0
  115. package/dist/cli/helpers/naming.js +14 -0
  116. package/dist/cli/helpers/naming.js.map +1 -0
  117. package/dist/cli/index.d.ts +9 -0
  118. package/dist/cli/index.d.ts.map +1 -0
  119. package/dist/cli/index.js +33 -0
  120. package/dist/cli/index.js.map +1 -0
  121. package/dist/cli/utils.d.ts +10 -0
  122. package/dist/cli/utils.d.ts.map +1 -0
  123. package/dist/cli/utils.js +31 -0
  124. package/dist/cli/utils.js.map +1 -0
  125. package/dist/index.d.ts +3 -0
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +4 -0
  128. package/dist/index.js.map +1 -1
  129. package/dist/server-bin.d.ts +12 -0
  130. package/dist/server-bin.d.ts.map +1 -0
  131. package/dist/server-bin.js +75 -0
  132. package/dist/server-bin.js.map +1 -0
  133. package/package.json +17 -5
  134. package/templates/skill/SKILL.md +91 -0
  135. package/templates/skill/references/README.md +67 -0
  136. package/templates/skill/references/data-model.md +87 -0
  137. package/templates/skill/references/skill-development.md +46 -0
  138. package/templates/skill/references/troubleshooting.md +35 -0
@@ -0,0 +1,325 @@
1
+ /**
2
+ * loom generate page <name>
3
+ *
4
+ * With --model: generate capabilities → CRUD page → auto-wire App.tsx
5
+ * Without --model: generate minimal skeleton page
6
+ */
7
+ import chalk from 'chalk';
8
+ import { promises as fs } from 'fs';
9
+ import path from 'path';
10
+ import { loadConfig, getModelSchema, generateCapabilities } from '../../index.js';
11
+ import { resolveProjectRoot } from '../utils.js';
12
+ import { toPascalCase, toCamelCase } from '../helpers/naming.js';
13
+ import { fieldToFormItem } from '../helpers/field-template.js';
14
+ /** Generate table columns from model fields */
15
+ function generateColumns(fields, modelName) {
16
+ const cols = fields
17
+ .filter((f) => f.name !== 'id') // skip id column in form
18
+ .map((f) => {
19
+ const label = f.description || f.name;
20
+ const renders = [];
21
+ if (f.type === 'boolean') {
22
+ renders.push(` render: (val: boolean) => val ? '是' : '否',`);
23
+ }
24
+ else if (f.type === 'string[]') {
25
+ renders.push(` render: (val: string[]) => val?.join(', '),`);
26
+ }
27
+ else if (f.type === 'number[]') {
28
+ renders.push(` render: (val: number[]) => val?.join(', '),`);
29
+ }
30
+ return ` {
31
+ title: '${label}',
32
+ dataIndex: '${f.name}',
33
+ key: '${f.name}',
34
+ ${renders.join('\n')} },`;
35
+ })
36
+ .join('\n');
37
+ // Add action column
38
+ return `${cols}
39
+ {
40
+ title: '操作',
41
+ key: 'action',
42
+ render: (_: unknown, record: ${toPascalCase(modelName)}Record) => (
43
+ <Space>
44
+ <Button type="link" onClick={() => handleEdit(record)}>编辑</Button>
45
+ <Popconfirm title="确认删除?" onConfirm={() => handleDelete(record.id)}>
46
+ <Button type="link" danger>删除</Button>
47
+ </Popconfirm>
48
+ </Space>
49
+ ),
50
+ },`;
51
+ }
52
+ /** Generate CRUD page template from model schema */
53
+ function crudPageTemplate(model) {
54
+ const pascalName = toPascalCase(model.name);
55
+ const camelName = toCamelCase(model.name);
56
+ const recordType = `${pascalName}Record`;
57
+ // Build TypeScript interface from fields
58
+ const fieldDefs = model.fields.map((f) => {
59
+ const tsType = f.type === 'string[]' ? 'string[]'
60
+ : f.type === 'number[]' ? 'number[]'
61
+ : f.type === 'json' ? 'Record<string, unknown>'
62
+ : f.type === 'number' ? 'number'
63
+ : f.type === 'boolean' ? 'boolean'
64
+ : f.type === 'date' ? 'string'
65
+ : 'string';
66
+ return ` ${f.name}${f.required ? '' : '?'}: ${tsType};`;
67
+ }).join('\n');
68
+ const columns = generateColumns(model.fields, model.name);
69
+ const formItems = model.fields
70
+ .filter((f) => f.name !== 'id') // id is auto-generated
71
+ .map((f) => fieldToFormItem(f, model.name))
72
+ .join('\n');
73
+ return `import React, { useEffect, useState } from 'react';
74
+ import { Table, Button, Modal, Form, Input, InputNumber, Select, Switch, DatePicker, Space, Popconfirm, message } from 'antd';
75
+ import { PlusOutlined } from '@ant-design/icons';
76
+ import { useData } from '@loom-framework/frontend-antd';
77
+
78
+ interface ${recordType} {
79
+ ${fieldDefs}
80
+ }
81
+
82
+ export function ${pascalName}Page(): React.ReactElement {
83
+ const { list, create, update, remove, loading, refresh } = useData<${recordType}>('${model.name}');
84
+ const [form] = Form.useForm();
85
+ const [modalOpen, setModalOpen] = useState(false);
86
+ const [editingRecord, setEditingRecord] = useState<${recordType} | null>(null);
87
+
88
+ useEffect(() => {
89
+ refresh();
90
+ }, [refresh]);
91
+
92
+ const handleAdd = () => {
93
+ setEditingRecord(null);
94
+ form.resetFields();
95
+ setModalOpen(true);
96
+ };
97
+
98
+ const handleEdit = (record: ${recordType}) => {
99
+ setEditingRecord(record);
100
+ form.setFieldsValue(record);
101
+ setModalOpen(true);
102
+ };
103
+
104
+ const handleDelete = async (id: string) => {
105
+ try {
106
+ await remove(id);
107
+ message.success('删除成功');
108
+ refresh();
109
+ } catch {
110
+ message.error('删除失败');
111
+ }
112
+ };
113
+
114
+ const handleSave = async () => {
115
+ try {
116
+ const values = await form.validateFields();
117
+ if (editingRecord?.id) {
118
+ await update(editingRecord.id, values);
119
+ message.success('更新成功');
120
+ } else {
121
+ await create(values);
122
+ message.success('创建成功');
123
+ }
124
+ setModalOpen(false);
125
+ refresh();
126
+ } catch {
127
+ // form validation failed
128
+ }
129
+ };
130
+
131
+ const columns = [
132
+ ${columns}
133
+ ];
134
+
135
+ return (
136
+ <div style={{ padding: 24 }}>
137
+ <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
138
+ <h2>${model.description || pascalName}管理</h2>
139
+ <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
140
+ 新增
141
+ </Button>
142
+ </div>
143
+
144
+ <Table
145
+ columns={columns}
146
+ dataSource={list}
147
+ rowKey="id"
148
+ loading={loading}
149
+ />
150
+
151
+ <Modal
152
+ title={editingRecord ? '编辑' : '新增'}
153
+ open={modalOpen}
154
+ onOk={handleSave}
155
+ onCancel={() => setModalOpen(false)}
156
+ destroyOnClose
157
+ >
158
+ <Form form={form} layout="vertical">
159
+ ${formItems}
160
+ </Form>
161
+ </Modal>
162
+ </div>
163
+ );
164
+ }
165
+
166
+ export default ${pascalName}Page;
167
+ `;
168
+ }
169
+ /** Minimal skeleton page template (no model) */
170
+ const SKELETON_TEMPLATE = (pascalName) => `import React from 'react';
171
+
172
+ export interface ${pascalName}Props {
173
+ // TODO: Define page props
174
+ }
175
+
176
+ export function ${pascalName}(props: ${pascalName}Props): React.ReactElement {
177
+ return (
178
+ <div className="${pascalName.toLowerCase()}-page">
179
+ <h1>${pascalName}</h1>
180
+ <p>TODO: Implement this page.</p>
181
+ </div>
182
+ );
183
+ }
184
+
185
+ export default ${pascalName};
186
+ `;
187
+ export function registerGeneratePageCommand(program) {
188
+ program
189
+ .command('page <name>')
190
+ .description('Create a new frontend page component with PascalCase naming')
191
+ .option('--model <model>', 'Data model name from loom.config.ts to generate CRUD page (auto-generates capabilities and wires App.tsx)')
192
+ .action(async (name, cmdOptions) => {
193
+ try {
194
+ const projectRoot = await resolveProjectRoot();
195
+ const pascalName = toPascalCase(name);
196
+ const pageDir = path.join(projectRoot, 'frontend', 'src', 'components', 'pages');
197
+ const pagePath = path.join(pageDir, `${pascalName}.tsx`);
198
+ // Check if page already exists
199
+ try {
200
+ await fs.access(pagePath);
201
+ console.error(chalk.red(`Page "${pascalName}" already exists at ${pagePath}`));
202
+ process.exit(1);
203
+ }
204
+ catch {
205
+ // File does not exist, proceed
206
+ }
207
+ let template;
208
+ let modelLabel = pascalName;
209
+ if (cmdOptions.model) {
210
+ // Load config and find model schema
211
+ const config = await loadConfig(projectRoot);
212
+ const modelSchema = getModelSchema(config, cmdOptions.model);
213
+ if (!modelSchema) {
214
+ console.error(chalk.red(`Model "${cmdOptions.model}" not found in loom.config.ts`));
215
+ console.error(chalk.dim(`Available models: ${config.data.models.map((m) => m.name).join(', ')}`));
216
+ process.exit(1);
217
+ }
218
+ modelLabel = modelSchema.description || pascalName;
219
+ // Step 1: Auto-generate capabilities (MCP Server + CLI data commands)
220
+ const capResult = await generateCapabilities(projectRoot, config);
221
+ console.log(chalk.green('Capabilities generated'), chalk.dim(`(${capResult.filesWritten.length} files)`));
222
+ // Step 2: Generate CRUD page
223
+ template = crudPageTemplate(modelSchema);
224
+ }
225
+ else {
226
+ template = SKELETON_TEMPLATE(pascalName);
227
+ }
228
+ await fs.mkdir(pageDir, { recursive: true });
229
+ await fs.writeFile(pagePath, template, 'utf-8');
230
+ console.log(chalk.green('Page created successfully!'));
231
+ console.log();
232
+ console.log(chalk.bold(' Page:'), pascalName);
233
+ console.log(chalk.bold(' Path:'), path.join('frontend', 'src', 'components', 'pages', `${pascalName}.tsx`));
234
+ if (cmdOptions.model) {
235
+ console.log(chalk.bold(' Model:'), cmdOptions.model);
236
+ }
237
+ // Step 3: Auto-wire App.tsx when using --model
238
+ if (cmdOptions.model) {
239
+ const wired = await wireAppTsxAutomatic(projectRoot, pascalName, cmdOptions.model, modelLabel);
240
+ if (wired) {
241
+ console.log(chalk.green(' App.tsx wired automatically'));
242
+ }
243
+ else {
244
+ console.log(chalk.yellow(' Could not auto-wire App.tsx — add the page import, navItem, and switch case manually'));
245
+ }
246
+ }
247
+ else {
248
+ console.log();
249
+ console.log(chalk.dim(' Use --model <name> to generate a CRUD page from a data model.'));
250
+ }
251
+ }
252
+ catch (err) {
253
+ const message = err instanceof Error ? err.message : String(err);
254
+ console.error(chalk.red('Failed to create page:'), message);
255
+ process.exit(1);
256
+ }
257
+ });
258
+ }
259
+ /**
260
+ * Auto-wire App.tsx: add import, navItem, and switch case for a new page.
261
+ * Returns true if successful, false if App.tsx structure is unexpected.
262
+ */
263
+ async function wireAppTsxAutomatic(projectRoot, pascalName, modelKey, modelLabel) {
264
+ const appPath = path.join(projectRoot, 'frontend', 'src', 'App.tsx');
265
+ let content;
266
+ try {
267
+ content = await fs.readFile(appPath, 'utf-8');
268
+ }
269
+ catch {
270
+ return false;
271
+ }
272
+ // Check if this page is already wired (avoid duplicates)
273
+ if (content.includes(`from './components/pages/${pascalName}'`) || content.includes(`<${pascalName}Page`)) {
274
+ return false;
275
+ }
276
+ let modified = content;
277
+ // 1. Add import after the last import line
278
+ const importLine = `import ${pascalName}Page from './components/pages/${pascalName}';`;
279
+ const lastImportEnd = modified.lastIndexOf('\n', modified.indexOf('\nexport'));
280
+ if (lastImportEnd === -1)
281
+ return false;
282
+ modified = modified.slice(0, lastImportEnd + 1) + importLine + '\n' + modified.slice(lastImportEnd + 1);
283
+ // 2. Add navItem (before the closing ] of navItems array)
284
+ const navItemLine = ` { key: '${modelKey}', label: '${modelLabel}' },`;
285
+ const navItemsEnd = modified.indexOf('// Add more nav items');
286
+ if (navItemsEnd !== -1) {
287
+ // Insert before the comment placeholder
288
+ const lineStart = modified.lastIndexOf('\n', navItemsEnd) + 1;
289
+ modified = modified.slice(0, lineStart) + navItemLine + '\n' + modified.slice(lineStart);
290
+ }
291
+ else {
292
+ // Fallback: find the closing ] of navItems array
293
+ const navArrayMatch = modified.match(/const navItems\s*=\s*\[/);
294
+ if (!navArrayMatch)
295
+ return false;
296
+ const arrayStart = navArrayMatch.index + navArrayMatch[0].length;
297
+ // Find the matching ]
298
+ let depth = 1;
299
+ let pos = arrayStart;
300
+ while (pos < modified.length && depth > 0) {
301
+ if (modified[pos] === '[')
302
+ depth++;
303
+ else if (modified[pos] === ']')
304
+ depth--;
305
+ pos++;
306
+ }
307
+ const closingBracket = pos - 1;
308
+ modified = modified.slice(0, closingBracket) + navItemLine + '\n' + modified.slice(closingBracket);
309
+ }
310
+ // 3. Add switch case (before the default case)
311
+ const caseLine = ` case '${modelKey}': return <${pascalName}Page />;`;
312
+ const defaultCase = modified.indexOf('default:');
313
+ if (defaultCase === -1)
314
+ return false;
315
+ // Find the line start of the default case
316
+ const defaultLineStart = modified.lastIndexOf('\n', defaultCase) + 1;
317
+ modified = modified.slice(0, defaultLineStart) + caseLine + '\n' + modified.slice(defaultLineStart);
318
+ // 4. Ensure baseUrl="" on AppShell (prevent /api/v1/api/v1 double prefix)
319
+ if (modified.includes('<AppShell') && !modified.includes('baseUrl=')) {
320
+ modified = modified.replace('<AppShell', '<AppShell\n baseUrl=""');
321
+ }
322
+ await fs.writeFile(appPath, modified, 'utf-8');
323
+ return true;
324
+ }
325
+ //# sourceMappingURL=generate-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-page.js","sourceRoot":"","sources":["../../../src/cli/commands/generate-page.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * loom generate skill <name>
3
+ *
4
+ * Create .claude/skills/<name>/SKILL.md skeleton and references/ directory.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerGenerateSkillCommand(program: Command): void;
8
+ //# sourceMappingURL=generate-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-skill.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate-skill.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCzC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyCnE"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * loom generate skill <name>
3
+ *
4
+ * Create .claude/skills/<name>/SKILL.md skeleton and references/ directory.
5
+ */
6
+ import chalk from 'chalk';
7
+ import { promises as fs } from 'fs';
8
+ import path from 'path';
9
+ import { resolveProjectRoot } from '../utils.js';
10
+ const SKILL_MD_TEMPLATE = (name) => `---
11
+ name: ${name}
12
+ version: 0.1.0
13
+ description: ""
14
+ tags: []
15
+ ---
16
+
17
+ # ${name}
18
+
19
+ ## Overview
20
+
21
+ TODO: Describe what this skill does.
22
+
23
+ ## Instructions
24
+
25
+ TODO: Step-by-step instructions for the skill.
26
+
27
+ ## Examples
28
+
29
+ TODO: Example inputs and outputs.
30
+
31
+ ## References
32
+
33
+ TODO: List reference files in the references/ directory.
34
+ `;
35
+ export function registerGenerateSkillCommand(program) {
36
+ program
37
+ .command('skill <name>')
38
+ .description('Create a new skill skeleton with SKILL.md and references directory')
39
+ .action(async (name) => {
40
+ try {
41
+ const projectRoot = await resolveProjectRoot();
42
+ const skillDir = path.join(projectRoot, '.claude', 'skills', name);
43
+ const skillMdPath = path.join(skillDir, 'SKILL.md');
44
+ const referencesDir = path.join(skillDir, 'references');
45
+ // Check if skill already exists
46
+ try {
47
+ await fs.access(skillDir);
48
+ console.error(chalk.red(`Skill "${name}" already exists at ${skillDir}`));
49
+ process.exit(1);
50
+ }
51
+ catch {
52
+ // Directory does not exist, proceed
53
+ }
54
+ await fs.mkdir(referencesDir, { recursive: true });
55
+ await fs.writeFile(skillMdPath, SKILL_MD_TEMPLATE(name), 'utf-8');
56
+ // Create a .gitkeep in references so the directory is tracked
57
+ await fs.writeFile(path.join(referencesDir, '.gitkeep'), '', 'utf-8');
58
+ console.log(chalk.green('Skill created successfully!'));
59
+ console.log();
60
+ console.log(chalk.bold(' Skill:'), name);
61
+ console.log(chalk.bold(' Path:'), skillDir);
62
+ console.log(chalk.bold(' Files:'));
63
+ console.log(chalk.gray(' -'), 'SKILL.md');
64
+ console.log(chalk.gray(' -'), 'references/');
65
+ console.log();
66
+ console.log(chalk.dim(` Edit ${path.join('.claude/skills', name, 'SKILL.md')} to define the skill.`));
67
+ }
68
+ catch (err) {
69
+ const message = err instanceof Error ? err.message : String(err);
70
+ console.error(chalk.red('Failed to create skill:'), message);
71
+ process.exit(1);
72
+ }
73
+ });
74
+ }
75
+ //# sourceMappingURL=generate-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-skill.js","sourceRoot":"","sources":["../../../src/cli/commands/generate-skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * loom generate - Code generation commands
3
+ */
4
+ import type { Command } from 'commander';
5
+ export declare function registerGenerateCommand(program: Command): void;
6
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS9D"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * loom generate - Code generation commands
3
+ */
4
+ import { registerGenerateCapabilitiesCommand } from './generate-capabilities.js';
5
+ import { registerGenerateSkillCommand } from './generate-skill.js';
6
+ import { registerGeneratePageCommand } from './generate-page.js';
7
+ import { registerGenerateCliCommandCommand } from './generate-cli-command.js';
8
+ export function registerGenerateCommand(program) {
9
+ const generate = program
10
+ .command('generate')
11
+ .description('Generate code from config and templates');
12
+ registerGenerateCapabilitiesCommand(generate);
13
+ registerGenerateSkillCommand(generate);
14
+ registerGeneratePageCommand(generate);
15
+ registerGenerateCliCommandCommand(generate);
16
+ }
17
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,mCAAmC,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAE9E,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,yCAAyC,CAAC,CAAC;IAE1D,mCAAmC,CAAC,QAAQ,CAAC,CAAC;IAC9C,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IACvC,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IACtC,iCAAiC,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * loom init <name>
3
+ *
4
+ * Create a new Loom project. All options via CLI flags, no interactive prompts.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerInitCommand(program: Command): void;
8
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe1D"}