@agfpd/iapeer 0.4.72 → 0.4.73

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agfpd/iapeer",
3
- "version": "0.4.72",
3
+ "version": "0.4.73",
4
4
  "description": "Run Claude Code and Codex CLI as local background agents that message each other, wake on demand, and share one memory.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "agfpd",
@@ -277,11 +277,15 @@ export const claudeAdapter: RuntimeAdapter = {
277
277
  *
278
278
  * - '--dangerously-skip-permissions' claude-start.sh:318, spawner.ts:776 —
279
279
  * headless peer has no interactive owner to grant per-tool permission.
280
- * - '--disallowedTools','AskUserQuestion' claude-start.sh:313/316,
281
- * spawner.ts:777 — AskUserQuestion would render in a TUI no headless peer
282
- * owner watches; the question goes "into the void". Default is the literal
283
- * 'AskUserQuestion'; the per-peer override (PEER_DISALLOWED_TOOLS empty =
284
- * allow all) is install-time launch.env, not this path.
280
+ * - '--disallowedTools', <list> claude-start.sh:313/316, spawner.ts:777 —
281
+ * AskUserQuestion would render in a TUI no headless peer owner watches; the
282
+ * question goes "into the void", so it is disallowed by DEFAULT. The value is
283
+ * an OPT-IN per-peer override via spec.disallowedTools (launch.env
284
+ * PEER_DISALLOWED_TOOLS, merged in buildLaunchInvocation): UNDEFINED (the
285
+ * fleet default) → the literal 'AskUserQuestion'; an EXPLICIT empty string →
286
+ * the flag is OMITTED (allow all — e.g. to re-enable AskUserQuestion for a
287
+ * throwaway peer); a non-empty value → that verbatim list. Only an explicitly
288
+ * set env key changes behavior — the whole existing fleet is byte-identical.
285
289
  * - '--add-dir','/' grants the file/edit/bash tools access OUTSIDE cwd (the
286
290
  * CLI equivalent of settings `permissions.additionalDirectories`). A peer
287
291
  * reads/writes its memory vault (often an iCloud Obsidian dir) and ~/.iapeer,
@@ -314,11 +318,14 @@ export const claudeAdapter: RuntimeAdapter = {
314
318
  // active as a fail-SAFE backstop, and the separately-installed PreToolUse hook is
315
319
  // the primary interceptor (it fires regardless of mode — verified live 2.1.201).
316
320
  const gated = spec.approvalMode === 'gated'
321
+ // Opt-in disallowedTools (docs/17 — real-modal acceptance / general per-peer control). UNDEFINED →
322
+ // the hardcoded default 'AskUserQuestion' (fleet unchanged); explicit '' → omit the flag (allow all);
323
+ // a value → that verbatim list. A blank/whitespace value collapses to "omit" (the re-enable case).
324
+ const disallowed = (spec.disallowedTools === undefined ? 'AskUserQuestion' : spec.disallowedTools).trim()
317
325
  return [
318
326
  cfg.claudeBin,
319
327
  ...(gated ? ['--permission-mode', 'default'] : ['--dangerously-skip-permissions']),
320
- '--disallowedTools',
321
- 'AskUserQuestion',
328
+ ...(disallowed ? ['--disallowedTools', disallowed] : []),
322
329
  '--add-dir',
323
330
  '/',
324
331
  ...(spec.systemPromptFile ? ['--system-prompt-file', spec.systemPromptFile] : []),
@@ -34,10 +34,15 @@ export function buildLaunchInvocation(
34
34
  ): LaunchInvocation {
35
35
  const env = cfg.env ?? process.env
36
36
  const launchEnv = readLaunchEnv(spec.cwd, spec.runtime)
37
- const specWithArgs: LaunchSpec =
38
- launchEnv.startArgs.length > 0
39
- ? { ...spec, extraArgs: [...(spec.extraArgs ?? []), ...launchEnv.startArgs] }
40
- : spec
37
+ const specWithArgs: LaunchSpec = {
38
+ ...spec,
39
+ ...(launchEnv.startArgs.length > 0 ? { extraArgs: [...(spec.extraArgs ?? []), ...launchEnv.startArgs] } : {}),
40
+ // launch.env PEER_DISALLOWED_TOOLS opt-in — an explicit spec.disallowedTools (caller override) wins;
41
+ // else the launch.env value (undefined = key absent → adapter default, fleet unchanged).
42
+ ...(spec.disallowedTools === undefined && launchEnv.disallowedTools !== undefined
43
+ ? { disallowedTools: launchEnv.disallowedTools }
44
+ : {}),
45
+ }
41
46
  const argv = adapter.buildArgv(specWithArgs, cfg)
42
47
  const childEnv: NodeJS.ProcessEnv = {
43
48
  ...env,
@@ -159,6 +159,11 @@ export interface LaunchSpec {
159
159
  resumeRef?: string
160
160
  /** Free-form extra CLI args (PEER_START_ARGS). */
161
161
  extraArgs?: string[]
162
+ /** claude `--disallowedTools` value (opt-in per-peer override via launch.env `PEER_DISALLOWED_TOOLS`).
163
+ * UNDEFINED (the default for the whole fleet) → the adapter's hardcoded default (`AskUserQuestion`);
164
+ * an EXPLICIT empty string → the flag is OMITTED (allow all — e.g. re-enable AskUserQuestion); a
165
+ * non-empty value → that verbatim list. Only claude's buildArgv consumes it (codex has no such flag). */
166
+ disallowedTools?: string
162
167
  /** Peer intelligence (artificial/natural/absent). Used to enforce an adapter's
163
168
  * intelligence gate at launch (telegram allows natural|absent). Optional: a doctrine-
164
169
  * less throwaway may omit it, but an adapter that declares allowedIntelligences
@@ -215,6 +215,11 @@ export function peerLaunchEnvPath(cwd: string, runtime: Runtime): string {
215
215
  export interface LaunchEnv {
216
216
  /** Tokens from PEER_START_ARGS, appended AFTER the adapter's base argv flags. */
217
217
  startArgs: string[]
218
+ /** claude `--disallowedTools` override from PEER_DISALLOWED_TOOLS. UNDEFINED = the key was ABSENT
219
+ * (→ the adapter default is used, the whole fleet unchanged); a string (incl. '') = the key was
220
+ * PRESENT (opt-in: '' omits the flag, a value sets it). The absent-vs-empty distinction is the
221
+ * opt-in gate — only an explicitly-present key changes behavior. */
222
+ disallowedTools?: string
218
223
  /** Other KEY=VALUE assignments — extra child-process env for the peer session. */
219
224
  env: Record<string, string>
220
225
  }
@@ -255,8 +260,15 @@ export function readLaunchEnv(cwd: string, runtime: Runtime): LaunchEnv {
255
260
  }
256
261
  const startArgsRaw = (env.PEER_START_ARGS ?? '').trim()
257
262
  delete env.PEER_START_ARGS // consumed as argv, not propagated as a child env var
263
+ // PEER_DISALLOWED_TOOLS — a LAUNCH DIRECTIVE (claude --disallowedTools), not a child env var. Preserve
264
+ // the ABSENT (undefined → default) vs PRESENT-EMPTY ('' → omit the flag) distinction: an unset key must
265
+ // leave the whole fleet on the hardcoded default. Consumed out of the child env like PEER_START_ARGS.
266
+ const hasDisallowed = Object.prototype.hasOwnProperty.call(env, 'PEER_DISALLOWED_TOOLS')
267
+ const disallowedTools = hasDisallowed ? env.PEER_DISALLOWED_TOOLS : undefined
268
+ delete env.PEER_DISALLOWED_TOOLS
258
269
  return {
259
270
  startArgs: startArgsRaw ? startArgsRaw.split(/\s+/) : [],
271
+ ...(disallowedTools !== undefined ? { disallowedTools } : {}),
260
272
  env,
261
273
  }
262
274
  }