Create, install and share a package
Local packages are available now. The public package server is undergoing validation and testing and will be available soon.
Share a host module
To reuse an identity adapter, place the module under host/ and add these
fields to the package manifest. Include its helper files:
{
"hosts": [
{ "id": "approval", "kind": "human_approval", "path": "host/approval.mjs" }
],
"files": ["host"]
}
touba package check --publishing
touba package pack
The consumer installs the package, reviews the adapter, configures its environment and explicitly selects its entry point:
touba run --project . --human-approval-host pkg:acme.review/approval
The adapter exports attestHumanApproval and, when needed,
resolveInitiator in JavaScript; attest_human_approval and
resolve_initiator in Python. The
approval tutorial explains their
contract. A decision adapter uses kind: "decision_provider" and
--agent-decision-provider. Files are checked before loading; access and
identities remain application configuration.
A Touba package is the reusable unit: types, functions, tools, executable skills, agents, strategies, memories and contextual procedures can coexist. An integration is a package use case, not another format. Library collects packages, the Hub presents them, and a registry indexes their versions.
Complete workflow
Build an author project, then distribute an archive to a consumer project. The CLI generates the structure and checks its contents; you write the business contract, tests and usage instructions. For every command in sequence, follow the creation and usage tutorial.
Install Touba first and check touba version and touba doctor. A package of
pure Touba code needs no host SDK, model key or server. An SDK is needed when
host code imports it; the handler language does not change the package format.
| Content to share | Contract to declare | Application usage |
|---|---|---|
| Type, constant, function or executable skill | Public references in exports, sources in files | Typed import from the module, then a Touba call |
| Agent and workflow | exports.agents and exports.strategies, with dependencies | Import; a workflow is a strategy, not a second format |
| External service integration | Exported tool, proposed handler and documented requirements | Host-reviewed binding, optional SDK and explicit authorization |
| Contextual procedure | A contexts entry and Markdown procedure | Context selection and activation, not import skill |
The installed name (acme.review), module (acme.review) and declaration
(skill:acme.review/Echo) serve different purposes. They partly coincide in
the generated example; imports use the module, never a path into
packages/. Each project has one managed dependency directory.
Create the author project
touba package new asks for organization, name, description, author, version,
license and initial content. It shows the identity and destination before
confirmation. Cancelling creates no files. For scripts:
touba package new review --org acme --license MIT --yes
cd review
touba package check
touba package test
Choose a license you are entitled to use. --context generates a Markdown
procedure instead of a sample skill. Spaces become hyphens: Atelier Nord
and Gestion factures become atelier-nord.gestion-factures, in the
gestion-factures/ directory. Names are lowercase. Unsupported characters
are reported, not silently discarded. Local creation does not reserve a name
or authenticate an organization.
review/
touba.package.json
README.md
.gitignore
src/acme/review.tb
tests/echo.test.mjs
packages/
One manifest holds identity, version, exports and requirements. The generated module uses underscores for hyphens: package identity and module references are distinct. Existing imports are never rewritten.
packages/ is reserved for dependencies in author projects and applications
created with touba init. A file, link or case alias such as Packages at
that location is refused, never replaced. VS Code's P badge identifies the
directory, not the trustworthiness of its contents. Develop in a separate
author directory, never in an installed copy.
Commands find the nearest manifest from subdirectories: no repeated ../
for checks, tests, versioning or packing.
Develop the content and public contract
The generator provides a working starting point. Replace Echo in src/ with
your business declarations, then update the exports references and test
assertions. Add each new test file to contract_tests: the command does not
invent test cases.
This is the manifest generated by the command above. You do not need to copy it; it shows which fields to maintain as the contents change.
{
"package_schema_version": "touba-package-v1",
"name": "acme.review",
"version": "0.1.0",
"description": "Reusable acme.review package.",
"touba": {
"air_profile": "touba-air-json-canonical-v1",
"runtime_compatibility": ">=1.0.0 <2.0.0"
},
"exports": {
"skills": [
"skill:acme.review/Echo"
]
},
"readme": "README.md",
"files": [
"src",
".gitignore"
],
"publisher": "acme",
"license": "MIT",
"contract_tests": [
"tests/echo.test.mjs"
]
}
exportsdefines the public API. Renaming a declaration requires updating its export and affected consumers. Other declarations remain package-internal.fileslists distributable content. The manifest, README, declared tests, handlers and context resources also enter the inventory through their declarations. Add other resources explicitly. Review the inventory fromtouba package check --jsonbefore sharing.touba.runtime_compatibilitystates the range actually tested, not a promise about future versions.dependenciescontains exact versions. Runtouba package addin the author project to record the dependency and lock together.enginescurrently checks Node ranges and platforms. Document other requirements, including Python, its dependencies, services and variables, in the README; do not invent unsupported manifest fields.
The README should let another developer install, import and run an example
without contacting you: inputs, outputs, exports, commands, requirements,
requested permissions, expected errors and license. Keep identifiers, prompts
and model-facing descriptions in English. Include no keys, .env files,
caches or node_modules dependencies in the archive.
Add a JavaScript or Python handler
Declare and export the Touba tool, implement the handler using the
JavaScript or
Python walkthrough, then declare its file in
handlers following the reference. Document host
libraries and their installation. package add runs no npm install,
pip install or post-install script.
The consumer explicitly chooses touba sdk install javascript or
touba sdk install python. They review the touba prepare plan, handler code
and host decisions before execution. Shipping code supplies no secret, grant
or approval. Package tests remain Node tests declared in contract_tests;
Python handler tests use the separate command shown in their tutorial.
Check and test
check validates structure, inventory, host requirements, exact dependencies,
compilation and actual exports. Its report lists missing publication metadata;
check --publishing makes those fields mandatory. No handler or test runs.
test runs the Node files declared in contract_tests, after validation.
The generated test compiles and runs the Echo skill: replace it with your
business contracts. A textual procedure with no declared tests returns
no_tests and a nonzero exit code. An empty file or fully skipped suite
is not reported as a success.
Review tests before execution: they run with your account's filesystem
permissions, not in a sandbox. Environment secrets are not inherited by default;
--env NAME explicitly passes a variable. This does not prevent host code
from reading accessible files. Isolate third-party tests.
Requirements for companies and authors
Before sharing:
- Choose a stable
organization.nameidentity and exact SemVer version. - Declare only public exports and exact dependencies.
- Set
description,publisherandlicense. Prepare an overview: the packagereadmeis sufficient and enables direct CLI publication; a publication service can also accept this content separately. - Explain inputs, outputs, failures, effects, limits and import examples.
- Declare host requirements in
enginesand explain expected configuration. - Test successful and refused operations without private data or secrets.
- Install the archive in another project and test real usage.
A handler follows touba-tool-handler-v1. Shipping it does not create an
approved binding: the consumer chooses its path, grants, secrets, scopes and
limits. Archive integrity does not establish code safety. For a JavaScript
handler importing @touba/sdk, follow the SDK guide.
Package installation never runs npm behind the scenes.
Share without a server
From the author project:
touba package check --publishing
touba package test
touba package pack
The archive is dist/acme.review-0.1.0.tar.gz. --output <path> selects
another destination; an existing archive is never overwritten. Declared files
and the dependency closure are included. The CLI reports a SHA-256 digest.
Share it through a channel with a verifiable origin. No Touba server is required.
In an application created with touba init, supply the real path to an archive
or author directory:
touba package add /path/to/acme.review-0.1.0.tar.gz
touba package list
touba package check
For manual installation, place distributable files under packages/acme.review/,
then run touba package add acme.review, even from src/. Do not copy author
build outputs, caches or secrets. Copying a directory alone does not register it.
In an application, installation updates touba.project.json and
touba.packages.lock.json. In an author package, it updates dependencies
in touba.package.json and the same lock. Version these files and keep
installed directories for offline work. prepare, the editor and
run --project verify their integrity.
Evolve a version
touba package version patch
touba package test
touba package pack
Use patch, minor, major or an exact, strictly higher version. With no
argument, an interactive terminal asks for the choice. Only the manifest version
changes: no commit, tag, remote publication or consumer changes. Touba does not
infer business compatibility from your edits.
Keep the published organization.name identity: another name denotes another
package. Published version contents stay fixed. Change descriptions, licenses,
README content or exports in a new version.
Dependencies and local development
One exact version per name, no implicit “latest”. Missing dependencies, cycles
and conflicts produce diagnostics. add does not replace an installed version.
Prepare an upgrade in a working copy: touba package remove <name>, install
the new version, review changes and prepare again. Removal refuses a dependency
still required by another package.
For mutable local sources, a project packages entry may specify manifest,
version and editable: true, outside the managed packages/ directory.
This explicit mode does not provide locked-installation integrity. Do not mix
the two modes for one identity.
Explicit registry selection
touba package add acme.review@0.1.0 --registry ./registry
The registry is a directory or HTTPS URL; no default address is assumed. Archive identity and digest are checked. Withdrawn versions are refused. Editorial review status does not replace your authorization decisions.
For a remote URL, supply the operator's approved keys with
--trust registry-trust.json. The CLI checks the signed index and its validity,
then the metadata and archive digests. Obtain and verify the trust file through
the operator, independently of the package.
See the signed registry reference.
touba registry check --registry ./registry --source-root ./registry checks
the index, metadata and artifacts. --previous <trusted-published-snapshot>
also checks continuity: no deletion, rename or replacement of a published
version. Withdrawal preserves its record. The operator must authenticate
publishers and protect their namespaces; this local check is not an identity service.
Preserve governance
Imports keep their references. Packages do not expand uses, callable_by,
grants, secrets or scopes. Agents retain their source callers; an exported
strategy can invoke them under that contract. A context guides the model
without granting capabilities.
Continue with the import tutorial, contextual procedures and reference.
Publish a local static registry
publish compiles and packages the content, then generates the index and
metadata consumed by Touba. It does not run author tests, upload anything or
authenticate the organization.
touba package test
touba package publish --registry ./registry
touba registry check --registry ./registry --source-root ./registry
The target contains index.json, metadata/<name>-<version>.json and
archives/<name>-<version>.tar.gz. The touba-registry-index-v1 index links
each identity/version to metadata and its SHA-256 digest.
touba-registry-package-v1 metadata describes identity, status, compatibility
and the archive with its digest. These files are generated; authors do not
rebuild the format by hand.
Local publication starts as draft. After code review, consumers can
explicitly accept it:
touba package add acme.review@0.1.0 --registry ./registry --allow-draft
Publication executes no third-party code and never overwrites an existing
identity/version. A lock serializes publication. Interrupted unindexed files
remain for inspection and are not silently replaced. Use registry check
before sharing the directory. Production hosting and remote uploads remain
separate operations.
Publish to a compatible service
touba package publish --registry https://registry.example.org/registry
Open the proposed link, confirm the code displayed in your terminal and
authenticate in the browser. The service checks your publication rights in
the package's namespace and qualifies the archive before storing it.
Published versions are immutable; use touba package version for changes.
Use --no-browser on a workstation without a browser. This example URL
represents a compatible service. The workflow is identical for JavaScript
and Python packages.
Prepare a draft from your editor
To review the overview before publishing, choose a service that supports drafts:
touba package submit --registry https://registry.example.org/registry
Touba prepares and checks the archive, opens browser authentication and submits it. The service checks your permissions and runs isolated tests. The command returns the private draft link: complete the overview, preview it and publish.
To continue a package created in the service interface, copy its draft ID:
touba package checkout 11111111-1111-4111-8111-111111111111 --registry https://registry.example.org/registry
cd review
touba package check
touba package test
touba package submit
Replace the example ID with your draft ID. The new folder uses the package’s
short name (review here). --root selects an existing parent directory;
existing folders are preserved. Checkout checks digests, contents and source
contracts without executing author code.
The local .touba/package-draft.json link records the registry, draft identity
and archive digest. It contains no secret and stays outside the archive.
Later submissions reuse this link. The service keeps the saved overview and
images, and records every replacement.
If remote source changes, review the new draft before continuing.
--draft <id> explicitly selects a target with the same name and version.
After an interruption, check the service to see whether submission completed.
Inspect any remaining local lock before recovery.
The commands are identical for JavaScript and Python handlers.
Select a proposed handler
When preparing host decisions, bindings[toolRef].package_handler selects the
package identity, for example "acme.billing". This selects the declared
entrypoint only. The host separately approves grants, secrets, effect contract
and limits. No unused local stub is created for that selected tool.
Prepare a draft from GitHub Actions
An owner authorizes the repository, workflow file, branch and environment in the publication service after strong authentication. The service provides an authorization ID, with no secret to store in GitHub.
In a job with Touba installed and the package sources checked out, enable
id-token: write, select the authorized environment, then run:
touba package submit --ci 11111111-1111-4111-8111-111111111111 --registry https://registry.example.org/registry
Replace the ID and URL with those of your service. The GitHub token stays in memory and is used for one submission. The service checks the stable repository and owner IDs, workflow, branch and environment, then qualifies the archive. The result includes the private draft link and its provenance. An authorized member previews and publishes it afterwards.
This mode creates a new draft; an already-submitted version is reported for review. The command and manifest are identical for JavaScript and Python.