@swarm.ing/pieui 2.0.10 → 2.0.13

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 (70) hide show
  1. package/README.md +48 -0
  2. package/dist/cli.js +437 -193
  3. package/dist/code/args.d.ts.map +1 -1
  4. package/dist/code/commands/add.d.ts +2 -2
  5. package/dist/code/commands/add.d.ts.map +1 -1
  6. package/dist/code/commands/create.d.ts +2 -0
  7. package/dist/code/commands/create.d.ts.map +1 -0
  8. package/dist/code/commands/init.d.ts.map +1 -1
  9. package/dist/code/commands/pageAdd.d.ts +2 -0
  10. package/dist/code/commands/pageAdd.d.ts.map +1 -0
  11. package/dist/code/public/favicon.ico +0 -0
  12. package/dist/code/public/favicon.svg +1 -0
  13. package/dist/code/public/pieui.png +0 -0
  14. package/dist/code/public/swarm.ing.png +0 -0
  15. package/dist/code/templates/componentTypes.d.ts +2 -1
  16. package/dist/code/templates/componentTypes.d.ts.map +1 -1
  17. package/dist/code/templates/env.d.ts +2 -0
  18. package/dist/code/templates/env.d.ts.map +1 -0
  19. package/dist/code/templates/homePage.d.ts +2 -0
  20. package/dist/code/templates/homePage.d.ts.map +1 -0
  21. package/dist/code/templates/index.d.ts +7 -4
  22. package/dist/code/templates/index.d.ts.map +1 -1
  23. package/dist/code/templates/loadingScreen.d.ts +2 -0
  24. package/dist/code/templates/loadingScreen.d.ts.map +1 -0
  25. package/dist/code/templates/nextConfig.d.ts +1 -1
  26. package/dist/code/templates/nextConfig.d.ts.map +1 -1
  27. package/dist/code/templates/pages/components/complexComponent.d.ts +3 -0
  28. package/dist/code/templates/pages/components/complexComponent.d.ts.map +1 -0
  29. package/dist/code/templates/pages/components/complexContainerComponent.d.ts +3 -0
  30. package/dist/code/templates/pages/components/complexContainerComponent.d.ts.map +1 -0
  31. package/dist/code/templates/pages/components/index.d.ts +5 -0
  32. package/dist/code/templates/pages/components/index.d.ts.map +1 -0
  33. package/dist/code/templates/pages/components/shared.d.ts +5 -0
  34. package/dist/code/templates/pages/components/shared.d.ts.map +1 -0
  35. package/dist/code/templates/pages/components/simpleComponent.d.ts +3 -0
  36. package/dist/code/templates/pages/components/simpleComponent.d.ts.map +1 -0
  37. package/dist/code/templates/pages/components/simpleContainerComponent.d.ts +3 -0
  38. package/dist/code/templates/pages/components/simpleContainerComponent.d.ts.map +1 -0
  39. package/dist/code/templates/pages/index.d.ts +6 -0
  40. package/dist/code/templates/pages/index.d.ts.map +1 -0
  41. package/dist/code/templates/pages/page.d.ts +2 -0
  42. package/dist/code/templates/pages/page.d.ts.map +1 -0
  43. package/dist/code/templates/rootLayout.d.ts +2 -0
  44. package/dist/code/templates/rootLayout.d.ts.map +1 -0
  45. package/dist/code/templates/sharedPage.d.ts +2 -0
  46. package/dist/code/templates/sharedPage.d.ts.map +1 -0
  47. package/dist/code/types.d.ts +11 -0
  48. package/dist/code/types.d.ts.map +1 -1
  49. package/package.json +5 -13
  50. package/dist/__tests__/step1-local.test.d.cts +0 -2
  51. package/dist/__tests__/step1-local.test.d.cts.map +0 -1
  52. package/dist/__tests__/step2-remote.test.d.cts +0 -2
  53. package/dist/__tests__/step2-remote.test.d.cts.map +0 -1
  54. package/dist/__tests__/step3-contract.test.d.cts +0 -2
  55. package/dist/__tests__/step3-contract.test.d.cts.map +0 -1
  56. package/dist/__tests__/step4-ci.test.d.cts +0 -2
  57. package/dist/__tests__/step4-ci.test.d.cts.map +0 -1
  58. package/dist/__tests__/step5-regres.test.d.cts +0 -2
  59. package/dist/__tests__/step5-regres.test.d.cts.map +0 -1
  60. package/dist/code/templates/complexComponent.d.ts +0 -2
  61. package/dist/code/templates/complexComponent.d.ts.map +0 -1
  62. package/dist/code/templates/complexContainerComponent.d.ts +0 -2
  63. package/dist/code/templates/complexContainerComponent.d.ts.map +0 -1
  64. package/dist/code/templates/simpleComponent.d.ts +0 -2
  65. package/dist/code/templates/simpleComponent.d.ts.map +0 -1
  66. package/dist/code/templates/simpleContainerComponent.d.ts +0 -2
  67. package/dist/code/templates/simpleContainerComponent.d.ts.map +0 -1
  68. package/dist/create.d.ts +0 -3
  69. package/dist/create.d.ts.map +0 -1
  70. package/dist/create.js +0 -162
package/dist/cli.js CHANGED
@@ -193027,6 +193027,7 @@ var require_lib4 = __commonJS((exports2, module2) => {
193027
193027
  // src/code/args.ts
193028
193028
  var parseArgs = (argv) => {
193029
193029
  const [command = ""] = argv;
193030
+ const cardFlagSet = new Set(["--io", "--ajax"]);
193030
193031
  const outDirFlag = argv.find((arg) => arg.startsWith("--out-dir="));
193031
193032
  const srcDirFlag = argv.find((arg) => arg.startsWith("--src-dir="));
193032
193033
  const outDirIndex = argv.findIndex((arg) => arg === "--out-dir" || arg === "-o");
@@ -193038,12 +193039,17 @@ var parseArgs = (argv) => {
193038
193039
  let componentName;
193039
193040
  let createAppName;
193040
193041
  let eventName;
193042
+ let cardAction;
193043
+ let cardAjax = false;
193044
+ let cardIo = false;
193045
+ let pageAction;
193046
+ let pagePath;
193041
193047
  let removeComponentName;
193042
193048
  let listFilter;
193043
193049
  if (command === "remove" && argv[1]) {
193044
193050
  removeComponentName = argv[1];
193045
193051
  }
193046
- if (command === "create-pie-app" && argv[1]) {
193052
+ if ((command === "create-pie-app" || command === "create") && argv[1]) {
193047
193053
  createAppName = argv[1];
193048
193054
  }
193049
193055
  if (command === "list") {
@@ -193057,19 +193063,37 @@ var parseArgs = (argv) => {
193057
193063
  const filterArg = argv[1];
193058
193064
  listFilter = filterArg && validFilters.includes(filterArg) ? filterArg : "all";
193059
193065
  }
193060
- if (command === "add" && argv[1]) {
193066
+ if (command === "card" && argv[1]) {
193067
+ const validActions = ["add"];
193068
+ if (validActions.includes(argv[1])) {
193069
+ cardAction = argv[1];
193070
+ }
193071
+ }
193072
+ if ((command === "card" && cardAction === "add" || command === "add") && argv[1]) {
193073
+ const offset = command === "card" ? 2 : 1;
193074
+ const cardArgv = argv.slice(offset);
193075
+ const positionalArgs = cardArgv.filter((arg) => !cardFlagSet.has(arg));
193076
+ cardIo = cardArgv.includes("--io");
193077
+ cardAjax = cardArgv.includes("--ajax");
193061
193078
  const validTypes = [
193062
193079
  "simple",
193063
193080
  "complex",
193064
193081
  "simple-container",
193065
193082
  "complex-container"
193066
193083
  ];
193067
- if (validTypes.includes(argv[1])) {
193068
- componentType = argv[1];
193069
- componentName = argv[2];
193084
+ if (validTypes.includes(positionalArgs[0])) {
193085
+ componentType = positionalArgs[0];
193086
+ componentName = positionalArgs[1];
193070
193087
  } else {
193071
193088
  componentType = "complex-container";
193072
- componentName = argv[1];
193089
+ componentName = positionalArgs[0];
193090
+ }
193091
+ }
193092
+ if (command === "page" && argv[1]) {
193093
+ const validActions = ["add"];
193094
+ if (validActions.includes(argv[1])) {
193095
+ pageAction = argv[1];
193096
+ pagePath = argv[2];
193073
193097
  }
193074
193098
  }
193075
193099
  if (command === "list-events" && argv[1]) {
@@ -193102,16 +193126,23 @@ var parseArgs = (argv) => {
193102
193126
  componentType,
193103
193127
  eventName,
193104
193128
  removeComponentName,
193105
- listFilter
193129
+ listFilter,
193130
+ cardAction,
193131
+ cardAjax,
193132
+ cardIo,
193133
+ pageAction,
193134
+ pagePath
193106
193135
  };
193107
193136
  };
193108
193137
  var printUsage = () => {
193109
193138
  console.log("Usage: pieui <command> [options]");
193110
193139
  console.log("");
193111
193140
  console.log("Commands:");
193141
+ console.log(" create <AppName> Create a Next.js app and run pieui init inside it");
193112
193142
  console.log(" create-pie-app <AppName> Create a blank Next.js web template for PieUI (bun create next-app under the hood)");
193113
193143
  console.log(" init Initialize piecomponents directory with registry.ts");
193114
- console.log(" add [type] <ComponentName> Create a new component in piecomponents directory");
193144
+ console.log(" card add [type] <ComponentName> [--io] [--ajax] Create a new component in piecomponents directory");
193145
+ console.log(" page add <path> Create app/<path>/page.tsx from the standard Pie page template");
193115
193146
  console.log(" push <ComponentName> Archive piecomponents/<ComponentName> and upload to PieUI server");
193116
193147
  console.log(" pull <ComponentName> Download archive from PieUI server and extract into piecomponents/<ComponentName>");
193117
193148
  console.log(" remote-remove <ComponentName> Remove remote component from PieUI server");
@@ -193121,13 +193152,17 @@ var printUsage = () => {
193121
193152
  console.log(" postbuild Scan for components and generate manifest");
193122
193153
  console.log(" list [filter] List registered components in a table");
193123
193154
  console.log("");
193124
- console.log("Component types for add command:");
193155
+ console.log("Component types for card add command:");
193125
193156
  console.log(" simple Simple component (only data prop)");
193126
193157
  console.log(" complex Complex component (data + children props)");
193127
193158
  console.log(" simple-container Container with single content (data + content)");
193128
193159
  console.log(" complex-container Container with array content (data + content[])");
193129
193160
  console.log(" (default if type not specified)");
193130
193161
  console.log("");
193162
+ console.log("Options for card add:");
193163
+ console.log(" --io Add realtime support fields to the generated data interface");
193164
+ console.log(" --ajax Add AJAX request fields to the generated data interface");
193165
+ console.log("");
193131
193166
  console.log("Options for init:");
193132
193167
  console.log(" --out-dir <dir>, -o <dir> Base directory for piecomponents (default: .)");
193133
193168
  console.log("");
@@ -193154,11 +193189,14 @@ var printUsage = () => {
193154
193189
  console.log("");
193155
193190
  console.log("Examples:");
193156
193191
  console.log(" pieui init");
193192
+ console.log(" pieui create my-pie-app");
193157
193193
  console.log(" pieui create-pie-app my-pie-app");
193158
193194
  console.log(" pieui init --out-dir packages/app");
193159
- console.log(" pieui add MyCustomCard # Creates complex-container by default");
193160
- console.log(" pieui add simple MySimpleCard # Creates simple component");
193161
- console.log(" pieui add complex-container MyContainerCard # Creates complex container");
193195
+ console.log(" pieui card add MyCustomCard # Creates complex-container by default");
193196
+ console.log(" pieui card add simple MySimpleCard # Creates simple component");
193197
+ console.log(" pieui card add complex-container MyContainerCard # Creates complex container");
193198
+ console.log(" pieui card add simple LiveCard --io --ajax # Adds realtime and AJAX fields");
193199
+ console.log(" pieui page add chat # Creates app/chat/page.tsx");
193162
193200
  console.log(" pieui postbuild --append --out-dir dist");
193163
193201
  console.log(" pieui list # List all components");
193164
193202
  console.log(" pieui list simple # List only simple components");
@@ -193175,7 +193213,7 @@ var import_fs = __toESM(require("fs"));
193175
193213
  var import_path = __toESM(require("path"));
193176
193214
 
193177
193215
  // src/code/templates/componentIndex.ts
193178
- var componentIndexTemplate = (componentName) => `import { registerPieComponent } from "@piedata/pieui";
193216
+ var componentIndexTemplate = (componentName) => `import { registerPieComponent } from "@swarm.ing/pieui";
193179
193217
  import ${componentName} from "./ui/${componentName}";
193180
193218
 
193181
193219
  export default registerPieComponent({
@@ -193185,26 +193223,204 @@ export default registerPieComponent({
193185
193223
  `;
193186
193224
 
193187
193225
  // src/code/templates/componentTypes.ts
193188
- var componentTypesTemplate = (componentName, baseInterface) => `import { ${baseInterface} } from '@piedata/pieui'
193226
+ var ioFields = ` useSocketioSupport?: boolean
193227
+ useCentrifugeSupport?: boolean
193228
+ useMittSupport?: boolean
193229
+ centrifugeChannel?: string`;
193230
+ var ajaxFields = ` pathname?: string
193231
+ depsNames: string[]
193232
+ kwargs: Record<string, string | number | boolean>`;
193233
+ var componentTypesTemplate = (componentName, baseInterface, options = {}) => {
193234
+ const extraSections = [options.io ? ioFields : "", options.ajax ? ajaxFields : ""].filter(Boolean).join(`
193235
+
193236
+ `);
193237
+ const extraFields = extraSections ? `
193238
+
193239
+ ${extraSections}` : "";
193240
+ return `import { ${baseInterface} } from '@swarm.ing/pieui'
193189
193241
 
193190
193242
  export interface ${componentName}Data {
193191
193243
  name: string
193192
193244
  // Add your component-specific props here
193245
+ ${extraFields}
193193
193246
  }
193194
193247
 
193195
193248
  export type ${componentName}Props = ${baseInterface}<${componentName}Data>
193196
193249
  `;
193250
+ };
193251
+
193252
+ // src/code/templates/env.ts
193253
+ var envTemplate = () => `PIE_ENABLE_RENDERING_LOG=true
193254
+ PIE_API_SERVER=http://localhost:8008/
193255
+ PIE_CENTRIFUGE_SERVER=wss://localhost:8000/connection/websocket
193256
+
193257
+ NEXT_PUBLIC_PIE_ENABLE_RENDERING_LOG=true
193258
+ NEXT_PUBLIC_PIE_API_SERVER=http://localhost:8008/
193259
+ NEXT_PUBLIC_PIE_CENTRIFUGE_SERVER=wss://localhost:8000/connection/websocket
193260
+ `;
193261
+
193262
+ // src/code/templates/homePage.ts
193263
+ var homePageTemplate = `"use client";
193264
+
193265
+ import PiePage from "@/app/_shared/page";
193266
+ import { Suspense } from "react";
193267
+
193268
+ export default function HomePage() {
193269
+ return (
193270
+ <Suspense fallback={<></>}>
193271
+ <PiePage />
193272
+ </Suspense>
193273
+ );
193274
+ }
193275
+ `;
193276
+
193277
+ // src/code/templates/loadingScreen.ts
193278
+ var loadingScreenTemplate = `"use client";
193279
+
193280
+ export default function LoadingScreen() {
193281
+ return (
193282
+ <div className="flex min-h-screen items-center justify-center text-sm text-neutral-500">
193283
+ Loading...
193284
+ </div>
193285
+ );
193286
+ }
193287
+ `;
193288
+
193289
+ // src/code/templates/rootLayout.ts
193290
+ var rootLayoutTemplate = `import type { Metadata } from "next";
193291
+ import "./globals.css";
193292
+
193293
+ export const metadata: Metadata = {
193294
+ title: "PieUI Project",
193295
+ description: "Generated by PieUI.",
193296
+ applicationName: "PieUI Project",
193297
+ icons: {
193298
+ icon: "/favicon.ico",
193299
+ shortcut: "/favicon.ico",
193300
+ },
193301
+ };
193302
+
193303
+ export default function RootLayout({
193304
+ children,
193305
+ }: Readonly<{
193306
+ children: React.ReactNode;
193307
+ }>) {
193308
+ return (
193309
+ <html lang="en">
193310
+ <body>{children}</body>
193311
+ </html>
193312
+ );
193313
+ }
193314
+ `;
193315
+
193316
+ // src/code/templates/sharedPage.ts
193317
+ var sharedPageTemplate = `"use client";
193318
+
193319
+ import { useRouter } from "next/navigation";
193320
+ import { PieRoot } from "@swarm.ing/pieui";
193321
+ import "@/piecomponents/registry";
193322
+ import { usePathname, useSearchParams } from "next/navigation";
193323
+
193324
+ export default function PiePage() {
193325
+ const router = useRouter();
193326
+ const pathname = usePathname();
193327
+ const searchParams = useSearchParams();
193328
+ const search = searchParams.toString();
193329
+
193330
+ return (
193331
+ <PieRoot
193332
+ location={{ pathname, search }}
193333
+ config={{
193334
+ apiServer: process.env.PIE_API_SERVER!,
193335
+ centrifugeServer: process.env.PIE_CENTRIFUGE_SERVER!,
193336
+ enableRenderingLog: true,
193337
+ }}
193338
+ onNavigate={(url) => router.push(url)}
193339
+ fallback={<></>}
193340
+ />
193341
+ );
193342
+ }
193343
+ `;
193197
193344
 
193198
- // src/code/templates/simpleComponent.ts
193199
- var simpleComponentTemplate = (componentName) => `import React from 'react'
193200
- import { PieCard } from '@piedata/pieui'
193345
+ // src/code/templates/nextConfig.ts
193346
+ var REQUIRED_NEXT_CONFIG_ENV_KEYS = [
193347
+ "PIE_API_SERVER",
193348
+ "PIE_CENTRIFUGE_SERVER",
193349
+ "PIE_ENABLE_RENDERING_LOG"
193350
+ ];
193351
+ var nextConfigTemplate = () => `import type { NextConfig } from "next";
193352
+
193353
+ const nextConfig: NextConfig = {
193354
+ output: "standalone",
193355
+ reactCompiler: false,
193356
+ env: {
193357
+ PIE_API_SERVER: process.env.PIE_API_SERVER,
193358
+ PIE_CENTRIFUGE_SERVER: process.env.PIE_CENTRIFUGE_SERVER,
193359
+ PIE_ENABLE_RENDERING_LOG: process.env.PIE_ENABLE_RENDERING_LOG,
193360
+ },
193361
+ reactStrictMode: true,
193362
+ transpilePackages: ["@swarm.ing/pieui"],
193363
+ };
193364
+
193365
+ export default nextConfig;
193366
+ `;
193367
+
193368
+ // src/code/templates/pages/components/shared.ts
193369
+ var dataDestructureFor = (options = {}) => {
193370
+ if (!options.io && !options.ajax) {
193371
+ return "const { name } = data";
193372
+ }
193373
+ const fields = ["name"];
193374
+ if (options.io) {
193375
+ fields.push("useSocketioSupport", "useCentrifugeSupport", "useMittSupport", "centrifugeChannel");
193376
+ }
193377
+ if (options.ajax) {
193378
+ fields.push("pathname", "depsNames", "kwargs");
193379
+ }
193380
+ return `const {
193381
+ ${fields.join(`,
193382
+ `)},
193383
+ } = data`;
193384
+ };
193385
+ var pieCardOpeningTagFor = (componentName, options = {}) => {
193386
+ if (!options.io) {
193387
+ return `<PieCard card='${componentName}' data={data}>`;
193388
+ }
193389
+ return `<PieCard
193390
+ card='${componentName}'
193391
+ data={data}
193392
+ useSocketioSupport={useSocketioSupport}
193393
+ useCentrifugeSupport={useCentrifugeSupport}
193394
+ useMittSupport={useMittSupport}
193395
+ centrifugeChannel={centrifugeChannel}
193396
+ methods={{
193397
+ }}
193398
+ >`;
193399
+ };
193400
+ var ajaxSubmitDeclarationFor = (options = {}) => {
193401
+ if (!options.ajax) {
193402
+ return "";
193403
+ }
193404
+ return `
193405
+ const ajaxSubmit = useAjaxSubmit(
193406
+ setUiAjaxConfiguration,
193407
+ kwargs,
193408
+ depsNames,
193409
+ pathname
193410
+ )`;
193411
+ };
193412
+
193413
+ // src/code/templates/pages/components/simpleComponent.ts
193414
+ var simpleComponentTemplate = (componentName, options = {}) => `import React from 'react'
193415
+ import { PieCard${options.ajax ? ", useAjaxSubmit, type SetUiAjaxConfigurationType" : ""} } from '@swarm.ing/pieui'
193201
193416
  import { ${componentName}Props } from '../types'
193202
193417
 
193203
- const ${componentName} = ({ data }: ${componentName}Props) => {
193204
- const { name } = data
193418
+ const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }: ${componentName}Props${options.ajax ? " & { setUiAjaxConfiguration?: SetUiAjaxConfigurationType }" : ""}) => {
193419
+ ${dataDestructureFor(options)}
193420
+ ${ajaxSubmitDeclarationFor(options)}
193205
193421
 
193206
193422
  return (
193207
- <PieCard card='${componentName}' data={data}>
193423
+ ${pieCardOpeningTagFor(componentName, options)}
193208
193424
  <div>
193209
193425
  <h2>${componentName}</h2>
193210
193426
  {/* Add your component logic here */}
@@ -193215,17 +193431,17 @@ const ${componentName} = ({ data }: ${componentName}Props) => {
193215
193431
 
193216
193432
  export default ${componentName}
193217
193433
  `;
193218
-
193219
- // src/code/templates/complexComponent.ts
193220
- var complexComponentTemplate = (componentName) => `import React from 'react'
193221
- import { PieCard } from '@piedata/pieui'
193434
+ // src/code/templates/pages/components/complexComponent.ts
193435
+ var complexComponentTemplate = (componentName, options = {}) => `import React from 'react'
193436
+ import { PieCard${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
193222
193437
  import { ${componentName}Props } from '../types'
193223
193438
 
193224
- const ${componentName} = ({ data }: ${componentName}Props) => {
193225
- const { name } = data
193439
+ const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }: ${componentName}Props) => {
193440
+ ${dataDestructureFor(options)}
193441
+ ${ajaxSubmitDeclarationFor(options)}
193226
193442
 
193227
193443
  return (
193228
- <PieCard card='${componentName}' data={data}>
193444
+ ${pieCardOpeningTagFor(componentName, options)}
193229
193445
  <div>
193230
193446
  <h2>${componentName}</h2>
193231
193447
  {/* Add your component logic here */}
@@ -193236,10 +193452,9 @@ const ${componentName} = ({ data }: ${componentName}Props) => {
193236
193452
 
193237
193453
  export default ${componentName}
193238
193454
  `;
193239
-
193240
- // src/code/templates/simpleContainerComponent.ts
193241
- var simpleContainerComponentTemplate = (componentName) => `import React, { useContext } from 'react'
193242
- import { PieCard, UI, UIRendererContext } from '@piedata/pieui'
193455
+ // src/code/templates/pages/components/simpleContainerComponent.ts
193456
+ var simpleContainerComponentTemplate = (componentName, options = {}) => `import React, { useContext } from 'react'
193457
+ import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
193243
193458
  import { ${componentName}Props } from '../types'
193244
193459
 
193245
193460
  const ${componentName} = ({
@@ -193247,11 +193462,12 @@ const ${componentName} = ({
193247
193462
  content,
193248
193463
  setUiAjaxConfiguration,
193249
193464
  }: ${componentName}Props) => {
193250
- const { name } = data
193465
+ ${dataDestructureFor(options)}
193466
+ ${ajaxSubmitDeclarationFor(options)}
193251
193467
  const Renderer = useContext(UIRendererContext) ?? UI
193252
193468
 
193253
193469
  return (
193254
- <PieCard card='${componentName}' data={data}>
193470
+ ${pieCardOpeningTagFor(componentName, options)}
193255
193471
  <div>
193256
193472
  <h2>${componentName}</h2>
193257
193473
  {/* Add your component logic here */}
@@ -193268,10 +193484,9 @@ const ${componentName} = ({
193268
193484
 
193269
193485
  export default ${componentName}
193270
193486
  `;
193271
-
193272
- // src/code/templates/complexContainerComponent.ts
193273
- var complexContainerComponentTemplate = (componentName) => `import React, { useContext } from 'react'
193274
- import { PieCard, UI, UIRendererContext } from '@piedata/pieui'
193487
+ // src/code/templates/pages/components/complexContainerComponent.ts
193488
+ var complexContainerComponentTemplate = (componentName, options = {}) => `import React, { useContext } from 'react'
193489
+ import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
193275
193490
  import { ${componentName}Props } from '../types'
193276
193491
 
193277
193492
  const ${componentName} = ({
@@ -193279,11 +193494,12 @@ const ${componentName} = ({
193279
193494
  content,
193280
193495
  setUiAjaxConfiguration,
193281
193496
  }: ${componentName}Props) => {
193282
- const { name } = data
193497
+ ${dataDestructureFor(options)}
193498
+ ${ajaxSubmitDeclarationFor(options)}
193283
193499
  const Renderer = useContext(UIRendererContext) ?? UI
193284
193500
 
193285
193501
  return (
193286
- <PieCard card='${componentName}' data={data}>
193502
+ ${pieCardOpeningTagFor(componentName, options)}
193287
193503
  <div>
193288
193504
  <h2>${componentName}</h2>
193289
193505
  {/* Add your component logic here */}
@@ -193301,33 +193517,22 @@ const ${componentName} = ({
193301
193517
 
193302
193518
  export default ${componentName}
193303
193519
  `;
193520
+ // src/code/templates/pages/page.ts
193521
+ var pageTemplate = (pageComponentName) => `"use client";
193304
193522
 
193305
- // src/code/templates/nextConfig.ts
193306
- var REQUIRED_NEXT_CONFIG_ENV_KEYS = [
193307
- "PIE_API_SERVER",
193308
- "PIE_CENTRIFUGE_SERVER",
193309
- "PIE_ENABLE_RENDERING_LOG",
193310
- "PIE_PLATFORM"
193311
- ];
193312
- var nextConfigTemplate = () => `import type { NextConfig } from "next";
193313
-
193314
- const nextConfig: NextConfig = {
193315
- output: "standalone",
193316
- reactCompiler: false,
193317
- env: {
193318
- PIE_API_SERVER: process.env.PIE_API_SERVER,
193319
- PIE_CENTRIFUGE_SERVER: process.env.PIE_CENTRIFUGE_SERVER,
193320
- PIE_ENABLE_RENDERING_LOG: process.env.PIE_ENABLE_RENDERING_LOG,
193321
- PIE_PLATFORM: process.env.PIE_PLATFORM || "telegram",
193322
- },
193323
- reactStrictMode: true,
193324
- transpilePackages: ["@piedata/pieui"],
193325
- };
193523
+ import PiePage from "@/app/_shared/page";
193524
+ import { Suspense } from "react";
193326
193525
 
193327
- export default nextConfig;
193526
+ export default function ${pageComponentName}() {
193527
+ return (
193528
+ <Suspense fallback={<></>}>
193529
+ <PiePage />
193530
+ </Suspense>
193531
+ );
193532
+ }
193328
193533
  `;
193329
193534
 
193330
- // src/code/templates/index.ts
193535
+ // src/code/templates/pages/index.ts
193331
193536
  var BASE_INTERFACE_BY_TYPE = {
193332
193537
  simple: "PieSimpleComponentProps",
193333
193538
  complex: "PieComplexComponentProps",
@@ -193335,17 +193540,17 @@ var BASE_INTERFACE_BY_TYPE = {
193335
193540
  "complex-container": "PieComplexContainerComponentProps"
193336
193541
  };
193337
193542
  var baseInterfaceFor = (componentType) => BASE_INTERFACE_BY_TYPE[componentType];
193338
- var componentTemplateFor = (componentType, componentName) => {
193543
+ var componentTemplateFor = (componentType, componentName, options = {}) => {
193339
193544
  switch (componentType) {
193340
193545
  case "simple":
193341
- return simpleComponentTemplate(componentName);
193546
+ return simpleComponentTemplate(componentName, options);
193342
193547
  case "complex":
193343
- return complexComponentTemplate(componentName);
193548
+ return complexComponentTemplate(componentName, options);
193344
193549
  case "simple-container":
193345
- return simpleContainerComponentTemplate(componentName);
193550
+ return simpleContainerComponentTemplate(componentName, options);
193346
193551
  case "complex-container":
193347
193552
  default:
193348
- return complexContainerComponentTemplate(componentName);
193553
+ return complexContainerComponentTemplate(componentName, options);
193349
193554
  }
193350
193555
  };
193351
193556
 
@@ -193375,7 +193580,7 @@ var initCommand = (outDir) => {
193375
193580
  }
193376
193581
  const tailwindConfigPath = import_path.default.join(resolvedOutDir, "tailwind.config.js");
193377
193582
  const tailwindConfigTsPath = import_path.default.join(resolvedOutDir, "tailwind.config.ts");
193378
- const pieuiContentPath = "./node_modules/@piedata/pieui/dist/**/*.{js,mjs,ts,jsx,tsx}";
193583
+ const pieuiContentPath = "./node_modules/@swarm.ing/pieui/dist/**/*.{js,mjs,ts,jsx,tsx}";
193379
193584
  let configPath = null;
193380
193585
  if (import_fs.default.existsSync(tailwindConfigPath)) {
193381
193586
  configPath = tailwindConfigPath;
@@ -193418,7 +193623,7 @@ var initCommand = (outDir) => {
193418
193623
  console.log("[pieui] Initialization complete!");
193419
193624
  console.log("[pieui] Next steps:");
193420
193625
  console.log(' 1. Import "./piecomponents/registry" in your app entry point');
193421
- console.log(' 2. Use "pieui add <ComponentName>" to create new components');
193626
+ console.log(' 2. Use "pieui card add <ComponentName>" to create new components');
193422
193627
  };
193423
193628
  var ensureNextConfig = (resolvedOutDir) => {
193424
193629
  const candidates = [
@@ -193455,12 +193660,7 @@ var ensureNextConfig = (resolvedOutDir) => {
193455
193660
  }
193456
193661
  };
193457
193662
  var CONFIG_OBJECT_OPEN = /(const\s+nextConfig\s*(?::\s*[A-Za-z_][\w.]*)?\s*=\s*|module\.exports\s*=\s*|export\s+default\s*)\{/;
193458
- var envEntryFor = (key) => {
193459
- if (key === "PIE_PLATFORM") {
193460
- return ` ${key}: process.env.${key} || "telegram",`;
193461
- }
193462
- return ` ${key}: process.env.${key},`;
193463
- };
193663
+ var envEntryFor = (key) => ` ${key}: process.env.${key},`;
193464
193664
  var ensureEnvKeys = (content) => {
193465
193665
  const missingKeys = REQUIRED_NEXT_CONFIG_ENV_KEYS.filter((key) => !content.includes(key));
193466
193666
  if (missingKeys.length === 0)
@@ -193493,16 +193693,16 @@ ${missingKeys.map(envEntryFor).join(`
193493
193693
  var ensureTranspilePieui = (content) => {
193494
193694
  const match = content.match(/transpilePackages\s*:\s*\[([\s\S]*?)]/);
193495
193695
  if (match) {
193496
- if (match[1].includes("@piedata/pieui"))
193696
+ if (match[1].includes("@swarm.ing/pieui"))
193497
193697
  return content;
193498
193698
  const inner = match[1].trim();
193499
193699
  const separator = inner.length > 0 ? ", " : "";
193500
- console.log('[pieui] Adding "@piedata/pieui" to transpilePackages');
193501
- return content.replace(match[0], `transpilePackages: [${inner}${separator}"@piedata/pieui"]`);
193700
+ console.log('[pieui] Adding "@swarm.ing/pieui" to transpilePackages');
193701
+ return content.replace(match[0], `transpilePackages: [${inner}${separator}"@swarm.ing/pieui"]`);
193502
193702
  }
193503
- const inserted = insertIntoConfigObject(content, ' transpilePackages: ["@piedata/pieui"],');
193703
+ const inserted = insertIntoConfigObject(content, ' transpilePackages: ["@swarm.ing/pieui"],');
193504
193704
  if (inserted) {
193505
- console.log('[pieui] Adding transpilePackages: ["@piedata/pieui"]');
193705
+ console.log('[pieui] Adding transpilePackages: ["@swarm.ing/pieui"]');
193506
193706
  return inserted;
193507
193707
  }
193508
193708
  console.log("[pieui] Warning: could not locate nextConfig object to add transpilePackages automatically");
@@ -193557,10 +193757,10 @@ var updateRegistryFile = (registryPath, componentName, componentDir) => {
193557
193757
  `;
193558
193758
  import_fs3.default.writeFileSync(registryPath, registryContent, "utf8");
193559
193759
  };
193560
- var addCommand = (componentName, componentType = "complex-container") => {
193760
+ var addCommand = (componentName, componentType = "complex-container", options = {}) => {
193561
193761
  if (!componentName) {
193562
193762
  console.error("[pieui] Error: Component name is required");
193563
- console.log("Usage: pieui add [type] <ComponentName>");
193763
+ console.log("Usage: pieui card add [type] <ComponentName>");
193564
193764
  process.exit(1);
193565
193765
  }
193566
193766
  if (!/^[A-Z][a-zA-Z0-9]+$/.test(componentName)) {
@@ -193583,8 +193783,8 @@ var addCommand = (componentName, componentType = "complex-container") => {
193583
193783
  import_fs3.default.mkdirSync(import_path3.default.join(componentDir, "ui"), { recursive: true });
193584
193784
  import_fs3.default.mkdirSync(import_path3.default.join(componentDir, "types"), { recursive: true });
193585
193785
  import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "index.ts"), componentIndexTemplate(componentName), "utf8");
193586
- import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "types", "index.ts"), componentTypesTemplate(componentName, baseInterfaceFor(componentType)), "utf8");
193587
- import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "ui", `${componentName}.tsx`), componentTemplateFor(componentType, componentName), "utf8");
193786
+ import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "types", "index.ts"), componentTypesTemplate(componentName, baseInterfaceFor(componentType), options), "utf8");
193787
+ import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "ui", `${componentName}.tsx`), componentTemplateFor(componentType, componentName, options), "utf8");
193588
193788
  const registryPath = resolveRegistryPath(pieComponentsDir);
193589
193789
  updateRegistryFile(registryPath, componentName, componentDir);
193590
193790
  } catch (error) {
@@ -193599,6 +193799,8 @@ var addCommand = (componentName, componentType = "complex-container") => {
193599
193799
  console.log(`[pieui] Updated registry.ts with new component`);
193600
193800
  console.log("");
193601
193801
  console.log(`[pieui] Component type: ${componentType}`);
193802
+ console.log(`[pieui] IO fields: ${options.io ? "enabled" : "disabled"}`);
193803
+ console.log(`[pieui] AJAX fields: ${options.ajax ? "enabled" : "disabled"}`);
193602
193804
  switch (componentType) {
193603
193805
  case "simple":
193604
193806
  console.log(" - Props: data only");
@@ -197911,7 +198113,7 @@ var postbuildCommand = async (srcDir, outDir, append) => {
197911
198113
  let existingEntries = [];
197912
198114
  if (append) {
197913
198115
  console.log("[pieui] Append mode enabled - loading existing pieui components");
197914
- const nodeModulesPath = import_path9.default.join(process.cwd(), "node_modules", "@piedata", "pieui", "dist", MANIFEST_FILENAME);
198116
+ const nodeModulesPath = import_path9.default.join(process.cwd(), "node_modules", "@swarm.ing", "pieui", "dist", MANIFEST_FILENAME);
197915
198117
  if (import_fs7.default.existsSync(nodeModulesPath)) {
197916
198118
  try {
197917
198119
  const existingManifest = import_fs7.default.readFileSync(nodeModulesPath, "utf8");
@@ -198177,118 +198379,128 @@ ${text2}` : ""}`);
198177
198379
  [pieui] ${text}` : ""}`);
198178
198380
  };
198179
198381
 
198180
- // src/code/commands/createPieApp.ts
198382
+ // src/code/commands/pageAdd.ts
198181
198383
  var import_fs11 = __toESM(require("fs"));
198182
198384
  var import_path13 = __toESM(require("path"));
198385
+ var normalizePagePath = (pagePath) => {
198386
+ const trimmed = pagePath.trim();
198387
+ if (!trimmed) {
198388
+ throw new Error("Path is required for page add command");
198389
+ }
198390
+ const normalizedSlashes = trimmed.replace(/\\/g, "/");
198391
+ const withoutRelativePrefix = normalizedSlashes.replace(/^\.\/+/, "");
198392
+ const withoutAppPrefix = withoutRelativePrefix.replace(/^app\//, "");
198393
+ const withoutEdgeSlashes = withoutAppPrefix.replace(/^\/+|\/+$/g, "");
198394
+ const normalized = import_path13.default.posix.normalize(withoutEdgeSlashes);
198395
+ if (!normalized || normalized === ".") {
198396
+ throw new Error("Path is required for page add command");
198397
+ }
198398
+ if (normalized === ".." || normalized.startsWith("../") || normalized.includes("/../")) {
198399
+ throw new Error("Page path must stay inside the app directory");
198400
+ }
198401
+ return normalized;
198402
+ };
198403
+ var toPascalCase = (value2) => value2.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
198404
+ var pageComponentNameForPath = (pagePath) => {
198405
+ const segments = pagePath.split("/").map((segment) => toPascalCase(segment)).filter(Boolean);
198406
+ if (segments.length === 0) {
198407
+ return "Page";
198408
+ }
198409
+ return `${segments.join("")}Page`;
198410
+ };
198411
+ var pageAddCommand = (pagePath) => {
198412
+ const normalizedPath = normalizePagePath(pagePath);
198413
+ const pageComponentName = pageComponentNameForPath(normalizedPath);
198414
+ const appDir = import_path13.default.join(process.cwd(), "app");
198415
+ const targetFile = import_path13.default.join(appDir, normalizedPath, "page.tsx");
198416
+ const relativeTarget = import_path13.default.relative(appDir, targetFile);
198417
+ if (relativeTarget.startsWith("..") || import_path13.default.isAbsolute(relativeTarget)) {
198418
+ throw new Error("Page path must stay inside the app directory");
198419
+ }
198420
+ if (import_fs11.default.existsSync(targetFile)) {
198421
+ console.error(`[pieui] Error: Page already exists at app/${normalizedPath}/page.tsx`);
198422
+ process.exit(1);
198423
+ }
198424
+ import_fs11.default.mkdirSync(import_path13.default.dirname(targetFile), { recursive: true });
198425
+ import_fs11.default.writeFileSync(targetFile, pageTemplate(pageComponentName), "utf8");
198426
+ console.log(`[pieui] Page created successfully at app/${normalizedPath}/page.tsx`);
198427
+ };
198428
+
198429
+ // src/code/commands/create.ts
198430
+ var import_fs12 = __toESM(require("fs"));
198431
+ var import_path14 = __toESM(require("path"));
198183
198432
  var import_child_process = require("child_process");
198184
198433
  var DEFAULT_TEMPLATE_SPEC = "next-app@latest";
198185
- var SHARED_TEMPLATE_DIR_ENV = "PIEUI_SHARED_TEMPLATE_DIR";
198186
- var AI_EXCHANGE_BOT_DIR_ENV = "PIEUI_AI_EXCHANGE_BOT_DIR";
198187
- var BACKEND_LINK_COMMENT = "// TODO(pie-backend): Link generated Python Unicorn backend routes here once backend template sync is enabled.";
198188
- var updateNextScriptsToBun = (packageJsonPath) => {
198189
- if (!import_fs11.default.existsSync(packageJsonPath))
198434
+ var clearDirectory = (targetDir) => {
198435
+ if (!import_fs12.default.existsSync(targetDir))
198190
198436
  return;
198191
- try {
198192
- const pkg = JSON.parse(import_fs11.default.readFileSync(packageJsonPath, "utf8"));
198193
- if (!pkg.scripts)
198194
- return;
198195
- const updates = {
198196
- dev: "bun --bun next dev",
198197
- build: "bun --bun next build",
198198
- start: "bun --bun next start"
198199
- };
198200
- for (const [scriptName, scriptValue] of Object.entries(updates)) {
198201
- if (pkg.scripts[scriptName]) {
198202
- pkg.scripts[scriptName] = scriptValue;
198203
- }
198204
- }
198205
- import_fs11.default.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
198206
- `, "utf8");
198207
- } catch {
198437
+ for (const entry of import_fs12.default.readdirSync(targetDir)) {
198438
+ import_fs12.default.rmSync(import_path14.default.join(targetDir, entry), { recursive: true, force: true });
198208
198439
  }
198209
198440
  };
198210
- var appendBackendLinkComment = (pagePath) => {
198211
- if (!import_fs11.default.existsSync(pagePath))
198212
- return;
198213
- const page = import_fs11.default.readFileSync(pagePath, "utf8");
198214
- if (page.includes(BACKEND_LINK_COMMENT))
198215
- return;
198216
- import_fs11.default.writeFileSync(pagePath, `${page.trimEnd()}
198217
-
198218
- ${BACKEND_LINK_COMMENT}
198219
- `, "utf8");
198441
+ var writeFile = (filePath, content) => {
198442
+ import_fs12.default.mkdirSync(import_path14.default.dirname(filePath), { recursive: true });
198443
+ import_fs12.default.writeFileSync(filePath, content, "utf8");
198220
198444
  };
198221
- var uniq = (items) => [...new Set(items)];
198222
- var isDirectory = (target) => {
198223
- try {
198224
- return import_fs11.default.statSync(target).isDirectory();
198225
- } catch {
198226
- return false;
198227
- }
198228
- };
198229
- var resolveSharedTemplateDir = () => {
198230
- const explicitSharedDir = process.env[SHARED_TEMPLATE_DIR_ENV];
198231
- if (explicitSharedDir) {
198232
- const normalized = import_path13.default.resolve(explicitSharedDir);
198233
- if (!isDirectory(normalized)) {
198234
- throw new Error(`${SHARED_TEMPLATE_DIR_ENV} points to a missing directory: ${normalized}`);
198235
- }
198236
- return normalized;
198237
- }
198238
- const cwd = process.cwd();
198239
- const baseDirs = [cwd, import_path13.default.resolve(cwd, ".."), import_path13.default.resolve(cwd, "../..")];
198240
- const explicitRepoDir = process.env[AI_EXCHANGE_BOT_DIR_ENV];
198241
- if (explicitRepoDir) {
198242
- baseDirs.unshift(import_path13.default.resolve(explicitRepoDir));
198243
- }
198244
- const repoNames = ["ai-exchange-bot", "ai-exchange-web", "a-exchange-web"];
198245
- const repoCandidates = uniq([
198246
- ...baseDirs,
198247
- ...baseDirs.flatMap((base) => repoNames.map((name) => import_path13.default.join(base, name)))
198248
- ]).filter((candidate) => isDirectory(candidate));
198249
- const sharedSubpaths = [
198250
- "_shared",
198251
- "src/_shared",
198252
- "app/_shared",
198253
- "pages/_shared",
198254
- "pages/components/_shared",
198255
- "apps/web/_shared",
198256
- "apps/web/src/_shared"
198445
+ var resolveTemplatePublicDir = () => {
198446
+ const entrypointPath = process.argv[1] ? import_path14.default.resolve(process.argv[1]) : import_path14.default.join(process.cwd(), "src", "cli.ts");
198447
+ const entrypointDir = import_path14.default.dirname(entrypointPath);
198448
+ const candidateDirs = [
198449
+ import_path14.default.join(entrypointDir, "code", "public"),
198450
+ import_path14.default.join(process.cwd(), "src", "code", "public")
198257
198451
  ];
198258
- for (const repoDir of repoCandidates) {
198259
- for (const subpath of sharedSubpaths) {
198260
- const candidate = import_path13.default.join(repoDir, subpath);
198261
- if (isDirectory(candidate)) {
198262
- return candidate;
198263
- }
198452
+ for (const candidateDir of candidateDirs) {
198453
+ if (import_fs12.default.existsSync(candidateDir)) {
198454
+ return candidateDir;
198264
198455
  }
198265
198456
  }
198266
- throw new Error([
198267
- "Could not locate a _shared template directory from ai-exchange-bot.",
198268
- `Set ${SHARED_TEMPLATE_DIR_ENV}=/absolute/path/to/_shared`,
198269
- `or ${AI_EXCHANGE_BOT_DIR_ENV}=/absolute/path/to/ai-exchange-bot.`
198270
- ].join(" "));
198457
+ throw new Error("[pieui] Could not resolve bundled public template assets");
198271
198458
  };
198272
- var copySharedTemplate = (sharedTemplateDir, appDir) => {
198273
- const destination = import_path13.default.join(appDir, "_shared");
198274
- import_fs11.default.cpSync(sharedTemplateDir, destination, { recursive: true, force: true });
198459
+ var scaffoldCreateAppFiles = (appDir) => {
198460
+ clearDirectory(import_path14.default.join(appDir, "public"));
198461
+ writeFile(import_path14.default.join(appDir, "app", "_shared", "page.tsx"), sharedPageTemplate);
198462
+ writeFile(import_path14.default.join(appDir, "app", "page.tsx"), homePageTemplate);
198463
+ writeFile(import_path14.default.join(appDir, "app", "layout.tsx"), rootLayoutTemplate);
198464
+ import_fs12.default.rmSync(import_path14.default.join(appDir, "app", "_shared", "simple.tsx"), {
198465
+ force: true
198466
+ });
198467
+ import_fs12.default.rmSync(import_path14.default.join(appDir, "app", "piecache.json"), { force: true });
198468
+ import_fs12.default.rmSync(import_path14.default.join(appDir, "app", "favicon.ico"), { force: true });
198469
+ writeFile(import_path14.default.join(appDir, "components", "LoadingScreen.tsx"), loadingScreenTemplate);
198470
+ import_fs12.default.rmSync(import_path14.default.join(appDir, "components", "ErrorToast.tsx"), { force: true });
198471
+ import_fs12.default.cpSync(resolveTemplatePublicDir(), import_path14.default.join(appDir, "public"), {
198472
+ recursive: true,
198473
+ force: true
198474
+ });
198275
198475
  };
198276
- var createPieAppCommand = (appName) => {
198476
+ var runBunCommand = (bunBin, args, cwd) => {
198477
+ const result = import_child_process.spawnSync(bunBin, args, {
198478
+ cwd,
198479
+ stdio: "inherit",
198480
+ env: process.env
198481
+ });
198482
+ if (result.error) {
198483
+ throw result.error;
198484
+ }
198485
+ if (result.status !== 0) {
198486
+ throw new Error(`${args.join(" ")} failed (exit code ${result.status ?? "unknown"})`);
198487
+ }
198488
+ };
198489
+ var createCommand = (appName) => {
198277
198490
  const trimmedAppName = appName.trim();
198278
198491
  if (!trimmedAppName) {
198279
- console.error("[pieui] Error: App name is required for create-pie-app command");
198492
+ console.error("[pieui] Error: App name is required for create command");
198280
198493
  process.exit(1);
198281
198494
  }
198282
- const appDir = import_path13.default.resolve(process.cwd(), trimmedAppName);
198283
- if (import_fs11.default.existsSync(appDir)) {
198495
+ const appDir = import_path14.default.resolve(process.cwd(), trimmedAppName);
198496
+ if (import_fs12.default.existsSync(appDir)) {
198284
198497
  console.error(`[pieui] Error: Target directory already exists: ${trimmedAppName}`);
198285
198498
  process.exit(1);
198286
198499
  }
198287
198500
  const bunBin = process.env.PIEUI_CREATE_BUN_BIN || "bun";
198288
198501
  const templateSpec = process.env.PIEUI_CREATE_NEXT_APP_SPEC || DEFAULT_TEMPLATE_SPEC;
198289
- console.log(`[pieui] Creating blank PieUI web template in "${trimmedAppName}"...`);
198290
- const args = ["create", templateSpec, trimmedAppName, "--yes"];
198291
- const result = import_child_process.spawnSync(bunBin, args, {
198502
+ console.log(`[pieui] Creating Next.js app in "${trimmedAppName}"...`);
198503
+ const result = import_child_process.spawnSync(bunBin, ["create", templateSpec, trimmedAppName, "--yes"], {
198292
198504
  cwd: process.cwd(),
198293
198505
  stdio: "inherit",
198294
198506
  env: process.env
@@ -198297,18 +198509,13 @@ var createPieAppCommand = (appName) => {
198297
198509
  throw result.error;
198298
198510
  }
198299
198511
  if (result.status !== 0) {
198300
- throw new Error(`create-pie-app failed (exit code ${result.status ?? "unknown"})`);
198301
- }
198302
- const sharedTemplateDir = resolveSharedTemplateDir();
198303
- copySharedTemplate(sharedTemplateDir, appDir);
198304
- updateNextScriptsToBun(import_path13.default.join(appDir, "package.json"));
198305
- appendBackendLinkComment(import_path13.default.join(appDir, "app", "page.tsx"));
198306
- console.log("[pieui] Template created successfully.");
198307
- console.log(`[pieui] Copied _shared from: ${sharedTemplateDir}`);
198308
- console.log(`[pieui] Next steps:`);
198309
- console.log(` 1. cd ${trimmedAppName}`);
198310
- console.log(` 2. bun install`);
198311
- console.log(` 3. bun run dev`);
198512
+ throw new Error(`create failed (exit code ${result.status ?? "unknown"})`);
198513
+ }
198514
+ scaffoldCreateAppFiles(appDir);
198515
+ initCommand(trimmedAppName);
198516
+ writeFile(import_path14.default.join(appDir, ".env"), envTemplate());
198517
+ runBunCommand(bunBin, ["install"], appDir);
198518
+ runBunCommand(bunBin, ["run", "dev"], appDir);
198312
198519
  };
198313
198520
 
198314
198521
  // src/cli.ts
@@ -198323,28 +198530,65 @@ var main = async () => {
198323
198530
  componentType,
198324
198531
  removeComponentName,
198325
198532
  listFilter,
198326
- eventName
198533
+ eventName,
198534
+ cardAction,
198535
+ cardAjax,
198536
+ cardIo,
198537
+ pageAction,
198538
+ pagePath
198327
198539
  } = parseArgs(process.argv.slice(2));
198328
198540
  console.log(`[pieui] CLI started with command: "${command}"`);
198329
198541
  switch (command) {
198330
198542
  case "init":
198331
198543
  initCommand(outDir);
198332
198544
  return;
198333
- case "create-pie-app":
198545
+ case "create":
198334
198546
  if (!createAppName) {
198335
- console.error("[pieui] Error: App name is required for create-pie-app command");
198547
+ console.error("[pieui] Error: App name is required for create command");
198336
198548
  printUsage();
198337
198549
  process.exit(1);
198338
198550
  }
198339
- createPieAppCommand(createAppName);
198551
+ createCommand(createAppName);
198552
+ return;
198553
+ case "card":
198554
+ if (cardAction !== "add") {
198555
+ console.error("[pieui] Error: Supported card subcommands: add");
198556
+ printUsage();
198557
+ process.exit(1);
198558
+ }
198559
+ if (!componentName) {
198560
+ console.error("[pieui] Error: Component name is required for card add command");
198561
+ printUsage();
198562
+ process.exit(1);
198563
+ }
198564
+ addCommand(componentName, componentType, {
198565
+ ajax: cardAjax,
198566
+ io: cardIo
198567
+ });
198340
198568
  return;
198341
198569
  case "add":
198342
198570
  if (!componentName) {
198343
- console.error("[pieui] Error: Component name is required for add command");
198571
+ console.error("[pieui] Error: Component name is required for card add command");
198572
+ printUsage();
198573
+ process.exit(1);
198574
+ }
198575
+ addCommand(componentName, componentType, {
198576
+ ajax: cardAjax,
198577
+ io: cardIo
198578
+ });
198579
+ return;
198580
+ case "page":
198581
+ if (pageAction !== "add") {
198582
+ console.error("[pieui] Error: Supported page subcommands: add");
198583
+ printUsage();
198584
+ process.exit(1);
198585
+ }
198586
+ if (!pagePath) {
198587
+ console.error("[pieui] Error: Path is required for page add command");
198344
198588
  printUsage();
198345
198589
  process.exit(1);
198346
198590
  }
198347
- addCommand(componentName, componentType);
198591
+ pageAddCommand(pagePath);
198348
198592
  return;
198349
198593
  case "remove":
198350
198594
  if (!removeComponentName) {