compound-agent 1.2.9 → 1.2.10

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/CHANGELOG.md CHANGED
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.2.10] - 2026-02-19
13
+
14
+ ### Fixed
15
+
16
+ - **pnpm native build auto-configuration**: `ca setup` and `ca init` now detect pnpm projects (via `pnpm-lock.yaml`) and automatically add `better-sqlite3` and `node-llama-cpp` to `pnpm.onlyBuiltDependencies` in the consumer's `package.json`. Prevents the "better-sqlite3 failed to load" error that pnpm v9+ users encountered when native addon builds were silently blocked.
17
+ - **Improved error message**: `better-sqlite3` load failure now suggests running `npx ca setup` as the primary fix.
18
+
12
19
  ## [1.2.9] - 2026-02-19
13
20
 
14
21
  ### Added
@@ -527,7 +534,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
527
534
  - Vitest test suite
528
535
  - tsup build configuration
529
536
 
530
- [Unreleased]: https://github.com/Nathandela/learning_agent/compare/v1.2.9...HEAD
537
+ [Unreleased]: https://github.com/Nathandela/learning_agent/compare/v1.2.10...HEAD
538
+ [1.2.10]: https://github.com/Nathandela/learning_agent/compare/v1.2.9...v1.2.10
531
539
  [1.2.9]: https://github.com/Nathandela/learning_agent/compare/v1.2.7...v1.2.9
532
540
  [1.2.7]: https://github.com/Nathandela/learning_agent/compare/v1.2.6...v1.2.7
533
541
  [1.2.6]: https://github.com/Nathandela/learning_agent/compare/v1.2.5...v1.2.6
package/README.md CHANGED
@@ -81,7 +81,9 @@ npx ca setup --skip-model
81
81
 
82
82
  ### pnpm Users
83
83
 
84
- pnpm v9+ blocks native addon builds by default. Add to your `package.json`:
84
+ pnpm v9+ blocks native addon builds by default. Running `npx ca setup` automatically detects pnpm and adds the required config to your `package.json`.
85
+
86
+ If you prefer to configure manually, add to your `package.json`:
85
87
 
86
88
  ```json
87
89
  {
package/dist/cli.js CHANGED
@@ -333,11 +333,7 @@ function ensureSqliteAvailable() {
333
333
  checked = true;
334
334
  } catch (cause) {
335
335
  throw new Error(
336
- `better-sqlite3 failed to load.
337
- If using pnpm, add to your project's package.json:
338
- "pnpm": { "onlyBuiltDependencies": ["better-sqlite3"] }
339
- Then run: pnpm install && pnpm rebuild better-sqlite3
340
- For npm/yarn, run: npm rebuild better-sqlite3`,
336
+ 'better-sqlite3 failed to load.\nRun: npx ca setup (auto-configures pnpm native builds)\nOr manually add to your package.json:\n "pnpm": { "onlyBuiltDependencies": ["better-sqlite3", "node-llama-cpp"] }\nThen run: pnpm install && pnpm rebuild better-sqlite3\nFor npm/yarn, run: npm rebuild better-sqlite3',
341
337
  { cause }
342
338
  );
343
339
  }
@@ -4193,6 +4189,62 @@ async function installAgentRoleSkills(repoRoot) {
4193
4189
  }
4194
4190
  return created;
4195
4191
  }
4192
+ var REQUIRED_BUILD_DEPS = ["better-sqlite3", "node-llama-cpp"];
4193
+ async function ensurePnpmBuildConfig(repoRoot) {
4194
+ const lockPath = join(repoRoot, "pnpm-lock.yaml");
4195
+ const hasLockfile = existsSync(lockPath);
4196
+ const pkgPath = join(repoRoot, "package.json");
4197
+ const hasPkgJson = existsSync(pkgPath);
4198
+ if (!hasLockfile) {
4199
+ if (!hasPkgJson) {
4200
+ return { isPnpm: false, alreadyConfigured: false, added: [] };
4201
+ }
4202
+ const pkg2 = readPkgJsonSafe(pkgPath, await readFile(pkgPath, "utf-8"));
4203
+ if (pkg2 === null) return { isPnpm: false, alreadyConfigured: false, added: [] };
4204
+ const pm = typeof pkg2.packageManager === "string" ? pkg2.packageManager : "";
4205
+ if (!pm.startsWith("pnpm")) {
4206
+ return { isPnpm: false, alreadyConfigured: false, added: [] };
4207
+ }
4208
+ return mergePnpmConfig(pkgPath, pkg2);
4209
+ }
4210
+ if (!hasPkgJson) {
4211
+ return { isPnpm: true, alreadyConfigured: false, added: [] };
4212
+ }
4213
+ const pkg = readPkgJsonSafe(pkgPath, await readFile(pkgPath, "utf-8"));
4214
+ if (pkg === null) return { isPnpm: true, alreadyConfigured: false, added: [] };
4215
+ return mergePnpmConfig(pkgPath, pkg);
4216
+ }
4217
+ function readPkgJsonSafe(pkgPath, raw) {
4218
+ try {
4219
+ return JSON.parse(raw);
4220
+ } catch {
4221
+ console.error(`Warning: Could not parse ${pkgPath} \u2014 skipping pnpm build config.
4222
+ Fix the JSON syntax and re-run setup.`);
4223
+ return null;
4224
+ }
4225
+ }
4226
+ async function mergePnpmConfig(pkgPath, pkg) {
4227
+ if (!pkg.pnpm || typeof pkg.pnpm !== "object") {
4228
+ pkg.pnpm = {};
4229
+ }
4230
+ const pnpmConfig = pkg.pnpm;
4231
+ if (!Array.isArray(pnpmConfig.onlyBuiltDependencies)) {
4232
+ pnpmConfig.onlyBuiltDependencies = [];
4233
+ }
4234
+ const existing = pnpmConfig.onlyBuiltDependencies;
4235
+ const added = [];
4236
+ for (const dep of REQUIRED_BUILD_DEPS) {
4237
+ if (!existing.includes(dep)) {
4238
+ existing.push(dep);
4239
+ added.push(dep);
4240
+ }
4241
+ }
4242
+ if (added.length === 0) {
4243
+ return { isPnpm: true, alreadyConfigured: true, added: [] };
4244
+ }
4245
+ await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
4246
+ return { isPnpm: true, alreadyConfigured: false, added };
4247
+ }
4196
4248
 
4197
4249
  // src/setup/all.ts
4198
4250
  async function ensureLessonsDirectory(repoRoot) {
@@ -4221,6 +4273,7 @@ async function configureClaudeSettings() {
4221
4273
  }
4222
4274
  async function runSetup(options) {
4223
4275
  const repoRoot = getRepoRoot();
4276
+ const pnpmConfig = await ensurePnpmBuildConfig(repoRoot);
4224
4277
  const lessonsDir = await ensureLessonsDirectory(repoRoot);
4225
4278
  const agentsMdUpdated = await updateAgentsMd(repoRoot);
4226
4279
  await ensureClaudeMdReference(repoRoot);
@@ -4253,7 +4306,8 @@ async function runSetup(options) {
4253
4306
  agentsMd: agentsMdUpdated,
4254
4307
  hooks,
4255
4308
  gitHooks,
4256
- model: modelStatus
4309
+ model: modelStatus,
4310
+ pnpmConfig
4257
4311
  };
4258
4312
  }
4259
4313
  async function runUninstall(repoRoot, dryRun) {
@@ -4412,6 +4466,14 @@ function printSetupGitHooksStatus(gitHooks) {
4412
4466
  }
4413
4467
  console.log(" Git hooks: Already configured");
4414
4468
  }
4469
+ function printPnpmConfigStatus(result) {
4470
+ if (!result.isPnpm) return;
4471
+ if (result.alreadyConfigured) {
4472
+ console.log(" pnpm config: onlyBuiltDependencies already configured");
4473
+ } else if (result.added.length > 0) {
4474
+ console.log(` pnpm config: Added onlyBuiltDependencies [${result.added.join(", ")}]`);
4475
+ }
4476
+ }
4415
4477
  function registerSetupAllCommand(setupCommand) {
4416
4478
  setupCommand.description("One-shot setup: init + hooks + model");
4417
4479
  setupCommand.command("all", { isDefault: true }).description("Run full setup (default)").option("--skip-model", "Skip embedding model download").option("--skip-hooks", "Skip git hooks installation").option("--uninstall", "Remove all generated files and configuration").option("--update", "Regenerate files (preserves user customizations)").option("--status", "Show installation status").option("--dry-run", "Show what would change without changing").action(async (options) => {
@@ -4453,6 +4515,7 @@ function registerSetupAllCommand(setupCommand) {
4453
4515
  console.log(` AGENTS.md: ${result.agentsMd ? "Updated" : "Already configured"}`);
4454
4516
  console.log(` Claude hooks: ${result.hooks ? "Installed" : "Already configured"}`);
4455
4517
  printSetupGitHooksStatus(result.gitHooks);
4518
+ printPnpmConfigStatus(result.pnpmConfig);
4456
4519
  switch (result.model) {
4457
4520
  case "skipped":
4458
4521
  console.log(" Model: Skipped (--skip-model)");
@@ -4689,6 +4752,7 @@ async function createIndexFile(repoRoot) {
4689
4752
  async function initAction(cmd, options) {
4690
4753
  const repoRoot = getRepoRoot();
4691
4754
  const { quiet } = getGlobalOpts(cmd);
4755
+ const pnpmConfig = await ensurePnpmBuildConfig(repoRoot);
4692
4756
  await createLessonsDirectory(repoRoot);
4693
4757
  await createIndexFile(repoRoot);
4694
4758
  const lessonsDir = dirname(join(repoRoot, LESSONS_PATH));
@@ -4723,7 +4787,8 @@ async function initAction(cmd, options) {
4723
4787
  agentsMd: agentsMdUpdated,
4724
4788
  hooks: hooksChanged,
4725
4789
  hookStatus: hookResult?.status ?? "skipped",
4726
- claudeHooks: claudeHooksInstalled
4790
+ claudeHooks: claudeHooksInstalled,
4791
+ pnpmConfig: pnpmConfig.isPnpm ? { added: pnpmConfig.added, alreadyConfigured: pnpmConfig.alreadyConfigured } : null
4727
4792
  }));
4728
4793
  return;
4729
4794
  }
@@ -4733,6 +4798,7 @@ async function initAction(cmd, options) {
4733
4798
  printAgentsMdStatus(agentsMdUpdated, options.skipAgents);
4734
4799
  printHookStatus(hookResult, options.skipHooks);
4735
4800
  printClaudeHooksStatus(claudeHooksResult, options.skipClaude);
4801
+ printPnpmConfigStatus2(pnpmConfig);
4736
4802
  }
4737
4803
  function printAgentsMdStatus(updated, skipped) {
4738
4804
  if (updated) {
@@ -4767,6 +4833,14 @@ function printClaudeHooksStatus(result, skipped) {
4767
4833
  console.log(` Claude hooks: Error - ${result.error}`);
4768
4834
  }
4769
4835
  }
4836
+ function printPnpmConfigStatus2(result) {
4837
+ if (!result.isPnpm) return;
4838
+ if (result.alreadyConfigured) {
4839
+ console.log(" pnpm config: onlyBuiltDependencies already configured");
4840
+ } else if (result.added.length > 0) {
4841
+ console.log(` pnpm config: Added onlyBuiltDependencies [${result.added.join(", ")}]`);
4842
+ }
4843
+ }
4770
4844
  function registerInitCommand(program2) {
4771
4845
  program2.command("init").description("Initialize compound-agent in this repository").option("--skip-agents", "Skip AGENTS.md modification").option("--skip-hooks", "Skip git hooks installation").option("--skip-claude", "Skip Claude Code hooks installation").option("--json", "Output result as JSON").action(async function(options) {
4772
4846
  await initAction(this, options);