create-objectstack 4.0.4 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +9 -9
- package/package.json +20 -3
- package/.turbo/turbo-build.log +0 -13
- package/CHANGELOG.md +0 -45
- package/src/index.ts +0 -768
- package/src/templates/copilot-instructions.md +0 -74
- package/tsconfig.json +0 -23
- package/tsup.config.ts +0 -15
package/dist/index.js
CHANGED
|
@@ -70,7 +70,7 @@ export default defineStack({
|
|
|
70
70
|
include: ["*.ts", "src/**/*"],
|
|
71
71
|
exclude: ["dist", "node_modules"]
|
|
72
72
|
}, null, 2) + "\n",
|
|
73
|
-
"src/objects/task.ts": () => `import
|
|
73
|
+
"src/objects/task.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
74
74
|
|
|
75
75
|
const task: Data.Object = {
|
|
76
76
|
name: 'task',
|
|
@@ -204,7 +204,7 @@ export default defineStack({
|
|
|
204
204
|
include: ["*.ts", "src/**/*"],
|
|
205
205
|
exclude: ["dist", "node_modules"]
|
|
206
206
|
}, null, 2) + "\n",
|
|
207
|
-
"src/objects/contact.ts": () => `import
|
|
207
|
+
"src/objects/contact.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
208
208
|
|
|
209
209
|
const contact: Data.Object = {
|
|
210
210
|
name: 'contact',
|
|
@@ -239,7 +239,7 @@ const contact: Data.Object = {
|
|
|
239
239
|
|
|
240
240
|
export default contact;
|
|
241
241
|
`,
|
|
242
|
-
"src/objects/company.ts": () => `import
|
|
242
|
+
"src/objects/company.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
243
243
|
|
|
244
244
|
const company: Data.Object = {
|
|
245
245
|
name: 'company',
|
|
@@ -270,7 +270,7 @@ const company: Data.Object = {
|
|
|
270
270
|
|
|
271
271
|
export default company;
|
|
272
272
|
`,
|
|
273
|
-
"src/objects/deal.ts": () => `import
|
|
273
|
+
"src/objects/deal.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
274
274
|
|
|
275
275
|
const deal: Data.Object = {
|
|
276
276
|
name: 'deal',
|
|
@@ -321,7 +321,7 @@ export default deal;
|
|
|
321
321
|
export { default as company } from './company';
|
|
322
322
|
export { default as deal } from './deal';
|
|
323
323
|
`,
|
|
324
|
-
"src/views/contact_list.ts": () => `import
|
|
324
|
+
"src/views/contact_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
325
325
|
|
|
326
326
|
const contactList: UI.View = {
|
|
327
327
|
name: 'contact_list',
|
|
@@ -333,7 +333,7 @@ const contactList: UI.View = {
|
|
|
333
333
|
|
|
334
334
|
export default contactList;
|
|
335
335
|
`,
|
|
336
|
-
"src/views/company_list.ts": () => `import
|
|
336
|
+
"src/views/company_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
337
337
|
|
|
338
338
|
const companyList: UI.View = {
|
|
339
339
|
name: 'company_list',
|
|
@@ -345,7 +345,7 @@ const companyList: UI.View = {
|
|
|
345
345
|
|
|
346
346
|
export default companyList;
|
|
347
347
|
`,
|
|
348
|
-
"src/views/deal_list.ts": () => `import
|
|
348
|
+
"src/views/deal_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
349
349
|
|
|
350
350
|
const dealList: UI.View = {
|
|
351
351
|
name: 'deal_list',
|
|
@@ -357,7 +357,7 @@ const dealList: UI.View = {
|
|
|
357
357
|
|
|
358
358
|
export default dealList;
|
|
359
359
|
`,
|
|
360
|
-
"src/apps/crm.ts": () => `import
|
|
360
|
+
"src/apps/crm.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
361
361
|
|
|
362
362
|
const crm: UI.App = {
|
|
363
363
|
name: 'crm',
|
|
@@ -469,7 +469,7 @@ export default defineStack({
|
|
|
469
469
|
*/
|
|
470
470
|
export * as objects from './objects';
|
|
471
471
|
`,
|
|
472
|
-
"src/objects/sample.ts": (name) => `import
|
|
472
|
+
"src/objects/sample.ts": (name) => `import * as Data from '@objectstack/spec/data';
|
|
473
473
|
|
|
474
474
|
const sample: Data.Object = {
|
|
475
475
|
name: '${name}_sample',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-objectstack",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "Create a new ObjectStack project — npx create-objectstack",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-objectstack": "./bin/create-objectstack.js"
|
|
@@ -19,9 +19,26 @@
|
|
|
19
19
|
"commander": "^14.0.3"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^25.6.
|
|
22
|
+
"@types/node": "^25.6.2",
|
|
23
23
|
"tsup": "^8.5.1",
|
|
24
|
-
"typescript": "^6.0.
|
|
24
|
+
"typescript": "^6.0.3"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/objectstack-ai/framework.git",
|
|
29
|
+
"directory": "packages/create-objectstack"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://objectstack.ai/docs",
|
|
32
|
+
"bugs": "https://github.com/objectstack-ai/framework/issues",
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18.0.0"
|
|
25
42
|
},
|
|
26
43
|
"scripts": {
|
|
27
44
|
"build": "tsup",
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> create-objectstack@4.0.4 build /home/runner/work/framework/framework/packages/create-objectstack
|
|
3
|
-
> tsup
|
|
4
|
-
|
|
5
|
-
[34mCLI[39m Building entry: src/index.ts
|
|
6
|
-
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
-
[34mCLI[39m tsup v8.5.1
|
|
8
|
-
[34mCLI[39m Using tsup config: /home/runner/work/framework/framework/packages/create-objectstack/tsup.config.ts
|
|
9
|
-
[34mCLI[39m Target: es2022
|
|
10
|
-
[34mCLI[39m Cleaning output folder
|
|
11
|
-
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/index.js [22m[32m17.97 KB[39m
|
|
13
|
-
[32mESM[39m ⚡️ Build success in 45ms
|
package/CHANGELOG.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# create-objectstack
|
|
2
|
-
|
|
3
|
-
## 4.0.4
|
|
4
|
-
|
|
5
|
-
## 4.0.3
|
|
6
|
-
|
|
7
|
-
## 4.0.2
|
|
8
|
-
|
|
9
|
-
## 4.0.0
|
|
10
|
-
|
|
11
|
-
## 3.3.1
|
|
12
|
-
|
|
13
|
-
## 3.3.0
|
|
14
|
-
|
|
15
|
-
## 3.2.9
|
|
16
|
-
|
|
17
|
-
## 3.2.8
|
|
18
|
-
|
|
19
|
-
## 3.2.7
|
|
20
|
-
|
|
21
|
-
## 3.2.6
|
|
22
|
-
|
|
23
|
-
## 3.2.5
|
|
24
|
-
|
|
25
|
-
## 3.2.4
|
|
26
|
-
|
|
27
|
-
## 3.2.3
|
|
28
|
-
|
|
29
|
-
## 3.2.2
|
|
30
|
-
|
|
31
|
-
## 3.2.1
|
|
32
|
-
|
|
33
|
-
## 3.2.0
|
|
34
|
-
|
|
35
|
-
## 3.1.1
|
|
36
|
-
|
|
37
|
-
## 3.1.0
|
|
38
|
-
|
|
39
|
-
## 3.0.11
|
|
40
|
-
|
|
41
|
-
## 3.0.10
|
|
42
|
-
|
|
43
|
-
## 3.0.9
|
|
44
|
-
|
|
45
|
-
## 3.0.8
|
package/src/index.ts
DELETED
|
@@ -1,768 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { execSync } from 'child_process';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = path.dirname(__filename);
|
|
12
|
-
const TEMPLATES_DIR = path.resolve(__dirname, 'templates');
|
|
13
|
-
|
|
14
|
-
// ─── Template Registry ──────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
type TemplateFiles = Record<string, (name: string) => string>;
|
|
17
|
-
|
|
18
|
-
interface Template {
|
|
19
|
-
description: string;
|
|
20
|
-
files: TemplateFiles;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const TEMPLATES: Record<string, Template> = {
|
|
24
|
-
'minimal-api': {
|
|
25
|
-
description: 'Server + memory driver + 1 object + REST API',
|
|
26
|
-
files: {
|
|
27
|
-
'objectstack.config.ts': (name) => `import { defineStack } from '@objectstack/spec';
|
|
28
|
-
import * as objects from './src/objects';
|
|
29
|
-
|
|
30
|
-
export default defineStack({
|
|
31
|
-
manifest: {
|
|
32
|
-
id: 'com.example.${name}',
|
|
33
|
-
namespace: '${name}',
|
|
34
|
-
version: '0.1.0',
|
|
35
|
-
type: 'app',
|
|
36
|
-
name: '${toTitleCase(name)}',
|
|
37
|
-
description: '${toTitleCase(name)} — built with ObjectStack',
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
objects: Object.values(objects),
|
|
41
|
-
|
|
42
|
-
api: {
|
|
43
|
-
rest: { enabled: true, basePath: '/api' },
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
`,
|
|
47
|
-
'package.json': (name) => JSON.stringify({
|
|
48
|
-
name,
|
|
49
|
-
version: '0.1.0',
|
|
50
|
-
private: true,
|
|
51
|
-
type: 'module',
|
|
52
|
-
scripts: {
|
|
53
|
-
dev: 'objectstack dev',
|
|
54
|
-
start: 'objectstack serve',
|
|
55
|
-
build: 'objectstack compile',
|
|
56
|
-
validate: 'objectstack validate',
|
|
57
|
-
typecheck: 'tsc --noEmit',
|
|
58
|
-
},
|
|
59
|
-
dependencies: {
|
|
60
|
-
'@objectstack/spec': '^3.0.0',
|
|
61
|
-
'@objectstack/runtime': '^3.0.0',
|
|
62
|
-
'@objectstack/driver-memory': '^3.0.0',
|
|
63
|
-
'@objectstack/plugin-hono-server': '^3.0.0',
|
|
64
|
-
},
|
|
65
|
-
devDependencies: {
|
|
66
|
-
'@objectstack/cli': '^3.0.0',
|
|
67
|
-
'typescript': '^5.3.0',
|
|
68
|
-
},
|
|
69
|
-
}, null, 2) + '\n',
|
|
70
|
-
'tsconfig.json': () => JSON.stringify({
|
|
71
|
-
compilerOptions: {
|
|
72
|
-
target: 'ES2022',
|
|
73
|
-
module: 'ESNext',
|
|
74
|
-
moduleResolution: 'bundler',
|
|
75
|
-
strict: true,
|
|
76
|
-
esModuleInterop: true,
|
|
77
|
-
skipLibCheck: true,
|
|
78
|
-
outDir: 'dist',
|
|
79
|
-
rootDir: '.',
|
|
80
|
-
declaration: true,
|
|
81
|
-
},
|
|
82
|
-
include: ['*.ts', 'src/**/*'],
|
|
83
|
-
exclude: ['dist', 'node_modules'],
|
|
84
|
-
}, null, 2) + '\n',
|
|
85
|
-
'src/objects/task.ts': () => `import { Data } from '@objectstack/spec';
|
|
86
|
-
|
|
87
|
-
const task: Data.Object = {
|
|
88
|
-
name: 'task',
|
|
89
|
-
label: 'Task',
|
|
90
|
-
ownership: 'own',
|
|
91
|
-
fields: {
|
|
92
|
-
title: {
|
|
93
|
-
type: 'text',
|
|
94
|
-
label: 'Title',
|
|
95
|
-
required: true,
|
|
96
|
-
},
|
|
97
|
-
description: {
|
|
98
|
-
type: 'textarea',
|
|
99
|
-
label: 'Description',
|
|
100
|
-
},
|
|
101
|
-
status: {
|
|
102
|
-
type: 'select',
|
|
103
|
-
label: 'Status',
|
|
104
|
-
options: [
|
|
105
|
-
{ label: 'Open', value: 'open' },
|
|
106
|
-
{ label: 'In Progress', value: 'in_progress' },
|
|
107
|
-
{ label: 'Done', value: 'done' },
|
|
108
|
-
],
|
|
109
|
-
defaultValue: 'open',
|
|
110
|
-
},
|
|
111
|
-
due_date: {
|
|
112
|
-
type: 'date',
|
|
113
|
-
label: 'Due Date',
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export default task;
|
|
119
|
-
`,
|
|
120
|
-
'src/objects/index.ts': () => `export { default as task } from './task';
|
|
121
|
-
`,
|
|
122
|
-
'.gitignore': () => `node_modules/
|
|
123
|
-
dist/
|
|
124
|
-
*.tsbuildinfo
|
|
125
|
-
`,
|
|
126
|
-
'README.md': (name) => `# ${toTitleCase(name)}
|
|
127
|
-
|
|
128
|
-
Built with [ObjectStack](https://objectstack.com).
|
|
129
|
-
|
|
130
|
-
## Quick Start
|
|
131
|
-
|
|
132
|
-
\`\`\`bash
|
|
133
|
-
# Install dependencies
|
|
134
|
-
npm install
|
|
135
|
-
|
|
136
|
-
# Start development server
|
|
137
|
-
npm run dev
|
|
138
|
-
|
|
139
|
-
# Validate configuration
|
|
140
|
-
npm run validate
|
|
141
|
-
\`\`\`
|
|
142
|
-
|
|
143
|
-
## Project Structure
|
|
144
|
-
|
|
145
|
-
- \`objectstack.config.ts\` — Stack definition (objects, API, settings)
|
|
146
|
-
- \`src/objects/\` — Object definitions
|
|
147
|
-
- \`dist/\` — Compiled output
|
|
148
|
-
|
|
149
|
-
## Learn More
|
|
150
|
-
|
|
151
|
-
- [ObjectStack Documentation](https://objectstack.com/docs)
|
|
152
|
-
`,
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
'full-stack': {
|
|
157
|
-
description: 'Server + UI + auth + 3 CRM objects',
|
|
158
|
-
files: {
|
|
159
|
-
'objectstack.config.ts': (name) => `import { defineStack } from '@objectstack/spec';
|
|
160
|
-
import * as objects from './src/objects';
|
|
161
|
-
import * as apps from './src/apps';
|
|
162
|
-
|
|
163
|
-
export default defineStack({
|
|
164
|
-
manifest: {
|
|
165
|
-
id: 'com.example.${name}',
|
|
166
|
-
namespace: '${name}',
|
|
167
|
-
version: '0.1.0',
|
|
168
|
-
type: 'app',
|
|
169
|
-
name: '${toTitleCase(name)}',
|
|
170
|
-
description: '${toTitleCase(name)} CRM — built with ObjectStack',
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
objects: Object.values(objects),
|
|
174
|
-
apps: Object.values(apps),
|
|
175
|
-
|
|
176
|
-
api: {
|
|
177
|
-
rest: { enabled: true, basePath: '/api' },
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
`,
|
|
181
|
-
'package.json': (name) => JSON.stringify({
|
|
182
|
-
name,
|
|
183
|
-
version: '0.1.0',
|
|
184
|
-
private: true,
|
|
185
|
-
type: 'module',
|
|
186
|
-
scripts: {
|
|
187
|
-
dev: 'objectstack dev',
|
|
188
|
-
start: 'objectstack serve',
|
|
189
|
-
build: 'objectstack compile',
|
|
190
|
-
validate: 'objectstack validate',
|
|
191
|
-
typecheck: 'tsc --noEmit',
|
|
192
|
-
},
|
|
193
|
-
dependencies: {
|
|
194
|
-
'@objectstack/spec': '^3.0.0',
|
|
195
|
-
'@objectstack/runtime': '^3.0.0',
|
|
196
|
-
'@objectstack/driver-memory': '^3.0.0',
|
|
197
|
-
'@objectstack/plugin-hono-server': '^3.0.0',
|
|
198
|
-
'@objectstack/plugin-auth': '^3.0.0',
|
|
199
|
-
},
|
|
200
|
-
devDependencies: {
|
|
201
|
-
'@objectstack/cli': '^3.0.0',
|
|
202
|
-
'typescript': '^5.3.0',
|
|
203
|
-
},
|
|
204
|
-
}, null, 2) + '\n',
|
|
205
|
-
'tsconfig.json': () => JSON.stringify({
|
|
206
|
-
compilerOptions: {
|
|
207
|
-
target: 'ES2022',
|
|
208
|
-
module: 'ESNext',
|
|
209
|
-
moduleResolution: 'bundler',
|
|
210
|
-
strict: true,
|
|
211
|
-
esModuleInterop: true,
|
|
212
|
-
skipLibCheck: true,
|
|
213
|
-
outDir: 'dist',
|
|
214
|
-
rootDir: '.',
|
|
215
|
-
declaration: true,
|
|
216
|
-
},
|
|
217
|
-
include: ['*.ts', 'src/**/*'],
|
|
218
|
-
exclude: ['dist', 'node_modules'],
|
|
219
|
-
}, null, 2) + '\n',
|
|
220
|
-
'src/objects/contact.ts': () => `import { Data } from '@objectstack/spec';
|
|
221
|
-
|
|
222
|
-
const contact: Data.Object = {
|
|
223
|
-
name: 'contact',
|
|
224
|
-
label: 'Contact',
|
|
225
|
-
ownership: 'own',
|
|
226
|
-
fields: {
|
|
227
|
-
first_name: {
|
|
228
|
-
type: 'text',
|
|
229
|
-
label: 'First Name',
|
|
230
|
-
required: true,
|
|
231
|
-
},
|
|
232
|
-
last_name: {
|
|
233
|
-
type: 'text',
|
|
234
|
-
label: 'Last Name',
|
|
235
|
-
required: true,
|
|
236
|
-
},
|
|
237
|
-
email: {
|
|
238
|
-
type: 'text',
|
|
239
|
-
label: 'Email',
|
|
240
|
-
},
|
|
241
|
-
phone: {
|
|
242
|
-
type: 'text',
|
|
243
|
-
label: 'Phone',
|
|
244
|
-
},
|
|
245
|
-
company: {
|
|
246
|
-
type: 'lookup',
|
|
247
|
-
label: 'Company',
|
|
248
|
-
reference: 'company',
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
export default contact;
|
|
254
|
-
`,
|
|
255
|
-
'src/objects/company.ts': () => `import { Data } from '@objectstack/spec';
|
|
256
|
-
|
|
257
|
-
const company: Data.Object = {
|
|
258
|
-
name: 'company',
|
|
259
|
-
label: 'Company',
|
|
260
|
-
ownership: 'own',
|
|
261
|
-
fields: {
|
|
262
|
-
name: {
|
|
263
|
-
type: 'text',
|
|
264
|
-
label: 'Company Name',
|
|
265
|
-
required: true,
|
|
266
|
-
},
|
|
267
|
-
website: {
|
|
268
|
-
type: 'text',
|
|
269
|
-
label: 'Website',
|
|
270
|
-
},
|
|
271
|
-
industry: {
|
|
272
|
-
type: 'select',
|
|
273
|
-
label: 'Industry',
|
|
274
|
-
options: [
|
|
275
|
-
{ label: 'Technology', value: 'technology' },
|
|
276
|
-
{ label: 'Finance', value: 'finance' },
|
|
277
|
-
{ label: 'Healthcare', value: 'healthcare' },
|
|
278
|
-
{ label: 'Other', value: 'other' },
|
|
279
|
-
],
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
export default company;
|
|
285
|
-
`,
|
|
286
|
-
'src/objects/deal.ts': () => `import { Data } from '@objectstack/spec';
|
|
287
|
-
|
|
288
|
-
const deal: Data.Object = {
|
|
289
|
-
name: 'deal',
|
|
290
|
-
label: 'Deal',
|
|
291
|
-
ownership: 'own',
|
|
292
|
-
fields: {
|
|
293
|
-
name: {
|
|
294
|
-
type: 'text',
|
|
295
|
-
label: 'Deal Name',
|
|
296
|
-
required: true,
|
|
297
|
-
},
|
|
298
|
-
amount: {
|
|
299
|
-
type: 'number',
|
|
300
|
-
label: 'Amount',
|
|
301
|
-
},
|
|
302
|
-
stage: {
|
|
303
|
-
type: 'select',
|
|
304
|
-
label: 'Stage',
|
|
305
|
-
options: [
|
|
306
|
-
{ label: 'Prospecting', value: 'prospecting' },
|
|
307
|
-
{ label: 'Qualification', value: 'qualification' },
|
|
308
|
-
{ label: 'Proposal', value: 'proposal' },
|
|
309
|
-
{ label: 'Closed Won', value: 'closed_won' },
|
|
310
|
-
{ label: 'Closed Lost', value: 'closed_lost' },
|
|
311
|
-
],
|
|
312
|
-
defaultValue: 'prospecting',
|
|
313
|
-
},
|
|
314
|
-
contact: {
|
|
315
|
-
type: 'lookup',
|
|
316
|
-
label: 'Contact',
|
|
317
|
-
reference: 'contact',
|
|
318
|
-
},
|
|
319
|
-
company: {
|
|
320
|
-
type: 'lookup',
|
|
321
|
-
label: 'Company',
|
|
322
|
-
reference: 'company',
|
|
323
|
-
},
|
|
324
|
-
close_date: {
|
|
325
|
-
type: 'date',
|
|
326
|
-
label: 'Close Date',
|
|
327
|
-
},
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
export default deal;
|
|
332
|
-
`,
|
|
333
|
-
'src/objects/index.ts': () => `export { default as contact } from './contact';
|
|
334
|
-
export { default as company } from './company';
|
|
335
|
-
export { default as deal } from './deal';
|
|
336
|
-
`,
|
|
337
|
-
'src/views/contact_list.ts': () => `import { UI } from '@objectstack/spec';
|
|
338
|
-
|
|
339
|
-
const contactList: UI.View = {
|
|
340
|
-
name: 'contact_list',
|
|
341
|
-
label: 'All Contacts',
|
|
342
|
-
object: 'contact',
|
|
343
|
-
type: 'list',
|
|
344
|
-
columns: ['first_name', 'last_name', 'email', 'phone', 'company'],
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
export default contactList;
|
|
348
|
-
`,
|
|
349
|
-
'src/views/company_list.ts': () => `import { UI } from '@objectstack/spec';
|
|
350
|
-
|
|
351
|
-
const companyList: UI.View = {
|
|
352
|
-
name: 'company_list',
|
|
353
|
-
label: 'All Companies',
|
|
354
|
-
object: 'company',
|
|
355
|
-
type: 'list',
|
|
356
|
-
columns: ['name', 'website', 'industry'],
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
export default companyList;
|
|
360
|
-
`,
|
|
361
|
-
'src/views/deal_list.ts': () => `import { UI } from '@objectstack/spec';
|
|
362
|
-
|
|
363
|
-
const dealList: UI.View = {
|
|
364
|
-
name: 'deal_list',
|
|
365
|
-
label: 'All Deals',
|
|
366
|
-
object: 'deal',
|
|
367
|
-
type: 'list',
|
|
368
|
-
columns: ['name', 'amount', 'stage', 'contact', 'close_date'],
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
export default dealList;
|
|
372
|
-
`,
|
|
373
|
-
'src/apps/crm.ts': () => `import { UI } from '@objectstack/spec';
|
|
374
|
-
|
|
375
|
-
const crm: UI.App = {
|
|
376
|
-
name: 'crm',
|
|
377
|
-
label: 'CRM',
|
|
378
|
-
description: 'Customer Relationship Management',
|
|
379
|
-
navigation: [
|
|
380
|
-
{ type: 'object', object: 'contact', label: 'Contacts' },
|
|
381
|
-
{ type: 'object', object: 'company', label: 'Companies' },
|
|
382
|
-
{ type: 'object', object: 'deal', label: 'Deals' },
|
|
383
|
-
],
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
export default crm;
|
|
387
|
-
`,
|
|
388
|
-
'src/apps/index.ts': () => `export { default as crm } from './crm';
|
|
389
|
-
`,
|
|
390
|
-
'.gitignore': () => `node_modules/
|
|
391
|
-
dist/
|
|
392
|
-
*.tsbuildinfo
|
|
393
|
-
`,
|
|
394
|
-
'README.md': (name) => `# ${toTitleCase(name)}
|
|
395
|
-
|
|
396
|
-
A full-stack CRM application built with [ObjectStack](https://objectstack.com).
|
|
397
|
-
|
|
398
|
-
## Quick Start
|
|
399
|
-
|
|
400
|
-
\`\`\`bash
|
|
401
|
-
npm install
|
|
402
|
-
npm run dev
|
|
403
|
-
\`\`\`
|
|
404
|
-
|
|
405
|
-
## Project Structure
|
|
406
|
-
|
|
407
|
-
- \`objectstack.config.ts\` — Stack definition
|
|
408
|
-
- \`src/objects/\` — Data objects (Contact, Company, Deal)
|
|
409
|
-
- \`src/views/\` — List views
|
|
410
|
-
- \`src/apps/crm.ts\` — CRM app with navigation
|
|
411
|
-
|
|
412
|
-
## Learn More
|
|
413
|
-
|
|
414
|
-
- [ObjectStack Documentation](https://objectstack.com/docs)
|
|
415
|
-
`,
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
|
|
419
|
-
plugin: {
|
|
420
|
-
description: 'Plugin skeleton with test setup',
|
|
421
|
-
files: {
|
|
422
|
-
'objectstack.config.ts': (name) => `import { defineStack } from '@objectstack/spec';
|
|
423
|
-
import * as objects from './src/objects';
|
|
424
|
-
|
|
425
|
-
export default defineStack({
|
|
426
|
-
manifest: {
|
|
427
|
-
id: 'com.objectstack.plugin-${name}',
|
|
428
|
-
namespace: 'plugin_${name}',
|
|
429
|
-
version: '0.1.0',
|
|
430
|
-
type: 'plugin',
|
|
431
|
-
name: '${toTitleCase(name)} Plugin',
|
|
432
|
-
description: 'ObjectStack Plugin: ${toTitleCase(name)}',
|
|
433
|
-
},
|
|
434
|
-
|
|
435
|
-
objects: Object.values(objects),
|
|
436
|
-
});
|
|
437
|
-
`,
|
|
438
|
-
'package.json': (name) => JSON.stringify({
|
|
439
|
-
name: `@objectstack/plugin-${name}`,
|
|
440
|
-
version: '0.1.0',
|
|
441
|
-
description: `ObjectStack Plugin: ${toTitleCase(name)}`,
|
|
442
|
-
main: 'dist/index.js',
|
|
443
|
-
types: 'dist/index.d.ts',
|
|
444
|
-
type: 'module',
|
|
445
|
-
scripts: {
|
|
446
|
-
build: 'tsc',
|
|
447
|
-
dev: 'tsc --watch',
|
|
448
|
-
test: 'vitest run',
|
|
449
|
-
validate: 'objectstack validate',
|
|
450
|
-
typecheck: 'tsc --noEmit',
|
|
451
|
-
},
|
|
452
|
-
keywords: ['objectstack', 'plugin', name],
|
|
453
|
-
author: '',
|
|
454
|
-
license: 'MIT',
|
|
455
|
-
dependencies: {
|
|
456
|
-
'@objectstack/spec': '^3.0.0',
|
|
457
|
-
},
|
|
458
|
-
devDependencies: {
|
|
459
|
-
'@types/node': '^22.0.0',
|
|
460
|
-
'typescript': '^5.3.0',
|
|
461
|
-
'vitest': '^4.0.0',
|
|
462
|
-
},
|
|
463
|
-
}, null, 2) + '\n',
|
|
464
|
-
'tsconfig.json': () => JSON.stringify({
|
|
465
|
-
compilerOptions: {
|
|
466
|
-
target: 'ES2022',
|
|
467
|
-
module: 'ESNext',
|
|
468
|
-
moduleResolution: 'bundler',
|
|
469
|
-
strict: true,
|
|
470
|
-
esModuleInterop: true,
|
|
471
|
-
skipLibCheck: true,
|
|
472
|
-
outDir: 'dist',
|
|
473
|
-
rootDir: '.',
|
|
474
|
-
declaration: true,
|
|
475
|
-
},
|
|
476
|
-
include: ['*.ts', 'src/**/*'],
|
|
477
|
-
exclude: ['dist', 'node_modules'],
|
|
478
|
-
}, null, 2) + '\n',
|
|
479
|
-
'src/index.ts': (name) => `/**
|
|
480
|
-
* ${toTitleCase(name)} Plugin for ObjectStack
|
|
481
|
-
*
|
|
482
|
-
* Entry point — re-exports all plugin metadata.
|
|
483
|
-
*/
|
|
484
|
-
export * as objects from './objects';
|
|
485
|
-
`,
|
|
486
|
-
'src/objects/sample.ts': (name) => `import { Data } from '@objectstack/spec';
|
|
487
|
-
|
|
488
|
-
const sample: Data.Object = {
|
|
489
|
-
name: '${name}_sample',
|
|
490
|
-
label: '${toTitleCase(name)} Sample',
|
|
491
|
-
ownership: 'own',
|
|
492
|
-
fields: {
|
|
493
|
-
name: {
|
|
494
|
-
type: 'text',
|
|
495
|
-
label: 'Name',
|
|
496
|
-
required: true,
|
|
497
|
-
},
|
|
498
|
-
},
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
export default sample;
|
|
502
|
-
`,
|
|
503
|
-
'src/objects/index.ts': () => `export { default as sample } from './sample';
|
|
504
|
-
`,
|
|
505
|
-
'test/sample.test.ts': (name) => `import { describe, it, expect } from 'vitest';
|
|
506
|
-
import sample from '../src/objects/sample';
|
|
507
|
-
|
|
508
|
-
describe('${name} plugin', () => {
|
|
509
|
-
it('should export a valid sample object', () => {
|
|
510
|
-
expect(sample).toBeDefined();
|
|
511
|
-
expect(sample.name).toBe('${name}_sample');
|
|
512
|
-
expect(sample.fields).toHaveProperty('name');
|
|
513
|
-
});
|
|
514
|
-
});
|
|
515
|
-
`,
|
|
516
|
-
'.gitignore': () => `node_modules/
|
|
517
|
-
dist/
|
|
518
|
-
*.tsbuildinfo
|
|
519
|
-
`,
|
|
520
|
-
'README.md': (name) => `# @objectstack/plugin-${name}
|
|
521
|
-
|
|
522
|
-
ObjectStack Plugin: ${toTitleCase(name)}
|
|
523
|
-
|
|
524
|
-
## Installation
|
|
525
|
-
|
|
526
|
-
\`\`\`bash
|
|
527
|
-
npm install @objectstack/plugin-${name}
|
|
528
|
-
\`\`\`
|
|
529
|
-
|
|
530
|
-
## Usage
|
|
531
|
-
|
|
532
|
-
\`\`\`typescript
|
|
533
|
-
import { defineStack } from '@objectstack/spec';
|
|
534
|
-
|
|
535
|
-
export default defineStack({
|
|
536
|
-
plugins: [
|
|
537
|
-
'@objectstack/plugin-${name}',
|
|
538
|
-
],
|
|
539
|
-
});
|
|
540
|
-
\`\`\`
|
|
541
|
-
|
|
542
|
-
## Development
|
|
543
|
-
|
|
544
|
-
\`\`\`bash
|
|
545
|
-
# Run tests
|
|
546
|
-
npm test
|
|
547
|
-
|
|
548
|
-
# Build
|
|
549
|
-
npm run build
|
|
550
|
-
|
|
551
|
-
# Validate metadata
|
|
552
|
-
npm run validate
|
|
553
|
-
\`\`\`
|
|
554
|
-
|
|
555
|
-
## License
|
|
556
|
-
|
|
557
|
-
MIT
|
|
558
|
-
`,
|
|
559
|
-
},
|
|
560
|
-
},
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
// ─── Shared AI Configuration Files ──────────────────────────────────
|
|
564
|
-
// These files are added to every template so third-party developers
|
|
565
|
-
// get AI-assisted development (Copilot + Claude) out of the box.
|
|
566
|
-
// Templates are maintained as standalone files in src/templates/ for
|
|
567
|
-
// easy editing — no need to modify TypeScript code.
|
|
568
|
-
|
|
569
|
-
function readTemplate(filename: string): string {
|
|
570
|
-
return fs.readFileSync(path.join(TEMPLATES_DIR, filename), 'utf-8');
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const AI_CONFIG_FILES: TemplateFiles = {
|
|
574
|
-
'.github/copilot-instructions.md': (name) =>
|
|
575
|
-
readTemplate('copilot-instructions.md')
|
|
576
|
-
.replaceAll('{{PROJECT_NAME}}', name)
|
|
577
|
-
.replaceAll('{{PROJECT_TITLE}}', toTitleCase(name)),
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
// ─── Helpers ────────────────────────────────────────────────────────
|
|
581
|
-
|
|
582
|
-
function toCamelCase(str: string): string {
|
|
583
|
-
return str.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
function toTitleCase(str: string): string {
|
|
587
|
-
return str.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// ─── Formatting (matches @objectstack/cli style) ────────────────────
|
|
591
|
-
|
|
592
|
-
function printHeader(title: string) {
|
|
593
|
-
console.log(chalk.bold(`\n◆ ${title}`));
|
|
594
|
-
console.log(chalk.dim('─'.repeat(40)));
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
function printKV(key: string, value: string) {
|
|
598
|
-
console.log(` ${chalk.dim(key + ':')} ${chalk.white(value)}`);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function printSuccess(msg: string) {
|
|
602
|
-
console.log(chalk.green(` ✓ ${msg}`));
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
function printError(msg: string) {
|
|
606
|
-
console.log(chalk.red(` ✗ ${msg}`));
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function printStep(msg: string) {
|
|
610
|
-
console.log(chalk.yellow(` → ${msg}`));
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
function printWarning(msg: string) {
|
|
614
|
-
console.log(chalk.yellow(` ⚠ ${msg}`));
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// ─── CLI Program ────────────────────────────────────────────────────
|
|
618
|
-
|
|
619
|
-
const program = new Command()
|
|
620
|
-
.name('create-objectstack')
|
|
621
|
-
.description('Create a new ObjectStack project')
|
|
622
|
-
.version('3.0.0')
|
|
623
|
-
.argument('[name]', 'Project name (defaults to current directory name)')
|
|
624
|
-
.option(
|
|
625
|
-
'-t, --template <template>',
|
|
626
|
-
'Project template: minimal-api, full-stack, plugin',
|
|
627
|
-
'minimal-api',
|
|
628
|
-
)
|
|
629
|
-
.option('--skip-install', 'Skip dependency installation')
|
|
630
|
-
.action(async (name: string | undefined, options: { template: string; skipInstall?: boolean }) => {
|
|
631
|
-
// Banner
|
|
632
|
-
console.log('');
|
|
633
|
-
console.log(chalk.bold.cyan(' ╔═══════════════════════════════════╗'));
|
|
634
|
-
console.log(chalk.bold.cyan(' ║') + chalk.bold(' ◆ Create ObjectStack ') + chalk.dim('v3.0') + chalk.bold.cyan(' ║'));
|
|
635
|
-
console.log(chalk.bold.cyan(' ╚═══════════════════════════════════╝'));
|
|
636
|
-
|
|
637
|
-
printHeader('New Project');
|
|
638
|
-
|
|
639
|
-
// Resolve template
|
|
640
|
-
const template = TEMPLATES[options.template];
|
|
641
|
-
if (!template) {
|
|
642
|
-
printError(`Unknown template: ${options.template}`);
|
|
643
|
-
console.log(chalk.dim(` Available: ${Object.keys(TEMPLATES).join(', ')}`));
|
|
644
|
-
process.exit(1);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// Resolve project name and directory
|
|
648
|
-
const cwd = process.cwd();
|
|
649
|
-
const projectName = name || path.basename(cwd);
|
|
650
|
-
const targetDir = name ? path.resolve(cwd, name) : cwd;
|
|
651
|
-
const isCurrentDir = targetDir === cwd;
|
|
652
|
-
|
|
653
|
-
printKV('Project', projectName);
|
|
654
|
-
printKV('Template', `${options.template} — ${template.description}`);
|
|
655
|
-
printKV('Directory', targetDir);
|
|
656
|
-
console.log('');
|
|
657
|
-
|
|
658
|
-
// Guard: if creating in a sub-directory, check it doesn't already exist
|
|
659
|
-
if (!isCurrentDir && fs.existsSync(targetDir)) {
|
|
660
|
-
const existing = fs.readdirSync(targetDir);
|
|
661
|
-
if (existing.length > 0) {
|
|
662
|
-
printError(`Directory already exists and is not empty: ${targetDir}`);
|
|
663
|
-
process.exit(1);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const createdFiles: string[] = [];
|
|
668
|
-
|
|
669
|
-
try {
|
|
670
|
-
// Ensure target directory exists
|
|
671
|
-
if (!fs.existsSync(targetDir)) {
|
|
672
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// Merge template files with shared AI configuration files
|
|
676
|
-
const allFiles: TemplateFiles = { ...template.files, ...AI_CONFIG_FILES };
|
|
677
|
-
|
|
678
|
-
// Write every file defined by the template + AI config
|
|
679
|
-
for (const [filePath, contentFn] of Object.entries(allFiles)) {
|
|
680
|
-
const fullPath = path.join(targetDir, filePath);
|
|
681
|
-
const dir = path.dirname(fullPath);
|
|
682
|
-
|
|
683
|
-
if (!fs.existsSync(dir)) {
|
|
684
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
fs.writeFileSync(fullPath, contentFn(projectName));
|
|
688
|
-
createdFiles.push(filePath);
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
// Summary
|
|
692
|
-
console.log(chalk.bold(' Created files:'));
|
|
693
|
-
for (const f of createdFiles) {
|
|
694
|
-
console.log(chalk.green(` + ${f}`));
|
|
695
|
-
}
|
|
696
|
-
console.log('');
|
|
697
|
-
|
|
698
|
-
// Install dependencies
|
|
699
|
-
if (!options.skipInstall) {
|
|
700
|
-
printStep('Installing dependencies...');
|
|
701
|
-
try {
|
|
702
|
-
// Detect package manager — prefer pnpm, fall back to npm
|
|
703
|
-
const pm = detectPackageManager();
|
|
704
|
-
execSync(`${pm} install`, { stdio: 'inherit', cwd: targetDir });
|
|
705
|
-
console.log('');
|
|
706
|
-
} catch {
|
|
707
|
-
printWarning('Dependency installation failed. Run `npm install` manually.');
|
|
708
|
-
console.log('');
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// Install ObjectStack AI skills via the standard skills CLI
|
|
713
|
-
if (!options.skipInstall) {
|
|
714
|
-
printStep('Installing AI skills for your coding agent...');
|
|
715
|
-
try {
|
|
716
|
-
execSync('npx -y skills add objectstack-ai/framework --all', {
|
|
717
|
-
stdio: 'inherit',
|
|
718
|
-
cwd: targetDir,
|
|
719
|
-
});
|
|
720
|
-
console.log('');
|
|
721
|
-
} catch {
|
|
722
|
-
printWarning(
|
|
723
|
-
'Skills installation skipped. Run manually:\n' +
|
|
724
|
-
' npx skills add objectstack-ai/framework',
|
|
725
|
-
);
|
|
726
|
-
console.log('');
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
printSuccess('Project created!');
|
|
731
|
-
console.log('');
|
|
732
|
-
|
|
733
|
-
// Next steps
|
|
734
|
-
console.log(chalk.bold(' Next steps:'));
|
|
735
|
-
if (!isCurrentDir) {
|
|
736
|
-
console.log(chalk.dim(` cd ${name}`));
|
|
737
|
-
}
|
|
738
|
-
if (options.skipInstall) {
|
|
739
|
-
console.log(chalk.dim(' npm install'));
|
|
740
|
-
}
|
|
741
|
-
console.log(chalk.dim(' npm run dev # Start development server'));
|
|
742
|
-
console.log(chalk.dim(' npm run validate # Check configuration'));
|
|
743
|
-
if (options.skipInstall) {
|
|
744
|
-
console.log('');
|
|
745
|
-
console.log(chalk.bold(' AI Skills (recommended):'));
|
|
746
|
-
console.log(chalk.dim(' npx skills add objectstack-ai/framework'));
|
|
747
|
-
}
|
|
748
|
-
console.log('');
|
|
749
|
-
|
|
750
|
-
} catch (error: any) {
|
|
751
|
-
printError(error.message || String(error));
|
|
752
|
-
process.exit(1);
|
|
753
|
-
}
|
|
754
|
-
});
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Detect available package manager (pnpm > npm).
|
|
758
|
-
*/
|
|
759
|
-
function detectPackageManager(): string {
|
|
760
|
-
try {
|
|
761
|
-
execSync('pnpm --version', { stdio: 'ignore' });
|
|
762
|
-
return 'pnpm';
|
|
763
|
-
} catch {
|
|
764
|
-
return 'npm';
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
program.parse();
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# {{PROJECT_TITLE}} — Copilot Instructions
|
|
2
|
-
|
|
3
|
-
> Auto-generated by `create-objectstack`. Customise freely.
|
|
4
|
-
|
|
5
|
-
## Project Context
|
|
6
|
-
|
|
7
|
-
This is an **ObjectStack** application — a metadata-driven low-code project
|
|
8
|
-
that defines business objects, views, automations, and AI agents in TypeScript.
|
|
9
|
-
|
|
10
|
-
- **Entry point:** `objectstack.config.ts` (uses `defineStack()`)
|
|
11
|
-
- **Spec package:** `@objectstack/spec` (Zod-first schemas and types)
|
|
12
|
-
|
|
13
|
-
## Naming Conventions
|
|
14
|
-
|
|
15
|
-
| Context | Convention | Example |
|
|
16
|
-
|:--------|:-----------|:--------|
|
|
17
|
-
| Config keys (TS props) | `camelCase` | `maxLength`, `defaultValue` |
|
|
18
|
-
| Machine names (data values) | `snake_case` | `project_task`, `first_name` |
|
|
19
|
-
| Metadata type names | singular | `'agent'`, `'view'`, `'flow'` |
|
|
20
|
-
| File names | `{name}.{type}.ts` | `task.object.ts`, `main.app.ts` |
|
|
21
|
-
|
|
22
|
-
## Key Rules
|
|
23
|
-
|
|
24
|
-
1. **Zod First** — All schema definitions start with Zod. Types are derived via `z.infer<>`.
|
|
25
|
-
2. `defineStack()` is the single configuration entry point in `objectstack.config.ts`.
|
|
26
|
-
3. Use `Object.values()` barrel pattern for metadata arrays.
|
|
27
|
-
4. Import from `@objectstack/spec` — never use relative paths into the spec package.
|
|
28
|
-
|
|
29
|
-
## Project Structure
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
{{PROJECT_NAME}}/
|
|
33
|
-
├── objectstack.config.ts # defineStack() — the single entry point
|
|
34
|
-
├── src/
|
|
35
|
-
│ ├── objects/ # Business object definitions (snake_case names)
|
|
36
|
-
│ ├── views/ # UI view definitions (list, form, kanban, calendar)
|
|
37
|
-
│ ├── apps/ # App navigation & page structure
|
|
38
|
-
│ ├── flows/ # Automation flows & workflows
|
|
39
|
-
│ ├── actions/ # Custom actions (buttons, bulk ops)
|
|
40
|
-
│ ├── dashboards/ # BI dashboards
|
|
41
|
-
│ ├── reports/ # Analytics reports
|
|
42
|
-
│ ├── agents/ # AI agent definitions
|
|
43
|
-
│ ├── i18n/ # Translation bundles
|
|
44
|
-
│ └── handlers/ # Runtime hook handlers
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## AI Skills
|
|
48
|
-
|
|
49
|
-
This project uses ObjectStack skills from `objectstack-ai/framework`.
|
|
50
|
-
Install or update skills with the standard [skills CLI](https://skills.sh/):
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
npx skills add objectstack-ai/framework
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Skills are triggered automatically based on task context:
|
|
57
|
-
|
|
58
|
-
| Skill | Trigger Context |
|
|
59
|
-
|:------|:----------------|
|
|
60
|
-
| **objectstack-schema** | Define objects, fields, relationships, validations, indexes |
|
|
61
|
-
| **objectstack-query** | Filters, sorting, pagination, aggregation, ObjectQL |
|
|
62
|
-
| **objectstack-ui** | Views, dashboards, apps, reports, actions, navigation |
|
|
63
|
-
| **objectstack-api** | REST endpoints, authentication, service contracts |
|
|
64
|
-
| **objectstack-plugin** | Plugin lifecycle, DI, services, hooks, events |
|
|
65
|
-
| **objectstack-automation** | Flows, workflows, triggers, approvals, state machines |
|
|
66
|
-
| **objectstack-ai** | Agents, tools, skills, RAG pipelines, LLM config |
|
|
67
|
-
| **objectstack-quickstart** | Project setup, defineStack(), driver selection |
|
|
68
|
-
| **objectstack-i18n** | Translation bundles, locale config, coverage detection |
|
|
69
|
-
|
|
70
|
-
## Learn More
|
|
71
|
-
|
|
72
|
-
- [ObjectStack Documentation](https://objectstack.com/docs)
|
|
73
|
-
- [GitHub: objectstack-ai/framework](https://github.com/objectstack-ai/framework)
|
|
74
|
-
- [Skills CLI](https://skills.sh/) — Manage AI skills across agents
|
package/tsconfig.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"lib": [
|
|
7
|
-
"ES2022"
|
|
8
|
-
],
|
|
9
|
-
"strict": true,
|
|
10
|
-
"esModuleInterop": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"forceConsistentCasingInFileNames": true,
|
|
13
|
-
"outDir": "dist",
|
|
14
|
-
"rootDir": "src",
|
|
15
|
-
"types": [
|
|
16
|
-
"node"
|
|
17
|
-
],
|
|
18
|
-
"ignoreDeprecations": "6.0"
|
|
19
|
-
},
|
|
20
|
-
"include": [
|
|
21
|
-
"src"
|
|
22
|
-
]
|
|
23
|
-
}
|
package/tsup.config.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import { defineConfig } from 'tsup';
|
|
4
|
-
import { cpSync } from 'fs';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
entry: ['src/index.ts'],
|
|
8
|
-
format: ['esm'],
|
|
9
|
-
clean: true,
|
|
10
|
-
shims: true,
|
|
11
|
-
onSuccess: async () => {
|
|
12
|
-
// Copy template files to dist/ so they sit alongside the bundled JS
|
|
13
|
-
cpSync('src/templates', 'dist/templates', { recursive: true });
|
|
14
|
-
},
|
|
15
|
-
});
|