@hachej/boring-ui-plugin-cli 0.1.31 → 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.
@@ -0,0 +1,43 @@
1
+ // Vitest setup for this plugin. Each plugin owns its own copy of this
2
+ // file; keep them in sync with packages/plugin-cli/templates/plugin/src/test-setup.ts when
3
+ // the canonical setup changes (rare — see the comment below).
4
+ //
5
+ // Extends vitest's `expect` with jest-dom matchers manually rather than
6
+ // via `import "@testing-library/jest-dom/vitest"`. The shorthand
7
+ // re-imports `vitest` through jest-dom's own resolution path, which —
8
+ // after lockfile churn in this monorepo — lands on a *different* copy
9
+ // of vitest than test files do. Extensions go nowhere and you get
10
+ // `Invalid Chai property: toBeInTheDocument` everywhere. Doing the
11
+ // extend manually pins both sides to the same expect.
12
+ import { expect, afterEach } from "vitest"
13
+ import * as matchers from "@testing-library/jest-dom/matchers"
14
+ import { cleanup } from "@testing-library/react"
15
+
16
+ expect.extend(matchers)
17
+
18
+ if (typeof globalThis.ResizeObserver === "undefined") {
19
+ globalThis.ResizeObserver = class ResizeObserver {
20
+ observe() {}
21
+ unobserve() {}
22
+ disconnect() {}
23
+ }
24
+ }
25
+
26
+ // jsdom doesn't implement layout. Plugins using tiptap / ProseMirror
27
+ // call getClientRects on Range/Element instances during scrollIntoView;
28
+ // stub them so transactions don't throw.
29
+ if (typeof Range !== "undefined" && !Range.prototype.getClientRects) {
30
+ Range.prototype.getClientRects = function () {
31
+ return { length: 0, item: () => null, [Symbol.iterator]: function* () {} } as any
32
+ }
33
+ Range.prototype.getBoundingClientRect = function () {
34
+ return {
35
+ x: 0, y: 0, top: 0, left: 0, right: 0, bottom: 0,
36
+ width: 0, height: 0, toJSON: () => ({}),
37
+ } as DOMRect
38
+ }
39
+ }
40
+
41
+ afterEach(() => {
42
+ cleanup()
43
+ })
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "resolveJsonModule": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "noEmit": true,
14
+ "types": ["vitest/globals", "@testing-library/jest-dom"],
15
+ "paths": {
16
+ "@hachej/boring-workspace": ["../../packages/workspace/src/index.ts"],
17
+ "@hachej/boring-workspace/server": ["../../packages/workspace/src/server/index.ts"],
18
+ "@hachej/boring-workspace/events": ["../../packages/workspace/src/front/events/index.ts"]
19
+ }
20
+ },
21
+ "include": ["src/**/*"],
22
+ "exclude": ["node_modules", "dist"]
23
+ }
@@ -0,0 +1,21 @@
1
+ import { defineConfig } from "tsup"
2
+
3
+ export default defineConfig({
4
+ entry: {
5
+ "front/index": "src/front/index.ts",
6
+ "server/index": "src/server/index.ts",
7
+ "shared/index": "src/shared/index.ts",
8
+ },
9
+ format: ["esm"],
10
+ dts: true,
11
+ splitting: false,
12
+ clean: true,
13
+ platform: "neutral",
14
+ target: "es2022",
15
+ external: [
16
+ /^@hachej\/boring-/,
17
+ "react",
18
+ "react-dom",
19
+ "react/jsx-runtime",
20
+ ],
21
+ })
@@ -0,0 +1,20 @@
1
+ import { defineConfig } from "vitest/config"
2
+ import { resolve } from "node:path"
3
+ import react from "@vitejs/plugin-react"
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ resolve: {
8
+ alias: {
9
+ "@hachej/boring-workspace/server": resolve(__dirname, "../../packages/workspace/src/server/index.ts"),
10
+ "@hachej/boring-workspace/events": resolve(__dirname, "../../packages/workspace/src/front/events/index.ts"),
11
+ "@hachej/boring-workspace/plugin": resolve(__dirname, "../../packages/workspace/src/plugin.ts"),
12
+ "@hachej/boring-workspace": resolve(__dirname, "../../packages/workspace/src/index.ts"),
13
+ },
14
+ },
15
+ test: {
16
+ environment: "jsdom",
17
+ globals: true,
18
+ setupFiles: ["./src/test-setup.ts"],
19
+ },
20
+ })
@@ -0,0 +1,42 @@
1
+ // CANONICAL server/index.ts for advanced boring-ui server integration.
2
+ // This is boot-time/static composition only for .pi/extensions plugins:
3
+ // /reload does NOT hot-register these routes or agent tools. Prefer
4
+ // pi.extensions for hot-reloadable agent behavior.
5
+ // Copy this shape only when the host will compose/restart the plugin.
6
+
7
+ import { defineServerPlugin, type WorkspaceServerPlugin } from "@hachej/boring-workspace/server"
8
+
9
+ export default function (
10
+ _options: unknown,
11
+ ctx: { workspaceRoot: string; bridge: unknown },
12
+ ): WorkspaceServerPlugin {
13
+ return defineServerPlugin({
14
+ id: "<kebab-name>", // contribution namespace; matching package name is recommended
15
+ agentTools: [
16
+ {
17
+ name: "<snake_case_tool_name>",
18
+ description: "<what the tool does>",
19
+ parameters: { type: "object", properties: {} },
20
+ async execute() {
21
+ return { content: [{ type: "text", text: "..." }] }
22
+ },
23
+ },
24
+ ],
25
+ systemPrompt: "Use <snake_case_tool_name> when …",
26
+ })
27
+ }
28
+
29
+ // Key rules — agents commonly get these wrong:
30
+ // - Method is `execute` (NOT `handler`).
31
+ // - Return shape MUST be `{ content: [{ type: "text", text: "..." }] }`
32
+ // (NOT a bare string and NOT `{ result: ... }`).
33
+ // - Import from `@hachej/boring-workspace/server`
34
+ // (NOT `@hachej/boring-pi` and NOT `@boring-ui/*`).
35
+ // - Default-export a FUNCTION that returns the plugin object —
36
+ // do NOT `export const eval_cross_ping = { ... }`.
37
+ // - package.json must set `boring.server: "server/index.ts"`
38
+ // (a relative path string). NOT `true` — the manifest validator
39
+ // rejects `true` with `INVALID_PLUGIN_METADATA`. Valid values:
40
+ // a path string, OR `false` (no server), OR omit.
41
+ // - For .pi/extensions user plugins, /reload only refreshes front/Pi
42
+ // assets. Server entries require static composition plus restart.