@hachej/boring-workspace 0.1.17 → 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 (37) hide show
  1. package/README.md +36 -34
  2. package/dist/{FileTree-Dvaud3jU.js → FileTree-DHVB9rpk.js} +15 -15
  3. package/dist/{MarkdownEditor-sLkqTXDj.js → MarkdownEditor-L1KDH0bM.js} +1 -1
  4. package/dist/{WorkspaceLoadingState-zLzh1tGc.js → WorkspaceLoadingState-DYDxUYnx.js} +114 -110
  5. package/dist/WorkspaceProvider-CDPaAO5u.js +5971 -0
  6. package/dist/app-front.d.ts +94 -107
  7. package/dist/app-front.js +243 -233
  8. package/dist/app-server.d.ts +130 -15
  9. package/dist/app-server.js +1569 -304
  10. package/dist/{bootstrapServer-BreQ9QBc.d.ts → createInMemoryBridge-BDxDzihm.d.ts} +11 -26
  11. package/dist/manifest-CyNNdfYz.d.ts +58 -0
  12. package/dist/plugin.d.ts +199 -0
  13. package/dist/plugin.js +300 -0
  14. package/dist/server.d.ts +239 -4
  15. package/dist/server.js +901 -78
  16. package/dist/shared.d.ts +4 -112
  17. package/dist/surface-COYagY2m.d.ts +111 -0
  18. package/dist/testing.d.ts +19 -1
  19. package/dist/testing.js +2 -2
  20. package/dist/{agent-tool-DEtfQPVB.d.ts → ui-bridge-Gfh1MMgl.d.ts} +30 -30
  21. package/dist/workspace.css +36 -0
  22. package/dist/workspace.d.ts +165 -120
  23. package/dist/workspace.js +330 -377
  24. package/docs/INTERFACES.md +9 -9
  25. package/docs/PLUGIN_STRUCTURE.md +39 -145
  26. package/docs/PLUGIN_SYSTEM.md +355 -0
  27. package/docs/README.md +6 -1
  28. package/docs/plans/README.md +1 -0
  29. package/docs/plans/archive/HOT_RELOADABLE_AGENT_PLUGINS_PLAN.md +218 -0
  30. package/docs/plans/archive/RELOAD_PLUGGABILITY_PLAN.md +174 -0
  31. package/docs/plans/archive/UNIFIED_PLUGIN_SYSTEM_PLAN.md +769 -0
  32. package/package.json +11 -5
  33. package/dist/CommandPalette-CJHuTJlD.js +0 -5716
  34. package/docs/bridge.md +0 -135
  35. package/docs/panels.md +0 -102
  36. package/docs/plugins.md +0 -158
  37. /package/docs/plans/{MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md → archive/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md} +0 -0
package/dist/server.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- export { C as ComposeServerPluginsOptions, S as ServerBootstrapOptions, f as ServerBootstrapResult, g as ServerPluginError, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, W as WorkspaceServerPlugin, h as bootstrapServer, d as composeServerPlugins, c as createInMemoryBridge, e as defineServerPlugin, v as validateServerPlugin } from './bootstrapServer-BreQ9QBc.js';
1
+ export { S as ServerBootstrapOptions, d as ServerBootstrapResult, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, W as WorkspaceServerPlugin, e as bootstrapServer, c as createInMemoryBridge, f as defineServerPlugin, v as validateServerPlugin } from './createInMemoryBridge-BDxDzihm.js';
2
2
  import { FastifyRequest, FastifyInstance } from 'fastify';
3
- import { U as UiBridge, A as AgentTool } from './agent-tool-DEtfQPVB.js';
4
- export { C as CommandResult, a as UiCommand, b as UiState } from './agent-tool-DEtfQPVB.js';
3
+ import { U as UiBridge, A as AgentTool } from './ui-bridge-Gfh1MMgl.js';
4
+ export { C as CommandResult, b as UiCommand, c as UiState } from './ui-bridge-Gfh1MMgl.js';
5
+ import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-CyNNdfYz.js';
5
6
  export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
6
7
 
7
8
  interface UiRoutesOptions {
@@ -59,4 +60,238 @@ declare function createExecUiTool(uiBridge: UiBridge, opts?: ExecUiToolOptions):
59
60
  */
60
61
  declare function createWorkspaceUiTools(uiBridge: UiBridge, opts?: ExecUiToolOptions): AgentTool[];
61
62
 
62
- export { UiBridge, type UiRoutesOptions, createExecUiTool, createGetUiStateTool, createWorkspaceUiTools, uiRoutes };
63
+ /**
64
+ * boring-ui system prompt — workflow steps + a Pi-style docs pointer
65
+ * block (per DECISIONS.md #17). The block lists absolute paths into the
66
+ * installed `@hachej/boring-pi` package so the agent's `read` tool can
67
+ * fetch the SKILL.md + reference docs on demand, without inlining their
68
+ * ~12-30 KB of markdown into every system prompt.
69
+ *
70
+ * `@hachej/boring-pi` is a runtime dep of `@hachej/boring-workspace`;
71
+ * a missing install means the host shipped without it (degraded mode),
72
+ * in which case we still emit the workflow + skill-by-name reference
73
+ * for `<available_skills>` consumers but skip the absolute paths.
74
+ */
75
+ interface BuildBoringSystemPromptOptions {
76
+ /**
77
+ * CLI invocation that writes the canonical files (e.g.
78
+ * `boring-ui scaffold-plugin`). When unset, step 1 falls back to
79
+ * "read the skill" — the agent then has no canonical anchor and
80
+ * reliability suffers on smaller models, so always provide this in
81
+ * production.
82
+ */
83
+ scaffoldCommand?: string;
84
+ /** CLI invocation that validates `.pi/extensions/*` manifests. Omit when unavailable. */
85
+ verifyCommand?: string;
86
+ /**
87
+ * Test escape hatch. Overrides the runtime `require.resolve` of
88
+ * `@hachej/boring-pi/package.json`:
89
+ * - `undefined` (default): resolve via require.resolve
90
+ * - `string`: use as the boring-pi root verbatim
91
+ * - `null`: force the degraded path (no resolution attempt)
92
+ * Production should leave unset.
93
+ */
94
+ boringPiRootOverride?: string | null;
95
+ }
96
+ declare function buildBoringSystemPrompt(opts: BuildBoringSystemPromptOptions): string;
97
+
98
+ interface BoringServerPluginManifest {
99
+ id: string;
100
+ rootDir: string;
101
+ version: string;
102
+ boring: BoringPackageBoringField;
103
+ pi?: BoringPackagePiField;
104
+ frontPath?: string;
105
+ frontUrl?: string;
106
+ serverPath?: string;
107
+ extensionPaths?: string[];
108
+ skillPaths?: string[];
109
+ }
110
+ /**
111
+ * Surfaces whose changes the hot-reload pipeline can't re-load mid-
112
+ * session — set when a plugin's load DID succeed but a sub-surface
113
+ * (the agent-tools registry, Fastify routes) carries stale code from
114
+ * the previous revision. The /reload caller (chat UI, verify-plugin,
115
+ * etc.) should surface a "restart needed for X" warning.
116
+ *
117
+ * - `'routes'`: a `WorkspaceServerPlugin.routes` function changed. The
118
+ * workspace's Fastify instance can't unregister + re-register routes
119
+ * mid-flight; the previous routes stay live until next boot.
120
+ * - `'agentTools'`: a `WorkspaceServerPlugin.agentTools` array changed.
121
+ * The current Pi session still has the old tool list; new sessions
122
+ * get the new list.
123
+ * - Multiple surfaces: order is deterministic (`routes` before
124
+ * `agentTools`) so subscribers can format consistently.
125
+ */
126
+ type PluginRestartSurface = "routes" | "agentTools";
127
+ type BoringPluginEvent = {
128
+ type: "boring.plugin.load";
129
+ id: string;
130
+ boring: BoringPackageBoringField;
131
+ version: string;
132
+ revision: number;
133
+ frontUrl?: string;
134
+ /**
135
+ * Non-empty when the plugin loaded but one or more server-side
136
+ * surfaces still hold pre-load code. UI consumers should render
137
+ * a "restart needed: <surfaces>" hint. Empty/omitted = fully
138
+ * live.
139
+ */
140
+ requiresRestart?: PluginRestartSurface[];
141
+ } | {
142
+ type: "boring.plugin.unload";
143
+ id: string;
144
+ revision: number;
145
+ } | {
146
+ type: "boring.plugin.error";
147
+ id: string;
148
+ revision: number;
149
+ message: string;
150
+ };
151
+ interface BoringPluginListEntry {
152
+ id: string;
153
+ boring: BoringPackageBoringField;
154
+ pi?: BoringPackagePiField;
155
+ version: string;
156
+ revision: number;
157
+ frontUrl?: string;
158
+ }
159
+
160
+ interface BoringPluginPreflightIssue {
161
+ pluginDir: string;
162
+ pluginId?: string;
163
+ code: "MISSING_PACKAGE_JSON" | "INVALID_PACKAGE_JSON" | "INVALID_PLUGIN_METADATA";
164
+ message: string;
165
+ }
166
+ interface BoringPluginPreflightResult {
167
+ ok: boolean;
168
+ errors: BoringPluginPreflightIssue[];
169
+ }
170
+ interface BoringPluginScanResult {
171
+ preflight: BoringPluginPreflightResult;
172
+ plugins: BoringServerPluginManifest[];
173
+ }
174
+ declare function scanBoringPlugins(pluginDirs: string[]): BoringPluginScanResult;
175
+ declare function preflightBoringPlugins(pluginDirs: string[]): BoringPluginPreflightResult;
176
+ declare function readBoringPlugins(pluginDirs: string[]): BoringServerPluginManifest[];
177
+
178
+ interface BoringPluginAssetManagerOptions {
179
+ pluginDirs: string[];
180
+ /**
181
+ * Root directory for per-plugin `.error` sidecar files written by the
182
+ * asset manager and read by verify-plugin. Defaults to `<cwd>/.pi/extensions`.
183
+ * Multi-tenant / non-standard layouts MUST provide an explicit path —
184
+ * the default assumes workspace root equals `process.cwd()`.
185
+ */
186
+ errorRoot?: string;
187
+ }
188
+ interface LoadBoringAssetsError {
189
+ id: string;
190
+ revision: number;
191
+ message: string;
192
+ }
193
+ interface LoadBoringAssetsResult {
194
+ loaded: BoringPluginListEntry[];
195
+ events: BoringPluginEvent[];
196
+ errors: LoadBoringAssetsError[];
197
+ }
198
+ type Listener = (event: BoringPluginEvent) => void;
199
+ declare class BoringPluginAssetManager {
200
+ private readonly pluginDirs;
201
+ private readonly errorRoot;
202
+ private readonly loaded;
203
+ private readonly revisions;
204
+ private readonly listeners;
205
+ private loading;
206
+ private reloadQueued;
207
+ constructor(options: BoringPluginAssetManagerOptions);
208
+ preflight(): BoringPluginPreflightResult;
209
+ list(): BoringPluginListEntry[];
210
+ getError(pluginId: string): string | null;
211
+ subscribe(listener: Listener): () => void;
212
+ load(): Promise<LoadBoringAssetsResult>;
213
+ private drainLoads;
214
+ private doLoadOnce;
215
+ private collectPreflightErrors;
216
+ private bumpRevision;
217
+ private emit;
218
+ private errorPath;
219
+ private writeError;
220
+ private clearError;
221
+ }
222
+
223
+ interface PluginReloadRebuild {
224
+ ok: boolean;
225
+ diagnostics: {
226
+ source: string;
227
+ message: string;
228
+ pluginId?: string;
229
+ }[];
230
+ }
231
+ /**
232
+ * One per plugin whose load event carried a non-empty
233
+ * `requiresRestart` field. Surfaced alongside the /reload response so
234
+ * the agent (and chat UI) can warn the user without subscribing to
235
+ * the SSE event stream.
236
+ */
237
+ interface PluginRestartWarning {
238
+ id: string;
239
+ surfaces: PluginRestartSurface[];
240
+ message: string;
241
+ }
242
+ /**
243
+ * Walk a load result's events for boring.plugin.load events that
244
+ * carried `requiresRestart`. Each becomes a human-readable warning
245
+ * with a one-line message — small, surface-aware, formatted for both
246
+ * humans and agents.
247
+ */
248
+ declare function collectRestartWarnings(events: BoringPluginEvent[]): PluginRestartWarning[];
249
+ interface BoringPluginRoutesOptions {
250
+ manager: BoringPluginAssetManager;
251
+ /**
252
+ * Server-side plugin rebuild closure (jiti re-import of dir-source
253
+ * entries). Called AFTER the asset manager scan. Per-plugin failures
254
+ * surface as diagnostics; combined with asset-manager errors into the
255
+ * 422 response body so the agent's /reload UI can show them. Optional —
256
+ * tests that exercise the route in isolation can omit it.
257
+ */
258
+ rebuildPlugins?: () => Promise<PluginReloadRebuild>;
259
+ /** Register the developer reload endpoint. Static discovery/listing remains available when false. */
260
+ enableReloadRoute?: boolean;
261
+ }
262
+ declare function boringPluginRoutes(app: FastifyInstance, opts: BoringPluginRoutesOptions): Promise<void>;
263
+
264
+ /**
265
+ * Concatenates the `pi.systemPrompt` from every currently loaded boring
266
+ * plugin into a single block, prefixed by a stable header. Returns
267
+ * `undefined` when no plugin contributes a prompt so the harness can skip
268
+ * the append entirely.
269
+ *
270
+ * The harness calls this on every prompt rebuild — Pi calls it from
271
+ * `before_agent_start`, which `piSession.reload()` re-fires. Live plugin
272
+ * additions/removals therefore land on the next agent turn without any
273
+ * workspace-injected harness extension.
274
+ */
275
+ declare function aggregatePluginPrompts(manager: BoringPluginAssetManager): string | undefined;
276
+
277
+ interface PluginSignatureCachePayload {
278
+ version: 1;
279
+ /**
280
+ * `fileSignature(serverPath)` at load time, or null when the plugin
281
+ * has no server entry.
282
+ */
283
+ serverSignature: string | null;
284
+ /** Unix ms when the manager wrote this cache. */
285
+ loadedAt: number;
286
+ }
287
+ /**
288
+ * mtimeMs+size — cheap, mirrors what the asset manager uses to decide
289
+ * whether to fire `requiresRestart` on /reload. Bytes are deliberately
290
+ * NOT hashed (perf bug on 50MB+ bundles, and we only need change
291
+ * detection, not content equality).
292
+ */
293
+ declare function pluginFileSignature(path: string | undefined): string;
294
+ declare function writePluginSignatureCache(pluginRootDir: string, payload: Omit<PluginSignatureCachePayload, "version" | "loadedAt"> & Partial<Pick<PluginSignatureCachePayload, "loadedAt">>): void;
295
+ declare function readPluginSignatureCache(pluginRootDir: string): PluginSignatureCachePayload | null;
296
+
297
+ export { BoringPluginAssetManager, type BoringPluginEvent, type BoringPluginListEntry, type BoringPluginScanResult, type BoringServerPluginManifest, type PluginReloadRebuild, type PluginRestartWarning, UiBridge, type UiRoutesOptions, aggregatePluginPrompts, boringPluginRoutes, buildBoringSystemPrompt, collectRestartWarnings, createExecUiTool, createGetUiStateTool, createWorkspaceUiTools, pluginFileSignature, preflightBoringPlugins, readBoringPlugins, readPluginSignatureCache, scanBoringPlugins, uiRoutes, writePluginSignatureCache };