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.
- package/CHANGELOG.md +55 -1
- package/README.md +29 -13
- package/bin/wisp.js +3 -2
- package/package.json +3 -3
- package/server/adapters/antigravity.js +7 -3
- package/server/adapters/claude.js +79 -55
- package/server/adapters/codex.js +5 -2
- package/server/adapters/common.js +14 -34
- package/server/adapters/cursor.js +4 -2
- package/server/adapters/grok.js +17 -2
- package/server/adapters/index.js +25 -2
- package/server/adapters/opencode.js +78 -12
- package/server/checkpoint.js +12 -68
- package/server/client.js +6 -4
- package/server/git.js +9 -4
- package/server/handoff.js +71 -0
- package/server/http/respond.js +59 -0
- package/server/http/router.js +64 -0
- package/server/http/static.js +36 -0
- package/server/index.js +138 -1216
- package/server/machines/bootstrap.js +56 -0
- package/server/machines/hosts.js +127 -0
- package/server/machines.js +7 -179
- package/server/mcp-ask.js +113 -8
- package/server/mcp-wisp.js +17 -5
- package/server/mentions.js +39 -0
- package/server/openapi.js +36 -4
- package/server/paths.js +32 -0
- package/server/preferences.js +2 -6
- package/server/proc.js +54 -0
- package/server/protocol.js +8 -1
- package/server/recipes.js +2 -4
- package/server/remote.js +14 -14
- package/server/render.js +3 -1
- package/server/router.js +7 -3
- package/server/routes/auto.js +29 -0
- package/server/routes/automations.js +92 -0
- package/server/routes/internal.js +176 -0
- package/server/routes/machines.js +43 -0
- package/server/routes/meta.js +76 -0
- package/server/routes/proxy.js +47 -0
- package/server/routes/sessions.js +351 -0
- package/server/routes/settings.js +144 -0
- package/server/routes/ship.js +61 -0
- package/server/routes/uploads.js +19 -0
- package/server/runner.js +216 -49
- package/server/services/auto.js +67 -0
- package/server/services/feedback.js +53 -0
- package/server/services/install.js +69 -0
- package/server/services/launch.js +127 -0
- package/server/services/phone.js +65 -0
- package/server/services/ship.js +82 -0
- package/server/services/telemetry.js +34 -0
- package/server/services/uploads.js +59 -0
- package/server/services/webhooks.js +28 -0
- package/server/store.js +13 -5
- package/server/subagents.js +5 -4
- package/server/telemetry.js +1 -1
- package/server/terminal.js +2 -1
- package/server/triggers.js +5 -7
- package/server/update.js +4 -3
- package/server/usage.js +94 -0
- package/server/util.js +42 -0
- package/server/welcome.js +3 -3
- package/web/css/auto.css +29 -0
- package/web/css/automations.css +71 -0
- package/web/css/base.css +83 -0
- package/web/css/blocks.css +461 -0
- package/web/css/composer.css +84 -0
- package/web/css/feed.css +235 -0
- package/web/css/launcher.css +204 -0
- package/web/css/layout.css +61 -0
- package/web/css/machines.css +125 -0
- package/web/css/modals.css +176 -0
- package/web/css/palette.css +79 -0
- package/web/css/responsive.css +35 -0
- package/web/css/ship.css +95 -0
- package/web/css/subagents.css +130 -0
- package/web/css/tokens.css +115 -0
- package/web/index.html +17 -1
- package/web/js/app.js +28 -5237
- package/web/js/blocks.js +46 -0
- package/web/js/core/api.js +25 -0
- package/web/js/core/bus.js +28 -0
- package/web/js/core/dom.js +7 -0
- package/web/js/core/format.js +27 -0
- package/web/js/core/state.js +43 -0
- package/web/js/features/actions.js +344 -0
- package/web/js/features/attachments.js +115 -0
- package/web/js/features/auto.js +54 -0
- package/web/js/features/automations.js +305 -0
- package/web/js/features/commands.js +123 -0
- package/web/js/features/compare.js +105 -0
- package/web/js/features/composer.js +315 -0
- package/web/js/features/feed.js +400 -0
- package/web/js/features/feedback.js +127 -0
- package/web/js/features/keys.js +83 -0
- package/web/js/features/launcher.js +561 -0
- package/web/js/features/live.js +91 -0
- package/web/js/features/machines.js +313 -0
- package/web/js/features/memory.js +154 -0
- package/web/js/features/mentions.js +125 -0
- package/web/js/features/notify.js +36 -0
- package/web/js/features/phone.js +124 -0
- package/web/js/features/places.js +38 -0
- package/web/js/features/projects.js +284 -0
- package/web/js/features/runner-picker.js +233 -0
- package/web/js/features/runners.js +163 -0
- package/web/js/features/scroll.js +75 -0
- package/web/js/features/settings.js +390 -0
- package/web/js/features/setup.js +94 -0
- package/web/js/features/ship.js +122 -0
- package/web/js/features/team.js +386 -0
- package/web/js/features/turns.js +432 -0
- package/web/js/features/update.js +48 -0
- package/web/js/features/usage.js +75 -0
- package/web/js/mention-text.js +59 -0
- package/web/js/ui/kbd.js +46 -0
- package/web/js/ui/overlay.js +38 -0
- package/web/js/ui/popover.js +52 -0
- package/web/js/ui/toast.js +23 -0
- package/web/css/app.css +0 -1910
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// A small route table: `route('PATCH', '/sessions/:id', handler)`. Patterns match whole path
|
|
2
|
+
// segments under /api; `:name` captures one (URI-decoded). Routes are tried in the order they
|
|
3
|
+
// were added, so a fixed segment (`/projects/discover`) goes before a capture (`/projects/:id`).
|
|
4
|
+
//
|
|
5
|
+
// A handler gets one context object and answers through it:
|
|
6
|
+
// { req, res, url, query, params, body(), send(status, data) }
|
|
7
|
+
// body() reads and parses the JSON request body (once). Options: `doc: false` marks a route that
|
|
8
|
+
// is not part of the public API (left out of openapi.json on purpose); `when(params)` narrows a
|
|
9
|
+
// pattern further (a route whose `when` says no is skipped, as if it didn't match).
|
|
10
|
+
|
|
11
|
+
import { readJson, send } from './respond.js';
|
|
12
|
+
|
|
13
|
+
export class Routes {
|
|
14
|
+
#list = [];
|
|
15
|
+
|
|
16
|
+
route(method, pattern, handler, { doc = true, when = null } = {}) {
|
|
17
|
+
const segs = pattern.split('/').filter(Boolean);
|
|
18
|
+
for (const m of [method].flat()) this.#list.push({ method: m, pattern, segs, handler, doc, when });
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Every route, for the docs check in the tests.
|
|
23
|
+
list() {
|
|
24
|
+
return this.#list.map(({ method, pattern, doc }) => ({ method, pattern, doc }));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Handles the request and returns true, or returns false when nothing matched.
|
|
28
|
+
async handle(req, res, url) {
|
|
29
|
+
const parts = url.pathname.split('/').filter(Boolean).slice(1); // drop "api"
|
|
30
|
+
for (const r of this.#list) {
|
|
31
|
+
if (r.method !== req.method) continue;
|
|
32
|
+
const params = match(r.segs, parts);
|
|
33
|
+
if (!params || (r.when && !r.when(params))) continue;
|
|
34
|
+
let parsed;
|
|
35
|
+
const ctx = {
|
|
36
|
+
req,
|
|
37
|
+
res,
|
|
38
|
+
url,
|
|
39
|
+
params,
|
|
40
|
+
query: url.searchParams,
|
|
41
|
+
body: () => (parsed ??= readJson(req)),
|
|
42
|
+
send: (status, data) => send(res, status, data),
|
|
43
|
+
};
|
|
44
|
+
await r.handler(ctx);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function match(segs, parts) {
|
|
52
|
+
if (segs.length !== parts.length) return null;
|
|
53
|
+
const params = {};
|
|
54
|
+
for (let i = 0; i < segs.length; i++) {
|
|
55
|
+
if (segs[i].startsWith(':')) {
|
|
56
|
+
try {
|
|
57
|
+
params[segs[i].slice(1)] = decodeURIComponent(parts[i]);
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
} else if (segs[i] !== parts[i]) return null;
|
|
62
|
+
}
|
|
63
|
+
return params;
|
|
64
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// The web UI: files under web/, with index.html for every other path (the app routes itself).
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
export const WEB = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'web');
|
|
8
|
+
|
|
9
|
+
export const MIME = {
|
|
10
|
+
'.html': 'text/html; charset=utf-8',
|
|
11
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
12
|
+
'.css': 'text/css; charset=utf-8',
|
|
13
|
+
'.svg': 'image/svg+xml',
|
|
14
|
+
'.png': 'image/png',
|
|
15
|
+
'.jpg': 'image/jpeg',
|
|
16
|
+
'.jpeg': 'image/jpeg',
|
|
17
|
+
'.gif': 'image/gif',
|
|
18
|
+
'.webp': 'image/webp',
|
|
19
|
+
'.ico': 'image/x-icon',
|
|
20
|
+
'.mp4': 'video/mp4',
|
|
21
|
+
'.webm': 'video/webm',
|
|
22
|
+
'.mov': 'video/quicktime',
|
|
23
|
+
'.pdf': 'application/pdf',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function serveStatic(res, pathname) {
|
|
27
|
+
const p = path.normalize(path.join(WEB, pathname === '/' ? 'index.html' : pathname));
|
|
28
|
+
// Inside web/ only: a sibling folder whose name starts with "web" doesn't count.
|
|
29
|
+
if (!p.startsWith(WEB + path.sep) || !fs.existsSync(p) || fs.statSync(p).isDirectory()) {
|
|
30
|
+
// SPA fallback
|
|
31
|
+
res.writeHead(200, { 'content-type': MIME['.html'] });
|
|
32
|
+
return fs.createReadStream(path.join(WEB, 'index.html')).pipe(res);
|
|
33
|
+
}
|
|
34
|
+
res.writeHead(200, { 'content-type': MIME[path.extname(p)] || 'application/octet-stream', 'cache-control': 'no-cache' });
|
|
35
|
+
fs.createReadStream(p).pipe(res);
|
|
36
|
+
}
|