@jobshimo/browser-link 0.42.0 → 0.44.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.
Files changed (79) hide show
  1. package/README.md +42 -2
  2. package/dist/activity/db.js +18 -0
  3. package/dist/activity/db.js.map +1 -1
  4. package/dist/activity/extract.d.ts +18 -2
  5. package/dist/activity/extract.js +122 -1
  6. package/dist/activity/extract.js.map +1 -1
  7. package/dist/activity/queries.d.ts +1 -1
  8. package/dist/activity/queries.js +20 -4
  9. package/dist/activity/queries.js.map +1 -1
  10. package/dist/activity/summary.d.ts +54 -0
  11. package/dist/activity/summary.js +95 -0
  12. package/dist/activity/summary.js.map +1 -0
  13. package/dist/activity/types.d.ts +30 -0
  14. package/dist/activity/types.js +31 -1
  15. package/dist/activity/types.js.map +1 -1
  16. package/dist/bridge/ws-bridge.d.ts +6 -2
  17. package/dist/bridge/ws-bridge.js +34 -27
  18. package/dist/bridge/ws-bridge.js.map +1 -1
  19. package/dist/cdp/inpage/observer.d.ts +2 -2
  20. package/dist/cdp/inpage/observer.js +11 -4
  21. package/dist/cdp/inpage/observer.js.map +1 -1
  22. package/dist/cli.d.ts +6 -0
  23. package/dist/cli.js +50 -9
  24. package/dist/cli.js.map +1 -1
  25. package/dist/commands/activity.d.ts +5 -0
  26. package/dist/commands/activity.js +92 -1
  27. package/dist/commands/activity.js.map +1 -1
  28. package/dist/commands/config.d.ts +29 -0
  29. package/dist/commands/config.js +99 -5
  30. package/dist/commands/config.js.map +1 -1
  31. package/dist/commands/doctor.d.ts +20 -1
  32. package/dist/commands/doctor.js +41 -19
  33. package/dist/commands/doctor.js.map +1 -1
  34. package/dist/config.d.ts +30 -0
  35. package/dist/config.js +20 -0
  36. package/dist/config.js.map +1 -1
  37. package/dist/downloads.d.ts +10 -3
  38. package/dist/downloads.js +23 -4
  39. package/dist/downloads.js.map +1 -1
  40. package/dist/extension/inpage/observer.d.ts +2 -2
  41. package/dist/extension/inpage/observer.js +11 -4
  42. package/dist/extension/inpage/observer.js.map +1 -1
  43. package/dist/extension/manifest.json +1 -1
  44. package/dist/lifecycle/election.d.ts +16 -5
  45. package/dist/lifecycle/election.js +21 -4
  46. package/dist/lifecycle/election.js.map +1 -1
  47. package/dist/lifecycle/processes.d.ts +18 -0
  48. package/dist/lifecycle/processes.js +40 -7
  49. package/dist/lifecycle/processes.js.map +1 -1
  50. package/dist/lifecycle/repair.d.ts +15 -3
  51. package/dist/lifecycle/repair.js +41 -8
  52. package/dist/lifecycle/repair.js.map +1 -1
  53. package/dist/lifecycle/version-endpoint.d.ts +8 -3
  54. package/dist/lifecycle/version-endpoint.js +19 -4
  55. package/dist/lifecycle/version-endpoint.js.map +1 -1
  56. package/dist/manual/refresh.js +6 -0
  57. package/dist/manual/refresh.js.map +1 -1
  58. package/dist/manual/topics.js +2 -2
  59. package/dist/manual/topics.js.map +1 -1
  60. package/dist/map/db.js +26 -0
  61. package/dist/map/db.js.map +1 -1
  62. package/dist/map/learning.d.ts +81 -0
  63. package/dist/map/learning.js +244 -0
  64. package/dist/map/learning.js.map +1 -0
  65. package/dist/map/queries.d.ts +45 -0
  66. package/dist/map/queries.js +108 -5
  67. package/dist/map/queries.js.map +1 -1
  68. package/dist/map/tools.js +2 -1
  69. package/dist/map/tools.js.map +1 -1
  70. package/dist/permissions.js +6 -0
  71. package/dist/permissions.js.map +1 -1
  72. package/dist/server.js +17 -4
  73. package/dist/server.js.map +1 -1
  74. package/dist/tools/browser-definitions.js +21 -2
  75. package/dist/tools/browser-definitions.js.map +1 -1
  76. package/dist/tools/browser-dispatch.d.ts +10 -0
  77. package/dist/tools/browser-dispatch.js +116 -22
  78. package/dist/tools/browser-dispatch.js.map +1 -1
  79. package/package.json +1 -1
@@ -17,6 +17,12 @@
17
17
  export type ExecFileLike = (file: string, args: readonly string[], options: {
18
18
  timeout: number;
19
19
  }) => string;
20
+ /** Asynchronous `ExecFileLike`: same argv and timeout, stdout resolved. Used
21
+ * where the listing runs alongside other probes (`doctor`), so the slow WMI
22
+ * scan does not block the event loop. */
23
+ export type ExecFileAsyncLike = (file: string, args: readonly string[], options: {
24
+ timeout: number;
25
+ }) => Promise<string>;
20
26
  /** One row of the OS process table. `startedAt` is epoch milliseconds, or
21
27
  * `null` when the OS did not report a usable start time. */
22
28
  export interface ProcessEntry {
@@ -26,6 +32,7 @@ export interface ProcessEntry {
26
32
  command: string;
27
33
  }
28
34
  export declare const defaultExecFile: ExecFileLike;
35
+ export declare const defaultExecFileAsync: ExecFileAsyncLike;
29
36
  /**
30
37
  * Parse a process start time in any of the forms the OS tools print:
31
38
  * PowerShell 5.1's JSON `/Date(ms)/`, ISO 8601 (PowerShell 7 JSON,
@@ -40,6 +47,8 @@ export declare function parseWindowsProcessList(stdout: string): ProcessEntry[];
40
47
  export declare function parseUnixProcessList(stdout: string): ProcessEntry[];
41
48
  /** The whole process table, or `[]` when it cannot be read. */
42
49
  export declare function listProcesses(os?: NodeJS.Platform, exec?: ExecFileLike): ProcessEntry[];
50
+ /** `listProcesses` without blocking the event loop. Never rejects. */
51
+ export declare function listProcessesAsync(os?: NodeJS.Platform, exec?: ExecFileAsyncLike): Promise<ProcessEntry[]>;
43
52
  /** Start time of one process (epoch ms), or `null` when unknown. */
44
53
  export declare function readProcessStartTime(pid: number, opts?: {
45
54
  os?: NodeJS.Platform;
@@ -55,6 +64,8 @@ export declare function readProcessStartTime(pid: number, opts?: {
55
64
  export declare function matchBrowserLinkCommand(command: string): {
56
65
  subcommand: string | null;
57
66
  } | null;
67
+ /** `selfPid` and every ancestor reachable through `ppid` in `list`. */
68
+ export declare function selfAndAncestors(list: readonly ProcessEntry[], selfPid: number): Set<number>;
58
69
  /** Live browser-link bridges in `list`, excluding `selfPid`, its ancestor
59
70
  * chain (the shell or client that launched it) and non-bridge commands. */
60
71
  export declare function findBridgeProcesses(list: readonly ProcessEntry[], selfPid: number): ProcessEntry[];
@@ -63,5 +74,12 @@ export declare function listBridgeProcesses(opts?: {
63
74
  exec?: ExecFileLike;
64
75
  selfPid?: number;
65
76
  }): ProcessEntry[];
77
+ /** `listBridgeProcesses` without blocking the event loop, so `doctor` runs
78
+ * it concurrently with its other probes. Never rejects. */
79
+ export declare function listBridgeProcessesAsync(opts?: {
80
+ os?: NodeJS.Platform;
81
+ exec?: ExecFileAsyncLike;
82
+ selfPid?: number;
83
+ }): Promise<ProcessEntry[]>;
66
84
  /** Short, display-only form: runtime name, `browser-link`, then arguments. */
67
85
  export declare function shortCommand(command: string, max?: number): string;
@@ -1,4 +1,4 @@
1
- import { execFileSync } from 'node:child_process';
1
+ import { execFile, execFileSync } from 'node:child_process';
2
2
  import { platform } from 'node:os';
3
3
  /** WMI cold starts are slow: same budget `silent-debugger.ts` documents. */
4
4
  const LIST_TIMEOUT_MS = 5000;
@@ -10,6 +10,19 @@ export const defaultExecFile = (file, args, options) => execFileSync(file, args,
10
10
  // `ps` prints lstart in the C locale only when told so.
11
11
  env: { ...process.env, LC_ALL: 'C' },
12
12
  });
13
+ export const defaultExecFileAsync = (file, args, options) => new Promise((resolve, reject) => {
14
+ execFile(file, [...args], {
15
+ encoding: 'utf8',
16
+ windowsHide: true,
17
+ timeout: options.timeout,
18
+ env: { ...process.env, LC_ALL: 'C' },
19
+ }, (err, stdout) => {
20
+ if (err)
21
+ reject(new Error(err.message));
22
+ else
23
+ resolve(stdout);
24
+ });
25
+ });
13
26
  /**
14
27
  * Parse a process start time in any of the forms the OS tools print:
15
28
  * PowerShell 5.1's JSON `/Date(ms)/`, ISO 8601 (PowerShell 7 JSON,
@@ -85,14 +98,29 @@ const WINDOWS_LIST_SCRIPT = 'Get-CimInstance Win32_Process | ' +
85
98
  function powershell(script) {
86
99
  return ['powershell', ['-NoProfile', '-NonInteractive', '-Command', script]];
87
100
  }
101
+ /** The OS command that lists the whole process table, and its parser. */
102
+ function processListCommand(os) {
103
+ if (os === 'win32') {
104
+ const [file, args] = powershell(WINDOWS_LIST_SCRIPT);
105
+ return { file, args, parse: parseWindowsProcessList };
106
+ }
107
+ return { file: 'ps', args: ['-axo', 'pid=,ppid=,lstart=,command='], parse: parseUnixProcessList };
108
+ }
88
109
  /** The whole process table, or `[]` when it cannot be read. */
89
110
  export function listProcesses(os = platform(), exec = defaultExecFile) {
90
111
  try {
91
- if (os === 'win32') {
92
- const [file, args] = powershell(WINDOWS_LIST_SCRIPT);
93
- return parseWindowsProcessList(exec(file, args, { timeout: LIST_TIMEOUT_MS }));
94
- }
95
- return parseUnixProcessList(exec('ps', ['-axo', 'pid=,ppid=,lstart=,command='], { timeout: LIST_TIMEOUT_MS }));
112
+ const { file, args, parse } = processListCommand(os);
113
+ return parse(exec(file, args, { timeout: LIST_TIMEOUT_MS }));
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ }
119
+ /** `listProcesses` without blocking the event loop. Never rejects. */
120
+ export async function listProcessesAsync(os = platform(), exec = defaultExecFileAsync) {
121
+ try {
122
+ const { file, args, parse } = processListCommand(os);
123
+ return parse(await exec(file, args, { timeout: LIST_TIMEOUT_MS }));
96
124
  }
97
125
  catch {
98
126
  return [];
@@ -199,7 +227,7 @@ function isBridgeSubcommand(subcommand) {
199
227
  return subcommand === null || subcommand === 'start';
200
228
  }
201
229
  /** `selfPid` and every ancestor reachable through `ppid` in `list`. */
202
- function selfAndAncestors(list, selfPid) {
230
+ export function selfAndAncestors(list, selfPid) {
203
231
  const byPid = new Map(list.map((p) => [p.pid, p]));
204
232
  const out = new Set();
205
233
  let pid = selfPid;
@@ -223,6 +251,11 @@ export function findBridgeProcesses(list, selfPid) {
223
251
  export function listBridgeProcesses(opts = {}) {
224
252
  return findBridgeProcesses(listProcesses(opts.os, opts.exec), opts.selfPid ?? process.pid);
225
253
  }
254
+ /** `listBridgeProcesses` without blocking the event loop, so `doctor` runs
255
+ * it concurrently with its other probes. Never rejects. */
256
+ export async function listBridgeProcessesAsync(opts = {}) {
257
+ return findBridgeProcesses(await listProcessesAsync(opts.os, opts.exec), opts.selfPid ?? process.pid);
258
+ }
226
259
  /** Short, display-only form: runtime name, `browser-link`, then arguments. */
227
260
  export function shortCommand(command, max = 80) {
228
261
  const tokens = tokenize(command);
@@ -1 +1 @@
1
- {"version":3,"file":"processes.js","sourceRoot":"","sources":["../../src/lifecycle/processes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"processes.js","sourceRoot":"","sources":["../../src/lifecycle/processes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA2CnC,4EAA4E;AAC5E,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,CAAC,MAAM,eAAe,GAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CACnE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;IACvB,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;IACnC,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,wDAAwD;IACxD,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;CACrC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAC7E,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,QAAQ,CACN,IAAI,EACJ,CAAC,GAAG,IAAI,CAAC,EACT;QACE,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;KACrC,EACD,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACd,IAAI,GAAG;YAAE,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;;YACnC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,uEAAuE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/F,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,OAAO,GAAG,GAAG,QAAQ,CAAC;IACxB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AASD;mEACmE;AACnE,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAc,CAAC;IAChE,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QACtD,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,GAAwB,CAAC;QAC3F,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAAE,SAAS;QACjD,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC;YACP,GAAG;YACH,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,SAAS,EAAE,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI;YACnF,OAAO,EAAE,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;SACnE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,QAAQ,GACZ,qFAAqF,CAAC;AAExF,8DAA8D;AAC9D,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,GAAG,CAAC,IAAI,CAAC;YACP,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClB,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACrB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,mBAAmB,GACvB,kCAAkC;IAClC,wEAAwE;IACxE,0BAA0B,CAAC;AAE7B,SAAS,UAAU,CAAC,MAAc;IAChC,OAAO,CAAC,YAAY,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,yEAAyE;AACzE,SAAS,kBAAkB,CAAC,EAAmB;IAK7C,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,6BAA6B,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;AACpG,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAC3B,KAAsB,QAAQ,EAAE,EAChC,OAAqB,eAAe;IAEpC,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAsB,QAAQ,EAAE,EAChC,OAA0B,oBAAoB;IAE9C,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAClC,GAAW,EACX,OAAsD,EAAE;IAExD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,CAAC;IAC1C,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU,CAC7B,sDAAsD,GAAG,MAAM;gBAC7D,+CAA+C;gBAC/C,uDAAuD,CAC1D,CAAC;YACF,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,gBAAgB,CACrB,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAC/E,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;uEACuE;AACvE,SAAS,QAAQ,CAAC,OAAe;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,QAAQ,GAAG,CAAC,QAAQ,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,IAAI,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,SAAS;QACX,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;QACd,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IACD,IAAI,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,kDAAkD;AAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAC3E,qEAAqE;AACrE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAE1D,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,+EAA+E;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,iBAAiB,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,CAAC,IAAI,CAAC,CAAC;QACP,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;YAAE,CAAC,IAAI,CAAC,CAAC;QACxF,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;;;kCAIkC;AAClC,SAAS,kBAAkB,CAAC,UAAyB;IACnD,OAAO,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,OAAO,CAAC;AACvD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,IAA6B,EAAE,OAAe;IAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,GAAG,GAAuB,OAAO,CAAC;IACtC,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACb,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;2EAC2E;AAC3E,MAAM,UAAU,mBAAmB,CACjC,IAA6B,EAC7B,OAAe;IAEf,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,KAAK,GAAG,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACjD,OAAO,KAAK,KAAK,IAAI,IAAI,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAwE,EAAE;IAE1E,OAAO,mBAAmB,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED;2DAC2D;AAC3D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAA6E,EAAE;IAE/E,OAAO,mBAAmB,CACxB,MAAM,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAC5C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAC5B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,GAAG,GAAG,EAAE;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAChC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtD,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC"}
@@ -20,9 +20,7 @@ export interface RepairDeps {
20
20
  detached: true;
21
21
  stdio: 'ignore';
22
22
  windowsHide: true;
23
- }) => {
24
- unref(): void;
25
- };
23
+ }) => RepairChild;
26
24
  terminateSockets: () => void;
27
25
  stopIpc: () => Promise<void>;
28
26
  exit: (code: number) => void;
@@ -30,11 +28,25 @@ export interface RepairDeps {
30
28
  delay: (ms: number) => Promise<void>;
31
29
  log?: (msg: string) => void;
32
30
  }
31
+ /** The slice of Node's `ChildProcess` the repair uses. A spawn can fail
32
+ * asynchronously (`error` after `spawn()` returned, e.g. EACCES); `spawn`
33
+ * is emitted once the child really started. */
34
+ export interface RepairChild {
35
+ unref(): void;
36
+ on(event: 'spawn' | 'error', listener: (err?: Error) => void): unknown;
37
+ }
33
38
  /** Time given to the `bridge.repair.result` frame before sockets die. */
34
39
  export declare const REPAIR_FLUSH_DELAY_MS = 150;
40
+ /** Longest wait for the child's `spawn`/`error` event. Node emits one of
41
+ * them within a tick or two; past this the child is assumed started. */
42
+ export declare const REPAIR_SPAWN_CONFIRM_MS = 2000;
35
43
  export interface RepairController {
36
44
  /** Start the restart (once). Returns whether it is (now) in progress. */
37
45
  start(): boolean;
46
+ /** True from `start()` until the process exits, or until a failed spawn
47
+ * gave up. `/version` reports it as `repairing` so the successor waits for
48
+ * the port instead of deferring to a same-version primary. */
49
+ readonly inProgress: boolean;
38
50
  /** Settles when the current restart attempt finished (tests). */
39
51
  readonly done: Promise<void>;
40
52
  }
@@ -1,26 +1,56 @@
1
1
  /** Time given to the `bridge.repair.result` frame before sockets die. */
2
2
  export const REPAIR_FLUSH_DELAY_MS = 150;
3
+ /** Longest wait for the child's `spawn`/`error` event. Node emits one of
4
+ * them within a tick or two; past this the child is assumed started. */
5
+ export const REPAIR_SPAWN_CONFIRM_MS = 2000;
3
6
  export function createRepairController(deps) {
4
7
  let inProgress = false;
5
8
  let done = Promise.resolve();
9
+ const giveUp = (err) => {
10
+ // Without a successor, exiting would leave no server at all: keep
11
+ // serving and let the user fall back to `browser-link stop`.
12
+ inProgress = false;
13
+ deps.log?.(`Repair: could not start the installed server (${err instanceof Error ? err.message : String(err)}); still serving.`);
14
+ };
6
15
  const run = async () => {
7
16
  await deps.delay(REPAIR_FLUSH_DELAY_MS);
17
+ let child;
8
18
  try {
9
- deps
10
- .spawn(deps.execPath, [deps.cliPath], {
19
+ child = deps.spawn(deps.execPath, [deps.cliPath], {
11
20
  detached: true,
12
21
  stdio: 'ignore',
13
22
  windowsHide: true,
14
- })
15
- .unref();
23
+ });
16
24
  }
17
25
  catch (err) {
18
- // Without a successor, exiting would leave no server at all: keep
19
- // serving and let the user fall back to `browser-link stop`.
20
- inProgress = false;
21
- deps.log?.(`Repair: could not start the installed server (${err instanceof Error ? err.message : String(err)}); still serving.`);
26
+ giveUp(err);
22
27
  return;
23
28
  }
29
+ // Wait for the child to really start before handing anything over: an
30
+ // asynchronous spawn failure arrives as an `error` event, which would
31
+ // also crash this process if nobody listened. The listener stays
32
+ // attached for the rest of the process's life for the same reason.
33
+ const started = await new Promise((resolve) => {
34
+ const timer = setTimeout(() => {
35
+ resolve(true);
36
+ }, REPAIR_SPAWN_CONFIRM_MS);
37
+ timer.unref();
38
+ child.on('spawn', () => {
39
+ clearTimeout(timer);
40
+ resolve(true);
41
+ });
42
+ child.on('error', (err) => {
43
+ clearTimeout(timer);
44
+ const error = err ?? new Error('spawn failed');
45
+ deps.log?.(`Repair: installed server error: ${error.message}`);
46
+ resolve(error);
47
+ });
48
+ });
49
+ if (started !== true) {
50
+ giveUp(started);
51
+ return;
52
+ }
53
+ child.unref();
24
54
  deps.log?.('Repair: installed server started; handing over the port.');
25
55
  deps.terminateSockets();
26
56
  try {
@@ -42,6 +72,9 @@ export function createRepairController(deps) {
42
72
  get done() {
43
73
  return done;
44
74
  },
75
+ get inProgress() {
76
+ return inProgress;
77
+ },
45
78
  };
46
79
  }
47
80
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/lifecycle/repair.ts"],"names":[],"mappings":"AAiCA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AASzC,MAAM,UAAU,sBAAsB,CAAC,IAAgB;IACrD,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAE5C,MAAM,GAAG,GAAG,KAAK,IAAmB,EAAE;QACpC,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,IAAI;iBACD,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBACpC,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,IAAI;aAClB,CAAC;iBACD,KAAK,EAAE,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kEAAkE;YAClE,6DAA6D;YAC7D,UAAU,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,GAAG,EAAE,CACR,iDAAiD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CACrH,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC,0DAA0D,CAAC,CAAC;QACvE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;YACH,IAAI,UAAU;gBAAE,OAAO,IAAI,CAAC;YAC5B,UAAU,GAAG,IAAI,CAAC;YAClB,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI;YACN,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAwB,EACxB,IAAwC,EACxC,WAAwC;IAExC,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,EAAE,sBAAsB;YAC5B,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,gDAAgD;SACxD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC9F,WAAW,EAAE,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/lifecycle/repair.ts"],"names":[],"mappings":"AAyCA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC;wEACwE;AACxE,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAa5C,MAAM,UAAU,sBAAsB,CAAC,IAAgB;IACrD,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAE5C,MAAM,MAAM,GAAG,CAAC,GAAY,EAAQ,EAAE;QACpC,kEAAkE;QAClE,6DAA6D;QAC7D,UAAU,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,GAAG,EAAE,CACR,iDAAiD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CACrH,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,KAAK,IAAmB,EAAE;QACpC,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACxC,IAAI,KAAkB,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBAChD,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,CAAC;YACZ,OAAO;QACT,CAAC;QACD,sEAAsE;QACtE,sEAAsE;QACtE,iEAAiE;QACjE,mEAAmE;QACnE,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,EAAE,uBAAuB,CAAC,CAAC;YAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC/C,IAAI,CAAC,GAAG,EAAE,CAAC,mCAAmC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/D,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,CAAC,OAAO,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QACD,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,EAAE,CAAC,0DAA0D,CAAC,CAAC;QACvE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;YACH,IAAI,UAAU;gBAAE,OAAO,IAAI,CAAC;YAC5B,UAAU,GAAG,IAAI,CAAC;YAClB,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI;YACN,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,UAAU;YACZ,OAAO,UAAU,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAwB,EACxB,IAAwC,EACxC,WAAwC;IAExC,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,EAAE,sBAAsB;YAC5B,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,gDAAgD;SACxD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC9F,WAAW,EAAE,CAAC;AAChB,CAAC"}
@@ -11,6 +11,11 @@ export declare const INSTALLED_CLI_PATH: string;
11
11
  export declare function readInstalledCodeMtime(path?: string): number | null;
12
12
  /** Approximate wall-clock start of this process, epoch ms. */
13
13
  export declare const PROCESS_STARTED_AT: number;
14
- export declare function buildVersionInfo(version: string, pid?: number, startedAt?: number, installed?: () => string | null): VersionInfo;
15
- /** The bridge's plain-HTTP handler: `/version` or 404. */
16
- export declare function handleBridgeHttpRequest(req: IncomingMessage, res: ServerResponse, version: string): void;
14
+ export declare function buildVersionInfo(version: string, pid?: number, startedAt?: number, installed?: () => string | null, repairing?: boolean): VersionInfo;
15
+ /** Whether a request's `Host` header names this machine's loopback. A web
16
+ * page reaching the port through DNS rebinding carries its own host name,
17
+ * so it never reads the pid and versions. */
18
+ export declare function isLoopbackHost(host: string | undefined): boolean;
19
+ /** The bridge's plain-HTTP handler: `/version` (loopback `Host` only, else
20
+ * 403) or 404. `isRepairing` reports a repair hand-off in progress. */
21
+ export declare function handleBridgeHttpRequest(req: IncomingMessage, res: ServerResponse, version: string, isRepairing?: () => boolean): void;
@@ -27,21 +27,36 @@ export function readInstalledCodeMtime(path = INSTALLED_CLI_PATH) {
27
27
  }
28
28
  /** Approximate wall-clock start of this process, epoch ms. */
29
29
  export const PROCESS_STARTED_AT = Date.now() - Math.round(process.uptime() * 1000);
30
- export function buildVersionInfo(version, pid = process.pid, startedAt = PROCESS_STARTED_AT, installed = readInstalledVersion) {
30
+ export function buildVersionInfo(version, pid = process.pid, startedAt = PROCESS_STARTED_AT, installed = readInstalledVersion, repairing = false) {
31
31
  return {
32
32
  name: PACKAGE_NAME,
33
33
  version,
34
34
  pid,
35
35
  startedAt: new Date(startedAt).toISOString(),
36
36
  installedVersion: installed(),
37
+ repairing,
37
38
  };
38
39
  }
39
- /** The bridge's plain-HTTP handler: `/version` or 404. */
40
- export function handleBridgeHttpRequest(req, res, version) {
40
+ /** `127.0.0.1`, `localhost` or `[::1]`, each with an optional port. */
41
+ const LOOPBACK_HOST = /^(?:127\.0\.0\.1|localhost|\[::1\])(?::\d{1,5})?$/i;
42
+ /** Whether a request's `Host` header names this machine's loopback. A web
43
+ * page reaching the port through DNS rebinding carries its own host name,
44
+ * so it never reads the pid and versions. */
45
+ export function isLoopbackHost(host) {
46
+ return host !== undefined && LOOPBACK_HOST.test(host);
47
+ }
48
+ /** The bridge's plain-HTTP handler: `/version` (loopback `Host` only, else
49
+ * 403) or 404. `isRepairing` reports a repair hand-off in progress. */
50
+ export function handleBridgeHttpRequest(req, res, version, isRepairing = () => false) {
41
51
  const path = (req.url ?? '').split('?')[0];
42
52
  if (req.method === 'GET' && path === '/version') {
53
+ if (!isLoopbackHost(req.headers.host)) {
54
+ res.writeHead(403, { 'content-type': 'text/plain' });
55
+ res.end('Forbidden');
56
+ return;
57
+ }
43
58
  res.writeHead(200, { 'content-type': 'application/json' });
44
- res.end(JSON.stringify(buildVersionInfo(version)));
59
+ res.end(JSON.stringify(buildVersionInfo(version, undefined, undefined, undefined, isRepairing())));
45
60
  return;
46
61
  }
47
62
  res.writeHead(404, { 'content-type': 'text/plain' });
@@ -1 +1 @@
1
- {"version":3,"file":"version-endpoint.js","sourceRoot":"","sources":["../../src/lifecycle/version-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGnE;;;;;GAKG;AAEH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAW,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEnF,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,OAAe,kBAAkB;IACtE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAW,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAE3F,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,MAAc,OAAO,CAAC,GAAG,EACzB,YAAoB,kBAAkB,EACtC,YAAiC,oBAAoB;IAErD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,OAAO;QACP,GAAG;QACH,SAAS,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAC5C,gBAAgB,EAAE,SAAS,EAAE;KAC9B,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,uBAAuB,CACrC,GAAoB,EACpB,GAAmB,EACnB,OAAe;IAEf,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAChD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"version-endpoint.js","sourceRoot":"","sources":["../../src/lifecycle/version-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGnE;;;;;GAKG;AAEH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAW,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEnF,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,OAAe,kBAAkB;IACtE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAW,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAE3F,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,MAAc,OAAO,CAAC,GAAG,EACzB,YAAoB,kBAAkB,EACtC,YAAiC,oBAAoB,EACrD,SAAS,GAAG,KAAK;IAEjB,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,OAAO;QACP,GAAG;QACH,SAAS,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAC5C,gBAAgB,EAAE,SAAS,EAAE;QAC7B,SAAS;KACV,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,aAAa,GAAG,oDAAoD,CAAC;AAE3E;;6CAE6C;AAC7C,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO,IAAI,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED;uEACuE;AACvE,MAAM,UAAU,uBAAuB,CACrC,GAAoB,EACpB,GAAmB,EACnB,OAAe,EACf,cAA6B,GAAG,EAAE,CAAC,KAAK;IAExC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAChD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC,CAC1F,CAAC;QACF,OAAO;IACT,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
@@ -22,6 +22,12 @@ export function refreshOutdatedBlocks(input) {
22
22
  if (installer === undefined)
23
23
  return s;
24
24
  try {
25
+ // Re-read right before writing: the status may be stale (read at
26
+ // connect time). Only a block that is still ours and still outdated
27
+ // is rewritten; a block the user removed is never re-added.
28
+ const current = installer.detect().state;
29
+ if (current.kind !== 'installed-outdated')
30
+ return { ...s, state: current };
25
31
  installer.install();
26
32
  const after = { ...s, state: installer.detect().state };
27
33
  refreshed.push(after);
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/manual/refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,kBAAkB,EAAiC,MAAM,aAAa,CAAC;AAiBhF,MAAM,UAAU,qBAAqB,CAAC,KAIrC;IACC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACtC,MAAM,SAAS,GAA+B,EAAE,CAAC;IACjD,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACxC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB;YAAE,OAAO,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,KAAK,GAA6B,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;YAClF,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAC,CAAC;YACH,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC;AAED;;;mCAGmC;AACnC,MAAM,UAAU,aAAa,CAAC,MAAqB,EAAE,OAAO,GAAG,OAAO;IACpE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,KAAK,CAAC,IAAI,CACR,wDAAwD,OAAO,QAAQ,KAAK,kCAAkC,CAC/G,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9D,IAAI,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtF,KAAK,CAAC,IAAI,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/manual/refresh.ts"],"names":[],"mappings":"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"}
@@ -37,7 +37,7 @@ export const TOPICS = {
37
37
  },
38
38
  map: {
39
39
  title: 'The persistent map — identifying the app, mechanisms and pitfalls',
40
- body: lines('The map is a private, per-machine SQLite cache of UI structure in the data dir ($XDG_DATA_HOME/browser-link on Linux, ~/Library/Application Support/browser-link on macOS, %APPDATA%/browser-link on Windows; override with $BROWSER_LINK_DATA_DIR). It is never written to a repo.', '- `origin` = scheme://host:port of the tab. `app_key` tells apart apps that share an origin; omit it on the first save (derived from the page title) and fix a poor guess with `browser.map.rename_app`.', '- After a non-trivial flow worked end-to-end, `browser.map.save` the selectors you just executed, optionally with `flows` recipes that use placeholders (`<QUERY>`, `<NAME>`) for every free-text value.', '- Save how the app behaves underneath too: `mechanisms: [{ key, description }]` ("a GET of an item URL marks it complete server-side") and `pitfalls: [{ key, description, symptom? }]` ("click on the next link returns ok but does not navigate"). A pitfall costs far more to rediscover than a selector; `recall` returns pitfalls first.', '- A `find` single match carries `semantic_key`. When the selector you save is structural (`:nth-of-type`), save that `semantic_key` in the payload next to it, and use `browser.find({ key })` when recall returns `prefer: "semantic_key"`. Never save a key for an `ambiguous` entry.', '- Never save a `ref` (refs die with the document) or an `ambiguous` selector, and never domain data: no IDs, names, dates or real values.'),
40
+ body: lines('The map is a private per-machine SQLite cache of UI structure in the data dir ($BROWSER_LINK_DATA_DIR overrides it), never in a repo.', '- `origin` = scheme://host:port of the tab. `app_key` tells apart apps that share an origin; omit it on the first save (from the page title) and fix a poor guess with `browser.map.rename_app`.', '- After a non-trivial flow worked end-to-end, `browser.map.save` the selectors you just executed, optionally with `flows` recipes that use placeholders (`<QUERY>`, `<NAME>`) for every free-text value.', '- Save how the app behaves underneath too: `mechanisms: [{ key, description }]` ("a GET of an item URL marks it complete server-side") and `pitfalls: [{ key, description, symptom? }]` ("click on the next link returns ok but does not navigate"). A pitfall costs far more to rediscover than a selector; `recall` returns pitfalls first.', '- A `find` single match carries `semantic_key`. When the selector you save is structural (`:nth-of-type`), save that `semantic_key` in the payload next to it, and use `browser.find({ key })` when recall returns `prefer: "semantic_key"`. Never save a key for an `ambiguous` entry.', '- Never save a `ref` or an `ambiguous` selector, and never domain data: no IDs, names, dates or real values.', '- It learns alone: `recall`/`list_tabs` show `learned` counts per selector or `find` key, failed first: avoid those. Never values. Off: `browser-link config set map-learning off`.'),
41
41
  },
42
42
  'token-efficiency': {
43
43
  title: 'Token-efficient patterns and reading data',
@@ -45,7 +45,7 @@ export const TOPICS = {
45
45
  },
46
46
  'multi-agent': {
47
47
  title: 'Sharing tabs with other agents (multi-agent mode)',
48
- body: lines('Several MCP clients can share one bridge; a cooperative claim layer keeps two agents off the same tab.', '- Action tools (`browser.click`, `browser.type`, `browser.navigate`, `browser.evaluate`) auto-claim a free tab on first use. If another agent holds it they fail naming the owner: ask the user whose tab it is, or use a different one.', '- Read tools (`browser.snapshot`, `browser.state`, `browser.console`, `browser.network`, `browser.network_body`, `browser.events`, `browser.ping`) ignore claims.', '- Give `browser.claim_tab` a stable `label` ("claude-code", "opencode"); claims also end on disconnect and after the inactivity TTL. The label is display only: ownership rests on the IPC session id, not on what an agent calls itself.', '- One server process is the primary. A newer browser-link that starts displaces an older primary (it reads `GET /version` on the bridge port, then stops the old process), and the extension reconnects by itself.', '- A `list_tabs` hint "server running X, installed Y" means the package was updated under a live server: ask the user to run `browser-link stop` and restart the agent, or to click "Repair connection" in the extension popup. Do not kill processes yourself.'),
48
+ body: lines('Several MCP clients can share one bridge; a cooperative claim layer keeps two agents off the same tab.', '- Action tools (`browser.click`, `browser.type`, `browser.navigate`, `browser.evaluate`) auto-claim a free tab on first use. If another agent holds it they fail naming the owner: ask the user whose tab it is, or use a different one.', '- Read tools (`browser.snapshot`, `browser.state`, `browser.console`, `browser.network`, `browser.network_body`, `browser.events`, `browser.ping`) ignore claims.', '- Give `browser.claim_tab` a stable `label` ("claude-code", "opencode"); claims also end on disconnect and after the inactivity TTL. The label is display only: ownership rests on the IPC session id, not on what an agent calls itself.', '- One server process is the primary. A newer browser-link that starts displaces an older primary (it reads `GET /version` on the bridge port, then stops the old process), and the extension reconnects by itself.', '- `browser.activity({ summary: true })` is the friction report: errors and flagged calls (`not-found`, `unsettled`, flow or download `timeout`...) by flag, by tool, top failing selectors and one line per agent session; narrow it with `since`, `since_id` or `agent_id`.', '- A `list_tabs` hint "server running X, installed Y" means the package was updated under a live server: ask the user to run `browser-link stop` and restart the agent, or to click "Repair connection" in the extension popup. Do not kill processes yourself.'),
49
49
  },
50
50
  'cdp-direct': {
51
51
  title: 'cdp-direct tabs (optional, off by default, human-gated)',
@@ -1 +1 @@
1
- {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../src/manual/topics.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,KAAK;IACL,kBAAkB;IAClB,aAAa;IACb,YAAY;CACJ,CAAC;AASX,MAAM,KAAK,GAAG,CAAC,GAAG,CAAW,EAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEvD,MAAM,CAAC,MAAM,MAAM,GAA6B;IAC9C,SAAS,EAAE;QACT,KAAK,EAAE,2CAA2C;QAClD,IAAI,EAAE,KAAK,CACT,kOAAkO,EAClO,+OAA+O,EAC/O,0EAA0E,EAC1E,uHAAuH,CACxH;KACF;IACD,MAAM,EAAE;QACN,KAAK,EAAE,0DAA0D;QACjE,IAAI,EAAE,KAAK,CACT,+OAA+O,EAC/O,oPAAoP,EACpP,oSAAoS,CACrS;KACF;IACD,UAAU,EAAE;QACV,KAAK,EAAE,mCAAmC;QAC1C,IAAI,EAAE,KAAK,CACT,wKAAwK,EACxK,oLAAoL,EACpL,oFAAoF,CACrF;KACF;IACD,KAAK,EAAE;QACL,KAAK,EAAE,wDAAwD;QAC/D,IAAI,EAAE,KAAK,CACT,gaAAga,EACha,EAAE,EACF,iJAAiJ,EACjJ,6HAA6H,EAC7H,iOAAiO,EACjO,gWAAgW,EAChW,qIAAqI,EACrI,sXAAsX,EACtX,kMAAkM,EAClM,EAAE,EACF,6aAA6a,EAC7a,EAAE,EACF,2XAA2X,EAC3X,kNAAkN,EAClN,qGAAqG,EACrG,uGAAuG,EACvG,mLAAmL,CACpL;KACF;IACD,GAAG,EAAE;QACH,KAAK,EAAE,mEAAmE;QAC1E,IAAI,EAAE,KAAK,CACT,qRAAqR,EACrR,0MAA0M,EAC1M,0MAA0M,EAC1M,+UAA+U,EAC/U,yRAAyR,EACzR,2IAA2I,CAC5I;KACF;IACD,kBAAkB,EAAE;QAClB,KAAK,EAAE,2CAA2C;QAClD,IAAI,EAAE,KAAK,CACT,kGAAkG,EAClG,qRAAqR,EACrR,iJAAiJ,EACjJ,gNAAgN,EAChN,wFAAwF,EACxF,2HAA2H,EAC3H,iGAAiG,EACjG,sPAAsP,EACtP,uaAAua,EACva,sQAAsQ,EACtQ,+HAA+H,EAC/H,2QAA2Q,EAC3Q,oNAAoN,CACrN;KACF;IACD,aAAa,EAAE;QACb,KAAK,EAAE,mDAAmD;QAC1D,IAAI,EAAE,KAAK,CACT,wGAAwG,EACxG,0OAA0O,EAC1O,mKAAmK,EACnK,2OAA2O,EAC3O,oNAAoN,EACpN,gQAAgQ,CACjQ;KACF;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,yDAAyD;QAChE,IAAI,EAAE,KAAK,CACT,yOAAyO,EACzO,gIAAgI,EAChI,qHAAqH,EACrH,0GAA0G,CAC3G;KACF;CACF,CAAC;AAEF,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,IAAe;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../src/manual/topics.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,KAAK;IACL,kBAAkB;IAClB,aAAa;IACb,YAAY;CACJ,CAAC;AASX,MAAM,KAAK,GAAG,CAAC,GAAG,CAAW,EAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEvD,MAAM,CAAC,MAAM,MAAM,GAA6B;IAC9C,SAAS,EAAE;QACT,KAAK,EAAE,2CAA2C;QAClD,IAAI,EAAE,KAAK,CACT,kOAAkO,EAClO,+OAA+O,EAC/O,0EAA0E,EAC1E,uHAAuH,CACxH;KACF;IACD,MAAM,EAAE;QACN,KAAK,EAAE,0DAA0D;QACjE,IAAI,EAAE,KAAK,CACT,+OAA+O,EAC/O,oPAAoP,EACpP,oSAAoS,CACrS;KACF;IACD,UAAU,EAAE;QACV,KAAK,EAAE,mCAAmC;QAC1C,IAAI,EAAE,KAAK,CACT,wKAAwK,EACxK,oLAAoL,EACpL,oFAAoF,CACrF;KACF;IACD,KAAK,EAAE;QACL,KAAK,EAAE,wDAAwD;QAC/D,IAAI,EAAE,KAAK,CACT,gaAAga,EACha,EAAE,EACF,iJAAiJ,EACjJ,6HAA6H,EAC7H,iOAAiO,EACjO,gWAAgW,EAChW,qIAAqI,EACrI,sXAAsX,EACtX,kMAAkM,EAClM,EAAE,EACF,6aAA6a,EAC7a,EAAE,EACF,2XAA2X,EAC3X,kNAAkN,EAClN,qGAAqG,EACrG,uGAAuG,EACvG,mLAAmL,CACpL;KACF;IACD,GAAG,EAAE;QACH,KAAK,EAAE,mEAAmE;QAC1E,IAAI,EAAE,KAAK,CACT,uIAAuI,EACvI,kMAAkM,EAClM,0MAA0M,EAC1M,+UAA+U,EAC/U,yRAAyR,EACzR,8GAA8G,EAC9G,qLAAqL,CACtL;KACF;IACD,kBAAkB,EAAE;QAClB,KAAK,EAAE,2CAA2C;QAClD,IAAI,EAAE,KAAK,CACT,kGAAkG,EAClG,qRAAqR,EACrR,iJAAiJ,EACjJ,gNAAgN,EAChN,wFAAwF,EACxF,2HAA2H,EAC3H,iGAAiG,EACjG,sPAAsP,EACtP,uaAAua,EACva,sQAAsQ,EACtQ,+HAA+H,EAC/H,2QAA2Q,EAC3Q,oNAAoN,CACrN;KACF;IACD,aAAa,EAAE;QACb,KAAK,EAAE,mDAAmD;QAC1D,IAAI,EAAE,KAAK,CACT,wGAAwG,EACxG,0OAA0O,EAC1O,mKAAmK,EACnK,2OAA2O,EAC3O,oNAAoN,EACpN,8QAA8Q,EAC9Q,gQAAgQ,CACjQ;KACF;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,yDAAyD;QAChE,IAAI,EAAE,KAAK,CACT,yOAAyO,EACzO,gIAAgI,EAChI,qHAAqH,EACrH,0GAA0G,CAC3G;KACF;CACF,CAAC;AAEF,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,IAAe;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC"}
package/dist/map/db.js CHANGED
@@ -121,6 +121,32 @@ function runMigrations(db) {
121
121
  );
122
122
 
123
123
  CREATE INDEX IF NOT EXISTS idx_insights_app ON insights(app_id);
124
+ `);
125
+ // v0.43.0: what the map learned from use, with no bookkeeping by the agent
126
+ // (see map/learning.ts). One row per durable target (a CSS selector or a
127
+ // `browser.find` semantic key, never typed text or values) per action per
128
+ // route, with ok/fail counters. Additive CREATE-IF-NOT-EXISTS like every
129
+ // table above: an older DB picks it up on next open, no row is rewritten.
130
+ // `last_reason` holds a fixed enum (`LEARNED_REASONS` in learning.ts),
131
+ // enforced in code rather than by a CHECK, so widening the enum later
132
+ // never means rebuilding this table (see the `insights` comment).
133
+ db.exec(`
134
+ CREATE TABLE IF NOT EXISTS selector_outcomes (
135
+ id INTEGER PRIMARY KEY,
136
+ app_id INTEGER NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
137
+ url_pattern TEXT NOT NULL,
138
+ target TEXT NOT NULL,
139
+ target_kind TEXT NOT NULL CHECK (target_kind IN ('selector', 'key')),
140
+ action TEXT NOT NULL,
141
+ ok_n INTEGER NOT NULL DEFAULT 0,
142
+ fail_n INTEGER NOT NULL DEFAULT 0,
143
+ last_reason TEXT,
144
+ last_ok_at TEXT,
145
+ last_fail_at TEXT,
146
+ UNIQUE(app_id, url_pattern, target, target_kind, action)
147
+ );
148
+
149
+ CREATE INDEX IF NOT EXISTS idx_selector_outcomes_app ON selector_outcomes(app_id);
124
150
  `);
125
151
  // v0.20.0: normalize apps.origin rows written before the write path
126
152
  // canonicalized origins (see origin.ts). Before this release, save
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/map/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type Database from 'better-sqlite3';
2
+ /**
3
+ * The map learns from use.
4
+ *
5
+ * Every click/type/press/find/wait_for an agent dispatches already tells us
6
+ * whether a target worked: a thrown `retargeted`, a `find` that resolved with
7
+ * `matched: false`, a click whose `expect` was met. Until now that evidence
8
+ * died with the tool result. This module turns it into ok/fail counters per
9
+ * durable target in the map DB (`selector_outcomes`, see db.ts), so the
10
+ * `list_tabs` hint and `browser.map.recall` can say "this selector failed
11
+ * here before" without the agent doing any bookkeeping.
12
+ *
13
+ * Privacy rule: the stored target is the CSS selector string or the
14
+ * `browser.find` semantic key, and nothing else. Typed text, evaluate
15
+ * expressions, key names and any other value an action carried are never
16
+ * read here.
17
+ *
18
+ * Two layers:
19
+ * - `classifyOutcome` is pure: (tool, args, result, error) → verdict.
20
+ * - `recordOutcome` persists one verdict; `learnFromDispatch` is the glue
21
+ * the dispatcher's `recordOutcome` dep calls, gated by the config switch.
22
+ */
23
+ /** The fixed failure vocabulary. `last_reason` never holds anything else. */
24
+ export declare const LEARNED_REASONS: readonly ["retargeted", "ref-stale", "expect-failed", "not-found", "multiple-matches", "unmatched", "timeout", "unsettled", "hit-mismatch"];
25
+ export type LearnedReason = (typeof LEARNED_REASONS)[number];
26
+ export type LearnedOutcome = {
27
+ ok: true;
28
+ } | {
29
+ ok: false;
30
+ reason: LearnedReason;
31
+ };
32
+ export type TargetKind = 'selector' | 'key';
33
+ /** Rows kept per app. Past it, the least used row is evicted. */
34
+ export declare const MAX_LEARNED_PER_APP = 200;
35
+ /**
36
+ * Classify one dispatched call.
37
+ *
38
+ * Returns `{ ok: true }`, `{ ok: false, reason }`, or null when there is
39
+ * nothing to learn: a tool outside click/type/press/find/wait_for, a call
40
+ * without a durable target, or a result that proves neither success nor
41
+ * failure (a quiet click with no `expect`: quiet is not effect).
42
+ */
43
+ export declare function classifyOutcome(tool: string, args: unknown, result: unknown, error: unknown): LearnedOutcome | null;
44
+ export interface RecordOutcomeInput {
45
+ origin: string;
46
+ pathname: string;
47
+ target: string;
48
+ target_kind: TargetKind;
49
+ action: string;
50
+ outcome: LearnedOutcome;
51
+ }
52
+ /**
53
+ * Persist one verdict: upsert the counters of the (app, route, target,
54
+ * kind, action) row, then enforce the per-app cap.
55
+ *
56
+ * The app is resolved by `resolveLearnerApp`: the most recently seen app
57
+ * of the origin (the one `list_tabs` and `recall` show), left untouched,
58
+ * or a new app keyed by the origin host when the origin has none. The tab
59
+ * title is never an input: a title such as "Inbox (3) - My App" would mint
60
+ * a fresh app that then hides the saved map.
61
+ */
62
+ export declare function recordOutcome(db: Database.Database, input: RecordOutcomeInput): void;
63
+ /** What the dispatcher hands the learner after a call settles. */
64
+ export interface DispatchOutcomeContext {
65
+ tool: string;
66
+ args: unknown;
67
+ result: unknown;
68
+ error: unknown;
69
+ /** The tab's URL after the call, from the live tab table. */
70
+ url: string | null;
71
+ /** The tab's title. Part of the dispatcher contract but deliberately
72
+ * ignored by the learner: it never resolves apps from or stores titles. */
73
+ title: string | null;
74
+ }
75
+ /**
76
+ * The dispatcher's `recordOutcome` dep in production (wired in server.ts).
77
+ * Classifies first, so calls with nothing to learn cost no config read and
78
+ * no DB access; then honours the `mapLearningEnabled` switch, read on every
79
+ * call so `browser-link config set map-learning off` applies at once.
80
+ */
81
+ export declare function learnFromDispatch(ctx: DispatchOutcomeContext): void;