previewra 0.1.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.
- previewra-0.1.0/.claude/settings.local.json +104 -0
- previewra-0.1.0/.gitignore +10 -0
- previewra-0.1.0/LICENSE +21 -0
- previewra-0.1.0/PKG-INFO +172 -0
- previewra-0.1.0/README.md +154 -0
- previewra-0.1.0/claude.md +967 -0
- previewra-0.1.0/pyproject.toml +35 -0
- previewra-0.1.0/src/pvr/__init__.py +3 -0
- previewra-0.1.0/src/pvr/ai/__init__.py +0 -0
- previewra-0.1.0/src/pvr/ai/client.py +58 -0
- previewra-0.1.0/src/pvr/ai/config.py +113 -0
- previewra-0.1.0/src/pvr/ai/healer.py +238 -0
- previewra-0.1.0/src/pvr/cli.py +666 -0
- previewra-0.1.0/src/pvr/config.py +67 -0
- previewra-0.1.0/src/pvr/core/__init__.py +0 -0
- previewra-0.1.0/src/pvr/core/context.py +17 -0
- previewra-0.1.0/src/pvr/core/lifecycle.py +16 -0
- previewra-0.1.0/src/pvr/core/session.py +67 -0
- previewra-0.1.0/src/pvr/dashboard/__init__.py +0 -0
- previewra-0.1.0/src/pvr/dashboard/app.py +218 -0
- previewra-0.1.0/src/pvr/dashboard/proxy.py +158 -0
- previewra-0.1.0/src/pvr/dashboard/static/index.html +341 -0
- previewra-0.1.0/src/pvr/dashboard/ws.py +52 -0
- previewra-0.1.0/src/pvr/detector/__init__.py +0 -0
- previewra-0.1.0/src/pvr/detector/base.py +34 -0
- previewra-0.1.0/src/pvr/detector/fastapi_.py +54 -0
- previewra-0.1.0/src/pvr/detector/flask_.py +88 -0
- previewra-0.1.0/src/pvr/detector/node.py +63 -0
- previewra-0.1.0/src/pvr/detector/python_script.py +50 -0
- previewra-0.1.0/src/pvr/detector/react.py +51 -0
- previewra-0.1.0/src/pvr/detector/registry.py +51 -0
- previewra-0.1.0/src/pvr/detector/static.py +24 -0
- previewra-0.1.0/src/pvr/doctor/__init__.py +0 -0
- previewra-0.1.0/src/pvr/doctor/diagnose.py +155 -0
- previewra-0.1.0/src/pvr/i18n/__init__.py +74 -0
- previewra-0.1.0/src/pvr/i18n/locale.py +56 -0
- previewra-0.1.0/src/pvr/i18n/messages/en.json +50 -0
- previewra-0.1.0/src/pvr/i18n/messages/zh_CN.json +50 -0
- previewra-0.1.0/src/pvr/i18n/messages/zh_TW.json +50 -0
- previewra-0.1.0/src/pvr/installer/__init__.py +0 -0
- previewra-0.1.0/src/pvr/installer/base.py +17 -0
- previewra-0.1.0/src/pvr/installer/node.py +35 -0
- previewra-0.1.0/src/pvr/installer/python_.py +61 -0
- previewra-0.1.0/src/pvr/manifest/__init__.py +0 -0
- previewra-0.1.0/src/pvr/manifest/schema.py +92 -0
- previewra-0.1.0/src/pvr/monitor/__init__.py +0 -0
- previewra-0.1.0/src/pvr/monitor/aggregator.py +184 -0
- previewra-0.1.0/src/pvr/monitor/event_bus.py +46 -0
- previewra-0.1.0/src/pvr/monitor/healthcheck.py +62 -0
- previewra-0.1.0/src/pvr/monitor/port_probe.py +56 -0
- previewra-0.1.0/src/pvr/monitor/process_probe.py +31 -0
- previewra-0.1.0/src/pvr/monitor/simulator.py +39 -0
- previewra-0.1.0/src/pvr/runner/__init__.py +0 -0
- previewra-0.1.0/src/pvr/runner/manager.py +40 -0
- previewra-0.1.0/src/pvr/runner/process.py +168 -0
- previewra-0.1.0/src/pvr/runtime/__init__.py +0 -0
- previewra-0.1.0/src/pvr/runtime/history.py +57 -0
- previewra-0.1.0/src/pvr/runtime/snapshot.py +43 -0
- previewra-0.1.0/src/pvr/utils/__init__.py +0 -0
- previewra-0.1.0/src/pvr/utils/log.py +51 -0
- previewra-0.1.0/src/pvr/utils/platform_.py +24 -0
- previewra-0.1.0/src/pvr/utils/port.py +39 -0
- previewra-0.1.0/src/pvr/version.py +1 -0
- previewra-0.1.0/src/pvr/watcher/__init__.py +0 -0
- previewra-0.1.0/src/pvr/watcher/file_watcher.py +64 -0
- previewra-0.1.0/tests/__init__.py +0 -0
- previewra-0.1.0/tests/test_detector.py +151 -0
- previewra-0.1.0/tests/test_doctor.py +160 -0
- previewra-0.1.0/tests/test_healer.py +296 -0
- previewra-0.1.0/tests/test_i18n.py +97 -0
- previewra-0.1.0/tests/test_monitor.py +158 -0
- previewra-0.1.0/tests/test_runner.py +175 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(find /mnt/d/claude-dev/previewra -type f -name \"*.py\" 2>/dev/null | head -20)",
|
|
5
|
+
"Bash(pip install -e . 2>&1)",
|
|
6
|
+
"Bash(python3 -m venv .venv && . .venv/bin/activate && pip install -e \".[dev]\" 2>&1 || . .venv/bin/activate && pip install -e . 2>&1)",
|
|
7
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr --help)",
|
|
8
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr config lang zh-CN)",
|
|
9
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr sessions --help)",
|
|
10
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr preview .)",
|
|
11
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr config lang en && pvr preview .)",
|
|
12
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pip install pytest -q 2>&1 && python -m pytest tests/test_i18n.py -v)",
|
|
13
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && python -m pytest tests/test_detector.py -v 2>&1)",
|
|
14
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr config lang zh-CN && pvr preview . 2>&1)",
|
|
15
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr config lang en && pvr preview /tmp/test-fastapi 2>&1)",
|
|
16
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && python -c \"\nfrom pvr.manifest.schema import Manifest\nm = Manifest.load\\(__import__\\('pathlib'\\).Path\\('/tmp/test-fastapi/.pvr/manifest.json'\\)\\)\nprint\\(m.model_dump_json\\(indent=2\\)\\)\n\")",
|
|
17
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pip install pytest-asyncio -q 2>&1 && python -m pytest tests/test_runner.py -v 2>&1)",
|
|
18
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 10 pvr --lang en preview /tmp/test-fastapi 2>&1; echo \"EXIT CODE: $?\")",
|
|
19
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 12 pvr preview /tmp/test-fastapi --lang en 2>&1; echo \"EXIT CODE: $?\")",
|
|
20
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && python -m pytest tests/ -v 2>&1)",
|
|
21
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && python -m pytest tests/test_monitor.py -v 2>&1)",
|
|
22
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 20 pvr preview /tmp/test-fastapi --lang en 2>&1; echo \"EXIT: $?\")",
|
|
23
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr status /tmp/test-fastapi --lang en 2>&1)",
|
|
24
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 18 pvr preview /tmp/test-fastapi --lang en 2>&1; echo \"EXIT: $?\")",
|
|
25
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pip install websockets -q 2>&1)",
|
|
26
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pip install \"uvicorn[standard]\" 2>&1)",
|
|
27
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 15 bash -c '\npvr preview /tmp/test-fastapi --lang en &\nPVR_PID=$!\nsleep 10\n\n# Test Dashboard APIs\necho \"=== API /api/status ===\"\ncurl -s http://localhost:9000/api/status | python3 -m json.tool | head -5\n\necho \"=== API /api/manifest ===\"\ncurl -s http://localhost:9000/api/manifest | python3 -m json.tool | head -5\n\necho \"=== API /api/i18n ===\"\ncurl -s http://localhost:9000/api/i18n | python3 -m json.tool | head -5\n\necho \"=== Proxy /preview/backend/ ===\"\ncurl -s http://localhost:9000/preview/backend/ | head -1\n\necho \"=== Dashboard HTML ===\"\ncurl -s http://localhost:9000/ | head -3\n\nkill $PVR_PID 2>/dev/null\nwait $PVR_PID 2>/dev/null\n' 2>&1)",
|
|
28
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr doctor /tmp/test-fastapi --lang en 2>&1)",
|
|
29
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr doctor /tmp/test-fastapi --lang zh-CN 2>&1)",
|
|
30
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr doctor /tmp/test-fastapi --json --lang en 2>&1)",
|
|
31
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr sessions list /tmp/test-fastapi --lang en 2>&1)",
|
|
32
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && pvr sessions show 291bcff38aaa /tmp/test-fastapi --lang en 2>&1)",
|
|
33
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 15 pvr watch /tmp/test-fastapi --lang en 2>&1 | head -20; echo \"EXIT: $?\")",
|
|
34
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && timeout 15 pvr watch /tmp/test-fastapi --lang en 2>&1; echo \"EXIT: $?\")",
|
|
35
|
+
"Bash(. /mnt/d/claude-dev/previewra/.venv/bin/activate && python -m pytest tests/ -v --tb=short 2>&1)",
|
|
36
|
+
"Bash(cat <<'EOF'\nComplete File Listing for /mnt/d/claude-dev/previewra\n\nPROJECT ROOT:\nEOF\n\nls -lh /mnt/d/claude-dev/previewra/ | grep -E \"pyproject.toml|README.md|CLAUDE.md|LICENSE\"\n\necho -e \"\\\\nSOURCE STRUCTURE \\(/mnt/d/claude-dev/previewra/src/pvr\\):\"\n\nfind /mnt/d/claude-dev/previewra/src/pvr -type f \\\\\\( -name \"*.py\" -o -name \"*.json\" -o -name \"*.html\" \\\\\\) | grep -v __pycache__ | sort | sed 's|/mnt/d/claude-dev/previewra/src/pvr/||' | awk '{\n module = $0\n sub\\(/\\\\/[^/]*$/, \"\", module\\)\n if \\(module == \"\"\\) module = \"[ROOT]\"\n printf \" %-50s %s\\\\n\", module, $0\n}' | sort\n\necho -e \"\\\\nTEST FILES \\(/mnt/d/claude-dev/previewra/tests\\):\"\nls -1 /mnt/d/claude-dev/previewra/tests/*.py 2>/dev/null | xargs -I {} basename {})",
|
|
37
|
+
"Bash(cat <<'EOF'\n================================================================================\n COMPLETE FILE LISTING & DIRECTORY TREE\n /mnt/d/claude-dev/previewra\n================================================================================\n\nPROJECT STATISTICS:\nEOF\n\necho \" Total Python files: $\\(find /mnt/d/claude-dev/previewra/src/pvr -name \"*.py\" | wc -l\\)\"\necho \" Total Test files: $\\(find /mnt/d/claude-dev/previewra/tests -name \"test_*.py\" 2>/dev/null | wc -l\\)\"\necho \" Total i18n JSON files: $\\(find /mnt/d/claude-dev/previewra/src/pvr/i18n/messages -name \"*.json\" | wc -l\\)\"\n\ncat <<'EOF'\n\n================================================================================\n DIRECTORY TREE\n================================================================================\n\n/mnt/d/claude-dev/previewra/\n├── pyproject.toml\n├── README.md\n├── LICENSE\n├── CLAUDE.md \\(if exists\\)\n│\n├── src/\n│ └── pvr/ ← Main package \\(devpreview renamed to pvr\\)\n│ ├── __init__.py\n│ ├── version.py\n│ ├── cli.py ← CLI entry point \\(Typer app\\)\n│ ├── config.py ← Configuration & constants\n│ │\n│ ├── core/\n│ │ ├── __init__.py\n│ │ ├── context.py ← RuntimeContext dataclass\n│ │ ├── session.py ← SessionManager\n│ │ └── lifecycle.py ← LifecycleState enum\n│ │\n│ ├── detector/\n│ │ ├── __init__.py\n│ │ ├── base.py ← BaseDetector ABC, DetectionResult\n│ │ ├── registry.py ← DetectorRegistry\n│ │ ├── fastapi_.py ← FastAPI detector \\(priority=10\\)\n│ │ ├── flask_.py ← Flask detector \\(priority=20\\)\n│ │ ├── react.py ← React detector \\(priority=30\\)\n│ │ ├── python_script.py ← Python script detector \\(priority=80\\)\n│ │ └── static.py ← Static file detector \\(priority=90\\)\n│ │\n│ ├── installer/\n│ │ ├── __init__.py\n│ │ ├── base.py ← BaseInstaller ABC\n│ │ ├── node.py ← NodeInstaller \\(npm\\)\n│ │ └── python_.py ← PythonInstaller \\(venv + pip\\)\n│ │\n│ ├── runner/\n│ │ ├── __init__.py\n│ │ ├── process.py ← ProcessRunner \\(single service\\)\n│ │ └── manager.py ← RunnerManager \\(multi-service\\)\n│ │\n│ ├── monitor/\n│ │ ├── __init__.py\n│ │ ├── event_bus.py ← EventBus pub/sub system\n│ │ ├── process_probe.py ← Process monitoring \\(psutil\\)\n│ │ ├── port_probe.py ← Port connectivity check\n│ │ ├── healthcheck.py ← Health check engine\n│ │ ├── simulator.py ← GET homepage validation\n│ │ └── aggregator.py ← RuntimeAggregator → RuntimeState\n│ │\n│ ├── dashboard/\n│ │ ├── __init__.py\n│ │ ├── app.py ← FastAPI dashboard server\n│ │ ├── proxy.py ← Reverse proxy handler\n│ │ ├── ws.py ← WebSocket handlers\n│ │ └── static/\n│ │ └── index.html ← Single-file dashboard UI\n│ │\n│ ├── doctor/\n│ │ ├── __init__.py\n│ │ └── diagnose.py ← DiagnosticEngine\n│ │\n│ ├── manifest/\n│ │ ├── __init__.py\n│ │ └── schema.py ← ServiceConfig, Manifest Pydantic models\n│ │\n│ ├── runtime/\n│ │ ├── __init__.py\n│ │ ├── history.py ← Session history CRUD\n│ │ └── snapshot.py ← RuntimeState snapshots\n│ │\n│ ├── watcher/\n│ │ ├── __init__.py\n│ │ └── file_watcher.py ← File change watcher \\(watchdog\\)\n│ │\n│ ├── i18n/ ← Internationalization\n│ │ ├── __init__.py ← T\\(\\), set_locale\\(\\), get_locale\\(\\)\n│ │ ├── locale.py ← Locale detection & persistence\n│ │ └── messages/\n│ │ ├── en.json ← English translations\n│ │ ├── zh_CN.json ← Simplified Chinese translations\n│ │ └── zh_TW.json ← Traditional Chinese translations\n│ │\n│ └── utils/\n│ ├── __init__.py\n│ ├── port.py ← Port utilities \\(is_port_in_use, etc\\)\n│ ├── platform_.py ← WSL detection, browser opening\n│ └── log.py ← Rich console wrapper + log buffer\n│\n└── tests/\n ├── __init__.py\n ├── test_i18n.py ← i18n translation tests\n ├── test_detector.py ← Project detection tests\n ├── test_runner.py ← Process runner tests\n ├── test_monitor.py ← Monitoring system tests\n └── test_doctor.py ← Diagnostic engine tests\n\n================================================================================\n COMPLETE FILE LIST\n================================================================================\n\nPACKAGE ROOT FILES:\n /mnt/d/claude-dev/previewra/pyproject.toml\n /mnt/d/claude-dev/previewra/README.md\n /mnt/d/claude-dev/previewra/LICENSE\n\nSOURCE FILES \\(src/pvr/\\):\n\nCore Package:\n /mnt/d/claude-dev/previewra/src/pvr/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/version.py\n /mnt/d/claude-dev/previewra/src/pvr/cli.py\n /mnt/d/claude-dev/previewra/src/pvr/config.py\n\nCore Module:\n /mnt/d/claude-dev/previewra/src/pvr/core/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/core/context.py\n /mnt/d/claude-dev/previewra/src/pvr/core/session.py\n /mnt/d/claude-dev/previewra/src/pvr/core/lifecycle.py\n\nDetector Module:\n /mnt/d/claude-dev/previewra/src/pvr/detector/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/base.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/registry.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/fastapi_.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/flask_.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/react.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/python_script.py\n /mnt/d/claude-dev/previewra/src/pvr/detector/static.py\n\nInstaller Module:\n /mnt/d/claude-dev/previewra/src/pvr/installer/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/installer/base.py\n /mnt/d/claude-dev/previewra/src/pvr/installer/node.py\n /mnt/d/claude-dev/previewra/src/pvr/installer/python_.py\n\nRunner Module:\n /mnt/d/claude-dev/previewra/src/pvr/runner/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/runner/process.py\n /mnt/d/claude-dev/previewra/src/pvr/runner/manager.py\n\nMonitor Module:\n /mnt/d/claude-dev/previewra/src/pvr/monitor/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/event_bus.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/process_probe.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/port_probe.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/healthcheck.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/simulator.py\n /mnt/d/claude-dev/previewra/src/pvr/monitor/aggregator.py\n\nDashboard Module:\n /mnt/d/claude-dev/previewra/src/pvr/dashboard/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/dashboard/app.py\n /mnt/d/claude-dev/previewra/src/pvr/dashboard/proxy.py\n /mnt/d/claude-dev/previewra/src/pvr/dashboard/ws.py\n /mnt/d/claude-dev/previewra/src/pvr/dashboard/static/index.html\n\nDoctor Module:\n /mnt/d/claude-dev/previewra/src/pvr/doctor/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/doctor/diagnose.py\n\nManifest Module:\n /mnt/d/claude-dev/previewra/src/pvr/manifest/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/manifest/schema.py\n\nRuntime Module:\n /mnt/d/claude-dev/previewra/src/pvr/runtime/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/runtime/history.py\n /mnt/d/claude-dev/previewra/src/pvr/runtime/snapshot.py\n\nWatcher Module:\n /mnt/d/claude-dev/previewra/src/pvr/watcher/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/watcher/file_watcher.py\n\ni18n Module:\n /mnt/d/claude-dev/previewra/src/pvr/i18n/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/i18n/locale.py\n /mnt/d/claude-dev/previewra/src/pvr/i18n/messages/en.json\n /mnt/d/claude-dev/previewra/src/pvr/i18n/messages/zh_CN.json\n /mnt/d/claude-dev/previewra/src/pvr/i18n/messages/zh_TW.json\n\nUtils Module:\n /mnt/d/claude-dev/previewra/src/pvr/utils/__init__.py\n /mnt/d/claude-dev/previewra/src/pvr/utils/log.py\n /mnt/d/claude-dev/previewra/src/pvr/utils/platform_.py\n /mnt/d/claude-dev/previewra/src/pvr/utils/port.py\n\nTEST FILES \\(tests/\\):\n /mnt/d/claude-dev/previewra/tests/__init__.py\n /mnt/d/claude-dev/previewra/tests/test_i18n.py\n /mnt/d/claude-dev/previewra/tests/test_detector.py\n /mnt/d/claude-dev/previewra/tests/test_runner.py\n /mnt/d/claude-dev/previewra/tests/test_monitor.py\n /mnt/d/claude-dev/previewra/tests/test_doctor.py\n\n================================================================================\n MODULE BREAKDOWN\n================================================================================\n\n1. CORE MODULES \\(Architecture\\):\n - core/context.py → RuntimeContext dataclass\n - core/session.py → Session management\n - core/lifecycle.py → State machine enum\n\n2. DETECTION & SETUP \\(Project Recognition\\):\n - detector/base.py → Base detector interface\n - detector/registry.py → Detector orchestration\n - detector/*.py → 5 specific detectors \\(fastapi, flask, react, python_script, static\\)\n - installer/base.py → Base installer interface\n - installer/*.py → 2 installers \\(node, python\\)\n\n3. EXECUTION \\(Process Management\\):\n - runner/process.py → Single process runner\n - runner/manager.py → Multi-process orchestration\n\n4. MONITORING \\(Health & Status\\):\n - monitor/event_bus.py → Pub/sub messaging\n - monitor/process_probe.py → Process metrics \\(psutil\\)\n - monitor/port_probe.py → Port connectivity \\(httpx\\)\n - monitor/healthcheck.py → Health scoring\n - monitor/simulator.py → Functional testing\n - monitor/aggregator.py → State aggregation\n\n5. UI & PRESENTATION \\(Dashboard\\):\n - dashboard/app.py → FastAPI server\n - dashboard/proxy.py → Reverse proxy\n - dashboard/ws.py → WebSocket handlers\n - dashboard/static/index.html → SPA Dashboard\n\n6. DIAGNOSTICS \\(Problem Solving\\):\n - doctor/diagnose.py → Issue detection & suggestions\n\n7. PERSISTENCE \\(Data Storage\\):\n - manifest/schema.py → Service & project definitions\n - runtime/history.py → Session tracking\n - runtime/snapshot.py → State persistence\n\n8. UTILITIES \\(Support\\):\n - utils/log.py → Rich console + buffering\n - utils/port.py → Port availability\n - utils/platform_.py → WSL + browser detection\n - i18n/* → 3-language support \\(EN, ZH-CN, ZH-TW\\)\n\n9. FILE WATCHING:\n - watcher/file_watcher.py → File change detection\n\n10. CLI:\n - cli.py → Typer command dispatcher\n\n================================================================================\n\nTOTAL FILE COUNT:\n - Python source files: 52\n - Test files: 5 \\(+ 1 __init__\\)\n - i18n JSON files: 3\n - HTML/Dashboard: 1\n - Configuration: 1 \\(pyproject.toml\\)\n - Documentation: 2 \\(README.md, LICENSE\\)\n\nTOTAL: ~65 production + test files\n\nEOF)",
|
|
38
|
+
"Bash(/mnt/d/claude-dev/previewra/.venv/bin/pip install --upgrade pip 2>&1)",
|
|
39
|
+
"Bash(.venv/bin/pip install -e . 2>&1)",
|
|
40
|
+
"Bash(.venv/bin/pvr --help 2>&1)",
|
|
41
|
+
"Bash(.venv/bin/pvr config lang zh-CN 2>&1)",
|
|
42
|
+
"Bash(.venv/bin/pvr preview . 2>&1 | head -20)",
|
|
43
|
+
"Bash(find /mnt/d/claude-dev/previewra/src -type f -name \"*.py\" 2>/dev/null | head -30)",
|
|
44
|
+
"Bash(.venv/bin/python -c \"\nfrom pathlib import Path\nfrom pvr.detector.registry import DetectorRegistry\nr = DetectorRegistry\\(\\)\nresults = r.detect\\(Path\\('/mnt/d/claude-dev/curivai'\\)\\)\nfor s in results:\n print\\(f'类型: {s.project_type}'\\)\n print\\(f'名称: {s.name}'\\)\n print\\(f'启动命令: {s.start_command}'\\)\n print\\(f'安装命令: {s.install_command}'\\)\n print\\(f'端口: {s.port}'\\)\n\")",
|
|
45
|
+
"Bash(python -c \"\nfrom pathlib import Path\nfrom pvr.detector.registry import DetectorRegistry\n\nregistry = DetectorRegistry\\(\\)\nresults = registry.detect\\(Path\\('/mnt/d/claude-dev-backup/resona'\\)\\)\nfor svc in results:\n print\\(f'project_type: {svc.project_type}'\\)\n print\\(f'name: {svc.name}'\\)\n print\\(f'start_command: {svc.start_command}'\\)\n print\\(f'install_command: {svc.install_command}'\\)\n print\\(f'port: {svc.port}'\\)\n\")",
|
|
46
|
+
"Bash(pvr --help 2>&1 | head -30)",
|
|
47
|
+
"Bash(pvr config --help 2>&1 && pvr config ai --help 2>&1)",
|
|
48
|
+
"Bash(cd /tmp && pvr config ai set kimi sk-test-key-xxx 2>&1 && cat /tmp/.pvr/config.json 2>&1)",
|
|
49
|
+
"Bash(cd /tmp && pvr config ai show 2>&1)",
|
|
50
|
+
"Bash(python3 -c \"from pvr.ai.config import load_ai_config, save_ai_config, PRESETS, AIConfig; from pvr.ai.client import AIClient; from pvr.ai.healer import AutoHealer, HealingSuggestion; print\\('All AI imports OK'\\); print\\('Presets:', list\\(PRESETS.keys\\(\\)\\)\\)\")",
|
|
51
|
+
"Bash(cd /tmp/test-broken && timeout 60 pvr preview . 2>&1 || true)",
|
|
52
|
+
"Bash(python3 -c \"\nimport asyncio\nfrom pvr.ai.config import AIConfig\nfrom pvr.ai.client import AIClient\n\nasync def test\\(\\):\n cfg = AIConfig\\(\n api_key='sk-TRkkkiqBqyrA27ScZa5Sf22JdkeuM9Xwju6aHZenF6jABIjI',\n base_url='https://api.moonshot.cn/v1',\n model='moonshot-v1-8k',\n \\)\n client = AIClient\\(cfg\\)\n resp = await client.complete\\('Reply with exactly: {\\\\\"status\\\\\": \\\\\"ok\\\\\"}'\\)\n print\\('Response:', resp[:200]\\)\n\nasyncio.run\\(test\\(\\)\\)\n\" 2>&1)",
|
|
53
|
+
"Bash(curl -s --max-time 10 https://api.moonshot.cn/v1/models -H \"Authorization: Bearer sk-TRkkkiqBqyrA27ScZa5Sf22JdkeuM9Xwju6aHZenF6jABIjI\" 2>&1 | head -5)",
|
|
54
|
+
"Bash(curl -v --max-time 10 https://api.moonshot.cn 2>&1 | tail -10)",
|
|
55
|
+
"Bash(echo \"HTTP_PROXY=$HTTP_PROXY HTTPS_PROXY=$HTTPS_PROXY http_proxy=$http_proxy https_proxy=$https_proxy\" && curl -s --max-time 5 https://httpbin.org/ip 2>&1)",
|
|
56
|
+
"Bash(python3 -c \"\nimport asyncio\nimport json\nfrom unittest.mock import AsyncMock, MagicMock, patch\nfrom pathlib import Path\nfrom pvr.ai.healer import AutoHealer, _build_prompt, _extract_json_block\nfrom pvr.ai.config import AIConfig\nfrom pvr.manifest.schema import ServiceConfig\n\n# 1. 测试 JSON 提取\nresp_text = '''\n这里是分析...\n\n\\\\`\\\\`\\\\`json\n{\n \\\\\"analysis\\\\\": \\\\\"missing pandas, add to requirements.txt\\\\\",\n \\\\\"start_command\\\\\": \\\\\"uvicorn app:app --host 0.0.0.0 --port 8000 --reload\\\\\",\n \\\\\"install_command\\\\\": \\\\\"pip install -r requirements.txt\\\\\",\n \\\\\"port\\\\\": 8000,\n \\\\\"env\\\\\": {},\n \\\\\"confidence\\\\\": 0.9\n}\n\\\\`\\\\`\\\\`\n'''\nresult = _extract_json_block\\(resp_text\\)\nassert result is not None, 'JSON extraction failed'\nassert result['confidence'] == 0.9\nassert 'pandas' in result['analysis']\nprint\\('✓ JSON extraction OK:', result['analysis']\\)\n\n# 2. 测试 prompt 构建\nsvc = ServiceConfig\\(name='backend', project_type='fastapi', start_command='uvicorn app:app --port 8000', port=8000\\)\nprompt = _build_prompt\\(Path\\('/tmp'\\), svc, ['ModuleNotFoundError: No module named pandas'], {'app.py': 'from fastapi import FastAPI\\\\nimport pandas'}\\)\nassert 'pandas' in prompt\nassert 'ModuleNotFoundError' in prompt\nprint\\('✓ Prompt building OK, length:', len\\(prompt\\)\\)\n\n# 3. 测试 healer mock(不真实调用 API)\nasync def test_healer_mock\\(\\):\n ai_cfg = AIConfig\\(api_key='sk-fake', base_url='https://api.moonshot.cn/v1', model='moonshot-v1-8k'\\)\n svc = ServiceConfig\\(name='backend', project_type='fastapi', start_command='uvicorn app:app --port 8000', port=8000\\)\n \n mock_state = MagicMock\\(\\)\n mock_state.services = {\n 'backend': MagicMock\\(status='CRASHED'\\)\n }\n mock_runner = MagicMock\\(\\)\n mock_runner.get_recent_logs.return_value = ['ModuleNotFoundError: No module named pandas']\n mock_rm = MagicMock\\(\\)\n mock_rm.get_runner.return_value = mock_runner\n \n mock_response = json.dumps\\({\n 'analysis': 'Add pandas to requirements.txt',\n 'start_command': 'uvicorn app:app --host 0.0.0.0 --port 8000 --reload',\n 'install_command': 'pip install pandas fastapi uvicorn',\n 'port': 8000,\n 'env': {},\n 'confidence': 0.88\n }\\)\n \n with patch\\('pvr.ai.healer.AIClient'\\) as MockClient:\n instance = MockClient.return_value\n instance.complete = AsyncMock\\(return_value=f'\\\\`\\\\`\\\\`json\\\\n{mock_response}\\\\n\\\\`\\\\`\\\\`'\\)\n \n healer = AutoHealer\\(\\)\n result = await healer.heal\\(Path\\('/tmp/test-broken'\\), [svc], mock_rm, mock_state, ai_cfg\\)\n \n assert result is not None, 'healer returned None'\n assert result[0].start_command == 'uvicorn app:app --host 0.0.0.0 --port 8000 --reload'\n assert result[0].install_command == 'pip install pandas fastapi uvicorn'\n print\\('✓ AutoHealer mock test OK'\\)\n print\\(' Fixed start_command:', result[0].start_command\\)\n print\\(' Fixed install_command:', result[0].install_command\\)\n\nasyncio.run\\(test_healer_mock\\(\\)\\)\nprint\\(\\)\nprint\\('所有测试通过 ✓'\\)\n\" 2>&1)",
|
|
57
|
+
"Bash(WSLCONFIG=\"/mnt/c/Users/$\\(cmd.exe /c 'echo %USERNAME%' 2>/dev/null | tr -d '\\\\r'\\)/.wslconfig\"\necho \"Path: $WSLCONFIG\")",
|
|
58
|
+
"Bash(python3 -c \"\nimport sys\nsys.path.insert\\(0, '/mnt/d/claude-dev/previewra/src'\\)\nfrom pvr.monitor.event_bus import EventType\nfrom pvr.runner.process import _PORT_PATTERNS, ProcessRunner\nfrom pvr.dashboard.proxy import proxy_request\nprint\\('EventType.PORT_DISCOVERED =', EventType.PORT_DISCOVERED\\)\nprint\\('Port patterns count:', len\\(_PORT_PATTERNS\\)\\)\n\n# Test each pattern against known log formats\ntest_lines = [\n 'Running on http://127.0.0.1:59210',\n 'Flask server started on http://127.0.0.1:59210',\n 'Uvicorn running on http://0.0.0.0:8000 \\(Press CTRL+C to quit\\)',\n 'Local: http://localhost:5173/',\n 'Listening on http://0.0.0.0:3000',\n 'Listening on port 4000',\n]\nimport re\nfor line in test_lines:\n for p in _PORT_PATTERNS:\n m = p.search\\(line\\)\n if m:\n print\\(f' {line!r:60s} -> port {m.group\\(1\\)}'\\)\n break\n else:\n print\\(f' {line!r:60s} -> NO MATCH'\\)\nprint\\('All imports OK'\\)\n\")",
|
|
59
|
+
"Bash(python3 -c \"\nimport sys\nsys.path.insert\\(0, '/mnt/d/claude-dev/previewra/src'\\)\n# Verify _port_discovered flag exists on ProcessRunner\nfrom pvr.runner.process import ProcessRunner\nfrom pvr.manifest.schema import ServiceConfig\nfrom pvr.monitor.event_bus import EventBus\nfrom pathlib import Path\nsc = ServiceConfig\\(name='backend', project_type='flask', start_command='python app.py', port=5000\\)\nbus = EventBus\\(\\)\nrunner = ProcessRunner\\(sc, bus, Path\\('/tmp'\\)\\)\nprint\\('_port_discovered initial:', runner._port_discovered\\)\nprint\\('service_config.port initial:', runner.service_config.port\\)\n\")",
|
|
60
|
+
"Bash(find /mnt/d/claude-dev/previewra/src/pvr/i18n -name \"*.json\" | xargs ls)",
|
|
61
|
+
"Bash(grep -l \"ai_healing\\\\|ai_no_key\\\\|ai_config\" /mnt/d/claude-dev/previewra/src/pvr/i18n/messages/*.json)",
|
|
62
|
+
"Bash(python3 -c \"\nimport json, sys\nsys.path.insert\\(0, '/mnt/d/claude-dev/previewra/src'\\)\n\n# Check which AI keys exist in each file\nai_keys = [\n 'ai_healing_start', 'ai_healing_attempt', 'ai_healing_success',\n 'ai_healing_failed', 'ai_no_key', 'ai_config_show', 'ai_config_saved',\n]\n\nfor locale in ['en', 'zh_CN', 'zh_TW']:\n path = f'/mnt/d/claude-dev/previewra/src/pvr/i18n/messages/{locale}.json'\n data = json.load\\(open\\(path\\)\\)\n missing = [k for k in ai_keys if k not in data]\n present = [k for k in ai_keys if k in data]\n print\\(f'{locale}: present={len\\(present\\)}, missing={missing}'\\)\n\")",
|
|
63
|
+
"Bash(python3 -c \"\nimport sys\nsys.path.insert\\(0, '/mnt/d/claude-dev/previewra/src'\\)\nfrom pvr.dashboard.app import create_dashboard_app, _heal_background\nfrom pvr.i18n import T, set_locale\n\n# Verify API endpoint exists\nimport inspect\nsrc = inspect.getsource\\(create_dashboard_app\\)\nassert '/api/heal' in src, 'Missing /api/heal'\nprint\\('OK: /api/heal endpoint present'\\)\n\n# Verify _heal_background exists and references key symbols\nsrc2 = inspect.getsource\\(_heal_background\\)\nassert 'AutoHealer' in src2\nassert 'stop_all' in src2\nassert 'start_all' in src2\nassert 'stop_periodic_check' in src2\nprint\\('OK: _heal_background logic complete'\\)\n\n# Verify i18n keys in all locales\nfor locale, code in [\\('zh-CN','zh_CN'\\), \\('zh-TW','zh_TW'\\), \\('en','en'\\)]:\n set_locale\\(locale\\)\n for key in ['btn_ai_heal', 'ai_heal_started', 'ai_heal_healthy', 'ai_heal_no_key']:\n val = T\\(key\\)\n assert val != key, f'Missing key {key} in {locale}'\n print\\(f'OK: {locale} i18n keys present'\\)\n\")",
|
|
64
|
+
"Bash(python -c \"from pvr.dashboard.proxy import proxy_request; print\\('Proxy module imports OK'\\)\")",
|
|
65
|
+
"Bash(/mnt/d/claude-dev/previewra/.venv/bin/python -c \"from pvr.dashboard.proxy import proxy_request; print\\('Proxy module imports OK'\\)\")",
|
|
66
|
+
"Bash(.venv/bin/python -c \"from pvr.cli import app; print\\('CLI module loads OK'\\)\")",
|
|
67
|
+
"Bash(timeout 30 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 || true)",
|
|
68
|
+
"Bash(timeout 60 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 || true)",
|
|
69
|
+
"Bash(fuser -k 59211/tcp 2>/dev/null; sleep 1\n\ncd /mnt/d/claude-dev-backup/resona && .venv/bin/python -c \"\nimport sys, os\nsys.path.insert\\(0, '.'\\)\nfrom core.database import init_db\ninit_db\\(\\)\nfrom routes import create_app\napp = create_app\\(\\)\nimport threading, time\nt = threading.Thread\\(target=lambda: app.run\\(host='127.0.0.1', port=59211, debug=False, use_reloader=False\\), daemon=True\\)\nt.start\\(\\)\ntime.sleep\\(3\\)\n# Use curl-like approach to see response\nimport http.client\nconn = http.client.HTTPConnection\\('127.0.0.1', 59211\\)\nconn.request\\('GET', '/'\\)\nr = conn.getresponse\\(\\)\nprint\\('STATUS:', r.status, r.reason\\)\nprint\\('HEADERS:', dict\\(r.getheaders\\(\\)\\)\\)\nbody = r.read\\(\\).decode\\('utf-8', errors='ignore'\\)[:3000]\nprint\\('BODY:', body\\)\n\" 2>&1)",
|
|
70
|
+
"Bash(.venv/bin/python -c \"from pvr.dashboard.proxy import proxy_request, _rewrite_html; print\\('Proxy module loads OK'\\)\")",
|
|
71
|
+
"Bash(.venv/bin/python -c \"\nfrom pvr.dashboard.proxy import _rewrite_html\n\nhtml = b'''<html><head><title>Test</title></head><body>\n<link href=\\\\\"/static/css/main.css\\\\\" rel=\\\\\"stylesheet\\\\\">\n<img src=\\\\\"/static/img/logo.svg\\\\\">\n<a href=\\\\\"/api/feeds\\\\\">feeds</a>\n<script>fetch\\('/api/data'\\)</script>\n</body></html>'''\n\nresult = _rewrite_html\\(html, 'backend'\\).decode\\(\\)\nprint\\(result[:1000]\\)\n\")",
|
|
72
|
+
"Bash(timeout 45 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 || true)",
|
|
73
|
+
"Bash(echo \"HTTP_PROXY=$HTTP_PROXY\"\necho \"HTTPS_PROXY=$HTTPS_PROXY\"\necho \"ALL_PROXY=$ALL_PROXY\"\necho \"http_proxy=$http_proxy\"\necho \"https_proxy=$https_proxy\"\necho \"no_proxy=$no_proxy\"\necho \"NO_PROXY=$NO_PROXY\")",
|
|
74
|
+
"Bash(fuser -k 59210/tcp 2>/dev/null; fuser -k 9000/tcp 2>/dev/null; sleep 1)",
|
|
75
|
+
"Bash(timeout 50 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 || true)",
|
|
76
|
+
"Bash(fuser -k 59210/tcp 2>/dev/null; fuser -k 9000/tcp 2>/dev/null; sleep 1\ntimeout 50 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 | head -40)",
|
|
77
|
+
"Bash(fuser -k 59210/tcp 2>/dev/null\nfuser -k 9000/tcp 2>/dev/null\nsleep 1)",
|
|
78
|
+
"Bash(timeout 50 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 | head -25)",
|
|
79
|
+
"Bash(fuser -k 59210/tcp 2>/dev/null; sleep 1)",
|
|
80
|
+
"Bash(timeout 55 .venv/bin/pvr preview /mnt/d/claude-dev-backup/resona --lang en 2>&1 | grep -v \"^backend \" | head -20)",
|
|
81
|
+
"Bash(fuser -k 59210/tcp 2>/dev/null; fuser -k 9000/tcp 2>/dev/null; sleep 2)",
|
|
82
|
+
"Bash(python -c \"from pvr.ai.config import PRESETS, AIConfig, get_available_models; print\\('PRESETS ok:', list\\(PRESETS.keys\\(\\)\\)\\); print\\('models:', PRESETS['kimi']['models']\\); print\\('AIConfig fields:', list\\(AIConfig.model_fields.keys\\(\\)\\)\\)\")",
|
|
83
|
+
"Bash(python3 -c \"from pvr.ai.config import PRESETS, AIConfig, get_available_models; print\\('PRESETS ok:', list\\(PRESETS.keys\\(\\)\\)\\); print\\('kimi models:', PRESETS['kimi']['models']\\); print\\('AIConfig fields:', list\\(AIConfig.model_fields.keys\\(\\)\\)\\)\")",
|
|
84
|
+
"Bash(PYTHONPATH=src python3 -c \"from pvr.ai.config import PRESETS, AIConfig, get_available_models; print\\('PRESETS ok:', list\\(PRESETS.keys\\(\\)\\)\\); print\\('kimi models:', PRESETS['kimi']['models']\\); print\\('AIConfig fields:', list\\(AIConfig.model_fields.keys\\(\\)\\)\\)\")",
|
|
85
|
+
"Bash(PYTHONPATH=src python3 -c \"\nimport ast, json\n\n# Verify config.py parses correctly\nwith open\\('src/pvr/ai/config.py'\\) as f:\n ast.parse\\(f.read\\(\\)\\)\nprint\\('config.py: syntax OK'\\)\n\n# Verify cli.py parses correctly\nwith open\\('src/pvr/cli.py'\\) as f:\n ast.parse\\(f.read\\(\\)\\)\nprint\\('cli.py: syntax OK'\\)\n\n# Verify dashboard app.py parses correctly\nwith open\\('src/pvr/dashboard/app.py'\\) as f:\n ast.parse\\(f.read\\(\\)\\)\nprint\\('dashboard/app.py: syntax OK'\\)\n\n# Verify all 3 JSON files parse\nfor lang in ['en', 'zh_CN', 'zh_TW']:\n path = f'src/pvr/i18n/messages/{lang}.json'\n with open\\(path\\) as f:\n d = json.load\\(f\\)\n assert 'ai_model_switched' in d, f'{lang} missing ai_model_switched'\n assert 'ai_model_list' in d, f'{lang} missing ai_model_list'\n print\\(f'{lang}.json: OK \\({len\\(d\\)} keys\\)'\\)\n\n# Verify HTML parses \\(at least check for key elements\\)\nwith open\\('src/pvr/dashboard/static/index.html'\\) as f:\n html = f.read\\(\\)\nassert 'modelSelect' in html, 'missing modelSelect'\nassert 'loadModels' in html, 'missing loadModels'\nassert '/api/ai/model/' in html, 'missing API call'\nprint\\('index.html: OK'\\)\n\")",
|
|
86
|
+
"Bash(git init && git status)",
|
|
87
|
+
"Bash(git add .gitignore LICENSE README.md claude.md pyproject.toml src/ tests/ && git status)",
|
|
88
|
+
"Bash(git commit -m \"$\\(cat <<'EOF'\nfeat: initial project + refine AI self-fix scope and copy\n\n- Add full previewra project skeleton \\(detector, runner, monitor, dashboard, i18n, etc.\\)\n- Rewrite AI healer as self-correction module: only fixes previewra's own\n detection mistakes \\(start_command, port, install_command, env\\); will not\n touch user application code\n- Add cannot_fix path: when AI determines root cause is in user code, emit\n localized warning and skip without modifying config\n- Narrow /api/heal trigger to CRASHED/FAILED only \\(exclude DEGRADED, which\n indicates a user-side HTTP error\\)\n- Update Dashboard button label and tooltip to reflect new scope \\(AI Self-Fix\\)\n- Add ai_heal_cannot_fix i18n key in en/zh_CN/zh_TW\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
89
|
+
"Bash(.venv/bin/python -m pytest --collect-only 2>&1 | head -40)",
|
|
90
|
+
"Bash(.venv/bin/python -m pytest tests/test_healer.py -v 2>&1)",
|
|
91
|
+
"Bash(git add tests/test_healer.py && git commit -m \"$\\(cat <<'EOF'\ntest: add test_healer.py covering AI self-fix flow\n\n20 tests across three layers:\n- _collect_project_context: verifies source code content is never sent to AI,\n only config file contents + file name listing\n- _build_prompt: verifies scope restrictions and cannot_fix docs are present\n- AutoHealer.heal\\(\\): covers fix applied, port/env corrected, cannot_fix path,\n i18n log message, low confidence skip, DEGRADED/HEALTHY skip, AI failure,\n unparseable response, and multi-service isolation\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
92
|
+
"Bash(gh auth status 2>&1)",
|
|
93
|
+
"Bash(gh repo create previewra --public --source=. --remote=origin --push 2>&1)",
|
|
94
|
+
"Bash(git add README.md && git commit -m \"$\\(cat <<'EOF'\ndocs: rewrite README with full project intro and usage\n\nAdd project background, quick start, command reference, Dashboard overview,\nAI Self-Fix scope explanation, supported project types table, and\nlanguage/AI provider configuration examples.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\nEOF\n\\)\" && git push)",
|
|
95
|
+
"Bash(git add README.md && git commit -m \"docs: add GitHub stars badge to README\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\" && git push)",
|
|
96
|
+
"Bash(git add README.md && git commit -m \"docs: add MIT license badge to README\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\" && git push)",
|
|
97
|
+
"Bash(git add README.md && git commit -m \"docs: add Python version badge to README\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\" && git push)",
|
|
98
|
+
"Bash(git add README.md && git commit -m \"docs: add PyPI version badge to README\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\" && git push)",
|
|
99
|
+
"Bash(pip show twine build 2>&1 | grep -E \"^Name|not found\" ; .venv/bin/pip show twine build 2>&1 | grep -E \"^Name|not found\")",
|
|
100
|
+
"Bash(.venv/bin/pip install build twine -q && echo \"done\")",
|
|
101
|
+
"Bash(.venv/bin/python -m build 2>&1)"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}
|
previewra-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Previewra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
previewra-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: previewra
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-native Runtime OS Layer — instant preview for AI-coded projects
|
|
5
|
+
Author: previewra
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: fastapi>=0.104.0
|
|
10
|
+
Requires-Dist: httpx>=0.25.0
|
|
11
|
+
Requires-Dist: psutil>=5.9.0
|
|
12
|
+
Requires-Dist: pydantic>=2.0.0
|
|
13
|
+
Requires-Dist: rich>=13.0.0
|
|
14
|
+
Requires-Dist: typer>=0.9.0
|
|
15
|
+
Requires-Dist: uvicorn[standard]>=0.24.0
|
|
16
|
+
Requires-Dist: watchdog>=3.0.0
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# Previewra (pvr)
|
|
20
|
+
|
|
21
|
+
[](https://github.com/wangjun3862/previewra/stargazers)
|
|
22
|
+
[](https://github.com/wangjun3862/previewra/blob/main/LICENSE)
|
|
23
|
+
[](https://www.python.org/)
|
|
24
|
+
[](https://pypi.org/project/previewra/)
|
|
25
|
+
|
|
26
|
+
**AI-native Runtime OS Layer — instant preview for AI-coded projects.**
|
|
27
|
+
|
|
28
|
+
AI 编写的代码往往缺少运行说明。Previewra 自动检测项目类型、安装依赖、启动服务,并通过 Web Dashboard 实时预览,让 AI 生成的项目开箱即用。
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- **Zero-config launch** — 自动识别 FastAPI / Flask / React / Vite / 静态站 / Python 脚本
|
|
35
|
+
- **Auto install** — 自动执行 `pip install` 或 `npm install`
|
|
36
|
+
- **Real-time dashboard** — 内置 Web 面板,含服务状态、日志流、反向代理预览
|
|
37
|
+
- **AI Self-Fix** — 服务启动失败时,AI 自动检查并修正 previewra 自身的检测配置(不修改你的代码)
|
|
38
|
+
- **Doctor** — 诊断引擎,输出结构化故障报告
|
|
39
|
+
- **File watcher** — 文件变化后自动刷新服务
|
|
40
|
+
- **Session history** — 记录每次运行的会话,支持查询历史
|
|
41
|
+
- **Tri-language** — 简体中文 / 繁体中文 / English
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
**要求:** Python ≥ 3.10
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install previewra
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
开发模式安装(本地源码):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/wangjun3862/previewra.git
|
|
57
|
+
cd previewra
|
|
58
|
+
pip install -e .
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# 进入你的项目目录,一键启动
|
|
67
|
+
pvr preview .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Previewra 会自动完成:检测 → 安装依赖 → 启动服务 → 打开 Dashboard → 浏览器预览。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Commands
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pvr preview <path> # 检测 + 安装 + 启动 + 打开 Dashboard
|
|
78
|
+
pvr watch <path> # 同上,并监听文件变化自动刷新
|
|
79
|
+
pvr status <path> # 输出当前 RuntimeState JSON
|
|
80
|
+
pvr doctor <path> # 诊断报告(加 --json 输出纯 JSON)
|
|
81
|
+
pvr stop <path> # 优雅停止所有服务
|
|
82
|
+
pvr refresh <path> # 重新检测并热重启
|
|
83
|
+
|
|
84
|
+
pvr sessions list # 列出历史会话
|
|
85
|
+
pvr sessions show <session_id> # 查看某次会话详情
|
|
86
|
+
|
|
87
|
+
pvr config lang <locale> # 设置语言(zh-CN / zh-TW / en)
|
|
88
|
+
pvr config ai set <preset> <api-key> # 配置 AI 自检修复
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
全局选项 `--lang` 可临时切换语言:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pvr --lang en preview .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Dashboard
|
|
100
|
+
|
|
101
|
+
服务启动后,Dashboard 自动在浏览器打开(默认 `http://localhost:18080`)。
|
|
102
|
+
|
|
103
|
+
| 区域 | 说明 |
|
|
104
|
+
|---|---|
|
|
105
|
+
| 服务标签页 | 多服务切换,实时状态徽章 |
|
|
106
|
+
| 指标行 | CPU / 内存 / Uptime / 端口 / 响应时间 |
|
|
107
|
+
| 预览 iframe | 通过内置反向代理展示你的应用 |
|
|
108
|
+
| 日志区 | WebSocket 实时日志流 |
|
|
109
|
+
| AI Self-Fix | 一键让 AI 修正 previewra 的检测失误 |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## AI Self-Fix
|
|
114
|
+
|
|
115
|
+
当服务状态为 **CRASHED** 或 **FAILED** 时,点击 Dashboard 的 **AI Self-Fix** 按钮:
|
|
116
|
+
|
|
117
|
+
1. AI 分析启动日志 + 项目配置文件(requirements.txt、package.json 等)
|
|
118
|
+
2. 判断是否为 previewra 自身的检测失误(错误的启动命令、端口、缺失 flag 等)
|
|
119
|
+
3. 若是 → 自动修正配置并热重启服务,**不修改你的任何代码**
|
|
120
|
+
4. 若根因在用户代码 → 在日志区提示"超出 previewra 的修复范围",由开发者处理
|
|
121
|
+
|
|
122
|
+
配置 AI 提供商(支持 OpenAI / Kimi / DeepSeek / Qwen / Gemini / Anthropic):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pvr config ai set openai sk-xxxx
|
|
126
|
+
pvr config ai set kimi <moonshot-api-key>
|
|
127
|
+
pvr config ai set deepseek <deepseek-api-key>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
或通过环境变量:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
export PVR_AI_API_KEY=sk-xxxx
|
|
134
|
+
export PVR_AI_BASE_URL=https://api.openai.com/v1
|
|
135
|
+
export PVR_AI_MODEL=gpt-4o-mini
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Supported Project Types
|
|
141
|
+
|
|
142
|
+
| 类型 | 检测条件 | 默认端口 |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| FastAPI | `.py` 文件含 `from fastapi` / `import fastapi` | 8000 |
|
|
145
|
+
| Flask | `.py` 文件含 `from flask` / `import flask` | 5000 |
|
|
146
|
+
| React (Vite) | `package.json` 含 `vite` 依赖 | 5173 |
|
|
147
|
+
| React (CRA) | `package.json` 含 `react` 依赖 | 3000 |
|
|
148
|
+
| Python Script | 存在 `main.py` / `app.py` | — |
|
|
149
|
+
| Static | 存在 `index.html` | 8080 |
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Language Support
|
|
154
|
+
|
|
155
|
+
| 语言 | locale |
|
|
156
|
+
|---|---|
|
|
157
|
+
| English | `en` |
|
|
158
|
+
| 简体中文 | `zh-CN` |
|
|
159
|
+
| 繁体中文 | `zh-TW` |
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pvr config lang zh-CN # 持久化设置
|
|
163
|
+
pvr --lang en preview . # 单次覆盖
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Dashboard 语言通过右上角下拉框切换,实时生效。
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Previewra (pvr)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/wangjun3862/previewra/stargazers)
|
|
4
|
+
[](https://github.com/wangjun3862/previewra/blob/main/LICENSE)
|
|
5
|
+
[](https://www.python.org/)
|
|
6
|
+
[](https://pypi.org/project/previewra/)
|
|
7
|
+
|
|
8
|
+
**AI-native Runtime OS Layer — instant preview for AI-coded projects.**
|
|
9
|
+
|
|
10
|
+
AI 编写的代码往往缺少运行说明。Previewra 自动检测项目类型、安装依赖、启动服务,并通过 Web Dashboard 实时预览,让 AI 生成的项目开箱即用。
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Zero-config launch** — 自动识别 FastAPI / Flask / React / Vite / 静态站 / Python 脚本
|
|
17
|
+
- **Auto install** — 自动执行 `pip install` 或 `npm install`
|
|
18
|
+
- **Real-time dashboard** — 内置 Web 面板,含服务状态、日志流、反向代理预览
|
|
19
|
+
- **AI Self-Fix** — 服务启动失败时,AI 自动检查并修正 previewra 自身的检测配置(不修改你的代码)
|
|
20
|
+
- **Doctor** — 诊断引擎,输出结构化故障报告
|
|
21
|
+
- **File watcher** — 文件变化后自动刷新服务
|
|
22
|
+
- **Session history** — 记录每次运行的会话,支持查询历史
|
|
23
|
+
- **Tri-language** — 简体中文 / 繁体中文 / English
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
**要求:** Python ≥ 3.10
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install previewra
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
开发模式安装(本地源码):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/wangjun3862/previewra.git
|
|
39
|
+
cd previewra
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 进入你的项目目录,一键启动
|
|
49
|
+
pvr preview .
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Previewra 会自动完成:检测 → 安装依赖 → 启动服务 → 打开 Dashboard → 浏览器预览。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pvr preview <path> # 检测 + 安装 + 启动 + 打开 Dashboard
|
|
60
|
+
pvr watch <path> # 同上,并监听文件变化自动刷新
|
|
61
|
+
pvr status <path> # 输出当前 RuntimeState JSON
|
|
62
|
+
pvr doctor <path> # 诊断报告(加 --json 输出纯 JSON)
|
|
63
|
+
pvr stop <path> # 优雅停止所有服务
|
|
64
|
+
pvr refresh <path> # 重新检测并热重启
|
|
65
|
+
|
|
66
|
+
pvr sessions list # 列出历史会话
|
|
67
|
+
pvr sessions show <session_id> # 查看某次会话详情
|
|
68
|
+
|
|
69
|
+
pvr config lang <locale> # 设置语言(zh-CN / zh-TW / en)
|
|
70
|
+
pvr config ai set <preset> <api-key> # 配置 AI 自检修复
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
全局选项 `--lang` 可临时切换语言:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pvr --lang en preview .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Dashboard
|
|
82
|
+
|
|
83
|
+
服务启动后,Dashboard 自动在浏览器打开(默认 `http://localhost:18080`)。
|
|
84
|
+
|
|
85
|
+
| 区域 | 说明 |
|
|
86
|
+
|---|---|
|
|
87
|
+
| 服务标签页 | 多服务切换,实时状态徽章 |
|
|
88
|
+
| 指标行 | CPU / 内存 / Uptime / 端口 / 响应时间 |
|
|
89
|
+
| 预览 iframe | 通过内置反向代理展示你的应用 |
|
|
90
|
+
| 日志区 | WebSocket 实时日志流 |
|
|
91
|
+
| AI Self-Fix | 一键让 AI 修正 previewra 的检测失误 |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## AI Self-Fix
|
|
96
|
+
|
|
97
|
+
当服务状态为 **CRASHED** 或 **FAILED** 时,点击 Dashboard 的 **AI Self-Fix** 按钮:
|
|
98
|
+
|
|
99
|
+
1. AI 分析启动日志 + 项目配置文件(requirements.txt、package.json 等)
|
|
100
|
+
2. 判断是否为 previewra 自身的检测失误(错误的启动命令、端口、缺失 flag 等)
|
|
101
|
+
3. 若是 → 自动修正配置并热重启服务,**不修改你的任何代码**
|
|
102
|
+
4. 若根因在用户代码 → 在日志区提示"超出 previewra 的修复范围",由开发者处理
|
|
103
|
+
|
|
104
|
+
配置 AI 提供商(支持 OpenAI / Kimi / DeepSeek / Qwen / Gemini / Anthropic):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pvr config ai set openai sk-xxxx
|
|
108
|
+
pvr config ai set kimi <moonshot-api-key>
|
|
109
|
+
pvr config ai set deepseek <deepseek-api-key>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
或通过环境变量:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
export PVR_AI_API_KEY=sk-xxxx
|
|
116
|
+
export PVR_AI_BASE_URL=https://api.openai.com/v1
|
|
117
|
+
export PVR_AI_MODEL=gpt-4o-mini
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Supported Project Types
|
|
123
|
+
|
|
124
|
+
| 类型 | 检测条件 | 默认端口 |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| FastAPI | `.py` 文件含 `from fastapi` / `import fastapi` | 8000 |
|
|
127
|
+
| Flask | `.py` 文件含 `from flask` / `import flask` | 5000 |
|
|
128
|
+
| React (Vite) | `package.json` 含 `vite` 依赖 | 5173 |
|
|
129
|
+
| React (CRA) | `package.json` 含 `react` 依赖 | 3000 |
|
|
130
|
+
| Python Script | 存在 `main.py` / `app.py` | — |
|
|
131
|
+
| Static | 存在 `index.html` | 8080 |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Language Support
|
|
136
|
+
|
|
137
|
+
| 语言 | locale |
|
|
138
|
+
|---|---|
|
|
139
|
+
| English | `en` |
|
|
140
|
+
| 简体中文 | `zh-CN` |
|
|
141
|
+
| 繁体中文 | `zh-TW` |
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pvr config lang zh-CN # 持久化设置
|
|
145
|
+
pvr --lang en preview . # 单次覆盖
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Dashboard 语言通过右上角下拉框切换,实时生效。
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|