@wipcomputer/wip-ldm-os 0.4.85-alpha.3 → 0.4.85-alpha.30
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/README.md +22 -2
- package/SKILL.md +136 -14
- package/bin/ldm.js +422 -75
- package/docs/universal-installer/SPEC.md +16 -3
- package/docs/universal-installer/TECHNICAL.md +4 -4
- package/lib/deploy.mjs +104 -20
- package/lib/detect.mjs +35 -4
- package/lib/registry-migrations.mjs +296 -0
- package/package.json +17 -2
- package/scripts/test-crc-agentid-tenant-boundary.mjs +80 -0
- package/scripts/test-crc-e2ee-key-persistence.mjs +150 -0
- package/scripts/test-crc-e2ee-session-route.mjs +129 -0
- package/scripts/test-crc-pair-login-flow.mjs +40 -0
- package/scripts/test-crc-pair-relink-audit-and-rotation.mjs +164 -0
- package/scripts/test-crc-pair-status-poll-token.mjs +73 -0
- package/scripts/test-crc-websocket-abuse-limits.mjs +128 -0
- package/scripts/test-install-prompt-policy.mjs +84 -0
- package/scripts/test-installer-skill-directory.mjs +55 -0
- package/scripts/test-installer-skill-dry-run-destinations.mjs +100 -0
- package/scripts/test-installer-target-self-update.mjs +131 -0
- package/scripts/test-ldm-status-concurrency.mjs +118 -0
- package/scripts/test-ldm-status-timeout.mjs +96 -0
- package/scripts/test-legacy-npm-sources-migration.mjs +460 -0
- package/scripts/test-readme-install-prompt.mjs +66 -0
- package/shared/templates/install-prompt.md +20 -2
- package/src/hosted-mcp/README.md +37 -0
- package/src/hosted-mcp/app/footer.js +74 -0
- package/src/hosted-mcp/app/kaleidoscope-login.html +846 -0
- package/src/hosted-mcp/app/pair.html +165 -57
- package/src/hosted-mcp/app/sprites.png +0 -0
- package/src/hosted-mcp/codex-relay-e2ee-registry.mjs +208 -0
- package/src/hosted-mcp/codex-relay-ws-abuse-limits.mjs +140 -0
- package/src/hosted-mcp/demo/index.html +3 -7
- package/src/hosted-mcp/demo/login.html +318 -20
- package/src/hosted-mcp/deploy.sh +308 -56
- package/src/hosted-mcp/docs/self-host.md +268 -0
- package/src/hosted-mcp/nginx/codex-relay.conf +25 -0
- package/src/hosted-mcp/nginx/conf.d/redact-logs.conf +60 -0
- package/src/hosted-mcp/nginx/mcp-oauth.conf +58 -0
- package/src/hosted-mcp/nginx/wip.computer.conf +25 -1
- package/src/hosted-mcp/scripts/audit-logs.sh +205 -0
- package/src/hosted-mcp/scripts/verify-deploy.sh +102 -0
- package/src/hosted-mcp/server.mjs +1034 -146
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Hosted MCP And Relay
|
|
2
|
+
|
|
3
|
+
This directory contains the public source for the hosted WIP relay that serves `wip.computer`.
|
|
4
|
+
|
|
5
|
+
It includes:
|
|
6
|
+
|
|
7
|
+
- OAuth, passkey, and hosted MCP routes in `server.mjs`;
|
|
8
|
+
- Codex Remote Control relay routes under `/api/codex-relay/*`;
|
|
9
|
+
- nginx snippets for the relay, MCP, and site proxy;
|
|
10
|
+
- Prisma schema and migrations for Postgres-backed account, API key, passkey, device, and wallet state;
|
|
11
|
+
- PM2 and deploy helpers for the WIP-operated VPS.
|
|
12
|
+
|
|
13
|
+
WIP runs the production hosted relay so user setup is easy and works across networks. The source is public so users can inspect the relay path and build their own infrastructure.
|
|
14
|
+
|
|
15
|
+
## Codex Remote Control WebSocket Abuse Limits
|
|
16
|
+
|
|
17
|
+
The browser relay path enforces app-layer limits after a Remote Control ticket attaches:
|
|
18
|
+
|
|
19
|
+
- max browser frame bytes;
|
|
20
|
+
- max messages per rate window;
|
|
21
|
+
- max browser bytes per rate window;
|
|
22
|
+
- max malformed browser frames;
|
|
23
|
+
- max pending bytes on the daemon socket before forwarding;
|
|
24
|
+
- max browser sockets per `(tenant id, thread id)`;
|
|
25
|
+
- idle connection TTL;
|
|
26
|
+
- env-driven operator kill switch for all tenants or selected tenant ids.
|
|
27
|
+
|
|
28
|
+
Violation logs are metadata-only: reason, tenant id, thread id, and a generated connection id. The relay does not inspect decrypted Remote Control payloads.
|
|
29
|
+
|
|
30
|
+
Operational notes:
|
|
31
|
+
|
|
32
|
+
- rate windows are tumbling windows, not sliding windows, so short bursts can straddle a window boundary;
|
|
33
|
+
- kill switch environment changes take effect after the hosted relay process reloads;
|
|
34
|
+
- idle close runs on a timer, so the close can happen up to one polling interval after the configured TTL;
|
|
35
|
+
- daemon-to-browser Codex output is intentionally not throughput-limited in this browser-abuse slice.
|
|
36
|
+
|
|
37
|
+
For the self-hosting shape, read [docs/self-host.md](docs/self-host.md).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Shared footer for all Kaleidoscope pages (production-owned).
|
|
2
|
+
// Include with: <div id="kscope-footer"></div><script src="/app/footer.js"></script>
|
|
3
|
+
(function() {
|
|
4
|
+
var container = document.getElementById('kscope-footer');
|
|
5
|
+
if (!container) return;
|
|
6
|
+
|
|
7
|
+
var mobile = navigator.maxTouchPoints > 0 && window.innerWidth < 768;
|
|
8
|
+
|
|
9
|
+
// Desktop: fixed at bottom. Mobile: in page flow (below fold).
|
|
10
|
+
if (mobile) {
|
|
11
|
+
container.style.cssText = 'background:#FFFDF5;padding:16px 0;';
|
|
12
|
+
} else {
|
|
13
|
+
container.style.cssText = 'position:fixed;bottom:0;left:0;right:0;background:#FFFDF5;padding:16px 0;';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
var inner = document.createElement('div');
|
|
17
|
+
inner.style.cssText = 'max-width:980px;margin:0 auto;padding:0 24px;border-top:1px solid rgba(0,0,0,0.06);padding-top:16px;text-align:left;font-size:13px;color:#a8a4a0;line-height:1.6;';
|
|
18
|
+
|
|
19
|
+
// On mobile, copyright and links on separate lines (like Apple)
|
|
20
|
+
if (mobile) {
|
|
21
|
+
inner.innerHTML = '<p style="margin:0;">WIP Computer, Inc.</p>'
|
|
22
|
+
+ '<p style="margin:2px 0 0;">Learning Dreaming Machines</p>'
|
|
23
|
+
+ '<p style="margin:8px 0 0;">Copyright © 2026 WIP Computer, Inc. All rights reserved.</p>'
|
|
24
|
+
+ '<p style="margin:4px 0 0;">'
|
|
25
|
+
+ '<a href="/legal/privacy/en-ww/" style="color:#a8a4a0;text-decoration:none;">Privacy Policy</a> | '
|
|
26
|
+
+ '<a href="/legal/internet-services/terms/site.html" style="color:#a8a4a0;text-decoration:none;">Terms of Use</a></p>'
|
|
27
|
+
+ '<p style="margin:4px 0 0;">'
|
|
28
|
+
+ '<a href="/agent.txt" style="color:#a8a4a0;text-decoration:none;">Are you an AI Agent?</a></p>'
|
|
29
|
+
+ '<p style="margin:4px 0 0;">Made in California.</p>';
|
|
30
|
+
} else {
|
|
31
|
+
inner.innerHTML = '<p style="margin:0;">WIP Computer, Inc.</p>'
|
|
32
|
+
+ '<p style="margin:2px 0 0;">Learning Dreaming Machines</p>'
|
|
33
|
+
+ '<p style="margin:8px 0 0;">Copyright © 2026 WIP Computer, Inc. All rights reserved. '
|
|
34
|
+
+ '<a href="/legal/privacy/en-ww/" style="color:#a8a4a0;text-decoration:none;">Privacy Policy</a> | '
|
|
35
|
+
+ '<a href="/legal/internet-services/terms/site.html" style="color:#a8a4a0;text-decoration:none;">Terms of Use</a></p>'
|
|
36
|
+
+ '<p style="margin:4px 0 0;">'
|
|
37
|
+
+ '<a href="/agent.txt" style="color:#a8a4a0;text-decoration:none;">Are you an AI Agent?</a> | '
|
|
38
|
+
+ '<a id="localPasskeysToggle" onclick="toggleLocalPasskeys()" style="color:#a8a4a0;text-decoration:none;cursor:pointer;display:inline-flex;align-items:center;gap:4px;vertical-align:middle;">'
|
|
39
|
+
+ '<span id="passkeys-dot" style="display:inline-block;width:8px;height:8px;border-radius:50%;"></span> '
|
|
40
|
+
+ '<span id="passkeys-label">Local passkeys off</span></a></p>'
|
|
41
|
+
+ '<p style="margin:4px 0 0;">Made in California.</p>';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
container.appendChild(inner);
|
|
45
|
+
|
|
46
|
+
// Local passkeys toggle
|
|
47
|
+
if (!window.isLocalPasskeysOn) {
|
|
48
|
+
window.isLocalPasskeysOn = function() { return localStorage.getItem('localPasskeys') === 'on'; };
|
|
49
|
+
}
|
|
50
|
+
if (!window.toggleLocalPasskeys) {
|
|
51
|
+
window.toggleLocalPasskeys = function() {
|
|
52
|
+
var on = isLocalPasskeysOn();
|
|
53
|
+
localStorage.setItem('localPasskeys', on ? 'off' : 'on');
|
|
54
|
+
updatePasskeysDot();
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (!window.updatePasskeysDot) {
|
|
58
|
+
window.updatePasskeysDot = function() {
|
|
59
|
+
var dot = document.getElementById('passkeys-dot');
|
|
60
|
+
var label = document.getElementById('passkeys-label');
|
|
61
|
+
if (!dot) return;
|
|
62
|
+
if (isLocalPasskeysOn()) {
|
|
63
|
+
dot.style.background = '#2E7D32';
|
|
64
|
+
dot.style.opacity = '1';
|
|
65
|
+
if (label) label.textContent = 'Local passkeys on';
|
|
66
|
+
} else {
|
|
67
|
+
dot.style.background = '#D32F2F';
|
|
68
|
+
dot.style.opacity = '0.4';
|
|
69
|
+
if (label) label.textContent = 'Local passkeys off';
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
updatePasskeysDot();
|
|
74
|
+
})();
|