@zhushanwen/pi-base-tool-enhance 0.7.1 → 0.7.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/pi-base-tool-enhance",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Base tool enhancement - override builtin bash tool: foreground delegates to pi official factory, incremental background mode (design decisions documented in source comments)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"skills/"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@zhushanwen/extension-protocol": "0.
|
|
31
|
+
"@zhushanwen/extension-protocol": "0.17.0",
|
|
32
32
|
"@zhushanwen/pi-ext-guards": "0.4.2",
|
|
33
33
|
"@zhushanwen/pi-extension-logger": "0.6.1",
|
|
34
34
|
"@zhushanwen/pi-file-lock": "0.4.1",
|
|
35
|
-
"@zhushanwen/pi-llm-shared": "0.
|
|
35
|
+
"@zhushanwen/pi-llm-shared": "0.11.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@vitest/coverage-v8": "^4.1.9",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
43
43
|
"typebox": "*",
|
|
44
|
-
"@zhushanwen/pi-pending-notifications": "0.8.
|
|
44
|
+
"@zhushanwen/pi-pending-notifications": "0.8.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"@zhushanwen/pi-pending-notifications": {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/__tests__/command-display.test.ts
|
|
2
|
+
//
|
|
3
|
+
// truncateCommand 单源实现的输出等价锚(plan-mode-audit-remediation 批次 3
|
|
4
|
+
// 活路径去重组:原 spawn-background.ts / notify.ts 两份同构定义去重留一份)。
|
|
5
|
+
// 断言即两份旧副本共同产出的输出形态:
|
|
6
|
+
// - ≤80 字符(含恰好 80)原样返回
|
|
7
|
+
// - >80 取前 80 字符 + 单个省略号(总长 81,与 notify.test.ts 的 emit 路径断言一致)
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
|
|
10
|
+
import { COMMAND_DISPLAY_LIMIT, truncateCommand } from "../background/command-display";
|
|
11
|
+
|
|
12
|
+
describe("truncateCommand(单源,原双份定义的输出等价锚)", () => {
|
|
13
|
+
it("short command returned as-is", () => {
|
|
14
|
+
expect(truncateCommand("pnpm test")).toBe("pnpm test");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it(`command of exactly ${COMMAND_DISPLAY_LIMIT} chars not truncated (boundary: length > limit)`, () => {
|
|
18
|
+
const exact = "c".repeat(COMMAND_DISPLAY_LIMIT);
|
|
19
|
+
expect(truncateCommand(exact)).toBe(exact);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("long command truncated to first 80 chars + single ellipsis (total 81)", () => {
|
|
23
|
+
const long = `echo ${"x".repeat(200)}`;
|
|
24
|
+
expect(truncateCommand(long)).toBe(`${long.slice(0, COMMAND_DISPLAY_LIMIT)}…`);
|
|
25
|
+
expect(truncateCommand(long).length).toBe(COMMAND_DISPLAY_LIMIT + 1);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 命令文案在错误消息 / 通知中的展示截断(单份实现)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么独立成叶子模块:truncateCommand 曾在 spawn-background.ts 与 notify.ts 各留
|
|
5
|
+
* 一份同构定义——notify 被 spawn-background import(emitPendingRegister),反向 import
|
|
6
|
+
* 会成环,两份只能靠数值对齐隐式同步。抽到双方共同依赖的叶子模块后环消失,截断
|
|
7
|
+
* 口径(80 字符 + 省略号)单源。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** 命令在错误文案中的展示长度上限。 */
|
|
11
|
+
export const COMMAND_DISPLAY_LIMIT = 80;
|
|
12
|
+
|
|
13
|
+
/** 超上限取前 80 字符 + 省略号;等长/短命令原样返回。 */
|
|
14
|
+
export function truncateCommand(command: string): string {
|
|
15
|
+
return command.length > COMMAND_DISPLAY_LIMIT
|
|
16
|
+
? `${command.slice(0, COMMAND_DISPLAY_LIMIT)}…`
|
|
17
|
+
: command;
|
|
18
|
+
}
|
package/src/background/notify.ts
CHANGED
|
@@ -30,6 +30,7 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
|
30
30
|
import { toErrorMessage } from "@zhushanwen/pi-ext-guards";
|
|
31
31
|
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
32
32
|
|
|
33
|
+
import { truncateCommand } from "./command-display.ts";
|
|
33
34
|
import type { BackgroundTask, BackgroundTaskEndReason } from "./types.ts";
|
|
34
35
|
|
|
35
36
|
const logger = getLogger("base-tool-enhance");
|
|
@@ -40,24 +41,6 @@ const logger = getLogger("base-tool-enhance");
|
|
|
40
41
|
*/
|
|
41
42
|
export const BACKGROUND_BASH_CUSTOM_TYPE = "background-bash";
|
|
42
43
|
|
|
43
|
-
/**
|
|
44
|
-
* pending register 的 name 截断长度(§3.5 数据流 ⑤「command 前 80 字符」)。
|
|
45
|
-
* 与 spawn-background COMMAND_DISPLAY_LIMIT 同值但刻意不共享 import——notify 被
|
|
46
|
-
* spawn-background import,反向 import 会造成 spawn ↔ notify 循环依赖;两处语义
|
|
47
|
-
* (pending 列表展示 / 错误文案展示)各自独立演化,仅数值对齐。
|
|
48
|
-
*/
|
|
49
|
-
const PENDING_NAME_LIMIT = 80;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 命令文案截断(pending register 的 name 与完成通知 head 行共用同一口径):
|
|
53
|
-
* 超 PENDING_NAME_LIMIT 取前 80 字符 + 省略号。
|
|
54
|
-
*/
|
|
55
|
-
function truncateCommand(command: string): string {
|
|
56
|
-
return command.length > PENDING_NAME_LIMIT
|
|
57
|
-
? `${command.slice(0, PENDING_NAME_LIMIT)}…`
|
|
58
|
-
: command;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
44
|
/** 模块级「当前 pi 引用」(D17 核心可变状态,见文件头)。 */
|
|
62
45
|
let currentPi: ExtensionAPI | undefined;
|
|
63
46
|
|
|
@@ -249,7 +232,7 @@ export interface BackgroundBashDetails {
|
|
|
249
232
|
* 完成通知 details(D1):终态字段与 buildNotificationContent 同源——durationMs
|
|
250
233
|
* 同用 `?? 0` 归一(终态条目必已物化,缺省仅防御)。
|
|
251
234
|
*
|
|
252
|
-
* command 取原始终态值不截断:截断(
|
|
235
|
+
* command 取原始终态值不截断:截断(COMMAND_DISPLAY_LIMIT)是 content 行宽约束,结构化
|
|
253
236
|
* 消费方的行宽由渲染层自己决定(旧数据无 details 时仍走 content 原文兜底)。
|
|
254
237
|
*/
|
|
255
238
|
export function buildNotifyDetails(task: NotificationTaskLike): BackgroundBashDetails {
|
|
@@ -21,6 +21,7 @@ import { getProcessStartTimeSec, killProcessTree, pidStartMatchesRegistered } fr
|
|
|
21
21
|
import { toErrorMessage } from "@zhushanwen/pi-ext-guards";
|
|
22
22
|
import { getLogger } from "@zhushanwen/pi-extension-logger";
|
|
23
23
|
|
|
24
|
+
import { truncateCommand } from "./command-display.ts";
|
|
24
25
|
import { emitPendingRegister } from "./notify.ts";
|
|
25
26
|
import { ensurePollerRunning } from "./poller.ts";
|
|
26
27
|
import { getRegistryPath, taskToRegistryEntry, writeRegistryEntry } from "./registry.ts";
|
|
@@ -50,9 +51,6 @@ const TASK_ID_RAND_LENGTH = 6;
|
|
|
50
51
|
const TASK_ID_RADIX = 36;
|
|
51
52
|
const TASK_ID_RAND_SPACE = TASK_ID_RADIX ** TASK_ID_RAND_LENGTH;
|
|
52
53
|
|
|
53
|
-
/** 命令在错误文案中的展示长度上限。 */
|
|
54
|
-
const COMMAND_DISPLAY_LIMIT = 80;
|
|
55
|
-
|
|
56
54
|
/**
|
|
57
55
|
* task_id 生成:`bt-<ts>-<rand>`(前缀 bt- 刻意区别于 subagent-workflow 的
|
|
58
56
|
* bg-/run-,§2.3)。**禁止进程内自增序列**——pi 重启后撞旧 id 会破坏 pending
|
|
@@ -290,9 +288,3 @@ function accessOrThrow(cwd: string): void {
|
|
|
290
288
|
// 独立小函数:保持与内置 fsAccess(constants.F_OK) 语义一致的同步版本
|
|
291
289
|
accessSync(cwd, constants.F_OK);
|
|
292
290
|
}
|
|
293
|
-
|
|
294
|
-
export function truncateCommand(command: string): string {
|
|
295
|
-
return command.length > COMMAND_DISPLAY_LIMIT
|
|
296
|
-
? `${command.slice(0, COMMAND_DISPLAY_LIMIT)}…`
|
|
297
|
-
: command;
|
|
298
|
-
}
|
package/src/bash-output-tool.ts
CHANGED
|
@@ -17,9 +17,9 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
|
17
17
|
import { readOutputTail } from "@zhushanwen/extension-protocol/background-task";
|
|
18
18
|
import { Type } from "typebox";
|
|
19
19
|
|
|
20
|
+
import { truncateCommand } from "./background/command-display.ts";
|
|
20
21
|
import { TAIL_MAX_BYTES, TAIL_MAX_LINES } from "./background/output-tail.ts";
|
|
21
22
|
import { getRegistryPath, readRegistry } from "./background/registry.ts";
|
|
22
|
-
import { truncateCommand } from "./background/spawn-background.ts";
|
|
23
23
|
import { getAllTasks } from "./background/task-store.ts";
|
|
24
24
|
import { isTerminalState, type BackgroundTask, type RegistryEntry } from "./background/types.ts";
|
|
25
25
|
|
package/src/bash-tool.ts
CHANGED
|
@@ -19,11 +19,8 @@ import type { AgentToolUpdateCallback, BashToolDetails, ExtensionContext } from
|
|
|
19
19
|
import { createBashToolDefinition, getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
20
20
|
import { Type } from "typebox";
|
|
21
21
|
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
spawnBackgroundTask,
|
|
25
|
-
truncateCommand,
|
|
26
|
-
} from "./background/spawn-background.ts";
|
|
22
|
+
import { truncateCommand } from "./background/command-display.ts";
|
|
23
|
+
import { resolveBackgroundTimeoutSec, spawnBackgroundTask } from "./background/spawn-background.ts";
|
|
27
24
|
import { isSubagentProcess } from "./background/subagent-guard.ts";
|
|
28
25
|
import { loadBaseToolEnhanceConfig, type BaseToolEnhanceConfig } from "./config.ts";
|
|
29
26
|
import { compileForcePatterns, describeForceMatch, matchForceBackground } from "./force-patterns.ts";
|