Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"test:watch": "vitest"
},
"dependencies": {
"@ellipsis-dev/sdk": "^0.16.0",
"@ellipsis-dev/sdk": "^0.17.0",
"chalk": "^5.6.2",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
Expand Down
2 changes: 2 additions & 0 deletions src/cli.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { registerMe } from './commands/me'
import { registerSession } from './commands/session'
import { registerReview } from './commands/review'
import { registerConfig } from './commands/config'
import { registerEnvironment } from './commands/environment'
import { registerVariable } from './commands/variable'
import { registerFile } from './commands/file'
import { registerTemplate } from './commands/template'
Expand Down Expand Up @@ -42,6 +43,7 @@ registerMe(program)
registerSession(program)
registerReview(program)
registerConfig(program)
registerEnvironment(program)
registerVariable(program)
registerFile(program)
registerTemplate(program)
Expand Down
58 changes: 35 additions & 23 deletions src/commands/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Command } from 'commander'
import { parse as parseYaml } from 'yaml'
import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
import { basename, dirname, extname } from 'node:path'
import { api } from '../lib/api'
Expand Down Expand Up @@ -117,21 +118,36 @@ export function registerConfig(program: Command): void {
json?: boolean
}) => {
await runAction(async () => {
// The server enforces "exactly one of config / template_id";
// pre-check locally for a clearer error than a bare 400.
if (!opts.file === !opts.template) {
throw new Error('provide exactly one of --file <path> or --template <slug>')
}
if (opts.path && !opts.repo) {
throw new Error('--path names a location in a repository, so it needs --repo <name>')
}
const req: CreateAgentConfigRequest = {
repository: opts.repo,
path: opts.path,
const client = api()
// Templates left the create request (#6394): resolve the slug to its
// YAML and create from that config.
const config = opts.file
? (readConfigFile(opts.file) as AgentConfig)
: (parseYaml((await client.agents.templates.get(opts.template!)).yaml) as AgentConfig)
const req: CreateAgentConfigRequest = { config }
const created = await client.agents.configs.create(req)
// With --repo the agent is then moved into the repository by pull
// request (create + link, the two-step the API exposes today).
if (opts.repo) {
const linked = await client.agents.configs.link(created.config.id, {
repository: opts.repo,
path: opts.path,
})
if (opts.json) {
printJson(linked)
return
}
console.log(`✓ created "${configName(linked.config)}" (${linked.config.id}) — live now`)
console.log(`✓ opened a pull request adding the agent config (${linked.path})`)
console.log(linked.pull_request_url)
return
}
if (opts.file) req.config = readConfigFile(opts.file) as AgentConfig
if (opts.template) req.template_id = opts.template
const created = await api().agents.configs.create(req)
if (opts.json) {
printJson(created)
return
Expand Down Expand Up @@ -415,13 +431,17 @@ export function registerConfig(program: Command): void {
return
}
await runAction(async () => {
printCreated(
await api().agents.configs.create({
template_id: opts.template,
repository: opts.repo!,
path: opts.path,
}),
)
const client = api()
const template = await client.agents.templates.get(opts.template!)
const created = await client.agents.configs.create({
config: parseYaml(template.yaml) as AgentConfig,
})
const linked = await client.agents.configs.link(created.config.id, {
repository: opts.repo!,
path: opts.path,
})
console.log(`✓ opened a pull request adding the agent config (${linked.path})`)
console.log(linked.pull_request_url)
})
return
}
Expand All @@ -443,15 +463,7 @@ export function registerConfig(program: Command): void {
const COMMIT_HINT =
'Commit it to your default branch. Ellipsis syncs agent configs from GitHub.'

// A create answers two ways: with a repository the agent waits on a pull
// request, without one it is already live and has no file.
function printCreated(created: CreatedAgentConfig): void {
if (created.pull_request_url) {
console.log(`✓ opened a pull request adding the agent config (${created.path})`)
console.log(created.pull_request_url)
console.log('Merge it to deploy the agent.')
return
}
console.log(`✓ created "${configName(created.config)}" (${created.config.id}) — live now`)
console.log('It has no file; change it with `agent config edit`, or `agent config link` to move it into a repo.')
}
Expand Down
Loading
Loading