@01.software/init 0.1.2 → 0.1.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/dist/index.js ADDED
@@ -0,0 +1,574 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import pc2 from "picocolors";
5
+
6
+ // src/detect.ts
7
+ import fs from "fs";
8
+ import path from "path";
9
+ function detectProject(cwd) {
10
+ const pkgPath = path.join(cwd, "package.json");
11
+ const hasPackageJson = fs.existsSync(pkgPath);
12
+ let env = "node";
13
+ let hasSdk = false;
14
+ if (hasPackageJson) {
15
+ let pkg;
16
+ try {
17
+ pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
18
+ } catch {
19
+ return { hasPackageJson: false, env: "node", packageManager: null, hasSdk: false, srcDir: false };
20
+ }
21
+ const deps = {
22
+ ...pkg.dependencies || {},
23
+ ...pkg.devDependencies || {}
24
+ };
25
+ hasSdk = "@01.software/sdk" in deps;
26
+ if ("next" in deps) {
27
+ env = "nextjs";
28
+ } else if ("astro" in deps || "@astrojs/node" in deps) {
29
+ env = "other";
30
+ } else if ("@remix-run/node" in deps || "@remix-run/react" in deps) {
31
+ env = "other";
32
+ } else if ("@sveltejs/kit" in deps) {
33
+ env = "other";
34
+ } else if ("react" in deps) {
35
+ if ("vite" in deps) {
36
+ env = "react-vite";
37
+ } else if ("react-scripts" in deps) {
38
+ env = "react-cra";
39
+ } else {
40
+ env = "node";
41
+ }
42
+ }
43
+ }
44
+ let packageManager = null;
45
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
46
+ packageManager = "pnpm";
47
+ } else if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
48
+ packageManager = "yarn";
49
+ } else if (fs.existsSync(path.join(cwd, "bun.lockb")) || fs.existsSync(path.join(cwd, "bun.lock"))) {
50
+ packageManager = "bun";
51
+ } else if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
52
+ packageManager = "npm";
53
+ }
54
+ const srcDir = env === "nextjs" ? fs.existsSync(path.join(cwd, "src", "app")) : fs.existsSync(path.join(cwd, "src"));
55
+ return { hasPackageJson, env, packageManager, hasSdk, srcDir };
56
+ }
57
+ function needsClient(env) {
58
+ return env === "nextjs" || env === "react-vite" || env === "react-cra" || env === "vanilla";
59
+ }
60
+ function needsServer(env) {
61
+ return env === "nextjs" || env === "node" || env === "edge";
62
+ }
63
+ function needsReactQuery(env) {
64
+ return env === "nextjs" || env === "react-vite" || env === "react-cra";
65
+ }
66
+ function supportsMcp(env) {
67
+ return env === "nextjs" || env === "node" || env === "edge";
68
+ }
69
+ function getClientKeyEnvVar(env) {
70
+ switch (env) {
71
+ case "nextjs":
72
+ return "NEXT_PUBLIC_SOFTWARE_CLIENT_KEY";
73
+ case "react-vite":
74
+ return "VITE_SOFTWARE_CLIENT_KEY";
75
+ case "react-cra":
76
+ return "REACT_APP_SOFTWARE_CLIENT_KEY";
77
+ default:
78
+ return "SOFTWARE_CLIENT_KEY";
79
+ }
80
+ }
81
+
82
+ // src/prompts.ts
83
+ import prompts from "prompts";
84
+ var AMBIGUOUS_ENVS = ["node"];
85
+ async function promptUser(hasSdk, detectedEnv, detectedPm) {
86
+ const onCancel = () => {
87
+ throw new Error("cancelled");
88
+ };
89
+ if (hasSdk) {
90
+ const { proceed } = await prompts(
91
+ {
92
+ type: "confirm",
93
+ name: "proceed",
94
+ message: "@01.software/sdk is already installed. Re-initialize?",
95
+ initial: false
96
+ },
97
+ { onCancel }
98
+ );
99
+ if (!proceed) return null;
100
+ }
101
+ let env = detectedEnv;
102
+ if (AMBIGUOUS_ENVS.includes(detectedEnv)) {
103
+ const { selectedEnv } = await prompts(
104
+ {
105
+ type: "select",
106
+ name: "selectedEnv",
107
+ message: "Which environment are you using?",
108
+ choices: [
109
+ {
110
+ title: "Next.js",
111
+ description: "Full-stack React (client + server)",
112
+ value: "nextjs"
113
+ },
114
+ {
115
+ title: "React + Vite",
116
+ description: "Client-only SPA with Vite",
117
+ value: "react-vite"
118
+ },
119
+ {
120
+ title: "React + Webpack / other",
121
+ description: "Client-only SPA, CRA or custom bundler",
122
+ value: "react-cra"
123
+ },
124
+ {
125
+ title: "Vanilla JS",
126
+ description: "Browser app without a framework",
127
+ value: "vanilla"
128
+ },
129
+ {
130
+ title: "Node.js / Bun / Deno",
131
+ description: "Server-only, no browser client",
132
+ value: "node"
133
+ },
134
+ {
135
+ title: "Edge runtime",
136
+ description: "Cloudflare Workers, Vercel Edge Functions",
137
+ value: "edge"
138
+ },
139
+ {
140
+ title: "Other (Astro / Remix / SvelteKit\u2026)",
141
+ description: "Print manual setup guide for your framework",
142
+ value: "other"
143
+ }
144
+ ]
145
+ },
146
+ { onCancel }
147
+ );
148
+ env = selectedEnv;
149
+ }
150
+ if (env === "other") {
151
+ return { env, clientKey: "", secretKey: "", setupMcp: false, packageManager: void 0 };
152
+ }
153
+ let packageManager;
154
+ if (!detectedPm) {
155
+ const { pm } = await prompts(
156
+ {
157
+ type: "select",
158
+ name: "pm",
159
+ message: "Which package manager do you use?",
160
+ choices: [
161
+ { title: "npm", value: "npm" },
162
+ { title: "pnpm", value: "pnpm" },
163
+ { title: "yarn", value: "yarn" },
164
+ { title: "bun", value: "bun" }
165
+ ]
166
+ },
167
+ { onCancel }
168
+ );
169
+ packageManager = pm;
170
+ }
171
+ const needsSecretKey = env === "nextjs" || env === "node" || env === "edge";
172
+ const keyPrompts = [];
173
+ if (env !== "vanilla") {
174
+ keyPrompts.push({
175
+ type: "text",
176
+ name: "clientKey",
177
+ message: "Client Key (optional, saved to .env)",
178
+ initial: ""
179
+ });
180
+ }
181
+ if (needsSecretKey) {
182
+ keyPrompts.push({
183
+ type: "text",
184
+ name: "secretKey",
185
+ message: "Secret Key (optional, saved to .env)",
186
+ initial: ""
187
+ });
188
+ }
189
+ const keys = keyPrompts.length > 0 ? await prompts(keyPrompts, { onCancel }) : {};
190
+ let setupMcp = false;
191
+ if (supportsMcp(env)) {
192
+ const result = await prompts(
193
+ {
194
+ type: "confirm",
195
+ name: "setupMcp",
196
+ message: "Set up MCP integration? (.mcp.json)",
197
+ initial: true
198
+ },
199
+ { onCancel }
200
+ );
201
+ setupMcp = result.setupMcp;
202
+ }
203
+ return {
204
+ env,
205
+ clientKey: keys.clientKey ?? "",
206
+ secretKey: keys.secretKey ?? "",
207
+ setupMcp,
208
+ packageManager
209
+ };
210
+ }
211
+
212
+ // src/init.ts
213
+ import fs2 from "fs";
214
+ import path2 from "path";
215
+ import { execSync } from "child_process";
216
+ import pc from "picocolors";
217
+
218
+ // src/templates.ts
219
+ function getClientTemplate(env, clientKeyEnvVar) {
220
+ if (env === "nextjs") {
221
+ return `import { createBrowserClient } from '@01.software/sdk'
222
+
223
+ export const client = createBrowserClient({
224
+ clientKey: process.env.${clientKeyEnvVar}!,
225
+ })
226
+ `;
227
+ }
228
+ if (env === "react-cra") {
229
+ return `import { createBrowserClient } from '@01.software/sdk'
230
+
231
+ export const client = createBrowserClient({
232
+ clientKey: process.env.${clientKeyEnvVar}!,
233
+ })
234
+ `;
235
+ }
236
+ if (env === "vanilla") {
237
+ return `import { createBrowserClient } from '@01.software/sdk'
238
+
239
+ // Replace 'YOUR_CLIENT_KEY' with your actual client key from the 01.software console
240
+ export const client = createBrowserClient({
241
+ clientKey: 'YOUR_CLIENT_KEY',
242
+ })
243
+ `;
244
+ }
245
+ return `import { createBrowserClient } from '@01.software/sdk'
246
+
247
+ export const client = createBrowserClient({
248
+ clientKey: import.meta.env.${clientKeyEnvVar},
249
+ })
250
+ `;
251
+ }
252
+ function getQueryProviderTemplate(env) {
253
+ const useClientDirective = env === "nextjs" ? "'use client'\n\n" : "";
254
+ return `${useClientDirective}import { QueryClientProvider } from '@tanstack/react-query'
255
+ import { client } from './client'
256
+
257
+ export function QueryProvider({ children }: { children: React.ReactNode }) {
258
+ return (
259
+ <QueryClientProvider client={client.queryClient}>
260
+ {children}
261
+ </QueryClientProvider>
262
+ )
263
+ }
264
+ `;
265
+ }
266
+ function getServerTemplate(env, clientKeyEnvVar, secretKeyEnvVar) {
267
+ if (env === "edge") {
268
+ return `import { createServerClient } from '@01.software/sdk'
269
+
270
+ // Edge runtime: pass your env bindings here
271
+ // e.g. Cloudflare Workers: use env.SOFTWARE_CLIENT_KEY from the handler context
272
+ // e.g. Vercel Edge: use process.env.${clientKeyEnvVar}
273
+ export function createEdgeClient(clientKey: string, secretKey: string) {
274
+ return createServerClient({ clientKey, secretKey })
275
+ }
276
+ `;
277
+ }
278
+ return `import { createServerClient } from '@01.software/sdk'
279
+
280
+ export const serverClient = createServerClient({
281
+ clientKey: process.env.${clientKeyEnvVar}!,
282
+ secretKey: process.env.${secretKeyEnvVar}!,
283
+ })
284
+ `;
285
+ }
286
+ function getEnvContent(clientKey, secretKey, clientKeyEnvVar, secretKeyEnvVar) {
287
+ let content = `
288
+ # 01.software
289
+ ${clientKeyEnvVar}=${clientKey}
290
+ `;
291
+ if (secretKeyEnvVar) {
292
+ content += `${secretKeyEnvVar}=${secretKey}
293
+ `;
294
+ }
295
+ return content;
296
+ }
297
+ function getMcpServerEntry(apiKey) {
298
+ return {
299
+ type: "http",
300
+ url: "https://mcp.01.software/mcp",
301
+ headers: { "x-api-key": apiKey }
302
+ };
303
+ }
304
+ function getMcpConfigTemplate(apiKey) {
305
+ return JSON.stringify(
306
+ { mcpServers: { "01software": getMcpServerEntry(apiKey) } },
307
+ null,
308
+ 2
309
+ ) + "\n";
310
+ }
311
+
312
+ // src/init.ts
313
+ var SECRET_KEY_ENV_VAR = "SOFTWARE_SECRET_KEY";
314
+ async function init(cwd, info, answers) {
315
+ const { packageManager, srcDir } = info;
316
+ const env = answers.env;
317
+ const baseDir = srcDir ? path2.join(cwd, "src") : cwd;
318
+ const clientKeyEnvVar = getClientKeyEnvVar(env);
319
+ const wantsClient = needsClient(env);
320
+ const wantsServer = needsServer(env);
321
+ const wantsReactQuery = needsReactQuery(env);
322
+ const deps = ["@01.software/sdk"];
323
+ if (wantsReactQuery) deps.push("@tanstack/react-query");
324
+ console.log(pc.dim(` Installing ${deps.join(" and ")}...`));
325
+ const wsPatched = packageManager === "pnpm" && patchPnpmWorkspace(cwd);
326
+ const pkgs = deps.join(" ");
327
+ const pnpmFlag = hasPnpmWorkspace(cwd) ? " -w" : "";
328
+ const addCmd = packageManager === "pnpm" ? `pnpm add${pnpmFlag} ${pkgs}` : packageManager === "yarn" ? `yarn add ${pkgs}` : packageManager === "bun" ? `bun add ${pkgs}` : `npm install ${pkgs}`;
329
+ try {
330
+ execSync(addCmd, { cwd, stdio: "pipe" });
331
+ } catch (error) {
332
+ const err = error;
333
+ const msg = String(err.stderr || "").trim() || String(err.stdout || "").trim() || String(error);
334
+ console.log(pc.red(" Failed to install dependencies:"));
335
+ console.log(pc.dim(` ${msg}`));
336
+ throw error;
337
+ } finally {
338
+ if (wsPatched) restorePnpmWorkspace(cwd);
339
+ }
340
+ const libDir = path2.join(baseDir, "lib", "software");
341
+ fs2.mkdirSync(libDir, { recursive: true });
342
+ if (wantsClient) {
343
+ const clientPath = path2.join(libDir, "client.ts");
344
+ if (fs2.existsSync(clientPath)) {
345
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, clientPath), pc.dim("(already exists)"));
346
+ } else {
347
+ fs2.writeFileSync(clientPath, getClientTemplate(env, clientKeyEnvVar));
348
+ console.log(pc.green(" Created"), relativePath(cwd, clientPath));
349
+ }
350
+ }
351
+ if (wantsReactQuery) {
352
+ const queryProviderPath = path2.join(libDir, "query-provider.tsx");
353
+ if (fs2.existsSync(queryProviderPath)) {
354
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, queryProviderPath), pc.dim("(already exists)"));
355
+ } else {
356
+ fs2.writeFileSync(queryProviderPath, getQueryProviderTemplate(env));
357
+ console.log(pc.green(" Created"), relativePath(cwd, queryProviderPath));
358
+ }
359
+ }
360
+ if (wantsServer) {
361
+ const serverPath = path2.join(libDir, "server.ts");
362
+ if (fs2.existsSync(serverPath)) {
363
+ console.log(pc.yellow(" Skipped"), relativePath(cwd, serverPath), pc.dim("(already exists)"));
364
+ } else {
365
+ fs2.writeFileSync(serverPath, getServerTemplate(env, clientKeyEnvVar, SECRET_KEY_ENV_VAR));
366
+ console.log(pc.green(" Created"), relativePath(cwd, serverPath));
367
+ }
368
+ }
369
+ if (env !== "vanilla" && env !== "edge") {
370
+ const envPath = path2.join(cwd, ".env");
371
+ const envContent = getEnvContent(
372
+ answers.clientKey || "",
373
+ answers.secretKey || "",
374
+ clientKeyEnvVar,
375
+ wantsServer ? SECRET_KEY_ENV_VAR : null
376
+ );
377
+ if (fs2.existsSync(envPath)) {
378
+ const existing = fs2.readFileSync(envPath, "utf-8");
379
+ if (existing.includes(clientKeyEnvVar)) {
380
+ console.log(pc.yellow(" Skipped"), ".env", pc.dim("(keys already present)"));
381
+ } else {
382
+ fs2.appendFileSync(envPath, envContent);
383
+ console.log(pc.green(" Updated"), ".env");
384
+ }
385
+ } else {
386
+ fs2.writeFileSync(envPath, envContent.trimStart());
387
+ console.log(pc.green(" Created"), ".env");
388
+ }
389
+ }
390
+ if (answers.setupMcp) {
391
+ const clientKey = answers.clientKey || "";
392
+ const secretKey = answers.secretKey || "";
393
+ const apiKey = clientKey && secretKey ? Buffer.from(`${clientKey}:${secretKey}`).toString("base64") : "YOUR_API_KEY";
394
+ const mcpPath = path2.join(cwd, ".mcp.json");
395
+ if (fs2.existsSync(mcpPath)) {
396
+ try {
397
+ const existing = JSON.parse(fs2.readFileSync(mcpPath, "utf-8"));
398
+ if (existing.mcpServers?.["01software"]) {
399
+ console.log(pc.yellow(" Skipped"), ".mcp.json", pc.dim("(01software already configured)"));
400
+ } else {
401
+ existing.mcpServers = existing.mcpServers || {};
402
+ existing.mcpServers["01software"] = getMcpServerEntry(apiKey);
403
+ fs2.writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + "\n");
404
+ console.log(pc.green(" Updated"), ".mcp.json");
405
+ }
406
+ } catch {
407
+ console.log(pc.yellow(" Skipped"), ".mcp.json", pc.dim("(could not parse existing file)"));
408
+ }
409
+ } else {
410
+ fs2.writeFileSync(mcpPath, getMcpConfigTemplate(apiKey));
411
+ console.log(pc.green(" Created"), ".mcp.json");
412
+ }
413
+ const gitignorePath = path2.join(cwd, ".gitignore");
414
+ if (fs2.existsSync(gitignorePath)) {
415
+ const gitignore = fs2.readFileSync(gitignorePath, "utf-8");
416
+ if (!gitignore.includes(".mcp.json")) {
417
+ fs2.appendFileSync(gitignorePath, "\n# MCP config (contains API key)\n.mcp.json\n");
418
+ console.log(pc.green(" Updated"), ".gitignore", pc.dim("(added .mcp.json)"));
419
+ }
420
+ }
421
+ }
422
+ }
423
+ function relativePath(cwd, filePath) {
424
+ return path2.relative(cwd, filePath);
425
+ }
426
+ var WS_FILE = "pnpm-workspace.yaml";
427
+ var WS_BACKUP = "pnpm-workspace.yaml.bak";
428
+ function hasPnpmWorkspace(cwd) {
429
+ return fs2.existsSync(path2.join(cwd, WS_FILE));
430
+ }
431
+ function patchPnpmWorkspace(cwd) {
432
+ const wsPath = path2.join(cwd, WS_FILE);
433
+ if (!fs2.existsSync(wsPath)) return false;
434
+ const content = fs2.readFileSync(wsPath, "utf-8");
435
+ if (content.includes("packages:")) return false;
436
+ fs2.copyFileSync(wsPath, path2.join(cwd, WS_BACKUP));
437
+ fs2.writeFileSync(wsPath, content.trimEnd() + "\npackages: []\n");
438
+ return true;
439
+ }
440
+ function restorePnpmWorkspace(cwd) {
441
+ const backupPath = path2.join(cwd, WS_BACKUP);
442
+ if (!fs2.existsSync(backupPath)) return;
443
+ fs2.copyFileSync(backupPath, path2.join(cwd, WS_FILE));
444
+ fs2.unlinkSync(backupPath);
445
+ }
446
+
447
+ // src/index.ts
448
+ var ENV_LABELS = {
449
+ nextjs: "Next.js",
450
+ "react-vite": "React + Vite",
451
+ "react-cra": "React + Webpack/CRA",
452
+ vanilla: "Vanilla JS",
453
+ node: "Node.js",
454
+ edge: "Edge runtime",
455
+ other: "Other framework"
456
+ };
457
+ var OTHER_FRAMEWORK_GUIDE = `
458
+ Astro, Remix, SvelteKit, and other meta-frameworks have their own
459
+ environment conventions. Manual setup:
460
+
461
+ 1. Install the SDK:
462
+ npm install @01.software/sdk
463
+
464
+ 2. Browser client (client islands / RSC):
465
+ import { createBrowserClient } from '@01.software/sdk'
466
+ export const client = createBrowserClient({ clientKey: 'YOUR_CLIENT_KEY' })
467
+
468
+ 3. Server client (SSR / loaders / endpoints):
469
+ import { createServerClient } from '@01.software/sdk'
470
+ export const serverClient = createServerClient({
471
+ clientKey: process.env.PUBLIC_SOFTWARE_CLIENT_KEY!, // prefix varies by framework
472
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
473
+ })
474
+
475
+ 4. Docs: https://01.software/docs/guide/quickstart
476
+ `;
477
+ async function main() {
478
+ const cwd = process.cwd();
479
+ console.log();
480
+ console.log(pc2.bold(" @01.software/init"));
481
+ console.log(pc2.dim(" Initialize 01.software SDK in your project"));
482
+ console.log();
483
+ const info = detectProject(cwd);
484
+ if (!info.hasPackageJson) {
485
+ console.log(pc2.red(" No package.json found in the current directory."));
486
+ console.log(pc2.dim(" Run this command inside an existing project."));
487
+ console.log();
488
+ process.exit(1);
489
+ }
490
+ const detectedParts = [ENV_LABELS[info.env]];
491
+ if (info.packageManager) detectedParts.push(info.packageManager);
492
+ if (info.srcDir) detectedParts.push("src/");
493
+ if (info.env !== "node") {
494
+ console.log(pc2.dim(` Detected: ${detectedParts.join(" / ")}`));
495
+ console.log();
496
+ }
497
+ try {
498
+ const answers = await promptUser(info.hasSdk, info.env, info.packageManager);
499
+ if (!answers) {
500
+ console.log(pc2.yellow(" Cancelled."));
501
+ process.exit(0);
502
+ }
503
+ if (answers.env === "other") {
504
+ console.log(pc2.yellow(" Manual setup required for your framework:"));
505
+ console.log(OTHER_FRAMEWORK_GUIDE);
506
+ process.exit(0);
507
+ }
508
+ const resolvedPm = info.packageManager ?? answers.packageManager ?? "npm";
509
+ const resolvedInfo = { ...info, packageManager: resolvedPm };
510
+ console.log();
511
+ await init(cwd, resolvedInfo, answers);
512
+ const env = answers.env;
513
+ const run = resolvedPm === "npm" ? "npm run" : resolvedPm;
514
+ console.log();
515
+ console.log(pc2.green(" Done!"));
516
+ console.log();
517
+ console.log(" Next steps:");
518
+ console.log();
519
+ if (env === "nextjs") {
520
+ console.log(pc2.dim(" Add QueryProvider to your root layout:"));
521
+ console.log();
522
+ console.log(pc2.cyan(" import { QueryProvider } from '@/lib/software/query-provider'"));
523
+ console.log(pc2.cyan(" <QueryProvider>{children}</QueryProvider>"));
524
+ console.log();
525
+ } else if (env === "react-vite" || env === "react-cra") {
526
+ console.log(pc2.dim(" Wrap your app entry with QueryProvider:"));
527
+ console.log();
528
+ console.log(pc2.cyan(" import { QueryProvider } from './lib/software/query-provider'"));
529
+ console.log(pc2.cyan(" <QueryProvider><App /></QueryProvider>"));
530
+ console.log();
531
+ } else if (env === "vanilla") {
532
+ console.log(pc2.dim(" Replace YOUR_CLIENT_KEY in lib/software/client.ts"));
533
+ console.log();
534
+ console.log(pc2.cyan(" import { client } from './lib/software/client'"));
535
+ console.log(pc2.cyan(" const posts = await client.from('posts').find()"));
536
+ console.log();
537
+ } else if (env === "node") {
538
+ console.log(pc2.dim(" Use the server client:"));
539
+ console.log();
540
+ console.log(pc2.cyan(" import { serverClient } from './lib/software/server'"));
541
+ console.log(pc2.cyan(" const posts = await serverClient.from('posts').find()"));
542
+ console.log();
543
+ } else if (env === "edge") {
544
+ console.log(pc2.dim(" Pass your env bindings to createEdgeClient():"));
545
+ console.log();
546
+ console.log(pc2.cyan(" import { createEdgeClient } from './lib/software/server'"));
547
+ console.log(pc2.cyan(" const serverClient = createEdgeClient(env.CLIENT_KEY, env.SECRET_KEY)"));
548
+ console.log();
549
+ }
550
+ const missingClientKey = env !== "vanilla" && !answers.clientKey;
551
+ const missingSecretKey = (env === "nextjs" || env === "node") && !answers.secretKey;
552
+ if (missingClientKey || missingSecretKey) {
553
+ console.log(pc2.dim(" Update .env with your API keys"));
554
+ console.log();
555
+ }
556
+ if (answers.setupMcp && (!answers.clientKey || !answers.secretKey)) {
557
+ console.log(pc2.dim(" Update .mcp.json x-api-key with Base64(clientKey:secretKey)"));
558
+ console.log();
559
+ }
560
+ if (env !== "vanilla") {
561
+ console.log(pc2.cyan(` ${run} dev`));
562
+ console.log();
563
+ }
564
+ } catch (error) {
565
+ if (error instanceof Error && error.message === "cancelled") {
566
+ console.log(pc2.yellow(" Cancelled."));
567
+ process.exit(0);
568
+ }
569
+ console.error(pc2.red(" Error:"), error);
570
+ process.exit(1);
571
+ }
572
+ }
573
+ main();
574
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/detect.ts","../src/prompts.ts","../src/init.ts","../src/templates.ts"],"sourcesContent":["import pc from 'picocolors'\nimport { detectProject } from './detect'\nimport type { ProjectEnv } from './detect'\nimport { promptUser } from './prompts'\nimport { init } from './init'\n\nconst ENV_LABELS: Record<ProjectEnv, string> = {\n nextjs: 'Next.js',\n 'react-vite': 'React + Vite',\n 'react-cra': 'React + Webpack/CRA',\n vanilla: 'Vanilla JS',\n node: 'Node.js',\n edge: 'Edge runtime',\n other: 'Other framework',\n}\n\n// Manual setup guide for unsupported frameworks\nconst OTHER_FRAMEWORK_GUIDE = `\n Astro, Remix, SvelteKit, and other meta-frameworks have their own\n environment conventions. Manual setup:\n\n 1. Install the SDK:\n npm install @01.software/sdk\n\n 2. Browser client (client islands / RSC):\n import { createBrowserClient } from '@01.software/sdk'\n export const client = createBrowserClient({ clientKey: 'YOUR_CLIENT_KEY' })\n\n 3. Server client (SSR / loaders / endpoints):\n import { createServerClient } from '@01.software/sdk'\n export const serverClient = createServerClient({\n clientKey: process.env.PUBLIC_SOFTWARE_CLIENT_KEY!, // prefix varies by framework\n secretKey: process.env.SOFTWARE_SECRET_KEY!,\n })\n\n 4. Docs: https://01.software/docs/guide/quickstart\n`\n\nasync function main() {\n const cwd = process.cwd()\n\n console.log()\n console.log(pc.bold(' @01.software/init'))\n console.log(pc.dim(' Initialize 01.software SDK in your project'))\n console.log()\n\n // 1. Detect project\n const info = detectProject(cwd)\n\n if (!info.hasPackageJson) {\n console.log(pc.red(' No package.json found in the current directory.'))\n console.log(pc.dim(' Run this command inside an existing project.'))\n console.log()\n process.exit(1)\n }\n\n // Show detected environment\n const detectedParts: string[] = [ENV_LABELS[info.env]]\n if (info.packageManager) detectedParts.push(info.packageManager)\n if (info.srcDir) detectedParts.push('src/')\n\n if (info.env !== 'node') {\n // Only show detected label when it's unambiguous\n console.log(pc.dim(` Detected: ${detectedParts.join(' / ')}`))\n console.log()\n }\n\n try {\n // 2. Prompt\n const answers = await promptUser(info.hasSdk, info.env, info.packageManager)\n if (!answers) {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n\n // \"Other\" framework — print guide and exit\n if (answers.env === 'other') {\n console.log(pc.yellow(' Manual setup required for your framework:'))\n console.log(OTHER_FRAMEWORK_GUIDE)\n process.exit(0)\n }\n\n // Resolve package manager from detection or user selection\n const resolvedPm = info.packageManager ?? answers.packageManager ?? 'npm'\n const resolvedInfo = { ...info, packageManager: resolvedPm }\n\n // 3. Init\n console.log()\n await init(cwd, resolvedInfo, answers)\n\n // 4. Next steps\n const env = answers.env\n const run = resolvedPm === 'npm' ? 'npm run' : resolvedPm\n\n console.log()\n console.log(pc.green(' Done!'))\n console.log()\n console.log(' Next steps:')\n console.log()\n\n if (env === 'nextjs') {\n console.log(pc.dim(' Add QueryProvider to your root layout:'))\n console.log()\n console.log(pc.cyan(\" import { QueryProvider } from '@/lib/software/query-provider'\"))\n console.log(pc.cyan(' <QueryProvider>{children}</QueryProvider>'))\n console.log()\n } else if (env === 'react-vite' || env === 'react-cra') {\n console.log(pc.dim(' Wrap your app entry with QueryProvider:'))\n console.log()\n console.log(pc.cyan(\" import { QueryProvider } from './lib/software/query-provider'\"))\n console.log(pc.cyan(' <QueryProvider><App /></QueryProvider>'))\n console.log()\n } else if (env === 'vanilla') {\n console.log(pc.dim(' Replace YOUR_CLIENT_KEY in lib/software/client.ts'))\n console.log()\n console.log(pc.cyan(\" import { client } from './lib/software/client'\"))\n console.log(pc.cyan(\" const posts = await client.from('posts').find()\"))\n console.log()\n } else if (env === 'node') {\n console.log(pc.dim(' Use the server client:'))\n console.log()\n console.log(pc.cyan(\" import { serverClient } from './lib/software/server'\"))\n console.log(pc.cyan(\" const posts = await serverClient.from('posts').find()\"))\n console.log()\n } else if (env === 'edge') {\n console.log(pc.dim(' Pass your env bindings to createEdgeClient():'))\n console.log()\n console.log(pc.cyan(\" import { createEdgeClient } from './lib/software/server'\"))\n console.log(pc.cyan(' const serverClient = createEdgeClient(env.CLIENT_KEY, env.SECRET_KEY)'))\n console.log()\n }\n\n const missingClientKey = env !== 'vanilla' && !answers.clientKey\n const missingSecretKey = (env === 'nextjs' || env === 'node') && !answers.secretKey\n if (missingClientKey || missingSecretKey) {\n console.log(pc.dim(' Update .env with your API keys'))\n console.log()\n }\n if (answers.setupMcp && (!answers.clientKey || !answers.secretKey)) {\n console.log(pc.dim(' Update .mcp.json x-api-key with Base64(clientKey:secretKey)'))\n console.log()\n }\n if (env !== 'vanilla') {\n console.log(pc.cyan(` ${run} dev`))\n console.log()\n }\n } catch (error) {\n if (error instanceof Error && error.message === 'cancelled') {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n console.error(pc.red(' Error:'), error)\n process.exit(1)\n }\n}\n\nmain()\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\nexport type ProjectEnv =\n | 'nextjs'\n | 'react-vite'\n | 'react-cra'\n | 'vanilla'\n | 'node'\n | 'edge'\n | 'other' // Astro, Remix, SvelteKit, etc. — print guidance only\n\nexport interface ProjectInfo {\n hasPackageJson: boolean\n env: ProjectEnv\n packageManager: PackageManager | null\n hasSdk: boolean\n srcDir: boolean\n}\n\nexport function detectProject(cwd: string): ProjectInfo {\n const pkgPath = path.join(cwd, 'package.json')\n const hasPackageJson = fs.existsSync(pkgPath)\n\n let env: ProjectEnv = 'node'\n let hasSdk = false\n\n if (hasPackageJson) {\n let pkg: Record<string, unknown>\n try {\n pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n } catch {\n return { hasPackageJson: false, env: 'node', packageManager: null, hasSdk: false, srcDir: false }\n }\n\n const deps = {\n ...((pkg.dependencies as Record<string, string>) || {}),\n ...((pkg.devDependencies as Record<string, string>) || {}),\n }\n hasSdk = '@01.software/sdk' in deps\n\n if ('next' in deps) {\n env = 'nextjs'\n } else if ('astro' in deps || '@astrojs/node' in deps) {\n env = 'other'\n } else if ('@remix-run/node' in deps || '@remix-run/react' in deps) {\n env = 'other'\n } else if ('@sveltejs/kit' in deps) {\n env = 'other'\n } else if ('react' in deps) {\n if ('vite' in deps) {\n env = 'react-vite'\n } else if ('react-scripts' in deps) {\n env = 'react-cra'\n } else {\n // React + unknown bundler (Webpack, Parcel, etc.) — leave as 'node'\n // so the prompt selector is shown\n env = 'node'\n }\n }\n // else: no react/next → 'node' (covers real Node.js, Deno, Bun, etc.)\n }\n\n // Detect package manager from lockfile\n let packageManager: PackageManager | null = null\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {\n packageManager = 'pnpm'\n } else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {\n packageManager = 'yarn'\n } else if (\n fs.existsSync(path.join(cwd, 'bun.lockb')) ||\n fs.existsSync(path.join(cwd, 'bun.lock'))\n ) {\n packageManager = 'bun'\n } else if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {\n packageManager = 'npm'\n }\n\n // Detect src directory structure\n const srcDir =\n env === 'nextjs'\n ? fs.existsSync(path.join(cwd, 'src', 'app'))\n : fs.existsSync(path.join(cwd, 'src'))\n\n return { hasPackageJson, env, packageManager, hasSdk, srcDir }\n}\n\n/** Environments that generate a browser client file */\nexport function needsClient(env: ProjectEnv): boolean {\n return env === 'nextjs' || env === 'react-vite' || env === 'react-cra' || env === 'vanilla'\n}\n\n/** Environments that generate a server client file */\nexport function needsServer(env: ProjectEnv): boolean {\n return env === 'nextjs' || env === 'node' || env === 'edge'\n}\n\n/** Environments that generate a query-provider file */\nexport function needsReactQuery(env: ProjectEnv): boolean {\n return env === 'nextjs' || env === 'react-vite' || env === 'react-cra'\n}\n\n/** Environments that support MCP setup (need both client + secret key) */\nexport function supportsMcp(env: ProjectEnv): boolean {\n return env === 'nextjs' || env === 'node' || env === 'edge'\n}\n\n/** Get the env var name for the public client key */\nexport function getClientKeyEnvVar(env: ProjectEnv): string {\n switch (env) {\n case 'nextjs':\n return 'NEXT_PUBLIC_SOFTWARE_CLIENT_KEY'\n case 'react-vite':\n return 'VITE_SOFTWARE_CLIENT_KEY'\n case 'react-cra':\n return 'REACT_APP_SOFTWARE_CLIENT_KEY'\n default:\n return 'SOFTWARE_CLIENT_KEY'\n }\n}\n","import prompts from 'prompts'\nimport type { PackageManager, ProjectEnv } from './detect'\nimport { supportsMcp } from './detect'\n\nexport interface InitAnswers {\n env: ProjectEnv\n clientKey: string\n secretKey: string\n setupMcp: boolean\n packageManager?: PackageManager\n}\n\n// Envs that need the user to disambiguate (couldn't be auto-detected)\nconst AMBIGUOUS_ENVS: ProjectEnv[] = ['node']\n\nexport async function promptUser(\n hasSdk: boolean,\n detectedEnv: ProjectEnv,\n detectedPm: PackageManager | null,\n): Promise<InitAnswers | null> {\n const onCancel = () => {\n throw new Error('cancelled')\n }\n\n // Confirm re-init if SDK already installed\n if (hasSdk) {\n const { proceed } = await prompts(\n {\n type: 'confirm',\n name: 'proceed',\n message: '@01.software/sdk is already installed. Re-initialize?',\n initial: false,\n },\n { onCancel },\n )\n if (!proceed) return null\n }\n\n // Ask for environment when auto-detection is ambiguous\n let env = detectedEnv\n if (AMBIGUOUS_ENVS.includes(detectedEnv)) {\n const { selectedEnv } = await prompts(\n {\n type: 'select',\n name: 'selectedEnv',\n message: 'Which environment are you using?',\n choices: [\n {\n title: 'Next.js',\n description: 'Full-stack React (client + server)',\n value: 'nextjs',\n },\n {\n title: 'React + Vite',\n description: 'Client-only SPA with Vite',\n value: 'react-vite',\n },\n {\n title: 'React + Webpack / other',\n description: 'Client-only SPA, CRA or custom bundler',\n value: 'react-cra',\n },\n {\n title: 'Vanilla JS',\n description: 'Browser app without a framework',\n value: 'vanilla',\n },\n {\n title: 'Node.js / Bun / Deno',\n description: 'Server-only, no browser client',\n value: 'node',\n },\n {\n title: 'Edge runtime',\n description: 'Cloudflare Workers, Vercel Edge Functions',\n value: 'edge',\n },\n {\n title: 'Other (Astro / Remix / SvelteKit…)',\n description: 'Print manual setup guide for your framework',\n value: 'other',\n },\n ],\n },\n { onCancel },\n )\n env = selectedEnv as ProjectEnv\n }\n\n // \"Other\" frameworks — we can't scaffold correctly; exit with guidance\n if (env === 'other') {\n return { env, clientKey: '', secretKey: '', setupMcp: false, packageManager: undefined }\n }\n\n // Ask for package manager if no lockfile detected\n let packageManager: PackageManager | undefined\n if (!detectedPm) {\n const { pm } = await prompts(\n {\n type: 'select',\n name: 'pm',\n message: 'Which package manager do you use?',\n choices: [\n { title: 'npm', value: 'npm' },\n { title: 'pnpm', value: 'pnpm' },\n { title: 'yarn', value: 'yarn' },\n { title: 'bun', value: 'bun' },\n ],\n },\n { onCancel },\n )\n packageManager = pm\n }\n\n const needsSecretKey = env === 'nextjs' || env === 'node' || env === 'edge'\n\n const keyPrompts: prompts.PromptObject[] = []\n\n // Vanilla JS doesn't use env vars — no prompts for keys\n if (env !== 'vanilla') {\n keyPrompts.push({\n type: 'text',\n name: 'clientKey',\n message: 'Client Key (optional, saved to .env)',\n initial: '',\n })\n }\n\n if (needsSecretKey) {\n keyPrompts.push({\n type: 'text',\n name: 'secretKey',\n message: 'Secret Key (optional, saved to .env)',\n initial: '',\n })\n }\n\n const keys = keyPrompts.length > 0 ? await prompts(keyPrompts, { onCancel }) : {}\n\n // MCP requires both client + secret key\n let setupMcp = false\n if (supportsMcp(env)) {\n const result = await prompts(\n {\n type: 'confirm',\n name: 'setupMcp',\n message: 'Set up MCP integration? (.mcp.json)',\n initial: true,\n },\n { onCancel },\n )\n setupMcp = result.setupMcp\n }\n\n return {\n env,\n clientKey: (keys as Record<string, string>).clientKey ?? '',\n secretKey: (keys as Record<string, string>).secretKey ?? '',\n setupMcp,\n packageManager,\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync } from 'node:child_process'\nimport pc from 'picocolors'\nimport type { PackageManager, ProjectInfo } from './detect'\nimport {\n needsClient,\n needsServer,\n needsReactQuery,\n getClientKeyEnvVar,\n} from './detect'\nimport type { InitAnswers } from './prompts'\nimport {\n getClientTemplate,\n getQueryProviderTemplate,\n getServerTemplate,\n getEnvContent,\n getMcpConfigTemplate,\n getMcpServerEntry,\n} from './templates'\n\ntype ResolvedProjectInfo = Omit<ProjectInfo, 'packageManager'> & {\n packageManager: PackageManager\n}\n\nconst SECRET_KEY_ENV_VAR = 'SOFTWARE_SECRET_KEY'\n\nexport async function init(\n cwd: string,\n info: ResolvedProjectInfo,\n answers: InitAnswers,\n): Promise<void> {\n const { packageManager, srcDir } = info\n const env = answers.env\n const baseDir = srcDir ? path.join(cwd, 'src') : cwd\n\n const clientKeyEnvVar = getClientKeyEnvVar(env)\n const wantsClient = needsClient(env)\n const wantsServer = needsServer(env)\n const wantsReactQuery = needsReactQuery(env)\n\n // 1. Install dependencies\n const deps = ['@01.software/sdk']\n if (wantsReactQuery) deps.push('@tanstack/react-query')\n\n console.log(pc.dim(` Installing ${deps.join(' and ')}...`))\n\n // pnpm-workspace.yaml without packages: breaks pnpm add — patch temporarily\n const wsPatched = packageManager === 'pnpm' && patchPnpmWorkspace(cwd)\n\n const pkgs = deps.join(' ')\n const pnpmFlag = hasPnpmWorkspace(cwd) ? ' -w' : ''\n const addCmd =\n packageManager === 'pnpm'\n ? `pnpm add${pnpmFlag} ${pkgs}`\n : packageManager === 'yarn'\n ? `yarn add ${pkgs}`\n : packageManager === 'bun'\n ? `bun add ${pkgs}`\n : `npm install ${pkgs}`\n\n try {\n execSync(addCmd, { cwd, stdio: 'pipe' })\n } catch (error) {\n const err = error as { stdout?: Buffer; stderr?: Buffer }\n const msg =\n String(err.stderr || '').trim() ||\n String(err.stdout || '').trim() ||\n String(error)\n console.log(pc.red(' Failed to install dependencies:'))\n console.log(pc.dim(` ${msg}`))\n throw error\n } finally {\n if (wsPatched) restorePnpmWorkspace(cwd)\n }\n\n // 2. Write lib/software/ files\n const libDir = path.join(baseDir, 'lib', 'software')\n fs.mkdirSync(libDir, { recursive: true })\n\n // Client (browser)\n if (wantsClient) {\n const clientPath = path.join(libDir, 'client.ts')\n if (fs.existsSync(clientPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, clientPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(clientPath, getClientTemplate(env, clientKeyEnvVar))\n console.log(pc.green(' Created'), relativePath(cwd, clientPath))\n }\n }\n\n // Query Provider (React)\n if (wantsReactQuery) {\n const queryProviderPath = path.join(libDir, 'query-provider.tsx')\n if (fs.existsSync(queryProviderPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, queryProviderPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(queryProviderPath, getQueryProviderTemplate(env))\n console.log(pc.green(' Created'), relativePath(cwd, queryProviderPath))\n }\n }\n\n // Server\n if (wantsServer) {\n const serverPath = path.join(libDir, 'server.ts')\n if (fs.existsSync(serverPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, serverPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(serverPath, getServerTemplate(env, clientKeyEnvVar, SECRET_KEY_ENV_VAR))\n console.log(pc.green(' Created'), relativePath(cwd, serverPath))\n }\n }\n\n // 3. Append to .env (vanilla uses inline key, no env file needed)\n if (env !== 'vanilla' && env !== 'edge') {\n const envPath = path.join(cwd, '.env')\n const envContent = getEnvContent(\n answers.clientKey || '',\n answers.secretKey || '',\n clientKeyEnvVar,\n wantsServer ? SECRET_KEY_ENV_VAR : null,\n )\n\n if (fs.existsSync(envPath)) {\n const existing = fs.readFileSync(envPath, 'utf-8')\n if (existing.includes(clientKeyEnvVar)) {\n console.log(pc.yellow(' Skipped'), '.env', pc.dim('(keys already present)'))\n } else {\n fs.appendFileSync(envPath, envContent)\n console.log(pc.green(' Updated'), '.env')\n }\n } else {\n fs.writeFileSync(envPath, envContent.trimStart())\n console.log(pc.green(' Created'), '.env')\n }\n }\n\n // 4. Write .mcp.json (MCP integration)\n if (answers.setupMcp) {\n const clientKey = answers.clientKey || ''\n const secretKey = answers.secretKey || ''\n const apiKey =\n clientKey && secretKey\n ? Buffer.from(`${clientKey}:${secretKey}`).toString('base64')\n : 'YOUR_API_KEY'\n\n const mcpPath = path.join(cwd, '.mcp.json')\n if (fs.existsSync(mcpPath)) {\n try {\n const existing = JSON.parse(fs.readFileSync(mcpPath, 'utf-8'))\n if (existing.mcpServers?.['01software']) {\n console.log(pc.yellow(' Skipped'), '.mcp.json', pc.dim('(01software already configured)'))\n } else {\n existing.mcpServers = existing.mcpServers || {}\n existing.mcpServers['01software'] = getMcpServerEntry(apiKey)\n fs.writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + '\\n')\n console.log(pc.green(' Updated'), '.mcp.json')\n }\n } catch {\n console.log(pc.yellow(' Skipped'), '.mcp.json', pc.dim('(could not parse existing file)'))\n }\n } else {\n fs.writeFileSync(mcpPath, getMcpConfigTemplate(apiKey))\n console.log(pc.green(' Created'), '.mcp.json')\n }\n\n // 5. Add .mcp.json to .gitignore (contains API key)\n const gitignorePath = path.join(cwd, '.gitignore')\n if (fs.existsSync(gitignorePath)) {\n const gitignore = fs.readFileSync(gitignorePath, 'utf-8')\n if (!gitignore.includes('.mcp.json')) {\n fs.appendFileSync(gitignorePath, '\\n# MCP config (contains API key)\\n.mcp.json\\n')\n console.log(pc.green(' Updated'), '.gitignore', pc.dim('(added .mcp.json)'))\n }\n }\n }\n}\n\nfunction relativePath(cwd: string, filePath: string): string {\n return path.relative(cwd, filePath)\n}\n\nconst WS_FILE = 'pnpm-workspace.yaml'\nconst WS_BACKUP = 'pnpm-workspace.yaml.bak'\n\nfunction hasPnpmWorkspace(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, WS_FILE))\n}\n\nfunction patchPnpmWorkspace(cwd: string): boolean {\n const wsPath = path.join(cwd, WS_FILE)\n if (!fs.existsSync(wsPath)) return false\n const content = fs.readFileSync(wsPath, 'utf-8')\n if (content.includes('packages:')) return false\n fs.copyFileSync(wsPath, path.join(cwd, WS_BACKUP))\n fs.writeFileSync(wsPath, content.trimEnd() + '\\npackages: []\\n')\n return true\n}\n\nfunction restorePnpmWorkspace(cwd: string): void {\n const backupPath = path.join(cwd, WS_BACKUP)\n if (!fs.existsSync(backupPath)) return\n fs.copyFileSync(backupPath, path.join(cwd, WS_FILE))\n fs.unlinkSync(backupPath)\n}\n","import type { ProjectEnv } from './detect'\n\n// ── Client template (browser) ────────────────────────────────────────\n\nexport function getClientTemplate(env: ProjectEnv, clientKeyEnvVar: string): string {\n if (env === 'nextjs') {\n return `import { createBrowserClient } from '@01.software/sdk'\n\nexport const client = createBrowserClient({\n clientKey: process.env.${clientKeyEnvVar}!,\n})\n`\n }\n\n if (env === 'react-cra') {\n return `import { createBrowserClient } from '@01.software/sdk'\n\nexport const client = createBrowserClient({\n clientKey: process.env.${clientKeyEnvVar}!,\n})\n`\n }\n\n if (env === 'vanilla') {\n return `import { createBrowserClient } from '@01.software/sdk'\n\n// Replace 'YOUR_CLIENT_KEY' with your actual client key from the 01.software console\nexport const client = createBrowserClient({\n clientKey: 'YOUR_CLIENT_KEY',\n})\n`\n }\n\n // react-vite (import.meta.env)\n return `import { createBrowserClient } from '@01.software/sdk'\n\nexport const client = createBrowserClient({\n clientKey: import.meta.env.${clientKeyEnvVar},\n})\n`\n}\n\n// ── Query Provider template ──────────────────────────────────────────\n\nexport function getQueryProviderTemplate(env: ProjectEnv): string {\n const useClientDirective = env === 'nextjs' ? \"'use client'\\n\\n\" : ''\n\n return `${useClientDirective}import { QueryClientProvider } from '@tanstack/react-query'\nimport { client } from './client'\n\nexport function QueryProvider({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={client.queryClient}>\n {children}\n </QueryClientProvider>\n )\n}\n`\n}\n\n// ── Server template ──────────────────────────────────────────────────\n\nexport function getServerTemplate(\n env: ProjectEnv,\n clientKeyEnvVar: string,\n secretKeyEnvVar: string,\n): string {\n if (env === 'edge') {\n return `import { createServerClient } from '@01.software/sdk'\n\n// Edge runtime: pass your env bindings here\n// e.g. Cloudflare Workers: use env.SOFTWARE_CLIENT_KEY from the handler context\n// e.g. Vercel Edge: use process.env.${clientKeyEnvVar}\nexport function createEdgeClient(clientKey: string, secretKey: string) {\n return createServerClient({ clientKey, secretKey })\n}\n`\n }\n\n return `import { createServerClient } from '@01.software/sdk'\n\nexport const serverClient = createServerClient({\n clientKey: process.env.${clientKeyEnvVar}!,\n secretKey: process.env.${secretKeyEnvVar}!,\n})\n`\n}\n\n// ── Env file content ─────────────────────────────────────────────────\n\nexport function getEnvContent(\n clientKey: string,\n secretKey: string,\n clientKeyEnvVar: string,\n secretKeyEnvVar: string | null,\n): string {\n let content = `\\n# 01.software\\n${clientKeyEnvVar}=${clientKey}\\n`\n if (secretKeyEnvVar) {\n content += `${secretKeyEnvVar}=${secretKey}\\n`\n }\n return content\n}\n\n// ── MCP config ───────────────────────────────────────────────────────\n\nexport function getMcpServerEntry(apiKey: string) {\n return {\n type: 'http' as const,\n url: 'https://mcp.01.software/mcp',\n headers: { 'x-api-key': apiKey },\n }\n}\n\nexport function getMcpConfigTemplate(apiKey: string): string {\n return (\n JSON.stringify(\n { mcpServers: { '01software': getMcpServerEntry(apiKey) } },\n null,\n 2,\n ) + '\\n'\n )\n}\n"],"mappings":"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","names":["pc","fs","path","path","fs","pc"]}
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@01.software/init",
3
- "version": "0.1.2",
4
- "description": "Initialize 01.software SDK in your Next.js project",
3
+ "version": "0.1.4",
4
+ "description": "Initialize 01.software SDK in your project (Next.js, React, Vanilla JS, Node.js, Edge)",
5
+ "type": "module",
5
6
  "bin": {
6
- "01-init": "./dist/index.mjs"
7
+ "01-init": "./dist/index.js"
7
8
  },
8
9
  "files": [
9
10
  "dist"
10
11
  ],
11
- "scripts": {
12
- "build": "tsup",
13
- "dev": "tsup --watch",
14
- "check-types": "tsc --noEmit"
12
+ "engines": {
13
+ "node": ">=18.0.0"
15
14
  },
16
15
  "dependencies": {
17
16
  "prompts": "^2.4.2",
@@ -25,5 +24,16 @@
25
24
  "publishConfig": {
26
25
  "access": "public"
27
26
  },
28
- "license": "MIT"
29
- }
27
+ "scripts": {
28
+ "build": "tsup",
29
+ "dev": "tsup --watch",
30
+ "check-types": "tsc --noEmit",
31
+ "version:dev": "node ../../scripts/update-version.js",
32
+ "publish:dev": "pnpm run version:dev && pnpm publish --no-git-checks --access public --tag dev",
33
+ "publish:local": "pnpm run version:dev && pnpm publish --no-git-checks --access public --tag local",
34
+ "version:patch": "pnpm version patch --no-git-tag-version",
35
+ "version:minor": "pnpm version minor --no-git-tag-version",
36
+ "version:major": "pnpm version major --no-git-tag-version",
37
+ "publish:prod": "pnpm publish --access public"
38
+ }
39
+ }
package/dist/index.mjs DELETED
@@ -1,318 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/index.ts
4
- import pc2 from "picocolors";
5
-
6
- // src/detect.ts
7
- import fs from "fs";
8
- import path from "path";
9
- function detectProject(cwd) {
10
- const pkgPath = path.join(cwd, "package.json");
11
- const hasPackageJson = fs.existsSync(pkgPath);
12
- let isNextProject = false;
13
- let hasSdk = false;
14
- if (hasPackageJson) {
15
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
16
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
17
- isNextProject = "next" in allDeps;
18
- hasSdk = "@01.software/sdk" in allDeps;
19
- }
20
- let packageManager = null;
21
- if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
22
- packageManager = "pnpm";
23
- } else if (fs.existsSync(path.join(cwd, "yarn.lock"))) {
24
- packageManager = "yarn";
25
- } else if (fs.existsSync(path.join(cwd, "bun.lockb")) || fs.existsSync(path.join(cwd, "bun.lock"))) {
26
- packageManager = "bun";
27
- } else if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
28
- packageManager = "npm";
29
- }
30
- const srcDir = fs.existsSync(path.join(cwd, "src", "app"));
31
- return { hasPackageJson, isNextProject, packageManager, hasSdk, srcDir };
32
- }
33
-
34
- // src/prompts.ts
35
- import prompts from "prompts";
36
- async function promptUser(hasSdk, detectedPm) {
37
- const onCancel = () => {
38
- throw new Error("cancelled");
39
- };
40
- if (hasSdk) {
41
- const { proceed } = await prompts(
42
- {
43
- type: "confirm",
44
- name: "proceed",
45
- message: "@01.software/sdk is already installed. Re-initialize?",
46
- initial: false
47
- },
48
- { onCancel }
49
- );
50
- if (!proceed) return null;
51
- }
52
- let packageManager;
53
- if (!detectedPm) {
54
- const { pm } = await prompts(
55
- {
56
- type: "select",
57
- name: "pm",
58
- message: "Which package manager do you use?",
59
- choices: [
60
- { title: "npm", value: "npm" },
61
- { title: "pnpm", value: "pnpm" },
62
- { title: "yarn", value: "yarn" },
63
- { title: "bun", value: "bun" }
64
- ]
65
- },
66
- { onCancel }
67
- );
68
- packageManager = pm;
69
- }
70
- const response = await prompts(
71
- [
72
- {
73
- type: "text",
74
- name: "clientKey",
75
- message: "Client Key (optional, saved to .env)",
76
- initial: ""
77
- }
78
- ],
79
- { onCancel }
80
- );
81
- return { ...response, packageManager };
82
- }
83
-
84
- // src/init.ts
85
- import fs2 from "fs";
86
- import path2 from "path";
87
- import { execSync } from "child_process";
88
- import pc from "picocolors";
89
-
90
- // src/templates.ts
91
- function getClientTemplate() {
92
- return `import { createBrowserClient } from '@01.software/sdk'
93
-
94
- export const client = createBrowserClient({
95
- clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
96
- })
97
- `;
98
- }
99
- function getQueryProviderTemplate() {
100
- return `'use client'
101
-
102
- import { QueryClientProvider } from '@tanstack/react-query'
103
- import { client } from './client'
104
-
105
- export function QueryProvider({ children }: { children: React.ReactNode }) {
106
- return (
107
- <QueryClientProvider client={client.queryClient}>
108
- {children}
109
- </QueryClientProvider>
110
- )
111
- }
112
- `;
113
- }
114
- function getServerTemplate() {
115
- return `import { createServerClient } from '@01.software/sdk'
116
-
117
- export const serverClient = createServerClient({
118
- clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
119
- secretKey: process.env.SOFTWARE_SECRET_KEY!,
120
- })
121
- `;
122
- }
123
- function getPageTemplate() {
124
- return `'use client'
125
-
126
- import { client } from '@/lib/software/client'
127
-
128
- export default function Home() {
129
- const { data, isLoading } = client.query.useQuery({
130
- collection: 'products',
131
- options: { limit: 10 },
132
- })
133
-
134
- return (
135
- <main style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>
136
- <h1>My App</h1>
137
- <p>Built with <a href="https://01.software">01.software</a> SDK</p>
138
-
139
- <h2>Products</h2>
140
- {isLoading ? (
141
- <p>Loading...</p>
142
- ) : (
143
- <ul>
144
- {data?.docs.map((product) => (
145
- <li key={product.id}>{product.title ?? product.id}</li>
146
- ))}
147
- {data?.docs.length === 0 && <li>No products found</li>}
148
- </ul>
149
- )}
150
- </main>
151
- )
152
- }
153
- `;
154
- }
155
- function getEnvContent(clientKey) {
156
- return `
157
- # 01.software
158
- NEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}
159
- SOFTWARE_SECRET_KEY=
160
- `;
161
- }
162
-
163
- // src/init.ts
164
- async function init(cwd, info, answers) {
165
- const { packageManager, srcDir } = info;
166
- const baseDir = srcDir ? path2.join(cwd, "src") : cwd;
167
- console.log(pc.dim(" Installing @01.software/sdk and @tanstack/react-query..."));
168
- const wsPatched = packageManager === "pnpm" && patchPnpmWorkspace(cwd);
169
- const pkgs = "@01.software/sdk @tanstack/react-query";
170
- const pnpmFlag = hasPnpmWorkspace(cwd) ? " -w" : "";
171
- const addCmd = packageManager === "pnpm" ? `pnpm add${pnpmFlag} ${pkgs}` : packageManager === "yarn" ? `yarn add ${pkgs}` : packageManager === "bun" ? `bun add ${pkgs}` : `npm add ${pkgs}`;
172
- try {
173
- execSync(addCmd, { cwd, stdio: "pipe" });
174
- } catch (error) {
175
- const err = error;
176
- const msg = String(err.stderr || "").trim() || String(err.stdout || "").trim() || String(error);
177
- console.log(pc.red(" Failed to install dependencies:"));
178
- console.log(pc.dim(` ${msg}`));
179
- throw error;
180
- } finally {
181
- if (wsPatched) restorePnpmWorkspace(cwd);
182
- }
183
- const libDir = path2.join(baseDir, "lib", "software");
184
- fs2.mkdirSync(libDir, { recursive: true });
185
- const clientPath = path2.join(libDir, "client.ts");
186
- if (fs2.existsSync(clientPath)) {
187
- console.log(pc.yellow(" Skipped"), relativePath(cwd, clientPath), pc.dim("(already exists)"));
188
- } else {
189
- fs2.writeFileSync(clientPath, getClientTemplate());
190
- console.log(pc.green(" Created"), relativePath(cwd, clientPath));
191
- }
192
- const queryProviderPath = path2.join(libDir, "query-provider.tsx");
193
- if (fs2.existsSync(queryProviderPath)) {
194
- console.log(pc.yellow(" Skipped"), relativePath(cwd, queryProviderPath), pc.dim("(already exists)"));
195
- } else {
196
- fs2.writeFileSync(queryProviderPath, getQueryProviderTemplate());
197
- console.log(pc.green(" Created"), relativePath(cwd, queryProviderPath));
198
- }
199
- const serverPath = path2.join(libDir, "server.ts");
200
- if (fs2.existsSync(serverPath)) {
201
- console.log(pc.yellow(" Skipped"), relativePath(cwd, serverPath), pc.dim("(already exists)"));
202
- } else {
203
- fs2.writeFileSync(serverPath, getServerTemplate());
204
- console.log(pc.green(" Created"), relativePath(cwd, serverPath));
205
- }
206
- const appDir = path2.join(baseDir, "app");
207
- const pagePath = path2.join(appDir, "page.tsx");
208
- if (!fs2.existsSync(pagePath)) {
209
- fs2.mkdirSync(appDir, { recursive: true });
210
- fs2.writeFileSync(pagePath, getPageTemplate());
211
- console.log(pc.green(" Created"), relativePath(cwd, pagePath));
212
- }
213
- const envPath = path2.join(cwd, ".env");
214
- const envContent = getEnvContent(answers.clientKey || "");
215
- if (fs2.existsSync(envPath)) {
216
- const existing = fs2.readFileSync(envPath, "utf-8");
217
- if (existing.includes("NEXT_PUBLIC_SOFTWARE_CLIENT_KEY")) {
218
- console.log(pc.yellow(" Skipped"), ".env", pc.dim("(keys already present)"));
219
- } else {
220
- fs2.appendFileSync(envPath, envContent);
221
- console.log(pc.green(" Updated"), ".env");
222
- }
223
- } else {
224
- fs2.writeFileSync(envPath, envContent.trimStart());
225
- console.log(pc.green(" Created"), ".env");
226
- }
227
- }
228
- function relativePath(cwd, filePath) {
229
- return path2.relative(cwd, filePath);
230
- }
231
- var WS_FILE = "pnpm-workspace.yaml";
232
- var WS_BACKUP = "pnpm-workspace.yaml.bak";
233
- function hasPnpmWorkspace(cwd) {
234
- return fs2.existsSync(path2.join(cwd, WS_FILE));
235
- }
236
- function patchPnpmWorkspace(cwd) {
237
- const wsPath = path2.join(cwd, WS_FILE);
238
- if (!fs2.existsSync(wsPath)) return false;
239
- const content = fs2.readFileSync(wsPath, "utf-8");
240
- if (content.includes("packages:")) return false;
241
- fs2.copyFileSync(wsPath, path2.join(cwd, WS_BACKUP));
242
- fs2.writeFileSync(wsPath, content.trimEnd() + "\npackages: []\n");
243
- return true;
244
- }
245
- function restorePnpmWorkspace(cwd) {
246
- const backupPath = path2.join(cwd, WS_BACKUP);
247
- if (!fs2.existsSync(backupPath)) return;
248
- fs2.copyFileSync(backupPath, path2.join(cwd, WS_FILE));
249
- fs2.unlinkSync(backupPath);
250
- }
251
-
252
- // src/index.ts
253
- async function main() {
254
- const cwd = process.cwd();
255
- console.log();
256
- console.log(pc2.bold(" @01.software/init"));
257
- console.log(pc2.dim(" Initialize 01.software SDK in your Next.js project"));
258
- console.log();
259
- const info = detectProject(cwd);
260
- if (!info.hasPackageJson) {
261
- console.log(pc2.red(" No package.json found in the current directory."));
262
- console.log(pc2.dim(" Run this command inside an existing Next.js project."));
263
- console.log();
264
- process.exit(1);
265
- }
266
- if (!info.isNextProject) {
267
- console.log(pc2.red(" This does not appear to be a Next.js project."));
268
- console.log(pc2.dim(" Create one first: npx create-next-app my-app"));
269
- console.log();
270
- process.exit(1);
271
- }
272
- if (info.packageManager) {
273
- console.log(pc2.dim(` Detected: Next.js / ${info.packageManager} / ${info.srcDir ? "src/app" : "app"}`));
274
- } else {
275
- console.log(pc2.dim(` Detected: Next.js / ${info.srcDir ? "src/app" : "app"}`));
276
- }
277
- console.log();
278
- try {
279
- const answers = await promptUser(info.hasSdk, info.packageManager);
280
- if (!answers) {
281
- console.log(pc2.yellow(" Cancelled."));
282
- process.exit(0);
283
- }
284
- const resolvedPm = info.packageManager ?? answers.packageManager ?? "npm";
285
- const resolvedInfo = { ...info, packageManager: resolvedPm };
286
- console.log();
287
- await init(cwd, resolvedInfo, answers);
288
- const run = resolvedPm === "npm" ? "npm run" : resolvedPm;
289
- console.log();
290
- console.log(pc2.green(" Done!"));
291
- console.log();
292
- console.log(" Next steps:");
293
- console.log();
294
- console.log(pc2.dim(" Add the QueryProvider to your root layout:"));
295
- console.log();
296
- console.log(pc2.cyan(" import { QueryProvider } from '@/lib/software/query-provider'"));
297
- console.log();
298
- console.log(pc2.dim(" Wrap children with <QueryProvider>:"));
299
- console.log();
300
- console.log(pc2.cyan(" <QueryProvider>{children}</QueryProvider>"));
301
- console.log();
302
- if (!answers.clientKey) {
303
- console.log(pc2.dim(" Update .env with your API keys"));
304
- console.log();
305
- }
306
- console.log(pc2.cyan(` ${run} dev`));
307
- console.log();
308
- } catch (error) {
309
- if (error instanceof Error && error.message === "cancelled") {
310
- console.log(pc2.yellow(" Cancelled."));
311
- process.exit(0);
312
- }
313
- console.error(pc2.red(" Error:"), error);
314
- process.exit(1);
315
- }
316
- }
317
- main();
318
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/detect.ts","../src/prompts.ts","../src/init.ts","../src/templates.ts"],"sourcesContent":["import pc from 'picocolors'\nimport { detectProject } from './detect'\nimport { promptUser } from './prompts'\nimport { init } from './init'\n\nasync function main() {\n const cwd = process.cwd()\n\n console.log()\n console.log(pc.bold(' @01.software/init'))\n console.log(pc.dim(' Initialize 01.software SDK in your Next.js project'))\n console.log()\n\n // 1. Detect project\n const info = detectProject(cwd)\n\n if (!info.hasPackageJson) {\n console.log(pc.red(' No package.json found in the current directory.'))\n console.log(pc.dim(' Run this command inside an existing Next.js project.'))\n console.log()\n process.exit(1)\n }\n\n if (!info.isNextProject) {\n console.log(pc.red(' This does not appear to be a Next.js project.'))\n console.log(pc.dim(' Create one first: npx create-next-app my-app'))\n console.log()\n process.exit(1)\n }\n\n if (info.packageManager) {\n console.log(pc.dim(` Detected: Next.js / ${info.packageManager} / ${info.srcDir ? 'src/app' : 'app'}`))\n } else {\n console.log(pc.dim(` Detected: Next.js / ${info.srcDir ? 'src/app' : 'app'}`))\n }\n console.log()\n\n try {\n // 2. Prompt\n const answers = await promptUser(info.hasSdk, info.packageManager)\n if (!answers) {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n\n // Resolve package manager from detection or user selection\n const resolvedPm = info.packageManager ?? answers.packageManager ?? 'npm'\n const resolvedInfo = { ...info, packageManager: resolvedPm }\n\n // 3. Init\n console.log()\n await init(cwd, resolvedInfo, answers)\n\n // 4. Next steps\n const run = resolvedPm === 'npm' ? 'npm run' : resolvedPm\n\n console.log()\n console.log(pc.green(' Done!'))\n console.log()\n console.log(' Next steps:')\n console.log()\n console.log(pc.dim(' Add the QueryProvider to your root layout:'))\n console.log()\n console.log(pc.cyan(\" import { QueryProvider } from '@/lib/software/query-provider'\"))\n console.log()\n console.log(pc.dim(' Wrap children with <QueryProvider>:'))\n console.log()\n console.log(pc.cyan(' <QueryProvider>{children}</QueryProvider>'))\n console.log()\n if (!answers.clientKey) {\n console.log(pc.dim(' Update .env with your API keys'))\n console.log()\n }\n console.log(pc.cyan(` ${run} dev`))\n console.log()\n } catch (error) {\n if (error instanceof Error && error.message === 'cancelled') {\n console.log(pc.yellow(' Cancelled.'))\n process.exit(0)\n }\n console.error(pc.red(' Error:'), error)\n process.exit(1)\n }\n}\n\nmain()\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\nexport interface ProjectInfo {\n hasPackageJson: boolean\n isNextProject: boolean\n packageManager: PackageManager | null // null if no lockfile detected\n hasSdk: boolean\n srcDir: boolean // true if src/app exists, false if app exists at root\n}\n\nexport function detectProject(cwd: string): ProjectInfo {\n const pkgPath = path.join(cwd, 'package.json')\n const hasPackageJson = fs.existsSync(pkgPath)\n\n let isNextProject = false\n let hasSdk = false\n\n if (hasPackageJson) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }\n isNextProject = 'next' in allDeps\n hasSdk = '@01.software/sdk' in allDeps\n }\n\n // Detect package manager from lockfile\n let packageManager: PackageManager | null = null\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {\n packageManager = 'pnpm'\n } else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {\n packageManager = 'yarn'\n } else if (\n fs.existsSync(path.join(cwd, 'bun.lockb')) ||\n fs.existsSync(path.join(cwd, 'bun.lock'))\n ) {\n packageManager = 'bun'\n } else if (fs.existsSync(path.join(cwd, 'package-lock.json'))) {\n packageManager = 'npm'\n }\n\n // Detect src/app vs app directory structure\n const srcDir = fs.existsSync(path.join(cwd, 'src', 'app'))\n\n return { hasPackageJson, isNextProject, packageManager, hasSdk, srcDir }\n}\n","import prompts from 'prompts'\nimport type { PackageManager } from './detect'\n\nexport interface InitAnswers {\n clientKey: string\n packageManager?: PackageManager\n}\n\nexport async function promptUser(\n hasSdk: boolean,\n detectedPm: PackageManager | null,\n): Promise<InitAnswers | null> {\n const onCancel = () => {\n throw new Error('cancelled')\n }\n\n // Confirm re-init if SDK already installed\n if (hasSdk) {\n const { proceed } = await prompts(\n {\n type: 'confirm',\n name: 'proceed',\n message: '@01.software/sdk is already installed. Re-initialize?',\n initial: false,\n },\n { onCancel },\n )\n if (!proceed) return null\n }\n\n // Ask for package manager if no lockfile detected\n let packageManager: PackageManager | undefined\n if (!detectedPm) {\n const { pm } = await prompts(\n {\n type: 'select',\n name: 'pm',\n message: 'Which package manager do you use?',\n choices: [\n { title: 'npm', value: 'npm' },\n { title: 'pnpm', value: 'pnpm' },\n { title: 'yarn', value: 'yarn' },\n { title: 'bun', value: 'bun' },\n ],\n },\n { onCancel },\n )\n packageManager = pm\n }\n\n const response = await prompts(\n [\n {\n type: 'text',\n name: 'clientKey',\n message: 'Client Key (optional, saved to .env)',\n initial: '',\n },\n ],\n { onCancel },\n )\n\n return { ...response, packageManager } as InitAnswers\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync } from 'node:child_process'\nimport pc from 'picocolors'\nimport type { PackageManager, ProjectInfo } from './detect'\n\ntype ResolvedProjectInfo = Omit<ProjectInfo, 'packageManager'> & {\n packageManager: PackageManager\n}\nimport type { InitAnswers } from './prompts'\nimport {\n getClientTemplate,\n getQueryProviderTemplate,\n getServerTemplate,\n getPageTemplate,\n getEnvContent,\n} from './templates'\n\nexport async function init(\n cwd: string,\n info: ResolvedProjectInfo,\n answers: InitAnswers,\n): Promise<void> {\n const { packageManager, srcDir } = info\n const baseDir = srcDir ? path.join(cwd, 'src') : cwd\n\n // 1. Install dependencies\n console.log(pc.dim(' Installing @01.software/sdk and @tanstack/react-query...'))\n\n // pnpm-workspace.yaml without packages: breaks pnpm add — patch temporarily\n const wsPatched = packageManager === 'pnpm' && patchPnpmWorkspace(cwd)\n\n const pkgs = '@01.software/sdk @tanstack/react-query'\n const pnpmFlag = hasPnpmWorkspace(cwd) ? ' -w' : ''\n const addCmd =\n packageManager === 'pnpm'\n ? `pnpm add${pnpmFlag} ${pkgs}`\n : packageManager === 'yarn'\n ? `yarn add ${pkgs}`\n : packageManager === 'bun'\n ? `bun add ${pkgs}`\n : `npm add ${pkgs}`\n\n try {\n execSync(addCmd, { cwd, stdio: 'pipe' })\n } catch (error) {\n const err = error as { stdout?: Buffer; stderr?: Buffer }\n const msg =\n String(err.stderr || '').trim() || String(err.stdout || '').trim() || String(error)\n console.log(pc.red(' Failed to install dependencies:'))\n console.log(pc.dim(` ${msg}`))\n throw error\n } finally {\n if (wsPatched) restorePnpmWorkspace(cwd)\n }\n\n // 2. Write lib/software/client.ts\n const libDir = path.join(baseDir, 'lib', 'software')\n fs.mkdirSync(libDir, { recursive: true })\n\n const clientPath = path.join(libDir, 'client.ts')\n if (fs.existsSync(clientPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, clientPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(clientPath, getClientTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, clientPath))\n }\n\n // 3. Write lib/software/query-provider.tsx\n const queryProviderPath = path.join(libDir, 'query-provider.tsx')\n if (fs.existsSync(queryProviderPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, queryProviderPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(queryProviderPath, getQueryProviderTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, queryProviderPath))\n }\n\n // 4. Write lib/software/server.ts\n const serverPath = path.join(libDir, 'server.ts')\n if (fs.existsSync(serverPath)) {\n console.log(pc.yellow(' Skipped'), relativePath(cwd, serverPath), pc.dim('(already exists)'))\n } else {\n fs.writeFileSync(serverPath, getServerTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, serverPath))\n }\n\n // 5. Write app/page.tsx (only if no existing page)\n const appDir = path.join(baseDir, 'app')\n const pagePath = path.join(appDir, 'page.tsx')\n if (!fs.existsSync(pagePath)) {\n fs.mkdirSync(appDir, { recursive: true })\n fs.writeFileSync(pagePath, getPageTemplate())\n console.log(pc.green(' Created'), relativePath(cwd, pagePath))\n }\n\n // 6. Append to .env (skip if keys already present)\n const envPath = path.join(cwd, '.env')\n const envContent = getEnvContent(answers.clientKey || '')\n if (fs.existsSync(envPath)) {\n const existing = fs.readFileSync(envPath, 'utf-8')\n if (existing.includes('NEXT_PUBLIC_SOFTWARE_CLIENT_KEY')) {\n console.log(pc.yellow(' Skipped'), '.env', pc.dim('(keys already present)'))\n } else {\n fs.appendFileSync(envPath, envContent)\n console.log(pc.green(' Updated'), '.env')\n }\n } else {\n fs.writeFileSync(envPath, envContent.trimStart())\n console.log(pc.green(' Created'), '.env')\n }\n}\n\nfunction relativePath(cwd: string, filePath: string): string {\n return path.relative(cwd, filePath)\n}\n\nconst WS_FILE = 'pnpm-workspace.yaml'\nconst WS_BACKUP = 'pnpm-workspace.yaml.bak'\n\nfunction hasPnpmWorkspace(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, WS_FILE))\n}\n\n/** Append packages: [] if pnpm-workspace.yaml exists without it — returns true if patched */\nfunction patchPnpmWorkspace(cwd: string): boolean {\n const wsPath = path.join(cwd, WS_FILE)\n if (!fs.existsSync(wsPath)) return false\n const content = fs.readFileSync(wsPath, 'utf-8')\n if (content.includes('packages:')) return false\n // backup original and append packages: []\n fs.copyFileSync(wsPath, path.join(cwd, WS_BACKUP))\n fs.writeFileSync(wsPath, content.trimEnd() + '\\npackages: []\\n')\n return true\n}\n\n/** Restore original pnpm-workspace.yaml from backup */\nfunction restorePnpmWorkspace(cwd: string): void {\n const backupPath = path.join(cwd, WS_BACKUP)\n if (!fs.existsSync(backupPath)) return\n fs.copyFileSync(backupPath, path.join(cwd, WS_FILE))\n fs.unlinkSync(backupPath)\n}\n","export function getClientTemplate(): string {\n return `import { createBrowserClient } from '@01.software/sdk'\n\nexport const client = createBrowserClient({\n clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,\n})\n`\n}\n\nexport function getQueryProviderTemplate(): string {\n return `'use client'\n\nimport { QueryClientProvider } from '@tanstack/react-query'\nimport { client } from './client'\n\nexport function QueryProvider({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={client.queryClient}>\n {children}\n </QueryClientProvider>\n )\n}\n`\n}\n\nexport function getServerTemplate(): string {\n return `import { createServerClient } from '@01.software/sdk'\n\nexport const serverClient = createServerClient({\n clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,\n secretKey: process.env.SOFTWARE_SECRET_KEY!,\n})\n`\n}\n\nexport function getPageTemplate(): string {\n return `'use client'\n\nimport { client } from '@/lib/software/client'\n\nexport default function Home() {\n const { data, isLoading } = client.query.useQuery({\n collection: 'products',\n options: { limit: 10 },\n })\n\n return (\n <main style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>\n <h1>My App</h1>\n <p>Built with <a href=\"https://01.software\">01.software</a> SDK</p>\n\n <h2>Products</h2>\n {isLoading ? (\n <p>Loading...</p>\n ) : (\n <ul>\n {data?.docs.map((product) => (\n <li key={product.id}>{product.title ?? product.id}</li>\n ))}\n {data?.docs.length === 0 && <li>No products found</li>}\n </ul>\n )}\n </main>\n )\n}\n`\n}\n\nexport function getEnvContent(clientKey: string): string {\n return `\\n# 01.software\nNEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}\nSOFTWARE_SECRET_KEY=\n`\n}"],"mappings":"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","names":["pc","fs","path","path","fs","pc"]}