Skip to content

Arete documentation

Project Dependencies

For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending .md to the URL or sending Accept: text/markdown.

For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /building-stacks/configuration.md.

An Arete project keeps three records of its dependencies:

  • arete.toml says what you want. You or your agent write it.
  • arete.lock says exactly what that resolved to, and stays put until you ask for a change.
  • Provenance inside the generated SDK says which locked input produced each output.

Use a4 install, a4 update, and a4 remove to keep all three in step. If you have used package.json with a lockfile, or Cargo.toml with Cargo.lock, the arrangement will feel familiar.

Terminal window
a4 init -y

Initialization creates a minimal manifest if there isn’t one yet and configures the project’s agents. It never adds registry dependencies on its own.

manifest_version = 1
[project]
name = "my-project"
private = true

Start with the catalog, inspect the exact descriptor, and prefer its install command:

Terminal window
a4 explore catalog --query "token accounts" --json
a4 explore catalog program spl-token --json
a4 install program spl-token --ts

For a hosted stack:

Terminal window
a4 explore catalog --query "<intent>" --kind stack --mode subscribe --json
a4 explore catalog stack <slug> --json
a4 install stack <slug> --ts

Adding a package saves what you asked for and resolves the complete set of dependencies. Run plain a4 install later to restore everything the project declares.

manifest_version = 1
[project]
name = "my-analytics-app"
private = true
[install]
allow_outside_project = false
[sdk]
targets = ["typescript", "rust"]
[sdk.typescript]
output_dir = "./src/generated"
package = "@my-org/arete-generated"
[sdk.rust]
output_dir = "./crates/generated"
module_mode = true
crate_prefix = "my_app"
[sdk.python]
output_dir = "./python/generated"
module_mode = false
package_prefix = "my_app"
[dependencies.programs.token]
source = { registry = "spl-token" }
version = "^1.0.0" # use the requirement saved by the current install command
targets = ["typescript"]
[dependencies.programs.token.outputs]
typescript = "./src/generated/programs/token"
# Illustrative: replace with a stack slug and version returned by its descriptor.
[dependencies.stacks.market-data]
source = { registry = "market-data" }
version = "^1.0.0"
targets = ["typescript", "rust"]

The package names and versions above are illustrative, so check the catalog before copying any of them. Better still, let a4 install write the correct table from the descriptor you selected.

A dependency has exactly one source:

SourceMeaning
registryResolve a published package by slug and version requirement
pathUse an exact local ProgramSpec or StackManifest artifact
workspaceRefer to a same-kind entry under [authoring], including a composed stack

A registry requirement expresses what you want. The lockfile records the exact package release and artifact identities that satisfied it.

Registry versions use Arete’s semantic versioning system. They describe compatibility of the published Arete package.

Without dependency-specific overrides, outputs are namespaced by kind:

  • TypeScript: <output_dir>/stacks/<alias> and <output_dir>/programs/<alias>;
  • Rust: <output_dir>/stacks/<prefix>-<alias>-stack and <output_dir>/programs/<prefix>-<alias>-program;
  • Python: <output_dir>/stacks/<prefix>-<alias>-stack and <output_dir>/programs/<prefix>-<alias>-program.

This permits a stack and standalone program to share an alias. Aliases must be unique within their own kind.

Protocol clients ([dependencies.protocols], added with a4 install protocol <ref> --ts, --rust or --python) are registry-only and generate TypeScript, Rust or Python clients. They generate <output_dir>/protocols/<alias>/ (Rust and Python: <alias>-protocol/), with the stacks and programs the protocol hoists nested under stacks/ and programs/. A program the protocol pins only by its local IDL (no program package, so the package leaves it unpinned) is not generated: the client’s README.md lists it, and you install it yourself with a4 install program if your app needs its SDK. A protocol records the deployment its client calls, never a credential: your app’s own key mints a protocol session at runtime.

A dependency-level output is an exact override and does not receive the automatic kind directory.

Terminal window
a4 install
a4 install --locked
a4 install --dry-run
a4 update
a4 update program token
a4 remove program token

Important behaviors:

  • a4 install resolves the complete declared graph.
  • --locked requires a fresh existing lock and never changes resolution.
  • --dry-run validates and prints the plan without writing.
  • a package add saves intent unless --no-save is explicit.
  • generated output and arete.lock are committed only after successful generation of the complete graph.
  • a4 update changes resolution; plain install does not silently replace an exact fresh lock.

Generated directories belong to the installer. Don’t hand-edit entry files, extensions, SDK manifests, or provenance records. Your edits are replaced the next time the code is generated. And if you add files of your own to a generated directory, a4 install refuses to touch it until they are gone.

Commit arete.lock for applications and services that need reproducible generation. It pins exact package and artifact identities, not only semantic versions.

After merging dependency changes, CI should run:

Terminal window
a4 install --locked

A stale lock is a project health warning reported by a4 doctor.

Authored artifacts have stable project names under [authoring]:

[authoring.stacks.local-indexer]
manifest = "./.arete/LocalIndexer.stack-manifest.json"
artifact_roots = ["./.arete"]
deployment_name = "local-indexer"
[dependencies.stacks.indexer]
source = { workspace = "local-indexer" }

artifact_roots grants explicit access to the related content-addressed files. Workspace dependencies make local authored content part of normal project SDK generation.

An [authoring.stacks] entry can also compose a stack from parts instead of naming a StackManifest file: live views from published stacks or LiveSpec files, and program SDKs from program packages or ProgramSpec files. a4 stack compose writes the entry; you can also write it by hand.

[authoring.stacks.ore-plus-token]
live.ore = { stack = "ore", version = "^1", views = ["OreRound/latest", "OreMiner/state"] }
programs = [{ package = "spl-token", version = "^1" }]
[dependencies.stacks.ore-plus-token]
source = { workspace = "ore-plus-token" }
targets = ["typescript"]

live.<alias> names the views the composed stack serves under <alias>:

KeyMeaning
stackA published stack
versionIts version requirement. Omitted: any version; arete.lock pins the release
live_aliasWhich of the stack’s live aliases, when it has more than one
pathA LiveSpec file, instead of stack
viewsThe selected views, in order. Omitted: every view the stack serves (or the file defines)

programs lists program SDKs: { package = "...", version = "..." } for a program package, or { path = "..." } for a ProgramSpec file. An entry has either manifest or live (with optional programs), never both.

When a4 install generates the composed stack:

  • the programs the views index come with them, as the program SDKs their stack references. A programs entry for the same program replaces that SDK, and the install output says so. Other entries are independent programs.
  • selected views must exist in the LiveSpec, and be views the stack serves.
  • a live alias from a stack with hosted delivery reads that stack’s deployment, and its sessions name the version the deployment serves. An alias from a definition-only stack or a LiveSpec file has no endpoints until you deploy the composed stack with a4 up <name>.
  • arete.lock pins every part, from package releases to the composed StackManifest, so a4 install --locked detects any drift and a4 update stack <alias> advances the parts.

See Composed stacks for details. Publishing a composed stack to the registry is not available yet.

The lower-level a4 sdk create command is useful for direct artifact work. It does not write arete.toml or arete.lock and should not replace dependency- backed installation for application projects.

Terminal window
a4 config validate
a4 doctor --json

Validation runs offline. It checks strict keys, source and workspace kinds, local artifact closure, path policy, output collisions, and lock freshness. It can’t tell you whether a hosted service is healthy. When that matters, inspect the exact descriptor and perform a small bounded read.

Authentication is stored separately from the project manifest. Use:

Terminal window
a4 auth signup
a4 auth login --key <a4_ak_...>

Never commit credentials. In headless environments, configure the supported secret environment through the CI secret manager.

VariablePurpose
ARETE_API_URLIntentional API origin override
ARETE_API_KEYHeadless authentication

Overriding the API origin changes who you are trusting. Never send a production key to an origin you don’t trust.