feat(agent-core-v2): add built-in capabilities (kimi-cu, kimi-webbridge) with REST routes - #2407
feat(agent-core-v2): add built-in capabilities (kimi-cu, kimi-webbridge) with REST routes#2407wbxl2000 wants to merge 15 commits into
Conversation
…ge) with REST routes
Add a capability domain holding a closed registry of built-in product
capabilities. Each entry owns layered readiness detection and idempotent
install orchestration: binary runtimes from fixed official CDN URLs
(KimiCU.app + launchd service + TCC permission state; the WebBridge
daemon with start-if-down semantics for Kimi Work coexistence) plus
agent wiring through the plugin service. The WebBridge wiring un-shadows
stale user-source skill copies (user priority beats plugin priority).
kap-server exposes the domain as GET /api/v1/capabilities,
GET /api/v1/capabilities/{id}, and POST /api/v1/capabilities/{id}:install
with client-polled progress and new wire codes 40418 / 40922 / 40923.
The plugin marketplace gains an official kimi-webbridge entry
(browser-control skills) packaged by the existing CDN build.
🦋 Changeset detectedLatest commit: 0635e99 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db8b9da550
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| await ctx.plugins.installPlugin({ source: PLUGIN_ZIP_URL }); | ||
| // Un-shadow the plugin copy: the user-source skill (priority 20) wins | ||
| // over the plugin source (priority 5) on name collisions. | ||
| await rm(userSourceSkillDir, { recursive: true, force: true }); |
There was a problem hiding this comment.
Preserve existing user WebBridge skills
When the user has a hand-authored or modified ~/.kimi-code/skills/kimi-webbridge skill, this unconditional recursive removal deletes that user-owned directory during capability install. The priority conflict is real, but the installer needs to verify this is the known legacy official copy or back it up before removing it; otherwise installing WebBridge can erase user data.
Useful? React with 👍 / 👎.
| platform: process.platform, | ||
| arch: process.arch, | ||
| kimiHomeDir: bootstrap.homeDir, | ||
| userHomeDir: homedir(), |
There was a problem hiding this comment.
Use the bootstrap host snapshot
When a test or embedding host seeds IBootstrapService with an overridden platform, arch, or osHomeDir, this constructor ignores that snapshot and reads process globals instead. In those contexts capability support checks and WebBridge install/detect run against the real process home/platform rather than the configured host, so sandboxed servers can write under the user's actual ~/.kimi-webbridge or report the wrong platform state; use bootstrap.platform, bootstrap.arch, and bootstrap.osHomeDir here.
Useful? React with 👍 / 👎.
| ctx.fetchImpl, | ||
| ); | ||
| await mkdir(binDir, { recursive: true }); | ||
| await rename(staging, binPath).catch(async (error: NodeJS.ErrnoException) => { |
There was a problem hiding this comment.
Avoid overwriting a running Windows daemon
On Windows, when WebBridge was installed once and the daemon is still running from ~\.kimi-webbridge\bin\kimi-webbridge.exe, this rename tries to replace the running executable before checking /status. Windows keeps running executables locked, so an idempotent reinstall/upgrade fails with EPERM and never reaches the start-if-down/plugin refresh path; check daemon status before replacing the binary or stage a versioned replacement for a user-driven restart.
Useful? React with 👍 / 👎.
…dge-skill An official kimi-webbridge guide plugin (install/remove setup skills, v3.0.4) already exists at the marketplace path the capability installer pointed at — a different artifact owned by another release line. Give the browser-control usage-skill plugin its own id/path instead of colliding with (or overwriting) the guide plugin. The capability entry's detect/install now tracks kimi-webbridge-skill; a machine with only the guide plugin correctly reports the skill layer as missing.
…ayers Two changes to make the plugin marketplace a first-class install path: - Marketplace gains kimi-cu (sourced from the CU team's CDN zip — no repackaging) and the kimi-webbridge usage-skill plugin now claims the kimi-webbridge id at v4.0.0, deliberately superseding the WebBridge guide plugin (v3.0.4, install/remove guide skills): guide users get a version upgrade onto the real usage skill. - The capability service subscribes to IPluginService.onDidReload: when a capability's wiring step flips to ok through ANY install path (shelf, TUI, CLI), it auto-completes the missing binary layers (KimiCU.app + service, or the WebBridge daemon). Triggers only on the false→true edge so completed installs with still-missing manual steps (TCC permissions) never retrigger heavy downloads on later reloads.
…tream skill The plugin version tracks the bundled official usage skill (1.11.3) so version drift against the WebBridge release line stays visible, instead of minting an independent 4.0.0.
…on as the product version The on-disk ~/.kimi-webbridge/bin/kimi-webbridge.version file tracks the installer's own lineage (3.1.x, bumps on every install/upgrade run), not the product version (v1.11.3 — daemon, extension, and skills all share it). A downed daemon would have shown the misleading installer number; report no version instead (live /status remains the source of truth).
Marketplace versions are optional by schema: rows display the version detected from the installed plugin's manifest, and update prompts only fire on a valid semver latest > local comparison. A hand-maintained number would drift just like the guide plugin's did. The locally built kimi-webbridge entry keeps its manifest-stamped version (1.11.3).
…plicit reload installPlugin / setPluginEnabled / removePlugin changed the catalog silently — consumers listening to onDidReload (session skill-catalog convergence, the capability shelf-install hook) only converged on an explicit reloadPlugins(). Fire the same summary-shaped event on every mutation (added:[id] / [] / removed:[id]) so every install path converges. This also unbreaks the shelf-install hook on real hosts: its unit tests passed against a fake emitter that fired on installs, which the real service never did.
Expose the App-scope plugin service over the wire so non-CLI hosts
(desktop, web) can manage plugins end to end:
- GET /api/v1/plugins/marketplace — catalog (pluginMarketplaceUrl
server option / KIMI_CODE_PLUGIN_MARKETPLACE_URL env / production
default) merged on demand with live install state; updateAvailable
only on strict semver catalog > installed (no semver dependency)
- GET /api/v1/plugins, POST /api/v1/plugins {source}
- POST /api/v1/plugins/{id}:{enable,disable,remove}
- New wire code 40419 plugin.not_found
Mutations flow through IPluginService, so they serialize with other
install paths and fire onDidReload (session skill catalogs and the
capability shelf-install hook converge).
CapabilityEntry.install now resolves an optional note exposed through CapabilityInstallProgress.note (wire-visible). The webbridge entry returns 'user-skill-migrated' when it replaces a pre-existing user-source skill (from the official installer) with the plugin-managed copy — clients can localize the migration instead of the skill silently disappearing from the user's directory.
…ed promo The hardcoded Web Bridge row was built when WebBridge had no plugin package — it pinned above the Official tab and shadowed any catalog entry with the same id (open-in-browser only). Now that the marketplace carries the real kimi-webbridge plugin, flip the precedence: the catalog entry renders and installs normally, and the pinned promo becomes a loading/error/legacy-catalog fallback only. Footer counts keep their old semantics (catalog-only; the promo row is never counted).
…action Both badges shared a near-identical green-ish treatment in the same column, making a quiet fact look like a clickable action. States now recede (installed → textDim) while actions stay loud (install → primary, update → warning).
… home Multiple hosts share one KIMI_CODE_HOME (CLI, desktop, other agents), but each PluginService kept a private in-memory snapshot: a plugin installed or removed in one process stayed invisible to every other live process until its next restart — new sessions there kept offering stale plugin skills/MCP, and the capability shelf hook never saw peer installs. Watch <home>/plugins for installed.json changes and reloadPlugins (debounced, echo-suppressed around our own mutations) so all consumers converge in well under a second: session skill catalogs, plugin MCP mounts, and the capability shelf-install hook alike.
kimi-code resolves user-scope skills from two roots (~/.kimi-code/skills and ~/.agents/skills), both at priority 20 — a stale copy in either shadows the plugin-managed wiring (priority 5), and also keeps the capability working after the plugin is removed, which reads as 'uninstall did nothing'. Migrate copies in both dirs during install; other runtimes' dirs (~/.claude, ~/.codex) remain untouched.
Installing a capability plugin (kimi-cu, kimi-webbridge) from the
/plugins shelf kicked off a silent background binary install — the row
flipped to installed while megabytes of runtime downloaded invisibly.
Route capability entries through the capability surface instead: the
panel's inline installing line now mirrors live progress (step +
percent) until the install settles, and the transcript reports
ready / failure-with-retry / still-running accordingly. Capability
removal prints an explicit note that runtime binaries are deliberately
left untouched (the capability keeps working), since that read as
'uninstall did nothing'.
Plumbs the capability service through klient's global facade
('capabilityService' decorator resolves in-process) and the node-sdk
v2 client; Session exposes it with a structural feature-detect so v1
engines fail clearly.
…client Only the capability-aware clients auto-install the KimiCU.app runtime; older builds still get wiring-only (the wrapper's error message then points at the official setup script). Don't overpromise in the catalog text every version reads.
What
Adds a capability domain to agent-core-v2: a closed registry of built-in product capabilities that own layered readiness detection and idempotent install orchestration, exposed by kap-server as REST routes — and wired into the plugin marketplace so shelf installs are complete installs.
Capability domain (
agent-core-v2/src/app/capability/)Two hardcoded entries (install sources are fixed official CDN URLs, never client-supplied):
kimi-cu(macOS): official plugin (stdio MCP wrapper + skill) → KimiCU.app download +dittointo /Applications (osascript elevation fallback) → launchd service registration → TCC permission state machine (machine-readable via barerequest-permissions).kimi-webbridge(macOS/Linux/Windows): platform-matrix daemon download → start-if-down (never stop/restart/uninstall — Kimi Work desktop coexistence contract) → plugin wiring viaIPluginService→ removes stale user-source skill copies (user priority 20 shadows plugin priority 5).Installs are idempotent and re-entrant; progress lives in memory and is client-polled (no WS events in v1).
installPlugin's upsert semantics make reinstall = upgrade.kap-server routes
GET /api/v1/capabilities·GET /api/v1/capabilities/{id}·POST /api/v1/capabilities/{id}:install40418,40922,40923Marketplace
kimi-webbridgeplugin (official) — the real browser-control usage skill, version-aligned with the bundled upstream skill (v1.11.3). It takes over thekimi-webbridgeid, replacing the WebBridge guide plugin (v3.0.4, install/remove guide skills) — the intended end state. Packaged by the existing CDN build. Theplugins/cdnartifacts need a republish for it to appear in production.kimi-cumarketplace entry — sourced directly from the CU team's CDN zip (no repackaging), making the shelf row installable.Shelf-install hook
CapabilityServicesubscribes toIPluginService.onDidReload: when a capability's wiring step flips to ok through any install path (marketplace shelf, TUI, CLI), it auto-completes the missing binary layers (KimiCU.app + launchd service, or the WebBridge daemon). Triggers only on the false→true edge, so completed installs with still-missing manual steps (TCC permissions) never retrigger heavy downloads on later reloads.Tests
Notes