원클릭으로
meta-tool-creator
Create custom Pi tools via extensions that the LLM can call. Use when adding new callable functions for the LLM.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Create custom Pi tools via extensions that the LLM can call. Use when adding new callable functions for the LLM.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Bosun configuration — models, sandbox, daemon, Pi settings. Use when changing models, editing config, or understanding how bosun is set up.
Bootstrap a new project using bosun as a foundation — via bun dependency (recommended) or git submodule. Creates a downstream project that inherits bosun's multi-agent infrastructure while adding custom agents, skills, and extensions. Works standalone — fetchable by any pi agent via raw GitHub URL.
Search curated markdown memory like sessions, plans, docs, and skills. Use when recalling prior context or looking for relevant historical/project knowledge.
Analyze Pi session JSONL files using jq patterns. Use when extracting metrics, tool usage, costs, or reviewing session history. Load for session export, summarization, or workflow analysis.
Session-based browser plan review primitives for Bosun. Provides a local-first state model, markdown-aware anchor extraction, and review-session persistence for reviewing existing plan files in dedicated CDP browser windows. Triggers: "plan-review", "review this plan", "review markdown plan".
Session-based browser diff review primitives for Bosun. Provides transport- agnostic v1 schemas plus local state and git snapshot helpers for immutable review rounds. Triggers: "diff-review", "reround", "review round", "snapshot-backed review".
| name | meta-tool-creator |
| description | Create custom Pi tools via extensions that the LLM can call. Use when adding new callable functions for the LLM. |
| license | MIT |
| compatibility | pi |
| metadata | {"audience":"developers","category":"meta"} |
Create custom tools that extend Pi's capabilities. Tools are functions the LLM can call during conversations.
Use this skill when:
Do NOT use for:
Create .pi/extensions/my-tool/index.ts:
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Type } from "@sinclair/typebox";
export default function myTool(pi: ExtensionAPI) {
pi.registerTool({
name: "my_tool",
label: "My Tool",
description: "Query the project database",
parameters: Type.Object({
query: Type.String({ description: "SQL query to execute" }),
}),
async execute(_toolCallId, params, _onUpdate, ctx, _signal) {
const result = `Executed: ${params.query}`;
return {
content: [{ type: "text", text: result }],
};
},
});
}
async execute(_toolCallId, params, _onUpdate, ctx, signal) {
// ctx provides session context
const cwd = ctx.cwd; // Current working directory
const hasUI = ctx.hasUI; // Is UI available?
// signal for cancellation
if (signal.aborted) {
return { content: [{ type: "text", text: "Cancelled" }] };
}
return {
content: [{ type: "text", text: `Working in ${cwd}` }],
};
}
import { Text } from "@mariozechner/pi-tui";
pi.registerTool({
name: "my_tool",
// ... params ...
async execute(_toolCallId, params, _onUpdate, ctx, _signal) {
return {
content: [{ type: "text", text: "Done" }],
details: { count: 42 }, // Custom details for rendering
};
},
renderCall(args, theme) {
return new Text(theme.fg("accent", `my_tool: ${args.query}`), 0, 0);
},
renderResult(result, _options, theme) {
const count = result.details?.count || 0;
return new Text(theme.fg("success", `Processed ${count} items`), 0, 0);
},
});
.pi/extensions/<name>/index.ts"extensions": ["extensions/*"] in settings (no config change needed)import { Type } from "@sinclair/typebox";
Type.String({ description: "A string" })
Type.Number({ description: "A number" })
Type.Boolean({ description: "A boolean" })
Type.Optional(Type.String()) // Optional field
Type.Array(Type.String()) // Array of strings
Type.Union([Type.Literal("a"), Type.Literal("b")]) // Enum-like
Type.Object({ nested: Type.String() }) // Nested object
import { exec } from "child_process";
import { promisify } from "util";
const execAsync = promisify(exec);
async execute(_toolCallId, params, _onUpdate, ctx, _signal) {
// Python
const { stdout } = await execAsync(`python3 script.py ${params.input}`);
// Or with Bun
const result = await Bun.$`./script.sh ${params.param}`.text();
return { content: [{ type: "text", text: stdout.trim() }] };
}
For tools that need user input, use ctx.ui.custom():
const result = await ctx.ui.custom<string | null>((tui, theme, _kb, done) => {
// Return render/handleInput functions
// Call done(value) when complete
});
See the pi-question extension for a full example.
{ content: [{ type: "text", text: "..." }] }renderResultbun build to check for errors