Skip to content

Commit 0797850

Browse files
authored
Release CLI 2.30.0 with SDK 0.30.0 (#150)
1 parent f58c2a5 commit 0797850

24 files changed

Lines changed: 534 additions & 484 deletions

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ jobs:
1313
- uses: oven-sh/setup-bun@v2
1414
with:
1515
bun-version: latest
16-
- run: bun install
16+
- run: bun install --frozen-lockfile
17+
- run: bun run check:versions
1718
- run: bun run typecheck
1819
- run: bun run test
1920
- run: bun run build

‎.github/workflows/release.yml‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
workflow_dispatch:
88
inputs:
99
version:
10-
description: "Version to build (without leading v), e.g. 0.1.0"
10+
description: "Must match package.json, e.g. 2.30.0 (SDK 0.30.0)"
1111
required: true
1212

1313
permissions:
@@ -25,21 +25,27 @@ jobs:
2525

2626
- name: Resolve version
2727
id: version
28+
env:
29+
INPUT_VERSION: ${{ inputs.version }}
2830
run: |
2931
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
30-
echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
32+
echo "version=$INPUT_VERSION" >> "$GITHUB_OUTPUT"
3133
else
3234
echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
3335
fi
3436
35-
- name: Stamp version into the binary
36-
# package.json is the single source of truth — src/lib/constants.ts reads
37-
# pkg.version, which tsup/bun inline at build time. This MUST match the tag
38-
# because the Homebrew `test do` block asserts `agent --version` == version.
39-
run: npm version "${{ steps.version.outputs.version }}" --no-git-tag-version --allow-same-version
40-
4137
- name: Install dependencies
42-
run: bun install
38+
run: bun install --frozen-lockfile
39+
40+
- name: Check CLI, SDK, and release versions
41+
env:
42+
RELEASE_VERSION: ${{ steps.version.outputs.version }}
43+
run: bun run check:versions "$RELEASE_VERSION"
44+
45+
- name: Validate CLI
46+
run: |
47+
bun run typecheck
48+
bun run test
4349
4450
- name: Build platform binaries
4551
run: |

‎README.md‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,22 @@ only inside their automation — dashboard starts, cron runs — do not
193193
match a repo filter, so `"repo": "any"` is the way to see those alongside the
194194
rest.
195195

196+
## SDK 0.30 configuration
197+
198+
Session configs select one native block. Put the first message inside it:
199+
200+
```yaml
201+
session:
202+
claude_code:
203+
prompt: Fix the failing tests.
204+
# Or: codex: {model: gpt-6-astra, prompt: Fix the failing tests.}
205+
```
206+
207+
The old `harness`, `instructions`, and top-level `prompt` fields are no longer
208+
accepted. `--system` now reports an error; put task instructions in the prompt
209+
or a repository `AGENTS.md` file. Environment build scripts use
210+
`hooks.build_base` and `hooks.after_checkout`; the old `image` block is removed.
211+
196212
## Develop
197213

198214
```sh
@@ -251,7 +267,7 @@ tarballs, and regenerates the formula in
251267
[`ellipsis-dev/homebrew-cli`](https://github.com/ellipsis-dev/homebrew-cli).
252268

253269
```sh
254-
git tag v0.1.0 && git push origin v0.1.0
270+
git tag v2.30.0 && git push origin v2.30.0
255271
```
256272

257273
The cross-repo push to the tap uses a write-scoped **deploy key**: the public

‎bun.lock‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎docs/RELEASING.md‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,35 @@
22

33
The CLI ships only as a Homebrew formula from the `ellipsis-dev/homebrew-cli`
44
tap. It is never published to npm: `package.json` is `private`, has no `bin`,
5-
and there is no `publishConfig`. The single `npm` call in the release workflow
6-
(`npm version --no-git-tag-version`) is just a local tool to rewrite the
7-
version field, not a registry publish.
5+
and there is no `publishConfig`.
6+
7+
CLI **2.X.Y** always uses SDK **0.X.Y**. For example, CLI **2.30.0** uses
8+
`@ellipsis-dev/sdk` **0.30.0**. Keep the CLI version and exact SDK dependency
9+
in `package.json` up to date together, and commit the regenerated `bun.lock`.
10+
Version ranges such as `^0.30.0` are not allowed. CLI-only changes also need
11+
a matching SDK release when advancing the CLI version.
812

913
Publishing is fully automated by `.github/workflows/release.yml`, triggered by
10-
pushing a `vX.Y.Z` git tag (there is also a `workflow_dispatch` fallback that
14+
pushing a `v2.X.Y` git tag (there is also a `workflow_dispatch` fallback that
1115
takes a version input in the Actions UI). On a tag push it:
1216

13-
1. Stamps the version into `package.json` (the single source of truth:
14-
`src/lib/constants.ts` reads `pkg.version`, which bun inlines into the
15-
binary, so `agent --version` never drifts).
17+
1. Installs dependencies with the frozen lockfile, checks that the release
18+
version matches `package.json` and the installed SDK follows the version
19+
rule, then runs typechecking and tests. Mismatches stop the release.
1620
2. Cross-compiles four binaries (`darwin-arm64`, `darwin-x64`, `linux-x64`,
1721
`linux-arm64`) with `bun build --compile`, tars each, and computes SHA-256
1822
checksums.
1923
3. Creates the GitHub release with the tarballs and `checksums.txt`.
2024
4. Regenerates `Formula/agent.rb` in the tap repo from the template and pushes
2125
it, so `brew install ellipsis-dev/cli/agent` picks up the new version.
2226

23-
The only manual steps (Hunter cuts releases) are: ensure CI is green, then
24-
create and push the `vX.Y.Z` tag on the main commit to release. No
25-
`package.json` bump commit is needed — the workflow's `npm version` step
26-
stamps the tag's version into `package.json` before building, so the field on
27-
main goes stale by design (releases since v1.4.0 tag main directly).
27+
The manual steps (Hunter cuts releases) are: commit the version updates and
28+
SDK migration, ensure CI is green, then create and push the matching `v2.X.Y`
29+
tag on the main commit to release. For CLI 2.30.0, use `v2.30.0`. The workflow
30+
validates the committed version; it does not rewrite it.
2831

29-
Because the field is stale, local builds don't read their version from it:
30-
`bun run compile` (scripts/compile.sh) stamps the binary from
31-
`git describe --tags`, so `./agent --version` reports exactly what it was
32-
built from — `1.6.0` on a clean tagged checkout, `1.6.0-2-g08ea24d-dirty` two
33-
commits past the tag with uncommitted changes. Only `tsx` dev runs fall back
34-
to the stale `package.json` field.
32+
`package.json` is the version source for development, local compiled binaries,
33+
and releases. `bun run compile` checks the CLI/SDK pair before building;
34+
`./agent --version` reports `2.30.0` for this version, including local builds.
35+
Run `bun run check:versions` to check the pair without building, or
36+
`bun run check:versions 2.30.0` to also validate an intended release version.

‎package.json‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ellipsis/cli",
3-
"version": "1.3.0",
3+
"version": "2.30.0",
44
"description": "Ellipsis agent CLI: drive the Ellipsis cloud from your terminal",
55
"license": "MIT",
66
"type": "module",
@@ -13,14 +13,15 @@
1313
"scripts": {
1414
"dev": "tsx src/cli.tsx",
1515
"build": "tsup",
16+
"check:versions": "bun scripts/check-versions.mjs",
1617
"typecheck": "tsc --noEmit",
1718
"compile": "./scripts/compile.sh",
1819
"start": "node dist/cli.js",
1920
"test": "vitest run",
2021
"test:watch": "vitest"
2122
},
2223
"dependencies": {
23-
"@ellipsis-dev/sdk": "^0.28.0",
24+
"@ellipsis-dev/sdk": "0.30.0",
2425
"chalk": "^5.6.2",
2526
"cli-table3": "^0.6.5",
2627
"commander": "^12.1.0",

‎scripts/check-versions.mjs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { readFileSync } from 'node:fs'
2+
3+
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
4+
const sdk = JSON.parse(readFileSync(new URL('../node_modules/@ellipsis-dev/sdk/package.json', import.meta.url), 'utf8'))
5+
const match = /^2\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(pkg.version)
6+
if (!match) throw new Error('CLI version must be 2.X.Y')
7+
8+
const expectedSdk = `0.${match[1]}.${match[2]}`
9+
if (pkg.dependencies['@ellipsis-dev/sdk'] !== expectedSdk || sdk.version !== expectedSdk) {
10+
throw new Error(`CLI ${pkg.version} requires SDK ${expectedSdk}, pinned exactly and installed`)
11+
}
12+
13+
const releaseVersion = process.argv[2]
14+
if (releaseVersion !== undefined && releaseVersion !== pkg.version) {
15+
throw new Error(`Release version ${releaseVersion} must match package.json version ${pkg.version}`)
16+
}
17+
18+
console.log(`CLI ${pkg.version} / SDK ${sdk.version}`)

‎scripts/compile.sh‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
#!/usr/bin/env bash
2-
# Local/dev compile. Stamps the binary's version from `git describe` so
3-
# `./agent --version` reports exactly what it was built from, e.g.
4-
# "1.6.0-2-g08ea24d-dirty" = 2 commits past v1.6.0 at 08ea24d with
5-
# uncommitted changes (a tagged, clean checkout reads the bare "1.6.0").
6-
# package.json's version field is NOT the truth for local builds: releases
7-
# stopped bumping it (the release workflow rewrites it at tag time and
8-
# builds directly, without this script), so it goes stale on main by design.
2+
# Local builds use the same package.json version as release builds.
93
set -euo pipefail
104
cd "$(dirname "$0")/.."
11-
version="$(git describe --tags --always --dirty | sed 's/^v//')"
12-
exec bun build src/cli.tsx --compile --outfile agent \
13-
--define "BUILD_GIT_VERSION=\"${version}\""
5+
bun run check:versions
6+
exec bun build src/cli.tsx --compile --outfile agent

‎skills/ellipsis/SKILL.md‎

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ and `web`:
9898
```yaml
9999
ellipsis:
100100
version: v1
101+
kind: agent
101102
name: Recent work summary
102103
description: Summarizes the week's merged work across api and web
103104

@@ -106,14 +107,13 @@ trigger:
106107
schedule: "0 9 * * 1"
107108

108109
session:
109-
harness:
110-
type: claude_code
110+
claude_code:
111111
model: claude-haiku-4-5-20251001
112-
instructions: |
113-
Summarize the pull requests merged in api and web over the last 7
114-
days. Group them by theme, lead with user-facing changes, and return
115-
the summary as your answer. Ground every line in a real PR. Never
116-
invent activity.
112+
prompt: |
113+
Summarize the pull requests merged in api and web over the last 7
114+
days. Group them by theme, lead with user-facing changes, and return
115+
the summary as your answer. Ground every line in a real PR. Never
116+
invent activity.
117117
118118
environment:
119119
repositories:
@@ -183,6 +183,7 @@ Actions and filters live inside the surface block:
183183
```yaml
184184
ellipsis:
185185
version: v1
186+
kind: agent
186187
name: Migration reviewer
187188
description: Flags unsafe database migrations on pull requests
188189
@@ -195,14 +196,13 @@ trigger:
195196
paths: ["migrations/**"]
196197
197198
session:
198-
harness:
199-
type: claude_code
200-
instructions: |
201-
Review the database migrations in this pull request for production
202-
safety: locking that blocks writes on large tables, missing backfills
203-
for new non-null columns, and rollout ordering that breaks if the
204-
migration and the code deploy out of order. Comment on the pull
205-
request with what you find.
199+
claude_code:
200+
prompt: |
201+
Review the database migrations in this pull request for production
202+
safety: locking that blocks writes on large tables, missing backfills
203+
for new non-null columns, and rollout ordering that breaks if the
204+
migration and the code deploy out of order. Comment on the pull
205+
request with what you find.
206206
207207
environment:
208208
repositories:
@@ -487,7 +487,7 @@ Top-level keys, all optional except `ellipsis`:
487487

488488
| Key | Purpose |
489489
| --- | --- |
490-
| `ellipsis` | `version: v1`, `name`, `description`, `metadata`, and the `enabled`, `interactive`, `ide` flags. Its presence marks the file as a config. |
490+
| `ellipsis` | `kind: agent`, `version: v1`, `name`, `description`, `metadata`, and `enabled`. Its presence marks the file as a config. |
491491
| `trigger` | One trigger, or omit for a manual-only agent. |
492492
| `input` | A JSON Schema for the payload `agent automation run` passes, and the message template it renders into. |
493493
| `session` | What every session runs on; the keys below. The same keys, flattened, are the body of `agent` / `POST /v1/sessions`. |
@@ -496,9 +496,8 @@ Under `session`:
496496

497497
| Key | Purpose |
498498
| --- | --- |
499-
| `harness` | Required: `type: claude_code` or `type: codex`, plus that harness's native `model` and `effort` options. Claude Code also accepts `fallback_model`, `max_turns`, and `settings`. |
500-
| `instructions` | Text or repository file references appended to the harness prompt. |
501-
| `environment` | A saved environment by name, or an inline block: `repositories`, `variables`, `ports`, `compute`, `image`, `hooks`, `mcp_servers`. |
499+
| `claude_code` or `codex` | Exactly one native block, with `prompt`, `model`, and `effort`. Claude Code also accepts `fallback_model`, `max_turns`, and `settings`. |
500+
| `environment` | A saved environment by name, or an inline block: `repositories`, `variables`, `compute`, `hooks`, `mcp_servers`. |
502501
| `permissions` | What it may do: `github` scopes its GitHub token, `ellipsis` its API token. |
503502
| `skills` | Claude Code skills beyond what the cloned repositories provide. |
504503
| `output` | A JSON Schema contract, so downstream automation gets typed data. |
@@ -507,10 +506,10 @@ Under `session`:
507506
The schema is strict, so an unknown or misplaced key fails validation rather
508507
than being silently dropped. Points that decide whether a config works:
509508

510-
- `session.instructions` takes inline text, a `{file: path}` reference to a repository
511-
file, or an ordered list of both, joined at session start. It is appended to
512-
the selected harness's default prompt. 64 KiB per file.
513-
- `session.harness.model` selects a model for the chosen harness. Claude Code
509+
- `session.claude_code.prompt` or `session.codex.prompt` supplies the first user
510+
message verbatim. Put repository guidance in `AGENTS.md`. The former `harness`
511+
and `instructions` keys are rejected.
512+
- `session.claude_code.model` or `session.codex.model` selects a model. Claude Code
514513
inherits the organization default when omitted. `agent model list` reports
515514
the available ids and the harness certified for each. Digest and
516515
summary jobs run well on `claude-haiku-4-5-20251001`; judgment jobs earn the
@@ -525,8 +524,8 @@ than being silently dropped. Points that decide whether a config works:
525524
your JSON Schema, so downstream automation gets typed data instead of prose to
526525
parse. Schema failures exit loudly as `tool_call_failed`. It does not go
527526
together with a mention trigger.
528-
- `ellipsis.interactive: false` opts sessions out of messages entirely, for
529-
fire-and-forget automations. `ellipsis.ide: false` locks the sandbox shut.
527+
- Raw session starts accept `lifecycle.interactive: false` to run once. The
528+
returned `lifecycle.prompting` describes whether direct messages are accepted.
530529

531530
Validation surfaces on push to the default branch, on config pull requests, in
532531
the dashboard editor, and at session start for checks that need the session's

0 commit comments

Comments
 (0)