autokap 1.0.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 (93) hide show
  1. package/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
  2. package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
  3. package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
  4. package/assets/devices/ipad-pro-11-m4.json +52 -0
  5. package/assets/devices/iphone-16-pro.json +53 -0
  6. package/assets/devices/macbook-air-13.json +45 -0
  7. package/assets/frames/MacBook Air 13.svg +242 -0
  8. package/assets/frames/Status bar - iPhone.png +0 -0
  9. Menu bar- iPad.png +0 -0
  10. package/assets/frames/iPad Pro M4 11_.png +0 -0
  11. package/assets/frames/iPhone 16 Pro.png +0 -0
  12. package/assets/icons/Cellular Connection.svg +3 -0
  13. package/assets/icons/Union.svg +6 -0
  14. package/assets/icons/Wifi.svg +3 -0
  15. package/assets/icons/battery.svg +5 -0
  16. package/assets/icons/battery_charging.svg +8 -0
  17. package/assets/skill/SKILL.md +575 -0
  18. package/dist/abort.d.ts +5 -0
  19. package/dist/abort.js +44 -0
  20. package/dist/agent.d.ts +142 -0
  21. package/dist/agent.js +4504 -0
  22. package/dist/browser-bar.d.ts +40 -0
  23. package/dist/browser-bar.js +147 -0
  24. package/dist/browser-pool.d.ts +34 -0
  25. package/dist/browser-pool.js +122 -0
  26. package/dist/browser.d.ts +279 -0
  27. package/dist/browser.js +2902 -0
  28. package/dist/cli-utils.d.ts +25 -0
  29. package/dist/cli-utils.js +80 -0
  30. package/dist/cli.d.ts +4 -0
  31. package/dist/cli.js +365 -0
  32. package/dist/clip-orchestrator.d.ts +148 -0
  33. package/dist/clip-orchestrator.js +950 -0
  34. package/dist/clip-postprocess.d.ts +42 -0
  35. package/dist/clip-postprocess.js +192 -0
  36. package/dist/cookie-dismiss.d.ts +5 -0
  37. package/dist/cookie-dismiss.js +172 -0
  38. package/dist/credential-templates.d.ts +5 -0
  39. package/dist/credential-templates.js +60 -0
  40. package/dist/element-capture.d.ts +53 -0
  41. package/dist/element-capture.js +766 -0
  42. package/dist/hybrid-navigator.d.ts +138 -0
  43. package/dist/hybrid-navigator.js +468 -0
  44. package/dist/index.d.ts +15 -0
  45. package/dist/index.js +11 -0
  46. package/dist/llm-usage.d.ts +17 -0
  47. package/dist/llm-usage.js +45 -0
  48. package/dist/logger.d.ts +46 -0
  49. package/dist/logger.js +79 -0
  50. package/dist/mockup-html.d.ts +119 -0
  51. package/dist/mockup-html.js +253 -0
  52. package/dist/mockup.d.ts +94 -0
  53. package/dist/mockup.js +604 -0
  54. package/dist/mouse-animation.d.ts +46 -0
  55. package/dist/mouse-animation.js +100 -0
  56. package/dist/overlay-utils.d.ts +14 -0
  57. package/dist/overlay-utils.js +13 -0
  58. package/dist/posthog.d.ts +4 -0
  59. package/dist/posthog.js +26 -0
  60. package/dist/prompt-cache.d.ts +10 -0
  61. package/dist/prompt-cache.js +24 -0
  62. package/dist/prompts.d.ts +167 -0
  63. package/dist/prompts.js +1165 -0
  64. package/dist/security.d.ts +20 -0
  65. package/dist/security.js +569 -0
  66. package/dist/session-profile.d.ts +86 -0
  67. package/dist/session-profile.js +1471 -0
  68. package/dist/sf-pro-fonts.d.ts +4 -0
  69. package/dist/sf-pro-fonts.js +7 -0
  70. package/dist/status-bar-l10n.d.ts +14 -0
  71. package/dist/status-bar-l10n.js +177 -0
  72. package/dist/status-bar.d.ts +44 -0
  73. package/dist/status-bar.js +336 -0
  74. package/dist/tools.d.ts +4 -0
  75. package/dist/tools.js +578 -0
  76. package/dist/types.d.ts +796 -0
  77. package/dist/types.js +2 -0
  78. package/dist/video-agent.d.ts +143 -0
  79. package/dist/video-agent.js +4783 -0
  80. package/dist/video-observation.d.ts +36 -0
  81. package/dist/video-observation.js +192 -0
  82. package/dist/video-planner.d.ts +12 -0
  83. package/dist/video-planner.js +500 -0
  84. package/dist/video-prompts.d.ts +37 -0
  85. package/dist/video-prompts.js +554 -0
  86. package/dist/video-tools.d.ts +3 -0
  87. package/dist/video-tools.js +59 -0
  88. package/dist/video-variant-state.d.ts +29 -0
  89. package/dist/video-variant-state.js +80 -0
  90. package/dist/vision-model.d.ts +17 -0
  91. package/dist/vision-model.js +74 -0
  92. package/package.json +165 -0
  93. package/readme.md +61 -0
@@ -0,0 +1,80 @@
1
+ import { evaluateRequestedLanguageState, evaluateRequestedThemeState as evaluateRequestedThemeStateRich, } from './session-profile.js';
2
+ function normalizeConfidenceScore(confidence) {
3
+ switch (confidence) {
4
+ case 'high':
5
+ return 1;
6
+ case 'medium':
7
+ return 0.78;
8
+ case 'low':
9
+ default:
10
+ return 0.58;
11
+ }
12
+ }
13
+ export function scoreLocaleSignals(signals, requestedLang) {
14
+ if (!requestedLang)
15
+ return { score: 1, reasons: [], ambiguous: false };
16
+ const languageState = evaluateRequestedLanguageState({
17
+ currentUrl: signals.url,
18
+ requestedLang,
19
+ signals,
20
+ });
21
+ if (languageState.active) {
22
+ return {
23
+ score: normalizeConfidenceScore(languageState.confidence),
24
+ reasons: languageState.reasons,
25
+ ambiguous: false,
26
+ };
27
+ }
28
+ if (languageState.ambiguous) {
29
+ return {
30
+ score: languageState.confidence === 'high' ? 0.45 : languageState.confidence === 'medium' ? 0.32 : 0.18,
31
+ reasons: languageState.reasons,
32
+ ambiguous: true,
33
+ };
34
+ }
35
+ return {
36
+ score: 0,
37
+ reasons: languageState.reasons,
38
+ ambiguous: false,
39
+ };
40
+ }
41
+ export function evaluateRequestedThemeState(signals, requestedTheme) {
42
+ const themeState = evaluateRequestedThemeStateRich({
43
+ requestedTheme,
44
+ signals,
45
+ });
46
+ return {
47
+ detected: themeState.detected,
48
+ active: themeState.active,
49
+ ambiguous: themeState.ambiguous,
50
+ reason: themeState.reasons.join('; ') || 'no_theme_signal',
51
+ };
52
+ }
53
+ export async function detectVariantStateDeterministic(browser, requestedLang, requestedTheme) {
54
+ const signals = await browser.capturePageSignals();
55
+ const languageState = evaluateRequestedLanguageState({
56
+ currentUrl: signals.url,
57
+ requestedLang,
58
+ signals,
59
+ });
60
+ const themeState = evaluateRequestedThemeStateRich({
61
+ requestedTheme,
62
+ signals,
63
+ });
64
+ return {
65
+ lang: {
66
+ requested: requestedLang,
67
+ detected: languageState.detected,
68
+ active: requestedLang ? languageState.active : true,
69
+ ambiguous: requestedLang ? languageState.ambiguous : false,
70
+ },
71
+ theme: {
72
+ requested: requestedTheme,
73
+ detected: themeState.detected,
74
+ active: requestedTheme ? themeState.active : true,
75
+ ambiguous: requestedTheme ? themeState.ambiguous : false,
76
+ },
77
+ pageSignals: signals,
78
+ };
79
+ }
80
+ //# sourceMappingURL=video-variant-state.js.map
@@ -0,0 +1,17 @@
1
+ export declare class VisionModelUnsupportedError extends Error {
2
+ requestedModel: string;
3
+ fallbackModel?: string;
4
+ constructor(requestedModel: string, fallbackModel?: string);
5
+ }
6
+ export declare function isImageInputUnsupportedError(err: unknown): boolean;
7
+ export declare function buildVisionModelUnavailableMessage(requestedModel: string, fallbackModel?: string): string;
8
+ export declare function callVisionCapableModel<T>(params: {
9
+ primaryModel: string;
10
+ fallbackModel?: string;
11
+ callModel: (model: string) => Promise<T>;
12
+ onFallbackActivated?: (model: string, reason: string) => void;
13
+ }): Promise<{
14
+ result: T;
15
+ model: string;
16
+ fellBack: boolean;
17
+ }>;
@@ -0,0 +1,74 @@
1
+ export class VisionModelUnsupportedError extends Error {
2
+ requestedModel;
3
+ fallbackModel;
4
+ constructor(requestedModel, fallbackModel) {
5
+ super(buildVisionModelUnavailableMessage(requestedModel, fallbackModel));
6
+ this.name = 'VisionModelUnsupportedError';
7
+ this.requestedModel = requestedModel;
8
+ this.fallbackModel = fallbackModel;
9
+ }
10
+ }
11
+ function extractNestedErrorMessage(err) {
12
+ if (!err || typeof err !== 'object')
13
+ return '';
14
+ const errorRecord = err;
15
+ const directMessage = typeof errorRecord.message === 'string' ? errorRecord.message : '';
16
+ const nestedError = errorRecord.error;
17
+ const nestedMessage = nestedError && typeof nestedError === 'object' && typeof nestedError.message === 'string'
18
+ ? nestedError.message
19
+ : '';
20
+ if (nestedMessage && nestedMessage === directMessage)
21
+ return directMessage;
22
+ return [directMessage, nestedMessage].filter(Boolean).join(' ');
23
+ }
24
+ export function isImageInputUnsupportedError(err) {
25
+ if (!err || typeof err !== 'object')
26
+ return false;
27
+ const errorRecord = err;
28
+ const status = typeof errorRecord.status === 'number' ? errorRecord.status : undefined;
29
+ const message = extractNestedErrorMessage(err).toLowerCase();
30
+ if (!message)
31
+ return false;
32
+ const mentionsImageEndpoint = message.includes('no endpoints found that support image input')
33
+ || message.includes('no providers that support image input')
34
+ || (message.includes('image input') && message.includes('no') && message.includes('support'))
35
+ || (message.includes('image input') && message.includes('endpoint') && message.includes('no'));
36
+ if (!mentionsImageEndpoint)
37
+ return false;
38
+ return status === undefined || status === 400 || status === 404 || status === 422;
39
+ }
40
+ export function buildVisionModelUnavailableMessage(requestedModel, fallbackModel) {
41
+ const fallbackHint = fallbackModel && fallbackModel !== requestedModel
42
+ ? ` Automatic fallback to "${fallbackModel}" also failed or was unavailable.`
43
+ : '';
44
+ return `The model "${requestedModel}" has no available endpoint that supports image input.${fallbackHint} Configure a vision-capable default/fallback model or retry later if the provider is degraded.`;
45
+ }
46
+ export async function callVisionCapableModel(params) {
47
+ const { primaryModel, fallbackModel, callModel, onFallbackActivated } = params;
48
+ let fallbackReason = '';
49
+ try {
50
+ const result = await callModel(primaryModel);
51
+ return { result, model: primaryModel, fellBack: false };
52
+ }
53
+ catch (err) {
54
+ if (!isImageInputUnsupportedError(err)) {
55
+ throw err;
56
+ }
57
+ fallbackReason = extractNestedErrorMessage(err) || 'image input unsupported';
58
+ if (!fallbackModel || fallbackModel === primaryModel) {
59
+ throw new VisionModelUnsupportedError(primaryModel, fallbackModel);
60
+ }
61
+ }
62
+ try {
63
+ const result = await callModel(fallbackModel);
64
+ onFallbackActivated?.(fallbackModel, fallbackReason);
65
+ return { result, model: fallbackModel, fellBack: true };
66
+ }
67
+ catch (fallbackErr) {
68
+ if (isImageInputUnsupportedError(fallbackErr)) {
69
+ throw new VisionModelUnsupportedError(primaryModel, fallbackModel);
70
+ }
71
+ throw fallbackErr;
72
+ }
73
+ }
74
+ //# sourceMappingURL=vision-model.js.map
package/package.json ADDED
@@ -0,0 +1,165 @@
1
+ {
2
+ "name": "autokap",
3
+ "version": "1.0.0",
4
+ "description": "AI-powered CLI tool for capturing clean screenshots of websites",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./browser": {
14
+ "types": "./dist/browser.d.ts",
15
+ "default": "./dist/browser.js"
16
+ },
17
+ "./agent": {
18
+ "types": "./dist/agent.d.ts",
19
+ "default": "./dist/agent.js"
20
+ },
21
+ "./cookie-dismiss": {
22
+ "types": "./dist/cookie-dismiss.d.ts",
23
+ "default": "./dist/cookie-dismiss.js"
24
+ },
25
+ "./logger": {
26
+ "types": "./dist/logger.d.ts",
27
+ "default": "./dist/logger.js"
28
+ },
29
+ "./types": {
30
+ "types": "./dist/types.d.ts",
31
+ "default": "./dist/types.js"
32
+ },
33
+ "./mockup": {
34
+ "types": "./dist/mockup.d.ts",
35
+ "default": "./dist/mockup.js"
36
+ },
37
+ "./mockup-html": {
38
+ "types": "./dist/mockup-html.d.ts",
39
+ "default": "./dist/mockup-html.js"
40
+ },
41
+ "./status-bar": {
42
+ "types": "./dist/status-bar.d.ts",
43
+ "default": "./dist/status-bar.js"
44
+ },
45
+ "./browser-bar": {
46
+ "types": "./dist/browser-bar.d.ts",
47
+ "default": "./dist/browser-bar.js"
48
+ },
49
+ "./status-bar-l10n": {
50
+ "types": "./dist/status-bar-l10n.d.ts",
51
+ "default": "./dist/status-bar-l10n.js"
52
+ },
53
+ "./element-capture": {
54
+ "types": "./dist/element-capture.d.ts",
55
+ "default": "./dist/element-capture.js"
56
+ },
57
+ "./prompts": {
58
+ "types": "./dist/prompts.d.ts",
59
+ "default": "./dist/prompts.js"
60
+ },
61
+ "./session-profile": {
62
+ "types": "./dist/session-profile.d.ts",
63
+ "default": "./dist/session-profile.js"
64
+ },
65
+ "./tools": {
66
+ "types": "./dist/tools.d.ts",
67
+ "default": "./dist/tools.js"
68
+ },
69
+ "./security": {
70
+ "types": "./dist/security.d.ts",
71
+ "default": "./dist/security.js"
72
+ },
73
+ "./video-agent": {
74
+ "types": "./dist/video-agent.d.ts",
75
+ "default": "./dist/video-agent.js"
76
+ },
77
+ "./video-planner": {
78
+ "types": "./dist/video-planner.d.ts",
79
+ "default": "./dist/video-planner.js"
80
+ },
81
+ "./mouse-animation": {
82
+ "types": "./dist/mouse-animation.d.ts",
83
+ "default": "./dist/mouse-animation.js"
84
+ },
85
+ "./clip-orchestrator": {
86
+ "types": "./dist/clip-orchestrator.d.ts",
87
+ "default": "./dist/clip-orchestrator.js"
88
+ },
89
+ "./clip-postprocess": {
90
+ "types": "./dist/clip-postprocess.d.ts",
91
+ "default": "./dist/clip-postprocess.js"
92
+ },
93
+ "./hybrid-navigator": {
94
+ "types": "./dist/hybrid-navigator.d.ts",
95
+ "default": "./dist/hybrid-navigator.js"
96
+ }
97
+ },
98
+ "bin": {
99
+ "autokap": "dist/cli.js"
100
+ },
101
+ "scripts": {
102
+ "postinstall": "node scripts/patch-playwright-video-recorder.mjs",
103
+ "build": "tsc && cd web && npm run build",
104
+ "dev": "cd web && npm run dev",
105
+ "dev:lib:watch": "tsc -w --preserveWatchOutput",
106
+ "start": "cd web && npm run start",
107
+ "rebuild": "tsc && cd web && npx tsc --noEmit",
108
+ "typecheck": "tsc --noEmit",
109
+ "test": "vitest run",
110
+ "test:watch": "vitest",
111
+ "test:billing-limits": "node --test --import tsx scripts/billing-plan-limits.test.ts",
112
+ "deploy": "bash deploy.sh",
113
+ "sync-env": "bash scripts/sync-env.sh",
114
+ "screenshot:benchmark": "tsx scripts/screenshot-benchmark.ts",
115
+ "video:smoke": "tsx scripts/video-smoke-test.ts",
116
+ "video:regression": "tsx scripts/video-regression.ts"
117
+ },
118
+ "engines": {
119
+ "node": ">=20"
120
+ },
121
+ "files": [
122
+ "dist/**/*.js",
123
+ "dist/**/*.d.ts",
124
+ "!dist/**/*.js.map",
125
+ "assets/chrome",
126
+ "assets/devices",
127
+ "assets/frames/iPad*",
128
+ "assets/frames/iPhone*",
129
+ "assets/frames/MacBook*",
130
+ "assets/frames/Status*",
131
+ "assets/icons",
132
+ "assets/skill"
133
+ ],
134
+ "keywords": [
135
+ "screenshot",
136
+ "capture",
137
+ "automation",
138
+ "ai",
139
+ "cli",
140
+ "playwright",
141
+ "mockup",
142
+ "website"
143
+ ],
144
+ "author": "AutoKap",
145
+ "license": "ISC",
146
+ "homepage": "https://app.autokap.com",
147
+ "dependencies": {
148
+ "chalk": "^5.6.2",
149
+ "commander": "^14.0.3",
150
+ "dotenv": "^17.3.1",
151
+ "openai": "^6.25.0",
152
+ "playwright": "^1.58.2",
153
+ "posthog-node": "^5.26.2",
154
+ "sharp": "^0.34.5"
155
+ },
156
+ "devDependencies": {
157
+ "@types/node": "^25.3.3",
158
+ "tsx": "^4.21.0",
159
+ "typescript": "^5.9.3",
160
+ "vitest": "^4.0.18"
161
+ },
162
+ "overrides": {
163
+ "picomatch": ">=4.0.4"
164
+ }
165
+ }
package/readme.md ADDED
@@ -0,0 +1,61 @@
1
+ # AutoKap
2
+
3
+ AI-powered website screenshot capture across every device, language, and theme.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Install dependencies
9
+ cd web && npm install
10
+
11
+ # Set up environment
12
+ cp .env.example .env.local
13
+ # Fill in NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
14
+
15
+ # Run dev server
16
+ npm run dev
17
+ ```
18
+
19
+ ## Auth Setup (Supabase)
20
+
21
+ AutoKap uses Supabase Auth for user authentication. You need to configure the following providers in your Supabase dashboard:
22
+
23
+ ### 1. Email/Password
24
+
25
+ - Go to **Authentication > Providers > Email** in the Supabase dashboard
26
+ - Enable **Email provider**
27
+ - Configure email templates if needed
28
+ - Enable/disable **Confirm email** depending on your needs
29
+
30
+ ### 2. Google OAuth
31
+
32
+ - Go to **Authentication > Providers > Google**
33
+ - Enable the Google provider
34
+ - Create OAuth credentials in the [Google Cloud Console](https://console.cloud.google.com/apis/credentials):
35
+ - Create an OAuth 2.0 Client ID (Web application)
36
+ - Add `https://<your-supabase-project>.supabase.co/auth/v1/callback` as an authorized redirect URI
37
+ - Copy the **Client ID** and **Client Secret** into the Supabase Google provider settings
38
+
39
+ ### 3. GitHub OAuth
40
+
41
+ - Go to **Authentication > Providers > GitHub**
42
+ - Enable the GitHub provider
43
+ - Create an OAuth App in [GitHub Developer Settings](https://github.com/settings/developers):
44
+ - Set the **Authorization callback URL** to `https://<your-supabase-project>.supabase.co/auth/v1/callback`
45
+ - Copy the **Client ID** and **Client Secret** into the Supabase GitHub provider settings
46
+
47
+ ### 4. Database Schema
48
+
49
+ Make sure the `captures` table has a `run_id` UUID column:
50
+
51
+ ```sql
52
+ ALTER TABLE captures ADD COLUMN IF NOT EXISTS run_id UUID;
53
+ CREATE INDEX IF NOT EXISTS idx_captures_run_id ON captures(run_id);
54
+ ```
55
+
56
+ ## Architecture
57
+
58
+ - **Web App**: Next.js 16 (App Router) + Tailwind CSS 4 + shadcn/ui + framer-motion
59
+ - **Backend**: Node.js + Playwright for browser automation + AI agent (OpenRouter)
60
+ - **Database**: Supabase (PostgreSQL + Storage + Auth)
61
+ - **Routes**: `/presets`, `/capture/new`, `/capture/live`, `/gallery`, `/login`