@armadra/agent 0.6.8 → 0.7.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/CHANGELOG.md +61 -0
- package/CHANGELOG.zh-CN.md +43 -0
- package/README.md +4 -3
- package/README.zh-CN.md +1 -1
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +2 -2
- package/dist/ai/apis/shared.d.ts +7 -1
- package/dist/ai/apis/shared.js +10 -0
- package/dist/ai/fake/fake-provider.js +5 -1
- package/dist/ai/fake/fake-script.d.ts +5 -2
- package/dist/ai/fake/fake-script.js +6 -2
- package/dist/ai/types.d.ts +2 -1
- package/dist/bundle/ama.cjs +48757 -47456
- package/dist/cli/args.d.ts +6 -0
- package/dist/cli/args.js +46 -0
- package/dist/cli/bootstrap.js +13 -2
- package/dist/cli/compose-events.d.ts +10 -0
- package/dist/cli/compose-events.js +97 -0
- package/dist/cli/compose-session.d.ts +25 -4
- package/dist/cli/compose-session.js +130 -103
- package/dist/cli/compose.js +6 -1
- package/dist/cli/runtime.d.ts +3 -1
- package/dist/cli/subcommands/auth.d.ts +13 -1
- package/dist/cli/subcommands/auth.js +28 -1
- package/dist/drivers/acp/client.d.ts +7 -2
- package/dist/drivers/acp/client.js +10 -1
- package/dist/drivers/acp/driver.d.ts +15 -4
- package/dist/drivers/acp/driver.js +110 -33
- package/dist/drivers/acp/testing/fake-agent-main.d.ts +1 -1
- package/dist/drivers/acp/testing/fake-agent-main.js +9 -2
- package/dist/drivers/acp/testing/fake-agent.d.ts +17 -2
- package/dist/drivers/acp/testing/fake-agent.js +108 -25
- package/dist/drivers/acp/types.d.ts +76 -12
- package/dist/drivers/acp/types.js +11 -3
- package/dist/drivers/jsonrpc.d.ts +13 -3
- package/dist/drivers/jsonrpc.js +40 -7
- package/dist/drivers/turn.d.ts +15 -2
- package/dist/drivers/turn.js +33 -4
- package/dist/i18n/catalog.d.ts +59 -16
- package/dist/i18n/catalog.js +4 -1
- package/dist/i18n/messages/acp.d.ts +125 -0
- package/dist/i18n/messages/acp.js +126 -0
- package/dist/i18n/messages/auth.d.ts +2 -0
- package/dist/i18n/messages/auth.js +4 -2
- package/dist/i18n/messages/cli-args.d.ts +2 -0
- package/dist/i18n/messages/cli-args.js +2 -0
- package/dist/i18n/messages/cli.d.ts +4 -0
- package/dist/i18n/messages/cli.js +2 -0
- package/dist/i18n/messages/print.d.ts +3 -33
- package/dist/i18n/messages/print.js +3 -33
- package/dist/modes/acp/acp-auth-gate.d.ts +40 -0
- package/dist/modes/acp/acp-auth-gate.js +201 -0
- package/dist/modes/acp/acp-config.d.ts +43 -0
- package/dist/modes/acp/acp-config.js +151 -0
- package/dist/modes/acp/acp-connection.d.ts +29 -0
- package/dist/modes/acp/acp-connection.js +37 -0
- package/dist/modes/acp/acp-events.d.ts +59 -23
- package/dist/modes/acp/acp-events.js +154 -88
- package/dist/modes/acp/acp-mode.d.ts +13 -2
- package/dist/modes/acp/acp-mode.js +23 -8
- package/dist/modes/acp/acp-server.d.ts +59 -32
- package/dist/modes/acp/acp-server.js +322 -128
- package/dist/modes/acp/acp-sessions.d.ts +80 -0
- package/dist/modes/acp/acp-sessions.js +157 -0
- package/dist/modes/acp/acp-tool-text.d.ts +23 -0
- package/dist/modes/acp/acp-tool-text.js +83 -0
- package/dist/modes/print/json-event.d.ts +2 -1
- package/dist/modes/print/json-event.js +6 -1
- package/dist/tools/edit.d.ts +6 -2
- package/dist/tools/edit.js +19 -2
- package/dist/tools/types.d.ts +11 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/write.d.ts +1 -0
- package/dist/tools/write.js +21 -3
- package/docs/acp.md +143 -29
- package/docs/agents.md +2 -0
- package/docs/codemode.md +1 -1
- package/docs/en/acp.md +192 -0
- package/package.json +1 -1
package/dist/drivers/turn.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* 一个回合的结果汇总(各驱动共用)。[W5-E]
|
|
3
3
|
*
|
|
4
4
|
* 驱动把归一化后的 {@link DriverEvent} 交给收集器:它转发给 `onEvent`,同时累计最终文本、
|
|
5
|
-
* 工具摘要(≤ 20 行,§5.2)、触及的文件(edit / delete / move 类工具的 locations
|
|
5
|
+
* 工具摘要(≤ 20 行,§5.2)、触及的文件(edit / delete / move 类工具的 locations,以及带 diff 内容的
|
|
6
|
+
* 工具改动的路径——不论种类,见 {@link TurnCollector.noteDiff})与用量。
|
|
6
7
|
* 原始事件只在内存里流过,不落盘(§5.4 敏感数据)。
|
|
7
8
|
*/
|
|
8
9
|
export const TOOL_SUMMARY_LINES = 20;
|
|
@@ -16,7 +17,10 @@ export class TurnCollector {
|
|
|
16
17
|
constructor(onEvent) {
|
|
17
18
|
this.onEvent = onEvent;
|
|
18
19
|
}
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* 归一化事件:累计后转发给 onEvent。同一工具调用回到已报过的状态(如审批前后
|
|
22
|
+
* `in_progress → pending → in_progress`)且标题、种类、位置都没变时不再转发,免得下游重复报进度。
|
|
23
|
+
*/
|
|
20
24
|
push(event) {
|
|
21
25
|
switch (event.type) {
|
|
22
26
|
case "message_delta":
|
|
@@ -29,10 +33,20 @@ export class TurnCollector {
|
|
|
29
33
|
kind: event.kind,
|
|
30
34
|
status: event.status,
|
|
31
35
|
locations: event.locations ?? known?.locations ?? [],
|
|
36
|
+
...(known?.diffPaths !== undefined ? { diffPaths: known.diffPaths } : {}),
|
|
37
|
+
reported: known?.reported ?? new Set(),
|
|
32
38
|
};
|
|
33
39
|
if (known === undefined)
|
|
34
40
|
this.order.push(event.id);
|
|
35
41
|
this.tools.set(event.id, next);
|
|
42
|
+
const repeat = known !== undefined &&
|
|
43
|
+
next.reported.has(event.status) &&
|
|
44
|
+
next.title === known.title &&
|
|
45
|
+
next.kind === known.kind &&
|
|
46
|
+
next.locations.join("\n") === known.locations.join("\n");
|
|
47
|
+
if (repeat)
|
|
48
|
+
return;
|
|
49
|
+
next.reported.add(event.status);
|
|
36
50
|
break;
|
|
37
51
|
}
|
|
38
52
|
case "usage":
|
|
@@ -43,6 +57,16 @@ export class TurnCollector {
|
|
|
43
57
|
}
|
|
44
58
|
this.onEvent(event);
|
|
45
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* 记下工具改动的文件(diff 内容的路径):工具完成后计入 filesTouched,不论它报的种类。
|
|
62
|
+
* 在 `push` 该工具的 `tool_call` 之后调(未知的 id 忽略)。[ACP-D]
|
|
63
|
+
*/
|
|
64
|
+
noteDiff(id, paths) {
|
|
65
|
+
const known = this.tools.get(id);
|
|
66
|
+
if (known === undefined || paths.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
known.diffPaths = [...new Set([...(known.diffPaths ?? []), ...paths])];
|
|
69
|
+
}
|
|
46
70
|
/** 工具调用的最近状态(驱动做 tool_call_update 时补全标题与种类)。 */
|
|
47
71
|
tool(id) {
|
|
48
72
|
return this.tools.get(id);
|
|
@@ -67,10 +91,15 @@ export class TurnCollector {
|
|
|
67
91
|
}
|
|
68
92
|
result(stopReason) {
|
|
69
93
|
const files = new Set();
|
|
70
|
-
for (const tool of this.tools.values())
|
|
71
|
-
if (
|
|
94
|
+
for (const tool of this.tools.values()) {
|
|
95
|
+
if (tool.status !== "completed")
|
|
96
|
+
continue;
|
|
97
|
+
if (WRITE_KINDS.has(tool.kind))
|
|
72
98
|
for (const path of tool.locations)
|
|
73
99
|
files.add(path);
|
|
100
|
+
for (const path of tool.diffPaths ?? [])
|
|
101
|
+
files.add(path);
|
|
102
|
+
}
|
|
74
103
|
const lines = this.order.map((id) => {
|
|
75
104
|
const tool = this.tools.get(id);
|
|
76
105
|
return `${tool.status === "failed" ? "✗" : tool.status === "completed" ? "✓" : "…"} ${tool.kind} ${tool.title}`;
|
package/dist/i18n/catalog.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 领域 → 所有者:cli / subcommands(I1);interactive / approval / plan / rewind / panels / permissions(I2);
|
|
6
6
|
* report / print / drivers / session / errors(I3);config(I4);agents(A);trace(T1 / T2);
|
|
7
|
-
* memory(M);auth(O);settings(S)。
|
|
7
|
+
* memory(M);auth(O);settings(S);acp(ACP-C0 新增,docs/acp-plan.md D15)。
|
|
8
8
|
*/
|
|
9
9
|
import type { Messages } from "./types.js";
|
|
10
10
|
import * as rewind from "./messages/rewind.js";
|
|
@@ -16,6 +16,7 @@ declare const en: {
|
|
|
16
16
|
flagsConflict: (flags: readonly string[]) => string;
|
|
17
17
|
invalidChoice: (option: string, choices: readonly string[], got: string) => string;
|
|
18
18
|
emptyValue: (option: string) => string;
|
|
19
|
+
unknownTerminalAuth: (id: string) => string;
|
|
19
20
|
fullscreenUnsupported: string;
|
|
20
21
|
maxTurnsPositive: (got: string) => string;
|
|
21
22
|
maxCostPositive: (got: string) => string;
|
|
@@ -162,6 +163,7 @@ declare const en: {
|
|
|
162
163
|
appendToolFailed: (name: string, message: string) => string;
|
|
163
164
|
notComposed: string;
|
|
164
165
|
switchWhileStreaming: string;
|
|
166
|
+
notLiveSession: string;
|
|
165
167
|
};
|
|
166
168
|
composeStore: {
|
|
167
169
|
ambiguousId: (id: string, candidates: readonly string[]) => string;
|
|
@@ -1279,21 +1281,6 @@ declare const en: {
|
|
|
1279
1281
|
noPlan: string;
|
|
1280
1282
|
badMode: (modes: readonly string[]) => string;
|
|
1281
1283
|
};
|
|
1282
|
-
acp: {
|
|
1283
|
-
missingParam: (key: string) => string;
|
|
1284
|
-
promptNotArray: string;
|
|
1285
|
-
unparsable: (reason: string) => string;
|
|
1286
|
-
missingProtocolVersion: string;
|
|
1287
|
-
fixedCwd: (cwd: string, got: string) => string;
|
|
1288
|
-
sessionNotFound: (id: string, error: string) => string;
|
|
1289
|
-
busy: string;
|
|
1290
|
-
modelFailed: string;
|
|
1291
|
-
unknownMode: (mode: string) => string;
|
|
1292
|
-
allowOnce: string;
|
|
1293
|
-
allowAlways: string;
|
|
1294
|
-
rejectOnce: string;
|
|
1295
|
-
truncated: (length: number) => string;
|
|
1296
|
-
};
|
|
1297
1284
|
};
|
|
1298
1285
|
config: {
|
|
1299
1286
|
keys: {
|
|
@@ -1995,6 +1982,7 @@ declare const en: {
|
|
|
1995
1982
|
unknownAction: (action: string) => string;
|
|
1996
1983
|
setPrompt: (provider: string) => string;
|
|
1997
1984
|
noKeyFromStdin: string;
|
|
1985
|
+
pickProvider: string;
|
|
1998
1986
|
saved: (provider: string, path: string) => string;
|
|
1999
1987
|
warning: (text: string) => string;
|
|
2000
1988
|
listEmpty: (path: string) => string;
|
|
@@ -2255,6 +2243,61 @@ declare const en: {
|
|
|
2255
2243
|
missingValue: string;
|
|
2256
2244
|
};
|
|
2257
2245
|
};
|
|
2246
|
+
acp: {
|
|
2247
|
+
core: {
|
|
2248
|
+
missingParam: (key: string) => string;
|
|
2249
|
+
promptNotArray: string;
|
|
2250
|
+
unparsable: (reason: string) => string;
|
|
2251
|
+
missingProtocolVersion: string;
|
|
2252
|
+
fixedCwd: (cwd: string, got: string) => string;
|
|
2253
|
+
sessionNotFound: (id: string, error: string) => string;
|
|
2254
|
+
modelFailed: string;
|
|
2255
|
+
unknownMode: (mode: string) => string;
|
|
2256
|
+
allowOnce: string;
|
|
2257
|
+
allowAlways: string;
|
|
2258
|
+
rejectOnce: string;
|
|
2259
|
+
unknownConfigOption: (id: string) => string;
|
|
2260
|
+
};
|
|
2261
|
+
auth: {
|
|
2262
|
+
chatgptName: string;
|
|
2263
|
+
chatgptDescription: string;
|
|
2264
|
+
apiKeyName: string;
|
|
2265
|
+
apiKeyDescription: string;
|
|
2266
|
+
notAgentMethod: string;
|
|
2267
|
+
waiting: (reason: string) => string;
|
|
2268
|
+
ready: (model: string) => string;
|
|
2269
|
+
};
|
|
2270
|
+
session: {
|
|
2271
|
+
notOpen: (id: string) => string;
|
|
2272
|
+
invalidCursor: string;
|
|
2273
|
+
ignoredMcp: (count: number) => string;
|
|
2274
|
+
ignoredDirs: (count: number) => string;
|
|
2275
|
+
};
|
|
2276
|
+
tools: {
|
|
2277
|
+
codemodePrefix: (title: string) => string;
|
|
2278
|
+
truncated: (length: number) => string;
|
|
2279
|
+
};
|
|
2280
|
+
config: {
|
|
2281
|
+
model: string;
|
|
2282
|
+
mode: string;
|
|
2283
|
+
thinking: string;
|
|
2284
|
+
levels: {
|
|
2285
|
+
off: string;
|
|
2286
|
+
minimal: string;
|
|
2287
|
+
low: string;
|
|
2288
|
+
medium: string;
|
|
2289
|
+
high: string;
|
|
2290
|
+
xhigh: string;
|
|
2291
|
+
};
|
|
2292
|
+
invalidValue: (id: string, value: string) => string;
|
|
2293
|
+
unknownModel: (ref: string) => string;
|
|
2294
|
+
};
|
|
2295
|
+
client: {
|
|
2296
|
+
authRequired: (agent: string, methods: readonly string[]) => string;
|
|
2297
|
+
authNoMethods: (agent: string) => string;
|
|
2298
|
+
authTerminal: (name: string, command: string) => string;
|
|
2299
|
+
};
|
|
2300
|
+
};
|
|
2258
2301
|
};
|
|
2259
2302
|
/** 运行期取用的目录形状:en 的形状、叶子放宽为 string / 同签名函数。 */
|
|
2260
2303
|
export type Catalog = Messages<typeof en>;
|
package/dist/i18n/catalog.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 领域 → 所有者:cli / subcommands(I1);interactive / approval / plan / rewind / panels / permissions(I2);
|
|
6
6
|
* report / print / drivers / session / errors(I3);config(I4);agents(A);trace(T1 / T2);
|
|
7
|
-
* memory(M);auth(O);settings(S)。
|
|
7
|
+
* memory(M);auth(O);settings(S);acp(ACP-C0 新增,docs/acp-plan.md D15)。
|
|
8
8
|
*/
|
|
9
9
|
import * as cli from "./messages/cli.js";
|
|
10
10
|
import * as subcommands from "./messages/subcommands.js";
|
|
@@ -25,6 +25,7 @@ import * as trace from "./messages/trace.js";
|
|
|
25
25
|
import * as memory from "./messages/memory.js";
|
|
26
26
|
import * as auth from "./messages/auth.js";
|
|
27
27
|
import * as settings from "./messages/settings.js";
|
|
28
|
+
import * as acp from "./messages/acp.js";
|
|
28
29
|
const en = {
|
|
29
30
|
cli: cli.en,
|
|
30
31
|
subcommands: subcommands.en,
|
|
@@ -45,6 +46,7 @@ const en = {
|
|
|
45
46
|
memory: memory.en,
|
|
46
47
|
auth: auth.en,
|
|
47
48
|
settings: settings.en,
|
|
49
|
+
acp: acp.en,
|
|
48
50
|
};
|
|
49
51
|
const zh = {
|
|
50
52
|
cli: cli.zh,
|
|
@@ -66,6 +68,7 @@ const zh = {
|
|
|
66
68
|
memory: memory.zh,
|
|
67
69
|
auth: auth.zh,
|
|
68
70
|
settings: settings.zh,
|
|
71
|
+
acp: acp.zh,
|
|
69
72
|
};
|
|
70
73
|
export const CATALOGS = { en, zh };
|
|
71
74
|
/** 领域名(一级命名空间)。 */
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 消息目录:acp(键名规范见 docs/i18n.md)。[ACP-C0 从 print.acp 迁入,docs/acp-plan.md D15]
|
|
3
|
+
*
|
|
4
|
+
* en 是形状源;zh 用 `satisfies Messages<typeof en>`,缺键 / 多键 / 参数不符在 tsc 期报错。
|
|
5
|
+
* 整句一个键、禁止片段拼接;插值写成函数,条件分支写进函数体。
|
|
6
|
+
* 发给 ACP 客户端的 name / description / error message 是给人看的,走这里;`_meta`、id、value 等机器字段不翻译。
|
|
7
|
+
* 子对象各归一个批次:core(现有服务端文案)、auth(A)、session(B)、tools(C)、config / client(D)。
|
|
8
|
+
*/
|
|
9
|
+
export declare const en: {
|
|
10
|
+
/** ACP 服务端(`ama --mode acp`)的现有文案。 */
|
|
11
|
+
core: {
|
|
12
|
+
missingParam: (key: string) => string;
|
|
13
|
+
promptNotArray: string;
|
|
14
|
+
unparsable: (reason: string) => string;
|
|
15
|
+
missingProtocolVersion: string;
|
|
16
|
+
fixedCwd: (cwd: string, got: string) => string;
|
|
17
|
+
sessionNotFound: (id: string, error: string) => string;
|
|
18
|
+
modelFailed: string;
|
|
19
|
+
unknownMode: (mode: string) => string;
|
|
20
|
+
allowOnce: string;
|
|
21
|
+
allowAlways: string;
|
|
22
|
+
rejectOnce: string;
|
|
23
|
+
unknownConfigOption: (id: string) => string;
|
|
24
|
+
};
|
|
25
|
+
/** [ACP-A] 认证门与终端认证方法。 */
|
|
26
|
+
auth: {
|
|
27
|
+
chatgptName: string;
|
|
28
|
+
chatgptDescription: string;
|
|
29
|
+
apiKeyName: string;
|
|
30
|
+
apiKeyDescription: string;
|
|
31
|
+
notAgentMethod: string;
|
|
32
|
+
waiting: (reason: string) => string;
|
|
33
|
+
ready: (model: string) => string;
|
|
34
|
+
};
|
|
35
|
+
/** [ACP-B] 多会话与会话元数据。 */
|
|
36
|
+
session: {
|
|
37
|
+
notOpen: (id: string) => string;
|
|
38
|
+
invalidCursor: string;
|
|
39
|
+
ignoredMcp: (count: number) => string;
|
|
40
|
+
ignoredDirs: (count: number) => string;
|
|
41
|
+
};
|
|
42
|
+
/** [ACP-C] 工具调用映射。 */
|
|
43
|
+
tools: {
|
|
44
|
+
/** codemode 脚本里的内层调用的标题。 */
|
|
45
|
+
codemodePrefix: (title: string) => string;
|
|
46
|
+
truncated: (length: number) => string;
|
|
47
|
+
};
|
|
48
|
+
/** [ACP-D] 配置项与命令表。 */
|
|
49
|
+
config: {
|
|
50
|
+
model: string;
|
|
51
|
+
mode: string;
|
|
52
|
+
thinking: string;
|
|
53
|
+
levels: {
|
|
54
|
+
off: string;
|
|
55
|
+
minimal: string;
|
|
56
|
+
low: string;
|
|
57
|
+
medium: string;
|
|
58
|
+
high: string;
|
|
59
|
+
xhigh: string;
|
|
60
|
+
};
|
|
61
|
+
invalidValue: (id: string, value: string) => string;
|
|
62
|
+
unknownModel: (ref: string) => string;
|
|
63
|
+
};
|
|
64
|
+
/** [ACP-D] ama 作 ACP 客户端时的文案。 */
|
|
65
|
+
client: {
|
|
66
|
+
authRequired: (agent: string, methods: readonly string[]) => string;
|
|
67
|
+
authNoMethods: (agent: string) => string;
|
|
68
|
+
authTerminal: (name: string, command: string) => string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export declare const zh: {
|
|
72
|
+
core: {
|
|
73
|
+
missingParam: (key: string) => string;
|
|
74
|
+
promptNotArray: string;
|
|
75
|
+
unparsable: (reason: string) => string;
|
|
76
|
+
missingProtocolVersion: string;
|
|
77
|
+
fixedCwd: (cwd: string, got: string) => string;
|
|
78
|
+
sessionNotFound: (id: string, error: string) => string;
|
|
79
|
+
modelFailed: string;
|
|
80
|
+
unknownMode: (mode: string) => string;
|
|
81
|
+
allowOnce: string;
|
|
82
|
+
allowAlways: string;
|
|
83
|
+
rejectOnce: string;
|
|
84
|
+
unknownConfigOption: (id: string) => string;
|
|
85
|
+
};
|
|
86
|
+
auth: {
|
|
87
|
+
chatgptName: string;
|
|
88
|
+
chatgptDescription: string;
|
|
89
|
+
apiKeyName: string;
|
|
90
|
+
apiKeyDescription: string;
|
|
91
|
+
notAgentMethod: string;
|
|
92
|
+
waiting: (reason: string) => string;
|
|
93
|
+
ready: (model: string) => string;
|
|
94
|
+
};
|
|
95
|
+
session: {
|
|
96
|
+
notOpen: (id: string) => string;
|
|
97
|
+
invalidCursor: string;
|
|
98
|
+
ignoredMcp: (count: number) => string;
|
|
99
|
+
ignoredDirs: (count: number) => string;
|
|
100
|
+
};
|
|
101
|
+
tools: {
|
|
102
|
+
codemodePrefix: (title: string) => string;
|
|
103
|
+
truncated: (length: number) => string;
|
|
104
|
+
};
|
|
105
|
+
config: {
|
|
106
|
+
model: string;
|
|
107
|
+
mode: string;
|
|
108
|
+
thinking: string;
|
|
109
|
+
levels: {
|
|
110
|
+
off: string;
|
|
111
|
+
minimal: string;
|
|
112
|
+
low: string;
|
|
113
|
+
medium: string;
|
|
114
|
+
high: string;
|
|
115
|
+
xhigh: string;
|
|
116
|
+
};
|
|
117
|
+
invalidValue: (id: string, value: string) => string;
|
|
118
|
+
unknownModel: (ref: string) => string;
|
|
119
|
+
};
|
|
120
|
+
client: {
|
|
121
|
+
authRequired: (agent: string, methods: readonly string[]) => string;
|
|
122
|
+
authNoMethods: (agent: string) => string;
|
|
123
|
+
authTerminal: (name: string, command: string) => string;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 消息目录:acp(键名规范见 docs/i18n.md)。[ACP-C0 从 print.acp 迁入,docs/acp-plan.md D15]
|
|
3
|
+
*
|
|
4
|
+
* en 是形状源;zh 用 `satisfies Messages<typeof en>`,缺键 / 多键 / 参数不符在 tsc 期报错。
|
|
5
|
+
* 整句一个键、禁止片段拼接;插值写成函数,条件分支写进函数体。
|
|
6
|
+
* 发给 ACP 客户端的 name / description / error message 是给人看的,走这里;`_meta`、id、value 等机器字段不翻译。
|
|
7
|
+
* 子对象各归一个批次:core(现有服务端文案)、auth(A)、session(B)、tools(C)、config / client(D)。
|
|
8
|
+
*/
|
|
9
|
+
import { plural } from "../format.js";
|
|
10
|
+
export const en = {
|
|
11
|
+
/** ACP 服务端(`ama --mode acp`)的现有文案。 */
|
|
12
|
+
core: {
|
|
13
|
+
missingParam: (key) => `missing ${key}`,
|
|
14
|
+
promptNotArray: "prompt must be an array of content blocks",
|
|
15
|
+
unparsable: (reason) => `ACP: unparsable input (${reason})`,
|
|
16
|
+
missingProtocolVersion: "missing protocolVersion",
|
|
17
|
+
fixedCwd: (cwd, got) => `the session directory of ama --mode acp is fixed to the start directory ${cwd} (got ${got})`,
|
|
18
|
+
sessionNotFound: (id, error) => `session ${id} not found: ${error}`,
|
|
19
|
+
modelFailed: "model request failed",
|
|
20
|
+
unknownMode: (mode) => `unknown mode: ${mode}`,
|
|
21
|
+
allowOnce: "Allow",
|
|
22
|
+
allowAlways: "Allow for this session",
|
|
23
|
+
rejectOnce: "Deny",
|
|
24
|
+
unknownConfigOption: (id) => `unknown config option: ${id}`,
|
|
25
|
+
},
|
|
26
|
+
/** [ACP-A] 认证门与终端认证方法。 */
|
|
27
|
+
auth: {
|
|
28
|
+
chatgptName: "Sign in with ChatGPT",
|
|
29
|
+
chatgptDescription: "Runs ama auth login chatgpt in a terminal (ChatGPT subscription)",
|
|
30
|
+
apiKeyName: "Enter an API key",
|
|
31
|
+
apiKeyDescription: "Runs ama auth set in a terminal: pick a provider, then paste its API key",
|
|
32
|
+
notAgentMethod: "ama only offers terminal auth methods, which are not passed to authenticate; run the method in a terminal",
|
|
33
|
+
waiting: (reason) => `no model available yet (${reason}); ACP stays up — sign in from the client's terminal login or run ama auth set, then open a session again`,
|
|
34
|
+
ready: (model) => `model available (${model}); ACP sessions are served from now on`,
|
|
35
|
+
},
|
|
36
|
+
/** [ACP-B] 多会话与会话元数据。 */
|
|
37
|
+
session: {
|
|
38
|
+
notOpen: (id) => `session ${id} is not open in this connection; send session/load or session/resume first`,
|
|
39
|
+
invalidCursor: "invalid cursor (pass back the nextCursor of a previous session/list)",
|
|
40
|
+
ignoredMcp: (count) => `ACP: ignoring ${plural(count, "MCP server")} from the client (ama does not connect MCP servers)`,
|
|
41
|
+
ignoredDirs: (count) => `ACP: ignoring ${plural(count, "additional directory", "additional directories")} from the client (the workspace is fixed to the start directory)`,
|
|
42
|
+
},
|
|
43
|
+
/** [ACP-C] 工具调用映射。 */
|
|
44
|
+
tools: {
|
|
45
|
+
/** codemode 脚本里的内层调用的标题。 */
|
|
46
|
+
codemodePrefix: (title) => `codemode › ${title}`,
|
|
47
|
+
truncated: (length) => `…(truncated, ${plural(length, "character")} in total)`,
|
|
48
|
+
},
|
|
49
|
+
/** [ACP-D] 配置项与命令表。 */
|
|
50
|
+
config: {
|
|
51
|
+
model: "Model",
|
|
52
|
+
mode: "Permission mode",
|
|
53
|
+
thinking: "Thinking level",
|
|
54
|
+
levels: {
|
|
55
|
+
off: "Off",
|
|
56
|
+
minimal: "Minimal",
|
|
57
|
+
low: "Low",
|
|
58
|
+
medium: "Medium",
|
|
59
|
+
high: "High",
|
|
60
|
+
xhigh: "Extra high",
|
|
61
|
+
},
|
|
62
|
+
invalidValue: (id, value) => `invalid value for config option ${id}: ${value}`,
|
|
63
|
+
unknownModel: (ref) => `unknown model: ${ref}`,
|
|
64
|
+
},
|
|
65
|
+
/** [ACP-D] ama 作 ACP 客户端时的文案。 */
|
|
66
|
+
client: {
|
|
67
|
+
authRequired: (agent, methods) => `${agent} requires sign-in. Sign in with one of: ${methods.join("; ")}; then try again`,
|
|
68
|
+
authNoMethods: (agent) => `${agent} requires sign-in and offers no sign-in method; sign in with the agent's own CLI, then try again`,
|
|
69
|
+
authTerminal: (name, command) => `${name} (run in a terminal: ${command})`,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
export const zh = {
|
|
73
|
+
core: {
|
|
74
|
+
missingParam: (key) => `缺少 ${key}`,
|
|
75
|
+
promptNotArray: "prompt 应为内容块数组",
|
|
76
|
+
unparsable: (reason) => `ACP:无法解析的输入(${reason})`,
|
|
77
|
+
missingProtocolVersion: "缺少 protocolVersion",
|
|
78
|
+
fixedCwd: (cwd, got) => `ama --mode acp 的会话目录固定为启动目录 ${cwd}(收到 ${got})`,
|
|
79
|
+
sessionNotFound: (id, error) => `找不到会话 ${id}:${error}`,
|
|
80
|
+
modelFailed: "模型请求失败",
|
|
81
|
+
unknownMode: (mode) => `未知模式:${mode}`,
|
|
82
|
+
allowOnce: "允许",
|
|
83
|
+
allowAlways: "本会话允许",
|
|
84
|
+
rejectOnce: "拒绝",
|
|
85
|
+
unknownConfigOption: (id) => `未知配置项:${id}`,
|
|
86
|
+
},
|
|
87
|
+
auth: {
|
|
88
|
+
chatgptName: "使用 ChatGPT 登录",
|
|
89
|
+
chatgptDescription: "在终端运行 ama auth login chatgpt(ChatGPT 订阅)",
|
|
90
|
+
apiKeyName: "填写 API key",
|
|
91
|
+
apiKeyDescription: "在终端运行 ama auth set:选供应商后粘贴它的 API key",
|
|
92
|
+
notAgentMethod: "ama 只提供终端型认证方法,这类方法不经 authenticate;请在终端里运行该方法",
|
|
93
|
+
waiting: (reason) => `暂无可用模型(${reason});ACP 连接保持——在客户端的终端登录或运行 ama auth set 后再开会话`,
|
|
94
|
+
ready: (model) => `模型已可用(${model}),开始处理 ACP 会话`,
|
|
95
|
+
},
|
|
96
|
+
session: {
|
|
97
|
+
notOpen: (id) => `会话 ${id} 没有在本连接中打开;先发 session/load 或 session/resume`,
|
|
98
|
+
invalidCursor: "无效的 cursor(应原样传回上一次 session/list 的 nextCursor)",
|
|
99
|
+
ignoredMcp: (count) => `ACP:忽略客户端给的 ${count} 个 MCP 服务器(ama 不连接 MCP)`,
|
|
100
|
+
ignoredDirs: (count) => `ACP:忽略客户端给的 ${count} 个附加目录(工作目录固定为启动目录)`,
|
|
101
|
+
},
|
|
102
|
+
tools: {
|
|
103
|
+
codemodePrefix: (title) => `codemode › ${title}`,
|
|
104
|
+
truncated: (length) => `…(已截断,共 ${length} 字符)`,
|
|
105
|
+
},
|
|
106
|
+
config: {
|
|
107
|
+
model: "模型",
|
|
108
|
+
mode: "权限模式",
|
|
109
|
+
thinking: "思考级别",
|
|
110
|
+
levels: {
|
|
111
|
+
off: "关",
|
|
112
|
+
minimal: "最低",
|
|
113
|
+
low: "低",
|
|
114
|
+
medium: "中",
|
|
115
|
+
high: "高",
|
|
116
|
+
xhigh: "超高",
|
|
117
|
+
},
|
|
118
|
+
invalidValue: (id, value) => `配置项 ${id} 的值无效:${value}`,
|
|
119
|
+
unknownModel: (ref) => `未知模型:${ref}`,
|
|
120
|
+
},
|
|
121
|
+
client: {
|
|
122
|
+
authRequired: (agent, methods) => `${agent} 需要先登录。可用的登录方式:${methods.join(";")};登录后再试`,
|
|
123
|
+
authNoMethods: (agent) => `${agent} 需要先登录,但没有提供登录方式;请用它自己的命令行登录后再试`,
|
|
124
|
+
authTerminal: (name, command) => `${name}(在终端里运行:${command})`,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
@@ -19,6 +19,7 @@ export declare const en: {
|
|
|
19
19
|
unknownAction: (action: string) => string;
|
|
20
20
|
setPrompt: (provider: string) => string;
|
|
21
21
|
noKeyFromStdin: string;
|
|
22
|
+
pickProvider: string;
|
|
22
23
|
saved: (provider: string, path: string) => string;
|
|
23
24
|
warning: (text: string) => string;
|
|
24
25
|
listEmpty: (path: string) => string;
|
|
@@ -116,6 +117,7 @@ export declare const zh: {
|
|
|
116
117
|
unknownAction: (action: string) => string;
|
|
117
118
|
setPrompt: (provider: string) => string;
|
|
118
119
|
noKeyFromStdin: string;
|
|
120
|
+
pickProvider: string;
|
|
119
121
|
saved: (provider: string, path: string) => string;
|
|
120
122
|
warning: (text: string) => string;
|
|
121
123
|
listEmpty: (path: string) => string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 文案里从不放 token、code、账户 id;邮箱只放掩码。
|
|
7
7
|
*/
|
|
8
8
|
export const en = {
|
|
9
|
-
usage: `Usage: ama auth set <provider> [--auth-file <file>] read the key from stdin
|
|
9
|
+
usage: `Usage: ama auth set [<provider>] [--auth-file <file>] read the key from stdin (no provider on a TTY: pick one)
|
|
10
10
|
ama auth list [--auth-file <file>]
|
|
11
11
|
ama auth remove <provider> [--auth-file <file>]
|
|
12
12
|
ama auth login chatgpt [--flavor siwc|codex] [--paste | --device] [--port <n>] [--no-browser] [--yes] [--auth-file <file>]
|
|
@@ -20,6 +20,7 @@ export const en = {
|
|
|
20
20
|
unknownAction: (action) => `unknown auth subcommand: ${action}`,
|
|
21
21
|
setPrompt: (provider) => `Enter the API key for ${provider} (hidden), then press Enter: `,
|
|
22
22
|
noKeyFromStdin: "no key read from stdin",
|
|
23
|
+
pickProvider: "Which provider is the API key for?",
|
|
23
24
|
saved: (provider, path) => `Saved the key for ${provider} → ${path} (0600)`,
|
|
24
25
|
warning: (text) => `ama: warning: ${text}`,
|
|
25
26
|
listEmpty: (path) => `${path}: no saved keys`,
|
|
@@ -114,7 +115,7 @@ export const en = {
|
|
|
114
115
|
},
|
|
115
116
|
};
|
|
116
117
|
export const zh = {
|
|
117
|
-
usage: `用法:ama auth set <provider> [--auth-file <文件>] 从 stdin 读取 key
|
|
118
|
+
usage: `用法:ama auth set [<provider>] [--auth-file <文件>] 从 stdin 读取 key(TTY 下不给供应商则先选)
|
|
118
119
|
ama auth list [--auth-file <文件>]
|
|
119
120
|
ama auth remove <provider> [--auth-file <文件>]
|
|
120
121
|
ama auth login chatgpt [--flavor siwc|codex] [--paste | --device] [--port <n>] [--no-browser] [--yes] [--auth-file <文件>]
|
|
@@ -128,6 +129,7 @@ export const zh = {
|
|
|
128
129
|
unknownAction: (action) => `未知的 auth 子命令:${action}`,
|
|
129
130
|
setPrompt: (provider) => `输入 ${provider} 的 API key(不回显),回车结束:`,
|
|
130
131
|
noKeyFromStdin: "没有从 stdin 读到 key",
|
|
132
|
+
pickProvider: "这个 API key 属于哪个供应商?",
|
|
131
133
|
saved: (provider, path) => `已保存 ${provider} 的 key → ${path}(0600)`,
|
|
132
134
|
warning: (text) => `ama: 警告:${text}`,
|
|
133
135
|
listEmpty: (path) => `${path}:没有保存的 key`,
|
|
@@ -9,6 +9,7 @@ export declare const en: {
|
|
|
9
9
|
flagsConflict: (flags: readonly string[]) => string;
|
|
10
10
|
invalidChoice: (option: string, choices: readonly string[], got: string) => string;
|
|
11
11
|
emptyValue: (option: string) => string;
|
|
12
|
+
unknownTerminalAuth: (id: string) => string;
|
|
12
13
|
fullscreenUnsupported: string;
|
|
13
14
|
maxTurnsPositive: (got: string) => string;
|
|
14
15
|
maxCostPositive: (got: string) => string;
|
|
@@ -29,6 +30,7 @@ export declare const zh: {
|
|
|
29
30
|
flagsConflict: (flags: readonly string[]) => string;
|
|
30
31
|
invalidChoice: (option: string, choices: readonly string[], got: string) => string;
|
|
31
32
|
emptyValue: (option: string) => string;
|
|
33
|
+
unknownTerminalAuth: (id: string) => string;
|
|
32
34
|
fullscreenUnsupported: string;
|
|
33
35
|
maxTurnsPositive: (got: string) => string;
|
|
34
36
|
maxCostPositive: (got: string) => string;
|
|
@@ -9,6 +9,7 @@ export const en = {
|
|
|
9
9
|
flagsConflict: (flags) => `${flags.length > 2 ? `${flags.slice(0, -1).join(", ")} and ${flags.at(-1)}` : flags.join(" and ")} cannot be used together`,
|
|
10
10
|
invalidChoice: (option, choices, got) => `--${option} must be one of ${choices.join(" | ")} (got ${got})`,
|
|
11
11
|
emptyValue: (option) => `--${option} cannot be empty`,
|
|
12
|
+
unknownTerminalAuth: (id) => `--acp-terminal-auth: unknown method ${id} (expected chatgpt or api-key)`,
|
|
12
13
|
fullscreenUnsupported: "--tui-mode fullscreen is not supported yet (only regular for now)",
|
|
13
14
|
maxTurnsPositive: (got) => `--max-turns must be a positive integer (got ${got})`,
|
|
14
15
|
maxCostPositive: (got) => `--max-cost must be a positive number (USD, got ${got})`,
|
|
@@ -29,6 +30,7 @@ export const zh = {
|
|
|
29
30
|
flagsConflict: (flags) => `${flags.join(" 与 ")} 不能同时使用`,
|
|
30
31
|
invalidChoice: (option, choices, got) => `--${option} 的取值应为 ${choices.join(" | ")}(收到 ${got})`,
|
|
31
32
|
emptyValue: (option) => `--${option} 的值不能为空`,
|
|
33
|
+
unknownTerminalAuth: (id) => `--acp-terminal-auth:未知的认证方法 ${id}(应为 chatgpt 或 api-key)`,
|
|
32
34
|
fullscreenUnsupported: "--tui-mode fullscreen 尚未支持(第一期只有 regular)",
|
|
33
35
|
maxTurnsPositive: (got) => `--max-turns 应为正整数(收到 ${got})`,
|
|
34
36
|
maxCostPositive: (got) => `--max-cost 应为正数(美元,收到 ${got})`,
|
|
@@ -11,6 +11,7 @@ export declare const en: {
|
|
|
11
11
|
flagsConflict: (flags: readonly string[]) => string;
|
|
12
12
|
invalidChoice: (option: string, choices: readonly string[], got: string) => string;
|
|
13
13
|
emptyValue: (option: string) => string;
|
|
14
|
+
unknownTerminalAuth: (id: string) => string;
|
|
14
15
|
fullscreenUnsupported: string;
|
|
15
16
|
maxTurnsPositive: (got: string) => string;
|
|
16
17
|
maxCostPositive: (got: string) => string;
|
|
@@ -160,6 +161,7 @@ export declare const en: {
|
|
|
160
161
|
appendToolFailed: (name: string, message: string) => string;
|
|
161
162
|
notComposed: string;
|
|
162
163
|
switchWhileStreaming: string;
|
|
164
|
+
notLiveSession: string;
|
|
163
165
|
};
|
|
164
166
|
composeStore: {
|
|
165
167
|
ambiguousId: (id: string, candidates: readonly string[]) => string;
|
|
@@ -177,6 +179,7 @@ export declare const zh: {
|
|
|
177
179
|
flagsConflict: (flags: readonly string[]) => string;
|
|
178
180
|
invalidChoice: (option: string, choices: readonly string[], got: string) => string;
|
|
179
181
|
emptyValue: (option: string) => string;
|
|
182
|
+
unknownTerminalAuth: (id: string) => string;
|
|
180
183
|
fullscreenUnsupported: string;
|
|
181
184
|
maxTurnsPositive: (got: string) => string;
|
|
182
185
|
maxCostPositive: (got: string) => string;
|
|
@@ -323,6 +326,7 @@ export declare const zh: {
|
|
|
323
326
|
appendToolFailed: (name: string, message: string) => string;
|
|
324
327
|
notComposed: string;
|
|
325
328
|
switchWhileStreaming: string;
|
|
329
|
+
notLiveSession: string;
|
|
326
330
|
};
|
|
327
331
|
composeStore: {
|
|
328
332
|
ambiguousId: (id: string, candidates: readonly string[]) => string;
|
|
@@ -150,6 +150,7 @@ export const en = {
|
|
|
150
150
|
appendToolFailed: (name, message) => `Failed to append tool ${name}: ${message}`,
|
|
151
151
|
notComposed: "This session was not created by the composition root and cannot be switched",
|
|
152
152
|
switchWhileStreaming: "Cannot switch sessions while a run is in progress",
|
|
153
|
+
notLiveSession: "This session is not an open session of this runtime",
|
|
153
154
|
},
|
|
154
155
|
composeStore: {
|
|
155
156
|
ambiguousId: (id, candidates) => `Session id prefix ${id} is ambiguous, candidates: ${candidates.join(", ")}`,
|
|
@@ -298,6 +299,7 @@ export const zh = {
|
|
|
298
299
|
appendToolFailed: (name, message) => `追加工具 ${name} 失败:${message}`,
|
|
299
300
|
notComposed: "该会话不是由组装根创建的,不能切换",
|
|
300
301
|
switchWhileStreaming: "运行中不能切换会话",
|
|
302
|
+
notLiveSession: "该会话不是本运行期里打开着的会话",
|
|
301
303
|
},
|
|
302
304
|
composeStore: {
|
|
303
305
|
ambiguousId: (id, candidates) => `会话 id 前缀 ${id} 不唯一,候选:${candidates.join(", ")}`,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 消息目录:print(键名规范见 docs/i18n.md)。[W6-C0 建空壳,W6-I3 迁入 `src/modes/{print,rpc
|
|
2
|
+
* 消息目录:print(键名规范见 docs/i18n.md)。[W6-C0 建空壳,W6-I3 迁入 `src/modes/{print,rpc}/**`;
|
|
3
|
+
* ACP 的文案在 [ACP-C0] 迁到 acp.ts]
|
|
3
4
|
*
|
|
4
5
|
* en 是形状源;zh 用 `satisfies Messages<typeof en>`,缺键 / 多键 / 参数不符在 tsc 期报错。
|
|
5
6
|
* 整句一个键、禁止片段拼接;插值写成函数,条件分支写进函数体。
|
|
6
|
-
* RPC
|
|
7
|
+
* RPC 的 `error` / `message` 是人读文本,宿主按 `code` 判断(docs/rpc.md);JSON 字段名不在这里。
|
|
7
8
|
*/
|
|
8
9
|
export declare const en: {
|
|
9
10
|
/** `ama -p` 的 stderr。 */
|
|
@@ -32,22 +33,6 @@ export declare const en: {
|
|
|
32
33
|
noPlan: string;
|
|
33
34
|
badMode: (modes: readonly string[]) => string;
|
|
34
35
|
};
|
|
35
|
-
/** ACP 服务端(`ama --mode acp`)。 */
|
|
36
|
-
acp: {
|
|
37
|
-
missingParam: (key: string) => string;
|
|
38
|
-
promptNotArray: string;
|
|
39
|
-
unparsable: (reason: string) => string;
|
|
40
|
-
missingProtocolVersion: string;
|
|
41
|
-
fixedCwd: (cwd: string, got: string) => string;
|
|
42
|
-
sessionNotFound: (id: string, error: string) => string;
|
|
43
|
-
busy: string;
|
|
44
|
-
modelFailed: string;
|
|
45
|
-
unknownMode: (mode: string) => string;
|
|
46
|
-
allowOnce: string;
|
|
47
|
-
allowAlways: string;
|
|
48
|
-
rejectOnce: string;
|
|
49
|
-
truncated: (length: number) => string;
|
|
50
|
-
};
|
|
51
36
|
};
|
|
52
37
|
export declare const zh: {
|
|
53
38
|
print: {
|
|
@@ -74,19 +59,4 @@ export declare const zh: {
|
|
|
74
59
|
noPlan: string;
|
|
75
60
|
badMode: (modes: readonly string[]) => string;
|
|
76
61
|
};
|
|
77
|
-
acp: {
|
|
78
|
-
missingParam: (key: string) => string;
|
|
79
|
-
promptNotArray: string;
|
|
80
|
-
unparsable: (reason: string) => string;
|
|
81
|
-
missingProtocolVersion: string;
|
|
82
|
-
fixedCwd: (cwd: string, got: string) => string;
|
|
83
|
-
sessionNotFound: (id: string, error: string) => string;
|
|
84
|
-
busy: string;
|
|
85
|
-
modelFailed: string;
|
|
86
|
-
unknownMode: (mode: string) => string;
|
|
87
|
-
allowOnce: string;
|
|
88
|
-
allowAlways: string;
|
|
89
|
-
rejectOnce: string;
|
|
90
|
-
truncated: (length: number) => string;
|
|
91
|
-
};
|
|
92
62
|
};
|