@chem-x/starter-kit 26.9.20-1318 → 26.9.20-1340

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/cli/create.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import fs from 'node:fs';
3
4
  import { runScaffold } from './scaffold.js';
4
5
  import { runAudit } from './index.js';
5
6
  import { sanitizeOutputStreams } from './terminal.js';
@@ -9,6 +10,43 @@ sanitizeOutputStreams();
9
10
  installGlobalErrorCatcher();
10
11
 
11
12
  const rawArgs = process.argv.slice(2);
13
+
14
+ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
15
+ process.stdout.write(`
16
+ Chemical X Protocol: Project Scaffolder
17
+
18
+ USAGE
19
+ npm create chemx [directory] [options]
20
+ npx create-chemx [directory] [options]
21
+
22
+ OPTIONS
23
+ --yes, -y Skip interactive prompts and scaffold Community Edition immediately
24
+ --headless Run in headless mode for CI/CD and AI agent automation
25
+ -h, --help Show this help message
26
+ -v, --version Show version number
27
+
28
+ EXAMPLES
29
+ npm create chemx my-molecular-app
30
+ npx create-chemx my-molecular-app --yes
31
+ pnpm create chemx my-app
32
+
33
+ DOCUMENTATION
34
+ https://chemicalx.xophz.com
35
+ \n`);
36
+ process.exit(0);
37
+ }
38
+
39
+ if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
40
+ try {
41
+ const pkgPath = new URL('../package.json', import.meta.url);
42
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
43
+ process.stdout.write(`create-chemx v${pkg.version || 'unknown'}\n`);
44
+ } catch {
45
+ process.stdout.write('create-chemx\n');
46
+ }
47
+ process.exit(0);
48
+ }
49
+
12
50
  const nonFlagArgs = rawArgs.filter((arg) => !arg.startsWith('-'));
13
51
  const dirArg = (nonFlagArgs[0] === 'create' || nonFlagArgs[0] === 'init' || nonFlagArgs[0] === 'scaffold')
14
52
  ? nonFlagArgs[1]
@@ -56,6 +56,36 @@ describe('Scaffolding Entrypoint Invocations', () => {
56
56
  assert.ok(fs.existsSync(path.join(defaultTarget, 'package.json')), 'package.json should exist in default directory');
57
57
  });
58
58
 
59
+ test('node cli/create.js --help prints usage and does not scaffold', () => {
60
+ const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-test-'));
61
+ cleanupDirs.push(tmpBase);
62
+
63
+ const result = spawnSync('node', [CREATE_BIN, '--help'], {
64
+ encoding: 'utf-8',
65
+ cwd: tmpBase,
66
+ timeout: 5000
67
+ });
68
+
69
+ assert.equal(result.status, 0, 'Should exit with code 0 on --help');
70
+ assert.match(result.stdout, /Chemical X Protocol: Project Scaffolder/, 'Should show scaffolder help');
71
+ assert.ok(!fs.existsSync(path.join(tmpBase, 'my-molecular-app')), 'Must not scaffold any directory on --help');
72
+ });
73
+
74
+ test('node cli/create.js --version prints version and does not scaffold', () => {
75
+ const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-test-'));
76
+ cleanupDirs.push(tmpBase);
77
+
78
+ const result = spawnSync('node', [CREATE_BIN, '--version'], {
79
+ encoding: 'utf-8',
80
+ cwd: tmpBase,
81
+ timeout: 5000
82
+ });
83
+
84
+ assert.equal(result.status, 0, 'Should exit with code 0 on --version');
85
+ assert.match(result.stdout, /create-chemx v/, 'Should print create-chemx version');
86
+ assert.ok(!fs.existsSync(path.join(tmpBase, 'my-molecular-app')), 'Must not scaffold any directory on --version');
87
+ });
88
+
59
89
  test('node cli/create.js create <dir> --yes tolerates redundant create argument', () => {
60
90
  const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-test-'));
61
91
  cleanupDirs.push(tmpBase);
@@ -133,14 +163,38 @@ describe('Scaffolding Entrypoint Invocations', () => {
133
163
  assert.ok(fs.existsSync(path.join(targetDir, 'package.json')), 'package.json should exist');
134
164
  });
135
165
 
136
- test('node cli/index.js config still fails fast as unknown command', () => {
166
+ test('node cli/index.js config fails fast as unknown command without creating directory', () => {
167
+ const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-test-'));
168
+ cleanupDirs.push(tmpBase);
169
+
137
170
  const result = spawnSync('node', [INDEX_BIN, 'config'], {
138
171
  encoding: 'utf-8',
172
+ cwd: tmpBase,
139
173
  timeout: 5000
140
174
  });
141
175
 
142
176
  assert.equal(result.status, 1, 'Unknown command should exit with code 1');
143
177
  assert.match(result.stderr, /Unknown command "config"/, 'Should report unknown command');
178
+ assert.ok(!fs.existsSync(path.join(tmpBase, 'config')), 'Must NOT create a config directory');
144
179
  });
145
- });
146
180
 
181
+ test('node cli/index.js under create-chemx path STILL fails fast on unknown command (regression test)', () => {
182
+ const tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-test-'));
183
+ cleanupDirs.push(tmpBase);
184
+ // Simulate being installed inside a path with "create-chemx" in its name
185
+ const pkgDir = path.join(tmpBase, 'node_modules', '@chemx', 'create-chemx', 'cli');
186
+ fs.mkdirSync(pkgDir, { recursive: true });
187
+ const fakeIndex = path.join(pkgDir, 'index.js');
188
+ fs.symlinkSync(INDEX_BIN, fakeIndex);
189
+
190
+ const result = spawnSync('node', [fakeIndex, 'config'], {
191
+ encoding: 'utf-8',
192
+ cwd: tmpBase,
193
+ timeout: 5000
194
+ });
195
+
196
+ assert.equal(result.status, 1, 'Unknown command should exit with code 1');
197
+ assert.match(result.stderr, /Unknown command "config"/, 'Should report unknown command');
198
+ assert.ok(!fs.existsSync(path.join(tmpBase, 'config')), 'Must NOT create a config directory when installed under create-chemx path');
199
+ });
200
+ });
package/cli/index.js CHANGED
@@ -83,11 +83,6 @@ const loadProjectConfig = () => {
83
83
  return {};
84
84
  }
85
85
  };
86
- const isCreateInvoked =
87
- invokedBin.includes('create') ||
88
- Boolean(process.argv[1] && process.argv[1].includes('create-chemx')) ||
89
- Boolean(process.env.npm_lifecycle_event && process.env.npm_lifecycle_event.includes('create')) ||
90
- Boolean(rawArgs[0] && (rawArgs[0] === 'create' || rawArgs[0] === 'init' || rawArgs[0] === 'scaffold'));
91
86
 
92
87
  export const runAudit = async (customDir = null, isCli = false) => {
93
88
  const projectConfig = loadProjectConfig();
@@ -296,15 +291,6 @@ export {
296
291
  const main = async () => {
297
292
  const firstArg = rawArgs[0];
298
293
 
299
- if (isCreateInvoked) {
300
- const nonFlagArgs = rawArgs.filter((arg) => !arg.startsWith('-'));
301
- const dirArg = (nonFlagArgs[0] === 'create' || nonFlagArgs[0] === 'init' || nonFlagArgs[0] === 'scaffold')
302
- ? nonFlagArgs[1]
303
- : nonFlagArgs[0];
304
- await runScaffold(dirArg, rawArgs, runAudit);
305
- return;
306
- }
307
-
308
294
  switch (firstArg) {
309
295
  case 'team':
310
296
  case 'swarm':
@@ -346,7 +332,8 @@ const main = async () => {
346
332
  case 'init':
347
333
  await runInit(rawArgs[1] || 'src/chemical-x', rawArgs, runAudit);
348
334
  break;
349
- case 'create': {
335
+ case 'create':
336
+ case 'scaffold': {
350
337
  const nonFlagArgs = rawArgs.slice(1).filter((arg) => !arg.startsWith('-'));
351
338
  await runScaffold(nonFlagArgs[0], rawArgs, runAudit);
352
339
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chem-x/starter-kit",
3
- "version": "26.9.20-1318",
3
+ "version": "26.9.20-1340",
4
4
  "description": "Chemical X Protocol: Private drop-in architecture starter kit and capsule generator",
5
5
  "type": "module",
6
6
  "bin": {