create-twinbloc-app 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/cli.js +37 -16
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -69,10 +69,11 @@ const runInstall = (dir, pm) => {
69
69
  const brandPrimary = chalk.hex("#6CABDD");
70
70
  const brandDeep = chalk.hex("#1C2C5B");
71
71
  const rnBlue = chalk.hex("#61DAFB");
72
- const uiMuted = chalk.gray;
73
- const uiAccent = chalk.hex("#9FD7F2");
74
- const uiActive = chalk.hex("#88C6FF");
75
- const uiSelected = chalk.hex("#6EDC91");
72
+ const uiMuted = chalk.hex("#A0A0A0");
73
+ const uiAccent = chalk.hex("#00F0FF");
74
+ const uiActive = chalk.hex("#FFFFFF");
75
+ const uiSelected = chalk.hex("#00FF9D");
76
+ const uiHighlight = chalk.hex("#FF79C6");
76
77
 
77
78
  const printBanner = () => {
78
79
  const lines = [
@@ -93,16 +94,16 @@ const printBanner = () => {
93
94
  };
94
95
 
95
96
  const agentDirectories = [
96
- { key: "antigravity", path: ".agents/skills", label: "Antigravity" },
97
97
  { key: "agent", path: ".agent/skills", label: "Vscode" },
98
+ { key: "cursor", path: ".cursor", label: "Cursor" },
98
99
  { key: "claude", path: ".claude/skills", label: "Claude" },
100
+ { key: "windsurf", path: ".windsurf/skills", label: "Windsurf" },
99
101
  { key: "codex", path: ".codex/skills", label: "Codex" },
100
- { key: "cursor", path: ".cursor", label: "Cursor" },
102
+ { key: "antigravity", path: ".agents/skills", label: "Antigravity" },
101
103
  { key: "github", path: ".github/skills", label: "Github" },
102
104
  { key: "kilocode", path: ".kilocode/skills", label: "Kilocode" },
103
105
  { key: "opencode", path: ".opencode/skills", label: "Opencode" },
104
106
  { key: "trae", path: ".trae/skills", label: "Trae" },
105
- { key: "windsurf", path: ".windsurf/skills", label: "Windsurf" },
106
107
  ];
107
108
 
108
109
  const getExistingAgentKeys = async (rootDir) => {
@@ -118,7 +119,7 @@ const getExistingAgentKeys = async (rootDir) => {
118
119
  const renderAgentSelectionHeader = () => {
119
120
  output.write("\x1b[2J\x1b[0;0H");
120
121
  printBanner();
121
- console.log(brandPrimary.bold("Select agent configs"));
122
+ console.log(uiHighlight.bold("Select agent configs"));
122
123
  console.log(uiMuted("↑/↓ move · space toggle · enter confirm · empty = none"));
123
124
  console.log("");
124
125
  };
@@ -136,7 +137,7 @@ const renderAgentSelectionList = (choices, selectedKeys, activeIndex, { resetCur
136
137
  const label = isSelected ? uiSelected.bold(choice.label) : uiAccent(choice.label);
137
138
  const line = ` ${pointer} ${mark} ${label}`;
138
139
  if (isActive) {
139
- console.log(chalk.bgHex("#0F2438").hex("#DDF1FF")(line));
140
+ console.log(chalk.bgHex("#0F2438").hex("#FFFFFF")(line));
140
141
  return;
141
142
  }
142
143
  console.log(line);
@@ -222,6 +223,22 @@ const main = async () => {
222
223
  const selectedKeys = await promptAgentSelection(agentDirectories, defaultKeys);
223
224
  const selectedLabels = agentDirectories.filter((dir) => selectedKeys.has(dir.key)).map((dir) => dir.label);
224
225
 
226
+ // Copy skills from .agents/skills (master source) to other selected agents
227
+ const sourceAgent = agentDirectories.find((d) => d.key === "antigravity");
228
+ const sourcePath = path.join(targetDir, sourceAgent.path);
229
+
230
+ if (await fs.pathExists(sourcePath)) {
231
+ await Promise.all(
232
+ agentDirectories
233
+ .filter((dir) => selectedKeys.has(dir.key) && dir.key !== "antigravity")
234
+ .map(async (dir) => {
235
+ const destPath = path.join(targetDir, dir.path);
236
+ await fs.ensureDir(destPath);
237
+ await fs.copy(sourcePath, destPath, { overwrite: true });
238
+ }),
239
+ );
240
+ }
241
+
225
242
  await Promise.all(agentDirectories.filter((dir) => selectedKeys.has(dir.key)).map((dir) => fs.ensureDir(path.join(targetDir, dir.path))));
226
243
 
227
244
  const dirsToRemove = agentDirectories.filter((dir) => !selectedKeys.has(dir.key));
@@ -235,28 +252,32 @@ const main = async () => {
235
252
  await fs.writeJson(targetPackageJson, pkg, { spaces: 2 });
236
253
  }
237
254
 
255
+ const pm = detectPackageManager();
256
+
238
257
  if (!options.skipInstall) {
239
- const pm = detectPackageManager();
240
258
  if (pm === "bun") {
241
259
  await cleanLockfilesForBun(targetDir);
242
260
  }
243
261
  runInstall(targetDir, pm);
244
262
  }
245
263
 
264
+ const runCommand = pm === "npm" ? "npm run" : pm;
265
+ const execCommand = pm === "npm" ? "npx" : pm;
266
+
246
267
  printBanner();
247
268
  console.log(
248
269
  [
249
- brandPrimary.bold("Project created successfully."),
270
+ uiSelected.bold("Project created successfully."),
250
271
  "",
251
272
  uiMuted(`Agent configs: ${selectedLabels.length > 0 ? selectedLabels.join(", ") : "none"}`),
252
273
  "",
253
- brandPrimary("Next steps"),
274
+ uiHighlight("Next steps"),
254
275
  uiAccent(` cd ${appName}`),
255
- options.skipInstall ? uiAccent(" npm install") : null,
256
- uiAccent(" npm run start"),
276
+ options.skipInstall ? uiAccent(` ${pm} install`) : null,
277
+ uiAccent(` ${runCommand} start`),
257
278
  "",
258
- brandPrimary("Then"),
259
- uiMuted(" - Build a dev client (if you haven’t): npx expo run:ios / npx expo run:android"),
279
+ uiHighlight("Then"),
280
+ uiMuted(` - Build a dev client (if you haven’t): ${execCommand} expo run:ios / ${execCommand} expo run:android`),
260
281
  uiMuted(" - Open the app from the dev client on your device or simulator"),
261
282
  ]
262
283
  .filter(Boolean)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-twinbloc-app",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "React Native starter template with optional examples",
5
5
  "type": "module",
6
6
  "bin": {