@skybridge/vite-plugin 0.0.0-dev.7aada9d → 0.0.0-dev.8a4b6f5

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/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @skybridge/vite-plugin
2
+
3
+ The Vite plugin behind [Skybridge](https://skybridge.tech): it discovers view
4
+ modules, serves them as virtual entries, applies the `data-llm` transform, and
5
+ tells `skybridge build` which packages to leave unbundled.
6
+
7
+ Its `evals` option wires up [`@skybridge/test`](https://www.npmjs.com/package/@skybridge/test),
8
+ which boots the server and extends vitest's assertions with chat-oriented
9
+ matchers for checking that a prompt reaches the right tool.
10
+
11
+ Projects created with `npm create skybridge` already have it wired up.
12
+
13
+ ```ts
14
+ import { defineConfig } from "vite";
15
+ import { skybridge } from "@skybridge/vite-plugin";
16
+
17
+ export default defineConfig({
18
+ plugins: [skybridge()],
19
+ });
20
+ ```
21
+
22
+ See the [documentation](https://docs.skybridge.tech) for the options it accepts.
@@ -0,0 +1,4 @@
1
+ import type { TestProject } from "vitest/node";
2
+ import "./types.js";
3
+ export default function setup(project: TestProject): Promise<(() => Promise<void>) | undefined>;
4
+ //# sourceMappingURL=global-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-setup.d.ts","sourceRoot":"","sources":["../../src/evals/global-setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,YAAY,CAAC;AAEpB,wBAA8B,KAAK,CAAC,OAAO,EAAE,WAAW,8CAwBvD"}
@@ -0,0 +1,25 @@
1
+ import { startServer } from "./server-harness.js";
2
+ import "./types.js";
3
+ export default async function setup(project) {
4
+ const options = project.config.provide?.skybridgeEvals;
5
+ if (options === undefined) {
6
+ return;
7
+ }
8
+ if (options.server !== undefined) {
9
+ project.provide("skybridgeEvalsUrl", options.server);
10
+ return;
11
+ }
12
+ if (options.project === undefined) {
13
+ throw new Error("The evals plugin needs either `server` or `project`");
14
+ }
15
+ const server = await startServer(options.project);
16
+ project.provide("skybridgeEvalsUrl", server.url);
17
+ return async () => {
18
+ const output = server.output().trim();
19
+ await server.stop();
20
+ if (output !== "") {
21
+ console.log(`\n--- server output ---\n${output}\n---`);
22
+ }
23
+ };
24
+ }
25
+ //# sourceMappingURL=global-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-setup.js","sourceRoot":"","sources":["../../src/evals/global-setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK,CAAC,OAAoB;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC;IACvD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAEjD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,OAAO,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { ChatAssertion, ChatMatchers } from "./matchers.js";
2
+ export type { ChatLike, ToolCall } from "./types.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evals/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/evals/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import type { ToolInput, ToolNames } from "skybridge/server";
2
+ import type { ChatLike } from "./types.js";
3
+ /**
4
+ * Assertions about the tool calls a conversation produced. Kept off vitest's
5
+ * global `Matchers` so they never appear on unrelated `expect()` calls, and so
6
+ * this stays the one place later tool-call helpers are added.
7
+ */
8
+ export interface ChatMatchers<App> {
9
+ toHaveCalledToolOnce<Name extends ToolNames<App>>(name: Name, args?: Partial<ToolInput<App, Name>>): void;
10
+ toHaveCalledToolWith<Name extends ToolNames<App>>(name: Name, args: Partial<ToolInput<App, Name>>): void;
11
+ toNeverHaveCalledTool<Name extends ToolNames<App>>(name: Name): void;
12
+ toHaveFailedToolCall<Name extends ToolNames<App>>(name: Name): void;
13
+ /**
14
+ * Whether any assistant turn matches. A string matches case-insensitively as
15
+ * a substring, with runs of whitespace collapsed; a RegExp is used as
16
+ * written. Model prose varies between runs, so prefer asserting on tool
17
+ * calls where you can, and keep these assertions loose.
18
+ */
19
+ toHaveSaid(text: string | RegExp): void;
20
+ }
21
+ export interface ChatAssertion<App> extends ChatMatchers<App> {
22
+ not: ChatMatchers<App>;
23
+ }
24
+ declare module "vitest" {
25
+ interface ExpectStatic {
26
+ chat<App>(chat: ChatLike<App>): ChatAssertion<App>;
27
+ }
28
+ }
29
+ //# sourceMappingURL=matchers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/evals/matchers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,YAAY,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,GAAG;IAC/B,oBAAoB,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,CAAC,EAC9C,IAAI,EAAE,IAAI,EACV,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GACnC,IAAI,CAAC;IACR,oBAAoB,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,CAAC,EAC9C,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAClC,IAAI,CAAC;IACR,qBAAqB,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IACrE,oBAAoB,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IACpE;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,aAAa,CAAC,GAAG,CAAE,SAAQ,YAAY,CAAC,GAAG,CAAC;IAC3D,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;CACxB;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,YAAY;QACpB,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;KACpD;CACF"}
@@ -0,0 +1,102 @@
1
+ import { expect } from "vitest";
2
+ function attemptedCalls(chat, name) {
3
+ return chat.toolCalls.filter((call) => String(call.name) === name);
4
+ }
5
+ function acceptedCalls(chat, name) {
6
+ return attemptedCalls(chat, name).filter((call) => call.failed === undefined);
7
+ }
8
+ function observed(chat) {
9
+ if (chat.toolCalls.length === 0) {
10
+ return " (no tool was called)";
11
+ }
12
+ return chat.toolCalls
13
+ .map((call, index) => ` ${index + 1}. ${call.name} ${JSON.stringify(call.arguments)}${call.failed === undefined ? "" : ` (failed: ${call.failed})`}`)
14
+ .join("\n");
15
+ }
16
+ function collapse(text) {
17
+ return text.replace(/\s+/g, " ").trim();
18
+ }
19
+ function said(chat, text) {
20
+ return chat.assistantTurns.some((turn) => typeof text === "string"
21
+ ? collapse(turn).toLowerCase().includes(collapse(text).toLowerCase())
22
+ : text.test(turn));
23
+ }
24
+ function spoken(chat) {
25
+ if (chat.assistantTurns.length === 0) {
26
+ return " (the assistant said nothing)";
27
+ }
28
+ return chat.assistantTurns
29
+ .map((turn, index) => ` ${index + 1}. ${collapse(turn)}`)
30
+ .join("\n");
31
+ }
32
+ function report(chat, summary) {
33
+ return `${summary}
34
+
35
+ Calls the model actually made:
36
+ ${observed(chat)}
37
+
38
+ Tool definitions the model was looking at:
39
+ ${chat.describeTools()}`;
40
+ }
41
+ expect.extend({
42
+ toHaveCalledToolOnce(received, name, args) {
43
+ const matching = acceptedCalls(received, name);
44
+ const argsMatch = args === undefined ||
45
+ (matching.length === 1 &&
46
+ this.equals(matching[0]?.arguments, expect.objectContaining(args)));
47
+ const pass = matching.length === 1 && argsMatch;
48
+ return {
49
+ pass,
50
+ message: () => report(received, pass
51
+ ? `Expected "${name}" not to be called exactly once.`
52
+ : matching.length === 1
53
+ ? `Expected "${name}" to be called once with ${JSON.stringify(args)}, but it was called with ${JSON.stringify(matching[0]?.arguments)}.`
54
+ : `Expected "${name}" to be called exactly once by a call that succeeded, but ${matching.length} such calls were made.`),
55
+ };
56
+ },
57
+ toHaveCalledToolWith(received, name, args) {
58
+ const pass = acceptedCalls(received, name).some((call) => this.equals(call.arguments, expect.objectContaining(args)));
59
+ return {
60
+ pass,
61
+ message: () => report(received, pass
62
+ ? `Expected no call to "${name}" with ${JSON.stringify(args)}.`
63
+ : `Expected "${name}" to be called with ${JSON.stringify(args)}.`),
64
+ };
65
+ },
66
+ toHaveFailedToolCall(received, name) {
67
+ const attempted = attemptedCalls(received, name);
68
+ const failed = attempted.filter((call) => call.failed !== undefined);
69
+ return {
70
+ pass: failed.length > 0,
71
+ message: () => report(received, failed.length > 0
72
+ ? `Expected every call to "${name}" to succeed.`
73
+ : attempted.length === 0
74
+ ? `Expected "${name}" to be called and fail, but it was never called.`
75
+ : `Expected "${name}" to fail, but all ${attempted.length} calls succeeded.`),
76
+ };
77
+ },
78
+ toHaveSaid(received, text) {
79
+ const pass = said(received, text);
80
+ const wanted = typeof text === "string" ? `"${text}"` : String(text);
81
+ return {
82
+ pass,
83
+ message: () => `${pass
84
+ ? `Expected the assistant not to say ${wanted}.`
85
+ : `Expected the assistant to say ${wanted}.`}
86
+
87
+ What the assistant actually said:
88
+ ${spoken(received)}`,
89
+ };
90
+ },
91
+ toNeverHaveCalledTool(received, name) {
92
+ const matching = attemptedCalls(received, name);
93
+ return {
94
+ pass: matching.length === 0,
95
+ message: () => report(received, matching.length === 0
96
+ ? `Expected "${name}" to be called at least once.`
97
+ : `Expected "${name}" never to be called, but it was called ${matching.length} times.`),
98
+ };
99
+ },
100
+ });
101
+ expect.chat = (chat) => expect(chat);
102
+ //# sourceMappingURL=matchers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchers.js","sourceRoot":"","sources":["../../src/evals/matchers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface RunningServer {
2
+ url: string;
3
+ /** Everything the server wrote to stdout/stderr, for failure reports. */
4
+ output: () => string;
5
+ stop: () => Promise<void>;
6
+ }
7
+ /**
8
+ * Spawns the project's server with `__PORT=0` and an IPC channel, and waits
9
+ * for the `skybridge:listening` message carrying the port the OS picked.
10
+ * Binding and reporting both happen in the child, so there is no window in
11
+ * which another process can steal the port.
12
+ */
13
+ export declare function startServer({ cwd, command, env, }: {
14
+ cwd: string;
15
+ command: string[];
16
+ env?: Record<string, string>;
17
+ }): Promise<RunningServer>;
18
+ //# sourceMappingURL=server-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-harness.d.ts","sourceRoot":"","sources":["../../src/evals/server-harness.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAiBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,EAChC,GAAG,EACH,OAAO,EACP,GAAQ,GACT,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,OAAO,CAAC,aAAa,CAAC,CA4EzB"}
@@ -0,0 +1,79 @@
1
+ import { spawn } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+ function hasExited(child) {
4
+ return child.exitCode !== null || child.signalCode !== null;
5
+ }
6
+ function isListeningMessage(message) {
7
+ return (typeof message === "object" &&
8
+ message !== null &&
9
+ message.type === "skybridge:listening" &&
10
+ typeof message.port === "number");
11
+ }
12
+ /**
13
+ * Spawns the project's server with `__PORT=0` and an IPC channel, and waits
14
+ * for the `skybridge:listening` message carrying the port the OS picked.
15
+ * Binding and reporting both happen in the child, so there is no window in
16
+ * which another process can steal the port.
17
+ */
18
+ export async function startServer({ cwd, command, env = {}, }) {
19
+ const timeoutMs = 60_000;
20
+ const [bin, ...args] = command;
21
+ if (bin === undefined) {
22
+ throw new Error("Empty server command");
23
+ }
24
+ const executable = bin.startsWith(".") ? resolve(cwd, bin) : bin;
25
+ const child = spawn(executable, args, {
26
+ cwd,
27
+ env: {
28
+ ...process.env,
29
+ NODE_ENV: "production",
30
+ ...env,
31
+ __PORT: "0",
32
+ },
33
+ stdio: ["ignore", "pipe", "pipe", "ipc"],
34
+ });
35
+ let captured = "";
36
+ const output = () => captured;
37
+ child.stdout?.on("data", (chunk) => {
38
+ captured += chunk;
39
+ });
40
+ child.stderr?.on("data", (chunk) => {
41
+ captured += chunk;
42
+ });
43
+ const stop = async () => {
44
+ if (hasExited(child)) {
45
+ return;
46
+ }
47
+ const exited = new Promise((resolveExit) => {
48
+ child.once("exit", () => resolveExit());
49
+ });
50
+ child.kill("SIGTERM");
51
+ const forced = setTimeout(() => child.kill("SIGKILL"), 3_000);
52
+ await exited;
53
+ clearTimeout(forced);
54
+ };
55
+ const port = await new Promise((resolvePort, reject) => {
56
+ const timer = setTimeout(() => {
57
+ reject(new Error(`Server did not report a port in ${timeoutMs}ms. \`command\` must start the server process directly (node, tsx): wrappers such as \`pnpm run\` do not forward the IPC channel the readiness signal uses. It must also run a skybridge version that sends skybridge:listening.\n${output()}`));
58
+ }, timeoutMs);
59
+ child.on("message", (message) => {
60
+ if (isListeningMessage(message)) {
61
+ clearTimeout(timer);
62
+ resolvePort(message.port);
63
+ }
64
+ });
65
+ child.on("error", (error) => {
66
+ clearTimeout(timer);
67
+ reject(new Error(`Failed to spawn ${command.join(" ")}: ${error.message}`));
68
+ });
69
+ child.on("exit", () => {
70
+ clearTimeout(timer);
71
+ reject(new Error(`Server exited with code ${child.exitCode} before reporting its port:\n${output()}`));
72
+ });
73
+ }).catch(async (error) => {
74
+ await stop();
75
+ throw error;
76
+ });
77
+ return { url: `http://127.0.0.1:${port}/mcp`, output, stop };
78
+ }
79
+ //# sourceMappingURL=server-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-harness.js","sourceRoot":"","sources":["../../src/evals/server-harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ToolInput, ToolNames } from "skybridge/server";
2
+ import type { EvalsOptions } from "../plugin.js";
3
+ /**
4
+ * One recorded call, typed against the project's own registry: `name` is a
5
+ * union of the project's tool names and `arguments` is discriminated on it.
6
+ * `failed` carries the server's reason when the call did not go through.
7
+ */
8
+ export type ToolCall<App> = {
9
+ [Name in ToolNames<App>]: {
10
+ name: Name;
11
+ arguments: ToolInput<App, Name>;
12
+ failed?: string;
13
+ };
14
+ }[ToolNames<App>];
15
+ /** The part of a conversation the matchers assert on. */
16
+ export interface ChatLike<App> {
17
+ readonly toolCalls: ToolCall<App>[];
18
+ readonly assistantTurns: string[];
19
+ /**
20
+ * The tool definitions the model was looking at, rendered for failure
21
+ * reports. Deliberately a string: descriptions and schemas are prompt text
22
+ * that changes freely, so they are worth reading when an eval fails and not
23
+ * worth asserting on.
24
+ */
25
+ describeTools(): string;
26
+ }
27
+ declare module "vitest" {
28
+ interface ProvidedContext {
29
+ skybridgeEvals: EvalsOptions | undefined;
30
+ skybridgeEvalsUrl: string | undefined;
31
+ }
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evals/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,CAAC,GAAG,IAAI;KACzB,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG;QACxB,IAAI,EAAE,IAAI,CAAC;QACX,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;CACF,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAElB,yDAAyD;AACzD,MAAM,WAAW,QAAQ,CAAC,GAAG;IAC3B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,aAAa,IAAI,MAAM,CAAC;CACzB;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,eAAe;QACvB,cAAc,EAAE,YAAY,GAAG,SAAS,CAAC;QACzC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;KACvC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/evals/types.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export { type EvalsPluginOptions, type SkybridgePluginOptions, skybridge, } from "./plugin.js";
2
- export { assertUniqueViewNames, type DiscoveredView, discoverViewsSync, scanAndWriteViewsDts, scanViewsSync, writeViewsDts, } from "./scan-views.js";
1
+ export { type EvalsOptions, type SkybridgePluginOptions, skybridge, } from "./plugin.js";
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,KAAK,cAAc,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,SAAS,GACV,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
1
  export { skybridge, } from "./plugin.js";
2
- export { assertUniqueViewNames, discoverViewsSync, scanAndWriteViewsDts, scanViewsSync, writeViewsDts, } from "./scan-views.js";
3
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EAErB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,SAAS,GACV,MAAM,aAAa,CAAC"}
package/dist/plugin.d.ts CHANGED
@@ -1,17 +1,10 @@
1
- import type { PluginOption } from "vite";
1
+ import type { Plugin } from "vite";
2
2
  /**
3
- * Options for the eval runner wired in through the `evals` plugin option.
4
- * Mirrors `EvalsOptions` from `@skybridge/test`, which owns the runtime; the
5
- * shape is duplicated here so this package needs no dependency on it.
3
+ * Options for the eval runner, wired in through the `evals` plugin option and
4
+ * consumed by `@skybridge/test`. Defined here so the runtime package can
5
+ * import the shape while this package keeps no dependency on it.
6
6
  */
7
- export interface EvalsPluginOptions {
8
- model: {
9
- provider: "anthropic";
10
- name: string;
11
- apiKeyEnv?: string;
12
- } | {
13
- file: string;
14
- };
7
+ export interface EvalsOptions {
15
8
  temperature?: number;
16
9
  systemPrompt?: string;
17
10
  maxSteps?: number;
@@ -33,14 +26,11 @@ export interface SkybridgePluginOptions {
33
26
  */
34
27
  serverExternal?: string[];
35
28
  /**
36
- * Wires the eval runner into vitest: contributes `setupFiles`,
37
- * `globalSetup`, `provide` and `testTimeout` from `@skybridge/test`, loaded
38
- * lazily so production builds never touch it. Set it only in the config
39
- * vitest uses for evals; when omitted, no test config is contributed and
40
- * ordinary unit tests are unaffected. Requires `@skybridge/test` as a dev
41
- * dependency.
29
+ * Runs the app's eval scenarios against a real model: how to boot the server
30
+ * they talk to, plus defaults for the conversation. Point vitest at this
31
+ * config to run them. Requires `@skybridge/test` as a dev dependency.
42
32
  */
43
- evals?: EvalsPluginOptions;
33
+ evals?: EvalsOptions;
44
34
  }
45
35
  /**
46
36
  * Vite plugin that wires a Skybridge project's view files into Vite.
@@ -68,5 +58,5 @@ export interface SkybridgePluginOptions {
68
58
  * });
69
59
  * ```
70
60
  */
71
- export declare function skybridge(options?: SkybridgePluginOptions): PluginOption[];
61
+ export declare function skybridge(options?: SkybridgePluginOptions): Plugin;
72
62
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,YAAY,EAAiB,MAAM,MAAM,CAAC;AAchE;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EACD;QAAE,QAAQ,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3D;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC9B,CAAC;CACH;AAED,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,YAAY,EAAE,CAO1E"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAOlD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC9B,CAAC;CACH;AAED,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAElE"}
package/dist/plugin.js CHANGED
@@ -1,9 +1,7 @@
1
- import { createRequire } from "node:module";
2
1
  import { isAbsolute, relative, resolve } from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { assertUniqueViewNames, discoverViewsSync, scanViewsSync, writeViewsDts, } from "./scan-views.js";
2
+ import { fileURLToPath } from "node:url";
3
+ import { assertUniqueViewNames, discoverViewsSync, hasDefaultExport, scanViewsSync, writeViewsDts, } from "skybridge/views";
5
4
  import { transform as dataLlmTransform } from "./transform-data-llm.js";
6
- import { hasDefaultExport } from "./validate-view.js";
7
5
  const VIRTUAL_PREFIX = "/_skybridge/view/";
8
6
  const VIRTUAL_MODULE_PREFIX = "\0skybridge:view:";
9
7
  function buildVirtualEntry(viewFilePath) {
@@ -46,29 +44,10 @@ function getViewEntryPattern(viewsDir) {
46
44
  * ```
47
45
  */
48
46
  export function skybridge(options) {
49
- const plugins = [viewsPlugin(options)];
50
- const evals = options?.evals;
51
- if (evals !== undefined) {
52
- plugins.push(loadEvalsPlugin(evals));
53
- }
54
- return plugins;
47
+ return viewsPlugin(options);
55
48
  }
56
- /**
57
- * Resolves `@skybridge/test/plugin` from the user's project rather than from
58
- * this package, which never depends on it: the eval runtime is an optional
59
- * dev dependency of the app.
60
- */
61
- async function loadEvalsPlugin(evals) {
62
- const projectRequire = createRequire(resolve(process.cwd(), "package.json"));
63
- let resolved;
64
- try {
65
- resolved = projectRequire.resolve("@skybridge/test/plugin");
66
- }
67
- catch {
68
- throw new Error("The `evals` option requires the @skybridge/test package. Install it as a dev dependency.");
69
- }
70
- const module = (await import(pathToFileURL(resolved).href));
71
- return module.evals(evals);
49
+ function here(file) {
50
+ return fileURLToPath(new URL(file, import.meta.url));
72
51
  }
73
52
  function viewsPlugin(options) {
74
53
  const rawViewsDir = options?.viewsDir ?? "src/views";
@@ -95,7 +74,7 @@ function viewsPlugin(options) {
95
74
  for (const view of views) {
96
75
  input[view.name] = `${VIRTUAL_PREFIX}${view.name}`;
97
76
  }
98
- return {
77
+ const base = {
99
78
  base: "/assets",
100
79
  // Fixes "Invalid hook call" on createStore by forcing a single
101
80
  // copy of React. Under pnpm's isolated node_modules, zustand
@@ -146,6 +125,14 @@ function viewsPlugin(options) {
146
125
  },
147
126
  },
148
127
  };
128
+ return {
129
+ ...base,
130
+ test: {
131
+ setupFiles: [here("./evals/matchers.js")],
132
+ globalSetup: [here("./evals/global-setup.js")],
133
+ provide: { skybridgeEvals: options?.evals },
134
+ },
135
+ };
149
136
  },
150
137
  resolveId(id) {
151
138
  if (id.startsWith(VIRTUAL_PREFIX)) {
@@ -217,7 +204,7 @@ function viewsPlugin(options) {
217
204
  server.watcher.on("unlink", rescan);
218
205
  },
219
206
  async transform(code, id) {
220
- if (viewEntryPattern?.test(id) && !hasDefaultExport(code, id)) {
207
+ if (viewEntryPattern?.test(id) && !hasDefaultExport(code)) {
221
208
  this.warn(`View file "${id.split("/").pop()}" is missing a default export.`);
222
209
  }
223
210
  return await dataLlmTransform(code, id);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,qBAAqB,EAErB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAExE,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAC3C,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAqClD,SAAS,iBAAiB,CAAC,YAAoB;IAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO;QACL,4CAA4C;QAC5C,0BAA0B,UAAU,IAAI;QACxC,wCAAwC;QACxC,sCAAsC;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAChE,OAAO,IAAI,MAAM,CACf,GAAG,OAAO,mEAAmE,CAC9E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgC;IACxD,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAAC,OAAgC;IACnD,MAAM,WAAW,GAAG,OAAO,EAAE,QAAQ,IAAI,WAAW,CAAC;IACrD,IAAI,gBAAwB,CAAC;IAC7B,IAAI,WAAmB,CAAC;IACxB,IAAI,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,IAAI,gBAAwB,CAAC;IAE7B,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,KAAK;QACd,0EAA0E;QAC1E,4DAA4D;QAC5D,GAAG,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE;QAEvE,MAAM,CAAC,MAAM;YACX,WAAW,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAC3C,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC;gBACxC,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACtC,gBAAgB,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;YAEzD,MAAM,KAAK,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;YAClD,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAElC,MAAM,KAAK,GAA2B,EAAE,CAAC;YACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACrD,CAAC;YAED,MAAM,IAAI,GAAmB;gBAC3B,IAAI,EAAE,SAAS;gBACf,+DAA+D;gBAC/D,6DAA6D;gBAC7D,yDAAyD;gBACzD,qDAAqD;gBACrD,OAAO,EAAE;oBACP,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;iBAC/B;gBACD,KAAK,EAAE;oBACL,MAAM,EAAE,aAAa;oBACrB,WAAW,EAAE,IAAI;oBACjB,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,IAAI;oBACZ,YAAY,EAAE,KAAK;oBACnB,aAAa,EAAE;wBACb,KAAK;qBACN;iBACF;gBACD,+DAA+D;gBAC/D,iEAAiE;gBACjE,8DAA8D;gBAC9D,8DAA8D;gBAC9D,YAAY,EAAE;oBACZ,gEAAgE;oBAChE,8BAA8B;oBAC9B,OAAO,EAAE;wBACP,GAAG,gBAAgB,cAAc;wBACjC,GAAG,gBAAgB,oBAAoB;qBACxC;oBACD,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,CAAC;iBAC5D;gBACD,YAAY,EAAE;oBACZ,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;wBACzC,kEAAkE;wBAClE,iEAAiE;wBACjE,6DAA6D;wBAC7D,2DAA2D;wBAC3D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;4BACtB,OAAO;gCACL,OAAO,EAAE,yCAAyC,QAAQ,GAAG;6BAC9D,CAAC;wBACJ,CAAC;wBACD,qEAAqE;wBACrE,qEAAqE;wBACrE,+DAA+D;wBAC/D,4DAA4D;wBAC5D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;oBAC5B,CAAC;iBACF;aACF,CAAC;YAEF,OAAO;gBACL,GAAG,IAAI;gBACP,IAAI,EAAE;oBACJ,UAAU,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBACzC,WAAW,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;oBAC9C,OAAO,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE;iBAC5C;aACF,CAAC;QACJ,CAAC;QAED,SAAS,CAAC,EAAE;YACV,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,OAAO,GAAG,qBAAqB,GAAG,IAAI,EAAE,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,EAAE;YACL,IAAI,EAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;gBACpD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,IAAI,EAAE,CAAC;oBACT,OAAO,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,eAAe,CAAC,MAAqB;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBACjD,gBAAgB,GAAG,UAAU,CAAC,WAAW,CAAC;oBACxC,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;gBAC/B,WAAW,GAAG,IAAI,CAAC;gBACnB,gBAAgB,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACrC,gEAAgE;YAChE,mEAAmE;YACnE,IAAI,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;YACrC,MAAM,MAAM,GAAG,GAAG,EAAE;gBAClB,IAAI,CAAC;oBACH,2DAA2D;oBAC3D,6DAA6D;oBAC7D,kDAAkD;oBAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;oBAC3D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAE5D,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;wBACnC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CACvB,0BAA0B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,iEAAiE,CAC3H,CAAC;wBACJ,CAAC;oBACH,CAAC;oBACD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;wBACpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CACvB,0BAA0B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,aAAa,CACvE,CAAC;wBACJ,CAAC;oBACH,CAAC;oBACD,YAAY,GAAG,WAAW,CAAC;oBAE3B,qBAAqB,CAAC,KAAK,CAAC,CAAC;oBAC7B,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjD,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,iEAAiE;oBACjE,gEAAgE;oBAChE,6DAA6D;oBAC7D,+BAA+B;oBAC/B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CACxB,mCAAmC,OAAO,EAAE,CAC7C,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC;YAEF,sEAAsE;YACtE,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE;YACtB,IAAI,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,IAAI,CAAC,IAAI,CACP,cAAc,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,gCAAgC,CAClE,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skybridge/vite-plugin",
3
- "version": "0.0.0-dev.7aada9d",
3
+ "version": "0.0.0-dev.8a4b6f5",
4
4
  "description": "The Skybridge Vite plugin: view discovery, data-llm transforms, and eval wiring",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -12,6 +12,10 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "default": "./dist/index.js"
15
+ },
16
+ "./evals": {
17
+ "types": "./dist/evals/index.d.ts",
18
+ "default": "./dist/evals/index.js"
15
19
  }
16
20
  },
17
21
  "files": [
@@ -21,18 +25,26 @@
21
25
  "@babel/core": "^7.29.7"
22
26
  },
23
27
  "peerDependencies": {
24
- "vite": ">=7.3.1"
28
+ "skybridge": "^2.0.0",
29
+ "vite": ">=7.3.1",
30
+ "vitest": ">=4.1.0"
25
31
  },
26
32
  "devDependencies": {
27
33
  "@types/babel__core": "^7.20.5",
28
34
  "@types/node": "^24.13.3",
29
35
  "typescript": "^5.9.3",
30
36
  "vite": "^8.1.5",
31
- "vitest": "^4.1.10"
37
+ "vitest": "^4.1.10",
38
+ "skybridge": "0.0.0-dev.8a4b6f5"
32
39
  },
33
40
  "engines": {
34
41
  "node": ">=22.23.1"
35
42
  },
43
+ "peerDependenciesMeta": {
44
+ "vitest": {
45
+ "optional": true
46
+ }
47
+ },
36
48
  "scripts": {
37
49
  "build": "tsc -p tsconfig.json",
38
50
  "format": "biome check --write --error-on-warnings",
@@ -1,17 +0,0 @@
1
- export interface DiscoveredView {
2
- name: string;
3
- filePath: string;
4
- }
5
- export interface InvalidView {
6
- filePath: string;
7
- }
8
- export declare function scanViewsSync(viewsDir: string): {
9
- valid: DiscoveredView[];
10
- invalid: InvalidView[];
11
- };
12
- export declare function assertUniqueViewNames(views: DiscoveredView[]): void;
13
- export declare function discoverViewsSync(viewsDir: string): DiscoveredView[];
14
- export declare function generateViewsDts(views: DiscoveredView[]): string;
15
- export declare function writeViewsDts(projectRoot: string, views: DiscoveredView[]): void;
16
- export declare function scanAndWriteViewsDts(projectRoot?: string, viewsDir?: string): void;
17
- //# sourceMappingURL=scan-views.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scan-views.d.ts","sourceRoot":"","sources":["../src/scan-views.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC/C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB,CAmCA;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAenE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAIpE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,CAYhE;AAED,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,cAAc,EAAE,GACtB,IAAI,CAiBN;AAED,wBAAgB,oBAAoB,CAClC,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAON"}
@@ -1,88 +0,0 @@
1
- import { globSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { basename, dirname, isAbsolute, join, parse, resolve } from "node:path";
3
- import { hasDefaultExport } from "./validate-view.js";
4
- export function scanViewsSync(viewsDir) {
5
- const flatPattern = resolve(viewsDir, "*.{tsx,jsx}");
6
- const dirPattern = resolve(viewsDir, "*/index.{tsx,jsx}");
7
- const flatFiles = globSync(flatPattern).map((file) => ({
8
- name: parse(file).name,
9
- filePath: file,
10
- }));
11
- const dirFiles = globSync(dirPattern).map((file) => ({
12
- name: basename(dirname(file)),
13
- filePath: file,
14
- }));
15
- // A barrel file like `views/foo/index.tsx` (no default export) must not
16
- // falsely collide with a sibling `views/foo.tsx`. Drop top-level `index`
17
- // before splitting valid vs invalid.
18
- const candidates = [...flatFiles, ...dirFiles].filter((v) => v.name !== "index");
19
- const valid = [];
20
- const invalid = [];
21
- for (const candidate of candidates) {
22
- const code = readFileSync(candidate.filePath, "utf-8");
23
- if (hasDefaultExport(code, candidate.filePath)) {
24
- valid.push(candidate);
25
- }
26
- else {
27
- invalid.push({
28
- filePath: candidate.filePath,
29
- });
30
- }
31
- }
32
- return { valid, invalid };
33
- }
34
- export function assertUniqueViewNames(views) {
35
- const nameMap = new Map();
36
- for (const view of views) {
37
- const paths = nameMap.get(view.name) ?? [];
38
- paths.push(view.filePath);
39
- nameMap.set(view.name, paths);
40
- }
41
- for (const [name, paths] of nameMap) {
42
- if (paths.length > 1) {
43
- throw new Error(`skybridge: duplicate view name "${name}" resolved from:\n - ${paths.join("\n - ")}\nRename one of the files to avoid the conflict.`);
44
- }
45
- }
46
- }
47
- export function discoverViewsSync(viewsDir) {
48
- const { valid } = scanViewsSync(viewsDir);
49
- assertUniqueViewNames(valid);
50
- return valid;
51
- }
52
- export function generateViewsDts(views) {
53
- const entries = views.map((v) => ` "${v.name}": true;`).join("\n");
54
- return [
55
- "export {};",
56
- "",
57
- 'declare module "skybridge/server" {',
58
- " interface ViewNameRegistry {",
59
- entries,
60
- " }",
61
- "}",
62
- "",
63
- ].join("\n");
64
- }
65
- export function writeViewsDts(projectRoot, views) {
66
- const dir = join(projectRoot, ".skybridge");
67
- mkdirSync(dir, { recursive: true });
68
- const filePath = join(dir, "views.d.ts");
69
- const content = generateViewsDts(views);
70
- try {
71
- const existing = readFileSync(filePath, "utf-8");
72
- if (existing === content) {
73
- return;
74
- }
75
- }
76
- catch {
77
- // File doesn't exist yet
78
- }
79
- writeFileSync(filePath, content, "utf-8");
80
- }
81
- export function scanAndWriteViewsDts(projectRoot, viewsDir) {
82
- const root = projectRoot ?? process.cwd();
83
- const rawDir = viewsDir ?? "src/views";
84
- const resolvedDir = isAbsolute(rawDir) ? rawDir : resolve(root, rawDir);
85
- const views = discoverViewsSync(resolvedDir);
86
- writeViewsDts(root, views);
87
- }
88
- //# sourceMappingURL=scan-views.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scan-views.js","sourceRoot":"","sources":["../src/scan-views.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export declare function hasDefaultExport(code: string, _filePath?: string): boolean;
2
- //# sourceMappingURL=validate-view.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-view.d.ts","sourceRoot":"","sources":["../src/validate-view.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAM1E"}
@@ -1,9 +0,0 @@
1
- function stripComments(code) {
2
- return code.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
3
- }
4
- export function hasDefaultExport(code, _filePath) {
5
- const stripped = stripComments(code);
6
- return (/export\s+default\s/.test(stripped) ||
7
- /export\s*\{[^}]*\bas\s+default\b[^}]*}/.test(stripped));
8
- }
9
- //# sourceMappingURL=validate-view.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-view.js","sourceRoot":"","sources":["../src/validate-view.ts"],"names":[],"mappings":"AAAA,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAkB;IAC/D,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CACL,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACnC,wCAAwC,CAAC,IAAI,CAAC,QAAQ,CAAC,CACxD,CAAC;AACJ,CAAC"}