@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 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
- npm run dev
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.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.0",
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",
@@ -10,7 +10,7 @@ export interface LoopOptions {
10
10
  pollInterval?: string;
11
11
  model?: string;
12
12
  perIssueBranch?: boolean;
13
- noBranch?: boolean;
13
+ branch?: boolean;
14
14
  features?: boolean;
15
15
  skipPerms?: boolean;
16
16
  bare?: boolean;
@@ -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.noBranch || false;
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;
@@ -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;
@@ -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;
@@ -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'))
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boopkit/cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "CLI tool to scaffold new projects from boop profiles and capabilities",
5
5
  "main": "dist/cli.js",
6
6
  "workspaces": [
@@ -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: `src/db/prisma/schema.prisma`
30
- - Models in `src/db/models/`, Generated client at `@prisma/*`
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** (`src/db/prisma/`) — PostgreSQL models, migrations, and generated client
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