@teambit/ripple 0.0.0-052dba832e4972e600830470de534854eb544af9

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.
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_chalk","data","_interopRequireDefault","require","_cliTable","_rippleUtils","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","RippleCmd","constructor","report","code","exports","RippleListCmd","ripple","args","flags","jobs","ownerUsed","getFilteredJobs","length","hint","lane","scope","tip","chalk","yellow","table","Table","head","cyan","chars","top","bottom","left","mid","right","middle","style","job","push","id","truncate","name","getScopeFromLaneId","laneId","colorPhase","status","phase","user","username","formatDate","startedAt","formatDuration","finishedAt","header","gray","toString","filter","Boolean","join","json","requestedLimit","limit","parseInt","isFinite","Error","filters","all","owner","getDefaultOwner","owners","lanes","scopes","toUpperCase","needsClientFilter","fetchLimit","Math","max","listJobs","userFilter","toLowerCase","j","includes","slice","RippleLogCmd","description","resolveJob","jobId","getJob","getCurrentLaneId","found","findLatestJobForLane","red","lines","bold","displayName","Date","toLocaleString","jobUrl","getJobUrl","component","appendComponentDetail","appendComponentList","componentId","summary","getComponentBuildSummary","tasks","task","startTime","warnings","ciNodes","getCiGraphNodes","totalComponents","reduce","sum","n","componentIds","shown","node","compId","icon","isFailedPhase","green","componentBuild","RippleErrorsCmd","getErrors","failedNodes","succeededNodes","otherNodes","failedComponents","flatMap","blockedComponents","containerNames","map","containerName","logMap","getContainerLogs","compList","logMessages","get","errorLines","log","extractErrorsFromLog","msg","clean","stripAnsi","test","succeededCount","error","containerLogs","messages","RippleRetryCmd","resolved","resolveJobId","allowedPhases","actionVerb","result","retryJob","RippleStopCmd","stopJob","dateStr","start","getTime","end","now","ms","seconds","floor","minutes","remainingSeconds","hours","remainingMinutes","split","str","substring"],"sources":["ripple.cmd.ts"],"sourcesContent":["import type { Command, CommandOptions } from '@teambit/cli';\nimport chalk from 'chalk';\nimport Table from 'cli-table';\nimport type { RippleMain, RippleJob, CiGraphNode } from './ripple.main.runtime';\nimport { colorPhase, isFailedPhase, stripAnsi, resolveJobId } from './ripple-utils';\n\nexport class RippleCmd implements Command {\n name = 'ripple <sub-command>';\n description = 'manage Ripple CI jobs on bit.cloud';\n extendedDescription = 'view, retry, and manage Ripple CI jobs that build your components in the cloud after export.';\n group = 'collaborate';\n skipWorkspace = true;\n remoteOp = true;\n\n options: CommandOptions = [];\n commands: Command[] = [];\n\n async report() {\n return { code: 1, data: '[ripple] please specify a subcommand. See --help for available commands.' };\n }\n}\n\nexport class RippleListCmd implements Command {\n name = 'list';\n description = 'list recent Ripple CI jobs (filtered by workspace owner by default)';\n skipWorkspace = true;\n remoteOp = true;\n alias = '';\n\n options: CommandOptions = [\n ['', 'all', 'show jobs from all owners, not just the workspace owner'],\n ['o', 'owner <owner>', 'filter by organization (default: detected from workspace defaultScope)'],\n ['s', 'scope <scope>', 'filter by scope (e.g. \"teambit.cloud\")'],\n ['', 'lane <lane>', 'filter by lane ID (e.g. \"scope/lane-name\")'],\n ['u', 'user <user>', 'filter by username'],\n ['', 'status <status>', 'filter by status (e.g. SUCCESS, FAILURE, RUNNING)'],\n ['l', 'limit <limit>', 'max number of jobs to show (default: 20)'],\n ['j', 'json', 'return the output as JSON'],\n ];\n\n constructor(private ripple: RippleMain) {}\n\n async report(\n args: [],\n flags: {\n all?: boolean;\n owner?: string;\n scope?: string;\n lane?: string;\n user?: string;\n status?: string;\n limit?: string;\n }\n ) {\n const { jobs, ownerUsed } = await this.getFilteredJobs(flags);\n\n if (!jobs || jobs.length === 0) {\n let hint = '';\n if (flags.lane) hint = ` for lane \"${flags.lane}\"`;\n else if (flags.scope) hint = ` for scope \"${flags.scope}\"`;\n else if (ownerUsed) hint = ` for owner \"${ownerUsed}\"`;\n const tip = ownerUsed ? ' Use --all to see jobs from all owners.' : '';\n return chalk.yellow(`No Ripple CI jobs found${hint}.${tip}`);\n }\n\n const table = new Table({\n head: [\n chalk.cyan('Job ID'),\n chalk.cyan('Name'),\n chalk.cyan('Scope'),\n chalk.cyan('Status'),\n chalk.cyan('User'),\n chalk.cyan('Started'),\n chalk.cyan('Duration'),\n ],\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n middle: ' ',\n },\n style: { 'padding-left': 1, 'padding-right': 1 },\n });\n\n for (const job of jobs) {\n table.push([\n job.id,\n truncate(job.name || '-', 40),\n getScopeFromLaneId(job.laneId),\n colorPhase(job.status?.phase),\n job.user?.username || '-',\n formatDate(job.status?.startedAt),\n formatDuration(job.status?.startedAt, job.status?.finishedAt),\n ]);\n }\n\n const header = ownerUsed ? chalk.gray(`showing jobs for owner \"${ownerUsed}\" (use --all for all jobs)`) : '';\n return [header, table.toString()].filter(Boolean).join('\\n');\n }\n\n async json(\n args: [],\n flags: {\n all?: boolean;\n owner?: string;\n scope?: string;\n lane?: string;\n user?: string;\n status?: string;\n limit?: string;\n }\n ) {\n const { jobs } = await this.getFilteredJobs(flags);\n return { jobs: jobs || [] };\n }\n\n private async getFilteredJobs(flags: {\n all?: boolean;\n owner?: string;\n scope?: string;\n lane?: string;\n user?: string;\n status?: string;\n limit?: string;\n }): Promise<{ jobs: RippleJob[]; ownerUsed?: string }> {\n const requestedLimit = flags.limit ? parseInt(flags.limit, 10) : 20;\n if (!Number.isFinite(requestedLimit) || requestedLimit < 1) {\n throw new Error(`Invalid --limit value \"${flags.limit}\". Expected a positive integer.`);\n }\n\n // build server-side filters\n const filters: { lanes?: string[]; owners?: string[]; scopes?: string[]; status?: string } = {};\n\n // determine owner for default filtering (skip when --lane or --scope is given explicitly)\n let ownerUsed: string | undefined;\n if (!flags.all && !flags.lane && !flags.scope) {\n ownerUsed = flags.owner || this.ripple.getDefaultOwner();\n } else if (flags.owner) {\n ownerUsed = flags.owner;\n }\n\n if (ownerUsed) filters.owners = [ownerUsed];\n if (flags.lane) filters.lanes = [flags.lane];\n if (flags.scope) filters.scopes = [flags.scope];\n if (flags.status) filters.status = flags.status.toUpperCase();\n\n // user filter is not supported server-side, so overfetch if needed\n const needsClientFilter = !!flags.user;\n const fetchLimit = needsClientFilter ? Math.max(requestedLimit * 5, 100) : requestedLimit;\n let jobs = await this.ripple.listJobs({ filters, limit: fetchLimit });\n\n // apply client-side filters for fields not supported by FilterOptions\n if (flags.user) {\n const userFilter = flags.user.toLowerCase();\n jobs = jobs.filter((j) => j.user?.username?.toLowerCase().includes(userFilter));\n }\n\n jobs = jobs.slice(0, requestedLimit);\n\n return { jobs, ownerUsed };\n }\n}\n\nexport class RippleLogCmd implements Command {\n name = 'log [job-id]';\n description = 'show job details and component build task summaries (auto-detects current lane when no job-id given)';\n skipWorkspace = true;\n remoteOp = true;\n alias = '';\n\n options: CommandOptions = [\n ['', 'lane <lane>', 'lane ID to find the latest job for (default: detected from .bitmap)'],\n ['c', 'component <component>', 'show build tasks for a specific component (full component ID)'],\n ['j', 'json', 'return the output as JSON'],\n ];\n\n arguments = [{ name: 'job-id', description: 'the Ripple CI job ID (optional — auto-detects from current lane)' }];\n\n constructor(private ripple: RippleMain) {}\n\n private async resolveJob(jobId: string | undefined, flags: { lane?: string }) {\n if (jobId) {\n return this.ripple.getJob(jobId);\n }\n const laneId = flags.lane || this.ripple.getCurrentLaneId();\n if (!laneId) return null;\n const found = await this.ripple.findLatestJobForLane(laneId);\n return found ? this.ripple.getJob(found.id) : null;\n }\n\n async report([jobId]: [string], flags: { lane?: string; component?: string }) {\n const job = await this.resolveJob(jobId, flags);\n if (!job) {\n if (!jobId) {\n const laneId = flags.lane || this.ripple.getCurrentLaneId();\n if (laneId) {\n return chalk.red(`No Ripple CI job found for lane \"${laneId}\".`);\n }\n return chalk.red(\n 'Could not find a Ripple CI job. Provide a job ID, use --lane, or run from a workspace on a lane.'\n );\n }\n return chalk.red(`Job \"${jobId}\" not found.`);\n }\n\n const lines: string[] = [];\n lines.push(chalk.bold('Job Details'));\n lines.push(` ${chalk.cyan('ID:')} ${job.id}`);\n if (job.name) lines.push(` ${chalk.cyan('Name:')} ${job.name}`);\n lines.push(` ${chalk.cyan('Status:')} ${colorPhase(job.status?.phase)}`);\n if (job.laneId) lines.push(` ${chalk.cyan('Lane:')} ${job.laneId}`);\n if (job.user?.displayName)\n lines.push(` ${chalk.cyan('User:')} ${job.user.displayName} (${job.user.username})`);\n if (job.status?.startedAt)\n lines.push(` ${chalk.cyan('Started:')} ${new Date(job.status.startedAt).toLocaleString()}`);\n if (job.status?.finishedAt)\n lines.push(` ${chalk.cyan('Finished:')} ${new Date(job.status.finishedAt).toLocaleString()}`);\n const jobUrl = this.ripple.getJobUrl(job);\n lines.push(` ${chalk.cyan('URL:')} ${jobUrl}`);\n\n if (flags.component) {\n await this.appendComponentDetail(lines, job.id, flags.component);\n } else {\n this.appendComponentList(lines, job);\n }\n\n return lines.join('\\n');\n }\n\n private async appendComponentDetail(lines: string[], jobId: string, componentId: string) {\n const summary = await this.ripple.getComponentBuildSummary(jobId, componentId);\n if (!summary) {\n lines.push('');\n lines.push(chalk.yellow(`No build summary found for component \"${componentId}\" in this job.`));\n return;\n }\n lines.push('');\n lines.push(chalk.bold(`Build Tasks for ${summary.name || componentId}`));\n if (!summary.tasks || summary.tasks.length === 0) {\n lines.push(chalk.gray(' No build tasks found.'));\n return;\n }\n const table = new Table({\n head: [chalk.cyan('Task'), chalk.cyan('Status'), chalk.cyan('Started'), chalk.cyan('Warnings')],\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n middle: ' ',\n },\n style: { 'padding-left': 1, 'padding-right': 1 },\n });\n for (const task of summary.tasks) {\n table.push([\n task.name || '-',\n colorPhase(task.status?.status),\n task.startTime ? new Date(task.startTime).toLocaleString() : '-',\n task.status?.warnings ? chalk.yellow(String(task.status.warnings)) : '0',\n ]);\n }\n lines.push(table.toString());\n }\n\n private appendComponentList(lines: string[], job: { ciGraph?: string }) {\n const ciNodes = this.ripple.getCiGraphNodes(job);\n if (ciNodes.length === 0) return;\n const totalComponents = ciNodes.reduce((sum, n) => sum + n.componentIds.length, 0);\n lines.push('');\n lines.push(chalk.bold(`Components (${totalComponents})`));\n lines.push(chalk.gray(' Use --component <id> to see build tasks for a specific component'));\n let shown = 0;\n for (const node of ciNodes) {\n if (shown >= 30) {\n lines.push(chalk.gray(` ... and ${totalComponents - shown} more`));\n break;\n }\n for (const compId of node.componentIds) {\n if (shown >= 30) break;\n const icon = isFailedPhase(node.phase)\n ? chalk.red('✗')\n : node.phase === 'SUCCESS'\n ? chalk.green('✓')\n : chalk.yellow('○');\n lines.push(` ${icon} ${compId}`);\n shown++;\n }\n }\n }\n\n async json([jobId]: [string], flags: { lane?: string; component?: string }) {\n const job = await this.resolveJob(jobId, flags);\n if (flags.component && job) {\n const summary = await this.ripple.getComponentBuildSummary(job.id, flags.component);\n return { job, componentBuild: summary };\n }\n return { job };\n }\n}\n\nexport class RippleErrorsCmd implements Command {\n name = 'errors [job-id]';\n description = 'show build errors for a Ripple CI job (auto-detects current lane when no job-id given)';\n skipWorkspace = true;\n remoteOp = true;\n alias = '';\n\n options: CommandOptions = [\n ['', 'lane <lane>', 'lane ID to find the latest failed job for (default: detected from .bitmap)'],\n ['', 'log', 'show full build log for failed containers (not just the error summary)'],\n ['j', 'json', 'return the output as JSON'],\n ];\n\n arguments = [{ name: 'job-id', description: 'the Ripple CI job ID (optional — auto-detects from current lane)' }];\n\n constructor(private ripple: RippleMain) {}\n\n async report([jobId]: [string], flags: { lane?: string; log?: boolean }) {\n const { job, ciNodes } = await this.getErrors(jobId, flags);\n\n if (!job) {\n if (jobId) {\n return chalk.red(`Job \"${jobId}\" not found.`);\n }\n const laneId = flags.lane || this.ripple.getCurrentLaneId();\n if (laneId) {\n return chalk.red(`No failed Ripple CI job found for lane \"${laneId}\".`);\n }\n return chalk.red(\n 'Could not find a Ripple CI job. Provide a job ID, use --lane, or run from a workspace on a lane.'\n );\n }\n\n const lines: string[] = [];\n lines.push(chalk.bold(`Ripple CI Errors — ${job.name || job.id}`));\n lines.push(` ${chalk.cyan('Job ID:')} ${job.id}`);\n lines.push(` ${chalk.cyan('Status:')} ${colorPhase(job.status?.phase)}`);\n if (job.laneId) lines.push(` ${chalk.cyan('Lane:')} ${job.laneId}`);\n lines.push(` ${chalk.cyan('URL:')} ${this.ripple.getJobUrl(job)}`);\n\n if (ciNodes.length === 0) {\n lines.push('');\n lines.push(chalk.yellow('Could not determine which components are in this job.'));\n return lines.join('\\n');\n }\n\n const failedNodes = ciNodes.filter((n) => isFailedPhase(n.phase));\n const succeededNodes = ciNodes.filter((n) => n.phase === 'SUCCESS');\n const otherNodes = ciNodes.filter((n) => !isFailedPhase(n.phase) && n.phase !== 'SUCCESS');\n\n const totalComponents = ciNodes.reduce((sum, n) => sum + n.componentIds.length, 0);\n const failedComponents = failedNodes.flatMap((n) => n.componentIds);\n const blockedComponents = otherNodes.flatMap((n) => n.componentIds);\n\n if (failedComponents.length === 0) {\n if (job.status?.phase?.toUpperCase() === 'FAILURE') {\n lines.push('');\n lines.push(\n chalk.yellow(`${totalComponents} component(s) in this job — no individual component failures found.`)\n );\n lines.push(chalk.yellow('The failure may be in a pipeline-level step. Check the Ripple CI URL above.'));\n } else {\n lines.push('');\n lines.push(chalk.green(`All ${totalComponents} component(s) built successfully.`));\n }\n return lines.join('\\n');\n }\n\n lines.push('');\n lines.push(chalk.red.bold(`${failedComponents.length} component(s) with build failures:`));\n\n // fetch all build logs in parallel\n const containerNames = failedNodes.map((n) => n.containerName);\n const logMap = await this.ripple.getContainerLogs(job.id, containerNames);\n\n for (const node of failedNodes) {\n const compList = node.componentIds.join(', ');\n lines.push('');\n lines.push(chalk.bold(` ${compList}`));\n\n const logMessages = logMap.get(node.containerName);\n if (logMessages && logMessages.length > 0) {\n const errorLines = flags.log ? logMessages : this.ripple.extractErrorsFromLog(logMessages);\n if (errorLines.length > 0) {\n for (const msg of errorLines) {\n const clean = stripAnsi(msg);\n // skip stack trace lines (noisy) unless --log is used\n if (!flags.log && /^\\s+at\\s/.test(clean)) continue;\n if (clean.length > 0) {\n lines.push(` ${clean}`);\n }\n }\n } else {\n lines.push(chalk.gray(' No error details found in build log.'));\n }\n } else {\n lines.push(chalk.gray(' Build log not available.'));\n }\n }\n\n if (blockedComponents.length > 0) {\n lines.push('');\n lines.push(chalk.yellow(`${blockedComponents.length} component(s) not built (blocked by failure):`));\n for (const compId of blockedComponents) {\n lines.push(` ${chalk.yellow('○')} ${compId}`);\n }\n }\n\n if (succeededNodes.length > 0) {\n const succeededCount = succeededNodes.reduce((sum, n) => sum + n.componentIds.length, 0);\n lines.push('');\n lines.push(chalk.green(`${succeededCount} component(s) built successfully.`));\n }\n\n return lines.join('\\n');\n }\n\n async json([jobId]: [string], flags: { lane?: string; log?: boolean }) {\n const { job, ciNodes } = await this.getErrors(jobId, flags);\n if (!job) return { error: 'No job found', job: null, ciNodes: [], containerLogs: {} };\n\n // fetch error logs for failed containers in parallel\n const failedNodes = ciNodes.filter((n) => isFailedPhase(n.phase));\n const containerNames = failedNodes.map((n) => n.containerName);\n const logMap = await this.ripple.getContainerLogs(job.id, containerNames);\n const containerLogs: Record<string, string[]> = {};\n for (const [name, messages] of logMap) {\n containerLogs[name] = flags.log ? messages : this.ripple.extractErrorsFromLog(messages);\n }\n\n return { job, ciNodes, containerLogs };\n }\n\n private async getErrors(\n jobId: string | undefined,\n flags: { lane?: string }\n ): Promise<{\n job: any;\n ciNodes: CiGraphNode[];\n }> {\n let job;\n\n if (jobId) {\n job = await this.ripple.getJob(jobId);\n } else {\n const laneId = flags.lane || this.ripple.getCurrentLaneId();\n if (!laneId) {\n return { job: null, ciNodes: [] };\n }\n const found = await this.ripple.findLatestJobForLane(laneId, 'FAILURE');\n job = found ? await this.ripple.getJob(found.id) : null;\n }\n\n if (!job) {\n return { job: null, ciNodes: [] };\n }\n\n // use ciGraph (internal graph) for job-specific build status per container/component\n const ciNodes = this.ripple.getCiGraphNodes(job);\n\n return { job, ciNodes };\n }\n}\n\nexport class RippleRetryCmd implements Command {\n name = 'retry [job-id]';\n description = 'retry a failed Ripple CI job (auto-detects current lane when no job-id given)';\n skipWorkspace = true;\n remoteOp = true;\n alias = '';\n\n options: CommandOptions = [\n ['', 'lane <lane>', 'lane ID to find the latest job for (default: detected from .bitmap)'],\n ['j', 'json', 'return the output as JSON'],\n ];\n\n arguments = [\n { name: 'job-id', description: 'the Ripple CI job ID to retry (optional — auto-detects from current lane)' },\n ];\n\n constructor(private ripple: RippleMain) {}\n\n async report([jobId]: [string], flags: { lane?: string }) {\n const resolved = await resolveJobId(this.ripple, jobId, flags, {\n allowedPhases: ['FAILURE', 'FAILED'],\n actionVerb: 'retry',\n });\n if ('error' in resolved) return chalk.red(resolved.error);\n\n const result = await this.ripple.retryJob(resolved.id);\n if (!result) {\n return chalk.red(`Failed to retry job \"${resolved.id}\". Make sure the job exists and has failed.`);\n }\n const lines: string[] = [];\n lines.push(chalk.green(`Successfully retried job \"${resolved.id}\".`));\n if (result.id) lines.push(` ${chalk.cyan('New Job ID:')} ${result.id}`);\n if (result.status?.phase) lines.push(` ${chalk.cyan('Status:')} ${result.status.phase}`);\n const jobUrl = this.ripple.getJobUrl(result);\n lines.push(` ${chalk.cyan('URL:')} ${jobUrl}`);\n return lines.join('\\n');\n }\n\n async json([jobId]: [string], flags: { lane?: string }) {\n const resolved = await resolveJobId(this.ripple, jobId, flags, {\n allowedPhases: ['FAILURE', 'FAILED'],\n actionVerb: 'retry',\n });\n if ('error' in resolved) return { error: resolved.error };\n const result = await this.ripple.retryJob(resolved.id);\n return { job: result };\n }\n}\n\nexport class RippleStopCmd implements Command {\n name = 'stop [job-id]';\n description = 'stop a running Ripple CI job (auto-detects current lane when no job-id given)';\n skipWorkspace = true;\n remoteOp = true;\n alias = '';\n\n options: CommandOptions = [\n ['', 'lane <lane>', 'lane ID to find the latest job for (default: detected from .bitmap)'],\n ['j', 'json', 'return the output as JSON'],\n ];\n\n arguments = [\n { name: 'job-id', description: 'the Ripple CI job ID to stop (optional — auto-detects from current lane)' },\n ];\n\n constructor(private ripple: RippleMain) {}\n\n async report([jobId]: [string], flags: { lane?: string }) {\n const resolved = await resolveJobId(this.ripple, jobId, flags, {\n allowedPhases: ['RUNNING', 'IN_PROGRESS', 'PROCESSING'],\n actionVerb: 'stop',\n });\n if ('error' in resolved) return chalk.red(resolved.error);\n\n const result = await this.ripple.stopJob(resolved.id);\n if (!result) {\n return chalk.red(`Failed to stop job \"${resolved.id}\". Make sure the job exists and is currently running.`);\n }\n return chalk.green(`Successfully stopped job \"${resolved.id}\".`);\n }\n\n async json([jobId]: [string], flags: { lane?: string }) {\n const resolved = await resolveJobId(this.ripple, jobId, flags, {\n allowedPhases: ['RUNNING', 'IN_PROGRESS', 'PROCESSING'],\n actionVerb: 'stop',\n });\n if ('error' in resolved) return { error: resolved.error };\n const result = await this.ripple.stopJob(resolved.id);\n return { job: result };\n }\n}\n\nfunction formatDate(dateStr?: string): string {\n if (!dateStr) return '-';\n try {\n return new Date(dateStr).toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\nfunction formatDuration(startedAt?: string, finishedAt?: string): string {\n if (!startedAt) return '-';\n const start = new Date(startedAt).getTime();\n const end = finishedAt ? new Date(finishedAt).getTime() : Date.now();\n const ms = end - start;\n if (ms < 0) return '-';\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}h ${remainingMinutes}m`;\n}\n\nfunction getScopeFromLaneId(laneId?: string): string {\n if (!laneId) return '-';\n return laneId.split('/')[0] || '-';\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return `${str.substring(0, max - 1)}…`;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,111 @@
1
+ import type { RuntimeDefinition } from '@teambit/harmony';
2
+ import { type CLIMain } from '@teambit/cli';
3
+ import { type LoggerMain, type Logger } from '@teambit/logger';
4
+ import { type CloudMain } from '@teambit/cloud';
5
+ import type { Workspace } from '@teambit/workspace';
6
+ export type JobStatus = {
7
+ startedAt?: string;
8
+ finishedAt?: string;
9
+ phase?: string;
10
+ };
11
+ export type RippleJob = {
12
+ id: string;
13
+ name?: string;
14
+ laneId?: string;
15
+ simulation?: boolean;
16
+ user?: {
17
+ username?: string;
18
+ displayName?: string;
19
+ };
20
+ status?: JobStatus;
21
+ };
22
+ export type BuildTaskStatus = {
23
+ status?: string;
24
+ warnings?: number;
25
+ };
26
+ export type BuildTaskSummary = {
27
+ name?: string;
28
+ description?: string;
29
+ startTime?: string;
30
+ status?: BuildTaskStatus;
31
+ };
32
+ export type ComponentBuildSummary = {
33
+ id?: string;
34
+ name?: string;
35
+ tasks?: BuildTaskSummary[];
36
+ };
37
+ export type CiGraphNode = {
38
+ componentIds: string[];
39
+ containerName: string;
40
+ phase: string;
41
+ };
42
+ export declare class RippleMain {
43
+ private cloud;
44
+ private logger;
45
+ private workspace?;
46
+ static runtime: RuntimeDefinition;
47
+ static dependencies: import("@teambit/harmony").Aspect[];
48
+ constructor(cloud: CloudMain, logger: Logger, workspace?: Workspace | undefined);
49
+ private static LIST_JOBS;
50
+ private static GET_JOB;
51
+ private static GET_COMPONENT_BUILD_SUMMARY;
52
+ private static RETRY_JOB;
53
+ private static STOP_JOB;
54
+ private ensureAuthenticated;
55
+ private fetchRippleGQL;
56
+ listJobs(opts: {
57
+ limit?: number;
58
+ offset?: number;
59
+ filters?: {
60
+ lanes?: string[];
61
+ owners?: string[];
62
+ scopes?: string[];
63
+ status?: string;
64
+ };
65
+ }): Promise<RippleJob[]>;
66
+ getJob(jobId: string): Promise<(RippleJob & {
67
+ hash?: string;
68
+ ciGraph?: string;
69
+ ciComponentGraph?: string;
70
+ }) | null>;
71
+ /**
72
+ * parse a job's ciGraph (internal graph) to extract per-node build status.
73
+ * ciGraph has the job-specific build results (unlike ciComponentGraph which is static).
74
+ * each node represents a build container that builds one or more components.
75
+ */
76
+ getCiGraphNodes(job: {
77
+ ciGraph?: string;
78
+ }): CiGraphNode[];
79
+ getComponentBuildSummary(jobId: string, componentId: string): Promise<ComponentBuildSummary | null>;
80
+ /**
81
+ * fetch build logs for a specific container in a job via the REST SSE endpoint.
82
+ * uses an idle timeout to detect end-of-stream (SSE connections may not close).
83
+ */
84
+ getContainerLog(jobId: string, containerName: string): Promise<string[]>;
85
+ /**
86
+ * fetch build logs for multiple containers in parallel.
87
+ */
88
+ getContainerLogs(jobId: string, containerNames: string[]): Promise<Map<string, string[]>>;
89
+ /**
90
+ * extract the error section from container log messages.
91
+ * looks for common error patterns in the build output.
92
+ */
93
+ extractErrorsFromLog(messages: string[]): string[];
94
+ retryJob(jobId: string): Promise<RippleJob | null>;
95
+ stopJob(jobId: string): Promise<RippleJob | null>;
96
+ /**
97
+ * detect the current lane from the workspace.
98
+ * returns the laneId in "scope/lane-name" format, or undefined if not on a lane.
99
+ */
100
+ getCurrentLaneId(): string | undefined;
101
+ /**
102
+ * find the latest job for a given laneId, optionally filtered by status phase.
103
+ */
104
+ findLatestJobForLane(laneId: string, phase?: string): Promise<RippleJob | null>;
105
+ /**
106
+ * detect the workspace owner from the workspace defaultScope.
107
+ */
108
+ getDefaultOwner(): string | undefined;
109
+ getJobUrl(job: RippleJob): string;
110
+ static provider([cli, cloud, loggerAspect, workspace]: [CLIMain, CloudMain, LoggerMain, Workspace]): Promise<RippleMain>;
111
+ }
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RippleMain = void 0;
7
+ function _cli() {
8
+ const data = require("@teambit/cli");
9
+ _cli = function () {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _logger() {
15
+ const data = require("@teambit/logger");
16
+ _logger = function () {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _cloud() {
22
+ const data = require("@teambit/cloud");
23
+ _cloud = function () {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _workspace() {
29
+ const data = require("@teambit/workspace");
30
+ _workspace = function () {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ function _legacy() {
36
+ const data = require("@teambit/legacy.constants");
37
+ _legacy = function () {
38
+ return data;
39
+ };
40
+ return data;
41
+ }
42
+ function _rippleUtils() {
43
+ const data = require("./ripple-utils");
44
+ _rippleUtils = function () {
45
+ return data;
46
+ };
47
+ return data;
48
+ }
49
+ function _stripAnsi() {
50
+ const data = _interopRequireDefault(require("strip-ansi"));
51
+ _stripAnsi = function () {
52
+ return data;
53
+ };
54
+ return data;
55
+ }
56
+ function _ripple() {
57
+ const data = require("./ripple.aspect");
58
+ _ripple = function () {
59
+ return data;
60
+ };
61
+ return data;
62
+ }
63
+ function _ripple2() {
64
+ const data = require("./ripple.cmd");
65
+ _ripple2 = function () {
66
+ return data;
67
+ };
68
+ return data;
69
+ }
70
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
71
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
72
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
73
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
74
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
75
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
76
+ class RippleMain {
77
+ constructor(cloud, logger, workspace) {
78
+ this.cloud = cloud;
79
+ this.logger = logger;
80
+ this.workspace = workspace;
81
+ }
82
+ ensureAuthenticated() {
83
+ if (!this.cloud.getAuthToken()) {
84
+ throw new Error('You are not logged in. Please run "bit login" first.');
85
+ }
86
+ }
87
+ async fetchRippleGQL(query, variables) {
88
+ this.ensureAuthenticated();
89
+ const graphqlUrl = `${this.cloud.getCloudApi()}/graphql`;
90
+ const body = JSON.stringify({
91
+ query,
92
+ variables
93
+ });
94
+ const headers = _objectSpread({
95
+ 'Content-Type': 'application/json'
96
+ }, this.cloud.getAuthHeader());
97
+ const response = await fetch(graphqlUrl, {
98
+ method: 'POST',
99
+ headers,
100
+ body
101
+ });
102
+ if (!response.ok) {
103
+ const text = await response.text().catch(() => '');
104
+ throw new Error(`Ripple CI API returned HTTP ${response.status}: ${text}`);
105
+ }
106
+ const json = await response.json();
107
+ if (json.errors?.length) {
108
+ const messages = json.errors.map(e => e.message).join(', ');
109
+ throw new Error(`Ripple CI API error: ${messages}`);
110
+ }
111
+ return json.data ?? null;
112
+ }
113
+ async listJobs(opts) {
114
+ const data = await this.fetchRippleGQL(RippleMain.LIST_JOBS, {
115
+ filters: opts.filters,
116
+ limit: opts.limit ?? 20,
117
+ offset: opts.offset
118
+ });
119
+ return data?.listJobs ?? [];
120
+ }
121
+ async getJob(jobId) {
122
+ const data = await this.fetchRippleGQL(RippleMain.GET_JOB, {
123
+ jobId
124
+ });
125
+ return data?.getJob ?? null;
126
+ }
127
+
128
+ /**
129
+ * parse a job's ciGraph (internal graph) to extract per-node build status.
130
+ * ciGraph has the job-specific build results (unlike ciComponentGraph which is static).
131
+ * each node represents a build container that builds one or more components.
132
+ */
133
+ getCiGraphNodes(job) {
134
+ if (!job.ciGraph) return [];
135
+ try {
136
+ const graph = JSON.parse(job.ciGraph);
137
+ if (!graph.nodes) return [];
138
+ return graph.nodes.map(node => {
139
+ const attr = typeof node.attr === 'string' ? JSON.parse(node.attr) : node.attr;
140
+ const ids = (attr.ids || []).map(id => (0, _rippleUtils().stripComponentVersion)(id));
141
+ return {
142
+ componentIds: ids,
143
+ containerName: attr.status?.name || node.id,
144
+ phase: attr.status?.phase || 'UNKNOWN'
145
+ };
146
+ });
147
+ } catch {
148
+ return [];
149
+ }
150
+ }
151
+ async getComponentBuildSummary(jobId, componentId) {
152
+ const data = await this.fetchRippleGQL(RippleMain.GET_COMPONENT_BUILD_SUMMARY, {
153
+ jobId,
154
+ componentId
155
+ });
156
+ return data?.getComponentBuildSummary ?? null;
157
+ }
158
+
159
+ /**
160
+ * fetch build logs for a specific container in a job via the REST SSE endpoint.
161
+ * uses an idle timeout to detect end-of-stream (SSE connections may not close).
162
+ */
163
+ async getContainerLog(jobId, containerName) {
164
+ this.ensureAuthenticated();
165
+ const url = `${this.cloud.getCloudApi()}/ripple-ci/api/job/log/${jobId}/${containerName}`;
166
+ const headers = _objectSpread({
167
+ Accept: 'text/event-stream'
168
+ }, this.cloud.getAuthHeader());
169
+ const controller = new AbortController();
170
+ // hard cap to avoid hanging forever
171
+ const hardTimeout = setTimeout(() => controller.abort(), 30_000);
172
+ const messages = [];
173
+ let idleTimer;
174
+ try {
175
+ const response = await fetch(url, {
176
+ headers,
177
+ signal: controller.signal
178
+ });
179
+ if (!response.ok || !response.body) {
180
+ clearTimeout(hardTimeout);
181
+ return [];
182
+ }
183
+ const reader = response.body.getReader();
184
+ const decoder = new TextDecoder();
185
+ let buffer = '';
186
+ const resetIdle = () => {
187
+ if (idleTimer) clearTimeout(idleTimer);
188
+ idleTimer = setTimeout(() => controller.abort(), 3_000);
189
+ };
190
+ resetIdle();
191
+ // eslint-disable-next-line no-constant-condition
192
+ while (true) {
193
+ // eslint-disable-next-line no-await-in-loop
194
+ const {
195
+ done,
196
+ value
197
+ } = await reader.read();
198
+ if (done) break;
199
+ resetIdle();
200
+ buffer += decoder.decode(value, {
201
+ stream: true
202
+ });
203
+ const lines = buffer.split('\n');
204
+ buffer = lines.pop() || '';
205
+ for (const line of lines) {
206
+ if (!line.startsWith('data: ')) continue;
207
+ try {
208
+ const parsed = JSON.parse(line.substring(6));
209
+ if (parsed.message != null) messages.push(parsed.message);
210
+ } catch {
211
+ // skip malformed lines
212
+ }
213
+ }
214
+ }
215
+ } catch (err) {
216
+ if (err?.name !== 'AbortError') {
217
+ this.logger.warn(`Failed to fetch container log: ${err?.message}`);
218
+ }
219
+ } finally {
220
+ if (idleTimer) clearTimeout(idleTimer);
221
+ clearTimeout(hardTimeout);
222
+ }
223
+ return messages;
224
+ }
225
+
226
+ /**
227
+ * fetch build logs for multiple containers in parallel.
228
+ */
229
+ async getContainerLogs(jobId, containerNames) {
230
+ const results = await Promise.allSettled(containerNames.map(async name => {
231
+ const log = await this.getContainerLog(jobId, name);
232
+ return {
233
+ name,
234
+ log
235
+ };
236
+ }));
237
+ const logMap = new Map();
238
+ for (const result of results) {
239
+ if (result.status === 'fulfilled') {
240
+ logMap.set(result.value.name, result.value.log);
241
+ }
242
+ }
243
+ return logMap;
244
+ }
245
+
246
+ /**
247
+ * extract the error section from container log messages.
248
+ * looks for common error patterns in the build output.
249
+ */
250
+ extractErrorsFromLog(messages) {
251
+ const patterns = ['errors were found', 'Failed task', 'threw an error', 'Error:', 'FAIL'];
252
+ for (const pattern of patterns) {
253
+ const idx = messages.findIndex(m => (0, _stripAnsi().default)(m).includes(pattern));
254
+ if (idx >= 0) {
255
+ return messages.slice(idx);
256
+ }
257
+ }
258
+ // last resort: grab the last 30 lines if the log has content
259
+ if (messages.length > 0) {
260
+ return messages.slice(-30);
261
+ }
262
+ return [];
263
+ }
264
+ async retryJob(jobId) {
265
+ const data = await this.fetchRippleGQL(RippleMain.RETRY_JOB, {
266
+ jobId
267
+ });
268
+ return data?.retryJob ?? null;
269
+ }
270
+ async stopJob(jobId) {
271
+ const data = await this.fetchRippleGQL(RippleMain.STOP_JOB, {
272
+ jobId
273
+ });
274
+ return data?.stopJob ?? null;
275
+ }
276
+
277
+ /**
278
+ * detect the current lane from the workspace.
279
+ * returns the laneId in "scope/lane-name" format, or undefined if not on a lane.
280
+ */
281
+ getCurrentLaneId() {
282
+ if (!this.workspace) return undefined;
283
+ const laneId = this.workspace.getCurrentLaneId();
284
+ if (!laneId || laneId.isDefault()) return undefined;
285
+ return laneId.toString();
286
+ }
287
+
288
+ /**
289
+ * find the latest job for a given laneId, optionally filtered by status phase.
290
+ */
291
+ async findLatestJobForLane(laneId, phase) {
292
+ const filters = {
293
+ lanes: [laneId]
294
+ };
295
+ if (phase) {
296
+ filters.status = phase;
297
+ }
298
+ const jobs = await this.listJobs({
299
+ filters,
300
+ limit: 1
301
+ });
302
+ return jobs[0] ?? null;
303
+ }
304
+
305
+ /**
306
+ * detect the workspace owner from the workspace defaultScope.
307
+ */
308
+ getDefaultOwner() {
309
+ const defaultScope = this.workspace?.defaultScope;
310
+ if (!defaultScope?.includes('.')) return undefined;
311
+ return defaultScope.split('.')[0];
312
+ }
313
+ getJobUrl(job) {
314
+ if (job.laneId) {
315
+ // laneId format: "scope/lane-name", e.g. "att-bit.duc/my-lane"
316
+ const [scope, ...laneParts] = job.laneId.split('/');
317
+ const laneName = laneParts.join('/');
318
+ if (scope && laneName) {
319
+ return `https://${(0, _legacy().getCloudDomain)()}/${scope.split('.').join('/')}/~lane/${laneName}/~ripple-ci/job/${job.id}`;
320
+ }
321
+ }
322
+ return `https://${(0, _legacy().getCloudDomain)()}/ripple-ci/job/${job.id}`;
323
+ }
324
+ static async provider([cli, cloud, loggerAspect, workspace]) {
325
+ const logger = loggerAspect.createLogger(_ripple().RippleAspect.id);
326
+ const ripple = new RippleMain(cloud, logger, workspace);
327
+ const rippleCmd = new (_ripple2().RippleCmd)();
328
+ rippleCmd.commands = [new (_ripple2().RippleListCmd)(ripple), new (_ripple2().RippleLogCmd)(ripple), new (_ripple2().RippleErrorsCmd)(ripple), new (_ripple2().RippleRetryCmd)(ripple), new (_ripple2().RippleStopCmd)(ripple)];
329
+ cli.register(rippleCmd);
330
+ return ripple;
331
+ }
332
+ }
333
+ exports.RippleMain = RippleMain;
334
+ _defineProperty(RippleMain, "runtime", _cli().MainRuntime);
335
+ _defineProperty(RippleMain, "dependencies", [_cli().CLIAspect, _cloud().CloudAspect, _logger().LoggerAspect, _workspace().WorkspaceAspect]);
336
+ _defineProperty(RippleMain, "LIST_JOBS", `
337
+ query listJobs($filters: FilterOptions, $limit: Int, $offset: Int) {
338
+ listJobs(filters: $filters, limit: $limit, offset: $offset) {
339
+ id
340
+ name
341
+ laneId
342
+ simulation
343
+ user { username displayName }
344
+ status { startedAt finishedAt phase }
345
+ }
346
+ }
347
+ `);
348
+ _defineProperty(RippleMain, "GET_JOB", `
349
+ query getJob($jobId: ID!) {
350
+ getJob(jobId: $jobId) {
351
+ id
352
+ name
353
+ laneId
354
+ hash
355
+ simulation
356
+ user { username displayName }
357
+ status { startedAt finishedAt phase }
358
+ ciGraph
359
+ ciComponentGraph
360
+ }
361
+ }
362
+ `);
363
+ _defineProperty(RippleMain, "GET_COMPONENT_BUILD_SUMMARY", `
364
+ query getComponentBuildSummary($jobId: ID!, $componentId: String!) {
365
+ getComponentBuildSummary(jobId: $jobId, componentId: $componentId) {
366
+ id
367
+ name
368
+ tasks {
369
+ name
370
+ description
371
+ startTime
372
+ status { status warnings }
373
+ }
374
+ }
375
+ }
376
+ `);
377
+ _defineProperty(RippleMain, "RETRY_JOB", `
378
+ mutation retryJob($jobId: ID!) {
379
+ retryJob(jobId: $jobId) {
380
+ id
381
+ name
382
+ laneId
383
+ status { startedAt finishedAt phase }
384
+ }
385
+ }
386
+ `);
387
+ _defineProperty(RippleMain, "STOP_JOB", `
388
+ mutation stopJob($jobId: ID!) {
389
+ stopJob(jobId: $jobId) {
390
+ id
391
+ name
392
+ laneId
393
+ status { startedAt finishedAt phase }
394
+ }
395
+ }
396
+ `);
397
+ _ripple().RippleAspect.addRuntime(RippleMain);
398
+
399
+ //# sourceMappingURL=ripple.main.runtime.js.map