@boopkit/cli 0.1.6 → 0.1.8
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 +21 -1
- package/dist/capability-versions.json +3 -2
- package/dist/commands/loop.d.ts +1 -1
- package/dist/commands/loop.js +1 -1
- package/dist/commands/status.js +4 -4
- package/dist/commands/update.js +3 -3
- package/dist/lib/preflight.js +3 -3
- package/dist/lib/update.js +1 -1
- package/package.json +1 -1
- package/profiles/web-app/reference/architecture.ref.md +3 -3
package/README.md
CHANGED
|
@@ -17,9 +17,29 @@ npx @boopkit/cli@beta init myapp
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
+
# go to your projects directory
|
|
21
|
+
cd ~/projects
|
|
22
|
+
|
|
23
|
+
# install the boop CLI globally
|
|
24
|
+
npm install -g @boopkit/cli@beta
|
|
25
|
+
|
|
26
|
+
# scaffold a new app from the default profile (web-app)
|
|
20
27
|
boop init my-app
|
|
21
28
|
cd my-app
|
|
22
|
-
|
|
29
|
+
boop status # have your agent follow instructions to finish setup
|
|
30
|
+
|
|
31
|
+
# start your web server
|
|
32
|
+
npm run dev
|
|
33
|
+
|
|
34
|
+
# stop the server...
|
|
35
|
+
|
|
36
|
+
# see available capabilities to add new features
|
|
37
|
+
npm caps
|
|
38
|
+
|
|
39
|
+
# add user authentication and account management features
|
|
40
|
+
# have your agent follow instructions to finish setup
|
|
41
|
+
boop add users-and-accounts
|
|
42
|
+
|
|
23
43
|
```
|
|
24
44
|
|
|
25
45
|
## Commands
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"@boopkit/cap-api": "0.1.0",
|
|
3
|
+
"@boopkit/cap-background-jobs": "0.1.0",
|
|
3
4
|
"@boopkit/cap-cloud-storage": "0.1.0",
|
|
4
5
|
"@boopkit/cap-coding": "0.1.0",
|
|
5
|
-
"@boopkit/cap-database": "0.1.
|
|
6
|
+
"@boopkit/cap-database": "0.1.3",
|
|
6
7
|
"@boopkit/cap-email": "0.1.0",
|
|
7
8
|
"@boopkit/cap-hello": "0.1.0",
|
|
8
|
-
"@boopkit/cap-noticeboard": "0.1.
|
|
9
|
+
"@boopkit/cap-noticeboard": "0.1.1",
|
|
9
10
|
"@boopkit/cap-product-design": "0.1.0",
|
|
10
11
|
"@boopkit/cap-project-mgmt": "0.1.0",
|
|
11
12
|
"@boopkit/cap-services": "0.1.0",
|
package/dist/commands/loop.d.ts
CHANGED
package/dist/commands/loop.js
CHANGED
|
@@ -577,7 +577,7 @@ async function runLoop(options) {
|
|
|
577
577
|
const pollInterval = parseInt(options.pollInterval || '60', 10);
|
|
578
578
|
const model = options.model || 'claude-opus-4-6';
|
|
579
579
|
const perIssueBranch = options.perIssueBranch || false;
|
|
580
|
-
const noBranch = options.
|
|
580
|
+
const noBranch = options.branch === false;
|
|
581
581
|
let includeFeatures = options.features || false;
|
|
582
582
|
const skipPerms = options.skipPerms !== false; // default true
|
|
583
583
|
const bare = options.bare || false;
|
package/dist/commands/status.js
CHANGED
|
@@ -68,7 +68,7 @@ function getStatusData(manifest, dir) {
|
|
|
68
68
|
const capabilities = {};
|
|
69
69
|
for (const capName of manifest.capabilities) {
|
|
70
70
|
const capConfig = manifest.capabilityConfig?.[capName];
|
|
71
|
-
const capMeta = (0, capability_1.getCapability)(capName);
|
|
71
|
+
const capMeta = (0, capability_1.getCapability)(capName, [dir]);
|
|
72
72
|
const capType = capMeta?.type;
|
|
73
73
|
// Resolve env declarations: prefer manifest capabilityConfig, fall back to capability definition
|
|
74
74
|
let envEntries;
|
|
@@ -118,7 +118,7 @@ function getStatusData(manifest, dir) {
|
|
|
118
118
|
}
|
|
119
119
|
if (allRequiredSet) {
|
|
120
120
|
// Env vars are set — check if capability has setup checks or postInstall steps
|
|
121
|
-
const capDef = (0, capability_1.getCapability)(capName);
|
|
121
|
+
const capDef = (0, capability_1.getCapability)(capName, [dir]);
|
|
122
122
|
const hasSetupChecks = capDef?.postInstall?.setupChecks?.length;
|
|
123
123
|
const hasPostInstall = capDef?.postInstall && (capDef.postInstall.steps?.length || capDef.postInstall.verify);
|
|
124
124
|
if (hasSetupChecks || hasPostInstall) {
|
|
@@ -131,7 +131,7 @@ function getStatusData(manifest, dir) {
|
|
|
131
131
|
}
|
|
132
132
|
else {
|
|
133
133
|
// Enrich next steps with postInstall guidance from capability definition
|
|
134
|
-
const capDef = (0, capability_1.getCapability)(capName);
|
|
134
|
+
const capDef = (0, capability_1.getCapability)(capName, [dir]);
|
|
135
135
|
if (capDef?.postInstall) {
|
|
136
136
|
const vars = { projectName: manifest.name, capabilityName: capName };
|
|
137
137
|
const pi = capDef.postInstall;
|
|
@@ -171,7 +171,7 @@ async function enrichWithSetupChecks(data, envValues, projectDir, projectName) {
|
|
|
171
171
|
for (const [capName, cap] of Object.entries(data.capabilities)) {
|
|
172
172
|
if (cap.status !== 'setup')
|
|
173
173
|
continue;
|
|
174
|
-
const capDef = (0, capability_1.getCapability)(capName);
|
|
174
|
+
const capDef = (0, capability_1.getCapability)(capName, [projectDir]);
|
|
175
175
|
const checks = capDef?.postInstall?.setupChecks;
|
|
176
176
|
if (!checks?.length)
|
|
177
177
|
continue;
|
package/dist/commands/update.js
CHANGED
|
@@ -67,7 +67,7 @@ function runUpdate(capabilityName, options) {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
if (plans.length === 0) {
|
|
70
|
-
const diagnosticMessage = diagnoseMissingPlans(capsToUpdate, capabilityName);
|
|
70
|
+
const diagnosticMessage = diagnoseMissingPlans(capsToUpdate, capabilityName, targetDir);
|
|
71
71
|
if (options.json) {
|
|
72
72
|
console.log(JSON.stringify({ capabilities: [], message: diagnosticMessage }, null, 2));
|
|
73
73
|
}
|
|
@@ -160,7 +160,7 @@ function runUpdate(capabilityName, options) {
|
|
|
160
160
|
/**
|
|
161
161
|
* Diagnose why no update plans were generated and return a specific message.
|
|
162
162
|
*/
|
|
163
|
-
function diagnoseMissingPlans(capsToUpdate, requestedCap) {
|
|
163
|
+
function diagnoseMissingPlans(capsToUpdate, requestedCap, targetDir) {
|
|
164
164
|
if (capsToUpdate.length === 0) {
|
|
165
165
|
return 'No capabilities installed. Run `boop add <capability>` to install one.';
|
|
166
166
|
}
|
|
@@ -168,7 +168,7 @@ function diagnoseMissingPlans(capsToUpdate, requestedCap) {
|
|
|
168
168
|
const noPackage = [];
|
|
169
169
|
const noBoopkit = [];
|
|
170
170
|
for (const cap of capsToUpdate) {
|
|
171
|
-
const pkgDir = (0, capability_1.getPackageDir)(cap);
|
|
171
|
+
const pkgDir = (0, capability_1.getPackageDir)(cap, [targetDir]);
|
|
172
172
|
if (!pkgDir) {
|
|
173
173
|
noPackage.push(cap);
|
|
174
174
|
continue;
|
package/dist/lib/preflight.js
CHANGED
|
@@ -73,8 +73,8 @@ function planAdd(targetDir, capabilityName) {
|
|
|
73
73
|
throw new PreflightError('Pre-flight failed', checks);
|
|
74
74
|
}
|
|
75
75
|
checks.push({ name: 'project-exists', passed: true });
|
|
76
|
-
// 2. Resolve capability
|
|
77
|
-
const cap = (0, capability_1.getCapability)(capabilityName);
|
|
76
|
+
// 2. Resolve capability (search project's node_modules first, then CLI root)
|
|
77
|
+
const cap = (0, capability_1.getCapability)(capabilityName, [targetDir]);
|
|
78
78
|
if (!cap) {
|
|
79
79
|
checks.push({ name: 'capability-exists', passed: false, message: `Capability "${capabilityName}" not found` });
|
|
80
80
|
throw new PreflightError('Pre-flight failed', checks);
|
|
@@ -101,7 +101,7 @@ function planAdd(targetDir, capabilityName) {
|
|
|
101
101
|
}
|
|
102
102
|
// 5. Enumerate files that would be copied — check for conflicts
|
|
103
103
|
// Resolve from package (scaffold/ and skills/) or source tree (files/ and skills/)
|
|
104
|
-
const pkgDir = (0, capability_1.getPackageDir)(capabilityName);
|
|
104
|
+
const pkgDir = (0, capability_1.getPackageDir)(capabilityName, [targetDir]);
|
|
105
105
|
const pkgJsonPath = pkgDir ? path.join(pkgDir, 'package.json') : null;
|
|
106
106
|
const pkgJson = pkgJsonPath && fs.existsSync(pkgJsonPath)
|
|
107
107
|
? JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'))
|
package/dist/lib/update.js
CHANGED
|
@@ -69,7 +69,7 @@ function planCapabilityUpdate(targetDir, capabilityName, projectManifest) {
|
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
// Must have a package
|
|
72
|
-
const pkgDir = (0, capability_1.getPackageDir)(capabilityName);
|
|
72
|
+
const pkgDir = (0, capability_1.getPackageDir)(capabilityName, [targetDir]);
|
|
73
73
|
if (!pkgDir)
|
|
74
74
|
return null;
|
|
75
75
|
const pkgJsonPath = path.join(pkgDir, 'package.json');
|
package/package.json
CHANGED
|
@@ -26,8 +26,8 @@ As the application grows, the architecture supports additional Heroku process ty
|
|
|
26
26
|
|
|
27
27
|
## Data Layer
|
|
28
28
|
### **PostgreSQL** (Prisma ORM) - Primary data store
|
|
29
|
-
- Schema: `
|
|
30
|
-
-
|
|
29
|
+
- Schema directory: `prisma/schema/` (multi-file — Prisma auto-discovers all `.prisma` files)
|
|
30
|
+
- Generated client at `@prisma/client`
|
|
31
31
|
|
|
32
32
|
> **Context:** This project uses a hybrid relational + document model: key entities are tables with FK relationships; most attributes live in an `info` JSON column with `info_schema` and `revision` for change tracking.
|
|
33
33
|
|
|
@@ -60,6 +60,6 @@ Some services are low-level and more 'data' oriented or third-party API wrappers
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
### Data Access
|
|
63
|
-
- **Prisma ORM** (`
|
|
63
|
+
- **Prisma ORM** (`prisma/schema/`) — PostgreSQL models, migrations, and generated client
|
|
64
64
|
- **ClickHouse** (`src/ch/`) — Analytics queries via `ClickHouseService`
|
|
65
65
|
- **S3** — Object storage via `StorageService` with per-feature clients
|