@wix/web50-cli 0.1.1 → 0.1.2
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/bin/web5.js +1 -2
- package/dist/cjs/auth/deviceFlow.js +90 -17
- package/dist/cjs/auth/deviceFlow.js.map +1 -1
- package/dist/cjs/auth/index.js +40 -10
- package/dist/cjs/auth/index.js.map +1 -1
- package/dist/cjs/cli.js +3 -3
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/bundle.js +12 -4
- package/dist/cjs/commands/bundle.js.map +1 -1
- package/dist/cjs/commands/conversation.js.map +1 -1
- package/dist/cjs/commands/conversationWizard.js +3 -1
- package/dist/cjs/commands/conversationWizard.js.map +1 -1
- package/dist/cjs/commands/deploy.js +55 -10
- package/dist/cjs/commands/deploy.js.map +1 -1
- package/dist/cjs/commands/ecom.js +239 -0
- package/dist/cjs/commands/ecom.js.map +1 -0
- package/dist/cjs/commands/embed.js.map +1 -1
- package/dist/cjs/commands/init.js +34 -3
- package/dist/cjs/commands/init.js.map +1 -1
- package/dist/cjs/commands/instructions.js +147 -51
- package/dist/cjs/commands/instructions.js.map +1 -1
- package/dist/cjs/commands/login.js +8 -4
- package/dist/cjs/commands/login.js.map +1 -1
- package/dist/cjs/commands/serve.js.map +1 -1
- package/dist/cjs/commands/validate.js +368 -16
- package/dist/cjs/commands/validate.js.map +1 -1
- package/dist/cjs/commands/whoami.js.map +1 -1
- package/dist/cjs/templates/aiInstructionsSchema.js +5 -1
- package/dist/cjs/templates/aiInstructionsSchema.js.map +1 -1
- package/dist/cjs/templates/cmsMappingSchema.js +132 -0
- package/dist/cjs/templates/cmsMappingSchema.js.map +1 -0
- package/dist/cjs/utils/project.js +13 -0
- package/dist/cjs/utils/project.js.map +1 -1
- package/dist/cjs/utils/wixApi.js +3 -1
- package/dist/cjs/utils/wixApi.js.map +1 -1
- package/dist/esm/auth/deviceFlow.js +89 -17
- package/dist/esm/auth/deviceFlow.js.map +1 -1
- package/dist/esm/auth/index.js +40 -11
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/cli.js +3 -3
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/bundle.js +12 -4
- package/dist/esm/commands/bundle.js.map +1 -1
- package/dist/esm/commands/conversation.js.map +1 -1
- package/dist/esm/commands/conversationWizard.js +3 -1
- package/dist/esm/commands/conversationWizard.js.map +1 -1
- package/dist/esm/commands/deploy.js +55 -10
- package/dist/esm/commands/deploy.js.map +1 -1
- package/dist/esm/commands/ecom.js +234 -0
- package/dist/esm/commands/ecom.js.map +1 -0
- package/dist/esm/commands/embed.js.map +1 -1
- package/dist/esm/commands/init.js +34 -3
- package/dist/esm/commands/init.js.map +1 -1
- package/dist/esm/commands/instructions.js +152 -53
- package/dist/esm/commands/instructions.js.map +1 -1
- package/dist/esm/commands/login.js +8 -4
- package/dist/esm/commands/login.js.map +1 -1
- package/dist/esm/commands/serve.js.map +1 -1
- package/dist/esm/commands/validate.js +373 -19
- package/dist/esm/commands/validate.js.map +1 -1
- package/dist/esm/commands/whoami.js.map +1 -1
- package/dist/esm/templates/aiInstructionsSchema.js +5 -1
- package/dist/esm/templates/aiInstructionsSchema.js.map +1 -1
- package/dist/esm/templates/cmsMappingSchema.js +128 -0
- package/dist/esm/templates/cmsMappingSchema.js.map +1 -0
- package/dist/esm/utils/project.js +15 -0
- package/dist/esm/utils/project.js.map +1 -1
- package/dist/esm/utils/wixApi.js +4 -2
- package/dist/esm/utils/wixApi.js.map +1 -1
- package/dist/types/auth/deviceFlow.d.ts +1 -1
- package/dist/types/auth/deviceFlow.d.ts.map +1 -1
- package/dist/types/auth/index.d.ts +2 -1
- package/dist/types/auth/index.d.ts.map +1 -1
- package/dist/types/commands/bundle.d.ts.map +1 -1
- package/dist/types/commands/conversation.d.ts.map +1 -1
- package/dist/types/commands/conversationWizard.d.ts.map +1 -1
- package/dist/types/commands/deploy.d.ts.map +1 -1
- package/dist/types/commands/ecom.d.ts +3 -0
- package/dist/types/commands/ecom.d.ts.map +1 -0
- package/dist/types/commands/embed.d.ts.map +1 -1
- package/dist/types/commands/init.d.ts.map +1 -1
- package/dist/types/commands/instructions.d.ts.map +1 -1
- package/dist/types/commands/login.d.ts.map +1 -1
- package/dist/types/commands/serve.d.ts.map +1 -1
- package/dist/types/commands/validate.d.ts +4 -2
- package/dist/types/commands/validate.d.ts.map +1 -1
- package/dist/types/commands/whoami.d.ts.map +1 -1
- package/dist/types/templates/aiInstructionsSchema.d.ts.map +1 -1
- package/dist/types/templates/cmsMappingSchema.d.ts +2 -0
- package/dist/types/templates/cmsMappingSchema.d.ts.map +1 -0
- package/dist/types/utils/project.d.ts +2 -0
- package/dist/types/utils/project.d.ts.map +1 -1
- package/dist/types/utils/wixApi.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/cjs/commands/getClientId.js +0 -60
- package/dist/cjs/commands/getClientId.js.map +0 -1
- package/dist/esm/commands/getClientId.js +0 -56
- package/dist/esm/commands/getClientId.js.map +0 -1
- package/dist/types/commands/getClientId.d.ts +0 -3
- package/dist/types/commands/getClientId.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Command","inquirer","open","wixRequest","success","error","info","spinner","isJsonMode","BASE","POLL_INTERVAL_MS","POLL_TIMEOUT_MS","pollUntilActive","deadline","Date","now","Promise","r","setTimeout","data","path","method","status","connectCmd","description","option","action","opts","statusSp","statusData","stop","process","exit","storeId","answer","prompt","type","name","message","validate","v","trim","length","sp","body","platform","shopify","url","authorizationUrl","authorization_url","polling","active","err_","statusCmd","console","log","JSON","stringify","errorMessage","lastFullSync","lastAlignmentSync","fullSyncCmd","alignmentSyncCmd","counts","syncedCounts","table","count","Object","entries","alignCmsCmd","disconnectCmd","confirmed","default","ecomCommand","addCommand"],"sources":["../../../src/commands/ecom.ts"],"sourcesContent":["import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport open from 'open';\nimport { wixRequest } from '../utils/wixApi';\nimport { success, error, info, spinner, isJsonMode } from '../utils/print';\n\nconst BASE = '/_api/ecom-integrations/v1/ecom-integrations';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\ninterface InitiateOAuthResponse {\n authorizationUrl?: string;\n authorization_url?: string;\n}\n\ninterface ConnectionStatusResponse {\n status?: string;\n platformMetadata?: Record<string, string>;\n lastFullSync?: string;\n lastAlignmentSync?: string;\n errorMessage?: string;\n}\n\ninterface SyncResponse {\n status?: string;\n syncedCounts?: Record<string, number>;\n}\n\n// ── connect ───────────────────────────────────────────────────────────────────\n\nconst POLL_INTERVAL_MS = 3000;\nconst POLL_TIMEOUT_MS = 120_000;\n\nasync function pollUntilActive(): Promise<boolean> {\n const deadline = Date.now() + POLL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n try {\n const data = await wixRequest<ConnectionStatusResponse>({\n path: `${BASE}/connection-status`,\n method: 'GET',\n });\n if (data.status === 'ACTIVE') {\n return true;\n }\n } catch {\n // ignore transient errors and keep polling\n }\n }\n return false;\n}\n\nconst connectCmd = new Command('connect')\n .description('Connect a Shopify store via OAuth2 (opens browser)')\n .option('--store-id <id>', 'Shopify store slug (e.g. mystore)')\n .action(async (opts: { storeId?: string }) => {\n const statusSp = spinner('Checking connection status...');\n try {\n const statusData = await wixRequest<ConnectionStatusResponse>({\n path: `${BASE}/connection-status`,\n method: 'GET',\n });\n statusSp.stop();\n if (statusData.status === 'ACTIVE') {\n error(\n 'Already connected. Use `web5 ecom disconnect` first to reconnect.',\n );\n process.exit(1);\n }\n } catch {\n statusSp.stop();\n // not connected yet, proceed\n }\n\n let storeId = opts.storeId;\n\n if (!storeId) {\n const answer = await inquirer.prompt<{ storeId: string }>([\n {\n type: 'input',\n name: 'storeId',\n message: 'Shopify store slug (e.g. mystore):',\n validate: (v: string) =>\n v.trim().length > 0 || 'Store ID is required',\n },\n ]);\n storeId = answer.storeId.trim();\n }\n\n const sp = spinner('Initiating Shopify OAuth...');\n try {\n const data = await wixRequest<InitiateOAuthResponse>({\n path: `${BASE}/shopify-oauth/initiate`,\n method: 'POST',\n body: {\n platform: 'SHOPIFY',\n shopify: { storeId },\n },\n });\n sp.stop();\n\n const url = data.authorizationUrl ?? data.authorization_url;\n if (!url) {\n error('No authorization URL returned by the server.');\n process.exit(1);\n }\n\n info(`Authorization URL: ${url}`);\n await open(url);\n info('Browser opened — complete the Shopify authorization...');\n\n const polling = spinner('Waiting for connection to become active...');\n const active = await pollUntilActive();\n polling.stop();\n\n if (active) {\n success('Connected! Your Shopify store is now active.');\n } else {\n error(\n 'Timed out waiting for the connection to become active. Run `web5 ecom status` to check.',\n );\n process.exit(1);\n }\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── status ────────────────────────────────────────────────────────────────────\n\nconst statusCmd = new Command('status')\n .description('Show the current ecom provider connection status')\n .action(async () => {\n const sp = spinner('Fetching connection status...');\n try {\n const data = await wixRequest<ConnectionStatusResponse>({\n path: `${BASE}/connection-status`,\n method: 'GET',\n });\n sp.stop();\n\n if (isJsonMode()) {\n console.log(JSON.stringify(data));\n return;\n }\n\n const status = data.status ?? 'UNKNOWN';\n\n if (status === 'UNKNOWN') {\n info('Status: not connected');\n return;\n }\n\n if (status === 'ACTIVE') {\n success(`Status: ${status}`);\n } else {\n error(`Status: ${status}`);\n if (data.errorMessage) {\n info(`Error: ${data.errorMessage}`);\n }\n }\n\n if (data.lastFullSync) {\n info(`Last full sync: ${data.lastFullSync}`);\n } else {\n info('Last full sync: never');\n }\n\n if (data.lastAlignmentSync) {\n info(`Last alignment: ${data.lastAlignmentSync}`);\n } else {\n info('Last alignment: never');\n }\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── full-sync ─────────────────────────────────────────────────────────────────\n\nconst fullSyncCmd = new Command('full-sync')\n .description('Trigger a full sync from the ecom provider into CMS')\n .action(async () => {\n const sp = spinner('Running full sync...');\n try {\n const data = await wixRequest<SyncResponse>({\n path: `${BASE}/full-sync`,\n method: 'POST',\n body: {},\n });\n sp.stop();\n success(data.status ?? 'Full sync triggered');\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── alignment-sync ────────────────────────────────────────────────────────────\n\nconst alignmentSyncCmd = new Command('alignment-sync')\n .description('Run an alignment sync to catch any missed webhook updates')\n .action(async () => {\n const sp = spinner('Running alignment sync...');\n try {\n const data = await wixRequest<SyncResponse>({\n path: `${BASE}/alignment-sync`,\n method: 'POST',\n body: {},\n });\n sp.stop();\n success(data.status ?? 'Alignment sync complete');\n\n const counts = data.syncedCounts ?? {};\n for (const [table, count] of Object.entries(counts)) {\n info(` ${table}: ${count}`);\n }\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── align-cms ─────────────────────────────────────────────────────────────────\n\nconst alignCmsCmd = new Command('align-cms')\n .description('Align CMS collections with the ecom provider schema')\n .action(async () => {\n const sp = spinner('Aligning CMS collections...');\n try {\n await wixRequest({\n path: `${BASE}/align-cms-collections`,\n method: 'POST',\n body: {},\n });\n sp.stop();\n success('CMS collections aligned');\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── disconnect ────────────────────────────────────────────────────────────────\n\nconst disconnectCmd = new Command('disconnect')\n .description('Disconnect from the ecom provider')\n .action(async () => {\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message: 'Are you sure you want to disconnect from the ecom provider?',\n default: false,\n },\n ]);\n\n if (!confirmed) {\n info('Disconnect cancelled.');\n return;\n }\n\n const sp = spinner('Disconnecting...');\n try {\n await wixRequest({\n path: `${BASE}/disconnect`,\n method: 'POST',\n body: {},\n });\n sp.stop();\n success('Disconnected from ecom provider');\n } catch (err_) {\n sp.stop();\n error((err_ as Error).message);\n process.exit(1);\n }\n });\n\n// ── root ecom command ─────────────────────────────────────────────────────────\n\nexport const ecomCommand = new Command('ecom')\n .description('Manage ecom provider integrations')\n .addCommand(connectCmd)\n .addCommand(statusCmd)\n .addCommand(fullSyncCmd)\n .addCommand(alignmentSyncCmd)\n .addCommand(alignCmsCmd)\n .addCommand(disconnectCmd);\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Command","readline","execSync","inquirer","wixRequest","isJsonMode","findProjectRoot","readConfig","writeConfig","copyToClipboard","text","cmd","process","platform","undefined","input","promptCopyToClipboard","rl","createInterface","stdin","output","stdout","Promise","resolve","question","close","console","log","promptForType","type","prompt","name","message","choices","value","getOrCreateClientId","_createData$oAuthApp","queryData","path","method","body","apps","oAuthApps","existing","find","app","id","createData","oAuthApp","application_type","Error","embedCommand","description","option","action","opts","root","cwd","config","clientId","embedScript","JSON","stringify","embedCode","clipboard","isTTY","err","error","exit"],"sources":["../../../src/commands/embed.ts"],"sourcesContent":["import { Command } from 'commander';\nimport * as readline from 'readline';\nimport { execSync } from 'child_process';\nimport inquirer from 'inquirer';\nimport { wixRequest } from '../utils/wixApi';\nimport { isJsonMode } from '../utils/print';\nimport { findProjectRoot, readConfig, writeConfig } from '../utils/project';\n\nfunction copyToClipboard(text: string): void {\n const cmd =\n process.platform === 'win32'\n ? `echo ${text} | clip`\n : process.platform === 'darwin'\n ? 'pbcopy'\n : 'xclip -selection clipboard';\n\n execSync(\n process.platform === 'win32' ? `echo ${text} | clip` : cmd,\n process.platform === 'win32' ? undefined : { input: text },\n );\n}\n\nasync function promptCopyToClipboard(text: string): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question('\\nPress Enter to copy to clipboard...', () => {\n rl.close();\n copyToClipboard(text);\n console.log('Copied to clipboard.');\n resolve();\n });\n });\n}\n\ntype EmbedType = 'script' | 'react';\n\ninterface OAuthApp {\n id: string;\n name: string;\n}\n\ninterface QueryResponse {\n oAuthApps?: OAuthApp[];\n}\n\ninterface CreateResponse {\n oAuthApp?: OAuthApp;\n}\n\nasync function promptForType(): Promise<EmbedType> {\n const { type } = await inquirer.prompt<{ type: EmbedType }>([\n {\n type: 'list',\n name: 'type',\n message: 'Select embed type:',\n choices: [\n { name: 'Script tag', value: 'script' },\n { name: 'React component', value: 'react' },\n ],\n },\n ]);\n return type;\n}\n\nasync function getOrCreateClientId(): Promise<string> {\n console.log('Searching for client ID...');\n\n const queryData = await wixRequest<QueryResponse>({\n path: '/oauth-app/v1/oauth-apps/query',\n method: 'POST',\n body: {},\n });\n\n const apps = queryData.oAuthApps ?? [];\n const existing = apps.find((app) => app.name === 'web5');\n\n if (existing) {\n console.log(`Found client ID: ${existing.id}`);\n return existing.id;\n }\n\n console.log('Client ID not found, creating...');\n\n const createData = await wixRequest<CreateResponse>({\n path: '/oauth-app/v1/oauth-apps',\n method: 'POST',\n body: { oAuthApp: { name: 'web5', application_type: 'WEB_APP' } },\n });\n\n const id = createData.oAuthApp?.id;\n if (!id) {\n throw new Error('Failed to create OAuth app — no ID returned');\n }\n\n console.log(`Client ID created: ${id}`);\n return id;\n}\n\nexport const embedCommand = new Command('embed')\n .description('Generate embed code for a Web5 component')\n .option('--type <type>', 'Embed type: script or react')\n .option('--client-id <id>'
|
|
1
|
+
{"version":3,"names":["Command","readline","execSync","inquirer","wixRequest","isJsonMode","findProjectRoot","readConfig","writeConfig","copyToClipboard","text","cmd","process","platform","undefined","input","promptCopyToClipboard","rl","createInterface","stdin","output","stdout","Promise","resolve","question","close","console","log","promptForType","type","prompt","name","message","choices","value","getOrCreateClientId","_createData$oAuthApp","queryData","path","method","body","apps","oAuthApps","existing","find","app","id","createData","oAuthApp","application_type","Error","embedCommand","description","option","action","opts","root","cwd","config","clientId","embedScript","JSON","stringify","embedCode","clipboard","isTTY","err","error","exit"],"sources":["../../../src/commands/embed.ts"],"sourcesContent":["import { Command } from 'commander';\nimport * as readline from 'readline';\nimport { execSync } from 'child_process';\nimport inquirer from 'inquirer';\nimport { wixRequest } from '../utils/wixApi';\nimport { isJsonMode } from '../utils/print';\nimport { findProjectRoot, readConfig, writeConfig } from '../utils/project';\n\nfunction copyToClipboard(text: string): void {\n const cmd =\n process.platform === 'win32'\n ? `echo ${text} | clip`\n : process.platform === 'darwin'\n ? 'pbcopy'\n : 'xclip -selection clipboard';\n\n execSync(\n process.platform === 'win32' ? `echo ${text} | clip` : cmd,\n process.platform === 'win32' ? undefined : { input: text },\n );\n}\n\nasync function promptCopyToClipboard(text: string): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question('\\nPress Enter to copy to clipboard...', () => {\n rl.close();\n copyToClipboard(text);\n console.log('Copied to clipboard.');\n resolve();\n });\n });\n}\n\ntype EmbedType = 'script' | 'react';\n\ninterface OAuthApp {\n id: string;\n name: string;\n}\n\ninterface QueryResponse {\n oAuthApps?: OAuthApp[];\n}\n\ninterface CreateResponse {\n oAuthApp?: OAuthApp;\n}\n\nasync function promptForType(): Promise<EmbedType> {\n const { type } = await inquirer.prompt<{ type: EmbedType }>([\n {\n type: 'list',\n name: 'type',\n message: 'Select embed type:',\n choices: [\n { name: 'Script tag', value: 'script' },\n { name: 'React component', value: 'react' },\n ],\n },\n ]);\n return type;\n}\n\nasync function getOrCreateClientId(): Promise<string> {\n console.log('Searching for client ID...');\n\n const queryData = await wixRequest<QueryResponse>({\n path: '/oauth-app/v1/oauth-apps/query',\n method: 'POST',\n body: {},\n });\n\n const apps = queryData.oAuthApps ?? [];\n const existing = apps.find((app) => app.name === 'web5');\n\n if (existing) {\n console.log(`Found client ID: ${existing.id}`);\n return existing.id;\n }\n\n console.log('Client ID not found, creating...');\n\n const createData = await wixRequest<CreateResponse>({\n path: '/oauth-app/v1/oauth-apps',\n method: 'POST',\n body: { oAuthApp: { name: 'web5', application_type: 'WEB_APP' } },\n });\n\n const id = createData.oAuthApp?.id;\n if (!id) {\n throw new Error('Failed to create OAuth app — no ID returned');\n }\n\n console.log(`Client ID created: ${id}`);\n return id;\n}\n\nexport const embedCommand = new Command('embed')\n .description('Generate embed code for a Web5 component')\n .option('--type <type>', 'Embed type: script or react')\n .option(\n '--client-id <id>',\n 'Use this client ID instead of fetching from the API',\n )\n .option('--no-clipboard', 'Print to stdout only — skip the clipboard prompt')\n .action(\n async (opts: { type?: string; clientId?: string; clipboard: boolean }) => {\n try {\n const type: EmbedType =\n (opts.type as EmbedType) ?? (await promptForType());\n\n if (type === 'react') {\n console.log('no react for now');\n return;\n }\n\n const root = findProjectRoot(process.cwd());\n const config = root ? readConfig(root) : null;\n\n const clientId =\n opts.clientId ??\n (config?.clientId || undefined) ??\n (await getOrCreateClientId());\n\n if (root && config && config.clientId !== clientId) {\n writeConfig(root, { ...config, clientId });\n }\n\n const embedScript = `<script src=\"https://www.wix.com/embed/v1/component.js\" data-client-id=\"${clientId}\"></script>`;\n\n if (isJsonMode()) {\n console.log(\n JSON.stringify({ type, clientId, embedCode: embedScript }),\n );\n return;\n }\n\n console.log('\\nEmbed script:\\n');\n console.log(embedScript);\n\n if (opts.clipboard !== false && process.stdout.isTTY) {\n await promptCopyToClipboard(embedScript);\n }\n } catch (err) {\n console.error('Error:', (err as Error).message);\n process.exit(1);\n }\n },\n );\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,WAAW;AACnC,OAAO,KAAKC,QAAQ,MAAM,UAAU;AACpC,SAASC,QAAQ,QAAQ,eAAe;AACxC,OAAOC,QAAQ,MAAM,UAAU;AAC/B,SAASC,UAAU,QAAQ,iBAAiB;AAC5C,SAASC,UAAU,QAAQ,gBAAgB;AAC3C,SAASC,eAAe,EAAEC,UAAU,EAAEC,WAAW,QAAQ,kBAAkB;AAE3E,SAASC,eAAeA,CAACC,IAAY,EAAQ;EAC3C,MAAMC,GAAG,GACPC,OAAO,CAACC,QAAQ,KAAK,OAAO,GACxB,QAAQH,IAAI,SAAS,GACrBE,OAAO,CAACC,QAAQ,KAAK,QAAQ,GAC7B,QAAQ,GACR,4BAA4B;EAElCX,QAAQ,CACNU,OAAO,CAACC,QAAQ,KAAK,OAAO,GAAG,QAAQH,IAAI,SAAS,GAAGC,GAAG,EAC1DC,OAAO,CAACC,QAAQ,KAAK,OAAO,GAAGC,SAAS,GAAG;IAAEC,KAAK,EAAEL;EAAK,CAC3D,CAAC;AACH;AAEA,eAAeM,qBAAqBA,CAACN,IAAY,EAAiB;EAChE,MAAMO,EAAE,GAAGhB,QAAQ,CAACiB,eAAe,CAAC;IAClCH,KAAK,EAAEH,OAAO,CAACO,KAAK;IACpBC,MAAM,EAAER,OAAO,CAACS;EAClB,CAAC,CAAC;EACF,OAAO,IAAIC,OAAO,CAAEC,OAAO,IAAK;IAC9BN,EAAE,CAACO,QAAQ,CAAC,uCAAuC,EAAE,MAAM;MACzDP,EAAE,CAACQ,KAAK,CAAC,CAAC;MACVhB,eAAe,CAACC,IAAI,CAAC;MACrBgB,OAAO,CAACC,GAAG,CAAC,sBAAsB,CAAC;MACnCJ,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;EACJ,CAAC,CAAC;AACJ;AAiBA,eAAeK,aAAaA,CAAA,EAAuB;EACjD,MAAM;IAAEC;EAAK,CAAC,GAAG,MAAM1B,QAAQ,CAAC2B,MAAM,CAAsB,CAC1D;IACED,IAAI,EAAE,MAAM;IACZE,IAAI,EAAE,MAAM;IACZC,OAAO,EAAE,oBAAoB;IAC7BC,OAAO,EAAE,CACP;MAAEF,IAAI,EAAE,YAAY;MAAEG,KAAK,EAAE;IAAS,CAAC,EACvC;MAAEH,IAAI,EAAE,iBAAiB;MAAEG,KAAK,EAAE;IAAQ,CAAC;EAE/C,CAAC,CACF,CAAC;EACF,OAAOL,IAAI;AACb;AAEA,eAAeM,mBAAmBA,CAAA,EAAoB;EAAA,IAAAC,oBAAA;EACpDV,OAAO,CAACC,GAAG,CAAC,4BAA4B,CAAC;EAEzC,MAAMU,SAAS,GAAG,MAAMjC,UAAU,CAAgB;IAChDkC,IAAI,EAAE,gCAAgC;IACtCC,MAAM,EAAE,MAAM;IACdC,IAAI,EAAE,CAAC;EACT,CAAC,CAAC;EAEF,MAAMC,IAAI,GAAGJ,SAAS,CAACK,SAAS,IAAI,EAAE;EACtC,MAAMC,QAAQ,GAAGF,IAAI,CAACG,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACd,IAAI,KAAK,MAAM,CAAC;EAExD,IAAIY,QAAQ,EAAE;IACZjB,OAAO,CAACC,GAAG,CAAC,oBAAoBgB,QAAQ,CAACG,EAAE,EAAE,CAAC;IAC9C,OAAOH,QAAQ,CAACG,EAAE;EACpB;EAEApB,OAAO,CAACC,GAAG,CAAC,kCAAkC,CAAC;EAE/C,MAAMoB,UAAU,GAAG,MAAM3C,UAAU,CAAiB;IAClDkC,IAAI,EAAE,0BAA0B;IAChCC,MAAM,EAAE,MAAM;IACdC,IAAI,EAAE;MAAEQ,QAAQ,EAAE;QAAEjB,IAAI,EAAE,MAAM;QAAEkB,gBAAgB,EAAE;MAAU;IAAE;EAClE,CAAC,CAAC;EAEF,MAAMH,EAAE,IAAAV,oBAAA,GAAGW,UAAU,CAACC,QAAQ,qBAAnBZ,oBAAA,CAAqBU,EAAE;EAClC,IAAI,CAACA,EAAE,EAAE;IACP,MAAM,IAAII,KAAK,CAAC,6CAA6C,CAAC;EAChE;EAEAxB,OAAO,CAACC,GAAG,CAAC,sBAAsBmB,EAAE,EAAE,CAAC;EACvC,OAAOA,EAAE;AACX;AAEA,OAAO,MAAMK,YAAY,GAAG,IAAInD,OAAO,CAAC,OAAO,CAAC,CAC7CoD,WAAW,CAAC,0CAA0C,CAAC,CACvDC,MAAM,CAAC,eAAe,EAAE,6BAA6B,CAAC,CACtDA,MAAM,CACL,kBAAkB,EAClB,qDACF,CAAC,CACAA,MAAM,CAAC,gBAAgB,EAAE,kDAAkD,CAAC,CAC5EC,MAAM,CACL,MAAOC,IAA8D,IAAK;EACxE,IAAI;IACF,MAAM1B,IAAe,GAClB0B,IAAI,CAAC1B,IAAI,KAAmB,MAAMD,aAAa,CAAC,CAAC,CAAC;IAErD,IAAIC,IAAI,KAAK,OAAO,EAAE;MACpBH,OAAO,CAACC,GAAG,CAAC,kBAAkB,CAAC;MAC/B;IACF;IAEA,MAAM6B,IAAI,GAAGlD,eAAe,CAACM,OAAO,CAAC6C,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAMC,MAAM,GAAGF,IAAI,GAAGjD,UAAU,CAACiD,IAAI,CAAC,GAAG,IAAI;IAE7C,MAAMG,QAAQ,GACZJ,IAAI,CAACI,QAAQ,KACZ,CAAAD,MAAM,oBAANA,MAAM,CAAEC,QAAQ,KAAI7C,SAAS,CAAC,KAC9B,MAAMqB,mBAAmB,CAAC,CAAC,CAAC;IAE/B,IAAIqB,IAAI,IAAIE,MAAM,IAAIA,MAAM,CAACC,QAAQ,KAAKA,QAAQ,EAAE;MAClDnD,WAAW,CAACgD,IAAI,EAAE;QAAE,GAAGE,MAAM;QAAEC;MAAS,CAAC,CAAC;IAC5C;IAEA,MAAMC,WAAW,GAAG,2EAA2ED,QAAQ,aAAa;IAEpH,IAAItD,UAAU,CAAC,CAAC,EAAE;MAChBqB,OAAO,CAACC,GAAG,CACTkC,IAAI,CAACC,SAAS,CAAC;QAAEjC,IAAI;QAAE8B,QAAQ;QAAEI,SAAS,EAAEH;MAAY,CAAC,CAC3D,CAAC;MACD;IACF;IAEAlC,OAAO,CAACC,GAAG,CAAC,mBAAmB,CAAC;IAChCD,OAAO,CAACC,GAAG,CAACiC,WAAW,CAAC;IAExB,IAAIL,IAAI,CAACS,SAAS,KAAK,KAAK,IAAIpD,OAAO,CAACS,MAAM,CAAC4C,KAAK,EAAE;MACpD,MAAMjD,qBAAqB,CAAC4C,WAAW,CAAC;IAC1C;EACF,CAAC,CAAC,OAAOM,GAAG,EAAE;IACZxC,OAAO,CAACyC,KAAK,CAAC,QAAQ,EAAGD,GAAG,CAAWlC,OAAO,CAAC;IAC/CpB,OAAO,CAACwD,IAAI,CAAC,CAAC,CAAC;EACjB;AACF,CACF,CAAC","ignoreList":[]}
|
|
@@ -6,6 +6,8 @@ import { readFile, cp } from 'fs/promises';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { success, error, info, warn } from '../utils/print';
|
|
8
8
|
import { atomicWrite, ensureDir } from '../utils/fs';
|
|
9
|
+
import { isAuthenticated, getToken } from '../auth';
|
|
10
|
+
import { promptSiteSelection } from '../auth/deviceFlow';
|
|
9
11
|
const DEFAULTS_DIR = path.join(__dirname, '../../../defaults');
|
|
10
12
|
function printBanner() {
|
|
11
13
|
const logo = ['██╗ ██╗ ███████╗ ██████╗ ███████╗', '██║ ██║ ██╔════╝ ██╔══██╗ ██╔════╝', '██║ █╗ ██║ █████╗ ██████╔╝ ███████╗', '██║███╗██║ ██╔══╝ ██╔══██╗ ╚════██║', '╚███╔███╔╝ ███████╗ ██████╔╝ ███████║', ' ╚══╝╚══╝ ╚══════╝ ╚═════╝ ╚══════╝'];
|
|
@@ -73,8 +75,13 @@ async function resolveString(flag, isTTY, question, opts) {
|
|
|
73
75
|
const answers = await inquirer.prompt(question);
|
|
74
76
|
return answers.value ?? opts.defaultValue ?? '';
|
|
75
77
|
}
|
|
76
|
-
export const initCommand = new Command('init').description('Scaffold a new Web5 client component library').option('--mode <mode>', 'scaffold mode: defaults or scratch', 'defaults').option('--name <name>', 'npm package name (e.g. @wix/my-components)').option('--display-name <displayName>', 'human-readable display name').option('--dir <dir>', 'output directory (default: derived from package name)').action(async opts => {
|
|
78
|
+
export const initCommand = new Command('init').description('Scaffold a new Web5 client component library').option('--mode <mode>', 'scaffold mode: defaults or scratch', 'defaults').option('--name <name>', 'npm package name (e.g. @wix/my-components)').option('--display-name <displayName>', 'human-readable display name').option('--dir <dir>', 'output directory (default: derived from package name)').option('--msid <msid>', 'Wix site ID to bind this project to').action(async opts => {
|
|
77
79
|
try {
|
|
80
|
+
const authed = await isAuthenticated();
|
|
81
|
+
if (!authed) {
|
|
82
|
+
error('You must be logged in. Run `web5 login` first.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
78
85
|
printBanner();
|
|
79
86
|
const existing = findExistingConfig(process.cwd());
|
|
80
87
|
if (existing) {
|
|
@@ -98,6 +105,28 @@ export const initCommand = new Command('init').description('Scaffold a new Web5
|
|
|
98
105
|
const stem = name.split('/').pop();
|
|
99
106
|
const displayName = opts.displayName ?? stem.replace(/-/g, ' ');
|
|
100
107
|
const dir = opts.dir ?? stem;
|
|
108
|
+
let msid;
|
|
109
|
+
if (opts.msid) {
|
|
110
|
+
msid = opts.msid;
|
|
111
|
+
} else if (isTTY) {
|
|
112
|
+
const token = await getToken();
|
|
113
|
+
msid = await promptSiteSelection(token);
|
|
114
|
+
} else {
|
|
115
|
+
error('--msid is required in non-interactive mode');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
let platformType;
|
|
119
|
+
if (isTTY) {
|
|
120
|
+
const answers = await inquirer.prompt([{
|
|
121
|
+
type: 'list',
|
|
122
|
+
name: 'value',
|
|
123
|
+
message: 'Platform type:',
|
|
124
|
+
choices: ['Content', 'Ecommerce']
|
|
125
|
+
}]);
|
|
126
|
+
platformType = answers.value;
|
|
127
|
+
} else {
|
|
128
|
+
platformType = 'Content';
|
|
129
|
+
}
|
|
101
130
|
const outDir = path.resolve(process.cwd(), dir);
|
|
102
131
|
if (fs.existsSync(outDir) && fs.readdirSync(outDir).length > 0) {
|
|
103
132
|
warn(`Directory ${outDir} already exists and is not empty`);
|
|
@@ -106,11 +135,13 @@ export const initCommand = new Command('init').description('Scaffold a new Web5
|
|
|
106
135
|
void mode;
|
|
107
136
|
const subs = {
|
|
108
137
|
NAME: name,
|
|
109
|
-
DISPLAY_NAME: displayName
|
|
138
|
+
DISPLAY_NAME: displayName,
|
|
139
|
+
MSID: msid,
|
|
140
|
+
PLATFORM_TYPE: platformType
|
|
110
141
|
};
|
|
111
142
|
|
|
112
143
|
// ── Root config files ─────────────────────────────────────────────────
|
|
113
|
-
await copyDefault('web5.config.json', path.join(outDir, 'web5.config.json'), subs);
|
|
144
|
+
await copyDefault('.web5.config.json', path.join(outDir, 'web5.config.json'), subs);
|
|
114
145
|
await copyDefault('package.template.json', path.join(outDir, 'package.json'), subs);
|
|
115
146
|
await copyDefault('tsconfig.json', path.join(outDir, 'tsconfig.json'));
|
|
116
147
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Command","inquirer","path","fs","readFile","cp","chalk","success","error","info","warn","atomicWrite","ensureDir","DEFAULTS_DIR","join","__dirname","printBanner","logo","console","log","line","cyan","dim","copyDefault","srcRelative","destAbsolute","substitutions","srcPath","content","token","value","Object","entries","replaceAll","copyDefaultTree","filter","recursive","findExistingConfig","startDir","current","parent","dirname","candidate","existsSync","resolveString","flag","isTTY","question","opts","defaultValue","undefined","exitMsg","process","exit","answers","prompt","initCommand","description","option","action","existing","cwd","Boolean","stdin","mode","name","type","message","validate","v","trim","length","stem","split","pop","displayName","replace","dir","outDir","resolve","readdirSync","subs","NAME","DISPLAY_NAME","skill","folder","componentDir","err_","Error","String"],"sources":["../../../src/commands/init.ts"],"sourcesContent":["import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { readFile, cp } from 'fs/promises';\nimport chalk from 'chalk';\nimport { success, error, info, warn } from '../utils/print';\nimport { atomicWrite, ensureDir } from '../utils/fs';\n\nconst DEFAULTS_DIR = path.join(__dirname, '../../../defaults');\n\nfunction printBanner(): void {\n const logo = [\n '██╗ ██╗ ███████╗ ██████╗ ███████╗',\n '██║ ██║ ██╔════╝ ██╔══██╗ ██╔════╝',\n '██║ █╗ ██║ █████╗ ██████╔╝ ███████╗',\n '██║███╗██║ ██╔══╝ ██╔══██╗ ╚════██║',\n '╚███╔███╔╝ ███████╗ ██████╔╝ ███████║',\n ' ╚══╝╚══╝ ╚══════╝ ╚═════╝ ╚══════╝',\n ];\n console.log('');\n for (const line of logo) {\n console.log(chalk.cyan(line));\n }\n console.log('');\n console.log(chalk.dim(' Build AI-powered client components for the Wix platform.'));\n console.log(chalk.dim(' Define sections, actions, and AI instructions —'));\n console.log(chalk.dim(' the platform interprets user intent and delivers personalized experiences.'));\n console.log('');\n}\n\ntype Mode = 'defaults' | 'scratch';\n\ninterface InitOptions {\n mode?: Mode;\n name?: string;\n displayName?: string;\n dir?: string;\n}\n\nasync function copyDefault(\n srcRelative: string,\n destAbsolute: string,\n substitutions: Record<string, string> = {},\n): Promise<void> {\n const srcPath = path.join(DEFAULTS_DIR, srcRelative);\n let content = await readFile(srcPath, 'utf8');\n for (const [token, value] of Object.entries(substitutions)) {\n content = content.replaceAll(`{{${token}}}`, value);\n }\n await atomicWrite(destAbsolute, content);\n}\n\nasync function copyDefaultTree(\n srcRelative: string,\n destAbsolute: string,\n filter?: (src: string, dest: string) => boolean,\n): Promise<void> {\n const srcPath = path.join(DEFAULTS_DIR, srcRelative);\n await cp(srcPath, destAbsolute, { recursive: true, filter });\n}\n\nfunction findExistingConfig(startDir: string): string | null {\n let current = startDir;\n let parent = path.dirname(current);\n while (current !== parent) {\n const candidate = path.join(current, 'web5.config.json');\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n current = parent;\n parent = path.dirname(current);\n }\n const candidate = path.join(current, 'web5.config.json');\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n return null;\n}\n\nasync function resolveString(\n flag: string | undefined,\n isTTY: boolean,\n question: Parameters<typeof inquirer.prompt>[0],\n opts: { defaultValue?: string; exitMsg?: string } = {},\n): Promise<string> {\n if (flag) {\n return flag;\n }\n if (!isTTY) {\n if (opts.defaultValue !== undefined) {\n return opts.defaultValue;\n }\n if (opts.exitMsg) {\n error(opts.exitMsg);\n }\n process.exit(1);\n }\n const answers = await inquirer.prompt<{ value: string }>(question);\n return answers.value ?? opts.defaultValue ?? '';\n}\n\nexport const initCommand = new Command('init')\n .description('Scaffold a new Web5 client component library')\n .option('--mode <mode>', 'scaffold mode: defaults or scratch', 'defaults')\n .option('--name <name>', 'npm package name (e.g. @wix/my-components)')\n .option('--display-name <displayName>', 'human-readable display name')\n .option(\n '--dir <dir>',\n 'output directory (default: derived from package name)',\n )\n .action(async (opts: InitOptions) => {\n try {\n printBanner();\n\n const existing = findExistingConfig(process.cwd());\n if (existing) {\n warn(`web5.config.json already exists at ${existing}`);\n warn('Proceeding will create a nested project.');\n }\n\n const isTTY = Boolean(process.stdin.isTTY);\n const mode: Mode = opts.mode ?? 'defaults';\n\n // ── Collect: package name ─────────────────────────────────────────────\n const name = await resolveString(\n opts.name,\n isTTY,\n [\n {\n type: 'input',\n name: 'value',\n message: 'Package name (e.g. @wix/my-components):',\n validate: (v: string) =>\n v.trim().length > 0 ? true : 'Package name is required',\n },\n ],\n { exitMsg: '--name is required in non-interactive mode' },\n );\n\n // ── Derive: display name and output directory from package name ───────\n const stem = name.split('/').pop()!;\n const displayName = opts.displayName ?? stem.replace(/-/g, ' ');\n const dir = opts.dir ?? stem;\n\n const outDir = path.resolve(process.cwd(), dir);\n\n if (fs.existsSync(outDir) && fs.readdirSync(outDir).length > 0) {\n warn(`Directory ${outDir} already exists and is not empty`);\n }\n\n info(`Scaffolding ${name} \\u2192 ${outDir}`);\n void mode;\n\n const subs = { NAME: name, DISPLAY_NAME: displayName };\n\n // ── Root config files ─────────────────────────────────────────────────\n await copyDefault(\n 'web5.config.json',\n path.join(outDir, 'web5.config.json'),\n subs,\n );\n await copyDefault(\n 'package.template.json',\n path.join(outDir, 'package.json'),\n subs,\n );\n await copyDefault('tsconfig.json', path.join(outDir, 'tsconfig.json'));\n\n // ── src/ ──────────────────────────────────────────────────────────────\n await copyDefault(\n 'src/index.ts',\n path.join(outDir, 'src', 'index.ts'),\n subs,\n );\n await copyDefault(\n 'src/createRegistry.ts',\n path.join(outDir, 'src', 'createRegistry.ts'),\n );\n await copyDefaultTree(\n 'src/components',\n path.join(outDir, 'src', 'components'),\n );\n await copyDefaultTree(\n '.storybook',\n path.join(outDir, '.storybook'),\n );\n await copyDefault(\n 'src/vite.cdn.config.ts',\n path.join(outDir, 'src', 'vite.cdn.config.ts'),\n );\n // ── src/configuration/ ────────────────────────────────────────────────\n await copyDefault(\n 'src/client.config.ts',\n path.join(outDir, 'src', 'client.config.ts'),\n );\n await copyDefault(\n 'src/configuration/ai/prompt-instructions.yaml',\n path.join(\n outDir,\n 'src',\n 'configuration',\n 'ai',\n 'prompt-instructions.yaml',\n ),\n );\n await copyDefault(\n 'src/configuration/cms/cms-mapping.yaml',\n path.join(outDir, 'src', 'configuration', 'cms', 'cms-mapping.yaml'),\n );\n await copyDefault(\n 'src/configuration/cms/cms-schema.yaml',\n path.join(outDir, 'src', 'configuration', 'cms', 'cms-schema.yaml'),\n );\n\n // ── src/actions/ ──────────────────────────────────────────────────────\n await copyDefault(\n 'src/actions/index.ts',\n path.join(outDir, 'src', 'actions', 'index.ts'),\n );\n await copyDefault(\n 'src/actions/bookDemoAction.ts',\n path.join(outDir, 'src', 'actions', 'bookDemoAction.ts'),\n );\n await copyDefault(\n 'src/actions/book-demo.yaml',\n path.join(outDir, 'src', 'actions', 'book-demo.yaml'),\n );\n await copyDefault(\n 'src/actions/contactAction.ts',\n path.join(outDir, 'src', 'actions', 'contactAction.ts'),\n );\n await copyDefault(\n 'src/actions/contact-action.yaml',\n path.join(outDir, 'src', 'actions', 'contact-action.yaml'),\n );\n\n // ── AGENTS.md ─────────────────────────────────────────────────────────\n await copyDefault('AGENTS.md', path.join(outDir, 'AGENTS.md'), subs);\n\n // ── docs/ ─────────────────────────────────────────────────────────────\n await copyDefault(\n 'docs/architecture.md',\n path.join(outDir, 'docs', 'architecture.md'),\n subs,\n );\n await copyDefault(\n 'docs/api-reference.md',\n path.join(outDir, 'docs', 'api-reference.md'),\n subs,\n );\n\n // ── skills/ ───────────────────────────────────────────────────────────\n for (const skill of [\n 'action-add',\n 'action-remove',\n 'action-update',\n 'section-add',\n 'section-remove',\n 'section-update',\n 'slot-add',\n ]) {\n await copyDefault(\n `skills/${skill}.md`,\n path.join(outDir, 'skills', `${skill}.md`),\n );\n }\n\n // ── Component subdirectories ──────────────────────────────────────────\n for (const folder of ['base', 'slots', 'sections']) {\n const componentDir = path.join(outDir, 'src', 'components', folder);\n await ensureDir(componentDir);\n await atomicWrite(path.join(componentDir, '.gitkeep'), '');\n }\n\n // ── Done ──────────────────────────────────────────────────────────────\n success(`Created ${name}`);\n console.log('');\n info('Next steps:');\n info(` cd ${dir}`);\n info(' npm install');\n } catch (err_) {\n error(err_ instanceof Error ? err_.message : String(err_));\n process.exit(1);\n }\n });\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Command","inquirer","path","fs","readFile","cp","chalk","success","error","info","warn","atomicWrite","ensureDir","isAuthenticated","getToken","promptSiteSelection","DEFAULTS_DIR","join","__dirname","printBanner","logo","console","log","line","cyan","dim","copyDefault","srcRelative","destAbsolute","substitutions","srcPath","content","token","value","Object","entries","replaceAll","copyDefaultTree","filter","recursive","findExistingConfig","startDir","current","parent","dirname","candidate","existsSync","resolveString","flag","isTTY","question","opts","defaultValue","undefined","exitMsg","process","exit","answers","prompt","initCommand","description","option","action","authed","existing","cwd","Boolean","stdin","mode","name","type","message","validate","v","trim","length","stem","split","pop","displayName","replace","dir","msid","platformType","choices","outDir","resolve","readdirSync","subs","NAME","DISPLAY_NAME","MSID","PLATFORM_TYPE","skill","folder","componentDir","err_","Error","String"],"sources":["../../../src/commands/init.ts"],"sourcesContent":["import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { readFile, cp } from 'fs/promises';\nimport chalk from 'chalk';\nimport { success, error, info, warn } from '../utils/print';\nimport { atomicWrite, ensureDir } from '../utils/fs';\nimport { isAuthenticated, getToken } from '../auth';\nimport { promptSiteSelection } from '../auth/deviceFlow';\n\nconst DEFAULTS_DIR = path.join(__dirname, '../../../defaults');\n\nfunction printBanner(): void {\n const logo = [\n '██╗ ██╗ ███████╗ ██████╗ ███████╗',\n '██║ ██║ ██╔════╝ ██╔══██╗ ██╔════╝',\n '██║ █╗ ██║ █████╗ ██████╔╝ ███████╗',\n '██║███╗██║ ██╔══╝ ██╔══██╗ ╚════██║',\n '╚███╔███╔╝ ███████╗ ██████╔╝ ███████║',\n ' ╚══╝╚══╝ ╚══════╝ ╚═════╝ ╚══════╝',\n ];\n console.log('');\n for (const line of logo) {\n console.log(chalk.cyan(line));\n }\n console.log('');\n console.log(\n chalk.dim(' Build AI-powered client components for the Wix platform.'),\n );\n console.log(chalk.dim(' Define sections, actions, and AI instructions —'));\n console.log(\n chalk.dim(\n ' the platform interprets user intent and delivers personalized experiences.',\n ),\n );\n console.log('');\n}\n\ntype Mode = 'defaults' | 'scratch';\n\ninterface InitOptions {\n mode?: Mode;\n name?: string;\n displayName?: string;\n dir?: string;\n msid?: string;\n}\n\nasync function copyDefault(\n srcRelative: string,\n destAbsolute: string,\n substitutions: Record<string, string> = {},\n): Promise<void> {\n const srcPath = path.join(DEFAULTS_DIR, srcRelative);\n let content = await readFile(srcPath, 'utf8');\n for (const [token, value] of Object.entries(substitutions)) {\n content = content.replaceAll(`{{${token}}}`, value);\n }\n await atomicWrite(destAbsolute, content);\n}\n\nasync function copyDefaultTree(\n srcRelative: string,\n destAbsolute: string,\n filter?: (src: string, dest: string) => boolean,\n): Promise<void> {\n const srcPath = path.join(DEFAULTS_DIR, srcRelative);\n await cp(srcPath, destAbsolute, { recursive: true, filter });\n}\n\nfunction findExistingConfig(startDir: string): string | null {\n let current = startDir;\n let parent = path.dirname(current);\n while (current !== parent) {\n const candidate = path.join(current, 'web5.config.json');\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n current = parent;\n parent = path.dirname(current);\n }\n const candidate = path.join(current, 'web5.config.json');\n if (fs.existsSync(candidate)) {\n return candidate;\n }\n return null;\n}\n\nasync function resolveString(\n flag: string | undefined,\n isTTY: boolean,\n question: Parameters<typeof inquirer.prompt>[0],\n opts: { defaultValue?: string; exitMsg?: string } = {},\n): Promise<string> {\n if (flag) {\n return flag;\n }\n if (!isTTY) {\n if (opts.defaultValue !== undefined) {\n return opts.defaultValue;\n }\n if (opts.exitMsg) {\n error(opts.exitMsg);\n }\n process.exit(1);\n }\n const answers = await inquirer.prompt<{ value: string }>(question);\n return answers.value ?? opts.defaultValue ?? '';\n}\n\nexport const initCommand = new Command('init')\n .description('Scaffold a new Web5 client component library')\n .option('--mode <mode>', 'scaffold mode: defaults or scratch', 'defaults')\n .option('--name <name>', 'npm package name (e.g. @wix/my-components)')\n .option('--display-name <displayName>', 'human-readable display name')\n .option(\n '--dir <dir>',\n 'output directory (default: derived from package name)',\n )\n .option('--msid <msid>', 'Wix site ID to bind this project to')\n .action(async (opts: InitOptions) => {\n try {\n const authed = await isAuthenticated();\n if (!authed) {\n error('You must be logged in. Run `web5 login` first.');\n process.exit(1);\n }\n\n printBanner();\n\n const existing = findExistingConfig(process.cwd());\n if (existing) {\n warn(`web5.config.json already exists at ${existing}`);\n warn('Proceeding will create a nested project.');\n }\n\n const isTTY = Boolean(process.stdin.isTTY);\n const mode: Mode = opts.mode ?? 'defaults';\n\n // ── Collect: package name ─────────────────────────────────────────────\n const name = await resolveString(\n opts.name,\n isTTY,\n [\n {\n type: 'input',\n name: 'value',\n message: 'Package name (e.g. @wix/my-components):',\n validate: (v: string) =>\n v.trim().length > 0 ? true : 'Package name is required',\n },\n ],\n { exitMsg: '--name is required in non-interactive mode' },\n );\n\n // ── Derive: display name and output directory from package name ───────\n const stem = name.split('/').pop()!;\n const displayName = opts.displayName ?? stem.replace(/-/g, ' ');\n const dir = opts.dir ?? stem;\n\n let msid: string;\n if (opts.msid) {\n msid = opts.msid;\n } else if (isTTY) {\n const token = await getToken();\n msid = await promptSiteSelection(token!);\n } else {\n error('--msid is required in non-interactive mode');\n process.exit(1);\n }\n\n let platformType: string;\n if (isTTY) {\n const answers = await inquirer.prompt<{ value: string }>([\n {\n type: 'list',\n name: 'value',\n message: 'Platform type:',\n choices: ['Content', 'Ecommerce'],\n },\n ]);\n platformType = answers.value;\n } else {\n platformType = 'Content';\n }\n\n const outDir = path.resolve(process.cwd(), dir);\n\n if (fs.existsSync(outDir) && fs.readdirSync(outDir).length > 0) {\n warn(`Directory ${outDir} already exists and is not empty`);\n }\n\n info(`Scaffolding ${name} \\u2192 ${outDir}`);\n void mode;\n\n const subs = {\n NAME: name,\n DISPLAY_NAME: displayName,\n MSID: msid,\n PLATFORM_TYPE: platformType,\n };\n\n // ── Root config files ─────────────────────────────────────────────────\n await copyDefault(\n '.web5.config.json',\n path.join(outDir, 'web5.config.json'),\n subs,\n );\n await copyDefault(\n 'package.template.json',\n path.join(outDir, 'package.json'),\n subs,\n );\n await copyDefault('tsconfig.json', path.join(outDir, 'tsconfig.json'));\n\n // ── src/ ──────────────────────────────────────────────────────────────\n await copyDefault(\n 'src/index.ts',\n path.join(outDir, 'src', 'index.ts'),\n subs,\n );\n await copyDefault(\n 'src/createRegistry.ts',\n path.join(outDir, 'src', 'createRegistry.ts'),\n );\n await copyDefaultTree(\n 'src/components',\n path.join(outDir, 'src', 'components'),\n );\n await copyDefaultTree('.storybook', path.join(outDir, '.storybook'));\n await copyDefault(\n 'src/vite.cdn.config.ts',\n path.join(outDir, 'src', 'vite.cdn.config.ts'),\n );\n // ── src/configuration/ ────────────────────────────────────────────────\n await copyDefault(\n 'src/client.config.ts',\n path.join(outDir, 'src', 'client.config.ts'),\n );\n await copyDefault(\n 'src/configuration/ai/prompt-instructions.yaml',\n path.join(\n outDir,\n 'src',\n 'configuration',\n 'ai',\n 'prompt-instructions.yaml',\n ),\n );\n await copyDefault(\n 'src/configuration/cms/cms-mapping.yaml',\n path.join(outDir, 'src', 'configuration', 'cms', 'cms-mapping.yaml'),\n );\n await copyDefault(\n 'src/configuration/cms/cms-schema.yaml',\n path.join(outDir, 'src', 'configuration', 'cms', 'cms-schema.yaml'),\n );\n\n // ── src/actions/ ──────────────────────────────────────────────────────\n await copyDefault(\n 'src/actions/index.ts',\n path.join(outDir, 'src', 'actions', 'index.ts'),\n );\n await copyDefault(\n 'src/actions/bookDemoAction.ts',\n path.join(outDir, 'src', 'actions', 'bookDemoAction.ts'),\n );\n await copyDefault(\n 'src/actions/book-demo.yaml',\n path.join(outDir, 'src', 'actions', 'book-demo.yaml'),\n );\n await copyDefault(\n 'src/actions/contactAction.ts',\n path.join(outDir, 'src', 'actions', 'contactAction.ts'),\n );\n await copyDefault(\n 'src/actions/contact-action.yaml',\n path.join(outDir, 'src', 'actions', 'contact-action.yaml'),\n );\n\n // ── AGENTS.md ─────────────────────────────────────────────────────────\n await copyDefault('AGENTS.md', path.join(outDir, 'AGENTS.md'), subs);\n\n // ── docs/ ─────────────────────────────────────────────────────────────\n await copyDefault(\n 'docs/architecture.md',\n path.join(outDir, 'docs', 'architecture.md'),\n subs,\n );\n await copyDefault(\n 'docs/api-reference.md',\n path.join(outDir, 'docs', 'api-reference.md'),\n subs,\n );\n\n // ── skills/ ───────────────────────────────────────────────────────────\n for (const skill of [\n 'action-add',\n 'action-remove',\n 'action-update',\n 'section-add',\n 'section-remove',\n 'section-update',\n 'slot-add',\n ]) {\n await copyDefault(\n `skills/${skill}.md`,\n path.join(outDir, 'skills', `${skill}.md`),\n );\n }\n\n // ── Component subdirectories ──────────────────────────────────────────\n for (const folder of ['base', 'slots', 'sections']) {\n const componentDir = path.join(outDir, 'src', 'components', folder);\n await ensureDir(componentDir);\n await atomicWrite(path.join(componentDir, '.gitkeep'), '');\n }\n\n // ── Done ──────────────────────────────────────────────────────────────\n success(`Created ${name}`);\n console.log('');\n info('Next steps:');\n info(` cd ${dir}`);\n info(' npm install');\n } catch (err_) {\n error(err_ instanceof Error ? err_.message : String(err_));\n process.exit(1);\n }\n });\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,WAAW;AACnC,OAAOC,QAAQ,MAAM,UAAU;AAC/B,OAAO,KAAKC,IAAI,MAAM,MAAM;AAC5B,OAAO,KAAKC,EAAE,MAAM,IAAI;AACxB,SAASC,QAAQ,EAAEC,EAAE,QAAQ,aAAa;AAC1C,OAAOC,KAAK,MAAM,OAAO;AACzB,SAASC,OAAO,EAAEC,KAAK,EAAEC,IAAI,EAAEC,IAAI,QAAQ,gBAAgB;AAC3D,SAASC,WAAW,EAAEC,SAAS,QAAQ,aAAa;AACpD,SAASC,eAAe,EAAEC,QAAQ,QAAQ,SAAS;AACnD,SAASC,mBAAmB,QAAQ,oBAAoB;AAExD,MAAMC,YAAY,GAAGd,IAAI,CAACe,IAAI,CAACC,SAAS,EAAE,mBAAmB,CAAC;AAE9D,SAASC,WAAWA,CAAA,EAAS;EAC3B,MAAMC,IAAI,GAAG,CACX,0CAA0C,EAC1C,0CAA0C,EAC1C,0CAA0C,EAC1C,0CAA0C,EAC1C,0CAA0C,EAC1C,0CAA0C,CAC3C;EACDC,OAAO,CAACC,GAAG,CAAC,EAAE,CAAC;EACf,KAAK,MAAMC,IAAI,IAAIH,IAAI,EAAE;IACvBC,OAAO,CAACC,GAAG,CAAChB,KAAK,CAACkB,IAAI,CAACD,IAAI,CAAC,CAAC;EAC/B;EACAF,OAAO,CAACC,GAAG,CAAC,EAAE,CAAC;EACfD,OAAO,CAACC,GAAG,CACThB,KAAK,CAACmB,GAAG,CAAC,4DAA4D,CACxE,CAAC;EACDJ,OAAO,CAACC,GAAG,CAAChB,KAAK,CAACmB,GAAG,CAAC,mDAAmD,CAAC,CAAC;EAC3EJ,OAAO,CAACC,GAAG,CACThB,KAAK,CAACmB,GAAG,CACP,8EACF,CACF,CAAC;EACDJ,OAAO,CAACC,GAAG,CAAC,EAAE,CAAC;AACjB;AAYA,eAAeI,WAAWA,CACxBC,WAAmB,EACnBC,YAAoB,EACpBC,aAAqC,EACtB;EAAA,IADfA,aAAqC;IAArCA,aAAqC,GAAG,CAAC,CAAC;EAAA;EAE1C,MAAMC,OAAO,GAAG5B,IAAI,CAACe,IAAI,CAACD,YAAY,EAAEW,WAAW,CAAC;EACpD,IAAII,OAAO,GAAG,MAAM3B,QAAQ,CAAC0B,OAAO,EAAE,MAAM,CAAC;EAC7C,KAAK,MAAM,CAACE,KAAK,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACN,aAAa,CAAC,EAAE;IAC1DE,OAAO,GAAGA,OAAO,CAACK,UAAU,CAAC,KAAKJ,KAAK,IAAI,EAAEC,KAAK,CAAC;EACrD;EACA,MAAMtB,WAAW,CAACiB,YAAY,EAAEG,OAAO,CAAC;AAC1C;AAEA,eAAeM,eAAeA,CAC5BV,WAAmB,EACnBC,YAAoB,EACpBU,MAA+C,EAChC;EACf,MAAMR,OAAO,GAAG5B,IAAI,CAACe,IAAI,CAACD,YAAY,EAAEW,WAAW,CAAC;EACpD,MAAMtB,EAAE,CAACyB,OAAO,EAAEF,YAAY,EAAE;IAAEW,SAAS,EAAE,IAAI;IAAED;EAAO,CAAC,CAAC;AAC9D;AAEA,SAASE,kBAAkBA,CAACC,QAAgB,EAAiB;EAC3D,IAAIC,OAAO,GAAGD,QAAQ;EACtB,IAAIE,MAAM,GAAGzC,IAAI,CAAC0C,OAAO,CAACF,OAAO,CAAC;EAClC,OAAOA,OAAO,KAAKC,MAAM,EAAE;IACzB,MAAME,SAAS,GAAG3C,IAAI,CAACe,IAAI,CAACyB,OAAO,EAAE,kBAAkB,CAAC;IACxD,IAAIvC,EAAE,CAAC2C,UAAU,CAACD,SAAS,CAAC,EAAE;MAC5B,OAAOA,SAAS;IAClB;IACAH,OAAO,GAAGC,MAAM;IAChBA,MAAM,GAAGzC,IAAI,CAAC0C,OAAO,CAACF,OAAO,CAAC;EAChC;EACA,MAAMG,SAAS,GAAG3C,IAAI,CAACe,IAAI,CAACyB,OAAO,EAAE,kBAAkB,CAAC;EACxD,IAAIvC,EAAE,CAAC2C,UAAU,CAACD,SAAS,CAAC,EAAE;IAC5B,OAAOA,SAAS;EAClB;EACA,OAAO,IAAI;AACb;AAEA,eAAeE,aAAaA,CAC1BC,IAAwB,EACxBC,KAAc,EACdC,QAA+C,EAC/CC,IAAiD,EAChC;EAAA,IADjBA,IAAiD;IAAjDA,IAAiD,GAAG,CAAC,CAAC;EAAA;EAEtD,IAAIH,IAAI,EAAE;IACR,OAAOA,IAAI;EACb;EACA,IAAI,CAACC,KAAK,EAAE;IACV,IAAIE,IAAI,CAACC,YAAY,KAAKC,SAAS,EAAE;MACnC,OAAOF,IAAI,CAACC,YAAY;IAC1B;IACA,IAAID,IAAI,CAACG,OAAO,EAAE;MAChB9C,KAAK,CAAC2C,IAAI,CAACG,OAAO,CAAC;IACrB;IACAC,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC;EACjB;EACA,MAAMC,OAAO,GAAG,MAAMxD,QAAQ,CAACyD,MAAM,CAAoBR,QAAQ,CAAC;EAClE,OAAOO,OAAO,CAACxB,KAAK,IAAIkB,IAAI,CAACC,YAAY,IAAI,EAAE;AACjD;AAEA,OAAO,MAAMO,WAAW,GAAG,IAAI3D,OAAO,CAAC,MAAM,CAAC,CAC3C4D,WAAW,CAAC,8CAA8C,CAAC,CAC3DC,MAAM,CAAC,eAAe,EAAE,oCAAoC,EAAE,UAAU,CAAC,CACzEA,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC,CACrEA,MAAM,CAAC,8BAA8B,EAAE,6BAA6B,CAAC,CACrEA,MAAM,CACL,aAAa,EACb,uDACF,CAAC,CACAA,MAAM,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAC9DC,MAAM,CAAC,MAAOX,IAAiB,IAAK;EACnC,IAAI;IACF,MAAMY,MAAM,GAAG,MAAMlD,eAAe,CAAC,CAAC;IACtC,IAAI,CAACkD,MAAM,EAAE;MACXvD,KAAK,CAAC,gDAAgD,CAAC;MACvD+C,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC;IACjB;IAEArC,WAAW,CAAC,CAAC;IAEb,MAAM6C,QAAQ,GAAGxB,kBAAkB,CAACe,OAAO,CAACU,GAAG,CAAC,CAAC,CAAC;IAClD,IAAID,QAAQ,EAAE;MACZtD,IAAI,CAAC,sCAAsCsD,QAAQ,EAAE,CAAC;MACtDtD,IAAI,CAAC,0CAA0C,CAAC;IAClD;IAEA,MAAMuC,KAAK,GAAGiB,OAAO,CAACX,OAAO,CAACY,KAAK,CAAClB,KAAK,CAAC;IAC1C,MAAMmB,IAAU,GAAGjB,IAAI,CAACiB,IAAI,IAAI,UAAU;;IAE1C;IACA,MAAMC,IAAI,GAAG,MAAMtB,aAAa,CAC9BI,IAAI,CAACkB,IAAI,EACTpB,KAAK,EACL,CACE;MACEqB,IAAI,EAAE,OAAO;MACbD,IAAI,EAAE,OAAO;MACbE,OAAO,EAAE,yCAAyC;MAClDC,QAAQ,EAAGC,CAAS,IAClBA,CAAC,CAACC,IAAI,CAAC,CAAC,CAACC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG;IACjC,CAAC,CACF,EACD;MAAErB,OAAO,EAAE;IAA6C,CAC1D,CAAC;;IAED;IACA,MAAMsB,IAAI,GAAGP,IAAI,CAACQ,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAE;IACnC,MAAMC,WAAW,GAAG5B,IAAI,CAAC4B,WAAW,IAAIH,IAAI,CAACI,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;IAC/D,MAAMC,GAAG,GAAG9B,IAAI,CAAC8B,GAAG,IAAIL,IAAI;IAE5B,IAAIM,IAAY;IAChB,IAAI/B,IAAI,CAAC+B,IAAI,EAAE;MACbA,IAAI,GAAG/B,IAAI,CAAC+B,IAAI;IAClB,CAAC,MAAM,IAAIjC,KAAK,EAAE;MAChB,MAAMjB,KAAK,GAAG,MAAMlB,QAAQ,CAAC,CAAC;MAC9BoE,IAAI,GAAG,MAAMnE,mBAAmB,CAACiB,KAAM,CAAC;IAC1C,CAAC,MAAM;MACLxB,KAAK,CAAC,4CAA4C,CAAC;MACnD+C,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC;IACjB;IAEA,IAAI2B,YAAoB;IACxB,IAAIlC,KAAK,EAAE;MACT,MAAMQ,OAAO,GAAG,MAAMxD,QAAQ,CAACyD,MAAM,CAAoB,CACvD;QACEY,IAAI,EAAE,MAAM;QACZD,IAAI,EAAE,OAAO;QACbE,OAAO,EAAE,gBAAgB;QACzBa,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW;MAClC,CAAC,CACF,CAAC;MACFD,YAAY,GAAG1B,OAAO,CAACxB,KAAK;IAC9B,CAAC,MAAM;MACLkD,YAAY,GAAG,SAAS;IAC1B;IAEA,MAAME,MAAM,GAAGnF,IAAI,CAACoF,OAAO,CAAC/B,OAAO,CAACU,GAAG,CAAC,CAAC,EAAEgB,GAAG,CAAC;IAE/C,IAAI9E,EAAE,CAAC2C,UAAU,CAACuC,MAAM,CAAC,IAAIlF,EAAE,CAACoF,WAAW,CAACF,MAAM,CAAC,CAACV,MAAM,GAAG,CAAC,EAAE;MAC9DjE,IAAI,CAAC,aAAa2E,MAAM,kCAAkC,CAAC;IAC7D;IAEA5E,IAAI,CAAC,eAAe4D,IAAI,WAAWgB,MAAM,EAAE,CAAC;IAC5C,KAAKjB,IAAI;IAET,MAAMoB,IAAI,GAAG;MACXC,IAAI,EAAEpB,IAAI;MACVqB,YAAY,EAAEX,WAAW;MACzBY,IAAI,EAAET,IAAI;MACVU,aAAa,EAAET;IACjB,CAAC;;IAED;IACA,MAAMzD,WAAW,CACf,mBAAmB,EACnBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,kBAAkB,CAAC,EACrCG,IACF,CAAC;IACD,MAAM9D,WAAW,CACf,uBAAuB,EACvBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,cAAc,CAAC,EACjCG,IACF,CAAC;IACD,MAAM9D,WAAW,CAAC,eAAe,EAAExB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,eAAe,CAAC,CAAC;;IAEtE;IACA,MAAM3D,WAAW,CACf,cAAc,EACdxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,EACpCG,IACF,CAAC;IACD,MAAM9D,WAAW,CACf,uBAAuB,EACvBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,mBAAmB,CAC9C,CAAC;IACD,MAAMhD,eAAe,CACnB,gBAAgB,EAChBnC,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,YAAY,CACvC,CAAC;IACD,MAAMhD,eAAe,CAAC,YAAY,EAAEnC,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM3D,WAAW,CACf,wBAAwB,EACxBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,oBAAoB,CAC/C,CAAC;IACD;IACA,MAAM3D,WAAW,CACf,sBAAsB,EACtBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAC7C,CAAC;IACD,MAAM3D,WAAW,CACf,+CAA+C,EAC/CxB,IAAI,CAACe,IAAI,CACPoE,MAAM,EACN,KAAK,EACL,eAAe,EACf,IAAI,EACJ,0BACF,CACF,CAAC;IACD,MAAM3D,WAAW,CACf,wCAAwC,EACxCxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,kBAAkB,CACrE,CAAC;IACD,MAAM3D,WAAW,CACf,uCAAuC,EACvCxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,CACpE,CAAC;;IAED;IACA,MAAM3D,WAAW,CACf,sBAAsB,EACtBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAChD,CAAC;IACD,MAAM3D,WAAW,CACf,+BAA+B,EAC/BxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,CACzD,CAAC;IACD,MAAM3D,WAAW,CACf,4BAA4B,EAC5BxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,CACtD,CAAC;IACD,MAAM3D,WAAW,CACf,8BAA8B,EAC9BxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,kBAAkB,CACxD,CAAC;IACD,MAAM3D,WAAW,CACf,iCAAiC,EACjCxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,qBAAqB,CAC3D,CAAC;;IAED;IACA,MAAM3D,WAAW,CAAC,WAAW,EAAExB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,WAAW,CAAC,EAAEG,IAAI,CAAC;;IAEpE;IACA,MAAM9D,WAAW,CACf,sBAAsB,EACtBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAC5CG,IACF,CAAC;IACD,MAAM9D,WAAW,CACf,uBAAuB,EACvBxB,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAC7CG,IACF,CAAC;;IAED;IACA,KAAK,MAAMK,KAAK,IAAI,CAClB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,CACX,EAAE;MACD,MAAMnE,WAAW,CACf,UAAUmE,KAAK,KAAK,EACpB3F,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,QAAQ,EAAE,GAAGQ,KAAK,KAAK,CAC3C,CAAC;IACH;;IAEA;IACA,KAAK,MAAMC,MAAM,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;MAClD,MAAMC,YAAY,GAAG7F,IAAI,CAACe,IAAI,CAACoE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAES,MAAM,CAAC;MACnE,MAAMlF,SAAS,CAACmF,YAAY,CAAC;MAC7B,MAAMpF,WAAW,CAACT,IAAI,CAACe,IAAI,CAAC8E,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;IAC5D;;IAEA;IACAxF,OAAO,CAAC,WAAW8D,IAAI,EAAE,CAAC;IAC1BhD,OAAO,CAACC,GAAG,CAAC,EAAE,CAAC;IACfb,IAAI,CAAC,aAAa,CAAC;IACnBA,IAAI,CAAC,QAAQwE,GAAG,EAAE,CAAC;IACnBxE,IAAI,CAAC,eAAe,CAAC;EACvB,CAAC,CAAC,OAAOuF,IAAI,EAAE;IACbxF,KAAK,CAACwF,IAAI,YAAYC,KAAK,GAAGD,IAAI,CAACzB,OAAO,GAAG2B,MAAM,CAACF,IAAI,CAAC,CAAC;IAC1DzC,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -7,7 +7,10 @@ import ora from 'ora';
|
|
|
7
7
|
import { wixRequest } from '../utils/wixApi';
|
|
8
8
|
import { success, error, spinner } from '../utils/print';
|
|
9
9
|
const BASE = '/web5/instructions/cli';
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
// ── Display helpers ───────────────────────────────────────────────────────────
|
|
11
14
|
|
|
12
15
|
const BOX_W = 66;
|
|
13
16
|
function printHeader(title) {
|
|
@@ -26,17 +29,124 @@ function truncate(text, max) {
|
|
|
26
29
|
if (max === void 0) {
|
|
27
30
|
max = 48;
|
|
28
31
|
}
|
|
29
|
-
const clean = text.replace(/\n/g, ' ').trim();
|
|
32
|
+
const clean = (text ?? '').replace(/\n/g, ' ').trim();
|
|
30
33
|
return clean.length > max ? `${clean.slice(0, max - 1)}…` : clean;
|
|
31
34
|
}
|
|
35
|
+
function printInstructionContent(inst) {
|
|
36
|
+
// Intents
|
|
37
|
+
console.log(chalk.bold(' Intents'));
|
|
38
|
+
console.log(chalk.dim(' ' + '─'.repeat(40)));
|
|
39
|
+
const intents = inst.intents ?? {};
|
|
40
|
+
if (Object.keys(intents).length === 0) {
|
|
41
|
+
console.log(chalk.dim(' (none)'));
|
|
42
|
+
} else {
|
|
43
|
+
for (const [k, v] of Object.entries(intents)) {
|
|
44
|
+
console.log(` ${chalk.cyan(k)}: ${v}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
console.log();
|
|
48
|
+
|
|
49
|
+
// Semantics
|
|
50
|
+
console.log(chalk.bold(' Semantics'));
|
|
51
|
+
console.log(chalk.dim(' ' + '─'.repeat(40)));
|
|
52
|
+
const semantics = inst.semantics ?? {};
|
|
53
|
+
if (Object.keys(semantics).length === 0) {
|
|
54
|
+
console.log(chalk.dim(' (none)'));
|
|
55
|
+
} else {
|
|
56
|
+
for (const [k, v] of Object.entries(semantics)) {
|
|
57
|
+
console.log(` ${chalk.cyan(k)}: ${v}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
console.log();
|
|
61
|
+
|
|
62
|
+
// Actions
|
|
63
|
+
console.log(chalk.bold(' Actions'));
|
|
64
|
+
console.log(chalk.dim(' ' + '─'.repeat(40)));
|
|
65
|
+
const actions = inst.actions ?? [];
|
|
66
|
+
if (actions.length === 0) {
|
|
67
|
+
console.log(chalk.dim(' (none)'));
|
|
68
|
+
} else {
|
|
69
|
+
for (const action of actions) {
|
|
70
|
+
const desc = action.description ? chalk.dim(` — ${action.description}`) : '';
|
|
71
|
+
console.log(` ${chalk.cyan('• ' + action.name)}${desc}`);
|
|
72
|
+
for (const p of action.params ?? []) {
|
|
73
|
+
const preview = p.values.length > 0 ? chalk.dim(` [${p.values.slice(0, 3).join(', ')}${p.values.length > 3 ? ', …' : ''}]`) : '';
|
|
74
|
+
const optTag = p.optional ? chalk.dim(' (optional)') : '';
|
|
75
|
+
console.log(` ${p.param}${preview}${optTag}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
console.log();
|
|
80
|
+
|
|
81
|
+
// Free-text instruction
|
|
82
|
+
console.log(chalk.bold(' Instruction'));
|
|
83
|
+
console.log(chalk.dim(' ' + '─'.repeat(40)));
|
|
84
|
+
console.log(` ${inst.content ?? ''}`);
|
|
85
|
+
console.log();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ── Diff helper ───────────────────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
function diffLines(aStr, bStr) {
|
|
91
|
+
const aLines = aStr.split('\n');
|
|
92
|
+
const bLines = bStr.split('\n');
|
|
93
|
+
const out = [];
|
|
94
|
+
const maxLen = Math.max(aLines.length, bLines.length);
|
|
95
|
+
for (let i = 0; i < maxLen; i++) {
|
|
96
|
+
const aLine = i < aLines.length ? aLines[i] : null;
|
|
97
|
+
const bLine = i < bLines.length ? bLines[i] : null;
|
|
98
|
+
if (aLine === bLine) {
|
|
99
|
+
out.push(` ${aLine ?? ''}`);
|
|
100
|
+
} else {
|
|
101
|
+
if (aLine !== null) {
|
|
102
|
+
out.push(chalk.red(`- ${aLine}`));
|
|
103
|
+
}
|
|
104
|
+
if (bLine !== null) {
|
|
105
|
+
out.push(chalk.green(`+ ${bLine}`));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return out.join('\n');
|
|
110
|
+
}
|
|
111
|
+
function formatKV(obj) {
|
|
112
|
+
return Object.entries(obj ?? {}).map(_ref => {
|
|
113
|
+
let [k, v] = _ref;
|
|
114
|
+
return `${k}: ${v}`;
|
|
115
|
+
}).join('\n');
|
|
116
|
+
}
|
|
117
|
+
function formatActions(actions) {
|
|
118
|
+
return (actions ?? []).map(a => {
|
|
119
|
+
const params = (a.params ?? []).map(p => ` ${p.param}: [${p.values.join(', ')}]`).join('\n');
|
|
120
|
+
const header = a.description ? `${a.name} — ${a.description}` : a.name;
|
|
121
|
+
return params ? `${header}\n${params}` : header;
|
|
122
|
+
}).join('\n\n');
|
|
123
|
+
}
|
|
124
|
+
function diffInstructions(a, b, v1, v2) {
|
|
125
|
+
const out = [chalk.dim(`--- v${v1}`), chalk.dim(`+++ v${v2}`), ''];
|
|
126
|
+
const sections = [['Intents', formatKV(a.intents), formatKV(b.intents)], ['Semantics', formatKV(a.semantics), formatKV(b.semantics)], ['Actions', formatActions(a.actions), formatActions(b.actions)], ['Instruction', a.content ?? '', b.content ?? '']];
|
|
127
|
+
for (const [label, aStr, bStr] of sections) {
|
|
128
|
+
out.push(chalk.bold(`── ${label} ──`));
|
|
129
|
+
if (aStr === bStr) {
|
|
130
|
+
out.push(chalk.dim(' (no changes)'));
|
|
131
|
+
} else {
|
|
132
|
+
out.push(diffLines(aStr, bStr));
|
|
133
|
+
}
|
|
134
|
+
out.push('');
|
|
135
|
+
}
|
|
136
|
+
return out.join('\n');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── Wizard ────────────────────────────────────────────────────────────────────
|
|
140
|
+
|
|
32
141
|
async function showInstructionDetail(version, instructions) {
|
|
33
142
|
const inst = instructions.find(i => i.version === version);
|
|
34
|
-
if (!inst)
|
|
143
|
+
if (!inst) {
|
|
144
|
+
return 'back';
|
|
145
|
+
}
|
|
35
146
|
console.clear();
|
|
36
147
|
const activeLabel = inst.active ? chalk.green(' (active)') : '';
|
|
37
148
|
printHeader(`📋 AI Instructions ❯ Version ${version}${activeLabel}`);
|
|
38
|
-
|
|
39
|
-
console.log(`\n${inst.content}\n`);
|
|
149
|
+
printInstructionContent(inst);
|
|
40
150
|
const choices = [{
|
|
41
151
|
name: ` ${chalk.dim('← Back')}`,
|
|
42
152
|
value: 'back'
|
|
@@ -77,8 +187,6 @@ async function runInstructionsWizard() {
|
|
|
77
187
|
console.log(chalk.dim('\nBye.\n'));
|
|
78
188
|
process.exit(0);
|
|
79
189
|
});
|
|
80
|
-
|
|
81
|
-
// Fetch once, keep local copy so activation updates in-memory
|
|
82
190
|
const sp = ora('Fetching instructions…').start();
|
|
83
191
|
let instructions = [];
|
|
84
192
|
try {
|
|
@@ -100,7 +208,7 @@ async function runInstructionsWizard() {
|
|
|
100
208
|
console.log(chalk.yellow('No instructions found.'));
|
|
101
209
|
process.exit(0);
|
|
102
210
|
}
|
|
103
|
-
|
|
211
|
+
const running = true;
|
|
104
212
|
while (running) {
|
|
105
213
|
console.clear();
|
|
106
214
|
printHeader(`📋 AI Instructions ${chalk.dim(`${instructions.length} versions`)}`);
|
|
@@ -125,9 +233,13 @@ async function runInstructionsWizard() {
|
|
|
125
233
|
choices,
|
|
126
234
|
pageSize: 12
|
|
127
235
|
}]);
|
|
128
|
-
if (version === '__exit__')
|
|
236
|
+
if (version === '__exit__') {
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
129
239
|
const result = await showInstructionDetail(version, instructions);
|
|
130
|
-
if (result === 'exit')
|
|
240
|
+
if (result === 'exit') {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
131
243
|
if (result === 'refetch') {
|
|
132
244
|
try {
|
|
133
245
|
const data = await wixRequest({
|
|
@@ -148,27 +260,7 @@ async function runInstructionsWizard() {
|
|
|
148
260
|
process.exit(0);
|
|
149
261
|
}
|
|
150
262
|
|
|
151
|
-
// ──
|
|
152
|
-
|
|
153
|
-
function diffContent(a, b, v1, v2) {
|
|
154
|
-
const aLines = a.split('\n');
|
|
155
|
-
const bLines = b.split('\n');
|
|
156
|
-
const out = [chalk.dim(`--- v${v1}`), chalk.dim(`+++ v${v2}`), ''];
|
|
157
|
-
const maxLen = Math.max(aLines.length, bLines.length);
|
|
158
|
-
for (let i = 0; i < maxLen; i++) {
|
|
159
|
-
const aLine = i < aLines.length ? aLines[i] : null;
|
|
160
|
-
const bLine = i < bLines.length ? bLines[i] : null;
|
|
161
|
-
if (aLine === bLine) {
|
|
162
|
-
out.push(` ${aLine ?? ''}`);
|
|
163
|
-
} else {
|
|
164
|
-
if (aLine !== null) out.push(chalk.red(`- ${aLine}`));
|
|
165
|
-
if (bLine !== null) out.push(chalk.green(`+ ${bLine}`));
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return out.join('\n');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ── Subcommands ───────────────────────────────────────────────────────────
|
|
263
|
+
// ── Subcommands ───────────────────────────────────────────────────────────────
|
|
172
264
|
|
|
173
265
|
const getActiveCmd = new Command('get-active').description('Get the currently active instruction').action(async () => {
|
|
174
266
|
const sp = spinner('Fetching active instruction...');
|
|
@@ -177,13 +269,10 @@ const getActiveCmd = new Command('get-active').description('Get the currently ac
|
|
|
177
269
|
path: `${BASE}/active`
|
|
178
270
|
});
|
|
179
271
|
sp.stop();
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
content
|
|
183
|
-
} = data.instruction;
|
|
184
|
-
console.log(chalk.bold(`Version ${version}`));
|
|
272
|
+
const inst = data.instruction;
|
|
273
|
+
console.log(chalk.bold(`Version ${inst.version}`));
|
|
185
274
|
console.log();
|
|
186
|
-
|
|
275
|
+
printInstructionContent(inst);
|
|
187
276
|
} catch (err_) {
|
|
188
277
|
sp.stop();
|
|
189
278
|
error(err_.message);
|
|
@@ -206,28 +295,34 @@ const listCmd = new Command('list').description('List all instructions').option(
|
|
|
206
295
|
items = items.filter(i => i.active);
|
|
207
296
|
}
|
|
208
297
|
if (opts.format === 'json') {
|
|
209
|
-
const view = items.map(
|
|
298
|
+
const view = items.map(_ref2 => {
|
|
210
299
|
let {
|
|
211
300
|
version,
|
|
212
301
|
active,
|
|
302
|
+
intents,
|
|
303
|
+
semantics,
|
|
304
|
+
actions,
|
|
213
305
|
content
|
|
214
|
-
} =
|
|
306
|
+
} = _ref2;
|
|
215
307
|
return {
|
|
216
308
|
version,
|
|
217
309
|
active: active ?? false,
|
|
310
|
+
intents,
|
|
311
|
+
semantics,
|
|
312
|
+
actions,
|
|
218
313
|
content
|
|
219
314
|
};
|
|
220
315
|
});
|
|
221
316
|
console.log(JSON.stringify(view, null, 2));
|
|
222
317
|
} else {
|
|
223
|
-
const header = `${'Version'.padEnd(10)}${'Active'.padEnd(10)}
|
|
318
|
+
const header = `${'Version'.padEnd(10)}${'Active'.padEnd(10)}Instruction`;
|
|
224
319
|
console.log(chalk.bold(header));
|
|
225
320
|
console.log('─'.repeat(60));
|
|
226
321
|
for (const i of items) {
|
|
227
322
|
const ver = `v${i.version}`.padEnd(10);
|
|
228
323
|
const active = (i.active ? '✓' : '').padEnd(10);
|
|
229
|
-
const
|
|
230
|
-
console.log(`${chalk.cyan(ver)}${chalk.green(active)}${
|
|
324
|
+
const preview = truncate(i.content, 40);
|
|
325
|
+
console.log(`${chalk.cyan(ver)}${chalk.green(active)}${preview}`);
|
|
231
326
|
}
|
|
232
327
|
}
|
|
233
328
|
} catch (err_) {
|
|
@@ -258,20 +353,17 @@ const getCmd = new Command('get').description('Get an instruction by version num
|
|
|
258
353
|
path: `${BASE}/by-version/${version}`
|
|
259
354
|
});
|
|
260
355
|
sp.stop();
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
content
|
|
264
|
-
} = data.instruction;
|
|
265
|
-
console.log(chalk.bold(`Version ${ver}`));
|
|
356
|
+
const inst = data.instruction;
|
|
357
|
+
console.log(chalk.bold(`Version ${inst.version}`));
|
|
266
358
|
console.log();
|
|
267
|
-
|
|
359
|
+
printInstructionContent(inst);
|
|
268
360
|
} catch (err_) {
|
|
269
361
|
sp.stop();
|
|
270
362
|
error(err_.message);
|
|
271
363
|
process.exit(1);
|
|
272
364
|
}
|
|
273
365
|
});
|
|
274
|
-
const diffCmd = new Command('diff').description('Show
|
|
366
|
+
const diffCmd = new Command('diff').description('Show diff between two instruction versions across all sections').argument('<v1>', 'First version number').argument('<v2>', 'Second version number').action(async (v1, v2) => {
|
|
275
367
|
const sp = spinner(`Fetching versions ${v1} and ${v2}...`);
|
|
276
368
|
try {
|
|
277
369
|
const [d1, d2] = await Promise.all([wixRequest({
|
|
@@ -280,22 +372,29 @@ const diffCmd = new Command('diff').description('Show line-by-line diff between
|
|
|
280
372
|
path: `${BASE}/by-version/${v2}`
|
|
281
373
|
})]);
|
|
282
374
|
sp.stop();
|
|
283
|
-
console.log(
|
|
375
|
+
console.log(diffInstructions(d1.instruction, d2.instruction, v1, v2));
|
|
284
376
|
} catch (err_) {
|
|
285
377
|
sp.stop();
|
|
286
378
|
error(err_.message);
|
|
287
379
|
process.exit(1);
|
|
288
380
|
}
|
|
289
381
|
});
|
|
290
|
-
const exportCmd = new Command('export').description('Export an instruction version to a local file').requiredOption('--version <v>', 'Version number to export').requiredOption('--output <file>', 'Output file path').action(async opts => {
|
|
382
|
+
const exportCmd = new Command('export').description('Export an instruction version to a local file').requiredOption('--version <v>', 'Version number to export').requiredOption('--output <file>', 'Output file path (.json)').action(async opts => {
|
|
291
383
|
const sp = spinner(`Fetching instruction version ${opts.version}...`);
|
|
292
384
|
try {
|
|
293
385
|
const data = await wixRequest({
|
|
294
386
|
path: `${BASE}/by-version/${opts.version}`
|
|
295
387
|
});
|
|
296
388
|
sp.stop();
|
|
389
|
+
const inst = data.instruction;
|
|
390
|
+
const outContent = JSON.stringify({
|
|
391
|
+
intents: inst.intents,
|
|
392
|
+
semantics: inst.semantics,
|
|
393
|
+
actions: inst.actions,
|
|
394
|
+
content: inst.content
|
|
395
|
+
}, null, 2);
|
|
297
396
|
const outPath = path.resolve(opts.output);
|
|
298
|
-
fs.writeFileSync(outPath,
|
|
397
|
+
fs.writeFileSync(outPath, outContent, 'utf8');
|
|
299
398
|
success(`Exported version ${opts.version} to ${outPath}`);
|
|
300
399
|
} catch (err_) {
|
|
301
400
|
sp.stop();
|
|
@@ -339,7 +438,7 @@ const rollbackCmd = new Command('rollback').description('Re-activate the version
|
|
|
339
438
|
}
|
|
340
439
|
});
|
|
341
440
|
|
|
342
|
-
// ── Command export
|
|
441
|
+
// ── Command export ────────────────────────────────────────────────────────────
|
|
343
442
|
|
|
344
443
|
const wizardCmd = new Command('wizard').description('Open the interactive TUI to browse and activate instruction versions').action(async () => {
|
|
345
444
|
try {
|