@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 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": "/path/to/talk.db" },
264
+ "talk": { "db_path": "~/data/talk.db" },
263
265
  }
264
266
  ```
265
267
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.0.194",
3
+ "version": "0.0.195",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -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 = expandPath(p);
238
+ const expanded = expandHome(p);
246
239
  if (expanded === ".") return cwd;
247
240
  return expanded;
248
241
  }
@@ -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 dbPath =
121
- process.env.PI_TALK_DB ?? readDbPathFromSettings() ?? path.join(getAgentDir(), "talk.db");
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;
@@ -13,8 +13,7 @@
13
13
  */
14
14
 
15
15
  import { readFile } from "node:fs/promises";
16
- import { homedir } from "node:os";
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 = resolvePath(allowed, cwd);
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 = resolvePath(rawPath, ctx.cwd);
206
+ const resolved = resolveHomePath(rawPath, ctx.cwd);
218
207
 
219
208
  if (isPathAllowed(resolved, ctx.cwd)) return;
220
209