@autofleet/cli 2.20.0-ofek.0 → 2.20.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.
@@ -1 +1 @@
1
- {"version":3,"file":"git-autofleet.js","names":["asyncSpawn","versionType","path","packageName: string | undefined"],"sources":["../bin/git-autofleet.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { basename, sep } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport parseArgs from './utils/parser.js';\nimport asyncSpawn from './utils/asyncSpawn.js';\nimport { endWithError } from './utils/index.js';\nimport { promptForConfirmation, safeSelect } from './utils/inquirer.js';\nimport { getChangesOfFile, getCurrentBranch, getGitPath } from './utils/git.js';\nimport { readdir } from 'node:fs/promises';\n\nconst preReleaseVersionTypes = ['premajor', 'preminor', 'prepatch', 'prerelease'] as const;\nconst versionTypes = ['major', 'minor', 'patch', ...preReleaseVersionTypes] as const;\n\nconst COMMANDS = {\n bumpVersion: `[${versionTypes.join('|')}]`,\n openPR: 'Opens github UI for creating a PR from the current branch.',\n releaseBeta: 'Bumps version if needed, and publishes a beta release to NPM.',\n};\nconst isCommand = (c: string): c is keyof typeof COMMANDS => Object.keys(COMMANDS).includes(c);\nconst bumpVersion = async ({ versionType, packageName, preReleaseId = '' }: { versionType: string; packageName?: string; preReleaseId?: string; }): Promise<string> => {\n const { stdout: newVersion } = await asyncSpawn('npm', ['version', versionType, '--no-git-tag-version', '--preid', preReleaseId], {\n print: false,\n cwd: packageName ? `.${sep}packages${sep}${packageName}` : undefined,\n });\n await asyncSpawn('git', ['add', 'package*'], { print: false });\n await asyncSpawn('git', ['commit', '-m', `${versionType} version: ${newVersion}`], { print: false });\n console.log(`Created commit for version bump: ${versionType}. Version is now ${newVersion}`);\n return newVersion;\n};\nconst getCurrentPackageVersionPrereleaseId = async (packageName: string | undefined) => {\n const path = await getGitPath();\n const packageJsonPath = packageName ? `${path}${sep}packages${sep}${packageName}` : path;\n const { default: { version } } = await import(`${packageJsonPath}${sep}package.json`, { assert: { type: 'json' }, with: { type: 'json' } }) as { default: { version: string; }; };\n\n return version.replace(/\\d+\\.\\d+\\.\\d+(?:-beta-([\\w]+)?\\.\\d+)?/, '$1');\n};\n\nconst { positionals, help } = parseArgs({\n strict: true,\n binName: 'git autofleet',\n allowPositionals: true,\n options: {},\n commands: COMMANDS,\n});\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nconst [command, versionType, positionalPackageName] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nif (command === 'openPR') {\n const [gitPath, currentBranch] = await Promise.all([getGitPath(), getCurrentBranch()]);\n const repoName = basename(gitPath);\n const url = `https://github.com/Autofleet/${repoName}/compare/${currentBranch}?expand=1`;\n await asyncSpawn('open', [url], { print: false });\n process.exit(0);\n}\n\nasync function getPackageName(message: string) {\n const gitPath = await getGitPath();\n const repoName = gitPath.split(sep).pop();\n const isAutorepo = repoName === 'autorepo';\n let packageName: string | undefined = positionalPackageName as string | undefined;\n\n if (isAutorepo) {\n const packageNames = (await readdir(`${gitPath}${sep}packages`)).filter(name => !name.startsWith('.'));\n if (packageName) {\n if (!packageNames.includes(packageName)) {\n endWithError(new Error(`Package name ${packageName} does not exist in autorepo packages`), help);\n }\n } else {\n packageName = await safeSelect({\n message,\n choices: packageNames.map(type => ({ name: type, value: type })),\n });\n }\n if (!packageName) {\n endWithError(new Error('No package name provided, exiting...'), help);\n }\n }\n return packageName;\n}\n\nif (command === 'bumpVersion') {\n const packageName = await getPackageName('Which package do you want to bump?');\n const finalVersionType = versionType || await safeSelect({\n message: 'Which version type do you want to bump?',\n choices: (command === 'bumpVersion' ? versionTypes : preReleaseVersionTypes).map(type => ({ name: type, value: type })),\n });\n if (!finalVersionType) {\n endWithError(new Error(`Must explicitly define version type.\\n\\tVersion type can be one of: ${versionTypes.join(', ')}`), help);\n }\n const currentBranch = await getCurrentBranch();\n if (['main', 'master'].includes(currentBranch)) {\n const shouldProceed = await promptForConfirmation('Are you sure you want to bump version on main branch?');\n if (!shouldProceed) {\n process.exit(0);\n }\n }\n await bumpVersion({ versionType: finalVersionType, packageName });\n process.exit(0);\n}\n\nif (command === 'releaseBeta') {\n const packageName = await getPackageName('Which package do you want to release?');\n if (versionType && !preReleaseVersionTypes.includes(versionType as typeof preReleaseVersionTypes[number])) {\n endWithError(new Error(`Invalid version type: ${versionType}\\n\\tVersion must be a prerelease type. (${preReleaseVersionTypes.join(', ')})`), help);\n }\n const currentBranch = await getCurrentBranch();\n if (['main', 'master'].includes(currentBranch)) {\n endWithError(new Error('Cannot release beta from main branch'), help);\n }\n const cwd = packageName ? `.${sep}packages${sep}${packageName}` : undefined;\n const packageChanges = await getChangesOfFile(packageName ? `.${sep}packages${sep}${packageName}${sep}package.json` : 'package.json');\n const versionChanged = packageChanges.split('\\n').some(line => /^\\+\\s*\"version\":\\s*\"\\d+\\.\\d+\\.\\d+(?:-(?:[\\w-]+\\.)?\\d+)?\",/.test(line));\n const shouldReBump = !versionChanged || await promptForConfirmation('Version already bumped on branch. Should version be re-bumped?');\n const preReleaseId = shouldReBump && await getCurrentPackageVersionPrereleaseId(packageName);\n const newVersion = shouldReBump && (await bumpVersion({\n versionType: versionType || 'prerelease',\n preReleaseId: `beta-${preReleaseId || randomUUID().split('-')[0]}`,\n packageName,\n }));\n await asyncSpawn('npm', ['run', 'build'], { cwd });\n try {\n await asyncSpawn('npm', ['publish', '--tag', 'beta', '--@autofleet:registry=https://registry.npmjs.org'], { cwd });\n } catch (e) {\n console.error(e);\n endWithError('Failed to publish beta version');\n }\n if (newVersion) {\n console.log(`Published beta version with new version: ${newVersion}`);\n } else {\n const { stdout: previousVersion } = await asyncSpawn('npm', ['info', '.', 'version'], { print: false, cwd });\n console.log(`Published beta version with existing version: ${previousVersion}`);\n }\n process.exit(0);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"git-autofleet.js","names":["asyncSpawn","versionType","path","packageName: string | undefined"],"sources":["../bin/git-autofleet.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { basename, sep } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { readdir } from 'node:fs/promises';\nimport parseArgs from './utils/parser.js';\nimport asyncSpawn from './utils/asyncSpawn.js';\nimport { endWithError } from './utils/index.js';\nimport { promptForConfirmation, safeInput, safeSelect } from './utils/inquirer.js';\nimport { getChangesOfFile, getCurrentBranch, getGitPath } from './utils/git.js';\n\nconst preReleaseVersionTypes = ['premajor', 'preminor', 'prepatch', 'prerelease'] as const;\nconst versionTypes = ['major', 'minor', 'patch', ...preReleaseVersionTypes] as const;\n\nconst COMMANDS = {\n bumpVersion: `[${versionTypes.join('|')}]`,\n openPR: 'Opens github UI for creating a PR from the current branch.',\n releaseBeta: 'Bumps version if needed, and publishes a beta release to NPM registry.',\n};\nconst isCommand = (c: string): c is keyof typeof COMMANDS => Object.keys(COMMANDS).includes(c);\nconst bumpVersion = async ({ versionType, packageName, preReleaseId = '' }: { versionType: string; packageName?: string; preReleaseId?: string; }): Promise<string> => {\n const { stdout: newVersion } = await asyncSpawn('npm', ['version', versionType, '--no-git-tag-version', '--preid', preReleaseId], {\n print: false,\n cwd: packageName ? `.${sep}packages${sep}${packageName}` : undefined,\n });\n await asyncSpawn('git', ['add', 'package*'], { print: false });\n await asyncSpawn('git', ['commit', '-m', `${versionType} version: ${newVersion}`], { print: false });\n console.log(`Created commit for version bump: ${versionType}. Version is now ${newVersion}`);\n return newVersion;\n};\nconst getCurrentPackageVersionPrereleaseId = async (packageName: string | undefined) => {\n const path = await getGitPath();\n const packageJsonPath = packageName ? `${path}${sep}packages${sep}${packageName}` : path;\n const { default: { version } } = await import(`${packageJsonPath}${sep}package.json`, { assert: { type: 'json' }, with: { type: 'json' } }) as { default: { version: string; }; };\n\n return version.replace(/\\d+\\.\\d+\\.\\d+(?:-beta-([\\w]+)?\\.\\d+)?/, '$1');\n};\n\nconst { positionals, help } = parseArgs({\n strict: true,\n binName: 'git autofleet',\n allowPositionals: true,\n options: {},\n commands: COMMANDS,\n});\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nconst [command, versionType, positionalPackageName] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nif (command === 'openPR') {\n const [gitPath, currentBranch] = await Promise.all([getGitPath(), getCurrentBranch()]);\n const repoName = basename(gitPath);\n const url = `https://github.com/Autofleet/${repoName}/compare/${currentBranch}?expand=1`;\n await asyncSpawn('open', [url], { print: false });\n process.exit(0);\n}\n\nasync function getPathIfAutorepo() {\n const gitPath = await getGitPath();\n const repoName = gitPath.split(sep).pop();\n if (repoName === 'autorepo') {\n return gitPath;\n }\n return false;\n}\n\nasync function getPackageName({ message, pathIfAutorepo }: { message: string; pathIfAutorepo?: string | boolean; }) {\n pathIfAutorepo ??= await getPathIfAutorepo();\n let packageName: string | undefined = positionalPackageName as string | undefined;\n\n if (pathIfAutorepo) {\n const packageNames = (await readdir(`${pathIfAutorepo}${sep}packages`)).filter(name => !name.startsWith('.'));\n if (packageName) {\n if (!packageNames.includes(packageName)) {\n endWithError(new Error(`Package name ${packageName} does not exist in autorepo packages`), help);\n }\n } else {\n packageName = await safeSelect({\n message,\n choices: packageNames.map(type => ({ name: type, value: type })),\n });\n }\n if (!packageName) {\n endWithError(new Error('No package name provided, exiting...'), help);\n }\n }\n return packageName;\n}\n\nif (command === 'bumpVersion') {\n const packageName = await getPackageName({ message: 'Which package do you want to bump?' });\n const finalVersionType = versionType || await safeSelect({\n message: 'Which version type do you want to bump?',\n choices: (command === 'bumpVersion' ? versionTypes : preReleaseVersionTypes).map(type => ({ name: type, value: type })),\n });\n if (!finalVersionType) {\n endWithError(new Error(`Must explicitly define version type.\\n\\tVersion type can be one of: ${versionTypes.join(', ')}`), help);\n }\n const currentBranch = await getCurrentBranch();\n if (['main', 'master'].includes(currentBranch)) {\n const shouldProceed = await promptForConfirmation('Are you sure you want to bump version on main branch?');\n if (!shouldProceed) {\n process.exit(0);\n }\n }\n await bumpVersion({ versionType: finalVersionType, packageName });\n process.exit(0);\n}\n\nif (command === 'releaseBeta') {\n const isAutorepo = await getPathIfAutorepo();\n const packageName = await getPackageName({ message: 'Which package do you want to release?', pathIfAutorepo: isAutorepo });\n if (versionType && !preReleaseVersionTypes.includes(versionType as typeof preReleaseVersionTypes[number])) {\n endWithError(new Error(`Invalid version type: ${versionType}\\n\\tVersion must be a prerelease type. (${preReleaseVersionTypes.join(', ')})`), help);\n }\n const currentBranch = await getCurrentBranch();\n if (['main', 'master'].includes(currentBranch)) {\n endWithError(new Error('Cannot release beta from main branch'), help);\n }\n const cwd = packageName ? `.${sep}packages${sep}${packageName}` : undefined;\n const packageChanges = await getChangesOfFile(packageName ? `.${sep}packages${sep}${packageName}${sep}package.json` : 'package.json');\n const versionChanged = packageChanges.split('\\n').some(line => /^\\+\\s*\"version\":\\s*\"\\d+\\.\\d+\\.\\d+(?:-(?:[\\w-]+\\.)?\\d+)?\",/.test(line));\n const shouldReBump = !versionChanged || await promptForConfirmation('Version already bumped on branch. Should version be re-bumped?');\n const preReleaseId = shouldReBump && await getCurrentPackageVersionPrereleaseId(packageName);\n const newVersion = shouldReBump && (await bumpVersion({\n versionType: versionType || 'prerelease',\n preReleaseId: `beta-${preReleaseId || randomUUID().split('-')[0]}`,\n packageName,\n }));\n const pmExecutable = isAutorepo ? 'pnpm' : 'npm';\n await asyncSpawn(pmExecutable, ['run', 'build'], { cwd });\n const otp = await safeInput({ message: 'In case your token requires an OTP, please enter it:' });\n try {\n const args = [\n 'publish',\n '--tag',\n 'beta',\n '--@autofleet:registry=https://registry.npmjs.org',\n ...(otp ? ['--otp', otp] : []),\n ...(isAutorepo ? [`--no-git-checks`] : []),\n ];\n await asyncSpawn(pmExecutable, args, { cwd });\n } catch (e) {\n console.error(e);\n endWithError('Failed to publish beta version');\n }\n if (newVersion) {\n console.log(`Published beta version with new version: ${newVersion}`);\n } else {\n const { stdout: previousVersion } = await asyncSpawn(pmExecutable, ['info', '.', 'version'], { print: false, cwd });\n console.log(`Published beta version with existing version: ${previousVersion}`);\n }\n process.exit(0);\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{S as e,_ as t,a as n,b as r,c as i,d as a,f as o,h as s,i as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h,v as g,x as ee,y as te}from"./utils-DMxGZWe6.js";import{styleText as _}from"node:util";import*as ne from"node:fs";import{spawn as re}from"node:child_process";import{confirm as v}from"@inquirer/prompts";import{mkdir as ie,readFile as y,writeFile as b}from"node:fs/promises";import*as ae from"node:path";import{basename as x,join as S,resolve as C,sep as w}from"node:path";import{randomUUID as oe}from"node:crypto";import{setTimeout as se}from"node:timers/promises";import{cwd as T}from"node:process";import*as E from"node:os";import{EOL as D}from"node:os";const O=`.mirrord`;async function k({makeDir:e=!1}={}){let t=S(await g(),O);return e&&await ie(t,{recursive:!0}),S(t,`mirrord.json`)}async function ce(e){let t=await k({makeDir:!0}),n={feature:{network:{incoming:{mode:`steal`,http_filter:{path_filter:`^(?!/alive)`}},outgoing:!0},fs:`read`,env:!0},target:{namespace:e||oe()},agent:{startup_timeout:120}};return await b(t,JSON.stringify(n,null,2)),{mirrordConfigData:n,mirrordPath:t}}async function le(){try{let e=await y(await k(),{encoding:`utf-8`});return JSON.parse(e||`{}`)?.target?.namespace??``}catch{return``}}function ue(e){process.once(`exit`,e),process.once(`SIGTERM`,e),process.once(`SIGINT`,e)}function A(e){return e&&=e.trim(),e&&(e.startsWith(`'`)&&e.endsWith(`'`)&&(e=e.slice(1,-1)),e)}const j=`livenessProbe`,M=`readinessProbe`,N=e=>`jsonpath='{.spec.template.spec.containers[?(@.name=="worker")].${e}}'`,P=(...e)=>`{"spec": {"template": {"spec": {"containers": [{"name": "worker",${e.map(([e,t])=>`"${e}": ${t}`).join(`,`)}}]}}}}`;var de=async(e,t,n)=>{console.log(`Will now disable health check to allow debugging.`);let[{stdout:i},{stdout:a}]=await Promise.all([r(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,N(j)],{print:!1}),r(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,N(M)],{print:!1})]);i&&=A(i),a&&=A(a),(i||a)&&(await r(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,P([j,`null`],[M,`null`])],{print:!1}),console.log(`Health check disabled, will now start mirrord and run "npm run dev". Make sure to attach a debugger!`));let o=new AbortController;ue(async()=>{globalThis.executedExitHooks||(globalThis.executedExitHooks=!0,o.abort(),(i||a)&&(console.log(`Re-enabling health check.`),await r(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,`'${P([j,i],[M,a])}'`],{print:!1,shell:!0}),console.log(`health check enabled.`)),process.exit(0))});try{await r(`mirrord`,[`exec`,`-t`,`deployment/${n}`,`-n`,t,`--steal`,`npm`,`run`,`dev`],{signal:o.signal})}catch(e){if(e&&typeof e==`object`&&`code`in e&&e.code===`ABORT_ERR`)return;c(e)}},fe=async(e,t)=>{if(await f(e),e===`expManager`||e===`dev1`){let{variationId:e}=await h({variationId:t},[`variationId`]);e!==``&&(await n()===e&&(console.log(`Already connected to simulation with uuid: ${e}, skipping namespace switch...`),process.exit(0)),await r(`kubectl`,[`config`,`set-context`,`--current`,`--namespace=${e}`],{print:!1}),console.log(`Switched to simulation with uuid: ${e} successfully`))}process.exit(0)};async function pe(){try{await r(`telepresence`,[`version`],{print:!1})}catch{c(`Telepresence is not installed. Please install it from:
3
- https://www.telepresence.io/docs/latest/quick-start/`)}}function me(){return s({message:`Do you want to leave the connection or create a new one?`,choices:[{name:`Leave the current connection`,value:`leave`},{name:`Create a new connection`,value:`connect`}],default:`connect`})}async function he(e){await pe();let{cluster:t=``,service:n=``}=e;await f(t);let i=await me();if([`leave`,`connect`].includes(i)||c(`Invalid action, how did you get here? 🤔`),i===`leave`){await r(`telepresence`,[`leave`,n]),console.log(`Disconnected! 👋`);return}let a=e.variationId||await d(),s=e[`local-port`]&&Number.parseInt(e[`local-port`],10)||Number.parseInt(await o()||``,10);await r(`telepresence`,[`connect`,`--namespace=${a}`]),await r(`telepresence`,[`intercept`,n,`--port`,s.toString(),`--env-file=./.env`]),console.log(`Everything is set up! 🚀`),console.log(`You can now access the service at localhost:${s}`),console.log(`You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.`),process.exit(0)}var F=async(e,t,n)=>{n||c(Error(`service is required for exposeService`),t),await r(`kubectl`,[`patch`,`svc`,e,n,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),console.log(`exposed ${n} successfully. the service is now creating an internal load balancer ip to use with vpn`),process.exit(0)},I=async(e,t,n,i,a)=>{let o=Number.parseInt(e[`local-port`]??`5432`,10);Number.isNaN(o)&&c(Error(`if defined, local-port must be a number`),i);let s=`afpass_${n}`,l=`postgres`,u=n.replaceAll(`-`,`_`),d=a?`${a.replaceAll(`-`,`_`)||``}_${u}`:`postgres`,f=`postgres://${l}:${s}@localhost:${o}/${d}?&nickname=var_${n}`;console.log(`Forwarding db to local port ${o}.\naccess the DB at ${f}\nPress ctrl+c to stop.`);let p=` DB_USERNAME=${l}
4
- DB_PASSWORD=${s}
5
- DB_NAME=${a?d:`<service_name>_${u}`}`;console.log(`Generated database environment for local development:
6
- `,p),se(1500).then(()=>r(`open`,[f],{print:!1})).catch(()=>null),await r(`kubectl`,[t,`port-forward`,`svc/p${n}-postgresql`,`${o}:5432`],{print:!1}),process.exit(0)},L=async(e,t,n,i)=>{let a=Number.parseInt(e.port??`8080`,10),o=Number.parseInt(e[`local-port`]??``,10)||a;i||c(Error(`service is required for forwardService`),n),(!a||Number.isNaN(a))&&c(Error(`port is required and must be a numbers`),n),o&&Number.isNaN(o)&&c(Error(`local-port must be a number`),n);let{stdout:s}=await r(`kubectl`,[`get`,`pods`,t,`-l`,`service=${i}`,`-o`,`jsonpath="{.items[0].metadata.name}"`],{print:!1});s&&=s.trim(),s||c(Error(`No pods found for service ${i}`)),s.startsWith(`"`)&&s.endsWith(`"`)&&(s=s.slice(1,-1)),console.log(`Found pod ${s}, serving locally on port ${o} from remote port ${a}.\nPress ctrl+c to stop.`),await r(`kubectl`,[`port-forward`,t,s,`${o}:${a}`],{print:!1}),process.exit(0)},R=async e=>{let{stdout:t}=await r(`kubectl`,[e,`get`,`services`],{print:!1});i(t).forEach(e=>console.log(e)),process.exit(0)},ge=async(e,t)=>{let n=`simulation-cluster-front`;await r(`kubectl`,[`annotate`,e,`service`,n,`cloud.google.com/load-balancer-type-`]),await r(`kubectl`,[`patch`,`svc`,e,n,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),await r(`kubectl`,[`create`,e,`rolebinding`,`admin`,`--clusterrole=cluster-admin`,`--serviceaccount=${t}:default`]),console.log(`Successfully exposed ${n} and added role binding to dispatch simulations`),process.exit(0)},_e=async()=>{let e=e=>[`get`,`secret`,`rabbitmq-default-user`,`-o`,`jsonpath="{.data.${e}}"`],[{stdout:t},{stdout:n}]=await Promise.all([r(`kubectl`,e(`username`),{print:!1}),r(`kubectl`,e(`password`),{print:!1})]);console.log(`username: ${Buffer.from(t,`base64`).toString(`ascii`)}`),console.log(`password: ${Buffer.from(n,`base64`).toString(`ascii`)}`),process.exit(0)},ve=async e=>{let n=await g(),i=n.split(w).pop()===`autorepo`,o;i?(o=await a(n),o||(console.error(`No service name provided, exiting...`),process.exit(1))):o=x(T());let[s,c]=await Promise.all([t(),r(`uname`,[`-m`],{print:!1})]),l=c.stdout.trim(),u=new Date,d=`${u.getHours().toString().padStart(2,`0`)}-${u.getMinutes().toString().padStart(2,`0`)}-${u.getSeconds().toString().padStart(2,`0`)}`,f=`gcr.io/autofleetprod/${o}:${s}-${d}`;console.log(`Building and pushing image ${f}`);let p=l===`x86_64`?[]:[`--platform`,`linux/amd64`],m=i?`apps/${o}${w}Dockerfile`:`Dockerfile`;i&&await r(`npx`,[`nx`,`build`,o]),await r(`docker`,[`build`,`.`,`-f`,m,...p,`-t`,f,`--build-arg`,`NPM_TOKEN=${process.env.NPM_TOKEN}`]),await r(`docker`,[`push`,f]);let{stdout:h}=await r(`kubectl`,[`describe`,`pod`,e,`-l`,`service=${o}`],{print:!1});h.includes(`Init Containers:`)&&await r(`kubectl`,[`patch`,`deployment/${o}`,e,`--patch`,`{"spec": {"template": {"spec": {"initContainers": [{"name": "init","image": "${f}"}]}}}}`]),await r(`kubectl`,[`set`,`image`,`deployment/${o}`,`worker=${f}`,e]),await r(`kubectl`,[`rollout`,`status`,`deployments`,o,e]),process.exit(0)};async function z(e,t,n){let r=C(e,`.env`),i=(await y(r,`utf8`)).split(D),a=`(?<!#\\s*)${t}(?==)`,o=i.find(e=>e.match(a));if(o?.split(`=`).at(-1)===n)return!1;let s=o?i.indexOf(o):-1;return s===-1?i.push(`${t}=${n}`):i.splice(s,1,`${t}=${n}`),await b(r,i.join(D)),!0}var ye=async(e,t,n)=>{let i=`LOCAL_ENV_NAME`,a=`api-gateway-ms`,o=`control-center-ms`,s;s=t.includes(`prod`)?`production`:t===`staging`?`staging`:`simulator-${n}`;let l=await g();x(l)!==`control-center`&&c(Error("The `localDev` command must be run from the control-center repository"));let u=`localhost:8081`;await z(l,`API_GATEWAY_MS_SERVICE_HOST`,u)&&console.log(`Updated .env file to use ${a} IP (${u}).`);let d=`localhost:8085`;await z(l,`CONTROL_CENTER_MS_SERVICE_HOST`,d)&&console.log(`Updated .env file to use ${o} IP (${d}).`),await z(l,i,s)&&console.log(`Updated .env file ${i} to ${s} (used for firebase setup).`);let f=r(`kubectl`,[`port-forward`,e,`svc/${o}`,`8085:80`],{print:!1}),p=r(`kubectl`,[`port-forward`,e,`svc/${a}`,`8081:80`],{print:!1});console.log(`Starting port-forwarding of ${o} to port 8085`),console.log(`Starting port-forwarding of ${a} to port 8081`),console.log(`Press Ctrl+C to stop the port-forwarding processes.`),await Promise.all([f,p])};async function be(e){if(await te(O))return;let t=C(e,`..`,`..`,`.gitignore`),n=(await y(t,`utf8`)).split(`
7
- `).filter(Boolean);n.push(O),await b(t,`${n.join(`
8
- `)}\n`)}var xe=async e=>{let{mirrordConfigData:t,mirrordPath:n}=await ce(e);await be(n),console.log(`Wrote the default mirrord config for the requested variation ID`,{mirrordConfigData:t}),process.exit(0)},Se=async()=>{let e=ae.join(E.tmpdir(),`docker-compose.yml`);ne.writeFileSync(e,`
2
+ import{C as e,S as t,a as n,b as r,c as i,d as a,f as o,g as s,i as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h,v as ee,x as g,y as _}from"./utils-CVOVF4Ra.js";import{styleText as v}from"node:util";import*as te from"node:fs";import y from"node:fs";import{execSync as b,spawn as ne}from"node:child_process";import{confirm as x}from"@inquirer/prompts";import*as S from"node:path";import{basename as C,join as w,resolve as T,sep as re}from"node:path";import{mkdir as ie,readFile as E,writeFile as D}from"node:fs/promises";import{randomUUID as ae}from"node:crypto";import{setTimeout as oe}from"node:timers/promises";import{cwd as O}from"node:process";import*as se from"node:os";import{EOL as k}from"node:os";const A=`.mirrord`;async function j({makeDir:e=!1}={}){let t=w(await _(),A);return e&&await ie(t,{recursive:!0}),w(t,`mirrord.json`)}async function ce(e){let t=await j({makeDir:!0}),n={feature:{network:{incoming:{mode:`steal`,http_filter:{path_filter:`^(?!/alive)`}},outgoing:!0},fs:`read`,env:!0},target:{namespace:e||ae()},agent:{startup_timeout:120}};return await D(t,JSON.stringify(n,null,2)),{mirrordConfigData:n,mirrordPath:t}}async function le(){try{let e=await E(await j(),{encoding:`utf-8`});return JSON.parse(e||`{}`)?.target?.namespace??``}catch{return``}}function ue(e){process.once(`exit`,e),process.once(`SIGTERM`,e),process.once(`SIGINT`,e)}function M(e){return e&&=e.trim(),e&&(e.startsWith(`'`)&&e.endsWith(`'`)&&(e=e.slice(1,-1)),e)}const N=`livenessProbe`,P=`readinessProbe`,F=e=>`jsonpath='{.spec.template.spec.containers[?(@.name=="worker")].${e}}'`,I=(...e)=>`{"spec": {"template": {"spec": {"containers": [{"name": "worker",${e.map(([e,t])=>`"${e}": ${t}`).join(`,`)}}]}}}}`;var de=async(e,t,n)=>{console.log(`Will now disable health check to allow debugging.`);let[{stdout:r},{stdout:i}]=await Promise.all([g(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,F(N)],{print:!1}),g(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,F(P)],{print:!1})]);r&&=M(r),i&&=M(i),(r||i)&&(await g(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,I([N,`null`],[P,`null`])],{print:!1}),console.log(`Health check disabled, will now start mirrord and run "npm run dev". Make sure to attach a debugger!`));let a=new AbortController;ue(async()=>{globalThis.executedExitHooks||(globalThis.executedExitHooks=!0,a.abort(),(r||i)&&(console.log(`Re-enabling health check.`),await g(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,`'${I([N,r],[P,i])}'`],{print:!1,shell:!0}),console.log(`health check enabled.`)),process.exit(0))});try{await g(`mirrord`,[`exec`,`-t`,`deployment/${n}`,`-n`,t,`--steal`,`npm`,`run`,`dev`],{signal:a.signal})}catch(e){if(e&&typeof e==`object`&&`code`in e&&e.code===`ABORT_ERR`)return;c(e)}},fe=async(e,t)=>{if(await f(e),e===`expManager`||e===`dev1`){let{variationId:e}=await h({variationId:t},[`variationId`]);e!==``&&(await n()===e&&(console.log(`Already connected to simulation with uuid: ${e}, skipping namespace switch...`),process.exit(0)),await g(`kubectl`,[`config`,`set-context`,`--current`,`--namespace=${e}`],{print:!1}),console.log(`Switched to simulation with uuid: ${e} successfully`))}process.exit(0)};async function pe(){try{await g(`telepresence`,[`version`],{print:!1})}catch{c(`Telepresence is not installed. Please install it from:
3
+ https://www.telepresence.io/docs/latest/quick-start/`)}}function me(){return s({message:`Do you want to leave the connection or create a new one?`,choices:[{name:`Leave the current connection`,value:`leave`},{name:`Create a new connection`,value:`connect`}],default:`connect`})}async function he(e){await pe();let{cluster:t=``,service:n=``}=e;await f(t);let r=await me();if([`leave`,`connect`].includes(r)||c(`Invalid action, how did you get here? 🤔`),r===`leave`){await g(`telepresence`,[`leave`,n]),console.log(`Disconnected! 👋`);return}let i=e.variationId||await d(),a=e[`local-port`]&&Number.parseInt(e[`local-port`],10)||Number.parseInt(await o()||``,10);await g(`telepresence`,[`connect`,`--namespace=${i}`]),await g(`telepresence`,[`intercept`,n,`--port`,a.toString(),`--env-file=./.env`]),console.log(`Everything is set up! 🚀`),console.log(`You can now access the service at localhost:${a}`),console.log(`You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.`),process.exit(0)}var L=async(e,t,n)=>{n||c(Error(`service is required for exposeService`),t),await g(`kubectl`,[`patch`,`svc`,e,n,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),console.log(`exposed ${n} successfully. the service is now creating an internal load balancer ip to use with vpn`),process.exit(0)},R=async(e,t,n,r,i)=>{let a=Number.parseInt(e[`local-port`]??`5432`,10);Number.isNaN(a)&&c(Error(`if defined, local-port must be a number`),r);let o=`afpass_${n}`,s=`postgres`,l=n.replaceAll(`-`,`_`),u=i?`${i.replaceAll(`-`,`_`)||``}_${l}`:`postgres`,d=`postgres://${s}:${o}@localhost:${a}/${u}?&nickname=var_${n}`;console.log(`Forwarding db to local port ${a}.\naccess the DB at ${d}\nPress ctrl+c to stop.`);let f=` DB_USERNAME=${s}
4
+ DB_PASSWORD=${o}
5
+ DB_NAME=${i?u:`<service_name>_${l}`}`;console.log(`Generated database environment for local development:
6
+ `,f),oe(1500).then(()=>g(`open`,[d],{print:!1})).catch(()=>null),await g(`kubectl`,[t,`port-forward`,`svc/p${n}-postgresql`,`${a}:5432`],{print:!1}),process.exit(0)},ge=async(e,t,n,r)=>{let i=Number.parseInt(e.port??`8080`,10),a=Number.parseInt(e[`local-port`]??``,10)||i;r||c(Error(`service is required for forwardService`),n),(!i||Number.isNaN(i))&&c(Error(`port is required and must be a numbers`),n),a&&Number.isNaN(a)&&c(Error(`local-port must be a number`),n);let{stdout:o}=await g(`kubectl`,[`get`,`pods`,t,`-l`,`service=${r}`,`-o`,`jsonpath="{.items[0].metadata.name}"`],{print:!1});o&&=o.trim(),o||c(Error(`No pods found for service ${r}`)),o.startsWith(`"`)&&o.endsWith(`"`)&&(o=o.slice(1,-1)),console.log(`Found pod ${o}, serving locally on port ${a} from remote port ${i}.\nPress ctrl+c to stop.`),await g(`kubectl`,[`port-forward`,t,o,`${a}:${i}`],{print:!1}),process.exit(0)},_e=async e=>{let{stdout:t}=await g(`kubectl`,[e,`get`,`services`],{print:!1});i(t).forEach(e=>console.log(e)),process.exit(0)},ve=async(e,t)=>{let n=`simulation-cluster-front`;await g(`kubectl`,[`annotate`,e,`service`,n,`cloud.google.com/load-balancer-type-`]),await g(`kubectl`,[`patch`,`svc`,e,n,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),await g(`kubectl`,[`create`,e,`rolebinding`,`admin`,`--clusterrole=cluster-admin`,`--serviceaccount=${t}:default`]),console.log(`Successfully exposed ${n} and added role binding to dispatch simulations`),process.exit(0)},z=async()=>{let e=e=>[`get`,`secret`,`rabbitmq-default-user`,`-o`,`jsonpath="{.data.${e}}"`],[{stdout:t},{stdout:n}]=await Promise.all([g(`kubectl`,e(`username`),{print:!1}),g(`kubectl`,e(`password`),{print:!1})]);console.log(`username: ${Buffer.from(t,`base64`).toString(`ascii`)}`),console.log(`password: ${Buffer.from(n,`base64`).toString(`ascii`)}`),process.exit(0)},ye=async e=>{let t=await _(),n=t.split(re).pop()===`autorepo`,r;n?(r=await a(t),r||(console.error(`No service name provided, exiting...`),process.exit(1))):r=C(O());let[i,o]=await Promise.all([ee(),g(`uname`,[`-m`],{print:!1})]),s=o.stdout.trim(),c=new Date,l=`${c.getHours().toString().padStart(2,`0`)}-${c.getMinutes().toString().padStart(2,`0`)}-${c.getSeconds().toString().padStart(2,`0`)}`,u=`gcr.io/autofleetprod/${r}:${i}-${l}`;console.log(`Building and pushing image ${u}`);let d=s===`x86_64`?[]:[`--platform`,`linux/amd64`],f=[`--secret`,`id=npm_token,env=NPM_TOKEN`],p=[],m=[];if(n){let{stdout:e}=await g(`ls`,[`-1`,`packages`],{print:!1}),n=e.trim().replace(/\n/g,` `),a={APP:r,PACKAGES:n,BRANCH:i},o=`${t}/apps/${r}/project.json`;(JSON.parse(await E(o,`utf-8`)).tags||[]).includes(`elasticsearch`)&&(a.NODE_TLS_REJECT_UNAUTHORIZED=`0`);let s=r.endsWith(`-ms`)?`backend`:`frontend`;s===`frontend`&&(a.API_SOURCE=[`partner-admin`,`web-booker`].includes(r)?`client`:`api`),p=Object.entries(a).flatMap(([e,t])=>[`--build-arg`,`${e}=${t}`]),m=[`--target`,s]}await g(`docker`,[`build`,`.`,`-f`,`Dockerfile`,...m,...d,`-t`,u,...p,...f]),await g(`docker`,[`push`,u]);let{stdout:h}=await g(`kubectl`,[`describe`,`pod`,e,`-l`,`service=${r}`],{print:!1});h.includes(`Init Containers:`)&&await g(`kubectl`,[`patch`,`deployment/${r}`,e,`--patch`,`{"spec": {"template": {"spec": {"initContainers": [{"name": "init","image": "${u}"}]}}}}`]),await g(`kubectl`,[`set`,`image`,`deployment/${r}`,`worker=${u}`,e]),await g(`kubectl`,[`rollout`,`status`,`deployments`,r,e]),process.exit(0)};async function B(e,t,n){let r=T(e,`.env`),i=(await E(r,`utf8`)).split(k),a=`(?<!#\\s*)${t}(?==)`,o=i.find(e=>e.match(a));if(o?.split(`=`).at(-1)===n)return!1;let s=o?i.indexOf(o):-1;return s===-1?i.push(`${t}=${n}`):i.splice(s,1,`${t}=${n}`),await D(r,i.join(k)),!0}var be=async(e,t,n)=>{let r=`LOCAL_ENV_NAME`,i=`api-gateway-ms`,a=`control-center-ms`,o;o=t.toLocaleLowerCase().includes(`prod`)?`production`:t===`staging`?`staging`:`simulator-${n}`;let s=await _();C(s)!==`control-center`&&c(Error("The `localDev` command must be run from the control-center repository"));let l=`localhost:8081`;await B(s,`API_GATEWAY_MS_SERVICE_HOST`,l)&&console.log(`Updated .env file to use ${i} IP (${l}).`);let u=`localhost:8085`;await B(s,`CONTROL_CENTER_MS_SERVICE_HOST`,u)&&console.log(`Updated .env file to use ${a} IP (${u}).`),await B(s,r,o)&&console.log(`Updated .env file ${r} to ${o} (used for firebase setup).`);let d=g(`kubectl`,[`port-forward`,e,`svc/${a}`,`8085:80`],{print:!1}),f=g(`kubectl`,[`port-forward`,e,`svc/${i}`,`8081:80`],{print:!1});console.log(`Starting port-forwarding of ${a} to port 8085`),console.log(`Starting port-forwarding of ${i} to port 8081`),console.log(`Press Ctrl+C to stop the port-forwarding processes.`),await Promise.all([d,f])};async function xe(e){if(await r(A))return;let t=T(e,`..`,`..`,`.gitignore`),n=(await E(t,`utf8`)).split(`
7
+ `).filter(Boolean);n.push(A),await D(t,`${n.join(`
8
+ `)}\n`)}var Se=async e=>{let{mirrordConfigData:t,mirrordPath:n}=await ce(e);await xe(n),console.log(`Wrote the default mirrord config for the requested variation ID`,{mirrordConfigData:t}),process.exit(0)},Ce=async()=>{let e=S.join(se.tmpdir(),`docker-compose.yml`);te.writeFileSync(e,`
9
9
  services:
10
10
  redis:
11
11
  image: redis:6
@@ -71,25 +71,32 @@ volumes:
71
71
  rabbitmq_data:
72
72
  postgres_data:
73
73
  elasticsearch_data:
74
- `),await r(`docker-compose`,[`-f`,e,`up`,`-d`],{print:!1}),console.log(`--------------------------------------------------------------------------------`),console.log(`Successfully started the services:
75
- `),console.log(`redis: localhost:6379 🚀`),console.log(`postgres: localhost:5432, user: postgres, password: postgres 🐘`),console.log(`rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇`),console.log(`elasticsearch: localhost:9200 ❓`),console.log(`kibana: http://localhost:5601 ❓`),process.exit(0)},Ce=async e=>{p(e)&&(console.error(`Connecting to Redis is not supported for simulation clusters (need to be added)`),process.exit(1));let{project:t,name:n}=await f(e),{stdout:i}=await r(`gcloud`,[`redis`,`instances`,`list`,`--region`,u(e),`--project`,t||n,`--format`,`json`],{print:!1}),a;try{a=JSON.parse(i)}catch(e){console.error(`Failed to parse redis instances`,{redisInstances:i,e}),process.exit(1)}let o=Object.fromEntries(a.map(e=>{let t=e.name.split(`/`);return[e.displayName||t?.at(-1)||e.name,e.host]})),c=await s({message:`which redis instance do you want to connect to?`,choices:Object.entries(o).map(([e,t])=>({name:e,value:t})),default:Object.keys(o)[0]});c||(console.error(`No redis instance selected`),process.exit(1));let{stdout:l}=await r(`kubectl`,[`get`,`pods`,`--no-headers`,`-o`,`custom-columns=:metadata.name`],{print:!1}),d=l.split(`
76
- `).find(e=>e.includes(`redis`));d?.trim()||(console.error(`No redis pod found`),process.exit(1));try{let{promise:e,resolve:t,reject:n}=ee(),r=re(`kubectl`,[`exec`,`-it`,d,`--`,`redis-cli`,`-h`,c],{stdio:`inherit`,shell:!0});r.on(`exit`,e=>{e===0?t():n(Error(`Process exited with code ${e}`))}),r.on(`error`,e=>{console.error(`Process error:`,e),n(e)}),console.log(`Connecting to Redis... Could take a few seconds âąī¸`),await e,process.exit(0)}catch(e){console.error(`Failed to connect to Redis:`,e),process.exit(1)}};async function we(e){try{let{stdout:t}=await r(`npm`,[`view`,e,`version`],{print:!1});return t.trim()}catch(t){throw console.error(`Failed to get latest version for ${e}:`,t),t}}async function Te(e,t){try{let{stdout:n}=await r(`npm`,[`view`,`${e}@${t}`,`peerDependencies`,`--json`],{print:!1}),i=n.trim();return!i||i===``?void 0:JSON.parse(i)}catch{return}}async function Ee(e,t){try{let{stdout:n}=await r(`npm`,[`view`,`${e}@${t}`,`peerDependenciesMeta`,`--json`],{print:!1}),i=n.trim();return!i||i===``?void 0:JSON.parse(i)}catch{return}}function B(e){return e.replace(/^[\^~]/,``)}function V(e){let t=B(e),n=/^(\d+)/.exec(t);return n?parseInt(n[1],10):0}function De(e,t){let n=V(e);return V(t)>n}async function Oe(){let e=S(T(),`package.json`);try{let t=await y(e,`utf-8`);return JSON.parse(t)}catch{return c(Error(`Failed to read package.json at ${e}`))}}function ke(e){let t=[];if(e.dependencies)for(let[n,r]of Object.entries(e.dependencies))n.startsWith(`@autofleet/`)&&t.push({name:n,currentVersion:r,latestVersion:``,isDev:!1});if(e.devDependencies)for(let[n,r]of Object.entries(e.devDependencies))n.startsWith(`@autofleet/`)&&t.push({name:n,currentVersion:r,latestVersion:``,isDev:!0});return t}var Ae=async(e=!1)=>{e&&console.log(_(`yellow`,`[DRY RUN MODE] - No packages will be installed`)+`
74
+ `),await g(`docker-compose`,[`-f`,e,`up`,`-d`],{print:!1}),console.log(`--------------------------------------------------------------------------------`),console.log(`Successfully started the services:
75
+ `),console.log(`redis: localhost:6379 🚀`),console.log(`postgres: localhost:5432, user: postgres, password: postgres 🐘`),console.log(`rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇`),console.log(`elasticsearch: localhost:9200 ❓`),console.log(`kibana: http://localhost:5601 ❓`),process.exit(0)},we=async e=>{p(e)&&(console.error(`Connecting to Redis is not supported for simulation clusters (need to be added)`),process.exit(1));let{project:n,name:r}=await f(e),{stdout:i}=await g(`gcloud`,[`redis`,`instances`,`list`,`--region`,u(e),`--project`,n||r,`--format`,`json`],{print:!1}),a;try{a=JSON.parse(i)}catch(e){console.error(`Failed to parse redis instances`,{redisInstances:i,e}),process.exit(1)}let o=Object.fromEntries(a.map(e=>{let t=e.name.split(`/`);return[e.displayName||t?.at(-1)||e.name,e.host]})),c=await s({message:`which redis instance do you want to connect to?`,choices:Object.entries(o).map(([e,t])=>({name:e,value:t})),default:Object.keys(o)[0]});c||(console.error(`No redis instance selected`),process.exit(1));let{stdout:l}=await g(`kubectl`,[`get`,`pods`,`--no-headers`,`-o`,`custom-columns=:metadata.name`],{print:!1}),d=l.split(`
76
+ `).find(e=>e.includes(`redis`));d?.trim()||(console.error(`No redis pod found`),process.exit(1));try{let{promise:e,resolve:n,reject:r}=t(),i=ne(`kubectl`,[`exec`,`-it`,d,`--`,`redis-cli`,`-h`,c],{stdio:`inherit`,shell:!0});i.on(`exit`,e=>{e===0?n():r(Error(`Process exited with code ${e}`))}),i.on(`error`,e=>{console.error(`Process error:`,e),r(e)}),console.log(`Connecting to Redis... Could take a few seconds âąī¸`),await e,process.exit(0)}catch(e){console.error(`Failed to connect to Redis:`,e),process.exit(1)}};async function Te(e){try{let{stdout:t}=await g(`npm`,[`view`,e,`version`],{print:!1});return t.trim()}catch(t){throw console.error(`Failed to get latest version for ${e}:`,t),t}}async function Ee(e,t){try{let{stdout:n}=await g(`npm`,[`view`,`${e}@${t}`,`peerDependencies`,`--json`],{print:!1}),r=n.trim();return!r||r===``?void 0:JSON.parse(r)}catch{return}}async function De(e,t){try{let{stdout:n}=await g(`npm`,[`view`,`${e}@${t}`,`peerDependenciesMeta`,`--json`],{print:!1}),r=n.trim();return!r||r===``?void 0:JSON.parse(r)}catch{return}}function V(e){return e.replace(/^[\^~]/,``)}function H(e){let t=V(e),n=/^(\d+)/.exec(t);return n?parseInt(n[1],10):0}function Oe(e,t){let n=H(e);return H(t)>n}async function ke(){let e=w(O(),`package.json`);try{let t=await E(e,`utf-8`);return JSON.parse(t)}catch{return c(Error(`Failed to read package.json at ${e}`))}}function Ae(e){let t=[];if(e.dependencies)for(let[n,r]of Object.entries(e.dependencies))n.startsWith(`@autofleet/`)&&t.push({name:n,currentVersion:r,latestVersion:``,isDev:!1});if(e.devDependencies)for(let[n,r]of Object.entries(e.devDependencies))n.startsWith(`@autofleet/`)&&t.push({name:n,currentVersion:r,latestVersion:``,isDev:!0});return t}var je=async(e=!1)=>{e&&console.log(v(`yellow`,`[DRY RUN MODE] - No packages will be installed`)+`
77
77
  `),console.log(`Scanning for @autofleet packages...
78
- `);let t=await Oe(),n=ke(t);n.length===0&&(console.log(`No @autofleet packages found in this repository.`),process.exit(0)),console.log(`Found ${n.length} @autofleet package(s):\n`),n.forEach(e=>{console.log(` - ${e.name} (${e.currentVersion})`)}),console.log(``),console.log(`Fetching latest versions...
79
- `);for(let e of n)try{e.latestVersion=await we(e.name)}catch{c(Error(`Failed to fetch latest version for ${e.name}`))}let i=n.filter(e=>B(e.currentVersion)!==e.latestVersion);i.length===0&&(console.log(`All @autofleet packages are already up to date!`),process.exit(0));let a=[];for(let e of i)De(e.currentVersion,e.latestVersion)&&a.push({name:e.name,fromMajor:V(e.currentVersion),toMajor:V(e.latestVersion),currentVersion:B(e.currentVersion),latestVersion:e.latestVersion});if(a.length>0){console.log(_(`yellow`,`âš ī¸ WARNING: The following packages have major version updates:`)+`
80
- `);for(let e of a)console.log(` - ${e.name}: v${e.fromMajor}.x.x → v${e.toMajor}.x.x (${e.currentVersion} → ${e.latestVersion})`);console.log(``),e||(await v({message:`Major version updates may contain breaking changes. Do you want to continue?`,default:!0})||(console.log(`Aborting package updates.`),process.exit(0)),console.log(``))}console.log(`The following packages will be updated:
81
- `);for(let e of i){let t=a.some(t=>t.name===e.name)?_(`yellow`,`(major)`):``;console.log(` - ${e.name}: ${B(e.currentVersion)} → ${e.latestVersion} ${t}`)}console.log(``);let o=new Map,s=new Map;console.log(`Checking peer dependencies...
82
- `);for(let e of i){let[n,r]=await Promise.all([Te(e.name,e.latestVersion),Ee(e.name,e.latestVersion)]);if(n)for(let[e,i]of Object.entries(n))t.dependencies?.[e]||t.devDependencies?.[e]||(r?.[e]?.optional===!0?s.set(e,i):o.set(e,i))}if(o.size>0){console.log(_(`yellow`,`âš ī¸ The following peer dependencies are required but not installed:`)+`
83
- `);for(let[e,t]of o.entries())console.log(` - ${e}@${t}`);if(console.log(``),e)console.log(_(`yellow`,`[DRY RUN] Would prompt to install required peer dependencies`)+`
84
- `);else{if(!await v({message:`Do you want to install these peer dependencies?`,default:!0}))console.log(_(`red`,`âš ī¸ Warning: Skipping peer dependencies may cause issues.`));else for(let[e,t]of o.entries())i.push({name:e,currentVersion:``,latestVersion:t.replace(/^[\^~]/,``),isDev:!1});console.log(``)}}if(s.size>0){console.log(_(`cyan`,`â„šī¸ The following optional peer dependencies are not installed:`)+`
85
- `);for(let[e,t]of s.entries())console.log(` - ${e}@${t} ${_(`dim`,`(optional)`)}`);if(console.log(``),e)console.log(_(`yellow`,`[DRY RUN] Would prompt to install optional peer dependencies`)+`
86
- `);else{if(await v({message:`Do you want to install these optional peer dependencies?`,default:!1}))for(let[e,t]of s.entries())i.push({name:e,currentVersion:``,latestVersion:t.replace(/^[\^~]/,``),isDev:!1});console.log(``)}}e&&(console.log(_(`yellow`,`[DRY RUN] Would install the following packages:`)+`
87
- `),i.map(e=>`${e.name}@${e.latestVersion}`).forEach(e=>{console.log(` - ${e}`)}),console.log(`
88
- `+_(`yellow`,`[DRY RUN] Would run: npm dedupe`)),console.log(`
89
- `+_(`green`,`✓ Dry run completed successfully!`)),process.exit(0)),console.log(`Installing packages...
90
- `);let l=i.map(e=>`${e.name}@${e.latestVersion}`);try{await r(`npm`,[`install`,...l],{print:!0})}catch{c(Error(`Failed to install packages`))}console.log(`
78
+ `);let t=await ke(),n=Ae(t);n.length===0&&(console.log(`No @autofleet packages found in this repository.`),process.exit(0)),console.log(`Found ${n.length} @autofleet package(s):\n`),n.forEach(e=>{console.log(` - ${e.name} (${e.currentVersion})`)}),console.log(``),console.log(`Fetching latest versions...
79
+ `);for(let e of n)try{e.latestVersion=await Te(e.name)}catch{c(Error(`Failed to fetch latest version for ${e.name}`))}let r=n.filter(e=>V(e.currentVersion)!==e.latestVersion);r.length===0&&(console.log(`All @autofleet packages are already up to date!`),process.exit(0));let i=[];for(let e of r)Oe(e.currentVersion,e.latestVersion)&&i.push({name:e.name,fromMajor:H(e.currentVersion),toMajor:H(e.latestVersion),currentVersion:V(e.currentVersion),latestVersion:e.latestVersion});if(i.length>0){console.log(v(`yellow`,`âš ī¸ WARNING: The following packages have major version updates:`)+`
80
+ `);for(let e of i)console.log(` - ${e.name}: v${e.fromMajor}.x.x → v${e.toMajor}.x.x (${e.currentVersion} → ${e.latestVersion})`);console.log(``),e||(await x({message:`Major version updates may contain breaking changes. Do you want to continue?`,default:!0})||(console.log(`Aborting package updates.`),process.exit(0)),console.log(``))}console.log(`The following packages will be updated:
81
+ `);for(let e of r){let t=i.some(t=>t.name===e.name)?v(`yellow`,`(major)`):``;console.log(` - ${e.name}: ${V(e.currentVersion)} → ${e.latestVersion} ${t}`)}console.log(``);let a=new Map,o=new Map;console.log(`Checking peer dependencies...
82
+ `);for(let e of r){let[n,r]=await Promise.all([Ee(e.name,e.latestVersion),De(e.name,e.latestVersion)]);if(n)for(let[e,i]of Object.entries(n))t.dependencies?.[e]||t.devDependencies?.[e]||(r?.[e]?.optional===!0?o.set(e,i):a.set(e,i))}if(a.size>0){console.log(v(`yellow`,`âš ī¸ The following peer dependencies are required but not installed:`)+`
83
+ `);for(let[e,t]of a.entries())console.log(` - ${e}@${t}`);if(console.log(``),e)console.log(v(`yellow`,`[DRY RUN] Would prompt to install required peer dependencies`)+`
84
+ `);else{if(!await x({message:`Do you want to install these peer dependencies?`,default:!0}))console.log(v(`red`,`âš ī¸ Warning: Skipping peer dependencies may cause issues.`));else for(let[e,t]of a.entries())r.push({name:e,currentVersion:``,latestVersion:t.replace(/^[\^~]/,``),isDev:!1});console.log(``)}}if(o.size>0){console.log(v(`cyan`,`â„šī¸ The following optional peer dependencies are not installed:`)+`
85
+ `);for(let[e,t]of o.entries())console.log(` - ${e}@${t} ${v(`dim`,`(optional)`)}`);if(console.log(``),e)console.log(v(`yellow`,`[DRY RUN] Would prompt to install optional peer dependencies`)+`
86
+ `);else{if(await x({message:`Do you want to install these optional peer dependencies?`,default:!1}))for(let[e,t]of o.entries())r.push({name:e,currentVersion:``,latestVersion:t.replace(/^[\^~]/,``),isDev:!1});console.log(``)}}e&&(console.log(v(`yellow`,`[DRY RUN] Would install the following packages:`)+`
87
+ `),r.map(e=>`${e.name}@${e.latestVersion}`).forEach(e=>{console.log(` - ${e}`)}),console.log(`
88
+ `+v(`yellow`,`[DRY RUN] Would run: npm dedupe`)),console.log(`
89
+ `+v(`green`,`✓ Dry run completed successfully!`)),process.exit(0)),console.log(`Installing packages...
90
+ `);let s=r.map(e=>`${e.name}@${e.latestVersion}`);try{await g(`npm`,[`install`,...s],{print:!0})}catch{c(Error(`Failed to install packages`))}console.log(`
91
91
  Deduplicating packages...
92
- `);try{await r(`npm`,[`dedupe`],{print:!0})}catch{console.error(_(`yellow`,`âš ī¸ Warning: Failed to deduplicate packages`))}console.log(`
93
- `+_(`green`,`✓ All @autofleet packages have been updated successfully!`)),process.exit(0)};const H=[{name:`figma`,description:`Figma design integration`,transport:`http`,url:`https://mcp.figma.com/mcp`},{name:`notion`,description:`Notion workspace integration`,transport:`http`,url:`https://mcp.notion.com/mcp`},{name:`atlassian`,description:`Jira & Confluence integration`,transport:`sse`,url:`https://mcp.atlassian.com/v1/sse`},{name:`browserstack`,description:`Testing & accessibility tools`,transport:`http`,url:`https://mcp.browserstack.com/mcp`},{name:`sequential-thinking`,description:`Problem-solving helper`,command:`npx`,args:[`@modelcontextprotocol/server-sequential-thinking`]},{name:`postgres`,description:`Database queries (localhost:5432)`,command:`npx`,args:()=>[`@modelcontextprotocol/server-postgres`,`postgresql://${E.userInfo().username}:postgres@127.0.0.1/postgres`]}];var U=async()=>{console.log(`Setting up Claude Code MCP servers globally...
94
- `);let e=[];for(let t of H)try{if(t.url&&t.transport)await r(`claude`,[`mcp`,`add`,t.name,`--transport`,t.transport,`--scope`,`user`,t.url],{print:!1});else if(t.command&&t.args){let e=typeof t.args==`function`?t.args():t.args;await r(`claude`,[`mcp`,`add`,t.name,`--scope`,`user`,`--`,t.command,...e],{print:!1})}e.push({name:t.name,success:!0}),console.log(` ${_(`green`,`✓`)} ${t.name}`)}catch{e.push({name:t.name,success:!1}),console.log(` ${_(`red`,`✗`)} ${t.name} - failed to add`)}let t=e.filter(e=>e.success).length,n=e.filter(e=>!e.success).length;if(console.log(``),n>0&&console.log(_(`yellow`,`âš ī¸ ${n} server(s) failed to configure`)),t>0){console.log(_(`green`,`✓ ${t} MCP server(s) configured globally for Claude Code:\n`));for(let t of H)e.find(e=>e.name===t.name)?.success&&console.log(` - ${t.name}: ${t.description}`)}console.log(`\nRun ${_(`cyan`,`claude mcp list`)} to verify.`),process.exit(n>0?1:0)};const W=`--variationId=<yourVariationUuid> --cluster=<${m.join(`/`)}>`,G={switchCluster:W,exposeService:`--service=<driver-ms> ${W}`,forwardDb:`${W} --local-port=<localPort>`,forwardService:`--service=<driver-ms> ${W} --port=<port> --local-port=<localPort>`,getIps:W,enableSimulator:W,rabbitCreds:W,updateExp:W,telepresenceWizard:`--service=<driver-ms> ${W} --local-port=<localPort>`,localDev:W,mirrord:`--service=<driver-ms> ${W}`,mirrordConfig:`--variationId=<yourVariationUuid>`,dockerInit:``,openRedis:"--cluster=<${clusterOptions}",updateAutofleetPackages:``,mcpInit:``},je=e=>Object.keys(G).includes(e),{positionals:K,values:q,help:J}=e({strict:!0,binName:`autofleet`,allowPositionals:!0,options:{cluster:{type:`string`,short:`c`,description:`The cluster name. One of dev1, e2eManager, expManager`},variationId:{type:`string`,short:`i`,description:`The variation id`},service:{type:`string`,short:`s`,description:`The service name`},port:{type:`string`,short:`p`,description:`The remote port to forward`},"local-port":{type:`string`,short:`l`,description:`The local port to forward to`},"prefer-pod":{type:`boolean`,short:`r`,default:!1,description:`Wether the mirrord command should run against the pod, rather than the deployment.`},"dry-run":{type:`boolean`,short:`d`,default:!1,description:`Perform a dry run without installing packages`}},commands:G});K.length||(console.log(J),process.exit(0)),K.length>1&&c(`Only one command is allowed`,J);const[Y]=K;je(Y)||c(Error(`Command ${Y} does not exist`),J),await h(q,{switchCluster:[`cluster`],exposeService:[`cluster`,`variationId`,`service`],forwardDb:[`cluster`,`variationId`,{option:`local-port`,defaultVal:`5432`}],forwardService:[`cluster`,`variationId`,`service`,`port`],telepresenceWizard:[`cluster`,`service`],mirrordConfig:[`variationId`],mirrord:[`cluster`,{option:`variationId`,defaultVal:Y===`mirrord`?await le():``},`service`],dockerInit:[],openRedis:[`cluster`],updateAutofleetPackages:[],mcpInit:[]}[Y]??[`cluster`,`variationId`]);const{cluster:X,variationId:Z,service:Q}=q;switch(Y){case`mirrordConfig`:await xe(Z);break;case`dockerInit`:await Se();break;case`updateAutofleetPackages`:await Ae(q[`dry-run`]);break;case`mcpInit`:await U();break}switch(X||c(Error(`cluster required`),J),Y){case`telepresenceWizard`:await he(q);break;case`switchCluster`:await fe(X,Z);break;case`openRedis`:await Ce(X);break}Z||c(Error(`variationId required`),J);let $;try{$=await l({clusterName:X,variationId:Z})}catch(e){c(e)}switch(Y){case`mirrord`:await de($,Z,Q);break;case`exposeService`:await F($,J,Q);break;case`forwardDb`:await I(q,$,Z,J,Q);break;case`forwardService`:await L(q,$,J,Q);break;case`getIps`:await R($);break;case`enableSimulator`:await ge($,Z);break;case`rabbitCreds`:await _e();break;case`updateExp`:await ve($);break;case`localDev`:await ye($,X,Z);break}export{};
92
+ `);try{await g(`npm`,[`dedupe`],{print:!0})}catch{console.error(v(`yellow`,`âš ī¸ Warning: Failed to deduplicate packages`))}console.log(`
93
+ `+v(`green`,`✓ All @autofleet packages have been updated successfully!`)),process.exit(0)};const U=import.meta.dirname,Me=e=>{try{return b(`claude plugin list`,{encoding:`utf-8`}).includes(`${e}`)}catch{return!1}},Ne=e=>{console.log(`đŸ“Ĩ Adding Autofleet marketplace...`);try{b(`claude plugin marketplace remove autofleet`,{stdio:`pipe`})}catch{}try{b(`claude plugin marketplace add ${e}`,{stdio:`pipe`}),console.log(`✓ Marketplace added
94
+ `)}catch{console.log(`âš ī¸ Failed to add marketplace
95
+ `),process.exit(1)}},Pe=(e,t)=>{let n=JSON.parse(y.readFileSync(e,`utf-8`)),[r,i,a]=n.version.split(`.`).map(Number),o=`${r}.${i}.${a+1}`;if(n.version=o,y.writeFileSync(e,JSON.stringify(n,null,2)+`
96
+ `),y.existsSync(t)){let e=JSON.parse(y.readFileSync(t,`utf-8`));e.version=o,y.writeFileSync(t,JSON.stringify(e,null,2)+`
97
+ `)}},Fe=(e,t)=>{if(!Me(e))try{b(`claude plugin install ${e}`,{stdio:`inherit`})}catch{console.log(`âš ī¸ Failed to install plugin
98
+ `),process.exit(1)}console.log(`â„šī¸ Plugin already installed, reinstalling to get latest version...`);try{Pe(S.join(t,`plugins/autofleet/.claude-plugin/plugin.json`),S.resolve(U,`../bin/commands/base/claude-init/claude-marketplace/plugins/autofleet/.claude-plugin/plugin.json`)),b(`claude plugin remove ${e}`,{stdio:`pipe`}),b(`claude plugin install ${e}`,{stdio:`inherit`})}catch{console.log(`âš ī¸ Failed to reinstall plugin
99
+ `),process.exit(1)}};var Ie=()=>{console.log(`🚀 Setting up Autofleet Claude Code plugin...
100
+ `);let e=S.resolve(U,`./claude-marketplace`);Ne(e),Fe(`autofleet@autofleet`,e),console.log(`🎉 Plugin setup complete!
101
+ `),process.exit(0)};const W=`--variationId=<yourVariationUuid> --cluster=<${m.join(`/`)}>`,G={switchCluster:W,exposeService:`--service=<driver-ms> ${W}`,forwardDb:`${W} --local-port=<localPort>`,forwardService:`--service=<driver-ms> ${W} --port=<port> --local-port=<localPort>`,getIps:W,enableSimulator:W,rabbitCreds:W,updateExp:W,telepresenceWizard:`--service=<driver-ms> ${W} --local-port=<localPort>`,localDev:W,mirrord:`--service=<driver-ms> ${W}`,mirrordConfig:`--variationId=<yourVariationUuid>`,dockerInit:``,openRedis:"--cluster=<${clusterOptions}",updateAutofleetPackages:``,claudeInit:``},Le=e=>Object.keys(G).includes(e),{positionals:K,values:q,help:J}=e({strict:!0,binName:`autofleet`,allowPositionals:!0,options:{cluster:{type:`string`,short:`c`,description:`The cluster name. One of dev1, e2eManager, expManager`},variationId:{type:`string`,short:`i`,description:`The variation id`},service:{type:`string`,short:`s`,description:`The service name`},port:{type:`string`,short:`p`,description:`The remote port to forward`},"local-port":{type:`string`,short:`l`,description:`The local port to forward to`},"prefer-pod":{type:`boolean`,short:`r`,default:!1,description:`Wether the mirrord command should run against the pod, rather than the deployment.`},"dry-run":{type:`boolean`,short:`d`,default:!1,description:`Perform a dry run without installing packages`}},commands:G});K.length||(console.log(J),process.exit(0)),K.length>1&&c(`Only one command is allowed`,J);const[Y]=K;Le(Y)||c(Error(`Command ${Y} does not exist`),J),await h(q,{switchCluster:[`cluster`],exposeService:[`cluster`,`variationId`,`service`],forwardDb:[`cluster`,`variationId`,{option:`local-port`,defaultVal:`5432`}],forwardService:[`cluster`,`variationId`,`service`,`port`],telepresenceWizard:[`cluster`,`service`],mirrordConfig:[`variationId`],mirrord:[`cluster`,{option:`variationId`,defaultVal:Y===`mirrord`?await le():``},`service`],dockerInit:[],openRedis:[`cluster`],updateAutofleetPackages:[],claudeInit:[]}[Y]??[`cluster`,`variationId`]);const{cluster:X,variationId:Z,service:Q}=q;switch(Y){case`mirrordConfig`:await Se(Z);break;case`dockerInit`:await Ce();break;case`updateAutofleetPackages`:await je(q[`dry-run`]);break;case`claudeInit`:Ie();break}switch(X||c(Error(`cluster required`),J),Y){case`telepresenceWizard`:await he(q);break;case`switchCluster`:await fe(X,Z);break;case`openRedis`:await we(X);break}Z||c(Error(`variationId required`),J);let $;try{$=await l({clusterName:X,variationId:Z})}catch(e){c(e)}switch(Y){case`mirrord`:await de($,Z,Q);break;case`exposeService`:await L($,J,Q);break;case`forwardDb`:await R(q,$,Z,J,Q);break;case`forwardService`:await ge(q,$,J,Q);break;case`getIps`:await _e($);break;case`enableSimulator`:await ve($,Z);break;case`rabbitCreds`:await z();break;case`updateExp`:await ye($);break;case`localDev`:await be($,X,Z);break}export{};
95
102
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["variationId","asyncSpawn","service","prefix","variationId","cluster","asyncSpawn","asyncSpawn","values","cluster","service","service","help","asyncSpawn","prefix","values","help","variationId","service","asyncSpawn","prefix","values","service","help","asyncSpawn","prefix","asyncSpawn","prefix","asyncSpawn","prefix","variationId","asyncSpawn","serviceName: string | undefined","asyncSpawn","prefix","envNameToUse: string","cluster","variationId","asyncSpawn","prefix","variationId","path","asyncSpawn","asyncSpawn","name","asyncSpawn","packages: PackageInfo[]","majorUpdates: MajorUpdateInfo[]","MCP_SERVERS: McpServer[]","results: { name: string; success: boolean; }[]","asyncSpawn","parseArgs","mirrordConfig","dockerInit","updateAutofleetPackages","mcpInit","switchCluster","openRedis","prefix: string","mirrord","exposeService","forwardDb","forwardService","getIps","enableSimulator","rabbitCreds","updateExp","localDev"],"sources":["../bin/utils/mirrord.ts","../bin/utils/exitHandler.ts","../bin/commands/base/mirrord.ts","../bin/commands/base/switchCluster.ts","../bin/commands/base/telepresenceWizard.ts","../bin/commands/base/exposeService.ts","../bin/commands/base/forwardDb.ts","../bin/commands/base/forwardService.ts","../bin/commands/base/getIps.ts","../bin/commands/base/enableSimulator.ts","../bin/commands/base/rabbitCreds.ts","../bin/commands/base/updateExp.ts","../bin/utils/env.ts","../bin/commands/base/localDev.ts","../bin/commands/base/mirrordConfig.ts","../bin/commands/base/dockerInit.ts","../bin/commands/base/openRedis.ts","../bin/commands/base/updateAutofleetPackages.ts","../bin/commands/base/mcpInit.ts","../bin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { getGitPath } from './git.js';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\n\nexport const MIRRORD_FOLDER_NAME = '.mirrord';\n\nasync function getMirrodFolderPath({ makeDir = false } = {}) {\n const repoPath = await getGitPath();\n const mirrordPath = join(repoPath, MIRRORD_FOLDER_NAME);\n if (makeDir) {\n await mkdir(mirrordPath, { recursive: true });\n }\n return join(mirrordPath, 'mirrord.json');\n}\n\nexport async function writeMirrordFile(variationId?: string) {\n const mirrordPath = await getMirrodFolderPath({ makeDir: true });\n const mirrordConfigData = {\n feature: {\n network: {\n incoming: {\n mode: 'steal',\n http_filter: {\n path_filter: '^(?!/alive)',\n },\n },\n outgoing: true,\n },\n fs: 'read',\n env: true,\n },\n target: {\n namespace: variationId || randomUUID(),\n },\n agent: {\n startup_timeout: 120,\n },\n };\n await writeFile(mirrordPath, JSON.stringify(mirrordConfigData, null, 2));\n\n return { mirrordConfigData, mirrordPath };\n}\n\nexport async function getVariationIdFromMirrodConfig() {\n try {\n const mirrordPath = await getMirrodFolderPath();\n const mirrordConfigDataString = await readFile(mirrordPath, { encoding: 'utf-8' });\n const mirrordConfigData = JSON.parse(mirrordConfigDataString || '{}') as { target?: { namespace?: string; }; };\n return mirrordConfigData?.target?.namespace ?? '';\n } catch {\n return '';\n }\n}\n","export function registerProcessForCleanup(onExit: (e?: unknown) => void | PromiseLike<void>) {\n process.once('exit', onExit);\n process.once('SIGTERM', onExit);\n process.once('SIGINT', onExit);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { registerProcessForCleanup } from '../../utils/exitHandler.js';\n\ndeclare global {\n var executedExitHooks: boolean;\n}\n\nfunction trimProbeString(str: string): string {\n str &&= str.trim();\n if (!str) {\n return str;\n }\n if (str.startsWith('\\'') && str.endsWith('\\'')) {\n str = str.slice(1, -1);\n }\n return str;\n}\n\nconst LIVENESS_PROBE = 'livenessProbe';\nconst READINESS_PROBE = 'readinessProbe';\nconst WORKER_PATH = (leaf: string) => `jsonpath='{.spec.template.spec.containers[?(@.name==\"worker\")].${leaf}}'`;\nconst SET_PROBE_VALUES = (...probeAndValues: [string, string][]) =>\n `{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"worker\",${probeAndValues\n .map(([probe, value]) => `\"${probe}\": ${value}`)\n .join(',')}}]}}}}`;\n\nexport default async (prefix: string, variationId: string, service?: string) => {\n console.log('Will now disable health check to allow debugging.');\n let [{ stdout: livenessProbe }, { stdout: readinessProbe }] = await Promise.all([\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(LIVENESS_PROBE)], { print: false }),\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(READINESS_PROBE)], { print: false }),\n ]);\n livenessProbe &&= trimProbeString(livenessProbe);\n readinessProbe &&= trimProbeString(readinessProbe);\n if (livenessProbe || readinessProbe) {\n await asyncSpawn('kubectl', ['patch', `deployment/${service}`, prefix, '--patch', SET_PROBE_VALUES([LIVENESS_PROBE, 'null'], [READINESS_PROBE, 'null'])], { print: false });\n console.log('Health check disabled, will now start mirrord and run \"npm run dev\". Make sure to attach a debugger!');\n }\n const abortController = new AbortController();\n registerProcessForCleanup(async () => {\n if (globalThis.executedExitHooks) {\n return;\n }\n globalThis.executedExitHooks = true;\n abortController.abort();\n if (livenessProbe || readinessProbe) {\n console.log('Re-enabling health check.');\n await asyncSpawn(\n 'kubectl',\n [\n 'patch',\n `deployment/${service}`,\n prefix,\n '--patch',\n `'${SET_PROBE_VALUES(\n [LIVENESS_PROBE, livenessProbe],\n [READINESS_PROBE, readinessProbe],\n )}'`,\n ],\n { print: false, shell: true },\n );\n console.log('health check enabled.');\n }\n process.exit(0);\n });\n try {\n await asyncSpawn('mirrord', ['exec', '-t', `deployment/${service}`, '-n', variationId, '--steal', 'npm', 'run', 'dev'], { signal: abortController.signal });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ABORT_ERR') {\n return;\n }\n endWithError(error as Error);\n }\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getCurrentNamespace } from '../../utils/index.js';\nimport { fillMissingRequiredValues } from '../../utils/inquirer.js';\n\nexport default async (cluster: string, variationId?: string) => {\n await connectToCluster(cluster);\n\n if (cluster === 'expManager' || cluster === 'dev1') {\n const { variationId: namespace } = await fillMissingRequiredValues({ variationId }, ['variationId']);\n if (namespace !== '') {\n if (await getCurrentNamespace() === namespace) {\n console.log(`Already connected to simulation with uuid: ${namespace}, skipping namespace switch...`);\n process.exit(0);\n }\n await asyncSpawn('kubectl', ['config', 'set-context', '--current', `--namespace=${namespace}`], { print: false });\n console.log(`Switched to simulation with uuid: ${namespace} successfully`);\n }\n }\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getVariationId, getLocalPort, safeSelect } from '../../utils/inquirer.js';\nimport { connectToCluster, endWithError } from '../../utils/index.js';\nimport type { Values } from '../../index.js';\n\nasync function ensureTelepresenceInstalled() {\n try {\n await asyncSpawn('telepresence', ['version'], { print: false });\n } catch {\n endWithError('Telepresence is not installed. Please install it from:\\nhttps://www.telepresence.io/docs/latest/quick-start/');\n }\n}\n\nfunction leaveOrConnect() {\n return safeSelect({\n message: 'Do you want to leave the connection or create a new one?',\n choices: [\n { name: 'Leave the current connection', value: 'leave' },\n { name: 'Create a new connection', value: 'connect' },\n ] as const,\n default: 'connect',\n });\n}\n\nexport default async function telepresenceWizard(values: Values): Promise<void> {\n await ensureTelepresenceInstalled();\n\n const { cluster = '', service = '' } = values; // Values should be defined by now, thanks to inquirer. Default to hint to TS we always have values.\n await connectToCluster(cluster);\n\n const action = await leaveOrConnect();\n if (!['leave', 'connect'].includes(action!)) {\n endWithError('Invalid action, how did you get here? 🤔');\n }\n if (action === 'leave') {\n await asyncSpawn('telepresence', ['leave', service]);\n console.log('Disconnected! 👋');\n return;\n }\n const namespace = values.variationId || await getVariationId();\n const localPort = (values['local-port'] && Number.parseInt(values['local-port'], 10)) || Number.parseInt((await getLocalPort()) || '', 10);\n await asyncSpawn('telepresence', ['connect', `--namespace=${namespace}`]);\n await asyncSpawn('telepresence', ['intercept', service, '--port', localPort.toString(), '--env-file=./.env']);\n console.log('Everything is set up! 🚀');\n console.log(`You can now access the service at localhost:${localPort}`);\n console.log('You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.');\n process.exit(0);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\nexport default async (prefix: string, help: string, service?: string) => {\n if (!service) {\n endWithError(new Error('service is required for exposeService'), help);\n }\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, service, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n console.log(`exposed ${service} successfully. the service is now creating an internal load balancer ip to use with vpn`);\n process.exit(0);\n};\n","import { setTimeout } from 'node:timers/promises';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, variationId: string, help: string, service?: string) => {\n const localPort = Number.parseInt(values['local-port'] ?? '5432', 10);\n if (Number.isNaN(localPort)) {\n endWithError(new Error('if defined, local-port must be a number'), help);\n }\n const DB_PASSWORD = `afpass_${variationId}`;\n const USER_NAME = 'postgres';\n const variationUnderScore = variationId.replaceAll('-', '_');\n const DB_NAME = service ? `${service.replaceAll('-', '_') || ''}_${variationUnderScore}` : 'postgres';\n\n const postgressPath = `postgres://${USER_NAME}:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?&nickname=var_${variationId}`;\n console.log(`Forwarding db to local port ${localPort}.\\naccess the DB at ${postgressPath}\\nPress ctrl+c to stop.`);\n\n const dbEnvs = ` DB_USERNAME=${USER_NAME}\n DB_PASSWORD=${DB_PASSWORD}\n DB_NAME=${service ? DB_NAME : `<service_name>_${variationUnderScore}`}`;\n console.log('Generated database environment for local development:\\n', dbEnvs);\n\n setTimeout(1500).then(() => asyncSpawn('open', [postgressPath], { print: false })).catch(() => null);\n await asyncSpawn('kubectl', [prefix, 'port-forward', `svc/p${variationId}-postgresql`, `${localPort}:5432`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n port?: string;\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, help: string, service?: string) => {\n const port = Number.parseInt(values.port ?? '8080', 10);\n const localPort = Number.parseInt(values['local-port'] ?? '', 10) || port;\n if (!service) {\n endWithError(new Error('service is required for forwardService'), help);\n }\n if (!port || Number.isNaN(port)) {\n endWithError(new Error('port is required and must be a numbers'), help);\n }\n if (localPort && Number.isNaN(localPort)) {\n endWithError(new Error('local-port must be a number'), help);\n }\n let { stdout: podName } = await asyncSpawn('kubectl', ['get', 'pods', prefix, '-l', `service=${service}`, '-o', 'jsonpath=\"{.items[0].metadata.name}\"'], { print: false });\n podName &&= podName.trim();\n if (!podName) {\n endWithError(new Error(`No pods found for service ${service}`));\n }\n if (podName.startsWith('\"') && podName.endsWith('\"')) {\n podName = podName.slice(1, -1);\n }\n console.log(`Found pod ${podName}, serving locally on port ${localPort} from remote port ${port}.\\nPress ctrl+c to stop.`);\n await asyncSpawn('kubectl', ['port-forward', prefix, podName, `${localPort}:${port}`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { parseIps } from '../../utils/index.js';\n\nexport default async (prefix: string) => {\n const { stdout } = await asyncSpawn('kubectl', [prefix, 'get', 'services'], { print: false });\n const ips = parseIps(stdout);\n ips.forEach(ip => console.log(ip));\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async (prefix: string, variationId: string) => {\n const SIMULATION_CLUSTER_FRONT = 'simulation-cluster-front';\n await asyncSpawn('kubectl', ['annotate', prefix, 'service', SIMULATION_CLUSTER_FRONT, 'cloud.google.com/load-balancer-type-']);\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, SIMULATION_CLUSTER_FRONT, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n await asyncSpawn('kubectl', ['create', prefix, 'rolebinding', 'admin', '--clusterrole=cluster-admin', `--serviceaccount=${variationId}:default`]);\n console.log(`Successfully exposed ${SIMULATION_CLUSTER_FRONT} and added role binding to dispatch simulations`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async () => {\n const getArgs = (dataKey: string) => ['get', 'secret', 'rabbitmq-default-user', '-o', `jsonpath=\"{.data.${dataKey}}\"`];\n const [{ stdout: username }, { stdout: password }] = await Promise.all([\n asyncSpawn('kubectl', getArgs('username'), { print: false }),\n asyncSpawn('kubectl', getArgs('password'), { print: false }),\n ]);\n console.log(`username: ${Buffer.from(username, 'base64').toString('ascii')}`);\n console.log(`password: ${Buffer.from(password, 'base64').toString('ascii')}`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { basename, sep } from 'node:path';\nimport { cwd } from 'node:process';\nimport { getCurrentBranch, getGitPath } from '../../utils/git.js';\nimport { getAutorepoAppName } from '../../utils/inquirer.js';\n\nexport default async (prefix: string) => {\n const gitPath = await getGitPath();\n const repoName = gitPath.split(sep).pop();\n const isAutorepo = repoName === 'autorepo';\n let serviceName: string | undefined;\n if (isAutorepo) {\n serviceName = await getAutorepoAppName(gitPath);\n if (!serviceName) {\n console.error('No service name provided, exiting...');\n process.exit(1);\n }\n } else {\n serviceName = basename(cwd());\n }\n const [branchName, archResult] = await Promise.all([getCurrentBranch(), asyncSpawn('uname', ['-m'], { print: false })]);\n const arch = archResult.stdout.trim();\n const date = new Date();\n const dateSuffix = `${date.getHours().toString().padStart(2, '0')}-${date.getMinutes().toString().padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}`;\n const imageName = `gcr.io/autofleetprod/${serviceName}:${branchName}-${dateSuffix}`;\n console.log(`Building and pushing image ${imageName}`);\n const platformFlag = arch === 'x86_64' ? [] : ['--platform', 'linux/amd64'];\n const dockerfilePath = isAutorepo ? `apps/${serviceName}${sep}Dockerfile` : 'Dockerfile';\n if (isAutorepo) {\n await asyncSpawn('npx', ['nx', 'build', serviceName]);\n }\n await asyncSpawn('docker', ['build', '.', '-f', dockerfilePath, ...platformFlag, '-t', imageName, '--build-arg', `NPM_TOKEN=${process.env.NPM_TOKEN}`]);\n await asyncSpawn('docker', ['push', imageName]);\n const { stdout: podDescription } = await asyncSpawn('kubectl', ['describe', 'pod', prefix, '-l', `service=${serviceName}`], { print: false });\n if (podDescription.includes('Init Containers:')) {\n await asyncSpawn('kubectl', ['patch', `deployment/${serviceName}`, prefix, '--patch', `{\"spec\": {\"template\": {\"spec\": {\"initContainers\": [{\"name\": \"init\",\"image\": \"${imageName}\"}]}}}}`]);\n }\n await asyncSpawn('kubectl', ['set', 'image', `deployment/${serviceName}`, `worker=${imageName}`, prefix]);\n await asyncSpawn('kubectl', ['rollout', 'status', 'deployments', serviceName, prefix]);\n process.exit(0);\n};\n","import { EOL } from 'node:os';\nimport { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\n\nexport async function setEnvValue(repoRoot: string, key: string, value: string): Promise<boolean> {\n const filePath = resolve(repoRoot, '.env');\n const envFileContent = await readFile(filePath, 'utf8');\n const envVars = envFileContent.split(EOL);\n\n // (?<!#\\\\s*) Negative lookbehind to avoid matching comments (lines that starts with #).\n // There is a double slash in the RegExp constructor to escape it.\n // (?==) Positive lookahead to check if there is an equal sign right after the key.\n // This is to prevent matching keys prefixed with the key of the env var to update.\n const regexString = `(?<!#\\\\s*)${key}(?==)`;\n const matchingLine = envVars.find((line: string) => line.match(regexString));\n\n if (matchingLine?.split('=').at(-1) === value) {\n return false;\n }\n\n const target = matchingLine ? envVars.indexOf(matchingLine) : -1;\n\n if (target !== -1) {\n envVars.splice(target, 1, `${key}=${value}`);\n } else {\n envVars.push(`${key}=${value}`);\n }\n\n await writeFile(filePath, envVars.join(EOL));\n return true;\n}\n","import { basename } from 'node:path';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getGitPath } from '../../utils/git.js';\nimport { endWithError } from '../../utils/index.js';\nimport { setEnvValue } from '../../utils/env.js';\n\nexport default async (prefix: string, cluster: string, variationId: string) => {\n const LOCAL_ENV_NAME = 'LOCAL_ENV_NAME';\n const API_GATEWAY_MS = 'api-gateway-ms';\n const CONTROL_CENTER_MS = 'control-center-ms';\n let envNameToUse: string;\n if (cluster.includes('prod')) {\n envNameToUse = 'production';\n } else if (cluster === 'staging') {\n envNameToUse = 'staging';\n } else {\n envNameToUse = `simulator-${variationId}`;\n }\n\n const repoPath = await getGitPath();\n if (basename(repoPath) !== 'control-center') {\n endWithError(new Error('The `localDev` command must be run from the control-center repository'));\n }\n\n const apiGatewayMsIP = 'localhost:8081';\n const changedAiGatewayMsIP = await setEnvValue(repoPath, 'API_GATEWAY_MS_SERVICE_HOST', apiGatewayMsIP);\n\n if (changedAiGatewayMsIP) {\n console.log(`Updated .env file to use ${API_GATEWAY_MS} IP (${apiGatewayMsIP}).`);\n }\n\n const controlCenterMsIP = 'localhost:8085';\n const changedControlCenterIP = await setEnvValue(repoPath, 'CONTROL_CENTER_MS_SERVICE_HOST', controlCenterMsIP);\n\n if (changedControlCenterIP) {\n console.log(`Updated .env file to use ${CONTROL_CENTER_MS} IP (${controlCenterMsIP}).`);\n }\n\n const changedEnvName = await setEnvValue(repoPath, LOCAL_ENV_NAME, envNameToUse);\n\n if (changedEnvName) {\n console.log(`Updated .env file ${LOCAL_ENV_NAME} to ${envNameToUse} (used for firebase setup).`);\n }\n\n const controlCenterProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${CONTROL_CENTER_MS}`, '8085:80'], { print: false });\n const apiGatewayProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${API_GATEWAY_MS}`, '8081:80'], { print: false });\n\n console.log(`Starting port-forwarding of ${CONTROL_CENTER_MS} to port 8085`);\n console.log(`Starting port-forwarding of ${API_GATEWAY_MS} to port 8081`);\n console.log('Press Ctrl+C to stop the port-forwarding processes.');\n\n await Promise.all([controlCenterProcess, apiGatewayProcess]);\n};\n","import { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { isPathIgnored } from '../../utils/git.js';\nimport { writeMirrordFile, MIRRORD_FOLDER_NAME } from '../../utils/mirrord.js';\n\nasync function addToGitIgnore(mirrordPath: string) {\n const isIgnored = await isPathIgnored(MIRRORD_FOLDER_NAME);\n if (isIgnored) {\n return;\n }\n const gitIgnoreFile = resolve(mirrordPath, '..', '..', '.gitignore');\n const gitIgnoreFileContent = await readFile(gitIgnoreFile, 'utf8');\n const gitIgnoreFileContentLines = gitIgnoreFileContent.split('\\n').filter(Boolean);\n gitIgnoreFileContentLines.push(MIRRORD_FOLDER_NAME);\n await writeFile(gitIgnoreFile, `${gitIgnoreFileContentLines.join('\\n')}\\n`);\n}\n\nexport default async (variationId?: string) => {\n const { mirrordConfigData, mirrordPath } = await writeMirrordFile(variationId);\n await addToGitIgnore(mirrordPath);\n console.log('Wrote the default mirrord config for the requested variation ID', { mirrordConfigData });\n process.exit(0);\n};\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\n\nconst dockerComposeFile = `\nservices:\n redis:\n image: redis:6\n ports:\n - \"6379:6379\"\n volumes:\n - redis_data:/data\n command: redis-server --appendonly yes\n\n rabbitmq:\n image: rabbitmq:3.12.13-management\n ports:\n - \"5672:5672\" # AMQP protocol port\n - \"15672:15672\" # Management UI port\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n environment:\n - RABBITMQ_DEFAULT_USER=guest\n - RABBITMQ_DEFAULT_PASS=guest\n\n postgres:\n image: postgis/postgis:14-3.3\n platform: linux/amd64\n ports:\n - \"5432:5432\"\n volumes:\n - postgres_data:/var/lib/postgresql/data\n environment:\n - POSTGRES_DB=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_PASSWORD=postgres\n\n elasticsearch:\n image: docker.elastic.co/elasticsearch/elasticsearch:8.8.1\n ports:\n - \"9200:9200\"\n - \"9300:9300\"\n environment:\n - discovery.type=single-node\n - xpack.security.enabled=false\n - xpack.security.transport.ssl.enabled=false\n - xpack.security.http.ssl.enabled=false\n - ES_JAVA_OPTS=-Xms1g -Xmx1g\n volumes:\n - elasticsearch_data:/usr/share/elasticsearch/data\n ulimits:\n memlock:\n soft: -1\n hard: -1\n mem_limit: 2g\n\n kibana:\n image: docker.elastic.co/kibana/kibana:8.8.1\n ports:\n - \"5601:5601\"\n environment:\n - ELASTICSEARCH_HOSTS=http://elasticsearch:9200\n depends_on:\n - elasticsearch\n\nvolumes:\n redis_data:\n rabbitmq_data:\n postgres_data:\n elasticsearch_data:\n`;\n\nexport default async () => {\n const dockerComposePath = path.join(os.tmpdir(), 'docker-compose.yml');\n fs.writeFileSync(dockerComposePath, dockerComposeFile);\n await asyncSpawn('docker-compose', ['-f', dockerComposePath, 'up', '-d'], { print: false });\n console.log('--------------------------------------------------------------------------------');\n console.log('Successfully started the services:\\n');\n console.log('redis: localhost:6379 🚀');\n console.log('postgres: localhost:5432, user: postgres, password: postgres 🐘');\n console.log('rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇');\n console.log('elasticsearch: localhost:9200 ❓');\n console.log('kibana: http://localhost:5601 ❓');\n process.exit(0);\n};\n","import { spawn } from 'node:child_process';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getRedisRegion, isSimulationCluster } from '../../utils/index.js';\nimport { safeSelect } from '../../utils/inquirer.js';\nimport { createDeferredPromise } from '../../utils/promise.js';\n\ninterface RedisInstance {\n displayName?: string;\n host: string;\n name: string;\n}\n\nexport default async (clusterName: string) => {\n if (isSimulationCluster(clusterName)) {\n console.error('Connecting to Redis is not supported for simulation clusters (need to be added)');\n process.exit(1);\n }\n\n const {\n project,\n name,\n } = await connectToCluster(clusterName);\n const redisRegion = getRedisRegion(clusterName);\n const { stdout: redisInstances } = await asyncSpawn('gcloud', ['redis', 'instances', 'list', '--region', redisRegion, '--project', project || name, '--format', 'json'], { print: false });\n let redisInstancesJson;\n try {\n redisInstancesJson = JSON.parse(redisInstances) as RedisInstance[];\n } catch (e) {\n console.error('Failed to parse redis instances', { redisInstances, e });\n process.exit(1);\n }\n\n const redisNameToIpMap = Object.fromEntries(redisInstancesJson.map((instance: RedisInstance) => {\n const redisPath = instance.name.split('/');\n return [instance.displayName || redisPath?.at(-1) || instance.name, instance.host];\n }));\n\n const redisIp = await safeSelect({\n message: 'which redis instance do you want to connect to?',\n choices: Object.entries(redisNameToIpMap).map(([name, ip]) => ({ name, value: ip })),\n default: Object.keys(redisNameToIpMap)[0],\n });\n\n if (!redisIp) {\n console.error('No redis instance selected');\n process.exit(1);\n }\n\n const { stdout: allPodsName } = await asyncSpawn('kubectl', ['get', 'pods', '--no-headers', '-o', 'custom-columns=:metadata.name'], { print: false });\n const redisPodName = allPodsName.split('\\n').find(podName => podName.includes('redis'));\n\n if (!redisPodName?.trim()) {\n console.error('No redis pod found');\n process.exit(1);\n }\n\n try {\n const { promise, resolve, reject } = createDeferredPromise<void>();\n const shell = spawn('kubectl', [\n 'exec',\n '-it',\n redisPodName,\n '--',\n 'redis-cli',\n '-h',\n redisIp,\n ], {\n stdio: 'inherit',\n shell: true,\n });\n shell.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n shell.on('error', (error) => {\n console.error('Process error:', error);\n reject(error);\n });\n\n console.log('Connecting to Redis... Could take a few seconds âąī¸');\n\n await promise;\n\n process.exit(0);\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n process.exit(1);\n }\n};\n","import { readFile } from 'node:fs/promises';\nimport { cwd } from 'node:process';\nimport { join } from 'node:path';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { confirm } from '@inquirer/prompts';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface PackageInfo {\n name: string;\n currentVersion: string;\n latestVersion: string;\n isDev: boolean;\n}\n\ninterface MajorUpdateInfo {\n name: string;\n fromMajor: number;\n toMajor: number;\n currentVersion: string;\n latestVersion: string;\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', packageName, 'version'], { print: false });\n return stdout.trim();\n } catch (_error) {\n console.error(`Failed to get latest version for ${packageName}:`, _error);\n throw _error;\n }\n}\n\nasync function getPeerDependencies(packageName: string, version: string): Promise<Record<string, string> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependencies', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function getPeerDependenciesMeta(packageName: string, version: string): Promise<Record<string, { optional?: boolean; }> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependenciesMeta', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nfunction parseVersion(version: string): string {\n return version.replace(/^[\\^~]/, '');\n}\n\nfunction getMajorVersion(version: string): number {\n const cleaned = parseVersion(version);\n const regex = /^(\\d+)/;\n const match = regex.exec(cleaned);\n return match ? parseInt(match[1], 10) : 0;\n}\n\nfunction isMajorUpdate(currentVersion: string, latestVersion: string): boolean {\n const currentMajor = getMajorVersion(currentVersion);\n const latestMajor = getMajorVersion(latestVersion);\n return latestMajor > currentMajor;\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const packageJsonPath = join(cwd(), 'package.json');\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return endWithError(new Error(`Failed to read package.json at ${packageJsonPath}`));\n }\n}\n\nfunction getAutofleetPackages(packageJson: PackageJson): PackageInfo[] {\n const packages: PackageInfo[] = [];\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: false });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(packageJson.devDependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: true });\n }\n }\n }\n\n return packages;\n}\n\nexport default async (dryRun = false) => {\n if (dryRun) {\n console.log(styleText('yellow', '[DRY RUN MODE] - No packages will be installed') + '\\n');\n }\n console.log('Scanning for @autofleet packages...\\n');\n\n const packageJson = await readPackageJson();\n const autofleetPackages = getAutofleetPackages(packageJson);\n\n if (autofleetPackages.length === 0) {\n console.log('No @autofleet packages found in this repository.');\n process.exit(0);\n }\n\n console.log(`Found ${autofleetPackages.length} @autofleet package(s):\\n`);\n autofleetPackages.forEach((pkg) => {\n console.log(` - ${pkg.name} (${pkg.currentVersion})`);\n });\n console.log('');\n\n console.log('Fetching latest versions...\\n');\n\n // Fetch latest versions\n for (const pkg of autofleetPackages) {\n try {\n pkg.latestVersion = await getLatestVersion(pkg.name);\n } catch {\n endWithError(new Error(`Failed to fetch latest version for ${pkg.name}`));\n }\n }\n\n // Check for packages that are already up to date\n const packagesToUpdate = autofleetPackages.filter(\n pkg => parseVersion(pkg.currentVersion) !== pkg.latestVersion,\n );\n\n if (packagesToUpdate.length === 0) {\n console.log('All @autofleet packages are already up to date!');\n process.exit(0);\n }\n\n // Identify major version updates\n const majorUpdates: MajorUpdateInfo[] = [];\n\n for (const pkg of packagesToUpdate) {\n if (isMajorUpdate(pkg.currentVersion, pkg.latestVersion)) {\n majorUpdates.push({\n name: pkg.name,\n fromMajor: getMajorVersion(pkg.currentVersion),\n toMajor: getMajorVersion(pkg.latestVersion),\n currentVersion: parseVersion(pkg.currentVersion),\n latestVersion: pkg.latestVersion,\n });\n }\n }\n\n // Show major version update warning\n if (majorUpdates.length > 0) {\n console.log(styleText('yellow', 'âš ī¸ WARNING: The following packages have major version updates:') + '\\n');\n for (const update of majorUpdates) {\n console.log(` - ${update.name}: v${update.fromMajor}.x.x → v${update.toMajor}.x.x (${update.currentVersion} → ${update.latestVersion})`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldContinue = await confirm({\n message: 'Major version updates may contain breaking changes. Do you want to continue?',\n default: true,\n });\n\n if (!shouldContinue) {\n console.log('Aborting package updates.');\n process.exit(0);\n }\n console.log('');\n }\n }\n\n // Show packages to update\n console.log('The following packages will be updated:\\n');\n for (const pkg of packagesToUpdate) {\n const isMajor = majorUpdates.some(b => b.name === pkg.name);\n const marker = isMajor ? styleText('yellow', '(major)') : '';\n console.log(` - ${pkg.name}: ${parseVersion(pkg.currentVersion)} → ${pkg.latestVersion} ${marker}`);\n }\n console.log('');\n\n // Collect all peer dependencies\n const missingRequiredPeerDeps = new Map<string, string>();\n const missingOptionalPeerDeps = new Map<string, string>();\n\n console.log('Checking peer dependencies...\\n');\n for (const pkg of packagesToUpdate) {\n const [peerDeps, peerDepsMeta] = await Promise.all([\n getPeerDependencies(pkg.name, pkg.latestVersion),\n getPeerDependenciesMeta(pkg.name, pkg.latestVersion),\n ]);\n\n if (peerDeps) {\n for (const [peerName, peerVersion] of Object.entries(peerDeps)) {\n // Check if peer dependency is already in package.json\n const currentPeerVersion\n = packageJson.dependencies?.[peerName]\n || packageJson.devDependencies?.[peerName];\n\n if (!currentPeerVersion) {\n // Check if this peer dependency is optional\n const isOptional = peerDepsMeta?.[peerName]?.optional === true;\n if (isOptional) {\n missingOptionalPeerDeps.set(peerName, peerVersion);\n } else {\n missingRequiredPeerDeps.set(peerName, peerVersion);\n }\n }\n }\n }\n }\n\n // Handle missing required peer dependencies\n if (missingRequiredPeerDeps.size > 0) {\n console.log(styleText('yellow', 'âš ī¸ The following peer dependencies are required but not installed:') + '\\n');\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n console.log(` - ${name}@${version}`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldInstallPeers = await confirm({\n message: 'Do you want to install these peer dependencies?',\n default: true,\n });\n\n if (!shouldInstallPeers) {\n console.log(styleText('red', 'âš ī¸ Warning: Skipping peer dependencies may cause issues.'));\n } else {\n // Add to packages to update\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n console.log('');\n } else {\n console.log(styleText('yellow', '[DRY RUN] Would prompt to install required peer dependencies') + '\\n');\n }\n }\n\n // Handle missing optional peer dependencies\n if (missingOptionalPeerDeps.size > 0) {\n console.log(styleText('cyan', 'â„šī¸ The following optional peer dependencies are not installed:') + '\\n');\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n console.log(` - ${name}@${version} ${styleText('dim', '(optional)')}`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldInstallOptionalPeers = await confirm({\n message: 'Do you want to install these optional peer dependencies?',\n default: false,\n });\n\n if (shouldInstallOptionalPeers) {\n // Add to packages to update\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n console.log('');\n } else {\n console.log(styleText('yellow', '[DRY RUN] Would prompt to install optional peer dependencies') + '\\n');\n }\n }\n\n if (dryRun) {\n console.log(styleText('yellow', '[DRY RUN] Would install the following packages:') + '\\n');\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n packagesToInstall.forEach((pkg) => {\n console.log(` - ${pkg}`);\n });\n console.log('\\n' + styleText('yellow', '[DRY RUN] Would run: npm dedupe'));\n console.log('\\n' + styleText('green', '✓ Dry run completed successfully!'));\n process.exit(0);\n }\n\n console.log('Installing packages...\\n');\n\n // Install packages\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n\n try {\n await asyncSpawn('npm', ['install', ...packagesToInstall], { print: true });\n } catch {\n endWithError(new Error('Failed to install packages'));\n }\n\n console.log('\\nDeduplicating packages...\\n');\n\n try {\n await asyncSpawn('npm', ['dedupe'], { print: true });\n } catch {\n console.error(styleText('yellow', 'âš ī¸ Warning: Failed to deduplicate packages'));\n }\n\n console.log('\\n' + styleText('green', '✓ All @autofleet packages have been updated successfully!'));\n process.exit(0);\n};\n","import * as os from 'node:os';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\n\ninterface McpServer {\n name: string;\n description: string;\n transport?: 'http' | 'sse';\n url?: string;\n command?: string;\n args?: string[] | (() => string[]);\n}\n\nconst MCP_SERVERS: McpServer[] = [\n {\n name: 'figma',\n description: 'Figma design integration',\n transport: 'http',\n url: 'https://mcp.figma.com/mcp',\n },\n {\n name: 'notion',\n description: 'Notion workspace integration',\n transport: 'http',\n url: 'https://mcp.notion.com/mcp',\n },\n {\n name: 'atlassian',\n description: 'Jira & Confluence integration',\n transport: 'sse',\n url: 'https://mcp.atlassian.com/v1/sse',\n },\n {\n name: 'browserstack',\n description: 'Testing & accessibility tools',\n transport: 'http',\n url: 'https://mcp.browserstack.com/mcp',\n },\n {\n name: 'sequential-thinking',\n description: 'Problem-solving helper',\n command: 'npx',\n args: ['@modelcontextprotocol/server-sequential-thinking'],\n },\n {\n name: 'postgres',\n description: 'Database queries (localhost:5432)',\n command: 'npx',\n args: () => {\n const username = os.userInfo().username;\n return ['@modelcontextprotocol/server-postgres', `postgresql://${username}:postgres@127.0.0.1/postgres`];\n },\n },\n];\n\nexport default async () => {\n console.log('Setting up Claude Code MCP servers globally...\\n');\n\n const results: { name: string; success: boolean; }[] = [];\n\n for (const server of MCP_SERVERS) {\n try {\n if (server.url && server.transport) {\n await asyncSpawn(\n 'claude',\n ['mcp', 'add', server.name, '--transport', server.transport, '--scope', 'user', server.url],\n { print: false },\n );\n } else if (server.command && server.args) {\n const args = typeof server.args === 'function' ? server.args() : server.args;\n await asyncSpawn(\n 'claude',\n ['mcp', 'add', server.name, '--scope', 'user', '--', server.command, ...args],\n { print: false },\n );\n }\n results.push({ name: server.name, success: true });\n console.log(` ${styleText('green', '✓')} ${server.name}`);\n } catch {\n results.push({ name: server.name, success: false });\n console.log(` ${styleText('red', '✗')} ${server.name} - failed to add`);\n }\n }\n\n const successCount = results.filter(r => r.success).length;\n const failCount = results.filter(r => !r.success).length;\n\n console.log('');\n\n if (failCount > 0) {\n console.log(styleText('yellow', `âš ī¸ ${failCount} server(s) failed to configure`));\n }\n\n if (successCount > 0) {\n console.log(styleText('green', `✓ ${successCount} MCP server(s) configured globally for Claude Code:\\n`));\n for (const server of MCP_SERVERS) {\n const result = results.find(r => r.name === server.name);\n if (result?.success) {\n console.log(` - ${server.name}: ${server.description}`);\n }\n }\n }\n\n console.log(`\\nRun ${styleText('cyan', 'claude mcp list')} to verify.`);\n process.exit(failCount > 0 ? 1 : 0);\n};\n","#!/usr/bin/env node\nimport parseArgs from './utils/parser.js';\nimport {\n SUPPORTED_CLUSTERS,\n connectAndGetPrefix, endWithError,\n} from './utils/index.js';\nimport { fillMissingRequiredValues } from './utils/inquirer.js';\nimport { getVariationIdFromMirrodConfig } from './utils/mirrord.js';\nimport {\n mirrord,\n switchCluster,\n telepresenceWizard,\n enableSimulator,\n exposeService,\n forwardDb,\n forwardService,\n getIps,\n localDev,\n rabbitCreds,\n updateExp,\n mirrordConfig,\n dockerInit,\n openRedis,\n updateAutofleetPackages,\n mcpInit,\n} from './commands/index.js';\n\nconst clusterOptions = SUPPORTED_CLUSTERS.join('/');\nconst variationAndCluster = `--variationId=<yourVariationUuid> --cluster=<${clusterOptions}>`;\n\nconst COMMANDS = {\n switchCluster: variationAndCluster,\n exposeService: `--service=<driver-ms> ${variationAndCluster}`,\n forwardDb: `${variationAndCluster} --local-port=<localPort>`,\n forwardService: `--service=<driver-ms> ${variationAndCluster} --port=<port> --local-port=<localPort>`,\n getIps: variationAndCluster,\n enableSimulator: variationAndCluster,\n rabbitCreds: variationAndCluster,\n updateExp: variationAndCluster,\n telepresenceWizard: `--service=<driver-ms> ${variationAndCluster} --local-port=<localPort>`,\n localDev: variationAndCluster,\n mirrord: `--service=<driver-ms> ${variationAndCluster}`,\n mirrordConfig: '--variationId=<yourVariationUuid>',\n dockerInit: '',\n openRedis: '--cluster=<${clusterOptions}',\n updateAutofleetPackages: '',\n mcpInit: '',\n};\ntype Command = keyof typeof COMMANDS;\nconst isCommand = (c: string): c is Command => Object.keys(COMMANDS).includes(c);\n\nconst { positionals, values, help } = parseArgs({\n strict: true,\n binName: 'autofleet',\n allowPositionals: true,\n options: {\n cluster: {\n type: 'string',\n short: 'c',\n description: 'The cluster name. One of dev1, e2eManager, expManager',\n },\n variationId: {\n type: 'string',\n short: 'i',\n description: 'The variation id',\n },\n service: {\n type: 'string',\n short: 's',\n description: 'The service name',\n },\n port: {\n type: 'string',\n short: 'p',\n description: 'The remote port to forward',\n },\n 'local-port': {\n type: 'string',\n short: 'l',\n description: 'The local port to forward to',\n },\n 'prefer-pod': {\n type: 'boolean',\n short: 'r',\n default: false,\n description: 'Wether the mirrord command should run against the pod, rather than the deployment.',\n },\n 'dry-run': {\n type: 'boolean',\n short: 'd',\n default: false,\n description: 'Perform a dry run without installing packages',\n },\n },\n commands: COMMANDS,\n});\n\nexport type Values = typeof values;\ntype ValueWithDefault<T = keyof Values> = T | { option: T; defaultVal: string; };\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nif (positionals.length > 1) {\n endWithError('Only one command is allowed', help);\n}\n\nconst [command] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nconst COMMAND_REQUIRED_VALUES_MAP: Partial<Record<Command, ValueWithDefault[]>> = {\n switchCluster: ['cluster'],\n exposeService: ['cluster', 'variationId', 'service'],\n forwardDb: ['cluster', 'variationId', { option: 'local-port', defaultVal: '5432' }],\n forwardService: ['cluster', 'variationId', 'service', 'port'],\n telepresenceWizard: ['cluster', 'service'],\n mirrordConfig: ['variationId'],\n mirrord: ['cluster', { option: 'variationId', defaultVal: command === 'mirrord' ? await getVariationIdFromMirrodConfig() : '' }, 'service'],\n dockerInit: [],\n openRedis: ['cluster'],\n updateAutofleetPackages: [],\n mcpInit: [],\n};\n\nawait fillMissingRequiredValues(\n values,\n COMMAND_REQUIRED_VALUES_MAP[command] ?? ['cluster', 'variationId'],\n);\nconst { cluster, variationId, service } = values;\n\nswitch (command) {\n case 'mirrordConfig':\n await mirrordConfig(variationId);\n break;\n case 'dockerInit':\n await dockerInit();\n break;\n case 'updateAutofleetPackages':\n await updateAutofleetPackages(values['dry-run']);\n break;\n case 'mcpInit':\n await mcpInit();\n break;\n}\n\nif (!cluster) {\n endWithError(new Error('cluster required'), help);\n}\n\nswitch (command) {\n case 'telepresenceWizard':\n await telepresenceWizard(values);\n break;\n case 'switchCluster':\n await switchCluster(cluster, variationId);\n break;\n case 'openRedis':\n await openRedis(cluster);\n break;\n}\n\nif (!variationId) {\n endWithError(new Error('variationId required'), help);\n}\n\nlet prefix: string;\ntry {\n prefix = await connectAndGetPrefix({ clusterName: cluster, variationId });\n} catch (error) {\n endWithError(error as Error);\n}\n\nswitch (command) {\n case 'mirrord':\n await mirrord(prefix, variationId, service);\n break;\n case 'exposeService':\n await exposeService(prefix, help, service);\n break;\n case 'forwardDb':\n await forwardDb(values, prefix, variationId, help, service);\n break;\n case 'forwardService':\n await forwardService(values, prefix, help, service);\n break;\n case 'getIps':\n await getIps(prefix);\n break;\n case 'enableSimulator':\n await enableSimulator(prefix, variationId);\n break;\n case 'rabbitCreds':\n await rabbitCreds();\n break;\n case 'updateExp':\n await updateExp(prefix);\n break;\n case 'localDev':\n await localDev(prefix, cluster, variationId);\n break;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["variationId","asyncSpawn","service","prefix","variationId","cluster","asyncSpawn","asyncSpawn","values","cluster","service","service","help","asyncSpawn","prefix","values","help","variationId","service","asyncSpawn","prefix","values","service","help","asyncSpawn","prefix","asyncSpawn","prefix","asyncSpawn","prefix","variationId","asyncSpawn","serviceName: string | undefined","asyncSpawn","buildArgFlags: string[]","targetFlag: string[]","buildArgs: Record<string, string>","prefix","envNameToUse: string","cluster","variationId","asyncSpawn","prefix","variationId","path","asyncSpawn","asyncSpawn","name","asyncSpawn","packages: PackageInfo[]","majorUpdates: MajorUpdateInfo[]","path","parseArgs","mirrordConfig","dockerInit","updateAutofleetPackages","switchCluster","openRedis","prefix: string","mirrord","exposeService","forwardDb","forwardService","getIps","enableSimulator","rabbitCreds","updateExp","localDev"],"sources":["../bin/utils/mirrord.ts","../bin/utils/exitHandler.ts","../bin/commands/base/mirrord.ts","../bin/commands/base/switchCluster.ts","../bin/commands/base/telepresenceWizard.ts","../bin/commands/base/exposeService.ts","../bin/commands/base/forwardDb.ts","../bin/commands/base/forwardService.ts","../bin/commands/base/getIps.ts","../bin/commands/base/enableSimulator.ts","../bin/commands/base/rabbitCreds.ts","../bin/commands/base/updateExp.ts","../bin/utils/env.ts","../bin/commands/base/localDev.ts","../bin/commands/base/mirrordConfig.ts","../bin/commands/base/dockerInit.ts","../bin/commands/base/openRedis.ts","../bin/commands/base/updateAutofleetPackages.ts","../bin/commands/base/claude-init/index.ts","../bin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { getGitPath } from './git.js';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\n\nexport const MIRRORD_FOLDER_NAME = '.mirrord';\n\nasync function getMirrodFolderPath({ makeDir = false } = {}) {\n const repoPath = await getGitPath();\n const mirrordPath = join(repoPath, MIRRORD_FOLDER_NAME);\n if (makeDir) {\n await mkdir(mirrordPath, { recursive: true });\n }\n return join(mirrordPath, 'mirrord.json');\n}\n\nexport async function writeMirrordFile(variationId?: string) {\n const mirrordPath = await getMirrodFolderPath({ makeDir: true });\n const mirrordConfigData = {\n feature: {\n network: {\n incoming: {\n mode: 'steal',\n http_filter: {\n path_filter: '^(?!/alive)',\n },\n },\n outgoing: true,\n },\n fs: 'read',\n env: true,\n },\n target: {\n namespace: variationId || randomUUID(),\n },\n agent: {\n startup_timeout: 120,\n },\n };\n await writeFile(mirrordPath, JSON.stringify(mirrordConfigData, null, 2));\n\n return { mirrordConfigData, mirrordPath };\n}\n\nexport async function getVariationIdFromMirrodConfig() {\n try {\n const mirrordPath = await getMirrodFolderPath();\n const mirrordConfigDataString = await readFile(mirrordPath, { encoding: 'utf-8' });\n const mirrordConfigData = JSON.parse(mirrordConfigDataString || '{}') as { target?: { namespace?: string; }; };\n return mirrordConfigData?.target?.namespace ?? '';\n } catch {\n return '';\n }\n}\n","export function registerProcessForCleanup(onExit: (e?: unknown) => void | PromiseLike<void>) {\n process.once('exit', onExit);\n process.once('SIGTERM', onExit);\n process.once('SIGINT', onExit);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { registerProcessForCleanup } from '../../utils/exitHandler.js';\n\ndeclare global {\n var executedExitHooks: boolean;\n}\n\nfunction trimProbeString(str: string): string {\n str &&= str.trim();\n if (!str) {\n return str;\n }\n if (str.startsWith('\\'') && str.endsWith('\\'')) {\n str = str.slice(1, -1);\n }\n return str;\n}\n\nconst LIVENESS_PROBE = 'livenessProbe';\nconst READINESS_PROBE = 'readinessProbe';\nconst WORKER_PATH = (leaf: string) => `jsonpath='{.spec.template.spec.containers[?(@.name==\"worker\")].${leaf}}'`;\nconst SET_PROBE_VALUES = (...probeAndValues: [string, string][]) =>\n `{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"worker\",${probeAndValues\n .map(([probe, value]) => `\"${probe}\": ${value}`)\n .join(',')}}]}}}}`;\n\nexport default async (prefix: string, variationId: string, service?: string) => {\n console.log('Will now disable health check to allow debugging.');\n let [{ stdout: livenessProbe }, { stdout: readinessProbe }] = await Promise.all([\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(LIVENESS_PROBE)], { print: false }),\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(READINESS_PROBE)], { print: false }),\n ]);\n livenessProbe &&= trimProbeString(livenessProbe);\n readinessProbe &&= trimProbeString(readinessProbe);\n if (livenessProbe || readinessProbe) {\n await asyncSpawn('kubectl', ['patch', `deployment/${service}`, prefix, '--patch', SET_PROBE_VALUES([LIVENESS_PROBE, 'null'], [READINESS_PROBE, 'null'])], { print: false });\n console.log('Health check disabled, will now start mirrord and run \"npm run dev\". Make sure to attach a debugger!');\n }\n const abortController = new AbortController();\n registerProcessForCleanup(async () => {\n if (globalThis.executedExitHooks) {\n return;\n }\n globalThis.executedExitHooks = true;\n abortController.abort();\n if (livenessProbe || readinessProbe) {\n console.log('Re-enabling health check.');\n await asyncSpawn(\n 'kubectl',\n [\n 'patch',\n `deployment/${service}`,\n prefix,\n '--patch',\n `'${SET_PROBE_VALUES(\n [LIVENESS_PROBE, livenessProbe],\n [READINESS_PROBE, readinessProbe],\n )}'`,\n ],\n { print: false, shell: true },\n );\n console.log('health check enabled.');\n }\n process.exit(0);\n });\n try {\n await asyncSpawn('mirrord', ['exec', '-t', `deployment/${service}`, '-n', variationId, '--steal', 'npm', 'run', 'dev'], { signal: abortController.signal });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ABORT_ERR') {\n return;\n }\n endWithError(error as Error);\n }\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getCurrentNamespace } from '../../utils/index.js';\nimport { fillMissingRequiredValues } from '../../utils/inquirer.js';\n\nexport default async (cluster: string, variationId?: string) => {\n await connectToCluster(cluster);\n\n if (cluster === 'expManager' || cluster === 'dev1') {\n const { variationId: namespace } = await fillMissingRequiredValues({ variationId }, ['variationId']);\n if (namespace !== '') {\n if (await getCurrentNamespace() === namespace) {\n console.log(`Already connected to simulation with uuid: ${namespace}, skipping namespace switch...`);\n process.exit(0);\n }\n await asyncSpawn('kubectl', ['config', 'set-context', '--current', `--namespace=${namespace}`], { print: false });\n console.log(`Switched to simulation with uuid: ${namespace} successfully`);\n }\n }\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getVariationId, getLocalPort, safeSelect } from '../../utils/inquirer.js';\nimport { connectToCluster, endWithError } from '../../utils/index.js';\nimport type { Values } from '../../index.js';\n\nasync function ensureTelepresenceInstalled() {\n try {\n await asyncSpawn('telepresence', ['version'], { print: false });\n } catch {\n endWithError('Telepresence is not installed. Please install it from:\\nhttps://www.telepresence.io/docs/latest/quick-start/');\n }\n}\n\nfunction leaveOrConnect() {\n return safeSelect({\n message: 'Do you want to leave the connection or create a new one?',\n choices: [\n { name: 'Leave the current connection', value: 'leave' },\n { name: 'Create a new connection', value: 'connect' },\n ] as const,\n default: 'connect',\n });\n}\n\nexport default async function telepresenceWizard(values: Values): Promise<void> {\n await ensureTelepresenceInstalled();\n\n const { cluster = '', service = '' } = values; // Values should be defined by now, thanks to inquirer. Default to hint to TS we always have values.\n await connectToCluster(cluster);\n\n const action = await leaveOrConnect();\n if (!['leave', 'connect'].includes(action!)) {\n endWithError('Invalid action, how did you get here? 🤔');\n }\n if (action === 'leave') {\n await asyncSpawn('telepresence', ['leave', service]);\n console.log('Disconnected! 👋');\n return;\n }\n const namespace = values.variationId || await getVariationId();\n const localPort = (values['local-port'] && Number.parseInt(values['local-port'], 10)) || Number.parseInt((await getLocalPort()) || '', 10);\n await asyncSpawn('telepresence', ['connect', `--namespace=${namespace}`]);\n await asyncSpawn('telepresence', ['intercept', service, '--port', localPort.toString(), '--env-file=./.env']);\n console.log('Everything is set up! 🚀');\n console.log(`You can now access the service at localhost:${localPort}`);\n console.log('You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.');\n process.exit(0);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\nexport default async (prefix: string, help: string, service?: string) => {\n if (!service) {\n endWithError(new Error('service is required for exposeService'), help);\n }\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, service, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n console.log(`exposed ${service} successfully. the service is now creating an internal load balancer ip to use with vpn`);\n process.exit(0);\n};\n","import { setTimeout } from 'node:timers/promises';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, variationId: string, help: string, service?: string) => {\n const localPort = Number.parseInt(values['local-port'] ?? '5432', 10);\n if (Number.isNaN(localPort)) {\n endWithError(new Error('if defined, local-port must be a number'), help);\n }\n const DB_PASSWORD = `afpass_${variationId}`;\n const USER_NAME = 'postgres';\n const variationUnderScore = variationId.replaceAll('-', '_');\n const DB_NAME = service ? `${service.replaceAll('-', '_') || ''}_${variationUnderScore}` : 'postgres';\n\n const postgressPath = `postgres://${USER_NAME}:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?&nickname=var_${variationId}`;\n console.log(`Forwarding db to local port ${localPort}.\\naccess the DB at ${postgressPath}\\nPress ctrl+c to stop.`);\n\n const dbEnvs = ` DB_USERNAME=${USER_NAME}\n DB_PASSWORD=${DB_PASSWORD}\n DB_NAME=${service ? DB_NAME : `<service_name>_${variationUnderScore}`}`;\n console.log('Generated database environment for local development:\\n', dbEnvs);\n\n setTimeout(1500).then(() => asyncSpawn('open', [postgressPath], { print: false })).catch(() => null);\n await asyncSpawn('kubectl', [prefix, 'port-forward', `svc/p${variationId}-postgresql`, `${localPort}:5432`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n port?: string;\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, help: string, service?: string) => {\n const port = Number.parseInt(values.port ?? '8080', 10);\n const localPort = Number.parseInt(values['local-port'] ?? '', 10) || port;\n if (!service) {\n endWithError(new Error('service is required for forwardService'), help);\n }\n if (!port || Number.isNaN(port)) {\n endWithError(new Error('port is required and must be a numbers'), help);\n }\n if (localPort && Number.isNaN(localPort)) {\n endWithError(new Error('local-port must be a number'), help);\n }\n let { stdout: podName } = await asyncSpawn('kubectl', ['get', 'pods', prefix, '-l', `service=${service}`, '-o', 'jsonpath=\"{.items[0].metadata.name}\"'], { print: false });\n podName &&= podName.trim();\n if (!podName) {\n endWithError(new Error(`No pods found for service ${service}`));\n }\n if (podName.startsWith('\"') && podName.endsWith('\"')) {\n podName = podName.slice(1, -1);\n }\n console.log(`Found pod ${podName}, serving locally on port ${localPort} from remote port ${port}.\\nPress ctrl+c to stop.`);\n await asyncSpawn('kubectl', ['port-forward', prefix, podName, `${localPort}:${port}`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { parseIps } from '../../utils/index.js';\n\nexport default async (prefix: string) => {\n const { stdout } = await asyncSpawn('kubectl', [prefix, 'get', 'services'], { print: false });\n const ips = parseIps(stdout);\n ips.forEach(ip => console.log(ip));\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async (prefix: string, variationId: string) => {\n const SIMULATION_CLUSTER_FRONT = 'simulation-cluster-front';\n await asyncSpawn('kubectl', ['annotate', prefix, 'service', SIMULATION_CLUSTER_FRONT, 'cloud.google.com/load-balancer-type-']);\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, SIMULATION_CLUSTER_FRONT, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n await asyncSpawn('kubectl', ['create', prefix, 'rolebinding', 'admin', '--clusterrole=cluster-admin', `--serviceaccount=${variationId}:default`]);\n console.log(`Successfully exposed ${SIMULATION_CLUSTER_FRONT} and added role binding to dispatch simulations`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async () => {\n const getArgs = (dataKey: string) => ['get', 'secret', 'rabbitmq-default-user', '-o', `jsonpath=\"{.data.${dataKey}}\"`];\n const [{ stdout: username }, { stdout: password }] = await Promise.all([\n asyncSpawn('kubectl', getArgs('username'), { print: false }),\n asyncSpawn('kubectl', getArgs('password'), { print: false }),\n ]);\n console.log(`username: ${Buffer.from(username, 'base64').toString('ascii')}`);\n console.log(`password: ${Buffer.from(password, 'base64').toString('ascii')}`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { basename, sep } from 'node:path';\nimport { cwd } from 'node:process';\nimport { getCurrentBranch, getGitPath } from '../../utils/git.js';\nimport { getAutorepoAppName } from '../../utils/inquirer.js';\nimport { readFile } from 'node:fs/promises';\n\nexport default async (prefix: string) => {\n const gitPath = await getGitPath();\n const repoName = gitPath.split(sep).pop();\n const isAutorepo = repoName === 'autorepo';\n let serviceName: string | undefined;\n if (isAutorepo) {\n serviceName = await getAutorepoAppName(gitPath);\n if (!serviceName) {\n console.error('No service name provided, exiting...');\n process.exit(1);\n }\n } else {\n serviceName = basename(cwd());\n }\n const [branchName, archResult] = await Promise.all([getCurrentBranch(), asyncSpawn('uname', ['-m'], { print: false })]);\n const arch = archResult.stdout.trim();\n const date = new Date();\n const dateSuffix = `${date.getHours().toString().padStart(2, '0')}-${date.getMinutes().toString().padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}`;\n const imageName = `gcr.io/autofleetprod/${serviceName}:${branchName}-${dateSuffix}`;\n console.log(`Building and pushing image ${imageName}`);\n const platformFlag = arch === 'x86_64' ? [] : ['--platform', 'linux/amd64'];\n const secretFlags = ['--secret', 'id=npm_token,env=NPM_TOKEN'];\n let buildArgFlags: string[] = [];\n let targetFlag: string[] = [];\n\n if (isAutorepo) {\n const { stdout: packagesOutput } = await asyncSpawn('ls', ['-1', 'packages'], { print: false });\n const packages = packagesOutput.trim().replace(/\\n/g, ' ');\n\n const buildArgs: Record<string, string> = {\n APP: serviceName,\n PACKAGES: packages,\n BRANCH: branchName,\n };\n\n const projectJsonPath = `${gitPath}/apps/${serviceName}/project.json`;\n const projectJson = JSON.parse(await readFile(projectJsonPath, 'utf-8'));\n const tags = projectJson.tags || [];\n\n // Apps with elasticsearch tag need NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed certs\n if (tags.includes('elasticsearch')) {\n buildArgs.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n const targetBuildType = serviceName.endsWith('-ms') ? 'backend' : 'frontend';\n if (targetBuildType === 'frontend') {\n const apiSource = ['partner-admin', 'web-booker'].includes(serviceName) ? 'client' : 'api';\n buildArgs.API_SOURCE = apiSource;\n }\n\n buildArgFlags = Object.entries(buildArgs)\n .flatMap(([key, val]) => ['--build-arg', `${key}=${val}`]);\n\n targetFlag = ['--target', targetBuildType];\n }\n\n await asyncSpawn('docker', ['build', '.', '-f', 'Dockerfile', ...targetFlag, ...platformFlag, '-t', imageName, ...buildArgFlags, ...secretFlags]);\n await asyncSpawn('docker', ['push', imageName]);\n const { stdout: podDescription } = await asyncSpawn('kubectl', ['describe', 'pod', prefix, '-l', `service=${serviceName}`], { print: false });\n if (podDescription.includes('Init Containers:')) {\n await asyncSpawn('kubectl', ['patch', `deployment/${serviceName}`, prefix, '--patch', `{\"spec\": {\"template\": {\"spec\": {\"initContainers\": [{\"name\": \"init\",\"image\": \"${imageName}\"}]}}}}`]);\n }\n await asyncSpawn('kubectl', ['set', 'image', `deployment/${serviceName}`, `worker=${imageName}`, prefix]);\n await asyncSpawn('kubectl', ['rollout', 'status', 'deployments', serviceName, prefix]);\n process.exit(0);\n};\n","import { EOL } from 'node:os';\nimport { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\n\nexport async function setEnvValue(repoRoot: string, key: string, value: string): Promise<boolean> {\n const filePath = resolve(repoRoot, '.env');\n const envFileContent = await readFile(filePath, 'utf8');\n const envVars = envFileContent.split(EOL);\n\n // (?<!#\\\\s*) Negative lookbehind to avoid matching comments (lines that starts with #).\n // There is a double slash in the RegExp constructor to escape it.\n // (?==) Positive lookahead to check if there is an equal sign right after the key.\n // This is to prevent matching keys prefixed with the key of the env var to update.\n const regexString = `(?<!#\\\\s*)${key}(?==)`;\n const matchingLine = envVars.find((line: string) => line.match(regexString));\n\n if (matchingLine?.split('=').at(-1) === value) {\n return false;\n }\n\n const target = matchingLine ? envVars.indexOf(matchingLine) : -1;\n\n if (target !== -1) {\n envVars.splice(target, 1, `${key}=${value}`);\n } else {\n envVars.push(`${key}=${value}`);\n }\n\n await writeFile(filePath, envVars.join(EOL));\n return true;\n}\n","import { basename } from 'node:path';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getGitPath } from '../../utils/git.js';\nimport { endWithError } from '../../utils/index.js';\nimport { setEnvValue } from '../../utils/env.js';\n\nexport default async (prefix: string, cluster: string, variationId: string) => {\n const LOCAL_ENV_NAME = 'LOCAL_ENV_NAME';\n const API_GATEWAY_MS = 'api-gateway-ms';\n const CONTROL_CENTER_MS = 'control-center-ms';\n let envNameToUse: string;\n if (cluster.toLocaleLowerCase().includes('prod')) {\n envNameToUse = 'production';\n } else if (cluster === 'staging') {\n envNameToUse = 'staging';\n } else {\n envNameToUse = `simulator-${variationId}`;\n }\n\n const repoPath = await getGitPath();\n if (basename(repoPath) !== 'control-center') {\n endWithError(new Error('The `localDev` command must be run from the control-center repository'));\n }\n\n const apiGatewayMsIP = 'localhost:8081';\n const changedAiGatewayMsIP = await setEnvValue(repoPath, 'API_GATEWAY_MS_SERVICE_HOST', apiGatewayMsIP);\n\n if (changedAiGatewayMsIP) {\n console.log(`Updated .env file to use ${API_GATEWAY_MS} IP (${apiGatewayMsIP}).`);\n }\n\n const controlCenterMsIP = 'localhost:8085';\n const changedControlCenterIP = await setEnvValue(repoPath, 'CONTROL_CENTER_MS_SERVICE_HOST', controlCenterMsIP);\n\n if (changedControlCenterIP) {\n console.log(`Updated .env file to use ${CONTROL_CENTER_MS} IP (${controlCenterMsIP}).`);\n }\n\n const changedEnvName = await setEnvValue(repoPath, LOCAL_ENV_NAME, envNameToUse);\n\n if (changedEnvName) {\n console.log(`Updated .env file ${LOCAL_ENV_NAME} to ${envNameToUse} (used for firebase setup).`);\n }\n\n const controlCenterProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${CONTROL_CENTER_MS}`, '8085:80'], { print: false });\n const apiGatewayProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${API_GATEWAY_MS}`, '8081:80'], { print: false });\n\n console.log(`Starting port-forwarding of ${CONTROL_CENTER_MS} to port 8085`);\n console.log(`Starting port-forwarding of ${API_GATEWAY_MS} to port 8081`);\n console.log('Press Ctrl+C to stop the port-forwarding processes.');\n\n await Promise.all([controlCenterProcess, apiGatewayProcess]);\n};\n","import { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { isPathIgnored } from '../../utils/git.js';\nimport { writeMirrordFile, MIRRORD_FOLDER_NAME } from '../../utils/mirrord.js';\n\nasync function addToGitIgnore(mirrordPath: string) {\n const isIgnored = await isPathIgnored(MIRRORD_FOLDER_NAME);\n if (isIgnored) {\n return;\n }\n const gitIgnoreFile = resolve(mirrordPath, '..', '..', '.gitignore');\n const gitIgnoreFileContent = await readFile(gitIgnoreFile, 'utf8');\n const gitIgnoreFileContentLines = gitIgnoreFileContent.split('\\n').filter(Boolean);\n gitIgnoreFileContentLines.push(MIRRORD_FOLDER_NAME);\n await writeFile(gitIgnoreFile, `${gitIgnoreFileContentLines.join('\\n')}\\n`);\n}\n\nexport default async (variationId?: string) => {\n const { mirrordConfigData, mirrordPath } = await writeMirrordFile(variationId);\n await addToGitIgnore(mirrordPath);\n console.log('Wrote the default mirrord config for the requested variation ID', { mirrordConfigData });\n process.exit(0);\n};\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\n\nconst dockerComposeFile = `\nservices:\n redis:\n image: redis:6\n ports:\n - \"6379:6379\"\n volumes:\n - redis_data:/data\n command: redis-server --appendonly yes\n\n rabbitmq:\n image: rabbitmq:3.12.13-management\n ports:\n - \"5672:5672\" # AMQP protocol port\n - \"15672:15672\" # Management UI port\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n environment:\n - RABBITMQ_DEFAULT_USER=guest\n - RABBITMQ_DEFAULT_PASS=guest\n\n postgres:\n image: postgis/postgis:14-3.3\n platform: linux/amd64\n ports:\n - \"5432:5432\"\n volumes:\n - postgres_data:/var/lib/postgresql/data\n environment:\n - POSTGRES_DB=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_PASSWORD=postgres\n\n elasticsearch:\n image: docker.elastic.co/elasticsearch/elasticsearch:8.8.1\n ports:\n - \"9200:9200\"\n - \"9300:9300\"\n environment:\n - discovery.type=single-node\n - xpack.security.enabled=false\n - xpack.security.transport.ssl.enabled=false\n - xpack.security.http.ssl.enabled=false\n - ES_JAVA_OPTS=-Xms1g -Xmx1g\n volumes:\n - elasticsearch_data:/usr/share/elasticsearch/data\n ulimits:\n memlock:\n soft: -1\n hard: -1\n mem_limit: 2g\n\n kibana:\n image: docker.elastic.co/kibana/kibana:8.8.1\n ports:\n - \"5601:5601\"\n environment:\n - ELASTICSEARCH_HOSTS=http://elasticsearch:9200\n depends_on:\n - elasticsearch\n\nvolumes:\n redis_data:\n rabbitmq_data:\n postgres_data:\n elasticsearch_data:\n`;\n\nexport default async () => {\n const dockerComposePath = path.join(os.tmpdir(), 'docker-compose.yml');\n fs.writeFileSync(dockerComposePath, dockerComposeFile);\n await asyncSpawn('docker-compose', ['-f', dockerComposePath, 'up', '-d'], { print: false });\n console.log('--------------------------------------------------------------------------------');\n console.log('Successfully started the services:\\n');\n console.log('redis: localhost:6379 🚀');\n console.log('postgres: localhost:5432, user: postgres, password: postgres 🐘');\n console.log('rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇');\n console.log('elasticsearch: localhost:9200 ❓');\n console.log('kibana: http://localhost:5601 ❓');\n process.exit(0);\n};\n","import { spawn } from 'node:child_process';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getRedisRegion, isSimulationCluster } from '../../utils/index.js';\nimport { safeSelect } from '../../utils/inquirer.js';\nimport { createDeferredPromise } from '../../utils/promise.js';\n\ninterface RedisInstance {\n displayName?: string;\n host: string;\n name: string;\n}\n\nexport default async (clusterName: string) => {\n if (isSimulationCluster(clusterName)) {\n console.error('Connecting to Redis is not supported for simulation clusters (need to be added)');\n process.exit(1);\n }\n\n const {\n project,\n name,\n } = await connectToCluster(clusterName);\n const redisRegion = getRedisRegion(clusterName);\n const { stdout: redisInstances } = await asyncSpawn('gcloud', ['redis', 'instances', 'list', '--region', redisRegion, '--project', project || name, '--format', 'json'], { print: false });\n let redisInstancesJson;\n try {\n redisInstancesJson = JSON.parse(redisInstances) as RedisInstance[];\n } catch (e) {\n console.error('Failed to parse redis instances', { redisInstances, e });\n process.exit(1);\n }\n\n const redisNameToIpMap = Object.fromEntries(redisInstancesJson.map((instance: RedisInstance) => {\n const redisPath = instance.name.split('/');\n return [instance.displayName || redisPath?.at(-1) || instance.name, instance.host];\n }));\n\n const redisIp = await safeSelect({\n message: 'which redis instance do you want to connect to?',\n choices: Object.entries(redisNameToIpMap).map(([name, ip]) => ({ name, value: ip })),\n default: Object.keys(redisNameToIpMap)[0],\n });\n\n if (!redisIp) {\n console.error('No redis instance selected');\n process.exit(1);\n }\n\n const { stdout: allPodsName } = await asyncSpawn('kubectl', ['get', 'pods', '--no-headers', '-o', 'custom-columns=:metadata.name'], { print: false });\n const redisPodName = allPodsName.split('\\n').find(podName => podName.includes('redis'));\n\n if (!redisPodName?.trim()) {\n console.error('No redis pod found');\n process.exit(1);\n }\n\n try {\n const { promise, resolve, reject } = createDeferredPromise<void>();\n const shell = spawn('kubectl', [\n 'exec',\n '-it',\n redisPodName,\n '--',\n 'redis-cli',\n '-h',\n redisIp,\n ], {\n stdio: 'inherit',\n shell: true,\n });\n shell.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n shell.on('error', (error) => {\n console.error('Process error:', error);\n reject(error);\n });\n\n console.log('Connecting to Redis... Could take a few seconds âąī¸');\n\n await promise;\n\n process.exit(0);\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n process.exit(1);\n }\n};\n","import { readFile } from 'node:fs/promises';\nimport { cwd } from 'node:process';\nimport { join } from 'node:path';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { confirm } from '@inquirer/prompts';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface PackageInfo {\n name: string;\n currentVersion: string;\n latestVersion: string;\n isDev: boolean;\n}\n\ninterface MajorUpdateInfo {\n name: string;\n fromMajor: number;\n toMajor: number;\n currentVersion: string;\n latestVersion: string;\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', packageName, 'version'], { print: false });\n return stdout.trim();\n } catch (_error) {\n console.error(`Failed to get latest version for ${packageName}:`, _error);\n throw _error;\n }\n}\n\nasync function getPeerDependencies(packageName: string, version: string): Promise<Record<string, string> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependencies', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function getPeerDependenciesMeta(packageName: string, version: string): Promise<Record<string, { optional?: boolean; }> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependenciesMeta', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nfunction parseVersion(version: string): string {\n return version.replace(/^[\\^~]/, '');\n}\n\nfunction getMajorVersion(version: string): number {\n const cleaned = parseVersion(version);\n const regex = /^(\\d+)/;\n const match = regex.exec(cleaned);\n return match ? parseInt(match[1], 10) : 0;\n}\n\nfunction isMajorUpdate(currentVersion: string, latestVersion: string): boolean {\n const currentMajor = getMajorVersion(currentVersion);\n const latestMajor = getMajorVersion(latestVersion);\n return latestMajor > currentMajor;\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const packageJsonPath = join(cwd(), 'package.json');\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return endWithError(new Error(`Failed to read package.json at ${packageJsonPath}`));\n }\n}\n\nfunction getAutofleetPackages(packageJson: PackageJson): PackageInfo[] {\n const packages: PackageInfo[] = [];\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: false });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(packageJson.devDependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: true });\n }\n }\n }\n\n return packages;\n}\n\nexport default async (dryRun = false) => {\n if (dryRun) {\n console.log(styleText('yellow', '[DRY RUN MODE] - No packages will be installed') + '\\n');\n }\n console.log('Scanning for @autofleet packages...\\n');\n\n const packageJson = await readPackageJson();\n const autofleetPackages = getAutofleetPackages(packageJson);\n\n if (autofleetPackages.length === 0) {\n console.log('No @autofleet packages found in this repository.');\n process.exit(0);\n }\n\n console.log(`Found ${autofleetPackages.length} @autofleet package(s):\\n`);\n autofleetPackages.forEach((pkg) => {\n console.log(` - ${pkg.name} (${pkg.currentVersion})`);\n });\n console.log('');\n\n console.log('Fetching latest versions...\\n');\n\n // Fetch latest versions\n for (const pkg of autofleetPackages) {\n try {\n pkg.latestVersion = await getLatestVersion(pkg.name);\n } catch {\n endWithError(new Error(`Failed to fetch latest version for ${pkg.name}`));\n }\n }\n\n // Check for packages that are already up to date\n const packagesToUpdate = autofleetPackages.filter(\n pkg => parseVersion(pkg.currentVersion) !== pkg.latestVersion,\n );\n\n if (packagesToUpdate.length === 0) {\n console.log('All @autofleet packages are already up to date!');\n process.exit(0);\n }\n\n // Identify major version updates\n const majorUpdates: MajorUpdateInfo[] = [];\n\n for (const pkg of packagesToUpdate) {\n if (isMajorUpdate(pkg.currentVersion, pkg.latestVersion)) {\n majorUpdates.push({\n name: pkg.name,\n fromMajor: getMajorVersion(pkg.currentVersion),\n toMajor: getMajorVersion(pkg.latestVersion),\n currentVersion: parseVersion(pkg.currentVersion),\n latestVersion: pkg.latestVersion,\n });\n }\n }\n\n // Show major version update warning\n if (majorUpdates.length > 0) {\n console.log(styleText('yellow', 'âš ī¸ WARNING: The following packages have major version updates:') + '\\n');\n for (const update of majorUpdates) {\n console.log(` - ${update.name}: v${update.fromMajor}.x.x → v${update.toMajor}.x.x (${update.currentVersion} → ${update.latestVersion})`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldContinue = await confirm({\n message: 'Major version updates may contain breaking changes. Do you want to continue?',\n default: true,\n });\n\n if (!shouldContinue) {\n console.log('Aborting package updates.');\n process.exit(0);\n }\n console.log('');\n }\n }\n\n // Show packages to update\n console.log('The following packages will be updated:\\n');\n for (const pkg of packagesToUpdate) {\n const isMajor = majorUpdates.some(b => b.name === pkg.name);\n const marker = isMajor ? styleText('yellow', '(major)') : '';\n console.log(` - ${pkg.name}: ${parseVersion(pkg.currentVersion)} → ${pkg.latestVersion} ${marker}`);\n }\n console.log('');\n\n // Collect all peer dependencies\n const missingRequiredPeerDeps = new Map<string, string>();\n const missingOptionalPeerDeps = new Map<string, string>();\n\n console.log('Checking peer dependencies...\\n');\n for (const pkg of packagesToUpdate) {\n const [peerDeps, peerDepsMeta] = await Promise.all([\n getPeerDependencies(pkg.name, pkg.latestVersion),\n getPeerDependenciesMeta(pkg.name, pkg.latestVersion),\n ]);\n\n if (peerDeps) {\n for (const [peerName, peerVersion] of Object.entries(peerDeps)) {\n // Check if peer dependency is already in package.json\n const currentPeerVersion\n = packageJson.dependencies?.[peerName]\n || packageJson.devDependencies?.[peerName];\n\n if (!currentPeerVersion) {\n // Check if this peer dependency is optional\n const isOptional = peerDepsMeta?.[peerName]?.optional === true;\n if (isOptional) {\n missingOptionalPeerDeps.set(peerName, peerVersion);\n } else {\n missingRequiredPeerDeps.set(peerName, peerVersion);\n }\n }\n }\n }\n }\n\n // Handle missing required peer dependencies\n if (missingRequiredPeerDeps.size > 0) {\n console.log(styleText('yellow', 'âš ī¸ The following peer dependencies are required but not installed:') + '\\n');\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n console.log(` - ${name}@${version}`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldInstallPeers = await confirm({\n message: 'Do you want to install these peer dependencies?',\n default: true,\n });\n\n if (!shouldInstallPeers) {\n console.log(styleText('red', 'âš ī¸ Warning: Skipping peer dependencies may cause issues.'));\n } else {\n // Add to packages to update\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n console.log('');\n } else {\n console.log(styleText('yellow', '[DRY RUN] Would prompt to install required peer dependencies') + '\\n');\n }\n }\n\n // Handle missing optional peer dependencies\n if (missingOptionalPeerDeps.size > 0) {\n console.log(styleText('cyan', 'â„šī¸ The following optional peer dependencies are not installed:') + '\\n');\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n console.log(` - ${name}@${version} ${styleText('dim', '(optional)')}`);\n }\n console.log('');\n\n if (!dryRun) {\n const shouldInstallOptionalPeers = await confirm({\n message: 'Do you want to install these optional peer dependencies?',\n default: false,\n });\n\n if (shouldInstallOptionalPeers) {\n // Add to packages to update\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n console.log('');\n } else {\n console.log(styleText('yellow', '[DRY RUN] Would prompt to install optional peer dependencies') + '\\n');\n }\n }\n\n if (dryRun) {\n console.log(styleText('yellow', '[DRY RUN] Would install the following packages:') + '\\n');\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n packagesToInstall.forEach((pkg) => {\n console.log(` - ${pkg}`);\n });\n console.log('\\n' + styleText('yellow', '[DRY RUN] Would run: npm dedupe'));\n console.log('\\n' + styleText('green', '✓ Dry run completed successfully!'));\n process.exit(0);\n }\n\n console.log('Installing packages...\\n');\n\n // Install packages\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n\n try {\n await asyncSpawn('npm', ['install', ...packagesToInstall], { print: true });\n } catch {\n endWithError(new Error('Failed to install packages'));\n }\n\n console.log('\\nDeduplicating packages...\\n');\n\n try {\n await asyncSpawn('npm', ['dedupe'], { print: true });\n } catch {\n console.error(styleText('yellow', 'âš ī¸ Warning: Failed to deduplicate packages'));\n }\n\n console.log('\\n' + styleText('green', '✓ All @autofleet packages have been updated successfully!'));\n process.exit(0);\n};\n","import { execSync } from 'node:child_process';\nimport * as path from 'node:path';\nimport fs from 'node:fs';\n\nconst __dirname = import.meta.dirname;\n\nconst isPluginInstalled = (pluginIdentifier: string): boolean => {\n try {\n const output = execSync('claude plugin list', { encoding: 'utf-8' });\n return output.includes(`${pluginIdentifier}`);\n } catch {\n return false;\n }\n};\n\nconst addMarketplace = (marketplacePath: string): void => {\n console.log('đŸ“Ĩ Adding Autofleet marketplace...');\n try {\n execSync(`claude plugin marketplace remove autofleet`, { stdio: 'pipe' });\n } catch {\n // Marketplace might not exist, that's fine\n }\n try {\n execSync(`claude plugin marketplace add ${marketplacePath}`, { stdio: 'pipe' });\n console.log('✓ Marketplace added\\n');\n } catch {\n console.log('âš ī¸ Failed to add marketplace\\n');\n process.exit(1);\n }\n};\n\nconst bumpPluginVersion = (distPluginJsonPath: string, sourcePluginJsonPath: string): void => {\n const distPluginJson = JSON.parse(fs.readFileSync(distPluginJsonPath, 'utf-8'));\n const [major, minor, patch] = distPluginJson.version.split('.').map(Number);\n const newVersion = `${major}.${minor}.${patch + 1}`;\n\n distPluginJson.version = newVersion;\n fs.writeFileSync(distPluginJsonPath, JSON.stringify(distPluginJson, null, 2) + '\\n');\n\n if (fs.existsSync(sourcePluginJsonPath)) {\n const sourcePluginJson = JSON.parse(fs.readFileSync(sourcePluginJsonPath, 'utf-8'));\n sourcePluginJson.version = newVersion;\n fs.writeFileSync(sourcePluginJsonPath, JSON.stringify(sourcePluginJson, null, 2) + '\\n');\n }\n};\n\nconst installOrUpdatePlugin = (pluginIdentifier: string, marketplacePath: string): void => {\n if (!isPluginInstalled(pluginIdentifier)) {\n try {\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('âš ī¸ Failed to install plugin\\n');\n process.exit(1);\n }\n }\n\n console.log('â„šī¸ Plugin already installed, reinstalling to get latest version...');\n try {\n const distPluginJsonPath = path.join(marketplacePath, 'plugins/autofleet/.claude-plugin/plugin.json');\n const sourcePluginJsonPath = path.resolve(__dirname, '../bin/commands/base/claude-init/claude-marketplace/plugins/autofleet/.claude-plugin/plugin.json');\n bumpPluginVersion(distPluginJsonPath, sourcePluginJsonPath);\n execSync(`claude plugin remove ${pluginIdentifier}`, { stdio: 'pipe' });\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('âš ī¸ Failed to reinstall plugin\\n');\n process.exit(1);\n }\n};\n\nexport default () => {\n console.log('🚀 Setting up Autofleet Claude Code plugin...\\n');\n const marketplacePath = path.resolve(__dirname, './claude-marketplace');\n\n addMarketplace(marketplacePath);\n installOrUpdatePlugin('autofleet@autofleet', marketplacePath);\n\n console.log('🎉 Plugin setup complete!\\n');\n process.exit(0);\n};\n","#!/usr/bin/env node\nimport parseArgs from './utils/parser.js';\nimport {\n SUPPORTED_CLUSTERS,\n connectAndGetPrefix, endWithError,\n} from './utils/index.js';\nimport { fillMissingRequiredValues } from './utils/inquirer.js';\nimport { getVariationIdFromMirrodConfig } from './utils/mirrord.js';\nimport {\n mirrord,\n switchCluster,\n telepresenceWizard,\n enableSimulator,\n exposeService,\n forwardDb,\n forwardService,\n getIps,\n localDev,\n rabbitCreds,\n updateExp,\n mirrordConfig,\n dockerInit,\n openRedis,\n updateAutofleetPackages,\n claudeInit,\n} from './commands/index.js';\n\nconst clusterOptions = SUPPORTED_CLUSTERS.join('/');\nconst variationAndCluster = `--variationId=<yourVariationUuid> --cluster=<${clusterOptions}>`;\n\nconst COMMANDS = {\n switchCluster: variationAndCluster,\n exposeService: `--service=<driver-ms> ${variationAndCluster}`,\n forwardDb: `${variationAndCluster} --local-port=<localPort>`,\n forwardService: `--service=<driver-ms> ${variationAndCluster} --port=<port> --local-port=<localPort>`,\n getIps: variationAndCluster,\n enableSimulator: variationAndCluster,\n rabbitCreds: variationAndCluster,\n updateExp: variationAndCluster,\n telepresenceWizard: `--service=<driver-ms> ${variationAndCluster} --local-port=<localPort>`,\n localDev: variationAndCluster,\n mirrord: `--service=<driver-ms> ${variationAndCluster}`,\n mirrordConfig: '--variationId=<yourVariationUuid>',\n dockerInit: '',\n openRedis: '--cluster=<${clusterOptions}',\n updateAutofleetPackages: '',\n claudeInit: '',\n};\ntype Command = keyof typeof COMMANDS;\nconst isCommand = (c: string): c is Command => Object.keys(COMMANDS).includes(c);\n\nconst { positionals, values, help } = parseArgs({\n strict: true,\n binName: 'autofleet',\n allowPositionals: true,\n options: {\n cluster: {\n type: 'string',\n short: 'c',\n description: 'The cluster name. One of dev1, e2eManager, expManager',\n },\n variationId: {\n type: 'string',\n short: 'i',\n description: 'The variation id',\n },\n service: {\n type: 'string',\n short: 's',\n description: 'The service name',\n },\n port: {\n type: 'string',\n short: 'p',\n description: 'The remote port to forward',\n },\n 'local-port': {\n type: 'string',\n short: 'l',\n description: 'The local port to forward to',\n },\n 'prefer-pod': {\n type: 'boolean',\n short: 'r',\n default: false,\n description: 'Wether the mirrord command should run against the pod, rather than the deployment.',\n },\n 'dry-run': {\n type: 'boolean',\n short: 'd',\n default: false,\n description: 'Perform a dry run without installing packages',\n },\n },\n commands: COMMANDS,\n});\n\nexport type Values = typeof values;\ntype ValueWithDefault<T = keyof Values> = T | { option: T; defaultVal: string; };\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nif (positionals.length > 1) {\n endWithError('Only one command is allowed', help);\n}\n\nconst [command] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nconst COMMAND_REQUIRED_VALUES_MAP: Partial<Record<Command, ValueWithDefault[]>> = {\n switchCluster: ['cluster'],\n exposeService: ['cluster', 'variationId', 'service'],\n forwardDb: ['cluster', 'variationId', { option: 'local-port', defaultVal: '5432' }],\n forwardService: ['cluster', 'variationId', 'service', 'port'],\n telepresenceWizard: ['cluster', 'service'],\n mirrordConfig: ['variationId'],\n mirrord: ['cluster', { option: 'variationId', defaultVal: command === 'mirrord' ? await getVariationIdFromMirrodConfig() : '' }, 'service'],\n dockerInit: [],\n openRedis: ['cluster'],\n updateAutofleetPackages: [],\n claudeInit: [],\n};\n\nawait fillMissingRequiredValues(\n values,\n COMMAND_REQUIRED_VALUES_MAP[command] ?? ['cluster', 'variationId'],\n);\nconst { cluster, variationId, service } = values;\n\nswitch (command) {\n case 'mirrordConfig':\n await mirrordConfig(variationId);\n break;\n case 'dockerInit':\n await dockerInit();\n break;\n case 'updateAutofleetPackages':\n await updateAutofleetPackages(values['dry-run']);\n break;\n case 'claudeInit':\n claudeInit();\n break;\n}\n\nif (!cluster) {\n endWithError(new Error('cluster required'), help);\n}\n\nswitch (command) {\n case 'telepresenceWizard':\n await telepresenceWizard(values);\n break;\n case 'switchCluster':\n await switchCluster(cluster, variationId);\n break;\n case 'openRedis':\n await openRedis(cluster);\n break;\n}\n\nif (!variationId) {\n endWithError(new Error('variationId required'), help);\n}\n\nlet prefix: string;\ntry {\n prefix = await connectAndGetPrefix({ clusterName: cluster, variationId });\n} catch (error) {\n endWithError(error as Error);\n}\n\nswitch (command) {\n case 'mirrord':\n await mirrord(prefix, variationId, service);\n break;\n case 'exposeService':\n await exposeService(prefix, help, service);\n break;\n case 'forwardDb':\n await forwardDb(values, prefix, variationId, help, service);\n break;\n case 'forwardService':\n await forwardService(values, prefix, help, service);\n break;\n case 'getIps':\n await getIps(prefix);\n break;\n case 'enableSimulator':\n await enableSimulator(prefix, variationId);\n break;\n case 'rabbitCreds':\n await rabbitCreds();\n break;\n case 'updateExp':\n await updateExp(prefix);\n break;\n case 'localDev':\n await localDev(prefix, cluster, variationId);\n break;\n}\n"],"mappings":"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"}