You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Suppress informational log messages in TUI mode (#26)
## Problem
All lore log messages used `console.error()` which writes to stderr. The
TUI renders stderr as red error text, making routine status messages
look like alarming errors to users:

Examples seen in the wild:
- `[lore] incremental distillation: 54 undistilled messages in
ses_3502bf6e2ffe`
- `[lore] pruned 9 oversized knowledge entries (confidence set to 0)`
## Solution
Added `src/log.ts` with three levels:
| Level | Visibility | Use case |
|-------|-----------|----------|
| `log.info()` | Suppressed by default | Routine operations —
distillation, pruning, consolidation, imports |
| `log.warn()` | Suppressed by default | Non-actionable oddities —
dropping trailing messages |
| `log.error()` | Always visible | Real failures — catch blocks where
something actually broke |
Set `LORE_DEBUG=1` to see all messages when debugging the plugin.
## Changes
- **New:** `src/log.ts` — lightweight logger with LORE\_DEBUG gating
- **`src/index.ts`** — 18 `console.error` calls replaced with
appropriate log level
- **`src/distillation.ts`** — 1 `console.error` → `log.info`
***Stuck compaction loops leave orphaned user+assistant message pairs in DB**: When OpenCode compaction overflows, it creates paired user+assistant messages per retry (assistant has error.name:'ContextOverflowError', mode:'compaction'). These accumulate and worsen the session. Recovery: find last good assistant message (has tokens, no error), delete all messages after it from both \`message\` and \`part\` tables. Use json\_extract(data, '$.error.name') to identify compaction debris.
***Lore test suite uses live DB — no test isolation for db.test.ts**: The lore test suite (test/db.test.ts, test/ltm.test.ts) uses the live DB at ~/.local/share/opencode-lore/lore.db — no LORE\_DB\_PATH override. Test fixtures create entries with 019c9026-\* UUIDs that persist and leak into AGENTS.md exports. Known leaked entries: 'Kubernetes deployment pattern', 'TypeScript strict mode caveat', 'React useState async pitfall', 'Fine entry'. These require periodic manual cleanup from the DB. Fix needed: set LORE\_DB\_PATH to a temp file in tests.
31
+
***Lore test suite uses live DB — no test isolation for db.test.ts**: Lore test suite (test/db.test.ts, test/ltm.test.ts) uses the live DB at ~/.local/share/opencode-lore/lore.db — no LORE\_DB\_PATH override. Test fixtures create entries with 019c9026-\* UUIDs that persist and leak into AGENTS.md exports. Known leaked entries: 'Kubernetes deployment pattern', 'TypeScript strict mode caveat', 'React useState async pitfall', 'Fine entry'. Require periodic manual cleanup. Fix needed: LORE\_DB\_PATH temp file in tests.
32
32
33
-
### Preference
33
+
### Pattern
34
34
35
-
<!-- lore:019ca19d-fc02-7657-b2e9-7764658c01a5-->
36
-
***Code style**: User prefers no backwards-compat shims — fix callers directly. Prefer explicit error handling over silent failures. Derive thresholds from existing constants rather than hardcoding magic numbers (e.g., use \`raw.length <= COL\_COUNT\` instead of \`n < 10\_000\`). In CI, define shared env vars at workflow level, not per-job.
35
+
<!-- lore:019cb050-ef48-7cbe-8e58-802f17c34591-->
36
+
***Lore logging: LORE\_DEBUG gating for info/warn, always-on for errors**: src/log.ts provides three levels: log.info() and log.warn() are suppressed unless LORE\_DEBUG=1 or LORE\_DEBUG=true; log.error() always emits. All write to stderr with \[lore] prefix. This exists because OpenCode TUI renders all stderr as red error text — routine status messages (distillation counts, pruning stats, consolidation) were alarming users. Rule: use log.info() for successful operations and status, log.warn() for non-actionable oddities (e.g. dropping trailing messages), log.error() only in catch blocks for real failures. Never use console.error directly in plugin source files.
***Always dry-run before bulk DB deletes**: Never execute bulk DELETE/destructive operations without first running the equivalent SELECT to verify row count and inspect affected rows. A hardcoded timestamp off by one year caused deletion of all 1638 messages + 5927 parts instead of 5 debris rows. Pattern: (1) SELECT with same WHERE, (2) verify count, (3) then DELETE. Applies to any destructive op — DB mutations, git reset, file deletion.
***Code style**: User prefers no backwards-compat shims — fix callers directly. Prefer explicit error handling over silent failures. Derive thresholds from existing constants rather than hardcoding magic numbers (e.g., use \`raw.length <= COL\_COUNT\` instead of \`n < 10\_000\`). In CI, define shared env vars at workflow level, not per-job.
0 commit comments