quilltap 3.3.0-dev → 3.3.0-dev.39

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
@@ -89,6 +89,23 @@ Quilltap stores its database, files, and logs in a platform-specific directory:
89
89
 
90
90
  Override with `--data-dir` or the `QUILLTAP_DATA_DIR` environment variable.
91
91
 
92
+ ## Theme Management
93
+
94
+ The CLI includes theme management commands:
95
+
96
+ ```bash
97
+ quilltap themes list # List all installed themes
98
+ quilltap themes install my.qtap-theme # Install a .qtap-theme bundle
99
+ quilltap themes validate my.qtap-theme # Validate a bundle
100
+ quilltap themes uninstall my-theme # Uninstall a bundle theme
101
+ quilltap themes export earl-grey # Export any theme as a bundle
102
+ quilltap themes create sunset # Scaffold a new theme
103
+ quilltap themes search "dark" # Search registries
104
+ quilltap themes update # Check for theme updates
105
+ quilltap themes registry list # List configured registries
106
+ quilltap themes registry add <url> # Add a registry source
107
+ ```
108
+
92
109
  ## Requirements
93
110
 
94
111
  - Node.js 18 or later
package/bin/quilltap.js CHANGED
@@ -57,6 +57,7 @@ function parseArgs(argv) {
57
57
  opts.help = true;
58
58
  break;
59
59
  default:
60
+ // Allow subcommands to pass through (they're handled before parseArgs)
60
61
  console.error(`Unknown argument: ${args[i]}`);
61
62
  console.error('Run "quilltap --help" for usage information.');
62
63
  process.exit(1);
@@ -73,6 +74,10 @@ Quilltap - Self-hosted AI workspace
73
74
 
74
75
  Usage: quilltap [options]
75
76
 
77
+ Subcommands:
78
+ db Query encrypted databases
79
+ themes Manage theme bundles
80
+
76
81
  Options:
77
82
  -p, --port <number> Port to listen on (default: 3000)
78
83
  -d, --data-dir <path> Data directory (default: platform-specific)
@@ -131,20 +136,21 @@ function resolveModuleDir(moduleName) {
131
136
  function ensureNativeModules() {
132
137
  const needsRebuild = [];
133
138
 
134
- // Check better-sqlite3: it lazy-loads the native .node binary only when you
135
- // create a Database, so a bare require('better-sqlite3') always succeeds.
139
+ // Check better-sqlite3-multiple-ciphers (provides SQLCipher encryption support).
140
+ // The main app depends on this via an npm alias as 'better-sqlite3', so we must
141
+ // ensure the SQLCipher-capable version is available and link it as 'better-sqlite3'.
136
142
  // We must load the native binding directly to detect NODE_MODULE_VERSION mismatches.
137
- // Use require.resolve to find it regardless of npm hoisting.
138
143
  try {
139
- const modDir = resolveModuleDir('better-sqlite3');
144
+ const modDir = resolveModuleDir('better-sqlite3-multiple-ciphers')
145
+ || resolveModuleDir('better-sqlite3');
140
146
  if (!modDir) throw Object.assign(new Error('not found'), { code: 'MODULE_NOT_FOUND' });
141
147
  const bindingsPath = path.join(modDir, 'build', 'Release', 'better_sqlite3.node');
142
148
  require(bindingsPath);
143
149
  } catch (err) {
144
150
  if (err.message && err.message.includes('NODE_MODULE_VERSION')) {
145
- needsRebuild.push('better-sqlite3');
151
+ needsRebuild.push('better-sqlite3-multiple-ciphers');
146
152
  } else if (err.code === 'MODULE_NOT_FOUND') {
147
- needsRebuild.push('better-sqlite3');
153
+ needsRebuild.push('better-sqlite3-multiple-ciphers');
148
154
  }
149
155
  }
150
156
 
@@ -223,8 +229,10 @@ function linkNativeModules(standaloneDir) {
223
229
  }
224
230
  }
225
231
 
226
- // Link better-sqlite3
227
- const betterSqlite3Dir = resolveModuleDir('better-sqlite3');
232
+ // Link better-sqlite3-multiple-ciphers as 'better-sqlite3' (the app imports it
233
+ // via npm alias). Prefer the SQLCipher build; fall back to plain better-sqlite3.
234
+ const betterSqlite3Dir = resolveModuleDir('better-sqlite3-multiple-ciphers')
235
+ || resolveModuleDir('better-sqlite3');
228
236
  linkModule('better-sqlite3', betterSqlite3Dir);
229
237
 
230
238
  // Link sharp
@@ -514,8 +522,13 @@ async function dbCommand(args) {
514
522
  process.exit(1);
515
523
  }
516
524
 
517
- // Open database
518
- const Database = require('better-sqlite3');
525
+ // Open database — prefer SQLCipher-capable build
526
+ let Database;
527
+ try {
528
+ Database = require('better-sqlite3-multiple-ciphers');
529
+ } catch {
530
+ Database = require('better-sqlite3');
531
+ }
519
532
  const db = new Database(dbPath, { readonly: !repl });
520
533
 
521
534
  if (pepper) {
@@ -605,6 +618,9 @@ async function dbCommand(args) {
605
618
  // Route to subcommand or main
606
619
  if (process.argv[2] === 'db') {
607
620
  dbCommand(process.argv.slice(3));
621
+ } else if (process.argv[2] === 'themes') {
622
+ const { themesCommand } = require('../lib/theme-commands');
623
+ themesCommand(process.argv.slice(3));
608
624
  } else {
609
625
  main();
610
626
  }