[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-preact-signals-debugging":3,"mdc--kq6ylz-key":39,"related-repo-preact-signals-debugging":1207,"related-org-preact-signals-debugging":1216},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":34,"sourceUrl":37,"mdContent":38},"signals-debugging","diagnose reactive UI bugs in Preact","Interprets `@preact\u002Fsignals-debug` updates and the AI-native Vite event stream to diagnose reactive UI bugs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"preact","Preact","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fpreact.png","preactjs",[13,17,18,21],{"name":14,"slug":15,"type":16},"Performance","performance","tag",{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},"Frontend","frontend",{"name":22,"slug":23,"type":16},"Debugging","debugging",4466,"https:\u002F\u002Fgithub.com\u002Fpreactjs\u002Fsignals","2026-07-13T06:01:55.102961",null,126,[8,30,31,32,33],"react","reactivity","signals","state-management",{"repoUrl":25,"stars":24,"forks":28,"topics":35,"description":36},[8,30,31,32,33],"Manage state with style in every framework","https:\u002F\u002Fgithub.com\u002Fpreactjs\u002Fsignals\u002Ftree\u002FHEAD\u002Fskills\u002Fsignals-debugging","---\nname: signals-debugging\ndescription: Interprets `@preact\u002Fsignals-debug` updates and the AI-native Vite event stream to diagnose reactive UI bugs.\n---\n\n# Signals Debugging\n\nUse this skill when a user reports a UI bug in an app that uses `@preact\u002Fsignals-debug`, the Signals devtools bridge, or `@preact\u002Fsignals-agent-vite`.\n\nThe Vite plugin is configured with `signalsVite()`.\n\n## What the Debug Stream Means\n\nSignals debug data is structured, not just console text.\n\n- `source: \"signals\"`, `type: \"update\"`\n  - A plain signal or computed changed value.\n  - Important fields: `signalName`, `signalType`, `prevValue`, `newValue`, `timestamp`, `page.pathname`.\n- `source: \"signals\"`, `type: \"effect\"`\n  - An effect ran because one of its dependencies changed.\n  - Important fields: `signalName`, `subscribedTo`, `allDependencies`.\n- `source: \"signals\"`, `type: \"component\"`\n  - A component render was triggered.\n  - Useful for confirming whether state changes reached the view layer.\n- `source: \"signals\"`, `type: \"disposed\"`\n  - A signal\u002Fcomputed\u002Feffect was torn down.\n  - Useful for unmount bugs and stale subscriptions.\n- `source: \"network\"`\n  - `request`, `response`, and `error` events are transport context.\n  - Use these to correlate auth failures, validation fetches, and retries.\n- `source: \"page\"`\n  - `ready`, `navigate`, `interaction`, `error`, and `unhandledrejection` provide user-flow context.\n\n## How to Read a Signal Cascade\n\nThink in this order:\n\n1. **Interaction** - what the user or test just did (`page.interaction`, `network.request`)\n2. **Root signal** - which signal changed first (`signals.update` with depth 0 in raw debug output)\n3. **Derived state** - which computed values re-ran because of it\n4. **Effects\u002Fcomponents** - whether the change reached side effects or rendering\n5. **Mismatch** - compare the final signal state to the outcome\n\n## High-Signal Heuristics\n\n- Network says `401` or `500`, but a status signal becomes `success`\n  - The error path is mutating the wrong signal.\n- A form submit interaction happens, but no relevant signal update follows\n  - The handler is not wired, is throwing early, or is reading stale state.\n- A signal updates but no `component` event follows\n  - The component is not subscribed, is reading via `peek()`, or was disposed.\n- The same signal flips rapidly between values\n  - Look for an effect loop or conflicting async writes.\n- `disposed` happens before the expected UI update\n  - The component\u002Feffect is unmounting or losing subscriptions too early.\n\n## Vite Plugin Workflow\n\nWhen the app uses `@preact\u002Fsignals-agent-vite`, use this flow:\n\n1. Create a session:\n\n```bash\ncurl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions \\\n\t-H 'content-type: application\u002Fjson'\n```\n\n2. Reproduce the issue in the browser or with Playwright.\n3. Fetch or stream the session events:\n\n```bash\ncurl \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions\u002F\u003Csession-id>\u002Fevents\n```\n\n4. Reset the local buffer between reproductions when you need a clean run:\n\n```bash\ncurl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Freset\n```\n\n5. Build a timeline:\n   - page interaction\n   - network request\u002Fresponse\n   - root signal update\n   - derived updates\n   - final rendered state\n6. Point to the first contradiction, not just the last error.\n\n## Signal Naming\n\n- The Babel transform can name signals automatically from the variable they are assigned to.\n  - Example: `const count = signal(0)` can become `signal(0, { name: \"count\" })` in development transforms.\n  - This is why debug events often contain readable `signalName` values even when the source code did not add one manually.\n- Signals and computeds can also name themselves directly with the second options argument.\n  - Example: `signal(0, { name: \"count\" })`\n  - Example: `computed(() => count.value * 2, { name: \"doubled\" })`\n- Prefer the explicit second argument when the local variable name is too generic or when you want stable names across refactors.\n\nYou can use these names in a param `filterPatterns` that you can pass to your session creation. This will make the debug stream only include events that match at least one pattern, which is helpful for noisy apps.\n\nExample:\n\n```bash\ncurl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions \\\n\t-H 'content-type: application\u002Fjson' \\\n\t-d '{\"filterPatterns\":[\"AuthForm\",\"password\"]}'\n```\n\n## How to Filter Well\n\nStart tight, then widen only if needed.\n\n- Good first filters for form issues: component name, route name, feature name\n- For auth flows: `AuthForm`, `auth`, `login`, `session`, `token`\n- If nothing shows up, remove component-specific filters and inspect the global stream\n\n## What to Say Back\n\nRespond with:\n\n1. the triggering action\n2. the key network or page fact\n3. the contradictory signal transition\n4. the likely faulty branch or file\n5. the smallest fix that would align state with reality\n\nExample:\n\n```\nSubmitting `AuthForm` sends `POST \u002Fapi\u002Flogin`, which returns `401`.\nThe debug stream then shows `AuthForm.status` changing from `submitting` to `success` instead of `error`.\nThat means the catch path is writing the success state on failure.\nFix the submit error branch so it sets the error signal and leaves the form in an error state.\n```\n\n## Cautions\n\n- Treat sanitized\u002Fsensitive values like `[Redacted]` as evidence that sensitive state exists, not as missing data.\n- Do not assume every page or network error is causal; correlate it with nearby signal events.\n- Prefer the earliest contradictory event in the timeline over the loudest downstream symptom.\n",{"data":40,"body":41},{"name":4,"description":6},{"type":42,"children":43},"root",[44,52,75,87,94,99,372,378,383,461,467,579,585,597,605,695,708,767,776,819,861,867,943,956,961,1053,1059,1064,1116,1122,1127,1155,1159,1169,1175,1201],{"type":45,"tag":46,"props":47,"children":48},"element","h1",{"id":4},[49],{"type":50,"value":51},"text","Signals Debugging",{"type":45,"tag":53,"props":54,"children":55},"p",{},[56,58,65,67,73],{"type":50,"value":57},"Use this skill when a user reports a UI bug in an app that uses ",{"type":45,"tag":59,"props":60,"children":62},"code",{"className":61},[],[63],{"type":50,"value":64},"@preact\u002Fsignals-debug",{"type":50,"value":66},", the Signals devtools bridge, or ",{"type":45,"tag":59,"props":68,"children":70},{"className":69},[],[71],{"type":50,"value":72},"@preact\u002Fsignals-agent-vite",{"type":50,"value":74},".",{"type":45,"tag":53,"props":76,"children":77},{},[78,80,86],{"type":50,"value":79},"The Vite plugin is configured with ",{"type":45,"tag":59,"props":81,"children":83},{"className":82},[],[84],{"type":50,"value":85},"signalsVite()",{"type":50,"value":74},{"type":45,"tag":88,"props":89,"children":91},"h2",{"id":90},"what-the-debug-stream-means",[92],{"type":50,"value":93},"What the Debug Stream Means",{"type":45,"tag":53,"props":95,"children":96},{},[97],{"type":50,"value":98},"Signals debug data is structured, not just console text.",{"type":45,"tag":100,"props":101,"children":102},"ul",{},[103,176,223,251,279,322],{"type":45,"tag":104,"props":105,"children":106},"li",{},[107,113,115,121],{"type":45,"tag":59,"props":108,"children":110},{"className":109},[],[111],{"type":50,"value":112},"source: \"signals\"",{"type":50,"value":114},", ",{"type":45,"tag":59,"props":116,"children":118},{"className":117},[],[119],{"type":50,"value":120},"type: \"update\"",{"type":45,"tag":100,"props":122,"children":123},{},[124,129],{"type":45,"tag":104,"props":125,"children":126},{},[127],{"type":50,"value":128},"A plain signal or computed changed value.",{"type":45,"tag":104,"props":130,"children":131},{},[132,134,140,141,147,148,154,155,161,162,168,169,175],{"type":50,"value":133},"Important fields: ",{"type":45,"tag":59,"props":135,"children":137},{"className":136},[],[138],{"type":50,"value":139},"signalName",{"type":50,"value":114},{"type":45,"tag":59,"props":142,"children":144},{"className":143},[],[145],{"type":50,"value":146},"signalType",{"type":50,"value":114},{"type":45,"tag":59,"props":149,"children":151},{"className":150},[],[152],{"type":50,"value":153},"prevValue",{"type":50,"value":114},{"type":45,"tag":59,"props":156,"children":158},{"className":157},[],[159],{"type":50,"value":160},"newValue",{"type":50,"value":114},{"type":45,"tag":59,"props":163,"children":165},{"className":164},[],[166],{"type":50,"value":167},"timestamp",{"type":50,"value":114},{"type":45,"tag":59,"props":170,"children":172},{"className":171},[],[173],{"type":50,"value":174},"page.pathname",{"type":50,"value":74},{"type":45,"tag":104,"props":177,"children":178},{},[179,184,185,191],{"type":45,"tag":59,"props":180,"children":182},{"className":181},[],[183],{"type":50,"value":112},{"type":50,"value":114},{"type":45,"tag":59,"props":186,"children":188},{"className":187},[],[189],{"type":50,"value":190},"type: \"effect\"",{"type":45,"tag":100,"props":192,"children":193},{},[194,199],{"type":45,"tag":104,"props":195,"children":196},{},[197],{"type":50,"value":198},"An effect ran because one of its dependencies changed.",{"type":45,"tag":104,"props":200,"children":201},{},[202,203,208,209,215,216,222],{"type":50,"value":133},{"type":45,"tag":59,"props":204,"children":206},{"className":205},[],[207],{"type":50,"value":139},{"type":50,"value":114},{"type":45,"tag":59,"props":210,"children":212},{"className":211},[],[213],{"type":50,"value":214},"subscribedTo",{"type":50,"value":114},{"type":45,"tag":59,"props":217,"children":219},{"className":218},[],[220],{"type":50,"value":221},"allDependencies",{"type":50,"value":74},{"type":45,"tag":104,"props":224,"children":225},{},[226,231,232,238],{"type":45,"tag":59,"props":227,"children":229},{"className":228},[],[230],{"type":50,"value":112},{"type":50,"value":114},{"type":45,"tag":59,"props":233,"children":235},{"className":234},[],[236],{"type":50,"value":237},"type: \"component\"",{"type":45,"tag":100,"props":239,"children":240},{},[241,246],{"type":45,"tag":104,"props":242,"children":243},{},[244],{"type":50,"value":245},"A component render was triggered.",{"type":45,"tag":104,"props":247,"children":248},{},[249],{"type":50,"value":250},"Useful for confirming whether state changes reached the view layer.",{"type":45,"tag":104,"props":252,"children":253},{},[254,259,260,266],{"type":45,"tag":59,"props":255,"children":257},{"className":256},[],[258],{"type":50,"value":112},{"type":50,"value":114},{"type":45,"tag":59,"props":261,"children":263},{"className":262},[],[264],{"type":50,"value":265},"type: \"disposed\"",{"type":45,"tag":100,"props":267,"children":268},{},[269,274],{"type":45,"tag":104,"props":270,"children":271},{},[272],{"type":50,"value":273},"A signal\u002Fcomputed\u002Feffect was torn down.",{"type":45,"tag":104,"props":275,"children":276},{},[277],{"type":50,"value":278},"Useful for unmount bugs and stale subscriptions.",{"type":45,"tag":104,"props":280,"children":281},{},[282,288],{"type":45,"tag":59,"props":283,"children":285},{"className":284},[],[286],{"type":50,"value":287},"source: \"network\"",{"type":45,"tag":100,"props":289,"children":290},{},[291,317],{"type":45,"tag":104,"props":292,"children":293},{},[294,300,301,307,309,315],{"type":45,"tag":59,"props":295,"children":297},{"className":296},[],[298],{"type":50,"value":299},"request",{"type":50,"value":114},{"type":45,"tag":59,"props":302,"children":304},{"className":303},[],[305],{"type":50,"value":306},"response",{"type":50,"value":308},", and ",{"type":45,"tag":59,"props":310,"children":312},{"className":311},[],[313],{"type":50,"value":314},"error",{"type":50,"value":316}," events are transport context.",{"type":45,"tag":104,"props":318,"children":319},{},[320],{"type":50,"value":321},"Use these to correlate auth failures, validation fetches, and retries.",{"type":45,"tag":104,"props":323,"children":324},{},[325,331],{"type":45,"tag":59,"props":326,"children":328},{"className":327},[],[329],{"type":50,"value":330},"source: \"page\"",{"type":45,"tag":100,"props":332,"children":333},{},[334],{"type":45,"tag":104,"props":335,"children":336},{},[337,343,344,350,351,357,358,363,364,370],{"type":45,"tag":59,"props":338,"children":340},{"className":339},[],[341],{"type":50,"value":342},"ready",{"type":50,"value":114},{"type":45,"tag":59,"props":345,"children":347},{"className":346},[],[348],{"type":50,"value":349},"navigate",{"type":50,"value":114},{"type":45,"tag":59,"props":352,"children":354},{"className":353},[],[355],{"type":50,"value":356},"interaction",{"type":50,"value":114},{"type":45,"tag":59,"props":359,"children":361},{"className":360},[],[362],{"type":50,"value":314},{"type":50,"value":308},{"type":45,"tag":59,"props":365,"children":367},{"className":366},[],[368],{"type":50,"value":369},"unhandledrejection",{"type":50,"value":371}," provide user-flow context.",{"type":45,"tag":88,"props":373,"children":375},{"id":374},"how-to-read-a-signal-cascade",[376],{"type":50,"value":377},"How to Read a Signal Cascade",{"type":45,"tag":53,"props":379,"children":380},{},[381],{"type":50,"value":382},"Think in this order:",{"type":45,"tag":384,"props":385,"children":386},"ol",{},[387,413,431,441,451],{"type":45,"tag":104,"props":388,"children":389},{},[390,396,398,404,405,411],{"type":45,"tag":391,"props":392,"children":393},"strong",{},[394],{"type":50,"value":395},"Interaction",{"type":50,"value":397}," - what the user or test just did (",{"type":45,"tag":59,"props":399,"children":401},{"className":400},[],[402],{"type":50,"value":403},"page.interaction",{"type":50,"value":114},{"type":45,"tag":59,"props":406,"children":408},{"className":407},[],[409],{"type":50,"value":410},"network.request",{"type":50,"value":412},")",{"type":45,"tag":104,"props":414,"children":415},{},[416,421,423,429],{"type":45,"tag":391,"props":417,"children":418},{},[419],{"type":50,"value":420},"Root signal",{"type":50,"value":422}," - which signal changed first (",{"type":45,"tag":59,"props":424,"children":426},{"className":425},[],[427],{"type":50,"value":428},"signals.update",{"type":50,"value":430}," with depth 0 in raw debug output)",{"type":45,"tag":104,"props":432,"children":433},{},[434,439],{"type":45,"tag":391,"props":435,"children":436},{},[437],{"type":50,"value":438},"Derived state",{"type":50,"value":440}," - which computed values re-ran because of it",{"type":45,"tag":104,"props":442,"children":443},{},[444,449],{"type":45,"tag":391,"props":445,"children":446},{},[447],{"type":50,"value":448},"Effects\u002Fcomponents",{"type":50,"value":450}," - whether the change reached side effects or rendering",{"type":45,"tag":104,"props":452,"children":453},{},[454,459],{"type":45,"tag":391,"props":455,"children":456},{},[457],{"type":50,"value":458},"Mismatch",{"type":50,"value":460}," - compare the final signal state to the outcome",{"type":45,"tag":88,"props":462,"children":464},{"id":463},"high-signal-heuristics",[465],{"type":50,"value":466},"High-Signal Heuristics",{"type":45,"tag":100,"props":468,"children":469},{},[470,505,518,547,560],{"type":45,"tag":104,"props":471,"children":472},{},[473,475,481,483,489,491,497],{"type":50,"value":474},"Network says ",{"type":45,"tag":59,"props":476,"children":478},{"className":477},[],[479],{"type":50,"value":480},"401",{"type":50,"value":482}," or ",{"type":45,"tag":59,"props":484,"children":486},{"className":485},[],[487],{"type":50,"value":488},"500",{"type":50,"value":490},", but a status signal becomes ",{"type":45,"tag":59,"props":492,"children":494},{"className":493},[],[495],{"type":50,"value":496},"success",{"type":45,"tag":100,"props":498,"children":499},{},[500],{"type":45,"tag":104,"props":501,"children":502},{},[503],{"type":50,"value":504},"The error path is mutating the wrong signal.",{"type":45,"tag":104,"props":506,"children":507},{},[508,510],{"type":50,"value":509},"A form submit interaction happens, but no relevant signal update follows\n",{"type":45,"tag":100,"props":511,"children":512},{},[513],{"type":45,"tag":104,"props":514,"children":515},{},[516],{"type":50,"value":517},"The handler is not wired, is throwing early, or is reading stale state.",{"type":45,"tag":104,"props":519,"children":520},{},[521,523,529,531],{"type":50,"value":522},"A signal updates but no ",{"type":45,"tag":59,"props":524,"children":526},{"className":525},[],[527],{"type":50,"value":528},"component",{"type":50,"value":530}," event follows\n",{"type":45,"tag":100,"props":532,"children":533},{},[534],{"type":45,"tag":104,"props":535,"children":536},{},[537,539,545],{"type":50,"value":538},"The component is not subscribed, is reading via ",{"type":45,"tag":59,"props":540,"children":542},{"className":541},[],[543],{"type":50,"value":544},"peek()",{"type":50,"value":546},", or was disposed.",{"type":45,"tag":104,"props":548,"children":549},{},[550,552],{"type":50,"value":551},"The same signal flips rapidly between values\n",{"type":45,"tag":100,"props":553,"children":554},{},[555],{"type":45,"tag":104,"props":556,"children":557},{},[558],{"type":50,"value":559},"Look for an effect loop or conflicting async writes.",{"type":45,"tag":104,"props":561,"children":562},{},[563,569,571],{"type":45,"tag":59,"props":564,"children":566},{"className":565},[],[567],{"type":50,"value":568},"disposed",{"type":50,"value":570}," happens before the expected UI update\n",{"type":45,"tag":100,"props":572,"children":573},{},[574],{"type":45,"tag":104,"props":575,"children":576},{},[577],{"type":50,"value":578},"The component\u002Feffect is unmounting or losing subscriptions too early.",{"type":45,"tag":88,"props":580,"children":582},{"id":581},"vite-plugin-workflow",[583],{"type":50,"value":584},"Vite Plugin Workflow",{"type":45,"tag":53,"props":586,"children":587},{},[588,590,595],{"type":50,"value":589},"When the app uses ",{"type":45,"tag":59,"props":591,"children":593},{"className":592},[],[594],{"type":50,"value":72},{"type":50,"value":596},", use this flow:",{"type":45,"tag":384,"props":598,"children":599},{},[600],{"type":45,"tag":104,"props":601,"children":602},{},[603],{"type":50,"value":604},"Create a session:",{"type":45,"tag":606,"props":607,"children":612},"pre",{"className":608,"code":609,"language":610,"meta":611,"style":611},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions \\\n    -H 'content-type: application\u002Fjson'\n","bash","",[613],{"type":45,"tag":59,"props":614,"children":615},{"__ignoreMap":611},[616,671],{"type":45,"tag":617,"props":618,"children":621},"span",{"class":619,"line":620},"line",1,[622,628,634,639,645,650,656,661,666],{"type":45,"tag":617,"props":623,"children":625},{"style":624},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[626],{"type":50,"value":627},"curl",{"type":45,"tag":617,"props":629,"children":631},{"style":630},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[632],{"type":50,"value":633}," -X",{"type":45,"tag":617,"props":635,"children":636},{"style":630},[637],{"type":50,"value":638}," POST",{"type":45,"tag":617,"props":640,"children":642},{"style":641},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[643],{"type":50,"value":644}," \u003C",{"type":45,"tag":617,"props":646,"children":647},{"style":630},[648],{"type":50,"value":649},"YOUR_DEV_UR",{"type":45,"tag":617,"props":651,"children":653},{"style":652},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[654],{"type":50,"value":655},"L",{"type":45,"tag":617,"props":657,"children":658},{"style":641},[659],{"type":50,"value":660},">",{"type":45,"tag":617,"props":662,"children":663},{"style":630},[664],{"type":50,"value":665},"\u002F__signals_agent__\u002Fsessions",{"type":45,"tag":617,"props":667,"children":668},{"style":652},[669],{"type":50,"value":670}," \\\n",{"type":45,"tag":617,"props":672,"children":674},{"class":619,"line":673},2,[675,680,685,690],{"type":45,"tag":617,"props":676,"children":677},{"style":630},[678],{"type":50,"value":679},"    -H",{"type":45,"tag":617,"props":681,"children":682},{"style":641},[683],{"type":50,"value":684}," '",{"type":45,"tag":617,"props":686,"children":687},{"style":630},[688],{"type":50,"value":689},"content-type: application\u002Fjson",{"type":45,"tag":617,"props":691,"children":692},{"style":641},[693],{"type":50,"value":694},"'\n",{"type":45,"tag":384,"props":696,"children":697},{"start":673},[698,703],{"type":45,"tag":104,"props":699,"children":700},{},[701],{"type":50,"value":702},"Reproduce the issue in the browser or with Playwright.",{"type":45,"tag":104,"props":704,"children":705},{},[706],{"type":50,"value":707},"Fetch or stream the session events:",{"type":45,"tag":606,"props":709,"children":711},{"className":608,"code":710,"language":610,"meta":611,"style":611},"curl \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions\u002F\u003Csession-id>\u002Fevents\n",[712],{"type":45,"tag":59,"props":713,"children":714},{"__ignoreMap":611},[715],{"type":45,"tag":617,"props":716,"children":717},{"class":619,"line":620},[718,722,726,730,734,738,743,748,753,758,762],{"type":45,"tag":617,"props":719,"children":720},{"style":624},[721],{"type":50,"value":627},{"type":45,"tag":617,"props":723,"children":724},{"style":641},[725],{"type":50,"value":644},{"type":45,"tag":617,"props":727,"children":728},{"style":630},[729],{"type":50,"value":649},{"type":45,"tag":617,"props":731,"children":732},{"style":652},[733],{"type":50,"value":655},{"type":45,"tag":617,"props":735,"children":736},{"style":641},[737],{"type":50,"value":660},{"type":45,"tag":617,"props":739,"children":740},{"style":630},[741],{"type":50,"value":742},"\u002F__signals_agent__\u002Fsessions\u002F",{"type":45,"tag":617,"props":744,"children":745},{"style":641},[746],{"type":50,"value":747},"\u003C",{"type":45,"tag":617,"props":749,"children":750},{"style":630},[751],{"type":50,"value":752},"session-i",{"type":45,"tag":617,"props":754,"children":755},{"style":652},[756],{"type":50,"value":757},"d",{"type":45,"tag":617,"props":759,"children":760},{"style":641},[761],{"type":50,"value":660},{"type":45,"tag":617,"props":763,"children":764},{"style":630},[765],{"type":50,"value":766},"\u002Fevents\n",{"type":45,"tag":384,"props":768,"children":770},{"start":769},4,[771],{"type":45,"tag":104,"props":772,"children":773},{},[774],{"type":50,"value":775},"Reset the local buffer between reproductions when you need a clean run:",{"type":45,"tag":606,"props":777,"children":779},{"className":608,"code":778,"language":610,"meta":611,"style":611},"curl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Freset\n",[780],{"type":45,"tag":59,"props":781,"children":782},{"__ignoreMap":611},[783],{"type":45,"tag":617,"props":784,"children":785},{"class":619,"line":620},[786,790,794,798,802,806,810,814],{"type":45,"tag":617,"props":787,"children":788},{"style":624},[789],{"type":50,"value":627},{"type":45,"tag":617,"props":791,"children":792},{"style":630},[793],{"type":50,"value":633},{"type":45,"tag":617,"props":795,"children":796},{"style":630},[797],{"type":50,"value":638},{"type":45,"tag":617,"props":799,"children":800},{"style":641},[801],{"type":50,"value":644},{"type":45,"tag":617,"props":803,"children":804},{"style":630},[805],{"type":50,"value":649},{"type":45,"tag":617,"props":807,"children":808},{"style":652},[809],{"type":50,"value":655},{"type":45,"tag":617,"props":811,"children":812},{"style":641},[813],{"type":50,"value":660},{"type":45,"tag":617,"props":815,"children":816},{"style":630},[817],{"type":50,"value":818},"\u002F__signals_agent__\u002Freset\n",{"type":45,"tag":384,"props":820,"children":822},{"start":821},5,[823,856],{"type":45,"tag":104,"props":824,"children":825},{},[826,828],{"type":50,"value":827},"Build a timeline:\n",{"type":45,"tag":100,"props":829,"children":830},{},[831,836,841,846,851],{"type":45,"tag":104,"props":832,"children":833},{},[834],{"type":50,"value":835},"page interaction",{"type":45,"tag":104,"props":837,"children":838},{},[839],{"type":50,"value":840},"network request\u002Fresponse",{"type":45,"tag":104,"props":842,"children":843},{},[844],{"type":50,"value":845},"root signal update",{"type":45,"tag":104,"props":847,"children":848},{},[849],{"type":50,"value":850},"derived updates",{"type":45,"tag":104,"props":852,"children":853},{},[854],{"type":50,"value":855},"final rendered state",{"type":45,"tag":104,"props":857,"children":858},{},[859],{"type":50,"value":860},"Point to the first contradiction, not just the last error.",{"type":45,"tag":88,"props":862,"children":864},{"id":863},"signal-naming",[865],{"type":50,"value":866},"Signal Naming",{"type":45,"tag":100,"props":868,"children":869},{},[870,911,938],{"type":45,"tag":104,"props":871,"children":872},{},[873,875],{"type":50,"value":874},"The Babel transform can name signals automatically from the variable they are assigned to.\n",{"type":45,"tag":100,"props":876,"children":877},{},[878,899],{"type":45,"tag":104,"props":879,"children":880},{},[881,883,889,891,897],{"type":50,"value":882},"Example: ",{"type":45,"tag":59,"props":884,"children":886},{"className":885},[],[887],{"type":50,"value":888},"const count = signal(0)",{"type":50,"value":890}," can become ",{"type":45,"tag":59,"props":892,"children":894},{"className":893},[],[895],{"type":50,"value":896},"signal(0, { name: \"count\" })",{"type":50,"value":898}," in development transforms.",{"type":45,"tag":104,"props":900,"children":901},{},[902,904,909],{"type":50,"value":903},"This is why debug events often contain readable ",{"type":45,"tag":59,"props":905,"children":907},{"className":906},[],[908],{"type":50,"value":139},{"type":50,"value":910}," values even when the source code did not add one manually.",{"type":45,"tag":104,"props":912,"children":913},{},[914,916],{"type":50,"value":915},"Signals and computeds can also name themselves directly with the second options argument.\n",{"type":45,"tag":100,"props":917,"children":918},{},[919,928],{"type":45,"tag":104,"props":920,"children":921},{},[922,923],{"type":50,"value":882},{"type":45,"tag":59,"props":924,"children":926},{"className":925},[],[927],{"type":50,"value":896},{"type":45,"tag":104,"props":929,"children":930},{},[931,932],{"type":50,"value":882},{"type":45,"tag":59,"props":933,"children":935},{"className":934},[],[936],{"type":50,"value":937},"computed(() => count.value * 2, { name: \"doubled\" })",{"type":45,"tag":104,"props":939,"children":940},{},[941],{"type":50,"value":942},"Prefer the explicit second argument when the local variable name is too generic or when you want stable names across refactors.",{"type":45,"tag":53,"props":944,"children":945},{},[946,948,954],{"type":50,"value":947},"You can use these names in a param ",{"type":45,"tag":59,"props":949,"children":951},{"className":950},[],[952],{"type":50,"value":953},"filterPatterns",{"type":50,"value":955}," that you can pass to your session creation. This will make the debug stream only include events that match at least one pattern, which is helpful for noisy apps.",{"type":45,"tag":53,"props":957,"children":958},{},[959],{"type":50,"value":960},"Example:",{"type":45,"tag":606,"props":962,"children":964},{"className":608,"code":963,"language":610,"meta":611,"style":611},"curl -X POST \u003CYOUR_DEV_URL>\u002F__signals_agent__\u002Fsessions \\\n    -H 'content-type: application\u002Fjson' \\\n    -d '{\"filterPatterns\":[\"AuthForm\",\"password\"]}'\n",[965],{"type":45,"tag":59,"props":966,"children":967},{"__ignoreMap":611},[968,1007,1031],{"type":45,"tag":617,"props":969,"children":970},{"class":619,"line":620},[971,975,979,983,987,991,995,999,1003],{"type":45,"tag":617,"props":972,"children":973},{"style":624},[974],{"type":50,"value":627},{"type":45,"tag":617,"props":976,"children":977},{"style":630},[978],{"type":50,"value":633},{"type":45,"tag":617,"props":980,"children":981},{"style":630},[982],{"type":50,"value":638},{"type":45,"tag":617,"props":984,"children":985},{"style":641},[986],{"type":50,"value":644},{"type":45,"tag":617,"props":988,"children":989},{"style":630},[990],{"type":50,"value":649},{"type":45,"tag":617,"props":992,"children":993},{"style":652},[994],{"type":50,"value":655},{"type":45,"tag":617,"props":996,"children":997},{"style":641},[998],{"type":50,"value":660},{"type":45,"tag":617,"props":1000,"children":1001},{"style":630},[1002],{"type":50,"value":665},{"type":45,"tag":617,"props":1004,"children":1005},{"style":652},[1006],{"type":50,"value":670},{"type":45,"tag":617,"props":1008,"children":1009},{"class":619,"line":673},[1010,1014,1018,1022,1027],{"type":45,"tag":617,"props":1011,"children":1012},{"style":630},[1013],{"type":50,"value":679},{"type":45,"tag":617,"props":1015,"children":1016},{"style":641},[1017],{"type":50,"value":684},{"type":45,"tag":617,"props":1019,"children":1020},{"style":630},[1021],{"type":50,"value":689},{"type":45,"tag":617,"props":1023,"children":1024},{"style":641},[1025],{"type":50,"value":1026},"'",{"type":45,"tag":617,"props":1028,"children":1029},{"style":652},[1030],{"type":50,"value":670},{"type":45,"tag":617,"props":1032,"children":1034},{"class":619,"line":1033},3,[1035,1040,1044,1049],{"type":45,"tag":617,"props":1036,"children":1037},{"style":630},[1038],{"type":50,"value":1039},"    -d",{"type":45,"tag":617,"props":1041,"children":1042},{"style":641},[1043],{"type":50,"value":684},{"type":45,"tag":617,"props":1045,"children":1046},{"style":630},[1047],{"type":50,"value":1048},"{\"filterPatterns\":[\"AuthForm\",\"password\"]}",{"type":45,"tag":617,"props":1050,"children":1051},{"style":641},[1052],{"type":50,"value":694},{"type":45,"tag":88,"props":1054,"children":1056},{"id":1055},"how-to-filter-well",[1057],{"type":50,"value":1058},"How to Filter Well",{"type":45,"tag":53,"props":1060,"children":1061},{},[1062],{"type":50,"value":1063},"Start tight, then widen only if needed.",{"type":45,"tag":100,"props":1065,"children":1066},{},[1067,1072,1111],{"type":45,"tag":104,"props":1068,"children":1069},{},[1070],{"type":50,"value":1071},"Good first filters for form issues: component name, route name, feature name",{"type":45,"tag":104,"props":1073,"children":1074},{},[1075,1077,1083,1084,1090,1091,1097,1098,1104,1105],{"type":50,"value":1076},"For auth flows: ",{"type":45,"tag":59,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":50,"value":1082},"AuthForm",{"type":50,"value":114},{"type":45,"tag":59,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":50,"value":1089},"auth",{"type":50,"value":114},{"type":45,"tag":59,"props":1092,"children":1094},{"className":1093},[],[1095],{"type":50,"value":1096},"login",{"type":50,"value":114},{"type":45,"tag":59,"props":1099,"children":1101},{"className":1100},[],[1102],{"type":50,"value":1103},"session",{"type":50,"value":114},{"type":45,"tag":59,"props":1106,"children":1108},{"className":1107},[],[1109],{"type":50,"value":1110},"token",{"type":45,"tag":104,"props":1112,"children":1113},{},[1114],{"type":50,"value":1115},"If nothing shows up, remove component-specific filters and inspect the global stream",{"type":45,"tag":88,"props":1117,"children":1119},{"id":1118},"what-to-say-back",[1120],{"type":50,"value":1121},"What to Say Back",{"type":45,"tag":53,"props":1123,"children":1124},{},[1125],{"type":50,"value":1126},"Respond with:",{"type":45,"tag":384,"props":1128,"children":1129},{},[1130,1135,1140,1145,1150],{"type":45,"tag":104,"props":1131,"children":1132},{},[1133],{"type":50,"value":1134},"the triggering action",{"type":45,"tag":104,"props":1136,"children":1137},{},[1138],{"type":50,"value":1139},"the key network or page fact",{"type":45,"tag":104,"props":1141,"children":1142},{},[1143],{"type":50,"value":1144},"the contradictory signal transition",{"type":45,"tag":104,"props":1146,"children":1147},{},[1148],{"type":50,"value":1149},"the likely faulty branch or file",{"type":45,"tag":104,"props":1151,"children":1152},{},[1153],{"type":50,"value":1154},"the smallest fix that would align state with reality",{"type":45,"tag":53,"props":1156,"children":1157},{},[1158],{"type":50,"value":960},{"type":45,"tag":606,"props":1160,"children":1164},{"className":1161,"code":1163,"language":50},[1162],"language-text","Submitting `AuthForm` sends `POST \u002Fapi\u002Flogin`, which returns `401`.\nThe debug stream then shows `AuthForm.status` changing from `submitting` to `success` instead of `error`.\nThat means the catch path is writing the success state on failure.\nFix the submit error branch so it sets the error signal and leaves the form in an error state.\n",[1165],{"type":45,"tag":59,"props":1166,"children":1167},{"__ignoreMap":611},[1168],{"type":50,"value":1163},{"type":45,"tag":88,"props":1170,"children":1172},{"id":1171},"cautions",[1173],{"type":50,"value":1174},"Cautions",{"type":45,"tag":100,"props":1176,"children":1177},{},[1178,1191,1196],{"type":45,"tag":104,"props":1179,"children":1180},{},[1181,1183,1189],{"type":50,"value":1182},"Treat sanitized\u002Fsensitive values like ",{"type":45,"tag":59,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":50,"value":1188},"[Redacted]",{"type":50,"value":1190}," as evidence that sensitive state exists, not as missing data.",{"type":45,"tag":104,"props":1192,"children":1193},{},[1194],{"type":50,"value":1195},"Do not assume every page or network error is causal; correlate it with nearby signal events.",{"type":45,"tag":104,"props":1197,"children":1198},{},[1199],{"type":50,"value":1200},"Prefer the earliest contradictory event in the timeline over the loudest downstream symptom.",{"type":45,"tag":1202,"props":1203,"children":1204},"style",{},[1205],{"type":50,"value":1206},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1208,"total":620},[1209],{"slug":4,"name":4,"fn":5,"description":6,"org":1210,"tags":1211,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1212,1213,1214,1215],{"name":22,"slug":23,"type":16},{"name":19,"slug":20,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"items":1217,"total":620},[1218],{"slug":4,"name":4,"fn":5,"description":6,"org":1219,"tags":1220,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1221,1222,1223,1224],{"name":22,"slug":23,"type":16},{"name":19,"slug":20,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16}]