@01.software/init 0.1.3 → 0.1.5

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 CHANGED
@@ -9,13 +9,37 @@ import path from "path";
9
9
  function detectProject(cwd) {
10
10
  const pkgPath = path.join(cwd, "package.json");
11
11
  const hasPackageJson = fs.existsSync(pkgPath);
12
- let isNextProject = false;
12
+ let env = "node";
13
13
  let hasSdk = false;
14
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;
15
+ let pkg;
16
+ try {
17
+ pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
18
+ } catch {
19
+ return { hasPackageJson: false, parseError: true, 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
+ }
19
43
  }
20
44
  let packageManager = null;
21
45
  if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) {
@@ -27,13 +51,38 @@ function detectProject(cwd) {
27
51
  } else if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
28
52
  packageManager = "npm";
29
53
  }
30
- const srcDir = fs.existsSync(path.join(cwd, "src", "app"));
31
- return { hasPackageJson, isNextProject, packageManager, hasSdk, srcDir };
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
+ }
32
80
  }
33
81
 
34
82
  // src/prompts.ts
35
83
  import prompts from "prompts";
36
- async function promptUser(hasSdk, detectedPm) {
84
+ var AMBIGUOUS_ENVS = ["node"];
85
+ async function promptUser(hasSdk, detectedEnv, detectedPm) {
37
86
  const onCancel = () => {
38
87
  throw new Error("cancelled");
39
88
  };
@@ -49,6 +98,58 @@ async function promptUser(hasSdk, detectedPm) {
49
98
  );
50
99
  if (!proceed) return null;
51
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
+ }
52
153
  let packageManager;
53
154
  if (!detectedPm) {
54
155
  const { pm } = await prompts(
@@ -67,33 +168,45 @@ async function promptUser(hasSdk, detectedPm) {
67
168
  );
68
169
  packageManager = pm;
69
170
  }
70
- const keys = await prompts(
71
- [
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(
72
193
  {
73
- type: "text",
74
- name: "clientKey",
75
- message: "Client Key (optional, saved to .env)",
76
- initial: ""
194
+ type: "confirm",
195
+ name: "setupMcp",
196
+ message: "Set up MCP integration? (.mcp.json)",
197
+ initial: true
77
198
  },
78
- {
79
- type: "text",
80
- name: "secretKey",
81
- message: "Secret Key (optional, saved to .env)",
82
- initial: ""
83
- }
84
- ],
85
- { onCancel }
86
- );
87
- const { setupMcp } = await prompts(
88
- {
89
- type: "confirm",
90
- name: "setupMcp",
91
- message: "Set up MCP integration? (.mcp.json)",
92
- initial: true
93
- },
94
- { onCancel }
95
- );
96
- return { ...keys, setupMcp, packageManager };
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
+ };
97
210
  }
98
211
 
99
212
  // src/init.ts
@@ -103,18 +216,42 @@ import { execSync } from "child_process";
103
216
  import pc from "picocolors";
104
217
 
105
218
  // src/templates.ts
106
- function getClientTemplate() {
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
+ }
107
245
  return `import { createBrowserClient } from '@01.software/sdk'
108
246
 
109
247
  export const client = createBrowserClient({
110
- clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
248
+ clientKey: import.meta.env.${clientKeyEnvVar},
111
249
  })
112
250
  `;
113
251
  }
114
- function getQueryProviderTemplate() {
115
- return `'use client'
116
-
117
- import { QueryClientProvider } from '@tanstack/react-query'
252
+ function getQueryProviderTemplate(env) {
253
+ const useClientDirective = env === "nextjs" ? "'use client'\n\n" : "";
254
+ return `${useClientDirective}import { QueryClientProvider } from '@tanstack/react-query'
118
255
  import { client } from './client'
119
256
 
120
257
  export function QueryProvider({ children }: { children: React.ReactNode }) {
@@ -126,21 +263,36 @@ export function QueryProvider({ children }: { children: React.ReactNode }) {
126
263
  }
127
264
  `;
128
265
  }
129
- function getServerTemplate() {
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
+ }
130
278
  return `import { createServerClient } from '@01.software/sdk'
131
279
 
132
280
  export const serverClient = createServerClient({
133
- clientKey: process.env.NEXT_PUBLIC_SOFTWARE_CLIENT_KEY!,
134
- secretKey: process.env.SOFTWARE_SECRET_KEY!,
281
+ clientKey: process.env.${clientKeyEnvVar}!,
282
+ secretKey: process.env.${secretKeyEnvVar}!,
135
283
  })
136
284
  `;
137
285
  }
138
- function getEnvContent(clientKey, secretKey) {
139
- return `
286
+ function getEnvContent(clientKey, secretKey, clientKeyEnvVar, secretKeyEnvVar) {
287
+ let content = `
140
288
  # 01.software
141
- NEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}
142
- SOFTWARE_SECRET_KEY=${secretKey}
289
+ ${clientKeyEnvVar}=${clientKey}
143
290
  `;
291
+ if (secretKeyEnvVar) {
292
+ content += `${secretKeyEnvVar}=${secretKey}
293
+ `;
294
+ }
295
+ return content;
144
296
  }
145
297
  function getMcpServerEntry(apiKey) {
146
298
  return {
@@ -158,12 +310,20 @@ function getMcpConfigTemplate(apiKey) {
158
310
  }
159
311
 
160
312
  // src/init.ts
313
+ var SECRET_KEY_ENV_VAR = "SOFTWARE_SECRET_KEY";
161
314
  async function init(cwd, info, answers) {
162
315
  const { packageManager, srcDir } = info;
316
+ const env = answers.env;
163
317
  const baseDir = srcDir ? path2.join(cwd, "src") : cwd;
164
- console.log(pc.dim(" Installing @01.software/sdk and @tanstack/react-query..."));
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 ")}...`));
165
325
  const wsPatched = packageManager === "pnpm" && patchPnpmWorkspace(cwd);
166
- const pkgs = "@01.software/sdk @tanstack/react-query";
326
+ const pkgs = deps.join(" ");
167
327
  const pnpmFlag = hasPnpmWorkspace(cwd) ? " -w" : "";
168
328
  const addCmd = packageManager === "pnpm" ? `pnpm add${pnpmFlag} ${pkgs}` : packageManager === "yarn" ? `yarn add ${pkgs}` : packageManager === "bun" ? `bun add ${pkgs}` : `npm install ${pkgs}`;
169
329
  try {
@@ -179,40 +339,53 @@ async function init(cwd, info, answers) {
179
339
  }
180
340
  const libDir = path2.join(baseDir, "lib", "software");
181
341
  fs2.mkdirSync(libDir, { recursive: true });
182
- const clientPath = path2.join(libDir, "client.ts");
183
- if (fs2.existsSync(clientPath)) {
184
- console.log(pc.yellow(" Skipped"), relativePath(cwd, clientPath), pc.dim("(already exists)"));
185
- } else {
186
- fs2.writeFileSync(clientPath, getClientTemplate());
187
- console.log(pc.green(" Created"), relativePath(cwd, clientPath));
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
+ }
188
350
  }
189
- const queryProviderPath = path2.join(libDir, "query-provider.tsx");
190
- if (fs2.existsSync(queryProviderPath)) {
191
- console.log(pc.yellow(" Skipped"), relativePath(cwd, queryProviderPath), pc.dim("(already exists)"));
192
- } else {
193
- fs2.writeFileSync(queryProviderPath, getQueryProviderTemplate());
194
- console.log(pc.green(" Created"), relativePath(cwd, queryProviderPath));
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
+ }
195
359
  }
196
- const serverPath = path2.join(libDir, "server.ts");
197
- if (fs2.existsSync(serverPath)) {
198
- console.log(pc.yellow(" Skipped"), relativePath(cwd, serverPath), pc.dim("(already exists)"));
199
- } else {
200
- fs2.writeFileSync(serverPath, getServerTemplate());
201
- console.log(pc.green(" Created"), relativePath(cwd, serverPath));
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
+ }
202
368
  }
203
- const envPath = path2.join(cwd, ".env");
204
- const envContent = getEnvContent(answers.clientKey || "", answers.secretKey || "");
205
- if (fs2.existsSync(envPath)) {
206
- const existing = fs2.readFileSync(envPath, "utf-8");
207
- if (existing.includes("NEXT_PUBLIC_SOFTWARE_CLIENT_KEY")) {
208
- console.log(pc.yellow(" Skipped"), ".env", pc.dim("(keys already present)"));
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
+ }
209
385
  } else {
210
- fs2.appendFileSync(envPath, envContent);
211
- console.log(pc.green(" Updated"), ".env");
386
+ fs2.writeFileSync(envPath, envContent.trimStart());
387
+ console.log(pc.green(" Created"), ".env");
212
388
  }
213
- } else {
214
- fs2.writeFileSync(envPath, envContent.trimStart());
215
- console.log(pc.green(" Created"), ".env");
216
389
  }
217
390
  if (answers.setupMcp) {
218
391
  const clientKey = answers.clientKey || "";
@@ -244,6 +417,9 @@ async function init(cwd, info, answers) {
244
417
  fs2.appendFileSync(gitignorePath, "\n# MCP config (contains API key)\n.mcp.json\n");
245
418
  console.log(pc.green(" Updated"), ".gitignore", pc.dim("(added .mcp.json)"));
246
419
  }
420
+ } else {
421
+ fs2.writeFileSync(gitignorePath, "# MCP config (contains API key)\n.mcp.json\n");
422
+ console.log(pc.green(" Created"), ".gitignore", pc.dim("(added .mcp.json)"));
247
423
  }
248
424
  }
249
425
  }
@@ -272,56 +448,116 @@ function restorePnpmWorkspace(cwd) {
272
448
  }
273
449
 
274
450
  // src/index.ts
451
+ var ENV_LABELS = {
452
+ nextjs: "Next.js",
453
+ "react-vite": "React + Vite",
454
+ "react-cra": "React + Webpack/CRA",
455
+ vanilla: "Vanilla JS",
456
+ node: "Node.js",
457
+ edge: "Edge runtime",
458
+ other: "Other framework"
459
+ };
460
+ var OTHER_FRAMEWORK_GUIDE = `
461
+ Astro, Remix, SvelteKit, and other meta-frameworks have their own
462
+ environment conventions. Manual setup:
463
+
464
+ 1. Install the SDK:
465
+ npm install @01.software/sdk
466
+
467
+ 2. Browser client (client islands / RSC):
468
+ import { createBrowserClient } from '@01.software/sdk'
469
+ export const client = createBrowserClient({ clientKey: 'YOUR_CLIENT_KEY' })
470
+
471
+ 3. Server client (SSR / loaders / endpoints):
472
+ import { createServerClient } from '@01.software/sdk'
473
+ export const serverClient = createServerClient({
474
+ clientKey: process.env.PUBLIC_SOFTWARE_CLIENT_KEY!, // prefix varies by framework
475
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
476
+ })
477
+
478
+ 4. Docs: https://01.software/docs/guide/quickstart
479
+ `;
275
480
  async function main() {
276
481
  const cwd = process.cwd();
277
482
  console.log();
278
483
  console.log(pc2.bold(" @01.software/init"));
279
- console.log(pc2.dim(" Initialize 01.software SDK in your Next.js project"));
484
+ console.log(pc2.dim(" Initialize 01.software SDK in your project"));
280
485
  console.log();
281
486
  const info = detectProject(cwd);
282
487
  if (!info.hasPackageJson) {
283
- console.log(pc2.red(" No package.json found in the current directory."));
284
- console.log(pc2.dim(" Run this command inside an existing Next.js project."));
488
+ if (info.parseError) {
489
+ console.log(pc2.red(" Could not parse package.json (invalid JSON)."));
490
+ console.log(pc2.dim(" Fix the syntax error and try again."));
491
+ } else {
492
+ console.log(pc2.red(" No package.json found in the current directory."));
493
+ console.log(pc2.dim(" Run this command inside an existing project."));
494
+ }
285
495
  console.log();
286
496
  process.exit(1);
287
497
  }
288
- if (!info.isNextProject) {
289
- console.log(pc2.red(" This does not appear to be a Next.js project."));
290
- console.log(pc2.dim(" Create one first: npx create-next-app my-app"));
498
+ const detectedParts = [ENV_LABELS[info.env]];
499
+ if (info.packageManager) detectedParts.push(info.packageManager);
500
+ if (info.srcDir) detectedParts.push("src/");
501
+ if (info.env !== "node") {
502
+ console.log(pc2.dim(` Detected: ${detectedParts.join(" / ")}`));
291
503
  console.log();
292
- process.exit(1);
293
504
  }
294
- if (info.packageManager) {
295
- console.log(pc2.dim(` Detected: Next.js / ${info.packageManager} / ${info.srcDir ? "src/app" : "app"}`));
296
- } else {
297
- console.log(pc2.dim(` Detected: Next.js / ${info.srcDir ? "src/app" : "app"}`));
298
- }
299
- console.log();
300
505
  try {
301
- const answers = await promptUser(info.hasSdk, info.packageManager);
506
+ const answers = await promptUser(info.hasSdk, info.env, info.packageManager);
302
507
  if (!answers) {
303
508
  console.log(pc2.yellow(" Cancelled."));
304
509
  process.exit(0);
305
510
  }
511
+ if (answers.env === "other") {
512
+ console.log(pc2.yellow(" Manual setup required for your framework:"));
513
+ console.log(OTHER_FRAMEWORK_GUIDE);
514
+ process.exit(0);
515
+ }
306
516
  const resolvedPm = info.packageManager ?? answers.packageManager ?? "npm";
307
517
  const resolvedInfo = { ...info, packageManager: resolvedPm };
308
518
  console.log();
309
519
  await init(cwd, resolvedInfo, answers);
520
+ const env = answers.env;
310
521
  const run = resolvedPm === "npm" ? "npm run" : resolvedPm;
311
522
  console.log();
312
523
  console.log(pc2.green(" Done!"));
313
524
  console.log();
314
525
  console.log(" Next steps:");
315
526
  console.log();
316
- console.log(pc2.dim(" Add the QueryProvider to your root layout:"));
317
- console.log();
318
- console.log(pc2.cyan(" import { QueryProvider } from '@/lib/software/query-provider'"));
319
- console.log();
320
- console.log(pc2.dim(" Wrap children with <QueryProvider>:"));
321
- console.log();
322
- console.log(pc2.cyan(" <QueryProvider>{children}</QueryProvider>"));
323
- console.log();
324
- if (!answers.clientKey || !answers.secretKey) {
527
+ if (env === "nextjs") {
528
+ console.log(pc2.dim(" Add QueryProvider to your root layout:"));
529
+ console.log();
530
+ console.log(pc2.cyan(" import { QueryProvider } from '@/lib/software/query-provider'"));
531
+ console.log(pc2.cyan(" <QueryProvider>{children}</QueryProvider>"));
532
+ console.log();
533
+ } else if (env === "react-vite" || env === "react-cra") {
534
+ console.log(pc2.dim(" Wrap your app entry with QueryProvider:"));
535
+ console.log();
536
+ console.log(pc2.cyan(" import { QueryProvider } from './lib/software/query-provider'"));
537
+ console.log(pc2.cyan(" <QueryProvider><App /></QueryProvider>"));
538
+ console.log();
539
+ } else if (env === "vanilla") {
540
+ console.log(pc2.dim(" Replace YOUR_CLIENT_KEY in lib/software/client.ts"));
541
+ console.log();
542
+ console.log(pc2.cyan(" import { client } from './lib/software/client'"));
543
+ console.log(pc2.cyan(" const posts = await client.from('posts').find()"));
544
+ console.log();
545
+ } else if (env === "node") {
546
+ console.log(pc2.dim(" Use the server client:"));
547
+ console.log();
548
+ console.log(pc2.cyan(" import { serverClient } from './lib/software/server'"));
549
+ console.log(pc2.cyan(" const posts = await serverClient.from('posts').find()"));
550
+ console.log();
551
+ } else if (env === "edge") {
552
+ console.log(pc2.dim(" Pass your env bindings to createEdgeClient():"));
553
+ console.log();
554
+ console.log(pc2.cyan(" import { createEdgeClient } from './lib/software/server'"));
555
+ console.log(pc2.cyan(" const serverClient = createEdgeClient(env.CLIENT_KEY, env.SECRET_KEY)"));
556
+ console.log();
557
+ }
558
+ const missingClientKey = env !== "vanilla" && !answers.clientKey;
559
+ const missingSecretKey = (env === "nextjs" || env === "node") && !answers.secretKey;
560
+ if (missingClientKey || missingSecretKey) {
325
561
  console.log(pc2.dim(" Update .env with your API keys"));
326
562
  console.log();
327
563
  }
@@ -329,8 +565,10 @@ async function main() {
329
565
  console.log(pc2.dim(" Update .mcp.json x-api-key with Base64(clientKey:secretKey)"));
330
566
  console.log();
331
567
  }
332
- console.log(pc2.cyan(` ${run} dev`));
333
- console.log();
568
+ if (env !== "vanilla") {
569
+ console.log(pc2.cyan(` ${run} dev`));
570
+ console.log();
571
+ }
334
572
  } catch (error) {
335
573
  if (error instanceof Error && error.message === "cancelled") {
336
574
  console.log(pc2.yellow(" Cancelled."));
package/dist/index.js.map CHANGED
@@ -1 +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 { 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 || !answers.secretKey) {\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 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 secretKey: string\n setupMcp: boolean\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 keys = await prompts(\n [\n {\n type: 'text',\n name: 'clientKey',\n message: 'Client Key (optional, saved to .env)',\n initial: '',\n },\n {\n type: 'text',\n name: 'secretKey',\n message: 'Secret Key (optional, saved to .env)',\n initial: '',\n },\n ],\n { onCancel },\n )\n\n const { setupMcp } = 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\n return { ...keys, setupMcp, 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 getEnvContent,\n getMcpConfigTemplate,\n getMcpServerEntry,\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 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() || 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. Append to .env (skip if keys already present)\n const envPath = path.join(cwd, '.env')\n const envContent = getEnvContent(answers.clientKey || '', answers.secretKey || '')\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 // 6. 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 // 7. 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\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 getEnvContent(clientKey: string, secretKey: string): string {\n return `\\n# 01.software\nNEXT_PUBLIC_SOFTWARE_CLIENT_KEY=${clientKey}\nSOFTWARE_SECRET_KEY=${secretKey}\n`\n}\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 JSON.stringify(\n { mcpServers: { '01software': getMcpServerEntry(apiKey) } },\n null,\n 2,\n ) + '\\n'\n}"],"mappings":"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","names":["pc","fs","path","path","fs","pc"]}
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 if (info.parseError) {\n console.log(pc.red(' Could not parse package.json (invalid JSON).'))\n console.log(pc.dim(' Fix the syntax error and try again.'))\n } else {\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 }\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 parseError?: 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, parseError: true, 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 } else {\n fs.writeFileSync(gitignorePath, '# MCP config (contains API key)\\n.mcp.json\\n')\n console.log(pc.green(' Created'), '.gitignore', pc.dim('(added .mcp.json)'))\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,7 +1,7 @@
1
1
  {
2
2
  "name": "@01.software/init",
3
- "version": "0.1.3",
4
- "description": "Initialize 01.software SDK in your Next.js project",
3
+ "version": "0.1.5",
4
+ "description": "Initialize 01.software SDK in your project (Next.js, React, Vanilla JS, Node.js, Edge)",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "01-init": "./dist/index.js"
@@ -21,6 +21,7 @@
21
21
  "tsup": "^8.5.0",
22
22
  "typescript": "^5.9.3"
23
23
  },
24
+ "author": "<office@01.works>",
24
25
  "publishConfig": {
25
26
  "access": "public"
26
27
  },
@@ -30,6 +31,7 @@
30
31
  "check-types": "tsc --noEmit",
31
32
  "version:dev": "node ../../scripts/update-version.js",
32
33
  "publish:dev": "pnpm run version:dev && pnpm publish --no-git-checks --access public --tag dev",
34
+ "publish:local": "pnpm run version:dev && pnpm publish --no-git-checks --access public --tag local",
33
35
  "version:patch": "pnpm version patch --no-git-tag-version",
34
36
  "version:minor": "pnpm version minor --no-git-tag-version",
35
37
  "version:major": "pnpm version major --no-git-tag-version",