@fluid-app/fluid-cli-portal 0.1.7 → 0.1.8

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/index.d.mts CHANGED
@@ -106,6 +106,13 @@ interface DestroyOptions {
106
106
  readonly yes?: boolean;
107
107
  }
108
108
  /**
109
+ * Options for the widget create command
110
+ */
111
+ interface WidgetCreateOptions {
112
+ /** Category for palette grouping */
113
+ readonly category?: string;
114
+ }
115
+ /**
109
116
  * Template variables for Handlebars processing
110
117
  */
111
118
  interface TemplateVariables {
@@ -236,6 +243,12 @@ declare const createCommand: Command;
236
243
  //#region src/commands/destroy.d.ts
237
244
  declare const destroyCommand: Command;
238
245
  //#endregion
246
+ //#region src/commands/widget-create.d.ts
247
+ declare const widgetCommand: Command;
248
+ //#endregion
249
+ //#region src/commands/doctor.d.ts
250
+ declare const doctorCommand: Command;
251
+ //#endregion
239
252
  //#region src/utils/cloud-run.d.ts
240
253
  /**
241
254
  * Cloud Run error codes and default messages
@@ -572,5 +585,5 @@ declare function provisionDatabase(config: TursoConfig, projectName: string, loc
572
585
  //#region src/index.d.ts
573
586
  declare const plugin: FluidPlugin;
574
587
  //#endregion
575
- export { type BuildOptions, CLOUD_RUN_ERRORS, type CloudRunConfig, type CloudRunDeployCallbacks, type CloudRunError, type CloudRunResult, type CreateOptions, type DeployOptions, type DestroyOptions, type DevOptions, FILE_SYSTEM_ERRORS, FLUID_API_ERROR, type FileSystemError, type FileSystemErrorCode, type FluidApiError, type FluidApiErrorCode, type FluidCompany, type ProjectConfig, type ResolvedTursoConfig, type SelectedPageTemplate, TEMPLATES, TURSO_ERROR, type TemplateName, type TemplatePaths, type TemplateVariables, type TursoConfig, type TursoConfigSource, type TursoDatabase, type TursoError, type TursoOrg, type TursoProvisionCallbacks, copyTemplate, copyTemplateSafe, createCommand, createDatabase, createDatabaseToken, createDirectory, createDirectorySafe, plugin as default, deleteCloudRunService, deleteDatabase, deployToCloudRun, destroyCommand, directoryExists, ensureGroup, fetchLocations, fileExists, getGcpProject, getInstallCommand, getRunCommand, getSdkVersion, getSdkVersionSafe, getTemplatePaths, installDependencies, isTemplateName, parseOrgList, pathExists, promptProjectConfig, provisionDatabase, readFileSafe, resolveFluidApiKey, resolveTursoConfig, runPackageManager, validateFluidApiKey, validateGcloudAuth, validateGcloudInstalled, validateLocation, validateTursoConfig, writeFileSafe };
588
+ export { type BuildOptions, CLOUD_RUN_ERRORS, type CloudRunConfig, type CloudRunDeployCallbacks, type CloudRunError, type CloudRunResult, type CreateOptions, type DeployOptions, type DestroyOptions, type DevOptions, FILE_SYSTEM_ERRORS, FLUID_API_ERROR, type FileSystemError, type FileSystemErrorCode, type FluidApiError, type FluidApiErrorCode, type FluidCompany, type ProjectConfig, type ResolvedTursoConfig, type SelectedPageTemplate, TEMPLATES, TURSO_ERROR, type TemplateName, type TemplatePaths, type TemplateVariables, type TursoConfig, type TursoConfigSource, type TursoDatabase, type TursoError, type TursoOrg, type TursoProvisionCallbacks, type WidgetCreateOptions, copyTemplate, copyTemplateSafe, createCommand, createDatabase, createDatabaseToken, createDirectory, createDirectorySafe, plugin as default, deleteCloudRunService, deleteDatabase, deployToCloudRun, destroyCommand, directoryExists, doctorCommand, ensureGroup, fetchLocations, fileExists, getGcpProject, getInstallCommand, getRunCommand, getSdkVersion, getSdkVersionSafe, getTemplatePaths, installDependencies, isTemplateName, parseOrgList, pathExists, promptProjectConfig, provisionDatabase, readFileSafe, resolveFluidApiKey, resolveTursoConfig, runPackageManager, validateFluidApiKey, validateGcloudAuth, validateGcloudInstalled, validateLocation, validateTursoConfig, widgetCommand, writeFileSafe };
576
589
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/utils/package-manager.ts","../src/utils/file-system.ts","../src/utils/prompts.ts","../src/commands/create.ts","../src/commands/destroy.ts","../src/utils/cloud-run.ts","../src/utils/fluid-api.ts","../src/utils/turso.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/utils/package-manager.ts","../src/utils/file-system.ts","../src/utils/prompts.ts","../src/commands/create.ts","../src/commands/destroy.ts","../src/commands/widget-create.ts","../src/commands/doctor.ts","../src/utils/cloud-run.ts","../src/utils/fluid-api.ts","../src/utils/turso.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  import { Command } from "commander";
2
2
  import chalk from "chalk";
3
3
  import ora from "ora";
4
- import { dirname, join, resolve } from "node:path";
4
+ import path, { dirname, join, resolve } from "node:path";
5
5
  import { copyFile, mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
6
6
  import prompts from "prompts";
7
- import { existsSync } from "node:fs";
7
+ import { existsSync, readFileSync } from "node:fs";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import Handlebars from "handlebars";
10
10
  import { failure, getErrorMessage, success } from "@fluid-app/fluid-cli";
11
11
  import { execa } from "execa";
12
12
  import fs from "fs-extra";
13
- import path from "path";
13
+ import path$1 from "path";
14
14
  import { config } from "dotenv";
15
15
  //#region src/types.ts
16
16
  /**
@@ -110,13 +110,13 @@ async function promptProjectConfig(projectName, options) {
110
110
  }
111
111
  //#endregion
112
112
  //#region src/utils/file-system.ts
113
- const _currentDir = dirname(fileURLToPath(import.meta.url));
113
+ const _currentDir$1 = dirname(fileURLToPath(import.meta.url));
114
114
  /**
115
115
  * Find the package root by walking up from the current directory to the nearest package.json.
116
116
  * Works whether running from dist/ (bundled) or src/utils/ (tsx dev mode).
117
117
  */
118
118
  function findPackageRoot() {
119
- let dir = _currentDir;
119
+ let dir = _currentDir$1;
120
120
  while (!existsSync(join(dir, "package.json"))) {
121
121
  const parent = dirname(dir);
122
122
  if (parent === dir) throw new Error("Could not find package root");
@@ -1314,7 +1314,7 @@ async function validateFluidApiKey(apiKey) {
1314
1314
  * Read project name from package.json
1315
1315
  */
1316
1316
  async function getProjectName(cwd) {
1317
- const packageJsonPath = path.join(cwd, "package.json");
1317
+ const packageJsonPath = path$1.join(cwd, "package.json");
1318
1318
  if (await fs.pathExists(packageJsonPath)) return (await fs.readJson(packageJsonPath)).name;
1319
1319
  }
1320
1320
  /**
@@ -1351,8 +1351,8 @@ const EXTRACT_FILENAME = "__fluid_extract_nav.ts";
1351
1351
  * @param projectDir - The project root directory containing src/navigation.config.ts
1352
1352
  */
1353
1353
  async function extractNavigation(projectDir) {
1354
- const configPath = path.join(projectDir, "src", "navigation.config.ts");
1355
- const extractFile = path.join(projectDir, EXTRACT_FILENAME);
1354
+ const configPath = path$1.join(projectDir, "src", "navigation.config.ts");
1355
+ const extractFile = path$1.join(projectDir, EXTRACT_FILENAME);
1356
1356
  try {
1357
1357
  const configSource = await fs.readFile(configPath, "utf-8");
1358
1358
  if (!/export\s+(const|let)\s+navigation\s*=/.test(configSource)) return success(null);
@@ -1610,11 +1610,11 @@ async function syncNavigation(apiKey, codeItems) {
1610
1610
  * Detect if the project is a fullstack template (has server entry)
1611
1611
  */
1612
1612
  async function isFullstackProject(cwd) {
1613
- return fs.pathExists(path.join(cwd, "src", "server", "index.ts"));
1613
+ return fs.pathExists(path$1.join(cwd, "src", "server", "index.ts"));
1614
1614
  }
1615
1615
  const deployCommand = new Command("deploy").description("Deploy the fullstack application to Cloud Run + Turso").option("--region <region>", "Cloud Run region", "us-central1").option("--gcp-project <id>", "GCP project ID (default: from gcloud config)").option("-p, --project <name>", "Service name override (default: from package.json)").option("--db-region <location>", "Turso database group location", "aws-us-east-1").option("--require-auth", "Require IAM authentication for the Cloud Run service (default: public)").option("--migrate", "Run database migrations (db:push) after successful deploy").option("--skip-local-build", "Skip the local Docker build check before deploying").option("--turso-org <slug>", "Turso organization slug (skips interactive org selection)").option("--fluid-company-api-key <key>", "Fluid company API key (skips env var lookup and prompt)").option("--skip-nav-sync", "Skip navigation sync from portal.config.ts").action(async (options) => {
1616
1616
  const cwd = process.cwd();
1617
- config({ path: path.join(cwd, ".env") });
1617
+ config({ path: path$1.join(cwd, ".env") });
1618
1618
  console.log();
1619
1619
  console.log(chalk.blue.bold("Fluid Deploy") + chalk.gray(" (Cloud Run + Turso)"));
1620
1620
  console.log();
@@ -1646,7 +1646,7 @@ const deployCommand = new Command("deploy").description("Deploy the fullstack ap
1646
1646
  process.exit(1);
1647
1647
  }
1648
1648
  spinner.succeed(`Fluid company: ${chalk.cyan(fluidResult.value.name)}`);
1649
- if (!await fs.pathExists(path.join(cwd, "Dockerfile"))) {
1649
+ if (!await fs.pathExists(path$1.join(cwd, "Dockerfile"))) {
1650
1650
  console.log(chalk.red("Error:") + " No Dockerfile found in current directory.");
1651
1651
  console.log();
1652
1652
  console.log("Fullstack projects created with the latest template include a Dockerfile.");
@@ -1845,7 +1845,7 @@ const deployCommand = new Command("deploy").description("Deploy the fullstack ap
1845
1845
  console.log(chalk.gray("GCP Project: ") + chalk.cyan(deployResult.value.gcpProject));
1846
1846
  console.log();
1847
1847
  if (!options.skipNavSync) {
1848
- const configPath = path.join(cwd, "src", "navigation.config.ts");
1848
+ const configPath = path$1.join(cwd, "src", "navigation.config.ts");
1849
1849
  if (await fs.pathExists(configPath)) {
1850
1850
  const navSpinner = ora("Extracting navigation from navigation.config.ts...").start();
1851
1851
  const extractResult = await extractNavigation(cwd);
@@ -1936,7 +1936,7 @@ function registerDeployCommand(ctx) {
1936
1936
  //#region src/commands/destroy.ts
1937
1937
  const destroyCommand = new Command("destroy").description("Tear down deployed Cloud Run service and Turso database").option("--region <region>", "Cloud Run region", "us-central1").option("--gcp-project <id>", "GCP project ID (default: from gcloud config)").option("-p, --project <name>", "Service name override (default: from package.json)").option("--turso-org <slug>", "Turso organization slug (skips interactive org selection)").option("--fluid-company-api-key <key>", "Fluid company API key (skips env var lookup and prompt)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
1938
1938
  const cwd = process.cwd();
1939
- config({ path: path.join(cwd, ".env") });
1939
+ config({ path: path$1.join(cwd, ".env") });
1940
1940
  console.log();
1941
1941
  console.log(chalk.red.bold("Fluid Destroy") + chalk.gray(" (Cloud Run + Turso)"));
1942
1942
  console.log();
@@ -2072,6 +2072,354 @@ function registerDestroyCommand(ctx) {
2072
2072
  ctx.program.addCommand(destroyCommand);
2073
2073
  }
2074
2074
  //#endregion
2075
+ //#region src/utils/widget-helpers.ts
2076
+ /**
2077
+ * Pure helper functions for widget scaffolding.
2078
+ * Extracted from widget-create command for testability.
2079
+ */
2080
+ /**
2081
+ * Convert kebab-case name to PascalCase widget type.
2082
+ * e.g., "stock-ticker" → "StockTickerWidget"
2083
+ */
2084
+ function toWidgetType(name) {
2085
+ const pascal = name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
2086
+ return pascal.endsWith("Widget") ? pascal : `${pascal}Widget`;
2087
+ }
2088
+ /**
2089
+ * Derive the component name from a widget type.
2090
+ * Strips the trailing "Widget" suffix, but only if the result is non-empty
2091
+ * and starts with a letter (not a digit).
2092
+ * e.g., "StockTickerWidget" → "StockTicker"
2093
+ */
2094
+ function toComponentName(widgetType) {
2095
+ if (widgetType === "Widget") return "Widget";
2096
+ return widgetType.replace(/Widget$/, "") || widgetType;
2097
+ }
2098
+ /**
2099
+ * Convert kebab-case name to a display name.
2100
+ * e.g., "stock-ticker" → "Stock Ticker"
2101
+ */
2102
+ function toDisplayName(name) {
2103
+ return name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
2104
+ }
2105
+ /**
2106
+ * Convert kebab-case to camelCase.
2107
+ * e.g., "stock-ticker" → "stockTicker"
2108
+ */
2109
+ function toCamelCase(name) {
2110
+ return name.replace(/-./g, (x) => x.charAt(1).toUpperCase());
2111
+ }
2112
+ /**
2113
+ * Validate a widget name for scaffold.
2114
+ * Must be kebab-case, no trailing/consecutive dashes, no bare "widget".
2115
+ */
2116
+ function validateWidgetName(name) {
2117
+ if (!/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(name)) return "Widget name must be kebab-case with no trailing or consecutive dashes (e.g., stock-ticker).";
2118
+ if (name === "widget") return "Widget name \"widget\" is reserved. Use a more descriptive name (e.g., custom-widget).";
2119
+ return null;
2120
+ }
2121
+ /**
2122
+ * Insert an import line after the last import in a source file.
2123
+ * Skips if the import already exists (prevents duplicates on re-scaffold).
2124
+ * Returns null if no imports exist in the source.
2125
+ */
2126
+ function insertImport(source, importLine) {
2127
+ if (source.includes(importLine)) return source;
2128
+ const lastImportIndex = source.lastIndexOf("import ");
2129
+ if (lastImportIndex === -1) return null;
2130
+ const lineEnd = source.indexOf("\n", lastImportIndex);
2131
+ if (lineEnd === -1) return source + "\n" + importLine + "\n";
2132
+ return source.slice(0, lineEnd + 1) + importLine + "\n" + source.slice(lineEnd + 1);
2133
+ }
2134
+ /**
2135
+ * Insert a manifest reference into the customWidgets array.
2136
+ * Preserves developer comments. Skips if already present.
2137
+ * Returns null if the array pattern isn't found.
2138
+ */
2139
+ function insertIntoCustomWidgets(source, camelName) {
2140
+ let matched = false;
2141
+ const result = source.replace(/export const customWidgets:\s*WidgetManifest\[\]\s*=\s*\[([^\]]*)\]/, (_match, inner) => {
2142
+ matched = true;
2143
+ const lines = inner.split("\n");
2144
+ const existingEntries = [];
2145
+ for (const line of lines) {
2146
+ const trimmed = line.trim();
2147
+ if (trimmed && !trimmed.startsWith("//")) existingEntries.push(trimmed.replace(/,$/, ""));
2148
+ }
2149
+ if (existingEntries.includes(camelName)) return _match;
2150
+ const commentLines = lines.filter((line) => line.trim().startsWith("//")).map((line) => line.trimEnd());
2151
+ return `export const customWidgets: WidgetManifest[] = [${commentLines.length > 0 ? "\n" + commentLines.join("\n") : ""}\n${[...existingEntries, camelName].map((e) => ` ${e},`).join("\n")}\n]`;
2152
+ });
2153
+ return matched ? result : null;
2154
+ }
2155
+ //#endregion
2156
+ //#region src/commands/widget-create.ts
2157
+ const createSubcommand = new Command("create").description("Scaffold a new custom widget").argument("<name>", "Widget name in kebab-case (e.g., stock-ticker)").option("-c, --category <category>", "Widget category for palette grouping", "components").action(async (name, options) => {
2158
+ const cwd = process.cwd();
2159
+ const widgetDir = path.join(cwd, "src", "widgets", name);
2160
+ const validationError = validateWidgetName(name);
2161
+ if (validationError) {
2162
+ console.error(chalk.red(`Error: ${validationError}`));
2163
+ process.exit(1);
2164
+ }
2165
+ if (!fs.existsSync(path.join(cwd, "src", "portal.config.ts"))) {
2166
+ console.error(chalk.red("Error: No src/portal.config.ts found."));
2167
+ console.error(chalk.yellow("Run this command from a Fluid portal project root."));
2168
+ process.exit(1);
2169
+ }
2170
+ if (fs.existsSync(widgetDir)) {
2171
+ console.error(chalk.red(`Error: Widget directory already exists: src/widgets/${name}`));
2172
+ process.exit(1);
2173
+ }
2174
+ const widgetType = toWidgetType(name);
2175
+ const componentName = toComponentName(widgetType);
2176
+ const displayName = toDisplayName(name);
2177
+ const category = options.category ?? "components";
2178
+ try {
2179
+ await fs.ensureDir(widgetDir);
2180
+ await fs.writeFile(path.join(widgetDir, "component.tsx"), `interface ${widgetType}Props {
2181
+ title?: string;
2182
+ }
2183
+
2184
+ export function ${componentName}({ title = "${displayName}" }: ${widgetType}Props) {
2185
+ return (
2186
+ <div className="p-4">
2187
+ <h3 className="text-lg font-semibold">{title}</h3>
2188
+ <p className="text-sm text-gray-500">
2189
+ Edit this widget in src/widgets/${name}/component.tsx
2190
+ </p>
2191
+ </div>
2192
+ );
2193
+ }
2194
+ `);
2195
+ await fs.writeFile(path.join(widgetDir, "manifest.ts"), `import type { WidgetManifest } from "@fluid-app/portal-core/registries";
2196
+ import { ${componentName} } from "./component";
2197
+
2198
+ export const manifest: WidgetManifest = {
2199
+ manifestVersion: 1,
2200
+ type: "${widgetType}",
2201
+ component: ${componentName},
2202
+ displayName: "${displayName}",
2203
+ description: "A custom ${displayName.toLowerCase()} widget",
2204
+ icon: "puzzle-piece",
2205
+ category: "${category}",
2206
+ propertySchema: {
2207
+ widgetType: "${widgetType}",
2208
+ displayName: "${displayName}",
2209
+ fields: [{ key: "title", label: "Title", type: "text" }],
2210
+ },
2211
+ defaultProps: {
2212
+ title: "${displayName}",
2213
+ },
2214
+ };
2215
+ `);
2216
+ await fs.writeFile(path.join(widgetDir, "index.ts"), `export { ${componentName} } from "./component";
2217
+ export { manifest } from "./manifest";
2218
+ `);
2219
+ } catch (err) {
2220
+ await fs.remove(widgetDir).catch(() => {});
2221
+ console.error(chalk.red("Error: Failed to scaffold widget files."));
2222
+ console.error(err);
2223
+ process.exit(1);
2224
+ }
2225
+ const configPath = path.join(cwd, "src", "portal.config.ts");
2226
+ const camelName = toCamelCase(name);
2227
+ const importLine = `import { manifest as ${camelName} } from "./widgets/${name}";`;
2228
+ const configSource = await fs.readFile(configPath, "utf-8");
2229
+ const withImport = insertImport(configSource, importLine);
2230
+ if (withImport === null) {
2231
+ console.warn(chalk.yellow("Warning: Could not find import statements in portal.config.ts. Add the import manually:"));
2232
+ console.warn(chalk.cyan(` ${importLine}`));
2233
+ }
2234
+ const updated = insertIntoCustomWidgets(withImport ?? configSource, camelName);
2235
+ if (updated === null) {
2236
+ console.warn(chalk.yellow("Warning: Could not find customWidgets array in portal.config.ts. Add the manifest manually:"));
2237
+ console.warn(chalk.cyan(` ${camelName}`));
2238
+ }
2239
+ if (updated !== null) await fs.writeFile(configPath, updated, "utf-8");
2240
+ else if (withImport !== null) await fs.writeFile(configPath, withImport, "utf-8");
2241
+ console.log();
2242
+ console.log(chalk.green("Created widget:") + ` src/widgets/${name}/`);
2243
+ console.log(chalk.gray(" component.tsx — React component"));
2244
+ console.log(chalk.gray(" manifest.ts — WidgetManifest"));
2245
+ console.log(chalk.gray(" index.ts — Re-exports"));
2246
+ console.log();
2247
+ if (updated !== null) {
2248
+ console.log(chalk.green("Registered") + ` in ${chalk.cyan("src/portal.config.ts")}`);
2249
+ console.log();
2250
+ }
2251
+ console.log(chalk.yellow("Next steps:"));
2252
+ console.log(` 1. Edit the component in ${chalk.cyan(`src/widgets/${name}/component.tsx`)}`);
2253
+ console.log(` 2. Customize the manifest fields in ${chalk.cyan(`src/widgets/${name}/manifest.ts`)}`);
2254
+ console.log(` 3. Run ${chalk.cyan("fluid dev")} to preview in the builder`);
2255
+ });
2256
+ const widgetCommand = new Command("widget").description("Manage custom portal widgets").addCommand(createSubcommand);
2257
+ function registerWidgetCommand(ctx) {
2258
+ ctx.program.addCommand(widgetCommand);
2259
+ }
2260
+ //#endregion
2261
+ //#region src/commands/doctor.ts
2262
+ /** Files that are managed by the SDK and should match the canonical template. */
2263
+ const INFRASTRUCTURE_FILES = [
2264
+ "index.html",
2265
+ "tsconfig.json",
2266
+ "vite.config.ts",
2267
+ ".oxlintrc.json"
2268
+ ];
2269
+ /** Entry files with expected content patterns after Phase 2 absorption. */
2270
+ const ENTRY_CHECKS = [{
2271
+ file: "src/main.tsx",
2272
+ expectedPattern: "createPortal",
2273
+ hint: "main.tsx should use createPortal() from @fluid-app/portal-sdk. Run \"fluid create\" to see the latest template."
2274
+ }, {
2275
+ file: "src/index.css",
2276
+ expectedPattern: "@fluid-app/portal-sdk/globals.css",
2277
+ hint: "index.css should import @fluid-app/portal-sdk/globals.css instead of inline theme tokens."
2278
+ }];
2279
+ /** Files that should NOT exist after Phase 2 (absorbed into SDK). */
2280
+ const REMOVED_FILES = [{
2281
+ file: "src/App.tsx",
2282
+ hint: "App.tsx is no longer needed — createPortal() handles the AppShell wiring internally."
2283
+ }, {
2284
+ file: "src/fluid.config.ts",
2285
+ hint: "fluid.config.ts is no longer needed — pass config overrides to createPortal() directly."
2286
+ }];
2287
+ function readFileOrNull(filePath) {
2288
+ try {
2289
+ return readFileSync(filePath, "utf-8");
2290
+ } catch {
2291
+ return null;
2292
+ }
2293
+ }
2294
+ const _currentDir = dirname(fileURLToPath(import.meta.url));
2295
+ function findTemplateDir() {
2296
+ let dir = _currentDir;
2297
+ while (!existsSync(join(dir, "package.json"))) {
2298
+ const parent = dirname(dir);
2299
+ if (parent === dir) break;
2300
+ dir = parent;
2301
+ }
2302
+ const templateDir = join(dir, "templates");
2303
+ if (existsSync(join(templateDir, "base"))) return templateDir;
2304
+ return null;
2305
+ }
2306
+ function checkInfrastructureDrift(cwd, templateDir) {
2307
+ const diagnostics = [];
2308
+ for (const file of INFRASTRUCTURE_FILES) {
2309
+ const portalPath = join(cwd, file);
2310
+ const templatePath = join(templateDir, "base", file);
2311
+ if (!existsSync(portalPath)) {
2312
+ diagnostics.push({
2313
+ file,
2314
+ severity: "warn",
2315
+ message: `Missing file: ${file}`
2316
+ });
2317
+ continue;
2318
+ }
2319
+ if (!existsSync(templatePath)) continue;
2320
+ const portalContent = readFileOrNull(portalPath);
2321
+ const templateContent = readFileOrNull(templatePath);
2322
+ if (portalContent !== null && templateContent !== null) {
2323
+ if (portalContent.trim() !== templateContent.trim()) diagnostics.push({
2324
+ file,
2325
+ severity: "warn",
2326
+ message: `Content differs from canonical template. Review and update if needed.`
2327
+ });
2328
+ }
2329
+ }
2330
+ return diagnostics;
2331
+ }
2332
+ function checkEntryPatterns(cwd) {
2333
+ const diagnostics = [];
2334
+ for (const check of ENTRY_CHECKS) {
2335
+ const content = readFileOrNull(join(cwd, check.file));
2336
+ if (content === null) {
2337
+ diagnostics.push({
2338
+ file: check.file,
2339
+ severity: "error",
2340
+ message: `Missing file. ${check.hint}`
2341
+ });
2342
+ continue;
2343
+ }
2344
+ if (!content.includes(check.expectedPattern)) diagnostics.push({
2345
+ file: check.file,
2346
+ severity: "warn",
2347
+ message: `Does not contain expected pattern "${check.expectedPattern}". ${check.hint}`
2348
+ });
2349
+ }
2350
+ return diagnostics;
2351
+ }
2352
+ function checkRemovedFiles(cwd) {
2353
+ const diagnostics = [];
2354
+ for (const check of REMOVED_FILES) if (existsSync(join(cwd, check.file))) diagnostics.push({
2355
+ file: check.file,
2356
+ severity: "info",
2357
+ message: `File can be removed. ${check.hint}`
2358
+ });
2359
+ return diagnostics;
2360
+ }
2361
+ function formatDiagnostic(d) {
2362
+ return ` ${d.severity === "error" ? chalk.red("ERROR") : d.severity === "warn" ? chalk.yellow(" WARN") : chalk.blue(" INFO")} ${chalk.bold(d.file)}\n ${chalk.dim(d.message)}`;
2363
+ }
2364
+ const doctorCommand = new Command("doctor").description("Check portal for scaffold drift and report stale infrastructure files").action(async () => {
2365
+ const cwd = process.cwd();
2366
+ const packageJsonPath = join(cwd, "package.json");
2367
+ if (!existsSync(packageJsonPath)) {
2368
+ console.error(chalk.red("Error: No package.json found in current directory"));
2369
+ console.error(chalk.yellow("Make sure you're in a Fluid portal project directory"));
2370
+ process.exit(1);
2371
+ }
2372
+ let packageJson;
2373
+ try {
2374
+ packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
2375
+ } catch {
2376
+ console.error(chalk.red("Error: Could not parse package.json"));
2377
+ console.error(chalk.yellow("Ensure package.json contains valid JSON"));
2378
+ process.exit(1);
2379
+ }
2380
+ if (!{
2381
+ ...packageJson.dependencies,
2382
+ ...packageJson.devDependencies
2383
+ }["@fluid-app/portal-sdk"]) {
2384
+ console.error(chalk.red("Error: @fluid-app/portal-sdk not found in dependencies"));
2385
+ console.error(chalk.yellow("This command must be run from a Fluid portal project directory"));
2386
+ process.exit(1);
2387
+ }
2388
+ console.log();
2389
+ console.log(chalk.bold("Fluid Portal Doctor"));
2390
+ console.log(chalk.dim("Checking for scaffold drift...\n"));
2391
+ const diagnostics = [];
2392
+ diagnostics.push(...checkEntryPatterns(cwd));
2393
+ diagnostics.push(...checkRemovedFiles(cwd));
2394
+ const templateDir = findTemplateDir();
2395
+ if (templateDir) diagnostics.push(...checkInfrastructureDrift(cwd, templateDir));
2396
+ else console.log(chalk.dim(" (Skipping infrastructure diff — template files not available)\n"));
2397
+ if (diagnostics.length === 0) {
2398
+ console.log(chalk.green(" All clear — no drift detected.\n"));
2399
+ return;
2400
+ }
2401
+ const errors = diagnostics.filter((d) => d.severity === "error");
2402
+ const warns = diagnostics.filter((d) => d.severity === "warn");
2403
+ const infos = diagnostics.filter((d) => d.severity === "info");
2404
+ for (const d of [
2405
+ ...errors,
2406
+ ...warns,
2407
+ ...infos
2408
+ ]) {
2409
+ console.log(formatDiagnostic(d));
2410
+ console.log();
2411
+ }
2412
+ const parts = [];
2413
+ if (errors.length > 0) parts.push(chalk.red(`${errors.length} error(s)`));
2414
+ if (warns.length > 0) parts.push(chalk.yellow(`${warns.length} warning(s)`));
2415
+ if (infos.length > 0) parts.push(chalk.blue(`${infos.length} info`));
2416
+ console.log(` ${parts.join(", ")}\n`);
2417
+ if (errors.length > 0) process.exit(1);
2418
+ });
2419
+ function registerDoctorCommand(ctx) {
2420
+ ctx.program.addCommand(doctorCommand);
2421
+ }
2422
+ //#endregion
2075
2423
  //#region src/index.ts
2076
2424
  const plugin = {
2077
2425
  name: "fluid-cli-portal",
@@ -2082,9 +2430,11 @@ const plugin = {
2082
2430
  registerBuildCommand(ctx);
2083
2431
  registerDeployCommand(ctx);
2084
2432
  registerDestroyCommand(ctx);
2433
+ registerWidgetCommand(ctx);
2434
+ registerDoctorCommand(ctx);
2085
2435
  }
2086
2436
  };
2087
2437
  //#endregion
2088
- export { CLOUD_RUN_ERRORS, FILE_SYSTEM_ERRORS, FLUID_API_ERROR, TEMPLATES, TURSO_ERROR, copyTemplate, copyTemplateSafe, createCommand, createDatabase, createDatabaseToken, createDirectory, createDirectorySafe, plugin as default, deleteCloudRunService, deleteDatabase, deployToCloudRun, destroyCommand, directoryExists, ensureGroup, fetchLocations, fileExists, getGcpProject, getInstallCommand, getRunCommand, getSdkVersion, getSdkVersionSafe, getTemplatePaths, installDependencies, isTemplateName, parseOrgList, pathExists, promptProjectConfig, provisionDatabase, readFileSafe, resolveFluidApiKey, resolveTursoConfig, runPackageManager, validateFluidApiKey, validateGcloudAuth, validateGcloudInstalled, validateLocation, validateTursoConfig, writeFileSafe };
2438
+ export { CLOUD_RUN_ERRORS, FILE_SYSTEM_ERRORS, FLUID_API_ERROR, TEMPLATES, TURSO_ERROR, copyTemplate, copyTemplateSafe, createCommand, createDatabase, createDatabaseToken, createDirectory, createDirectorySafe, plugin as default, deleteCloudRunService, deleteDatabase, deployToCloudRun, destroyCommand, directoryExists, doctorCommand, ensureGroup, fetchLocations, fileExists, getGcpProject, getInstallCommand, getRunCommand, getSdkVersion, getSdkVersionSafe, getTemplatePaths, installDependencies, isTemplateName, parseOrgList, pathExists, promptProjectConfig, provisionDatabase, readFileSafe, resolveFluidApiKey, resolveTursoConfig, runPackageManager, validateFluidApiKey, validateGcloudAuth, validateGcloudInstalled, validateLocation, validateTursoConfig, widgetCommand, writeFileSafe };
2089
2439
 
2090
2440
  //# sourceMappingURL=index.mjs.map