@trim21/personal-pi-extensions 0.1.605 → 0.1.608

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": "@trim21/personal-pi-extensions",
3
- "version": "0.1.605",
3
+ "version": "0.1.608",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
package/src/aft/bridge.ts CHANGED
@@ -26,12 +26,9 @@ import { type AftLogger, createAftLogger } from "./logger.js";
26
26
 
27
27
  export { findBinary } from "@cortexkit/aft-bridge";
28
28
 
29
- /** Pi 会话 ID:Rust 侧用它做 session 作用域(undo/checkpoint),感知工具可留空。 */
30
- export function resolveSessionId(extCtx: ExtensionContext): string | undefined {
31
- const manager = (extCtx as unknown as { sessionManager?: { getSessionId?: () => string } })
32
- .sessionManager;
33
- const id = manager?.getSessionId?.();
34
- return typeof id === "string" && id.length > 0 ? id : undefined;
29
+ /** Pi 会话 ID:Rust 侧用它做 session 作用域(undo/checkpoint)。 */
30
+ export function resolveSessionId(extCtx: ExtensionContext): string {
31
+ return extCtx.sessionManager.getSessionId();
35
32
  }
36
33
 
37
34
  export interface AftPool {
@@ -140,18 +137,20 @@ export async function createAftPool(
140
137
  *
141
138
  * `signal`:宿主取消信号,透传给 bridge 的 abortSignal——standalone transport
142
139
  * 会在 abort 时向 Rust 发 cancel_request(subc route 忽略,靠 route 关闭取消)。
140
+ *
141
+ * `sessionId` 由调用方从自己的 context 解析(工具走 resolveSessionId(ctx)),
142
+ * 独立 CLI 没有 session,传 undefined。
143
143
  */
144
144
  export async function callAftTool(
145
145
  bridge: AftProjectTransport,
146
146
  command: string,
147
147
  rawArgs: Record<string, unknown>,
148
- extCtx: ExtensionContext,
148
+ sessionId: string | undefined,
149
149
  options?: BridgeRequestOptions & { preview?: boolean },
150
150
  softCodes?: ReadonlySet<string>,
151
151
  signal?: AbortSignal,
152
152
  ): Promise<{ text: string; response: Record<string, unknown> }> {
153
153
  const timeoutMs = timeoutForCommand(command);
154
- const sessionId = resolveSessionId(extCtx);
155
154
  const sendOptions = {
156
155
  ...(timeoutMs !== undefined && { timeoutMs }),
157
156
  ...options,
@@ -168,14 +167,14 @@ export async function callAftTool(
168
167
  if (softCodes?.has(code)) {
169
168
  return {
170
169
  text: response.text || response.message || "",
171
- response: response as unknown as Record<string, unknown>,
170
+ response,
172
171
  };
173
172
  }
174
173
  throw new Error(response.text || response.message || `${command} failed`);
175
174
  }
176
175
  return {
177
176
  text: typeof response.text === "string" ? response.text : "",
178
- response: response as unknown as Record<string, unknown>,
177
+ response,
179
178
  };
180
179
  }
181
180
 
package/src/aft/tools.ts CHANGED
@@ -25,7 +25,12 @@ import { Value } from "typebox/value";
25
25
 
26
26
  import { formatDisplayPath, formatSubtitlePath, resolvePathArg } from "../lib/path.js";
27
27
  import { type ToolPendant } from "../lib/pendant.js";
28
- import { type AftState, callAftTool, SEMANTIC_INDEX_WAIT_TIMEOUT_MS } from "./bridge.js";
28
+ import {
29
+ type AftState,
30
+ callAftTool,
31
+ resolveSessionId,
32
+ SEMANTIC_INDEX_WAIT_TIMEOUT_MS,
33
+ } from "./bridge.js";
29
34
 
30
35
  /** 工具使用指南,以 markdown 形式维护,读起来像文档。 */
31
36
  const OUTLINE_PROMPT = readFileSync(
@@ -157,7 +162,7 @@ export function registerOutlineTool(pi: ExtensionAPI, ctx: AftToolContext): void
157
162
  bridgeFor(ctx),
158
163
  "outline",
159
164
  rawArgs,
160
- extCtx,
165
+ resolveSessionId(extCtx),
161
166
  undefined,
162
167
  undefined,
163
168
  signal,
@@ -236,7 +241,7 @@ export function registerZoomTool(pi: ExtensionAPI, ctx: AftToolContext): void {
236
241
  bridgeFor(ctx),
237
242
  "zoom",
238
243
  rawArgs,
239
- extCtx,
244
+ resolveSessionId(extCtx),
240
245
  undefined,
241
246
  undefined,
242
247
  signal,
@@ -343,7 +348,7 @@ export async function callCallgraphWithBuildRetry(
343
348
  bridge,
344
349
  "callgraph",
345
350
  rawArgs,
346
- extCtx,
351
+ resolveSessionId(extCtx),
347
352
  undefined,
348
353
  CALLGRAPH_SOFT_CODES,
349
354
  signal,
@@ -637,7 +642,7 @@ export function registerSearchTool(pi: ExtensionAPI, ctx: AftToolContext): void
637
642
  bridge,
638
643
  "search",
639
644
  rawArgs,
640
- extCtx,
645
+ resolveSessionId(extCtx),
641
646
  {
642
647
  // 默认 search 传输超时仅 60s,会早于索引等待(600s)触发;覆盖为等待
643
648
  // 上限 + 常规执行预算。超时只说明响应被挤掉而非 bridge 挂死,保留
@@ -329,8 +329,7 @@ export async function startNetworkStack(options: NetworkStackOptions): Promise<N
329
329
  // Node 没有公开 API 拿它(stdio[3].fd 恒为 undefined,只能读 _handle,且仅在
330
330
  // 子进程存活期间有效);pipe 要跨两个子进程共享(holder 持写端、slirp4netns
331
331
  // 持读端),所以必须把父进程侧的 fd 重新 dup 给 slirp4netns。
332
- const exitReadFd = (holder.stdio[3] as unknown as { _handle?: { fd?: number } } | null)?._handle
333
- ?.fd;
332
+ const exitReadFd = (holder.stdio[3] as { _handle?: { fd?: number } } | null)?._handle?.fd;
334
333
  if (typeof exitReadFd !== "number") {
335
334
  throw new TypeError("Failed to resolve exit-fd from holder stdio");
336
335
  }
package/src/lib/cli.ts CHANGED
@@ -127,7 +127,7 @@ function buildFlagInfos<TFlags extends TObject>(spec: CommandSpec<TFlags>): Flag
127
127
  const meta = spec.flagMeta as Record<string, FlagMeta> | undefined;
128
128
  const infos: FlagInfo[] = [];
129
129
  for (const [key, rawSchema] of Object.entries(spec.flags.properties)) {
130
- const schema = rawSchema as unknown as FlagSchema;
130
+ const schema = rawSchema as FlagSchema;
131
131
  const m = meta?.[key];
132
132
  infos.push({
133
133
  key,
package/src/lib/github.ts CHANGED
@@ -320,7 +320,7 @@ export function createGithubSearch(options: GithubClientOptions = {}): GithubSea
320
320
  q,
321
321
  per_page: limit,
322
322
  });
323
- return data.items.map((item) => normalize(item as unknown as RawSearchItem));
323
+ return data.items.map((item) => normalize(item as RawSearchItem));
324
324
  } catch (error) {
325
325
  const status = (error as { status?: number }).status;
326
326
  const message = (error as { message?: string }).message ?? String(error);
@@ -92,7 +92,7 @@ export class SqliteTalkStorage implements TalkStorage {
92
92
  listKeys(namespace: string): Promise<string[]> {
93
93
  const rows = this.db
94
94
  .prepare("SELECT key FROM talk_kv WHERE namespace = ? ORDER BY key")
95
- .all(namespace) as unknown as { key: string }[];
95
+ .all(namespace) as { key: string }[];
96
96
  return Promise.resolve(rows.map((r) => r.key));
97
97
  }
98
98
 
@@ -142,7 +142,7 @@ export class SqliteTalkStorage implements TalkStorage {
142
142
  readLog(logName: string): Promise<string[]> {
143
143
  const rows = this.db
144
144
  .prepare("SELECT line FROM talk_log WHERE name = ? ORDER BY seq")
145
- .all(logName) as unknown as { line: string }[];
145
+ .all(logName) as { line: string }[];
146
146
  return Promise.resolve(rows.map((r) => r.line));
147
147
  }
148
148
  }