@trim21/personal-pi-extensions 0.1.592 → 0.1.593

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
@@ -399,7 +399,7 @@ System prompt for the agent goes here.
399
399
  ```
400
400
 
401
401
  - **默认只读**:frontmatter 不声明 `tools` 时只有 `read`/`grep`/`find`/`ls`,没有 bash/write/edit
402
- - **`sandbox`**:完整沙箱配置直接作为该子代理 bash 的沙箱(不读用户 sandbox.json),非沙盒请求直接拒绝,`/bwrap-*` 命令不注册;不声明则跟随用户沙箱配置
402
+ - **`sandbox`**:完整沙箱配置直接作为该子代理 bash 的沙箱(不读用户 sandbox.json),非沙盒请求直接拒绝,`/bwrap-*` 命令不注册;不声明则用子代理默认沙箱 `fs: readonly` + `network: block`(同样不继承用户 sandbox.json,需要写工作区或联网须显式声明)
403
403
  - **校验跳过**:frontmatter 校验失败(缺 name/description、字段类型错)的文件直接跳过
404
404
  - **全局默认**:`~/.pi/agent/spawn-agent.json`(provider / model / thinkingLevel),frontmatter 优先于它,二者都优先于 settings.json 的默认值
405
405
  - **可见子代理列表**通过工具的 promptGuidelines 注入 system prompt;改 `agents/*.md` 或 `spawn-agent.json` 后 `/reload` 生效
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.1.592",
3
+ "version": "0.1.593",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -37,7 +37,9 @@
37
37
  * Fields are optional and fall back to the standard bwrap defaults (e.g.
38
38
  * `sandbox: { fs: { mode: readonly } }` alone is enough for a read-only shell);
39
39
  * `fs.extraWritablePaths` is the writable escape hatch under a read-only fs mode.
40
- * Without `sandbox`, the subagent's bash follows the user bwrap config.
40
+ * Without `sandbox`, the bash tool falls back to SUBAGENT_DEFAULT_SANDBOX
41
+ * (readonly fs, blocked network; see spawn-agent.ts) instead of the user's
42
+ * bwrap config.
41
43
  *
42
44
  * Global defaults for provider/model/thinkingLevel come from
43
45
  * `~/.pi/agent/spawn-agent.json` (see loadSpawnAgentConfig); frontmatter
@@ -89,7 +91,7 @@ export interface AgentConfig {
89
91
  model?: string;
90
92
  /** Thinking level, applied via --thinking. */
91
93
  thinkingLevel?: (typeof THINKING_LEVELS)[number];
92
- /** bash 的完整沙箱配置(bwrap.json 同构);undefined 表示跟随用户 bwrap 配置。 */
94
+ /** bash 的完整沙箱配置(bwrap.json 同构);undefined 表示用子代理默认沙箱(只读 + 断网)。 */
93
95
  sandbox?: BwrapConfig;
94
96
  systemPrompt: string;
95
97
  filePath: string;
@@ -33,6 +33,9 @@
33
33
  * (sandbox.json shape, e.g. fs.mode readonly): it is passed to the subagent's
34
34
  * bwrap runtime as the complete config, unsandboxed execution requests are
35
35
  * refused, and /bwrap-* commands are not registered (see spawn-agent-agents.ts).
36
+ * Without `sandbox:` the bash tool gets SUBAGENT_DEFAULT_SANDBOX (readonly fs,
37
+ * blocked network) with the same fixed-sandbox semantics: subagents never
38
+ * inherit the user's sandbox.json, whose modes may be relaxed for interactive use.
36
39
  */
37
40
 
38
41
  import { existsSync } from "node:fs";
@@ -58,6 +61,7 @@ import {
58
61
  } from "@earendil-works/pi-coding-agent";
59
62
  import { Type } from "typebox";
60
63
 
64
+ import { type BwrapConfig, completeBwrapConfig } from "./bwrap/core.js";
61
65
  import { type BwrapRuntime, createBwrapRuntime } from "./bwrap/runtime.js";
62
66
  import { registerShellTools } from "./claude-code/shell.js";
63
67
  import { type ToolPendant } from "./lib/pendant.js";
@@ -77,6 +81,16 @@ import {
77
81
  const MAX_OUTPUT_BYTES = 50 * 1024;
78
82
  /** Read-only toolset used when an agent does not declare `tools`. */
79
83
  const DEFAULT_TOOLS = ["read", "grep", "find", "ls"];
84
+ /**
85
+ * 子代理未在 frontmatter 声明 `sandbox` 时 bash 使用的固定沙箱:文件系统只读 + 断网。
86
+ * 与主会话(跟随用户 sandbox.json)相反,子代理不继承用户配置——为交互会话放宽的
87
+ * 模式不应被自动委派的任务顺带复用;要写工作区或联网的 agent 必须在 frontmatter 里
88
+ * 显式声明自己的 sandbox。
89
+ */
90
+ export const SUBAGENT_DEFAULT_SANDBOX: BwrapConfig = completeBwrapConfig({
91
+ fs: { mode: "readonly" },
92
+ network: { mode: "block" },
93
+ });
80
94
  /** Progress log keeps only the most recent lines (rolling window). */
81
95
  const MAX_PROGRESS_LINES = 5;
82
96
  /** Progress line content (without the `tool:` / `text:` prefix) is capped at 21 chars; longer text is folded to the first/last 9 chars joined by ` … `. */
@@ -283,15 +297,19 @@ export function overrideExtensionPaths(tools: string[]): string[] {
283
297
  /**
284
298
  * bash 类工具(opencode `bash` / cc `Bash`)的内联扩展工厂:bwrap runtime 随闭包
285
299
  * 携带该 agent 的完整沙箱配置(frontmatter `sandbox`,已在 discoverAgents 补全成
286
- * BwrapConfig)。路径式 override(additionalExtensionPaths)没有 per-agent 配置
287
- * 通道,extensionFactories 的工厂闭包是 SDK 提供的唯一注入点。agent.sandbox 为
288
- * undefined 时与各注册函数的默认构造完全一致(跟随用户 bwrap 配置)。
300
+ * BwrapConfig),未声明时用 SUBAGENT_DEFAULT_SANDBOX。路径式 override
301
+ * (additionalExtensionPaths)没有 per-agent 配置通道,extensionFactories 的工厂
302
+ * 闭包是 SDK 提供的唯一注入点。
289
303
  */
290
304
  export function subagentShellExtension(
291
305
  agent: AgentConfig,
292
306
  register: (pi: ExtensionAPI, runtime: BwrapRuntime) => void,
293
307
  ): InlineExtension {
294
- return (pi) => register(pi, createBwrapRuntime(createRequestPolicy(pi.events), agent.sandbox));
308
+ return (pi) =>
309
+ register(
310
+ pi,
311
+ createBwrapRuntime(createRequestPolicy(pi.events), agent.sandbox ?? SUBAGENT_DEFAULT_SANDBOX),
312
+ );
295
313
  }
296
314
 
297
315
  /**