neckbeard-agent 0.0.3 → 0.0.6

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/README.md CHANGED
@@ -41,6 +41,9 @@ const agent = new Agent({
41
41
  summary: z.string(),
42
42
  keyPoints: z.array(z.string()),
43
43
  }),
44
+ envs: {
45
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
46
+ },
44
47
  run: async (input) => {
45
48
  for await (const message of query({
46
49
  prompt: `Research "${input.topic}" and return JSON`,
@@ -67,7 +70,7 @@ npm install neckbeard-agent
67
70
 
68
71
  ```bash
69
72
  export E2B_API_KEY=your-key
70
- export ANTHROPIC_API_KEY=your-key
73
+ export ANTHROPIC_API_KEY=your-key # Pass via envs config, not auto-forwarded
71
74
  ```
72
75
 
73
76
  ## The Details
@@ -87,6 +90,7 @@ new Agent({
87
90
  },
88
91
  files?: [{ url, path }], // pre-download into sandbox
89
92
  claudeDir?: string, // upload .claude/ skills directory
93
+ envs?: Record<string, string | undefined>, // environment variables for sandbox
90
94
  })
91
95
  ```
92
96
 
@@ -102,6 +106,19 @@ The `files` option downloads things into the sandbox before your agent runs—us
102
106
 
103
107
  The `claudeDir` option uploads a local `.claude/` directory to the sandbox, enabling Claude Agent SDK skills. Point it at a directory containing `.claude/skills/*/SKILL.md` files.
104
108
 
109
+ The `envs` option passes environment variables to the sandbox. These are available to your agent code via `process.env` and `ctx.env`. Undefined values are filtered out:
110
+
111
+ ```typescript
112
+ const agent = new Agent({
113
+ template: 'code-interpreter-v1',
114
+ envs: {
115
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
116
+ MY_API_KEY: process.env.MY_API_KEY,
117
+ },
118
+ // ...
119
+ });
120
+ ```
121
+
105
122
  Some packages can't be bundled because they spawn child processes or have native modules. The Claude Agent SDK is like this. These get automatically marked as external and installed via npm in the sandbox.
106
123
 
107
124
  The `run` function gets a context object with an `executionId`, an `AbortSignal`, environment variables, and a logger.
package/dist/index.cjs CHANGED
@@ -232,6 +232,7 @@ var Agent = class {
232
232
  dependencies;
233
233
  files;
234
234
  claudeDir;
235
+ envs;
235
236
  /** @internal Used by the sandbox runner - must be public for bundled code access */
236
237
  _run;
237
238
  _sourceFile;
@@ -246,6 +247,7 @@ var Agent = class {
246
247
  this.dependencies = config.dependencies ?? DEFAULT_DEPENDENCIES;
247
248
  this.files = config.files ?? [];
248
249
  this.claudeDir = config.claudeDir;
250
+ this.envs = config.envs ?? {};
249
251
  }
250
252
  get sandboxId() {
251
253
  return this._sandboxId;
@@ -272,14 +274,7 @@ var Agent = class {
272
274
  if (this._sandboxId) return this._sandboxId;
273
275
  const e2bApiKey = requireEnv("E2B_API_KEY");
274
276
  const esbuild = await getEsbuild();
275
- const { Sandbox, Template } = await getE2b();
276
- const templateExists = await Template.aliasExists(this.template, { apiKey: e2bApiKey });
277
- if (!templateExists) {
278
- throw new DeploymentError(
279
- `Template "${this.template}" not found. Create it via E2B CLI: e2b template build --name ${this.template} --cpu-count 2 --memory-mb 2048
280
- Or use an existing template like 'code-interpreter-v1' (2 cores, 2048 MB) or 'base' (2 cores, 512 MB).`
281
- );
282
- }
277
+ const { Sandbox } = await getE2b();
283
278
  const collectedExternals = /* @__PURE__ */ new Set();
284
279
  const result = await esbuild.build({
285
280
  entryPoints: [this._sourceFile],
@@ -527,9 +522,9 @@ try {
527
522
  let capturedStderr = "";
528
523
  const result = await sandbox.commands.run(`cd ${SANDBOX_PATHS.agentDir} && node runner.mjs`, {
529
524
  timeoutMs: this.maxDuration * 1e3,
530
- envs: {
531
- ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY ?? ""
532
- },
525
+ envs: Object.fromEntries(
526
+ Object.entries(this.envs).filter(([_, v]) => v !== void 0).map(([k, v]) => [k, v])
527
+ ),
533
528
  onStdout: (data) => {
534
529
  capturedStdout += data;
535
530
  },
package/dist/index.d.cts CHANGED
@@ -124,6 +124,20 @@ interface AgentConfig<TInput, TOutput> {
124
124
  * - allowedTools includes 'Skill'
125
125
  */
126
126
  claudeDir?: string;
127
+ /**
128
+ * Environment variables to pass to the sandbox.
129
+ * These will be available to the agent code via process.env and ctx.env.
130
+ * Undefined values are filtered out.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * envs: {
135
+ * ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
136
+ * MY_API_KEY: process.env.MY_API_KEY,
137
+ * }
138
+ * ```
139
+ */
140
+ envs?: Record<string, string | undefined>;
127
141
  }
128
142
  declare class Agent<TInput, TOutput> {
129
143
  readonly template: string;
@@ -133,6 +147,7 @@ declare class Agent<TInput, TOutput> {
133
147
  readonly dependencies: OsDependencies;
134
148
  readonly files: FileDownload[];
135
149
  readonly claudeDir?: string;
150
+ readonly envs: Record<string, string | undefined>;
136
151
  /** @internal Used by the sandbox runner - must be public for bundled code access */
137
152
  _run: (input: TInput, ctx: AgentRunContext) => Promise<TOutput>;
138
153
  private _sourceFile;
package/dist/index.d.ts CHANGED
@@ -124,6 +124,20 @@ interface AgentConfig<TInput, TOutput> {
124
124
  * - allowedTools includes 'Skill'
125
125
  */
126
126
  claudeDir?: string;
127
+ /**
128
+ * Environment variables to pass to the sandbox.
129
+ * These will be available to the agent code via process.env and ctx.env.
130
+ * Undefined values are filtered out.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * envs: {
135
+ * ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
136
+ * MY_API_KEY: process.env.MY_API_KEY,
137
+ * }
138
+ * ```
139
+ */
140
+ envs?: Record<string, string | undefined>;
127
141
  }
128
142
  declare class Agent<TInput, TOutput> {
129
143
  readonly template: string;
@@ -133,6 +147,7 @@ declare class Agent<TInput, TOutput> {
133
147
  readonly dependencies: OsDependencies;
134
148
  readonly files: FileDownload[];
135
149
  readonly claudeDir?: string;
150
+ readonly envs: Record<string, string | undefined>;
136
151
  /** @internal Used by the sandbox runner - must be public for bundled code access */
137
152
  _run: (input: TInput, ctx: AgentRunContext) => Promise<TOutput>;
138
153
  private _sourceFile;
package/dist/index.js CHANGED
@@ -199,6 +199,7 @@ var Agent = class {
199
199
  dependencies;
200
200
  files;
201
201
  claudeDir;
202
+ envs;
202
203
  /** @internal Used by the sandbox runner - must be public for bundled code access */
203
204
  _run;
204
205
  _sourceFile;
@@ -213,6 +214,7 @@ var Agent = class {
213
214
  this.dependencies = config.dependencies ?? DEFAULT_DEPENDENCIES;
214
215
  this.files = config.files ?? [];
215
216
  this.claudeDir = config.claudeDir;
217
+ this.envs = config.envs ?? {};
216
218
  }
217
219
  get sandboxId() {
218
220
  return this._sandboxId;
@@ -239,14 +241,7 @@ var Agent = class {
239
241
  if (this._sandboxId) return this._sandboxId;
240
242
  const e2bApiKey = requireEnv("E2B_API_KEY");
241
243
  const esbuild = await getEsbuild();
242
- const { Sandbox, Template } = await getE2b();
243
- const templateExists = await Template.aliasExists(this.template, { apiKey: e2bApiKey });
244
- if (!templateExists) {
245
- throw new DeploymentError(
246
- `Template "${this.template}" not found. Create it via E2B CLI: e2b template build --name ${this.template} --cpu-count 2 --memory-mb 2048
247
- Or use an existing template like 'code-interpreter-v1' (2 cores, 2048 MB) or 'base' (2 cores, 512 MB).`
248
- );
249
- }
244
+ const { Sandbox } = await getE2b();
250
245
  const collectedExternals = /* @__PURE__ */ new Set();
251
246
  const result = await esbuild.build({
252
247
  entryPoints: [this._sourceFile],
@@ -494,9 +489,9 @@ try {
494
489
  let capturedStderr = "";
495
490
  const result = await sandbox.commands.run(`cd ${SANDBOX_PATHS.agentDir} && node runner.mjs`, {
496
491
  timeoutMs: this.maxDuration * 1e3,
497
- envs: {
498
- ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY ?? ""
499
- },
492
+ envs: Object.fromEntries(
493
+ Object.entries(this.envs).filter(([_, v]) => v !== void 0).map(([k, v]) => [k, v])
494
+ ),
500
495
  onStdout: (data) => {
501
496
  capturedStdout += data;
502
497
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neckbeard-agent",
3
- "version": "0.0.3",
3
+ "version": "0.0.6",
4
4
  "description": "Deploy AI agents to E2B sandboxes",
5
5
  "type": "module",
6
6
  "exports": {
@@ -32,20 +32,24 @@
32
32
  "prepare": "npm run build"
33
33
  },
34
34
  "dependencies": {
35
- "e2b": "^2.10.2",
36
35
  "esbuild": "^0.24.0",
37
36
  "pkg-types": "^2.3.0"
38
37
  },
39
38
  "peerDependencies": {
39
+ "e2b": "^2.2.0",
40
40
  "zod": "^3.0.0 || ^4.0.0"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
+ "e2b": {
44
+ "optional": false
45
+ },
43
46
  "zod": {
44
47
  "optional": true
45
48
  }
46
49
  },
47
50
  "devDependencies": {
48
51
  "@types/node": "^22.0.0",
52
+ "e2b": "^2.2.1",
49
53
  "tsup": "^8.3.0",
50
54
  "typescript": "^5.6.0"
51
55
  },