cli

package
v1.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT Imports: 81 Imported by: 0

Documentation

Overview

Package cli implements the iterion command-line interface.

Index

Constants

View Source
const IterationLatest = -1

IterationLatest is the sentinel value of *InspectOptions.Iteration meaning "use the most recently started iteration of (branch, node)".

Variables

View Source
var ErrNotLoggedIn = errors.New("not logged in — run `iterion remote login <url>` first")

ErrNotLoggedIn reports that no remote credential is stored.

View Source
var ErrUserInput = errors.New("user input")

ErrUserInput wraps an underlying error to mark it as caused by a bad user-supplied value (flag, argument, file path, env var) rather than an internal failure. The CLI entry point uses this to map the error to exit code 2 ("usage error") instead of the generic exit 1 ("internal error"), matching the convention shared by most modern CLIs.

Wrap at the call site where the user-facing validation rejected the input:

if err := git.ValidateBranchName(opts.BranchName); err != nil {
    return cli.UserInputError(fmt.Errorf("--branch-name: %w", err))
}

errors.Is(err, ErrUserInput) reports whether any wrapper in the chain marked it as a user-input failure.

Functions

func BotsCreate added in v1.0.0

func BotsCreate(opts BotsCreateOptions, p *Printer) error

BotsCreate scaffolds a new bot bundle at <Dest>/<Slug> from a gallery template, then refreshes the orchestrator-facing catalog so the new bot is routable. It is the CLI half of the studio's "New bot" flow — both call the same botscaffold engine, so a bot created either way is byte-identical.

func BotsList added in v0.39.0

func BotsList(opts BotsListOptions, w io.Writer) error

BotsList walks Opts.Paths, parses metadata, and writes the result to w.

func BotsRegenCatalog added in v0.39.0

func BotsRegenCatalog(workdir string) (string, error)

BotsRegenCatalog regenerates the orchestrator-facing bot catalog (the generated region of the whats-next bundle's iterion-bot-catalog.md) from the live manifests discovered under workdir, applying the workspace overlay. Returns the written path, or "" when the workspace ships no catalog template. The runtime regenerates this automatically at whats-next start and the studio on every bot-metadata save; this is the manual escape hatch (and the way to refresh the committed copy).

func BotsTemplates added in v1.0.0

func BotsTemplates(p *Printer) error

BotsTemplates renders the bot-creation gallery — the same catalog the studio builder shows at /bots/new.

func BuildDefaultConfig added in v0.39.0

func BuildDefaultConfig(storeDir, projectDir string) (*dispatcher.Config, error)

BuildDefaultConfig returns the in-memory dispatcher configuration used by `iterion dispatch` when invoked without a YAML argument: native tracker, HTTP on [defaultDispatchPort], polling every 30 s, the embedded bot catalogue extracted under <storeDir>/dispatcher/ bots, and the `default` fallback bot bound for unassigned issues.

projectDir is the host git repository the dispatcher should seed per-issue workspaces from. When non-empty, an `after_create` hook is wired that runs `git worktree add` from projectDir into the freshly-created issue workspace, so bots see a populated checkout matching the host repo's HEAD instead of an empty directory. When empty (out-of-tree CLI invocations), the hook is omitted and the operator is expected to populate workspaces through a different mechanism (a custom hook, a bind-mount, or a workflow-level worktree: auto block).

The returned Config has [Config.ApplyDefaults] already applied and has passed Validate, so callers can hand it straight to a Manager. SourcePath is left empty so downstream code (notably the ConfigWatcher) can tell baked-in mode apart from YAML-on-disk mode.

func ClearRemoteConfig added in v0.39.0

func ClearRemoteConfig() (string, error)

ClearRemoteConfig removes the stored credential, returning its path.

func DefaultAssigneeNames added in v0.39.0

func DefaultAssigneeNames(paths []string) []string

DefaultAssigneeNames returns the enabled bots discovered under paths, by name, sorted — the routable assignees for the CLI startup banner. Discovery-driven (no hardcoded list), so it reflects custom bots too.

func FormatDuration

func FormatDuration(d time.Duration) string

FormatDuration formats a duration for human display.

func FormatTime

func FormatTime(t time.Time) string

FormatTime formats a time for human display.

func IsTTY

func IsTTY() bool

IsTTY reports whether stdin is connected to a terminal.

func LocalSecretStores added in v0.39.0

func LocalSecretStores(projectStoreDir string) (*secrets.LayeredGenericSecretStore, error)

LocalSecretStores builds the local (non-cloud) secret stores: a required machine-global store at <GlobalIterionDataDir>/secrets.json and an optional per-project store at <projectStoreDir>/secrets.json when that directory is distinct from the global one. The project layer overrides the global by name (LayeredGenericSecretStore).

projectStoreDir is the run's resolved store dir (the `.iterion` the studio / `--store-dir` points at). Pass "" to build a global-only store.

func MarketplaceList added in v0.39.0

func MarketplaceList(ctx context.Context, opts MarketplaceListOptions) ([]marketplace.Entry, error)

MarketplaceList returns the registry entries matching the filters.

func MarketplaceSubmit added in v0.39.0

func MarketplaceSubmit(ctx context.Context, opts MarketplaceSubmitOptions) (*marketplace.Entry, error)

MarketplaceSubmit validates the source (no install), detects its artifact kind (bot bundle or plugin) and indexes it in the local registry, returning the persisted entry. Mirrors the server's POST /api/v1/marketplace/submit business logic.

func MarketplaceUninstall added in v0.43.0

func MarketplaceUninstall(ctx context.Context, opts MarketplaceUninstallOptions) (*marketplace.Entry, error)

MarketplaceUninstall resolves the slug and removes the installed artifact per its kind: a bot's workspace bundle (botinstall.Remove) or an installed plugin (plugin.Uninstall). The registry entry itself is untouched. Returns the entry so callers can echo what was removed.

func ParseAnswerFlags

func ParseAnswerFlags(flags []string) (map[string]string, error)

ParseAnswerFlags parses a slice of "key=value" strings into a map.

func ParseAnswersFile

func ParseAnswersFile(path string) (map[string]any, error)

ParseAnswersFile reads a JSON file containing answer key-value pairs.

func ParseAttachFlags added in v0.39.0

func ParseAttachFlags(flags []string) (map[string]string, error)

ParseAttachFlags parses repeated "name=path" attachment flags.

func ParseVarFlags

func ParseVarFlags(flags []string) (map[string]string, error)

ParseVarFlags parses a slice of "key=value" strings into a map.

func PluginInstall added in v0.39.0

func PluginInstall(ctx context.Context, src string) (string, error)

PluginInstall installs a plugin from a local directory or git URL into ~/.iterion/plugins/<name>/ and returns the installed plugin's name. The mechanism lives in pkg/plugin so the CLI and the HTTP server install identically; see plugin.Install.

func PluginRun added in v0.39.0

func PluginRun(ctx context.Context, name, phase, workspace string) error

PluginRun executes a plugin's lifecycle command ("index" or "refresh") in the given workspace (default: cwd), streaming output to stdout/stderr. The mechanism lives in pkg/plugin (plugin.RunLifecycle) so the CLI and the HTTP server run lifecycles identically.

func PluginSetEnabled added in v0.39.0

func PluginSetEnabled(name string, enabled bool) error

PluginSetEnabled enables or disables a plugin and persists the decision.

func PluginUninstall added in v0.39.0

func PluginUninstall(name string) error

PluginUninstall removes an installed plugin (delegates to plugin.Uninstall).

func PreflightSandbox added in v0.39.0

func PreflightSandbox(ctx context.Context, wf *ir.Workflow, opts SandboxDoctorOptions, logf func(status CheckStatus, c SandboxCheck)) error

PreflightSandbox runs the strict pre-flight battery for an already-compiled workflow + the run's sandbox options, returning a UserInputError when any check fails so the caller can abort the run before booting the engine. It is the opt-in hook `iterion run` invokes (gated by ITERION_SANDBOX_PREFLIGHT) so a misconfigured sandbox surfaces in ~1s with an actionable hint instead of 30s into the run with a cryptic Docker/K8s error.

Unlike the doctor command it does NOT print the full report — it logs each warning at warn level and each failure at error level, then returns a single aborting error pointing at `iterion sandbox doctor --strict` for the detail. Warnings never abort.

func PrintError

func PrintError(w io.Writer, err error)

StatusIcon returns a human-friendly icon for a run status. PrintError writes a structured error message to w. If the error is a RuntimeError it includes the error code, node, and hint.

func PrintRemoteJSON added in v0.39.0

func PrintRemoteJSON(p *Printer, body []byte)

PrintRemoteJSON renders a raw server response: lossless passthrough in --json mode, pretty-printed JSON otherwise. The fallback for commands whose payload has no table rendering.

func PromptHumanAnswers

func PromptHumanAnswers(interaction *store.Interaction) (map[string]any, error)

PromptHumanAnswers displays the interaction questions and prompts the user for answers interactively via stdin. Returns the answers as a map.

func QueryString added in v0.39.0

func QueryString(pairs map[string]string) string

QueryString builds a ?k=v&… query from the non-empty pairs (empty string when none are set).

func RawCommit added in v0.4.0

func RawCommit() string

RawCommit returns the bare commit string (short SHA, possibly empty).

func RawVersion added in v0.4.0

func RawVersion() string

RawVersion returns the bare version string (e.g. "v1.2.3" or "dev"). Used by the desktop About panel and the auto-updater to compare semver against the latest manifest.

func ReadDataArg added in v0.39.0

func ReadDataArg(data string) ([]byte, error)

ReadDataArg reads a `--data` argument: literal JSON, or `@file` (with `@-` reading stdin). Empty input returns nil.

func ReadSecretValue added in v0.39.0

func ReadSecretValue(fromEnv, fromFile string, stdinOK bool) (string, error)

ReadSecretValue resolves a secret's value from --from-env, @file, or stdin — never from a positional argument (process lists leak argv).

func RemoteAPIKeysCreate added in v0.39.0

func RemoteAPIKeysCreate(ctx context.Context, c *RemoteClient, p *Printer, scope, teamFlag, provider, name, value string, isDefault bool) error

func RemoteAPIPrint added in v0.39.0

func RemoteAPIPrint(ctx context.Context, c *RemoteClient, p *Printer, method, path string, body []byte) error

RemoteAPIPrint is the `remote api` escape hatch: it prints the response body regardless of status (an error response is exactly what the caller asked to see) and maps non-2xx to an *APIError.

func RemoteConfigPath added in v0.39.0

func RemoteConfigPath() (string, error)

RemoteConfigPath is where the CLI stores the remote credential.

func RemoteGetPrint added in v0.39.0

func RemoteGetPrint(ctx context.Context, c *RemoteClient, p *Printer, path string) error

RemoteGetPrint fetches a GET endpoint and prints the JSON response — the shared implementation for the long-tail read commands whose payloads have no dedicated table rendering.

func RemoteIssuesCreate added in v0.39.0

func RemoteIssuesCreate(ctx context.Context, c *RemoteClient, p *Printer, f RemoteIssueFields) error

func RemoteIssuesList added in v0.39.0

func RemoteIssuesList(ctx context.Context, c *RemoteClient, p *Printer, opts RemoteIssuesListOptions) error

func RemoteIssuesUpdate added in v0.39.0

func RemoteIssuesUpdate(ctx context.Context, c *RemoteClient, p *Printer, id string, f RemoteIssueFields, set map[string]bool) error

RemoteIssuesUpdate PATCHes only the explicitly-set fields (set maps flag-name presence, so an empty string can clear a field).

func RemoteOrgsList added in v0.39.0

func RemoteOrgsList(ctx context.Context, c *RemoteClient, p *Printer) error

RemoteOrgsList renders the orgs derivable from the account's memberships.

func RemoteOrgsSwitch added in v0.39.0

func RemoteOrgsSwitch(ctx context.Context, c *RemoteClient, p *Printer, orgID string) error

RemoteOrgsSwitch persists the default org used by org-scoped commands. Org scope is path-based for the API, so no re-mint is needed.

func RemoteRoutesList added in v0.39.0

func RemoteRoutesList(ctx context.Context, c *RemoteClient, p *Printer) error

RemoteRoutesList renders the instance's live route table.

func RemoteRunsAction added in v0.39.0

func RemoteRunsAction(ctx context.Context, c *RemoteClient, p *Printer, id, action string, body any) error

RemoteRunsAction posts a bodyless (or fixed-body) lifecycle action.

func RemoteRunsArtifacts added in v0.39.0

func RemoteRunsArtifacts(ctx context.Context, c *RemoteClient, p *Printer, id, node, file string) error

RemoteRunsArtifacts lists artifacts, or the artifact file tree/content.

func RemoteRunsCommits added in v0.39.0

func RemoteRunsCommits(ctx context.Context, c *RemoteClient, p *Printer, id, sha string, diff bool) error

func RemoteRunsDelete added in v0.39.0

func RemoteRunsDelete(ctx context.Context, c *RemoteClient, p *Printer, id string) error

func RemoteRunsEvents added in v0.39.0

func RemoteRunsEvents(ctx context.Context, c *RemoteClient, p *Printer, id string, from int64, follow bool, interval time.Duration) error

RemoteRunsEvents prints a page of events; with follow it keeps polling by seq cursor until the run reaches a terminal status.

func RemoteRunsFiles added in v0.39.0

func RemoteRunsFiles(ctx context.Context, c *RemoteClient, p *Printer, id string, opts RemoteRunsFilesOptions) error

func RemoteRunsFollow added in v0.39.0

func RemoteRunsFollow(ctx context.Context, c *RemoteClient, p *Printer, id string, interval time.Duration) error

RemoteRunsFollow tails a run until it terminates; exits with an error when the terminal status is failed/failed_resumable/cancelled.

func RemoteRunsGet added in v0.39.0

func RemoteRunsGet(ctx context.Context, c *RemoteClient, p *Printer, id string) error

func RemoteRunsLaunch added in v0.39.0

func RemoteRunsLaunch(ctx context.Context, c *RemoteClient, p *Printer, opts RemoteRunsLaunchOptions) error

func RemoteRunsList added in v0.39.0

func RemoteRunsList(ctx context.Context, c *RemoteClient, p *Printer, opts RemoteRunsListOptions) error

func RemoteRunsPreviewCost added in v0.39.0

func RemoteRunsPreviewCost(ctx context.Context, c *RemoteClient, p *Printer, filePath string, vars map[string]string) error

func RemoteRunsRaw added in v0.39.0

func RemoteRunsRaw(ctx context.Context, c *RemoteClient, p *Printer, id, endpoint string) error

RemoteRunsRaw streams a raw endpoint (log, workflow source) to output.

func RemoteRunsResume added in v0.39.0

func RemoteRunsResume(ctx context.Context, c *RemoteClient, p *Printer, id string, opts RemoteRunsResumeOptions) error

func RemoteRunsUploadFile added in v0.39.0

func RemoteRunsUploadFile(ctx context.Context, c *RemoteClient, path string) (string, error)

RemoteRunsUploadFile stages a local file via POST /api/runs/uploads and returns the upload id.

func RemoteSecretsRotate added in v0.39.0

func RemoteSecretsRotate(ctx context.Context, c *RemoteClient, p *Printer, scope, teamFlag, secretID, value string) error

func RemoteSecretsSet added in v0.39.0

func RemoteSecretsSet(ctx context.Context, c *RemoteClient, p *Printer, scope, teamFlag, name, value string) error

func RemoteSendData added in v0.39.0

func RemoteSendData(ctx context.Context, c *RemoteClient, p *Printer, method, path, dataArg, what string) error

RemoteSendData is RemoteSendPrint fed by a --data argument (literal JSON, @file, or @- for stdin), which it requires to be non-empty. `what` names the expected payload in the error message.

func RemoteSendPrint added in v0.39.0

func RemoteSendPrint(ctx context.Context, c *RemoteClient, p *Printer, method, path string, body []byte) error

RemoteSendPrint sends a request with an optional raw JSON body and prints the response — the shared implementation for long-tail mutation commands driven by --data.

func RemoteTeamsList added in v0.39.0

func RemoteTeamsList(ctx context.Context, c *RemoteClient, p *Printer) error

func RemoteTeamsSwitch added in v0.39.0

func RemoteTeamsSwitch(ctx context.Context, c *RemoteClient, p *Printer, teamID, tokenName string) error

RemoteTeamsSwitch changes the CLI's default team. A PAT's identity team is pinned at mint time, so switching means minting a NEW token pinned to the target team, persisting it, and revoking the previous CLI token (identified deterministically by its SHA-256 fingerprint; an env-provided or unmatched token is left alone with a notice).

func RemoteTokensCreate added in v0.39.0

func RemoteTokensCreate(ctx context.Context, c *RemoteClient, p *Printer, name, teamID string, expiresInDays int) error

RemoteTokensCreate mints a PAT and prints the plaintext once.

func RemoteTokensList added in v0.39.0

func RemoteTokensList(ctx context.Context, c *RemoteClient, p *Printer) error

func RemoteTokensRevoke added in v0.39.0

func RemoteTokensRevoke(ctx context.Context, c *RemoteClient, p *Printer, tokenID string) error

func ResolveRecipePath added in v0.39.0

func ResolveRecipePath(path string) string

ResolveRecipePath returns a real on-disk path for `path`, transparently falling back to the recipes shipped embedded in the binary when the requested path does not exist on disk. This makes commands like

iterion run feature-dev/main.bot
iterion run bots/whole-improve-loop/main.bot

work from any working directory — the user does not have to explicitly point at `<repo>/examples/...`. Bundle directories (`examples/<name>/main.bot`) and `.botz` archives are NOT in the embed glob; resolve them by explicit path or by `iterion run <name>.botz` when packed adjacent to the source.

Resolution order:

  1. If the path exists on disk, return it as-is.
  2. Otherwise, look up `path` in the embedded recipe FS. If found, materialise the content into a stable per-user cache directory and return that path.
  3. Otherwise, return the original `path` so callers surface the usual "no such file" error to the user.

We materialise to a real file rather than reading from embed.FS at each call site because the engine, parser, and several runtime helpers operate on real paths (worktree relative locations, file-watcher, sandbox bind-mounts). Materialisation keeps that contract intact at the cost of a tiny one-time write.

func RunAnswer added in v1.1.0

func RunAnswer(opts AnswerOptions, p *Printer) error

RunAnswer answers one pending async question: records the answer on the interaction, emits interaction_answered, and queues the node-scoped delivery message for the asking node.

func RunBenchAsymptote added in v0.39.0

func RunBenchAsymptote(opts BenchAsymptoteOptions, p *Printer) error

RunBenchAsymptote loads the requested runs, parses each with the asymptote pipeline, aggregates per group, renders, and writes the report.

func RunBundlePack added in v0.39.0

func RunBundlePack(srcDir, outPath string, force bool, p *Printer) error

RunBundlePack writes a deterministic `.botz` archive from srcDir.

  • srcDir must be an existing directory containing `main.bot` at the root.
  • outPath, when empty, defaults to "<srcDir>.botz" in srcDir's parent.
  • force, when true, removes any existing output before packing.

Reports the result via the printer in either human or JSON format.

func RunDiagram

func RunDiagram(opts DiagramOptions, p *Printer) error

RunDiagram compiles a .bot file and outputs its Mermaid diagram.

func RunDispatch added in v0.39.0

func RunDispatch(p *Printer, opts DispatchOptions) error

RunDispatch loads the config, opens the necessary stores, builds a Manager + starts a dispatcher, then serves the REST/WS surface until SIGINT/SIGTERM.

This is the standalone CLI path — same Manager primitive that the studio server uses, just driven by a YAML on disk instead of the SPA's PUT /api/v1/dispatcher/config endpoint.

func RunImport added in v0.50.0

func RunImport(opts ImportOptions, p *Printer) error

RunImport converts a Claude-Code workflow script (.js) into a draft .bot file. The conversion is lossy by contract: everything the lowering can't express becomes an annotated `## IMPORT` marker plus a report entry, and the draft is compile-checked before any write.

func RunInspect

func RunInspect(opts InspectOptions, p *Printer) error

RunInspect loads and displays a run's state.

func RunIssueBoardInit added in v0.39.0

func RunIssueBoardInit(p *Printer, opts IssueBoardInitOptions) error

RunIssueBoardInit replaces the board configuration.

func RunIssueBoardShow added in v0.39.0

func RunIssueBoardShow(p *Printer, opts IssueCommonOptions) error

RunIssueBoardShow prints the current board.json.

func RunIssueClose added in v0.39.0

func RunIssueClose(p *Printer, opts IssueRefOptions) error

RunIssueClose moves the issue to the first terminal state on the board.

func RunIssueCreate added in v0.39.0

func RunIssueCreate(p *Printer, opts IssueCreateOptions) error

RunIssueCreate creates a new issue in the native tracker.

func RunIssueImport added in v0.50.0

func RunIssueImport(p *Printer, opts IssueImportOptions) error

RunIssueImport imports a forge repo's issues into the native board, reusing the store-agnostic sync core via server.ImportForgeIssues. The token is read only from the NAMED env var (secrets discipline — never a flag value). The import is idempotent: re-running upserts existing cards instead of duplicating them.

func RunIssueList added in v0.39.0

func RunIssueList(p *Printer, opts IssueListOptions) error

RunIssueList prints issues from the native tracker.

func RunIssueMove added in v0.39.0

func RunIssueMove(p *Printer, opts IssueMoveOptions) error

RunIssueMove transitions an issue.

func RunIssueShow added in v0.39.0

func RunIssueShow(p *Printer, opts IssueRefOptions) error

RunIssueShow prints a single issue.

func RunIssueUpdate added in v0.39.0

func RunIssueUpdate(p *Printer, opts IssueUpdateOptions) error

RunIssueUpdate applies the patch.

func RunModels added in v0.39.0

func RunModels(ctx context.Context, opts ModelsOptions, p *Printer) error

RunModels resolves and prints ModelCapabilities for one model (--spec/arg) or a representative known set, reporting the resolution source (aggregator|curated) and the context window. With opts.Refresh it first force-refetches the model-spec cache via the shared resolver; a failed refresh is reported but non-fatal so the command still works offline.

func RunPrune added in v0.50.0

func RunPrune(opts PruneOptions, p *Printer) error

RunPrune is the entry point for `iterion runs prune`.

func RunQuestions added in v1.1.0

func RunQuestions(opts QuestionsOptions, p *Printer) error

RunQuestions lists a run's pending async questions.

func RunReport

func RunReport(opts ReportOptions, p *Printer) error

RunReport generates a detailed chronological report for a run.

func RunResumeWithFile

func RunResumeWithFile(ctx context.Context, iterFile string, opts ResumeOptions, p *Printer) error

RunResumeWithFile resumes a paused run using a workflow file and answers. iterFile is optional: when empty, the run's persisted FilePath (recorded at launch — for inline launches, this is the server's inline-source cache path) is used. This lets the CLI resume an inline-launched run without the caller re-supplying the source.

func RunRun

func RunRun(ctx context.Context, opts RunOptions, p *Printer) error

RunRun executes a workflow or recipe and reports the outcome.

func RunSandboxDoctor added in v0.4.0

func RunSandboxDoctor(ctx context.Context, p *Printer, opts SandboxDoctorOptions) error

RunSandboxDoctor implements `iterion sandbox doctor`. Without SandboxDoctorOptions.Strict it prints the host-only report (unchanged from prior releases). With Strict it resolves the effective sandbox spec and runs the full pre-flight battery, returning a non-nil error (non-zero exit) when any check fails.

func RunScheduleAdd added in v0.39.0

func RunScheduleAdd(p *Printer, opts ScheduleAddOptions) error

func RunScheduleAudit added in v0.50.0

func RunScheduleAudit(p *Printer, opts ScheduleAuditOptions) error

RunScheduleAudit prints the tick-decision history recorded by RunScheduleRun (and any other surface writing to the same file).

func RunScheduleInstall added in v0.39.0

func RunScheduleInstall(p *Printer, opts ScheduleInstallOptions) error

func RunScheduleList added in v0.39.0

func RunScheduleList(p *Printer, opts ScheduleCommonOptions) error

func RunScheduleRemove added in v0.39.0

func RunScheduleRemove(p *Printer, opts ScheduleRefOptions) error

func RunScheduleRun added in v0.39.0

func RunScheduleRun(ctx context.Context, p *Printer, opts ScheduleRunOptions) error

func RunScheduleUninstall added in v0.39.0

func RunScheduleUninstall(p *Printer, opts ScheduleCommonOptions) error

func RunSecretList added in v0.39.0

func RunSecretList(p *Printer, opts SecretOptions) error

RunSecretList prints every local secret (both layers) with its scope and last4 — never the value.

func RunSecretRemove added in v0.39.0

func RunSecretRemove(p *Printer, opts SecretOptions) error

RunSecretRemove deletes a local secret by name (searching the project layer first, then global).

func RunSecretSet added in v0.39.0

func RunSecretSet(p *Printer, opts SecretOptions) error

RunSecretSet creates or rotates (upsert-by-name) a local secret. The value is read — never from argv — via --from-env, a stdin pipe, or a masked TTY prompt. The value is AES-GCM sealed before it touches disk and is never echoed back.

func RunSkillAdd added in v0.39.0

func RunSkillAdd(p *Printer, opts SkillOptions) error

RunSkillAdd creates or overwrites a skill from a file (--from) or stdin.

func RunSkillExport added in v0.39.0

func RunSkillExport(p *Printer, opts SkillOptions) error

RunSkillExport copies a skill's file(s) out to a destination directory.

func RunSkillImport added in v0.39.0

func RunSkillImport(p *Printer, opts SkillOptions) error

RunSkillImport installs a public skill library (a bare skills/ git repo or a local dir) via the plugin skills-only-manifest path — the third-party-pack half of the hybride model. The installed pack is enable/disable-able via `iterion plugin`; enable it to make its skills mirror into runs.

func RunSkillList added in v0.39.0

func RunSkillList(p *Printer, opts SkillOptions) error

RunSkillList prints every library skill (both layers) with scope + description.

func RunSkillRemove added in v0.39.0

func RunSkillRemove(p *Printer, opts SkillOptions) error

RunSkillRemove deletes a skill at the selected scope.

func RunSkillShow added in v0.39.0

func RunSkillShow(p *Printer, opts SkillOptions) error

RunSkillShow prints the resolved path + full body of one skill.

func RunStudio added in v0.39.0

func RunStudio(ctx context.Context, opts StudioOptions, p *Printer) error

func RunSupervise added in v0.39.0

func RunSupervise(p *Printer, opts SuperviseOptions) error

RunSupervise attaches a supervisor to either an iterion run (--run-id) or a raw Claude Code session (--claude-session) and blocks until the target ends or the operator interrupts (SIGINT/SIGTERM).

func RunSuperviseInstallHook added in v0.39.0

func RunSuperviseInstallHook(p *Printer, repoDir string, project, remove bool) error

RunSuperviseInstallHook installs (or removes, when remove=true) the drain hook in the target repo's Claude Code settings.

func RunValidate

func RunValidate(path string, p *Printer) error

RunValidate parses, compiles, and validates a .bot file or `.botz` archive. For bundles, the workflow source is extracted to a cache directory and validated; bundle metadata (name, version) is reported alongside the workflow result.

func SaveRemoteConfig added in v0.39.0

func SaveRemoteConfig(c RemoteConfig) error

func SeedMarketplace added in v0.39.0

func SeedMarketplace(ctx context.Context, store marketplace.Store, opts SeedOptions) (int, error)

SeedMarketplace indexes the bundles discovered under opts.Paths as builtin, pre-approved, public registry entries so the marketplace isn't empty out of the box. It is idempotent and conservative:

  • a slug already owned by a user (git/upload source) is never clobbered;
  • a builtin entry is rewritten only when absent or its version drifted, so reseeding is a no-op and install counters survive (Upsert preserves Installs when the new entry carries 0).

Returns the number of entries written (created or updated).

func SeedMarketplaceDefault added in v0.39.0

func SeedMarketplaceDefault(ctx context.Context, store marketplace.Store, workdir string) (int, error)

SeedMarketplaceDefault seeds store from the default catalog roots (ITERION_MARKETPLACE_SEED_PATHS, comma-separated, workspace-relative; defaults to "bots") resolved under workdir. It is the cloud-server counterpart to the inline seeding the studio command does, exported so cmd/iterion can call it without duplicating the path resolution. A "none"/"-" override (or an empty result) skips seeding and returns (0, nil). Best-effort + idempotent — see SeedMarketplace.

func SplitRunIDs added in v0.39.0

func SplitRunIDs(csv string) []string

SplitRunIDs parses a comma-separated CLI flag value into a slice of run IDs, trimming whitespace and skipping empty entries.

func StatusIcon

func StatusIcon(status string) string

func UserInputError added in v0.39.0

func UserInputError(err error) error

UserInputError wraps err with ErrUserInput so the CLI exits with status 2. Returns nil when err is nil so the caller can chain `return cli.UserInputError(maybeErr)` without a nil check.

func Version

func Version() string

Version returns the human-readable version string (e.g. "v1.2.3 (abc1234)"). It is the public entry point for cmd/iterion (and cmd/iterion-desktop) to read version info without importing internal/appinfo directly — Go's internal-package rule forbids imports of pkg/internal/ from outside pkg/.

Types

type APIError added in v0.39.0

type APIError struct {
	Status int
	Method string
	Path   string
	Body   string
}

APIError is a non-2xx response from the remote instance. Message is the first line of the response body — the server's httpError text.

func (*APIError) Error added in v0.39.0

func (e *APIError) Error() string

type AnswerOptions added in v1.1.0

type AnswerOptions struct {
	StoreDir      string
	RunID         string
	InteractionID string
	Answer        string
}

AnswerOptions configures RunAnswer.

type BenchAsymptoteOptions added in v0.39.0

type BenchAsymptoteOptions struct {
	StoreDir          string
	Runs              []string // canonical asymptote subjects (same workflow, N independent sessions)
	VariantRuns       []string // optional: alternative recipe variant for comparison
	Label             string   // primary group label (default: "asymptote")
	VariantLabel      string   // variant group label (default: "variant")
	JudgeNode         string   // IR node ID of the judge whose verdicts we score
	JudgeField        string   // output field name (default "approved")
	LoopName          string   // optional: pin to one loop (default: first observed)
	ApprovalThreshold float64  // default 0.5
	Output            string   // markdown path; "-" or "" → stdout
	Title             string
	IncludePerRun     bool
}

BenchAsymptoteOptions configures the `iterion bench asymptote` command.

The asymptote thesis (see docs/why-iterion.md) holds that running the same workflow across N independent sessions produces a quality curve that climbs and stabilises — that stabilisation is the asymptote, and it measures the (model + recipe)'s reliability ceiling for the task.

Primary use: feed N runs of the same workflow via --runs and observe the per-iteration aggregate + cross-session distribution.

Secondary use: feed an alternative recipe variant via --variant-runs to quantify a lift (typically a multi-family alternation variant for security-critical or complex tasks). Multi-family alternation is *not* the default thesis — it is the optional refinement.

type BotEntry added in v0.39.0

type BotEntry = botregistry.Entry

BotEntry is an alias of botregistry.Entry so existing CLI callers and tests keep working. Discovery + schema-augmented variants live in pkg/botregistry (importable by pkg/server, which cannot import pkg/cli).

type BotsCreateOptions added in v1.0.0

type BotsCreateOptions struct {
	// Slug is the bundle directory + technical name (botscaffold.SlugRe).
	Slug string
	// Workdir is the workspace root (default: current directory). It
	// anchors both Dest and the catalog refresh, mirroring
	// botinstall.Options.
	Workdir string
	// Dest is the parent directory for the bundle, relative to Workdir
	// unless absolute (default: bots/).
	Dest string
	// Template is a gallery template ID (default: blank).
	Template string

	DisplayName  string
	Description  string
	Instructions string
	Model        string
	Backend      string
	Worktree     *bool
	Sandbox      *bool
}

BotsCreateOptions configures BotsCreate. Empty string fields and nil pointers mean "keep the template's value" — only what the operator actually passed overrides the gallery template.

type BotsListOptions added in v0.39.0

type BotsListOptions struct {
	// Paths is the list of roots to walk. A path may point to a single
	// .bot file (treated as one entry), a .botz bundle directory, or a
	// directory containing many .bot files / sub-bundles.
	Paths []string

	// Format selects the output rendering: "json" (default), "markdown",
	// or "skill" (a SKILL.md ready to drop in a `<bundle>/skills/`).
	Format string
}

BotsListOptions configures discovery for BotsList.

type BudgetOverrides added in v0.39.0

type BudgetOverrides = ir.BudgetOverrides

BudgetOverrides aliases ir.BudgetOverrides so existing CLI callers (RunOptions.Budget, ResumeOptions.Budget, cmd/iterion flag wiring) keep compiling unchanged. The canonical type + apply logic live in pkg/dsl/ir/budget_override.go, shared with the server launch path.

type BundlePackResult added in v0.39.0

type BundlePackResult struct {
	Output   string `json:"output"`
	Hash     string `json:"hash"`
	Entries  int    `json:"entries"`
	BytesIn  int64  `json:"bytes_in"`
	BytesOut int64  `json:"bytes_out"`
}

BundlePackResult is the JSON shape emitted by `iterion bundle pack --json`.

type CheckStatus added in v0.39.0

type CheckStatus string

CheckStatus is the outcome of a single strict-doctor check.

const (
	CheckPass CheckStatus = "pass"
	CheckWarn CheckStatus = "warn"
	CheckFail CheckStatus = "fail"
)

type DiagramOptions

type DiagramOptions struct {
	File string // .bot file path
	View string // "compact" (default), "detailed", or "full"
}

DiagramOptions holds options for the diagram command.

type DiagramResult

type DiagramResult struct {
	File         string `json:"file"`
	WorkflowName string `json:"workflow_name"`
	View         string `json:"view"`
	Mermaid      string `json:"mermaid"`
}

DiagramResult holds the output of a diagram command.

type DispatchOptions added in v0.39.0

type DispatchOptions struct {
	ConfigPath string
	StoreDir   string
	Port       int  // overrides cfg.Server.Port if > 0
	NoServer   bool // overrides cfg.Server.Port to disable HTTP
}

DispatchOptions captures CLI flags for `iterion dispatch`.

type ImportOptions added in v0.50.0

type ImportOptions struct {
	// File is the workflow script to import (.js).
	File string
	// Out is the output .bot path. Empty: <workflow-name>.bot next to
	// the source file.
	Out string
	// Name overrides the workflow name (default meta.name, then stem).
	Name string
	// DryRun prints the draft instead of writing it.
	DryRun bool
}

ImportOptions configures RunImport.

type InspectOptions

type InspectOptions struct {
	RunID    string
	StoreDir string
	Events   bool // show event log
	Full     bool // show all details

	Node      string
	Branch    string
	Iteration *int // nil = unset; -1 = latest started
	// ExecutionID is the alternative single-string selector
	// ("exec:<branch>:<node>:<iter>"). Mutually exclusive with --node.
	ExecutionID string
	Section     InspectSection
	LogTail     int
	ListNodes   bool
}

InspectOptions holds the configuration for the inspect command.

type InspectSection

type InspectSection string

InspectSection enumerates the per-node report buckets the caller can restrict to via --section. Empty value behaves as SectionAll.

const (
	SectionAll          InspectSection = "all"
	SectionSummary      InspectSection = "summary"
	SectionEvents       InspectSection = "events"
	SectionTrace        InspectSection = "trace"
	SectionTools        InspectSection = "tools"
	SectionArtifacts    InspectSection = "artifacts"
	SectionInteractions InspectSection = "interactions"
	SectionLog          InspectSection = "log"
)

type IssueBoardInitOptions added in v0.39.0

type IssueBoardInitOptions struct {
	IssueCommonOptions
	From  string // optional path to a board.json
	Force bool
}

IssueBoardInitOptions configures `issue board init`.

type IssueCommonOptions added in v0.39.0

type IssueCommonOptions struct {
	StoreDir string
}

IssueCommonOptions are flags shared by every `iterion issue` subcommand.

type IssueCreateOptions added in v0.39.0

type IssueCreateOptions struct {
	IssueCommonOptions
	Title    string
	Body     string
	State    string
	Labels   []string
	Priority int
	Assignee string
	Blockers []string
	Fields   []string // custom-field key=value pairs (Issue.Fields)
	Bot      string   // typed workflow override consumed by the dispatcher
	BotArgs  []string // typed dispatcher var overrides as key=value (Issue.BotArgs)
}

IssueCreateOptions captures the flags for `iterion issue create`.

type IssueImportOptions added in v0.50.0

type IssueImportOptions struct {
	IssueCommonOptions
	Forge    string // github | forgejo | gitlab
	Repo     string // owner/name
	TokenEnv string // NAME of the env var holding the forge token (never the value)
	BaseURL  string // forge API base; empty = provider default
	Since    string // RFC3339; empty = full re-sync
	// MinAuthorRole is the trust threshold (gitlab vocabulary; "" →
	// developer) above which an issue author's fresh card is stamped
	// triage:auto instead of parked needs:approval.
	MinAuthorRole string
}

IssueImportOptions captures the flags for `iterion issue import`: mirror a self-hosted forge repo's issues into the native board.

type IssueListOptions added in v0.39.0

type IssueListOptions struct {
	IssueCommonOptions
	States    []string
	Labels    []string
	Assignee  string
	OnlyClaim bool
	OnlyFree  bool
}

IssueListOptions captures the flags for `iterion issue list`.

type IssueMoveOptions added in v0.39.0

type IssueMoveOptions struct {
	IssueCommonOptions
	IDOrPrefix string
	To         string
}

IssueMoveOptions moves an issue to a new state.

type IssueRefOptions added in v0.39.0

type IssueRefOptions struct {
	IssueCommonOptions
	IDOrPrefix string
}

IssueRefOptions identifies a single issue by ID or prefix.

type IssueUpdateOptions added in v0.39.0

type IssueUpdateOptions struct {
	IssueCommonOptions
	IDOrPrefix string
	Title      *string
	Body       *string
	Labels     *[]string
	Priority   *int
	Assignee   *string
	Blockers   *[]string
	Fields     []string // key=value (set or replace)
	ClearField []string
}

IssueUpdateOptions captures partial-update fields. Nil pointer means "unchanged".

type MarketplaceInstallOptions added in v0.39.0

type MarketplaceInstallOptions struct {
	StoreDir string
	Slug     string
	Workdir  string
	Force    bool
}

MarketplaceInstallOptions configures `iterion marketplace install`.

type MarketplaceInstallResult added in v0.43.0

type MarketplaceInstallResult struct {
	Kind   marketplace.Kind
	Bot    *botinstall.Result
	Plugin string
	Entry  *marketplace.Entry
}

MarketplaceInstallResult is the kind-aware outcome of MarketplaceInstall: Bot is set for bot entries (the .botz install result), Plugin for plugin entries (the installed plugin name).

func MarketplaceInstall added in v0.39.0

MarketplaceInstall resolves the slug and installs the entry per its kind — a bot's bundle into the workspace's .botz/, a plugin into ~/.iterion/plugins/ — bumping the install counter. Returns the kind-aware result with the refreshed entry.

type MarketplaceListOptions added in v0.39.0

type MarketplaceListOptions struct {
	StoreDir string
	Text     string
	Tag      string
	// Kind filters by artifact kind: "" (any), "bot" or "plugin".
	Kind string
}

MarketplaceListOptions configures `iterion marketplace list`.

type MarketplaceSubmitOptions added in v0.39.0

type MarketplaceSubmitOptions struct {
	StoreDir string
	Source   string // git URL (optionally url#ref) or local path
	Ref      string
	Path     string
	Tags     []string
}

MarketplaceSubmitOptions configures `iterion marketplace submit`.

type MarketplaceUninstallOptions added in v0.43.0

type MarketplaceUninstallOptions struct {
	StoreDir string
	Slug     string
	Workdir  string
}

MarketplaceUninstallOptions configures `iterion marketplace uninstall`.

type MigrateOrgsResult added in v0.39.0

type MigrateOrgsResult struct {
	ScannedTeams      int
	OrgsCreated       int
	TeamsLinked       int
	OrgMembersCreated int
	OrgsDeleted       int // reverse only
	// Mapping is teamID → orgID for the teams this run created/linked.
	Mapping map[string]string
	// Changes is a human-readable log of every mutation (or would-be
	// mutation under dry-run).
	Changes []string
}

MigrateOrgsResult summarizes a teams→orgs backfill (or its reversal).

func MigrateTeamsToOrgs added in v0.39.0

func MigrateTeamsToOrgs(ctx context.Context, st identity.Store, logger *iterlog.Logger, dryRun bool) (MigrateOrgsResult, error)

MigrateTeamsToOrgs is the idempotent teams→orgs backfill (ADR-048). For every team that has no parent org yet it creates a new Org (a new id, marked MigratedFromTeamID for idempotency + reversal), links the team to it, and mirrors the team's memberships up to org memberships (team owners/admins → org admins, everyone else → org member).

Idempotent: a team already carrying an OrgID, or one that already has an org with MigratedFromTeamID == team.ID, is skipped — re-running is a no-op. The monthly run/cost/memory quota fields moved from Team to Org in this release; legacy custom caps are NOT carried over (they decode away from the new Team struct), so a migrated org starts on the platform defaults and an operator re-applies any custom cap via the admin console. Personal/Status are copied up.

Pure store operations, so it runs against the Mongo store in production and the memory store in tests.

func ReverseTeamsToOrgs added in v0.39.0

func ReverseTeamsToOrgs(ctx context.Context, st identity.Store, logger *iterlog.Logger, dryRun bool) (MigrateOrgsResult, error)

ReverseTeamsToOrgs undoes a backfill: for every org created by the migration (MigratedFromTeamID set) it clears the source team's OrgID, deletes the org's memberships, and deletes the org. Idempotent.

type MigrateRunPathsOptions added in v0.39.0

type MigrateRunPathsOptions struct {
	// StoreDir is the run store root; runs live under
	// <StoreDir>/runs/<id>/run.json.
	StoreDir string
	// DryRun reports the changes without writing them.
	DryRun bool
}

MigrateRunPathsOptions configures MigrateRunPaths.

type MigrateRunPathsResult added in v0.39.0

type MigrateRunPathsResult struct {
	Scanned int             `json:"scanned"`
	Updated int             `json:"updated"`
	Changes []RunPathChange `json:"changes"`
}

MigrateRunPathsResult summarises a migration pass.

func MigrateRunPaths added in v0.39.0

func MigrateRunPaths(opts MigrateRunPathsOptions) (MigrateRunPathsResult, error)

MigrateRunPaths rewrites file_path + bundle_path in every <StoreDir>/runs/*/run.json that still points at a relocated bot's old examples/ source. Idempotent and field-scoped (the rest of each run.json is preserved byte-for-byte). A missing runs/ directory is a no-op (returns a zero result, no error).

type ModelsOptions added in v0.39.0

type ModelsOptions struct {
	// Spec is an optional "provider/model-id". When empty the command lists a
	// representative set of known models (model.KnownModelSpecs()).
	Spec string
	// Refresh force-refetches the model-spec cache before resolving.
	Refresh bool
}

ModelsOptions configures the `iterion models` command.

type OutputFormat

type OutputFormat int

OutputFormat controls how results are rendered.

const (
	OutputHuman OutputFormat = iota
	OutputJSON
)

type PluginView added in v0.39.0

type PluginView = plugin.View

PluginView is the listing-facing projection of a loaded plugin (an alias of plugin.View so the CLI and the HTTP server render plugins identically).

func PluginConfigSet added in v0.39.0

func PluginConfigSet(name string, sets []string) (PluginView, error)

PluginConfigSet parses "key=value" --set flags and applies them to a plugin (accepting only declared fields, keeping a secret left blank), returning the refreshed view. Parsing shares the package's kv-flag scanner.

func PluginConfigView added in v0.39.0

func PluginConfigView(name string) (PluginView, error)

PluginConfigView returns a plugin's view (config schema + masked values).

func PluginInfo added in v0.39.0

func PluginInfo(name string) (PluginView, *plugin.Manifest, error)

PluginInfo returns the full view for one plugin (incl. config schema + current values via ViewFor) plus its manifest.

func PluginList added in v0.39.0

func PluginList() ([]PluginView, error)

PluginList loads the registry and returns every plugin as a view.

type Printer

type Printer struct {
	W      io.Writer
	Format OutputFormat
}

Printer writes structured output in the selected format.

func NewPrinter

func NewPrinter(format OutputFormat) *Printer

NewPrinter creates a Printer writing to stdout.

func (*Printer) Blank

func (p *Printer) Blank()

Blank prints an empty line.

func (*Printer) Header

func (p *Printer) Header(title string)

Header prints a section header.

func (*Printer) JSON

func (p *Printer) JSON(v any)

JSON emits v as indented JSON. If encoding fails (non-marshalable value: channels, cycles, etc.), write a JSON error envelope to stderr so machine consumers see a parse-able failure signal rather than an empty stdout that looks like a clean success.

func (*Printer) KV

func (p *Printer) KV(key, value string)

KV prints a key-value pair with aligned formatting.

func (*Printer) Line

func (p *Printer) Line(format string, args ...any)

Line prints a formatted line.

func (*Printer) Table

func (p *Printer) Table(headers []string, rows [][]string)

Table prints rows with column headers.

type PruneOptions added in v0.50.0

type PruneOptions struct {
	StoreDir  string
	OlderThan time.Duration
	KeepLast  int
	Statuses  []string
	DryRun    bool
	Now       func() time.Time // test seam; nil = time.Now
}

PruneOptions holds the configuration for `iterion runs prune`.

type PruneResult added in v0.50.0

type PruneResult struct {
	StoreDir     string      `json:"store_dir"`
	AgeField     string      `json:"age_field"`
	OlderThan    string      `json:"older_than"`
	KeepLast     int         `json:"keep_last"`
	Statuses     []string    `json:"statuses"`
	DryRun       bool        `json:"dry_run"`
	Scanned      int         `json:"scanned"`
	Pruned       []PrunedRun `json:"pruned"`
	PrunedCount  int         `json:"pruned_count"`
	SkippedCount int         `json:"skipped_count"`
	// Unreadable lists run dirs whose run.json could not be loaded
	// (partial delete, crash before the first write). They are never
	// deleted — the operator inspects or removes them by hand.
	Unreadable []string `json:"unreadable,omitempty"`
	// TombstonesReaped counts the deletion markers older than the
	// retention horizon that this sweep removed for good.
	TombstonesReaped int `json:"tombstones_reaped,omitempty"`
}

PruneResult is the top-level payload for --json.

type PrunedRun added in v0.50.0

type PrunedRun struct {
	ID           string    `json:"id"`
	Name         string    `json:"name,omitempty"`
	WorkflowName string    `json:"workflow_name,omitempty"`
	BundleName   string    `json:"bundle_name,omitempty"`
	Status       string    `json:"status"`
	AgeSeconds   int64     `json:"age_seconds"`
	Timestamp    time.Time `json:"timestamp"`
	Deleted      bool      `json:"deleted"`
}

PrunedRun is a machine-readable record of one prune decision. Used as the row element of both the human table and the --json output.

type QuestionsOptions added in v1.1.0

type QuestionsOptions struct {
	StoreDir string
	RunID    string
}

QuestionsOptions configures RunQuestions.

type RemoteClient added in v0.39.0

type RemoteClient struct {
	// contains filtered or unexported fields
}

RemoteClient does authenticated requests to a configured instance.

func NewRemoteClient added in v0.39.0

func NewRemoteClient() (*RemoteClient, error)

func NewRemoteClientFor added in v0.39.0

func NewRemoteClientFor(cfg RemoteConfig) *RemoteClient

func (*RemoteClient) API added in v0.39.0

func (c *RemoteClient) API(ctx context.Context, method, path string, body []byte) (int, []byte, error)

API performs an authenticated request with the stored token.

func (*RemoteClient) BaseURL added in v0.39.0

func (c *RemoteClient) BaseURL() string

func (*RemoteClient) Call added in v0.39.0

func (c *RemoteClient) Call(ctx context.Context, method, path string, in, out any) ([]byte, error)

Call performs an authenticated JSON request. A non-nil `in` is marshalled as the request body; a non-2xx status returns *APIError; a non-nil `out` receives the decoded response. The raw response body is always returned so --json output can be a lossless passthrough of what the server sent.

func (*RemoteClient) LoginWithPassword added in v0.39.0

func (c *RemoteClient) LoginWithPassword(ctx context.Context, email, password, patName string) (string, error)

LoginWithPassword exchanges email+password for an access JWT, then mints a long-lived PAT and returns it (the credential to store).

func (*RemoteClient) Me added in v0.39.0

func (c *RemoteClient) Me(ctx context.Context) (RemoteMe, error)

Me fetches the authenticated account's identity view.

func (*RemoteClient) ResolveOrg added in v0.39.0

func (c *RemoteClient) ResolveOrg(ctx context.Context, flag string) (string, error)

ResolveOrg is ResolveTeam's org-level counterpart.

func (*RemoteClient) ResolveTeam added in v0.39.0

func (c *RemoteClient) ResolveTeam(ctx context.Context, flag string) (string, error)

ResolveTeam resolves the team id for a team-scoped command: explicit flag > env/persisted default (both already folded into cfg.TeamID by ResolveRemoteConfig) > the account's active team from /api/auth/me. Never a silent guess: an unresolvable team is an explicit error.

func (*RemoteClient) Upload added in v0.39.0

func (c *RemoteClient) Upload(ctx context.Context, path, field, filename string, r io.Reader, extra map[string]string, out any) ([]byte, error)

Upload performs an authenticated multipart/form-data POST with the file under `field`, plus optional extra form values. Non-2xx returns *APIError; a non-nil `out` receives the decoded response.

type RemoteConfig added in v0.39.0

type RemoteConfig struct {
	BaseURL string `json:"base_url"`
	Token   string `json:"token"`
	Email   string `json:"email,omitempty"`
	// TeamID / OrgID are the default tenant scope for team-/org-scoped
	// commands. Persisted by `iterion remote teams|orgs switch`; a
	// per-command --team/--org flag or ITERION_REMOTE_TEAM/_ORG wins.
	TeamID string `json:"team_id,omitempty"`
	OrgID  string `json:"org_id,omitempty"`
}

RemoteConfig is the stored credential for talking to a remote iterion instance over its HTTP API. The token is an `iap_` personal access token sent as a Bearer header; long-lived, so the CLI never juggles refresh tokens.

func LoadRemoteConfig added in v0.39.0

func LoadRemoteConfig() (RemoteConfig, error)

func ResolveRemoteConfig added in v0.39.0

func ResolveRemoteConfig() (RemoteConfig, error)

ResolveRemoteConfig resolves the remote credential for a command. ITERION_REMOTE_URL switches to a pure-environment config (token from ITERION_REMOTE_TOKEN, falling back to ITERION_TOKEN) so CI can drive an instance with zero config file — and so a stored token is never sent to a different host than the one it was minted for. Without the env URL the stored ~/.iterion/cli-auth.json is used. ITERION_REMOTE_TEAM / ITERION_REMOTE_ORG override the persisted default scope either way.

type RemoteIssueFields added in v0.39.0

type RemoteIssueFields struct {
	Title    string
	Body     string
	State    string
	Labels   []string
	Priority int
	Assignee string
	Bot      string
	BotArgs  map[string]string
}

RemoteIssueFields carries the create/update payload the CLI exposes.

type RemoteIssuesListOptions added in v0.39.0

type RemoteIssuesListOptions struct {
	States   []string
	Labels   []string
	Assignee string
}

RemoteIssuesListOptions filter the board issue list.

type RemoteMe added in v0.39.0

type RemoteMe struct {
	User struct {
		ID           string `json:"id"`
		Email        string `json:"email"`
		Name         string `json:"name"`
		IsSuperAdmin bool   `json:"is_super_admin"`
	} `json:"user"`
	ActiveOrgID  string `json:"active_org_id"`
	ActiveTeamID string `json:"active_team_id"`
	Teams        []struct {
		TeamID   string `json:"team_id"`
		TeamName string `json:"team_name"`
		OrgID    string `json:"org_id"`
		Role     string `json:"role"`
	} `json:"teams"`
}

RemoteMe is the subset of GET /api/auth/me the CLI consumes.

type RemoteRunsFilesOptions added in v0.39.0

type RemoteRunsFilesOptions struct {
	Path     string
	Mode     string // "uncommitted" | "branch" (server-side default applies)
	Diff     bool
	Content  bool
	EditFile string // local file whose bytes replace the remote path (PUT)
}

RemoteRunsFilesOptions selects the workspace-files view.

type RemoteRunsLaunchOptions added in v0.39.0

type RemoteRunsLaunchOptions struct {
	FilePath      string // local .bot file; read and sent inline as source
	BotID         string // catalog bot id (alternative to FilePath)
	Vars          map[string]string
	Preset        string
	Timeout       string
	Backend       string
	Compress      string
	Permission    string
	ReviewMode    string
	MergeInto     string
	BranchName    string
	MergeStrategy string
	AutoMerge     bool
	// Attach maps attachment name -> local file path; each is uploaded
	// to /api/runs/uploads first and referenced by upload id.
	Attach             map[string]string
	ModelOverridesJSON []byte // raw model_overrides array (from @file)
	CallbackURL        string
	CallbackToken      string
	Follow             bool
	FollowInterval     time.Duration
}

RemoteRunsLaunchOptions mirrors the POST /api/runs body the CLI fills.

type RemoteRunsListOptions added in v0.39.0

type RemoteRunsListOptions struct {
	Status   string
	Workflow string
	Repo     string
	Since    string // RFC3339, passed through verbatim
	Limit    int
}

RemoteRunsListOptions filter the run list (server-side query params).

type RemoteRunsResumeOptions added in v0.39.0

type RemoteRunsResumeOptions struct {
	AnswersFile string // JSON map of answers (@file semantics handled by caller)
	FilePath    string // optionally push a modified workflow
	Force       bool
	Timeout     string
}

RemoteRunsResumeOptions mirrors resumeRunRequest.

type ReportOptions

type ReportOptions struct {
	RunID    string
	StoreDir string
	Output   string // output file path (empty = stdout)
}

ReportOptions holds the configuration for the report command.

type ResumeOptions

type ResumeOptions struct {
	RunID       string
	StoreDir    string
	AnswersFile string            // path to JSON answers file
	Answers     map[string]string // --answer key=value overrides
	LogLevel    string            // log level (default: "info", env: ITERION_LOG_LEVEL)
	Force       bool              // allow resume despite workflow hash change
	// ForceStale auto-promotes a status=running run to failed_resumable
	// IFF its events.jsonl mtime is older than forceStaleStaleAfter.
	// The server-boot sweep (pkg/store.PromoteStaleOrphans) covers the
	// common case automatically; this flag is the operator's escape
	// hatch when they spot an orphan in a long-running session, or want
	// to bypass waiting for the next server restart.
	ForceStale bool
	Executor   runtime.NodeExecutor
	// Background marks this invocation as a managed-runner subprocess
	// spawned by the studio server. The CLI writes a .pid file so the
	// server can detect liveness across its own restart.
	Background bool
	// Budget carries CLI overrides for the workflow's budget: block,
	// mirroring `iterion run`. The documented "budget exceeded → raise the
	// budget + resume" recovery relies on this. Non-zero wins; zero
	// inherits. See applyBudgetOverrides.
	Budget BudgetOverrides
	// Permission overrides the tool-permission gate on resume. Adding an
	// allow rule here is how an operator authorizes a call the run paused
	// on (`permission: ask`): the rule lands in the resolved policy, the
	// agent re-issues the call, and it proceeds. See docs/permissions.md.
	Permission      string
	PermissionAllow []string
	PermissionAsk   []string
	PermissionDeny  []string
	// ModelFor / BackendFor re-apply the launch-time per-node/-group model+
	// backend overrides on resume (repeatable --model / --backend,
	// "selector=value" or bare "value"). Resume does NOT persist the original
	// run's overrides, so a run launched with e.g. `--model 'judge=...'` falls
	// back to the node's DSL model unless the same flags are passed again here.
	// Parsed via model.ParseModelOverrides in buildResumeExecutor.
	ModelFor   []string
	BackendFor []string
	// AutoResume is the bounded run-level auto-resume budget N
	// (`--auto-resume`, env ITERION_AUTO_RESUME; default 0 = off). Mirrors
	// RunOptions.AutoResume so `iterion resume` can itself keep re-driving a
	// transient-failing run without a human in the loop. See auto_resume.go.
	AutoResume int
}

ResumeOptions holds the configuration for the resume command.

type RunOptions

type RunOptions struct {
	File          string               // .bot file path or .botz bundle path
	Recipe        string               // recipe JSON file path (alternative to File)
	Vars          map[string]string    // --var key=value overrides
	Preset        string               // --preset <name>: applies an in-source named preset before --var
	RunID         string               // explicit run ID (auto-generated if empty)
	Source        *store.RunSource     // originating-action provenance stamped on the run (schedule launches)
	StoreDir      string               // explicit store override; empty uses store.ResolveStoreDir anchored at the workflow project
	Timeout       time.Duration        // maximum run duration (0 = no limit)
	LogLevel      string               // log level (default: "info", env: ITERION_LOG_LEVEL)
	NoInteractive bool                 // disable interactive TTY prompting on human pause
	Executor      runtime.NodeExecutor // pluggable executor (nil = stub)
	// Background marks this invocation as a managed-runner subprocess
	// spawned by the studio server. The CLI writes a .pid file so the
	// server can detect liveness across its own restart, and forces
	// NoInteractive (no TTY in the spawned process).
	Background bool
	// MergeInto controls the worktree-finalization fast-forward target
	// for `worktree: auto` runs. "" or "current" → FF the user's
	// currently-checked-out branch (default); "none" → skip FF;
	// <branch-name> → FF that branch (must match currently-checked-out).
	MergeInto string
	// BranchName overrides the default storage branch
	// `iterion/run/<friendly>` created on the worktree's HEAD. The
	// branch is always created (GC guard); on collision a numeric
	// suffix is appended.
	BranchName string
	// MergeStrategy selects how the run's commits are landed on the
	// merge target when AutoMerge is on: "squash" (default) collapses
	// into one commit; "merge" fast-forwards (preserves history).
	MergeStrategy string
	// AutoMerge toggles whether the engine performs the merge at end
	// of run. CLI default is true (preserves prior behaviour); the
	// studio sets false by default to defer merge to a UI action.
	AutoMerge bool
	// Sandbox is the run-level override for the sandbox activation
	// mode ("", "none", "auto"). "" inherits the global default
	// (ITERION_SANDBOX_DEFAULT, else "auto" — sandbox-by-default, see
	// runtime.ResolveGlobalSandboxDefault). The workflow's own
	// `sandbox:` block is the next layer of precedence; per-node
	// overrides win above all. See pkg/sandbox.
	Sandbox string
	// SandboxDefaultImage overrides the image ref used by `sandbox: auto`
	// when no .devcontainer/devcontainer.json is found in the workspace.
	// Empty inherits ITERION_SANDBOX_DEFAULT_IMAGE then the built-in
	// default (`ghcr.io/socialgouv/iterion-sandbox-slim:<iterion-version>`).
	SandboxDefaultImage string
	// SandboxHostState controls whether the host's `~/.iterion` (run
	// store) and `~/.claude` (Claude Code OAuth + sessions) are
	// auto-mounted into the sandbox so persistent memory survives
	// across runs. Values: "", "auto", "none". Empty inherits
	// ITERION_SANDBOX_HOST_STATE then the built-in default "auto".
	SandboxHostState string
	// Compress is the run-level command-output-compression override
	// ("", "on", "ultra", "off"). "" inherits the workflow/node `compress:`
	// DSL then the ITERION_COMPRESS env default. It is the highest-priority
	// input to rewrite.Resolve. See docs/plugins.md.
	Compress string
	// Permission is the run-level tool-permission-gate mode override
	// ("", "off", "ask", "deny"). "" inherits the workflow/node
	// `permission:` DSL then the ITERION_PERMISSION env default.
	// PermissionAllow/Ask/Deny are run-level rules, additive to the
	// workflow-level lists. See docs/permissions.md.
	Permission      string
	PermissionAllow []string
	PermissionAsk   []string
	PermissionDeny  []string
	// Budget carries CLI overrides for the workflow's budget: block
	// (--max-cost-usd / --max-tokens / --max-duration / --max-iterations /
	// --max-parallel-branches). Non-zero fields win over the DSL/recipe
	// budget; zero fields inherit. See applyBudgetOverrides.
	Budget BudgetOverrides
	// ReviewMode is the run-level override for bi-model review-loop bots'
	// mono/dual topology ("", "auto", "mono", "dual"). Only bots that
	// declare a review_mode var are affected. "" / "auto" resolves from
	// detected provider credentials at launch (pkg/reviewtopology);
	// "mono"/"dual" force the topology. See docs on review topology.
	ReviewMode string
	// ModelFor / BackendFor are launch-time per-node/-group model+backend
	// overrides (repeatable --model / --backend flags), each a
	// "selector=value" (or a bare "value" targeting every LLM node). They win
	// over the node's DSL model:/backend: so a run can re-target the bot per
	// node-group without editing the .bot. Parsed via model.ParseModelOverrides
	// in buildRunExecutor. See model_override.go.
	ModelFor   []string
	BackendFor []string
	// AutoResume is the bounded run-level auto-resume budget N
	// (`--auto-resume`, env ITERION_AUTO_RESUME; default 0 = off). When the
	// run exits failed_resumable with a retryable cause, the CLI waits
	// (capped exponential backoff) and re-invokes resume in-process up to N
	// times, re-using this run's exact overrides. See auto_resume.go.
	AutoResume int
	// SkipMCPHealth downgrades a failing MCP startup health-check from a
	// fatal error to a warning: the check still runs (its diagnostics are
	// logged) but a failure no longer aborts the run. Set by --skip-mcp-health
	// or a truthy ITERION_SKIP_MCP_HEALTH env var. Useful when the project
	// .mcp.json declares a server that is unreachable/unauthorized in this
	// environment (e.g. an HTTP-OAuth MCP) but the run does not depend on it.
	SkipMCPHealth bool
}

RunOptions holds the configuration for the run command.

type RunPathChange added in v0.39.0

type RunPathChange struct {
	RunID string `json:"run_id"`
	Field string `json:"field"`
	From  string `json:"from"`
	To    string `json:"to"`
}

RunPathChange is one rewritten field in one run.

type SandboxCheck added in v0.39.0

type SandboxCheck struct {
	Name        string      `json:"name"`
	Status      CheckStatus `json:"status"`
	Detail      string      `json:"detail,omitempty"`
	Remediation string      `json:"remediation,omitempty"`
}

SandboxCheck is one line of the strict report: a named check, its status, an optional human detail, and a remediation hint shown only for non-pass results.

type SandboxDoctorOptions added in v0.39.0

type SandboxDoctorOptions struct {
	// Strict turns on the pre-run validation battery (driver liveness,
	// image resolvability, k8s compatibility, network syntax, …) and
	// makes the command exit non-zero on any failure.
	Strict bool
	// File is an optional workflow (.bot/.botz/dir) whose sandbox:
	// block is resolved and validated. Empty runs host-level checks only.
	File string
	// Sandbox / SandboxDefaultImage / SandboxHostState mirror the
	// `iterion run` flags so the doctor validates the EXACT spec a run
	// with the same flags would use.
	Sandbox             string
	SandboxDefaultImage string
	SandboxHostState    string
	// Target selects the check battery: "auto" (follow the selected
	// driver, default), "cloud" (force the kubernetes/host-independent
	// battery — validate a cloud workflow from a laptop), or "local"
	// (force docker).
	Target string
}

SandboxDoctorOptions tunes `iterion sandbox doctor`. The zero value reproduces the historical host-only report.

type SandboxStrictReport added in v0.39.0

type SandboxStrictReport struct {
	Host   string         `json:"host"`
	Target string         `json:"target,omitempty"`
	Driver string         `json:"driver,omitempty"`
	Mode   string         `json:"mode"`
	Source string         `json:"source,omitempty"`
	Image  string         `json:"image,omitempty"`
	Checks []SandboxCheck `json:"checks"`
}

SandboxStrictReport is the full result of `iterion sandbox doctor --strict`. It is rendered human-readably or as JSON, and drives the process exit code via SandboxStrictReport.Failed.

func (*SandboxStrictReport) Failed added in v0.39.0

func (r *SandboxStrictReport) Failed() bool

Failed reports whether any check has status fail.

type ScheduleAddOptions added in v0.39.0

type ScheduleAddOptions struct {
	ScheduleCommonOptions
	Name          string
	Cron          string
	Bot           string
	Workdir       string
	StoreDir      string
	Sandbox       string
	Timeout       string
	VarFlags      []string
	Description   string
	Disabled      bool
	Overlap       string
	MaxConcurrent int
	Guard         string
	GuardTimeout  string
	GuardVar      string
	StaleAfter    string
}

type ScheduleAuditOptions added in v0.50.0

type ScheduleAuditOptions struct {
	ScheduleCommonOptions
	Name    string // filter: schedule name/id ("" = all)
	Surface string // filter: host-cron|trigger|cloud ("" = all)
	Since   string // filter: Go duration lookback ("" = all)
	Tail    int    // keep only the last N matching rows (0 = all)
}

type ScheduleCommonOptions added in v0.39.0

type ScheduleCommonOptions struct {
	ManifestPath string // --manifest; "" → resolveScheduleManifestPath
}

type ScheduleEntry added in v0.39.0

type ScheduleEntry struct {
	Name        string            `yaml:"name"`
	Cron        string            `yaml:"cron"`
	Bot         string            `yaml:"bot"`
	Workdir     string            `yaml:"workdir,omitempty"`
	StoreDir    string            `yaml:"store_dir,omitempty"`
	Sandbox     string            `yaml:"sandbox,omitempty"`
	Timeout     string            `yaml:"timeout,omitempty"`
	Vars        map[string]string `yaml:"vars,omitempty"`
	Description string            `yaml:"description,omitempty"`
	Disabled    bool              `yaml:"disabled,omitempty"`

	// Overlap policy + pre-launch guard (pkg/schedgate). Overlap
	// defaults to "skip": a tick whose previous run is still live is
	// skipped (and audited) instead of piling up concurrent runs.
	// Guard is an optional `sh -lc` snippet run before any launch —
	// exit 0 fires the run with its stdout in vars[guard_var],
	// non-zero skips the tick. See docs/scheduling.md#overlap-policy.
	// Overlap "keepalive" runs the bot always-on at the cron cadence (host
	// crontab floors at 1 minute — sub-minute keepalive needs the resident
	// scheduler): a stale run silent past StaleAfter is relaunched.
	Overlap       string `yaml:"overlap,omitempty"`
	MaxConcurrent int    `yaml:"max_concurrent,omitempty"`
	Guard         string `yaml:"guard,omitempty"`
	GuardTimeout  string `yaml:"guard_timeout,omitempty"`
	GuardVar      string `yaml:"guard_var,omitempty"`
	StaleAfter    string `yaml:"stale_after,omitempty"`
}

ScheduleEntry is one recurring run. Cron is a standard 5-field expression passed opaquely to the host cron — iterion does not interpret it, the host scheduler does.

type ScheduleInstallOptions added in v0.39.0

type ScheduleInstallOptions struct {
	ScheduleCommonOptions
	Print bool   // render the managed block to stdout; don't touch the crontab
	TZ    string // crontab CRON_TZ; "" → UTC
}

type ScheduleManifest added in v0.39.0

type ScheduleManifest struct {
	Version   int             `yaml:"version"`
	Schedules []ScheduleEntry `yaml:"schedules"`
}

ScheduleManifest is the declarative set of recurring runs. It is host-wide (a host has a single crontab); each entry carries its own Workdir so one manifest can schedule bots across several repositories.

type ScheduleRefOptions added in v0.39.0

type ScheduleRefOptions struct {
	ScheduleCommonOptions
	Name string
}

type ScheduleRunOptions added in v0.39.0

type ScheduleRunOptions struct {
	ScheduleCommonOptions
	Name   string
	DryRun bool
}

type SecretOptions added in v0.39.0

type SecretOptions struct {
	Name     string
	FromEnv  string
	Project  bool
	Hosts    []string
	HostsSet bool // whether --hosts was explicitly passed (distinguish "clear" from "leave")
	StoreDir string
}

SecretOptions carries the shared inputs for the `iterion secret` subcommands. StoreDir is the per-project store dir (the `.iterion` the run store uses); empty resolves it from the working directory. Project selects the per-project layer over the machine-global one for set/remove.

type SeedOptions added in v0.39.0

type SeedOptions struct {
	// Paths are bundle source roots to index (e.g. ["bots"]). Resolved
	// relative to Workdir when not absolute. Whatever bots the target
	// repo ships under these paths become the seeded entries — the
	// mechanism is repo-agnostic; it never assumes a specific layout.
	Paths []string
	// Workdir is the base for relative Paths (default: current dir).
	Workdir string
}

SeedOptions configures SeedMarketplace.

type SkillOptions added in v0.39.0

type SkillOptions struct {
	Name     string
	From     string // file to read the skill body from (add); empty = stdin
	Project  bool
	StoreDir string
	Dir      string // export destination dir
}

SkillOptions carries the shared inputs for the `iterion skill` subcommands. StoreDir is the per-project store dir (the `.iterion` the run store uses); empty resolves it from the working directory. Project selects the per-project layer (<store>/.iterion/skills) over the machine-global one (~/.iterion/skills) for add/rm.

type StudioOptions added in v0.39.0

type StudioOptions struct {
	Port      int
	Bind      string // bind address (default "127.0.0.1"); use "0.0.0.0" to expose on LAN
	Dir       string // working directory (for examples)
	StoreDir  string // explicit store override; empty uses store.ResolveStoreDir anchored at Dir
	NoBrowser bool   // skip opening browser
	// NoBrowserPane disables every Browser-pane code path: the
	// preview proxy, the CDP WS endpoint, and the Chromium runner.
	// Useful for emergency lockdown (security incident) or for
	// shaving startup latency when the operator never needs the
	// pane. Defaults to false (pane enabled).
	NoBrowserPane bool

	// OnReady, when non-nil, is invoked once the HTTP listener is up and
	// the server has accepted its bind address. The argument is the actual
	// host:port the listener is bound to (useful when Port=0 / random).
	// Invoked from a goroutine; callers must be ready for it to fire
	// concurrently with their own Run loop.
	OnReady func(addr string)

	// Mode, when set, advertises the deployment context in
	// /api/server/info and tunes upload defaults ("desktop" raises
	// the per-file cap to 1 GB; "" / "local" / "web" keep the 50 MB
	// cap). The server's Config.Mode owns the same field.
	Mode string

	// MaxUploadSize / MaxTotalUploadSize / MaxUploadsPerRun /
	// AllowUploadMime override the server's upload limits. Zero
	// values fall through to mode-specific defaults applied by
	// pkg/server.applyUploadDefaults.
	MaxUploadSize      int64
	MaxTotalUploadSize int64
	MaxUploadsPerRun   int
	AllowUploadMime    []string

	// MaxConcurrentPipelines caps how many ROOT pipelines run at once
	// (0 = unlimited). Over the cap, launches wait in the pipeline
	// board's Todo lane. Threaded into server.Config →
	// runview.WithMaxConcurrentPipelines.
	MaxConcurrentPipelines int

	// OnForceRefresh, when non-nil, is forwarded to the server and fires
	// before /api/backends/detect?force=1 invalidates its cache. The
	// desktop host uses this to re-source ~/.iterion/env so dotenv
	// edits (including key deletions) are picked up without a restart.
	OnForceRefresh func()

	// BotsPaths configures where the /api/v1/bots endpoint walks to
	// discover bots for the Board ticket form's bot picker. Empty
	// falls back to <Dir>/bots, <Dir>/examples, <Dir>/.botz.
	BotsPaths []string

	// DesktopAlertSink, when non-nil, is wired as the run-health alert
	// desktop delivery sink (the desktop app injects a Wails
	// EventsEmit-backed sink for native OS notifications). It is honoured
	// only when desktop alerts are enabled (ITERION_ALERTS_DESKTOP_ENABLED
	// / alerts.desktop.enabled). The headless CLI and the --server-only
	// daemon leave it nil — they have no Wails runtime to emit through.
	DesktopAlertSink alert.Sink
}

StudioOptions holds options for the studio command.

type SuperviseOptions added in v0.39.0

type SuperviseOptions struct {
	RunID    string
	Session  string // raw Claude Code session: cwd or session id (mutually exclusive with RunID)
	Name     string
	Model    string
	System   string   // inline policy text, or @path to read from a file
	Nodes    []string // node ids to watch (empty = whole run)
	Monitors []string // pre-declared monitors as "key=val,key=val" specs
	Cooldown time.Duration
	MaxEvals int
	StoreDir string
}

SuperviseOptions configures `iterion supervise` — the attach path that points an LLM supervisor at an already-running run (the in-.bot `supervisor <name>:` declaration auto-spawns the same coordinator and needs none of this). The supervisor watches the run's event stream and enqueues steering messages the run picks up at its next turn.

type ValidateResult

type ValidateResult struct {
	File               string   `json:"file"`
	Valid              bool     `json:"valid"`
	WorkflowName       string   `json:"workflow_name,omitempty"`
	NodeCount          int      `json:"node_count,omitempty"`
	EdgeCount          int      `json:"edge_count,omitempty"`
	BundleName         string   `json:"bundle_name,omitempty"`
	BundleVersion      string   `json:"bundle_version,omitempty"`
	ParseDiagnostics   []string `json:"parse_diagnostics,omitempty"`
	CompileDiagnostics []string `json:"compile_diagnostics,omitempty"`
	// BundleDiagnostics holds manifest↔workflow consistency findings
	// (bundlelint, C2xx). Kept separate from CompileDiagnostics so the
	// studio can distinguish DSL-level from manifest-level issues.
	BundleDiagnostics []string `json:"bundle_diagnostics,omitempty"`
}

ValidateResult holds the outcome of a validate command.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL