create-twinbloc-app 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -4
- package/bin/cli.js +141 -2
- package/package.json +1 -1
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/SKILL.md +89 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/template/react-native-starter/.agents/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/AGENTS.md +2897 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/SKILL.md +121 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/template/react-native-starter/.agents/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
- package/template/react-native-starter/.env.development +2 -0
- package/template/react-native-starter/.env.production +2 -0
- package/template/react-native-starter/.env.staging +2 -0
- package/template/react-native-starter/README.md +1 -2
- package/template/react-native-starter/app.config.ts +57 -0
- package/template/react-native-starter/babel.config.js +21 -0
- package/template/react-native-starter/eslint.config.js +35 -3
- package/template/react-native-starter/global.css +3 -0
- package/template/react-native-starter/jest.config.js +13 -0
- package/template/react-native-starter/jest.setup.js +184 -0
- package/template/react-native-starter/metro.config.js +8 -0
- package/template/react-native-starter/nativewind-env.d.ts +3 -0
- package/template/react-native-starter/package-lock.json +5913 -1647
- package/template/react-native-starter/package.json +53 -2
- package/template/react-native-starter/root-env.js +122 -0
- package/template/react-native-starter/src/api/common/__tests__/api-provider.test.tsx +83 -0
- package/template/react-native-starter/src/api/common/__tests__/api-utils.test.ts +117 -0
- package/template/react-native-starter/src/api/common/__tests__/execute-client.test.ts +118 -0
- package/template/react-native-starter/src/api/common/api-provider.tsx +57 -0
- package/template/react-native-starter/src/api/common/api-utils.ts +159 -0
- package/template/react-native-starter/src/api/common/execute-client.ts +89 -0
- package/template/react-native-starter/src/api/common/index.ts +4 -0
- package/template/react-native-starter/src/api/common/types.ts +10 -0
- package/template/react-native-starter/src/api/index.ts +1 -0
- package/template/react-native-starter/src/app/(main)/_layout.tsx +15 -0
- package/template/react-native-starter/src/app/(main)/index.tsx +223 -0
- package/template/react-native-starter/src/app/+html.tsx +46 -0
- package/template/react-native-starter/src/app/[...messing].tsx +25 -0
- package/template/react-native-starter/src/app/_layout.tsx +56 -0
- package/template/react-native-starter/src/app/onboarding.tsx +23 -0
- package/template/react-native-starter/src/components/index.ts +1 -0
- package/template/react-native-starter/src/components/providers/index.tsx +62 -0
- package/template/react-native-starter/src/components/ui/__tests__/ui-basic.test.tsx +212 -0
- package/template/react-native-starter/src/components/ui/__tests__/ui-forms.test.tsx +116 -0
- package/template/react-native-starter/src/components/ui/accordion.tsx +142 -0
- package/template/react-native-starter/src/components/ui/avatar.tsx +141 -0
- package/template/react-native-starter/src/components/ui/bottom-sheet.tsx +120 -0
- package/template/react-native-starter/src/components/ui/button.tsx +139 -0
- package/template/react-native-starter/src/components/ui/check-box.tsx +74 -0
- package/template/react-native-starter/src/components/ui/container.tsx +52 -0
- package/template/react-native-starter/src/components/ui/icon.tsx +30 -0
- package/template/react-native-starter/src/components/ui/image.tsx +18 -0
- package/template/react-native-starter/src/components/ui/index.ts +15 -0
- package/template/react-native-starter/src/components/ui/input-view.tsx +22 -0
- package/template/react-native-starter/src/components/ui/input.tsx +132 -0
- package/template/react-native-starter/src/components/ui/progress-bar.tsx +136 -0
- package/template/react-native-starter/src/components/ui/radio.tsx +67 -0
- package/template/react-native-starter/src/components/ui/safe-fast-image.tsx +50 -0
- package/template/react-native-starter/src/components/ui/select.tsx +247 -0
- package/template/react-native-starter/src/components/ui/stacks.tsx +49 -0
- package/template/react-native-starter/src/components/ui/switch.tsx +134 -0
- package/template/react-native-starter/src/components/ui/text.tsx +115 -0
- package/template/react-native-starter/src/components/ui/toggle-shared.tsx +49 -0
- package/template/react-native-starter/src/components/utilities/colors.js +147 -0
- package/template/react-native-starter/src/components/utilities/confirm-dialog.tsx +112 -0
- package/template/react-native-starter/src/components/utilities/index.ts +4 -0
- package/template/react-native-starter/src/components/utilities/show-toast.ts +75 -0
- package/template/react-native-starter/src/components/utilities/ui-utils.tsx +7 -0
- package/template/react-native-starter/src/hooks/general/index.ts +0 -0
- package/template/react-native-starter/src/hooks/general/use-countdown.ts +61 -0
- package/template/react-native-starter/src/hooks/general/use-debounce.ts +22 -0
- package/template/react-native-starter/src/hooks/general/use-is-first-time.tsx +17 -0
- package/template/react-native-starter/src/hooks/general/use-select-theme.ts +34 -0
- package/template/react-native-starter/src/hooks/general/use-theme.tsx +47 -0
- package/template/react-native-starter/src/hooks/index.ts +1 -0
- package/template/react-native-starter/src/lib/app-initializer.ts +31 -0
- package/template/react-native-starter/src/lib/env.ts +12 -0
- package/template/react-native-starter/src/lib/i18n/__tests__/index.test.ts +108 -0
- package/template/react-native-starter/src/lib/i18n/__tests__/utils.test.ts +123 -0
- package/template/react-native-starter/src/lib/i18n/index.tsx +51 -0
- package/template/react-native-starter/src/lib/i18n/react-i18next.d.ts +12 -0
- package/template/react-native-starter/src/lib/i18n/resources.ts +28 -0
- package/template/react-native-starter/src/lib/i18n/types.ts +23 -0
- package/template/react-native-starter/src/lib/i18n/utils.tsx +65 -0
- package/template/react-native-starter/src/lib/index.ts +1 -0
- package/template/react-native-starter/src/lib/utils/__tests__/secure-store.test.ts +75 -0
- package/template/react-native-starter/src/lib/utils/__tests__/storage.test.ts +168 -0
- package/template/react-native-starter/src/lib/utils/blurhash.ts +29 -0
- package/template/react-native-starter/src/lib/utils/extract-error.ts +23 -0
- package/template/react-native-starter/src/lib/utils/format-currency.ts +13 -0
- package/template/react-native-starter/src/lib/utils/index.ts +2 -0
- package/template/react-native-starter/src/lib/utils/rate-app.ts +37 -0
- package/template/react-native-starter/src/lib/utils/secure-store.ts +83 -0
- package/template/react-native-starter/src/lib/utils/storage.ts +126 -0
- package/template/react-native-starter/src/lib/utils/toast-config.ts +33 -0
- package/template/react-native-starter/src/store/auth/index.ts +69 -0
- package/template/react-native-starter/src/store/auth/utils.ts +26 -0
- package/template/react-native-starter/src/store/store-utils.ts +13 -0
- package/template/react-native-starter/src/store/utility/index.tsx +39 -0
- package/template/react-native-starter/src/translations/ar.json +13 -0
- package/template/react-native-starter/src/translations/en.json +13 -0
- package/template/react-native-starter/src/translations/es.json +13 -0
- package/template/react-native-starter/src/translations/fr.json +13 -0
- package/template/react-native-starter/src/types/expo-asset.d.ts +9 -0
- package/template/react-native-starter/tailwind.config.js +18 -0
- package/template/react-native-starter/tsconfig.json +7 -9
- package/template/react-native-starter/app/_layout.tsx +0 -5
- package/template/react-native-starter/app/index.tsx +0 -86
- package/template/react-native-starter/app.json +0 -50
- /package/template/react-native-starter/src/{state → store}/useCounterStore.ts +0 -0
package/README.md
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
# Create Twinbloc App
|
|
2
2
|
|
|
3
|
-
Create a React Native app from the Twinbloc starter template.
|
|
3
|
+
Create a React Native app from the Twinbloc starter template (Expo + Expo Router).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 18+
|
|
8
|
+
- npm, yarn, pnpm, or bun
|
|
9
|
+
- Xcode for iOS (macOS) and/or Android Studio for Android
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
6
12
|
|
|
7
13
|
```bash
|
|
8
14
|
npx create-twinbloc-app@latest MyApp
|
|
15
|
+
cd MyApp
|
|
16
|
+
npm run start
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Using Other Package Managers
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn create twinbloc-app MyApp
|
|
23
|
+
pnpm create twinbloc-app MyApp
|
|
24
|
+
bun create twinbloc-app MyApp
|
|
9
25
|
```
|
|
10
26
|
|
|
11
27
|
## Options
|
|
@@ -19,6 +35,41 @@ npx create-twinbloc-app@latest MyApp --pm pnpm
|
|
|
19
35
|
npx create-twinbloc-app@latest MyApp --pm bun
|
|
20
36
|
```
|
|
21
37
|
|
|
22
|
-
##
|
|
38
|
+
## Running the App (Dev Client)
|
|
39
|
+
|
|
40
|
+
This template uses a development build. After creating the project:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd MyApp
|
|
44
|
+
npm run start
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Then build and open a dev client:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx expo run:ios
|
|
51
|
+
npx expo run:android
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Project Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
MyApp/
|
|
58
|
+
app/ # Expo Router routes
|
|
59
|
+
assets/ # Images and icons
|
|
60
|
+
src/ # App state and shared utilities
|
|
61
|
+
app.json # Expo configuration
|
|
62
|
+
package.json # Scripts and dependencies
|
|
63
|
+
tsconfig.json # TypeScript config
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Template Details
|
|
67
|
+
|
|
68
|
+
- Location: `template/react-native-starter`
|
|
69
|
+
- Framework: Expo SDK 54 + Expo Router
|
|
70
|
+
- State: Zustand example in `src/state`
|
|
71
|
+
|
|
72
|
+
## Troubleshooting
|
|
23
73
|
|
|
24
|
-
|
|
74
|
+
- If install fails, retry with `--pm` to force a package manager.
|
|
75
|
+
- If the folder is not empty, choose a new directory name.
|
package/bin/cli.js
CHANGED
|
@@ -5,6 +5,8 @@ import fs from "fs-extra";
|
|
|
5
5
|
import { spawnSync } from "child_process";
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
|
+
import readline from "readline";
|
|
9
|
+
import { stdin as input, stdout as output } from "process";
|
|
8
10
|
|
|
9
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
12
|
const __dirname = path.dirname(__filename);
|
|
@@ -64,6 +66,115 @@ const runInstall = (dir, pm) => {
|
|
|
64
66
|
if (result.status !== 0) process.exit(result.status);
|
|
65
67
|
};
|
|
66
68
|
|
|
69
|
+
const brandPrimary = chalk.hex("#6CABDD");
|
|
70
|
+
const brandDeep = chalk.hex("#1C2C5B");
|
|
71
|
+
|
|
72
|
+
const printBanner = () => {
|
|
73
|
+
const lines = [
|
|
74
|
+
"████████╗██╗ ██╗██╗███╗ ██╗██████╗ ██╗ ██████╗ ██████╗",
|
|
75
|
+
"╚══██╔══╝██║ ██║██║████╗ ██║██╔══██╗██║ ██╔═══██╗██╔════╝",
|
|
76
|
+
" ██║ ██║ █╗ ██║██║██╔██╗ ██║██████╔╝██║ ██║ ██║██║",
|
|
77
|
+
" ██║ ██║███╗██║██║██║╚██╗██║██╔══██╗██║ ██║ ██║██║",
|
|
78
|
+
" ██║ ╚███╔███╔╝██║██║ ╚████║██████╔╝███████╗╚██████╔╝╚██████╗",
|
|
79
|
+
" ╚═╝ ╚══╝╚══╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝",
|
|
80
|
+
];
|
|
81
|
+
lines.forEach((line, index) => {
|
|
82
|
+
const paint = index < 3 ? brandPrimary : brandDeep;
|
|
83
|
+
console.log(paint(line));
|
|
84
|
+
});
|
|
85
|
+
console.log(brandPrimary("React Native Starter"));
|
|
86
|
+
console.log("");
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const agentDirectories = [
|
|
90
|
+
{ key: "Antigravity", path: ".agents", label: ".agents/skills" },
|
|
91
|
+
{ key: "agent", path: ".agent", label: ".agent/skills" },
|
|
92
|
+
{ key: "claude", path: ".claude", label: ".claude/skills" },
|
|
93
|
+
{ key: "codex", path: ".codex", label: ".codex/skills" },
|
|
94
|
+
{ key: "cursor", path: ".cursor", label: ".cursor/skills" },
|
|
95
|
+
{ key: "github", path: ".github", label: ".github/skills" },
|
|
96
|
+
{ key: "kilocode", path: ".kilocode", label: ".kilocode/skills" },
|
|
97
|
+
{ key: "opencode", path: ".opencode", label: ".opencode/skills" },
|
|
98
|
+
{ key: "trae", path: ".trae", label: ".trae" },
|
|
99
|
+
{ key: "vscode", path: ".vscode", label: ".vscode" },
|
|
100
|
+
{ key: "windsurf", path: ".windsurf", label: ".windsurf" },
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const getExistingAgentKeys = async (rootDir) => {
|
|
104
|
+
const existing = new Set();
|
|
105
|
+
for (const dir of agentDirectories) {
|
|
106
|
+
if (await fs.pathExists(path.join(rootDir, dir.path))) {
|
|
107
|
+
existing.add(dir.key);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return existing;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const renderAgentSelection = (choices, selectedKeys, activeIndex) => {
|
|
114
|
+
output.write("\x1b[2J\x1b[0;0H");
|
|
115
|
+
printBanner();
|
|
116
|
+
console.log(brandPrimary.bold("Select agent configs to include:"));
|
|
117
|
+
console.log(brandDeep("Use ↑/↓ to move, space to toggle, enter to confirm."));
|
|
118
|
+
console.log(brandDeep("Press enter with nothing selected for none."));
|
|
119
|
+
console.log("");
|
|
120
|
+
|
|
121
|
+
choices.forEach((choice, index) => {
|
|
122
|
+
const isActive = index === activeIndex;
|
|
123
|
+
const isSelected = selectedKeys.has(choice.key);
|
|
124
|
+
const cursor = isActive ? ">" : " ";
|
|
125
|
+
const mark = isSelected ? "x" : " ";
|
|
126
|
+
const line = `${cursor} [${mark}] ${choice.label}`;
|
|
127
|
+
console.log(isActive ? brandPrimary.bold(line) : brandDeep(line));
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const promptAgentSelection = async (choices, defaultKeys) => {
|
|
132
|
+
readline.emitKeypressEvents(input);
|
|
133
|
+
if (input.isTTY) {
|
|
134
|
+
input.setRawMode(true);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const selectedKeys = new Set(defaultKeys);
|
|
138
|
+
let activeIndex = 0;
|
|
139
|
+
|
|
140
|
+
renderAgentSelection(choices, selectedKeys, activeIndex);
|
|
141
|
+
|
|
142
|
+
return new Promise((resolve) => {
|
|
143
|
+
const onKeypress = (_str, key) => {
|
|
144
|
+
if (key.name === "up") {
|
|
145
|
+
activeIndex = (activeIndex - 1 + choices.length) % choices.length;
|
|
146
|
+
renderAgentSelection(choices, selectedKeys, activeIndex);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (key.name === "down") {
|
|
150
|
+
activeIndex = (activeIndex + 1) % choices.length;
|
|
151
|
+
renderAgentSelection(choices, selectedKeys, activeIndex);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (key.name === "space") {
|
|
155
|
+
const choice = choices[activeIndex];
|
|
156
|
+
if (selectedKeys.has(choice.key)) {
|
|
157
|
+
selectedKeys.delete(choice.key);
|
|
158
|
+
} else {
|
|
159
|
+
selectedKeys.add(choice.key);
|
|
160
|
+
}
|
|
161
|
+
renderAgentSelection(choices, selectedKeys, activeIndex);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (key.name === "return") {
|
|
165
|
+
input.off("keypress", onKeypress);
|
|
166
|
+
if (input.isTTY) {
|
|
167
|
+
input.setRawMode(false);
|
|
168
|
+
}
|
|
169
|
+
output.write("\n");
|
|
170
|
+
resolve(selectedKeys);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
input.on("keypress", onKeypress);
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
67
178
|
const main = async () => {
|
|
68
179
|
const empty = await isEmptyDir(targetDir);
|
|
69
180
|
if (!empty) {
|
|
@@ -89,10 +200,20 @@ const main = async () => {
|
|
|
89
200
|
await fs.copy(examplePath, targetDir, { overwrite: true });
|
|
90
201
|
}
|
|
91
202
|
|
|
203
|
+
const existingAgentKeys = await getExistingAgentKeys(targetDir);
|
|
204
|
+
const defaultKeys = agentDirectories.filter((dir) => existingAgentKeys.has(dir.key)).map((dir) => dir.key);
|
|
205
|
+
|
|
206
|
+
const selectedKeys = await promptAgentSelection(agentDirectories, defaultKeys);
|
|
207
|
+
const selectedLabels = agentDirectories.filter((dir) => selectedKeys.has(dir.key)).map((dir) => dir.label);
|
|
208
|
+
|
|
209
|
+
const dirsToRemove = agentDirectories.filter((dir) => !selectedKeys.has(dir.key));
|
|
210
|
+
await Promise.all(dirsToRemove.map((dir) => fs.remove(path.join(targetDir, dir.path))));
|
|
211
|
+
|
|
212
|
+
const appName = path.basename(targetDir);
|
|
92
213
|
const targetPackageJson = path.join(targetDir, "package.json");
|
|
93
214
|
if (fs.existsSync(targetPackageJson)) {
|
|
94
215
|
const pkg = await fs.readJson(targetPackageJson);
|
|
95
|
-
pkg.name =
|
|
216
|
+
pkg.name = appName;
|
|
96
217
|
await fs.writeJson(targetPackageJson, pkg, { spaces: 2 });
|
|
97
218
|
}
|
|
98
219
|
|
|
@@ -104,7 +225,25 @@ const main = async () => {
|
|
|
104
225
|
runInstall(targetDir, pm);
|
|
105
226
|
}
|
|
106
227
|
|
|
107
|
-
|
|
228
|
+
printBanner();
|
|
229
|
+
console.log(
|
|
230
|
+
[
|
|
231
|
+
brandPrimary.bold("Project created successfully."),
|
|
232
|
+
"",
|
|
233
|
+
brandDeep(`Agent configs: ${selectedLabels.length > 0 ? selectedLabels.join(", ") : "none"}`),
|
|
234
|
+
"",
|
|
235
|
+
brandPrimary("Next steps:"),
|
|
236
|
+
brandDeep(` cd ${appName}`),
|
|
237
|
+
options.skipInstall ? brandDeep(" npm install") : null,
|
|
238
|
+
brandDeep(" npm run start"),
|
|
239
|
+
"",
|
|
240
|
+
brandPrimary("Then:"),
|
|
241
|
+
brandDeep(" - Build a dev client (if you haven’t): npx expo run:ios / npx expo run:android"),
|
|
242
|
+
brandDeep(" - Open the app from the dev client on your device or simulator"),
|
|
243
|
+
]
|
|
244
|
+
.filter(Boolean)
|
|
245
|
+
.join("\n"),
|
|
246
|
+
);
|
|
108
247
|
};
|
|
109
248
|
|
|
110
249
|
main().catch((error) => {
|