quilltap 4.10.0-dev.59 → 4.10.0-dev.61

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.
@@ -478,6 +478,11 @@ function cmdMessages(args, ctx) {
478
478
  params.push(last);
479
479
  const rows = db.prepare(sql).all(...params).reverse(); // oldest first
480
480
 
481
+ // `content` may be a brotli BLOB (see lib/text-codec.js). Decode before
482
+ // anything prints or JSON-serializes it — a raw BLOB prints as binary and
483
+ // JSON.stringify turns it into a byte array.
484
+ for (const r of rows) r.content = decodeText(r.content);
485
+
481
486
  if (json) return printJson({ chat, total: totalRow.n, returned: rows.length, messages: rows });
482
487
 
483
488
  console.log(`Chat: ${chat.title} (${chat.id}) — showing ${rows.length} of ${totalRow.n} matching messages`);
@@ -558,6 +563,13 @@ function cmdMessage(args, ctx) {
558
563
  try {
559
564
  const row = db.prepare('SELECT * FROM chat_messages WHERE id = ?').get(id);
560
565
  if (!row) throw new Error(`No chat_message with id ${id}`);
566
+
567
+ // The four large text columns may be brotli BLOBs (see lib/text-codec.js).
568
+ // Decode before anything prints or JSON-serializes them.
569
+ for (const col of ['content', 'opaqueContent', 'description', 'context']) {
570
+ if (col in row) row[col] = decodeText(row[col]);
571
+ }
572
+
561
573
  if (json) return printJson(row);
562
574
 
563
575
  printRecord(`Message ${row.id}`, {
package/lib/db-helpers.js CHANGED
@@ -202,8 +202,11 @@ function openEncryptedDb(dbPath, pepper, { readonly = true, friendlyName = 'data
202
202
  'The database may be encrypted with a different key, or the .dbkey file may be missing.');
203
203
  }
204
204
 
205
- // Compressed text columns (llm_logs.request/response and friends) are
206
- // BLOBs; qt_text() lets raw SQL and the repl read inside them.
205
+ // Compressed text columns (llm_logs.request/response, chat_messages.content
206
+ // and friends) are BLOBs; qt_text() lets raw SQL and the repl read inside
207
+ // them. It is also REQUIRED for any --write that touches chat_messages: the
208
+ // message search triggers call it, so a connection without it fails the
209
+ // write loudly rather than letting the index drift.
207
210
  try {
208
211
  registerTextCodecFunction(db);
209
212
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quilltap",
3
- "version": "4.10.0-dev.59",
3
+ "version": "4.10.0-dev.61",
4
4
  "description": "Self-hosted AI workspace for writers, worldbuilders, and roleplayers. Run with npx quilltap.",
5
5
  "author": {
6
6
  "name": "Charles Sebold",