@wasao/kagemusha 0.1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/commands/capture.d.ts +7 -0
  4. package/dist/commands/capture.d.ts.map +1 -0
  5. package/dist/commands/capture.js +27 -0
  6. package/dist/commands/capture.js.map +1 -0
  7. package/dist/commands/init.d.ts +2 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/init.js +269 -0
  10. package/dist/commands/init.js.map +1 -0
  11. package/dist/commands/preview.d.ts +6 -0
  12. package/dist/commands/preview.d.ts.map +1 -0
  13. package/dist/commands/preview.js +33 -0
  14. package/dist/commands/preview.js.map +1 -0
  15. package/dist/commands/run.d.ts +6 -0
  16. package/dist/commands/run.d.ts.map +1 -0
  17. package/dist/commands/run.js +39 -0
  18. package/dist/commands/run.js.map +1 -0
  19. package/dist/commands/validate.d.ts +2 -0
  20. package/dist/commands/validate.d.ts.map +1 -0
  21. package/dist/commands/validate.js +53 -0
  22. package/dist/commands/validate.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +63 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/annotate.d.ts +3 -0
  28. package/dist/lib/annotate.d.ts.map +1 -0
  29. package/dist/lib/annotate.js +102 -0
  30. package/dist/lib/annotate.js.map +1 -0
  31. package/dist/lib/config.d.ts +9 -0
  32. package/dist/lib/config.d.ts.map +1 -0
  33. package/dist/lib/config.js +92 -0
  34. package/dist/lib/config.js.map +1 -0
  35. package/dist/lib/crawl.d.ts +6 -0
  36. package/dist/lib/crawl.d.ts.map +1 -0
  37. package/dist/lib/crawl.js +95 -0
  38. package/dist/lib/crawl.js.map +1 -0
  39. package/dist/lib/screenshot.d.ts +3 -0
  40. package/dist/lib/screenshot.d.ts.map +1 -0
  41. package/dist/lib/screenshot.js +166 -0
  42. package/dist/lib/screenshot.js.map +1 -0
  43. package/dist/lib/upload.d.ts +9 -0
  44. package/dist/lib/upload.d.ts.map +1 -0
  45. package/dist/lib/upload.js +43 -0
  46. package/dist/lib/upload.js.map +1 -0
  47. package/dist/types.d.ts +168 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +2 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hideto Iwasawa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # kagemusha
2
+
3
+ Auto-update help center screenshots when your code changes.
4
+ The shadow warrior for your documentation.
5
+
6
+ ## What it does
7
+
8
+ When you push code, Kagemusha automatically captures screenshots of your app and uploads them to S3. No more manually taking screenshots and updating help articles.
9
+
10
+ - **Auto-discover pages** — Crawls your app to find pages, select which ones to capture
11
+ - **Playwright-powered** — Supports login, click actions, element selection, and full-page capture
12
+ - **Annotations** — Add arrows, rectangles, and labels to screenshots
13
+ - **S3 upload** — Screenshots are uploaded with stable URLs for embedding in help centers
14
+ - **Local mode** — Save screenshots locally for review before uploading
15
+ - **GitHub Actions ready** — Runs on every merge to main
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Install
21
+ npm install -D kagemusha
22
+
23
+ # Interactive setup (generates config, discovers pages, creates workflow)
24
+ npx kagemusha init
25
+
26
+ # Preview screenshots locally
27
+ npx kagemusha preview
28
+
29
+ # Run full pipeline (capture → upload)
30
+ npx kagemusha run
31
+ ```
32
+
33
+ ## How it works
34
+
35
+ 1. `npx kagemusha init` scans your app and lets you pick which pages to screenshot
36
+ 2. Config and definition files are generated in your repo
37
+ 3. On every merge to main, GitHub Actions runs `npx kagemusha run`
38
+ 4. Screenshots are captured and uploaded to S3
39
+ 5. Help center articles reference the S3 URLs — images stay up to date automatically
40
+
41
+ ## Commands
42
+
43
+ | Command | Description |
44
+ |---------|-------------|
45
+ | `kagemusha init` | Interactive setup |
46
+ | `kagemusha run` | Full pipeline: capture + upload |
47
+ | `kagemusha capture` | Capture screenshots only |
48
+ | `kagemusha preview` | Preview in browser |
49
+ | `kagemusha validate` | Validate config files |
50
+ | `kagemusha compare` | VRT diff detection (coming soon) |
51
+ | `kagemusha publish` | Publish to Intercom/Zendesk (coming soon) |
52
+
53
+ ## Config
54
+
55
+ `kagemusha init` generates these files:
56
+
57
+ ```
58
+ kagemusha.config.yaml # App URL, auth, save destination
59
+ .kagemusha/definitions/*.json # One file per screenshot
60
+ ```
61
+
62
+ ### Screenshot definition example
63
+
64
+ ```json
65
+ {
66
+ "id": "dashboard",
67
+ "name": "dashboard",
68
+ "url": "/dashboard",
69
+ "capture": { "mode": "fullPage" },
70
+ "hideElements": [".intercom-launcher"],
71
+ "decorations": [
72
+ {
73
+ "type": "rect",
74
+ "target": { "x": 32, "y": 120, "width": 310, "height": 120 },
75
+ "style": { "color": "#FF0000", "strokeWidth": 2 }
76
+ }
77
+ ]
78
+ }
79
+ ```
80
+
81
+ ## GitHub Actions
82
+
83
+ ```yaml
84
+ name: Kagemusha
85
+ on:
86
+ pull_request:
87
+ types: [closed]
88
+ branches: [main]
89
+
90
+ jobs:
91
+ screenshots:
92
+ if: github.event.pull_request.merged == true
93
+ runs-on: ubuntu-latest
94
+ steps:
95
+ - uses: actions/checkout@v4
96
+ - uses: actions/setup-node@v4
97
+ with:
98
+ node-version: 20
99
+ - run: npm ci
100
+ - run: npx kagemusha run
101
+ env:
102
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
103
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
104
+ ```
105
+
106
+ ## Try it locally
107
+
108
+ ```bash
109
+ cd example
110
+ bun install
111
+ bun run serve # Start sample app
112
+ bunx kagemusha init # Set up kagemusha
113
+ bunx kagemusha preview # See screenshots
114
+ ```
115
+
116
+ ## Roadmap
117
+
118
+ - [x] Screenshot capture with Playwright
119
+ - [x] Annotations (rect, arrow, label)
120
+ - [x] S3 upload
121
+ - [x] Auto-discover pages
122
+ - [ ] Visual regression testing (VRT)
123
+ - [ ] Intercom / Zendesk integration
124
+ - [ ] AI-powered text updates
125
+
126
+ ## License
127
+
128
+ MIT
@@ -0,0 +1,7 @@
1
+ interface CaptureOptions {
2
+ ids?: string;
3
+ all?: boolean;
4
+ }
5
+ export declare function captureCommand(options: CaptureOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC3E"}
@@ -0,0 +1,27 @@
1
+ import chalk from "chalk";
2
+ import { annotateScreenshots } from "../lib/annotate.js";
3
+ import { findProjectRoot, loadConfig, loadDefinitions } from "../lib/config.js";
4
+ import { captureScreenshots } from "../lib/screenshot.js";
5
+ export async function captureCommand(options) {
6
+ console.log(chalk.bold("\n🥷 Kagemusha — Capture screenshots\n"));
7
+ const projectRoot = findProjectRoot();
8
+ const config = loadConfig(projectRoot);
9
+ let definitions = loadDefinitions(projectRoot);
10
+ if (options.ids) {
11
+ const ids = options.ids.split(",").map((s) => s.trim());
12
+ definitions = definitions.filter((d) => ids.includes(d.id));
13
+ }
14
+ if (definitions.length === 0) {
15
+ console.log(chalk.yellow("No screenshot definitions found."));
16
+ return;
17
+ }
18
+ console.log(chalk.blue(`📸 Capturing ${definitions.length} screenshot(s)...`));
19
+ const results = await captureScreenshots(config, definitions, projectRoot);
20
+ console.log(chalk.blue("🎨 Drawing annotations..."));
21
+ await annotateScreenshots(definitions, results, projectRoot);
22
+ console.log(chalk.bold.green(`\n✅ Done! Screenshots saved to screenshots/\n`));
23
+ for (const r of results) {
24
+ console.log(chalk.gray(` ${r.id} → ${r.rawPath}`));
25
+ }
26
+ }
27
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO1D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAElE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC9D,OAAO;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,MAAM,mBAAmB,CAAC,CACjE,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAE3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,MAAM,mBAAmB,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAE7D,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC,CACjE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAwQjD"}
@@ -0,0 +1,269 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import inquirer from "inquirer";
5
+ import { stringify as toYaml } from "yaml";
6
+ import { discoverPages } from "../lib/crawl.js";
7
+ export async function initCommand() {
8
+ console.log(chalk.bold("\n🥷 Kagemusha — Setup\n"));
9
+ const cwd = process.cwd();
10
+ if (fs.existsSync(path.join(cwd, "kagemusha.config.yaml"))) {
11
+ const { overwrite } = await inquirer.prompt({
12
+ type: "confirm",
13
+ name: "overwrite",
14
+ message: "kagemusha.config.yaml already exists. Overwrite?",
15
+ default: false,
16
+ });
17
+ if (!overwrite) {
18
+ console.log(chalk.yellow("Aborted."));
19
+ return;
20
+ }
21
+ }
22
+ // Step 1: Basic config
23
+ const { baseUrl } = await inquirer.prompt({
24
+ type: "input",
25
+ name: "baseUrl",
26
+ message: "Target URL (the app to take screenshots of):",
27
+ default: "http://localhost:3000",
28
+ });
29
+ const { needsAuth } = await inquirer.prompt({
30
+ type: "confirm",
31
+ name: "needsAuth",
32
+ message: "Does the app require login?",
33
+ default: true,
34
+ });
35
+ let loginUrl = "/login";
36
+ let emailSelector = "#email";
37
+ let passwordSelector = "#password";
38
+ let submitSelector = "button[type='submit']";
39
+ if (needsAuth) {
40
+ const authAnswers = await inquirer.prompt([
41
+ {
42
+ type: "input",
43
+ name: "loginUrl",
44
+ message: "Login page path:",
45
+ default: "/login",
46
+ },
47
+ {
48
+ type: "input",
49
+ name: "emailSelector",
50
+ message: "Email input selector:",
51
+ default: "#email",
52
+ },
53
+ {
54
+ type: "input",
55
+ name: "passwordSelector",
56
+ message: "Password input selector:",
57
+ default: "#password",
58
+ },
59
+ {
60
+ type: "input",
61
+ name: "submitSelector",
62
+ message: "Login button selector:",
63
+ default: "button[type='submit']",
64
+ },
65
+ ]);
66
+ loginUrl = authAnswers.loginUrl;
67
+ emailSelector = authAnswers.emailSelector;
68
+ passwordSelector = authAnswers.passwordSelector;
69
+ submitSelector = authAnswers.submitSelector;
70
+ }
71
+ const { destination } = await inquirer.prompt({
72
+ type: "list",
73
+ name: "destination",
74
+ message: "Where to save screenshots?",
75
+ choices: [
76
+ { name: "Local (./screenshots)", value: "local" },
77
+ { name: "S3", value: "s3" },
78
+ ],
79
+ });
80
+ let outputDir = "./screenshots";
81
+ let cdnBucket = "";
82
+ let cdnBaseUrl = "";
83
+ if (destination === "local") {
84
+ const { dir } = await inquirer.prompt({
85
+ type: "input",
86
+ name: "dir",
87
+ message: "Output directory for screenshots:",
88
+ default: "./screenshots",
89
+ });
90
+ outputDir = dir;
91
+ }
92
+ else {
93
+ const s3Answers = await inquirer.prompt([
94
+ {
95
+ type: "input",
96
+ name: "cdnBucket",
97
+ message: "S3 bucket name:",
98
+ default: "kagemusha-screenshots",
99
+ },
100
+ {
101
+ type: "input",
102
+ name: "cdnBaseUrl",
103
+ message: "S3 public URL base:",
104
+ default: "https://kagemusha-screenshots.s3.ap-northeast-1.amazonaws.com",
105
+ },
106
+ ]);
107
+ cdnBucket = s3Answers.cdnBucket;
108
+ cdnBaseUrl = s3Answers.cdnBaseUrl;
109
+ }
110
+ // Build config
111
+ const config = {
112
+ app: { baseUrl },
113
+ screenshot: {
114
+ defaultViewport: { width: 1280, height: 720, deviceScaleFactor: 2 },
115
+ defaultDiffThreshold: 0.5,
116
+ },
117
+ };
118
+ if (destination === "local") {
119
+ config.publish = {
120
+ destination: "local",
121
+ outputDir,
122
+ };
123
+ }
124
+ else {
125
+ config.publish = {
126
+ destination: "s3",
127
+ cdnBucket,
128
+ cdnBaseUrl,
129
+ };
130
+ }
131
+ if (needsAuth) {
132
+ config.auth = {
133
+ loginUrl,
134
+ steps: [
135
+ {
136
+ action: "type",
137
+ selector: emailSelector,
138
+ text: "${KAGEMUSHA_DEMO_EMAIL}",
139
+ },
140
+ {
141
+ action: "type",
142
+ selector: passwordSelector,
143
+ text: "${KAGEMUSHA_DEMO_PASSWORD}",
144
+ },
145
+ { action: "click", selector: submitSelector },
146
+ { action: "waitForNavigation" },
147
+ ],
148
+ };
149
+ }
150
+ // Write config
151
+ fs.writeFileSync(path.join(cwd, "kagemusha.config.yaml"), toYaml(config, { lineWidth: 120 }));
152
+ console.log(chalk.green("\n✓ Created kagemusha.config.yaml"));
153
+ // Step 2: Discover pages and create screenshot definitions
154
+ fs.mkdirSync(path.join(cwd, ".kagemusha/definitions"), { recursive: true });
155
+ console.log(chalk.blue(`\n🔍 Scanning ${baseUrl} for pages...\n`));
156
+ let pages = [];
157
+ try {
158
+ pages = await discoverPages(baseUrl);
159
+ }
160
+ catch {
161
+ console.log(chalk.yellow(" Could not auto-discover pages.\n"));
162
+ }
163
+ let selectedPaths = [];
164
+ if (pages.length > 0) {
165
+ console.log(chalk.green(` Found ${pages.length} page(s)\n`));
166
+ const { selected } = await inquirer.prompt({
167
+ type: "checkbox",
168
+ name: "selected",
169
+ message: "Select pages to capture (space to toggle):",
170
+ choices: pages.map((p) => ({
171
+ name: `${p.path} ${chalk.gray(p.title)}`,
172
+ value: p.path,
173
+ checked: true,
174
+ })),
175
+ });
176
+ selectedPaths = selected;
177
+ }
178
+ else {
179
+ console.log(chalk.yellow(" No pages found. Add them manually.\n"));
180
+ let addMore = true;
181
+ while (addMore) {
182
+ const { manualPath } = await inquirer.prompt({
183
+ type: "input",
184
+ name: "manualPath",
185
+ message: "Page path (e.g. /index.html):",
186
+ });
187
+ selectedPaths.push(manualPath);
188
+ const { more } = await inquirer.prompt({
189
+ type: "confirm",
190
+ name: "more",
191
+ message: "Add another page?",
192
+ default: false,
193
+ });
194
+ addMore = more;
195
+ }
196
+ }
197
+ for (const pagePath of selectedPaths) {
198
+ const id = deriveIdFromPath(pagePath);
199
+ const definition = {
200
+ id,
201
+ name: id,
202
+ url: pagePath,
203
+ capture: { mode: "fullPage" },
204
+ hideElements: [],
205
+ decorations: [],
206
+ };
207
+ const defPath = path.join(cwd, ".kagemusha/definitions", `${id}.json`);
208
+ fs.writeFileSync(defPath, `${JSON.stringify(definition, null, 2)}\n`);
209
+ console.log(chalk.green(` ✓ ${id} → ${defPath}`));
210
+ }
211
+ console.log("");
212
+ // Step 3: GitHub Actions workflow
213
+ const { createWorkflow } = await inquirer.prompt({
214
+ type: "confirm",
215
+ name: "createWorkflow",
216
+ message: "Generate GitHub Actions workflow?",
217
+ default: true,
218
+ });
219
+ if (createWorkflow) {
220
+ const workflowDir = path.join(cwd, ".github/workflows");
221
+ fs.mkdirSync(workflowDir, { recursive: true });
222
+ fs.writeFileSync(path.join(workflowDir, "kagemusha.yml"), generateWorkflowTemplate());
223
+ console.log(chalk.green("✓ Created .github/workflows/kagemusha.yml"));
224
+ }
225
+ console.log(chalk.bold.green("\n✅ Setup complete!\n"));
226
+ console.log(chalk.gray("Next steps:"));
227
+ console.log(chalk.gray(" npx kagemusha preview — Preview screenshots locally"));
228
+ console.log(chalk.gray(" npx kagemusha validate — Validate config files"));
229
+ console.log(chalk.gray(" npx kagemusha run — Run full pipeline\n"));
230
+ }
231
+ function generateWorkflowTemplate() {
232
+ return `name: Kagemusha - Screenshot Update
233
+
234
+ on:
235
+ pull_request:
236
+ types: [closed]
237
+ branches: [main]
238
+ workflow_dispatch:
239
+
240
+ jobs:
241
+ update-screenshots:
242
+ if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
243
+ runs-on: ubuntu-latest
244
+ steps:
245
+ - uses: actions/checkout@v4
246
+ with:
247
+ fetch-depth: 0
248
+ - uses: actions/setup-node@v4
249
+ with:
250
+ node-version: 20
251
+ - run: npm ci
252
+ - run: npx playwright install chromium
253
+
254
+ - run: npx kagemusha run
255
+ env:
256
+ KAGEMUSHA_DEMO_EMAIL: \${{ secrets.KAGEMUSHA_DEMO_EMAIL }}
257
+ KAGEMUSHA_DEMO_PASSWORD: \${{ secrets.KAGEMUSHA_DEMO_PASSWORD }}
258
+ AWS_ACCESS_KEY_ID: \${{ secrets.AWS_ACCESS_KEY_ID }}
259
+ AWS_SECRET_ACCESS_KEY: \${{ secrets.AWS_SECRET_ACCESS_KEY }}
260
+ `;
261
+ }
262
+ function deriveIdFromPath(urlPath) {
263
+ return (urlPath
264
+ .replace(/^\//, "")
265
+ .replace(/\.\w+$/, "")
266
+ .replace(/[/\\]/g, "-")
267
+ .replace(/[^a-zA-Z0-9-]/g, "") || "page");
268
+ }
269
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,WAAW;IAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEpD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAyB;YACnE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,kDAAkD;YAC3D,OAAO,EAAE,KAAK;SACd,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YACtC,OAAO;QACR,CAAC;IACF,CAAC;IAED,uBAAuB;IACvB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAsB;QAC9D,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,8CAA8C;QACvD,OAAO,EAAE,uBAAuB;KAChC,CAAC,CAAC;IAEH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAyB;QACnE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,6BAA6B;QACtC,OAAO,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,IAAI,aAAa,GAAG,QAAQ,CAAC;IAC7B,IAAI,gBAAgB,GAAG,WAAW,CAAC;IACnC,IAAI,cAAc,GAAG,uBAAuB,CAAC;IAE7C,IAAI,SAAS,EAAE,CAAC;QACf,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,MAAM,CAKtC;YACF;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,kBAAkB;gBAC3B,OAAO,EAAE,QAAQ;aACjB;YACD;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,uBAAuB;gBAChC,OAAO,EAAE,QAAQ;aACjB;YACD;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,0BAA0B;gBACnC,OAAO,EAAE,WAAW;aACpB;YACD;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE,wBAAwB;gBACjC,OAAO,EAAE,uBAAuB;aAChC;SACD,CAAC,CAAC;QACH,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;QAChC,aAAa,GAAG,WAAW,CAAC,aAAa,CAAC;QAC1C,gBAAgB,GAAG,WAAW,CAAC,gBAAgB,CAAC;QAChD,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC;IAC7C,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAA0B;QACtE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,4BAA4B;QACrC,OAAO,EAAE;YACR,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,OAAO,EAAE;YACjD,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;SAC3B;KACD,CAAC,CAAC;IAEH,IAAI,SAAS,GAAG,eAAe,CAAC;IAChC,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,UAAU,GAAG,EAAE,CAAC;IAEpB,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAkB;YACtD,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,mCAAmC;YAC5C,OAAO,EAAE,eAAe;SACxB,CAAC,CAAC;QACH,SAAS,GAAG,GAAG,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM,CAGpC;YACF;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,iBAAiB;gBAC1B,OAAO,EAAE,uBAAuB;aAChC;YACD;gBACC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EACN,+DAA+D;aAChE;SACD,CAAC,CAAC;QACH,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;QAChC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC;IACnC,CAAC;IAED,eAAe;IACf,MAAM,MAAM,GAA4B;QACvC,GAAG,EAAE,EAAE,OAAO,EAAE;QAChB,UAAU,EAAE;YACX,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC,EAAE;YACnE,oBAAoB,EAAE,GAAG;SACzB;KACD,CAAC;IAEF,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,OAAO,GAAG;YAChB,WAAW,EAAE,OAAO;YACpB,SAAS;SACT,CAAC;IACH,CAAC;SAAM,CAAC;QACP,MAAM,CAAC,OAAO,GAAG;YAChB,WAAW,EAAE,IAAI;YACjB,SAAS;YACT,UAAU;SACV,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,GAAG;YACb,QAAQ;YACR,KAAK,EAAE;gBACN;oBACC,MAAM,EAAE,MAAM;oBACd,QAAQ,EAAE,aAAa;oBACvB,IAAI,EAAE,yBAAyB;iBAC/B;gBACD;oBACC,MAAM,EAAE,MAAM;oBACd,QAAQ,EAAE,gBAAgB;oBAC1B,IAAI,EAAE,4BAA4B;iBAClC;gBACD,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE;gBAC7C,EAAE,MAAM,EAAE,mBAAmB,EAAE;aAC/B;SACD,CAAC;IACH,CAAC;IAED,eAAe;IACf,EAAE,CAAC,aAAa,CACf,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,EACvC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAClC,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAE9D,2DAA2D;IAC3D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,wBAAwB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,OAAO,iBAAiB,CAAC,CAAC,CAAC;IAEnE,IAAI,KAAK,GAAsC,EAAE,CAAC;IAClD,IAAI,CAAC;QACJ,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,aAAa,GAAa,EAAE,CAAC;IAEjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC;QAE9D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAyB;YAClE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,4CAA4C;YACrD,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;gBACzC,KAAK,EAAE,CAAC,CAAC,IAAI;gBACb,OAAO,EAAE,IAAI;aACb,CAAC,CAAC;SACH,CAAC,CAAC;QACH,aAAa,GAAG,QAAQ,CAAC;IAC1B,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wCAAwC,CAAC,CAAC,CAAC;QAEpE,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,OAAO,OAAO,EAAE,CAAC;YAChB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAyB;gBACpE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,+BAA+B;aACxC,CAAC,CAAC;YACH,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAE/B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAoB;gBACzD,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,mBAAmB;gBAC5B,OAAO,EAAE,KAAK;aACd,CAAC,CAAC;YACH,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;IACF,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG;YAClB,EAAE;YACF,IAAI,EAAE,EAAE;YACR,GAAG,EAAE,QAAQ;YACb,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAC7B,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,EAAE;SACf,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,kCAAkC;IAClC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAC/C;QACC,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,mCAAmC;QAC5C,OAAO,EAAE,IAAI;KACb,CACD,CAAC;IAEF,IAAI,cAAc,EAAE,CAAC;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACxD,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,EAAE,CAAC,aAAa,CACf,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,EACvC,wBAAwB,EAAE,CAC1B,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CACtE,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,wBAAwB;IAChC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BP,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACxC,OAAO,CACN,OAAO;SACL,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,MAAM,CACzC,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface PreviewOptions {
2
+ id?: string;
3
+ }
4
+ export declare function previewCommand(options: PreviewOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC3E"}
@@ -0,0 +1,33 @@
1
+ import chalk from "chalk";
2
+ import { chromium } from "playwright-chromium";
3
+ import { annotateScreenshots } from "../lib/annotate.js";
4
+ import { findProjectRoot, loadConfig, loadDefinitions } from "../lib/config.js";
5
+ import { captureScreenshots } from "../lib/screenshot.js";
6
+ export async function previewCommand(options) {
7
+ console.log(chalk.bold("\n🥷 Kagemusha — Preview\n"));
8
+ const projectRoot = findProjectRoot();
9
+ const config = loadConfig(projectRoot);
10
+ let definitions = loadDefinitions(projectRoot);
11
+ if (options.id) {
12
+ definitions = definitions.filter((d) => d.id === options.id);
13
+ if (definitions.length === 0) {
14
+ console.log(chalk.red(`Definition not found: ${options.id}`));
15
+ return;
16
+ }
17
+ }
18
+ console.log(chalk.blue(`📸 Capturing ${definitions.length} screenshot(s)...`));
19
+ const results = await captureScreenshots(config, definitions, projectRoot);
20
+ const annotated = await annotateScreenshots(definitions, results, projectRoot);
21
+ console.log(chalk.green("\n✅ Screenshots captured. Opening preview...\n"));
22
+ // Open annotated screenshots in browser
23
+ const browser = await chromium.launch({ headless: false });
24
+ const context = await browser.newContext();
25
+ for (const result of annotated) {
26
+ const page = await context.newPage();
27
+ await page.goto(`file://${result.annotatedPath}`);
28
+ }
29
+ console.log(chalk.gray("Press Ctrl+C to close preview.\n"));
30
+ // Keep process alive until user closes
31
+ await new Promise(() => { });
32
+ }
33
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO;QACR,CAAC;IACF,CAAC;IAED,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,MAAM,mBAAmB,CAAC,CACjE,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAC1C,WAAW,EACX,OAAO,EACP,WAAW,CACX,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAE3E,wCAAwC;IACxC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAE3C,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAE5D,uCAAuC;IACvC,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface RunOptions {
2
+ ids?: string;
3
+ }
4
+ export declare function runCommand(options: RunOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAMA,UAAU,UAAU;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DnE"}
@@ -0,0 +1,39 @@
1
+ import chalk from "chalk";
2
+ import { annotateScreenshots } from "../lib/annotate.js";
3
+ import { findProjectRoot, loadConfig, loadDefinitions } from "../lib/config.js";
4
+ import { captureScreenshots } from "../lib/screenshot.js";
5
+ import { uploadToS3 } from "../lib/upload.js";
6
+ export async function runCommand(options) {
7
+ console.log(chalk.bold("\n🥷 Kagemusha — Running pipeline\n"));
8
+ const projectRoot = findProjectRoot();
9
+ const config = loadConfig(projectRoot);
10
+ let definitions = loadDefinitions(projectRoot);
11
+ if (options.ids) {
12
+ const ids = options.ids.split(",").map((s) => s.trim());
13
+ definitions = definitions.filter((d) => ids.includes(d.id));
14
+ }
15
+ if (definitions.length === 0) {
16
+ console.log(chalk.yellow("No screenshot definitions to process. Skipping."));
17
+ return;
18
+ }
19
+ console.log(chalk.gray(` Found ${definitions.length} definition(s) to process\n`));
20
+ // Step 1: Capture
21
+ console.log(chalk.blue("📸 Capturing screenshots..."));
22
+ const captureResults = await captureScreenshots(config, definitions, projectRoot);
23
+ console.log(chalk.green(` ✓ Captured ${captureResults.length} screenshot(s)\n`));
24
+ // Step 2: Annotate
25
+ console.log(chalk.blue("🎨 Drawing annotations..."));
26
+ const annotatedResults = await annotateScreenshots(definitions, captureResults, projectRoot);
27
+ console.log(chalk.green(` ✓ Annotated ${annotatedResults.length} screenshot(s)\n`));
28
+ // Step 3: Publish
29
+ if (config.publish?.destination === "s3") {
30
+ console.log(chalk.blue("☁️ Uploading to S3..."));
31
+ const uploadResults = await uploadToS3(config, annotatedResults, projectRoot);
32
+ console.log(chalk.green(` ✓ Uploaded ${uploadResults.length} screenshot(s)\n`));
33
+ }
34
+ else {
35
+ console.log(chalk.green(` Screenshots saved locally\n`));
36
+ }
37
+ console.log(chalk.bold.green("✅ Pipeline complete!\n"));
38
+ }
39
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAM9C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAmB;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,MAAM,CAAC,iDAAiD,CAAC,CAC/D,CAAC;QACF,OAAO;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,CAAC,MAAM,6BAA6B,CAAC,CACtE,CAAC;IAEF,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAC9C,MAAM,EACN,WAAW,EACX,WAAW,CACX,CAAC;IACF,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,KAAK,CAAC,gBAAgB,cAAc,CAAC,MAAM,kBAAkB,CAAC,CACpE,CAAC;IAEF,mBAAmB;IACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CACjD,WAAW,EACX,cAAc,EACd,WAAW,CACX,CAAC;IACF,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,KAAK,CAAC,iBAAiB,gBAAgB,CAAC,MAAM,kBAAkB,CAAC,CACvE,CAAC;IAEF,kBAAkB;IAClB,IAAI,MAAM,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,MAAM,UAAU,CACrC,MAAM,EACN,gBAAgB,EAChB,WAAW,CACX,CAAC;QACF,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,KAAK,CAAC,gBAAgB,aAAa,CAAC,MAAM,kBAAkB,CAAC,CACnE,CAAC;IACH,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function validateCommand(): Promise<void>;
2
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AASA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDrD"}
@@ -0,0 +1,53 @@
1
+ import chalk from "chalk";
2
+ import { findProjectRoot, loadConfig, loadDefinitions, validateConfig, validateDefinition, } from "../lib/config.js";
3
+ export async function validateCommand() {
4
+ console.log(chalk.bold("\n🥷 Kagemusha — Validate\n"));
5
+ let hasErrors = false;
6
+ try {
7
+ const projectRoot = findProjectRoot();
8
+ // Validate config
9
+ console.log(chalk.blue("Checking kagemusha.config.yaml..."));
10
+ const config = loadConfig(projectRoot);
11
+ const configErrors = validateConfig(config);
12
+ if (configErrors.length > 0) {
13
+ hasErrors = true;
14
+ for (const err of configErrors) {
15
+ console.log(chalk.red(` ✗ ${err}`));
16
+ }
17
+ }
18
+ else {
19
+ console.log(chalk.green(" ✓ Config is valid"));
20
+ }
21
+ // Validate definitions
22
+ const definitions = loadDefinitions(projectRoot);
23
+ console.log(chalk.blue(`\nChecking ${definitions.length} definition(s)...`));
24
+ for (const def of definitions) {
25
+ const errors = validateDefinition(def);
26
+ if (errors.length > 0) {
27
+ hasErrors = true;
28
+ console.log(chalk.red(` ✗ ${def.id ?? "(no id)"}`));
29
+ for (const err of errors) {
30
+ console.log(chalk.red(` - ${err}`));
31
+ }
32
+ }
33
+ else {
34
+ console.log(chalk.green(` ✓ ${def.id}`));
35
+ }
36
+ }
37
+ if (definitions.length === 0) {
38
+ console.log(chalk.yellow(" No definitions found in .kagemusha/definitions/"));
39
+ }
40
+ }
41
+ catch (err) {
42
+ hasErrors = true;
43
+ console.log(chalk.red(`\n✗ ${err.message}`));
44
+ }
45
+ if (hasErrors) {
46
+ console.log(chalk.red("\n❌ Validation failed\n"));
47
+ process.exit(1);
48
+ }
49
+ else {
50
+ console.log(chalk.bold.green("\n✅ All checks passed!\n"));
51
+ }
52
+ }
53
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACN,eAAe,EACf,UAAU,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,eAAe;IACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAEvD,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;QAEtC,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,SAAS,GAAG,IAAI,CAAC;YACjB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,uBAAuB;QACvB,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,MAAM,mBAAmB,CAAC,CAC/D,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,SAAS,GAAG,IAAI,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC;gBACrD,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC;gBACxC,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,MAAM,CAAC,mDAAmD,CAAC,CACjE,CAAC;QACH,CAAC;IACF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,SAAS,GAAG,IAAI,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAQ,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC3D,CAAC;AACF,CAAC"}