@trim21/personal-pi-extensions 0.1.622 → 0.1.626

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.
@@ -103,7 +103,7 @@ export type LspConfig = Static<typeof lspConfigSchema>;
103
103
  * 解析期缺省(单一来源)。超时/LRU 与 client.create 共用 clientDefaults;
104
104
  * watch 无 client 对应项,数值在此集中。
105
105
  */
106
- export const configDefaults = {
106
+ const configDefaults = {
107
107
  watch: {
108
108
  enabled: true,
109
109
  debounceMs: 300,
@@ -119,7 +119,7 @@ const RETRY_COOLDOWN_MS = 60_000;
119
119
  const NOTIFY_INTERVAL_MS = 5 * 60_000;
120
120
 
121
121
  /** 生效的工作区监听配置(缺省值已应用)。 */
122
- export interface EffectiveWatchConfig {
122
+ interface EffectiveWatchConfig {
123
123
  enabled: boolean;
124
124
  debounceMs: number;
125
125
  flushMs: number;
@@ -388,21 +388,21 @@ interface LspState {
388
388
  }
389
389
 
390
390
  /** 渲染 LSP status 文本的回调(传入 undefined 表示清除)。 */
391
- export type StatusRenderer = (text: string | undefined) => void;
391
+ type StatusRenderer = (text: string | undefined) => void;
392
392
 
393
- export type LspInspectQuery = "definition" | "references" | "hover";
393
+ type LspInspectQuery = "definition" | "references" | "hover";
394
394
 
395
395
  /**
396
396
  * 返回类型与 query 关联:query 为 "hover" 时返回 hover 内容,否则返回位置列表。
397
397
  * 关联由 `inspect` 的重载签名建立(泛型参数下 TS 无法验证分支与返回体的对应关系,
398
398
  * 所以接口按 query 分重载,实现体只需返回这个联合)。
399
399
  */
400
- export type LspInspectResult<Q extends LspInspectQuery = LspInspectQuery> = Q extends "hover"
400
+ type LspInspectResult<Q extends LspInspectQuery = LspInspectQuery> = Q extends "hover"
401
401
  ? { serverID: string; query: "hover"; hover: Hover | null }
402
402
  : { serverID: string; query: "definition" | "references"; locations: InspectLocation[] };
403
403
 
404
404
  /** 只读符号查询的入参:query 决定返回体(见 LspInspectResult)。line / character 为 0-based。 */
405
- export interface LspInspectRequest<Q extends LspInspectQuery = LspInspectQuery> {
405
+ interface LspInspectRequest<Q extends LspInspectQuery = LspInspectQuery> {
406
406
  file: string;
407
407
  cwd: string;
408
408
  line: number;
@@ -411,7 +411,7 @@ export interface LspInspectRequest<Q extends LspInspectQuery = LspInspectQuery>
411
411
  options?: LspRequestOptions;
412
412
  }
413
413
 
414
- export interface LspRequestOptions {
414
+ interface LspRequestOptions {
415
415
  notify?: ExtensionUIContext["notify"];
416
416
  /** 中止时提前结束诊断等待(已中止时直接跳过诊断)。 */
417
417
  signal?: AbortSignal;
@@ -196,7 +196,7 @@ export function canonicalizeEdit(edit: WorkspaceEdit): string {
196
196
  const WORD_PATTERN = /[\p{L}\p{N}_$]+/gu;
197
197
 
198
198
  /** 两个路径集合是否一致(用于判断 references 结果是否收敛)。 */
199
- export function samePathSet(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean {
199
+ function samePathSet(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean {
200
200
  if (a.size !== b.size) {
201
201
  return false;
202
202
  }
@@ -36,7 +36,7 @@ export interface FileChange {
36
36
  isDirectory: boolean;
37
37
  }
38
38
 
39
- export const DEFAULT_IGNORE = [
39
+ const DEFAULT_IGNORE = [
40
40
  "**/node_modules/**",
41
41
  "**/.git/**",
42
42
  "**/dist/**",
package/src/lib/path.ts CHANGED
@@ -73,7 +73,7 @@ export function formatDisplayPath(cwd: string, filePath: string): string {
73
73
  }
74
74
 
75
75
  /** subtitle 中路径的最大显示长度,超过时退化为 `parent/basename`。 */
76
- export const MAX_SUBTITLE_PATH_LENGTH = 30;
76
+ const MAX_SUBTITLE_PATH_LENGTH = 30;
77
77
 
78
78
  function shortenSubtitlePath(filePath: string, display: string): string {
79
79
  if (display.length <= MAX_SUBTITLE_PATH_LENGTH) {
package/src/lib/proxy.ts CHANGED
@@ -37,7 +37,7 @@ export interface HttpProxySettings {
37
37
  noProxy?: string;
38
38
  }
39
39
 
40
- export function proxyConfigPath(): string {
40
+ function proxyConfigPath(): string {
41
41
  return join(homedir(), ".pi", "agent", "proxy.json");
42
42
  }
43
43
 
@@ -89,7 +89,7 @@ function normalizeProxy(value: string): string {
89
89
  * 这里是仓库里允许的同步例外)。文件不存在 = 未配置;文件读不了、JSON 非法或
90
90
  * 字段不符都直接抛。
91
91
  */
92
- export function readProxySettings(
92
+ function readProxySettings(
93
93
  configPath: string = proxyConfigPath(),
94
94
  env: NodeJS.ProcessEnv = process.env,
95
95
  ): HttpProxySettings {
@@ -20,7 +20,7 @@ export const REQUEST_POLICY_CHANNEL = "bwrap:request-policy";
20
20
 
21
21
  const requestPolicyMessageSchema = Type.Object({ denyRequests: Type.Boolean() });
22
22
 
23
- export type RequestPolicyMessage = Static<typeof requestPolicyMessageSchema>;
23
+ type RequestPolicyMessage = Static<typeof requestPolicyMessageSchema>;
24
24
 
25
25
  export interface RequestPolicy {
26
26
  /** 是否拒绝一切非沙盒请求(不弹审批框,直接拒绝)。 */
@@ -9,9 +9,9 @@ import { join } from "node:path";
9
9
  import { type Static, Type } from "typebox";
10
10
  import { Value } from "typebox/value";
11
11
 
12
- export const DEFAULT_PROVIDER_ID = "openai-cost";
13
- export const DEFAULT_PROVIDER_NAME = "OpenAI Cost";
14
- export const DEFAULT_API_KEY_ENV = "OPENAI_COST_API_KEY";
12
+ const DEFAULT_PROVIDER_ID = "openai-cost";
13
+ const DEFAULT_PROVIDER_NAME = "OpenAI Cost";
14
+ const DEFAULT_API_KEY_ENV = "OPENAI_COST_API_KEY";
15
15
  export const DEFAULT_CONTEXT_WINDOW = 128000;
16
16
  export const DEFAULT_MAX_TOKENS = 8192;
17
17
  export const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } as const;
@@ -54,7 +54,7 @@ export interface OpenaiCostConfig {
54
54
  models?: OpenaiCostModelConfig[];
55
55
  }
56
56
 
57
- export function openaiCostConfigPath(): string {
57
+ function openaiCostConfigPath(): string {
58
58
  return join(homedir(), ".pi", "agent", "openai-cost.json");
59
59
  }
60
60
 
@@ -98,7 +98,7 @@ export function costFromSseLine(line: string): number | undefined {
98
98
  }
99
99
  }
100
100
 
101
- export async function scanSseCost(body: ReadableStream<Uint8Array>): Promise<number | undefined> {
101
+ async function scanSseCost(body: ReadableStream<Uint8Array>): Promise<number | undefined> {
102
102
  const reader = body.getReader();
103
103
  const decoder = new TextDecoder();
104
104
  let buffer = "";
@@ -196,7 +196,7 @@ function messageOf(event: AssistantMessageEvent): AssistantMessage {
196
196
  return event.partial;
197
197
  }
198
198
 
199
- export function applyCostToEvent(
199
+ function applyCostToEvent(
200
200
  event: AssistantMessageEvent,
201
201
  reported: number | undefined,
202
202
  ): AssistantMessageEvent {
@@ -200,7 +200,7 @@ function isBinaryFileBySample(sample: Uint8Array): boolean {
200
200
  return nonPrintableCount / sample.length > 0.3;
201
201
  }
202
202
 
203
- export interface TruncationResult {
203
+ interface TruncationResult {
204
204
  content: string;
205
205
  truncated: boolean;
206
206
  truncatedBy: "lines" | "bytes" | null;
@@ -872,7 +872,7 @@ function registerWriteTool(
872
872
 
873
873
  // ── 入口 ─────────────────────────────────────────────────────────────────────
874
874
 
875
- export function registerFileTools(
875
+ function registerFileTools(
876
876
  pi: ExtensionAPI,
877
877
  getService: () => LspService,
878
878
  policy: RequestPolicy,
@@ -130,7 +130,7 @@ export function renderGrepOutput(matches: readonly GrepMatch[], truncated: boole
130
130
  }
131
131
 
132
132
  /** 搜索根:绝对路径原样,相对路径按调用 cwd 解析。 */
133
- export function resolveSearchRoot(path: string | undefined, cwd: string): string {
133
+ function resolveSearchRoot(path: string | undefined, cwd: string): string {
134
134
  if (path === undefined || path === "") {
135
135
  return cwd;
136
136
  }
@@ -2,9 +2,7 @@
2
2
  * opencode —— 统一注册 opencode 风格工具扩展。
3
3
  *
4
4
  * 聚合 files(read / edit / write 统一构建,共享 LSP service)、grep /
5
- * glob(ripgrep 搜索)、todo / question / bash,一次加载全部注册;各工具的
6
- * 公开 API(匹配引擎、纯函数等)也从这里重新导出,方便测试与其他模块
7
- * (如 lib/write-guard)引用。
5
+ * glob(ripgrep 搜索)、todo / question / bash,一次加载全部注册。
8
6
  *
9
7
  * Usage:
10
8
  * pi -e ./opencode/index.ts
@@ -24,28 +22,6 @@ import opencodeGrep from "./grep.js";
24
22
  import opencodeQuestion from "./question.js";
25
23
  import opencodeTodo from "./todo.js";
26
24
 
27
- export { default as opencodeBash } from "./bash.js";
28
- export {
29
- applyEdit,
30
- convertToLineEnding,
31
- detectLineEnding,
32
- normalizeForEdit,
33
- normalizeToLF,
34
- replace,
35
- restoreLineEndings,
36
- stripBom,
37
- } from "./edit-engine.js";
38
- export {
39
- default as opencodeFileTools,
40
- readLines,
41
- resolveBom,
42
- type TruncationResult,
43
- } from "./files.js";
44
- export { default as opencodeGlob } from "./glob.js";
45
- export { default as opencodeGrep } from "./grep.js";
46
- export { default as opencodeQuestion } from "./question.js";
47
- export { default as opencodeTodo } from "./todo.js";
48
-
49
25
  export default function opencode(pi: ExtensionAPI) {
50
26
  // 非沙盒请求策略由本入口创建,注入文件工具与 bash runtime 共享同一份;
51
27
  // 独立入口(web/fetch.ts 等)各自创建一份并经 pi.events 保持同步。
@@ -35,7 +35,7 @@ export const CUSTOM_LABEL = "Type your own answer.";
35
35
  export const DONE_LABEL = "✓ Done";
36
36
 
37
37
  /** 与 opencode question.txt 语义一致的描述 */
38
- export const QUESTION_DESCRIPTION = [
38
+ const QUESTION_DESCRIPTION = [
39
39
  "Use this tool when you need to ask the user questions during execution. This allows you to:",
40
40
  "1. Gather user preferences or requirements",
41
41
  "2. Clarify ambiguous instructions",
@@ -68,8 +68,6 @@ export const questionParamsSchema = Type.Object({
68
68
 
69
69
  // ── types ────────────────────────────────────────────────────────────────────
70
70
 
71
- export type QuestionOption = Static<typeof optionSchema>;
72
-
73
71
  /** 与 schema 对齐的输入形状(multiple 可选) */
74
72
  export type QuestionInput = Static<typeof questionSchema>;
75
73
 
@@ -32,14 +32,13 @@ import { type ToolPendant } from "../lib/pendant.js";
32
32
 
33
33
  export const TOOL_NAME = "todowrite";
34
34
 
35
- export const TODO_STATUSES = ["pending", "in_progress", "completed", "cancelled"] as const;
36
- export const TODO_PRIORITIES = ["high", "medium", "low"] as const;
35
+ const TODO_STATUSES = ["pending", "in_progress", "completed", "cancelled"] as const;
36
+ const TODO_PRIORITIES = ["high", "medium", "low"] as const;
37
37
 
38
- export type TodoStatus = (typeof TODO_STATUSES)[number];
39
- export type TodoPriority = (typeof TODO_PRIORITIES)[number];
38
+ type TodoStatus = (typeof TODO_STATUSES)[number];
40
39
 
41
40
  /** opencode 的 todowrite 描述(语义等价),补上「整体替换」这一关键规则 */
42
- export const TODOWRITE_DESCRIPTION = [
41
+ const TODOWRITE_DESCRIPTION = [
43
42
  "Create and maintain a structured task list for the current coding session. Tracks progress, organizes multi-step work, and surfaces status to the user.",
44
43
  "",
45
44
  "This tool REPLACES the entire todo list: pass the full updated list of todos on every call.",
@@ -35,7 +35,7 @@ export function formatDelivery(letter: Letter, now: number = Date.now()): string
35
35
  /** One agent as the model sees it in a listing. `id` is the stable pi
36
36
  * agent uuid; `name` is the display name when one was set; `self` marks
37
37
  * the calling agent itself. */
38
- export interface AgentListItem {
38
+ interface AgentListItem {
39
39
  status: string;
40
40
  work_dir: string;
41
41
  id: string;
package/src/talk/group.ts CHANGED
@@ -20,7 +20,7 @@ import { Value } from "typebox/value";
20
20
 
21
21
  import type { TalkStorage } from "./storage.js";
22
22
 
23
- export const GroupSchema = Type.Object({
23
+ const GroupSchema = Type.Object({
24
24
  id: Type.String(),
25
25
  /** pi agent uuids of the members. */
26
26
  members: Type.Array(Type.String()),
@@ -29,7 +29,7 @@ export const GroupSchema = Type.Object({
29
29
  });
30
30
  export type Group = Static<typeof GroupSchema>;
31
31
 
32
- export const GROUPS_NS = "groups";
32
+ const GROUPS_NS = "groups";
33
33
 
34
34
  /**
35
35
  * Group names are user-facing and become storage keys, so they are
@@ -38,7 +38,7 @@ export const GROUPS_NS = "groups";
38
38
  */
39
39
  const GROUP_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
40
40
 
41
- export function assertGroupId(id: string): void {
41
+ function assertGroupId(id: string): void {
42
42
  if (!GROUP_ID_PATTERN.test(id)) {
43
43
  throw new TypeError(`Invalid group name: ${id}`);
44
44
  }
@@ -22,7 +22,7 @@ import { isRecord } from "../lib/narrow.js";
22
22
  import { asksNs, assertAddress, inboxNs } from "./registry.js";
23
23
  import type { TalkStorage } from "./storage.js";
24
24
 
25
- export const LetterSchema = Type.Object({
25
+ const LetterSchema = Type.Object({
26
26
  id: Type.String(),
27
27
  from: Type.Object({
28
28
  addr: Type.String(),
@@ -48,7 +48,7 @@ export type LetterKind = Letter["kind"];
48
48
  * sender's pi session id as `from.sessionId`. Current letters pass through
49
49
  * unchanged; anything else returns null.
50
50
  */
51
- export function normalizeLetter(value: unknown): Letter | null {
51
+ function normalizeLetter(value: unknown): Letter | null {
52
52
  if (Value.Check(LetterSchema, value)) {
53
53
  return value;
54
54
  }
@@ -69,7 +69,7 @@ export function normalizeLetter(value: unknown): Letter | null {
69
69
  return Value.Check(LetterSchema, migrated) ? migrated : null;
70
70
  }
71
71
 
72
- export const OutAskSchema = Type.Object({
72
+ const OutAskSchema = Type.Object({
73
73
  askId: Type.String(),
74
74
  toAddr: Type.String(),
75
75
  body: Type.String(),
@@ -77,7 +77,7 @@ export const OutAskSchema = Type.Object({
77
77
  });
78
78
  export type OutAsk = Static<typeof OutAskSchema>;
79
79
 
80
- export const AuditRecordSchema = Type.Object({
80
+ const AuditRecordSchema = Type.Object({
81
81
  ts: Type.Number(),
82
82
  event: Type.Union([
83
83
  Type.Literal("deposit"),
@@ -112,7 +112,7 @@ function assertMessageId(id: string): void {
112
112
  }
113
113
 
114
114
  /** The storage key for a letter: `<ts>-<id>.json`, sorted oldest-first. */
115
- export function letterFileName(letter: Letter): string {
115
+ function letterFileName(letter: Letter): string {
116
116
  assertMessageId(letter.id);
117
117
  if (!Number.isSafeInteger(letter.ts) || letter.ts < 0) {
118
118
  throw new TypeError(`Invalid talk letter timestamp: ${letter.ts}`);
@@ -121,7 +121,7 @@ export function letterFileName(letter: Letter): string {
121
121
  }
122
122
 
123
123
  /** Structural validation plus filename safety (id/timestamp shape). */
124
- export function isValidLetter(value: unknown): value is Letter {
124
+ function isValidLetter(value: unknown): value is Letter {
125
125
  if (!Value.Check(LetterSchema, value)) {
126
126
  return false;
127
127
  }
@@ -8,9 +8,9 @@
8
8
 
9
9
  import { MAX_BODY_CHARS } from "./mailbox.js";
10
10
 
11
- export const DEDUPE_WINDOW_MS = 10_000;
12
- export const RATE_LIMIT_MAX = 8;
13
- export const RATE_LIMIT_WINDOW_MS = 30_000;
11
+ const DEDUPE_WINDOW_MS = 10_000;
12
+ const RATE_LIMIT_MAX = 8;
13
+ const RATE_LIMIT_WINDOW_MS = 30_000;
14
14
  export const BACKLOG_CAP = 50;
15
15
 
16
16
  export type OutboundVerdict = { ok: true } | { ok: false; reason: string };
@@ -32,7 +32,7 @@ const STATUS_SCHEMA = Type.Union([
32
32
  Type.Literal("waiting-talk-message"),
33
33
  ]);
34
34
 
35
- export const AgentRecordSchema = Type.Object({
35
+ const AgentRecordSchema = Type.Object({
36
36
  addr: Type.String(),
37
37
  agentId: Type.String(),
38
38
  name: Type.String(),
@@ -69,9 +69,9 @@ const LegacyAgentRecordSchema = Type.Object({
69
69
  export type Presence = "live" | "offline";
70
70
 
71
71
  /** Sweep leaves a record alone until its last activity was this long ago. */
72
- export const SWEEP_OFFLINE_GRACE_MS = 24 * 60 * 60 * 1000;
72
+ const SWEEP_OFFLINE_GRACE_MS = 24 * 60 * 60 * 1000;
73
73
  /** A mailbox holding undelivered mail is kept this long after last contact. */
74
- export const SWEEP_MAIL_KEEP_MS = 30 * 24 * 60 * 60 * 1000;
74
+ const SWEEP_MAIL_KEEP_MS = 30 * 24 * 60 * 60 * 1000;
75
75
 
76
76
  const ADDRESS_PATTERN = /^[a-f0-9]{12}$/;
77
77
 
@@ -88,7 +88,7 @@ export function assertAddress(addr: string): void {
88
88
 
89
89
  // ── Storage namespaces ───────────────────────────────────────────────────
90
90
 
91
- export const RECORDS_NS = "records";
91
+ const RECORDS_NS = "records";
92
92
 
93
93
  export function inboxNs(addr: string): string {
94
94
  assertAddress(addr);
package/src/web/config.ts CHANGED
@@ -13,7 +13,7 @@ const webSearchSchema = Type.Object({
13
13
  search1apiApiKey: Type.Optional(Type.String()),
14
14
  });
15
15
 
16
- export function webSearchConfigPath(): string {
16
+ function webSearchConfigPath(): string {
17
17
  return join(homedir(), ".pi", "web-search.json");
18
18
  }
19
19