jetbrains-pi-acp 0.1.1 → 0.1.2

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 CHANGED
@@ -11,7 +11,7 @@ Requires **Node.js 22.19.0+** and a JetBrains IDE with ACP support, such as Inte
11
11
  1. Sign in to your model provider from a terminal:
12
12
 
13
13
  ```bash
14
- npx --yes jetbrains-pi-acp@0.1.1 --setup
14
+ npx --yes jetbrains-pi-acp@0.1.2 --setup
15
15
  ```
16
16
 
17
17
  In pi, run `/login`, complete sign-in, then exit pi and return to the IDE. Credentials are managed by pi.
@@ -23,7 +23,7 @@ Requires **Node.js 22.19.0+** and a JetBrains IDE with ACP support, such as Inte
23
23
  "agent_servers": {
24
24
  "pi": {
25
25
  "command": "npx",
26
- "args": ["--yes", "jetbrains-pi-acp@0.1.1"],
26
+ "args": ["--yes", "jetbrains-pi-acp@0.1.2"],
27
27
  "use_idea_mcp": true,
28
28
  "use_custom_mcp": true
29
29
  }
@@ -51,7 +51,7 @@ The IDE must be able to find `npx`; use its absolute path if needed. Menu locati
51
51
  Append pi options after `--` in the agent's `args`, for example:
52
52
 
53
53
  ```json
54
- ["--yes", "jetbrains-pi-acp@0.1.1", "--", "--model", "provider/model-id", "--thinking", "medium"]
54
+ ["--yes", "jetbrains-pi-acp@0.1.2", "--", "--model", "provider/model-id", "--thinking", "medium"]
55
55
  ```
56
56
 
57
57
  Use configuration options here, not initial prompts, interactive mode, or session-selection arguments. The adapter manages RPC mode and sessions.
package/README.zh-CN.md CHANGED
@@ -11,7 +11,7 @@
11
11
  1. 在终端中登录模型提供商:
12
12
 
13
13
  ```bash
14
- npx --yes jetbrains-pi-acp@0.1.1 --setup
14
+ npx --yes jetbrains-pi-acp@0.1.2 --setup
15
15
  ```
16
16
 
17
17
  在 pi 中运行 `/login`,完成登录后退出 pi 并返回 IDE。凭据由 pi 管理。
@@ -23,7 +23,7 @@
23
23
  "agent_servers": {
24
24
  "pi": {
25
25
  "command": "npx",
26
- "args": ["--yes", "jetbrains-pi-acp@0.1.1"],
26
+ "args": ["--yes", "jetbrains-pi-acp@0.1.2"],
27
27
  "use_idea_mcp": true,
28
28
  "use_custom_mcp": true
29
29
  }
@@ -38,8 +38,9 @@ IDE 必须能找到 `npx`,必要时使用其绝对路径。菜单位置随 IDE
38
38
  ## 主要功能
39
39
 
40
40
  - 支持 ACP v1 和 v2 草案,流式展示回答、思考、工具状态、终端输出和用量。
41
+ - 每轮汇总模型请求与自动压缩的输入、输出及缓存读写 token,取消仍保留已发生用量;通过 `usage_update.cost` 发布 pi 记录的会话累计美元费用,恢复历史后继续累计。可用 `/status` 查看累计 token、费用和上下文用量。
41
42
  - 使用 pi 原生历史,支持会话列表、加载、恢复、改名、分叉和删除。
42
- - 支持切换模型与推理级别,以及完全访问、标准访问、只读和规划模式。
43
+ - 支持切换模型与推理级别,以及完全访问、标准访问、只读和规划模式。名称和模式说明在启动时按系统语言自动切换中英文:依次读取非空的 `LC_ALL`、`LC_MESSAGES`、`LANG`,未设置时使用系统默认语言;中文使用中文,其余语言使用英文。更改系统语言后需重启适配器。
43
44
  - 展示内置 `edit/write` 工具的文件 diff,可协商 Air Git patch 和每轮文件报告。
44
45
  - 转发 stdio/HTTP MCP 配置及 IDE 工具;支持子 agent、后台 shell 任务和定向停止。
45
46
  - 按客户端能力提供 steering、终端 stdin、表单和 URL 交互。Air v1 可在命令执行期间发送 `/stdin 文本` 和 `/eof`。
@@ -51,7 +52,7 @@ IDE 必须能找到 `npx`,必要时使用其绝对路径。菜单位置随 IDE
51
52
  在 Agent 的 `args` 末尾添加 `--`,随后传递 pi 参数,例如:
52
53
 
53
54
  ```json
54
- ["--yes", "jetbrains-pi-acp@0.1.1", "--", "--model", "provider/model-id", "--thinking", "medium"]
55
+ ["--yes", "jetbrains-pi-acp@0.1.2", "--", "--model", "provider/model-id", "--thinking", "medium"]
55
56
  ```
56
57
 
57
58
  这里只传配置选项,不传初始提示、交互模式或会话选择参数。RPC 模式和会话由适配器管理。
@@ -69,6 +70,7 @@ IDE 必须能找到 `npx`,必要时使用其绝对路径。菜单位置随 IDE
69
70
  - diff 有大小限制,二进制文件或旧历史可能无法展示。每轮文件报告的单次快照最多扫描 20,000 项或两秒,无法准确区分外部并发修改。
70
71
  - 不支持 MCP SSE、音频和二进制内嵌资源,图片支持取决于模型。
71
72
  - ACP v2 仍为草案,客户端界面展示、真实提供商账号登录及 Windows 实机仍需验证。
73
+ - 每轮 token 在 v1 提示响应的 `usage`、v2 完成状态的 `usage` 中返回;未上报用量时省略,不单列思考 token 或每轮费用。费用取自 pi 的模型计价数据;上下文用量不可用时不发送 `usage_update`,IDE 展示取决于客户端支持。
72
74
 
73
75
  ## 开发
74
76
 
package/examples/acp.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "pi": {
4
4
  "command": "/绝对路径/node",
5
5
  "args": [
6
- "/绝对路径/jetbrains-acp/src/index.js",
6
+ "/绝对路径/jetbrains-pi-acp/src/index.js",
7
7
  "--pi-command",
8
8
  "/绝对路径/pi"
9
9
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jetbrains-pi-acp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "连接 JetBrains IDE 与 pi coding agent 的 ACP 适配器",
6
6
  "bin": {
package/src/agent.js CHANGED
@@ -15,12 +15,20 @@ import { changedFiles, fileSnapshot } from './file-changes.js';
15
15
  const executeFile = promisify(execFile);
16
16
  const extensionPath = fileURLToPath(new URL('../extensions/acp.ts', import.meta.url));
17
17
  const invalid = message => Object.assign(new Error(message), { code: -32602 });
18
- const modes = [
19
- { id: 'plan', name: '规划', description: '只分析和制定计划,自动拒绝修改文件及执行命令' },
20
- { id: 'read-only', name: '只读', description: '自动拒绝写文件、执行命令及其他非内置只读工具' },
21
- { id: 'standard', name: '标准访问', description: '写文件、执行命令及其他非内置只读工具逐次请求授权' },
22
- { id: 'full', name: '完全访问', description: '本会话自动允许全部工具调用,包括写文件和执行命令' },
23
- ];
18
+ const modes = {
19
+ zh: [
20
+ { id: 'plan', name: '规划', description: '只分析和制定计划,自动拒绝修改文件及执行命令' },
21
+ { id: 'read-only', name: '只读', description: '自动拒绝写文件、执行命令及其他非内置只读工具' },
22
+ { id: 'standard', name: '标准访问', description: '写文件、执行命令及其他非内置只读工具逐次请求授权' },
23
+ { id: 'full', name: '完全访问', description: '本会话自动允许全部工具调用,包括写文件和执行命令' },
24
+ ],
25
+ en: [
26
+ { id: 'plan', name: 'Plan', description: 'Analyze and plan only; automatically deny file changes and command execution' },
27
+ { id: 'read-only', name: 'Read Only', description: 'Automatically deny file writes, command execution, and tools other than built-in read-only tools' },
28
+ { id: 'standard', name: 'Standard Access', description: 'Request approval for each file write, command execution, or tool other than built-in read-only tools' },
29
+ { id: 'full', name: 'Full Access', description: 'Automatically allow all tool calls in this session, including file writes and command execution' },
30
+ ],
31
+ };
24
32
  const toolKind = name => ({ read: 'read', grep: 'search', find: 'search', ls: 'read',
25
33
  write: 'edit', edit: 'edit', update_plan: 'think', background_shell: 'execute', bash: 'execute', powershell: 'execute' })[name] || 'other';
26
34
 
@@ -93,6 +101,10 @@ export function convertPrompt(blocks) {
93
101
 
94
102
  export class Agent {
95
103
  constructor({ send, command = 'pi', args = [] }) {
104
+ const locale = process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG ||
105
+ Intl.DateTimeFormat().resolvedOptions().locale;
106
+ this.chinese = /^zh(?:[-_.@]|$)/i.test(locale);
107
+ this.modes = modes[this.chinese ? 'zh' : 'en'];
96
108
  this.send = send;
97
109
  this.command = command;
98
110
  this.args = args;
@@ -258,7 +270,7 @@ export class Agent {
258
270
  }
259
271
  if (method === 'session/set_mode' || (method === 'session/set_config_option' && params.configId === 'mode')) {
260
272
  const modeId = method === 'session/set_mode' ? params.modeId : params.value;
261
- if (!modes.some(mode => mode.id === modeId)) throw invalid('未知权限模式');
273
+ if (!this.modes.some(mode => mode.id === modeId)) throw invalid('未知权限模式');
262
274
  await this.setMode(session, modeId);
263
275
  return method === 'session/set_mode' ? {} : { configOptions: this.modelConfig(session) };
264
276
  }
@@ -1209,7 +1221,7 @@ export class Agent {
1209
1221
 
1210
1222
  sessionState(session) {
1211
1223
  return { sessionId: session.id, configOptions: this.modelConfig(session),
1212
- modes: { currentModeId: session.mode, availableModes: modes }, models: {
1224
+ modes: { currentModeId: session.mode, availableModes: this.modes }, models: {
1213
1225
  currentModelId: session.currentModelId,
1214
1226
  availableModels: session.availableModels.map(model => ({
1215
1227
  modelId: `${model.provider}/${model.id}`, name: `${model.name || model.id} (${model.provider})`,
@@ -1263,7 +1275,7 @@ export class Agent {
1263
1275
  }
1264
1276
 
1265
1277
  modelConfig(session) {
1266
- return [{ id: 'model', name: '模型', category: 'model', type: 'select',
1278
+ return [{ id: 'model', name: this.chinese ? '模型' : 'Model', category: 'model', type: 'select',
1267
1279
  currentValue: session.currentModelId,
1268
1280
  ...(this.airRecommendedValue ? { _meta: { jetbrains: { air: {
1269
1281
  version: 1, recommendedValue: session.recommendedModelId,
@@ -1271,17 +1283,19 @@ export class Agent {
1271
1283
  options: session.availableModels.map(model => ({
1272
1284
  value: `${model.provider}/${model.id}`, name: `${model.name || model.id} (${model.provider})`,
1273
1285
  })),
1274
- }, { id: 'thinking', name: '推理级别', category: 'thought_level', type: 'select',
1286
+ }, { id: 'thinking', name: this.chinese ? '推理级别' : 'Thinking Level', category: 'thought_level', type: 'select',
1275
1287
  currentValue: session.thinkingLevel,
1276
1288
  ...(this.airRecommendedValue && session.thinkingLevels.includes(session.recommendedThinkingLevel) ? { _meta: { jetbrains: { air: {
1277
1289
  version: 1, recommendedValue: session.recommendedThinkingLevel,
1278
1290
  } } } } : {}),
1279
1291
  options: session.thinkingLevels.map(level => ({ value: level,
1280
- name: ({ off: '关闭', minimal: '最低', low: '低', medium: '中', high: '高', xhigh: '极高', max: '最高' })[level] || level,
1292
+ name: (this.chinese
1293
+ ? { off: '关闭', minimal: '最低', low: '低', medium: '中', high: '高', xhigh: '极高', max: '最高' }
1294
+ : { off: 'Off', minimal: 'Minimal', low: 'Low', medium: 'Medium', high: 'High', xhigh: 'Extra High', max: 'Max' })[level] || level,
1281
1295
  })),
1282
- }, { id: 'mode', name: '权限模式', category: 'mode', type: 'select',
1296
+ }, { id: 'mode', name: this.chinese ? '权限模式' : 'Permission Mode', category: 'mode', type: 'select',
1283
1297
  currentValue: session.mode,
1284
- options: modes.map(mode => ({ value: mode.id, name: mode.name, description: mode.description })),
1298
+ options: this.modes.map(mode => ({ value: mode.id, name: mode.name, description: mode.description })),
1285
1299
  }];
1286
1300
  }
1287
1301