syncorejs 0.1.0 → 0.2.1

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.
Files changed (200) hide show
  1. package/dist/{core/src/cli.d.ts → _vendor/cli/app.d.mts} +4 -2
  2. package/dist/_vendor/cli/app.d.mts.map +1 -0
  3. package/dist/_vendor/cli/app.mjs +997 -0
  4. package/dist/_vendor/cli/app.mjs.map +1 -0
  5. package/dist/_vendor/cli/context.mjs +180 -0
  6. package/dist/_vendor/cli/context.mjs.map +1 -0
  7. package/dist/_vendor/cli/dev-session.mjs +49 -0
  8. package/dist/_vendor/cli/dev-session.mjs.map +1 -0
  9. package/dist/_vendor/cli/doctor.mjs +80 -0
  10. package/dist/_vendor/cli/doctor.mjs.map +1 -0
  11. package/dist/_vendor/cli/errors.mjs +22 -0
  12. package/dist/_vendor/cli/errors.mjs.map +1 -0
  13. package/dist/_vendor/cli/help.mjs +26 -0
  14. package/dist/_vendor/cli/help.mjs.map +1 -0
  15. package/dist/_vendor/cli/index.d.mts +2 -0
  16. package/dist/_vendor/cli/index.mjs +23 -0
  17. package/dist/_vendor/cli/index.mjs.map +1 -0
  18. package/dist/_vendor/cli/messages.mjs +32 -0
  19. package/dist/_vendor/cli/messages.mjs.map +1 -0
  20. package/dist/_vendor/cli/preflight.mjs +35 -0
  21. package/dist/_vendor/cli/preflight.mjs.map +1 -0
  22. package/dist/_vendor/cli/project.mjs +583 -0
  23. package/dist/_vendor/cli/project.mjs.map +1 -0
  24. package/dist/_vendor/cli/render.mjs +133 -0
  25. package/dist/_vendor/cli/render.mjs.map +1 -0
  26. package/dist/_vendor/cli/targets.mjs +87 -0
  27. package/dist/_vendor/cli/targets.mjs.map +1 -0
  28. package/dist/_vendor/core/cli.d.mts +59 -1
  29. package/dist/_vendor/core/cli.d.mts.map +1 -1
  30. package/dist/_vendor/core/cli.mjs +528 -75
  31. package/dist/_vendor/core/cli.mjs.map +1 -1
  32. package/dist/_vendor/core/index.d.mts +12 -4
  33. package/dist/_vendor/core/index.d.mts.map +1 -0
  34. package/dist/_vendor/core/index.mjs +4 -3
  35. package/dist/_vendor/core/index.mjs.map +1 -1
  36. package/dist/_vendor/core/runtime/devtools.d.mts +32 -6
  37. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  38. package/dist/_vendor/core/runtime/devtools.mjs +397 -182
  39. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  40. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  41. package/dist/_vendor/core/runtime/runtime.d.mts +89 -7
  42. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  43. package/dist/_vendor/core/runtime/runtime.mjs +303 -32
  44. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  45. package/dist/_vendor/devtools-protocol/index.d.ts +189 -82
  46. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  47. package/dist/_vendor/devtools-protocol/index.js +39 -0
  48. package/dist/_vendor/devtools-protocol/index.js.map +1 -0
  49. package/dist/_vendor/next/config.d.ts.map +1 -1
  50. package/dist/_vendor/next/config.js +2 -5
  51. package/dist/_vendor/next/config.js.map +1 -1
  52. package/dist/_vendor/platform-expo/index.d.ts +15 -5
  53. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  54. package/dist/_vendor/platform-expo/index.js +33 -3
  55. package/dist/_vendor/platform-expo/index.js.map +1 -1
  56. package/dist/_vendor/platform-expo/react.js.map +1 -1
  57. package/dist/_vendor/platform-node/index.d.mts +10 -5
  58. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  59. package/dist/_vendor/platform-node/index.mjs +145 -35
  60. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  61. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  62. package/dist/_vendor/platform-web/external-change.d.ts +39 -0
  63. package/dist/_vendor/platform-web/external-change.d.ts.map +1 -0
  64. package/dist/_vendor/platform-web/external-change.js +61 -0
  65. package/dist/_vendor/platform-web/external-change.js.map +1 -0
  66. package/dist/_vendor/platform-web/index.d.ts +27 -5
  67. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  68. package/dist/_vendor/platform-web/index.js +310 -44
  69. package/dist/_vendor/platform-web/index.js.map +1 -1
  70. package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
  71. package/dist/_vendor/platform-web/opfs.js.map +1 -1
  72. package/dist/_vendor/platform-web/persistence.js.map +1 -1
  73. package/dist/_vendor/platform-web/react.js.map +1 -1
  74. package/dist/_vendor/platform-web/sqljs.js +22 -2
  75. package/dist/_vendor/platform-web/sqljs.js.map +1 -1
  76. package/dist/_vendor/schema/definition.js.map +1 -1
  77. package/dist/_vendor/schema/planner.js.map +1 -1
  78. package/dist/_vendor/schema/validators.js.map +1 -1
  79. package/dist/browser-react.d.ts +1 -1
  80. package/dist/browser-react.js +1 -1
  81. package/dist/browser.d.ts +6 -7
  82. package/dist/browser.d.ts.map +1 -1
  83. package/dist/browser.js +4 -5
  84. package/dist/browser.js.map +1 -1
  85. package/dist/cli.d.ts +1 -1
  86. package/dist/cli.js +12 -3
  87. package/dist/cli.js.map +1 -1
  88. package/dist/expo-react.d.ts +1 -1
  89. package/dist/expo-react.js +1 -1
  90. package/dist/expo.d.ts +1 -2
  91. package/dist/expo.js +1 -2
  92. package/dist/index.d.ts +3 -7
  93. package/dist/index.js +3 -8
  94. package/dist/next-config.d.ts +1 -2
  95. package/dist/next-config.js +1 -2
  96. package/dist/next.d.ts +1 -3
  97. package/dist/next.js +1 -3
  98. package/dist/node-ipc-react.d.ts +1 -1
  99. package/dist/node-ipc-react.js +1 -1
  100. package/dist/node-ipc.d.ts +1 -2
  101. package/dist/node-ipc.js +1 -2
  102. package/dist/node.d.ts +1 -4
  103. package/dist/node.js +1 -3
  104. package/dist/react.d.ts +1 -2
  105. package/dist/react.js +1 -2
  106. package/dist/svelte.d.ts +1 -2
  107. package/dist/svelte.js +1 -2
  108. package/package.json +6 -3
  109. package/dist/core/src/cli.d.ts.map +0 -1
  110. package/dist/core/src/cli.js +0 -1196
  111. package/dist/core/src/cli.js.map +0 -1
  112. package/dist/core/src/index.js +0 -7
  113. package/dist/core/src/runtime/devtools.d.ts +0 -7
  114. package/dist/core/src/runtime/devtools.d.ts.map +0 -1
  115. package/dist/core/src/runtime/devtools.js +0 -300
  116. package/dist/core/src/runtime/devtools.js.map +0 -1
  117. package/dist/core/src/runtime/functions.d.ts +0 -123
  118. package/dist/core/src/runtime/functions.d.ts.map +0 -1
  119. package/dist/core/src/runtime/functions.js +0 -71
  120. package/dist/core/src/runtime/functions.js.map +0 -1
  121. package/dist/core/src/runtime/id.d.ts +0 -13
  122. package/dist/core/src/runtime/id.d.ts.map +0 -1
  123. package/dist/core/src/runtime/id.js +0 -28
  124. package/dist/core/src/runtime/id.js.map +0 -1
  125. package/dist/core/src/runtime/runtime.d.ts +0 -371
  126. package/dist/core/src/runtime/runtime.d.ts.map +0 -1
  127. package/dist/core/src/runtime/runtime.js +0 -1143
  128. package/dist/core/src/runtime/runtime.js.map +0 -1
  129. package/dist/devtools-protocol/src/index.d.ts +0 -201
  130. package/dist/devtools-protocol/src/index.d.ts.map +0 -1
  131. package/dist/next/src/config.d.ts +0 -17
  132. package/dist/next/src/config.d.ts.map +0 -1
  133. package/dist/next/src/config.js +0 -73
  134. package/dist/next/src/config.js.map +0 -1
  135. package/dist/next/src/index.d.ts +0 -80
  136. package/dist/next/src/index.d.ts.map +0 -1
  137. package/dist/next/src/index.js +0 -82
  138. package/dist/next/src/index.js.map +0 -1
  139. package/dist/platform-expo/src/index.d.ts +0 -96
  140. package/dist/platform-expo/src/index.d.ts.map +0 -1
  141. package/dist/platform-expo/src/index.js +0 -198
  142. package/dist/platform-expo/src/index.js.map +0 -1
  143. package/dist/platform-expo/src/react.d.ts +0 -26
  144. package/dist/platform-expo/src/react.d.ts.map +0 -1
  145. package/dist/platform-expo/src/react.js +0 -30
  146. package/dist/platform-expo/src/react.js.map +0 -1
  147. package/dist/platform-node/src/index.d.ts +0 -145
  148. package/dist/platform-node/src/index.d.ts.map +0 -1
  149. package/dist/platform-node/src/index.js +0 -407
  150. package/dist/platform-node/src/index.js.map +0 -1
  151. package/dist/platform-node/src/ipc-react.d.ts +0 -25
  152. package/dist/platform-node/src/ipc-react.d.ts.map +0 -1
  153. package/dist/platform-node/src/ipc-react.js +0 -21
  154. package/dist/platform-node/src/ipc-react.js.map +0 -1
  155. package/dist/platform-node/src/ipc.d.ts +0 -76
  156. package/dist/platform-node/src/ipc.d.ts.map +0 -1
  157. package/dist/platform-node/src/ipc.js +0 -344
  158. package/dist/platform-node/src/ipc.js.map +0 -1
  159. package/dist/platform-web/src/index.d.ts +0 -106
  160. package/dist/platform-web/src/index.d.ts.map +0 -1
  161. package/dist/platform-web/src/index.js +0 -311
  162. package/dist/platform-web/src/index.js.map +0 -1
  163. package/dist/platform-web/src/indexeddb.js +0 -125
  164. package/dist/platform-web/src/indexeddb.js.map +0 -1
  165. package/dist/platform-web/src/opfs.js +0 -146
  166. package/dist/platform-web/src/opfs.js.map +0 -1
  167. package/dist/platform-web/src/persistence.d.ts +0 -20
  168. package/dist/platform-web/src/persistence.d.ts.map +0 -1
  169. package/dist/platform-web/src/persistence.js +0 -23
  170. package/dist/platform-web/src/persistence.js.map +0 -1
  171. package/dist/platform-web/src/react.d.ts +0 -35
  172. package/dist/platform-web/src/react.d.ts.map +0 -1
  173. package/dist/platform-web/src/react.js +0 -42
  174. package/dist/platform-web/src/react.js.map +0 -1
  175. package/dist/platform-web/src/sqljs.js +0 -133
  176. package/dist/platform-web/src/sqljs.js.map +0 -1
  177. package/dist/platform-web/src/worker.d.ts +0 -79
  178. package/dist/platform-web/src/worker.d.ts.map +0 -1
  179. package/dist/platform-web/src/worker.js +0 -308
  180. package/dist/platform-web/src/worker.js.map +0 -1
  181. package/dist/react/src/index.d.ts +0 -59
  182. package/dist/react/src/index.d.ts.map +0 -1
  183. package/dist/react/src/index.js +0 -151
  184. package/dist/react/src/index.js.map +0 -1
  185. package/dist/schema/src/definition.d.ts +0 -98
  186. package/dist/schema/src/definition.d.ts.map +0 -1
  187. package/dist/schema/src/definition.js +0 -84
  188. package/dist/schema/src/definition.js.map +0 -1
  189. package/dist/schema/src/planner.d.ts +0 -42
  190. package/dist/schema/src/planner.d.ts.map +0 -1
  191. package/dist/schema/src/planner.js +0 -131
  192. package/dist/schema/src/planner.js.map +0 -1
  193. package/dist/schema/src/validators.d.ts +0 -194
  194. package/dist/schema/src/validators.d.ts.map +0 -1
  195. package/dist/schema/src/validators.js +0 -158
  196. package/dist/schema/src/validators.js.map +0 -1
  197. package/dist/svelte/src/index.d.ts +0 -44
  198. package/dist/svelte/src/index.d.ts.map +0 -1
  199. package/dist/svelte/src/index.js +0 -75
  200. package/dist/svelte/src/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.mjs","names":[],"sources":["../src/app.ts"],"sourcesContent":["import { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { Command } from \"commander\";\nimport type { SyncoreDevtoolsSubscriptionResultPayload } from \"@syncore/devtools-protocol\";\nimport {\n createSchemaSnapshot,\n diffSchemaSnapshots,\n renderMigrationSql\n} from \"@syncore/core\";\nimport {\n type SyncoreTemplateName,\n VALID_SYNCORE_TEMPLATES,\n applyProjectMigrations,\n detectProjectTemplate,\n formatError,\n getNextMigrationNumber,\n hasSyncoreProject,\n isLocalPortInUse,\n loadProjectSchema,\n readStoredSnapshot,\n resolveRequestedTemplate,\n runCodegen,\n runDevProjectBootstrap,\n scaffoldProject,\n slugify,\n startDevHub,\n writeStoredSnapshot\n} from \"@syncore/core/cli\";\nimport { CliContext, type CliChoice, type GlobalCliOptions, openTarget } from \"./context.js\";\nimport { runShellCommand, printCompactDevPhase, printDevSessionIntro, withConsoleCapture } from \"./dev-session.js\";\nimport { buildDoctorReport } from \"./doctor.js\";\nimport { applyRootHelp } from \"./help.js\";\nimport {\n buildDevBootstrapNextSteps,\n buildInitNextSteps,\n buildTargetCommandNextSteps,\n buildHubUnavailableNextSteps,\n templateUsesConnectedClients\n} from \"./messages.js\";\nimport {\n buildRuntimeLookup,\n type ClientRuntimeLookupEntry,\n type ClientTargetDescriptor,\n type TargetCapability,\n connectToProjectHub,\n createPublicRuntimeId,\n createManagedProjectClient,\n exportProjectData,\n importProjectData,\n isKnownTemplate,\n listAvailableTargets,\n listConnectedClientTargets,\n listProjectTables,\n loadImportDocumentBatches,\n readProjectTable,\n resolveDashboardUrl,\n resolveDevtoolsUrl,\n resolveDocsTarget,\n resolveProjectFunction,\n targetSupportsCapability,\n writeExportData\n} from \"./project.js\";\nimport {\n type JsonLikeFormat,\n type PersistedLogEntry,\n printDevReadySummary,\n printDoctorReport,\n printTargetsTable,\n renderOutput\n} from \"./render.js\";\nimport { resolveClientRuntime, resolveOperationalTarget } from \"./targets.js\";\n\ninterface InitCommandOptions {\n template: SyncoreTemplateName | \"auto\";\n force?: boolean;\n}\n\ninterface DevCommandOptions {\n template: string;\n once?: boolean;\n openDashboard?: boolean;\n untilSuccess?: boolean;\n run?: string;\n runSh?: string;\n}\n\ninterface RunCommandOptions {\n watch?: boolean;\n format: JsonLikeFormat;\n target?: string;\n runtime?: string;\n}\n\ninterface DataCommandOptions {\n limit: string;\n order?: \"asc\" | \"desc\";\n format: JsonLikeFormat;\n target?: string;\n runtime?: string;\n watch?: boolean;\n}\n\ninterface ImportCommandOptions {\n table?: string;\n target?: string;\n runtime?: string;\n}\n\ninterface ExportCommandOptions {\n path: string;\n table?: string;\n target?: string;\n runtime?: string;\n}\n\ninterface LogsCommandOptions {\n target?: string;\n runtime?: string;\n limit: string;\n watch?: boolean;\n kind?: \"query\" | \"mutation\" | \"action\" | \"system\";\n format: JsonLikeFormat;\n}\n\ninterface TargetsCommandOptions {\n onlineOnly?: boolean;\n capability?: TargetCapability;\n}\n\ninterface OpenCommandOptions {\n open?: boolean;\n}\n\nexport async function runSyncoreCli(argv = process.argv): Promise<void> {\n const program = buildProgram();\n\n if (argv.length <= 2) {\n argv = [...argv, \"--help\"];\n }\n\n try {\n await program.parseAsync(argv);\n } catch (error) {\n const context = new CliContext(parseGlobalOptionsFromArgv(argv));\n context.handleError(error);\n }\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"syncorejs\")\n .usage(\"<command> [options]\")\n .option(\"--cwd <path>\", \"Run the command as if started from the given directory\")\n .option(\"--json\", \"Emit machine-readable JSON output\")\n .option(\"--verbose\", \"Print additional diagnostics\")\n .option(\"--no-interactive\", \"Disable prompts and terminal UX\")\n .option(\"-y, --yes\", \"Assume yes for confirmations\")\n .showHelpAfterError()\n .showSuggestionAfterError()\n .helpCommand(\"help <command>\", \"Show help for a command\");\n applyRootHelp(program);\n\n addInitCommand(program);\n addCodegenCommand(program);\n addDoctorCommand(program);\n addTargetsCommand(program);\n addDevCommand(program);\n addMigrateCommand(program);\n addRunCommand(program);\n addDataCommand(program);\n addImportCommand(program);\n addExportCommand(program);\n addLogsCommand(program);\n addDashboardCommand(program);\n addDocsCommand(program);\n\n return program;\n}\n\nfunction addInitCommand(program: Command): void {\n program\n .command(\"init\")\n .summary(\"Scaffold Syncore into the current project\")\n .description(\"Scaffold Syncore files, scripts, and generated types into the selected directory.\")\n .option(\n \"--template <template>\",\n `Template to scaffold (${VALID_SYNCORE_TEMPLATES.join(\", \")}, or auto)`,\n \"auto\"\n )\n .option(\"--force\", \"Overwrite Syncore-managed files\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs init\",\n \" npx syncorejs init --template react-web\",\n \" npx syncorejs init --cwd ./examples/my-app\"\n ].join(\"\\n\")\n )\n .action(async (options: InitCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (\n !options.force &&\n !(await isDirectoryEmpty(ctx.cwd)) &&\n !(await ctx.confirm(\n \"The target directory is not empty. Continue scaffolding into it?\",\n false\n ))\n ) {\n ctx.fail(\"Scaffolding cancelled by user.\", 1);\n }\n\n let template = options.template;\n if (template === \"auto\") {\n const detectedTemplate = await detectProjectTemplate(ctx.cwd);\n template =\n detectedTemplate === \"minimal\" && ctx.interactive\n ? await promptForTemplate(ctx, detectedTemplate)\n : detectedTemplate;\n }\n\n if (!isKnownTemplate(template)) {\n ctx.fail(\n `Unknown template ${JSON.stringify(template)}. Expected one of ${VALID_SYNCORE_TEMPLATES.join(\", \")} or auto.`\n );\n }\n const resolvedTemplate: SyncoreTemplateName = template;\n\n const result = await ctx.withSpinner(\"Scaffolding Syncore\", async () =>\n scaffoldProject(ctx.cwd, {\n template: resolvedTemplate,\n ...(options.force ? { force: true } : {})\n })\n );\n await ctx.withSpinner(\"Generating typed references\", async () =>\n runCodegen(ctx.cwd)\n );\n\n ctx.printResult({\n summary: `Syncore scaffolded with the ${resolvedTemplate} template.`,\n command: \"init\",\n data: result,\n nextSteps: buildInitNextSteps(resolvedTemplate)\n });\n\n if (!ctx.json) {\n printScaffoldChanges(ctx, result);\n }\n });\n });\n}\n\nfunction addCodegenCommand(program: Command): void {\n program\n .command(\"codegen\")\n .summary(\"Generate typed Syncore references\")\n .description(\"Regenerate syncore/_generated from the current syncore/functions tree.\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" npx syncorejs codegen\", \" npx syncorejs codegen --cwd ./apps/web\"].join(\n \"\\n\"\n )\n )\n .action(async (_options: Record<string, never>, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n await ctx.withSpinner(\"Generating typed references\", async () =>\n runCodegen(ctx.cwd)\n );\n ctx.printResult({\n summary: \"Generated syncore/_generated files.\",\n command: \"codegen\"\n });\n });\n });\n}\n\nfunction addDoctorCommand(program: Command): void {\n program\n .command(\"doctor\")\n .summary(\"Inspect the current Syncore project state\")\n .description(\"Check project structure, template capabilities, hub state, and available targets.\")\n .addHelpText(\n \"after\",\n [\"\", \"Examples:\", \" npx syncorejs doctor\", \" npx syncorejs doctor --json\"].join(\"\\n\")\n )\n .action(async (_options: Record<string, never>, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const report = await buildDoctorReport(ctx.cwd);\n if (ctx.json) {\n ctx.printResult({\n command: \"doctor\",\n data: report\n });\n return;\n }\n\n ctx.info(`Detected template: ${report.template}`);\n ctx.info(`Project status: ${report.status}`);\n ctx.info(\n `Project target: ${report.projectTarget ? report.projectTarget.databasePath : \"not configured\"}`\n );\n ctx.info(`Devtools hub: ${report.hub.running ? report.hub.url : \"not running\"}`);\n printDoctorReport(report, {\n verbose: ctx.verbose\n });\n if (report.workspaceMatches.length > 0) {\n ctx.warn(\"You appear to be at a workspace root instead of inside an app package.\");\n for (const match of report.workspaceMatches) {\n process.stdout.write(\n ` - ${match.relativePath} (${match.template}) -> use --cwd ${match.relativePath}\\n`\n );\n }\n }\n for (const suggestion of report.suggestions) {\n ctx.nextStep(suggestion);\n }\n });\n });\n}\n\nfunction addTargetsCommand(program: Command): void {\n program\n .command(\"targets\")\n .summary(\"List available Syncore targets\")\n .description(\"Inspect project and connected client targets for run, data, import, export, and logs.\")\n .option(\"--online-only\", \"Only show online targets\")\n .option(\n \"--capability <capability>\",\n \"Filter targets by capability: run, readData, writeData, exportData, streamLogs\"\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs targets\",\n \" npx syncorejs targets --capability run\",\n \" npx syncorejs targets --json\"\n ].join(\"\\n\")\n )\n .action(async (options: TargetsCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.capability && !isTargetCapability(options.capability)) {\n ctx.fail(\n `Unknown capability ${JSON.stringify(options.capability)}. Expected run, readData, writeData, exportData, or streamLogs.`\n );\n }\n const targets = await listAvailableTargets(ctx.cwd);\n const filtered = targets.filter((target) => {\n if (options.onlineOnly && !target.online) {\n return false;\n }\n if (options.capability && !targetSupportsCapability(target, options.capability)) {\n return false;\n }\n return true;\n });\n\n ctx.printResult({\n command: \"targets\",\n summary: `Found ${filtered.length} target(s).`,\n data: filtered,\n nextSteps: buildTargetCommandNextSteps(filtered[0]?.id)\n });\n\n if (!ctx.json) {\n printTargetsTable(filtered, {\n verbose: ctx.verbose\n });\n }\n });\n });\n}\n\nfunction addDevCommand(program: Command): void {\n program\n .command(\"dev\")\n .summary(\"Run the Syncore development loop\")\n .description(\n \"Bootstrap the local Syncore project, start the hub, discover targets, and keep the local workflow in sync.\"\n )\n .option(\n \"--template <template>\",\n `Template to scaffold when Syncore is missing (${VALID_SYNCORE_TEMPLATES.join(\", \")}, or auto)`,\n \"auto\"\n )\n .option(\"--once\", \"Run bootstrap once and exit\")\n .option(\"--until-success\", \"Retry bootstrap until it succeeds\")\n .option(\"--run <function>\", \"Run a Syncore function after bootstrap succeeds\")\n .option(\"--run-sh <command>\", \"Run a shell command after bootstrap succeeds\")\n .option(\"--open-dashboard\", \"Open the dashboard URL even in non-interactive mode\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs dev\",\n \" npx syncorejs dev --once\",\n \" npx syncorejs dev --until-success\",\n \" npx syncorejs dev --run tasks/list\",\n \" npx syncorejs dev --open-dashboard\",\n \" npx syncorejs dev --run-sh \\\"npm run dev\\\"\"\n ].join(\"\\n\")\n )\n .action(async (options: DevCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.run && options.runSh) {\n ctx.fail(\"`syncorejs dev` accepts either --run or --run-sh, not both.\");\n }\n const shouldOpenDashboard =\n Boolean(options.openDashboard) || isRealInteractiveTerminal(ctx);\n await ensureLocalPortConfiguration(ctx);\n\n const template = await resolveRequestedTemplate(ctx.cwd, options.template);\n printDevSessionIntro(ctx);\n await ensureDevProjectExists(ctx, template);\n\n if (options.once) {\n await runDevBootstrapLoop(ctx, template, options.untilSuccess ?? false);\n await runDevFollowup(ctx, options);\n const targets = await listAvailableTargets(ctx.cwd);\n ctx.printResult({\n summary: \"Syncore dev bootstrap completed.\",\n command: \"dev\",\n nextSteps: buildDevBootstrapNextSteps()\n });\n if (!ctx.json) {\n printDevReadySummary(ctx, {\n template,\n projectTargetConfigured: targets.some((target) => target.kind === \"project\"),\n dashboardUrl: resolveDashboardUrl(),\n devtoolsUrl: resolveDevtoolsUrl(),\n targets\n });\n }\n return;\n }\n\n await runDevBootstrapLoop(ctx, template, options.untilSuccess ?? false);\n const targets = await listAvailableTargets(ctx.cwd);\n printDevReadySummary(ctx, {\n template,\n projectTargetConfigured: targets.some((target) => target.kind === \"project\"),\n dashboardUrl: resolveDashboardUrl(),\n devtoolsUrl: resolveDevtoolsUrl(),\n targets\n });\n\n await startManagedDevHub(ctx, template);\n await maybeOpenDashboard(ctx, shouldOpenDashboard);\n await monitorLiveDevSession(ctx, template);\n });\n });\n}\n\nfunction isRealInteractiveTerminal(context: CliContext): boolean {\n return context.interactive && Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nasync function maybeOpenDashboard(\n context: CliContext,\n shouldOpenDashboard: boolean\n): Promise<void> {\n if (!shouldOpenDashboard) {\n return;\n }\n const opened = await openTarget(resolveDashboardUrl());\n if (opened) {\n context.info(`Opened dashboard at ${resolveDashboardUrl()}.`);\n return;\n }\n context.warn(\"Unable to open the dashboard automatically.\");\n}\n\nfunction addMigrateCommand(program: Command): void {\n const migrate = program\n .command(\"migrate\")\n .summary(\"Generate and apply local SQL migrations\")\n .description(\"Work with schema diffs, migration SQL, and the local Syncore database.\");\n\n migrate\n .command(\"status\")\n .summary(\"Show the current schema diff status\")\n .action(async (_options: Record<string, never>, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const schema = await loadProjectSchema(ctx.cwd);\n const currentSnapshot = createSchemaSnapshot(schema);\n const storedSnapshot = await readStoredSnapshot(ctx.cwd);\n const plan = diffSchemaSnapshots(storedSnapshot, currentSnapshot);\n\n ctx.printResult({\n summary: \"Migration status computed.\",\n command: \"migrate status\",\n data: {\n currentSchemaHash: currentSnapshot.hash,\n storedSchemaHash: storedSnapshot?.hash ?? null,\n statements: plan.statements,\n warnings: plan.warnings,\n destructiveChanges: plan.destructiveChanges\n }\n });\n\n if (!ctx.json) {\n process.stdout.write(`Current schema hash: ${currentSnapshot.hash}\\n`);\n process.stdout.write(`Stored snapshot: ${storedSnapshot?.hash ?? \"none\"}\\n`);\n process.stdout.write(`Statements to generate: ${plan.statements.length}\\n`);\n process.stdout.write(`Warnings: ${plan.warnings.length}\\n`);\n process.stdout.write(`Destructive changes: ${plan.destructiveChanges.length}\\n`);\n for (const warning of plan.warnings) {\n ctx.warn(warning);\n }\n for (const change of plan.destructiveChanges) {\n ctx.error(change);\n }\n }\n });\n });\n\n migrate\n .command(\"generate\")\n .argument(\"[name]\", \"Optional migration name\", \"auto\")\n .summary(\"Generate a SQL migration from the current schema diff\")\n .action(\n async (name: string, _options: Record<string, never>, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const schema = await loadProjectSchema(ctx.cwd);\n const currentSnapshot = createSchemaSnapshot(schema);\n const storedSnapshot = await readStoredSnapshot(ctx.cwd);\n const plan = diffSchemaSnapshots(storedSnapshot, currentSnapshot);\n\n if (plan.destructiveChanges.length > 0) {\n ctx.fail(\n `Destructive schema changes require a manual migration: ${plan.destructiveChanges.join(\"; \")}`\n );\n }\n if (plan.statements.length === 0 && plan.warnings.length === 0) {\n ctx.printResult({\n summary: \"No schema changes detected.\"\n });\n return;\n }\n\n const migrationsDirectory = path.join(ctx.cwd, \"syncore\", \"migrations\");\n await mkdir(migrationsDirectory, { recursive: true });\n const migrationNumber = await getNextMigrationNumber(migrationsDirectory);\n const slug = slugify(name);\n const fileName = `${String(migrationNumber).padStart(4, \"0\")}_${slug}.sql`;\n const migrationSql = renderMigrationSql(plan, {\n title: `Syncore migration ${fileName}`\n });\n await writeFile(path.join(migrationsDirectory, fileName), migrationSql);\n await writeStoredSnapshot(ctx.cwd, currentSnapshot);\n\n ctx.printResult({\n summary: `Generated syncore/migrations/${fileName}.`,\n command: \"migrate generate\",\n data: {\n path: path.join(\"syncore\", \"migrations\", fileName),\n statements: plan.statements,\n warnings: plan.warnings\n },\n nextSteps: [\"Run `npx syncorejs migrate apply` to apply pending migrations.\"]\n });\n });\n }\n );\n\n migrate\n .command(\"apply\")\n .summary(\"Apply SQL migrations to the local database\")\n .action(async (_options: Record<string, never>, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const appliedCount = await ctx.withSpinner(\"Applying migrations\", async () =>\n applyProjectMigrations(ctx.cwd)\n );\n ctx.printResult({\n summary: `Applied ${appliedCount} migration(s).`,\n command: \"migrate apply\"\n });\n });\n });\n}\n\nfunction addRunCommand(program: Command): void {\n program\n .command(\"run\")\n .summary(\"Run a local Syncore function\")\n .description(\"Execute a query, mutation, or action against the local runtime.\")\n .argument(\"<functionName>\", \"Function name like tasks/list or api.tasks.list\")\n .argument(\"[args]\", \"JSON object of arguments\", \"{}\")\n .option(\"--watch\", \"Watch a query for local changes\")\n .option(\"--target <target>\", \"Target id: project or a 5-digit client target id\")\n .option(\"--runtime <runtime>\", \"Runtime id inside the selected client target\")\n .option(\n \"--format <format>\",\n \"Output format: pretty, json, or jsonl\",\n \"pretty\"\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs run tasks/list\",\n \" npx syncorejs run api.tasks.create '{\\\"text\\\":\\\"Ship Syncore\\\"}' --target project\",\n \" npx syncorejs run tasks/list --watch --target 10427 --runtime 20318 --format json\"\n ].join(\"\\n\")\n )\n .action(\n async (\n functionName: string,\n argsText: string,\n options: RunCommandOptions,\n command: Command\n ) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.runtime && !options.target) {\n ctx.fail(\"`syncorejs run --runtime` requires --target.\");\n }\n const resolved = await resolveProjectFunction(ctx.cwd, functionName);\n const args = parseJsonObject(argsText, \"Function arguments\");\n\n if (options.watch && resolved.definition.kind !== \"query\") {\n ctx.fail(\"`syncorejs run --watch` only supports query functions.\");\n }\n\n const target = await resolveOperationalTarget(ctx, options.target, {\n command: \"run\",\n capability: \"run\"\n });\n const runtime = resolveClientRuntime(target, options.runtime, {\n command: \"run\"\n });\n ctx.info(\n options.watch\n ? `Watching ${resolved.name} on ${target.id}${runtime ? ` (${runtime.id} ${runtime.label})` : \"\"}.`\n : `Running ${resolved.name} on ${target.id}${runtime ? ` (${runtime.id} ${runtime.label})` : \"\"}.`\n );\n if (target.kind === \"project\") {\n const managed = await createManagedProjectClient(ctx.cwd);\n try {\n if (options.watch) {\n const watch = managed.client.watchQuery(\n resolved.reference as never,\n args\n );\n const render = () => {\n const error = watch.localQueryError();\n if (error) {\n ctx.handleError(error);\n return;\n }\n renderOutput(ctx, watch.localQueryResult(), options.format);\n };\n const unsubscribe = watch.onUpdate(render);\n ctx.info(\"Watching query. Press Ctrl+C to stop.\");\n await waitForSignal();\n unsubscribe();\n watch.dispose?.();\n return;\n }\n\n const result =\n resolved.definition.kind === \"query\"\n ? await managed.client.query(resolved.reference as never, args)\n : resolved.definition.kind === \"mutation\"\n ? await managed.client.mutation(\n resolved.reference as never,\n args\n )\n : await managed.client.action(resolved.reference as never, args);\n\n renderOutput(ctx, result, options.format);\n return;\n } finally {\n await managed.dispose();\n }\n }\n\n const hub = await requireHubConnection(ctx);\n try {\n if (options.watch) {\n const unsubscribe = hub.subscribe(runtime!.runtimeId, {\n kind: \"fn.watch\",\n functionName: resolved.name,\n functionType: \"query\",\n args\n }, {\n onData(payload) {\n if (payload.kind !== \"fn.watch.result\") {\n return;\n }\n if (payload.error) {\n ctx.handleError(new Error(payload.error));\n return;\n }\n renderOutput(ctx, payload.result, options.format);\n },\n onError(error) {\n ctx.handleError(new Error(error));\n }\n });\n ctx.info(`Watching query on ${target.id}. Press Ctrl+C to stop.`);\n await waitForSignal();\n unsubscribe();\n return;\n }\n\n const result = await hub.sendCommand(runtime!.runtimeId, {\n kind: \"fn.run\",\n functionName: resolved.name,\n functionType: resolved.definition.kind,\n args\n });\n if (result.kind === \"fn.run.result\") {\n if (result.error) {\n ctx.fail(result.error);\n }\n renderOutput(ctx, result.result, options.format);\n return;\n }\n if (result.kind === \"error\") {\n ctx.fail(result.message, 1, result);\n }\n ctx.fail(`Unexpected response from ${target.id}.`, 1, result);\n } finally {\n await hub.dispose();\n }\n });\n }\n );\n}\n\nfunction addDataCommand(program: Command): void {\n program\n .command(\"data\")\n .summary(\"Inspect local Syncore data\")\n .description(\"List tables or print local rows from a specific table.\")\n .argument(\"[table]\", \"Optional table to inspect\")\n .option(\"--target <target>\", \"Target id: project or a 5-digit client target id\")\n .option(\"--runtime <runtime>\", \"Runtime id inside the selected client target\")\n .option(\"--limit <n>\", \"Maximum rows to print\", \"100\")\n .option(\"--order <choice>\", \"Order by _creationTime\", \"desc\")\n .option(\"--watch\", \"Watch a table for changes on the selected target\")\n .option(\n \"--format <format>\",\n \"Output format: pretty, json, or jsonl\",\n \"pretty\"\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs data\",\n \" npx syncorejs data tasks --target project --limit 10\",\n \" npx syncorejs data tasks --target 10427 --runtime 20318 --watch --format jsonl\"\n ].join(\"\\n\")\n )\n .action(\n async (\n table: string | undefined,\n options: DataCommandOptions,\n command: Command\n ) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.runtime && !options.target) {\n ctx.fail(\"`syncorejs data --runtime` requires --target.\");\n }\n const target = await resolveOperationalTarget(ctx, options.target, {\n command: \"data\",\n capability: \"readData\"\n });\n const runtime = resolveClientRuntime(target, options.runtime, {\n command: \"data\"\n });\n if (!table) {\n const tables =\n target.kind === \"project\"\n ? await listProjectTables(ctx.cwd)\n : await listRemoteTables(runtime!.runtimeId, ctx);\n ctx.printResult({\n summary: `Found ${tables.length} table(s) on ${target.id}.`,\n command: \"data\",\n data: tables,\n target: target.id\n });\n if (!ctx.json) {\n for (const entry of tables) {\n process.stdout.write(\n ` ${entry.name} (${entry.documentCount} document(s))\\n`\n );\n }\n }\n return;\n }\n\n if (target.kind === \"project\") {\n const payload = await readProjectTable(ctx.cwd, table, {\n limit: Number.parseInt(options.limit, 10),\n order: options.order === \"asc\" ? \"asc\" : \"desc\"\n });\n renderOutput(ctx, payload.rows, options.format);\n return;\n }\n\n const hub = await requireHubConnection(ctx);\n try {\n const payload = await readRemoteTable(hub, runtime!.runtimeId, table, {\n limit: Number.parseInt(options.limit, 10)\n });\n renderOutput(ctx, payload.rows, options.format);\n\n if (!options.watch) {\n return;\n }\n\n const unsubscribe = hub.subscribe(runtime!.runtimeId, {\n kind: \"data.table\",\n table,\n limit: Number.parseInt(options.limit, 10)\n }, {\n onData(result) {\n if (result.kind !== \"data.table.result\") {\n return;\n }\n renderOutput(ctx, result.rows, options.format);\n },\n onError(error) {\n ctx.handleError(new Error(error));\n }\n });\n ctx.info(\n `Watching table ${table} on ${target.id} (${runtime!.id} ${runtime!.label}). Press Ctrl+C to stop.`\n );\n await waitForSignal();\n unsubscribe();\n } finally {\n await hub.dispose();\n }\n });\n }\n );\n}\n\nfunction addImportCommand(program: Command): void {\n program\n .command(\"import\")\n .summary(\"Import local data into Syncore\")\n .description(\"Import JSON, JSONL, directory, or ZIP data into the local Syncore database.\")\n .argument(\"<path>\", \"Path to a .json, .jsonl, directory, or .zip input\")\n .option(\"--table <table>\", \"Destination table for single-file imports\")\n .option(\"--target <target>\", \"Target id: project or a 5-digit client target id\")\n .option(\"--runtime <runtime>\", \"Runtime id inside the selected client target\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs import --table tasks sample.jsonl --target project\",\n \" npx syncorejs import --table tasks sample.json --target 10427 --runtime 20318\",\n \" npx syncorejs import backups/export.zip\"\n ].join(\"\\n\")\n )\n .action(\n async (\n sourcePath: string,\n options: ImportCommandOptions,\n command: Command\n ) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.runtime && !options.target) {\n ctx.fail(\"`syncorejs import --runtime` requires --target.\");\n }\n const target = await resolveOperationalTarget(ctx, options.target, {\n command: \"import\",\n capability: \"writeData\"\n });\n const runtime = resolveClientRuntime(target, options.runtime, {\n command: \"import\"\n });\n const preview = await previewImportPlan(ctx, sourcePath, options, target.id);\n if (\n ctx.interactive &&\n !(await ctx.confirm(\n `Import ${preview.totalRows} row(s) into ${target.id}?`,\n true\n ))\n ) {\n ctx.fail(\"Import cancelled by user.\");\n }\n const imported =\n target.kind === \"project\"\n ? await ctx.withSpinner(\"Importing local data\", async () =>\n importProjectData(ctx.cwd, sourcePath, {\n ...(options.table ? { table: options.table } : {})\n })\n )\n : await ctx.withSpinner(`Importing data into ${target.id}`, async () =>\n importIntoClientTarget(ctx, target, runtime!, sourcePath, options)\n );\n ctx.printResult({\n summary: `Imported ${imported.reduce((sum, entry) => sum + entry.importedCount, 0)} row(s).`,\n command: \"import\",\n data: imported,\n target: target.id\n });\n if (!ctx.json) {\n for (const entry of imported) {\n process.stdout.write(\n ` ${entry.table}: ${entry.importedCount} row(s)\\n`\n );\n }\n }\n });\n }\n );\n}\n\nfunction addExportCommand(program: Command): void {\n program\n .command(\"export\")\n .summary(\"Export local Syncore data\")\n .description(\"Export one or more local tables to JSON, JSONL, a directory, or a ZIP file.\")\n .requiredOption(\"--path <path>\", \"Output path (.json, .jsonl, directory, or .zip)\")\n .option(\"--table <table>\", \"Export a single table\")\n .option(\"--target <target>\", \"Target id: project or a 5-digit client target id\")\n .option(\"--runtime <runtime>\", \"Runtime id inside the selected client target\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs export --table tasks --path tasks.jsonl --target project\",\n \" npx syncorejs export --path ./exports --target 10427 --runtime 20318\",\n \" npx syncorejs export --path ./exports.zip\"\n ].join(\"\\n\")\n )\n .action(async (options: ExportCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.runtime && !options.target) {\n ctx.fail(\"`syncorejs export --runtime` requires --target.\");\n }\n const target = await resolveOperationalTarget(ctx, options.target, {\n command: \"export\",\n capability: \"exportData\"\n });\n const runtime = resolveClientRuntime(target, options.runtime, {\n command: \"export\"\n });\n const result =\n target.kind === \"project\"\n ? await ctx.withSpinner(\"Exporting local data\", async () =>\n exportProjectData(ctx.cwd, options.path, {\n ...(options.table ? { table: options.table } : {})\n })\n )\n : await ctx.withSpinner(`Exporting data from ${target.id}`, async () =>\n exportClientTargetData(ctx, target, runtime!, options)\n );\n ctx.printResult({\n summary: `Exported ${result.tables.length} table(s) to ${result.path}.`,\n command: \"export\",\n data: result,\n target: target.id\n });\n });\n });\n}\n\nfunction addLogsCommand(program: Command): void {\n program\n .command(\"logs\")\n .summary(\"Inspect Syncore runtime logs\")\n .description(\"Read persisted hub logs and optionally watch live runtime events.\")\n .option(\"--target <target>\", \"Target id, or all\", \"all\")\n .option(\"--runtime <runtime>\", \"Runtime id inside the selected client target\")\n .option(\"--limit <n>\", \"Maximum log lines to print\", \"100\")\n .option(\"--watch\", \"Stream new logs from the local devtools hub\")\n .option(\"--kind <kind>\", \"Filter by event kind: query, mutation, action, system\")\n .option(\"--format <format>\", \"Output format: pretty, json, or jsonl\", \"pretty\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" npx syncorejs logs\",\n \" npx syncorejs logs --target 10427 --runtime 20318 --watch\",\n \" npx syncorejs logs --kind mutation --format jsonl\"\n ].join(\"\\n\")\n )\n .action(async (options: LogsCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n if (options.runtime && (!options.target || options.target === \"all\")) {\n ctx.fail(\"`syncorejs logs --runtime` requires a specific --target.\");\n }\n await runLogsCommand(ctx, options);\n });\n });\n}\n\nfunction addDashboardCommand(program: Command): void {\n program\n .command(\"dashboard\")\n .summary(\"Print or open the local dashboard URL\")\n .description(\"Show the local Syncore dashboard URL, optionally opening it in the browser.\")\n .option(\"--open\", \"Open the dashboard URL\")\n .action(async (options: OpenCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const url = resolveDashboardUrl();\n if (options.open) {\n const opened = await openTarget(url);\n if (!opened) {\n ctx.warn(\"Unable to open the dashboard automatically.\");\n }\n }\n ctx.printResult({\n summary: \"Dashboard URL resolved.\",\n command: \"dashboard\",\n data: { url },\n nextSteps: [`Open ${url}`]\n });\n });\n });\n}\n\nfunction addDocsCommand(program: Command): void {\n program\n .command(\"docs\")\n .summary(\"Print or open the most relevant Syncore docs\")\n .description(\"Resolve the best local docs target for the detected template and optionally open it.\")\n .option(\"--open\", \"Open the docs target\")\n .action(async (options: OpenCommandOptions, command: Command) => {\n const ctx = createContext(command);\n await executeCommand(ctx, async () => {\n const url = await resolveDocsTarget(ctx.cwd);\n if (options.open) {\n const opened = await openTarget(url);\n if (!opened) {\n ctx.warn(\"Unable to open the docs target automatically.\");\n }\n }\n ctx.printResult({\n summary: \"Docs target resolved.\",\n command: \"docs\",\n data: { url }\n });\n });\n });\n}\n\nfunction createContext(command: Command): CliContext {\n const options = command.optsWithGlobals<GlobalCliOptions>();\n return new CliContext(options);\n}\n\nasync function executeCommand(\n context: CliContext,\n action: () => Promise<void>\n): Promise<void> {\n try {\n await action();\n } catch (error) {\n context.handleError(error);\n }\n}\n\nasync function ensureDevProjectExists(\n context: CliContext,\n template: SyncoreTemplateName\n): Promise<void> {\n if (await hasSyncoreProject(context.cwd)) {\n return;\n }\n\n if (!context.interactive) {\n context.fail(\n \"No Syncore project was found in this directory. Run `npx syncorejs init` first or rerun in an interactive terminal.\"\n );\n }\n\n const shouldScaffold = await context.confirm(\n \"No Syncore project was found. Scaffold one now?\",\n true\n );\n if (!shouldScaffold) {\n context.fail(\"Syncore dev cancelled because no project exists.\");\n }\n\n const result = await context.withSpinner(\"Scaffolding Syncore\", async () =>\n scaffoldProject(context.cwd, {\n template\n })\n );\n if (!context.json) {\n printScaffoldChanges(context, result);\n }\n}\n\ntype ConnectedHub = NonNullable<Awaited<ReturnType<typeof connectToProjectHub>>>;\n\nasync function ensureLocalPortConfiguration(context: CliContext): Promise<void> {\n const dashboardUrl = resolveDashboardUrl();\n const devtoolsUrl = resolveDevtoolsUrl();\n const dashboardPort = Number.parseInt(new URL(dashboardUrl).port, 10);\n const devtoolsPort = Number.parseInt(new URL(devtoolsUrl).port, 10);\n\n if (\n Number.isFinite(dashboardPort) &&\n Number.isFinite(devtoolsPort) &&\n dashboardPort === devtoolsPort\n ) {\n context.fail(\n [\n `Dashboard and devtools cannot share the same port (${dashboardPort}).`,\n \"Set different values for SYNCORE_DASHBOARD_PORT and SYNCORE_DEVTOOLS_PORT, then rerun `npx syncorejs dev`.\"\n ].join(\" \")\n );\n }\n\n if (\n Number.isFinite(dashboardPort) &&\n dashboardPort > 0 &&\n Number.isFinite(devtoolsPort) &&\n devtoolsPort > 0 &&\n (await isLocalPortInUse(dashboardPort)) &&\n !(await isLocalPortInUse(devtoolsPort))\n ) {\n context.warn(\n `Dashboard port ${dashboardPort} is already in use. If Syncore does not start cleanly, set SYNCORE_DASHBOARD_PORT to a different value.`\n );\n }\n}\n\nasync function runDevBootstrapLoop(\n context: CliContext,\n template: SyncoreTemplateName,\n untilSuccess: boolean\n): Promise<void> {\n while (true) {\n try {\n printCompactDevPhase(context, \"Project\");\n printCompactDevPhase(context, \"Codegen\");\n printCompactDevPhase(context, \"Schema\");\n await withConsoleCapture(\n (method, message) => {\n if (/destructive schema changes/i.test(message)) {\n context.error(\"Syncore dev blocked by destructive schema changes.\");\n return;\n }\n if (/Syncore dev warning:/i.test(message) || method === \"warn\") {\n context.warn(message.replace(/^Syncore dev warning:\\s*/i, \"\"));\n return;\n }\n if (/bootstrap failed/i.test(message) || method === \"error\") {\n context.error(message);\n }\n },\n async () => runDevProjectBootstrap(context.cwd, template)\n );\n return;\n } catch (error) {\n if (!untilSuccess) {\n throw error;\n }\n context.warn(`Syncore dev bootstrap failed, retrying: ${formatError(error)}`);\n await new Promise((resolve) => setTimeout(resolve, 1200));\n }\n }\n}\n\nasync function startManagedDevHub(\n context: CliContext,\n template: SyncoreTemplateName\n): Promise<void> {\n printCompactDevPhase(context, \"Hub\");\n printCompactDevPhase(context, \"Targets\");\n await withConsoleCapture(\n (method, message) => {\n if (/already running/i.test(message)) {\n context.info(message.replaceAll(\"127.0.0.1\", \"localhost\"));\n return;\n }\n if (/Dashboard shell:/i.test(message) || /devtools hub:/i.test(message)) {\n return;\n }\n if (/Watching syncore\\//i.test(message)) {\n context.info(\"Watching syncore/ for changes.\");\n return;\n }\n if (/runtime\\.disconnected/i.test(message)) {\n context.warn(message);\n return;\n }\n if (method === \"warn\") {\n context.warn(message);\n return;\n }\n if (method === \"error\") {\n context.error(message);\n }\n },\n async () =>\n startDevHub({\n cwd: context.cwd,\n template\n })\n );\n}\n\nasync function runDevFollowup(\n context: CliContext,\n options: DevCommandOptions\n): Promise<void> {\n if (options.run) {\n const target = await resolveOperationalTarget(context, undefined, {\n command: \"run\",\n capability: \"run\"\n });\n const resolved = await resolveProjectFunction(context.cwd, options.run);\n if (target.kind === \"project\") {\n const managed = await createManagedProjectClient(context.cwd);\n try {\n const result =\n resolved.definition.kind === \"query\"\n ? await managed.client.query(resolved.reference as never, {})\n : resolved.definition.kind === \"mutation\"\n ? await managed.client.mutation(resolved.reference as never, {})\n : await managed.client.action(resolved.reference as never, {});\n renderOutput(context, result, \"pretty\");\n } finally {\n await managed.dispose();\n }\n } else {\n const hub = await requireHubConnection(context);\n try {\n const result =\n await hub.sendCommand(target.runtimeId, {\n kind: \"fn.run\",\n functionName: resolved.name,\n functionType: resolved.definition.kind,\n args: {}\n });\n if (result.kind !== \"fn.run.result\") {\n context.fail(`Unexpected response from ${target.id}.`, 1, result);\n }\n if (result.error) {\n context.fail(result.error, 1, result);\n }\n renderOutput(context, result.result, \"pretty\");\n } finally {\n await hub.dispose();\n }\n }\n }\n\n if (options.runSh) {\n await runShellCommand(context, options.runSh);\n }\n}\n\nasync function monitorLiveDevSession(\n context: CliContext,\n template: SyncoreTemplateName\n): Promise<void> {\n if (!templateUsesConnectedClients(template)) {\n await waitForSignal();\n return;\n }\n\n let knownTargets = new Set<string>();\n let waitingNoticeVisible = false;\n const refreshTargets = async () => {\n const nextTargets = await listConnectedClientTargets();\n const nextIds = new Set(nextTargets.map((target) => target.id));\n\n for (const target of nextTargets) {\n if (!knownTargets.has(target.id)) {\n context.info(`Client target connected: ${target.id}`);\n }\n }\n for (const targetId of knownTargets) {\n if (!nextIds.has(targetId)) {\n context.warn(`Client target disconnected: ${targetId}`);\n }\n }\n\n if (nextTargets.length === 0 && !waitingNoticeVisible) {\n context.info(\"Hub ready. Start your app to connect a client target.\");\n waitingNoticeVisible = true;\n } else if (nextTargets.length > 0) {\n waitingNoticeVisible = false;\n }\n\n knownTargets = nextIds;\n };\n\n await refreshTargets();\n const interval = setInterval(() => {\n void refreshTargets();\n }, 1500);\n\n try {\n await waitForSignal();\n } finally {\n clearInterval(interval);\n }\n}\n\nasync function requireHubConnection(context: CliContext): Promise<ConnectedHub> {\n const hub = await connectToProjectHub();\n if (!hub) {\n context.fail(\n \"The local devtools hub is not running.\",\n 1,\n undefined,\n {\n category: \"hub\",\n nextSteps: buildHubUnavailableNextSteps()\n }\n );\n }\n return hub;\n}\n\nasync function listRemoteTables(\n runtimeId: string,\n context: CliContext\n): Promise<Array<{ name: string; documentCount: number }>> {\n const hub = await requireHubConnection(context);\n try {\n const result = await subscribeOnce(hub, runtimeId, {\n kind: \"schema.tables\"\n });\n if (result.kind !== \"schema.tables.result\") {\n context.fail(\"Unexpected response while listing remote tables.\", 1, result);\n }\n return result.tables.map((table) => ({\n name: table.name,\n documentCount: table.documentCount\n }));\n } finally {\n await hub.dispose();\n }\n}\n\nasync function readRemoteTable(\n hub: ConnectedHub,\n runtimeId: string,\n table: string,\n options: {\n limit: number;\n }\n): Promise<Extract<\n Awaited<ReturnType<typeof subscribeOnce>>,\n { kind: \"data.table.result\" }\n>> {\n const result = await subscribeOnce(hub, runtimeId, {\n kind: \"data.table\",\n table,\n limit: options.limit\n });\n if (result.kind !== \"data.table.result\") {\n throw new Error(`Unexpected response while reading table ${table}.`);\n }\n return result;\n}\n\nasync function importIntoClientTarget(\n context: CliContext,\n target: ClientTargetDescriptor,\n runtime: ClientTargetDescriptor[\"runtimes\"][number],\n sourcePath: string,\n options: ImportCommandOptions\n): Promise<Array<{ table: string; importedCount: number }>> {\n const batches = await loadImportDocumentBatches(context.cwd, sourcePath, {\n ...(options.table ? { table: options.table } : {})\n });\n const hub = await requireHubConnection(context);\n try {\n const results: Array<{ table: string; importedCount: number }> = [];\n for (const batch of batches) {\n let importedCount = 0;\n for (const row of batch.rows) {\n const payload = { ...row };\n delete payload._id;\n delete payload._creationTime;\n const result = await hub.sendCommand(runtime.runtimeId, {\n kind: \"data.insert\",\n table: batch.table,\n document: payload\n });\n if (result.kind !== \"data.mutate.result\" || !result.success) {\n const message =\n result.kind === \"data.mutate.result\"\n ? result.error ?? `Failed to import into ${batch.table}.`\n : `Unexpected response while importing into ${batch.table}.`;\n context.fail(message, 1, result);\n }\n importedCount += 1;\n }\n results.push({\n table: batch.table,\n importedCount\n });\n }\n return results;\n } finally {\n await hub.dispose();\n }\n}\n\nasync function exportClientTargetData(\n context: CliContext,\n target: ClientTargetDescriptor,\n runtime: ClientTargetDescriptor[\"runtimes\"][number],\n options: ExportCommandOptions\n): Promise<{\n path: string;\n tables: string[];\n format: \"json\" | \"jsonl\" | \"directory\" | \"zip\";\n}> {\n const hub = await requireHubConnection(context);\n try {\n const tables = options.table\n ? [options.table]\n : (await listRemoteTables(runtime.runtimeId, context)).map(\n (entry: { name: string }) => entry.name\n );\n const payloads = await Promise.all(\n tables.map(async (table) => ({\n table,\n rows: (await readRemoteTable(hub, runtime.runtimeId, table, {\n limit: Number.MAX_SAFE_INTEGER\n })).rows\n }))\n );\n return await writeExportData(path.resolve(context.cwd, options.path), payloads);\n } finally {\n await hub.dispose();\n }\n}\n\nasync function runLogsCommand(\n context: CliContext,\n options: LogsCommandOptions\n): Promise<void> {\n const availableTargets = await listAvailableTargets(context.cwd);\n const runtimeLookup = buildRuntimeLookup(availableTargets);\n const selectedTarget =\n options.target && options.target !== \"all\"\n ? availableTargets.find((target) => target.id === options.target)\n : undefined;\n if (options.target && options.target !== \"all\" && !selectedTarget) {\n context.fail(\n `Unknown target ${JSON.stringify(options.target)}. Available targets: ${availableTargets.map((target) => target.id).join(\", \")}`\n );\n }\n const selectedRuntime = selectedTarget\n ? resolveClientRuntime(selectedTarget, options.runtime, {\n command: \"logs\"\n })\n : null;\n const allowedRuntimeIds =\n selectedTarget?.kind === \"client\" ? new Set(selectedTarget.runtimeIds) : undefined;\n const entries = await readPersistedLogs(context.cwd);\n const filtered = entries\n .map((entry) => decoratePersistedLogEntry(entry, runtimeLookup))\n .filter((entry) =>\n options.target && options.target !== \"all\"\n ? entry.targetId === options.target ||\n (allowedRuntimeIds ? allowedRuntimeIds.has(entry.runtimeId) : false)\n : true\n )\n .filter((entry) =>\n selectedRuntime ? entry.runtimeId === selectedRuntime.runtimeId : true\n )\n .filter((entry) => (options.kind ? entry.category === options.kind : true))\n .slice(-Number.parseInt(options.limit, 10));\n\n renderOutput(context, filtered, options.format);\n\n if (!options.watch) {\n return;\n }\n\n const hub = await requireHubConnection(context);\n const unsubscribe = hub.onEvent((event) => {\n const entry = normalizeRuntimeEvent(\n event,\n runtimeLookup.get(event.runtimeId)\n );\n if (!entry) {\n return;\n }\n if (\n options.target &&\n options.target !== \"all\" &&\n entry.targetId !== options.target &&\n !(allowedRuntimeIds ? allowedRuntimeIds.has(entry.runtimeId) : false)\n ) {\n return;\n }\n if (options.kind && entry.category !== options.kind) {\n return;\n }\n if (selectedRuntime && entry.runtimeId !== selectedRuntime.runtimeId) {\n return;\n }\n renderOutput(context, entry, options.format);\n });\n context.info(\"Streaming logs. Press Ctrl+C to stop.\");\n await waitForSignal();\n unsubscribe();\n await hub.dispose();\n}\n\nasync function readPersistedLogs(cwd: string): Promise<PersistedLogEntry[]> {\n const logPath = path.join(cwd, \".syncore\", \"logs\", \"runtime.jsonl\");\n try {\n await stat(logPath);\n } catch {\n return [];\n }\n\n const source = await readFile(logPath, \"utf8\");\n return source\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => JSON.parse(line) as PersistedLogEntry)\n .filter((entry) => entry.version === 2)\n .filter((entry) => !shouldSuppressLogEntry(entry));\n}\n\nfunction normalizeRuntimeEvent(\n event: Record<string, unknown> & { type: string; runtimeId: string; timestamp: number },\n runtimeEntry?: ClientRuntimeLookupEntry\n): PersistedLogEntry | null {\n const functionName =\n typeof event.functionName === \"string\" ? event.functionName : \"unknown\";\n const logMessage =\n typeof event.message === \"string\" ? event.message : \"Syncore log\";\n const resolvedTargetId =\n event.runtimeId === \"syncore-dev-hub\"\n ? \"all\"\n : (runtimeEntry?.targetId ?? event.runtimeId);\n const runtimeLabel =\n event.runtimeId === \"syncore-dev-hub\"\n ? \"dashboard\"\n : (runtimeEntry?.label ?? \"runtime\");\n const publicRuntimeId =\n event.runtimeId === \"syncore-dev-hub\"\n ? undefined\n : (runtimeEntry?.id ?? createPublicRuntimeId(event.runtimeId));\n const targetLabel = runtimeEntry?.targetLabel;\n const origin =\n event.origin === \"dashboard\" || event.runtimeId === \"syncore-dev-hub\"\n ? \"dashboard\"\n : \"runtime\";\n const entryBase = {\n timestamp: event.timestamp,\n runtimeId: event.runtimeId,\n targetId: resolvedTargetId,\n ...(targetLabel ? { targetLabel } : {}),\n ...(publicRuntimeId ? { publicRuntimeId } : {}),\n ...(runtimeLabel ? { runtimeLabel } : {}),\n origin\n } satisfies Pick<\n PersistedLogEntry,\n | \"timestamp\"\n | \"runtimeId\"\n | \"targetId\"\n | \"targetLabel\"\n | \"publicRuntimeId\"\n | \"runtimeLabel\"\n | \"origin\"\n >;\n\n if (\n event.type === \"log\" &&\n shouldSuppressLogEntry({\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: logMessage,\n event\n })\n ) {\n return null;\n }\n\n switch (event.type) {\n case \"query.executed\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"query\",\n message: `${functionName} executed`,\n event\n };\n case \"query.invalidated\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: `${formatInvalidatedQueryId(event.queryId)} invalidated${typeof event.reason === \"string\" ? ` (${event.reason})` : \"\"}`,\n event\n };\n case \"mutation.committed\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"mutation\",\n message:\n Array.isArray(event.changedTables) && event.changedTables.length > 0\n ? `${functionName} committed (${event.changedTables.join(\", \")})`\n : `${functionName} committed`,\n event\n };\n case \"action.completed\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"action\",\n message:\n typeof event.error === \"string\" && event.error.length > 0\n ? `${functionName} failed: ${event.error}`\n : `${functionName} completed`,\n event\n };\n case \"runtime.connected\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: `${publicRuntimeId ?? \"runtime\"} ${runtimeLabel} connected`,\n event\n };\n case \"runtime.disconnected\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: `${publicRuntimeId ?? \"runtime\"} ${runtimeLabel} disconnected`,\n event\n };\n case \"storage.updated\":\n return {\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: `${typeof event.operation === \"string\" ? event.operation : \"update\"} ${typeof event.storageId === \"string\" ? event.storageId : \"storage\"}`,\n event\n };\n default:\n return {\n ...entryBase,\n eventType: event.type,\n category: \"system\",\n message: event.type === \"log\" ? logMessage : humanizeRuntimeEvent(event),\n event\n };\n }\n}\n\nfunction decoratePersistedLogEntry(\n entry: PersistedLogEntry,\n runtimeLookup: ReturnType<typeof buildRuntimeLookup>\n): PersistedLogEntry {\n const runtime = runtimeLookup.get(entry.runtimeId);\n return {\n ...entry,\n targetId:\n entry.targetId === \"all\"\n ? \"all\"\n : runtime?.targetId ?? entry.targetId ?? entry.runtimeId,\n ...(runtime?.targetLabel ? { targetLabel: runtime.targetLabel } : {}),\n ...(runtime?.id ? { publicRuntimeId: runtime.id } : {}),\n ...(runtime?.label ? { runtimeLabel: runtime.label } : {}),\n ...(entry.origin ? {} : { origin: entry.runtimeId === \"syncore-dev-hub\" ? \"dashboard\" : \"runtime\" })\n };\n}\n\nfunction shouldSuppressLogEntry(entry: PersistedLogEntry): boolean {\n return (\n entry.eventType === \"log\" &&\n /syncore devtools hub is alive/i.test(entry.message)\n );\n}\n\nfunction formatInvalidatedQueryId(queryId: unknown): string {\n if (typeof queryId !== \"string\" || queryId.length === 0) {\n return \"query\";\n }\n const separatorIndex = queryId.indexOf(\":\");\n if (separatorIndex === -1) {\n return queryId;\n }\n return queryId.slice(0, separatorIndex);\n}\n\nfunction humanizeRuntimeEvent(\n event: Record<string, unknown> & { type: string }\n): string {\n if (event.type === \"scheduler.tick\" && Array.isArray(event.executedJobIds)) {\n return `scheduler tick (${event.executedJobIds.length} job(s))`;\n }\n return event.type.replaceAll(\".\", \" \");\n}\n\nasync function subscribeOnce(\n hub: ConnectedHub,\n runtimeId: string,\n payload: Parameters<ConnectedHub[\"subscribe\"]>[1]\n): Promise<SyncoreDevtoolsSubscriptionResultPayload> {\n return await new Promise((resolve, reject) => {\n const unsubscribe = hub.subscribe(runtimeId, payload, {\n onData(result) {\n unsubscribe();\n resolve(result);\n },\n onError(error) {\n unsubscribe();\n reject(new Error(error));\n }\n });\n });\n}\n\nasync function promptForTemplate(\n context: CliContext,\n detectedTemplate: string\n): Promise<SyncoreTemplateName> {\n const choices: CliChoice<SyncoreTemplateName>[] = VALID_SYNCORE_TEMPLATES.map(\n (template) =>\n template === detectedTemplate\n ? {\n label: template,\n value: template,\n description: \"Detected from the current project\"\n }\n : {\n label: template,\n value: template\n }\n );\n return await context.select(\n \"Choose a Syncore template for this directory.\",\n choices,\n isKnownTemplate(detectedTemplate) ? detectedTemplate : VALID_SYNCORE_TEMPLATES[0]\n );\n}\n\nasync function isDirectoryEmpty(directory: string): Promise<boolean> {\n try {\n const entries = await readdir(directory);\n return entries.length === 0;\n } catch {\n return true;\n }\n}\n\nfunction printScaffoldChanges(\n context: CliContext,\n result: Awaited<ReturnType<typeof scaffoldProject>>\n): void {\n if (result.created.length > 0) {\n context.info(`Created: ${result.created.join(\", \")}`);\n }\n if (result.updated.length > 0) {\n context.info(`Updated: ${result.updated.join(\", \")}`);\n }\n if (result.skipped.length > 0) {\n context.warn(`Kept existing: ${result.skipped.join(\", \")}`);\n }\n}\n\nfunction isTargetCapability(value: string): value is TargetCapability {\n return (\n value === \"run\" ||\n value === \"readData\" ||\n value === \"writeData\" ||\n value === \"exportData\" ||\n value === \"streamLogs\"\n );\n}\n\nasync function previewImportPlan(\n context: CliContext,\n sourcePath: string,\n options: ImportCommandOptions,\n targetId: string\n): Promise<{\n target: string;\n format: string;\n totalRows: number;\n batches: Array<{ table: string; rowCount: number }>;\n}> {\n const batches = await loadImportDocumentBatches(context.cwd, sourcePath, {\n ...(options.table ? { table: options.table } : {})\n });\n const preview = {\n target: targetId,\n format: path.extname(sourcePath).toLowerCase() || \"directory\",\n totalRows: batches.reduce((sum, batch) => sum + batch.rows.length, 0),\n batches: batches.map((batch) => ({\n table: batch.table,\n rowCount: batch.rows.length\n }))\n };\n\n if (!context.json && context.interactive) {\n process.stdout.write(\"Import preview:\\n\");\n process.stdout.write(` target: ${preview.target}\\n`);\n process.stdout.write(` source: ${sourcePath}\\n`);\n process.stdout.write(` format: ${preview.format}\\n`);\n for (const batch of preview.batches) {\n process.stdout.write(` - ${batch.table}: ${batch.rowCount} row(s)\\n`);\n }\n }\n\n return preview;\n}\n\nfunction parseJsonObject(input: string, label: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(input);\n } catch (error) {\n throw new Error(`${label} must be valid JSON: ${formatError(error)}`);\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(`${label} must be a JSON object.`);\n }\n return parsed as Record<string, unknown>;\n}\n\nasync function waitForSignal(): Promise<void> {\n await new Promise<void>((resolve) => {\n const onSignal = () => {\n process.off(\"SIGINT\", onSignal);\n process.off(\"SIGTERM\", onSignal);\n resolve();\n };\n process.on(\"SIGINT\", onSignal);\n process.on(\"SIGTERM\", onSignal);\n });\n}\n\nfunction parseGlobalOptionsFromArgv(argv: string[]): GlobalCliOptions {\n const parsed: GlobalCliOptions = {};\n for (let index = 0; index < argv.length; index += 1) {\n const value = argv[index];\n if (value === \"--cwd\") {\n const nextValue = argv[index + 1];\n if (nextValue) {\n parsed.cwd = nextValue;\n }\n index += 1;\n continue;\n }\n if (value === \"--json\") {\n parsed.json = true;\n continue;\n }\n if (value === \"--verbose\") {\n parsed.verbose = true;\n continue;\n }\n if (value === \"--no-interactive\") {\n parsed.interactive = false;\n continue;\n }\n if (value === \"--yes\" || value === \"-y\") {\n parsed.yes = true;\n }\n }\n return parsed;\n}\n"],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ import { CliError, normalizeCliError } from "./errors.mjs";
2
+ import path from "node:path";
3
+ import { spawn } from "node:child_process";
4
+ import process from "node:process";
5
+ import readline from "node:readline/promises";
6
+ //#region src/context.ts
7
+ var CliContext = class {
8
+ cwd;
9
+ json;
10
+ verbose;
11
+ interactive;
12
+ yes;
13
+ constructor(options = {}) {
14
+ this.cwd = path.resolve(options.cwd ?? process.cwd());
15
+ this.json = options.json ?? false;
16
+ this.verbose = options.verbose ?? false;
17
+ this.yes = options.yes ?? false;
18
+ this.interactive = options.interactive === false ? false : process.env.SYNCORE_FORCE_INTERACTIVE === "1" ? true : Boolean(process.stdin.isTTY && process.stdout.isTTY && !this.json);
19
+ }
20
+ info(message) {
21
+ if (!this.json) process.stdout.write(`[info] ${message}\n`);
22
+ }
23
+ success(message) {
24
+ if (!this.json) process.stdout.write(`[done] ${message}\n`);
25
+ }
26
+ warn(message) {
27
+ if (!this.json) process.stderr.write(`[warn] ${message}\n`);
28
+ }
29
+ error(message) {
30
+ if (!this.json) process.stderr.write(`[error] ${message}\n`);
31
+ }
32
+ nextStep(message) {
33
+ if (!this.json) process.stdout.write(`[next] ${message}\n`);
34
+ }
35
+ printJson(payload) {
36
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
37
+ }
38
+ printResult(result) {
39
+ if (this.json) {
40
+ this.printJson({
41
+ ok: true,
42
+ cwd: this.cwd,
43
+ ...result.command ? { command: result.command } : {},
44
+ ...result.target ? { target: result.target } : {},
45
+ ...result.summary ? { summary: result.summary } : {},
46
+ ...result.data !== void 0 ? { data: result.data } : {},
47
+ ...result.nextSteps ? { nextSteps: result.nextSteps } : {}
48
+ });
49
+ return;
50
+ }
51
+ if (result.summary) this.success(result.summary);
52
+ if (result.nextSteps) for (const step of result.nextSteps) this.nextStep(step);
53
+ }
54
+ fail(message, exitCode = 1, details, options = {}) {
55
+ throw new CliError(message, {
56
+ exitCode,
57
+ details,
58
+ ...options.category ? { category: options.category } : {},
59
+ ...options.nextSteps ? { nextSteps: options.nextSteps } : {}
60
+ });
61
+ }
62
+ handleError(error) {
63
+ const cliError = normalizeCliError(error);
64
+ if (this.json) this.printJson({
65
+ ok: false,
66
+ cwd: this.cwd,
67
+ error: {
68
+ category: cliError.category,
69
+ message: cliError.message,
70
+ exitCode: cliError.exitCode,
71
+ ...cliError.details !== void 0 ? { details: cliError.details } : {},
72
+ ...cliError.nextSteps ? { nextSteps: cliError.nextSteps } : {}
73
+ }
74
+ });
75
+ else {
76
+ this.error(cliError.message);
77
+ if (cliError.nextSteps) for (const step of cliError.nextSteps) this.nextStep(step);
78
+ if (this.verbose && cliError.details !== void 0) this.error(JSON.stringify(cliError.details, null, 2));
79
+ }
80
+ process.exitCode = cliError.exitCode;
81
+ }
82
+ async confirm(message, defaultValue = true) {
83
+ if (this.yes) return true;
84
+ if (!this.interactive) return false;
85
+ const suffix = defaultValue ? "Y/n" : "y/N";
86
+ const normalized = (await this.input(`${message} [${suffix}]`, { defaultValue: defaultValue ? "y" : "n" })).trim().toLowerCase();
87
+ if (normalized.length === 0) return defaultValue;
88
+ return normalized === "y" || normalized === "yes";
89
+ }
90
+ async input(message, options = {}) {
91
+ if (!this.interactive) this.fail(`Cannot prompt in non-interactive mode: ${message}`);
92
+ const rl = readline.createInterface({
93
+ input: process.stdin,
94
+ output: process.stdout
95
+ });
96
+ try {
97
+ const prompt = options.defaultValue !== void 0 ? `${message} (${options.defaultValue}): ` : `${message}: `;
98
+ const answer = await rl.question(prompt);
99
+ if (answer.length === 0 && options.defaultValue !== void 0) return options.defaultValue;
100
+ if (answer.length === 0 && !options.allowEmpty) this.fail(`A value is required for: ${message}`);
101
+ return answer;
102
+ } finally {
103
+ rl.close();
104
+ }
105
+ }
106
+ async select(message, choices, defaultValue) {
107
+ if (!this.interactive) this.fail(`Cannot prompt in non-interactive mode: ${message}`);
108
+ if (choices.length === 0) this.fail(`No choices are available for: ${message}`);
109
+ this.info(message);
110
+ choices.forEach((choice, index) => {
111
+ const suffix = choice.description ? ` - ${choice.description}` : "";
112
+ process.stdout.write(` ${index + 1}. ${choice.label}${suffix}\n`);
113
+ });
114
+ const defaultIndex = defaultValue ? Math.max(choices.findIndex((choice) => choice.value === defaultValue), 0) : 0;
115
+ const rawValue = await this.input(`Choose 1-${choices.length}`, { defaultValue: String(defaultIndex + 1) });
116
+ const index = Number.parseInt(rawValue, 10);
117
+ if (Number.isNaN(index) || index < 1 || index > choices.length) this.fail(`Expected a value between 1 and ${choices.length}.`);
118
+ return choices[index - 1].value;
119
+ }
120
+ async withSpinner(label, action) {
121
+ if (!this.interactive) {
122
+ this.info(label);
123
+ return await action();
124
+ }
125
+ const frames = [
126
+ "-",
127
+ "\\",
128
+ "|",
129
+ "/"
130
+ ];
131
+ let index = 0;
132
+ process.stderr.write(`[work] ${label}`);
133
+ const timer = setInterval(() => {
134
+ process.stderr.write(`\r[${frames[index % frames.length]}] ${label}`);
135
+ index += 1;
136
+ }, 80);
137
+ try {
138
+ const result = await action();
139
+ clearInterval(timer);
140
+ process.stderr.write(`\r[done] ${label}\n`);
141
+ return result;
142
+ } catch (error) {
143
+ clearInterval(timer);
144
+ process.stderr.write(`\r[fail] ${label}\n`);
145
+ throw error;
146
+ }
147
+ }
148
+ };
149
+ async function openTarget(target) {
150
+ const command = process.platform === "win32" ? {
151
+ file: "cmd",
152
+ args: [
153
+ "/c",
154
+ "start",
155
+ "",
156
+ target
157
+ ]
158
+ } : process.platform === "darwin" ? {
159
+ file: "open",
160
+ args: [target]
161
+ } : {
162
+ file: "xdg-open",
163
+ args: [target]
164
+ };
165
+ return await new Promise((resolve) => {
166
+ const child = spawn(command.file, command.args, {
167
+ detached: true,
168
+ stdio: "ignore"
169
+ });
170
+ child.once("error", () => resolve(false));
171
+ child.once("spawn", () => {
172
+ child.unref();
173
+ resolve(true);
174
+ });
175
+ });
176
+ }
177
+ //#endregion
178
+ export { CliContext, openTarget };
179
+
180
+ //# sourceMappingURL=context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.mjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport readline from \"node:readline/promises\";\nimport { CliError, type CliErrorCategory, normalizeCliError } from \"./errors.js\";\n\nexport interface GlobalCliOptions {\n cwd?: string;\n json?: boolean;\n verbose?: boolean;\n interactive?: boolean;\n yes?: boolean;\n}\n\nexport interface CliChoice<TValue> {\n label: string;\n value: TValue;\n description?: string;\n}\n\nexport interface CliResult<TValue = unknown> {\n command?: string;\n summary?: string;\n target?: string;\n data?: TValue;\n nextSteps?: string[];\n}\n\nexport class CliContext {\n readonly cwd: string;\n readonly json: boolean;\n readonly verbose: boolean;\n readonly interactive: boolean;\n readonly yes: boolean;\n\n constructor(options: GlobalCliOptions = {}) {\n this.cwd = path.resolve(options.cwd ?? process.cwd());\n this.json = options.json ?? false;\n this.verbose = options.verbose ?? false;\n this.yes = options.yes ?? false;\n this.interactive =\n options.interactive === false\n ? false\n : process.env.SYNCORE_FORCE_INTERACTIVE === \"1\"\n ? true\n : Boolean(process.stdin.isTTY && process.stdout.isTTY && !this.json);\n }\n\n info(message: string): void {\n if (!this.json) {\n process.stdout.write(`[info] ${message}\\n`);\n }\n }\n\n success(message: string): void {\n if (!this.json) {\n process.stdout.write(`[done] ${message}\\n`);\n }\n }\n\n warn(message: string): void {\n if (!this.json) {\n process.stderr.write(`[warn] ${message}\\n`);\n }\n }\n\n error(message: string): void {\n if (!this.json) {\n process.stderr.write(`[error] ${message}\\n`);\n }\n }\n\n nextStep(message: string): void {\n if (!this.json) {\n process.stdout.write(`[next] ${message}\\n`);\n }\n }\n\n printJson(payload: unknown): void {\n process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`);\n }\n\n printResult<TValue>(result: CliResult<TValue>): void {\n if (this.json) {\n this.printJson({\n ok: true,\n cwd: this.cwd,\n ...(result.command ? { command: result.command } : {}),\n ...(result.target ? { target: result.target } : {}),\n ...(result.summary ? { summary: result.summary } : {}),\n ...(result.data !== undefined ? { data: result.data } : {}),\n ...(result.nextSteps ? { nextSteps: result.nextSteps } : {})\n });\n return;\n }\n\n if (result.summary) {\n this.success(result.summary);\n }\n if (result.nextSteps) {\n for (const step of result.nextSteps) {\n this.nextStep(step);\n }\n }\n }\n\n fail(\n message: string,\n exitCode = 1,\n details?: unknown,\n options: {\n category?: CliErrorCategory;\n nextSteps?: string[];\n } = {}\n ): never {\n const errorOptions = {\n exitCode,\n details,\n ...(options.category ? { category: options.category } : {}),\n ...(options.nextSteps ? { nextSteps: options.nextSteps } : {})\n };\n throw new CliError(message, errorOptions);\n }\n\n handleError(error: unknown): void {\n const cliError = normalizeCliError(error);\n\n if (this.json) {\n this.printJson({\n ok: false,\n cwd: this.cwd,\n error: {\n category: cliError.category,\n message: cliError.message,\n exitCode: cliError.exitCode,\n ...(cliError.details !== undefined ? { details: cliError.details } : {}),\n ...(cliError.nextSteps ? { nextSteps: cliError.nextSteps } : {})\n }\n });\n } else {\n this.error(cliError.message);\n if (cliError.nextSteps) {\n for (const step of cliError.nextSteps) {\n this.nextStep(step);\n }\n }\n if (this.verbose && cliError.details !== undefined) {\n this.error(JSON.stringify(cliError.details, null, 2));\n }\n }\n\n process.exitCode = cliError.exitCode;\n }\n\n async confirm(message: string, defaultValue = true): Promise<boolean> {\n if (this.yes) {\n return true;\n }\n if (!this.interactive) {\n return false;\n }\n\n const suffix = defaultValue ? \"Y/n\" : \"y/N\";\n const answer = await this.input(`${message} [${suffix}]`, {\n defaultValue: defaultValue ? \"y\" : \"n\"\n });\n const normalized = answer.trim().toLowerCase();\n if (normalized.length === 0) {\n return defaultValue;\n }\n return normalized === \"y\" || normalized === \"yes\";\n }\n\n async input(\n message: string,\n options: {\n defaultValue?: string;\n allowEmpty?: boolean;\n } = {}\n ): Promise<string> {\n if (!this.interactive) {\n this.fail(`Cannot prompt in non-interactive mode: ${message}`);\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n try {\n const prompt =\n options.defaultValue !== undefined\n ? `${message} (${options.defaultValue}): `\n : `${message}: `;\n const answer = await rl.question(prompt);\n if (answer.length === 0 && options.defaultValue !== undefined) {\n return options.defaultValue;\n }\n if (answer.length === 0 && !options.allowEmpty) {\n this.fail(`A value is required for: ${message}`);\n }\n return answer;\n } finally {\n rl.close();\n }\n }\n\n async select<TValue>(\n message: string,\n choices: CliChoice<TValue>[],\n defaultValue?: TValue\n ): Promise<TValue> {\n if (!this.interactive) {\n this.fail(`Cannot prompt in non-interactive mode: ${message}`);\n }\n if (choices.length === 0) {\n this.fail(`No choices are available for: ${message}`);\n }\n\n this.info(message);\n choices.forEach((choice, index) => {\n const suffix = choice.description ? ` - ${choice.description}` : \"\";\n process.stdout.write(` ${index + 1}. ${choice.label}${suffix}\\n`);\n });\n\n const defaultIndex = defaultValue\n ? Math.max(\n choices.findIndex((choice) => choice.value === defaultValue),\n 0\n )\n : 0;\n const rawValue = await this.input(`Choose 1-${choices.length}`, {\n defaultValue: String(defaultIndex + 1)\n });\n const index = Number.parseInt(rawValue, 10);\n if (Number.isNaN(index) || index < 1 || index > choices.length) {\n this.fail(`Expected a value between 1 and ${choices.length}.`);\n }\n return choices[index - 1]!.value;\n }\n\n async withSpinner<TValue>(\n label: string,\n action: () => Promise<TValue>\n ): Promise<TValue> {\n if (!this.interactive) {\n this.info(label);\n return await action();\n }\n\n const frames = [\"-\", \"\\\\\", \"|\", \"/\"];\n let index = 0;\n process.stderr.write(`[work] ${label}`);\n const timer = setInterval(() => {\n process.stderr.write(`\\r[${frames[index % frames.length]}] ${label}`);\n index += 1;\n }, 80);\n\n try {\n const result = await action();\n clearInterval(timer);\n process.stderr.write(`\\r[done] ${label}\\n`);\n return result;\n } catch (error) {\n clearInterval(timer);\n process.stderr.write(`\\r[fail] ${label}\\n`);\n throw error;\n }\n }\n}\n\nexport async function openTarget(target: string): Promise<boolean> {\n const command =\n process.platform === \"win32\"\n ? {\n file: \"cmd\",\n args: [\"/c\", \"start\", \"\", target]\n }\n : process.platform === \"darwin\"\n ? {\n file: \"open\",\n args: [target]\n }\n : {\n file: \"xdg-open\",\n args: [target]\n };\n\n return await new Promise((resolve) => {\n const child = spawn(command.file, command.args, {\n detached: true,\n stdio: \"ignore\"\n });\n child.once(\"error\", () => resolve(false));\n child.once(\"spawn\", () => {\n child.unref();\n resolve(true);\n });\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { spawn } from "node:child_process";
2
+ //#region src/dev-session.ts
3
+ async function withConsoleCapture(onMessage, action) {
4
+ const originalLog = console.log;
5
+ const originalWarn = console.warn;
6
+ const originalError = console.error;
7
+ const capture = (method) => (...args) => {
8
+ const message = args.map((value) => typeof value === "string" ? value : String(value)).join(" ").trim();
9
+ if (message.length > 0) onMessage(method, message);
10
+ };
11
+ console.log = capture("log");
12
+ console.warn = capture("warn");
13
+ console.error = capture("error");
14
+ try {
15
+ return await action();
16
+ } finally {
17
+ console.log = originalLog;
18
+ console.warn = originalWarn;
19
+ console.error = originalError;
20
+ }
21
+ }
22
+ function printDevSessionIntro(context) {
23
+ context.info("Starting Syncore local dev session...");
24
+ }
25
+ function printCompactDevPhase(context, label) {
26
+ context.info(label);
27
+ }
28
+ async function runShellCommand(context, command) {
29
+ context.info(`Starting host command after Syncore bootstrap: ${command}`);
30
+ await new Promise((resolve, reject) => {
31
+ const child = spawn(command, {
32
+ cwd: context.cwd,
33
+ shell: true,
34
+ stdio: "inherit"
35
+ });
36
+ child.once("error", reject);
37
+ child.once("exit", (code) => {
38
+ if ((code ?? 1) !== 0) {
39
+ reject(/* @__PURE__ */ new Error(`Shell command failed with exit code ${code ?? 1}.`));
40
+ return;
41
+ }
42
+ resolve();
43
+ });
44
+ });
45
+ }
46
+ //#endregion
47
+ export { printCompactDevPhase, printDevSessionIntro, runShellCommand, withConsoleCapture };
48
+
49
+ //# sourceMappingURL=dev-session.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-session.mjs","names":[],"sources":["../src/dev-session.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\n\nimport type { CliContext } from \"./context.js\";\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\n\nexport async function withConsoleCapture<TValue>(\n onMessage: (method: ConsoleMethod, message: string) => void,\n action: () => Promise<TValue>\n): Promise<TValue> {\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n const capture =\n (method: ConsoleMethod) =>\n (...args: unknown[]) => {\n const message = args\n .map((value) => (typeof value === \"string\" ? value : String(value)))\n .join(\" \")\n .trim();\n if (message.length > 0) {\n onMessage(method, message);\n }\n };\n\n console.log = capture(\"log\");\n console.warn = capture(\"warn\");\n console.error = capture(\"error\");\n\n try {\n return await action();\n } finally {\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n }\n}\n\nexport function printDevSessionIntro(context: CliContext): void {\n context.info(\"Starting Syncore local dev session...\");\n}\n\nexport function printCompactDevPhase(context: CliContext, label: string): void {\n context.info(label);\n}\n\nexport async function runShellCommand(\n context: CliContext,\n command: string\n): Promise<void> {\n context.info(`Starting host command after Syncore bootstrap: ${command}`);\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, {\n cwd: context.cwd,\n shell: true,\n stdio: \"inherit\"\n });\n child.once(\"error\", reject);\n child.once(\"exit\", (code) => {\n if ((code ?? 1) !== 0) {\n reject(new Error(`Shell command failed with exit code ${code ?? 1}.`));\n return;\n }\n resolve();\n });\n });\n}\n\n"],"mappings":";;AAMA,eAAsB,mBACpB,WACA,QACiB;CACjB,MAAM,cAAc,QAAQ;CAC5B,MAAM,eAAe,QAAQ;CAC7B,MAAM,gBAAgB,QAAQ;CAE9B,MAAM,WACH,YACA,GAAG,SAAoB;EACtB,MAAM,UAAU,KACb,KAAK,UAAW,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM,CAAE,CACnE,KAAK,IAAI,CACT,MAAM;AACT,MAAI,QAAQ,SAAS,EACnB,WAAU,QAAQ,QAAQ;;AAIhC,SAAQ,MAAM,QAAQ,MAAM;AAC5B,SAAQ,OAAO,QAAQ,OAAO;AAC9B,SAAQ,QAAQ,QAAQ,QAAQ;AAEhC,KAAI;AACF,SAAO,MAAM,QAAQ;WACb;AACR,UAAQ,MAAM;AACd,UAAQ,OAAO;AACf,UAAQ,QAAQ;;;AAIpB,SAAgB,qBAAqB,SAA2B;AAC9D,SAAQ,KAAK,wCAAwC;;AAGvD,SAAgB,qBAAqB,SAAqB,OAAqB;AAC7E,SAAQ,KAAK,MAAM;;AAGrB,eAAsB,gBACpB,SACA,SACe;AACf,SAAQ,KAAK,kDAAkD,UAAU;AACzE,OAAM,IAAI,SAAe,SAAS,WAAW;EAC3C,MAAM,QAAQ,MAAM,SAAS;GAC3B,KAAK,QAAQ;GACb,OAAO;GACP,OAAO;GACR,CAAC;AACF,QAAM,KAAK,SAAS,OAAO;AAC3B,QAAM,KAAK,SAAS,SAAS;AAC3B,QAAK,QAAQ,OAAO,GAAG;AACrB,2BAAO,IAAI,MAAM,uCAAuC,QAAQ,EAAE,GAAG,CAAC;AACtE;;AAEF,YAAS;IACT;GACF"}
@@ -0,0 +1,80 @@
1
+ import { findWorkspaceSyncoreProjects, listAvailableTargets, resolveDashboardUrl, resolveDevtoolsUrl, resolveProjectTargetDescriptor } from "./project.mjs";
2
+ import { templateUsesConnectedClients } from "./messages.mjs";
3
+ import path from "node:path";
4
+ import { detectProjectTemplate, fileExists, isLocalPortInUse } from "../core/cli.mjs";
5
+ //#region src/doctor.ts
6
+ async function buildDoctorReport(cwd) {
7
+ const template = await detectProjectTemplate(cwd);
8
+ const checks = [
9
+ {
10
+ category: "project",
11
+ path: "syncore.config.ts"
12
+ },
13
+ {
14
+ category: "schema",
15
+ path: path.join("syncore", "schema.ts")
16
+ },
17
+ {
18
+ category: "project",
19
+ path: path.join("syncore", "functions")
20
+ },
21
+ {
22
+ category: "generated",
23
+ path: path.join("syncore", "_generated", "functions.ts")
24
+ },
25
+ {
26
+ category: "schema",
27
+ path: path.join("syncore", "migrations")
28
+ }
29
+ ];
30
+ const checkResults = await Promise.all(checks.map(async (entry) => ({
31
+ category: entry.category,
32
+ path: entry.path.replaceAll("\\", "/"),
33
+ ok: await fileExists(path.join(cwd, entry.path))
34
+ })));
35
+ const projectTarget = await resolveProjectTargetDescriptor(cwd);
36
+ const targets = await listAvailableTargets(cwd);
37
+ const devtoolsUrl = resolveDevtoolsUrl();
38
+ const dashboardUrl = resolveDashboardUrl();
39
+ const hubPort = Number.parseInt(new URL(devtoolsUrl).port, 10);
40
+ const dashboardPort = Number.parseInt(new URL(dashboardUrl).port, 10);
41
+ const hub = {
42
+ url: devtoolsUrl,
43
+ dashboardUrl,
44
+ running: Number.isFinite(hubPort) && hubPort > 0 ? await isLocalPortInUse(hubPort) : false,
45
+ dashboardRunning: Number.isFinite(dashboardPort) && dashboardPort > 0 ? await isLocalPortInUse(dashboardPort) : false,
46
+ ports: {
47
+ devtools: hubPort,
48
+ dashboard: dashboardPort
49
+ }
50
+ };
51
+ const ready = checkResults.every((entry) => entry.ok);
52
+ const workspaceMatches = ready ? [] : await findWorkspaceSyncoreProjects(cwd);
53
+ const clientTargets = targets.filter((target) => target.kind === "client");
54
+ const status = ready ? !projectTarget && clientTargets.length === 0 ? "waiting-for-client" : "ready" : workspaceMatches.length > 0 ? "workspace-root" : checkResults.some((entry) => entry.ok) ? "incomplete" : "missing";
55
+ const suggestions = [];
56
+ if (status === "workspace-root") suggestions.push(`Run the command with --cwd ${workspaceMatches[0].relativePath} or change into a package directory.`);
57
+ if (status === "missing") suggestions.push("Run `npx syncorejs init` to scaffold a new Syncore project.");
58
+ if (status === "incomplete") {
59
+ suggestions.push("Run `npx syncorejs codegen` after restoring missing files.");
60
+ suggestions.push("Run `npx syncorejs migrate status` to inspect schema state.");
61
+ }
62
+ if (!projectTarget && templateUsesConnectedClients(template)) suggestions.push("Use `npx syncorejs dev` and a connected client target for run/data/import/export in this template.");
63
+ if (status === "waiting-for-client") suggestions.push("Start your app host, then run `npx syncorejs targets` to inspect connected client targets.");
64
+ if (!hub.running) suggestions.push("Run `npx syncorejs dev` to start the local devtools hub.");
65
+ return {
66
+ cwd,
67
+ template,
68
+ status,
69
+ checks: checkResults,
70
+ workspaceMatches,
71
+ suggestions,
72
+ projectTarget,
73
+ targets,
74
+ hub
75
+ };
76
+ }
77
+ //#endregion
78
+ export { buildDoctorReport };
79
+
80
+ //# sourceMappingURL=doctor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.mjs","names":[],"sources":["../src/doctor.ts"],"sourcesContent":["import path from \"node:path\";\nimport { detectProjectTemplate, fileExists, isLocalPortInUse } from \"@syncore/core/cli\";\nimport type { ClientTargetDescriptor, SyncoreTargetDescriptor, WorkspaceProjectMatch } from \"./project.js\";\nimport {\n findWorkspaceSyncoreProjects,\n listAvailableTargets,\n resolveDashboardUrl,\n resolveDevtoolsUrl,\n resolveProjectTargetDescriptor\n} from \"./project.js\";\nimport { templateUsesConnectedClients } from \"./messages.js\";\n\nexport type DoctorStatus =\n | \"ready\"\n | \"incomplete\"\n | \"workspace-root\"\n | \"missing\"\n | \"waiting-for-client\";\n\nexport type DoctorCheckCategory = \"project\" | \"generated\" | \"schema\";\n\nexport interface DoctorCheck {\n category: DoctorCheckCategory;\n path: string;\n ok: boolean;\n}\n\nexport interface DoctorReport {\n cwd: string;\n template: string;\n status: DoctorStatus;\n checks: DoctorCheck[];\n workspaceMatches: WorkspaceProjectMatch[];\n suggestions: string[];\n projectTarget: Awaited<ReturnType<typeof resolveProjectTargetDescriptor>>;\n targets: SyncoreTargetDescriptor[];\n hub: {\n url: string;\n dashboardUrl: string;\n running: boolean;\n dashboardRunning: boolean;\n ports: {\n devtools: number;\n dashboard: number;\n };\n };\n}\n\nexport async function buildDoctorReport(cwd: string): Promise<DoctorReport> {\n const template = await detectProjectTemplate(cwd);\n const checks = [\n { category: \"project\" as const, path: \"syncore.config.ts\" },\n { category: \"schema\" as const, path: path.join(\"syncore\", \"schema.ts\") },\n { category: \"project\" as const, path: path.join(\"syncore\", \"functions\") },\n {\n category: \"generated\" as const,\n path: path.join(\"syncore\", \"_generated\", \"functions.ts\")\n },\n { category: \"schema\" as const, path: path.join(\"syncore\", \"migrations\") }\n ];\n const checkResults = await Promise.all(\n checks.map(async (entry) => ({\n category: entry.category,\n path: entry.path.replaceAll(\"\\\\\", \"/\"),\n ok: await fileExists(path.join(cwd, entry.path))\n }))\n );\n const projectTarget = await resolveProjectTargetDescriptor(cwd);\n const targets = await listAvailableTargets(cwd);\n const devtoolsUrl = resolveDevtoolsUrl();\n const dashboardUrl = resolveDashboardUrl();\n const hubPort = Number.parseInt(new URL(devtoolsUrl).port, 10);\n const dashboardPort = Number.parseInt(new URL(dashboardUrl).port, 10);\n const hub = {\n url: devtoolsUrl,\n dashboardUrl,\n running:\n Number.isFinite(hubPort) && hubPort > 0\n ? await isLocalPortInUse(hubPort)\n : false,\n dashboardRunning:\n Number.isFinite(dashboardPort) && dashboardPort > 0\n ? await isLocalPortInUse(dashboardPort)\n : false,\n ports: {\n devtools: hubPort,\n dashboard: dashboardPort\n }\n };\n\n const ready = checkResults.every((entry) => entry.ok);\n const workspaceMatches = ready ? [] : await findWorkspaceSyncoreProjects(cwd);\n const clientTargets = targets.filter(\n (target): target is ClientTargetDescriptor => target.kind === \"client\"\n );\n const status =\n ready\n ? !projectTarget && clientTargets.length === 0\n ? \"waiting-for-client\"\n : \"ready\"\n : workspaceMatches.length > 0\n ? \"workspace-root\"\n : checkResults.some((entry) => entry.ok)\n ? \"incomplete\"\n : \"missing\";\n\n const suggestions: string[] = [];\n if (status === \"workspace-root\") {\n suggestions.push(\n `Run the command with --cwd ${workspaceMatches[0]!.relativePath} or change into a package directory.`\n );\n }\n if (status === \"missing\") {\n suggestions.push(\"Run `npx syncorejs init` to scaffold a new Syncore project.\");\n }\n if (status === \"incomplete\") {\n suggestions.push(\"Run `npx syncorejs codegen` after restoring missing files.\");\n suggestions.push(\"Run `npx syncorejs migrate status` to inspect schema state.\");\n }\n if (!projectTarget && templateUsesConnectedClients(template)) {\n suggestions.push(\n \"Use `npx syncorejs dev` and a connected client target for run/data/import/export in this template.\"\n );\n }\n if (status === \"waiting-for-client\") {\n suggestions.push(\"Start your app host, then run `npx syncorejs targets` to inspect connected client targets.\");\n }\n if (!hub.running) {\n suggestions.push(\"Run `npx syncorejs dev` to start the local devtools hub.\");\n }\n\n return {\n cwd,\n template,\n status,\n checks: checkResults,\n workspaceMatches,\n suggestions,\n projectTarget,\n targets,\n hub\n };\n}\n"],"mappings":";;;;;AAgDA,eAAsB,kBAAkB,KAAoC;CAC1E,MAAM,WAAW,MAAM,sBAAsB,IAAI;CACjD,MAAM,SAAS;EACb;GAAE,UAAU;GAAoB,MAAM;GAAqB;EAC3D;GAAE,UAAU;GAAmB,MAAM,KAAK,KAAK,WAAW,YAAY;GAAE;EACxE;GAAE,UAAU;GAAoB,MAAM,KAAK,KAAK,WAAW,YAAY;GAAE;EACzE;GACE,UAAU;GACV,MAAM,KAAK,KAAK,WAAW,cAAc,eAAe;GACzD;EACD;GAAE,UAAU;GAAmB,MAAM,KAAK,KAAK,WAAW,aAAa;GAAE;EAC1E;CACD,MAAM,eAAe,MAAM,QAAQ,IACjC,OAAO,IAAI,OAAO,WAAW;EAC3B,UAAU,MAAM;EAChB,MAAM,MAAM,KAAK,WAAW,MAAM,IAAI;EACtC,IAAI,MAAM,WAAW,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC;EACjD,EAAE,CACJ;CACD,MAAM,gBAAgB,MAAM,+BAA+B,IAAI;CAC/D,MAAM,UAAU,MAAM,qBAAqB,IAAI;CAC/C,MAAM,cAAc,oBAAoB;CACxC,MAAM,eAAe,qBAAqB;CAC1C,MAAM,UAAU,OAAO,SAAS,IAAI,IAAI,YAAY,CAAC,MAAM,GAAG;CAC9D,MAAM,gBAAgB,OAAO,SAAS,IAAI,IAAI,aAAa,CAAC,MAAM,GAAG;CACrE,MAAM,MAAM;EACV,KAAK;EACL;EACA,SACE,OAAO,SAAS,QAAQ,IAAI,UAAU,IAClC,MAAM,iBAAiB,QAAQ,GAC/B;EACN,kBACE,OAAO,SAAS,cAAc,IAAI,gBAAgB,IAC9C,MAAM,iBAAiB,cAAc,GACrC;EACN,OAAO;GACL,UAAU;GACV,WAAW;GACZ;EACF;CAED,MAAM,QAAQ,aAAa,OAAO,UAAU,MAAM,GAAG;CACrD,MAAM,mBAAmB,QAAQ,EAAE,GAAG,MAAM,6BAA6B,IAAI;CAC7E,MAAM,gBAAgB,QAAQ,QAC3B,WAA6C,OAAO,SAAS,SAC/D;CACD,MAAM,SACJ,QACI,CAAC,iBAAiB,cAAc,WAAW,IACzC,uBACA,UACF,iBAAiB,SAAS,IACxB,mBACA,aAAa,MAAM,UAAU,MAAM,GAAG,GACpC,eACA;CAEV,MAAM,cAAwB,EAAE;AAChC,KAAI,WAAW,iBACb,aAAY,KACV,8BAA8B,iBAAiB,GAAI,aAAa,sCACjE;AAEH,KAAI,WAAW,UACb,aAAY,KAAK,8DAA8D;AAEjF,KAAI,WAAW,cAAc;AAC3B,cAAY,KAAK,6DAA6D;AAC9E,cAAY,KAAK,8DAA8D;;AAEjF,KAAI,CAAC,iBAAiB,6BAA6B,SAAS,CAC1D,aAAY,KACV,qGACD;AAEH,KAAI,WAAW,qBACb,aAAY,KAAK,6FAA6F;AAEhH,KAAI,CAAC,IAAI,QACP,aAAY,KAAK,2DAA2D;AAG9E,QAAO;EACL;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;EACD"}
@@ -0,0 +1,22 @@
1
+ //#region src/errors.ts
2
+ var CliError = class extends Error {
3
+ exitCode;
4
+ category;
5
+ details;
6
+ nextSteps;
7
+ constructor(message, options = {}) {
8
+ super(message);
9
+ this.exitCode = options.exitCode ?? 1;
10
+ this.category = options.category ?? "system";
11
+ this.details = options.details;
12
+ this.nextSteps = options.nextSteps;
13
+ }
14
+ };
15
+ function normalizeCliError(error) {
16
+ if (error instanceof CliError) return error;
17
+ return new CliError(error instanceof Error ? error.message : String(error));
18
+ }
19
+ //#endregion
20
+ export { CliError, normalizeCliError };
21
+
22
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["export type CliErrorCategory =\n | \"usage\"\n | \"context\"\n | \"validation\"\n | \"target\"\n | \"hub\"\n | \"runtime\"\n | \"system\";\n\nexport interface CliErrorOptions {\n exitCode?: number;\n category?: CliErrorCategory;\n details?: unknown;\n nextSteps?: string[];\n}\n\nexport class CliError extends Error {\n readonly exitCode: number;\n readonly category: CliErrorCategory;\n readonly details: unknown;\n readonly nextSteps: string[] | undefined;\n\n constructor(message: string, options: CliErrorOptions = {}) {\n super(message);\n this.exitCode = options.exitCode ?? 1;\n this.category = options.category ?? \"system\";\n this.details = options.details;\n this.nextSteps = options.nextSteps;\n }\n}\n\nexport function normalizeCliError(error: unknown): CliError {\n if (error instanceof CliError) {\n return error;\n }\n\n return new CliError(error instanceof Error ? error.message : String(error));\n}\n"],"mappings":";AAgBA,IAAa,WAAb,cAA8B,MAAM;CAClC;CACA;CACA;CACA;CAEA,YAAY,SAAiB,UAA2B,EAAE,EAAE;AAC1D,QAAM,QAAQ;AACd,OAAK,WAAW,QAAQ,YAAY;AACpC,OAAK,WAAW,QAAQ,YAAY;AACpC,OAAK,UAAU,QAAQ;AACvB,OAAK,YAAY,QAAQ;;;AAI7B,SAAgB,kBAAkB,OAA0B;AAC1D,KAAI,iBAAiB,SACnB,QAAO;AAGT,QAAO,IAAI,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC"}