@hachej/boring-workspace 0.1.30 → 0.1.32
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-BltQETt9.js +289 -0
- package/dist/{MarkdownEditor-DPBSzTBz.js → MarkdownEditor-heUJdK4j.js} +1 -1
- package/dist/WorkspaceLoadingState-InXsc_8G.js +719 -0
- package/dist/{WorkspaceProvider-0V-2x7AH.js → WorkspaceProvider-Cg-J1wxr.js} +2750 -2570
- package/dist/app-front.d.ts +22 -2
- package/dist/app-front.js +672 -524
- package/dist/app-server.d.ts +21 -4
- package/dist/app-server.js +277 -104
- package/dist/boring-workspace.css +1 -1
- package/dist/{createInMemoryBridge--ZFPAgXy.d.ts → createInMemoryBridge-HJopAIbo.d.ts} +12 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/server.d.ts +62 -9
- package/dist/server.js +261 -46
- package/dist/shared.d.ts +2 -2
- package/dist/{surface-CEEkd81D.d.ts → surface-obE7YwJk.d.ts} +2 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +1 -1
- package/dist/{ui-bridge-Bdgl2hR8.d.ts → ui-bridge-DFNem0df.d.ts} +2 -2
- package/dist/workspace.css +79 -27
- package/dist/workspace.d.ts +88 -2
- package/dist/workspace.js +472 -386
- package/docs/PLUGIN_STRUCTURE.md +5 -4
- package/docs/PLUGIN_SYSTEM.md +6 -6
- package/docs/plans/archive/UNIFIED_PLUGIN_SYSTEM_PLAN.md +2 -2
- package/package.json +3 -3
- package/dist/FileTree-DUxjUbxL.js +0 -266
- package/dist/WorkspaceLoadingState-DJF_4S4_.js +0 -613
package/dist/app-server.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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 BoringPluginFrontTargetResolver, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, c as createInMemoryBridge } from './createInMemoryBridge
|
|
5
|
-
export { d as ServerWorkspaceRuntimeProvisioningInput } from './createInMemoryBridge
|
|
4
|
+
import { W as WorkspaceServerPlugin, S as ServerBootstrapOptions, B as BoringPluginFrontTargetResolver, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, c as createInMemoryBridge } from './createInMemoryBridge-HJopAIbo.js';
|
|
5
|
+
export { d as ServerWorkspaceRuntimeProvisioningInput } from './createInMemoryBridge-HJopAIbo.js';
|
|
6
6
|
import './manifest-C2vVgH_e.js';
|
|
7
|
-
import './ui-bridge-
|
|
7
|
+
import './ui-bridge-DFNem0df.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Directory-source entry: `{ dir, options?, hotReload? }`. Resolved via
|
|
@@ -133,11 +133,26 @@ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions,
|
|
|
133
133
|
appPackageJsonPath?: string;
|
|
134
134
|
/** Additional plugin collection roots to scan alongside workspace .pi/extensions and package/plugin-derived roots. */
|
|
135
135
|
additionalBoringPluginDirs?: string[];
|
|
136
|
+
/**
|
|
137
|
+
* Install and advertise the boring plugin-authoring runtime.
|
|
138
|
+
*
|
|
139
|
+
* Keep this off for production/hosted workspaces unless a plugin-editing
|
|
140
|
+
* experience is explicitly enabled. Remote sandboxes can support authoring,
|
|
141
|
+
* but the CLI should be provisioned only for that activated editing mode,
|
|
142
|
+
* not for every normal workspace boot.
|
|
143
|
+
*
|
|
144
|
+
* Defaults to true for local/standalone strong-filesystem runtimes and false
|
|
145
|
+
* for remote/best-effort runtimes. Core/full-app may choose a stricter
|
|
146
|
+
* default at its composition boundary.
|
|
147
|
+
*/
|
|
148
|
+
installPluginAuthoring?: boolean;
|
|
136
149
|
/** Optional host-owned front-target override for boring plugin list/event payloads. */
|
|
137
150
|
boringPluginFrontTargetResolver?: BoringPluginFrontTargetResolver;
|
|
138
151
|
/** Preserve legacy `/@fs/...` frontUrl payloads alongside frontTarget. Defaults to true. */
|
|
139
152
|
boringPluginIncludeLegacyFrontUrl?: boolean;
|
|
140
153
|
}
|
|
154
|
+
declare const PLUGIN_AUTHORING_PROVISIONING_IDS: Set<string>;
|
|
155
|
+
declare function omitPluginAuthoringProvisioning(plugins: WorkspaceRuntimeProvisioningInput[]): WorkspaceRuntimeProvisioningInput[];
|
|
141
156
|
interface WorkspaceAgentServerPluginCollection {
|
|
142
157
|
provisioningContributions: WorkspaceProvisioningContribution[];
|
|
143
158
|
runtimePlugins: WorkspaceRuntimeProvisioningInput[];
|
|
@@ -149,6 +164,8 @@ interface CollectWorkspaceAgentServerPluginsOptions extends Pick<ServerBootstrap
|
|
|
149
164
|
workspaceRoot?: string;
|
|
150
165
|
systemPromptAppend?: string;
|
|
151
166
|
pi?: WorkspaceAgentPiOptions;
|
|
167
|
+
/** Whether to include built-in boring plugin-authoring provisioning/prompt resources. */
|
|
168
|
+
installPluginAuthoring?: boolean;
|
|
152
169
|
}
|
|
153
170
|
declare function buildWorkspaceContextPrompt(): string;
|
|
154
171
|
declare function collectWorkspaceAgentServerPlugins(opts?: CollectWorkspaceAgentServerPluginsOptions): WorkspaceAgentServerPluginCollection;
|
|
@@ -181,4 +198,4 @@ interface ResolveDefaultWorkspacePluginPackagePathsOptions {
|
|
|
181
198
|
*/
|
|
182
199
|
declare function resolveDefaultWorkspacePluginPackagePaths({ workspaceRoot, defaultPluginPackages, appPackageJsonPath, }?: ResolveDefaultWorkspacePluginPackagePathsOptions): string[];
|
|
183
200
|
|
|
184
|
-
export { type CollectWorkspaceAgentServerPluginsOptions, type CreateWorkspaceAgentServerOptions, type DirPluginEntry, type PluginResolveContext, type ResolveDefaultWorkspacePluginPackagePathsOptions, type WorkspaceAgentPiOptions, type WorkspaceAgentServerPluginCollection, type WorkspaceAgentServerPluginContext, type WorkspacePluginEntry, type WorkspacePluginPackagePiSnapshot, WorkspaceProvisioningContribution, WorkspaceRouteContribution, type WorkspaceRuntimeProvisioningInput, buildWorkspaceContextPrompt, collectWorkspaceAgentServerPlugins, createWorkspaceAgentServer, hasDirServerPlugin, provisionWorkspaceAgentServer, readWorkspacePluginPackagePiSnapshot, readWorkspacePluginPackageRuntimePlugins, resolveDefaultWorkspacePluginPackagePaths, resolveOnePluginEntry };
|
|
201
|
+
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
|
@@ -54,7 +54,7 @@ function buildBoringSystemPrompt(opts) {
|
|
|
54
54
|
if (opts.scaffoldCommand) {
|
|
55
55
|
n += 1;
|
|
56
56
|
steps.push(
|
|
57
|
-
`**${n}. Check plugin-root support, then scaffold.** Bash \`boring-ui
|
|
57
|
+
`**${n}. Check plugin-root support, then scaffold.** Bash \`boring-ui-plugin status --json\`; continue only if \`workspaceLocalPluginRoots\` is \`true\`. Then bash \`${opts.scaffoldCommand} <kebab-name> "$BORING_AGENT_WORKSPACE_ROOT"\`. Read generated \`package.json\` + \`front/index.tsx\`; do NOT write from memory.`
|
|
58
58
|
);
|
|
59
59
|
} else {
|
|
60
60
|
n += 1;
|
|
@@ -64,7 +64,11 @@ function buildBoringSystemPrompt(opts) {
|
|
|
64
64
|
}
|
|
65
65
|
n += 1;
|
|
66
66
|
steps.push(
|
|
67
|
-
opts.scaffoldCommand ? `**${n}. Edit the generated files
|
|
67
|
+
opts.scaffoldCommand ? `**${n}. Edit the generated files.** Keep scaffold imports/layout. Use \`@hachej/boring-ui-kit\` + workspace primitives for native UI; avoid ad-hoc inline UI.` : `**${n}. Create or edit plugin files.** Use the boring-plugin-authoring skill for imports, \`definePlugin\`, manifest layout, and boring-ui-kit design defaults.`
|
|
68
|
+
);
|
|
69
|
+
n += 1;
|
|
70
|
+
steps.push(
|
|
71
|
+
`**${n}. Install plugin-local deps only when needed.** If adding a browser package, bash \`cd "$BORING_AGENT_WORKSPACE_ROOT/.pi/extensions/<kebab-name>" && npm install <dep>\`; never install at workspace root. \`/reload\` never installs packages.`
|
|
68
72
|
);
|
|
69
73
|
n += 1;
|
|
70
74
|
if (verify) {
|
|
@@ -88,7 +92,7 @@ function buildBoringSystemPrompt(opts) {
|
|
|
88
92
|
"The `boring-plugin-authoring` skill listed under `<available_skills>` is the authoritative reference (read its `<location>`). Additional reference docs (`panels.md`, `bridge.md`, `plugins.md`) are unavailable on this host \u2014 `@hachej/boring-pi` is not installed."
|
|
89
93
|
].join("\n");
|
|
90
94
|
return [
|
|
91
|
-
"You are operating inside boring-ui. Before `.pi/extensions/<name>/`, run `boring-ui
|
|
95
|
+
"You are operating inside boring-ui. Before `.pi/extensions/<name>/`, run `boring-ui-plugin status --json`; continue only when `workspaceLocalPluginRoots` is `true`. Default to `.pi/extensions/<name>/`. Global `~/.pi/agent/extensions/` only for explicit requests.",
|
|
92
96
|
[
|
|
93
97
|
"## Plugin authoring \u2014 required workflow",
|
|
94
98
|
"",
|
|
@@ -103,6 +107,7 @@ function buildBoringSystemPrompt(opts) {
|
|
|
103
107
|
'- Server/Pi tool method: `handler` \u2014 use `execute`. Return shape: `{ content: [{ type: "text", text }] }` (NEVER a bare string).',
|
|
104
108
|
"- Manifest values: `boring.server: true` \u2014 use `false`/omit for hot-reload user plugins, or a relative path string only for advanced boot-time/static server integration.",
|
|
105
109
|
"- File layout: files at the package root, or `src/` / `dist/` / `lib/` subdirectories \u2014 the scaffold's hot-reload layout (`front/index.tsx`, optional `agent/index.ts` declared in `pi.extensions`) is the one the workspace refreshes on `/reload`.",
|
|
110
|
+
"- Dependency installs: do NOT install plugin UI dependencies at the workspace root. Install them inside `.pi/extensions/<name>/` and keep React/workspace/boring-ui-kit imports as host singletons, not plugin dependencies.",
|
|
106
111
|
"- Hot-reload agent tools: do NOT put them in `.pi/extensions/<name>/server/index.ts`; use `pi.extensions` instead. `boring.server` requires static composition plus process restart."
|
|
107
112
|
].join("\n"),
|
|
108
113
|
docsBlock
|
|
@@ -662,6 +667,23 @@ function validateSkills(pluginId, skills) {
|
|
|
662
667
|
}
|
|
663
668
|
}
|
|
664
669
|
}
|
|
670
|
+
function validatePluginAssets(pluginId, assets) {
|
|
671
|
+
for (let i = 0; i < assets.length; i++) {
|
|
672
|
+
const asset = assets[i];
|
|
673
|
+
if (!asset || typeof asset !== "object") {
|
|
674
|
+
fail(pluginId, `assets[${i}] must be an object`);
|
|
675
|
+
}
|
|
676
|
+
if (!asset.name || typeof asset.name !== "string") {
|
|
677
|
+
fail(pluginId, `assets[${i}].name must be a non-empty string`);
|
|
678
|
+
}
|
|
679
|
+
if (!isPathLike(asset.source)) {
|
|
680
|
+
fail(pluginId, `assets[${i}].source must be a string or URL`);
|
|
681
|
+
}
|
|
682
|
+
if (asset.target !== void 0 && (!asset.target || typeof asset.target !== "string")) {
|
|
683
|
+
fail(pluginId, `assets[${i}].target must be a non-empty string when provided`);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
665
687
|
function validateProvisioning(pluginId, provisioning) {
|
|
666
688
|
if (!provisioning || typeof provisioning !== "object") {
|
|
667
689
|
fail(pluginId, "provisioning must be an object");
|
|
@@ -775,6 +797,12 @@ function validateServerPlugin(plugin) {
|
|
|
775
797
|
}
|
|
776
798
|
plugin.agentTools.forEach((tool, index) => validateAgentTool(plugin.id, tool, index));
|
|
777
799
|
}
|
|
800
|
+
if (plugin.assets !== void 0) {
|
|
801
|
+
if (!Array.isArray(plugin.assets)) {
|
|
802
|
+
fail(plugin.id, "assets must be an array when provided");
|
|
803
|
+
}
|
|
804
|
+
validatePluginAssets(plugin.id, plugin.assets);
|
|
805
|
+
}
|
|
778
806
|
if (plugin.routes !== void 0 && typeof plugin.routes !== "function") {
|
|
779
807
|
fail(plugin.id, "routes must be a Fastify plugin function when provided");
|
|
780
808
|
}
|
|
@@ -1465,10 +1493,11 @@ function createInMemoryBridge() {
|
|
|
1465
1493
|
async postCommand(cmd) {
|
|
1466
1494
|
const seq = nextSeq++;
|
|
1467
1495
|
const annotated = { ...cmd, seq };
|
|
1468
|
-
|
|
1496
|
+
let delivered = false;
|
|
1469
1497
|
for (const handler of subscribers) {
|
|
1470
|
-
handler(annotated);
|
|
1498
|
+
if (handler(annotated) !== false) delivered = true;
|
|
1471
1499
|
}
|
|
1500
|
+
if (!delivered) enqueuePending(annotated);
|
|
1472
1501
|
return { seq, status: "ok" };
|
|
1473
1502
|
},
|
|
1474
1503
|
subscribeCommands(handler) {
|
|
@@ -1602,9 +1631,9 @@ function isVerified(kind, params, state) {
|
|
|
1602
1631
|
}
|
|
1603
1632
|
function createExecUiTool(uiBridge, opts = {}) {
|
|
1604
1633
|
const { workspaceRoot, resolvePathKind } = opts;
|
|
1605
|
-
const verifyDelayMs = opts.verifyDelayMs ??
|
|
1606
|
-
const verifyRetries = opts.verifyRetries ??
|
|
1607
|
-
const verifyIntervalMs = opts.verifyIntervalMs ??
|
|
1634
|
+
const verifyDelayMs = opts.verifyDelayMs ?? 250;
|
|
1635
|
+
const verifyRetries = opts.verifyRetries ?? 20;
|
|
1636
|
+
const verifyIntervalMs = opts.verifyIntervalMs ?? 250;
|
|
1608
1637
|
return {
|
|
1609
1638
|
name: "exec_ui",
|
|
1610
1639
|
readinessRequirements: ["ui-bridge"],
|
|
@@ -1676,11 +1705,12 @@ function createExecUiTool(uiBridge, opts = {}) {
|
|
|
1676
1705
|
" showNotification params: { msg: string, level?: 'info'|'warn'|'error' }",
|
|
1677
1706
|
"",
|
|
1678
1707
|
"Returns { seq, status, uiState? }. For openFile / openPanel / openSurface /",
|
|
1679
|
-
"closePanel the response includes a `uiState` snapshot
|
|
1680
|
-
"
|
|
1708
|
+
"closePanel the response includes a `uiState` snapshot after waiting up",
|
|
1709
|
+
"to a few seconds for the browser to dispatch the command \u2014 check",
|
|
1710
|
+
"uiState.openTabs to confirm the action took effect.",
|
|
1681
1711
|
"If the expected tab is missing from openTabs the frontend silently",
|
|
1682
1712
|
"rejected the command (unknown panel component, unregistered surface",
|
|
1683
|
-
"resolver, or
|
|
1713
|
+
"resolver, or disconnected browser). For other kinds only { seq, status }",
|
|
1684
1714
|
"is returned. To open a FILE prefer openFile (path-aware) over openPanel",
|
|
1685
1715
|
"(which is for non-file panes like charts)."
|
|
1686
1716
|
].join("\n"),
|
|
@@ -1768,7 +1798,7 @@ function createExecUiTool(uiBridge, opts = {}) {
|
|
|
1768
1798
|
await new Promise((r) => setTimeout(r, verifyDelayMs));
|
|
1769
1799
|
let uiState = await uiBridge.getState();
|
|
1770
1800
|
for (let i = 0; i < verifyRetries; i++) {
|
|
1771
|
-
if (isVerified(effectiveKind, cmdParams, uiState)) break;
|
|
1801
|
+
if (uiState === null || isVerified(effectiveKind, cmdParams, uiState)) break;
|
|
1772
1802
|
await new Promise((r) => setTimeout(r, verifyIntervalMs));
|
|
1773
1803
|
uiState = await uiBridge.getState();
|
|
1774
1804
|
}
|
|
@@ -1794,18 +1824,170 @@ function createWorkspaceUiTools(uiBridge, opts = {}) {
|
|
|
1794
1824
|
}
|
|
1795
1825
|
|
|
1796
1826
|
// src/server/ui-control/http/uiRoutes.ts
|
|
1827
|
+
import { z as z2 } from "zod";
|
|
1828
|
+
|
|
1829
|
+
// src/server/ui-control/panelStatus/paneRenderStatusStore.ts
|
|
1830
|
+
var DEFAULT_STATUS_TTL_MS = 5 * 6e4;
|
|
1831
|
+
var DEFAULT_UI_CONTACT_TTL_MS = 3e4;
|
|
1832
|
+
var DEFAULT_WORKSPACE_ID = "default";
|
|
1833
|
+
var MAX_ERROR_MESSAGE_LENGTH = 500;
|
|
1834
|
+
function normalizeWorkspaceId(workspaceId) {
|
|
1835
|
+
const trimmed = workspaceId?.trim();
|
|
1836
|
+
return trimmed || DEFAULT_WORKSPACE_ID;
|
|
1837
|
+
}
|
|
1838
|
+
function statusKey(input) {
|
|
1839
|
+
return `${input.workspaceId}\0${input.pluginId}\0${input.panelId}\0${input.panelInstanceId}`;
|
|
1840
|
+
}
|
|
1841
|
+
function redactMessage(message) {
|
|
1842
|
+
return message.replace(/\s+/g, " ").trim().slice(0, MAX_ERROR_MESSAGE_LENGTH);
|
|
1843
|
+
}
|
|
1844
|
+
function createPaneRenderStatusStore(options = {}) {
|
|
1845
|
+
const ttlMs = options.ttlMs ?? DEFAULT_STATUS_TTL_MS;
|
|
1846
|
+
const uiContactTtlMs = options.uiContactTtlMs ?? DEFAULT_UI_CONTACT_TTL_MS;
|
|
1847
|
+
const now = options.now ?? (() => Date.now());
|
|
1848
|
+
const statuses = /* @__PURE__ */ new Map();
|
|
1849
|
+
const lastUiContactByWorkspace = /* @__PURE__ */ new Map();
|
|
1850
|
+
function pruneExpired(current = now()) {
|
|
1851
|
+
for (const [key, status] of statuses) {
|
|
1852
|
+
const reportedAtMs = Date.parse(status.reportedAt);
|
|
1853
|
+
if (!Number.isFinite(reportedAtMs) || current - reportedAtMs > ttlMs) {
|
|
1854
|
+
statuses.delete(key);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
function touchUi(workspaceId) {
|
|
1859
|
+
lastUiContactByWorkspace.set(normalizeWorkspaceId(workspaceId), now());
|
|
1860
|
+
}
|
|
1861
|
+
function hasRecentUiContact(workspaceId) {
|
|
1862
|
+
const last = lastUiContactByWorkspace.get(normalizeWorkspaceId(workspaceId));
|
|
1863
|
+
return last !== void 0 && now() - last <= uiContactTtlMs;
|
|
1864
|
+
}
|
|
1865
|
+
return {
|
|
1866
|
+
touchUi,
|
|
1867
|
+
hasRecentUiContact,
|
|
1868
|
+
report(input) {
|
|
1869
|
+
pruneExpired();
|
|
1870
|
+
const workspaceId = normalizeWorkspaceId(input.workspaceId);
|
|
1871
|
+
touchUi(workspaceId);
|
|
1872
|
+
const snapshot = {
|
|
1873
|
+
workspaceId,
|
|
1874
|
+
pluginId: input.pluginId,
|
|
1875
|
+
panelId: input.panelId,
|
|
1876
|
+
panelInstanceId: input.panelInstanceId,
|
|
1877
|
+
state: input.state,
|
|
1878
|
+
reportedAt: new Date(now()).toISOString(),
|
|
1879
|
+
...input.revision !== void 0 ? { revision: input.revision } : {},
|
|
1880
|
+
...input.error ? { error: { code: input.error.code, message: redactMessage(input.error.message) } } : {}
|
|
1881
|
+
};
|
|
1882
|
+
statuses.set(statusKey(snapshot), snapshot);
|
|
1883
|
+
return snapshot;
|
|
1884
|
+
},
|
|
1885
|
+
get(input) {
|
|
1886
|
+
pruneExpired();
|
|
1887
|
+
const workspaceId = normalizeWorkspaceId(input.workspaceId);
|
|
1888
|
+
if (input.pluginId && input.panelId) {
|
|
1889
|
+
return statuses.get(statusKey({ workspaceId, pluginId: input.pluginId, panelId: input.panelId, panelInstanceId: input.panelInstanceId }));
|
|
1890
|
+
}
|
|
1891
|
+
for (const status of statuses.values()) {
|
|
1892
|
+
if (status.workspaceId !== workspaceId) continue;
|
|
1893
|
+
if (status.panelInstanceId !== input.panelInstanceId) continue;
|
|
1894
|
+
if (input.pluginId && status.pluginId !== input.pluginId) continue;
|
|
1895
|
+
if (input.panelId && status.panelId !== input.panelId) continue;
|
|
1896
|
+
return status;
|
|
1897
|
+
}
|
|
1898
|
+
return void 0;
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// src/server/ui-control/http/paneRenderStatusRoutes.ts
|
|
1797
1904
|
import { z } from "zod";
|
|
1905
|
+
var reportBodySchema = z.object({
|
|
1906
|
+
workspaceId: z.string().optional(),
|
|
1907
|
+
pluginId: z.string().min(1),
|
|
1908
|
+
panelId: z.string().min(1),
|
|
1909
|
+
panelInstanceId: z.string().min(1),
|
|
1910
|
+
revision: z.number().optional(),
|
|
1911
|
+
state: z.enum(["loading", "ready", "error", "missing"]),
|
|
1912
|
+
error: z.object({
|
|
1913
|
+
code: z.string().min(1),
|
|
1914
|
+
message: z.string().min(1)
|
|
1915
|
+
}).optional()
|
|
1916
|
+
});
|
|
1917
|
+
function createBodyValidator(schema) {
|
|
1918
|
+
return async function validateBody(request, reply) {
|
|
1919
|
+
const parsed = schema.safeParse(request.body);
|
|
1920
|
+
if (!parsed.success) {
|
|
1921
|
+
const firstIssue = parsed.error.issues[0];
|
|
1922
|
+
const fieldName = firstIssue?.path?.map((segment) => String(segment)).join(".");
|
|
1923
|
+
reply.code(400).send({
|
|
1924
|
+
error: "validation_error",
|
|
1925
|
+
message: firstIssue?.message ?? "Invalid request body",
|
|
1926
|
+
field: fieldName || void 0
|
|
1927
|
+
});
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
request.body = parsed.data;
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
function resolvePaneStatusWorkspaceId(request) {
|
|
1934
|
+
const headers = request.headers;
|
|
1935
|
+
const header = headers["x-boring-workspace-id"] ?? headers["X-Boring-Workspace-Id"];
|
|
1936
|
+
if (Array.isArray(header)) return header[0];
|
|
1937
|
+
if (typeof header === "string" && header.trim()) return header;
|
|
1938
|
+
const query = request.query;
|
|
1939
|
+
const workspaceId = query?.workspaceId;
|
|
1940
|
+
return typeof workspaceId === "string" && workspaceId.trim() ? workspaceId : void 0;
|
|
1941
|
+
}
|
|
1942
|
+
function paneRenderStatusRoutes(app, opts = {}, done) {
|
|
1943
|
+
const store = opts.store ?? createPaneRenderStatusStore();
|
|
1944
|
+
const validateReport = createBodyValidator(reportBodySchema);
|
|
1945
|
+
const getWorkspaceId = async (request) => {
|
|
1946
|
+
return await opts.getWorkspaceId?.(request) ?? resolvePaneStatusWorkspaceId(request);
|
|
1947
|
+
};
|
|
1948
|
+
app.put(
|
|
1949
|
+
"/api/v1/ui/panels/status",
|
|
1950
|
+
{ preHandler: validateReport },
|
|
1951
|
+
async (request, reply) => {
|
|
1952
|
+
const body = request.body;
|
|
1953
|
+
const workspaceId = await getWorkspaceId(request) ?? body.workspaceId;
|
|
1954
|
+
const status = store.report({ ...body, workspaceId });
|
|
1955
|
+
return reply.code(200).send({ ok: true, status });
|
|
1956
|
+
}
|
|
1957
|
+
);
|
|
1958
|
+
app.get("/api/v1/ui/panels/status", async (request, reply) => {
|
|
1959
|
+
const query = request.query;
|
|
1960
|
+
const panelInstanceId = query.panelInstanceId;
|
|
1961
|
+
if (typeof panelInstanceId !== "string" || !panelInstanceId.trim()) {
|
|
1962
|
+
return reply.code(400).send({ error: "validation_error", message: "panelInstanceId is required", field: "panelInstanceId" });
|
|
1963
|
+
}
|
|
1964
|
+
const workspaceId = await getWorkspaceId(request);
|
|
1965
|
+
const pluginId = typeof query.pluginId === "string" ? query.pluginId : void 0;
|
|
1966
|
+
const panelId = typeof query.panelId === "string" ? query.panelId : void 0;
|
|
1967
|
+
const status = store.get({ workspaceId, panelInstanceId, pluginId, panelId });
|
|
1968
|
+
const connected = store.hasRecentUiContact(workspaceId);
|
|
1969
|
+
return {
|
|
1970
|
+
ok: true,
|
|
1971
|
+
connected,
|
|
1972
|
+
state: status?.state ?? (connected ? "missing" : "no-browser-connected"),
|
|
1973
|
+
...status ? { status } : {}
|
|
1974
|
+
};
|
|
1975
|
+
});
|
|
1976
|
+
done();
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
// src/server/ui-control/http/uiRoutes.ts
|
|
1798
1980
|
var UI_BRIDGE_PROTOCOL_VERSION = 1;
|
|
1799
1981
|
var HEARTBEAT_MS = 15e3;
|
|
1800
|
-
var setStateBodySchema =
|
|
1801
|
-
state:
|
|
1802
|
-
causedBy:
|
|
1982
|
+
var setStateBodySchema = z2.object({
|
|
1983
|
+
state: z2.record(z2.unknown()),
|
|
1984
|
+
causedBy: z2.enum(["user", "agent", "restore"]).optional()
|
|
1803
1985
|
});
|
|
1804
|
-
var postCommandBodySchema =
|
|
1805
|
-
kind:
|
|
1806
|
-
params:
|
|
1986
|
+
var postCommandBodySchema = z2.object({
|
|
1987
|
+
kind: z2.string().min(1),
|
|
1988
|
+
params: z2.record(z2.unknown()).default({})
|
|
1807
1989
|
});
|
|
1808
|
-
function
|
|
1990
|
+
function createBodyValidator2(schema) {
|
|
1809
1991
|
return async function validateBody(request, reply) {
|
|
1810
1992
|
const parsed = schema.safeParse(request.body);
|
|
1811
1993
|
if (!parsed.success) {
|
|
@@ -1823,8 +2005,13 @@ function createBodyValidator(schema) {
|
|
|
1823
2005
|
}
|
|
1824
2006
|
function uiRoutes(app, opts, done) {
|
|
1825
2007
|
const fallbackBridge = opts.bridge;
|
|
1826
|
-
const
|
|
1827
|
-
const
|
|
2008
|
+
const paneStatusStore = opts.paneStatusStore ?? createPaneRenderStatusStore();
|
|
2009
|
+
const getPaneWorkspaceId = async (request) => await opts.getWorkspaceId?.(request) ?? resolvePaneStatusWorkspaceId(request);
|
|
2010
|
+
const touchUi = async (request) => {
|
|
2011
|
+
paneStatusStore.touchUi(await getPaneWorkspaceId(request));
|
|
2012
|
+
};
|
|
2013
|
+
const validateSetState = createBodyValidator2(setStateBodySchema);
|
|
2014
|
+
const validatePostCommand = createBodyValidator2(postCommandBodySchema);
|
|
1828
2015
|
const resolveBridge = async (request) => {
|
|
1829
2016
|
if (opts.getBridge) return await opts.getBridge(request);
|
|
1830
2017
|
if (fallbackBridge) return fallbackBridge;
|
|
@@ -1836,7 +2023,10 @@ function uiRoutes(app, opts, done) {
|
|
|
1836
2023
|
kind: cmd.kind,
|
|
1837
2024
|
params: cmd.params
|
|
1838
2025
|
});
|
|
2026
|
+
paneRenderStatusRoutes(app, { store: paneStatusStore, getWorkspaceId: getPaneWorkspaceId }, () => {
|
|
2027
|
+
});
|
|
1839
2028
|
app.get("/api/v1/ui/state", async (request) => {
|
|
2029
|
+
await touchUi(request);
|
|
1840
2030
|
const bridge = await resolveBridge(request);
|
|
1841
2031
|
return await bridge.getState() ?? {};
|
|
1842
2032
|
});
|
|
@@ -1844,6 +2034,7 @@ function uiRoutes(app, opts, done) {
|
|
|
1844
2034
|
"/api/v1/ui/state",
|
|
1845
2035
|
{ preHandler: validateSetState },
|
|
1846
2036
|
async (request, reply) => {
|
|
2037
|
+
await touchUi(request);
|
|
1847
2038
|
const body = request.body;
|
|
1848
2039
|
const bridge = await resolveBridge(request);
|
|
1849
2040
|
const current = await bridge.getState() ?? {};
|
|
@@ -1865,6 +2056,7 @@ function uiRoutes(app, opts, done) {
|
|
|
1865
2056
|
}
|
|
1866
2057
|
);
|
|
1867
2058
|
app.get("/api/v1/ui/commands/next", async (request, reply) => {
|
|
2059
|
+
await touchUi(request);
|
|
1868
2060
|
const bridge = await resolveBridge(request);
|
|
1869
2061
|
const query = request.query;
|
|
1870
2062
|
if (query.poll === "true") {
|
|
@@ -1894,13 +2086,20 @@ data: ${JSON.stringify(encodeCommand(cmd))}
|
|
|
1894
2086
|
}
|
|
1895
2087
|
}
|
|
1896
2088
|
const unsub = bridge.subscribeCommands((cmd) => {
|
|
1897
|
-
reply.raw.
|
|
2089
|
+
if (reply.raw.destroyed || reply.raw.writableEnded) return false;
|
|
2090
|
+
try {
|
|
2091
|
+
reply.raw.write(`event: command
|
|
1898
2092
|
data: ${JSON.stringify(encodeCommand(cmd))}
|
|
1899
2093
|
|
|
1900
2094
|
`);
|
|
2095
|
+
return true;
|
|
2096
|
+
} catch {
|
|
2097
|
+
return false;
|
|
2098
|
+
}
|
|
1901
2099
|
});
|
|
1902
2100
|
const heartbeat = setInterval(() => {
|
|
1903
2101
|
if (reply.raw.writableEnded) return;
|
|
2102
|
+
void touchUi(request);
|
|
1904
2103
|
reply.raw.write(
|
|
1905
2104
|
`event: heartbeat
|
|
1906
2105
|
data: ${JSON.stringify({ v: UI_BRIDGE_PROTOCOL_VERSION })}
|
|
@@ -1949,41 +2148,9 @@ function readPackageVersion(packageRoot) {
|
|
|
1949
2148
|
return void 0;
|
|
1950
2149
|
}
|
|
1951
2150
|
}
|
|
1952
|
-
function nodePackageContribution(contributionId, nodePackageId, packageName, packageRoot) {
|
|
1953
|
-
if (!packageRoot || !existsSync7(join7(packageRoot, "package.json"))) return null;
|
|
1954
|
-
return {
|
|
1955
|
-
id: contributionId,
|
|
1956
|
-
provisioning: {
|
|
1957
|
-
nodePackages: [{ id: nodePackageId, packageName, packageRoot }]
|
|
1958
|
-
}
|
|
1959
|
-
};
|
|
1960
|
-
}
|
|
1961
|
-
function publishedNodePackageContribution(contributionId, nodePackageId, packageName, version, expectedBins) {
|
|
1962
|
-
return {
|
|
1963
|
-
id: contributionId,
|
|
1964
|
-
provisioning: {
|
|
1965
|
-
nodePackages: [
|
|
1966
|
-
{
|
|
1967
|
-
id: nodePackageId,
|
|
1968
|
-
packageName,
|
|
1969
|
-
...version ? { version } : {},
|
|
1970
|
-
...expectedBins ? { expectedBins } : {}
|
|
1971
|
-
}
|
|
1972
|
-
]
|
|
1973
|
-
}
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
2151
|
function useLocalPackageProvisioning() {
|
|
1977
2152
|
return process.env.BORING_USE_LOCAL_PACKAGES === "1";
|
|
1978
2153
|
}
|
|
1979
|
-
function createWorkspacePackageProvisioningContribution() {
|
|
1980
|
-
return nodePackageContribution(
|
|
1981
|
-
"boring-workspace-package",
|
|
1982
|
-
"boring-workspace",
|
|
1983
|
-
"@hachej/boring-workspace",
|
|
1984
|
-
resolveWorkspacePackageRoot()
|
|
1985
|
-
);
|
|
1986
|
-
}
|
|
1987
2154
|
function resolveBoringPiPackageRoot() {
|
|
1988
2155
|
const workspacePackageRoot = resolveWorkspacePackageRoot();
|
|
1989
2156
|
const candidates = [
|
|
@@ -2003,45 +2170,48 @@ function resolveBoringPiPackageRoot() {
|
|
|
2003
2170
|
return null;
|
|
2004
2171
|
}
|
|
2005
2172
|
}
|
|
2006
|
-
function
|
|
2007
|
-
|
|
2173
|
+
function isUsableBoringUiPluginCliPackageRoot(candidate) {
|
|
2174
|
+
try {
|
|
2175
|
+
const pkg = JSON.parse(readFileSync6(join7(candidate, "package.json"), "utf8"));
|
|
2176
|
+
return pkg.name === "@hachej/boring-ui-plugin-cli" && existsSync7(join7(candidate, "dist", "bin.js"));
|
|
2177
|
+
} catch {
|
|
2178
|
+
return false;
|
|
2179
|
+
}
|
|
2008
2180
|
}
|
|
2009
|
-
function
|
|
2181
|
+
function resolveBoringUiPluginCliPackageRoot() {
|
|
2010
2182
|
const workspacePackageRoot = resolveWorkspacePackageRoot();
|
|
2011
2183
|
const candidates = [
|
|
2012
|
-
join7(workspacePackageRoot, "..", "cli"),
|
|
2013
|
-
join7(workspacePackageRoot, "node_modules", "@hachej", "boring-ui-cli")
|
|
2184
|
+
join7(workspacePackageRoot, "..", "plugin-cli"),
|
|
2185
|
+
join7(workspacePackageRoot, "node_modules", "@hachej", "boring-ui-plugin-cli")
|
|
2014
2186
|
];
|
|
2015
2187
|
for (const candidate of candidates) {
|
|
2016
|
-
|
|
2017
|
-
const pkg = JSON.parse(readFileSync6(join7(candidate, "package.json"), "utf8"));
|
|
2018
|
-
if (pkg.name === "@hachej/boring-ui-cli") return candidate;
|
|
2019
|
-
} catch {
|
|
2020
|
-
}
|
|
2188
|
+
if (isUsableBoringUiPluginCliPackageRoot(candidate)) return candidate;
|
|
2021
2189
|
}
|
|
2022
2190
|
try {
|
|
2023
|
-
|
|
2191
|
+
const resolved = dirname7(require4.resolve("@hachej/boring-ui-plugin-cli/package.json"));
|
|
2192
|
+
return isUsableBoringUiPluginCliPackageRoot(resolved) ? resolved : null;
|
|
2024
2193
|
} catch {
|
|
2025
2194
|
return null;
|
|
2026
2195
|
}
|
|
2027
2196
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2197
|
+
var PLUGIN_AUTHORING_PROVISIONING_IDS = /* @__PURE__ */ new Set(["boring-ui-plugin-cli-package"]);
|
|
2198
|
+
function omitPluginAuthoringProvisioning(plugins) {
|
|
2199
|
+
return plugins.filter((plugin) => !PLUGIN_AUTHORING_PROVISIONING_IDS.has(plugin.id));
|
|
2200
|
+
}
|
|
2201
|
+
function createBoringUiPluginCliPackageProvisioningContribution() {
|
|
2202
|
+
const packageRoot = useLocalPackageProvisioning() ? resolveBoringUiPluginCliPackageRoot() : null;
|
|
2203
|
+
const version = readPackageVersion(resolveWorkspacePackageRoot());
|
|
2204
|
+
return {
|
|
2205
|
+
id: "boring-ui-plugin-cli-package",
|
|
2206
|
+
provisioning: {
|
|
2207
|
+
nodePackages: [{
|
|
2208
|
+
id: "boring-ui-plugin-cli",
|
|
2209
|
+
packageName: "@hachej/boring-ui-plugin-cli",
|
|
2210
|
+
...packageRoot ? { packageRoot } : { version },
|
|
2211
|
+
expectedBins: ["boring-ui-plugin"]
|
|
2212
|
+
}]
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2045
2215
|
}
|
|
2046
2216
|
function createBoringPiPackageSource(workspaceRoot) {
|
|
2047
2217
|
const workspacePackageRoot = join7(workspaceRoot, "node_modules", "@hachej", "boring-pi");
|
|
@@ -2062,7 +2232,7 @@ function buildWorkspaceContextPrompt() {
|
|
|
2062
2232
|
"- Root: `$BORING_AGENT_WORKSPACE_ROOT` (exported into every bash invocation)",
|
|
2063
2233
|
"- Generated plugin skills: `$BORING_AGENT_WORKSPACE_ROOT/.boring-agent/skills/` \u2014 readable with normal file tools",
|
|
2064
2234
|
"- User workspace skills: `$BORING_AGENT_WORKSPACE_ROOT/.agents/skills/`",
|
|
2065
|
-
"- Runtime CLIs (`boring-ui`, `bm`, `python`, `pip`, `uv`) come from `.boring-agent/node`, `.boring-agent/venv`, and `.boring-agent/sdk/uv` and are already on PATH"
|
|
2235
|
+
"- Runtime CLIs (`boring-ui-plugin`, `bm`, `python`, `pip`, `uv`) come from `.boring-agent/node`, `.boring-agent/venv`, and `.boring-agent/sdk/uv` and are already on PATH"
|
|
2066
2236
|
].join("\n");
|
|
2067
2237
|
}
|
|
2068
2238
|
function collectWorkspaceAgentServerPlugins(opts = {}) {
|
|
@@ -2076,11 +2246,8 @@ function collectWorkspaceAgentServerPlugins(opts = {}) {
|
|
|
2076
2246
|
const callerAdditional = opts.pi?.additionalSkillPaths ?? [];
|
|
2077
2247
|
const callerPiPackages = opts.pi?.packages ?? [];
|
|
2078
2248
|
const callerExtensionPaths = opts.pi?.extensionPaths ?? [];
|
|
2079
|
-
const
|
|
2080
|
-
|
|
2081
|
-
createBoringPiPackageProvisioningContribution(),
|
|
2082
|
-
createBoringUiCliPackageProvisioningContribution()
|
|
2083
|
-
].filter((entry) => Boolean(entry));
|
|
2249
|
+
const excludedDefaults = new Set(opts.excludeDefaults ?? []);
|
|
2250
|
+
const builtinProvisioningContributions = (opts.installPluginAuthoring === false ? [] : [createBoringUiPluginCliPackageProvisioningContribution()]).filter((entry) => Boolean(entry)).filter((entry) => !excludedDefaults.has(entry.id));
|
|
2084
2251
|
return {
|
|
2085
2252
|
provisioningContributions: [
|
|
2086
2253
|
...builtinProvisioningContributions,
|
|
@@ -2226,13 +2393,15 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2226
2393
|
const resolvedPlugins = await Promise.all(
|
|
2227
2394
|
allPluginEntries.map((entry) => resolveOnePluginEntry(entry, ctx))
|
|
2228
2395
|
);
|
|
2396
|
+
const pluginAuthoringEnabled = (opts.installPluginAuthoring ?? workspaceFsCapability === "strong") && !(opts.excludeDefaults ?? []).includes("boring-ui-plugin-cli-package");
|
|
2229
2397
|
const pluginCollection = collectWorkspaceAgentServerPlugins({
|
|
2230
2398
|
...opts,
|
|
2231
|
-
plugins: resolvedPlugins
|
|
2399
|
+
plugins: resolvedPlugins,
|
|
2400
|
+
installPluginAuthoring: pluginAuthoringEnabled
|
|
2232
2401
|
});
|
|
2233
|
-
const workspacePackagePiPackage = createBoringPiPackageSource(workspaceRoot);
|
|
2402
|
+
const workspacePackagePiPackage = pluginAuthoringEnabled ? createBoringPiPackageSource(workspaceRoot) : void 0;
|
|
2234
2403
|
const baseStaticPiSkillPaths = [
|
|
2235
|
-
...resolveBoringPiSkillPaths(workspaceRoot),
|
|
2404
|
+
...pluginAuthoringEnabled ? resolveBoringPiSkillPaths(workspaceRoot) : [],
|
|
2236
2405
|
...pluginCollection.agentOptions.pi?.additionalSkillPaths ?? []
|
|
2237
2406
|
];
|
|
2238
2407
|
const baseStaticPiPackages = [
|
|
@@ -2264,10 +2433,14 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2264
2433
|
frontTargetResolver: opts.boringPluginFrontTargetResolver,
|
|
2265
2434
|
includeLegacyFrontUrl: opts.boringPluginIncludeLegacyFrontUrl
|
|
2266
2435
|
});
|
|
2267
|
-
const buildRuntimeProvisioningInputs = () =>
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2436
|
+
const buildRuntimeProvisioningInputs = () => {
|
|
2437
|
+
const inputs = mergeRuntimeProvisioningInputs([
|
|
2438
|
+
...pluginCollection.runtimePlugins,
|
|
2439
|
+
...readWorkspacePluginPackageRuntimePlugins(boringPluginDirs)
|
|
2440
|
+
]);
|
|
2441
|
+
if (resolvedMode === "direct") return omitPluginAuthoringProvisioning(inputs);
|
|
2442
|
+
return inputs;
|
|
2443
|
+
};
|
|
2271
2444
|
let currentRuntimeProvisioning = opts.runtimeProvisioning;
|
|
2272
2445
|
const runtimeWorkspaceRoot = resolvedMode === "vercel-sandbox" ? VERCEL_SANDBOX_WORKSPACE_ROOT : workspaceRoot;
|
|
2273
2446
|
const runtimeLayout = getBoringAgentRuntimePaths(runtimeWorkspaceRoot);
|
|
@@ -2307,20 +2480,18 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2307
2480
|
],
|
|
2308
2481
|
systemPromptAppend: [
|
|
2309
2482
|
workspaceFsCapability === "strong" ? buildWorkspaceContextPrompt() : void 0,
|
|
2310
|
-
// `boring-ui` resolves via PATH
|
|
2311
|
-
//
|
|
2312
|
-
//
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
scaffoldCommand: "boring-ui scaffold-plugin",
|
|
2317
|
-
verifyCommand: "boring-ui verify-plugin",
|
|
2483
|
+
// `boring-ui-plugin` resolves via PATH from the provisioned workspace
|
|
2484
|
+
// runtime. It is the slim setup component for agent-authored plugins;
|
|
2485
|
+
// do not route plugin authoring through the full human-facing CLI.
|
|
2486
|
+
pluginAuthoringEnabled ? buildBoringSystemPrompt({
|
|
2487
|
+
scaffoldCommand: "boring-ui-plugin scaffold",
|
|
2488
|
+
verifyCommand: "boring-ui-plugin verify",
|
|
2318
2489
|
boringPiRootOverride: boringPiRootVisibleToAgentTools(
|
|
2319
2490
|
workspaceRoot,
|
|
2320
2491
|
resolvedMode,
|
|
2321
2492
|
opts.provisionWorkspace !== false
|
|
2322
2493
|
)
|
|
2323
|
-
}),
|
|
2494
|
+
}) : void 0,
|
|
2324
2495
|
pluginCollection.agentOptions.systemPromptAppend,
|
|
2325
2496
|
staticPluginPackagePiSnapshot.systemPromptAppend
|
|
2326
2497
|
].filter(Boolean).join("\n\n") || void 0,
|
|
@@ -2378,10 +2549,12 @@ async function createWorkspaceAgentServer(opts = {}) {
|
|
|
2378
2549
|
return app;
|
|
2379
2550
|
}
|
|
2380
2551
|
export {
|
|
2552
|
+
PLUGIN_AUTHORING_PROVISIONING_IDS,
|
|
2381
2553
|
buildWorkspaceContextPrompt,
|
|
2382
2554
|
collectWorkspaceAgentServerPlugins,
|
|
2383
2555
|
createWorkspaceAgentServer,
|
|
2384
2556
|
hasDirServerPlugin,
|
|
2557
|
+
omitPluginAuthoringProvisioning,
|
|
2385
2558
|
provisionWorkspaceAgentServer,
|
|
2386
2559
|
readWorkspacePluginPackagePiSnapshot,
|
|
2387
2560
|
readWorkspacePluginPackageRuntimePlugins,
|