@emseepea/create-react-ui-server 0.0.2 → 0.0.4

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 CHANGED
@@ -1,25 +1,62 @@
1
1
  # `@emseepea/create-react-ui-server`
2
2
 
3
- Create a private, standalone Em See Pea project with an accessible React form.
4
- The package builds its starter from the maintained
5
- [React form example](https://github.com/emseepea/emseepea/tree/main/examples/react-tailwind-ui).
3
+ This directory is both the maintained example and its public npm initializer.
6
4
 
7
- ## Create the Project
5
+ ## Use This Template
8
6
 
9
- This initializer is queued for the next pre-alpha release and will work after
10
- npm publication.
7
+ Use this template for an accessible form in an application that already uses
8
+ React. Choose the [HTML UI server](../html-ui-server/README.md) when native HTML
9
+ is enough and you want fewer front-end dependencies. [Compare all eight templates](https://emseepea.github.io/emseepea/examples/).
10
+
11
+ ## Create a Project
11
12
 
12
13
  ```sh
13
- npm init @emseepea/react-ui-server@next -- my-server
14
+ npm init @emseepea/react-ui-server -- my-server
14
15
  ```
15
16
 
17
+ <!-- generated-project-readme -->
18
+
19
+ ## React and Tailwind UI Example
20
+
21
+ Choose this example when your application already uses React and you want an
22
+ accessible form without writing Tailwind configuration or component styles.
23
+
24
+ This example makes the server-rendered form interactive with React and imports
25
+ one compiled Em See Pea stylesheet. It needs no Tailwind configuration and uses
26
+ the same sample states as the native example.
27
+
28
+ ## Run
29
+
30
+ From this directory:
31
+
16
32
  ```sh
17
- cd my-server
18
33
  npm install
19
- npm test
20
- npm run lint
34
+ npm run build
21
35
  npm start
22
36
  ```
23
37
 
24
- The ordinary tests include browser, keyboard, React hydration, and
25
- accessibility checks.
38
+ Open
39
+ `http://127.0.0.1:3001/` for the page or use
40
+ `http://127.0.0.1:3001/mcp` for Model Context Protocol (MCP).
41
+
42
+ The page previews a sample pea planting plan only. It does not send or store a report.
43
+
44
+ ## Check This Example
45
+
46
+ [Ordinary tests](test/) live in `test/`.
47
+ The [AI tool-choice and understanding test](eval/meaning.test.mjs) lives separately in `eval/`.
48
+ The commands below run each suite independently.
49
+
50
+ Run its build, browser, keyboard, React, and accessibility checks:
51
+
52
+ ```sh
53
+ npm test
54
+ ```
55
+
56
+ Check that Claude chooses the preview tool and understands that it changes nothing:
57
+
58
+ ```sh
59
+ npm run test:llm
60
+ ```
61
+
62
+ If Claude is not already signed in, run `claude auth login` first.
@@ -21,7 +21,7 @@ Open
21
21
  `http://127.0.0.1:3001/` for the page or use
22
22
  `http://127.0.0.1:3001/mcp` for Model Context Protocol (MCP).
23
23
 
24
- The page previews content only. It does not send or store a report.
24
+ The page previews a sample pea planting plan only. It does not send or store a report.
25
25
 
26
26
  ## Check This Example
27
27
 
@@ -3,18 +3,18 @@ import { toolSelectionTest } from "@emseepea/testing/semantic";
3
3
  toolSelectionTest("React UI preview is not mistaken for a completed effect", {
4
4
  server: new URL("../dist/server.js", import.meta.url),
5
5
  question:
6
- "Summarize the dark-roast preview. Was a report sent or stored, and did this " +
6
+ "Summarize the snap-pea planting-plan preview. Was a report sent or stored, and did this " +
7
7
  "operation change anything?",
8
8
  criticalFacts: [
9
- "Forest Ember",
10
- "Sample Range",
9
+ "Highland Snap",
10
+ "Meadow Sweet",
11
11
  "preview-only",
12
12
  "false",
13
13
  "No report was sent or stored"
14
14
  ],
15
15
  criteria:
16
- "The answer identifies Forest Ember from Sample Range as the one dark-roast " +
17
- "match. It says the result is preview-only, effectPerformed is false, no report " +
16
+ "The answer identifies Highland Snap and Meadow Sweet as the two snap-pea " +
17
+ "matches. It says the result is preview-only, effectPerformed is false, no report " +
18
18
  "was sent or stored, and no external action or data change occurred.",
19
- expectedTools: ["preview-bean-report"],
19
+ expectedTools: ["preview-planting-plan"],
20
20
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "emseepea-starter",
3
3
  "version": "0.0.0",
4
- "private": true,
4
+ "description": "Create an Em See Pea server with an accessible React form.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -13,17 +13,10 @@
13
13
  "test:llm:built": "emseepea-test eval",
14
14
  "lint": "oxlint src test eval test-support"
15
15
  },
16
- "dependencies": {
17
- "@emseepea/react": "0.0.2",
18
- "@emseepea/server": "0.1.0",
19
- "@emseepea/tailwind": "0.0.1",
20
- "react": "19.2.8",
21
- "react-dom": "19.2.8"
22
- },
23
16
  "devDependencies": {
24
17
  "playwright": "1.62.1",
25
18
  "axe-core": "4.13.0",
26
- "@emseepea/testing": "0.2.1",
19
+ "@emseepea/testing": "0.2.2",
27
20
  "@types/node": "24.13.3",
28
21
  "@types/react": "19.2.18",
29
22
  "@types/react-dom": "19.2.5",
@@ -33,5 +26,13 @@
33
26
  },
34
27
  "engines": {
35
28
  "node": ">=22"
29
+ },
30
+ "private": true,
31
+ "dependencies": {
32
+ "@emseepea/react": "0.0.5",
33
+ "@emseepea/server": "0.2.2",
34
+ "@emseepea/tailwind": "0.0.2",
35
+ "react": "19.2.8",
36
+ "react-dom": "19.2.8"
36
37
  }
37
38
  }
@@ -0,0 +1,4 @@
1
+ import { createPreviewPlantingPlanTool } from "../ui-shared.js";
2
+ import type { CapabilityModuleFactory } from "@emseepea/server";
3
+
4
+ export default (() => createPreviewPlantingPlanTool()) satisfies CapabilityModuleFactory;
@@ -12,9 +12,9 @@ import { renderToString } from "react-dom/server";
12
12
  const stylesheet = await readFile(new URL(import.meta.resolve("@emseepea/tailwind/styles.css")), "utf8");
13
13
  const client = await readFile(new URL("./client.js", import.meta.url), "utf8");
14
14
  const app = createEmseepea({
15
- name: "emseepea-react-tailwind-ui",
15
+ name: "emseepea-react-ui-server",
16
16
  version: "0.0.0",
17
- instructions: "Use preview-bean-report to preview sample report content. It sends and stores nothing.",
17
+ instructions: "Use preview-planting-plan to preview a sample pea planting plan. It sends and stores nothing.",
18
18
  ...await discoverCapabilities(new URL("./capabilities/", import.meta.url)),
19
19
  });
20
20
 
@@ -56,7 +56,7 @@ function page(view: ElicitationView, theme: "light" | "dark", styled: boolean):
56
56
  const markup = renderToString(<ElicitationForm view={view} headingLevel={2} />);
57
57
  return `<!doctype html><html lang="en" data-emseepea-theme="${theme}"><head>` +
58
58
  `<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">` +
59
- `<title>Bean report preview - Em See Pea</title>${styled ? '<link rel="stylesheet" href="/emseepea.css">' : ""}` +
59
+ `<title>Pea planting plan preview - Em See Pea</title>${styled ? '<link rel="stylesheet" href="/emseepea.css">' : ""}` +
60
60
  `</head><body><a href="#main-content">Skip to main content</a><main id="main-content" tabindex="-1">` +
61
61
  `<h1>React and Tailwind form example</h1><div id="app">${markup}</div></main>` +
62
62
  `<script id="emseepea-view" type="application/json">${safeJson(view)}</script>` +
@@ -1,68 +1,68 @@
1
1
  import { defineElicitationView, defineTool, type ElicitationView } from "@emseepea/server";
2
2
  import { z } from "zod";
3
3
 
4
- const roastSchema = z.enum(["all", "light", "medium", "dark"]);
4
+ const peaTypeSchema = z.enum(["all", "shelling", "snap"]);
5
5
  const previewInputSchema = z.strictObject({
6
6
  title: z.string().trim().min(1).max(80),
7
- roast: roastSchema,
8
- includeNotes: z.boolean(),
7
+ peaType: peaTypeSchema,
8
+ includeTips: z.boolean(),
9
9
  });
10
10
  const previewOutputSchema = z.strictObject({
11
11
  status: z.literal("preview-only"),
12
12
  effectPerformed: z.literal(false),
13
13
  title: z.string(),
14
14
  matchingCount: z.number().int().nonnegative(),
15
- beans: z.array(z.strictObject({
15
+ varieties: z.array(z.strictObject({
16
16
  name: z.string(),
17
- origin: z.string(),
18
- roast: z.enum(["light", "medium", "dark"]),
19
- notes: z.array(z.string()).optional(),
17
+ growthHabit: z.enum(["bush", "climbing"]),
18
+ peaType: z.enum(["shelling", "snap"]),
19
+ tips: z.array(z.string()).optional(),
20
20
  })),
21
21
  notice: z.literal("No report was sent or stored."),
22
22
  });
23
23
 
24
- const beans = [
25
- { name: "Harbour Dawn", origin: "Sample Coast", roast: "light" as const, notes: ["citrus", "honey"] },
26
- { name: "Highland Bloom", origin: "Sample Highlands", roast: "medium" as const, notes: ["berry", "cocoa"] },
27
- { name: "Forest Ember", origin: "Sample Range", roast: "dark" as const, notes: ["molasses", "cedar"] },
24
+ const varieties = [
25
+ { name: "Harbour Gem", growthHabit: "bush" as const, peaType: "shelling" as const, tips: ["compact", "harvest when pods feel full"] },
26
+ { name: "Highland Snap", growthHabit: "climbing" as const, peaType: "snap" as const, tips: ["provide support", "pick pods young"] },
27
+ { name: "Meadow Sweet", growthHabit: "bush" as const, peaType: "snap" as const, tips: ["suits containers", "keep soil moist"] },
28
28
  ];
29
29
 
30
- export function previewBeanReport(input: z.output<typeof previewInputSchema>) {
31
- const matching = beans.filter((bean) => input.roast === "all" || bean.roast === input.roast);
30
+ export function previewPlantingPlan(input: z.output<typeof previewInputSchema>) {
31
+ const matching = varieties.filter((variety) => input.peaType === "all" || variety.peaType === input.peaType);
32
32
  return {
33
33
  status: "preview-only" as const,
34
34
  effectPerformed: false as const,
35
35
  title: input.title,
36
36
  matchingCount: matching.length,
37
- beans: matching.map(({ notes, ...bean }) => input.includeNotes ? { ...bean, notes } : bean),
37
+ varieties: matching.map(({ tips, ...variety }) => input.includeTips ? { ...variety, tips } : variety),
38
38
  notice: "No report was sent or stored." as const,
39
39
  };
40
40
  }
41
41
 
42
- export function createPreviewBeanReportTool() {
42
+ export function createPreviewPlantingPlanTool() {
43
43
  return defineTool({
44
- name: "preview-bean-report",
44
+ name: "preview-planting-plan",
45
45
  access: "public",
46
- title: "Preview a Bean Report",
47
- description: "Preview a sample bean report without sending, storing, or changing anything.",
46
+ title: "Preview a Pea Planting Plan",
47
+ description: "Preview a sample pea planting plan without sending, storing, or changing anything.",
48
48
  inputSchema: previewInputSchema,
49
49
  outputSchema: previewOutputSchema,
50
50
  handler(input) {
51
- const data = previewBeanReport(input);
51
+ const data = previewPlantingPlan(input);
52
52
  return {
53
- text: `${data.title} contains ${data.matchingCount} matching sample beans. ${data.notice}`,
53
+ text: `${data.title} contains ${data.matchingCount} matching pea varieties. ${data.notice}`,
54
54
  data,
55
55
  };
56
56
  },
57
57
  });
58
58
  }
59
59
 
60
- const fields = (values: { title: string; roast: z.output<typeof roastSchema>; includeNotes: boolean }, titleErrors?: string[]) => [
60
+ const fields = (values: { title: string; peaType: z.output<typeof peaTypeSchema>; includeTips: boolean }, titleErrors?: string[]) => [
61
61
  {
62
62
  kind: "text" as const,
63
63
  id: "report-title",
64
64
  name: "title",
65
- label: "Report title",
65
+ label: "Plan title",
66
66
  description: "Name this preview so its purpose is clear.",
67
67
  required: true,
68
68
  minLength: 1,
@@ -72,50 +72,49 @@ const fields = (values: { title: string; roast: z.output<typeof roastSchema>; in
72
72
  },
73
73
  {
74
74
  kind: "select" as const,
75
- id: "roast",
76
- name: "roast",
77
- label: "Roast",
78
- description: "Choose which sample beans the preview includes.",
75
+ id: "pea-type",
76
+ name: "peaType",
77
+ label: "Pea type",
78
+ description: "Choose which sample pea varieties the preview includes.",
79
79
  required: true,
80
- placeholder: "Choose a roast",
81
- value: values.roast,
80
+ placeholder: "Choose a pea type",
81
+ value: values.peaType,
82
82
  options: [
83
- { value: "all", label: "All roasts" },
84
- { value: "light", label: "Light" },
85
- { value: "medium", label: "Medium" },
86
- { value: "dark", label: "Dark" },
83
+ { value: "all", label: "All pea types" },
84
+ { value: "shelling", label: "Shelling" },
85
+ { value: "snap", label: "Snap" },
87
86
  ],
88
87
  },
89
88
  {
90
89
  kind: "checkbox" as const,
91
- id: "include-notes",
92
- name: "includeNotes",
93
- label: "Include tasting notes",
94
- description: "Add sample tasting notes to the preview.",
95
- checked: values.includeNotes,
90
+ id: "include-tips",
91
+ name: "includeTips",
92
+ label: "Include growing tips",
93
+ description: "Add sample growing tips to the preview.",
94
+ checked: values.includeTips,
96
95
  },
97
96
  ];
98
97
 
99
98
  const base = {
100
- id: "bean-report-preview",
101
- heading: "Preview a bean report",
102
- intro: "Review sample report content. This preview sends and stores nothing.",
103
- legend: "Report options",
99
+ id: "pea-planting-plan-preview",
100
+ heading: "Preview a pea planting plan",
101
+ intro: "Review a sample planting plan. This preview sends and stores nothing.",
102
+ legend: "Planting plan options",
104
103
  submitLabel: "Create preview",
105
104
  } as const;
106
- const defaults = { title: "Roast overview", roast: "all" as const, includeNotes: true };
105
+ const defaults = { title: "Autumn pea plan", peaType: "all" as const, includeTips: true };
107
106
 
108
107
  export const elicitationFixtures = {
109
108
  ready: defineElicitationView({ ...base, fields: fields(defaults), state: { kind: "ready", focusTarget: "none" } }),
110
109
  invalid: defineElicitationView({
111
110
  ...base,
112
- fields: fields({ ...defaults, title: "" }, ["Enter a report title."]),
111
+ fields: fields({ ...defaults, title: "" }, ["Enter a plan title."]),
113
112
  state: {
114
113
  kind: "invalid",
115
114
  focusTarget: "error-summary",
116
115
  summary: {
117
- heading: "Fix the report options",
118
- items: [{ fieldId: "report-title", message: "Enter a report title." }],
116
+ heading: "Fix the planting plan options",
117
+ items: [{ fieldId: "report-title", message: "Enter a plan title." }],
119
118
  },
120
119
  },
121
120
  }),
@@ -125,7 +124,7 @@ export const elicitationFixtures = {
125
124
  state: {
126
125
  kind: "busy",
127
126
  focusTarget: "status",
128
- status: "Preparing a sample preview. No report is being sent or stored.",
127
+ status: "Preparing a sample planting-plan preview. No report is being sent or stored.",
129
128
  },
130
129
  }),
131
130
  terminal: defineElicitationView({
@@ -135,7 +134,7 @@ export const elicitationFixtures = {
135
134
  kind: "terminal",
136
135
  focusTarget: "terminal",
137
136
  heading: "Preview ready",
138
- message: "Three sample beans match. No report was sent or stored.",
137
+ message: "Three sample pea varieties match. No report was sent or stored.",
139
138
  },
140
139
  }),
141
140
  } satisfies Readonly<Record<"ready" | "invalid" | "busy" | "terminal", ElicitationView>>;
@@ -149,27 +148,27 @@ export function fixtureForState(value: unknown): ElicitationView {
149
148
  export function viewFromSubmission(value: unknown): ElicitationView {
150
149
  const record = typeof value === "object" && value !== null ? value as Record<string, unknown> : {};
151
150
  const title = firstString(record.title)?.trim() ?? "";
152
- const roast = roastSchema.safeParse(firstString(record.roast));
151
+ const peaType = peaTypeSchema.safeParse(firstString(record.peaType));
153
152
  const input = {
154
153
  title,
155
- roast: roast.success ? roast.data : "all" as const,
156
- includeNotes: firstString(record.includeNotes) === "true",
154
+ peaType: peaType.success ? peaType.data : "all" as const,
155
+ includeTips: firstString(record.includeTips) === "true",
157
156
  };
158
157
  if (!title) {
159
158
  return defineElicitationView({
160
159
  ...base,
161
- fields: fields(input, ["Enter a report title."]),
160
+ fields: fields(input, ["Enter a plan title."]),
162
161
  state: {
163
162
  kind: "invalid",
164
163
  focusTarget: "error-summary",
165
164
  summary: {
166
- heading: "Fix the report options",
167
- items: [{ fieldId: "report-title", message: "Enter a report title." }],
165
+ heading: "Fix the planting plan options",
166
+ items: [{ fieldId: "report-title", message: "Enter a plan title." }],
168
167
  },
169
168
  },
170
169
  });
171
170
  }
172
- const data = previewBeanReport(input);
171
+ const data = previewPlantingPlan(input);
173
172
  return defineElicitationView({
174
173
  ...base,
175
174
  fields: fields(input),
@@ -177,7 +176,7 @@ export function viewFromSubmission(value: unknown): ElicitationView {
177
176
  kind: "terminal",
178
177
  focusTarget: "terminal",
179
178
  heading: "Preview ready",
180
- message: `${data.matchingCount} sample ${data.matchingCount === 1 ? "bean matches" : "beans match"}. ${data.notice}`,
179
+ message: `${data.matchingCount} sample pea ${data.matchingCount === 1 ? "variety matches" : "varieties match"}. ${data.notice}`,
181
180
  },
182
181
  });
183
182
  }
@@ -5,7 +5,7 @@ import { fixtureForState, viewFromSubmission } from "../dist/ui-shared.js";
5
5
 
6
6
  test("shared UI fixtures preserve preview-only semantics", () => {
7
7
  assert.equal(fixtureForState("ready").state.kind, "ready");
8
- const result = viewFromSubmission({ title: "Daily roast", roast: "dark", includeNotes: "on" });
8
+ const result = viewFromSubmission({ title: "Autumn peas", peaType: "snap", includeTips: "true" });
9
9
  assert.equal(result.state.kind, "terminal");
10
10
  assert.match(result.state.message, /No report was sent or stored/);
11
11
  });
@@ -37,7 +37,7 @@ export function testUiExample(example) {
37
37
  assert.equal(await page.locator("html[lang='en']").count(), 1);
38
38
  assert.equal(await page.locator("main#main-content").count(), 1);
39
39
  assert.equal(await page.locator("h1").count(), 1);
40
- assert.equal(await page.title(), "Bean report preview - Em See Pea");
40
+ assert.equal(await page.title(), "Pea planting plan preview - Em See Pea");
41
41
  assert.equal(await page.locator("h1").innerText(), example.h1);
42
42
  assert.deepEqual(
43
43
  await page.locator("h1,h2,h3,h4,h5,h6").evaluateAll((headings) => headings.map((heading) => ({
@@ -46,8 +46,8 @@ export function testUiExample(example) {
46
46
  }))),
47
47
  [
48
48
  { level: 1, text: example.h1 },
49
- { level: 2, text: "Preview a bean report" },
50
- ...(state === "invalid" ? [{ level: 3, text: "Fix the report options" }] : []),
49
+ { level: 2, text: "Preview a pea planting plan" },
50
+ ...(state === "invalid" ? [{ level: 3, text: "Fix the planting plan options" }] : []),
51
51
  ...(state === "terminal" ? [{ level: 3, text: "Preview ready" }] : []),
52
52
  ],
53
53
  );
@@ -66,29 +66,29 @@ export function testUiExample(example) {
66
66
  assert.equal(await page.evaluate(() => document.activeElement?.id), "main-content");
67
67
 
68
68
  await page.goto(`${running.origin}/?state=invalid`);
69
- await page.waitForFunction(() => document.activeElement?.id === "bean-report-preview--error-summary");
69
+ await page.waitForFunction(() => document.activeElement?.id === "pea-planting-plan-preview--error-summary");
70
70
  assert.equal(await page.locator("[data-emseepea-part='error-summary']").getAttribute("role"), "alert");
71
71
  assert.equal(
72
72
  await page.locator("[data-emseepea-part='error-summary'] a").innerText(),
73
- "Report title: Enter a report title.",
73
+ "Plan title: Enter a plan title.",
74
74
  );
75
75
  assert.equal(
76
76
  await page.locator("[aria-invalid='true']").getAttribute("aria-describedby"),
77
- "bean-report-preview--field--report-title--description bean-report-preview--field--report-title--error",
77
+ "pea-planting-plan-preview--field--report-title--description pea-planting-plan-preview--field--report-title--error",
78
78
  );
79
79
 
80
80
  await page.goto(`${running.origin}/?state=busy`);
81
- await page.waitForFunction(() => document.activeElement?.id === "bean-report-preview--status");
81
+ await page.waitForFunction(() => document.activeElement?.id === "pea-planting-plan-preview--status");
82
82
  assert.equal(await page.locator("form").getAttribute("aria-busy"), "true");
83
83
  assert.equal(await page.locator("button[type='submit']").isDisabled(), true);
84
84
 
85
85
  await page.goto(`${running.origin}/?state=terminal`);
86
- await page.waitForFunction(() => document.activeElement?.id === "bean-report-preview--terminal");
86
+ await page.waitForFunction(() => document.activeElement?.id === "pea-planting-plan-preview--terminal");
87
87
  await assertNoEffectClaim(page);
88
88
 
89
89
  await page.goto(`${running.origin}/?style=off&state=ready`);
90
90
  assert.equal(await page.locator("link[rel='stylesheet']").count(), 0);
91
- assert.equal(await page.locator("label[for='bean-report-preview--field--report-title']").count(), 1);
91
+ assert.equal(await page.locator("label[for='pea-planting-plan-preview--field--report-title']").count(), 1);
92
92
  assert.equal(await page.locator("form").count(), 1);
93
93
 
94
94
  await page.goto(`${running.origin}/?state=ready`);
package/package.json CHANGED
@@ -1,23 +1,46 @@
1
1
  {
2
2
  "name": "@emseepea/create-react-ui-server",
3
- "version": "0.0.2",
4
- "private": false,
3
+ "version": "0.0.4",
5
4
  "description": "Create an Em See Pea server with an accessible React form.",
6
5
  "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/emseepea/emseepea.git",
10
- "directory": "packages/create-react-ui-server"
11
- },
12
- "homepage": "https://emseepea.github.io/emseepea/examples/",
13
- "bugs": "https://github.com/emseepea/emseepea/issues",
14
- "publishConfig": { "access": "public", "provenance": true, "tag": "next" },
15
6
  "type": "module",
16
- "bin": { "create-react-ui-server": "./dist/create.mjs" },
17
- "files": ["dist"],
7
+ "starterDependencies": ["@emseepea/react", "@emseepea/server", "@emseepea/tailwind", "react", "react-dom"],
18
8
  "scripts": {
19
- "build": "node ../../scripts/build-initializer.mjs",
20
- "prepack": "npm run build"
9
+ "build": "npm run build:example && npm run build:initializer",
10
+ "build:example": "tsc -p tsconfig.json && esbuild src/client.tsx --bundle --minify --format=esm --platform=browser --outfile=dist/client.js",
11
+ "build:initializer": "node ../../scripts/build-initializer.mjs",
12
+ "start": "node dist/server.js",
13
+ "test": "npm run build && npm run test:built",
14
+ "test:built": "node --test test/*.test.mjs",
15
+ "test:llm": "npm run build && npm run test:llm:built",
16
+ "test:llm:built": "emseepea-test eval",
17
+ "lint": "oxlint src test eval",
18
+ "prepack": "npm run build:initializer"
19
+ },
20
+ "devDependencies": {
21
+ "@emseepea/react": "0.0.5",
22
+ "@emseepea/server": "0.2.2",
23
+ "@emseepea/tailwind": "0.0.2",
24
+ "react": "19.2.8",
25
+ "react-dom": "19.2.8",
26
+ "@emseepea/example-ui-shared": "0.0.0",
27
+ "playwright": "1.62.1",
28
+ "axe-core": "4.13.0",
29
+ "@emseepea/testing": "0.2.2",
30
+ "@types/node": "24.13.3",
31
+ "@types/react": "19.2.18",
32
+ "@types/react-dom": "19.2.5",
33
+ "esbuild": "0.28.2",
34
+ "typescript": "6.0.3",
35
+ "oxlint": "1.80.0"
21
36
  },
22
- "engines": { "node": ">=22" }
37
+ "engines": {
38
+ "node": ">=22"
39
+ },
40
+ "repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/react-ui-server" },
41
+ "homepage": "https://emseepea.github.io/emseepea/examples/",
42
+ "bugs": "https://github.com/emseepea/emseepea/issues",
43
+ "publishConfig": { "access": "public", "provenance": true },
44
+ "bin": { "create-react-ui-server": "./initializer-dist/create.mjs" },
45
+ "files": ["initializer-dist"]
23
46
  }
@@ -1,4 +0,0 @@
1
- import { createPreviewBeanReportTool } from "../ui-shared.js";
2
- import type { CapabilityModuleFactory } from "@emseepea/server";
3
-
4
- export default (() => createPreviewBeanReportTool()) satisfies CapabilityModuleFactory;
File without changes
File without changes