全书 159 条引用,覆盖 51 个文件。每条都由 tools/check-citations.mjs 核对过:该行在 ac4ac9e 上的实际内容必须包含正文声称的片段。摘录截断至 110 字符。
| 行 | 该行内容(@ ac4ac9e) | 出现于 |
|---|---|---|
.github/APPROVED_CONTRIBUTORS 1 处 | ||
| L2 | # Format: <username> <capability> | 18 |
.github/workflows/approve-contributor.yml 3 处 | ||
| L33 | const approvalAtStartPattern = /^[\s.]*(?:@[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?(?:\s*,\s*|[.:]\s*|\s+ | 18 |
| L34 | const approvalAtEndPattern = /(?:^|[\s.])(lgtmi|lgtm)\s*(?:[^\p{L}\p{N}_\s])?\s*$/iu; | 18 |
| L35 | const approvalMatch = commentBody.match(approvalAtStartPattern) ?? commentBody.match(approvalAtEndPattern); | 18 |
.github/workflows/issue-analysis.yml 1 处 | ||
| L1 | # Runs the repo's /is prompt against an issue when the `pi-analyze` label is added | 13 |
.github/workflows/issue-gate.yml 2 处 | ||
| L100 | 'This issue was auto-closed. All issues from new contributors are auto-closed by default.', | 18 |
| L102 | `Maintainers review auto-closed issues daily and reopen worthwhile ones. Issues that do not meet the quality b | 18 |
.gitignore 1 处 | ||
| L11 | packages/ai/src/providers/data/ | 01 09 |
.npmrc 1 处 | ||
| L2 | min-release-age=2 | 16 |
.pi/extensions/import-repro.ts 1 处 | ||
| L2 | * Import a pi session shared as a gist by the issue-analysis CI workflow | 13 |
AGENTS.md 15 处 | ||
| L14 | - Read files in full before wide-ranging changes, before editing files you have not fully inspected, and when | 17 |
| L19 | - Never remove or downgrade code to fix type errors from outdated deps; upgrade the dep instead. | 17 |
| L21 | - Always ask before removing functionality or code that appears intentional. | 17 |
| L23 | - Never hardcode key checks (e.g. `matchesKey(keyData, "ctrl+x")`). Add defaults to `DEFAULT_EDITOR_KEYBINDING | 17 |
| L24 | - Never modify `packages/ai/src/models.generated.ts` directly; update `packages/ai/scripts/generate-models.ts` | 17 |
| L30 | - Never run the full vitest suite directly: it includes e2e tests that activate when endpoint/auth env vars ar | 17 |
| L34 | - For `packages/coding-agent/test/suite/`, use `test/suite/harness.ts` + the faux provider. No real provider A | 17 |
| L35 | - Put issue-specific regressions under `packages/coding-agent/test/suite/regressions/` named `<issue-number>-< | 17 |
| L42 | - When updating `undici`, you MUST read its changelog/release notes for the target version and evaluate whethe | 16 |
| L45 | - If `packages/coding-agent/npm-shrinkwrap.json` needs regen, run `node scripts/generate-coding-agent-shrinkwr | 16 |
| L55 | - Stage explicit paths (`git add <path1> <path2>`); never `git add -A` / `git add .`. | 17 |
| L67 | - If a conflict is in a file you did not modify, abort and ask the user. | 17 |
| L155 | Use `npm_config_min_release_age=0` only for the release command. The repo's normal npm age gate can otherwise | 16 |
| L159 | 4. **CI verifies and announces the npm release**: pushing the `vX.Y.Z` tag triggers `.github/workflows/build-b | 16 |
| L165 | If the user's instructions conflict with any rule in this document, ask for explicit confirmation before overr | 17 |
CONTRIBUTING.md 11 处 | ||
| L9 | If your feature does not belong in the core, it should be an extension. PRs that bloat the core will likely be | 01 |
| L11 | Pi's core exists to be minimal and to be extensible so that it can be influenced and manipulated by extensions | 02 03 |
| L15 | **You must understand your code.** If you cannot explain what your changes do and how they interact with the r | 18 |
| L17 | Using AI to write code is fine. Submitting AI-generated slop without understanding it is not. | 18 |
| L19 | If you use an agent, run it from the `pi` root directory so it picks up `AGENTS.md` automatically. Your agent | 17 |
| L23 | All issues and PRs from new contributors are auto-closed by default. | 18 |
| L25 | Issues submitted Friday through Sunday are not guaranteed to be reviewed. If something is urgent, ask on Disc | 18 |
| L34 | The command must be at the start of the reply (optionally after one or more `@username` mentions) or at the en | 18 |
| L42 | - Keep it concise. If it does not fit on one screen, it is too long. | 18 |
| L52 | If you ignore this document twice, or if you spam the tracker with agent-generated issues, your GitHub account | 18 |
| L93 | AI can help group duplicates, summarize reports, and spot missing information. It is not trusted to make final | 18 |
README.md 8 处 | ||
| L40 | Pi does not include a built-in permission system for restricting filesystem, process, network, or credential a | 15 |
| L50 | See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines and [AGENTS.md](AGENTS.md) for project-spec | 17 |
| L56 | npm run build # Refresh model data, then build all packages | 01 09 |
| L74 | The source archive includes the generated provider model data used for the release. `--offline-model-data` bui | 09 |
| L80 | - Direct external dependencies are pinned to exact versions. Internal workspace packages remain version-ranged | 16 |
| L84 | - The published CLI package includes `packages/coding-agent/npm-shrinkwrap.json`, generated from the root lock | 16 |
| L86 | - Local release installs, documented npm installs, and `pi update --self` use `--ignore-scripts` where support | 16 |
| L87 | - CI installs with `npm ci --ignore-scripts`, and a scheduled GitHub workflow runs `npm audit --omit=dev` plus | 16 |
package.json 1 处 | ||
| L18 | "check": "biome check --write --error-on-warnings . && npm run check:pinned-deps && npm run check:ts-imports & | 16 |
packages/agent/README.md 2 处 | ||
| L13 | The SQLite session backend and the `node:sqlite` adapter live in a separate package, `@earendil-works/pi-sessi | 07 |
| L299 | agent.shouldStopAfterTurn = async ({ context }) => shouldCompactBeforeNextTurn(context.messages); | 03 06 |
packages/agent/docs/harness-v2.md 12 处 | ||
| L3 | > **Compatibility policy.** Old coding-agent v3 JSONL sessions must open and restore idle. This is the only ba | 07 |
| L32 | - **Single writer.** One harness writes a session at a time. The serving layer enforces this. All lanes of a s | 07 |
| L3169 | Work is limited to `packages/agent`, `packages/session-backends/sqlite-node`, `packages/telemetry`, and the te | 08 19 |
| L3173 | 1. Sync with `main`. A package is claimable only when its checkbox is empty, every dependency is checked, and | 19 |
| L3174 | 2. Add `**Reserved: <package-id> by @<username>.**` immediately above the package entry. Land that change alon | 08 19 |
| L3178 | 2. Implement comprehensive focused tests that encode the package's acceptance criteria and every design invari | 19 |
| L3180 | 4. If the design does not hold, stop and consult Mario on Discord. After agreement, update the design and pack | 19 |
| L3189 | - Acceptance: a table-driven scaffold test covers every public method and proves no unfinished method reports | 08 |
| L3193 | This table is exhaustive. A package does not remove `HarnessNotImplemented` from a method until it owns the li | 19 |
| L3260 | **In progress and reserved: @davidbrai.** The work began before this plan was split into J0–J6. Before merge, | 08 19 |
| L3307 | **Reserved: I2 by @vegarsti.** | 08 |
| L3330 | **Reserved: L1 by @cristinaponcela.** Other agents must not pick L1 while this ownership marker remains. | 08 |
packages/agent/src/agent-loop.ts 29 处 | ||
| L64 | export function agentLoopContinue( | 03 |
| L104 | const currentContext: AgentContext = { | 03 |
| L136 | const currentContext: AgentContext = { ...context }; | 03 |
| L155 | async function runLoop( | 03 |
| L167 | let pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || []; | 03 |
| L196 | if (message.stopReason === "error" || message.stopReason === "aborted") { | 03 |
| L248 | await config.shouldStopAfterTurn?.({ | 03 |
| L259 | pendingMessages = (await config.getSteeringMessages?.()) || []; | 03 |
| L290 | if (config.transformContext) { | 05 |
| L295 | const llmMessages = await config.convertToLlm(messages); | 05 |
| L305 | const resolvedApiKey = | 10 |
| L377 | * best-effort JSON salvage parser, so a truncated message can yield tool calls | 03 |
| L396 | `Tool call "${toolCall.name}" was not executed: the response hit the output token limit, so its arguments may | 03 |
| L419 | const hasSequentialToolCall = toolCalls.some( | 04 |
| L422 | if (config.toolExecution === "sequential" || hasSequentialToolCall) { | 04 |
| L489 | async function executeToolCallsParallel( | 04 |
| L522 | finalizedCalls.push(async () => { | 04 |
| L540 | const orderedFinalizedCalls = await Promise.all( | 03 04 |
| L582 | function shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean { | 03 |
| L586 | function prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall { | 04 |
| L600 | async function prepareToolCall( | 04 |
| L607 | const tool = currentContext.tools?.find((t) => t.name === toolCall.name); | 04 |
| L618 | const validatedArgs = validateToolArguments(tool, preparedToolCall); | 04 |
| L636 | if (beforeResult?.block) { | 04 |
| L670 | async function executePreparedToolCall( | 04 |
| L683 | (partialResult) => { | 04 |
| L724 | if (config.afterToolCall) { | 04 |
| L747 | } catch (error) { | 04 |
| L782 | // Untyped tools (JS extensions) can return results without content; normalize | 04 |
packages/agent/src/agent.ts 2 处 | ||
| L437 | private createContextSnapshot(): AgentContext { | 03 |
| L588 | for (const listener of this.listeners) { | 03 |
packages/agent/src/harness/agent-harness.ts 2 处 | ||
| L351 | if (record !== undefined) throw new HarnessNotImplemented("create.restore"); | 08 |
| L356 | return Promise.reject(this.closed ? new HarnessClosed() : new HarnessNotImplemented(operation)); | 08 |
packages/agent/src/harness/compaction/compaction.ts 1 处 | ||
| L312 | function findValidCutPoints(entries: Entry[], startIndex: number, endIndex: number): number[] { | 06 |
packages/agent/src/harness/session/jsonl/codec.ts 2 处 | ||
| L7 | const ENTRY_TYPES = new Set<Entry["type"]>([ | 07 |
| L16 | const RECORD_TYPES = new Set<LaneRecord["type"]>([ | 07 |
packages/agent/src/harness/session/jsonl/types.ts 1 处 | ||
| L47 | export interface JsonlV4Header { | 07 |
packages/agent/src/harness/session/testing/conformance.ts 2 处 | ||
| L92 | export function createSessionBackendConformance( | 07 08 |
| L242 | await rejectsWithCode(session.findRecords({ limit: 0 }), "invalid_query"); | 07 |
packages/agent/src/harness/session/types.ts 2 处 | ||
| L18 | parentId: string | null; // storage-assigned: the appending lane's leaf | 07 |
| L317 | findOpenOperations(lane: string, options?: { limit?: number }): Promise<OperationStartedRecord[]>; | 07 |
packages/agent/src/harness/types.ts 1 处 | ||
| L315 | export interface ExecutionEnv extends FileSystem, Shell {} | 02 |
packages/agent/src/index.ts 1 处 | ||
| L75 | } from "./harness/compaction/compaction.ts"; | 06 |
packages/agent/test/harness/session/jsonl.test.ts 1 处 | ||
| L79 | const conformance = createSessionBackendConformance(async () => { | 07 |
packages/agent/test/harness/session/memory.test.ts 1 处 | ||
| L8 | const conformance = createSessionBackendConformance(() => | 07 |
packages/ai/README.md 4 处 | ||
| L3 | Unified LLM API with provider collections, automatic auth resolution, token and cost tracking, and simple cont | 02 |
| L5 | **Note**: This library only includes models that support tool calling (function calling), as this is essential | 02 09 |
| L330 | When you call `models.stream()`, the collection resolves auth through the owning provider and merges it into t | 09 10 |
| L343 | const providerAuth = await models.getAuth(model.provider); | 10 |
packages/ai/src/utils/event-stream.ts 1 处 | ||
| L21 | push(event: T): void { | 03 |
packages/coding-agent/README.md 1 处 | ||
| L498 | **No MCP.** Build CLI tools with READMEs (see [Skills](#skills)), or build an extension that adds MCP support. | 02 |
packages/coding-agent/docs/compaction.md 2 处 | ||
| L6 | - [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/earendil-works/pi-mono/blob/m | 06 |
| L23 | Both use the same structured summary format and track file operations cumulatively. Compaction and branch-summ | 06 |
packages/coding-agent/docs/containerization.md 1 处 | ||
| L17 | Extensions run wherever the `pi` process runs. If you run host `pi` with a tool-routing extension, other custo | 15 |
packages/coding-agent/docs/extensions.md 1 处 | ||
| L111 | > **Security:** Extensions run with your full system permissions and can execute arbitrary code. Only install | 12 |
packages/coding-agent/docs/json.md 1 处 | ||
| L7 | Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs. | 14 |
packages/coding-agent/docs/rpc.md 1 处 | ||
| L5 | **Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` | 14 |
packages/coding-agent/docs/security.md 7 处 | ||
| L9 | Pi considers a project to have resources that require trust when it finds any of these from the current workin | 15 |
| L27 | Declining trust skips protected resources. Context files such as `AGENTS.override.md`, `AGENTS.md`, and `CLAUD | 15 |
| L29 | Non-interactive modes (`-p`, `--mode json`, and `--mode rpc`) do not show a trust prompt. Without an applicabl | 15 |
| L37 | Project trust is only an input-loading guard. It prevents a repository from silently changing pi's settings or | 15 |
| L53 | If you bind-mount a host workspace read/write, writes from inside the container or VM can still modify host fi | 15 |
| L57 | To report a security issue, follow the repository [Security Policy](https://github.com/earendil-works/pi-mono/ | 15 |
| L59 | Expected local-agent behavior, lack of a built-in sandbox, prompt injection from untrusted content, and behavi | 15 |
packages/coding-agent/docs/skills.md 1 处 | ||
| L1 | > pi can create skills. Ask it to build one for your use case. | 13 |
packages/coding-agent/src/core/agent-session.ts 4 处 | ||
| L1952 | * Called after agent_end and before prompt submission. | 03 06 |
| L1997 | if (!willRetry) { | 06 |
| L1998 | return await this._runAutoCompaction("overflow", false); | 06 |
| L2049 | if (shouldCompact(contextTokens, contextWindow, settings)) { | 06 |
packages/coding-agent/src/core/compaction/compaction.ts 7 处 | ||
| L132 | export const DEFAULT_COMPACTION_SETTINGS: CompactionSettings = { | 06 |
| L308 | function isCutPointMessage(message: AgentMessage): boolean { | 06 |
| L347 | * Never cut at tool results (they must follow their tool call). | 06 |
| L355 | if (entry.type === "compaction") { | 06 |
| L403 | export function findCutPoint( | 06 |
| L710 | export function prepareCompaction( | 06 |
| L817 | export async function compact( | 06 |
packages/coding-agent/src/core/extensions/types.ts 2 处 | ||
| L397 | options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" }, | 03 |
| L1034 | export type ExtensionEvent = | 12 |
packages/coding-agent/src/core/messages.ts 7 处 | ||
| L11 | export const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the fo | 05 |
| L19 | export const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back | 05 |
| L148 | export function convertToLlm(messages: AgentMessage[]): Message[] { | 05 |
| L154 | if (m.excludeFromContext) { | 05 |
| L162 | case "custom": { | 05 |
| L176 | case "compactionSummary": | 05 |
| L190 | const _exhaustiveCheck: never = m; | 05 |
packages/coding-agent/src/core/sdk.ts 2 处 | ||
| L294 | agent = new Agent({ | 08 |
| L350 | transformContext: async (messages) => { | 05 |
packages/coding-agent/src/core/session-manager.ts 3 处 | ||
| L30 | export const CURRENT_SESSION_VERSION = 3; | 07 |
| L474 | * Encodes cwd into a safe directory name under ~/.pi/agent/sessions/. | 07 |
| L845 | * Manages conversation sessions as append-only trees stored in JSONL files. | 07 |
packages/coding-agent/src/server/create-harness.ts 1 处 | ||
| L151 | const created = await AgentHarness.create({ | 08 |
packages/coding-agent/test/server/create-harness.test.ts 1 处 | ||
| L78 | expect(await created.harness.getActiveTools()).toEqual(["read", "bash", "edit", "write"]); | 08 |
packages/protocol/README.md 1 处 | ||
| L10 | The first client message is always `hello`, containing `PROTOCOL_VERSION`. Subsequent messages use correlated | 14 |
packages/protocol/src/schemas.ts 1 处 | ||
| L37 | /** Matches AgentHarnessPhase so adapters do not need a second phase vocabulary. */ | 08 |
packages/server/README.md 1 处 | ||
| L3 | Experimental. This package is under active development and may change or be removed without notice. Its APIs a | 01 |
packages/session-backends/sqlite-node/test/conformance.test.ts 1 处 | ||
| L24 | const conformance = createSessionBackendConformance(async () => { | 07 |
packages/tui/README.md 1 处 | ||
| L8 | - **Differential Rendering**: Updates only changed lines or viewport rows | 11 |
scripts/check-lockfile-commit.mjs 1 处 | ||
| L5 | const allowValue = process.env.PI_ALLOW_LOCKFILE_CHANGE; | 16 |
scripts/check-pinned-deps.mjs 1 处 | ||
| L60 | console.error("Direct external dependencies must use exact versions:"); | 16 |
scripts/generate-coding-agent-shrinkwrap.mjs 1 处 | ||
| L13 | const allowedInstallScriptPackages = new Map([ | 16 |