@01.software/init 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-docs.d.ts +13 -0
- package/dist/ai-docs.js +0 -0
- package/dist/browser-auth-CJDrpp5T.d.ts +11 -0
- package/dist/{chunk-UA7WNT2F.js → chunk-4LHYICUL.js} +1 -1
- package/dist/chunk-4LHYICUL.js.map +1 -0
- package/dist/{chunk-R4GGO33X.js → chunk-NJ4X7VNK.js} +1 -1
- package/dist/{chunk-R4GGO33X.js.map → chunk-NJ4X7VNK.js.map} +1 -1
- package/dist/chunk-Q6MSORYN.js +0 -0
- package/dist/chunk-STM4DKVZ.js +183 -0
- package/dist/chunk-STM4DKVZ.js.map +1 -0
- package/dist/{chunk-ENQSB4OF.js → chunk-WDWJ73KP.js} +40 -214
- package/dist/chunk-WDWJ73KP.js.map +1 -0
- package/dist/create-app-templates/ecommerce/AGENTS.md +88 -0
- package/dist/create-app-templates/ecommerce/CHANGELOG.md +30 -0
- package/dist/create-app-templates/ecommerce/CLAUDE.md +1 -0
- package/dist/create-app-templates/ecommerce/README.md +139 -0
- package/dist/create-app-templates/ecommerce/app/api/auth/login/route.ts +30 -0
- package/dist/create-app-templates/ecommerce/app/api/auth/logout/route.ts +18 -0
- package/dist/create-app-templates/ecommerce/app/api/auth/register/route.ts +41 -0
- package/dist/create-app-templates/ecommerce/app/api/cart/clear/route.ts +12 -0
- package/dist/create-app-templates/ecommerce/app/api/cart/items/route.ts +45 -0
- package/dist/create-app-templates/ecommerce/app/api/cart/route.ts +14 -0
- package/dist/create-app-templates/ecommerce/app/api/checkout/payment-return/route.ts +86 -0
- package/dist/create-app-templates/ecommerce/app/api/checkout/reconcile/route.ts +50 -0
- package/dist/create-app-templates/ecommerce/app/api/checkout/route.ts +41 -0
- package/dist/create-app-templates/ecommerce/app/cart/page.tsx +10 -0
- package/dist/create-app-templates/ecommerce/app/checkout/page.tsx +10 -0
- package/dist/create-app-templates/ecommerce/app/checkout/success/page.tsx +34 -0
- package/dist/create-app-templates/ecommerce/app/favicon.ico +0 -0
- package/dist/create-app-templates/ecommerce/app/globals.css +67 -0
- package/dist/create-app-templates/ecommerce/app/layout.tsx +23 -0
- package/dist/create-app-templates/ecommerce/app/login/page.tsx +11 -0
- package/dist/create-app-templates/ecommerce/app/page.tsx +5 -0
- package/dist/create-app-templates/ecommerce/app/products/[slug]/page.tsx +46 -0
- package/dist/create-app-templates/ecommerce/app/products/page.tsx +45 -0
- package/dist/create-app-templates/ecommerce/app/register/page.tsx +11 -0
- package/dist/create-app-templates/ecommerce/app/webhook/payment/route.ts +20 -0
- package/dist/create-app-templates/ecommerce/app-config.ts +54 -0
- package/dist/create-app-templates/ecommerce/components/auth/auth-form.tsx +109 -0
- package/dist/create-app-templates/ecommerce/components/cart/cart-content.tsx +119 -0
- package/dist/create-app-templates/ecommerce/components/checkout/checkout-form.tsx +267 -0
- package/dist/create-app-templates/ecommerce/components/checkout/checkout-reconcile.tsx +78 -0
- package/dist/create-app-templates/ecommerce/components/layout/account-nav.tsx +48 -0
- package/dist/create-app-templates/ecommerce/components/layout/account-slot.tsx +12 -0
- package/dist/create-app-templates/ecommerce/components/layout/cart-link.tsx +13 -0
- package/dist/create-app-templates/ecommerce/components/layout/page-shell.tsx +11 -0
- package/dist/create-app-templates/ecommerce/components/layout/site-header.tsx +22 -0
- package/dist/create-app-templates/ecommerce/components/product/add-to-cart.tsx +116 -0
- package/dist/create-app-templates/ecommerce/components/product/product-card.tsx +50 -0
- package/dist/create-app-templates/ecommerce/components/product/product-gallery.tsx +39 -0
- package/dist/create-app-templates/ecommerce/data/mock-catalog.json +173 -0
- package/dist/create-app-templates/ecommerce/eslint.config.mjs +18 -0
- package/dist/create-app-templates/ecommerce/lib/cart/cookie.ts +40 -0
- package/dist/create-app-templates/ecommerce/lib/cart/normalize.ts +32 -0
- package/dist/create-app-templates/ecommerce/lib/cart/parse-cart-request.ts +56 -0
- package/dist/create-app-templates/ecommerce/lib/cart/route-helpers.ts +17 -0
- package/dist/create-app-templates/ecommerce/lib/cart/select-provider.ts +44 -0
- package/dist/create-app-templates/ecommerce/lib/cart/server-cart.ts +96 -0
- package/dist/create-app-templates/ecommerce/lib/cart/sync-on-login.server.ts +34 -0
- package/dist/create-app-templates/ecommerce/lib/cart/use-cart.tsx +151 -0
- package/dist/create-app-templates/ecommerce/lib/checkout/checkout-errors.ts +22 -0
- package/dist/create-app-templates/ecommerce/lib/checkout/checkout-provider.ts +28 -0
- package/dist/create-app-templates/ecommerce/lib/checkout/parse-checkout-payload.ts +76 -0
- package/dist/create-app-templates/ecommerce/lib/checkout/start-checkout.ts +63 -0
- package/dist/create-app-templates/ecommerce/lib/checkout/types.ts +3 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/adapters/mock.ts +336 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/adapters/software-mappers.ts +312 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/adapters/software.ts +913 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/product-summary.ts +37 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/provider.server.ts +60 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/provider.ts +96 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/stock.ts +37 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/types.ts +206 -0
- package/dist/create-app-templates/ecommerce/lib/commerce/variant-selection.ts +23 -0
- package/dist/create-app-templates/ecommerce/lib/customer/auth-actions.ts +131 -0
- package/dist/create-app-templates/ecommerce/lib/customer/cart-sync.ts +44 -0
- package/dist/create-app-templates/ecommerce/lib/customer/client.server.ts +109 -0
- package/dist/create-app-templates/ecommerce/lib/customer/current-customer.ts +15 -0
- package/dist/create-app-templates/ecommerce/lib/customer/route-guard.ts +58 -0
- package/dist/create-app-templates/ecommerce/lib/customer/route-helpers.ts +75 -0
- package/dist/create-app-templates/ecommerce/lib/customer/session.ts +108 -0
- package/dist/create-app-templates/ecommerce/lib/format.ts +7 -0
- package/dist/create-app-templates/ecommerce/lib/payment/adapters/mock.ts +84 -0
- package/dist/create-app-templates/ecommerce/lib/payment/adapters/portone.ts +254 -0
- package/dist/create-app-templates/ecommerce/lib/payment/adapters/tosspayments.ts +287 -0
- package/dist/create-app-templates/ecommerce/lib/payment/amount-gate.ts +86 -0
- package/dist/create-app-templates/ecommerce/lib/payment/provider.server.ts +51 -0
- package/dist/create-app-templates/ecommerce/lib/payment/provider.ts +18 -0
- package/dist/create-app-templates/ecommerce/lib/payment/sync-order-payment.ts +96 -0
- package/dist/create-app-templates/ecommerce/lib/payment/types.ts +71 -0
- package/dist/create-app-templates/ecommerce/lib/server-only-guard.ts +20 -0
- package/dist/create-app-templates/ecommerce/next-env.d.ts +6 -0
- package/dist/create-app-templates/ecommerce/next.config.ts +16 -0
- package/dist/create-app-templates/ecommerce/package.json +33 -0
- package/dist/create-app-templates/ecommerce/postcss.config.mjs +7 -0
- package/dist/create-app-templates/ecommerce/tests/customer-auth.test.ts +263 -0
- package/dist/create-app-templates/ecommerce/tests/customer-cart.test.ts +392 -0
- package/dist/create-app-templates/ecommerce/tests/domain.test.ts +1537 -0
- package/dist/create-app-templates/ecommerce/tsconfig.json +35 -0
- package/dist/create-app-templates/registry.json +66 -0
- package/dist/create-app.d.ts +40 -0
- package/dist/create-app.js +652 -0
- package/dist/create-app.js.map +1 -0
- package/dist/detect-Bjxp9wcS.d.ts +13 -0
- package/dist/file-ops.d.ts +21 -0
- package/dist/file-ops.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +40 -0
- package/dist/init.js +4 -3
- package/dist/templates.d.ts +27 -0
- package/dist/templates.js +1 -1
- package/package.json +31 -15
- package/dist/chunk-ENQSB4OF.js.map +0 -1
- package/dist/chunk-UA7WNT2F.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/create-app.ts","../src/template-registry.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport pc from 'picocolors'\nimport prompts from 'prompts'\nimport { startBrowserAuth } from './browser-auth'\nimport { writeEnvFile } from './file-ops'\nimport {\n findFeature,\n findPaymentProvider,\n findTemplate,\n readTemplateRegistry,\n} from './template-registry'\nimport type {\n RegistryPaymentProvider,\n RegistryTemplate,\n TemplateRegistry,\n} from './template-registry'\nimport type { PackageManager } from './detect'\n\ntype AuthMode = 'browser' | 'manual' | 'skip'\n\nexport interface CreateAppOptions {\n projectDir?: string\n /** Registry template name (e.g. `ecommerce`). */\n template?: string\n /** Payment provider id (e.g. `portone`). */\n paymentProvider?: string\n /**\n * Include the customer-accounts feature (login/register/logout + session).\n * Defaults to off — a guest-checkout-only storefront ships no auth code.\n */\n customerAccounts?: boolean\n packageManager?: PackageManager\n auth?: AuthMode\n publishableKey?: string\n secretKey?: string\n install?: boolean\n templateRoot?: string\n}\n\nexport interface CreateAppDeps {\n startBrowserAuth?: typeof startBrowserAuth\n runInstall?: (cmd: string, cwd: string) => void\n}\n\nexport interface CreateAppResult {\n projectDir: string\n template: string\n paymentProvider: string\n packageManager: PackageManager\n installed: boolean\n tenantName?: string\n}\n\ninterface ResolvedOptions {\n projectDir: string\n templateRoot: string\n registry: TemplateRegistry\n template: RegistryTemplate\n provider: RegistryPaymentProvider\n customerAccounts: boolean\n packageManager: PackageManager\n auth: AuthMode\n publishableKey: string\n secretKey: string\n install: boolean\n}\n\nconst PACKAGE_MANAGERS: PackageManager[] = ['pnpm', 'npm', 'yarn', 'bun']\nconst PACKAGE_MANAGER_VALUES = new Set<PackageManager>(PACKAGE_MANAGERS)\nconst AUTH_VALUES = new Set<AuthMode>(['browser', 'manual', 'skip'])\n\nexport async function createApp(\n rawOptions: CreateAppOptions = {},\n deps: CreateAppDeps = {},\n): Promise<CreateAppResult> {\n const options = await resolveOptions(rawOptions)\n const projectDir = path.resolve(options.projectDir)\n const sourceDir = path.join(options.templateRoot, options.template.dir)\n\n if (!fs.existsSync(sourceDir)) {\n throw new Error(`Template not found: ${options.template.name}`)\n }\n assertTargetAvailable(projectDir)\n\n fs.mkdirSync(projectDir, { recursive: true })\n copyTemplate(sourceDir, projectDir)\n rewritePackageName(projectDir)\n applyPaymentProvider(projectDir, options)\n applyCustomerAccounts(projectDir, options)\n writeAppConfig(projectDir, options)\n writeEnvExample(projectDir, options)\n\n let tenantName: string | undefined\n if (options.auth === 'browser') {\n const creds = await (deps.startBrowserAuth ?? startBrowserAuth)()\n writeSdkEnv(projectDir, creds.publishableKey, creds.secretKey)\n tenantName = creds.tenantName\n } else if (options.auth === 'manual') {\n writeSdkEnv(projectDir, options.publishableKey, options.secretKey)\n }\n\n let installed = false\n if (options.install) {\n const cmd = installCommand(options.packageManager)\n const runInstall =\n deps.runInstall ??\n ((installCmd, cwd) => execSync(installCmd, { cwd, stdio: 'inherit' }))\n runInstall(cmd, projectDir)\n installed = true\n }\n\n return {\n projectDir,\n template: options.template.name,\n paymentProvider: options.provider.id,\n packageManager: options.packageManager,\n installed,\n tenantName,\n }\n}\n\nasync function resolveOptions(raw: CreateAppOptions): Promise<ResolvedOptions> {\n const onCancel = () => {\n throw new Error('cancelled')\n }\n\n const templateRoot = raw.templateRoot ?? defaultTemplateRoot()\n const registry = readTemplateRegistry(templateRoot)\n\n let projectDir = raw.projectDir\n if (!projectDir) {\n const { name } = await prompts(\n {\n type: 'text',\n name: 'name',\n message: 'Project directory',\n initial: 'my-01-store',\n },\n { onCancel },\n )\n projectDir = name\n }\n\n const template = await resolveTemplate(registry, raw.template, onCancel)\n const provider = await resolveProvider(\n template,\n raw.paymentProvider,\n onCancel,\n )\n const customerAccounts = await resolveCustomerAccounts(\n template,\n raw.customerAccounts,\n onCancel,\n )\n\n let packageManager = raw.packageManager\n if (!packageManager) {\n const { pm } = await prompts(\n {\n type: 'select',\n name: 'pm',\n message: 'Package manager',\n choices: PACKAGE_MANAGERS.map((value) => ({ title: value, value })),\n initial: 0,\n },\n { onCancel },\n )\n packageManager = pm as PackageManager\n }\n\n let auth = raw.auth\n if (!auth) {\n const { mode } = await prompts(\n {\n type: 'select',\n name: 'mode',\n message: 'Connect to a 01.software tenant now?',\n choices: [\n { title: 'Browser login (recommended)', value: 'browser' },\n { title: 'Enter keys manually', value: 'manual' },\n { title: 'Skip and use demo data', value: 'skip' },\n ],\n initial: 0,\n },\n { onCancel },\n )\n auth = mode as AuthMode\n }\n\n let publishableKey = raw.publishableKey ?? ''\n let secretKey = raw.secretKey ?? ''\n if (auth === 'manual' && (!publishableKey || !secretKey)) {\n const keys = await prompts(\n [\n {\n type: 'text',\n name: 'publishableKey',\n message: 'NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY',\n initial: publishableKey,\n },\n {\n type: 'password',\n name: 'secretKey',\n message: 'SOFTWARE_SECRET_KEY',\n initial: secretKey,\n },\n ],\n { onCancel },\n )\n publishableKey = keys.publishableKey ?? ''\n secretKey = keys.secretKey ?? ''\n }\n\n if (!projectDir?.trim()) {\n throw new Error('Project directory is required.')\n }\n projectDir = projectDir.trim()\n if (!packageManager) {\n throw new Error('Package manager is required.')\n }\n if (!auth) {\n throw new Error('Auth mode is required.')\n }\n if (auth === 'manual' && (!publishableKey.trim() || !secretKey.trim())) {\n throw new Error(\n 'Manual auth requires NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY and SOFTWARE_SECRET_KEY. Use --auth skip for demo data.',\n )\n }\n\n return {\n projectDir,\n templateRoot,\n registry,\n template,\n provider,\n customerAccounts,\n packageManager,\n auth,\n publishableKey,\n secretKey,\n install: raw.install ?? true,\n }\n}\n\nasync function resolveTemplate(\n registry: TemplateRegistry,\n requested: string | undefined,\n onCancel: () => never,\n): Promise<RegistryTemplate> {\n if (requested) {\n const template = findTemplate(registry, requested)\n if (!template) {\n throw new Error(`Invalid template: ${requested}`)\n }\n return template\n }\n\n if (registry.templates.length === 1) {\n return registry.templates[0]\n }\n\n const { selected } = await prompts(\n {\n type: 'select',\n name: 'selected',\n message: 'Choose a starter',\n choices: registry.templates.map((template) => ({\n title: template.title,\n value: template.name,\n })),\n initial: 0,\n },\n { onCancel },\n )\n const template = findTemplate(registry, selected as string)\n if (!template) {\n throw new Error('Template is required.')\n }\n return template\n}\n\nasync function resolveProvider(\n template: RegistryTemplate,\n requested: string | undefined,\n onCancel: () => never,\n): Promise<RegistryPaymentProvider> {\n if (requested) {\n const provider = findPaymentProvider(template, requested)\n if (!provider) {\n throw new Error(`Invalid payment provider: ${requested}`)\n }\n return provider\n }\n\n if (template.paymentProviders.length === 1) {\n return template.paymentProviders[0]\n }\n\n const { selected } = await prompts(\n {\n type: 'select',\n name: 'selected',\n message: 'Choose a payment provider',\n choices: template.paymentProviders.map((provider) => ({\n title: provider.label,\n value: provider.id,\n })),\n initial: defaultProviderIndex(template),\n },\n { onCancel },\n )\n const provider = findPaymentProvider(template, selected as string)\n if (!provider) {\n throw new Error('Payment provider is required.')\n }\n return provider\n}\n\n/**\n * Decide whether to include the optional customer-accounts feature. Defaults to\n * off (guest-checkout-only). An explicit `--customer-accounts` /\n * `--no-customer-accounts` flag bypasses the prompt; templates without the\n * feature always resolve to false.\n */\nasync function resolveCustomerAccounts(\n template: RegistryTemplate,\n requested: boolean | undefined,\n onCancel: () => never,\n): Promise<boolean> {\n const feature = findFeature(template, 'customer-accounts')\n if (!feature) return false\n if (requested !== undefined) return requested\n // The feature has a sensible default (off), so a non-interactive run (CI,\n // scripted, no TTY) takes the default instead of stalling on a prompt; pass\n // `--customer-accounts` / `--no-customer-accounts` to choose explicitly.\n if (!process.stdin.isTTY) return feature.defaultEnabled ?? false\n\n const { include } = await prompts(\n {\n type: 'confirm',\n name: 'include',\n message: `Include ${feature.label}? Requires a starter+ plan; guest checkout works without it.`,\n initial: feature.defaultEnabled ?? false,\n },\n { onCancel },\n )\n return Boolean(include)\n}\n\nfunction defaultProviderIndex(template: RegistryTemplate): number {\n const index = template.paymentProviders.findIndex(\n (provider) => provider.id === template.defaultPaymentProvider,\n )\n return index === -1 ? 0 : index\n}\n\nfunction defaultTemplateRoot(): string {\n return path.join(path.dirname(fileURLToPath(import.meta.url)), 'create-app-templates')\n}\n\nfunction assertTargetAvailable(projectDir: string): void {\n if (!fs.existsSync(projectDir)) return\n const entries = fs.readdirSync(projectDir).filter((entry) => entry !== '.DS_Store')\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${projectDir}`)\n }\n}\n\nfunction copyTemplate(sourceDir: string, targetDir: string): void {\n const ignored = new Set([\n 'node_modules',\n '.next',\n '.turbo',\n 'dist',\n '.DS_Store',\n '.mock-orders.json',\n '.mock-payments.json',\n ])\n\n for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {\n if (ignored.has(entry.name)) continue\n const source = path.join(sourceDir, entry.name)\n const target = path.join(targetDir, entry.name)\n if (entry.isDirectory()) {\n fs.mkdirSync(target, { recursive: true })\n copyTemplate(source, target)\n } else if (entry.isFile()) {\n fs.mkdirSync(path.dirname(target), { recursive: true })\n fs.copyFileSync(source, target)\n }\n }\n}\n\nfunction rewritePackageName(projectDir: string): void {\n const packagePath = path.join(projectDir, 'package.json')\n const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8')) as {\n name?: string\n version?: string\n }\n packageJson.name = packageNameFromDir(projectDir)\n packageJson.version = '0.1.0'\n fs.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\\n`)\n}\n\n/**\n * Prune the scaffolded app down to the chosen payment provider: delete the\n * other providers' adapter files, strip their `scaffold:provider:<id>` marker\n * blocks from source files, remove their dependencies, and pin the SDK to an\n * exact version. The in-repo template intentionally ships every adapter; a\n * generated app ships exactly one.\n */\nfunction applyPaymentProvider(projectDir: string, options: ResolvedOptions): void {\n const others = options.template.paymentProviders.filter(\n (provider) => provider.id !== options.provider.id,\n )\n\n for (const provider of others) {\n fs.rmSync(path.join(projectDir, provider.adapterFile), { force: true })\n }\n\n stripProviderMarkers(\n projectDir,\n others.map((provider) => provider.id),\n )\n\n pruneDependencies(\n projectDir,\n others.flatMap((provider) => provider.dependencies),\n options.registry.sdk.package,\n )\n}\n\nfunction stripProviderMarkers(projectDir: string, otherProviderIds: string[]): void {\n for (const file of walkSourceFiles(projectDir)) {\n const content = fs.readFileSync(file, 'utf-8')\n if (!content.includes('scaffold:provider:')) continue\n\n let next = content\n // Remove the unused providers' blocks (markers + the code between them)...\n for (const id of otherProviderIds) {\n next = stripMarkerBlocks(next, id)\n }\n // ...then drop the kept provider's leftover marker comment lines so the\n // generated app carries no scaffolder bookkeeping.\n next = removeMarkerLines(next)\n if (next !== content) fs.writeFileSync(file, next)\n }\n}\n\n/**\n * Apply the customer-accounts feature choice (mirrors `applyPaymentProvider`).\n * When excluded, delete the feature's files/dirs and strip its\n * `scaffold:customer:start|end` blocks from shared source files and docs; when\n * included, drop the leftover marker comment lines so the generated app carries\n * no scaffolder bookkeeping. No-op for templates without the feature.\n */\nfunction applyCustomerAccounts(\n projectDir: string,\n options: ResolvedOptions,\n): void {\n const feature = findFeature(options.template, 'customer-accounts')\n if (!feature) return\n\n if (!options.customerAccounts) {\n for (const rel of feature.paths) {\n fs.rmSync(path.join(projectDir, rel), { recursive: true, force: true })\n }\n }\n\n const tagPrefix = `scaffold:${feature.marker}:`\n const linePattern = new RegExp(`scaffold:${feature.marker}:(?:start|end)\\\\b`)\n const transform = options.customerAccounts\n ? (content: string) => removeMarkerLinesFor(content, linePattern)\n : (content: string) => stripMarkerBlocksByTag(content, feature.marker)\n\n const files = walkSourceFiles(projectDir)\n const agentsMd = path.join(projectDir, 'AGENTS.md')\n if (fs.existsSync(agentsMd)) files.push(agentsMd)\n\n for (const file of files) {\n const content = fs.readFileSync(file, 'utf-8')\n if (!content.includes(tagPrefix)) continue\n const next = transform(content)\n if (next !== content) fs.writeFileSync(file, next)\n }\n}\n\nconst MARKER_LINE = /scaffold:provider:[\\w-]+:(?:start|end)\\b/\n\nfunction removeMarkerLinesFor(content: string, pattern: RegExp): string {\n return content\n .split('\\n')\n .filter((line) => !pattern.test(line))\n .join('\\n')\n}\n\nexport function removeMarkerLines(content: string): string {\n return removeMarkerLinesFor(content, MARKER_LINE)\n}\n\nexport function stripMarkerBlocks(content: string, providerId: string): string {\n return stripMarkerBlocksByTag(content, `provider:${providerId}`)\n}\n\n/**\n * Strip a `scaffold:<tag>:start|end` block (markers + the lines between them).\n * `tag` is the full marker tag, e.g. `provider:portone` or `customer`.\n */\nfunction stripMarkerBlocksByTag(content: string, tag: string): string {\n const startMarker = `scaffold:${tag}:start`\n const endMarker = `scaffold:${tag}:end`\n const lines = content.split('\\n')\n const result: string[] = []\n let skipping = false\n\n for (const line of lines) {\n if (!skipping && line.includes(startMarker)) {\n skipping = true\n continue\n }\n if (skipping) {\n if (line.includes(endMarker)) skipping = false\n continue\n }\n result.push(line)\n }\n\n if (skipping) {\n // Fail loud rather than silently truncating the file from the start marker\n // to EOF if a template author forgets (or mistypes) the end marker.\n throw new Error(\n `Unterminated scaffold marker: missing \"${endMarker}\" to close \"${startMarker}\"`,\n )\n }\n\n return result.join('\\n')\n}\n\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'])\nconst WALK_IGNORED = new Set(['node_modules', '.next', '.turbo', 'dist', '.git'])\n\nfunction walkSourceFiles(dir: string): string[] {\n const files: string[] = []\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (WALK_IGNORED.has(entry.name)) continue\n const full = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n files.push(...walkSourceFiles(full))\n } else if (entry.isFile() && SOURCE_EXTENSIONS.has(path.extname(entry.name))) {\n files.push(full)\n }\n }\n return files\n}\n\nfunction pruneDependencies(\n projectDir: string,\n depsToRemove: string[],\n sdkPackage: string,\n): void {\n const packagePath = path.join(projectDir, 'package.json')\n const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8')) as {\n dependencies?: Record<string, string>\n }\n const dependencies = packageJson.dependencies\n if (dependencies) {\n for (const dep of depsToRemove) delete dependencies[dep]\n const sdkRange = dependencies[sdkPackage]\n if (sdkRange) dependencies[sdkPackage] = sdkRange.replace(/^[\\^~]/, '')\n }\n fs.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}\\n`)\n}\n\nfunction writeAppConfig(projectDir: string, options: ResolvedOptions): void {\n const brand = humanize(path.basename(projectDir))\n const slug = packageNameFromDir(projectDir)\n const cartKey = `${slug}-cart`\n const customerKey = `${slug}-customer`\n const providerId = options.provider.id\n const label = options.provider.label\n\n const customerKeyField = options.customerAccounts\n ? `\n /** Cookie name holding the HttpOnly customer session JWT. */\n customerKey: string;`\n : ''\n const customerKeyValue = options.customerAccounts\n ? `\n customerKey: ${JSON.stringify(customerKey)},`\n : ''\n\n const content = `/**\n * App configuration generated by create-01-software-app.\n *\n * Generic source files read their per-app values from here so they stay\n * consistent across the app. Edit freely — this is your project's config.\n */\nexport type PaymentProviderId = ${JSON.stringify(providerId)};\n\nexport interface AppConfig {\n /** Brand name shown in the storefront chrome. */\n brand: string;\n /** Document title for the app. */\n title: string;\n /** Cookie name holding the HttpOnly guest-cart ownership token. */\n cartKey: string;${customerKeyField}\n /** Payment provider this app was scaffolded for. */\n paymentProvider: PaymentProviderId;\n}\n\nexport const appConfig: AppConfig = {\n brand: ${JSON.stringify(brand)},\n title: ${JSON.stringify(brand)},\n cartKey: ${JSON.stringify(cartKey)},${customerKeyValue}\n paymentProvider: ${JSON.stringify(providerId)},\n};\n\nexport const PAYMENT_PROVIDER_LABELS: Record<PaymentProviderId, string> = {\n ${JSON.stringify(providerId)}: ${JSON.stringify(label)},\n};\n\nexport function paymentProviderLabel(\n provider: PaymentProviderId = appConfig.paymentProvider,\n): string {\n return PAYMENT_PROVIDER_LABELS[provider];\n}\n`\n fs.writeFileSync(path.join(projectDir, 'app-config.ts'), content)\n}\n\nfunction humanize(name: string): string {\n const words = name\n .replace(/[._-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .split(' ')\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n return words.join(' ') || 'My 01 Store'\n}\n\nfunction packageNameFromDir(projectDir: string): string {\n const name = path.basename(projectDir)\n const normalized = name\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return normalized || 'my-01-store'\n}\n\nfunction writeSdkEnv(projectDir: string, publishableKey: string, secretKey: string): void {\n writeEnvFile(\n path.join(projectDir, '.env.local'),\n [\n '# 01.software',\n `NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY=${publishableKey}`,\n `SOFTWARE_SECRET_KEY=${secretKey}`,\n '',\n ].join('\\n'),\n )\n}\n\nfunction writeEnvExample(projectDir: string, options: ResolvedOptions): void {\n const lines = ['# 01.software']\n for (const entry of options.registry.sdk.env) {\n lines.push(`${entry.key}=${entry.value ?? ''}`)\n }\n lines.push('', `# ${options.provider.label}`)\n for (const entry of options.provider.env) {\n lines.push(`${entry.key}=${entry.value ?? ''}`)\n }\n lines.push('')\n\n fs.writeFileSync(path.join(projectDir, '.env.local.example'), `${lines.join('\\n')}\\n`)\n}\n\nfunction installCommand(packageManager: PackageManager): string {\n if (packageManager === 'yarn') return 'yarn install'\n if (packageManager === 'bun') return 'bun install'\n return `${packageManager} install`\n}\n\nfunction parseArgs(argv: string[]): CreateAppOptions & { help?: boolean } {\n const options: CreateAppOptions & { help?: boolean } = {}\n const rest: string[] = []\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index]\n if (arg === '--help' || arg === '-h') {\n options.help = true\n } else if (arg === '--template') {\n options.template = argv[++index]\n } else if (arg === '--adapter' || arg === '--provider') {\n options.paymentProvider = argv[++index]\n } else if (arg === '--customer-accounts') {\n options.customerAccounts = true\n } else if (arg === '--no-customer-accounts') {\n options.customerAccounts = false\n } else if (arg === '--package-manager') {\n const value = argv[++index]\n if (!isPackageManager(value)) {\n throw new Error(`Invalid package manager: ${value}`)\n }\n options.packageManager = value\n } else if (arg === '--auth') {\n const value = argv[++index]\n if (!isAuthMode(value)) {\n throw new Error(`Invalid auth mode: ${value}`)\n }\n options.auth = value\n } else if (arg === '--publishable-key') {\n options.publishableKey = argv[++index]\n } else if (arg === '--secret-key') {\n options.secretKey = argv[++index]\n } else if (arg === '--no-install') {\n options.install = false\n } else if (arg.startsWith('--')) {\n throw new Error(`Unknown option: ${arg}`)\n } else {\n rest.push(arg)\n }\n }\n\n if (rest[0]) options.projectDir = rest[0]\n return options\n}\n\nfunction isPackageManager(value: string | undefined): value is PackageManager {\n return PACKAGE_MANAGER_VALUES.has(value as PackageManager)\n}\n\nfunction isAuthMode(value: string | undefined): value is AuthMode {\n return AUTH_VALUES.has(value as AuthMode)\n}\n\nfunction printHelp(): void {\n console.log(`\ncreate-01-software-app\n\nUsage:\n create-01-software-app [project-dir] [options]\n\nOptions:\n --template <name> template name from templates/registry.json\n --adapter <id> payment provider id (alias: --provider)\n --customer-accounts include customer accounts (login/register; starter+)\n --no-customer-accounts guest checkout only (default)\n --package-manager pnpm|npm|yarn|bun\n --auth browser|manual|skip\n --publishable-key <key>\n --secret-key <key>\n --no-install\n`)\n}\n\nexport async function runCreateAppCli(\n argv: string[] = process.argv.slice(2),\n): Promise<void> {\n const options = parseArgs(argv)\n if (options.help) {\n printHelp()\n return\n }\n\n console.log()\n console.log(pc.bold(' create-01-software-app'))\n console.log(pc.dim(' Create a greenfield 01.software commerce app'))\n console.log()\n\n const result = await createApp(options)\n\n console.log()\n console.log(pc.green(' Created'), path.relative(process.cwd(), result.projectDir) || '.')\n if (result.tenantName) console.log(pc.dim(` Tenant: ${result.tenantName}`))\n console.log()\n console.log(' Next steps:')\n console.log(pc.cyan(` cd ${path.relative(process.cwd(), result.projectDir) || '.'}`))\n if (!result.installed) console.log(pc.cyan(` ${installCommand(result.packageManager)}`))\n console.log(pc.cyan(` ${result.packageManager === 'npm' ? 'npm run' : result.packageManager} dev`))\n console.log()\n}\n\nconst isDirectRun = process.argv[1] ? isEntrypoint(process.argv[1]) : false\n\nfunction isEntrypoint(argvPath: string): boolean {\n try {\n return fs.realpathSync(argvPath) === fileURLToPath(import.meta.url)\n } catch {\n return path.resolve(argvPath) === fileURLToPath(import.meta.url)\n }\n}\n\nif (isDirectRun) {\n runCreateAppCli().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 instanceof Error ? error.message : String(error))\n process.exit(1)\n })\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface RegistryEnvVar {\n key: string\n value?: string\n}\n\nexport interface RegistryPaymentProvider {\n id: string\n label: string\n adapterFile: string\n dependencies: string[]\n env: RegistryEnvVar[]\n}\n\n/**\n * An optional, prunable template feature (e.g. customer accounts). When the\n * operator opts out at scaffold time, `paths` are deleted and the feature's\n * `scaffold:<marker>:start|end` blocks are stripped from shared files. The\n * registry is the single source of truth for what the feature owns.\n */\nexport interface RegistryFeature {\n /** Stable feature id (e.g. `customer-accounts`). */\n id: string\n /** Human label shown in the scaffold prompt. */\n label: string\n /** Marker tag used in `scaffold:<marker>:start|end` comments. */\n marker: string\n /** Whether the feature is included by default when the operator does not choose. */\n defaultEnabled?: boolean\n /** Files/directories owned entirely by the feature; removed when opted out. */\n paths: string[]\n}\n\nexport interface RegistryTemplate {\n name: string\n dir: string\n title: string\n description?: string\n defaultPaymentProvider: string\n paymentProviders: RegistryPaymentProvider[]\n /** Optional, operator-selectable features pruned when not chosen. */\n features?: RegistryFeature[]\n}\n\nexport interface TemplateRegistry {\n sdk: { package: string; env: RegistryEnvVar[] }\n templates: RegistryTemplate[]\n}\n\nexport const REGISTRY_FILE_NAME = 'registry.json'\n\n/**\n * Read the template registry — the single source of truth for the template\n * roster, payment providers, env keys, and per-provider dependencies. The\n * scaffolder and the package-release scripts both derive their lists from it\n * instead of hardcoding template names.\n */\nexport function readTemplateRegistry(registryDir: string): TemplateRegistry {\n const file = path.join(registryDir, REGISTRY_FILE_NAME)\n const registry = JSON.parse(fs.readFileSync(file, 'utf-8')) as TemplateRegistry\n\n if (!Array.isArray(registry.templates) || registry.templates.length === 0) {\n throw new Error(`Template registry has no templates: ${file}`)\n }\n if (!registry.sdk?.package) {\n throw new Error(`Template registry is missing sdk.package: ${file}`)\n }\n for (const template of registry.templates) {\n if (!template.paymentProviders?.length) {\n throw new Error(\n `Template \"${template.name}\" has no payment providers in ${file}`,\n )\n }\n if (!findPaymentProvider(template, template.defaultPaymentProvider)) {\n throw new Error(\n `Template \"${template.name}\" defaultPaymentProvider \"${template.defaultPaymentProvider}\" is not a registered provider in ${file}`,\n )\n }\n for (const feature of template.features ?? []) {\n if (!feature.id || !feature.marker || !Array.isArray(feature.paths)) {\n throw new Error(\n `Template \"${template.name}\" has a malformed feature (needs id, marker, paths) in ${file}`,\n )\n }\n }\n }\n\n return registry\n}\n\nexport function findTemplate(\n registry: TemplateRegistry,\n name: string,\n): RegistryTemplate | undefined {\n return registry.templates.find((template) => template.name === name)\n}\n\nexport function findPaymentProvider(\n template: RegistryTemplate,\n id: string,\n): RegistryPaymentProvider | undefined {\n return template.paymentProviders.find((provider) => provider.id === id)\n}\n\nexport function findFeature(\n template: RegistryTemplate,\n id: string,\n): RegistryFeature | undefined {\n return template.features?.find((feature) => feature.id === id)\n}\n"],"mappings":"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","names":["fs","path","path","fs","template","provider"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
|
|
2
|
+
type ProjectEnv = 'nextjs' | 'react-vite' | 'react-cra' | 'vanilla' | 'node' | 'edge' | 'other';
|
|
3
|
+
interface ProjectInfo {
|
|
4
|
+
hasPackageJson: boolean;
|
|
5
|
+
parseError: boolean;
|
|
6
|
+
env: ProjectEnv;
|
|
7
|
+
packageManager: PackageManager | null;
|
|
8
|
+
hasSdk: boolean;
|
|
9
|
+
hasReactQuery: boolean;
|
|
10
|
+
srcDir: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type { PackageManager as P, ProjectEnv as a, ProjectInfo as b };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** POSIX file mode for secret-bearing files (`.env*`, global auth config). */
|
|
2
|
+
declare const SECRET_FILE_MODE = 384;
|
|
3
|
+
/** POSIX directory mode for parents of global auth-bearing config. */
|
|
4
|
+
declare const SECRET_DIR_MODE = 448;
|
|
5
|
+
/** Write a `.env*` file with mode `0o600` on POSIX. Skips mode on Windows
|
|
6
|
+
* (secret-handling caveats in `packages/init/AGENTS.md`). */
|
|
7
|
+
declare function writeEnvFile(target: string, content: string): void;
|
|
8
|
+
/** Apply secret-file mode to an existing file (no-op on Windows). Useful
|
|
9
|
+
* after merging an `.env*` file that already existed. */
|
|
10
|
+
declare function chmodSecretFile(target: string): void;
|
|
11
|
+
/** Write a global auth-bearing config (e.g. `~/.codex/config.toml`) using
|
|
12
|
+
* symlink-safe atomic rename. Throws when the existing target is a symlink,
|
|
13
|
+
* has multiple hard links, or is not a regular file. */
|
|
14
|
+
declare function writeSecretGlobalConfig(target: string, content: string): void;
|
|
15
|
+
declare function readEnvValue(content: string, name: string): string | null;
|
|
16
|
+
declare function setEnvValue(content: string, name: string, value: string): string;
|
|
17
|
+
/** Removes the existing `[mcp_servers.01software]` block and sub-blocks from a
|
|
18
|
+
* TOML document, then appends the provided section. */
|
|
19
|
+
declare function replaceTomlMcpSection(content: string, newSection: string): string;
|
|
20
|
+
|
|
21
|
+
export { SECRET_DIR_MODE, SECRET_FILE_MODE, chmodSecretFile, readEnvValue, replaceTomlMcpSection, setEnvValue, writeEnvFile, writeSecretGlobalConfig };
|
package/dist/file-ops.js
CHANGED
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectProject,
|
|
4
4
|
init
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WDWJ73KP.js";
|
|
6
6
|
import "./chunk-Q6MSORYN.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-STM4DKVZ.js";
|
|
8
|
+
import "./chunk-4LHYICUL.js";
|
|
9
|
+
import "./chunk-NJ4X7VNK.js";
|
|
9
10
|
|
|
10
11
|
// src/index.ts
|
|
11
12
|
import pc from "picocolors";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/prompts.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 { createClient } from '@01.software/sdk'\n export const client = createClient({ publishableKey: 'YOUR_PUBLISHABLE_KEY' })\n\n 3. Server client (SSR / loaders / endpoints):\n import { createServerClient } from '@01.software/sdk/server'\n export const serverClient = createServerClient({\n publishableKey: process.env.PUBLIC_SOFTWARE_PUBLISHABLE_KEY!, // prefix varies by framework\n secretKey: process.env.SOFTWARE_SECRET_KEY!,\n })\n\n 4. Docs: https://docs.01.software/developers/sdk\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 || info.parseError) {\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 const result = 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 (result.installFailed) {\n console.log(pc.yellow(' Install the SDK manually:'))\n console.log(pc.cyan(` ${result.installCmd}`))\n console.log()\n }\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 console.log(pc.dim(' Optional: start browser analytics with the generated helper:'))\n console.log()\n console.log(pc.cyan(\" import { analytics } from '@/lib/software/analytics'\"))\n console.log(pc.cyan(\" analytics.track('signup')\"))\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 console.log(pc.dim(' Optional: start browser analytics with the generated helper:'))\n console.log()\n console.log(pc.cyan(\" import { analytics } from './lib/software/analytics'\"))\n console.log(pc.cyan(\" analytics.track('signup')\"))\n console.log()\n } else if (env === 'vanilla') {\n console.log(pc.dim(' Replace YOUR_PUBLISHABLE_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 articles = await client.collections.from('articles').find()\"))\n console.log()\n console.log(pc.dim(' Optional: wire the analytics helper in lib/software/analytics.ts'))\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 articles = await serverClient.collections.from('articles').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.PUBLISHABLE_KEY, env.SECRET_KEY)'))\n console.log()\n }\n\n // Prefer keys returned by `init()` (e.g. from browser-auth) over the\n // original prompt answers. Browser-auth credentials are written directly\n // and must not leave the user looking at stale \"Update .env\" instructions.\n const effectivePublishableKey = result.publishableKey ?? answers.publishableKey\n const effectiveSecretKey = result.secretKey ?? answers.secretKey\n const missingPublishableKey = env !== 'vanilla' && !effectivePublishableKey\n const missingSecretKey = (env === 'nextjs' || env === 'node') && !effectiveSecretKey\n if (missingPublishableKey || missingSecretKey) {\n console.log(pc.dim(' Update .env with your SDK credentials'))\n console.log()\n }\n if (answers.aiTools.length > 0) {\n console.log(pc.dim(' MCP config uses OAuth discovery.'))\n console.log(pc.dim(' Agent discovery flow:'))\n console.log(pc.cyan(' 1. Read https://01.software/llms.txt'))\n console.log(pc.cyan(' 2. Connect https://mcp.01.software/mcp'))\n console.log(pc.cyan(' 3. Read https://docs.01.software/skill.md'))\n console.log(pc.cyan(' 4. Inspect https://docs.01.software/api/openapi'))\n console.log(pc.cyan(' 5. Run local lint, typecheck, tests, and build'))\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 prompts from 'prompts'\nimport type { PackageManager, ProjectEnv } from './detect'\n\nexport type AiTool =\n | 'claude'\n | 'cursor'\n | 'vscode'\n | 'windsurf'\n | 'codex'\n | 'gemini'\n\nexport type AuthMethod = 'browser' | 'manual' | 'skip'\n\nexport interface InitAnswers {\n env: ProjectEnv\n publishableKey: string\n secretKey: string\n aiTools: AiTool[]\n authMethod: AuthMethod\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, publishableKey: '', secretKey: '', aiTools: [], authMethod: 'skip', 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: 'publishableKey',\n message: 'Publishable 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 // AI tool multi-select (empty selection = skip)\n const { selectedTools } = await prompts(\n {\n type: 'multiselect',\n name: 'selectedTools',\n message: 'Connect AI tools (leave empty to skip):',\n choices: [\n { title: 'Claude Code', description: '.mcp.json + .claude/ docs', value: 'claude' },\n { title: 'Cursor', description: '.cursor/mcp.json', value: 'cursor' },\n { title: 'VS Code', description: '.vscode/mcp.json', value: 'vscode' },\n { title: 'Windsurf', description: '~/.codeium/windsurf/mcp_config.json', value: 'windsurf' },\n { title: 'Codex CLI', description: '~/.codex/config.toml', value: 'codex' },\n { title: 'Gemini CLI', description: '~/.gemini/settings.json', value: 'gemini' },\n ],\n hint: 'space to select, enter to confirm',\n },\n { onCancel },\n )\n\n const aiTools: AiTool[] = Array.isArray(selectedTools) ? (selectedTools as AiTool[]) : []\n\n // Auth method — only if tools selected and env supports secrets\n let authMethod: AuthMethod = 'skip'\n let keys: Record<string, string> = {}\n\n if (aiTools.length > 0 && env !== 'vanilla') {\n const { method } = await prompts(\n {\n type: 'select',\n name: 'method',\n message: 'SDK credentials:',\n choices: [\n { title: 'Browser login (recommended)', value: 'browser' },\n { title: 'Enter manually', value: 'manual' },\n { title: 'Skip for now', value: 'skip' },\n ],\n },\n { onCancel },\n )\n authMethod = (method as AuthMethod) ?? 'skip'\n\n if (authMethod === 'manual') {\n keys = await prompts(keyPrompts, { onCancel })\n }\n } else if (env !== 'vanilla') {\n // No AI tools selected — still collect keys from the key prompts if any were defined\n if (keyPrompts.length > 0) {\n keys = await prompts(keyPrompts, { onCancel })\n }\n authMethod = 'skip'\n }\n\n return {\n env,\n publishableKey: authMethod === 'browser' ? '' : (keys.publishableKey ?? ''),\n secretKey: authMethod === 'browser' ? '' : (keys.secretKey ?? ''),\n aiTools,\n authMethod,\n packageManager,\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/prompts.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 { createClient } from '@01.software/sdk'\n export const client = createClient({ publishableKey: 'YOUR_PUBLISHABLE_KEY' })\n\n 3. Server client (SSR / loaders / endpoints):\n import { createServerClient } from '@01.software/sdk/server'\n export const serverClient = createServerClient({\n publishableKey: process.env.PUBLIC_SOFTWARE_PUBLISHABLE_KEY!, // prefix varies by framework\n secretKey: process.env.SOFTWARE_SECRET_KEY!,\n })\n\n 4. Docs: https://docs.01.software/developers/sdk\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 || info.parseError) {\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 const result = 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 (result.installFailed) {\n console.log(pc.yellow(' Install the SDK manually:'))\n console.log(pc.cyan(` ${result.installCmd}`))\n console.log()\n }\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 console.log(pc.dim(' Optional: start browser analytics with the generated helper:'))\n console.log()\n console.log(pc.cyan(\" import { analytics } from '@/lib/software/analytics'\"))\n console.log(pc.cyan(\" analytics.track('signup')\"))\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 console.log(pc.dim(' Optional: start browser analytics with the generated helper:'))\n console.log()\n console.log(pc.cyan(\" import { analytics } from './lib/software/analytics'\"))\n console.log(pc.cyan(\" analytics.track('signup')\"))\n console.log()\n } else if (env === 'vanilla') {\n console.log(pc.dim(' Replace YOUR_PUBLISHABLE_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 articles = await client.collections.from('articles').find()\"))\n console.log()\n console.log(pc.dim(' Optional: wire the analytics helper in lib/software/analytics.ts'))\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 articles = await serverClient.collections.from('articles').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.PUBLISHABLE_KEY, env.SECRET_KEY)'))\n console.log()\n }\n\n // Prefer keys returned by `init()` (e.g. from browser-auth) over the\n // original prompt answers. Browser-auth credentials are written directly\n // and must not leave the user looking at stale \"Update .env\" instructions.\n const effectivePublishableKey = result.publishableKey ?? answers.publishableKey\n const effectiveSecretKey = result.secretKey ?? answers.secretKey\n const missingPublishableKey = env !== 'vanilla' && !effectivePublishableKey\n const missingSecretKey = (env === 'nextjs' || env === 'node') && !effectiveSecretKey\n if (missingPublishableKey || missingSecretKey) {\n console.log(pc.dim(' Update .env with your SDK credentials'))\n console.log()\n }\n if (answers.aiTools.length > 0) {\n console.log(pc.dim(' MCP config uses OAuth discovery.'))\n console.log(pc.dim(' Agent discovery flow:'))\n console.log(pc.cyan(' 1. Read https://01.software/llms.txt'))\n console.log(pc.cyan(' 2. Connect https://mcp.01.software/mcp'))\n console.log(pc.cyan(' 3. Read https://docs.01.software/skill.md'))\n console.log(pc.cyan(' 4. Inspect https://docs.01.software/api/openapi'))\n console.log(pc.cyan(' 5. Run local lint, typecheck, tests, and build'))\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 prompts from 'prompts'\nimport type { PackageManager, ProjectEnv } from './detect'\n\nexport type AiTool =\n | 'claude'\n | 'cursor'\n | 'vscode'\n | 'windsurf'\n | 'codex'\n | 'gemini'\n\nexport type AuthMethod = 'browser' | 'manual' | 'skip'\n\nexport interface InitAnswers {\n env: ProjectEnv\n publishableKey: string\n secretKey: string\n aiTools: AiTool[]\n authMethod: AuthMethod\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, publishableKey: '', secretKey: '', aiTools: [], authMethod: 'skip', 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: 'publishableKey',\n message: 'Publishable 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 // AI tool multi-select (empty selection = skip)\n const { selectedTools } = await prompts(\n {\n type: 'multiselect',\n name: 'selectedTools',\n message: 'Connect AI tools (leave empty to skip):',\n choices: [\n { title: 'Claude Code', description: '.mcp.json + .claude/ docs', value: 'claude' },\n { title: 'Cursor', description: '.cursor/mcp.json', value: 'cursor' },\n { title: 'VS Code', description: '.vscode/mcp.json', value: 'vscode' },\n { title: 'Windsurf', description: '~/.codeium/windsurf/mcp_config.json', value: 'windsurf' },\n { title: 'Codex CLI', description: '~/.codex/config.toml', value: 'codex' },\n { title: 'Gemini CLI', description: '~/.gemini/settings.json', value: 'gemini' },\n ],\n hint: 'space to select, enter to confirm',\n },\n { onCancel },\n )\n\n const aiTools: AiTool[] = Array.isArray(selectedTools) ? (selectedTools as AiTool[]) : []\n\n // Auth method — only if tools selected and env supports secrets\n let authMethod: AuthMethod = 'skip'\n let keys: Record<string, string> = {}\n\n if (aiTools.length > 0 && env !== 'vanilla') {\n const { method } = await prompts(\n {\n type: 'select',\n name: 'method',\n message: 'SDK credentials:',\n choices: [\n { title: 'Browser login (recommended)', value: 'browser' },\n { title: 'Enter manually', value: 'manual' },\n { title: 'Skip for now', value: 'skip' },\n ],\n },\n { onCancel },\n )\n authMethod = (method as AuthMethod) ?? 'skip'\n\n if (authMethod === 'manual') {\n keys = await prompts(keyPrompts, { onCancel })\n }\n } else if (env !== 'vanilla') {\n // No AI tools selected — still collect keys from the key prompts if any were defined\n if (keyPrompts.length > 0) {\n keys = await prompts(keyPrompts, { onCancel })\n }\n authMethod = 'skip'\n }\n\n return {\n env,\n publishableKey: authMethod === 'browser' ? '' : (keys.publishableKey ?? ''),\n secretKey: authMethod === 'browser' ? '' : (keys.secretKey ?? ''),\n aiTools,\n authMethod,\n packageManager,\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { a as ProjectEnv, P as PackageManager, b as ProjectInfo } from './detect-Bjxp9wcS.js';
|
|
2
|
+
import { s as startBrowserAuth } from './browser-auth-CJDrpp5T.js';
|
|
3
|
+
|
|
4
|
+
type AiTool = 'claude' | 'cursor' | 'vscode' | 'windsurf' | 'codex' | 'gemini';
|
|
5
|
+
type AuthMethod = 'browser' | 'manual' | 'skip';
|
|
6
|
+
interface InitAnswers {
|
|
7
|
+
env: ProjectEnv;
|
|
8
|
+
publishableKey: string;
|
|
9
|
+
secretKey: string;
|
|
10
|
+
aiTools: AiTool[];
|
|
11
|
+
authMethod: AuthMethod;
|
|
12
|
+
packageManager?: PackageManager;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type ResolvedProjectInfo = Omit<ProjectInfo, 'packageManager'> & {
|
|
16
|
+
packageManager: PackageManager;
|
|
17
|
+
};
|
|
18
|
+
type ConflictPolicy = 'overwrite' | 'skip' | 'ask';
|
|
19
|
+
interface InitResult {
|
|
20
|
+
installFailed: boolean;
|
|
21
|
+
installSkipped: boolean;
|
|
22
|
+
installCmd: string;
|
|
23
|
+
/** Set when browser-auth or manual entry produced a publishable key the
|
|
24
|
+
* caller should prefer over `answers.publishableKey` when computing
|
|
25
|
+
* next-step messages. */
|
|
26
|
+
publishableKey?: string;
|
|
27
|
+
/** Set when browser-auth or manual entry produced a secret key. */
|
|
28
|
+
secretKey?: string;
|
|
29
|
+
/** Tenant display name from browser-auth, when available. */
|
|
30
|
+
tenantName?: string;
|
|
31
|
+
}
|
|
32
|
+
interface InitDeps {
|
|
33
|
+
/** Test seam — replaces the real browser-auth flow. */
|
|
34
|
+
startBrowserAuth?: typeof startBrowserAuth;
|
|
35
|
+
/** Test seam — skips actually invoking the package manager. */
|
|
36
|
+
skipInstall?: boolean;
|
|
37
|
+
}
|
|
38
|
+
declare function init(cwd: string, info: ResolvedProjectInfo, answers: InitAnswers, deps?: InitDeps): Promise<InitResult>;
|
|
39
|
+
|
|
40
|
+
export { type ConflictPolicy, type InitDeps, type InitResult, init };
|
package/dist/init.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
init
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WDWJ73KP.js";
|
|
5
5
|
import "./chunk-Q6MSORYN.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-STM4DKVZ.js";
|
|
7
|
+
import "./chunk-4LHYICUL.js";
|
|
8
|
+
import "./chunk-NJ4X7VNK.js";
|
|
8
9
|
export {
|
|
9
10
|
init
|
|
10
11
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { a as ProjectEnv } from './detect-Bjxp9wcS.js';
|
|
2
|
+
|
|
3
|
+
declare function getClientTemplate(env: ProjectEnv, publishableKeyEnvVar: string): string;
|
|
4
|
+
declare function getAnalyticsTemplate(env: ProjectEnv, publishableKeyEnvVar: string): string;
|
|
5
|
+
declare function getQueryProviderTemplate(env: ProjectEnv): string;
|
|
6
|
+
declare function getServerTemplate(env: ProjectEnv, publishableKeyEnvVar: string, secretKeyEnvVar: string): string;
|
|
7
|
+
declare function getEnvContent(publishableKey: string, secretKey: string, publishableKeyEnvVar: string, secretKeyEnvVar: string | null): string;
|
|
8
|
+
type McpJsonClient = 'generic' | 'windsurf' | 'vscode';
|
|
9
|
+
/** VS Code's MCP config root key is `servers`; all other JSON clients use
|
|
10
|
+
* `mcpServers` (MCP config caveats in `packages/init/AGENTS.md`). */
|
|
11
|
+
declare function getMcpRootKey(client?: McpJsonClient): 'servers' | 'mcpServers';
|
|
12
|
+
declare function getMcpServerEntry(client?: McpJsonClient): {
|
|
13
|
+
serverUrl: string;
|
|
14
|
+
type?: undefined;
|
|
15
|
+
url?: undefined;
|
|
16
|
+
} | {
|
|
17
|
+
type: "http";
|
|
18
|
+
url: string;
|
|
19
|
+
serverUrl?: undefined;
|
|
20
|
+
};
|
|
21
|
+
declare function getMcpConfigTemplate(client?: McpJsonClient): string;
|
|
22
|
+
/** Codex CLI `[mcp_servers.01software]` block. Idempotent marker: the header
|
|
23
|
+
* line. Intended to be appended to `~/.codex/config.toml`. */
|
|
24
|
+
declare function getCodexMcpTomlSection(): string;
|
|
25
|
+
declare const CODEX_MCP_SECTION_MARKER = "[mcp_servers.01software]";
|
|
26
|
+
|
|
27
|
+
export { CODEX_MCP_SECTION_MARKER, type McpJsonClient, getAnalyticsTemplate, getClientTemplate, getCodexMcpTomlSection, getEnvContent, getMcpConfigTemplate, getMcpRootKey, getMcpServerEntry, getQueryProviderTemplate, getServerTemplate };
|
package/dist/templates.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@01.software/init",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Initialize 01.software SDK in your project (Next.js, React, Vanilla JS, Node.js, Edge)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,7 +8,22 @@
|
|
|
8
8
|
"directory": "packages/init"
|
|
9
9
|
},
|
|
10
10
|
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./create-app": {
|
|
19
|
+
"types": "./dist/create-app.d.ts",
|
|
20
|
+
"default": "./dist/create-app.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
11
23
|
"bin": {
|
|
24
|
+
"01-create-app": "./dist/create-app.js",
|
|
25
|
+
"create-01-software-app": "./dist/create-app.js",
|
|
26
|
+
"init": "./dist/index.js",
|
|
12
27
|
"01-init": "./dist/index.js"
|
|
13
28
|
},
|
|
14
29
|
"files": [
|
|
@@ -17,28 +32,29 @@
|
|
|
17
32
|
"engines": {
|
|
18
33
|
"node": ">=18.0.0"
|
|
19
34
|
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup && node scripts/copy-create-app-templates.mjs",
|
|
37
|
+
"dev": "tsup --watch",
|
|
38
|
+
"check-types": "tsc --noEmit",
|
|
39
|
+
"check-snippets": "tsc --project tsconfig.fixture.json --noEmit",
|
|
40
|
+
"test": "pnpm run build && node --test tests/**/*.test.mjs",
|
|
41
|
+
"prepublishOnly": "pnpm run check-types && pnpm run build",
|
|
42
|
+
"release:dev": "node ../../scripts/publish.js dev init",
|
|
43
|
+
"release:local": "node ../../scripts/publish.js local init"
|
|
44
|
+
},
|
|
20
45
|
"dependencies": {
|
|
21
46
|
"picocolors": "^1.1.1",
|
|
22
47
|
"prompts": "^2.4.2"
|
|
23
48
|
},
|
|
24
49
|
"devDependencies": {
|
|
25
|
-
"@
|
|
50
|
+
"@01.software/sdk": "workspace:^",
|
|
51
|
+
"@types/node": "catalog:node22",
|
|
26
52
|
"@types/prompts": "^2.4.9",
|
|
27
|
-
"tsup": "
|
|
28
|
-
"typescript": "
|
|
29
|
-
"@01.software/sdk": "^0.38.0"
|
|
53
|
+
"tsup": "catalog:",
|
|
54
|
+
"typescript": "catalog:"
|
|
30
55
|
},
|
|
31
56
|
"author": "<office@01.works>",
|
|
32
57
|
"publishConfig": {
|
|
33
58
|
"access": "public"
|
|
34
|
-
},
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "tsup",
|
|
37
|
-
"dev": "tsup --watch",
|
|
38
|
-
"check-types": "tsc --noEmit",
|
|
39
|
-
"check-snippets": "tsc --project tsconfig.fixture.json --noEmit",
|
|
40
|
-
"test": "pnpm run build && node --test tests/**/*.test.mjs",
|
|
41
|
-
"release:dev": "node ../../scripts/publish.js dev init",
|
|
42
|
-
"release:local": "node ../../scripts/publish.js local init"
|
|
43
59
|
}
|
|
44
|
-
}
|
|
60
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/init.ts","../src/detect.ts","../src/browser-auth.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { execSync } from 'node:child_process'\nimport pc from 'picocolors'\nimport prompts from 'prompts'\nimport type { PackageManager, ProjectEnv, ProjectInfo } from './detect'\nimport {\n needsClient,\n needsServer,\n needsReactQuery,\n getPublishableKeyEnvVar,\n} from './detect'\nimport type { AiTool, InitAnswers } from './prompts'\nimport {\n getClientTemplate,\n getAnalyticsTemplate,\n getQueryProviderTemplate,\n getServerTemplate,\n getEnvContent,\n getMcpConfigTemplate,\n getMcpRootKey,\n getMcpServerEntry,\n getCodexMcpTomlSection,\n CODEX_MCP_SECTION_MARKER,\n} from './templates'\nimport { startBrowserAuth } from './browser-auth'\nimport {\n generateClaudeMd,\n getSkillFiles,\n fetchTenantContext,\n} from './ai-docs'\nimport {\n readEnvValue,\n setEnvValue,\n replaceTomlMcpSection,\n writeEnvFile,\n chmodSecretFile,\n writeSecretGlobalConfig,\n} from './file-ops'\n\ntype ResolvedProjectInfo = Omit<ProjectInfo, 'packageManager'> & {\n packageManager: PackageManager\n}\n\nconst SECRET_KEY_ENV_VAR = 'SOFTWARE_SECRET_KEY'\n\nexport type ConflictPolicy = 'overwrite' | 'skip' | 'ask'\n\nexport interface InitResult {\n installFailed: boolean\n installSkipped: boolean\n installCmd: string\n /** Set when browser-auth or manual entry produced a publishable key the\n * caller should prefer over `answers.publishableKey` when computing\n * next-step messages. */\n publishableKey?: string\n /** Set when browser-auth or manual entry produced a secret key. */\n secretKey?: string\n /** Tenant display name from browser-auth, when available. */\n tenantName?: string\n}\n\nexport interface InitDeps {\n /** Test seam — replaces the real browser-auth flow. */\n startBrowserAuth?: typeof startBrowserAuth\n /** Test seam — skips actually invoking the package manager. */\n skipInstall?: boolean\n}\n\nexport async function init(\n cwd: string,\n info: ResolvedProjectInfo,\n answers: InitAnswers,\n deps: InitDeps = {},\n): Promise<InitResult> {\n const { packageManager, srcDir } = info\n const env = answers.env\n const baseDir = srcDir ? path.join(cwd, 'src') : cwd\n const browserAuth = deps.startBrowserAuth ?? startBrowserAuth\n\n const publishableKeyEnvVar = getPublishableKeyEnvVar(env)\n const wantsClient = needsClient(env)\n const wantsServer = needsServer(env)\n const wantsReactQuery = needsReactQuery(env)\n\n // 0. Plan: scan for conflicts and pick the env file. Both prompts are\n // front-loaded so the rest of init() doesn't interleave I/O with prompts.\n const plan = await planConflictsAndEnv(cwd, baseDir, env, answers)\n\n // 1. Install dependencies — skip whatever's already in package.json\n const installResult = deps.skipInstall\n ? {\n installFailed: false,\n installSkipped: true,\n installCmd: buildAddCmd(packageManager, hasPnpmWorkspace(cwd), [\n '@01.software/sdk',\n ]),\n }\n : installDeps(\n cwd,\n packageManager,\n info.hasSdk,\n info.hasReactQuery,\n wantsReactQuery,\n )\n\n // 2. Write lib/software/ files\n if (wantsClient || wantsReactQuery || wantsServer) {\n fs.mkdirSync(path.join(baseDir, 'lib', 'software'), { recursive: true })\n }\n const libDir = path.join(baseDir, 'lib', 'software')\n\n if (wantsClient) {\n await writeFileWithPolicy(\n cwd,\n path.join(libDir, 'client.ts'),\n getClientTemplate(env, publishableKeyEnvVar),\n plan.policy,\n )\n await writeFileWithPolicy(\n cwd,\n path.join(libDir, 'analytics.ts'),\n getAnalyticsTemplate(env, publishableKeyEnvVar),\n plan.policy,\n )\n }\n if (wantsReactQuery) {\n await writeFileWithPolicy(\n cwd,\n path.join(libDir, 'query-provider.tsx'),\n getQueryProviderTemplate(env),\n plan.policy,\n )\n }\n if (wantsServer) {\n await writeFileWithPolicy(\n cwd,\n path.join(libDir, 'server.ts'),\n getServerTemplate(env, publishableKeyEnvVar, SECRET_KEY_ENV_VAR),\n plan.policy,\n )\n }\n\n // 3. Append to env file (browser auth handles its own write in step 4)\n if (plan.envFile && answers.authMethod !== 'browser') {\n await writeEnv(\n cwd,\n plan.envFile,\n answers.publishableKey || '',\n answers.secretKey || '',\n publishableKeyEnvVar,\n wantsServer ? SECRET_KEY_ENV_VAR : null,\n plan.policy,\n )\n }\n\n // 4. Browser auth — get real credentials and force-write env\n let publishableKey = answers.publishableKey\n let secretKey = answers.secretKey\n let tenantName = ''\n\n if (answers.authMethod === 'browser' && answers.aiTools.length > 0) {\n try {\n console.log()\n const creds = await browserAuth()\n publishableKey = creds.publishableKey\n secretKey = creds.secretKey\n tenantName = creds.tenantName\n\n // Browser auth just minted fresh credentials → policy is overwrite.\n if (plan.envFile && publishableKey) {\n await writeEnv(\n cwd,\n plan.envFile,\n publishableKey,\n secretKey,\n publishableKeyEnvVar,\n wantsServer ? SECRET_KEY_ENV_VAR : null,\n 'overwrite',\n true,\n )\n }\n } catch (err) {\n console.log(\n pc.yellow(' Browser auth skipped:'),\n err instanceof Error ? err.message : String(err),\n )\n }\n }\n\n // 5. AI tool configs (MCP + Claude docs)\n if (answers.aiTools.length > 0) {\n for (const tool of answers.aiTools) {\n await writeMcpConfig(tool, cwd)\n }\n\n addToGitignore(cwd, answers.aiTools)\n\n if (answers.aiTools.includes('claude')) {\n await writeClaudeDocs(cwd, publishableKey, secretKey, tenantName, plan.policy)\n }\n }\n\n return {\n ...installResult,\n publishableKey: publishableKey || undefined,\n secretKey: secretKey || undefined,\n tenantName: tenantName || undefined,\n }\n}\n\n// ── Install ──────────────────────────────────────────────────────────\n\ninterface DepSpec {\n name: string\n installed: boolean\n needed: boolean\n}\n\nfunction installDeps(\n cwd: string,\n pm: PackageManager,\n hasSdk: boolean,\n hasReactQuery: boolean,\n wantsReactQuery: boolean,\n): InitResult {\n const allDeps: DepSpec[] = [\n { name: '@01.software/sdk', installed: hasSdk, needed: true },\n { name: '@tanstack/react-query', installed: hasReactQuery, needed: wantsReactQuery },\n ]\n const fullList = allDeps.filter((d) => d.needed).map((d) => d.name)\n const toInstall = allDeps.filter((d) => d.needed && !d.installed).map((d) => d.name)\n const fullCmd = buildAddCmd(pm, hasPnpmWorkspace(cwd), fullList)\n\n if (toInstall.length === 0) {\n console.log(pc.dim(` Dependencies already installed: ${fullList.join(', ')}`))\n return { installFailed: false, installSkipped: true, installCmd: fullCmd }\n }\n\n const addCmd = buildAddCmd(pm, hasPnpmWorkspace(cwd), toInstall)\n console.log(pc.dim(` Installing ${toInstall.join(' and ')}...`))\n\n const wsPatched = pm === 'pnpm' && patchPnpmWorkspace(cwd)\n let installFailed = false\n\n try {\n execSync(addCmd, { cwd, stdio: 'pipe' })\n console.log(pc.green(' Installed'), toInstall.join(', '))\n } catch (error) {\n installFailed = true\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.yellow(' Install failed — continuing with scaffolding'))\n const firstLines = msg.split('\\n').slice(0, 3).map((l) => ` ${l}`).join('\\n')\n if (firstLines) console.log(pc.dim(firstLines))\n console.log(pc.dim(` Run manually: ${addCmd}`))\n } finally {\n if (wsPatched) restorePnpmWorkspace(cwd)\n }\n\n return { installFailed, installSkipped: false, installCmd: addCmd }\n}\n\nfunction buildAddCmd(\n pm: PackageManager,\n hasPnpmWs: boolean,\n deps: string[],\n): string {\n const pkgs = deps.join(' ')\n switch (pm) {\n case 'pnpm':\n return hasPnpmWs ? `pnpm add -w ${pkgs}` : `pnpm add ${pkgs}`\n case 'yarn':\n return `yarn add ${pkgs}`\n case 'bun':\n return `bun add ${pkgs}`\n default:\n return `npm install ${pkgs}`\n }\n}\n\n// ── Conflict planning ────────────────────────────────────────────────\n\ninterface PlanResult {\n policy: ConflictPolicy\n /** Empty string when env file is not used (vanilla / edge) */\n envFile: string\n}\n\nasync function planConflictsAndEnv(\n cwd: string,\n baseDir: string,\n env: ProjectEnv,\n answers: InitAnswers,\n): Promise<PlanResult> {\n const candidates: string[] = []\n const libDir = path.join(baseDir, 'lib', 'software')\n if (needsClient(env)) candidates.push(path.join(libDir, 'client.ts'))\n if (needsReactQuery(env)) candidates.push(path.join(libDir, 'query-provider.tsx'))\n if (needsServer(env)) candidates.push(path.join(libDir, 'server.ts'))\n if (answers.aiTools.includes('claude')) {\n for (const { dirName } of getSkillFiles()) {\n candidates.push(path.join(cwd, '.claude', 'skills', dirName, 'SKILL.md'))\n }\n }\n\n const conflicts = candidates.filter((p) => fs.existsSync(p))\n\n let policy: ConflictPolicy = 'skip'\n if (conflicts.length > 0) {\n console.log(pc.yellow(` ${conflicts.length} file(s) already exist:`))\n for (const c of conflicts) console.log(pc.dim(` ${path.relative(cwd, c)}`))\n const { selected } = await prompts({\n type: 'select',\n name: 'selected',\n message: 'How should I handle existing files?',\n choices: [\n { title: 'Keep existing (skip)', value: 'skip' },\n { title: 'Overwrite all', value: 'overwrite' },\n { title: 'Ask for each', value: 'ask' },\n ],\n initial: 0,\n })\n policy = (selected as ConflictPolicy) ?? 'skip'\n }\n\n const envFile =\n env === 'vanilla' || env === 'edge' ? '' : await pickEnvFile(cwd, env)\n\n return { policy, envFile }\n}\n\nasync function pickEnvFile(cwd: string, env: ProjectEnv): Promise<string> {\n // Order matters — `.env.local` first so it's the default selection on\n // Next.js, where it's the conventional secret store.\n const candidates = ['.env.local', '.env', '.env.development']\n const existing = candidates.filter((f) => fs.existsSync(path.join(cwd, f)))\n const preferred = env === 'nextjs' ? '.env.local' : '.env'\n\n if (existing.length === 0) return preferred\n if (existing.length === 1 && existing[0] === preferred) return existing[0]\n\n // Multiple files exist OR the only existing file isn't the preferred default.\n const options = Array.from(new Set([...existing, preferred]))\n const choices = options.map((f) => ({\n title: f,\n description: existing.includes(f) ? 'exists' : 'create',\n value: f,\n }))\n const initial = Math.max(\n 0,\n choices.findIndex((c) => c.value === preferred),\n )\n const { file } = await prompts({\n type: 'select',\n name: 'file',\n message: 'Which env file should I write SDK credentials to?',\n choices,\n initial,\n })\n return file ?? preferred\n}\n\n// ── Generic file write ───────────────────────────────────────────────\n\nasync function writeFileWithPolicy(\n cwd: string,\n filePath: string,\n content: string,\n policy: ConflictPolicy,\n): Promise<void> {\n const rel = path.relative(cwd, filePath)\n if (!fs.existsSync(filePath)) {\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, content)\n console.log(pc.green(' Created'), rel)\n return\n }\n\n const existing = fs.readFileSync(filePath, 'utf-8')\n if (existing === content) {\n console.log(pc.dim(' Unchanged'), rel)\n return\n }\n\n let shouldWrite = false\n if (policy === 'overwrite') {\n shouldWrite = true\n } else if (policy === 'ask') {\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: `Overwrite ${rel}?`,\n initial: false,\n })\n shouldWrite = !!confirm\n }\n\n if (shouldWrite) {\n fs.writeFileSync(filePath, content)\n console.log(pc.green(' Overwrote'), rel)\n } else {\n console.log(pc.yellow(' Skipped'), rel, pc.dim('(already exists)'))\n }\n}\n\n// ── Env file write ───────────────────────────────────────────────────\n\nasync function writeEnv(\n cwd: string,\n envFile: string,\n publishableKey: string,\n secretKey: string,\n publishableKeyEnvVar: string,\n secretKeyEnvVar: string | null,\n policy: ConflictPolicy,\n fromBrowserAuth = false,\n): Promise<void> {\n const envPath = path.join(cwd, envFile)\n\n const targets: { name: string; value: string }[] = [\n { name: publishableKeyEnvVar, value: publishableKey },\n ]\n if (secretKeyEnvVar) {\n targets.push({ name: secretKeyEnvVar, value: secretKey })\n }\n\n if (!fs.existsSync(envPath)) {\n const initial = getEnvContent(publishableKey, secretKey, publishableKeyEnvVar, secretKeyEnvVar)\n writeEnvFile(envPath, initial.trimStart())\n console.log(pc.green(' Created'), envFile)\n return\n }\n\n let content = fs.readFileSync(envPath, 'utf-8')\n let modified = false\n let appendedHeader = false\n const headerAlreadyPresent = targets.some(\n (t) => readEnvValue(content, t.name) !== null,\n )\n\n for (const { name, value } of targets) {\n const existing = readEnvValue(content, name)\n\n if (existing === null) {\n // Append. Add the `# 01.software` section header on first append, but\n // only if no other 01.software keys are already in the file.\n if (!headerAlreadyPresent && !appendedHeader) {\n if (content.length > 0 && !content.endsWith('\\n')) content += '\\n'\n content += '\\n# 01.software\\n'\n appendedHeader = true\n }\n content = setEnvValue(content, name, value)\n modified = true\n continue\n }\n\n if (existing === value) continue\n // Don't overwrite an existing real value with empty (e.g. user skipped key entry).\n if (!value) continue\n\n let shouldOverwrite = false\n if (policy === 'overwrite') {\n shouldOverwrite = true\n } else if (policy === 'ask') {\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: `${name} already set in ${envFile}. Overwrite?`,\n initial: fromBrowserAuth,\n })\n shouldOverwrite = !!confirm\n }\n\n if (shouldOverwrite) {\n content = setEnvValue(content, name, value)\n modified = true\n }\n }\n\n if (modified) {\n writeEnvFile(envPath, content)\n console.log(\n pc.green(' Updated'),\n envFile,\n fromBrowserAuth ? pc.dim('(SDK credentials)') : '',\n )\n } else {\n // Tighten mode on existing files we did not modify, so re-runs harden\n // permissions on env files created by an earlier looser version.\n chmodSecretFile(envPath)\n console.log(pc.dim(' Unchanged'), envFile)\n }\n}\n\n// ── MCP targets registry ─────────────────────────────────────────────\n\ntype McpFormat = 'json' | 'toml'\ntype McpJsonClient = 'generic' | 'windsurf' | 'vscode'\ninterface McpLocation {\n kind: McpFormat\n absolutePath: string\n jsonClient?: McpJsonClient\n displayPath: string\n gitignoreEntry: string | null // null = global path, not worth ignoring\n /** Global config under user HOME — apply 0o600 mode, atomic rename, and\n * symlink/hardlink rejection per spec §\"Secret Handling Rules\". */\n global?: boolean\n}\n\nfunction resolveMcpLocation(tool: AiTool, cwd: string): McpLocation | null {\n const home = os.homedir()\n\n switch (tool) {\n case 'claude':\n return {\n kind: 'json',\n absolutePath: path.join(cwd, '.mcp.json'),\n displayPath: '.mcp.json',\n gitignoreEntry: '.mcp.json',\n }\n case 'cursor':\n return {\n kind: 'json',\n absolutePath: path.join(cwd, '.cursor', 'mcp.json'),\n displayPath: '.cursor/mcp.json',\n gitignoreEntry: '.cursor/mcp.json',\n }\n case 'vscode':\n return {\n kind: 'json',\n absolutePath: path.join(cwd, '.vscode', 'mcp.json'),\n jsonClient: 'vscode',\n displayPath: '.vscode/mcp.json',\n gitignoreEntry: '.vscode/mcp.json',\n }\n case 'windsurf': {\n if (!home) return null\n const p = path.join(home, '.codeium', 'windsurf', 'mcp_config.json')\n return {\n kind: 'json',\n absolutePath: p,\n jsonClient: 'windsurf',\n displayPath: p,\n gitignoreEntry: null,\n global: true,\n }\n }\n case 'codex': {\n if (!home) return null\n const p = path.join(home, '.codex', 'config.toml')\n return { kind: 'toml', absolutePath: p, displayPath: p, gitignoreEntry: null, global: true }\n }\n case 'gemini': {\n if (!home) return null\n const p = path.join(home, '.gemini', 'settings.json')\n return { kind: 'json', absolutePath: p, displayPath: p, gitignoreEntry: null, global: true }\n }\n }\n}\n\nasync function writeMcpConfig(\n tool: AiTool,\n cwd: string,\n): Promise<void> {\n const loc = resolveMcpLocation(tool, cwd)\n if (!loc) {\n console.log(pc.yellow(` Skipped ${tool}`), pc.dim('(HOME not set)'))\n return\n }\n\n // For global secret-bearing config, parent-dir creation with 0o700 is\n // handled inside `writeSecretGlobalConfig`. Repo-local writes (Claude Code,\n // Cursor, VS Code) keep loose mkdir — they only contain OAuth/discovery URLs.\n if (!loc.global) {\n fs.mkdirSync(path.dirname(loc.absolutePath), { recursive: true })\n }\n\n try {\n if (loc.kind === 'json') {\n writeJsonMcp(loc)\n } else {\n writeTomlMcp(loc)\n }\n } catch (err) {\n console.log(\n pc.yellow(` Skipped ${loc.displayPath}`),\n pc.dim(err instanceof Error ? err.message : String(err)),\n )\n }\n}\n\nfunction writeJsonMcp(loc: McpLocation): void {\n const writeFile = loc.global\n ? (target: string, content: string) => writeSecretGlobalConfig(target, content)\n : (target: string, content: string) => fs.writeFileSync(target, content)\n\n if (!fs.existsSync(loc.absolutePath)) {\n writeFile(loc.absolutePath, getMcpConfigTemplate(loc.jsonClient))\n console.log(pc.green(' Created'), loc.displayPath)\n return\n }\n\n // VS Code uses `servers` as the config root; all other JSON clients use `mcpServers`.\n const rootKey = getMcpRootKey(loc.jsonClient)\n\n let existing: Record<string, unknown>\n try {\n existing = JSON.parse(fs.readFileSync(loc.absolutePath, 'utf-8'))\n } catch {\n console.log(pc.yellow(' Skipped'), loc.displayPath, pc.dim('(could not parse existing file)'))\n return\n }\n\n const nextEntry = getMcpServerEntry(loc.jsonClient)\n const existingServers = (existing[rootKey] as Record<string, unknown> | undefined) ?? undefined\n if (\n existingServers?.['01software'] &&\n JSON.stringify(existingServers['01software']) === JSON.stringify(nextEntry)\n ) {\n console.log(pc.dim(' Unchanged'), loc.displayPath)\n return\n }\n\n const servers = (existing[rootKey] as Record<string, unknown> | undefined) ?? {}\n servers['01software'] = nextEntry\n existing[rootKey] = servers\n writeFile(loc.absolutePath, JSON.stringify(existing, null, 2) + '\\n')\n console.log(pc.green(' Updated'), loc.displayPath)\n}\n\nfunction writeTomlMcp(loc: McpLocation): void {\n const section = getCodexMcpTomlSection()\n const writeFile = loc.global\n ? (target: string, content: string) => writeSecretGlobalConfig(target, content)\n : (target: string, content: string) => fs.writeFileSync(target, content)\n\n if (!fs.existsSync(loc.absolutePath)) {\n writeFile(loc.absolutePath, section.trimStart())\n console.log(pc.green(' Created'), loc.displayPath)\n return\n }\n\n const existing = fs.readFileSync(loc.absolutePath, 'utf-8')\n\n if (!existing.includes(CODEX_MCP_SECTION_MARKER)) {\n const sep = existing.endsWith('\\n') ? '' : '\\n'\n // Atomic rewrite (read-modify-write) — `appendFileSync` would bypass the\n // symlink/hardlink guards and the 0o600 mode of `writeSecretGlobalConfig`.\n writeFile(loc.absolutePath, existing + sep + section)\n console.log(pc.green(' Updated'), loc.displayPath)\n return\n }\n\n const replaced = replaceTomlMcpSection(existing, section)\n if (replaced === existing) {\n console.log(pc.dim(' Unchanged'), loc.displayPath)\n return\n }\n\n writeFile(loc.absolutePath, replaced)\n console.log(pc.green(' Updated'), loc.displayPath)\n}\n\nfunction addToGitignore(cwd: string, tools: AiTool[]): void {\n const entries: string[] = []\n for (const tool of tools) {\n const loc = resolveMcpLocation(tool, cwd)\n if (loc?.gitignoreEntry) entries.push(loc.gitignoreEntry)\n }\n\n if (entries.length === 0) return\n\n const gitignorePath = path.join(cwd, '.gitignore')\n const existing = fs.existsSync(gitignorePath)\n ? fs.readFileSync(gitignorePath, 'utf-8')\n : ''\n const toAdd = entries.filter((e) => !existing.includes(e))\n if (toAdd.length === 0) return\n\n const content = '\\n# MCP configs\\n' + toAdd.join('\\n') + '\\n'\n if (fs.existsSync(gitignorePath)) {\n fs.appendFileSync(gitignorePath, content)\n } else {\n fs.writeFileSync(gitignorePath, content.trimStart())\n }\n console.log(pc.green(' Updated'), '.gitignore', pc.dim(`(added ${toAdd.join(', ')})`))\n}\n\nasync function writeClaudeDocs(\n cwd: string,\n publishableKey: string,\n secretKey: string,\n tenantName: string,\n policy: ConflictPolicy,\n): Promise<void> {\n let ctx = {\n tenantName: tenantName || 'Your Tenant',\n features: undefined as string[] | undefined,\n collections: undefined as string[] | undefined,\n }\n\n if (publishableKey && secretKey) {\n const fetched = await fetchTenantContext(publishableKey, secretKey)\n if (fetched) {\n ctx = {\n tenantName: fetched.tenantName || ctx.tenantName,\n features: fetched.features,\n collections: fetched.collections,\n }\n }\n }\n\n const claudeDir = path.join(cwd, '.claude')\n const softwareDir = path.join(claudeDir, '01software')\n const skillsDir = path.join(claudeDir, 'skills')\n fs.mkdirSync(softwareDir, { recursive: true })\n fs.mkdirSync(skillsDir, { recursive: true })\n\n // context.md is intentionally always overwritten so re-running init\n // refreshes tenant data; users don't customize this file.\n const contextPath = path.join(softwareDir, 'context.md')\n const contextExists = fs.existsSync(contextPath)\n fs.writeFileSync(contextPath, generateClaudeMd(ctx))\n console.log(pc.green(contextExists ? ' Updated' : ' Created'), '.claude/01software/context.md')\n\n // CLAUDE.md — append @import line (idempotent, never overwrites user content)\n const claudeMdPath = path.join(claudeDir, 'CLAUDE.md')\n const importLine = '@.claude/01software/context.md'\n if (!fs.existsSync(claudeMdPath)) {\n fs.writeFileSync(claudeMdPath, importLine + '\\n')\n console.log(pc.green(' Created'), '.claude/CLAUDE.md')\n } else {\n const existing = fs.readFileSync(claudeMdPath, 'utf-8')\n if (!existing.includes(importLine)) {\n const prefix = existing.endsWith('\\n') ? '\\n' : '\\n\\n'\n fs.appendFileSync(claudeMdPath, prefix + importLine + '\\n')\n console.log(pc.green(' Updated'), '.claude/CLAUDE.md', pc.dim('(added @import)'))\n } else {\n console.log(pc.dim(' Unchanged'), '.claude/CLAUDE.md')\n }\n }\n\n // Skill files honour the user's conflict policy (templates the user may have\n // tuned to their workflow).\n for (const { dirName, content } of getSkillFiles()) {\n const skillDir = path.join(skillsDir, dirName)\n const skillPath = path.join(skillDir, 'SKILL.md')\n fs.mkdirSync(skillDir, { recursive: true })\n await writeFileWithPolicy(cwd, skillPath, content, policy)\n }\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 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 hasReactQuery: 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 let hasReactQuery = false\n let parseError = 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 {\n hasPackageJson: true,\n parseError: true,\n env: 'node',\n packageManager: null,\n hasSdk: false,\n hasReactQuery: false,\n srcDir: false,\n }\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 hasReactQuery = '@tanstack/react-query' 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, parseError, env, packageManager, hasSdk, hasReactQuery, 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 publishable key */\nexport function getPublishableKeyEnvVar(env: ProjectEnv): string {\n switch (env) {\n case 'nextjs':\n return 'NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY'\n case 'react-vite':\n return 'VITE_SOFTWARE_PUBLISHABLE_KEY'\n case 'react-cra':\n return 'REACT_APP_SOFTWARE_PUBLISHABLE_KEY'\n default:\n return 'SOFTWARE_PUBLISHABLE_KEY'\n }\n}\n","import { randomBytes } from 'node:crypto'\nimport { createServer } from 'node:http'\nimport { execFile, exec } from 'node:child_process'\nimport { platform } from 'node:os'\nimport { URL } from 'node:url'\nimport pc from 'picocolors'\n\nconst DEFAULT_WEB_URL = process.env.SOFTWARE_WEB_URL || 'https://01.software'\nconst TIMEOUT_MS = 5 * 60 * 1000 // 5 minutes\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\nfunction openBrowser(url: string): void {\n const os = platform()\n\n const onError = () => {\n console.log(\n pc.yellow(\n `Could not open browser automatically. Open this URL manually:\\n${url}`,\n ),\n )\n }\n\n if (os === 'win32') {\n exec(`start \"\" \"${url}\"`, (err) => {\n if (err) onError()\n })\n } else {\n const cmd = os === 'darwin' ? 'open' : 'xdg-open'\n execFile(cmd, [url], (err) => {\n if (err) onError()\n })\n }\n}\n\nconst PAGE_STYLE = `*{margin:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;display:flex;justify-content:center;align-items:center;min-height:100vh;background:#fff;color:#252525}\n@media(prefers-color-scheme:dark){body{background:#252525;color:#f5f5f5}}\n.card{text-align:center;padding:2rem 2.5rem;border-radius:10px;max-width:380px;width:100%}\n.icon{width:40px;height:40px;margin:0 auto 1rem;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.25rem}\n.icon.ok{background:rgba(0,0,0,.05);color:#252525}\n.icon.err{background:rgba(220,38,38,.08);color:#dc2626}\n@media(prefers-color-scheme:dark){.icon.ok{background:rgba(255,255,255,.08);color:#f5f5f5}}\nh1{font-size:.875rem;font-weight:600;margin-bottom:.375rem}\np{font-size:.75rem;color:#737373;line-height:1.5}`\n\nconst SUCCESS_HTML = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>Login</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon ok\">\\u2713</div><h1>Authenticated</h1><p>You can close this tab and return to the terminal.</p></div></body></html>`\n\nconst ERROR_HTML = (msg: string) => `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>Login Error</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon err\">!</div><h1>Authentication failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`\n\ninterface ExchangeResponse {\n publishableKey: string\n secretKey: string\n tenantName: string\n tenantId: string\n}\n\nasync function exchangeCode(\n webUrl: string,\n code: string,\n): Promise<ExchangeResponse | null> {\n const url = `${webUrl}/api/cli/exchange`\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code }),\n })\n if (!res.ok) {\n const body = await res.text().catch(() => '')\n console.error(\n pc.red(\n `Exchange failed: HTTP ${res.status} from ${url}${body ? ` — ${body.slice(0, 200)}` : ''}`,\n ),\n )\n return null\n }\n const data = (await res.json()) as Partial<ExchangeResponse>\n if (\n typeof data.publishableKey !== 'string' ||\n typeof data.secretKey !== 'string' ||\n typeof data.tenantName !== 'string' ||\n typeof data.tenantId !== 'string'\n ) {\n console.error(pc.red(`Exchange failed: malformed response from ${url}`))\n return null\n }\n return {\n publishableKey: data.publishableKey,\n secretKey: data.secretKey,\n tenantName: data.tenantName,\n tenantId: data.tenantId,\n }\n } catch (err) {\n console.error(\n pc.red(\n `Exchange request to ${url} failed: ${err instanceof Error ? err.message : String(err)}`,\n ),\n )\n return null\n }\n}\n\nexport async function startBrowserAuth(options?: {\n webUrl?: string\n tenantId?: string\n}): Promise<{\n publishableKey: string\n secretKey: string\n tenantName: string\n tenantId?: string\n}> {\n const state = randomBytes(32).toString('hex')\n const webUrl = options?.webUrl ?? DEFAULT_WEB_URL\n\n return new Promise((resolve, reject) => {\n const server = createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end()\n return\n }\n\n const url = new URL(req.url, `http://localhost`)\n\n if (url.pathname !== '/callback' || req.method !== 'GET') {\n res.writeHead(404).end()\n return\n }\n\n const error = url.searchParams.get('error')\n if (error) {\n res\n .writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' })\n .end(ERROR_HTML(error))\n console.error(pc.red(`Login failed: ${error}`))\n cleanup(new Error(`Login failed: ${error}`))\n return\n }\n\n const code = url.searchParams.get('code')\n const receivedState = url.searchParams.get('state')\n\n if (!code || !receivedState) {\n res\n .writeHead(400, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' })\n .end(ERROR_HTML('Missing code or state.'))\n cleanup(new Error('Login failed: missing code or state.'))\n return\n }\n\n if (receivedState !== state) {\n res\n .writeHead(403, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' })\n .end(ERROR_HTML('State mismatch.'))\n console.error(pc.red('Login failed: state mismatch.'))\n cleanup(new Error('Login failed: state mismatch.'))\n return\n }\n\n exchangeCode(webUrl, code).then((creds) => {\n if (!creds) {\n res\n .writeHead(400, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' })\n .end(ERROR_HTML('Invalid or expired code.'))\n cleanup(new Error('Login failed: code exchange failed.'))\n return\n }\n\n res\n .writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' })\n .end(SUCCESS_HTML)\n\n console.log(pc.green(`\\nLogged in successfully!`))\n console.log(pc.dim(`Tenant: ${creds.tenantName}`))\n\n cleanup(null, creds)\n })\n })\n\n let timeout: ReturnType<typeof setTimeout>\n let completed = false\n\n function cleanup(err: Error | null, result?: ExchangeResponse) {\n if (completed) return\n completed = true\n clearTimeout(timeout)\n server.closeAllConnections?.()\n server.close(() => {\n if (err) {\n reject(err)\n } else {\n resolve(result!)\n }\n })\n }\n\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to start local server.'))\n return\n }\n\n const port = addr.port\n\n timeout = setTimeout(() => {\n console.error(pc.red('\\nLogin timed out (5 minutes). Please try again.'))\n cleanup(new Error('Login timed out'))\n }, TIMEOUT_MS)\n\n const params = new URLSearchParams({ port: String(port), state })\n if (options?.tenantId) {\n params.set('tenantId', options.tenantId)\n }\n const loginUrl = `${webUrl}/cli-auth?${params.toString()}`\n\n console.log(pc.dim('Opening browser for login...'))\n console.log(pc.dim(`If the browser does not open, visit:\\n${loginUrl}`))\n openBrowser(loginUrl)\n })\n\n server.on('error', (err) => {\n reject(err)\n })\n })\n}\n"],"mappings":"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","names":["fs","path","pc","os","path","fs","pc"]}
|