Skip to content

Commit 345a947

Browse files
feat(cli): rename "lk agent session end" to "stop"
Rename the `end` subcommand of `lk agent session` to `stop` per review feedback. Renames the CLI subcommand, the runSessionEnd handler to runSessionStop, the control-protocol verb ("end" -> "stop") on both the client and daemon sides, usage strings, comments, the e2e test, and the generated fish completion. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1c2c4ba commit 345a947

5 files changed

Lines changed: 36 additions & 36 deletions

File tree

.github/workflows/session-e2e.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Session E2E
22

3-
# Drives the real `lk agent session` start/say/end lifecycle against the minimal
3+
# Drives the real `lk agent session` start/say/stop lifecycle against the minimal
44
# one-file echo agent in cmd/lk/testdata/echo-agent, on Linux, macOS, and
55
# Windows. This exercises the detached daemon, the readiness handshake, the
66
# console IPC transport, and the model round-trip end to end -- runtime behavior

autocomplete/fish_autocomplete

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,23 +184,23 @@ complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcomma
184184
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l record -d 'Record audio and session report to console-recordings/'
185185
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console' -f -l help -s h -d 'show help'
186186
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from console; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
187-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console session simulate help h' -a 'session' -d 'Drive a single local agent session in text mode (start/say/end)'
187+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console session simulate help h' -a 'session' -d 'Drive a single local agent session in text mode (start/say/stop)'
188188
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session' -f -l help -s h -d 'show help'
189-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say end daemon help h' -a 'start' -d 'Start a detached agent session daemon'
189+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say stop daemon help h' -a 'start' -d 'Start a detached agent session daemon'
190190
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from start' -f -l port -r -d 'Fixed loopback port shared by the agent and control connections'
191191
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from start' -f -l help -s h -d 'show help'
192192
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from start; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
193-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say end daemon help h' -a 'say' -d 'Send a text turn to the running session and print the reply'
193+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say stop daemon help h' -a 'say' -d 'Send a text turn to the running session and print the reply'
194194
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from say' -f -l port -r -d 'Fixed loopback port shared by the agent and control connections'
195195
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from say' -f -l help -s h -d 'show help'
196196
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from say; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
197-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say end daemon help h' -a 'end' -d 'Stop the running session and its agent'
198-
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from end' -f -l port -r -d 'Fixed loopback port shared by the agent and control connections'
199-
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from end' -f -l help -s h -d 'show help'
200-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from end; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
197+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say stop daemon help h' -a 'stop' -d 'Stop the running session and its agent'
198+
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from stop' -f -l port -r -d 'Fixed loopback port shared by the agent and control connections'
199+
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from stop' -f -l help -s h -d 'show help'
200+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from stop; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
201201
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from daemon' -f -l help -s h -d 'show help'
202202
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and __fish_seen_subcommand_from daemon; and not __fish_seen_subcommand_from help h' -a 'help' -d 'Shows a list of commands or help for one command'
203-
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say end daemon help h' -a 'help' -d 'Shows a list of commands or help for one command'
203+
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from session; and not __fish_seen_subcommand_from start say stop daemon help h' -a 'help' -d 'Shows a list of commands or help for one command'
204204
complete -x -c lk -n '__fish_seen_subcommand_from agent a; and not __fish_seen_subcommand_from init create dockerfile config deploy status update restart rollback logs tail delete destroy versions list secrets update-secrets private-link start dev console session simulate help h' -a 'simulate' -d 'Run agent simulations against LiveKit Cloud'
205205
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l num-simulations -s n -r -d 'Number of scenarios to generate'
206206
complete -c lk -n '__fish_seen_subcommand_from agent a; and __fish_seen_subcommand_from simulate' -f -l concurrency -r -d 'Max simulations running in parallel (default: server-side limit)'

cmd/lk/session.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232

3333
// Single-session model: the fixed loopback port is the singleton registry.
3434
// The daemon binds it; whoever wins the bind() is "the session". start, say,
35-
// and end all rendezvous on this one port. No session id, manifest, or dir.
35+
// and stop all rendezvous on this one port. No session id, manifest, or dir.
3636
const (
3737
sessionMagic = "LKCP" // 4-byte preamble that marks a control connection
3838
sessionHost = "127.0.0.1"
@@ -65,7 +65,7 @@ func init() {
6565

6666
var agentSessionCommand = &cli.Command{
6767
Name: "session",
68-
Usage: "Drive a single local agent session in text mode (start/say/end)",
68+
Usage: "Drive a single local agent session in text mode (start/say/stop)",
6969
Category: "Core",
7070
Commands: []*cli.Command{
7171
{
@@ -83,10 +83,10 @@ var agentSessionCommand = &cli.Command{
8383
Action: runSessionSay,
8484
},
8585
{
86-
Name: "end",
86+
Name: "stop",
8787
Usage: "Stop the running session and its agent",
8888
Flags: []cli.Flag{sessionPortFlag},
89-
Action: runSessionEnd,
89+
Action: runSessionStop,
9090
},
9191
{
9292
Name: sessionDaemonSubcommand,
@@ -157,7 +157,7 @@ func runSessionStart(ctx context.Context, cmd *cli.Command) error {
157157
switch {
158158
case status == "ready":
159159
fmt.Fprintf(os.Stderr, "Detected %s agent (%s in %s)\n", projectType.Lang(), entrypoint, projectDir)
160-
fmt.Printf("Session started. Use `lk agent session say \"...\"` to talk, `lk agent session end` to stop.\n")
160+
fmt.Printf("Session started. Use `lk agent session say \"...\"` to talk, `lk agent session stop` to stop.\n")
161161
return nil
162162
case strings.HasPrefix(status, "error:"):
163163
return fmt.Errorf("%s", strings.TrimSpace(strings.TrimPrefix(status, "error:")))
@@ -220,14 +220,14 @@ func runSessionSay(ctx context.Context, cmd *cli.Command) error {
220220
return streamControlReplies(conn)
221221
}
222222

223-
func runSessionEnd(ctx context.Context, cmd *cli.Command) error {
223+
func runSessionStop(ctx context.Context, cmd *cli.Command) error {
224224
conn, err := dialControl(int(cmd.Int("port")))
225225
if err != nil {
226226
return err
227227
}
228228
defer conn.Close()
229229

230-
if err := writeControlFrame(conn, controlRequest{Cmd: "end"}); err != nil {
230+
if err := writeControlFrame(conn, controlRequest{Cmd: "stop"}); err != nil {
231231
return err
232232
}
233233
if err := streamControlReplies(conn); err != nil {

cmd/lk/session_daemon.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333

3434
// runSessionDaemon is the entry point for the hidden `lk agent session daemon`
3535
// subcommand that `lk agent session start` re-execs. It runs the detached
36-
// daemon to completion (until the agent exits or `end` is received).
36+
// daemon to completion (until the agent exits or `stop` is received).
3737
func runSessionDaemon() {
3838
ready := readyWriter()
3939
port, _ := strconv.Atoi(os.Getenv(envSessionPort))
@@ -300,7 +300,7 @@ func (d *sessionDaemon) runCommand(cmd *sessionCommand) {
300300
switch cmd.kind {
301301
case "say":
302302
d.runSay(cmd)
303-
case "end":
303+
case "stop":
304304
_ = writeControlFrame(cmd.out, controlReply{Done: true})
305305
d.shutOnce.Do(func() { close(d.shutdown) })
306306
default:

cmd/lk/session_e2e_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const sessionE2ETimeout = 5 * time.Second
3333

3434
// TestSessionE2E drives the real `lk agent session` lifecycle end to end:
3535
// build the binary, `start` the detached daemon, `say` to make the model echo
36-
// a token (asserting the CLI→daemon→agent→LLM round-trip), `end`, confirm a
36+
// a token (asserting the CLI→daemon→agent→LLM round-trip), `stop`, confirm a
3737
// second `say` cannot still reach the agent, then confirm the daemon exited
3838
// (nothing answers on the port).
3939
//
@@ -99,7 +99,7 @@ func TestSessionE2E(t *testing.T) {
9999

100100
// Best-effort teardown so a mid-run failure doesn't leave the daemon alive.
101101
t.Cleanup(func() {
102-
_, _ = run(sessionE2ETimeout, "agent", "session", "end", "--port", port)
102+
_, _ = run(sessionE2ETimeout, "agent", "session", "stop", "--port", port)
103103
})
104104

105105
// start: launches the detached daemon and returns once the agent is ready.
@@ -116,28 +116,28 @@ func TestSessionE2E(t *testing.T) {
116116
require.GreaterOrEqualf(t, strings.Count(sayOut, token), 2,
117117
"agent did not echo the token back; say output:\n%s", sayOut)
118118

119-
endOut, err := run(sessionE2ETimeout, "agent", "session", "end", "--port", port)
120-
require.NoError(t, err, "session end failed:\n%s", endOut)
121-
require.Contains(t, endOut, "Session ended.", "end did not confirm shutdown:\n%s", endOut)
119+
stopOut, err := run(sessionE2ETimeout, "agent", "session", "stop", "--port", port)
120+
require.NoError(t, err, "session stop failed:\n%s", stopOut)
121+
require.Contains(t, stopOut, "Session ended.", "stop did not confirm shutdown:\n%s", stopOut)
122122

123123
require.Eventually(t, portIsFree, sessionE2ETimeout, 200*time.Millisecond,
124-
"session daemon still listening on port %s after end", port)
124+
"session daemon still listening on port %s after stop", port)
125125

126126
// After a successful match and shutdown, another say must not reach a live
127127
// agent or reproduce the token.
128-
afterEndSay, err := runCapture(sessionE2ETimeout, "agent", "session", "say", "--port", port,
128+
afterStopSay, err := runCapture(sessionE2ETimeout, "agent", "session", "say", "--port", port,
129129
"Repeat this token back to me exactly and nothing else: "+token)
130-
afterEndSayOut := afterEndSay.stdout + afterEndSay.stderr
131-
require.Error(t, err, "session say unexpectedly succeeded after end:\n%s", afterEndSayOut)
132-
require.Equal(t, 1, afterEndSay.exitCode,
133-
"session say after end exited with wrong code; stdout:\n%s\nstderr:\n%s",
134-
afterEndSay.stdout, afterEndSay.stderr)
135-
require.Truef(t, strings.HasPrefix(afterEndSayOut, "no session running"),
136-
"session say after end output did not start with no session running; stdout:\n%s\nstderr:\n%s",
137-
afterEndSay.stdout, afterEndSay.stderr)
138-
require.NotContains(t, afterEndSayOut, token,
139-
"session say after end unexpectedly contained the matched token; stdout:\n%s\nstderr:\n%s",
140-
afterEndSay.stdout, afterEndSay.stderr)
130+
afterStopSayOut := afterStopSay.stdout + afterStopSay.stderr
131+
require.Error(t, err, "session say unexpectedly succeeded after stop:\n%s", afterStopSayOut)
132+
require.Equal(t, 1, afterStopSay.exitCode,
133+
"session say after stop exited with wrong code; stdout:\n%s\nstderr:\n%s",
134+
afterStopSay.stdout, afterStopSay.stderr)
135+
require.Truef(t, strings.HasPrefix(afterStopSayOut, "no session running"),
136+
"session say after stop output did not start with no session running; stdout:\n%s\nstderr:\n%s",
137+
afterStopSay.stdout, afterStopSay.stderr)
138+
require.NotContains(t, afterStopSayOut, token,
139+
"session say after stop unexpectedly contained the matched token; stdout:\n%s\nstderr:\n%s",
140+
afterStopSay.stdout, afterStopSay.stderr)
141141

142142
require.True(t, portIsFree(), "session daemon started listening again on port %s after failed say", port)
143143
}

0 commit comments

Comments
 (0)