Skip to content

Commit 6c1df48

Browse files
authored
agent environment: manage the environments agents run in (#135)
- environment group (alias env, moved off variable which keeps var/variables): create/list/get/edit/delete/init + default set/list/clear - session start -e/--environment; echoes the resolved environment - --config-override renamed --override (wire: override), template starts resolve the template YAML client-side, idle_start dropped (promptless = idle server-side) - SDK pin ^0.17.0
1 parent 7113399 commit 6c1df48

13 files changed

Lines changed: 509 additions & 102 deletions

File tree

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.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"test:watch": "vitest"
2121
},
2222
"dependencies": {
23-
"@ellipsis-dev/sdk": "^0.16.0",
23+
"@ellipsis-dev/sdk": "^0.17.0",
2424
"chalk": "^5.6.2",
2525
"cli-table3": "^0.6.5",
2626
"commander": "^12.1.0",

src/cli.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { registerMe } from './commands/me'
66
import { registerSession } from './commands/session'
77
import { registerReview } from './commands/review'
88
import { registerConfig } from './commands/config'
9+
import { registerEnvironment } from './commands/environment'
910
import { registerVariable } from './commands/variable'
1011
import { registerFile } from './commands/file'
1112
import { registerTemplate } from './commands/template'
@@ -42,6 +43,7 @@ registerMe(program)
4243
registerSession(program)
4344
registerReview(program)
4445
registerConfig(program)
46+
registerEnvironment(program)
4547
registerVariable(program)
4648
registerFile(program)
4749
registerTemplate(program)

src/commands/config.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type Command } from 'commander'
2+
import { parse as parseYaml } from 'yaml'
23
import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
34
import { basename, dirname, extname } from 'node:path'
45
import { api } from '../lib/api'
@@ -117,21 +118,36 @@ export function registerConfig(program: Command): void {
117118
json?: boolean
118119
}) => {
119120
await runAction(async () => {
120-
// The server enforces "exactly one of config / template_id";
121-
// pre-check locally for a clearer error than a bare 400.
122121
if (!opts.file === !opts.template) {
123122
throw new Error('provide exactly one of --file <path> or --template <slug>')
124123
}
125124
if (opts.path && !opts.repo) {
126125
throw new Error('--path names a location in a repository, so it needs --repo <name>')
127126
}
128-
const req: CreateAgentConfigRequest = {
129-
repository: opts.repo,
130-
path: opts.path,
127+
const client = api()
128+
// Templates left the create request (#6394): resolve the slug to its
129+
// YAML and create from that config.
130+
const config = opts.file
131+
? (readConfigFile(opts.file) as AgentConfig)
132+
: (parseYaml((await client.agents.templates.get(opts.template!)).yaml) as AgentConfig)
133+
const req: CreateAgentConfigRequest = { config }
134+
const created = await client.agents.configs.create(req)
135+
// With --repo the agent is then moved into the repository by pull
136+
// request (create + link, the two-step the API exposes today).
137+
if (opts.repo) {
138+
const linked = await client.agents.configs.link(created.config.id, {
139+
repository: opts.repo,
140+
path: opts.path,
141+
})
142+
if (opts.json) {
143+
printJson(linked)
144+
return
145+
}
146+
console.log(`✓ created "${configName(linked.config)}" (${linked.config.id}) — live now`)
147+
console.log(`✓ opened a pull request adding the agent config (${linked.path})`)
148+
console.log(linked.pull_request_url)
149+
return
131150
}
132-
if (opts.file) req.config = readConfigFile(opts.file) as AgentConfig
133-
if (opts.template) req.template_id = opts.template
134-
const created = await api().agents.configs.create(req)
135151
if (opts.json) {
136152
printJson(created)
137153
return
@@ -415,13 +431,17 @@ export function registerConfig(program: Command): void {
415431
return
416432
}
417433
await runAction(async () => {
418-
printCreated(
419-
await api().agents.configs.create({
420-
template_id: opts.template,
421-
repository: opts.repo!,
422-
path: opts.path,
423-
}),
424-
)
434+
const client = api()
435+
const template = await client.agents.templates.get(opts.template!)
436+
const created = await client.agents.configs.create({
437+
config: parseYaml(template.yaml) as AgentConfig,
438+
})
439+
const linked = await client.agents.configs.link(created.config.id, {
440+
repository: opts.repo!,
441+
path: opts.path,
442+
})
443+
console.log(`✓ opened a pull request adding the agent config (${linked.path})`)
444+
console.log(linked.pull_request_url)
425445
})
426446
return
427447
}
@@ -443,15 +463,7 @@ export function registerConfig(program: Command): void {
443463
const COMMIT_HINT =
444464
'Commit it to your default branch. Ellipsis syncs agent configs from GitHub.'
445465

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

0 commit comments

Comments
 (0)