create-idia-app 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +104 -0
  2. package/dist/index.js +412 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +33 -0
  5. package/template/.cursor/rules/idia-ui-ds-brain.mdc +32 -0
  6. package/template/.cursor/rules/idia-ui-forms.mdc +34 -0
  7. package/template/.cursor/rules/idia-ui-overlays.mdc +23 -0
  8. package/template/.idia/brain/AGENTS.md +37 -0
  9. package/template/.idia/brain/ai/agents/retrieval-cheatsheet.md +209 -0
  10. package/template/.idia/brain/ai/skills/components/button/SKILL.md +32 -0
  11. package/template/.idia/brain/ai/skills/ds-brain-action-hierarchy/SKILL.md +46 -0
  12. package/template/.idia/brain/ai/skills/ds-brain-forms/SKILL.md +67 -0
  13. package/template/.idia/brain/ai/skills/ds-brain-index/SKILL.md +76 -0
  14. package/template/.idia/brain/ai/skills/ds-brain-overlays/SKILL.md +30 -0
  15. package/template/.idia/brain/ai/skills/ds-brain-retrieval/SKILL.md +54 -0
  16. package/template/.idia/brain/registry/ai-index.generated.json +833 -0
  17. package/template/.idia/brain/registry/component-registry.generated.json +2947 -0
  18. package/template/.idia/manifest.json +17 -0
  19. package/template/.storybook/main.ts +9 -0
  20. package/template/.storybook/preview.tsx +20 -0
  21. package/template/AGENTS.md +11 -0
  22. package/template/App.tsx +24 -0
  23. package/template/README.md +75 -0
  24. package/template/app.json +13 -0
  25. package/template/babel.config.js +25 -0
  26. package/template/global.css +32 -0
  27. package/template/index.ts +8 -0
  28. package/template/metro.config.js +19 -0
  29. package/template/package.json +85 -0
  30. package/template/public/fonts/Inter.ttf +0 -0
  31. package/template/public/fonts/NunitoSans.woff2 +0 -0
  32. package/template/src/config/env.ts +4 -0
  33. package/template/src/config/versions.ts +7 -0
  34. package/template/src/navigation/RootNavigator.tsx +27 -0
  35. package/template/src/navigation/linking.ts +13 -0
  36. package/template/src/navigation/types.ts +10 -0
  37. package/template/src/providers/AppProviders.tsx +47 -0
  38. package/template/src/screens/Home/HomeScreen.tsx +12 -0
  39. package/template/src/screens/Welcome/WelcomeScreen.tsx +115 -0
  40. package/template/src/stories/Button.stories.tsx +31 -0
  41. package/template/storybook-static/assets/Button.stories-CfapbH7U.js +196 -0
  42. package/template/storybook-static/assets/Color-F6OSRLHC-CFwL-RM_.js +1 -0
  43. package/template/storybook-static/assets/DocsRenderer-CFRXHY34-AADCayzw.js +729 -0
  44. package/template/storybook-static/assets/_commonjsHelpers-Cpj98o6Y.js +1 -0
  45. package/template/storybook-static/assets/axe-d-K7rF9D.js +30 -0
  46. package/template/storybook-static/assets/chunk-XP5HYGXS-BHXC9YeQ.js +1 -0
  47. package/template/storybook-static/assets/client-DGEjZp2f.js +25 -0
  48. package/template/storybook-static/assets/entry-preview-Dc5wkB2s.js +2 -0
  49. package/template/storybook-static/assets/entry-preview-docs-BaxqCxyK.js +46 -0
  50. package/template/storybook-static/assets/iframe-Bl15XKnQ.js +211 -0
  51. package/template/storybook-static/assets/index-Bhelpi4i.js +11 -0
  52. package/template/storybook-static/assets/index-C_pJYAGD.js +1 -0
  53. package/template/storybook-static/assets/index-D5Inswos.js +1 -0
  54. package/template/storybook-static/assets/index-NGyRR_en.js +9 -0
  55. package/template/storybook-static/assets/index-zmTGQa7e.js +9 -0
  56. package/template/storybook-static/assets/jsx-runtime-BjG_zV1W.js +9 -0
  57. package/template/storybook-static/assets/preview-BNUqaTig.js +1 -0
  58. package/template/storybook-static/assets/preview-Cfo7ZnTc.js +2 -0
  59. package/template/storybook-static/assets/preview-CrKLV1aL.css +1 -0
  60. package/template/storybook-static/assets/preview-DkVJIpDn.js +2 -0
  61. package/template/storybook-static/assets/preview-DrRsTNnS.js +17 -0
  62. package/template/storybook-static/assets/react-18-Bfhi6ooJ.js +1 -0
  63. package/template/storybook-static/assets/react-FmFgRqLi.js +1 -0
  64. package/template/storybook-static/assets/react-native-gesture-handler-BzS7UzhZ.js +52 -0
  65. package/template/storybook-static/assets/test-utils-X4YdDMST.js +9 -0
  66. package/template/storybook-static/favicon.svg +1 -0
  67. package/template/storybook-static/fonts/Inter.ttf +0 -0
  68. package/template/storybook-static/fonts/NunitoSans.woff2 +0 -0
  69. package/template/storybook-static/iframe.html +668 -0
  70. package/template/storybook-static/index.html +145 -0
  71. package/template/storybook-static/index.json +1 -0
  72. package/template/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  73. package/template/storybook-static/nunito-sans-bold.woff2 +0 -0
  74. package/template/storybook-static/nunito-sans-italic.woff2 +0 -0
  75. package/template/storybook-static/nunito-sans-regular.woff2 +0 -0
  76. package/template/storybook-static/project.json +1 -0
  77. package/template/storybook-static/sb-addons/a11y-2/manager-bundle.js +3 -0
  78. package/template/storybook-static/sb-addons/links-1/manager-bundle.js +3 -0
  79. package/template/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  80. package/template/storybook-static/sb-common-assets/favicon.svg +1 -0
  81. package/template/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  82. package/template/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  83. package/template/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  84. package/template/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  85. package/template/storybook-static/sb-manager/globals-module-info.js +1052 -0
  86. package/template/storybook-static/sb-manager/globals-runtime.js +41775 -0
  87. package/template/storybook-static/sb-manager/globals.js +48 -0
  88. package/template/storybook-static/sb-manager/runtime.js +12048 -0
  89. package/template/tamagui.config.ts +18 -0
  90. package/template/tsconfig.json +11 -0
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # create-idia-app
2
+
3
+ Scaffold an Expo + React Navigation consumer app with `@idia-ui/core` and `@idia-ui/theme`.
4
+
5
+ **Track C Phase 2a** — local monorepo build only; not published to npm until Phase 5.
6
+
7
+ ## Build
8
+
9
+ From repo root:
10
+
11
+ ```bash
12
+ pnpm --filter create-idia-app build
13
+ ```
14
+
15
+ `prebuild` copies `templates/consumer-app/` into `packages/create-idia-app/template/`. Refresh the source template first when the sandbox changes:
16
+
17
+ ```bash
18
+ node scripts/sync-consumer-template.mjs
19
+ pnpm --filter create-idia-app build
20
+ ```
21
+
22
+ ## Local usage
23
+
24
+ ```bash
25
+ node packages/create-idia-app/dist/index.js my-app
26
+ # or
27
+ pnpm --filter create-idia-app exec create-idia-app my-app
28
+ ```
29
+
30
+ ### Flags
31
+
32
+ | Flag | Behavior |
33
+ |------|----------|
34
+ | `--pm <pnpm\|npm\|yarn>` | Override package manager |
35
+ | `--skip-install` | Skip install + doctor |
36
+ | `--force` | Overwrite existing directory |
37
+ | `--no-git` | Skip `git init` |
38
+ | `--with-storybook` | Warn only — Phase 3 |
39
+ | `--with-brain` | Warn only — Phase 4 |
40
+
41
+ ## E2E outside monorepo (pre–Phase 5)
42
+
43
+ `@idia-ui/*` is **not** on public npm at `0.2.0` yet. External e2e uses packed tarballs + `file:` overrides (same procedure as Phase 0.5 / 1a).
44
+
45
+ ### 1. Build runtime packages + CLI
46
+
47
+ ```bash
48
+ # repo root
49
+ pnpm --filter @idia-ui/tokens build
50
+ pnpm --filter @idia-ui/theme build
51
+ pnpm --filter @idia-ui/core build
52
+ pnpm --filter @idia-ui/hooks build
53
+ pnpm --filter @idia-ui/motion build
54
+ pnpm --filter @idia-ui/utils build
55
+ pnpm --filter @idia-ui/validators build
56
+ pnpm --filter @idia-ui/cli build
57
+ pnpm --filter create-idia-app build
58
+ ```
59
+
60
+ ### 2. Pack tarballs
61
+
62
+ ```bash
63
+ OUT_DIR=C:\Users\Ojanti\Desktop\Projects_\idia-ui-pack-tarballs
64
+ mkdir %OUT_DIR%
65
+ cd packages/tokens && pnpm pack --pack-destination %OUT_DIR%
66
+ # repeat for theme, core, hooks, motion, utils, validators, cli
67
+ ```
68
+
69
+ ### 3. Scaffold outside monorepo
70
+
71
+ ```powershell
72
+ cd $env:TEMP
73
+ node C:\Users\Ojanti\Desktop\Projects_\idia-ui\packages\create-idia-app\dist\index.js my-cli-test --skip-install
74
+ cd my-cli-test
75
+ ```
76
+
77
+ ### 4. Apply `file:` overrides
78
+
79
+ In generated `package.json`, replace semver `@idia-ui/*` and `@idia-ui/cli` with `file:<tarball>` paths. Add matching `pnpm.overrides` for all `@idia-ui/*` packages (transitive graph).
80
+
81
+ ### 5. Install, doctor, dev
82
+
83
+ ```bash
84
+ pnpm install
85
+ pnpm exec idia-ui doctor
86
+ pnpm dev
87
+ # or non-interactive smoke:
88
+ npx expo export --platform web
89
+ ```
90
+
91
+ When developing **inside** the monorepo, `create-idia-app` auto-detects `packages/cli/dist/cli.js` and runs doctor via the sibling CLI build (no npm install of `@idia-ui/cli` required for doctor during maintainer smoke).
92
+
93
+ ## Generated app contract
94
+
95
+ - `package.json` name + `@idia-ui/*` pinned to `^0.2.0`
96
+ - `app.json` name / slug / scheme renamed from `my-idia-app`
97
+ - `src/navigation/linking.ts` URL prefixes updated
98
+ - `.idia/manifest.json` stub with `idiaCli` + `core` versions
99
+ - `@idia-ui/cli` added to `devDependencies`
100
+ - Post-install: `idia-ui doctor` (non-strict) unless `--skip-install`
101
+
102
+ ## Version coupling
103
+
104
+ `create-idia-app@0.2.x` generates apps targeting `@idia-ui/core@0.2.x` and `@idia-ui/cli@0.2.x`.
package/dist/index.js ADDED
@@ -0,0 +1,412 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/scaffold.ts
5
+ var import_node_fs3 = require("fs");
6
+ var import_node_path3 = require("path");
7
+ var import_node_child_process = require("child_process");
8
+
9
+ // src/replace.ts
10
+ var import_node_fs = require("fs");
11
+ var import_node_path = require("path");
12
+
13
+ // src/constants.ts
14
+ var IDIA_UI_VERSION = "0.2.0";
15
+ var CREATE_APP_VERSION = "0.2.0";
16
+ var CLI_VERSION = "0.2.0";
17
+ var TEMPLATE_SLUG = "my-idia-app";
18
+
19
+ // src/replace.ts
20
+ function toKebabCase(name) {
21
+ return name.trim().replace(/[\s_]+/g, "-").replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
22
+ }
23
+ function validateProjectName(name) {
24
+ const slug = toKebabCase(name);
25
+ if (!slug) {
26
+ throw new Error("Project name is required.");
27
+ }
28
+ if (!/^[a-z][a-z0-9-]*$/.test(slug)) {
29
+ throw new Error(
30
+ `Invalid project name "${name}". Use lowercase letters, numbers, and hyphens (must start with a letter).`
31
+ );
32
+ }
33
+ return slug;
34
+ }
35
+ function replacePlaceholders(projectDir, projectName) {
36
+ const packageJsonPath = (0, import_node_path.join)(projectDir, "package.json");
37
+ const packageJson = JSON.parse((0, import_node_fs.readFileSync)(packageJsonPath, "utf8"));
38
+ packageJson.name = projectName;
39
+ for (const field of ["dependencies", "devDependencies"]) {
40
+ const deps = packageJson[field];
41
+ if (!deps) continue;
42
+ for (const pkg of Object.keys(deps)) {
43
+ if (pkg.startsWith("@idia-ui/")) {
44
+ deps[pkg] = `^${IDIA_UI_VERSION}`;
45
+ }
46
+ }
47
+ }
48
+ packageJson.devDependencies ??= {};
49
+ packageJson.devDependencies["@idia-ui/cli"] = `^${CLI_VERSION}`;
50
+ (0, import_node_fs.writeFileSync)(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
51
+ `, "utf8");
52
+ const appJsonPath = (0, import_node_path.join)(projectDir, "app.json");
53
+ const appJson = JSON.parse((0, import_node_fs.readFileSync)(appJsonPath, "utf8"));
54
+ appJson.expo.name = projectName;
55
+ appJson.expo.slug = projectName;
56
+ appJson.expo.scheme = projectName;
57
+ (0, import_node_fs.writeFileSync)(appJsonPath, `${JSON.stringify(appJson, null, 2)}
58
+ `, "utf8");
59
+ const linkingPath = (0, import_node_path.join)(projectDir, "src", "navigation", "linking.ts");
60
+ let linking = (0, import_node_fs.readFileSync)(linkingPath, "utf8");
61
+ linking = linking.replaceAll(TEMPLATE_SLUG, projectName);
62
+ (0, import_node_fs.writeFileSync)(linkingPath, linking, "utf8");
63
+ }
64
+ function writeManifest(projectDir) {
65
+ const manifestDir = (0, import_node_path.join)(projectDir, ".idia");
66
+ (0, import_node_fs.mkdirSync)(manifestDir, { recursive: true });
67
+ const manifestPath = (0, import_node_path.join)(manifestDir, "manifest.json");
68
+ const manifest = {
69
+ idiaCli: CLI_VERSION,
70
+ core: IDIA_UI_VERSION
71
+ };
72
+ (0, import_node_fs.writeFileSync)(manifestPath, `${JSON.stringify(manifest, null, 2)}
73
+ `, "utf8");
74
+ }
75
+
76
+ // src/pm.ts
77
+ var PM_VALUES = /* @__PURE__ */ new Set(["pnpm", "npm", "yarn"]);
78
+ function parsePackageManagerFlag(value) {
79
+ if (!value) return void 0;
80
+ const normalized = value.toLowerCase();
81
+ if (!PM_VALUES.has(normalized)) {
82
+ throw new Error(`Invalid --pm value "${value}". Use pnpm, npm, or yarn.`);
83
+ }
84
+ return normalized;
85
+ }
86
+ function detectPackageManager(override) {
87
+ if (override) return override;
88
+ const agent = process.env.npm_config_user_agent ?? "";
89
+ if (agent.includes("pnpm")) return "pnpm";
90
+ if (agent.includes("yarn")) return "yarn";
91
+ const execPath = process.env.npm_execpath ?? "";
92
+ if (execPath.includes("pnpm")) return "pnpm";
93
+ if (execPath.includes("yarn")) return "yarn";
94
+ return "npm";
95
+ }
96
+ function installCommand(pm) {
97
+ switch (pm) {
98
+ case "pnpm":
99
+ return { command: "pnpm", args: ["install"] };
100
+ case "yarn":
101
+ return { command: "yarn", args: ["install"] };
102
+ default:
103
+ return { command: "npm", args: ["install"] };
104
+ }
105
+ }
106
+ function devCommand(pm) {
107
+ switch (pm) {
108
+ case "pnpm":
109
+ return "pnpm dev";
110
+ case "yarn":
111
+ return "yarn dev";
112
+ default:
113
+ return "npm run dev";
114
+ }
115
+ }
116
+ function idiaUiCommand(pm, subcommand) {
117
+ switch (pm) {
118
+ case "pnpm":
119
+ return { command: "pnpm", args: ["exec", "idia-ui", ...subcommand] };
120
+ case "yarn":
121
+ return { command: "yarn", args: ["idia-ui", ...subcommand] };
122
+ default:
123
+ return { command: "npx", args: ["idia-ui", ...subcommand] };
124
+ }
125
+ }
126
+
127
+ // src/doctor.ts
128
+ var import_node_fs2 = require("fs");
129
+
130
+ // src/paths.ts
131
+ var import_node_path2 = require("path");
132
+ function cliEntryPath() {
133
+ const entry = process.argv[1];
134
+ if (!entry) {
135
+ throw new Error("Unable to resolve CLI entry path.");
136
+ }
137
+ return entry;
138
+ }
139
+ function packageRootDir() {
140
+ return (0, import_node_path2.join)((0, import_node_path2.dirname)(cliEntryPath()), "..");
141
+ }
142
+ function templateDir() {
143
+ return (0, import_node_path2.join)(packageRootDir(), "template");
144
+ }
145
+ function monorepoDoctorCliPath() {
146
+ return (0, import_node_path2.join)(packageRootDir(), "..", "cli", "dist", "cli.js");
147
+ }
148
+
149
+ // src/doctor.ts
150
+ function resolveMonorepoDoctorCli() {
151
+ const candidate = monorepoDoctorCliPath();
152
+ return (0, import_node_fs2.existsSync)(candidate) ? candidate : null;
153
+ }
154
+ function resolveIdiaUiInvocation(pm, subcommand) {
155
+ const monorepoCli = resolveMonorepoDoctorCli();
156
+ if (monorepoCli) {
157
+ return {
158
+ command: process.execPath,
159
+ args: [monorepoCli, ...subcommand],
160
+ via: "monorepo"
161
+ };
162
+ }
163
+ const viaPm = idiaUiCommand(pm, subcommand);
164
+ return { ...viaPm, via: "installed" };
165
+ }
166
+ function resolveDoctorInvocation(pm) {
167
+ return resolveIdiaUiInvocation(pm, ["doctor"]);
168
+ }
169
+
170
+ // src/scaffold.ts
171
+ function resolveTemplateDir() {
172
+ const bundled = templateDir();
173
+ if ((0, import_node_fs3.existsSync)(bundled)) return bundled;
174
+ throw new Error(
175
+ "Template directory missing. Run `pnpm run build` in packages/create-idia-app first."
176
+ );
177
+ }
178
+ function runCommand(command, args, cwd) {
179
+ const result = (0, import_node_child_process.spawnSync)(command, args, {
180
+ cwd,
181
+ stdio: "inherit",
182
+ shell: process.platform === "win32"
183
+ });
184
+ if (result.error) {
185
+ return { status: result.status, error: result.error };
186
+ }
187
+ return { status: result.status };
188
+ }
189
+ function scaffold(options) {
190
+ const projectName = validateProjectName(options.projectName);
191
+ const projectDir = options.targetDir ? (0, import_node_path3.join)(options.targetDir, projectName) : (0, import_node_path3.join)(process.cwd(), projectName);
192
+ const pm = detectPackageManager(options.pm);
193
+ if ((0, import_node_fs3.existsSync)(projectDir)) {
194
+ if (!options.force) {
195
+ throw new Error(
196
+ `Directory "${projectDir}" already exists. Pass --force to overwrite or choose another name.`
197
+ );
198
+ }
199
+ (0, import_node_fs3.rmSync)(projectDir, { recursive: true, force: true });
200
+ }
201
+ (0, import_node_fs3.mkdirSync)(projectDir, { recursive: true });
202
+ (0, import_node_fs3.cpSync)(resolveTemplateDir(), projectDir, { recursive: true });
203
+ replacePlaceholders(projectDir, projectName);
204
+ writeManifest(projectDir);
205
+ if (!options.noGit) {
206
+ const git = runCommand("git", ["init"], projectDir);
207
+ if (git.error) {
208
+ console.warn("\u26A0 git init skipped:", git.error.message);
209
+ }
210
+ }
211
+ let installed = false;
212
+ let doctorRan = false;
213
+ let doctorExitCode = null;
214
+ let doctorVia = "skipped";
215
+ if (!options.skipInstall) {
216
+ console.log(`
217
+ Installing dependencies with ${pm}\u2026`);
218
+ const install = installCommand(pm);
219
+ const installResult = runCommand(install.command, install.args, projectDir);
220
+ if (installResult.error) {
221
+ throw installResult.error;
222
+ }
223
+ if (installResult.status !== 0) {
224
+ throw new Error(`${pm} install failed with exit code ${installResult.status ?? 1}`);
225
+ }
226
+ installed = true;
227
+ console.log("\nRunning idia-ui doctor (non-strict)\u2026");
228
+ const doctor = resolveDoctorInvocation(pm);
229
+ doctorVia = doctor.via;
230
+ const doctorResult = runCommand(doctor.command, doctor.args, projectDir);
231
+ doctorRan = true;
232
+ doctorExitCode = doctorResult.status;
233
+ if (doctorResult.error) {
234
+ console.warn("\u26A0 idia-ui doctor could not run:", doctorResult.error.message);
235
+ doctorRan = false;
236
+ doctorExitCode = null;
237
+ } else if (doctorExitCode !== 0) {
238
+ console.warn(
239
+ `\u26A0 idia-ui doctor exited with code ${doctorExitCode}. Review warnings above; re-run after fixing peers.`
240
+ );
241
+ }
242
+ runPostScaffoldAddons(projectDir, pm, options);
243
+ } else {
244
+ console.log("\n--skip-install: skipping dependency install and idia-ui doctor.");
245
+ if (options.withStorybook || options.withBrain) {
246
+ console.warn(
247
+ "\u26A0 --with-storybook / --with-brain require install. After `pnpm install`, run idia-ui add storybook and/or idia-ui add brain."
248
+ );
249
+ }
250
+ }
251
+ printNextSteps(projectName, projectDir, pm, options);
252
+ return {
253
+ projectDir,
254
+ projectName,
255
+ pm,
256
+ installed,
257
+ doctorRan,
258
+ doctorExitCode,
259
+ doctorVia
260
+ };
261
+ }
262
+ function runPostScaffoldAddons(projectDir, pm, options) {
263
+ if (options.withStorybook) {
264
+ console.log("\nRunning idia-ui add storybook\u2026");
265
+ const add = resolveIdiaUiInvocation(pm, ["add", "storybook"]);
266
+ const result = runCommand(add.command, add.args, projectDir);
267
+ if (result.error) {
268
+ console.warn("\u26A0 idia-ui add storybook could not run:", result.error.message);
269
+ } else if (result.status !== 0) {
270
+ console.warn(
271
+ `\u26A0 idia-ui add storybook exited with code ${result.status ?? 1}. Re-run manually after fixing peers.`
272
+ );
273
+ }
274
+ }
275
+ if (options.withBrain) {
276
+ console.log("\nRunning idia-ui add brain\u2026");
277
+ const add = resolveIdiaUiInvocation(pm, ["add", "brain"]);
278
+ const result = runCommand(add.command, add.args, projectDir);
279
+ if (result.error) {
280
+ console.warn("\u26A0 idia-ui add brain could not run:", result.error.message);
281
+ } else if (result.status !== 0) {
282
+ console.warn(
283
+ `\u26A0 idia-ui add brain exited with code ${result.status ?? 1}. Re-run manually after fixing peers.`
284
+ );
285
+ }
286
+ }
287
+ }
288
+ function printNextSteps(projectName, projectDir, pm, options) {
289
+ const dev = devCommand(pm);
290
+ console.log("\n\u2713 Project scaffolded successfully\n");
291
+ console.log("Next steps:");
292
+ console.log(` cd ${projectDir}`);
293
+ if (!(0, import_node_fs3.existsSync)((0, import_node_path3.join)(projectDir, "node_modules"))) {
294
+ const install = installCommand(pm);
295
+ console.log(` ${install.command} ${install.args.join(" ")}`);
296
+ }
297
+ console.log(` ${dev}`);
298
+ console.log(` ${pm === "npm" ? "npx idia-ui doctor" : `${pm} exec idia-ui doctor`}`);
299
+ if (!options.withStorybook) {
300
+ console.log(` ${pm === "npm" ? "npx idia-ui add storybook" : `${pm} exec idia-ui add storybook`}`);
301
+ }
302
+ if (!options.withBrain) {
303
+ console.log(` ${pm === "npm" ? "npx idia-ui add brain" : `${pm} exec idia-ui add brain`}`);
304
+ }
305
+ }
306
+
307
+ // src/index.ts
308
+ function printHelp() {
309
+ console.log(`create-idia-app v${CREATE_APP_VERSION}
310
+
311
+ Usage:
312
+ create-idia-app [project-name] [options]
313
+
314
+ Options:
315
+ --pm <pnpm|npm|yarn> Override package manager detection
316
+ --skip-install Skip install and idia-ui doctor
317
+ --force Overwrite target directory if it exists
318
+ --no-git Skip git init
319
+ --with-storybook Not available (Phase 3) \u2014 prints warning
320
+ --with-brain Not available (Phase 4) \u2014 prints warning
321
+ -h, --help Show help
322
+ -V, --version Show version
323
+ `);
324
+ }
325
+ function parseArgs(argv) {
326
+ const result = {
327
+ projectName: void 0,
328
+ pm: void 0,
329
+ skipInstall: false,
330
+ force: false,
331
+ noGit: false,
332
+ withStorybook: false,
333
+ withBrain: false,
334
+ help: false,
335
+ version: false
336
+ };
337
+ for (let i = 0; i < argv.length; i += 1) {
338
+ const arg = argv[i];
339
+ switch (arg) {
340
+ case "--pm":
341
+ result.pm = parsePackageManagerFlag(argv[++i]);
342
+ break;
343
+ case "--skip-install":
344
+ result.skipInstall = true;
345
+ break;
346
+ case "--force":
347
+ result.force = true;
348
+ break;
349
+ case "--no-git":
350
+ result.noGit = true;
351
+ break;
352
+ case "--with-storybook":
353
+ result.withStorybook = true;
354
+ break;
355
+ case "--with-brain":
356
+ result.withBrain = true;
357
+ break;
358
+ case "-h":
359
+ case "--help":
360
+ result.help = true;
361
+ break;
362
+ case "-V":
363
+ case "--version":
364
+ result.version = true;
365
+ break;
366
+ default:
367
+ if (arg.startsWith("-")) {
368
+ throw new Error(`Unknown option: ${arg}`);
369
+ }
370
+ if (!result.projectName) {
371
+ result.projectName = arg;
372
+ } else {
373
+ throw new Error(`Unexpected argument: ${arg}`);
374
+ }
375
+ }
376
+ }
377
+ return result;
378
+ }
379
+ function main() {
380
+ try {
381
+ const args = parseArgs(process.argv.slice(2));
382
+ if (args.help) {
383
+ printHelp();
384
+ return;
385
+ }
386
+ if (args.version) {
387
+ console.log(CREATE_APP_VERSION);
388
+ return;
389
+ }
390
+ if (!args.projectName) {
391
+ printHelp();
392
+ throw new Error("Project name is required. Example: create-idia-app my-app");
393
+ }
394
+ scaffold({
395
+ projectName: args.projectName,
396
+ targetDir: process.cwd(),
397
+ pm: args.pm,
398
+ skipInstall: args.skipInstall,
399
+ force: args.force,
400
+ noGit: args.noGit,
401
+ withStorybook: args.withStorybook,
402
+ withBrain: args.withBrain
403
+ });
404
+ } catch (error) {
405
+ const message = error instanceof Error ? error.message : String(error);
406
+ console.error(`
407
+ Error: ${message}`);
408
+ process.exit(1);
409
+ }
410
+ }
411
+ main();
412
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scaffold.ts","../src/replace.ts","../src/constants.ts","../src/pm.ts","../src/doctor.ts","../src/paths.ts","../src/index.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, rmSync } from 'node:fs'\r\nimport { join } from 'node:path'\r\nimport { spawnSync } from 'node:child_process'\r\n\r\nimport { replacePlaceholders, validateProjectName, writeManifest } from './replace.js'\r\nimport {\r\n detectPackageManager,\r\n devCommand,\r\n installCommand,\r\n type PackageManager,\r\n} from './pm.js'\r\nimport { resolveDoctorInvocation, resolveIdiaUiInvocation } from './doctor.js'\r\nimport { templateDir } from './paths.js'\r\n\r\nexport type ScaffoldOptions = {\r\n projectName: string\r\n targetDir: string\r\n pm?: PackageManager\r\n skipInstall?: boolean\r\n force?: boolean\r\n noGit?: boolean\r\n withStorybook?: boolean\r\n withBrain?: boolean\r\n}\r\n\r\nexport type ScaffoldResult = {\r\n projectDir: string\r\n projectName: string\r\n pm: PackageManager\r\n installed: boolean\r\n doctorRan: boolean\r\n doctorExitCode: number | null\r\n doctorVia: 'monorepo' | 'installed' | 'skipped'\r\n}\r\n\r\nfunction resolveTemplateDir(): string {\r\n const bundled = templateDir()\r\n if (existsSync(bundled)) return bundled\r\n throw new Error(\r\n 'Template directory missing. Run `pnpm run build` in packages/create-idia-app first.',\r\n )\r\n}\r\n\r\nfunction runCommand(\r\n command: string,\r\n args: string[],\r\n cwd: string,\r\n): { status: number | null; error?: Error } {\r\n const result = spawnSync(command, args, {\r\n cwd,\r\n stdio: 'inherit',\r\n shell: process.platform === 'win32',\r\n })\r\n if (result.error) {\r\n return { status: result.status, error: result.error }\r\n }\r\n return { status: result.status }\r\n}\r\n\r\nexport function scaffold(options: ScaffoldOptions): ScaffoldResult {\r\n const projectName = validateProjectName(options.projectName)\r\n const projectDir = options.targetDir\r\n ? join(options.targetDir, projectName)\r\n : join(process.cwd(), projectName)\r\n const pm = detectPackageManager(options.pm)\r\n\r\n if (existsSync(projectDir)) {\r\n if (!options.force) {\r\n throw new Error(\r\n `Directory \"${projectDir}\" already exists. Pass --force to overwrite or choose another name.`,\r\n )\r\n }\r\n rmSync(projectDir, { recursive: true, force: true })\r\n }\r\n\r\n mkdirSync(projectDir, { recursive: true })\r\n cpSync(resolveTemplateDir(), projectDir, { recursive: true })\r\n\r\n replacePlaceholders(projectDir, projectName)\r\n writeManifest(projectDir)\r\n\r\n if (!options.noGit) {\r\n const git = runCommand('git', ['init'], projectDir)\r\n if (git.error) {\r\n console.warn('⚠ git init skipped:', git.error.message)\r\n }\r\n }\r\n\r\n let installed = false\r\n let doctorRan = false\r\n let doctorExitCode: number | null = null\r\n let doctorVia: ScaffoldResult['doctorVia'] = 'skipped'\r\n\r\n if (!options.skipInstall) {\r\n console.log(`\\nInstalling dependencies with ${pm}…`)\r\n const install = installCommand(pm)\r\n const installResult = runCommand(install.command, install.args, projectDir)\r\n if (installResult.error) {\r\n throw installResult.error\r\n }\r\n if (installResult.status !== 0) {\r\n throw new Error(`${pm} install failed with exit code ${installResult.status ?? 1}`)\r\n }\r\n installed = true\r\n\r\n console.log('\\nRunning idia-ui doctor (non-strict)…')\r\n const doctor = resolveDoctorInvocation(pm)\r\n doctorVia = doctor.via\r\n const doctorResult = runCommand(doctor.command, doctor.args, projectDir)\r\n doctorRan = true\r\n doctorExitCode = doctorResult.status\r\n if (doctorResult.error) {\r\n console.warn('⚠ idia-ui doctor could not run:', doctorResult.error.message)\r\n doctorRan = false\r\n doctorExitCode = null\r\n } else if (doctorExitCode !== 0) {\r\n console.warn(\r\n `⚠ idia-ui doctor exited with code ${doctorExitCode}. Review warnings above; re-run after fixing peers.`,\r\n )\r\n }\r\n\r\n runPostScaffoldAddons(projectDir, pm, options)\r\n } else {\r\n console.log('\\n--skip-install: skipping dependency install and idia-ui doctor.')\r\n if (options.withStorybook || options.withBrain) {\r\n console.warn(\r\n '⚠ --with-storybook / --with-brain require install. After `pnpm install`, run idia-ui add storybook and/or idia-ui add brain.',\r\n )\r\n }\r\n }\r\n\r\n printNextSteps(projectName, projectDir, pm, options)\r\n\r\n return {\r\n projectDir,\r\n projectName,\r\n pm,\r\n installed,\r\n doctorRan,\r\n doctorExitCode,\r\n doctorVia,\r\n }\r\n}\r\n\r\nfunction runPostScaffoldAddons(\r\n projectDir: string,\r\n pm: PackageManager,\r\n options: Pick<ScaffoldOptions, 'withStorybook' | 'withBrain'>,\r\n): void {\r\n if (options.withStorybook) {\r\n console.log('\\nRunning idia-ui add storybook…')\r\n const add = resolveIdiaUiInvocation(pm, ['add', 'storybook'])\r\n const result = runCommand(add.command, add.args, projectDir)\r\n if (result.error) {\r\n console.warn('⚠ idia-ui add storybook could not run:', result.error.message)\r\n } else if (result.status !== 0) {\r\n console.warn(\r\n `⚠ idia-ui add storybook exited with code ${result.status ?? 1}. Re-run manually after fixing peers.`,\r\n )\r\n }\r\n }\r\n\r\n if (options.withBrain) {\r\n console.log('\\nRunning idia-ui add brain…')\r\n const add = resolveIdiaUiInvocation(pm, ['add', 'brain'])\r\n const result = runCommand(add.command, add.args, projectDir)\r\n if (result.error) {\r\n console.warn('⚠ idia-ui add brain could not run:', result.error.message)\r\n } else if (result.status !== 0) {\r\n console.warn(\r\n `⚠ idia-ui add brain exited with code ${result.status ?? 1}. Re-run manually after fixing peers.`,\r\n )\r\n }\r\n }\r\n}\r\n\r\nfunction printNextSteps(\r\n projectName: string,\r\n projectDir: string,\r\n pm: PackageManager,\r\n options: Pick<ScaffoldOptions, 'withStorybook' | 'withBrain'>,\r\n): void {\r\n const dev = devCommand(pm)\r\n console.log('\\n✓ Project scaffolded successfully\\n')\r\n console.log('Next steps:')\r\n console.log(` cd ${projectDir}`)\r\n if (!existsSync(join(projectDir, 'node_modules'))) {\r\n const install = installCommand(pm)\r\n console.log(` ${install.command} ${install.args.join(' ')}`)\r\n }\r\n console.log(` ${dev}`)\r\n console.log(` ${pm === 'npm' ? 'npx idia-ui doctor' : `${pm} exec idia-ui doctor`}`)\r\n if (!options.withStorybook) {\r\n console.log(` ${pm === 'npm' ? 'npx idia-ui add storybook' : `${pm} exec idia-ui add storybook`}`)\r\n }\r\n if (!options.withBrain) {\r\n console.log(` ${pm === 'npm' ? 'npx idia-ui add brain' : `${pm} exec idia-ui add brain`}`)\r\n }\r\n}\r\n","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\r\nimport { join } from 'node:path'\r\n\r\nimport { CLI_VERSION, IDIA_UI_VERSION, TEMPLATE_SLUG } from './constants.js'\r\n\r\ntype PackageJson = {\r\n name?: string\r\n dependencies?: Record<string, string>\r\n devDependencies?: Record<string, string>\r\n}\r\n\r\nexport function toKebabCase(name: string): string {\r\n return name\r\n .trim()\r\n .replace(/[\\s_]+/g, '-')\r\n .replace(/([a-z])([A-Z])/g, '$1-$2')\r\n .toLowerCase()\r\n .replace(/[^a-z0-9-]/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-|-$/g, '')\r\n}\r\n\r\nexport function validateProjectName(name: string): string {\r\n const slug = toKebabCase(name)\r\n if (!slug) {\r\n throw new Error('Project name is required.')\r\n }\r\n if (!/^[a-z][a-z0-9-]*$/.test(slug)) {\r\n throw new Error(\r\n `Invalid project name \"${name}\". Use lowercase letters, numbers, and hyphens (must start with a letter).`,\r\n )\r\n }\r\n return slug\r\n}\r\n\r\nexport function replacePlaceholders(projectDir: string, projectName: string): void {\r\n const packageJsonPath = join(projectDir, 'package.json')\r\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as PackageJson\r\n\r\n packageJson.name = projectName\r\n\r\n for (const field of ['dependencies', 'devDependencies'] as const) {\r\n const deps = packageJson[field]\r\n if (!deps) continue\r\n for (const pkg of Object.keys(deps)) {\r\n if (pkg.startsWith('@idia-ui/')) {\r\n deps[pkg] = `^${IDIA_UI_VERSION}`\r\n }\r\n }\r\n }\r\n\r\n packageJson.devDependencies ??= {}\r\n packageJson.devDependencies['@idia-ui/cli'] = `^${CLI_VERSION}`\r\n\r\n writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, 'utf8')\r\n\r\n const appJsonPath = join(projectDir, 'app.json')\r\n const appJson = JSON.parse(readFileSync(appJsonPath, 'utf8')) as {\r\n expo: { name: string; slug: string; scheme: string }\r\n }\r\n appJson.expo.name = projectName\r\n appJson.expo.slug = projectName\r\n appJson.expo.scheme = projectName\r\n writeFileSync(appJsonPath, `${JSON.stringify(appJson, null, 2)}\\n`, 'utf8')\r\n\r\n const linkingPath = join(projectDir, 'src', 'navigation', 'linking.ts')\r\n let linking = readFileSync(linkingPath, 'utf8')\r\n linking = linking.replaceAll(TEMPLATE_SLUG, projectName)\r\n writeFileSync(linkingPath, linking, 'utf8')\r\n}\r\n\r\nexport function writeManifest(projectDir: string): void {\r\n const manifestDir = join(projectDir, '.idia')\r\n mkdirSync(manifestDir, { recursive: true })\r\n const manifestPath = join(manifestDir, 'manifest.json')\r\n const manifest = {\r\n idiaCli: CLI_VERSION,\r\n core: IDIA_UI_VERSION,\r\n }\r\n writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, 'utf8')\r\n}\r\n","/** Monorepo-local @idia-ui/* minor — pins generated app deps (RFC §10.4). */\r\nexport const IDIA_UI_VERSION = '0.2.0'\r\n\r\n/** create-idia-app package version — keep in sync with package.json. */\r\nexport const CREATE_APP_VERSION = '0.2.0'\r\n\r\n/** @idia-ui/cli version written to manifest + devDependency. */\r\nexport const CLI_VERSION = '0.2.0'\r\n\r\nexport const TEMPLATE_SLUG = 'my-idia-app'\r\n","export type PackageManager = 'pnpm' | 'npm' | 'yarn'\r\n\r\nconst PM_VALUES = new Set<PackageManager>(['pnpm', 'npm', 'yarn'])\r\n\r\nexport function parsePackageManagerFlag(value: string | undefined): PackageManager | undefined {\r\n if (!value) return undefined\r\n const normalized = value.toLowerCase() as PackageManager\r\n if (!PM_VALUES.has(normalized)) {\r\n throw new Error(`Invalid --pm value \"${value}\". Use pnpm, npm, or yarn.`)\r\n }\r\n return normalized\r\n}\r\n\r\nexport function detectPackageManager(override?: PackageManager): PackageManager {\r\n if (override) return override\r\n\r\n const agent = process.env.npm_config_user_agent ?? ''\r\n if (agent.includes('pnpm')) return 'pnpm'\r\n if (agent.includes('yarn')) return 'yarn'\r\n\r\n const execPath = process.env.npm_execpath ?? ''\r\n if (execPath.includes('pnpm')) return 'pnpm'\r\n if (execPath.includes('yarn')) return 'yarn'\r\n\r\n return 'npm'\r\n}\r\n\r\nexport function installCommand(pm: PackageManager): { command: string; args: string[] } {\r\n switch (pm) {\r\n case 'pnpm':\r\n return { command: 'pnpm', args: ['install'] }\r\n case 'yarn':\r\n return { command: 'yarn', args: ['install'] }\r\n default:\r\n return { command: 'npm', args: ['install'] }\r\n }\r\n}\r\n\r\nexport function devCommand(pm: PackageManager): string {\r\n switch (pm) {\r\n case 'pnpm':\r\n return 'pnpm dev'\r\n case 'yarn':\r\n return 'yarn dev'\r\n default:\r\n return 'npm run dev'\r\n }\r\n}\r\n\r\nexport function doctorCommand(pm: PackageManager): { command: string; args: string[] } {\r\n return idiaUiCommand(pm, ['doctor'])\r\n}\r\n\r\nexport type IdiaUiCommand = { command: string; args: string[] }\r\n\r\nexport function idiaUiCommand(\r\n pm: PackageManager,\r\n subcommand: string[],\r\n): IdiaUiCommand {\r\n switch (pm) {\r\n case 'pnpm':\r\n return { command: 'pnpm', args: ['exec', 'idia-ui', ...subcommand] }\r\n case 'yarn':\r\n return { command: 'yarn', args: ['idia-ui', ...subcommand] }\r\n default:\r\n return { command: 'npx', args: ['idia-ui', ...subcommand] }\r\n }\r\n}\r\n","import { existsSync } from 'node:fs'\r\n\r\nimport { monorepoDoctorCliPath } from './paths.js'\r\nimport { idiaUiCommand, type PackageManager } from './pm.js'\r\n\r\n/** Monorepo sibling @idia-ui/cli when developing create-idia-app locally. */\r\nexport function resolveMonorepoDoctorCli(): string | null {\r\n const candidate = monorepoDoctorCliPath()\r\n return existsSync(candidate) ? candidate : null\r\n}\r\n\r\nexport function resolveIdiaUiInvocation(\r\n pm: PackageManager,\r\n subcommand: string[],\r\n): { command: string; args: string[]; via: 'monorepo' | 'installed' } {\r\n const monorepoCli = resolveMonorepoDoctorCli()\r\n if (monorepoCli) {\r\n return {\r\n command: process.execPath,\r\n args: [monorepoCli, ...subcommand],\r\n via: 'monorepo',\r\n }\r\n }\r\n\r\n const viaPm = idiaUiCommand(pm, subcommand)\r\n return { ...viaPm, via: 'installed' }\r\n}\r\n\r\nexport function resolveDoctorInvocation(\r\n pm: PackageManager,\r\n): { command: string; args: string[]; via: 'monorepo' | 'installed' } {\r\n return resolveIdiaUiInvocation(pm, ['doctor'])\r\n}\r\n","import { dirname, join } from 'node:path'\r\n\r\n/** CLI entry file (dist/index.js) — reliable in CJS bin bundles. */\r\nfunction cliEntryPath(): string {\r\n const entry = process.argv[1]\r\n if (!entry) {\r\n throw new Error('Unable to resolve CLI entry path.')\r\n }\r\n return entry\r\n}\r\n\r\nexport function packageRootDir(): string {\r\n return join(dirname(cliEntryPath()), '..')\r\n}\r\n\r\nexport function templateDir(): string {\r\n return join(packageRootDir(), 'template')\r\n}\r\n\r\nexport function monorepoDoctorCliPath(): string {\r\n return join(packageRootDir(), '..', 'cli', 'dist', 'cli.js')\r\n}\r\n","import { scaffold } from './scaffold.js'\r\nimport { parsePackageManagerFlag } from './pm.js'\r\nimport { CREATE_APP_VERSION } from './constants.js'\r\n\r\nfunction printHelp(): void {\r\n console.log(`create-idia-app v${CREATE_APP_VERSION}\r\n\r\nUsage:\r\n create-idia-app [project-name] [options]\r\n\r\nOptions:\r\n --pm <pnpm|npm|yarn> Override package manager detection\r\n --skip-install Skip install and idia-ui doctor\r\n --force Overwrite target directory if it exists\r\n --no-git Skip git init\r\n --with-storybook Not available (Phase 3) — prints warning\r\n --with-brain Not available (Phase 4) — prints warning\r\n -h, --help Show help\r\n -V, --version Show version\r\n`)\r\n}\r\n\r\nfunction parseArgs(argv: string[]): {\r\n projectName?: string\r\n pm?: ReturnType<typeof parsePackageManagerFlag>\r\n skipInstall: boolean\r\n force: boolean\r\n noGit: boolean\r\n withStorybook: boolean\r\n withBrain: boolean\r\n help: boolean\r\n version: boolean\r\n} {\r\n const result = {\r\n projectName: undefined as string | undefined,\r\n pm: undefined as ReturnType<typeof parsePackageManagerFlag>,\r\n skipInstall: false,\r\n force: false,\r\n noGit: false,\r\n withStorybook: false,\r\n withBrain: false,\r\n help: false,\r\n version: false,\r\n }\r\n\r\n for (let i = 0; i < argv.length; i += 1) {\r\n const arg = argv[i]\r\n switch (arg) {\r\n case '--pm':\r\n result.pm = parsePackageManagerFlag(argv[++i])\r\n break\r\n case '--skip-install':\r\n result.skipInstall = true\r\n break\r\n case '--force':\r\n result.force = true\r\n break\r\n case '--no-git':\r\n result.noGit = true\r\n break\r\n case '--with-storybook':\r\n result.withStorybook = true\r\n break\r\n case '--with-brain':\r\n result.withBrain = true\r\n break\r\n case '-h':\r\n case '--help':\r\n result.help = true\r\n break\r\n case '-V':\r\n case '--version':\r\n result.version = true\r\n break\r\n default:\r\n if (arg.startsWith('-')) {\r\n throw new Error(`Unknown option: ${arg}`)\r\n }\r\n if (!result.projectName) {\r\n result.projectName = arg\r\n } else {\r\n throw new Error(`Unexpected argument: ${arg}`)\r\n }\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nfunction main(): void {\r\n try {\r\n const args = parseArgs(process.argv.slice(2))\r\n\r\n if (args.help) {\r\n printHelp()\r\n return\r\n }\r\n\r\n if (args.version) {\r\n console.log(CREATE_APP_VERSION)\r\n return\r\n }\r\n\r\n if (!args.projectName) {\r\n printHelp()\r\n throw new Error('Project name is required. Example: create-idia-app my-app')\r\n }\r\n\r\n scaffold({\r\n projectName: args.projectName,\r\n targetDir: process.cwd(),\r\n pm: args.pm,\r\n skipInstall: args.skipInstall,\r\n force: args.force,\r\n noGit: args.noGit,\r\n withStorybook: args.withStorybook,\r\n withBrain: args.withBrain,\r\n })\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.error(`\\nError: ${message}`)\r\n process.exit(1)\r\n }\r\n}\r\n\r\nmain()\r\n"],"mappings":"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","names":["import_node_fs","import_node_path","import_node_fs","import_node_path"]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "create-idia-app",
3
+ "version": "0.2.0",
4
+ "description": "Scaffold an Expo + idia-ui consumer app from the official template",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/idia-ui/idia-ui.git",
9
+ "directory": "packages/create-idia-app"
10
+ },
11
+ "bin": {
12
+ "create-idia-app": "dist/index.js"
13
+ },
14
+ "main": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "files": [
17
+ "dist",
18
+ "template"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "prebuild": "node scripts/copy-template.mjs",
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "clean": "rm -rf dist template",
28
+ "typecheck": "tsc --noEmit"
29
+ },
30
+ "engines": {
31
+ "node": ">=20"
32
+ }
33
+ }
@@ -0,0 +1,32 @@
1
+ ---
2
+ description: "Always-apply ds-brain rules: read AGENTS.md, use generated registry indexes, do not invent components or variants."
3
+ globs:
4
+ - "**/*"
5
+ alwaysApply: true
6
+ ---
7
+ # Idia UI — ds-brain
8
+
9
+ Operational rules for AI coding agents working in this repo.
10
+
11
+ - Read `.idia/brain/AGENTS.md` before design-system work.
12
+ - If authored docs and generated files conflict, authored docs win.
13
+ - `foundations/`
14
+ - `components/`
15
+ - `patterns/`
16
+ - `decisions/`
17
+ - Read `AGENTS.md` (repo root) — **session-start**; mandatory first Read for **any** task (see root `AGENTS.md`).
18
+ - Read `.idia/brain/AGENTS.md` — **gate step 1**; brain entrypoint (this file).
19
+ - Read `.idia/brain/registry/ai-index.generated.json` — **gate step 2**; **STOP** — required before any component or pattern doc.
20
+ - Read `.idia/brain/ai/skills/ds-brain-index/SKILL.md` — **gate step 3**; **required** meta router; read before domain skills and component/pattern docs.
21
+ - Classify **output mode** and **task intent** from the ai-index before opening authored component docs.
22
+ - Read `AGENTS.md` — entry routing and output-mode read lists.
23
+ - Read `.idia/brain/registry/ai-index.generated.json` — **required** gate before component/pattern docs.
24
+ - Read `ds-brain-index` skill (`.idia/brain/ai/skills/ds-brain-index/SKILL.md`) — **required** meta router before domain skills and authored component docs.
25
+ - Classify output mode from the ai-index.
26
+ - Prefer `.idia/brain/registry/ai-index.generated.json` when present.
27
+ - Use `.idia/brain/registry/component-registry.generated.json` for component metadata — do not invent components, props, variants, tokens, or Figma mappings.
28
+ - Do not edit `.idia/brain/` directly.
29
+ - Do not invent components, props, variants, tokens, or Figma mappings.
30
+ - Do not mark a doc `rich` unless required sections are substantive, especially accessibility for interactive components.
31
+ - Do not claim catalog completeness beyond what the pack registries summarize.
32
+ - If a gap is found, report it to the idia-ui maintainers rather than inventing API or docs.
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: "Form composition: action hierarchy, choice controls (radio/select/checkbox), validation patterns."
3
+ globs:
4
+ - "**/forms/**"
5
+ - "**/*Form*"
6
+ - "**/*form*"
7
+ alwaysApply: false
8
+ ---
9
+ # Idia UI — Forms
10
+
11
+ Apply when editing form flows, field groups, validation, or choice controls.
12
+
13
+ - Forms collect, validate, and submit structured user input — multiple related values the user enters or edits before a primary action completes the task.
14
+ - Retrieve this pattern plus `patterns/forms.md` and `decisions/action-hierarchy.md`.
15
+ - Retrieve `components/form-section.md` and `components/form-element.md` before generating hierarchy.
16
+ - Retrieve component brain docs for every field you render.
17
+ - Use `FormSection` when there are 2+ logical groups; use built-in `label` on `InputText`/`Select`/`TextArea`/`InputGroup` when possible.
18
+ - Reserve `FormElement` for custom/headless controls or `Toggle` group labels.
19
+ - Apply `FORM_V_GAP` / `FORM_H_GAP` from `foundations/spacing.md` — do not invent spacing tokens.
20
+ - Retrieve this pattern, `patterns/forms.md`, and `patterns/form-composition.md` for layout context.
21
+ - Retrieve `components/form-element.md` and every field component you render.
22
+ - Import validators from `@idia-ui/validators` — do not duplicate regex in screens.
23
+ - Map `formState.errors` to `hasError` + `errorText` on the matching field.
24
+ - Use `mode: 'onSubmit'` as default for short forms; gate on-change revalidation with `isSubmitted`.
25
+ - Set submit `Button` `loading` during async work.
26
+ - Each local action group should have **one primary action** — the control that completes the main task. Secondary actions support cancellation, back navigation, alternative flows, or lower-priority choices. Destructive actions must be visually distinct and must not read as casual alternatives to the primary action.
27
+ - **Form footers** — submit, save, continue, cancel, back (`patterns/forms.md`)
28
+ - **Dialog or sheet action rows** — confirm, dismiss, delete with confirmation (`patterns/modal-routing.md`, `components/confirmation-modal.md`)
29
+ - **Modal `footer` slots** — save/cancel pairs on responsive `Modal` branches (`components/modal.md`)
30
+ - **Wizard step footers** — next/continue vs back/submit on first, middle, and last steps (`patterns/wizard-flows.md`)
31
+ - Choose the control by **selection model**, **visibility needs**, and **visual density**. All Group A choice controls have brain docs — retrieve the cited component doc before generating props.
32
+ - Form task-intent components: avatar-upload, button, checkbox, custom-selection, date-input, date-range-input, form-element, form-section, ….
33
+ - Form foundations: color, spacing, tokens, typography.
34
+ - Retrieve pattern docs from ds-brain index task intent `form` before generating form UI.