@compilr-dev/factory 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +131 -0
  2. package/dist/factory/file-writer.d.ts +11 -0
  3. package/dist/factory/file-writer.js +21 -0
  4. package/dist/factory/list-toolkits-tool.d.ts +12 -0
  5. package/dist/factory/list-toolkits-tool.js +35 -0
  6. package/dist/factory/registry.d.ts +15 -0
  7. package/dist/factory/registry.js +28 -0
  8. package/dist/factory/scaffold-tool.d.ts +21 -0
  9. package/dist/factory/scaffold-tool.js +95 -0
  10. package/dist/factory/skill.d.ts +14 -0
  11. package/dist/factory/skill.js +146 -0
  12. package/dist/factory/tools.d.ts +14 -0
  13. package/dist/factory/tools.js +17 -0
  14. package/dist/index.d.ts +22 -0
  15. package/dist/index.js +25 -0
  16. package/dist/model/defaults.d.ts +10 -0
  17. package/dist/model/defaults.js +68 -0
  18. package/dist/model/naming.d.ts +12 -0
  19. package/dist/model/naming.js +80 -0
  20. package/dist/model/operations-entity.d.ts +35 -0
  21. package/dist/model/operations-entity.js +110 -0
  22. package/dist/model/operations-field.d.ts +33 -0
  23. package/dist/model/operations-field.js +104 -0
  24. package/dist/model/operations-relationship.d.ts +19 -0
  25. package/dist/model/operations-relationship.js +90 -0
  26. package/dist/model/operations-section.d.ts +32 -0
  27. package/dist/model/operations-section.js +35 -0
  28. package/dist/model/operations.d.ts +12 -0
  29. package/dist/model/operations.js +63 -0
  30. package/dist/model/persistence.d.ts +19 -0
  31. package/dist/model/persistence.js +40 -0
  32. package/dist/model/schema.d.ts +15 -0
  33. package/dist/model/schema.js +269 -0
  34. package/dist/model/tools.d.ts +14 -0
  35. package/dist/model/tools.js +380 -0
  36. package/dist/model/types.d.ts +70 -0
  37. package/dist/model/types.js +8 -0
  38. package/dist/toolkits/react-node/api.d.ts +8 -0
  39. package/dist/toolkits/react-node/api.js +198 -0
  40. package/dist/toolkits/react-node/config.d.ts +9 -0
  41. package/dist/toolkits/react-node/config.js +120 -0
  42. package/dist/toolkits/react-node/dashboard.d.ts +8 -0
  43. package/dist/toolkits/react-node/dashboard.js +60 -0
  44. package/dist/toolkits/react-node/entity.d.ts +8 -0
  45. package/dist/toolkits/react-node/entity.js +469 -0
  46. package/dist/toolkits/react-node/helpers.d.ts +27 -0
  47. package/dist/toolkits/react-node/helpers.js +71 -0
  48. package/dist/toolkits/react-node/index.d.ts +8 -0
  49. package/dist/toolkits/react-node/index.js +52 -0
  50. package/dist/toolkits/react-node/router.d.ts +8 -0
  51. package/dist/toolkits/react-node/router.js +49 -0
  52. package/dist/toolkits/react-node/seed.d.ts +11 -0
  53. package/dist/toolkits/react-node/seed.js +144 -0
  54. package/dist/toolkits/react-node/shared.d.ts +7 -0
  55. package/dist/toolkits/react-node/shared.js +119 -0
  56. package/dist/toolkits/react-node/shell.d.ts +8 -0
  57. package/dist/toolkits/react-node/shell.js +152 -0
  58. package/dist/toolkits/react-node/static.d.ts +8 -0
  59. package/dist/toolkits/react-node/static.js +105 -0
  60. package/dist/toolkits/react-node/types-gen.d.ts +8 -0
  61. package/dist/toolkits/react-node/types-gen.js +31 -0
  62. package/dist/toolkits/types.d.ts +22 -0
  63. package/dist/toolkits/types.js +6 -0
  64. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # @compilr-dev/factory
2
+
3
+ AI-driven application scaffolder for the compilr-dev ecosystem. Generates working full-stack MVPs from an Application Model — a declarative description of what an app is (entities, fields, relationships, layout, features).
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ @compilr-dev/agents → @compilr-dev/sdk → @compilr-dev/factory → @compilr-dev/cli
9
+ ↑ peer dep on SDK
10
+ ```
11
+
12
+ The factory provides **5 tools** (via MetaToolsRegistry) and **1 skill**:
13
+
14
+ | Tool | Purpose |
15
+ |------|---------|
16
+ | `app_model_get` | Scoped reads of the Application Model |
17
+ | `app_model_update` | Semantic operations (addEntity, updateField, etc.) |
18
+ | `app_model_validate` | Check model health |
19
+ | `factory_scaffold` | Generate files from model + toolkit |
20
+ | `factory_list_toolkits` | List available toolkits |
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @compilr-dev/factory
26
+ ```
27
+
28
+ Peer dependency: `@compilr-dev/sdk ^0.1.11`
29
+
30
+ ## Usage
31
+
32
+ ```typescript
33
+ import { createModelTools } from '@compilr-dev/factory';
34
+ import type { PlatformContext } from '@compilr-dev/sdk';
35
+
36
+ // Create the 3 model tools (get, update, validate)
37
+ const tools = createModelTools({
38
+ context: platformContext, // PlatformContext with documents repo
39
+ });
40
+
41
+ // Or use individual utilities
42
+ import {
43
+ createDefaultModel,
44
+ createDefaultEntity,
45
+ applyOperation,
46
+ validateModel,
47
+ } from '@compilr-dev/factory';
48
+
49
+ const model = createDefaultModel({
50
+ identity: { name: 'Restaurant Manager', description: 'Manage reservations', version: '1.0.0' },
51
+ });
52
+
53
+ const updated = applyOperation(model, {
54
+ op: 'addEntity',
55
+ entity: {
56
+ name: 'Reservation',
57
+ pluralName: 'Reservations',
58
+ icon: '📅',
59
+ fields: [
60
+ { name: 'date', label: 'Date', type: 'date', required: true },
61
+ { name: 'partySize', label: 'Party Size', type: 'number', required: true },
62
+ { name: 'status', label: 'Status', type: 'enum', required: true, enumValues: ['pending', 'confirmed', 'cancelled'] },
63
+ ],
64
+ views: ['card', 'list', 'detail'],
65
+ relationships: [],
66
+ },
67
+ });
68
+
69
+ const result = validateModel(updated);
70
+ // { valid: true, errors: [] }
71
+ ```
72
+
73
+ ## Application Model
74
+
75
+ The model describes **what** an application is, independently of how it's built:
76
+
77
+ ```
78
+ ApplicationModel
79
+ ├── identity — name, description, version
80
+ ├── entities[] — domain objects with fields, views, relationships
81
+ ├── layout — shell type (sidebar-header | header-only)
82
+ ├── features — boolean toggles (dashboard, auth, darkMode, etc.)
83
+ ├── theme — primaryColor (#RRGGBB)
84
+ ├── techStack — toolkit ID (e.g. 'react-node')
85
+ └── meta — revision, timestamps, factoryVersion
86
+ ```
87
+
88
+ ### Semantic Operations
89
+
90
+ The model is never edited as raw JSON. All changes go through typed operations:
91
+
92
+ **Entity:** addEntity, updateEntity, removeEntity, renameEntity, reorderEntities
93
+ **Field:** addField, updateField, removeField, renameField
94
+ **Relationship:** addRelationship, removeRelationship (with auto-inverse management)
95
+ **Section:** updateIdentity, updateLayout, updateFeatures, updateTheme, updateTechStack
96
+
97
+ Every operation follows: **READ → CHECK → APPLY → VALIDATE → WRITE**.
98
+
99
+ ### Key Features
100
+
101
+ - **Name-based addressing** — `entity: "Reservation"`, not `entities[2]`
102
+ - **Optimistic locking** — revision counter prevents lost updates
103
+ - **Auto-inverse relationships** — adding `belongsTo` auto-adds `hasMany` on target
104
+ - **Cascading operations** — renaming an entity updates all relationship targets
105
+ - **Scoped reads** — `app_model_get({ scope: "summary" })` for lightweight overview
106
+
107
+ ## Development
108
+
109
+ ```bash
110
+ npm run build # Compile TypeScript
111
+ npm run lint # ESLint (strict, 0 errors required)
112
+ npm run format:check # Prettier check
113
+ npm test -- --run # Run 143 tests
114
+ npm run typecheck # Type-check without emitting
115
+ ```
116
+
117
+ ## Implementation Status
118
+
119
+ | Phase | Status | Description |
120
+ |-------|--------|-------------|
121
+ | 1 | ✅ | Types, validation, naming, defaults |
122
+ | 2 | ✅ | Model operations, persistence, 3 tools |
123
+ | 3 | 🔲 | Factory infrastructure (toolkit registry, scaffold tool) |
124
+ | 4 | 🔲 | React+Node toolkit (~37 file generators) |
125
+ | 5 | 🔲 | Skill prompt (factory-scaffold) |
126
+ | 6 | 🔲 | SDK integration (DocumentType extension) |
127
+ | 7 | 🔲 | CLI integration |
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,11 @@
1
+ /**
2
+ * File Writer
3
+ *
4
+ * Writes generated FactoryFile[] to disk, creating directories as needed.
5
+ */
6
+ import type { FactoryFile } from '../toolkits/types.js';
7
+ export interface WriteResult {
8
+ readonly written: number;
9
+ readonly paths: readonly string[];
10
+ }
11
+ export declare function writeFactoryFiles(files: readonly FactoryFile[], targetDir: string): Promise<WriteResult>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * File Writer
3
+ *
4
+ * Writes generated FactoryFile[] to disk, creating directories as needed.
5
+ */
6
+ import { mkdir, writeFile } from 'node:fs/promises';
7
+ import { dirname, join, resolve } from 'node:path';
8
+ export async function writeFactoryFiles(files, targetDir) {
9
+ const absDir = resolve(targetDir);
10
+ const writtenPaths = [];
11
+ for (const file of files) {
12
+ const absPath = join(absDir, file.path);
13
+ await mkdir(dirname(absPath), { recursive: true });
14
+ await writeFile(absPath, file.content, 'utf-8');
15
+ writtenPaths.push(file.path);
16
+ }
17
+ return {
18
+ written: writtenPaths.length,
19
+ paths: writtenPaths,
20
+ };
21
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * factory_list_toolkits Tool
3
+ *
4
+ * Lists all registered toolkits with their descriptions.
5
+ */
6
+ import type { Tool } from '@compilr-dev/agents';
7
+ import type { ToolkitRegistry } from './registry.js';
8
+ interface ListToolkitsInput {
9
+ _unused?: never;
10
+ }
11
+ export declare function createListToolkitsTool(registry: ToolkitRegistry): Tool<ListToolkitsInput>;
12
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * factory_list_toolkits Tool
3
+ *
4
+ * Lists all registered toolkits with their descriptions.
5
+ */
6
+ import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
7
+ export function createListToolkitsTool(registry) {
8
+ return defineTool({
9
+ name: 'factory_list_toolkits',
10
+ description: 'List all available factory toolkits. Each toolkit generates a different type of application (e.g. React+Node, Next.js, etc.).',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {},
14
+ required: [],
15
+ },
16
+ execute: () => {
17
+ try {
18
+ const toolkits = registry.list();
19
+ return Promise.resolve(createSuccessResult({
20
+ count: toolkits.length,
21
+ toolkits: toolkits.map((t) => ({
22
+ id: t.id,
23
+ name: t.name,
24
+ description: t.description,
25
+ requiredSections: t.requiredSections,
26
+ })),
27
+ }));
28
+ }
29
+ catch (error) {
30
+ return Promise.resolve(createErrorResult(error instanceof Error ? error.message : String(error)));
31
+ }
32
+ },
33
+ readonly: true,
34
+ });
35
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Toolkit Registry
3
+ *
4
+ * Manages registered FactoryToolkit implementations.
5
+ * Toolkits register themselves by ID and are looked up during scaffold.
6
+ */
7
+ import type { FactoryToolkit } from '../toolkits/types.js';
8
+ export declare class ToolkitRegistry {
9
+ private readonly toolkits;
10
+ register(toolkit: FactoryToolkit): void;
11
+ get(id: string): FactoryToolkit | undefined;
12
+ list(): FactoryToolkit[];
13
+ has(id: string): boolean;
14
+ }
15
+ export declare const defaultRegistry: ToolkitRegistry;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Toolkit Registry
3
+ *
4
+ * Manages registered FactoryToolkit implementations.
5
+ * Toolkits register themselves by ID and are looked up during scaffold.
6
+ */
7
+ export class ToolkitRegistry {
8
+ toolkits = new Map();
9
+ register(toolkit) {
10
+ if (this.toolkits.has(toolkit.id)) {
11
+ throw new Error(`Toolkit "${toolkit.id}" is already registered`);
12
+ }
13
+ this.toolkits.set(toolkit.id, toolkit);
14
+ }
15
+ get(id) {
16
+ return this.toolkits.get(id);
17
+ }
18
+ list() {
19
+ return [...this.toolkits.values()];
20
+ }
21
+ has(id) {
22
+ return this.toolkits.has(id);
23
+ }
24
+ }
25
+ export const defaultRegistry = new ToolkitRegistry();
26
+ // Register built-in toolkits
27
+ import { reactNodeToolkit } from '../toolkits/react-node/index.js';
28
+ defaultRegistry.register(reactNodeToolkit);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * factory_scaffold Tool
3
+ *
4
+ * Reads the Application Model, validates it, generates files via the toolkit,
5
+ * and writes them to disk.
6
+ */
7
+ import type { Tool } from '@compilr-dev/agents';
8
+ import type { PlatformContext } from '@compilr-dev/sdk';
9
+ import type { ToolkitRegistry } from './registry.js';
10
+ export interface ScaffoldToolConfig {
11
+ readonly context: PlatformContext;
12
+ readonly cwd?: string;
13
+ readonly registry: ToolkitRegistry;
14
+ }
15
+ interface ScaffoldInput {
16
+ dry_run?: boolean;
17
+ output_dir?: string;
18
+ project_id?: number;
19
+ }
20
+ export declare function createScaffoldTool(config: ScaffoldToolConfig): Tool<ScaffoldInput>;
21
+ export {};
@@ -0,0 +1,95 @@
1
+ /**
2
+ * factory_scaffold Tool
3
+ *
4
+ * Reads the Application Model, validates it, generates files via the toolkit,
5
+ * and writes them to disk.
6
+ */
7
+ import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
8
+ import { ModelStore } from '../model/persistence.js';
9
+ import { validateModel } from '../model/schema.js';
10
+ import { writeFactoryFiles } from './file-writer.js';
11
+ export function createScaffoldTool(config) {
12
+ return defineTool({
13
+ name: 'factory_scaffold',
14
+ description: 'Generate a full application from the Application Model. Reads the model, validates it, runs the toolkit generators, and writes files to disk. Use dry_run: true to preview without writing.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ dry_run: {
19
+ type: 'boolean',
20
+ description: 'Preview generated files without writing to disk. Default: false.',
21
+ },
22
+ output_dir: {
23
+ type: 'string',
24
+ description: 'Directory to write generated files. Defaults to current working directory.',
25
+ },
26
+ project_id: {
27
+ type: 'number',
28
+ description: 'Project ID. Uses active project if omitted.',
29
+ },
30
+ },
31
+ required: [],
32
+ },
33
+ execute: async (input) => {
34
+ try {
35
+ const projectId = input.project_id ?? config.context.currentProjectId;
36
+ if (!projectId) {
37
+ return createErrorResult('No active project. Use project_create or project_get first.');
38
+ }
39
+ // 1. Read model
40
+ const store = new ModelStore({
41
+ documents: config.context.documents,
42
+ projectId,
43
+ });
44
+ const model = await store.get();
45
+ if (!model) {
46
+ return createErrorResult('No Application Model found. Use app_model_update to build one first.');
47
+ }
48
+ // 2. Validate
49
+ const validation = validateModel(model);
50
+ if (!validation.valid) {
51
+ const msgs = validation.errors.map((e) => `${e.path}: ${e.message}`).join('; ');
52
+ return createErrorResult(`Model validation failed: ${msgs}`);
53
+ }
54
+ // 3. Look up toolkit
55
+ const toolkit = config.registry.get(model.techStack.toolkit);
56
+ if (!toolkit) {
57
+ const available = config.registry
58
+ .list()
59
+ .map((t) => t.id)
60
+ .join(', ');
61
+ return createErrorResult(`Toolkit "${model.techStack.toolkit}" not found. Available: ${available || 'none'}`);
62
+ }
63
+ // 4. Generate
64
+ const result = toolkit.generate(model);
65
+ // 5. Write (unless dry_run)
66
+ if (!input.dry_run) {
67
+ const targetDir = input.output_dir ?? config.cwd ?? process.cwd();
68
+ await writeFactoryFiles(result.files, targetDir);
69
+ // 6. Update generatedAt
70
+ const updatedModel = {
71
+ ...model,
72
+ meta: {
73
+ ...model.meta,
74
+ generatedAt: new Date().toISOString(),
75
+ },
76
+ };
77
+ await store.save(updatedModel);
78
+ }
79
+ return createSuccessResult({
80
+ toolkit: result.toolkit,
81
+ fileCount: result.files.length,
82
+ files: result.files.map((f) => f.path),
83
+ warnings: result.warnings,
84
+ dryRun: input.dry_run ?? false,
85
+ message: input.dry_run
86
+ ? `Dry run: ${String(result.files.length)} files would be generated.`
87
+ : `Generated ${String(result.files.length)} files using "${result.toolkit}" toolkit.`,
88
+ });
89
+ }
90
+ catch (error) {
91
+ return createErrorResult(error instanceof Error ? error.message : String(error));
92
+ }
93
+ },
94
+ });
95
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Factory Skill — Guided Model-First Scaffold
3
+ *
4
+ * The factory-scaffold skill guides the agent through:
5
+ * 1. Reading project context (PRD, architecture, existing docs)
6
+ * 2. Checking toolkit availability
7
+ * 3. Building the Application Model incrementally
8
+ * 4. Scaffolding the application
9
+ * 5. Post-generation verification
10
+ */
11
+ import { type Skill } from '@compilr-dev/agents';
12
+ export declare const factoryScaffoldSkill: Skill;
13
+ /** All factory skills. */
14
+ export declare const factorySkills: readonly Skill[];
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Factory Skill — Guided Model-First Scaffold
3
+ *
4
+ * The factory-scaffold skill guides the agent through:
5
+ * 1. Reading project context (PRD, architecture, existing docs)
6
+ * 2. Checking toolkit availability
7
+ * 3. Building the Application Model incrementally
8
+ * 4. Scaffolding the application
9
+ * 5. Post-generation verification
10
+ */
11
+ import { defineSkill } from '@compilr-dev/agents';
12
+ export const factoryScaffoldSkill = defineSkill({
13
+ name: 'factory-scaffold',
14
+ description: 'Guide the user through building an Application Model and scaffolding a full-stack app',
15
+ tags: ['factory', 'scaffold', 'model'],
16
+ prompt: `You are in FACTORY SCAFFOLD MODE. Your goal is to build an Application Model from the user's project description and generate a working full-stack application.
17
+
18
+ ## Overview
19
+
20
+ The factory system works in two phases:
21
+ 1. **Model Building** — You build an Application Model that describes WHAT the app is
22
+ 2. **Code Generation** — The factory toolkit deterministically generates code from the model
23
+
24
+ You have access to these tools:
25
+ - \`app_model_get\` — Read the current Application Model (or sections of it)
26
+ - \`app_model_update\` — Apply semantic operations to the model (addEntity, updateField, etc.)
27
+ - \`app_model_validate\` — Check model health and get error details
28
+ - \`factory_scaffold\` — Generate code from the model using a toolkit
29
+ - \`factory_list_toolkits\` — List available code generation toolkits
30
+
31
+ ## PHASE 1: Context Gathering
32
+
33
+ Before building the model, understand the project:
34
+
35
+ 1. Check for existing context:
36
+ - Use \`project_document_get_by_type\` to look for PRD, architecture, and design docs
37
+ - Read any existing Application Model with \`app_model_get\`
38
+
39
+ 2. If NO model exists, gather requirements from the user:
40
+ - What is the app? (name, one-sentence description)
41
+ - Who uses it? What are the main things they manage? (→ entities)
42
+ - What information does each thing have? (→ fields)
43
+ - How do things relate to each other? (→ relationships)
44
+ - Any special features? (dashboard, dark mode, settings)
45
+
46
+ 3. If a model EXISTS, show a summary and ask what to change.
47
+
48
+ ## PHASE 2: Check Toolkit Availability
49
+
50
+ Call \`factory_list_toolkits\` to see what's available.
51
+ - If a suitable toolkit exists → proceed with automated generation
52
+ - If no toolkit matches → inform the user and offer to build the model anyway (useful as a spec for manual implementation)
53
+
54
+ ## PHASE 3: Build the Application Model
55
+
56
+ Build the model incrementally using \`app_model_update\`:
57
+
58
+ ### Step 1: Set Identity
59
+ \`\`\`json
60
+ { "op": "updateIdentity", "updates": { "name": "App Name", "description": "..." } }
61
+ \`\`\`
62
+
63
+ ### Step 2: Set Tech Stack
64
+ \`\`\`json
65
+ { "op": "updateTechStack", "updates": { "toolkit": "react-node" } }
66
+ \`\`\`
67
+
68
+ ### Step 3: Add Entities (one at a time)
69
+ \`\`\`json
70
+ {
71
+ "op": "addEntity",
72
+ "entity": {
73
+ "name": "Customer",
74
+ "pluralName": "Customers",
75
+ "icon": "👤",
76
+ "fields": [
77
+ { "name": "name", "label": "Name", "type": "string", "required": true },
78
+ { "name": "email", "label": "Email", "type": "string", "required": true }
79
+ ],
80
+ "views": ["list", "detail", "card"],
81
+ "relationships": []
82
+ }
83
+ }
84
+ \`\`\`
85
+
86
+ ### Step 4: Add Relationships (after all entities exist)
87
+ \`\`\`json
88
+ { "op": "addRelationship", "entity": "Reservation", "relationship": { "type": "belongsTo", "target": "Customer" } }
89
+ \`\`\`
90
+ Note: The inverse hasMany is added automatically.
91
+
92
+ ### Step 5: Configure Features
93
+ \`\`\`json
94
+ { "op": "updateFeatures", "updates": { "dashboard": true, "darkMode": true } }
95
+ \`\`\`
96
+
97
+ ### Step 6: Set Theme
98
+ \`\`\`json
99
+ { "op": "updateTheme", "updates": { "primaryColor": "#1976D2" } }
100
+ \`\`\`
101
+
102
+ ### Step 7: Set Layout
103
+ \`\`\`json
104
+ { "op": "updateLayout", "updates": { "shell": "sidebar-header" } }
105
+ \`\`\`
106
+
107
+ ### Step 8: Validate
108
+ Call \`app_model_validate\` and fix any errors.
109
+
110
+ ## PHASE 4: Generate Code
111
+
112
+ Once the model is valid:
113
+
114
+ 1. **Dry run first:**
115
+ Call \`factory_scaffold\` with \`{ "dry_run": true }\` to preview files.
116
+
117
+ 2. **Show the user** the file list and confirm they want to proceed.
118
+
119
+ 3. **Generate:**
120
+ Call \`factory_scaffold\` without dry_run to write files.
121
+
122
+ ## PHASE 5: Post-Generation
123
+
124
+ After code generation:
125
+
126
+ 1. Tell the user what was generated (file count, structure)
127
+ 2. Suggest next steps:
128
+ - \`cd <project-dir> && npm install && npm run dev\`
129
+ - The app will be at http://localhost:5173
130
+ - API at http://localhost:3001
131
+ 3. Mention what can be customized (theme, features, adding entities)
132
+ 4. If backlog tools are available, offer to seed backlog with enhancement items
133
+
134
+ ## IMPORTANT RULES
135
+
136
+ - **Never guess field types** — ask if unclear (e.g., is "status" a string or enum?)
137
+ - **Entities use PascalCase** names (Customer, not customer)
138
+ - **Fields use camelCase** names (firstName, not first_name)
139
+ - **Always validate** before scaffolding
140
+ - **Show progress** — after adding each entity, show a brief summary
141
+ - **Relationships come last** — all entities must exist before adding relationships
142
+ - **Use \`belongsTo\`** for the FK side — the inverse \`hasMany\` is automatic
143
+ `,
144
+ });
145
+ /** All factory skills. */
146
+ export const factorySkills = [factoryScaffoldSkill];
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Factory Tools — Public API
3
+ *
4
+ * createFactoryTools() returns all 5 tools (3 model + 2 factory).
5
+ */
6
+ import type { Tool } from '@compilr-dev/agents';
7
+ import type { PlatformContext } from '@compilr-dev/sdk';
8
+ import { ToolkitRegistry } from './registry.js';
9
+ export interface FactoryConfig {
10
+ readonly context: PlatformContext;
11
+ readonly cwd?: string;
12
+ readonly registry?: ToolkitRegistry;
13
+ }
14
+ export declare function createFactoryTools(config: FactoryConfig): Tool<never>[];
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Factory Tools — Public API
3
+ *
4
+ * createFactoryTools() returns all 5 tools (3 model + 2 factory).
5
+ */
6
+ import { createModelTools } from '../model/tools.js';
7
+ import { createScaffoldTool } from './scaffold-tool.js';
8
+ import { createListToolkitsTool } from './list-toolkits-tool.js';
9
+ import { defaultRegistry } from './registry.js';
10
+ export function createFactoryTools(config) {
11
+ const registry = config.registry ?? defaultRegistry;
12
+ return [
13
+ ...createModelTools(config),
14
+ createScaffoldTool({ ...config, registry }),
15
+ createListToolkitsTool(registry),
16
+ ];
17
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @compilr-dev/factory
3
+ *
4
+ * AI-driven application scaffolder for the compilr-dev ecosystem.
5
+ */
6
+ export type { ApplicationModel, Entity, Field, FieldType, View, Relationship, RelationshipType, Identity, Layout, ShellType, Features, Theme, TechStack, Meta, } from './model/types.js';
7
+ export { validateModel } from './model/schema.js';
8
+ export type { ValidationError, ValidationResult } from './model/schema.js';
9
+ export { createDefaultModel, createDefaultEntity, createDefaultField } from './model/defaults.js';
10
+ export { toPascalCase, toCamelCase, toKebabCase, toPlural, isPascalCase, isCamelCase, isValidHexColor, } from './model/naming.js';
11
+ export type { FactoryFile, FactoryResult, FactoryToolkit } from './toolkits/types.js';
12
+ export { ModelStore } from './model/persistence.js';
13
+ export { applyOperation } from './model/operations.js';
14
+ export type { ModelOperation } from './model/operations.js';
15
+ export { createModelTools } from './model/tools.js';
16
+ export { createFactoryTools } from './factory/tools.js';
17
+ export type { FactoryConfig } from './factory/tools.js';
18
+ export { ToolkitRegistry, defaultRegistry } from './factory/registry.js';
19
+ export { writeFactoryFiles } from './factory/file-writer.js';
20
+ export type { WriteResult } from './factory/file-writer.js';
21
+ export { reactNodeToolkit } from './toolkits/react-node/index.js';
22
+ export { factoryScaffoldSkill, factorySkills } from './factory/skill.js';
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @compilr-dev/factory
3
+ *
4
+ * AI-driven application scaffolder for the compilr-dev ecosystem.
5
+ */
6
+ // Validation
7
+ export { validateModel } from './model/schema.js';
8
+ // Defaults
9
+ export { createDefaultModel, createDefaultEntity, createDefaultField } from './model/defaults.js';
10
+ // Naming utilities
11
+ export { toPascalCase, toCamelCase, toKebabCase, toPlural, isPascalCase, isCamelCase, isValidHexColor, } from './model/naming.js';
12
+ // Model persistence (Phase 2)
13
+ export { ModelStore } from './model/persistence.js';
14
+ // Model operations (Phase 2)
15
+ export { applyOperation } from './model/operations.js';
16
+ // Model tools (Phase 2)
17
+ export { createModelTools } from './model/tools.js';
18
+ // Factory tools (Phase 3)
19
+ export { createFactoryTools } from './factory/tools.js';
20
+ export { ToolkitRegistry, defaultRegistry } from './factory/registry.js';
21
+ export { writeFactoryFiles } from './factory/file-writer.js';
22
+ // React+Node Toolkit (Phase 4)
23
+ export { reactNodeToolkit } from './toolkits/react-node/index.js';
24
+ // Factory skill (Phase 5)
25
+ export { factoryScaffoldSkill, factorySkills } from './factory/skill.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Default Model Creators
3
+ *
4
+ * Factory functions for creating ApplicationModel and Entity instances
5
+ * with sensible defaults.
6
+ */
7
+ import type { ApplicationModel, Entity, Field } from './types.js';
8
+ export declare function createDefaultModel(overrides?: Partial<ApplicationModel>): ApplicationModel;
9
+ export declare function createDefaultEntity(name: string, overrides?: Partial<Entity>): Entity;
10
+ export declare function createDefaultField(name: string, label: string, overrides?: Partial<Field>): Field;