@jobshimo/browser-link 0.16.0 → 0.18.0

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.
@@ -22,7 +22,7 @@ export interface SnapshotOpts {
22
22
  export declare function buildSnapshotJs(opts?: SnapshotOpts): string;
23
23
  /** Build the find-by-text expression. Returns one of:
24
24
  * { matched: true, selector, coords:{x,y}, tag, text, frame?, ambiguous? }
25
- * { matched: false, reason: 'not-found' }
25
+ * { matched: false, reason: 'not-found', error?, near_misses?: [{text,selector,role?}] }
26
26
  * { matched: false, reason: 'multiple-matches', candidates: [{selector,text,tag}] }
27
27
  *
28
28
  * Role-aware: when `role` is provided, only elements whose explicit ARIA
@@ -33,6 +33,22 @@ export declare function buildSnapshotJs(opts?: SnapshotOpts): string;
33
33
  * `deepQueryAll`. `coords` are mapped to TOP-LEVEL viewport coordinates
34
34
  * (accounting for ancestor iframe offsets) so they are directly usable by
35
35
  * `browser.drag` and other coordinate-based tools.
36
+ *
37
+ * `not-found` carries up to 3 `near_misses` — VISIBLE interactive-ish
38
+ * elements ranked by (1) case-insensitive substring containment of the
39
+ * query in the candidate's accessible text/name, then (2) token overlap —
40
+ * so the agent gets a "did you mean" instead of a bare miss. Omitted
41
+ * entirely when nothing scores (no junk suggestions). When `role` narrowed
42
+ * the scan and the text DOES exist outside that role, `error` names the
43
+ * exclusion explicitly (e.g. `text matched 2 elements but none with role
44
+ * "button" — closest: <div onclick> "GIF picker"`) and `near_misses` is
45
+ * populated from that broader, role-agnostic match set instead.
46
+ *
47
+ * Near-miss entries use `genSelector` (not `genSelectorInfo`), so the
48
+ * `ambiguous` flag is intentionally NOT carried — a near-miss selector
49
+ * that collides with structurally-identical twins in other roots resolves
50
+ * first-match-wins silently. Documented on the tool as: hints for the
51
+ * next `find`, never click targets.
36
52
  */
37
53
  export interface FindOpts {
38
54
  text: string;
@@ -47,8 +63,16 @@ export declare function buildFindJs(opts: FindOpts): string;
47
63
  * is set — hit-tests that point before returning it, so a covering overlay
48
64
  * is caught before background.ts dispatches CDP mouse events. Returns:
49
65
  * { ok: true, x, y, tag }
66
+ * { ok: false, reason: 'invalid-selector', error }
50
67
  * { ok: false, reason: 'not-found' }
51
68
  * { ok: false, reason: 'occluded', blocker }
69
+ *
70
+ * The `invalid-selector` check runs BEFORE `deepQueryFirst` — a malformed
71
+ * CSS selector throws the identical `SyntaxError` from every root's own
72
+ * `querySelector`, which `deepQueryFirst`'s per-root try/catch otherwise
73
+ * swallows into an indistinguishable "not-found". Checking once against
74
+ * `document` up front separates "the selector text is broken" from "the
75
+ * selector is valid but nothing on the page matches it".
52
76
  */
53
77
  export interface ClickResolveOpts {
54
78
  selector: string;
@@ -61,7 +85,13 @@ export declare function buildClickResolveJs(opts: ClickResolveOpts): string;
61
85
  * success so background.ts can follow up with CDP `Input.insertText`
62
86
  * (which types into whatever currently has focus at the browser level —
63
87
  * works the same whether that focus target lives in the top document, a
64
- * shadow root, or a same-origin iframe).
88
+ * shadow root, or a same-origin iframe). Returns:
89
+ * { ok: true }
90
+ * { ok: false, reason: 'invalid-selector', error }
91
+ * { ok: false, reason: 'not-found' }
92
+ *
93
+ * Same invalid-selector pre-check as `buildClickResolveJs` — see its doc
94
+ * comment for why the check has to run before `deepQueryFirst`.
65
95
  */
66
96
  export interface TypeResolveOpts {
67
97
  selector: string;
@@ -109,3 +139,27 @@ export interface SettleOpts {
109
139
  settle_timeout_ms: number;
110
140
  }
111
141
  export declare function buildSettleJs(opts: SettleOpts): string;
142
+ /**
143
+ * Build the `browser.state` expression: a compact orientation snapshot —
144
+ * current url/title, the deep-resolved focused element, visible dialog-role
145
+ * elements, scroll position, and viewport size. Cheaper than a full
146
+ * `browser.snapshot` when the agent only needs "where am I right now".
147
+ *
148
+ * `focused` descends through `document.activeElement` past shadow-root and
149
+ * same-origin-iframe boundaries to the real innermost focused element (a
150
+ * shadow host or an <iframe> being "active" at one level is not the actual
151
+ * focus target the agent cares about). Its `selector` goes through the same
152
+ * `genSelectorInfo` uniqueness check `snapshot`/`find` use, so it carries
153
+ * `ambiguous: true` under the same structurally-identical-twins condition.
154
+ *
155
+ * `dialogs` matches visible `[role=dialog]`, `[role=alertdialog]` and open
156
+ * `<dialog>` elements found via the same deep walk, with a best-effort
157
+ * `label` resolved from aria-label / aria-labelledby / the first heading
158
+ * inside the dialog.
159
+ *
160
+ * Every optional field is omitted when there is nothing to report: no
161
+ * `focused` beyond `<body>`, no `dialogs` when none are open, and no
162
+ * `scroll` when the page is at its default (0,0) position — token-lean by
163
+ * construction, matching the omit-falsy convention the other builders use.
164
+ */
165
+ export declare function buildStateJs(): string;
@@ -121,6 +121,7 @@ export function buildFindJs(opts) {
121
121
  role: typeof opts.role === 'string' && opts.role.length > 0 ? opts.role : null,
122
122
  exact: opts.exact === true,
123
123
  candidateLimit: 5,
124
+ nearMissLimit: 3,
124
125
  });
125
126
  return `
126
127
  (() => {
@@ -128,6 +129,7 @@ export function buildFindJs(opts) {
128
129
  ${DOM_HELPERS_JS}
129
130
  const opts = ${optsJson};
130
131
  const needle = opts.text.toLowerCase();
132
+ const needleTokens = needle.split(/[^a-z0-9]+/).filter(Boolean);
131
133
  const ROLE_SELECTORS = {
132
134
  button: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',
133
135
  link: 'a[href], [role="link"]',
@@ -136,9 +138,10 @@ export function buildFindJs(opts) {
136
138
  tab: '[role="tab"]',
137
139
  menuitem: '[role="menuitem"]',
138
140
  };
141
+ const BROAD_SELECTOR = 'button, a, input, textarea, select, [role], [onclick], [contenteditable="true"], [tabindex]';
139
142
  const selectorSet = opts.role && ROLE_SELECTORS[opts.role]
140
143
  ? ROLE_SELECTORS[opts.role]
141
- : 'button, a, input, textarea, select, [role], [onclick], [contenteditable="true"], [tabindex]';
144
+ : BROAD_SELECTOR;
142
145
  const all = deepQueryAll(selectorSet);
143
146
  const matches = [];
144
147
  for (const el of all) {
@@ -150,7 +153,79 @@ export function buildFindJs(opts) {
150
153
  if (ok) matches.push(el);
151
154
  }
152
155
  if (matches.length === 0) {
153
- return { matched: false, reason: 'not-found' };
156
+ // Near-miss ranking: containment beats token overlap; anything scoring
157
+ // 0 is dropped so the suggestion list never pads itself with noise.
158
+ function snippetOf(el) {
159
+ const t = accessibleText(el).trim();
160
+ return t.length > 60 ? t.slice(0, 60) + '...' : t;
161
+ }
162
+ function scoreText(text) {
163
+ const lower = text.toLowerCase();
164
+ const contains = lower.includes(needle);
165
+ const candTokens = lower.split(/[^a-z0-9]+/).filter(Boolean);
166
+ let overlap = 0;
167
+ for (let i = 0; i < needleTokens.length; i++) {
168
+ if (candTokens.indexOf(needleTokens[i]) !== -1) overlap++;
169
+ }
170
+ if (!contains && overlap === 0) return -1;
171
+ return (contains ? 1000 : 0) + overlap * 10;
172
+ }
173
+ function rankCandidates(elements) {
174
+ const scored = [];
175
+ for (const el of elements) {
176
+ if (!isVisible(el)) continue;
177
+ const text = accessibleText(el).trim();
178
+ if (text.length === 0) continue;
179
+ const score = scoreText(text);
180
+ if (score < 0) continue;
181
+ scored.push({ el: el, score: score });
182
+ }
183
+ scored.sort((a, b) => b.score - a.score);
184
+ return scored.slice(0, opts.nearMissLimit).map((s) => s.el);
185
+ }
186
+ function toNearMiss(el) {
187
+ const entry = { text: snippetOf(el), selector: genSelector(el) };
188
+ const roleAttr = el.getAttribute('role');
189
+ if (roleAttr) entry.role = roleAttr;
190
+ return entry;
191
+ }
192
+ function describeForError(el) {
193
+ const tag = el.tagName.toLowerCase();
194
+ if (el.hasAttribute('onclick')) return '<' + tag + ' onclick>';
195
+ const role = el.getAttribute('role');
196
+ if (role) return '<' + tag + ' role="' + role + '">';
197
+ return '<' + tag + '>';
198
+ }
199
+ const result = { matched: false, reason: 'not-found' };
200
+ if (opts.role) {
201
+ // Role narrowed the scan — check whether the text exists OUTSIDE the
202
+ // role filter so the error can name the exclusion explicitly instead
203
+ // of reporting a bare not-found.
204
+ const broadAll = deepQueryAll(BROAD_SELECTOR);
205
+ const broadTextMatches = [];
206
+ for (const el of broadAll) {
207
+ if (!isVisible(el)) continue;
208
+ const text = accessibleText(el).trim();
209
+ if (text.length === 0) continue;
210
+ if (text.toLowerCase().includes(needle)) broadTextMatches.push(el);
211
+ }
212
+ if (broadTextMatches.length > 0) {
213
+ const ranked = rankCandidates(broadTextMatches);
214
+ const closest = ranked[0];
215
+ result.error = 'text matched ' + broadTextMatches.length + ' element' +
216
+ (broadTextMatches.length === 1 ? '' : 's') +
217
+ ' but none with role "' + opts.role + '"' +
218
+ (closest ? ' — closest: ' + describeForError(closest) + ' "' + snippetOf(closest) + '"' : '');
219
+ result.near_misses = ranked.map(toNearMiss);
220
+ return result;
221
+ }
222
+ const ranked = rankCandidates(broadAll);
223
+ if (ranked.length > 0) result.near_misses = ranked.map(toNearMiss);
224
+ return result;
225
+ }
226
+ const ranked = rankCandidates(all);
227
+ if (ranked.length > 0) result.near_misses = ranked.map(toNearMiss);
228
+ return result;
154
229
  }
155
230
  if (matches.length > 1) {
156
231
  return {
@@ -189,6 +264,11 @@ export function buildClickResolveJs(opts) {
189
264
  (() => {
190
265
  ${DEEP_QUERY_JS}
191
266
  const opts = ${optsJson};
267
+ try {
268
+ document.querySelector(opts.selector);
269
+ } catch (e) {
270
+ return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
271
+ }
192
272
  const el = deepQueryFirst(opts.selector);
193
273
  if (!el) return { ok: false, reason: 'not-found' };
194
274
  const chain = frameElementChain(el);
@@ -214,11 +294,16 @@ export function buildTypeResolveJs(opts) {
214
294
  (() => {
215
295
  ${DEEP_QUERY_JS}
216
296
  const opts = ${optsJson};
297
+ try {
298
+ document.querySelector(opts.selector);
299
+ } catch (e) {
300
+ return { ok: false, reason: 'invalid-selector', error: e && e.message ? e.message : String(e) };
301
+ }
217
302
  const el = deepQueryFirst(opts.selector);
218
- if (!el) return false;
303
+ if (!el) return { ok: false, reason: 'not-found' };
219
304
  el.focus();
220
305
  ${opts.clear ? "if ('value' in el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }" : ''}
221
- return true;
306
+ return { ok: true };
222
307
  })()`;
223
308
  }
224
309
  export function buildFocusJs(opts) {
@@ -287,4 +372,116 @@ export function buildSettleJs(opts) {
287
372
  });
288
373
  })()`;
289
374
  }
375
+ /**
376
+ * Build the `browser.state` expression: a compact orientation snapshot —
377
+ * current url/title, the deep-resolved focused element, visible dialog-role
378
+ * elements, scroll position, and viewport size. Cheaper than a full
379
+ * `browser.snapshot` when the agent only needs "where am I right now".
380
+ *
381
+ * `focused` descends through `document.activeElement` past shadow-root and
382
+ * same-origin-iframe boundaries to the real innermost focused element (a
383
+ * shadow host or an <iframe> being "active" at one level is not the actual
384
+ * focus target the agent cares about). Its `selector` goes through the same
385
+ * `genSelectorInfo` uniqueness check `snapshot`/`find` use, so it carries
386
+ * `ambiguous: true` under the same structurally-identical-twins condition.
387
+ *
388
+ * `dialogs` matches visible `[role=dialog]`, `[role=alertdialog]` and open
389
+ * `<dialog>` elements found via the same deep walk, with a best-effort
390
+ * `label` resolved from aria-label / aria-labelledby / the first heading
391
+ * inside the dialog.
392
+ *
393
+ * Every optional field is omitted when there is nothing to report: no
394
+ * `focused` beyond `<body>`, no `dialogs` when none are open, and no
395
+ * `scroll` when the page is at its default (0,0) position — token-lean by
396
+ * construction, matching the omit-falsy convention the other builders use.
397
+ */
398
+ export function buildStateJs() {
399
+ return `
400
+ (() => {
401
+ ${DEEP_QUERY_JS}
402
+ ${DOM_HELPERS_JS}
403
+ function deepActiveElement() {
404
+ let el = document.activeElement;
405
+ let guard = 0;
406
+ while (el && guard < 20) {
407
+ guard++;
408
+ if (el.shadowRoot && el.shadowRoot.activeElement) {
409
+ el = el.shadowRoot.activeElement;
410
+ continue;
411
+ }
412
+ if (el.tagName === 'IFRAME') {
413
+ let innerDoc = null;
414
+ try {
415
+ innerDoc = el.contentDocument;
416
+ } catch (_) {
417
+ innerDoc = null;
418
+ }
419
+ if (innerDoc && innerDoc.activeElement && innerDoc.activeElement !== innerDoc.body) {
420
+ el = innerDoc.activeElement;
421
+ continue;
422
+ }
423
+ }
424
+ break;
425
+ }
426
+ return el;
427
+ }
428
+ function dialogLabel(el) {
429
+ const aria = el.getAttribute('aria-label');
430
+ if (aria) return aria;
431
+ const labelledby = el.getAttribute('aria-labelledby');
432
+ if (labelledby) {
433
+ const ids = labelledby.split(/\\s+/);
434
+ const parts = [];
435
+ for (let i = 0; i < ids.length; i++) {
436
+ if (!ids[i]) continue;
437
+ const target = deepQueryFirst('#' + CSS.escape(ids[i]));
438
+ if (target) {
439
+ const t = shortText(target);
440
+ if (t) parts.push(t);
441
+ }
442
+ }
443
+ const joined = parts.join(' ').trim();
444
+ if (joined) return joined;
445
+ }
446
+ const heading = deepQueryFirst('h1, h2, h3', el);
447
+ if (heading) {
448
+ const t = shortText(heading);
449
+ if (t) return t;
450
+ }
451
+ return '';
452
+ }
453
+
454
+ const result = {
455
+ url: location.href,
456
+ title: document.title,
457
+ viewport: { w: window.innerWidth, h: window.innerHeight },
458
+ };
459
+
460
+ const active = deepActiveElement();
461
+ if (active && active !== document.body && active.tagName) {
462
+ const selInfo = genSelectorInfo(active);
463
+ const focused = { selector: selInfo.selector, tag: active.tagName.toLowerCase() };
464
+ if (selInfo.ambiguous) focused.ambiguous = true;
465
+ result.focused = focused;
466
+ }
467
+
468
+ const dialogs = [];
469
+ deepQueryAll('[role="dialog"], [role="alertdialog"], dialog[open]').forEach((el) => {
470
+ if (!isVisible(el)) return;
471
+ const role = el.getAttribute('role') || 'dialog';
472
+ const entry = { selector: genSelector(el), role: role };
473
+ const label = dialogLabel(el);
474
+ if (label) entry.label = label;
475
+ dialogs.push(entry);
476
+ });
477
+ if (dialogs.length > 0) result.dialogs = dialogs;
478
+
479
+ const scrollX = Math.round(window.scrollX);
480
+ const scrollY = Math.round(window.scrollY);
481
+ if (scrollX !== 0 || scrollY !== 0) result.scroll = { x: scrollX, y: scrollY };
482
+
483
+ return result;
484
+ })()
485
+ `;
486
+ }
290
487
  //# sourceMappingURL=builders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAwBlD,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,cAAc,EAAE,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;QACtF,eAAe,EAAE,IAAI,CAAC,gBAAgB,KAAK,IAAI;QAC/C,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACxD,cAAc,EACZ,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC;YAClE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC;YACrC,CAAC,CAAC,GAAG;KACV,CAAC,CAAC;IACH,OAAO;;IAEL,aAAa;IACb,cAAc;iBACD,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FxB,CAAC;AACF,CAAC;AAsBD,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QAC9E,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI;QAC1B,cAAc,EAAE,CAAC;KAClB,CAAC,CAAC;IACH,OAAO;;IAEL,aAAa;IACb,cAAc;iBACD,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDxB,CAAC;AACF,CAAC;AAiBD,MAAM,UAAU,mBAAmB,CAAC,IAAsB;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAChF,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;;;;;;;;;;;;;;CAkBxB,CAAC;AACF,CAAC;AAeD,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;IAIrB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gGAAgG,CAAC,CAAC,CAAC,EAAE;;KAEjH,CAAC;AACN,CAAC;AAeD,MAAM,UAAU,YAAY,CAAC,IAAsB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO;;IAEL,aAAa;iBACA,QAAQ;;;;;KAKpB,CAAC;AACN,CAAC;AA8BD,MAAM,UAAU,aAAa,CAAC,IAAgB;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;QACrC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC;KAC/C,CAAC,CAAC;IACH,OAAO;;iBAEQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CpB,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"builders.js","sourceRoot":"","sources":["../../src/inpage/builders.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "browser-link",
4
- "version": "0.16.0",
4
+ "version": "0.18.0",
5
5
  "description": "Bridge between Chrome and an MCP client (Claude Code, OpenCode, GitHub Copilot CLI, …). Per-tab manual activation.",
6
6
  "permissions": [
7
7
  "debugger",
package/dist/map/db.js CHANGED
@@ -71,6 +71,32 @@ function runMigrations(db) {
71
71
 
72
72
  CREATE INDEX IF NOT EXISTS idx_entries_lookup ON entries(app_id, url_pattern);
73
73
  `);
74
+ // v0.18.0: named, replayable browser.flow recipes per app. Deliberately a
75
+ // separate table from `entries` — the pre-existing `entries.kind='flow'`
76
+ // is a free-form payload with no shape guarantee, while a row here always
77
+ // holds a `steps_json` array validated against the EXACT browser.flow step
78
+ // grammar (see `validateFlowSteps` in tools/browser-dispatch.ts, reused by
79
+ // map/tools.ts). Not scoped by url_pattern like entries — a flow recipe
80
+ // is identified by (app, name) only, since a multi-step recipe is not
81
+ // tied to a single route the way a selector or gotcha usually is.
82
+ // Same idempotent CREATE-TABLE-IF-NOT-EXISTS pattern as above, so an
83
+ // existing DB from before this table existed picks it up on next getDb()
84
+ // without touching any pre-existing row.
85
+ db.exec(`
86
+ CREATE TABLE IF NOT EXISTS flows (
87
+ id INTEGER PRIMARY KEY,
88
+ app_id INTEGER NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
89
+ name TEXT NOT NULL,
90
+ description TEXT,
91
+ steps_json TEXT NOT NULL,
92
+ created_at TEXT NOT NULL,
93
+ updated_at TEXT NOT NULL,
94
+ use_count INTEGER NOT NULL DEFAULT 0,
95
+ UNIQUE(app_id, name)
96
+ );
97
+
98
+ CREATE INDEX IF NOT EXISTS idx_flows_app ON flows(app_id);
99
+ `);
74
100
  }
75
101
  export function closeDb() {
76
102
  if (dbInstance) {
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,IAAI,UAAU,GAA6B,IAAI,CAAC;AAEhD,MAAM,UAAU,KAAK;IACnB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,UAAU,GAAG,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,IAAI,UAAU,GAA6B,IAAI,CAAC;AAEhD,MAAM,UAAU,KAAK;IACnB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,UAAU,GAAG,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,UAAkB;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BP,CAAC,CAAC;IAEH,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,wEAAwE;IACxE,sEAAsE;IACtE,kEAAkE;IAClE,qEAAqE;IACrE,yEAAyE;IACzE,yCAAyC;IACzC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;GAcP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;AACH,CAAC"}
@@ -50,6 +50,7 @@ export interface RecallInput {
50
50
  export interface RecallResult {
51
51
  app: AppRow | null;
52
52
  entries: EntryRow[];
53
+ flows: FlowRow[];
53
54
  }
54
55
  export declare function recall(input: RecallInput): RecallResult;
55
56
  export interface RecordUseInput {
@@ -70,3 +71,31 @@ export interface ForgetResult {
70
71
  export declare function forget(input: ForgetInput): ForgetResult;
71
72
  export declare function renameApp(app_id: number, new_app_key: string): AppRow | null;
72
73
  export declare function listApps(): AppRow[];
74
+ export interface FlowRow {
75
+ id: number;
76
+ app_id: number;
77
+ name: string;
78
+ description: string | null;
79
+ steps: unknown;
80
+ created_at: string;
81
+ updated_at: string;
82
+ use_count: number;
83
+ }
84
+ export interface SaveFlowInput {
85
+ origin: string;
86
+ app_key?: string | null;
87
+ title?: string | null;
88
+ name: string;
89
+ description?: string | null;
90
+ steps: unknown;
91
+ }
92
+ /** Upsert on (app, name) — saving an existing name replaces its
93
+ * description/steps and bumps updated_at, mirroring saveEntry's upsert
94
+ * semantics. `use_count` is left untouched on update (re-saving is not a
95
+ * "use"). */
96
+ export declare function saveFlow(input: SaveFlowInput): {
97
+ app: AppRow;
98
+ flow: FlowRow;
99
+ };
100
+ /** Every flow recipe saved for an app, alphabetical by name. */
101
+ export declare function listFlows(app_id: number): FlowRow[];
@@ -99,7 +99,7 @@ export function recall(input) {
99
99
  .get(input.origin);
100
100
  }
101
101
  if (!app)
102
- return { app: null, entries: [] };
102
+ return { app: null, entries: [], flows: [] };
103
103
  // Touch last_seen_at so apps that are actively used bubble up.
104
104
  db.prepare('UPDATE apps SET last_seen_at = ? WHERE id = ?').run(now(), app.id);
105
105
  const pathname = input.url ? extractPathname(input.url) : null;
@@ -110,7 +110,10 @@ export function recall(input) {
110
110
  : db
111
111
  .prepare(`SELECT * FROM entries WHERE app_id = ? ORDER BY url_pattern, updated_at DESC`)
112
112
  .all(app.id));
113
- return { app, entries: rows.map(hydrate) };
113
+ // Flow recipes are not url_pattern-scoped (see the schema comment in
114
+ // db.ts) — recall always returns every flow saved for the app, regardless
115
+ // of the optional `url` filter.
116
+ return { app, entries: rows.map(hydrate), flows: listFlows(app.id) };
114
117
  }
115
118
  function extractPathname(url) {
116
119
  try {
@@ -159,4 +162,43 @@ export function renameApp(app_id, new_app_key) {
159
162
  export function listApps() {
160
163
  return getDb().prepare('SELECT * FROM apps ORDER BY last_seen_at DESC').all();
161
164
  }
165
+ function hydrateFlow(row) {
166
+ const { steps_json, ...rest } = row;
167
+ return { ...rest, steps: parsePayload(steps_json) };
168
+ }
169
+ /** Upsert on (app, name) — saving an existing name replaces its
170
+ * description/steps and bumps updated_at, mirroring saveEntry's upsert
171
+ * semantics. `use_count` is left untouched on update (re-saving is not a
172
+ * "use"). */
173
+ export function saveFlow(input) {
174
+ const app = upsertApp({
175
+ origin: input.origin,
176
+ app_key: input.app_key ?? null,
177
+ title: input.title ?? null,
178
+ });
179
+ const ts = now();
180
+ const stepsJson = JSON.stringify(input.steps);
181
+ const db = getDb();
182
+ const existing = db
183
+ .prepare('SELECT * FROM flows WHERE app_id = ? AND name = ?')
184
+ .get(app.id, input.name);
185
+ if (existing) {
186
+ db.prepare('UPDATE flows SET description = ?, steps_json = ?, updated_at = ? WHERE id = ?').run(input.description ?? null, stepsJson, ts, existing.id);
187
+ const updated = db.prepare('SELECT * FROM flows WHERE id = ?').get(existing.id);
188
+ return { app, flow: hydrateFlow(updated) };
189
+ }
190
+ const info = db
191
+ .prepare(`INSERT INTO flows (app_id, name, description, steps_json, created_at, updated_at, use_count)
192
+ VALUES (?, ?, ?, ?, ?, ?, 0)`)
193
+ .run(app.id, input.name, input.description ?? null, stepsJson, ts, ts);
194
+ const inserted = db.prepare('SELECT * FROM flows WHERE id = ?').get(info.lastInsertRowid);
195
+ return { app, flow: hydrateFlow(inserted) };
196
+ }
197
+ /** Every flow recipe saved for an app, alphabetical by name. */
198
+ export function listFlows(app_id) {
199
+ const rows = getDb()
200
+ .prepare('SELECT * FROM flows WHERE app_id = ? ORDER BY name')
201
+ .all(app_id);
202
+ return rows.map(hydrateFlow);
203
+ }
162
204
  //# sourceMappingURL=queries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/map/queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/map/queries.ts"],"names":[],"mappings":"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"}