Skip to content

Commit f30b4d3

Browse files
committed
Reorganize directories
1 parent 7fe5f4e commit f30b4d3

39 files changed

Lines changed: 97 additions & 76 deletions

CLAUDE.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,36 @@ No test suite — manual testing by loading `public/` as an unpacked extension.
2222

2323
## Architecture
2424

25-
The extension has four components that communicate via a message-passing pipeline:
25+
The codebase is organized by execution context into two main directories:
26+
27+
- **`src/page/`** — Everything running in the page context (content scripts, injected scripts, observers)
28+
- **`src/panel/`** — DevTools panel UI (Svelte 5 components, state, messaging)
29+
30+
The DevTools panel communicates via a message-passing pipeline:
2631

2732
```
2833
Page Context (backend.js) ←→ proxy.js (content script) ←→ background.js ←→ panel/panel.js (DevTools UI)
2934
```
3035

31-
1. **`src/browser_panel/page/backend.js`** — Injected into the inspected page. Hooks Turbo/Stimulus APIs and observes DOM. Sends messages via `window.postMessage`.
32-
2. **`src/browser_panel/proxy.js`** — Content script bridge. Translates `window.postMessage` ↔ Chrome extension ports.
36+
1. **`src/page/backend.js`** — Injected into the inspected page. Hooks Turbo/Stimulus APIs and observes DOM. Sends messages via `window.postMessage`.
37+
2. **`src/page/proxy.js`** — Content script bridge. Translates `window.postMessage` ↔ Chrome extension ports.
3338
3. **`src/background.js`** — Central router. Injects proxy into the target tab when the panel opens, pipes messages bidirectionally, manages tab lifecycle.
34-
4. **`src/browser_panel/panel/`** — Svelte 5 DevTools UI (three tabs: Turbo, Stimulus, Logs).
39+
4. **`src/panel/`** — Svelte 5 DevTools UI (three tabs: Turbo, Stimulus, Logs).
40+
41+
Additionally, the extension has page-level features that work without opening DevTools:
42+
43+
5. **`src/page/content.js`** — Content script loaded on all pages. Handles on-page Turbo Frame/Stimulus highlighting, console logging of Turbo Streams, and diagnostics warnings.
44+
6. **`src/popup.js`** — Extension popup UI for configuring highlighting, console logging, and event monitoring options.
45+
7. **`src/page/inject_script.js`** — Injected into the page's real window context to access `window.Stimulus` and `window.Turbo`.
46+
8. **`src/page/detail_panel.js`** — In-page detail panel widget (shadow DOM) showing Stimulus/Turbo Frame/Turbo Stream info.
3547

3648
### State Management
3749

38-
`src/browser_panel/State.svelte.js` holds all reactive global state using Svelte 5 runes (`$state`). Incoming backend messages (handled in `messaging.js`) update this state, which automatically re-renders components.
50+
`src/panel/State.svelte.js` holds all reactive global state using Svelte 5 runes (`$state`). Incoming backend messages (handled in `messaging.js`) update this state, which automatically re-renders components.
3951

4052
### Backend Observers
4153

42-
Each feature has a dedicated observer class in `src/browser_panel/page/`:
54+
Each feature has a dedicated observer class in `src/page/observers/`:
4355
- `turbo_frame_observer.js` — tracks `<turbo-frame>` elements
4456
- `stimulus_observer.js` — tracks Stimulus controllers
4557
- `turbo_cable_observer.js` — tracks ActionCable subscriptions
@@ -62,9 +74,11 @@ All message type constants live in `src/lib/constants.js`. Two directions:
6274
```
6375
$src/ → src/
6476
$uikit/ → src/uikit/
65-
$components/ → src/components/
77+
$components/ → src/panel/components/
6678
$utils/ → src/utils/
6779
$lib/ → src/lib/
80+
$panel/ → src/panel/
81+
$page/ → src/page/
6882
```
6983

7084
### Svelte 5 Runes
@@ -81,6 +95,6 @@ This project uses Svelte 5 rune syntax exclusively — no legacy Svelte 4 patter
8195
- **svelte-splitpanes** — resizable panels
8296
- **highlight.js** — syntax highlighting in logs
8397

84-
### Legacy Code
98+
### Page-Level Features
8599

86-
`src/popup.js` and `src/content.js` are legacy popup-based features being phased out. All new development goes in `src/browser_panel/`.
100+
`src/popup.js` and `src/page/content.js` provide features that work without opening DevTools: on-page frame/controller highlighting, console event logging, and diagnostics warnings. These are configured via the extension popup. New debugging features should go in `src/panel/`.

build.js

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,23 @@ const browserSpecificSettings = {
2929
}
3030

3131
const outputFileNames = {
32-
"content.js": "hotwire_dev_tools_content.js",
33-
"popup.js": "hotwire_dev_tools_popup.js",
34-
"inject_script.js": "hotwire_dev_tools_inject_script.js",
32+
"content.js": { newName: "hotwire_dev_tools_content.js", moveToDistRoot: true },
33+
"popup.js": { newName: "hotwire_dev_tools_popup.js" },
34+
"inject_script.js": { newName: "hotwire_dev_tools_inject_script.js", moveToDistRoot: true },
3535
}
3636

3737
// Dev-only entry points (excluded from production builds)
38-
const devEntryPoints = ["./src/browser_panel/panel/dev.js"]
38+
const devEntryPoints = ["./src/panel/dev.js"]
3939

4040
const baseEntryPoints = [
41-
"./src/content.js",
41+
"./src/page/content.js",
4242
"./src/popup.js",
4343
"./src/background.js",
44-
"./src/inject_script.js",
45-
"./src/browser_panel/panel/panel.js",
46-
"./src/browser_panel/panel/register.js",
47-
"./src/browser_panel/page/backend.js",
48-
"./src/browser_panel/proxy.js",
44+
"./src/page/inject_script.js",
45+
"./src/panel/panel.js",
46+
"./src/panel/register.js",
47+
"./src/page/backend.js",
48+
"./src/page/proxy.js",
4949
]
5050

5151
const esbuildConfig = {
@@ -66,9 +66,11 @@ const esbuildConfig = {
6666
alias: {
6767
$src: path.resolve(__dirname, "src"),
6868
$uikit: path.resolve(__dirname, "src/uikit"),
69-
$components: path.resolve(__dirname, "src/components"),
69+
$components: path.resolve(__dirname, "src/panel/components"),
7070
$utils: path.resolve(__dirname, "src/utils"),
7171
$lib: path.resolve(__dirname, "src/lib"),
72+
$panel: path.resolve(__dirname, "src/panel"),
73+
$page: path.resolve(__dirname, "src/page"),
7274
},
7375
plugins: [
7476
sveltePlugin({
@@ -82,10 +84,13 @@ const esbuildConfig = {
8284
const outputFiles = Object.keys(result.metafile.outputs)
8385
for (const outputFile of outputFiles) {
8486
const originalName = path.basename(outputFile)
85-
const newName = outputFileNames[originalName]
87+
const config = outputFileNames[originalName]
8688

87-
if (newName) {
88-
const newPath = path.join(path.dirname(outputFile), newName)
89+
if (config) {
90+
const newName = typeof config === "string" ? config : config.newName
91+
const moveToDistRoot = typeof config === "object" && config.moveToDistRoot
92+
const targetDir = moveToDistRoot ? "./public/dist" : path.dirname(outputFile)
93+
const newPath = path.join(targetDir, newName)
8994
await fs.rename(outputFile, newPath)
9095
console.log(`Renamed ${originalName} to ${newName}`)
9196
}
@@ -111,10 +116,10 @@ async function generateManifest() {
111116
async function cleanupDevFiles() {
112117
const devFiles = [
113118
path.join(__dirname, "public", "dev.html"),
114-
path.join(__dirname, "public", "dist", "browser_panel", "panel", "dev.js"),
115-
path.join(__dirname, "public", "dist", "browser_panel", "panel", "dev.js.map"),
116-
path.join(__dirname, "public", "dist", "browser_panel", "panel", "dev.css"),
117-
path.join(__dirname, "public", "dist", "browser_panel", "panel", "dev.css.map"),
119+
path.join(__dirname, "public", "dist", "panel", "dev.js"),
120+
path.join(__dirname, "public", "dist", "panel", "dev.js.map"),
121+
path.join(__dirname, "public", "dist", "panel", "dev.css"),
122+
path.join(__dirname, "public", "dist", "panel", "dev.css.map"),
118123
]
119124

120125
for (const file of devFiles) {

jsconfig.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
"paths": {
55
"$src/*": ["src/*"],
66
"$uikit/*": ["src/uikit/*"],
7-
"$components/*": ["src/components/*"],
7+
"$components/*": ["src/panel/components/*"],
88
"$utils/*": ["src/utils/*"],
9-
"$lib/*": ["src/lib/*"]
9+
"$lib/*": ["src/lib/*"],
10+
"$panel/*": ["src/panel/*"],
11+
"$page/*": ["src/page/*"]
1012
}
1113
},
1214
"include": ["src/**/*"]

manifest.template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"styles/hotwire_dev_tools_detail_panel.css",
5353
"panel.html",
5454
"register.html",
55-
"dist/browser_panel/page/backend.js"
55+
"dist/page/backend.js"
5656
],
5757
"matches": ["<all_urls>"]
5858
}

public/panel.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
<link rel="stylesheet" href="styles/panel/code_highlight.css" />
1010

1111
<!-- Svelte Styles -->
12-
<link rel="stylesheet" href="dist/browser_panel/panel/panel.css" />
12+
<link rel="stylesheet" href="dist/panel/panel.css" />
1313
</head>
1414

1515
<body>
1616
<div id="app"></div>
17-
<script type="module" src="dist/browser_panel/panel/panel.js"></script>
17+
<script type="module" src="dist/panel/panel.js"></script>
1818
</body>
1919
</html>

public/register.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
<meta charset="utf-8" />
55
</head>
66
<body>
7-
<script src="./dist/browser_panel/panel/register.js"></script>
7+
<script src="./dist/panel/register.js"></script>
88
</body>
99
</html>

src/background.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// from the browser devtools panel and the backend.
33
// It sets up a two-way communication channel between the devtools panel and the backend script.
44

5-
import { isDevToolPanel, devToolPanelNameToTabId } from "./browser_panel/messaging"
5+
import { isDevToolPanel, devToolPanelNameToTabId } from "$panel/messaging"
66
import { PORT_IDENTIFIERS } from "$lib/constants"
77

88
let ports = {}
@@ -56,7 +56,7 @@ chrome.runtime.onConnect.addListener(async (port) => {
5656
try {
5757
await chrome.scripting.executeScript({
5858
target: { tabId: tabId },
59-
files: ["dist/browser_panel/proxy.js"],
59+
files: ["dist/page/proxy.js"],
6060
})
6161
} catch (error) {
6262
console.error(`Failed to inject script for tabId ${tabId}:`, error)
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { HOTWIRE_DEV_TOOLS_PROXY_SOURCE, HOTWIRE_DEV_TOOLS_BACKEND_SOURCE, BACKEND_TO_PANEL_MESSAGES, PANEL_TO_BACKEND_MESSAGES, TURBO_EVENTS } from "$lib/constants"
22
import { addHighlightOverlayToElements, removeHighlightOverlay } from "$utils/highlight"
33
import { debounce, generateUUID, getElementPath, getElementFromIndexPath, stringifyHTMLElementTag, safeStringifyEventDetail } from "$utils/utils"
4-
import TurboFrameObserver from "./turbo_frame_observer.js"
5-
import TurboCableObserver from "./turbo_cable_observer.js"
6-
import StimulusObserver from "./stimulus_observer.js"
7-
import TurboAttributeElementsObserver from "./turbo_attribute_elements_observer.js"
8-
import ElementObserver from "./element_observer.js"
4+
import TurboFrameObserver from "./observers/turbo_frame_observer.js"
5+
import TurboCableObserver from "./observers/turbo_cable_observer.js"
6+
import StimulusObserver from "./observers/stimulus_observer.js"
7+
import TurboAttributeElementsObserver from "./observers/turbo_attribute_elements_observer.js"
8+
import ElementObserver from "./observers/element_observer.js"
99
import LeaderLine from "$lib/leader_line.js"
1010

1111
// This is the backend script which interacts with the page's DOM.

src/content.js renamed to src/page/content.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { addHighlightOverlayToElements, removeHighlightOverlay } from "$utils/hi
44
import { TURBO_EVENTS } from "$lib/constants"
55

66
import Devtool from "$lib/devtool"
7-
import DetailPanel from "$components/detail_panel"
7+
import DetailPanel from "$page/detail_panel"
88
import DOMScanner from "$utils/dom_scanner"
99
import DiagnosticsChecker from "$lib/diagnostics_checker"
1010

0 commit comments

Comments
 (0)