create-what 0.6.0 → 0.6.2

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/index.js +254 -7
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -16,8 +16,39 @@ import { createInterface } from 'node:readline';
16
16
  const args = process.argv.slice(2);
17
17
  const positional = args.filter(a => !a.startsWith('-'));
18
18
  const flags = new Set(args.filter(a => a.startsWith('-')));
19
+ const allowedFlags = new Set(['--yes', '-y', '--help', '-h', '--version', '-v']);
20
+ const unknownFlags = [...flags].filter(flag => !allowedFlags.has(flag));
21
+
22
+ if (flags.has('--help') || flags.has('-h')) {
23
+ printHelp();
24
+ process.exit(0);
25
+ }
26
+
27
+ if (flags.has('--version') || flags.has('-v')) {
28
+ console.log('0.6.2');
29
+ process.exit(0);
30
+ }
31
+
32
+ if (unknownFlags.length > 0) {
33
+ console.error(`Unknown option: ${unknownFlags.join(', ')}`);
34
+ printHelp();
35
+ process.exit(1);
36
+ }
37
+
19
38
  const skipPrompts = flags.has('--yes') || flags.has('-y');
20
39
 
40
+ function printHelp() {
41
+ console.log(`create-what 0.6.2
42
+
43
+ Usage:
44
+ npx create-what [app-name] [--yes]
45
+
46
+ Options:
47
+ --yes, -y Skip prompts and use defaults
48
+ --version, -v Print version
49
+ --help, -h Show this help message`);
50
+ }
51
+
21
52
  // ---------------------------------------------------------------------------
22
53
  // Prompt helpers (zero-dependency, uses Node readline)
23
54
  // ---------------------------------------------------------------------------
@@ -123,17 +154,18 @@ async function gatherOptions() {
123
154
 
124
155
  function generatePackageJson(projectName, { reactCompat, cssApproach }) {
125
156
  const deps = {
126
- 'what-framework': '^0.6.0',
157
+ 'what-framework': '^0.6.2',
127
158
  };
128
159
  const devDeps = {
129
160
  vite: '^6.0.0',
130
- 'what-compiler': '^0.6.0',
161
+ 'what-compiler': '^0.6.2',
162
+ 'what-devtools-mcp': '^0.6.2',
131
163
  '@babel/core': '^7.23.0',
132
164
  };
133
165
 
134
166
  if (reactCompat) {
135
- deps['what-react'] = '^0.1.0';
136
- deps['what-core'] = '^0.6.0';
167
+ deps['what-react'] = '^0.6.2';
168
+ deps['what-core'] = '^0.6.2';
137
169
  // Include zustand as a demo React library
138
170
  deps['zustand'] = '^5.0.0';
139
171
  }
@@ -181,6 +213,10 @@ function generateViteConfig({ reactCompat, cssApproach }) {
181
213
  plugins.push('what()');
182
214
  }
183
215
 
216
+ // MCP DevTools — auto-injects devtools client in dev mode for AI agent debugging
217
+ imports.push(`import whatDevTools from 'what-devtools-mcp/vite-plugin';`);
218
+ plugins.push('whatDevTools()');
219
+
184
220
  if (cssApproach === 'tailwind') {
185
221
  imports.push(`import tailwindcss from '@tailwindcss/vite';`);
186
222
  plugins.push('tailwindcss()');
@@ -841,9 +877,220 @@ async function main() {
841
877
 
842
878
  mkdirSync(join(root, 'src'), { recursive: true });
843
879
  mkdirSync(join(root, 'public'), { recursive: true });
844
- // MCP config dirs created but left empty until what-devtools-mcp is published
845
- // mkdirSync(join(root, '.claude'), { recursive: true });
846
- // mkdirSync(join(root, '.cursor'), { recursive: true });
880
+ // MCP DevTools config — lets AI agents (Claude Code, Cursor, etc.) connect to the running app
881
+ writeFileSync(join(root, '.mcp.json'), JSON.stringify({
882
+ mcpServers: {
883
+ 'what-devtools-mcp': {
884
+ command: 'npx',
885
+ args: ['what-devtools-mcp'],
886
+ },
887
+ },
888
+ }, null, 2) + '\n');
889
+
890
+ // CLAUDE.md — agent instructions for Claude Code (also useful for other AI tools)
891
+ writeFileSync(join(root, 'CLAUDE.md'), `# ${projectName}
892
+
893
+ Built with What Framework — signal-based reactivity, components run once.
894
+
895
+ ## Writing Code
896
+
897
+ \`\`\`js
898
+ import { signal, effect, computed, batch, onMount, h, mount } from 'what-framework';
899
+
900
+ const count = signal(0, 'count'); // state
901
+ count() // read
902
+ count(5) // write
903
+ count(c => c + 1) // update
904
+
905
+ const doubled = computed(() => count() * 2); // derived
906
+ effect(() => console.log(count())); // side effect
907
+ \`\`\`
908
+
909
+ Components run ONCE. Use \`signal()\` for state, \`() =>\` in JSX for reactive text.
910
+
911
+ **Signal scope:** \`signal()\` works anywhere — module scope (shared state), component scope (local state). Components run once, so signal declarations execute exactly once.
912
+
913
+ ## MCP DevTools
914
+
915
+ This project includes MCP devtools that connect to the running app in the browser.
916
+
917
+ ### Quick Start (First 5 Minutes)
918
+
919
+ 1. \`what_connection_status\` — am I connected? how big is the app?
920
+ 2. \`what_diagnose\` — any errors or issues?
921
+ 3. \`what_page_map\` — what's on the page?
922
+ 4. \`what_components\` -> \`what_explain\` on a leaf component — deep dive
923
+ 5. \`what_signals({filter: "name", named_only: true})\` — check key state
924
+
925
+ ### Decision Tree
926
+
927
+ | I want to... | Use this |
928
+ |---|---|
929
+ | Get oriented / check connection | \`what_connection_status\` |
930
+ | Health check (errors + perf + reactivity) | \`what_diagnose\` |
931
+ | Find a component by name | \`what_components {filter}\` |
932
+ | Understand one component deeply | \`what_explain {componentId}\` |
933
+ | See the component hierarchy | \`what_component_tree\` |
934
+ | Check a signal's current value | \`what_signals {filter, named_only: true}\` |
935
+ | See all effects and their run counts | \`what_effects {minRunCount}\` |
936
+ | Understand why a signal changed | \`what_signal_trace {signalId}\` |
937
+ | See what depends on a signal | \`what_dependency_graph {signalId, direction: "downstream"}\` |
938
+ | See what an effect depends on | \`what_dependency_graph {effectId, direction: "upstream"}\` |
939
+ | Find runtime errors | \`what_errors\` |
940
+ | Get component layout/styles (no image) | \`what_look {componentId}\` |
941
+ | Get full page structure | \`what_page_map\` |
942
+ | Get a visual screenshot | \`what_screenshot {componentId}\` (use after what_look) |
943
+ | Inspect raw DOM | \`what_dom_inspect {componentId, depth}\` |
944
+ | Find performance issues | \`what_perf {threshold}\` |
945
+ | Compare before/after state | \`what_diff_snapshot {action: "save"}\` then \`{action: "diff"}\` |
946
+ | Change a signal live | \`what_set_signal {signalId, value}\` |
947
+ | Validate code before saving | \`what_lint {code}\` |
948
+ | Generate boilerplate | \`what_scaffold {type, name}\` |
949
+ | Diagnose an error code | \`what_fix {errorCode}\` |
950
+
951
+ ### Workflows
952
+
953
+ **Find and inspect a component:**
954
+ \`what_components({filter:"Stats"})\` -> get ID -> \`what_explain({componentId: 4})\`
955
+
956
+ **Debug a signal's reactive graph:**
957
+ \`what_signals({filter:"count"})\` -> get ID -> \`what_dependency_graph({signalId: 1, direction: "downstream"})\`
958
+
959
+ **Before/after comparison:**
960
+ \`what_diff_snapshot({action:"save"})\` -> make change -> \`what_diff_snapshot({action:"diff"})\`
961
+
962
+ **Performance audit:**
963
+ \`what_perf({threshold: 3})\` -> \`what_effects({minRunCount: 2})\` -> \`what_dependency_graph({effectId: N})\`
964
+
965
+ **Visual/layout audit:**
966
+ \`what_page_map\` -> \`what_look({componentId: N})\` on key components -> \`what_screenshot\` only if needed
967
+
968
+ **Disconnected reactivity (UI parts that should update together but don't):**
969
+ \`what_dependency_graph({signalId: N, direction: "downstream"})\` -> check ALL expected effects appear. Missing edges = component won't react to that signal.
970
+
971
+ **Multi-signal interaction (order-of-operations bugs):**
972
+ \`what_diff_snapshot(save)\` -> set signal A -> \`diff\` -> save -> set signal B -> \`diff\`. Compare cascades.
973
+
974
+ **Build & test new features:**
975
+ \`what_look\` to match styling -> \`what_scaffold\` for structure -> write code -> \`what_lint\` -> \`what_diff_snapshot(save)\` -> \`what_set_signal\` to simulate trigger -> \`what_diff_snapshot(diff)\` to verify cascade.
976
+
977
+ **Stale subscription (effect should fire but doesn't):**
978
+ If dep graph shows an edge but diff shows 0 re-runs, the effect lost its subscription during a remount. Fix: move effect to module scope or use \`computed()\`.
979
+
980
+ ### Understanding Diagnostics
981
+
982
+ - **"N signals with no subscribers"** — Normal. Signals in \`() => ...\` reactive text bindings (\`<!--fn-->\` in DOM) update the DOM directly, bypassing tracked effects. Only investigate if a signal should trigger an effect but isn't.
983
+ - **"N effects with no signal dependencies"** — Normal. One-shot setup effects that run once during component creation (DOM init, event listeners). Expected in "components run once" model.
984
+ - **Components with signalCount=0** — Module-scope signals (shared stores) don't appear on any component. Use \`what_signals\` directly.
985
+ - **\`<!--fn-->\` in DOM** — Reactive text binding markers. The primary reactivity mechanism in templates.
986
+
987
+ ### Key Parameters
988
+
989
+ | Param | Type | Notes |
990
+ |---|---|---|
991
+ | \`what_signals\` \`named_only\` | boolean | \`true\`/\`false\`, not a string |
992
+ | \`what_effects\` \`minRunCount\` | number | Filter effects that ran >= N times |
993
+ | \`what_dependency_graph\` \`direction\` | \`"upstream"\` \`"downstream"\` \`"both"\` | Default: both |
994
+ | \`what_dom_inspect\` \`depth\` | number | DOM traversal depth (default: 3) |
995
+ | \`what_perf\` \`threshold\` | number | Flag effects with >= N subscribers |
996
+
997
+ ### Efficiency
998
+
999
+ **Parallel-safe (batch these):** \`what_perf\`, \`what_effects\`, \`what_signals\`, \`what_components\`, \`what_dependency_graph\`, \`what_explain\`, \`what_look\`, \`what_page_map\`, \`what_diagnose\`, \`what_lint\`, \`what_scaffold\`. NOT safe to parallelize: \`what_set_signal\` calls on signals that share effects.
1000
+
1001
+ **Diff output:** \`effectsTriggered\` = re-ran. \`effectsAdded\` = new mounts. \`effectsRemoved\` = unmounts. \`what_perf\` includes \`largestSubscribers\` — skip \`what_signals\` if you only need hot signals.
1002
+
1003
+ ### Principles
1004
+ 1. \`what_connection_status\` first — always orient before diving in
1005
+ 2. \`what_explain\` over individual calls — replaces separate signals + effects + DOM lookups
1006
+ 3. \`what_look\` before \`what_screenshot\` — 10x cheaper, usually sufficient
1007
+ 4. \`what_signals\` with \`filter\` and \`named_only: true\` — never dump unfiltered
1008
+ 5. \`what_lint\` before saving generated code
1009
+ 6. Text tools before visual tools — orient with data, then confirm visually
1010
+ 7. Re-fetch component IDs after state changes — IDs are ephemeral after mount/unmount cycles
1011
+ 8. \`what_set_signal\` can cascade — use \`what_diff_snapshot\` to see full impact
1012
+
1013
+ ### Troubleshooting
1014
+ - **Not connected:** Open the app in a browser, wait 2-3s, retry. \`what_lint\`/\`what_scaffold\`/\`what_fix\` work offline.
1015
+ - **"Component N not found":** Re-fetch IDs with \`what_components\` after signal changes that alter the component tree.
1016
+ - **Screenshot fails:** Use \`what_look\` instead (usually sufficient without an image).
1017
+ - **\`what_lint\` false positive on \`signal-write-in-render\`:** Both named handlers and inline \`onClick={() => sig(val)}\` trigger this. Safe to ignore if signal write is inside an event handler. Re-run with \`rules\` excluding that rule to confirm.
1018
+ `);
1019
+
1020
+ // AGENTS.md — model-agnostic instructions for OpenCode, Codex, Gemini, Cursor, etc.
1021
+ writeFileSync(join(root, 'AGENTS.md'), `# ${projectName} — Agent Instructions
1022
+
1023
+ > Model-agnostic guide for AI agents using MCP DevTools with What Framework.
1024
+
1025
+ ## Framework Basics
1026
+
1027
+ Signal-based reactivity. Components run **once**. \`signal()\` for state, \`() =>\` in JSX for reactive text.
1028
+
1029
+ \`\`\`js
1030
+ import { signal, effect, computed, h, mount } from 'what-framework';
1031
+ const count = signal(0, 'count');
1032
+ count() // read
1033
+ count(5) // write
1034
+ count(c => c + 1) // update
1035
+ \`\`\`
1036
+
1037
+ ## MCP DevTools
1038
+
1039
+ **Always start:** \`what_connection_status\` — returns app info, tool list, next steps.
1040
+
1041
+ ### Pick the Right Tool
1042
+
1043
+ | Goal | Tool | Key params |
1044
+ |------|------|------------|
1045
+ | Orient / check connection | \`what_connection_status\` | none |
1046
+ | Health check | \`what_diagnose\` | none |
1047
+ | Find a component | \`what_components\` | \`filter\` (regex string) |
1048
+ | Deep-dive one component | \`what_explain\` | \`componentId\` (number) |
1049
+ | Check signal values | \`what_signals\` | \`filter\` (string), \`named_only\` (boolean) |
1050
+ | See effect run counts | \`what_effects\` | \`minRunCount\` (number) |
1051
+ | Signal dependency graph | \`what_dependency_graph\` | \`signalId\`/\`effectId\` (number), \`direction\` |
1052
+ | Page layout | \`what_page_map\` | none |
1053
+ | Component styling | \`what_look\` | \`componentId\` (number) |
1054
+ | Performance issues | \`what_perf\` | \`threshold\` (number) |
1055
+ | Before/after state | \`what_diff_snapshot\` | \`action\`: \`"save"\` then \`"diff"\` |
1056
+ | Change a signal | \`what_set_signal\` | \`signalId\` (number), \`value\` (any) |
1057
+ | Validate code | \`what_lint\` | \`code\` (string) |
1058
+ | Generate boilerplate | \`what_scaffold\` | \`type\`, \`name\` (strings) |
1059
+
1060
+ ### Recipes
1061
+
1062
+ **Find component:** \`what_components({filter:"Name"})\` -> \`what_explain({componentId: N})\`
1063
+ **Debug signal:** \`what_signals({filter:"name"})\` -> \`what_dependency_graph({signalId: N, direction: "downstream"})\`
1064
+ **Before/after:** \`what_diff_snapshot({action:"save"})\` -> change -> \`what_diff_snapshot({action:"diff"})\`
1065
+ **Build feature:** \`what_look\` (match styling) -> \`what_scaffold\` -> write code -> \`what_lint\` -> \`what_diff_snapshot\` (save/set/diff)
1066
+
1067
+ ### Parameter Types (common mistakes)
1068
+
1069
+ | Param | Correct | Wrong |
1070
+ |-------|---------|-------|
1071
+ | \`named_only\` | \`true\` (boolean) | \`"true"\` (string) |
1072
+ | \`componentId\` | \`4\` (number) | \`"4"\` (string) |
1073
+ | \`direction\` | \`"downstream"\` | \`downstream\` |
1074
+
1075
+ ### Pitfalls
1076
+
1077
+ - **Not connected:** Open app in browser, wait 3s, retry
1078
+ - **Component IDs change** after signal mutations — re-fetch with \`what_components\`
1079
+ - **\`what_lint\` FP on \`signal-write-in-render\`:** Handlers in event callbacks are safe
1080
+ - **\`what_set_signal\` cascades:** Use \`what_diff_snapshot\` to see full impact
1081
+ - **"N signals with no subscribers":** Normal — reactive text bindings bypass tracked effects
1082
+ `);
1083
+
1084
+ // Also generate a .cursor/mcp.json for Cursor users
1085
+ mkdirSync(join(root, '.cursor'), { recursive: true });
1086
+ writeFileSync(join(root, '.cursor', 'mcp.json'), JSON.stringify({
1087
+ mcpServers: {
1088
+ 'what-devtools-mcp': {
1089
+ command: 'npx',
1090
+ args: ['what-devtools-mcp'],
1091
+ },
1092
+ },
1093
+ }, null, 2) + '\n');
847
1094
 
848
1095
  // .gitignore
849
1096
  writeFileSync(join(root, '.gitignore'), `node_modules\ndist\n.DS_Store\n`);
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "create-what",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Scaffold a new What Framework project",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-what": "./index.js"
7
+ "create-what": "index.js"
8
8
  },
9
9
  "main": "index.js",
10
10
  "files": [
@@ -20,7 +20,7 @@
20
20
  "license": "MIT",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/CelsianJs/what-framework"
23
+ "url": "git+https://github.com/CelsianJs/what-framework.git"
24
24
  },
25
25
  "bugs": {
26
26
  "url": "https://github.com/CelsianJs/what-framework/issues"