Skip to content

Hor1zonZzz/pi-codeMode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pi-codemode-extension

pi-codemode-extension is a Pi package that registers an exec tool. Code Mode is the execution style: the tool lets Pi write and run one JavaScript async function that can orchestrate active Pi built-in tools through a typed codemode object.

This follows Pi's extension/package conventions: the extension is a TypeScript module, it registers an LLM-callable tool with pi.registerTool(), and the package exposes the extension through the pi.extensions manifest in package.json.

Quick Start

Install dependencies for local development:

npm install

Try the extension for a single Pi run:

pi -e ./extensions/code-mode.ts

Install this directory as a Pi package:

pi install .

Install into project-local settings instead of user settings:

pi install . -l

Uninstall

pi remove pi-codemode-extension

pi remove uninstalls the package and removes its settings entry. The persisted /codeMode config is written by the extension itself and is not tracked by Pi, so delete it manually if you want a fully clean uninstall:

rm ~/.pi/agent/codemode-extension.json

Package Manifest

Pi loads this package through the pi manifest in package.json:

{
  "pi": {
    "extensions": ["./extensions/code-mode.ts"]
  }
}

The extension entrypoint exports the standard Pi extension factory:

import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";

export default function codeModeExtension(pi: ExtensionAPI) {
  pi.registerTool({
    name: "exec",
    // ...
  });
}

Pi core packages are declared as peer dependencies, following the package guidance for imports that Pi already provides:

{
  "peerDependencies": {
    "@earendil-works/pi-coding-agent": "*",
    "@earendil-works/pi-tui": "*",
    "typebox": "*"
  }
}

Usage

Ask Pi to use exec when a task benefits from loops, branching, or multiple tool calls in one structured program.

Example tool input:

async () => {
  const root = await codemode.ls({ path: "." });
  console.log("Root entries:", root);
  return root;
}

The tool returns a JSON summary containing:

  • result: the value returned by the async function
  • logs: captured console.log/info/warn/error calls
  • calls: each codemode.* tool call, duration, status, and preview
  • durationMs: total runtime
  • timedOut: whether execution exceeded the timeout
  • error: runtime, validation, tool, or timeout error text when present

The /codeMode Command

Run /codeMode in an interactive Pi session to open a settings overlay. Use the arrow keys to move and Space to cycle each row:

  • Code Modeenabled / disabled. When enabled, the built-in tools are hidden from the model and exec is exposed in their place; the model can only reach them indirectly through exec. When disabled, exec is hidden and the built-in tools Pi had at startup are restored.
  • tool: read / write / edit / bash / grep / find / lson / off. Controls which built-in tools exec is allowed to orchestrate. Calling an off tool from inside exec fails that call with a clear error.

Changes apply immediately and persist across sessions in ~/.pi/agent/codemode-extension.json (alongside Pi's own config; honors $PI_CODING_AGENT_DIR). On first run of each session the defaults are seeded from the tools Pi has active at startup.

Available codemode API

exec recreates the Pi built-in tool definitions for the current session cwd. Its description declares exactly the tools currently enabled in /codeMode, e.g. with everything on:

codemode.read(input);
codemode.write(input);
codemode.edit(input);
codemode.bash(input);
codemode.grep(input);
codemode.find(input);
codemode.ls(input);

Notes:

  • exec does not expose itself recursively.
  • When you toggle a tool in /codeMode, exec is re-registered so its description always matches the orchestrable set — the model is never shown a tool it cannot call. (Toggling a tool therefore invalidates the prompt cache once; toggling Code Mode on/off does too.)
  • exec executes its own copies of the built-in tool definitions, so it can orchestrate a tool even though that tool is hidden from the model directly.
  • Arbitrary third-party extension tools are not exposed because Pi currently provides them through pi.getAllTools() as metadata, not executable definitions.

Safety Model

The JavaScript runs in a Worker-backed Node.js node:vm context. It exposes codemode, a limited console, and JSON-safe globals. It does not directly expose require, process, filesystem APIs, or network APIs.

This is a local execution guard, not a Cloudflare Worker or isolated-vm security boundary. Pi extensions and Pi packages run with full local system permissions, so only install and run code you trust.

Development

Run the TypeScript check:

npm run check

Runtime smoke test:

PI_OFFLINE=1 pi -e ./extensions/code-mode.ts --help

References


pi-codemode-extension 中文说明

pi-codemode-extension 是一个 Pi package,会注册一个 exec 工具。Code Mode 是执行模式:这个工具允许 Pi 写入并执行一个 JavaScript async 函数,然后通过类型化的 codemode 对象编排当前启用的 Pi 内置工具。

这个包遵循 Pi 的 extension/package 规范:扩展是 TypeScript 模块,通过 pi.registerTool() 注册可供模型调用的工具,并在 package.jsonpi.extensions manifest 中声明入口文件。

快速开始

安装本地开发依赖:

npm install

只在当前 Pi 运行中临时加载扩展:

pi -e ./extensions/code-mode.ts

把当前目录安装为 Pi package:

pi install .

安装到项目级配置,而不是用户级配置:

pi install . -l

卸载

pi remove pi-codemode-extension

pi remove 会卸载这个包并删除它的 settings 条目。/codeMode 的持久化配置是扩展自己 写的,Pi 不会跟踪它,所以如果想彻底清理干净,需要手动删除:

rm ~/.pi/agent/codemode-extension.json

Package Manifest

Pi 通过 package.json 里的 pi manifest 加载这个包:

{
  "pi": {
    "extensions": ["./extensions/code-mode.ts"]
  }
}

扩展入口导出标准 Pi extension factory:

import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";

export default function codeModeExtension(pi: ExtensionAPI) {
  pi.registerTool({
    name: "exec",
    // ...
  });
}

Pi 核心包按照 package 文档建议声明为 peer dependencies,因为这些导入由 Pi 运行时提供:

{
  "peerDependencies": {
    "@earendil-works/pi-coding-agent": "*",
    "@earendil-works/pi-tui": "*",
    "typebox": "*"
  }
}

使用方式

当一个任务需要循环、条件分支,或者一次性组合多个工具调用时,可以让 Pi 使用 exec

工具输入示例:

async () => {
  const root = await codemode.ls({ path: "." });
  console.log("Root entries:", root);
  return root;
}

工具会返回 JSON 摘要,包含:

  • result:async 函数返回值
  • logs:捕获到的 console.log/info/warn/error
  • calls:每次 codemode.* 调用的工具名、耗时、状态和预览
  • durationMs:总运行时间
  • timedOut:是否超时
  • error:运行时错误、参数校验错误、工具错误或超时错误

/codeMode 命令

在交互式 Pi 会话里运行 /codeMode 会打开一个设置面板。用方向键移动,用空格切换每一行的值:

  • Code Mode —— enabled / disabled。启用时,内置工具会从模型面前隐藏,由 exec 取而代之,模型只能通过 exec 间接调用它们;禁用时,exec 被隐藏,并恢复 Pi 启动时原有的内置工具。
  • tool: read / write / edit / bash / grep / find / ls —— on / off,控制 exec 被允许编排哪些内置工具。在 exec 里调用一个 off 的工具会让该次调用失败 并返回明确错误。

修改即时生效,并保存在 ~/.pi/agent/codemode-extension.json 中跨会话持久化(与 Pi 自身配置放在一起,并遵循 $PI_CODING_AGENT_DIR)。每个会话首次运行时,默认值会根据 Pi 启动时启用的工具来初始化。

可用的 codemode API

exec 会基于当前 session 的 cwd 重新创建 Pi 内置工具定义。它的描述只声明 /codeMode 中当前启用的工具 —— 例如全部开启时:

codemode.read(input);
codemode.write(input);
codemode.edit(input);
codemode.bash(input);
codemode.grep(input);
codemode.find(input);
codemode.ls(input);

注意:

  • exec 不会递归暴露自己。
  • /codeMode 里切换某个工具时,exec 会被重新注册,其描述始终与可编排集合一致 —— 模型永远不会看到一个它无法调用的工具。(因此切换单个工具会让 prompt 缓存失效一次; 切换 Code Mode 总开关同样如此。)
  • exec 执行的是它自己复制的内置工具定义,所以即使某个工具对模型直接隐藏,exec 仍可编排它。
  • 任意第三方 extension 工具不会被暴露,因为 Pi 目前通过 pi.getAllTools() 提供的是工具元数据,不是可执行定义。

安全模型

JavaScript 运行在 Worker 承载的 Node.js node:vm context 中。沙箱暴露 codemode、受限 console 和 JSON 安全的全局对象,不直接暴露 requireprocess、文件系统 API 或网络 API。

这只是本地执行防护,不是 Cloudflare Worker 或 isolated-vm 级别的安全边界。Pi extensions 和 Pi packages 拥有完整本机权限,所以只安装和运行你信任的代码。

开发

运行 TypeScript 检查:

npm run check

运行加载 smoke test:

PI_OFFLINE=1 pi -e ./extensions/code-mode.ts --help

参考

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors