@atlassian/chippy 0.0.0-stage → 0.0.1-beta.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 (133) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +276 -2
  3. package/bin/chippy.mjs +92 -0
  4. package/bin/pack.mjs +204 -0
  5. package/bin/skill-dir.mjs +15 -0
  6. package/lib/avalanche.js +2601 -0
  7. package/lib/avalanche.js.map +7 -0
  8. package/lib/bootstrap.d.ts +1 -0
  9. package/lib/bootstrap.js +70 -0
  10. package/lib/bootstrap.js.map +7 -0
  11. package/lib/browser.js +15 -0
  12. package/lib/browser.js.map +7 -0
  13. package/lib/extension/avalanche.es.js +5535 -0
  14. package/lib/extension/avalanche.es.js.map +1 -0
  15. package/lib/extension/chippy-page-bridge.js +1953 -0
  16. package/lib/extension/inspect-react.js +216 -0
  17. package/lib/extension/layout-lab.js +1453 -0
  18. package/lib/extension/panel-dom.js +90 -0
  19. package/lib/extension/resolve-probes.js +342 -0
  20. package/lib/mcp-skill/LICENSE +201 -0
  21. package/lib/mcp-skill/README.md +148 -0
  22. package/lib/mcp-skill/SKILL.md +335 -0
  23. package/lib/mcp-skill/browser-scripts/playwright-probes.js +368 -0
  24. package/lib/mcp-skill/browser-scripts/playwright-session.js +114 -0
  25. package/lib/mcp-skill/extension/armed-reload-startup.js +83 -0
  26. package/lib/mcp-skill/extension/avalanche.es.js +5535 -0
  27. package/lib/mcp-skill/extension/avalanche.es.js.map +1 -0
  28. package/lib/mcp-skill/extension/avalanche.iife.js +5536 -0
  29. package/lib/mcp-skill/extension/avalanche.iife.js.map +1 -0
  30. package/lib/mcp-skill/extension/background.js +325 -0
  31. package/lib/mcp-skill/extension/chippy-page-bridge.js +1953 -0
  32. package/lib/mcp-skill/extension/content-script.js +190 -0
  33. package/lib/mcp-skill/extension/devtools-hook-shim.js +85 -0
  34. package/lib/mcp-skill/extension/early-bootstrap.js +49 -0
  35. package/lib/mcp-skill/extension/icon-128.png +0 -0
  36. package/lib/mcp-skill/extension/icon-16.png +0 -0
  37. package/lib/mcp-skill/extension/icon-32.png +0 -0
  38. package/lib/mcp-skill/extension/icon-48.png +0 -0
  39. package/lib/mcp-skill/extension/inspect-react.js +216 -0
  40. package/lib/mcp-skill/extension/layout-lab.js +1453 -0
  41. package/lib/mcp-skill/extension/logo.svg +14 -0
  42. package/lib/mcp-skill/extension/manifest.json +69 -0
  43. package/lib/mcp-skill/extension/panel-dom.js +90 -0
  44. package/lib/mcp-skill/extension/panel-settings.js +173 -0
  45. package/lib/mcp-skill/extension/popup.html +41 -0
  46. package/lib/mcp-skill/extension/popup.js +80 -0
  47. package/lib/mcp-skill/extension/probe-descriptor.js +241 -0
  48. package/lib/mcp-skill/extension/resolve-probes.js +342 -0
  49. package/lib/mcp-skill/extension/startup-handoff.js +30 -0
  50. package/lib/mcp-skill/package.json +1 -0
  51. package/lib/mcp-skill/references/README.md +56 -0
  52. package/lib/mcp-skill/references/active-stimulus.md +85 -0
  53. package/lib/mcp-skill/references/avalanche-detector.md +731 -0
  54. package/lib/mcp-skill/references/bdd-router.md +310 -0
  55. package/lib/mcp-skill/references/browser-runtime-api.md +193 -0
  56. package/lib/mcp-skill/references/command-output-formats.md +1085 -0
  57. package/lib/mcp-skill/references/command-surface.md +183 -0
  58. package/lib/mcp-skill/references/cynefin.md +99 -0
  59. package/lib/mcp-skill/references/debug-hook.md +161 -0
  60. package/lib/mcp-skill/references/fixing-performance.md +490 -0
  61. package/lib/mcp-skill/references/hook-metrics.md +199 -0
  62. package/lib/mcp-skill/references/hooks-inspection.md +61 -0
  63. package/lib/mcp-skill/references/jira-taxonomy.md +81 -0
  64. package/lib/mcp-skill/references/mcp.md +122 -0
  65. package/lib/mcp-skill/references/mode-a-injection.md +102 -0
  66. package/lib/mcp-skill/references/operating-model.md +128 -0
  67. package/lib/mcp-skill/references/playwright-cli-setup.md +105 -0
  68. package/lib/mcp-skill/references/playwright-probes.md +205 -0
  69. package/lib/mcp-skill/references/procedures.md +545 -0
  70. package/lib/mcp-skill/references/recipes.txt +114 -0
  71. package/lib/mcp-skill/references/stability-render.md +428 -0
  72. package/lib/mcp-skill/references/test-mode-playbook.md +194 -0
  73. package/lib/mcp-skill/references/troubleshooting.md +59 -0
  74. package/lib/mcp-skill/scripts/avalanche-analyze.cjs +495 -0
  75. package/lib/mcp-skill/scripts/build-avalanche-command.js +34 -0
  76. package/lib/mcp-skill/scripts/build-fiber-state-command.js +19 -0
  77. package/lib/mcp-skill/scripts/chippy-helper-server.js +1768 -0
  78. package/lib/mcp-skill/scripts/chippy-mcp.cjs +273 -0
  79. package/lib/mcp-skill/scripts/chippy.sh +1252 -0
  80. package/lib/mcp-skill/scripts/format-probe-result.js +34 -0
  81. package/lib/mcp-skill/scripts/helper-access.js +158 -0
  82. package/lib/mcp-skill/scripts/helper-proxy.js +87 -0
  83. package/lib/mcp-skill/scripts/page-socket-trust.js +81 -0
  84. package/lib/mcp-skill/scripts/probe-annotation-channel.js +116 -0
  85. package/lib/mcp-skill/scripts/search-recipes.js +248 -0
  86. package/lib/mcp-skill/snippets/README.md +89 -0
  87. package/lib/mcp-skill/snippets/count-context-consumers.js +40 -0
  88. package/lib/mcp-skill/snippets/find-context-providers.js +38 -0
  89. package/lib/mcp-skill/snippets/find-legacy-context.js +47 -0
  90. package/lib/mcp-skill/snippets/find-prop.js +83 -0
  91. package/lib/mcp-skill/snippets/hook-metrics-sample.js +69 -0
  92. package/lib/mcp-skill/snippets/hook-metrics.js +60 -0
  93. package/lib/mcp-skill/snippets/hook-tracker.js +198 -0
  94. package/lib/mcp-skill/snippets/stability-nudge.js +101 -0
  95. package/lib/package.json +1 -0
  96. package/lib/plugin.js +119 -0
  97. package/lib/plugin.js.map +7 -0
  98. package/lib/storybook/avalanche-panel-model.js +79 -0
  99. package/lib/storybook/brand.jsx +6 -0
  100. package/lib/storybook/connection-fallback.jsx +47 -0
  101. package/lib/storybook/constants.js +15 -0
  102. package/lib/storybook/context-card.jsx +171 -0
  103. package/lib/storybook/manager-owner.js +42 -0
  104. package/lib/storybook/manager.jsx +425 -0
  105. package/lib/storybook/preset.js +7 -0
  106. package/lib/storybook/preview.js +298 -0
  107. package/lib/storybook/probe-annotation-editor.jsx +52 -0
  108. package/lib/storybook/probe-intent.js +23 -0
  109. package/lib/storybook/setup.js +104 -0
  110. package/lib/types/avalanche/commit-metrics-adapter.d.ts +76 -0
  111. package/lib/types/avalanche/commit-stats-indices.d.ts +41 -0
  112. package/lib/types/avalanche/commit-surface-ownership.d.ts +9 -0
  113. package/lib/types/avalanche/detector.d.ts +183 -0
  114. package/lib/types/avalanche/interaction-capture.d.ts +25 -0
  115. package/lib/types/avalanche/internals.d.ts +189 -0
  116. package/lib/types/avalanche/report-serializer.d.ts +283 -0
  117. package/lib/types/avalanche/reporter.d.ts +610 -0
  118. package/lib/types/chippy-bridge/fiber-source.d.ts +48 -0
  119. package/lib/types/chippy-bridge/react-renderer.d.ts +74 -0
  120. package/lib/types/chippy-bridge/recorded-source.d.ts +44 -0
  121. package/lib/types/chippy-bridge/source-map.d.ts +30 -0
  122. package/lib/types/debug-render/core.d.ts +78 -0
  123. package/lib/types/layout-lab/fiber-boundaries.d.ts +51 -0
  124. package/lib/types/layout-lab/fiber-walk.d.ts +131 -0
  125. package/lib/types/layout-lab/marker-context.d.ts +94 -0
  126. package/lib/types/package/avalanche.d.ts +6 -0
  127. package/lib/types/package/browser.d.ts +10 -0
  128. package/lib/types/package/plugin.d.ts +15 -0
  129. package/lib/types/plugins/atl/commit-metrics-adapter.d.ts +65 -0
  130. package/lib/types/plugins/atl/metrics-slot.d.ts +37 -0
  131. package/lib/types/plugins/index.d.ts +49 -0
  132. package/lib/types/plugins/jira/context-provider.d.ts +36 -0
  133. package/package.json +106 -4
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright (c) 2026 Atlassian US., Inc.
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -1,3 +1,277 @@
1
- # Temporary Holding Version
1
+ ![Chippy logo](https://raw.githubusercontent.com/atlassian-labs/chippy/main/.agents/skills/chippy/extension/icon-48.png)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # Chippy
4
+
5
+ [![Atlassian license](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](https://github.com/atlassian-labs/chippy/blob/main/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/atlassian-labs/chippy/blob/main/CONTRIBUTING.md)
6
+
7
+ **A friend who helps you understand what’s happening, find the cause, and fix it.**
8
+
9
+ <p align="center">
10
+ <a href="assets/chippy-intro.mp4"><img src="assets/chippy-intro.svg" width="900" alt="Animated intro: Chippy connects your coding agent to the running React page through React's DevTools hook, traces a button to its component, owners, and source line, runs experiments on live state, separates a slow click's trigger from the busiest component, and shows the browser scripts, local helper, and agent skill working as one system."></a>
11
+ <br><a href="assets/chippy-intro.mp4">Watch with sound</a>
12
+ </p>
13
+
14
+ Chippy lets your coding agent see the React app running in your browser: which
15
+ component drew an element, its props and state, where it lives in source, and
16
+ what re-rendered during a slow interaction. Ask the agent, or point at an element
17
+ on the page and leave it a note.
18
+
19
+ Chippy works with standard React and needs no patched packages. Development
20
+ builds give the most detail; production builds show less, and every answer says
21
+ what was available. See [React compatibility](https://github.com/atlassian-labs/chippy/blob/main/docs/react-compatibility.md).
22
+
23
+ ## What you can ask
24
+
25
+ - **Explore:** "Which components render this list, and what state do they hold?"
26
+ - **Debug:** "Where does this label's text come from?" or "Which boundary shows this spinner?"
27
+ - **Compare:** "What changed in the tree between these two states, or these two pages?"
28
+ - **Investigate:** "Why is this click slow?" or "What re-renders on initial load?"
29
+
30
+ ## Install
31
+
32
+ Chippy has three parts:
33
+
34
+ - The **agent skill** tells your coding agent how to run Chippy.
35
+ - The **local helper** is a small server on `127.0.0.1:7823`. The agent starts
36
+ it when it needs it.
37
+ - The **page runtime** runs inside the page and reads React.
38
+
39
+ The skill and the helper are the same in every setup. You choose how the page
40
+ runtime gets into the page; see [Connect a page](#connect-a-page).
41
+
42
+ You need Node.js 22.20 or later, which the skills CLI requires.
43
+
44
+ 1. Install the agent skill with the [skills CLI](https://github.com/vercel-labs/skills):
45
+
46
+ ```sh
47
+ npx skills add atlassian-labs/chippy --skill chippy -g
48
+ ```
49
+
50
+ Choose your coding agents when it asks, or name them with `-a`, for example
51
+ `-a claude-code`. With `-g`, every project can use the skill, and its files
52
+ live in `~/.agents/skills/chippy`; each agent's skills folder links to that
53
+ copy. Leave out `-g` to install it in the current project's
54
+ `.agents/skills/chippy` instead. Run `npx skills update chippy` to update it.
55
+
56
+ 2. Connect a page with one of the routes in [Connect a page](#connect-a-page).
57
+
58
+ 3. Ask your agent to use Chippy on the page.
59
+
60
+ The agent runs Chippy through the skill's `chippy.sh` script, which needs bash
61
+ (macOS, Linux, or WSL on Windows). You don't start anything yourself: the agent
62
+ starts a local helper on `127.0.0.1:7823` when it needs one. A sandboxed agent
63
+ asks for permission to reach it; approve the prompt or allow `chippy.sh`. If
64
+ your agent runs in a container or on a remote machine, the browser must reach
65
+ the helper's port through an SSH tunnel, a published container port, or other
66
+ forwarding your environment provides; Chippy does not set that up.
67
+ [Local and wide binds](https://github.com/atlassian-labs/chippy/blob/main/docs/trust-boundary.md#local-and-wide-binds)
68
+ lists what to set for each setup.
69
+
70
+ **Optional: connect over MCP.** If your agent supports MCP, it can call Chippy
71
+ as tools instead of running a script. Ask it:
72
+
73
+ > Connect Chippy over MCP using the MCP setup steps in the Chippy skill.
74
+
75
+ The agent adds the Chippy server to its own MCP configuration and checks the
76
+ connection. Some agents need a restart before the new tools appear. To set it
77
+ up yourself, see [MCP setup](https://github.com/atlassian-labs/chippy/blob/main/.agents/skills/chippy/references/mcp.md).
78
+
79
+ ## Connect a page
80
+
81
+ Every route loads the same page runtime and talks to the same helper. The
82
+ routes differ in what you set up, whether Chippy stays after a reload, and
83
+ whether Chippy can record the initial page load.
84
+
85
+ | Route | What you set up | After a reload | Records the initial load |
86
+ | --- | --- | --- | --- |
87
+ | [Browser extension](#browser-extension) | Load the extension once, then enable it for each site | Chippy loads again | Yes |
88
+ | [Agent-driven browser](#agent-driven-browser) | Nothing. The agent opens its own Playwright browser | Chippy loads again | Yes, when the agent loads Chippy before the page |
89
+ | [Local proxy](#local-proxy) | Nothing. The agent starts the proxy, and you open the proxy address | Chippy loads again | Yes |
90
+ | [Storybook addon](#storybook-addon) | Add the addon to your Storybook configuration | Chippy remounts the story and stays | The story's mount |
91
+ | [Console import](#console-import) | Paste one line into the page's console | Chippy is removed. Paste the line again | No |
92
+ | [Your app's code](#your-apps-code) | Install the npm package and call `connectChippy()` | Call it again | No |
93
+
94
+ "Records the initial load" means that the agent can reload the page and record
95
+ the renders from the first commit. Every route records renders that happen
96
+ after Chippy connects.
97
+
98
+ ### Browser extension
99
+
100
+ Use the extension for day-to-day work in your own Chrome or Chromium browser.
101
+
102
+ 1. Open `chrome://extensions`, turn on **Developer mode**, and choose
103
+ **Load unpacked**. Select the skill's `extension` folder:
104
+ `~/.agents/skills/chippy/extension`, or `.agents/skills/chippy/extension`
105
+ in your project if you installed without `-g`. The folder picker hides
106
+ folders whose names start with a dot, so type the path instead of browsing.
107
+ On macOS, press **Cmd+Shift+G**, paste the path, press **Return**, and
108
+ choose **Select**. On Linux, press **Ctrl+L** and paste the path. On
109
+ Windows, paste it into the address bar. After `npx skills update`, click
110
+ **Reload** on the Chippy card in `chrome://extensions`.
111
+ 2. Open your app, click the Chippy extension icon, and enable Chippy for the
112
+ page's origin.
113
+
114
+ ### Agent-driven browser
115
+
116
+ The agent opens a Playwright browser, loads Chippy into the page, and drives
117
+ the page itself. No extension is needed. Use this route for repeatable flows,
118
+ headless checks, and CI. Ask your agent to open the page with Chippy in
119
+ Playwright; the skill has the setup steps.
120
+
121
+ ### Local proxy
122
+
123
+ The helper can sit in front of a dev server on your machine and add Chippy to
124
+ the page before the page's own scripts run. No extension is needed, and this
125
+ route works in any browser, including one that your agent drives. Ask your
126
+ agent to start the Chippy proxy for your page, then open the address that it
127
+ gives you on `127.0.0.1:7823`. The proxy forwards only to servers on this
128
+ machine, and it adds Chippy only to the page address that the agent gave it.
129
+ It removes the page's Content Security Policy headers, so it also works for
130
+ pages that block the console import.
131
+
132
+ ### Storybook addon
133
+
134
+ In Storybook 10.3 or later, add the addon to your Storybook configuration:
135
+
136
+ ```js
137
+ export default {
138
+ addons: ['@atlassian/chippy/storybook'],
139
+ };
140
+ ```
141
+
142
+ The addon adds Chippy panels to Storybook and connects each story to your agent.
143
+ When the agent reloads the page, Storybook remounts the current story instead of
144
+ reloading the preview. See the
145
+ [package documentation](https://github.com/atlassian-labs/chippy/blob/main/docs/npm-package.md#storybook)
146
+ for build targets.
147
+
148
+ ### Console import
149
+
150
+ Use this for a quick look at a page where you cannot install the extension.
151
+ Once the agent has started the helper, paste this into the page's console:
152
+
153
+ ```js
154
+ import('http://127.0.0.1:7823/__chippy/inject.mjs')
155
+ ```
156
+
157
+ A reload removes Chippy, so paste the line again after every reload or
158
+ navigation. Sites with a strict Content Security Policy block the import.
159
+
160
+ ### Your app's code
161
+
162
+ For pages that the extension cannot reach, such as an embedded browser, call
163
+ `connectChippy()` from `@atlassian/chippy/browser` in the page. It loads the
164
+ same runtime as the console import. See
165
+ [Connect a browser page to an agent](https://github.com/atlassian-labs/chippy/blob/main/docs/npm-package.md#connect-a-browser-page-to-an-agent).
166
+
167
+ ## Ask the agent, or point at the page
168
+
169
+ - **Ask the agent** about the page. It finds components by name, text, test ID,
170
+ source file, or prop, reads their state, clicks through the page, and records
171
+ renders.
172
+ - **Point at the page:** click the Chippy button in the page corner and drag a
173
+ probe marker (P1, or P2 to compare two elements) onto an element. Choose
174
+ whether you want it explained, investigated, or changed, and add a note. Then
175
+ ask the agent to read it, or to keep watching for new notes while you click
176
+ around. The extension, the local proxy, and the Storybook addon show the
177
+ Chippy button. The console import does not.
178
+
179
+ <p align="center">
180
+ <a href="assets/chippy-call.mp4"><img src="assets/chippy-call.svg" width="900" alt="Animated clip: the asks roll in and Jira keeps them in line, so you call a chippy. Chippy gives your coding agent a hand in the running app: it finds the component and source line for a button to move, reads live props and state to show why a button stays disabled, compares before and after, finds what set off a slow click, connects the page, React, and your code, and turns the page into an experimentation lab."></a>
181
+ <br><a href="assets/chippy-call.mp4">Watch with sound</a>
182
+ </p>
183
+
184
+ ## Evidence, then edits
185
+
186
+ The agent works from what actually rendered instead of guessing from a code
187
+ search. Some deep inspections re-run a component's code; if your components have
188
+ side effects during render, say so and the agent uses read-only inspection
189
+ instead. Chippy changes your source only when you ask it to, and checks the fix
190
+ against the same page.
191
+
192
+ ## Use Chippy without an agent
193
+
194
+ The `@atlassian/chippy` npm package also works with no agent, helper, or
195
+ extension:
196
+
197
+ - **Catch re-render regressions in tests.** Record which components rendered
198
+ during an interaction, and why, in a test or a script. Install the recorder in
199
+ your app's entry module before React DOM loads, and it records from the first
200
+ commit.
201
+ - **Ship your own build** with extra plugins for your stack.
202
+
203
+ See the [package documentation](https://github.com/atlassian-labs/chippy/blob/main/docs/npm-package.md) for setup.
204
+
205
+ ## How Chippy compares
206
+
207
+ Other tools read what React already exposes, such as a component name or a
208
+ source line, and hand it to a person or an agent. Chippy is a system of three
209
+ parts that work together:
210
+
211
+ - **In the browser,** Chippy walks React's fiber tree, owners, props, and hooks,
212
+ records commits during an interaction or page load, and can replay a
213
+ component's render to see how its hooks produced a value.
214
+ - **The local helper** stores that evidence and gives the agent only what it
215
+ needs: compact summaries instead of raw trees, renders ranked by where a
216
+ cascade started, and diffs between snapshots of two states or two pages.
217
+ - **The agent acts back on the page** at the React level, not only through
218
+ clicks: it finds fibers by name, text, test ID, file, or prop, forces a single
219
+ component to re-render, calls a component's callbacks directly, and records
220
+ what happens.
221
+
222
+ | Tool | Built for | What it gives you | Where it stops |
223
+ | --- | --- | --- | --- |
224
+ | [React Developer Tools](https://react.dev/learn/react-developer-tools) | A person in DevTools | Component tree, props, state, hooks, and the Profiler | You read the panels and decide what to change |
225
+ | [react-grab](https://www.react-grab.com/) | A person handing off to an agent | Hover an element and copy its component name, file and line, and HTML for your agent | Your agent takes it from the pasted context |
226
+ | [react-scan](https://react-scan.com/) | A person watching the page | Render outlines, a toolbar showing what changed, and alerts on slow frames | Shows what is slow; finding the cause and fixing it is up to you |
227
+ | [agent-browser](https://github.com/vercel-labs/agent-browser) | An agent driving a browser | Navigation, clicks, form input, snapshots, and screenshots | Works at the DOM and accessibility level, not inside React |
228
+ | **Chippy** | An agent working from runtime evidence | Live React state, render recordings, and snapshot diffs, reduced for the agent, plus React-level actions on the page | Changes the source when you ask, then re-checks the same page |
229
+
230
+ **Compared with react-grab.** Both start when you point at something on the
231
+ page and the tool works out which React component it is. react-grab copies that
232
+ context to your agent and its work is done. For Chippy, that is the first step.
233
+ A probe resolves the owner chain, hooks, and props, so the agent can follow a
234
+ value up the chain to the component that created it, past components that only
235
+ pass it along. Two probes resolve to their nearest common parent. The agent then
236
+ opens the source line, makes the change, and probes again to confirm it.
237
+
238
+ **Compared with react-scan.** Both answer "what rendered, and why?" react-scan
239
+ shows the answer on the page for a person to read. Chippy returns it as data for
240
+ an agent to build on. Render recordings cover both a single interaction and the
241
+ initial page load. The helper ranks them by where a render cascade started, not
242
+ only by how long each component took, so the agent can tell the component that
243
+ caused a slowdown from the ones that rendered along with it. The agent can then
244
+ re-render a single component on purpose to test a fix, and record again to
245
+ confirm the cascade is gone.
246
+
247
+ **Compared with React Developer Tools.** Chippy reads the same information
248
+ through React's DevTools hook and adds the steps a person would otherwise do by
249
+ hand: tracing a value to where it comes from, replaying a render to explain a
250
+ hook, comparing two states or pages, and separating the trigger of a slow
251
+ interaction from collateral renders.
252
+
253
+ **Compared with browser automation.** Tools such as agent-browser or Playwright
254
+ operate the page as a user would: they click, type, and take screenshots. Chippy
255
+ operates it from inside React and explains what React did in response. They work
256
+ well together. The agent uses an automation tool to repeat a user flow and
257
+ Chippy to inspect, nudge, and record the result, and keeps going until the
258
+ change is verified.
259
+
260
+ ## Learn more
261
+
262
+ - [Agent skill](https://github.com/atlassian-labs/chippy/blob/main/.agents/skills/chippy/SKILL.md) and its [references](https://github.com/atlassian-labs/chippy/blob/main/.agents/skills/chippy/references/README.md)
263
+ - [React compatibility](https://github.com/atlassian-labs/chippy/blob/main/docs/react-compatibility.md)
264
+ - [Plugins](https://github.com/atlassian-labs/chippy/blob/main/docs/plugins.md) for app-specific knowledge
265
+ - [Trust boundary](https://github.com/atlassian-labs/chippy/blob/main/docs/trust-boundary.md): what page data Chippy sees and who can reach the helper
266
+ - [Security policy](https://github.com/atlassian-labs/chippy/blob/main/SECURITY.md)
267
+ - [Changelog](https://github.com/atlassian-labs/chippy/blob/main/CHANGELOG.md)
268
+
269
+ To build, test, or change Chippy, see [Contributing](https://github.com/atlassian-labs/chippy/blob/main/CONTRIBUTING.md) and the
270
+ [code of conduct](https://github.com/atlassian-labs/chippy/blob/main/CODE_OF_CONDUCT.md).
271
+
272
+ ## License
273
+
274
+ Copyright (c) 2026 Atlassian US., Inc.
275
+ Apache 2.0 licensed, see [LICENSE](https://github.com/atlassian-labs/chippy/blob/main/LICENSE) file.
276
+
277
+ [![With ❤️ from Atlassian](https://raw.githubusercontent.com/atlassian-internal/oss-assets/master/banner-cheers.png)](https://www.atlassian.com)
package/bin/chippy.mjs ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ // Packs a custom Chippy build with extra plugins (see pack.mjs). The agent
3
+ // skill is installed with the skills CLI, not by this package.
4
+ // npx @atlassian/chippy pack [--config <file>]
5
+ import { readFileSync, realpathSync } from 'node:fs';
6
+ import { dirname, join, resolve } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
10
+ export const SKILL_INSTALL_COMMAND = 'npx skills add atlassian-labs/chippy --skill chippy -g';
11
+
12
+ const COMMAND_OPTIONS = { pack: ['--config'] };
13
+ const HELP = new Set(['--help', '-h', 'help']);
14
+ const VERSION = new Set(['--version', '-v']);
15
+
16
+ export function parseArgs(argv) {
17
+ const args = { command: argv[0], config: 'chippy.config.mjs', help: false, version: false };
18
+ if (HELP.has(args.command)) return { ...args, command: undefined, help: true };
19
+ if (VERSION.has(args.command)) return { ...args, command: undefined, version: true };
20
+ if (args.command === 'install') return args;
21
+ const allowed = COMMAND_OPTIONS[args.command] ?? [];
22
+ const value = (i) => {
23
+ if (i >= argv.length || argv[i].startsWith('-')) throw new Error(`${argv[i - 1]} needs a value`);
24
+ return argv[i];
25
+ };
26
+ for (let i = 1; i < argv.length; i++) {
27
+ if (HELP.has(argv[i])) args.help = true;
28
+ else if (VERSION.has(argv[i])) args.version = true;
29
+ else if (!allowed.includes(argv[i])) throw new Error(`Unknown option for ${args.command}: ${argv[i]}`);
30
+ else if (argv[i] === '--config') args.config = value(++i);
31
+ }
32
+ return args;
33
+ }
34
+
35
+ function usage(name) {
36
+ return `Usage: npx ${name} pack [--config <file>]
37
+ npx ${name} --version
38
+
39
+ pack Builds a custom skill and extension with extra plugins from a config
40
+ file (default chippy.config.mjs). See the package README.
41
+
42
+ Install the Chippy agent skill with the skills CLI:
43
+ ${SKILL_INSTALL_COMMAND}
44
+ `;
45
+ }
46
+
47
+ // The skill used to be installed by this package; point earlier instructions
48
+ // at the skills CLI instead of failing with a bare usage message.
49
+ function installMoved() {
50
+ return `This package no longer installs the Chippy skill. Install it with the skills CLI:
51
+ ${SKILL_INSTALL_COMMAND}
52
+ Drop -g to install it in the current project only.
53
+ `;
54
+ }
55
+
56
+ async function main(argv) {
57
+ const { name, version } = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
58
+ const args = parseArgs(argv);
59
+ if (args.version) {
60
+ process.stdout.write(`${version}\n`);
61
+ return;
62
+ }
63
+ if (args.command === 'install') {
64
+ process.stderr.write(installMoved());
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ if (args.help || !COMMAND_OPTIONS[args.command]) {
69
+ process.stdout.write(usage(name));
70
+ process.exitCode = args.help || args.command === undefined ? 0 : 2;
71
+ return;
72
+ }
73
+ await pack(args.config);
74
+ }
75
+
76
+ async function pack(configPath) {
77
+ const { loadPackConfig, packChippy } = await import('./pack.mjs');
78
+ const result = await packChippy(await loadPackConfig(resolve(configPath)));
79
+ process.stdout.write(`Packed Chippy:
80
+ skill ${result.skillDir}
81
+ skill zip ${result.skillZip}
82
+ extension ${result.extensionZip}
83
+ `);
84
+ }
85
+
86
+ // npx and global installs start the bin through a symlink, so compare real paths.
87
+ if (process.argv[1] && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
88
+ main(process.argv.slice(2)).catch((error) => {
89
+ process.stderr.write(`${error.message}\n`);
90
+ process.exitCode = 1;
91
+ });
92
+ }