lazy-gravity 0.8.0 → 0.8.1

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.
@@ -64,6 +64,8 @@ function artifactTypeLabel(type) {
64
64
  // ---------------------------------------------------------------------------
65
65
  // ArtifactService
66
66
  // ---------------------------------------------------------------------------
67
+ /** Common words to ignore when scoring fuzzy title matches */
68
+ const COMMON_WORDS = new Set(['the', 'and', 'for', 'with', 'from', 'this', 'that']);
67
69
  class ArtifactService {
68
70
  brainBasePath;
69
71
  constructor(brainBasePath) {
@@ -147,6 +149,7 @@ class ArtifactService {
147
149
  }
148
150
  /**
149
151
  * Try to find a conversation UUID whose overview.txt contains the given session title.
152
+ * Uses an exact match first, falling back to keyword overlap scoring.
150
153
  * Returns the UUID or null if not found.
151
154
  */
152
155
  findConversationByTitle(title) {
@@ -167,6 +170,22 @@ class ArtifactService {
167
170
  })
168
171
  .sort((a, b) => b.mtime - a.mtime)
169
172
  .map(x => x.id);
173
+ let bestId = null;
174
+ let bestScore = 0;
175
+ // Unicode-aware split to support CJK. Preserve CJK characters (len 1) but filter short Latin words.
176
+ const cleanNeedleWords = needle
177
+ .replace(/[^\p{L}\p{N}]+/gu, ' ')
178
+ .split(/\s+/)
179
+ .filter(w => {
180
+ if (COMMON_WORDS.has(w))
181
+ return false;
182
+ // Allow CJK characters (Scripts: Han, Hiragana, Katakana, Hangul) even if length 1.
183
+ const isCJK = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u.test(w);
184
+ return isCJK || w.length > 2;
185
+ });
186
+ const uniqueNeedleWords = Array.from(new Set(cleanNeedleWords));
187
+ // Require a stronger minimum score of 2 to prevent weak one-word matches.
188
+ const minScore = 2;
170
189
  for (const id of sortedIds) {
171
190
  const overviewPath = path.join(this.brainBasePath, id, '.system_generated', 'logs', 'overview.txt');
172
191
  try {
@@ -180,7 +199,18 @@ class ArtifactService {
180
199
  const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
181
200
  const header = buf.slice(0, bytesRead).toString('utf-8').toLowerCase();
182
201
  if (header.includes(needle)) {
183
- return id;
202
+ return id; // Exact match takes precedence
203
+ }
204
+ // Use same Unicode-aware split for header tokens
205
+ const headerTokens = new Set(header.replace(/[^\p{L}\p{N}]+/gu, ' ').split(/\s+/));
206
+ let score = 0;
207
+ for (const word of uniqueNeedleWords) {
208
+ if (headerTokens.has(word))
209
+ score++;
210
+ }
211
+ if (score > bestScore) {
212
+ bestScore = score;
213
+ bestId = id;
184
214
  }
185
215
  }
186
216
  finally {
@@ -192,6 +222,9 @@ class ArtifactService {
192
222
  // Skip unreadable files
193
223
  }
194
224
  }
225
+ if (bestScore >= minScore) {
226
+ return bestId;
227
+ }
195
228
  return null;
196
229
  }
197
230
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazy-gravity",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Control Antigravity from anywhere — a local, secure bot (Discord + Telegram) that lets you remotely operate Antigravity on your home PC from your smartphone.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {