@aspectlylabs/mikka 0.0.193 → 0.0.195
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/agents/native-container.mjs +24 -9
- package/cli.js +477 -327
- package/client.js +19 -8
- package/http-link.js +98 -9
- package/login.js +19 -8
- package/main.js +414 -324
- package/mikka-release-manifest.json +23 -23
- package/mikka.js +477 -327
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/paths.js +2 -2
- package/sandbox.js +8 -2
- package/sbom.cdx.json +7 -7
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
// Private hosted-run bootstrap. The first stdin frame is host configuration;
|
|
2
2
|
// later bytes are the existing CLI protocol. No vault/provider token is accepted.
|
|
3
|
+
//
|
|
4
|
+
// It runs inside Anthropic's sandbox-runtime on the task's own E2B machine
|
|
5
|
+
// (one task, one machine; no Docker: decision 2026-11-01-1312), with the CLI
|
|
6
|
+
// it starts. The host names the CLI, the run's broker and egress sockets and
|
|
7
|
+
// its node. Those sockets are its only way out: the sandbox has no network.
|
|
3
8
|
import { spawn } from "node:child_process";
|
|
9
|
+
import { dirname } from "node:path";
|
|
4
10
|
import { createServer, request as httpRequest } from "node:http";
|
|
5
11
|
import { mkdirSync } from "node:fs";
|
|
6
12
|
import { startNativeEgress } from "./native-egress.mjs";
|
|
@@ -34,6 +40,10 @@ function onData(part) {
|
|
|
34
40
|
initial = Buffer.alloc(0);
|
|
35
41
|
void start(config, remainder).catch(fail);
|
|
36
42
|
}
|
|
43
|
+
/** An absolute host path the worker named; never one the task could shape. */
|
|
44
|
+
function hostPath(value) {
|
|
45
|
+
return typeof value === "string" && value.startsWith("/") && !/[\0\n\r:]/.test(value);
|
|
46
|
+
}
|
|
37
47
|
async function start(config, remainder) {
|
|
38
48
|
if (
|
|
39
49
|
!["claude_code", "codex"].includes(config.kind) ||
|
|
@@ -41,7 +51,12 @@ async function start(config, remainder) {
|
|
|
41
51
|
!config.args.every((a) => typeof a === "string") ||
|
|
42
52
|
typeof config.cwd !== "string" ||
|
|
43
53
|
!config.env ||
|
|
44
|
-
typeof config.env !== "object"
|
|
54
|
+
typeof config.env !== "object" ||
|
|
55
|
+
!hostPath(config.cli) ||
|
|
56
|
+
!hostPath(config.node) ||
|
|
57
|
+
!hostPath(config.brokerSocket) ||
|
|
58
|
+
(config.egressSocket !== undefined && !hostPath(config.egressSocket)) ||
|
|
59
|
+
(config.publicEgress === true) !== (config.egressSocket !== undefined)
|
|
45
60
|
)
|
|
46
61
|
fail();
|
|
47
62
|
for (const [key, value] of Object.entries(config.env)) {
|
|
@@ -56,11 +71,11 @@ async function start(config, remainder) {
|
|
|
56
71
|
}
|
|
57
72
|
delete config.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
58
73
|
if (config.githubBin !== undefined && (typeof config.githubBin !== 'string' || !config.githubBin.startsWith('/') || !config.githubBin.endsWith('/github/bin') || config.githubBin.includes(':') || config.githubBin.includes('\n'))) fail();
|
|
59
|
-
config.env.PATH = `${config.githubBin ? config.githubBin + ':' : ''}
|
|
74
|
+
config.env.PATH = `${config.githubBin ? config.githubBin + ':' : ''}${dirname(config.node)}:/usr/local/bin:/usr/bin:/bin`;
|
|
60
75
|
mkdirSync(config.env.HOME, { recursive: true, mode: 0o700 });
|
|
61
76
|
// Model credentials stay on the original task broker. Public downloads use
|
|
62
77
|
// a separate live, public-IP-only host proxy, never that credential endpoint.
|
|
63
|
-
const egress = config.publicEgress === true ? await startNativeEgress() : null;
|
|
78
|
+
const egress = config.publicEgress === true ? await startNativeEgress(config.egressSocket) : null;
|
|
64
79
|
if (egress) {
|
|
65
80
|
Object.assign(config.env, {
|
|
66
81
|
HTTP_PROXY: egress.url, HTTPS_PROXY: egress.url,
|
|
@@ -80,7 +95,7 @@ async function start(config, remainder) {
|
|
|
80
95
|
path = "/responses";
|
|
81
96
|
const upstream = httpRequest(
|
|
82
97
|
{
|
|
83
|
-
socketPath:
|
|
98
|
+
socketPath: config.brokerSocket,
|
|
84
99
|
method: "POST",
|
|
85
100
|
path,
|
|
86
101
|
headers: request.headers,
|
|
@@ -102,7 +117,8 @@ async function start(config, remainder) {
|
|
|
102
117
|
if (config.kind === "claude_code") {
|
|
103
118
|
config.env.ANTHROPIC_BASE_URL = base;
|
|
104
119
|
config.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR = "3";
|
|
105
|
-
//
|
|
120
|
+
// The worker's sandbox-runtime encloses the CLI and every command it runs;
|
|
121
|
+
// a nested sandbox cannot start inside it (no nested user namespaces).
|
|
106
122
|
const settingsIndex = args.findIndex(
|
|
107
123
|
(value) => value === "--settings" || value.startsWith("--settings="),
|
|
108
124
|
);
|
|
@@ -122,7 +138,7 @@ async function start(config, remainder) {
|
|
|
122
138
|
if (args[i] === "--mcp-config" && args[i + 1]) {
|
|
123
139
|
const value = JSON.parse(args[i + 1]);
|
|
124
140
|
if (value.mcpServers?.mikka)
|
|
125
|
-
value.mcpServers.mikka.command =
|
|
141
|
+
value.mcpServers.mikka.command = config.node;
|
|
126
142
|
args[i + 1] = JSON.stringify(value);
|
|
127
143
|
}
|
|
128
144
|
} else {
|
|
@@ -141,8 +157,7 @@ async function start(config, remainder) {
|
|
|
141
157
|
"-c",
|
|
142
158
|
"features.responses_websockets_v2=false",
|
|
143
159
|
);
|
|
144
|
-
args.push("-c",
|
|
145
|
-
for (const key of [
|
|
160
|
+
args.push("-c", `mcp_servers.mikka.command=${JSON.stringify(config.node)}`); for (const key of [
|
|
146
161
|
"GIT_DIR",
|
|
147
162
|
"GIT_WORK_TREE",
|
|
148
163
|
"GIT_CONFIG_GLOBAL",
|
|
@@ -158,7 +173,7 @@ async function start(config, remainder) {
|
|
|
158
173
|
`shell_environment_policy.set.${key}=${JSON.stringify(config.env[key])}`,
|
|
159
174
|
);
|
|
160
175
|
}
|
|
161
|
-
const child = spawn(
|
|
176
|
+
const child = spawn(config.cli, args, {
|
|
162
177
|
cwd: config.cwd,
|
|
163
178
|
env: config.env,
|
|
164
179
|
stdio:
|