compound-agent 1.4.1 → 1.4.3

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,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.4.3] - 2026-02-23
13
+
14
+ ### Fixed
15
+
16
+ - **Setup reports success when SQLite is broken**: `npx ca setup` now verifies that `better-sqlite3` actually loads after configuring `pnpm.onlyBuiltDependencies`, and auto-rebuilds if needed (escalates from `pnpm rebuild` to `pnpm install + rebuild`)
17
+ - **Misleading error message**: `ensureSqliteAvailable()` no longer suggests "Run: npx ca setup" (which didn't fix the problem); now provides per-package-manager rebuild instructions and build tools hint
18
+
19
+ ### Added
20
+
21
+ - **SQLite health check in `ca doctor`**: New check reports `[FAIL]` with fix hint when `better-sqlite3` cannot load
22
+ - **SQLite status in `ca setup --status`**: Shows "OK" or "not available" alongside other status checks
23
+ - **`resetSqliteAvailability()` export**: Allows re-probing SQLite after native module rebuild
24
+
25
+ ## [1.4.2] - 2026-02-23
26
+
27
+ ### Fixed
28
+
29
+ - **Banner audio crash on headless Linux**: Async `ENOENT` error from missing `aplay` no longer crashes `ca setup --update`
30
+ - **PowerShell path injection on Windows**: Temp paths containing apostrophes no longer break or inject commands in `banner-audio.ts`
31
+ - **Banner audio test coverage**: Rewrote tests with proper mock isolation (`vi.spyOn` + file-scope `vi.mock`), covering async ENOENT, sync throw, stop() idempotency, and normal exit cleanup
32
+
12
33
  ## [1.4.1] - 2026-02-22
13
34
 
14
35
  ### Changed
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ function ensureSqliteAvailable() {
33
33
  checked = true;
34
34
  } catch (cause) {
35
35
  throw new Error(
36
- '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',
36
+ 'better-sqlite3 failed to load.\nFor pnpm projects:\n 1. Ensure package.json has: "pnpm": { "onlyBuiltDependencies": ["better-sqlite3"] }\n 2. Run: pnpm install && pnpm rebuild better-sqlite3\nFor npm/yarn projects:\n Run: npm rebuild better-sqlite3\nIf the error persists, check that build tools (python3, make, g++) are installed.',
37
37
  { cause }
38
38
  );
39
39
  }
@@ -42,6 +42,10 @@ function getDatabaseConstructor() {
42
42
  ensureSqliteAvailable();
43
43
  return DatabaseConstructor;
44
44
  }
45
+ function resetSqliteAvailability() {
46
+ checked = false;
47
+ DatabaseConstructor = null;
48
+ }
45
49
  var require2, checked, DatabaseConstructor;
46
50
  var init_availability = __esm({
47
51
  "src/memory/storage/sqlite/availability.ts"() {
@@ -1086,6 +1090,9 @@ async function syncIfNeeded(repoRoot, options = {}) {
1086
1090
  return false;
1087
1091
  }
1088
1092
 
1093
+ // src/memory/storage/sqlite/index.ts
1094
+ init_availability();
1095
+
1089
1096
  // src/memory/search/hybrid.ts
1090
1097
  var DEFAULT_VECTOR_WEIGHT = 0.7;
1091
1098
  var DEFAULT_TEXT_WEIGHT = 0.3;
@@ -1957,7 +1964,7 @@ function spawnPlayer(filePath) {
1957
1964
  case "win32":
1958
1965
  return spawn("powershell", [
1959
1966
  "-c",
1960
- `(New-Object Media.SoundPlayer '${filePath}').PlaySync()`
1967
+ `(New-Object Media.SoundPlayer "${filePath.replace(/"/g, '`"')}").PlaySync()`
1961
1968
  ], { stdio: "ignore", detached: true });
1962
1969
  default:
1963
1970
  return null;
@@ -1990,6 +1997,12 @@ function playBannerAudio() {
1990
1997
  } catch {
1991
1998
  }
1992
1999
  };
2000
+ proc.on("error", () => {
2001
+ try {
2002
+ unlinkSync(tmpPath);
2003
+ } catch {
2004
+ }
2005
+ });
1993
2006
  proc.on("exit", () => {
1994
2007
  try {
1995
2008
  unlinkSync(tmpPath);
@@ -3611,6 +3624,19 @@ function printPnpmConfigStatus(result) {
3611
3624
  console.log(` pnpm config: Added onlyBuiltDependencies [${result.added.join(", ")}]`);
3612
3625
  }
3613
3626
  }
3627
+ var SQLITE_STATUS_MSG = {
3628
+ already_ok: "OK",
3629
+ rebuilt: "OK (rebuilt native module)",
3630
+ installed_and_rebuilt: "OK (installed + rebuilt native module)",
3631
+ failed: "FAILED"
3632
+ };
3633
+ function printSqliteStatus(result) {
3634
+ const msg = SQLITE_STATUS_MSG[result.action];
3635
+ console.log(` SQLite: ${msg}`);
3636
+ if (result.error) {
3637
+ console.log(` ${result.error}`);
3638
+ }
3639
+ }
3614
3640
  function printBeadsFullStatus(check) {
3615
3641
  console.log(` Beads CLI: ${check.cliAvailable ? "OK" : "not found"}`);
3616
3642
  if (check.cliAvailable) {
@@ -3645,6 +3671,13 @@ async function runStatus(repoRoot) {
3645
3671
  } catch {
3646
3672
  }
3647
3673
  console.log(` Hooks: ${hooksInstalled ? "installed" : "not installed"}`);
3674
+ let sqliteOk = false;
3675
+ try {
3676
+ ensureSqliteAvailable();
3677
+ sqliteOk = true;
3678
+ } catch {
3679
+ }
3680
+ console.log(` SQLite: ${sqliteOk ? "OK" : "not available (run: pnpm rebuild better-sqlite3)"}`);
3648
3681
  const fullBeads = runFullBeadsCheck(repoRoot);
3649
3682
  printBeadsFullStatus(fullBeads);
3650
3683
  const scope = checkUserScope(repoRoot);
@@ -6796,6 +6829,60 @@ async function mergePnpmConfig(pkgPath, pkg) {
6796
6829
  await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
6797
6830
  return { isPnpm: true, alreadyConfigured: false, added };
6798
6831
  }
6832
+ function trySqliteLoad() {
6833
+ try {
6834
+ ensureSqliteAvailable();
6835
+ return true;
6836
+ } catch {
6837
+ return false;
6838
+ }
6839
+ }
6840
+ function verifySqlite(repoRoot, pnpmConfig) {
6841
+ if (trySqliteLoad()) {
6842
+ return { available: true, action: "already_ok" };
6843
+ }
6844
+ if (!pnpmConfig.isPnpm) {
6845
+ return {
6846
+ available: false,
6847
+ action: "failed",
6848
+ error: "better-sqlite3 failed to load. Run: npm rebuild better-sqlite3"
6849
+ };
6850
+ }
6851
+ try {
6852
+ execFileSync("pnpm", ["rebuild", "better-sqlite3"], {
6853
+ cwd: repoRoot,
6854
+ stdio: "pipe",
6855
+ timeout: 6e4
6856
+ });
6857
+ } catch {
6858
+ }
6859
+ resetSqliteAvailability();
6860
+ if (trySqliteLoad()) {
6861
+ return { available: true, action: "rebuilt" };
6862
+ }
6863
+ try {
6864
+ execFileSync("pnpm", ["install"], {
6865
+ cwd: repoRoot,
6866
+ stdio: "pipe",
6867
+ timeout: 12e4
6868
+ });
6869
+ execFileSync("pnpm", ["rebuild", "better-sqlite3"], {
6870
+ cwd: repoRoot,
6871
+ stdio: "pipe",
6872
+ timeout: 6e4
6873
+ });
6874
+ } catch {
6875
+ }
6876
+ resetSqliteAvailability();
6877
+ if (trySqliteLoad()) {
6878
+ return { available: true, action: "installed_and_rebuilt" };
6879
+ }
6880
+ return {
6881
+ available: false,
6882
+ action: "failed",
6883
+ error: "Auto-rebuild failed. Run manually: pnpm install && pnpm rebuild better-sqlite3"
6884
+ };
6885
+ }
6799
6886
  async function runUninstall(repoRoot, dryRun) {
6800
6887
  const actions = [];
6801
6888
  const dirsToRemove = [
@@ -6992,6 +7079,7 @@ async function runSetup(options) {
6992
7079
  upgrade = await runUpgrade(repoRoot);
6993
7080
  }
6994
7081
  const pnpmConfig = await ensurePnpmBuildConfig(repoRoot);
7082
+ const sqlite = verifySqlite(repoRoot, pnpmConfig);
6995
7083
  const lessonsDir = await ensureLessonsDirectory(repoRoot);
6996
7084
  const agentsMdUpdated = await updateAgentsMd(repoRoot);
6997
7085
  await ensureClaudeMdReference(repoRoot);
@@ -7034,6 +7122,7 @@ async function runSetup(options) {
7034
7122
  postCommitHook,
7035
7123
  model: modelStatus,
7036
7124
  pnpmConfig,
7125
+ sqlite,
7037
7126
  beads,
7038
7127
  scope,
7039
7128
  upgrade,
@@ -7135,6 +7224,7 @@ async function printSetupResult(result, quiet, repoRoot) {
7135
7224
  printSetupGitHooksStatus(result.gitHooks);
7136
7225
  printPostCommitHookStatus(result.postCommitHook);
7137
7226
  printPnpmConfigStatus(result.pnpmConfig);
7227
+ printSqliteStatus(result.sqlite);
7138
7228
  printGitignoreStatus(result.gitignore);
7139
7229
  console.log(` Model: ${MODEL_STATUS_MSG[result.model]}`);
7140
7230
  const fullBeads = runFullBeadsCheck(repoRoot);
@@ -7786,6 +7876,13 @@ async function runDoctor(repoRoot) {
7786
7876
  } catch {
7787
7877
  }
7788
7878
  checks.push(modelOk ? { name: "Embedding model", status: "pass" } : { name: "Embedding model", status: "warn", fix: "Run: npx ca download-model" });
7879
+ let sqliteOk = false;
7880
+ try {
7881
+ ensureSqliteAvailable();
7882
+ sqliteOk = true;
7883
+ } catch {
7884
+ }
7885
+ checks.push(sqliteOk ? { name: "SQLite (better-sqlite3)", status: "pass" } : { name: "SQLite (better-sqlite3)", status: "fail", fix: "Run: pnpm rebuild better-sqlite3 (or npm rebuild better-sqlite3)" });
7789
7886
  const beadsResult = checkBeadsAvailable();
7790
7887
  checks.push(beadsResult.available ? { name: "Beads CLI", status: "pass" } : { name: "Beads CLI", status: "warn", fix: "Install beads: https://github.com/Nathandela/beads" });
7791
7888
  checks.push(checkGitignoreHealth(repoRoot) ? { name: ".gitignore health", status: "pass" } : { name: ".gitignore health", status: "warn", fix: "Run: npx ca setup --update" });
@@ -8589,30 +8686,32 @@ function registerVerifyGatesCommand(program2) {
8589
8686
  }
8590
8687
 
8591
8688
  // src/changelog-data.ts
8592
- var CHANGELOG_RECENT = `## [1.4.1] - 2026-02-22
8689
+ var CHANGELOG_RECENT = `## [1.4.3] - 2026-02-23
8593
8690
 
8594
- ### Changed
8691
+ ### Fixed
8595
8692
 
8596
- - **Broader retrieval messaging**: \`ca search\` and \`ca knowledge\` descriptions in prime output and AGENTS.md now encourage general-purpose use beyond mandatory architectural triggers
8693
+ - **Setup reports success when SQLite is broken**: \`npx ca setup\` now verifies that \`better-sqlite3\` actually loads after configuring \`pnpm.onlyBuiltDependencies\`, and auto-rebuilds if needed (escalates from \`pnpm rebuild\` to \`pnpm install + rebuild\`)
8694
+ - **Misleading error message**: \`ensureSqliteAvailable()\` no longer suggests "Run: npx ca setup" (which didn't fix the problem); now provides per-package-manager rebuild instructions and build tools hint
8597
8695
 
8598
- ## [1.4.0] - 2026-02-22
8696
+ ### Added
8599
8697
 
8600
- ### Fixed
8698
+ - **SQLite health check in \`ca doctor\`**: New check reports \`[FAIL]\` with fix hint when \`better-sqlite3\` cannot load
8699
+ - **SQLite status in \`ca setup --status\`**: Shows "OK" or "not available" alongside other status checks
8700
+ - **\`resetSqliteAvailability()\` export**: Allows re-probing SQLite after native module rebuild
8601
8701
 
8602
- - **Plugin manifest**: Corrected repository URL from \`compound_agent\` to \`learning_agent\`
8702
+ ## [1.4.2] - 2026-02-23
8603
8703
 
8604
- ### Changed
8704
+ ### Fixed
8605
8705
 
8606
- - **Version consolidation**: Roll-up release of v1.3.7\u2013v1.3.9 production readiness fixes (test pipeline hardening, data integrity, two-phase vector search, FTS5 sanitization)
8706
+ - **Banner audio crash on headless Linux**: Async \`ENOENT\` error from missing \`aplay\` no longer crashes \`ca setup --update\`
8707
+ - **PowerShell path injection on Windows**: Temp paths containing apostrophes no longer break or inject commands in \`banner-audio.ts\`
8708
+ - **Banner audio test coverage**: Rewrote tests with proper mock isolation (\`vi.spyOn\` + file-scope \`vi.mock\`), covering async ENOENT, sync throw, stop() idempotency, and normal exit cleanup
8607
8709
 
8608
- ## [1.3.9] - 2026-02-22
8710
+ ## [1.4.1] - 2026-02-22
8609
8711
 
8610
- ### Fixed
8712
+ ### Changed
8611
8713
 
8612
- - **Integration test pipeline reliability**: Moved \`pnpm build\` from vitest globalSetup to npm script pre-step, eliminating EPERM errors from tsx/IPC conflicts inside vitest's process
8613
- - **Fail-fast globalSetup**: Missing \`dist/cli.js\` now throws a clear error instead of cascading 68+ test failures
8614
- - **Integration pool isolation**: Changed from \`threads\` to \`forks\` for integration tests \u2014 proper process isolation for subprocess-spawning tests
8615
- - **Timeout safety net**: Added \`testTimeout: 30_000\` to fallback vitest.config.ts, preventing 5s default under edge conditions`;
8714
+ - **Broader retrieval messaging**: \`ca search\` and \`ca knowledge\` descriptions in prime output and AGENTS.md now encourage general-purpose use beyond mandatory architectural triggers`;
8616
8715
 
8617
8716
  // src/commands/about.ts
8618
8717
  function registerAboutCommand(program2) {