feat(managed-agent): require confirmation for removals

This commit is contained in:
chenanran555
2026-08-31 11:06:43 +08:00
parent 676b6c2ece
commit 67ae182ec3
5 changed files with 70 additions and 11 deletions
@@ -30,9 +30,16 @@ const SESSION_DELETE_FLAGS = {
export default defineCommand({
description: { "en-US": "Delete a session", "zh-CN": "删除 Session" },
auth: "apiKey",
risk: {
level: "high",
message: {
"en-US": "This deletes the specified remote managed Agent Session.",
"zh-CN": "该操作会删除指定的远端托管 Agent Session。",
},
},
usageArgs: "--session-id <id> [--provider <name>] [--file <path>]",
flags: SESSION_DELETE_FLAGS,
exampleArgs: ["--session-id sess_abc123"],
exampleArgs: ["--session-id sess_abc123 --yes"],
notes: CREDENTIALS_NOTE,
async run(ctx) {
const { settings, flags } = ctx;
@@ -37,9 +37,17 @@ export default defineCommand({
"zh-CN": "从 State 中移除资源,但不销毁远端资源",
},
auth: "none",
risk: {
level: "high",
message: {
"en-US":
"This removes the resource from local state without deleting it remotely, so this project will no longer track it.",
"zh-CN": "该操作会从本地 State 中移除资源但不会删除远端资源,此项目将不再跟踪该资源。",
},
},
usageArgs: "--address <provider.type.name> [--file <path>]",
flags: STATE_RM_FLAGS,
exampleArgs: ["--address bailian.agent.assistant"],
exampleArgs: ["--address bailian.agent.assistant --yes"],
notes: OFFLINE_NOTE,
async run(ctx) {
const { settings, flags } = ctx;
@@ -149,6 +149,38 @@ describe("e2e: managed-agent", () => {
});
});
test.each([
["state rm", ["state", "rm"]],
["session delete", ["session", "delete"]],
])("managed-agent %s --help 展示 runtime 注入的 --yes", async (_commandName, commandPath) => {
const { stderr, exitCode } = await runCommandE2e(MANAGED_AGENT_ROUTES, [
"managed-agent",
...commandPath,
"--help",
]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toMatch(/--yes/i);
});
test.each([
["state rm", ["state", "rm", "--address", "bailian.agent.assistant"]],
[
"session delete",
["session", "delete", "--session-id", "sess_e2e", "--api-key", "e2e-dummy-key"],
],
])("managed-agent %s 无 --yes 返回确认请求 (7)", async (_commandName, commandArgs) => {
const { stderr, exitCode } = await runCommandE2e(MANAGED_AGENT_ROUTES, [
"managed-agent",
...commandArgs,
"--output",
"json",
]);
expect(exitCode).toBe(7);
expect(JSON.parse(stderr)).toMatchObject({
error: { code: 7, type: "requires_confirmation" },
});
});
test("managed-agent session delete 缺少 --session-id 时退出为用法错误 (2)", async () => {
const { stderr, exitCode } = await runCommandE2e(MANAGED_AGENT_ROUTES, [
"managed-agent",
+1 -1
View File
@@ -26,7 +26,7 @@ description: >-
2. Ask the user to confirm the exact action and scope shown in the plan.
3. Only then run `apply` / `destroy` with `--yes`; a changed plan requires confirmation again.
`session delete` and future `risk: high` commands follow the shared protocol.
`state rm`, `session delete`, and future `risk: high` commands follow the shared protocol.
## IaC lifecycle
@@ -237,6 +237,10 @@ bl managed-agent session create --agent assistant --title 'debug run'
| **Description** | Delete a session |
| **Authentication** | API Key |
| **Usage** | `bl managed-agent session delete --session-id <id> [--provider <name>] [--file <path>]` |
| **Risk** | `high` |
| **Risk message** | This deletes the specified remote managed Agent Session. |
> **Agent safety:** Never add `--yes` automatically. On `type="requires_confirmation"`, stop and ask for explicit user confirmation of the same action and scope.
#### Flags
@@ -245,6 +249,7 @@ bl managed-agent session create --agent assistant --title 'debug run'
| `--session-id <id>` | string | yes | Session ID (required) |
| `--file <path>` | string | no | Config file path (default: agents.yaml) |
| `--provider <name>` | string | no | Target provider |
| `--yes` | switch | no | Confirm this high-risk operation |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
@@ -257,7 +262,8 @@ bl managed-agent session create --agent assistant --title 'debug run'
#### Examples
```bash
bl managed-agent session delete --session-id sess_abc123
# Only after explicit user confirmation:
bl managed-agent session delete --session-id sess_abc123 --yes
```
### `bl managed-agent session events`
@@ -552,12 +558,16 @@ bl managed-agent state list --file agents.yaml
### `bl managed-agent state rm`
| Field | Value |
| ------------------ | -------------------------------------------------------------------------- |
| **Name** | `managed-agent state rm` |
| **Description** | Remove a resource from state without destroying it remotely |
| **Authentication** | No Auth |
| **Usage** | `bl managed-agent state rm --address <provider.type.name> [--file <path>]` |
| Field | Value |
| ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **Name** | `managed-agent state rm` |
| **Description** | Remove a resource from state without destroying it remotely |
| **Authentication** | No Auth |
| **Usage** | `bl managed-agent state rm --address <provider.type.name> [--file <path>]` |
| **Risk** | `high` |
| **Risk message** | This removes the resource from local state without deleting it remotely, so this project will no longer track it. |
> **Agent safety:** Never add `--yes` automatically. On `type="requires_confirmation"`, stop and ask for explicit user confirmation of the same action and scope.
#### Flags
@@ -565,6 +575,7 @@ bl managed-agent state list --file agents.yaml
| -------------------------------- | ------ | -------- | --------------------------------------- |
| `--address <provider.type.name>` | string | yes | Resource state address (required) |
| `--file <path>` | string | no | Config file path (default: agents.yaml) |
| `--yes` | switch | no | Confirm this high-risk operation |
#### Notes
@@ -573,7 +584,8 @@ bl managed-agent state list --file agents.yaml
#### Examples
```bash
bl managed-agent state rm --address bailian.agent.assistant
# Only after explicit user confirmation:
bl managed-agent state rm --address bailian.agent.assistant --yes
```
### `bl managed-agent state show`