@trim21/personal-pi-extensions 0.1.683 → 0.1.685

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
@@ -36,12 +36,14 @@
36
36
  - **嵌套调用经工具总线**:`call("Bash", { command })` 最终执行的是 `Bash` 工具自己的
37
37
  `execute`,所以工具的审批照常生效(Bash 沙箱外执行会弹自己的提权确认)。codemode
38
38
  不额外加确认层:脚本里连发十次调用就是十次工具自己的审批(需要审批的那些)。
39
- - **可调用集合** = 总线上实际注册的工具减去排除名单,执行时再与当前 active 列表求交,
40
- 所以 `personalExtensions.disabledTools`、pi 的 `defaultTools` / `--tools`、子代理的工具
41
- 白名单都同样约束脚本。排除名单:`codemode` 自身与 `spawn-agent`;两套文件工具集的
42
- 读写工具(`Read`/`Edit`/`Write` 与 `read`/`edit`/`write`);两套工具集的搜索工具
43
- (`Grep`/`Glob` 与 `grep`/`glob`)——脚本搜文件用 `call("Bash", { command: "rg …" })`,
44
- 走同一个沙箱、拿得到退出码,还能拼管道,而那两个工具是给模型看结果的。
39
+ - **可调用集合 = 声明了结构化输出的工具**(有 `structuredSchema` 的才进),执行时再与当前
40
+ active 列表求交,所以 `personalExtensions.disabledTools`、pi 的 `defaultTools` /
41
+ `--tools`、子代理的工具白名单都同样约束脚本。脚本拿到的返回值必须有确定的形状,因此没给
42
+ 结构化结果的工具不进集合——这条规则自己维持一致,不需要维护一份会漂移的黑名单。由此天然
43
+ 不在集合里的:`codemode` 自身与 `spawn-agent`、文件读写工具(脚本用 `fs.read` /
44
+ `fs.write`)、搜索工具(脚本用 `call("Bash", { command: "rg …" })`,走同一个沙箱、拿得到
45
+ 退出码,还能拼管道)、`lsp-rename`(写工具)以及 talk / 会话工具(会把执行时间交给外部
46
+ 输入)。
45
47
  - **文件读写只有 `fs` 一条路**:`fs.read(path)` 返回文件全文的原始 UTF-8 文本(不加行号、
46
48
  不截断、不设大小上限,只有内容不是合法 UTF-8 时报错),`fs.write(path, content)` 整体写入并自动创建
47
49
  父目录,相对路径相对当前 cwd。`fs.write` 与写类工具共用同一套保护:写前要求「已读且读后
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.1.683",
3
+ "version": "0.1.685",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -0,0 +1,246 @@
1
+ /**
2
+ * AFT 感知工具的结构化结果 schema。
3
+ *
4
+ * 载荷就是引擎自己的响应字段(去掉 envelope 的 request id),外加一个 `text`——我们自己
5
+ * 渲染(或引擎渲染)的文本,与工具输出一致。字段名与类型来自三处证据:
6
+ *
7
+ * - 本仓库对真引擎的实测响应(outline 两种模式、zoom,见 `test/fixtures/aft/`);
8
+ * - `@cortexkit/aft-bridge` 自己的格式化器读哪些字段(callgraph 各 op、zoom 的注解);
9
+ * - 引擎的 `ListEnvelope` / 截断字段(walk_truncated、collection_truncated、truncated)。
10
+ *
11
+ * 两条刻意的宽松:
12
+ *
13
+ * 1. 所有引擎字段都是可选、且允许额外字段(`additionalProperties: true`)。引擎不归我们
14
+ * 管,它的响应会加字段、换字段名;声明成必需会让版本一升级就把工具调用变成失败。
15
+ * 2. 嵌套条目(callgraph 的调用点、搜索命中等)把已知字段列全但全部可选——引擎自己也用
16
+ * `?? "(unknown)"` 兜底,说明这些字段并非永远在场。
17
+ *
18
+ * 载荷只经总线 `Value.Parse` 复核一次(见 `src/lib/tool-bus.ts`),因此「宽松」不等于
19
+ * 不校验:`text` 必需,列出的字段类型必须对得上。
20
+ */
21
+
22
+ import { Type } from "typebox";
23
+
24
+ /** 引擎渲染的文本,与工具输出一致。 */
25
+ const text = Type.String({ description: "引擎渲染的文本,与工具输出一致" });
26
+
27
+ /** 行号区间(zoom):引擎的 Range 序列化时行号从 1 开始。 */
28
+ const rangeSchema = Type.Object(
29
+ {
30
+ start_line: Type.Number(),
31
+ end_line: Type.Number(),
32
+ start_col: Type.Optional(Type.Number()),
33
+ end_col: Type.Optional(Type.Number()),
34
+ },
35
+ { additionalProperties: true },
36
+ );
37
+
38
+ /** 调用图注解里的一条引用(zoom 的 calls_out / called_by)。 */
39
+ const callRefSchema = Type.Object(
40
+ {
41
+ name: Type.String(),
42
+ line: Type.Number(),
43
+ /** 同一行上还有多少条同类引用被折叠。 */
44
+ extra_count: Type.Optional(Type.Number()),
45
+ },
46
+ { additionalProperties: true },
47
+ );
48
+
49
+ /** `aft_outline`:单文件模式只有 text(引擎不返回符号树),files 模式带文件条目。 */
50
+ export const aftOutlineStructuredSchema = Type.Object(
51
+ {
52
+ text,
53
+ /** 引擎是否确定给全了结果。 */
54
+ complete: Type.Optional(Type.Boolean()),
55
+ /** files 模式(目录 + files: true)的文件条目。 */
56
+ files: Type.Optional(
57
+ Type.Array(
58
+ Type.Object(
59
+ {
60
+ path: Type.String(),
61
+ language: Type.String(),
62
+ /** 顶层符号数;未知时引擎省略该字段。 */
63
+ symbols: Type.Optional(Type.Number()),
64
+ /** 行数;null 表示不在索引里(line_count_gaps 列出这些文件)。 */
65
+ lines: Type.Union([Type.Number(), Type.Null()]),
66
+ },
67
+ { additionalProperties: true },
68
+ ),
69
+ ),
70
+ ),
71
+ /** 目录遍历触到上限。 */
72
+ walk_truncated: Type.Optional(Type.Boolean()),
73
+ /** 条目收集触到上限。 */
74
+ collection_truncated: Type.Optional(Type.Boolean()),
75
+ },
76
+ { additionalProperties: true },
77
+ );
78
+
79
+ /** `aft_zoom`:单符号源码 + 行号区间 + 同文件调用注解。 */
80
+ export const aftZoomStructuredSchema = Type.Object(
81
+ {
82
+ text,
83
+ /** 符号名;行范围模式是 "lines X-Y",符号歧义时缺省。 */
84
+ name: Type.Optional(Type.String()),
85
+ /** function / class / method / lines / ambiguous_symbol … */
86
+ kind: Type.Optional(Type.String()),
87
+ range: Type.Optional(rangeSchema),
88
+ /** 符号源码(不含上下文行)。 */
89
+ content: Type.Optional(Type.String()),
90
+ context_before: Type.Optional(Type.Array(Type.String())),
91
+ context_after: Type.Optional(Type.Array(Type.String())),
92
+ annotations: Type.Optional(
93
+ Type.Object(
94
+ {
95
+ calls_out: Type.Optional(Type.Array(callRefSchema)),
96
+ called_by: Type.Optional(Type.Array(callRefSchema)),
97
+ },
98
+ { additionalProperties: true },
99
+ ),
100
+ ),
101
+ },
102
+ { additionalProperties: true },
103
+ );
104
+
105
+ /** 调用图上的一条位置(callers 的调用点、impact 的受害点)。 */
106
+ const callgraphSiteSchema = Type.Object(
107
+ {
108
+ file: Type.Optional(Type.String()),
109
+ line: Type.Optional(Type.Number()),
110
+ /** callers 分组的调用符号名。 */
111
+ symbol: Type.Optional(Type.String()),
112
+ /** impact 的调用点符号名(与 caller_file 成对)。 */
113
+ caller_symbol: Type.Optional(Type.String()),
114
+ caller_file: Type.Optional(Type.String()),
115
+ /** impact:该调用点自身是入口(脚本常据此过滤)。 */
116
+ is_entry_point: Type.Optional(Type.Boolean()),
117
+ /** 仅按名字解析出来的边(可能指向同名符号)。 */
118
+ approximate: Type.Optional(Type.Boolean()),
119
+ /** "name_match" 等解析来源。 */
120
+ resolved_by: Type.Optional(Type.String()),
121
+ },
122
+ { additionalProperties: true },
123
+ );
124
+
125
+ /** 调用链上的一跳(trace_to / trace_to_symbol)。 */
126
+ const callgraphHopSchema = Type.Object(
127
+ {
128
+ symbol: Type.Optional(Type.String()),
129
+ file: Type.Optional(Type.String()),
130
+ line: Type.Optional(Type.Number()),
131
+ is_entry_point: Type.Optional(Type.Boolean()),
132
+ /** trace_data:该跳流转的变量名与流向。 */
133
+ variable: Type.Optional(Type.String()),
134
+ flow_type: Type.Optional(Type.String()),
135
+ approximate: Type.Optional(Type.Boolean()),
136
+ resolved_by: Type.Optional(Type.String()),
137
+ },
138
+ { additionalProperties: true },
139
+ );
140
+
141
+ /**
142
+ * `aft_callgraph`:一个工具名下 6 个 op,响应形状各不同(callers 是分组列表、call_tree 是
143
+ * 树、impact 是扁平调用点、trace_to 是路径列表、trace_to_symbol 是单条路径、trace_data 是
144
+ * 数据流跳)。这里把各 op 的锚点与列表都列为可选字段,脚本按 op 取用。
145
+ */
146
+ export const aftCallgraphStructuredSchema = Type.Object(
147
+ {
148
+ text,
149
+ /** 被查询的符号(callers / impact 的锚点)。 */
150
+ symbol: Type.Optional(Type.String()),
151
+ file: Type.Optional(Type.String()),
152
+ /** call_tree 根节点的锚点。 */
153
+ name: Type.Optional(Type.String()),
154
+ line: Type.Optional(Type.Number()),
155
+ signature: Type.Optional(Type.String()),
156
+ /** callers:按文件分组的调用点。 */
157
+ callers: Type.Optional(
158
+ Type.Array(
159
+ Type.Object(
160
+ {
161
+ file: Type.Optional(Type.String()),
162
+ callers: Type.Optional(Type.Array(callgraphSiteSchema)),
163
+ },
164
+ { additionalProperties: true },
165
+ ),
166
+ ),
167
+ ),
168
+ /** call_tree 根节点的直接子节点(整棵树在 payload 里,这里只标出形状)。 */
169
+ children: Type.Optional(Type.Array(Type.Unknown())),
170
+ /** call_tree 节点是否解析到定义;false 且无子节点 = 未解析的叶子。 */
171
+ resolved: Type.Optional(Type.Boolean()),
172
+ total_callers: Type.Optional(Type.Number()),
173
+ total_affected: Type.Optional(Type.Number()),
174
+ affected_files: Type.Optional(Type.Number()),
175
+ /** impact 的参数表(改签名时要知道)。 */
176
+ parameters: Type.Optional(Type.Array(Type.String())),
177
+ /** trace_to:到目标符号的路径,每条路径是一串跳。 */
178
+ paths: Type.Optional(
179
+ Type.Array(
180
+ Type.Object(
181
+ { hops: Type.Optional(Type.Array(callgraphHopSchema)) },
182
+ { additionalProperties: true },
183
+ ),
184
+ ),
185
+ ),
186
+ total_paths: Type.Optional(Type.Number()),
187
+ /** trace_to_symbol:单条最短路径(没有路径时为 null)。 */
188
+ path: Type.Optional(Type.Union([Type.Array(callgraphHopSchema), Type.Null()])),
189
+ /** trace_data:值在赋值/参数/返回间的流转。 */
190
+ hops: Type.Optional(Type.Array(callgraphHopSchema)),
191
+ depth_limited: Type.Optional(Type.Boolean()),
192
+ /** 因结果上限被折叠的条目数(引擎给的是数字,不是布尔)。 */
193
+ truncated: Type.Optional(Type.Number()),
194
+ /** 软失败(symbol_not_found / callgraph_building …)的错误码。 */
195
+ code: Type.Optional(Type.String()),
196
+ },
197
+ { additionalProperties: true },
198
+ );
199
+
200
+ /** 搜索命中:常规 ranking 条目(symbol)与降级时的 grep 行共用一份宽条目。 */
201
+ const searchHitSchema = Type.Object(
202
+ {
203
+ file: Type.Optional(Type.String()),
204
+ name: Type.Optional(Type.String()),
205
+ kind: Type.Optional(Type.String()),
206
+ start_line: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
207
+ end_line: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
208
+ /** "matching line" / "line range" / "[file summary]" / "GrepLine"。 */
209
+ location: Type.Optional(Type.String()),
210
+ score: Type.Optional(Type.Number()),
211
+ source: Type.Optional(Type.String()),
212
+ semantic_score: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
213
+ lexical_score: Type.Optional(Type.Union([Type.Number(), Type.Null()])),
214
+ exact: Type.Optional(Type.Boolean()),
215
+ snippet: Type.Optional(Type.String()),
216
+ /** grep 行条目:行号、列号与命中文本。 */
217
+ line: Type.Optional(Type.Number()),
218
+ column: Type.Optional(Type.Number()),
219
+ line_text: Type.Optional(Type.String()),
220
+ match_text: Type.Optional(Type.String()),
221
+ },
222
+ { additionalProperties: true },
223
+ );
224
+
225
+ /** `aft_search`:查询解释 + 命中列表 + 截断/降级状态。 */
226
+ export const aftSearchStructuredSchema = Type.Object(
227
+ {
228
+ text,
229
+ query: Type.Optional(Type.String()),
230
+ /** 引擎对查询的最终解释(regex / literal / semantic / hybrid)。 */
231
+ interpreted_as: Type.Optional(Type.String()),
232
+ result_count: Type.Optional(Type.Number()),
233
+ complete: Type.Optional(Type.Boolean()),
234
+ /** 还有更多命中没给(与分页上限的区别由引擎的 envelope 说明)。 */
235
+ more_available: Type.Optional(Type.Boolean()),
236
+ engine_capped: Type.Optional(Type.Boolean()),
237
+ /** 语义索引状态:ready / building / disabled / unavailable / external。 */
238
+ semantic_status: Type.Optional(Type.String()),
239
+ results: Type.Optional(Type.Array(searchHitSchema)),
240
+ /** 引擎给出的警告(索引降级等),原样转发。 */
241
+ warnings: Type.Optional(Type.Array(Type.String())),
242
+ /** 软失败(search_lanes_unavailable …)的错误码。 */
243
+ code: Type.Optional(Type.String()),
244
+ },
245
+ { additionalProperties: true },
246
+ );