create-loomstack-app 0.0.1 → 0.0.2
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/README.md +88 -9
- package/dist/{chunk-QTMEZJHE.js → chunk-EQQCF3Q6.js} +38 -38
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,25 +1,104 @@
|
|
|
1
1
|
# create-loomstack-app
|
|
2
2
|
|
|
3
|
-
Create
|
|
3
|
+
Create an agent-operable TypeScript fullstack application with React, Vite, Koa, PostgreSQL, Zod, pnpm, and Vitest.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
**Requirements:** Node 22+, pnpm 11+, and Docker Compose.
|
|
4
8
|
|
|
5
9
|
```bash
|
|
6
10
|
npm create loomstack-app@latest my-app
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
cd my-app
|
|
12
|
+
pnpm install
|
|
13
|
+
pnpm loomstack init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`init` validates the project and starts the web, API, and PostgreSQL development services. Open [http://localhost:3000](http://localhost:3000) when it finishes.
|
|
17
|
+
|
|
18
|
+
Use `pnpm loomstack init --no-start` to initialize without starting Docker, or `pnpm loomstack init --skip-install` when dependencies are managed separately.
|
|
19
|
+
|
|
20
|
+
## Create your first feature
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm loomstack create feature people --json
|
|
24
|
+
pnpm loomstack context feature people --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then describe the product behavior to your coding agent:
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
Implement the people feature. Users can create people with a name and optional
|
|
31
|
+
job title, list only their own people newest-first, and open the list at /people.
|
|
32
|
+
Read AGENTS.md first. Generate, verify, and test before finishing.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
LoomStack gives the agent a deterministic context → edit → generate → verify → test workflow and keeps product behavior in canonical feature slices.
|
|
36
|
+
|
|
37
|
+
## What gets created
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
apps/web/ React + Vite presentation
|
|
41
|
+
apps/api/ Koa RPC transport
|
|
42
|
+
features/ Product behavior and tests
|
|
43
|
+
shared/generated/ Generated registries
|
|
44
|
+
.loomstack/ Generated context, graph, and hashes
|
|
45
|
+
compose.yaml Web, API, and PostgreSQL services
|
|
46
|
+
AGENTS.md Project-specific agent instructions
|
|
9
47
|
```
|
|
10
48
|
|
|
11
|
-
|
|
49
|
+
Generated wiring is marked as do-not-edit. Schemas, policies, actions, queries, views, and tests remain authored inside `features/`.
|
|
50
|
+
|
|
51
|
+
## Common commands
|
|
52
|
+
|
|
53
|
+
| Command | Purpose |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `pnpm loomstack context --json` | Inspect the project and architectural rules |
|
|
56
|
+
| `pnpm loomstack context feature <name> --json` | Inspect one feature before editing |
|
|
57
|
+
| `pnpm loomstack create feature <name> --json` | Scaffold a canonical feature |
|
|
58
|
+
| `pnpm loomstack affected <file> --json` | Find related authored files |
|
|
59
|
+
| `pnpm loomstack generate --json` | Regenerate deterministic wiring |
|
|
60
|
+
| `pnpm loomstack verify --json` | Verify contracts, boundaries, and generated files |
|
|
61
|
+
| `pnpm loomstack dev status --json` | Check development service status |
|
|
62
|
+
| `pnpm loomstack doctor --json` | Diagnose environment and setup problems |
|
|
63
|
+
| `pnpm loomstack explain <code> --json` | Get repair guidance for a stable error code |
|
|
12
64
|
|
|
13
|
-
##
|
|
65
|
+
## Creator options
|
|
14
66
|
|
|
15
67
|
```text
|
|
16
68
|
create-loomstack-app <name> [--cwd <directory>] [--json]
|
|
17
69
|
```
|
|
18
70
|
|
|
19
|
-
|
|
71
|
+
- `<name>` must be lowercase kebab-case.
|
|
72
|
+
- `--cwd` selects the parent directory.
|
|
73
|
+
- `--json` emits one machine-readable result document.
|
|
74
|
+
- Existing target directories are never overwritten.
|
|
75
|
+
|
|
76
|
+
You can also run the initializer directly:
|
|
20
77
|
|
|
21
78
|
```bash
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
79
|
+
npx create-loomstack-app@latest my-app
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Troubleshooting
|
|
83
|
+
|
|
84
|
+
Check the local environment:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pnpm loomstack doctor --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If a command returns a `loomstack…` error code, inspect its repair contract:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pnpm loomstack explain <code> --json
|
|
25
94
|
```
|
|
95
|
+
|
|
96
|
+
Normal source edits use hot reload. Run `pnpm loomstack dev refresh --json` only after dependency, Dockerfile, Compose, or environment changes.
|
|
97
|
+
|
|
98
|
+
## Links
|
|
99
|
+
|
|
100
|
+
- [Documentation](https://github.com/DenizOkcu/loomstack/tree/master/docs)
|
|
101
|
+
- [Architecture](https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md)
|
|
102
|
+
- [CLI contracts](https://github.com/DenizOkcu/loomstack/blob/master/docs/commands.md)
|
|
103
|
+
- [GitHub repository](https://github.com/DenizOkcu/loomstack)
|
|
104
|
+
- [Issue tracker](https://github.com/DenizOkcu/loomstack/issues)
|
|
@@ -30,157 +30,157 @@ var ERROR_CATALOG = {
|
|
|
30
30
|
title: "Feature ID does not match folder name",
|
|
31
31
|
defaultMessage: "The feature manifest ID must match its folder name.",
|
|
32
32
|
repair: "Rename the folder or update feature.yaml so the feature ID matches the folder name.",
|
|
33
|
-
docs: "
|
|
33
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#verification-and-errors"
|
|
34
34
|
},
|
|
35
35
|
loomstack1002: {
|
|
36
36
|
title: "Missing or invalid feature manifest field",
|
|
37
37
|
defaultMessage: "A required feature manifest field is missing or invalid.",
|
|
38
38
|
repair: "Add the required field to feature.yaml using the canonical manifest shape.",
|
|
39
|
-
docs: "
|
|
39
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#feature-contracts"
|
|
40
40
|
},
|
|
41
41
|
loomstack1003: {
|
|
42
42
|
title: "Manifest action is not exported",
|
|
43
43
|
defaultMessage: "An action declared in the manifest has no implementation.",
|
|
44
44
|
repair: "Create the action file or update the manifest action name.",
|
|
45
|
-
docs: "
|
|
45
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
46
46
|
},
|
|
47
47
|
loomstack1004: {
|
|
48
48
|
title: "Exported action is missing from manifest",
|
|
49
49
|
defaultMessage: "An exported action is not declared in feature.yaml.",
|
|
50
50
|
repair: "Add the action name to feature.yaml or remove the action implementation.",
|
|
51
|
-
docs: "
|
|
51
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
52
52
|
},
|
|
53
53
|
loomstack1005: {
|
|
54
54
|
title: "Duplicate route path",
|
|
55
55
|
defaultMessage: "Route paths must be globally unique.",
|
|
56
56
|
repair: "Change one route path so every route path is globally unique.",
|
|
57
|
-
docs: "
|
|
57
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#feature-contracts"
|
|
58
58
|
},
|
|
59
59
|
loomstack1006: {
|
|
60
60
|
title: "Invalid feature manifest YAML",
|
|
61
61
|
defaultMessage: "feature.yaml could not be parsed.",
|
|
62
62
|
repair: "Fix the YAML syntax and run loomstack verify again.",
|
|
63
|
-
docs: "
|
|
63
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#feature-contracts"
|
|
64
64
|
},
|
|
65
65
|
loomstack1007: {
|
|
66
66
|
title: "Manifest query is not exported",
|
|
67
67
|
defaultMessage: "A query declared in the manifest has no implementation.",
|
|
68
68
|
repair: "Create the query file or update the manifest query name.",
|
|
69
|
-
docs: "
|
|
69
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
70
70
|
},
|
|
71
71
|
loomstack1008: {
|
|
72
72
|
title: "Exported query is missing from manifest",
|
|
73
73
|
defaultMessage: "An exported query is not declared in feature.yaml.",
|
|
74
74
|
repair: "Add the query name to feature.yaml or remove the query implementation.",
|
|
75
|
-
docs: "
|
|
75
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
76
76
|
},
|
|
77
77
|
loomstack1009: {
|
|
78
78
|
title: "Manifest view is not exported",
|
|
79
79
|
defaultMessage: "A route references a view that does not exist.",
|
|
80
80
|
repair: "Create the declared *.view.tsx file or update the route view in feature.yaml.",
|
|
81
|
-
docs: "
|
|
81
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#react-presentation"
|
|
82
82
|
},
|
|
83
83
|
loomstack1010: {
|
|
84
84
|
title: "Manifest entity is not exported",
|
|
85
85
|
defaultMessage: "An entity declared in the manifest has no schema export.",
|
|
86
86
|
repair: "Export the entity from model.schema.ts or update the manifest entity name.",
|
|
87
|
-
docs: "
|
|
87
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#schemas-and-persistence"
|
|
88
88
|
},
|
|
89
89
|
loomstack1011: {
|
|
90
90
|
title: "Invalid feature name",
|
|
91
91
|
defaultMessage: "Feature IDs must be kebab-case.",
|
|
92
92
|
repair: "Use a lowercase kebab-case feature name such as project-notes.",
|
|
93
|
-
docs: "
|
|
93
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#feature-contracts"
|
|
94
94
|
},
|
|
95
95
|
loomstack2001: {
|
|
96
96
|
title: "Forbidden database import in UI file",
|
|
97
97
|
defaultMessage: "Database imports are forbidden in React UI files.",
|
|
98
98
|
repair: "Move database access into queries/*.query.ts or actions/*.action.ts.",
|
|
99
|
-
docs: "
|
|
99
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#verification-and-errors"
|
|
100
100
|
},
|
|
101
101
|
loomstack2002: {
|
|
102
102
|
title: "Forbidden raw fetch in UI file",
|
|
103
103
|
defaultMessage: "Raw fetch is forbidden in React UI files.",
|
|
104
104
|
repair: "Use the generated loomstack action/query client.",
|
|
105
|
-
docs: "
|
|
105
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#verification-and-errors"
|
|
106
106
|
},
|
|
107
107
|
loomstack2003: {
|
|
108
108
|
title: "Koa import in feature logic",
|
|
109
109
|
defaultMessage: "Feature logic must be transport-independent.",
|
|
110
110
|
repair: "Remove the Koa dependency and use LoomStackRequestContext.",
|
|
111
|
-
docs: "
|
|
111
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#verification-and-errors"
|
|
112
112
|
},
|
|
113
113
|
loomstack3001: {
|
|
114
114
|
title: "Action input validation failed",
|
|
115
115
|
defaultMessage: "Action input did not match its schema.",
|
|
116
116
|
repair: "Send input matching the action input schema.",
|
|
117
|
-
docs: "
|
|
117
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
118
118
|
},
|
|
119
119
|
loomstack3002: {
|
|
120
120
|
title: "Runtime output validation failed",
|
|
121
121
|
defaultMessage: "Action or query output did not match its schema.",
|
|
122
122
|
repair: "Return a value matching the declared output schema.",
|
|
123
|
-
docs: "
|
|
123
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
124
124
|
},
|
|
125
125
|
loomstack3003: {
|
|
126
126
|
title: "Authentication required",
|
|
127
127
|
defaultMessage: "This operation requires an authenticated user.",
|
|
128
128
|
repair: "Authenticate the request before calling this operation.",
|
|
129
|
-
docs: "
|
|
129
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#actions-queries-and-policies"
|
|
130
130
|
},
|
|
131
131
|
loomstack4040: {
|
|
132
132
|
title: "Unknown action",
|
|
133
133
|
defaultMessage: "The requested action is not registered.",
|
|
134
134
|
repair: "Use an action declared in feature.yaml and run loomstack generate.",
|
|
135
|
-
docs: "
|
|
135
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#koa-transport"
|
|
136
136
|
},
|
|
137
137
|
loomstack4041: {
|
|
138
138
|
title: "Unknown query",
|
|
139
139
|
defaultMessage: "The requested query is not registered.",
|
|
140
140
|
repair: "Use a query declared in feature.yaml and run loomstack generate.",
|
|
141
|
-
docs: "
|
|
141
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#koa-transport"
|
|
142
142
|
},
|
|
143
143
|
loomstack4050: {
|
|
144
144
|
title: "Invalid RPC method",
|
|
145
145
|
defaultMessage: "loomstack RPC endpoints accept only HTTP POST.",
|
|
146
146
|
repair: "Send the action or query request with HTTP POST.",
|
|
147
|
-
docs: "
|
|
147
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#koa-transport"
|
|
148
148
|
},
|
|
149
149
|
loomstack4001: {
|
|
150
150
|
title: "Generated file was manually modified",
|
|
151
151
|
defaultMessage: "A generated file does not match its recorded hash.",
|
|
152
152
|
repair: "Run loomstack generate or move custom logic out of the generated file.",
|
|
153
|
-
docs: "
|
|
153
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#generation"
|
|
154
154
|
},
|
|
155
155
|
loomstack4002: {
|
|
156
156
|
title: "Generated file is stale",
|
|
157
157
|
defaultMessage: "Generated output does not match current feature contracts.",
|
|
158
158
|
repair: "Run loomstack generate.",
|
|
159
|
-
docs: "
|
|
159
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#generation"
|
|
160
160
|
},
|
|
161
161
|
loomstack5001: {
|
|
162
162
|
title: "Missing loomstack config",
|
|
163
163
|
defaultMessage: "No loomstack.config.ts was found.",
|
|
164
164
|
repair: "Create loomstack.config.ts or run the command inside a loomstack project.",
|
|
165
|
-
docs: "
|
|
165
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#application-structure"
|
|
166
166
|
},
|
|
167
167
|
loomstack5002: {
|
|
168
168
|
title: "Target already exists",
|
|
169
169
|
defaultMessage: "The requested target already exists.",
|
|
170
170
|
repair: "Choose another name or remove the existing target first.",
|
|
171
|
-
docs: "
|
|
171
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/commands.md#creation"
|
|
172
172
|
},
|
|
173
173
|
loomstack5003: {
|
|
174
174
|
title: "Invalid project configuration",
|
|
175
175
|
defaultMessage: "loomstack.config.ts does not contain the required golden-path values.",
|
|
176
176
|
repair: "Use React, Koa, PostgreSQL, pnpm, and explicit featuresDir/generatedDir values.",
|
|
177
|
-
docs: "
|
|
177
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#application-structure"
|
|
178
178
|
},
|
|
179
179
|
loomstack6001: {
|
|
180
180
|
title: "Unsupported PostgreSQL field",
|
|
181
181
|
defaultMessage: "An entity field cannot be represented by the v0.1 PostgreSQL adapter.",
|
|
182
182
|
repair: "Use a supported scalar field or provide explicit persistence logic.",
|
|
183
|
-
docs: "
|
|
183
|
+
docs: "https://github.com/DenizOkcu/loomstack/blob/master/docs/architecture.md#schemas-and-persistence"
|
|
184
184
|
}
|
|
185
185
|
};
|
|
186
186
|
function frameworkError(code, options = {}) {
|
|
@@ -677,7 +677,7 @@ function appTemplateFiles(appName) {
|
|
|
677
677
|
return {
|
|
678
678
|
"package.json": `${JSON.stringify({
|
|
679
679
|
name: appName,
|
|
680
|
-
version: "0.0.
|
|
680
|
+
version: "0.0.2",
|
|
681
681
|
private: true,
|
|
682
682
|
type: "module",
|
|
683
683
|
packageManager: "pnpm@11.11.0",
|
|
@@ -694,10 +694,10 @@ function appTemplateFiles(appName) {
|
|
|
694
694
|
build: "pnpm generate && pnpm -r --filter './apps/*' build"
|
|
695
695
|
},
|
|
696
696
|
devDependencies: {
|
|
697
|
-
"@loomstack/cli": "^0.0.
|
|
698
|
-
"@loomstack/react": "^0.0.
|
|
699
|
-
"@loomstack/runtime": "^0.0.
|
|
700
|
-
"@loomstack/postgres": "^0.0.
|
|
697
|
+
"@loomstack/cli": "^0.0.2",
|
|
698
|
+
"@loomstack/react": "^0.0.2",
|
|
699
|
+
"@loomstack/runtime": "^0.0.2",
|
|
700
|
+
"@loomstack/postgres": "^0.0.2",
|
|
701
701
|
"@types/node": "^24.0.0",
|
|
702
702
|
"@types/react": "^19.0.0",
|
|
703
703
|
"@types/react-dom": "^19.0.0",
|
|
@@ -931,13 +931,13 @@ volumes:
|
|
|
931
931
|
"features/.gitkeep": "",
|
|
932
932
|
"apps/web/package.json": `${JSON.stringify({
|
|
933
933
|
name: `@${appName}/web`,
|
|
934
|
-
version: "0.0.
|
|
934
|
+
version: "0.0.2",
|
|
935
935
|
private: true,
|
|
936
936
|
type: "module",
|
|
937
937
|
scripts: { dev: "vite", build: "vite build" },
|
|
938
938
|
dependencies: {
|
|
939
|
-
"@loomstack/react": "^0.0.
|
|
940
|
-
"@loomstack/runtime": "^0.0.
|
|
939
|
+
"@loomstack/react": "^0.0.2",
|
|
940
|
+
"@loomstack/runtime": "^0.0.2",
|
|
941
941
|
"@vitejs/plugin-react": "^6.0.3",
|
|
942
942
|
react: "^19.2.7",
|
|
943
943
|
"react-dom": "^19.2.7",
|
|
@@ -996,14 +996,14 @@ export default defineConfig({
|
|
|
996
996
|
`,
|
|
997
997
|
"apps/api/package.json": `${JSON.stringify({
|
|
998
998
|
name: `@${appName}/api`,
|
|
999
|
-
version: "0.0.
|
|
999
|
+
version: "0.0.2",
|
|
1000
1000
|
private: true,
|
|
1001
1001
|
type: "module",
|
|
1002
1002
|
scripts: { dev: "tsx watch src/server.ts", build: "tsup src/server.ts --format esm --clean" },
|
|
1003
1003
|
dependencies: {
|
|
1004
|
-
"@loomstack/koa": "^0.0.
|
|
1005
|
-
"@loomstack/runtime": "^0.0.
|
|
1006
|
-
"@loomstack/postgres": "^0.0.
|
|
1004
|
+
"@loomstack/koa": "^0.0.2",
|
|
1005
|
+
"@loomstack/runtime": "^0.0.2",
|
|
1006
|
+
"@loomstack/postgres": "^0.0.2",
|
|
1007
1007
|
koa: "^3.2.1",
|
|
1008
1008
|
"koa-bodyparser": "^4.4.1"
|
|
1009
1009
|
},
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-loomstack-app",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Create a full-stack loomstack application",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"yaml": "^2.9.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@loomstack/generator": "0.0.
|
|
23
|
+
"@loomstack/generator": "0.0.2"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=22.0.0"
|