@hachej/boring-workspace 0.1.23 → 0.1.26

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.
@@ -0,0 +1,161 @@
1
+ import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-C2vVgH_e.js';
2
+ import { PiPackageSource, PluginSkillSource, ProvisionWorkspaceRuntimeOptions } from '@hachej/boring-agent/server';
3
+ import { FastifyPluginAsync } from 'fastify';
4
+ import { A as AgentTool, U as UiBridge } from './ui-bridge-Bdgl2hR8.js';
5
+
6
+ type BoringPluginNativeFrontTargetTrust$1 = "local-trusted-native";
7
+ /**
8
+ * Host-owned runtime import target for a plugin front entry.
9
+ *
10
+ * Only the trusted native/browser-module case exists today. Future
11
+ * target kinds (iframe/artifact/...) can extend the union without
12
+ * rewriting list/event payload shapes.
13
+ */
14
+ interface BoringPluginNativeFrontTarget$1 {
15
+ kind: "native";
16
+ entryUrl: string;
17
+ revision: number;
18
+ trust: BoringPluginNativeFrontTargetTrust$1;
19
+ }
20
+ type BoringPluginFrontTarget$1 = BoringPluginNativeFrontTarget$1;
21
+ type BoringPluginEvent$1 = {
22
+ type: "boring.plugin.load";
23
+ id: string;
24
+ boring: BoringPackageBoringField;
25
+ version: string;
26
+ revision: number;
27
+ frontUrl?: string;
28
+ frontTarget?: BoringPluginFrontTarget$1;
29
+ } | {
30
+ type: "boring.plugin.unload";
31
+ id: string;
32
+ revision: number;
33
+ } | {
34
+ type: "boring.plugin.error";
35
+ id: string;
36
+ revision: number;
37
+ message: string;
38
+ };
39
+ interface BoringPluginListEntry$1 {
40
+ id: string;
41
+ boring: BoringPackageBoringField;
42
+ pi?: BoringPackagePiField;
43
+ version: string;
44
+ revision: number;
45
+ frontUrl?: string;
46
+ frontTarget?: BoringPluginFrontTarget$1;
47
+ }
48
+
49
+ interface BoringServerPluginManifest {
50
+ id: string;
51
+ rootDir: string;
52
+ version: string;
53
+ boring: BoringPackageBoringField;
54
+ pi?: BoringPackagePiField;
55
+ frontPath?: string;
56
+ /** Legacy Vite-dev browser import fallback (`/@fs/...`). */
57
+ frontUrl?: string;
58
+ serverPath?: string;
59
+ extensionPaths?: string[];
60
+ skillPaths?: string[];
61
+ }
62
+ type BoringPluginNativeFrontTargetTrust = BoringPluginNativeFrontTargetTrust$1;
63
+ type BoringPluginNativeFrontTarget = BoringPluginNativeFrontTarget$1;
64
+ type BoringPluginFrontTarget = BoringPluginFrontTarget$1;
65
+ type BoringPluginListEntry = BoringPluginListEntry$1;
66
+ interface BoringPluginFrontTargetResolverContext {
67
+ revision: number;
68
+ /** Plugin-root-relative front entry path normalized for URL-like consumers. */
69
+ frontEntrySubpath: string;
70
+ }
71
+ type BoringPluginFrontTargetResolver = (plugin: BoringServerPluginManifest, context: BoringPluginFrontTargetResolverContext) => BoringPluginFrontTarget | undefined;
72
+ /**
73
+ * Surfaces whose changes the hot-reload pipeline can't re-load mid-
74
+ * session — set when a plugin's load DID succeed but a sub-surface
75
+ * (the agent-tools registry, Fastify routes) carries stale code from
76
+ * the previous revision. The /reload caller (chat UI, verify-plugin,
77
+ * etc.) should surface a "restart needed for X" warning.
78
+ *
79
+ * - `'routes'`: a `WorkspaceServerPlugin.routes` function changed. The
80
+ * workspace's Fastify instance can't unregister + re-register routes
81
+ * mid-flight; the previous routes stay live until next boot.
82
+ * - `'agentTools'`: a `WorkspaceServerPlugin.agentTools` array changed.
83
+ * The current Pi session still has the old tool list; new sessions
84
+ * get the new list.
85
+ * - Multiple surfaces: order is deterministic (`routes` before
86
+ * `agentTools`) so subscribers can format consistently.
87
+ */
88
+ type PluginRestartSurface = "routes" | "agentTools";
89
+ type BoringPluginEvent = (Extract<BoringPluginEvent$1, {
90
+ type: "boring.plugin.load";
91
+ }> & {
92
+ /**
93
+ * Non-empty when the plugin loaded but one or more server-side
94
+ * surfaces still hold pre-load code. UI consumers should render
95
+ * a "restart needed: <surfaces>" hint. Empty/omitted = fully
96
+ * live.
97
+ */
98
+ requiresRestart?: PluginRestartSurface[];
99
+ }) | Extract<BoringPluginEvent$1, {
100
+ type: "boring.plugin.unload";
101
+ }> | Extract<BoringPluginEvent$1, {
102
+ type: "boring.plugin.error";
103
+ }>;
104
+
105
+ type WorkspaceRuntimeProvisioning = NonNullable<ProvisionWorkspaceRuntimeOptions["plugins"][number]["provisioning"]>;
106
+ interface WorkspaceServerPlugin {
107
+ id: string;
108
+ label?: string;
109
+ /**
110
+ * Native Pi package sources required by this workspace integration.
111
+ * Workspace declares them; @hachej/boring-agent applies them through Pi's native
112
+ * resource loader without asking Pi packages to export Boring adapters.
113
+ */
114
+ piPackages?: PiPackageSource[];
115
+ /**
116
+ * Native pi extension entrypoints contributed by this plugin.
117
+ * Passed to DefaultResourceLoader.additionalExtensionPaths so pi owns jiti
118
+ * loading and ctx.reload() re-imports fresh source.
119
+ */
120
+ extensionPaths?: string[];
121
+ systemPrompt?: string;
122
+ skills?: PluginSkillSource[];
123
+ agentTools?: AgentTool[];
124
+ provisioning?: WorkspaceRuntimeProvisioning;
125
+ routes?: FastifyPluginAsync;
126
+ /** UI state keys owned by this plugin that browser state PUTs must not overwrite. */
127
+ preservedUiStateKeys?: string[];
128
+ }
129
+ declare function validateServerPlugin(plugin: WorkspaceServerPlugin): void;
130
+ declare function defineServerPlugin<T extends WorkspaceServerPlugin>(plugin: T): T;
131
+
132
+ interface ServerBootstrapOptions {
133
+ plugins?: WorkspaceServerPlugin[];
134
+ defaults?: WorkspaceServerPlugin[];
135
+ excludeDefaults?: string[];
136
+ }
137
+ type WorkspaceRuntimeProvisioningInput = ProvisionWorkspaceRuntimeOptions["plugins"][number];
138
+ type WorkspaceProvisioningContribution = {
139
+ id: string;
140
+ provisioning: NonNullable<WorkspaceRuntimeProvisioningInput["provisioning"]>;
141
+ };
142
+ type WorkspaceRouteContribution = {
143
+ id: string;
144
+ routes: FastifyPluginAsync;
145
+ };
146
+ interface ServerBootstrapResult {
147
+ registered: string[];
148
+ systemPromptAppend: string;
149
+ piPackages: PiPackageSource[];
150
+ extensionPaths: string[];
151
+ agentTools: AgentTool[];
152
+ runtimePlugins: WorkspaceRuntimeProvisioningInput[];
153
+ provisioningContributions: WorkspaceProvisioningContribution[];
154
+ routeContributions: WorkspaceRouteContribution[];
155
+ preservedUiStateKeys: string[];
156
+ }
157
+ declare function bootstrapServer(options: ServerBootstrapOptions): ServerBootstrapResult;
158
+
159
+ declare function createInMemoryBridge(): UiBridge;
160
+
161
+ export { type BoringPluginFrontTargetResolver as B, type PluginRestartSurface as P, type ServerBootstrapOptions as S, type WorkspaceServerPlugin as W, type WorkspaceProvisioningContribution as a, type WorkspaceRouteContribution as b, createInMemoryBridge as c, type WorkspaceRuntimeProvisioningInput as d, type BoringServerPluginManifest as e, type BoringPluginListEntry as f, type BoringPluginFrontTarget as g, type BoringPluginEvent as h, type BoringPluginFrontTargetResolverContext as i, type BoringPluginNativeFrontTarget as j, type BoringPluginNativeFrontTargetTrust as k, type ServerBootstrapResult as l, bootstrapServer as m, defineServerPlugin as n, validateServerPlugin as v };
package/dist/events.d.ts CHANGED
@@ -58,6 +58,9 @@ type WorkspacePanelMatch = {
58
58
  } | {
59
59
  param: string;
60
60
  value: unknown;
61
+ } | {
62
+ paramPrefix: string;
63
+ value: string;
61
64
  };
62
65
  /**
63
66
  * Discriminated origin metadata. Encoded as a union (rather than a
@@ -8,6 +8,8 @@
8
8
  * - `boring`: workspace/UI package discovery (front/server entrypoints and labels)
9
9
  */
10
10
  interface BoringPackageBoringField {
11
+ /** Optional stable plugin id. Defaults to package.json#name normalized for package discovery. */
12
+ id?: string;
11
13
  /** Browser entry that default-exports a BoringFrontFactory. */
12
14
  front?: string;
13
15
  /** Workspace/UI support server entry. Set false to disable convention lookup. */
package/dist/plugin.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ComponentType, ReactNode } from 'react';
2
- import { P as PaneProps, a as PanelConfig, S as SurfaceOpenRequest, c as SurfacePanelResolution } from './surface-COYagY2m.js';
3
- export { W as WORKSPACE_OPEN_PATH_SURFACE_KIND } from './surface-COYagY2m.js';
4
- export { B as BoringPackageBoringField, a as BoringPackagePiField, b as BoringPackagePiSource, c as BoringPackagePiSourceObject, d as BoringPluginManifestErrorCode, e as BoringPluginManifestIssue, f as BoringPluginManifestValidationResult, g as BoringPluginPackageJson, i as isSafePluginRelativePath, h as isValidBoringPluginId, v as validateBoringPluginManifest } from './manifest-CyNNdfYz.js';
2
+ import { P as PaneProps, a as PanelConfig, S as SurfaceOpenRequest, c as SurfacePanelResolution } from './surface-CEEkd81D.js';
3
+ export { W as WORKSPACE_OPEN_PATH_SURFACE_KIND } from './surface-CEEkd81D.js';
4
+ export { B as BoringPackageBoringField, a as BoringPackagePiField, b as BoringPackagePiSource, c as BoringPackagePiSourceObject, d as BoringPluginManifestErrorCode, e as BoringPluginManifestIssue, f as BoringPluginManifestValidationResult, g as BoringPluginPackageJson, i as isSafePluginRelativePath, h as isValidBoringPluginId, v as validateBoringPluginManifest } from './manifest-C2vVgH_e.js';
5
5
  import 'dockview-react';
6
6
 
7
7
  type CatalogBadge = {
@@ -69,6 +69,10 @@ interface LeftTabParams {
69
69
  searchQuery?: string;
70
70
  bridge?: unknown;
71
71
  chromeless?: boolean;
72
+ revealFileTreeRequest?: {
73
+ path: string;
74
+ seq: number;
75
+ } | null;
72
76
  }
73
77
 
74
78
  interface BoringFrontPanelRegistration<T = unknown> {
@@ -85,6 +89,7 @@ interface BoringFrontPanelRegistration<T = unknown> {
85
89
  essential?: boolean;
86
90
  lazy?: boolean;
87
91
  chromeless?: boolean;
92
+ supportsFullPage?: boolean;
88
93
  source?: string;
89
94
  }
90
95
  interface BoringFrontPanelCommandRegistration {
package/dist/plugin.js CHANGED
@@ -183,8 +183,8 @@ function validateBoringField(issues, boring) {
183
183
  ));
184
184
  }
185
185
  }
186
- if (boring.id !== void 0) {
187
- issues.push(issue("INVALID_FIELD", "boring.id", "boring.id is not supported; package discovery identity comes from package.json#name"));
186
+ if (boring.id !== void 0 && (typeof boring.id !== "string" || !isValidBoringPluginId(boring.id))) {
187
+ issues.push(issue("INVALID_ID", "boring.id", "boring.id must start with a letter or number and use only letters, numbers, dot, underscore, colon, or dash"));
188
188
  }
189
189
  const front = boring.front;
190
190
  if (front !== void 0 && (typeof front !== "string" || !isSafePluginRelativePath(front))) {
@@ -198,6 +198,7 @@ function validateBoringField(issues, boring) {
198
198
  issues.push(issue("INVALID_FIELD", "boring.label", "boring.label must be a string when provided"));
199
199
  }
200
200
  return {
201
+ ...typeof boring.id === "string" ? { id: boring.id } : {},
201
202
  ...typeof boring.front === "string" ? { front: boring.front } : {},
202
203
  ...typeof boring.server === "string" || boring.server === false ? { server: boring.server } : {},
203
204
  ...typeof boring.label === "string" ? { label: boring.label } : {}
package/dist/server.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- export { S as ServerBootstrapOptions, e as ServerBootstrapResult, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, W as WorkspaceServerPlugin, f as bootstrapServer, c as createInMemoryBridge, g as defineServerPlugin, v as validateServerPlugin } from './createInMemoryBridge-CYNW1h_o.js';
1
+ import { e as BoringServerPluginManifest, B as BoringPluginFrontTargetResolver, f as BoringPluginListEntry, g as BoringPluginFrontTarget, h as BoringPluginEvent, P as PluginRestartSurface } from './createInMemoryBridge--ZFPAgXy.js';
2
+ export { i as BoringPluginFrontTargetResolverContext, j as BoringPluginNativeFrontTarget, k as BoringPluginNativeFrontTargetTrust, S as ServerBootstrapOptions, l as ServerBootstrapResult, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, W as WorkspaceServerPlugin, m as bootstrapServer, c as createInMemoryBridge, n as defineServerPlugin, v as validateServerPlugin } from './createInMemoryBridge--ZFPAgXy.js';
2
3
  import { FastifyRequest, FastifyInstance } from 'fastify';
3
- import { U as UiBridge, A as AgentTool } from './ui-bridge-CT18yqwN.js';
4
- export { C as CommandResult, a as UiCommand, b as UiState } from './ui-bridge-CT18yqwN.js';
5
- import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-CyNNdfYz.js';
4
+ import { U as UiBridge, A as AgentTool } from './ui-bridge-Bdgl2hR8.js';
5
+ export { C as CommandResult, a as UiCommand, b as UiState } from './ui-bridge-Bdgl2hR8.js';
6
+ import { PiPackageSource } from '@hachej/boring-agent/server';
6
7
  export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
8
+ import './manifest-C2vVgH_e.js';
7
9
 
8
10
  interface UiRoutesOptions {
9
11
  bridge?: UiBridge;
@@ -29,6 +31,13 @@ interface ExecUiToolOptions {
29
31
  * but existence is left to the frontend/remote filesystem.
30
32
  */
31
33
  workspaceRoot?: string;
34
+ /**
35
+ * Optional workspace-backed stat hook for modes where the host path is not
36
+ * directly stat-able (for example remote sandboxes). When provided, path-
37
+ * bearing UI commands can still reject missing paths and convert folders to
38
+ * file-tree reveal commands.
39
+ */
40
+ resolvePathKind?: (relPath: string) => Promise<"file" | "dir" | null>;
32
41
  /**
33
42
  * After dispatching a state-changing command (openFile, openPanel,
34
43
  * openSurface, closePanel), wait this many ms before the first state
@@ -62,9 +71,9 @@ declare function createWorkspaceUiTools(uiBridge: UiBridge, opts?: ExecUiToolOpt
62
71
 
63
72
  /**
64
73
  * 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
74
+ * block (per DECISIONS.md #17). The block lists workspace-readable paths
75
+ * into the installed `@hachej/boring-pi` package so the agent's `read` tool
76
+ * can fetch the SKILL.md + reference docs on demand, without inlining their
68
77
  * ~12-30 KB of markdown into every system prompt.
69
78
  *
70
79
  * `@hachej/boring-pi` is a runtime dep of `@hachej/boring-workspace`;
@@ -95,68 +104,6 @@ interface BuildBoringSystemPromptOptions {
95
104
  }
96
105
  declare function buildBoringSystemPrompt(opts: BuildBoringSystemPromptOptions): string;
97
106
 
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
107
  interface BoringPluginPreflightIssue {
161
108
  pluginDir: string;
162
109
  pluginId?: string;
@@ -184,6 +131,16 @@ interface BoringPluginAssetManagerOptions {
184
131
  * the default assumes workspace root equals `process.cwd()`.
185
132
  */
186
133
  errorRoot?: string;
134
+ /**
135
+ * Optional host-owned runtime front-target resolver. When omitted, list/event
136
+ * payloads preserve the existing `frontUrl` (`/@fs/...`) fallback only.
137
+ */
138
+ frontTargetResolver?: BoringPluginFrontTargetResolver;
139
+ /**
140
+ * Keep legacy `/@fs/...` frontUrl payloads alongside frontTarget. Defaults
141
+ * to true for back-compat; packaged CLI folder/workspaces mode can disable it.
142
+ */
143
+ includeLegacyFrontUrl?: boolean;
187
144
  }
188
145
  interface LoadBoringAssetsError {
189
146
  id: string;
@@ -195,25 +152,48 @@ interface LoadBoringAssetsResult {
195
152
  events: BoringPluginEvent[];
196
153
  errors: LoadBoringAssetsError[];
197
154
  }
155
+ interface LoadedBoringPluginInspection {
156
+ id: string;
157
+ version: string;
158
+ revision: number;
159
+ rootDir: string;
160
+ frontPath?: string;
161
+ frontTarget?: BoringPluginFrontTarget;
162
+ }
163
+ interface LoadedBoringPluginPiSnapshot {
164
+ additionalSkillPaths: string[];
165
+ packages: PiPackageSource[];
166
+ extensionPaths: string[];
167
+ systemPromptAppend?: string;
168
+ }
198
169
  type Listener = (event: BoringPluginEvent) => void;
199
170
  declare class BoringPluginAssetManager {
200
171
  private readonly pluginDirs;
201
172
  private readonly errorRoot;
173
+ private readonly frontTargetResolver?;
174
+ private readonly includeLegacyFrontUrl;
202
175
  private readonly loaded;
203
176
  private readonly revisions;
204
177
  private readonly listeners;
178
+ private readonly lastErrors;
205
179
  private loading;
206
180
  private reloadQueued;
207
181
  constructor(options: BoringPluginAssetManagerOptions);
208
182
  preflight(): BoringPluginPreflightResult;
209
183
  list(): BoringPluginListEntry[];
210
184
  getError(pluginId: string): string | null;
185
+ getErrors(): LoadBoringAssetsError[];
186
+ inspectLoaded(): LoadedBoringPluginInspection[];
187
+ inspectLoadedPiSnapshot(): LoadedBoringPluginPiSnapshot;
211
188
  subscribe(listener: Listener): () => void;
212
189
  load(): Promise<LoadBoringAssetsResult>;
213
190
  private drainLoads;
214
191
  private doLoadOnce;
215
192
  private collectPreflightErrors;
216
193
  private bumpRevision;
194
+ private toListEntry;
195
+ private frontUrlPayload;
196
+ private resolveFrontTarget;
217
197
  private emit;
218
198
  private errorPath;
219
199
  private writeError;
@@ -294,4 +274,4 @@ declare function pluginFileSignature(path: string | undefined): string;
294
274
  declare function writePluginSignatureCache(pluginRootDir: string, payload: Omit<PluginSignatureCachePayload, "version" | "loadedAt"> & Partial<Pick<PluginSignatureCachePayload, "loadedAt">>): void;
295
275
  declare function readPluginSignatureCache(pluginRootDir: string): PluginSignatureCachePayload | null;
296
276
 
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 };
277
+ export { BoringPluginAssetManager, BoringPluginEvent, BoringPluginFrontTarget, BoringPluginFrontTargetResolver, BoringPluginListEntry, type BoringPluginScanResult, BoringServerPluginManifest, type PluginReloadRebuild, type PluginRestartWarning, UiBridge, type UiRoutesOptions, aggregatePluginPrompts, boringPluginRoutes, buildBoringSystemPrompt, collectRestartWarnings, createExecUiTool, createGetUiStateTool, createWorkspaceUiTools, pluginFileSignature, preflightBoringPlugins, readBoringPlugins, readPluginSignatureCache, scanBoringPlugins, uiRoutes, writePluginSignatureCache };