This document defines the semver-public package surface for
@flyingrobots/graft.
The only semver-public JavaScript module path is:
import { ... } from "@flyingrobots/graft";Deep imports into src/, dist/, or other package-internal paths are
not public contract. If external code imports those paths, it is opting
into implementation churn.
The root package exposes four public families plus metadata.
These are the preferred direct typed surfaces for in-process integration:
createRepoWorkspace(...)RepoWorkspaceObservationCacheCreateRepoWorkspaceOptionsRepoWorkspace*Resultexported result types
Use this family when a host app wants governed repo-local reads without MCP transport receipts.
These are the preferred direct typed surfaces for dirty-buffer editor work:
createStructuredBuffer(...)createProjectionBundle(...)CreateStructuredBufferOptionsCreateProjectionBundleOptionsStructuredBufferProseProjectionProvidercreateColorfulCliProseProjector(...)COLORFUL_CLI_MINIMUM_VERSIONcreateProjectionProviderRegistry(...)ProjectionProviderRegistryError- exported
ProjectionProvider*registry, registration, resolution, and binding types createProjectionProfileResolver(...)ProjectionProfileResolverError- exported
ProjectionProfile*,ProjectionRoute*,ResolvedAuthorityContext, andProjectionRoutingFailure*types EdictProjectionProviderEdictProjectionErrorcreateEdictCliProjectionProvider(...)- exported
Edict*Projection*request, result, slot, compiler-context, target-settings, status, and failure types ensureParserReady(...)WarmProjectionBasisWarmProjectionBundleResult- exported
Buffer*,Syntax*,Fold*,Selection*,Rename*,SemanticSummary*, and related structured-buffer result/value types
Use this family when a host app wants editor-native parsing, spans, rename previews, and diff/mapping on unsaved text.
Tree-sitter grammar loading is async and lazy. Hosts that need full
parser-backed results from the synchronous StructuredBuffer surface
should call await ensureParserReady() during their own startup or
before constructing JavaScript, TypeScript, Rust, or GraphQL buffers. If
they do not, the sync buffer surface remains non-throwing and returns
partial, parser-unavailable results until the lazy runtime has warmed.
Warm buffer results carry explicit basis identity when the caller
provides it. Single-buffer queries expose basis; comparison-style
results expose fromBasis / toBasis. That lets hosts compare the
projection basis they received against the editor's current head/tick
truth.
For hosts that want one coherent warm-layer payload instead of several
feature-specific calls, createProjectionBundle(...) and
StructuredBuffer#projectionBundle(...) return syntax spans,
diagnostics, fold regions, outline, and explicit bundle-level parse
status over one known editor head.
CreateStructuredBufferOptions and CreateProjectionBundleOptions also
accept proseProjector. This optional port lets a host project prose into
the same syntax/outline bundle shape as parser-backed source files. Graft
ships createColorfulCliProseProjector(...) for the Colorful
colorful.syntax/v1 contract as emitted by colorful >= 0.2.1; it shells out
through a supplied ProcessRunner, validates source and vocabulary hashes, and
returns format: "prose" for supported .txt buffers. Without a projector, or
without a compatible colorful CLI, text files keep the explicit
UNSUPPORTED_LANGUAGE result.
CreateStructuredBufferOptions and CreateProjectionBundleOptions also
accept edictProjector. This optional port lets a host project dirty .edict
buffers through Edict's public JSONL project operation without writing the
buffer to disk. Graft ships createEdictCliProjectionProvider(...), which
shells out through a supplied ProcessRunner, sends source text on stdin, and
maps Edict syntax byte offsets into normal Graft row/column spans. The Edict
bundle preserves compiler diagnostics plus Core and Target IR projection slots
with explicit not_requested, available, blocked, and failed states.
Without an Edict projector, .edict buffers are still recognized and report
PROJECTION_PROVIDER_UNAVAILABLE; Graft does not execute Echo or admit
bundles.
Hosts that prefer registry-based routing can pass projectionRegistry, created
with createProjectionProviderRegistry(...). The current public provider
binding routes Edict projections; future provider bindings can extend the same
registry shell without adding one top-level buffer option per language. Registry
entries bind a language id, one or more file extensions, and a language-specific
provider binding. Routing is case-insensitive for extensions, and the optional
language field on buffer options lets synthetic dirty buffers route without
pretending that the path exists on disk. Blank language ids are treated as
absent. The direct edictProjector option remains supported and takes
precedence for .edict buffers; the registry does not normalize
language-specific payloads into an Edict-shaped model.
Hosts preparing profile-aware projection can create a
ProjectionProfileResolver with createProjectionProfileResolver(...). The
resolver accepts an already-parsed in-memory profile config, computes
deterministic profileDigest and routingDigest review strings, and resolves
dirty-buffer names through explicit profile override, project route globs, or
extension fallback. Blank profile overrides are treated as absent, unknown
profiles and ambiguous route matches return structured routing failures, and
route-only changes move only routingDigest. Resolver config rejects lossy
digest preimages, sparse option arrays, fallback/profile language mismatches,
negated route globs, and malformed fallback file extensions. Profile digests
preserve JSON option keys named __proto__ and are independent of semantic
extension declaration order using locale-free code-point comparison. This
resolver does not read graft.projections.toml or interpret Wesley SDL,
descriptor, Echo, Edict, or Colorful semantics.
CreateStructuredBufferOptions and CreateProjectionBundleOptions also accept
projectionProfileResolver and optional profile. When a resolver is supplied,
Graft resolves authority before provider invocation and includes an authority
slot on WarmProjectionBundleResult: not_configured, resolved, or
failed. Resolved slots carry the selected profile id, profile digest, optional
routing digest, provider id, language id, resolution source, and semantic
extension identities. Failed slots preserve the resolver's structured routing
failure and skip provider invocation. Registry-routed providers receive the
same resolved authority context as optional request metadata. This is routing
and support context only; Graft still does not interpret Wesley SDL or execute
target runtimes.
These exports are public, but they are bridge-shaped around Graft’s tool contract rather than the preferred typed application services:
createRepoLocalGraft(...)callGraftTool(...)parseGraftToolPayload(...)MCP_TOOL_NAMESMcpToolNameMcpToolResult
Use this family when a host wants direct in-process access to the same tool model used by MCP without paying transport overhead.
These exports are public advanced host surfaces for embedding Graft itself:
createGraftServer(...)startStdioServer(...)startDaemonServer(...)ensureGitVersionSupportsGraft(...)CreateGraftServerOptionsGraftServerStartDaemonServerOptionsGitVersionGitVersionGuardOptions
Use this family when a host needs to boot or embed Graft runtimes,
rather than call repo-local or buffer-local services directly.
ensureGitVersionSupportsGraft(...) is an additive host guard for
checking that the installed Git supports the plumbing features Graft
runtimes require.
GRAFT_VERSIONGRAFT_MINIMUM_GIT_VERSION
These are public for version introspection and host diagnostics.
The following are not semver-public:
- deep imports into
src/** - deep imports into
dist/** - unexported implementation modules
- incidental file layout outside the documented root export families
The root package export surface is public. The implementation tree is not.
Graft is still pre-1.0. That means the public API can change between minor versions, but those changes must still be treated as externally meaningful and reviewed explicitly.
Release classification rules:
- additive root exports or additive public option/result fields:
release-worthy and normally
minor - bug fixes or hardening with no intended public API change: normally
patch - removing, renaming, or incompatibly changing documented root exports,
option types, result types, or documented semantics: breaking change;
after
1.0this ismajor, and before1.0it must still be called out explicitly in the release packet and user-facing notes
For bridge-shaped outputs that remain schema-backed, the versioned
output schema contract still applies. callGraftTool(...) does not make
schema changes invisible just because the call stays in-process.
Any release that changes the documented public API must answer these questions explicitly:
- what public root exports changed
- whether the change is additive or breaking
- whether migration guidance is required for integrators
If a change does not affect the documented public API, it should be classified as internal refactor or internal hardening instead.