@trim21/personal-pi-extensions 0.0.398 → 0.0.399

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.0.398",
3
+ "version": "0.0.399",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { createWriteStream, existsSync, mkdirSync, readFileSync, type WriteStream } from "node:fs";
3
- import { mkdir, writeFile } from "node:fs/promises";
3
+ import { mkdir, unlink, writeFile } from "node:fs/promises";
4
4
  import { dirname, join } from "node:path";
5
5
 
6
6
  import {
@@ -141,7 +141,7 @@ function countNewlines(data: Buffer): number {
141
141
 
142
142
  /**
143
143
  * 合并 stdout/stderr 的流式输出累积器:输出在运行时就直接写入
144
- * agent-dir/tmp/{uuid}.txt(完整内容),内存只保留尾部缓冲。
144
+ * agent-dir/tmp/{sessionId}/{uuid}.txt(完整内容),内存只保留尾部缓冲。
145
145
  * 大输出不会撑爆内存;最终结果只返回截断后的文本。
146
146
  */
147
147
  class BashOutput {
@@ -151,13 +151,18 @@ class BashOutput {
151
151
  private tailBytes = 0;
152
152
  private totalBytes = 0;
153
153
  private totalLines = 0;
154
+ private readonly sessionId: string;
154
155
  filePath: string | undefined;
155
156
 
157
+ constructor(sessionId: string) {
158
+ this.sessionId = sessionId;
159
+ }
160
+
156
161
  append(data: Buffer): void {
157
162
  this.totalBytes += data.length;
158
163
  this.totalLines += countNewlines(data);
159
164
  if (!this.stream) {
160
- const dir = join(getAgentDir(), "tmp");
165
+ const dir = join(getAgentDir(), "tmp", this.sessionId);
161
166
  mkdirSync(dir, { recursive: true });
162
167
  this.filePath = join(dir, `${randomUUID()}.txt`);
163
168
  this.stream = createWriteStream(this.filePath, { flags: "w" });
@@ -361,7 +366,7 @@ export class BwrapRuntime {
361
366
  isWindows || needsApproval || !runtime.bwrapEnabled
362
367
  ? createLocalBashOperations()
363
368
  : createBwrapBashOperations(runtime, workspace);
364
- const output = new BashOutput();
369
+ const output = new BashOutput(request.ctx.sessionManager.getSessionId());
365
370
  const { onUpdate } = request;
366
371
 
367
372
  // 流式进度:节流推送尾部快照(对齐 pi 内置 bash 的实时输出体验)
@@ -406,6 +411,16 @@ export class BwrapRuntime {
406
411
  });
407
412
  await output.close();
408
413
  const truncation = truncateTail(output.tailText());
414
+ // 未截断:完整输出已直接返回给模型,临时文件没有用途,删掉避免
415
+ // agent-dir/tmp 堆积无主文件(删除失败只残留文件,不影响命令结果)
416
+ if (!truncation.truncated && output.filePath) {
417
+ try {
418
+ await unlink(output.filePath);
419
+ } catch {
420
+ // 删除失败(如沙箱只读):best-effort,命令结果不受影响
421
+ }
422
+ output.filePath = undefined;
423
+ }
409
424
  return {
410
425
  exitCode,
411
426
  output: truncation.content,