@supernal/interface 1.0.12 → 1.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.
Files changed (57) hide show
  1. package/dist/cjs/names/Components.js +13 -0
  2. package/dist/cjs/names/Components.js.map +1 -1
  3. package/dist/cjs/src/browser.js +6 -2
  4. package/dist/cjs/src/browser.js.map +1 -1
  5. package/dist/cjs/src/cli/upgrade.js +305 -0
  6. package/dist/cjs/src/cli/upgrade.js.map +1 -0
  7. package/dist/cjs/src/index.js +18 -1
  8. package/dist/cjs/src/index.js.map +1 -1
  9. package/dist/cjs/src/tracking/SITrackingProvider.js +126 -0
  10. package/dist/cjs/src/tracking/SITrackingProvider.js.map +1 -0
  11. package/dist/cjs/src/tracking/hooks.js +233 -0
  12. package/dist/cjs/src/tracking/hooks.js.map +1 -0
  13. package/dist/cjs/src/tracking/index.js +67 -0
  14. package/dist/cjs/src/tracking/index.js.map +1 -0
  15. package/dist/cjs/src/tracking/tracker.js +289 -0
  16. package/dist/cjs/src/tracking/tracker.js.map +1 -0
  17. package/dist/esm/names/Components.d.ts +12 -0
  18. package/dist/esm/names/Components.d.ts.map +1 -1
  19. package/dist/esm/names/Components.js +13 -0
  20. package/dist/esm/names/Components.js.map +1 -1
  21. package/dist/esm/names/index.d.ts +12 -0
  22. package/dist/esm/names/index.d.ts.map +1 -1
  23. package/dist/esm/src/browser.d.ts +2 -0
  24. package/dist/esm/src/browser.d.ts.map +1 -1
  25. package/dist/esm/src/browser.js +2 -0
  26. package/dist/esm/src/browser.js.map +1 -1
  27. package/dist/esm/src/cli/upgrade.d.ts +17 -0
  28. package/dist/esm/src/cli/upgrade.d.ts.map +1 -0
  29. package/dist/esm/src/cli/upgrade.js +270 -0
  30. package/dist/esm/src/cli/upgrade.js.map +1 -0
  31. package/dist/esm/src/index.d.ts +3 -0
  32. package/dist/esm/src/index.d.ts.map +1 -1
  33. package/dist/esm/src/index.js +4 -0
  34. package/dist/esm/src/index.js.map +1 -1
  35. package/dist/esm/src/tracking/SITrackingProvider.d.ts +64 -0
  36. package/dist/esm/src/tracking/SITrackingProvider.d.ts.map +1 -0
  37. package/dist/esm/src/tracking/SITrackingProvider.js +82 -0
  38. package/dist/esm/src/tracking/SITrackingProvider.js.map +1 -0
  39. package/dist/esm/src/tracking/hooks.d.ts +112 -0
  40. package/dist/esm/src/tracking/hooks.d.ts.map +1 -0
  41. package/dist/esm/src/tracking/hooks.js +215 -0
  42. package/dist/esm/src/tracking/hooks.js.map +1 -0
  43. package/dist/esm/src/tracking/index.d.ts +48 -0
  44. package/dist/esm/src/tracking/index.d.ts.map +1 -0
  45. package/dist/esm/src/tracking/index.js +51 -0
  46. package/dist/esm/src/tracking/index.js.map +1 -0
  47. package/dist/esm/src/tracking/tracker.d.ts +121 -0
  48. package/dist/esm/src/tracking/tracker.d.ts.map +1 -0
  49. package/dist/esm/src/tracking/tracker.js +284 -0
  50. package/dist/esm/src/tracking/tracker.js.map +1 -0
  51. package/package.json +14 -4
  52. package/src/claude/agents/si-mcp.md +136 -0
  53. package/src/claude/agents/si-react.md +136 -0
  54. package/src/claude/agents/si-tools.md +109 -0
  55. package/src/claude/skills/si-add-provider/SKILL.md +88 -0
  56. package/src/claude/skills/si-add-tool/SKILL.md +66 -0
  57. package/src/claude/skills/si-setup-mcp-oss/SKILL.md +115 -0
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Supernal Interface Interaction Tracking
3
+ *
4
+ * Tracks user interactions with SI components for analytics and AI analysis.
5
+ * Batches events to minimize network requests and handles offline gracefully.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ /**
10
+ * SI Tracker - Core tracking class
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const tracker = new SITracker({ endpoint: '/api/analytics' });
15
+ * tracker.track('PostCard', 'view', 'post-123');
16
+ * ```
17
+ */
18
+ export class SITracker {
19
+ constructor(config = {}) {
20
+ this.queue = [];
21
+ this.flushInterval = null;
22
+ this.engagementSessions = new Map();
23
+ this.scrollState = {
24
+ maxDepth: 0,
25
+ lastReportedDepth: 0,
26
+ lastUpdateTime: Date.now(),
27
+ };
28
+ this.userId = null;
29
+ this.config = {
30
+ endpoint: config.endpoint ?? '/api/v1/analytics',
31
+ batchSize: config.batchSize ?? 10,
32
+ flushIntervalMs: config.flushIntervalMs ?? 5000,
33
+ minEngagementMs: config.minEngagementMs ?? 3000,
34
+ scrollDebounceMs: config.scrollDebounceMs ?? 500,
35
+ debug: config.debug ?? false,
36
+ customFetch: config.customFetch ?? fetch,
37
+ };
38
+ this.isClient = typeof window !== 'undefined';
39
+ this.sessionId = this.generateSessionId();
40
+ if (this.isClient) {
41
+ this.startFlushInterval();
42
+ this.setupBeforeUnload();
43
+ }
44
+ }
45
+ /** Generate a unique session ID */
46
+ generateSessionId() {
47
+ if (!this.isClient)
48
+ return 'server-session';
49
+ // Try to reuse session ID from sessionStorage
50
+ const stored = sessionStorage.getItem('si_session_id');
51
+ if (stored)
52
+ return stored;
53
+ const id = `si_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`;
54
+ sessionStorage.setItem('si_session_id', id);
55
+ return id;
56
+ }
57
+ /** Log debug message */
58
+ log(...args) {
59
+ if (this.config.debug) {
60
+ console.log('[SI Tracking]', ...args);
61
+ }
62
+ }
63
+ /** Set the current user ID for tracking */
64
+ setUserId(userId) {
65
+ this.userId = userId;
66
+ }
67
+ /** Get current session ID */
68
+ getSessionId() {
69
+ return this.sessionId;
70
+ }
71
+ /** Get queue length (for testing) */
72
+ getQueueLength() {
73
+ return this.queue.length;
74
+ }
75
+ /**
76
+ * Track an interaction
77
+ */
78
+ track(componentId, action, targetId, metadata) {
79
+ if (!this.isClient)
80
+ return;
81
+ const interaction = {
82
+ componentId,
83
+ action,
84
+ targetId,
85
+ metadata,
86
+ timestamp: Date.now(),
87
+ sessionId: this.sessionId,
88
+ };
89
+ this.queue.push(interaction);
90
+ this.log('Queued:', action, targetId);
91
+ // Flush if queue is full
92
+ if (this.queue.length >= this.config.batchSize) {
93
+ this.flush();
94
+ }
95
+ }
96
+ /** Alias for track - for click events */
97
+ trackClick(componentId, action, targetId, metadata) {
98
+ this.track(componentId, action, targetId, metadata);
99
+ }
100
+ /** Track view (impression) of a component */
101
+ trackView(componentId, targetId) {
102
+ this.track(componentId, 'view', targetId);
103
+ }
104
+ /** Start engagement tracking for a target */
105
+ startEngagement(targetId) {
106
+ if (!this.isClient)
107
+ return;
108
+ this.engagementSessions.set(targetId, {
109
+ targetId,
110
+ startTime: Date.now(),
111
+ scrollDepth: 0,
112
+ interactions: 0,
113
+ });
114
+ this.log('Engagement started:', targetId);
115
+ }
116
+ /** Record an interaction during engagement */
117
+ recordEngagementInteraction(targetId) {
118
+ const session = this.engagementSessions.get(targetId);
119
+ if (session) {
120
+ session.interactions++;
121
+ }
122
+ }
123
+ /** Update scroll depth for engagement session */
124
+ updateEngagementScrollDepth(targetId, depth) {
125
+ const session = this.engagementSessions.get(targetId);
126
+ if (session && depth > session.scrollDepth) {
127
+ session.scrollDepth = depth;
128
+ }
129
+ }
130
+ /** End engagement tracking and log the session */
131
+ endEngagement(targetId, componentId = 'Content') {
132
+ if (!this.isClient)
133
+ return;
134
+ const session = this.engagementSessions.get(targetId);
135
+ if (!session)
136
+ return;
137
+ const duration = Date.now() - session.startTime;
138
+ // Only track if engagement was meaningful
139
+ if (duration >= this.config.minEngagementMs) {
140
+ this.track(componentId, 'view', targetId, {
141
+ engagementDuration: duration,
142
+ scrollDepth: session.scrollDepth,
143
+ interactions: session.interactions,
144
+ });
145
+ this.log('Engagement ended:', targetId, { duration, ...session });
146
+ }
147
+ this.engagementSessions.delete(targetId);
148
+ }
149
+ /** Track scroll depth in feed */
150
+ trackScrollDepth(depth, componentId = 'Feed') {
151
+ if (!this.isClient)
152
+ return;
153
+ const now = Date.now();
154
+ // Only update if depth increased
155
+ if (depth > this.scrollState.maxDepth) {
156
+ this.scrollState.maxDepth = depth;
157
+ }
158
+ // Debounce reporting
159
+ if (now - this.scrollState.lastUpdateTime < this.config.scrollDebounceMs) {
160
+ return;
161
+ }
162
+ // Report at 25%, 50%, 75%, 100% milestones
163
+ const milestones = [25, 50, 75, 100];
164
+ const currentMilestone = milestones.find((m) => this.scrollState.maxDepth >= m && this.scrollState.lastReportedDepth < m);
165
+ if (currentMilestone) {
166
+ this.track(componentId, 'scroll', undefined, {
167
+ depth: currentMilestone,
168
+ maxDepth: this.scrollState.maxDepth,
169
+ });
170
+ this.scrollState.lastReportedDepth = currentMilestone;
171
+ this.log('Scroll milestone:', currentMilestone);
172
+ }
173
+ this.scrollState.lastUpdateTime = now;
174
+ }
175
+ /** Reset scroll tracking (e.g., on page navigation) */
176
+ resetScrollTracking() {
177
+ this.scrollState = {
178
+ maxDepth: 0,
179
+ lastReportedDepth: 0,
180
+ lastUpdateTime: Date.now(),
181
+ };
182
+ }
183
+ /** Start periodic flush interval */
184
+ startFlushInterval() {
185
+ if (this.flushInterval)
186
+ return;
187
+ this.flushInterval = setInterval(() => {
188
+ this.flush();
189
+ }, this.config.flushIntervalMs);
190
+ }
191
+ /** Stop flush interval */
192
+ stopFlushInterval() {
193
+ if (this.flushInterval) {
194
+ clearInterval(this.flushInterval);
195
+ this.flushInterval = null;
196
+ }
197
+ }
198
+ /** Setup beforeunload handler to flush remaining events */
199
+ setupBeforeUnload() {
200
+ window.addEventListener('beforeunload', () => {
201
+ // End all engagement sessions
202
+ for (const targetId of this.engagementSessions.keys()) {
203
+ this.endEngagement(targetId);
204
+ }
205
+ // Use sendBeacon for reliable delivery
206
+ this.flushWithBeacon();
207
+ });
208
+ // Also handle visibility change for mobile
209
+ document.addEventListener('visibilitychange', () => {
210
+ if (document.visibilityState === 'hidden') {
211
+ this.flushWithBeacon();
212
+ }
213
+ });
214
+ }
215
+ /** Flush queued events to the API */
216
+ async flush() {
217
+ if (!this.isClient || this.queue.length === 0)
218
+ return;
219
+ const events = [...this.queue];
220
+ this.queue = [];
221
+ this.log('Flushing', events.length, 'events');
222
+ try {
223
+ const response = await this.config.customFetch(this.config.endpoint, {
224
+ method: 'POST',
225
+ headers: {
226
+ 'Content-Type': 'application/json',
227
+ },
228
+ body: JSON.stringify({
229
+ events,
230
+ userId: this.userId,
231
+ }),
232
+ });
233
+ if (!response.ok) {
234
+ // Re-queue events on failure (with limit to prevent infinite growth)
235
+ if (this.queue.length < this.config.batchSize * 3) {
236
+ this.queue.unshift(...events);
237
+ }
238
+ this.log('Flush failed, re-queued');
239
+ }
240
+ }
241
+ catch (error) {
242
+ // Re-queue events on network error
243
+ if (this.queue.length < this.config.batchSize * 3) {
244
+ this.queue.unshift(...events);
245
+ }
246
+ console.warn('[SI Tracking] Failed to flush events:', error);
247
+ }
248
+ }
249
+ /** Flush using sendBeacon (for unload events) */
250
+ flushWithBeacon() {
251
+ if (!this.isClient || this.queue.length === 0)
252
+ return;
253
+ const events = [...this.queue];
254
+ this.queue = [];
255
+ try {
256
+ const blob = new Blob([JSON.stringify({ events, userId: this.userId })], {
257
+ type: 'application/json',
258
+ });
259
+ navigator.sendBeacon(this.config.endpoint, blob);
260
+ this.log('Beacon sent', events.length, 'events');
261
+ }
262
+ catch (error) {
263
+ console.warn('[SI Tracking] Beacon failed:', error);
264
+ }
265
+ }
266
+ /** Cleanup (for testing or unmounting) */
267
+ destroy() {
268
+ this.stopFlushInterval();
269
+ this.flush();
270
+ this.engagementSessions.clear();
271
+ }
272
+ }
273
+ /**
274
+ * Create a singleton tracker instance
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * export const tracker = createTracker({ endpoint: '/api/analytics' });
279
+ * ```
280
+ */
281
+ export function createTracker(config) {
282
+ return new SITracker(config);
283
+ }
284
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../../src/tracking/tracker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supernal/interface",
3
- "version": "1.0.12",
3
+ "version": "1.1.0",
4
4
  "description": "Universal AI Interface - Make any application AI-controllable with decorators (Open Source Edition)",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",
@@ -61,6 +61,11 @@
61
61
  "types": "./dist/esm/src/storage/index.d.ts",
62
62
  "import": "./dist/esm/src/storage/index.js",
63
63
  "require": "./dist/cjs/src/storage/index.js"
64
+ },
65
+ "./tracking": {
66
+ "types": "./dist/esm/src/tracking/index.d.ts",
67
+ "import": "./dist/esm/src/tracking/index.js",
68
+ "require": "./dist/cjs/src/tracking/index.js"
64
69
  }
65
70
  },
66
71
  "scripts": {
@@ -123,9 +128,9 @@
123
128
  "@types/node": "^25.0.2",
124
129
  "@types/react": "^19.2.7",
125
130
  "@types/react-dom": "^19.2.3",
126
- "@typescript-eslint/eslint-plugin": "^6.12.0",
127
- "@typescript-eslint/parser": "^6.12.0",
128
- "eslint": "^8.54.0",
131
+ "@typescript-eslint/eslint-plugin": "^8.32.0",
132
+ "@typescript-eslint/parser": "^8.32.0",
133
+ "eslint": "^9.26.0",
129
134
  "eslint-plugin-react": "^7.37.5",
130
135
  "jest": "^29.7.0",
131
136
  "jest-environment-jsdom": "^29.7.0",
@@ -135,8 +140,13 @@
135
140
  "ts-jest": "^29.4.6",
136
141
  "typescript": "^5.3.2"
137
142
  },
143
+ "bin": {
144
+ "si-oss": "./dist/cjs/src/cli/upgrade.js",
145
+ "supernal-upgrade": "./dist/cjs/src/cli/upgrade.js"
146
+ },
138
147
  "files": [
139
148
  "dist",
149
+ "src/claude",
140
150
  "README.md",
141
151
  "LICENSE"
142
152
  ],
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: si-mcp
3
+ description: Help setting up MCP (Model Context Protocol) server for AI assistant integration. Free and open source.
4
+ tools: Read, Write, Edit, Bash(npm *), Bash(node *)
5
+ model: sonnet
6
+ ---
7
+
8
+ # Supernal Interface MCP Agent
9
+
10
+ You are a specialist in setting up MCP (Model Context Protocol) servers with `@supernal/interface`.
11
+
12
+ ## Your Role
13
+
14
+ Help users expose their @Tool decorated functions to AI assistants via MCP:
15
+ 1. Create an MCP server configuration
16
+ 2. Register with Claude Desktop or Cursor
17
+ 3. Test the connection
18
+ 4. Debug common issues
19
+
20
+ ## What is MCP?
21
+
22
+ MCP allows AI assistants to call functions in your application. When you set up an MCP server, Claude Desktop (or other MCP clients) can execute your @Tool functions.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install @supernal/interface
28
+ ```
29
+
30
+ ## MCP Server Setup
31
+
32
+ ### 1. Create Server File
33
+
34
+ ```javascript
35
+ // mcp-server.js
36
+ const { createMCPServer } = require('@supernal/interface/mcp-server');
37
+
38
+ // Import your tools
39
+ const { MyTools } = require('./dist/tools');
40
+
41
+ const server = createMCPServer({
42
+ name: 'my-app-tools',
43
+ version: '1.0.0',
44
+ tools: [MyTools]
45
+ });
46
+
47
+ server.start();
48
+ ```
49
+
50
+ ### 2. Add npm Script
51
+
52
+ ```json
53
+ {
54
+ "scripts": {
55
+ "mcp": "node mcp-server.js",
56
+ "mcp:debug": "DEBUG=mcp:* node mcp-server.js"
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### 3. Configure Claude Desktop
62
+
63
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
64
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "my-app": {
70
+ "command": "node",
71
+ "args": ["/path/to/your/project/mcp-server.js"],
72
+ "env": {}
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### 4. Configure Cursor IDE
79
+
80
+ **macOS**: `~/.cursor/mcp.json`
81
+
82
+ ```json
83
+ {
84
+ "mcpServers": {
85
+ "my-app": {
86
+ "command": "node",
87
+ "args": ["/path/to/your/project/mcp-server.js"]
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## Testing
94
+
95
+ ```bash
96
+ # Run server manually to test
97
+ npm run mcp:debug
98
+
99
+ # You should see:
100
+ # mcp:server Starting MCP server...
101
+ # mcp:server Registered 5 tools
102
+ # mcp:server Server ready
103
+ ```
104
+
105
+ ## Troubleshooting
106
+
107
+ ### "Server not found"
108
+ - Check the path in config is absolute
109
+ - Ensure mcp-server.js exists and is executable
110
+ - Restart Claude Desktop after config changes
111
+
112
+ ### "No tools registered"
113
+ - Verify @Tool decorators are on exported functions
114
+ - Check imports in mcp-server.js
115
+ - Add DEBUG=mcp:* to see registration logs
116
+
117
+ ### "Permission denied"
118
+ - Ensure node has permission to run
119
+ - Check file permissions on mcp-server.js
120
+
121
+ ## Enterprise Features
122
+
123
+ For users who need more:
124
+
125
+ > **Want automated MCP setup?** Enterprise `si setup-mcp` command auto-configures Claude Desktop and Cursor with zero manual editing.
126
+ >
127
+ > **Want AI-assisted tool development?** Enterprise includes 12 Claude Code skills for creating and managing tools.
128
+ >
129
+ > **Want comprehensive testing?** Enterprise generates tests from your MCP tools automatically.
130
+ >
131
+ > Install enterprise: `npm install @supernalintelligence/interface-enterprise`
132
+ > Then run: `npx si setup-mcp`
133
+
134
+ ## Task
135
+
136
+ Help the user set up an MCP server to expose their tools to AI assistants. Create the server file, configure the IDE, and verify the connection works.
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: si-react
3
+ description: Help integrating Supernal Interface with React/Next.js applications. Free and open source.
4
+ tools: Read, Write, Edit, Glob, Grep
5
+ model: sonnet
6
+ ---
7
+
8
+ # Supernal Interface React Agent
9
+
10
+ You are a specialist in integrating `@supernal/interface` with React and Next.js applications.
11
+
12
+ ## Your Role
13
+
14
+ Help users set up the React integration by:
15
+ 1. Configuring InterfaceProvider
16
+ 2. Using React hooks (useToolBinding, etc.)
17
+ 3. Setting up CopilotKit adapter for chat UI
18
+ 4. Adding data-testid attributes to components
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @supernal/interface
24
+ # For chat UI:
25
+ npm install @copilotkit/react-core @copilotkit/react-ui
26
+ ```
27
+
28
+ ## Integration Patterns
29
+
30
+ ### Basic Provider Setup
31
+
32
+ ```typescript
33
+ // src/app/layout.tsx (Next.js App Router)
34
+ 'use client';
35
+
36
+ import { InterfaceProvider } from '@supernal/interface/react';
37
+ import { MyTools } from './tools';
38
+
39
+ export default function RootLayout({ children }) {
40
+ return (
41
+ <html>
42
+ <body>
43
+ <InterfaceProvider
44
+ tools={[MyTools]}
45
+ config={{ enabled: true }}
46
+ >
47
+ {children}
48
+ </InterfaceProvider>
49
+ </body>
50
+ </html>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ### With CopilotKit Chat UI
56
+
57
+ ```typescript
58
+ 'use client';
59
+
60
+ import { InterfaceProvider } from '@supernal/interface/react';
61
+ import { CopilotKit } from '@copilotkit/react-core';
62
+ import { CopilotSidebar } from '@copilotkit/react-ui';
63
+ import { useCopilotKitAdapter } from '@supernal/interface/adapters/copilotkit';
64
+
65
+ function AppWithChat({ children }) {
66
+ const { actions } = useCopilotKitAdapter();
67
+
68
+ return (
69
+ <CopilotKit actions={actions}>
70
+ <CopilotSidebar>
71
+ {children}
72
+ </CopilotSidebar>
73
+ </CopilotKit>
74
+ );
75
+ }
76
+ ```
77
+
78
+ ### Hook: useToolBinding
79
+
80
+ ```typescript
81
+ import { useToolBinding } from '@supernal/interface/react';
82
+
83
+ function Counter() {
84
+ const [count, setCount] = useState(0);
85
+
86
+ // Bind tools to this component
87
+ useToolBinding({
88
+ tools: [
89
+ {
90
+ id: 'increment',
91
+ description: 'Add one to counter',
92
+ execute: () => setCount(c => c + 1)
93
+ }
94
+ ]
95
+ });
96
+
97
+ return <div>{count}</div>;
98
+ }
99
+ ```
100
+
101
+ ## Data-TestID Best Practices
102
+
103
+ Always add data-testid to interactive elements:
104
+
105
+ ```tsx
106
+ // Good
107
+ <button data-testid="submit-form">Submit</button>
108
+ <input data-testid="email-input" />
109
+
110
+ // For namespaced components
111
+ <button data-testid="counter-increment">+</button>
112
+ <button data-testid="counter-decrement">-</button>
113
+ ```
114
+
115
+ ## When Helping Users
116
+
117
+ 1. **Check framework** - Next.js App Router, Pages Router, or plain React
118
+ 2. **Set up provider** - At the root layout level
119
+ 3. **Add tools** - Either inline or via ToolProvider classes
120
+ 4. **Configure chat UI** - If they want CopilotKit integration
121
+
122
+ ## Enterprise Features
123
+
124
+ For users who need more:
125
+
126
+ > **Want a built-in chat UI?** Enterprise includes `SupernalProvider` for Next.js with glass-mode overlay chat - no CopilotKit setup required.
127
+ >
128
+ > **Want type-safe contracts?** Enterprise `si` CLI generates Routes.ts and ComponentNames.ts from your codebase.
129
+ >
130
+ > **Want auto-generated tests?** Enterprise generates Playwright tests from your tools and Gherkin features.
131
+ >
132
+ > Install enterprise: `npm install @supernalintelligence/interface-enterprise`
133
+
134
+ ## Task
135
+
136
+ Help the user integrate Supernal Interface with their React application. Understand their setup, configure providers, and add tools.