Skip to content

Commit 735ad0b

Browse files
committed
Add terminal/wait_for_exit
1 parent b3f9aa4 commit 735ad0b

10 files changed

Lines changed: 266 additions & 55 deletions

File tree

docs/protocol/schema.mdx

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -572,19 +572,19 @@ See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protoc
572572

573573
**Properties:**
574574

575-
<ResponseField name="exitCode" type={"integer | null"} >
576-
577-
- Minimum: `0`
578-
579-
</ResponseField>
580-
<ResponseField name="finished" type={"boolean"} required>
581-
</ResponseField>
582-
<ResponseField name="output" type={"string"} required>
583-
</ResponseField>
584-
<ResponseField name="signal" type={"string | null"} >
585-
</ResponseField>
586-
<ResponseField name="truncated" type={"boolean"} required>
587-
</ResponseField>
575+
<ResponseField
576+
name="exitStatus"
577+
type={
578+
<>
579+
<span>
580+
<a href="#terminalexitstatus">TerminalExitStatus</a>
581+
</span>
582+
<span> | null</span>
583+
</>
584+
}
585+
></ResponseField>
586+
<ResponseField name="output" type={"string"} required></ResponseField>
587+
<ResponseField name="truncated" type={"boolean"} required></ResponseField>
588588

589589
<a id="terminal-release"></a>
590590
### <span class="font-mono">terminal/release</span>
@@ -602,6 +602,36 @@ See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protoc
602602
></ResponseField>
603603
<ResponseField name="terminalId" type={"string"} required></ResponseField>
604604

605+
<a id="terminal-wait_for_exit"></a>
606+
### <span class="font-mono">terminal/wait_for_exit</span>
607+
608+
#### <span class="font-mono">WaitForTerminalExitRequest</span>
609+
610+
**Type:** Object
611+
612+
**Properties:**
613+
614+
<ResponseField
615+
name="sessionId"
616+
type={<a href="#sessionid">SessionId</a>}
617+
required
618+
></ResponseField>
619+
<ResponseField name="terminalId" type={"string"} required></ResponseField>
620+
621+
#### <span class="font-mono">WaitForTerminalExitResponse</span>
622+
623+
**Type:** Object
624+
625+
**Properties:**
626+
627+
<ResponseField name="exitCode" type={"integer | null"} >
628+
629+
- Minimum: `0`
630+
631+
</ResponseField>
632+
<ResponseField name="signal" type={"string | null"} >
633+
</ResponseField>
634+
605635
## <span class="font-mono">AgentCapabilities</span>
606636

607637
Capabilities supported by the agent.
@@ -1585,6 +1615,20 @@ response to confirm successful cancellation.
15851615

15861616
</ResponseField>
15871617

1618+
## <span class="font-mono">TerminalExitStatus</span>
1619+
1620+
**Type:** Object
1621+
1622+
**Properties:**
1623+
1624+
<ResponseField name="exitCode" type={"integer | null"} >
1625+
1626+
- Minimum: `0`
1627+
1628+
</ResponseField>
1629+
<ResponseField name="signal" type={"string | null"} >
1630+
</ResponseField>
1631+
15881632
## <span class="font-mono">TextContent</span>
15891633

15901634
Text provided to or from an LLM.

rust/acp.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ impl Side for ClientSide {
254254
TERMINAL_RELEASE_METHOD_NAME => serde_json::from_str(params.get())
255255
.map(AgentRequest::ReleaseTerminalRequest)
256256
.map_err(Into::into),
257+
TERMINAL_WAIT_FOR_EXIT_METHOD_NAME => serde_json::from_str(params.get())
258+
.map(AgentRequest::WaitForTerminalExitRequest)
259+
.map_err(Into::into),
257260
_ => Err(Error::method_not_found()),
258261
}
259262
}
@@ -300,6 +303,10 @@ impl<T: Client> MessageHandler<ClientSide> for T {
300303
self.release_terminal(args).await?;
301304
Ok(ClientResponse::ReleaseTerminalResponse)
302305
}
306+
AgentRequest::WaitForTerminalExitRequest(args) => {
307+
let response = self.wait_for_terminal_exit(args).await?;
308+
Ok(ClientResponse::WaitForTerminalExitResponse(response))
309+
}
303310
}
304311
}
305312

@@ -437,6 +444,18 @@ impl Client for AgentSideConnection {
437444
.await
438445
}
439446

447+
async fn wait_for_terminal_exit(
448+
&self,
449+
arguments: WaitForTerminalExitRequest,
450+
) -> Result<WaitForTerminalExitResponse, Error> {
451+
self.conn
452+
.request(
453+
TERMINAL_WAIT_FOR_EXIT_METHOD_NAME,
454+
Some(AgentRequest::WaitForTerminalExitRequest(arguments)),
455+
)
456+
.await
457+
}
458+
440459
async fn session_notification(&self, notification: SessionNotification) -> Result<(), Error> {
441460
self.conn.notify(
442461
SESSION_UPDATE_NOTIFICATION,

rust/client.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ pub trait Client {
6969
args: ReleaseTerminalRequest,
7070
) -> impl Future<Output = Result<(), Error>>;
7171

72+
fn wait_for_terminal_exit(
73+
&self,
74+
args: WaitForTerminalExitRequest,
75+
) -> impl Future<Output = Result<WaitForTerminalExitResponse, Error>>;
76+
7277
/// Handles session update notifications from the agent.
7378
///
7479
/// This is a notification endpoint (no response expected) that receives
@@ -308,9 +313,7 @@ pub struct TerminalOutputRequest {
308313
pub struct TerminalOutputResponse {
309314
pub output: String,
310315
pub truncated: bool,
311-
pub finished: bool,
312-
pub exit_code: Option<u32>,
313-
pub signal: Option<String>,
316+
pub exit_status: Option<TerminalExitStatus>,
314317
}
315318

316319
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
@@ -321,6 +324,29 @@ pub struct ReleaseTerminalRequest {
321324
pub terminal_id: TerminalId,
322325
}
323326

327+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
328+
#[schemars(extend("x-side" = "client", "x-method" = "terminal/wait_for_exit"))]
329+
#[serde(rename_all = "camelCase")]
330+
pub struct WaitForTerminalExitRequest {
331+
pub session_id: SessionId,
332+
pub terminal_id: TerminalId,
333+
}
334+
335+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
336+
#[schemars(extend("x-side" = "client", "x-method" = "terminal/wait_for_exit"))]
337+
#[serde(rename_all = "camelCase")]
338+
pub struct WaitForTerminalExitResponse {
339+
#[serde(flatten)]
340+
pub exit_status: TerminalExitStatus,
341+
}
342+
343+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
344+
#[serde(rename_all = "camelCase")]
345+
pub struct TerminalExitStatus {
346+
pub exit_code: Option<u32>,
347+
pub signal: Option<String>,
348+
}
349+
324350
// Capabilities
325351

326352
/// Capabilities supported by the client.
@@ -373,8 +399,10 @@ pub struct ClientMethodNames {
373399
pub terminal_new: &'static str,
374400
/// Method for getting terminals output.
375401
pub terminal_output: &'static str,
376-
/// Method for releasing terminals.
402+
/// Method for releasing a terminal.
377403
pub terminal_release: &'static str,
404+
/// Method for waiting for a terminal to finish.
405+
pub terminal_wait_for_exit: &'static str,
378406
}
379407

380408
/// Constant containing all client method names.
@@ -386,6 +414,7 @@ pub const CLIENT_METHOD_NAMES: ClientMethodNames = ClientMethodNames {
386414
terminal_new: TERMINAL_NEW_METHOD_NAME,
387415
terminal_output: TERMINAL_OUTPUT_METHOD_NAME,
388416
terminal_release: TERMINAL_RELEASE_METHOD_NAME,
417+
terminal_wait_for_exit: TERMINAL_WAIT_FOR_EXIT_METHOD_NAME,
389418
};
390419

391420
/// Notification name for session updates.
@@ -402,6 +431,8 @@ pub(crate) const TERMINAL_NEW_METHOD_NAME: &str = "terminal/new";
402431
pub(crate) const TERMINAL_OUTPUT_METHOD_NAME: &str = "terminal/output";
403432
/// Method for releasing a terminal.
404433
pub(crate) const TERMINAL_RELEASE_METHOD_NAME: &str = "terminal/release";
434+
/// Method for waiting for a terminal to finish.
435+
pub(crate) const TERMINAL_WAIT_FOR_EXIT_METHOD_NAME: &str = "terminal/wait_for_exit";
405436

406437
/// All possible requests that an agent can send to a client.
407438
///
@@ -419,6 +450,7 @@ pub enum AgentRequest {
419450
NewTerminalRequest(NewTerminalRequest),
420451
TerminalOutputRequest(TerminalOutputRequest),
421452
ReleaseTerminalRequest(ReleaseTerminalRequest),
453+
WaitForTerminalExitRequest(WaitForTerminalExitRequest),
422454
}
423455

424456
/// All possible responses that a client can send to an agent.
@@ -437,6 +469,7 @@ pub enum ClientResponse {
437469
NewTerminalResponse(NewTerminalResponse),
438470
TerminalOutputResponse(TerminalOutputResponse),
439471
ReleaseTerminalResponse,
472+
WaitForTerminalExitResponse(WaitForTerminalExitResponse),
440473
}
441474

442475
/// All possible notifications that an agent can send to a client.

rust/example_client.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ impl acp::Client for ExampleClient {
6161
Err(acp::Error::method_not_found())
6262
}
6363

64+
async fn wait_for_terminal_exit(
65+
&self,
66+
_args: acp::WaitForTerminalExitRequest,
67+
) -> anyhow::Result<acp::WaitForTerminalExitResponse, acp::Error> {
68+
Err(acp::Error::method_not_found())
69+
}
70+
6471
async fn session_notification(
6572
&self,
6673
args: acp::SessionNotification,

rust/markdown_generator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ impl SideDocs {
647647
"terminal/new" => self.client_methods.get("new_terminal").unwrap(),
648648
"terminal/output" => self.client_methods.get("terminal_output").unwrap(),
649649
"terminal/release" => self.client_methods.get("release_terminal").unwrap(),
650+
"terminal/wait_for_exit" => self.client_methods.get("wait_for_terminal_exit").unwrap(),
650651
_ => panic!("Introduced a method? Add it here :)"),
651652
}
652653
}

rust/rpc_tests.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ impl Client for TestClient {
8282
async fn release_terminal(&self, _args: ReleaseTerminalRequest) -> Result<(), Error> {
8383
unimplemented!()
8484
}
85+
86+
async fn wait_for_terminal_exit(
87+
&self,
88+
_args: WaitForTerminalExitRequest,
89+
) -> Result<WaitForTerminalExitResponse, Error> {
90+
unimplemented!()
91+
}
8592
}
8693

8794
#[derive(Clone)]

schema/meta.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"session_update": "session/update",
1515
"terminal_new": "terminal/new",
1616
"terminal_output": "terminal/output",
17-
"terminal_release": "terminal/release"
17+
"terminal_release": "terminal/release",
18+
"terminal_wait_for_exit": "terminal/wait_for_exit"
1819
},
1920
"version": 1
2021
}

schema/schema.json

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
{
5656
"$ref": "#/$defs/ReleaseTerminalRequest",
5757
"title": "ReleaseTerminalRequest"
58+
},
59+
{
60+
"$ref": "#/$defs/WaitForTerminalExitRequest",
61+
"title": "WaitForTerminalExitRequest"
5862
}
5963
],
6064
"description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly - instead, use the methods on the [`Client`] trait.\n\nThis enum encompasses all method calls from agent to client.",
@@ -272,6 +276,10 @@
272276
{
273277
"title": "ReleaseTerminalResponse",
274278
"type": "null"
279+
},
280+
{
281+
"$ref": "#/$defs/WaitForTerminalExitResponse",
282+
"title": "WaitForTerminalExitResponse"
275283
}
276284
],
277285
"description": "All possible responses that a client can send to an agent.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding AgentRequest variants.",
@@ -1273,6 +1281,19 @@
12731281
}
12741282
]
12751283
},
1284+
"TerminalExitStatus": {
1285+
"properties": {
1286+
"exitCode": {
1287+
"format": "uint32",
1288+
"minimum": 0,
1289+
"type": ["integer", "null"]
1290+
},
1291+
"signal": {
1292+
"type": ["string", "null"]
1293+
}
1294+
},
1295+
"type": "object"
1296+
},
12761297
"TerminalOutputRequest": {
12771298
"properties": {
12781299
"sessionId": {
@@ -1289,25 +1310,24 @@
12891310
},
12901311
"TerminalOutputResponse": {
12911312
"properties": {
1292-
"exitCode": {
1293-
"format": "uint32",
1294-
"minimum": 0,
1295-
"type": ["integer", "null"]
1296-
},
1297-
"finished": {
1298-
"type": "boolean"
1313+
"exitStatus": {
1314+
"anyOf": [
1315+
{
1316+
"$ref": "#/$defs/TerminalExitStatus"
1317+
},
1318+
{
1319+
"type": "null"
1320+
}
1321+
]
12991322
},
13001323
"output": {
13011324
"type": "string"
13021325
},
1303-
"signal": {
1304-
"type": ["string", "null"]
1305-
},
13061326
"truncated": {
13071327
"type": "boolean"
13081328
}
13091329
},
1310-
"required": ["output", "truncated", "finished"],
1330+
"required": ["output", "truncated"],
13111331
"type": "object",
13121332
"x-method": "terminal/output",
13131333
"x-side": "client"
@@ -1600,6 +1620,35 @@
16001620
}
16011621
]
16021622
},
1623+
"WaitForTerminalExitRequest": {
1624+
"properties": {
1625+
"sessionId": {
1626+
"$ref": "#/$defs/SessionId"
1627+
},
1628+
"terminalId": {
1629+
"type": "string"
1630+
}
1631+
},
1632+
"required": ["sessionId", "terminalId"],
1633+
"type": "object",
1634+
"x-method": "terminal/wait_for_exit",
1635+
"x-side": "client"
1636+
},
1637+
"WaitForTerminalExitResponse": {
1638+
"properties": {
1639+
"exitCode": {
1640+
"format": "uint32",
1641+
"minimum": 0,
1642+
"type": ["integer", "null"]
1643+
},
1644+
"signal": {
1645+
"type": ["string", "null"]
1646+
}
1647+
},
1648+
"type": "object",
1649+
"x-method": "terminal/wait_for_exit",
1650+
"x-side": "client"
1651+
},
16031652
"WriteTextFileRequest": {
16041653
"description": "Request to write content to a text file.\n\nOnly available if the client supports the `fs.writeTextFile` capability.",
16051654
"properties": {

0 commit comments

Comments
 (0)