@trim21/personal-pi-extensions 0.0.194 → 0.0.195
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 +3 -1
- package/package.json +1 -1
- package/src/bwrap/index.ts +3 -10
- package/src/lib/path.ts +28 -0
- package/src/talk/index.ts +5 -2
- package/src/workspace-guard.ts +4 -15
package/README.md
CHANGED
|
@@ -256,10 +256,12 @@ sqlite 文件路径按优先级取第一个可用值:
|
|
|
256
256
|
2. global `~/.pi/agent/settings.json` 里的 `talk.db_path`
|
|
257
257
|
3. 默认 `~/.pi/agent/talk.db`
|
|
258
258
|
|
|
259
|
+
`db_path` 支持 `~` 展开(`~/…` → 用户主目录),相对路径相对 `~/.pi/agent` 解析;绝对路径原样使用。
|
|
260
|
+
|
|
259
261
|
```jsonc
|
|
260
262
|
// ~/.pi/agent/settings.json
|
|
261
263
|
{
|
|
262
|
-
"talk": { "db_path": "/
|
|
264
|
+
"talk": { "db_path": "~/data/talk.db" },
|
|
263
265
|
}
|
|
264
266
|
```
|
|
265
267
|
|
package/package.json
CHANGED
package/src/bwrap/index.ts
CHANGED
|
@@ -67,6 +67,8 @@ import { type BashOperations, createBashTool, getAgentDir } from "@earendil-work
|
|
|
67
67
|
import { Type } from "typebox";
|
|
68
68
|
import { Value } from "typebox/value";
|
|
69
69
|
|
|
70
|
+
import { expandHome } from "../lib/path.js";
|
|
71
|
+
|
|
70
72
|
const SANDBOX_PROMPT = `
|
|
71
73
|
## Command Execution
|
|
72
74
|
You are running inside a sandbox.
|
|
@@ -232,17 +234,8 @@ function deepMerge(base: BwrapConfig, overrides: Partial<BwrapConfig>): BwrapCon
|
|
|
232
234
|
};
|
|
233
235
|
}
|
|
234
236
|
|
|
235
|
-
function expandPath(p: string): string {
|
|
236
|
-
if (p.startsWith("~/")) {
|
|
237
|
-
const home = process.env.HOME;
|
|
238
|
-
if (home === undefined) return p;
|
|
239
|
-
return join(home, p.slice(2));
|
|
240
|
-
}
|
|
241
|
-
return p;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
237
|
function resolvePath(p: string, cwd: string): string {
|
|
245
|
-
const expanded =
|
|
238
|
+
const expanded = expandHome(p);
|
|
246
239
|
if (expanded === ".") return cwd;
|
|
247
240
|
return expanded;
|
|
248
241
|
}
|
package/src/lib/path.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path helpers used by multiple extensions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Expand a leading `~` to the user's home directory.
|
|
10
|
+
* - `~` → home
|
|
11
|
+
* - `~/rest` → `home/rest`
|
|
12
|
+
* - anything else (including `~user`) is left untouched.
|
|
13
|
+
*/
|
|
14
|
+
export function expandHome(p: string): string {
|
|
15
|
+
if (p === "~") return homedir();
|
|
16
|
+
if (p.startsWith("~/")) return join(homedir(), p.slice(2));
|
|
17
|
+
return p;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a path that may start with `~` (expanded to home) and may be
|
|
22
|
+
* relative (resolved against `baseDir`). Absolute paths are returned
|
|
23
|
+
* normalized.
|
|
24
|
+
*/
|
|
25
|
+
export function resolveHomePath(p: string, baseDir: string): string {
|
|
26
|
+
const expanded = expandHome(p);
|
|
27
|
+
return isAbsolute(expanded) ? resolve(expanded) : resolve(baseDir, expanded);
|
|
28
|
+
}
|
package/src/talk/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
|
17
17
|
import { Box, Text } from "@earendil-works/pi-tui";
|
|
18
18
|
import { Type } from "typebox";
|
|
19
19
|
|
|
20
|
+
import { resolveHomePath } from "../lib/path.js";
|
|
20
21
|
import { TalkCore } from "./core.js";
|
|
21
22
|
import { formatDelivery } from "./format.js";
|
|
22
23
|
import type { Letter } from "./mailbox.js";
|
|
@@ -117,8 +118,10 @@ function readDbPathFromSettings(): string | undefined {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
export default function talk(pi: ExtensionAPI) {
|
|
120
|
-
const
|
|
121
|
-
|
|
121
|
+
const configured = process.env.PI_TALK_DB ?? readDbPathFromSettings();
|
|
122
|
+
const dbPath = configured
|
|
123
|
+
? resolveHomePath(configured, getAgentDir())
|
|
124
|
+
: path.join(getAgentDir(), "talk.db");
|
|
122
125
|
const storage = new SqliteTalkStorage(dbPath);
|
|
123
126
|
|
|
124
127
|
let self: SessionRecord | undefined;
|
package/src/workspace-guard.ts
CHANGED
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
16
|
-
import {
|
|
17
|
-
import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
16
|
+
import { basename, isAbsolute, relative, sep } from "node:path";
|
|
18
17
|
|
|
19
18
|
import {
|
|
20
19
|
type ExtensionAPI,
|
|
@@ -22,6 +21,7 @@ import {
|
|
|
22
21
|
type ToolCallEvent,
|
|
23
22
|
} from "@earendil-works/pi-coding-agent";
|
|
24
23
|
|
|
24
|
+
import { resolveHomePath } from "./lib/path.js";
|
|
25
25
|
import { normalizeForEdit, replace } from "./opencode-edit-engine.js";
|
|
26
26
|
|
|
27
27
|
const WRITE_TOOLS = new Set(["write", "edit"]);
|
|
@@ -37,17 +37,6 @@ export function getWriteTarget(input: ToolCallEvent["input"]): string | undefine
|
|
|
37
37
|
return undefined;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function resolvePath(filePath: string, cwd: string): string {
|
|
41
|
-
let p = filePath;
|
|
42
|
-
if (p.startsWith("~")) {
|
|
43
|
-
const rest = p.slice(1);
|
|
44
|
-
if (rest === "" || rest.startsWith("/")) {
|
|
45
|
-
p = join(homedir(), rest.slice(1));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return isAbsolute(p) ? resolve(p) : resolve(cwd, p);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
40
|
function isInside(dir: string, filePath: string): boolean {
|
|
52
41
|
const rel = relative(dir, filePath);
|
|
53
42
|
return rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
|
|
@@ -57,7 +46,7 @@ function isPathAllowed(resolvedPath: string, cwd: string): boolean {
|
|
|
57
46
|
if (isInside(cwd, resolvedPath)) return true;
|
|
58
47
|
|
|
59
48
|
for (const allowed of ALWAYS_ALLOW) {
|
|
60
|
-
const resolvedAllowed =
|
|
49
|
+
const resolvedAllowed = resolveHomePath(allowed, cwd);
|
|
61
50
|
if (isInside(resolvedAllowed, resolvedPath)) return true;
|
|
62
51
|
}
|
|
63
52
|
|
|
@@ -214,7 +203,7 @@ export default function workspaceGuard(pi: ExtensionAPI) {
|
|
|
214
203
|
const rawPath = getWriteTarget(event.input);
|
|
215
204
|
if (!rawPath) return;
|
|
216
205
|
|
|
217
|
-
const resolved =
|
|
206
|
+
const resolved = resolveHomePath(rawPath, ctx.cwd);
|
|
218
207
|
|
|
219
208
|
if (isPathAllowed(resolved, ctx.cwd)) return;
|
|
220
209
|
|