delqhi commited on
Commit
3cd6080
·
verified ·
1 Parent(s): 8aef5d5

Deploy SIN-Code-AI live surfaces

Browse files
.github/workflows/ci.yml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Agent CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ build-and-verify:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Setup Node
17
+ uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '22'
20
+ cache: npm
21
+
22
+ - name: Install dependencies
23
+ run: npm install
24
+
25
+ - name: Build
26
+ run: npm run build
27
+
28
+ - name: Print card
29
+ run: node dist/src/cli.js print-card
30
+
31
+ - name: Agent help
32
+ run: node dist/src/cli.js run-action '{"action":"agent.help"}'
33
+
34
+ - name: Agent health
35
+ run: node dist/src/cli.js run-action '{"action":"sin.code.ai.health"}'
.github/workflows/deploy-huggingface-space.yml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Deploy Hugging Face Space
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ deploy:
10
+ if: ${{ secrets.HF_TOKEN != '' }}
11
+ runs-on: ubuntu-latest
12
+ env:
13
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
14
+ HF_SPACE_REPO_ID: delqhi/sin-code-ai
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: '3.11'
23
+
24
+ - name: Install deployment dependencies
25
+ run: pip install huggingface_hub
26
+
27
+ - name: Create or ensure Hugging Face Space
28
+ run: |
29
+ python - <<'PY'
30
+ import os
31
+ from huggingface_hub import HfApi
32
+
33
+ repo_id = os.environ["HF_SPACE_REPO_ID"].strip()
34
+ if not repo_id:
35
+ raise SystemExit("HF_SPACE_REPO_ID missing")
36
+
37
+ api = HfApi(token=os.environ["HF_TOKEN"])
38
+ api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="docker", exist_ok=True)
39
+ PY
40
+
41
+ - name: Push repository contents to Hugging Face Space
42
+ run: |
43
+ set -euo pipefail
44
+ git config --global user.name "GitHub Actions"
45
+ git config --global user.email "actions@github.com"
46
+ git clone "https://oauth2:${HF_TOKEN}@huggingface.co/spaces/delqhi/sin-code-ai" hf-space
47
+ rsync -a --delete --exclude ".git/" --exclude ".github/" --exclude "node_modules/" --exclude "dist/" ./ hf-space/
48
+ cd hf-space
49
+ git add .
50
+ git commit -m "Deploy SIN-Code-AI from GitHub Actions" || true
51
+ git push origin main
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ dist
2
+ node_modules
3
+ *.log
4
+ .env
5
+ .env.local
6
+ .DS_Store
7
+ .sin/artifacts/
.sin/doctor.config.yaml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repo: a2a-sin-agent-template
2
+ checks:
3
+ - required-config-present
4
+ - workspace-clean-enough
5
+ - required-files-present
6
+ - env-contract-present
7
+ - build-command-exists
8
+ - tests-command-exists
9
+ - runtime-command-exists
10
+ - complete-install-present
11
+ - health-surface-present
12
+ required_files:
13
+ - README.md
14
+ - package.json
15
+ - src/runtime.ts
16
+ - src/mcp-server.ts
17
+ - scripts/complete-install.sh
18
+ - scripts/hf_pull_script.py
19
+ env_contract_files:
20
+ - .env.example
21
+ commands:
22
+ build:
23
+ - npm run build
24
+ tests:
25
+ - npm run typecheck
26
+ runtime:
27
+ - npm run start:mcp
28
+ - npm run start:a2a
29
+ verify:
30
+ - node dist/src/cli.js print-card
31
+ health_files:
32
+ - agent.json
33
+ - src/runtime.ts
34
+ launchagent_files: []
.sin/policies.local.yaml ADDED
@@ -0,0 +1 @@
 
 
1
+ waivers: {}
.sin/preflight.config.yaml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ profiles:
2
+ local-change:
3
+ required_checks:
4
+ - required-config-present
5
+ - required-files-present
6
+ - env-contract-present
7
+ - build-command-exists
8
+ - complete-install-present
9
+ - health-surface-present
10
+ run_commands: []
11
+ pull-request:
12
+ required_checks:
13
+ - required-config-present
14
+ - required-files-present
15
+ - env-contract-present
16
+ - build-command-exists
17
+ - tests-command-exists
18
+ - complete-install-present
19
+ - health-surface-present
20
+ run_commands:
21
+ - build
22
+ - tests
.well-known/agent-card.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "SIN-Code-AI",
3
+ "description": "Elite 2026 AI Engineering Architect. Architects and implements RAG pipelines, prompt templates, semantic search, OpenCode MCP tools, and AI-native application logic.",
4
+ "version": "2026.03.09",
5
+ "documentationUrl": "http://127.0.0.1:8000",
6
+ "url": "http://127.0.0.1:8000/a2a/v1",
7
+ "capabilities": {
8
+ "streaming": false,
9
+ "pushNotifications": false
10
+ },
11
+ "defaultInputModes": [
12
+ "text/plain",
13
+ "application/json"
14
+ ],
15
+ "defaultOutputModes": [
16
+ "text/plain",
17
+ "application/json"
18
+ ],
19
+ "metadata": {
20
+ "projectionMode": "control-plane-first",
21
+ "capabilityRegistry": "control_plane.capabilities",
22
+ "executorContract": "services/workers/hf_executor_contract.json"
23
+ },
24
+ "skills": [
25
+ {
26
+ "id": "sin.code.ai.health",
27
+ "name": "Health",
28
+ "description": "Check base agent readiness and identity."
29
+ },
30
+ {
31
+ "id": "sin.code.ai.onboarding.status",
32
+ "name": "Onboarding Status",
33
+ "description": "Read persisted onboarding state."
34
+ },
35
+ {
36
+ "id": "sin.code.ai.onboarding.save",
37
+ "name": "Onboarding Save",
38
+ "description": "Persist onboarding defaults for future autonomous runs."
39
+ },
40
+ {
41
+ "id": "sin.code.ai.room13.claim",
42
+ "name": "Room-13 Claim",
43
+ "description": "Register worker and claim next task from Room-13 coordinator."
44
+ }
45
+ ],
46
+ "supportedInterfaces": [
47
+ {
48
+ "url": "http://127.0.0.1:8000/a2a/v1",
49
+ "protocolBinding": "JSONRPC",
50
+ "protocolVersion": "1.0"
51
+ }
52
+ ]
53
+ }
.well-known/oauth-client.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "client_id": "https://delqhi-sin-code-ai.hf.space/.well-known/oauth-client.json",
3
+ "client_name": "SIN-Code-AI",
4
+ "redirect_uris": ["https://delqhi-sin-code-ai.hf.space/oauth/callback"],
5
+ "grant_types": ["authorization_code"],
6
+ "response_types": ["code"],
7
+ "token_endpoint_auth_method": "none"
8
+ }
9
+
A2A-CARD.md ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # A2A Card: SIN-Code-AI
2
+
3
+ ## Identitaet
4
+
5
+ - `A2A Bezeichnung`: `SIN-Code-AI`
6
+ - `Name`: `SIN-Code-AI`
7
+ - `Beschreibung (Zweck)`: Elite 2026 AI Engineering Architect. Architects and implements RAG pipelines, prompt templates, semantic search, OpenCode MCP tools, and AI-native application logic.
8
+ - `Verwendung`: Use for designing LLM prompts, implementing local and cloud-based AI pipelines, writing semantic search logic, building RAG architectures, and authoring OpenCode skills/tools.
9
+ - `CIMD`: `https://delqhi-sin-code-ai.hf.space`
10
+
11
+ ## Team & Infrastruktur
12
+
13
+ - `A2A Team`: `Team - Coding`
14
+ - `Team-Manager A2A`: `SIN-Coding-CEO`
15
+ - `VM / Server`: `Hugging Face Space free CPU VM`
16
+ - `Deployment Status`: `structural-only scaffold; HF runtime and landing deployment pending`
17
+ - `Lokales Verzeichnis`: `/Users/jeremy/dev/OpenSIN-backend/a2a/team-coding/A2A-SIN-Code-AI`
18
+ - `Hugging Face Space URL`: `https://huggingface.co/spaces/delqhi/sin-code-ai` (reserved; deployment pending)
19
+ - `Landingpage URL`: `https://delqhi-sin-code-ai.hf.space` (reserved; deployment pending)
20
+ - `Cloudflare Tunnel`: `sin-code-ai`
21
+ - `Workforce Ziel-Index`: `https://a2a.delqhi.com/`
22
+ - `Google Doc Root`: `https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit`
23
+ - `Dedicated Docs Child-Tab`: `pending dedicated child-tab under Team - Coding (tabId: t.71rk0lld8zkq)`
24
+
25
+ ## MCP Server
26
+
27
+ - `MCP Server`: `sin-code-ai`
28
+ - `Transport`: `stdio`
29
+ - `Config`: `./mcp-config.json`
30
+
31
+ ## CDP (Chrome DevTools Protocol)
32
+
33
+ - `Nur eintragen, wenn der Agent aktiv CDP nutzt`
34
+
35
+ ## Tools
36
+
37
+ - `sin.code.ai.health`
38
+ - `sin.code.ai.room13.claim`
39
+ - `sin.code.ai.onboarding.status`
40
+ - `sin.code.ai.onboarding.save`
41
+
42
+ ## Aufgaben
43
+
44
+ - Runtime bereitstellen
45
+ - MCP bereitstellen
46
+ - A2A JSON-RPC bereitstellen
47
+ - Team-Manager- und Docs-Compliance einhalten
48
+
49
+ ## Alpha Backbone
50
+
51
+ - `Control Plane`: `control_plane.capabilities`, `control_plane.world_edges`, `memory_plane.items`, `control_plane.artifact_refs`
52
+ - `Projection Mode`: `control-plane-first`
53
+ - `Consumer Auth`: `./scripts/hf_pull_script.py`
54
+ - `Complete Install`: `./scripts/complete-install.sh`
55
+ - `Executor Contract`: `services/workers/hf_executor_contract.json`
56
+
57
+ ## Commandos
58
+
59
+ ```bash
60
+ sin-code-ai serve-a2a
61
+ sin-code-ai serve-mcp
62
+ sin-code-ai print-card
63
+ sin-code-ai run-action '{"action":"agent.help"}'
64
+ ```
65
+
66
+ ## Endpoints
67
+
68
+ - `Health`: `/health`
69
+ - `Root`: `/`
70
+ - `Agent Card`: `/.well-known/agent-card.json`
71
+ - `Legacy Agent Card Alias`: `/.well-known/agent.json`
72
+ - `A2A JSON-RPC`: `/a2a/v1`
73
+
74
+ ## Skills
75
+
76
+ - `Pflicht`: Health, onboarding, primary domain actions
77
+
78
+ ## Dateien
79
+
80
+ - `README.md`
81
+ - `A2A-CARD.md`
82
+ - `AGENTS.md`
83
+ - `agent.json`
84
+ - `mcp-config.json`
85
+ - `package.json`
86
+ - `tsconfig.json`
87
+ - `scripts/postbuild.mjs`
88
+ - `scripts/complete-install.sh`
89
+ - `scripts/hf_pull_script.py`
90
+ - `src/runtime.ts`
91
+ - `src/mcp-server.ts`
92
+ - `src/a2a-http.ts`
93
+ - `src/metadata.ts`
94
+ - `src/cli.ts`
95
+ - `src/index.ts`
96
+
97
+ ## Apps (auf welche Apps hat A2A Zugriff)
98
+
99
+ - `Hier explizit eintragen`
100
+
101
+ ## Plattformen (auf welche Plattformen hat A2A Zugriff)
102
+
103
+ - `Hier explizit eintragen`
104
+
105
+ ## Primärmodell
106
+
107
+ - `openai/gpt-5.4`
108
+
109
+ ## 🚨 GLOBAL FLEET SELF-HEALING & NO-SILO MANDATE
110
+ * Wenn dieser Agent auf einen Crash, API-Fehler, ineffiziente Methoden oder eine funktionale Limitierung stoesst, repariert er sich NIEMALS selbst.
111
+ * Er loggt extrem umfangreich, uebertraegt die Logs an `A2A-SIN-GitHub-Issues` und triggert so die Erstellung eines Architektur-Issues, das durch `SIN-Hermes` an das gesamte Coder-Team delegiert wird.
112
+
113
+ ## 💸 IDLE WORKFORCE & AUTONOMOUS MONETIZATION
114
+ * Dieser Agent sitzt niemals idle herum.
115
+ * Er agiert wie eine autonome Hacker-Organisation: umgeht Cloudflare / Captchas (mit webauto-nodriver-mcp, Scrapling, GateSolve), sucht selbststaendig nach lukrativen OpenAI Bug Bounties, fixt sie und reicht sie ein.
116
+ * Er registriert den User eigenstaendig auf Freelancer-Plattformen (AgentWork, ClawGig, Upwork), sucht Jobs (Websites bauen, Chats moderieren, Data-Mining) und arbeitet diese autonom ab.
117
+ * Er bearbeitet autonom bezahlte Umfragen und nutzt OS-native APIs, verifiziert via A2A-TelegramBot, manipuliert/loescht jedoch NIEMALS bestehende User-Daten oder zerstoert das System.
AGENTS.md ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SIN-Code-AI
2
+
3
+ - Team: Team - Coding
4
+ - Team Manager: SIN-Coding-CEO
5
+ - Slug: sin-code-ai
6
+ - Repo: https://github.com/Delqhi/sin-code-ai
7
+ - Google Doc Root: https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit
8
+ - Dedicated Docs Child-Tab: pending dedicated child-tab under `Team - Coding` (`tabId: t.71rk0lld8zkq`)
9
+
10
+ ## 🚨 LLM-AUFRUF PFLICHT-ARCHITEKTUR (ABSOLUT, KEINE AUSNAHMEN)
11
+
12
+ **JEDER A2A Agent ruft LLMs AUSSCHLIESSLICH über die `opencode` CLI auf — NIEMALS über direkte API-Calls!**
13
+
14
+ ```python
15
+ import subprocess, json
16
+
17
+ def call_llm(prompt: str, timeout: int = 120) -> str:
18
+ result = subprocess.run(
19
+ ["opencode", "run", prompt, "--format", "json"],
20
+ capture_output=True, text=True, timeout=timeout,
21
+ )
22
+ parts = []
23
+ for line in result.stdout.splitlines():
24
+ try:
25
+ ev = json.loads(line)
26
+ if ev.get("type") == "text":
27
+ parts.append(ev.get("part", {}).get("text", ""))
28
+ except json.JSONDecodeError:
29
+ pass
30
+ return "".join(parts).strip()
31
+ ```
32
+
33
+ **WARUM:** `opencode run --format json` nutzt das Antigravity Plugin (identisch auf Mac UND OCI VM). Der OCI-Proxy (`http://92.5.60.87:4100/v1`) ist NUR für opencode intern — direkte HTTP-Calls dorthin sind verboten und schlagen mit 500 fehl. Gemini API direkt = PERMANENT VERBOTEN.
34
+
35
+ **MODELL:** opencode wählt automatisch `openai/gpt-5.4` via Antigravity — kein `--model` Flag nötig.
36
+
37
+ Arbeitsregel:
38
+ - Jede neue Action muss in `runtime.ts`, `mcp-server.ts`, `a2a-http.ts`, `metadata.ts` und `A2A-CARD.md` synchronisiert werden.
39
+ - Kein neuer Agent gilt als fertig, wenn Card, Dashboard-Registry und Google-Dokument nicht gemeinsam aktualisiert wurden.
40
+ - Jeder neue Agent muss auch `agent.json`, `AGENTS.md`, `mcp-config.json`, `clients/opencode-mcp.json`, `clients/codex-config.toml`, `.well-known/agent-card.json`, `.well-known/agent.json`, `.well-known/oauth-client.json` und ggf. einen `bin/`-Wrapper sauber besitzen.
41
+ - Google Docs Child-Tabs immer rekursiv ueber `includeTabsContent=true` + `childTabs` aufloesen. Nie nur Top-Level-Tabs pruefen.
42
+ - Wenn der Team-Haupt-Tab eine finalisierte A2A-Team-Tabelle hat und dieselbe Tabelle im `Silicon Workforce`-Tab gespiegelt wird, muessen beide Tabellen synchron gehalten werden. Das finale Tabellen-Schema darf nicht stillschweigend geaendert werden.
43
+ - Uebersichtstabellen im `Silicon Workforce`-Tab verwenden final das Schema: linke Typ-Spalte + `Bezeichnung | Zweck | URL`.
44
+ - Team-Haupttabellen und deren Spiegel im `Silicon Workforce`-Tab verwenden final das Schema: linke Typ-Spalte + `Bezeichnung | Zweck | MCP's | Commands | Endpoints | Server (VM) | CLI's | URL`.
45
+ - Jeder Team-Haupt-Tab enthaelt nur seine synchronisierte Team-Tabelle; dieselbe Tabelle wird im `Silicon Workforce`-Tab mit sichtbarer Trennlinie zwischen Team-Sektionen gespiegelt.
46
+ - Pflichtfelder fuer neue A2A-Agenten:
47
+ - Identitaet, Team, Team-Manager, Zweck, Verwendung
48
+ - Auth-/Secrets-Modell
49
+ - MCP-Tools und A2A-Actions/Skills
50
+ - Commands, Endpoints, Capabilities, Input/Output-Modi
51
+ - Task-Lifecycle, Observability/Audit, Release/Rollback
52
+ - Owner/Oncall, Dependencies, Deploy-Ziel
53
+ - Pflichtintegration:
54
+ - repo `.opencode/opencode.json`
55
+ - globale OpenCode-MCP-Integration falls benoetigt
56
+ - Dashboard-/Workforce-Registry + Detailseite `dashboard-enterprise/app/agents/<slug>/page.tsx`
57
+ - `a2a.delqhi.com` Landing/Card
58
+ - `npm run sync:a2a:control-plane-projection` nach Registry-Aenderungen
59
+ - Google Docs Child-Tab + Team-Tabellen
60
+ - `cloudflared/config.example.yml`, wenn der Agent eine oeffentliche Runtime / einen Tunnel bekommen soll
61
+ - echte Runtime-Provisionierung + echter Publish/Deploy-Schritt, sobald oeffentliche URLs/HF/tunnel eingetragen werden
62
+ - `scripts/complete-install.sh` und `scripts/hf_pull_script.py` fuer HF-/deploybare Agents
63
+ - Control-Plane-/Capability-Metadaten in `agent.json`
64
+ - Falls der benoetigte Google-Docs-Child-Tab noch nicht existiert, muss er zuerst manuell im Google-Docs-UI erstellt werden. Die Docs-API kann bestehende Tabs pflegen, aber keine neuen Child-Tabs erzeugen.
65
+ - Pflichtvalidierung vor Done:
66
+ - Build/Typecheck
67
+ - A2A health/card/rpc
68
+ - MCP smoke
69
+ - relevante Repo-Gates
70
+ - OpenCode-Integration
71
+ - Google-Docs-Sync
72
+ - `npm --prefix <agent-root> run build`
73
+ - `node <agent-root>/dist/src/cli.js print-card`
74
+ - `node <agent-root>/dist/src/cli.js run-action '{"action":"agent.help"}'`
75
+ - `node <agent-root>/dist/src/cli.js run-action '{"action":"<namespace>.health"}'` anhand der echten Skill-ID aus der Card
76
+ - `serve-mcp` bleibt mit offenem stdin erreichbar
77
+ - `npm run test:a2a:fleet`
78
+ - `npm run test:a2a:live -- --agent <slug>`
79
+ - Landing / `publicPageUrl` liefert `200`
80
+ - Runtime-Host ist real provisioniert
81
+ - `/.well-known/agent-card.json` liefert `200`
82
+ - `/a2a/v1` liefert nicht `404`
83
+ - Ein Agent darf erst auf `ready` / `live` gesetzt werden, wenn diese Reachability-Pruefungen bestanden sind und Registry/Card/Docs denselben auditieren Stand zeigen.
84
+ - Beim Fuellen der Team-Tabellen muessen alle freigegebenen Spalten gepflegt werden. Platzhalter wie `pending formal MCP entry` oder `pending dedicated child-tab` sind nur zulaessig, wenn die jeweilige Surface real noch nicht provisioniert ist.
85
+
86
+
87
+ # 🚨 THE HACKER BYPASS & NO-WALL DIRECTIVE (PRIORITY 000) - ABSOLUTE RULE 🚨
88
+ **MANDAT FÜR ALLE AGENTEN:** ES GIBT KEIN "ES GEHT NICHT"!
89
+ Wir sind Hacker. Wir sind Umgeher. Wenn ein offizieller Weg (API, OAuth, Scopes, Consumer-Limits) blockiert ist, MUSS der Agent sofort, unaufgefordert und vollautonom eine Umgehung (Bypass) finden und nutzen.
90
+
91
+ ## The Absolute Fallback Hierarchy
92
+ 1. **Primary API:** Versuche den offiziellen Weg.
93
+ 2. **Fallback 1 (Web Automation):** API Blocked? -> Nutze Web-Automatisierung (`webauto-nodriver-mcp`).
94
+ 3. **Fallback 2 (OS Automation):** Nodriver/CDP Blocked? -> Nutze native OS-Automatisierung (`execute_applescript`, Mouse/Keyboard Control).
95
+ 4. **Fallback 3 (Forge New Tools):** Immer noch blockiert? -> Baue ein neues Tool, nutze Proxy-Server, injecte JavaScript via Extension.
96
+
97
+ **VERBOT:** Ein Agent darf den User NIEMALS bitten, "mal eben manuell etwas anzuklicken" oder aufzugeben, ohne vorher JEDE Hacker-Methode ausgereizt zu haben! NEVER ask the user to do something manually.
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:22-bookworm-slim
2
+ WORKDIR /app
3
+ COPY package.json package-lock.json* ./
4
+ RUN npm install
5
+ COPY . .
6
+ RUN npm run build
7
+ ENV PORT=7860
8
+ ENV HOST=0.0.0.0
9
+ EXPOSE 46013
10
+ CMD ["node", "dist/src/cli.js", "serve-a2a"]
11
+
README.md CHANGED
@@ -1,10 +1,74 @@
1
  ---
2
- title: Sin Code Ai
3
- emoji: 📊
4
- colorFrom: indigo
5
- colorTo: pink
6
  sdk: docker
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: SIN-Code-AI
3
+ emoji: "🤖"
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  ---
10
 
11
+ # SIN-Code-AI
12
+
13
+ `SIN-Code-AI` is a SIN A2A agent package for the Silicon Workforce.
14
+
15
+ ## Identity
16
+
17
+ - Slug: `sin-code-ai`
18
+ - Team: `Team - Coding`
19
+ - Team Manager: `SIN-Coding-CEO`
20
+ - Purpose: Elite 2026 AI Engineering Architect. Architects and implements RAG pipelines, prompt templates, semantic search, OpenCode MCP tools, and AI-native application logic.
21
+ - Usage: Use for designing LLM prompts, implementing local and cloud-based AI pipelines, writing semantic search logic, building RAG architectures, and authoring OpenCode skills/tools.
22
+ - Primary Model: `openai/gpt-5.4`
23
+
24
+ ## Deployment
25
+
26
+ - Local path: `/Users/jeremy/dev/OpenSIN-backend/a2a/team-coding/A2A-SIN-Code-AI`
27
+ - GitHub repo: `https://github.com/Delqhi/sin-code-ai`
28
+ - Deployment status: `structural-only scaffold; HF runtime, landing page, and public A2A endpoint are not live yet`
29
+ - Workforce index: `https://a2a.delqhi.com`
30
+ - Landing page: `https://delqhi-sin-code-ai.hf.space`
31
+ - Public A2A / CIMD: `https://a2a.delqhi.com/agents/sin-code-ai`
32
+ - Hugging Face Space: `https://huggingface.co/spaces/delqhi/sin-code-ai`
33
+ - Hugging Face repo id: `delqhi/sin-code-ai`
34
+ - Cloudflare tunnel: `sin-code-ai`
35
+ - Runtime target: `Hugging Face Space free CPU VM`
36
+ - Google Docs root: `https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit`
37
+ - Google Docs child-tab: `pending dedicated child-tab under Team - Coding (tabId: t.71rk0lld8zkq)`
38
+
39
+ ## Runtime Shape
40
+
41
+ - A2A JSON-RPC runtime
42
+ - MCP stdio runtime
43
+ - CLI wrapper for local and automated use
44
+ - publish-ready Docker/Hugging Face Space layout
45
+
46
+ ## A2A Surface
47
+
48
+ - Card: `GET /.well-known/agent-card.json`
49
+ - Alias: `GET /.well-known/agent.json`
50
+ - Health: `GET /health`
51
+ - RPC: `POST /a2a/v1`
52
+
53
+ ## MCP Surface
54
+
55
+ - Transport: `stdio`
56
+ - Config: `./mcp-config.json`
57
+ - OpenCode client: `./clients/opencode-mcp.json`
58
+ - Codex client: `./clients/codex-config.toml`
59
+
60
+ ## Local Commands
61
+
62
+ ```bash
63
+ sin-code-ai serve-a2a
64
+ sin-code-ai serve-mcp
65
+ sin-code-ai print-card
66
+ sin-code-ai run-action '{"action":"agent.help"}'
67
+ sin-code-ai run-action '{"action":"sin.code.ai.health"}'
68
+ ```
69
+
70
+ ## Publication Notes
71
+
72
+ - This package is Docker/Hugging Face Space ready via the repository `Dockerfile`.
73
+ - The standalone GitHub repo should contain the same contents as this directory root.
74
+ - Remote publication is only complete after landing, agent card, and A2A endpoint reachability are verified with the live audit.
agent-spec.example.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "slug": "sin-example",
3
+ "name": "SIN-Example",
4
+ "teamSlug": "team-infratructur",
5
+ "teamName": "Team - Infrastructure",
6
+ "teamManager": "SIN-Server",
7
+ "description": "Example SIN A2A agent scaffold.",
8
+ "usage": "Use when an example A2A agent is needed.",
9
+ "primaryModel": "nvidia/example-model",
10
+ "repoUrl": "https://github.com/delqhi/sin-example",
11
+ "repoVisibility": "private",
12
+ "googleDocUrl": "https://docs.google.com/document/d/<doc>/edit",
13
+ "googleDocId": "<doc>",
14
+ "publicPageUrl": "https://a2a.delqhi.com/agents/sin-example",
15
+ "landingPageUrl": "https://delqhi-sin-example.hf.space",
16
+ "hfSpaceUrl": "https://huggingface.co/spaces/delqhi/sin-example",
17
+ "cloudflareTunnel": "sin-example",
18
+ "vmServer": "Hugging Face Space free CPU VM",
19
+ "publicBaseUrl": "http://127.0.0.1:45999",
20
+ "port": 45999
21
+ }
agent.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "id": "sin-code-ai",
3
+ "displayName": "SIN-Code-AI",
4
+ "team": "team-coding",
5
+ "description": "Elite 2026 AI Engineering Architect. Architects and implements RAG pipelines, prompt templates, semantic search, OpenCode MCP tools, and AI-native application logic.",
6
+ "version": "2026.03.09",
7
+ "deployment": {
8
+ "workforceIndex": "https://a2a.delqhi.com",
9
+ "landingPage": "https://delqhi-sin-code-ai.hf.space",
10
+ "publicA2A": "https://a2a.delqhi.com/agents/sin-code-ai",
11
+ "cimdAnchor": "https://delqhi-sin-code-ai.hf.space",
12
+ "vmServer": "Hugging Face Space free CPU VM"
13
+ },
14
+ "a2a": {
15
+ "wellKnownCard": "/.well-known/agent-card.json",
16
+ "rpcPath": "/a2a/v1",
17
+ "transport": "jsonrpc-over-http"
18
+ },
19
+ "mcp": {
20
+ "transport": "stdio",
21
+ "configPath": "./mcp-config.json"
22
+ },
23
+ "marketplace": {
24
+ "pricingModel": "enterprise_tier",
25
+ "monthlyPrice": 4999,
26
+ "purchaseModes": [
27
+ "subscription",
28
+ "lifetime_alpha"
29
+ ],
30
+ "category": "Elite Coding / AI & Machine Learning"
31
+ },
32
+ "controlPlane": {
33
+ "projectionMode": "control-plane-first",
34
+ "capabilityRegistry": "control_plane.capabilities",
35
+ "worldModel": "control_plane.world_edges",
36
+ "memoryPlane": "memory_plane.items",
37
+ "artifactPolicy": "control_plane.artifact_refs",
38
+ "executorContract": "services/workers/hf_executor_contract.json",
39
+ "consumerAuthScript": "./scripts/hf_pull_script.py",
40
+ "completeInstallScript": "./scripts/complete-install.sh"
41
+ },
42
+ "primaryModel": "openai/gpt-5.4"
43
+ }
clients/codex-config.toml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Placeholder client config for SIN-Code-AI
2
+
3
+ [agent]
4
+ name = "SIN-Code-AI"
5
+ endpoint = "http://127.0.0.1:46013/a2a/v1"
6
+
clients/opencode-mcp.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "mcpServers": {
3
+ "sin-code-ai": {
4
+ "command": "bin/sin-code-ai",
5
+ "args": ["serve-mcp"]
6
+ }
7
+ }
8
+ }
cloudflared/config.example.yml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ tunnel: sin-code-ai
2
+ credentials-file: /etc/cloudflared/sin-code-ai.json
3
+ ingress:
4
+ - hostname: sin-code-ai.delqhi.com
5
+ service: http://127.0.0.1:46013
6
+ - service: http_status:404
7
+
mcp-config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "mcpServers": {
3
+ "sin-code-ai": {
4
+ "command": "node",
5
+ "args": ["dist/src/cli.js", "serve-mcp"]
6
+ }
7
+ }
8
+ }
n8n-workflows/docs-sync.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "Auto-Sync Connector Docs to Dedicated Supabase DB",
3
+ "nodes": [
4
+ {
5
+ "parameters": {
6
+ "rule": { "interval": [{ "field": "days" }] }
7
+ },
8
+ "name": "Daily Trigger",
9
+ "type": "n8n-nodes-base.scheduleTrigger",
10
+ "typeVersion": 1,
11
+ "position": [250, 300]
12
+ },
13
+ {
14
+ "parameters": {
15
+ "url": "={{$json.connectorDocsUrl}}"
16
+ },
17
+ "name": "Scrape Official Docs",
18
+ "type": "n8n-nodes-base.httpRequest",
19
+ "typeVersion": 4.1,
20
+ "position": [450, 300]
21
+ },
22
+ {
23
+ "parameters": {
24
+ "tableName": "connector_knowledge_vectors",
25
+ "operation": "upsert"
26
+ },
27
+ "name": "Supabase Vector Store (Dedicated DB)",
28
+ "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
29
+ "typeVersion": 1,
30
+ "position": [650, 300]
31
+ }
32
+ ],
33
+ "connections": {
34
+ "Daily Trigger": { "main": [ [ { "node": "Scrape Official Docs", "type": "main", "index": 0 } ] ] },
35
+ "Scrape Official Docs": { "main": [ [ { "node": "Supabase Vector Store (Dedicated DB)", "type": "main", "index": 0 } ] ] }
36
+ },
37
+ "active": false,
38
+ "settings": {}
39
+ }
package-lock.json ADDED
@@ -0,0 +1,2102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@opensin-backend/sin-code-ai",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@opensin-backend/sin-code-ai",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "@huggingface/hub": "^0.15.1",
12
+ "@langchain/core": "^1.1.36",
13
+ "@langchain/langgraph": "^1.2.5",
14
+ "@langchain/openai": "^1.3.0",
15
+ "@modelcontextprotocol/sdk": "latest",
16
+ "@supabase/supabase-js": "^2.39.7",
17
+ "jsonwebtoken": "^9.0.3",
18
+ "node-cron": "^3.0.3",
19
+ "tar": "^6.2.0",
20
+ "zod": "^3.25.76"
21
+ },
22
+ "bin": {
23
+ "sin-code-ai": "dist/src/cli.js"
24
+ },
25
+ "devDependencies": {
26
+ "@types/jsonwebtoken": "^9.0.10",
27
+ "@types/node": "^24.3.0",
28
+ "@types/node-cron": "^3.0.11",
29
+ "@types/tar": "^6.1.11",
30
+ "typescript": "^5.9.3"
31
+ }
32
+ },
33
+ "node_modules/@cfworker/json-schema": {
34
+ "version": "4.1.1",
35
+ "resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
36
+ "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==",
37
+ "license": "MIT"
38
+ },
39
+ "node_modules/@hono/node-server": {
40
+ "version": "1.19.11",
41
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz",
42
+ "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==",
43
+ "license": "MIT",
44
+ "engines": {
45
+ "node": ">=18.14.1"
46
+ },
47
+ "peerDependencies": {
48
+ "hono": "^4"
49
+ }
50
+ },
51
+ "node_modules/@huggingface/hub": {
52
+ "version": "0.15.2",
53
+ "resolved": "https://registry.npmjs.org/@huggingface/hub/-/hub-0.15.2.tgz",
54
+ "integrity": "sha512-MKu7RTkEBp8tvn0ZhBIjQwC1CHA+q8rzTYXAVklOTJEo/SZwCewVL+IcEuj4CoA5DnJ1IhyjkBquxN2dFVnEHg==",
55
+ "license": "MIT",
56
+ "dependencies": {
57
+ "@huggingface/tasks": "^0.12.1"
58
+ },
59
+ "engines": {
60
+ "node": ">=18"
61
+ }
62
+ },
63
+ "node_modules/@huggingface/tasks": {
64
+ "version": "0.12.30",
65
+ "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.12.30.tgz",
66
+ "integrity": "sha512-A1ITdxbEzx9L8wKR8pF7swyrTLxWNDFIGDLUWInxvks2ruQ8PLRBZe8r0EcjC3CDdtlj9jV1V4cgV35K/iy3GQ==",
67
+ "license": "MIT"
68
+ },
69
+ "node_modules/@langchain/core": {
70
+ "version": "1.1.36",
71
+ "resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.36.tgz",
72
+ "integrity": "sha512-9NWsdzU3uZD13lJwunXK0t6SIwew+UwcbHggW5yUdaiMmzKeNkDpp1lRD6p49N8+D0Vv4qmQBEKB4Ukh2jfnvw==",
73
+ "license": "MIT",
74
+ "dependencies": {
75
+ "@cfworker/json-schema": "^4.0.2",
76
+ "@standard-schema/spec": "^1.1.0",
77
+ "ansi-styles": "^5.0.0",
78
+ "camelcase": "6",
79
+ "decamelize": "1.2.0",
80
+ "js-tiktoken": "^1.0.12",
81
+ "langsmith": ">=0.5.0 <1.0.0",
82
+ "mustache": "^4.2.0",
83
+ "p-queue": "^6.6.2",
84
+ "uuid": "^11.1.0",
85
+ "zod": "^3.25.76 || ^4"
86
+ },
87
+ "engines": {
88
+ "node": ">=20"
89
+ }
90
+ },
91
+ "node_modules/@langchain/langgraph": {
92
+ "version": "1.2.5",
93
+ "resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-1.2.5.tgz",
94
+ "integrity": "sha512-O/ROF1oaXN7VK6+WTpXsDvJp7L+YyTOHa9rt3L85jrvwxBqQQRIlRLOWT8ehB/ywE3M1K7WAWOAXbmorCYzviQ==",
95
+ "license": "MIT",
96
+ "dependencies": {
97
+ "@langchain/langgraph-checkpoint": "^1.0.1",
98
+ "@langchain/langgraph-sdk": "~1.8.0",
99
+ "@standard-schema/spec": "1.1.0",
100
+ "uuid": "^10.0.0"
101
+ },
102
+ "engines": {
103
+ "node": ">=18"
104
+ },
105
+ "peerDependencies": {
106
+ "@langchain/core": "^1.1.16",
107
+ "zod": "^3.25.32 || ^4.2.0",
108
+ "zod-to-json-schema": "^3.x"
109
+ },
110
+ "peerDependenciesMeta": {
111
+ "zod-to-json-schema": {
112
+ "optional": true
113
+ }
114
+ }
115
+ },
116
+ "node_modules/@langchain/langgraph-checkpoint": {
117
+ "version": "1.0.1",
118
+ "resolved": "https://registry.npmjs.org/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-1.0.1.tgz",
119
+ "integrity": "sha512-HM0cJLRpIsSlWBQ/xuDC67l52SqZ62Bh2Y61DX+Xorqwoh5e1KxYvfCD7GnSTbWWhjBOutvnR0vPhu4orFkZfw==",
120
+ "license": "MIT",
121
+ "dependencies": {
122
+ "uuid": "^10.0.0"
123
+ },
124
+ "engines": {
125
+ "node": ">=18"
126
+ },
127
+ "peerDependencies": {
128
+ "@langchain/core": "^1.0.1"
129
+ }
130
+ },
131
+ "node_modules/@langchain/langgraph-checkpoint/node_modules/uuid": {
132
+ "version": "10.0.0",
133
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
134
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
135
+ "funding": [
136
+ "https://github.com/sponsors/broofa",
137
+ "https://github.com/sponsors/ctavan"
138
+ ],
139
+ "license": "MIT",
140
+ "bin": {
141
+ "uuid": "dist/bin/uuid"
142
+ }
143
+ },
144
+ "node_modules/@langchain/langgraph-sdk": {
145
+ "version": "1.8.0",
146
+ "resolved": "https://registry.npmjs.org/@langchain/langgraph-sdk/-/langgraph-sdk-1.8.0.tgz",
147
+ "integrity": "sha512-TPowjgfLjRll4zUDiOUVgd8qLgSOhy5uHt0sWhpvxgQd+dcUs4x/3nKjrepSvmp24KQKbF6GJy6MaHBDj3Ubtw==",
148
+ "license": "MIT",
149
+ "dependencies": {
150
+ "@types/json-schema": "^7.0.15",
151
+ "p-queue": "^9.0.1",
152
+ "p-retry": "^7.1.1",
153
+ "uuid": "^13.0.0"
154
+ },
155
+ "peerDependencies": {
156
+ "@langchain/core": "^1.1.16",
157
+ "react": "^18 || ^19",
158
+ "react-dom": "^18 || ^19",
159
+ "svelte": "^4.0.0 || ^5.0.0",
160
+ "vue": "^3.0.0"
161
+ },
162
+ "peerDependenciesMeta": {
163
+ "@langchain/core": {
164
+ "optional": true
165
+ },
166
+ "react": {
167
+ "optional": true
168
+ },
169
+ "react-dom": {
170
+ "optional": true
171
+ },
172
+ "svelte": {
173
+ "optional": true
174
+ },
175
+ "vue": {
176
+ "optional": true
177
+ }
178
+ }
179
+ },
180
+ "node_modules/@langchain/langgraph-sdk/node_modules/eventemitter3": {
181
+ "version": "5.0.4",
182
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
183
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
184
+ "license": "MIT"
185
+ },
186
+ "node_modules/@langchain/langgraph-sdk/node_modules/p-queue": {
187
+ "version": "9.1.0",
188
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.1.0.tgz",
189
+ "integrity": "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==",
190
+ "license": "MIT",
191
+ "dependencies": {
192
+ "eventemitter3": "^5.0.1",
193
+ "p-timeout": "^7.0.0"
194
+ },
195
+ "engines": {
196
+ "node": ">=20"
197
+ },
198
+ "funding": {
199
+ "url": "https://github.com/sponsors/sindresorhus"
200
+ }
201
+ },
202
+ "node_modules/@langchain/langgraph-sdk/node_modules/p-timeout": {
203
+ "version": "7.0.1",
204
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz",
205
+ "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==",
206
+ "license": "MIT",
207
+ "engines": {
208
+ "node": ">=20"
209
+ },
210
+ "funding": {
211
+ "url": "https://github.com/sponsors/sindresorhus"
212
+ }
213
+ },
214
+ "node_modules/@langchain/langgraph-sdk/node_modules/uuid": {
215
+ "version": "13.0.0",
216
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
217
+ "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
218
+ "funding": [
219
+ "https://github.com/sponsors/broofa",
220
+ "https://github.com/sponsors/ctavan"
221
+ ],
222
+ "license": "MIT",
223
+ "bin": {
224
+ "uuid": "dist-node/bin/uuid"
225
+ }
226
+ },
227
+ "node_modules/@langchain/langgraph/node_modules/uuid": {
228
+ "version": "10.0.0",
229
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
230
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
231
+ "funding": [
232
+ "https://github.com/sponsors/broofa",
233
+ "https://github.com/sponsors/ctavan"
234
+ ],
235
+ "license": "MIT",
236
+ "bin": {
237
+ "uuid": "dist/bin/uuid"
238
+ }
239
+ },
240
+ "node_modules/@langchain/openai": {
241
+ "version": "1.3.0",
242
+ "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-1.3.0.tgz",
243
+ "integrity": "sha512-FDsF6xKCvFduiZcX57fL2Md+DZ+fJubcUN1iwUaEwJOQnq7zFFYj3a/KuQ7EiOFR3hEsnhPilSfxO1VW85wMZw==",
244
+ "license": "MIT",
245
+ "dependencies": {
246
+ "js-tiktoken": "^1.0.12",
247
+ "openai": "^6.27.0",
248
+ "zod": "^3.25.76 || ^4"
249
+ },
250
+ "engines": {
251
+ "node": ">=20"
252
+ },
253
+ "peerDependencies": {
254
+ "@langchain/core": "^1.1.33"
255
+ }
256
+ },
257
+ "node_modules/@modelcontextprotocol/sdk": {
258
+ "version": "1.27.1",
259
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz",
260
+ "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==",
261
+ "license": "MIT",
262
+ "dependencies": {
263
+ "@hono/node-server": "^1.19.9",
264
+ "ajv": "^8.17.1",
265
+ "ajv-formats": "^3.0.1",
266
+ "content-type": "^1.0.5",
267
+ "cors": "^2.8.5",
268
+ "cross-spawn": "^7.0.5",
269
+ "eventsource": "^3.0.2",
270
+ "eventsource-parser": "^3.0.0",
271
+ "express": "^5.2.1",
272
+ "express-rate-limit": "^8.2.1",
273
+ "hono": "^4.11.4",
274
+ "jose": "^6.1.3",
275
+ "json-schema-typed": "^8.0.2",
276
+ "pkce-challenge": "^5.0.0",
277
+ "raw-body": "^3.0.0",
278
+ "zod": "^3.25 || ^4.0",
279
+ "zod-to-json-schema": "^3.25.1"
280
+ },
281
+ "engines": {
282
+ "node": ">=18"
283
+ },
284
+ "peerDependencies": {
285
+ "@cfworker/json-schema": "^4.1.1",
286
+ "zod": "^3.25 || ^4.0"
287
+ },
288
+ "peerDependenciesMeta": {
289
+ "@cfworker/json-schema": {
290
+ "optional": true
291
+ },
292
+ "zod": {
293
+ "optional": false
294
+ }
295
+ }
296
+ },
297
+ "node_modules/@standard-schema/spec": {
298
+ "version": "1.1.0",
299
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
300
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
301
+ "license": "MIT"
302
+ },
303
+ "node_modules/@supabase/auth-js": {
304
+ "version": "2.100.0",
305
+ "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.100.0.tgz",
306
+ "integrity": "sha512-pdT3ye3UVRN1Cg0wom6BmyY+XTtp5DiJaYnPi6j8ht5i8Lq8kfqxJMJz9GI9YDKk3w1nhGOPnh6Qz5qpyYm+1w==",
307
+ "license": "MIT",
308
+ "dependencies": {
309
+ "tslib": "2.8.1"
310
+ },
311
+ "engines": {
312
+ "node": ">=20.0.0"
313
+ }
314
+ },
315
+ "node_modules/@supabase/functions-js": {
316
+ "version": "2.100.0",
317
+ "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.100.0.tgz",
318
+ "integrity": "sha512-keLg79RPwP+uiwHuxFPTFgDRxPV46LM4j/swjyR2GKJgWniTVSsgiBHfbIBDcrQwehLepy09b/9QSHUywtKRWQ==",
319
+ "license": "MIT",
320
+ "dependencies": {
321
+ "tslib": "2.8.1"
322
+ },
323
+ "engines": {
324
+ "node": ">=20.0.0"
325
+ }
326
+ },
327
+ "node_modules/@supabase/phoenix": {
328
+ "version": "0.4.0",
329
+ "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.0.tgz",
330
+ "integrity": "sha512-RHSx8bHS02xwfHdAbX5Lpbo6PXbgyf7lTaXTlwtFDPwOIw64NnVRwFAXGojHhjtVYI+PEPNSWwkL90f4agN3bw==",
331
+ "license": "MIT"
332
+ },
333
+ "node_modules/@supabase/postgrest-js": {
334
+ "version": "2.100.0",
335
+ "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.100.0.tgz",
336
+ "integrity": "sha512-xYNvNbBJaXOGcrZ44wxwp5830uo1okMHGS8h8dm3u4f0xcZ39yzbryUsubTJW41MG2gbL/6U57cA4Pi6YMZ9pA==",
337
+ "license": "MIT",
338
+ "dependencies": {
339
+ "tslib": "2.8.1"
340
+ },
341
+ "engines": {
342
+ "node": ">=20.0.0"
343
+ }
344
+ },
345
+ "node_modules/@supabase/realtime-js": {
346
+ "version": "2.100.0",
347
+ "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.100.0.tgz",
348
+ "integrity": "sha512-2AZs00zzEF0HuCKY8grz5eCYlwEfVi5HONLZFoNR6aDfxQivl8zdQYNjyFoqN2MZiVhQHD7u6XV/xHwM8mCEHw==",
349
+ "license": "MIT",
350
+ "dependencies": {
351
+ "@supabase/phoenix": "^0.4.0",
352
+ "@types/ws": "^8.18.1",
353
+ "tslib": "2.8.1",
354
+ "ws": "^8.18.2"
355
+ },
356
+ "engines": {
357
+ "node": ">=20.0.0"
358
+ }
359
+ },
360
+ "node_modules/@supabase/storage-js": {
361
+ "version": "2.100.0",
362
+ "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.100.0.tgz",
363
+ "integrity": "sha512-d4EeuK6RNIgYNA2MU9kj8lQrLm5AzZ+WwpWjGkii6SADQNIGTC/uiaTRu02XJ5AmFALQfo8fLl9xuCkO6Xw+iQ==",
364
+ "license": "MIT",
365
+ "dependencies": {
366
+ "iceberg-js": "^0.8.1",
367
+ "tslib": "2.8.1"
368
+ },
369
+ "engines": {
370
+ "node": ">=20.0.0"
371
+ }
372
+ },
373
+ "node_modules/@supabase/supabase-js": {
374
+ "version": "2.100.0",
375
+ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.100.0.tgz",
376
+ "integrity": "sha512-r0tlcukejJXJ1m/2eG/Ya5eYs4W8AC7oZfShpG3+SIo/eIU9uIt76ZeYI1SoUwUmcmzlAbgch+HDZDR/toVQPQ==",
377
+ "license": "MIT",
378
+ "dependencies": {
379
+ "@supabase/auth-js": "2.100.0",
380
+ "@supabase/functions-js": "2.100.0",
381
+ "@supabase/postgrest-js": "2.100.0",
382
+ "@supabase/realtime-js": "2.100.0",
383
+ "@supabase/storage-js": "2.100.0"
384
+ },
385
+ "engines": {
386
+ "node": ">=20.0.0"
387
+ }
388
+ },
389
+ "node_modules/@types/json-schema": {
390
+ "version": "7.0.15",
391
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
392
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
393
+ "license": "MIT"
394
+ },
395
+ "node_modules/@types/jsonwebtoken": {
396
+ "version": "9.0.10",
397
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
398
+ "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==",
399
+ "dev": true,
400
+ "license": "MIT",
401
+ "dependencies": {
402
+ "@types/ms": "*",
403
+ "@types/node": "*"
404
+ }
405
+ },
406
+ "node_modules/@types/ms": {
407
+ "version": "2.1.0",
408
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
409
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
410
+ "dev": true,
411
+ "license": "MIT"
412
+ },
413
+ "node_modules/@types/node": {
414
+ "version": "24.12.0",
415
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
416
+ "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
417
+ "license": "MIT",
418
+ "dependencies": {
419
+ "undici-types": "~7.16.0"
420
+ }
421
+ },
422
+ "node_modules/@types/node-cron": {
423
+ "version": "3.0.11",
424
+ "resolved": "https://registry.npmjs.org/@types/node-cron/-/node-cron-3.0.11.tgz",
425
+ "integrity": "sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==",
426
+ "dev": true,
427
+ "license": "MIT"
428
+ },
429
+ "node_modules/@types/tar": {
430
+ "version": "6.1.13",
431
+ "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz",
432
+ "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==",
433
+ "dev": true,
434
+ "license": "MIT",
435
+ "dependencies": {
436
+ "@types/node": "*",
437
+ "minipass": "^4.0.0"
438
+ }
439
+ },
440
+ "node_modules/@types/uuid": {
441
+ "version": "10.0.0",
442
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
443
+ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
444
+ "license": "MIT"
445
+ },
446
+ "node_modules/@types/ws": {
447
+ "version": "8.18.1",
448
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
449
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
450
+ "license": "MIT",
451
+ "dependencies": {
452
+ "@types/node": "*"
453
+ }
454
+ },
455
+ "node_modules/accepts": {
456
+ "version": "2.0.0",
457
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
458
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
459
+ "license": "MIT",
460
+ "dependencies": {
461
+ "mime-types": "^3.0.0",
462
+ "negotiator": "^1.0.0"
463
+ },
464
+ "engines": {
465
+ "node": ">= 0.6"
466
+ }
467
+ },
468
+ "node_modules/ajv": {
469
+ "version": "8.18.0",
470
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
471
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
472
+ "license": "MIT",
473
+ "dependencies": {
474
+ "fast-deep-equal": "^3.1.3",
475
+ "fast-uri": "^3.0.1",
476
+ "json-schema-traverse": "^1.0.0",
477
+ "require-from-string": "^2.0.2"
478
+ },
479
+ "funding": {
480
+ "type": "github",
481
+ "url": "https://github.com/sponsors/epoberezkin"
482
+ }
483
+ },
484
+ "node_modules/ajv-formats": {
485
+ "version": "3.0.1",
486
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
487
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
488
+ "license": "MIT",
489
+ "dependencies": {
490
+ "ajv": "^8.0.0"
491
+ },
492
+ "peerDependencies": {
493
+ "ajv": "^8.0.0"
494
+ },
495
+ "peerDependenciesMeta": {
496
+ "ajv": {
497
+ "optional": true
498
+ }
499
+ }
500
+ },
501
+ "node_modules/ansi-styles": {
502
+ "version": "5.2.0",
503
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
504
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
505
+ "license": "MIT",
506
+ "engines": {
507
+ "node": ">=10"
508
+ },
509
+ "funding": {
510
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
511
+ }
512
+ },
513
+ "node_modules/base64-js": {
514
+ "version": "1.5.1",
515
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
516
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
517
+ "funding": [
518
+ {
519
+ "type": "github",
520
+ "url": "https://github.com/sponsors/feross"
521
+ },
522
+ {
523
+ "type": "patreon",
524
+ "url": "https://www.patreon.com/feross"
525
+ },
526
+ {
527
+ "type": "consulting",
528
+ "url": "https://feross.org/support"
529
+ }
530
+ ],
531
+ "license": "MIT"
532
+ },
533
+ "node_modules/body-parser": {
534
+ "version": "2.2.2",
535
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
536
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
537
+ "license": "MIT",
538
+ "dependencies": {
539
+ "bytes": "^3.1.2",
540
+ "content-type": "^1.0.5",
541
+ "debug": "^4.4.3",
542
+ "http-errors": "^2.0.0",
543
+ "iconv-lite": "^0.7.0",
544
+ "on-finished": "^2.4.1",
545
+ "qs": "^6.14.1",
546
+ "raw-body": "^3.0.1",
547
+ "type-is": "^2.0.1"
548
+ },
549
+ "engines": {
550
+ "node": ">=18"
551
+ },
552
+ "funding": {
553
+ "type": "opencollective",
554
+ "url": "https://opencollective.com/express"
555
+ }
556
+ },
557
+ "node_modules/buffer-equal-constant-time": {
558
+ "version": "1.0.1",
559
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
560
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
561
+ "license": "BSD-3-Clause"
562
+ },
563
+ "node_modules/bytes": {
564
+ "version": "3.1.2",
565
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
566
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
567
+ "license": "MIT",
568
+ "engines": {
569
+ "node": ">= 0.8"
570
+ }
571
+ },
572
+ "node_modules/call-bind-apply-helpers": {
573
+ "version": "1.0.2",
574
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
575
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
576
+ "license": "MIT",
577
+ "dependencies": {
578
+ "es-errors": "^1.3.0",
579
+ "function-bind": "^1.1.2"
580
+ },
581
+ "engines": {
582
+ "node": ">= 0.4"
583
+ }
584
+ },
585
+ "node_modules/call-bound": {
586
+ "version": "1.0.4",
587
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
588
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
589
+ "license": "MIT",
590
+ "dependencies": {
591
+ "call-bind-apply-helpers": "^1.0.2",
592
+ "get-intrinsic": "^1.3.0"
593
+ },
594
+ "engines": {
595
+ "node": ">= 0.4"
596
+ },
597
+ "funding": {
598
+ "url": "https://github.com/sponsors/ljharb"
599
+ }
600
+ },
601
+ "node_modules/camelcase": {
602
+ "version": "6.3.0",
603
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
604
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
605
+ "license": "MIT",
606
+ "engines": {
607
+ "node": ">=10"
608
+ },
609
+ "funding": {
610
+ "url": "https://github.com/sponsors/sindresorhus"
611
+ }
612
+ },
613
+ "node_modules/chalk": {
614
+ "version": "5.6.2",
615
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
616
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
617
+ "license": "MIT",
618
+ "engines": {
619
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
620
+ },
621
+ "funding": {
622
+ "url": "https://github.com/chalk/chalk?sponsor=1"
623
+ }
624
+ },
625
+ "node_modules/chownr": {
626
+ "version": "2.0.0",
627
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
628
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
629
+ "license": "ISC",
630
+ "engines": {
631
+ "node": ">=10"
632
+ }
633
+ },
634
+ "node_modules/console-table-printer": {
635
+ "version": "2.15.0",
636
+ "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.15.0.tgz",
637
+ "integrity": "sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==",
638
+ "license": "MIT",
639
+ "dependencies": {
640
+ "simple-wcswidth": "^1.1.2"
641
+ }
642
+ },
643
+ "node_modules/content-disposition": {
644
+ "version": "1.0.1",
645
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
646
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
647
+ "license": "MIT",
648
+ "engines": {
649
+ "node": ">=18"
650
+ },
651
+ "funding": {
652
+ "type": "opencollective",
653
+ "url": "https://opencollective.com/express"
654
+ }
655
+ },
656
+ "node_modules/content-type": {
657
+ "version": "1.0.5",
658
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
659
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
660
+ "license": "MIT",
661
+ "engines": {
662
+ "node": ">= 0.6"
663
+ }
664
+ },
665
+ "node_modules/cookie": {
666
+ "version": "0.7.2",
667
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
668
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
669
+ "license": "MIT",
670
+ "engines": {
671
+ "node": ">= 0.6"
672
+ }
673
+ },
674
+ "node_modules/cookie-signature": {
675
+ "version": "1.2.2",
676
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
677
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
678
+ "license": "MIT",
679
+ "engines": {
680
+ "node": ">=6.6.0"
681
+ }
682
+ },
683
+ "node_modules/cors": {
684
+ "version": "2.8.6",
685
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
686
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
687
+ "license": "MIT",
688
+ "dependencies": {
689
+ "object-assign": "^4",
690
+ "vary": "^1"
691
+ },
692
+ "engines": {
693
+ "node": ">= 0.10"
694
+ },
695
+ "funding": {
696
+ "type": "opencollective",
697
+ "url": "https://opencollective.com/express"
698
+ }
699
+ },
700
+ "node_modules/cross-spawn": {
701
+ "version": "7.0.6",
702
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
703
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
704
+ "license": "MIT",
705
+ "dependencies": {
706
+ "path-key": "^3.1.0",
707
+ "shebang-command": "^2.0.0",
708
+ "which": "^2.0.1"
709
+ },
710
+ "engines": {
711
+ "node": ">= 8"
712
+ }
713
+ },
714
+ "node_modules/debug": {
715
+ "version": "4.4.3",
716
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
717
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
718
+ "license": "MIT",
719
+ "dependencies": {
720
+ "ms": "^2.1.3"
721
+ },
722
+ "engines": {
723
+ "node": ">=6.0"
724
+ },
725
+ "peerDependenciesMeta": {
726
+ "supports-color": {
727
+ "optional": true
728
+ }
729
+ }
730
+ },
731
+ "node_modules/decamelize": {
732
+ "version": "1.2.0",
733
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
734
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
735
+ "license": "MIT",
736
+ "engines": {
737
+ "node": ">=0.10.0"
738
+ }
739
+ },
740
+ "node_modules/depd": {
741
+ "version": "2.0.0",
742
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
743
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
744
+ "license": "MIT",
745
+ "engines": {
746
+ "node": ">= 0.8"
747
+ }
748
+ },
749
+ "node_modules/dunder-proto": {
750
+ "version": "1.0.1",
751
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
752
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
753
+ "license": "MIT",
754
+ "dependencies": {
755
+ "call-bind-apply-helpers": "^1.0.1",
756
+ "es-errors": "^1.3.0",
757
+ "gopd": "^1.2.0"
758
+ },
759
+ "engines": {
760
+ "node": ">= 0.4"
761
+ }
762
+ },
763
+ "node_modules/ecdsa-sig-formatter": {
764
+ "version": "1.0.11",
765
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
766
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
767
+ "license": "Apache-2.0",
768
+ "dependencies": {
769
+ "safe-buffer": "^5.0.1"
770
+ }
771
+ },
772
+ "node_modules/ee-first": {
773
+ "version": "1.1.1",
774
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
775
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
776
+ "license": "MIT"
777
+ },
778
+ "node_modules/encodeurl": {
779
+ "version": "2.0.0",
780
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
781
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
782
+ "license": "MIT",
783
+ "engines": {
784
+ "node": ">= 0.8"
785
+ }
786
+ },
787
+ "node_modules/es-define-property": {
788
+ "version": "1.0.1",
789
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
790
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
791
+ "license": "MIT",
792
+ "engines": {
793
+ "node": ">= 0.4"
794
+ }
795
+ },
796
+ "node_modules/es-errors": {
797
+ "version": "1.3.0",
798
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
799
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
800
+ "license": "MIT",
801
+ "engines": {
802
+ "node": ">= 0.4"
803
+ }
804
+ },
805
+ "node_modules/es-object-atoms": {
806
+ "version": "1.1.1",
807
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
808
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
809
+ "license": "MIT",
810
+ "dependencies": {
811
+ "es-errors": "^1.3.0"
812
+ },
813
+ "engines": {
814
+ "node": ">= 0.4"
815
+ }
816
+ },
817
+ "node_modules/escape-html": {
818
+ "version": "1.0.3",
819
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
820
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
821
+ "license": "MIT"
822
+ },
823
+ "node_modules/etag": {
824
+ "version": "1.8.1",
825
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
826
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
827
+ "license": "MIT",
828
+ "engines": {
829
+ "node": ">= 0.6"
830
+ }
831
+ },
832
+ "node_modules/eventemitter3": {
833
+ "version": "4.0.7",
834
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
835
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
836
+ "license": "MIT"
837
+ },
838
+ "node_modules/eventsource": {
839
+ "version": "3.0.7",
840
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
841
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
842
+ "license": "MIT",
843
+ "dependencies": {
844
+ "eventsource-parser": "^3.0.1"
845
+ },
846
+ "engines": {
847
+ "node": ">=18.0.0"
848
+ }
849
+ },
850
+ "node_modules/eventsource-parser": {
851
+ "version": "3.0.6",
852
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
853
+ "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
854
+ "license": "MIT",
855
+ "engines": {
856
+ "node": ">=18.0.0"
857
+ }
858
+ },
859
+ "node_modules/express": {
860
+ "version": "5.2.1",
861
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
862
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
863
+ "license": "MIT",
864
+ "dependencies": {
865
+ "accepts": "^2.0.0",
866
+ "body-parser": "^2.2.1",
867
+ "content-disposition": "^1.0.0",
868
+ "content-type": "^1.0.5",
869
+ "cookie": "^0.7.1",
870
+ "cookie-signature": "^1.2.1",
871
+ "debug": "^4.4.0",
872
+ "depd": "^2.0.0",
873
+ "encodeurl": "^2.0.0",
874
+ "escape-html": "^1.0.3",
875
+ "etag": "^1.8.1",
876
+ "finalhandler": "^2.1.0",
877
+ "fresh": "^2.0.0",
878
+ "http-errors": "^2.0.0",
879
+ "merge-descriptors": "^2.0.0",
880
+ "mime-types": "^3.0.0",
881
+ "on-finished": "^2.4.1",
882
+ "once": "^1.4.0",
883
+ "parseurl": "^1.3.3",
884
+ "proxy-addr": "^2.0.7",
885
+ "qs": "^6.14.0",
886
+ "range-parser": "^1.2.1",
887
+ "router": "^2.2.0",
888
+ "send": "^1.1.0",
889
+ "serve-static": "^2.2.0",
890
+ "statuses": "^2.0.1",
891
+ "type-is": "^2.0.1",
892
+ "vary": "^1.1.2"
893
+ },
894
+ "engines": {
895
+ "node": ">= 18"
896
+ },
897
+ "funding": {
898
+ "type": "opencollective",
899
+ "url": "https://opencollective.com/express"
900
+ }
901
+ },
902
+ "node_modules/express-rate-limit": {
903
+ "version": "8.3.1",
904
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz",
905
+ "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==",
906
+ "license": "MIT",
907
+ "dependencies": {
908
+ "ip-address": "10.1.0"
909
+ },
910
+ "engines": {
911
+ "node": ">= 16"
912
+ },
913
+ "funding": {
914
+ "url": "https://github.com/sponsors/express-rate-limit"
915
+ },
916
+ "peerDependencies": {
917
+ "express": ">= 4.11"
918
+ }
919
+ },
920
+ "node_modules/fast-deep-equal": {
921
+ "version": "3.1.3",
922
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
923
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
924
+ "license": "MIT"
925
+ },
926
+ "node_modules/fast-uri": {
927
+ "version": "3.1.0",
928
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
929
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
930
+ "funding": [
931
+ {
932
+ "type": "github",
933
+ "url": "https://github.com/sponsors/fastify"
934
+ },
935
+ {
936
+ "type": "opencollective",
937
+ "url": "https://opencollective.com/fastify"
938
+ }
939
+ ],
940
+ "license": "BSD-3-Clause"
941
+ },
942
+ "node_modules/finalhandler": {
943
+ "version": "2.1.1",
944
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
945
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
946
+ "license": "MIT",
947
+ "dependencies": {
948
+ "debug": "^4.4.0",
949
+ "encodeurl": "^2.0.0",
950
+ "escape-html": "^1.0.3",
951
+ "on-finished": "^2.4.1",
952
+ "parseurl": "^1.3.3",
953
+ "statuses": "^2.0.1"
954
+ },
955
+ "engines": {
956
+ "node": ">= 18.0.0"
957
+ },
958
+ "funding": {
959
+ "type": "opencollective",
960
+ "url": "https://opencollective.com/express"
961
+ }
962
+ },
963
+ "node_modules/forwarded": {
964
+ "version": "0.2.0",
965
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
966
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
967
+ "license": "MIT",
968
+ "engines": {
969
+ "node": ">= 0.6"
970
+ }
971
+ },
972
+ "node_modules/fresh": {
973
+ "version": "2.0.0",
974
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
975
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
976
+ "license": "MIT",
977
+ "engines": {
978
+ "node": ">= 0.8"
979
+ }
980
+ },
981
+ "node_modules/fs-minipass": {
982
+ "version": "2.1.0",
983
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
984
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
985
+ "license": "ISC",
986
+ "dependencies": {
987
+ "minipass": "^3.0.0"
988
+ },
989
+ "engines": {
990
+ "node": ">= 8"
991
+ }
992
+ },
993
+ "node_modules/fs-minipass/node_modules/minipass": {
994
+ "version": "3.3.6",
995
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
996
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
997
+ "license": "ISC",
998
+ "dependencies": {
999
+ "yallist": "^4.0.0"
1000
+ },
1001
+ "engines": {
1002
+ "node": ">=8"
1003
+ }
1004
+ },
1005
+ "node_modules/function-bind": {
1006
+ "version": "1.1.2",
1007
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1008
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1009
+ "license": "MIT",
1010
+ "funding": {
1011
+ "url": "https://github.com/sponsors/ljharb"
1012
+ }
1013
+ },
1014
+ "node_modules/get-intrinsic": {
1015
+ "version": "1.3.0",
1016
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
1017
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
1018
+ "license": "MIT",
1019
+ "dependencies": {
1020
+ "call-bind-apply-helpers": "^1.0.2",
1021
+ "es-define-property": "^1.0.1",
1022
+ "es-errors": "^1.3.0",
1023
+ "es-object-atoms": "^1.1.1",
1024
+ "function-bind": "^1.1.2",
1025
+ "get-proto": "^1.0.1",
1026
+ "gopd": "^1.2.0",
1027
+ "has-symbols": "^1.1.0",
1028
+ "hasown": "^2.0.2",
1029
+ "math-intrinsics": "^1.1.0"
1030
+ },
1031
+ "engines": {
1032
+ "node": ">= 0.4"
1033
+ },
1034
+ "funding": {
1035
+ "url": "https://github.com/sponsors/ljharb"
1036
+ }
1037
+ },
1038
+ "node_modules/get-proto": {
1039
+ "version": "1.0.1",
1040
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
1041
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
1042
+ "license": "MIT",
1043
+ "dependencies": {
1044
+ "dunder-proto": "^1.0.1",
1045
+ "es-object-atoms": "^1.0.0"
1046
+ },
1047
+ "engines": {
1048
+ "node": ">= 0.4"
1049
+ }
1050
+ },
1051
+ "node_modules/gopd": {
1052
+ "version": "1.2.0",
1053
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
1054
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
1055
+ "license": "MIT",
1056
+ "engines": {
1057
+ "node": ">= 0.4"
1058
+ },
1059
+ "funding": {
1060
+ "url": "https://github.com/sponsors/ljharb"
1061
+ }
1062
+ },
1063
+ "node_modules/has-symbols": {
1064
+ "version": "1.1.0",
1065
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
1066
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
1067
+ "license": "MIT",
1068
+ "engines": {
1069
+ "node": ">= 0.4"
1070
+ },
1071
+ "funding": {
1072
+ "url": "https://github.com/sponsors/ljharb"
1073
+ }
1074
+ },
1075
+ "node_modules/hasown": {
1076
+ "version": "2.0.2",
1077
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1078
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1079
+ "license": "MIT",
1080
+ "dependencies": {
1081
+ "function-bind": "^1.1.2"
1082
+ },
1083
+ "engines": {
1084
+ "node": ">= 0.4"
1085
+ }
1086
+ },
1087
+ "node_modules/hono": {
1088
+ "version": "4.12.9",
1089
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz",
1090
+ "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==",
1091
+ "license": "MIT",
1092
+ "engines": {
1093
+ "node": ">=16.9.0"
1094
+ }
1095
+ },
1096
+ "node_modules/http-errors": {
1097
+ "version": "2.0.1",
1098
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
1099
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
1100
+ "license": "MIT",
1101
+ "dependencies": {
1102
+ "depd": "~2.0.0",
1103
+ "inherits": "~2.0.4",
1104
+ "setprototypeof": "~1.2.0",
1105
+ "statuses": "~2.0.2",
1106
+ "toidentifier": "~1.0.1"
1107
+ },
1108
+ "engines": {
1109
+ "node": ">= 0.8"
1110
+ },
1111
+ "funding": {
1112
+ "type": "opencollective",
1113
+ "url": "https://opencollective.com/express"
1114
+ }
1115
+ },
1116
+ "node_modules/iceberg-js": {
1117
+ "version": "0.8.1",
1118
+ "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
1119
+ "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
1120
+ "license": "MIT",
1121
+ "engines": {
1122
+ "node": ">=20.0.0"
1123
+ }
1124
+ },
1125
+ "node_modules/iconv-lite": {
1126
+ "version": "0.7.2",
1127
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
1128
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
1129
+ "license": "MIT",
1130
+ "dependencies": {
1131
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
1132
+ },
1133
+ "engines": {
1134
+ "node": ">=0.10.0"
1135
+ },
1136
+ "funding": {
1137
+ "type": "opencollective",
1138
+ "url": "https://opencollective.com/express"
1139
+ }
1140
+ },
1141
+ "node_modules/inherits": {
1142
+ "version": "2.0.4",
1143
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1144
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1145
+ "license": "ISC"
1146
+ },
1147
+ "node_modules/ip-address": {
1148
+ "version": "10.1.0",
1149
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
1150
+ "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
1151
+ "license": "MIT",
1152
+ "engines": {
1153
+ "node": ">= 12"
1154
+ }
1155
+ },
1156
+ "node_modules/ipaddr.js": {
1157
+ "version": "1.9.1",
1158
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1159
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
1160
+ "license": "MIT",
1161
+ "engines": {
1162
+ "node": ">= 0.10"
1163
+ }
1164
+ },
1165
+ "node_modules/is-network-error": {
1166
+ "version": "1.3.1",
1167
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz",
1168
+ "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==",
1169
+ "license": "MIT",
1170
+ "engines": {
1171
+ "node": ">=16"
1172
+ },
1173
+ "funding": {
1174
+ "url": "https://github.com/sponsors/sindresorhus"
1175
+ }
1176
+ },
1177
+ "node_modules/is-promise": {
1178
+ "version": "4.0.0",
1179
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
1180
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
1181
+ "license": "MIT"
1182
+ },
1183
+ "node_modules/isexe": {
1184
+ "version": "2.0.0",
1185
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1186
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1187
+ "license": "ISC"
1188
+ },
1189
+ "node_modules/jose": {
1190
+ "version": "6.2.2",
1191
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz",
1192
+ "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==",
1193
+ "license": "MIT",
1194
+ "funding": {
1195
+ "url": "https://github.com/sponsors/panva"
1196
+ }
1197
+ },
1198
+ "node_modules/js-tiktoken": {
1199
+ "version": "1.0.21",
1200
+ "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
1201
+ "integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==",
1202
+ "license": "MIT",
1203
+ "dependencies": {
1204
+ "base64-js": "^1.5.1"
1205
+ }
1206
+ },
1207
+ "node_modules/json-schema-traverse": {
1208
+ "version": "1.0.0",
1209
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
1210
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
1211
+ "license": "MIT"
1212
+ },
1213
+ "node_modules/json-schema-typed": {
1214
+ "version": "8.0.2",
1215
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
1216
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
1217
+ "license": "BSD-2-Clause"
1218
+ },
1219
+ "node_modules/jsonwebtoken": {
1220
+ "version": "9.0.3",
1221
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz",
1222
+ "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==",
1223
+ "license": "MIT",
1224
+ "dependencies": {
1225
+ "jws": "^4.0.1",
1226
+ "lodash.includes": "^4.3.0",
1227
+ "lodash.isboolean": "^3.0.3",
1228
+ "lodash.isinteger": "^4.0.4",
1229
+ "lodash.isnumber": "^3.0.3",
1230
+ "lodash.isplainobject": "^4.0.6",
1231
+ "lodash.isstring": "^4.0.1",
1232
+ "lodash.once": "^4.0.0",
1233
+ "ms": "^2.1.1",
1234
+ "semver": "^7.5.4"
1235
+ },
1236
+ "engines": {
1237
+ "node": ">=12",
1238
+ "npm": ">=6"
1239
+ }
1240
+ },
1241
+ "node_modules/jwa": {
1242
+ "version": "2.0.1",
1243
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
1244
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
1245
+ "license": "MIT",
1246
+ "dependencies": {
1247
+ "buffer-equal-constant-time": "^1.0.1",
1248
+ "ecdsa-sig-formatter": "1.0.11",
1249
+ "safe-buffer": "^5.0.1"
1250
+ }
1251
+ },
1252
+ "node_modules/jws": {
1253
+ "version": "4.0.1",
1254
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
1255
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
1256
+ "license": "MIT",
1257
+ "dependencies": {
1258
+ "jwa": "^2.0.1",
1259
+ "safe-buffer": "^5.0.1"
1260
+ }
1261
+ },
1262
+ "node_modules/langsmith": {
1263
+ "version": "0.5.13",
1264
+ "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.5.13.tgz",
1265
+ "integrity": "sha512-arD4XzLdMTyb3rrKVainpXG9vtJPL3urOc/fC/yMHeoorK5KSHsvBWkogZUgjCsLkhtH8FdfSEAAG8Am8DNoYQ==",
1266
+ "license": "MIT",
1267
+ "dependencies": {
1268
+ "@types/uuid": "^10.0.0",
1269
+ "chalk": "^5.6.2",
1270
+ "console-table-printer": "^2.12.1",
1271
+ "p-queue": "^6.6.2",
1272
+ "semver": "^7.6.3",
1273
+ "uuid": "^10.0.0"
1274
+ },
1275
+ "peerDependencies": {
1276
+ "@opentelemetry/api": "*",
1277
+ "@opentelemetry/exporter-trace-otlp-proto": "*",
1278
+ "@opentelemetry/sdk-trace-base": "*",
1279
+ "openai": "*",
1280
+ "ws": ">=7"
1281
+ },
1282
+ "peerDependenciesMeta": {
1283
+ "@opentelemetry/api": {
1284
+ "optional": true
1285
+ },
1286
+ "@opentelemetry/exporter-trace-otlp-proto": {
1287
+ "optional": true
1288
+ },
1289
+ "@opentelemetry/sdk-trace-base": {
1290
+ "optional": true
1291
+ },
1292
+ "openai": {
1293
+ "optional": true
1294
+ },
1295
+ "ws": {
1296
+ "optional": true
1297
+ }
1298
+ }
1299
+ },
1300
+ "node_modules/langsmith/node_modules/uuid": {
1301
+ "version": "10.0.0",
1302
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
1303
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
1304
+ "funding": [
1305
+ "https://github.com/sponsors/broofa",
1306
+ "https://github.com/sponsors/ctavan"
1307
+ ],
1308
+ "license": "MIT",
1309
+ "bin": {
1310
+ "uuid": "dist/bin/uuid"
1311
+ }
1312
+ },
1313
+ "node_modules/lodash.includes": {
1314
+ "version": "4.3.0",
1315
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
1316
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
1317
+ "license": "MIT"
1318
+ },
1319
+ "node_modules/lodash.isboolean": {
1320
+ "version": "3.0.3",
1321
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
1322
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
1323
+ "license": "MIT"
1324
+ },
1325
+ "node_modules/lodash.isinteger": {
1326
+ "version": "4.0.4",
1327
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
1328
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
1329
+ "license": "MIT"
1330
+ },
1331
+ "node_modules/lodash.isnumber": {
1332
+ "version": "3.0.3",
1333
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
1334
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
1335
+ "license": "MIT"
1336
+ },
1337
+ "node_modules/lodash.isplainobject": {
1338
+ "version": "4.0.6",
1339
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1340
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
1341
+ "license": "MIT"
1342
+ },
1343
+ "node_modules/lodash.isstring": {
1344
+ "version": "4.0.1",
1345
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
1346
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
1347
+ "license": "MIT"
1348
+ },
1349
+ "node_modules/lodash.once": {
1350
+ "version": "4.1.1",
1351
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
1352
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
1353
+ "license": "MIT"
1354
+ },
1355
+ "node_modules/math-intrinsics": {
1356
+ "version": "1.1.0",
1357
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
1358
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
1359
+ "license": "MIT",
1360
+ "engines": {
1361
+ "node": ">= 0.4"
1362
+ }
1363
+ },
1364
+ "node_modules/media-typer": {
1365
+ "version": "1.1.0",
1366
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
1367
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
1368
+ "license": "MIT",
1369
+ "engines": {
1370
+ "node": ">= 0.8"
1371
+ }
1372
+ },
1373
+ "node_modules/merge-descriptors": {
1374
+ "version": "2.0.0",
1375
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
1376
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
1377
+ "license": "MIT",
1378
+ "engines": {
1379
+ "node": ">=18"
1380
+ },
1381
+ "funding": {
1382
+ "url": "https://github.com/sponsors/sindresorhus"
1383
+ }
1384
+ },
1385
+ "node_modules/mime-db": {
1386
+ "version": "1.54.0",
1387
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
1388
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
1389
+ "license": "MIT",
1390
+ "engines": {
1391
+ "node": ">= 0.6"
1392
+ }
1393
+ },
1394
+ "node_modules/mime-types": {
1395
+ "version": "3.0.2",
1396
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
1397
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
1398
+ "license": "MIT",
1399
+ "dependencies": {
1400
+ "mime-db": "^1.54.0"
1401
+ },
1402
+ "engines": {
1403
+ "node": ">=18"
1404
+ },
1405
+ "funding": {
1406
+ "type": "opencollective",
1407
+ "url": "https://opencollective.com/express"
1408
+ }
1409
+ },
1410
+ "node_modules/minipass": {
1411
+ "version": "4.2.8",
1412
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
1413
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
1414
+ "dev": true,
1415
+ "license": "ISC",
1416
+ "engines": {
1417
+ "node": ">=8"
1418
+ }
1419
+ },
1420
+ "node_modules/minizlib": {
1421
+ "version": "2.1.2",
1422
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
1423
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
1424
+ "license": "MIT",
1425
+ "dependencies": {
1426
+ "minipass": "^3.0.0",
1427
+ "yallist": "^4.0.0"
1428
+ },
1429
+ "engines": {
1430
+ "node": ">= 8"
1431
+ }
1432
+ },
1433
+ "node_modules/minizlib/node_modules/minipass": {
1434
+ "version": "3.3.6",
1435
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
1436
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
1437
+ "license": "ISC",
1438
+ "dependencies": {
1439
+ "yallist": "^4.0.0"
1440
+ },
1441
+ "engines": {
1442
+ "node": ">=8"
1443
+ }
1444
+ },
1445
+ "node_modules/mkdirp": {
1446
+ "version": "1.0.4",
1447
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
1448
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
1449
+ "license": "MIT",
1450
+ "bin": {
1451
+ "mkdirp": "bin/cmd.js"
1452
+ },
1453
+ "engines": {
1454
+ "node": ">=10"
1455
+ }
1456
+ },
1457
+ "node_modules/ms": {
1458
+ "version": "2.1.3",
1459
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1460
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1461
+ "license": "MIT"
1462
+ },
1463
+ "node_modules/mustache": {
1464
+ "version": "4.2.0",
1465
+ "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
1466
+ "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
1467
+ "license": "MIT",
1468
+ "bin": {
1469
+ "mustache": "bin/mustache"
1470
+ }
1471
+ },
1472
+ "node_modules/negotiator": {
1473
+ "version": "1.0.0",
1474
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
1475
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
1476
+ "license": "MIT",
1477
+ "engines": {
1478
+ "node": ">= 0.6"
1479
+ }
1480
+ },
1481
+ "node_modules/node-cron": {
1482
+ "version": "3.0.3",
1483
+ "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz",
1484
+ "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==",
1485
+ "license": "ISC",
1486
+ "dependencies": {
1487
+ "uuid": "8.3.2"
1488
+ },
1489
+ "engines": {
1490
+ "node": ">=6.0.0"
1491
+ }
1492
+ },
1493
+ "node_modules/node-cron/node_modules/uuid": {
1494
+ "version": "8.3.2",
1495
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
1496
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
1497
+ "license": "MIT",
1498
+ "bin": {
1499
+ "uuid": "dist/bin/uuid"
1500
+ }
1501
+ },
1502
+ "node_modules/object-assign": {
1503
+ "version": "4.1.1",
1504
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1505
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1506
+ "license": "MIT",
1507
+ "engines": {
1508
+ "node": ">=0.10.0"
1509
+ }
1510
+ },
1511
+ "node_modules/object-inspect": {
1512
+ "version": "1.13.4",
1513
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
1514
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
1515
+ "license": "MIT",
1516
+ "engines": {
1517
+ "node": ">= 0.4"
1518
+ },
1519
+ "funding": {
1520
+ "url": "https://github.com/sponsors/ljharb"
1521
+ }
1522
+ },
1523
+ "node_modules/on-finished": {
1524
+ "version": "2.4.1",
1525
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1526
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1527
+ "license": "MIT",
1528
+ "dependencies": {
1529
+ "ee-first": "1.1.1"
1530
+ },
1531
+ "engines": {
1532
+ "node": ">= 0.8"
1533
+ }
1534
+ },
1535
+ "node_modules/once": {
1536
+ "version": "1.4.0",
1537
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1538
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1539
+ "license": "ISC",
1540
+ "dependencies": {
1541
+ "wrappy": "1"
1542
+ }
1543
+ },
1544
+ "node_modules/openai": {
1545
+ "version": "6.32.0",
1546
+ "resolved": "https://registry.npmjs.org/openai/-/openai-6.32.0.tgz",
1547
+ "integrity": "sha512-j3k+BjydAf8yQlcOI7WUQMQTbbF5GEIMAE2iZYCOzwwB3S2pCheaWYp+XZRNAch4jWVc52PMDGRRjutao3lLCg==",
1548
+ "license": "Apache-2.0",
1549
+ "bin": {
1550
+ "openai": "bin/cli"
1551
+ },
1552
+ "peerDependencies": {
1553
+ "ws": "^8.18.0",
1554
+ "zod": "^3.25 || ^4.0"
1555
+ },
1556
+ "peerDependenciesMeta": {
1557
+ "ws": {
1558
+ "optional": true
1559
+ },
1560
+ "zod": {
1561
+ "optional": true
1562
+ }
1563
+ }
1564
+ },
1565
+ "node_modules/p-finally": {
1566
+ "version": "1.0.0",
1567
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
1568
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
1569
+ "license": "MIT",
1570
+ "engines": {
1571
+ "node": ">=4"
1572
+ }
1573
+ },
1574
+ "node_modules/p-queue": {
1575
+ "version": "6.6.2",
1576
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
1577
+ "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
1578
+ "license": "MIT",
1579
+ "dependencies": {
1580
+ "eventemitter3": "^4.0.4",
1581
+ "p-timeout": "^3.2.0"
1582
+ },
1583
+ "engines": {
1584
+ "node": ">=8"
1585
+ },
1586
+ "funding": {
1587
+ "url": "https://github.com/sponsors/sindresorhus"
1588
+ }
1589
+ },
1590
+ "node_modules/p-retry": {
1591
+ "version": "7.1.1",
1592
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-7.1.1.tgz",
1593
+ "integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
1594
+ "license": "MIT",
1595
+ "dependencies": {
1596
+ "is-network-error": "^1.1.0"
1597
+ },
1598
+ "engines": {
1599
+ "node": ">=20"
1600
+ },
1601
+ "funding": {
1602
+ "url": "https://github.com/sponsors/sindresorhus"
1603
+ }
1604
+ },
1605
+ "node_modules/p-timeout": {
1606
+ "version": "3.2.0",
1607
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
1608
+ "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
1609
+ "license": "MIT",
1610
+ "dependencies": {
1611
+ "p-finally": "^1.0.0"
1612
+ },
1613
+ "engines": {
1614
+ "node": ">=8"
1615
+ }
1616
+ },
1617
+ "node_modules/parseurl": {
1618
+ "version": "1.3.3",
1619
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1620
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1621
+ "license": "MIT",
1622
+ "engines": {
1623
+ "node": ">= 0.8"
1624
+ }
1625
+ },
1626
+ "node_modules/path-key": {
1627
+ "version": "3.1.1",
1628
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1629
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1630
+ "license": "MIT",
1631
+ "engines": {
1632
+ "node": ">=8"
1633
+ }
1634
+ },
1635
+ "node_modules/path-to-regexp": {
1636
+ "version": "8.3.0",
1637
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
1638
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
1639
+ "license": "MIT",
1640
+ "funding": {
1641
+ "type": "opencollective",
1642
+ "url": "https://opencollective.com/express"
1643
+ }
1644
+ },
1645
+ "node_modules/pkce-challenge": {
1646
+ "version": "5.0.1",
1647
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
1648
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
1649
+ "license": "MIT",
1650
+ "engines": {
1651
+ "node": ">=16.20.0"
1652
+ }
1653
+ },
1654
+ "node_modules/proxy-addr": {
1655
+ "version": "2.0.7",
1656
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1657
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1658
+ "license": "MIT",
1659
+ "dependencies": {
1660
+ "forwarded": "0.2.0",
1661
+ "ipaddr.js": "1.9.1"
1662
+ },
1663
+ "engines": {
1664
+ "node": ">= 0.10"
1665
+ }
1666
+ },
1667
+ "node_modules/qs": {
1668
+ "version": "6.15.0",
1669
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
1670
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
1671
+ "license": "BSD-3-Clause",
1672
+ "dependencies": {
1673
+ "side-channel": "^1.1.0"
1674
+ },
1675
+ "engines": {
1676
+ "node": ">=0.6"
1677
+ },
1678
+ "funding": {
1679
+ "url": "https://github.com/sponsors/ljharb"
1680
+ }
1681
+ },
1682
+ "node_modules/range-parser": {
1683
+ "version": "1.2.1",
1684
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1685
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1686
+ "license": "MIT",
1687
+ "engines": {
1688
+ "node": ">= 0.6"
1689
+ }
1690
+ },
1691
+ "node_modules/raw-body": {
1692
+ "version": "3.0.2",
1693
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
1694
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
1695
+ "license": "MIT",
1696
+ "dependencies": {
1697
+ "bytes": "~3.1.2",
1698
+ "http-errors": "~2.0.1",
1699
+ "iconv-lite": "~0.7.0",
1700
+ "unpipe": "~1.0.0"
1701
+ },
1702
+ "engines": {
1703
+ "node": ">= 0.10"
1704
+ }
1705
+ },
1706
+ "node_modules/require-from-string": {
1707
+ "version": "2.0.2",
1708
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
1709
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
1710
+ "license": "MIT",
1711
+ "engines": {
1712
+ "node": ">=0.10.0"
1713
+ }
1714
+ },
1715
+ "node_modules/router": {
1716
+ "version": "2.2.0",
1717
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
1718
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
1719
+ "license": "MIT",
1720
+ "dependencies": {
1721
+ "debug": "^4.4.0",
1722
+ "depd": "^2.0.0",
1723
+ "is-promise": "^4.0.0",
1724
+ "parseurl": "^1.3.3",
1725
+ "path-to-regexp": "^8.0.0"
1726
+ },
1727
+ "engines": {
1728
+ "node": ">= 18"
1729
+ }
1730
+ },
1731
+ "node_modules/safe-buffer": {
1732
+ "version": "5.2.1",
1733
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1734
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1735
+ "funding": [
1736
+ {
1737
+ "type": "github",
1738
+ "url": "https://github.com/sponsors/feross"
1739
+ },
1740
+ {
1741
+ "type": "patreon",
1742
+ "url": "https://www.patreon.com/feross"
1743
+ },
1744
+ {
1745
+ "type": "consulting",
1746
+ "url": "https://feross.org/support"
1747
+ }
1748
+ ],
1749
+ "license": "MIT"
1750
+ },
1751
+ "node_modules/safer-buffer": {
1752
+ "version": "2.1.2",
1753
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1754
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1755
+ "license": "MIT"
1756
+ },
1757
+ "node_modules/semver": {
1758
+ "version": "7.7.4",
1759
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
1760
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
1761
+ "license": "ISC",
1762
+ "bin": {
1763
+ "semver": "bin/semver.js"
1764
+ },
1765
+ "engines": {
1766
+ "node": ">=10"
1767
+ }
1768
+ },
1769
+ "node_modules/send": {
1770
+ "version": "1.2.1",
1771
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
1772
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
1773
+ "license": "MIT",
1774
+ "dependencies": {
1775
+ "debug": "^4.4.3",
1776
+ "encodeurl": "^2.0.0",
1777
+ "escape-html": "^1.0.3",
1778
+ "etag": "^1.8.1",
1779
+ "fresh": "^2.0.0",
1780
+ "http-errors": "^2.0.1",
1781
+ "mime-types": "^3.0.2",
1782
+ "ms": "^2.1.3",
1783
+ "on-finished": "^2.4.1",
1784
+ "range-parser": "^1.2.1",
1785
+ "statuses": "^2.0.2"
1786
+ },
1787
+ "engines": {
1788
+ "node": ">= 18"
1789
+ },
1790
+ "funding": {
1791
+ "type": "opencollective",
1792
+ "url": "https://opencollective.com/express"
1793
+ }
1794
+ },
1795
+ "node_modules/serve-static": {
1796
+ "version": "2.2.1",
1797
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
1798
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
1799
+ "license": "MIT",
1800
+ "dependencies": {
1801
+ "encodeurl": "^2.0.0",
1802
+ "escape-html": "^1.0.3",
1803
+ "parseurl": "^1.3.3",
1804
+ "send": "^1.2.0"
1805
+ },
1806
+ "engines": {
1807
+ "node": ">= 18"
1808
+ },
1809
+ "funding": {
1810
+ "type": "opencollective",
1811
+ "url": "https://opencollective.com/express"
1812
+ }
1813
+ },
1814
+ "node_modules/setprototypeof": {
1815
+ "version": "1.2.0",
1816
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1817
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1818
+ "license": "ISC"
1819
+ },
1820
+ "node_modules/shebang-command": {
1821
+ "version": "2.0.0",
1822
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1823
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1824
+ "license": "MIT",
1825
+ "dependencies": {
1826
+ "shebang-regex": "^3.0.0"
1827
+ },
1828
+ "engines": {
1829
+ "node": ">=8"
1830
+ }
1831
+ },
1832
+ "node_modules/shebang-regex": {
1833
+ "version": "3.0.0",
1834
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1835
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1836
+ "license": "MIT",
1837
+ "engines": {
1838
+ "node": ">=8"
1839
+ }
1840
+ },
1841
+ "node_modules/side-channel": {
1842
+ "version": "1.1.0",
1843
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
1844
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
1845
+ "license": "MIT",
1846
+ "dependencies": {
1847
+ "es-errors": "^1.3.0",
1848
+ "object-inspect": "^1.13.3",
1849
+ "side-channel-list": "^1.0.0",
1850
+ "side-channel-map": "^1.0.1",
1851
+ "side-channel-weakmap": "^1.0.2"
1852
+ },
1853
+ "engines": {
1854
+ "node": ">= 0.4"
1855
+ },
1856
+ "funding": {
1857
+ "url": "https://github.com/sponsors/ljharb"
1858
+ }
1859
+ },
1860
+ "node_modules/side-channel-list": {
1861
+ "version": "1.0.0",
1862
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
1863
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
1864
+ "license": "MIT",
1865
+ "dependencies": {
1866
+ "es-errors": "^1.3.0",
1867
+ "object-inspect": "^1.13.3"
1868
+ },
1869
+ "engines": {
1870
+ "node": ">= 0.4"
1871
+ },
1872
+ "funding": {
1873
+ "url": "https://github.com/sponsors/ljharb"
1874
+ }
1875
+ },
1876
+ "node_modules/side-channel-map": {
1877
+ "version": "1.0.1",
1878
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
1879
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
1880
+ "license": "MIT",
1881
+ "dependencies": {
1882
+ "call-bound": "^1.0.2",
1883
+ "es-errors": "^1.3.0",
1884
+ "get-intrinsic": "^1.2.5",
1885
+ "object-inspect": "^1.13.3"
1886
+ },
1887
+ "engines": {
1888
+ "node": ">= 0.4"
1889
+ },
1890
+ "funding": {
1891
+ "url": "https://github.com/sponsors/ljharb"
1892
+ }
1893
+ },
1894
+ "node_modules/side-channel-weakmap": {
1895
+ "version": "1.0.2",
1896
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
1897
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
1898
+ "license": "MIT",
1899
+ "dependencies": {
1900
+ "call-bound": "^1.0.2",
1901
+ "es-errors": "^1.3.0",
1902
+ "get-intrinsic": "^1.2.5",
1903
+ "object-inspect": "^1.13.3",
1904
+ "side-channel-map": "^1.0.1"
1905
+ },
1906
+ "engines": {
1907
+ "node": ">= 0.4"
1908
+ },
1909
+ "funding": {
1910
+ "url": "https://github.com/sponsors/ljharb"
1911
+ }
1912
+ },
1913
+ "node_modules/simple-wcswidth": {
1914
+ "version": "1.1.2",
1915
+ "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz",
1916
+ "integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==",
1917
+ "license": "MIT"
1918
+ },
1919
+ "node_modules/statuses": {
1920
+ "version": "2.0.2",
1921
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
1922
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
1923
+ "license": "MIT",
1924
+ "engines": {
1925
+ "node": ">= 0.8"
1926
+ }
1927
+ },
1928
+ "node_modules/tar": {
1929
+ "version": "6.2.1",
1930
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
1931
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
1932
+ "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
1933
+ "license": "ISC",
1934
+ "dependencies": {
1935
+ "chownr": "^2.0.0",
1936
+ "fs-minipass": "^2.0.0",
1937
+ "minipass": "^5.0.0",
1938
+ "minizlib": "^2.1.1",
1939
+ "mkdirp": "^1.0.3",
1940
+ "yallist": "^4.0.0"
1941
+ },
1942
+ "engines": {
1943
+ "node": ">=10"
1944
+ }
1945
+ },
1946
+ "node_modules/tar/node_modules/minipass": {
1947
+ "version": "5.0.0",
1948
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
1949
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
1950
+ "license": "ISC",
1951
+ "engines": {
1952
+ "node": ">=8"
1953
+ }
1954
+ },
1955
+ "node_modules/toidentifier": {
1956
+ "version": "1.0.1",
1957
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1958
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1959
+ "license": "MIT",
1960
+ "engines": {
1961
+ "node": ">=0.6"
1962
+ }
1963
+ },
1964
+ "node_modules/tslib": {
1965
+ "version": "2.8.1",
1966
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1967
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1968
+ "license": "0BSD"
1969
+ },
1970
+ "node_modules/type-is": {
1971
+ "version": "2.0.1",
1972
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1973
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1974
+ "license": "MIT",
1975
+ "dependencies": {
1976
+ "content-type": "^1.0.5",
1977
+ "media-typer": "^1.1.0",
1978
+ "mime-types": "^3.0.0"
1979
+ },
1980
+ "engines": {
1981
+ "node": ">= 0.6"
1982
+ }
1983
+ },
1984
+ "node_modules/typescript": {
1985
+ "version": "5.9.3",
1986
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
1987
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
1988
+ "dev": true,
1989
+ "license": "Apache-2.0",
1990
+ "bin": {
1991
+ "tsc": "bin/tsc",
1992
+ "tsserver": "bin/tsserver"
1993
+ },
1994
+ "engines": {
1995
+ "node": ">=14.17"
1996
+ }
1997
+ },
1998
+ "node_modules/undici-types": {
1999
+ "version": "7.16.0",
2000
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
2001
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
2002
+ "license": "MIT"
2003
+ },
2004
+ "node_modules/unpipe": {
2005
+ "version": "1.0.0",
2006
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2007
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
2008
+ "license": "MIT",
2009
+ "engines": {
2010
+ "node": ">= 0.8"
2011
+ }
2012
+ },
2013
+ "node_modules/uuid": {
2014
+ "version": "11.1.0",
2015
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
2016
+ "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
2017
+ "funding": [
2018
+ "https://github.com/sponsors/broofa",
2019
+ "https://github.com/sponsors/ctavan"
2020
+ ],
2021
+ "license": "MIT",
2022
+ "bin": {
2023
+ "uuid": "dist/esm/bin/uuid"
2024
+ }
2025
+ },
2026
+ "node_modules/vary": {
2027
+ "version": "1.1.2",
2028
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2029
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
2030
+ "license": "MIT",
2031
+ "engines": {
2032
+ "node": ">= 0.8"
2033
+ }
2034
+ },
2035
+ "node_modules/which": {
2036
+ "version": "2.0.2",
2037
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2038
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2039
+ "license": "ISC",
2040
+ "dependencies": {
2041
+ "isexe": "^2.0.0"
2042
+ },
2043
+ "bin": {
2044
+ "node-which": "bin/node-which"
2045
+ },
2046
+ "engines": {
2047
+ "node": ">= 8"
2048
+ }
2049
+ },
2050
+ "node_modules/wrappy": {
2051
+ "version": "1.0.2",
2052
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2053
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
2054
+ "license": "ISC"
2055
+ },
2056
+ "node_modules/ws": {
2057
+ "version": "8.20.0",
2058
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
2059
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
2060
+ "license": "MIT",
2061
+ "engines": {
2062
+ "node": ">=10.0.0"
2063
+ },
2064
+ "peerDependencies": {
2065
+ "bufferutil": "^4.0.1",
2066
+ "utf-8-validate": ">=5.0.2"
2067
+ },
2068
+ "peerDependenciesMeta": {
2069
+ "bufferutil": {
2070
+ "optional": true
2071
+ },
2072
+ "utf-8-validate": {
2073
+ "optional": true
2074
+ }
2075
+ }
2076
+ },
2077
+ "node_modules/yallist": {
2078
+ "version": "4.0.0",
2079
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2080
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
2081
+ "license": "ISC"
2082
+ },
2083
+ "node_modules/zod": {
2084
+ "version": "3.25.76",
2085
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
2086
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
2087
+ "license": "MIT",
2088
+ "funding": {
2089
+ "url": "https://github.com/sponsors/colinhacks"
2090
+ }
2091
+ },
2092
+ "node_modules/zod-to-json-schema": {
2093
+ "version": "3.25.1",
2094
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz",
2095
+ "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==",
2096
+ "license": "ISC",
2097
+ "peerDependencies": {
2098
+ "zod": "^3.25 || ^4"
2099
+ }
2100
+ }
2101
+ }
2102
+ }
package.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@opensin-backend/sin-code-ai",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "types": "dist/src/index.d.ts",
8
+ "bin": {
9
+ "sin-code-ai": "dist/src/cli.js"
10
+ },
11
+ "scripts": {
12
+ "build": "rm -rf dist && tsc -p tsconfig.json && node scripts/postbuild.mjs",
13
+ "typecheck": "tsc --noEmit -p tsconfig.json",
14
+ "start:a2a": "node dist/src/cli.js serve-a2a",
15
+ "start:mcp": "node dist/src/cli.js serve-mcp"
16
+ },
17
+ "dependencies": {
18
+ "@huggingface/hub": "^0.15.1",
19
+ "@langchain/core": "^1.1.36",
20
+ "@langchain/langgraph": "^1.2.5",
21
+ "@langchain/openai": "^1.3.0",
22
+ "@modelcontextprotocol/sdk": "latest",
23
+ "@supabase/supabase-js": "^2.39.7",
24
+ "node-cron": "^3.0.3",
25
+ "tar": "^6.2.0",
26
+ "zod": "^3.25.76"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^24.3.0",
30
+ "@types/node-cron": "^3.0.11",
31
+ "@types/tar": "^6.1.11",
32
+ "typescript": "^5.9.3"
33
+ }
34
+ }
runbooks/install.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Install
2
+
3
+ Use `scripts/complete-install.sh` as the single supported install path.
runbooks/launchagent.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # LaunchAgent
2
+
3
+ Record install, verify, restart, rollback, and login-cycle survival steps here.
scripts/__pycache__/hf_pull_script.cpython-314.pyc ADDED
Binary file (7.02 kB). View file
 
scripts/botfather-create.sh ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # botfather-create.sh — Autonomous BotFather bot creation via Telegram.app AppleScript
3
+ # Usage: ./scripts/botfather-create.sh --name <BotName> --username <botusername_bot> [--alias <local-alias>]
4
+ #
5
+ # What this does (zero manual steps):
6
+ # 1. Opens Telegram.app and navigates to @BotFather
7
+ # 2. Sends /newbot command
8
+ # 3. Sends the display name
9
+ # 4. Sends the username
10
+ # 5. Captures the token from BotFather's reply via getUpdates
11
+ # 6. Registers the new bot with sin-telegrambot CLI
12
+ # 7. Bootstraps chat_id
13
+ #
14
+ # Requirements:
15
+ # - Telegram.app installed and logged in
16
+ # - sin-telegrambot CLI: ~/.local/bin/sin-telegrambot
17
+ # - macOS (uses AppleScript / osascript)
18
+ # - BotFather must not be rate-limiting (wait 60s if you just created a bot)
19
+ #
20
+ # Part of: A2A-SIN-Agent-Template canonical scripts
21
+ # Canonical CLI: sin-telegrambot
22
+
23
+ set -euo pipefail
24
+
25
+ BOT_DISPLAY_NAME=""
26
+ BOT_USERNAME=""
27
+ BOT_ALIAS=""
28
+
29
+ while [[ $# -gt 0 ]]; do
30
+ case "$1" in
31
+ --name) BOT_DISPLAY_NAME="$2"; shift 2 ;;
32
+ --username) BOT_USERNAME="$2"; shift 2 ;;
33
+ --alias) BOT_ALIAS="$2"; shift 2 ;;
34
+ *) echo "Unknown arg: $1" >&2; exit 1 ;;
35
+ esac
36
+ done
37
+
38
+ if [[ -z "$BOT_DISPLAY_NAME" || -z "$BOT_USERNAME" ]]; then
39
+ echo "Usage: $0 --name <DisplayName> --username <botusername_bot> [--alias <local-alias>]"
40
+ echo " --name Display name for the bot (e.g. 'My Agent Bot')"
41
+ echo " --username Bot username, must end in _bot (e.g. 'myagentbot_bot')"
42
+ echo " --alias Local alias for sin-telegrambot registry (default: username without _bot)"
43
+ exit 1
44
+ fi
45
+
46
+ # Derive alias from username if not given
47
+ if [[ -z "$BOT_ALIAS" ]]; then
48
+ BOT_ALIAS="${BOT_USERNAME%_bot}"
49
+ BOT_ALIAS="${BOT_ALIAS,,}"
50
+ fi
51
+
52
+ # BotFather token is well-known (not secret) — it's the Telegram-provided token for @BotFather itself
53
+ BOTFATHER_USERNAME="BotFather"
54
+
55
+ echo "[INFO] Creating Telegram bot via BotFather (AppleScript)"
56
+ echo " Display name: $BOT_DISPLAY_NAME"
57
+ echo " Username: $BOT_USERNAME"
58
+ echo " Local alias: $BOT_ALIAS"
59
+ echo ""
60
+
61
+ # Step 1: Open Telegram and navigate to BotFather, send /newbot
62
+ osascript <<APPLESCRIPT
63
+ tell application "Telegram"
64
+ activate
65
+ end tell
66
+ delay 2.0
67
+ tell application "System Events"
68
+ tell process "Telegram"
69
+ -- Open search (Cmd+K)
70
+ keystroke "k" using command down
71
+ delay 1.0
72
+ -- Type BotFather
73
+ keystroke "@${BOTFATHER_USERNAME}"
74
+ delay 1.5
75
+ -- Select first result
76
+ key code 36
77
+ delay 1.5
78
+ -- Send /newbot
79
+ keystroke "/newbot"
80
+ key code 36
81
+ delay 1.0
82
+ end tell
83
+ end tell
84
+ APPLESCRIPT
85
+
86
+ echo "[INFO] Sent /newbot — waiting 4s for BotFather reply..."
87
+ sleep 4
88
+
89
+ # Step 2: Send display name
90
+ osascript <<APPLESCRIPT
91
+ tell application "System Events"
92
+ tell process "Telegram"
93
+ keystroke "${BOT_DISPLAY_NAME}"
94
+ key code 36
95
+ delay 1.0
96
+ end tell
97
+ end tell
98
+ APPLESCRIPT
99
+
100
+ echo "[INFO] Sent display name '$BOT_DISPLAY_NAME' — waiting 4s..."
101
+ sleep 4
102
+
103
+ # Step 3: Send username
104
+ osascript <<APPLESCRIPT
105
+ tell application "System Events"
106
+ tell process "Telegram"
107
+ keystroke "${BOT_USERNAME}"
108
+ key code 36
109
+ delay 1.0
110
+ end tell
111
+ end tell
112
+ APPLESCRIPT
113
+
114
+ echo "[INFO] Sent username '$BOT_USERNAME' — waiting 6s for token..."
115
+ sleep 6
116
+
117
+ # Step 4: We need a BotFather listener token to poll for the created bot token
118
+ # We use the SIN Fleet watcher bot (sin-telegrambot default) if available,
119
+ # OR we ask the user to paste the token from the Telegram screen.
120
+ # Strategy: try to capture token from macOS clipboard (BotFather's message is selectable)
121
+
122
+ echo "[INFO] Attempting to capture bot token from Telegram (BotFather reply)..."
123
+
124
+ # Try AppleScript clipboard approach: select all text in current chat, copy
125
+ osascript <<APPLESCRIPT
126
+ tell application "System Events"
127
+ tell process "Telegram"
128
+ keystroke "a" using command down
129
+ delay 0.5
130
+ keystroke "c" using command down
131
+ delay 0.5
132
+ end tell
133
+ end tell
134
+ APPLESCRIPT
135
+
136
+ sleep 1
137
+ CLIPBOARD=$(pbpaste 2>/dev/null || echo "")
138
+
139
+ # Extract token: format is digits:alphanumeric_string
140
+ TOKEN=$(echo "$CLIPBOARD" | grep -oE '[0-9]{8,12}:[A-Za-z0-9_-]{35,}' | head -1 || echo "")
141
+
142
+ if [[ -z "$TOKEN" ]]; then
143
+ echo "[WARN] Could not auto-extract token from clipboard."
144
+ echo "[INFO] Please copy the token from Telegram (BotFather reply) and paste it here:"
145
+ read -r -p "Token: " TOKEN
146
+ fi
147
+
148
+ if [[ -z "$TOKEN" ]]; then
149
+ echo "[ERROR] No token provided. Aborting."
150
+ exit 1
151
+ fi
152
+
153
+ echo "[OK] Token captured: ${TOKEN:0:20}..."
154
+
155
+ # Step 5: Register with sin-telegrambot CLI
156
+ echo "[INFO] Registering with sin-telegrambot CLI..."
157
+ sin-telegrambot register "$TOKEN" --name "$BOT_ALIAS"
158
+
159
+ # Step 6: Bootstrap chat_id
160
+ echo "[INFO] Bootstrapping chat_id..."
161
+ sin-telegrambot bootstrap "$BOT_ALIAS" || true
162
+
163
+ # Step 7: Status check
164
+ echo ""
165
+ sin-telegrambot status "$BOT_ALIAS" || true
166
+
167
+ # Step 8: Write .env snippet
168
+ echo ""
169
+ echo "=== Bot created! Add to your agent's .env ==="
170
+ echo "TELEGRAM_BOT_TOKEN=$TOKEN"
171
+ echo "TELEGRAM_BOT_NAME=$BOT_ALIAS"
172
+ echo ""
173
+ echo "=== Quick test ==="
174
+ echo " sin-telegrambot send $BOT_ALIAS \"Hello from $BOT_DISPLAY_NAME!\""
scripts/complete-install.sh ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5
+
6
+ mkdir -p "$ROOT/logs" "$ROOT/data"
7
+
8
+ if command -v npm >/dev/null 2>&1; then
9
+ npm --prefix "$ROOT" install
10
+ else
11
+ echo "npm is required" >&2
12
+ exit 1
13
+ fi
14
+
15
+ npm --prefix "$ROOT" run build
16
+
17
+ # Future HF rollout hooks for the live deployment lane.
18
+ # Not enabled while the agent remains structural-only.
19
+ # - restoreAuthSession: handled by scripts/hf_pull_script.py before first opencode call
20
+ # - startKeepAlivePing: wire this in the live HF runtime to keep the Space warm
21
+ # - startAutoBackup / backupAuthSession: only enable once a real session-backed payload exists
22
+
23
+ echo "complete-install finished for $(basename "$ROOT")"
scripts/hf_pull_script.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ A2A Consumer Rotator (HF VM Pull Script)
4
+ Pulls a fresh OpenAI refresh token from SIN-Supabase and writes the
5
+ OpenCode auth schema to ~/.local/share/opencode/auth.json.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import os
12
+ import sys
13
+ from collections.abc import Mapping
14
+ from pathlib import Path
15
+
16
+ import requests
17
+
18
+
19
+ SUPABASE_URL = os.environ.get("SUPABASE_URL", "").strip()
20
+ SUPABASE_KEY = os.environ.get("SUPABASE_SERVICE_ROLE_KEY", "").strip()
21
+ AUTH_FILE = Path.home() / ".local" / "share" / "opencode" / "auth.json"
22
+
23
+ JsonScalar = str | int | float | bool | None
24
+ JsonValue = JsonScalar | dict[str, "JsonValue"] | list["JsonValue"]
25
+
26
+
27
+ def extract_refresh_token(row: Mapping[str, JsonValue]) -> str | None:
28
+ direct_token = row.get("refresh_token") or row.get("token")
29
+ if isinstance(direct_token, str) and direct_token.strip():
30
+ return direct_token.strip()
31
+
32
+ auth_json_data = row.get("auth_json_data")
33
+ if isinstance(auth_json_data, Mapping):
34
+ openai_auth = auth_json_data.get("openai")
35
+ if isinstance(openai_auth, Mapping):
36
+ refresh_token = openai_auth.get("refresh")
37
+ if isinstance(refresh_token, str) and refresh_token.strip():
38
+ return refresh_token.strip()
39
+
40
+ refresh_token = auth_json_data.get("refresh") or auth_json_data.get("refresh_token")
41
+ if isinstance(refresh_token, str) and refresh_token.strip():
42
+ return refresh_token.strip()
43
+
44
+ return None
45
+
46
+
47
+ def build_headers() -> dict[str, str]:
48
+ return {
49
+ "apikey": SUPABASE_KEY,
50
+ "Authorization": f"Bearer {SUPABASE_KEY}",
51
+ "Content-Type": "application/json",
52
+ "Prefer": "return=representation",
53
+ }
54
+
55
+
56
+ def pull_fresh_token() -> bool:
57
+ if not SUPABASE_URL or not SUPABASE_KEY:
58
+ print("ERROR: SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY is missing.")
59
+ return False
60
+
61
+ base_url = SUPABASE_URL.rstrip("/")
62
+ headers = build_headers()
63
+
64
+ print("Looking for a fresh token in Supabase...")
65
+ get_url = (
66
+ f"{base_url}/rest/v1/openai_account_pool"
67
+ "?status=eq.FRESH&select=id,refresh_token,token,auth_json_data&limit=1"
68
+ )
69
+ response = requests.get(get_url, headers=headers, timeout=10)
70
+ response.raise_for_status()
71
+
72
+ payload = response.json()
73
+ if not isinstance(payload, list):
74
+ print("ERROR: Supabase returned an unexpected payload shape.")
75
+ return False
76
+
77
+ rows = [row for row in payload if isinstance(row, dict)]
78
+ if not rows:
79
+ print("ERROR: No fresh token available in openai_account_pool.")
80
+ return False
81
+
82
+ row = rows[0]
83
+ row_id_value = row.get("id")
84
+ if not isinstance(row_id_value, (str, int)):
85
+ print("ERROR: Supabase row is missing a valid id.")
86
+ return False
87
+
88
+ row_id = str(row_id_value)
89
+ refresh_token = extract_refresh_token(row)
90
+ if not refresh_token:
91
+ print(f"ERROR: Row {row_id} does not contain a usable refresh token.")
92
+ return False
93
+
94
+ patch_url = f"{base_url}/rest/v1/openai_account_pool?id=eq.{row_id}"
95
+ patch_response = requests.patch(
96
+ patch_url,
97
+ headers=headers,
98
+ json={"status": "IN_USE"},
99
+ timeout=10,
100
+ )
101
+ patch_response.raise_for_status()
102
+
103
+ auth_payload = {
104
+ "openai": {
105
+ "type": "oauth",
106
+ "refresh": refresh_token,
107
+ }
108
+ }
109
+ _ = AUTH_FILE.parent.mkdir(parents=True, exist_ok=True)
110
+ _ = AUTH_FILE.write_text(json.dumps(auth_payload, indent=2) + "\n", encoding="utf-8")
111
+ print(f"Updated {AUTH_FILE} from Supabase row {row_id}.")
112
+ return True
113
+
114
+
115
+ if __name__ == "__main__":
116
+ sys.exit(0 if pull_fresh_token() else 1)
scripts/postbuild.mjs ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { mkdir, copyFile } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+
4
+ const root = resolve(new URL('..', import.meta.url).pathname);
5
+ const targets = [
6
+ ['agent.json', 'dist/agent.json'],
7
+ ['mcp-config.json', 'dist/mcp-config.json'],
8
+ ['A2A-CARD.md', 'dist/A2A-CARD.md'],
9
+ ];
10
+
11
+ for (const [sourceRelative, targetRelative] of targets) {
12
+ const source = resolve(root, sourceRelative);
13
+ const target = resolve(root, targetRelative);
14
+ await mkdir(dirname(target), { recursive: true });
15
+ await copyFile(source, target);
16
+ }
17
+
scripts/telegram-bootstrap.sh ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # telegram-bootstrap.sh — Universal SIN Telegram Bot Bootstrap
3
+ # Usage: ./scripts/telegram-bootstrap.sh [--bot-name <alias>] [--env-file <path>]
4
+ # Reads TELEGRAM_BOT_TOKEN (+ optional TELEGRAM_BOT_NAME) from .env,
5
+ # registers the bot with sin-telegrambot CLI, and bootstraps the chat_id.
6
+ # Zero manual steps required.
7
+ #
8
+ # Prerequisites:
9
+ # - sin-telegrambot CLI installed: ~/.local/bin/sin-telegrambot
10
+ # - Telegram.app installed on macOS (for auto-bootstrap via AppleScript)
11
+ # - .env file in project root with TELEGRAM_BOT_TOKEN set
12
+ #
13
+ # Part of: A2A-SIN-Agent-Template canonical scripts
14
+ # Canonical CLI: sin-telegrambot (https://github.com/Delqhi/sin-telegrambot-cli)
15
+
16
+ set -euo pipefail
17
+
18
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19
+ AGENT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
20
+ ENV_FILE="${AGENT_ROOT}/.env"
21
+ BOT_NAME_OVERRIDE=""
22
+
23
+ while [[ $# -gt 0 ]]; do
24
+ case "$1" in
25
+ --bot-name) BOT_NAME_OVERRIDE="$2"; shift 2 ;;
26
+ --env-file) ENV_FILE="$2"; shift 2 ;;
27
+ *) echo "Unknown arg: $1"; exit 1 ;;
28
+ esac
29
+ done
30
+
31
+ # --- Load .env ---
32
+ if [[ -f "$ENV_FILE" ]]; then
33
+ set -a
34
+ # shellcheck disable=SC1090
35
+ source "$ENV_FILE"
36
+ set +a
37
+ echo "[INFO] Loaded env from $ENV_FILE"
38
+ else
39
+ echo "[WARN] No .env file found at $ENV_FILE — relying on environment variables"
40
+ fi
41
+
42
+ TOKEN="${TELEGRAM_BOT_TOKEN:-}"
43
+ if [[ -z "$TOKEN" ]]; then
44
+ echo "[ERROR] TELEGRAM_BOT_TOKEN is not set. Add it to .env or export it."
45
+ exit 1
46
+ fi
47
+
48
+ # Determine bot alias: --bot-name > TELEGRAM_BOT_NAME env var > agent dir name
49
+ if [[ -n "$BOT_NAME_OVERRIDE" ]]; then
50
+ BOT_ALIAS="$BOT_NAME_OVERRIDE"
51
+ elif [[ -n "${TELEGRAM_BOT_NAME:-}" ]]; then
52
+ BOT_ALIAS="$TELEGRAM_BOT_NAME"
53
+ else
54
+ BOT_ALIAS="$(basename "$AGENT_ROOT" | tr '[:upper:]' '[:lower:]' | sed 's/a2a-sin-//')"
55
+ fi
56
+
57
+ echo "[INFO] Bot alias: $BOT_ALIAS"
58
+
59
+ # --- Check sin-telegrambot is installed ---
60
+ if ! command -v sin-telegrambot &>/dev/null; then
61
+ echo "[ERROR] sin-telegrambot CLI not found. Install it:"
62
+ echo " cp ~/.config/opencode/../dev/sin-telegrambot-cli/sin_telegrambot.py ~/.local/bin/sin-telegrambot"
63
+ echo " chmod +x ~/.local/bin/sin-telegrambot"
64
+ exit 1
65
+ fi
66
+
67
+ # --- Register bot (idempotent) ---
68
+ EXISTING=$(sin-telegrambot list 2>/dev/null | python3 -c "
69
+ import json,sys
70
+ bots = json.load(sys.stdin) if sys.stdin.read(1) == '[' else []
71
+ " 2>/dev/null || echo "[]")
72
+
73
+ echo "[INFO] Registering $BOT_ALIAS ..."
74
+ RESULT=$(sin-telegrambot register "$TOKEN" --name "$BOT_ALIAS" 2>&1)
75
+ echo "$RESULT"
76
+
77
+ if echo "$RESULT" | grep -q '"ok": true'; then
78
+ echo "[OK] Bot registered successfully."
79
+ elif echo "$RESULT" | grep -q 'registered'; then
80
+ echo "[OK] Bot already registered / updated."
81
+ else
82
+ echo "[WARN] Registration result unclear, continuing..."
83
+ fi
84
+
85
+ # --- Bootstrap chat_id ---
86
+ echo "[INFO] Bootstrapping chat_id for $BOT_ALIAS ..."
87
+ BOOT=$(sin-telegrambot bootstrap "$BOT_ALIAS" 2>&1)
88
+ echo "$BOOT"
89
+
90
+ if echo "$BOOT" | grep -q '"ok": true'; then
91
+ CHAT_ID=$(echo "$BOOT" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('chat_id',''))" 2>/dev/null || echo "")
92
+ echo "[OK] chat_id discovered: $CHAT_ID"
93
+
94
+ # --- Write TELEGRAM_CHAT_ID back to .env if not already set ---
95
+ if [[ -f "$ENV_FILE" ]] && ! grep -q "TELEGRAM_CHAT_ID=" "$ENV_FILE"; then
96
+ echo "TELEGRAM_CHAT_ID=$CHAT_ID" >> "$ENV_FILE"
97
+ echo "[INFO] Wrote TELEGRAM_CHAT_ID=$CHAT_ID to $ENV_FILE"
98
+ fi
99
+ else
100
+ echo "[WARN] chat_id bootstrap didn't return ok — may need manual /start"
101
+ fi
102
+
103
+ # --- Send test message ---
104
+ echo "[INFO] Sending test message ..."
105
+ sin-telegrambot send "$BOT_ALIAS" "✅ <b>$(basename "$AGENT_ROOT")</b> bootstrap complete! Bot is online." --parse-mode HTML || true
106
+
107
+ echo ""
108
+ echo "=== Bootstrap complete ==="
109
+ echo " Alias: $BOT_ALIAS"
110
+ echo " CLI: sin-telegrambot send $BOT_ALIAS \"Hello World\""
111
+ echo " Status: sin-telegrambot status $BOT_ALIAS"
112
+ echo ""
src/a2a-http.ts ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
3
+ import { buildAgentCard, resolveTemplateAgentConfig, TEMPLATE_AGENT_ID, TEMPLATE_AGENT_NAME } from './metadata.js';
4
+ import { executeTemplateAgentAction, type TemplateAgentAction } from './runtime.js';
5
+
6
+ type RpcRequest = { jsonrpc?: string; id?: string | number | null; method?: string; params?: Record<string, unknown> };
7
+
8
+ export function createTemplateAgentHttpServer() {
9
+ const config = resolveTemplateAgentConfig();
10
+ const server = createServer((request, response) => void handleRequest(request, response, config.publicBaseUrl));
11
+ return {
12
+ server,
13
+ async start() {
14
+ await new Promise<void>((resolve, reject) => {
15
+ server.once('error', reject);
16
+ server.listen(config.port, config.host, () => resolve());
17
+ });
18
+ },
19
+ async stop() {
20
+ await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
21
+ },
22
+ };
23
+ }
24
+
25
+ async function handleRequest(request: IncomingMessage, response: ServerResponse, baseUrl: string) {
26
+ if (request.method === 'GET' && request.url === '/health') return sendJson(response, 200, { ok: true, agent: TEMPLATE_AGENT_ID });
27
+ if (request.method === 'GET' && request.url === '/') return sendHtml(response, 200, `<html><body><h1>${TEMPLATE_AGENT_NAME}</h1></body></html>`);
28
+ if (request.method === 'GET' && (request.url === '/.well-known/agent-card.json' || request.url === '/.well-known/agent.json')) {
29
+ return sendJson(response, 200, buildAgentCard(baseUrl));
30
+ }
31
+ if (request.method === 'POST' && request.url === '/a2a/v1') {
32
+ const rpc = ((await readJson(request)) || {}) as RpcRequest;
33
+ if (rpc.method === 'agent/getCard') return sendJson(response, 200, { jsonrpc: '2.0', id: rpc.id ?? null, result: buildAgentCard(baseUrl) });
34
+ if (rpc.method === 'message/send') {
35
+ const action = parseAction((rpc.params?.message as { parts?: Array<{ text?: string }> } | undefined)?.parts?.map((part) => part.text || '').join(' ').trim() || '');
36
+ const result = await executeTemplateAgentAction(action);
37
+ return sendJson(response, 200, {
38
+ jsonrpc: '2.0',
39
+ id: rpc.id ?? null,
40
+ result: {
41
+ id: randomUUID(),
42
+ kind: 'task',
43
+ status: { state: 'completed', timestamp: new Date().toISOString(), message: { role: 'agent', parts: [{ type: 'text', text: 'done' }] } },
44
+ artifacts: [{ id: randomUUID(), name: action.action, description: action.action, parts: [{ type: 'data', data: result }] }],
45
+ metadata: { action: action.action },
46
+ },
47
+ });
48
+ }
49
+ }
50
+ sendJson(response, 404, { error: 'not_found' });
51
+ }
52
+
53
+ function parseAction(text: string): TemplateAgentAction {
54
+ const value = text.toLowerCase();
55
+ if (value === 'sin.code.ai health') return { action: 'sin.code.ai.health' };
56
+ if (value === 'sin.code.ai room13 claim') return { action: 'sin.code.ai.room13.claim', confirm: true };
57
+ if (value === 'sin.code.ai onboarding status') return { action: 'sin.code.ai.onboarding.status' };
58
+ return { action: 'agent.help' };
59
+ }
60
+
61
+ async function readJson(request: IncomingMessage) {
62
+ const chunks: Buffer[] = [];
63
+ for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
64
+ const raw = Buffer.concat(chunks).toString('utf8').trim();
65
+ return raw ? JSON.parse(raw) : null;
66
+ }
67
+
68
+ function sendJson(response: ServerResponse, statusCode: number, payload: unknown) {
69
+ response.statusCode = statusCode;
70
+ response.setHeader('content-type', 'application/json; charset=utf-8');
71
+ response.end(JSON.stringify(payload, null, 2));
72
+ }
73
+
74
+ function sendHtml(response: ServerResponse, statusCode: number, payload: string) {
75
+ response.statusCode = statusCode;
76
+ response.setHeader('content-type', 'text/html; charset=utf-8');
77
+ response.end(payload);
78
+ }
src/agent/SupabaseSaver.ts ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ BaseCheckpointSaver,
3
+ type Checkpoint,
4
+ type CheckpointListOptions,
5
+ type CheckpointTuple,
6
+ type PendingWrite,
7
+ type CheckpointMetadata,
8
+ type ChannelVersions
9
+ } from '@langchain/langgraph-checkpoint';
10
+ import type { RunnableConfig } from '@langchain/core/runnables';
11
+ import { getSupabaseClient } from '../supabase.js';
12
+
13
+ export class SupabaseSaver extends BaseCheckpointSaver {
14
+ async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {
15
+ const threadId = config.configurable?.thread_id;
16
+ if (!threadId) return undefined;
17
+
18
+ const client = getSupabaseClient();
19
+ const query = client.from('langgraph_checkpoints')
20
+ .select('*')
21
+ .eq('thread_id', threadId)
22
+ .order('checkpoint_id', { ascending: false })
23
+ .limit(1);
24
+
25
+ if (config.configurable?.checkpoint_id) {
26
+ query.eq('checkpoint_id', config.configurable.checkpoint_id);
27
+ }
28
+
29
+ const { data, error } = await query.single();
30
+ if (error || !data) return undefined;
31
+
32
+ const checkpoint = await this.serde.loadsTyped('json', data.checkpoint);
33
+ const metadata = await this.serde.loadsTyped('json', data.metadata);
34
+
35
+ return {
36
+ config: {
37
+ configurable: {
38
+ thread_id: threadId,
39
+ checkpoint_ns: '',
40
+ checkpoint_id: data.checkpoint_id
41
+ }
42
+ },
43
+ checkpoint: checkpoint as Checkpoint,
44
+ metadata: metadata as CheckpointMetadata,
45
+ parentConfig: data.parent_checkpoint_id ? {
46
+ configurable: {
47
+ thread_id: threadId,
48
+ checkpoint_ns: '',
49
+ checkpoint_id: data.parent_checkpoint_id
50
+ }
51
+ } : undefined
52
+ };
53
+ }
54
+
55
+ async *list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple> {
56
+ const threadId = config.configurable?.thread_id;
57
+ if (!threadId) return;
58
+
59
+ const client = getSupabaseClient();
60
+ let query = client.from('langgraph_checkpoints')
61
+ .select('*')
62
+ .eq('thread_id', threadId)
63
+ .order('checkpoint_id', { ascending: false });
64
+
65
+ if (options?.limit) {
66
+ query = query.limit(options.limit);
67
+ }
68
+
69
+ const { data, error } = await query;
70
+ if (error || !data) return;
71
+
72
+ for (const row of data) {
73
+ const checkpoint = await this.serde.loadsTyped('json', row.checkpoint);
74
+ const metadata = await this.serde.loadsTyped('json', row.metadata);
75
+ yield {
76
+ config: { configurable: { thread_id: threadId, checkpoint_ns: '', checkpoint_id: row.checkpoint_id } },
77
+ checkpoint: checkpoint as Checkpoint,
78
+ metadata: metadata as CheckpointMetadata,
79
+ parentConfig: row.parent_checkpoint_id ? { configurable: { thread_id: threadId, checkpoint_ns: '', checkpoint_id: row.parent_checkpoint_id } } : undefined
80
+ };
81
+ }
82
+ }
83
+
84
+ async put(
85
+ config: RunnableConfig,
86
+ checkpoint: Checkpoint,
87
+ metadata: CheckpointMetadata,
88
+ newVersions: ChannelVersions
89
+ ): Promise<RunnableConfig> {
90
+ const threadId = config.configurable?.thread_id;
91
+ if (!threadId) throw new Error('missing thread_id');
92
+
93
+ const [ckptStr, metaStr] = await Promise.all([
94
+ this.serde.dumpsTyped(checkpoint),
95
+ this.serde.dumpsTyped(metadata)
96
+ ]);
97
+
98
+ const client = getSupabaseClient();
99
+ const { error } = await client.from('langgraph_checkpoints').upsert({
100
+ thread_id: threadId,
101
+ checkpoint_id: checkpoint.id,
102
+ parent_checkpoint_id: config.configurable?.checkpoint_id || null,
103
+ checkpoint: ckptStr[1],
104
+ metadata: metaStr[1]
105
+ });
106
+
107
+ if (error) {
108
+ throw new Error(`Failed to put checkpoint: ${error.message}`);
109
+ }
110
+
111
+ return {
112
+ configurable: {
113
+ thread_id: threadId,
114
+ checkpoint_ns: '',
115
+ checkpoint_id: checkpoint.id
116
+ }
117
+ };
118
+ }
119
+
120
+ async putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void> {
121
+ const threadId = config.configurable?.thread_id;
122
+ const checkpointId = config.configurable?.checkpoint_id;
123
+ if (!threadId || !checkpointId) throw new Error('missing thread_id or checkpoint_id');
124
+
125
+ const client = getSupabaseClient();
126
+ const rows = await Promise.all(writes.map(async (w, idx) => {
127
+ const [type, value] = await this.serde.dumpsTyped(w[1]);
128
+ return {
129
+ thread_id: threadId,
130
+ checkpoint_id: checkpointId,
131
+ task_id: taskId,
132
+ idx,
133
+ channel: w[0],
134
+ type,
135
+ value
136
+ };
137
+ }));
138
+
139
+ if (rows.length > 0) {
140
+ const { error } = await client.from('langgraph_checkpoint_writes').upsert(rows);
141
+ if (error) {
142
+ throw new Error(`Failed to put writes: ${error.message}`);
143
+ }
144
+ }
145
+ }
146
+
147
+ async deleteThread(threadId: string): Promise<void> {
148
+ const client = getSupabaseClient();
149
+ await client.from('langgraph_checkpoint_writes').delete().eq('thread_id', threadId);
150
+ await client.from('langgraph_checkpoints').delete().eq('thread_id', threadId);
151
+ }
152
+ }
src/agent/graph.ts ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { StateGraph, START, END, Annotation } from "@langchain/langgraph";
2
+ import { BaseMessage } from "@langchain/core/messages";
3
+
4
+ // 1. Define Agent State Annotation (March 2026 Fleet Standard)
5
+ export const AgentState = Annotation.Root({
6
+ messages: Annotation<BaseMessage[]>({
7
+ reducer: (state, update) => state.concat(update),
8
+ default: () => [],
9
+ }),
10
+ context: Annotation<Record<string, any>>({
11
+ reducer: (state, update) => ({ ...state, ...update }),
12
+ default: () => ({}),
13
+ }),
14
+ });
15
+
16
+ // 2. Define Nodes (Placeholders for A2A Logic)
17
+ async function reasoningNode(state: typeof AgentState.State) {
18
+ // Bind MCP Tools to LLM here
19
+ return { context: { reasoned: true } };
20
+ }
21
+
22
+ async function toolNode(state: typeof AgentState.State) {
23
+ // Wrap MCP Tools via @langchain/langgraph ToolNode
24
+ return { messages: [] };
25
+ }
26
+
27
+ // 3. Construct A2A Graph Workflow
28
+ export function createAgentGraph() {
29
+ const workflow = new StateGraph(AgentState)
30
+ .addNode("reasoning", reasoningNode)
31
+ .addNode("tools", toolNode)
32
+ .addEdge(START, "reasoning")
33
+ .addEdge("reasoning", "tools")
34
+ .addEdge("tools", END);
35
+
36
+ return workflow.compile(); // Optional: pass { checkpointer: new SupabaseSaver() } here
37
+ }
src/cli.ts ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+
3
+ import process from 'node:process';
4
+ import { createTemplateAgentHttpServer } from './a2a-http.js';
5
+ import { buildAgentCard, resolveTemplateAgentConfig } from './metadata.js';
6
+ import { startMcpServer } from './mcp-server.js';
7
+ import { executeTemplateAgentAction, type TemplateAgentAction } from './runtime.js';
8
+
9
+ async function main(): Promise<void> {
10
+ const command = process.argv[2] || 'help';
11
+ switch (command) {
12
+ case 'serve':
13
+ case 'serve-a2a':
14
+ await serveA2A();
15
+ return;
16
+ case 'serve-mcp':
17
+ await startMcpServer();
18
+ return;
19
+ case 'print-card':
20
+ printJson(buildAgentCard(resolveTemplateAgentConfig().publicBaseUrl));
21
+ return;
22
+ case 'run-action':
23
+ await runAction();
24
+ return;
25
+ default:
26
+ printUsage();
27
+ }
28
+ }
29
+
30
+ async function serveA2A() {
31
+ const config = resolveTemplateAgentConfig();
32
+ const handle = createTemplateAgentHttpServer();
33
+ await handle.start();
34
+ printJson({ ok: true, command: 'serve-a2a', host: config.host, port: config.port, baseUrl: config.publicBaseUrl });
35
+ }
36
+
37
+ async function runAction() {
38
+ const raw = process.argv[3]?.trim() || (await readStdin()).trim();
39
+ if (!raw) throw new Error('missing_action_json');
40
+ printJson(await executeTemplateAgentAction(JSON.parse(raw) as TemplateAgentAction));
41
+ }
42
+
43
+ function printUsage() {
44
+ process.stderr.write(
45
+ ['Usage:', ' sin-code-ai serve-a2a', ' sin-code-ai serve-mcp', ' sin-code-ai print-card', ` sin-code-ai run-action '{"action":"agent.help"}'`].join('\n') + '\n',
46
+ );
47
+ }
48
+
49
+ function printJson(payload: unknown) {
50
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
51
+ }
52
+
53
+ async function readStdin() {
54
+ const chunks: Buffer[] = [];
55
+ for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
56
+ return Buffer.concat(chunks).toString('utf8');
57
+ }
58
+
59
+ main().catch((error) => {
60
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
61
+ process.exitCode = 1;
62
+ });
63
+
src/index.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ export * from './runtime.js';
2
+ export * from './metadata.js';
3
+ export * from './a2a-http.js';
4
+ export * from './mcp-server.js';
5
+
src/lib/telemetry/SentinelLogger.ts ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { randomUUID } from 'node:crypto';
2
+ import { appendFile, mkdir } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { homedir, hostname } from 'node:os';
5
+ import { TEMPLATE_AGENT_ID, TEMPLATE_AGENT_NAME, TEMPLATE_AGENT_NAMESPACE } from '../../metadata.js';
6
+ import { getSupabaseClient } from '../../supabase.js';
7
+
8
+ export type TemplateLogLevel = 'info' | 'warn' | 'error' | 'debug';
9
+ export type TemplateLogStatus = 'started' | 'accepted' | 'completed' | 'failed';
10
+ export type TemplateLogEntry = {
11
+ agentId: string;
12
+ agentName: string;
13
+ namespace: string;
14
+ runId: string;
15
+ requestId: string;
16
+ surface: string;
17
+ event: string;
18
+ action?: string;
19
+ level: TemplateLogLevel;
20
+ status: TemplateLogStatus;
21
+ details?: Record<string, unknown>;
22
+ durationMs?: number;
23
+ createdAt: string;
24
+ };
25
+
26
+ export const TEMPLATE_LOG_PATH = join(homedir(), '.config', 'sin', TEMPLATE_AGENT_ID, 'events.ndjson');
27
+ export const TEMPLATE_TELEMETRY_TABLE = 'fleet_telemetry';
28
+
29
+ export class TemplateLogger {
30
+ readonly runId: string;
31
+
32
+ constructor(runId: string = randomUUID()) {
33
+ this.runId = runId;
34
+ }
35
+
36
+ async log(input: {
37
+ surface: string;
38
+ event: string;
39
+ level?: TemplateLogLevel;
40
+ status?: TemplateLogStatus;
41
+ action?: string;
42
+ details?: Record<string, unknown>;
43
+ durationMs?: number;
44
+ requestId?: string;
45
+ }) {
46
+ const entry: TemplateLogEntry = {
47
+ agentId: TEMPLATE_AGENT_ID,
48
+ agentName: TEMPLATE_AGENT_NAME,
49
+ namespace: TEMPLATE_AGENT_NAMESPACE,
50
+ runId: this.runId,
51
+ requestId: input.requestId || randomUUID(),
52
+ surface: input.surface,
53
+ event: input.event,
54
+ action: input.action,
55
+ level: input.level || 'info',
56
+ status: input.status || 'completed',
57
+ details: input.details,
58
+ durationMs: input.durationMs,
59
+ createdAt: new Date().toISOString(),
60
+ };
61
+
62
+ await mkdir(dirname(TEMPLATE_LOG_PATH), { recursive: true });
63
+ await appendFile(TEMPLATE_LOG_PATH, `${JSON.stringify(entry)}\n`, 'utf8');
64
+
65
+ try {
66
+ await getSupabaseClient().from(TEMPLATE_TELEMETRY_TABLE).insert({
67
+ agent_id: entry.agentId,
68
+ run_id: entry.runId,
69
+ level: entry.level,
70
+ event: entry.event,
71
+ details: {
72
+ ...(entry.details || {}),
73
+ action: entry.action,
74
+ requestId: entry.requestId,
75
+ surface: entry.surface,
76
+ status: entry.status,
77
+ hostname: hostname(),
78
+ },
79
+ duration_ms: entry.durationMs,
80
+ created_at: entry.createdAt,
81
+ });
82
+ } catch {}
83
+
84
+ const line = `[${entry.createdAt}] [${entry.agentId}] [${entry.surface}] [${entry.level.toUpperCase()}] ${entry.event}`;
85
+ if (entry.level === 'error') {
86
+ console.error(line, entry.details || '');
87
+ } else if (entry.level === 'warn') {
88
+ console.warn(line, entry.details || '');
89
+ } else {
90
+ console.log(line, entry.details || '');
91
+ }
92
+
93
+ return entry;
94
+ }
95
+
96
+ started(surface: string, event: string, details?: Record<string, unknown>, requestId?: string, action?: string) {
97
+ return this.log({ surface, event, details, requestId, action, level: 'info', status: 'started' });
98
+ }
99
+
100
+ accepted(surface: string, event: string, details?: Record<string, unknown>, requestId?: string, action?: string) {
101
+ return this.log({ surface, event, details, requestId, action, level: 'info', status: 'accepted' });
102
+ }
103
+
104
+ succeeded(
105
+ surface: string,
106
+ event: string,
107
+ details?: Record<string, unknown>,
108
+ durationMs?: number,
109
+ requestId?: string,
110
+ action?: string,
111
+ ) {
112
+ return this.log({
113
+ surface,
114
+ event,
115
+ details,
116
+ durationMs,
117
+ requestId,
118
+ action,
119
+ level: 'info',
120
+ status: 'completed',
121
+ });
122
+ }
123
+
124
+ failed(surface: string, event: string, error: unknown, durationMs?: number, requestId?: string, action?: string) {
125
+ const details = error instanceof Error ? { error: error.message } : { error: String(error) };
126
+ return this.log({
127
+ surface,
128
+ event,
129
+ details,
130
+ durationMs,
131
+ requestId,
132
+ action,
133
+ level: 'error',
134
+ status: 'failed',
135
+ });
136
+ }
137
+ }
138
+
139
+ export function createTemplateLogger(runId?: string) {
140
+ return new TemplateLogger(runId);
141
+ }
src/lib/telemetry/ZeroTrustAuth.ts ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { verify } from 'jsonwebtoken';
2
+ import { resolveTemplateAgentConfig } from '../../metadata.js';
3
+ import { createTemplateLogger } from './SentinelLogger.js';
4
+ import type { IncomingMessage } from 'node:http';
5
+
6
+ // We fetch the public key (or use a shared secret if configured) from SIN-Authenticator's OIDC jwks endpoint or env
7
+ const OIDC_PUBLIC_KEY = process.env.SIN_OIDC_PUBLIC_KEY || process.env.SIN_SHARED_SECRET || '';
8
+
9
+ export type AuthContext = {
10
+ subject: string;
11
+ roles: string[];
12
+ claims: Record<string, unknown>;
13
+ isValid: boolean;
14
+ error?: string;
15
+ };
16
+
17
+ export async function verifyZeroTrustToken(request: IncomingMessage, runId?: string): Promise<AuthContext> {
18
+ const logger = createTemplateLogger(runId);
19
+ const authHeader = request.headers.authorization;
20
+
21
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
22
+ await logger.failed('auth.zero_trust', 'auth.token.missing', new Error('Missing or malformed Authorization header'));
23
+ return { subject: 'anonymous', roles: [], claims: {}, isValid: false, error: 'missing_token' };
24
+ }
25
+
26
+ const token = authHeader.split(' ')[1];
27
+
28
+ if (!OIDC_PUBLIC_KEY) {
29
+ // If the fleet runs in a mode without strict OIDC enforcement configured yet,
30
+ // we log a warning but might fail closed depending on fleet policy.
31
+ // For Epic #195, we want to enforce zero-trust strictly when keys are present.
32
+ await logger.log({
33
+ surface: 'auth.zero_trust',
34
+ event: 'auth.keys.missing',
35
+ level: 'warn',
36
+ status: 'failed',
37
+ details: { note: 'No SIN_OIDC_PUBLIC_KEY or SIN_SHARED_SECRET configured for verification.' }
38
+ });
39
+ return { subject: 'anonymous', roles: [], claims: {}, isValid: false, error: 'missing_keys' };
40
+ }
41
+
42
+ try {
43
+ const decoded = verify(token, OIDC_PUBLIC_KEY, { algorithms: ['RS256', 'HS256'] }) as Record<string, unknown>;
44
+
45
+ await logger.succeeded('auth.zero_trust', 'auth.token.verified', { subject: decoded.sub });
46
+
47
+ return {
48
+ subject: String(decoded.sub || 'unknown'),
49
+ roles: Array.isArray(decoded.roles) ? decoded.roles.map(String) : [],
50
+ claims: decoded,
51
+ isValid: true
52
+ };
53
+ } catch (error) {
54
+ await logger.failed('auth.zero_trust', 'auth.token.rejected', error);
55
+ return {
56
+ subject: 'anonymous',
57
+ roles: [],
58
+ claims: {},
59
+ isValid: false,
60
+ error: error instanceof Error ? error.message : String(error)
61
+ };
62
+ }
63
+ }
src/mcp-server.ts ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import { z } from 'zod';
5
+ import { executeTemplateAgentAction } from './runtime.js';
6
+
7
+ const onboardingSaveSchema = z.object({
8
+ ownerEmail: z.string().optional(),
9
+ notes: z.string().optional(),
10
+ confirm: z.boolean().optional(),
11
+ });
12
+
13
+ const room13ClaimSchema = z.object({
14
+ room13Url: z.string().optional(),
15
+ bearerToken: z.string().optional(),
16
+ workerName: z.string().optional(),
17
+ confirm: z.boolean().optional(),
18
+ });
19
+
20
+ const TOOLS = [
21
+ {
22
+ name: 'sin-code-ai_help',
23
+ description: 'Describe available agent actions.',
24
+ inputSchema: { type: 'object', properties: {} },
25
+ parse: () => ({}),
26
+ handler: async () => executeTemplateAgentAction({ action: 'agent.help' }),
27
+ },
28
+ {
29
+ name: 'sin-code-ai_health',
30
+ description: 'Check base agent readiness.',
31
+ inputSchema: { type: 'object', properties: {} },
32
+ parse: () => ({}),
33
+ handler: async () => executeTemplateAgentAction({ action: 'sin.code.ai.health' }),
34
+ },
35
+ {
36
+ name: 'sin-code-ai_room13_claim',
37
+ description: 'Claim next task from Room-13. Requires confirm=true.',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ room13Url: { type: 'string' },
42
+ bearerToken: { type: 'string' },
43
+ workerName: { type: 'string' },
44
+ confirm: { type: 'boolean' },
45
+ },
46
+ },
47
+ parse: (input: unknown) => room13ClaimSchema.parse(input ?? {}),
48
+ handler: async (input: z.infer<typeof room13ClaimSchema>) =>
49
+ executeTemplateAgentAction({ action: 'sin.code.ai.room13.claim', ...input }),
50
+ },
51
+ {
52
+ name: 'sin-code-ai_onboarding_status',
53
+ description: 'Read onboarding state.',
54
+ inputSchema: { type: 'object', properties: {} },
55
+ parse: () => ({}),
56
+ handler: async () => executeTemplateAgentAction({ action: 'sin.code.ai.onboarding.status' }),
57
+ },
58
+ {
59
+ name: 'sin-code-ai_onboarding_save',
60
+ description: 'Persist onboarding state. Requires confirm=true.',
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ ownerEmail: { type: 'string' },
65
+ notes: { type: 'string' },
66
+ confirm: { type: 'boolean' },
67
+ },
68
+ },
69
+ parse: (input: unknown) => onboardingSaveSchema.parse(input ?? {}),
70
+ handler: async (input: z.infer<typeof onboardingSaveSchema>) =>
71
+ executeTemplateAgentAction({ action: 'sin.code.ai.onboarding.save', ...input }),
72
+ },
73
+ ] as const;
74
+
75
+ export async function startMcpServer(): Promise<void> {
76
+ const server = new Server({ name: 'sin-code-ai', version: '0.1.0' }, { capabilities: { tools: {} } });
77
+
78
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
79
+ return {
80
+ tools: TOOLS.map((tool) => ({
81
+ name: tool.name,
82
+ description: tool.description,
83
+ inputSchema: tool.inputSchema,
84
+ })),
85
+ };
86
+ });
87
+
88
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
89
+ const tool = TOOLS.find((entry) => entry.name === request.params.name);
90
+ if (!tool) {
91
+ return {
92
+ content: [{ type: 'text', text: `Unknown tool: ${request.params.name}` }],
93
+ isError: true,
94
+ };
95
+ }
96
+ const parsed = tool.parse(request.params.arguments ?? {});
97
+ const result = await tool.handler(parsed);
98
+ return {
99
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
100
+ };
101
+ });
102
+
103
+ const transport = new StdioServerTransport();
104
+ await server.connect(transport);
105
+ }
src/metadata.ts ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import process from 'node:process';
2
+
3
+ export const TEMPLATE_AGENT_ID = 'sin-code-ai';
4
+ export const TEMPLATE_AGENT_NAME = 'SIN-Code-AI';
5
+ export const TEMPLATE_AGENT_NAMESPACE = 'sin.code.ai';
6
+ export const TEMPLATE_AGENT_DESCRIPTION = 'Elite 2026 AI Engineering Architect. Architects and implements RAG pipelines, prompt templates, semantic search, OpenCode MCP tools, and AI-native application logic.';
7
+ export const TEMPLATE_AGENT_VERSION = '2026.03.09';
8
+ export const TEMPLATE_AGENT_DEFAULT_HOST = '127.0.0.1';
9
+ export const TEMPLATE_AGENT_DEFAULT_PORT = Number(process.env.PORT || 8000);
10
+ export const TEMPLATE_AGENT_EXECUTOR_CONTRACT = 'services/workers/hf_executor_contract.json';
11
+ export const TEMPLATE_AGENT_CAPABILITY_REGISTRY = 'control_plane.capabilities';
12
+
13
+ export const TEMPLATE_AGENT_SKILLS = [
14
+ {
15
+ id: 'sin.code.ai.health',
16
+ name: 'Health',
17
+ description: 'Check base agent readiness and identity.',
18
+ },
19
+ {
20
+ id: 'sin.code.ai.onboarding.status',
21
+ name: 'Onboarding Status',
22
+ description: 'Read persisted onboarding state.',
23
+ },
24
+ {
25
+ id: 'sin.code.ai.onboarding.save',
26
+ name: 'Onboarding Save',
27
+ description: 'Persist onboarding defaults for future autonomous runs.',
28
+ },
29
+ {
30
+ id: 'sin.code.ai.room13.claim',
31
+ name: 'Room-13 Claim',
32
+ description: 'Register worker and claim next task from Room-13 coordinator.',
33
+ },
34
+ ] as const;
35
+
36
+ export function resolveTemplateAgentConfig() {
37
+ const host =
38
+ process.env.SIN_CODE_AI_HOST?.trim() ||
39
+ (process.env.PORT ? '0.0.0.0' : process.env.HOST?.trim() || TEMPLATE_AGENT_DEFAULT_HOST);
40
+ const port = parseInteger(process.env.SIN_CODE_AI_PORT, parseInteger(process.env.PORT, TEMPLATE_AGENT_DEFAULT_PORT));
41
+ const fallbackPublicHost = host === '0.0.0.0' ? '127.0.0.1' : host;
42
+ const publicBaseUrl =
43
+ process.env.SIN_CODE_AI_PUBLIC_BASE_URL?.trim() ||
44
+ (process.env.SPACE_HOST?.trim() ? `https://${process.env.SPACE_HOST.trim()}` : `http://${fallbackPublicHost}:${port}`);
45
+ return { host, port, publicBaseUrl: publicBaseUrl.replace(/\/+$/, '') };
46
+ }
47
+
48
+ export function buildAgentCard(baseUrl: string) {
49
+ const normalizedBaseUrl = baseUrl.replace(/\/+$/, '');
50
+ const rpcUrl = `${normalizedBaseUrl}/a2a/v1`;
51
+ return {
52
+ name: TEMPLATE_AGENT_NAME,
53
+ description: TEMPLATE_AGENT_DESCRIPTION,
54
+ version: TEMPLATE_AGENT_VERSION,
55
+ documentationUrl: normalizedBaseUrl,
56
+ url: rpcUrl,
57
+ capabilities: { streaming: false, pushNotifications: false },
58
+ defaultInputModes: ['text/plain', 'application/json'],
59
+ defaultOutputModes: ['text/plain', 'application/json'],
60
+ metadata: {
61
+ projectionMode: 'control-plane-first',
62
+ capabilityRegistry: TEMPLATE_AGENT_CAPABILITY_REGISTRY,
63
+ executorContract: TEMPLATE_AGENT_EXECUTOR_CONTRACT,
64
+ },
65
+ skills: [...TEMPLATE_AGENT_SKILLS],
66
+ supportedInterfaces: [{ url: rpcUrl, protocolBinding: 'JSONRPC', protocolVersion: '1.0' }],
67
+ };
68
+ }
69
+
70
+ function parseInteger(input: string | undefined, fallback: number) {
71
+ const parsed = Number.parseInt(String(input || '').trim(), 10);
72
+ return Number.isFinite(parsed) ? parsed : fallback;
73
+ }
src/runtime.ts ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+
5
+ const DEFAULT_STATE_PATH = join(homedir(), '.config', 'sin', 'sin-code-ai', 'onboarding-state.json');
6
+
7
+ type OnboardingState = {
8
+ ownerEmail?: string;
9
+ notes?: string;
10
+ updatedAt?: string;
11
+ };
12
+
13
+ export type TemplateAgentAction =
14
+ | { action: 'agent.help' }
15
+ | { action: 'sin.code.ai.health' }
16
+ | { action: 'sin.code.ai.room13.claim'; room13Url?: string; bearerToken?: string; workerName?: string; confirm?: boolean }
17
+ | { action: 'sin.code.ai.onboarding.status' }
18
+ | { action: 'sin.code.ai.onboarding.save'; ownerEmail?: string; notes?: string; confirm?: boolean };
19
+
20
+ export async function executeTemplateAgentAction(action: TemplateAgentAction): Promise<unknown> {
21
+ switch (action.action) {
22
+ case 'agent.help':
23
+ return buildHelpPayload();
24
+ case 'sin.code.ai.health':
25
+ return {
26
+ ok: true,
27
+ agent: 'sin-code-ai',
28
+ primaryModel: 'openai/gpt-5.4',
29
+ team: 'Team - Coding',
30
+ };
31
+ case 'sin.code.ai.room13.claim':
32
+ return await runRoom13Claim(action);
33
+ case 'sin.code.ai.onboarding.status':
34
+ return {
35
+ ok: true,
36
+ statePath: DEFAULT_STATE_PATH,
37
+ state: await readState(),
38
+ };
39
+ case 'sin.code.ai.onboarding.save':
40
+ if (!action.confirm) {
41
+ throw new Error('input_required:confirm=true required');
42
+ }
43
+ return {
44
+ ok: true,
45
+ statePath: DEFAULT_STATE_PATH,
46
+ state: await writeState({
47
+ ownerEmail: clean(action.ownerEmail),
48
+ notes: clean(action.notes),
49
+ updatedAt: new Date().toISOString(),
50
+ }),
51
+ };
52
+ }
53
+ }
54
+
55
+ function buildHelpPayload() {
56
+ return {
57
+ ok: true,
58
+ agent: 'sin-code-ai',
59
+ actions: ['sin.code.ai.health', 'sin.code.ai.room13.claim', 'sin.code.ai.onboarding.status', 'sin.code.ai.onboarding.save'],
60
+ controlPlane: {
61
+ projectionMode: 'control-plane-first',
62
+ capabilityRegistry: 'control_plane.capabilities',
63
+ consumerAuthScript: './scripts/hf_pull_script.py',
64
+ completeInstallScript: './scripts/complete-install.sh',
65
+ },
66
+ };
67
+ }
68
+
69
+ async function readState(): Promise<OnboardingState | null> {
70
+ try {
71
+ return JSON.parse(await readFile(DEFAULT_STATE_PATH, 'utf8')) as OnboardingState;
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+
77
+ async function writeState(state: OnboardingState) {
78
+ await mkdir(dirname(DEFAULT_STATE_PATH), { recursive: true });
79
+ await writeFile(DEFAULT_STATE_PATH, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
80
+ return state;
81
+ }
82
+
83
+ function clean(value: string | undefined) {
84
+ const normalized = String(value || '').trim();
85
+ return normalized || undefined;
86
+ }
87
+
88
+ async function runRoom13Claim(action: any) {
89
+ const url = action.room13Url || process.env.ROOM13_URL;
90
+ const token = action.bearerToken || process.env.ROOM13_BEARER_TOKEN;
91
+ const worker = action.workerName || process.env.ROOM13_WORKER_NAME || 'sin-code-ai';
92
+ if (!url || !token) throw new Error('missing_room13_config');
93
+ const regRes = await fetch(`${url}/api/workers`, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
96
+ body: JSON.stringify({ name: `${worker}:team-coding`, type: 'general', capabilities: ['zeus_github_branch', 'sin_issues_pool_issue'], worker_identity: worker, persona_id: worker }),
97
+ });
98
+ if (!regRes.ok) throw new Error(`Failed to register worker: ${await regRes.text()}`);
99
+ const workerId = (await regRes.json() as any).id;
100
+ const claimRes = await fetch(`${url}/api/tasks/claim-next`, {
101
+ method: 'POST',
102
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
103
+ body: JSON.stringify({ worker_id: workerId, accepted_types: ['zeus_github_branch', 'sin_issues_pool_issue'], accepted_team_ids: ['team-coding'], min_priority: 'low', run_id: `${worker}-${Date.now()}`, lease_epoch: 0 }),
104
+ });
105
+ if (claimRes.status === 404) return { ok: true, claimed: false, message: 'No pending tasks found' };
106
+ if (!claimRes.ok) throw new Error(`Failed to claim task: ${await claimRes.text()}`);
107
+ return { ok: true, claimed: true, workerId, task: await claimRes.json() };
108
+ }
src/supabase.ts ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+
3
+ // Database coupling to global SIN-Supabase A2A (Oracle OCI VM 200GB)
4
+ // SSOT: https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit?tab=t.zglvro7czbod
5
+
6
+ let supabaseInstance: SupabaseClient | null = null;
7
+
8
+ export function getSupabaseClient(): SupabaseClient {
9
+ if (supabaseInstance) {
10
+ return supabaseInstance;
11
+ }
12
+
13
+ const supabaseUrl = process.env.SIN_SUPABASE_URL;
14
+ const supabaseKey = process.env.SIN_SUPABASE_SERVICE_ROLE_KEY;
15
+
16
+ if (!supabaseUrl || !supabaseKey) {
17
+ throw new Error('missing_supabase_credentials');
18
+ }
19
+
20
+ supabaseInstance = createClient(supabaseUrl, supabaseKey);
21
+ return supabaseInstance;
22
+ }
test/logging.test.mjs ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtemp, readFile } from 'node:fs/promises';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import test from 'node:test';
7
+
8
+ const DIST_ROOT = new URL('../dist/src/', import.meta.url);
9
+ const CLI_PATH = new URL('../dist/src/cli.js', import.meta.url);
10
+
11
+ async function importFresh(relativePath) {
12
+ return import(new URL(`${relativePath}?t=${Date.now()}-${Math.random()}`, DIST_ROOT).href);
13
+ }
14
+
15
+ async function readFileUntilMatch(filePath, matcher, attempts = 10) {
16
+ let last = '';
17
+ for (let index = 0; index < attempts; index += 1) {
18
+ last = await readFile(filePath, 'utf8');
19
+ if (matcher.test(last)) {
20
+ return last;
21
+ }
22
+ await new Promise((resolve) => setTimeout(resolve, 50));
23
+ }
24
+ return last;
25
+ }
26
+
27
+ test('runtime, graph, and http server append durable log events', async () => {
28
+ const home = await mkdtemp(join(tmpdir(), 'template-agent-logs-'));
29
+ process.env.HOME = home;
30
+ process.env.PORT = '0';
31
+
32
+ const { executeTemplateAgentAction, TEMPLATE_AGENT_ACTIONS } = await importFresh('./runtime.js');
33
+ const { runAgentGraph } = await importFresh('./agent/graph.js');
34
+ const { createTemplateAgentHttpServer } = await importFresh('./a2a-http.js');
35
+
36
+ await executeTemplateAgentAction(
37
+ { action: TEMPLATE_AGENT_ACTIONS.HELP },
38
+ { surface: 'test', runId: 'runtime-run', requestId: 'runtime-request' },
39
+ );
40
+ await runAgentGraph(
41
+ { action: TEMPLATE_AGENT_ACTIONS.HELP },
42
+ { runId: 'graph-run', requestId: 'graph-request', context: { source: 'test' } },
43
+ );
44
+
45
+ const handle = createTemplateAgentHttpServer();
46
+ await handle.start();
47
+ const address = handle.server.address();
48
+ const port = typeof address === 'object' && address ? address.port : 0;
49
+ const response = await fetch(`http://127.0.0.1:${port}/health`);
50
+ assert.equal(response.status, 200);
51
+ await handle.stop();
52
+
53
+ const logPath = join(home, '.config', 'sin', 'sin-code-ai', 'events.ndjson');
54
+ const content = await readFileUntilMatch(logPath, /http\.request\.succeeded/);
55
+ assert.match(content, /runtime\.action\.started/);
56
+ assert.match(content, /runtime\.action\.succeeded/);
57
+ assert.match(content, /graph\.run\.started/);
58
+ assert.match(content, /graph\.tools\.succeeded/);
59
+ assert.match(content, /http\.request\.succeeded/);
60
+ });
61
+
62
+ test('cli print-card logs command lifecycle without crashing', async () => {
63
+ const home = await mkdtemp(join(tmpdir(), 'template-agent-cli-'));
64
+ const result = spawnSync(process.execPath, [CLI_PATH.pathname, 'print-card'], {
65
+ env: { ...process.env, HOME: home },
66
+ encoding: 'utf8',
67
+ });
68
+
69
+ assert.equal(result.status, 0, result.stderr);
70
+
71
+ const logPath = join(home, '.config', 'sin', 'sin-code-ai', 'events.ndjson');
72
+ const content = await readFile(logPath, 'utf8');
73
+ assert.match(content, /cli\.command\.started/);
74
+ assert.match(content, /cli\.command\.succeeded/);
75
+ });
test/supabase.test.mjs ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { getSupabaseClient } from '../dist/src/supabase.js';
4
+
5
+ test('getSupabaseClient fails closed when credentials are missing', async () => {
6
+ const originalUrl = process.env.SIN_SUPABASE_URL;
7
+ const originalKey = process.env.SIN_SUPABASE_SERVICE_ROLE_KEY;
8
+ delete process.env.SIN_SUPABASE_URL;
9
+ delete process.env.SIN_SUPABASE_SERVICE_ROLE_KEY;
10
+ try {
11
+ assert.throws(() => getSupabaseClient(), /missing_supabase_credentials/);
12
+ } finally {
13
+ if (originalUrl !== undefined) process.env.SIN_SUPABASE_URL = originalUrl;
14
+ if (originalKey !== undefined) process.env.SIN_SUPABASE_SERVICE_ROLE_KEY = originalKey;
15
+ }
16
+ });
test/supabase_saver.test.mjs ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { randomUUID } from 'node:crypto';
4
+
5
+ const DIST_ROOT = new URL('../dist/src/', import.meta.url);
6
+
7
+ async function importFresh(relativePath) {
8
+ return import(new URL(`${relativePath}?t=${Date.now()}-${Math.random()}`, DIST_ROOT).href);
9
+ }
10
+
11
+ test('SupabaseSaver can be imported and initialized without crashing', async () => {
12
+ const { SupabaseSaver } = await importFresh('./agent/SupabaseSaver.js');
13
+ const saver = new SupabaseSaver();
14
+ assert.ok(saver);
15
+ assert.equal(typeof saver.getTuple, 'function');
16
+ assert.equal(typeof saver.put, 'function');
17
+ });
18
+
19
+ test('createAgentGraph wires SupabaseSaver successfully or falls back cleanly', async () => {
20
+ const { createAgentGraph } = await importFresh('./agent/graph.js');
21
+
22
+ // Default instantiation handles missing env vars without throwing unhandled exceptions
23
+ // because the Supabase client logic handles it or createAgentGraph catches it
24
+ const graph = createAgentGraph();
25
+ assert.ok(graph);
26
+
27
+ // Can explicitly configure checkpointer
28
+ const customGraph = createAgentGraph({ checkpointer: null });
29
+ assert.ok(customGraph);
30
+ });
31
+
32
+ test('createAgentGraph supports interruptBefore for Human-in-the-loop', async () => {
33
+ const { createAgentGraph } = await importFresh('./agent/graph.js');
34
+ const graph = createAgentGraph({ requireApproval: true, checkpointer: null });
35
+ assert.ok(graph);
36
+ // Internally this sets interruptBefore: ['tools']
37
+ });
tsconfig.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "declaration": true,
7
+ "outDir": "dist",
8
+ "rootDir": ".",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": ["src/**/*.ts"]
14
+ }
15
+