@hachej/boring-agent 0.1.70 → 0.1.72

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.
@@ -1,6 +1,6 @@
1
- import { u as AgentConfig, b as Agent } from '../harness-DN9KdrT7.js';
2
- export { a as AGENT_NOT_IMPLEMENTED_UNTIL_T1, c as AgentActor, d as AgentCoreHarness, e as AgentCoreHarnessFactory, f as AgentCorePromptInput, g as AgentCoreSessionAdapter, h as AgentCoreSessionSnapshot, i as AgentEvent, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadiness, o as AgentReadinessStatus, p as AgentResolveInputResponse, q as AgentRuntimeAdapter, r as AgentSendInput, s as AgentStartReceipt, t as AgentStreamOptions } from '../harness-DN9KdrT7.js';
3
- import '../piChatEvent-B6Lg9ft-.js';
1
+ import { u as AgentConfig, b as Agent } from '../harness-Dwxh6USt.js';
2
+ export { a as AGENT_NOT_IMPLEMENTED_UNTIL_T1, c as AgentActor, d as AgentCoreHarness, e as AgentCoreHarnessFactory, f as AgentCorePromptInput, g as AgentCoreSessionAdapter, h as AgentCoreSessionSnapshot, i as AgentEvent, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadiness, o as AgentReadinessStatus, p as AgentResolveInputResponse, q as AgentRuntimeAdapter, r as AgentSendInput, s as AgentStartReceipt, t as AgentStreamOptions } from '../harness-Dwxh6USt.js';
3
+ import '../session-DKMQNtNG.js';
4
4
  import 'zod';
5
5
  import '@mariozechner/pi-coding-agent';
6
6
 
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentProps, HTMLAttributes, FormEvent, ReactNode, ComponentType } from 'react';
3
3
  import { FileUIPart, ChatStatus, UIMessage } from 'ai';
4
- import { T as ToolUiMetadata, B as BoringChatPart, e as BoringChatMessage, k as PiChatStatus, Q as QueuedUserMessage, C as ChatError, P as PiChatEvent, n as SessionSummary } from '../piChatEvent-B6Lg9ft-.js';
5
- import { P as PromptPayload, c as PromptReceipt, F as FollowUpPayload, a as FollowUpReceipt, Q as QueueClearPayload, d as QueueClearReceipt, I as InterruptPayload, C as CommandReceipt, S as StopPayload, e as StopReceipt } from '../piChatCommand-C5ZM-AMG.js';
4
+ import { T as ToolUiMetadata, B as BoringChatPart, e as BoringChatMessage, k as PiChatStatus, Q as QueuedUserMessage, C as ChatError, P as PiChatEvent, n as SessionSummary } from '../session-DKMQNtNG.js';
5
+ import { P as PromptPayload, c as PromptReceipt, F as FollowUpPayload, a as FollowUpReceipt, Q as QueueClearPayload, d as QueueClearReceipt, I as InterruptPayload, C as CommandReceipt, S as StopPayload, e as StopReceipt } from '../piChatCommand-CSepU1NX.js';
6
6
  import { InputGroupAddon, InputGroupButton, InputGroupTextarea, Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from '@hachej/boring-ui-kit';
7
7
  import { Streamdown } from 'streamdown';
8
8
  import { StickToBottom } from 'use-stick-to-bottom';
@@ -1,4 +1,4 @@
1
- import { S as SessionCtx, P as PiChatEvent, a as SessionStore } from './piChatEvent-B6Lg9ft-.js';
1
+ import { S as SessionCtx, P as PiChatEvent, a as SessionStore } from './session-DKMQNtNG.js';
2
2
  import { AgentSessionEvent, PromptOptions } from '@mariozechner/pi-coding-agent';
3
3
 
4
4
  interface TelemetrySink {
@@ -1,5 +1,5 @@
1
1
  import { C as ChatSubmitPayload } from './chatSubmitPayload-DwOHyiqR.js';
2
- import { Q as QueuedUserMessage } from './piChatEvent-B6Lg9ft-.js';
2
+ import { Q as QueuedUserMessage } from './session-DKMQNtNG.js';
3
3
 
4
4
  type PromptPayload = ChatSubmitPayload;
5
5
  interface FollowUpPayload {
@@ -1,10 +1,10 @@
1
- import { j as WorkspaceRuntimeContext, S as Sandbox, f as SandboxHandleStore, e as SandboxHandleRecord, W as Workspace, F as FileSearch, g as Stat, E as Entry, b as ExecResult, k as WorkspaceChangeEvent, a as ExecOptions, P as PluginRestartWarning } from '../agentPluginEvents-ChUzG2Lh.js';
1
+ import { j as WorkspaceRuntimeContext, S as Sandbox, f as SandboxHandleStore, e as SandboxHandleRecord, W as Workspace, F as FileSearch, g as Stat, E as Entry, b as ExecResult, k as WorkspaceChangeEvent, a as ExecOptions, P as PluginRestartWarning } from '../agentPluginEvents-CqLTEdG2.js';
2
2
  import { Sandbox as Sandbox$1 } from '@vercel/sandbox';
3
- import { v as TelemetrySink, C as ToolReadinessRequirement, i as AgentEvent, b as Agent, c as AgentActor, A as AgentTool, D as AgentHarnessFactory } from '../harness-DN9KdrT7.js';
4
- export { u as AgentConfig, E as AgentHarnessFactoryInput } from '../harness-DN9KdrT7.js';
3
+ import { v as TelemetrySink, C as ToolReadinessRequirement, i as AgentEvent, b as Agent, c as AgentActor, A as AgentTool, D as AgentHarnessFactory } from '../harness-Dwxh6USt.js';
4
+ export { u as AgentConfig, E as AgentHarnessFactoryInput } from '../harness-Dwxh6USt.js';
5
5
  import { FastifyInstance, FastifyRequest, FastifyPluginAsync } from 'fastify';
6
6
  export { createAgent } from '../core/index.js';
7
- import { S as SessionCtx, f as ErrorCode } from '../piChatEvent-B6Lg9ft-.js';
7
+ import { S as SessionCtx, f as ErrorCode } from '../session-DKMQNtNG.js';
8
8
  import { IncomingMessage, ServerResponse } from 'node:http';
9
9
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
10
  import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
@@ -456,6 +456,7 @@ interface RuntimeFilesystemBindingOperations {
456
456
  path: string;
457
457
  }): Promise<{
458
458
  content: string;
459
+ mtimeMs?: number;
459
460
  metadata?: unknown;
460
461
  }>;
461
462
  list(descriptor: {
@@ -557,6 +557,13 @@ function createNodeWatcher(root) {
557
557
  return { ok: false, reason: "workspace_too_large", message };
558
558
  }
559
559
  startFsw();
560
+ if (fsw) {
561
+ await new Promise((resolve10) => {
562
+ fsw.once("ready", resolve10);
563
+ fsw.once("error", () => resolve10());
564
+ });
565
+ }
566
+ if (closed) return { ok: false, reason: "closed" };
560
567
  return { ok: true };
561
568
  })();
562
569
  return readiness;
@@ -2648,11 +2655,16 @@ function classifyError(err, reply, subject) {
2648
2655
  const statusCode = err?.statusCode;
2649
2656
  const stableCode = err?.code;
2650
2657
  if (typeof statusCode === "number" && statusCode >= 400 && statusCode < 600) {
2658
+ const details = err?.details;
2659
+ const conflictDetails = stableCode === ERROR_CODE_CONFLICT && details && typeof details === "object" && !Array.isArray(details) ? details : null;
2651
2660
  return reply.code(statusCode).send({
2652
2661
  error: {
2653
2662
  code: typeof stableCode === "string" ? stableCode : ERROR_CODE_INTERNAL,
2654
2663
  message,
2655
- details: err?.details
2664
+ ...conflictDetails ? {
2665
+ currentMtimeMs: conflictDetails.currentMtimeMs,
2666
+ expectedMtimeMs: conflictDetails.expectedMtimeMs
2667
+ } : { details }
2656
2668
  }
2657
2669
  });
2658
2670
  }
@@ -2881,7 +2893,7 @@ function fileRoutes(app, opts, done) {
2881
2893
  const binding = await resolveFilesystemBinding(request, filesystem);
2882
2894
  if (!binding) return sendNotFoundOrDenied(reply);
2883
2895
  const result = await binding.operations.read({ filesystem, path: path4 });
2884
- return { content: result.content, access: binding.access };
2896
+ return { content: result.content, mtimeMs: result.mtimeMs, access: binding.access };
2885
2897
  } catch {
2886
2898
  return sendNotFoundOrDenied(reply);
2887
2899
  }
@@ -7376,7 +7388,7 @@ function withFilesystemParameter(parameters, filesystemIds2, dynamicBindings = f
7376
7388
  ...properties,
7377
7389
  filesystem: {
7378
7390
  type: "string",
7379
- description: filesystemIds2.length > 0 ? "Logical filesystem to use. Omit or use user for workspace files; use an advertised named filesystem for bound readonly context." : "Logical filesystem to use. Omit or use user for workspace files.",
7391
+ description: filesystemIds2.length > 0 ? "Logical filesystem to use. Omit or use user for workspace files; use an advertised named filesystem for bound context." : "Logical filesystem to use. Omit or use user for workspace files.",
7380
7392
  ...dynamicBindings ? {} : { enum: ["user", ...filesystemIds2] }
7381
7393
  }
7382
7394
  }
@@ -7401,12 +7413,9 @@ function assertNotFilesystemPathSpoof(path4, filesystemIds2) {
7401
7413
  }
7402
7414
  }
7403
7415
  function filesystemBinding(bindings, filesystem) {
7404
- return bindings.find((binding) => binding.filesystem === filesystem);
7405
- }
7406
- function boundOperations(bindings, filesystem) {
7407
- const binding = filesystemBinding(bindings, filesystem);
7416
+ const binding = bindings.find((entry) => entry.filesystem === filesystem);
7408
7417
  if (!binding) throw new Error(`No filesystem binding is available for ${filesystem}`);
7409
- return binding.operations;
7418
+ return binding;
7410
7419
  }
7411
7420
  function formatBoundRead(content) {
7412
7421
  return { content: [{ type: "text", text: content }] };
@@ -7420,10 +7429,32 @@ function formatBoundFind(paths) {
7420
7429
  function formatBoundGrep(matches) {
7421
7430
  return { content: [{ type: "text", text: matches.map((match) => `${match.path}:${match.line}:${match.text}`).join("\n") }] };
7422
7431
  }
7432
+ function applyExactEdits(original, edits) {
7433
+ if (edits.length === 0) throw new Error("edit requires at least one edit");
7434
+ const ranges = edits.map((edit) => {
7435
+ if (!edit.oldText) throw new Error("edit oldText must not be empty");
7436
+ const start = original.indexOf(edit.oldText);
7437
+ const duplicate = start >= 0 ? original.indexOf(edit.oldText, start + 1) : -1;
7438
+ if (start < 0 || duplicate >= 0) {
7439
+ const occurrences = start < 0 ? 0 : 2;
7440
+ throw new Error(`edit requires oldText to match exactly once; found ${occurrences}`);
7441
+ }
7442
+ return { ...edit, start, end: start + edit.oldText.length };
7443
+ }).sort((left, right) => left.start - right.start);
7444
+ for (let index = 1; index < ranges.length; index += 1) {
7445
+ if (ranges[index].start < ranges[index - 1].end) throw new Error("edit ranges must not overlap");
7446
+ }
7447
+ let output = original;
7448
+ for (const range of ranges.reverse()) {
7449
+ output = `${output.slice(0, range.start)}${range.newText}${output.slice(range.end)}`;
7450
+ }
7451
+ return output;
7452
+ }
7423
7453
  async function executeBoundFilesystemTool(toolName, filesystem, params, bindings) {
7424
7454
  const path4 = boundFilesystemPath(params);
7425
- assertNotFilesystemPathSpoof(path4, bindings.map((binding) => binding.filesystem));
7426
- const operations = boundOperations(bindings, filesystem);
7455
+ assertNotFilesystemPathSpoof(path4, bindings.map((binding2) => binding2.filesystem));
7456
+ const binding = filesystemBinding(bindings, filesystem);
7457
+ const operations = binding.operations;
7427
7458
  if (toolName === "read") {
7428
7459
  const result = await operations.read({ filesystem, path: path4 });
7429
7460
  return { ...formatBoundRead(result.content), details: { metadata: result.metadata } };
@@ -7444,8 +7475,37 @@ async function executeBoundFilesystemTool(toolName, filesystem, params, bindings
7444
7475
  const result = await operations.grep({ filesystem, path: path4 }, pattern, { limit });
7445
7476
  return { ...formatBoundGrep(result.matches), details: { metadata: result.metadata } };
7446
7477
  }
7447
- if (toolName === "write" || toolName === "edit") {
7448
- operations.rejectMutation(toolName, { filesystem, path: path4 });
7478
+ if (toolName === "write") {
7479
+ if (binding.access !== "readwrite" || !operations.write) operations.rejectMutation(toolName, { filesystem, path: path4 });
7480
+ const write = operations.write;
7481
+ if (!write) throw new Error(`Tool ${toolName} does not support filesystem ${filesystem}`);
7482
+ const content = typeof params.content === "string" ? params.content : "";
7483
+ const parent = path4.includes("/") ? path4.slice(0, path4.lastIndexOf("/")) || "/" : null;
7484
+ if (parent && operations.mkdir) await operations.mkdir({ filesystem, path: parent, recursive: true });
7485
+ const result = await write({ filesystem, path: path4, content });
7486
+ return { content: [{ type: "text", text: `Wrote ${path4}` }], details: { metadata: result.metadata, mtimeMs: result.mtimeMs } };
7487
+ }
7488
+ if (toolName === "edit") {
7489
+ if (binding.access !== "readwrite" || !operations.write) operations.rejectMutation(toolName, { filesystem, path: path4 });
7490
+ const write = operations.write;
7491
+ if (!write) throw new Error(`Tool ${toolName} does not support filesystem ${filesystem}`);
7492
+ const edits = Array.isArray(params.edits) ? params.edits.map((edit) => {
7493
+ if (!edit || typeof edit !== "object") throw new Error("edit entries must be objects");
7494
+ const record = edit;
7495
+ if (typeof record.oldText !== "string" || typeof record.newText !== "string") {
7496
+ throw new Error("edit entries require string oldText and newText");
7497
+ }
7498
+ return { oldText: record.oldText, newText: record.newText };
7499
+ }) : [];
7500
+ const current = await operations.read({ filesystem, path: path4 });
7501
+ const content = applyExactEdits(current.content, edits);
7502
+ const result = await write({
7503
+ filesystem,
7504
+ path: path4,
7505
+ content,
7506
+ ...current.mtimeMs !== void 0 ? { expectedMtimeMs: current.mtimeMs } : {}
7507
+ });
7508
+ return { content: [{ type: "text", text: `Edited ${path4}` }], details: { metadata: result.metadata, mtimeMs: result.mtimeMs } };
7449
7509
  }
7450
7510
  throw new Error(`Tool ${toolName} does not support filesystem ${filesystem}`);
7451
7511
  }
@@ -7454,8 +7514,8 @@ function withBoundFilesystemPromptGuidance(promptSnippet, filesystemIds2, dynami
7454
7514
  const target = filesystemIds2.length > 0 ? ` (${filesystemIds2.join(", ")})` : "";
7455
7515
  const guidance = [
7456
7516
  "Named filesystem bindings: file tools default to the user workspace when filesystem is omitted.",
7457
- `Use the filesystem parameter explicitly for bound readonly context${target}, and start browsing at / unless told otherwise.`,
7458
- "Readonly filesystem bindings reject writes; do not use path prefixes like filesystem:/x to switch filesystem."
7517
+ `Use the filesystem parameter explicitly for named context${target}, and start browsing at / unless told otherwise.`,
7518
+ "A binding may be readonly or readwrite; do not use path prefixes like filesystem:/x to switch filesystem."
7459
7519
  ].join("\n");
7460
7520
  return [promptSnippet, guidance].filter(Boolean).join("\n");
7461
7521
  }
@@ -1,12 +1,12 @@
1
- import { A as AgentTool } from '../harness-DN9KdrT7.js';
2
- export { a as AGENT_NOT_IMPLEMENTED_UNTIL_T1, b as Agent, c as AgentActor, d as AgentCoreHarness, e as AgentCoreHarnessFactory, f as AgentCorePromptInput, g as AgentCoreSessionAdapter, h as AgentCoreSessionSnapshot, i as AgentEvent, j as AgentHarness, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadiness, o as AgentReadinessStatus, p as AgentResolveInputResponse, q as AgentRuntimeAdapter, r as AgentSendInput, s as AgentStartReceipt, t as AgentStreamOptions, u as CoreAgentConfig, J as JSONSchema, M as MessageAttachment, R as RunContext, S as SendMessageInput, T as TelemetryEvent, v as TelemetrySink, w as ToolExecContext, x as ToolResult, y as noopTelemetry, z as safeCapture, B as sessionStreamPath } from '../harness-DN9KdrT7.js';
3
- import { W as Workspace, S as Sandbox, F as FileSearch } from '../agentPluginEvents-ChUzG2Lh.js';
4
- export { C as CommandNotifyPayload, E as Entry, a as ExecOptions, b as ExecResult, I as IsolatedCodeInput, c as IsolatedCodeOutput, d as SandboxCapability, e as SandboxHandleRecord, f as SandboxHandleStore, g as Stat, h as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, i as WORKSPACE_COMMAND_NOTIFY_EVENT, j as WorkspaceRuntimeContext } from '../agentPluginEvents-ChUzG2Lh.js';
5
- import { B as BoringChatPart, T as ToolUiMetadata } from '../piChatEvent-B6Lg9ft-.js';
6
- export { A as ApiErrorPayload, b as ApiErrorPayloadSchema, c as ApiErrorResponse, d as ApiErrorResponseSchema, e as BoringChatMessage, C as ChatError, E as ERROR_CODES, f as ErrorCode, g as ErrorLogFields, h as ErrorLogFieldsSchema, P as PiChatEvent, i as PiChatHeartbeatFrame, j as PiChatSnapshot, k as PiChatStatus, l as PiChatStreamFrame, Q as QueuedUserMessage, S as SessionCtx, m as SessionDetail, a as SessionStore, n as SessionSummary, o as extractToolUiMetadata, p as isToolUiMetadata } from '../piChatEvent-B6Lg9ft-.js';
1
+ import { A as AgentTool } from '../harness-Dwxh6USt.js';
2
+ export { a as AGENT_NOT_IMPLEMENTED_UNTIL_T1, b as Agent, c as AgentActor, d as AgentCoreHarness, e as AgentCoreHarnessFactory, f as AgentCorePromptInput, g as AgentCoreSessionAdapter, h as AgentCoreSessionSnapshot, i as AgentEvent, j as AgentHarness, k as AgentMessageContent, l as AgentMessagePart, m as AgentNotImplementedError, n as AgentReadiness, o as AgentReadinessStatus, p as AgentResolveInputResponse, q as AgentRuntimeAdapter, r as AgentSendInput, s as AgentStartReceipt, t as AgentStreamOptions, u as CoreAgentConfig, J as JSONSchema, M as MessageAttachment, R as RunContext, S as SendMessageInput, T as TelemetryEvent, v as TelemetrySink, w as ToolExecContext, x as ToolResult, y as noopTelemetry, z as safeCapture, B as sessionStreamPath } from '../harness-Dwxh6USt.js';
3
+ import { W as Workspace, S as Sandbox, F as FileSearch } from '../agentPluginEvents-CqLTEdG2.js';
4
+ export { C as CommandNotifyPayload, E as Entry, a as ExecOptions, b as ExecResult, I as IsolatedCodeInput, c as IsolatedCodeOutput, d as SandboxCapability, e as SandboxHandleRecord, f as SandboxHandleStore, g as Stat, h as WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT, i as WORKSPACE_COMMAND_NOTIFY_EVENT, j as WorkspaceRuntimeContext } from '../agentPluginEvents-CqLTEdG2.js';
5
+ import { B as BoringChatPart, T as ToolUiMetadata } from '../session-DKMQNtNG.js';
6
+ export { A as ApiErrorPayload, b as ApiErrorPayloadSchema, c as ApiErrorResponse, d as ApiErrorResponseSchema, e as BoringChatMessage, C as ChatError, E as ERROR_CODES, f as ErrorCode, g as ErrorLogFields, h as ErrorLogFieldsSchema, P as PiChatEvent, i as PiChatHeartbeatFrame, j as PiChatSnapshot, k as PiChatStatus, l as PiChatStreamFrame, Q as QueuedUserMessage, S as SessionCtx, m as SessionDetail, a as SessionStore, n as SessionSummary, o as extractToolUiMetadata, p as isToolUiMetadata } from '../session-DKMQNtNG.js';
7
7
  import { z } from 'zod';
8
8
  export { a as ChatAttachmentPayload, b as ChatModelSelection, C as ChatSubmitPayload, T as ThinkingLevel } from '../chatSubmitPayload-DwOHyiqR.js';
9
- export { C as CommandReceipt, F as FollowUpPayload, a as FollowUpReceipt, I as InterruptPayload, b as InterruptReceipt, P as PromptPayload, c as PromptReceipt, Q as QueueClearPayload, d as QueueClearReceipt, S as StopPayload, e as StopReceipt } from '../piChatCommand-C5ZM-AMG.js';
9
+ export { C as CommandReceipt, F as FollowUpPayload, a as FollowUpReceipt, I as InterruptPayload, b as InterruptReceipt, P as PromptPayload, c as PromptReceipt, Q as QueueClearPayload, d as QueueClearReceipt, S as StopPayload, e as StopReceipt } from '../piChatCommand-CSepU1NX.js';
10
10
  import '@mariozechner/pi-coding-agent';
11
11
 
12
12
  declare const ToolUiMetadataSchema: z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-agent",
3
- "version": "0.1.70",
3
+ "version": "0.1.72",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Pane-embeddable coding agent. Ships direct/local/vercel-sandbox execution modes behind one interface.",
@@ -62,8 +62,8 @@
62
62
  "@streamdown/mermaid": "^1.0.2",
63
63
  "@tanstack/react-query": "^5.101.1",
64
64
  "@vercel/blob": "^2.5.0",
65
- "@vercel/sandbox": "2.2.1",
66
- "ai": "^7.0.2",
65
+ "@vercel/sandbox": "2.3.0",
66
+ "ai": "^7.0.9",
67
67
  "chokidar": "^5.0.0",
68
68
  "class-variance-authority": "^0.7.1",
69
69
  "clsx": "^2.1.1",
@@ -79,7 +79,7 @@
79
79
  "use-stick-to-bottom": "^1.1.6",
80
80
  "yaml": "^2.9.0",
81
81
  "zod": "^3.25.76",
82
- "@hachej/boring-ui-kit": "0.1.70"
82
+ "@hachej/boring-ui-kit": "0.1.72"
83
83
  },
84
84
  "devDependencies": {
85
85
  "@antithesishq/bombadil": "0.6.1",
@@ -96,7 +96,7 @@
96
96
  "tsup": "^8.4.0",
97
97
  "tsx": "^4.22.4",
98
98
  "typescript": "^6.0.3",
99
- "vite": "^6.3.3",
99
+ "vite": "^8.1.2",
100
100
  "vitest": "^4.1.9"
101
101
  },
102
102
  "peerDependencies": {
@@ -285,10 +285,6 @@ interface IsolatedCodeOutput {
285
285
  exitCode: number;
286
286
  }
287
287
 
288
- interface FileSearch {
289
- search(glob: string, limit?: number): Promise<string[]>;
290
- }
291
-
292
288
  interface SandboxHandleRecord {
293
289
  workspaceId: string;
294
290
  sandboxId: string;
@@ -303,6 +299,10 @@ interface SandboxHandleStore {
303
299
  list(): Promise<SandboxHandleRecord[]>;
304
300
  }
305
301
 
302
+ interface FileSearch {
303
+ search(glob: string, limit?: number): Promise<string[]>;
304
+ }
305
+
306
306
  /**
307
307
  * Browser CustomEvent name dispatched on `window` after the workspace's
308
308
  * agent-plugin hot reload subscriber commits a registry change (load,
@@ -1,31 +1,5 @@
1
1
  import { z } from 'zod';
2
2
 
3
- interface SessionStore {
4
- list(ctx: SessionCtx, options?: SessionListOptions): Promise<SessionSummary[]>;
5
- create(ctx: SessionCtx, init?: {
6
- title?: string;
7
- }): Promise<SessionSummary>;
8
- load(ctx: SessionCtx, sessionId: string): Promise<SessionDetail>;
9
- delete(ctx: SessionCtx, sessionId: string): Promise<void>;
10
- }
11
- interface SessionCtx {
12
- workspaceId?: string;
13
- userId?: string;
14
- }
15
- interface SessionListOptions {
16
- limit?: number;
17
- offset?: number;
18
- includeId?: string;
19
- }
20
- interface SessionSummary {
21
- id: string;
22
- title: string;
23
- createdAt: string;
24
- updatedAt: string;
25
- turnCount: number;
26
- }
27
- type SessionDetail = SessionSummary;
28
-
29
3
  interface ToolUiMetadata {
30
4
  /** Renderer key registered by the app shell, e.g. `pi-subagent`. */
31
5
  rendererId?: string;
@@ -294,4 +268,30 @@ interface PiChatHeartbeatFrame {
294
268
  }
295
269
  type PiChatStreamFrame = PiChatEvent | PiChatHeartbeatFrame;
296
270
 
271
+ interface SessionStore {
272
+ list(ctx: SessionCtx, options?: SessionListOptions): Promise<SessionSummary[]>;
273
+ create(ctx: SessionCtx, init?: {
274
+ title?: string;
275
+ }): Promise<SessionSummary>;
276
+ load(ctx: SessionCtx, sessionId: string): Promise<SessionDetail>;
277
+ delete(ctx: SessionCtx, sessionId: string): Promise<void>;
278
+ }
279
+ interface SessionCtx {
280
+ workspaceId?: string;
281
+ userId?: string;
282
+ }
283
+ interface SessionListOptions {
284
+ limit?: number;
285
+ offset?: number;
286
+ includeId?: string;
287
+ }
288
+ interface SessionSummary {
289
+ id: string;
290
+ title: string;
291
+ createdAt: string;
292
+ updatedAt: string;
293
+ turnCount: number;
294
+ }
295
+ type SessionDetail = SessionSummary;
296
+
297
297
  export { type ApiErrorPayload as A, type BoringChatPart as B, type ChatError as C, ERROR_CODES as E, type PiChatEvent as P, type QueuedUserMessage as Q, type SessionCtx as S, type ToolUiMetadata as T, type SessionStore as a, ApiErrorPayloadSchema as b, type ApiErrorResponse as c, ApiErrorResponseSchema as d, type BoringChatMessage as e, ErrorCode as f, type ErrorLogFields as g, ErrorLogFieldsSchema as h, type PiChatHeartbeatFrame as i, type PiChatSnapshot as j, type PiChatStatus as k, type PiChatStreamFrame as l, type SessionDetail as m, type SessionSummary as n, extractToolUiMetadata as o, isToolUiMetadata as p };