@bike4mind/cli 1.1.0 → 1.2.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 (28) hide show
  1. package/README.md +1 -0
  2. package/bin/bike4mind-cli.mjs +0 -5
  3. package/dist/AgentHistoryStore-B2NEOvSW.mjs +18014 -0
  4. package/dist/{ApiClient-BOWpVvTq.mjs → ApiClient-D0fQ2FT6.mjs} +2 -2
  5. package/dist/{BubblewrapRuntime-CkL9-gnG.mjs → BubblewrapRuntime-5bLPTwEC.mjs} +2 -2
  6. package/dist/{ConfigStore-DdHHCH2t.mjs → ConfigStore-qV7NrCgZ.mjs} +1154 -1365
  7. package/dist/{ProxyManager-C1-lgzEU.mjs → ProxyManager-B0-RuR2w.mjs} +21 -4
  8. package/dist/{SandboxOrchestrator-CIegJrCj.mjs → SandboxOrchestrator-BcUv9fQ3.mjs} +46 -12
  9. package/dist/{SandboxRuntimeAdapter-ChGlxSGQ.mjs → SandboxRuntimeAdapter-BgLUVTJL.mjs} +2 -2
  10. package/dist/{SandboxRuntimeAdapter-CKelGICD.mjs → SandboxRuntimeAdapter-BmHELLuM.mjs} +1 -1
  11. package/dist/{SeatbeltRuntime-Qqt19cAN.mjs → SeatbeltRuntime-C_Y8q8Mr.mjs} +9 -1
  12. package/dist/buildAgent-C-C-VGff.mjs +2001 -0
  13. package/dist/commands/acpCommand.mjs +8 -6
  14. package/dist/commands/apiCommand.mjs +1 -1
  15. package/dist/commands/doctorCommand.mjs +1 -1
  16. package/dist/commands/envCommand.mjs +1 -1
  17. package/dist/commands/headlessCommand.mjs +26 -16
  18. package/dist/commands/mcpCommand.mjs +3 -3
  19. package/dist/commands/pluginCommand.mjs +1 -1
  20. package/dist/commands/updateCommand.mjs +1 -1
  21. package/dist/index.mjs +444 -100
  22. package/dist/{package-Bqg2LSnH.mjs → package-CGZIoxcs.mjs} +1 -1
  23. package/dist/{serve-DO9Edl5S.mjs → serve-CPXqcEZr.mjs} +2 -2
  24. package/package.json +9 -10
  25. package/dist/AgentHistoryStore-kT9eNMRO.mjs +0 -39471
  26. package/dist/ProxyManager-B1jFWL7b.mjs +0 -3
  27. package/dist/SandboxOrchestrator-BbMDgjzr.mjs +0 -3
  28. package/dist/buildAgent-B_kArQ_Y.mjs +0 -833
@@ -194,14 +194,30 @@ var ProxyManager = class {
194
194
  constructor(networkConfig) {
195
195
  this.proxy = null;
196
196
  this.eventHandlers = /* @__PURE__ */ new Set();
197
+ this.startPromise = null;
197
198
  this.networkConfig = {
198
199
  ...networkConfig,
199
200
  allowedDomains: [...networkConfig.allowedDomains]
200
201
  };
201
202
  }
202
- async start() {
203
- if (!this.networkConfig.enabled) return;
204
- if (this.proxy?.isRunning()) return;
203
+ /**
204
+ * Update the live enabled flag so a runtime toggle takes effect on the next
205
+ * start()/stop(). Without this, start() would early-return on the enabled value
206
+ * snapshotted at construction and grant egress with no proxy actually running.
207
+ */
208
+ setEnabled(enabled) {
209
+ this.networkConfig.enabled = enabled;
210
+ }
211
+ start() {
212
+ if (!this.networkConfig.enabled) return Promise.resolve();
213
+ if (this.proxy?.isRunning()) return Promise.resolve();
214
+ if (this.startPromise) return this.startPromise;
215
+ this.startPromise = this.doStart().finally(() => {
216
+ this.startPromise = null;
217
+ });
218
+ return this.startPromise;
219
+ }
220
+ async doStart() {
205
221
  this.proxy = new HttpConnectProxy({ allowedDomains: this.networkConfig.allowedDomains });
206
222
  this.proxy.on("proxy-event", (event) => {
207
223
  for (const handler of this.eventHandlers) handler(event);
@@ -209,6 +225,7 @@ var ProxyManager = class {
209
225
  await this.proxy.start();
210
226
  }
211
227
  async stop() {
228
+ if (this.startPromise) await this.startPromise.catch(() => {});
212
229
  if (!this.proxy) return;
213
230
  await this.proxy.stop();
214
231
  this.proxy = null;
@@ -256,4 +273,4 @@ var ProxyManager = class {
256
273
  }
257
274
  };
258
275
  //#endregion
259
- export { ProxyManager as t };
276
+ export { ProxyManager };
@@ -10,7 +10,7 @@ var SandboxOrchestrator = class {
10
10
  violations: 0
11
11
  };
12
12
  this.violationStore = null;
13
- this.config = config ?? DEFAULT_SANDBOX_CONFIG;
13
+ this.config = structuredClone(config ?? DEFAULT_SANDBOX_CONFIG);
14
14
  this.runtime = runtime ?? null;
15
15
  this.proxyManager = proxyManager ?? null;
16
16
  }
@@ -52,6 +52,7 @@ var SandboxOrchestrator = class {
52
52
  command,
53
53
  cwd,
54
54
  filesystemConfig: this.config.filesystem,
55
+ networkEnabled: this.config.network.enabled && (this.proxyManager?.isRunning() ?? false),
55
56
  env: proxyEnv,
56
57
  ...this.runtime.platform === "linux" && this.config.platform.linux.seccompProfile && { seccompProfile: this.config.platform.linux.seccompProfile }
57
58
  })
@@ -78,21 +79,54 @@ var SandboxOrchestrator = class {
78
79
  getConfig() {
79
80
  return this.config;
80
81
  }
81
- /** Update config (does not persist - caller must save) */
82
- updateConfig(config) {
83
- this.config = config;
82
+ /**
83
+ * Toggle network egress at runtime and keep the runtime flag and the actual
84
+ * proxy in lockstep - this is the SINGLE lifecycle owner. Fail-closed: when
85
+ * enabling, the proxy must be running afterwards or the flag stays false. The
86
+ * flag is not trusted on its own either - shouldSandbox additionally gates on
87
+ * proxyManager.isRunning(), so a stale network.enabled left by any other path
88
+ * can never hand the runtime raw egress. Note the proxy only filters clients
89
+ * that honor HTTP(S)_PROXY; raw sockets (`curl --noproxy`, `nc`) still egress
90
+ * when network is on, so allowedDomains binds proxy-aware traffic only.
91
+ * Returns whether network is enabled on return. Does not persist - caller saves.
92
+ */
93
+ async setNetworkEnabled(enabled) {
94
+ if (!enabled) {
95
+ this.config.network.enabled = false;
96
+ this.proxyManager?.setEnabled(false);
97
+ await this.proxyManager?.stop().catch(() => {});
98
+ return false;
99
+ }
100
+ if (!this.proxyManager) {
101
+ this.config.network.enabled = false;
102
+ return false;
103
+ }
104
+ this.proxyManager.setEnabled(true);
105
+ try {
106
+ await this.proxyManager.start();
107
+ } catch {}
108
+ if (!this.proxyManager.isRunning()) {
109
+ this.proxyManager.setEnabled(false);
110
+ this.config.network.enabled = false;
111
+ return false;
112
+ }
113
+ this.config.network.enabled = true;
114
+ return true;
84
115
  }
85
116
  /** Get the ProxyManager instance (if any) */
86
117
  getProxyManager() {
87
118
  return this.proxyManager;
88
119
  }
89
- /** Start the network proxy (if configured) */
90
- async startProxy() {
91
- await this.proxyManager?.start();
92
- }
93
- /** Stop the network proxy */
94
- async stopProxy() {
95
- await this.proxyManager?.stop();
120
+ /**
121
+ * Trust a domain for network egress. Updates BOTH the persisted config (the
122
+ * source of truth getConfig/saveSandboxConfig read) and the live proxy - the
123
+ * config is structuredClone'd at construction, so updating only the proxy would
124
+ * leave getConfig()'s allowedDomains stale and a later /sandbox:network or
125
+ * /sandbox:enable save would silently drop the grant. No-op on a duplicate.
126
+ */
127
+ addAllowedDomain(domain) {
128
+ if (!this.config.network.allowedDomains.includes(domain)) this.config.network.allowedDomains.push(domain);
129
+ this.proxyManager?.addAllowedDomain(domain);
96
130
  }
97
131
  /** Get full status information for display */
98
132
  getStatus() {
@@ -156,4 +190,4 @@ var SandboxOrchestrator = class {
156
190
  }
157
191
  };
158
192
  //#endregion
159
- export { SandboxOrchestrator as t };
193
+ export { SandboxOrchestrator };
@@ -42,12 +42,12 @@ async function createSandboxRuntime() {
42
42
  const platform = detectPlatform();
43
43
  if (!platform) return null;
44
44
  if (platform === "darwin") {
45
- const { SeatbeltRuntime } = await import("./SeatbeltRuntime-Qqt19cAN.mjs");
45
+ const { SeatbeltRuntime } = await import("./SeatbeltRuntime-C_Y8q8Mr.mjs");
46
46
  const runtime = new SeatbeltRuntime();
47
47
  return runtime.isAvailable() ? runtime : null;
48
48
  }
49
49
  if (platform === "linux") {
50
- const { BubblewrapRuntime } = await import("./BubblewrapRuntime-CkL9-gnG.mjs");
50
+ const { BubblewrapRuntime } = await import("./BubblewrapRuntime-5bLPTwEC.mjs");
51
51
  const runtime = new BubblewrapRuntime();
52
52
  return runtime.isAvailable() ? runtime : null;
53
53
  }
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-ChGlxSGQ.mjs";
2
+ import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-BgLUVTJL.mjs";
3
3
  export { createSandboxRuntime, detectPlatform, expandPath, isBinaryAvailable };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-ChGlxSGQ.mjs";
2
+ import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-BgLUVTJL.mjs";
3
3
  import { mkdtempSync, writeFileSync } from "fs";
4
4
  import os from "os";
5
5
  import path from "path";
@@ -54,6 +54,14 @@ var SeatbeltRuntime = class {
54
54
  "(allow default)",
55
55
  ""
56
56
  ];
57
+ if (!options.networkEnabled) {
58
+ lines.push("; Deny all network, then re-allow local unix sockets (net: IP-only denial)");
59
+ lines.push("(deny network*)");
60
+ lines.push("(allow network-outbound (remote unix-socket))");
61
+ lines.push("(allow network-inbound (local unix-socket))");
62
+ lines.push("(allow network-bind (local unix-socket))");
63
+ lines.push("");
64
+ }
57
65
  if (filesystemConfig.writeOnlyToWorkingDir) {
58
66
  lines.push("; Deny all file writes globally");
59
67
  lines.push("(deny file-write*)");