Plugin development
Extend Kibi with capability plugins: the SDK, manifests, and plugin lifecycle.
Kibi capability plugins extend four host-owned seams without taking over validation, Prolog, mutation, or proof:
kibi.semantic-classifier.v1— lane / ambiguity classification over host propositionskibi.ontology-pack.v1— predicate schemas and match candidateskibi.symbol-extractor.v1— language-specific source symbol analysiskibi.vocabulary-alignment.v1— modeling-time vocabulary convergence:rankSubjects(reuse an existing subject or declarenew_subject) andcompareClaims(possible-duplicate candidates for review)
Every capability is optional for third-party plugins: a plugin declares only the capabilities it provides, and plugins written before a capability existed keep validating and loading unchanged. The builtin plugin provides all four.
This is distinct from host plugins such as kibi-cursor, kibi-opencode,
kibi-codex, kibi-zcode, and kibi-claude, which adapt an IDE or agent host to Kibi's
operation surface. Capability plugins never register MCP tools or Git hooks.
Automatic builtin
kibi-plugin-builtin ships with the standard CLI distribution and is always
registered. It is not listed in package.json kibi.plugins. With no
kibi.plugins config, only the builtin pack runs.
Named export
Activated packages must export a single named kibiPlugin binding that
passes validateKibiPlugin / defineKibiPlugin from kibi-plugin-sdk.
A default export alone is not accepted by the host loader.
import { KIBI_PLUGIN_API_VERSION, defineKibiPlugin } from "kibi-plugin-sdk";
export const kibiPlugin = defineKibiPlugin({
apiVersion: KIBI_PLUGIN_API_VERSION,
id: "example-ontology",
version: "0.1.0",
permissions: { network: false, metered: false, secrets: [] },
capabilities: {
ontologyPack: {
id: "example-ontology.pack",
schemas: () => [],
match: () => [],
},
},
});Third-party plugins need only kibi-plugin-sdk. They must not depend on
kibi-cli or kibi-mcp internals.
Activation
Declare the package as a project dependency and activate capabilities under
package.json:
{
"kibi": {
"plugins": [
{
"package": "kibi-plugin-jev",
"capabilities": {
"kibi.semantic-classifier.v1": { "mode": "augment" }
}
}
]
}
}Rules:
- Bare package names only (no paths, URLs, or aliases)
- Package must appear in
dependencies,devDependencies, oroptionalDependencies - Resolution follows the project's package manager (npm, pnpm symlink, Yarn PnP)
NODE_PATH, global installs, and ambient ancestor packages are rejected
Configuration surface
package.json#kibi.plugins is the canonical activation and mode surface. Each entry names a bare package and the capabilities it may provide, with augment, replace, or shadow. That manifest is small, declarative, and validated before any plugin module is imported. Provider secrets stay in the environment, outside repository configuration.
The manifest does not include kibi.config.ts, generic plugin options, plugin factories, or executable config.
kibi doctor prints the parsed plugin rows (package, capability, mode, declared dependency) without importing the plugin package. First-party Jev secret and model diagnostics are known statically. Generic plugins do not get secret introspection. A configured package that is not listed in dependencies, devDependencies, or optionalDependencies fails that check. Add the package to one of those fields, or remove the kibi.plugins entry. Editing package.json remains the way to enable or disable a plugin.
Modes
Per capability, at most one replace is allowed. augment providers run in
package activation order with capability-specific builtin positioning.
shadow providers never affect canonical results; they may contribute
comparison metadata only.
| Capability | Builtin position | Notes |
|---|---|---|
| Semantic classifier | First for augment; fallback for replace failure |
External classifiers run only from kb_semantic_advisor and kb_compile_intent. Valid empty decisions[] under replace is abstention (conservative none), not builtin fill. |
| Ontology pack | Catalog starts with builtin for augment |
replace excludes the builtin provider catalog. Valid empty match() is abstention (no builtin consult). Allowed wherever Kibi already matches ontology |
| Symbol extractor | Builtin first for supported files under augment |
replace gets first claim with builtin fallback |
| Vocabulary alignment | Builtin always runs first; fallback for replace failure |
External providers run only from kb_model_requirement. augment refines only clauses the builtin left as new_subject and pairs it did not judge duplicates (it can add candidates, never remove them). A provider may only choose among the builtin-ranked candidates or new_subject; any other answer is rejected and falls back to builtin with fallbackUsed. Results are advice in the modeling plan, never check outcomes |
Sync maintenance paths (sync, check, kb_upsert, status, proof, and
related) keep deterministic builtin analysis for every capability and must
never invoke external semantic classifiers, ontology packs, symbol extractors,
or vocabulary-alignment providers. kb_check in particular never resolves
plugins: domain-redundancy, subject-key-identity, and the other Prolog
checks remain the only pass/fail authority. Async advisor / compile-intent / staged-symbol paths compose the
registry (replace / augment / shadow); replace mode strips or overrides any
sync-path builtin suggestions before results are returned.
Trust boundary
Explicit activation grants code-execution trust to the npm package. Module
evaluation can run arbitrary top-level code. Kibi cannot enforce a third-party
network: false declaration after import.
permissions.network, permissions.metered, and permissions.secrets are
disclosure-only metadata for operators and UIs, not an in-process sandbox.
Plugins cannot bypass completeness checks, Prolog, mutation gates, or proof.
Host validators stamp provider provenance (pluginId, mode, external,
network/metered, fallback).
Privacy and cost
Semantic classifiers may receive claim keys, proposition text, and minimal role
or signal context. Prefer local/offline providers when possible. Metered
providers must declare metered: true and list required secret names.
Testing
- Unit-test classifiers/packs/extractors against
kibi-plugin-sdkvalidators - Keep import side effects free of network I/O until an allowed capability call
- For optional providers such as Jev, cover missing key, timeout, and malformed responses with injectable clients and offline fixtures
Vocabulary alignment contract
rankSubjects({ clauses }) receives, per clause, a claimKey, the clause
text, the proposedSubjectKey Kibi would otherwise declare, and builtin
candidates (subjectKey, score in [0, 1], optional title and
requirementTitles). It returns one decision per clause: choice is one of the
candidate subject keys or new_subject, plus a confidence in [0, 1].
compareClaims({ pairs }) receives pairs sharing a subject key (or predicate
name) whose signatures differ, and returns { pairKey, sameObligation, confidence } per pair. sameObligation: true only nominates the pair for
review; exact duplicates are detected by the deterministic domain-redundancy
check.
Results are validated by validateRankSubjectsResult and
validateCompareClaimsResult: foreign keys, duplicate keys, invented subjects,
and out-of-range confidences are rejected before they reach the plan.
Optional Jev provider
kibi-plugin-jev implements kibi.semantic-classifier.v1 and
kibi.vocabulary-alignment.v1 via TypeSafe Jev (@typesafe-ai/sdk). Each is
activated separately. It is not a default CLI or MCP dependency.
- Install and activate explicitly (see install.md)
- Set
TYPESAFE_API_KEYvia Kibi env bootstrap (same for every MCP host):
mkdir -p ~/.config/kibi
printf '%s\n' 'TYPESAFE_API_KEY=...' >> ~/.config/kibi/env Optional project override: <workspace>/.env.kibi. Process env wins;
KIBI_ENV_FILE replaces the project path; legacy .env fills gaps only.
Never store the key in package.json. Restart long-running MCP after changes.
- Optional
KIBI_JEV_MODEL(defaultjev-latest; empty or whitespace is unset) - Optional
KIBI_JEV_TIMEOUT_MS, a positive integer of at most 120000. Malformed values fail with a provider diagnostic that includes the effective model and not the API key - Explicit
JevSemanticClassifierOptions.modelandtimeoutMsoverride those environment defaults. They are a programmatic constructor API, not fields inpackage.json - Importing the package, or leaving it installed but inactive, performs no TypeSafe client or network call
- On failure Kibi falls back to the builtin classifier with an advisory warning
kb_model_requirementdoes not invoke the classifier. External semantic classifiers run only fromkb_semantic_advisorandkb_compile_intent- Vocabulary alignment (
rankSubjectsas achoiceover the builtin top 5 plusnew_subject;compareClaimsas anoulper pair) runs only fromkb_model_requirement, and only whenkibi.vocabulary-alignment.v1is activated - Live tests require both
KIBI_JEV_LIVE_TEST=1andTYPESAFE_API_KEY kibi doctorreports first-party Jev secret source labels and model/timeout without importing the plugin or leaking values
See also packages/plugin-jev/README.md.