Skip to content

Latest commit

 

History

History
253 lines (212 loc) · 15.2 KB

File metadata and controls

253 lines (212 loc) · 15.2 KB

Extension Runtime Compatibility Matrix

This document provides a comprehensive compatibility matrix for the Pi extension runtime. It covers Node.js built-in module shims, Bun API surface, npm package stubs, and the Pi SDK -- everything an extension author needs to know about what works in the QuickJS-based runtime.

Node.js Built-in Module Shims

The extension runtime provides shims for standard Node.js built-in modules. Each shim runs inside the QuickJS sandbox and routes I/O through the capability-gated hostcall interface.

Coverage Summary

Module Coverage Key APIs
node:path Full join, dirname, resolve, basename, relative, isAbsolute, extname, normalize, parse, format, sep, delimiter, posix
node:os Full homedir, tmpdir, hostname, platform, arch, type, release, cpus, totalmem, freemem, uptime, loadavg, networkInterfaces, userInfo, endianness, EOL, devNull, constants
node:fs Partial readFileSync, writeFileSync, existsSync, readdirSync, statSync, mkdirSync, rmdirSync, unlinkSync, renameSync, symlinkSync, readlinkSync, realpathSync, copyFileSync, appendFileSync, chmodSync/chownSync path checks, accessSync, lstatSync, openSync, closeSync, readSync, writeSync, fstatSync, createReadStream, createWriteStream, promises.*, callback variants
node:buffer Full Buffer.from, Buffer.alloc, Buffer.allocUnsafe, Buffer.concat, Buffer.isBuffer, Buffer.byteLength, toString(encoding) (utf8, hex, base64, latin1, ascii)
node:events Full EventEmitter class with on, once, off, emit, removeListener, removeAllListeners, listenerCount, listeners, prependListener
node:util Full inspect, promisify, callbackify, format, deprecate, inherits, debuglog, stripVTControlCharacters, types.*, TextEncoder, TextDecoder
node:child_process Full spawn, spawnSync, execSync, exec, execFile, execFileSync, fork (stub)
node:crypto Partial randomBytes, randomUUID, createHash (SHA-256/SHA-384/SHA-512, SHA-1, MD5), createHmac, timingSafeEqual, getHashes, pbkdf2/scrypt, AES-128-GCM/AES-256-GCM createCipheriv/createDecipheriv, Ed25519 sign/verify
node:http Partial request, get, createServer (stub), STATUS_CODES, METHODS, IncomingMessage, ClientRequest -- routes through pi.http() hostcall
node:url Partial URL (globalThis), URLSearchParams, parse, format, resolve, fileURLToPath, pathToFileURL
node:stream Partial Readable, Writable, Transform, PassThrough, Duplex, pipeline, finished
node:net Stub createConnection (stub), Socket (stub); createServer throws -- network APIs outside sandbox
node:readline Partial createInterface, promises.createInterface -- questions use pi.ui('input') when available and resolve to empty strings otherwise

node:fs Detail

The filesystem shim uses a virtual filesystem (VFS) backed by an in-memory Map. Host filesystem access is available through a fallback mechanism that routes readFileSync and statSync calls through the hostcall boundary (capability-gated by the read capability).

API Implementation Notes
readFileSync Real VFS first, host fallback for real files
writeFileSync Real VFS-only (sandboxed)
existsSync Real VFS + host fallback
statSync Real VFS + host fallback
readdirSync Real VFS-only
mkdirSync Real VFS-only, supports recursive
promises.readFile Real Async wrapper around sync
promises.writeFile Real Async wrapper around sync
promises.stat Real Async wrapper around sync
promises.mkdir Real Async wrapper around sync
promises.readdir Real Async wrapper around sync
promises.access Real Async wrapper around sync
promises.rm Real Async wrapper around sync
promises.rename Real Async wrapper around sync
promises.chmod/promises.chown/promises.utimes Partial Path-checking no-ops; missing paths fail with ENOENT
openSync/closeSync/readSync/writeSync Real File descriptor API
readlink/readlinkSync Real VFS symlink target lookup
chmodSync/chownSync Partial Path-checking no-ops; missing paths fail with ENOENT
createReadStream Real Returns Readable stream
createWriteStream Real Returns Writable stream
watch/watchFile Stub No real file watching; existing paths return no-op watcher facades and missing paths fail with ENOENT
Callback variants (readFile, writeFile, etc.) Real 9 callback-style functions

node:crypto Detail

API Implementation Notes
randomBytes(n) Real Uses QuickJS random source
randomUUID() Real v4 UUID generation
createHash(algo) Real SHA-256, SHA-384, SHA-512, SHA-1, MD5 via native hostcall
createHmac(algo, key) Real HMAC-SHA256, HMAC-SHA384, HMAC-SHA512, HMAC-SHA1, HMAC-MD5
timingSafeEqual(a, b) Real Constant-time comparison
getHashes() Real Returns supported algorithm list
pbkdf2/scrypt Real Key derivation via native hostcall
sign/verify Partial Ed25519 with PKCS#8 private and SPKI public keys; RSA/ECDSA fail closed
createCipheriv/createDecipheriv Partial Buffered AES-128-GCM and AES-256-GCM with 12-byte IVs, 16-byte auth tags, optional AAD, and fail-closed unsupported algorithms
createCipher/createDecipher Missing Deprecated password-derived cipher APIs are not implemented

node:child_process Detail

All subprocess APIs route through the pi.exec() hostcall, which requires the exec capability. The exec capability is denied by default in Standard and Safe policy profiles.

API Implementation Notes
spawn(cmd, args, opts) Real Returns ChildProcess with stdout/stderr streams
spawnSync(cmd, args, opts) Real Synchronous via __pi_exec_sync_native
execSync(cmd, opts) Real Shell execution, returns stdout
exec(cmd, opts, cb) Real Async shell execution
execFile(file, args, opts, cb) Real Async file execution
execFileSync(file, args, opts) Real Synchronous file execution
fork(modulePath) Stub Not supported in sandbox

Bun API Surface

The runtime provides a Bun global object for compatibility with extensions that target the Bun runtime.

API Status Notes
Bun.argv Supported Process arguments array
Bun.file(path) Supported Returns object with exists(), text(), arrayBuffer(), json()
Bun.write(dest, data) Supported Write file via node:fs shim
Bun.which(cmd) Supported Locate command via which exec
Bun.spawn(cmd, opts) Supported Via node:child_process shim
Bun.connect(...) Unsupported Network connections outside sandbox
Bun.listen(...) Unsupported Server listeners outside sandbox

npm Package Stubs

Extensions that import npm packages get virtual module stubs. These provide enough API surface for extensions to load and register without errors. Some stubs are functional (e.g., uuid, shell-quote), while others are no-ops for optional features.

Functional Stubs

Package Coverage Key APIs
uuid Functional v4(), v7(), v1(), v3(), v5(), validate(), version()
shell-quote Functional parse(cmd), quote(args)
diff Functional createTwoFilesPatch, createPatch, diffLines, diffChars, diffWords
dotenv Functional config(opts), parse(src)
ms Functional Duration parsing (ms("2h") -> 7200000)
glob Partial globSync, glob, Glob class (basic *, ?, ** over VFS-known files)
jsonwebtoken Partial decode(), HS256/HS384/HS512 sign()/verify(); asymmetric algorithms fail closed

No-op Stubs (Extension Loads, Feature Unavailable)

Package Stubbed APIs Reason
chalk Passthrough (no color) Terminal colors not applicable in QuickJS
chokidar watch() returns no-op File watching not available
jsdom JSDOM class (empty) DOM not available
turndown TurndownService (passthrough) HTML-to-markdown not available
node-pty spawn() returns no-op PTY not available in sandbox
@opentelemetry/* No-op spans/metrics Telemetry not collected
@xterm/* No-op terminal Terminal emulation not available
vscode-languageserver-protocol Type constants only LSP types for compatibility
@sinclair/typebox Type schema builder JSON Schema construction
@modelcontextprotocol/sdk Client, transport classes MCP client stubs
c12 (config loader) define(), loadConfig() Config loading stub
execa bash() returns empty Process execution via hostcall instead
@anthropic-ai/sdk Anthropic class API client stub
@anthropic-ai/bedrock-sdk SandboxManager Sandbox manager stub
openai OpenAI class API client stub
adm-zip AdmZip class Zip handling stub
linkedom parseHTML() DOM parser stub
@sourcegraph/scip-typescript scip.Index class Indexer stub

Pi SDK (@mariozechner/pi-coding-agent)

The Pi SDK virtual module provides the primary extension API surface.

Export Type Description
keyHint(action, fallback) Function Keyboard hint display helper
compact(prep, model, key, instr, signal) Function Context compaction
completeSimple(model, prompt, opts) Function Simple LLM completion
fuzzyMatch(query, text, opts) Function Fuzzy string matching (returns {score, positions})
fuzzyFilter(query, items, opts) Function Filter items by fuzzy match score
Text, Container, Markdown, Spacer Classes TUI rendering components
Editor, Box, SelectList, Input Classes TUI input components
Image, DynamicBorder, CancellableLoader Classes TUI display components
Key Object Key binding constants
CURSOR_MARKER String Cursor position marker
truncateToWidth, visibleWidth, wrapTextWithAnsi Functions Text rendering utilities
getEditorKeybindings Function Editor key binding configuration
VERSION, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES Constants Runtime constants
truncateHead, truncateTail Functions Content truncation
parseSessionEntries, convertToLlm, serializeConversation Functions Session data utilities
createBashTool, createReadTool, createWriteTool, etc. Functions Tool factory functions
getAgentDir, copyToClipboard Functions System utilities
highlightCode, getLanguageFromPath Functions Code display helpers
AssistantMessageComponent, ToolExecutionComponent, UserMessageComponent Classes Message rendering
SessionManager Class Session state management

Pi AI SDK (@mariozechner/pi-ai)

Export Type Description
StringEnum(values) Function Enum type builder
calculateCost() Function Token cost calculation (uses model.cost × usage tokens)
getEnvApiKey(provider) Function Capability-filtered environment key lookup
getOAuthApiKey(provider) Function Unsupported in PiJS; fails closed
complete(model, messages, opts) Function Unsupported in PiJS without a provider host bridge; fails closed
completeSimple(model, prompt, opts) Function Unsupported in PiJS without a provider host bridge; fails closed
createAssistantMessageEventStream() Function Async-iterable assistant event stream factory for extension providers
streamSimpleAnthropic() Function Unsupported in PiJS without a provider host bridge; fails closed
streamSimpleOpenAIResponses() Function Unsupported in PiJS without a provider host bridge; fails closed
streamSimpleOpenAICompletions() Function Unsupported in PiJS without a provider host bridge; fails closed
getProviders(), getModel(provider, modelId), getModels(provider) Functions Synchronous built-in registry lookup for bundled provider metadata; currently includes OpenAI Codex models needed by extension provider mirrors
getApiProvider(api) Function Synchronous provider bridge for known API IDs; stream calls route through the host provider bridge and fail closed if unavailable
getModel(), getApiProvider(), getModels() with no lookup arguments Functions Session/model host-context helpers; fail closed when no host bridge is configured

Conformance Status

Tested against a corpus of 223 real-world extensions:

Source Tier Pass Fail N/A Total Pass Rate
Official (pi-mono) 56 4 6 66 93.3%
Community 58 0 0 58 100%*
npm Registry 63 12 0 75 84.0%*
Third-party GitHub 20 3 0 23 87.0%*
Agents 1 0 0 1 100%*

*Community/npm/third-party extensions are tested via the compatibility validation pack, which uses a broader load-and-register test rather than the full differential oracle.

Remaining Failure Categories

Category Count Root Cause
Multi-file dependency resolution 4 Relative specifiers across files not yet supported
Missing npm package specifiers 5 Extensions import real npm packages not stubbed
Host-read policy denial 4 Extension reads files outside allowed root
Runtime shape/load errors 4 Miscellaneous load-time errors
Test fixture (not a real extension) 1 base_fixtures is test infrastructure

Runtime API Matrix

Surface Pass Fail Total
Node.js APIs 13 0 13
Bun APIs 5 2 7

Failing Bun APIs: Bun.connect and Bun.listen (network server/client APIs outside the extension sandbox).

Unsupported Features

These features are intentionally not supported in the extension sandbox:

Feature Reason Alternative
Native Node addons (.node) Binary modules cannot run in QuickJS Use hostcalls or WASM
Direct network sockets Security boundary enforcement Use pi.http() hostcall
Direct filesystem access Capability-gated for safety Use pi.tool("Read", ...) or node:fs shim
Server listeners (net.createServer) Extensions are clients, not servers Not applicable
Worker threads QuickJS is single-threaded Not applicable
node:cluster Process clustering not available Not applicable
node:dgram UDP sockets outside sandbox Not applicable
node:tls TLS handled by host HTTP client Use pi.http() with HTTPS

Version Information

  • QuickJS runtime: embedded via rquickjs crate
  • Node.js API target: Node 18+ compatibility subset
  • Bun API target: Bun 1.x compatibility subset
  • Extension API version: 1.0