superun-ai-cli 0.1.29 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.en.md +22 -2
  2. package/README.md +46 -4
  3. package/dist/api/security-review-api.d.ts +20 -0
  4. package/dist/api/security-review-api.js +75 -0
  5. package/dist/api/security-review-api.js.map +1 -0
  6. package/dist/commands/chat/index.js +2 -0
  7. package/dist/commands/chat/index.js.map +1 -1
  8. package/dist/commands/chat/security.d.ts +4 -0
  9. package/dist/commands/chat/security.js +57 -0
  10. package/dist/commands/chat/security.js.map +1 -0
  11. package/dist/commands/chat/state.js +6 -2
  12. package/dist/commands/chat/state.js.map +1 -1
  13. package/dist/commands/chat/stop.js +17 -0
  14. package/dist/commands/chat/stop.js.map +1 -1
  15. package/dist/commands/chat/wait.js +5 -1
  16. package/dist/commands/chat/wait.js.map +1 -1
  17. package/dist/commands/session/index.js +36 -1
  18. package/dist/commands/session/index.js.map +1 -1
  19. package/dist/commands/shared.d.ts +6 -0
  20. package/dist/commands/shared.js +81 -2
  21. package/dist/commands/shared.js.map +1 -1
  22. package/dist/contracts/cli-output.d.ts +4 -1
  23. package/dist/contracts/security-review.d.ts +102 -0
  24. package/dist/contracts/security-review.js +47 -0
  25. package/dist/contracts/security-review.js.map +1 -0
  26. package/dist/conversation/next-actions.d.ts +1 -1
  27. package/dist/conversation/next-actions.js +22 -10
  28. package/dist/conversation/next-actions.js.map +1 -1
  29. package/dist/conversation/security-review.d.ts +129 -0
  30. package/dist/conversation/security-review.js +246 -0
  31. package/dist/conversation/security-review.js.map +1 -0
  32. package/dist/conversation/session-waiter.d.ts +3 -1
  33. package/dist/conversation/session-waiter.js +5 -2
  34. package/dist/conversation/session-waiter.js.map +1 -1
  35. package/dist/interactions/managed-agent-model.d.ts +15 -15
  36. package/dist/output/writer.d.ts +1 -1
  37. package/dist/output/writer.js +8 -3
  38. package/dist/output/writer.js.map +1 -1
  39. package/dist/program.js +2 -0
  40. package/dist/program.js.map +1 -1
  41. package/dist/runtime.d.ts +4 -2
  42. package/dist/runtime.js +12 -5
  43. package/dist/runtime.js.map +1 -1
  44. package/dist/session/binding.d.ts +74 -0
  45. package/dist/session/binding.js +97 -0
  46. package/dist/session/binding.js.map +1 -0
  47. package/dist/session/host-context.d.ts +5 -0
  48. package/dist/session/host-context.js +83 -0
  49. package/dist/session/host-context.js.map +1 -0
  50. package/package.json +1 -1
package/README.en.md CHANGED
@@ -78,9 +78,12 @@ superun-ai
78
78
  │ ├── login # Sign in and save a PAT
79
79
  │ ├── status # Check local PAT configuration
80
80
  │ └── logout # Remove the locally saved PAT
81
- ├── session # Query projects
81
+ ├── session # Query projects and conversation binding
82
82
  │ ├── list # List projects
83
- │ └── get <sessionId> # Get project details
83
+ │ ├── get <sessionId> # Get project details
84
+ │ ├── current # Read the saved project for this host conversation
85
+ │ ├── use <sessionId> # Select a project for this conversation
86
+ │ └── clear # Clear the local binding and keep the remote project
84
87
  ├── chat # Conversational creation
85
88
  │ ├── create # Create a project and send a request
86
89
  │ ├── send <sessionId> # Continue the conversation
@@ -98,6 +101,7 @@ superun-ai
98
101
  │ │ └── select <sessionId> <choiceId> # Choose a style and show the development feature list
99
102
  │ ├── demo <sessionId> # View the demo and record it as viewed
100
103
  │ ├── develop <sessionId> # Keep the demo and plan development
104
+ │ ├── security <sessionId> # Scan security, apply necessary fixes, and generate an audit report
101
105
  │ ├── interaction # Answer or skip interactions
102
106
  │ │ ├── reply <sessionId> <interactionId> # Submit an answer
103
107
  │ │ └── skip <sessionId> <interactionId> # 跳过当前交互
@@ -116,6 +120,22 @@ superun-ai
116
120
 
117
121
  Run `npm run docs:sync` after changing command registration to update both command trees. `npm run docs:check` validates their completeness; `prepack` also checks them before packaging.
118
122
 
123
+ ## Restore the project for this conversation
124
+
125
+ In Codex and WorkBuddy / CodeBuddy environments with a verifiable conversation identity, the CLI remembers one project per conversation. Creating a project or explicitly operating on another project replaces the binding. Listing projects, reading details, and waiting for tasks do not change it.
126
+
127
+ ```bash
128
+ superun-ai session current
129
+ superun-ai session use <sessionId>
130
+ superun-ai session clear
131
+ ```
132
+
133
+ `current` returns the saved `sessionId`. Use existing commands to read project details or continue with `chat send <sessionId>`. Use `use` when switching projects without starting work; `clear` removes only the local binding and keeps the remote project. You do not need to run `use` before every command.
134
+
135
+ Bindings survive reopening the same host conversation and are isolated by conversation, superun account, and endpoint. WorkBuddy subagents share the main task binding when their ownership can be verified. Bindings are local to this device.
136
+
137
+ `UNBOUND` means no project is selected. `UNAVAILABLE` means the host conversation cannot be identified; continue passing an explicit `sessionId`. For `CREATING` or `CREATE_UNKNOWN`, check the original creation request before creating again. Once you have confirmed the project ID, restore the binding with `use`.
138
+
119
139
  ## PAT login
120
140
 
121
141
  ```bash
package/README.md CHANGED
@@ -80,9 +80,12 @@ superun-ai
80
80
  │ ├── login # 登录 superun 并保存 PAT
81
81
  │ ├── status # 查看本地 PAT 配置状态
82
82
  │ └── logout # 清除本地 PAT
83
- ├── session # 查询项目
83
+ ├── session # 查询项目与当前会话绑定
84
84
  │ ├── list # 查询项目列表
85
- │ └── get <sessionId> # 查询项目详情
85
+ │ ├── get <sessionId> # 查询项目详情
86
+ │ ├── current # 读取当前宿主会话保存的项目绑定
87
+ │ ├── use <sessionId> # 选择当前会话继续使用的项目
88
+ │ └── clear # 清除当前会话的项目绑定,保留远端项目
86
89
  ├── chat # 对话创作
87
90
  │ ├── create # 新建项目并发送需求
88
91
  │ ├── send <sessionId> # 继续项目创作
@@ -100,6 +103,7 @@ superun-ai
100
103
  │ │ └── select <sessionId> <choiceId> # 选择风格并展示开发功能清单
101
104
  │ ├── demo <sessionId> # 查看演示快照并记录已查看状态
102
105
  │ ├── develop <sessionId> # 保留演示,进入研发并生成规划
106
+ │ ├── security <sessionId> # 安全扫描,自动评估、必要修复并生成审计报告
103
107
  │ ├── interaction # 回答或跳过交互
104
108
  │ │ ├── reply <sessionId> <interactionId> # 提交回答
105
109
  │ │ └── skip <sessionId> <interactionId> # 跳过当前交互
@@ -118,6 +122,22 @@ superun-ai
118
122
 
119
123
  命令树以源码注册为准。新增或调整命令后执行 `npm run docs:sync` 同步中英文命令树;`npm run docs:check` 校验完整性。发包前的 `prepack` 同样执行校验,发现遗漏或过期参数时停止发包准备。
120
124
 
125
+ ## 恢复当前会话的项目
126
+
127
+ 在可识别会话归属的 Codex、WorkBuddy / CodeBuddy 环境中,CLI 会自动记住当前会话正在创作的一个项目。新建项目会替换原绑定;显式操作另一个项目也会切换。列出项目、查询详情或等待任务不会改变绑定。
128
+
129
+ ```bash
130
+ superun-ai session current
131
+ superun-ai session use <sessionId>
132
+ superun-ai session clear
133
+ ```
134
+
135
+ `current` 返回已保存的 `sessionId`。需要项目详情时,用该 ID 调用已有查询命令;继续创作仍使用 `chat send <sessionId>`。`use` 适用于只切换项目、暂不创作的情况;`clear` 只解除本地绑定,保留远端项目。平时无需在每次命令前执行 `use`。
136
+
137
+ 同一宿主会话重开后可恢复绑定,不同会话、superun 账号和连接环境分别保存。WorkBuddy 子专家在能核对主任务归属时共用主任务绑定。该记录保存在本机,不跨设备同步。
138
+
139
+ `UNBOUND` 表示尚未绑定;`UNAVAILABLE` 表示无法识别宿主会话,此时继续显式传入 `sessionId`。若返回 `CREATING` 或 `CREATE_UNKNOWN`,先核对原创建请求,不要重复创建;确认已有项目后可用 `use` 恢复绑定。
140
+
121
141
  ## PAT 登录
122
142
 
123
143
  ```bash
@@ -247,7 +267,7 @@ superun-ai chat state <sessionId>
247
267
 
248
268
  不传内容时发送“帮我测一下刚才完成的功能。”;`--message` 与 `--input` 只能选一个,JSON 形状与 `chat send` 相同,支持附件。指定内容原样发送,空白内容会被拒绝。测试使用 `business_type=auto_test`,默认等待测试、结果回传及必要的修复结束;运行中不得重复发起。探索阶段和待回答交互先按当前流程处理。
249
269
 
250
- 每次研发完成后,引导用户选择“代码审查 / 自动测试 / 继续创作 / 上线运营”。用户明确要求“自动测试”“测一下刚才的功能”后直接调用;指定范围时将原文作为内容提交。讨论是否需要测试不等于要求执行。普通主动调用不承诺免费。
270
+ 每次研发完成后,引导用户选择“代码审查 / 自动测试 / 安全扫描 / 继续创作 / 上线运营”。用户明确要求“自动测试”“测一下刚才的功能”后直接调用;指定范围时将原文作为内容提交。讨论是否需要测试不等于要求执行。普通主动调用不承诺免费。
251
271
 
252
272
  结果中的 `autoTest.phase` 区分 `test` 与后续 `repair`,`autoTest.reportMessages` 保留本次最新报告,`messages` 保留对话内容。`autoTest.sourceMessageId` 用于后续回复来源校验;`previousReportMessages` 如有返回,仅用于追溯上一份报告的编号和问题,不能替代本次结果。会话 `COMPLETED` 只表示操作结束,不表示测试通过。CLI 不从正文关键词推断结构化通过数或修复状态,由接入 Agent 依据实际报告按以下规则展示。
253
273
 
@@ -306,6 +326,7 @@ superun-ai chat state <sessionId>
306
326
  >
307
327
  > - **代码审查**:回复“代码审查”,检查刚才改动的代码,发现问题后先告知你,再自动修复。
308
328
  > - **自动测试**:回复“自动测试”,实际验证刚才完成的功能,发现确认的问题后先告知你,再自动修复。
329
+ > - **安全扫描**:检查项目安全风险,必要时自动修复并生成审计报告。
309
330
  > - **继续创作**:直接告诉我想新增或调整的内容。
310
331
  > - **上线运营**:回复“上线运营”。
311
332
 
@@ -349,6 +370,27 @@ superun-ai chat send <sessionId> --review-followup <sourceMessageId> --message "
349
370
 
350
371
  不增加“暂不需要”步骤。用户明确要求“审查完再自动测试”时,在审查及修复有效完成且无遗留问题后沿用已有授权衔接,否则等待用户选择。选择自动测试后沿用自动测试的结果规则;选择上线运营后沿用现有发布流程。当前审查流程不会在修复后自动重复审查同一范围。
351
372
 
373
+ ## 安全扫描
374
+
375
+ 研发完成后的引导增加“**安全扫描**:检查项目安全风险,必要时自动修复并生成审计报告”。用户选择即执行,默认扫描当前项目全部可用项,不展示费用和预计耗时、不增加二次确认或检查项选择。
376
+
377
+ ```bash
378
+ superun-ai chat security <sessionId>
379
+ superun-ai chat security <sessionId> --no-wait
380
+ superun-ai chat state <sessionId> --review-id <reviewId>
381
+ superun-ai chat wait <sessionId> --review-id <reviewId>
382
+ superun-ai chat stop <sessionId> --review-id <reviewId>
383
+ superun-ai chat security <sessionId> --retry-report <reviewId>
384
+ ```
385
+
386
+ 用户主动指定范围时,可通过可重复的 `--check <category>` 传实际检查项。启动使用 Glow 同源接口,服务端将扫描写入项目会话,并自动推进评估、必要修复和报告生成。不要再通过普通 `chat send` 发送扫描或修复指令。已有扫描进行中时直接跟进,不重复启动。
387
+
388
+ `securityReview` 返回本次扫描 ID、检查项、阶段和报告;`taskProgress.markdown` 展示本次检查列表及等待中、进行中、已完成、失败、取消、跳过状态。仅变化时输出扫描进度事件,按同一 ID 更新,不展示历史扫描列表或内部任务派发消息。普通 `chat state` / `wait` 会识别当前安全扫描会话;返回的等待命令携带 `--review-id`,跨修复轮次保持本次身份。`--review-id` 和 `--message-id` 不应混用。
389
+
390
+ 检查完成、扫描消息结束或修复任务启动都不代表整个流程完成。CLI 等到报告成功且取得正文后,由接入 Agent 根据 `securityReview.reportResult` 展示简洁的结果摘要,保留发现的问题、修复结果和必要注意事项。报告数据用于摘要,不展开完整正文、不提供完整报告或 PDF 下载链接、不另行生成报告文件;宿主支持直接内嵌 PDF 时可展示原 PDF,否则只展示结果。正常完成后接上“继续创作 / 自动测试 / 上线运营”引导;仅有未来条件下才需处理的注意事项时不省略菜单,存在当前必须处理的阻碍时先引导解决。修复由后端自动执行,无需用户再次确认;真实业务问题仍按现有交互处理。报告生成失败时,只在用户要求后使用 `--retry-report` 重试报告;扫描失效、失败或取消时如实说明,不自动重启。
391
+
392
+ 本地超时或 Ctrl+C 只结束等待,远端任务继续;使用返回的扫描 ID 恢复等待。用户明确要求取消才调用专用取消接口。启动结果不确定时先查询已有记录,不重发写请求。
393
+
352
394
  ## 余额不足与充值后重试
353
395
 
354
396
  创建请求或对话执行中余额不足时,CLI 返回充值引导:前往 [superun.ai](https://superun.ai) 充值,完成后回复“重试”。用户确认前不自动重试,也不展示继续创作或上线运营菜单。
@@ -403,7 +445,7 @@ superun-ai chat publish visibility <sessionId> private
403
445
 
404
446
  `routing` 包含 `status`(ready/fallback/unavailable)、`sourceFile`、`hasMultipleSides`、`defaultSide`、`groups` 和 `warnings`。每组包含 `side`、`label`、`basePath`、`entryPath`、`entryUrl`、`shareUrl` 及 `routes`(名称、路径、可生成的 URL)。默认端取第一组,进入地址取该组第一条路由,分享地址使用 basePath;动态参数路径不虚构参数和链接。
405
447
 
406
- - **单端创作完成**:直接展示该端 entryUrl,命名为“查看预览”,再给“代码审查 / 自动测试 / 继续创作 / 上线运营”。
448
+ - **单端创作完成**:直接展示该端 entryUrl,命名为“查看预览”,再给“代码审查 / 自动测试 / 安全扫描 / 继续创作 / 上线运营”。
407
449
  - **多端创作完成**:按原顺序逐端展示全部有名预览链接,引导点击进入;测试和继续创作引导用户说明对应端与功能。
408
450
  - **单端发布完成**:展示“访问网站”和继续创作引导。
409
451
  - **多端发布完成**:逐端展示全部有名正式链接,引导进入对应端,再提供继续创作引导。
@@ -0,0 +1,20 @@
1
+ import type { ApiClient } from '../transport/api-client.js';
2
+ import type { SecurityReviewView, SecurityReviewResult } from '../contracts/security-review.js';
3
+ export declare function securityActive(review: SecurityReviewView | SecurityReviewResult): boolean;
4
+ export declare class SecurityReviewApi {
5
+ private readonly client;
6
+ private startReceipt?;
7
+ constructor(client: ApiClient);
8
+ options(sessionId: string): Promise<{
9
+ category: string;
10
+ label: string;
11
+ description?: string | undefined;
12
+ seq?: number | undefined;
13
+ selectable?: boolean | undefined;
14
+ available?: boolean | undefined;
15
+ }[]>;
16
+ start(sessionId: string, checks: string[]): Promise<SecurityReviewView>;
17
+ query(sessionId: string, reviewId?: string, includeResults?: boolean): Promise<SecurityReviewView>;
18
+ cancel(sessionId: string, reviewId: string): Promise<void>;
19
+ retryReport(sessionId: string, reviewId: string): Promise<void>;
20
+ }
@@ -0,0 +1,75 @@
1
+ /** Glow 同源的安全扫描接口;编排和自动修复由 Center 负责。@author xiuyu.yi */
2
+ import { z } from 'zod';
3
+ import { parseWire } from '../contracts/node-wire.js';
4
+ import { CliError } from '../output/exit-codes.js';
5
+ import { securityReviewSchema, SecurityStage } from '../contracts/security-review.js';
6
+ const PREFIX = '/api/uxa-center/agent/AgentSecurityReview';
7
+ export function securityActive(review) {
8
+ return review.stage !== undefined && review.stage < SecurityStage.COMPLETED;
9
+ }
10
+ export class SecurityReviewApi {
11
+ client;
12
+ startReceipt;
13
+ constructor(client) {
14
+ this.client = client;
15
+ }
16
+ async options(sessionId) {
17
+ return parseWire(z.object({
18
+ checks: z.array(z.object({
19
+ category: z.string().min(1),
20
+ label: z.string(),
21
+ description: z.string().optional(),
22
+ seq: z.number().optional(),
23
+ selectable: z.boolean().optional(),
24
+ available: z.boolean().optional(),
25
+ })),
26
+ }), await this.client.call(`${PREFIX}/listSecurityCheckOptions`, { sessionId })).checks;
27
+ }
28
+ async start(sessionId, checks) {
29
+ const response = await this.client.call(`${PREFIX}/startSecurityReview`, {
30
+ sessionId,
31
+ checks,
32
+ locale: this.client.config.locale,
33
+ }, true);
34
+ try {
35
+ const started = parseWire(securityReviewSchema.omit({ found: true }).extend({ reviewId: z.string().min(1) }), response);
36
+ const review = { ...started, found: true, stage: started.stage ?? SecurityStage.CREATED };
37
+ this.startReceipt = { sessionId, review };
38
+ return review;
39
+ }
40
+ catch {
41
+ throw new CliError('OUTCOME_UNKNOWN', '扫描已提交但回执不完整,请查询当前扫描,勿重复启动', {
42
+ sessionId,
43
+ retryable: false,
44
+ });
45
+ }
46
+ }
47
+ async query(sessionId, reviewId, includeResults = false) {
48
+ const review = parseWire(securityReviewSchema, await this.client.call(`${PREFIX}/querySecurityReview`, {
49
+ sessionId,
50
+ ...(reviewId ? { reviewId } : {}),
51
+ includeResults,
52
+ }));
53
+ // 新建记录尚未同步到查询副本时保留已接受回执,继续等待同一个 ID,绝不重发启动。
54
+ if (!review.found &&
55
+ this.startReceipt?.sessionId === sessionId &&
56
+ this.startReceipt.review.reviewId === reviewId)
57
+ return this.startReceipt.review;
58
+ if (review.found &&
59
+ (!review.reviewId || review.stage === undefined || (reviewId && review.reviewId !== reviewId)))
60
+ throw new CliError('PROTOCOL_ERROR', '扫描状态缺少身份、阶段或与本次扫描不一致', {
61
+ sessionId,
62
+ reviewId,
63
+ });
64
+ if (review.found && this.startReceipt?.review.reviewId === reviewId)
65
+ this.startReceipt = undefined;
66
+ return review;
67
+ }
68
+ async cancel(sessionId, reviewId) {
69
+ await this.client.call(`${PREFIX}/cancelSecurityReview`, { sessionId, reviewId }, true);
70
+ }
71
+ async retryReport(sessionId, reviewId) {
72
+ await this.client.call(`${PREFIX}/retrySecurityAuditReport`, { sessionId, reviewId }, true);
73
+ }
74
+ }
75
+ //# sourceMappingURL=security-review-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-review-api.js","sourceRoot":"","sources":["../../src/api/security-review-api.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { registerRetry } from './retry.js';
9
9
  import { registerStyle } from './style.js';
10
10
  import { registerDemo } from './demo.js';
11
11
  import { registerDevelop } from './develop.js';
12
+ import { registerSecurity } from './security.js';
12
13
  import { registerInteraction } from './interaction.js';
13
14
  import { registerPlugin } from './plugin.js';
14
15
  import { registerPublish } from './publish.js';
@@ -25,6 +26,7 @@ export function registerChat(program, context) {
25
26
  registerStyle(chat, context);
26
27
  registerDemo(chat, context);
27
28
  registerDevelop(chat, context);
29
+ registerSecurity(chat, context);
28
30
  registerInteraction(chat, context);
29
31
  registerPlugin(chat, context);
30
32
  registerPublish(chat, context);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/chat/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,OAAuB;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzD,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/chat/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,OAAuB;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzD,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9B,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** 选择安全扫描即执行,后续评估、修复和报告均由 Center 自动推进。@author xiuyu.yi */
2
+ import type { Command } from 'commander';
3
+ import type { CommandContext } from '../shared.js';
4
+ export declare function registerSecurity(chat: Command, context: CommandContext): void;
@@ -0,0 +1,57 @@
1
+ import { runtime, businessWrite, withWait, waitOptions } from '../shared.js';
2
+ import { object, text } from '../../contracts/value.js';
3
+ import { SecurityStage, SecurityStatus } from '../../contracts/security-review.js';
4
+ import { securityActive } from '../../api/security-review-api.js';
5
+ import { CliError } from '../../output/exit-codes.js';
6
+ import { appendValue } from './message.js';
7
+ export function registerSecurity(chat, context) {
8
+ withWait(chat.command('security <sessionId>').description('安全扫描,自动评估、必要修复并生成审计报告'))
9
+ .option('--check <category>', '仅在用户指定范围时传入检查项,可重复使用;默认全部可用项', appendValue, [])
10
+ .option('--retry-report <reviewId>', '只重试本次失败的审计报告,不重新扫描或修复')
11
+ .action(async (sessionId, _options, command) => {
12
+ const service = await runtime(context, command);
13
+ const options = object(command.opts());
14
+ const retryId = text(options.retryReport);
15
+ const requested = options.check;
16
+ if (retryId && requested.length)
17
+ throw new CliError('INVALID_ARGUMENT', '重试报告不能指定检查项');
18
+ const current = await service.security.query(sessionId, retryId);
19
+ let reviewId = current.reviewId;
20
+ if (retryId) {
21
+ if (!current.found ||
22
+ current.stage !== SecurityStage.FAILED ||
23
+ current.reportStatus !== SecurityStatus.FAILED)
24
+ throw new CliError('INVALID_ARGUMENT', '本次报告不处于可重试状态,请查询扫描进度', {
25
+ sessionId,
26
+ reviewId: retryId,
27
+ });
28
+ await businessWrite(context, service, sessionId, () => service.security.retryReport(sessionId, retryId));
29
+ }
30
+ else if (!current.found || !securityActive(current)) {
31
+ const catalog = (await service.security.options(sessionId)).filter((item) => item.selectable !== false && item.available !== false);
32
+ if (!catalog.length)
33
+ throw new CliError('INVALID_ARGUMENT', '当前项目暂无可执行的安全检查项,请先完成研发', {
34
+ sessionId,
35
+ });
36
+ if (requested.some((category) => !catalog.some((item) => item.category === category)))
37
+ throw new CliError('INVALID_ARGUMENT', '指定检查项不可用,请使用当前项目的实际检查项', {
38
+ checks: catalog,
39
+ });
40
+ const checks = requested.length ? [...new Set(requested)] : catalog.map((item) => item.category);
41
+ await businessWrite(context, service, sessionId, async () => {
42
+ const response = await service.security.start(sessionId, checks);
43
+ reviewId = response.reviewId;
44
+ return response;
45
+ });
46
+ }
47
+ if (!reviewId)
48
+ throw new CliError('OUTCOME_UNKNOWN', '扫描回执缺少标识,请查询会话,勿重复启动', {
49
+ sessionId,
50
+ retryable: false,
51
+ });
52
+ context.output.write(options.wait === false
53
+ ? await service.state(sessionId, reviewId)
54
+ : await service.wait(sessionId, { ...waitOptions(command), reviewId }));
55
+ });
56
+ }
57
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/commands/chat/security.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,28 @@
1
1
  import { z } from 'zod';
2
- import { object } from '../../contracts/value.js';
2
+ import { object, text } from '../../contracts/value.js';
3
3
  import { applySnapshot } from '../../conversation/session-waiter.js';
4
4
  import { runtime } from '../shared.js';
5
5
  import { appendValue } from './message.js';
6
+ import { CliError } from '../../output/exit-codes.js';
6
7
  export function registerState(chat, context) {
7
8
  chat
8
9
  .command('state <sessionId>')
9
10
  .description('查询当前任务和交互')
10
11
  .option('--message-id <messageId>', '刷新指定消息快照')
12
+ .option('--review-id <reviewId>', '查询指定的本次安全扫描及报告')
11
13
  .option('--progress-revision <revision>', '上次已展示的任务进度版本')
12
14
  .option('--include-file <name>', '包含指定可见附件正文,可重复使用', appendValue, [])
13
15
  .action(async (sessionId, _options, command) => {
14
16
  const service = await runtime(context, command), options = object(command.opts());
17
+ if (options.reviewId && options.messageId)
18
+ throw new CliError('INVALID_ARGUMENT', '扫描 ID 与消息 ID 不能同时指定');
15
19
  let view = await service.load(sessionId);
16
20
  if (typeof options.messageId === 'string') {
17
21
  const snapshot = await service.conversation.snapshot(sessionId, options.messageId);
18
22
  if (snapshot.pipeline)
19
23
  view = applySnapshot(view, snapshot.pipeline);
20
24
  }
21
- const result = await service.inspect(view), names = z.array(z.string()).parse(options.includeFile);
25
+ const result = await service.inspect(view, undefined, text(options.reviewId)), names = z.array(z.string()).parse(options.includeFile);
22
26
  if (result.taskProgress)
23
27
  result.taskProgress.changed = result.taskProgress.revision !== options.progressRevision;
24
28
  if (names.length)
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/commands/chat/state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,OAAuB;IAClE,IAAI;SACD,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,WAAW,CAAC;SACxB,MAAM,CAAC,0BAA0B,EAAE,UAAU,CAAC;SAC9C,MAAM,CAAC,gCAAgC,EAAE,cAAc,CAAC;SACxD,MAAM,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACnF,IAAI,QAAQ,CAAC,QAAQ;gBAAE,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EACxC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,YAAY;YACrB,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,KAAK,OAAO,CAAC,gBAAgB,CAAC;QAC1F,IAAI,KAAK,CAAC,MAAM;YAAE,MAAM,CAAC,WAAW,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACzF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/commands/chat/state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,OAAuB;IAClE,IAAI;SACD,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,WAAW,CAAC;SACxB,MAAM,CAAC,0BAA0B,EAAE,UAAU,CAAC;SAC9C,MAAM,CAAC,wBAAwB,EAAE,gBAAgB,CAAC;SAClD,MAAM,CAAC,gCAAgC,EAAE,cAAc,CAAC;SACxD,MAAM,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS;YACvC,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;QAChE,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACnF,IAAI,QAAQ,CAAC,QAAQ;gBAAE,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAC3E,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,YAAY;YACrB,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,KAAK,OAAO,CAAC,gBAAgB,CAAC;QAC1F,IAAI,KAAK,CAAC,MAAM;YAAE,MAAM,CAAC,WAAW,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACzF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,14 +1,31 @@
1
1
  import { Option } from 'commander';
2
2
  import { object, text } from '../../contracts/value.js';
3
3
  import { runtime, businessWrite } from '../shared.js';
4
+ import { securityActive } from '../../api/security-review-api.js';
5
+ import { CliError } from '../../output/exit-codes.js';
4
6
  export function registerStop(chat, context) {
5
7
  chat
6
8
  .command('stop <sessionId>')
7
9
  .description('停止远端任务')
8
10
  .option('--message-id <messageId>', '指定任务消息')
11
+ .option('--review-id <reviewId>', '只取消指定安全扫描及其自动修复')
9
12
  .addOption(new Option('--scope <scope>', '停止范围').choices(['own', 'all']).default('own'))
10
13
  .action(async (sessionId, _options, command) => {
11
14
  const service = await runtime(context, command), options = object(command.opts());
15
+ if (options.reviewId && (options.messageId || options.scope === 'all'))
16
+ throw new CliError('INVALID_ARGUMENT', '指定安全扫描时不能同时指定消息或全部停止');
17
+ const reviewId = text(options.reviewId);
18
+ if (reviewId) {
19
+ const review = await service.security.query(sessionId, reviewId);
20
+ if (!review.found || !securityActive(review))
21
+ throw new CliError('INVALID_ARGUMENT', '该安全扫描已结束或不存在,无需取消', {
22
+ sessionId,
23
+ reviewId,
24
+ });
25
+ await businessWrite(context, service, sessionId, () => service.security.cancel(sessionId, reviewId));
26
+ context.output.write(await service.state(sessionId, reviewId));
27
+ return;
28
+ }
12
29
  await businessWrite(context, service, sessionId, () => service.command.stop(sessionId, options.scope === 'all' ? 'all' : 'own', text(options.messageId)));
13
30
  context.output.write({ state: 'COMPLETED', sessionId });
14
31
  });
@@ -1 +1 @@
1
- {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/commands/chat/stop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,OAAuB;IACjE,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,QAAQ,CAAC;SACrB,MAAM,CAAC,0BAA0B,EAAE,QAAQ,CAAC;SAC5C,SAAS,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;SACvF,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CACpD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAClG,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/commands/chat/stop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,OAAuB;IACjE,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,QAAQ,CAAC;SACrB,MAAM,CAAC,0BAA0B,EAAE,QAAQ,CAAC;SAC5C,MAAM,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;SACnD,SAAS,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;SACvF,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC;YACpE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACjE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;gBAC1C,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,mBAAmB,EAAE;oBAC1D,SAAS;oBACT,QAAQ;iBACT,CAAC,CAAC;YACL,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;YACrG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CACpD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAClG,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,18 +1,22 @@
1
1
  import { runtime, positive, waitOptions } from '../shared.js';
2
+ import { CliError } from '../../output/exit-codes.js';
2
3
  export function registerWait(chat, context) {
3
4
  chat
4
5
  .command('wait <sessionId>')
5
6
  .description('等待当前交互或任务结果,期间持续展示任务进度')
6
7
  .option('--message-id <messageId>', '起始消息 ID')
8
+ .option('--review-id <reviewId>', '持续跟进指定安全扫描,直到报告生成')
7
9
  .option('--timeout <seconds>', '本地等待上限;不传则持续等待', positive)
8
10
  .option('--interval <seconds>', '轮询最小间隔', positive)
9
11
  .option('--progress-revision <revision>', '上次已展示的任务进度版本;仅输出变化的进度')
10
12
  .action(async (sessionId, _options, command) => {
11
13
  const options = waitOptions(command);
14
+ if (options.reviewId && options.messageId)
15
+ throw new CliError('INVALID_ARGUMENT', '扫描 ID 与消息 ID 不能同时指定');
12
16
  context.output.write(await (await runtime(context, command)).wait(sessionId, {
13
17
  ...options,
14
18
  // no-wait 回执带的新消息也必须先入流,不能返回前一轮结果。
15
- requiredMessageId: options.messageId,
19
+ requiredMessageId: options.reviewId ? undefined : options.messageId,
16
20
  }));
17
21
  });
18
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/commands/chat/wait.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,OAAuB;IACjE,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,0BAA0B,EAAE,SAAS,CAAC;SAC7C,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,QAAQ,CAAC;SACzD,MAAM,CAAC,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAClD,MAAM,CAAC,gCAAgC,EAAE,uBAAuB,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,MAAM,CACJ,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAChC,CAAC,IAAI,CAAC,SAAS,EAAE;YAChB,GAAG,OAAO;YACV,mCAAmC;YACnC,iBAAiB,EAAE,OAAO,CAAC,SAAS;SACrC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/commands/chat/wait.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,OAAuB;IACjE,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,0BAA0B,EAAE,SAAS,CAAC;SAC7C,MAAM,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;SACrD,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,QAAQ,CAAC;SACzD,MAAM,CAAC,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAClD,MAAM,CAAC,gCAAgC,EAAE,uBAAuB,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAiB,EAAE,OAAgB,EAAE,EAAE;QACvE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS;YACvC,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;QAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,MAAM,CACJ,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAChC,CAAC,IAAI,CAAC,SAAS,EAAE;YAChB,GAAG,OAAO;YACV,mCAAmC;YACnC,iBAAiB,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS;SACpE,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,8 +1,43 @@
1
1
  import { registerList } from './list.js';
2
2
  import { registerGet } from './get.js';
3
+ import { runtime, sessionBinding } from '../shared.js';
4
+ import { CliError } from '../../output/exit-codes.js';
3
5
  export function registerSession(program, context) {
4
- const session = program.command('session').description('查询项目');
6
+ const session = program.command('session').description('查询项目与当前会话绑定');
5
7
  registerList(session, context);
6
8
  registerGet(session, context);
9
+ session
10
+ .command('current')
11
+ .description('读取当前宿主会话保存的项目绑定')
12
+ .action(async (_options, command) => {
13
+ const binding = await sessionBinding(context, await runtime(context, command));
14
+ context.output.write(binding
15
+ ? await binding.current()
16
+ : {
17
+ state: 'UNAVAILABLE',
18
+ reason: '宿主未提供可确认归属的会话身份,请继续显式传入 sessionId。',
19
+ });
20
+ });
21
+ session
22
+ .command('use <sessionId>')
23
+ .description('选择当前会话继续使用的项目')
24
+ .action(async (sessionId, _options, command) => {
25
+ const service = await runtime(context, command);
26
+ const binding = await sessionBinding(context, service);
27
+ if (!binding)
28
+ throw new CliError('INVALID_ARGUMENT', '宿主未提供可确认归属的会话身份,无法保存项目绑定');
29
+ await binding.select(service, sessionId);
30
+ context.output.write(await binding.current());
31
+ });
32
+ session
33
+ .command('clear')
34
+ .description('清除当前会话的项目绑定,保留远端项目')
35
+ .action(async (_options, command) => {
36
+ const binding = await sessionBinding(context, await runtime(context, command));
37
+ if (!binding)
38
+ throw new CliError('INVALID_ARGUMENT', '宿主未提供可确认归属的会话身份,无法清除项目绑定');
39
+ await binding.clear();
40
+ context.output.write(await binding.current());
41
+ });
7
42
  }
8
43
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/session/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,OAAuB;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/D,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/session/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,OAAuB;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IACtE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,iBAAiB,CAAC;SAC9B,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,OAAO;YACL,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE;YACzB,CAAC,CAAC;gBACE,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,oCAAoC;aAC7C,CACN,CAAC;IACJ,CAAC,CAAC,CAAC;IACL,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QACrD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YACV,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC;QACrE,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IACL,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,oBAAoB,CAAC;SACjC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,OAAO;YACV,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC;QACrE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -4,12 +4,15 @@ import { runtimeConfig } from '../config/runtime-config.js';
4
4
  import { CreationRuntime } from '../runtime.js';
5
5
  import type { OutputWriter } from '../output/writer.js';
6
6
  import type { JsonObject } from '../contracts/value.js';
7
+ import { SessionBinding } from '../session/binding.js';
7
8
  export type CommandContext = {
8
9
  output: OutputWriter;
9
10
  patStore: PatStore;
10
11
  signal: AbortSignal;
11
12
  makeRuntime?: (config: ReturnType<typeof runtimeConfig>, pat: string) => CreationRuntime;
12
13
  connection?: Promise<CredentialContext>;
14
+ sessionBinding?: Promise<SessionBinding | undefined>;
15
+ selectedSessionId?: string;
13
16
  };
14
17
  export type CredentialContext = {
15
18
  service: CreationRuntime;
@@ -18,12 +21,15 @@ export type CredentialContext = {
18
21
  /** 已有 PAT 直接复用;允许浏览器登录时自动补齐缺失的凭据。 */
19
22
  export declare function requireCredentials(context: CommandContext, command: Command, allowBrowser?: boolean): Promise<CredentialContext>;
20
23
  export declare function runtime(context: CommandContext, command: Command): Promise<CreationRuntime>;
24
+ /** 绑定归属仅在公共层识别一次;宿主未提供可靠身份时保留显式调用能力。 */
25
+ export declare function sessionBinding(context: CommandContext, service: CreationRuntime): Promise<SessionBinding | undefined>;
21
26
  export declare function positive(value: string): number;
22
27
  export declare function waitOptions(command: Command): {
23
28
  timeout?: number;
24
29
  interval?: number;
25
30
  messageId?: string;
26
31
  progressRevision?: string;
32
+ reviewId?: string;
27
33
  };
28
34
  export declare function withWait(command: Command, noWaitDescription?: string): Command;
29
35
  export declare function readInput(path: string): Promise<JsonObject>;