@hachej/boring-workspace 0.1.20 → 0.1.23

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/app-front.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsx as d, jsxs as xe, Fragment as $ } from "react/jsx-runtime";
2
2
  import { useSyncExternalStore as qe, useMemo as P, useCallback as v, useRef as K, useState as re, useEffect as y } from "react";
3
3
  import { ChatPanel as et, useSessions as tt } from "@hachej/boring-agent/front";
4
- import { ak as st, U as We, o as rt, al as nt, u as ot, am as at } from "./WorkspaceProvider-CDPaAO5u.js";
5
- import { T as ct, C as it, r as Le, w as lt, W as Re } from "./WorkspaceLoadingState-DYDxUYnx.js";
4
+ import { ak as st, U as We, o as rt, al as nt, u as ot, am as at } from "./WorkspaceProvider-Cn0sPgaB.js";
5
+ import { T as ct, C as it, r as Le, w as lt, W as Re } from "./WorkspaceLoadingState-hKrnYCL3.js";
6
6
  function ut() {
7
7
  const e = `s${Date.now()}`;
8
8
  return {
@@ -1,8 +1,9 @@
1
- import { PiPackageSource, PiExtensionFactory, CreateAgentAppOptions } from '@hachej/boring-agent/server';
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, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, c as createInMemoryBridge } from './createInMemoryBridge-BDxDzihm.js';
5
- import './ui-bridge-Gfh1MMgl.js';
4
+ import { W as WorkspaceServerPlugin, S as ServerBootstrapOptions, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, c as createInMemoryBridge } from './createInMemoryBridge-CYNW1h_o.js';
5
+ export { d as ServerWorkspaceRuntimeProvisioningInput } from './createInMemoryBridge-CYNW1h_o.js';
6
+ import './ui-bridge-CT18yqwN.js';
6
7
 
7
8
  /**
8
9
  * Directory-source entry: `{ dir, options?, hotReload? }`. Resolved via
@@ -132,6 +133,7 @@ interface CreateWorkspaceAgentServerOptions extends WorkspaceAgentCreateOptions,
132
133
  }
133
134
  interface WorkspaceAgentServerPluginCollection {
134
135
  provisioningContributions: WorkspaceProvisioningContribution[];
136
+ runtimePlugins: WorkspaceRuntimeProvisioningInput[];
135
137
  routeContributions: WorkspaceRouteContribution[];
136
138
  preservedUiStateKeys: string[];
137
139
  agentOptions: Pick<WorkspaceAgentCreateOptions, "extraTools" | "systemPromptAppend" | "pi">;
@@ -154,6 +156,8 @@ interface WorkspacePluginPackagePiSnapshot {
154
156
  extensionPaths: string[];
155
157
  systemPromptAppend?: string;
156
158
  }
159
+ type WorkspaceRuntimeProvisioningInput = ProvisionWorkspaceRuntimeOptions["plugins"][number];
160
+ declare function readWorkspacePluginPackageRuntimePlugins(pluginDirs: string[]): WorkspaceRuntimeProvisioningInput[];
157
161
  declare function readWorkspacePluginPackagePiSnapshot(pluginDirs: string[]): WorkspacePluginPackagePiSnapshot;
158
162
  declare function createWorkspaceAgentServer(opts?: CreateWorkspaceAgentServerOptions): Promise<FastifyInstance>;
159
163
 
@@ -170,4 +174,4 @@ interface ResolveDefaultWorkspacePluginPackagePathsOptions {
170
174
  */
171
175
  declare function resolveDefaultWorkspacePluginPackagePaths({ workspaceRoot, defaultPluginPackages, appPackageJsonPath, }?: ResolveDefaultWorkspacePluginPackagePathsOptions): string[];
172
176
 
173
- export { type CollectWorkspaceAgentServerPluginsOptions, type CreateWorkspaceAgentServerOptions, type DirPluginEntry, type PluginResolveContext, type ResolveDefaultWorkspacePluginPackagePathsOptions, type WorkspaceAgentPiOptions, type WorkspaceAgentServerPluginCollection, type WorkspaceAgentServerPluginContext, type WorkspacePluginEntry, type WorkspacePluginPackagePiSnapshot, WorkspaceProvisioningContribution, WorkspaceRouteContribution, buildWorkspaceContextPrompt, collectWorkspaceAgentServerPlugins, createWorkspaceAgentServer, hasDirServerPlugin, provisionWorkspaceAgentServer, readWorkspacePluginPackagePiSnapshot, resolveDefaultWorkspacePluginPackagePaths, resolveOnePluginEntry };
177
+ 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 };
@@ -2,8 +2,11 @@
2
2
  import {
3
3
  autoDetectMode,
4
4
  createAgentApp,
5
+ getBoringAgentRuntimePaths,
5
6
  provisionRuntimeWorkspace,
6
- resolveMode
7
+ provisionWorkspaceRuntime,
8
+ resolveMode,
9
+ VERCEL_SANDBOX_WORKSPACE_ROOT
7
10
  } from "@hachej/boring-agent/server";
8
11
  import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
9
12
  import { dirname as dirname7, join as join7 } from "path";
@@ -985,6 +988,20 @@ function validatePiPackages2(pluginId, piPackages) {
985
988
  }
986
989
  }
987
990
  }
991
+ function validateSkills(pluginId, skills) {
992
+ for (let i = 0; i < skills.length; i++) {
993
+ const skill = skills[i];
994
+ if (!skill || typeof skill !== "object") {
995
+ fail(pluginId, `skills[${i}] must be an object`);
996
+ }
997
+ if (!skill.name || typeof skill.name !== "string") {
998
+ fail(pluginId, `skills[${i}].name must be a non-empty string`);
999
+ }
1000
+ if (!isPathLike(skill.source)) {
1001
+ fail(pluginId, `skills[${i}].source must be a string or URL`);
1002
+ }
1003
+ }
1004
+ }
988
1005
  function validateProvisioning(pluginId, provisioning) {
989
1006
  if (!provisioning || typeof provisioning !== "object") {
990
1007
  fail(pluginId, "provisioning must be an object");
@@ -1024,7 +1041,7 @@ function validateProvisioning(pluginId, provisioning) {
1024
1041
  if (!spec.packageName || typeof spec.packageName !== "string") {
1025
1042
  fail(pluginId, `provisioning.nodePackages[${i}].packageName must be a non-empty string`);
1026
1043
  }
1027
- if (!isPathLike(spec.packageRoot)) {
1044
+ if (spec.packageRoot !== void 0 && !isPathLike(spec.packageRoot)) {
1028
1045
  fail(pluginId, `provisioning.nodePackages[${i}].packageRoot must be a string or URL`);
1029
1046
  }
1030
1047
  }
@@ -1086,6 +1103,12 @@ function validateServerPlugin(plugin) {
1086
1103
  }
1087
1104
  });
1088
1105
  }
1106
+ if (plugin.skills !== void 0) {
1107
+ if (!Array.isArray(plugin.skills)) {
1108
+ fail(plugin.id, "skills must be an array when provided");
1109
+ }
1110
+ validateSkills(plugin.id, plugin.skills);
1111
+ }
1089
1112
  if (plugin.agentTools !== void 0) {
1090
1113
  if (!Array.isArray(plugin.agentTools)) {
1091
1114
  fail(plugin.id, "agentTools must be an array when provided");
@@ -1130,6 +1153,11 @@ function bootstrapServer(options) {
1130
1153
  const piPackages = compactPiPackages(finalPlugins.flatMap((plugin) => plugin.piPackages ?? []));
1131
1154
  const extensionPaths = finalPlugins.flatMap((p) => p.extensionPaths ?? []);
1132
1155
  const provisioningContributions = finalPlugins.filter((p) => p.provisioning).map((p) => ({ id: p.id, provisioning: p.provisioning }));
1156
+ const runtimePlugins = finalPlugins.map((plugin) => ({
1157
+ id: plugin.id,
1158
+ ...plugin.skills ? { skills: plugin.skills } : {},
1159
+ ...plugin.provisioning ? { provisioning: plugin.provisioning } : {}
1160
+ }));
1133
1161
  const routeContributions = finalPlugins.filter((p) => p.routes).map((p) => ({ id: p.id, routes: p.routes }));
1134
1162
  const preservedUiStateKeys = [...new Set(finalPlugins.flatMap((p) => p.preservedUiStateKeys ?? []))];
1135
1163
  return {
@@ -1138,6 +1166,7 @@ function bootstrapServer(options) {
1138
1166
  piPackages,
1139
1167
  extensionPaths,
1140
1168
  agentTools,
1169
+ runtimePlugins,
1141
1170
  provisioningContributions,
1142
1171
  routeContributions,
1143
1172
  preservedUiStateKeys
@@ -1885,8 +1914,9 @@ function buildWorkspaceContextPrompt() {
1885
1914
  return [
1886
1915
  "## Workspace",
1887
1916
  "- Root: `$BORING_AGENT_WORKSPACE_ROOT` (exported into every bash invocation)",
1888
- "- Skills: `$BORING_AGENT_WORKSPACE_ROOT/.agents/skills/`",
1889
- "- CLI shims (`bm`, `python`, `pip`): `$BORING_AGENT_WORKSPACE_ROOT/.boring-agent/bin/` \u2014 already on PATH, call directly"
1917
+ "- Generated plugin skills: `$BORING_AGENT_WORKSPACE_ROOT/.boring-agent/skills/` \u2014 readable with normal file tools",
1918
+ "- User workspace skills: `$BORING_AGENT_WORKSPACE_ROOT/.agents/skills/`",
1919
+ "- 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"
1890
1920
  ].join("\n");
1891
1921
  }
1892
1922
  function collectWorkspaceAgentServerPlugins(opts = {}) {
@@ -1900,13 +1930,20 @@ function collectWorkspaceAgentServerPlugins(opts = {}) {
1900
1930
  const callerAdditional = opts.pi?.additionalSkillPaths ?? [];
1901
1931
  const callerPiPackages = opts.pi?.packages ?? [];
1902
1932
  const callerExtensionPaths = opts.pi?.extensionPaths ?? [];
1933
+ const builtinProvisioningContributions = [
1934
+ createWorkspacePackageProvisioningContribution(),
1935
+ createBoringPiPackageProvisioningContribution(),
1936
+ createBoringUiCliPackageProvisioningContribution()
1937
+ ].filter((entry) => Boolean(entry));
1903
1938
  return {
1904
1939
  provisioningContributions: [
1905
- createWorkspacePackageProvisioningContribution(),
1906
- createBoringPiPackageProvisioningContribution(),
1907
- createBoringUiCliPackageProvisioningContribution(),
1940
+ ...builtinProvisioningContributions,
1908
1941
  ...result.provisioningContributions
1909
- ].filter((entry) => Boolean(entry)),
1942
+ ],
1943
+ runtimePlugins: [
1944
+ ...builtinProvisioningContributions,
1945
+ ...result.runtimePlugins
1946
+ ],
1910
1947
  routeContributions: result.routeContributions,
1911
1948
  preservedUiStateKeys: result.preservedUiStateKeys,
1912
1949
  agentOptions: {
@@ -1947,9 +1984,42 @@ function collectBoringPluginDirs(workspaceRoot, pluginCollection) {
1947
1984
  ...pluginRoots
1948
1985
  ];
1949
1986
  }
1987
+ function mergeRuntimeProvisioningInputs(plugins) {
1988
+ const byId = /* @__PURE__ */ new Map();
1989
+ for (const plugin of plugins) {
1990
+ const current = byId.get(plugin.id) ?? { id: plugin.id };
1991
+ byId.set(plugin.id, {
1992
+ id: plugin.id,
1993
+ skills: [...current.skills ?? [], ...plugin.skills ?? []],
1994
+ provisioning: {
1995
+ templateDirs: [...current.provisioning?.templateDirs ?? [], ...plugin.provisioning?.templateDirs ?? []],
1996
+ python: [...current.provisioning?.python ?? [], ...plugin.provisioning?.python ?? []],
1997
+ nodePackages: [...current.provisioning?.nodePackages ?? [], ...plugin.provisioning?.nodePackages ?? []]
1998
+ }
1999
+ });
2000
+ }
2001
+ return [...byId.values()];
2002
+ }
1950
2003
  function emptyPackageJsonPiSnapshot() {
1951
2004
  return { additionalSkillPaths: [], packages: [], extensionPaths: [] };
1952
2005
  }
2006
+ function skillNameFromResolvedPath(path) {
2007
+ const leaf = path.split(/[\\/]/).filter(Boolean).at(-1) ?? "skill";
2008
+ if (leaf.toLowerCase() !== "skill.md") return leaf;
2009
+ return path.split(/[\\/]/).filter(Boolean).at(-2) ?? "skill";
2010
+ }
2011
+ function readWorkspacePluginPackageRuntimePlugins(pluginDirs) {
2012
+ const scan = scanBoringPlugins(pluginDirs);
2013
+ return scan.plugins.map((plugin) => ({
2014
+ id: plugin.id,
2015
+ ...plugin.skillPaths?.length ? {
2016
+ skills: plugin.skillPaths.map((source) => ({
2017
+ name: skillNameFromResolvedPath(source),
2018
+ source
2019
+ }))
2020
+ } : {}
2021
+ }));
2022
+ }
1953
2023
  function aggregatePluginSystemPromptsFromScan(scan) {
1954
2024
  const prompts = scan.plugins.map((plugin) => plugin.pi?.systemPrompt?.trim()).filter((prompt) => Boolean(prompt));
1955
2025
  if (prompts.length === 0) return void 0;
@@ -1980,7 +2050,8 @@ async function createWorkspaceAgentServer(opts = {}) {
1980
2050
  const workspaceRoot = opts.workspaceRoot ?? process.cwd();
1981
2051
  const bridge = createInMemoryBridge();
1982
2052
  const resolvedMode = opts.runtimeModeAdapter?.id ?? opts.mode ?? autoDetectMode();
1983
- const workspaceFsCapability = opts.runtimeModeAdapter ? opts.runtimeModeAdapter.workspaceFsCapability ?? "best-effort" : resolveMode(resolvedMode).workspaceFsCapability ?? "best-effort";
2053
+ const modeAdapter = opts.runtimeModeAdapter ?? resolveMode(resolvedMode);
2054
+ const workspaceFsCapability = modeAdapter.workspaceFsCapability ?? "best-effort";
1984
2055
  const validateUiPaths = opts.validateUiPaths ?? workspaceFsCapability === "strong";
1985
2056
  const uiTools = createWorkspaceUiTools(bridge, {
1986
2057
  workspaceRoot: validateUiPaths ? workspaceRoot : void 0
@@ -2004,13 +2075,6 @@ async function createWorkspaceAgentServer(opts = {}) {
2004
2075
  ...opts,
2005
2076
  plugins: resolvedPlugins
2006
2077
  });
2007
- if (opts.provisionWorkspace !== false) {
2008
- await provisionWorkspaceAgentServer({
2009
- workspaceRoot,
2010
- provisioningContributions: pluginCollection.provisioningContributions,
2011
- force: opts.workspaceProvisioning?.force
2012
- });
2013
- }
2014
2078
  const workspacePackagePiPackage = createBoringPiPackageSource(workspaceRoot);
2015
2079
  const baseStaticPiSkillPaths = [
2016
2080
  ...resolveBoringPiSkillPaths(workspaceRoot),
@@ -2043,6 +2107,28 @@ async function createWorkspaceAgentServer(opts = {}) {
2043
2107
  pluginDirs: boringPluginDirs,
2044
2108
  errorRoot: join7(workspaceRoot, ".pi", "extensions")
2045
2109
  });
2110
+ const buildRuntimeProvisioningInputs = () => mergeRuntimeProvisioningInputs([
2111
+ ...pluginCollection.runtimePlugins,
2112
+ ...readWorkspacePluginPackageRuntimePlugins(boringPluginDirs)
2113
+ ]);
2114
+ let currentRuntimeProvisioning = opts.runtimeProvisioning;
2115
+ const runtimeWorkspaceRoot = resolvedMode === "vercel-sandbox" ? VERCEL_SANDBOX_WORKSPACE_ROOT : workspaceRoot;
2116
+ const runtimeLayout = getBoringAgentRuntimePaths(runtimeWorkspaceRoot);
2117
+ const runRuntimeProvisioning = async () => {
2118
+ if (opts.provisionWorkspace === false) return currentRuntimeProvisioning;
2119
+ const adapter = modeAdapter.createProvisioningAdapter?.(runtimeLayout, {
2120
+ workspaceRoot,
2121
+ sessionId: opts.sessionId ?? "default"
2122
+ });
2123
+ if (!adapter) return currentRuntimeProvisioning;
2124
+ currentRuntimeProvisioning = await provisionWorkspaceRuntime({
2125
+ plugins: buildRuntimeProvisioningInputs(),
2126
+ adapter,
2127
+ runtimeLayout
2128
+ });
2129
+ return currentRuntimeProvisioning;
2130
+ };
2131
+ await runRuntimeProvisioning();
2046
2132
  const rebuildPlugins = async () => {
2047
2133
  return rebuildServerPlugins({ entries: allPluginEntries, ctx });
2048
2134
  };
@@ -2088,6 +2174,7 @@ async function createWorkspaceAgentServer(opts = {}) {
2088
2174
  const rebuild = await rebuildPlugins();
2089
2175
  diagnostics = [...scanDiagnostics, ...rebuild.diagnostics];
2090
2176
  }
2177
+ await runRuntimeProvisioning();
2091
2178
  const callerResult = await opts.beforeReload?.();
2092
2179
  const callerRestartWarnings = callerResult && typeof callerResult === "object" ? callerResult.restart_warnings ?? [] : [];
2093
2180
  const callerDiagnostics = callerResult && typeof callerResult === "object" ? callerResult.diagnostics ?? [] : [];
@@ -2099,6 +2186,8 @@ async function createWorkspaceAgentServer(opts = {}) {
2099
2186
  ...mergedDiagnostics.length > 0 ? { diagnostics: mergedDiagnostics } : {}
2100
2187
  };
2101
2188
  },
2189
+ runtimeProvisioning: currentRuntimeProvisioning,
2190
+ getRuntimeProvisioning: () => currentRuntimeProvisioning,
2102
2191
  pi: {
2103
2192
  ...pluginCollection.agentOptions.pi,
2104
2193
  additionalSkillPaths: staticPiSkillPaths,
@@ -2130,6 +2219,7 @@ export {
2130
2219
  hasDirServerPlugin,
2131
2220
  provisionWorkspaceAgentServer,
2132
2221
  readWorkspacePluginPackagePiSnapshot,
2222
+ readWorkspacePluginPackageRuntimePlugins,
2133
2223
  resolveDefaultWorkspacePluginPackagePaths,
2134
2224
  resolveOnePluginEntry
2135
2225
  };
@@ -1,7 +1,8 @@
1
- import { PiPackageSource, RuntimeProvisioningContribution } from '@hachej/boring-agent/server';
1
+ import { PiPackageSource, PluginSkillSource, ProvisionWorkspaceRuntimeOptions } from '@hachej/boring-agent/server';
2
2
  import { FastifyPluginAsync } from 'fastify';
3
- import { A as AgentTool, U as UiBridge } from './ui-bridge-Gfh1MMgl.js';
3
+ import { A as AgentTool, U as UiBridge } from './ui-bridge-CT18yqwN.js';
4
4
 
5
+ type WorkspaceRuntimeProvisioning = NonNullable<ProvisionWorkspaceRuntimeOptions["plugins"][number]["provisioning"]>;
5
6
  interface WorkspaceServerPlugin {
6
7
  id: string;
7
8
  label?: string;
@@ -18,8 +19,9 @@ interface WorkspaceServerPlugin {
18
19
  */
19
20
  extensionPaths?: string[];
20
21
  systemPrompt?: string;
22
+ skills?: PluginSkillSource[];
21
23
  agentTools?: AgentTool[];
22
- provisioning?: RuntimeProvisioningContribution;
24
+ provisioning?: WorkspaceRuntimeProvisioning;
23
25
  routes?: FastifyPluginAsync;
24
26
  /** UI state keys owned by this plugin that browser state PUTs must not overwrite. */
25
27
  preservedUiStateKeys?: string[];
@@ -32,9 +34,10 @@ interface ServerBootstrapOptions {
32
34
  defaults?: WorkspaceServerPlugin[];
33
35
  excludeDefaults?: string[];
34
36
  }
37
+ type WorkspaceRuntimeProvisioningInput = ProvisionWorkspaceRuntimeOptions["plugins"][number];
35
38
  type WorkspaceProvisioningContribution = {
36
39
  id: string;
37
- provisioning: RuntimeProvisioningContribution;
40
+ provisioning: NonNullable<WorkspaceRuntimeProvisioningInput["provisioning"]>;
38
41
  };
39
42
  type WorkspaceRouteContribution = {
40
43
  id: string;
@@ -46,6 +49,7 @@ interface ServerBootstrapResult {
46
49
  piPackages: PiPackageSource[];
47
50
  extensionPaths: string[];
48
51
  agentTools: AgentTool[];
52
+ runtimePlugins: WorkspaceRuntimeProvisioningInput[];
49
53
  provisioningContributions: WorkspaceProvisioningContribution[];
50
54
  routeContributions: WorkspaceRouteContribution[];
51
55
  preservedUiStateKeys: string[];
@@ -54,4 +58,4 @@ declare function bootstrapServer(options: ServerBootstrapOptions): ServerBootstr
54
58
 
55
59
  declare function createInMemoryBridge(): UiBridge;
56
60
 
57
- export { type ServerBootstrapOptions as S, type WorkspaceServerPlugin as W, type WorkspaceProvisioningContribution as a, type WorkspaceRouteContribution as b, createInMemoryBridge as c, type ServerBootstrapResult as d, bootstrapServer as e, defineServerPlugin as f, validateServerPlugin as v };
61
+ export { type ServerBootstrapOptions as S, type WorkspaceServerPlugin as W, type WorkspaceProvisioningContribution as a, type WorkspaceRouteContribution as b, createInMemoryBridge as c, type WorkspaceRuntimeProvisioningInput as d, type ServerBootstrapResult as e, bootstrapServer as f, defineServerPlugin as g, validateServerPlugin as v };
package/dist/server.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { S as ServerBootstrapOptions, d as ServerBootstrapResult, a as WorkspaceProvisioningContribution, b as WorkspaceRouteContribution, W as WorkspaceServerPlugin, e as bootstrapServer, c as createInMemoryBridge, f as defineServerPlugin, v as validateServerPlugin } from './createInMemoryBridge-BDxDzihm.js';
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';
2
2
  import { FastifyRequest, FastifyInstance } from 'fastify';
3
- import { U as UiBridge, A as AgentTool } from './ui-bridge-Gfh1MMgl.js';
4
- export { C as CommandResult, b as UiCommand, c as UiState } from './ui-bridge-Gfh1MMgl.js';
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
5
  import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-CyNNdfYz.js';
6
6
  export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
7
7
 
package/dist/server.js CHANGED
@@ -516,6 +516,20 @@ function validatePiPackages(pluginId, piPackages) {
516
516
  }
517
517
  }
518
518
  }
519
+ function validateSkills(pluginId, skills) {
520
+ for (let i = 0; i < skills.length; i++) {
521
+ const skill = skills[i];
522
+ if (!skill || typeof skill !== "object") {
523
+ fail(pluginId, `skills[${i}] must be an object`);
524
+ }
525
+ if (!skill.name || typeof skill.name !== "string") {
526
+ fail(pluginId, `skills[${i}].name must be a non-empty string`);
527
+ }
528
+ if (!isPathLike(skill.source)) {
529
+ fail(pluginId, `skills[${i}].source must be a string or URL`);
530
+ }
531
+ }
532
+ }
519
533
  function validateProvisioning(pluginId, provisioning) {
520
534
  if (!provisioning || typeof provisioning !== "object") {
521
535
  fail(pluginId, "provisioning must be an object");
@@ -555,7 +569,7 @@ function validateProvisioning(pluginId, provisioning) {
555
569
  if (!spec.packageName || typeof spec.packageName !== "string") {
556
570
  fail(pluginId, `provisioning.nodePackages[${i}].packageName must be a non-empty string`);
557
571
  }
558
- if (!isPathLike(spec.packageRoot)) {
572
+ if (spec.packageRoot !== void 0 && !isPathLike(spec.packageRoot)) {
559
573
  fail(pluginId, `provisioning.nodePackages[${i}].packageRoot must be a string or URL`);
560
574
  }
561
575
  }
@@ -617,6 +631,12 @@ function validateServerPlugin(plugin) {
617
631
  }
618
632
  });
619
633
  }
634
+ if (plugin.skills !== void 0) {
635
+ if (!Array.isArray(plugin.skills)) {
636
+ fail(plugin.id, "skills must be an array when provided");
637
+ }
638
+ validateSkills(plugin.id, plugin.skills);
639
+ }
620
640
  if (plugin.agentTools !== void 0) {
621
641
  if (!Array.isArray(plugin.agentTools)) {
622
642
  fail(plugin.id, "agentTools must be an array when provided");
@@ -665,6 +685,11 @@ function bootstrapServer(options) {
665
685
  const piPackages = compactPiPackages(finalPlugins.flatMap((plugin) => plugin.piPackages ?? []));
666
686
  const extensionPaths = finalPlugins.flatMap((p) => p.extensionPaths ?? []);
667
687
  const provisioningContributions = finalPlugins.filter((p) => p.provisioning).map((p) => ({ id: p.id, provisioning: p.provisioning }));
688
+ const runtimePlugins = finalPlugins.map((plugin) => ({
689
+ id: plugin.id,
690
+ ...plugin.skills ? { skills: plugin.skills } : {},
691
+ ...plugin.provisioning ? { provisioning: plugin.provisioning } : {}
692
+ }));
668
693
  const routeContributions = finalPlugins.filter((p) => p.routes).map((p) => ({ id: p.id, routes: p.routes }));
669
694
  const preservedUiStateKeys = [...new Set(finalPlugins.flatMap((p) => p.preservedUiStateKeys ?? []))];
670
695
  return {
@@ -673,6 +698,7 @@ function bootstrapServer(options) {
673
698
  piPackages,
674
699
  extensionPaths,
675
700
  agentTools,
701
+ runtimePlugins,
676
702
  provisioningContributions,
677
703
  routeContributions,
678
704
  preservedUiStateKeys
package/dist/shared.d.ts CHANGED
@@ -1,4 +1,18 @@
1
- export { A as AgentTool, C as CommandResult, J as JSONSchema, T as ToolExecContext, a as ToolResult, U as UiBridge, b as UiCommand, c as UiState } from './ui-bridge-Gfh1MMgl.js';
1
+ export { A as AgentTool, C as CommandResult, J as JSONSchema, T as ToolExecContext, c as ToolResult, U as UiBridge, a as UiCommand, b as UiState } from './ui-bridge-CT18yqwN.js';
2
2
  export { C as CommandConfig, P as PaneProps, a as PanelConfig, b as PanelRegistration, S as SurfaceOpenRequest, c as SurfacePanelResolution, d as SurfaceResolverConfig, e as SurfaceResolverRegistration, W as WORKSPACE_OPEN_PATH_SURFACE_KIND, f as definePanel } from './surface-COYagY2m.js';
3
3
  import 'react';
4
4
  import 'dockview-react';
5
+
6
+ interface TelemetrySink {
7
+ capture(event: TelemetryEvent): void | Promise<void>;
8
+ flush?(): void | Promise<void>;
9
+ }
10
+ interface TelemetryEvent {
11
+ name: string;
12
+ distinctId?: string;
13
+ properties?: Record<string, unknown>;
14
+ }
15
+ declare const noopTelemetry: TelemetrySink;
16
+ declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
17
+
18
+ export { type TelemetryEvent, type TelemetrySink, noopTelemetry, safeCapture };
package/dist/shared.js CHANGED
@@ -5,7 +5,22 @@ var WORKSPACE_OPEN_PATH_SURFACE_KIND = "workspace.open.path";
5
5
  function definePanel(config) {
6
6
  return config;
7
7
  }
8
+
9
+ // src/shared/telemetry.ts
10
+ var noopTelemetry = {
11
+ capture() {
12
+ }
13
+ };
14
+ function safeCapture(telemetry, event) {
15
+ try {
16
+ void Promise.resolve(telemetry.capture(event)).catch(() => {
17
+ });
18
+ } catch {
19
+ }
20
+ }
8
21
  export {
9
22
  WORKSPACE_OPEN_PATH_SURFACE_KIND,
10
- definePanel
23
+ definePanel,
24
+ noopTelemetry,
25
+ safeCapture
11
26
  };
package/dist/testing.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx as Ba } from "react/jsx-runtime";
2
2
  import * as Pa from "react";
3
3
  import { createElement as is, useMemo as wn, useLayoutEffect as us, isValidElement as ss, cloneElement as ds, useSyncExternalStore as Gi } from "react";
4
- import { h as cs, o as fs, aj as ps } from "./WorkspaceProvider-CDPaAO5u.js";
4
+ import { h as cs, o as fs, aj as ps } from "./WorkspaceProvider-Cn0sPgaB.js";
5
5
  import { d as ms } from "./panel-DnvDNQac.js";
6
6
  import * as bs from "react-dom/test-utils";
7
7
  import ka from "react-dom";
@@ -97,4 +97,4 @@ interface CommandResult {
97
97
  };
98
98
  }
99
99
 
100
- export type { AgentTool as A, CommandResult as C, JSONSchema as J, ToolExecContext as T, UiBridge as U, ToolResult as a, UiCommand as b, UiState as c };
100
+ export type { AgentTool as A, CommandResult as C, JSONSchema as J, ToolExecContext as T, UiBridge as U, UiCommand as a, UiState as b, ToolResult as c };