heroshot 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/dist/cli/cli.js +25 -28
- package/dist/index.js +1 -2
- package/dist/mcp/index.js +5 -11282
- package/dist/server-BklhdmjN.js +319 -0
- package/dist/server-CqRfIFJa.js +3 -0
- package/dist/{snippet-Cm6b-EdU.js → snippet-ZcZmuryj.js} +14 -83
- package/dist/templates/heroshotReadme.txt +1 -1
- package/editor/dist/editor.js +1733 -1194
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://heroshot.
|
|
2
|
+
<a href="https://heroshot.dev">
|
|
3
3
|
<picture>
|
|
4
4
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/omachala/heroshot/refs/heads/main/docs/public/screenshots/hero-desktop-dark.png">
|
|
5
5
|
<img src="https://raw.githubusercontent.com/omachala/heroshot/refs/heads/main/docs/public/screenshots/hero-desktop-light.png" alt="heroshot">
|
|
6
6
|
</picture>
|
|
7
7
|
</a>
|
|
8
8
|
</p>
|
|
9
|
-
<p align="center"><em>👆 This hero shot of <a href="https://heroshot.
|
|
9
|
+
<p align="center"><em>👆 This hero shot of <a href="https://heroshot.dev">heroshot.dev</a> is <a href="https://github.com/omachala/heroshot/blob/main/.github/workflows/update-screenshots.yml#L17">taken</a> by heroshot ⚡️</em></p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/heroshot"><img src="https://img.shields.io/npm/dt/heroshot?style=for-the-badge" alt="npm downloads"></a>
|
|
13
13
|
<a href="https://www.npmjs.com/package/heroshot"><img src="https://img.shields.io/npm/v/heroshot?style=for-the-badge&logo=npm" alt="npm version"></a>
|
|
14
14
|
<a href="https://codecov.io/gh/omachala/heroshot"><img src="https://img.shields.io/codecov/c/github/omachala/heroshot?style=for-the-badge" alt="coverage"></a>
|
|
15
15
|
<a href="https://sonarcloud.io/summary/new_code?id=omachala_heroshot"><img src="https://img.shields.io/sonar/quality_gate/omachala_heroshot?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarcloud" alt="quality gate"></a>
|
|
16
|
-
<a href="https://heroshot.
|
|
16
|
+
<a href="https://heroshot.dev"><img src="https://img.shields.io/badge/docs-heroshot.dev-blue?style=for-the-badge" alt="docs"></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
|
-
<p align="center">Like Heroshot? Share your story — <a href="https://x.com/intent/tweet?url=https%3A%2F%2Fheroshot.
|
|
19
|
+
<p align="center">Like Heroshot? Share your story — <a href="https://x.com/intent/tweet?url=https%3A%2F%2Fheroshot.dev">X/Twitter</a> · <a href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fheroshot.dev">LinkedIn</a> · <a href="https://www.reddit.com/submit?url=https%3A%2F%2Fheroshot.dev&title=Heroshot%20%E2%80%93%20Define%20screenshots%20once%2C%20update%20them%20forever">Reddit</a> ❤️</p>
|
|
20
20
|
|
|
21
21
|
Your app changes constantly. New features, design tweaks, bug fixes. Meanwhile, the screenshots in your README and docs quietly become lies.
|
|
22
22
|
|
|
@@ -36,7 +36,7 @@ First run opens a browser with a visual editor. Pick elements, adjust padding, s
|
|
|
36
36
|
|
|
37
37
|
## Use in Your Docs
|
|
38
38
|
|
|
39
|
-
**VitePress** · [Full guide](https://heroshot.
|
|
39
|
+
**VitePress** · [Full guide](https://heroshot.dev/docs/integrations/vitepress)
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
42
|
// .vitepress/config.ts
|
|
@@ -52,7 +52,7 @@ import { Heroshot } from 'heroshot/vue';
|
|
|
52
52
|
<Heroshot name="dashboard" alt="Dashboard" />
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
**Docusaurus** · [Full guide](https://heroshot.
|
|
55
|
+
**Docusaurus** · [Full guide](https://heroshot.dev/docs/integrations/docusaurus)
|
|
56
56
|
|
|
57
57
|
```js
|
|
58
58
|
// docusaurus.config.js
|
|
@@ -64,7 +64,7 @@ import { Heroshot } from 'heroshot/docusaurus';
|
|
|
64
64
|
<Heroshot name="dashboard" alt="Dashboard" />;
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
**MkDocs** · [Full guide](https://heroshot.
|
|
67
|
+
**MkDocs** · [Full guide](https://heroshot.dev/docs/integrations/mkdocs)
|
|
68
68
|
|
|
69
69
|
```yaml
|
|
70
70
|
# mkdocs.yml
|
|
@@ -100,13 +100,13 @@ One component/macro, all variants - light/dark mode switches automatically, resp
|
|
|
100
100
|
|
|
101
101
|
## Learn More
|
|
102
102
|
|
|
103
|
-
| |
|
|
104
|
-
| ------------------- |
|
|
105
|
-
| **Documentation** | [heroshot.
|
|
106
|
-
| **Getting Started** | [Quick start guide](https://heroshot.
|
|
107
|
-
| **Configuration** | [Config options](https://heroshot.
|
|
108
|
-
| **CI/CD Setup** | [Automated updates](https://heroshot.
|
|
109
|
-
| **CLI Reference** | [All commands & flags](https://heroshot.
|
|
103
|
+
| | |
|
|
104
|
+
| ------------------- | ---------------------------------------------------------------------- |
|
|
105
|
+
| **Documentation** | [heroshot.dev](https://heroshot.dev) |
|
|
106
|
+
| **Getting Started** | [Quick start guide](https://heroshot.dev/docs/getting-started) |
|
|
107
|
+
| **Configuration** | [Config options](https://heroshot.dev/docs/config) |
|
|
108
|
+
| **CI/CD Setup** | [Automated updates](https://heroshot.dev/docs/guide/automated-updates) |
|
|
109
|
+
| **CLI Reference** | [All commands & flags](https://heroshot.dev/docs/cli) |
|
|
110
110
|
|
|
111
111
|
## Support the Project
|
|
112
112
|
|
package/dist/cli/cli.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as intro, D as setVerbose, E as outro, O as spinner, S as error, T as note, _ as loadConfig, a as launchBrowser, c as generateSessionKey, d as loadSession, f as saveLocalKey, g as getConfigPath, h as ensureHeroshotDirectory, k as verbose, l as getSessionPath, m as sessionExists, n as snippetAction, o as DEFAULT_VIEWPORT, p as saveSession, r as sync, s as EDITOR_DIR, u as loadLocalKey, v as saveConfig, w as log, x as generateUid, y as VIEWPORT_PRESETS } from "../snippet-
|
|
2
|
+
import { C as intro, D as setVerbose, E as outro, O as spinner, S as error, T as note, _ as loadConfig, a as launchBrowser, c as generateSessionKey, d as loadSession, f as saveLocalKey, g as getConfigPath, h as ensureHeroshotDirectory, k as verbose, l as getSessionPath, m as sessionExists, n as snippetAction, o as DEFAULT_VIEWPORT, p as saveSession, r as sync, s as EDITOR_DIR, u as loadLocalKey, v as saveConfig, w as log, x as generateUid, y as VIEWPORT_PRESETS } from "../snippet-ZcZmuryj.js";
|
|
3
3
|
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
|
|
9
8
|
//#region src/browser/configToScreenshotData.ts
|
|
10
9
|
/**
|
|
11
10
|
* Convert config screenshots to toolbar ScreenshotData format.
|
|
@@ -31,7 +30,6 @@ function configToScreenshotData(screenshots) {
|
|
|
31
30
|
...screenshot.borderRadius && { borderRadius: screenshot.borderRadius }
|
|
32
31
|
}));
|
|
33
32
|
}
|
|
34
|
-
|
|
35
33
|
//#endregion
|
|
36
34
|
//#region src/browser/pageScripts.ts
|
|
37
35
|
/**
|
|
@@ -64,7 +62,6 @@ function dispatchHighlightJob(options) {
|
|
|
64
62
|
screenshotId: options.screenshotId
|
|
65
63
|
} }));
|
|
66
64
|
}
|
|
67
|
-
|
|
68
65
|
//#endregion
|
|
69
66
|
//#region src/browser/toConfigScreenshot.ts
|
|
70
67
|
/**
|
|
@@ -95,7 +92,6 @@ function toConfigScreenshot(data) {
|
|
|
95
92
|
...data.borderRadius && { borderRadius: data.borderRadius }
|
|
96
93
|
};
|
|
97
94
|
}
|
|
98
|
-
|
|
99
95
|
//#endregion
|
|
100
96
|
//#region src/browser/saveCurrentConfig.ts
|
|
101
97
|
/**
|
|
@@ -123,7 +119,6 @@ function saveCurrentConfig(configPath, allScreenshots, browserSettings, hiddenEl
|
|
|
123
119
|
saveConfig(configPath, config);
|
|
124
120
|
verbose("Config saved");
|
|
125
121
|
}
|
|
126
|
-
|
|
127
122
|
//#endregion
|
|
128
123
|
//#region src/browser/handleEvent.ts
|
|
129
124
|
function createEventHandler(state, browser, context) {
|
|
@@ -209,7 +204,6 @@ function createEventHandler(state, browser, context) {
|
|
|
209
204
|
}
|
|
210
205
|
};
|
|
211
206
|
}
|
|
212
|
-
|
|
213
207
|
//#endregion
|
|
214
208
|
//#region src/browser/schema.ts
|
|
215
209
|
/**
|
|
@@ -301,7 +295,6 @@ const toolbarEventSchema = z.discriminatedUnion("type", [
|
|
|
301
295
|
z.object({ type: z.literal("job-complete") }),
|
|
302
296
|
z.object({ type: z.literal("done") })
|
|
303
297
|
]);
|
|
304
|
-
|
|
305
298
|
//#endregion
|
|
306
299
|
//#region src/browser/injectToolbar.ts
|
|
307
300
|
/**
|
|
@@ -393,7 +386,6 @@ async function doInjectToolbar(page, options) {
|
|
|
393
386
|
document.body.appendChild(script);
|
|
394
387
|
})(${JSON.stringify(screenshots)}, ${JSON.stringify(settings)}, ${JSON.stringify(pendingJob)}, ${JSON.stringify(selectedId)}, ${JSON.stringify(sidebarExpanded)}, ${JSON.stringify(hiddenElements)}, ${JSON.stringify(scriptContent)})`);
|
|
395
388
|
}
|
|
396
|
-
|
|
397
389
|
//#endregion
|
|
398
390
|
//#region src/browser/browser.ts
|
|
399
391
|
async function setup(options = {}) {
|
|
@@ -478,7 +470,7 @@ async function setup(options = {}) {
|
|
|
478
470
|
context.on("page", initPage);
|
|
479
471
|
const page = context.pages()[0] ?? await context.newPage();
|
|
480
472
|
initPage(page);
|
|
481
|
-
await page.goto("https://heroshot.
|
|
473
|
+
await page.goto("https://heroshot.dev/welcome", { waitUntil: "domcontentloaded" });
|
|
482
474
|
try {
|
|
483
475
|
await injectToolbar(page, injectOptions());
|
|
484
476
|
verbose("Toolbar injected on welcome page");
|
|
@@ -491,7 +483,6 @@ async function setup(options = {}) {
|
|
|
491
483
|
if (isNewKey) note("To print your session key:\n npx heroshot session-key\n\nFor CI, add HEROSHOT_SESSION_KEY as a repository secret.", "Session encrypted");
|
|
492
484
|
return { hasScreenshots: allScreenshots.length > 0 };
|
|
493
485
|
}
|
|
494
|
-
|
|
495
486
|
//#endregion
|
|
496
487
|
//#region src/cli/generateScreenshotFilename.ts
|
|
497
488
|
/**
|
|
@@ -511,7 +502,6 @@ function generateScreenshotFilename(url, selector) {
|
|
|
511
502
|
return "screenshot.png";
|
|
512
503
|
}
|
|
513
504
|
}
|
|
514
|
-
|
|
515
505
|
//#endregion
|
|
516
506
|
//#region src/cli/buildScreenshotEntry.ts
|
|
517
507
|
/**
|
|
@@ -539,7 +529,6 @@ function buildScreenshotEntry(url, options) {
|
|
|
539
529
|
else if (options?.desktop) screenshot.viewports = ["desktop"];
|
|
540
530
|
return screenshot;
|
|
541
531
|
}
|
|
542
|
-
|
|
543
532
|
//#endregion
|
|
544
533
|
//#region src/cli/optionsParsers.ts
|
|
545
534
|
/**
|
|
@@ -563,6 +552,20 @@ function getDeviceScaleFactor(options, existingConfig) {
|
|
|
563
552
|
return existingConfig?.browser?.deviceScaleFactor;
|
|
564
553
|
}
|
|
565
554
|
/**
|
|
555
|
+
* Build browser settings for a oneshot capture from CLI options,
|
|
556
|
+
* falling back to existing config defaults.
|
|
557
|
+
*/
|
|
558
|
+
function buildBrowserSettings(options, existingConfig) {
|
|
559
|
+
return {
|
|
560
|
+
viewport: getViewport(options, existingConfig),
|
|
561
|
+
colorScheme: getColorScheme(options, false),
|
|
562
|
+
deviceScaleFactor: getDeviceScaleFactor(options, existingConfig),
|
|
563
|
+
reducedMotion: options?.reducedMotion ? "reduce" : existingConfig?.browser?.reducedMotion,
|
|
564
|
+
userAgent: options?.userAgent ?? existingConfig?.browser?.userAgent,
|
|
565
|
+
ignoreHTTPSErrors: options?.ignoreHttpsErrors ?? existingConfig?.browser?.ignoreHTTPSErrors
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
566
569
|
* Get viewport from CLI options.
|
|
567
570
|
* Checks preset flags (mobile/tablet/desktop), custom dimensions, then existing config.
|
|
568
571
|
*/
|
|
@@ -579,7 +582,6 @@ function getViewport(options, existingConfig) {
|
|
|
579
582
|
}
|
|
580
583
|
return existingConfig?.browser?.viewport;
|
|
581
584
|
}
|
|
582
|
-
|
|
583
585
|
//#endregion
|
|
584
586
|
//#region src/cli/buildShotConfig.ts
|
|
585
587
|
/**
|
|
@@ -591,17 +593,10 @@ function buildShotConfig(url, options, existingConfig) {
|
|
|
591
593
|
outputDirectory: ".",
|
|
592
594
|
outputFormat: options?.quality ? "jpeg" : existingConfig?.outputFormat ?? "png",
|
|
593
595
|
jpegQuality: options?.quality ?? existingConfig?.jpegQuality ?? 80,
|
|
594
|
-
browser:
|
|
595
|
-
viewport: getViewport(options, existingConfig),
|
|
596
|
-
colorScheme: getColorScheme(options, false),
|
|
597
|
-
deviceScaleFactor: getDeviceScaleFactor(options, existingConfig),
|
|
598
|
-
reducedMotion: options?.reducedMotion ? "reduce" : existingConfig?.browser?.reducedMotion,
|
|
599
|
-
userAgent: options?.userAgent ?? existingConfig?.browser?.userAgent
|
|
600
|
-
},
|
|
596
|
+
browser: buildBrowserSettings(options, existingConfig),
|
|
601
597
|
screenshots: [screenshot]
|
|
602
598
|
};
|
|
603
599
|
}
|
|
604
|
-
|
|
605
600
|
//#endregion
|
|
606
601
|
//#region src/cli/handlers.ts
|
|
607
602
|
/**
|
|
@@ -725,7 +720,6 @@ function sessionKeyAction() {
|
|
|
725
720
|
error("No session key found. Run \"heroshot config\" first to generate one.");
|
|
726
721
|
return false;
|
|
727
722
|
}
|
|
728
|
-
|
|
729
723
|
//#endregion
|
|
730
724
|
//#region src/cli/list.ts
|
|
731
725
|
/**
|
|
@@ -763,7 +757,6 @@ function listAction(options, globalOptions) {
|
|
|
763
757
|
}
|
|
764
758
|
return true;
|
|
765
759
|
}
|
|
766
|
-
|
|
767
760
|
//#endregion
|
|
768
761
|
//#region src/cli/cli.ts
|
|
769
762
|
function getVersion() {
|
|
@@ -777,11 +770,12 @@ function getVersion() {
|
|
|
777
770
|
}
|
|
778
771
|
const version = getVersion();
|
|
779
772
|
const program = new Command();
|
|
780
|
-
program.name("heroshot").description("Define your screenshots once, update them forever with one command").version(version).option("-v, --verbose", "Show detailed output").option("-c, --config <path>", "Path to config file").option("-s, --session-key <key>", "Session key for encrypted auth (or set HEROSHOT_SESSION_KEY)").hook("preAction", () => {
|
|
773
|
+
program.name("heroshot").description("Define your screenshots once, update them forever with one command").version(version).option("-v, --verbose", "Show detailed output").option("-c, --config <path>", "Path to config file").option("-s, --session-key <key>", "Session key for encrypted auth (or set HEROSHOT_SESSION_KEY)").hook("preAction", (_thisCommand, actionCommand) => {
|
|
781
774
|
setVerbose(program.opts().verbose ?? false);
|
|
775
|
+
if (actionCommand.name() === "mcp") return;
|
|
782
776
|
intro(version);
|
|
783
777
|
});
|
|
784
|
-
program.command("oneshot [url]", { isDefault: true }).description("Capture URL directly, or sync all screenshots from config").option("--selector <selector...>", "CSS selector(s) to capture").option("-o, --output <file>", "Output filename").option("-p, --padding <pixels>", "Padding around element", Number.parseInt).option("-w, --width <pixels>", "Viewport width", Number.parseInt).option("--height <pixels>", "Viewport height", Number.parseInt).option("--mobile", "Use mobile viewport (430x932)").option("--tablet", "Use tablet viewport (768x1024)").option("--desktop", "Use desktop viewport (1280x800)").option("--dark", "Force dark color scheme").option("--light", "Force light color scheme").option("--scale <factor>", "Device scale factor (1, 2, 3)", Number.parseInt).option("--retina", "Use retina scale (2x)").option("-q, --quality <percent>", "JPEG quality (1-100), outputs JPEG", Number.parseInt).option("--viewport-only", "Capture only viewport (not full page)").option("--reduced-motion", "Emulate prefers-reduced-motion: reduce (disables animations)").option("--user-agent <string>", "Custom user agent string").option("--save", "Save screenshot definition to config").option("--clean", "Delete stale files in output directory").option("--workers <count>", "Number of parallel capture workers", Number.parseInt).option("--headed", "Run browser in headed mode (visible window) for debugging").action(async (url, options) => {
|
|
778
|
+
program.command("oneshot [url]", { isDefault: true }).description("Capture URL directly, or sync all screenshots from config").option("--selector <selector...>", "CSS selector(s) to capture").option("-o, --output <file>", "Output filename").option("-p, --padding <pixels>", "Padding around element", Number.parseInt).option("-w, --width <pixels>", "Viewport width", Number.parseInt).option("--height <pixels>", "Viewport height", Number.parseInt).option("--mobile", "Use mobile viewport (430x932)").option("--tablet", "Use tablet viewport (768x1024)").option("--desktop", "Use desktop viewport (1280x800)").option("--dark", "Force dark color scheme").option("--light", "Force light color scheme").option("--scale <factor>", "Device scale factor (1, 2, 3)", Number.parseInt).option("--retina", "Use retina scale (2x)").option("-q, --quality <percent>", "JPEG quality (1-100), outputs JPEG", Number.parseInt).option("--viewport-only", "Capture only viewport (not full page)").option("--reduced-motion", "Emulate prefers-reduced-motion: reduce (disables animations)").option("--user-agent <string>", "Custom user agent string").option("--ignore-https-errors", "Ignore TLS certificate errors (self-signed certs, dev only)").option("--save", "Save screenshot definition to config").option("--clean", "Delete stale files in output directory").option("--workers <count>", "Number of parallel capture workers", Number.parseInt).option("--headed", "Run browser in headed mode (visible window) for debugging").action(async (url, options) => {
|
|
785
779
|
if (!await shotAction(url, options, program.opts())) process.exitCode = 1;
|
|
786
780
|
});
|
|
787
781
|
program.command("config").description("Open browser to add/edit screenshot definitions").option("--reset", "Clear existing session and start fresh").option("--only", "Only run config, skip sync afterwards").option("--light", "Force light mode (prefers-color-scheme: light)").option("--dark", "Force dark mode (prefers-color-scheme: dark)").action(async (options) => {
|
|
@@ -794,10 +788,13 @@ program.command("snippet [pattern]").description("Generate markdown/HTML snippet
|
|
|
794
788
|
const globalOptions = program.opts();
|
|
795
789
|
if (!snippetAction(pattern, options ?? {}, globalOptions.config)) process.exitCode = 1;
|
|
796
790
|
});
|
|
791
|
+
program.command("mcp").description("Start the MCP (Model Context Protocol) server over stdio").action(async () => {
|
|
792
|
+
const { startMcpServer } = await import("../server-CqRfIFJa.js");
|
|
793
|
+
await startMcpServer();
|
|
794
|
+
});
|
|
797
795
|
program.command("list").description("List all configured screenshots").option("--json", "Output as JSON").action((options) => {
|
|
798
796
|
if (!listAction(options, program.opts())) process.exitCode = 1;
|
|
799
797
|
});
|
|
800
798
|
program.parse();
|
|
801
|
-
|
|
802
799
|
//#endregion
|
|
803
|
-
export {
|
|
800
|
+
export {};
|