@chem-x/create-chemx 26.9.9-632

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 ADDED
@@ -0,0 +1,38 @@
1
+ # Chemical X Protocol: Starter Kit
2
+
3
+ [![Live App](https://img.shields.io/badge/Web%20App-chemicalx.xophz.com-06b6d4?style=for-the-badge&logo=cloudflare)](https://chemicalx.xophz.com)
4
+ [![Parent Repo](https://img.shields.io/badge/Repository-awesome--secret--sauce-8b5cf6?style=for-the-badge)](https://github.com/Chemical-X-Protocol/awesome-secret-sauce)
5
+ [![Benchmarks](https://img.shields.io/badge/Benchmarks-Agent%20Evaluations-10b981?style=for-the-badge)](https://github.com/Chemical-X-Protocol/benchmarks)
6
+
7
+ Modular architecture blueprints, production hooks, and drop-in crystalline component capsule generators for high-velocity AI coding.
8
+
9
+ ---
10
+
11
+ ## Live Interactive Portal
12
+
13
+ Access the interactive book, prompt generator, and asset vault at [https://chemicalx.xophz.com](https://chemicalx.xophz.com).
14
+
15
+ ---
16
+
17
+ ## Structure
18
+
19
+ ```
20
+ starter-kit/
21
+ ├── blueprints/
22
+ │ ├── view-template.tsx # < 20 line Table-of-Contents view blueprint
23
+ │ ├── molecule-capsule/ # Isolated crystalline molecule blueprint
24
+ │ └── composable-template.ts # Standardized 3-to-5 return state composable
25
+ ├── hooks/
26
+ │ ├── useAsyncData.ts # 3-state async pipeline with toResult
27
+ │ ├── useSelfCleaningTimer.ts # Unmount-safe timer and RAF hook
28
+ │ └── useTwoStageDecision.ts # Concept to Decision composition
29
+ └── cli/
30
+ └── index.js # Interactive capsule generator
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Licensing & Access
36
+
37
+ Unlocked for verified GitHub Sponsors and VIP license key holders of `chemical-x-protocol`.
38
+ Explore activation details at [https://chemicalx.xophz.com/#starter-kit](https://chemicalx.xophz.com/#starter-kit).
package/cli/index.js ADDED
@@ -0,0 +1,486 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import readline from 'node:readline';
7
+ import { spawnSync } from 'node:child_process';
8
+
9
+ const rawArgs = process.argv.slice(2);
10
+ const invokedBin = path.basename(process.argv[1] || '');
11
+ const isCreateInvoked = invokedBin.includes('create-chemx') || (rawArgs[0] && rawArgs[0] === 'create');
12
+
13
+ const CONFIG_DIR = path.join(os.homedir(), '.chemical-x');
14
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
15
+ const DEVICE_FILE = path.join(CONFIG_DIR, 'device_id');
16
+
17
+ const API_BASE = process.env.CHEMICAL_X_API_URL || 'https://chemicalx.xophz.com';
18
+ const URL_STANDARD = 'https://mycompassconsulting.com/buy/chemical-x/standard';
19
+ const URL_MASTER = 'https://mycompassconsulting.com/buy/chemical-x/master';
20
+
21
+ if (!fs.existsSync(CONFIG_DIR)) {
22
+ try { fs.mkdirSync(CONFIG_DIR, { recursive: true }); } catch {}
23
+ }
24
+
25
+ const openBrowser = (url) => {
26
+ const platform = process.platform;
27
+ try {
28
+ if (platform === 'darwin') spawnSync('open', [url], { stdio: 'ignore' });
29
+ else if (platform === 'win32') spawnSync('cmd.exe', ['/c', 'start', '""', url], { stdio: 'ignore' });
30
+ else spawnSync('xdg-open', [url], { stdio: 'ignore' });
31
+ } catch {}
32
+ };
33
+
34
+ const hasGum = () => {
35
+ try {
36
+ return spawnSync('which', ['gum'], { stdio: 'ignore' }).status === 0;
37
+ } catch {
38
+ return false;
39
+ }
40
+ };
41
+
42
+ const gumChoose = (options, header = '') => {
43
+ const args = ['choose', ...options];
44
+ if (header) args.unshift(`--header=${header}`);
45
+ const res = spawnSync('gum', args, { encoding: 'utf-8', stdio: ['inherit', 'pipe', 'inherit'] });
46
+ return (res.stdout || '').trim();
47
+ };
48
+
49
+ const gumInput = (promptText, placeholder = '', isPassword = false) => {
50
+ const args = ['input', `--prompt=${promptText} `, `--placeholder=${placeholder}`];
51
+ if (isPassword) args.push('--password');
52
+ const res = spawnSync('gum', args, { encoding: 'utf-8', stdio: ['inherit', 'pipe', 'inherit'] });
53
+ return (res.stdout || '').trim();
54
+ };
55
+
56
+ const promptQuestion = (query) => {
57
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
58
+ return new Promise((resolve) => {
59
+ rl.question(query, (answer) => {
60
+ rl.close();
61
+ resolve(answer.trim());
62
+ });
63
+ });
64
+ };
65
+
66
+ const getOrCreateDeviceId = () => {
67
+ if (fs.existsSync(DEVICE_FILE)) {
68
+ try {
69
+ const id = fs.readFileSync(DEVICE_FILE, 'utf-8').trim();
70
+ if (id) return id;
71
+ } catch {}
72
+ }
73
+ const newId = `cli_${Math.random().toString(36).substring(2, 12)}_${Date.now()}`;
74
+ try { fs.writeFileSync(DEVICE_FILE, newId, 'utf-8'); } catch {}
75
+ return newId;
76
+ };
77
+
78
+ const getCachedLicenseKey = () => {
79
+ if (fs.existsSync(CONFIG_FILE)) {
80
+ try {
81
+ const data = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
82
+ return data.licenseKey || null;
83
+ } catch {
84
+ return null;
85
+ }
86
+ }
87
+ return null;
88
+ };
89
+
90
+ const saveLicenseKey = (licenseKey) => {
91
+ try {
92
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify({ licenseKey, updatedAt: new Date().toISOString() }, null, 2), 'utf-8');
93
+ } catch {}
94
+ };
95
+
96
+ const renderBanner = (title = 'Chemical X Protocol: Quantum Architecture') => {
97
+ if (hasGum()) {
98
+ spawnSync('gum', [
99
+ 'style',
100
+ '--border=normal',
101
+ '--margin=1',
102
+ '--padding=1 2',
103
+ '--border-foreground=45',
104
+ '--foreground=81',
105
+ '--bold',
106
+ ` ${title}\n Zero-Context-Rot Scaffolding & Engineering Directives`
107
+ ], { stdio: 'inherit' });
108
+ } else {
109
+ process.stdout.write('\n\x1b[38;2;98;201;255m=====================================================\x1b[0m\n');
110
+ process.stdout.write(`\x1b[1m\x1b[38;2;98;201;255m ${title}\x1b[0m\n`);
111
+ process.stdout.write(' Zero-Context-Rot Scaffolding & Engineering Directives\n');
112
+ process.stdout.write('\x1b[38;2;98;201;255m=====================================================\x1b[0m\n\n');
113
+ }
114
+ };
115
+
116
+ const obtainLicenseKey = async () => {
117
+ let cached = getCachedLicenseKey();
118
+ const cliFlagIdx = rawArgs.indexOf('--license');
119
+ if (cliFlagIdx !== -1 && rawArgs[cliFlagIdx + 1]) {
120
+ cached = rawArgs[cliFlagIdx + 1].trim();
121
+ }
122
+
123
+ if (cached) {
124
+ return cached;
125
+ }
126
+
127
+ const useGum = hasGum();
128
+
129
+ if (useGum) {
130
+ const choice = gumChoose([
131
+ '1. Enter Chemical X License Key',
132
+ '2. Buy Standard Edition ($49) [mycompassconsulting.com]',
133
+ '3. Buy Master Bundle ($99) [mycompassconsulting.com]',
134
+ '4. Run Free Public Audit (npx chemx audit)',
135
+ '5. Exit'
136
+ ], 'Select an option to proceed:');
137
+
138
+ if (choice.startsWith('2.')) {
139
+ process.stdout.write(`\x1b[36mOpening checkout in default browser:\x1b[0m ${URL_STANDARD}\n`);
140
+ openBrowser(URL_STANDARD);
141
+ process.stdout.write('\nOnce completed, paste your Sponsor / VIP License Key below.\n');
142
+ return gumInput('License Key (CX-XXXX-XXXX-XXXX):', 'CX-XXXX-XXXX-XXXX');
143
+ }
144
+
145
+ if (choice.startsWith('3.')) {
146
+ process.stdout.write(`\x1b[36mOpening checkout in default browser:\x1b[0m ${URL_MASTER}\n`);
147
+ openBrowser(URL_MASTER);
148
+ process.stdout.write('\nOnce completed, paste your Sponsor / VIP License Key below.\n');
149
+ return gumInput('License Key (CX-XXXX-XXXX-XXXX):', 'CX-XXXX-XXXX-XXXX');
150
+ }
151
+
152
+ if (choice.startsWith('4.')) {
153
+ runAudit();
154
+ process.exit(0);
155
+ }
156
+
157
+ if (choice.startsWith('5.') || !choice) {
158
+ process.exit(0);
159
+ }
160
+
161
+ return gumInput('License Key (CX-XXXX-XXXX-XXXX):', 'CX-XXXX-XXXX-XXXX');
162
+ }
163
+
164
+ process.stdout.write('\x1b[1mAuthentication Options:\x1b[0m\n');
165
+ process.stdout.write(' [1] Enter License Key\n');
166
+ process.stdout.write(' [2] Buy Standard Edition ($49) - Opens browser\n');
167
+ process.stdout.write(' [3] Buy Master Bundle ($99) - Opens browser\n');
168
+ process.stdout.write(' [4] Run Free Public Audit (npx chemx audit)\n');
169
+ process.stdout.write(' [5] Exit\n\n');
170
+
171
+ const selection = await promptQuestion('Select option [1-5]: ');
172
+
173
+ if (selection === '2') {
174
+ process.stdout.write(`Opening: ${URL_STANDARD}\n`);
175
+ openBrowser(URL_STANDARD);
176
+ return promptQuestion('Enter License Key after purchase: ');
177
+ }
178
+
179
+ if (selection === '3') {
180
+ process.stdout.write(`Opening: ${URL_MASTER}\n`);
181
+ openBrowser(URL_MASTER);
182
+ return promptQuestion('Enter License Key after purchase: ');
183
+ }
184
+
185
+ if (selection === '4') {
186
+ runAudit();
187
+ process.exit(0);
188
+ }
189
+
190
+ if (selection === '5') {
191
+ process.exit(0);
192
+ }
193
+
194
+ return promptQuestion('Enter Chemical X Sponsor License Key (CX-XXXX-XXXX-XXXX): ');
195
+ };
196
+
197
+ const fetchStarterKitFiles = async (licenseKey) => {
198
+ const normalizedKey = licenseKey.trim().toUpperCase();
199
+ const deviceId = getOrCreateDeviceId();
200
+
201
+ process.stdout.write(`\nVerifying license via edge: ${API_BASE}...\n`);
202
+
203
+ try {
204
+ const res = await fetch(`${API_BASE}/api/starter-kit/download`, {
205
+ method: 'POST',
206
+ headers: { 'Content-Type': 'application/json' },
207
+ body: JSON.stringify({ licenseKey: normalizedKey, deviceId })
208
+ });
209
+
210
+ const responseData = await res.json();
211
+
212
+ if (!res.ok || !responseData.valid) {
213
+ process.stderr.write(`\x1b[31m✕ License Verification Failed: ${responseData.error || 'Invalid key.'}\x1b[0m\n`);
214
+ process.stderr.write(`Purchase key at: ${URL_STANDARD}\n\n`);
215
+ process.exit(1);
216
+ }
217
+
218
+ saveLicenseKey(normalizedKey);
219
+ process.stdout.write(`\x1b[32m✔ Verified License for @${responseData.githubUser || 'sponsor'}\x1b[0m\n\n`);
220
+ return responseData.files || {};
221
+ } catch (err) {
222
+ process.stderr.write(`\x1b[31m✕ Network Error: Failed to reach edge server (${err.message}).\x1b[0m\n`);
223
+ process.exit(1);
224
+ }
225
+ };
226
+
227
+ const runScaffold = async (projectName) => {
228
+ renderBanner('Chemical X: Quantum Scaffolder (npm create chemx)');
229
+
230
+ let targetName = projectName;
231
+ if (!targetName) {
232
+ if (hasGum()) {
233
+ targetName = gumInput('Project directory name:', 'my-quantum-app');
234
+ } else {
235
+ targetName = await promptQuestion('Project directory name [my-quantum-app]: ');
236
+ }
237
+ }
238
+
239
+ const finalDirName = targetName.trim() || 'my-quantum-app';
240
+ const targetDir = path.resolve(process.cwd(), finalDirName);
241
+
242
+ if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length > 0) {
243
+ process.stderr.write(`\x1b[31m✕ Error: Directory '${finalDirName}' already exists and is not empty.\x1b[0m\n`);
244
+ process.exit(1);
245
+ }
246
+
247
+ const licenseKey = await obtainLicenseKey();
248
+ if (!licenseKey) {
249
+ process.stderr.write('\x1b[31m✕ Valid license key is required to scaffold blueprints.\x1b[0m\n');
250
+ process.exit(1);
251
+ }
252
+
253
+ const files = await fetchStarterKitFiles(licenseKey);
254
+
255
+ process.stdout.write(`Scaffolding Quantum Architecture into: \x1b[36m${finalDirName}/\x1b[0m\n`);
256
+ fs.mkdirSync(targetDir, { recursive: true });
257
+
258
+ for (const [relPath, content] of Object.entries(files)) {
259
+ const fullPath = path.join(targetDir, relPath);
260
+ const dirName = path.dirname(fullPath);
261
+ if (!fs.existsSync(dirName)) {
262
+ fs.mkdirSync(dirName, { recursive: true });
263
+ }
264
+ fs.writeFileSync(fullPath, content, 'utf-8');
265
+ process.stdout.write(` \x1b[32m✔\x1b[0m ${relPath}\n`);
266
+ }
267
+
268
+ const cursorRulesPath = path.join(targetDir, '.cursorrules');
269
+ if (!fs.existsSync(cursorRulesPath)) {
270
+ const rules = `# Chemical X Quantum Architecture Directives\nStrictly follow AGENTS.md rules. Never exceed 500 lines per file. All molecule capsules must stay under 100 lines.\n`;
271
+ fs.writeFileSync(cursorRulesPath, rules, 'utf-8');
272
+ process.stdout.write(` \x1b[32m✔\x1b[0m .cursorrules\n`);
273
+ }
274
+
275
+ process.stdout.write(`\n\x1b[1m\x1b[32m✔ Quantum project created successfully at ${finalDirName}!\x1b[0m\n\n`);
276
+ process.stdout.write('Next Steps:\n');
277
+ process.stdout.write(` 1. cd ${finalDirName}\n`);
278
+ process.stdout.write(' 2. Review AGENTS.md for line budgets and architecture standards\n');
279
+ process.stdout.write(' 3. Run npx chemx generate m-<feature> to create capsules\n');
280
+ process.stdout.write(' 4. Run npx chemx audit to scan for line budget compliance\n\n');
281
+ };
282
+
283
+ const runInit = async (targetSubDir = 'src/chemical-x') => {
284
+ renderBanner('Chemical X: In-Repo Capsule Drop-in');
285
+
286
+ const targetDir = path.resolve(process.cwd(), targetSubDir);
287
+ const licenseKey = await obtainLicenseKey();
288
+ if (!licenseKey) {
289
+ process.stderr.write('\x1b[31m✕ Valid license key is required.\x1b[0m\n');
290
+ process.exit(1);
291
+ }
292
+
293
+ const files = await fetchStarterKitFiles(licenseKey);
294
+
295
+ process.stdout.write(`Unpacking blueprints and hooks into: \x1b[36m${targetSubDir}/\x1b[0m\n`);
296
+
297
+ let count = 0;
298
+ for (const [relPath, content] of Object.entries(files)) {
299
+ const fullPath = path.join(targetDir, relPath);
300
+ const dirName = path.dirname(fullPath);
301
+ if (!fs.existsSync(dirName)) {
302
+ fs.mkdirSync(dirName, { recursive: true });
303
+ }
304
+ fs.writeFileSync(fullPath, content, 'utf-8');
305
+ process.stdout.write(` \x1b[32m✔\x1b[0m ${relPath}\n`);
306
+ count++;
307
+ }
308
+
309
+ process.stdout.write(`\n\x1b[1m\x1b[32m✔ Successfully installed ${count} Chemical X assets into ${targetSubDir}!\x1b[0m\n\n`);
310
+ };
311
+
312
+ const runGenerateCapsule = (capsuleName) => {
313
+ const normalizedName = capsuleName.startsWith('m-') ? capsuleName : `m-${capsuleName}`;
314
+ const targetDir = path.resolve(process.cwd(), normalizedName);
315
+
316
+ if (fs.existsSync(targetDir)) {
317
+ process.stderr.write(`\x1b[31m✕ Error: Directory ${normalizedName} already exists.\x1b[0m\n`);
318
+ process.exit(1);
319
+ }
320
+
321
+ fs.mkdirSync(targetDir, { recursive: true });
322
+
323
+ const pascalName = normalizedName
324
+ .split('-')
325
+ .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
326
+ .join('');
327
+
328
+ const componentCode = `import React from 'react';
329
+ import type { ${pascalName}Props } from './types';
330
+
331
+ export const ${pascalName}: React.FC<${pascalName}Props> = ({ label }) => {
332
+ return (
333
+ <div className="${normalizedName}">
334
+ <span>{label}</span>
335
+ </div>
336
+ );
337
+ };
338
+
339
+ export default ${pascalName};
340
+ `;
341
+
342
+ const typesCode = `export interface ${pascalName}Props {
343
+ readonly label: string;
344
+ }
345
+ `;
346
+
347
+ const indexCode = `export { ${pascalName} } from './${normalizedName}';
348
+ export type { ${pascalName}Props } from './types';
349
+ `;
350
+
351
+ fs.writeFileSync(path.join(targetDir, `${normalizedName}.tsx`), componentCode, 'utf-8');
352
+ fs.writeFileSync(path.join(targetDir, 'types.d.ts'), typesCode, 'utf-8');
353
+ fs.writeFileSync(path.join(targetDir, 'index.ts'), indexCode, 'utf-8');
354
+
355
+ process.stdout.write(`\x1b[32m✔ Successfully generated crystalline capsule:\x1b[0m ${normalizedName}/\n`);
356
+ process.stdout.write(` - ${normalizedName}/${normalizedName}.tsx (< 50 lines)\n`);
357
+ process.stdout.write(` - ${normalizedName}/types.d.ts\n`);
358
+ process.stdout.write(` - ${normalizedName}/index.ts\n\n`);
359
+ };
360
+
361
+ export const runAudit = () => {
362
+ process.stdout.write('\n\x1b[38;2;98;201;255m[Chemical X Public Audit]\x1b[0m Scanning codebase for line-budget hazards...\n');
363
+ const targetDir = process.cwd();
364
+
365
+ let scanned = 0;
366
+ let violations = 0;
367
+ const offendingFiles = [];
368
+
369
+ const checkFile = (filePath) => {
370
+ const ext = path.extname(filePath);
371
+ if (!['.ts', '.tsx', '.js', '.jsx', '.vue'].includes(ext)) return;
372
+ if (filePath.includes('node_modules') || filePath.includes('.next') || filePath.includes('dist') || filePath.includes('.git')) return;
373
+
374
+ try {
375
+ const content = fs.readFileSync(filePath, 'utf-8');
376
+ const lines = content.split('\n').length;
377
+ scanned++;
378
+
379
+ if (lines > 500) {
380
+ const rel = path.relative(targetDir, filePath);
381
+ offendingFiles.push({ file: rel, lines });
382
+ violations++;
383
+ }
384
+ } catch {
385
+ // Fallback
386
+ }
387
+ };
388
+
389
+ const walk = (dir) => {
390
+ try {
391
+ const files = fs.readdirSync(dir);
392
+ for (const file of files) {
393
+ const full = path.join(dir, file);
394
+ const stat = fs.statSync(full);
395
+ if (stat.isDirectory()) {
396
+ if (!['node_modules', '.git', '.next', 'dist', 'out'].includes(file)) {
397
+ walk(full);
398
+ }
399
+ } else {
400
+ checkFile(full);
401
+ }
402
+ }
403
+ } catch {
404
+ // Fallback
405
+ }
406
+ };
407
+
408
+ walk(targetDir);
409
+
410
+ process.stdout.write(`Scanned ${scanned} source files.\n\n`);
411
+
412
+ if (violations === 0) {
413
+ process.stdout.write('\x1b[1m\x1b[32m✔ 100% Quantum Compliant: All source files meet the 500-line budget ceiling.\x1b[0m\n\n');
414
+ } else {
415
+ process.stdout.write(`\x1b[31m✕ Found ${violations} Monolith Line-Budget Hazards (> 500 lines):\x1b[0m\n`);
416
+ for (const item of offendingFiles) {
417
+ process.stdout.write(` - \x1b[33m${item.file}\x1b[0m (${item.lines} lines)\n`);
418
+ }
419
+
420
+ process.stdout.write('\n\x1b[1m\x1b[38;2;98;201;255mEliminate AI Context Rot with Chemical X Architecture:\x1b[0m\n');
421
+ process.stdout.write(` * Book & Standards: ${URL_STANDARD}\n`);
422
+ process.stdout.write(` * Master Bundle: ${URL_MASTER}\n`);
423
+ process.stdout.write(' * Create Starter: npm create chemx\n');
424
+ process.stdout.write(' * Drop-in Capsules: npx @chemx/starter-kit init\n\n');
425
+ }
426
+ };
427
+
428
+ const printHelp = () => {
429
+ renderBanner();
430
+ process.stdout.write('\x1b[1mAvailable Commands:\x1b[0m\n');
431
+ process.stdout.write(' \x1b[36mnpm create chemx [dir]\x1b[0m Scaffold complete Quantum Architecture project\n');
432
+ process.stdout.write(' \x1b[36mnpx @chemx/starter-kit init [dir]\x1b[0m Drop blueprints & hooks into existing project\n');
433
+ process.stdout.write(' \x1b[36mnpx chemx generate <m-name>\x1b[0m Generate isolated molecule capsule (< 100 lines)\n');
434
+ process.stdout.write(' \x1b[36mnpx chemx audit\x1b[0m [FREE] Scan codebase for line-budget hazards\n\n');
435
+ };
436
+
437
+ const main = async () => {
438
+ const firstArg = rawArgs[0];
439
+
440
+ if (isCreateInvoked) {
441
+ const dirArg = firstArg === 'create' ? rawArgs[1] : firstArg;
442
+ await runScaffold(dirArg);
443
+ return;
444
+ }
445
+
446
+ switch (firstArg) {
447
+ case 'audit':
448
+ runAudit();
449
+ break;
450
+ case 'init':
451
+ await runInit(rawArgs[1] || 'src/chemical-x');
452
+ break;
453
+ case 'create':
454
+ await runScaffold(rawArgs[1]);
455
+ break;
456
+ case 'generate':
457
+ case 'capsule':
458
+ case 'add':
459
+ if (!rawArgs[1]) {
460
+ process.stderr.write('Usage: npx chemx generate <capsule-name>\nExample: npx chemx generate m-user-avatar\n');
461
+ process.exit(1);
462
+ }
463
+ runGenerateCapsule(rawArgs[1]);
464
+ break;
465
+ case 'help':
466
+ case '--help':
467
+ case '-h':
468
+ printHelp();
469
+ break;
470
+ default:
471
+ if (firstArg && firstArg.startsWith('m-')) {
472
+ runGenerateCapsule(firstArg);
473
+ } else if (firstArg && !firstArg.startsWith('-')) {
474
+ await runScaffold(firstArg);
475
+ } else {
476
+ printHelp();
477
+ }
478
+ break;
479
+ }
480
+ };
481
+
482
+ main().catch((err) => {
483
+ process.stderr.write(`\x1b[31m✕ Unexpected Error: ${err.message}\x1b[0m\n`);
484
+ process.exit(1);
485
+ });
486
+
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to the Chemical X Starter Kit repository will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
+
7
+ ## [2026-09-08]
8
+
9
+ ### Added
10
+ - Initial private starter-kit repository architecture.
11
+ - Table-of-Contents view blueprint (`blueprints/view-template.tsx`).
12
+ - Molecule capsule blueprint (`blueprints/molecule-capsule/`).
13
+ - Core hook library:
14
+ - `toResult`: functional result tuple pattern
15
+ - `useAsyncData`: 3-state async pipeline
16
+ - `useSelfCleaningTimer`: unmount-safe interval and timeout utilities
17
+ - Interactive CLI capsule generator (`cli/index.js`).
18
+
19
+ ## [2026-09-09]
20
+
21
+ ### Added
22
+ - Edge-authenticated single-device project scaffolding command (`npx chemical-x init`) with machine fingerprinting and Cloudflare KV validation.
23
+ - AST hazard line budget audit command (`npx chemical-x audit`) scanning project trees for > 500 line monolith hazards.
24
+ - Automated NPM publish GitHub Actions workflow (`.github/workflows/publish.yml`) chained to `Auto Version` completion via `workflow_run`.
25
+
26
+ ### Changed
27
+ - Updated default API endpoint in CLI (`cli/index.js`) to production custom domain `https://chemicalx.xophz.com`.
28
+ - Expanded `AGENTS.md` blueprint in CLI (`cli/index.js`) to include all 7 Quantum Engineering Architecture pillars.
29
+ - Configured npm package distribution for `@chemx/starter-kit` with `create-chemx`, `chemx`, `chem-x`, and `chemical-x` binary aliases.
30
+ - Added public publish configuration for `@chemx` scope and multi-target distribution (`create-chemx`, `@chemx/starter-kit`, `@chem-x/starter-kit`, `@chemx/create-chemx`, `@chem-x/create-chemx`, `chemx`, `chem-x`).
31
+ - Integrated Charm `gum` terminal UI styling with zero-dependency ANSI fallback across all interactive CLI workflows.
32
+ - Added cross-platform browser checkout launcher for `mycompassconsulting.com/buy/chemical-x/standard` and `master`.
33
+ - Unlocked `npx chemx audit` command as 100% free, unauthenticated, and ungated public utility with conversion CTAs.
34
+ - Added dual project scaffolder (`npm create chemx` / `create-chemx`) and in-repo capsule drop-in (`init`).
35
+
36
+ ### Fixed
37
+ - Removed embedded offline blueprint fallbacks and preview bypass keys from CLI executable (`cli/index.js`).
38
+ - Restricted npm package distribution via `files` whitelist and `.npmignore` to prevent leaking private blueprints and hooks in public tarballs.
39
+ - Added explicit `--tag` support and automatic default fallback for prerelease/CalVer versions in multi-target publisher (`scripts/publish-both.mjs`).
40
+
41
+
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@chem-x/create-chemx",
3
+ "version": "26.9.9-632",
4
+ "description": "Chemical X Protocol: Private drop-in architecture starter kit and capsule generator",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-chemx": "cli/index.js",
8
+ "chemx": "cli/index.js"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "tag": "latest"
13
+ },
14
+ "files": [
15
+ "cli",
16
+ "README.md",
17
+ "docs"
18
+ ],
19
+ "scripts": {
20
+ "publish:both": "node scripts/publish-both.mjs",
21
+ "typecheck": "tsc --noEmit",
22
+ "create-capsule": "node cli/index.js"
23
+ },
24
+ "dependencies": {
25
+ "react": "^18.3.1",
26
+ "react-dom": "^18.3.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.13.5",
30
+ "@types/react": "^18.3.18",
31
+ "@types/react-dom": "^18.3.5",
32
+ "typescript": "^5.7.3"
33
+ }
34
+ }