ccrecall 0.0.5 → 0.0.6
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 +8 -4
- package/package.json +1 -1
- package/src/db.ts +27 -1
package/README.md
CHANGED
|
@@ -63,10 +63,14 @@ bun src/index.ts stats
|
|
|
63
63
|
|
|
64
64
|
### Commands
|
|
65
65
|
|
|
66
|
-
| Command
|
|
67
|
-
|
|
|
68
|
-
| `sync`
|
|
69
|
-
| `stats`
|
|
66
|
+
| Command | Description |
|
|
67
|
+
| ---------- | ------------------------------------------ |
|
|
68
|
+
| `sync` | Import transcripts and teams (incremental) |
|
|
69
|
+
| `stats` | Show session/message/team/token counts |
|
|
70
|
+
| `sessions` | List recent sessions |
|
|
71
|
+
| `search` | Full-text search across messages |
|
|
72
|
+
| `tools` | Show most-used tools |
|
|
73
|
+
| `query` | Execute raw SQL against the database |
|
|
70
74
|
|
|
71
75
|
### Options
|
|
72
76
|
|
package/package.json
CHANGED
package/src/db.ts
CHANGED
|
@@ -142,6 +142,32 @@ CREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE ON messages BEGIN
|
|
|
142
142
|
END;
|
|
143
143
|
`;
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Escape a search term for FTS5 MATCH queries.
|
|
147
|
+
* Handles special characters while preserving prefix (*) and phrase ("") searches.
|
|
148
|
+
*/
|
|
149
|
+
function escape_fts5_query(term: string): string {
|
|
150
|
+
// If already a phrase query (wrapped in quotes), just escape internal quotes
|
|
151
|
+
if (term.startsWith('"') && term.endsWith('"')) {
|
|
152
|
+
return term;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Check for prefix search (ends with *)
|
|
156
|
+
const is_prefix = term.endsWith('*');
|
|
157
|
+
const base_term = is_prefix ? term.slice(0, -1) : term;
|
|
158
|
+
|
|
159
|
+
// FTS5 special chars that cause syntax errors
|
|
160
|
+
const has_special = /[/\-:()^]/.test(base_term);
|
|
161
|
+
|
|
162
|
+
if (!has_special && !base_term.includes('"')) {
|
|
163
|
+
return term; // Safe as-is
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Escape by wrapping in quotes (double internal quotes)
|
|
167
|
+
const escaped = `"${base_term.replace(/"/g, '""')}"`;
|
|
168
|
+
return is_prefix ? escaped + '*' : escaped;
|
|
169
|
+
}
|
|
170
|
+
|
|
145
171
|
export class Database {
|
|
146
172
|
private db: BunDB;
|
|
147
173
|
private stmt_upsert_session: Statement;
|
|
@@ -490,7 +516,7 @@ export class Database {
|
|
|
490
516
|
JOIN sessions s ON s.id = m.session_id
|
|
491
517
|
WHERE messages_fts MATCH ?
|
|
492
518
|
`;
|
|
493
|
-
const params: (string | number)[] = [term];
|
|
519
|
+
const params: (string | number)[] = [escape_fts5_query(term)];
|
|
494
520
|
|
|
495
521
|
if (options.project) {
|
|
496
522
|
query += ` AND s.project_path LIKE ?`;
|