refactor(internal-urls): renamed embedded docs protocol from pi:// to omp://

- Renamed the internal URL protocol handler from `pi` to `omp` and updated the router export/import wiring to use `OmpProtocolHandler` with the `omp://` scheme.
- Updated embedded documentation link rendering and related validation/error messages in the protocol handler to reference `omp://` URLs.
- Adjusted tests and prompt/docs references so `read` examples and harness documentation guidance now use the renamed `omp://` scheme.
This commit is contained in:
can1357
2026-05-16 18:48:08 +02:00
parent 9bd4d0099b
commit 959cd42798
8 changed files with 23 additions and 19 deletions
+2 -2
View File
@@ -10,7 +10,7 @@
- `packages/coding-agent/src/tools/archive-reader.ts` — detect `archive.ext:inner/path`, index archives, list/read entries.
- `packages/coding-agent/src/tools/sqlite-reader.ts` — detect SQLite targets, parse selectors, render tables.
- `packages/coding-agent/src/tools/fetch.ts` — URL parsing, fetch/render pipeline, URL cache/artifacts.
- `packages/coding-agent/src/internal-urls/router.ts` — resolve `agent://`, `artifact://`, `local://`, `mcp://`, `memory://`, `pi://`, `rule://`, `skill://`.
- `packages/coding-agent/src/internal-urls/router.ts` — resolve `agent://`, `artifact://`, `local://`, `mcp://`, `memory://`, `omp://`, `rule://`, `skill://`.
- `packages/coding-agent/src/edit/notebook.ts` — convert `.ipynb` to editable `# %% [...] cell:N` text.
- `packages/coding-agent/src/utils/file-display-mode.ts` — decide hashline vs line-number vs raw display.
- `packages/coding-agent/src/workspace-tree.ts` — render directory trees.
@@ -194,7 +194,7 @@ URL selectors are parsed separately in `packages/coding-agent/src/tools/fetch.ts
### Internal URLs
- `read` does not resolve these itself; it delegates to `session.internalRouter.resolve()`.
- Registered protocols are outside this file, but the router in `packages/coding-agent/src/internal-urls/router.ts` is built for `agent://`, `artifact://`, `issue://`, `local://`, `mcp://`, `memory://`, `pi://`, `pr://`, `rule://`, and `skill://`.
- Registered protocols are outside this file, but the router in `packages/coding-agent/src/internal-urls/router.ts` is built for `agent://`, `artifact://`, `issue://`, `local://`, `mcp://`, `memory://`, `omp://`, `pr://`, `rule://`, and `skill://`.
- `#handleInternalUrl()` behavior:
- parses the URL with `parseInternalUrl()` so colons inside the host segment are legal
- for `agent://`, treats non-root path extraction or `?q=` extraction as a special no-pagination mode
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Breaking Changes
- Renamed the embedded-documentation internal URL scheme from `pi://` to `omp://`. `OmpProtocolHandler` replaces `PiProtocolHandler`; update any external references accordingly.
## [15.1.2] - 2026-05-15
### Fixed
@@ -15,8 +15,8 @@ export * from "./json-query";
export * from "./local-protocol";
export * from "./mcp-protocol";
export * from "./memory-protocol";
export * from "./omp-protocol";
export * from "./parse";
export * from "./pi-protocol";
export * from "./router";
export * from "./rule-protocol";
export * from "./skill-protocol";
@@ -1,23 +1,23 @@
/**
* Protocol handler for pi:// URLs.
* Protocol handler for omp:// URLs.
*
* Serves statically embedded documentation files bundled at build time.
*
* URL forms:
* - pi:// - Lists all available documentation files
* - pi://<file>.md - Reads a specific documentation file
* - omp:// - Lists all available documentation files
* - omp://<file>.md - Reads a specific documentation file
*/
import * as path from "node:path";
import { EMBEDDED_DOC_FILENAMES, EMBEDDED_DOCS } from "./docs-index.generated";
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
/**
* Handler for pi:// URLs.
* Handler for omp:// URLs.
*
* Resolves documentation file names to their content, or lists available docs.
*/
export class PiProtocolHandler implements ProtocolHandler {
readonly scheme = "pi";
export class OmpProtocolHandler implements ProtocolHandler {
readonly scheme = "omp";
readonly immutable = true;
async resolve(url: InternalUrl): Promise<InternalResource> {
@@ -38,7 +38,7 @@ export class PiProtocolHandler implements ProtocolHandler {
throw new Error("No documentation files found");
}
const listing = EMBEDDED_DOC_FILENAMES.map(f => `- [${f}](pi://${f})`).join("\n");
const listing = EMBEDDED_DOC_FILENAMES.map(f => `- [${f}](omp://${f})`).join("\n");
const content = `# Documentation\n\n${EMBEDDED_DOC_FILENAMES.length} files available:\n\n${listing}\n`;
return {
@@ -52,12 +52,12 @@ export class PiProtocolHandler implements ProtocolHandler {
async #readDoc(filename: string, url: InternalUrl): Promise<InternalResource> {
// Validate: no traversal, no absolute paths
if (path.isAbsolute(filename)) {
throw new Error("Absolute paths are not allowed in pi:// URLs");
throw new Error("Absolute paths are not allowed in omp:// URLs");
}
const normalized = path.posix.normalize(filename.replaceAll("\\", "/"));
if (normalized === ".." || normalized.startsWith("../") || normalized.includes("/../")) {
throw new Error("Path traversal (..) is not allowed in pi:// URLs");
throw new Error("Path traversal (..) is not allowed in omp:// URLs");
}
const content = EMBEDDED_DOCS[normalized];
@@ -69,7 +69,7 @@ export class PiProtocolHandler implements ProtocolHandler {
const suffix =
suggestions.length > 0
? `\nDid you mean: ${suggestions.join(", ")}`
: "\nUse pi:// to list available files.";
: "\nUse omp:// to list available files.";
throw new Error(`Documentation file not found: ${filename}${suffix}`);
}
@@ -1,5 +1,5 @@
/**
* Internal URL router for internal protocols (agent://, artifact://, memory://, skill://, rule://, mcp://, pi://, local://).
* Internal URL router for internal protocols (agent://, artifact://, memory://, skill://, rule://, mcp://, omp://, local://).
*
* One process-global router with one handler per scheme. Access via
* `InternalUrlRouter.instance()`. Handlers are stateless; per-session and
@@ -11,8 +11,8 @@ import { IssueProtocolHandler, PrProtocolHandler } from "./issue-pr-protocol";
import { LocalProtocolHandler } from "./local-protocol";
import { McpProtocolHandler } from "./mcp-protocol";
import { MemoryProtocolHandler } from "./memory-protocol";
import { OmpProtocolHandler } from "./omp-protocol";
import { parseInternalUrl } from "./parse";
import { PiProtocolHandler } from "./pi-protocol";
import { RuleProtocolHandler } from "./rule-protocol";
import { SkillProtocolHandler } from "./skill-protocol";
import type { InternalResource, InternalUrl, ProtocolHandler, ResolveContext } from "./types";
@@ -23,7 +23,7 @@ export class InternalUrlRouter {
#handlers = new Map<string, ProtocolHandler>();
constructor() {
this.register(new PiProtocolHandler());
this.register(new OmpProtocolHandler());
this.register(new AgentProtocolHandler());
this.register(new ArtifactProtocolHandler());
this.register(new MemoryProtocolHandler());
@@ -1,7 +1,7 @@
/**
* Types for the internal URL routing system.
*
* Internal URLs (agent://, artifact://, memory://, skill://, rule://, mcp://, pi://, local://) are resolved by tools like read,
* Internal URLs (agent://, artifact://, memory://, skill://, rule://, mcp://, omp://, local://) are resolved by tools like read,
* providing access to agent outputs and server resources without exposing filesystem paths.
*/
@@ -62,7 +62,7 @@ With most FS/bash-like tools, static references to them will automatically resol
- `mcp://<uri>`: MCP resource
- `issue://<N>` (or `issue://<owner>/<repo>/<N>`): GitHub issue view; cached on disk so re-reads are free. Bare `issue://` (or `issue://<owner>/<repo>`) lists recent issues; supports `?state=open|closed|all&limit=&author=&label=`.
- `pr://<N>` (or `pr://<owner>/<repo>/<N>`): GitHub PR view; same cache. Append `?comments=0` to drop the comments section. Bare `pr://` (or `pr://<owner>/<repo>`) lists recent PRs; supports `?state=open|closed|merged|all&limit=&author=&label=`.
- `pi://`: Harness documentation; AVOID reading unless user mentions the harness itself
- `omp://`: Harness documentation; AVOID reading unless user mentions the harness itself
{{#if skills.length}}
# Skills
@@ -99,7 +99,7 @@ describe("readArgsTargetInternalUrl", () => {
it.each([
["skill://my-skill"],
["skill://my-skill/file.md"],
["pi://docs/tools/read.md"],
["omp://docs/tools/read.md"],
["issue://123"],
["pr://can1357/oh-my-pi/456"],
["agent://abc"],