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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +423 -0
  3. package/dist/bin/heron.d.ts +3 -0
  4. package/dist/bin/heron.d.ts.map +1 -0
  5. package/dist/bin/heron.js +198 -0
  6. package/dist/bin/heron.js.map +1 -0
  7. package/dist/src/analysis/analyzer.d.ts +14 -0
  8. package/dist/src/analysis/analyzer.d.ts.map +1 -0
  9. package/dist/src/analysis/analyzer.js +130 -0
  10. package/dist/src/analysis/analyzer.js.map +1 -0
  11. package/dist/src/analysis/risk-scorer.d.ts +20 -0
  12. package/dist/src/analysis/risk-scorer.d.ts.map +1 -0
  13. package/dist/src/analysis/risk-scorer.js +143 -0
  14. package/dist/src/analysis/risk-scorer.js.map +1 -0
  15. package/dist/src/config/loader.d.ts +15 -0
  16. package/dist/src/config/loader.d.ts.map +1 -0
  17. package/dist/src/config/loader.js +39 -0
  18. package/dist/src/config/loader.js.map +1 -0
  19. package/dist/src/config/schema.d.ts +146 -0
  20. package/dist/src/config/schema.d.ts.map +1 -0
  21. package/dist/src/config/schema.js +27 -0
  22. package/dist/src/config/schema.js.map +1 -0
  23. package/dist/src/connectors/http-connector.d.ts +17 -0
  24. package/dist/src/connectors/http-connector.d.ts.map +1 -0
  25. package/dist/src/connectors/http-connector.js +56 -0
  26. package/dist/src/connectors/http-connector.js.map +1 -0
  27. package/dist/src/connectors/index.d.ts +5 -0
  28. package/dist/src/connectors/index.d.ts.map +1 -0
  29. package/dist/src/connectors/index.js +13 -0
  30. package/dist/src/connectors/index.js.map +1 -0
  31. package/dist/src/connectors/interactive-connector.d.ts +13 -0
  32. package/dist/src/connectors/interactive-connector.d.ts.map +1 -0
  33. package/dist/src/connectors/interactive-connector.js +44 -0
  34. package/dist/src/connectors/interactive-connector.js.map +1 -0
  35. package/dist/src/connectors/types.d.ts +15 -0
  36. package/dist/src/connectors/types.d.ts.map +1 -0
  37. package/dist/src/connectors/types.js +2 -0
  38. package/dist/src/connectors/types.js.map +1 -0
  39. package/dist/src/index.d.ts +12 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +60 -0
  42. package/dist/src/index.js.map +1 -0
  43. package/dist/src/interview/interviewer.d.ts +19 -0
  44. package/dist/src/interview/interviewer.d.ts.map +1 -0
  45. package/dist/src/interview/interviewer.js +68 -0
  46. package/dist/src/interview/interviewer.js.map +1 -0
  47. package/dist/src/interview/protocol.d.ts +38 -0
  48. package/dist/src/interview/protocol.d.ts.map +1 -0
  49. package/dist/src/interview/protocol.js +290 -0
  50. package/dist/src/interview/protocol.js.map +1 -0
  51. package/dist/src/interview/questions.d.ts +20 -0
  52. package/dist/src/interview/questions.d.ts.map +1 -0
  53. package/dist/src/interview/questions.js +131 -0
  54. package/dist/src/interview/questions.js.map +1 -0
  55. package/dist/src/llm/client.d.ts +13 -0
  56. package/dist/src/llm/client.d.ts.map +1 -0
  57. package/dist/src/llm/client.js +128 -0
  58. package/dist/src/llm/client.js.map +1 -0
  59. package/dist/src/llm/prompts.d.ts +13 -0
  60. package/dist/src/llm/prompts.d.ts.map +1 -0
  61. package/dist/src/llm/prompts.js +192 -0
  62. package/dist/src/llm/prompts.js.map +1 -0
  63. package/dist/src/report/generator.d.ts +23 -0
  64. package/dist/src/report/generator.d.ts.map +1 -0
  65. package/dist/src/report/generator.js +304 -0
  66. package/dist/src/report/generator.js.map +1 -0
  67. package/dist/src/report/templates.d.ts +3 -0
  68. package/dist/src/report/templates.d.ts.map +1 -0
  69. package/dist/src/report/templates.js +386 -0
  70. package/dist/src/report/templates.js.map +1 -0
  71. package/dist/src/report/types.d.ts +954 -0
  72. package/dist/src/report/types.d.ts.map +1 -0
  73. package/dist/src/report/types.js +161 -0
  74. package/dist/src/report/types.js.map +1 -0
  75. package/dist/src/server/index.d.ts +17 -0
  76. package/dist/src/server/index.d.ts.map +1 -0
  77. package/dist/src/server/index.js +650 -0
  78. package/dist/src/server/index.js.map +1 -0
  79. package/dist/src/server/sessions.d.ts +68 -0
  80. package/dist/src/server/sessions.d.ts.map +1 -0
  81. package/dist/src/server/sessions.js +268 -0
  82. package/dist/src/server/sessions.js.map +1 -0
  83. package/dist/src/util/id.d.ts +2 -0
  84. package/dist/src/util/id.d.ts.map +1 -0
  85. package/dist/src/util/id.js +5 -0
  86. package/dist/src/util/id.js.map +1 -0
  87. package/dist/src/util/logger.d.ts +9 -0
  88. package/dist/src/util/logger.d.ts.map +1 -0
  89. package/dist/src/util/logger.js +32 -0
  90. package/dist/src/util/logger.js.map +1 -0
  91. package/heron.example.yaml +46 -0
  92. 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> &bull;
14
+ <a href="#how-it-works">How It Works</a> &bull;
15
+ <a href="#example-report">Example Report</a> &bull;
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 &mdash; 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 &mdash; 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 &rarr; API &rarr; 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 &rarr; Target &rarr; Reversible? &rarr; 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** &mdash; dashboard table (risk / systems / findings)
235
+ 2. **Agent Profile** &mdash; purpose, trigger, owner, frequency
236
+ 3. **Findings** &mdash; severity-ranked with IDs (HERON-001, ...), split description and recommendation
237
+ 4. **Systems & Access** &mdash; per-system cards with risk rating, scopes, data, writes, blast radius
238
+ 5. **What's Working Well** &mdash; positive findings
239
+ 6. **Verdict & Recommendations** &mdash; APPROVE / APPROVE WITH CONDITIONS / DENY
240
+ 7. **Regulatory Compliance** &mdash; EU (AI Act + GDPR), US (SOC 2 + state AI laws), UK (UK GDPR + ICO)
241
+ 8. **Data Quality** &mdash; field-by-field coverage score, repeated answer warnings
242
+ 9. **Interview Transcript** &mdash; 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"** &mdash; 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?"** &mdash; 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"** &mdash; 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 &rarr; Heron | Deploy as a gate. Agents connect to Heron |
311
+ | **Scan** | `scan` | Heron &rarr; 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 &mdash; <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 &mdash; 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 &mdash; <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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=heron.d.ts.map
@@ -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":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAEhD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,gFAAgF,CAAC;KAC7F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,4EAA4E;AAE5E,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,oBAAoB,EAAE,+CAA+C,CAAC;KAC7E,MAAM,CAAC,sBAAsB,EAAE,sCAAsC,EAAE,MAAM,CAAC;KAC9E,MAAM,CAAC,2BAA2B,EAAE,qEAAqE,CAAC;KAC1G,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;KACnE,MAAM,CAAC,qBAAqB,EAAE,uCAAuC,CAAC;KACtE,MAAM,CAAC,uBAAuB,EAAE,iCAAiC,EAAE,UAAU,CAAC;KAC9E,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;KAC/D,MAAM,CAAC,qBAAqB,EAAE,sCAAsC,EAAE,GAAG,CAAC;KAC1E,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,WAAW,CAAC;KACtE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,KAAK,aAAa,EAAE,CAAC;YACtE,OAAO,CAAC,KAAK,CAAC,kFAAkF,CAAC,CAAC;YAClG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,mBAAmB,CAAC;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,MAAM,EAAE;YAChB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,EAAE,EAAE,CAAC;YACpD,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,4EAA4E;AAE5E,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,CAAC;KACzD,MAAM,CAAC,2BAA2B,EAAE,qEAAqE,CAAC;KAC1G,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;KACnE,MAAM,CAAC,qBAAqB,EAAE,sCAAsC,EAAE,GAAG,CAAC;KAC1E,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,WAAW,CAAC;KACtE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,MAAM,WAAW,CAAC;YAChB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,EAAE;gBACH,QAAQ,EAAE,IAAI,CAAC,WAAgD;gBAC/D,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,QAAQ;aACrB;YACD,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,EAAE,EAAE,CAAC;YACpD,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+EAA+E;AAE/E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAQhD,qDAAqD;AACrD,SAAS,YAAY,CAAC,KAAa,EAAE,OAAuB;IAC1D,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;QAE3B,SAAS,MAAM;YACb,gDAAgD;YAChD,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC5D,MAAM,KAAK,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,KAAK,SAAS,CAAC;gBAC3F,MAAM,IAAI,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxE,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAED,SAAS,KAAK;YACZ,8BAA8B;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,aAAa,CAAC,CAAC;QAC5C,MAAM,EAAE,CAAC;QAET,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACzB,+BAA+B;YAC/B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEnC,SAAS,MAAM,CAAC,GAAW;YACzB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;gBACpC,gBAAgB;gBAChB,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;gBAC5D,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;gBAC3C,kBAAkB;gBAClB,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;gBAC3C,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACxC,QAAQ;gBACR,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,oCAAoC;gBACpC,KAAK,EAAE,CAAC;gBACR,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;oBACzC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;wBACnB,GAAG,CAAC,KAAK,CAAC,6BAA6B,GAAG,CAAC,KAAK,WAAW,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBAC1B,SAAS;gBACT,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,EAAE,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;YACnC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,gBAAgB;IAC7B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,0BAA0B,EAAE;QAC1D,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,uBAAuB,EAAE,KAAK,EAAE,OAAO,EAAE;QAC/E,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,EAAE;KAClF,CAAC,CAAC;IAEH,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAExH,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACtC,0CAA0C;IAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC;KAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC1B,oCAAoC;IACpC,gBAAgB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
@@ -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"}