From 5efa6c3b464bafcbe295aab185df398e6a13016f Mon Sep 17 00:00:00 2001 From: Julius Olsson Date: Thu, 27 Aug 2026 18:48:39 -0700 Subject: [PATCH] fix: match the host's real capability set and correct the preset import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two things in this package told authors something the host does not do. ExtensionCapability declared ten capabilities. The host implements three. The other seven — fs.read, transcript.read, git.read, sessions.prompt, fs.write, git.commit, network.fetch — had no request method, no broker arm and no API surface, and Agent Code now refuses to install a manifest that asks for one. That inverted this package's entire purpose. It exists so an author gets a type error instead of a runtime surprise, and instead `permissions: ['fs.write']` type-checked cleanly and then failed the install with a message about a capability the SDK had just told them was valid. A capability belongs in this union only once the host can perform it. The vite preset's usage comment named `agent-code-extension-api/vite`. The package declares exactly one export path ("."), so that subpath resolves to nothing and an author copying the line got a module-not-found before their first build. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Hyzz9bxqTQ2zSawmHDN72o --- dist/manifest.d.ts | 17 +++++++++++++++-- dist/vite-preset.js | 6 +++++- package.json | 2 +- src/manifest.ts | 27 +++++++++++++++------------ src/vite-preset.ts | 6 +++++- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/dist/manifest.d.ts b/dist/manifest.d.ts index 060df36..2124518 100644 --- a/dist/manifest.d.ts +++ b/dist/manifest.d.ts @@ -41,8 +41,21 @@ export type ExtensionContributions = { settings?: ExtensionSettingContribution[]; keybindings?: ExtensionKeybindingContribution[]; }; -/** A power requested beyond the always-granted Tier-0 API. Granted at install. */ -export type ExtensionCapability = 'workspace.observe' | 'sessions.observe' | 'panes.observe' | 'fs.read' | 'transcript.read' | 'git.read' | 'sessions.prompt' | 'fs.write' | 'git.commit' | 'network.fetch'; +/** + * A power requested beyond the always-granted Tier-0 API. Granted at install. + * + * ── THIS LIST MUST MATCH WHAT THE HOST IMPLEMENTS, NOT WHAT IT PLANS TO ── + * It previously also declared fs.read, transcript.read, git.read, sessions.prompt, + * fs.write, git.commit and network.fetch. None of them were implemented anywhere: + * no request method could carry them, no broker arm performed them, and the host + * now REFUSES to install a manifest that asks for one. + * + * Keeping them here was worse than useless. This package exists so an author gets + * a type error instead of a runtime surprise — and it delivered the exact opposite: + * `permissions: ['fs.write']` type-checked cleanly and then failed the install. + * A capability belongs in this union only once the host can actually perform it. + */ +export type ExtensionCapability = 'workspace.observe' | 'sessions.observe' | 'panes.observe'; export type ExtensionActivationEvent = 'onStartupFinished' | '*' | `onCommand:${string}` | `onView:${string}`; export type ExtensionManifest = { id: string; diff --git a/dist/vite-preset.js b/dist/vite-preset.js index 9857f04..bf3f7ad 100644 --- a/dist/vite-preset.js +++ b/dist/vite-preset.js @@ -15,8 +15,12 @@ // dev guards throw at activate() unless it is defined at build time. // // Usage — vite.config.ts: -// import { extensionViteConfig } from 'agent-code-extension-api/vite' +// import { extensionViteConfig } from 'agent-code-extension-api' // export default extensionViteConfig() +// +// NOTE the specifier: the package exposes exactly ONE export path ("." in +// package.json), so the `/vite` subpath this comment used to name resolves to +// nothing — an author copying it got a module-not-found before their first build. /** A plain object matching Vite's `UserConfig` shape — returned untyped so this * package need not depend on vite. Spread/return it from vite.config.ts. */ export function extensionViteConfig(options = {}) { diff --git a/package.json b/package.json index d6435cf..503e7e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agent-code-extension-api", - "version": "0.2.0", + "version": "0.3.0", "description": "Types and authoring helpers for building Agent Code extensions.", "type": "module", "main": "dist/index.js", diff --git a/src/manifest.ts b/src/manifest.ts index 21a30d9..0f01b72 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -37,18 +37,21 @@ export type ExtensionContributions = { keybindings?: ExtensionKeybindingContribution[] } -/** A power requested beyond the always-granted Tier-0 API. Granted at install. */ -export type ExtensionCapability = - | 'workspace.observe' - | 'sessions.observe' - | 'panes.observe' - | 'fs.read' - | 'transcript.read' - | 'git.read' - | 'sessions.prompt' - | 'fs.write' - | 'git.commit' - | 'network.fetch' +/** + * A power requested beyond the always-granted Tier-0 API. Granted at install. + * + * ── THIS LIST MUST MATCH WHAT THE HOST IMPLEMENTS, NOT WHAT IT PLANS TO ── + * It previously also declared fs.read, transcript.read, git.read, sessions.prompt, + * fs.write, git.commit and network.fetch. None of them were implemented anywhere: + * no request method could carry them, no broker arm performed them, and the host + * now REFUSES to install a manifest that asks for one. + * + * Keeping them here was worse than useless. This package exists so an author gets + * a type error instead of a runtime surprise — and it delivered the exact opposite: + * `permissions: ['fs.write']` type-checked cleanly and then failed the install. + * A capability belongs in this union only once the host can actually perform it. + */ +export type ExtensionCapability = 'workspace.observe' | 'sessions.observe' | 'panes.observe' export type ExtensionActivationEvent = | 'onStartupFinished' diff --git a/src/vite-preset.ts b/src/vite-preset.ts index 4e9283a..26d6fa9 100644 --- a/src/vite-preset.ts +++ b/src/vite-preset.ts @@ -15,8 +15,12 @@ // dev guards throw at activate() unless it is defined at build time. // // Usage — vite.config.ts: -// import { extensionViteConfig } from 'agent-code-extension-api/vite' +// import { extensionViteConfig } from 'agent-code-extension-api' // export default extensionViteConfig() +// +// NOTE the specifier: the package exposes exactly ONE export path ("." in +// package.json), so the `/vite` subpath this comment used to name resolves to +// nothing — an author copying it got a module-not-found before their first build. export type ExtensionViteOptions = { /** Entry module path. Default: 'src/index.ts'. Must match manifest `entry` once built. */