mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
feat: 组合包配置集中到 my-pi/ 目录并改为整体重建
- 组合包拥有、可随时重建的配置、日志与缓存统一放在 <agentDir>/my-pi/:permission-system/(policy.jsonc、hard-guards.jsonc、 logs/)、rtk-optimizer/config.json、tool-search/(config.json、 catalog-v1.json)与 system-prompt-cover.md。hashline.json、lsp.json 由外部扩展读取固定路径,是唯一例外。 - 新增 config/bundle-manifest.json 与 scripts/rebuild-bundle-config.mjs: 先校验全部来源与目标,在临时目录构建完整树,再整体删除旧 my-pi/ (符号链接只删链接)并原子替换,不备份。install.sh / update.sh 每次 运行都调用它;扩展自身不再播种或迁移配置。 - update.sh 删除 pi update 失败后的 git clean 恢复逻辑:Pi 1.3.0 会在 下一次 pi update 时依据中断标记自行恢复。同时删除 Tool Search settings.json 快照迁移与封面部署脚本。 - Tool Search 改为读取 my-pi/tool-search/config.json(源为 config/tool-search.json,须与 BUNDLE_TOOL_SEARCH_DEFAULTS 一致), 不再读写 settings.json 的 toolSearch 段,移除 bundleDefaultsVersion。 - 默认权限策略开启 debugLog。 - 旧位置的残留文件不迁移、不清理;AGENTS.md / README 同步新约束。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
7e6a8faae1
commit
2682bd7fa7
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- **Cache approvals within one user message.** An `allow` is reused for the same action while the conversation's latest trusted entry is unchanged; a new user message invalidates the cache, and rejects and failures are never cached.
|
||||
- Bound the rendered transcript with a conservative token estimator (ASCII counts a quarter token per character, every non-ASCII codepoint a full token — `length / 4` under-counts CJK by roughly 2–4x), expose the budgets under `autoReview.transcript` (`messageTokens`, `toolTokens`, `maxUntrustedEntries`), and substitute pi-compaction tool-result summaries when they are strictly shorter.
|
||||
- Make `autoReview.reasoning` effective again (default `"low"`), passed only to reasoning-capable models; add `autoReview.timeoutMs` (default `30000`, total across attempts), `autoReview.maxAttempts` (default `2`), and `autoReview.maxOutputTokens` (default `4000`).
|
||||
- **Move the global config directory into the bundle-owned rebuild tree.** Policy, hard guards, and logs now live under `<agentDir>/my-pi/permission-system/` instead of `<agentDir>/extensions/pi-permission-system/`; the bundle's install/update scripts delete and redeploy that whole directory on every run, so the extension itself never seeds or migrates configuration. Files left at the old location are ignored.
|
||||
|
||||
### Removed
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ pi install npm:@gotgenes/pi-permission-system
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Create ordinary policy at `~/.pi/agent/extensions/pi-permission-system/policy.jsonc`:
|
||||
1. Create ordinary policy at `~/.pi/agent/my-pi/permission-system/policy.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -51,7 +51,7 @@ pi install npm:@gotgenes/pi-permission-system
|
||||
}
|
||||
```
|
||||
|
||||
2. Create independent hard guards at `~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc`:
|
||||
2. Create independent hard guards at `~/.pi/agent/my-pi/permission-system/hard-guards.jsonc`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -86,12 +86,12 @@ The integrated extension uses two independent global JSONC files:
|
||||
|
||||
| Purpose | Scope | Path |
|
||||
| ------- | ----- | ---- |
|
||||
| Ordinary policy, runtime knobs, AutoReview | Global only | `~/.pi/agent/extensions/pi-permission-system/policy.jsonc` |
|
||||
| Non-overridable hard guards | Global only | `~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc` |
|
||||
| Ordinary policy, runtime knobs, AutoReview | Global only | `~/.pi/agent/my-pi/permission-system/policy.jsonc` |
|
||||
| Non-overridable hard guards | Global only | `~/.pi/agent/my-pi/permission-system/hard-guards.jsonc` |
|
||||
|
||||
Project-level `policy.jsonc` files are ignored. Project agent Markdown remains a separate per-agent restriction mechanism.
|
||||
|
||||
The bundle seeds missing files with mode `0600`. During `update.sh`, only the exact known legacy default policy is backed up and replaced by the current bundled seed. Any customized or invalid policy is preserved and reported instead of being guessed or overwritten.
|
||||
The bundle deploys both files with mode `0600` via `scripts/rebuild-bundle-config.mjs`: every `install.sh` / `update.sh` run rebuilds the whole `<agentDir>/my-pi/` tree, overwriting local edits without a backup — keep durable changes in the repository's `config/` sources. Files left at the former `extensions/pi-permission-system/` location are ignored.
|
||||
|
||||
Within a pattern map, the most specific match wins: exact patterns, then more literal characters, fewer wildcards, and longer patterns. Declaration order is only a tie-breaker.
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ Pi Permission System reads two user-level JSONC files:
|
||||
|
||||
| Purpose | Scope | Path |
|
||||
| ------- | ----- | ---- |
|
||||
| Ordinary policy + runtime | Global only | `~/.pi/agent/extensions/pi-permission-system/policy.jsonc` |
|
||||
| Hard guards | Global only | `~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc` |
|
||||
| Ordinary policy + runtime | Global only | `~/.pi/agent/my-pi/permission-system/policy.jsonc` |
|
||||
| Hard guards | Global only | `~/.pi/agent/my-pi/permission-system/hard-guards.jsonc` |
|
||||
|
||||
`PI_CODING_AGENT_DIR` replaces `~/.pi/agent` when set. Project-level `policy.jsonc` files are not loaded. Project agent Markdown may still provide per-agent restrictions; it is not a second ordinary policy file.
|
||||
|
||||
@@ -141,7 +141,7 @@ Each review outcome is written to the permission review log — the resolved mod
|
||||
| `toolTextSummaryMaxLength` | — | **Deprecated and ignored.** Superseded by `promptMaxRows` / `promptFieldMaxWidth`. Still accepted so an existing config is not rejected, but the value no longer applies; setting it logs a warning. |
|
||||
| `authorizerChain` | `[]` | Ordered names of registered live-authority chain links to consult before the terminal authorizer (see [Authorizer chain](#authorizer-chain--case-by-case-decision-links)). |
|
||||
|
||||
Both logs write to `~/.pi/agent/extensions/pi-permission-system/logs/`.
|
||||
Both logs write to `~/.pi/agent/my-pi/permission-system/logs/`.
|
||||
No debug output is printed to the terminal.
|
||||
|
||||
### Inline permission dialog (TUI)
|
||||
|
||||
@@ -49,7 +49,7 @@ If your OpenCode config uses these features, the equivalent works in this extens
|
||||
| `mcp` surface | Not a documented permission surface | First-class with server/tool-level granularity |
|
||||
| Top-level string shorthand | `"permission": "allow"` sets all surfaces | Not supported; must use an object |
|
||||
| Per-agent config location | `agent` key in config JSON or YAML frontmatter | YAML frontmatter in agent `.md` files only |
|
||||
| Config file paths | `~/.config/opencode/opencode.json` | `~/.pi/agent/extensions/pi-permission-system/policy.jsonc` plus global `hard-guards.jsonc` |
|
||||
| Config file paths | `~/.config/opencode/opencode.json` | `~/.pi/agent/my-pi/permission-system/policy.jsonc` plus global `hard-guards.jsonc` |
|
||||
| Subagent prompt forwarding | Not documented | `ask` policies work in non-UI subagent contexts |
|
||||
| Infrastructure auto-allow | N/A | Read-only tools to Pi infra dirs bypass the gate |
|
||||
| Permission review log | No equivalent documented | Writes decisions to a JSONL audit log |
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
| Problem | Cause | Solution |
|
||||
| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Config not applied (everything asks) | File not found or parse error | Verify the global policy at `~/.pi/agent/extensions/pi-permission-system/policy.jsonc` (respects `PI_CODING_AGENT_DIR`); check JSONC syntax |
|
||||
| Config not applied (everything asks) | File not found or parse error | Verify the global policy at `~/.pi/agent/my-pi/permission-system/policy.jsonc` (respects `PI_CODING_AGENT_DIR`); check JSONC syntax |
|
||||
| Per-agent override not applied | Frontmatter parsing issue | Ensure `---` delimiters at file top; keep YAML simple; restart session |
|
||||
| Tool blocked as unregistered | Unknown tool name | Use a registered `mcp` tool for server tools: `{ "tool": "server:tool" }` |
|
||||
| `/skill:<name>` blocked | Deny policy or confirmation unavailable | Check merged `skill` policy (global/project/agent layers). `ask` still requires UI or forwarded confirmation. |
|
||||
@@ -22,7 +22,7 @@ This makes it easy to verify which files the extension actually loaded:
|
||||
```jsonc
|
||||
{
|
||||
"event": "config.resolved",
|
||||
"globalConfigPath": "/…/.pi/agent/extensions/pi-permission-system/policy.jsonc",
|
||||
"globalConfigPath": "/…/.pi/agent/my-pi/permission-system/policy.jsonc",
|
||||
"globalConfigExists": true,
|
||||
"projectConfigPath": "/…/my-project/.pi/extensions/pi-permission-system/policy.jsonc",
|
||||
"projectConfigExists": false,
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
"additionalProperties": false,
|
||||
"title": "PI Permission System Configuration",
|
||||
"description": "Ordinary JSONC policy combining runtime knobs, AutoReview settings, and flat permission rules for pi-permission-system.",
|
||||
"markdownDescription": "Global ordinary JSONC policy for [pi-permission-system](https://github.com/gotgenes/pi-packages/tree/main/packages/pi-permission-system).\n\nPlace at `~/.pi/agent/extensions/pi-permission-system/policy.jsonc`. Project-level policy files are not loaded. Global-only hard guards use the separate `hard-guards.jsonc` schema.",
|
||||
"markdownDescription": "Global ordinary JSONC policy for [pi-permission-system](https://github.com/gotgenes/pi-packages/tree/main/packages/pi-permission-system).\n\nPlace at `~/.pi/agent/my-pi/permission-system/policy.jsonc`. Project-level policy files are not loaded. Global-only hard guards use the separate `hard-guards.jsonc` schema.",
|
||||
"$defs": {
|
||||
"permissionState": {
|
||||
"anyOf": [
|
||||
|
||||
@@ -2,11 +2,20 @@ import { join } from "node:path";
|
||||
|
||||
const EXTENSION_ID = "pi-permission-system";
|
||||
|
||||
/**
|
||||
* Bundle-owned config tree under the agent directory: install.sh / update.sh
|
||||
* delete and rebuild `my-pi/` wholesale on every run, so policy, hard guards,
|
||||
* and logs all live beneath it. Files at the former
|
||||
* `extensions/pi-permission-system/` location are ignored — never migrated.
|
||||
*/
|
||||
const BUNDLE_CONFIG_DIR = "my-pi";
|
||||
const BUNDLE_PERMISSION_DIR = "permission-system";
|
||||
|
||||
export const DEBUG_LOG_FILENAME = `${EXTENSION_ID}-debug.jsonl`;
|
||||
export const REVIEW_LOG_FILENAME = `${EXTENSION_ID}-permission-review.jsonl`;
|
||||
|
||||
export function getGlobalConfigDir(agentDir: string): string {
|
||||
return join(agentDir, "extensions", EXTENSION_ID);
|
||||
return join(agentDir, BUNDLE_CONFIG_DIR, BUNDLE_PERMISSION_DIR);
|
||||
}
|
||||
|
||||
export function getGlobalConfigPath(agentDir: string): string {
|
||||
|
||||
@@ -262,7 +262,7 @@ export const unifiedConfigSchema = z
|
||||
description:
|
||||
"Ordinary JSONC policy combining runtime knobs, AutoReview settings, and flat permission rules for pi-permission-system.",
|
||||
markdownDescription:
|
||||
"Global ordinary JSONC policy for [pi-permission-system](https://github.com/gotgenes/pi-packages/tree/main/packages/pi-permission-system).\n\nPlace at `~/.pi/agent/extensions/pi-permission-system/policy.jsonc`. Project-level policy files are not loaded. Global-only hard guards use the separate `hard-guards.jsonc` schema.",
|
||||
"Global ordinary JSONC policy for [pi-permission-system](https://github.com/gotgenes/pi-packages/tree/main/packages/pi-permission-system).\n\nPlace at `~/.pi/agent/my-pi/permission-system/policy.jsonc`. Project-level policy files are not loaded. Global-only hard guards use the separate `hard-guards.jsonc` schema.",
|
||||
});
|
||||
|
||||
/** A permission decision. */
|
||||
|
||||
@@ -687,7 +687,7 @@ describe("loadAndMergeConfigs", () => {
|
||||
});
|
||||
|
||||
function writeGlobal(content: Record<string, unknown>): void {
|
||||
const dir = join(agentDir, "extensions", "pi-permission-system");
|
||||
const dir = join(agentDir, "my-pi", "permission-system");
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(join(dir, "policy.jsonc"), JSON.stringify(content));
|
||||
}
|
||||
@@ -727,7 +727,7 @@ describe("loadAndMergeConfigs", () => {
|
||||
const result = loadAndMergeConfigs(agentDir, cwd, extensionRoot);
|
||||
expect(result.issues).toHaveLength(1);
|
||||
expect(result.issues[0]).toContain("pi-permissions.jsonc");
|
||||
expect(result.issues[0]).toContain("extensions/pi-permission-system");
|
||||
expect(result.issues[0]).toContain("my-pi/permission-system");
|
||||
// Legacy file has no flat-format permission key — no rules extracted
|
||||
expect(result.merged.permission).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -10,15 +10,15 @@ import {
|
||||
describe("config-paths", () => {
|
||||
const agentDir = "/home/user/.pi/agent";
|
||||
|
||||
it("places the global policy at extensions/pi-permission-system/policy.jsonc under the agent dir", () => {
|
||||
it("places the global policy at my-pi/permission-system/policy.jsonc under the agent dir", () => {
|
||||
expect(getGlobalConfigPath(agentDir)).toBe(
|
||||
join(agentDir, "extensions", "pi-permission-system", "policy.jsonc"),
|
||||
join(agentDir, "my-pi", "permission-system", "policy.jsonc"),
|
||||
);
|
||||
});
|
||||
|
||||
it("places logs next to the global config dir", () => {
|
||||
expect(getGlobalLogsDir(agentDir)).toBe(
|
||||
join(agentDir, "extensions", "pi-permission-system", "logs"),
|
||||
join(agentDir, "my-pi", "permission-system", "logs"),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("config pipeline seam", () => {
|
||||
});
|
||||
|
||||
function writeGlobal(content: Record<string, unknown>): void {
|
||||
const dir = join(agentDir, "extensions", "pi-permission-system");
|
||||
const dir = join(agentDir, "my-pi", "permission-system");
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(join(dir, "policy.jsonc"), JSON.stringify(content));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { PermissionManager } from "#src/permission-manager";
|
||||
|
||||
test("buildResolvedConfigLogEntry reports global and agent policy paths", () => {
|
||||
const policyPaths: ResolvedPolicyPaths = {
|
||||
globalConfigPath: "/home/user/.pi/agent/extensions/pi-permission-system/policy.jsonc",
|
||||
globalConfigPath: "/home/user/.pi/agent/my-pi/permission-system/policy.jsonc",
|
||||
globalConfigExists: true,
|
||||
agentsDir: "/home/user/.pi/agent/agents",
|
||||
agentsDirExists: true,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
import { getGlobalConfigPath } from "#src/config-paths";
|
||||
import { PermissionManager, type PolicyLoader } from "#src/permission-manager";
|
||||
@@ -232,7 +232,7 @@ export function createAgentDirHarness(opts: {
|
||||
const cwd = join(baseDir, "project");
|
||||
|
||||
const globalConfigPath = getGlobalConfigPath(agentDir);
|
||||
mkdirSync(join(agentDir, "extensions", "pi-permission-system"), {
|
||||
mkdirSync(dirname(globalConfigPath), {
|
||||
recursive: true,
|
||||
});
|
||||
writeFileSync(
|
||||
|
||||
Reference in New Issue
Block a user