@chemx/create-chemx 26.9.25-943 → 26.9.26-253

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.
@@ -66,7 +66,7 @@ export const formatGroupedPromptViolations = (violations = [], options = {}) =>
66
66
  export const buildAgentCommandsSection = () => [
67
67
  '### AI AGENT DISCOVERY & REFACTORING COMMANDS:',
68
68
  '- Claim Work: Run `chemx team task list --status=queued` and claim via `chemx team task claim <id> --as=@coder`.',
69
- '- Inspect Target: Run `chemx read <target_path> --outline` to inspect AST signatures without token bloat.',
69
+ '- Inspect Target: Run `chemx read <target_path> --outline` for AST signatures or `--outline --enrich` for signatures + logic flow without token bloat.',
70
70
  '- Verify & Auto-Resolve: Run `chemx verify`. Clean files auto-reconcile tasks to done in SQLite.',
71
71
  '- MCP Invocations: If invoking via MCP, pass command string directly via `chemx({ command: "..." })`.'
72
72
  ].join('\n');
@@ -75,6 +75,16 @@ export const dispatchCommand = async (firstArg, rawArgs, runAudit, getPackageVer
75
75
  await runSearch(rawArgs.slice(1), true);
76
76
  break;
77
77
  }
78
+ case 'trace': {
79
+ const { runTraceCli } = await import('../search-commands-graph.js');
80
+ await runTraceCli(rawArgs.slice(1), true);
81
+ break;
82
+ }
83
+ case 'backtrace': {
84
+ const { runBacktraceCli } = await import('../search-commands-graph.js');
85
+ await runBacktraceCli(rawArgs.slice(1), true);
86
+ break;
87
+ }
78
88
  case 'build':
79
89
  case 'run':
80
90
  case 'wrap': {
@@ -166,9 +176,10 @@ export const dispatchCommand = async (firstArg, rawArgs, runAudit, getPackageVer
166
176
  case 'g':
167
177
  case 'gen':
168
178
  case 'generate':
169
- case 'capsule': {
179
+ case 'capsule':
180
+ case 'jig': {
170
181
  const { runGenerateWizard } = await import('../scaffold.js');
171
- await runGenerateWizard(rawArgs.slice(1));
182
+ await runGenerateWizard(rawArgs);
172
183
  break;
173
184
  }
174
185
  case 'badge':
@@ -201,6 +212,13 @@ export const dispatchCommand = async (firstArg, rawArgs, runAudit, getPackageVer
201
212
  await runTypecheckAudit(rawArgs.slice(1), true);
202
213
  break;
203
214
  }
215
+ case 'lint':
216
+ case 'check:lint':
217
+ case 'eslint': {
218
+ const { runLintAudit } = await import('../verify-lint.js');
219
+ await runLintAudit(rawArgs.slice(1), true);
220
+ break;
221
+ }
204
222
  case 'test':
205
223
  case 'tests':
206
224
  case 'check:test': {
@@ -16,7 +16,9 @@ export const COMMANDS_SCHEMA = [
16
16
  { flag: '-i, --inspect', desc: 'Inspect props and hooks without full source' },
17
17
  { flag: '--tier=<tier>', desc: 'Filter by tier: atom, molecule, organism, hook, view' },
18
18
  { flag: '--blast-radius', desc: 'Map direct consumers, transitive dependents & impacted tiers (aliases: --blast, --impact)' },
19
- { flag: '--max-depth=<N>', desc: 'Max depth for blast radius traversal (default: 5)' },
19
+ { flag: '--trace', desc: 'Forward call trace: downstream functions invoked by target' },
20
+ { flag: '--backtrace', desc: 'Reverse backtrace: upstream callers and causal paths leading to target' },
21
+ { flag: '--max-depth=<N>', desc: 'Max depth for blast radius / trace traversal (default: 5)' },
20
22
  { flag: '--semantic', desc: 'Concept search via vector cosine similarity' },
21
23
  { flag: '--hybrid', desc: 'Blended BM25 keyword + Vector RRF ranking' },
22
24
  { flag: '--hazards', desc: 'Query architectural rule violations directly (flags: --rule=<id>, --critical)' },
@@ -26,6 +28,8 @@ export const COMMANDS_SCHEMA = [
26
28
  examples: [
27
29
  'npx chemx search "badge"',
28
30
  'pnpm q a-button --blast-radius --json',
31
+ 'pnpm q useUserCardController --trace',
32
+ 'pnpm q handleAction --backtrace',
29
33
  'pnpm q "button click handler" --semantic',
30
34
  'pnpm q "useAttentionCardController" --hybrid --json',
31
35
  'pnpm q "useTheme" --inspect',
@@ -34,13 +38,18 @@ export const COMMANDS_SCHEMA = [
34
38
  },
35
39
  {
36
40
  name: 'read',
37
- aliases: ['view'],
41
+ aliases: ['view', 'r'],
38
42
  usage: 'npx chemx read <file> [options]',
39
- summary: 'Token-minified file reader with AST outline extraction.',
40
- description: 'Extracts structural AST outlines, stripped comments, line ranges, or targeted symbol declarations to minimize LLM context token consumption.',
43
+ summary: 'Token-minified file reader with AST outline and logic extraction.',
44
+ description: 'Extracts structural AST outlines, logic skeletons, stripped comments, line ranges, or targeted symbol declarations to minimize LLM context token consumption.',
41
45
  flags: [
42
- { flag: '--outline', desc: 'Signatures only (80%+ token savings)' },
43
- { flag: '--symbol=<name>', desc: 'Target a specific symbol definition' },
46
+ { flag: '--outline, -o', desc: 'Signatures only (80%+ token savings)' },
47
+ { flag: '--logic, -l', desc: 'AST logic skeleton: control flow, guards, and mutations without decorative syntax' },
48
+ { flag: '--template, -t', desc: 'Extract template markup only (Vue/Svelte/JSX)' },
49
+ { flag: '--enrich', desc: 'Append compacted logic skeleton after outline (free-lunch overlay). Compose with --outline for signatures + logic in one call.' },
50
+ { flag: '--trace=<name>', desc: 'Append forward call trace card inline (requires --enrich)' },
51
+ { flag: '--backtrace=<name>', desc: 'Append reverse caller chain card inline (requires --enrich)' },
52
+ { flag: '--symbol=<name>, -s', desc: 'Target a specific symbol definition' },
44
53
  { flag: '--connections', desc: 'Include caller graph and dependent references alongside symbol' },
45
54
  { flag: '--strip-comments', desc: 'Remove all code comments' },
46
55
  { flag: '--compact', desc: 'Remove blank lines and indentation' },
@@ -50,10 +59,42 @@ export const COMMANDS_SCHEMA = [
50
59
  ],
51
60
  examples: [
52
61
  'npx chemx read src/store.ts --outline',
62
+ 'npx chemx read src/controller.ts --outline --enrich',
63
+ 'npx chemx read src/card.vue --outline --enrich --trace=handleSubmit',
64
+ 'npx chemx read src/controller.ts --logic',
65
+ 'npx chemx read src/card.vue --template',
53
66
  'npx chemx read api.ts --symbol=login --connections',
54
67
  'npx chemx read src/ui/atoms/a-button/types.d.ts --symbol=ButtonVariant'
55
68
  ]
56
69
  },
70
+ {
71
+ name: 'trace',
72
+ usage: 'npx chemx trace <symbol> [options]',
73
+ summary: 'Forward call trace: inspects downstream function invocations.',
74
+ description: 'Maps the execution tree of functions, services, and external APIs called by the target symbol.',
75
+ flags: [
76
+ { flag: '--max-depth=<N>', desc: 'Max depth for call trace traversal (default: 3)' },
77
+ { flag: '--json', desc: 'Output call tree as minified JSON' }
78
+ ],
79
+ examples: [
80
+ 'npx chemx trace useCartController',
81
+ 'npx chemx trace handleCheckout --json'
82
+ ]
83
+ },
84
+ {
85
+ name: 'backtrace',
86
+ usage: 'npx chemx backtrace <symbol> [options]',
87
+ summary: 'Reverse call backtrace: maps upstream caller chains leading to target.',
88
+ description: 'Traces the causal path of how user interactions, components, and views trigger the target symbol.',
89
+ flags: [
90
+ { flag: '--max-depth=<N>', desc: 'Max depth for backtrace traversal (default: 5)' },
91
+ { flag: '--json', desc: 'Output causal path as minified JSON' }
92
+ ],
93
+ examples: [
94
+ 'npx chemx backtrace handleCheckout',
95
+ 'npx chemx backtrace postOrder --json'
96
+ ]
97
+ },
57
98
  {
58
99
  name: 'patch',
59
100
  aliases: ['edit'],
@@ -178,6 +219,24 @@ export const COMMANDS_SCHEMA = [
178
219
  'pnpm chemx verify --json'
179
220
  ]
180
221
  },
222
+ {
223
+ name: 'lint',
224
+ aliases: ['check:lint', 'eslint'],
225
+ usage: 'npx chemx lint [path] [options]',
226
+ summary: 'Token-conserving linter runner and tree-formatter with automatic fix.',
227
+ description: 'Executes ESLint with token-efficient diagnostics, target scoping, and automatic --fix support.',
228
+ flags: [
229
+ { flag: '--fix', desc: 'Automatically fix fixable lint and tree-formatting errors' },
230
+ { flag: '--json', desc: 'Output structured diagnostics as JSON for AI agents' },
231
+ { flag: '--raw', desc: 'Do not capture or format output' }
232
+ ],
233
+ examples: [
234
+ 'npx chemx lint',
235
+ 'npx chemx lint --fix',
236
+ 'npx chemx lint apps/youmeos/components/blueprints/desktop/u-desktop.vue --fix',
237
+ 'pnpm chemx lint --json'
238
+ ]
239
+ },
181
240
  {
182
241
  name: 'pillars',
183
242
  aliases: ['config:pillars', 'rules'],
@@ -12,18 +12,29 @@ export const printGenerateHelp = () => {
12
12
  ` ${CYAN}npx chemx generate${RESET} <name> [options]`,
13
13
  ` ${CYAN}npx chemx generate${RESET} <tier> <name> [options]`,
14
14
  '',
15
- `${BOLD}TIERS${RESET}`,
16
- ` ${CYAN}atom${RESET} (a-) Foundational UI elements (raw HTML permitted)`,
15
+ `${BOLD}TIERS & JIG KINDS${RESET}`,
17
16
  ` ${CYAN}molecule${RESET} (m-) Groups of atoms (no raw HTML, co-located controller)`,
17
+ ` ${CYAN}atom${RESET} (a-) Foundational UI elements (raw HTML permitted)`,
18
18
  ` ${CYAN}organism${RESET} (o-) Complex feature modules`,
19
19
  ` ${CYAN}hook${RESET} (use-) Domain state / headless composables (< 5 return properties)`,
20
20
  ` ${CYAN}view${RESET} (v-) Declarative Table-of-Contents views`,
21
+ ` ${CYAN}service${RESET} Domain service / API client with Result tuples and spec`,
22
+ ` ${CYAN}route${RESET} HTTP API route handler with schema validation and test`,
23
+ ` ${CYAN}store${RESET} State store / reactive machine with discriminated unions`,
24
+ ` ${CYAN}repo${RESET} Database repository with CRUD methods and Result tuples`,
25
+ ` ${CYAN}util${RESET} Pure stateless utility functions with test spec`,
26
+ ` ${CYAN}spec${RESET} Isolated unit test spec for an existing target`,
21
27
  '',
22
28
  `${BOLD}OPTIONS${RESET}`,
23
- ` ${CYAN}--tier=<tier>${RESET} Specify component tier`,
29
+ ` ${CYAN}--tier=<tier>${RESET} Specify component tier (atom, molecule, organism, hook, view)`,
30
+ ` ${CYAN}--jig=<kind>${RESET} Specify programmatic file kind (service, route, store, repo, util, spec)`,
24
31
  ` ${CYAN}--framework=<react|vue|svelte>${RESET} Framework flavor (default: auto-detected or react)`,
25
- ` ${CYAN}--dir=<path>${RESET} Target directory (default: src/components/<tier>s)`,
32
+ ` ${CYAN}--dir=<path>${RESET} Target directory (default: src/components/<tier>s or src/<kind>s)`,
26
33
  ` ${CYAN}--desc="<text>"${RESET} Describe functionality to tailor archetype and state`,
34
+ ` ${CYAN}--methods="<m1,m2>"${RESET} Method names or signatures for service/repo/store`,
35
+ ` ${CYAN}--state="<s1,s2>"${RESET} State property definitions for store or controller`,
36
+ ` ${CYAN}--routes="<r1,r2>"${RESET} Route definitions for API route jig (e.g. GET /items, POST /items)`,
37
+ ` ${CYAN}--schema="<json>"${RESET} Structured JSON schema definition payload`,
27
38
  ` ${CYAN}--dry-run${RESET} Preview planned files and lines without touching disk`,
28
39
  ` ${CYAN}--lean${RESET} Generate minimal capsule without controller/spec`,
29
40
  ` ${CYAN}--json${RESET} Output result as minified JSON`,
@@ -32,14 +43,23 @@ export const printGenerateHelp = () => {
32
43
  '',
33
44
  `${BOLD}EXAMPLES${RESET}`,
34
45
  ` ${CYAN}npx chemx generate m-task-list --framework=react${RESET}`,
35
- ` ${CYAN}npx chemx generate m-task-list --desc="add, toggle, remove items"${RESET}`,
36
- ` ${CYAN}npx chemx generate m-task-list --dry-run${RESET}`,
46
+ ` ${CYAN}npx chemx generate --jig=service payment-gateway --methods="processCharge,refund"${RESET}`,
47
+ ` ${CYAN}npx chemx jig route api-orders --routes="GET /orders, POST /orders"${RESET}`,
48
+ ` ${CYAN}npx chemx jig store session-machine --desc="user authentication lifecycle"${RESET}`,
37
49
  ` ${CYAN}npx chemx generate hook use-task-filter${RESET}`,
38
50
  ` ${CYAN}npx chemx generate view v-user-profile${RESET}`,
39
51
  '',
52
+ `${BOLD}TOKEN ECONOMICS & AGENT JIG${RESET}`,
53
+ ` ${DIM}Thesis: Passing a 30-50 token parameter payload to chemx generate / jig replaces${RESET}`,
54
+ ` ${DIM} 1,000-2,500 output tokens of repetitive TypeScript, SCSS, and spec boilerplate.${RESET}`,
55
+ ` ${DIM}Reduction: 90%+ fewer LLM output tokens consumed per component, service, or route.${RESET}`,
56
+ ` ${DIM}Invariants: Guarantees <100 LOC limits, Result tuples, 2-stage booleans, zero synthetic data,${RESET}`,
57
+ ` ${DIM} and co-located unit test specs without LLM syntax drift or hallucination.${RESET}`,
58
+ '',
40
59
  `${BOLD}LINE LIMITS${RESET}`,
41
60
  ` ${DIM}Molecule capsule template: < 100 lines (outer bound)${RESET}`,
42
61
  ` ${DIM}Co-located controller hook: < 100 lines (pure reactive state)${RESET}`,
62
+ ` ${DIM}Domain service / repo: < 100 lines (stateless or cohesive atomic class)${RESET}`,
43
63
  ` ${DIM}Table of Contents view: 10-20 lines (declarative slot assembly)${RESET}`,
44
64
  ''
45
65
  ];
@@ -0,0 +1,67 @@
1
+ import { createJigFiles, normalizeJigKind, JIG_KINDS } from './generator-jig.js';
2
+
3
+ export const handleJigCli = ({ rawArgs, positional, rawName, dirArg, descArg, isDryRun, isJson }) => {
4
+ const jigFlag = (rawArgs.find((a) => a.startsWith('--jig=')) || '').split('=')[1];
5
+ const kindFlag = (rawArgs.find((a) => a.startsWith('--kind=')) || '').split('=')[1];
6
+
7
+ let resolvedKind = jigFlag || kindFlag;
8
+ let resolvedName = rawName;
9
+
10
+ if (!resolvedKind && positional[0] && JIG_KINDS.has(positional[0].toLowerCase())) {
11
+ resolvedKind = positional[0].toLowerCase();
12
+ resolvedName = positional[1] || rawName;
13
+ } else if (positional[0] && positional[0].toLowerCase() === 'jig') {
14
+ resolvedKind = positional[1];
15
+ resolvedName = positional[2] || rawName;
16
+ }
17
+ resolvedKind = normalizeJigKind(resolvedKind || 'service');
18
+
19
+ const methodsArg = (rawArgs.find((a) => a.startsWith('--methods=')) || '').replace(/^--methods=/, '');
20
+ const stateArg = (rawArgs.find((a) => a.startsWith('--state=')) || '').replace(/^--state=/, '');
21
+ const routesArg = (rawArgs.find((a) => a.startsWith('--routes=')) || '').replace(/^--routes=/, '');
22
+ const presetArg = (rawArgs.find((a) => a.startsWith('--preset=')) || '').replace(/^--preset=/, '');
23
+ const schemaArg = (rawArgs.find((a) => a.startsWith('--schema=')) || '').replace(/^--schema=/, '');
24
+
25
+ let schemaData = {};
26
+ if (schemaArg) {
27
+ try {
28
+ schemaData = JSON.parse(schemaArg);
29
+ } catch {
30
+ // ignore JSON parse error
31
+ }
32
+ }
33
+
34
+ const jigRes = createJigFiles({
35
+ kind: schemaData.kind || resolvedKind,
36
+ name: schemaData.name || resolvedName || `sample-${resolvedKind}`,
37
+ dir: dirArg,
38
+ preset: presetArg,
39
+ methods: schemaData.methods || methodsArg,
40
+ state: schemaData.state || stateArg,
41
+ routes: schemaData.routes || routesArg,
42
+ desc: descArg || schemaData.desc,
43
+ dryRun: isDryRun,
44
+ cwd: process.cwd()
45
+ });
46
+
47
+ if (isJson) {
48
+ process.stdout.write(JSON.stringify(jigRes) + '\n');
49
+ return jigRes;
50
+ }
51
+
52
+ if (jigRes.dryRun) {
53
+ process.stdout.write(`\n\x1b[1m\x1b[33m[DRY RUN]\x1b[0m Would generate programmatic jig (${jigRes.kind}) at \x1b[36m${jigRes.relativeDir}/\x1b[0m:\n`);
54
+ for (const f of jigRes.previews || []) {
55
+ process.stdout.write(` \x1b[33m•\x1b[0m ${f.file} (${f.lines} lines)\n`);
56
+ }
57
+ process.stdout.write('\n\x1b[2mDry run complete. No files were written to disk.\x1b[0m\n\n');
58
+ return jigRes;
59
+ }
60
+
61
+ process.stdout.write(`\n\x1b[1m\x1b[32m✔ Successfully generated programmatic jig (${jigRes.kind}):\x1b[0m \x1b[36m${jigRes.relativeDir}/\x1b[0m\n`);
62
+ for (const f of jigRes.filesCreated) {
63
+ process.stdout.write(` \x1b[32m✔\x1b[0m ${f}\n`);
64
+ }
65
+ process.stdout.write('\n\x1b[2mChemical X Standards verified: < 100 lines per file, Result tuples, co-located spec tests.\x1b[0m\n\n');
66
+ return jigRes;
67
+ };