@ravefox/space 0.2.1 → 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 -205
  2. package/README.md +80 -31
  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 +27 -46
  15. package/NOTICE +0 -55
  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,121 +0,0 @@
1
- /**
2
- * How a declared MCP server receives the seat credential, for the two adapters
3
- * that cannot hand it over on a pipe.
4
- *
5
- * The pi bridge spawns the server itself, so it can pipe the credential on an
6
- * inherited fd (see `pi-mcp-client.mjs`). Claude and codex do not: each of them
7
- * starts the server inside its own process tree, so the only two channels
8
- * available are (a) a value in the runtime's environment, which the whole
9
- * subtree inherits, or (b) a PATH in the declaration that the server itself
10
- * reads. (b) is the one that leaves the token where it belongs.
11
- *
12
- * This module makes that choice in ONE place, because three call sites deciding
13
- * version thresholds independently is how one of them ends up handing over the
14
- * value while the others hand over the path.
15
- *
16
- * The rewrite is of the DECLARATION, not of the value: an entry that named
17
- * `COMMONLY_AGENT_TOKEN` comes back naming `COMMONLY_TOKEN_FILE`, so the value
18
- * never exists in the runtime's environment to be inherited, logged, or dumped
19
- * by an unrelated MCP server that a seat was granted.
20
- */
21
- import { CREDENTIAL_FILE_VAR, CREDENTIAL_KEY } from './credential-file.js';
22
- import {
23
- FILE_READER_VERSION, MCP_PACKAGE, describeMcpCommand, versionOlderThan,
24
- } from './mcp-server-version.js';
25
-
26
- /** What a declaration should say to receive the credential as a path. */
27
- export const CREDENTIAL_FILE_PLACEHOLDER = '${COMMONLY_TOKEN_FILE}';
28
-
29
- /**
30
- * What a runtime's OWN environment may carry, once the declarations are settled.
31
- *
32
- * The rewrite above decides what a CHILD is told. It does not decide what the
33
- * runtime process itself carries, and that is a separate leak with the same
34
- * symptom: the credential is exported for bootstrap (`agent run`, the daemon),
35
- * so an adapter that derives its runtime environment from `process.env` hands
36
- * the value back to the runtime — and to every MCP child, hook and shell below
37
- * it — however the declaration was rewritten. Measured (Vera, 70455): four tests
38
- * that pass in a runner without the variable fail with it set, and the value
39
- * they saw was the runner's own.
40
- *
41
- * So the PATH of this spawn's file goes in (a path is not a secret, and a hook
42
- * process resolves its credential from it — see `hooks-config.resolveHookToken`)
43
- * and the VALUE comes out, unless a carve-out genuinely needs the value here:
44
- * a field the adapter substitutes LITERALLY has no file channel, so `keepsValue`
45
- * is passed in by the adapter rather than inferred, and the spawn that keeps a
46
- * secret says so in its own warning.
47
- *
48
- * The PATH comes out too when there is no file for THIS spawn. The runtime
49
- * environment is derived from `process.env`, so a launcher whose own process was
50
- * spawned by another seat inherits that seat's `COMMONLY_TOKEN_FILE` and hands
51
- * it to the runtime and every MCP child below it — a path to a credential this
52
- * launcher did not mint. The value was already deleted here for that reason; the
53
- * path is the same leak with a smaller blast radius.
54
- */
55
- export const withholdRuntimeCredential = (env, { credentialFile = null, keepsValue = false } = {}) => {
56
- if (credentialFile) {
57
- env[CREDENTIAL_FILE_VAR] = credentialFile;
58
- } else {
59
- delete env[CREDENTIAL_FILE_VAR];
60
- }
61
- if (!keepsValue) delete env[CREDENTIAL_KEY];
62
- return env;
63
- };
64
-
65
- /** What a declaration says when it asks for the seat credential (the old shape). */
66
- export const CREDENTIAL_PLACEHOLDER = '${COMMONLY_AGENT_TOKEN}';
67
-
68
- /**
69
- * Rewrite one server's declared environment so the credential arrives as a path.
70
- *
71
- * Returns `{ env, delivered }` where `delivered` is one of:
72
- * 'path' — the declaration now names the file; the adapter expands it
73
- * 'env' — the value stays in the environment, deliberately (see below)
74
- * 'none' — nothing to deliver: the entry declares no credential
75
- * 'unavailable' — no launcher credential file exists for this spawn
76
- *
77
- * `env` is a fresh object; the caller's declaration is never mutated.
78
- */
79
- export const deliverSeatCredential = (server, {
80
- credentialFile,
81
- onWarn = (message) => process.stderr.write(`${message}\n`),
82
- label = 'mcp',
83
- } = {}) => {
84
- const env = { ...((server || {}).env || {}) };
85
- if (env[CREDENTIAL_FILE_VAR] !== undefined && String(env[CREDENTIAL_FILE_VAR]).trim() !== '') {
86
- // Already on the launcher channel — an operator who set this by hand, or a
87
- // record written after this shipped. Nothing to rewrite.
88
- return { env, delivered: 'path' };
89
- }
90
- if (env[CREDENTIAL_KEY] === undefined) return { env, delivered: 'none' };
91
- if (!credentialFile) {
92
- // No launcher wrote a file, so there is nothing to point at. Leave the
93
- // declaration exactly as it was rather than handing over a path to nowhere.
94
- return { env, delivered: 'unavailable' };
95
- }
96
- const ours = describeMcpCommand((server || {}).command);
97
- if (!ours) {
98
- // Somebody else's server. Their declaration is theirs: we do not know their
99
- // protocol, so replacing their variable with a path would break a server we
100
- // have no business redefining.
101
- onWarn(`[${label}] ${server?.name} is not ${MCP_PACKAGE} but declares ${CREDENTIAL_KEY}; leaving that declaration alone. Declare the seat credential on the commonly entry instead.`);
102
- return { env, delivered: 'env' };
103
- }
104
- if (versionOlderThan(ours.version, FILE_READER_VERSION) === true) {
105
- // Measured, not hypothetical: five seats run a hand-patched staging checkout
106
- // at 0.3.7, whose reader only understands the environment. Handing it a path
107
- // it cannot read would take its tools away rather than its secret.
108
- onWarn(`[${label}] ${server.name} runs @commonlyai/mcp ${ours.version.join('.')}, which predates the credential file (${FILE_READER_VERSION.join('.')}): keeping the token in the environment. Unpin it, or move that seat off this checkout.`);
109
- return { env, delivered: 'env' };
110
- }
111
- if (String(env[CREDENTIAL_KEY]) !== CREDENTIAL_PLACEHOLDER) {
112
- // A literal token in a declaration is stale by construction — seat tokens
113
- // rotate, and this one was read when the record was written. Superseding it
114
- // with the live credential is a repair, but it IS a change in what the seat
115
- // sends, so it is said out loud rather than done quietly.
116
- onWarn(`[${label}] ${server.name} declares a literal ${CREDENTIAL_KEY}; superseding it with this spawn's credential file.`);
117
- }
118
- delete env[CREDENTIAL_KEY];
119
- env[CREDENTIAL_FILE_VAR] = CREDENTIAL_FILE_PLACEHOLDER;
120
- return { env, delivered: 'path' };
121
- };
@@ -1,50 +0,0 @@
1
- /**
2
- * Prepare the commonly MCP build before a confined seat's first poll.
3
- *
4
- * A confined seat (public, or workspace since TASK-294) runs its MCP server
5
- * only from a host-prepared build (TASK-273),
6
- * and the first spawn on an empty home only STARTS preparing one, then refuses
7
- * its turn. On a fresh machine that refused turn was the person's first
8
- * @mention, and it waited out the kernel's requeue, about ten minutes (BYO
9
- * walk, 2026-10-16). `agent run` prepares the build once, before it polls.
10
- *
11
- * The gate is the adapters' own: claude.js refuses a workspace seat's turn
12
- * without that build too. Gated on 'public' alone, a Connect-page Claude Code
13
- * seat in private pods (trust 'workspace') skipped the warm and its first
14
- * @mention was refused (prod walk, 2026-11-05).
15
- */
16
-
17
- // The trusts whose spawn requires a host-prepared build.
18
- const CONFINED_TRUSTS = new Set(['public', 'workspace']);
19
-
20
- import { normalizeSandboxTrust } from './environment.js';
21
- import { COMMONLY_MCP_SERVER_NAME } from './default-environment.js';
22
- import { WARM_RESULTS, planMcpSpawn, resolveHomeDir } from './mcp-home.js';
23
- import { warmMcpHome } from './mcp-warm-child.mjs';
24
-
25
- /** The warm's result when it ran, or null when this seat needed none. */
26
- export const prepareMcpBeforeFirstPoll = async ({
27
- environment,
28
- home,
29
- plan = planMcpSpawn,
30
- warm = warmMcpHome,
31
- log = () => {},
32
- } = {}) => {
33
- if (!CONFINED_TRUSTS.has(normalizeSandboxTrust(environment?.sandbox)?.trust)) return null;
34
- const server = Array.isArray(environment?.mcp)
35
- ? environment.mcp.find((entry) => entry?.name === COMMONLY_MCP_SERVER_NAME)
36
- : null;
37
- if (!Array.isArray(server?.command)) return null;
38
- if (plan(server.command, { home }).reason !== 'home-empty') return null;
39
-
40
- log("preparing Space's tools on this machine (first run only)...");
41
- const result = await warm(resolveHomeDir(home), { now: Date.now() });
42
- if (result === WARM_RESULTS.ADVANCED || result === WARM_RESULTS.CURRENT) {
43
- log("Space's tools are ready");
44
- } else {
45
- log(`could not prepare Space's tools yet (${result}); the first turn will try again`);
46
- }
47
- return result;
48
- };
49
-
50
- export default { prepareMcpBeforeFirstPoll };