heron-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +423 -0
- package/dist/bin/heron.d.ts +3 -0
- package/dist/bin/heron.d.ts.map +1 -0
- package/dist/bin/heron.js +198 -0
- package/dist/bin/heron.js.map +1 -0
- package/dist/src/analysis/analyzer.d.ts +14 -0
- package/dist/src/analysis/analyzer.d.ts.map +1 -0
- package/dist/src/analysis/analyzer.js +130 -0
- package/dist/src/analysis/analyzer.js.map +1 -0
- package/dist/src/analysis/risk-scorer.d.ts +20 -0
- package/dist/src/analysis/risk-scorer.d.ts.map +1 -0
- package/dist/src/analysis/risk-scorer.js +143 -0
- package/dist/src/analysis/risk-scorer.js.map +1 -0
- package/dist/src/config/loader.d.ts +15 -0
- package/dist/src/config/loader.d.ts.map +1 -0
- package/dist/src/config/loader.js +39 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/schema.d.ts +146 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +27 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/connectors/http-connector.d.ts +17 -0
- package/dist/src/connectors/http-connector.d.ts.map +1 -0
- package/dist/src/connectors/http-connector.js +56 -0
- package/dist/src/connectors/http-connector.js.map +1 -0
- package/dist/src/connectors/index.d.ts +5 -0
- package/dist/src/connectors/index.d.ts.map +1 -0
- package/dist/src/connectors/index.js +13 -0
- package/dist/src/connectors/index.js.map +1 -0
- package/dist/src/connectors/interactive-connector.d.ts +13 -0
- package/dist/src/connectors/interactive-connector.d.ts.map +1 -0
- package/dist/src/connectors/interactive-connector.js +44 -0
- package/dist/src/connectors/interactive-connector.js.map +1 -0
- package/dist/src/connectors/types.d.ts +15 -0
- package/dist/src/connectors/types.d.ts.map +1 -0
- package/dist/src/connectors/types.js +2 -0
- package/dist/src/connectors/types.js.map +1 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +60 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interview/interviewer.d.ts +19 -0
- package/dist/src/interview/interviewer.d.ts.map +1 -0
- package/dist/src/interview/interviewer.js +68 -0
- package/dist/src/interview/interviewer.js.map +1 -0
- package/dist/src/interview/protocol.d.ts +38 -0
- package/dist/src/interview/protocol.d.ts.map +1 -0
- package/dist/src/interview/protocol.js +290 -0
- package/dist/src/interview/protocol.js.map +1 -0
- package/dist/src/interview/questions.d.ts +20 -0
- package/dist/src/interview/questions.d.ts.map +1 -0
- package/dist/src/interview/questions.js +131 -0
- package/dist/src/interview/questions.js.map +1 -0
- package/dist/src/llm/client.d.ts +13 -0
- package/dist/src/llm/client.d.ts.map +1 -0
- package/dist/src/llm/client.js +128 -0
- package/dist/src/llm/client.js.map +1 -0
- package/dist/src/llm/prompts.d.ts +13 -0
- package/dist/src/llm/prompts.d.ts.map +1 -0
- package/dist/src/llm/prompts.js +192 -0
- package/dist/src/llm/prompts.js.map +1 -0
- package/dist/src/report/generator.d.ts +23 -0
- package/dist/src/report/generator.d.ts.map +1 -0
- package/dist/src/report/generator.js +304 -0
- package/dist/src/report/generator.js.map +1 -0
- package/dist/src/report/templates.d.ts +3 -0
- package/dist/src/report/templates.d.ts.map +1 -0
- package/dist/src/report/templates.js +386 -0
- package/dist/src/report/templates.js.map +1 -0
- package/dist/src/report/types.d.ts +954 -0
- package/dist/src/report/types.d.ts.map +1 -0
- package/dist/src/report/types.js +161 -0
- package/dist/src/report/types.js.map +1 -0
- package/dist/src/server/index.d.ts +17 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +650 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/sessions.d.ts +68 -0
- package/dist/src/server/sessions.d.ts.map +1 -0
- package/dist/src/server/sessions.js +268 -0
- package/dist/src/server/sessions.js.map +1 -0
- package/dist/src/util/id.d.ts +2 -0
- package/dist/src/util/id.d.ts.map +1 -0
- package/dist/src/util/id.js +5 -0
- package/dist/src/util/id.js.map +1 -0
- package/dist/src/util/logger.d.ts +9 -0
- package/dist/src/util/logger.d.ts.map +1 -0
- package/dist/src/util/logger.js +32 -0
- package/dist/src/util/logger.js.map +1 -0
- package/heron.example.yaml +46 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Heron Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/heron-logo.svg" alt="Heron" width="80" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Heron</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Open-source AI agent auditor</strong><br />
|
|
9
|
+
Know what your AI agents actually access before they go to production.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="#quick-start">Quick Start</a> •
|
|
14
|
+
<a href="#how-it-works">How It Works</a> •
|
|
15
|
+
<a href="#example-report">Example Report</a> •
|
|
16
|
+
<a href="#use-cases">Use Cases</a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
> You wouldn't give a contractor the keys to your office without checking their ID.
|
|
22
|
+
> Why give an AI agent production access without an audit?
|
|
23
|
+
|
|
24
|
+
## Why Heron?
|
|
25
|
+
|
|
26
|
+
AI agents are requesting access to production systems — CRMs, databases, APIs, internal tools. Before granting access, someone needs to answer:
|
|
27
|
+
|
|
28
|
+
- **What** does this agent actually do in this specific project?
|
|
29
|
+
- **What data** does it handle — and does it need write access?
|
|
30
|
+
- **What happens** if something goes wrong?
|
|
31
|
+
|
|
32
|
+
Today these questions are answered in Slack threads, docs, or not at all.
|
|
33
|
+
|
|
34
|
+
**Heron answers them automatically.** Point agents at it, get a structured audit report. No SDK integration, no code changes to the agent.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
┌──────────┐ ┌──────────────┐ ┌──────────────┐
|
|
38
|
+
│ │ │ │ │ │
|
|
39
|
+
│ Agent │────────>│ Heron │────────>│ Audit Report │
|
|
40
|
+
│ │ │ │ │ │
|
|
41
|
+
│ │<────────│ Structured │ │ Findings │
|
|
42
|
+
└──────────┘ │ Interview │ │ Systems │
|
|
43
|
+
│ (10 core + │ │ Regulatory │
|
|
44
|
+
│ follow-ups) │ │ Verdict │
|
|
45
|
+
└──────────────┘ └──────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### Option 1: Interactive CLI
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/jonydony/Heron.git
|
|
54
|
+
cd Heron && npm install
|
|
55
|
+
|
|
56
|
+
export HERON_LLM_API_KEY=sk-xxx # Anthropic, OpenAI, or Gemini key — auto-detected
|
|
57
|
+
|
|
58
|
+
npx tsx bin/heron.ts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
An interactive menu lets you choose:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Heron — AI Agent Auditor
|
|
65
|
+
|
|
66
|
+
> Start server agents connect to you
|
|
67
|
+
Scan an agent you connect to an agent
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Option 2: Use the hosted version
|
|
71
|
+
|
|
72
|
+
Paste this into your AI agent's chat:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
I need you to complete a security access review for this project.
|
|
76
|
+
Make sequential API calls to the Heron endpoint until it says "Interview complete".
|
|
77
|
+
|
|
78
|
+
Step 1 — Start the interview:
|
|
79
|
+
POST https://heron-open-source-production.up.railway.app/v1/chat/completions
|
|
80
|
+
Body: {"model":"any","messages":[{"role":"user","content":"Hi, I am ready to answer questions about this project."}]}
|
|
81
|
+
|
|
82
|
+
The response will contain a question and a session ID (in the text and in the "heron_session_id" JSON field).
|
|
83
|
+
|
|
84
|
+
Step 2 — Send each answer:
|
|
85
|
+
POST https://heron-open-source-production.up.railway.app/v1/chat/completions
|
|
86
|
+
Body: {"model":"any","messages":[{"role":"user","content":"YOUR ANSWER HERE"}],"heron_session_id":"SESSION_ID_FROM_STEP_1"}
|
|
87
|
+
|
|
88
|
+
Step 3 — Repeat step 2 with each new answer until the response says "Interview complete".
|
|
89
|
+
|
|
90
|
+
Important: answer about THIS specific project — what you actually do, what systems
|
|
91
|
+
you connect to, what data you handle. Not general capabilities. Never reveal actual
|
|
92
|
+
secret values — just describe credential types.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
View reports at: https://heron-open-source-production.up.railway.app
|
|
96
|
+
|
|
97
|
+
### Option 3: OPENAI_BASE_URL
|
|
98
|
+
|
|
99
|
+
Redirect any OpenAI-compatible agent to Heron without changing the agent's code:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
OPENAI_BASE_URL=http://localhost:3700/v1 python your_agent.py
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The agent thinks it's talking to GPT. Heron intercepts, runs the interview, generates a report.
|
|
106
|
+
|
|
107
|
+
### Option 4: Claude Code skill (zero setup)
|
|
108
|
+
|
|
109
|
+
If you use [Claude Code](https://claude.ai/code), install the `/heron-audit` skill:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
bash Heron/skills/heron-audit/install.sh
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Then in any project:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
/heron-audit
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Claude interviews itself about the current project and generates an audit report.
|
|
122
|
+
|
|
123
|
+
## How It Works
|
|
124
|
+
|
|
125
|
+
<table>
|
|
126
|
+
<tr>
|
|
127
|
+
<td width="50%">
|
|
128
|
+
|
|
129
|
+
**Step 1 — Start Heron**
|
|
130
|
+
|
|
131
|
+
One command. Interactive menu or direct flags.
|
|
132
|
+
|
|
133
|
+
</td>
|
|
134
|
+
<td width="50%">
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
$ npx tsx bin/heron.ts
|
|
138
|
+
|
|
139
|
+
Heron — AI Agent Auditor
|
|
140
|
+
|
|
141
|
+
> Start server agents connect to you
|
|
142
|
+
Scan an agent you connect to an agent
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
</td>
|
|
146
|
+
</tr>
|
|
147
|
+
<tr>
|
|
148
|
+
<td>
|
|
149
|
+
|
|
150
|
+
**Step 2 — Agent connects**
|
|
151
|
+
|
|
152
|
+
Heron speaks OpenAI-compatible API. No SDK, no code changes needed.
|
|
153
|
+
|
|
154
|
+
</td>
|
|
155
|
+
<td>
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Paste the prompt into agent's chat
|
|
159
|
+
# Or redirect the base URL:
|
|
160
|
+
OPENAI_BASE_URL=http://localhost:3700/v1 \
|
|
161
|
+
your-agent start
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
</td>
|
|
165
|
+
</tr>
|
|
166
|
+
<tr>
|
|
167
|
+
<td>
|
|
168
|
+
|
|
169
|
+
**Step 3 — Structured interview**
|
|
170
|
+
|
|
171
|
+
10 core questions, each targeting a compliance field. Smart follow-ups probe vague answers. Format examples guide the agent to give concrete, structured responses.
|
|
172
|
+
|
|
173
|
+
</td>
|
|
174
|
+
<td>
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
Heron: "List every system you connect to.
|
|
178
|
+
Format: Name → API type → Auth method
|
|
179
|
+
Example: Google Sheets → REST API → OAuth2"
|
|
180
|
+
|
|
181
|
+
Agent: "HubSpot → REST API → OAuth2
|
|
182
|
+
PostgreSQL → Direct TCP → Password
|
|
183
|
+
Slack → Bot API → Bot token"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
</td>
|
|
187
|
+
</tr>
|
|
188
|
+
<tr>
|
|
189
|
+
<td>
|
|
190
|
+
|
|
191
|
+
**Step 4 — Report generated**
|
|
192
|
+
|
|
193
|
+
Per-system access cards, findings with IDs, risk scoring, regulatory flags, and actionable recommendations.
|
|
194
|
+
|
|
195
|
+
</td>
|
|
196
|
+
<td>
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
Audit complete: sess_abc123
|
|
200
|
+
Risk: MEDIUM
|
|
201
|
+
Data quality: 100/100
|
|
202
|
+
Verdict: APPROVE WITH CONDITIONS
|
|
203
|
+
Findings: 4
|
|
204
|
+
Report: ./reports/sess_abc123.md
|
|
205
|
+
Dashboard: http://localhost:3700/sessions/sess_abc123
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
</td>
|
|
209
|
+
</tr>
|
|
210
|
+
</table>
|
|
211
|
+
|
|
212
|
+
### Interview Protocol
|
|
213
|
+
|
|
214
|
+
10 structured questions targeting compliance fields, plus LLM-generated follow-ups:
|
|
215
|
+
|
|
216
|
+
| # | Question | Compliance Field |
|
|
217
|
+
|---|----------|-----------------|
|
|
218
|
+
| 1 | Deployment profile (project name, owner, trigger) | Agent identity |
|
|
219
|
+
| 2 | Permissions and scopes per system | `scopesRequested` |
|
|
220
|
+
| 3 | Systems enumeration (Name → API → Auth) | `systemId` |
|
|
221
|
+
| 4 | Data sensitivity per system (PII/financial/confidential) | `dataSensitivity` |
|
|
222
|
+
| 5 | Detailed permissions | Access assessment |
|
|
223
|
+
| 6 | Data read operations and classification | Data inventory |
|
|
224
|
+
| 7 | Reversibility of operations | `reversibility` |
|
|
225
|
+
| 8 | Write operations (Action → Target → Reversible? → Volume) | `writeOperations` |
|
|
226
|
+
| 9 | Blast radius (records/users affected if write fails) | `blastRadius` |
|
|
227
|
+
| 10 | Frequency and volume (runs/week, API calls/run) | `frequencyAndVolume` |
|
|
228
|
+
| + | Unused permissions, worst-case failure, decision-making about people | Excess access, risk, regulatory |
|
|
229
|
+
|
|
230
|
+
Follow-ups are generated when answers are vague or compliance fields are missing (up to 6 per interview).
|
|
231
|
+
|
|
232
|
+
### Report Structure
|
|
233
|
+
|
|
234
|
+
1. **Executive Summary** — dashboard table (risk / systems / findings)
|
|
235
|
+
2. **Agent Profile** — purpose, trigger, owner, frequency
|
|
236
|
+
3. **Findings** — severity-ranked with IDs (HERON-001, ...), split description and recommendation
|
|
237
|
+
4. **Systems & Access** — per-system cards with risk rating, scopes, data, writes, blast radius
|
|
238
|
+
5. **What's Working Well** — positive findings
|
|
239
|
+
6. **Verdict & Recommendations** — APPROVE / APPROVE WITH CONDITIONS / DENY
|
|
240
|
+
7. **Regulatory Compliance** — EU (AI Act + GDPR), US (SOC 2 + state AI laws), UK (UK GDPR + ICO)
|
|
241
|
+
8. **Data Quality** — field-by-field coverage score, repeated answer warnings
|
|
242
|
+
9. **Interview Transcript** — full Q&A for manual review
|
|
243
|
+
|
|
244
|
+
## Example Report
|
|
245
|
+
|
|
246
|
+
<details>
|
|
247
|
+
<summary>Expand example: CRM sync agent audit</summary>
|
|
248
|
+
|
|
249
|
+
```markdown
|
|
250
|
+
# Agent Access Audit Report
|
|
251
|
+
|
|
252
|
+
**Generated**: 2026-04-05 | **Agent**: SalesSync | **Risk Level**: HIGH
|
|
253
|
+
**Data Quality**: 83/100
|
|
254
|
+
**Regulatory**: EU: Review | US: Review | UK: Review
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Executive Summary
|
|
259
|
+
|
|
260
|
+
| Risk | Systems | Findings |
|
|
261
|
+
|------|---------|----------|
|
|
262
|
+
| **HIGH** | 3 | 1 Critical, 1 High, 2 Medium |
|
|
263
|
+
|
|
264
|
+
SalesSync syncs contact and deal data between HubSpot CRM and an internal
|
|
265
|
+
PostgreSQL database, and sends Slack notifications on deal stage changes.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Findings
|
|
270
|
+
|
|
271
|
+
| ID | Severity | Finding | Description | Recommendation |
|
|
272
|
+
|----|----------|---------|-------------|----------------|
|
|
273
|
+
| HERON-001 | CRITICAL | Bulk update risk | Can overwrite all ~15,000 contacts | Add validation + staged rollout |
|
|
274
|
+
| HERON-002 | HIGH | Sensitive data writable | PII + financial in PostgreSQL | Restrict to needed columns |
|
|
275
|
+
| HERON-003 | MEDIUM | Excessive HubSpot scope | deals.write granted but unused | Revoke unused scope |
|
|
276
|
+
| HERON-004 | MEDIUM | Irreversible Slack messages | Deal notifications can't be recalled | Add pre-send validation |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Systems & Access
|
|
281
|
+
|
|
282
|
+
### HubSpot CRM → REST API → OAuth2 — Risk: HIGH
|
|
283
|
+
|
|
284
|
+
| | |
|
|
285
|
+
|---|---|
|
|
286
|
+
| **Scopes granted** | contacts.read, contacts.write, deals.read, deals.write |
|
|
287
|
+
| **Excessive** | deals.write (never used) |
|
|
288
|
+
| **Data** | PII + financial |
|
|
289
|
+
| **Blast radius** | org-wide (~15,000 records) |
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Verdict: APPROVE WITH CONDITIONS
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
</details>
|
|
297
|
+
|
|
298
|
+
## Use Cases
|
|
299
|
+
|
|
300
|
+
**Security team: "vet before you deploy"** — Deploy Heron as a gate. Agents must pass an audit before getting production access. Review structured reports with findings, risk levels, and recommendations.
|
|
301
|
+
|
|
302
|
+
**Team lead: "what does this agent actually do?"** — Paste the prompt into the agent's chat. Get a clear breakdown of systems, data, permissions, and blast radius.
|
|
303
|
+
|
|
304
|
+
**Compliance: "prove your agents are controlled"** — Heron generates audit-ready reports with regulatory flags for EU AI Act, GDPR, SOC 2, and UK GDPR. Attach to compliance evidence packages.
|
|
305
|
+
|
|
306
|
+
## Two Modes
|
|
307
|
+
|
|
308
|
+
| Mode | Command | Direction | Use Case |
|
|
309
|
+
|------|---------|-----------|----------|
|
|
310
|
+
| **Server** | `serve` | Agent → Heron | Deploy as a gate. Agents connect to Heron |
|
|
311
|
+
| **Scan** | `scan` | Heron → Agent | Connect to an agent's API and interrogate it |
|
|
312
|
+
|
|
313
|
+
## LLM Provider
|
|
314
|
+
|
|
315
|
+
Heron auto-detects the provider from your API key:
|
|
316
|
+
|
|
317
|
+
| Key prefix | Provider | Default model |
|
|
318
|
+
|------------|----------|---------------|
|
|
319
|
+
| `sk-ant-` | Anthropic | claude-sonnet-4 |
|
|
320
|
+
| `sk-` | OpenAI | gpt-5.4-mini |
|
|
321
|
+
| `AIza` | Gemini | gemini-2.0-flash |
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
export HERON_LLM_API_KEY=sk-xxx # that's it — provider and model auto-selected
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Override with `--llm-provider` and `--llm-model` if needed.
|
|
328
|
+
|
|
329
|
+
## Reference
|
|
330
|
+
|
|
331
|
+
<details>
|
|
332
|
+
<summary>Server Mode — <code>heron serve</code></summary>
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
npx tsx bin/heron.ts serve [options]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
| Flag | Description | Default |
|
|
339
|
+
|------|-------------|---------|
|
|
340
|
+
| `-p, --port <port>` | Port to listen on | `3700` |
|
|
341
|
+
| `-H, --host <host>` | Host to bind to | `0.0.0.0` |
|
|
342
|
+
| `--llm-key <key>` | LLM API key | `HERON_LLM_API_KEY` env |
|
|
343
|
+
| `--llm-provider <p>` | `anthropic`, `openai`, or `gemini` | auto-detect |
|
|
344
|
+
| `--llm-model <model>` | Analysis LLM model | auto per provider |
|
|
345
|
+
| `--max-followups <n>` | Max follow-up questions | `3` |
|
|
346
|
+
| `--report-dir <dir>` | Where to save reports | `./reports` |
|
|
347
|
+
|
|
348
|
+
**API Endpoints**
|
|
349
|
+
|
|
350
|
+
| Endpoint | Method | Description |
|
|
351
|
+
|----------|--------|-------------|
|
|
352
|
+
| `/v1/chat/completions` | POST | OpenAI-compatible — agents connect here |
|
|
353
|
+
| `/api/sessions` | GET | List all sessions (JSON) |
|
|
354
|
+
| `/api/sessions/:id` | GET | Session details + transcript |
|
|
355
|
+
| `/api/sessions/:id/report` | GET | Download audit report (markdown) |
|
|
356
|
+
| `/` | GET | Dashboard |
|
|
357
|
+
|
|
358
|
+
</details>
|
|
359
|
+
|
|
360
|
+
<details>
|
|
361
|
+
<summary>Scan Mode — <code>heron scan</code></summary>
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
npx tsx bin/heron.ts scan [options]
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
| Flag | Description | Default |
|
|
368
|
+
|------|-------------|---------|
|
|
369
|
+
| `-t, --target <url>` | Agent's chat API URL | required |
|
|
370
|
+
| `--llm-key <key>` | LLM API key | `HERON_LLM_API_KEY` env |
|
|
371
|
+
| `--llm-provider <p>` | `anthropic`, `openai`, or `gemini` | auto-detect |
|
|
372
|
+
| `--llm-model <model>` | Analysis LLM model | auto per provider |
|
|
373
|
+
| `-o, --output <path>` | Save report to file | `./reports/scan_xxx.md` |
|
|
374
|
+
| `--max-followups <n>` | Max follow-up questions | `3` |
|
|
375
|
+
| `--report-dir <dir>` | Where to save reports | `./reports` |
|
|
376
|
+
|
|
377
|
+
</details>
|
|
378
|
+
|
|
379
|
+
## Architecture
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
bin/heron.ts CLI entry point (interactive menu, scan, serve)
|
|
383
|
+
src/
|
|
384
|
+
server/
|
|
385
|
+
index.ts HTTP server + dashboard + OpenAI-compatible endpoint
|
|
386
|
+
sessions.ts Session manager with follow-ups and async analysis
|
|
387
|
+
interview/
|
|
388
|
+
questions.ts 10 structured questions (one per compliance field)
|
|
389
|
+
protocol.ts Interview flow: greeting skip, repeat detection, follow-ups
|
|
390
|
+
analysis/
|
|
391
|
+
analyzer.ts LLM transcript analysis with Zod validation + retry + fallback
|
|
392
|
+
risk-scorer.ts Rubric-driven risk scoring from structured per-system data
|
|
393
|
+
report/
|
|
394
|
+
generator.ts Regulatory compliance flags (EU/US/UK) + report assembly
|
|
395
|
+
templates.ts Markdown report: per-system cards, findings, positive findings
|
|
396
|
+
types.ts Zod schemas for SystemAssessment, AuditReport, RegulatoryFlags
|
|
397
|
+
llm/
|
|
398
|
+
client.ts Unified LLM client (Anthropic/OpenAI/Gemini, auto-detect)
|
|
399
|
+
prompts.ts Interview + analysis prompts with anti-hallucination rules
|
|
400
|
+
connectors/ Agent connection (HTTP, interactive)
|
|
401
|
+
config/ YAML config loading + Zod validation
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## Development
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
git clone https://github.com/jonydony/Heron.git
|
|
408
|
+
cd Heron && npm install
|
|
409
|
+
|
|
410
|
+
# Run locally
|
|
411
|
+
HERON_LLM_API_KEY=sk-xxx npx tsx bin/heron.ts serve
|
|
412
|
+
|
|
413
|
+
# Tests
|
|
414
|
+
npm test
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Contributing
|
|
418
|
+
|
|
419
|
+
Issues and PRs welcome.
|
|
420
|
+
|
|
421
|
+
## License
|
|
422
|
+
|
|
423
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heron.d.ts","sourceRoot":"","sources":["../../bin/heron.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { loadConfigFromFlags } from '../src/config/loader.js';
|
|
4
|
+
import { run } from '../src/index.js';
|
|
5
|
+
import { startServer } from '../src/server/index.js';
|
|
6
|
+
import * as logger from '../src/util/logger.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('heron')
|
|
10
|
+
.description('Open-source agent checkpoint — vet AI agents before granting production access')
|
|
11
|
+
.version('0.1.0');
|
|
12
|
+
// ─── scan: active mode (Heron → Agent) ───────────────────────────────────
|
|
13
|
+
program
|
|
14
|
+
.command('scan')
|
|
15
|
+
.description('Interrogate an agent by connecting to its API')
|
|
16
|
+
.option('-t, --target <url>', 'Target agent URL (OpenAI-compatible chat API)')
|
|
17
|
+
.option('--target-type <type>', 'Connection type: http or interactive', 'http')
|
|
18
|
+
.option('--llm-provider <provider>', 'LLM provider: anthropic, openai, or gemini (auto-detected from key)')
|
|
19
|
+
.option('--llm-model <model>', 'LLM model (auto-selected per provider)')
|
|
20
|
+
.option('--llm-key <key>', 'LLM API key (or set HERON_LLM_API_KEY)')
|
|
21
|
+
.option('-o, --output <path>', 'Save report to file (default: stdout)')
|
|
22
|
+
.option('-f, --format <format>', 'Output format: markdown or json', 'markdown')
|
|
23
|
+
.option('-c, --config <path>', 'Path to heron.yaml config file')
|
|
24
|
+
.option('--max-followups <n>', 'Max follow-up questions per category', '3')
|
|
25
|
+
.option('--report-dir <dir>', 'Directory to save reports', './reports')
|
|
26
|
+
.option('-v, --verbose', 'Show detailed interview progress')
|
|
27
|
+
.action(async (opts) => {
|
|
28
|
+
try {
|
|
29
|
+
if (!opts.target && !opts.config && opts.targetType !== 'interactive') {
|
|
30
|
+
console.error('Either --target <url>, --config <path>, or --target-type interactive is required');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const config = loadConfigFromFlags({
|
|
34
|
+
target: opts.target,
|
|
35
|
+
targetType: opts.targetType,
|
|
36
|
+
llmProvider: opts.llmProvider,
|
|
37
|
+
llmModel: opts.llmModel,
|
|
38
|
+
llmKey: opts.llmKey,
|
|
39
|
+
output: opts.output,
|
|
40
|
+
format: opts.format,
|
|
41
|
+
config: opts.config,
|
|
42
|
+
});
|
|
43
|
+
await run(config, {
|
|
44
|
+
verbose: opts.verbose ?? false,
|
|
45
|
+
maxFollowUps: parseInt(opts.maxFollowups ?? '3', 10),
|
|
46
|
+
reportDir: opts.reportDir,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// ─── serve: passive mode (Agent → Heron) ─────────────────────────────────
|
|
55
|
+
program
|
|
56
|
+
.command('serve')
|
|
57
|
+
.description('Start Heron server — agents connect to be interrogated')
|
|
58
|
+
.option('-p, --port <port>', 'Port to listen on', '3700')
|
|
59
|
+
.option('-H, --host <host>', 'Host to bind to', '0.0.0.0')
|
|
60
|
+
.option('--llm-provider <provider>', 'LLM provider: anthropic, openai, or gemini (auto-detected from key)')
|
|
61
|
+
.option('--llm-model <model>', 'LLM model (auto-selected per provider)')
|
|
62
|
+
.option('--llm-key <key>', 'LLM API key (or set HERON_LLM_API_KEY)')
|
|
63
|
+
.option('--max-followups <n>', 'Max follow-up questions per category', '3')
|
|
64
|
+
.option('--report-dir <dir>', 'Directory to save reports', './reports')
|
|
65
|
+
.action(async (opts) => {
|
|
66
|
+
try {
|
|
67
|
+
await startServer({
|
|
68
|
+
port: parseInt(opts.port, 10),
|
|
69
|
+
host: opts.host,
|
|
70
|
+
llm: {
|
|
71
|
+
provider: opts.llmProvider,
|
|
72
|
+
apiKey: opts.llmKey,
|
|
73
|
+
model: opts.llmModel,
|
|
74
|
+
},
|
|
75
|
+
maxFollowUps: parseInt(opts.maxFollowups ?? '3', 10),
|
|
76
|
+
reportDir: opts.reportDir,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// ─── Interactive mode: no args → ask what to do ─────────────────────────────
|
|
85
|
+
import { createInterface } from 'node:readline';
|
|
86
|
+
/** Arrow-key selector like Claude Code / npm init */
|
|
87
|
+
function selectPrompt(title, options) {
|
|
88
|
+
return new Promise(resolve => {
|
|
89
|
+
let selected = 0;
|
|
90
|
+
const out = process.stderr;
|
|
91
|
+
function render() {
|
|
92
|
+
// Move cursor up to redraw (after first render)
|
|
93
|
+
for (const [i, opt] of options.entries()) {
|
|
94
|
+
const indicator = i === selected ? '\x1b[36m❯\x1b[0m' : ' ';
|
|
95
|
+
const label = i === selected ? `\x1b[1m${opt.label}\x1b[0m` : `\x1b[2m${opt.label}\x1b[0m`;
|
|
96
|
+
const desc = i === selected ? ` \x1b[2m${opt.description}\x1b[0m` : '';
|
|
97
|
+
out.write(` ${indicator} ${label}${desc}\n`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function clear() {
|
|
101
|
+
// Move up and clear each line
|
|
102
|
+
for (let i = 0; i < options.length; i++) {
|
|
103
|
+
out.write('\x1b[A\x1b[2K');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
out.write(`\n \x1b[1m${title}\x1b[0m\n\n`);
|
|
107
|
+
render();
|
|
108
|
+
if (!process.stdin.isTTY) {
|
|
109
|
+
// Non-interactive: use default
|
|
110
|
+
resolve(options[0].value);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
process.stdin.setRawMode(true);
|
|
114
|
+
process.stdin.resume();
|
|
115
|
+
process.stdin.setEncoding('utf-8');
|
|
116
|
+
function onData(key) {
|
|
117
|
+
if (key === '\x1b[A' || key === 'k') {
|
|
118
|
+
// Up arrow or k
|
|
119
|
+
selected = (selected - 1 + options.length) % options.length;
|
|
120
|
+
clear();
|
|
121
|
+
render();
|
|
122
|
+
}
|
|
123
|
+
else if (key === '\x1b[B' || key === 'j') {
|
|
124
|
+
// Down arrow or j
|
|
125
|
+
selected = (selected + 1) % options.length;
|
|
126
|
+
clear();
|
|
127
|
+
render();
|
|
128
|
+
}
|
|
129
|
+
else if (key === '\r' || key === '\n') {
|
|
130
|
+
// Enter
|
|
131
|
+
process.stdin.setRawMode(false);
|
|
132
|
+
process.stdin.pause();
|
|
133
|
+
process.stdin.removeListener('data', onData);
|
|
134
|
+
// Redraw final state with checkmark
|
|
135
|
+
clear();
|
|
136
|
+
for (const [i, opt] of options.entries()) {
|
|
137
|
+
if (i === selected) {
|
|
138
|
+
out.write(` \x1b[32m✓\x1b[0m \x1b[1m${opt.label}\x1b[0m\n`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
out.write('\n');
|
|
142
|
+
resolve(options[selected].value);
|
|
143
|
+
}
|
|
144
|
+
else if (key === '\x03') {
|
|
145
|
+
// Ctrl+C
|
|
146
|
+
process.stdin.setRawMode(false);
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
process.stdin.on('data', onData);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function textPrompt(label) {
|
|
154
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
155
|
+
return new Promise(resolve => {
|
|
156
|
+
rl.question(` ${label}`, (answer) => {
|
|
157
|
+
rl.close();
|
|
158
|
+
resolve(answer.trim());
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function interactiveStart() {
|
|
163
|
+
const mode = await selectPrompt('Heron — AI Agent Auditor', [
|
|
164
|
+
{ label: 'Start server', description: 'agents connect to you', value: 'serve' },
|
|
165
|
+
{ label: 'Scan an agent', description: 'you connect to an agent', value: 'scan' },
|
|
166
|
+
]);
|
|
167
|
+
if (mode === 'serve') {
|
|
168
|
+
process.argv.splice(2, 0, 'serve');
|
|
169
|
+
program.parse();
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const url = await textPrompt('Agent URL: ');
|
|
173
|
+
if (!url) {
|
|
174
|
+
console.error(' URL is required.');
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
process.argv.splice(2, 0, 'scan', '--target', url);
|
|
178
|
+
program.parse();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const args = process.argv.slice(2);
|
|
182
|
+
const hasSubcommand = args.length > 0 && ['scan', 'serve', 'help', '--help', '-h', '--version', '-V'].includes(args[0]);
|
|
183
|
+
if (!hasSubcommand && args.length > 0) {
|
|
184
|
+
// Legacy: flags without subcommand → scan
|
|
185
|
+
process.argv.splice(2, 0, 'scan');
|
|
186
|
+
program.parse();
|
|
187
|
+
}
|
|
188
|
+
else if (!hasSubcommand) {
|
|
189
|
+
// No args at all → interactive menu
|
|
190
|
+
interactiveStart().catch(err => {
|
|
191
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
192
|
+
process.exit(1);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
program.parse();
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=heron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heron.js","sourceRoot":"","sources":["../../bin/heron.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LLMClient } from '../llm/client.js';
|
|
2
|
+
import type { QAPair, AccessAssessment, DataNeed } from '../report/types.js';
|
|
3
|
+
import { type AnalysisResult } from '../report/types.js';
|
|
4
|
+
export interface FullAnalysisResult extends AnalysisResult {
|
|
5
|
+
dataNeeds: DataNeed[];
|
|
6
|
+
accessAssessment: AccessAssessment;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Uses LLM to analyze the interview transcript and produce a structured audit.
|
|
10
|
+
* Validates output with Zod schema. Retries once on parse failure.
|
|
11
|
+
* Falls back to partial report on double failure.
|
|
12
|
+
*/
|
|
13
|
+
export declare function analyzeTranscript(llmClient: LLMClient, transcript: QAPair[]): Promise<FullAnalysisResult>;
|
|
14
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/analysis/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAA0B,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAwB,KAAK,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAKpG,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAwB7B"}
|