wisp-agents 0.15.0 → 0.17.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 (122) hide show
  1. package/CHANGELOG.md +55 -1
  2. package/README.md +29 -13
  3. package/bin/wisp.js +3 -2
  4. package/package.json +3 -3
  5. package/server/adapters/antigravity.js +7 -3
  6. package/server/adapters/claude.js +79 -55
  7. package/server/adapters/codex.js +5 -2
  8. package/server/adapters/common.js +14 -34
  9. package/server/adapters/cursor.js +4 -2
  10. package/server/adapters/grok.js +17 -2
  11. package/server/adapters/index.js +25 -2
  12. package/server/adapters/opencode.js +78 -12
  13. package/server/checkpoint.js +12 -68
  14. package/server/client.js +6 -4
  15. package/server/git.js +9 -4
  16. package/server/handoff.js +71 -0
  17. package/server/http/respond.js +59 -0
  18. package/server/http/router.js +64 -0
  19. package/server/http/static.js +36 -0
  20. package/server/index.js +138 -1216
  21. package/server/machines/bootstrap.js +56 -0
  22. package/server/machines/hosts.js +127 -0
  23. package/server/machines.js +7 -179
  24. package/server/mcp-ask.js +113 -8
  25. package/server/mcp-wisp.js +17 -5
  26. package/server/mentions.js +39 -0
  27. package/server/openapi.js +36 -4
  28. package/server/paths.js +32 -0
  29. package/server/preferences.js +2 -6
  30. package/server/proc.js +54 -0
  31. package/server/protocol.js +8 -1
  32. package/server/recipes.js +2 -4
  33. package/server/remote.js +14 -14
  34. package/server/render.js +3 -1
  35. package/server/router.js +7 -3
  36. package/server/routes/auto.js +29 -0
  37. package/server/routes/automations.js +92 -0
  38. package/server/routes/internal.js +176 -0
  39. package/server/routes/machines.js +43 -0
  40. package/server/routes/meta.js +76 -0
  41. package/server/routes/proxy.js +47 -0
  42. package/server/routes/sessions.js +351 -0
  43. package/server/routes/settings.js +144 -0
  44. package/server/routes/ship.js +61 -0
  45. package/server/routes/uploads.js +19 -0
  46. package/server/runner.js +216 -49
  47. package/server/services/auto.js +67 -0
  48. package/server/services/feedback.js +53 -0
  49. package/server/services/install.js +69 -0
  50. package/server/services/launch.js +127 -0
  51. package/server/services/phone.js +65 -0
  52. package/server/services/ship.js +82 -0
  53. package/server/services/telemetry.js +34 -0
  54. package/server/services/uploads.js +59 -0
  55. package/server/services/webhooks.js +28 -0
  56. package/server/store.js +13 -5
  57. package/server/subagents.js +5 -4
  58. package/server/telemetry.js +1 -1
  59. package/server/terminal.js +2 -1
  60. package/server/triggers.js +5 -7
  61. package/server/update.js +4 -3
  62. package/server/usage.js +94 -0
  63. package/server/util.js +42 -0
  64. package/server/welcome.js +3 -3
  65. package/web/css/auto.css +29 -0
  66. package/web/css/automations.css +71 -0
  67. package/web/css/base.css +83 -0
  68. package/web/css/blocks.css +461 -0
  69. package/web/css/composer.css +84 -0
  70. package/web/css/feed.css +235 -0
  71. package/web/css/launcher.css +204 -0
  72. package/web/css/layout.css +61 -0
  73. package/web/css/machines.css +125 -0
  74. package/web/css/modals.css +176 -0
  75. package/web/css/palette.css +79 -0
  76. package/web/css/responsive.css +35 -0
  77. package/web/css/ship.css +95 -0
  78. package/web/css/subagents.css +130 -0
  79. package/web/css/tokens.css +115 -0
  80. package/web/index.html +17 -1
  81. package/web/js/app.js +28 -5237
  82. package/web/js/blocks.js +46 -0
  83. package/web/js/core/api.js +25 -0
  84. package/web/js/core/bus.js +28 -0
  85. package/web/js/core/dom.js +7 -0
  86. package/web/js/core/format.js +27 -0
  87. package/web/js/core/state.js +43 -0
  88. package/web/js/features/actions.js +344 -0
  89. package/web/js/features/attachments.js +115 -0
  90. package/web/js/features/auto.js +54 -0
  91. package/web/js/features/automations.js +305 -0
  92. package/web/js/features/commands.js +123 -0
  93. package/web/js/features/compare.js +105 -0
  94. package/web/js/features/composer.js +315 -0
  95. package/web/js/features/feed.js +400 -0
  96. package/web/js/features/feedback.js +127 -0
  97. package/web/js/features/keys.js +83 -0
  98. package/web/js/features/launcher.js +561 -0
  99. package/web/js/features/live.js +91 -0
  100. package/web/js/features/machines.js +313 -0
  101. package/web/js/features/memory.js +154 -0
  102. package/web/js/features/mentions.js +125 -0
  103. package/web/js/features/notify.js +36 -0
  104. package/web/js/features/phone.js +124 -0
  105. package/web/js/features/places.js +38 -0
  106. package/web/js/features/projects.js +284 -0
  107. package/web/js/features/runner-picker.js +233 -0
  108. package/web/js/features/runners.js +163 -0
  109. package/web/js/features/scroll.js +75 -0
  110. package/web/js/features/settings.js +390 -0
  111. package/web/js/features/setup.js +94 -0
  112. package/web/js/features/ship.js +122 -0
  113. package/web/js/features/team.js +386 -0
  114. package/web/js/features/turns.js +432 -0
  115. package/web/js/features/update.js +48 -0
  116. package/web/js/features/usage.js +75 -0
  117. package/web/js/mention-text.js +59 -0
  118. package/web/js/ui/kbd.js +46 -0
  119. package/web/js/ui/overlay.js +38 -0
  120. package/web/js/ui/popover.js +52 -0
  121. package/web/js/ui/toast.js +23 -0
  122. package/web/css/app.css +0 -1910
@@ -0,0 +1,46 @@
1
+ // Keyboard shortcuts as they read on this OS, how they're matched, and the dialog that lists them.
2
+
3
+ import { el } from '../core/dom.js';
4
+ import { overlay } from './overlay.js';
5
+
6
+ // The keyboard shortcut for a menu item, shown at its right edge. Menus act on the
7
+ // focused card, so the key does the same thing as the click.
8
+ export const keyHint = (k) => `<kbd class="menu-kbd">${k}</kbd>`;
9
+
10
+ export function shortcuts() {
11
+ const rows = [
12
+ [combo('K'), 'Search & commands'],
13
+ [`N · ${combo('L')}`, 'New wisp (focus the launcher)'],
14
+ ['J / K', 'Next / previous item'],
15
+ ['O / ↵', 'Expand / collapse item'],
16
+ ['/', 'Follow up on item'],
17
+ ['E', 'Mark done & go to next'],
18
+ ['A', 'Archive / unarchive'],
19
+ ['M', 'Rename item'],
20
+ ['⌫', 'Delete item'],
21
+ ['T', 'Take over in terminal'],
22
+ ['R', 'Replay presentation'],
23
+ ['⇧R', 'Rerun with another harness, model or thinking level'],
24
+ ['S', 'Ship it: commit, push and open a PR (worktree tasks)'],
25
+ ['1–9', 'Pick an answer when asked'],
26
+ ['↵', 'Launch / send'],
27
+ ['⇧↵', 'New line'],
28
+ ['/feedback', 'Send feedback to the wisp team (in any prompt box)'],
29
+ ['C', 'Collapse all'],
30
+ ['U', 'Back to top'],
31
+ ['Esc', 'Close / collapse'],
32
+ ];
33
+ const node = el(`<div class="modal keys-modal"><header><h2>Shortcuts</h2></header>${rows.map(([k, l]) => `<div class="krow"><kbd>${k}</kbd><span>${l}</span></div>`).join('')}</div>`);
34
+ overlay(node);
35
+ }
36
+
37
+ const IS_MAC = /Mac|iPhone|iPad/.test(navigator.platform);
38
+
39
+ // How a modifier shortcut reads on this OS: "⌘L" on macOS, "Ctrl+L" on Windows/Linux.
40
+ export const combo = (k) => (IS_MAC ? `⌘${k}` : `Ctrl+${k}`);
41
+
42
+ // ⌘ on macOS, Ctrl elsewhere (AltGr on Windows reports Ctrl+Alt, so Alt is excluded). Falls back to
43
+ // the physical key on non-Latin layouts, where e.key is e.g. "д" for the L key.
44
+ export const modKey = (e, k) =>
45
+ (e.metaKey || e.ctrlKey) && !e.altKey && !e.shiftKey &&
46
+ (e.key.toLowerCase() === k || (!/^[a-z]$/i.test(e.key) && e.code === `Key${k.toUpperCase()}`));
@@ -0,0 +1,38 @@
1
+ import { $ } from '../core/dom.js';
2
+ import { sweep } from '../core/bus.js';
3
+
4
+ // The one modal layer (#overlay). Opening a dialog replaces whatever it showed.
5
+ export function overlay(node, { onClose } = {}) {
6
+ const o = $('#overlay');
7
+ o.innerHTML = '';
8
+ o.append(node);
9
+ o.hidden = false;
10
+ requestAnimationFrame(() => o.classList.add('on'));
11
+ const close = () => {
12
+ o.classList.remove('on');
13
+ // Another overlay may have replaced this one while it faded (palette → settings): leave that alone.
14
+ setTimeout(() => {
15
+ if (o.firstChild === node) (o.hidden = true), (o.innerHTML = '');
16
+ sweep();
17
+ }, 200);
18
+ onClose?.();
19
+ };
20
+ // A block body: an on* handler that returns false cancels the click, which would stop every
21
+ // submit button inside the dialog from submitting its form.
22
+ o.onclick = (e) => {
23
+ if (e.target === o) close();
24
+ };
25
+ o.close = close;
26
+ return close;
27
+ }
28
+
29
+ export const closeOverlay = () => !$('#overlay').hidden && $('#overlay').close?.();
30
+
31
+ // A view opens as its own dialog, or inside another one (Settings) that hands it a host.
32
+ // Returns what closes it for good: the whole overlay either way.
33
+ export function present(node, host) {
34
+ if (host) return host(node);
35
+ const close = overlay(node);
36
+ $('.close', node).onclick = close;
37
+ return close;
38
+ }
@@ -0,0 +1,52 @@
1
+ // Menus and popovers floating over the page. A mousedown anywhere else closes them; the button
2
+ // that opened one (`anchor`) doesn't count, so clicking it again can toggle. Escape closes the
3
+ // newest one, wherever focus is, and puts focus back on its anchor. Callers build and position
4
+ // the node; this appends it and owns closing.
5
+ //
6
+ // anchor the button that opened it
7
+ // keep selector for other floating parts (a picker it opened) whose clicks keep it open
8
+ // capture watch for outside clicks in the capture phase
9
+ // onClose runs once it's gone
10
+ //
11
+ // Returns close, which is also set as node.close.
12
+
13
+ const stack = []; // open popovers, newest last
14
+
15
+ document.addEventListener(
16
+ 'keydown',
17
+ (e) => {
18
+ if (e.key !== 'Escape' || !stack.length) return;
19
+ // Only the newest: a picker opened from the subagents popover closes alone. Nothing behind it
20
+ // (the page's own Escape, which collapses the focused card) sees the key.
21
+ e.preventDefault();
22
+ e.stopImmediatePropagation();
23
+ const top = stack.at(-1);
24
+ top.close();
25
+ top.anchor?.focus();
26
+ },
27
+ true,
28
+ );
29
+
30
+ export function popover(node, { anchor, keep, capture = false, onClose } = {}) {
31
+ let open = true;
32
+ const outside = (e) => {
33
+ if (node.contains(e.target) || anchor?.contains(e.target) || (keep && e.target.closest?.(keep))) return;
34
+ close();
35
+ };
36
+ const entry = { close, anchor };
37
+ function close() {
38
+ if (!open) return;
39
+ open = false;
40
+ clearTimeout(arm);
41
+ stack.splice(stack.indexOf(entry), 1);
42
+ node.remove();
43
+ document.removeEventListener('mousedown', outside, capture);
44
+ onClose?.();
45
+ }
46
+ // Not yet: the mousedown that opened it is still going on.
47
+ const arm = setTimeout(() => document.addEventListener('mousedown', outside, capture));
48
+ stack.push(entry);
49
+ node.close = close;
50
+ document.body.append(node);
51
+ return close;
52
+ }
@@ -0,0 +1,23 @@
1
+ import { $, el } from '../core/dom.js';
2
+ import { esc } from '../md.js';
3
+
4
+ export function toast(html, { tone = '', action, timeout = 4200 } = {}) {
5
+ const t = el(`<div class="toast ${tone}"><span>${html}</span>${action ? `<button class="link">${esc(action.label)}</button>` : ''}</div>`);
6
+ if (action) t.querySelector('button').onclick = () => (action.run(), t.remove());
7
+ $('#toasts').append(t);
8
+ setTimeout(() => t.classList.add('out'), timeout);
9
+ setTimeout(() => t.remove(), timeout + 400);
10
+ }
11
+
12
+ // An error (usually the server refusing something) as a red toast.
13
+ export const toastError = (err, opts) => toast(esc(err.message), { tone: 'bad', ...opts });
14
+
15
+ // Run an action that talks to the server; a failure shows as a red toast instead of throwing.
16
+ // Resolves to what `fn` returns, or undefined when it failed.
17
+ export async function tryApi(fn, opts) {
18
+ try {
19
+ return await fn();
20
+ } catch (err) {
21
+ toastError(err, opts);
22
+ }
23
+ }