@jobshimo/browser-link 0.8.2 → 0.9.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 (116) hide show
  1. package/dist/agent-instructions/content.js +42 -27
  2. package/dist/agent-instructions/content.js.map +1 -1
  3. package/dist/agent-instructions/file-ops.js +7 -2
  4. package/dist/agent-instructions/file-ops.js.map +1 -1
  5. package/dist/bridge/events.d.ts +3 -0
  6. package/dist/bridge/events.js +8 -0
  7. package/dist/bridge/events.js.map +1 -1
  8. package/dist/commands/doctor.js +30 -1
  9. package/dist/commands/doctor.js.map +1 -1
  10. package/dist/commands/update-check.d.ts +25 -0
  11. package/dist/commands/update-check.js +108 -0
  12. package/dist/commands/update-check.js.map +1 -0
  13. package/dist/commands/welcome.d.ts +15 -0
  14. package/dist/commands/welcome.js +44 -2
  15. package/dist/commands/welcome.js.map +1 -1
  16. package/dist/extension/background.js +37 -1
  17. package/dist/extension/background.js.map +1 -1
  18. package/dist/extension/manifest.json +1 -1
  19. package/dist/extension/popup.d.ts +2 -1
  20. package/dist/extension/popup.html +128 -50
  21. package/dist/extension/popup.js +22 -3
  22. package/dist/extension/popup.js.map +1 -1
  23. package/dist/map/tools.d.ts +1 -5
  24. package/dist/map/tools.js +45 -0
  25. package/dist/map/tools.js.map +1 -1
  26. package/dist/server.js +42 -36
  27. package/dist/server.js.map +1 -1
  28. package/dist/tools/browser-definitions.d.ts +6 -0
  29. package/dist/tools/browser-definitions.js +150 -0
  30. package/dist/tools/browser-definitions.js.map +1 -1
  31. package/dist/tools/browser-dispatch.d.ts +8 -14
  32. package/dist/tools/browser-dispatch.js +10 -0
  33. package/dist/tools/browser-dispatch.js.map +1 -1
  34. package/dist/tools/server-instructions.d.ts +16 -2
  35. package/dist/tools/server-instructions.js +87 -68
  36. package/dist/tools/server-instructions.js.map +1 -1
  37. package/dist/tools/tab-claims.d.ts +5 -1
  38. package/dist/tools/tab-claims.js +17 -0
  39. package/dist/tools/tab-claims.js.map +1 -1
  40. package/dist/tools/types.d.ts +26 -1
  41. package/dist/ui/app.js +40 -5
  42. package/dist/ui/app.js.map +1 -1
  43. package/dist/ui/components.d.ts +15 -3
  44. package/dist/ui/components.js +34 -14
  45. package/dist/ui/components.js.map +1 -1
  46. package/dist/ui/hooks/use-update-check.d.ts +16 -0
  47. package/dist/ui/hooks/use-update-check.js +48 -0
  48. package/dist/ui/hooks/use-update-check.js.map +1 -0
  49. package/dist/ui/primitives/badge.d.ts +11 -0
  50. package/dist/ui/primitives/badge.js +35 -0
  51. package/dist/ui/primitives/badge.js.map +1 -0
  52. package/dist/ui/primitives/check-row.d.ts +11 -0
  53. package/dist/ui/primitives/check-row.js +10 -0
  54. package/dist/ui/primitives/check-row.js.map +1 -0
  55. package/dist/ui/primitives/footer-keys.d.ts +12 -0
  56. package/dist/ui/primitives/footer-keys.js +11 -0
  57. package/dist/ui/primitives/footer-keys.js.map +1 -0
  58. package/dist/ui/primitives/index.d.ts +8 -0
  59. package/dist/ui/primitives/index.js +13 -0
  60. package/dist/ui/primitives/index.js.map +1 -0
  61. package/dist/ui/primitives/inline-spinner.d.ts +7 -0
  62. package/dist/ui/primitives/inline-spinner.js +23 -0
  63. package/dist/ui/primitives/inline-spinner.js.map +1 -0
  64. package/dist/ui/primitives/key-cap.d.ts +6 -0
  65. package/dist/ui/primitives/key-cap.js +6 -0
  66. package/dist/ui/primitives/key-cap.js.map +1 -0
  67. package/dist/ui/primitives/menu-row.d.ts +17 -0
  68. package/dist/ui/primitives/menu-row.js +8 -0
  69. package/dist/ui/primitives/menu-row.js.map +1 -0
  70. package/dist/ui/primitives/section-head.d.ts +11 -0
  71. package/dist/ui/primitives/section-head.js +7 -0
  72. package/dist/ui/primitives/section-head.js.map +1 -0
  73. package/dist/ui/primitives/status-bar.d.ts +13 -0
  74. package/dist/ui/primitives/status-bar.js +17 -0
  75. package/dist/ui/primitives/status-bar.js.map +1 -0
  76. package/dist/ui/screens/about.js +13 -4
  77. package/dist/ui/screens/about.js.map +1 -1
  78. package/dist/ui/screens/agent-instructions.d.ts +7 -1
  79. package/dist/ui/screens/agent-instructions.js +62 -46
  80. package/dist/ui/screens/agent-instructions.js.map +1 -1
  81. package/dist/ui/screens/client-picker.js +64 -16
  82. package/dist/ui/screens/client-picker.js.map +1 -1
  83. package/dist/ui/screens/doctor.js +20 -7
  84. package/dist/ui/screens/doctor.js.map +1 -1
  85. package/dist/ui/screens/empty-clients.d.ts +8 -0
  86. package/dist/ui/screens/empty-clients.js +57 -0
  87. package/dist/ui/screens/empty-clients.js.map +1 -0
  88. package/dist/ui/screens/extension.js +25 -8
  89. package/dist/ui/screens/extension.js.map +1 -1
  90. package/dist/ui/screens/free-port.js +48 -33
  91. package/dist/ui/screens/free-port.js.map +1 -1
  92. package/dist/ui/screens/index.d.ts +2 -0
  93. package/dist/ui/screens/index.js +2 -0
  94. package/dist/ui/screens/index.js.map +1 -1
  95. package/dist/ui/screens/install-result.js +29 -6
  96. package/dist/ui/screens/install-result.js.map +1 -1
  97. package/dist/ui/screens/language.js +39 -18
  98. package/dist/ui/screens/language.js.map +1 -1
  99. package/dist/ui/screens/menu.d.ts +10 -1
  100. package/dist/ui/screens/menu.js +118 -30
  101. package/dist/ui/screens/menu.js.map +1 -1
  102. package/dist/ui/screens/multi-agent.js +24 -18
  103. package/dist/ui/screens/multi-agent.js.map +1 -1
  104. package/dist/ui/screens/permissions.js +145 -33
  105. package/dist/ui/screens/permissions.js.map +1 -1
  106. package/dist/ui/screens/port-collision.d.ts +18 -0
  107. package/dist/ui/screens/port-collision.js +95 -0
  108. package/dist/ui/screens/port-collision.js.map +1 -0
  109. package/dist/ui/screens/updates.js +44 -21
  110. package/dist/ui/screens/updates.js.map +1 -1
  111. package/dist/ui/screens/welcome.js +56 -26
  112. package/dist/ui/screens/welcome.js.map +1 -1
  113. package/dist/ui/tokens.d.ts +37 -0
  114. package/dist/ui/tokens.js +58 -0
  115. package/dist/ui/tokens.js.map +1 -0
  116. package/package.json +1 -1
@@ -1,43 +1,91 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import { useState } from 'react';
4
- import { Frame, Menu } from '../components.js';
4
+ import { Frame } from '../components.js';
5
+ import { GLYPHS } from '../tokens.js';
6
+ import { Badge, FooterKeys, MenuRow } from '../primitives/index.js';
5
7
  import { INSTALLERS } from '../../installers/index.js';
6
8
  const PICKER_I18N = {
7
9
  en: {
8
10
  title: 'Register browser-link in…',
9
11
  prompt: 'Which MCP client?',
10
- footer: '↑↓ navigate · register · Esc back',
12
+ refreshHint: 'Re-running install on a registered client refreshes the entry in place.',
13
+ footerNav: 'navigate',
14
+ footerRegister: 'register',
15
+ footerBack: 'back',
16
+ registered: 'registered',
17
+ notRegistered: 'not registered',
18
+ notDetected: 'not detected',
11
19
  },
12
20
  es: {
13
21
  title: 'Registrar browser-link en…',
14
22
  prompt: '¿Qué cliente MCP?',
15
- footer: '↑↓ moverse · registrar · Esc volver',
23
+ refreshHint: 'Volver a correr el install en un cliente registrado refresca la entrada en el lugar.',
24
+ footerNav: 'moverse',
25
+ footerRegister: 'registrar',
26
+ footerBack: 'volver',
27
+ registered: 'registrado',
28
+ notRegistered: 'no registrado',
29
+ notDetected: 'no detectado',
16
30
  },
17
31
  };
32
+ /* Hotkeys: lowercase initial of the client id, stable across languages.
33
+ * `claude` → c, `opencode` → o, `copilot` → p (Copilot starts with 'c'
34
+ * too — fall back to the second-most-distinctive letter, 'p' from
35
+ * "Copilot"). */
36
+ const HOTKEY_BY_CLIENT = {
37
+ claude: 'c',
38
+ opencode: 'o',
39
+ copilot: 'p',
40
+ };
18
41
  export function ClientPicker({ language, onPick, onBack }) {
19
42
  const t = PICKER_I18N[language];
20
- const STATUS = {
21
- en: { registered: 'registered', notRegistered: 'not registered', notDetected: 'not detected' },
22
- es: { registered: 'registrado', notRegistered: 'no registrado', notDetected: 'no detectado' },
23
- };
24
- const s = STATUS[language];
25
- const items = INSTALLERS.map((inst) => {
43
+ const [idx, setIdx] = useState(0);
44
+ /* Build the row payload once per render calling detect() inside
45
+ * the JSX leaks a stat() into every row's diff path. */
46
+ const rows = INSTALLERS.map((inst) => {
26
47
  const d = inst.detect();
27
- const hint = !d.installed ? s.notDetected : d.registered ? s.registered : s.notRegistered;
28
- return { value: inst.id, label: inst.displayName, hint };
48
+ let kind;
49
+ let label;
50
+ if (!d.installed) {
51
+ kind = 'off';
52
+ label = t.notDetected;
53
+ }
54
+ else if (d.registered) {
55
+ kind = 'ok';
56
+ label = t.registered;
57
+ }
58
+ else {
59
+ kind = 'warn';
60
+ label = t.notRegistered;
61
+ }
62
+ return {
63
+ id: inst.id,
64
+ displayName: inst.displayName,
65
+ hotkey: HOTKEY_BY_CLIENT[inst.id],
66
+ badgeKind: kind,
67
+ badgeLabel: label,
68
+ };
29
69
  });
30
- const [idx, setIdx] = useState(0);
31
70
  useInput((input, key) => {
32
71
  if (key.upArrow)
33
- setIdx((i) => (i - 1 + items.length) % items.length);
72
+ setIdx((i) => (i - 1 + rows.length) % rows.length);
34
73
  else if (key.downArrow)
35
- setIdx((i) => (i + 1) % items.length);
74
+ setIdx((i) => (i + 1) % rows.length);
36
75
  else if (key.return)
37
- onPick(items[idx].value);
76
+ onPick(rows[idx].id);
38
77
  else if (input === 'q' || key.escape)
39
78
  onBack();
79
+ else {
80
+ const target = rows.find((r) => r.hotkey === input.toLowerCase());
81
+ if (target)
82
+ onPick(target.id);
83
+ }
40
84
  });
41
- return (_jsxs(Frame, { title: t.title, footer: t.footer, children: [_jsx(Text, { color: "white", bold: true, children: t.prompt }), _jsx(Box, { marginTop: 1, children: _jsx(Menu, { items: items, selectedIndex: idx }) })] }));
85
+ return (_jsxs(Frame, { title: t.title, footer: _jsx(FooterKeys, { items: [
86
+ { k: `${GLYPHS.up}${GLYPHS.down}`, label: t.footerNav },
87
+ { k: GLYPHS.enter, label: t.footerRegister },
88
+ { k: 'Esc', label: t.footerBack },
89
+ ] }), children: [_jsx(Text, { color: "white", bold: true, children: t.prompt }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: rows.map((row, i) => (_jsx(MenuRow, { selected: i === idx, hotkey: row.hotkey, label: row.displayName, badge: _jsx(Badge, { kind: row.badgeKind, label: row.badgeLabel }) }, row.id))) }), _jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { italic: true, dimColor: true, children: t.refreshHint }) })] }));
42
90
  }
43
91
  //# sourceMappingURL=client-picker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-picker.js","sourceRoot":"","sources":["../../../src/ui/screens/client-picker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAiB,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAiB,MAAM,2BAA2B,CAAC;AAQtE,MAAM,WAAW,GAAwE;IACvF,EAAE,EAAE;QACF,KAAK,EAAE,2BAA2B;QAClC,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,qCAAqC;KAC9C;IACD,EAAE,EAAE;QACF,KAAK,EAAE,4BAA4B;QACnC,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,uCAAuC;KAChD;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAqB;IAC1E,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,MAAM,GAGR;QACF,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE;QAC9F,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE;KAC9F,CAAC;IACF,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAyB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1F,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACjE,IAAI,GAAG,CAAC,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aACzD,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;aACzC,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,aACrC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,kBACrB,CAAC,CAAC,MAAM,GACJ,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,GAAI,GACtC,IACA,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"client-picker.js","sourceRoot":"","sources":["../../../src/ui/screens/client-picker.tsx"],"names":[],"mappings":"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"}
@@ -1,20 +1,30 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Text, useInput } from 'ink';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
3
  import { useEffect, useState } from 'react';
4
4
  import { Frame } from '../components.js';
5
+ import { COLORS, GLYPHS } from '../tokens.js';
6
+ import { FooterKeys, InlineSpinner } from '../primitives/index.js';
5
7
  import { runDoctor, formatDoctor } from '../../commands/doctor.js';
8
+ /* Doctor — runs `runDoctor()` and dumps the formatted output.
9
+ *
10
+ * v0.9.0: replace the plain "Diagnosing…" string with an inline spinner
11
+ * so the long-running check feels alive, and adopt the FooterKeys strip
12
+ * for the keybindings. The formatted output itself comes from
13
+ * `formatDoctor()` which is a pre-styled plain string — we render it
14
+ * as-is so the existing tests keep passing.
15
+ */
6
16
  const DOCTOR_I18N = {
7
17
  en: {
8
18
  title: 'Doctor — diagnose current setup',
9
19
  loading: 'Diagnosing…',
10
- refresh: 'r refresh · ↵ / Esc back to menu',
11
- footer: '↵ / Esc back to menu',
20
+ refreshLabel: 'refresh',
21
+ backLabel: 'back to menu',
12
22
  },
13
23
  es: {
14
24
  title: 'Diagnóstico — estado actual de la instalación',
15
25
  loading: 'Diagnosticando…',
16
- refresh: 'r refrescar · ↵ / Esc volver al menú',
17
- footer: '↵ / Esc volver al menú',
26
+ refreshLabel: 'refrescar',
27
+ backLabel: 'volver al menú',
18
28
  },
19
29
  };
20
30
  export function DoctorView({ language, onBack }) {
@@ -38,6 +48,9 @@ export function DoctorView({ language, onBack }) {
38
48
  else if (input === 'r')
39
49
  setRefreshKey((k) => k + 1);
40
50
  });
41
- return (_jsx(Frame, { title: t.title, footer: t.refresh, children: output === null ? _jsx(Text, { color: "gray", children: t.loading }) : _jsx(Text, { children: output }) }));
51
+ return (_jsx(Frame, { title: t.title, footer: _jsx(FooterKeys, { items: [
52
+ { k: 'r', label: t.refreshLabel },
53
+ { k: GLYPHS.enter, label: t.backLabel },
54
+ ] }), children: output === null ? (_jsxs(Box, { children: [_jsx(InlineSpinner, {}), _jsx(Text, { color: COLORS.muted, children: ` ${t.loading}` })] })) : (_jsx(Text, { children: output })) }));
42
55
  }
43
56
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/ui/screens/doctor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,GAGb;IACF,EAAE,EAAE;QACF,KAAK,EAAE,iCAAiC;QACxC,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,kCAAkC;QAC3C,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,KAAK,EAAE,+CAA+C;QACtD,OAAO,EAAE,iBAAiB;QAC1B,OAAO,EAAE,sCAAsC;QAC/C,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAMF,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAmB;IAC9D,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1B,IAAI,CAAC,SAAS;gBAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAClC,IAAI,KAAK,KAAK,GAAG;YAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,YACrC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,CAAC,CAAC,OAAO,GAAQ,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,MAAM,GAAQ,GAC1E,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/ui/screens/doctor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,WAAW,GAGb;IACF,EAAE,EAAE;QACF,KAAK,EAAE,iCAAiC;QACxC,OAAO,EAAE,aAAa;QACtB,YAAY,EAAE,SAAS;QACvB,SAAS,EAAE,cAAc;KAC1B;IACD,EAAE,EAAE;QACF,KAAK,EAAE,+CAA+C;QACtD,OAAO,EAAE,iBAAiB;QAC1B,YAAY,EAAE,WAAW;QACzB,SAAS,EAAE,gBAAgB;KAC5B;CACF,CAAC;AAMF,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAmB;IAC9D,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1B,IAAI,CAAC,SAAS;gBAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;aAClC,IAAI,KAAK,KAAK,GAAG;YAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,MAAM,EACJ,KAAC,UAAU,IACT,KAAK,EAAE;gBACL,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE;gBACjC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE;aACxC,GACD,YAGH,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACjB,MAAC,GAAG,eACF,KAAC,aAAa,KAAG,EACjB,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,YAAG,IAAI,CAAC,CAAC,OAAO,EAAE,GAAQ,IAC/C,CACP,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,cAAE,MAAM,GAAQ,CACtB,GACK,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { CommonProps } from './types.js';
2
+ interface EmptyClientsViewProps extends CommonProps {
3
+ onRescan: () => void;
4
+ onOpenRepo: () => void;
5
+ onBack: () => void;
6
+ }
7
+ export declare function EmptyClientsView({ language, onRescan, onOpenRepo, onBack, }: EmptyClientsViewProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { Frame } from '../components.js';
4
+ import { COLORS, GLYPHS } from '../tokens.js';
5
+ import { FooterKeys, SectionHead } from '../primitives/index.js';
6
+ /* Empty clients — the "no MCP clients detected" state shown when
7
+ * register would otherwise have rendered an unusable picker.
8
+ *
9
+ * Design source: states.jsx → StateEmpty.
10
+ *
11
+ * Triggered when none of the supported MCP installers' `detect().installed`
12
+ * returns true. The screen tells the user which clients are supported
13
+ * and where to install them, then offers rescan / back as the only
14
+ * forward actions.
15
+ */
16
+ const EMPTY_I18N = {
17
+ en: {
18
+ title: 'Register browser-link in…',
19
+ headline: 'No MCP clients detected on this machine.',
20
+ sub: 'Install one of the supported clients, then re-run browser-link.',
21
+ supportedHeader: 'Supported clients',
22
+ rescan: 'rescan',
23
+ openRepo: 'open repo',
24
+ back: 'back',
25
+ },
26
+ es: {
27
+ title: 'Registrar browser-link en…',
28
+ headline: 'No se detectó ningún cliente MCP en esta máquina.',
29
+ sub: 'Instalá alguno de los clientes soportados y volvé a correr browser-link.',
30
+ supportedHeader: 'Clientes soportados',
31
+ rescan: 'reescanear',
32
+ openRepo: 'abrir repo',
33
+ back: 'volver',
34
+ },
35
+ };
36
+ const SUPPORTED = [
37
+ { name: 'Claude Code', where: 'claude.ai/code' },
38
+ { name: 'OpenCode', where: 'opencode.ai' },
39
+ { name: 'GitHub Copilot CLI', where: 'gh extension install github/gh-copilot' },
40
+ ];
41
+ export function EmptyClientsView({ language, onRescan, onOpenRepo, onBack, }) {
42
+ const t = EMPTY_I18N[language];
43
+ useInput((input, key) => {
44
+ if (input === 'r')
45
+ onRescan();
46
+ else if (input === 'g')
47
+ onOpenRepo();
48
+ else if (key.escape || key.return || input === 'q')
49
+ onBack();
50
+ });
51
+ return (_jsxs(Frame, { title: t.title, footer: _jsx(FooterKeys, { items: [
52
+ { k: 'r', label: t.rescan },
53
+ { k: 'g', label: t.openRepo },
54
+ { k: 'Esc', label: t.back },
55
+ ] }), children: [_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { color: COLORS.muted, children: `${GLYPHS.dot} ${GLYPHS.dot} ${GLYPHS.dot}` }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "white", bold: true, children: t.headline }) }), _jsx(Text, { color: COLORS.muted, dimColor: true, children: t.sub }), _jsx(SectionHead, { children: t.supportedHeader }), SUPPORTED.map((c) => (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { children: [_jsx(Text, { color: "white", children: `${GLYPHS.dot} ${c.name}` }), _jsx(Text, { color: COLORS.muted, children: ' ' }), _jsx(Text, { color: COLORS.primary, children: c.where })] }) }, c.name)))] }));
56
+ }
57
+ //# sourceMappingURL=empty-clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-clients.js","sourceRoot":"","sources":["../../../src/ui/screens/empty-clients.tsx"],"names":[],"mappings":"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"}
@@ -1,23 +1,37 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import { Frame } from '../components.js';
4
+ import { COLORS, GLYPHS } from '../tokens.js';
5
+ import { FooterKeys, SectionHead } from '../primitives/index.js';
4
6
  import { getExtensionInfo } from '../../commands/extension.js';
7
+ /* Chrome extension — install steps. v0.9.0 layout:
8
+ * - "Extension assets are at" → path in cyan, indented.
9
+ * - "Steps" header, then the existing numbered-line steps split into
10
+ * row-per-step rendering with cyan-bold ordinals.
11
+ * - Trailing italic dim note about activation, footer via FooterKeys.
12
+ *
13
+ * The actual step text is generated by `getExtensionInfo().hints` (which
14
+ * is already a numbered, multi-line string) — we keep that text intact
15
+ * and only restyle the surrounding chrome.
16
+ */
5
17
  const EXT_I18N = {
6
18
  en: {
7
19
  title: 'Chrome extension — install steps',
8
- pathLabel: 'Extension assets are at:',
9
- stepsLabel: 'Install steps:',
20
+ pathLabel: 'Extension assets are at',
21
+ stepsLabel: 'Steps',
10
22
  afterLoading: 'After loading, open the extension popup on any tab and click "Conectar" to bridge it.',
11
23
  notFound: 'Extension assets not found. Run `npm run build:extension` (dev) or reinstall the package.',
12
- footer: '↵ / Esc back to menu',
24
+ footerBack: 'back to menu',
25
+ footerBackKey: 'back',
13
26
  },
14
27
  es: {
15
28
  title: 'Extensión de Chrome — pasos de instalación',
16
- pathLabel: 'Los assets de la extensión están en:',
17
- stepsLabel: 'Pasos:',
29
+ pathLabel: 'Los assets de la extensión están en',
30
+ stepsLabel: 'Pasos',
18
31
  afterLoading: 'Después de cargarla, abrí el popup de la extensión en cualquier pestaña y hacé click en "Conectar" para puentearla.',
19
32
  notFound: 'No se encontraron los assets. Corré `npm run build:extension` (dev) o reinstalá el paquete.',
20
- footer: '↵ / Esc volver al menú',
33
+ footerBack: 'volver al menú',
34
+ footerBackKey: 'volver',
21
35
  },
22
36
  };
23
37
  export function ExtensionView({ language, onBack }) {
@@ -27,6 +41,9 @@ export function ExtensionView({ language, onBack }) {
27
41
  if (key.return || key.escape)
28
42
  onBack();
29
43
  });
30
- return (_jsx(Frame, { title: t.title, footer: t.footer, children: info.path ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: t.pathLabel }), _jsx(Text, { color: "cyan", children: info.path }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: t.stepsLabel }), _jsx(Text, { children: info.hints })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", italic: true, children: t.afterLoading }) })] })) : (_jsx(Text, { color: "yellow", children: t.notFound })) }));
44
+ return (_jsx(Frame, { title: t.title, footer: _jsx(FooterKeys, { items: [
45
+ { k: GLYPHS.enter, label: t.footerBack },
46
+ { k: 'Esc', label: t.footerBackKey },
47
+ ] }), children: info.path ? (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: t.pathLabel }), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: COLORS.primary, children: info.path }) }), _jsx(SectionHead, { children: t.stepsLabel }), _jsx(Text, { children: info.hints }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { italic: true, dimColor: true, children: t.afterLoading }) })] })) : (_jsx(Text, { color: COLORS.warn, children: t.notFound })) }));
31
48
  }
32
49
  //# sourceMappingURL=extension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/ui/screens/extension.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,MAAM,QAAQ,GAUV;IACF,EAAE,EAAE;QACF,KAAK,EAAE,kCAAkC;QACzC,SAAS,EAAE,0BAA0B;QACrC,UAAU,EAAE,gBAAgB;QAC5B,YAAY,EACV,uFAAuF;QACzF,QAAQ,EACN,2FAA2F;QAC7F,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,KAAK,EAAE,4CAA4C;QACnD,SAAS,EAAE,sCAAsC;QACjD,UAAU,EAAE,QAAQ;QACpB,YAAY,EACV,qHAAqH;QACvH,QAAQ,EACN,6FAA6F;QAC/F,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAMF,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAsB;IACpE,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,YACpC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,CAAC,CAAC,SAAS,GAAQ,EAC/B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,IAAI,CAAC,IAAI,GAAQ,EACrC,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,KAAC,IAAI,IAAC,IAAI,kBAAE,CAAC,CAAC,UAAU,GAAQ,EAChC,KAAC,IAAI,cAAE,IAAI,CAAC,KAAK,GAAQ,IACrB,EACN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,MAAM,kBACtB,CAAC,CAAC,YAAY,GACV,GACH,IACL,CACJ,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,CAAC,CAAC,QAAQ,GAAQ,CACzC,GACK,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/ui/screens/extension.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D;;;;;;;;;GASG;AACH,MAAM,QAAQ,GAWV;IACF,EAAE,EAAE;QACF,KAAK,EAAE,kCAAkC;QACzC,SAAS,EAAE,yBAAyB;QACpC,UAAU,EAAE,OAAO;QACnB,YAAY,EACV,uFAAuF;QACzF,QAAQ,EACN,2FAA2F;QAC7F,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,MAAM;KACtB;IACD,EAAE,EAAE;QACF,KAAK,EAAE,4CAA4C;QACnD,SAAS,EAAE,qCAAqC;QAChD,UAAU,EAAE,OAAO;QACnB,YAAY,EACV,qHAAqH;QACvH,QAAQ,EACN,6FAA6F;QAC/F,UAAU,EAAE,gBAAgB;QAC5B,aAAa,EAAE,QAAQ;KACxB;CACF,CAAC;AAMF,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAsB;IACpE,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,MAAM,EACJ,KAAC,UAAU,IACT,KAAK,EAAE;gBACL,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE;gBACxC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE;aACrC,GACD,YAGH,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,CAAC,CAAC,SAAS,GAAQ,EAC/B,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,YACjB,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,YAAG,IAAI,CAAC,IAAI,GAAQ,GAC3C,EACN,KAAC,WAAW,cAAE,CAAC,CAAC,UAAU,GAAe,EACzC,KAAC,IAAI,cAAE,IAAI,CAAC,KAAK,GAAQ,EACzB,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,MAAM,QAAC,QAAQ,kBAClB,CAAC,CAAC,YAAY,GACV,GACH,IACL,CACJ,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,YAAG,CAAC,CAAC,QAAQ,GAAQ,CAC9C,GACK,CACT,CAAC;AACJ,CAAC"}
@@ -1,7 +1,9 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import { useState } from 'react';
4
- import { Frame, Menu } from '../components.js';
4
+ import { Frame } from '../components.js';
5
+ import { COLORS, GLYPHS } from '../tokens.js';
6
+ import { FooterKeys, InlineSpinner, MenuRow, SectionHead } from '../primitives/index.js';
5
7
  import { runFreePort } from '../../commands/free-port.js';
6
8
  const FREE_PORT_I18N = {
7
9
  en: {
@@ -11,16 +13,16 @@ const FREE_PORT_I18N = {
11
13
  'shutting down browser-link cleanly, the next client crashes with',
12
14
  '"port already in use". This screen finds the process holding',
13
15
  '127.0.0.1:17529 and stops it.',
14
- '',
15
- 'Safety: only processes whose image starts with "node" are killed.',
16
- 'Anything else is left alone with an explanation.',
17
16
  ].join('\n'),
17
+ safety: 'Safety: only processes whose image starts with "node" are killed. Anything else is left alone with an explanation.',
18
18
  confirmPrompt: 'Stop the process holding port 17529?',
19
19
  confirmYes: 'Yes — kill it',
20
20
  confirmNo: 'No — back to menu',
21
21
  running: 'Stopping…',
22
- footer: '↑↓ navigate · ↵ select · Esc back',
23
- doneFooter: '↵ / Esc back to menu',
22
+ footerNav: 'navigate',
23
+ footerSelect: 'select',
24
+ footerBack: 'back',
25
+ footerDone: 'back to menu',
24
26
  },
25
27
  es: {
26
28
  title: 'Liberar puerto 17529',
@@ -29,55 +31,68 @@ const FREE_PORT_I18N = {
29
31
  'browser-link de forma limpia, el próximo cliente crashea con',
30
32
  '"port already in use". Esta pantalla busca el proceso que tiene',
31
33
  '127.0.0.1:17529 y lo para.',
32
- '',
33
- 'Seguridad: sólo se matan procesos cuyo nombre empieza con "node".',
34
- 'Cualquier otro se deja vivo con una explicación.',
35
34
  ].join('\n'),
35
+ safety: 'Seguridad: sólo se matan procesos cuyo nombre empieza con "node". Cualquier otro se deja vivo con una explicación.',
36
36
  confirmPrompt: '¿Parar el proceso que tiene el puerto 17529?',
37
37
  confirmYes: 'Sí — matalo',
38
38
  confirmNo: 'No — volver al menú',
39
39
  running: 'Parando…',
40
- footer: '↑↓ moverse · ↵ elegir · Esc volver',
41
- doneFooter: '↵ / Esc volver al menú',
40
+ footerNav: 'moverse',
41
+ footerSelect: 'elegir',
42
+ footerBack: 'volver',
43
+ footerDone: 'volver al menú',
42
44
  },
43
45
  };
44
46
  export function FreePortView({ language, onBack }) {
45
47
  const t = FREE_PORT_I18N[language];
46
48
  const [phase, setPhase] = useState('confirm');
47
49
  const [result, setResult] = useState(null);
48
- const items = [
49
- { value: 'yes', label: t.confirmYes },
50
- { value: 'no', label: t.confirmNo },
50
+ const rows = [
51
+ { value: 'yes', hotkey: 'y', label: t.confirmYes },
52
+ { value: 'no', hotkey: 'n', label: t.confirmNo },
51
53
  ];
54
+ /* Default cursor on "No" — destructive action gates behind an explicit
55
+ * confirmation, matching the previous behaviour. */
52
56
  const [idx, setIdx] = useState(1);
53
- useInput((_input, key) => {
57
+ const confirm = (value) => {
58
+ if (value === 'no') {
59
+ onBack();
60
+ return;
61
+ }
62
+ setPhase('running');
63
+ /* Defer the synchronous kill so Ink renders the "running" phase. */
64
+ setTimeout(() => {
65
+ const r = runFreePort(language);
66
+ setResult(r);
67
+ setPhase('done');
68
+ }, 0);
69
+ };
70
+ useInput((input, key) => {
54
71
  if (phase === 'confirm') {
55
72
  if (key.upArrow)
56
- setIdx((i) => (i - 1 + items.length) % items.length);
73
+ setIdx((i) => (i - 1 + rows.length) % rows.length);
57
74
  else if (key.downArrow)
58
- setIdx((i) => (i + 1) % items.length);
59
- else if (key.return) {
60
- const v = items[idx].value;
61
- if (v === 'no')
62
- onBack();
63
- else {
64
- setPhase('running');
65
- // Defer the synchronous kill so Ink renders the "running" state.
66
- setTimeout(() => {
67
- const r = runFreePort(language);
68
- setResult(r);
69
- setPhase('done');
70
- }, 0);
71
- }
72
- }
75
+ setIdx((i) => (i + 1) % rows.length);
76
+ else if (key.return)
77
+ confirm(rows[idx].value);
73
78
  else if (key.escape)
74
79
  onBack();
80
+ else {
81
+ const target = rows.find((r) => r.hotkey === input.toLowerCase());
82
+ if (target)
83
+ confirm(target.value);
84
+ }
75
85
  }
76
86
  else if (phase === 'done') {
77
87
  if (key.return || key.escape)
78
88
  onBack();
79
89
  }
80
90
  });
81
- return (_jsxs(Frame, { title: t.title, footer: phase === 'done' ? t.doneFooter : t.footer, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: t.intro }) }), phase === 'confirm' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "white", bold: true, children: t.confirmPrompt }), _jsx(Box, { marginTop: 1, children: _jsx(Menu, { items: items, selectedIndex: idx }) })] })), phase === 'running' && _jsx(Text, { color: "gray", children: t.running }), phase === 'done' && result && (_jsx(Text, { color: result.ok ? 'green' : 'yellow', children: result.message }))] }));
91
+ const footer = phase === 'done' ? (_jsx(FooterKeys, { items: [{ k: GLYPHS.enter, label: t.footerDone }] })) : (_jsx(FooterKeys, { items: [
92
+ { k: `${GLYPHS.up}${GLYPHS.down}`, label: t.footerNav },
93
+ { k: GLYPHS.enter, label: t.footerSelect },
94
+ { k: 'Esc', label: t.footerBack },
95
+ ] }));
96
+ return (_jsxs(Frame, { title: t.title, footer: footer, children: [_jsx(Text, { children: t.intro }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: COLORS.warn, children: [GLYPHS.warn, " "] }), _jsx(Text, { children: t.safety })] }), phase === 'confirm' && (_jsxs(_Fragment, { children: [_jsx(SectionHead, { children: t.confirmPrompt }), rows.map((row, i) => (_jsx(MenuRow, { selected: i === idx, hotkey: row.hotkey, label: row.label }, row.value)))] })), phase === 'running' && (_jsxs(Box, { marginTop: 1, children: [_jsx(InlineSpinner, {}), _jsx(Text, { color: COLORS.primary, children: ` ${t.running}` })] })), phase === 'done' && result && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: result.ok ? COLORS.success : COLORS.warn, children: [result.ok ? GLYPHS.success : GLYPHS.warn, " ", result.message] }) }))] }));
82
97
  }
83
98
  //# sourceMappingURL=free-port.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"free-port.js","sourceRoot":"","sources":["../../../src/ui/screens/free-port.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"free-port.js","sourceRoot":"","sources":["../../../src/ui/screens/free-port.tsx"],"names":[],"mappings":"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"}
@@ -11,3 +11,5 @@ export { LanguageView } from './language.js';
11
11
  export { MultiAgentView } from './multi-agent.js';
12
12
  export { FreePortView } from './free-port.js';
13
13
  export { AgentInstructionsView } from './agent-instructions.js';
14
+ export { EmptyClientsView } from './empty-clients.js';
15
+ export { PortCollisionView, type PortCollisionInfo } from './port-collision.js';
@@ -11,4 +11,6 @@ export { LanguageView } from './language.js';
11
11
  export { MultiAgentView } from './multi-agent.js';
12
12
  export { FreePortView } from './free-port.js';
13
13
  export { AgentInstructionsView } from './agent-instructions.js';
14
+ export { EmptyClientsView } from './empty-clients.js';
15
+ export { PortCollisionView } from './port-collision.js';
14
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/screens/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAmB,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/screens/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAmB,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAA0B,MAAM,qBAAqB,CAAC"}
@@ -1,18 +1,34 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import { Frame } from '../components.js';
4
+ import { COLORS, GLYPHS } from '../tokens.js';
5
+ import { Badge, FooterKeys, SectionHead } from '../primitives/index.js';
4
6
  const RESULT_I18N = {
5
7
  en: {
6
8
  ok: 'Registered',
7
9
  warn: 'Not registered',
8
- hint: 'Restart the MCP client so it picks up the new entry.',
9
- footer: ' / Esc back to menu',
10
+ nextStep: 'Next step',
11
+ nextStepBody: 'Restart the MCP client so it picks up the new entry.',
12
+ then: 'Then',
13
+ thenBody: 'Pick',
14
+ thenAction: 'Agent instructions',
15
+ fix: 'Fix',
16
+ fixBody: 'Install the client first, then re-run this screen.',
17
+ footerBack: 'back to menu',
18
+ footerRetry: 'back',
10
19
  },
11
20
  es: {
12
21
  ok: 'Registrado',
13
22
  warn: 'No registrado',
14
- hint: 'Reiniciá el cliente MCP para que tome la nueva entrada.',
15
- footer: ' / Esc volver al menú',
23
+ nextStep: 'Próximo paso',
24
+ nextStepBody: 'Reiniciá el cliente MCP para que tome la nueva entrada.',
25
+ then: 'Después',
26
+ thenBody: 'Elegí',
27
+ thenAction: 'Instrucciones del agente',
28
+ fix: 'Arreglo',
29
+ fixBody: 'Instalá el cliente primero, y volvé a esta pantalla.',
30
+ footerBack: 'volver al menú',
31
+ footerRetry: 'volver',
16
32
  },
17
33
  };
18
34
  export function InstallResultView({ language, report, onBack }) {
@@ -22,6 +38,13 @@ export function InstallResultView({ language, report, onBack }) {
22
38
  onBack();
23
39
  });
24
40
  const ok = report.installedClient;
25
- return (_jsxs(Frame, { title: `${report.displayName} ${ok ? t.ok : t.warn}`, footer: t.footer, children: [_jsxs(Text, { color: ok ? 'green' : 'yellow', children: [ok ? '✓ ' : '⚠ ', report.message] }), ok && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "cyan", children: ["\u2192 ", t.hint] }) }))] }));
41
+ /* Title is the client name followed by a colored status word. We feed
42
+ * the title to Frame as a ReactNode so the colored portion renders
43
+ * inline with the (always-cyan) frame heading style. */
44
+ const title = (_jsxs(Text, { children: [_jsx(Text, { color: COLORS.heading, bold: true, children: report.displayName }), _jsx(Text, { color: COLORS.muted, children: ` ${GLYPHS.dot} ` }), _jsx(Text, { color: ok ? COLORS.success : COLORS.warn, bold: true, children: ok ? t.ok : t.warn })] }));
45
+ return (_jsxs(Frame, { title: title, footer: _jsx(FooterKeys, { items: [
46
+ { k: GLYPHS.enter, label: t.footerBack },
47
+ { k: 'Esc', label: t.footerRetry },
48
+ ] }), children: [_jsx(Box, { children: _jsx(Badge, { kind: ok ? 'ok' : 'warn', label: report.message }) }), ok ? (_jsxs(_Fragment, { children: [_jsx(SectionHead, { children: `${GLYPHS.arrow} ${t.nextStep}` }), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { children: t.nextStepBody }) }), _jsx(SectionHead, { children: `${GLYPHS.arrow} ${t.then}` }), _jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { children: [t.thenBody, ' ', _jsx(Text, { color: COLORS.primary, bold: true, children: t.thenAction }), "."] }) })] })) : (_jsxs(_Fragment, { children: [_jsx(SectionHead, { children: `${GLYPHS.arrow} ${t.fix}` }), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { children: t.fixBody }) })] }))] }));
26
49
  }
27
50
  //# sourceMappingURL=install-result.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install-result.js","sourceRoot":"","sources":["../../../src/ui/screens/install-result.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAUzC,MAAM,WAAW,GAAiF;IAChG,EAAE,EAAE;QACF,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,sDAAsD;QAC5D,MAAM,EAAE,sBAAsB;KAC/B;IACD,EAAE,EAAE;QACF,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,yDAAyD;QAC/D,MAAM,EAAE,wBAAwB;KACjC;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAsB;IAChF,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,MAAM,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC;IAClC,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAE,GAAG,MAAM,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,aAC7E,MAAC,IAAI,IAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,aACjC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAChB,MAAM,CAAC,OAAO,IACV,EACN,EAAE,IAAI,CACL,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAI,CAAC,CAAC,IAAI,IAAQ,GAChC,CACP,IACK,CACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"install-result.js","sourceRoot":"","sources":["../../../src/ui/screens/install-result.tsx"],"names":[],"mappings":"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"}