Move all three skills into skills/; add root README; fix paths

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VasanthandClaude Sonnet 5.5 committed 2026-10-16 17:04:38 +05:30
1 parent 312742cfef
commit d95e5d452d
84 files changed
+97 -31

No files matched your search

@@ -0,0 +1,37 @@
"""PyQt6 host for the AI desktop dashboard: the no-AI Bridge plus one slot for the AI contract.
Copy next to the no-AI bridge.py and bot_runner.py, with server_stub.py and bands.py.
Run it with: python dashboard/ai_bridge.py
The page sends each AI request (templates/contract.md: runs, review rows, the approve gate)
as ai_request(id, method, path, body) and gets one `ai_response` envelope back. The review
backend answers it in Python, so the approve gate holds whatever the page does.
"""
import json, sys, threading
from PyQt6.QtCore import QUrl, pyqtSlot
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWebChannel import QWebChannel
import bridge
import server_stub as review # sample data. Once the project has its own review backend, import that (same dispatch()).
class AiBridge(bridge.Bridge):
@pyqtSlot(int, str, str, str)
def ai_request(self, req_id, method, path, body):
# ponytail: answered on the GUI thread; move to a worker if the backend gets slow.
status, payload = review.dispatch(method, path, json.loads(body or "{}"))
self.send_to_js("ai_response", {"id": req_id, "status": status, "body": payload})
if __name__ == "__main__":
threading.Thread(target=review.simulate_extraction, daemon=True).start() # sample data only: delete with server_stub
app = QApplication(sys.argv)
win, view = QMainWindow(), QWebEngineView()
host, channel = AiBridge(view), QWebChannel()
channel.registerObject("pyBridge", host)
view.page().setWebChannel(channel)
view.setUrl(QUrl.fromLocalFile(str(bridge.HTML_PATH)))
win.setCentralWidget(view); win.resize(1280, 820); win.setWindowTitle("{{APP_NAME}}"); win.show()
sys.exit(app.exec())