@hachej/boring-workspace 0.1.35 → 0.1.37
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.
- package/dist/{FileTree-CkCxHBDu.js → FileTree-D6oUyX8I.js} +1 -1
- package/dist/{MarkdownEditor-CtPphEVP.js → MarkdownEditor-DPFwqtbH.js} +1 -1
- package/dist/{WorkspaceLoadingState-Bl-92Dly.js → WorkspaceLoadingState-C-whZTne.js} +12 -13
- package/dist/{WorkspaceProvider-BhRPFy5R.js → WorkspaceProvider-CX_4aV6Z.js} +2546 -2645
- package/dist/agent-tool-CB0RQyx9.d.ts +32 -0
- package/dist/app-front.d.ts +1 -20
- package/dist/app-front.js +396 -388
- package/dist/app-server.d.ts +27 -40
- package/dist/app-server.js +96 -87
- package/dist/boring-workspace.css +1 -1
- package/dist/{createInMemoryBridge-zb8MpO60.d.ts → createInMemoryBridge-DSjZ9efK.d.ts} +13 -4
- package/dist/plugin.d.ts +65 -1
- package/dist/plugin.js +39 -0
- package/dist/server.d.ts +43 -16
- package/dist/server.js +39 -19
- package/dist/shared.d.ts +2 -1
- package/dist/testing.js +1 -1
- package/dist/{ui-bridge-DFNem0df.d.ts → ui-bridge-LeBuZqfA.d.ts} +1 -32
- package/dist/workspace.css +42 -43
- package/dist/workspace.d.ts +0 -19
- package/dist/workspace.js +129 -129
- package/docs/PLUGIN_SYSTEM.md +2 -12
- package/package.json +4 -4
package/dist/app-server.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { PiPackageSource, PiExtensionFactory, CreateAgentAppOptions, ProvisionWorkspaceRuntimeOptions } from '@hachej/boring-agent/server';
|
|
2
2
|
export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
|
|
3
3
|
import { FastifyInstance } from 'fastify';
|
|
4
|
-
import { W as WorkspaceServerPlugin, S as ServerBootstrapOptions, B as BoringPluginSourceInput, a as BoringPluginFrontTargetResolver, b as WorkspaceProvisioningContribution, c as WorkspaceRouteContribution, d as createInMemoryBridge } from './createInMemoryBridge-
|
|
5
|
-
export { e as ServerWorkspaceRuntimeProvisioningInput } from './createInMemoryBridge-
|
|
4
|
+
import { W as WorkspaceServerPlugin, S as ServerBootstrapOptions, B as BoringPluginSourceInput, a as BoringPluginFrontTargetResolver, b as WorkspaceProvisioningContribution, c as WorkspaceRouteContribution, d as createInMemoryBridge } from './createInMemoryBridge-DSjZ9efK.js';
|
|
5
|
+
export { e as ServerWorkspaceRuntimeProvisioningInput } from './createInMemoryBridge-DSjZ9efK.js';
|
|
6
6
|
import './manifest-C2vVgH_e.js';
|
|
7
|
-
import './
|
|
7
|
+
import './agent-tool-CB0RQyx9.js';
|
|
8
|
+
import './ui-bridge-LeBuZqfA.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Directory-source entry: `{ dir, options?, hotReload? }`. Resolved via
|
|
@@ -89,14 +90,6 @@ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions,
|
|
|
89
90
|
force?: boolean;
|
|
90
91
|
};
|
|
91
92
|
validateUiPaths?: boolean;
|
|
92
|
-
/**
|
|
93
|
-
* Whether the canonical agent reload refreshes discovered package plugins.
|
|
94
|
-
* When true, chat `/reload` refreshes package front/Pi metadata and reports
|
|
95
|
-
* static-server restart warnings; dir-source server entries are re-imported
|
|
96
|
-
* for diagnostics only. When false, initial static discovery still runs, but
|
|
97
|
-
* dynamic Pi/system-prompt refresh is disabled. Defaults to true.
|
|
98
|
-
*/
|
|
99
|
-
pluginHotReload?: boolean;
|
|
100
93
|
/**
|
|
101
94
|
* App-default plugin packages (by npm name OR absolute filesystem path).
|
|
102
95
|
* Each entry is resolved at boot, registered as a Pi package (so Pi sees
|
|
@@ -112,28 +105,12 @@ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions,
|
|
|
112
105
|
*/
|
|
113
106
|
defaultPluginPackages?: string[];
|
|
114
107
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* against the package.json's own directory.
|
|
120
|
-
*
|
|
121
|
-
* Example app `package.json`:
|
|
122
|
-
*
|
|
123
|
-
* {
|
|
124
|
-
* "name": "my-app",
|
|
125
|
-
* "boring": {
|
|
126
|
-
* "defaultPluginPackages": [
|
|
127
|
-
* "@hachej/boring-ask-user",
|
|
128
|
-
* "./src/plugins/playgroundDataCatalog"
|
|
129
|
-
* ]
|
|
130
|
-
* }
|
|
131
|
-
* }
|
|
132
|
-
*
|
|
133
|
-
* Lets apps declare their plugin set in the canonical app manifest
|
|
134
|
-
* instead of inside the server boot path.
|
|
108
|
+
* The host app's package root. Anchors npm-name resolution of
|
|
109
|
+
* `defaultPluginPackages` at the app's own node_modules (in addition to a
|
|
110
|
+
* walk-up from `workspaceRoot`). Pass when the workspace root does not
|
|
111
|
+
* live under the app directory.
|
|
135
112
|
*/
|
|
136
|
-
|
|
113
|
+
appRoot?: string;
|
|
137
114
|
/** Additional plugin collection roots to scan alongside workspace .pi/extensions and package/plugin-derived roots. */
|
|
138
115
|
additionalBoringPluginDirs?: BoringPluginSourceInput[];
|
|
139
116
|
/**
|
|
@@ -151,8 +128,6 @@ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions,
|
|
|
151
128
|
installPluginAuthoring?: boolean;
|
|
152
129
|
/** Optional host-owned front-target override for boring plugin list/event payloads. */
|
|
153
130
|
boringPluginFrontTargetResolver?: BoringPluginFrontTargetResolver;
|
|
154
|
-
/** Preserve legacy `/@fs/...` frontUrl payloads alongside frontTarget. Defaults to true. */
|
|
155
|
-
boringPluginIncludeLegacyFrontUrl?: boolean;
|
|
156
131
|
}
|
|
157
132
|
declare const PLUGIN_AUTHORING_PROVISIONING_IDS: Set<string>;
|
|
158
133
|
declare function omitPluginAuthoringProvisioning(plugins: WorkspaceRuntimeProvisioningInput[]): WorkspaceRuntimeProvisioningInput[];
|
|
@@ -190,15 +165,27 @@ declare function createWorkspaceAgentServer(opts?: CreateWorkspaceAgentServerOpt
|
|
|
190
165
|
|
|
191
166
|
interface ResolveDefaultWorkspacePluginPackagePathsOptions {
|
|
192
167
|
workspaceRoot?: string;
|
|
168
|
+
/**
|
|
169
|
+
* Internal plugin packages, listed explicitly in host boot code — npm
|
|
170
|
+
* package names (resolved via require.resolve) or absolute directory
|
|
171
|
+
* paths. Mirrors the front side, where internal plugins are statically
|
|
172
|
+
* imported in the app: both sides declare the same explicit list.
|
|
173
|
+
*/
|
|
193
174
|
defaultPluginPackages?: string[];
|
|
194
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Directory whose node_modules anchors npm-name resolution (the host
|
|
177
|
+
* package's own root). Defaults to walking up from `workspaceRoot`,
|
|
178
|
+
* then from this module's location.
|
|
179
|
+
*/
|
|
180
|
+
anchorDir?: string;
|
|
195
181
|
}
|
|
196
182
|
/**
|
|
197
|
-
* Resolve
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
183
|
+
* Resolve each entry in `defaultPluginPackages` to an absolute package
|
|
184
|
+
* directory. Accepts either an npm-style name (resolved via
|
|
185
|
+
* `require.resolve('<name>/package.json')`) or an absolute filesystem
|
|
186
|
+
* path. THROWS on unresolved entries — a typo or missing dependency
|
|
187
|
+
* is an app boot-time error, not something to silently drop.
|
|
201
188
|
*/
|
|
202
|
-
declare function resolveDefaultWorkspacePluginPackagePaths({ workspaceRoot, defaultPluginPackages,
|
|
189
|
+
declare function resolveDefaultWorkspacePluginPackagePaths({ workspaceRoot, defaultPluginPackages, anchorDir, }?: ResolveDefaultWorkspacePluginPackagePathsOptions): string[];
|
|
203
190
|
|
|
204
191
|
export { type CollectWorkspaceAgentServerPluginsOptions, type CreateWorkspaceAgentServerOptions, type DirPluginEntry, PLUGIN_AUTHORING_PROVISIONING_IDS, type PluginResolveContext, type ResolveDefaultWorkspacePluginPackagePathsOptions, type WorkspaceAgentPiOptions, type WorkspaceAgentServerPluginCollection, type WorkspaceAgentServerPluginContext, type WorkspacePluginEntry, type WorkspacePluginPackagePiSnapshot, WorkspaceProvisioningContribution, WorkspaceRouteContribution, type WorkspaceRuntimeProvisioningInput, buildWorkspaceContextPrompt, collectWorkspaceAgentServerPlugins, createWorkspaceAgentServer, hasDirServerPlugin, omitPluginAuthoringProvisioning, provisionWorkspaceAgentServer, readWorkspacePluginPackagePiSnapshot, readWorkspacePluginPackageRuntimePlugins, resolveDefaultWorkspacePluginPackagePaths, resolveOnePluginEntry };
|
package/dist/app-server.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveMode,
|
|
9
9
|
VERCEL_SANDBOX_WORKSPACE_ROOT
|
|
10
10
|
} from "@hachej/boring-agent/server";
|
|
11
|
-
import { existsSync as existsSync7, readFileSync as
|
|
11
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
12
12
|
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join7, resolve as resolve7 } from "path";
|
|
13
13
|
import { homedir } from "os";
|
|
14
14
|
import { createRequire as createRequire4 } from "module";
|
|
@@ -987,7 +987,6 @@ var BoringPluginAssetManager = class {
|
|
|
987
987
|
pluginDirs;
|
|
988
988
|
errorRoot;
|
|
989
989
|
frontTargetResolver;
|
|
990
|
-
includeLegacyFrontUrl;
|
|
991
990
|
loaded = /* @__PURE__ */ new Map();
|
|
992
991
|
revisions = /* @__PURE__ */ new Map();
|
|
993
992
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -998,7 +997,16 @@ var BoringPluginAssetManager = class {
|
|
|
998
997
|
this.pluginDirs = options.pluginDirs;
|
|
999
998
|
this.errorRoot = options.errorRoot ?? join4(process.cwd(), ".pi", "extensions");
|
|
1000
999
|
this.frontTargetResolver = options.frontTargetResolver;
|
|
1001
|
-
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Replace the scanned source roots. Lets hosts re-resolve discovery inputs
|
|
1003
|
+
* (e.g. workspace `.pi/settings.json` package sources, which can gain
|
|
1004
|
+
* entries after `boring-ui-plugin install`) before the next load() so
|
|
1005
|
+
* `/reload` picks up newly installed plugin sources without a process
|
|
1006
|
+
* restart.
|
|
1007
|
+
*/
|
|
1008
|
+
setPluginDirs(pluginDirs) {
|
|
1009
|
+
this.pluginDirs = pluginDirs;
|
|
1002
1010
|
}
|
|
1003
1011
|
preflight() {
|
|
1004
1012
|
return preflightBoringPlugins(this.pluginDirs);
|
|
@@ -1006,6 +1014,17 @@ var BoringPluginAssetManager = class {
|
|
|
1006
1014
|
list() {
|
|
1007
1015
|
return [...this.loaded.values()].map((plugin) => this.toListEntry(plugin));
|
|
1008
1016
|
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Plugins whose front lifecycle the SSE channel owns. Internal plugins are
|
|
1019
|
+
* app code — their front is statically bundled by the host app and must
|
|
1020
|
+
* never be re-imported through the hot-reload pipeline (a second module
|
|
1021
|
+
* instance would carry a fresh React context identity, breaking
|
|
1022
|
+
* provider ↔ panel lookups). They are loaded server-side (routes, agent
|
|
1023
|
+
* tools, Pi snapshot) but excluded from SSE replay and live events.
|
|
1024
|
+
*/
|
|
1025
|
+
listExternal() {
|
|
1026
|
+
return [...this.loaded.values()].filter((plugin) => plugin.source.kind === "external").map((plugin) => this.toListEntry(plugin));
|
|
1027
|
+
}
|
|
1009
1028
|
getError(pluginId) {
|
|
1010
1029
|
const path = this.errorPath(pluginId);
|
|
1011
1030
|
if (!path || !existsSync4(path)) return null;
|
|
@@ -1082,9 +1101,7 @@ ${prompts.join("\n\n")}` } : {}
|
|
|
1082
1101
|
} catch {
|
|
1083
1102
|
}
|
|
1084
1103
|
}
|
|
1085
|
-
|
|
1086
|
-
events.push(event);
|
|
1087
|
-
this.emit(event);
|
|
1104
|
+
this.record(events, { type: "boring.plugin.unload", id, revision }, previous?.source);
|
|
1088
1105
|
}
|
|
1089
1106
|
for (const plugin of nextPlugins) {
|
|
1090
1107
|
try {
|
|
@@ -1115,22 +1132,18 @@ ${prompts.join("\n\n")}` } : {}
|
|
|
1115
1132
|
boring: plugin.boring,
|
|
1116
1133
|
version: plugin.version,
|
|
1117
1134
|
revision,
|
|
1118
|
-
...this.frontUrlPayload(plugin.frontUrl),
|
|
1119
1135
|
...frontTarget ? { frontTarget } : {},
|
|
1120
1136
|
...requiresRestart.length > 0 ? { requiresRestart } : {}
|
|
1121
1137
|
};
|
|
1122
|
-
|
|
1123
|
-
this.emit(event);
|
|
1138
|
+
this.record(events, event, plugin.source);
|
|
1124
1139
|
} catch (error) {
|
|
1125
1140
|
const revision = this.bumpRevision(plugin.id);
|
|
1126
1141
|
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
1127
1142
|
this.writeError(plugin.id, message);
|
|
1128
|
-
const event = { type: "boring.plugin.error", id: plugin.id, revision, message };
|
|
1129
1143
|
const loadError = { id: plugin.id, revision, message };
|
|
1130
1144
|
this.lastErrors.set(plugin.id, loadError);
|
|
1131
1145
|
errors.push(loadError);
|
|
1132
|
-
events.
|
|
1133
|
-
this.emit(event);
|
|
1146
|
+
this.record(events, { type: "boring.plugin.error", id: plugin.id, revision, message }, plugin.source);
|
|
1134
1147
|
}
|
|
1135
1148
|
}
|
|
1136
1149
|
return { loaded: this.list(), events, errors };
|
|
@@ -1163,16 +1176,14 @@ Plugin dir: ${error.pluginDir}`;
|
|
|
1163
1176
|
...plugin.pi ? { pi: plugin.pi } : {},
|
|
1164
1177
|
version: plugin.version,
|
|
1165
1178
|
revision: plugin.revision,
|
|
1166
|
-
...this.frontUrlPayload(plugin.frontUrl),
|
|
1167
1179
|
...plugin.frontTarget ? { frontTarget: plugin.frontTarget } : {}
|
|
1168
1180
|
};
|
|
1169
1181
|
}
|
|
1170
|
-
frontUrlPayload(frontUrl) {
|
|
1171
|
-
if (!this.includeLegacyFrontUrl || !frontUrl) return {};
|
|
1172
|
-
return { frontUrl };
|
|
1173
|
-
}
|
|
1174
1182
|
resolveFrontTarget(plugin, revision) {
|
|
1175
|
-
if (!plugin.frontPath
|
|
1183
|
+
if (!plugin.frontPath) return void 0;
|
|
1184
|
+
if (!this.frontTargetResolver) {
|
|
1185
|
+
return plugin.frontUrl ? { kind: "module-url", entryUrl: plugin.frontUrl, revision } : void 0;
|
|
1186
|
+
}
|
|
1176
1187
|
const frontEntrySubpath = typeof plugin.boring.front === "string" ? plugin.boring.front.replace(/^\.\//, "") : normalizePluginSubpath(plugin.rootDir, plugin.frontPath);
|
|
1177
1188
|
const frontTarget = this.frontTargetResolver(plugin, {
|
|
1178
1189
|
revision,
|
|
@@ -1181,6 +1192,16 @@ Plugin dir: ${error.pluginDir}`;
|
|
|
1181
1192
|
if (!frontTarget) return void 0;
|
|
1182
1193
|
return { ...frontTarget, revision };
|
|
1183
1194
|
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Append to the load result's events array and emit on the SSE channel —
|
|
1197
|
+
* unless the source is internal. Internal plugins are app code: their
|
|
1198
|
+
* events stay in the load result (for /reload diagnostics and restart
|
|
1199
|
+
* warnings) but never reach SSE subscribers (see listExternal).
|
|
1200
|
+
*/
|
|
1201
|
+
record(events, event, source) {
|
|
1202
|
+
events.push(event);
|
|
1203
|
+
if (source?.kind !== "internal") this.emit(event);
|
|
1204
|
+
}
|
|
1184
1205
|
emit(event) {
|
|
1185
1206
|
for (const listener of [...this.listeners]) {
|
|
1186
1207
|
try {
|
|
@@ -1265,14 +1286,13 @@ async function boringPluginRoutes(app, opts) {
|
|
|
1265
1286
|
}
|
|
1266
1287
|
write(event.type, payload);
|
|
1267
1288
|
});
|
|
1268
|
-
for (const plugin of manager.
|
|
1289
|
+
for (const plugin of manager.listExternal()) {
|
|
1269
1290
|
write("boring.plugin.load", {
|
|
1270
1291
|
type: "boring.plugin.load",
|
|
1271
1292
|
id: plugin.id,
|
|
1272
1293
|
boring: plugin.boring,
|
|
1273
1294
|
version: plugin.version,
|
|
1274
1295
|
revision: plugin.revision,
|
|
1275
|
-
...plugin.frontUrl ? { frontUrl: plugin.frontUrl } : {},
|
|
1276
1296
|
...plugin.frontTarget ? { frontTarget: plugin.frontTarget } : {},
|
|
1277
1297
|
replay: true
|
|
1278
1298
|
});
|
|
@@ -1872,31 +1892,18 @@ async function rebuildServerPlugins(opts) {
|
|
|
1872
1892
|
}
|
|
1873
1893
|
|
|
1874
1894
|
// src/app/server/defaultPluginPackages.ts
|
|
1875
|
-
import { existsSync as existsSync6
|
|
1895
|
+
import { existsSync as existsSync6 } from "fs";
|
|
1876
1896
|
import { createRequire as createRequire3 } from "module";
|
|
1877
1897
|
import { dirname as dirname6, isAbsolute as isAbsolute3, join as join6 } from "path";
|
|
1878
|
-
function
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
} catch {
|
|
1884
|
-
return [];
|
|
1885
|
-
}
|
|
1886
|
-
const entries = pkg.boring?.defaultPluginPackages;
|
|
1887
|
-
if (!Array.isArray(entries)) return [];
|
|
1888
|
-
const pkgDir = dirname6(appPackageJsonPath);
|
|
1889
|
-
return entries.filter((e) => typeof e === "string").map((entry) => {
|
|
1890
|
-
if (entry.startsWith("./") || entry.startsWith("../")) {
|
|
1891
|
-
return join6(pkgDir, entry);
|
|
1892
|
-
}
|
|
1893
|
-
return entry;
|
|
1894
|
-
});
|
|
1895
|
-
}
|
|
1896
|
-
function resolveDefaultPluginPackagePaths(workspaceRoot, defaultPluginPackages) {
|
|
1898
|
+
function resolveDefaultWorkspacePluginPackagePaths({
|
|
1899
|
+
workspaceRoot = process.cwd(),
|
|
1900
|
+
defaultPluginPackages = [],
|
|
1901
|
+
anchorDir
|
|
1902
|
+
} = {}) {
|
|
1897
1903
|
if (defaultPluginPackages.length === 0) return [];
|
|
1898
|
-
const
|
|
1899
|
-
const
|
|
1904
|
+
const requireFromAnchor = anchorDir ? createRequire3(join6(anchorDir, "package.json")) : null;
|
|
1905
|
+
const requireFromWorkspace = createRequire3(join6(workspaceRoot, "package.json"));
|
|
1906
|
+
const resolvers = [requireFromAnchor, requireFromWorkspace].filter((req) => req !== null);
|
|
1900
1907
|
const resolved = [];
|
|
1901
1908
|
for (const entry of defaultPluginPackages) {
|
|
1902
1909
|
if (isAbsolute3(entry)) {
|
|
@@ -1909,32 +1916,22 @@ function resolveDefaultPluginPackagePaths(workspaceRoot, defaultPluginPackages)
|
|
|
1909
1916
|
continue;
|
|
1910
1917
|
}
|
|
1911
1918
|
let resolvedPath = null;
|
|
1912
|
-
|
|
1913
|
-
resolvedPath = dirname6(require5.resolve(`${entry}/package.json`));
|
|
1914
|
-
} catch {
|
|
1919
|
+
for (const req of resolvers) {
|
|
1915
1920
|
try {
|
|
1916
|
-
resolvedPath = dirname6(
|
|
1921
|
+
resolvedPath = dirname6(req.resolve(`${entry}/package.json`));
|
|
1922
|
+
break;
|
|
1917
1923
|
} catch {
|
|
1918
|
-
throw new Error(
|
|
1919
|
-
`defaultPluginPackages: cannot resolve "${entry}" \u2014 install it as a dep of the app (or workspace root) so require.resolve can find its package.json. Pass an absolute path instead if the package lives outside node_modules.`
|
|
1920
|
-
);
|
|
1921
1924
|
}
|
|
1922
1925
|
}
|
|
1926
|
+
if (!resolvedPath) {
|
|
1927
|
+
throw new Error(
|
|
1928
|
+
`defaultPluginPackages: cannot resolve "${entry}" \u2014 install it as a dep of the app so require.resolve can find its package.json. Pass an absolute path instead if the package lives outside node_modules.`
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1923
1931
|
resolved.push(resolvedPath);
|
|
1924
1932
|
}
|
|
1925
1933
|
return resolved;
|
|
1926
1934
|
}
|
|
1927
|
-
function resolveDefaultWorkspacePluginPackagePaths({
|
|
1928
|
-
workspaceRoot = process.cwd(),
|
|
1929
|
-
defaultPluginPackages = [],
|
|
1930
|
-
appPackageJsonPath
|
|
1931
|
-
} = {}) {
|
|
1932
|
-
const manifestPluginPackages = readAppManifestDefaultPlugins(appPackageJsonPath);
|
|
1933
|
-
return resolveDefaultPluginPackagePaths(workspaceRoot, [
|
|
1934
|
-
...manifestPluginPackages,
|
|
1935
|
-
...defaultPluginPackages
|
|
1936
|
-
]);
|
|
1937
|
-
}
|
|
1938
1935
|
|
|
1939
1936
|
// src/server/bridge/createInMemoryBridge.ts
|
|
1940
1937
|
var MAX_PENDING_COMMANDS = 1e3;
|
|
@@ -1979,6 +1976,20 @@ function createInMemoryBridge() {
|
|
|
1979
1976
|
};
|
|
1980
1977
|
}
|
|
1981
1978
|
|
|
1979
|
+
// src/shared/plugins/uiBridgeRegistry.ts
|
|
1980
|
+
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("@hachej/boring-workspace:active-ui-bridge");
|
|
1981
|
+
function slot() {
|
|
1982
|
+
return globalThis;
|
|
1983
|
+
}
|
|
1984
|
+
function registerWorkspaceUiBridge(bridge) {
|
|
1985
|
+
slot()[REGISTRY_KEY] = bridge;
|
|
1986
|
+
return () => {
|
|
1987
|
+
if (slot()[REGISTRY_KEY] === bridge) {
|
|
1988
|
+
slot()[REGISTRY_KEY] = void 0;
|
|
1989
|
+
}
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1982
1993
|
// src/server/ui-control/tools/uiTools.ts
|
|
1983
1994
|
import { stat } from "fs/promises";
|
|
1984
1995
|
import { resolve as resolve6, isAbsolute as isAbsolute4, relative as relative3, win32 } from "path";
|
|
@@ -2598,7 +2609,7 @@ function resolveWorkspacePackageRoot() {
|
|
|
2598
2609
|
];
|
|
2599
2610
|
for (const candidate of candidates) {
|
|
2600
2611
|
try {
|
|
2601
|
-
const pkg = JSON.parse(
|
|
2612
|
+
const pkg = JSON.parse(readFileSync5(join7(candidate, "package.json"), "utf8"));
|
|
2602
2613
|
if (pkg.name === "@hachej/boring-workspace") return candidate;
|
|
2603
2614
|
} catch {
|
|
2604
2615
|
}
|
|
@@ -2608,7 +2619,7 @@ function resolveWorkspacePackageRoot() {
|
|
|
2608
2619
|
function readPackageVersion(packageRoot) {
|
|
2609
2620
|
if (!packageRoot) return void 0;
|
|
2610
2621
|
try {
|
|
2611
|
-
const pkg = JSON.parse(
|
|
2622
|
+
const pkg = JSON.parse(readFileSync5(join7(packageRoot, "package.json"), "utf8"));
|
|
2612
2623
|
return typeof pkg.version === "string" && pkg.version.length > 0 ? pkg.version : void 0;
|
|
2613
2624
|
} catch {
|
|
2614
2625
|
return void 0;
|
|
@@ -2625,7 +2636,7 @@ function resolveBoringPiPackageRoot() {
|
|
|
2625
2636
|
];
|
|
2626
2637
|
for (const candidate of candidates) {
|
|
2627
2638
|
try {
|
|
2628
|
-
const pkg = JSON.parse(
|
|
2639
|
+
const pkg = JSON.parse(readFileSync5(join7(candidate, "package.json"), "utf8"));
|
|
2629
2640
|
if (pkg.name === "@hachej/boring-pi") return candidate;
|
|
2630
2641
|
} catch {
|
|
2631
2642
|
}
|
|
@@ -2638,7 +2649,7 @@ function resolveBoringPiPackageRoot() {
|
|
|
2638
2649
|
}
|
|
2639
2650
|
function isUsableBoringUiPluginCliPackageRoot(candidate) {
|
|
2640
2651
|
try {
|
|
2641
|
-
const pkg = JSON.parse(
|
|
2652
|
+
const pkg = JSON.parse(readFileSync5(join7(candidate, "package.json"), "utf8"));
|
|
2642
2653
|
return pkg.name === "@hachej/boring-ui-plugin-cli" && existsSync7(join7(candidate, "dist", "bin.js"));
|
|
2643
2654
|
} catch {
|
|
2644
2655
|
return false;
|
|
@@ -2776,7 +2787,7 @@ function resolveLocalPiPackageSource(settingsDir, source) {
|
|
|
2776
2787
|
function readPiSettingsBoringPluginSources(settingsPath, workspaceId) {
|
|
2777
2788
|
let raw;
|
|
2778
2789
|
try {
|
|
2779
|
-
raw = JSON.parse(
|
|
2790
|
+
raw = JSON.parse(readFileSync5(settingsPath, "utf8"));
|
|
2780
2791
|
} catch {
|
|
2781
2792
|
return [];
|
|
2782
2793
|
}
|
|
@@ -2885,6 +2896,7 @@ function readWorkspacePluginPackagePiSnapshot(pluginDirs) {
|
|
|
2885
2896
|
async function createWorkspaceAgentServer(opts = {}) {
|
|
2886
2897
|
const workspaceRoot = opts.workspaceRoot ?? process.cwd();
|
|
2887
2898
|
const bridge = createInMemoryBridge();
|
|
2899
|
+
const unregisterUiBridge = registerWorkspaceUiBridge(bridge);
|
|
2888
2900
|
const resolvedMode = opts.runtimeModeAdapter?.id ?? opts.mode ?? autoDetectMode();
|
|
2889
2901
|
const modeAdapter = opts.runtimeModeAdapter ?? resolveMode(resolvedMode);
|
|
2890
2902
|
const workspaceFsCapability = modeAdapter.workspaceFsCapability ?? "best-effort";
|
|
@@ -2895,11 +2907,10 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2895
2907
|
const ctx = { workspaceRoot, bridge };
|
|
2896
2908
|
const defaultPluginPackagePaths = resolveDefaultWorkspacePluginPackagePaths({
|
|
2897
2909
|
workspaceRoot,
|
|
2898
|
-
|
|
2899
|
-
|
|
2910
|
+
defaultPluginPackages: opts.defaultPluginPackages,
|
|
2911
|
+
anchorDir: opts.appRoot
|
|
2900
2912
|
});
|
|
2901
|
-
const
|
|
2902
|
-
const defaultPluginDirEntries = defaultPluginPackagePaths.map((dir) => ({ dir, hotReload: pluginHotReload })).filter((entry) => hasDirServerPlugin(entry));
|
|
2913
|
+
const defaultPluginDirEntries = defaultPluginPackagePaths.map((dir) => ({ dir, hotReload: true })).filter((entry) => hasDirServerPlugin(entry));
|
|
2903
2914
|
const allPluginEntries = [
|
|
2904
2915
|
...defaultPluginDirEntries,
|
|
2905
2916
|
...opts.plugins ?? []
|
|
@@ -2933,7 +2944,7 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2933
2944
|
return boringPluginDirs;
|
|
2934
2945
|
};
|
|
2935
2946
|
refreshBoringPluginDirs();
|
|
2936
|
-
const staticPluginPackagePiSnapshot =
|
|
2947
|
+
const staticPluginPackagePiSnapshot = emptyPackageJsonPiSnapshot();
|
|
2937
2948
|
const staticPiSkillPaths = [
|
|
2938
2949
|
...baseStaticPiSkillPaths,
|
|
2939
2950
|
...staticPluginPackagePiSnapshot.additionalSkillPaths
|
|
@@ -2946,12 +2957,11 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2946
2957
|
...baseStaticPiExtensionPaths,
|
|
2947
2958
|
...staticPluginPackagePiSnapshot.extensionPaths
|
|
2948
2959
|
];
|
|
2949
|
-
const getHotReloadablePiResources =
|
|
2960
|
+
const getHotReloadablePiResources = () => readWorkspacePluginPackagePiSnapshot(refreshBoringPluginDirs());
|
|
2950
2961
|
const boringAssetManager = new BoringPluginAssetManager({
|
|
2951
2962
|
pluginDirs: boringPluginDirs,
|
|
2952
2963
|
errorRoot: join7(workspaceRoot, ".pi", "extensions"),
|
|
2953
|
-
frontTargetResolver: opts.boringPluginFrontTargetResolver
|
|
2954
|
-
includeLegacyFrontUrl: opts.boringPluginIncludeLegacyFrontUrl
|
|
2964
|
+
frontTargetResolver: opts.boringPluginFrontTargetResolver
|
|
2955
2965
|
});
|
|
2956
2966
|
const runtimeBackendRegistry = new RuntimeBackendRegistry();
|
|
2957
2967
|
const buildRuntimeProvisioningInputs = () => {
|
|
@@ -3019,19 +3029,17 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
3019
3029
|
beforeReload: async () => {
|
|
3020
3030
|
let restart_warnings = [];
|
|
3021
3031
|
let diagnostics = [];
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
diagnostics = [...scanDiagnostics, ...backendReload.diagnostics, ...rebuild.diagnostics];
|
|
3034
|
-
}
|
|
3032
|
+
refreshBoringPluginDirs();
|
|
3033
|
+
const scan = await boringAssetManager.load();
|
|
3034
|
+
const backendReload = await runtimeBackendRegistry.reloadFromLoadedPlugins(boringAssetManager.inspectLoaded());
|
|
3035
|
+
restart_warnings = collectRestartWarnings(scan.events);
|
|
3036
|
+
const scanDiagnostics = scan.errors.map((error) => ({
|
|
3037
|
+
source: `boring plugin asset scan (${error.id})`,
|
|
3038
|
+
message: error.message,
|
|
3039
|
+
pluginId: error.id
|
|
3040
|
+
}));
|
|
3041
|
+
const rebuild = await rebuildPlugins();
|
|
3042
|
+
diagnostics = [...scanDiagnostics, ...backendReload.diagnostics, ...rebuild.diagnostics];
|
|
3035
3043
|
await runRuntimeProvisioning();
|
|
3036
3044
|
const callerResult = await opts.beforeReload?.();
|
|
3037
3045
|
const callerRestartWarnings = callerResult && typeof callerResult === "object" ? callerResult.restart_warnings ?? [] : [];
|
|
@@ -3054,7 +3062,7 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
3054
3062
|
extensionFactories: pluginCollection.agentOptions.pi?.extensionFactories,
|
|
3055
3063
|
getHotReloadableResources: getHotReloadablePiResources
|
|
3056
3064
|
},
|
|
3057
|
-
systemPromptDynamic:
|
|
3065
|
+
systemPromptDynamic: () => aggregatePluginPrompts(boringAssetManager)
|
|
3058
3066
|
});
|
|
3059
3067
|
refreshBoringPluginDirs();
|
|
3060
3068
|
await boringAssetManager.load();
|
|
@@ -3062,6 +3070,7 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
3062
3070
|
if (typeof app.addHook === "function") {
|
|
3063
3071
|
app.addHook("onClose", async () => {
|
|
3064
3072
|
await runtimeBackendRegistry.close();
|
|
3073
|
+
unregisterUiBridge();
|
|
3065
3074
|
});
|
|
3066
3075
|
}
|
|
3067
3076
|
await app.register(uiRoutes, { bridge, preserveStateKeys: pluginCollection.preservedUiStateKeys });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.dv-shell{--dv-background-color: var(--background);--dv-paneview-header-border-color: var(--border);--dv-tabs-and-actions-container-font-size: .8125rem;--dv-tabs-and-actions-container-height: 52px;--dv-tab-close-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--dv-group-view-background-color: var(--background);--dv-tabs-and-actions-container-background-color: var(--background);--dv-activegroup-visiblepanel-tab-background-color: var(--background);--dv-activegroup-hiddenpanel-tab-background-color: var(--muted);--dv-inactivegroup-visiblepanel-tab-background-color: var(--background);--dv-inactivegroup-hiddenpanel-tab-background-color: var(--muted);--dv-activegroup-visiblepanel-tab-color: var(--foreground);--dv-activegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-inactivegroup-visiblepanel-tab-color: var(--foreground);--dv-inactivegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-tab-divider-color: transparent;--dv-drag-over-background-color: oklch(from var(--accent) l c h / .3);--dv-drag-over-border-color: var(--accent);--dv-separator-border: var(--border);color:var(--foreground);background-color:var(--background)}.dv-shell .dv-tabs-and-actions-container,.dv-shell .tabs-and-actions-container{background-color:var(--background)!important;border-bottom:1px solid oklch(from var(--border) l c h / .4);padding:6px 8px 0;gap:4px;align-items:flex-end}.dv-shell .dv-tabs-container,.dv-shell .tab-container{background-color:transparent!important;gap:4px;align-self:stretch;display:flex;align-items:flex-end}.workbench-dockview .dv-shell .dv-tabs-and-actions-container,.workbench-dockview .dv-shell .tabs-and-actions-container,.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{height:44px!important}.workbench-dockview[data-collapsed-sources=true] .dv-tabs-and-actions-container,.workbench-dockview[data-collapsed-sources=true] .tabs-and-actions-container{padding-left:44px!important}.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{padding-right:44px!important}.dv-shell .dv-tab,.dv-shell .tab{color:var(--muted-foreground)!important;background-color:transparent!important;border:1px solid transparent;border-top-left-radius:8px;border-top-right-radius:8px;transition:color .18s cubic-bezier(.22,1,.36,1),background-color .18s cubic-bezier(.22,1,.36,1),border-color .18s cubic-bezier(.22,1,.36,1);min-width:120px;max-width:220px;padding:0;height:34px;align-self:end;font-size:12.5px;letter-spacing:-.01em}.dv-shell .dv-tab:hover,.dv-shell .tab:hover{color:var(--foreground)!important;background-color:oklch(from var(--foreground) l c h / .04)!important}.dv-shell .dv-tab>*,.dv-shell .tab>*{width:100%;height:100%}.dv-shell .dv-tab.dv-active-tab,.dv-shell .tab.active-tab{color:var(--foreground)!important;background-color:var(--background)!important;border-color:oklch(from var(--border) l c h / .5);border-bottom-color:var(--background);margin-bottom:-1px;position:relative;z-index:1;font-weight:500}.dv-shell .dv-tab.dv-active-tab:before,.dv-shell .tab.active-tab:before{content:"";position:absolute;left:10px;right:10px;top:-1px;height:2px;background:var(--accent);border-radius:0 0 2px 2px;opacity:0;transition:opacity .2s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-tab.dv-active-tab:hover:before,.dv-shell .tab.active-tab:hover:before{opacity:.7}.dv-shell .sash-container .sash,.dv-shell .dv-sash-container .dv-sash{transition:background-color .
|
|
1
|
+
.dv-shell{--dv-background-color: var(--background);--dv-paneview-header-border-color: var(--border);--dv-tabs-and-actions-container-font-size: .8125rem;--dv-tabs-and-actions-container-height: 52px;--dv-tab-close-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--dv-group-view-background-color: var(--background);--dv-tabs-and-actions-container-background-color: var(--background);--dv-activegroup-visiblepanel-tab-background-color: var(--background);--dv-activegroup-hiddenpanel-tab-background-color: var(--muted);--dv-inactivegroup-visiblepanel-tab-background-color: var(--background);--dv-inactivegroup-hiddenpanel-tab-background-color: var(--muted);--dv-activegroup-visiblepanel-tab-color: var(--foreground);--dv-activegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-inactivegroup-visiblepanel-tab-color: var(--foreground);--dv-inactivegroup-hiddenpanel-tab-color: var(--muted-foreground);--dv-tab-divider-color: transparent;--dv-drag-over-background-color: oklch(from var(--accent) l c h / .3);--dv-drag-over-border-color: var(--accent);--dv-separator-border: var(--border);color:var(--foreground);background-color:var(--background)}.dv-shell .dv-tabs-and-actions-container,.dv-shell .tabs-and-actions-container{background-color:var(--background)!important;border-bottom:1px solid oklch(from var(--border) l c h / .4);padding:6px 8px 0;gap:4px;align-items:flex-end}.dv-shell .dv-tabs-container,.dv-shell .tab-container{background-color:transparent!important;gap:4px;align-self:stretch;display:flex;align-items:flex-end}.workbench-dockview .dv-shell .dv-tabs-and-actions-container,.workbench-dockview .dv-shell .tabs-and-actions-container,.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{height:44px!important}.workbench-dockview[data-collapsed-sources=true] .dv-tabs-and-actions-container,.workbench-dockview[data-collapsed-sources=true] .tabs-and-actions-container{padding-left:44px!important}.workbench-dockview .dv-tabs-and-actions-container,.workbench-dockview .tabs-and-actions-container{padding-right:44px!important}.dv-shell .dv-tab,.dv-shell .tab{color:var(--muted-foreground)!important;background-color:transparent!important;border:1px solid transparent;border-top-left-radius:8px;border-top-right-radius:8px;transition:color .18s cubic-bezier(.22,1,.36,1),background-color .18s cubic-bezier(.22,1,.36,1),border-color .18s cubic-bezier(.22,1,.36,1);min-width:120px;max-width:220px;padding:0;height:34px;align-self:end;font-size:12.5px;letter-spacing:-.01em}.dv-shell .dv-tab:hover,.dv-shell .tab:hover{color:var(--foreground)!important;background-color:oklch(from var(--foreground) l c h / .04)!important}.dv-shell .dv-tab>*,.dv-shell .tab>*{width:100%;height:100%}.dv-shell .dv-tab.dv-active-tab,.dv-shell .tab.active-tab{color:var(--foreground)!important;background-color:var(--background)!important;border-color:oklch(from var(--border) l c h / .5);border-bottom-color:var(--background);margin-bottom:-1px;position:relative;z-index:1;font-weight:500}.dv-shell .dv-tab.dv-active-tab:before,.dv-shell .tab.active-tab:before{content:"";position:absolute;left:10px;right:10px;top:-1px;height:2px;background:var(--accent);border-radius:0 0 2px 2px;opacity:0;transition:opacity .2s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-tab.dv-active-tab:hover:before,.dv-shell .tab.active-tab:hover:before{opacity:.7}.dv-shell{--dv-sash-color: transparent;--dv-active-sash-color: transparent;--dv-active-sash-transition-delay: 0s}.dv-shell .sash-container .sash,.dv-shell .dv-sash-container .dv-sash{transition:box-shadow .16s cubic-bezier(.22,1,.36,1),background-color .16s cubic-bezier(.22,1,.36,1)}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash{width:12px;margin-left:-4px}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash{height:12px;margin-top:-4px}.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 5px 0 oklch(from var(--primary) l c h / .35),inset 6px 0 oklch(from var(--primary) l c h / .35)}.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:hover,.dv-shell .dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash:active{box-shadow:inset 0 0 0 1px oklch(from var(--primary) l c h / .45),inset 0 5px oklch(from var(--primary) l c h / .35),inset 0 6px oklch(from var(--primary) l c h / .35)}.dv-shell .drop-target-dropzone>.drop-target-selection,.dv-shell .dv-drop-target-dropzone>.dv-drop-target-selection{background-color:oklch(from var(--primary) l c h / .15);border:2px dashed var(--primary);border-radius:calc(var(--radius) - 2px)}.dv-shell .watermark,.dv-shell .dv-watermark{color:var(--muted-foreground)}.dv-shell,.dv-shell .dv-dockview,.dv-shell .dv-groupview,.dv-shell .groupview,.dv-shell .groupview>.content-container,.dv-shell .dv-view-container,.dv-shell .view-container{background-color:var(--background)}.dv-shell .dv-groupview,.dv-shell .groupview{color:var(--foreground)}.dv-shell .right-actions-container,.dv-shell .left-actions-container,.dv-shell .dv-right-actions-container,.dv-shell .dv-left-actions-container{color:var(--muted-foreground);display:flex;align-items:center;align-self:stretch}.dv-shell .right-actions-container:hover,.dv-shell .left-actions-container:hover,.dv-shell .dv-right-actions-container:hover,.dv-shell .dv-left-actions-container:hover{color:var(--foreground)}.dv-shell .dv-drag-image{opacity:.85;border:1px solid var(--border);border-radius:calc(var(--radius) - 2px);box-shadow:0 4px 12px #00000026}.dv-chat-stage{--dv-tabs-and-actions-container-height: 32px;--dv-tabs-and-actions-container-font-size: .75rem;--dv-activegroup-visiblepanel-tab-background-color: transparent;--dv-activegroup-hiddenpanel-tab-background-color: transparent;--dv-inactivegroup-visiblepanel-tab-background-color: transparent;--dv-inactivegroup-hiddenpanel-tab-background-color: transparent}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container{border-bottom:none;padding:0;gap:0;align-items:stretch}.dv-shell.dv-chat-stage .dv-tabs-and-actions-container.dv-single-tab .dv-tabs-container{width:100%}.dv-shell.dv-chat-stage .dv-tab,.dv-shell.dv-chat-stage .dv-tab.dv-active-tab{width:100%;height:100%;min-width:0;max-width:none;flex:1 1 auto;align-self:stretch;margin-bottom:0;padding:0;border:none;border-radius:0;background-color:transparent!important}.dv-shell.dv-chat-stage .dv-tab.dv-active-tab:before{content:none}.dv-chat-stage .dv-default-tab-action{display:none}.dv-chat-stage .dv-groupview{position:relative}.dv-chat-stage .dv-groupview:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;pointer-events:none;background:transparent;transition:background-color .22s cubic-bezier(.22,1,.36,1),box-shadow .22s cubic-bezier(.22,1,.36,1)}[data-boring-workspace-part=chat-pane-stage][data-multi-pane=true] .dv-groupview:not(.dv-active-group):after{background:oklch(from var(--foreground) l c h / .035)}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-C2vVgH_e.js';
|
|
2
2
|
import { PiPackageSource, PluginSkillSource, ProvisionWorkspaceRuntimeOptions } from '@hachej/boring-agent/server';
|
|
3
3
|
import { FastifyPluginAsync } from 'fastify';
|
|
4
|
-
import { A as AgentTool
|
|
4
|
+
import { A as AgentTool } from './agent-tool-CB0RQyx9.js';
|
|
5
|
+
import { U as UiBridge } from './ui-bridge-LeBuZqfA.js';
|
|
5
6
|
|
|
6
7
|
type BoringPluginNativeFrontTargetTrust$1 = "local-trusted-native";
|
|
7
8
|
/**
|
|
@@ -17,14 +18,23 @@ interface BoringPluginNativeFrontTarget$1 {
|
|
|
17
18
|
revision: number;
|
|
18
19
|
trust: BoringPluginNativeFrontTargetTrust$1;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Plugin front served as a plain browser module URL — the Vite-dev transport
|
|
23
|
+
* (`/@fs/...`). Hosts running a Vite dev server let Vite transform the entry;
|
|
24
|
+
* the CLI's runtime host mints `native` targets instead.
|
|
25
|
+
*/
|
|
26
|
+
interface BoringPluginModuleUrlFrontTarget {
|
|
27
|
+
kind: "module-url";
|
|
28
|
+
entryUrl: string;
|
|
29
|
+
revision: number;
|
|
30
|
+
}
|
|
31
|
+
type BoringPluginFrontTarget$1 = BoringPluginNativeFrontTarget$1 | BoringPluginModuleUrlFrontTarget;
|
|
21
32
|
type BoringPluginEvent$1 = {
|
|
22
33
|
type: "boring.plugin.load";
|
|
23
34
|
id: string;
|
|
24
35
|
boring: BoringPackageBoringField;
|
|
25
36
|
version: string;
|
|
26
37
|
revision: number;
|
|
27
|
-
frontUrl?: string;
|
|
28
38
|
frontTarget?: BoringPluginFrontTarget$1;
|
|
29
39
|
} | {
|
|
30
40
|
type: "boring.plugin.unload";
|
|
@@ -42,7 +52,6 @@ interface BoringPluginListEntry$1 {
|
|
|
42
52
|
pi?: BoringPackagePiField;
|
|
43
53
|
version: string;
|
|
44
54
|
revision: number;
|
|
45
|
-
frontUrl?: string;
|
|
46
55
|
frontTarget?: BoringPluginFrontTarget$1;
|
|
47
56
|
}
|
|
48
57
|
|
package/dist/plugin.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ComponentType, ReactNode } from 'react';
|
|
|
2
2
|
import { P as PaneProps, a as PanelConfig, S as SurfaceOpenRequest, c as SurfacePanelResolution } from './surface-obE7YwJk.js';
|
|
3
3
|
export { W as WORKSPACE_OPEN_PATH_SURFACE_KIND } from './surface-obE7YwJk.js';
|
|
4
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
|
+
import { a as UiCommand, C as CommandResult, U as UiBridge } from './ui-bridge-LeBuZqfA.js';
|
|
5
6
|
import 'dockview-react';
|
|
6
7
|
|
|
7
8
|
type CatalogBadge = {
|
|
@@ -209,4 +210,67 @@ declare function createCapturingBoringFrontAPI(options?: {
|
|
|
209
210
|
}): CapturingBoringFrontAPIHandle;
|
|
210
211
|
declare function captureFrontPlugin(plugin: BoringFrontFactoryWithId): CapturedFrontPlugin;
|
|
211
212
|
|
|
212
|
-
|
|
213
|
+
/**
|
|
214
|
+
* In-process registry that lets a plugin's Pi slash command reach the live
|
|
215
|
+
* workspace `UiBridge` WITHOUT an HTTP round-trip or a `BORING_UI_URL` env var.
|
|
216
|
+
*
|
|
217
|
+
* Why this exists
|
|
218
|
+
* ---------------
|
|
219
|
+
* A Pi extension slash-command handler only receives Pi's terminal-oriented
|
|
220
|
+
* `ctx.ui` (notify/select/confirm). It has no concept of the boring-ui
|
|
221
|
+
* workspace UI bridge, so the old canonical template resorted to
|
|
222
|
+
* `fetch(BORING_UI_URL + "/api/v1/ui/commands")` — fragile, and it silently
|
|
223
|
+
* no-op'd whenever the env var was unset (which is the common case). The bridge
|
|
224
|
+
* is already an in-process object owned by the agent server, so the right thing
|
|
225
|
+
* is to call `bridge.postCommand(...)` directly — the exact same path the
|
|
226
|
+
* agent's `exec_ui` tool uses.
|
|
227
|
+
*
|
|
228
|
+
* Why globalThis
|
|
229
|
+
* --------------
|
|
230
|
+
* Hot-reloadable plugins are loaded by Pi through jiti, which keeps its own
|
|
231
|
+
* module cache. A plain module-level singleton populated by the server is NOT
|
|
232
|
+
* guaranteed to be the same instance the plugin imports. `globalThis` is shared
|
|
233
|
+
* across every module realm in the process, so a `Symbol.for`-keyed slot is the
|
|
234
|
+
* one storage that both the server and a jiti-loaded plugin observe identically.
|
|
235
|
+
*
|
|
236
|
+
* This module is browser-safe (only `globalThis` + types), so it can live on
|
|
237
|
+
* the `@hachej/boring-workspace/plugin` authoring surface.
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
/** The active workspace `UiBridge`, or `undefined` when none is registered. */
|
|
241
|
+
declare function getWorkspaceUiBridge(): UiBridge | undefined;
|
|
242
|
+
/**
|
|
243
|
+
* Thrown by the plugin-facing helpers when no workspace bridge is active — for
|
|
244
|
+
* example when plugin code runs under a bare Pi CLI with no workspace UI
|
|
245
|
+
* attached. The message is deliberately actionable.
|
|
246
|
+
*/
|
|
247
|
+
declare class NoWorkspaceUiBridgeError extends Error {
|
|
248
|
+
constructor();
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Dispatch an arbitrary UI command through the active workspace bridge. This is
|
|
252
|
+
* the same call the agent's `exec_ui` tool makes; the connected browser drains
|
|
253
|
+
* the command. Prefer the named helpers below for common actions.
|
|
254
|
+
*/
|
|
255
|
+
declare function execWorkspaceUi(command: UiCommand): Promise<CommandResult>;
|
|
256
|
+
interface OpenPanelArgs {
|
|
257
|
+
/** Tab instance id. Reuse the same id to re-activate an existing tab. */
|
|
258
|
+
id: string;
|
|
259
|
+
/** Panel component id (one of the workspace's registered panels). */
|
|
260
|
+
component: string;
|
|
261
|
+
/** Optional params forwarded to the panel component. */
|
|
262
|
+
params?: Record<string, unknown>;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Open an app/plugin panel in the workspace from a plugin slash command.
|
|
266
|
+
* In-process — no URL, no env. Throws `NoWorkspaceUiBridgeError` if no bridge.
|
|
267
|
+
*/
|
|
268
|
+
declare function openPanel(args: OpenPanelArgs): Promise<CommandResult>;
|
|
269
|
+
/**
|
|
270
|
+
* Show a workspace notification (toast) from a plugin slash command. Unlike
|
|
271
|
+
* Pi's `ctx.ui.notify` (a terminal notification that is swallowed in
|
|
272
|
+
* server/headless mode), this surfaces in the browser via the UI bridge.
|
|
273
|
+
*/
|
|
274
|
+
declare function notify(msg: string, level?: "info" | "warn" | "error"): Promise<CommandResult>;
|
|
275
|
+
|
|
276
|
+
export { type BoringFrontAPI, type BoringFrontBindingRegistration, type BoringFrontFactory, type BoringFrontFactoryWithId, type BoringFrontLeftTabRegistration, type BoringFrontPanelCommandRegistration, type BoringFrontPanelRegistration, type BoringFrontProviderRegistration, type BoringFrontSetup, type BoringFrontSurfaceResolverRegistration, type CapturedBoringFrontRegistrations, type CapturedFrontPlugin, type CapturingBoringFrontAPIHandle, type DefinePluginConfig, NoWorkspaceUiBridgeError, type OpenPanelArgs, PaneProps, captureFrontPlugin, createCapturingBoringFrontAPI, definePlugin, execWorkspaceUi, getWorkspaceUiBridge, notify, openPanel };
|