@trim21/personal-pi-extensions 0.1.662 → 0.1.664

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
@@ -43,7 +43,8 @@
43
43
  - **只有脚本输出进上下文**:`text(value)` / `console.log(...)` 与 `return` 值进入工具结果,
44
44
  中间的工具调用与它们的返回内容不会(也不在会话记录里留下工具调用条目)。
45
45
  - **脚本接口**:`tools` / `ALL_TOOLS` / `text` / `image` / `exit` / `console.*` /
46
- `store(key, value)` / `load(key)`;首行可选 `// @options: {"max_output_tokens": 10000}`。
46
+ `store.set` / `store.get` / `store.list`(会话内持久的键值表);首行可选
47
+ `// @options: {"max_output_tokens": 10000}`。
47
48
  脚本没有超时:死循环由调用方中止(Esc)结束,等嵌套调用返回(含用户审批弹窗)多久都不算超时。
48
49
  - **store** 记在每次成功调用工具结果的 `details.store` 上(与 `src/lib/file-reads.ts` 的
49
50
  已读记账同一套做法),下一次调用从当前分支的 toolResult 重放;输出超过 `max_output_tokens`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.1.662",
3
+ "version": "0.1.664",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -97,7 +97,6 @@ export function renderDeclarations(tools: readonly ToolLike[]): string {
97
97
  "declare function text(value: unknown): void;",
98
98
  "declare function image(value: unknown): void;",
99
99
  "declare function exit(): void;",
100
- "declare function store(key: string, value: unknown): void;",
101
- "declare function load(key: string): unknown;",
100
+ "declare const store: { set(key: string, value: unknown): void; get(key: string): unknown; list(): string[] };",
102
101
  ].join("\n");
103
102
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * codemode 脚本侧的 prelude:在 QuickJS VM 里先于脚本求值,构建脚本能看到的全部
3
- * 能力(`tools` / `ALL_TOOLS` / `text` / `image` / `exit` / `console` / `store` /
4
- * `load`),并把宿主桥接封在闭包里——脚本拿不到 `bridge` 本身。
3
+ * 能力(`tools` / `ALL_TOOLS` / `text` / `image` / `exit` / `console` / `store`),
4
+ * 并把宿主桥接封在闭包里——脚本拿不到 `bridge` 本身。
5
5
  *
6
6
  * 值与参数过桥时都是 JSON 文本,本侧负责 parse/stringify;异步调用用一个 pending
7
7
  * 表把 id 映射到 promise,由宿主在结果到达时 settle。
@@ -13,7 +13,7 @@
13
13
  * - `"done"`(ok, valueJsonOrErrorJson, writesJson)
14
14
  */
15
15
 
16
- /** `store()` 单个值的 JSON 上限(字符数)。 */
16
+ /** `store.set()` 单个值的 JSON 上限(字符数)。 */
17
17
  export const MAX_STORE_VALUE_CHARS = 256 * 1024;
18
18
  /** 全部 store 值的 JSON 上限(字符数)。 */
19
19
  export const MAX_STORE_TOTAL_CHARS = 1024 * 1024;
@@ -118,41 +118,47 @@ export const PRELUDE_SOURCE = String.raw`(function (bridge, toolsJson, storeJson
118
118
  if (typeof key !== "string") throw new TypeErrorCtor(name + "() key must be a string");
119
119
  }
120
120
 
121
- function store(key, value) {
122
- checkKey("store", key);
123
- const previous = stored.has(key) ? key.length + stored.get(key).length : 0;
124
- if (value === undefined) {
125
- stored.delete(key);
126
- storedChars -= previous;
127
- writes.set(key, undefined);
128
- return;
129
- }
130
- let json;
131
- try {
132
- json = stringify(value);
133
- } catch (error) {
134
- throw new TypeErrorCtor("store(" + stringify(key) + ") value is not JSON-serializable: " + format(error));
135
- }
136
- if (json === undefined) {
137
- throw new TypeErrorCtor("store(" + stringify(key) + ") value is not JSON-serializable");
138
- }
139
- if (json.length > ${MAX_STORE_VALUE_CHARS}) {
140
- throw new RangeError("store(" + stringify(key) + ") value exceeds ${MAX_STORE_VALUE_CHARS} characters of JSON");
141
- }
142
- const next = storedChars - previous + key.length + json.length;
143
- if (next > ${MAX_STORE_TOTAL_CHARS}) {
144
- throw new RangeError("store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON");
145
- }
146
- stored.set(key, json);
147
- storedChars = next;
148
- writes.set(key, json);
149
- }
150
-
151
- function load(key) {
152
- checkKey("load", key);
153
- const json = stored.get(key);
154
- return json === undefined ? undefined : parse(json);
155
- }
121
+ // 脚本侧是一个键值表:store.set / store.get / store.list,数据本身留在闭包里
122
+ const store = Object.freeze({
123
+ set(key, value) {
124
+ checkKey("store.set", key);
125
+ const previous = stored.has(key) ? key.length + stored.get(key).length : 0;
126
+ if (value === undefined) {
127
+ stored.delete(key);
128
+ storedChars -= previous;
129
+ writes.set(key, undefined);
130
+ return;
131
+ }
132
+ let json;
133
+ try {
134
+ json = stringify(value);
135
+ } catch (error) {
136
+ throw new TypeErrorCtor("store.set(" + stringify(key) + ") value is not JSON-serializable: " + format(error));
137
+ }
138
+ if (json === undefined) {
139
+ throw new TypeErrorCtor("store.set(" + stringify(key) + ") value is not JSON-serializable");
140
+ }
141
+ if (json.length > ${MAX_STORE_VALUE_CHARS}) {
142
+ throw new RangeError("store.set(" + stringify(key) + ") value exceeds ${MAX_STORE_VALUE_CHARS} characters of JSON");
143
+ }
144
+ const next = storedChars - previous + key.length + json.length;
145
+ if (next > ${MAX_STORE_TOTAL_CHARS}) {
146
+ throw new RangeError("store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON");
147
+ }
148
+ stored.set(key, json);
149
+ storedChars = next;
150
+ writes.set(key, json);
151
+ },
152
+ get(key) {
153
+ checkKey("store.get", key);
154
+ const json = stored.get(key);
155
+ return json === undefined ? undefined : parse(json);
156
+ },
157
+ // 升序返回当前键:上下文压缩后模型可以靠它找回自己写过的名字
158
+ list() {
159
+ return Array.from(stored.keys()).sort();
160
+ },
161
+ });
156
162
 
157
163
  function serializeWrites() {
158
164
  const entries = [];
@@ -161,7 +167,6 @@ export const PRELUDE_SOURCE = String.raw`(function (bridge, toolsJson, storeJson
161
167
  }
162
168
 
163
169
  Object.defineProperty(globalThis, "store", { value: store, enumerable: true });
164
- Object.defineProperty(globalThis, "load", { value: load, enumerable: true });
165
170
 
166
171
  // 原始值转字符串,其余 JSON 化
167
172
  function outputText(value) {
@@ -73,7 +73,8 @@ function buildDescription(tools: readonly CallableTool[]): string {
73
73
  " and a failing tool rejects with an `Error` you can catch.",
74
74
  "- Only what the script passes to `text(value)` / `console.log(...)` and its `return` value enter",
75
75
  " this conversation; nested calls and their results stay out of it.",
76
- "- `store(key, value)` and `load(key)` keep values across codemode calls in this session.",
76
+ "- `store.set(key, value)`, `store.get(key)` and `store.list()` are a small key/value store that",
77
+ " persists across codemode calls in this session; `store.set(key, undefined)` removes a key.",
77
78
  "- The sandbox has no file system, network, timers or Node APIs: calling tools is its only",
78
79
  " capability. Tool calls still go through each tool's own approvals, so a call that needs the",
79
80
  " user's consent will ask for it.",
@@ -103,41 +103,47 @@ var PRELUDE_SOURCE = String.raw`(function (bridge, toolsJson, storeJson) {
103
103
  if (typeof key !== "string") throw new TypeErrorCtor(name + "() key must be a string");
104
104
  }
105
105
 
106
- function store(key, value) {
107
- checkKey("store", key);
108
- const previous = stored.has(key) ? key.length + stored.get(key).length : 0;
109
- if (value === undefined) {
110
- stored.delete(key);
111
- storedChars -= previous;
112
- writes.set(key, undefined);
113
- return;
114
- }
115
- let json;
116
- try {
117
- json = stringify(value);
118
- } catch (error) {
119
- throw new TypeErrorCtor("store(" + stringify(key) + ") value is not JSON-serializable: " + format(error));
120
- }
121
- if (json === undefined) {
122
- throw new TypeErrorCtor("store(" + stringify(key) + ") value is not JSON-serializable");
123
- }
124
- if (json.length > ${MAX_STORE_VALUE_CHARS}) {
125
- throw new RangeError("store(" + stringify(key) + ") value exceeds ${MAX_STORE_VALUE_CHARS} characters of JSON");
126
- }
127
- const next = storedChars - previous + key.length + json.length;
128
- if (next > ${MAX_STORE_TOTAL_CHARS}) {
129
- throw new RangeError("store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON");
130
- }
131
- stored.set(key, json);
132
- storedChars = next;
133
- writes.set(key, json);
134
- }
135
-
136
- function load(key) {
137
- checkKey("load", key);
138
- const json = stored.get(key);
139
- return json === undefined ? undefined : parse(json);
140
- }
106
+ // 脚本侧是一个键值表:store.set / store.get / store.list,数据本身留在闭包里
107
+ const store = Object.freeze({
108
+ set(key, value) {
109
+ checkKey("store.set", key);
110
+ const previous = stored.has(key) ? key.length + stored.get(key).length : 0;
111
+ if (value === undefined) {
112
+ stored.delete(key);
113
+ storedChars -= previous;
114
+ writes.set(key, undefined);
115
+ return;
116
+ }
117
+ let json;
118
+ try {
119
+ json = stringify(value);
120
+ } catch (error) {
121
+ throw new TypeErrorCtor("store.set(" + stringify(key) + ") value is not JSON-serializable: " + format(error));
122
+ }
123
+ if (json === undefined) {
124
+ throw new TypeErrorCtor("store.set(" + stringify(key) + ") value is not JSON-serializable");
125
+ }
126
+ if (json.length > ${MAX_STORE_VALUE_CHARS}) {
127
+ throw new RangeError("store.set(" + stringify(key) + ") value exceeds ${MAX_STORE_VALUE_CHARS} characters of JSON");
128
+ }
129
+ const next = storedChars - previous + key.length + json.length;
130
+ if (next > ${MAX_STORE_TOTAL_CHARS}) {
131
+ throw new RangeError("store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON");
132
+ }
133
+ stored.set(key, json);
134
+ storedChars = next;
135
+ writes.set(key, json);
136
+ },
137
+ get(key) {
138
+ checkKey("store.get", key);
139
+ const json = stored.get(key);
140
+ return json === undefined ? undefined : parse(json);
141
+ },
142
+ // 升序返回当前键:上下文压缩后模型可以靠它找回自己写过的名字
143
+ list() {
144
+ return Array.from(stored.keys()).sort();
145
+ },
146
+ });
141
147
 
142
148
  function serializeWrites() {
143
149
  const entries = [];
@@ -146,7 +152,6 @@ var PRELUDE_SOURCE = String.raw`(function (bridge, toolsJson, storeJson) {
146
152
  }
147
153
 
148
154
  Object.defineProperty(globalThis, "store", { value: store, enumerable: true });
149
- Object.defineProperty(globalThis, "load", { value: load, enumerable: true });
150
155
 
151
156
  // 原始值转字符串,其余 JSON 化
152
157
  function outputText(value) {