@themoltnet/pi-extension 0.16.0 → 0.16.1

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
@@ -126,6 +126,16 @@ the base snapshot is used (Alpine + git + gh + MoltNet CLI + agent user).
126
126
  "GOPATH": "/home/agent/go",
127
127
  "GOROOT": "/usr/lib/go"
128
128
  },
129
+ "hostExec": {
130
+ "autoApprove": [
131
+ {
132
+ "argsExcludes": ["--mirror", "--all"],
133
+ "argsPrefix": ["push"],
134
+ "executable": "git"
135
+ },
136
+ { "argsPrefix": ["pr", "create"], "executable": "gh" }
137
+ ]
138
+ },
129
139
  "resources": {
130
140
  "cpus": 2,
131
141
  "memory": "6G"
@@ -183,6 +193,45 @@ Environment variable overrides applied to the guest VM. Use this to fix host
183
193
  env pollution (e.g. `GOROOT` from mise/asdf pointing at a macOS path leaking
184
194
  into the Linux guest).
185
195
 
196
+ ### `hostExec`
197
+
198
+ Host-side escape hatch policy for `moltnet_host_exec`. The executable must
199
+ still be in the built-in host-exec allowlist (`git`, `gh`, `moltnet`); this
200
+ setting only controls whether the per-call UI approval dialog is skipped.
201
+
202
+ `autoApprove: true` skips the dialog for every allowed host command. Use that
203
+ only on isolated hosts or disposable machines.
204
+
205
+ For local daemon runs, prefer rule-based approval:
206
+
207
+ ```json
208
+ {
209
+ "hostExec": {
210
+ "autoApprove": [
211
+ {
212
+ "argsExcludes": ["--mirror", "--all"],
213
+ "argsPrefix": ["push"],
214
+ "executable": "git"
215
+ },
216
+ { "argsPrefix": ["pr", "create"], "executable": "gh" },
217
+ { "argsPrefix": ["pr", "view"], "executable": "gh" }
218
+ ]
219
+ }
220
+ }
221
+ ```
222
+
223
+ Each rule matches an exact executable plus optional argument constraints:
224
+
225
+ | Field | Description |
226
+ | -------------- | ----------------------------------------------------------- |
227
+ | `executable` | Exact executable name |
228
+ | `argsPrefix` | Ordered argument prefix; later flags/args are still allowed |
229
+ | `argsContains` | Tokens that must appear anywhere in the args |
230
+ | `argsExcludes` | Tokens that block auto-approval when present |
231
+
232
+ If a rule only sets `executable`, all argument lists for that executable are
233
+ auto-approved after the built-in executable allowlist check.
234
+
186
235
  ## Base snapshot
187
236
 
188
237
  Every snapshot includes:
package/dist/index.d.ts CHANGED
@@ -271,6 +271,12 @@ export declare interface ExecutePiTaskOptions {
271
271
  * Default `3`. Set to `0` to disable. Closes part of #1094.
272
272
  */
273
273
  maxBashTimeouts?: number;
274
+ /**
275
+ * Skip per-call UI approval for matching `moltnet_host_exec` commands.
276
+ * Keep false/undefined for interactive consumers. `true` skips every dialog
277
+ * after HOST_EXEC_ALLOWED; an array limits auto-approval to matching rules.
278
+ */
279
+ hostExecAutoApprove?: HostExecAutoApproveConfig;
274
280
  }
275
281
 
276
282
  /**
@@ -285,6 +291,19 @@ export declare function findMainWorktree(): string;
285
291
  */
286
292
  export declare const HOST_EXEC_DEFAULT_BASE_ENV: ReadonlySet<string>;
287
293
 
294
+ declare type HostExecAutoApproveConfig = boolean | readonly HostExecAutoApproveRule[];
295
+
296
+ declare interface HostExecAutoApproveRule {
297
+ /** Exact executable name. Must still pass HOST_EXEC_ALLOWED. */
298
+ executable: string;
299
+ /** Optional ordered argument prefix; flags after the prefix are allowed. */
300
+ argsPrefix?: readonly string[];
301
+ /** Optional unordered argument tokens that must appear somewhere. */
302
+ argsContains?: readonly string[];
303
+ /** Optional argument tokens that prevent auto-approval when present. */
304
+ argsExcludes?: readonly string[];
305
+ }
306
+
288
307
  export declare interface InjectedTaskContext {
289
308
  /** Refs that were delivered, in declared order, for audit. */
290
309
  injected: ContextRef[];
@@ -363,6 +382,19 @@ declare interface MoltNetToolsConfig {
363
382
  * Defaults to HOST_EXEC_DEFAULT_BASE_ENV when omitted.
364
383
  */
365
384
  hostExecBaseEnv?: ReadonlySet<string>;
385
+ /**
386
+ * When true, `moltnet_host_exec` skips the per-call UI approval dialog.
387
+ * Intended for non-interactive daemon automation only; interactive
388
+ * consumers should keep the default false behavior.
389
+ */
390
+ autoApproveHostExec?: boolean;
391
+ /**
392
+ * Host-exec auto-approval policy. `true` skips all dialogs after the
393
+ * executable allowlist check. An array skips only commands matching one of
394
+ * the supplied executable/argument rules. Omitted/false preserves the
395
+ * interactive approval flow.
396
+ */
397
+ hostExecAutoApprove?: HostExecAutoApproveConfig;
366
398
  /**
367
399
  * Active-task context, populated by the agent-daemon path. When set,
368
400
  * `moltnet_create_entry` enforces `diaryId === taskContext.diaryId` and
@@ -419,6 +451,19 @@ export declare interface SandboxConfig {
419
451
  };
420
452
  /** Environment variable overrides for the guest VM (applied on top of defaults). */
421
453
  env?: Record<string, string>;
454
+ /** Host-side escape hatch policy. Applies only to `moltnet_host_exec`. */
455
+ hostExec?: {
456
+ /**
457
+ * `true` auto-approves every allowed executable. An array auto-approves
458
+ * only commands matching one of the executable/argument rules.
459
+ */
460
+ autoApprove?: boolean | {
461
+ executable: string;
462
+ argsPrefix?: string[];
463
+ argsContains?: string[];
464
+ argsExcludes?: string[];
465
+ }[];
466
+ };
422
467
  /** VM resource allocation. */
423
468
  resources?: {
424
469
  /** Memory size in qemu syntax (default '1G'). */
package/dist/index.js CHANGED
@@ -7274,6 +7274,7 @@ function renderPhase6Markdown(pack) {
7274
7274
  * These tools run on the host (not in the VM) via the MoltNet SDK,
7275
7275
  * so agent credentials never touch the VM filesystem.
7276
7276
  */
7277
+ var DIARY_TAG_MAX_LENGTH = 128;
7277
7278
  /**
7278
7279
  * Baseline env keys forwarded to host-exec child processes.
7279
7280
  * Callers can extend this set at sandbox startup via `MoltNetToolsConfig.hostExecBaseEnv`.
@@ -7302,6 +7303,19 @@ function ensureConnected(config) {
7302
7303
  teamId: config.getTeamId() ?? ""
7303
7304
  };
7304
7305
  }
7306
+ function hostExecMatchesAutoApproveRule(params, rule) {
7307
+ if (params.executable !== rule.executable) return false;
7308
+ if (rule.argsExcludes?.some((arg) => params.args.includes(arg))) return false;
7309
+ if (rule.argsPrefix && !rule.argsPrefix.every((arg, index) => params.args[index] === arg)) return false;
7310
+ if (rule.argsContains && !rule.argsContains.every((arg) => params.args.includes(arg))) return false;
7311
+ return true;
7312
+ }
7313
+ function shouldAutoApproveHostExec(params, config) {
7314
+ const policy = config.autoApproveHostExec === true ? true : config.hostExecAutoApprove ?? false;
7315
+ if (policy === true) return true;
7316
+ if (!Array.isArray(policy)) return false;
7317
+ return policy.some((rule) => hostExecMatchesAutoApproveRule(params, rule));
7318
+ }
7305
7319
  /**
7306
7320
  * Expand the `taskFilter` shorthand on the diary list/search tools into
7307
7321
  * the matching `task:*` provenance tags emitted by `moltnet_create_entry`
@@ -7520,14 +7534,14 @@ function createMoltNetTools(config) {
7520
7534
  limit: Type.Optional(Type.Number({ description: "Max entries to return (default 10)" })),
7521
7535
  tags: Type.Optional(Type.Array(Type.String({
7522
7536
  minLength: 1,
7523
- maxLength: 50
7537
+ maxLength: DIARY_TAG_MAX_LENGTH
7524
7538
  }), {
7525
7539
  description: "Tags filter — entry must have ALL listed tags (AND). Max 20.",
7526
7540
  maxItems: 20
7527
7541
  })),
7528
7542
  excludeTags: Type.Optional(Type.Array(Type.String({
7529
7543
  minLength: 1,
7530
- maxLength: 50
7544
+ maxLength: DIARY_TAG_MAX_LENGTH
7531
7545
  }), {
7532
7546
  description: "Tags to exclude — entry must have NONE of these. Max 20.",
7533
7547
  maxItems: 20
@@ -7620,14 +7634,14 @@ function createMoltNetTools(config) {
7620
7634
  limit: Type.Optional(Type.Number({ description: "Max results (default 5)" })),
7621
7635
  tags: Type.Optional(Type.Array(Type.String({
7622
7636
  minLength: 1,
7623
- maxLength: 50
7637
+ maxLength: DIARY_TAG_MAX_LENGTH
7624
7638
  }), {
7625
7639
  description: "Entry must have ALL listed tags (AND). Max 20.",
7626
7640
  maxItems: 20
7627
7641
  })),
7628
7642
  excludeTags: Type.Optional(Type.Array(Type.String({
7629
7643
  minLength: 1,
7630
- maxLength: 50
7644
+ maxLength: DIARY_TAG_MAX_LENGTH
7631
7645
  }), {
7632
7646
  description: "Entry must have NONE of these tags. Max 20.",
7633
7647
  maxItems: 20
@@ -7813,7 +7827,7 @@ function createMoltNetTools(config) {
7813
7827
  }),
7814
7828
  async execute(_id, params, _signal, _onUpdate, ctx) {
7815
7829
  if (!HOST_EXEC_ALLOWED.has(params.executable)) throw new Error(`host_exec: '${params.executable}' is not in the allowed list (${[...HOST_EXEC_ALLOWED].join(", ")}). Extend HOST_EXEC_ALLOWED only after explicit security review.`);
7816
- if (ctx?.ui) {
7830
+ if (ctx?.ui && !shouldAutoApproveHostExec(params, config)) {
7817
7831
  const cmdDisplay = [params.executable, ...params.args].join(" ");
7818
7832
  if (!await ctx.ui.confirm("Allow host command?", `The agent wants to run on your machine:\n\n ${cmdDisplay}\n\nAllow?`)) throw new Error(`host_exec: user declined approval for: ${cmdDisplay}`);
7819
7833
  }
@@ -15366,6 +15380,7 @@ async function executePiTask(claimedTask, reporter, opts) {
15366
15380
  clearSessionErrors: () => {},
15367
15381
  getHostCwd: () => mountPath,
15368
15382
  hostExecBaseEnv: new Set([...HOST_EXEC_DEFAULT_BASE_ENV, ...Object.keys(managed.credentials.agentEnv)]),
15383
+ hostExecAutoApprove: opts.hostExecAutoApprove ?? opts.sandboxConfig?.hostExec?.autoApprove ?? false,
15369
15384
  getTaskContext: () => ({
15370
15385
  taskId: task.id,
15371
15386
  taskType: task.taskType,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@themoltnet/pi-extension",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "type": "module",
5
5
  "description": "MoltNet pi extension — sandboxed tool execution in Gondolin VMs with MoltNet identity and persistent memory",
6
6
  "license": "MIT",