@hachej/boring-workspace 0.1.10 → 0.1.13
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/{CommandPalette-D5KPKtKA.js → CommandPalette-Dme9em28.js} +600 -599
- package/dist/{FileTree-CwC01Ijr.js → FileTree-BVfqs3rR.js} +1 -1
- package/dist/{MarkdownEditor-CB7nfhN9.js → MarkdownEditor-CcCDF65H.js} +1 -1
- package/dist/{WorkspaceLoadingState-J8XVhEyL.js → WorkspaceLoadingState-BjZGQLS_.js} +85 -85
- package/dist/app-front.js +2 -2
- package/dist/app-server.d.ts +3 -3
- package/dist/app-server.js +50 -19
- package/dist/server.d.ts +3 -3
- package/dist/server.js +42 -16
- package/dist/testing.js +1 -1
- package/dist/workspace.css +3 -3
- package/dist/workspace.d.ts +3 -1
- package/dist/workspace.js +718 -692
- package/docs/plans/ASK_USER_QUESTIONS_PLUGIN_SPEC.md +322 -0
- package/package.json +3 -3
package/dist/server.js
CHANGED
|
@@ -162,7 +162,7 @@ data: ${JSON.stringify({ v: UI_BRIDGE_PROTOCOL_VERSION })}
|
|
|
162
162
|
|
|
163
163
|
// src/server/ui-control/tools/uiTools.ts
|
|
164
164
|
import { access } from "fs/promises";
|
|
165
|
-
import { resolve, isAbsolute, relative } from "path";
|
|
165
|
+
import { resolve, isAbsolute, relative, win32 } from "path";
|
|
166
166
|
function makeError(message) {
|
|
167
167
|
return {
|
|
168
168
|
content: [{ type: "text", text: message }],
|
|
@@ -174,16 +174,37 @@ function getPathParam(kind, params) {
|
|
|
174
174
|
const raw = kind === "navigateToLine" ? params.file : params.path;
|
|
175
175
|
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
176
176
|
}
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
function isPathAbsolute(filePath) {
|
|
178
|
+
return isAbsolute(filePath) || win32.isAbsolute(filePath);
|
|
179
|
+
}
|
|
180
|
+
function isOutsideWorkspaceRel(rel) {
|
|
181
|
+
return rel === ".." || rel.startsWith("../") || rel.startsWith("..\\") || isPathAbsolute(rel);
|
|
182
|
+
}
|
|
183
|
+
function validatePathSyntax(relPath, workspaceRoot) {
|
|
184
|
+
const rootHint = workspaceRoot ? ` (${workspaceRoot})` : "";
|
|
185
|
+
if (isPathAbsolute(relPath)) {
|
|
179
186
|
return {
|
|
180
187
|
ok: false,
|
|
181
|
-
reason: `path "${relPath}" is absolute \u2014 pass a path relative to the workspace root
|
|
188
|
+
reason: `path "${relPath}" is absolute \u2014 pass a path relative to the workspace root${rootHint}.`
|
|
182
189
|
};
|
|
183
190
|
}
|
|
191
|
+
if (relPath.includes("\0")) {
|
|
192
|
+
return { ok: false, reason: `path "${relPath}" contains a null byte.` };
|
|
193
|
+
}
|
|
194
|
+
if (relPath.split(/[\\/]+/).includes("..")) {
|
|
195
|
+
return {
|
|
196
|
+
ok: false,
|
|
197
|
+
reason: `path "${relPath}" escapes the workspace root${rootHint}.`
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return { ok: true };
|
|
201
|
+
}
|
|
202
|
+
async function validatePath(workspaceRoot, relPath) {
|
|
203
|
+
const syntax = validatePathSyntax(relPath, workspaceRoot);
|
|
204
|
+
if (!syntax.ok) return syntax;
|
|
184
205
|
const resolved = resolve(workspaceRoot, relPath);
|
|
185
206
|
const rel = relative(workspaceRoot, resolved);
|
|
186
|
-
if (
|
|
207
|
+
if (isOutsideWorkspaceRel(rel)) {
|
|
187
208
|
return {
|
|
188
209
|
ok: false,
|
|
189
210
|
reason: `path "${relPath}" escapes the workspace root (${workspaceRoot}).`
|
|
@@ -286,13 +307,14 @@ function createExecUiTool(uiBridge, opts = {}) {
|
|
|
286
307
|
" auto-opens if collapsed. Path must be relative to the",
|
|
287
308
|
" workspace root (e.g. `src/foo.ts`, not `foo.ts` if it",
|
|
288
309
|
" lives under src/).",
|
|
289
|
-
" Recovery on file-not-found:
|
|
290
|
-
"
|
|
291
|
-
" exist. On that error,
|
|
292
|
-
" grep) to locate the file,
|
|
293
|
-
" openFile AGAIN using the EXACT path
|
|
294
|
-
" give up and don't switch to the read
|
|
295
|
-
" until openFile succeeds or no candidate
|
|
310
|
+
" Recovery on file-not-found: when the server has local",
|
|
311
|
+
" filesystem access, this tool stat-checks the path and",
|
|
312
|
+
" returns an error if it doesn't exist. On that error,",
|
|
313
|
+
" immediately call find (or grep) to locate the file,",
|
|
314
|
+
" then call exec_ui openFile AGAIN using the EXACT path",
|
|
315
|
+
" returned \u2014 don't give up and don't switch to the read",
|
|
316
|
+
" tool. Repeat until openFile succeeds or no candidate",
|
|
317
|
+
" is found.",
|
|
296
318
|
" Example: {kind:'openFile', params:{path:'README.md'}}",
|
|
297
319
|
"",
|
|
298
320
|
" openPanel params: { id: string, component: string,",
|
|
@@ -376,16 +398,20 @@ function createExecUiTool(uiBridge, opts = {}) {
|
|
|
376
398
|
return makeError("openSurface: meta must be an object when provided");
|
|
377
399
|
}
|
|
378
400
|
}
|
|
379
|
-
if (
|
|
401
|
+
if (PATH_BEARING_KINDS.has(kind)) {
|
|
380
402
|
const relPath = getPathParam(kind, cmdParams);
|
|
381
403
|
if (!relPath) {
|
|
382
404
|
return makeError(
|
|
383
405
|
`${kind}: ${kind === "navigateToLine" ? "file" : "path"} param is required`
|
|
384
406
|
);
|
|
385
407
|
}
|
|
386
|
-
const
|
|
387
|
-
if (!
|
|
388
|
-
|
|
408
|
+
const syntax = validatePathSyntax(relPath, workspaceRoot);
|
|
409
|
+
if (!syntax.ok) return makeError(syntax.reason);
|
|
410
|
+
if (workspaceRoot) {
|
|
411
|
+
const check = await validatePath(workspaceRoot, relPath);
|
|
412
|
+
if (!check.ok) {
|
|
413
|
+
return makeError(check.reason);
|
|
414
|
+
}
|
|
389
415
|
}
|
|
390
416
|
}
|
|
391
417
|
try {
|
package/dist/testing.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as ka } from "react/jsx-runtime";
|
|
2
2
|
import * as Pa from "react";
|
|
3
3
|
import { createElement as ds, useMemo as Tn, useLayoutEffect as fs, isValidElement as ps, cloneElement as ms, useSyncExternalStore as Ji } from "react";
|
|
4
|
-
import { i as vs, q as bs, ai as hs } from "./CommandPalette-
|
|
4
|
+
import { i as vs, q as bs, ai as hs } from "./CommandPalette-Dme9em28.js";
|
|
5
5
|
import { d as ys } from "./panel-DnvDNQac.js";
|
|
6
6
|
import * as Rs from "react-dom/test-utils";
|
|
7
7
|
import Ba from "react-dom";
|
package/dist/workspace.css
CHANGED
|
@@ -1868,9 +1868,6 @@
|
|
|
1868
1868
|
.w-6 {
|
|
1869
1869
|
width: calc(var(--spacing) * 6);
|
|
1870
1870
|
}
|
|
1871
|
-
.w-7 {
|
|
1872
|
-
width: calc(var(--spacing) * 7);
|
|
1873
|
-
}
|
|
1874
1871
|
.w-9 {
|
|
1875
1872
|
width: calc(var(--spacing) * 9);
|
|
1876
1873
|
}
|
|
@@ -1913,6 +1910,9 @@
|
|
|
1913
1910
|
.max-w-2xl {
|
|
1914
1911
|
max-width: var(--container-2xl);
|
|
1915
1912
|
}
|
|
1913
|
+
.max-w-20 {
|
|
1914
|
+
max-width: calc(var(--spacing) * 20);
|
|
1915
|
+
}
|
|
1916
1916
|
.max-w-\[68ch\] {
|
|
1917
1917
|
max-width: 68ch;
|
|
1918
1918
|
}
|
package/dist/workspace.d.ts
CHANGED
|
@@ -509,7 +509,7 @@ export declare interface DataCatalogVisualizationState extends DataCatalogResolv
|
|
|
509
509
|
title: string;
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
export declare function DataExplorer({ adapter, facets: facetConfigs, groupBy, onActivate, getDragPayload, emptyState, searchPlaceholder, searchable, query, pageSize, debounceMs, className, }: DataExplorerProps): JSX.Element;
|
|
512
|
+
export declare function DataExplorer({ adapter, facets: facetConfigs, groupBy, onActivate, getDragPayload, emptyState, searchPlaceholder, searchable, query, onQueryChange, pageSize, debounceMs, className, }: DataExplorerProps): JSX.Element;
|
|
513
513
|
|
|
514
514
|
export declare type DataExplorerProps = {
|
|
515
515
|
adapter: ExplorerAdapter;
|
|
@@ -532,6 +532,8 @@ export declare type DataExplorerProps = {
|
|
|
532
532
|
* Useful when an outer chrome already owns a search box.
|
|
533
533
|
*/
|
|
534
534
|
query?: string;
|
|
535
|
+
/** Called when the toolbar search changes. Use with `query` for controlled per-tab search. */
|
|
536
|
+
onQueryChange?: (query: string) => void;
|
|
535
537
|
/** Page size and debounce — passed through to useExplorerState. */
|
|
536
538
|
pageSize?: number;
|
|
537
539
|
debounceMs?: number;
|