@trim21/personal-pi-extensions 0.1.595 → 0.1.597
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 +1 -2
- package/src/bwrap/core.ts +4 -17
- package/src/gh/base.ts +28 -7
- package/src/gh/tools/get-workflow-jobs.ts +2 -2
- package/src/gh/tools/read-issue-comments.ts +2 -2
- package/src/gh/tools/read-issue.ts +2 -2
- package/src/gh/tools/read-pr-comments.ts +4 -7
- package/src/gh/tools/read-pr.ts +2 -2
- package/vendor/mihomo-linux-x64 +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trim21/personal-pi-extensions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.597",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
|
|
6
6
|
"keywords": [
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"src",
|
|
16
|
-
"vendor",
|
|
17
16
|
"README.md"
|
|
18
17
|
],
|
|
19
18
|
"publishConfig": {
|
package/src/bwrap/core.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { constants, type Dirent, existsSync, readFileSync } from "node:fs";
|
|
|
3
3
|
import { access as fsAccess, readdir, realpath, stat } from "node:fs/promises";
|
|
4
4
|
import { delimiter, join } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
6
|
|
|
8
7
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
9
8
|
import { type BashOperations, getAgentDir, getShellConfig } from "@earendil-works/pi-coding-agent";
|
|
@@ -266,28 +265,16 @@ function findCommandInPath(name: string, hint: string): string {
|
|
|
266
265
|
throw new Error(hint);
|
|
267
266
|
}
|
|
268
267
|
|
|
269
|
-
|
|
270
|
-
// 源码方式运行(vendor 不存在)时自然跳过,走 PATH 查找。
|
|
271
|
-
const VENDORED_MIHOMO_PATH = fileURLToPath(
|
|
272
|
-
new URL("../../vendor/mihomo-linux-x64", import.meta.url),
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
export function findMihomo(override?: string, bundledPath = VENDORED_MIHOMO_PATH): string {
|
|
268
|
+
export function findMihomo(override?: string): string {
|
|
276
269
|
if (override) {
|
|
277
270
|
if (!existsSync(override)) {
|
|
278
271
|
throw new Error(`mihomo not found at configured path: ${override}`);
|
|
279
272
|
}
|
|
280
273
|
return override;
|
|
281
274
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (existsSync(candidate)) return candidate;
|
|
286
|
-
}
|
|
287
|
-
if (existsSync(bundledPath)) return bundledPath;
|
|
288
|
-
throw new Error(
|
|
289
|
-
"mihomo not found in PATH and the package ships no bundled binary. " +
|
|
290
|
-
"Install it from https://github.com/MetaCubeX/mihomo",
|
|
275
|
+
return findCommandInPath(
|
|
276
|
+
"mihomo",
|
|
277
|
+
"mihomo not found in PATH. Install it from https://github.com/MetaCubeX/mihomo",
|
|
291
278
|
);
|
|
292
279
|
}
|
|
293
280
|
|
package/src/gh/base.ts
CHANGED
|
@@ -151,11 +151,11 @@ export function runGh(
|
|
|
151
151
|
resolve({
|
|
152
152
|
stdout,
|
|
153
153
|
stderr,
|
|
154
|
-
// When killed by a signal the close event's code is null
|
|
155
|
-
//
|
|
156
|
-
// sentinel for "did not exit normally" — distinct
|
|
157
|
-
// failure exit code (1), which is always in 0-255.
|
|
158
|
-
code: code ??
|
|
154
|
+
// When killed by a signal the close event's code is null — including
|
|
155
|
+
// kills we did not initiate. Report failure instead of pretending it
|
|
156
|
+
// succeeded. -1 is a sentinel for "did not exit normally" — distinct
|
|
157
|
+
// from a real gh failure exit code (1), which is always in 0-255.
|
|
158
|
+
code: code ?? -1,
|
|
159
159
|
killed,
|
|
160
160
|
combined: combined.join(""),
|
|
161
161
|
reason: killReason,
|
|
@@ -309,11 +309,19 @@ export function truncate(
|
|
|
309
309
|
out.push(line);
|
|
310
310
|
bytes += lineBytes;
|
|
311
311
|
}
|
|
312
|
-
return { text: out.join("\n"), truncated: true };
|
|
312
|
+
if (out.length > 0) return { text: out.join("\n"), truncated: true };
|
|
313
|
+
|
|
314
|
+
// 首行自己就超过 maxBytes(如单行超长文本):保底保留字节前缀,
|
|
315
|
+
// 不能把非空输出截成空字符串。
|
|
316
|
+
return {
|
|
317
|
+
text: Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8"),
|
|
318
|
+
truncated: true,
|
|
319
|
+
};
|
|
313
320
|
}
|
|
314
321
|
|
|
315
322
|
/**
|
|
316
|
-
* Format a successful gh invocation's stdout into a tool result
|
|
323
|
+
* Format a successful gh invocation's text stdout into a tool result,
|
|
324
|
+
* line-truncated. JSON output must go through `toToolResultJson` instead.
|
|
317
325
|
* Failures are thrown by `ghExec` as `GhError`, so only the success path lives here.
|
|
318
326
|
*/
|
|
319
327
|
export function toToolResult(
|
|
@@ -330,6 +338,19 @@ export function toToolResult(
|
|
|
330
338
|
};
|
|
331
339
|
}
|
|
332
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Format a successful gh invocation's JSON stdout into a tool result, passed
|
|
343
|
+
* through whole. Line-based truncation must not touch JSON: it would cut the
|
|
344
|
+
* payload into invalid JSON, and since `gh --json` prints one line, any
|
|
345
|
+
* over-budget payload used to be blanked entirely.
|
|
346
|
+
*/
|
|
347
|
+
export function toToolResultJson(json: string, input?: unknown): ToolResult {
|
|
348
|
+
return {
|
|
349
|
+
content: [{ type: "text", text: json }],
|
|
350
|
+
details: { ...(input !== undefined && { input }), truncated: false },
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
333
354
|
/**
|
|
334
355
|
* Pendant subtitle for a tool result: `repo=x/y` (when provided) plus the
|
|
335
356
|
* tool's id parameter, e.g. `repo=x/y number=123`. Returns undefined when
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type ToolCall,
|
|
10
10
|
type ToolResult,
|
|
11
11
|
toPositiveId,
|
|
12
|
-
|
|
12
|
+
toToolResultJson,
|
|
13
13
|
} from "../base.js";
|
|
14
14
|
|
|
15
15
|
interface RunIdParams {
|
|
@@ -25,7 +25,7 @@ async function workflowJobs(gh: GhClient, call: ToolCall<RunIdParams>): Promise<
|
|
|
25
25
|
const { owner, repo: name } = splitRepo(effectiveRepo);
|
|
26
26
|
|
|
27
27
|
const jobs = await gh.checks.runJobs(owner, name, runId, signal);
|
|
28
|
-
const result =
|
|
28
|
+
const result = toToolResultJson(JSON.stringify({ total_count: jobs.length, jobs }), params);
|
|
29
29
|
result.details.pendant = subtitlePendant(params, "run_id");
|
|
30
30
|
return result;
|
|
31
31
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
|
|
4
|
-
import { type GhClient, ghExec, repoArgs, subtitlePendant,
|
|
4
|
+
import { type GhClient, ghExec, repoArgs, subtitlePendant, toToolResultJson } from "../base.js";
|
|
5
5
|
|
|
6
6
|
export function addReadIssueCommentsTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
7
7
|
pi.registerTool({
|
|
@@ -15,7 +15,7 @@ export function addReadIssueCommentsTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
|
15
15
|
}),
|
|
16
16
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
17
17
|
const { number, repo } = params;
|
|
18
|
-
const result =
|
|
18
|
+
const result = toToolResultJson(
|
|
19
19
|
await ghExec(["issue", "view", String(number), ...repoArgs(repo), "--json", "comments"], {
|
|
20
20
|
cwd: ctx.cwd,
|
|
21
21
|
signal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
|
|
4
|
-
import { type GhClient, ghExec, repoArgs, subtitlePendant,
|
|
4
|
+
import { type GhClient, ghExec, repoArgs, subtitlePendant, toToolResultJson } from "../base.js";
|
|
5
5
|
|
|
6
6
|
export function addReadIssueTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
7
7
|
pi.registerTool({
|
|
@@ -15,7 +15,7 @@ export function addReadIssueTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
|
15
15
|
}),
|
|
16
16
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
17
17
|
const { number, repo } = params;
|
|
18
|
-
const result =
|
|
18
|
+
const result = toToolResultJson(
|
|
19
19
|
await ghExec(
|
|
20
20
|
[
|
|
21
21
|
"issue",
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
repoArgs,
|
|
9
9
|
resolveRepo,
|
|
10
10
|
subtitlePendant,
|
|
11
|
-
|
|
11
|
+
toToolResultJson,
|
|
12
12
|
} from "../base.js";
|
|
13
13
|
|
|
14
14
|
export function addReadPrCommentsTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
@@ -65,12 +65,9 @@ export function addReadPrCommentsTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
|
65
65
|
},
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
return
|
|
71
|
-
content: [{ type: "text", text }],
|
|
72
|
-
details: { input: params, truncated, ...(pendant && { pendant }) },
|
|
73
|
-
};
|
|
68
|
+
const result = toToolResultJson(out, params);
|
|
69
|
+
result.details.pendant = subtitlePendant(params, "number");
|
|
70
|
+
return result;
|
|
74
71
|
},
|
|
75
72
|
});
|
|
76
73
|
}
|
package/src/gh/tools/read-pr.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
|
|
4
|
-
import { type GhClient, ghExec, repoArgs, subtitlePendant,
|
|
4
|
+
import { type GhClient, ghExec, repoArgs, subtitlePendant, toToolResultJson } from "../base.js";
|
|
5
5
|
|
|
6
6
|
export function addReadPrTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
7
7
|
pi.registerTool({
|
|
@@ -15,7 +15,7 @@ export function addReadPrTool(_gh: GhClient, pi: ExtensionAPI) {
|
|
|
15
15
|
}),
|
|
16
16
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
17
17
|
const { number, repo } = params;
|
|
18
|
-
const result =
|
|
18
|
+
const result = toToolResultJson(
|
|
19
19
|
await ghExec(
|
|
20
20
|
[
|
|
21
21
|
"pr",
|
package/vendor/mihomo-linux-x64
DELETED