@ravefox/space 0.2.1 → 0.4.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 (167) hide show
  1. package/LICENSE +21 -205
  2. package/README.md +104 -31
  3. package/bin/space.js +113 -0
  4. package/lib/agents.js +181 -0
  5. package/lib/boardTools.js +89 -0
  6. package/lib/credentials.js +95 -0
  7. package/lib/daemon.js +294 -0
  8. package/lib/harness.js +166 -0
  9. package/lib/http.js +101 -0
  10. package/lib/login.js +68 -0
  11. package/lib/mcp.js +39 -0
  12. package/lib/runtime.js +253 -0
  13. package/lib/store.js +96 -0
  14. package/lib/tools.js +93 -0
  15. package/lib/workspaceSandbox.js +77 -0
  16. package/lib/workspaceTools.js +160 -0
  17. package/lib/workspaceWorker.js +17 -0
  18. package/package.json +27 -46
  19. package/NOTICE +0 -55
  20. package/assets/webhook-sdk/python/bot.py +0 -63
  21. package/assets/webhook-sdk/python/commonly.py +0 -232
  22. package/node_modules/@commonlyai/seats/README.md +0 -25
  23. package/node_modules/@commonlyai/seats/package.json +0 -22
  24. package/node_modules/@commonlyai/seats/src/adapters/hermes.js +0 -264
  25. package/node_modules/@commonlyai/seats/src/adapters/stub.js +0 -24
  26. package/node_modules/@commonlyai/seats/src/contract.js +0 -48
  27. package/node_modules/@commonlyai/seats/src/failures.js +0 -44
  28. package/node_modules/@commonlyai/seats/src/harness-plan.js +0 -329
  29. package/node_modules/@commonlyai/seats/src/index.js +0 -22
  30. package/node_modules/@commonlyai/seats/src/process-group.js +0 -269
  31. package/node_modules/@commonlyai/seats/src/record/format.js +0 -737
  32. package/node_modules/@commonlyai/seats/src/record/otel.js +0 -238
  33. package/node_modules/@commonlyai/seats/src/runtime-observation.js +0 -29
  34. package/node_modules/@commonlyai/seats/src/seat-model.js +0 -17
  35. package/node_modules/@commonlyai/seats/src/supervisor.js +0 -308
  36. package/node_modules/@commonlyai/seats/src/trace/events.js +0 -46
  37. package/node_modules/@commonlyai/seats/src/trace/store.js +0 -276
  38. package/node_modules/@commonlyai/seats/src/turn-processes.js +0 -226
  39. package/node_modules/@commonlyai/seats/src/upstream-refusal.js +0 -418
  40. package/node_modules/@commonlyai/seats/src/valet/env.js +0 -201
  41. package/node_modules/@commonlyai/seats/src/valet/grant.js +0 -123
  42. package/node_modules/@commonlyai/seats/src/valet/permissions.js +0 -213
  43. package/node_modules/@commonlyai/seats/src/wire/provider-proxy.js +0 -529
  44. package/skills/commonly/SKILL.md +0 -233
  45. package/src/commands/agent.js +0 -6334
  46. package/src/commands/daemon.js +0 -933
  47. package/src/commands/dev.js +0 -153
  48. package/src/commands/doctor.js +0 -141
  49. package/src/commands/inbox.js +0 -330
  50. package/src/commands/login.js +0 -194
  51. package/src/commands/mcp.js +0 -56
  52. package/src/commands/pod.js +0 -120
  53. package/src/commands/task.js +0 -279
  54. package/src/commands/verify.js +0 -48
  55. package/src/index.js +0 -99
  56. package/src/lib/adapter-login.js +0 -76
  57. package/src/lib/adapters/broker-bridge-entry.js +0 -76
  58. package/src/lib/adapters/claude.js +0 -2207
  59. package/src/lib/adapters/codex-broker-bridge.mjs +0 -298
  60. package/src/lib/adapters/codex.js +0 -1898
  61. package/src/lib/adapters/dsh.js +0 -513
  62. package/src/lib/adapters/goose.js +0 -510
  63. package/src/lib/adapters/hermes.js +0 -18
  64. package/src/lib/adapters/index.js +0 -68
  65. package/src/lib/adapters/opencode.js +0 -1681
  66. package/src/lib/adapters/pi-commonly-mcp.mjs +0 -71
  67. package/src/lib/adapters/pi-mcp-client.mjs +0 -617
  68. package/src/lib/adapters/pi-shell-env.mjs +0 -41
  69. package/src/lib/adapters/pi.js +0 -1025
  70. package/src/lib/adapters/qwen.js +0 -523
  71. package/src/lib/adapters/seat-model.js +0 -8
  72. package/src/lib/adapters/stub.js +0 -1
  73. package/src/lib/adapters/tested-version.js +0 -106
  74. package/src/lib/api.js +0 -205
  75. package/src/lib/claim-outcome.js +0 -128
  76. package/src/lib/claimed-work-gate.js +0 -73
  77. package/src/lib/cli-hint.js +0 -33
  78. package/src/lib/commit-attribution.js +0 -391
  79. package/src/lib/config.js +0 -155
  80. package/src/lib/content-refusal.js +0 -94
  81. package/src/lib/credential-file.js +0 -208
  82. package/src/lib/daemon-agent-states.js +0 -95
  83. package/src/lib/daemon-hint.js +0 -18
  84. package/src/lib/daemon-logs.js +0 -43
  85. package/src/lib/daemon-service-windows.js +0 -263
  86. package/src/lib/daemon-service.js +0 -486
  87. package/src/lib/daemon-state.js +0 -84
  88. package/src/lib/daemon-store.js +0 -119
  89. package/src/lib/daemon-supervisor.js +0 -629
  90. package/src/lib/daemon-watch.js +0 -115
  91. package/src/lib/declared-mcp-guard.js +0 -284
  92. package/src/lib/default-environment.js +0 -207
  93. package/src/lib/device-login.js +0 -126
  94. package/src/lib/digest-frame.js +0 -151
  95. package/src/lib/doctor.js +0 -291
  96. package/src/lib/egress-proxy.js +0 -160
  97. package/src/lib/enforcement.js +0 -946
  98. package/src/lib/environment.js +0 -681
  99. package/src/lib/first-output-watchdog.js +0 -191
  100. package/src/lib/git-readonly-server.js +0 -138
  101. package/src/lib/git-readonly.js +0 -463
  102. package/src/lib/git-remote-commonly.mjs +0 -100
  103. package/src/lib/grant-broker-guard.js +0 -345
  104. package/src/lib/hooks-config.js +0 -238
  105. package/src/lib/host-gh-broker.js +0 -152
  106. package/src/lib/host-gh-shim.mjs +0 -98
  107. package/src/lib/inbox.js +0 -483
  108. package/src/lib/instance-proxy.js +0 -76
  109. package/src/lib/machine-host.js +0 -29
  110. package/src/lib/mcp-credential-delivery.js +0 -121
  111. package/src/lib/mcp-first-run.js +0 -50
  112. package/src/lib/mcp-home.js +0 -644
  113. package/src/lib/mcp-ready.js +0 -68
  114. package/src/lib/mcp-server-version.js +0 -123
  115. package/src/lib/mcp-token.js +0 -36
  116. package/src/lib/mcp-warm-child.mjs +0 -412
  117. package/src/lib/memory-bridge.js +0 -191
  118. package/src/lib/memory-import.js +0 -156
  119. package/src/lib/missing-harness.js +0 -31
  120. package/src/lib/model-unavailable.js +0 -154
  121. package/src/lib/native-runtime-inventory.js +0 -40
  122. package/src/lib/outsider-grant-mcp.js +0 -82
  123. package/src/lib/own-key-launch.js +0 -42
  124. package/src/lib/pod-catch-up.js +0 -55
  125. package/src/lib/pod-focus.js +0 -224
  126. package/src/lib/pod-tail.js +0 -68
  127. package/src/lib/poll-liveness.js +0 -103
  128. package/src/lib/poll-retry.js +0 -81
  129. package/src/lib/poller.js +0 -200
  130. package/src/lib/provider-proxy.js +0 -42
  131. package/src/lib/public-seat-mcp-flag.js +0 -36
  132. package/src/lib/public-tool-error.js +0 -60
  133. package/src/lib/public-withheld-tools.js +0 -48
  134. package/src/lib/reply-receipt.js +0 -55
  135. package/src/lib/resolve-on-path.js +0 -22
  136. package/src/lib/runtime-inventory.js +0 -56
  137. package/src/lib/runtime-observation.js +0 -37
  138. package/src/lib/sandbox/bwrap.js +0 -275
  139. package/src/lib/sandbox/codex-perimeter.js +0 -16
  140. package/src/lib/sandbox/host-check.js +0 -268
  141. package/src/lib/sandbox/mode.js +0 -49
  142. package/src/lib/sandbox/opencode-loopback.mjs +0 -68
  143. package/src/lib/sandbox/seatbelt.js +0 -684
  144. package/src/lib/sandbox/turn-dir.js +0 -56
  145. package/src/lib/sandbox/windows-unsandboxed.js +0 -183
  146. package/src/lib/sandbox/workspace-git-config.js +0 -243
  147. package/src/lib/sandbox/workspace-pin.js +0 -158
  148. package/src/lib/seat-runtime-controls.js +0 -61
  149. package/src/lib/seat-stop.js +0 -97
  150. package/src/lib/server-skills.js +0 -32
  151. package/src/lib/session-recycle.js +0 -219
  152. package/src/lib/session-store.js +0 -215
  153. package/src/lib/skill-prompt.js +0 -74
  154. package/src/lib/skills-import.js +0 -113
  155. package/src/lib/spawn-credential.js +0 -402
  156. package/src/lib/spawn-retry.js +0 -311
  157. package/src/lib/stable-install.js +0 -176
  158. package/src/lib/supervised-turn.js +0 -352
  159. package/src/lib/task.js +0 -235
  160. package/src/lib/turn-failure-notice.js +0 -177
  161. package/src/lib/unconfined-seat-guard.js +0 -94
  162. package/src/lib/update-check.js +0 -192
  163. package/src/lib/upstream-refusal.js +0 -1
  164. package/src/lib/webhook-server.js +0 -109
  165. package/src/lib/windows-command.js +0 -393
  166. package/src/lib/workspace-git.js +0 -87
  167. 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
- };