create-semaphor-app 0.1.5 → 0.1.6

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 CHANGED
@@ -35,8 +35,8 @@ Options:
35
35
  --template-ref <ref> Git branch/tag for the default starter repo. Defaults to main.
36
36
  --shadcn-preset <preset> Apply a shadcn preset before adding Semaphor components.
37
37
  --shadcn-base <base> Pass base or radix to shadcn init when using a preset.
38
- --components <list> Add Semaphor registry components. Defaults to all. Use none, query, metrics,
39
- filters, card, table, matrix, recommended, all, or a comma-separated list.
38
+ --components <list> Add Semaphor registry components. Defaults to all. Use none, kit, query,
39
+ metrics, filters, card, table, matrix, recommended, all, or a comma-separated list.
40
40
  --yes Use noninteractive defaults; skip optional plugin installs unless explicit.
41
41
  --help Show help.
42
42
  ```
@@ -67,6 +67,7 @@ Component presets:
67
67
  | Value | Installs |
68
68
  | --- | --- |
69
69
  | `none` | No Semaphor registry components. |
70
+ | `kit` | `data-app-kit`, the one-command registry bundle. |
70
71
  | `query` | `query-state` |
71
72
  | `metrics` | `query-state-boundary`, `metric-kpis` |
72
73
  | `filters` | `filter-controls` |
@@ -74,10 +75,16 @@ Component presets:
74
75
  | `table` | `query-state`, `server-data-table` |
75
76
  | `matrix` | `query-state`, `matrix-table` |
76
77
  | `recommended` | `query-state`, `query-state-boundary`, `view-card`, `metric-kpis`, `filter-controls`, `server-data-table` |
77
- | `all` | `query-state`, `query-state-boundary`, `view-card`, `metric-kpis`, `filter-controls`, `server-data-table`, `matrix-table`. This is the default. |
78
+ | `all` | Full component set, installed through `data-app-kit`. This is the default. |
78
79
 
79
80
  Registry components install as source into the generated app. They are optional
80
81
  UI accelerators and do not replace `react-semaphor/data-app-sdk`.
82
+ The default starter keeps its shadcn primitives aligned with the public
83
+ registry, so default component installs should not ask overwrite questions.
84
+ `create-semaphor-app` does not pass `--overwrite`; customer-owned base
85
+ components stay intact. During the `data-app-kit` rollout, the CLI falls back
86
+ to one multi-component install if an older registry deployment does not have
87
+ the kit item yet.
81
88
 
82
89
  `--shadcn-preset` and installed registry components run the shadcn CLI. To skip
83
90
  installs, pass `--no-install --components none`, then run the shadcn commands
@@ -14,6 +14,7 @@ const DEFAULT_APP_NAME = 'semaphor-data-app';
14
14
  const MARKETPLACE = 'semaphor-analytics/agent-plugin';
15
15
  const PLUGIN_ID = 'semaphor@semaphor-analytics';
16
16
  const SEMAPHOR_COMPONENT_REGISTRY = 'semaphor-analytics/semaphor-data-app-components';
17
+ const SEMAPHOR_COMPONENT_KIT = 'data-app-kit';
17
18
  const SEMAPHOR_COMPONENT_PRESETS = Object.freeze({
18
19
  none: [],
19
20
  query: ['query-state'],
@@ -41,6 +42,8 @@ const SEMAPHOR_COMPONENT_PRESETS = Object.freeze({
41
42
  ],
42
43
  });
43
44
  const SEMAPHOR_COMPONENT_ALIASES = Object.freeze({
45
+ kit: SEMAPHOR_COMPONENT_KIT,
46
+ 'data-app-kit': SEMAPHOR_COMPONENT_KIT,
44
47
  'query-state': 'query-state',
45
48
  'query-state-boundary': 'query-state-boundary',
46
49
  'view-card': 'view-card',
@@ -74,8 +77,8 @@ Options:
74
77
  --template-ref <ref> Git branch/tag for the default starter repo.
75
78
  --shadcn-preset <preset> Apply a shadcn preset before adding Semaphor components.
76
79
  --shadcn-base <base> Pass base or radix to shadcn init when using a preset.
77
- --components <list> Add Semaphor registry components. Defaults to all. Use none, query, metrics,
78
- filters, card, table, matrix, recommended, all, or a comma-separated list.
80
+ --components <list> Add Semaphor registry components. Defaults to all. Use none, kit, query,
81
+ metrics, filters, card, table, matrix, recommended, all, or a comma-separated list.
79
82
  --yes, -y Use noninteractive defaults; skip optional plugin installs unless explicit.
80
83
  --help, -h Show this help.
81
84
  `;
@@ -407,7 +410,7 @@ function normalizeSemaphorComponents(value) {
407
410
  }
408
411
  if (!hasOwn(SEMAPHOR_COMPONENT_ALIASES, entry)) {
409
412
  throw new Error(
410
- `Unsupported Semaphor component "${entry}". Use none, query, metrics, filters, card, table, matrix, recommended, all, or one of ${Object.keys(SEMAPHOR_COMPONENT_ALIASES).join(', ')}.`,
413
+ `Unsupported Semaphor component "${entry}". Use none, kit, query, metrics, filters, card, table, matrix, recommended, all, or one of ${Object.keys(SEMAPHOR_COMPONENT_ALIASES).join(', ')}.`,
411
414
  );
412
415
  }
413
416
  components.push(SEMAPHOR_COMPONENT_ALIASES[entry]);
@@ -453,6 +456,44 @@ function runShadcn(packageManager, targetDir, args) {
453
456
  });
454
457
  }
455
458
 
459
+ function selectedComponentsUseFullKit(components) {
460
+ const selected = new Set(components);
461
+ const full = SEMAPHOR_COMPONENT_PRESETS.all;
462
+ return selected.size === full.length && full.every((component) => selected.has(component));
463
+ }
464
+
465
+ function componentRegistryAddress(component) {
466
+ return `${SEMAPHOR_COMPONENT_REGISTRY}/${component}`;
467
+ }
468
+
469
+ function installSemaphorRegistryComponents(packageManager, targetDir, components) {
470
+ if (components.length === 0) return [];
471
+
472
+ if (selectedComponentsUseFullKit(components)) {
473
+ try {
474
+ runShadcn(packageManager, targetDir, [
475
+ 'add',
476
+ componentRegistryAddress(SEMAPHOR_COMPONENT_KIT),
477
+ ]);
478
+ console.log(`✓ Added ${SEMAPHOR_COMPONENT_KIT}`);
479
+ return [SEMAPHOR_COMPONENT_KIT];
480
+ } catch {
481
+ console.log(
482
+ 'data-app-kit was not available from the registry yet; falling back to individual Semaphor components.',
483
+ );
484
+ }
485
+ }
486
+
487
+ runShadcn(packageManager, targetDir, [
488
+ 'add',
489
+ ...components.map(componentRegistryAddress),
490
+ ]);
491
+ for (const component of components) {
492
+ console.log(`✓ Added ${component}`);
493
+ }
494
+ return components;
495
+ }
496
+
456
497
  function customizeShadcn(args, packageManager, targetDir) {
457
498
  const components = normalizeSemaphorComponents(args.components);
458
499
  const shadcnBase = normalizeShadcnBase(args.shadcnBase);
@@ -481,13 +522,7 @@ function customizeShadcn(args, packageManager, targetDir) {
481
522
 
482
523
  if (components.length > 0) {
483
524
  console.log('\nAdding Semaphor registry components...');
484
- for (const component of components) {
485
- runShadcn(packageManager, targetDir, [
486
- 'add',
487
- `${SEMAPHOR_COMPONENT_REGISTRY}/${component}`,
488
- ]);
489
- console.log(`✓ Added ${component}`);
490
- }
525
+ installSemaphorRegistryComponents(packageManager, targetDir, components);
491
526
  }
492
527
 
493
528
  return { presetApplied: Boolean(args.shadcnPreset), components };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-semaphor-app",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Create a Semaphor Data App starter project.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -205,20 +205,10 @@ async function main() {
205
205
  const npmInstallLog = fs.readFileSync(npmLog, 'utf8');
206
206
  assert(npmInstallLog.includes('npm install'), 'expected npm install command');
207
207
  const log = fs.readFileSync(shadcnLog, 'utf8');
208
- for (const component of [
209
- 'query-state',
210
- 'query-state-boundary',
211
- 'view-card',
212
- 'metric-kpis',
213
- 'filter-controls',
214
- 'server-data-table',
215
- 'matrix-table',
216
- ]) {
217
- assert(
218
- log.includes(`npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/${component}`),
219
- `expected default ${component} registry add command`,
220
- );
221
- }
208
+ assert(
209
+ log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/data-app-kit'),
210
+ 'expected default data-app-kit registry add command',
211
+ );
222
212
  console.log('✓ default Semaphor registry component install');
223
213
  }
224
214
 
@@ -262,34 +252,89 @@ async function main() {
262
252
  'expected shadcn preset init command',
263
253
  );
264
254
  assert(
265
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/query-state'),
266
- 'expected query-state registry add command',
267
- );
268
- assert(
269
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/query-state-boundary'),
270
- 'expected query-state-boundary registry add command',
271
- );
272
- assert(
273
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/view-card'),
274
- 'expected view-card registry add command',
275
- );
276
- assert(
277
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/metric-kpis'),
278
- 'expected metric-kpis registry add command',
279
- );
280
- assert(
281
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/filter-controls'),
282
- 'expected filter-controls registry add command',
255
+ log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/data-app-kit'),
256
+ 'expected full component selection to use data-app-kit registry add command',
283
257
  );
258
+ console.log('✓ shadcn preset and registry component path');
259
+ }
260
+
261
+ {
262
+ const root = createTempRoot('component-kit-alias-');
263
+ const binDir = path.join(root, 'bin');
264
+ fs.mkdirSync(binDir, { recursive: true });
265
+ const shadcnLog = path.join(root, 'shadcn.log');
266
+ const npmLog = path.join(root, 'npm.log');
267
+ createFakeCommand(binDir, 'npx', shadcnLog);
268
+ createFakeCommand(binDir, 'npm', npmLog);
269
+
270
+ const result = runCli([
271
+ 'kit-alias-app',
272
+ '--template',
273
+ defaultLocalStarterPath,
274
+ '--skip-plugin',
275
+ '--yes',
276
+ '--package-manager',
277
+ 'npm',
278
+ '--components',
279
+ 'kit',
280
+ ], {
281
+ cwd: root,
282
+ env: {
283
+ ...process.env,
284
+ PATH: `${binDir}${path.delimiter}${process.env.PATH || ''}`,
285
+ },
286
+ });
287
+ assertSuccess(result, 'component kit alias install');
288
+ assertScaffold(root, 'kit-alias-app');
289
+ const log = fs.readFileSync(shadcnLog, 'utf8');
284
290
  assert(
285
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/server-data-table'),
286
- 'expected server-data-table registry add command',
291
+ log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/data-app-kit'),
292
+ 'expected kit alias to use data-app-kit registry add command',
287
293
  );
294
+ console.log('✓ Semaphor data-app-kit component alias');
295
+ }
296
+
297
+ {
298
+ const root = createTempRoot('component-subset-');
299
+ const binDir = path.join(root, 'bin');
300
+ fs.mkdirSync(binDir, { recursive: true });
301
+ const shadcnLog = path.join(root, 'shadcn.log');
302
+ const npmLog = path.join(root, 'npm.log');
303
+ createFakeCommand(binDir, 'npx', shadcnLog);
304
+ createFakeCommand(binDir, 'npm', npmLog);
305
+
306
+ const result = runCli([
307
+ 'subset-app',
308
+ '--template',
309
+ defaultLocalStarterPath,
310
+ '--skip-plugin',
311
+ '--yes',
312
+ '--package-manager',
313
+ 'npm',
314
+ '--components',
315
+ 'table,filters',
316
+ ], {
317
+ cwd: root,
318
+ env: {
319
+ ...process.env,
320
+ PATH: `${binDir}${path.delimiter}${process.env.PATH || ''}`,
321
+ },
322
+ });
323
+ assertSuccess(result, 'component subset install');
324
+ assertScaffold(root, 'subset-app');
325
+ const log = fs.readFileSync(shadcnLog, 'utf8');
288
326
  assert(
289
- log.includes('npx shadcn@latest add semaphor-analytics/semaphor-data-app-components/matrix-table'),
290
- 'expected matrix-table registry add command',
327
+ log.includes(
328
+ [
329
+ 'npx shadcn@latest add',
330
+ 'semaphor-analytics/semaphor-data-app-components/query-state',
331
+ 'semaphor-analytics/semaphor-data-app-components/server-data-table',
332
+ 'semaphor-analytics/semaphor-data-app-components/filter-controls',
333
+ ].join(' '),
334
+ ),
335
+ 'expected subset components to install in one registry add command',
291
336
  );
292
- console.log('✓ shadcn preset and registry component path');
337
+ console.log('✓ Semaphor component subset installs in one command');
293
338
  }
294
339
 
295
340
  {