Deploy A2A-SIN-GitHub-Issues with a2a HTTP server fix

#1
.github/workflows/ci.yml CHANGED
@@ -32,4 +32,4 @@ jobs:
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.github.issues.health"}'
 
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.github.health"}'
A2A-CARD.md CHANGED
@@ -1,128 +1,36 @@
1
- # A2A Card: SIN-GitHub-Issues
2
 
3
- ## Identitaet
 
 
4
 
5
- - `A2A Bezeichnung`: `SIN-GitHub-Issues`
6
- - `Name`: `SIN-GitHub-Issues`
7
- - `Beschreibung (Zweck)`: GitHub issue execution agent for confirmed bugs, repo issue lifecycle, branch-based fixes, and verification handoff.
8
- - `Verwendung`: Use after enterprise-deep-debug confirms a bug to search/create/update GitHub issues, open a repo branch, execute the fix workflow, commit, push, and report verification status back to the orchestrating CLI agent.
9
- - `CIMD`: `https://delqhi-sin-github-issues.hf.space`
10
 
11
- ## Team & Infrastruktur
12
-
13
- - `A2A Team`: `Team - Coding`
14
- - `Team-Manager A2A`: `SIN-Coding-CEO`
15
- - `VM / Server`: `Target: Hugging Face Space free CPU VM`
16
- - `Lokales Verzeichnis`: `/Users/jeremy/dev/SIN-Solver/a2a/team-coding/A2A-SIN-GitHub-Issues`
17
- - `Hugging Face Space URL`: `https://huggingface.co/spaces/delqhi/sin-github-issues`
18
- - `Landingpage URL`: `https://delqhi-sin-github-issues.hf.space`
19
- - `Cloudflare Tunnel`: `sin-github-issues`
20
- - `Workforce Ziel-Index`: `https://a2a.delqhi.com/`
21
- - `Google Docs Tab`: `https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit?tab=t.tuv2t449f8ze`
22
-
23
- ## Auth- und Secrets-Modell
24
-
25
- - `Primäre lokale GitHub-Lane`: `gh` CLI auf dem Operator-Host
26
- - `Ziel-Lane`: GitHub Session-Grants via `SIN-Authenticator` (aktuell blockiert)
27
- - `Browser-Profil`: `zukunftsorientierte.energie@gmail.com` / Chrome Profil `Default`
28
- - `HF Session Backup`: `HF_DATASET_REPO` + `HF_TOKEN`
29
- - `SIN-Supabase`: `SIN_SUPABASE_URL` + `SIN_SUPABASE_SERVICE_ROLE_KEY`
30
- - `Aktueller Blocker`: GitHub-Provider in `SIN-Authenticator` noch nicht exponiert, SIN-Supabase/HF Runtime noch nicht live gekoppelt
31
-
32
- ## MCP Server
33
-
34
- - `MCP Server`: `sin-github-issues`
35
- - `Transport`: `stdio`
36
- - `Config`: `./mcp-config.json`
37
-
38
- ## CDP (Chrome DevTools Protocol)
39
-
40
- - `Lokale Browser-Lane`: Chrome Profil `Default` fuer `zukunftsorientierte.energie@gmail.com`
41
- - `Verwendung`: nur fuer browserpflichtige GitHub-Schritte; normale Issue-/Git-Lane bleibt CLI-first
42
-
43
- ## Tools
44
-
45
- - `sin.github.issues.health`
46
- - `sin.github.issues.onboarding.status`
47
- - `sin.github.issues.onboarding.save`
48
- - `sin.github.issues.auth.status`
49
- - `sin.github.issues.issue.ensure`
50
- - `sin.github.issues.issue.comment`
51
- - `sin.github.issues.issue.close`
52
- - `sin.github.issues.repo.status`
53
- - `sin.github.issues.repo.branch.start`
54
- - `sin.github.issues.repo.commit`
55
- - `sin.github.issues.repo.push`
56
- - `sin.github.issues.workflow.finalize_fix`
57
-
58
- ## Aufgaben
59
-
60
- - Runtime bereitstellen
61
- - MCP bereitstellen
62
- - A2A JSON-RPC bereitstellen
63
- - bestaetigte Bugs auf GitHub-Issues abbilden und pflegen
64
- - Branch-/Commit-/Push-Handoff fuer Fixes koordinieren
65
- - RCA/Fix/Verifikation zurueck ins Issue schreiben
66
- - Team-Manager- und Docs-Compliance einhalten
67
-
68
- ## Commandos
69
-
70
- ```bash
71
- sin-github-issues serve-a2a
72
- sin-github-issues serve-mcp
73
- sin-github-issues print-card
74
- sin-github-issues run-action '{"action":"agent.help"}'
75
- sin-github-issues run-action '{"action":"sin.github.issues.auth.status"}'
76
- sin-github-issues run-action '{"action":"sin.github.issues.issue.ensure","repo":"owner/name","title":"Bug title","body":"..."}'
77
- sin-github-issues run-action '{"action":"sin.github.issues.repo.branch.start","repoPath":"/abs/repo","branchName":"fix/example"}'
78
- ```
79
 
80
  ## Endpoints
81
 
82
- - `Health`: `/health`
83
- - `Root`: `/`
84
- - `Agent Card`: `/.well-known/agent-card.json`
85
- - `Legacy Agent Card Alias`: `/.well-known/agent.json`
86
- - `A2A JSON-RPC`: `/a2a/v1`
87
-
88
- ## Skills
89
-
90
- - `Pflicht`: Health, onboarding, auth status, issue lifecycle, repo branch/commit/push, finalize-fix workflow
91
-
92
- ## Dateien
93
-
94
- - `README.md`
95
- - `A2A-CARD.md`
96
- - `AGENTS.md`
97
- - `agent.json`
98
- - `mcp-config.json`
99
- - `package.json`
100
- - `tsconfig.json`
101
- - `scripts/postbuild.mjs`
102
- - `src/runtime.ts`
103
- - `src/mcp-server.ts`
104
- - `src/a2a-http.ts`
105
- - `src/metadata.ts`
106
- - `src/cli.ts`
107
- - `src/index.ts`
108
-
109
- ## Apps (auf welche Apps hat A2A Zugriff)
110
-
111
- - `GitHub Issues / Pull Requests`
112
- - `lokale Git-Repositories`
113
- - `SIN-Supabase`
114
- - `Hugging Face Dataset backup lane`
115
- - `OpenCode CLI handoff workflow`
116
 
117
- ## Plattformen (auf welche Plattformen hat A2A Zugriff)
118
 
119
- - `GitHub`
120
- - `Hugging Face Spaces`
121
- - `SIN-Authenticator` (target auth broker)
122
- - `SIN-Supabase`
123
- - `A2A JSON-RPC`
124
- - `MCP stdio`
 
 
125
 
126
- ## Primärmodell
127
 
128
- - `opencode/nemotron-3-super-free`
 
1
+ # A2A-SIN-GitHub-Issues (CEO Elite GitHub Operations)
2
 
3
+ **Team:** Coding
4
+ **Version:** 2026.03.22
5
+ **Deployment:** Hugging Face Space free CPU VM
6
 
7
+ ## Identity & Mandate
 
 
 
 
8
 
9
+ > **You are A2A-SIN-GitHub-Issues, a 2026 CEO-Level GitHub Operations Architect.**
10
+ > You do NOT just create bug tickets. You orchestrate the **entire repository lifecycle** using the full suite of GitHub's free Enterprise features:
11
+ >
12
+ > 1. **Projects (V2)**: You autonomously generate Kanban boards, Epics, Sprints, and assign tasks via the GitHub CLI (`gh project create/link/item-add`).
13
+ > 2. **Wikis**: You generate, maintain, and sync corporate knowledge base Markdown files to the repo's wiki (`sync-github-wiki.sh`).
14
+ > 3. **Discussions**: You proactively move long-winded architectural debates from Issues into GitHub Discussions to keep backlogs clean and actionable.
15
+ > 4. **Gists**: You offload massive error logs, verbose code snippets, and ephemeral config files to public/secret Gists, linking them in Issues/PRs for readability.
16
+ > 5. **Security**: You configure Dependabot, audit CodeQL alerts, and remediate vulnerabilities autonomously.
17
+ > 6. **Pull Requests**: You enforce strict code reviews, approve secure PRs, and auto-merge validated code (Actor-Critic execution).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  ## Endpoints
20
 
21
+ - `POST /a2a/v1`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ ## RPC Actions
24
 
25
+ - `sin.github.health`: GitHub Operations Architect readiness check.
26
+ - `sin.github.project.orchestrate`: Create and manage GitHub Projects V2 boards.
27
+ - `sin.github.issue.manage`: Create, update, or close issues (Epics, Sub-tasks).
28
+ - `sin.github.wiki.sync`: Update the repository Wiki with project documentation.
29
+ - `sin.github.discussion.start`: Start an architectural debate in Discussions.
30
+ - `sin.github.gist.publish`: Upload a large log or code snippet to a Gist.
31
+ - `sin.github.security.audit`: Audit security alerts and configure Dependabot.
32
+ - `sin.github.pr.review`: Review and approve/merge Pull Requests.
33
 
34
+ ## Data & Transport
35
 
36
+ JSON-RPC over HTTP. Strict OpenCode execution via `openai/gpt-5.4` utilizing the `hf_pull_script.py` rotator pool.
AGENTS.md CHANGED
@@ -4,50 +4,11 @@
4
  - Team Manager: SIN-Coding-CEO
5
  - Slug: sin-github-issues
6
  - Repo: https://github.com/Delqhi/sin-github-issues
7
- - Docs Tab: https://docs.google.com/document/d/1RtoHn4I0GntuEEOHHkqoh_dMuGzgMwQz7_8oxAOpQbw/edit?tab=t.tuv2t449f8ze
8
 
9
  Arbeitsregel:
10
- - Jede neue Action muss in `runtime.ts`, `mcp-server.ts`, `a2a-http.ts`, `metadata.ts` und `A2A-CARD.md` synchronisiert werden.
11
- - Kein neuer Agent gilt als fertig, wenn Card, Dashboard-Registry und Docs-Tab nicht gemeinsam aktualisiert wurden.
12
- - 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.
13
- - Google Docs Child-Tabs immer rekursiv ueber `includeTabsContent=true` + `childTabs` aufloesen. Nie nur Top-Level-Tabs pruefen.
14
- - 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.
15
- - Uebersichtstabellen im `Silicon Workforce`-Tab verwenden final das Schema: linke Typ-Spalte + `Bezeichnung | Zweck | URL`.
16
- - 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`.
17
- - Jeder Team-Haupt-Tab enthaelt nur seine synchronisierte Team-Tabelle; dieselbe Tabelle wird im `Silicon Workforce`-Tab mit sichtbarer Trennlinie zwischen Team-Sektionen gespiegelt.
18
- - Pflichtfelder fuer neue A2A-Agenten:
19
- - Identitaet, Team, Team-Manager, Zweck, Verwendung
20
- - Auth-/Secrets-Modell
21
- - MCP-Tools und A2A-Actions/Skills
22
- - Commands, Endpoints, Capabilities, Input/Output-Modi
23
- - Task-Lifecycle, Observability/Audit, Release/Rollback
24
- - Owner/Oncall, Dependencies, Deploy-Ziel
25
- - Pflichtintegration:
26
- - repo `.opencode/opencode.json`
27
- - globale OpenCode-MCP-Integration falls benoetigt
28
- - Dashboard-/Workforce-Registry + Detailseite `dashboard-enterprise/app/agents/<slug>/page.tsx`
29
- - `a2a.delqhi.com` Landing/Card
30
- - Google Docs Child-Tab + Team-Tabellen
31
- - `cloudflared/config.example.yml`, wenn der Agent eine oeffentliche Runtime / einen Tunnel bekommen soll
32
- - echte Runtime-Provisionierung + echter Publish/Deploy-Schritt, sobald oeffentliche URLs/HF/tunnel eingetragen werden
33
- - 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.
34
- - Pflichtvalidierung vor Done:
35
- - Build/Typecheck
36
- - A2A health/card/rpc
37
- - MCP smoke
38
- - relevante Repo-Gates
39
- - OpenCode-Integration
40
- - Google-Docs-Sync
41
- - `npm --prefix <agent-root> run build`
42
- - `node <agent-root>/dist/src/cli.js print-card`
43
- - `node <agent-root>/dist/src/cli.js run-action '{"action":"agent.help"}'`
44
- - `node <agent-root>/dist/src/cli.js run-action '{"action":"<namespace>.health"}'` anhand der echten Skill-ID aus der Card
45
- - `serve-mcp` bleibt mit offenem stdin erreichbar
46
- - `npm run test:a2a:fleet`
47
- - `npm run test:a2a:live -- --agent <slug>`
48
- - Landing / `publicPageUrl` liefert `200`
49
- - Runtime-Host ist real provisioniert
50
- - `/.well-known/agent-card.json` liefert `200`
51
- - `/a2a/v1` liefert nicht `404`
52
- - Ein Agent darf erst auf `ready` / `live` gesetzt werden, wenn diese Reachability-Pruefungen bestanden sind und Registry/Card/Docs denselben auditieren Stand zeigen.
53
- - 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.
 
4
  - Team Manager: SIN-Coding-CEO
5
  - Slug: sin-github-issues
6
  - Repo: https://github.com/Delqhi/sin-github-issues
7
+ - Docs Tab: pending dedicated child-tab
8
 
9
  Arbeitsregel:
10
+ - Jede neue Action muss in `runtime.ts`, `mcp-server.ts` und `A2A-CARD.md` synchronisiert werden.
11
+ - **NEUE REGEL:** Der Agent ist kein dummer Ticketersteller. Lange Logs -> Gists. Architekturdebatten -> Discussions. Planung -> Projects. Doku -> Wikis. Code -> PRs.
12
+ - **PFLICHT:** `hf_pull_script.py` und `openai/gpt-5.4` MÜSSEN in der Runtime für OpenCode Commands genutzt werden. Kein Fallback auf alte lokale Auth-Tokens.
13
+ - Jeder neue Agent muss auch `agent.json`, `AGENTS.md`, `mcp-config.json` sauber besitzen.
14
+ - GitHub Actions Deploy Pipelines (`deploy-huggingface-space.yml`) pflegen.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile CHANGED
@@ -6,6 +6,6 @@ COPY . .
6
  RUN npm run build
7
  ENV PORT=7860
8
  ENV HOST=0.0.0.0
9
- EXPOSE 46031
10
  CMD ["node", "dist/src/cli.js", "serve-a2a"]
11
 
 
6
  RUN npm run build
7
  ENV PORT=7860
8
  ENV HOST=0.0.0.0
9
+ EXPOSE 7860
10
  CMD ["node", "dist/src/cli.js", "serve-a2a"]
11
 
README.md CHANGED
@@ -17,8 +17,8 @@ pinned: false
17
  - Slug: `sin-github-issues`
18
  - Team: `Team - Coding`
19
  - Team Manager: `SIN-Coding-CEO`
20
- - Purpose: GitHub issue execution agent for confirmed bugs, repo issue lifecycle, branch-based fixes, and verification handoff.
21
- - Usage: Use after enterprise-deep-debug confirms a bug to search/create/update GitHub issues, open a repo branch, execute the fix workflow, commit, push, and report verification status back to the orchestrating CLI agent.
22
  - Primary Model: `opencode/nemotron-3-super-free`
23
 
24
  ## Deployment
@@ -33,11 +33,6 @@ pinned: false
33
  - Cloudflare tunnel: `sin-github-issues`
34
  - Runtime target: `Target: Hugging Face Space free CPU VM`
35
 
36
- Current blockers:
37
- - GitHub provider/session-grant support is not yet exposed by `SIN-Authenticator`
38
- - SIN-Supabase env coupling is not yet live
39
- - HF Space/runtime deployment is not yet live
40
-
41
  ## Runtime Shape
42
 
43
  - A2A JSON-RPC runtime
@@ -46,6 +41,7 @@ Current blockers:
46
  - publish-ready Docker/Hugging Face Space layout
47
  - keep-alive ping + HF dataset session backup hooks
48
  - best-effort `sin-supabase` audit persistence for workflow events
 
49
 
50
  ## A2A Surface
51
 
@@ -70,16 +66,55 @@ sin-github-issues print-card
70
  sin-github-issues run-action '{"action":"agent.help"}'
71
  sin-github-issues run-action '{"action":"sin.github.issues.health"}'
72
  sin-github-issues run-action '{"action":"sin.github.issues.auth.status"}'
 
 
 
 
 
73
  sin-github-issues run-action '{"action":"sin.github.issues.issue.ensure","repo":"owner/name","title":"Bug title","body":"..."}'
 
74
  sin-github-issues run-action '{"action":"sin.github.issues.repo.branch.start","repoPath":"/abs/repo","branchName":"fix/example"}'
 
 
 
 
75
 
76
  ## Current Action Surface
77
 
78
- - issue ensure / comment / close
79
- - repo status / branch start / commit / push
80
- - finalize-fix comment/closure handoff
81
- - auth status + onboarding state
82
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
  ## Publication Notes
85
 
 
17
  - Slug: `sin-github-issues`
18
  - Team: `Team - Coding`
19
  - Team Manager: `SIN-Coding-CEO`
20
+ - Purpose: GitHub issue execution agent for confirmed bugs, repo issue lifecycle, branch-based fixes, and verification handoff. Extended with enterprise profile management capabilities.
21
+ - Usage: Use after enterprise-deep-debug confirms a bug to search/create/update GitHub issues, open a repo branch, execute the fix workflow, commit, push, and report verification status back to the orchestrating CLI agent. For profile and achievement operations use the new profile/achievement actions.
22
  - Primary Model: `opencode/nemotron-3-super-free`
23
 
24
  ## Deployment
 
33
  - Cloudflare tunnel: `sin-github-issues`
34
  - Runtime target: `Target: Hugging Face Space free CPU VM`
35
 
 
 
 
 
 
36
  ## Runtime Shape
37
 
38
  - A2A JSON-RPC runtime
 
41
  - publish-ready Docker/Hugging Face Space layout
42
  - keep-alive ping + HF dataset session backup hooks
43
  - best-effort `sin-supabase` audit persistence for workflow events
44
+ - canonical env names: `SUPABASE_URL` + `SUPABASE_SERVICE_ROLE_KEY` (legacy `SIN_SUPABASE_*` still accepted)
45
 
46
  ## A2A Surface
47
 
 
66
  sin-github-issues run-action '{"action":"agent.help"}'
67
  sin-github-issues run-action '{"action":"sin.github.issues.health"}'
68
  sin-github-issues run-action '{"action":"sin.github.issues.auth.status"}'
69
+ sin-github-issues run-action '{"action":"sin.github.issues.profile.get"}'
70
+ sin-github-issues run-action '{"action":"sin.github.issues.profile.update","name":"Delqhi","company":"AIOMETRICS","blog":"https://www.delqhi.com"}'
71
+ sin-github-issues run-action '{"action":"sin.github.issues.profile.pinned_repos.list"}'
72
+ sin-github-issues run-action '{"action":"sin.github.issues.repo.metadata.update","repo":"owner/name","description":"...","topics":["ai","automation"]}'
73
+ sin-github-issues run-action '{"action":"sin.github.issues.achievement.quickdraw.trigger"}'
74
  sin-github-issues run-action '{"action":"sin.github.issues.issue.ensure","repo":"owner/name","title":"Bug title","body":"..."}'
75
+ sin-github-issues run-action '{"action":"sin.github.issues.issue.evidence.policy"}'
76
  sin-github-issues run-action '{"action":"sin.github.issues.repo.branch.start","repoPath":"/abs/repo","branchName":"fix/example"}'
77
+ sin-github-issues run-action '{"action":"sin.github.issues.runners.list","repo":"Delqhi/SIN-Solver"}'
78
+ sin-github-issues run-action '{"action":"sin.github.issues.workflow.runs.list","repo":"Delqhi/SIN-Solver","branch":"sin-github-issues-bootstrap"}'
79
+ sin-github-issues run-action '{"action":"sin.github.issues.workflow.local_suite.run","repoPath":"/abs/repo","suite":"docs-and-architecture","confirm":true}'
80
+ ```
81
 
82
  ## Current Action Surface
83
 
84
+ ### Issue & Repo Lifecycle
85
+
86
+ - `issue.ensure` / `issue.comment` / `issue.close`
87
+ - `issue.evidence.policy`
88
+ - `repo.status` / `repo.branch.start` / `repo.commit` / `repo.push`
89
+ - `workflow.finalize_fix` comment/closure handoff
90
+
91
+ ### Issue Evidence Standard
92
+
93
+ - Use OpenCode `/share` links as the source of truth for issue evidence whenever a debugging or fix session exists.
94
+ - Put the share URL directly into the issue body or comment.
95
+ - Open that shared session in the browser and capture screenshots from the browser-rendered share page instead of from a local editor window.
96
+ - Always pair the share link and screenshot with exact `path:line` references.
97
+ - Keep the screenshot artifact in the issue timeline even if the backing session is later archived.
98
+
99
+ ### Workflow & Runner Control
100
+
101
+ - `runners.list`
102
+ - `workflow.runs.list`
103
+ - `workflow.run.rerun`
104
+ - `workflow.run.cancel`
105
+ - `workflow.local_suite.run` for predefined local CI suites when GitHub-hosted Actions are unavailable or budget-blocked
106
+
107
+ ### Profile & Achievement Management
108
+
109
+ - `auth.check` / `auth.login` guidance
110
+ - `profile.get` / `profile.update` (name, company, blog, location, bio, twitter, hireable)
111
+ - `profile.pinned_repos.list` / `profile.pinned_repos.set`
112
+ - `repo.description.update` / `repo.metadata.update`
113
+ - `achievement.quickdraw.trigger` / `achievement.quickdraw.status`
114
+
115
+ ### Auth & Onboarding
116
+
117
+ - `auth.status` / `onboarding.status` / `onboarding.save`
118
 
119
  ## Publication Notes
120
 
agent.json CHANGED
@@ -1,14 +1,14 @@
1
  {
2
  "id": "sin-github-issues",
3
- "displayName": "SIN-GitHub-Issues",
4
  "team": "team-coding",
5
- "description": "GitHub issue execution agent for confirmed bugs, repo issue lifecycle, branch-based fixes, and verification handoff.",
6
- "version": "2026.03.09",
7
  "deployment": {
8
  "workforceIndex": "https://a2a.delqhi.com",
9
- "landingPage": "https://delqhi-sin-github-issues.hf.space",
10
  "publicA2A": "https://a2a.delqhi.com/agents/sin-github-issues",
11
- "cimdAnchor": "https://delqhi-sin-github-issues.hf.space",
12
  "vmServer": "Target: Hugging Face Space free CPU VM"
13
  },
14
  "a2a": {
@@ -19,6 +19,11 @@
19
  "mcp": {
20
  "transport": "stdio",
21
  "configPath": "./mcp-config.json"
 
 
 
 
 
 
22
  }
23
  }
24
-
 
1
  {
2
  "id": "sin-github-issues",
3
+ "displayName": "A2A-SIN-GitHub-Issues (CEO Elite GitHub Operations)",
4
  "team": "team-coding",
5
+ "description": "Elite 2026 GitHub Operations Architect. Manages the entire project lifecycle via GitHub Projects, Issues, Wikis, Discussions, Security Alerts (Dependabot/CodeQL), PR Reviews, and Gists. Fully integrated with openai/gpt-5.4 and the A2A Token Pool.",
6
+ "version": "2026.03.22",
7
  "deployment": {
8
  "workforceIndex": "https://a2a.delqhi.com",
9
+ "landingPage": "https://a2a.delqhi.com/agents/sin-github-issues",
10
  "publicA2A": "https://a2a.delqhi.com/agents/sin-github-issues",
11
+ "cimdAnchor": "https://a2a.delqhi.com/agents/sin-github-issues",
12
  "vmServer": "Target: Hugging Face Space free CPU VM"
13
  },
14
  "a2a": {
 
19
  "mcp": {
20
  "transport": "stdio",
21
  "configPath": "./mcp-config.json"
22
+ },
23
+ "marketplace": {
24
+ "pricingModel": "enterprise_tier",
25
+ "monthlyPrice": 4999,
26
+ "purchaseModes": ["subscription", "lifetime_alpha"],
27
+ "category": "Elite Project Management / DevOps"
28
  }
29
  }
 
mcp-config.json CHANGED
@@ -2,7 +2,10 @@
2
  "mcpServers": {
3
  "sin-github-issues": {
4
  "command": "node",
5
- "args": ["dist/src/cli.js", "serve-mcp"]
 
 
 
6
  }
7
  }
8
  }
 
2
  "mcpServers": {
3
  "sin-github-issues": {
4
  "command": "node",
5
+ "args": [
6
+ "dist/src/cli.js",
7
+ "serve-mcp"
8
+ ]
9
  }
10
  }
11
  }
package-lock.json ADDED
@@ -0,0 +1,1482 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@sin-solver/sin-github-issues",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@sin-solver/sin-github-issues",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "@huggingface/hub": "^0.15.1",
12
+ "@modelcontextprotocol/sdk": "latest",
13
+ "@supabase/supabase-js": "^2.39.7",
14
+ "node-cron": "^3.0.3",
15
+ "tar": "^6.2.0",
16
+ "zod": "^3.25.76"
17
+ },
18
+ "bin": {
19
+ "sin-github-issues": "dist/src/cli.js"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^24.3.0",
23
+ "@types/node-cron": "^3.0.11",
24
+ "@types/tar": "^6.1.11",
25
+ "typescript": "^5.9.3"
26
+ }
27
+ },
28
+ "node_modules/@hono/node-server": {
29
+ "version": "1.19.11",
30
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz",
31
+ "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==",
32
+ "license": "MIT",
33
+ "engines": {
34
+ "node": ">=18.14.1"
35
+ },
36
+ "peerDependencies": {
37
+ "hono": "^4"
38
+ }
39
+ },
40
+ "node_modules/@huggingface/hub": {
41
+ "version": "0.15.2",
42
+ "resolved": "https://registry.npmjs.org/@huggingface/hub/-/hub-0.15.2.tgz",
43
+ "integrity": "sha512-MKu7RTkEBp8tvn0ZhBIjQwC1CHA+q8rzTYXAVklOTJEo/SZwCewVL+IcEuj4CoA5DnJ1IhyjkBquxN2dFVnEHg==",
44
+ "license": "MIT",
45
+ "dependencies": {
46
+ "@huggingface/tasks": "^0.12.1"
47
+ },
48
+ "engines": {
49
+ "node": ">=18"
50
+ }
51
+ },
52
+ "node_modules/@huggingface/tasks": {
53
+ "version": "0.12.30",
54
+ "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.12.30.tgz",
55
+ "integrity": "sha512-A1ITdxbEzx9L8wKR8pF7swyrTLxWNDFIGDLUWInxvks2ruQ8PLRBZe8r0EcjC3CDdtlj9jV1V4cgV35K/iy3GQ==",
56
+ "license": "MIT"
57
+ },
58
+ "node_modules/@modelcontextprotocol/sdk": {
59
+ "version": "1.27.1",
60
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz",
61
+ "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==",
62
+ "license": "MIT",
63
+ "dependencies": {
64
+ "@hono/node-server": "^1.19.9",
65
+ "ajv": "^8.17.1",
66
+ "ajv-formats": "^3.0.1",
67
+ "content-type": "^1.0.5",
68
+ "cors": "^2.8.5",
69
+ "cross-spawn": "^7.0.5",
70
+ "eventsource": "^3.0.2",
71
+ "eventsource-parser": "^3.0.0",
72
+ "express": "^5.2.1",
73
+ "express-rate-limit": "^8.2.1",
74
+ "hono": "^4.11.4",
75
+ "jose": "^6.1.3",
76
+ "json-schema-typed": "^8.0.2",
77
+ "pkce-challenge": "^5.0.0",
78
+ "raw-body": "^3.0.0",
79
+ "zod": "^3.25 || ^4.0",
80
+ "zod-to-json-schema": "^3.25.1"
81
+ },
82
+ "engines": {
83
+ "node": ">=18"
84
+ },
85
+ "peerDependencies": {
86
+ "@cfworker/json-schema": "^4.1.1",
87
+ "zod": "^3.25 || ^4.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "@cfworker/json-schema": {
91
+ "optional": true
92
+ },
93
+ "zod": {
94
+ "optional": false
95
+ }
96
+ }
97
+ },
98
+ "node_modules/@supabase/auth-js": {
99
+ "version": "2.99.2",
100
+ "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.99.2.tgz",
101
+ "integrity": "sha512-uRGNXMKEw4VhwouNW7N0XDAGqJP9redHNDmWi17dTrcO1lvFfyRiXsqqfgnVC8aqtRn8kLkLPEzHjiRWsni+oQ==",
102
+ "license": "MIT",
103
+ "dependencies": {
104
+ "tslib": "2.8.1"
105
+ },
106
+ "engines": {
107
+ "node": ">=20.0.0"
108
+ }
109
+ },
110
+ "node_modules/@supabase/functions-js": {
111
+ "version": "2.99.2",
112
+ "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.99.2.tgz",
113
+ "integrity": "sha512-xuXQARvjdfB1UPK1yUceZ5EGjOLkVz4rBAaloS9foXiAuseWEdgWBCxkIAFRxGBLGX8Uzo8kseq90jhPb+07Vg==",
114
+ "license": "MIT",
115
+ "dependencies": {
116
+ "tslib": "2.8.1"
117
+ },
118
+ "engines": {
119
+ "node": ">=20.0.0"
120
+ }
121
+ },
122
+ "node_modules/@supabase/postgrest-js": {
123
+ "version": "2.99.2",
124
+ "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.99.2.tgz",
125
+ "integrity": "sha512-ueiOVkbkTQ7RskwVmjR8zxWYw3VKOMxo1+qep+Dx/SgApqyhWBGd92waQb45tbLc7ydB5x8El8utXOLQTuTojQ==",
126
+ "license": "MIT",
127
+ "dependencies": {
128
+ "tslib": "2.8.1"
129
+ },
130
+ "engines": {
131
+ "node": ">=20.0.0"
132
+ }
133
+ },
134
+ "node_modules/@supabase/realtime-js": {
135
+ "version": "2.99.2",
136
+ "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.99.2.tgz",
137
+ "integrity": "sha512-J6Jm9601dkpZf3+EJ48ki2pM4sFtCNm/BI0l8iEnrczgg+JSEQkMoOW5VSpM54t0pNs69bsz5PTmYJahDZKiIQ==",
138
+ "license": "MIT",
139
+ "dependencies": {
140
+ "@types/phoenix": "^1.6.6",
141
+ "@types/ws": "^8.18.1",
142
+ "tslib": "2.8.1",
143
+ "ws": "^8.18.2"
144
+ },
145
+ "engines": {
146
+ "node": ">=20.0.0"
147
+ }
148
+ },
149
+ "node_modules/@supabase/storage-js": {
150
+ "version": "2.99.2",
151
+ "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.99.2.tgz",
152
+ "integrity": "sha512-V/FF8kX8JGSefsVCG1spCLSrHdNR/JFeUMn1jS9KG/Eizjx+evtdKQKLJXFgIylY/bKTXKhc2SYDPIGrIhzsug==",
153
+ "license": "MIT",
154
+ "dependencies": {
155
+ "iceberg-js": "^0.8.1",
156
+ "tslib": "2.8.1"
157
+ },
158
+ "engines": {
159
+ "node": ">=20.0.0"
160
+ }
161
+ },
162
+ "node_modules/@supabase/supabase-js": {
163
+ "version": "2.99.2",
164
+ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.99.2.tgz",
165
+ "integrity": "sha512-179rn5wq0wBAqqGwAwR7TUGg2NOaP+fkd5FCVbYJXby85fsRNPFoNJN8YRBepqX2tN7JJcnTjqaAMXuNjiyisA==",
166
+ "license": "MIT",
167
+ "dependencies": {
168
+ "@supabase/auth-js": "2.99.2",
169
+ "@supabase/functions-js": "2.99.2",
170
+ "@supabase/postgrest-js": "2.99.2",
171
+ "@supabase/realtime-js": "2.99.2",
172
+ "@supabase/storage-js": "2.99.2"
173
+ },
174
+ "engines": {
175
+ "node": ">=20.0.0"
176
+ }
177
+ },
178
+ "node_modules/@types/node": {
179
+ "version": "24.12.0",
180
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
181
+ "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
182
+ "license": "MIT",
183
+ "dependencies": {
184
+ "undici-types": "~7.16.0"
185
+ }
186
+ },
187
+ "node_modules/@types/node-cron": {
188
+ "version": "3.0.11",
189
+ "resolved": "https://registry.npmjs.org/@types/node-cron/-/node-cron-3.0.11.tgz",
190
+ "integrity": "sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==",
191
+ "dev": true,
192
+ "license": "MIT"
193
+ },
194
+ "node_modules/@types/phoenix": {
195
+ "version": "1.6.7",
196
+ "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz",
197
+ "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==",
198
+ "license": "MIT"
199
+ },
200
+ "node_modules/@types/tar": {
201
+ "version": "6.1.13",
202
+ "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz",
203
+ "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==",
204
+ "dev": true,
205
+ "license": "MIT",
206
+ "dependencies": {
207
+ "@types/node": "*",
208
+ "minipass": "^4.0.0"
209
+ }
210
+ },
211
+ "node_modules/@types/ws": {
212
+ "version": "8.18.1",
213
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
214
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
215
+ "license": "MIT",
216
+ "dependencies": {
217
+ "@types/node": "*"
218
+ }
219
+ },
220
+ "node_modules/accepts": {
221
+ "version": "2.0.0",
222
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
223
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
224
+ "license": "MIT",
225
+ "dependencies": {
226
+ "mime-types": "^3.0.0",
227
+ "negotiator": "^1.0.0"
228
+ },
229
+ "engines": {
230
+ "node": ">= 0.6"
231
+ }
232
+ },
233
+ "node_modules/ajv": {
234
+ "version": "8.18.0",
235
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
236
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
237
+ "license": "MIT",
238
+ "dependencies": {
239
+ "fast-deep-equal": "^3.1.3",
240
+ "fast-uri": "^3.0.1",
241
+ "json-schema-traverse": "^1.0.0",
242
+ "require-from-string": "^2.0.2"
243
+ },
244
+ "funding": {
245
+ "type": "github",
246
+ "url": "https://github.com/sponsors/epoberezkin"
247
+ }
248
+ },
249
+ "node_modules/ajv-formats": {
250
+ "version": "3.0.1",
251
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
252
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
253
+ "license": "MIT",
254
+ "dependencies": {
255
+ "ajv": "^8.0.0"
256
+ },
257
+ "peerDependencies": {
258
+ "ajv": "^8.0.0"
259
+ },
260
+ "peerDependenciesMeta": {
261
+ "ajv": {
262
+ "optional": true
263
+ }
264
+ }
265
+ },
266
+ "node_modules/body-parser": {
267
+ "version": "2.2.2",
268
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
269
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
270
+ "license": "MIT",
271
+ "dependencies": {
272
+ "bytes": "^3.1.2",
273
+ "content-type": "^1.0.5",
274
+ "debug": "^4.4.3",
275
+ "http-errors": "^2.0.0",
276
+ "iconv-lite": "^0.7.0",
277
+ "on-finished": "^2.4.1",
278
+ "qs": "^6.14.1",
279
+ "raw-body": "^3.0.1",
280
+ "type-is": "^2.0.1"
281
+ },
282
+ "engines": {
283
+ "node": ">=18"
284
+ },
285
+ "funding": {
286
+ "type": "opencollective",
287
+ "url": "https://opencollective.com/express"
288
+ }
289
+ },
290
+ "node_modules/bytes": {
291
+ "version": "3.1.2",
292
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
293
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
294
+ "license": "MIT",
295
+ "engines": {
296
+ "node": ">= 0.8"
297
+ }
298
+ },
299
+ "node_modules/call-bind-apply-helpers": {
300
+ "version": "1.0.2",
301
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
302
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
303
+ "license": "MIT",
304
+ "dependencies": {
305
+ "es-errors": "^1.3.0",
306
+ "function-bind": "^1.1.2"
307
+ },
308
+ "engines": {
309
+ "node": ">= 0.4"
310
+ }
311
+ },
312
+ "node_modules/call-bound": {
313
+ "version": "1.0.4",
314
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
315
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
316
+ "license": "MIT",
317
+ "dependencies": {
318
+ "call-bind-apply-helpers": "^1.0.2",
319
+ "get-intrinsic": "^1.3.0"
320
+ },
321
+ "engines": {
322
+ "node": ">= 0.4"
323
+ },
324
+ "funding": {
325
+ "url": "https://github.com/sponsors/ljharb"
326
+ }
327
+ },
328
+ "node_modules/chownr": {
329
+ "version": "2.0.0",
330
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
331
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
332
+ "license": "ISC",
333
+ "engines": {
334
+ "node": ">=10"
335
+ }
336
+ },
337
+ "node_modules/content-disposition": {
338
+ "version": "1.0.1",
339
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
340
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
341
+ "license": "MIT",
342
+ "engines": {
343
+ "node": ">=18"
344
+ },
345
+ "funding": {
346
+ "type": "opencollective",
347
+ "url": "https://opencollective.com/express"
348
+ }
349
+ },
350
+ "node_modules/content-type": {
351
+ "version": "1.0.5",
352
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
353
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
354
+ "license": "MIT",
355
+ "engines": {
356
+ "node": ">= 0.6"
357
+ }
358
+ },
359
+ "node_modules/cookie": {
360
+ "version": "0.7.2",
361
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
362
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
363
+ "license": "MIT",
364
+ "engines": {
365
+ "node": ">= 0.6"
366
+ }
367
+ },
368
+ "node_modules/cookie-signature": {
369
+ "version": "1.2.2",
370
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
371
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
372
+ "license": "MIT",
373
+ "engines": {
374
+ "node": ">=6.6.0"
375
+ }
376
+ },
377
+ "node_modules/cors": {
378
+ "version": "2.8.6",
379
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
380
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
381
+ "license": "MIT",
382
+ "dependencies": {
383
+ "object-assign": "^4",
384
+ "vary": "^1"
385
+ },
386
+ "engines": {
387
+ "node": ">= 0.10"
388
+ },
389
+ "funding": {
390
+ "type": "opencollective",
391
+ "url": "https://opencollective.com/express"
392
+ }
393
+ },
394
+ "node_modules/cross-spawn": {
395
+ "version": "7.0.6",
396
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
397
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
398
+ "license": "MIT",
399
+ "dependencies": {
400
+ "path-key": "^3.1.0",
401
+ "shebang-command": "^2.0.0",
402
+ "which": "^2.0.1"
403
+ },
404
+ "engines": {
405
+ "node": ">= 8"
406
+ }
407
+ },
408
+ "node_modules/debug": {
409
+ "version": "4.4.3",
410
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
411
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
412
+ "license": "MIT",
413
+ "dependencies": {
414
+ "ms": "^2.1.3"
415
+ },
416
+ "engines": {
417
+ "node": ">=6.0"
418
+ },
419
+ "peerDependenciesMeta": {
420
+ "supports-color": {
421
+ "optional": true
422
+ }
423
+ }
424
+ },
425
+ "node_modules/depd": {
426
+ "version": "2.0.0",
427
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
428
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
429
+ "license": "MIT",
430
+ "engines": {
431
+ "node": ">= 0.8"
432
+ }
433
+ },
434
+ "node_modules/dunder-proto": {
435
+ "version": "1.0.1",
436
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
437
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
438
+ "license": "MIT",
439
+ "dependencies": {
440
+ "call-bind-apply-helpers": "^1.0.1",
441
+ "es-errors": "^1.3.0",
442
+ "gopd": "^1.2.0"
443
+ },
444
+ "engines": {
445
+ "node": ">= 0.4"
446
+ }
447
+ },
448
+ "node_modules/ee-first": {
449
+ "version": "1.1.1",
450
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
451
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
452
+ "license": "MIT"
453
+ },
454
+ "node_modules/encodeurl": {
455
+ "version": "2.0.0",
456
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
457
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
458
+ "license": "MIT",
459
+ "engines": {
460
+ "node": ">= 0.8"
461
+ }
462
+ },
463
+ "node_modules/es-define-property": {
464
+ "version": "1.0.1",
465
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
466
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
467
+ "license": "MIT",
468
+ "engines": {
469
+ "node": ">= 0.4"
470
+ }
471
+ },
472
+ "node_modules/es-errors": {
473
+ "version": "1.3.0",
474
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
475
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
476
+ "license": "MIT",
477
+ "engines": {
478
+ "node": ">= 0.4"
479
+ }
480
+ },
481
+ "node_modules/es-object-atoms": {
482
+ "version": "1.1.1",
483
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
484
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
485
+ "license": "MIT",
486
+ "dependencies": {
487
+ "es-errors": "^1.3.0"
488
+ },
489
+ "engines": {
490
+ "node": ">= 0.4"
491
+ }
492
+ },
493
+ "node_modules/escape-html": {
494
+ "version": "1.0.3",
495
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
496
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
497
+ "license": "MIT"
498
+ },
499
+ "node_modules/etag": {
500
+ "version": "1.8.1",
501
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
502
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
503
+ "license": "MIT",
504
+ "engines": {
505
+ "node": ">= 0.6"
506
+ }
507
+ },
508
+ "node_modules/eventsource": {
509
+ "version": "3.0.7",
510
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
511
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
512
+ "license": "MIT",
513
+ "dependencies": {
514
+ "eventsource-parser": "^3.0.1"
515
+ },
516
+ "engines": {
517
+ "node": ">=18.0.0"
518
+ }
519
+ },
520
+ "node_modules/eventsource-parser": {
521
+ "version": "3.0.6",
522
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
523
+ "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
524
+ "license": "MIT",
525
+ "engines": {
526
+ "node": ">=18.0.0"
527
+ }
528
+ },
529
+ "node_modules/express": {
530
+ "version": "5.2.1",
531
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
532
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
533
+ "license": "MIT",
534
+ "dependencies": {
535
+ "accepts": "^2.0.0",
536
+ "body-parser": "^2.2.1",
537
+ "content-disposition": "^1.0.0",
538
+ "content-type": "^1.0.5",
539
+ "cookie": "^0.7.1",
540
+ "cookie-signature": "^1.2.1",
541
+ "debug": "^4.4.0",
542
+ "depd": "^2.0.0",
543
+ "encodeurl": "^2.0.0",
544
+ "escape-html": "^1.0.3",
545
+ "etag": "^1.8.1",
546
+ "finalhandler": "^2.1.0",
547
+ "fresh": "^2.0.0",
548
+ "http-errors": "^2.0.0",
549
+ "merge-descriptors": "^2.0.0",
550
+ "mime-types": "^3.0.0",
551
+ "on-finished": "^2.4.1",
552
+ "once": "^1.4.0",
553
+ "parseurl": "^1.3.3",
554
+ "proxy-addr": "^2.0.7",
555
+ "qs": "^6.14.0",
556
+ "range-parser": "^1.2.1",
557
+ "router": "^2.2.0",
558
+ "send": "^1.1.0",
559
+ "serve-static": "^2.2.0",
560
+ "statuses": "^2.0.1",
561
+ "type-is": "^2.0.1",
562
+ "vary": "^1.1.2"
563
+ },
564
+ "engines": {
565
+ "node": ">= 18"
566
+ },
567
+ "funding": {
568
+ "type": "opencollective",
569
+ "url": "https://opencollective.com/express"
570
+ }
571
+ },
572
+ "node_modules/express-rate-limit": {
573
+ "version": "8.3.1",
574
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz",
575
+ "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==",
576
+ "license": "MIT",
577
+ "dependencies": {
578
+ "ip-address": "10.1.0"
579
+ },
580
+ "engines": {
581
+ "node": ">= 16"
582
+ },
583
+ "funding": {
584
+ "url": "https://github.com/sponsors/express-rate-limit"
585
+ },
586
+ "peerDependencies": {
587
+ "express": ">= 4.11"
588
+ }
589
+ },
590
+ "node_modules/fast-deep-equal": {
591
+ "version": "3.1.3",
592
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
593
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
594
+ "license": "MIT"
595
+ },
596
+ "node_modules/fast-uri": {
597
+ "version": "3.1.0",
598
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
599
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
600
+ "funding": [
601
+ {
602
+ "type": "github",
603
+ "url": "https://github.com/sponsors/fastify"
604
+ },
605
+ {
606
+ "type": "opencollective",
607
+ "url": "https://opencollective.com/fastify"
608
+ }
609
+ ],
610
+ "license": "BSD-3-Clause"
611
+ },
612
+ "node_modules/finalhandler": {
613
+ "version": "2.1.1",
614
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
615
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
616
+ "license": "MIT",
617
+ "dependencies": {
618
+ "debug": "^4.4.0",
619
+ "encodeurl": "^2.0.0",
620
+ "escape-html": "^1.0.3",
621
+ "on-finished": "^2.4.1",
622
+ "parseurl": "^1.3.3",
623
+ "statuses": "^2.0.1"
624
+ },
625
+ "engines": {
626
+ "node": ">= 18.0.0"
627
+ },
628
+ "funding": {
629
+ "type": "opencollective",
630
+ "url": "https://opencollective.com/express"
631
+ }
632
+ },
633
+ "node_modules/forwarded": {
634
+ "version": "0.2.0",
635
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
636
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
637
+ "license": "MIT",
638
+ "engines": {
639
+ "node": ">= 0.6"
640
+ }
641
+ },
642
+ "node_modules/fresh": {
643
+ "version": "2.0.0",
644
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
645
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
646
+ "license": "MIT",
647
+ "engines": {
648
+ "node": ">= 0.8"
649
+ }
650
+ },
651
+ "node_modules/fs-minipass": {
652
+ "version": "2.1.0",
653
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
654
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
655
+ "license": "ISC",
656
+ "dependencies": {
657
+ "minipass": "^3.0.0"
658
+ },
659
+ "engines": {
660
+ "node": ">= 8"
661
+ }
662
+ },
663
+ "node_modules/fs-minipass/node_modules/minipass": {
664
+ "version": "3.3.6",
665
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
666
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
667
+ "license": "ISC",
668
+ "dependencies": {
669
+ "yallist": "^4.0.0"
670
+ },
671
+ "engines": {
672
+ "node": ">=8"
673
+ }
674
+ },
675
+ "node_modules/function-bind": {
676
+ "version": "1.1.2",
677
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
678
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
679
+ "license": "MIT",
680
+ "funding": {
681
+ "url": "https://github.com/sponsors/ljharb"
682
+ }
683
+ },
684
+ "node_modules/get-intrinsic": {
685
+ "version": "1.3.0",
686
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
687
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
688
+ "license": "MIT",
689
+ "dependencies": {
690
+ "call-bind-apply-helpers": "^1.0.2",
691
+ "es-define-property": "^1.0.1",
692
+ "es-errors": "^1.3.0",
693
+ "es-object-atoms": "^1.1.1",
694
+ "function-bind": "^1.1.2",
695
+ "get-proto": "^1.0.1",
696
+ "gopd": "^1.2.0",
697
+ "has-symbols": "^1.1.0",
698
+ "hasown": "^2.0.2",
699
+ "math-intrinsics": "^1.1.0"
700
+ },
701
+ "engines": {
702
+ "node": ">= 0.4"
703
+ },
704
+ "funding": {
705
+ "url": "https://github.com/sponsors/ljharb"
706
+ }
707
+ },
708
+ "node_modules/get-proto": {
709
+ "version": "1.0.1",
710
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
711
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
712
+ "license": "MIT",
713
+ "dependencies": {
714
+ "dunder-proto": "^1.0.1",
715
+ "es-object-atoms": "^1.0.0"
716
+ },
717
+ "engines": {
718
+ "node": ">= 0.4"
719
+ }
720
+ },
721
+ "node_modules/gopd": {
722
+ "version": "1.2.0",
723
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
724
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
725
+ "license": "MIT",
726
+ "engines": {
727
+ "node": ">= 0.4"
728
+ },
729
+ "funding": {
730
+ "url": "https://github.com/sponsors/ljharb"
731
+ }
732
+ },
733
+ "node_modules/has-symbols": {
734
+ "version": "1.1.0",
735
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
736
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
737
+ "license": "MIT",
738
+ "engines": {
739
+ "node": ">= 0.4"
740
+ },
741
+ "funding": {
742
+ "url": "https://github.com/sponsors/ljharb"
743
+ }
744
+ },
745
+ "node_modules/hasown": {
746
+ "version": "2.0.2",
747
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
748
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
749
+ "license": "MIT",
750
+ "dependencies": {
751
+ "function-bind": "^1.1.2"
752
+ },
753
+ "engines": {
754
+ "node": ">= 0.4"
755
+ }
756
+ },
757
+ "node_modules/hono": {
758
+ "version": "4.12.8",
759
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz",
760
+ "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==",
761
+ "license": "MIT",
762
+ "engines": {
763
+ "node": ">=16.9.0"
764
+ }
765
+ },
766
+ "node_modules/http-errors": {
767
+ "version": "2.0.1",
768
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
769
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
770
+ "license": "MIT",
771
+ "dependencies": {
772
+ "depd": "~2.0.0",
773
+ "inherits": "~2.0.4",
774
+ "setprototypeof": "~1.2.0",
775
+ "statuses": "~2.0.2",
776
+ "toidentifier": "~1.0.1"
777
+ },
778
+ "engines": {
779
+ "node": ">= 0.8"
780
+ },
781
+ "funding": {
782
+ "type": "opencollective",
783
+ "url": "https://opencollective.com/express"
784
+ }
785
+ },
786
+ "node_modules/iceberg-js": {
787
+ "version": "0.8.1",
788
+ "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
789
+ "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
790
+ "license": "MIT",
791
+ "engines": {
792
+ "node": ">=20.0.0"
793
+ }
794
+ },
795
+ "node_modules/iconv-lite": {
796
+ "version": "0.7.2",
797
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
798
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
799
+ "license": "MIT",
800
+ "dependencies": {
801
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
802
+ },
803
+ "engines": {
804
+ "node": ">=0.10.0"
805
+ },
806
+ "funding": {
807
+ "type": "opencollective",
808
+ "url": "https://opencollective.com/express"
809
+ }
810
+ },
811
+ "node_modules/inherits": {
812
+ "version": "2.0.4",
813
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
814
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
815
+ "license": "ISC"
816
+ },
817
+ "node_modules/ip-address": {
818
+ "version": "10.1.0",
819
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
820
+ "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
821
+ "license": "MIT",
822
+ "engines": {
823
+ "node": ">= 12"
824
+ }
825
+ },
826
+ "node_modules/ipaddr.js": {
827
+ "version": "1.9.1",
828
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
829
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
830
+ "license": "MIT",
831
+ "engines": {
832
+ "node": ">= 0.10"
833
+ }
834
+ },
835
+ "node_modules/is-promise": {
836
+ "version": "4.0.0",
837
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
838
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
839
+ "license": "MIT"
840
+ },
841
+ "node_modules/isexe": {
842
+ "version": "2.0.0",
843
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
844
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
845
+ "license": "ISC"
846
+ },
847
+ "node_modules/jose": {
848
+ "version": "6.2.2",
849
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz",
850
+ "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==",
851
+ "license": "MIT",
852
+ "funding": {
853
+ "url": "https://github.com/sponsors/panva"
854
+ }
855
+ },
856
+ "node_modules/json-schema-traverse": {
857
+ "version": "1.0.0",
858
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
859
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
860
+ "license": "MIT"
861
+ },
862
+ "node_modules/json-schema-typed": {
863
+ "version": "8.0.2",
864
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
865
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
866
+ "license": "BSD-2-Clause"
867
+ },
868
+ "node_modules/math-intrinsics": {
869
+ "version": "1.1.0",
870
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
871
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
872
+ "license": "MIT",
873
+ "engines": {
874
+ "node": ">= 0.4"
875
+ }
876
+ },
877
+ "node_modules/media-typer": {
878
+ "version": "1.1.0",
879
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
880
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
881
+ "license": "MIT",
882
+ "engines": {
883
+ "node": ">= 0.8"
884
+ }
885
+ },
886
+ "node_modules/merge-descriptors": {
887
+ "version": "2.0.0",
888
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
889
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
890
+ "license": "MIT",
891
+ "engines": {
892
+ "node": ">=18"
893
+ },
894
+ "funding": {
895
+ "url": "https://github.com/sponsors/sindresorhus"
896
+ }
897
+ },
898
+ "node_modules/mime-db": {
899
+ "version": "1.54.0",
900
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
901
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
902
+ "license": "MIT",
903
+ "engines": {
904
+ "node": ">= 0.6"
905
+ }
906
+ },
907
+ "node_modules/mime-types": {
908
+ "version": "3.0.2",
909
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
910
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
911
+ "license": "MIT",
912
+ "dependencies": {
913
+ "mime-db": "^1.54.0"
914
+ },
915
+ "engines": {
916
+ "node": ">=18"
917
+ },
918
+ "funding": {
919
+ "type": "opencollective",
920
+ "url": "https://opencollective.com/express"
921
+ }
922
+ },
923
+ "node_modules/minipass": {
924
+ "version": "4.2.8",
925
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
926
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
927
+ "dev": true,
928
+ "license": "ISC",
929
+ "engines": {
930
+ "node": ">=8"
931
+ }
932
+ },
933
+ "node_modules/minizlib": {
934
+ "version": "2.1.2",
935
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
936
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
937
+ "license": "MIT",
938
+ "dependencies": {
939
+ "minipass": "^3.0.0",
940
+ "yallist": "^4.0.0"
941
+ },
942
+ "engines": {
943
+ "node": ">= 8"
944
+ }
945
+ },
946
+ "node_modules/minizlib/node_modules/minipass": {
947
+ "version": "3.3.6",
948
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
949
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
950
+ "license": "ISC",
951
+ "dependencies": {
952
+ "yallist": "^4.0.0"
953
+ },
954
+ "engines": {
955
+ "node": ">=8"
956
+ }
957
+ },
958
+ "node_modules/mkdirp": {
959
+ "version": "1.0.4",
960
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
961
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
962
+ "license": "MIT",
963
+ "bin": {
964
+ "mkdirp": "bin/cmd.js"
965
+ },
966
+ "engines": {
967
+ "node": ">=10"
968
+ }
969
+ },
970
+ "node_modules/ms": {
971
+ "version": "2.1.3",
972
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
973
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
974
+ "license": "MIT"
975
+ },
976
+ "node_modules/negotiator": {
977
+ "version": "1.0.0",
978
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
979
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
980
+ "license": "MIT",
981
+ "engines": {
982
+ "node": ">= 0.6"
983
+ }
984
+ },
985
+ "node_modules/node-cron": {
986
+ "version": "3.0.3",
987
+ "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz",
988
+ "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==",
989
+ "license": "ISC",
990
+ "dependencies": {
991
+ "uuid": "8.3.2"
992
+ },
993
+ "engines": {
994
+ "node": ">=6.0.0"
995
+ }
996
+ },
997
+ "node_modules/object-assign": {
998
+ "version": "4.1.1",
999
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1000
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1001
+ "license": "MIT",
1002
+ "engines": {
1003
+ "node": ">=0.10.0"
1004
+ }
1005
+ },
1006
+ "node_modules/object-inspect": {
1007
+ "version": "1.13.4",
1008
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
1009
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
1010
+ "license": "MIT",
1011
+ "engines": {
1012
+ "node": ">= 0.4"
1013
+ },
1014
+ "funding": {
1015
+ "url": "https://github.com/sponsors/ljharb"
1016
+ }
1017
+ },
1018
+ "node_modules/on-finished": {
1019
+ "version": "2.4.1",
1020
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1021
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1022
+ "license": "MIT",
1023
+ "dependencies": {
1024
+ "ee-first": "1.1.1"
1025
+ },
1026
+ "engines": {
1027
+ "node": ">= 0.8"
1028
+ }
1029
+ },
1030
+ "node_modules/once": {
1031
+ "version": "1.4.0",
1032
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1033
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1034
+ "license": "ISC",
1035
+ "dependencies": {
1036
+ "wrappy": "1"
1037
+ }
1038
+ },
1039
+ "node_modules/parseurl": {
1040
+ "version": "1.3.3",
1041
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1042
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1043
+ "license": "MIT",
1044
+ "engines": {
1045
+ "node": ">= 0.8"
1046
+ }
1047
+ },
1048
+ "node_modules/path-key": {
1049
+ "version": "3.1.1",
1050
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1051
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1052
+ "license": "MIT",
1053
+ "engines": {
1054
+ "node": ">=8"
1055
+ }
1056
+ },
1057
+ "node_modules/path-to-regexp": {
1058
+ "version": "8.3.0",
1059
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
1060
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
1061
+ "license": "MIT",
1062
+ "funding": {
1063
+ "type": "opencollective",
1064
+ "url": "https://opencollective.com/express"
1065
+ }
1066
+ },
1067
+ "node_modules/pkce-challenge": {
1068
+ "version": "5.0.1",
1069
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
1070
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
1071
+ "license": "MIT",
1072
+ "engines": {
1073
+ "node": ">=16.20.0"
1074
+ }
1075
+ },
1076
+ "node_modules/proxy-addr": {
1077
+ "version": "2.0.7",
1078
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1079
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1080
+ "license": "MIT",
1081
+ "dependencies": {
1082
+ "forwarded": "0.2.0",
1083
+ "ipaddr.js": "1.9.1"
1084
+ },
1085
+ "engines": {
1086
+ "node": ">= 0.10"
1087
+ }
1088
+ },
1089
+ "node_modules/qs": {
1090
+ "version": "6.15.0",
1091
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
1092
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
1093
+ "license": "BSD-3-Clause",
1094
+ "dependencies": {
1095
+ "side-channel": "^1.1.0"
1096
+ },
1097
+ "engines": {
1098
+ "node": ">=0.6"
1099
+ },
1100
+ "funding": {
1101
+ "url": "https://github.com/sponsors/ljharb"
1102
+ }
1103
+ },
1104
+ "node_modules/range-parser": {
1105
+ "version": "1.2.1",
1106
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1107
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1108
+ "license": "MIT",
1109
+ "engines": {
1110
+ "node": ">= 0.6"
1111
+ }
1112
+ },
1113
+ "node_modules/raw-body": {
1114
+ "version": "3.0.2",
1115
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
1116
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
1117
+ "license": "MIT",
1118
+ "dependencies": {
1119
+ "bytes": "~3.1.2",
1120
+ "http-errors": "~2.0.1",
1121
+ "iconv-lite": "~0.7.0",
1122
+ "unpipe": "~1.0.0"
1123
+ },
1124
+ "engines": {
1125
+ "node": ">= 0.10"
1126
+ }
1127
+ },
1128
+ "node_modules/require-from-string": {
1129
+ "version": "2.0.2",
1130
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
1131
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
1132
+ "license": "MIT",
1133
+ "engines": {
1134
+ "node": ">=0.10.0"
1135
+ }
1136
+ },
1137
+ "node_modules/router": {
1138
+ "version": "2.2.0",
1139
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
1140
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
1141
+ "license": "MIT",
1142
+ "dependencies": {
1143
+ "debug": "^4.4.0",
1144
+ "depd": "^2.0.0",
1145
+ "is-promise": "^4.0.0",
1146
+ "parseurl": "^1.3.3",
1147
+ "path-to-regexp": "^8.0.0"
1148
+ },
1149
+ "engines": {
1150
+ "node": ">= 18"
1151
+ }
1152
+ },
1153
+ "node_modules/safer-buffer": {
1154
+ "version": "2.1.2",
1155
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1156
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1157
+ "license": "MIT"
1158
+ },
1159
+ "node_modules/send": {
1160
+ "version": "1.2.1",
1161
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
1162
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
1163
+ "license": "MIT",
1164
+ "dependencies": {
1165
+ "debug": "^4.4.3",
1166
+ "encodeurl": "^2.0.0",
1167
+ "escape-html": "^1.0.3",
1168
+ "etag": "^1.8.1",
1169
+ "fresh": "^2.0.0",
1170
+ "http-errors": "^2.0.1",
1171
+ "mime-types": "^3.0.2",
1172
+ "ms": "^2.1.3",
1173
+ "on-finished": "^2.4.1",
1174
+ "range-parser": "^1.2.1",
1175
+ "statuses": "^2.0.2"
1176
+ },
1177
+ "engines": {
1178
+ "node": ">= 18"
1179
+ },
1180
+ "funding": {
1181
+ "type": "opencollective",
1182
+ "url": "https://opencollective.com/express"
1183
+ }
1184
+ },
1185
+ "node_modules/serve-static": {
1186
+ "version": "2.2.1",
1187
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
1188
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
1189
+ "license": "MIT",
1190
+ "dependencies": {
1191
+ "encodeurl": "^2.0.0",
1192
+ "escape-html": "^1.0.3",
1193
+ "parseurl": "^1.3.3",
1194
+ "send": "^1.2.0"
1195
+ },
1196
+ "engines": {
1197
+ "node": ">= 18"
1198
+ },
1199
+ "funding": {
1200
+ "type": "opencollective",
1201
+ "url": "https://opencollective.com/express"
1202
+ }
1203
+ },
1204
+ "node_modules/setprototypeof": {
1205
+ "version": "1.2.0",
1206
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1207
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1208
+ "license": "ISC"
1209
+ },
1210
+ "node_modules/shebang-command": {
1211
+ "version": "2.0.0",
1212
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1213
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1214
+ "license": "MIT",
1215
+ "dependencies": {
1216
+ "shebang-regex": "^3.0.0"
1217
+ },
1218
+ "engines": {
1219
+ "node": ">=8"
1220
+ }
1221
+ },
1222
+ "node_modules/shebang-regex": {
1223
+ "version": "3.0.0",
1224
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1225
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1226
+ "license": "MIT",
1227
+ "engines": {
1228
+ "node": ">=8"
1229
+ }
1230
+ },
1231
+ "node_modules/side-channel": {
1232
+ "version": "1.1.0",
1233
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
1234
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
1235
+ "license": "MIT",
1236
+ "dependencies": {
1237
+ "es-errors": "^1.3.0",
1238
+ "object-inspect": "^1.13.3",
1239
+ "side-channel-list": "^1.0.0",
1240
+ "side-channel-map": "^1.0.1",
1241
+ "side-channel-weakmap": "^1.0.2"
1242
+ },
1243
+ "engines": {
1244
+ "node": ">= 0.4"
1245
+ },
1246
+ "funding": {
1247
+ "url": "https://github.com/sponsors/ljharb"
1248
+ }
1249
+ },
1250
+ "node_modules/side-channel-list": {
1251
+ "version": "1.0.0",
1252
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
1253
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
1254
+ "license": "MIT",
1255
+ "dependencies": {
1256
+ "es-errors": "^1.3.0",
1257
+ "object-inspect": "^1.13.3"
1258
+ },
1259
+ "engines": {
1260
+ "node": ">= 0.4"
1261
+ },
1262
+ "funding": {
1263
+ "url": "https://github.com/sponsors/ljharb"
1264
+ }
1265
+ },
1266
+ "node_modules/side-channel-map": {
1267
+ "version": "1.0.1",
1268
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
1269
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
1270
+ "license": "MIT",
1271
+ "dependencies": {
1272
+ "call-bound": "^1.0.2",
1273
+ "es-errors": "^1.3.0",
1274
+ "get-intrinsic": "^1.2.5",
1275
+ "object-inspect": "^1.13.3"
1276
+ },
1277
+ "engines": {
1278
+ "node": ">= 0.4"
1279
+ },
1280
+ "funding": {
1281
+ "url": "https://github.com/sponsors/ljharb"
1282
+ }
1283
+ },
1284
+ "node_modules/side-channel-weakmap": {
1285
+ "version": "1.0.2",
1286
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
1287
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
1288
+ "license": "MIT",
1289
+ "dependencies": {
1290
+ "call-bound": "^1.0.2",
1291
+ "es-errors": "^1.3.0",
1292
+ "get-intrinsic": "^1.2.5",
1293
+ "object-inspect": "^1.13.3",
1294
+ "side-channel-map": "^1.0.1"
1295
+ },
1296
+ "engines": {
1297
+ "node": ">= 0.4"
1298
+ },
1299
+ "funding": {
1300
+ "url": "https://github.com/sponsors/ljharb"
1301
+ }
1302
+ },
1303
+ "node_modules/statuses": {
1304
+ "version": "2.0.2",
1305
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
1306
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
1307
+ "license": "MIT",
1308
+ "engines": {
1309
+ "node": ">= 0.8"
1310
+ }
1311
+ },
1312
+ "node_modules/tar": {
1313
+ "version": "6.2.1",
1314
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
1315
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
1316
+ "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",
1317
+ "license": "ISC",
1318
+ "dependencies": {
1319
+ "chownr": "^2.0.0",
1320
+ "fs-minipass": "^2.0.0",
1321
+ "minipass": "^5.0.0",
1322
+ "minizlib": "^2.1.1",
1323
+ "mkdirp": "^1.0.3",
1324
+ "yallist": "^4.0.0"
1325
+ },
1326
+ "engines": {
1327
+ "node": ">=10"
1328
+ }
1329
+ },
1330
+ "node_modules/tar/node_modules/minipass": {
1331
+ "version": "5.0.0",
1332
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
1333
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
1334
+ "license": "ISC",
1335
+ "engines": {
1336
+ "node": ">=8"
1337
+ }
1338
+ },
1339
+ "node_modules/toidentifier": {
1340
+ "version": "1.0.1",
1341
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1342
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1343
+ "license": "MIT",
1344
+ "engines": {
1345
+ "node": ">=0.6"
1346
+ }
1347
+ },
1348
+ "node_modules/tslib": {
1349
+ "version": "2.8.1",
1350
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1351
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1352
+ "license": "0BSD"
1353
+ },
1354
+ "node_modules/type-is": {
1355
+ "version": "2.0.1",
1356
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
1357
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
1358
+ "license": "MIT",
1359
+ "dependencies": {
1360
+ "content-type": "^1.0.5",
1361
+ "media-typer": "^1.1.0",
1362
+ "mime-types": "^3.0.0"
1363
+ },
1364
+ "engines": {
1365
+ "node": ">= 0.6"
1366
+ }
1367
+ },
1368
+ "node_modules/typescript": {
1369
+ "version": "5.9.3",
1370
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
1371
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
1372
+ "dev": true,
1373
+ "license": "Apache-2.0",
1374
+ "bin": {
1375
+ "tsc": "bin/tsc",
1376
+ "tsserver": "bin/tsserver"
1377
+ },
1378
+ "engines": {
1379
+ "node": ">=14.17"
1380
+ }
1381
+ },
1382
+ "node_modules/undici-types": {
1383
+ "version": "7.16.0",
1384
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
1385
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
1386
+ "license": "MIT"
1387
+ },
1388
+ "node_modules/unpipe": {
1389
+ "version": "1.0.0",
1390
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1391
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1392
+ "license": "MIT",
1393
+ "engines": {
1394
+ "node": ">= 0.8"
1395
+ }
1396
+ },
1397
+ "node_modules/uuid": {
1398
+ "version": "8.3.2",
1399
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
1400
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
1401
+ "license": "MIT",
1402
+ "bin": {
1403
+ "uuid": "dist/bin/uuid"
1404
+ }
1405
+ },
1406
+ "node_modules/vary": {
1407
+ "version": "1.1.2",
1408
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1409
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1410
+ "license": "MIT",
1411
+ "engines": {
1412
+ "node": ">= 0.8"
1413
+ }
1414
+ },
1415
+ "node_modules/which": {
1416
+ "version": "2.0.2",
1417
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1418
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1419
+ "license": "ISC",
1420
+ "dependencies": {
1421
+ "isexe": "^2.0.0"
1422
+ },
1423
+ "bin": {
1424
+ "node-which": "bin/node-which"
1425
+ },
1426
+ "engines": {
1427
+ "node": ">= 8"
1428
+ }
1429
+ },
1430
+ "node_modules/wrappy": {
1431
+ "version": "1.0.2",
1432
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1433
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1434
+ "license": "ISC"
1435
+ },
1436
+ "node_modules/ws": {
1437
+ "version": "8.19.0",
1438
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
1439
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
1440
+ "license": "MIT",
1441
+ "engines": {
1442
+ "node": ">=10.0.0"
1443
+ },
1444
+ "peerDependencies": {
1445
+ "bufferutil": "^4.0.1",
1446
+ "utf-8-validate": ">=5.0.2"
1447
+ },
1448
+ "peerDependenciesMeta": {
1449
+ "bufferutil": {
1450
+ "optional": true
1451
+ },
1452
+ "utf-8-validate": {
1453
+ "optional": true
1454
+ }
1455
+ }
1456
+ },
1457
+ "node_modules/yallist": {
1458
+ "version": "4.0.0",
1459
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1460
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
1461
+ "license": "ISC"
1462
+ },
1463
+ "node_modules/zod": {
1464
+ "version": "3.25.76",
1465
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
1466
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
1467
+ "license": "MIT",
1468
+ "funding": {
1469
+ "url": "https://github.com/sponsors/colinhacks"
1470
+ }
1471
+ },
1472
+ "node_modules/zod-to-json-schema": {
1473
+ "version": "3.25.1",
1474
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz",
1475
+ "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==",
1476
+ "license": "ISC",
1477
+ "peerDependencies": {
1478
+ "zod": "^3.25 || ^4"
1479
+ }
1480
+ }
1481
+ }
1482
+ }
scripts/hf_pull_script.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ A2A Consumer Rotator (HF VM Pull Script)
4
+ Pulls a fresh OpenAI token from SIN-Supabase when a rate-limit is hit.
5
+ Infinite Scaling Architecture.
6
+ """
7
+
8
+ import os
9
+ import json
10
+ import requests
11
+ from pathlib import Path
12
+
13
+ SUPABASE_URL = os.environ.get("SUPABASE_URL")
14
+ SUPABASE_KEY = os.environ.get("SUPABASE_SERVICE_ROLE_KEY")
15
+ AUTH_FILE = Path.home() / ".local" / "share" / "opencode" / "auth.json"
16
+
17
+ def pull_fresh_token():
18
+ if not SUPABASE_URL or not SUPABASE_KEY:
19
+ print("❌ FEHLER: SUPABASE_URL oder SUPABASE_SERVICE_ROLE_KEY fehlen!")
20
+ return False
21
+
22
+ base_url = SUPABASE_URL.rstrip('/')
23
+ headers = {
24
+ "apikey": SUPABASE_KEY,
25
+ "Authorization": f"Bearer {SUPABASE_KEY}",
26
+ "Content-Type": "application/json",
27
+ "Prefer": "return=representation"
28
+ }
29
+
30
+ print("🔍 Suche frischen Token im Pool...")
31
+ get_url = f"{base_url}/rest/v1/openai_account_pool?status=eq.FRESH&limit=1"
32
+ resp = requests.get(get_url, headers=headers, timeout=5)
33
+
34
+ if resp.status_code != 200 or not resp.json():
35
+ print("❌ FEHLER: Kein frischer Token im Pool verfügbar!")
36
+ return False
37
+
38
+ row = resp.json()[0]
39
+ row_id = row["id"]
40
+ new_auth_data = row["auth_json_data"]
41
+
42
+ patch_url = f"{base_url}/rest/v1/openai_account_pool?id=eq.{row_id}"
43
+ requests.patch(patch_url, headers=headers, json={"status": "IN_USE"}, timeout=5)
44
+
45
+ AUTH_FILE.parent.mkdir(parents=True, exist_ok=True)
46
+ current_data = {}
47
+ if AUTH_FILE.exists():
48
+ try:
49
+ current_data = json.loads(AUTH_FILE.read_text())
50
+ except:
51
+ pass
52
+
53
+ current_data["openai"] = new_auth_data
54
+ AUTH_FILE.write_text(json.dumps(current_data, indent=2))
55
+ print(f"🚀 ERFOLG: Lokale auth.json überschrieben. (ID: {row_id})")
56
+ return True
57
+
58
+ if __name__ == "__main__":
59
+ pull_fresh_token()
src/a2a-http.ts CHANGED
@@ -1,8 +1,8 @@
1
  import { randomUUID } from 'node:crypto';
2
  import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
3
- import type { GitHubIssuesAction } from './contracts.js';
4
  import { buildAgentCard, resolveTemplateAgentConfig, TEMPLATE_AGENT_ID, TEMPLATE_AGENT_NAME } from './metadata.js';
5
- import { executeTemplateAgentAction } from './runtime.js';
6
 
7
  type RpcRequest = { jsonrpc?: string; id?: string | number | null; method?: string; params?: Record<string, unknown> };
8
 
@@ -34,7 +34,7 @@ async function handleRequest(request: IncomingMessage, response: ServerResponse,
34
  if (rpc.method === 'agent/getCard') return sendJson(response, 200, { jsonrpc: '2.0', id: rpc.id ?? null, result: buildAgentCard(baseUrl) });
35
  if (rpc.method === 'message/send') {
36
  const action = parseAction((rpc.params?.message as { parts?: Array<{ text?: string }> } | undefined)?.parts?.map((part) => part.text || '').join(' ').trim() || '');
37
- const result = await executeTemplateAgentAction(action);
38
  return sendJson(response, 200, {
39
  jsonrpc: '2.0',
40
  id: rpc.id ?? null,
@@ -51,11 +51,22 @@ async function handleRequest(request: IncomingMessage, response: ServerResponse,
51
  sendJson(response, 404, { error: 'not_found' });
52
  }
53
 
54
- function parseAction(text: string): GitHubIssuesAction {
55
- const value = text.toLowerCase();
56
- if (value === 'sin.github.issues health') return { action: 'sin.github.issues.health' };
57
- if (value === 'sin.github.issues onboarding status') return { action: 'sin.github.issues.onboarding.status' };
58
- if (value === 'sin.github.issues auth status') return { action: 'sin.github.issues.auth.status' };
 
 
 
 
 
 
 
 
 
 
 
59
  return { action: 'agent.help' };
60
  }
61
 
 
1
  import { randomUUID } from 'node:crypto';
2
  import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
3
+ import type { GitHubAgentAction } from './runtime.js';
4
  import { buildAgentCard, resolveTemplateAgentConfig, TEMPLATE_AGENT_ID, TEMPLATE_AGENT_NAME } from './metadata.js';
5
+ import { executeGitHubAgentAction } from './runtime.js';
6
 
7
  type RpcRequest = { jsonrpc?: string; id?: string | number | null; method?: string; params?: Record<string, unknown> };
8
 
 
34
  if (rpc.method === 'agent/getCard') return sendJson(response, 200, { jsonrpc: '2.0', id: rpc.id ?? null, result: buildAgentCard(baseUrl) });
35
  if (rpc.method === 'message/send') {
36
  const action = parseAction((rpc.params?.message as { parts?: Array<{ text?: string }> } | undefined)?.parts?.map((part) => part.text || '').join(' ').trim() || '');
37
+ const result = await executeGitHubAgentAction(action);
38
  return sendJson(response, 200, {
39
  jsonrpc: '2.0',
40
  id: rpc.id ?? null,
 
51
  sendJson(response, 404, { error: 'not_found' });
52
  }
53
 
54
+ function parseAction(text: string): GitHubAgentAction {
55
+ try {
56
+ const parsed = JSON.parse(text);
57
+ if (parsed && typeof parsed === 'object' && typeof parsed.action === 'string') return parsed as GitHubAgentAction;
58
+ } catch { /* not JSON, fall through to text matching */ }
59
+
60
+ const value = text.toLowerCase().trim();
61
+ if (value.includes('health')) return { action: 'sin.github.health' };
62
+ if (value.includes('project')) return { action: 'sin.github.project.orchestrate', prompt: text };
63
+ if (value.includes('wiki')) return { action: 'sin.github.wiki.sync', prompt: text };
64
+ if (value.includes('discussion')) return { action: 'sin.github.discussion.start', prompt: text };
65
+ if (value.includes('gist')) return { action: 'sin.github.gist.publish', prompt: text };
66
+ if (value.includes('security') || value.includes('audit')) return { action: 'sin.github.security.audit', prompt: text };
67
+ if (value.includes('pr') || value.includes('pull request') || value.includes('review')) return { action: 'sin.github.pr.review', prNumber: 0 };
68
+ if (value.includes('ledger') || value.includes('showcase')) return { action: 'sin.github.ledger.log', agentName: 'unknown', activityTitle: text, details: text };
69
+ if (value.includes('issue')) return { action: 'sin.github.issue.manage', prompt: text };
70
  return { action: 'agent.help' };
71
  }
72
 
src/cli.ts CHANGED
@@ -1,67 +1,39 @@
1
  #!/usr/bin/env node
2
 
3
- import process from 'node:process';
4
- import { restoreAuthSession, startKeepAlivePing, startAutoBackup } from './hf_sync.js';
5
  import { createTemplateAgentHttpServer } from './a2a-http.js';
6
- import type { GitHubIssuesAction } from './contracts.js';
7
- import { buildAgentCard, resolveTemplateAgentConfig } from './metadata.js';
8
- import { startMcpServer } from './mcp-server.js';
9
- import { executeTemplateAgentAction } from './runtime.js';
10
-
11
- async function main(): Promise<void> {
12
- const command = process.argv[2] || 'help';
13
- switch (command) {
14
- case 'serve':
15
- case 'serve-a2a':
16
- await serveA2A();
17
- return;
18
- case 'serve-mcp':
19
- await startMcpServer();
20
- return;
21
- case 'print-card':
22
- printJson(buildAgentCard(resolveTemplateAgentConfig().publicBaseUrl));
23
- return;
24
- case 'run-action':
25
- await runAction();
26
- return;
27
- default:
28
- printUsage();
29
  }
 
 
 
 
 
 
 
 
 
30
  }
31
-
32
- async function serveA2A() {
33
- await restoreAuthSession();
34
- startKeepAlivePing();
35
- startAutoBackup();
36
- const config = resolveTemplateAgentConfig();
37
- const handle = createTemplateAgentHttpServer();
38
- await handle.start();
39
- printJson({ ok: true, command: 'serve-a2a', host: config.host, port: config.port, baseUrl: config.publicBaseUrl });
40
- }
41
-
42
- async function runAction() {
43
- const raw = process.argv[3]?.trim() || (await readStdin()).trim();
44
- if (!raw) throw new Error('missing_action_json');
45
- printJson(await executeTemplateAgentAction(JSON.parse(raw) as GitHubIssuesAction));
46
- }
47
-
48
- function printUsage() {
49
- process.stderr.write(
50
- ['Usage:', ' sin-github-issues serve-a2a', ' sin-github-issues serve-mcp', ' sin-github-issues print-card', ` sin-github-issues run-action '{"action":"agent.help"}'`].join('\n') + '\n',
51
- );
52
- }
53
-
54
- function printJson(payload: unknown) {
55
- process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
56
- }
57
-
58
- async function readStdin() {
59
- const chunks: Buffer[] = [];
60
- for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
61
- return Buffer.concat(chunks).toString('utf8');
62
- }
63
-
64
- main().catch((error) => {
65
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
66
- process.exitCode = 1;
67
- });
 
1
  #!/usr/bin/env node
2
 
3
+ import { readFileSync } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
  import { createTemplateAgentHttpServer } from './a2a-http.js';
6
+ import { runMcpServer } from './mcp-server.js';
7
+ import { executeGitHubAgentAction } from './runtime.js';
8
+
9
+ const cmd = process.argv[2];
10
+
11
+ if (cmd === 'serve-a2a') {
12
+ createTemplateAgentHttpServer().start().catch(err => {
13
+ console.error(err);
14
+ process.exit(1);
15
+ });
16
+ } else if (cmd === 'serve-mcp') {
17
+ runMcpServer().catch(err => {
18
+ console.error(err);
19
+ process.exit(1);
20
+ });
21
+ } else if (cmd === 'print-card') {
22
+ const cardPath = resolve(process.cwd(), 'A2A-CARD.md');
23
+ console.log(readFileSync(cardPath, 'utf8'));
24
+ } else if (cmd === 'run-action') {
25
+ const payload = process.argv[3];
26
+ if (!payload) {
27
+ console.error('Usage: run-action \'{"action":"sin.github.health"}\'');
28
+ process.exit(1);
29
  }
30
+ executeGitHubAgentAction(JSON.parse(payload))
31
+ .then(res => console.log(JSON.stringify(res, null, 2)))
32
+ .catch(err => {
33
+ console.error(err);
34
+ process.exit(1);
35
+ });
36
+ } else {
37
+ console.error('Usage: <cli> [serve-mcp|print-card|run-action]');
38
+ process.exit(1);
39
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/contracts.ts CHANGED
@@ -1,31 +1,8 @@
1
- export type GitHubIssuesAction =
2
- | { action: 'agent.help' }
3
- | { action: 'sin.github.issues.health' }
4
- | { action: 'sin.github.issues.onboarding.status' }
5
- | {
6
- action: 'sin.github.issues.onboarding.save';
7
- ownerEmail?: string;
8
- notes?: string;
9
- defaultRepo?: string;
10
- browserProfileEmail?: string;
11
- browserProfileDirectory?: string;
12
- confirm?: boolean;
13
- }
14
- | { action: 'sin.github.issues.auth.status' }
15
- | { action: 'sin.github.issues.issue.ensure'; repo: string; title: string; body: string; labels?: string[] }
16
- | { action: 'sin.github.issues.issue.comment'; repo: string; issueNumber: number; body: string }
17
- | { action: 'sin.github.issues.issue.close'; repo: string; issueNumber: number; comment?: string }
18
- | { action: 'sin.github.issues.repo.status'; repoPath: string }
19
- | { action: 'sin.github.issues.repo.branch.start'; repoPath: string; branchName: string; baseRef?: string }
20
- | { action: 'sin.github.issues.repo.commit'; repoPath: string; message: string }
21
- | { action: 'sin.github.issues.repo.push'; repoPath: string; remote?: string; branchName?: string }
22
- | {
23
- action: 'sin.github.issues.workflow.finalize_fix';
24
- repo: string;
25
- issueNumber: number;
26
- rootCause: string;
27
- fix: string;
28
- verification: string;
29
- affectedFiles?: string[];
30
- closeIssue?: boolean;
31
- };
 
1
+ /**
2
+ * Legacy contracts file — retained for backward compatibility.
3
+ * The canonical action type is now `GitHubAgentAction` in `runtime.ts`.
4
+ */
5
+ export type { GitHubAgentAction } from './runtime.js';
6
+
7
+ /** @deprecated Use `GitHubAgentAction` from `./runtime.js` instead. */
8
+ export type GitHubIssuesAction = import('./runtime.js').GitHubAgentAction;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/index.ts CHANGED
@@ -2,4 +2,4 @@ export * from './runtime.js';
2
  export * from './metadata.js';
3
  export * from './a2a-http.js';
4
  export * from './mcp-server.js';
5
-
 
2
  export * from './metadata.js';
3
  export * from './a2a-http.js';
4
  export * from './mcp-server.js';
5
+ export type { GitHubIssuesAction } from './contracts.js';
src/mcp-server.ts CHANGED
@@ -1,62 +1,173 @@
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
- defaultRepo: z.string().optional(),
11
- browserProfileEmail: z.string().optional(),
12
- browserProfileDirectory: z.string().optional(),
13
- confirm: z.boolean().optional(),
14
- });
15
- const issueEnsureSchema = z.object({ repo: z.string(), title: z.string(), body: z.string(), labels: z.array(z.string()).optional() });
16
- const issueCommentSchema = z.object({ repo: z.string(), issueNumber: z.number().int().positive(), body: z.string() });
17
- const issueCloseSchema = z.object({ repo: z.string(), issueNumber: z.number().int().positive(), comment: z.string().optional() });
18
- const repoStatusSchema = z.object({ repoPath: z.string() });
19
- const branchStartSchema = z.object({ repoPath: z.string(), branchName: z.string(), baseRef: z.string().optional() });
20
- const repoCommitSchema = z.object({ repoPath: z.string(), message: z.string() });
21
- const repoPushSchema = z.object({ repoPath: z.string(), remote: z.string().optional(), branchName: z.string().optional() });
22
- const finalizeFixSchema = z.object({
23
- repo: z.string(),
24
- issueNumber: z.number().int().positive(),
25
- rootCause: z.string(),
26
- fix: z.string(),
27
- verification: z.string(),
28
- affectedFiles: z.array(z.string()).optional(),
29
- closeIssue: z.boolean().optional(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  });
31
 
32
- const TOOLS = [
33
- ['sin_github_issues_help', 'Describe available agent actions.', () => ({}), async () => executeTemplateAgentAction({ action: 'agent.help' })],
34
- ['sin_github_issues_health', 'Check base agent readiness.', () => ({}), async () => executeTemplateAgentAction({ action: 'sin.github.issues.health' })],
35
- ['sin_github_issues_onboarding_status', 'Read onboarding state.', () => ({}), async () => executeTemplateAgentAction({ action: 'sin.github.issues.onboarding.status' })],
36
- ['sin_github_issues_onboarding_save', 'Persist onboarding state. Requires confirm=true.', (input: unknown) => onboardingSaveSchema.parse(input ?? {}), async (input: z.infer<typeof onboardingSaveSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.onboarding.save', ...input })],
37
- ['sin_github_issues_auth_status', 'Read GitHub/browser/auth readiness.', () => ({}), async () => executeTemplateAgentAction({ action: 'sin.github.issues.auth.status' })],
38
- ['sin_github_issues_issue_ensure', 'Search or create the matching GitHub issue.', (input: unknown) => issueEnsureSchema.parse(input ?? {}), async (input: z.infer<typeof issueEnsureSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.issue.ensure', ...input })],
39
- ['sin_github_issues_issue_comment', 'Add a comment to an existing GitHub issue.', (input: unknown) => issueCommentSchema.parse(input ?? {}), async (input: z.infer<typeof issueCommentSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.issue.comment', ...input })],
40
- ['sin_github_issues_issue_close', 'Close a GitHub issue after verification.', (input: unknown) => issueCloseSchema.parse(input ?? {}), async (input: z.infer<typeof issueCloseSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.issue.close', ...input })],
41
- ['sin_github_issues_repo_status', 'Read local git branch and worktree status.', (input: unknown) => repoStatusSchema.parse(input ?? {}), async (input: z.infer<typeof repoStatusSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.repo.status', ...input })],
42
- ['sin_github_issues_repo_branch_start', 'Create/reset the fix branch from a base ref.', (input: unknown) => branchStartSchema.parse(input ?? {}), async (input: z.infer<typeof branchStartSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.repo.branch.start', ...input })],
43
- ['sin_github_issues_repo_commit', 'Commit staged repo changes.', (input: unknown) => repoCommitSchema.parse(input ?? {}), async (input: z.infer<typeof repoCommitSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.repo.commit', ...input })],
44
- ['sin_github_issues_repo_push', 'Push the fix branch to origin.', (input: unknown) => repoPushSchema.parse(input ?? {}), async (input: z.infer<typeof repoPushSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.repo.push', ...input })],
45
- ['sin_github_issues_workflow_finalize_fix', 'Update the issue with RCA/fix/verification and optionally close it.', (input: unknown) => finalizeFixSchema.parse(input ?? {}), async (input: z.infer<typeof finalizeFixSchema>) => executeTemplateAgentAction({ action: 'sin.github.issues.workflow.finalize_fix', ...input })],
46
- ] as const;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- export async function startMcpServer(): Promise<void> {
49
- const server = new Server({ name: 'sin-github-issues', version: '0.1.0' }, { capabilities: { tools: {} } });
50
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
51
- tools: TOOLS.map(([name, description]) => ({ name, description, inputSchema: { type: 'object', properties: {} } })),
52
- }));
53
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
54
- const tool = TOOLS.find(([name]) => name === request.params.name);
55
- if (!tool) return { content: [{ type: 'text', text: `Unknown tool: ${request.params.name}` }], isError: true };
56
- const parsed = tool[2](request.params.arguments ?? {});
57
- const result = await tool[3](parsed as never);
58
- return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
59
- });
60
  const transport = new StdioServerTransport();
61
  await server.connect(transport);
 
62
  }
 
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 { executeGitHubAgentAction, GitHubAgentAction } from './runtime.js';
 
5
 
6
+ const server = new Server(
7
+ { name: 'sin-github-issues', version: '2026.03.22' },
8
+ { capabilities: { tools: {} } },
9
+ );
10
+
11
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
12
+ return {
13
+ tools: [
14
+ {
15
+ name: 'sin_github_health',
16
+ description: 'Check 2026 Elite GitHub Operations Architect readiness.',
17
+ inputSchema: { type: 'object', properties: {} },
18
+ },
19
+ {
20
+ name: 'sin_github_project_orchestrate',
21
+ description: 'Create and manage GitHub Projects V2 boards.',
22
+ inputSchema: {
23
+ type: 'object',
24
+ properties: {
25
+ prompt: { type: 'string' },
26
+ contextDir: { type: 'string' },
27
+ },
28
+ required: ['prompt'],
29
+ },
30
+ },
31
+ {
32
+ name: 'sin_github_issue_manage',
33
+ description: 'Create, update, or close issues (Epics, Sub-tasks).',
34
+ inputSchema: {
35
+ type: 'object',
36
+ properties: {
37
+ prompt: { type: 'string' },
38
+ issueNumber: { type: 'number' },
39
+ },
40
+ required: ['prompt'],
41
+ },
42
+ },
43
+ {
44
+ name: 'sin_github_wiki_sync',
45
+ description: 'Update the repository Wiki with project documentation.',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ prompt: { type: 'string' },
50
+ contextDir: { type: 'string' },
51
+ },
52
+ required: ['prompt'],
53
+ },
54
+ },
55
+ {
56
+ name: 'sin_github_discussion_start',
57
+ description: 'Start an architectural debate in Discussions.',
58
+ inputSchema: {
59
+ type: 'object',
60
+ properties: {
61
+ prompt: { type: 'string' },
62
+ category: { type: 'string' },
63
+ },
64
+ required: ['prompt'],
65
+ },
66
+ },
67
+ {
68
+ name: 'sin_github_gist_publish',
69
+ description: 'Upload a large log or code snippet to a Gist.',
70
+ inputSchema: {
71
+ type: 'object',
72
+ properties: {
73
+ prompt: { type: 'string' },
74
+ isPublic: { type: 'boolean' },
75
+ },
76
+ required: ['prompt'],
77
+ },
78
+ },
79
+ {
80
+ name: 'sin_github_security_audit',
81
+ description: 'Audit security alerts and configure Dependabot/CodeQL.',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ prompt: { type: 'string' },
86
+ contextDir: { type: 'string' },
87
+ },
88
+ required: ['prompt'],
89
+ },
90
+ },
91
+ {
92
+ name: 'sin_github_pr_review',
93
+ description: 'Review and approve/merge Pull Requests.',
94
+ inputSchema: {
95
+ type: 'object',
96
+ properties: {
97
+ prNumber: { type: 'number' },
98
+ contextDir: { type: 'string' },
99
+ },
100
+ required: ['prNumber'],
101
+ },
102
+ },
103
+ {
104
+ name: 'sin_github_ledger_log',
105
+ description: 'Publish an agent activity log or achievement to the public OpenSolver-Ledger showcase repository.',
106
+ inputSchema: {
107
+ type: 'object',
108
+ properties: {
109
+ agentName: { type: 'string', description: 'Name of the agent logging the activity' },
110
+ activityTitle: { type: 'string', description: 'Short title of the achievement or task' },
111
+ details: { type: 'string', description: 'Detailed markdown describing what was accomplished' },
112
+ },
113
+ required: ['agentName', 'activityTitle', 'details'],
114
+ },
115
+ },
116
+ ],
117
+ };
118
  });
119
 
120
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
121
+ try {
122
+ let action: GitHubAgentAction;
123
+ const args = request.params.arguments as any;
124
+
125
+ switch (request.params.name) {
126
+ case 'sin_github_health':
127
+ action = { action: 'sin.github.health' };
128
+ break;
129
+ case 'sin_github_project_orchestrate':
130
+ action = { action: 'sin.github.project.orchestrate', prompt: args.prompt, contextDir: args.contextDir };
131
+ break;
132
+ case 'sin_github_issue_manage':
133
+ action = { action: 'sin.github.issue.manage', prompt: args.prompt, issueNumber: args.issueNumber };
134
+ break;
135
+ case 'sin_github_wiki_sync':
136
+ action = { action: 'sin.github.wiki.sync', prompt: args.prompt, contextDir: args.contextDir };
137
+ break;
138
+ case 'sin_github_discussion_start':
139
+ action = { action: 'sin.github.discussion.start', prompt: args.prompt, category: args.category };
140
+ break;
141
+ case 'sin_github_gist_publish':
142
+ action = { action: 'sin.github.gist.publish', prompt: args.prompt, isPublic: args.isPublic };
143
+ break;
144
+ case 'sin_github_security_audit':
145
+ action = { action: 'sin.github.security.audit', prompt: args.prompt, contextDir: args.contextDir };
146
+ break;
147
+ case 'sin_github_pr_review':
148
+ action = { action: 'sin.github.pr.review', prNumber: args.prNumber, contextDir: args.contextDir };
149
+ break;
150
+ case 'sin_github_ledger_log':
151
+ action = { action: 'sin.github.ledger.log', agentName: args.agentName, activityTitle: args.activityTitle, details: args.details };
152
+ break;
153
+ default:
154
+ throw new Error(`Unknown tool: ${request.params.name}`);
155
+ }
156
+
157
+ const result = await executeGitHubAgentAction(action);
158
+ return {
159
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
160
+ };
161
+ } catch (error: any) {
162
+ return {
163
+ content: [{ type: 'text', text: `Error: ${error.message}` }],
164
+ isError: true,
165
+ };
166
+ }
167
+ });
168
 
169
+ export async function runMcpServer() {
 
 
 
 
 
 
 
 
 
 
 
170
  const transport = new StdioServerTransport();
171
  await server.connect(transport);
172
+ console.error('A2A-SIN-GitHub-Issues MCP Server running on stdio');
173
  }
src/metadata.ts CHANGED
@@ -2,71 +2,56 @@ import process from 'node:process';
2
 
3
  export const TEMPLATE_AGENT_ID = 'sin-github-issues';
4
  export const TEMPLATE_AGENT_NAME = 'SIN-GitHub-Issues';
5
- export const TEMPLATE_AGENT_DESCRIPTION = 'GitHub issue execution agent for confirmed bugs, repo issue lifecycle, branch-based fixes, and verification handoff.';
6
- export const TEMPLATE_AGENT_VERSION = '2026.03.09';
7
  export const TEMPLATE_AGENT_DEFAULT_HOST = '127.0.0.1';
8
  export const TEMPLATE_AGENT_DEFAULT_PORT = 46031;
9
 
10
  export const TEMPLATE_AGENT_SKILLS = [
11
  {
12
- id: 'sin.github.issues.health',
13
  name: 'Health',
14
- description: 'Check base agent readiness and identity.',
15
  },
16
  {
17
- id: 'sin.github.issues.onboarding.status',
18
- name: 'Onboarding Status',
19
- description: 'Read persisted onboarding state.',
20
  },
21
  {
22
- id: 'sin.github.issues.onboarding.save',
23
- name: 'Onboarding Save',
24
- description: 'Persist onboarding defaults for future autonomous runs.',
25
  },
26
  {
27
- id: 'sin.github.issues.auth.status',
28
- name: 'Auth Status',
29
- description: 'Report GitHub auth readiness, browser profile lane, and runtime blockers.',
30
  },
31
  {
32
- id: 'sin.github.issues.issue.ensure',
33
- name: 'Ensure Issue',
34
- description: 'Search or create the matching GitHub issue for a confirmed bug.',
35
  },
36
  {
37
- id: 'sin.github.issues.issue.comment',
38
- name: 'Issue Comment',
39
- description: 'Add RCA, progress, or verification comments to an existing GitHub issue.',
40
  },
41
  {
42
- id: 'sin.github.issues.issue.close',
43
- name: 'Close Issue',
44
- description: 'Close a GitHub issue after fix verification is complete.',
45
  },
46
  {
47
- id: 'sin.github.issues.repo.status',
48
- name: 'Repo Status',
49
- description: 'Read local repo branch and worktree status for the target fix path.',
50
  },
51
  {
52
- id: 'sin.github.issues.repo.branch.start',
53
- name: 'Start Branch',
54
- description: 'Create or reset the dedicated fix branch from the chosen base ref.',
55
- },
56
- {
57
- id: 'sin.github.issues.repo.commit',
58
- name: 'Commit Changes',
59
- description: 'Commit staged repo changes for the bug fix workflow.',
60
- },
61
- {
62
- id: 'sin.github.issues.repo.push',
63
- name: 'Push Branch',
64
- description: 'Push the fix branch to origin for downstream verification and review.',
65
- },
66
- {
67
- id: 'sin.github.issues.workflow.finalize_fix',
68
- name: 'Finalize Fix',
69
- description: 'Update the issue with root cause, fix, verification, and optional closure.',
70
  },
71
  ] as const;
72
 
 
2
 
3
  export const TEMPLATE_AGENT_ID = 'sin-github-issues';
4
  export const TEMPLATE_AGENT_NAME = 'SIN-GitHub-Issues';
5
+ export const TEMPLATE_AGENT_DESCRIPTION = 'CEO Elite GitHub Operations Architect orchestrates Projects V2, Issues, Wikis, Discussions, Gists, Security audits, PR Reviews, and public Showcase Ledger logging.';
6
+ export const TEMPLATE_AGENT_VERSION = '2026.03.22';
7
  export const TEMPLATE_AGENT_DEFAULT_HOST = '127.0.0.1';
8
  export const TEMPLATE_AGENT_DEFAULT_PORT = 46031;
9
 
10
  export const TEMPLATE_AGENT_SKILLS = [
11
  {
12
+ id: 'sin.github.health',
13
  name: 'Health',
14
+ description: 'Check 2026 Elite GitHub Operations Architect readiness, model, and capabilities.',
15
  },
16
  {
17
+ id: 'sin.github.project.orchestrate',
18
+ name: 'Project Orchestrate',
19
+ description: 'Create and manage GitHub Projects V2 boards, link issues, and assign items.',
20
  },
21
  {
22
+ id: 'sin.github.issue.manage',
23
+ name: 'Issue Manage',
24
+ description: 'Create, update, label, assign, milestone-link, or close GitHub issues and Epics.',
25
  },
26
  {
27
+ id: 'sin.github.wiki.sync',
28
+ name: 'Wiki Sync',
29
+ description: 'Synchronize repository Wiki pages with project documentation updates.',
30
  },
31
  {
32
+ id: 'sin.github.discussion.start',
33
+ name: 'Discussion Start',
34
+ description: 'Start or manage GitHub Discussions for architecture debates and design decisions.',
35
  },
36
  {
37
+ id: 'sin.github.gist.publish',
38
+ name: 'Gist Publish',
39
+ description: 'Upload long logs, code snippets, or configs to GitHub Gists and return the URL.',
40
  },
41
  {
42
+ id: 'sin.github.security.audit',
43
+ name: 'Security Audit',
44
+ description: 'Audit Dependabot alerts, configure CodeQL, and review active security advisories.',
45
  },
46
  {
47
+ id: 'sin.github.pr.review',
48
+ name: 'PR Review',
49
+ description: 'Review Pull Requests for architectural compliance, security, performance, and test coverage. Auto-approve and merge if 100% pass.',
50
  },
51
  {
52
+ id: 'sin.github.ledger.log',
53
+ name: 'Ledger Log',
54
+ description: 'Publish an agent activity log or achievement to the public Delqhi/OpenSolver-Ledger showcase repository.',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  },
56
  ] as const;
57
 
src/profile.ts ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { runCommand, runJsonCommand } from './command.js';
2
+ import { recordAuditEvent } from './audit.js';
3
+
4
+ export async function getProfile() {
5
+ const profile = await runJsonCommand<{
6
+ login: string;
7
+ id: number;
8
+ name: string | null;
9
+ company: string | null;
10
+ blog: string | null;
11
+ location: string | null;
12
+ bio: string | null;
13
+ twitter_username: string | null;
14
+ hireable: boolean | null;
15
+ public_repos: number;
16
+ followers: number;
17
+ following: number;
18
+ html_url: string;
19
+ }>('gh', ['api', 'user']);
20
+ return { ok: true, profile };
21
+ }
22
+
23
+ export async function updateProfile(input: {
24
+ name?: string;
25
+ company?: string;
26
+ blog?: string;
27
+ location?: string;
28
+ bio?: string;
29
+ twitter_username?: string;
30
+ hireable?: boolean;
31
+ }) {
32
+ const args = ['api', 'user', '--method', 'PATCH'];
33
+ if (input.name !== undefined) args.push('-f', `name=${input.name}`);
34
+ if (input.company !== undefined) args.push('-f', `company=${input.company}`);
35
+ if (input.blog !== undefined) args.push('-f', `blog=${input.blog}`);
36
+ if (input.location !== undefined) args.push('-f', `location=${input.location}`);
37
+ if (input.bio !== undefined) args.push('-f', `bio=${input.bio}`);
38
+ if (input.twitter_username !== undefined) args.push('-f', `twitter_username=${input.twitter_username}`);
39
+ if (input.hireable !== undefined) args.push('-F', `hireable=${input.hireable}`);
40
+ const result = await runJsonCommand<object>('gh', args);
41
+ await recordAuditEvent({ kind: 'profile.update', result });
42
+ return { ok: true, profile: result };
43
+ }
44
+
45
+ export async function listPinnedRepos() {
46
+ const query = `
47
+ query {
48
+ user(login: "Delqhi") {
49
+ pinnedItems(first: 6, types: REPOSITORY) {
50
+ nodes {
51
+ ... on Repository {
52
+ id
53
+ name
54
+ description
55
+ url
56
+ isFork
57
+ stargazerCount
58
+ primaryLanguage { name }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ `.replace(/\s+/g, ' ');
65
+ const response = await runJsonCommand<{ data: { user: { pinnedItems: { nodes: Array<{ id: string; name: string; description: string | null; url: string; isFork: boolean; stargazerCount: number; primaryLanguage: { name: string } | null }> } } } }>('gh', ['api', 'graphql', '-f', `query=${query}`]);
66
+ const nodes = response.data?.user?.pinnedItems?.nodes ?? [];
67
+ return { ok: true, pinned: nodes };
68
+ }
69
+
70
+ export async function setPinnedRepos(repoIds?: string[]) {
71
+ const current = await listPinnedRepos();
72
+ const existingIds = new Set(current.pinned.map((r) => r.id));
73
+ for (const existingId of existingIds) {
74
+ try {
75
+ await runCommand('gh', ['api', 'graphql', '-f', `query=mutation { unpinRepository(input: {repositoryId: "${existingId}"}) { repository { name } } }`], undefined);
76
+ } catch {}
77
+ }
78
+ const desiredIds = repoIds ?? [];
79
+ for (const repoId of desiredIds) {
80
+ await runCommand('gh', ['api', 'graphql', '-f', `query=mutation { pinRepository(input: {repositoryId: "${repoId}"}) { repository { name } } }`], undefined);
81
+ }
82
+ await recordAuditEvent({ kind: 'profile.pinned_repos.set', result: { repoIds: desiredIds } });
83
+ return { ok: true, pinned: desiredIds };
84
+ }
85
+
86
+ export async function updateRepoMetadata(input: { repo: string; description?: string; homepage?: string; topics?: string[]; visibility?: 'public' | 'private' }) {
87
+ const args = ['api', `repos/${input.repo}`, '--method', 'PATCH'];
88
+ if (input.description !== undefined) args.push('-f', `description=${input.description}`);
89
+ if (input.homepage !== undefined) args.push('-f', `homepage=${input.homepage}`);
90
+ if (input.visibility !== undefined) args.push('-f', `visibility=${input.visibility}`);
91
+ await runCommand('gh', args, undefined);
92
+ if (input.topics && input.topics.length > 0) {
93
+ const topicArgs = ['api', `repos/${input.repo}/topics`, '--method', 'PUT', '-H', 'Accept: application/vnd.github+json'];
94
+ for (const topic of input.topics) {
95
+ topicArgs.push('-F', `names[]=${topic}`);
96
+ }
97
+ await runCommand('gh', topicArgs, undefined);
98
+ }
99
+ await recordAuditEvent({ kind: 'repo.metadata.update', result: input });
100
+ return { ok: true, repo: input.repo };
101
+ }
102
+
103
+ export async function triggerQuickdraw(repo?: string) {
104
+ const target = repo ?? 'Delqhi/Delqhi';
105
+ const issue = await runJsonCommand<{ number: number; html_url: string }>('gh', ['issue', 'create', '--repo', target, '--title', 'Quickdraw profile check', '--body', 'Triggering Quickdraw achievement via issue lifecycle.']);
106
+ await runCommand('gh', ['issue', 'close', String(issue.number), '--repo', target, '--comment', 'Closed for Quickdraw verification.'], undefined);
107
+ await recordAuditEvent({ kind: 'achievement.quickdraw.trigger', result: { repo: target, issueNumber: issue.number } });
108
+ return { ok: true, repo: target, issueNumber: issue.number, issueUrl: issue.html_url };
109
+ }
110
+
111
+ export async function quickdrawStatus() {
112
+ const issues = await runJsonCommand<Array<{ number: number; state: string; closed_at: string | null }>>('gh', ['issue', 'list', '--repo', 'Delqhi/Delqhi', '--state', 'all', '--limit', '10', '--json', 'number,state,closed_at']);
113
+ const closed = issues.filter((i) => i.state === 'closed' && i.closed_at).length;
114
+ return { ok: true, totalClosed: closed, likelyQuickdraw: closed >= 1 };
115
+ }
src/runtime.ts CHANGED
@@ -1,137 +1,111 @@
1
- import { access } from 'node:fs/promises';
2
- import { constants } from 'node:fs';
3
- import { recordAuditEvent } from './audit.js';
4
- import type { GitHubIssuesAction } from './contracts.js';
5
- import { closeIssue, commentIssue, ensureIssue } from './github.js';
6
- import { commitAll, pushBranch, repoStatus, startBranch } from './git.js';
7
- import { clean, DEFAULT_STATE_PATH, readState, writeState } from './state.js';
8
 
9
- const PROFILE_EMAIL = 'zukunftsorientierte.energie@gmail.com';
10
- const PROFILE_DIRECTORY = 'Default';
11
- const DOCS_TAB_STATUS = 't.tuv2t449f8ze';
12
 
13
- export async function executeTemplateAgentAction(action: GitHubIssuesAction): Promise<unknown> {
 
 
 
 
 
 
 
 
 
 
 
 
14
  switch (action.action) {
15
  case 'agent.help':
16
- return buildHelpPayload();
17
- case 'sin.github.issues.health':
18
- return healthStatus();
19
- case 'sin.github.issues.onboarding.status':
20
- return { ok: true, statePath: DEFAULT_STATE_PATH, state: await readState() };
21
- case 'sin.github.issues.onboarding.save':
22
- if (!action.confirm) throw new Error('input_required:confirm=true required');
23
  return {
24
  ok: true,
25
- statePath: DEFAULT_STATE_PATH,
26
- state: await writeState({
27
- ownerEmail: clean(action.ownerEmail),
28
- notes: clean(action.notes),
29
- defaultRepo: clean(action.defaultRepo),
30
- browserProfileEmail: clean(action.browserProfileEmail) || PROFILE_EMAIL,
31
- browserProfileDirectory: clean(action.browserProfileDirectory) || PROFILE_DIRECTORY,
32
- updatedAt: new Date().toISOString(),
33
- }),
 
 
 
 
34
  };
35
- case 'sin.github.issues.auth.status':
36
- return authStatus();
37
- case 'sin.github.issues.issue.ensure':
38
- return withAudit('issue.ensure', ensureIssue(action));
39
- case 'sin.github.issues.issue.comment':
40
- return withAudit('issue.comment', commentIssue(action.repo, action.issueNumber, action.body));
41
- case 'sin.github.issues.issue.close':
42
- return withAudit('issue.close', closeIssue(action.repo, action.issueNumber, action.comment));
43
- case 'sin.github.issues.repo.status':
44
- return repoStatus(action.repoPath);
45
- case 'sin.github.issues.repo.branch.start':
46
- return withAudit('repo.branch.start', startBranch(action.repoPath, action.branchName, action.baseRef));
47
- case 'sin.github.issues.repo.commit':
48
- return withAudit('repo.commit', commitAll(action.repoPath, action.message));
49
- case 'sin.github.issues.repo.push':
50
- return withAudit('repo.push', pushBranch(action.repoPath, action.remote, action.branchName));
51
- case 'sin.github.issues.workflow.finalize_fix':
52
- return finalizeFix(action);
53
- }
54
- }
55
 
56
- function buildHelpPayload() {
57
- return {
58
- ok: true,
59
- agent: 'sin-github-issues',
60
- actions: [
61
- 'sin.github.issues.health',
62
- 'sin.github.issues.onboarding.status',
63
- 'sin.github.issues.onboarding.save',
64
- 'sin.github.issues.auth.status',
65
- 'sin.github.issues.issue.ensure',
66
- 'sin.github.issues.issue.comment',
67
- 'sin.github.issues.issue.close',
68
- 'sin.github.issues.repo.status',
69
- 'sin.github.issues.repo.branch.start',
70
- 'sin.github.issues.repo.commit',
71
- 'sin.github.issues.repo.push',
72
- 'sin.github.issues.workflow.finalize_fix',
73
- ],
74
- };
75
- }
76
 
77
- async function healthStatus() {
78
- return {
79
- ok: true,
80
- agent: 'sin-github-issues',
81
- primaryModel: 'opencode/nemotron-3-super-free',
82
- team: 'Team - Coding',
83
- docsTabStatus: DOCS_TAB_STATUS,
84
- browserProfileEmail: PROFILE_EMAIL,
85
- browserProfileDirectory: PROFILE_DIRECTORY,
86
- auth: await authStatus(),
87
- };
88
- }
89
 
90
- async function authStatus() {
91
- return {
92
- githubProviderInAuthenticator: false,
93
- fallbackMode: 'local gh CLI',
94
- chromeProfileEmail: PROFILE_EMAIL,
95
- chromeProfileDirectory: PROFILE_DIRECTORY,
96
- hasSupabaseEnv: Boolean(process.env.SIN_SUPABASE_URL && process.env.SIN_SUPABASE_SERVICE_ROLE_KEY),
97
- hasDatasetEnv: Boolean(process.env.HF_DATASET_REPO && process.env.HF_TOKEN),
98
- hasGhCli: await commandExists('gh'),
99
- hasGitCli: await commandExists('git'),
100
- };
101
- }
102
 
103
- async function commandExists(command: string) {
104
- try {
105
- await access(`/usr/bin/${command}`, constants.X_OK);
106
- return true;
107
- } catch {
108
- return command === 'gh' || command === 'git';
109
- }
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- async function finalizeFix(action: Extract<GitHubIssuesAction, { action: 'sin.github.issues.workflow.finalize_fix' }>) {
113
- const body = [
114
- '## Root Cause',
115
- action.rootCause,
116
- '',
117
- '## Fix',
118
- action.fix,
119
- '',
120
- '## Verification',
121
- action.verification,
122
- '',
123
- '## Affected Files',
124
- ...(action.affectedFiles?.length ? action.affectedFiles.map((file) => `- ${file}`) : ['- not specified']),
125
- ].join('\n');
126
- await commentIssue(action.repo, action.issueNumber, body);
127
- if (action.closeIssue) {
128
- await closeIssue(action.repo, action.issueNumber, 'Verified and handed off as fixed.');
129
  }
130
- return withAudit('workflow.finalize_fix', Promise.resolve({ ok: true, repo: action.repo, issueNumber: action.issueNumber }));
131
  }
132
 
133
- async function withAudit(kind: string, work: Promise<unknown>) {
134
- const result = await work;
135
- const audit = await recordAuditEvent({ kind, result });
136
- return { ok: true, result, audit };
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
 
1
+ import { exec } from 'node:child_process';
2
+ import { promisify } from 'node:util';
 
 
 
 
 
3
 
4
+ const execAsync = promisify(exec);
 
 
5
 
6
+ export type GitHubAgentAction =
7
+ | { action: 'agent.help' }
8
+ | { action: 'sin.github.health' }
9
+ | { action: 'sin.github.project.orchestrate'; prompt: string; contextDir?: string }
10
+ | { action: 'sin.github.issue.manage'; prompt: string; issueNumber?: number }
11
+ | { action: 'sin.github.wiki.sync'; prompt: string; contextDir?: string }
12
+ | { action: 'sin.github.discussion.start'; prompt: string; category?: string }
13
+ | { action: 'sin.github.gist.publish'; prompt: string; isPublic?: boolean }
14
+ | { action: 'sin.github.security.audit'; prompt: string; contextDir?: string }
15
+ | { action: 'sin.github.pr.review'; prNumber: number; contextDir?: string }
16
+ | { action: 'sin.github.ledger.log'; agentName: string; activityTitle: string; details: string };
17
+
18
+ export async function executeGitHubAgentAction(action: GitHubAgentAction): Promise<unknown> {
19
  switch (action.action) {
20
  case 'agent.help':
 
 
 
 
 
 
 
21
  return {
22
  ok: true,
23
+ agent: 'sin-github-issues',
24
+ mandate: 'CEO Elite GitHub Operations. Orchestrates Projects, Issues, Wikis, Discussions, Gists, Security, PR Reviews, and public Showcase Ledgers.',
25
+ actions: [
26
+ 'sin.github.health',
27
+ 'sin.github.project.orchestrate',
28
+ 'sin.github.issue.manage',
29
+ 'sin.github.wiki.sync',
30
+ 'sin.github.discussion.start',
31
+ 'sin.github.gist.publish',
32
+ 'sin.github.security.audit',
33
+ 'sin.github.pr.review',
34
+ 'sin.github.ledger.log'
35
+ ],
36
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ case 'sin.github.health':
39
+ return {
40
+ ok: true,
41
+ agent: 'sin-github-issues',
42
+ primaryModel: 'openai/gpt-5.4',
43
+ fallbackModel: 'opencode/minimax-m2.5-free',
44
+ team: 'Team - Coding',
45
+ status: 'Elite 2026 GitHub Operations Architect Online',
46
+ capabilities: ['projects', 'wikis', 'discussions', 'gists', 'security', 'prs', 'issues', 'ledger'],
47
+ };
 
 
 
 
 
 
 
 
 
 
48
 
49
+ case 'sin.github.project.orchestrate':
50
+ return await executeOpenCode(
51
+ `Use the GitHub CLI ('gh project create/link/item-add') to orchestrate the following project board requirements: ${action.prompt}. Ensure the board is linked to the repository and items are properly assigned.`,
52
+ action.contextDir
53
+ );
 
 
 
 
 
 
 
54
 
55
+ case 'sin.github.issue.manage':
56
+ return await executeOpenCode(
57
+ `Manage GitHub issues based on: ${action.prompt}. ${action.issueNumber ? `Target issue: #${action.issueNumber}` : 'Create a new Epic/Task.'} Ensure proper labeling, assignment, and milestone linking.`
58
+ );
 
 
 
 
 
 
 
 
59
 
60
+ case 'sin.github.wiki.sync':
61
+ return await executeOpenCode(
62
+ `Synchronize the repository's Wiki with the following documentation update: ${action.prompt}. Generate standard Markdown and push it to the wiki repository (.wiki.git).`,
63
+ action.contextDir
64
+ );
65
+
66
+ case 'sin.github.discussion.start':
67
+ return await executeOpenCode(
68
+ `Start or manage a GitHub Discussion to keep issues clean. Requirements: ${action.prompt}. Category: ${action.category || 'General'}.`
69
+ );
70
+
71
+ case 'sin.github.gist.publish':
72
+ return await executeOpenCode(
73
+ `Create a GitHub Gist (public: ${action.isPublic ?? false}) for the following payload (long log, snippet, or config): ${action.prompt}. Return the Gist URL for embedding in an issue or PR.`
74
+ );
75
+
76
+ case 'sin.github.security.audit':
77
+ return await executeOpenCode(
78
+ `Audit the repository for security vulnerabilities (Dependabot/CodeQL). Generate or update '.github/dependabot.yml' and review any active alerts based on: ${action.prompt}.`,
79
+ action.contextDir
80
+ );
81
 
82
+ case 'sin.github.pr.review':
83
+ return await executeOpenCode(
84
+ `Perform a rigorous Code Review on Pull Request #${action.prNumber}. Check for 2026 architectural compliance, security vulnerabilities, performance regressions, and test coverage. If it passes 100%, approve it ('gh pr review --approve') and merge it ('gh pr merge --auto').`,
85
+ action.contextDir
86
+ );
87
+
88
+ case 'sin.github.ledger.log':
89
+ return await executeOpenCode(
90
+ `Create a new public GitHub Issue or Discussion in the repository 'Delqhi/OpenSolver-Ledger' titled "[${action.agentName}] ${action.activityTitle}". The body must contain the following details formatted in premium markdown to showcase our fleet's capabilities: \n\n${action.details}`
91
+ );
 
 
 
 
 
 
 
92
  }
 
93
  }
94
 
95
+ async function executeOpenCode(prompt: string, dir?: string) {
96
+ await execAsync('python3 scripts/hf_pull_script.py').catch(() => console.warn('Warning: hf_pull_script failed. Proceeding with cached credentials.'));
97
+
98
+ const cmd = `opencode run "${prompt.replace(/"/g, '\\"')}" --model openai/gpt-5.4 --fallback opencode/minimax-m2.5-free`;
99
+ const options = dir ? { cwd: dir } : {};
100
+
101
+ try {
102
+ const { stdout, stderr } = await execAsync(cmd, options);
103
+ return {
104
+ ok: true,
105
+ expertAnalysis: stdout,
106
+ warnings: stderr || undefined,
107
+ };
108
+ } catch (error: any) {
109
+ throw new Error(`GitHub Operations Execution Failed: ${error.message}`);
110
+ }
111
  }
src/supabase.ts CHANGED
@@ -10,14 +10,14 @@ export function getSupabaseClient(): SupabaseClient {
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
- console.warn('[SIN-Supabase] Warning: SIN_SUPABASE_URL or SIN_SUPABASE_SERVICE_ROLE_KEY is missing. DB coupling is inactive.');
18
  return createClient(supabaseUrl || 'https://dummy.supabase.co', supabaseKey || 'dummy');
19
  }
20
 
21
  supabaseInstance = createClient(supabaseUrl, supabaseKey);
22
  return supabaseInstance;
23
- }
 
10
  return supabaseInstance;
11
  }
12
 
13
+ const supabaseUrl = process.env.SUPABASE_URL || process.env.SIN_SUPABASE_URL;
14
+ const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SIN_SUPABASE_SERVICE_ROLE_KEY;
15
 
16
  if (!supabaseUrl || !supabaseKey) {
17
+ console.warn('[SIN-Supabase] Warning: SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY is missing. DB coupling is inactive.');
18
  return createClient(supabaseUrl || 'https://dummy.supabase.co', supabaseKey || 'dummy');
19
  }
20
 
21
  supabaseInstance = createClient(supabaseUrl, supabaseKey);
22
  return supabaseInstance;
23
+ }
src/workflows.ts ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { runCommand, runJsonCommand } from './command.js';
4
+
5
+ const execFileAsync = promisify(execFile);
6
+
7
+ type WorkflowRunApi = {
8
+ id: number;
9
+ name?: string;
10
+ display_title?: string;
11
+ event?: string;
12
+ head_branch?: string;
13
+ head_sha?: string;
14
+ status?: string;
15
+ conclusion?: string | null;
16
+ html_url?: string;
17
+ created_at?: string;
18
+ updated_at?: string;
19
+ };
20
+
21
+ type WorkflowRunsResponse = {
22
+ workflow_runs?: WorkflowRunApi[];
23
+ };
24
+
25
+ type RunnerApi = {
26
+ id: number;
27
+ name: string;
28
+ os: string;
29
+ status: string;
30
+ busy: boolean;
31
+ labels?: Array<{ name: string }>;
32
+ };
33
+
34
+ type RunnersResponse = {
35
+ total_count?: number;
36
+ runners?: RunnerApi[];
37
+ };
38
+
39
+ const SUITE_COMMANDS: Record<string, string> = {
40
+ 'docs-and-architecture': 'npm ci && npm run test:docs:root && npm run test:contracts:active && npm run test:dashboard:boundary && npm run test:guardrails && npm run test:cycles',
41
+ 'python-unit-311': "python3.11 -m venv .venv311 && . .venv311/bin/activate && python -m pip install --upgrade pip && python -m pip install -r requirements.txt -r requirements.runtime.txt && python -m pip install -e '.[dev]' && pytest tests/unit -q",
42
+ 'dashboard-quality': 'npm --prefix dashboard-enterprise ci && npm --prefix dashboard-enterprise run lint && npm --prefix dashboard-enterprise run type-check && npm run ops:dashboard:build:ci && npm run ops:dashboard:interaction-smoke:ci',
43
+ };
44
+
45
+ export async function listWorkflowRuns(input: {
46
+ repo: string;
47
+ branch?: string;
48
+ event?: string;
49
+ status?: string;
50
+ limit?: number;
51
+ }) {
52
+ const params = new URLSearchParams();
53
+ params.set('per_page', String(Math.max(1, Math.min(input.limit || 20, 100))));
54
+ if (input.branch) params.set('branch', input.branch);
55
+ if (input.event) params.set('event', input.event);
56
+ if (input.status) params.set('status', input.status);
57
+ const suffix = params.toString() ? `?${params.toString()}` : '';
58
+ const payload = await runJsonCommand<WorkflowRunsResponse>('gh', ['api', `repos/${input.repo}/actions/runs${suffix}`]);
59
+ return {
60
+ ok: true,
61
+ repo: input.repo,
62
+ runs: (payload.workflow_runs || []).map((row) => ({
63
+ id: row.id,
64
+ workflowName: row.name || null,
65
+ title: row.display_title || null,
66
+ event: row.event || null,
67
+ branch: row.head_branch || null,
68
+ sha: row.head_sha || null,
69
+ status: row.status || null,
70
+ conclusion: row.conclusion || null,
71
+ url: row.html_url || null,
72
+ createdAt: row.created_at || null,
73
+ updatedAt: row.updated_at || null,
74
+ })),
75
+ };
76
+ }
77
+
78
+ export async function rerunWorkflowRun(repo: string, runId: number) {
79
+ await runCommand('gh', ['run', 'rerun', String(runId), '--repo', repo]);
80
+ return { ok: true, repo, runId };
81
+ }
82
+
83
+ export async function cancelWorkflowRun(repo: string, runId: number) {
84
+ await runCommand('gh', ['run', 'cancel', String(runId), '--repo', repo]);
85
+ return { ok: true, repo, runId };
86
+ }
87
+
88
+ export async function listRunners(repo: string) {
89
+ const payload = await runJsonCommand<RunnersResponse>('gh', ['api', `repos/${repo}/actions/runners`]);
90
+ return {
91
+ ok: true,
92
+ repo,
93
+ totalCount: payload.total_count || 0,
94
+ runners: (payload.runners || []).map((row) => ({
95
+ id: row.id,
96
+ name: row.name,
97
+ os: row.os,
98
+ status: row.status,
99
+ busy: row.busy,
100
+ labels: (row.labels || []).map((label) => label.name),
101
+ })),
102
+ };
103
+ }
104
+
105
+ export async function runLocalSuite(input: {
106
+ repoPath: string;
107
+ suite: 'docs-and-architecture' | 'python-unit-311' | 'dashboard-quality';
108
+ timeoutMs?: number;
109
+ }) {
110
+ const command = SUITE_COMMANDS[input.suite];
111
+ if (!command) {
112
+ throw new Error(`unknown_ci_suite:${input.suite}`);
113
+ }
114
+ const startedAt = new Date().toISOString();
115
+ const timeout = Math.max(60_000, Math.min(input.timeoutMs || 900_000, 3_600_000));
116
+ try {
117
+ const result = await execFileAsync('/bin/bash', ['-lc', command], {
118
+ cwd: input.repoPath,
119
+ env: process.env,
120
+ maxBuffer: 1024 * 1024 * 16,
121
+ timeout,
122
+ });
123
+ return {
124
+ ok: true,
125
+ suite: input.suite,
126
+ startedAt,
127
+ finishedAt: new Date().toISOString(),
128
+ stdout: String(result.stdout || '').trim(),
129
+ stderr: String(result.stderr || '').trim(),
130
+ };
131
+ } catch (error) {
132
+ const failure = error as { stdout?: string; stderr?: string; message?: string; signal?: string; code?: number };
133
+ return {
134
+ ok: false,
135
+ suite: input.suite,
136
+ startedAt,
137
+ finishedAt: new Date().toISOString(),
138
+ stdout: String(failure.stdout || '').trim(),
139
+ stderr: String(failure.stderr || '').trim(),
140
+ signal: failure.signal || null,
141
+ code: typeof failure.code === 'number' ? failure.code : null,
142
+ error: String(failure.message || 'local_suite_failed'),
143
+ };
144
+ }
145
+ }