@ticktockbent/charlotte 0.3.0 → 0.4.1
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.
- package/CHANGELOG.md +34 -0
- package/README.md +45 -29
- package/dist/browser/page-manager.d.ts +21 -0
- package/dist/browser/page-manager.d.ts.map +1 -1
- package/dist/browser/page-manager.js +81 -24
- package/dist/browser/page-manager.js.map +1 -1
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +40 -0
- package/dist/cli.js.map +1 -0
- package/dist/dev/dev-mode-state.d.ts +3 -0
- package/dist/dev/dev-mode-state.d.ts.map +1 -1
- package/dist/dev/dev-mode-state.js +5 -0
- package/dist/dev/dev-mode-state.js.map +1 -1
- package/dist/dev/static-server.d.ts +1 -0
- package/dist/dev/static-server.d.ts.map +1 -1
- package/dist/dev/static-server.js +9 -2
- package/dist/dev/static-server.js.map +1 -1
- package/dist/index.js +16 -4
- package/dist/index.js.map +1 -1
- package/dist/renderer/content-extractor.d.ts.map +1 -1
- package/dist/renderer/content-extractor.js +10 -4
- package/dist/renderer/content-extractor.js.map +1 -1
- package/dist/renderer/renderer-pipeline.d.ts.map +1 -1
- package/dist/renderer/renderer-pipeline.js +4 -1
- package/dist/renderer/renderer-pipeline.js.map +1 -1
- package/dist/server.d.ts +11 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +51 -13
- package/dist/server.js.map +1 -1
- package/dist/tools/dev-mode.d.ts +2 -2
- package/dist/tools/dev-mode.d.ts.map +1 -1
- package/dist/tools/dev-mode.js +5 -3
- package/dist/tools/dev-mode.js.map +1 -1
- package/dist/tools/dialog.d.ts +2 -1
- package/dist/tools/dialog.d.ts.map +1 -1
- package/dist/tools/dialog.js +3 -1
- package/dist/tools/dialog.js.map +1 -1
- package/dist/tools/evaluate.d.ts +2 -2
- package/dist/tools/evaluate.d.ts.map +1 -1
- package/dist/tools/evaluate.js +53 -39
- package/dist/tools/evaluate.js.map +1 -1
- package/dist/tools/interaction.d.ts +2 -1
- package/dist/tools/interaction.d.ts.map +1 -1
- package/dist/tools/interaction.js +178 -26
- package/dist/tools/interaction.js.map +1 -1
- package/dist/tools/meta-tool.d.ts +14 -0
- package/dist/tools/meta-tool.d.ts.map +1 -0
- package/dist/tools/meta-tool.js +123 -0
- package/dist/tools/meta-tool.js.map +1 -0
- package/dist/tools/monitoring.d.ts +4 -0
- package/dist/tools/monitoring.d.ts.map +1 -0
- package/dist/tools/monitoring.js +129 -0
- package/dist/tools/monitoring.js.map +1 -0
- package/dist/tools/navigation.d.ts +2 -1
- package/dist/tools/navigation.d.ts.map +1 -1
- package/dist/tools/navigation.js +6 -4
- package/dist/tools/navigation.js.map +1 -1
- package/dist/tools/observation.d.ts +2 -1
- package/dist/tools/observation.d.ts.map +1 -1
- package/dist/tools/observation.js +102 -10
- package/dist/tools/observation.js.map +1 -1
- package/dist/tools/session.d.ts +2 -1
- package/dist/tools/session.d.ts.map +1 -1
- package/dist/tools/session.js +13 -11
- package/dist/tools/session.js.map +1 -1
- package/dist/tools/tool-groups.d.ts +42 -0
- package/dist/tools/tool-groups.d.ts.map +1 -0
- package/dist/tools/tool-groups.js +251 -0
- package/dist/tools/tool-groups.js.map +1 -0
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +1 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/element-id.d.ts.map +1 -1
- package/dist/types/element-id.js +1 -0
- package/dist/types/element-id.js.map +1 -1
- package/dist/types/page-representation.d.ts +1 -0
- package/dist/types/page-representation.d.ts.map +1 -1
- package/dist/utils/wait.js +1 -1
- package/dist/utils/wait.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Charlotte will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.4.1] - 2026-03-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`charlotte:click_at`** — Click at specific page coordinates (x, y). Enables interaction with non-semantic elements (custom widgets, canvas regions, SVG graphics) that don't appear in the accessibility tree. Supports left/right/double click and modifier keys.
|
|
10
|
+
- **CSS selector mode for `charlotte:find`** — New `selector` parameter queries the DOM directly via `DOM.querySelectorAll`, returning elements with Charlotte IDs usable by all interaction tools. Complements the existing accessibility tree search for elements that lack semantic roles.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`charlotte:evaluate` silent null on multi-statement code** — Replaced `new Function('return ' + expr)` with CDP `Runtime.evaluate`, which evaluates JavaScript as a program and returns the completion value of the last expression-statement. The previous implementation suffered from ASI (Automatic Semicolon Insertion) silently converting `return\n...` into `return;`, causing multi-line scripts to return null without error.
|
|
15
|
+
|
|
16
|
+
## [0.4.0] - 2026-03-03
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Tiered tool visibility** — Startup profiles control which tools load into the agent's context. `--profile=browse` (default, 22 tools) replaces the previous behavior of loading all 40 tools. Six profiles available: `core` (7), `browse` (22), `interact` (27), `develop` (30), `audit` (13), `full` (40). Granular group selection via `--tools=group1,group2`.
|
|
21
|
+
- **`charlotte:tools` meta-tool** — Runtime tool group management. Agents can list available groups, enable groups to activate tools mid-session, and disable groups to reduce overhead — without restarting the server. Always registered regardless of profile.
|
|
22
|
+
- **Profile benchmark suite** — `npx tsx benchmarks/run-benchmarks.ts --suite profiles` runs tool definition overhead benchmarks across full, browse, and core profiles. Four tests: pure overhead measurement, 5-site browsing session, form interaction, and runtime toggle correctness. Results archived under `benchmarks/results/raw/tiered-profiles-v1/`.
|
|
23
|
+
- **`charlotte:drag`** — Drag an element to another element using mouse primitives (mousedown → intermediate moves → mouseup). Accepts `source_id` and `target_id` element IDs. Closes GAP-01 from the Playwright MCP gap analysis.
|
|
24
|
+
- **Landmark IDs** — Landmarks now have stable hash-based IDs (`rgn-xxxx`) like headings and interactive elements, making them referenceable by tools (e.g., as drag-and-drop targets).
|
|
25
|
+
- **`charlotte:console`** — Retrieve console messages from the active page at all severity levels (log, info, warn, error, debug) with timestamps. Supports level filtering and buffer clearing. Closes GAP-21 from the Playwright MCP gap analysis.
|
|
26
|
+
- **`charlotte:requests`** — Retrieve network request history from the active page with method, status, resource type, and timestamps. Supports filtering by URL pattern, resource type, and minimum status code. Closes GAP-22 from the Playwright MCP gap analysis.
|
|
27
|
+
- **Modifier key clicks** — `charlotte:click` now accepts an optional `modifiers` parameter (`ctrl`, `shift`, `alt`, `meta`, or combinations) for Ctrl+Click, Shift+Click, etc. Works with all click types (left, right, double).
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **Pseudo-element content duplication** — `extractFullContent()` was emitting both content-role node names and their StaticText children, causing duplicate text when CSS `::before`/`::after` pseudo-elements were present.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Default startup profile is now `browse` (22 tools) instead of loading all 40 tools. Use `--profile=full` for the previous behavior.
|
|
36
|
+
- PageManager now captures all console messages and all network responses (not just errors). Ring buffers capped at 1000 entries each. Backward-compatible: `getConsoleErrors()` and `getNetworkErrors()` still return only errors for `PageRepresentation.errors`.
|
|
37
|
+
- Static server now binds to `127.0.0.1` instead of `0.0.0.0`, preventing external network access. Directory traversal prevention via `allowedWorkspaceRoot` validation with `fs.realpathSync()`.
|
|
38
|
+
|
|
5
39
|
## [0.3.0] - 2026-02-24
|
|
6
40
|
|
|
7
41
|
### Added
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Charlotte takes a different approach. It decomposes each page into a typed, stru
|
|
|
12
12
|
|
|
13
13
|
### Benchmarks
|
|
14
14
|
|
|
15
|
-
Charlotte v0.
|
|
15
|
+
Charlotte v0.4.1 vs Playwright MCP, measured by characters returned per tool call on real websites:
|
|
16
16
|
|
|
17
17
|
**Navigation** (first contact with a page):
|
|
18
18
|
|
|
@@ -25,16 +25,15 @@ Charlotte v0.3.0 vs Playwright MCP, measured by characters returned per tool cal
|
|
|
25
25
|
|
|
26
26
|
Charlotte's `navigate` returns minimal detail by default — landmarks, headings, and interactive element counts grouped by page region. Enough to orient, not enough to overwhelm. On Wikipedia, that's **135x smaller** than Playwright's response.
|
|
27
27
|
|
|
28
|
-
**
|
|
28
|
+
**Tool definition overhead** (invisible cost per API call):
|
|
29
29
|
|
|
30
|
-
|
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
| GitHub repo | 37,628 | 80,190 |
|
|
30
|
+
| Profile | Tools | Def. tokens/call | Savings vs full |
|
|
31
|
+
|:---|---:|---:|---:|
|
|
32
|
+
| full | 41 | ~7,400 | — |
|
|
33
|
+
| browse (default) | 23 | ~3,900 | **~47%** |
|
|
34
|
+
| core | 7 | 1,677 | **~77%** |
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
Tool definitions are sent on every API round-trip. With the default `browse` profile, Charlotte carries ~47% less definition overhead than loading all 41 tools. Over a 20-call browsing session, that's **~38% fewer total tokens**. See the [profile benchmark report](docs/charlotte-profile-benchmark-report.md) for full results.
|
|
38
37
|
|
|
39
38
|
**The workflow difference:** Playwright agents receive 61K+ characters every time they look at Hacker News, whether they're reading headlines or looking for a login button. Charlotte agents get 336 characters on arrival, call `find({ type: "link", text: "login" })` to get exactly what they need, and never pay for the rest.
|
|
40
39
|
|
|
@@ -64,9 +63,11 @@ Agents receive landmarks, headings, interactive elements with typed metadata, bo
|
|
|
64
63
|
|
|
65
64
|
**Navigation** — `navigate`, `back`, `forward`, `reload`
|
|
66
65
|
|
|
67
|
-
**Observation** — `observe` (3 detail levels), `find` (spatial + semantic search), `screenshot`, `diff` (structural comparison against snapshots)
|
|
66
|
+
**Observation** — `observe` (3 detail levels), `find` (spatial + semantic search, CSS selector mode), `screenshot`, `diff` (structural comparison against snapshots)
|
|
67
|
+
|
|
68
|
+
**Interaction** — `click`, `click_at` (coordinate-based), `type`, `select`, `toggle`, `submit`, `scroll`, `hover`, `drag`, `key`, `wait_for` (async condition polling), `dialog` (accept/dismiss JS dialogs)
|
|
68
69
|
|
|
69
|
-
**
|
|
70
|
+
**Monitoring** — `console` (all severity levels, filtering, timestamps), `requests` (full HTTP history, method/status/resource type filtering)
|
|
70
71
|
|
|
71
72
|
**Session Management** — `tabs`, `tab_open`, `tab_switch`, `tab_close`, `viewport` (device presets), `network` (throttling, URL blocking), `set_cookies`, `get_cookies`, `clear_cookies`, `set_headers`, `configure`
|
|
72
73
|
|
|
@@ -74,6 +75,27 @@ Agents receive landmarks, headings, interactive elements with typed metadata, bo
|
|
|
74
75
|
|
|
75
76
|
**Utilities** — `evaluate` (arbitrary JS execution in page context)
|
|
76
77
|
|
|
78
|
+
## Tool Profiles
|
|
79
|
+
|
|
80
|
+
Charlotte ships 41 tools, but most workflows only need a subset. Startup profiles control which tools load into the agent's context, reducing definition overhead by up to 77%.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
charlotte --profile browse # 23 tools (default) — navigate, observe, interact, tabs
|
|
84
|
+
charlotte --profile core # 7 tools — navigate, observe, find, click, type, submit
|
|
85
|
+
charlotte --profile full # 41 tools — everything
|
|
86
|
+
charlotte --profile interact # 28 tools — full interaction + dialog + evaluate
|
|
87
|
+
charlotte --profile develop # 31 tools — interact + dev_serve, dev_inject, dev_audit
|
|
88
|
+
charlotte --profile audit # 13 tools — navigation + observation + dev_audit + viewport
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Agents can activate more tools mid-session without restarting:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
charlotte:tools enable dev_mode → activates dev_serve, dev_audit, dev_inject
|
|
95
|
+
charlotte:tools disable dev_mode → deactivates them
|
|
96
|
+
charlotte:tools list → see what's loaded
|
|
97
|
+
```
|
|
98
|
+
|
|
77
99
|
## Quick Start
|
|
78
100
|
|
|
79
101
|
### Prerequisites
|
|
@@ -116,9 +138,12 @@ npm run build
|
|
|
116
138
|
Charlotte communicates over stdio using the MCP protocol:
|
|
117
139
|
|
|
118
140
|
```bash
|
|
119
|
-
# If installed globally
|
|
141
|
+
# If installed globally (default browse profile)
|
|
120
142
|
charlotte
|
|
121
143
|
|
|
144
|
+
# With a specific profile
|
|
145
|
+
charlotte --profile core
|
|
146
|
+
|
|
122
147
|
# If installed from source
|
|
123
148
|
npm start
|
|
124
149
|
```
|
|
@@ -226,8 +251,8 @@ Full interactive element list with typed metadata, form structures, and content
|
|
|
226
251
|
"viewport": { "width": 1280, "height": 720 },
|
|
227
252
|
"structure": {
|
|
228
253
|
"landmarks": [
|
|
229
|
-
{ "role": "banner", "label": "Site header", "bounds": { "x": 0, "y": 0, "w": 1280, "h": 64 } },
|
|
230
|
-
{ "role": "main", "label": "Content", "bounds": { "x": 240, "y": 64, "w": 1040, "h": 656 } }
|
|
254
|
+
{ "id": "rgn-b2c1", "role": "banner", "label": "Site header", "bounds": { "x": 0, "y": 0, "w": 1280, "h": 64 } },
|
|
255
|
+
{ "id": "rgn-d4e5", "role": "main", "label": "Content", "bounds": { "x": 240, "y": 64, "w": 1040, "h": 656 } }
|
|
231
256
|
],
|
|
232
257
|
"headings": [{ "level": 1, "text": "Dashboard", "id": "h-1a2b" }],
|
|
233
258
|
"content_summary": "main: 2 headings, 5 links, 1 form"
|
|
@@ -267,6 +292,8 @@ Element IDs are stable across minor DOM mutations. They're generated by hashing
|
|
|
267
292
|
btn-a3f1 (button) inp-c7e2 (text input)
|
|
268
293
|
lnk-d4b9 (link) sel-e8a3 (select)
|
|
269
294
|
chk-f1a2 (checkbox) frm-b1d4 (form)
|
|
295
|
+
rgn-e0d2 (landmark) hdg-0f40 (heading)
|
|
296
|
+
dom-b2c3 (DOM element, from CSS selector queries)
|
|
270
297
|
```
|
|
271
298
|
|
|
272
299
|
IDs survive unrelated DOM changes and element reordering within the same container. When an agent navigates at minimal detail (no individual element IDs), it uses `find` to locate elements by text, type, or spatial proximity — the returned elements include IDs ready for interaction.
|
|
@@ -320,7 +347,7 @@ All tools go through `renderActivePage()` which handles snapshots, reload events
|
|
|
320
347
|
|
|
321
348
|
## Sandbox
|
|
322
349
|
|
|
323
|
-
Charlotte includes a test website in `tests/sandbox/` that exercises all
|
|
350
|
+
Charlotte includes a test website in `tests/sandbox/` that exercises all 41 tools without touching the public internet. Serve it locally with:
|
|
324
351
|
|
|
325
352
|
```
|
|
326
353
|
dev_serve({ path: "tests/sandbox" })
|
|
@@ -338,30 +365,16 @@ Four pages cover navigation, forms, interactive elements, delayed content, scrol
|
|
|
338
365
|
|
|
339
366
|
**No file upload support** — Charlotte identifies `file_input` elements in the page representation but provides no tool to set file paths on them. Workflows that require file uploads cannot be completed.
|
|
340
367
|
|
|
341
|
-
**No drag-and-drop support** — There is no tool for drag-and-drop interactions. Kanban boards, sortable lists, slider handles, and file drop zones cannot be automated.
|
|
342
|
-
|
|
343
|
-
**Console and network monitoring are error-only** — Charlotte captures console errors and failed network requests in the page representation, but does not expose a dedicated tool for retrieving all console messages or all network requests. Agents debugging JavaScript or API issues have limited visibility.
|
|
344
|
-
|
|
345
368
|
## Roadmap
|
|
346
369
|
|
|
347
370
|
### Interaction Gaps
|
|
348
371
|
|
|
349
372
|
**File Upload** — Add a `charlotte:upload` tool to set file paths on `file_input` elements via Puppeteer's `elementHandle.uploadFile()`. Charlotte already identifies file inputs but cannot act on them.
|
|
350
373
|
|
|
351
|
-
**Drag and Drop** — Add a `charlotte:drag` tool for element-to-element drag-and-drop using Puppeteer mouse primitives. Covers kanban boards, sortable lists, sliders, and drop zones.
|
|
352
|
-
|
|
353
374
|
**Batch Form Fill** — Add a `charlotte:fill_form` tool that accepts an array of `{element_id, value}` pairs and fills an entire form in a single tool call, reducing N sequential `type`/`select`/`toggle` calls to one.
|
|
354
375
|
|
|
355
376
|
**Slow Typing** — Add a `slowly` or `character_delay` parameter to `charlotte:type` for character-by-character input. Required for sites with key-by-key event handlers (autocomplete, search-as-you-type, input validation).
|
|
356
377
|
|
|
357
|
-
**Click Modifiers** — Add a `modifiers` parameter (`ctrl`, `shift`, `alt`, `meta`) to `charlotte:click` for Ctrl+Click (open in new tab), Shift+Click (range select), and similar patterns.
|
|
358
|
-
|
|
359
|
-
### Monitoring
|
|
360
|
-
|
|
361
|
-
**Console Message Retrieval** — Add a `charlotte:console` tool to retrieve all console messages (not just errors) with level filtering. Charlotte already listens to console events internally but only surfaces errors in the page representation.
|
|
362
|
-
|
|
363
|
-
**Network Request Monitoring** — Add a `charlotte:requests` tool to retrieve all network requests (not just failures) with filtering options. Enables agents to debug API calls and resource loading.
|
|
364
|
-
|
|
365
378
|
### Session & Configuration
|
|
366
379
|
|
|
367
380
|
**Connect to Existing Browser** — Add a `--cdp-endpoint` CLI argument so Charlotte can attach to an already-running browser via `puppeteer.connect()` instead of always launching a new instance. Enables working with logged-in sessions and browser extensions.
|
|
@@ -397,3 +410,6 @@ See [docs/CHARLOTTE_SPEC.md](docs/CHARLOTTE_SPEC.md) for the complete specificat
|
|
|
397
410
|
## Contributing
|
|
398
411
|
|
|
399
412
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
*Part of a growing suite of literary-named MCP servers. See more at [github.com/TickTockBent](https://github.com/TickTockBent).*
|
|
@@ -8,6 +8,19 @@ export interface TabInfo {
|
|
|
8
8
|
title: string;
|
|
9
9
|
active: boolean;
|
|
10
10
|
}
|
|
11
|
+
export interface ConsoleMessage {
|
|
12
|
+
level: string;
|
|
13
|
+
text: string;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
}
|
|
16
|
+
export interface NetworkRequest {
|
|
17
|
+
url: string;
|
|
18
|
+
method: string;
|
|
19
|
+
status: number;
|
|
20
|
+
statusText: string;
|
|
21
|
+
resourceType: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
}
|
|
11
24
|
export declare class PageManager {
|
|
12
25
|
private pages;
|
|
13
26
|
private activeTabId;
|
|
@@ -19,15 +32,23 @@ export declare class PageManager {
|
|
|
19
32
|
listTabs(): Promise<TabInfo[]>;
|
|
20
33
|
getActivePage(): Page;
|
|
21
34
|
getActiveTabId(): string;
|
|
35
|
+
/** Return only error/warn console messages (for PageRepresentation.errors). */
|
|
22
36
|
getConsoleErrors(): Array<{
|
|
23
37
|
level: string;
|
|
24
38
|
text: string;
|
|
25
39
|
}>;
|
|
40
|
+
/** Return only HTTP error responses (status >= 400, for PageRepresentation.errors). */
|
|
26
41
|
getNetworkErrors(): Array<{
|
|
27
42
|
url: string;
|
|
28
43
|
status: number;
|
|
29
44
|
statusText: string;
|
|
30
45
|
}>;
|
|
46
|
+
/** Return all console messages, optionally filtered by level. */
|
|
47
|
+
getConsoleMessages(level?: string): ConsoleMessage[];
|
|
48
|
+
/** Return all network requests, optionally filtered. */
|
|
49
|
+
getNetworkRequests(): NetworkRequest[];
|
|
50
|
+
clearConsoleMessages(): void;
|
|
51
|
+
clearNetworkRequests(): void;
|
|
31
52
|
clearErrors(): void;
|
|
32
53
|
getPendingDialogInfo(): PendingDialog | null;
|
|
33
54
|
getPendingDialog(): Dialog | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-manager.d.ts","sourceRoot":"","sources":["../../src/browser/page-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1D,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"page-manager.d.ts","sourceRoot":"","sources":["../../src/browser/page-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1D,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,CAAC,EAAE,eAAe;IAK9B,OAAO,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuFtE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtC,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAapC,aAAa,IAAI,IAAI;IAmBrB,cAAc,IAAI,MAAM;IAUxB,+EAA+E;IAC/E,gBAAgB,IAAI,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAS1D,uFAAuF;IACvF,gBAAgB,IAAI,KAAK,CAAC;QACxB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IASF,iEAAiE;IACjE,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAUpD,wDAAwD;IACxD,kBAAkB,IAAI,cAAc,EAAE;IAOtC,oBAAoB,IAAI,IAAI;IAQ5B,oBAAoB,IAAI,IAAI;IAQ5B,WAAW,IAAI,IAAI;IASnB,oBAAoB,IAAI,aAAa,GAAG,IAAI;IAM5C,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAMjC,kBAAkB,IAAI,IAAI;IAS1B,QAAQ,IAAI,OAAO;CAGpB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createDefaultConfig } from "../types/config.js";
|
|
2
2
|
import { CharlotteError, CharlotteErrorCode } from "../types/errors.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
+
const MAX_CONSOLE_MESSAGES = 1000;
|
|
5
|
+
const MAX_NETWORK_REQUESTS = 1000;
|
|
4
6
|
let nextTabIdCounter = 1;
|
|
5
7
|
function generateTabId() {
|
|
6
8
|
return `tab-${nextTabIdCounter++}`;
|
|
@@ -19,30 +21,35 @@ export class PageManager {
|
|
|
19
21
|
const managedPage = {
|
|
20
22
|
id: tabId,
|
|
21
23
|
page,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
consoleMessages: [],
|
|
25
|
+
networkRequests: [],
|
|
24
26
|
pendingDialog: null,
|
|
25
27
|
pendingDialogInfo: null,
|
|
26
28
|
};
|
|
27
|
-
// Collect console
|
|
29
|
+
// Collect all console messages
|
|
28
30
|
page.on("console", (msg) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
managedPage.consoleErrors.push({
|
|
32
|
-
level,
|
|
33
|
-
text: msg.text(),
|
|
34
|
-
});
|
|
31
|
+
if (managedPage.consoleMessages.length >= MAX_CONSOLE_MESSAGES) {
|
|
32
|
+
managedPage.consoleMessages.shift();
|
|
35
33
|
}
|
|
34
|
+
managedPage.consoleMessages.push({
|
|
35
|
+
level: msg.type(),
|
|
36
|
+
text: msg.text(),
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
});
|
|
36
39
|
});
|
|
37
|
-
// Collect network
|
|
40
|
+
// Collect all network responses
|
|
38
41
|
page.on("response", (response) => {
|
|
39
|
-
if (
|
|
40
|
-
managedPage.
|
|
41
|
-
url: response.url(),
|
|
42
|
-
status: response.status(),
|
|
43
|
-
statusText: response.statusText(),
|
|
44
|
-
});
|
|
42
|
+
if (managedPage.networkRequests.length >= MAX_NETWORK_REQUESTS) {
|
|
43
|
+
managedPage.networkRequests.shift();
|
|
45
44
|
}
|
|
45
|
+
managedPage.networkRequests.push({
|
|
46
|
+
url: response.url(),
|
|
47
|
+
method: response.request().method(),
|
|
48
|
+
status: response.status(),
|
|
49
|
+
statusText: response.statusText(),
|
|
50
|
+
resourceType: response.request().resourceType(),
|
|
51
|
+
timestamp: new Date().toISOString(),
|
|
52
|
+
});
|
|
46
53
|
});
|
|
47
54
|
// Handle JavaScript dialogs (alert, confirm, prompt, beforeunload)
|
|
48
55
|
page.on("dialog", async (dialog) => {
|
|
@@ -67,10 +74,13 @@ export class PageManager {
|
|
|
67
74
|
timestamp: new Date().toISOString(),
|
|
68
75
|
};
|
|
69
76
|
});
|
|
70
|
-
// Clear stale dialog references on navigation
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
// Clear stale dialog references on main-frame navigation only.
|
|
78
|
+
// Subframe navigations (iframes, ads, embeds) must not wipe dialog state.
|
|
79
|
+
page.on("framenavigated", (frame) => {
|
|
80
|
+
if (frame === page.mainFrame()) {
|
|
81
|
+
managedPage.pendingDialog = null;
|
|
82
|
+
managedPage.pendingDialogInfo = null;
|
|
83
|
+
}
|
|
74
84
|
});
|
|
75
85
|
this.pages.set(tabId, managedPage);
|
|
76
86
|
this.activeTabId = tabId;
|
|
@@ -131,25 +141,72 @@ export class PageManager {
|
|
|
131
141
|
}
|
|
132
142
|
return this.activeTabId;
|
|
133
143
|
}
|
|
144
|
+
/** Return only error/warn console messages (for PageRepresentation.errors). */
|
|
134
145
|
getConsoleErrors() {
|
|
135
146
|
if (!this.activeTabId)
|
|
136
147
|
return [];
|
|
137
148
|
const managedPage = this.pages.get(this.activeTabId);
|
|
138
|
-
|
|
149
|
+
if (!managedPage)
|
|
150
|
+
return [];
|
|
151
|
+
return managedPage.consoleMessages
|
|
152
|
+
.filter((m) => m.level === "error" || m.level === "warn")
|
|
153
|
+
.map(({ level, text }) => ({ level, text }));
|
|
139
154
|
}
|
|
155
|
+
/** Return only HTTP error responses (status >= 400, for PageRepresentation.errors). */
|
|
140
156
|
getNetworkErrors() {
|
|
141
157
|
if (!this.activeTabId)
|
|
142
158
|
return [];
|
|
143
159
|
const managedPage = this.pages.get(this.activeTabId);
|
|
144
|
-
|
|
160
|
+
if (!managedPage)
|
|
161
|
+
return [];
|
|
162
|
+
return managedPage.networkRequests
|
|
163
|
+
.filter((r) => r.status >= 400)
|
|
164
|
+
.map(({ url, status, statusText }) => ({ url, status, statusText }));
|
|
165
|
+
}
|
|
166
|
+
/** Return all console messages, optionally filtered by level. */
|
|
167
|
+
getConsoleMessages(level) {
|
|
168
|
+
if (!this.activeTabId)
|
|
169
|
+
return [];
|
|
170
|
+
const managedPage = this.pages.get(this.activeTabId);
|
|
171
|
+
if (!managedPage)
|
|
172
|
+
return [];
|
|
173
|
+
if (level && level !== "all") {
|
|
174
|
+
return managedPage.consoleMessages.filter((m) => m.level === level);
|
|
175
|
+
}
|
|
176
|
+
return [...managedPage.consoleMessages];
|
|
177
|
+
}
|
|
178
|
+
/** Return all network requests, optionally filtered. */
|
|
179
|
+
getNetworkRequests() {
|
|
180
|
+
if (!this.activeTabId)
|
|
181
|
+
return [];
|
|
182
|
+
const managedPage = this.pages.get(this.activeTabId);
|
|
183
|
+
if (!managedPage)
|
|
184
|
+
return [];
|
|
185
|
+
return [...managedPage.networkRequests];
|
|
186
|
+
}
|
|
187
|
+
clearConsoleMessages() {
|
|
188
|
+
if (!this.activeTabId)
|
|
189
|
+
return;
|
|
190
|
+
const managedPage = this.pages.get(this.activeTabId);
|
|
191
|
+
if (managedPage) {
|
|
192
|
+
managedPage.consoleMessages = [];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
clearNetworkRequests() {
|
|
196
|
+
if (!this.activeTabId)
|
|
197
|
+
return;
|
|
198
|
+
const managedPage = this.pages.get(this.activeTabId);
|
|
199
|
+
if (managedPage) {
|
|
200
|
+
managedPage.networkRequests = [];
|
|
201
|
+
}
|
|
145
202
|
}
|
|
146
203
|
clearErrors() {
|
|
147
204
|
if (!this.activeTabId)
|
|
148
205
|
return;
|
|
149
206
|
const managedPage = this.pages.get(this.activeTabId);
|
|
150
207
|
if (managedPage) {
|
|
151
|
-
managedPage.
|
|
152
|
-
managedPage.
|
|
208
|
+
managedPage.consoleMessages = [];
|
|
209
|
+
managedPage.networkRequests = [];
|
|
153
210
|
}
|
|
154
211
|
}
|
|
155
212
|
getPendingDialogInfo() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-manager.js","sourceRoot":"","sources":["../../src/browser/page-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"page-manager.js","sourceRoot":"","sources":["../../src/browser/page-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parsing for Charlotte.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from index.ts so it can be tested without triggering
|
|
5
|
+
* the main() side effect.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolProfile, ToolGroupName } from "./tools/tool-groups.js";
|
|
8
|
+
export declare function parseCliArgs(argv?: string[]): {
|
|
9
|
+
profile?: ToolProfile;
|
|
10
|
+
toolGroups?: ToolGroupName[];
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAWzE,wBAAgB,YAAY,CAC1B,IAAI,GAAE,MAAM,EAA0B,GACrC;IAAE,OAAO,CAAC,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,EAAE,CAAA;CAAE,CA4BzD"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parsing for Charlotte.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from index.ts so it can be tested without triggering
|
|
5
|
+
* the main() side effect.
|
|
6
|
+
*/
|
|
7
|
+
import { logger } from "./utils/logger.js";
|
|
8
|
+
const VALID_PROFILES = [
|
|
9
|
+
"core", "browse", "interact", "develop", "audit", "full",
|
|
10
|
+
];
|
|
11
|
+
const VALID_GROUPS = [
|
|
12
|
+
"navigation", "observation", "interaction", "session",
|
|
13
|
+
"dev_mode", "dialog", "evaluate", "monitoring",
|
|
14
|
+
];
|
|
15
|
+
export function parseCliArgs(argv = process.argv.slice(2)) {
|
|
16
|
+
const profileArg = argv.find((a) => a.startsWith("--profile="));
|
|
17
|
+
const toolsArg = argv.find((a) => a.startsWith("--tools="));
|
|
18
|
+
if (profileArg && toolsArg) {
|
|
19
|
+
logger.warn("Both --profile and --tools provided; --profile takes precedence");
|
|
20
|
+
}
|
|
21
|
+
if (profileArg) {
|
|
22
|
+
const profile = profileArg.split("=")[1];
|
|
23
|
+
if (!VALID_PROFILES.includes(profile)) {
|
|
24
|
+
throw new Error(`Invalid profile: ${profile}. Valid profiles: ${VALID_PROFILES.join(", ")}`);
|
|
25
|
+
}
|
|
26
|
+
return { profile };
|
|
27
|
+
}
|
|
28
|
+
if (toolsArg) {
|
|
29
|
+
const groups = toolsArg.split("=")[1].split(",");
|
|
30
|
+
for (const group of groups) {
|
|
31
|
+
if (!VALID_GROUPS.includes(group)) {
|
|
32
|
+
throw new Error(`Invalid tool group: ${group}. Valid groups: ${VALID_GROUPS.join(", ")}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { toolGroups: groups };
|
|
36
|
+
}
|
|
37
|
+
// Default: no profile or groups specified — createServer defaults to browse
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,MAAM,cAAc,GAAkB;IACpC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;CACzD,CAAC;AAEF,MAAM,YAAY,GAAoB;IACpC,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS;IACrD,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY;CAC/C,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEtC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAE5D,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAgB,CAAC;QACxD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,qBAAqB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;QACpE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,mBAAmB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PageManager } from "../browser/page-manager.js";
|
|
2
2
|
import type { ReloadEvent } from "../types/page-representation.js";
|
|
3
|
+
import type { CharlotteConfig } from "../types/config.js";
|
|
3
4
|
import { type StaticServerInfo } from "./static-server.js";
|
|
4
5
|
export interface DevServeOptions {
|
|
5
6
|
directoryPath: string;
|
|
@@ -10,6 +11,8 @@ export interface DevServeOptions {
|
|
|
10
11
|
usePolling?: boolean;
|
|
11
12
|
}
|
|
12
13
|
export declare class DevModeState {
|
|
14
|
+
private config;
|
|
15
|
+
constructor(config: CharlotteConfig);
|
|
13
16
|
private staticServer;
|
|
14
17
|
private fileWatcher;
|
|
15
18
|
private pendingReloadEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-mode-state.d.ts","sourceRoot":"","sources":["../../src/dev/dev-mode-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIzE,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,gBAAgB,CAA8B;IAEhD,YAAY,CAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev-mode-state.d.ts","sourceRoot":"","sources":["../../src/dev/dev-mode-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIzE,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,eAAe;IAInC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,gBAAgB,CAA8B;IAEhD,YAAY,CAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC;IAuBtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,yBAAyB,IAAI,WAAW,GAAG,IAAI;IAM/C,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,gBAAgB,GAAG,IAAI;IAIxC,OAAO,CAAC,kBAAkB;CAiD3B"}
|
|
@@ -2,6 +2,10 @@ import { StaticServer } from "./static-server.js";
|
|
|
2
2
|
import { FileWatcher } from "./file-watcher.js";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
4
|
export class DevModeState {
|
|
5
|
+
config;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
5
9
|
staticServer = new StaticServer();
|
|
6
10
|
fileWatcher = new FileWatcher();
|
|
7
11
|
pendingReloadEvent = null;
|
|
@@ -11,6 +15,7 @@ export class DevModeState {
|
|
|
11
15
|
await this.stopAll();
|
|
12
16
|
const serverInfo = await this.staticServer.start({
|
|
13
17
|
directoryPath: options.directoryPath,
|
|
18
|
+
allowedRoot: this.config.allowedWorkspaceRoot,
|
|
14
19
|
port: options.port,
|
|
15
20
|
});
|
|
16
21
|
if (options.watch) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-mode-state.js","sourceRoot":"","sources":["../../src/dev/dev-mode-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev-mode-state.js","sourceRoot":"","sources":["../../src/dev/dev-mode-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-server.d.ts","sourceRoot":"","sources":["../../src/dev/static-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"static-server.d.ts","sourceRoot":"","sources":["../../src/dev/static-server.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,UAAU,CAAiC;IAE7C,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuD9D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,SAAS,IAAI,OAAO;IAIpB,OAAO,IAAI,gBAAgB,GAAG,IAAI;CAGnC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import * as fs from "node:fs";
|
|
3
4
|
import { logger } from "../utils/logger.js";
|
|
4
5
|
export class StaticServer {
|
|
5
6
|
httpServer = null;
|
|
@@ -9,12 +10,18 @@ export class StaticServer {
|
|
|
9
10
|
if (this.httpServer) {
|
|
10
11
|
await this.stop();
|
|
11
12
|
}
|
|
12
|
-
const
|
|
13
|
+
const resolvedDirPath = path.resolve(options.directoryPath);
|
|
14
|
+
const absoluteDirectoryPath = fs.existsSync(resolvedDirPath) ? fs.realpathSync(resolvedDirPath) : resolvedDirPath;
|
|
15
|
+
const configuredRoot = options.allowedRoot ? path.resolve(options.allowedRoot) : process.cwd();
|
|
16
|
+
const rootPath = fs.existsSync(configuredRoot) ? fs.realpathSync(configuredRoot) : configuredRoot;
|
|
17
|
+
if (!absoluteDirectoryPath.startsWith(rootPath)) {
|
|
18
|
+
throw new Error(`Directory traversal blocked. Path must be within ${rootPath}`);
|
|
19
|
+
}
|
|
13
20
|
const app = express();
|
|
14
21
|
app.use(express.static(absoluteDirectoryPath));
|
|
15
22
|
const listenPort = options.port ?? 0;
|
|
16
23
|
return new Promise((resolve, reject) => {
|
|
17
|
-
const server = app.listen(listenPort, () => {
|
|
24
|
+
const server = app.listen(listenPort, "127.0.0.1", () => {
|
|
18
25
|
const address = server.address();
|
|
19
26
|
if (!address || typeof address === "string") {
|
|
20
27
|
reject(new Error("Failed to get server address"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-server.js","sourceRoot":"","sources":["../../src/dev/static-server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"static-server.js","sourceRoot":"","sources":["../../src/dev/static-server.ts"],"names":[],"mappings":"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"}
|