@henryqw/pi-subagent 27.1.1 → 27.1.2

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.
@@ -71,6 +71,8 @@ export interface EphemeralSubagentExecutor {
71
71
  * It reuses the active Pi process invocation; it does not resolve a standalone Pi installation.
72
72
  */
73
73
  export declare function createEphemeralSubagentExecutor(options: EphemeralSubagentExecutorOptions): EphemeralSubagentExecutor;
74
+ /** Longest prefix of `text` within `maxBytes` UTF-8 bytes, never splitting a code point. */
75
+ export declare function utf8Prefix(text: string, maxBytes: number): string;
74
76
  export declare function capEphemeralSubagentOutput(text: string): string;
75
77
  export declare function addUsage(left: Usage | undefined, right: Usage | undefined): Usage | undefined;
76
78
  export declare function formatDuration(milliseconds: number): string;
package/dist/ephemeral.js CHANGED
@@ -271,7 +271,8 @@ function oversizedToolStart(prefix) {
271
271
  return;
272
272
  }
273
273
  }
274
- function utf8Prefix(text, maxBytes) {
274
+ /** Longest prefix of `text` within `maxBytes` UTF-8 bytes, never splitting a code point. */
275
+ export function utf8Prefix(text, maxBytes) {
275
276
  return new StringDecoder().write(Buffer.from(text).subarray(0, maxBytes));
276
277
  }
277
278
  function cappedPrefix(text, totalBytes) {
package/dist/runner.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { EphemeralSubagentExecutor } from "./ephemeral.ts";
1
+ import { type EphemeralSubagentExecutor } from "./ephemeral.ts";
2
2
  import type { PruneOwnership } from "./prune.ts";
3
3
  import { IntegrationGit } from "./integration-git.ts";
4
4
  import { type AllocationKind, type CheckCommand, type ChangesetTaskRequest, type CleanupKind, type ExecuteRequest, type ExecutionPolicySnapshot, type HostAllocationIntent, type HostAllocationPlan, type ModelClass, type ReviewEvidence, type ResumeRequest, type RunState, type TaskAttempt, type TaskRequest, type TaskState, type WorktreeAllocationIntent, type WorktreeAllocationPlan, type WorkspaceIdentity } from "./schema.ts";
package/dist/runner.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { readFileSync, realpathSync } from "node:fs";
2
+ import { utf8Prefix } from "./ephemeral.js";
2
3
  import { createChildWorktree, finalizeChildWorktree, inspectWorktreeDirty } from "./worktree.js";
3
4
  import { runGit } from "./git-process.js";
4
5
  import { IntegrationGit } from "./integration-git.js";
@@ -162,11 +163,7 @@ class FollowupControl {
162
163
  function bounded(value, maxBytes = MAX_PERSISTED_RUNTIME_TEXT_BYTES) {
163
164
  if (Buffer.byteLength(value, "utf8") <= maxBytes)
164
165
  return value;
165
- const contentBytes = maxBytes - Buffer.byteLength(TRUNCATION_MARKER, "utf8");
166
- let end = Math.min(value.length, contentBytes);
167
- while (end > 0 && Buffer.byteLength(value.slice(0, end), "utf8") > contentBytes)
168
- end -= 1;
169
- return `${value.slice(0, end)}${TRUNCATION_MARKER}`;
166
+ return `${utf8Prefix(value, maxBytes - Buffer.byteLength(TRUNCATION_MARKER, "utf8"))}${TRUNCATION_MARKER}`;
170
167
  }
171
168
  function boundedRuntimeText(value, field) {
172
169
  if (typeof value !== "string")
@@ -2,7 +2,7 @@ import { basename } from "node:path";
2
2
  import type { JsonValue } from "@earendil-works/pi-ai";
3
3
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
4
4
  import { truncateToWidth } from "@earendil-works/pi-tui";
5
- import type { EphemeralSubagentExecutor } from "../dist/ephemeral.js";
5
+ import { utf8Prefix, type EphemeralSubagentExecutor } from "../dist/ephemeral.js";
6
6
  import type { EffectiveExecutionPolicy } from "./config.ts";
7
7
  import {
8
8
  createCanonicalGitRootResolver,
@@ -196,9 +196,7 @@ function boundedReport(lines: readonly string[], omitted: string): string {
196
196
 
197
197
  function boundedPublicText(value: string, maxBytes = PUBLIC_EVIDENCE_MAX_BYTES): string {
198
198
  if (Buffer.byteLength(value, "utf8") <= maxBytes) return value;
199
- let end = Math.min(value.length, maxBytes);
200
- while (end > 0 && Buffer.byteLength(value.slice(0, end), "utf8") > maxBytes) end -= 1;
201
- return `${value.slice(0, end)}\n[truncated]`;
199
+ return `${utf8Prefix(value, maxBytes)}\n[truncated]`;
202
200
  }
203
201
 
204
202
  function publicFailedCheck(evidence: CheckBatchEvidence | undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henryqw/pi-subagent",
3
- "version": "27.1.1",
3
+ "version": "27.1.2",
4
4
  "description": "Delegate bounded direct work or durable checked isolated task graphs to Pi roles.",
5
5
  "keywords": [
6
6
  "pi-package",