@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,186 @@
1
+ /**
2
+ * loom skill - Skill management commands
3
+ *
4
+ * loom skill list - Scan .claude/skills/ directory, list all skills
5
+ * loom skill validate [name] - Validate SKILL.md frontmatter and references
6
+ */
7
+ import chalk from 'chalk';
8
+ import { promises as fs } from 'fs';
9
+ import path from 'path';
10
+ import { resolveProjectRoot } from '../utils.js';
11
+ export function registerSkillCommand(program) {
12
+ const skill = program
13
+ .command('skill')
14
+ .description('Skill management commands');
15
+ // loom skill list
16
+ skill
17
+ .command('list')
18
+ .description('List all skills in the project')
19
+ .action(async () => {
20
+ try {
21
+ const projectRoot = await resolveProjectRoot();
22
+ const skillsDir = path.join(projectRoot, '.claude', 'skills');
23
+ let entries;
24
+ try {
25
+ entries = await fs.readdir(skillsDir);
26
+ }
27
+ catch {
28
+ console.log(chalk.yellow('No skills directory found.'));
29
+ console.log(chalk.dim(' Run `loom generate skill <name>` to create one.'));
30
+ return;
31
+ }
32
+ const skillDirs = entries.filter(async (entry) => {
33
+ const stat = await fs.stat(path.join(skillsDir, entry));
34
+ return stat.isDirectory();
35
+ });
36
+ const validSkillDirs = [];
37
+ for (const entry of entries) {
38
+ const entryPath = path.join(skillsDir, entry);
39
+ try {
40
+ const stat = await fs.stat(entryPath);
41
+ if (stat.isDirectory()) {
42
+ validSkillDirs.push(entry);
43
+ }
44
+ }
45
+ catch {
46
+ continue;
47
+ }
48
+ }
49
+ if (validSkillDirs.length === 0) {
50
+ console.log(chalk.yellow('No skills found.'));
51
+ console.log(chalk.dim(' Run `loom generate skill <name>` to create one.'));
52
+ return;
53
+ }
54
+ console.log(chalk.bold(`Skills (${validSkillDirs.length}):`));
55
+ console.log();
56
+ for (const dirName of validSkillDirs) {
57
+ const skillMdPath = path.join(skillsDir, dirName, 'SKILL.md');
58
+ let hasSkillMd = false;
59
+ try {
60
+ await fs.access(skillMdPath);
61
+ hasSkillMd = true;
62
+ }
63
+ catch {
64
+ // No SKILL.md
65
+ }
66
+ const marker = hasSkillMd ? chalk.green('✓') : chalk.red('✗');
67
+ console.log(` ${marker} ${chalk.cyan(dirName)}`);
68
+ if (!hasSkillMd) {
69
+ console.log(chalk.dim(` Missing SKILL.md`));
70
+ }
71
+ }
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : String(err);
75
+ console.error(chalk.red('Failed to list skills:'), message);
76
+ process.exit(1);
77
+ }
78
+ });
79
+ // loom skill validate [name]
80
+ skill
81
+ .command('validate [name]')
82
+ .description('Validate skill SKILL.md frontmatter and references')
83
+ .action(async (name) => {
84
+ try {
85
+ const projectRoot = await resolveProjectRoot();
86
+ const skillsDir = path.join(projectRoot, '.claude', 'skills');
87
+ if (name) {
88
+ // Validate specific skill
89
+ await validateSkill(skillsDir, name);
90
+ }
91
+ else {
92
+ // Validate all skills
93
+ let entries;
94
+ try {
95
+ entries = await fs.readdir(skillsDir);
96
+ }
97
+ catch {
98
+ console.log(chalk.yellow('No skills directory found.'));
99
+ return;
100
+ }
101
+ const dirs = [];
102
+ for (const entry of entries) {
103
+ try {
104
+ const stat = await fs.stat(path.join(skillsDir, entry));
105
+ if (stat.isDirectory())
106
+ dirs.push(entry);
107
+ }
108
+ catch {
109
+ continue;
110
+ }
111
+ }
112
+ if (dirs.length === 0) {
113
+ console.log(chalk.yellow('No skills to validate.'));
114
+ return;
115
+ }
116
+ let allValid = true;
117
+ for (const dir of dirs) {
118
+ const valid = await validateSkill(skillsDir, dir);
119
+ if (!valid)
120
+ allValid = false;
121
+ }
122
+ if (!allValid) {
123
+ process.exit(1);
124
+ }
125
+ }
126
+ }
127
+ catch (err) {
128
+ const message = err instanceof Error ? err.message : String(err);
129
+ console.error(chalk.red('Validation failed:'), message);
130
+ process.exit(1);
131
+ }
132
+ });
133
+ }
134
+ /**
135
+ * Validate a single skill directory
136
+ */
137
+ async function validateSkill(skillsDir, name) {
138
+ const skillDir = path.join(skillsDir, name);
139
+ const errors = [];
140
+ // Check SKILL.md exists
141
+ const skillMdPath = path.join(skillDir, 'SKILL.md');
142
+ try {
143
+ const content = await fs.readFile(skillMdPath, 'utf-8');
144
+ // Check frontmatter exists
145
+ if (!content.startsWith('---')) {
146
+ errors.push('SKILL.md is missing frontmatter (must start with ---)');
147
+ }
148
+ else {
149
+ const frontmatterEnd = content.indexOf('---', 3);
150
+ if (frontmatterEnd === -1) {
151
+ errors.push('SKILL.md has unclosed frontmatter');
152
+ }
153
+ else {
154
+ const frontmatter = content.slice(3, frontmatterEnd).trim();
155
+ // Check for required frontmatter fields
156
+ if (!frontmatter.includes('name:')) {
157
+ errors.push('SKILL.md frontmatter missing "name" field');
158
+ }
159
+ if (!frontmatter.includes('version:')) {
160
+ errors.push('SKILL.md frontmatter missing "version" field');
161
+ }
162
+ }
163
+ }
164
+ }
165
+ catch {
166
+ errors.push('SKILL.md not found');
167
+ }
168
+ // Check references/ directory exists
169
+ const referencesDir = path.join(skillDir, 'references');
170
+ try {
171
+ await fs.access(referencesDir);
172
+ }
173
+ catch {
174
+ errors.push('references/ directory not found');
175
+ }
176
+ if (errors.length > 0) {
177
+ console.log(chalk.red(` ✗ ${name}`));
178
+ for (const error of errors) {
179
+ console.log(chalk.dim(` - ${error}`));
180
+ }
181
+ return false;
182
+ }
183
+ console.log(chalk.green(` ✓ ${name}`));
184
+ return true;
185
+ }
186
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/cli/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Duration parsing utility - extracted for testability
3
+ */
4
+ export declare function parseDuration(duration: string): number;
5
+ //# sourceMappingURL=duration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../../../src/cli/helpers/duration.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CActD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Duration parsing utility - extracted for testability
3
+ */
4
+ export function parseDuration(duration) {
5
+ const match = duration.match(/^(\d+)(s|m|h|d)$/);
6
+ if (!match) {
7
+ throw new Error(`Invalid duration: ${duration}. Use format like '1h', '30m', '7d'`);
8
+ }
9
+ const value = parseInt(match[1], 10);
10
+ const unit = match[2];
11
+ switch (unit) {
12
+ case 's': return value * 1000;
13
+ case 'm': return value * 60 * 1000;
14
+ case 'h': return value * 60 * 60 * 1000;
15
+ case 'd': return value * 24 * 60 * 60 * 1000;
16
+ default: throw new Error(`Unknown unit: ${unit}`);
17
+ }
18
+ }
19
+ //# sourceMappingURL=duration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.js","sourceRoot":"","sources":["../../../src/cli/helpers/duration.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,qCAAqC,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,GAAG,IAAI,CAAC;QAC9B,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC;QACnC,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACxC,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC7C,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Field-to-template utilities - extracted for testability
3
+ */
4
+ import type { FieldDefinition, FieldType } from '../../index.js';
5
+ /** Map FieldType to Ant Design table column render hint */
6
+ export declare function fieldToColumnType(type: FieldType): string;
7
+ /** Generate Ant Design form item for a field */
8
+ export declare function fieldToFormItem(field: FieldDefinition, modelName: string): string;
9
+ //# sourceMappingURL=field-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-template.d.ts","sourceRoot":"","sources":["../../../src/cli/helpers/field-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEjE,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAYzD;AAED,gDAAgD;AAChD,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyCjF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Field-to-template utilities - extracted for testability
3
+ */
4
+ /** Map FieldType to Ant Design table column render hint */
5
+ export function fieldToColumnType(type) {
6
+ switch (type) {
7
+ case 'number':
8
+ case 'number[]':
9
+ return "'right'";
10
+ case 'boolean':
11
+ return "'bool'";
12
+ case 'date':
13
+ return "'date'";
14
+ default:
15
+ return "'text'";
16
+ }
17
+ }
18
+ /** Generate Ant Design form item for a field */
19
+ export function fieldToFormItem(field, modelName) {
20
+ const name = field.name;
21
+ const label = field.description || name;
22
+ const requiredRule = field.required ? ` rules={[{ required: true, message: '请输入${label}' }]}` : '';
23
+ if (field.enum) {
24
+ const options = field.enum.map((v) => ` <Select.Option value="${v}">${v}</Select.Option>`).join('\n');
25
+ return ` <Form.Item name="${name}" label="${label}"${requiredRule}>
26
+ <Select placeholder="请选择${label}">
27
+ ${options}
28
+ </Select>
29
+ </Form.Item>`;
30
+ }
31
+ switch (field.type) {
32
+ case 'boolean':
33
+ return ` <Form.Item name="${name}" label="${label}" valuePropName="checked">
34
+ <Switch />
35
+ </Form.Item>`;
36
+ case 'number':
37
+ case 'number[]':
38
+ return ` <Form.Item name="${name}" label="${label}"${requiredRule}>
39
+ <InputNumber style={{ width: '100%' }} />
40
+ </Form.Item>`;
41
+ case 'string[]':
42
+ return ` <Form.Item name="${name}" label="${label}">
43
+ <Select mode="tags" placeholder="请输入${label}" />
44
+ </Form.Item>`;
45
+ case 'json':
46
+ return ` <Form.Item name="${name}" label="${label}">
47
+ <Input.TextArea rows={4} placeholder="请输入JSON" />
48
+ </Form.Item>`;
49
+ case 'date':
50
+ return ` <Form.Item name="${name}" label="${label}"${requiredRule}>
51
+ <DatePicker style={{ width: '100%' }} />
52
+ </Form.Item>`;
53
+ default:
54
+ return ` <Form.Item name="${name}" label="${label}"${requiredRule}>
55
+ <Input placeholder="请输入${label}" />
56
+ </Form.Item>`;
57
+ }
58
+ }
59
+ //# sourceMappingURL=field-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-template.js","sourceRoot":"","sources":["../../../src/cli/helpers/field-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,2DAA2D;AAC3D,MAAM,UAAU,iBAAiB,CAAC,IAAe;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU;YACb,OAAO,SAAS,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,QAAQ,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,QAAQ,CAAC;QAClB;YACE,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,eAAe,CAAC,KAAsB,EAAE,SAAiB;IACvE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC;IACxC,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,2CAA2C,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iCAAiC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7G,OAAO,0BAA0B,IAAI,YAAY,KAAK,IAAI,YAAY;kCACxC,KAAK;EACrC,OAAO;;mBAEU,CAAC;IAClB,CAAC;IAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,0BAA0B,IAAI,YAAY,KAAK;;mBAEzC,CAAC;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU;YACb,OAAO,0BAA0B,IAAI,YAAY,KAAK,IAAI,YAAY;;mBAEzD,CAAC;QAChB,KAAK,UAAU;YACb,OAAO,0BAA0B,IAAI,YAAY,KAAK;8CACd,KAAK;mBAChC,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,0BAA0B,IAAI,YAAY,KAAK;;mBAEzC,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,0BAA0B,IAAI,YAAY,KAAK,IAAI,YAAY;;mBAEzD,CAAC;QAChB;YACE,OAAO,0BAA0B,IAAI,YAAY,KAAK,IAAI,YAAY;iCAC3C,KAAK;mBACnB,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Naming utilities - extracted for testability
3
+ */
4
+ export declare function toPascalCase(name: string): string;
5
+ export declare function toCamelCase(name: string): string;
6
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../../src/cli/helpers/naming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Naming utilities - extracted for testability
3
+ */
4
+ export function toPascalCase(name) {
5
+ return name
6
+ .split(/[-_]/)
7
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
8
+ .join('');
9
+ }
10
+ export function toCamelCase(name) {
11
+ const pascal = toPascalCase(name);
12
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
13
+ }
14
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/cli/helpers/naming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACzE,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Loom CLI - Main Program
3
+ *
4
+ * Registers all subcommands and runs the CLI.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare function createProgram(): Command;
8
+ export declare function run(): Promise<void>;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,aAAa,IAAI,OAAO,CAiBvC;AAED,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAGzC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Loom CLI - Main Program
3
+ *
4
+ * Registers all subcommands and runs the CLI.
5
+ */
6
+ import { Command } from 'commander';
7
+ import { registerGenerateCommand } from './commands/generate.js';
8
+ import { registerDevCommand } from './commands/dev.js';
9
+ import { registerBuildCommand } from './commands/build.js';
10
+ import { registerDataCommand } from './commands/data.js';
11
+ import { registerSkillCommand } from './commands/skill.js';
12
+ import { registerObserveCommand } from './commands/observe.js';
13
+ import { registerInitCommand } from './commands/init.js';
14
+ export function createProgram() {
15
+ const program = new Command();
16
+ program
17
+ .name('loom')
18
+ .description('Loom - Weave AI capabilities into your application')
19
+ .version('0.1.0');
20
+ registerInitCommand(program);
21
+ registerGenerateCommand(program);
22
+ registerDevCommand(program);
23
+ registerBuildCommand(program);
24
+ registerDataCommand(program);
25
+ registerSkillCommand(program);
26
+ registerObserveCommand(program);
27
+ return program;
28
+ }
29
+ export async function run() {
30
+ const program = createProgram();
31
+ await program.parseAsync(process.argv);
32
+ }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,oDAAoD,CAAC;SACjE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared CLI utilities
3
+ */
4
+ /**
5
+ * Resolve the project root directory.
6
+ * Walks up from CWD looking for loom.config.ts or loom.config.js.
7
+ * Falls back to CWD if no config found.
8
+ */
9
+ export declare function resolveProjectRoot(): Promise<string>;
10
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/cli/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAoB1D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared CLI utilities
3
+ */
4
+ import { promises as fs } from 'fs';
5
+ import path from 'path';
6
+ /**
7
+ * Resolve the project root directory.
8
+ * Walks up from CWD looking for loom.config.ts or loom.config.js.
9
+ * Falls back to CWD if no config found.
10
+ */
11
+ export async function resolveProjectRoot() {
12
+ let current = process.cwd();
13
+ for (let i = 0; i < 20; i++) {
14
+ for (const candidate of ['loom.config.ts', 'loom.config.js']) {
15
+ try {
16
+ await fs.access(path.join(current, candidate));
17
+ return current;
18
+ }
19
+ catch {
20
+ continue;
21
+ }
22
+ }
23
+ const parent = path.dirname(current);
24
+ if (parent === current)
25
+ break; // reached root
26
+ current = parent;
27
+ }
28
+ // Fallback to CWD
29
+ return process.cwd();
30
+ }
31
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/cli/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;gBAC/C,OAAO,OAAO,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,OAAO;YAAE,MAAM,CAAC,eAAe;QAC9C,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IAED,kBAAkB;IAClB,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -12,4 +12,7 @@ export type { SQLiteAdapterOptions } from './adapter-sqlite.js';
12
12
  export { generateCapabilities } from './capability-generator.js';
13
13
  export type { GenerateResult } from './capability-generator.js';
14
14
  export { defineCommand } from './commands.js';
15
+ export { LoomServer, startServer } from './backend/index.js';
16
+ export type { LoomServerOptions } from './backend/index.js';
17
+ export { createProgram, run } from './cli/index.js';
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,aAAa,EACb,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACX,SAAS,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGrI,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,aAAa,EACb,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACX,SAAS,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGrI,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -12,4 +12,8 @@ export { SQLiteAdapter } from './adapter-sqlite.js';
12
12
  export { generateCapabilities } from './capability-generator.js';
13
13
  // Command Framework
14
14
  export { defineCommand } from './commands.js';
15
+ // Backend
16
+ export { LoomServer, startServer } from './backend/index.js';
17
+ // CLI
18
+ export { createProgram, run } from './cli/index.js';
15
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkCH,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErI,cAAc;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,uBAAuB;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkCH,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAErI,cAAc;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,uBAAuB;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG7D,MAAM;AACN,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC"}
@@ -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=server-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-bin.d.ts","sourceRoot":"","sources":["../src/server-bin.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
@@ -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('./backend/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 init <name>');
70
+ process.exit(1);
71
+ }
72
+ throw error;
73
+ }
74
+ export {};
75
+ //# sourceMappingURL=server-bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-bin.js","sourceRoot":"","sources":["../src/server-bin.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,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,oBAAoB,CAAC,CAAC;IAC1D,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,mCAAmC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loom-framework/core",
3
- "version": "0.1.0-alpha.39",
4
- "description": "Loom framework core - DataAdapter, Capability Generator, config system",
3
+ "version": "0.1.0-alpha.40",
4
+ "description": "Loom framework - DataAdapter, Capability Generator, config system, backend server, CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -11,8 +11,13 @@
11
11
  "types": "./dist/index.d.ts"
12
12
  }
13
13
  },
14
+ "bin": {
15
+ "loom": "./dist/bin.js",
16
+ "loom-server": "./dist/server-bin.js"
17
+ },
14
18
  "files": [
15
- "dist"
19
+ "dist",
20
+ "templates"
16
21
  ],
17
22
  "scripts": {
18
23
  "build": "tsc",
@@ -22,7 +27,14 @@
22
27
  },
23
28
  "dependencies": {
24
29
  "jiti": "^2.6.1",
25
- "zod": "^3.23.0"
30
+ "zod": "^3.23.0",
31
+ "fastify": "^5.2.0",
32
+ "@fastify/cors": "^10.0.0",
33
+ "@fastify/static": "^8.0.0",
34
+ "commander": "^12.1.0",
35
+ "chalk": "^5.3.0",
36
+ "ora": "^8.0.0",
37
+ "glob": "^11.0.0"
26
38
  },
27
39
  "optionalDependencies": {
28
40
  "better-sqlite3": "^12.8.0"
@@ -31,4 +43,4 @@
31
43
  "@types/better-sqlite3": "^7.6.13",
32
44
  "typescript": "^5.6.0"
33
45
  }
34
- }
46
+ }