The Package compiles and its tests pass, but nothing can import it yet. Programs import from a Package store, yours or a server’s, and you test the policy by running a program under a Blueprint.
This guide shows you how to publish a Package. The example is Acme’s billing Package on Stripe. Substitute your Package.
Install it locally
Section titled “Install it locally”submilli build publish-local -p @acme/billinginstalled @acme/billing v0.1.0 -> ~/.submilli/packages/@acme/billingpublish-local compiles and installs into the local store, where
submilli run and a server on the same machine find it. Nothing is
uploaded. Without -p, it installs every Package in the project.
See what programs see
Section titled “See what programs see”The agent finds a Package by searching, then reads its declarations. Do the same:
submilli search billing@acme/billing — Goodwill credits for one customer of Acme's billing service.submilli docs @acme/billing prints the declarations and doc comments,
as Document the Package
shows. The description in submilli.toml and the doc comments are all the
model knows about the Package.
Add it to a Blueprint
Section titled “Add it to a Blueprint”In a new directory, start a Blueprint and add the Package. The
Blueprint commands read the capabilities.yaml the build derived on
Export a function:
submilli blueprint init supportsubmilli blueprint add-package @acme/billing --no-capabilities✓ created blueprint.yaml (name: support)warning: blueprint.yaml: package `@acme/billing` requires secret `BILLING_API_KEY`, but `secrets:` does not declare it✓ added @acme/billing to blueprint.yaml 1 provided capabilities not selected; `default: deny` denies calls to them added 3 rules to caller `@acme/billing` (default allow): allow http.get (filter: host == "api.stripe.com") allow http.post (filter: host == "api.stripe.com") allow secrets.get (filter: name == "BILLING_API_KEY")The three rules under the Package’s caller are requires, written as
grants, with the host from the constant and the secret by its name. The
warning is the secret the Package reads, which the Blueprint must
declare. The capability not selected comes from provides, with the
fields the payload reports:
submilli blueprint capability list @acme/billing@acme/billing acme.com/credits.apply — Add a goodwill credit to a customer's account. fields: amount: number, customerClass: string, customerId: stringTry it under a Blueprint
Section titled “Try it under a Blueprint”Finish the Blueprint as Start a Blueprint does. Declare the key, the customer the session is for, and one rule over the payload’s fields:
submilli blueprint secret add BILLING_API_KEY --store billing_api_keysubmilli secret put billing_api_keysubmilli blueprint variable add customerId --requiredsubmilli blueprint capability add acme.com/credits.apply \ --filter 'customerId == ${vars.customerId} and customerClass == "premium"'✓ declared secret 'BILLING_API_KEY' (store: billing_api_key) in blueprint.yamlValue for 'billing_api_key': [hidden]Stored secret 'billing_api_key'✓ declared variable 'customerId' (required) in blueprint.yaml✓ added allow acme.com/credits.apply (filter: customerId == ${vars.customerId} and customerClass == "premium") to caller 'main' in blueprint.yamlCreate credit.ts, a program like one the model would write. It credits
Northwind, a premium customer in Stripe’s test mode:
import { applyCredit } from "@acme/billing";
function main(): string { const credit = applyCredit("cus_VMQR3azuTWVAWs", 1500); return `credited ${credit.amount} cents, balance ${credit.balance}`;}Run it bound to Northwind:
submilli run --blueprint blueprint.yaml --var customerId=cus_VMQR3azuTWVAWs credit.tscredited 1500 cents, balance -1600The program reached Stripe through the Package and came back with the
account’s balance. Bound to another customer, the same program is refused
at the check, as Start a
Blueprint shows.
Make it installable
Section titled “Make it installable”Other machines install from source. Push the project to GitHub, and a developer installs the Package from the repository, built there and pinned to the commit it resolved:
submilli install acme/billing-package @acme/billingThe first argument is the repository, owner/repo, with @<ref> to pin
a branch, tag, or commit. The second is the Package, since one repository
can hold several. A private repository installs the same way once the CLI
has a GitHub token that can read it, as Start a
Blueprint shows:
submilli github authenticatesubmilli install acme/billing-package @acme/billingPut it on a server
Section titled “Put it on a server”A server on the same machine reads the local store, so it already has the
Package. Any other server installs it from the repository with
submilli server packages install, the same way. For a private
repository, refer to
Install private Packages.
Then put the Stripe key in the server’s store, register the Blueprint,
and run the program there, the way an application would:
submilli server secret put billing_api_keysubmilli server blueprint apply blueprint.yamlsubmilli server run-code credit.ts --blueprint support --var customerId=cus_VMQR3azuTWVAWsValue for 'billing_api_key': [hidden]Stored secret 'billing_api_key'Added blueprint 'support'credited 1500 cents, balance -6100