@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.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/CodeEditor-DQqOn4xz.js +266 -0
- package/dist/CommandPalette-aM61U-b0.js +5229 -0
- package/dist/FileTree-DRq_bfue.js +245 -0
- package/dist/MarkdownEditor-DjiHxnRv.js +349 -0
- package/dist/WorkspaceLoadingState-By0dZoPD.js +568 -0
- package/dist/agent-tool-NvxKfist.d.ts +28 -0
- package/dist/app-front.d.ts +485 -0
- package/dist/app-front.js +452 -0
- package/dist/app-server.d.ts +53 -0
- package/dist/app-server.js +769 -0
- package/dist/bootstrapServer-BRUqUpVW.d.ts +66 -0
- package/dist/boring-workspace.css +1 -0
- package/dist/charts.d.ts +114 -0
- package/dist/charts.js +143 -0
- package/dist/events.d.ts +178 -0
- package/dist/events.js +88 -0
- package/dist/explorer-DtLUnuah.d.ts +129 -0
- package/dist/panel-DnvDNQac.js +6 -0
- package/dist/server.d.ts +84 -0
- package/dist/server.js +811 -0
- package/dist/shared.d.ts +113 -0
- package/dist/shared.js +11 -0
- package/dist/testing-e2e.d.ts +68 -0
- package/dist/testing-e2e.js +45 -0
- package/dist/testing.d.ts +464 -0
- package/dist/testing.js +10984 -0
- package/dist/utils-B6yFEsav.js +8 -0
- package/dist/workspace.css +5780 -0
- package/dist/workspace.d.ts +2119 -0
- package/dist/workspace.js +1884 -0
- package/docs/INTERFACES.md +58 -0
- package/docs/PLUGIN_STRUCTURE.md +162 -0
- package/docs/README.md +19 -0
- package/docs/bridge.md +135 -0
- package/docs/panels.md +102 -0
- package/docs/plans/GENERIC_EXPLORER_PLUGIN_PLAN.md +455 -0
- package/docs/plans/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md +962 -0
- package/docs/plans/PLUGIN_OUTPUTS_ISOLATION_PLAN.md +301 -0
- package/docs/plans/README.md +9 -0
- package/docs/plans/UI_BRIDGE_OWNERSHIP_REFACTOR.md +303 -0
- package/docs/plans/archive/CODE_OWNERSHIP_CLEANUP_PLAN.md +387 -0
- package/docs/plans/archive/COMMAND_PALETTE_REGISTRY.md +814 -0
- package/docs/plans/archive/DECLARATIVE_LAYOUT_MIGRATION.md +277 -0
- package/docs/plans/archive/PLUGIN_MODEL.md +3674 -0
- package/docs/plans/archive/SRC_FOLDER_REORG_PLAN.md +307 -0
- package/docs/plans/archive/UNIFIED_EVENT_BUS.md +647 -0
- package/docs/plans/archive/WORKSPACE_V2_PLAN.md +2489 -0
- package/docs/plugins.md +158 -0
- package/package.json +164 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# `@boring/workspace` — src/ Folder Reorganization Plan
|
|
2
|
+
|
|
3
|
+
**Status:** Historical reorg plan. Filesystem ownership was superseded on
|
|
4
|
+
2026-04-30 by `PLUGIN_OUTPUTS_ISOLATION_PLAN.md`.
|
|
5
|
+
**Goal:** Consolidate all scattered root-level `src/` folders into the canonical
|
|
6
|
+
4-folder layout (`front/`, `server/`, `shared/`, `plugins/`) so the codebase
|
|
7
|
+
matches the plugin model's architectural intent end-to-end.
|
|
8
|
+
|
|
9
|
+
**Non-goals at the time:** No behavior changes. No public API breakage. Pure
|
|
10
|
+
moves + re-exports.
|
|
11
|
+
|
|
12
|
+
**2026-04-30 amendment:** the later plugin-isolation migration intentionally
|
|
13
|
+
removed `front/data` compatibility wrappers. Filesystem data, file handlers,
|
|
14
|
+
and the empty-file fallback now belong under `plugins/filesystemPlugin/`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Why
|
|
19
|
+
|
|
20
|
+
After j9p7, `src/` still has 8 directories sitting outside the 4-folder layout:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
src/
|
|
24
|
+
├── __tests__/ ← root-level integration tests (stays — integration scope)
|
|
25
|
+
├── data/ ← React data-fetching hooks
|
|
26
|
+
├── lib/ ← cn() + validation utils
|
|
27
|
+
├── panes/ ← plugin-owned panes sitting outside their plugins
|
|
28
|
+
├── store/ ← Zustand store + selectors
|
|
29
|
+
├── testing/ ← React test helpers (published as @boring/workspace/testing subpath)
|
|
30
|
+
├── theme/ ← CodeMirror + shadcn theme hooks
|
|
31
|
+
└── toast/ ← Sonner toast wrapper
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
These belong under `front/` (UI code) or inside their respective `plugins/`
|
|
35
|
+
(pane components). Leaving them at root creates two problems:
|
|
36
|
+
1. Import paths don't reflect ownership (`../../data` vs plugin-owned data)
|
|
37
|
+
2. `panes/` is the most glaring — plugin-owned components live outside their plugin
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Target Layout
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
src/
|
|
45
|
+
├── front/
|
|
46
|
+
│ ├── bridge/ (existing)
|
|
47
|
+
│ ├── chrome/ (existing — ArtifactSurfacePane + EmptyPane MOVE HERE)
|
|
48
|
+
│ │ ├── artifact-surface/
|
|
49
|
+
│ │ │ ├── SurfaceShell.tsx (existing)
|
|
50
|
+
│ │ │ ├── definition.ts (existing)
|
|
51
|
+
│ │ │ └── ArtifactSurfacePane.tsx ← MOVED from panes/ArtifactSurfacePane.tsx
|
|
52
|
+
│ │ ├── chat/ (existing)
|
|
53
|
+
│ │ ├── chat-stage-placeholder/ (existing)
|
|
54
|
+
│ │ ├── empty-pane/
|
|
55
|
+
│ │ │ └── EmptyPane.tsx ← MOVED from panes/EmptyPane.tsx
|
|
56
|
+
│ │ ├── session-list/ (existing)
|
|
57
|
+
│ │ └── workbench-left/ (existing)
|
|
58
|
+
│ ├── components/
|
|
59
|
+
│ │ ├── data-catalog/ ← MOVED from panes/data-catalog/ (see Phase C)
|
|
60
|
+
│ │ ├── DataExplorer/ (existing)
|
|
61
|
+
│ │ ├── ui/ (existing)
|
|
62
|
+
│ │ └── … (existing)
|
|
63
|
+
│ ├── dock/ (existing)
|
|
64
|
+
│ ├── events/ (existing)
|
|
65
|
+
│ ├── hooks/ (existing)
|
|
66
|
+
│ ├── layout/ (existing)
|
|
67
|
+
│ ├── lib/ ← MOVED from src/lib/
|
|
68
|
+
│ ├── plugin/ (existing)
|
|
69
|
+
│ ├── registry/ (existing)
|
|
70
|
+
│ ├── store/ ← MOVED from src/store/
|
|
71
|
+
│ ├── testing/ ← MOVED from src/testing/ (published subpath — see Phase A note)
|
|
72
|
+
│ ├── theme/ ← MOVED from src/theme/
|
|
73
|
+
│ ├── toast/ ← MOVED from src/toast/
|
|
74
|
+
│ └── WorkspaceProvider.tsx (existing)
|
|
75
|
+
│
|
|
76
|
+
├── plugins/
|
|
77
|
+
│ ├── filesystemPlugin/ (existing — panes move IN)
|
|
78
|
+
│ │ ├── index.ts (plugin def — update import paths)
|
|
79
|
+
│ │ ├── data/ ← filesystem client/hooks/provider
|
|
80
|
+
│ │ ├── empty-file-panel/ ← fallback for unmatched files
|
|
81
|
+
│ │ ├── FileTreeView.tsx ← MOVED from panes/file-tree/ (exports FileTreePane + FileTreeView)
|
|
82
|
+
│ │ ├── FileTree.tsx ← MOVED from panes/file-tree/
|
|
83
|
+
│ │ ├── CodeEditorPane.tsx ← MOVED from panes/code-editor/ (exports CodeEditorPane)
|
|
84
|
+
│ │ ├── CodeEditor.tsx ← MOVED from panes/code-editor/ (exports CodeEditor)
|
|
85
|
+
│ │ ├── MarkdownEditorPane.tsx ← MOVED from panes/markdown-editor/
|
|
86
|
+
│ │ ├── MarkdownEditor.tsx ← MOVED from panes/markdown-editor/
|
|
87
|
+
│ │ ├── defaultEditorPanels.ts ← MOVED from panes/ (3 apps consume via barrel — keep)
|
|
88
|
+
│ │ └── __tests__/
|
|
89
|
+
│ │
|
|
90
|
+
│ └── dataCatalogPlugin/ (reusable data catalog outputs + hooks)
|
|
91
|
+
│
|
|
92
|
+
├── server/ (existing)
|
|
93
|
+
└── shared/ (existing)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`src/panes/` is **deleted entirely** once all contents are rehomed.
|
|
97
|
+
`src/__tests__/` stays at root (integration tests covering the full package).
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Why DataCatalog Presentation Is Not the Plugin
|
|
102
|
+
|
|
103
|
+
`DataCatalog` / `DataCatalogPane` are **presentation components** — generic UI shells
|
|
104
|
+
with no concrete data of their own. Real catalogs come from app/domain plugins
|
|
105
|
+
that pass an `ExplorerAdapter` into the reusable data catalog plugin helpers.
|
|
106
|
+
The data catalog plugin is therefore a reusable factory, not a default workspace
|
|
107
|
+
plugin with hardcoded data.
|
|
108
|
+
|
|
109
|
+
`DataCatalog` belongs alongside `DataExplorer` in `front/components/` — both are
|
|
110
|
+
presentational peers. Move `panes/data-catalog/*` → `front/components/data-catalog/*`.
|
|
111
|
+
Apps install data catalog outputs through `createDataCatalogPlugin` or
|
|
112
|
+
`appendDataCatalogOutputs`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Public API — Zero Breaking Changes
|
|
117
|
+
|
|
118
|
+
All current `src/index.ts` exports remain. New locations are re-exported:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Standalone components — still exported from new locations
|
|
122
|
+
export { FileTreeView, FileTreePane } from "./plugins/filesystemPlugin/FileTreeView"
|
|
123
|
+
export { FileTree } from "./plugins/filesystemPlugin/FileTree"
|
|
124
|
+
export { CodeEditorPane } from "./plugins/filesystemPlugin/CodeEditorPane"
|
|
125
|
+
export { CodeEditor } from "./plugins/filesystemPlugin/CodeEditor"
|
|
126
|
+
export { MarkdownEditorPane } from "./plugins/filesystemPlugin/MarkdownEditorPane"
|
|
127
|
+
export { MarkdownEditor } from "./plugins/filesystemPlugin/MarkdownEditor"
|
|
128
|
+
export { defaultEditorPanels } from "./plugins/filesystemPlugin/defaultEditorPanels"
|
|
129
|
+
|
|
130
|
+
export { DataCatalog } from "./front/components/data-catalog/DataCatalog"
|
|
131
|
+
export { DataCatalogPane } from "./front/components/data-catalog/DataCatalogPane"
|
|
132
|
+
export { ArtifactSurfacePane } from "./front/chrome/artifact-surface/ArtifactSurfacePane"
|
|
133
|
+
export { EmptyPane } from "./front/chrome/empty-pane/EmptyPane"
|
|
134
|
+
|
|
135
|
+
// Filesystem data layer is plugin-owned and intentionally not re-exported
|
|
136
|
+
// from the package root. First-party code imports it from
|
|
137
|
+
// ./plugins/filesystemPlugin/data; consumers use the filesystem plugin surface.
|
|
138
|
+
export { createWorkspaceStore } from "./front/store"
|
|
139
|
+
export { bindStore, useActiveFile, … } from "./front/store/selectors"
|
|
140
|
+
export { createShadcnTheme, useShadcnTheme } from "./front/theme"
|
|
141
|
+
export { toast, Toaster, dismissToast } from "./front/toast"
|
|
142
|
+
export { cn } from "./front/lib/utils"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`public-api.test.ts` catches any accidental drops (verify file exists at
|
|
146
|
+
`src/__tests__/public-api.test.ts` before starting).
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Phases
|
|
151
|
+
|
|
152
|
+
### Phase A1 — Move lib/ first (zero dependents in other moved folders)
|
|
153
|
+
|
|
154
|
+
Move `src/lib/` → `src/front/lib/`. Update all internal imports.
|
|
155
|
+
Run `pnpm --filter @boring/workspace typecheck` — must be green before A2.
|
|
156
|
+
|
|
157
|
+
**Why first:** `store/`, `data/`, `toast/` all import `lib/utils` and
|
|
158
|
+
`lib/validation`. Moving lib first avoids transient broken imports in A2.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### Phase A2 — Remaining utility folders (parallel after A1)
|
|
163
|
+
|
|
164
|
+
Move 4 generic frontend directories simultaneously. The old `src/data/`
|
|
165
|
+
line from this plan was superseded; filesystem data now moves directly into
|
|
166
|
+
`src/plugins/filesystemPlugin/data/`.
|
|
167
|
+
|
|
168
|
+
| From | To |
|
|
169
|
+
|------|----|
|
|
170
|
+
| `src/store/` | `src/front/store/` |
|
|
171
|
+
| `src/theme/` | `src/front/theme/` |
|
|
172
|
+
| `src/toast/` | `src/front/toast/` |
|
|
173
|
+
| `src/testing/` | `src/front/testing/` |
|
|
174
|
+
|
|
175
|
+
**Critical — `vite.config.ts` build entry must be updated:**
|
|
176
|
+
```diff
|
|
177
|
+
- testing: "src/testing/index.ts",
|
|
178
|
+
+ testing: "src/front/testing/index.ts",
|
|
179
|
+
```
|
|
180
|
+
Failure to do this silently breaks the `@boring/workspace/testing` subpath
|
|
181
|
+
export in published dist.
|
|
182
|
+
|
|
183
|
+
**Acceptance:**
|
|
184
|
+
- `pnpm --filter @boring/workspace typecheck` green
|
|
185
|
+
- `pnpm --filter @boring/workspace test` green
|
|
186
|
+
- `pnpm --filter @boring/workspace build` produces `dist/testing.js` + `dist/testing.d.ts`
|
|
187
|
+
- Subpath smoke: `node -e "import('@boring/workspace/testing').then(m=>console.log(Object.keys(m)))"`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### Phase B — Chrome panes into front/chrome/
|
|
192
|
+
|
|
193
|
+
Move `ArtifactSurfacePane` and `EmptyPane` to sit alongside the rest of chrome:
|
|
194
|
+
|
|
195
|
+
| From | To |
|
|
196
|
+
|------|----|
|
|
197
|
+
| `src/panes/ArtifactSurfacePane.tsx` | `src/front/chrome/artifact-surface/ArtifactSurfacePane.tsx` |
|
|
198
|
+
| `src/panes/__tests__/ArtifactSurfacePane.*.test.tsx` | `src/front/chrome/artifact-surface/__tests__/` |
|
|
199
|
+
| `src/panes/EmptyPane.tsx` | `src/front/chrome/empty-pane/EmptyPane.tsx` |
|
|
200
|
+
|
|
201
|
+
**Internal imports to update:**
|
|
202
|
+
- `src/front/chrome/artifact-surface/SurfaceShell.tsx`: `../../../panes/ArtifactSurfacePane` → `./ArtifactSurfacePane`
|
|
203
|
+
|
|
204
|
+
Update `src/panes/index.ts` + `src/index.ts` re-exports.
|
|
205
|
+
|
|
206
|
+
**2026-04-30 update:** the registered empty-file fallback is no longer core
|
|
207
|
+
chrome. It lives in `src/plugins/filesystemPlugin/empty-file-panel/`.
|
|
208
|
+
`empty-pane/EmptyPane.tsx` remains the generic empty state component.
|
|
209
|
+
|
|
210
|
+
**Acceptance:** typecheck + tests green, public API test green.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### Phase C — Move data-catalog into front/components/
|
|
215
|
+
|
|
216
|
+
`DataCatalog` is a presentation component, not a plugin (see rationale above).
|
|
217
|
+
|
|
218
|
+
Move `src/panes/data-catalog/*` → `src/front/components/data-catalog/*`.
|
|
219
|
+
Update `src/panes/index.ts` + `src/index.ts` re-exports. No new plugin file.
|
|
220
|
+
|
|
221
|
+
**Acceptance:** typecheck + tests green, public API test green.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### Phase D — Filesystem panes into filesystemPlugin
|
|
226
|
+
|
|
227
|
+
Move the 3 pane families into `src/plugins/filesystemPlugin/`:
|
|
228
|
+
|
|
229
|
+
| From | To |
|
|
230
|
+
|------|----|
|
|
231
|
+
| `src/panes/file-tree/` | `src/plugins/filesystemPlugin/file-tree/` |
|
|
232
|
+
| `src/panes/code-editor/` | `src/plugins/filesystemPlugin/code-editor/` |
|
|
233
|
+
| `src/panes/markdown-editor/` | `src/plugins/filesystemPlugin/markdown-editor/` |
|
|
234
|
+
| `src/panes/defaultEditorPanels.ts` | `src/plugins/filesystemPlugin/defaultEditorPanels.ts` |
|
|
235
|
+
|
|
236
|
+
Update `filesystemPlugin/index.ts` imports (relative path changes only).
|
|
237
|
+
Re-export `FileTree`, `FileTreeView`, `FileTreePane`, `CodeEditor`, `CodeEditorPane`,
|
|
238
|
+
`MarkdownEditor`, `MarkdownEditorPane`, `defaultEditorPanels` via `src/index.ts`.
|
|
239
|
+
|
|
240
|
+
**Internal imports to update:**
|
|
241
|
+
- `src/front/chrome/workbench-left/WorkbenchLeftPane.tsx`: `../../../panes/file-tree/FileTreeView` → `../../../plugins/filesystemPlugin/file-tree/FileTreeView`
|
|
242
|
+
- `stories/*.stories.tsx` + `stories/storybook-mocks.tsx`: update pane import paths (or document Storybook as deferred)
|
|
243
|
+
|
|
244
|
+
**Note on `defaultEditorPanels.ts`:** Consumed externally by `workspace-playground`,
|
|
245
|
+
`boring-macro-v2`, `full-app` via the barrel. Uses `source: "app"` panel defs
|
|
246
|
+
(distinct from `filesystemPlugin`'s `source: "builtin"` panels). Keep as-is for
|
|
247
|
+
now — deduplication is a separate follow-up.
|
|
248
|
+
|
|
249
|
+
**Acceptance:** typecheck + tests green, `filesystemPlugin` exports all its panes,
|
|
250
|
+
public API test green, no remaining files in `src/panes/`.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### Phase E — Delete src/panes/
|
|
255
|
+
|
|
256
|
+
`src/panes/` should now be empty except `index.ts` (now an empty barrel).
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
rm -rf src/panes/
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Remove the now-dead `export * from "./panes"` line from `src/index.ts` if present.
|
|
263
|
+
Grep for any remaining `from "../../panes"` hits — must be zero.
|
|
264
|
+
|
|
265
|
+
**Acceptance:** `pnpm -w build` clean, all tests green.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### Phase F — Verification gate
|
|
270
|
+
|
|
271
|
+
1. `pnpm --filter @boring/workspace typecheck` — zero errors
|
|
272
|
+
2. `pnpm --filter @boring/workspace test` — zero failures
|
|
273
|
+
3. `pnpm --filter @boring/workspace build` — all dist subpaths present:
|
|
274
|
+
`dist/{workspace,testing,ui-shadcn,shared,server,events}.js` + `.d.ts`
|
|
275
|
+
4. Public API: `public-api.test.ts` passes (all exported symbols present)
|
|
276
|
+
5. Subpath smoke: `@boring/workspace/testing` importable
|
|
277
|
+
6. Grep: `grep -r 'from ".*\.\.\/panes"' src/` → zero hits
|
|
278
|
+
7. Storybook: confirm `stories/*` typecheck or explicitly defer
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Implementation Notes
|
|
283
|
+
|
|
284
|
+
- **Do phases in order** — each phase is independently committable and verifiable
|
|
285
|
+
- **git mv** for all moves to preserve file history
|
|
286
|
+
- **`vite.config.ts` lib.entry.testing** is the only build-config change required
|
|
287
|
+
- **`tsconfig.front.json`**: excludes `src/server/**` and plugin server files — no update needed (no server code in moved paths)
|
|
288
|
+
- **`tsconfig.server.json`**: excludes `src/shared/plugin/**` — no update needed
|
|
289
|
+
- **`package.json` exports field**: references `dist/*` — no update needed; build entry handles it
|
|
290
|
+
- **Apps** consuming via `@boring/workspace` barrel (`workspace-playground`, `boring-macro-v2`, `full-app`) — zero changes required; all exports are re-exported from barrel unchanged
|
|
291
|
+
- **`tsup.config.ts`**: verify no hardcoded `src/testing/` include before Phase A2
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Estimated Effort
|
|
296
|
+
|
|
297
|
+
| Phase | Files touched | Risk |
|
|
298
|
+
|-------|--------------|------|
|
|
299
|
+
| A1 (lib/) | ~10 import updates | Very low |
|
|
300
|
+
| A2 (5 utility folders + vite.config) | ~50 import updates | Low — vite entry is the trap |
|
|
301
|
+
| B (chrome panes) | ~15 import updates | Low |
|
|
302
|
+
| C (data-catalog → components) | ~10 files | Low |
|
|
303
|
+
| D (filesystem panes) | ~35 import updates + stories | Medium |
|
|
304
|
+
| E (delete panes/) | cleanup | Low |
|
|
305
|
+
| F (gate) | verify only | — |
|
|
306
|
+
|
|
307
|
+
Total: ~2 agent-days. Optimal swarm: A1 solo → A2+B in parallel → C → D → E+F.
|