reverse-api-engineer 0.3.2__tar.gz → 0.4.0__tar.gz
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.
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/.claude/settings.local.json +22 -1
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/.gitignore +2 -1
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/CHANGELOG.md +31 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/CLAUDE.md +4 -4
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/PKG-INFO +16 -14
- reverse_api_engineer-0.4.0/PROMPT_STASH.md +8 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/README.md +13 -13
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/shared/storage.ts +1 -1
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/sidepanel/side-panel.tsx +1 -1
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/pyproject.toml +27 -1
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/auto_engineer.py +177 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/base_engineer.py +137 -14
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/browser.py +5 -5
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/cli.py +196 -21
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/config.py +5 -4
- reverse_api_engineer-0.4.0/src/reverse_api/copilot_engineer.py +187 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/engineer.py +24 -118
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/native_host.py +5 -2
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/opencode_engineer.py +3 -3
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/pricing.py +39 -18
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/sync.py +53 -36
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/tui.py +25 -10
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/utils.py +1 -1
- reverse_api_engineer-0.4.0/tests/__init__.py +1 -0
- reverse_api_engineer-0.4.0/tests/conftest.py +68 -0
- reverse_api_engineer-0.4.0/tests/test_action_recorder.py +243 -0
- reverse_api_engineer-0.4.0/tests/test_auto_engineer.py +1035 -0
- reverse_api_engineer-0.4.0/tests/test_base_engineer.py +300 -0
- reverse_api_engineer-0.4.0/tests/test_collector.py +734 -0
- reverse_api_engineer-0.4.0/tests/test_collector_ui.py +180 -0
- reverse_api_engineer-0.4.0/tests/test_config.py +178 -0
- reverse_api_engineer-0.4.0/tests/test_engineer.py +549 -0
- reverse_api_engineer-0.4.0/tests/test_init.py +34 -0
- reverse_api_engineer-0.4.0/tests/test_messages.py +204 -0
- reverse_api_engineer-0.4.0/tests/test_native_host.py +781 -0
- reverse_api_engineer-0.4.0/tests/test_opencode_engineer.py +1471 -0
- reverse_api_engineer-0.4.0/tests/test_opencode_ui.py +477 -0
- reverse_api_engineer-0.4.0/tests/test_pricing.py +291 -0
- reverse_api_engineer-0.4.0/tests/test_session.py +186 -0
- reverse_api_engineer-0.4.0/tests/test_sync.py +372 -0
- reverse_api_engineer-0.4.0/tests/test_tui.py +332 -0
- reverse_api_engineer-0.4.0/tests/test_utils.py +895 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/uv.lock +260 -2
- reverse_api_engineer-0.3.2/TEST_UI_README.md +0 -194
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/.claude-plugin/marketplace.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/.python-version +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/CONTRIBUTING.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/INTERVIEW.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/LICENSE +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/RELEASING.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/assets/reverse-api-banner.svg +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/assets/reverse-api-engineer.gif +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/assets/reverse-api-logo.svg +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/.claude/settings.local.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/package-lock.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/package.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/postcss.config.js +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/_locales/en/messages.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/icons/icon-128.png +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/icons/icon-16.png +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/icons/icon-32.png +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/icons/icon-48.png +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/public/manifest.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/background/service-worker.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/components/agent-action.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/components/chat-input.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/components/markdown-renderer.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/components/plan.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/components/terminal.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/index.css +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/shared/capture.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/shared/native-host.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/shared/types.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/sidepanel/index.html +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/sidepanel/main.tsx +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/src/vite-env.d.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/tailwind.config.js +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/tsconfig.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/chrome-extension/vite.config.ts +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/INDEX.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/QUICKSTART.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/SUMMARY.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/extract_job_fields.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/main.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/quick_example.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/apple/requirements.txt +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/API_SUMMARY.txt +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/QUICKSTART.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/example_usage.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ashby/requirements.txt +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/autoscout24/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/autoscout24/SUMMARY.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/autoscout24/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ikea/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/ikea/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/API_ANALYSIS_SUMMARY.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/example_fetch_all_jobs.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/quick_start.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/examples/uber/requirements.txt +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/llm-docs/OPENCODE_API_SUMMARY.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/llm-docs/claude-agent-sdk/QUICKSTART.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/llm-docs/claude-agent-sdk/TODO_LIST.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/llm-docs/claude-agent-sdk/TOOLS.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/llm-docs/opencode-api.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/.claude-plugin/plugin.json +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/CHANGELOG.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/LICENSE +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/README.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/agents/api-reverse-engineer.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/commands/agent.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/commands/capture.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/commands/engineer.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/commands/manual.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/CHANGELOG.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/LICENSE +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/SKILL.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/references/AUTH_PATTERNS.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/references/HAR_ANALYSIS.md +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_analyze.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_filter.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_utils.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_validate.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/plugins/reverse-api-engineer/skills/reverse-engineering-api/templates/api_client.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/scripts/clean_build.sh +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/__init__.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/action_recorder.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/collector.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/collector_ui.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/messages.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/opencode_ui.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/playwright_codegen.py +0 -0
- {reverse_api_engineer-0.3.2 → reverse_api_engineer-0.4.0}/src/reverse_api/session.py +0 -0
|
@@ -82,7 +82,28 @@
|
|
|
82
82
|
"Bash(uv run:*)",
|
|
83
83
|
"Bash(/Users/kalilbouzigues/.reverse-api/native-host.py:*)",
|
|
84
84
|
"Bash(timeout 2 /Users/kalilbouzigues/.reverse-api/native-host.py:*)",
|
|
85
|
-
"Bash(./diagnose.sh)"
|
|
85
|
+
"Bash(./diagnose.sh)",
|
|
86
|
+
"Skill(remotion-best-practices)",
|
|
87
|
+
"Bash(npx create-video@latest video-promo --template blank)",
|
|
88
|
+
"Bash(npx:*)",
|
|
89
|
+
"Bash(npm install:*)",
|
|
90
|
+
"Bash(npm init:*)",
|
|
91
|
+
"Bash(npm run build:*)",
|
|
92
|
+
"Bash(npm ls:*)",
|
|
93
|
+
"Bash(node -e:*)",
|
|
94
|
+
"Bash(npm search:*)",
|
|
95
|
+
"Bash(npm show:*)",
|
|
96
|
+
"WebFetch(domain:docs.browserbase.com)",
|
|
97
|
+
"WebFetch(domain:sprites.dev)",
|
|
98
|
+
"Bash(npm run:*)",
|
|
99
|
+
"WebFetch(domain:docs.sprites.dev)",
|
|
100
|
+
"Bash(git status:*)",
|
|
101
|
+
"Bash(git branch:*)",
|
|
102
|
+
"Bash(gh api:*)",
|
|
103
|
+
"Bash(gh pr:*)",
|
|
104
|
+
"Bash(python3.11 -c \"import ast; ast.parse\\(open\\('src/reverse_api/base_engineer.py'\\).read\\(\\)\\)\" 2>&1 || echo \"SYNTAX ERROR\")",
|
|
105
|
+
"Bash(python3.11 -c \"import ast; ast.parse\\(open\\('src/reverse_api/base_engineer.py'\\).read\\(\\)\\)\" 2>&1 && echo \"OK\")",
|
|
106
|
+
"Bash(rm -rf dist/ && uv build)"
|
|
86
107
|
]
|
|
87
108
|
}
|
|
88
109
|
}
|
|
@@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] - 2026-03-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`list` CLI subcommand**: Non-interactive command to list generated scripts and runs
|
|
12
|
+
- Rich table output (compact and full modes) and JSON output (`--json`)
|
|
13
|
+
- Filter by mode (`--mode`), model (`--model`), prompt search (`--search`), and limit (`--limit`)
|
|
14
|
+
- Shows script directory paths, file counts, and local path detection
|
|
15
|
+
|
|
16
|
+
## [0.3.3] - 2026-03-10
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **GitHub Copilot SDK**: Third SDK option for reverse engineering using GitHub Copilot
|
|
20
|
+
- New `CopilotEngineer` for HAR analysis via Copilot subscription (cost: $0)
|
|
21
|
+
- Auto mode support with MCP browser integration via Copilot SDK
|
|
22
|
+
- Interactive `AskUserQuestion` tool support for Copilot sessions
|
|
23
|
+
- Permission handler and tool use hooks for agent visibility
|
|
24
|
+
- Install with: `pip install 'reverse-api-engineer[copilot]'`
|
|
25
|
+
- **Comprehensive Test Suite**: 593 tests achieving 97.4% code coverage
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **Claude Model Updates**: Updated from Claude 4.5 to Claude 4.6 (Opus and Sonnet)
|
|
29
|
+
- **Sync Filtering**: Unified sync filtering logic with relative paths; excludes `node_modules`
|
|
30
|
+
- **TUI Improvements**: Reduced thinking truncation for better agent visibility
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- **Python 3.11 Compatibility**: Fixed multi-line f-string expressions that required Python 3.12+
|
|
34
|
+
- **Thread Safety**: Used `loop.call_soon_threadsafe` for Copilot SDK event callbacks
|
|
35
|
+
- **Session Timeouts**: Added 10-minute timeout protection for Copilot session completion
|
|
36
|
+
- **Resource Cleanup**: Ensured `CopilotClient` is always stopped via `try/finally`
|
|
37
|
+
- **HAR Recording**: Changed HAR recording content mode to embed and optimized file saving
|
|
38
|
+
|
|
8
39
|
## [0.3.2] - 2026-01-15
|
|
9
40
|
|
|
10
41
|
### Added
|
|
@@ -112,9 +112,9 @@ uv run mypy src # Static analysis
|
|
|
112
112
|
|
|
113
113
|
```json
|
|
114
114
|
{
|
|
115
|
-
"claude_code_model": "claude-sonnet-4-
|
|
115
|
+
"claude_code_model": "claude-sonnet-4-6", // For Claude SDK
|
|
116
116
|
"opencode_provider": "anthropic", // For OpenCode SDK
|
|
117
|
-
"opencode_model": "claude-sonnet-4-
|
|
117
|
+
"opencode_model": "claude-sonnet-4-6", // For OpenCode SDK
|
|
118
118
|
"sdk": "claude", // "claude" or "opencode"
|
|
119
119
|
"agent_provider": "browser-use", // "browser-use" or "stagehand"
|
|
120
120
|
"browser_use_model": "bu-llm", // Browser-use agent model
|
|
@@ -124,7 +124,7 @@ uv run mypy src # Static analysis
|
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
### Model Naming
|
|
127
|
-
- **Claude models**: `claude-sonnet-4-
|
|
127
|
+
- **Claude models**: `claude-sonnet-4-6`, `claude-opus-4-6`, `claude-haiku-4-5`
|
|
128
128
|
- **Gemini models**: `gemini-3-flash`, `gemini-3-pro`, `gemini-3-pro-low`, `gemini-3-pro-high`
|
|
129
129
|
- **Antigravity models** (free tier): Require OpenCode SDK with `opencode_provider: "google"`
|
|
130
130
|
- **Agent models**: Format varies by provider
|
|
@@ -136,7 +136,7 @@ uv run mypy src # Static analysis
|
|
|
136
136
|
### Three-tier fallback for cost calculation:
|
|
137
137
|
1. **Local pricing** (`pricing.py`): Built-in prices for Claude/Gemini models
|
|
138
138
|
2. **LiteLLM pricing** (optional `[pricing]` extra): Extended coverage for 100+ models
|
|
139
|
-
3. **Default pricing**: Falls back to Claude Sonnet 4.
|
|
139
|
+
3. **Default pricing**: Falls back to Claude Sonnet 4.6 pricing
|
|
140
140
|
|
|
141
141
|
Pricing tracks:
|
|
142
142
|
- Input/output tokens
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reverse-api-engineer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A tool to capture browser traffic for API reverse engineering
|
|
5
5
|
Project-URL: Homepage, https://github.com/kalil0321/reverse-api-engineer
|
|
6
6
|
Project-URL: Repository, https://github.com/kalil0321/reverse-api-engineer
|
|
@@ -36,6 +36,8 @@ Requires-Dist: stagehand; extra == 'agent'
|
|
|
36
36
|
Provides-Extra: collector
|
|
37
37
|
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'collector'
|
|
38
38
|
Requires-Dist: markdownify>=0.12.0; extra == 'collector'
|
|
39
|
+
Provides-Extra: copilot
|
|
40
|
+
Requires-Dist: github-copilot-sdk>=0.1.0; extra == 'copilot'
|
|
39
41
|
Provides-Extra: pricing
|
|
40
42
|
Requires-Dist: litellm>=1.0.0; extra == 'pricing'
|
|
41
43
|
Description-Content-Type: text/markdown
|
|
@@ -84,7 +86,7 @@ No more manual reverse engineering—just browse, capture, and get clean API cod
|
|
|
84
86
|
- 🌐 **Browser Automation**: Built on Playwright with stealth mode for realistic browsing
|
|
85
87
|
- 🤖 **Autonomous Agent Mode**: Fully automated browser interaction using AI agents (auto mode with MCP, browser-use, stagehand)
|
|
86
88
|
- 📊 **HAR Recording**: Captures all network traffic in HTTP Archive format
|
|
87
|
-
- 🧠 **AI-Powered Generation**: Uses Claude 4.
|
|
89
|
+
- 🧠 **AI-Powered Generation**: Uses Claude 4.6 to analyze traffic and generate clean Python code
|
|
88
90
|
- 🔍 **Collector Mode**: Data collection with automatic JSON/CSV export
|
|
89
91
|
- 🔌 **Multi-SDK Support**: Native integration with Claude and OpenCode SDKs
|
|
90
92
|
- 💻 **Interactive CLI**: Minimalist terminal interface with mode cycling (Shift+Tab)
|
|
@@ -127,7 +129,7 @@ playwright install chromium
|
|
|
127
129
|
|
|
128
130
|
### Enhanced Pricing Support (Optional)
|
|
129
131
|
|
|
130
|
-
By default, Reverse API Engineer includes pricing data for the most common models (Claude 4.
|
|
132
|
+
By default, Reverse API Engineer includes pricing data for the most common models (Claude 4.6, Gemini 3). For extended model coverage (100+ additional models including OpenAI GPT, Mistral, DeepSeek, and more), install with pricing extras:
|
|
131
133
|
|
|
132
134
|
```bash
|
|
133
135
|
# With uv
|
|
@@ -140,7 +142,7 @@ pip install 'reverse-api-engineer[pricing]'
|
|
|
140
142
|
This enables automatic pricing lookup via [LiteLLM](https://github.com/BerriAI/litellm) for models not in the built-in database. The pricing system uses a 3-tier fallback:
|
|
141
143
|
1. **Local pricing** (highest priority) - Built-in pricing for common models
|
|
142
144
|
2. **LiteLLM pricing** (if installed) - Extended coverage for 100+ models
|
|
143
|
-
3. **Default pricing** (ultimate fallback) - Uses Claude Sonnet 4.
|
|
145
|
+
3. **Default pricing** (ultimate fallback) - Uses Claude Sonnet 4.6 pricing
|
|
144
146
|
|
|
145
147
|
Cost tracking will always work, with or without the pricing extras installed.
|
|
146
148
|
|
|
@@ -233,7 +235,7 @@ Web data collection using Claude Agent SDK:
|
|
|
233
235
|
- `README.md` - Collection metadata and schema documentation
|
|
234
236
|
|
|
235
237
|
**Model Configuration:**
|
|
236
|
-
Collector mode uses the `collector_model` setting (default: `claude-sonnet-4-
|
|
238
|
+
Collector mode uses the `collector_model` setting (default: `claude-sonnet-4-6`). This can be configured in `~/.reverse-api/config.json`.
|
|
237
239
|
|
|
238
240
|
Example workflow:
|
|
239
241
|
```bash
|
|
@@ -287,9 +289,9 @@ Settings stored in `~/.reverse-api/config.json`:
|
|
|
287
289
|
{
|
|
288
290
|
"agent_provider": "auto",
|
|
289
291
|
"browser_use_model": "bu-llm",
|
|
290
|
-
"claude_code_model": "claude-sonnet-4-
|
|
291
|
-
"collector_model": "claude-sonnet-4-
|
|
292
|
-
"opencode_model": "claude-sonnet-4-
|
|
292
|
+
"claude_code_model": "claude-sonnet-4-6",
|
|
293
|
+
"collector_model": "claude-sonnet-4-6",
|
|
294
|
+
"opencode_model": "claude-sonnet-4-6",
|
|
293
295
|
"opencode_provider": "anthropic",
|
|
294
296
|
"output_dir": null,
|
|
295
297
|
"output_language": "python",
|
|
@@ -301,14 +303,14 @@ Settings stored in `~/.reverse-api/config.json`:
|
|
|
301
303
|
|
|
302
304
|
### Model Selection
|
|
303
305
|
|
|
304
|
-
Choose from Claude 4.
|
|
305
|
-
- **Sonnet 4.
|
|
306
|
-
- **Opus 4.
|
|
306
|
+
Choose from Claude 4.6 models for API generation:
|
|
307
|
+
- **Sonnet 4.6** (default): Balanced performance and cost
|
|
308
|
+
- **Opus 4.6**: Maximum capability for complex APIs
|
|
307
309
|
- **Haiku 4.5**: Fastest and most economical
|
|
308
310
|
|
|
309
311
|
Change in `/settings` or via CLI:
|
|
310
312
|
```bash
|
|
311
|
-
reverse-api-engineer manual --model claude-sonnet-4-
|
|
313
|
+
reverse-api-engineer manual --model claude-sonnet-4-6
|
|
312
314
|
```
|
|
313
315
|
|
|
314
316
|
If you use Opencode, look at the [models](https://models.dev).
|
|
@@ -331,9 +333,9 @@ Configure AI agents for autonomous browser automation.
|
|
|
331
333
|
|
|
332
334
|
**Stagehand Provider (Computer Use only):**
|
|
333
335
|
- `openai/computer-use-preview-2025-03-11` - Requires `OPENAI_API_KEY`
|
|
334
|
-
- `anthropic/claude-sonnet-4-
|
|
336
|
+
- `anthropic/claude-sonnet-4-6-20260301` - Requires `ANTHROPIC_API_KEY`
|
|
335
337
|
- `anthropic/claude-haiku-4-5-20251001` - Requires `ANTHROPIC_API_KEY`
|
|
336
|
-
- `anthropic/claude-opus-4-
|
|
338
|
+
- `anthropic/claude-opus-4-6-20260301` - Requires `ANTHROPIC_API_KEY`
|
|
337
339
|
|
|
338
340
|
**Setting API Keys:**
|
|
339
341
|
```bash
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
please i have currently a ui for the chrome extension but i don't like it at all and want to make it polished. remove the current text input with a chat input with rounded corners auto resize and a send button. another thing is empty state should show the reverse-api-engineer logo on the center and then revamp the header part to make it more modern and stylish and polished while getting a minimalist design
|
|
2
|
+
|
|
3
|
+
now please create or explain the system to save the capture scripts (like the api_client.py) somewhere because otherwise we need to explore the hidden .reverse-api folder and it's annoying (also saved under id), so we need to thing about where to save generated scripts via chrome extension
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
please create a file called setup_sprite.py, it will do the following: install uv if not available
|
|
7
|
+
in the sandbox, do create a folder reverse-api-engineer, enter it, uv init && uv add (the deps
|
|
8
|
+
needed) and then download the agent_script in the sandbox.
|
|
@@ -42,7 +42,7 @@ No more manual reverse engineering—just browse, capture, and get clean API cod
|
|
|
42
42
|
- 🌐 **Browser Automation**: Built on Playwright with stealth mode for realistic browsing
|
|
43
43
|
- 🤖 **Autonomous Agent Mode**: Fully automated browser interaction using AI agents (auto mode with MCP, browser-use, stagehand)
|
|
44
44
|
- 📊 **HAR Recording**: Captures all network traffic in HTTP Archive format
|
|
45
|
-
- 🧠 **AI-Powered Generation**: Uses Claude 4.
|
|
45
|
+
- 🧠 **AI-Powered Generation**: Uses Claude 4.6 to analyze traffic and generate clean Python code
|
|
46
46
|
- 🔍 **Collector Mode**: Data collection with automatic JSON/CSV export
|
|
47
47
|
- 🔌 **Multi-SDK Support**: Native integration with Claude and OpenCode SDKs
|
|
48
48
|
- 💻 **Interactive CLI**: Minimalist terminal interface with mode cycling (Shift+Tab)
|
|
@@ -85,7 +85,7 @@ playwright install chromium
|
|
|
85
85
|
|
|
86
86
|
### Enhanced Pricing Support (Optional)
|
|
87
87
|
|
|
88
|
-
By default, Reverse API Engineer includes pricing data for the most common models (Claude 4.
|
|
88
|
+
By default, Reverse API Engineer includes pricing data for the most common models (Claude 4.6, Gemini 3). For extended model coverage (100+ additional models including OpenAI GPT, Mistral, DeepSeek, and more), install with pricing extras:
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
91
|
# With uv
|
|
@@ -98,7 +98,7 @@ pip install 'reverse-api-engineer[pricing]'
|
|
|
98
98
|
This enables automatic pricing lookup via [LiteLLM](https://github.com/BerriAI/litellm) for models not in the built-in database. The pricing system uses a 3-tier fallback:
|
|
99
99
|
1. **Local pricing** (highest priority) - Built-in pricing for common models
|
|
100
100
|
2. **LiteLLM pricing** (if installed) - Extended coverage for 100+ models
|
|
101
|
-
3. **Default pricing** (ultimate fallback) - Uses Claude Sonnet 4.
|
|
101
|
+
3. **Default pricing** (ultimate fallback) - Uses Claude Sonnet 4.6 pricing
|
|
102
102
|
|
|
103
103
|
Cost tracking will always work, with or without the pricing extras installed.
|
|
104
104
|
|
|
@@ -191,7 +191,7 @@ Web data collection using Claude Agent SDK:
|
|
|
191
191
|
- `README.md` - Collection metadata and schema documentation
|
|
192
192
|
|
|
193
193
|
**Model Configuration:**
|
|
194
|
-
Collector mode uses the `collector_model` setting (default: `claude-sonnet-4-
|
|
194
|
+
Collector mode uses the `collector_model` setting (default: `claude-sonnet-4-6`). This can be configured in `~/.reverse-api/config.json`.
|
|
195
195
|
|
|
196
196
|
Example workflow:
|
|
197
197
|
```bash
|
|
@@ -245,9 +245,9 @@ Settings stored in `~/.reverse-api/config.json`:
|
|
|
245
245
|
{
|
|
246
246
|
"agent_provider": "auto",
|
|
247
247
|
"browser_use_model": "bu-llm",
|
|
248
|
-
"claude_code_model": "claude-sonnet-4-
|
|
249
|
-
"collector_model": "claude-sonnet-4-
|
|
250
|
-
"opencode_model": "claude-sonnet-4-
|
|
248
|
+
"claude_code_model": "claude-sonnet-4-6",
|
|
249
|
+
"collector_model": "claude-sonnet-4-6",
|
|
250
|
+
"opencode_model": "claude-sonnet-4-6",
|
|
251
251
|
"opencode_provider": "anthropic",
|
|
252
252
|
"output_dir": null,
|
|
253
253
|
"output_language": "python",
|
|
@@ -259,14 +259,14 @@ Settings stored in `~/.reverse-api/config.json`:
|
|
|
259
259
|
|
|
260
260
|
### Model Selection
|
|
261
261
|
|
|
262
|
-
Choose from Claude 4.
|
|
263
|
-
- **Sonnet 4.
|
|
264
|
-
- **Opus 4.
|
|
262
|
+
Choose from Claude 4.6 models for API generation:
|
|
263
|
+
- **Sonnet 4.6** (default): Balanced performance and cost
|
|
264
|
+
- **Opus 4.6**: Maximum capability for complex APIs
|
|
265
265
|
- **Haiku 4.5**: Fastest and most economical
|
|
266
266
|
|
|
267
267
|
Change in `/settings` or via CLI:
|
|
268
268
|
```bash
|
|
269
|
-
reverse-api-engineer manual --model claude-sonnet-4-
|
|
269
|
+
reverse-api-engineer manual --model claude-sonnet-4-6
|
|
270
270
|
```
|
|
271
271
|
|
|
272
272
|
If you use Opencode, look at the [models](https://models.dev).
|
|
@@ -289,9 +289,9 @@ Configure AI agents for autonomous browser automation.
|
|
|
289
289
|
|
|
290
290
|
**Stagehand Provider (Computer Use only):**
|
|
291
291
|
- `openai/computer-use-preview-2025-03-11` - Requires `OPENAI_API_KEY`
|
|
292
|
-
- `anthropic/claude-sonnet-4-
|
|
292
|
+
- `anthropic/claude-sonnet-4-6-20260301` - Requires `ANTHROPIC_API_KEY`
|
|
293
293
|
- `anthropic/claude-haiku-4-5-20251001` - Requires `ANTHROPIC_API_KEY`
|
|
294
|
-
- `anthropic/claude-opus-4-
|
|
294
|
+
- `anthropic/claude-opus-4-6-20260301` - Requires `ANTHROPIC_API_KEY`
|
|
295
295
|
|
|
296
296
|
**Setting API Keys:**
|
|
297
297
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "reverse-api-engineer"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "A tool to capture browser traffic for API reverse engineering"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -48,6 +48,9 @@ collector = [
|
|
|
48
48
|
"markdownify>=0.12.0",
|
|
49
49
|
"beautifulsoup4>=4.12.0",
|
|
50
50
|
]
|
|
51
|
+
copilot = [
|
|
52
|
+
"github-copilot-sdk>=0.1.0",
|
|
53
|
+
]
|
|
51
54
|
|
|
52
55
|
[project.urls]
|
|
53
56
|
Homepage = "https://github.com/kalil0321/reverse-api-engineer"
|
|
@@ -71,6 +74,29 @@ packages = ["src/reverse_api"]
|
|
|
71
74
|
dev = [
|
|
72
75
|
"mypy>=1.19.1",
|
|
73
76
|
"ruff>=0.14.10",
|
|
77
|
+
"pytest>=8.0.0",
|
|
78
|
+
"pytest-cov>=6.0.0",
|
|
79
|
+
"pytest-asyncio>=0.24.0",
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
[tool.pytest.ini_options]
|
|
83
|
+
testpaths = ["tests"]
|
|
84
|
+
asyncio_mode = "auto"
|
|
85
|
+
|
|
86
|
+
[tool.coverage.run]
|
|
87
|
+
source = ["src/reverse_api"]
|
|
88
|
+
omit = [
|
|
89
|
+
"src/reverse_api/cli.py",
|
|
90
|
+
"src/reverse_api/browser.py",
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
[tool.coverage.report]
|
|
94
|
+
show_missing = true
|
|
95
|
+
precision = 1
|
|
96
|
+
exclude_lines = [
|
|
97
|
+
"pragma: no cover",
|
|
98
|
+
"if __name__ == .__main__.",
|
|
99
|
+
"if TYPE_CHECKING:",
|
|
74
100
|
]
|
|
75
101
|
|
|
76
102
|
[tool.ruff]
|
|
@@ -577,3 +577,180 @@ class OpenCodeAutoEngineer(OpenCodeEngineer):
|
|
|
577
577
|
debug_log(f"Cleaned up MCP server: {self.mcp_name}")
|
|
578
578
|
except Exception:
|
|
579
579
|
pass # Ignore cleanup errors
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
class CopilotAutoEngineer:
|
|
583
|
+
"""Auto mode using Copilot SDK: LLM controls browser via MCP while reverse engineering.
|
|
584
|
+
|
|
585
|
+
Uses composition rather than inheritance since CopilotEngineer requires lazy imports.
|
|
586
|
+
Delegates to CopilotEngineer for the core logic and adds MCP browser integration.
|
|
587
|
+
"""
|
|
588
|
+
|
|
589
|
+
def __init__(
|
|
590
|
+
self,
|
|
591
|
+
run_id: str,
|
|
592
|
+
prompt: str,
|
|
593
|
+
copilot_model: str | None = None,
|
|
594
|
+
output_dir: str | None = None,
|
|
595
|
+
**kwargs: Any,
|
|
596
|
+
):
|
|
597
|
+
from .copilot_engineer import CopilotEngineer
|
|
598
|
+
|
|
599
|
+
har_dir = get_har_dir(run_id, output_dir)
|
|
600
|
+
har_path = har_dir / "recording.har"
|
|
601
|
+
|
|
602
|
+
self._engineer = CopilotEngineer(
|
|
603
|
+
run_id=run_id,
|
|
604
|
+
har_path=har_path,
|
|
605
|
+
prompt=prompt,
|
|
606
|
+
copilot_model=copilot_model,
|
|
607
|
+
output_dir=output_dir,
|
|
608
|
+
**kwargs,
|
|
609
|
+
)
|
|
610
|
+
self.mcp_run_id = run_id
|
|
611
|
+
|
|
612
|
+
def start_sync(self) -> None:
|
|
613
|
+
self._engineer.start_sync()
|
|
614
|
+
|
|
615
|
+
def stop_sync(self) -> None:
|
|
616
|
+
self._engineer.stop_sync()
|
|
617
|
+
|
|
618
|
+
async def analyze_and_generate(self) -> dict[str, Any] | None:
|
|
619
|
+
"""Run auto mode with Copilot SDK and MCP browser integration."""
|
|
620
|
+
try:
|
|
621
|
+
from copilot import CopilotClient, PermissionHandler
|
|
622
|
+
except ImportError:
|
|
623
|
+
self._engineer.ui.error(
|
|
624
|
+
"GitHub Copilot SDK not installed. From source: uv sync --extra copilot. Installed: pip install 'reverse-api-engineer[copilot]'"
|
|
625
|
+
)
|
|
626
|
+
return None
|
|
627
|
+
|
|
628
|
+
eng = self._engineer
|
|
629
|
+
eng.ui.header(eng.run_id, eng.prompt, eng.copilot_model, eng.sdk)
|
|
630
|
+
eng.ui.start_analysis()
|
|
631
|
+
|
|
632
|
+
auto_prompt = ClaudeAutoEngineer._build_auto_prompt(eng)
|
|
633
|
+
eng.message_store.save_prompt(auto_prompt)
|
|
634
|
+
|
|
635
|
+
done_event = asyncio.Event()
|
|
636
|
+
loop = asyncio.get_running_loop()
|
|
637
|
+
accumulated_text: list[str] = []
|
|
638
|
+
|
|
639
|
+
def on_event(event: Any) -> None:
|
|
640
|
+
event_type = event.type.value if hasattr(event.type, "value") else str(event.type)
|
|
641
|
+
|
|
642
|
+
if event_type == "assistant.message_delta":
|
|
643
|
+
delta = ""
|
|
644
|
+
if hasattr(event, "data") and hasattr(event.data, "delta_content"):
|
|
645
|
+
delta = event.data.delta_content or ""
|
|
646
|
+
if delta:
|
|
647
|
+
accumulated_text.append(delta)
|
|
648
|
+
eng.ui.thinking(delta)
|
|
649
|
+
elif event_type == "assistant.message":
|
|
650
|
+
if hasattr(event, "data") and hasattr(event.data, "usage"):
|
|
651
|
+
usage = event.data.usage
|
|
652
|
+
if isinstance(usage, dict):
|
|
653
|
+
eng.usage_metadata["input_tokens"] = usage.get("prompt_tokens", 0)
|
|
654
|
+
eng.usage_metadata["output_tokens"] = usage.get("completion_tokens", 0)
|
|
655
|
+
elif event_type == "session.idle":
|
|
656
|
+
# Use thread-safe call in case SDK invokes callback from a different thread
|
|
657
|
+
loop.call_soon_threadsafe(done_event.set)
|
|
658
|
+
|
|
659
|
+
client = None
|
|
660
|
+
try:
|
|
661
|
+
client = CopilotClient(
|
|
662
|
+
{
|
|
663
|
+
"auto_start": True,
|
|
664
|
+
"use_logged_in_user": True,
|
|
665
|
+
}
|
|
666
|
+
)
|
|
667
|
+
await client.start()
|
|
668
|
+
|
|
669
|
+
mcp_config = {
|
|
670
|
+
"type": "local",
|
|
671
|
+
"command": "npx",
|
|
672
|
+
"args": [
|
|
673
|
+
"-y",
|
|
674
|
+
"rae-playwright-mcp@latest",
|
|
675
|
+
"run-mcp-server",
|
|
676
|
+
"--run-id",
|
|
677
|
+
self.mcp_run_id,
|
|
678
|
+
],
|
|
679
|
+
"tools": ["*"],
|
|
680
|
+
"timeout": 30000,
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
async def on_pre_tool_use(input: dict, _invocation: dict) -> dict:
|
|
684
|
+
tool_name = input.get("toolName", "unknown")
|
|
685
|
+
tool_args = input.get("toolArgs") or {}
|
|
686
|
+
eng.ui.tool_start(tool_name, tool_args)
|
|
687
|
+
eng.message_store.save_tool_start(tool_name, tool_args)
|
|
688
|
+
return {"permissionDecision": "allow", "modifiedArgs": tool_args}
|
|
689
|
+
|
|
690
|
+
async def on_post_tool_use(input: dict, invocation: dict) -> dict:
|
|
691
|
+
tool_name = input.get("toolName", "unknown")
|
|
692
|
+
is_error = invocation.get("resultType") == "error" if isinstance(invocation, dict) else False
|
|
693
|
+
output = invocation.get("result") if isinstance(invocation, dict) else None
|
|
694
|
+
eng.ui.tool_result(tool_name, is_error=is_error, output=str(output) if output else None)
|
|
695
|
+
eng.message_store.save_tool_result(tool_name, is_error, str(output) if output else None)
|
|
696
|
+
return {}
|
|
697
|
+
|
|
698
|
+
session = await client.create_session(
|
|
699
|
+
{
|
|
700
|
+
"model": eng.copilot_model,
|
|
701
|
+
"streaming": True,
|
|
702
|
+
"infinite_sessions": {"enabled": True},
|
|
703
|
+
"mcp_servers": {"playwright": mcp_config},
|
|
704
|
+
"on_permission_request": PermissionHandler.approve_all,
|
|
705
|
+
"hooks": {
|
|
706
|
+
"on_pre_tool_use": on_pre_tool_use,
|
|
707
|
+
"on_post_tool_use": on_post_tool_use,
|
|
708
|
+
},
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
|
|
712
|
+
session.on(on_event)
|
|
713
|
+
await session.send({"prompt": auto_prompt})
|
|
714
|
+
|
|
715
|
+
# Wait with timeout protection (10 minutes)
|
|
716
|
+
try:
|
|
717
|
+
await asyncio.wait_for(done_event.wait(), timeout=600)
|
|
718
|
+
except TimeoutError:
|
|
719
|
+
eng.ui.error("Session timed out (10 min)")
|
|
720
|
+
eng.message_store.save_error("Session timed out")
|
|
721
|
+
return None
|
|
722
|
+
|
|
723
|
+
if accumulated_text:
|
|
724
|
+
eng.message_store.save_thinking("".join(accumulated_text))
|
|
725
|
+
|
|
726
|
+
script_path = str(eng.scripts_dir / eng._get_client_filename())
|
|
727
|
+
local_path = str(eng.local_scripts_dir / eng._get_client_filename()) if eng.local_scripts_dir else None
|
|
728
|
+
eng.ui.success(script_path, local_path)
|
|
729
|
+
eng.usage_metadata["estimated_cost_usd"] = 0.0
|
|
730
|
+
|
|
731
|
+
result: dict[str, Any] = {
|
|
732
|
+
"script_path": script_path,
|
|
733
|
+
"usage": eng.usage_metadata,
|
|
734
|
+
}
|
|
735
|
+
eng.message_store.save_result(result)
|
|
736
|
+
return result
|
|
737
|
+
|
|
738
|
+
except Exception as e:
|
|
739
|
+
error_msg = str(e)
|
|
740
|
+
eng.ui.error(error_msg)
|
|
741
|
+
eng.message_store.save_error(error_msg)
|
|
742
|
+
|
|
743
|
+
if "buffer size" in error_msg.lower() or "1048576" in error_msg or "exceeded maximum buffer" in error_msg.lower():
|
|
744
|
+
eng.ui.console.print("\n[yellow]Screenshot too large (exceeds 1MB limit)[/yellow]")
|
|
745
|
+
eng.ui.console.print("[dim]Tip: The AI should take element-specific screenshots instead of full-page screenshots.[/dim]")
|
|
746
|
+
else:
|
|
747
|
+
eng.ui.console.print("\n[dim]Make sure GitHub Copilot CLI is installed and you are logged in: gh auth login[/dim]")
|
|
748
|
+
return None
|
|
749
|
+
|
|
750
|
+
finally:
|
|
751
|
+
# Always stop the client to avoid resource leaks
|
|
752
|
+
if client is not None:
|
|
753
|
+
try:
|
|
754
|
+
await client.stop()
|
|
755
|
+
except Exception:
|
|
756
|
+
pass
|