@autopilot-agent/cli 0.0.0-stage → 0.1.0
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.
- package/README.md +180 -2
- package/dist/activity-animation.d.ts +57 -0
- package/dist/activity-animation.js +145 -0
- package/dist/animation-clock.d.ts +22 -0
- package/dist/animation-clock.js +76 -0
- package/dist/composition-root.d.ts +105 -0
- package/dist/composition-root.js +588 -0
- package/dist/context-report.d.ts +20 -0
- package/dist/context-report.js +174 -0
- package/dist/controller.d.ts +79 -0
- package/dist/controller.js +681 -0
- package/dist/design-tokens.d.ts +34 -0
- package/dist/design-tokens.js +34 -0
- package/dist/error-diagnostics.d.ts +8 -0
- package/dist/error-diagnostics.js +62 -0
- package/dist/event-projector.d.ts +26 -0
- package/dist/event-projector.js +333 -0
- package/dist/file-mention-context.d.ts +34 -0
- package/dist/file-mention-context.js +173 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +14 -0
- package/dist/main.d.ts +40 -0
- package/dist/main.js +543 -0
- package/dist/parser.d.ts +17 -0
- package/dist/parser.js +391 -0
- package/dist/renderer.d.ts +9 -0
- package/dist/renderer.js +48 -0
- package/dist/scroll-viewport.d.ts +22 -0
- package/dist/scroll-viewport.js +62 -0
- package/dist/termination-format.d.ts +4 -0
- package/dist/termination-format.js +17 -0
- package/dist/timeline-lines.d.ts +38 -0
- package/dist/timeline-lines.js +104 -0
- package/dist/tui/app.d.ts +30 -0
- package/dist/tui/app.js +410 -0
- package/dist/tui/approval.d.ts +19 -0
- package/dist/tui/approval.js +37 -0
- package/dist/tui/brand/brand-header.d.ts +20 -0
- package/dist/tui/brand/brand-header.js +22 -0
- package/dist/tui/brand/intro.d.ts +12 -0
- package/dist/tui/brand/intro.js +88 -0
- package/dist/tui/brand/pixel.d.ts +8 -0
- package/dist/tui/brand/pixel.js +50 -0
- package/dist/tui/constants.d.ts +56 -0
- package/dist/tui/constants.js +57 -0
- package/dist/tui/context.d.ts +11 -0
- package/dist/tui/context.js +12 -0
- package/dist/tui/diff-stats.d.ts +8 -0
- package/dist/tui/diff-stats.js +7 -0
- package/dist/tui/format.d.ts +75 -0
- package/dist/tui/format.js +176 -0
- package/dist/tui/hooks/use-file-mention-index.d.ts +15 -0
- package/dist/tui/hooks/use-file-mention-index.js +59 -0
- package/dist/tui/hooks/use-pickers.d.ts +47 -0
- package/dist/tui/hooks/use-pickers.js +288 -0
- package/dist/tui/hooks/use-prompt-input.d.ts +54 -0
- package/dist/tui/hooks/use-prompt-input.js +258 -0
- package/dist/tui/hooks/use-status-view.d.ts +8 -0
- package/dist/tui/hooks/use-status-view.js +13 -0
- package/dist/tui/hooks/use-viewport.d.ts +22 -0
- package/dist/tui/hooks/use-viewport.js +117 -0
- package/dist/tui/input/file-mention.d.ts +33 -0
- package/dist/tui/input/file-mention.js +112 -0
- package/dist/tui/input/graphemes.d.ts +5 -0
- package/dist/tui/input/graphemes.js +10 -0
- package/dist/tui/input/keys.d.ts +16 -0
- package/dist/tui/input/keys.js +58 -0
- package/dist/tui/input/prompt-layout.d.ts +27 -0
- package/dist/tui/input/prompt-layout.js +84 -0
- package/dist/tui/input-area.d.ts +53 -0
- package/dist/tui/input-area.js +89 -0
- package/dist/tui/jobs.d.ts +10 -0
- package/dist/tui/jobs.js +24 -0
- package/dist/tui/lifecycle.d.ts +23 -0
- package/dist/tui/lifecycle.js +114 -0
- package/dist/tui/markdown/diff.d.ts +8 -0
- package/dist/tui/markdown/diff.js +19 -0
- package/dist/tui/markdown/inline.d.ts +4 -0
- package/dist/tui/markdown/inline.js +32 -0
- package/dist/tui/markdown/markdown.d.ts +17 -0
- package/dist/tui/markdown/markdown.js +117 -0
- package/dist/tui/markdown/table.d.ts +19 -0
- package/dist/tui/markdown/table.js +74 -0
- package/dist/tui/performance-diagnostics.d.ts +7 -0
- package/dist/tui/performance-diagnostics.js +57 -0
- package/dist/tui/pickers/effort.d.ts +10 -0
- package/dist/tui/pickers/effort.js +12 -0
- package/dist/tui/pickers/file-mention.d.ts +11 -0
- package/dist/tui/pickers/file-mention.js +22 -0
- package/dist/tui/pickers/model.d.ts +10 -0
- package/dist/tui/pickers/model.js +12 -0
- package/dist/tui/pickers/permission.d.ts +10 -0
- package/dist/tui/pickers/permission.js +13 -0
- package/dist/tui/pickers/skill.d.ts +13 -0
- package/dist/tui/pickers/skill.js +25 -0
- package/dist/tui/pickers/slash.d.ts +10 -0
- package/dist/tui/pickers/slash.js +11 -0
- package/dist/tui/prompt-input.d.ts +11 -0
- package/dist/tui/prompt-input.js +73 -0
- package/dist/tui/render-mode.d.ts +20 -0
- package/dist/tui/render-mode.js +31 -0
- package/dist/tui/run.d.ts +6 -0
- package/dist/tui/run.js +237 -0
- package/dist/tui/status-line.d.ts +16 -0
- package/dist/tui/status-line.js +37 -0
- package/dist/tui/store.d.ts +4 -0
- package/dist/tui/store.js +344 -0
- package/dist/tui/timeline/live.d.ts +16 -0
- package/dist/tui/timeline/live.js +151 -0
- package/dist/tui/timeline/presentation-timeline.d.ts +14 -0
- package/dist/tui/timeline/presentation-timeline.js +109 -0
- package/dist/tui/timeline/progress.d.ts +12 -0
- package/dist/tui/timeline/progress.js +43 -0
- package/dist/tui/timeline/static-timeline.d.ts +13 -0
- package/dist/tui/timeline/static-timeline.js +121 -0
- package/dist/tui/timeline/tool-tree.d.ts +7 -0
- package/dist/tui/timeline/tool-tree.js +25 -0
- package/dist/tui/timeline/turn.d.ts +19 -0
- package/dist/tui/timeline/turn.js +21 -0
- package/dist/tui/todo-list.d.ts +50 -0
- package/dist/tui/todo-list.js +120 -0
- package/dist/tui/transcript.d.ts +24 -0
- package/dist/tui/transcript.js +34 -0
- package/dist/tui/trust-dialog.d.ts +51 -0
- package/dist/tui/trust-dialog.js +127 -0
- package/dist/tui/types.d.ts +175 -0
- package/dist/tui/types.js +5 -0
- package/dist/tui/viewport/selection.d.ts +27 -0
- package/dist/tui/viewport/selection.js +79 -0
- package/dist/tui/viewport/sources.d.ts +29 -0
- package/dist/tui/viewport/sources.js +585 -0
- package/dist/tui/viewport/viewport.d.ts +12 -0
- package/dist/tui/viewport/viewport.js +87 -0
- package/dist/tui-input-history.d.ts +23 -0
- package/dist/tui-input-history.js +42 -0
- package/dist/tui-input-router.d.ts +24 -0
- package/dist/tui-input-router.js +115 -0
- package/dist/tui.d.ts +15 -0
- package/dist/tui.js +13 -0
- package/dist/types.d.ts +454 -0
- package/dist/types.js +7 -0
- package/package.json +58 -4
package/README.md
CHANGED
|
@@ -1,3 +1,181 @@
|
|
|
1
|
-
|
|
1
|
+
<!-- 本文件用于 npm CLI 用户了解安装、配置和使用方式。 -->
|
|
2
|
+
# @autopilot-agent/cli
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
Autopilot Agent 是一个在终端中使用的 AI 编程助手,可以运行在任何支持开启终端操作的IDE、ADE中;Autopilot 可以帮助你分析项目、修改代码、执行命令和管理会话。你可以通过权限设置和操作审批控制它对项目的访问。
|
|
5
|
+
|
|
6
|
+
安装后使用 `ap` 或 `autopilot` 启动,两者功能相同。
|
|
7
|
+
|
|
8
|
+
## 可以做什么
|
|
9
|
+
|
|
10
|
+
- **理解项目**:阅读文件、按文件名或内容搜索代码,梳理项目结构、解释实现、定位问题。输入 `@src/index.ts` 这样的相对路径,可以把指定文件带入当前对话。
|
|
11
|
+
- **编写和修改代码**:根据需求创建文件、修改已有代码,帮助修复 Bug、补充测试和整理文档;交互界面会展示文件修改信息。
|
|
12
|
+
- **执行开发命令**:运行测试、构建和其他命令,根据输出继续排查;耗时命令可以作为后台任务运行,随时查看输出或请求停止。
|
|
13
|
+
- **跟踪任务进度**:将复杂需求拆成待办事项,在执行过程中更新完成状态;任务运行时也可以排队提交下一条需求。
|
|
14
|
+
- **继续已有对话**:保存并管理项目会话,在已有会话中继续提问;中断后可恢复的任务可以通过 `ap resume` 继续。
|
|
15
|
+
- **管理上下文**:查看当前上下文用量,手动压缩对话;具备有效上下文预算时,也会按阈值自动压缩,帮助继续较长的任务。
|
|
16
|
+
- **控制操作权限**:确认项目是否可信,选择权限模式,并审批需要确认的操作;通过 `/undo` 预览并撤销当前会话最近一轮可撤销的文件修改。
|
|
17
|
+
- **扩展工具和工作流程**:加载已安装的 Skills,通过 `/skill` 选择使用;配置并授权 MCP 服务后,可以调用其提供的工具。
|
|
18
|
+
- **查资料和分析图片**:配置搜索服务后可以联网搜索、读取网页;配置可用的视觉模型后,可以分析项目中的图片,例如界面截图。
|
|
19
|
+
|
|
20
|
+
你可以直接用自然语言提出需求,例如:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
分析这个项目的入口和主要模块,先不要修改文件。
|
|
24
|
+
查找登录失败的原因,修复后运行相关测试。
|
|
25
|
+
根据这张UI设计图片,还原设计稿。
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 常用交互命令
|
|
29
|
+
|
|
30
|
+
启动 `ap` 后,输入 `/` 可以查看命令建议。
|
|
31
|
+
|
|
32
|
+
| 命令 | 用途 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `/model`、`/effort` | 选择后续任务使用的模型和思考强度 |
|
|
35
|
+
| `/skill` | 查看并选择已安装的 Skills |
|
|
36
|
+
| `/permissions` | 查看或切换当前会话的权限模式 |
|
|
37
|
+
| `/context`、`/context all` | 查看上下文用量,或展开详细信息 |
|
|
38
|
+
| `/compact` | 手动压缩当前上下文 |
|
|
39
|
+
| `/jobs` | 查看后台任务,也可查看输出或请求停止 |
|
|
40
|
+
| `/queue <需求>` | 将下一条需求加入队列 |
|
|
41
|
+
| `/undo` | 预览最近一轮可撤销的文件修改,再确认是否撤销 |
|
|
42
|
+
| `/cancel`、`/exit` | 取消当前任务,或退出 CLI |
|
|
43
|
+
|
|
44
|
+
## 安装
|
|
45
|
+
|
|
46
|
+
请先安装 **Node.js >=20.11.0 且 <22** 和 npm,再运行以下命令。安装时需要联网。
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g autopilot-agent
|
|
50
|
+
ap --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
只需安装 `autopilot-agent`,所需依赖会自动安装。
|
|
54
|
+
|
|
55
|
+
## 配置 settings.json
|
|
56
|
+
|
|
57
|
+
首次使用前,需要填写模型服务地址、API 密钥和模型名称。请在以下位置创建或编辑 `settings.json`:
|
|
58
|
+
|
|
59
|
+
| 系统 | 配置文件位置 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Windows | `%USERPROFILE%\.autopilot\settings.json` |
|
|
62
|
+
| macOS | `~/.autopilot/settings.json` |
|
|
63
|
+
|
|
64
|
+
`.autopilot` 目录会随 Autopilot Cli首次启动自动创建,如果 `.autopilot` 目录不存在,可先自行创建。配置文件使用标准 JSON,不支持注释或末尾多余的逗号。按下面的示例填写即可,不添加 `schemaVersion` 字段。
|
|
65
|
+
|
|
66
|
+
### 使用 Anthropic 或兼容服务
|
|
67
|
+
|
|
68
|
+
如果服务支持 Anthropic Messages 协议,使用以下配置,将 `YOUR_API_KEY` 和 `YOUR_MODEL_ID` 替换为你的密钥和模型名称。使用兼容服务时,也需要替换服务地址。
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"env": {
|
|
73
|
+
"ANTHROPIC_BASE_URL": "https://api.anthropic.com",
|
|
74
|
+
"ANTHROPIC_API_KEY": "YOUR_API_KEY"
|
|
75
|
+
},
|
|
76
|
+
"model": "YOUR_MODEL_ID"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
如果服务要求使用 `ANTHROPIC_AUTH_TOKEN`,请用它替换 `ANTHROPIC_API_KEY`,不要同时填写两者。服务地址不要追加 `/v1/messages`,也不要包含用户名、密码、查询参数或 `#` 后的内容。
|
|
81
|
+
|
|
82
|
+
### 使用 OpenAI Chat Completions 兼容服务
|
|
83
|
+
|
|
84
|
+
如果服务支持 OpenAI Chat Completions 协议,使用下面的配置。替换密钥、`baseUrl` 和两处 `YOUR_MODEL_ID`;其余字段可以保留示例写法。
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"env": { "USER_SETTINGS_CUSTOM_API_KEY": "YOUR_API_KEY" },
|
|
89
|
+
"providerRoutes": {
|
|
90
|
+
"custom": {
|
|
91
|
+
"id": "custom",
|
|
92
|
+
"apiProtocol": "openai-chat-completions",
|
|
93
|
+
"baseUrl": "https://api.example.com/v1",
|
|
94
|
+
"credentialRef": { "provider": "custom", "key": "USER_SETTINGS_CUSTOM_API_KEY" },
|
|
95
|
+
"models": [{ "id": "YOUR_MODEL_ID" }]
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"model": "custom/YOUR_MODEL_ID"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
不要同时设置 `env.ANTHROPIC_MODEL`,以免覆盖这里选择的模型。
|
|
103
|
+
|
|
104
|
+
需要配置多个服务时,可以在 `providerRoutes` 中增加其他条目。每个条目的名称、`id` 和 `credentialRef.provider` 应一致;`credentialRef.key` 对应 `env` 中的密钥名称。`model` 使用 `服务名称/模型名称` 的形式,模型必须列在对应服务的 `models` 中。协议只支持 `anthropic-messages` 和 `openai-chat-completions`。
|
|
105
|
+
|
|
106
|
+
### 常用可选参数
|
|
107
|
+
|
|
108
|
+
| 字段 | 用途与写法 |
|
|
109
|
+
|---|---|
|
|
110
|
+
| `model` | 使用的模型名称,或上面示例中的 `服务名称/模型名称`;建议填写服务商提供的完整模型名称 |
|
|
111
|
+
| `availableModels` | 默认连接允许使用的模型列表,例如 `["MODEL_A", "MODEL_B"]`;不能为空、不能重复,当前模型也需要在列表中 |
|
|
112
|
+
| `effortLevel` | 思考强度,可选 `"low"`、`"medium"`、`"high"`,具体效果取决于模型支持情况 |
|
|
113
|
+
| `alwaysThinkingEnabled` | 是否启用思考,填写 `true` 或 `false`,不要加引号;需要模型支持 |
|
|
114
|
+
| `maxOutputTokens` | 单次输出的 token 上限,填写 1–1,000,000 的整数;不是上下文大小 |
|
|
115
|
+
| `env.API_TIMEOUT_MS` | 默认模型连接的请求超时,单位毫秒,填写 1,000–600,000 的整数字符串,例如 `"60000"` |
|
|
116
|
+
| `visionModel` | 图片分析使用的模型,填写已配置的 Chat Completions 服务中的 `服务名称/模型名称`;`false` 关闭,省略时使用主模型 |
|
|
117
|
+
| `webSearch` | `false` 关闭模型联网搜索;启用时需另行配置搜索服务 |
|
|
118
|
+
|
|
119
|
+
`env` 中的值都需要写成字符串。填写模型名称和密钥时,避免带入首尾空格或换行。建议通过顶层 `model` 和 `effortLevel` 设置模型与思考强度;`env.ANTHROPIC_MODEL` 和 `env.CLAUDE_CODE_EFFORT_LEVEL` 会覆盖对应设置。
|
|
120
|
+
|
|
121
|
+
服务地址、密钥、模型列表等连接设置请放在上面的个人配置文件中,不要把密钥提交到项目或版本控制。项目也可以提供 `.autopilot/settings.json` 和 `.autopilot/settings.local.json`,在你信任该项目后应用允许的设置;项目设置不能替换个人配置中的连接信息。
|
|
122
|
+
|
|
123
|
+
### 修改配置
|
|
124
|
+
|
|
125
|
+
直接编辑个人 `settings.json` 可以修改完整配置。简单配置也可以通过以下命令修改模型、思考强度和可用模型列表:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
ap config set model YOUR_MODEL_ID --scope user
|
|
129
|
+
ap config set effortLevel high --scope user
|
|
130
|
+
ap config set availableModels MODEL_A,MODEL_B --scope user
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
命令中的模型列表用逗号分隔,配置文件中则使用 JSON 数组。如果文件中配置了自定义服务的 `credentialRef`、`maxOutputTokens` 等字段,当前版本可能拒绝上述修改命令,请直接编辑文件。修改后用 `ap doctor` 检查配置。
|
|
134
|
+
|
|
135
|
+
## 开始使用
|
|
136
|
+
|
|
137
|
+
进入要处理的项目目录后运行:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
ap
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
首次打开项目时,按提示确认是否信任该项目。确认后,可以检查配置和模型连接:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
ap doctor
|
|
147
|
+
ap doctor --connectivity
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`ap doctor` 检查本地配置,`--connectivity` 还会联网检查模型服务。未信任项目时,部分检查会跳过。
|
|
151
|
+
|
|
152
|
+
`ap` 会进入交互模式,你可以直接输入需求。也可以提交一次任务:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
ap chat "分析当前项目结构,不修改文件"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
常用管理命令:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
ap session list
|
|
162
|
+
ap trust status
|
|
163
|
+
ap sandbox status
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
查看各命令的具体参数与限制:`ap --help`。更新和卸载:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm install -g autopilot-agent@latest
|
|
170
|
+
npm uninstall -g autopilot-agent
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
卸载后,个人配置和会话数据仍会保留。
|
|
174
|
+
|
|
175
|
+
## 当前限制
|
|
176
|
+
|
|
177
|
+
- 当前提供终端使用方式,暂不包含图形界面、内置浏览器预览、自动长期记忆或私有知识库搜索。
|
|
178
|
+
- 沙箱功能需要额外的平台支持,可通过 `ap doctor` 和 `ap sandbox status` 查看状态。MCP 工具默认在本机运行,不提供操作系统级隔离。
|
|
179
|
+
- Windows 后台任务的子进程可能无法全部停止;沙箱中的 MCP 工具也可能遇到输入无法转发的问题。需要可靠停止的长任务,建议先在测试项目中验证。
|
|
180
|
+
- macOS 尚未完成完整功能验证,Linux 暂未验证。模型服务的可用性、限额和费用以服务商为准。
|
|
181
|
+
- 当前为早期版本,处理重要项目时,请保留版本控制或备份。
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI TUI 活动状态与离散动画。
|
|
3
|
+
*
|
|
4
|
+
* 状态由安全事件类型归约得到,动画只消费显式状态和共享时钟;稳定文案始终
|
|
5
|
+
* 可见。活动 glyph 采用 Claude Code 的单字符 ping-pong 形式,不把状态包装成
|
|
6
|
+
* 调试风格的进度条。
|
|
7
|
+
*/
|
|
8
|
+
import { type ReactNode } from "react";
|
|
9
|
+
import type { CliTurnStatus } from "./types.js";
|
|
10
|
+
import type { TuiAnimationClock } from "./animation-clock.js";
|
|
11
|
+
export type CliActivityPhase = "requesting" | "thinking" | "waiting" | "transition" | "responding" | "stalled" | "terminal";
|
|
12
|
+
export interface CliActivityState {
|
|
13
|
+
phase: CliActivityPhase;
|
|
14
|
+
lastProgressAt: number;
|
|
15
|
+
transitionStartedAt?: number;
|
|
16
|
+
hasActiveTool: boolean;
|
|
17
|
+
stallable: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface CliActivityView {
|
|
20
|
+
phase: CliActivityPhase;
|
|
21
|
+
label: string;
|
|
22
|
+
frame: string;
|
|
23
|
+
}
|
|
24
|
+
interface CliActivityEventLike {
|
|
25
|
+
type: string;
|
|
26
|
+
}
|
|
27
|
+
export declare const CLI_ACTIVITY_STALLED_AFTER_MS = 20000;
|
|
28
|
+
export declare const CLI_ACTIVITY_TRANSITION_MS = 2000;
|
|
29
|
+
/** 与 CC SpinnerGlyph 一致,glyph 每 120ms 前进一格;共享时钟仍可用 50ms tick。 */
|
|
30
|
+
export declare const CLI_ACTIVITY_SPINNER_FRAME_MS = 120;
|
|
31
|
+
/** 创建一个等待 Provider 首个事件的初始活动状态。 */
|
|
32
|
+
export declare function createInitialCliActivityState(now: number): CliActivityState;
|
|
33
|
+
/** 按安全事件类型归约活动状态,不读取事件文案或模型原始输出。 */
|
|
34
|
+
export declare function reduceCliActivityState(previous: CliActivityState, event: CliActivityEventLike, now: number): CliActivityState;
|
|
35
|
+
/** 把投影终态映射为不会继续驱动动画的活动状态。 */
|
|
36
|
+
export declare function settleCliActivityState(previous: CliActivityState, status: CliTurnStatus, now: number): CliActivityState;
|
|
37
|
+
/** 返回指定活动阶段对应的单 glyph 帧;外层 Box 负责固定占位宽度。 */
|
|
38
|
+
export declare function getCliActivityFrame(phase: CliActivityPhase, now: number): string;
|
|
39
|
+
/** 根据当前时间解析过场、stalled 和审批等待,形成最终可见活动状态。 */
|
|
40
|
+
export declare function resolveCliActivityView(input: {
|
|
41
|
+
activity: CliActivityState;
|
|
42
|
+
status: CliTurnStatus;
|
|
43
|
+
now: number;
|
|
44
|
+
waitingForApproval?: boolean;
|
|
45
|
+
}): CliActivityView | undefined;
|
|
46
|
+
/** 渲染稳定活动文案和可选的固定宽度离散帧。 */
|
|
47
|
+
export declare function TuiActivityLine(props: {
|
|
48
|
+
activity: CliActivityState;
|
|
49
|
+
status: CliTurnStatus;
|
|
50
|
+
waitingForApproval: boolean;
|
|
51
|
+
useColor: boolean;
|
|
52
|
+
screenReader: boolean;
|
|
53
|
+
reducedMotion: boolean;
|
|
54
|
+
animationActive: boolean;
|
|
55
|
+
clock: TuiAnimationClock;
|
|
56
|
+
}): ReactNode;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* CLI TUI 活动状态与离散动画。
|
|
4
|
+
*
|
|
5
|
+
* 状态由安全事件类型归约得到,动画只消费显式状态和共享时钟;稳定文案始终
|
|
6
|
+
* 可见。活动 glyph 采用 Claude Code 的单字符 ping-pong 形式,不把状态包装成
|
|
7
|
+
* 调试风格的进度条。
|
|
8
|
+
*/
|
|
9
|
+
import { useEffect, useState } from "react";
|
|
10
|
+
import { Box, Text } from "ink";
|
|
11
|
+
export const CLI_ACTIVITY_STALLED_AFTER_MS = 20_000;
|
|
12
|
+
export const CLI_ACTIVITY_TRANSITION_MS = 2_000;
|
|
13
|
+
/** CC v2.1.88 的默认 spinner glyph;首尾重复保证 ping-pong 转向自然。 */
|
|
14
|
+
const CLI_ACTIVITY_SPINNER_FRAMES = ["·", "✢", "*", "✶", "✻", "✽", "✽", "✻", "✶", "*", "✢", "·"];
|
|
15
|
+
/** 与 CC SpinnerGlyph 一致,glyph 每 120ms 前进一格;共享时钟仍可用 50ms tick。 */
|
|
16
|
+
export const CLI_ACTIVITY_SPINNER_FRAME_MS = 120;
|
|
17
|
+
/** 创建一个等待 Provider 首个事件的初始活动状态。 */
|
|
18
|
+
export function createInitialCliActivityState(now) {
|
|
19
|
+
return {
|
|
20
|
+
phase: "requesting",
|
|
21
|
+
lastProgressAt: now,
|
|
22
|
+
hasActiveTool: false,
|
|
23
|
+
stallable: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** 将活动状态推进到指定稳定阶段,并记录本次可观察进展时间。 */
|
|
27
|
+
function advanceCliActivityState(previous, phase, now, options = {}) {
|
|
28
|
+
return {
|
|
29
|
+
...previous,
|
|
30
|
+
phase,
|
|
31
|
+
lastProgressAt: now,
|
|
32
|
+
hasActiveTool: options.hasActiveTool ?? previous.hasActiveTool,
|
|
33
|
+
stallable: options.stallable ?? previous.stallable,
|
|
34
|
+
transitionStartedAt: options.transitionStartedAt,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** 按安全事件类型归约活动状态,不读取事件文案或模型原始输出。 */
|
|
38
|
+
export function reduceCliActivityState(previous, event, now) {
|
|
39
|
+
switch (event.type) {
|
|
40
|
+
case "turn_started":
|
|
41
|
+
return createInitialCliActivityState(now);
|
|
42
|
+
case "reasoning_summary":
|
|
43
|
+
case "reasoning_hidden":
|
|
44
|
+
case "model_recovery":
|
|
45
|
+
case "context_overflow":
|
|
46
|
+
case "context_compact_started":
|
|
47
|
+
case "context_compacted":
|
|
48
|
+
return advanceCliActivityState(previous, "thinking", now, { hasActiveTool: false, stallable: true });
|
|
49
|
+
case "tool_started":
|
|
50
|
+
return advanceCliActivityState(previous, "transition", now, { hasActiveTool: true, stallable: false, transitionStartedAt: now });
|
|
51
|
+
case "tool_result":
|
|
52
|
+
return advanceCliActivityState(previous, "transition", now, { hasActiveTool: false, stallable: true, transitionStartedAt: now });
|
|
53
|
+
case "approval_required":
|
|
54
|
+
return advanceCliActivityState(previous, "waiting", now, { hasActiveTool: false, stallable: false });
|
|
55
|
+
case "answer_delta":
|
|
56
|
+
return advanceCliActivityState(previous, "responding", now, { hasActiveTool: false, stallable: true });
|
|
57
|
+
case "status":
|
|
58
|
+
return previous;
|
|
59
|
+
default:
|
|
60
|
+
return previous;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** 把投影终态映射为不会继续驱动动画的活动状态。 */
|
|
64
|
+
export function settleCliActivityState(previous, status, now) {
|
|
65
|
+
if (status === "idle" || status === "running" || status === "waiting_approval")
|
|
66
|
+
return previous;
|
|
67
|
+
return advanceCliActivityState(previous, "terminal", now, { hasActiveTool: false, stallable: false });
|
|
68
|
+
}
|
|
69
|
+
/** 返回指定活动阶段对应的单 glyph 帧;外层 Box 负责固定占位宽度。 */
|
|
70
|
+
export function getCliActivityFrame(phase, now) {
|
|
71
|
+
if (phase === "terminal")
|
|
72
|
+
return "";
|
|
73
|
+
return CLI_ACTIVITY_SPINNER_FRAMES[Math.floor(Math.max(0, now) / CLI_ACTIVITY_SPINNER_FRAME_MS) % CLI_ACTIVITY_SPINNER_FRAMES.length] ?? "·";
|
|
74
|
+
}
|
|
75
|
+
function formatCliActivityElapsed(durationMs) {
|
|
76
|
+
const totalSeconds = Math.max(1, Math.floor(Math.max(0, durationMs) / 1_000));
|
|
77
|
+
if (totalSeconds < 60)
|
|
78
|
+
return `${totalSeconds}s`;
|
|
79
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
80
|
+
const seconds = totalSeconds % 60;
|
|
81
|
+
if (minutes < 60)
|
|
82
|
+
return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
83
|
+
return `${Math.floor(minutes / 60)}h ${String(minutes % 60).padStart(2, "0")}m ${String(seconds).padStart(2, "0")}s`;
|
|
84
|
+
}
|
|
85
|
+
/** 返回活动阶段的稳定文案,供动画降级和 screen reader 使用。 */
|
|
86
|
+
function getCliActivityLabel(phase, input = {}) {
|
|
87
|
+
switch (phase) {
|
|
88
|
+
case "requesting": return "Preparing · waiting for first event";
|
|
89
|
+
case "thinking": return "Thinking · planning next step";
|
|
90
|
+
case "waiting": return input.hasActiveTool ? "Waiting · tool result" : "Waiting · provider response";
|
|
91
|
+
case "transition": return "Running action · starting tool";
|
|
92
|
+
case "responding": return "Answering · receiving output";
|
|
93
|
+
case "stalled": return `Still working · no new event for ${formatCliActivityElapsed(input.idleForMs ?? 0)}`;
|
|
94
|
+
case "terminal": return "Completed";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** 根据当前时间解析过场、stalled 和审批等待,形成最终可见活动状态。 */
|
|
98
|
+
export function resolveCliActivityView(input) {
|
|
99
|
+
const { activity, status, now } = input;
|
|
100
|
+
if (status === "idle")
|
|
101
|
+
return undefined;
|
|
102
|
+
if (status !== "running" && status !== "waiting_approval")
|
|
103
|
+
return { phase: "terminal", label: status, frame: "" };
|
|
104
|
+
if (input.waitingForApproval || status === "waiting_approval") {
|
|
105
|
+
return { phase: "waiting", label: "Waiting for approval", frame: getCliActivityFrame("waiting", now) };
|
|
106
|
+
}
|
|
107
|
+
let phase = activity.phase;
|
|
108
|
+
if (phase === "transition" && activity.transitionStartedAt !== undefined && now - activity.transitionStartedAt >= CLI_ACTIVITY_TRANSITION_MS) {
|
|
109
|
+
phase = activity.hasActiveTool ? "waiting" : "thinking";
|
|
110
|
+
}
|
|
111
|
+
if (activity.hasActiveTool && phase !== "transition")
|
|
112
|
+
phase = "waiting";
|
|
113
|
+
if (activity.stallable && !activity.hasActiveTool && phase !== "waiting" && now - activity.lastProgressAt >= CLI_ACTIVITY_STALLED_AFTER_MS) {
|
|
114
|
+
phase = "stalled";
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
phase,
|
|
118
|
+
label: getCliActivityLabel(phase, { idleForMs: Math.max(0, now - activity.lastProgressAt), hasActiveTool: activity.hasActiveTool }),
|
|
119
|
+
frame: getCliActivityFrame(phase, now),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** 渲染稳定活动文案和可选的固定宽度离散帧。 */
|
|
123
|
+
export function TuiActivityLine(props) {
|
|
124
|
+
const [clockTime, setClockTime] = useState(props.clock.now());
|
|
125
|
+
const view = resolveCliActivityView({ activity: props.activity, status: props.status, now: clockTime, waitingForApproval: props.waitingForApproval });
|
|
126
|
+
const shouldAnimate = props.animationActive && !props.screenReader && !props.reducedMotion && view !== undefined && view.phase !== "terminal";
|
|
127
|
+
useEffect(function subscribeActivityClock() {
|
|
128
|
+
props.clock.setActive(shouldAnimate);
|
|
129
|
+
if (!shouldAnimate) {
|
|
130
|
+
setClockTime(props.clock.now());
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
setClockTime(props.clock.now());
|
|
134
|
+
return props.clock.subscribe(function updateActivityClock(time) {
|
|
135
|
+
setClockTime(time);
|
|
136
|
+
});
|
|
137
|
+
}, [props.clock, shouldAnimate]);
|
|
138
|
+
if (!view)
|
|
139
|
+
return null;
|
|
140
|
+
if (view.phase === "terminal")
|
|
141
|
+
return null;
|
|
142
|
+
const frame = shouldAnimate ? view.frame : "·";
|
|
143
|
+
const isStalled = view.phase === "stalled";
|
|
144
|
+
return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { bold: isStalled, color: props.useColor ? "ansi256(208)" : undefined, children: frame }) }), _jsx(Text, { bold: isStalled, dimColor: props.useColor && !isStalled, children: view.label })] }));
|
|
145
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI TUI 共享动画时钟。
|
|
3
|
+
*
|
|
4
|
+
* 时钟只负责向订阅者发出当前时间,不持有任何业务状态;终端活动区不可见、
|
|
5
|
+
* screen reader、reduced-motion 或终态时可以停止订阅,测试也可以注入时间和调度器。
|
|
6
|
+
*/
|
|
7
|
+
export interface TuiAnimationClock {
|
|
8
|
+
now(): number;
|
|
9
|
+
subscribe(listener: (time: number) => void): () => void;
|
|
10
|
+
setActive(active: boolean): void;
|
|
11
|
+
tick(): void;
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
14
|
+
/** 共享时钟可注入的调度器配置,避免动画单测依赖真实 setInterval。 */
|
|
15
|
+
export interface TuiAnimationClockOptions {
|
|
16
|
+
now?: () => number;
|
|
17
|
+
frameMs?: number;
|
|
18
|
+
schedule?: (listener: () => void, frameMs: number) => unknown;
|
|
19
|
+
cancel?: (handle: unknown) => void;
|
|
20
|
+
}
|
|
21
|
+
/** 创建可暂停、可注入且只在有订阅者时运行的 TUI 时钟。 */
|
|
22
|
+
export declare function createTuiAnimationClock(options?: TuiAnimationClockOptions): TuiAnimationClock;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI TUI 共享动画时钟。
|
|
3
|
+
*
|
|
4
|
+
* 时钟只负责向订阅者发出当前时间,不持有任何业务状态;终端活动区不可见、
|
|
5
|
+
* screen reader、reduced-motion 或终态时可以停止订阅,测试也可以注入时间和调度器。
|
|
6
|
+
*/
|
|
7
|
+
/** 使用 Node 默认定时器启动一枚共享时钟任务。 */
|
|
8
|
+
function scheduleDefaultTimer(listener, frameMs) {
|
|
9
|
+
return setInterval(listener, frameMs);
|
|
10
|
+
}
|
|
11
|
+
/** 清理由 Node 默认定时器创建的共享时钟任务。 */
|
|
12
|
+
function cancelDefaultTimer(handle) {
|
|
13
|
+
clearInterval(handle);
|
|
14
|
+
}
|
|
15
|
+
/** 创建可暂停、可注入且只在有订阅者时运行的 TUI 时钟。 */
|
|
16
|
+
export function createTuiAnimationClock(options = {}) {
|
|
17
|
+
const now = options.now ?? function readCurrentTime() { return Date.now(); };
|
|
18
|
+
const frameMs = Math.max(16, options.frameMs ?? 50);
|
|
19
|
+
const schedule = options.schedule ?? scheduleDefaultTimer;
|
|
20
|
+
const cancel = options.cancel ?? cancelDefaultTimer;
|
|
21
|
+
const listeners = new Set();
|
|
22
|
+
let timer;
|
|
23
|
+
let active = true;
|
|
24
|
+
let disposed = false;
|
|
25
|
+
/** 停止当前定时器,确保没有订阅者或时钟暂停时不继续唤醒进程。 */
|
|
26
|
+
function stopTimer() {
|
|
27
|
+
if (timer === undefined)
|
|
28
|
+
return;
|
|
29
|
+
cancel(timer);
|
|
30
|
+
timer = undefined;
|
|
31
|
+
}
|
|
32
|
+
/** 根据订阅者和 active 状态启动唯一的共享定时器。 */
|
|
33
|
+
function ensureTimer() {
|
|
34
|
+
if (disposed || !active || listeners.size === 0 || timer !== undefined)
|
|
35
|
+
return;
|
|
36
|
+
timer = schedule(function emitScheduledTick() { clock.tick(); }, frameMs);
|
|
37
|
+
}
|
|
38
|
+
const clock = {
|
|
39
|
+
now,
|
|
40
|
+
subscribe(listener) {
|
|
41
|
+
if (disposed)
|
|
42
|
+
return function ignoreDisposedSubscription() { };
|
|
43
|
+
listeners.add(listener);
|
|
44
|
+
ensureTimer();
|
|
45
|
+
return function unsubscribe() {
|
|
46
|
+
listeners.delete(listener);
|
|
47
|
+
if (listeners.size === 0)
|
|
48
|
+
stopTimer();
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
setActive(nextActive) {
|
|
52
|
+
if (disposed || active === nextActive)
|
|
53
|
+
return;
|
|
54
|
+
active = nextActive;
|
|
55
|
+
if (!active)
|
|
56
|
+
stopTimer();
|
|
57
|
+
else
|
|
58
|
+
ensureTimer();
|
|
59
|
+
},
|
|
60
|
+
tick() {
|
|
61
|
+
if (disposed || !active)
|
|
62
|
+
return;
|
|
63
|
+
const time = now();
|
|
64
|
+
for (const listener of [...listeners])
|
|
65
|
+
listener(time);
|
|
66
|
+
},
|
|
67
|
+
dispose() {
|
|
68
|
+
if (disposed)
|
|
69
|
+
return;
|
|
70
|
+
disposed = true;
|
|
71
|
+
stopTimer();
|
|
72
|
+
listeners.clear();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return clock;
|
|
76
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Composition Root。
|
|
3
|
+
*
|
|
4
|
+
* 负责选择 Core 默认 Runtime、共享 Node Adapter、canonical workspaceRoot、
|
|
5
|
+
* trust policy 和显式 stateRoot;不负责命令解析、事件投影或 Runtime 状态机。
|
|
6
|
+
*/
|
|
7
|
+
import { type AgentRuntime, type CapabilityLoader, type CreateRuntimeBootstrapServiceOptions, type RuntimeBootstrapService, type SafeBootstrapConfig, type SandboxCapabilityReport, type WorkspaceTrustEntry, type WorkspaceTrustPolicy } from "@autopilot-agent/core";
|
|
8
|
+
import type { CliRuntimeStatusDefaults, CliSkillSummary } from "./types.js";
|
|
9
|
+
import { type WorkspaceRegistryEntry, type NodeCapabilityLoader, type NodeSettingsLoader } from "@autopilot-agent/adapters";
|
|
10
|
+
import type { AutopilotSettingsScope } from "@autopilot-agent/core";
|
|
11
|
+
/** Doctor 单项结果;只含状态和脱敏摘要,绝不包含路径、凭据或 Provider 正文。 */
|
|
12
|
+
export interface CliDoctorCheck {
|
|
13
|
+
name: string;
|
|
14
|
+
status: "PASS" | "WARN" | "FAIL" | "SKIP";
|
|
15
|
+
detail: string;
|
|
16
|
+
}
|
|
17
|
+
/** CLI Composition Root 的装配选项。 */
|
|
18
|
+
export interface CreateCliCompositionRootOptions {
|
|
19
|
+
config?: SafeBootstrapConfig;
|
|
20
|
+
stateRoot?: string;
|
|
21
|
+
trustRoot?: string;
|
|
22
|
+
workspaceRoot?: string;
|
|
23
|
+
cwd?: string;
|
|
24
|
+
env?: NodeJS.ProcessEnv;
|
|
25
|
+
trustPolicy?: WorkspaceTrustPolicy;
|
|
26
|
+
capabilityLoader?: CliCapabilityLoader;
|
|
27
|
+
defaultRunConfig?: CreateRuntimeBootstrapServiceOptions["defaultRunConfig"];
|
|
28
|
+
/** 已信任 settings Loader 的测试 seam;生产默认创建 Node Loader。 */
|
|
29
|
+
settingsLoader?: NodeSettingsLoader;
|
|
30
|
+
/** Doctor 连通性探测的测试 seam;生产默认使用全局 fetch。 */
|
|
31
|
+
connectivityFetch?: typeof fetch;
|
|
32
|
+
/** Web Search 请求的 fake HTTP 测试 seam;生产默认使用平台原生 fetch。 */
|
|
33
|
+
webSearchFetch?: typeof fetch;
|
|
34
|
+
}
|
|
35
|
+
/** CLI 能力加载器:沿用 Node 的开发能力,但禁止 RAG loader 进入 CLI 装配边界。 */
|
|
36
|
+
export type CliCapabilityLoader = CapabilityLoader & Partial<Pick<NodeCapabilityLoader, "probeWebSearchConnectivity">>;
|
|
37
|
+
/** CLI Composition Root 对外暴露的启动边界。 */
|
|
38
|
+
export interface CliCompositionRoot {
|
|
39
|
+
readonly stateRoot: string;
|
|
40
|
+
/** 仅由已解析的业务命令调用,保障当前用户配置根存在且安全。 */
|
|
41
|
+
ensureUserConfigDirectory(): void;
|
|
42
|
+
/** Trust 成功后创建当前项目的 .autopilot 与临时文件目录,不生成 settings 文件。 */
|
|
43
|
+
ensureProjectAutopilotDirectory(workspaceRoot: string): void;
|
|
44
|
+
establishTrust(): Promise<{
|
|
45
|
+
workspaceRoot: string;
|
|
46
|
+
trustEntry: WorkspaceTrustEntry;
|
|
47
|
+
}>;
|
|
48
|
+
/** Trust 前解析 canonical 工作区并读取信任状态;未信任时返回记录而不抛 WorkspaceTrustError。 */
|
|
49
|
+
resolveTrust(): Promise<{
|
|
50
|
+
workspaceRoot: string;
|
|
51
|
+
trustEntry: WorkspaceTrustEntry;
|
|
52
|
+
}>;
|
|
53
|
+
/** 授予精确 canonical 工作区信任并返回持久化后的记录。 */
|
|
54
|
+
grantTrust(workspaceRoot: string): Promise<WorkspaceTrustEntry>;
|
|
55
|
+
/** 读取指定工作区的当前信任状态。 */
|
|
56
|
+
getTrustStatus(workspaceRoot: string): Promise<WorkspaceTrustEntry>;
|
|
57
|
+
/** 撤销当前 canonical workspace 的 Trust;调用后不得继续创建 Runtime。 */
|
|
58
|
+
revokeTrust(workspaceRoot: string): Promise<WorkspaceTrustEntry>;
|
|
59
|
+
/** 读取宿主级工作区索引;不会扫描磁盘或创建状态根。 */
|
|
60
|
+
listWorkspaceRegistry(): WorkspaceRegistryEntry[];
|
|
61
|
+
/** 仅注销 Registry 索引条目,不删除任何工作区数据。 */
|
|
62
|
+
removeWorkspaceRegistry(workspaceId: string): boolean;
|
|
63
|
+
/** 读取显式 scope 的脱敏 settings。 */
|
|
64
|
+
showConfig(scope: AutopilotSettingsScope, workspaceRoot: string): Record<string, unknown>;
|
|
65
|
+
/** 读取显式 scope 下允许公开的单个 settings 值。 */
|
|
66
|
+
getConfig(scope: AutopilotSettingsScope, key: string, workspaceRoot: string): unknown;
|
|
67
|
+
/** 写入显式 scope 下允许公开的单个 settings 值。 */
|
|
68
|
+
setConfig(scope: AutopilotSettingsScope, key: string, value: string, workspaceRoot: string): Record<string, unknown>;
|
|
69
|
+
/** 执行默认离线或显式受限连通性 Doctor 检查。 */
|
|
70
|
+
doctor(workspaceRoot: string, connectivity: boolean): Promise<CliDoctorCheck[]>;
|
|
71
|
+
/** 读取当前平台沙箱能力报告(脱敏);绑定传入的 canonical workspace。 */
|
|
72
|
+
sandboxStatus(workspaceRoot: string): Promise<SandboxCapabilityReport>;
|
|
73
|
+
/** 显式触发沙箱 setup(Windows UAC 安装;macOS 仅返回当前能力报告)。 */
|
|
74
|
+
sandboxSetup(workspaceRoot: string): Promise<SandboxCapabilityReport>;
|
|
75
|
+
createRuntime(workspaceRoot: string): Promise<AgentRuntime>;
|
|
76
|
+
bootstrap(): Promise<AgentRuntime>;
|
|
77
|
+
getBootstrapService(): RuntimeBootstrapService;
|
|
78
|
+
/** 只向 Controller 暴露可安全显示的已热更新 settings 默认值。 */
|
|
79
|
+
getRuntimeStatusDefaults(): CliRuntimeStatusDefaults;
|
|
80
|
+
/** 返回不含凭据的首次运行配置诊断;undefined 表示可继续启动。 */
|
|
81
|
+
getStartupConfigurationError(): string | undefined;
|
|
82
|
+
listSkills(): Promise<CliSkillSummary[]>;
|
|
83
|
+
resolveSkill(skill: string): Promise<{
|
|
84
|
+
skillId: string;
|
|
85
|
+
contentHash: string;
|
|
86
|
+
}>;
|
|
87
|
+
/** 返回不含环境变量的 MCP server 审批摘要与执行隔离事实。 */
|
|
88
|
+
listMcp(workspaceRoot: string): Promise<Array<{
|
|
89
|
+
serverName: string;
|
|
90
|
+
program: string;
|
|
91
|
+
args: string[];
|
|
92
|
+
cwd: string;
|
|
93
|
+
approved: boolean;
|
|
94
|
+
executionMode: "sandbox" | "host";
|
|
95
|
+
isolation: "sandboxed" | "unisolated";
|
|
96
|
+
}>>;
|
|
97
|
+
/** 保存精确 configHash 绑定的 workspace grant;调用方必须已完成 CLI 确认。 */
|
|
98
|
+
approveMcp(workspaceRoot: string, serverName: string): Promise<{
|
|
99
|
+
serverName: string;
|
|
100
|
+
}>;
|
|
101
|
+
/** 删除 server 当前 configHash 对应的 workspace grant。 */
|
|
102
|
+
revokeMcp(workspaceRoot: string, serverName: string): Promise<boolean>;
|
|
103
|
+
}
|
|
104
|
+
/** 创建 CLI Composition Root;只有 Runtime bootstrap 的 trust 成功阶段才初始化状态 manifest。 */
|
|
105
|
+
export declare function createCliCompositionRoot(options?: CreateCliCompositionRootOptions): CliCompositionRoot;
|