@kodara-agent/cli
v0.8.5
Published
Manage Kodara agent definitions as versioned Markdown folders.
Readme
Kodara CLI
@kodara-agent/cli manages Kodara agent definitions as small, versioned Markdown folders. The installed executable is kodara.
Install and authorize
npm install --global @kodara-agent/cli
kodara loginLogin opens a one-time browser approval page. Only a current Kodara super admin can approve access. The resulting revocable token is stored in the operating system's user configuration directory with owner-only file permissions.
Use --api-url http://localhost:3001 or KODARA_API_URL for a non-production API. An explicit flag wins over the environment, saved login URL, and production default.
Automatic interactive updates
The CLI treats an invocation as interactive only when process.stderr.isTTY === true. Every such developer-terminal invocation, including --help and --version, needs online access to the official npm registry and checks its current latest release before argument parsing or command execution. Non-interactive automation—including piped or captured stderr, cron, CI, and agent subprocesses—performs no registry lookup or self-update and behaves as before.
The installed version must exactly equal the registry value. A mismatch in either direction installs the exact observed latest version globally, verifies the installed package metadata, and relaunches the same entrypoint with the original arguments. Concurrent invocations serialize through a cross-process lock; a stale waiter rechecks both versions and relaunches its older process without repeating an installation that another process completed.
A registry, lock, npm installation, installed-metadata verification, relaunch, or maximum of three update-and-relaunch cycles failure hard-blocks the requested command. Recover manually with:
npm install --global @kodara-agent/cli@latestThere is no bypass. This strict policy means an unavailable registry or broken latest release also makes interactive help and version output unavailable.
The updater began with 0.8.0, which is published. Existing pre-0.8.0 installations cannot self-update into behavior they do not contain, so each developer must bootstrap once before automatic updates can take over:
npm install --global @kodara-agent/[email protected]Start with help
kodara --help
kodara agents --help
kodara agents eval --helpThe root and group help stay short, list only their direct children, and are therefore not exhaustive. Every executable command has command-specific, scoped --help with its purpose, usage, relevant options and operational notes when needed, and at least one copy-paste example. Scoped help is authoritative; the rest of this README documents long-lived workflow and safety contracts.
Private Agent V5 conversations
After kodara login, a current super admin can create, continue, and read a private Agent V5 conversation. The complete command forms are:
kodara conversations send --agent <agent-id> --message '<text>' [--task <task-id>] [--json]
kodara conversations get <task-id> [--json]For example:
kodara conversations send --agent 00000000-0000-4000-8000-000000000001 --message 'Summarize the strongest positioning angle.'
kodara conversations send --agent 00000000-0000-4000-8000-000000000001 --task 00000000-0000-4000-8000-000000000002 --message 'Turn that into three hooks.'
kodara conversations get 00000000-0000-4000-8000-000000000002send waits for the V5 turn to finish. A new turn creates a caller-owned task persisted as hidden, admin-audience, and non-onboarding; both the user message and the assistant response are stored in the canonical conversation. Only the profile authenticated by the CLI token can read or continue it. Another super admin receives the same Conversation not found response as an unknown task ID. Continuation requires --agent to name the same agent that created the task; an agent mismatch is rejected. Messages must contain 1 to 100,000 characters after trimming.
Human send output prints Task: <task-id> followed by Response: and the persisted assistant response. Human get output prints the task ID and persisted User: / Assistant: messages in chronological order. Human rendering normalizes line endings and removes terminal control and Unicode format characters while preserving ordinary Unicode and message newlines. With --json, the CLI prints the exact validated API DTO instead, including exact persisted message content without human-terminal sanitization. Before the CLI's strict DTO parsing, the API converts persisted PostgreSQL timestamptz values, including microseconds and explicit offsets, to UTC timestamps with exact millisecond .sssZ precision.
Conversation failures expose only bounded, allowlisted messages and never raw response bodies, prompts, provider details, or internal causes. Only one continuation can run for a task at a time across API instances. An overlapping continuation exits with Conversation already has a turn in progress before its message is appended; wait for the active turn to finish, read the task, then retry the continuation. Different task IDs and new sends can still run concurrently. If execution fails after a new task is created, the error returns its task ID and tells you to inspect it with kodara conversations get <task-id> or retry with the same agent and --task <task-id>. A failed continuation receives the same task-specific read/retry guidance when the returned validated task ID matches the requested task, without claiming that the task was created. A continuation response carrying a different task ID remains a generic bounded failure. Retrying a new send without --task creates a separate conversation.
This release does not provide conversation listing, deletion, files, customer selection, V3 fallback, or streaming terminal output.
Privileged V5 fleet benchmark
The repository benchmark uses an existing super-admin CLI access token for both direct discovery and fixed-case execution; it does not spawn the installed CLI:
KODARA_BENCHMARK_API_ORIGIN=https://api.kodara.com \
KODARA_BENCHMARK_TOKEN="$KODARA_CLI_ACCESS_TOKEN" \
KODARA_BENCHMARK_OUTPUT=/absolute/private/path/agent-v5-latency.json \
npm run benchmark:v5KODARA_BENCHMARK_CONCURRENCY is optional and defaults to 3. Fleet discovery pages the benchmark-only inventory endpoint until coverage is complete and fails closed on malformed pages, duplicate agents, repeated cursors, or the 1,000-page and 10,000-agent safety bounds. Every accepted run requires V5/version proof from headers plus initial and terminal SSE events and records the retained hidden task ID. Optional reports are exclusive 0600 files with recursive token redaction.
Organization runtime rollout
Use the guarded organization commands to inspect readiness, enable V5 everywhere in an organization, or roll back to V3:
kodara customers runtime status <organization-id>
kodara customers runtime enable-v5 <organization-id>
kodara customers runtime disable-v5 <organization-id>Each command accepts --json. Enablement is atomic and fails with agent-level blockers when any active available agent lacks a valid published V5 definition. Once enabled, V5 serves coach/customer chat, onboarding, and newly created voice sessions without V3 fallback. Disablement is unconditional; existing voice sessions keep the runtime pinned when they were created.
Find and pull an agent
Start with the command-specific help for each step:
kodara customers search --help
kodara agents list --help
kodara agents pull --helpA typical search and pull looks like:
kodara customers search "Acme"
kodara agents list --customer <organization-id>
kodara agents pull <agent-id>Pull writes kodara-workspace/<customer>/<agent>/ with index.md, linked rubric files, situation-grouped style examples, evals/*.md, Pending/Not applied feedback, and .kodara/manifest.json. Definitions and feedback are independently hashed. A concise AGENTS.md and project-local .agents/skills/ skills (rubric-editing, agent-improvement-loop, readiness-report) are created for coding agents. A pull safely refreshes AGENTS.md only when it matches a known unmodified generated version, including the immediately previous version; modified and custom instructions are preserved byte-for-byte. Do not edit the manifest or feedback contents.
Styles are pull-only, read-only context synced one way from the server. They inform review but are excluded from eval and publish payloads; local style edits are never sent back.
Brain is not bundled into a normal agent workspace pull. Discover and fetch only the evidence needed for the current task:
kodara agents brain search --help
kodara agents brain pull --helpOn-demand Brain files land under brain/ as local-only review evidence and are preserved across later workspace pulls. They are hidden from the web Agent Files editor and excluded from definition validation, diff, eval, provenance, and publish payloads. A local Brain edit blocks a non-force workspace pull so it cannot be discarded accidentally; --force still preserves it because Brain is no longer server-managed.
Explicitly download recent learning evidence when needed:
kodara agents learning pull ./kodara-workspace/acme/coachThis writes at most 100 recent conversations and 100 messages per conversation under local-only learning/. A normal agent pull never downloads, deletes, or publishes that tree. Use --conversations, --messages, or --force to lower bounds or intentionally replace a modified export.
Publish and restore
kodara agents publish ./kodara-workspace/acme/coach --message "Clarify identity"
kodara agents validate ./kodara-workspace/acme/coach
kodara agents diff ./kodara-workspace/acme/coach
kodara agents eval ./kodara-workspace/acme/coach --limit 20 --wait-seconds 900
kodara agents eval ./kodara-workspace/acme/coach --agent-version 4 --limit 20 --wait-seconds 900
kodara agents eval status ./kodara-workspace/acme/coach --wait-seconds 900
kodara agents eval resume ./kodara-workspace/acme/coach --wait-seconds 900
kodara agents versions ./kodara-workspace/acme/coach
kodara agents rollback 2 ./kodara-workspace/acme/coach --message "Restore tested behavior"diff compares versioned files with the exact pulled immutable base. eval runs up to 20 regression cases server-side against either the current unpublished local snapshot or a selected published version. It uses the editable coach-specific evals/evaluator.md, prints progress and bounded results, creates no chat data or agent version, and never publishes.
Before validate, diff, eval, or publish accepts a local workspace, the CLI checks the client-owned definition files. Paths must be safe lowercase Markdown paths with no normalized duplicates; index.md is required; the definition may contain at most 10,000 files, 64 KiB per file, and 10 MiB total; relative Markdown links must resolve; essential/index.md must be the canonical complete routing catalog; and the evaluator and eval cases must be valid. kodara agents validate performs this work without login or a Kodara API request. A pull is checked before it replaces local workspace files, so an invalid server response leaves the existing workspace untouched.
styles/** is server-owned review context and is excluded from this local definition check. On-demand brain/** files are local evidence and are excluded from definition validation, diff, eval, and publish. Local failures identify actionable client-owned files and retain at most 100 unique details; each message, path, or link target is limited to 500 Unicode code points, while the complete finding count is reported separately. Terminal controls and Unicode format or bidirectional controls are removed before diagnostics are displayed.
Eval polling waits at most 900 seconds by default; --wait-seconds accepts 1 through 14,400 seconds. As soon as a run is created, the CLI atomically saves its agent, run ID, and request identity in .kodara/eval-run.json. A timeout is non-terminal and never prints a score. Use kodara agents eval status [agent-directory] to poll that exact saved run without creating another snapshot, or kodara agents eval resume [agent-directory] to ask the server to resume the saved run before polling it. Both commands preserve the receipt and honor the same bounded wait.
The create response is authoritative once the server has persisted the eval run. If the initial queue acknowledgement is ambiguous, the same queued run receipt is returned instead of creating or failing a second run. An already accepted worker may claim it normally; otherwise the recurring stale-run sweeper re-enqueues it after 15 minutes.
The API remains authoritative. After immutable-base checks and before current styles are reconciled, an invalid submitted definition returns HTTP 400 with code agent_definition_validation_failed, the stable message Agent definition validation failed., the full issue count, and bounded code/path/target details. Fix those local files; do not reflexively re-pull. A genuine failure after the server overlays current styles remains the redacted HTTP 409 agent_style_reconciliation_failed response. Stale definition-version or style checkpoints also remain conflicts and require a fresh pull.
API failures keep the primary server error and expose only bounded, structured diagnostics. Definition-validation responses retain at most 100 unique details, with paths and link targets limited to 500 characters and the full count reported separately. The CLI's general API-error renderer displays at most 20 issues, with primary and issue messages limited to 500 Unicode code points and labels limited to 120. Truncation never splits a surrogate pair. The CLI renders only issue code, path, message, and target; it ignores malformed or unknown fields, removes terminal controls and Unicode format/bidirectional controls, preserves ordinary Unicode text, and never dumps arbitrary response JSON or customer content.
Every content-changing publish and rollback creates a new immutable server version immediately. push is a compatibility alias for publish. Publish uses the pulled base version, canonical snapshot hash, downloaded evidence cursor, and validated .kodara/improvement.json, so stale work is rejected instead of overwriting a newer publish. After successful inspection finds genuinely no evidence-backed definition change, do not manufacture an edit or run evals. Classify every pending feedback file, then use the supported no-change path, kodara agents publish <directory> without --message. The CLI requires that exact request to return created: false before advancing any local state. It omits stale .kodara/improvement.json from the request and removes it only after the created: false response and all local updates succeed. It records the reviewed evidence boundary without creating a version or changing publication time. Pull refuses to overwrite local edits unless --force is explicit. --force replaces the local Markdown map, including removing untracked Markdown absent from the server, but never bypasses symlink/path safety, manifest identity, or the workspace's pinned API origin.
To apply pending feedback, make the corresponding surgical definition edit and move its unchanged UUID file from feedback/pending/ to feedback/processed/. The CLI never sends feedback Markdown as runtime instructions. After inserting the immutable version, the server links eligible selected feedback through a scoped retryable write and reports only the IDs actually linked.
When feedback cannot be safely applied, keep its file unchanged and run kodara agents feedback review <agent-directory> <id> --note "...". The server records the note, moves the canonical file to feedback/unprocessable/, and creates no agent version. A transport failure after review or retry may follow a committed server write; use the printed force-pull recovery command instead of resending the mutation. Retry refuses to overwrite staged definition, feedback, or Coach Question changes. Every downloaded pending feedback file must be processed or reviewed as Not applied before its feedback cursor can advance. The item remains in future pulls and can later move from feedback/unprocessable/ to feedback/processed/ with the definition change that resolves it.
This review-note workflow ships in @kodara-agent/[email protected]. Tagging the merged release commit as cli-v0.8.5 triggers the existing Trusted Publishing workflow after the compatible API revision is serving traffic.
Coach Questions
Coach Questions are tuning questions the improvement loop authors for the coach. Each one presents a realistic client scenario with at least two drafted answers in different styles, and every option's meta names the tuning direction it represents:
kodara agents coach-questions add <agent-id> --question "..." [--context "..."] --angle "<angle>" --option "<label>|<meta>" --option "<label>|<meta>"A pull writes coach-questions/unanswered/<id>.md for questions still waiting on the coach and coach-questions/pending/<id>.md for answered, actionable ones. Both are evidence, never runtime instructions, and are excluded from definition hashes, diff, eval, and publish payloads. coach-questions/unanswered/** is read-only: any edit, move, or deletion is rejected.
To apply an answered question, make the corresponding surgical definition edit and move its unchanged file from coach-questions/pending/ to coach-questions/processed/. That is the only allowed transition; contents are immutable, exactly like feedback.
Readiness report
kodara agents report update ./kodara-workspace/acme/coach --file report.json
kodara agents report update --agent <agent-id> --file report.json --jsonreport update validates the JSON server-side against readinessReportSchema and overwrites the agent's public readiness report (agents.readiness_report), then prints the public report URL. Compose the JSON with the project-local .agents/skills/readiness-report/ skill after an eval run; the skill fixes the verdict-dependent score bands and the report structure.
Hourly improvement queue
The packaged $agent-improvement-loop skill claims durable queue requests in server priority order. Use one stable, non-secret worker ID for the lease lifecycle:
kodara --version
export KODARA_API_URL=https://api.kodara.com
kodara agents queue claim --limit 3 --lease-seconds 900 --worker-id codex:run-1 --json
kodara agents queue request <agent-id>
kodara agents queue pull <request-id> --dir ./kodara-queue --worker-id codex:run-1
kodara agents queue heartbeat <request-id> --worker-id codex:run-1 --lease-seconds 900
kodara agents queue fail <request-id> --worker-id codex:run-1 --outcome retryable --failure-code eval_failed
kodara agents queue fail <request-id> --worker-id codex:run-1 --outcome terminal --failure-code invalid_candidate
kodara agents publish <agent-directory> --request-id <request-id> --worker-id codex:run-1 --message "Apply verified improvement"Before every production action, run kodara --version, confirm the approved CLI version, and keep KODARA_API_URL=https://api.kodara.com set. Claim only current capacity, normally with kodara agents queue claim --limit 3, and process at most three concurrently because every claim starts its lease immediately. A limit of 100 is the API upper bound, not the operational batch size. After each batch, continue until a partial or empty response, or until all due requests reached terminal outcomes; there is no arbitrary pass cap. Use bounded per-request retries and accurate outcomes to avoid infinite loops. Skip not_ready requests. Pull without --force; each request uses its own workspace.
queue request creates a forced improvement request. queue pull validates the active owned lease and selects the right materialization automatically: manual_publish uses its immutable candidate, while forced_improvement, bootstrap, new_evidence, and maintenance use the current agent workspace. Heartbeat before lease expiry and around long reviews. New evidence is prompt work; the server's quiet maintenance policy is no more often than every five days. Styles are synchronized as server-managed one-way review context. Brain evidence is fetched on demand, and neither styles nor Brain files are edited or published by the CLI worker.
Validate and inspect the full diff. Run at most 20 evals only when the candidate changed, including a server style delta, and report scores on the 0–100 scale. Allow at most one correction pass. A transient failure uses --outcome retryable and records failed_retryable; a request that cannot succeed without new external input uses --outcome terminal and records failed_terminal. Failure codes are bounded categories—never customer, source, candidate, path, or error content.
A request-owned publish completes the leased request atomically; request and worker options must always be supplied together. If it returns server_completed_local_sync_failed, Server completion succeeded but local synchronization did not. Because the request is already complete, preserve the failed workspace and recover with kodara agents pull <agent-id> --dir <fresh-root> into a new empty root without --force. Never delete, overwrite, or reuse the failed root; do not fail or retry publication. Successful content and no-change publications remove the consumed .kodara/improvement.json; an API failure retains it.
Regression evals live at evals/<case-uuid>.md. Conversation cases preserve the source user-message UUID as the case UUID; essential-knowledge cases use a stable case UUID and record the exact essential/**/*.md path plus its lowercase SHA-256. They are versioned with the definition but are never readable by Agent V5 at runtime. Run kodara agents validate <agent-directory> before publishing; malformed evals report the exact file and contract failure without making an API request. Eval creation verifies essential receipts against the reconstructed candidate snapshot and rejects missing or stale source files before enqueueing.
Add general or message-linked feedback with:
kodara feedback add --agent <agent-id> --type <style|knowledge|issue> --message "..." [--message-id <id>]kodara logout revokes the server token before deleting the local credential. If revocation cannot be confirmed, the credential remains so logout can be retried.
After a rollback, pull the agent again to synchronize the restored files and new version into the local manifest.
