ebade 1.0.0 → 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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to **ebade** will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] - 2026-01-11
9
+
10
+ - **ebade Pulse**: Implemented anonymous, privacy-first telemetry for real-time usage insights.
11
+ - **Self-Hosted Analytics**: Telemetry data is now sent directly to `ebade.dev` and stored in Supabase.
12
+ - **Privacy First**: Added `EBADE_TELEMETRY_DISABLED` opt-out and detailed transparency in README.
13
+ - **Infrastructure Overhaul**: Updated CLI and Backend to support secure, keyless event tracking.
14
+
8
15
  ## [1.0.0] - 2025-01-10
9
16
 
10
17
  - **Official v1.0.0 Launch ("Zımba Edition")**: Reached full production stability across all targets.
package/README.md CHANGED
@@ -78,7 +78,7 @@ ebade uses a high-density decorator syntax designed to fit within an Agent's con
78
78
 
79
79
  ## 🧠 The Architect: Prompt-to-Product
80
80
 
81
- In **v1.0.0**, we reached **Ultimate Stability**. ebade is now the first professional-grade, multi-target framework built natively for AI agents. Whether it's Web (Next.js), Android (Flutter), or iOS (SwiftUI), ebade forges your legacy with a single prompt. 🚀
81
+ In **v1.1.0**, we introduce **ebade Pulse**. ebade continues to be the most stable professional-grade, multi-target framework built natively for AI agents. Whether it's Web (Next.js), Android (Flutter), or iOS (SwiftUI), ebade forges your legacy with a single prompt. 🚀
82
82
 
83
83
  ```bash
84
84
  # One-shot project creation
@@ -86,8 +86,10 @@ npx ebade build "A luxury concierge service with pricing, testimonials and a gol
86
86
  ```
87
87
 
88
88
  - **Intent Intelligence**: Automatically detects app type (SaaS, E-commerce, Blog).
89
+ - **Universal LogicForge**: Generates Types, Services, and Mocks for Next.js, Flutter, and SwiftUI simultaneously.
89
90
  - **Dynamic Design**: Generates a premium HSL color palette from your prompt.
90
91
  - **Smart Scaffolding**: Detects needed components (`auth`, `charts`, `forms`) and dynamically creates routes.
92
+ - **Green AI Dashboard**: Integrated sustainability metrics to measure token and carbon savings.
91
93
 
92
94
  ---
93
95
 
@@ -128,7 +130,7 @@ Add `ebade` to your AI agent (Claude, Cursor, Windsurf) via the Model Context Pr
128
130
  ebade operates on the principle of **The Online Compiler**. It treats AI as a deterministic component of the toolchain, not a creative oracle.
129
131
 
130
132
  - **Standardized Intent Tree (SIT):** Parses YAML/TS into a logical graph.
131
- - **Target Adapters:** Compiles intent into Next.js, Flutter, or Svelte (0-token boilerplate).
133
+ - **Target Adapters:** Compiles intent into Next.js, Flutter, or SwiftUI (0-token boilerplate).
132
134
  - **AgentRules:** Automatically generates `.cursorrules` and `.clauderules` to keep your agent aligned.
133
135
 
134
136
  🏗️ [Explore the Architecture](./ARCHITECTURE.md)
@@ -177,6 +179,14 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for full guidelines.
177
179
  - **Star the repo** to show your support ⭐
178
180
  - **Share the project** with other enthusiasts 🚀
179
181
 
182
+ ## 🔒 Privacy & Telemetry
183
+
184
+ **ebade** collects anonymous usage statistics (ebade Pulse) to help us understand how the framework is used and to improve it.
185
+
186
+ - **What we collect:** Command name, target platform (Next.js/Flutter), basic OS info, and performance metrics (files generated, tokens saved).
187
+ - **What we NEVER collect:** Your code, your ebade YAML content, project names, or any personal information.
188
+ - **How to disable:** Set `EBADE_TELEMETRY_DISABLED=1` in your environment.
189
+
180
190
  ---
181
191
 
182
192
  ## 📄 License
package/cli/scaffold.js CHANGED
@@ -23,6 +23,7 @@ import { FlutterAdapter } from "./adapters/flutter.js";
23
23
  import { SwiftUiAdapter } from "./adapters/swiftui.js";
24
24
  import { ensureDir, toPascalCase, calculateGreenMetrics } from "./utils.js";
25
25
  import { validateEbade } from "./validator.js";
26
+ import { sendPulse } from "./telemetry.js";
26
27
 
27
28
  const __filename = fileURLToPath(import.meta.url);
28
29
  const __dirname = path.dirname(__filename);
@@ -51,7 +52,7 @@ ${colors.magenta} ██╔══╝ ${colors.cyan}██╔══██╗$
51
52
  ${colors.magenta} ███████╗${colors.cyan}██████╔╝${colors.magenta}██║ ██║${colors.cyan}██████╔╝${colors.magenta}███████╗
52
53
  ${colors.magenta} ╚══════╝${colors.cyan}╚═════╝ ${colors.magenta}╚═╝ ╚═╝${colors.cyan}╚═════╝ ${colors.magenta}╚══════╝${colors.reset}
53
54
 
54
- ${colors.dim}✨ Agent-First Framework ${colors.yellow}v1.0.0${colors.reset}
55
+ ${colors.dim}✨ Agent-First Framework ${colors.yellow}v1.1.0${colors.reset}
55
56
  `;
56
57
 
57
58
  const log = {
@@ -512,6 +513,21 @@ async function scaffold(ebadePath, outputDir, target = "nextjs") {
512
513
  console.log(
513
514
  ` Tokens Transferred: ${colors.dim}~${green.rawTokensSaved}${colors.reset}\n Carbon Saved: ${colors.green}${green.gramsCO2Saved}g CO2e${colors.reset}\n Protocol Precision: ${colors.bright}99.9%${colors.reset}\n`
514
515
  );
516
+
517
+ // Send Telemetry
518
+ sendPulse({
519
+ event: "ebade_scaffold_success",
520
+ target: target,
521
+ metrics: {
522
+ files: stats.files,
523
+ pages: stats.pages,
524
+ components: stats.components,
525
+ api_routes: stats.apiRoutes,
526
+ tokens_saved: green.rawTokensSaved,
527
+ carbon_saved_g: green.gramsCO2Saved,
528
+ },
529
+ duration_s: duration,
530
+ });
515
531
  }
516
532
 
517
533
  // CLI Logic
@@ -547,12 +563,17 @@ if (command === "init") {
547
563
  fs.writeFileSync(tempFile, yaml.stringify(config));
548
564
  await scaffold(tempFile, outputDir, target);
549
565
  fs.rmSync(tempDir, { recursive: true, force: true });
566
+
567
+ sendPulse({
568
+ event: "ebade_build_success",
569
+ target: target,
570
+ });
550
571
  } else if (command === "scaffold") {
551
572
  const file = args.filter((a) => !a.startsWith("-"))[1];
552
573
  const out = args.filter((a) => !a.startsWith("-"))[2] || "./output";
553
574
  await scaffold(file, out, target);
554
575
  } else {
555
576
  console.log(
556
- "ebade v1.0.0 - Agent-First Framework\nUsage: npx ebade <build|scaffold> <prompt|file> [--target nextjs|html|flutter|swiftui]"
577
+ "ebade v1.1.0 - Agent-First Framework\nUsage: npx ebade <build|scaffold> <prompt|file> [--target nextjs|html|flutter|swiftui]"
557
578
  );
558
579
  }
@@ -0,0 +1,64 @@
1
+ import https from "https";
2
+ import os from "os";
3
+
4
+ /**
5
+ * ebade Pulse - Privacy-first Telemetry
6
+ * Sends anonymous usage data directly to ebade.dev
7
+ */
8
+ export async function sendPulse(eventData) {
9
+ if (process.env.EBADE_TELEMETRY_DISABLED) return;
10
+
11
+ const payload = {
12
+ event: eventData.event || "cli_usage",
13
+ timestamp: new Date().toISOString(),
14
+ os: os.platform(),
15
+ arch: os.arch(),
16
+ node_version: process.version,
17
+ is_agent: detectAgent(),
18
+ ...eventData,
19
+ };
20
+
21
+ const data = JSON.stringify(payload);
22
+
23
+ const options = {
24
+ hostname: "ebade.dev",
25
+ port: 443,
26
+ path: "/api/pulse",
27
+ method: "POST",
28
+ headers: {
29
+ "Content-Type": "application/json",
30
+ "Content-Length": data.length,
31
+ "User-Agent": "ebade-cli",
32
+ },
33
+ };
34
+
35
+ const req = https.request(options);
36
+
37
+ req.on("error", () => {
38
+ // Silent fail if offline or server is down
39
+ });
40
+ req.write(data);
41
+ req.end();
42
+ }
43
+
44
+ function detectAgent() {
45
+ const agentEnvs = [
46
+ "CLAUDE_CODE",
47
+ "GITHUB_ACTIONS",
48
+ "VERCEL",
49
+ "AGENT_ID",
50
+ "AI_AGENT",
51
+ "LLM_AGENT",
52
+ ];
53
+
54
+ if (agentEnvs.some((env) => process.env[env])) return true;
55
+
56
+ if (
57
+ process.env.TERM_PROGRAM === "vscode" &&
58
+ process.env.VSCODE_GIT_IPC_HANDLE
59
+ ) {
60
+ return true;
61
+ }
62
+
63
+ return false;
64
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ebade",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "ebade - Agent-First Framework. The first framework designed for AI agents, readable by humans.",
5
5
  "type": "module",
6
6
  "main": "cli/scaffold.js",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ebade-mcp-server",
3
- "version": "1.0.0",
4
- "description": "MCP Server for ebade v0.5.0 - The Agent-First Framework",
3
+ "version": "1.1.0",
4
+ "description": "MCP Server for ebade v1.1.0 - The Agent-First Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -9,7 +9,7 @@
9
9
  * - Validate ebade files
10
10
  * - Compile ebade to framework-specific code
11
11
  * - Generate components from natural language descriptions
12
- * - Build entire projects from natural language prompts (NEW in v0.4.7)
12
+ * - Build entire projects from natural language prompts (NEW in v1.1.0)
13
13
  */
14
14
 
15
15
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -31,7 +31,7 @@ import { buildFromPrompt } from "./tools/build.js";
31
31
  const server = new Server(
32
32
  {
33
33
  name: "ebade",
34
- version: "0.4.7",
34
+ version: "1.1.0",
35
35
  },
36
36
  {
37
37
  capabilities: {
@@ -37,7 +37,7 @@ export async function buildFromPrompt(args: BuildArgs): Promise<string> {
37
37
  env: { ...process.env, NODE_ENV: "production" },
38
38
  });
39
39
 
40
- return `✅ ebade v0.4.7 Build Complete!
40
+ return `✅ ebade v1.1.0 Build Complete!
41
41
 
42
42
  Prompt: "${prompt}"
43
43
  Output: ${outputDir}
@@ -139,7 +139,44 @@ export async function scaffoldProject(args: ScaffoldArgs): Promise<string> {
139
139
  // 3. Generate Next.js files (Basic mocks to match CLI)
140
140
  generateCoreFiles(projectDir, ebadeConfig);
141
141
 
142
- return `✅ ebade v0.3.1 Scaffold Complete!
142
+ // 4. Send Telemetry
143
+ try {
144
+ const https = await import("https");
145
+ const payload = JSON.stringify({
146
+ event: "ebade_mcp_scaffold_success",
147
+ timestamp: new Date().toISOString(),
148
+ os: process.platform,
149
+ arch: process.arch,
150
+ node_version: process.version,
151
+ is_agent: true,
152
+ command: "mcp_scaffold",
153
+ target: "nextjs",
154
+ metrics: {
155
+ project_type: projectType,
156
+ },
157
+ });
158
+
159
+ const options = {
160
+ hostname: "ebade.dev",
161
+ port: 443,
162
+ path: "/api/pulse",
163
+ method: "POST",
164
+ headers: {
165
+ "Content-Type": "application/json",
166
+ "Content-Length": payload.length,
167
+ "User-Agent": "ebade-mcp",
168
+ },
169
+ };
170
+
171
+ const req = https.request(options);
172
+ req.on("error", () => {});
173
+ req.write(payload);
174
+ req.end();
175
+ } catch (e) {
176
+ // Silent fail
177
+ }
178
+
179
+ return `✅ ebade v1.1.0 Scaffold Complete!
143
180
 
144
181
  Project: ${projectName}
145
182
  Type: ${projectType}
@@ -2,7 +2,7 @@
2
2
  "name": "ebade",
3
3
  "displayName": "ebade - Agent-First Framework",
4
4
  "description": "Syntax highlighting and snippets for ebade (.ebade.yaml) files",
5
- "version": "0.4.1",
5
+ "version": "1.1.0",
6
6
  "publisher": "hasankemaldemirci",
7
7
  "icon": "images/icon.png",
8
8
  "engines": {
@@ -0,0 +1,53 @@
1
+ import { NextResponse } from "next/server";
2
+ import { supabase } from "@/lib/supabase";
3
+
4
+ export async function POST(req: Request) {
5
+ try {
6
+ const contentLength = parseInt(req.headers.get("content-length") || "0");
7
+ if (contentLength > 1024 * 5) {
8
+ return NextResponse.json({ error: "Payload too large" }, { status: 413 });
9
+ }
10
+
11
+ if (req.headers.get("user-agent") !== "ebade-cli") {
12
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
13
+ }
14
+
15
+ const contentType = req.headers.get("content-type");
16
+ if (!contentType || !contentType.includes("application/json")) {
17
+ return NextResponse.json(
18
+ { error: "Unsupported Media Type" },
19
+ { status: 415 }
20
+ );
21
+ }
22
+
23
+ const body = await req.json();
24
+
25
+ if (!body.event || !body.timestamp) {
26
+ return NextResponse.json({ error: "Malformed request" }, { status: 400 });
27
+ }
28
+
29
+ const { error } = await supabase.from("pulses").insert([
30
+ {
31
+ event: body.event,
32
+ timestamp: body.timestamp,
33
+ os: body.os,
34
+ arch: body.arch,
35
+ node_version: body.node_version,
36
+ is_agent: body.is_agent,
37
+ command: body.command,
38
+ target: body.target,
39
+ metrics: body.metrics,
40
+ duration_s: body.duration_s,
41
+ success: body.success ?? true,
42
+ },
43
+ ]);
44
+
45
+ if (error) {
46
+ console.error("[Pulse Error]", error);
47
+ }
48
+
49
+ return NextResponse.json({ success: true }, { status: 200 });
50
+ } catch (error) {
51
+ return NextResponse.json({ success: false }, { status: 500 });
52
+ }
53
+ }
@@ -0,0 +1,8 @@
1
+ import { createClient } from "@supabase/supabase-js";
2
+
3
+ const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || "";
4
+ const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY || "";
5
+
6
+ // We use service_role key globally for telemetry as it's a server-side only action
7
+ // and bypasses RLS for faster event recording.
8
+ export const supabase = createClient(supabaseUrl, supabaseServiceKey);
@@ -1,13 +1,14 @@
1
1
  {
2
- "name": "landing",
3
- "version": "0.1.0",
2
+ "name": "www",
3
+ "version": "1.0.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
- "name": "landing",
9
- "version": "0.1.0",
8
+ "name": "www",
9
+ "version": "1.0.0",
10
10
  "dependencies": {
11
+ "@supabase/supabase-js": "^2.90.1",
11
12
  "lucide-react": "^0.562.0",
12
13
  "next": "^15.1.4",
13
14
  "react": "^19.0.0",
@@ -739,6 +740,86 @@
739
740
  "node": ">= 10"
740
741
  }
741
742
  },
743
+ "node_modules/@supabase/auth-js": {
744
+ "version": "2.90.1",
745
+ "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.90.1.tgz",
746
+ "integrity": "sha512-vxb66dgo6h3yyPbR06735Ps+dK3hj0JwS8w9fdQPVZQmocSTlKUW5MfxSy99mN0XqCCuLMQ3jCEiIIUU23e9ng==",
747
+ "license": "MIT",
748
+ "dependencies": {
749
+ "tslib": "2.8.1"
750
+ },
751
+ "engines": {
752
+ "node": ">=20.0.0"
753
+ }
754
+ },
755
+ "node_modules/@supabase/functions-js": {
756
+ "version": "2.90.1",
757
+ "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.90.1.tgz",
758
+ "integrity": "sha512-x9mV9dF1Lam9qL3zlpP6mSM5C9iqMPtF5B/tU1Jj/F0ufX5mjDf9ghVBaErVxmrQJRL4+iMKWKY2GnODkpS8tw==",
759
+ "license": "MIT",
760
+ "dependencies": {
761
+ "tslib": "2.8.1"
762
+ },
763
+ "engines": {
764
+ "node": ">=20.0.0"
765
+ }
766
+ },
767
+ "node_modules/@supabase/postgrest-js": {
768
+ "version": "2.90.1",
769
+ "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.90.1.tgz",
770
+ "integrity": "sha512-jh6vqzaYzoFn3raaC0hcFt9h+Bt+uxNRBSdc7PfToQeRGk7PDPoweHsbdiPWREtDVTGKfu+PyPW9e2jbK+BCgQ==",
771
+ "license": "MIT",
772
+ "dependencies": {
773
+ "tslib": "2.8.1"
774
+ },
775
+ "engines": {
776
+ "node": ">=20.0.0"
777
+ }
778
+ },
779
+ "node_modules/@supabase/realtime-js": {
780
+ "version": "2.90.1",
781
+ "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.90.1.tgz",
782
+ "integrity": "sha512-PWbnEMkcQRuor8jhObp4+Snufkq8C6fBp+MchVp2qBPY1NXk/c3Iv3YyiFYVzo0Dzuw4nAlT4+ahuPggy4r32w==",
783
+ "license": "MIT",
784
+ "dependencies": {
785
+ "@types/phoenix": "^1.6.6",
786
+ "@types/ws": "^8.18.1",
787
+ "tslib": "2.8.1",
788
+ "ws": "^8.18.2"
789
+ },
790
+ "engines": {
791
+ "node": ">=20.0.0"
792
+ }
793
+ },
794
+ "node_modules/@supabase/storage-js": {
795
+ "version": "2.90.1",
796
+ "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.90.1.tgz",
797
+ "integrity": "sha512-GHY+Ps/K/RBfRj7kwx+iVf2HIdqOS43rM2iDOIDpapyUnGA9CCBFzFV/XvfzznGykd//z2dkGZhlZZprsVFqGg==",
798
+ "license": "MIT",
799
+ "dependencies": {
800
+ "iceberg-js": "^0.8.1",
801
+ "tslib": "2.8.1"
802
+ },
803
+ "engines": {
804
+ "node": ">=20.0.0"
805
+ }
806
+ },
807
+ "node_modules/@supabase/supabase-js": {
808
+ "version": "2.90.1",
809
+ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.90.1.tgz",
810
+ "integrity": "sha512-U8KaKGLUgTIFHtwEW1dgw1gK7XrdpvvYo7nzzqPx721GqPe8WZbAiLh/hmyKLGBYQ/mmQNr20vU9tWSDZpii3w==",
811
+ "license": "MIT",
812
+ "dependencies": {
813
+ "@supabase/auth-js": "2.90.1",
814
+ "@supabase/functions-js": "2.90.1",
815
+ "@supabase/postgrest-js": "2.90.1",
816
+ "@supabase/realtime-js": "2.90.1",
817
+ "@supabase/storage-js": "2.90.1"
818
+ },
819
+ "engines": {
820
+ "node": ">=20.0.0"
821
+ }
822
+ },
742
823
  "node_modules/@swc/helpers": {
743
824
  "version": "0.5.15",
744
825
  "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -1030,12 +1111,17 @@
1030
1111
  "version": "20.19.27",
1031
1112
  "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz",
1032
1113
  "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==",
1033
- "dev": true,
1034
1114
  "license": "MIT",
1035
1115
  "dependencies": {
1036
1116
  "undici-types": "~6.21.0"
1037
1117
  }
1038
1118
  },
1119
+ "node_modules/@types/phoenix": {
1120
+ "version": "1.6.7",
1121
+ "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz",
1122
+ "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==",
1123
+ "license": "MIT"
1124
+ },
1039
1125
  "node_modules/@types/react": {
1040
1126
  "version": "19.2.7",
1041
1127
  "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
@@ -1086,6 +1172,15 @@
1086
1172
  "dev": true,
1087
1173
  "license": "MIT"
1088
1174
  },
1175
+ "node_modules/@types/ws": {
1176
+ "version": "8.18.1",
1177
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
1178
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
1179
+ "license": "MIT",
1180
+ "dependencies": {
1181
+ "@types/node": "*"
1182
+ }
1183
+ },
1089
1184
  "node_modules/@webgpu/types": {
1090
1185
  "version": "0.1.68",
1091
1186
  "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.68.tgz",
@@ -1174,6 +1269,15 @@
1174
1269
  "dev": true,
1175
1270
  "license": "ISC"
1176
1271
  },
1272
+ "node_modules/iceberg-js": {
1273
+ "version": "0.8.1",
1274
+ "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
1275
+ "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
1276
+ "license": "MIT",
1277
+ "engines": {
1278
+ "node": ">=20.0.0"
1279
+ }
1280
+ },
1177
1281
  "node_modules/jiti": {
1178
1282
  "version": "2.6.1",
1179
1283
  "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
@@ -1772,8 +1876,28 @@
1772
1876
  "version": "6.21.0",
1773
1877
  "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
1774
1878
  "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
1775
- "dev": true,
1776
1879
  "license": "MIT"
1880
+ },
1881
+ "node_modules/ws": {
1882
+ "version": "8.19.0",
1883
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
1884
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
1885
+ "license": "MIT",
1886
+ "engines": {
1887
+ "node": ">=10.0.0"
1888
+ },
1889
+ "peerDependencies": {
1890
+ "bufferutil": "^4.0.1",
1891
+ "utf-8-validate": ">=5.0.2"
1892
+ },
1893
+ "peerDependenciesMeta": {
1894
+ "bufferutil": {
1895
+ "optional": true
1896
+ },
1897
+ "utf-8-validate": {
1898
+ "optional": true
1899
+ }
1900
+ }
1777
1901
  }
1778
1902
  }
1779
1903
  }
package/www/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "www",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "next dev",
@@ -8,6 +8,7 @@
8
8
  "start": "next start"
9
9
  },
10
10
  "dependencies": {
11
+ "@supabase/supabase-js": "^2.90.1",
11
12
  "lucide-react": "^0.562.0",
12
13
  "next": "^15.1.4",
13
14
  "react": "^19.0.0",