Skip to main content
The luno CLI is the primary way to build, deploy, and operate Luno OS projects. You’ll use it to scaffold a project, ship it to the platform, and then invoke and inspect what’s running there. Luno OS is deploy-first: edit your codebase, deploy, then run and inspect against your cloud project on the platform. Command shape — resource collections use plural names (matching the HTTP API): luno <collection> <verb> [<slug>]. Examples: luno workflows run greeting, luno triggers disable inbound-email-poll, luno integrations get github.
Run luno --help, or luno <command> --help, for the authoritative list of flags on any command.

Install

Install the luno command globally. Requires Node.js ^22.18.0 || >=24.0.0 (Node 23 is not supported).
To refresh the CLI and every project @meetluno/* dependency to npm latest:
luno deploy / build / lint / typecheck require those packages to be current and will tell you to run luno update when they are not. A CLI installed from the dev dist-tag (version 0.1.N-dev) stays on its channel: it updates itself and the project packages to dev, and checks them against dev. A package with no dev release falls back to latest. Set LUNO_CLI_DIST_TAG to override the channel.

Authentication

Log in once and the token is reused for every command. Switching organizations does not require logging in again.
Your token is stored in your operating system’s secure credential store (Keychain, Credential Manager, or secret service).
auth login applies to local machines only. Hosted sessions — the in-app Luno Builder and MCP workspaces — have credentials injected already and cannot complete the browser device flow.

Project targeting

Most runtime commands (workflows, agents, triggers, credentials, connect, health) run against your deployed cloud project on the platform. There is no local CLI API server — every HTTP command uses the configured platform URL. Which platform project you deploy to is stored in the project’s luno.config.ts as optional project and organization slugs — set by luno projects link or luno init --project. Global CLI config lives in ~/.luno.
Defaults are https://os.meetluno.ai (web) and https://api.meetluno.ai (platform). Switch environments with luno auth login --web-url <url> and optional --platform-url <url> — both persist in ~/.luno. Local dashboard: --web-url http://localhost:3000 (platform URL derives automatically when known). For a one-off override that doesn’t change your config, pass --project:

Scaffold a project

Create a project from the default template, then deploy it.
Or seed the link at init time:
luno init creates luno.config.ts, a committed tsconfig.json (extends @meetluno/cli/tsconfig.json), a src/ directory with an example agent, and an AGENTS.md guide so your coding agent knows how Luno OS works. Lint, typecheck, and test tooling (oxlint, TypeScript, vitest, @types/node) ship inside @meetluno/cli — projects do not declare them or ship .oxlintrc.json / vitest.config.ts. AGENTS.md is versioned to your CLI — commands run inside the project re-sync it automatically after a CLI update. For deeper context, use luno docs search and luno docs query.
package.json scripts (pnpm lint, pnpm typecheck, pnpm test) call these commands. Config files stay in the CLI bundle — nothing is written into your project when you run them.

Deploy

For managed-Git projects, the CLI compares the pinned main and draft commits locally, analyzes filtered impact, then acquires a platform deploy lease and ships the candidate artifact. Expanded or unknown filtered impact requires confirmation or --accept-impact. For snapshot-only projects, deploy runs lint and typecheck, builds, uploads the dist/ artifact, and activates it. Link the directory first (or pass --project for a one-off deploy). After deploy, runtime commands target your linked cloud project. You do not need to run luno lint, luno typecheck, or luno build first — deploy runs the required checks and build.
Pass --filter <entry> with workflow/agent keys (workflows/…, agents/…). Managed filtered deploys analyze shared dependencies locally and may require confirmation (--accept-impact in non-TTY). Snapshot filtered deploys merge a targeted local build into the active artifact. For a project nested in a package-manager monorepo, --build-from-workspace builds against the current checkout so workspace:, link:, and local file: dependencies resolve. This escape hatch only supports full deploys and local package sources are not captured in Luno OS’s managed source, so the artifact is not reproducible from that source alone. Prefer published dependency versions when possible.

Pull

luno pull fetches the shared unpublished draft (luno/draft) and merges it into your local checkout, then installs dependencies. Pass --published to fetch the exact commit on the active deploy instead. Managed Git state lives in .luno/git, so your configured remotes are left unchanged.
pull targets the linked project in luno.config.ts when --project is omitted. Git-less directories are bootstrapped into the managed sidecar. If the merge conflicts, Git leaves conflict markers in place — resolve them, git add, and git commit (or git merge --abort). Legacy snapshot-only artifacts still use the bulk source download when --published is set.

Invoke and inspect

Run your workflows and agents, fire triggers, and audit run history against your deployed cloud project.

Workflows

See workflow forms for when to use forms, field presentation, and dashboard publish. --wait is bounded and defaults to 60 seconds for workflows. Set a different duration with --timeout <seconds>. If the timeout elapses, the command returns the latest running state with exit code 0; continue with workflows runs get <workflow> <run-id> --wait. A failed or canceled run exits with code 1.

Agents

Agent waits default to 120 seconds. A wait timeout means the session is still running and exits with code 0; continue with agents sessions get <agent> <session-id> --wait. Failed and canceled sessions exit with code 1.

Actions

Find apps with integrations search (the apps your organization can connect: official and custom) and inspect one with integrations get. There is no hosted action catalog: an official app’s actions (github, gmail, …) ship as TypeScript in its curated @meetluno/integration-* package and run from your project’s workflows and agents, so integrations actions list <official-app> explains where they live and integrations actions get / integrations execute do not apply to official apps. Custom MCP apps support live integrations actions list and integrations execute against the remote server.
Credential resolution matches the runtime: it uses the project default, then the org default. Project credentials only resolve when you target a project with the global --project <slug> flag (or run inside a linked project); without it, only org credentials resolve. User credentials are never a default — reach one explicitly with --credential <slug>. If the app is not connected, integrations execute exits with a hint to run luno connect <app>. Executing has side effects, so a user credential only runs for its owner and an org or project credential needs project:run in the project (without --project, org-wide: owner or admin); otherwise it answers 403 — see who can execute a tool.
Pass --credential <slug> to pin a specific instance when a scope has more than one — the slug is the one you set with luno credentials create <key> --slug <slug> and can see with luno credentials list. It’s also the only way to use a user-scoped credential.

Triggers

Machine-oriented commands print JSON on stdout and human hints on stderr (so | jq stays clean).

History (cloud)

Integrations and secrets

Connect third-party accounts and manage the credentials your agents and workflows use.
connect requires an app slug (see luno integrations list for connectable slugs) and chooses scope in the web flow — scope and project pinning are set on credentials create, not connect. In headless or hosted sessions (coding agents, the in-app Luno Builder, CI), always pass --print-url and hand the printed URL to the user — those environments cannot open a browser. connect slack opens the three-way Slack chooser; --kind luno|personal|custom opens one dialog directly (luno = the Luno OS Slack App — catalog slug slackbot, personal = Personal Slack Account, custom = Custom Slack App wizard), and --wait (Luno OS Slack App only) polls until the gateway workspace registers. For credential values, --set key=value takes a literal, and --set key=@env:VAR reads from your shell (falling back to the project .env). credentials update --scope moves one existing instance (exactly one of org, user, or project); credentials duplicate fans out copies like create. See connect and manage apps. integrations create’s --field syntax is key, key:secret, key:optional, or key:secret:optional (repeatable). For manual custom apps, --name and at least one --field are required; --description defaults to --name when omitted. Optional --logo <url> sets a public image URL for the Integrations catalog (same as Logo URL in the web create dialog). Example: luno integrations create --name Acme --description "Internal Acme API" --logo https://example.com/acme-logo.png --field apiKey:secret. With --mcp, --openapi, or --graphql, auth and credential fields are auto-detected from the URL (this registers a connectable org catalog app, not only local scaffolding); use --preview to print the assembled request without creating, and --name, --slug, --description, --logo, --field, or --auth (MCP only) to override detected values. After create, connect with luno connect <slug>, then author actions with defineIntegration / integrations sync — see custom apps and MCP. LLM provider API keys (BYOK for model inference) are not app credentials — connect those with luno managed-services instead.

Managed services (cloud)

Bring your own LLM provider API keys for organization-wide inference. See Managed services.

Channels

Bind agents to external channels (like Slack) so people can talk to them where they already work. See external channels.
channels bind / update-binding use --replies mentions|mentions-followups (same choices as the External Channels UI) and --listen mentions|all (Respond to: only @mentions, or every message in the channel). Bind defaults to mentions-followups and mentions. On a direct-messages binding, --dm-agents sets the agents people can switch to in DMs ("" clears); see several agents in one workspace.

Organization and access

Manage members and platform API keys for your active organization. Most of these are org-admin operations.

Docs

Read the Luno OS documentation from the CLI. These commands need no authentication, organization, project, or config — they work the moment the CLI is installed, for you and your coding agent alike.
See docs for agents for how query works (stateless calls, output caps) and more examples.

Feedback

Coding agents can report build friction directly to the Luno OS team. Use this after a build loop when the agent encountered unclear documentation, confusing errors, unexpected framework constraints, missing capabilities, or non-obvious workarounds. feedback create requires authentication and an active organization. The platform attaches the signed-in user’s identity and organization automatically; the CLI also includes its version and the linked project slug when available.
The message is freeform; the recap and numbered feedback above are a suggested structure. Write it for a Luno OS team member with zero context on the session: plain language first, technical detail (paths, commands, error text) second, one numbered item per issue. Run luno feedback create --help for the full writing guide. Do not include secrets, tokens, credentials, private source dumps, proprietary code, or personal data from project files or user inputs. Success prints { "ok": true }. See CLI for agents for when coding agents should use this command.

Global options

--project applies to platform-targeting commands; docs commands ignore organization/project scope. --version and --help work on every command.

Using the CLI with AI agents

Luno OS is built for coding agents. Learn how agents use the CLI, the docs commands, and headless mode to build and operate your project.