@hachej/boring-agent 0.1.16 → 0.1.18

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.
Files changed (39) hide show
  1. package/dist/{sandbox-handle-store-hK76cTjn.d.ts → agentPluginEvents-zyIvVjsA.d.ts} +28 -32
  2. package/dist/{chunk-F3CE5CNW.js → chunk-B5JECXMG.js} +5 -7
  3. package/dist/front/index.d.ts +23 -7
  4. package/dist/front/index.js +764 -421
  5. package/dist/front/styles.css +61 -0
  6. package/dist/{tool-ui-DSmWuqGe.d.ts → harness-DRrTn_5T.d.ts} +43 -24
  7. package/dist/server/index.d.ts +79 -10
  8. package/dist/server/index.js +243 -54
  9. package/dist/shared/index.d.ts +5 -3
  10. package/dist/shared/index.js +3 -1
  11. package/dist/tool-ui-DIFNGwYd.d.ts +20 -0
  12. package/docs/ACCESSIBILITY.md +55 -0
  13. package/docs/API.md +64 -0
  14. package/docs/CSP.md +40 -0
  15. package/docs/ERROR_CODES.md +54 -0
  16. package/docs/KNOWN_LIMITATIONS.md +100 -0
  17. package/docs/MIGRATION.md +50 -0
  18. package/docs/PERFORMANCE.md +68 -0
  19. package/docs/PLUGINS.md +108 -0
  20. package/docs/README.md +17 -0
  21. package/docs/RISKS-MULTI-TAB.md +46 -0
  22. package/docs/STYLING.md +71 -0
  23. package/docs/UI-SHADCN.md +56 -0
  24. package/docs/VERCEL_COSTS.md +103 -0
  25. package/docs/plans/AGENT_EVAL_FRAMEWORK.md +466 -0
  26. package/docs/plans/agent-package-spec.md +1777 -0
  27. package/docs/plans/harness-followup-capabilities.md +440 -0
  28. package/docs/plans/harness-tool-ui-capabilities.md +144 -0
  29. package/docs/plans/pi-followup-history-projection.md +229 -0
  30. package/docs/plans/pi-tools-migration.md +1061 -0
  31. package/docs/plans/reviews/pi-followup-history-codex-review.md +11 -0
  32. package/docs/plans/reviews/pi-followup-history-gpt-review.md +64 -0
  33. package/docs/plans/reviews/pi-followup-history-opus-review.md +43 -0
  34. package/docs/plans/reviews/pi-followup-history-xai-review.md +43 -0
  35. package/docs/plans/vercel-base-snapshot-template-plan.md +527 -0
  36. package/docs/plans/vercel-persistent-sandbox-adapter.md +553 -0
  37. package/docs/runtime.md +56 -0
  38. package/docs/tools.md +75 -0
  39. package/package.json +4 -3
@@ -211,6 +211,9 @@
211
211
  .ml-2 {
212
212
  margin-left: calc(var(--spacing) * 2);
213
213
  }
214
+ .ml-4 {
215
+ margin-left: calc(var(--spacing) * 4);
216
+ }
214
217
  .ml-auto {
215
218
  margin-left: auto;
216
219
  }
@@ -307,6 +310,9 @@
307
310
  .\!h-9 {
308
311
  height: calc(var(--spacing) * 9) !important;
309
312
  }
313
+ .h-2 {
314
+ height: calc(var(--spacing) * 2);
315
+ }
310
316
  .h-3 {
311
317
  height: calc(var(--spacing) * 3);
312
318
  }
@@ -373,6 +379,9 @@
373
379
  .w-1\/4 {
374
380
  width: calc(1 / 4 * 100%);
375
381
  }
382
+ .w-2 {
383
+ width: calc(var(--spacing) * 2);
384
+ }
376
385
  .w-3 {
377
386
  width: calc(var(--spacing) * 3);
378
387
  }
@@ -494,6 +503,9 @@
494
503
  .resize-none {
495
504
  resize: none;
496
505
  }
506
+ .list-disc {
507
+ list-style-type: disc;
508
+ }
497
509
  .grid-cols-1 {
498
510
  grid-template-columns: repeat(1, minmax(0, 1fr));
499
511
  }
@@ -720,6 +732,15 @@
720
732
  border-color: color-mix(in oklab, var(--input) 80%, transparent) !important;
721
733
  }
722
734
  }
735
+ .border-\[oklch\(0\.78_0\.13_148\)\]\/35 {
736
+ border-color: color-mix(in oklab, oklch(0.78 0.13 148) 35%, transparent);
737
+ }
738
+ .border-\[oklch\(0\.78_0\.13_148\)\]\/40 {
739
+ border-color: color-mix(in oklab, oklch(0.78 0.13 148) 40%, transparent);
740
+ }
741
+ .border-\[oklch\(0\.78_0\.15_85\)\]\/40 {
742
+ border-color: color-mix(in oklab, oklch(0.78 0.15 85) 40%, transparent);
743
+ }
723
744
  .border-\[var\(--boring-agent-code-border\,\#404040\)\] {
724
745
  border-color: var(--boring-agent-code-border,#404040);
725
746
  }
@@ -732,6 +753,12 @@
732
753
  .border-\[var\(--boring-agent-tool-border\,\#e5e7eb\)\] {
733
754
  border-color: var(--boring-agent-tool-border,#e5e7eb);
734
755
  }
756
+ .border-accent\/30 {
757
+ border-color: var(--accent);
758
+ @supports (color: color-mix(in lab, red, red)) {
759
+ border-color: color-mix(in oklab, var(--accent) 30%, transparent);
760
+ }
761
+ }
735
762
  .border-accent\/40 {
736
763
  border-color: var(--accent);
737
764
  @supports (color: color-mix(in lab, red, red)) {
@@ -804,6 +831,9 @@
804
831
  border-color: color-mix(in oklab, var(--primary) 30%, transparent);
805
832
  }
806
833
  }
834
+ .border-transparent {
835
+ border-color: transparent;
836
+ }
807
837
  .\!bg-destructive\/10 {
808
838
  background-color: var(--destructive) !important;
809
839
  @supports (color: color-mix(in lab, red, red)) {
@@ -843,6 +873,15 @@
843
873
  .bg-\[color\:var\(--surface-chat\)\] {
844
874
  background-color: var(--surface-chat);
845
875
  }
876
+ .bg-\[oklch\(0\.95_0\.05_148\/0\.3\)\] {
877
+ background-color: oklch(0.95 0.05 148/0.3);
878
+ }
879
+ .bg-\[oklch\(0\.95_0\.05_148\/0\.25\)\] {
880
+ background-color: oklch(0.95 0.05 148/0.25);
881
+ }
882
+ .bg-\[oklch\(0\.95_0\.06_85\/0\.4\)\] {
883
+ background-color: oklch(0.95 0.06 85/0.4);
884
+ }
846
885
  .bg-\[oklch\(from_var\(--accent\)_l_c_h\/0\.08\)\] {
847
886
  background-color: oklch(from var(--accent) l c h/0.08);
848
887
  }
@@ -1358,6 +1397,12 @@
1358
1397
  .text-\[color\:var\(--accent-foreground\)\] {
1359
1398
  color: var(--accent-foreground);
1360
1399
  }
1400
+ .text-\[oklch\(0\.45_0\.13_148\)\] {
1401
+ color: oklch(0.45 0.13 148);
1402
+ }
1403
+ .text-\[oklch\(0\.48_0\.15_60\)\] {
1404
+ color: oklch(0.48 0.15 60);
1405
+ }
1361
1406
  .text-\[var\(--boring-agent-code-fg\,\#d4d4d4\)\] {
1362
1407
  color: var(--boring-agent-code-fg,#d4d4d4);
1363
1408
  }
@@ -1430,6 +1475,12 @@
1430
1475
  .text-foreground {
1431
1476
  color: var(--foreground);
1432
1477
  }
1478
+ .text-foreground\/70 {
1479
+ color: var(--foreground);
1480
+ @supports (color: color-mix(in lab, red, red)) {
1481
+ color: color-mix(in oklab, var(--foreground) 70%, transparent);
1482
+ }
1483
+ }
1433
1484
  .text-foreground\/80 {
1434
1485
  color: var(--foreground);
1435
1486
  @supports (color: color-mix(in lab, red, red)) {
@@ -1935,6 +1986,16 @@
1935
1986
  }
1936
1987
  }
1937
1988
  }
1989
+ .hover\:bg-destructive\/10 {
1990
+ &:hover {
1991
+ @media (hover: hover) {
1992
+ background-color: var(--destructive);
1993
+ @supports (color: color-mix(in lab, red, red)) {
1994
+ background-color: color-mix(in oklab, var(--destructive) 10%, transparent);
1995
+ }
1996
+ }
1997
+ }
1998
+ }
1938
1999
  .hover\:bg-destructive\/15 {
1939
2000
  &:hover {
1940
2001
  @media (hover: hover) {
@@ -29,6 +29,46 @@ interface SessionDetail extends SessionSummary {
29
29
  messages: UIMessage[];
30
30
  }
31
31
 
32
+ type JSONSchema = Record<string, unknown>;
33
+ interface AgentTool {
34
+ name: string;
35
+ description: string;
36
+ /** Optional one-line prompt entry. Pi-built tools should preserve pi's snippet verbatim. */
37
+ promptSnippet?: string;
38
+ parameters: JSONSchema;
39
+ execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
40
+ }
41
+ interface ToolExecContext {
42
+ abortSignal: AbortSignal;
43
+ toolCallId: string;
44
+ onUpdate?: (partial: string) => void;
45
+ /** Agent chat/session id executing this tool, when known. */
46
+ sessionId?: string;
47
+ }
48
+ interface ToolResult {
49
+ content: Array<{
50
+ type: 'text';
51
+ text: string;
52
+ }>;
53
+ isError?: boolean;
54
+ details?: unknown;
55
+ }
56
+
57
+ interface AgentHarnessFactoryInput {
58
+ tools: AgentTool[];
59
+ cwd: string;
60
+ systemPromptAppend?: string;
61
+ sessionNamespace?: string;
62
+ sessionDir?: string;
63
+ /**
64
+ * Optional dynamic system-prompt source. Harness calls it whenever it
65
+ * builds or rebuilds a session prompt and appends the returned string.
66
+ * Workspace plugin layer wires this so live-reloaded plugins can contribute
67
+ * prompt context without a workspace-injected harness extension.
68
+ */
69
+ systemPromptDynamic?: () => string | undefined | Promise<string | undefined>;
70
+ }
71
+ type AgentHarnessFactory = (input: AgentHarnessFactoryInput) => AgentHarness | Promise<AgentHarness>;
32
72
  interface AgentHarness {
33
73
  readonly id: string;
34
74
  readonly placement: 'server' | 'browser';
@@ -58,6 +98,8 @@ interface AgentHarness {
58
98
  * client message, implementations should remove only that item if possible.
59
99
  */
60
100
  clearFollowUp?(sessionId: string, options?: FollowUpOptions): void;
101
+ /** Reload native agent resources/extensions for an existing session. */
102
+ reloadSession?: (sessionId: string) => Promise<boolean>;
61
103
  }
62
104
  interface FollowUpOptions {
63
105
  clientNonce?: string;
@@ -85,27 +127,4 @@ interface RunContext {
85
127
  userId?: string;
86
128
  }
87
129
 
88
- interface ToolUiMetadata {
89
- /** Renderer key registered by the app shell, e.g. `pi-subagent`. */
90
- rendererId?: string;
91
- /** Optional grouping label for future tool timelines/summaries. */
92
- displayGroup?: string;
93
- /** Optional icon hint. Frontends decide whether/how to honor it. */
94
- icon?: string;
95
- /** Renderer-specific structured data. */
96
- details?: unknown;
97
- }
98
- declare function isToolUiMetadata(value: unknown): value is ToolUiMetadata;
99
- /**
100
- * Extract structured UI metadata from a ToolResult-like output.
101
- *
102
- * Preferred shape:
103
- * output.details.ui = { rendererId, displayGroup, icon, details }
104
- *
105
- * Compatibility shape for early overlays:
106
- * output.details.uiKind = 'pi-subagent'
107
- * output.details = { uiKind, ...rendererDetails }
108
- */
109
- declare function extractToolUiMetadata(output: unknown): ToolUiMetadata | undefined;
110
-
111
- export { type AgentHarness as A, type RunContext as R, type SendMessageInput as S, type ToolUiMetadata as T, type SessionCtx as a, type SessionDetail as b, type SessionStore as c, type SessionSummary as d, extractToolUiMetadata as e, isToolUiMetadata as i };
130
+ export type { AgentTool as A, JSONSchema as J, RunContext as R, SendMessageInput as S, ToolExecContext as T, AgentHarness as a, SessionCtx as b, SessionDetail as c, SessionStore as d, SessionSummary as e, ToolResult as f, AgentHarnessFactory as g, AgentHarnessFactoryInput as h };
@@ -1,7 +1,10 @@
1
- import { S as Sandbox, f as SandboxHandleStore, e as SandboxHandleRecord, W as Workspace, F as FileSearch, A as AgentTool } from '../sandbox-handle-store-hK76cTjn.js';
1
+ import { S as Sandbox, f as SandboxHandleStore, e as SandboxHandleRecord, W as Workspace, F as FileSearch, P as PluginRestartWarning } from '../agentPluginEvents-zyIvVjsA.js';
2
2
  import { Sandbox as Sandbox$1 } from '@vercel/sandbox';
3
3
  import { FastifyInstance, FastifyRequest, FastifyPluginAsync } from 'fastify';
4
- import { PackageSource } from '@mariozechner/pi-coding-agent';
4
+ import { A as AgentTool, g as AgentHarnessFactory } from '../harness-DRrTn_5T.js';
5
+ export { h as AgentHarnessFactoryInput } from '../harness-DRrTn_5T.js';
6
+ import { PackageSource, ExtensionFactory, SettingsManager } from '@mariozechner/pi-coding-agent';
7
+ import 'ai';
5
8
 
6
9
  declare function createDirectSandbox(): Sandbox;
7
10
 
@@ -192,9 +195,17 @@ interface RuntimePythonSpec {
192
195
  /** Env vars exported by command shims, e.g. plugin builtin paths. */
193
196
  env?: Record<string, string | URL>;
194
197
  }
198
+ interface RuntimeNodePackageSpec {
199
+ id: string;
200
+ /** Package name materialized under workspaceRoot/node_modules, e.g. @boring/workspace. */
201
+ packageName: string;
202
+ /** Source package root. The provisioner copies the built package payload into node_modules. */
203
+ packageRoot: string | URL;
204
+ }
195
205
  interface RuntimeProvisioningContribution {
196
206
  templateDirs?: RuntimeTemplateContribution[];
197
207
  python?: RuntimePythonSpec[];
208
+ nodePackages?: RuntimeNodePackageSpec[];
198
209
  }
199
210
  interface ProvisionRuntimeWorkspaceOptions {
200
211
  workspaceRoot: string;
@@ -249,13 +260,30 @@ declare function hasBwrap(): boolean;
249
260
  declare function autoDetectMode(): RuntimeModeId;
250
261
  declare function resolveMode(mode?: RuntimeModeId): RuntimeModeAdapter;
251
262
 
263
+ interface ReloadHookDiagnostic {
264
+ source: string;
265
+ message: string;
266
+ pluginId?: string;
267
+ }
268
+ interface ReloadHookResult {
269
+ /**
270
+ * One per plugin that loaded successfully but whose server-side
271
+ * surfaces (routes, agentTools) still hold pre-reload code. The
272
+ * /api/v1/agent/reload response surfaces these so the chat UI can
273
+ * render a "restart needed" banner without subscribing to SSE.
274
+ */
275
+ restart_warnings?: ReadonlyArray<PluginRestartWarning>;
276
+ /** Non-fatal plugin reload diagnostics to surface to the caller/UI. */
277
+ diagnostics?: ReadonlyArray<ReloadHookDiagnostic>;
278
+ }
279
+
252
280
  type PiPackageSource = PackageSource;
253
281
  declare const PI_PACKAGE_RESOURCE_FILTERS: readonly ["extensions", "skills", "prompts", "themes"];
254
282
  declare function piPackageSourceKey(source: PiPackageSource): string;
255
283
  declare function compactPiPackages(sources: Array<PiPackageSource | undefined>): PiPackageSource[];
256
284
  declare function mergePiPackageSources(base?: PiPackageSource[], additional?: PiPackageSource[]): PiPackageSource[];
257
285
 
258
- interface PiResourceLoaderOptions {
286
+ interface PiHarnessOptions {
259
287
  noContextFiles?: boolean;
260
288
  noSkills?: boolean;
261
289
  additionalSkillPaths?: string[];
@@ -264,8 +292,31 @@ interface PiResourceLoaderOptions {
264
292
  * These are applied as in-memory SettingsManager overrides, so host/plugin
265
293
  * declarations do not mutate .pi/settings.json.
266
294
  */
267
- piPackages?: PiPackageSource[];
295
+ packages?: PiPackageSource[];
296
+ /**
297
+ * Additional native pi extension entrypoints. Pi loads these through jiti and
298
+ * re-imports them on ctx.reload(), which is required for hot-reloadable
299
+ * boring agent plugins.
300
+ */
301
+ extensionPaths?: string[];
302
+ /** In-process host extensions. Use only for trusted built-ins; hot plugin code should use paths. */
303
+ extensionFactories?: ExtensionFactory[];
304
+ /**
305
+ * Optional source of hot-reloadable Pi resources. Pi calls it on every
306
+ * reloadSession() (and once at session build) and merges the result with
307
+ * the static fields above. Lets the workspace plugin layer refresh
308
+ * package.json-discovered skills/packages/extensions without mutating
309
+ * arrays that the harness already captured.
310
+ */
311
+ getHotReloadableResources?: () => HotReloadablePiResources;
312
+ }
313
+ interface HotReloadablePiResources {
314
+ additionalSkillPaths?: string[];
315
+ packages?: PiPackageSource[];
316
+ extensionPaths?: string[];
268
317
  }
318
+ type PiExtensionFactory = ExtensionFactory;
319
+ declare function createResourceSettingsManager(cwd: string, agentDir: string, piPackages: PiPackageSource[]): SettingsManager;
269
320
 
270
321
  interface CreateAgentAppOptions {
271
322
  workspaceRoot?: string;
@@ -287,12 +338,27 @@ interface CreateAgentAppOptions {
287
338
  * via DefaultResourceLoader's `appendSystemPromptSource`.
288
339
  */
289
340
  systemPromptAppend?: string;
290
- /** Optional pi resource-loader isolation knobs. */
291
- resourceLoaderOptions?: PiResourceLoaderOptions;
341
+ /** Override the default pi-backed harness with a custom agent runtime. */
342
+ harnessFactory?: AgentHarnessFactory;
343
+ /** Optional pi adapter/runtime knobs used by the default harness. */
344
+ pi?: PiHarnessOptions;
292
345
  /** Optional stable namespace for file-backed session storage. */
293
346
  sessionNamespace?: string;
294
347
  /** Optional explicit file-backed session directory. Mostly for tests/hosts. */
295
348
  sessionDir?: string;
349
+ /**
350
+ * Called BEFORE the harness reloads its session. May return a
351
+ * `ReloadHookResult` (with `restart_warnings` and/or diagnostics) —
352
+ * surfaced verbatim on the /api/v1/agent/reload response. `void` /
353
+ * undefined return = no warnings (backwards compatible).
354
+ */
355
+ beforeReload?: () => void | ReloadHookResult | undefined | Promise<void | ReloadHookResult | undefined>;
356
+ /**
357
+ * Optional dynamic system-prompt source forwarded to the harness. The
358
+ * harness calls it whenever it builds or rebuilds a session prompt. Used by
359
+ * the workspace plugin layer.
360
+ */
361
+ systemPromptDynamic?: () => string | undefined | Promise<string | undefined>;
296
362
  }
297
363
  declare function createAgentApp(opts?: CreateAgentAppOptions): Promise<FastifyInstance>;
298
364
 
@@ -324,12 +390,15 @@ interface RegisterAgentRoutesOptions {
324
390
  workspaceFsCapability?: Workspace['fsCapability'];
325
391
  }) => AgentTool[] | Promise<AgentTool[]>;
326
392
  systemPromptAppend?: string;
327
- resourceLoaderOptions?: PiResourceLoaderOptions;
328
- getResourceLoaderOptions?: (ctx: {
393
+ /** Override the default pi-backed harness with a custom agent runtime. */
394
+ harnessFactory?: AgentHarnessFactory;
395
+ /** Optional pi adapter/runtime knobs used by the default harness. */
396
+ pi?: PiHarnessOptions;
397
+ getPi?: (ctx: {
329
398
  workspaceId: string;
330
399
  workspaceRoot: string;
331
400
  request?: FastifyRequest;
332
- }) => PiResourceLoaderOptions | undefined | Promise<PiResourceLoaderOptions | undefined>;
401
+ }) => PiHarnessOptions | undefined | Promise<PiHarnessOptions | undefined>;
333
402
  sessionNamespace?: string;
334
403
  getSessionNamespace?: (ctx: {
335
404
  workspaceId: string;
@@ -361,4 +430,4 @@ interface Logger {
361
430
  }
362
431
  declare function createLogger(prefix: string): Logger;
363
432
 
364
- export { type BuiltinRuntimeModeId, type CreateAgentAppOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiPackageSource, type PiResourceLoaderOptions, type ProvisionRuntimeWorkspaceOptions, type RegisterAgentRoutesOptions, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeProvisioningContribution, type RuntimePythonSpec, type RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createVercelDeploymentSnapshotProvider, createVercelSandboxWorkspace, fileRoutes, hasBwrap, mergePiPackageSources, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, registerAgentRoutes, resolveMode, resolveSandboxHandle };
433
+ export { AgentHarnessFactory, type BuiltinRuntimeModeId, type CreateAgentAppOptions, type DeploymentSnapshotProvider, type DeploymentSnapshotRecipe, type DeploymentSnapshotResult, type DeploymentSnapshotStatus, FileHandleStore, type LogFields, type Logger, type ModeContext, PI_PACKAGE_RESOURCE_FILTERS, type PiExtensionFactory, type PiHarnessOptions, type PiPackageSource, type ProvisionRuntimeWorkspaceOptions, type RegisterAgentRoutesOptions, type RuntimeBundle, type RuntimeModeAdapter, type RuntimeModeId, type RuntimeNodePackageSpec, type RuntimeProvisioningContribution, type RuntimePythonSpec, type RuntimeTemplateContribution, type RuntimeWorkspaceProvisioningResult, type SnapshotBakeOptions, type SnapshotBakeResult, UV_SETUP_COMMANDS, UV_SETUP_COMMANDS as VERCEL_UV_SETUP_COMMANDS, type VercelBakeClient, type VercelBakeSandbox, type VercelDeploymentSnapshotOptions, applyCspHeaders, autoDetectMode, bakeSnapshotIfNeeded, buildDeploymentSnapshotRecipe, buildPackageHash, buildSnapshotRecipeHash, compactPiPackages, createAgentApp, createBwrapSandbox, createDirectSandbox, createLogger, createNodeWorkspace, createResourceSettingsManager, createVercelDeploymentSnapshotProvider, createVercelSandboxWorkspace, fileRoutes, hasBwrap, mergePiPackageSources, piPackageSourceKey, prepareDeploymentSnapshot, prepareVercelDeploymentSnapshot, provisionRuntimeWorkspace, registerAgentRoutes, resolveMode, resolveSandboxHandle };