Skip to content

feat(cli): set up pi, Codex, DeepSeek Harness and Cursor with lightning code - #194

Open
rusenask wants to merge 2 commits into
mainfrom
feat/lightning-code-more-tools
Open

rusenask wants to merge 2 commits into
mainfrom
feat/lightning-code-more-tools

Conversation

@rusenask

@rusenask rusenask commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

What

lightning code setup | status | remove now handle pi, Codex, DeepSeek Harness (dsh) and Cursor, as well as OpenCode (#192). Each sets the tool up to use code.lightning.ai, with a key that bills the chosen org. The org picker, the Pro/Teams/Enterprise check, the model list from /v1/models and the DeepSeek V4.1 Flash default work the same for every tool.

$ lightning code setup pi --org my-org
pi now uses code.lightning.ai, billed to My Org [my-org].
  Provider: lightning in ~/.pi/agent/models.json
  Key file: ~/.pi/agent/auth.json
  API key:  pi on my-laptop 2026-10-09
  Default:  lightning/lightning-ai/deepseek-v4.1-flash

Start coding with `pi`, and switch models with /model.

$ lightning code setup codex --org my-org
Codex now uses code.lightning.ai, billed to My Org [my-org].
  Profile: ~/.codex/lightning.config.toml (holds the API key)
  API key: codex on my-laptop 2026-10-09
  Default: lightning-ai/deepseek-v4.1-flash

Start coding with `codex --profile lightning`, and switch models with -m <model id>.

$ lightning code setup dsh --org my-org
DeepSeek Harness now uses code.lightning.ai, billed to My Org [my-org].
  Provider: lightning in the web and headless profiles under ~/.dsh/profiles
  Key file: ~/.dsh/.credentials.yaml (LIGHTNING_CODE_API_KEY)
  API key:  dsh on my-laptop 2026-10-09
  Default:  lightning/lightning-ai/deepseek-v4.1-flash

$ lightning code setup cursor --org my-org
Cursor now uses code.lightning.ai, billed to My Org [my-org].
  API key: cursor on my-laptop 2026-10-09

Finish in Cursor (needs a paid Cursor plan):
  1. Open Cursor Settings (Cmd+Shift+J on macOS, Ctrl+Shift+J elsewhere) and go to Models.
  2. Under API Keys, paste this into OpenAI API Key and press Enter:
       sk-lit-…
  3. Turn on "Use OpenAI API Key".
  4. Turn on "Override OpenAI Base URL" and enter:
       https://code.lightning.ai/v1
  5. At the top of Models, add these model names and make sure they're switched on:
       lightning-ai/glm-5.3
       lightning-ai/glm-5.3-flash
       lightning-ai/deepseek-v4.1-flash
  6. Open a new chat and pick lightning-ai/deepseek-v4.1-flash.
  ...

$ lightning code status          # every tool, with org, key and default model
$ lightning code remove codex    # undo the setup and revoke the key
$ lightning code setup pi --org my-org --dry-run   # diff, with keys masked

How each tool is configured

Tool Provider Key Default model
OpenCode provider.lightning spliced into ~/.config/opencode/opencode.json[c] ~/.local/share/opencode/auth.json model, only if unset
pi providers.lightning spliced into ~/.pi/agent/models.json pi's auth.json (api_key) settings.json defaultProvider/defaultModel, only if unset
Codex its own profile ~/.codex/lightning.config.toml (0600), used with codex --profile lightning; config.toml is never touched experimental_bearer_token in the profile the profile's model (a /model choice in Codex is kept on re-runs)
dsh llm-pi-ai entry in the web and headless profile patches; only that entry and agent-default-model are rewritten, so other entries keep their text and comments ~/.dsh/.credentials.yaml as LIGHTNING_CODE_API_KEY agent-default-model, only if the profile has none
Cursor printed steps; Cursor keeps these settings in a database it holds open, with the key encrypted through the OS keychain printed once —

Notes on the choices:

  • Codex only speaks the Responses API to custom providers. Before building on it, I checked that /v1/responses streams correct Codex-shaped requests (store: false, tools) for all three models.
  • dsh's key name. dsh would derive LIGHTNING_API_KEY from the provider id, but Studios already set that variable to the platform key, and the environment wins over dsh's credential file. That's why it's LIGHTNING_CODE_API_KEY.
  • Cursor isn't configured automatically. Its cursor-agent CLI can't use custom endpoints, and while the base-URL override is on, Cursor's own GPT/Auto models stop working. The printed steps say both.
  • pi rejects its whole models.json if any entry is invalid, so only fields its schema accepts are written.

Changes to the existing OpenCode setup

  • enabled_providers: if the user's config has this allowlist, setup now adds lightning to it and remove takes it out again. Before, setup only warned, and OpenCode quietly ignored the provider. Testing on a real config found this.
  • Cleanup: remove deletes files setup created once nothing else is left in them. A file with the user's comments is kept.
  • Credential files: files that hold keys are never backed up, so no second copy of anyone's keys is left behind.
  • Dry runs: --dry-run masks sk-lit- keys. Shared credential files (auth.json, .credentials.yaml) get a one-line summary instead of a diff, so other providers' keys are never printed.

Structure

  • tool.py: the Tool interface:

    • read → ToolState
    • plan_setup / plan_remove → Plan, a list of FileChange objects with the before and after text
    • summary, instructions, warnings

    It also holds the shared apply step, which backs up files and writes them atomically, and the default-model rule.

  • opencode.py, pi.py, codex.py, dsh.py, cursor.py: one module per tool. registry.py lists them.

  • files.py: file helpers, plus ~/.lightning/code-tools.json (0600, IDs only, no keys). It records the org and key for tools with no place for metadata; OpenCode keeps using auth.json metadata.

  • utils/jsonc.py: gains array append_item / remove_item and has_comments.

Testing

On macOS (my Mac, default paths, real configs):

  • OpenCode 1.18.34, with an existing 260-line opencode.jsonc with six providers and an enabled_providers list:
    • opencode run -m lightning/deepseek-v4.1-flash answered pong.
    • remove restored opencode.jsonc byte-for-byte, and auth.json had the same entries.
  • Codex 0.160.0, with an existing config.toml:
    • codex exec -p lightning answered pong via deepseek-v4.1-flash.
    • With -m lightning-ai/glm-5.3 it ran wc -l through the shell tool and answered 3.
    • config.toml was untouched by our code, and remove deleted the profile.
  • pi 1.1.0:
    • pi --list-models lightning showed all three models with the right context, output and image support.
    • It answered pong with the default model and read a blue test image (Blue).
    • GLM-5.3 used the bash tool (4).
    • remove deleted the files setup created, and auth.json was restored.
  • dsh 0.2.0-rc.2, first run with no ~/.dsh:
    • dsh --profile headless answered pong and used its shell tool (5).
    • dsh kept our patch entries when it set up the profile.
    • remove left the empty [] patch dsh expects.
  • Cursor 3.22:
    • The steps print with the key and model ids.
    • The key and base URL return a streamed read_file tool call for a Cursor-style /v1/chat/completions request.
    • remove revokes the key and prints how to switch the override off.

On Linux, end to end in a Lightning Studio (lightningai-engineering/skills), with this branch's wheel, OpenCode 1.18.35, pi 1.1.0, Codex 0.162.0, dsh 0.2.0-rc.2 and Node 22.20:

  • All four file-based tools were set up at once, and status listed each with its org, key and default.
  • Prompts with the default model (deepseek-v4.1-flash): OpenCode, pi, Codex and dsh all answered pong.
  • Image input (Blue): OpenCode and pi.
  • Tool use with GLM-5.3 counting lines (6): OpenCode, pi, Codex and dsh.
  • remove for each revoked its key, and none of the test keys are left.

Locally:

  • 65 tests in tests/cli/code cover:
    • each tool's files and the user's content kept intact
    • byte-for-byte restore on remove
    • the default-model rules
    • foreign setups needing --force
    • key files at 0600 with no backups
    • masked dry runs that print no other credentials
    • dsh !!js tags kept
    • the Free plan stopping every tool
    • status covering every tool
    • the example files matching what setup writes
  • utils/test_jsonc.py, the entry point and non-interactive tests also pass.
  • ruff and mypy are clean.

Known limitation

Codex with images fails on the server. Codex sends no max_output_tokens, and on /v1/responses the server's default seems to be computed before the image tokens are counted. Prompt plus completion then lands 181 tokens over the 262,144 context (6,469 + 255,856), and the engine returns 400. Text and tool use through Codex work. The fix belongs in the worker: when a Responses request has no max_output_tokens, set it to the model's max_completion_tokens. The tutorial says Codex image input isn't supported yet.

🤖 Generated with Claude Code

…ing code`

`lightning code setup|status|remove` now take pi, codex, dsh and cursor as
well as opencode. Each tool plans its file changes as text, which the
commands show for --dry-run and apply, so a tool only decides what its files
should say:

- pi: provider spliced into ~/.pi/agent/models.json, key in pi's auth.json,
  default model in settings.json.
- Codex: its own profile, ~/.codex/lightning.config.toml (0600), used with
  `codex --profile lightning`; config.toml is never touched.
- dsh: provider and default model in the web and headless profile patches,
  only those entries rewritten; key in ~/.dsh/.credentials.yaml as
  LIGHTNING_CODE_API_KEY (not LIGHTNING_API_KEY, which Studios set).
- Cursor: can't be configured from outside, so a key is created and the steps
  to add it in Cursor Settings are printed.

Also: OpenCode adds `lightning` to an enabled_providers allowlist, remove
deletes files setup created, files holding keys are never backed up, and
--dry-run masks keys and summarises shared credential files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants