@hachej/boring-workspace 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/dist/CodeEditor-DQqOn4xz.js +266 -0
  4. package/dist/CommandPalette-aM61U-b0.js +5229 -0
  5. package/dist/FileTree-DRq_bfue.js +245 -0
  6. package/dist/MarkdownEditor-DjiHxnRv.js +349 -0
  7. package/dist/WorkspaceLoadingState-By0dZoPD.js +568 -0
  8. package/dist/agent-tool-NvxKfist.d.ts +28 -0
  9. package/dist/app-front.d.ts +485 -0
  10. package/dist/app-front.js +452 -0
  11. package/dist/app-server.d.ts +53 -0
  12. package/dist/app-server.js +769 -0
  13. package/dist/bootstrapServer-BRUqUpVW.d.ts +66 -0
  14. package/dist/boring-workspace.css +1 -0
  15. package/dist/charts.d.ts +114 -0
  16. package/dist/charts.js +143 -0
  17. package/dist/events.d.ts +178 -0
  18. package/dist/events.js +88 -0
  19. package/dist/explorer-DtLUnuah.d.ts +129 -0
  20. package/dist/panel-DnvDNQac.js +6 -0
  21. package/dist/server.d.ts +84 -0
  22. package/dist/server.js +811 -0
  23. package/dist/shared.d.ts +113 -0
  24. package/dist/shared.js +11 -0
  25. package/dist/testing-e2e.d.ts +68 -0
  26. package/dist/testing-e2e.js +45 -0
  27. package/dist/testing.d.ts +464 -0
  28. package/dist/testing.js +10984 -0
  29. package/dist/utils-B6yFEsav.js +8 -0
  30. package/dist/workspace.css +5780 -0
  31. package/dist/workspace.d.ts +2119 -0
  32. package/dist/workspace.js +1884 -0
  33. package/docs/INTERFACES.md +58 -0
  34. package/docs/PLUGIN_STRUCTURE.md +162 -0
  35. package/docs/README.md +19 -0
  36. package/docs/bridge.md +135 -0
  37. package/docs/panels.md +102 -0
  38. package/docs/plans/GENERIC_EXPLORER_PLUGIN_PLAN.md +455 -0
  39. package/docs/plans/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md +962 -0
  40. package/docs/plans/PLUGIN_OUTPUTS_ISOLATION_PLAN.md +301 -0
  41. package/docs/plans/README.md +9 -0
  42. package/docs/plans/UI_BRIDGE_OWNERSHIP_REFACTOR.md +303 -0
  43. package/docs/plans/archive/CODE_OWNERSHIP_CLEANUP_PLAN.md +387 -0
  44. package/docs/plans/archive/COMMAND_PALETTE_REGISTRY.md +814 -0
  45. package/docs/plans/archive/DECLARATIVE_LAYOUT_MIGRATION.md +277 -0
  46. package/docs/plans/archive/PLUGIN_MODEL.md +3674 -0
  47. package/docs/plans/archive/SRC_FOLDER_REORG_PLAN.md +307 -0
  48. package/docs/plans/archive/UNIFIED_EVENT_BUS.md +647 -0
  49. package/docs/plans/archive/WORKSPACE_V2_PLAN.md +2489 -0
  50. package/docs/plugins.md +158 -0
  51. package/package.json +164 -0
@@ -0,0 +1,158 @@
1
+ > boring-ui can create plugins. Ask it to build one for your use case.
2
+
3
+ # Plugins
4
+
5
+ Plugins are the primary extension point. A plugin contributes panels, commands, catalogs, left-tabs, and surface resolvers to the workspace shell.
6
+
7
+ **Key capabilities:**
8
+ - **Panels** — center/right/bottom panes opened programmatically by the agent or user
9
+ - **Commands** — entries in the command palette (`cmd+k`)
10
+ - **Left tabs** — persistent tabs in the left sidebar
11
+ - **Catalogs** — data explorer tabs with search + row selection
12
+ - **Surface resolvers** — map agent-emitted `openSurface` requests to concrete panel opens
13
+ - **Bindings / providers** — React components mounted in the provider tree
14
+
15
+ ## Table of Contents
16
+
17
+ - [Minimal plugin](#minimal-plugin)
18
+ - [Output types](#output-types)
19
+ - [System prompt](#system-prompt)
20
+ - [Composing plugins](#composing-plugins)
21
+ - [Server plugins](#server-plugins)
22
+ - [Registering with the shell](#registering-with-the-shell)
23
+ - [Plugin folder layout](#plugin-folder-layout)
24
+ - [Invariants](#invariants)
25
+
26
+ ---
27
+
28
+ ## Minimal plugin
29
+
30
+ ```ts
31
+ import { defineFrontPlugin, definePanel } from '@boring/workspace'
32
+
33
+ export const myPlugin = defineFrontPlugin({
34
+ id: 'my-plugin',
35
+ label: 'My Plugin',
36
+ systemPrompt: "You can open the widget panel with the 'open-panel' tool.",
37
+ outputs: [
38
+ {
39
+ type: 'panel',
40
+ panel: definePanel({
41
+ id: 'my-widget',
42
+ title: 'Widget',
43
+ placement: 'center',
44
+ component: () => import('./WidgetPane').then(m => ({ default: m.WidgetPane })),
45
+ }),
46
+ },
47
+ ],
48
+ })
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Output types
54
+
55
+ | type | contributes |
56
+ |---|---|
57
+ | `panel` | a center/right/bottom pane opened programmatically |
58
+ | `left-tab` | a persistent tab in the left sidebar |
59
+ | `command` | an entry in the command palette |
60
+ | `catalog` | a data explorer tab with search + row selection |
61
+ | `surface-resolver` | maps a `SurfaceOpenRequest` kind → panel id |
62
+ | `binding` | a React component mounted in the provider tree |
63
+ | `provider` | same as binding but receives `apiBaseUrl`, `authHeaders`, etc. |
64
+
65
+ ---
66
+
67
+ ## System prompt
68
+
69
+ The `systemPrompt` field on a plugin is injected into the agent's context. Use it to teach the agent what panels exist and when to open them.
70
+
71
+ ```ts
72
+ defineFrontPlugin({
73
+ id: 'contract-review',
74
+ systemPrompt: `
75
+ You can open the contract review panel when the user asks to review a contract.
76
+ Use exec_ui with kind "openSurface" and kind "contract-review.open".
77
+ `,
78
+ ...
79
+ })
80
+ ```
81
+
82
+ All plugin `systemPrompt` strings are concatenated and passed as `systemPromptAppend` to the agent harness.
83
+
84
+ ---
85
+
86
+ ## Composing plugins
87
+
88
+ ```ts
89
+ import { composePlugins } from '@boring/workspace'
90
+
91
+ export const myPlugin = composePlugins({
92
+ id: 'my-plugin',
93
+ plugins: [panelsPlugin, catalogPlugin, surfacePlugin],
94
+ })
95
+ ```
96
+
97
+ `composePlugins` flattens child panels, commands, catalogs, bindings, and outputs into one `WorkspaceFrontPlugin`. Child ownership adopts to the parent plugin id by default.
98
+
99
+ ---
100
+
101
+ ## Server plugins
102
+
103
+ Server plugins contribute agent tools, routes, and pi package declarations:
104
+
105
+ ```ts
106
+ import { defineServerPlugin } from '@boring/workspace/server'
107
+
108
+ export const myServerPlugin = defineServerPlugin({
109
+ id: 'my-plugin',
110
+ tools: [myAgentTool],
111
+ promptText: 'You have access to the my_tool tool.',
112
+ })
113
+ ```
114
+
115
+ Compose server plugins with `composeServerPlugins()`.
116
+
117
+ ---
118
+
119
+ ## Registering with the shell
120
+
121
+ ```tsx
122
+ import { WorkspaceAgentFront } from '@boring/workspace'
123
+
124
+ <WorkspaceAgentFront plugins={[myPlugin]} />
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Plugin folder layout
130
+
131
+ ```
132
+ src/plugins/myPlugin/
133
+ front/
134
+ index.tsx ← defineFrontPlugin(), public front exports
135
+ panels.tsx ← panel definitions
136
+ surfaceResolver.ts ← openSurface kind → panel resolution
137
+ server/
138
+ index.ts ← defineServerPlugin(), public server exports
139
+ tools.ts ← agent tools
140
+ shared/
141
+ constants.ts ← plugin id, surface kinds
142
+ types.ts ← platform-neutral shared types
143
+ ```
144
+
145
+ Use only the files the plugin needs.
146
+
147
+ ---
148
+
149
+ ## Invariants
150
+
151
+ ```bash
152
+ pnpm --filter @boring/workspace run lint:plugin-invariants
153
+ ```
154
+
155
+ Rejects cross-layer imports, legacy file names, and plugin-domain imports from workspace chrome.
156
+
157
+ See [panels.md](./panels.md) for panel component API.
158
+ See [bridge.md](./bridge.md) for how to open panels from the agent.
package/package.json ADDED
@@ -0,0 +1,164 @@
1
+ {
2
+ "name": "@hachej/boring-workspace",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "description": "Workspace UI, plugin, and bridge package for composing chat, files, catalogs, editors, and app-specific panes.",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/hachej/boring-ui.git"
10
+ },
11
+ "homepage": "https://github.com/hachej/boring-ui",
12
+ "files": [
13
+ "dist",
14
+ "docs"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/workspace.d.ts",
19
+ "import": "./dist/workspace.js"
20
+ },
21
+ "./testing": {
22
+ "types": "./dist/testing.d.ts",
23
+ "import": "./dist/testing.js"
24
+ },
25
+ "./testing/e2e": {
26
+ "types": "./dist/testing-e2e.d.ts",
27
+ "import": "./dist/testing-e2e.js"
28
+ },
29
+ "./charts": {
30
+ "types": "./dist/charts.d.ts",
31
+ "import": "./dist/charts.js"
32
+ },
33
+ "./shared": {
34
+ "types": "./dist/shared.d.ts",
35
+ "import": "./dist/shared.js"
36
+ },
37
+ "./app/front": {
38
+ "types": "./dist/app-front.d.ts",
39
+ "import": "./dist/app-front.js",
40
+ "default": "./dist/app-front.js"
41
+ },
42
+ "./app/server": {
43
+ "types": "./dist/app-server.d.ts",
44
+ "import": "./dist/app-server.js",
45
+ "default": "./dist/app-server.js"
46
+ },
47
+ "./server": {
48
+ "types": "./dist/server.d.ts",
49
+ "import": "./dist/server.js",
50
+ "default": "./dist/server.js"
51
+ },
52
+ "./events": {
53
+ "types": "./dist/events.d.ts",
54
+ "import": "./dist/events.js"
55
+ },
56
+ "./globals.css": "./dist/workspace.css"
57
+ },
58
+ "sideEffects": [
59
+ "**/*.css"
60
+ ],
61
+ "peerDependencies": {
62
+ "react": "^18.0.0 || ^19.0.0",
63
+ "react-dom": "^18.0.0 || ^19.0.0",
64
+ "recharts": "^2.15.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "@codemirror/state": {
68
+ "optional": true
69
+ },
70
+ "@codemirror/view": {
71
+ "optional": true
72
+ },
73
+ "@tiptap/react": {
74
+ "optional": true
75
+ },
76
+ "@tiptap/starter-kit": {
77
+ "optional": true
78
+ },
79
+ "recharts": {
80
+ "optional": true
81
+ }
82
+ },
83
+ "dependencies": {
84
+ "@codemirror/commands": "^6.10.3",
85
+ "@codemirror/lang-javascript": "^6.2.5",
86
+ "@codemirror/lang-json": "^6.0.2",
87
+ "@codemirror/lang-markdown": "^6.5.0",
88
+ "@codemirror/lang-python": "^6.2.1",
89
+ "@codemirror/lang-sql": "^6.10.0",
90
+ "@codemirror/lang-yaml": "^6.1.3",
91
+ "@codemirror/language": "^6.12.3",
92
+ "@codemirror/search": "^6.7.0",
93
+ "@codemirror/state": "^6.6.0",
94
+ "@codemirror/view": "^6.41.1",
95
+ "@lezer/highlight": "^1.2.3",
96
+ "@tanstack/react-query": "^5.0.0",
97
+ "@tiptap/core": "^3.22.4",
98
+ "@tiptap/extension-code-block-lowlight": "^3.22.4",
99
+ "@tiptap/extension-highlight": "^3.22.4",
100
+ "@tiptap/extension-image": "^3.22.4",
101
+ "@tiptap/extension-link": "^3.22.4",
102
+ "@tiptap/extension-placeholder": "^3.22.4",
103
+ "@tiptap/extension-table": "^3.22.5",
104
+ "@tiptap/extension-table-cell": "^3.22.5",
105
+ "@tiptap/extension-table-header": "^3.22.5",
106
+ "@tiptap/extension-table-row": "^3.22.5",
107
+ "@tiptap/extension-task-item": "^3.22.4",
108
+ "@tiptap/extension-task-list": "^3.22.4",
109
+ "@tiptap/extension-text-align": "^3.22.4",
110
+ "@tiptap/extension-underline": "^3.22.4",
111
+ "@tiptap/pm": "^3.22.4",
112
+ "@tiptap/react": "^3.22.4",
113
+ "@tiptap/starter-kit": "^3.22.4",
114
+ "class-variance-authority": "^0.7.0",
115
+ "clsx": "^2.1.0",
116
+ "cmdk": "^1.1.1",
117
+ "dockview-react": "^4.13.1",
118
+ "fastify": "^5.3.3",
119
+ "lowlight": "^3.3.0",
120
+ "lucide-react": "^1.8.0",
121
+ "micromatch": "^4.0.8",
122
+ "radix-ui": "^1.4.3",
123
+ "react-arborist": "^3.4.0",
124
+ "tailwind-merge": "^2.0.0",
125
+ "tiptap-markdown": "^0.9.0",
126
+ "zod": "^3.23.0",
127
+ "zustand": "^5.0.0",
128
+ "@hachej/boring-agent": "0.1.0",
129
+ "@hachej/boring-ui-kit": "0.1.0"
130
+ },
131
+ "devDependencies": {
132
+ "@tailwindcss/postcss": "^4.0.0",
133
+ "@tailwindcss/vite": "^4.0.0",
134
+ "@testing-library/jest-dom": "^6.9.1",
135
+ "@testing-library/react": "^16.3.2",
136
+ "@testing-library/user-event": "^14.6.1",
137
+ "@types/micromatch": "^4.0.10",
138
+ "@types/node": "^22.15.3",
139
+ "@types/react": "^19.0.0",
140
+ "@types/react-dom": "^19.0.0",
141
+ "@vitejs/plugin-react": "^4.0.0",
142
+ "fast-check": "^4.7.0",
143
+ "jsdom": "^29.0.2",
144
+ "postcss": "^8.5.13",
145
+ "react": "^19.0.0",
146
+ "react-dom": "^19.0.0",
147
+ "recharts": "^2.15.4",
148
+ "tailwindcss": "^4.0.0",
149
+ "tsup": "^8.0.0",
150
+ "typescript": "^5.4.0",
151
+ "vite": "^6.0.0",
152
+ "vite-plugin-dts": "^4.5.4",
153
+ "vitest": "^2.0.0"
154
+ },
155
+ "scripts": {
156
+ "dev": "vite",
157
+ "build": "pnpm --filter @hachej/boring-ui-kit build && tsup && vite build && node ./scripts/build-workspace-css.mjs && node ./scripts/assert-build-artifacts.mjs",
158
+ "typecheck": "pnpm --filter @hachej/boring-ui-kit build && pnpm --filter @hachej/boring-agent build && tsc --noEmit -p tsconfig.front.json && tsc --noEmit -p tsconfig.server.json",
159
+ "test": "vitest run",
160
+ "check:bundle-size": "node ./scripts/check-bundle-size.mjs",
161
+ "lint:plugin-invariants": "node ./scripts/check-plugin-invariants.mjs",
162
+ "lint": "pnpm run typecheck"
163
+ }
164
+ }