Package authoring
Harn packages are ordinary Harn projects with package metadata, stable exports,
tests, and optional connector contracts in harn.toml. They use the same
[dependencies], .harn/packages/, and harn.lock workflow as applications.
Create a package
harn new package acme-tools
cd acme-tools
harn test tests/
harn package check
harn package docs
harn package pack
The package template creates:
harn.tomlwith[package]metadata,[exports], and[dependencies]lib/main.harnwith a documented public functiontests/smoke testsREADME.md,LICENSE,docs/api.md- CI that installs
harn-cli, runs tests, checks docs drift, and runsharn package pack --dry-run
Consumers can add a local package while developing:
harn add ../acme-tools
harn install
harn package list
harn package doctor
Before publishing, replace local path dependencies with registry or git dependencies pinned to a version or rev.
Create a tool package
harn tool new acme-echo
cd acme-echo
harn test tests/
harn package check
harn package docs --check
harn package pack --dry-run
The tool template creates a package with a Harn-native registry builder,
[[package.tools]] metadata, a local smoke test that dispatches the tool,
and CI that exercises the same publish-readiness checks. The generated package
is intentionally ordinary Harn source; consumers install it with harn add,
import the stable export, and merge it into their own tool registry:
import { tools } from "acme-echo/tools"
Create an OpenAPI SDK package
harn package scaffold openapi \
--name acme-sdk-harn \
--module-name acme_sdk \
--client-name AcmeClient \
--spec ./openapi.json \
--out ./acme-sdk-harn
cd acme-sdk-harn
harn install
harn check src/lib.harn
harn test tests/
harn package check
harn package docs --check
harn package pack --dry-run
The OpenAPI scaffold uses harn-openapi to generate src/lib.harn, stores the
input spec under openapi/, writes a scripts/regen.harn regeneration path,
adds a package export for the generated module, and creates a smoke test that
uses a mocked operation when the spec has a no-argument operation. The package
is intentionally focused: it wraps the API described by the OpenAPI document,
not an entire provider product line.
Hand-written harness.net calls are fine for private one-off endpoints,
temporary admin probes, or gaps that are not in the OpenAPI document. Repeated
provider API coverage, connector helpers, and user-facing package exports
should use a generated SDK or a small Harn wrapper over one so auth,
pagination, rate-limit metadata, and package tests stay centralized.
Create a skill package
harn skill new review-helper
harn skill new is the singular alias for harn skills new. Package authors
can publish skills by adding [[package.skills]] entries that point at
package-root-relative skill directories containing SKILL.md.
Create a connector package
harn new connector echo-connector
cd echo-connector
harn connector test .
harn package docs
harn publish --dry-run
harn publish
Connector packages use harn connector test . as the CI gate. It runs package
metadata validation, harn check, harn lint, harn fmt --check, connector
contract fixtures, package-local fixture tests, install/import smoke tests, and
standalone Harn doc examples. Use harn connector check . when you only need
the lower-level pure-Harn connector contract check.
Connector packages should also declare package-facing capability coverage on
their [[providers]] entry so harn check --connector-matrix can compare
provider support:
[[providers]]
id = "acme"
connector = { harn = "src/lib.harn" }
capabilities = ["webhook", "oauth", "rate_limit", "pagination", "graphql", "streaming"]
Manifest metadata
Publishable packages should include:
[package]
name = "acme-tools"
version = "0.1.0"
description = "Reusable Harn helpers."
license = "MIT OR Apache-2.0"
repository = "https://github.com/acme/acme-tools"
provenance = "https://github.com/acme/acme-tools/releases/tag/v0.1.0"
harn = ">=0.8,<0.9"
docs_url = "docs/api.md"
permissions = ["tool:read_only"]
host_requirements = ["workspace.read_text"]
[exports]
lib = "lib/main.harn"
[[package.tools]]
name = "read-note"
module = "lib/main.harn"
symbol = "tools"
description = "Read a note through the package tool registry."
permissions = ["tool:read_only"]
[package.tools.input_schema]
type = "object"
required = ["path"]
[package.tools.annotations]
kind = "read"
side_effect_level = "read_only"
[[package.skills]]
name = "review"
path = "skills/review"
[dependencies]
json-helpers = { git = "https://github.com/acme/json-helpers", tag = "v0.1.0" }
harn package check validates required metadata, dependency declarations,
stable exports, tool and skill declarations, README/license presence, docs
links, and Harn compatibility. Tool declarations must point at a parseable
Harn module, provide valid JSON-schema-shaped input_schema and
output_schema tables when present, and use policy annotations that match the
runtime tool annotation schema. Skill declarations must stay inside the package
root and point at a directory with valid SKILL.md front matter. Publish
readiness rejects path-only dependencies and unsupported Harn version ranges
because they cannot be reproduced from a registry index. Publishable
dependencies should use direct git tag/rev pins or registry version
ranges; branch dependencies are accepted with a warning because they are
moving refs.
API docs
Document exported symbols with doc comments:
/// Return a greeting for `name`.
pub fn greet(name: string) -> string {
return "Hello, " + name + "!"
}
Generate docs with:
harn package docs
CI should use:
harn package docs --check
Pack and publish dry run
harn package pack validates the package and writes an inspectable artifact
directory at .harn/dist/<name>-<version>. It excludes local build state such
as .git/, .harn/, target/, and node_modules/.
harn package pack --dry-run
harn package pack
harn publish --dry-run runs the publish-readiness checks and prints the git
tag command plus the package-index diff that would be proposed. harn publish
requires a clean git worktree, a non-empty CHANGELOG.md entry for the package
version, and an unused vX.Y.Z tag. It then tags and pushes the configured
remote, and opens a PR against the configured package index. Use
--skip-index-pr to push only the tag when the index entry should be composed
manually.
Lockfile provenance
harn.lock is the executable record of what was resolved and why. Every
write captures:
version,generator_version, andprotocol_artifact_versionat the top level so downstream automation can detect when the lock was produced by an older Harn line.- Per-entry
source,commit, andcontent_hashfor git/registry deps, plus the resolvedtagwhen a tag was used,package_version,harn_compat, packageprovenance, and a separatemanifest_digesttaken from the resolved package'sharn.toml. - Exported modules, custom tools, skills, package permissions, and host requirements declared by the resolved package. Hosts and CI can inspect this metadata without reading arbitrary package source.
- A
[package.registry]table for entries originally resolved through the registry, preserving the registry source, package name, and exact resolved version soharn package outdatedcan compare against the registry's latest release without re-reading the manifest. Registry dependencies may remain inharn.tomlas semver ranges, for examplenotion-sdk-harn = { version = ">=1.2,<2.0" }.
Path dependencies remain live-linked; their lockfile entry records the
resolved path+file:// URI plus the same package_version and
manifest_digest so harn package audit flags drift without rebuilding.
Maturing the package surface
Once a manifest and lockfile are in place, these commands cover the day-to-day automation surface:
harn package list— summarize locked packages, materialization status, exported modules/tools/skills, and declared permission or host requirements. Use--jsonwhen the output feeds host UI or CI policy.harn package doctor— diagnose missing or stale lockfiles, missing materialized packages, content-hash mismatches, declared host capability gaps, and invalid installed package tool/skill metadata. It is safe for applications: publish-only checks remain underharn package check.harn package outdated— surface registry version bumps and (with--remote) git branch HEAD drift. JSON output matches the report struct documented incli-reference.md.harn package audit— verify provenance, compatibility, and content integrity in one pass.--jsonreturns a stablecodeper finding so CI can fail on specific issues (yanked registry pins, content-hash tampering, brokenharnranges) without parsing prose.harn package artifacts check— compare a vendored copy of the protocol artifact manifest (e.g.spec/protocol-artifacts/manifest.jsonin your repo) against the running Harn. The exit code is non-zero on drift, so a downstream that vendors generated TypeScript or Swift bindings can fail CI when those bindings would change after a Harn bump.
Cross-repo bump workflow
When Harn cuts a new release, downstream package authors and host integrators (Burin Code, Harn Cloud, third-party connectors) need a consistent way to land the bump. The recommended sequence:
- Refresh the running Harn binary in the downstream repo
(
fetch-harn,make setup, or whatever the local script is). - Re-resolve dependencies with
harn installsoharn.lockrewrites with the currentgenerator_version,protocol_artifact_version, exported package surface, and host requirements. - Inspect with
harn package list --jsonandharn package doctor --jsonso host requirements and materialized package state are visible before tests start. - Audit with
harn package audit --json. If any package declares aharnrange that excludes the new line, contact the package owner or pin to a previous tag. - Check vendored protocol bindings with
harn package artifacts check path/to/vendored/manifest.json. If it reports drift, regenerate the bindings (make gen-protocol-artifactsinside the downstream repo, orharn package artifacts manifest --output …to refresh the vendored copy). - Surface registry updates with
harn package outdated --jsonand bump dependency versions intentionally;harn update <alias>keeps each upgrade in its own commit.
Steps 2–5 are a single CI job for hosts that vendor Harn artifacts:
harn install --frozen --json, then harn package doctor --json, then
harn package audit --json, then harn package artifacts check. The --json
output is stable across Harn lines, so the same automation script runs against
multiple Harn versions during a staged rollout.