reverse-api-engineer 0.4.4__tar.gz → 0.4.5__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.4.4 → reverse_api_engineer-0.4.5}/CHANGELOG.md +8 -3
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/PKG-INFO +1 -1
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/pyproject.toml +1 -1
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/auto_engineer.py +80 -93
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/engineer.py +80 -94
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/uv.lock +1 -1
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/.claude/settings.local.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/.claude-plugin/marketplace.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/.gitignore +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/.python-version +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/CLAUDE.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/CONTRIBUTING.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/INTERVIEW.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/LICENSE +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/PROMPT_STASH.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/RELEASING.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/assets/reverse-api-banner.svg +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/assets/reverse-api-engineer.gif +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/assets/reverse-api-logo.svg +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/.claude/settings.local.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/components.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/package-lock.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/package.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/packed/reverse-api-engineer-chrome.zip +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/postcss.config.js +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/_locales/en/messages.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-128.png +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-16.png +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-32.png +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-48.png +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/manifest.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/background/service-worker.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/agent-action.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/chat-input.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/icons.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/markdown-renderer.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/mode-selector.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/plan.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/session-selector.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/terminal.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/ui/code-block.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/content/codegen-recorder.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/index.css +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/capture.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/native-host.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/storage.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/types.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/sidepanel/index.html +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/sidepanel/main.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/sidepanel/side-panel.tsx +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/vite-env.d.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/store-assets/screenshot-1280x800.png +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/tailwind.config.js +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/tsconfig.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/vite.config.ts +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/INDEX.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/QUICKSTART.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/SUMMARY.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/extract_job_fields.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/main.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/quick_example.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/requirements.txt +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/API_SUMMARY.txt +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/QUICKSTART.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/example_usage.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ashby/requirements.txt +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/autoscout24/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/autoscout24/SUMMARY.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/autoscout24/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ikea/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/ikea/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/mintlify/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/mintlify/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/API_ANALYSIS_SUMMARY.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/example_fetch_all_jobs.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/quick_start.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/requirements.txt +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/llm-docs/OPENCODE_API_SUMMARY.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/llm-docs/opencode-api.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/.claude-plugin/plugin.json +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/CHANGELOG.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/LICENSE +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/README.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/agents/api-reverse-engineer.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/commands/agent.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/commands/capture.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/commands/engineer.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/commands/manual.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/CHANGELOG.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/LICENSE +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/SKILL.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/references/AUTH_PATTERNS.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/references/HAR_ANALYSIS.md +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_analyze.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_filter.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_utils.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/scripts/har_validate.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/skills/reverse-engineering-api/templates/api_client.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/scripts/clean_build.sh +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/__init__.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/action_recorder.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/base_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/browser.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/cli.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/collector.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/collector_ui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/config.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/copilot_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/messages.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/native_host.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/opencode_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/opencode_ui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/playwright_codegen.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/pricing.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/session.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/sync.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/tui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/utils.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/__init__.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/conftest.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_action_recorder.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_auto_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_base_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_collector.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_collector_ui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_config.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_init.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_messages.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_native_host.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_opencode_engineer.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_opencode_ui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_pricing.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_session.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_sync.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_tui.py +0 -0
- {reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/tests/test_utils.py +0 -0
|
@@ -5,11 +5,11 @@ 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.
|
|
8
|
+
## [0.4.5] - 2026-03-15
|
|
9
9
|
|
|
10
10
|
### Fixed
|
|
11
|
-
- **Stream closed errors (#51)**:
|
|
12
|
-
- **
|
|
11
|
+
- **Stream closed errors (#51)**: Reverted from `query()` to `ClaudeSDKClient` which maintains a persistent bidirectional connection, eliminating "Error in hook callback hook_0: Stream closed" errors. The original AUQ fix (v0.4.3) unnecessarily switched APIs — only the `can_use_tool` callback signature needed updating
|
|
12
|
+
- **CLAUDECODE env var leak**: Clear inherited `CLAUDECODE` env var from CLI subprocess to prevent nested session interference when running inside Claude Code
|
|
13
13
|
- **CLI stderr noise**: Filter minified JS stack traces into a single clean error line (use `DEBUG=1` for full output)
|
|
14
14
|
|
|
15
15
|
### Changed
|
|
@@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
17
|
- **Agent mode**: No longer prompts for URL (agent navigates autonomously)
|
|
18
18
|
- **Header UI**: Version and task labels now use mode-specific colors (agent=coral, engineer=blue, collector=gold)
|
|
19
19
|
|
|
20
|
+
## [0.4.4] - 2026-03-15
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **Stream closed errors (#51)**: Partial fix using `query()` with env var workarounds (superseded by v0.4.5)
|
|
24
|
+
|
|
20
25
|
## [0.4.3] - 2026-03-12
|
|
21
26
|
|
|
22
27
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reverse-api-engineer
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
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
|
|
@@ -11,14 +11,13 @@ import httpx
|
|
|
11
11
|
from claude_agent_sdk import (
|
|
12
12
|
AssistantMessage,
|
|
13
13
|
ClaudeAgentOptions,
|
|
14
|
-
|
|
14
|
+
ClaudeSDKClient,
|
|
15
15
|
PermissionResultAllow,
|
|
16
16
|
ResultMessage,
|
|
17
17
|
TextBlock,
|
|
18
18
|
ToolPermissionContext,
|
|
19
19
|
ToolResultBlock,
|
|
20
20
|
ToolUseBlock,
|
|
21
|
-
query,
|
|
22
21
|
)
|
|
23
22
|
|
|
24
23
|
from .engineer import ClaudeEngineer
|
|
@@ -257,105 +256,93 @@ Your final response should confirm the files were created and provide a brief su
|
|
|
257
256
|
],
|
|
258
257
|
}
|
|
259
258
|
|
|
260
|
-
# Required: dummy hook keeps the stream open for can_use_tool
|
|
261
|
-
async def _dummy_hook(input_data: dict[str, Any], tool_use_id: str | None, context: Any) -> dict[str, Any]:
|
|
262
|
-
return {"continue_": True}
|
|
263
|
-
|
|
264
|
-
async def _prompt_stream():
|
|
265
|
-
yield {
|
|
266
|
-
"type": "user",
|
|
267
|
-
"message": {"role": "user", "content": self._build_auto_prompt()},
|
|
268
|
-
}
|
|
269
|
-
|
|
270
259
|
options = ClaudeAgentOptions(
|
|
271
260
|
mcp_servers={"playwright": mcp_config},
|
|
261
|
+
permission_mode="bypassPermissions",
|
|
272
262
|
can_use_tool=self._handle_tool_permission,
|
|
273
|
-
hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[_dummy_hook])]},
|
|
274
263
|
cwd=str(self.scripts_dir.parent.parent), # Project root
|
|
275
264
|
model=self.model,
|
|
276
|
-
env={"CLAUDECODE": ""
|
|
265
|
+
env={"CLAUDECODE": ""},
|
|
277
266
|
stderr=self._handle_cli_stderr,
|
|
278
267
|
)
|
|
279
268
|
|
|
280
|
-
final_result: dict[str, Any] | None = None
|
|
281
|
-
|
|
282
269
|
try:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
self.ui.console.print(f" [dim]
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
270
|
+
async with ClaudeSDKClient(options=options) as client:
|
|
271
|
+
await client.query(self._build_auto_prompt())
|
|
272
|
+
|
|
273
|
+
async for message in client.receive_response():
|
|
274
|
+
if hasattr(message, "usage") and isinstance(message.usage, dict):
|
|
275
|
+
self.usage_metadata.update(message.usage)
|
|
276
|
+
|
|
277
|
+
if isinstance(message, AssistantMessage):
|
|
278
|
+
last_tool_name = None
|
|
279
|
+
for block in message.content:
|
|
280
|
+
if isinstance(block, ToolUseBlock):
|
|
281
|
+
last_tool_name = block.name
|
|
282
|
+
self.ui.tool_start(block.name, block.input)
|
|
283
|
+
self.message_store.save_tool_start(block.name, block.input)
|
|
284
|
+
elif isinstance(block, ToolResultBlock):
|
|
285
|
+
is_error = block.is_error if block.is_error else False
|
|
286
|
+
|
|
287
|
+
output = None
|
|
288
|
+
if hasattr(block, "content"):
|
|
289
|
+
output = block.content
|
|
290
|
+
elif hasattr(block, "result"):
|
|
291
|
+
output = block.result
|
|
292
|
+
elif hasattr(block, "output"):
|
|
293
|
+
output = block.output
|
|
294
|
+
|
|
295
|
+
tool_name = last_tool_name or "Tool"
|
|
296
|
+
self.ui.tool_result(tool_name, is_error, output)
|
|
297
|
+
self.message_store.save_tool_result(tool_name, is_error, str(output) if output else None)
|
|
298
|
+
elif isinstance(block, TextBlock):
|
|
299
|
+
self.ui.thinking(block.text)
|
|
300
|
+
self.message_store.save_thinking(block.text)
|
|
301
|
+
|
|
302
|
+
elif isinstance(message, ResultMessage):
|
|
303
|
+
if message.is_error:
|
|
304
|
+
self.ui.error(message.result or "Unknown error")
|
|
305
|
+
self.message_store.save_error(message.result or "Unknown error")
|
|
306
|
+
return None
|
|
307
|
+
else:
|
|
308
|
+
script_path = str(self.scripts_dir / self._get_client_filename())
|
|
309
|
+
local_path = str(self.local_scripts_dir / self._get_client_filename()) if self.local_scripts_dir else None
|
|
310
|
+
self.ui.success(script_path, local_path)
|
|
311
|
+
|
|
312
|
+
if self.usage_metadata:
|
|
313
|
+
input_tokens = self.usage_metadata.get("input_tokens", 0)
|
|
314
|
+
output_tokens = self.usage_metadata.get("output_tokens", 0)
|
|
315
|
+
cache_creation_tokens = self.usage_metadata.get("cache_creation_input_tokens", 0)
|
|
316
|
+
cache_read_tokens = self.usage_metadata.get("cache_read_input_tokens", 0)
|
|
317
|
+
|
|
318
|
+
from .pricing import calculate_cost
|
|
319
|
+
|
|
320
|
+
cost = calculate_cost(
|
|
321
|
+
model_id=self.model,
|
|
322
|
+
input_tokens=input_tokens,
|
|
323
|
+
output_tokens=output_tokens,
|
|
324
|
+
cache_creation_tokens=cache_creation_tokens,
|
|
325
|
+
cache_read_tokens=cache_read_tokens,
|
|
326
|
+
)
|
|
327
|
+
self.usage_metadata["estimated_cost_usd"] = cost
|
|
328
|
+
|
|
329
|
+
self.ui.console.print(" [dim]Usage:[/dim]")
|
|
330
|
+
if input_tokens > 0:
|
|
331
|
+
self.ui.console.print(f" [dim] input: {input_tokens:,} tokens[/dim]")
|
|
332
|
+
if cache_creation_tokens > 0:
|
|
333
|
+
self.ui.console.print(f" [dim] cache creation: {cache_creation_tokens:,} tokens[/dim]")
|
|
334
|
+
if cache_read_tokens > 0:
|
|
335
|
+
self.ui.console.print(f" [dim] cache read: {cache_read_tokens:,} tokens[/dim]")
|
|
336
|
+
if output_tokens > 0:
|
|
337
|
+
self.ui.console.print(f" [dim] output: {output_tokens:,} tokens[/dim]")
|
|
338
|
+
self.ui.console.print(f" [dim] total cost: ${cost:.4f}[/dim]")
|
|
339
|
+
|
|
340
|
+
result: dict[str, Any] = {
|
|
341
|
+
"script_path": script_path,
|
|
342
|
+
"usage": self.usage_metadata,
|
|
343
|
+
}
|
|
344
|
+
self.message_store.save_result(result)
|
|
345
|
+
return result
|
|
359
346
|
|
|
360
347
|
except Exception as e:
|
|
361
348
|
error_msg = str(e)
|
|
@@ -374,7 +361,7 @@ Your final response should confirm the files were created and provide a brief su
|
|
|
374
361
|
self.ui.console.print("\n[dim]Make sure Claude Code CLI is installed: npm install -g @anthropic-ai/claude-code[/dim]")
|
|
375
362
|
return None
|
|
376
363
|
|
|
377
|
-
return
|
|
364
|
+
return None
|
|
378
365
|
|
|
379
366
|
|
|
380
367
|
class OpenCodeAutoEngineer(OpenCodeEngineer):
|
|
@@ -8,14 +8,13 @@ from typing import Any
|
|
|
8
8
|
from claude_agent_sdk import (
|
|
9
9
|
AssistantMessage,
|
|
10
10
|
ClaudeAgentOptions,
|
|
11
|
-
|
|
11
|
+
ClaudeSDKClient,
|
|
12
12
|
PermissionResultAllow,
|
|
13
13
|
ResultMessage,
|
|
14
14
|
TextBlock,
|
|
15
15
|
ToolPermissionContext,
|
|
16
16
|
ToolResultBlock,
|
|
17
17
|
ToolUseBlock,
|
|
18
|
-
query,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
from .base_engineer import BaseEngineer
|
|
@@ -46,105 +45,92 @@ class ClaudeEngineer(BaseEngineer):
|
|
|
46
45
|
self.ui.start_analysis()
|
|
47
46
|
self.message_store.save_prompt(self._build_analysis_prompt())
|
|
48
47
|
|
|
49
|
-
# Required: dummy hook keeps the stream open for can_use_tool
|
|
50
|
-
# See: https://platform.claude.com/docs/en/agent-sdk/user-input
|
|
51
|
-
async def _dummy_hook(input_data: dict[str, Any], tool_use_id: str | None, context: Any) -> dict[str, Any]:
|
|
52
|
-
return {"continue_": True}
|
|
53
|
-
|
|
54
|
-
async def _prompt_stream():
|
|
55
|
-
yield {
|
|
56
|
-
"type": "user",
|
|
57
|
-
"message": {"role": "user", "content": self._build_analysis_prompt()},
|
|
58
|
-
}
|
|
59
|
-
|
|
60
48
|
options = ClaudeAgentOptions(
|
|
49
|
+
permission_mode="acceptEdits",
|
|
61
50
|
can_use_tool=self._handle_tool_permission,
|
|
62
|
-
hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[_dummy_hook])]},
|
|
63
51
|
cwd=str(self.scripts_dir.parent.parent), # Project root
|
|
64
52
|
model=self.model,
|
|
65
|
-
env={"CLAUDECODE": ""
|
|
53
|
+
env={"CLAUDECODE": ""},
|
|
66
54
|
stderr=self._handle_cli_stderr,
|
|
67
55
|
)
|
|
68
56
|
|
|
69
|
-
final_result: dict[str, Any] | None = None
|
|
70
|
-
|
|
71
57
|
try:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
self.ui.console.print(f" [dim]
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
58
|
+
async with ClaudeSDKClient(options=options) as client:
|
|
59
|
+
await client.query(self._build_analysis_prompt())
|
|
60
|
+
|
|
61
|
+
async for message in client.receive_response():
|
|
62
|
+
if hasattr(message, "usage") and isinstance(message.usage, dict):
|
|
63
|
+
self.usage_metadata.update(message.usage)
|
|
64
|
+
|
|
65
|
+
if isinstance(message, AssistantMessage):
|
|
66
|
+
last_tool_name = None
|
|
67
|
+
for block in message.content:
|
|
68
|
+
if isinstance(block, ToolUseBlock):
|
|
69
|
+
last_tool_name = block.name
|
|
70
|
+
self.ui.tool_start(block.name, block.input)
|
|
71
|
+
self.message_store.save_tool_start(block.name, block.input)
|
|
72
|
+
elif isinstance(block, ToolResultBlock):
|
|
73
|
+
is_error = block.is_error if block.is_error else False
|
|
74
|
+
|
|
75
|
+
output = None
|
|
76
|
+
if hasattr(block, "content"):
|
|
77
|
+
output = block.content
|
|
78
|
+
elif hasattr(block, "result"):
|
|
79
|
+
output = block.result
|
|
80
|
+
elif hasattr(block, "output"):
|
|
81
|
+
output = block.output
|
|
82
|
+
|
|
83
|
+
tool_name = last_tool_name or "Tool"
|
|
84
|
+
self.ui.tool_result(tool_name, is_error, output)
|
|
85
|
+
self.message_store.save_tool_result(tool_name, is_error, str(output) if output else None)
|
|
86
|
+
elif isinstance(block, TextBlock):
|
|
87
|
+
self.ui.thinking(block.text)
|
|
88
|
+
self.message_store.save_thinking(block.text)
|
|
89
|
+
|
|
90
|
+
elif isinstance(message, ResultMessage):
|
|
91
|
+
if message.is_error:
|
|
92
|
+
self.ui.error(message.result or "Unknown error")
|
|
93
|
+
self.message_store.save_error(message.result or "Unknown error")
|
|
94
|
+
return None
|
|
95
|
+
else:
|
|
96
|
+
script_path = str(self.scripts_dir / self._get_client_filename())
|
|
97
|
+
local_path = str(self.local_scripts_dir / self._get_client_filename()) if self.local_scripts_dir else None
|
|
98
|
+
self.ui.success(script_path, local_path)
|
|
99
|
+
|
|
100
|
+
if self.usage_metadata:
|
|
101
|
+
input_tokens = self.usage_metadata.get("input_tokens", 0)
|
|
102
|
+
output_tokens = self.usage_metadata.get("output_tokens", 0)
|
|
103
|
+
cache_creation_tokens = self.usage_metadata.get("cache_creation_input_tokens", 0)
|
|
104
|
+
cache_read_tokens = self.usage_metadata.get("cache_read_input_tokens", 0)
|
|
105
|
+
|
|
106
|
+
from .pricing import calculate_cost
|
|
107
|
+
|
|
108
|
+
cost = calculate_cost(
|
|
109
|
+
model_id=self.model,
|
|
110
|
+
input_tokens=input_tokens,
|
|
111
|
+
output_tokens=output_tokens,
|
|
112
|
+
cache_creation_tokens=cache_creation_tokens,
|
|
113
|
+
cache_read_tokens=cache_read_tokens,
|
|
114
|
+
)
|
|
115
|
+
self.usage_metadata["estimated_cost_usd"] = cost
|
|
116
|
+
|
|
117
|
+
self.ui.console.print(" [dim]Usage:[/dim]")
|
|
118
|
+
if input_tokens > 0:
|
|
119
|
+
self.ui.console.print(f" [dim] input: {input_tokens:,} tokens[/dim]")
|
|
120
|
+
if cache_creation_tokens > 0:
|
|
121
|
+
self.ui.console.print(f" [dim] cache creation: {cache_creation_tokens:,} tokens[/dim]")
|
|
122
|
+
if cache_read_tokens > 0:
|
|
123
|
+
self.ui.console.print(f" [dim] cache read: {cache_read_tokens:,} tokens[/dim]")
|
|
124
|
+
if output_tokens > 0:
|
|
125
|
+
self.ui.console.print(f" [dim] output: {output_tokens:,} tokens[/dim]")
|
|
126
|
+
self.ui.console.print(f" [dim] total cost: ${cost:.4f}[/dim]")
|
|
127
|
+
|
|
128
|
+
result: dict[str, Any] = {
|
|
129
|
+
"script_path": script_path,
|
|
130
|
+
"usage": self.usage_metadata,
|
|
131
|
+
}
|
|
132
|
+
self.message_store.save_result(result)
|
|
133
|
+
return result
|
|
148
134
|
|
|
149
135
|
except Exception as e:
|
|
150
136
|
self.ui.error(str(e))
|
|
@@ -152,7 +138,7 @@ class ClaudeEngineer(BaseEngineer):
|
|
|
152
138
|
self.ui.console.print("\n[dim]Make sure Claude Code CLI is installed: npm install -g @anthropic-ai/claude-code[/dim]")
|
|
153
139
|
return None
|
|
154
140
|
|
|
155
|
-
return
|
|
141
|
+
return None
|
|
156
142
|
|
|
157
143
|
|
|
158
144
|
# Keep old class name for backwards compatibility
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/package-lock.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/postcss.config.js
RENAMED
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-128.png
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-16.png
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-32.png
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/icons/icon-48.png
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/public/manifest.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/icons.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/components/plan.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/capture.ts
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/native-host.ts
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/storage.ts
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/shared/types.ts
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/sidepanel/index.html
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/sidepanel/main.tsx
RENAMED
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/src/vite-env.d.ts
RENAMED
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/chrome-extension/tailwind.config.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/apple/extract_job_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/autoscout24/api_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/API_ANALYSIS_SUMMARY.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/examples/uber/example_fetch_all_jobs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/CHANGELOG.md
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/LICENSE
RENAMED
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/plugins/reverse-api-engineer/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/action_recorder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/copilot_engineer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/opencode_engineer.py
RENAMED
|
File without changes
|
|
File without changes
|
{reverse_api_engineer-0.4.4 → reverse_api_engineer-0.4.5}/src/reverse_api/playwright_codegen.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|