@ravefox/space 0.2.0 → 0.3.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 (163) hide show
  1. package/LICENSE +21 -203
  2. package/README.md +89 -26
  3. package/bin/space.js +106 -0
  4. package/lib/agents.js +119 -0
  5. package/lib/credentials.js +95 -0
  6. package/lib/daemon.js +294 -0
  7. package/lib/harness.js +166 -0
  8. package/lib/http.js +101 -0
  9. package/lib/login.js +68 -0
  10. package/lib/mcp.js +34 -0
  11. package/lib/runtime.js +241 -0
  12. package/lib/store.js +96 -0
  13. package/lib/tools.js +93 -0
  14. package/package.json +28 -40
  15. package/NOTICE +0 -44
  16. package/assets/webhook-sdk/python/bot.py +0 -63
  17. package/assets/webhook-sdk/python/commonly.py +0 -232
  18. package/node_modules/@commonlyai/seats/README.md +0 -25
  19. package/node_modules/@commonlyai/seats/package.json +0 -22
  20. package/node_modules/@commonlyai/seats/src/adapters/hermes.js +0 -264
  21. package/node_modules/@commonlyai/seats/src/adapters/stub.js +0 -24
  22. package/node_modules/@commonlyai/seats/src/contract.js +0 -48
  23. package/node_modules/@commonlyai/seats/src/failures.js +0 -44
  24. package/node_modules/@commonlyai/seats/src/harness-plan.js +0 -329
  25. package/node_modules/@commonlyai/seats/src/index.js +0 -22
  26. package/node_modules/@commonlyai/seats/src/process-group.js +0 -269
  27. package/node_modules/@commonlyai/seats/src/record/format.js +0 -737
  28. package/node_modules/@commonlyai/seats/src/record/otel.js +0 -238
  29. package/node_modules/@commonlyai/seats/src/runtime-observation.js +0 -29
  30. package/node_modules/@commonlyai/seats/src/seat-model.js +0 -17
  31. package/node_modules/@commonlyai/seats/src/supervisor.js +0 -308
  32. package/node_modules/@commonlyai/seats/src/trace/events.js +0 -46
  33. package/node_modules/@commonlyai/seats/src/trace/store.js +0 -276
  34. package/node_modules/@commonlyai/seats/src/turn-processes.js +0 -226
  35. package/node_modules/@commonlyai/seats/src/upstream-refusal.js +0 -418
  36. package/node_modules/@commonlyai/seats/src/valet/env.js +0 -201
  37. package/node_modules/@commonlyai/seats/src/valet/grant.js +0 -123
  38. package/node_modules/@commonlyai/seats/src/valet/permissions.js +0 -213
  39. package/node_modules/@commonlyai/seats/src/wire/provider-proxy.js +0 -529
  40. package/skills/commonly/SKILL.md +0 -233
  41. package/src/commands/agent.js +0 -6334
  42. package/src/commands/daemon.js +0 -933
  43. package/src/commands/dev.js +0 -153
  44. package/src/commands/doctor.js +0 -141
  45. package/src/commands/inbox.js +0 -330
  46. package/src/commands/login.js +0 -194
  47. package/src/commands/mcp.js +0 -56
  48. package/src/commands/pod.js +0 -120
  49. package/src/commands/task.js +0 -279
  50. package/src/commands/verify.js +0 -48
  51. package/src/index.js +0 -99
  52. package/src/lib/adapter-login.js +0 -76
  53. package/src/lib/adapters/broker-bridge-entry.js +0 -76
  54. package/src/lib/adapters/claude.js +0 -2207
  55. package/src/lib/adapters/codex-broker-bridge.mjs +0 -298
  56. package/src/lib/adapters/codex.js +0 -1898
  57. package/src/lib/adapters/dsh.js +0 -513
  58. package/src/lib/adapters/goose.js +0 -510
  59. package/src/lib/adapters/hermes.js +0 -18
  60. package/src/lib/adapters/index.js +0 -68
  61. package/src/lib/adapters/opencode.js +0 -1681
  62. package/src/lib/adapters/pi-commonly-mcp.mjs +0 -71
  63. package/src/lib/adapters/pi-mcp-client.mjs +0 -617
  64. package/src/lib/adapters/pi-shell-env.mjs +0 -41
  65. package/src/lib/adapters/pi.js +0 -1025
  66. package/src/lib/adapters/qwen.js +0 -523
  67. package/src/lib/adapters/seat-model.js +0 -8
  68. package/src/lib/adapters/stub.js +0 -1
  69. package/src/lib/adapters/tested-version.js +0 -106
  70. package/src/lib/api.js +0 -205
  71. package/src/lib/claim-outcome.js +0 -128
  72. package/src/lib/claimed-work-gate.js +0 -73
  73. package/src/lib/cli-hint.js +0 -33
  74. package/src/lib/commit-attribution.js +0 -391
  75. package/src/lib/config.js +0 -155
  76. package/src/lib/content-refusal.js +0 -94
  77. package/src/lib/credential-file.js +0 -208
  78. package/src/lib/daemon-agent-states.js +0 -95
  79. package/src/lib/daemon-hint.js +0 -18
  80. package/src/lib/daemon-logs.js +0 -43
  81. package/src/lib/daemon-service-windows.js +0 -263
  82. package/src/lib/daemon-service.js +0 -486
  83. package/src/lib/daemon-state.js +0 -84
  84. package/src/lib/daemon-store.js +0 -119
  85. package/src/lib/daemon-supervisor.js +0 -629
  86. package/src/lib/daemon-watch.js +0 -115
  87. package/src/lib/declared-mcp-guard.js +0 -284
  88. package/src/lib/default-environment.js +0 -207
  89. package/src/lib/device-login.js +0 -126
  90. package/src/lib/digest-frame.js +0 -151
  91. package/src/lib/doctor.js +0 -291
  92. package/src/lib/egress-proxy.js +0 -160
  93. package/src/lib/enforcement.js +0 -946
  94. package/src/lib/environment.js +0 -681
  95. package/src/lib/first-output-watchdog.js +0 -191
  96. package/src/lib/git-readonly-server.js +0 -138
  97. package/src/lib/git-readonly.js +0 -463
  98. package/src/lib/git-remote-commonly.mjs +0 -100
  99. package/src/lib/grant-broker-guard.js +0 -345
  100. package/src/lib/hooks-config.js +0 -238
  101. package/src/lib/host-gh-broker.js +0 -152
  102. package/src/lib/host-gh-shim.mjs +0 -98
  103. package/src/lib/inbox.js +0 -483
  104. package/src/lib/instance-proxy.js +0 -76
  105. package/src/lib/machine-host.js +0 -29
  106. package/src/lib/mcp-credential-delivery.js +0 -121
  107. package/src/lib/mcp-first-run.js +0 -50
  108. package/src/lib/mcp-home.js +0 -644
  109. package/src/lib/mcp-ready.js +0 -68
  110. package/src/lib/mcp-server-version.js +0 -123
  111. package/src/lib/mcp-token.js +0 -36
  112. package/src/lib/mcp-warm-child.mjs +0 -412
  113. package/src/lib/memory-bridge.js +0 -191
  114. package/src/lib/memory-import.js +0 -156
  115. package/src/lib/missing-harness.js +0 -31
  116. package/src/lib/model-unavailable.js +0 -154
  117. package/src/lib/native-runtime-inventory.js +0 -40
  118. package/src/lib/outsider-grant-mcp.js +0 -82
  119. package/src/lib/own-key-launch.js +0 -42
  120. package/src/lib/pod-catch-up.js +0 -55
  121. package/src/lib/pod-focus.js +0 -224
  122. package/src/lib/pod-tail.js +0 -68
  123. package/src/lib/poll-liveness.js +0 -103
  124. package/src/lib/poll-retry.js +0 -81
  125. package/src/lib/poller.js +0 -200
  126. package/src/lib/provider-proxy.js +0 -42
  127. package/src/lib/public-seat-mcp-flag.js +0 -36
  128. package/src/lib/public-tool-error.js +0 -60
  129. package/src/lib/public-withheld-tools.js +0 -48
  130. package/src/lib/reply-receipt.js +0 -55
  131. package/src/lib/resolve-on-path.js +0 -22
  132. package/src/lib/runtime-inventory.js +0 -56
  133. package/src/lib/runtime-observation.js +0 -37
  134. package/src/lib/sandbox/bwrap.js +0 -275
  135. package/src/lib/sandbox/codex-perimeter.js +0 -16
  136. package/src/lib/sandbox/host-check.js +0 -268
  137. package/src/lib/sandbox/mode.js +0 -49
  138. package/src/lib/sandbox/opencode-loopback.mjs +0 -68
  139. package/src/lib/sandbox/seatbelt.js +0 -684
  140. package/src/lib/sandbox/turn-dir.js +0 -56
  141. package/src/lib/sandbox/windows-unsandboxed.js +0 -183
  142. package/src/lib/sandbox/workspace-git-config.js +0 -243
  143. package/src/lib/sandbox/workspace-pin.js +0 -158
  144. package/src/lib/seat-runtime-controls.js +0 -61
  145. package/src/lib/seat-stop.js +0 -97
  146. package/src/lib/server-skills.js +0 -32
  147. package/src/lib/session-recycle.js +0 -219
  148. package/src/lib/session-store.js +0 -215
  149. package/src/lib/skill-prompt.js +0 -74
  150. package/src/lib/skills-import.js +0 -113
  151. package/src/lib/spawn-credential.js +0 -402
  152. package/src/lib/spawn-retry.js +0 -311
  153. package/src/lib/stable-install.js +0 -176
  154. package/src/lib/supervised-turn.js +0 -352
  155. package/src/lib/task.js +0 -235
  156. package/src/lib/turn-failure-notice.js +0 -177
  157. package/src/lib/unconfined-seat-guard.js +0 -94
  158. package/src/lib/update-check.js +0 -192
  159. package/src/lib/upstream-refusal.js +0 -1
  160. package/src/lib/webhook-server.js +0 -109
  161. package/src/lib/windows-command.js +0 -393
  162. package/src/lib/workspace-git.js +0 -87
  163. package/src/lib/workspace-trust.js +0 -162
@@ -1,160 +0,0 @@
1
- /**
2
- * A per-spawn loopback CONNECT proxy that reaches only a fixed list of hosts.
3
- *
4
- * A confined run gets no outbound network of its own (Seatbelt `network:
5
- * 'loopback'`); HTTPS_PROXY points it here. Only CONNECT to an allowlisted
6
- * name on an allowlisted port is opened, and the name is resolved here and
7
- * the connection made to the address resolved, so a name that resolves to
8
- * loopback or a private network is refused rather than followed. Plain HTTP
9
- * requests are refused: the proxy never sees the content of what it carries.
10
- *
11
- * There is no proxy credential. Everything the proxy reaches, any process on
12
- * the host already reaches; it gives the confined run a route, not authority.
13
- */
14
- import { createServer } from 'http';
15
- import { BlockList, connect, isIP } from 'net';
16
- import { lookup } from 'dns/promises';
17
-
18
- // GitHub's download hosts only. github.com and api.github.com accept writes
19
- // (git push, gists, issues) made with any token a run is handed, and a tunnel
20
- // cannot tell a read from a write, so they would be an outbound route for
21
- // anything the run can read. These hosts only serve content.
22
- export const GITHUB_CONTENT_HOSTS = Object.freeze([
23
- 'codeload.github.com',
24
- 'raw.githubusercontent.com',
25
- 'objects.githubusercontent.com',
26
- ]);
27
-
28
- const CONNECT_TIMEOUT_MS = 10_000;
29
- const MAX_REFUSALS_KEPT = 20;
30
-
31
- const nonPublic = new BlockList();
32
- for (const [address, prefix] of [
33
- ['0.0.0.0', 8], ['10.0.0.0', 8], ['100.64.0.0', 10], ['127.0.0.0', 8],
34
- ['169.254.0.0', 16], ['172.16.0.0', 12], ['192.0.0.0', 24], ['192.168.0.0', 16],
35
- ['198.18.0.0', 15], ['224.0.0.0', 4], ['240.0.0.0', 4],
36
- ]) nonPublic.addSubnet(address, prefix, 'ipv4');
37
- for (const [address, prefix] of [
38
- ['::', 128], ['::1', 128], ['fc00::', 7], ['fe80::', 10], ['ff00::', 8], ['64:ff9b::', 96],
39
- ]) nonPublic.addSubnet(address, prefix, 'ipv6');
40
-
41
- /** True for an address no public host name should resolve to. */
42
- export const isNonPublicAddress = (address) => {
43
- const mapped = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i.exec(address);
44
- if (mapped) return nonPublic.check(mapped[1], 'ipv4');
45
- const family = isIP(address);
46
- if (!family) return true;
47
- return nonPublic.check(address, family === 6 ? 'ipv6' : 'ipv4');
48
- };
49
-
50
- /** `host:port` from a CONNECT target, or null when it is not one. */
51
- const parseTarget = (target) => {
52
- const match = /^([A-Za-z0-9.-]+):(\d{1,5})$/.exec(target || '');
53
- if (!match) return null;
54
- const port = Number(match[2]);
55
- if (port < 1 || port > 65535) return null;
56
- return { host: match[1].toLowerCase().replace(/\.$/, ''), port };
57
- };
58
-
59
- /**
60
- * startEgressProxy({ allowHosts?, allowPorts? }) → { port, url, refusals, close }
61
- *
62
- * Listens on 127.0.0.1 at an ephemeral port. `_resolve` and `_allowPrivate`
63
- * exist for tests only, so a test can reach a loopback upstream.
64
- */
65
- export const startEgressProxy = async ({
66
- allowHosts = GITHUB_CONTENT_HOSTS,
67
- allowPorts = [443],
68
- _resolve = (host) => lookup(host, { all: true, verbatim: true }),
69
- _allowPrivate = false,
70
- } = {}) => {
71
- const hosts = new Set(allowHosts.map((host) => String(host).toLowerCase()));
72
- const ports = new Set(allowPorts);
73
- if (!hosts.size || [...ports].some((port) => !Number.isInteger(port) || port < 1 || port > 65535)) {
74
- throw new Error('Egress proxy needs at least one host and valid TCP ports');
75
- }
76
- const refusals = [];
77
- let opened = 0;
78
- const refuse = (socket, status, target, reason) => {
79
- refusals.push({ target, reason });
80
- if (refusals.length > MAX_REFUSALS_KEPT) refusals.shift();
81
- if (!socket.destroyed) socket.end(`HTTP/1.1 ${status}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`);
82
- };
83
- const sockets = new Set();
84
- const track = (socket) => {
85
- sockets.add(socket);
86
- socket.on('close', () => sockets.delete(socket));
87
- };
88
-
89
- const server = createServer((incoming, outgoing) => {
90
- incoming.resume();
91
- refusals.push({ target: String(incoming.url || '').slice(0, 200), reason: 'not CONNECT' });
92
- if (refusals.length > MAX_REFUSALS_KEPT) refusals.shift();
93
- outgoing.writeHead(405, { Connection: 'close' }).end();
94
- });
95
- server.on('connection', track);
96
- server.on('connect', async (request, client, head) => {
97
- client.on('error', () => {});
98
- const target = parseTarget(request.url);
99
- const label = String(request.url || '').slice(0, 200);
100
- if (!target) { refuse(client, '400 Bad Request', label, 'malformed target'); return; }
101
- if (isIP(target.host)) { refuse(client, '403 Forbidden', label, 'address literal'); return; }
102
- if (!hosts.has(target.host) || !ports.has(target.port)) {
103
- refuse(client, '403 Forbidden', label, 'not allowlisted');
104
- return;
105
- }
106
- let addresses;
107
- try {
108
- addresses = (await _resolve(target.host)).map((entry) => entry.address);
109
- } catch {
110
- refuse(client, '502 Bad Gateway', label, 'did not resolve');
111
- return;
112
- }
113
- // Every address must be public, not just the one used: a name that
114
- // resolves to both is not one this proxy was asked to reach.
115
- if (!addresses.length || (!_allowPrivate && addresses.some(isNonPublicAddress))) {
116
- refuse(client, '403 Forbidden', label, 'resolves to a non-public address');
117
- return;
118
- }
119
- if (client.destroyed) return;
120
- const upstream = connect({ host: addresses[0], port: target.port });
121
- track(upstream);
122
- let established = false;
123
- client.on('close', () => upstream.destroy());
124
- upstream.setTimeout(CONNECT_TIMEOUT_MS, () => upstream.destroy());
125
- upstream.on('error', () => {});
126
- upstream.on('close', () => {
127
- if (established) client.destroy();
128
- else refuse(client, '502 Bad Gateway', label, 'upstream unreachable');
129
- });
130
- upstream.once('connect', () => {
131
- upstream.setTimeout(0);
132
- established = true;
133
- opened += 1;
134
- client.write('HTTP/1.1 200 Connection Established\r\n\r\n');
135
- if (head?.length) upstream.write(head);
136
- upstream.pipe(client);
137
- client.pipe(upstream);
138
- });
139
- });
140
-
141
- await new Promise((resolve, reject) => {
142
- server.once('error', reject);
143
- server.listen(0, '127.0.0.1', () => {
144
- server.removeListener('error', reject);
145
- resolve();
146
- });
147
- });
148
- const { port } = server.address();
149
- return {
150
- port,
151
- url: `http://127.0.0.1:${port}`,
152
- /** { opened, refusals: [{ target, reason }] } — the last 20 refusals. */
153
- stats: () => ({ opened, refusals: refusals.map((entry) => ({ ...entry })) }),
154
- close: async () => {
155
- const closed = new Promise((resolve) => server.close(resolve));
156
- for (const socket of sockets) socket.destroy();
157
- await closed;
158
- },
159
- };
160
- };