create-what 0.6.0 → 0.7.0

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 +219 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -128,6 +128,7 @@ function generatePackageJson(projectName, { reactCompat, cssApproach }) {
128
128
  const devDeps = {
129
129
  vite: '^6.0.0',
130
130
  'what-compiler': '^0.6.0',
131
+ 'what-devtools-mcp': '^0.6.0',
131
132
  '@babel/core': '^7.23.0',
132
133
  };
133
134
 
@@ -181,6 +182,10 @@ function generateViteConfig({ reactCompat, cssApproach }) {
181
182
  plugins.push('what()');
182
183
  }
183
184
 
185
+ // MCP DevTools — auto-injects devtools client in dev mode for AI agent debugging
186
+ imports.push(`import whatDevTools from 'what-devtools-mcp/vite-plugin';`);
187
+ plugins.push('whatDevTools()');
188
+
184
189
  if (cssApproach === 'tailwind') {
185
190
  imports.push(`import tailwindcss from '@tailwindcss/vite';`);
186
191
  plugins.push('tailwindcss()');
@@ -841,9 +846,220 @@ async function main() {
841
846
 
842
847
  mkdirSync(join(root, 'src'), { recursive: true });
843
848
  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 });
849
+ // MCP DevTools config — lets AI agents (Claude Code, Cursor, etc.) connect to the running app
850
+ writeFileSync(join(root, '.mcp.json'), JSON.stringify({
851
+ mcpServers: {
852
+ 'what-devtools-mcp': {
853
+ command: 'npx',
854
+ args: ['what-devtools-mcp'],
855
+ },
856
+ },
857
+ }, null, 2) + '\n');
858
+
859
+ // CLAUDE.md — agent instructions for Claude Code (also useful for other AI tools)
860
+ writeFileSync(join(root, 'CLAUDE.md'), `# ${projectName}
861
+
862
+ Built with What Framework — signal-based reactivity, components run once.
863
+
864
+ ## Writing Code
865
+
866
+ \`\`\`js
867
+ import { signal, effect, computed, batch, onMount, h, mount } from 'what-framework';
868
+
869
+ const count = signal(0, 'count'); // state
870
+ count() // read
871
+ count(5) // write
872
+ count(c => c + 1) // update
873
+
874
+ const doubled = computed(() => count() * 2); // derived
875
+ effect(() => console.log(count())); // side effect
876
+ \`\`\`
877
+
878
+ Components run ONCE. Use \`signal()\` for state, \`() =>\` in JSX for reactive text.
879
+
880
+ **Signal scope:** \`signal()\` works anywhere — module scope (shared state), component scope (local state). Components run once, so signal declarations execute exactly once.
881
+
882
+ ## MCP DevTools
883
+
884
+ This project includes MCP devtools that connect to the running app in the browser.
885
+
886
+ ### Quick Start (First 5 Minutes)
887
+
888
+ 1. \`what_connection_status\` — am I connected? how big is the app?
889
+ 2. \`what_diagnose\` — any errors or issues?
890
+ 3. \`what_page_map\` — what's on the page?
891
+ 4. \`what_components\` -> \`what_explain\` on a leaf component — deep dive
892
+ 5. \`what_signals({filter: "name", named_only: true})\` — check key state
893
+
894
+ ### Decision Tree
895
+
896
+ | I want to... | Use this |
897
+ |---|---|
898
+ | Get oriented / check connection | \`what_connection_status\` |
899
+ | Health check (errors + perf + reactivity) | \`what_diagnose\` |
900
+ | Find a component by name | \`what_components {filter}\` |
901
+ | Understand one component deeply | \`what_explain {componentId}\` |
902
+ | See the component hierarchy | \`what_component_tree\` |
903
+ | Check a signal's current value | \`what_signals {filter, named_only: true}\` |
904
+ | See all effects and their run counts | \`what_effects {minRunCount}\` |
905
+ | Understand why a signal changed | \`what_signal_trace {signalId}\` |
906
+ | See what depends on a signal | \`what_dependency_graph {signalId, direction: "downstream"}\` |
907
+ | See what an effect depends on | \`what_dependency_graph {effectId, direction: "upstream"}\` |
908
+ | Find runtime errors | \`what_errors\` |
909
+ | Get component layout/styles (no image) | \`what_look {componentId}\` |
910
+ | Get full page structure | \`what_page_map\` |
911
+ | Get a visual screenshot | \`what_screenshot {componentId}\` (use after what_look) |
912
+ | Inspect raw DOM | \`what_dom_inspect {componentId, depth}\` |
913
+ | Find performance issues | \`what_perf {threshold}\` |
914
+ | Compare before/after state | \`what_diff_snapshot {action: "save"}\` then \`{action: "diff"}\` |
915
+ | Change a signal live | \`what_set_signal {signalId, value}\` |
916
+ | Validate code before saving | \`what_lint {code}\` |
917
+ | Generate boilerplate | \`what_scaffold {type, name}\` |
918
+ | Diagnose an error code | \`what_fix {errorCode}\` |
919
+
920
+ ### Workflows
921
+
922
+ **Find and inspect a component:**
923
+ \`what_components({filter:"Stats"})\` -> get ID -> \`what_explain({componentId: 4})\`
924
+
925
+ **Debug a signal's reactive graph:**
926
+ \`what_signals({filter:"count"})\` -> get ID -> \`what_dependency_graph({signalId: 1, direction: "downstream"})\`
927
+
928
+ **Before/after comparison:**
929
+ \`what_diff_snapshot({action:"save"})\` -> make change -> \`what_diff_snapshot({action:"diff"})\`
930
+
931
+ **Performance audit:**
932
+ \`what_perf({threshold: 3})\` -> \`what_effects({minRunCount: 2})\` -> \`what_dependency_graph({effectId: N})\`
933
+
934
+ **Visual/layout audit:**
935
+ \`what_page_map\` -> \`what_look({componentId: N})\` on key components -> \`what_screenshot\` only if needed
936
+
937
+ **Disconnected reactivity (UI parts that should update together but don't):**
938
+ \`what_dependency_graph({signalId: N, direction: "downstream"})\` -> check ALL expected effects appear. Missing edges = component won't react to that signal.
939
+
940
+ **Multi-signal interaction (order-of-operations bugs):**
941
+ \`what_diff_snapshot(save)\` -> set signal A -> \`diff\` -> save -> set signal B -> \`diff\`. Compare cascades.
942
+
943
+ **Build & test new features:**
944
+ \`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.
945
+
946
+ **Stale subscription (effect should fire but doesn't):**
947
+ 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()\`.
948
+
949
+ ### Understanding Diagnostics
950
+
951
+ - **"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.
952
+ - **"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.
953
+ - **Components with signalCount=0** — Module-scope signals (shared stores) don't appear on any component. Use \`what_signals\` directly.
954
+ - **\`<!--fn-->\` in DOM** — Reactive text binding markers. The primary reactivity mechanism in templates.
955
+
956
+ ### Key Parameters
957
+
958
+ | Param | Type | Notes |
959
+ |---|---|---|
960
+ | \`what_signals\` \`named_only\` | boolean | \`true\`/\`false\`, not a string |
961
+ | \`what_effects\` \`minRunCount\` | number | Filter effects that ran >= N times |
962
+ | \`what_dependency_graph\` \`direction\` | \`"upstream"\` \`"downstream"\` \`"both"\` | Default: both |
963
+ | \`what_dom_inspect\` \`depth\` | number | DOM traversal depth (default: 3) |
964
+ | \`what_perf\` \`threshold\` | number | Flag effects with >= N subscribers |
965
+
966
+ ### Efficiency
967
+
968
+ **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.
969
+
970
+ **Diff output:** \`effectsTriggered\` = re-ran. \`effectsAdded\` = new mounts. \`effectsRemoved\` = unmounts. \`what_perf\` includes \`largestSubscribers\` — skip \`what_signals\` if you only need hot signals.
971
+
972
+ ### Principles
973
+ 1. \`what_connection_status\` first — always orient before diving in
974
+ 2. \`what_explain\` over individual calls — replaces separate signals + effects + DOM lookups
975
+ 3. \`what_look\` before \`what_screenshot\` — 10x cheaper, usually sufficient
976
+ 4. \`what_signals\` with \`filter\` and \`named_only: true\` — never dump unfiltered
977
+ 5. \`what_lint\` before saving generated code
978
+ 6. Text tools before visual tools — orient with data, then confirm visually
979
+ 7. Re-fetch component IDs after state changes — IDs are ephemeral after mount/unmount cycles
980
+ 8. \`what_set_signal\` can cascade — use \`what_diff_snapshot\` to see full impact
981
+
982
+ ### Troubleshooting
983
+ - **Not connected:** Open the app in a browser, wait 2-3s, retry. \`what_lint\`/\`what_scaffold\`/\`what_fix\` work offline.
984
+ - **"Component N not found":** Re-fetch IDs with \`what_components\` after signal changes that alter the component tree.
985
+ - **Screenshot fails:** Use \`what_look\` instead (usually sufficient without an image).
986
+ - **\`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.
987
+ `);
988
+
989
+ // AGENTS.md — model-agnostic instructions for OpenCode, Codex, Gemini, Cursor, etc.
990
+ writeFileSync(join(root, 'AGENTS.md'), `# ${projectName} — Agent Instructions
991
+
992
+ > Model-agnostic guide for AI agents using MCP DevTools with What Framework.
993
+
994
+ ## Framework Basics
995
+
996
+ Signal-based reactivity. Components run **once**. \`signal()\` for state, \`() =>\` in JSX for reactive text.
997
+
998
+ \`\`\`js
999
+ import { signal, effect, computed, h, mount } from 'what-framework';
1000
+ const count = signal(0, 'count');
1001
+ count() // read
1002
+ count(5) // write
1003
+ count(c => c + 1) // update
1004
+ \`\`\`
1005
+
1006
+ ## MCP DevTools
1007
+
1008
+ **Always start:** \`what_connection_status\` — returns app info, tool list, next steps.
1009
+
1010
+ ### Pick the Right Tool
1011
+
1012
+ | Goal | Tool | Key params |
1013
+ |------|------|------------|
1014
+ | Orient / check connection | \`what_connection_status\` | none |
1015
+ | Health check | \`what_diagnose\` | none |
1016
+ | Find a component | \`what_components\` | \`filter\` (regex string) |
1017
+ | Deep-dive one component | \`what_explain\` | \`componentId\` (number) |
1018
+ | Check signal values | \`what_signals\` | \`filter\` (string), \`named_only\` (boolean) |
1019
+ | See effect run counts | \`what_effects\` | \`minRunCount\` (number) |
1020
+ | Signal dependency graph | \`what_dependency_graph\` | \`signalId\`/\`effectId\` (number), \`direction\` |
1021
+ | Page layout | \`what_page_map\` | none |
1022
+ | Component styling | \`what_look\` | \`componentId\` (number) |
1023
+ | Performance issues | \`what_perf\` | \`threshold\` (number) |
1024
+ | Before/after state | \`what_diff_snapshot\` | \`action\`: \`"save"\` then \`"diff"\` |
1025
+ | Change a signal | \`what_set_signal\` | \`signalId\` (number), \`value\` (any) |
1026
+ | Validate code | \`what_lint\` | \`code\` (string) |
1027
+ | Generate boilerplate | \`what_scaffold\` | \`type\`, \`name\` (strings) |
1028
+
1029
+ ### Recipes
1030
+
1031
+ **Find component:** \`what_components({filter:"Name"})\` -> \`what_explain({componentId: N})\`
1032
+ **Debug signal:** \`what_signals({filter:"name"})\` -> \`what_dependency_graph({signalId: N, direction: "downstream"})\`
1033
+ **Before/after:** \`what_diff_snapshot({action:"save"})\` -> change -> \`what_diff_snapshot({action:"diff"})\`
1034
+ **Build feature:** \`what_look\` (match styling) -> \`what_scaffold\` -> write code -> \`what_lint\` -> \`what_diff_snapshot\` (save/set/diff)
1035
+
1036
+ ### Parameter Types (common mistakes)
1037
+
1038
+ | Param | Correct | Wrong |
1039
+ |-------|---------|-------|
1040
+ | \`named_only\` | \`true\` (boolean) | \`"true"\` (string) |
1041
+ | \`componentId\` | \`4\` (number) | \`"4"\` (string) |
1042
+ | \`direction\` | \`"downstream"\` | \`downstream\` |
1043
+
1044
+ ### Pitfalls
1045
+
1046
+ - **Not connected:** Open app in browser, wait 3s, retry
1047
+ - **Component IDs change** after signal mutations — re-fetch with \`what_components\`
1048
+ - **\`what_lint\` FP on \`signal-write-in-render\`:** Handlers in event callbacks are safe
1049
+ - **\`what_set_signal\` cascades:** Use \`what_diff_snapshot\` to see full impact
1050
+ - **"N signals with no subscribers":** Normal — reactive text bindings bypass tracked effects
1051
+ `);
1052
+
1053
+ // Also generate a .cursor/mcp.json for Cursor users
1054
+ mkdirSync(join(root, '.cursor'), { recursive: true });
1055
+ writeFileSync(join(root, '.cursor', 'mcp.json'), JSON.stringify({
1056
+ mcpServers: {
1057
+ 'what-devtools-mcp': {
1058
+ command: 'npx',
1059
+ args: ['what-devtools-mcp'],
1060
+ },
1061
+ },
1062
+ }, null, 2) + '\n');
847
1063
 
848
1064
  // .gitignore
849
1065
  writeFileSync(join(root, '.gitignore'), `node_modules\ndist\n.DS_Store\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-what",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Scaffold a new What Framework project",
5
5
  "type": "module",
6
6
  "bin": {