everything-dev 1.26.1 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs.map +1 -1
- package/dist/cli/catalog.cjs.map +1 -1
- package/dist/cli/catalog.mjs.map +1 -1
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/infra.cjs +1 -1
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs +1 -1
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +127 -121
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +6 -6
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +6 -6
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +125 -121
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/parse.cjs.map +1 -1
- package/dist/cli/parse.mjs.map +1 -1
- package/dist/cli/prompts.cjs +29 -25
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +28 -25
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +46 -93
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +49 -96
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/timing.cjs.map +1 -1
- package/dist/cli/timing.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +41 -20
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +43 -22
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli.cjs +187 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +187 -12
- package/dist/cli.mjs.map +1 -1
- package/dist/components/dev-view.cjs.map +1 -1
- package/dist/components/dev-view.mjs.map +1 -1
- package/dist/components/streaming-view.cjs.map +1 -1
- package/dist/components/streaming-view.mjs.map +1 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +174 -173
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +48 -44
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +48 -44
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.mjs +3 -1
- package/dist/contract.mjs.map +1 -1
- package/dist/dev-logs.cjs.map +1 -1
- package/dist/dev-logs.mjs.map +1 -1
- package/dist/dev-session.cjs +0 -1
- package/dist/dev-session.mjs +1 -1
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.mjs.map +1 -1
- package/dist/index.cjs +2 -4
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -2
- package/dist/integrity.cjs.map +1 -1
- package/dist/integrity.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/merge.cjs.map +1 -1
- package/dist/merge.mjs.map +1 -1
- package/dist/near-cli.cjs +1 -1
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +1 -1
- package/dist/near-cli.mjs.map +1 -1
- package/dist/orchestrator.cjs +1 -1
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +1 -1
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +182 -171
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +72 -39
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +71 -39
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +170 -160
- package/dist/plugin.mjs.map +1 -1
- package/dist/sdk.cjs +2 -2
- package/dist/sdk.d.cts +1 -1
- package/dist/sdk.d.mts +1 -1
- package/dist/sdk.mjs +1 -1
- package/dist/service-descriptor.d.cts +34 -0
- package/dist/service-descriptor.d.cts.map +1 -0
- package/dist/service-descriptor.d.mts +36 -0
- package/dist/service-descriptor.d.mts.map +1 -0
- package/dist/shared.cjs.map +1 -1
- package/dist/shared.mjs.map +1 -1
- package/dist/types.cjs +184 -184
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +5 -5
- package/dist/types.d.mts +5 -5
- package/dist/types.mjs +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ui/types.d.cts +1 -0
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.mts +1 -0
- package/dist/ui/types.d.mts.map +1 -1
- package/dist/utils/banner.cjs.map +1 -1
- package/dist/utils/banner.mjs.map +1 -1
- package/dist/utils/run.cjs.map +1 -1
- package/dist/utils/run.mjs.map +1 -1
- package/package.json +3 -3
- package/skills/init-upgrade/SKILL.md +22 -16
- package/skills/publish-sync/SKILL.md +7 -18
- package/dist/utils/path-match.cjs +0 -18
- package/dist/utils/path-match.cjs.map +0 -1
- package/dist/utils/path-match.mjs +0 -17
- package/dist/utils/path-match.mjs.map +0 -1
- package/src/api-contract.ts +0 -623
- package/src/app.ts +0 -193
- package/src/cli/catalog.ts +0 -49
- package/src/cli/framework-version.ts +0 -61
- package/src/cli/help.ts +0 -13
- package/src/cli/infra.ts +0 -190
- package/src/cli/init.ts +0 -1202
- package/src/cli/parse.ts +0 -147
- package/src/cli/prompts.ts +0 -135
- package/src/cli/snapshot.ts +0 -46
- package/src/cli/status.ts +0 -99
- package/src/cli/sync.ts +0 -518
- package/src/cli/timing.ts +0 -63
- package/src/cli/upgrade.ts +0 -828
- package/src/cli.ts +0 -516
- package/src/components/dev-view.tsx +0 -352
- package/src/components/streaming-view.ts +0 -177
- package/src/config.ts +0 -893
- package/src/contract.meta.ts +0 -140
- package/src/contract.ts +0 -325
- package/src/dev-logs.ts +0 -92
- package/src/dev-session.ts +0 -283
- package/src/fastkv.ts +0 -181
- package/src/index.ts +0 -8
- package/src/integrity.ts +0 -138
- package/src/internal/manifest-normalizer.ts +0 -290
- package/src/merge.ts +0 -187
- package/src/mf.ts +0 -147
- package/src/near-cli.ts +0 -259
- package/src/network.ts +0 -3
- package/src/orchestrator.ts +0 -493
- package/src/plugin.ts +0 -1821
- package/src/sdk.ts +0 -14
- package/src/service-descriptor.ts +0 -281
- package/src/shared.ts +0 -249
- package/src/sidebar.ts +0 -140
- package/src/types.ts +0 -330
- package/src/ui/head.ts +0 -83
- package/src/ui/index.ts +0 -5
- package/src/ui/metadata.ts +0 -95
- package/src/ui/router.ts +0 -88
- package/src/ui/runtime.ts +0 -42
- package/src/ui/types.ts +0 -64
- package/src/utils/banner.ts +0 -21
- package/src/utils/linkify.ts +0 -11
- package/src/utils/path-match.ts +0 -16
- package/src/utils/run.ts +0 -31
- package/src/utils/save-config.ts +0 -20
- package/src/utils/theme.ts +0 -39
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["bosPlugin"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { findCommandDescriptor } from \"./cli/catalog\";\nimport { printHelp } from \"./cli/help\";\nimport { parseCommandInput } from \"./cli/parse\";\nimport { formatDuration, sumPhaseDurations } from \"./cli/timing\";\nimport { findConfigPath } from \"./config\";\nimport bosPlugin from \"./plugin\";\nimport { createPluginRuntime } from \"./sdk\";\nimport { printBanner } from \"./utils/banner\";\nimport { colors, frames, gradients, icons } from \"./utils/theme\";\n\nfunction printConfigView(result: {\n account: string;\n domain?: string;\n staging?: { domain: string };\n app: {\n host: { name?: string; development: string; production?: string };\n ui: { name?: string; development?: string; production?: string; ssr?: string };\n api: { name?: string; development?: string; production?: string; proxy?: string };\n };\n}) {\n console.log();\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.app} ${gradients.cyber(\"CONFIG\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n\n console.log(` ${colors.dim(\"Account\")} ${colors.cyan(result.account)}`);\n console.log(` ${colors.dim(\"Domain\")} ${colors.white(result.domain ?? \"not configured\")}`);\n if (result.staging) {\n console.log(` ${colors.dim(\"Staging\")} ${colors.magenta(result.staging.domain)}`);\n }\n console.log();\n}\n\nfunction formatTimeAgo(isoTimestamp: string): string {\n const now = Date.now();\n const then = new Date(isoTimestamp).getTime();\n const diffMs = now - then;\n const diffMins = Math.floor(diffMs / 60_000);\n if (diffMins < 1) return \"just now\";\n if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? \"s\" : \"\"} ago`;\n const diffHours = Math.floor(diffMins / 60);\n if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? \"s\" : \"\"} ago`;\n const diffDays = Math.floor(diffHours / 24);\n if (diffDays < 30) return `${diffDays} day${diffDays > 1 ? \"s\" : \"\"} ago`;\n return isoTimestamp.split(\"T\")[0] ?? isoTimestamp;\n}\n\nfunction normalizeVersion(v: string): string {\n return v.replace(/^[\\^~>=v]+/, \"\").trim();\n}\n\nfunction printTimingSummary(timings: Array<{ name: string; durationMs: number }> | undefined) {\n if (!timings || timings.length === 0) return;\n\n console.log(` ${colors.dim(\"Timings:\")}`);\n for (const timing of timings) {\n console.log(` ${colors.dim(timing.name.padEnd(22))} ${formatDuration(timing.durationMs)}`);\n }\n console.log(\n ` ${colors.dim(\"total\".padEnd(22))} ${formatDuration(sumPhaseDurations(timings))}`,\n );\n}\n\nasync function warnIfOutdated(client: any, command: string): Promise<void> {\n if (![\"dev\", \"build\", \"start\"].includes(command)) return;\n\n try {\n const status = await client.status();\n if (status.status === \"error\" || !status.packages) return;\n\n const frameworkPackages = [\"everything-dev\", \"every-plugin\"];\n\n const outdated = status.packages.filter(\n (p: { name: string; installed?: string; latest?: string }) =>\n p.installed &&\n p.latest &&\n normalizeVersion(p.installed) !== normalizeVersion(p.latest) &&\n frameworkPackages.includes(p.name),\n );\n\n if (outdated.length === 0) return;\n\n console.log();\n console.log(colors.yellow(` ! Outdated packages detected:`));\n for (const pkg of outdated) {\n console.log(colors.dim(` ${pkg.name} ${pkg.installed} → ${pkg.latest}`));\n }\n console.log(\n colors.dim(\n ` Run ${colors.cyan(\"bos upgrade\")} to update packages and sync template files.`,\n ),\n );\n console.log();\n } catch {\n // silently ignore if status check fails\n }\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n printHelp();\n return;\n }\n\n const invocationArgs = args.length > 0 ? args : [\"dev\"];\n const command = invocationArgs[0] ?? \"dev\";\n const configPath = findConfigPath();\n\n const commandMatch = findCommandDescriptor(invocationArgs);\n if (!commandMatch) {\n console.error(`Unknown command: ${command}`);\n process.exit(1);\n }\n\n const { descriptor, consumed } = commandMatch;\n const commandArgs = invocationArgs.slice(consumed);\n\n printBanner();\n\n const runtime = createPluginRuntime({\n registry: {\n bos: { module: bosPlugin },\n },\n secrets: {},\n });\n\n const pluginRuntime: any = runtime;\n const loadPlugin = pluginRuntime.usePlugin.bind(pluginRuntime);\n const plugin = await loadPlugin(\"bos\", {\n variables: {\n configPath: configPath ?? undefined,\n },\n secrets: {},\n });\n\n const client = plugin.createClient();\n\n await warnIfOutdated(client, command);\n\n try {\n const input = parseCommandInput(descriptor, commandArgs);\n const result = await (client as any)[descriptor.key](input);\n\n if (descriptor.key === \"config\") {\n if (!result.config) {\n console.error(\"No bos.config.json found\");\n process.exit(1);\n }\n\n printConfigView(result.config);\n process.stdout.write(`${JSON.stringify(result.config, null, 2)}\\n`);\n return;\n }\n\n if (descriptor.key === \"init\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n console.log(colors.green(`${icons.ok} Project initialized`));\n console.log(` ${colors.dim(\"Extends:\")} ${result.extends}`);\n console.log(` ${colors.dim(\"Directory:\")} ${result.directory}`);\n if (result.account) console.log(` ${colors.dim(\"Account:\")} ${result.account}`);\n if (result.domain) console.log(` ${colors.dim(\"Domain:\")} ${result.domain}`);\n if (result.overrides && result.overrides.length > 0)\n console.log(` ${colors.dim(\"Overrides:\")} ${result.overrides.join(\", \")}`);\n if (result.plugins && result.plugins.length > 0)\n console.log(` ${colors.dim(\"Plugins:\")} ${result.plugins.join(\", \")}`);\n console.log(` ${colors.dim(\"Files copied:\")} ${result.filesCopied}`);\n printTimingSummary(result.timings);\n console.log();\n console.log(colors.dim(\" Next steps:\"));\n console.log(colors.dim(` cd ${result.directory}`));\n if (result.status === \"initialized\" && !(input as any)?.noInstall) {\n console.log(colors.dim(\" docker compose up -d --wait\"));\n console.log(colors.dim(\" bun run dev\"));\n } else {\n console.log(colors.dim(\" bun install\"));\n console.log(colors.dim(\" docker compose up -d --wait\"));\n console.log(colors.dim(\" bun run dev\"));\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"sync\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n if (result.status === \"dry-run\") {\n console.log(colors.cyan(`${icons.ok} Dry run — no files written`));\n } else {\n console.log(colors.green(`${icons.ok} Template synced`));\n }\n if (result.updated.length > 0) {\n console.log(` ${colors.dim(\"Updated:\")} ${result.updated.length} file(s)`);\n for (const f of result.updated) console.log(` ${colors.dim(f)}`);\n }\n if (result.added.length > 0) {\n console.log(` ${colors.dim(\"Added:\")} ${result.added.length} file(s)`);\n for (const f of result.added) console.log(` ${colors.dim(f)}`);\n }\n if (result.skipped.length > 0) {\n console.log(\n ` ${colors.yellow(\"Skipped:\")} ${result.skipped.length} file(s) (locally modified, use --force to overwrite)`,\n );\n for (const f of result.skipped) console.log(` ${colors.dim(f)}`);\n }\n if (result.updated.length === 0 && result.added.length === 0 && result.skipped.length === 0) {\n console.log(` ${colors.dim(\"Already up to date\")}`);\n }\n if (result.status !== \"dry-run\" && result.updated.length > 0) {\n console.log();\n console.log(colors.dim(\" Review changes — your customizations take priority:\"));\n console.log(\n colors.dim(\n \" • api/src/contract.ts, api/src/index.ts, api/src/db/schema.ts — never overwritten\",\n ),\n );\n console.log(\n colors.dim(\" • ui/src/components/**, ui/src/styles.css — never overwritten\"),\n );\n console.log(\n colors.dim(\n \" • Other updated files — accept framework improvements, then restore your changes\",\n ),\n );\n console.log(colors.dim(\" • Skipped files — yours already, only update with --force\"));\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"upgrade\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n if (result.status === \"dry-run\") {\n console.log(colors.cyan(`${icons.ok} Dry run — no changes applied`));\n } else {\n console.log(colors.green(`${icons.ok} Upgrade successful`));\n }\n for (const pkg of result.packages) {\n if (pkg.from && pkg.from !== pkg.to) {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.from} → ${pkg.to}`);\n } else if (!pkg.from) {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.to} (new)`);\n } else {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.to} (up to date)`);\n }\n }\n if (result.changelogUrl) {\n console.log(` ${colors.dim(\"Changelog:\")} ${result.changelogUrl}`);\n }\n if (result.availablePlugins && result.availablePlugins.length > 0) {\n console.log(` ${colors.dim(\"New parent plugins:\")} ${result.availablePlugins.join(\", \")}`);\n }\n if (result.selectedPlugins && result.selectedPlugins.length > 0) {\n console.log(` ${colors.dim(\"Added plugins:\")} ${result.selectedPlugins.join(\", \")}`);\n }\n printTimingSummary(result.timings);\n if (result.sync) {\n const sync = result.sync;\n if (sync.updated.length > 0) {\n console.log(` ${colors.dim(\"Updated:\")} ${sync.updated.length} file(s)`);\n for (const f of sync.updated) console.log(` ${colors.dim(f)}`);\n }\n if (sync.added.length > 0) {\n console.log(` ${colors.dim(\"Added:\")} ${sync.added.length} file(s)`);\n for (const f of sync.added) console.log(` ${colors.dim(f)}`);\n }\n if (sync.skipped.length > 0) {\n console.log(\n ` ${colors.yellow(\"Skipped:\")} ${sync.skipped.length} file(s) (locally modified, use --force to overwrite)`,\n );\n for (const f of sync.skipped) console.log(` ${colors.dim(f)}`);\n }\n if (\n result.status !== \"dry-run\" &&\n (sync.updated.length > 0 || sync.added.length > 0 || sync.skipped.length > 0)\n ) {\n console.log();\n console.log(colors.dim(\" Resolve differences — your code takes priority:\"));\n console.log();\n console.log(colors.dim(\" Never overwritten (safe):\"));\n console.log(\n colors.dim(\" • api/src/contract.ts, api/src/index.ts, api/src/db/schema.ts\"),\n );\n console.log(colors.dim(\" • ui/src/components/**, ui/src/styles.css\"));\n console.log();\n console.log(colors.dim(\" Replaced — review and keep your changes:\"));\n console.log(\n colors.dim(\n \" • api/drizzle.config.ts, api/tsconfig.json, api/tsconfig.contract.json\",\n ),\n );\n console.log(colors.dim(\" • api/plugin.dev.ts, api/rspack.config.js\"));\n console.log(colors.dim(\" • ui/src/routes/* (core routes only)\"));\n console.log();\n console.log(colors.dim(\" Merged — your deps preserved:\"));\n console.log(colors.dim(\" • package.json, api/package.json, ui/package.json\"));\n console.log();\n console.log(colors.dim(\" Skipped — already yours:\"));\n console.log(colors.dim(\" • Use --force only if you want framework updates\"));\n }\n }\n if (result.migrated && result.migrated.length > 0) {\n console.log(` ${colors.yellow(\"Removed:\")} ${result.migrated.length} obsolete file(s)`);\n for (const f of result.migrated) console.log(` ${colors.dim(f)}`);\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"status\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.app} ${gradients.cyber(\"STATUS\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n if (result.extends) console.log(` ${colors.dim(\"Extends:\")} ${result.extends}`);\n if (result.account) console.log(` ${colors.dim(\"Account:\")} ${result.account}`);\n if (result.domain) console.log(` ${colors.dim(\"Domain:\")} ${result.domain}`);\n console.log();\n console.log(` ${colors.dim(\"Packages:\")}`);\n for (const pkg of result.packages) {\n const hasUpdate =\n pkg.installed &&\n pkg.latest &&\n normalizeVersion(pkg.installed) !== normalizeVersion(pkg.latest);\n const versionStr = hasUpdate\n ? `${pkg.installed} → ${pkg.latest}`\n : pkg.installed || \"not installed\";\n const label = hasUpdate ? colors.yellow(versionStr) : colors.dim(versionStr);\n console.log(` ${colors.dim(`${pkg.name}`)} ${label}`);\n }\n console.log();\n if (result.lastSync) {\n const ago = formatTimeAgo(result.lastSync);\n console.log(` ${colors.dim(\"Last sync:\")} ${ago}`);\n } else {\n console.log(` ${colors.dim(\"Last sync:\")} never`);\n }\n const envLabel =\n result.envFile === \"found\"\n ? colors.green(\"found\")\n : result.envFile === \"example-only\"\n ? colors.yellow(\"missing (only .env.example found)\")\n : colors.error(\"missing\");\n console.log(` ${colors.dim(\".env:\")} ${envLabel}`);\n if (result.parentReachable !== undefined) {\n const parentLabel = result.parentReachable\n ? colors.green(\"reachable\")\n : colors.error(\"unreachable\");\n console.log(` ${colors.dim(\"Parent:\")} ${parentLabel}`);\n }\n const hasUpdates = result.packages.some(\n (p: { installed?: string; latest?: string }) =>\n p.installed && p.latest && normalizeVersion(p.installed) !== normalizeVersion(p.latest),\n );\n if (hasUpdates) {\n console.log();\n console.log(\n colors.dim(\n ` Run ${colors.cyan(\"bos upgrade\")} to update packages and sync template files.`,\n ),\n );\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"typesGen\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n console.log(colors.green(`${icons.ok} Types generated`));\n if (result.source) {\n console.log(\n ` ${colors.dim(\"Mode:\")} ${result.source === \"remote\" ? colors.cyan(\"remote\") : colors.dim(\"local\")}`,\n );\n }\n if (result.generated.length > 0) {\n console.log(` ${colors.dim(\"Generated:\")}`);\n for (const f of result.generated) console.log(` ${colors.dim(f)}`);\n }\n if (result.fetched.length > 0) {\n console.log(` ${colors.dim(\"Fetched from remote:\")}`);\n for (const url of result.fetched) console.log(` ${colors.dim(url)}`);\n }\n if (result.skipped.length > 0) {\n console.log(` ${colors.dim(\"Skipped (local):\")}`);\n for (const s of result.skipped) console.log(` ${colors.dim(s)}`);\n }\n if (result.failed.length > 0) {\n console.log(` ${colors.yellow(\"Failed:\")}`);\n for (const f of result.failed) console.log(` ${colors.error(f)}`);\n }\n console.log();\n return;\n }\n\n if (result?.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n\n if (descriptor.key === \"keyPublish\") {\n process.stdout.write(`Generated publish key for ${result.account}\\n`);\n process.stdout.write(` Network: ${result.network}\\n`);\n process.stdout.write(` Contract: ${result.contract}\\n`);\n process.stdout.write(` Allowance: ${result.allowance}\\n`);\n process.stdout.write(` Functions: ${result.functionNames.join(\", \")}\\n`);\n process.stdout.write(` Public key: ${result.publicKey}\\n`);\n process.stdout.write(` Private key: ${result.privateKey}\\n`);\n process.stdout.write(` Copy: NEAR_PRIVATE_KEY=${result.privateKey}\\n`);\n }\n\n if (descriptor.key === \"pluginAdd\") {\n console.log();\n console.log(colors.green(`${icons.ok} Added plugin ${result.key}`));\n if (result.development) console.log(` ${colors.dim(\"Development:\")} ${result.development}`);\n if (result.production) console.log(` ${colors.dim(\"Production:\")} ${result.production}`);\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginRemove\") {\n console.log();\n console.log(colors.green(`${icons.ok} Removed plugin ${result.key}`));\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginList\") {\n console.log();\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.config} ${gradients.cyber(\"PLUGINS\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n if (result.plugins.length === 0) {\n console.log(colors.dim(\" No plugins configured\"));\n } else {\n for (const pluginItem of result.plugins) {\n console.log(` ${colors.cyan(pluginItem.key)}`);\n if (pluginItem.development)\n console.log(` ${colors.dim(\"Development:\")} ${pluginItem.development}`);\n if (pluginItem.production)\n console.log(` ${colors.dim(\"Production:\")} ${pluginItem.production}`);\n }\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginPublish\") {\n console.log();\n console.log(colors.green(`${icons.ok} Published plugin ${result.key}`));\n if (result.path) console.log(` ${colors.dim(\"Path:\")} ${result.path}`);\n if (result.script) console.log(` ${colors.dim(\"Script:\")} bun run ${result.script}`);\n if (result.production) console.log(` ${colors.dim(\"Production:\")} ${result.production}`);\n console.log();\n return;\n }\n\n if (descriptor.key === \"publish\") {\n if (result.status === \"dry-run\") {\n console.log();\n console.log(colors.cyan(`${icons.ok} Dry run complete`));\n console.log(` ${colors.dim(\"Registry URL:\")} ${result.registryUrl}`);\n console.log();\n return;\n }\n\n if (result.status === \"published\") {\n console.log();\n console.log(colors.green(`${icons.ok} Published successfully`));\n console.log(` ${colors.dim(\"Registry URL:\")} ${result.registryUrl}`);\n if (result.txHash) {\n console.log(` ${colors.dim(\"Transaction:\")} ${result.txHash}`);\n }\n if (result.built && result.built.length > 0) {\n console.log(` ${colors.dim(\"Built:\")} ${result.built.join(\", \")}`);\n }\n if (result.skipped && result.skipped.length > 0) {\n console.log(` ${colors.dim(\"Skipped:\")} ${result.skipped.join(\", \")}`);\n }\n console.log();\n return;\n }\n }\n } catch (error) {\n console.error(`[CLI] ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(\"[CLI] Fatal error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["bosPlugin"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport * as p from \"@clack/prompts\";\nimport { findCommandDescriptor } from \"./cli/catalog\";\nimport { printHelp } from \"./cli/help\";\nimport { fetchParentConfig, runDockerComposeUp } from \"./cli/init\";\nimport { parseCommandInput } from \"./cli/parse\";\nimport { promptInitBasic, promptInitOverrides } from \"./cli/prompts\";\nimport { formatDuration, sumPhaseDurations } from \"./cli/timing\";\nimport { findConfigPath } from \"./config\";\nimport type {\n DevOptions,\n DevResult,\n InitOptions,\n InitResult,\n OverrideSection,\n StartOptions,\n StartResult,\n} from \"./contract\";\nimport type { ProgressEvent, StartSummary } from \"./plugin\";\nimport bosPlugin, { consumeDevSession, pluginEvents } from \"./plugin\";\nimport { createPluginRuntime } from \"./sdk\";\nimport { printBanner } from \"./utils/banner\";\nimport { colors, frames, gradients, icons } from \"./utils/theme\";\n\nfunction printConfigView(result: {\n account: string;\n domain?: string;\n staging?: { domain: string };\n app: {\n host: { name?: string; development: string; production?: string };\n ui: { name?: string; development?: string; production?: string; ssr?: string };\n api: { name?: string; development?: string; production?: string; proxy?: string };\n };\n}) {\n console.log();\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.app} ${gradients.cyber(\"CONFIG\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n\n console.log(` ${colors.dim(\"Account\")} ${colors.cyan(result.account)}`);\n console.log(` ${colors.dim(\"Domain\")} ${colors.white(result.domain ?? \"not configured\")}`);\n if (result.staging) {\n console.log(` ${colors.dim(\"Staging\")} ${colors.magenta(result.staging.domain)}`);\n }\n console.log();\n}\n\nfunction formatTimeAgo(isoTimestamp: string): string {\n const now = Date.now();\n const then = new Date(isoTimestamp).getTime();\n const diffMs = now - then;\n const diffMins = Math.floor(diffMs / 60_000);\n if (diffMins < 1) return \"just now\";\n if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? \"s\" : \"\"} ago`;\n const diffHours = Math.floor(diffMins / 60);\n if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? \"s\" : \"\"} ago`;\n const diffDays = Math.floor(diffHours / 24);\n if (diffDays < 30) return `${diffDays} day${diffDays > 1 ? \"s\" : \"\"} ago`;\n return isoTimestamp.split(\"T\")[0] ?? isoTimestamp;\n}\n\nfunction normalizeVersion(v: string): string {\n return v.replace(/^[\\^~>=v]+/, \"\").trim();\n}\n\nfunction printTimingSummary(timings: Array<{ name: string; durationMs: number }> | undefined) {\n if (!timings || timings.length === 0) return;\n\n console.log(` ${colors.dim(\"Timings:\")}`);\n for (const timing of timings) {\n console.log(` ${colors.dim(timing.name.padEnd(22))} ${formatDuration(timing.durationMs)}`);\n }\n console.log(\n ` ${colors.dim(\"total\".padEnd(22))} ${formatDuration(sumPhaseDurations(timings))}`,\n );\n}\n\nfunction printStartSummary(summary: StartSummary) {\n console.log();\n console.log(` ${colors.dim(\"Config Source:\")} ${summary.configSource}`);\n if (summary.configSourceHttp) {\n console.log(` ${colors.dim(summary.configSourceHttp)}`);\n }\n console.log(` ${colors.dim(\"Account:\")} ${summary.account}`);\n console.log(` ${colors.dim(\"Domain:\")} ${summary.domain ?? \"not configured\"}`);\n console.log();\n console.log(` ${colors.dim(\"Modules:\")}`);\n console.log(` ${colors.dim(\"HOST\")} → ${summary.modules.host ?? \"local\"}`);\n console.log(` ${colors.dim(\"UI\")} → ${summary.modules.ui ?? \"local\"}`);\n console.log(` ${colors.dim(\"API\")} → ${summary.modules.api ?? \"local\"}`);\n if (summary.modules.auth) {\n console.log(` ${colors.dim(\"AUTH\")} → ${summary.modules.auth}`);\n }\n if (summary.warnings.length > 0) {\n console.log();\n for (const w of summary.warnings) {\n console.log(` ${colors.yellow(w)}`);\n }\n }\n console.log();\n}\n\nasync function warnIfOutdated(client: any, command: string): Promise<void> {\n if (![\"dev\", \"build\", \"start\"].includes(command)) return;\n\n try {\n const status = await client.status();\n if (status.status === \"error\" || !status.packages) return;\n\n const frameworkPackages = [\"everything-dev\", \"every-plugin\"];\n\n const outdated = status.packages.filter(\n (p: { name: string; installed?: string; latest?: string }) =>\n p.installed &&\n p.latest &&\n normalizeVersion(p.installed) !== normalizeVersion(p.latest) &&\n frameworkPackages.includes(p.name),\n );\n\n if (outdated.length === 0) return;\n\n console.log();\n console.log(colors.yellow(` ! Outdated packages detected:`));\n for (const pkg of outdated) {\n console.log(colors.dim(` ${pkg.name} ${pkg.installed} → ${pkg.latest}`));\n }\n console.log(\n colors.dim(\n ` Run ${colors.cyan(\"bos upgrade\")} to update packages and sync template files.`,\n ),\n );\n console.log();\n } catch {\n // silently ignore if status check fails\n }\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n printHelp();\n return;\n }\n\n const invocationArgs = args.length > 0 ? args : [\"dev\"];\n const command = invocationArgs[0] ?? \"dev\";\n const configPath = findConfigPath();\n\n const commandMatch = findCommandDescriptor(invocationArgs);\n if (!commandMatch) {\n console.error(`Unknown command: ${command}`);\n process.exit(1);\n }\n\n const { descriptor, consumed } = commandMatch;\n const commandArgs = invocationArgs.slice(consumed);\n\n printBanner();\n\n const runtime = createPluginRuntime({\n registry: {\n bos: { module: bosPlugin },\n },\n secrets: {},\n });\n\n const pluginRuntime: any = runtime;\n const loadPlugin = pluginRuntime.usePlugin.bind(pluginRuntime);\n const plugin = await loadPlugin(\"bos\", {\n variables: {\n configPath: configPath ?? undefined,\n },\n secrets: {},\n });\n\n const client = plugin.createClient();\n\n await warnIfOutdated(client, command);\n\n try {\n const input = parseCommandInput(descriptor, commandArgs);\n\n if (descriptor.key === \"dev\") {\n const devSpinner = p.spinner();\n devSpinner.start(\"Starting dev environment\");\n\n const devPhaseLabels: Record<string, string> = {\n config: \"Preparing config...\",\n install: \"Installing dependencies...\",\n \"build plugin\": \"Building plugin...\",\n build: \"Building everything-dev...\",\n };\n\n const onDevProgress = (event: ProgressEvent) => {\n const label = devPhaseLabels[event.phase] ?? event.phase;\n if (event.status === \"running\") {\n devSpinner.message(label);\n }\n };\n pluginEvents.on(\"progress\", onDevProgress);\n\n let result: DevResult;\n try {\n result = await client.dev(input as DevOptions);\n } finally {\n pluginEvents.off(\"progress\", onDevProgress);\n }\n\n if (result.status === \"error\") {\n devSpinner.stop(\"Failed\");\n console.error(`[CLI] ${result.description}`);\n process.exit(1);\n }\n\n devSpinner.stop(result.description || \"Started\");\n\n const session = consumeDevSession();\n if (session) {\n const { devApp } = await import(\"./dev-session\");\n devApp(session.orchestrator, session.services, session.runtimeConfig);\n }\n return;\n }\n\n if (descriptor.key === \"start\") {\n const startSpinner = p.spinner();\n startSpinner.start(\"Starting production environment\");\n\n const startPhaseLabels: Record<string, string> = {\n config: \"Preparing config...\",\n \"generate artifacts\": \"Generating code artifacts...\",\n };\n\n const onStartProgress = (event: ProgressEvent) => {\n const label = startPhaseLabels[event.phase] ?? event.phase;\n if (event.status === \"running\") {\n startSpinner.message(label);\n }\n };\n pluginEvents.on(\"progress\", onStartProgress);\n\n let result: StartResult;\n try {\n result = await client.start(input as StartOptions);\n } finally {\n pluginEvents.off(\"progress\", onStartProgress);\n }\n\n if (result.status === \"error\") {\n startSpinner.stop(\"Failed\");\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n\n startSpinner.stop(\"Ready\");\n\n const session = consumeDevSession();\n if (session) {\n const summary = session.summary;\n if (summary) {\n printStartSummary(summary);\n }\n const { startApp } = await import(\"./dev-session\");\n startApp(session.orchestrator, session.services, session.runtimeConfig);\n }\n return;\n }\n\n if (descriptor.key === \"init\") {\n let initInput: InitOptions = { ...(input as InitOptions) };\n\n if (!initInput.noInteractive) {\n const basic = await promptInitBasic({\n extends: initInput.extends,\n account: initInput.account,\n domain: initInput.domain,\n });\n\n let parentPluginKeys: string[] = [];\n let parentConfig: {\n title?: string;\n description?: string;\n plugins?: Record<string, unknown>;\n } | null = null;\n\n const fetchSpinner = p.spinner();\n fetchSpinner.start(\"Fetching parent config\");\n try {\n parentConfig = await fetchParentConfig(basic.extendsAccount, basic.extendsGateway);\n if (parentConfig?.plugins && typeof parentConfig.plugins === \"object\") {\n parentPluginKeys = Object.keys(parentConfig.plugins);\n }\n } catch {\n fetchSpinner.stop(\"Config not found\");\n console.error(\n `[CLI] No config found at bos://${basic.extendsAccount}/${basic.extendsGateway}`,\n );\n process.exit(1);\n }\n fetchSpinner.stop(\"Config fetched\");\n\n if (\n typeof parentConfig?.title === \"string\" &&\n parentConfig.title.trim() &&\n typeof parentConfig?.description === \"string\" &&\n parentConfig.description.trim()\n ) {\n const shouldContinue = await p.confirm({\n message: `You will be extending ${parentConfig.title} - ${parentConfig.description}. Continue?`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldContinue) || !shouldContinue) {\n process.exit(0);\n }\n }\n\n const overrides = await promptInitOverrides({\n parentPluginKeys,\n plugins: initInput.plugins,\n overrides: initInput.overrides as OverrideSection[] | undefined,\n });\n\n const directory = initInput.directory || basic.domain || basic.extendsGateway;\n\n initInput = {\n ...initInput,\n extends: `bos://${basic.extendsAccount}/${basic.extendsGateway}`,\n directory,\n account: basic.account,\n domain: basic.domain || undefined,\n plugins: overrides.plugins,\n overrides: overrides.overrides,\n noInteractive: true,\n };\n }\n\n const initSpinner = p.spinner();\n initSpinner.start(\"Initializing project\");\n\n const phaseLabels: Record<string, string> = {\n \"parent config\": \"Fetching parent config...\",\n \"template source\": \"Resolving template source...\",\n \"scaffold project\": \"Creating project scaffold...\",\n \"copy files\": \"Copying template files...\",\n \"personalize config\": \"Personalizing config...\",\n \"write snapshot\": \"Writing snapshot...\",\n \"resolve config\": \"Resolving config...\",\n \"generate env/docker\": \"Generating environment config...\",\n \"create env file\": \"Creating .env file...\",\n \"install dependencies\": \"Installing dependencies...\",\n \"generate types\": \"Generating types...\",\n \"generate migrations\": \"Generating database migrations...\",\n \"generate code artifacts\": \"Generating code artifacts...\",\n };\n\n const onProgress = (event: ProgressEvent) => {\n const label = phaseLabels[event.phase] ?? event.phase;\n if (event.status === \"running\") {\n initSpinner.message(label);\n }\n };\n pluginEvents.on(\"progress\", onProgress);\n\n let result: InitResult;\n try {\n result = await client.init(initInput);\n } finally {\n pluginEvents.off(\"progress\", onProgress);\n }\n\n if (result.status === \"error\") {\n initSpinner.stop(\"Failed\");\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n\n initSpinner.stop(\"Project initialized\");\n\n console.log(` ${colors.dim(\"Extends:\")} ${result.extends}`);\n console.log(` ${colors.dim(\"Directory:\")} ${result.directory}`);\n if (result.account) console.log(` ${colors.dim(\"Account:\")} ${result.account}`);\n if (result.domain) console.log(` ${colors.dim(\"Domain:\")} ${result.domain}`);\n if (result.overrides && result.overrides.length > 0)\n console.log(` ${colors.dim(\"Overrides:\")} ${result.overrides.join(\", \")}`);\n if (result.plugins && result.plugins.length > 0)\n console.log(` ${colors.dim(\"Plugins:\")} ${result.plugins.join(\", \")}`);\n console.log(` ${colors.dim(\"Files copied:\")} ${result.filesCopied}`);\n printTimingSummary(result.timings);\n console.log();\n console.log(colors.dim(\" Next steps:\"));\n console.log(colors.dim(` cd ${result.directory}`));\n if (!initInput.noInstall) {\n console.log(colors.dim(\" docker compose up -d --wait\"));\n console.log(colors.dim(\" bun run dev\"));\n } else {\n console.log(colors.dim(\" bun install\"));\n console.log(colors.dim(\" docker compose up -d --wait\"));\n console.log(colors.dim(\" bun run dev\"));\n }\n console.log();\n\n if (initInput.noInteractive !== true && !initInput.noInstall && result.targetDir) {\n const shouldStartDocker = await p.confirm({\n message: \"Run docker compose up -d --wait?\",\n initialValue: true,\n });\n\n if (shouldStartDocker === true) {\n const dockerSpinner = p.spinner();\n dockerSpinner.start(\"Starting Docker services\");\n try {\n await runDockerComposeUp(result.targetDir);\n dockerSpinner.stop(\"Docker services ready\");\n } catch (error) {\n dockerSpinner.stop(\"Docker services not started\");\n p.log.warn(\n `docker compose up -d --wait failed: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n }\n\n return;\n }\n\n const result = await (client as any)[descriptor.key](input);\n\n if (descriptor.key === \"config\") {\n if (!result.config) {\n console.error(\"No bos.config.json found\");\n process.exit(1);\n }\n\n printConfigView(result.config);\n process.stdout.write(`${JSON.stringify(result.config, null, 2)}\\n`);\n return;\n }\n\n if (descriptor.key === \"sync\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n if (result.status === \"dry-run\") {\n console.log(colors.cyan(`${icons.ok} Dry run — no files written`));\n } else {\n console.log(colors.green(`${icons.ok} Template synced`));\n }\n if (result.updated.length > 0) {\n console.log(` ${colors.dim(\"Updated:\")} ${result.updated.length} file(s)`);\n for (const f of result.updated) console.log(` ${colors.dim(f)}`);\n }\n if (result.added.length > 0) {\n console.log(` ${colors.dim(\"Added:\")} ${result.added.length} file(s)`);\n for (const f of result.added) console.log(` ${colors.dim(f)}`);\n }\n if (result.skipped.length > 0) {\n console.log(\n ` ${colors.yellow(\"Skipped:\")} ${result.skipped.length} file(s) (locally modified, use --force to overwrite)`,\n );\n for (const f of result.skipped) console.log(` ${colors.dim(f)}`);\n }\n if (result.updated.length === 0 && result.added.length === 0 && result.skipped.length === 0) {\n console.log(` ${colors.dim(\"Already up to date\")}`);\n }\n if (result.status !== \"dry-run\" && result.updated.length > 0) {\n console.log();\n console.log(colors.dim(\" Review changes — your customizations take priority:\"));\n console.log(\n colors.dim(\n \" • api/src/contract.ts, api/src/index.ts, api/src/db/schema.ts — never overwritten\",\n ),\n );\n console.log(\n colors.dim(\" • ui/src/components/**, ui/src/styles.css — never overwritten\"),\n );\n console.log(\n colors.dim(\n \" • Other updated files — accept framework improvements, then restore your changes\",\n ),\n );\n console.log(colors.dim(\" • Skipped files — yours already, only update with --force\"));\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"upgrade\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n if (result.status === \"dry-run\") {\n console.log(colors.cyan(`${icons.ok} Dry run — no changes applied`));\n } else {\n console.log(colors.green(`${icons.ok} Upgrade successful`));\n }\n for (const pkg of result.packages) {\n if (pkg.from && pkg.from !== pkg.to) {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.from} → ${pkg.to}`);\n } else if (!pkg.from) {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.to} (new)`);\n } else {\n console.log(` ${colors.dim(`${pkg.name}:`)} ${pkg.to} (up to date)`);\n }\n }\n if (result.changelogUrl) {\n console.log(` ${colors.dim(\"Changelog:\")} ${result.changelogUrl}`);\n }\n if (result.availablePlugins && result.availablePlugins.length > 0) {\n console.log(` ${colors.dim(\"New parent plugins:\")} ${result.availablePlugins.join(\", \")}`);\n }\n if (result.selectedPlugins && result.selectedPlugins.length > 0) {\n console.log(` ${colors.dim(\"Added plugins:\")} ${result.selectedPlugins.join(\", \")}`);\n }\n printTimingSummary(result.timings);\n if (result.sync) {\n const sync = result.sync;\n if (sync.updated.length > 0) {\n console.log(` ${colors.dim(\"Updated:\")} ${sync.updated.length} file(s)`);\n for (const f of sync.updated) console.log(` ${colors.dim(f)}`);\n }\n if (sync.added.length > 0) {\n console.log(` ${colors.dim(\"Added:\")} ${sync.added.length} file(s)`);\n for (const f of sync.added) console.log(` ${colors.dim(f)}`);\n }\n if (sync.skipped.length > 0) {\n console.log(\n ` ${colors.yellow(\"Skipped:\")} ${sync.skipped.length} file(s) (locally modified, use --force to overwrite)`,\n );\n for (const f of sync.skipped) console.log(` ${colors.dim(f)}`);\n }\n if (\n result.status !== \"dry-run\" &&\n (sync.updated.length > 0 || sync.added.length > 0 || sync.skipped.length > 0)\n ) {\n console.log();\n console.log(colors.dim(\" Resolve differences — your code takes priority:\"));\n console.log();\n console.log(colors.dim(\" Never overwritten (safe):\"));\n console.log(\n colors.dim(\" • api/src/contract.ts, api/src/index.ts, api/src/db/schema.ts\"),\n );\n console.log(colors.dim(\" • ui/src/components/**, ui/src/styles.css\"));\n console.log();\n console.log(colors.dim(\" Replaced — review and keep your changes:\"));\n console.log(\n colors.dim(\n \" • api/drizzle.config.ts, api/tsconfig.json, api/tsconfig.contract.json\",\n ),\n );\n console.log(colors.dim(\" • api/plugin.dev.ts, api/rspack.config.js\"));\n console.log(colors.dim(\" • ui/src/routes/* (core routes only)\"));\n console.log();\n console.log(colors.dim(\" Merged — your deps preserved:\"));\n console.log(colors.dim(\" • package.json, api/package.json, ui/package.json\"));\n console.log();\n console.log(colors.dim(\" Skipped — already yours:\"));\n console.log(colors.dim(\" • Use --force only if you want framework updates\"));\n }\n }\n if (result.migrated && result.migrated.length > 0) {\n console.log(` ${colors.yellow(\"Removed:\")} ${result.migrated.length} obsolete file(s)`);\n for (const f of result.migrated) console.log(` ${colors.dim(f)}`);\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"status\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.app} ${gradients.cyber(\"STATUS\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n if (result.extends) console.log(` ${colors.dim(\"Extends:\")} ${result.extends}`);\n if (result.account) console.log(` ${colors.dim(\"Account:\")} ${result.account}`);\n if (result.domain) console.log(` ${colors.dim(\"Domain:\")} ${result.domain}`);\n console.log();\n console.log(` ${colors.dim(\"Packages:\")}`);\n for (const pkg of result.packages) {\n const hasUpdate =\n pkg.installed &&\n pkg.latest &&\n normalizeVersion(pkg.installed) !== normalizeVersion(pkg.latest);\n const versionStr = hasUpdate\n ? `${pkg.installed} → ${pkg.latest}`\n : pkg.installed || \"not installed\";\n const label = hasUpdate ? colors.yellow(versionStr) : colors.dim(versionStr);\n console.log(` ${colors.dim(`${pkg.name}`)} ${label}`);\n }\n console.log();\n if (result.lastSync) {\n const ago = formatTimeAgo(result.lastSync);\n console.log(` ${colors.dim(\"Last sync:\")} ${ago}`);\n } else {\n console.log(` ${colors.dim(\"Last sync:\")} never`);\n }\n const envLabel =\n result.envFile === \"found\"\n ? colors.green(\"found\")\n : result.envFile === \"example-only\"\n ? colors.yellow(\"missing (only .env.example found)\")\n : colors.error(\"missing\");\n console.log(` ${colors.dim(\".env:\")} ${envLabel}`);\n if (result.parentReachable !== undefined) {\n const parentLabel = result.parentReachable\n ? colors.green(\"reachable\")\n : colors.error(\"unreachable\");\n console.log(` ${colors.dim(\"Parent:\")} ${parentLabel}`);\n }\n const hasUpdates = result.packages.some(\n (p: { installed?: string; latest?: string }) =>\n p.installed && p.latest && normalizeVersion(p.installed) !== normalizeVersion(p.latest),\n );\n if (hasUpdates) {\n console.log();\n console.log(\n colors.dim(\n ` Run ${colors.cyan(\"bos upgrade\")} to update packages and sync template files.`,\n ),\n );\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"typesGen\") {\n console.log();\n if (result.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n console.log(colors.green(`${icons.ok} Types generated`));\n if (result.source) {\n console.log(\n ` ${colors.dim(\"Mode:\")} ${result.source === \"remote\" ? colors.cyan(\"remote\") : colors.dim(\"local\")}`,\n );\n }\n if (result.generated.length > 0) {\n console.log(` ${colors.dim(\"Generated:\")}`);\n for (const f of result.generated) console.log(` ${colors.dim(f)}`);\n }\n if (result.fetched.length > 0) {\n console.log(` ${colors.dim(\"Fetched from remote:\")}`);\n for (const url of result.fetched) console.log(` ${colors.dim(url)}`);\n }\n if (result.skipped.length > 0) {\n console.log(` ${colors.dim(\"Skipped (local):\")}`);\n for (const s of result.skipped) console.log(` ${colors.dim(s)}`);\n }\n if (result.failed.length > 0) {\n console.log(` ${colors.yellow(\"Failed:\")}`);\n for (const f of result.failed) console.log(` ${colors.error(f)}`);\n }\n console.log();\n return;\n }\n\n if (result?.status === \"error\") {\n console.error(`[CLI] ${result.error || \"Unknown error\"}`);\n process.exit(1);\n }\n\n if (descriptor.key === \"keyPublish\") {\n process.stdout.write(`Generated publish key for ${result.account}\\n`);\n process.stdout.write(` Network: ${result.network}\\n`);\n process.stdout.write(` Contract: ${result.contract}\\n`);\n process.stdout.write(` Allowance: ${result.allowance}\\n`);\n process.stdout.write(` Functions: ${result.functionNames.join(\", \")}\\n`);\n process.stdout.write(` Public key: ${result.publicKey}\\n`);\n process.stdout.write(` Private key: ${result.privateKey}\\n`);\n process.stdout.write(` Copy: NEAR_PRIVATE_KEY=${result.privateKey}\\n`);\n }\n\n if (descriptor.key === \"pluginAdd\") {\n console.log();\n console.log(colors.green(`${icons.ok} Added plugin ${result.key}`));\n if (result.development) console.log(` ${colors.dim(\"Development:\")} ${result.development}`);\n if (result.production) console.log(` ${colors.dim(\"Production:\")} ${result.production}`);\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginRemove\") {\n console.log();\n console.log(colors.green(`${icons.ok} Removed plugin ${result.key}`));\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginList\") {\n console.log();\n console.log(colors.cyan(frames.top(52)));\n console.log(` ${icons.config} ${gradients.cyber(\"PLUGINS\")}`);\n console.log(colors.cyan(frames.bottom(52)));\n console.log();\n if (result.plugins.length === 0) {\n console.log(colors.dim(\" No plugins configured\"));\n } else {\n for (const pluginItem of result.plugins) {\n console.log(` ${colors.cyan(pluginItem.key)}`);\n if (pluginItem.development)\n console.log(` ${colors.dim(\"Development:\")} ${pluginItem.development}`);\n if (pluginItem.production)\n console.log(` ${colors.dim(\"Production:\")} ${pluginItem.production}`);\n }\n }\n console.log();\n return;\n }\n\n if (descriptor.key === \"pluginPublish\") {\n console.log();\n console.log(colors.green(`${icons.ok} Published plugin ${result.key}`));\n if (result.path) console.log(` ${colors.dim(\"Path:\")} ${result.path}`);\n if (result.script) console.log(` ${colors.dim(\"Script:\")} bun run ${result.script}`);\n if (result.production) console.log(` ${colors.dim(\"Production:\")} ${result.production}`);\n console.log();\n return;\n }\n\n if (descriptor.key === \"publish\") {\n if (result.status === \"dry-run\") {\n console.log();\n console.log(colors.cyan(`${icons.ok} Dry run complete`));\n console.log(` ${colors.dim(\"Registry URL:\")} ${result.registryUrl}`);\n console.log();\n return;\n }\n\n if (result.status === \"published\") {\n console.log();\n console.log(colors.green(`${icons.ok} Published successfully`));\n console.log(` ${colors.dim(\"Registry URL:\")} ${result.registryUrl}`);\n if (result.txHash) {\n console.log(` ${colors.dim(\"Transaction:\")} ${result.txHash}`);\n }\n if (result.built && result.built.length > 0) {\n console.log(` ${colors.dim(\"Built:\")} ${result.built.join(\", \")}`);\n }\n if (result.skipped && result.skipped.length > 0) {\n console.log(` ${colors.dim(\"Skipped:\")} ${result.skipped.join(\", \")}`);\n }\n console.log();\n return;\n }\n }\n } catch (error) {\n console.error(`[CLI] ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(\"[CLI] Fatal error:\", error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,SAAS,gBAAgB,QAStB;AACD,SAAQ,KAAK;AACb,SAAQ,IAAI,OAAO,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC;AACxC,SAAQ,IAAI,KAAK,MAAM,IAAI,GAAG,UAAU,MAAM,SAAS,GAAG;AAC1D,SAAQ,IAAI,OAAO,KAAK,OAAO,OAAO,GAAG,CAAC,CAAC;AAC3C,SAAQ,KAAK;AAEb,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,IAAI,OAAO,KAAK,OAAO,QAAQ,GAAG;AACzE,SAAQ,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,KAAK,OAAO,MAAM,OAAO,UAAU,iBAAiB,GAAG;AAC7F,KAAI,OAAO,QACT,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,IAAI,OAAO,QAAQ,OAAO,QAAQ,OAAO,GAAG;AAErF,SAAQ,KAAK;;AAGf,SAAS,cAAc,cAA8B;CAGnD,MAAM,SAFM,KAAK,KAEC,GADL,IAAI,KAAK,aAAa,CAAC,SACX;CACzB,MAAM,WAAW,KAAK,MAAM,SAAS,IAAO;AAC5C,KAAI,WAAW,EAAG,QAAO;AACzB,KAAI,WAAW,GAAI,QAAO,GAAG,SAAS,SAAS,WAAW,IAAI,MAAM,GAAG;CACvE,MAAM,YAAY,KAAK,MAAM,WAAW,GAAG;AAC3C,KAAI,YAAY,GAAI,QAAO,GAAG,UAAU,OAAO,YAAY,IAAI,MAAM,GAAG;CACxE,MAAM,WAAW,KAAK,MAAM,YAAY,GAAG;AAC3C,KAAI,WAAW,GAAI,QAAO,GAAG,SAAS,MAAM,WAAW,IAAI,MAAM,GAAG;AACpE,QAAO,aAAa,MAAM,IAAI,CAAC,MAAM;;AAGvC,SAAS,iBAAiB,GAAmB;AAC3C,QAAO,EAAE,QAAQ,cAAc,GAAG,CAAC,MAAM;;AAG3C,SAAS,mBAAmB,SAAkE;AAC5F,KAAI,CAAC,WAAW,QAAQ,WAAW,EAAG;AAEtC,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,GAAG;AAC1C,MAAK,MAAM,UAAU,QACnB,SAAQ,IAAI,OAAO,OAAO,IAAI,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,GAAG,eAAe,OAAO,WAAW,GAAG;AAE/F,SAAQ,IACN,OAAO,OAAO,IAAI,QAAQ,OAAO,GAAG,CAAC,CAAC,GAAG,eAAe,kBAAkB,QAAQ,CAAC,GACpF;;AAGH,SAAS,kBAAkB,SAAuB;AAChD,SAAQ,KAAK;AACb,SAAQ,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,IAAI,QAAQ,eAAe;AACzE,KAAI,QAAQ,iBACV,SAAQ,IAAI,qBAAqB,OAAO,IAAI,QAAQ,iBAAiB,GAAG;AAE1E,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,UAAU,QAAQ,UAAU;AACpE,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,WAAW,QAAQ,UAAU,mBAAmB;AACvF,SAAQ,KAAK;AACb,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,GAAG;AAC1C,SAAQ,IAAI,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,QAAQ,QAAQ,QAAQ,UAAU;AAC9E,SAAQ,IAAI,OAAO,OAAO,IAAI,KAAK,CAAC,OAAO,QAAQ,QAAQ,MAAM,UAAU;AAC3E,SAAQ,IAAI,OAAO,OAAO,IAAI,MAAM,CAAC,MAAM,QAAQ,QAAQ,OAAO,UAAU;AAC5E,KAAI,QAAQ,QAAQ,KAClB,SAAQ,IAAI,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,QAAQ,QAAQ,OAAO;AAErE,KAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,UAAQ,KAAK;AACb,OAAK,MAAM,KAAK,QAAQ,SACtB,SAAQ,IAAI,KAAK,OAAO,OAAO,EAAE,GAAG;;AAGxC,SAAQ,KAAK;;AAGf,eAAe,eAAe,QAAa,SAAgC;AACzE,KAAI,CAAC;EAAC;EAAO;EAAS;EAAQ,CAAC,SAAS,QAAQ,CAAE;AAElD,KAAI;EACF,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,MAAI,OAAO,WAAW,WAAW,CAAC,OAAO,SAAU;EAEnD,MAAM,oBAAoB,CAAC,kBAAkB,eAAe;EAE5D,MAAM,WAAW,OAAO,SAAS,QAC9B,MACC,EAAE,aACF,EAAE,UACF,iBAAiB,EAAE,UAAU,KAAK,iBAAiB,EAAE,OAAO,IAC5D,kBAAkB,SAAS,EAAE,KAAK,CACrC;AAED,MAAI,SAAS,WAAW,EAAG;AAE3B,UAAQ,KAAK;AACb,UAAQ,IAAI,OAAO,OAAO,kCAAkC,CAAC;AAC7D,OAAK,MAAM,OAAO,SAChB,SAAQ,IAAI,OAAO,IAAI,OAAO,IAAI,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI,SAAS,CAAC;AAE9E,UAAQ,IACN,OAAO,IACL,WAAW,OAAO,KAAK,cAAc,CAAC,8CACvC,CACF;AACD,UAAQ,KAAK;SACP;;AAKV,eAAe,OAAO;CACpB,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAElC,KAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,KAAK,EAAE;AAClD,aAAW;AACX;;CAGF,MAAM,iBAAiB,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM;CACvD,MAAM,UAAU,eAAe,MAAM;CACrC,MAAM,aAAa,gBAAgB;CAEnC,MAAM,eAAe,sBAAsB,eAAe;AAC1D,KAAI,CAAC,cAAc;AACjB,UAAQ,MAAM,oBAAoB,UAAU;AAC5C,UAAQ,KAAK,EAAE;;CAGjB,MAAM,EAAE,YAAY,aAAa;CACjC,MAAM,cAAc,eAAe,MAAM,SAAS;AAElD,cAAa;CASb,MAAM,gBAPU,oBAAoB;EAClC,UAAU,EACR,KAAK,EAAE,QAAQA,gBAAW,EAC3B;EACD,SAAS,EAAE;EACZ,CAEiC;CASlC,MAAM,UAAS,MARI,cAAc,UAAU,KAAK,cACjB,CAAC,OAAO;EACrC,WAAW,EACT,YAAY,cAAc,QAC3B;EACD,SAAS,EAAE;EACZ,CAAC,EAEoB,cAAc;AAEpC,OAAM,eAAe,QAAQ,QAAQ;AAErC,KAAI;EACF,MAAM,QAAQ,kBAAkB,YAAY,YAAY;AAExD,MAAI,WAAW,QAAQ,OAAO;GAC5B,MAAM,aAAa,EAAE,SAAS;AAC9B,cAAW,MAAM,2BAA2B;GAE5C,MAAM,iBAAyC;IAC7C,QAAQ;IACR,SAAS;IACT,gBAAgB;IAChB,OAAO;IACR;GAED,MAAM,iBAAiB,UAAyB;IAC9C,MAAM,QAAQ,eAAe,MAAM,UAAU,MAAM;AACnD,QAAI,MAAM,WAAW,UACnB,YAAW,QAAQ,MAAM;;AAG7B,gBAAa,GAAG,YAAY,cAAc;GAE1C,IAAI;AACJ,OAAI;AACF,aAAS,MAAM,OAAO,IAAI,MAAoB;aACtC;AACR,iBAAa,IAAI,YAAY,cAAc;;AAG7C,OAAI,OAAO,WAAW,SAAS;AAC7B,eAAW,KAAK,SAAS;AACzB,YAAQ,MAAM,SAAS,OAAO,cAAc;AAC5C,YAAQ,KAAK,EAAE;;AAGjB,cAAW,KAAK,OAAO,eAAe,UAAU;GAEhD,MAAM,UAAU,mBAAmB;AACnC,OAAI,SAAS;IACX,MAAM,EAAE,WAAW,MAAM,OAAO;AAChC,WAAO,QAAQ,cAAc,QAAQ,UAAU,QAAQ,cAAc;;AAEvE;;AAGF,MAAI,WAAW,QAAQ,SAAS;GAC9B,MAAM,eAAe,EAAE,SAAS;AAChC,gBAAa,MAAM,kCAAkC;GAErD,MAAM,mBAA2C;IAC/C,QAAQ;IACR,sBAAsB;IACvB;GAED,MAAM,mBAAmB,UAAyB;IAChD,MAAM,QAAQ,iBAAiB,MAAM,UAAU,MAAM;AACrD,QAAI,MAAM,WAAW,UACnB,cAAa,QAAQ,MAAM;;AAG/B,gBAAa,GAAG,YAAY,gBAAgB;GAE5C,IAAI;AACJ,OAAI;AACF,aAAS,MAAM,OAAO,MAAM,MAAsB;aAC1C;AACR,iBAAa,IAAI,YAAY,gBAAgB;;AAG/C,OAAI,OAAO,WAAW,SAAS;AAC7B,iBAAa,KAAK,SAAS;AAC3B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAGjB,gBAAa,KAAK,QAAQ;GAE1B,MAAM,UAAU,mBAAmB;AACnC,OAAI,SAAS;IACX,MAAM,UAAU,QAAQ;AACxB,QAAI,QACF,mBAAkB,QAAQ;IAE5B,MAAM,EAAE,aAAa,MAAM,OAAO;AAClC,aAAS,QAAQ,cAAc,QAAQ,UAAU,QAAQ,cAAc;;AAEzE;;AAGF,MAAI,WAAW,QAAQ,QAAQ;GAC7B,IAAI,YAAyB,EAAE,GAAI,OAAuB;AAE1D,OAAI,CAAC,UAAU,eAAe;IAC5B,MAAM,QAAQ,MAAM,gBAAgB;KAClC,SAAS,UAAU;KACnB,SAAS,UAAU;KACnB,QAAQ,UAAU;KACnB,CAAC;IAEF,IAAI,mBAA6B,EAAE;IACnC,IAAI,eAIO;IAEX,MAAM,eAAe,EAAE,SAAS;AAChC,iBAAa,MAAM,yBAAyB;AAC5C,QAAI;AACF,oBAAe,MAAM,kBAAkB,MAAM,gBAAgB,MAAM,eAAe;AAClF,SAAI,cAAc,WAAW,OAAO,aAAa,YAAY,SAC3D,oBAAmB,OAAO,KAAK,aAAa,QAAQ;YAEhD;AACN,kBAAa,KAAK,mBAAmB;AACrC,aAAQ,MACN,kCAAkC,MAAM,eAAe,GAAG,MAAM,iBACjE;AACD,aAAQ,KAAK,EAAE;;AAEjB,iBAAa,KAAK,iBAAiB;AAEnC,QACE,OAAO,cAAc,UAAU,YAC/B,aAAa,MAAM,MAAM,IACzB,OAAO,cAAc,gBAAgB,YACrC,aAAa,YAAY,MAAM,EAC/B;KACA,MAAM,iBAAiB,MAAM,EAAE,QAAQ;MACrC,SAAS,yBAAyB,aAAa,MAAM,KAAK,aAAa,YAAY;MACnF,cAAc;MACf,CAAC;AAEF,SAAI,EAAE,SAAS,eAAe,IAAI,CAAC,eACjC,SAAQ,KAAK,EAAE;;IAInB,MAAM,YAAY,MAAM,oBAAoB;KAC1C;KACA,SAAS,UAAU;KACnB,WAAW,UAAU;KACtB,CAAC;IAEF,MAAM,YAAY,UAAU,aAAa,MAAM,UAAU,MAAM;AAE/D,gBAAY;KACV,GAAG;KACH,SAAS,SAAS,MAAM,eAAe,GAAG,MAAM;KAChD;KACA,SAAS,MAAM;KACf,QAAQ,MAAM,UAAU;KACxB,SAAS,UAAU;KACnB,WAAW,UAAU;KACrB,eAAe;KAChB;;GAGH,MAAM,cAAc,EAAE,SAAS;AAC/B,eAAY,MAAM,uBAAuB;GAEzC,MAAM,cAAsC;IAC1C,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,cAAc;IACd,sBAAsB;IACtB,kBAAkB;IAClB,kBAAkB;IAClB,uBAAuB;IACvB,mBAAmB;IACnB,wBAAwB;IACxB,kBAAkB;IAClB,uBAAuB;IACvB,2BAA2B;IAC5B;GAED,MAAM,cAAc,UAAyB;IAC3C,MAAM,QAAQ,YAAY,MAAM,UAAU,MAAM;AAChD,QAAI,MAAM,WAAW,UACnB,aAAY,QAAQ,MAAM;;AAG9B,gBAAa,GAAG,YAAY,WAAW;GAEvC,IAAI;AACJ,OAAI;AACF,aAAS,MAAM,OAAO,KAAK,UAAU;aAC7B;AACR,iBAAa,IAAI,YAAY,WAAW;;AAG1C,OAAI,OAAO,WAAW,SAAS;AAC7B,gBAAY,KAAK,SAAS;AAC1B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAGjB,eAAY,KAAK,sBAAsB;AAEvC,WAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,OAAO,UAAU;AAC5D,WAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,YAAY;AAChE,OAAI,OAAO,QAAS,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,OAAO,UAAU;AAChF,OAAI,OAAO,OAAQ,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,GAAG,OAAO,SAAS;AAC7E,OAAI,OAAO,aAAa,OAAO,UAAU,SAAS,EAChD,SAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,UAAU,KAAK,KAAK,GAAG;AAC7E,OAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,EAC5C,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,OAAO,QAAQ,KAAK,KAAK,GAAG;AACzE,WAAQ,IAAI,KAAK,OAAO,IAAI,gBAAgB,CAAC,GAAG,OAAO,cAAc;AACrE,sBAAmB,OAAO,QAAQ;AAClC,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,IAAI,gBAAgB,CAAC;AACxC,WAAQ,IAAI,OAAO,IAAI,UAAU,OAAO,YAAY,CAAC;AACrD,OAAI,CAAC,UAAU,WAAW;AACxB,YAAQ,IAAI,OAAO,IAAI,kCAAkC,CAAC;AAC1D,YAAQ,IAAI,OAAO,IAAI,kBAAkB,CAAC;UACrC;AACL,YAAQ,IAAI,OAAO,IAAI,kBAAkB,CAAC;AAC1C,YAAQ,IAAI,OAAO,IAAI,kCAAkC,CAAC;AAC1D,YAAQ,IAAI,OAAO,IAAI,kBAAkB,CAAC;;AAE5C,WAAQ,KAAK;AAEb,OAAI,UAAU,kBAAkB,QAAQ,CAAC,UAAU,aAAa,OAAO,WAMrE;QAAI,MAL4B,EAAE,QAAQ;KACxC,SAAS;KACT,cAAc;KACf,CAAC,KAEwB,MAAM;KAC9B,MAAM,gBAAgB,EAAE,SAAS;AACjC,mBAAc,MAAM,2BAA2B;AAC/C,SAAI;AACF,YAAM,mBAAmB,OAAO,UAAU;AAC1C,oBAAc,KAAK,wBAAwB;cACpC,OAAO;AACd,oBAAc,KAAK,8BAA8B;AACjD,QAAE,IAAI,KACJ,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,QACjF;;;;AAKP;;EAGF,MAAM,SAAS,MAAO,OAAe,WAAW,KAAK,MAAM;AAE3D,MAAI,WAAW,QAAQ,UAAU;AAC/B,OAAI,CAAC,OAAO,QAAQ;AAClB,YAAQ,MAAM,2BAA2B;AACzC,YAAQ,KAAK,EAAE;;AAGjB,mBAAgB,OAAO,OAAO;AAC9B,WAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE,CAAC,IAAI;AACnE;;AAGF,MAAI,WAAW,QAAQ,QAAQ;AAC7B,WAAQ,KAAK;AACb,OAAI,OAAO,WAAW,SAAS;AAC7B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAEjB,OAAI,OAAO,WAAW,UACpB,SAAQ,IAAI,OAAO,KAAK,GAAG,MAAM,GAAG,6BAA6B,CAAC;OAElE,SAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAE1D,OAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,OAAO,QAAQ,OAAO,UAAU;AAC3E,SAAK,MAAM,KAAK,OAAO,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAErE,OAAI,OAAO,MAAM,SAAS,GAAG;AAC3B,YAAQ,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,GAAG,OAAO,MAAM,OAAO,UAAU;AACvE,SAAK,MAAM,KAAK,OAAO,MAAO,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEnE,OAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,IACN,KAAK,OAAO,OAAO,WAAW,CAAC,GAAG,OAAO,QAAQ,OAAO,uDACzD;AACD,SAAK,MAAM,KAAK,OAAO,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAErE,OAAI,OAAO,QAAQ,WAAW,KAAK,OAAO,MAAM,WAAW,KAAK,OAAO,QAAQ,WAAW,EACxF,SAAQ,IAAI,KAAK,OAAO,IAAI,qBAAqB,GAAG;AAEtD,OAAI,OAAO,WAAW,aAAa,OAAO,QAAQ,SAAS,GAAG;AAC5D,YAAQ,KAAK;AACb,YAAQ,IAAI,OAAO,IAAI,wDAAwD,CAAC;AAChF,YAAQ,IACN,OAAO,IACL,wFACD,CACF;AACD,YAAQ,IACN,OAAO,IAAI,oEAAoE,CAChF;AACD,YAAQ,IACN,OAAO,IACL,uFACD,CACF;AACD,YAAQ,IAAI,OAAO,IAAI,gEAAgE,CAAC;;AAE1F,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,WAAW;AAChC,WAAQ,KAAK;AACb,OAAI,OAAO,WAAW,SAAS;AAC7B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAEjB,OAAI,OAAO,WAAW,UACpB,SAAQ,IAAI,OAAO,KAAK,GAAG,MAAM,GAAG,+BAA+B,CAAC;OAEpE,SAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,qBAAqB,CAAC;AAE7D,QAAK,MAAM,OAAO,OAAO,SACvB,KAAI,IAAI,QAAQ,IAAI,SAAS,IAAI,GAC/B,SAAQ,IAAI,KAAK,OAAO,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,KAAK,KAAK,IAAI,KAAK;YAC7D,CAAC,IAAI,KACd,SAAQ,IAAI,KAAK,OAAO,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,QAAQ;OAE9D,SAAQ,IAAI,KAAK,OAAO,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,eAAe;AAGzE,OAAI,OAAO,aACT,SAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,eAAe;AAErE,OAAI,OAAO,oBAAoB,OAAO,iBAAiB,SAAS,EAC9D,SAAQ,IAAI,KAAK,OAAO,IAAI,sBAAsB,CAAC,GAAG,OAAO,iBAAiB,KAAK,KAAK,GAAG;AAE7F,OAAI,OAAO,mBAAmB,OAAO,gBAAgB,SAAS,EAC5D,SAAQ,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,GAAG,OAAO,gBAAgB,KAAK,KAAK,GAAG;AAEvF,sBAAmB,OAAO,QAAQ;AAClC,OAAI,OAAO,MAAM;IACf,MAAM,OAAO,OAAO;AACpB,QAAI,KAAK,QAAQ,SAAS,GAAG;AAC3B,aAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,KAAK,QAAQ,OAAO,UAAU;AACzE,UAAK,MAAM,KAAK,KAAK,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEnE,QAAI,KAAK,MAAM,SAAS,GAAG;AACzB,aAAQ,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,GAAG,KAAK,MAAM,OAAO,UAAU;AACrE,UAAK,MAAM,KAAK,KAAK,MAAO,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEjE,QAAI,KAAK,QAAQ,SAAS,GAAG;AAC3B,aAAQ,IACN,KAAK,OAAO,OAAO,WAAW,CAAC,GAAG,KAAK,QAAQ,OAAO,uDACvD;AACD,UAAK,MAAM,KAAK,KAAK,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEnE,QACE,OAAO,WAAW,cACjB,KAAK,QAAQ,SAAS,KAAK,KAAK,MAAM,SAAS,KAAK,KAAK,QAAQ,SAAS,IAC3E;AACA,aAAQ,KAAK;AACb,aAAQ,IAAI,OAAO,IAAI,oDAAoD,CAAC;AAC5E,aAAQ,KAAK;AACb,aAAQ,IAAI,OAAO,IAAI,8BAA8B,CAAC;AACtD,aAAQ,IACN,OAAO,IAAI,oEAAoE,CAChF;AACD,aAAQ,IAAI,OAAO,IAAI,gDAAgD,CAAC;AACxE,aAAQ,KAAK;AACb,aAAQ,IAAI,OAAO,IAAI,6CAA6C,CAAC;AACrE,aAAQ,IACN,OAAO,IACL,6EACD,CACF;AACD,aAAQ,IAAI,OAAO,IAAI,gDAAgD,CAAC;AACxE,aAAQ,IAAI,OAAO,IAAI,2CAA2C,CAAC;AACnE,aAAQ,KAAK;AACb,aAAQ,IAAI,OAAO,IAAI,kCAAkC,CAAC;AAC1D,aAAQ,IAAI,OAAO,IAAI,wDAAwD,CAAC;AAChF,aAAQ,KAAK;AACb,aAAQ,IAAI,OAAO,IAAI,6BAA6B,CAAC;AACrD,aAAQ,IAAI,OAAO,IAAI,uDAAuD,CAAC;;;AAGnF,OAAI,OAAO,YAAY,OAAO,SAAS,SAAS,GAAG;AACjD,YAAQ,IAAI,KAAK,OAAO,OAAO,WAAW,CAAC,GAAG,OAAO,SAAS,OAAO,mBAAmB;AACxF,SAAK,MAAM,KAAK,OAAO,SAAU,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEtE,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,UAAU;AAC/B,WAAQ,KAAK;AACb,OAAI,OAAO,WAAW,SAAS;AAC7B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAEjB,WAAQ,IAAI,OAAO,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC;AACxC,WAAQ,IAAI,KAAK,MAAM,IAAI,GAAG,UAAU,MAAM,SAAS,GAAG;AAC1D,WAAQ,IAAI,OAAO,KAAK,OAAO,OAAO,GAAG,CAAC,CAAC;AAC3C,WAAQ,KAAK;AACb,OAAI,OAAO,QAAS,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,OAAO,OAAO,UAAU;AACpF,OAAI,OAAO,QAAS,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,OAAO,OAAO,UAAU;AACpF,OAAI,OAAO,OAAQ,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,QAAQ,OAAO,SAAS;AAClF,WAAQ,KAAK;AACb,WAAQ,IAAI,KAAK,OAAO,IAAI,YAAY,GAAG;AAC3C,QAAK,MAAM,OAAO,OAAO,UAAU;IACjC,MAAM,YACJ,IAAI,aACJ,IAAI,UACJ,iBAAiB,IAAI,UAAU,KAAK,iBAAiB,IAAI,OAAO;IAClE,MAAM,aAAa,YACf,GAAG,IAAI,UAAU,OAAO,IAAI,WAC5B,IAAI,aAAa;IACrB,MAAM,QAAQ,YAAY,OAAO,OAAO,WAAW,GAAG,OAAO,IAAI,WAAW;AAC5E,YAAQ,IAAI,OAAO,OAAO,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,QAAQ;;AAE3D,WAAQ,KAAK;AACb,OAAI,OAAO,UAAU;IACnB,MAAM,MAAM,cAAc,OAAO,SAAS;AAC1C,YAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,KAAK,MAAM;SAErD,SAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,UAAU;GAEtD,MAAM,WACJ,OAAO,YAAY,UACf,OAAO,MAAM,QAAQ,GACrB,OAAO,YAAY,iBACjB,OAAO,OAAO,oCAAoC,GAClD,OAAO,MAAM,UAAU;AAC/B,WAAQ,IAAI,KAAK,OAAO,IAAI,QAAQ,CAAC,WAAW,WAAW;AAC3D,OAAI,OAAO,oBAAoB,QAAW;IACxC,MAAM,cAAc,OAAO,kBACvB,OAAO,MAAM,YAAY,GACzB,OAAO,MAAM,cAAc;AAC/B,YAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,QAAQ,cAAc;;AAM/D,OAJmB,OAAO,SAAS,MAChC,MACC,EAAE,aAAa,EAAE,UAAU,iBAAiB,EAAE,UAAU,KAAK,iBAAiB,EAAE,OAAO,CAE7E,EAAE;AACd,YAAQ,KAAK;AACb,YAAQ,IACN,OAAO,IACL,SAAS,OAAO,KAAK,cAAc,CAAC,8CACrC,CACF;;AAEH,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,YAAY;AACjC,WAAQ,KAAK;AACb,OAAI,OAAO,WAAW,SAAS;AAC7B,YAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,YAAQ,KAAK,EAAE;;AAEjB,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,kBAAkB,CAAC;AACxD,OAAI,OAAO,OACT,SAAQ,IACN,KAAK,OAAO,IAAI,QAAQ,CAAC,GAAG,OAAO,WAAW,WAAW,OAAO,KAAK,SAAS,GAAG,OAAO,IAAI,QAAQ,GACrG;AAEH,OAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,YAAQ,IAAI,KAAK,OAAO,IAAI,aAAa,GAAG;AAC5C,SAAK,MAAM,KAAK,OAAO,UAAW,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAEvE,OAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,IAAI,KAAK,OAAO,IAAI,uBAAuB,GAAG;AACtD,SAAK,MAAM,OAAO,OAAO,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,IAAI,GAAG;;AAEzE,OAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,IAAI,KAAK,OAAO,IAAI,mBAAmB,GAAG;AAClD,SAAK,MAAM,KAAK,OAAO,QAAS,SAAQ,IAAI,OAAO,OAAO,IAAI,EAAE,GAAG;;AAErE,OAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,YAAQ,IAAI,KAAK,OAAO,OAAO,UAAU,GAAG;AAC5C,SAAK,MAAM,KAAK,OAAO,OAAQ,SAAQ,IAAI,OAAO,OAAO,MAAM,EAAE,GAAG;;AAEtE,WAAQ,KAAK;AACb;;AAGF,MAAI,QAAQ,WAAW,SAAS;AAC9B,WAAQ,MAAM,SAAS,OAAO,SAAS,kBAAkB;AACzD,WAAQ,KAAK,EAAE;;AAGjB,MAAI,WAAW,QAAQ,cAAc;AACnC,WAAQ,OAAO,MAAM,6BAA6B,OAAO,QAAQ,IAAI;AACrE,WAAQ,OAAO,MAAM,cAAc,OAAO,QAAQ,IAAI;AACtD,WAAQ,OAAO,MAAM,eAAe,OAAO,SAAS,IAAI;AACxD,WAAQ,OAAO,MAAM,gBAAgB,OAAO,UAAU,IAAI;AAC1D,WAAQ,OAAO,MAAM,gBAAgB,OAAO,cAAc,KAAK,KAAK,CAAC,IAAI;AACzE,WAAQ,OAAO,MAAM,iBAAiB,OAAO,UAAU,IAAI;AAC3D,WAAQ,OAAO,MAAM,kBAAkB,OAAO,WAAW,IAAI;AAC7D,WAAQ,OAAO,MAAM,4BAA4B,OAAO,WAAW,IAAI;;AAGzE,MAAI,WAAW,QAAQ,aAAa;AAClC,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,gBAAgB,OAAO,MAAM,CAAC;AACnE,OAAI,OAAO,YAAa,SAAQ,IAAI,KAAK,OAAO,IAAI,eAAe,CAAC,GAAG,OAAO,cAAc;AAC5F,OAAI,OAAO,WAAY,SAAQ,IAAI,KAAK,OAAO,IAAI,cAAc,CAAC,GAAG,OAAO,aAAa;AACzF,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,gBAAgB;AACrC,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,kBAAkB,OAAO,MAAM,CAAC;AACrE,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,cAAc;AACnC,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC;AACxC,WAAQ,IAAI,KAAK,MAAM,OAAO,GAAG,UAAU,MAAM,UAAU,GAAG;AAC9D,WAAQ,IAAI,OAAO,KAAK,OAAO,OAAO,GAAG,CAAC,CAAC;AAC3C,WAAQ,KAAK;AACb,OAAI,OAAO,QAAQ,WAAW,EAC5B,SAAQ,IAAI,OAAO,IAAI,0BAA0B,CAAC;OAElD,MAAK,MAAM,cAAc,OAAO,SAAS;AACvC,YAAQ,IAAI,KAAK,OAAO,KAAK,WAAW,IAAI,GAAG;AAC/C,QAAI,WAAW,YACb,SAAQ,IAAI,OAAO,OAAO,IAAI,eAAe,CAAC,GAAG,WAAW,cAAc;AAC5E,QAAI,WAAW,WACb,SAAQ,IAAI,OAAO,OAAO,IAAI,cAAc,CAAC,GAAG,WAAW,aAAa;;AAG9E,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,iBAAiB;AACtC,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,oBAAoB,OAAO,MAAM,CAAC;AACvE,OAAI,OAAO,KAAM,SAAQ,IAAI,KAAK,OAAO,IAAI,QAAQ,CAAC,GAAG,OAAO,OAAO;AACvE,OAAI,OAAO,OAAQ,SAAQ,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,WAAW,OAAO,SAAS;AACrF,OAAI,OAAO,WAAY,SAAQ,IAAI,KAAK,OAAO,IAAI,cAAc,CAAC,GAAG,OAAO,aAAa;AACzF,WAAQ,KAAK;AACb;;AAGF,MAAI,WAAW,QAAQ,WAAW;AAChC,OAAI,OAAO,WAAW,WAAW;AAC/B,YAAQ,KAAK;AACb,YAAQ,IAAI,OAAO,KAAK,GAAG,MAAM,GAAG,mBAAmB,CAAC;AACxD,YAAQ,IAAI,KAAK,OAAO,IAAI,gBAAgB,CAAC,GAAG,OAAO,cAAc;AACrE,YAAQ,KAAK;AACb;;AAGF,OAAI,OAAO,WAAW,aAAa;AACjC,YAAQ,KAAK;AACb,YAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,yBAAyB,CAAC;AAC/D,YAAQ,IAAI,KAAK,OAAO,IAAI,gBAAgB,CAAC,GAAG,OAAO,cAAc;AACrE,QAAI,OAAO,OACT,SAAQ,IAAI,KAAK,OAAO,IAAI,eAAe,CAAC,GAAG,OAAO,SAAS;AAEjE,QAAI,OAAO,SAAS,OAAO,MAAM,SAAS,EACxC,SAAQ,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,GAAG,OAAO,MAAM,KAAK,KAAK,GAAG;AAErE,QAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,EAC5C,SAAQ,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,OAAO,QAAQ,KAAK,KAAK,GAAG;AAEzE,YAAQ,KAAK;AACb;;;UAGG,OAAO;AACd,UAAQ,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAAG;AAChF,UAAQ,KAAK,EAAE;;;AAInB,MAAM,CAAC,OAAO,UAAU;AACtB,SAAQ,MAAM,sBAAsB,MAAM;AAC1C,SAAQ,KAAK,EAAE;EACf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-view.cjs","names":["Text","icons","Box","linkify","frames","gradients","colors","divider"],"sources":["../../src/components/dev-view.tsx"],"sourcesContent":["import { Box, render, Text, useApp, useInput } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { SourceMode } from \"../types\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, divider, frames, gradients, icons } from \"../utils/theme\";\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: SourceMode;\n}\n\nexport interface LogEntry {\n id: string;\n source: string;\n line: string;\n timestamp: number;\n isError?: boolean;\n}\n\ninterface DevViewProps {\n processes: ProcessState[];\n logs: LogEntry[];\n description: string;\n proxyTarget?: string;\n onExit?: () => Promise<void> | void;\n onExportLogs?: () => Promise<void> | void;\n}\n\nfunction StatusIcon({ status }: { status: ProcessStatus }) {\n switch (status) {\n case \"pending\":\n return <Text color=\"gray\">{icons.pending}</Text>;\n case \"starting\":\n return <Text color=\"#00ffff\">{icons.scan}</Text>;\n case \"ready\":\n return <Text color=\"#00ff41\">{icons.ok}</Text>;\n case \"error\":\n return <Text color=\"#ff3366\">{icons.err}</Text>;\n }\n}\n\nfunction getServiceColor(name: string): string {\n if (name.startsWith(PLUGIN_PREFIX)) return \"#ffaa00\";\n return name === \"host\" ? \"#00ffff\" : name === \"ui\" ? \"#ff00ff\" : \"#0080ff\";\n}\n\nfunction getDisplayName(name: string): string {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n}\n\nfunction isPlugin(name: string): boolean {\n return name.startsWith(PLUGIN_PREFIX);\n}\n\nfunction getSectionedProcesses(processes: ProcessState[]): Array<{\n key: string;\n title: string;\n processes: ProcessState[];\n}> {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n}\n\nfunction getColumnWidths(processes: ProcessState[]): { name: number; source: number } {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? `(${p.source})`.length : 0)));\n return { name, source };\n}\n\nfunction ProcessRow({\n proc,\n nameWidth,\n sourceWidth,\n}: {\n proc: ProcessState;\n nameWidth: number;\n sourceWidth: number;\n}) {\n const color = getServiceColor(proc.name);\n const isRemote = proc.source === \"remote\";\n const isHost = proc.name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote);\n const portStr = showPort ? `:${proc.port}` : \"\";\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n\n const statusText =\n proc.status === \"pending\"\n ? \"waiting\"\n : proc.status === \"starting\"\n ? \"starting\"\n : proc.status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : \"failed\";\n\n return (\n <Box>\n <Text>{\" \"}</Text>\n <StatusIcon status={proc.status} />\n <Text> </Text>\n <Text color={color} bold>\n {getDisplayName(proc.name).padEnd(nameWidth)}\n </Text>\n <Text color=\"gray\">{sourceLabel.padEnd(sourceWidth)}</Text>\n <Text color={proc.status === \"ready\" ? \"#00ff41\" : \"gray\"}>{statusText}</Text>\n {showPort && <Text color=\"#00ffff\"> {portStr}</Text>}\n </Box>\n );\n}\n\nfunction SectionHeader({ title }: { title: string }) {\n return (\n <Box marginBottom={0} marginTop={1}>\n <Text color=\"#00ffff\" bold>\n {title}\n </Text>\n </Box>\n );\n}\n\nfunction LogLine({ entry }: { entry: LogEntry }) {\n const color = getServiceColor(entry.source);\n\n return (\n <Box>\n <Text color={color}>[{entry.source}]</Text>\n <Text color={entry.isError ? \"#ff3366\" : undefined}> {linkify(entry.line)}</Text>\n </Box>\n );\n}\n\nfunction truncateUrl(url: string, maxLen: number): string {\n if (url.length <= maxLen) return url;\n try {\n const parsed = new URL(url);\n const host = parsed.host;\n if (host.length > maxLen - 10) {\n return `${host.slice(0, maxLen - 13)}...`;\n }\n return host;\n } catch {\n return `${url.slice(0, maxLen - 3)}...`;\n }\n}\n\nfunction DevView({\n processes,\n logs,\n description,\n proxyTarget,\n onExit,\n onExportLogs,\n}: DevViewProps) {\n const { exit } = useApp();\n const [isShuttingDown, setIsShuttingDown] = useState(false);\n\n useInput((input, key) => {\n if (isShuttingDown) return;\n\n if (input === \"q\" || (key.ctrl && input === \"c\")) {\n setIsShuttingDown(true);\n Promise.resolve(onExit?.()).then(() => {\n exit();\n });\n }\n if (input === \"l\") {\n setIsShuttingDown(true);\n Promise.resolve(onExportLogs?.()).then(() => {\n exit();\n });\n }\n });\n\n const readyCount = processes.filter((p) => p.status === \"ready\").length;\n const total = processes.length;\n const allReady = readyCount === total;\n const hostProcess = processes.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const recentLogs = logs.slice(-12);\n const sectionedProcesses = getSectionedProcesses(processes);\n const columnWidths = getColumnWidths(processes);\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={0}>\n <Text color=\"#00ffff\">{frames.top(52)}</Text>\n </Box>\n <Box>\n <Text>\n {\" \"}\n {icons.run} {gradients.cyber(description.toUpperCase())}\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"#00ffff\">{frames.bottom(52)}</Text>\n </Box>\n\n {allReady && (\n <Box marginBottom={1} flexDirection=\"column\">\n <Box>\n <Text color=\"#00ff41\">\n {\" \"}\n {icons.app} APP READY\n </Text>\n </Box>\n <Box>\n <Text color=\"#00ff41\" bold>\n {\" \"}\n {icons.arrow} http://localhost:{hostPort}\n </Text>\n </Box>\n </Box>\n )}\n\n {proxyTarget && (\n <Box marginBottom={1}>\n <Text color=\"#ffaa00\">\n {\" \"}\n {icons.arrow} API PROXY → {truncateUrl(proxyTarget, 38)}\n </Text>\n </Box>\n )}\n\n <Box marginTop={0} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n {sectionedProcesses.map((section) => (\n <Box key={section.key} flexDirection=\"column\">\n <SectionHeader title={section.title} />\n {section.processes.map((proc) => (\n <ProcessRow\n key={proc.name}\n proc={proc}\n nameWidth={columnWidths.name}\n sourceWidth={columnWidths.source}\n />\n ))}\n </Box>\n ))}\n\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n <Box marginTop={0}>\n <Text color={allReady ? \"#00ff41\" : \"#00ffff\"}>\n {\" \"}\n {allReady\n ? `${icons.ok} All ${total} services running`\n : `${icons.scan} ${readyCount}/${total} ready`}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n {icons.dot} q quit {icons.dot} l logs\n </Text>\n </Box>\n\n {recentLogs.length > 0 && (\n <>\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={0}>\n {recentLogs.map((entry) => (\n <LogLine key={entry.id} entry={entry} />\n ))}\n </Box>\n </>\n )}\n </Box>\n );\n}\n\nexport interface DevViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => void;\n}\n\nexport function renderDevView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n onExportLogs?: () => Promise<void> | void,\n): DevViewHandle {\n let processes = [...initialProcesses];\n let logs: LogEntry[] = [];\n let rerender: (() => void) | null = null;\n const proxyTarget = env.API_PROXY;\n let logSeq = 0;\n let lastLogKey: string | null = null;\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n processes = processes.map((p) => (p.name === name ? { ...p, status, message } : p));\n rerender?.();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const nextKey = `${source}:${isError ? \"1\" : \"0\"}:${line}`;\n if (nextKey === lastLogKey) return;\n lastLogKey = nextKey;\n\n logs = [\n ...logs,\n { id: `${Date.now()}-${++logSeq}`, source, line, timestamp: Date.now(), isError },\n ];\n if (logs.length > 100) logs = logs.slice(-100);\n rerender?.();\n };\n\n function DevViewWrapper() {\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n rerender = () => forceUpdate((n: number) => n + 1);\n return () => {\n rerender = null;\n };\n }, []);\n\n return (\n <DevView\n processes={processes}\n logs={logs}\n description={description}\n proxyTarget={proxyTarget}\n onExit={onExit}\n onExportLogs={onExportLogs}\n />\n );\n }\n\n const { unmount } = render(<DevViewWrapper />);\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev-view.cjs","names":["Text","icons","Box","linkify","frames","gradients","colors","divider"],"sources":["../../src/components/dev-view.tsx"],"sourcesContent":["import { Box, render, Text, useApp, useInput } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { SourceMode } from \"../types\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, divider, frames, gradients, icons } from \"../utils/theme\";\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: SourceMode;\n}\n\nexport interface LogEntry {\n id: string;\n source: string;\n line: string;\n timestamp: number;\n isError?: boolean;\n}\n\ninterface DevViewProps {\n processes: ProcessState[];\n logs: LogEntry[];\n description: string;\n proxyTarget?: string;\n onExit?: () => Promise<void> | void;\n onExportLogs?: () => Promise<void> | void;\n}\n\nfunction StatusIcon({ status }: { status: ProcessStatus }) {\n switch (status) {\n case \"pending\":\n return <Text color=\"gray\">{icons.pending}</Text>;\n case \"starting\":\n return <Text color=\"#00ffff\">{icons.scan}</Text>;\n case \"ready\":\n return <Text color=\"#00ff41\">{icons.ok}</Text>;\n case \"error\":\n return <Text color=\"#ff3366\">{icons.err}</Text>;\n }\n}\n\nfunction getServiceColor(name: string): string {\n if (name.startsWith(PLUGIN_PREFIX)) return \"#ffaa00\";\n return name === \"host\" ? \"#00ffff\" : name === \"ui\" ? \"#ff00ff\" : \"#0080ff\";\n}\n\nfunction getDisplayName(name: string): string {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n}\n\nfunction isPlugin(name: string): boolean {\n return name.startsWith(PLUGIN_PREFIX);\n}\n\nfunction getSectionedProcesses(processes: ProcessState[]): Array<{\n key: string;\n title: string;\n processes: ProcessState[];\n}> {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n}\n\nfunction getColumnWidths(processes: ProcessState[]): { name: number; source: number } {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? `(${p.source})`.length : 0)));\n return { name, source };\n}\n\nfunction ProcessRow({\n proc,\n nameWidth,\n sourceWidth,\n}: {\n proc: ProcessState;\n nameWidth: number;\n sourceWidth: number;\n}) {\n const color = getServiceColor(proc.name);\n const isRemote = proc.source === \"remote\";\n const isHost = proc.name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote);\n const portStr = showPort ? `:${proc.port}` : \"\";\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n\n const statusText =\n proc.status === \"pending\"\n ? \"waiting\"\n : proc.status === \"starting\"\n ? \"starting\"\n : proc.status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : \"failed\";\n\n return (\n <Box>\n <Text>{\" \"}</Text>\n <StatusIcon status={proc.status} />\n <Text> </Text>\n <Text color={color} bold>\n {getDisplayName(proc.name).padEnd(nameWidth)}\n </Text>\n <Text color=\"gray\">{sourceLabel.padEnd(sourceWidth)}</Text>\n <Text color={proc.status === \"ready\" ? \"#00ff41\" : \"gray\"}>{statusText}</Text>\n {showPort && <Text color=\"#00ffff\"> {portStr}</Text>}\n </Box>\n );\n}\n\nfunction SectionHeader({ title }: { title: string }) {\n return (\n <Box marginBottom={0} marginTop={1}>\n <Text color=\"#00ffff\" bold>\n {title}\n </Text>\n </Box>\n );\n}\n\nfunction LogLine({ entry }: { entry: LogEntry }) {\n const color = getServiceColor(entry.source);\n\n return (\n <Box>\n <Text color={color}>[{entry.source}]</Text>\n <Text color={entry.isError ? \"#ff3366\" : undefined}> {linkify(entry.line)}</Text>\n </Box>\n );\n}\n\nfunction truncateUrl(url: string, maxLen: number): string {\n if (url.length <= maxLen) return url;\n try {\n const parsed = new URL(url);\n const host = parsed.host;\n if (host.length > maxLen - 10) {\n return `${host.slice(0, maxLen - 13)}...`;\n }\n return host;\n } catch {\n return `${url.slice(0, maxLen - 3)}...`;\n }\n}\n\nfunction DevView({\n processes,\n logs,\n description,\n proxyTarget,\n onExit,\n onExportLogs,\n}: DevViewProps) {\n const { exit } = useApp();\n const [isShuttingDown, setIsShuttingDown] = useState(false);\n\n useInput((input, key) => {\n if (isShuttingDown) return;\n\n if (input === \"q\" || (key.ctrl && input === \"c\")) {\n setIsShuttingDown(true);\n Promise.resolve(onExit?.()).then(() => {\n exit();\n });\n }\n if (input === \"l\") {\n setIsShuttingDown(true);\n Promise.resolve(onExportLogs?.()).then(() => {\n exit();\n });\n }\n });\n\n const readyCount = processes.filter((p) => p.status === \"ready\").length;\n const total = processes.length;\n const allReady = readyCount === total;\n const hostProcess = processes.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const recentLogs = logs.slice(-12);\n const sectionedProcesses = getSectionedProcesses(processes);\n const columnWidths = getColumnWidths(processes);\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={0}>\n <Text color=\"#00ffff\">{frames.top(52)}</Text>\n </Box>\n <Box>\n <Text>\n {\" \"}\n {icons.run} {gradients.cyber(description.toUpperCase())}\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"#00ffff\">{frames.bottom(52)}</Text>\n </Box>\n\n {allReady && (\n <Box marginBottom={1} flexDirection=\"column\">\n <Box>\n <Text color=\"#00ff41\">\n {\" \"}\n {icons.app} APP READY\n </Text>\n </Box>\n <Box>\n <Text color=\"#00ff41\" bold>\n {\" \"}\n {icons.arrow} http://localhost:{hostPort}\n </Text>\n </Box>\n </Box>\n )}\n\n {proxyTarget && (\n <Box marginBottom={1}>\n <Text color=\"#ffaa00\">\n {\" \"}\n {icons.arrow} API PROXY → {truncateUrl(proxyTarget, 38)}\n </Text>\n </Box>\n )}\n\n <Box marginTop={0} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n {sectionedProcesses.map((section) => (\n <Box key={section.key} flexDirection=\"column\">\n <SectionHeader title={section.title} />\n {section.processes.map((proc) => (\n <ProcessRow\n key={proc.name}\n proc={proc}\n nameWidth={columnWidths.name}\n sourceWidth={columnWidths.source}\n />\n ))}\n </Box>\n ))}\n\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n <Box marginTop={0}>\n <Text color={allReady ? \"#00ff41\" : \"#00ffff\"}>\n {\" \"}\n {allReady\n ? `${icons.ok} All ${total} services running`\n : `${icons.scan} ${readyCount}/${total} ready`}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n {icons.dot} q quit {icons.dot} l logs\n </Text>\n </Box>\n\n {recentLogs.length > 0 && (\n <>\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={0}>\n {recentLogs.map((entry) => (\n <LogLine key={entry.id} entry={entry} />\n ))}\n </Box>\n </>\n )}\n </Box>\n );\n}\n\nexport interface DevViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => void;\n}\n\nexport function renderDevView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n onExportLogs?: () => Promise<void> | void,\n): DevViewHandle {\n let processes = [...initialProcesses];\n let logs: LogEntry[] = [];\n let rerender: (() => void) | null = null;\n const proxyTarget = env.API_PROXY;\n let logSeq = 0;\n let lastLogKey: string | null = null;\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n processes = processes.map((p) => (p.name === name ? { ...p, status, message } : p));\n rerender?.();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const nextKey = `${source}:${isError ? \"1\" : \"0\"}:${line}`;\n if (nextKey === lastLogKey) return;\n lastLogKey = nextKey;\n\n logs = [\n ...logs,\n { id: `${Date.now()}-${++logSeq}`, source, line, timestamp: Date.now(), isError },\n ];\n if (logs.length > 100) logs = logs.slice(-100);\n rerender?.();\n };\n\n function DevViewWrapper() {\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n rerender = () => forceUpdate((n: number) => n + 1);\n return () => {\n rerender = null;\n };\n }, []);\n\n return (\n <DevView\n processes={processes}\n logs={logs}\n description={description}\n proxyTarget={proxyTarget}\n onExit={onExit}\n onExportLogs={onExportLogs}\n />\n );\n }\n\n const { unmount } = render(<DevViewWrapper />);\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-view.mjs","names":[],"sources":["../../src/components/dev-view.tsx"],"sourcesContent":["import { Box, render, Text, useApp, useInput } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { SourceMode } from \"../types\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, divider, frames, gradients, icons } from \"../utils/theme\";\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: SourceMode;\n}\n\nexport interface LogEntry {\n id: string;\n source: string;\n line: string;\n timestamp: number;\n isError?: boolean;\n}\n\ninterface DevViewProps {\n processes: ProcessState[];\n logs: LogEntry[];\n description: string;\n proxyTarget?: string;\n onExit?: () => Promise<void> | void;\n onExportLogs?: () => Promise<void> | void;\n}\n\nfunction StatusIcon({ status }: { status: ProcessStatus }) {\n switch (status) {\n case \"pending\":\n return <Text color=\"gray\">{icons.pending}</Text>;\n case \"starting\":\n return <Text color=\"#00ffff\">{icons.scan}</Text>;\n case \"ready\":\n return <Text color=\"#00ff41\">{icons.ok}</Text>;\n case \"error\":\n return <Text color=\"#ff3366\">{icons.err}</Text>;\n }\n}\n\nfunction getServiceColor(name: string): string {\n if (name.startsWith(PLUGIN_PREFIX)) return \"#ffaa00\";\n return name === \"host\" ? \"#00ffff\" : name === \"ui\" ? \"#ff00ff\" : \"#0080ff\";\n}\n\nfunction getDisplayName(name: string): string {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n}\n\nfunction isPlugin(name: string): boolean {\n return name.startsWith(PLUGIN_PREFIX);\n}\n\nfunction getSectionedProcesses(processes: ProcessState[]): Array<{\n key: string;\n title: string;\n processes: ProcessState[];\n}> {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n}\n\nfunction getColumnWidths(processes: ProcessState[]): { name: number; source: number } {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? `(${p.source})`.length : 0)));\n return { name, source };\n}\n\nfunction ProcessRow({\n proc,\n nameWidth,\n sourceWidth,\n}: {\n proc: ProcessState;\n nameWidth: number;\n sourceWidth: number;\n}) {\n const color = getServiceColor(proc.name);\n const isRemote = proc.source === \"remote\";\n const isHost = proc.name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote);\n const portStr = showPort ? `:${proc.port}` : \"\";\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n\n const statusText =\n proc.status === \"pending\"\n ? \"waiting\"\n : proc.status === \"starting\"\n ? \"starting\"\n : proc.status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : \"failed\";\n\n return (\n <Box>\n <Text>{\" \"}</Text>\n <StatusIcon status={proc.status} />\n <Text> </Text>\n <Text color={color} bold>\n {getDisplayName(proc.name).padEnd(nameWidth)}\n </Text>\n <Text color=\"gray\">{sourceLabel.padEnd(sourceWidth)}</Text>\n <Text color={proc.status === \"ready\" ? \"#00ff41\" : \"gray\"}>{statusText}</Text>\n {showPort && <Text color=\"#00ffff\"> {portStr}</Text>}\n </Box>\n );\n}\n\nfunction SectionHeader({ title }: { title: string }) {\n return (\n <Box marginBottom={0} marginTop={1}>\n <Text color=\"#00ffff\" bold>\n {title}\n </Text>\n </Box>\n );\n}\n\nfunction LogLine({ entry }: { entry: LogEntry }) {\n const color = getServiceColor(entry.source);\n\n return (\n <Box>\n <Text color={color}>[{entry.source}]</Text>\n <Text color={entry.isError ? \"#ff3366\" : undefined}> {linkify(entry.line)}</Text>\n </Box>\n );\n}\n\nfunction truncateUrl(url: string, maxLen: number): string {\n if (url.length <= maxLen) return url;\n try {\n const parsed = new URL(url);\n const host = parsed.host;\n if (host.length > maxLen - 10) {\n return `${host.slice(0, maxLen - 13)}...`;\n }\n return host;\n } catch {\n return `${url.slice(0, maxLen - 3)}...`;\n }\n}\n\nfunction DevView({\n processes,\n logs,\n description,\n proxyTarget,\n onExit,\n onExportLogs,\n}: DevViewProps) {\n const { exit } = useApp();\n const [isShuttingDown, setIsShuttingDown] = useState(false);\n\n useInput((input, key) => {\n if (isShuttingDown) return;\n\n if (input === \"q\" || (key.ctrl && input === \"c\")) {\n setIsShuttingDown(true);\n Promise.resolve(onExit?.()).then(() => {\n exit();\n });\n }\n if (input === \"l\") {\n setIsShuttingDown(true);\n Promise.resolve(onExportLogs?.()).then(() => {\n exit();\n });\n }\n });\n\n const readyCount = processes.filter((p) => p.status === \"ready\").length;\n const total = processes.length;\n const allReady = readyCount === total;\n const hostProcess = processes.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const recentLogs = logs.slice(-12);\n const sectionedProcesses = getSectionedProcesses(processes);\n const columnWidths = getColumnWidths(processes);\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={0}>\n <Text color=\"#00ffff\">{frames.top(52)}</Text>\n </Box>\n <Box>\n <Text>\n {\" \"}\n {icons.run} {gradients.cyber(description.toUpperCase())}\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"#00ffff\">{frames.bottom(52)}</Text>\n </Box>\n\n {allReady && (\n <Box marginBottom={1} flexDirection=\"column\">\n <Box>\n <Text color=\"#00ff41\">\n {\" \"}\n {icons.app} APP READY\n </Text>\n </Box>\n <Box>\n <Text color=\"#00ff41\" bold>\n {\" \"}\n {icons.arrow} http://localhost:{hostPort}\n </Text>\n </Box>\n </Box>\n )}\n\n {proxyTarget && (\n <Box marginBottom={1}>\n <Text color=\"#ffaa00\">\n {\" \"}\n {icons.arrow} API PROXY → {truncateUrl(proxyTarget, 38)}\n </Text>\n </Box>\n )}\n\n <Box marginTop={0} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n {sectionedProcesses.map((section) => (\n <Box key={section.key} flexDirection=\"column\">\n <SectionHeader title={section.title} />\n {section.processes.map((proc) => (\n <ProcessRow\n key={proc.name}\n proc={proc}\n nameWidth={columnWidths.name}\n sourceWidth={columnWidths.source}\n />\n ))}\n </Box>\n ))}\n\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n <Box marginTop={0}>\n <Text color={allReady ? \"#00ff41\" : \"#00ffff\"}>\n {\" \"}\n {allReady\n ? `${icons.ok} All ${total} services running`\n : `${icons.scan} ${readyCount}/${total} ready`}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n {icons.dot} q quit {icons.dot} l logs\n </Text>\n </Box>\n\n {recentLogs.length > 0 && (\n <>\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={0}>\n {recentLogs.map((entry) => (\n <LogLine key={entry.id} entry={entry} />\n ))}\n </Box>\n </>\n )}\n </Box>\n );\n}\n\nexport interface DevViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => void;\n}\n\nexport function renderDevView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n onExportLogs?: () => Promise<void> | void,\n): DevViewHandle {\n let processes = [...initialProcesses];\n let logs: LogEntry[] = [];\n let rerender: (() => void) | null = null;\n const proxyTarget = env.API_PROXY;\n let logSeq = 0;\n let lastLogKey: string | null = null;\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n processes = processes.map((p) => (p.name === name ? { ...p, status, message } : p));\n rerender?.();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const nextKey = `${source}:${isError ? \"1\" : \"0\"}:${line}`;\n if (nextKey === lastLogKey) return;\n lastLogKey = nextKey;\n\n logs = [\n ...logs,\n { id: `${Date.now()}-${++logSeq}`, source, line, timestamp: Date.now(), isError },\n ];\n if (logs.length > 100) logs = logs.slice(-100);\n rerender?.();\n };\n\n function DevViewWrapper() {\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n rerender = () => forceUpdate((n: number) => n + 1);\n return () => {\n rerender = null;\n };\n }, []);\n\n return (\n <DevView\n processes={processes}\n logs={logs}\n description={description}\n proxyTarget={proxyTarget}\n onExit={onExit}\n onExportLogs={onExportLogs}\n />\n );\n }\n\n const { unmount } = render(<DevViewWrapper />);\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev-view.mjs","names":[],"sources":["../../src/components/dev-view.tsx"],"sourcesContent":["import { Box, render, Text, useApp, useInput } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { SourceMode } from \"../types\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, divider, frames, gradients, icons } from \"../utils/theme\";\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport type ProcessStatus = \"pending\" | \"starting\" | \"ready\" | \"error\";\n\nexport interface ProcessState {\n name: string;\n status: ProcessStatus;\n port: number;\n message?: string;\n source?: SourceMode;\n}\n\nexport interface LogEntry {\n id: string;\n source: string;\n line: string;\n timestamp: number;\n isError?: boolean;\n}\n\ninterface DevViewProps {\n processes: ProcessState[];\n logs: LogEntry[];\n description: string;\n proxyTarget?: string;\n onExit?: () => Promise<void> | void;\n onExportLogs?: () => Promise<void> | void;\n}\n\nfunction StatusIcon({ status }: { status: ProcessStatus }) {\n switch (status) {\n case \"pending\":\n return <Text color=\"gray\">{icons.pending}</Text>;\n case \"starting\":\n return <Text color=\"#00ffff\">{icons.scan}</Text>;\n case \"ready\":\n return <Text color=\"#00ff41\">{icons.ok}</Text>;\n case \"error\":\n return <Text color=\"#ff3366\">{icons.err}</Text>;\n }\n}\n\nfunction getServiceColor(name: string): string {\n if (name.startsWith(PLUGIN_PREFIX)) return \"#ffaa00\";\n return name === \"host\" ? \"#00ffff\" : name === \"ui\" ? \"#ff00ff\" : \"#0080ff\";\n}\n\nfunction getDisplayName(name: string): string {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n}\n\nfunction isPlugin(name: string): boolean {\n return name.startsWith(PLUGIN_PREFIX);\n}\n\nfunction getSectionedProcesses(processes: ProcessState[]): Array<{\n key: string;\n title: string;\n processes: ProcessState[];\n}> {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n}\n\nfunction getColumnWidths(processes: ProcessState[]): { name: number; source: number } {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? `(${p.source})`.length : 0)));\n return { name, source };\n}\n\nfunction ProcessRow({\n proc,\n nameWidth,\n sourceWidth,\n}: {\n proc: ProcessState;\n nameWidth: number;\n sourceWidth: number;\n}) {\n const color = getServiceColor(proc.name);\n const isRemote = proc.source === \"remote\";\n const isHost = proc.name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote);\n const portStr = showPort ? `:${proc.port}` : \"\";\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n\n const statusText =\n proc.status === \"pending\"\n ? \"waiting\"\n : proc.status === \"starting\"\n ? \"starting\"\n : proc.status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : \"failed\";\n\n return (\n <Box>\n <Text>{\" \"}</Text>\n <StatusIcon status={proc.status} />\n <Text> </Text>\n <Text color={color} bold>\n {getDisplayName(proc.name).padEnd(nameWidth)}\n </Text>\n <Text color=\"gray\">{sourceLabel.padEnd(sourceWidth)}</Text>\n <Text color={proc.status === \"ready\" ? \"#00ff41\" : \"gray\"}>{statusText}</Text>\n {showPort && <Text color=\"#00ffff\"> {portStr}</Text>}\n </Box>\n );\n}\n\nfunction SectionHeader({ title }: { title: string }) {\n return (\n <Box marginBottom={0} marginTop={1}>\n <Text color=\"#00ffff\" bold>\n {title}\n </Text>\n </Box>\n );\n}\n\nfunction LogLine({ entry }: { entry: LogEntry }) {\n const color = getServiceColor(entry.source);\n\n return (\n <Box>\n <Text color={color}>[{entry.source}]</Text>\n <Text color={entry.isError ? \"#ff3366\" : undefined}> {linkify(entry.line)}</Text>\n </Box>\n );\n}\n\nfunction truncateUrl(url: string, maxLen: number): string {\n if (url.length <= maxLen) return url;\n try {\n const parsed = new URL(url);\n const host = parsed.host;\n if (host.length > maxLen - 10) {\n return `${host.slice(0, maxLen - 13)}...`;\n }\n return host;\n } catch {\n return `${url.slice(0, maxLen - 3)}...`;\n }\n}\n\nfunction DevView({\n processes,\n logs,\n description,\n proxyTarget,\n onExit,\n onExportLogs,\n}: DevViewProps) {\n const { exit } = useApp();\n const [isShuttingDown, setIsShuttingDown] = useState(false);\n\n useInput((input, key) => {\n if (isShuttingDown) return;\n\n if (input === \"q\" || (key.ctrl && input === \"c\")) {\n setIsShuttingDown(true);\n Promise.resolve(onExit?.()).then(() => {\n exit();\n });\n }\n if (input === \"l\") {\n setIsShuttingDown(true);\n Promise.resolve(onExportLogs?.()).then(() => {\n exit();\n });\n }\n });\n\n const readyCount = processes.filter((p) => p.status === \"ready\").length;\n const total = processes.length;\n const allReady = readyCount === total;\n const hostProcess = processes.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const recentLogs = logs.slice(-12);\n const sectionedProcesses = getSectionedProcesses(processes);\n const columnWidths = getColumnWidths(processes);\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={0}>\n <Text color=\"#00ffff\">{frames.top(52)}</Text>\n </Box>\n <Box>\n <Text>\n {\" \"}\n {icons.run} {gradients.cyber(description.toUpperCase())}\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text color=\"#00ffff\">{frames.bottom(52)}</Text>\n </Box>\n\n {allReady && (\n <Box marginBottom={1} flexDirection=\"column\">\n <Box>\n <Text color=\"#00ff41\">\n {\" \"}\n {icons.app} APP READY\n </Text>\n </Box>\n <Box>\n <Text color=\"#00ff41\" bold>\n {\" \"}\n {icons.arrow} http://localhost:{hostPort}\n </Text>\n </Box>\n </Box>\n )}\n\n {proxyTarget && (\n <Box marginBottom={1}>\n <Text color=\"#ffaa00\">\n {\" \"}\n {icons.arrow} API PROXY → {truncateUrl(proxyTarget, 38)}\n </Text>\n </Box>\n )}\n\n <Box marginTop={0} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n {sectionedProcesses.map((section) => (\n <Box key={section.key} flexDirection=\"column\">\n <SectionHeader title={section.title} />\n {section.processes.map((proc) => (\n <ProcessRow\n key={proc.name}\n proc={proc}\n nameWidth={columnWidths.name}\n sourceWidth={columnWidths.source}\n />\n ))}\n </Box>\n ))}\n\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n\n <Box marginTop={0}>\n <Text color={allReady ? \"#00ff41\" : \"#00ffff\"}>\n {\" \"}\n {allReady\n ? `${icons.ok} All ${total} services running`\n : `${icons.scan} ${readyCount}/${total} ready`}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n {icons.dot} q quit {icons.dot} l logs\n </Text>\n </Box>\n\n {recentLogs.length > 0 && (\n <>\n <Box marginTop={1} marginBottom={0}>\n <Text>{colors.dim(divider(52))}</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={0}>\n {recentLogs.map((entry) => (\n <LogLine key={entry.id} entry={entry} />\n ))}\n </Box>\n </>\n )}\n </Box>\n );\n}\n\nexport interface DevViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => void;\n}\n\nexport function renderDevView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n onExportLogs?: () => Promise<void> | void,\n): DevViewHandle {\n let processes = [...initialProcesses];\n let logs: LogEntry[] = [];\n let rerender: (() => void) | null = null;\n const proxyTarget = env.API_PROXY;\n let logSeq = 0;\n let lastLogKey: string | null = null;\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n processes = processes.map((p) => (p.name === name ? { ...p, status, message } : p));\n rerender?.();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const nextKey = `${source}:${isError ? \"1\" : \"0\"}:${line}`;\n if (nextKey === lastLogKey) return;\n lastLogKey = nextKey;\n\n logs = [\n ...logs,\n { id: `${Date.now()}-${++logSeq}`, source, line, timestamp: Date.now(), isError },\n ];\n if (logs.length > 100) logs = logs.slice(-100);\n rerender?.();\n };\n\n function DevViewWrapper() {\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n rerender = () => forceUpdate((n: number) => n + 1);\n return () => {\n rerender = null;\n };\n }, []);\n\n return (\n <DevView\n processes={processes}\n logs={logs}\n description={description}\n proxyTarget={proxyTarget}\n onExit={onExit}\n onExportLogs={onExportLogs}\n />\n );\n }\n\n const { unmount } = render(<DevViewWrapper />);\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":";;;;;;;AAMA,MAAM,gBAAgB;AA6BtB,SAAS,WAAW,EAAE,UAAqC;AACzD,SAAQ,QAAR;EACE,KAAK,UACH,QAAO,oBAAC,MAAD;GAAM,OAAM;aAAQ,MAAM;GAAe;EAClD,KAAK,WACH,QAAO,oBAAC,MAAD;GAAM,OAAM;aAAW,MAAM;GAAY;EAClD,KAAK,QACH,QAAO,oBAAC,MAAD;GAAM,OAAM;aAAW,MAAM;GAAU;EAChD,KAAK,QACH,QAAO,oBAAC,MAAD;GAAM,OAAM;aAAW,MAAM;GAAW;;;AAIrD,SAAS,gBAAgB,MAAsB;AAC7C,KAAI,KAAK,WAAW,cAAc,CAAE,QAAO;AAC3C,QAAO,SAAS,SAAS,YAAY,SAAS,OAAO,YAAY;;AAGnE,SAAS,eAAe,MAAsB;AAC5C,QAAO,KAAK,WAAW,cAAc,GACjC,KAAK,MAAM,EAAqB,CAAC,aAAa,GAC9C,KAAK,aAAa;;AAGxB,SAAS,SAAS,MAAuB;AACvC,QAAO,KAAK,WAAW,cAAc;;AAGvC,SAAS,sBAAsB,WAI5B;CACD,MAAM,UAAU,UAAU,QAAQ,MAAM,SAAS,EAAE,KAAK,CAAC;CACzD,MAAM,WAAW,UAAU,QAAQ,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC;CAC3D,MAAM,WAA6E,EAAE;AACrF,KAAI,QAAQ,SAAS,EAAG,UAAS,KAAK;EAAE,KAAK;EAAW,OAAO;EAAW,WAAW;EAAS,CAAC;AAC/F,KAAI,SAAS,SAAS,EACpB,UAAS,KAAK;EAAE,KAAK;EAAY,OAAO;EAAY,WAAW;EAAU,CAAC;AAC5E,QAAO;;AAGT,SAAS,gBAAgB,WAA6D;AAGpF,QAAO;EAAE,MAFI,KAAK,IAAI,GAAG,GAAG,UAAU,KAAK,MAAM,eAAe,EAAE,KAAK,CAAC,OAAO,CAElE;EAAE,QADA,KAAK,IAAI,IAAI,GAAG,UAAU,KAAK,MAAO,EAAE,SAAS,IAAI,EAAE,OAAO,GAAG,SAAS,EAAG,CACvE;EAAE;;AAGzB,SAAS,WAAW,EAClB,MACA,WACA,eAKC;CACD,MAAM,QAAQ,gBAAgB,KAAK,KAAK;CACxC,MAAM,WAAW,KAAK,WAAW;CACjC,MAAM,SAAS,KAAK,SAAS;CAC7B,MAAM,WAAW,KAAK,OAAO,MAAM,UAAU,CAAC;CAC9C,MAAM,UAAU,WAAW,IAAI,KAAK,SAAS;CAC7C,MAAM,cAAc,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK;CAExD,MAAM,aACJ,KAAK,WAAW,YACZ,YACA,KAAK,WAAW,aACd,aACA,KAAK,WAAW,UACd,YAAY,CAAC,SACX,WACA,YACF;AAEV,QACE,qBAAC,KAAD;EACE,oBAAC,MAAD,YAAO,MAAY;EACnB,oBAAC,YAAD,EAAY,QAAQ,KAAK,QAAU;EACnC,oBAAC,MAAD,YAAM,KAAQ;EACd,oBAAC,MAAD;GAAa;GAAO;aACjB,eAAe,KAAK,KAAK,CAAC,OAAO,UAAU;GACvC;EACP,oBAAC,MAAD;GAAM,OAAM;aAAQ,YAAY,OAAO,YAAY;GAAQ;EAC3D,oBAAC,MAAD;GAAM,OAAO,KAAK,WAAW,UAAU,YAAY;aAAS;GAAkB;EAC7E,YAAY,qBAAC,MAAD;GAAM,OAAM;aAAZ,CAAsB,KAAE,QAAe;;EAChD;;AAIV,SAAS,cAAc,EAAE,SAA4B;AACnD,QACE,oBAAC,KAAD;EAAK,cAAc;EAAG,WAAW;YAC/B,oBAAC,MAAD;GAAM,OAAM;GAAU;aACnB;GACI;EACH;;AAIV,SAAS,QAAQ,EAAE,SAA8B;AAG/C,QACE,qBAAC,KAAD,aACE,qBAAC,MAAD;EAAM,OAJI,gBAAgB,MAAM,OAId;YAAlB;GAAoB;GAAE,MAAM;GAAO;GAAQ;KAC3C,qBAAC,MAAD;EAAM,OAAO,MAAM,UAAU,YAAY;YAAzC,CAAoD,KAAE,QAAQ,MAAM,KAAK,CAAQ;IAC7E;;AAIV,SAAS,YAAY,KAAa,QAAwB;AACxD,KAAI,IAAI,UAAU,OAAQ,QAAO;AACjC,KAAI;EAEF,MAAM,OAAO,IADM,IAAI,IACJ,CAAC;AACpB,MAAI,KAAK,SAAS,SAAS,GACzB,QAAO,GAAG,KAAK,MAAM,GAAG,SAAS,GAAG,CAAC;AAEvC,SAAO;SACD;AACN,SAAO,GAAG,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;;;AAIvC,SAAS,QAAQ,EACf,WACA,MACA,aACA,aACA,QACA,gBACe;CACf,MAAM,EAAE,SAAS,QAAQ;CACzB,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;AAE3D,WAAU,OAAO,QAAQ;AACvB,MAAI,eAAgB;AAEpB,MAAI,UAAU,OAAQ,IAAI,QAAQ,UAAU,KAAM;AAChD,qBAAkB,KAAK;AACvB,WAAQ,QAAQ,UAAU,CAAC,CAAC,WAAW;AACrC,UAAM;KACN;;AAEJ,MAAI,UAAU,KAAK;AACjB,qBAAkB,KAAK;AACvB,WAAQ,QAAQ,gBAAgB,CAAC,CAAC,WAAW;AAC3C,UAAM;KACN;;GAEJ;CAEF,MAAM,aAAa,UAAU,QAAQ,MAAM,EAAE,WAAW,QAAQ,CAAC;CACjE,MAAM,QAAQ,UAAU;CACxB,MAAM,WAAW,eAAe;CAEhC,MAAM,WADc,UAAU,MAAM,MAAM,EAAE,SAAS,OACzB,EAAE,QAAQ;CACtC,MAAM,aAAa,KAAK,MAAM,IAAI;CAClC,MAAM,qBAAqB,sBAAsB,UAAU;CAC3D,MAAM,eAAe,gBAAgB,UAAU;AAE/C,QACE,qBAAC,KAAD;EAAK,eAAc;YAAnB;GACE,oBAAC,KAAD;IAAK,cAAc;cACjB,oBAAC,MAAD;KAAM,OAAM;eAAW,OAAO,IAAI,GAAG;KAAQ;IACzC;GACN,oBAAC,KAAD,YACE,qBAAC,MAAD;IACG;IACA,MAAM;IAAI;IAAE,UAAU,MAAM,YAAY,aAAa,CAAC;IAClD,KACH;GACN,oBAAC,KAAD;IAAK,cAAc;cACjB,oBAAC,MAAD;KAAM,OAAM;eAAW,OAAO,OAAO,GAAG;KAAQ;IAC5C;GAEL,YACC,qBAAC,KAAD;IAAK,cAAc;IAAG,eAAc;cAApC,CACE,oBAAC,KAAD,YACE,qBAAC,MAAD;KAAM,OAAM;eAAZ;MACG;MACA,MAAM;MAAI;MACN;QACH,GACN,oBAAC,KAAD,YACE,qBAAC,MAAD;KAAM,OAAM;KAAU;eAAtB;MACG;MACA,MAAM;MAAM;MAAmB;MAC3B;QACH,EACF;;GAGP,eACC,oBAAC,KAAD;IAAK,cAAc;cACjB,qBAAC,MAAD;KAAM,OAAM;eAAZ;MACG;MACA,MAAM;MAAM;MAAc,YAAY,aAAa,GAAG;MAClD;;IACH;GAGR,oBAAC,KAAD;IAAK,WAAW;IAAG,cAAc;cAC/B,oBAAC,MAAD,YAAO,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAQ;IAClC;GAEL,mBAAmB,KAAK,YACvB,qBAAC,KAAD;IAAuB,eAAc;cAArC,CACE,oBAAC,eAAD,EAAe,OAAO,QAAQ,OAAS,GACtC,QAAQ,UAAU,KAAK,SACtB,oBAAC,YAAD;KAEQ;KACN,WAAW,aAAa;KACxB,aAAa,aAAa;KAC1B,EAJK,KAAK,KAIV,CACF,CACE;MAVI,QAAQ,IAUZ,CACN;GAEF,oBAAC,KAAD;IAAK,WAAW;IAAG,cAAc;cAC/B,oBAAC,MAAD,YAAO,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAQ;IAClC;GAEN,qBAAC,KAAD;IAAK,WAAW;cAAhB,CACE,qBAAC,MAAD;KAAM,OAAO,WAAW,YAAY;eAApC,CACG,MACA,WACG,GAAG,MAAM,GAAG,OAAO,MAAM,qBACzB,GAAG,MAAM,KAAK,GAAG,WAAW,GAAG,MAAM,QACpC;QACP,qBAAC,MAAD;KAAM,OAAM;eAAZ;MACG;MACA,MAAM;MAAI;MAAS,MAAM;MAAI;MACzB;OACH;;GAEL,WAAW,SAAS,KACnB,4CACE,oBAAC,KAAD;IAAK,WAAW;IAAG,cAAc;cAC/B,oBAAC,MAAD,YAAO,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAQ;IAClC,GACN,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cACpC,WAAW,KAAK,UACf,oBAAC,SAAD,EAA+B,OAAS,EAA1B,MAAM,GAAoB,CACxC;IACE,EACL;GAED;;;AAUV,SAAgB,cACd,kBACA,aACA,KACA,QACA,cACe;CACf,IAAI,YAAY,CAAC,GAAG,iBAAiB;CACrC,IAAI,OAAmB,EAAE;CACzB,IAAI,WAAgC;CACpC,MAAM,cAAc,IAAI;CACxB,IAAI,SAAS;CACb,IAAI,aAA4B;CAEhC,MAAM,iBAAiB,MAAc,QAAuB,YAAqB;AAC/E,cAAY,UAAU,KAAK,MAAO,EAAE,SAAS,OAAO;GAAE,GAAG;GAAG;GAAQ;GAAS,GAAG,EAAG;AACnF,cAAY;;CAGd,MAAM,UAAU,QAAgB,MAAc,UAAU,UAAU;EAChE,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,MAAM,IAAI,GAAG;AACpD,MAAI,YAAY,WAAY;AAC5B,eAAa;AAEb,SAAO,CACL,GAAG,MACH;GAAE,IAAI,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE;GAAU;GAAQ;GAAM,WAAW,KAAK,KAAK;GAAE;GAAS,CAClF;AACD,MAAI,KAAK,SAAS,IAAK,QAAO,KAAK,MAAM,KAAK;AAC9C,cAAY;;CAGd,SAAS,iBAAiB;EACxB,MAAM,GAAG,eAAe,SAAS,EAAE;AAEnC,kBAAgB;AACd,oBAAiB,aAAa,MAAc,IAAI,EAAE;AAClD,gBAAa;AACX,eAAW;;KAEZ,EAAE,CAAC;AAEN,SACE,oBAAC,SAAD;GACa;GACL;GACO;GACA;GACL;GACM;GACd;;CAIN,MAAM,EAAE,YAAY,OAAO,oBAAC,gBAAD,EAAkB,EAAC;AAC9C,QAAO;EAAE;EAAe;EAAQ;EAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming-view.cjs","names":["colors","icons","linkify"],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n const headerLines: string[] = [\n \"\",\n colors.cyan(`${\"─\".repeat(52)}`),\n ` ${icons.run} ${colors.cyan(description.toUpperCase())}`,\n colors.cyan(`${\"─\".repeat(52)}`),\n \"\",\n ];\n\n if (proxyTarget) {\n headerLines.push(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`), \"\");\n }\n\n for (const section of sectionedProcesses) {\n headerLines.push(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n headerLines.push(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n headerLines.push(\"\");\n }\n console.log(headerLines.join(\"\\n\"));\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n const readyLines = [\n \"\",\n colors.dim(`${\"─\".repeat(52)}`),\n colors.green(`${icons.ok} All ${processes.size} services ready`),\n colors.green(`${icons.arrow} http://localhost:${hostPort}`),\n colors.dim(`${\"─\".repeat(52)}`),\n \"\",\n ];\n console.log(readyLines.join(\"\\n\"));\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const isRemote = proc?.source === \"remote\";\n const isHost = name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote) && status === \"ready\";\n const statusText =\n status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = showPort ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"streaming-view.cjs","names":["colors","icons","linkify"],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n const headerLines: string[] = [\n \"\",\n colors.cyan(`${\"─\".repeat(52)}`),\n ` ${icons.run} ${colors.cyan(description.toUpperCase())}`,\n colors.cyan(`${\"─\".repeat(52)}`),\n \"\",\n ];\n\n if (proxyTarget) {\n headerLines.push(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`), \"\");\n }\n\n for (const section of sectionedProcesses) {\n headerLines.push(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n headerLines.push(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n headerLines.push(\"\");\n }\n console.log(headerLines.join(\"\\n\"));\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n const readyLines = [\n \"\",\n colors.dim(`${\"─\".repeat(52)}`),\n colors.green(`${icons.ok} All ${processes.size} services ready`),\n colors.green(`${icons.arrow} http://localhost:${hostPort}`),\n colors.dim(`${\"─\".repeat(52)}`),\n \"\",\n ];\n console.log(readyLines.join(\"\\n\"));\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const isRemote = proc?.source === \"remote\";\n const isHost = name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote) && status === \"ready\";\n const statusText =\n status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = showPort ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming-view.mjs","names":[],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n const headerLines: string[] = [\n \"\",\n colors.cyan(`${\"─\".repeat(52)}`),\n ` ${icons.run} ${colors.cyan(description.toUpperCase())}`,\n colors.cyan(`${\"─\".repeat(52)}`),\n \"\",\n ];\n\n if (proxyTarget) {\n headerLines.push(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`), \"\");\n }\n\n for (const section of sectionedProcesses) {\n headerLines.push(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n headerLines.push(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n headerLines.push(\"\");\n }\n console.log(headerLines.join(\"\\n\"));\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n const readyLines = [\n \"\",\n colors.dim(`${\"─\".repeat(52)}`),\n colors.green(`${icons.ok} All ${processes.size} services ready`),\n colors.green(`${icons.arrow} http://localhost:${hostPort}`),\n colors.dim(`${\"─\".repeat(52)}`),\n \"\",\n ];\n console.log(readyLines.join(\"\\n\"));\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const isRemote = proc?.source === \"remote\";\n const isHost = name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote) && status === \"ready\";\n const statusText =\n status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = showPort ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"streaming-view.mjs","names":[],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n const headerLines: string[] = [\n \"\",\n colors.cyan(`${\"─\".repeat(52)}`),\n ` ${icons.run} ${colors.cyan(description.toUpperCase())}`,\n colors.cyan(`${\"─\".repeat(52)}`),\n \"\",\n ];\n\n if (proxyTarget) {\n headerLines.push(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`), \"\");\n }\n\n for (const section of sectionedProcesses) {\n headerLines.push(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n headerLines.push(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n headerLines.push(\"\");\n }\n console.log(headerLines.join(\"\\n\"));\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n const readyLines = [\n \"\",\n colors.dim(`${\"─\".repeat(52)}`),\n colors.green(`${icons.ok} All ${processes.size} services ready`),\n colors.green(`${icons.arrow} http://localhost:${hostPort}`),\n colors.dim(`${\"─\".repeat(52)}`),\n \"\",\n ];\n console.log(readyLines.join(\"\\n\"));\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const isRemote = proc?.source === \"remote\";\n const isHost = name === \"host\";\n const showPort = proc.port > 0 && (isHost || !isRemote) && status === \"ready\";\n const statusText =\n status === \"ready\"\n ? isRemote && !isHost\n ? \"loaded\"\n : \"running\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = showPort ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|