avantgate 2.0.0 → 2.2.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/README.md +26 -33
- package/dist/chunk-Z6QOMLZ2.mjs +55 -0
- package/dist/control-layer.d.ts.map +1 -1
- package/dist/custom-terms.d.ts +8 -0
- package/dist/custom-terms.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -5
- package/dist/index.mjs +83 -5
- package/dist/secret-guard.d.ts +5 -0
- package/dist/secret-guard.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/define-canvas.d.ts +6 -0
- package/dist/ui/define-canvas.d.ts.map +1 -0
- package/dist/ui/envelope.d.ts +19 -0
- package/dist/ui/envelope.d.ts.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +235 -0
- package/dist/ui/index.mjs +146 -0
- package/dist/ui/react/create-view-registry.d.ts +22 -0
- package/dist/ui/react/create-view-registry.d.ts.map +1 -0
- package/dist/ui/react/index.d.ts +3 -0
- package/dist/ui/react/index.d.ts.map +1 -0
- package/dist/ui/react/index.js +92 -0
- package/dist/ui/react/index.mjs +9 -0
- package/dist/ui/react/sanitize.d.ts +2 -0
- package/dist/ui/react/sanitize.d.ts.map +1 -0
- package/dist/ui/reducer.d.ts +15 -0
- package/dist/ui/reducer.d.ts.map +1 -0
- package/package.json +20 -10
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 🛡️ AvantGate (`avantgate`)
|
|
2
2
|
|
|
3
|
-
> **The Zero-Infrastructure, In-Process AI Application Firewall (AI-WAF), Deterministic Workflow Engine
|
|
4
|
-
> Real-time prompt guardrails, zero-egress PII redaction, deterministic Saga workflows, anti-IDOR tool boundary, and pre-flight token defense **without hosting Docker, proxies, PostgreSQL, ClickHouse, or Redis.**
|
|
3
|
+
> **The Zero-Infrastructure, In-Process AI Application Firewall (AI-WAF), Deterministic Workflow Engine, Privacy Guard & Headless UI Canvas for TypeScript.**
|
|
4
|
+
> Real-time prompt guardrails, zero-egress PII redaction, deterministic Saga workflows, canonical tool envelopes, anti-IDOR tool boundary, and pre-flight token defense **without hosting Docker, proxies, PostgreSQL, ClickHouse, or Redis.**
|
|
5
5
|
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
@@ -33,32 +33,17 @@ flowchart LR
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
## 🖥️
|
|
36
|
+
## 🖥️ Optional Visual Cockpit — GateWall (`gatewall`)
|
|
37
37
|
|
|
38
|
-
While the **AvantGate SDK**
|
|
38
|
+
While the **AvantGate SDK (`avantgate`)** runs **100% headless and in-process** inside your application runtime (zero servers, zero network latency), an optional visual control plane, **GateWall**, is available as a standalone repository for teams requiring a visual dashboard, real-time audit inspector, and Human-in-the-Loop approval interface.
|
|
39
39
|
|
|
40
40
|
```mermaid
|
|
41
41
|
flowchart LR
|
|
42
|
-
Agent[🤖 AvantGate Agent
|
|
43
|
-
GateWall -- "SSE
|
|
44
|
-
Browser -- "POST /api/v1/approvals<br/>(Approve / Reject)" --> GateWall
|
|
42
|
+
Agent[🤖 AvantGate In-Process Agent] -- "Optional HTTP Telemetry" --> GateWall["🛡️ Standalone GateWall Cockpit<br/>(Dedicated Repository)"]
|
|
43
|
+
GateWall -- "SSE Real-Time Stream" --> Browser["💻 Web Dashboard<br/>(localhost:3000)"]
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#### Option 1: One-Line Docker Compose (Recommended)
|
|
50
|
-
```bash
|
|
51
|
-
docker compose up -d
|
|
52
|
-
# or: npm run gatewall:docker
|
|
53
|
-
```
|
|
54
|
-
Open **`http://localhost:3000`** in your browser 🎉. Traces and audit sessions are automatically persisted.
|
|
55
|
-
|
|
56
|
-
#### Option 2: Run with Bun or Node.js
|
|
57
|
-
```bash
|
|
58
|
-
cd gatewall
|
|
59
|
-
bun install # or npm install
|
|
60
|
-
bun run dev # or npm run dev
|
|
61
|
-
```
|
|
46
|
+
> 💡 **Standalone Repository:** GateWall Cockpit is maintained independently at `../gatewall`. If your application runs headless, you do **not** need to deploy or run GateWall — all guardrails, PII redactions, and token budgets execute directly within your Node.js process.
|
|
62
47
|
|
|
63
48
|
---
|
|
64
49
|
|
|
@@ -71,9 +56,10 @@ bun run dev # or npm run dev
|
|
|
71
56
|
| **⚡ Real-Time Streaming (SSE)** | Low-latency Server-Sent Events (`/api/v1/realtime`) updating session trees, metrics, and alerts dynamically without manual page refresh. |
|
|
72
57
|
| **💰 FinOps & Token Tracking** | Automated token cost estimation and USD burn tracking across providers (GPT-4o, Claude 3.5 Sonnet, DeepSeek, etc.). |
|
|
73
58
|
| **🛡️ Loop Shield (Anti-Cycle Guard)** | Early visual detection of recursive agent loops and aberrant repetitive tool execution cycles. |
|
|
74
|
-
| **💾
|
|
59
|
+
| **💾 Pluggable Hexagonal Storage** | Zero setup overhead by default with embedded SQLite (`gatewall/data/gatewall.db`), zero-disk in-memory storage for CI tests, and production-ready PostgreSQL/Prisma adapter (`STORAGE_DRIVER=prisma`). |
|
|
60
|
+
| **🔏 Custom Redaction Terms Manager** | Interactive visual manager in the Security Cockpit to register, categorize (Project, Company, Infra), and redact proprietary secrets and NDA keywords in-flight. |
|
|
75
61
|
|
|
76
|
-
> 💡 **Agent Integration Recipes:** See [
|
|
62
|
+
> 💡 **Agent Integration Recipes:** See [GateWall Telemetry Recipe](examples/observability/10-gatewall-telemetry.ts) and [Integration Cookbook](examples/README.md) for complete code recipes using `HttpTelemetryExporter` (`avantgate/agent`), direct HTTP ingestion, and React front-end streaming (`avantgate/client`).
|
|
77
63
|
|
|
78
64
|
---
|
|
79
65
|
|
|
@@ -92,6 +78,7 @@ Contact our team at [contact@gatewall.fr](mailto:contact@gatewall.fr) for privat
|
|
|
92
78
|
| 🛑 **Agent Isolation & Anti-IDOR** | • **Dual-Channel DTOs**: Streams full records to UI while injecting sanitized summaries into LLM.<br/>• **Anti-IDOR Boundary**: Compile-time tenant scoping (`createTenantTool`) & runtime ownership checks.<br/>• **Server Idempotency Guard**: Zero-infra in-process guard (`withServerIdempotency`) with memory or storage adapters.<br/>• **Infinite Loop Shield**: Detects and breaks recursive agent tool execution loops. |
|
|
93
79
|
| 💰 **FinOps & Resilience** | • **Denial-of-Wallet**: Enforces hard token & USD budgets *before* external inference spend.<br/>• **Multi-Model Failover**: Instant client-side routing to fallback models or local Ollama on 429/500.<br/>• **FinOps Batch Deduplication**: Prevents double-counting of tokens & costs during network retries on GateWall.<br/>• **Live Cost Ledger**: Token burn calculation & pricing adapters with zero external DB. |
|
|
94
80
|
| ⚡ **Sagas, Replay & Telemetry** | • **Deterministic Sagas (`avantgate/workflow`)**: In-process FSM with automatic reverse compensation ($k-1 \to 0$).<br/>• **In-Context Replay (`avantgate/client`)**: React hook (`useTask`) with causal parent linkage (`parentRunId`) & `Idempotency-Key`.<br/>• **Human-in-the-Loop (HITL)**: Non-blocking suspension, approval queues & fail-closed 24h SLA timeout (TTL).<br/>• **Lightweight Telemetry**: < 1.7 KB client SDK & async audit bridge to GateWall. |
|
|
81
|
+
| 🎨 **Presentation Plane (`avantgate/ui`)** | • **Canonical Tool Envelopes**: Typed format carrying merge strategies (`REPLACE`, `APPEND_UNIQUE`, `UPDATE_ENTITY`) & `UIIntent`.<br/>• **Deterministic Concurrency Reducer**: Algebraic $O(N)$ Set-based convergence solving parallel tool calling races.<br/>• **React View Registry (`avantgate/ui/react`)**: Polymorphic $O(1)$ dynamic dispatch linking tools to your design system (shadcn/ui).<br/>• **Native Anti-XSS Guard**: Zero-dependency WHATWG `URL` scanner neutralizing `javascript:` & protocol-relative (`//evil.com`) vectors. |
|
|
95
82
|
|
|
96
83
|
---
|
|
97
84
|
|
|
@@ -99,14 +86,15 @@ Contact our team at [contact@gatewall.fr](mailto:contact@gatewall.fr) for privat
|
|
|
99
86
|
|
|
100
87
|
| Category | In-Depth Guides |
|
|
101
88
|
|---|---|
|
|
102
|
-
| 🚀 **Quickstart** | [Getting Started](docs/getting-started.md) • [Integration Cookbook](
|
|
89
|
+
| 🚀 **Quickstart** | [Getting Started](docs/getting-started.md) • [Integration Cookbook](examples/README.md) |
|
|
103
90
|
| 🛡️ **Security & AI-WAF** | [Prompt Guardrails](docs/security/prompt-guardrails.md) • [PII Redaction](docs/security/pii-redaction.md) • [Anti-IDOR Defense](docs/security/anti-idor.md) • [End-to-End Security](docs/security/end-to-end-security.md) |
|
|
104
91
|
| 💰 **FinOps & Cost** | [Pre-Flight Budget Guards](docs/finops/budget-guards.md) • [Pricing Adapters & SQLite](docs/finops/pricing-adapters.md) |
|
|
105
92
|
| 🤖 **Agents & Tools** | [Isolated Tools & DTOs](docs/agents/isolated-tools.md) • [Agent Runtime Manual](docs/agents/agent-runtime.md) • [Inter-Tool Chaining](docs/agents/inter-tool-chaining.md) |
|
|
106
93
|
| 🔄 **Deterministic Sagas** | [Durable Workflows Engine](docs/workflows/durable-workflows.md) |
|
|
107
94
|
| 📊 **Observability & Cockpit** | [GateWall Cockpit Console](docs/observability/gatewall-cockpit.md) • [Telemetry & Browser SDK](docs/observability/telemetry-and-browser-sdk.md) • [GateWall vs. Temporal](docs/observability/temporal-and-gatewall.md) |
|
|
108
95
|
| 💶 **Accounting** | [Financial Normalizer](docs/finance/normalizer.md) |
|
|
109
|
-
|
|
|
96
|
+
| 🎨 **Presentation Plane** | [Headless UI Canvas & React Bindings](docs/ui/headless-canvas.md) |
|
|
97
|
+
| 🚀 **Release Notes** | [v2.1.0 Release Notes](docs/release/release-2.1.0.md) • [v2.0.0 Release Notes](docs/release/release-2.0.0.md) • [v1.9.0 Release Notes](docs/release/release-1.9.0.md) |
|
|
110
98
|
|
|
111
99
|
---
|
|
112
100
|
|
|
@@ -125,6 +113,7 @@ Contact our team at [contact@gatewall.fr](mailto:contact@gatewall.fr) for privat
|
|
|
125
113
|
| **Multi-Model Failover** | ❌ App crashes | ⚠️ Proxy-dependent | ✅ **Built-in Fallback Router & Exponential Retry** |
|
|
126
114
|
| **Zod Schema Auto-Repair** | ❌ No | ❌ No | ✅ **Built-in JSON Heuristic Repair** |
|
|
127
115
|
| **Hierarchical Session Replay** | ❌ None | ⚠️ Flat span waterfall | ✅ **Causality Tree + In-Context Replay (`useTask`)** |
|
|
116
|
+
| **Headless UI Canvas State** | ❌ Manual parsing | ❌ Not supported | ✅ **Canonical Envelopes + Parallel Reducer (`avantgate/ui`)** |
|
|
128
117
|
|
|
129
118
|
---
|
|
130
119
|
|
|
@@ -140,13 +129,17 @@ yarn add avantgate zod
|
|
|
140
129
|
|
|
141
130
|
### 🧩 Subpath Exports
|
|
142
131
|
|
|
143
|
-
| Import Path | Description |
|
|
144
|
-
|
|
145
|
-
| `avantgate` | Core control plane: token budgets, cost ledger, prompt guards, multi-model failover & Zod repair. |
|
|
146
|
-
| `avantgate/finance` | Financial data normalizer (accounting parentheses, EU/US/UK/CH currencies & magnitudes). |
|
|
147
|
-
| `avantgate/agent` | Durable step runner, Human-in-the-Loop, dual-channel PII tool isolation, server idempotency (`withServerIdempotency`), & storage adapters. |
|
|
148
|
-
| `avantgate/workflow` | Deterministic sequential state machine, automatic reverse Saga rollback, durable HITL checkpoints & agent tool conversion. |
|
|
149
|
-
| `avantgate/client` | Front-end SDK (< 1.7 KB) with in-context task replay (`useTask`, `createTaskRunner`), causal idempotency helpers (`getIdempotencyHeaders`), & GateWall telemetry adapter. |
|
|
132
|
+
| Import Path | Description | Documentation |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `avantgate` | Core control plane: token budgets, cost ledger, prompt guards, multi-model failover & Zod repair. | [Getting Started](docs/getting-started.md) |
|
|
135
|
+
| `avantgate/finance` | Financial data normalizer (accounting parentheses, EU/US/UK/CH currencies & magnitudes). | [Financial Normalizer](docs/finance/normalizer.md) |
|
|
136
|
+
| `avantgate/agent` | Durable step runner, Human-in-the-Loop, dual-channel PII tool isolation, server idempotency (`withServerIdempotency`), & storage adapters. | [Isolated Tools & DTOs](docs/agents/isolated-tools.md) |
|
|
137
|
+
| `avantgate/workflow` | Deterministic sequential state machine, automatic reverse Saga rollback, durable HITL checkpoints & agent tool conversion. | [Durable Workflows](docs/workflows/durable-workflows.md) |
|
|
138
|
+
| `avantgate/client` | Front-end SDK (< 1.7 KB) with in-context task replay (`useTask`, `createTaskRunner`), causal idempotency helpers (`getIdempotencyHeaders`), & GateWall telemetry adapter. | [Telemetry & Browser SDK](docs/observability/telemetry-and-browser-sdk.md) |
|
|
139
|
+
| `avantgate/ui` | Headless UI canvas core (< 2.5 KB): canonical tool envelopes, deterministic $O(N)$ parallel reducer, `defineCanvas` factory. | [Headless UI Canvas](docs/ui/headless-canvas.md) |
|
|
140
|
+
| `avantgate/ui/react` | React presentation plane: polymorphic $O(1)$ view registry (`createViewRegistry`), `CanvasRenderer`, & anti-XSS URL sanitizer (`isValidSafeUrl`). | [Headless UI Canvas](docs/ui/headless-canvas.md) |
|
|
141
|
+
|
|
142
|
+
> 💡 **UI Canvas Cookbook:** See [Headless UI Canvas & React Bindings](docs/ui/headless-canvas.md) for complete step-by-step recipes connecting agent tools with typed envelopes and custom React views (shadcn/ui, Tailwind).
|
|
150
143
|
|
|
151
144
|
---
|
|
152
145
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/ui/react/create-view-registry.ts
|
|
2
|
+
import React from "react";
|
|
3
|
+
var createViewRegistry = (registry) => {
|
|
4
|
+
const CanvasRenderer = ({
|
|
5
|
+
state,
|
|
6
|
+
context = {}
|
|
7
|
+
}) => {
|
|
8
|
+
if (!state?.content) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const kind = state.content.kind;
|
|
12
|
+
const Component = registry[kind];
|
|
13
|
+
if (!Component) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return React.createElement(Component, {
|
|
17
|
+
data: state.content,
|
|
18
|
+
context,
|
|
19
|
+
activeIntent: state.activeIntent
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
registry,
|
|
24
|
+
CanvasRenderer
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/ui/react/sanitize.ts
|
|
29
|
+
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
30
|
+
var isValidSafeUrl = (rawUrl) => {
|
|
31
|
+
if (!rawUrl || typeof rawUrl !== "string") {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const trimmed = rawUrl.trim();
|
|
35
|
+
if (!trimmed) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (trimmed.startsWith("#")) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const parsed = new URL(trimmed);
|
|
46
|
+
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
createViewRegistry,
|
|
54
|
+
isValidSafeUrl
|
|
55
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-layer.d.ts","sourceRoot":"","sources":["../src/control-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,+BAA+B,EAC/B,eAAe,EAIhB,MAAM,SAAS,CAAC;AAiBjB,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,MAAM,EAAE,kBAAkB;IAgBtC,OAAO,CAAC,qBAAqB,CAU3B;IAEF,OAAO,CAAC,kBAAkB,CAaxB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"control-layer.d.ts","sourceRoot":"","sources":["../src/control-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,+BAA+B,EAC/B,eAAe,EAIhB,MAAM,SAAS,CAAC;AAiBjB,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,MAAM,EAAE,kBAAkB;IAgBtC,OAAO,CAAC,qBAAqB,CAU3B;IAEF,OAAO,CAAC,kBAAkB,CAaxB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,yBAAyB,CAiB/B;IAEF,OAAO,CAAC,oBAAoB,CAkC1B;IAEF,OAAO,CAAC,wBAAwB,CAW9B;IAEF,OAAO,CAAC,aAAa,CAOnB;IAEF,OAAO,CAAC,aAAa,CAUnB;IAEF,OAAO,CAAC,gBAAgB,CAMtB;IAEF,OAAO,CAAC,iBAAiB,CAsBvB;IAEF,OAAO,CAAC,uBAAuB,CAmB7B;IAEF,OAAO,CAAC,uBAAuB,CA+B7B;IAEF,OAAO,CAAC,cAAc,CAqBpB;IAEF,OAAO,CAAC,eAAe,CAarB;IAEF,OAAO,GAAU,SAAS;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,eAAe,CAAC;KACpC,KAAG,OAAO,CAAC,eAAe,CAAC,CA2B1B;IAGF,iBAAiB,GAAU,CAAC,EAAE,SAAS;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,eAAe,CAAC;KACpC,KAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAyBvC;IAEF,OAAO,CAAC,wBAAwB,CAO9B;IAEF,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,uBAAuB,CAe7B;IAEF,OAAO,CAAC,wBAAwB,CAqB9B;IAEF,OAAO,CAAC,uBAAuB,CAkB7B;IAEF,OAAO,CAAC,uBAAuB,CAY7B;IAEF,OAAO,CAAC,gCAAgC,CAiBtC;IAEF,OAAO,CAAC,qBAAqB,CAwB3B;IAEF,OAAO,CAAC,mBAAmB,CAazB;IAEF,OAAO,CAAC,gBAAgB,CAQtB;IAEF,wBAAwB,GAAU,CAAC,EACjC,SAAS,+BAA+B,CAAC,CAAC,CAAC,KAC1C,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAwCtC;CACH;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,kBAAkB,KAAG,qBAElE,CAAC;AAEF,eAAO,MAAM,eAAe,WAJkB,kBAAkB,KAAG,qBAIf,CAAC;AACrD,OAAO,EAAE,qBAAqB,IAAI,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CustomRedactionTermDef } from "./types";
|
|
2
|
+
export interface CustomTermsSanitizationResult {
|
|
3
|
+
text: string;
|
|
4
|
+
maskedCount: number;
|
|
5
|
+
matchedTerms: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare const sanitizeCustomTerms: (input: string, terms?: Array<string | CustomRedactionTermDef>) => CustomTermsSanitizationResult;
|
|
8
|
+
//# sourceMappingURL=custom-terms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-terms.d.ts","sourceRoot":"","sources":["../src/custom-terms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,SAAS,CAAC;AAEpE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAsED,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,QAAQ,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC,KAC7C,6BAeF,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,7 @@ __export(index_exports, {
|
|
|
61
61
|
isWorkflowAbortSignal: () => isWorkflowAbortSignal,
|
|
62
62
|
resolveModelPrice: () => resolveModelPrice,
|
|
63
63
|
resolveModelPriceAsync: () => resolveModelPriceAsync,
|
|
64
|
+
sanitizeCustomTerms: () => sanitizeCustomTerms,
|
|
64
65
|
sanitizePII: () => sanitizePII,
|
|
65
66
|
sanitizeSecrets: () => sanitizeSecrets,
|
|
66
67
|
validateUserInput: () => validateUserInput,
|
|
@@ -1172,6 +1173,70 @@ var createHttpProviderClient = (config) => {
|
|
|
1172
1173
|
return new HttpProviderClient(config);
|
|
1173
1174
|
};
|
|
1174
1175
|
|
|
1176
|
+
// src/custom-terms.ts
|
|
1177
|
+
var DEFAULT_MASKS = {
|
|
1178
|
+
PROJECT: "[REDACTED_PROJECT]",
|
|
1179
|
+
COMPANY: "[REDACTED_COMPANY]",
|
|
1180
|
+
INFRA: "[REDACTED_INFRA]",
|
|
1181
|
+
CUSTOM: "[REDACTED_CUSTOM]"
|
|
1182
|
+
};
|
|
1183
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1184
|
+
var resolveTermDefinition = (entry) => {
|
|
1185
|
+
if (typeof entry === "string") {
|
|
1186
|
+
return {
|
|
1187
|
+
term: entry.trim(),
|
|
1188
|
+
mask: DEFAULT_MASKS.CUSTOM,
|
|
1189
|
+
category: "CUSTOM",
|
|
1190
|
+
caseSensitive: false
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
const category = entry.category ?? "CUSTOM";
|
|
1194
|
+
return {
|
|
1195
|
+
term: entry.term.trim(),
|
|
1196
|
+
mask: entry.mask ?? (DEFAULT_MASKS[category] ?? DEFAULT_MASKS.CUSTOM),
|
|
1197
|
+
category,
|
|
1198
|
+
caseSensitive: Boolean(entry.caseSensitive)
|
|
1199
|
+
};
|
|
1200
|
+
};
|
|
1201
|
+
var buildTermRegex = (def) => {
|
|
1202
|
+
const escaped = escapeRegex(def.term);
|
|
1203
|
+
const leadingBoundary = /^\w/.test(def.term) ? "\\b" : "";
|
|
1204
|
+
const trailingBoundary = /\w$/.test(def.term) ? "\\b" : "";
|
|
1205
|
+
return new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, def.caseSensitive ? "g" : "gi");
|
|
1206
|
+
};
|
|
1207
|
+
var replaceTermsInText = (initialText, definitions) => {
|
|
1208
|
+
let currentText = initialText;
|
|
1209
|
+
let totalMaskedCount = 0;
|
|
1210
|
+
const matchedTermsSet = /* @__PURE__ */ new Set();
|
|
1211
|
+
for (const item of definitions) {
|
|
1212
|
+
const regex = buildTermRegex(item);
|
|
1213
|
+
let matchCount = 0;
|
|
1214
|
+
currentText = currentText.replace(regex, () => {
|
|
1215
|
+
matchCount++;
|
|
1216
|
+
return item.mask;
|
|
1217
|
+
});
|
|
1218
|
+
if (matchCount > 0) {
|
|
1219
|
+
totalMaskedCount += matchCount;
|
|
1220
|
+
matchedTermsSet.add(item.term);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
text: currentText,
|
|
1225
|
+
maskedCount: totalMaskedCount,
|
|
1226
|
+
matchedTerms: Array.from(matchedTermsSet)
|
|
1227
|
+
};
|
|
1228
|
+
};
|
|
1229
|
+
var sanitizeCustomTerms = (input, terms) => {
|
|
1230
|
+
if (!input || !terms || terms.length === 0) {
|
|
1231
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
1232
|
+
}
|
|
1233
|
+
const normalized = terms.map(resolveTermDefinition).filter((t) => t.term.length > 0).sort((a, b) => b.term.length - a.term.length);
|
|
1234
|
+
if (normalized.length === 0) {
|
|
1235
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
1236
|
+
}
|
|
1237
|
+
return replaceTermsInText(input, normalized);
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1175
1240
|
// src/secret-guard.ts
|
|
1176
1241
|
var SECRET_PATTERNS = [
|
|
1177
1242
|
// 1. Clés privées (RSA, OpenSSH, EC, DSA)
|
|
@@ -1252,6 +1317,7 @@ var sanitizeSecrets = (input) => {
|
|
|
1252
1317
|
var applyOutputGuards = (rawOutput, options) => {
|
|
1253
1318
|
let currentText = rawOutput;
|
|
1254
1319
|
let piiCount = 0;
|
|
1320
|
+
let customTermsCount = 0;
|
|
1255
1321
|
if (options?.maskPII) {
|
|
1256
1322
|
const piiResult = sanitizePII(currentText);
|
|
1257
1323
|
currentText = piiResult.text;
|
|
@@ -1259,6 +1325,11 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
1259
1325
|
}
|
|
1260
1326
|
const secretResult = sanitizeSecrets(currentText);
|
|
1261
1327
|
currentText = secretResult.text;
|
|
1328
|
+
if (options?.customRedactionTerms && options.customRedactionTerms.length > 0) {
|
|
1329
|
+
const customResult = sanitizeCustomTerms(currentText, options.customRedactionTerms);
|
|
1330
|
+
currentText = customResult.text;
|
|
1331
|
+
customTermsCount = customResult.maskedCount;
|
|
1332
|
+
}
|
|
1262
1333
|
if (secretResult.hasSecrets && options?.secretLeakAction === "BLOCK") {
|
|
1263
1334
|
const types = secretResult.detections.map((d) => d.type).join(", ");
|
|
1264
1335
|
throw new SecretLeakBlockedError(
|
|
@@ -1268,9 +1339,10 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
1268
1339
|
}
|
|
1269
1340
|
return {
|
|
1270
1341
|
text: currentText,
|
|
1271
|
-
sanitized: piiCount > 0 || secretResult.hasSecrets,
|
|
1342
|
+
sanitized: piiCount > 0 || secretResult.hasSecrets || customTermsCount > 0,
|
|
1272
1343
|
secretDetected: secretResult.hasSecrets,
|
|
1273
1344
|
piiMaskedCount: piiCount,
|
|
1345
|
+
customTermsMaskedCount: customTermsCount,
|
|
1274
1346
|
detections: secretResult.detections
|
|
1275
1347
|
};
|
|
1276
1348
|
};
|
|
@@ -1335,21 +1407,27 @@ var AvantGateControlLayer = class {
|
|
|
1335
1407
|
if (!guard.valid) {
|
|
1336
1408
|
throw new Error(`[AvantGate Security Guard] Request blocked: ${guard.blockedReason}`);
|
|
1337
1409
|
}
|
|
1410
|
+
let processed = userQuery;
|
|
1411
|
+
if (this.config.security?.customRedactionTerms && this.config.security.customRedactionTerms.length > 0) {
|
|
1412
|
+
processed = sanitizeCustomTerms(processed, this.config.security.customRedactionTerms).text;
|
|
1413
|
+
}
|
|
1338
1414
|
if (this.config.security?.maskPII) {
|
|
1339
|
-
return sanitizePII(
|
|
1415
|
+
return sanitizePII(processed).text;
|
|
1340
1416
|
}
|
|
1341
|
-
return
|
|
1417
|
+
return processed;
|
|
1342
1418
|
};
|
|
1343
1419
|
applyOutputSecurityGuards = (rawOutput) => {
|
|
1344
1420
|
const isDlpEnabled = this.config.security?.outputDLP ?? this.config.security?.maskPII ?? false;
|
|
1345
1421
|
const shouldCheckSecrets = this.config.security?.blockSecretLeaks ?? true;
|
|
1346
|
-
|
|
1422
|
+
const customTerms = this.config.security?.customRedactionTerms;
|
|
1423
|
+
if (!isDlpEnabled && !shouldCheckSecrets && (!customTerms || customTerms.length === 0)) {
|
|
1347
1424
|
return rawOutput;
|
|
1348
1425
|
}
|
|
1349
1426
|
const guardResult = applyOutputGuards(rawOutput, {
|
|
1350
1427
|
maskPII: isDlpEnabled,
|
|
1351
1428
|
blockSecretLeaks: shouldCheckSecrets,
|
|
1352
|
-
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT"
|
|
1429
|
+
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT",
|
|
1430
|
+
customRedactionTerms: customTerms
|
|
1353
1431
|
});
|
|
1354
1432
|
return guardResult.text;
|
|
1355
1433
|
};
|
|
@@ -2642,6 +2720,7 @@ var defineWorkflow = (config) => {
|
|
|
2642
2720
|
isWorkflowAbortSignal,
|
|
2643
2721
|
resolveModelPrice,
|
|
2644
2722
|
resolveModelPriceAsync,
|
|
2723
|
+
sanitizeCustomTerms,
|
|
2645
2724
|
sanitizePII,
|
|
2646
2725
|
sanitizeSecrets,
|
|
2647
2726
|
validateUserInput,
|
package/dist/index.mjs
CHANGED
|
@@ -562,6 +562,70 @@ var createHttpProviderClient = (config) => {
|
|
|
562
562
|
return new HttpProviderClient(config);
|
|
563
563
|
};
|
|
564
564
|
|
|
565
|
+
// src/custom-terms.ts
|
|
566
|
+
var DEFAULT_MASKS = {
|
|
567
|
+
PROJECT: "[REDACTED_PROJECT]",
|
|
568
|
+
COMPANY: "[REDACTED_COMPANY]",
|
|
569
|
+
INFRA: "[REDACTED_INFRA]",
|
|
570
|
+
CUSTOM: "[REDACTED_CUSTOM]"
|
|
571
|
+
};
|
|
572
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
573
|
+
var resolveTermDefinition = (entry) => {
|
|
574
|
+
if (typeof entry === "string") {
|
|
575
|
+
return {
|
|
576
|
+
term: entry.trim(),
|
|
577
|
+
mask: DEFAULT_MASKS.CUSTOM,
|
|
578
|
+
category: "CUSTOM",
|
|
579
|
+
caseSensitive: false
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
const category = entry.category ?? "CUSTOM";
|
|
583
|
+
return {
|
|
584
|
+
term: entry.term.trim(),
|
|
585
|
+
mask: entry.mask ?? (DEFAULT_MASKS[category] ?? DEFAULT_MASKS.CUSTOM),
|
|
586
|
+
category,
|
|
587
|
+
caseSensitive: Boolean(entry.caseSensitive)
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
var buildTermRegex = (def) => {
|
|
591
|
+
const escaped = escapeRegex(def.term);
|
|
592
|
+
const leadingBoundary = /^\w/.test(def.term) ? "\\b" : "";
|
|
593
|
+
const trailingBoundary = /\w$/.test(def.term) ? "\\b" : "";
|
|
594
|
+
return new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, def.caseSensitive ? "g" : "gi");
|
|
595
|
+
};
|
|
596
|
+
var replaceTermsInText = (initialText, definitions) => {
|
|
597
|
+
let currentText = initialText;
|
|
598
|
+
let totalMaskedCount = 0;
|
|
599
|
+
const matchedTermsSet = /* @__PURE__ */ new Set();
|
|
600
|
+
for (const item of definitions) {
|
|
601
|
+
const regex = buildTermRegex(item);
|
|
602
|
+
let matchCount = 0;
|
|
603
|
+
currentText = currentText.replace(regex, () => {
|
|
604
|
+
matchCount++;
|
|
605
|
+
return item.mask;
|
|
606
|
+
});
|
|
607
|
+
if (matchCount > 0) {
|
|
608
|
+
totalMaskedCount += matchCount;
|
|
609
|
+
matchedTermsSet.add(item.term);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
text: currentText,
|
|
614
|
+
maskedCount: totalMaskedCount,
|
|
615
|
+
matchedTerms: Array.from(matchedTermsSet)
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
var sanitizeCustomTerms = (input, terms) => {
|
|
619
|
+
if (!input || !terms || terms.length === 0) {
|
|
620
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
621
|
+
}
|
|
622
|
+
const normalized = terms.map(resolveTermDefinition).filter((t) => t.term.length > 0).sort((a, b) => b.term.length - a.term.length);
|
|
623
|
+
if (normalized.length === 0) {
|
|
624
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
625
|
+
}
|
|
626
|
+
return replaceTermsInText(input, normalized);
|
|
627
|
+
};
|
|
628
|
+
|
|
565
629
|
// src/secret-guard.ts
|
|
566
630
|
var SECRET_PATTERNS = [
|
|
567
631
|
// 1. Clés privées (RSA, OpenSSH, EC, DSA)
|
|
@@ -642,6 +706,7 @@ var sanitizeSecrets = (input) => {
|
|
|
642
706
|
var applyOutputGuards = (rawOutput, options) => {
|
|
643
707
|
let currentText = rawOutput;
|
|
644
708
|
let piiCount = 0;
|
|
709
|
+
let customTermsCount = 0;
|
|
645
710
|
if (options?.maskPII) {
|
|
646
711
|
const piiResult = sanitizePII(currentText);
|
|
647
712
|
currentText = piiResult.text;
|
|
@@ -649,6 +714,11 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
649
714
|
}
|
|
650
715
|
const secretResult = sanitizeSecrets(currentText);
|
|
651
716
|
currentText = secretResult.text;
|
|
717
|
+
if (options?.customRedactionTerms && options.customRedactionTerms.length > 0) {
|
|
718
|
+
const customResult = sanitizeCustomTerms(currentText, options.customRedactionTerms);
|
|
719
|
+
currentText = customResult.text;
|
|
720
|
+
customTermsCount = customResult.maskedCount;
|
|
721
|
+
}
|
|
652
722
|
if (secretResult.hasSecrets && options?.secretLeakAction === "BLOCK") {
|
|
653
723
|
const types = secretResult.detections.map((d) => d.type).join(", ");
|
|
654
724
|
throw new SecretLeakBlockedError(
|
|
@@ -658,9 +728,10 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
658
728
|
}
|
|
659
729
|
return {
|
|
660
730
|
text: currentText,
|
|
661
|
-
sanitized: piiCount > 0 || secretResult.hasSecrets,
|
|
731
|
+
sanitized: piiCount > 0 || secretResult.hasSecrets || customTermsCount > 0,
|
|
662
732
|
secretDetected: secretResult.hasSecrets,
|
|
663
733
|
piiMaskedCount: piiCount,
|
|
734
|
+
customTermsMaskedCount: customTermsCount,
|
|
664
735
|
detections: secretResult.detections
|
|
665
736
|
};
|
|
666
737
|
};
|
|
@@ -725,21 +796,27 @@ var AvantGateControlLayer = class {
|
|
|
725
796
|
if (!guard.valid) {
|
|
726
797
|
throw new Error(`[AvantGate Security Guard] Request blocked: ${guard.blockedReason}`);
|
|
727
798
|
}
|
|
799
|
+
let processed = userQuery;
|
|
800
|
+
if (this.config.security?.customRedactionTerms && this.config.security.customRedactionTerms.length > 0) {
|
|
801
|
+
processed = sanitizeCustomTerms(processed, this.config.security.customRedactionTerms).text;
|
|
802
|
+
}
|
|
728
803
|
if (this.config.security?.maskPII) {
|
|
729
|
-
return sanitizePII(
|
|
804
|
+
return sanitizePII(processed).text;
|
|
730
805
|
}
|
|
731
|
-
return
|
|
806
|
+
return processed;
|
|
732
807
|
};
|
|
733
808
|
applyOutputSecurityGuards = (rawOutput) => {
|
|
734
809
|
const isDlpEnabled = this.config.security?.outputDLP ?? this.config.security?.maskPII ?? false;
|
|
735
810
|
const shouldCheckSecrets = this.config.security?.blockSecretLeaks ?? true;
|
|
736
|
-
|
|
811
|
+
const customTerms = this.config.security?.customRedactionTerms;
|
|
812
|
+
if (!isDlpEnabled && !shouldCheckSecrets && (!customTerms || customTerms.length === 0)) {
|
|
737
813
|
return rawOutput;
|
|
738
814
|
}
|
|
739
815
|
const guardResult = applyOutputGuards(rawOutput, {
|
|
740
816
|
maskPII: isDlpEnabled,
|
|
741
817
|
blockSecretLeaks: shouldCheckSecrets,
|
|
742
|
-
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT"
|
|
818
|
+
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT",
|
|
819
|
+
customRedactionTerms: customTerms
|
|
743
820
|
});
|
|
744
821
|
return guardResult.text;
|
|
745
822
|
};
|
|
@@ -1444,6 +1521,7 @@ export {
|
|
|
1444
1521
|
isWorkflowAbortSignal,
|
|
1445
1522
|
resolveModelPrice,
|
|
1446
1523
|
resolveModelPriceAsync,
|
|
1524
|
+
sanitizeCustomTerms,
|
|
1447
1525
|
sanitizePII,
|
|
1448
1526
|
sanitizeSecrets,
|
|
1449
1527
|
validateUserInput,
|
package/dist/secret-guard.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { CustomRedactionTermDef } from "./types";
|
|
2
|
+
import { sanitizeCustomTerms, CustomTermsSanitizationResult } from "./custom-terms";
|
|
3
|
+
export { sanitizeCustomTerms, CustomTermsSanitizationResult };
|
|
1
4
|
export interface SecretPatternDef {
|
|
2
5
|
type: string;
|
|
3
6
|
regex: RegExp;
|
|
@@ -17,12 +20,14 @@ export interface OutputGuardOptions {
|
|
|
17
20
|
maskPII?: boolean;
|
|
18
21
|
blockSecretLeaks?: boolean;
|
|
19
22
|
secretLeakAction?: "REDACT" | "BLOCK";
|
|
23
|
+
customRedactionTerms?: Array<string | CustomRedactionTermDef>;
|
|
20
24
|
}
|
|
21
25
|
export interface OutputGuardResult {
|
|
22
26
|
text: string;
|
|
23
27
|
sanitized: boolean;
|
|
24
28
|
secretDetected: boolean;
|
|
25
29
|
piiMaskedCount: number;
|
|
30
|
+
customTermsMaskedCount: number;
|
|
26
31
|
detections: SecretDetection[];
|
|
27
32
|
}
|
|
28
33
|
export declare const applyOutputGuards: (rawOutput: string, options?: OutputGuardOptions) => OutputGuardResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-guard.d.ts","sourceRoot":"","sources":["../src/secret-guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secret-guard.d.ts","sourceRoot":"","sources":["../src/secret-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEzE,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAqDD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,qBA4B/C,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACtC,oBAAoB,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,UAAU,kBAAkB,KAC3B,iBAwCF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -67,6 +67,14 @@ export interface ProviderConfig {
|
|
|
67
67
|
client?: LLMProviderPort;
|
|
68
68
|
pricing?: ModelPrice;
|
|
69
69
|
}
|
|
70
|
+
export type TermCategory = "PROJECT" | "COMPANY" | "INFRA" | "CUSTOM";
|
|
71
|
+
export interface CustomRedactionTermDef {
|
|
72
|
+
id?: string;
|
|
73
|
+
term: string;
|
|
74
|
+
mask?: string;
|
|
75
|
+
category?: TermCategory;
|
|
76
|
+
caseSensitive?: boolean;
|
|
77
|
+
}
|
|
70
78
|
export interface SecurityConfig {
|
|
71
79
|
detectPromptInjection?: boolean;
|
|
72
80
|
maskPII?: boolean;
|
|
@@ -74,6 +82,7 @@ export interface SecurityConfig {
|
|
|
74
82
|
outputDLP?: boolean;
|
|
75
83
|
blockSecretLeaks?: boolean;
|
|
76
84
|
secretLeakAction?: "REDACT" | "BLOCK";
|
|
85
|
+
customRedactionTerms?: Array<string | CustomRedactionTermDef>;
|
|
77
86
|
}
|
|
78
87
|
export interface RetryConfig {
|
|
79
88
|
maxRetries?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ToolExecutionEnvelope } from "./envelope";
|
|
2
|
+
export declare const defineCanvas: <TContentMap extends Record<string, unknown>>() => {
|
|
3
|
+
createEnvelope: <K extends Extract<keyof TContentMap, string>>(options: Omit<ToolExecutionEnvelope<TContentMap[K], K>, "version">) => ToolExecutionEnvelope<TContentMap[K], K>;
|
|
4
|
+
canvasReducer: (currentState: import("./reducer").CanvasState<TContentMap> | null | undefined, envelope: ToolExecutionEnvelope<unknown, Extract<keyof TContentMap, string>>) => import("./reducer").CanvasState<TContentMap>;
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=define-canvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-canvas.d.ts","sourceRoot":"","sources":["../../src/ui/define-canvas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAG5E,eAAO,MAAM,YAAY,GAAI,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;qBAEnD,CAAC,SAAS,OAAO,CAAC,MAAM,WAAW,EAAE,MAAM,CAAC,WAClD,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,KACjE,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;CAM9C,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type ToolMergeStrategy = "REPLACE" | "APPEND_UNIQUE" | "UPDATE_ENTITY";
|
|
2
|
+
export type UIIntentAction = "HIGHLIGHT" | "SELECT" | "OPEN_MODAL" | "NAVIGATE";
|
|
3
|
+
export interface UIIntent {
|
|
4
|
+
action: UIIntentAction;
|
|
5
|
+
targetId: string;
|
|
6
|
+
targetType: "prospect" | "company" | "task" | "event" | string;
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolExecutionEnvelope<TPayload = unknown, TKind extends string = string> {
|
|
10
|
+
readonly version: 1;
|
|
11
|
+
readonly toolId: string;
|
|
12
|
+
readonly kind: TKind;
|
|
13
|
+
readonly mergeStrategy: ToolMergeStrategy;
|
|
14
|
+
readonly dedupeKey?: string;
|
|
15
|
+
readonly uiIntent?: UIIntent;
|
|
16
|
+
readonly data: TPayload;
|
|
17
|
+
}
|
|
18
|
+
export declare const createToolEnvelope: <TKind extends string, TPayload>(options: Omit<ToolExecutionEnvelope<TPayload, TKind>, "version">) => ToolExecutionEnvelope<TPayload, TKind>;
|
|
19
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/ui/envelope.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,eAAe,GAAG,eAAe,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;AAEhF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM;IACtF,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;CACzB;AAED,eAAO,MAAM,kBAAkB,GAAI,KAAK,SAAS,MAAM,EAAE,QAAQ,EAC/D,SAAS,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,KAC/D,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAKvC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createToolEnvelope, type ToolExecutionEnvelope, type ToolMergeStrategy, type UIIntent, type UIIntentAction, } from "./envelope";
|
|
2
|
+
export { createCanvasReducer, isSafeKey, mergeUniqueEntities, updateEntityInPlace, type CanvasContentState, type CanvasState, } from "./reducer";
|
|
3
|
+
export { defineCanvas } from "./define-canvas";
|
|
4
|
+
export { createViewRegistry, type CanvasRendererProps, type CanvasViewComponent, type CanvasViewContext, isValidSafeUrl, } from "./react";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,cAAc,GACf,MAAM,SAAS,CAAC"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/ui/index.ts
|
|
31
|
+
var ui_exports = {};
|
|
32
|
+
__export(ui_exports, {
|
|
33
|
+
createCanvasReducer: () => createCanvasReducer,
|
|
34
|
+
createToolEnvelope: () => createToolEnvelope,
|
|
35
|
+
createViewRegistry: () => createViewRegistry,
|
|
36
|
+
defineCanvas: () => defineCanvas,
|
|
37
|
+
isSafeKey: () => isSafeKey,
|
|
38
|
+
isValidSafeUrl: () => isValidSafeUrl,
|
|
39
|
+
mergeUniqueEntities: () => mergeUniqueEntities,
|
|
40
|
+
updateEntityInPlace: () => updateEntityInPlace
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(ui_exports);
|
|
43
|
+
|
|
44
|
+
// src/ui/envelope.ts
|
|
45
|
+
var createToolEnvelope = (options) => {
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
version: 1,
|
|
48
|
+
...options
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/ui/reducer.ts
|
|
53
|
+
var isSafeKey = (key) => {
|
|
54
|
+
return key !== "__proto__" && key !== "constructor" && key !== "prototype";
|
|
55
|
+
};
|
|
56
|
+
var filterSafeKeys = (source) => {
|
|
57
|
+
const result = {};
|
|
58
|
+
for (const key of Object.keys(source)) {
|
|
59
|
+
if (isSafeKey(key)) {
|
|
60
|
+
result[key] = source[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
var mergeEntityArrays = (prevItems, incomingItems, dedupeKey) => {
|
|
66
|
+
const seenKeys = new Set(
|
|
67
|
+
prevItems.filter((item) => item && typeof item === "object" && dedupeKey in item).map((item) => String(item[dedupeKey]))
|
|
68
|
+
);
|
|
69
|
+
const uniqueIncoming = incomingItems.filter((item) => {
|
|
70
|
+
const keyVal = item && typeof item === "object" ? String(item[dedupeKey]) : null;
|
|
71
|
+
if (!keyVal || seenKeys.has(keyVal)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
seenKeys.add(keyVal);
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
return [...prevItems, ...uniqueIncoming];
|
|
78
|
+
};
|
|
79
|
+
var mergeUniqueEntities = (prevContent, data, dedupeKey) => {
|
|
80
|
+
if (Array.isArray(data) && Array.isArray(prevContent)) {
|
|
81
|
+
return mergeEntityArrays(prevContent, data, dedupeKey);
|
|
82
|
+
}
|
|
83
|
+
if (!data || typeof data !== "object") {
|
|
84
|
+
return { ...prevContent };
|
|
85
|
+
}
|
|
86
|
+
const result = filterSafeKeys(prevContent);
|
|
87
|
+
const safeData = filterSafeKeys(data);
|
|
88
|
+
for (const key of Object.keys(safeData)) {
|
|
89
|
+
const incoming = safeData[key];
|
|
90
|
+
const prev = result[key];
|
|
91
|
+
result[key] = Array.isArray(incoming) && Array.isArray(prev) ? mergeEntityArrays(prev, incoming, dedupeKey) : incoming;
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
var updateEntityInArray = (items, data, dedupeKey) => {
|
|
96
|
+
let updated = false;
|
|
97
|
+
const targetId = String(data[dedupeKey]);
|
|
98
|
+
const newItems = items.map((item) => {
|
|
99
|
+
if (item && typeof item === "object" && String(item[dedupeKey]) === targetId) {
|
|
100
|
+
updated = true;
|
|
101
|
+
return { ...item, ...filterSafeKeys(data) };
|
|
102
|
+
}
|
|
103
|
+
return item;
|
|
104
|
+
});
|
|
105
|
+
return { updated, items: newItems };
|
|
106
|
+
};
|
|
107
|
+
var updateInternalArray = (target, safeData, dedupeKey) => {
|
|
108
|
+
for (const key of Object.keys(target)) {
|
|
109
|
+
if (!Array.isArray(target[key])) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const { updated, items } = updateEntityInArray(target[key], safeData, dedupeKey);
|
|
113
|
+
if (updated) {
|
|
114
|
+
target[key] = items;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
var updateEntityInPlace = (prevContent, data, dedupeKey) => {
|
|
121
|
+
if (!data || typeof data !== "object") {
|
|
122
|
+
return { ...prevContent };
|
|
123
|
+
}
|
|
124
|
+
const safeData = filterSafeKeys(data);
|
|
125
|
+
if (Array.isArray(prevContent)) {
|
|
126
|
+
return updateEntityInArray(prevContent, safeData, dedupeKey).items;
|
|
127
|
+
}
|
|
128
|
+
const result = filterSafeKeys(prevContent);
|
|
129
|
+
const targetId = safeData[dedupeKey] !== void 0 ? String(safeData[dedupeKey]) : null;
|
|
130
|
+
if (targetId && String(result[dedupeKey]) === targetId) {
|
|
131
|
+
return { ...result, ...safeData };
|
|
132
|
+
}
|
|
133
|
+
updateInternalArray(result, safeData, dedupeKey);
|
|
134
|
+
return result;
|
|
135
|
+
};
|
|
136
|
+
var createCanvasReducer = () => {
|
|
137
|
+
return (currentState, envelope) => {
|
|
138
|
+
const { kind, mergeStrategy, dedupeKey = "id", data, uiIntent } = envelope;
|
|
139
|
+
const prevContent = currentState?.content;
|
|
140
|
+
if (!prevContent || prevContent.kind !== kind || mergeStrategy === "REPLACE") {
|
|
141
|
+
return {
|
|
142
|
+
content: { kind, ...filterSafeKeys(data || {}) },
|
|
143
|
+
activeIntent: uiIntent
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (mergeStrategy === "APPEND_UNIQUE") {
|
|
147
|
+
return {
|
|
148
|
+
content: { kind, ...mergeUniqueEntities(prevContent, data, dedupeKey) },
|
|
149
|
+
activeIntent: uiIntent
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (mergeStrategy === "UPDATE_ENTITY") {
|
|
153
|
+
return {
|
|
154
|
+
content: { kind, ...updateEntityInPlace(prevContent, data, dedupeKey) },
|
|
155
|
+
activeIntent: uiIntent
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
content: prevContent,
|
|
160
|
+
activeIntent: uiIntent ?? currentState?.activeIntent
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/ui/define-canvas.ts
|
|
166
|
+
var defineCanvas = () => {
|
|
167
|
+
return {
|
|
168
|
+
createEnvelope: (options) => {
|
|
169
|
+
return createToolEnvelope(options);
|
|
170
|
+
},
|
|
171
|
+
canvasReducer: createCanvasReducer()
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// src/ui/react/create-view-registry.ts
|
|
176
|
+
var import_react = __toESM(require("react"));
|
|
177
|
+
var createViewRegistry = (registry) => {
|
|
178
|
+
const CanvasRenderer = ({
|
|
179
|
+
state,
|
|
180
|
+
context = {}
|
|
181
|
+
}) => {
|
|
182
|
+
if (!state?.content) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
const kind = state.content.kind;
|
|
186
|
+
const Component = registry[kind];
|
|
187
|
+
if (!Component) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return import_react.default.createElement(Component, {
|
|
191
|
+
data: state.content,
|
|
192
|
+
context,
|
|
193
|
+
activeIntent: state.activeIntent
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
registry,
|
|
198
|
+
CanvasRenderer
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// src/ui/react/sanitize.ts
|
|
203
|
+
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
204
|
+
var isValidSafeUrl = (rawUrl) => {
|
|
205
|
+
if (!rawUrl || typeof rawUrl !== "string") {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const trimmed = rawUrl.trim();
|
|
209
|
+
if (!trimmed) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (trimmed.startsWith("#")) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const parsed = new URL(trimmed);
|
|
220
|
+
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
221
|
+
} catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
226
|
+
0 && (module.exports = {
|
|
227
|
+
createCanvasReducer,
|
|
228
|
+
createToolEnvelope,
|
|
229
|
+
createViewRegistry,
|
|
230
|
+
defineCanvas,
|
|
231
|
+
isSafeKey,
|
|
232
|
+
isValidSafeUrl,
|
|
233
|
+
mergeUniqueEntities,
|
|
234
|
+
updateEntityInPlace
|
|
235
|
+
});
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createViewRegistry,
|
|
3
|
+
isValidSafeUrl
|
|
4
|
+
} from "../chunk-Z6QOMLZ2.mjs";
|
|
5
|
+
import "../chunk-Y6FXYEAI.mjs";
|
|
6
|
+
|
|
7
|
+
// src/ui/envelope.ts
|
|
8
|
+
var createToolEnvelope = (options) => {
|
|
9
|
+
return Object.freeze({
|
|
10
|
+
version: 1,
|
|
11
|
+
...options
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// src/ui/reducer.ts
|
|
16
|
+
var isSafeKey = (key) => {
|
|
17
|
+
return key !== "__proto__" && key !== "constructor" && key !== "prototype";
|
|
18
|
+
};
|
|
19
|
+
var filterSafeKeys = (source) => {
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const key of Object.keys(source)) {
|
|
22
|
+
if (isSafeKey(key)) {
|
|
23
|
+
result[key] = source[key];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
var mergeEntityArrays = (prevItems, incomingItems, dedupeKey) => {
|
|
29
|
+
const seenKeys = new Set(
|
|
30
|
+
prevItems.filter((item) => item && typeof item === "object" && dedupeKey in item).map((item) => String(item[dedupeKey]))
|
|
31
|
+
);
|
|
32
|
+
const uniqueIncoming = incomingItems.filter((item) => {
|
|
33
|
+
const keyVal = item && typeof item === "object" ? String(item[dedupeKey]) : null;
|
|
34
|
+
if (!keyVal || seenKeys.has(keyVal)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
seenKeys.add(keyVal);
|
|
38
|
+
return true;
|
|
39
|
+
});
|
|
40
|
+
return [...prevItems, ...uniqueIncoming];
|
|
41
|
+
};
|
|
42
|
+
var mergeUniqueEntities = (prevContent, data, dedupeKey) => {
|
|
43
|
+
if (Array.isArray(data) && Array.isArray(prevContent)) {
|
|
44
|
+
return mergeEntityArrays(prevContent, data, dedupeKey);
|
|
45
|
+
}
|
|
46
|
+
if (!data || typeof data !== "object") {
|
|
47
|
+
return { ...prevContent };
|
|
48
|
+
}
|
|
49
|
+
const result = filterSafeKeys(prevContent);
|
|
50
|
+
const safeData = filterSafeKeys(data);
|
|
51
|
+
for (const key of Object.keys(safeData)) {
|
|
52
|
+
const incoming = safeData[key];
|
|
53
|
+
const prev = result[key];
|
|
54
|
+
result[key] = Array.isArray(incoming) && Array.isArray(prev) ? mergeEntityArrays(prev, incoming, dedupeKey) : incoming;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
var updateEntityInArray = (items, data, dedupeKey) => {
|
|
59
|
+
let updated = false;
|
|
60
|
+
const targetId = String(data[dedupeKey]);
|
|
61
|
+
const newItems = items.map((item) => {
|
|
62
|
+
if (item && typeof item === "object" && String(item[dedupeKey]) === targetId) {
|
|
63
|
+
updated = true;
|
|
64
|
+
return { ...item, ...filterSafeKeys(data) };
|
|
65
|
+
}
|
|
66
|
+
return item;
|
|
67
|
+
});
|
|
68
|
+
return { updated, items: newItems };
|
|
69
|
+
};
|
|
70
|
+
var updateInternalArray = (target, safeData, dedupeKey) => {
|
|
71
|
+
for (const key of Object.keys(target)) {
|
|
72
|
+
if (!Array.isArray(target[key])) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const { updated, items } = updateEntityInArray(target[key], safeData, dedupeKey);
|
|
76
|
+
if (updated) {
|
|
77
|
+
target[key] = items;
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
};
|
|
83
|
+
var updateEntityInPlace = (prevContent, data, dedupeKey) => {
|
|
84
|
+
if (!data || typeof data !== "object") {
|
|
85
|
+
return { ...prevContent };
|
|
86
|
+
}
|
|
87
|
+
const safeData = filterSafeKeys(data);
|
|
88
|
+
if (Array.isArray(prevContent)) {
|
|
89
|
+
return updateEntityInArray(prevContent, safeData, dedupeKey).items;
|
|
90
|
+
}
|
|
91
|
+
const result = filterSafeKeys(prevContent);
|
|
92
|
+
const targetId = safeData[dedupeKey] !== void 0 ? String(safeData[dedupeKey]) : null;
|
|
93
|
+
if (targetId && String(result[dedupeKey]) === targetId) {
|
|
94
|
+
return { ...result, ...safeData };
|
|
95
|
+
}
|
|
96
|
+
updateInternalArray(result, safeData, dedupeKey);
|
|
97
|
+
return result;
|
|
98
|
+
};
|
|
99
|
+
var createCanvasReducer = () => {
|
|
100
|
+
return (currentState, envelope) => {
|
|
101
|
+
const { kind, mergeStrategy, dedupeKey = "id", data, uiIntent } = envelope;
|
|
102
|
+
const prevContent = currentState?.content;
|
|
103
|
+
if (!prevContent || prevContent.kind !== kind || mergeStrategy === "REPLACE") {
|
|
104
|
+
return {
|
|
105
|
+
content: { kind, ...filterSafeKeys(data || {}) },
|
|
106
|
+
activeIntent: uiIntent
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (mergeStrategy === "APPEND_UNIQUE") {
|
|
110
|
+
return {
|
|
111
|
+
content: { kind, ...mergeUniqueEntities(prevContent, data, dedupeKey) },
|
|
112
|
+
activeIntent: uiIntent
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (mergeStrategy === "UPDATE_ENTITY") {
|
|
116
|
+
return {
|
|
117
|
+
content: { kind, ...updateEntityInPlace(prevContent, data, dedupeKey) },
|
|
118
|
+
activeIntent: uiIntent
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
content: prevContent,
|
|
123
|
+
activeIntent: uiIntent ?? currentState?.activeIntent
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// src/ui/define-canvas.ts
|
|
129
|
+
var defineCanvas = () => {
|
|
130
|
+
return {
|
|
131
|
+
createEnvelope: (options) => {
|
|
132
|
+
return createToolEnvelope(options);
|
|
133
|
+
},
|
|
134
|
+
canvasReducer: createCanvasReducer()
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
createCanvasReducer,
|
|
139
|
+
createToolEnvelope,
|
|
140
|
+
createViewRegistry,
|
|
141
|
+
defineCanvas,
|
|
142
|
+
isSafeKey,
|
|
143
|
+
isValidSafeUrl,
|
|
144
|
+
mergeUniqueEntities,
|
|
145
|
+
updateEntityInPlace
|
|
146
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { UIIntent } from "../envelope";
|
|
3
|
+
import type { CanvasState } from "../reducer";
|
|
4
|
+
export interface CanvasViewContext {
|
|
5
|
+
onSendMessage?: (prompt: string) => void;
|
|
6
|
+
onSelectEntity?: (id: string, type?: string) => void;
|
|
7
|
+
isAgentBusy?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type CanvasViewComponent<TData> = React.FC<{
|
|
10
|
+
data: TData;
|
|
11
|
+
context: CanvasViewContext;
|
|
12
|
+
activeIntent?: UIIntent;
|
|
13
|
+
}>;
|
|
14
|
+
export interface CanvasRendererProps<TContentMap extends Record<string, unknown>> {
|
|
15
|
+
state: CanvasState<TContentMap> | null | undefined;
|
|
16
|
+
context?: CanvasViewContext;
|
|
17
|
+
}
|
|
18
|
+
export declare const createViewRegistry: <TContentMap extends Record<string, unknown>>(registry: { [K in keyof TContentMap]: CanvasViewComponent<TContentMap[K]>; }) => {
|
|
19
|
+
registry: { [K in keyof TContentMap]: CanvasViewComponent<TContentMap[K]>; };
|
|
20
|
+
CanvasRenderer: React.FC<CanvasRendererProps<TContentMap>>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=create-view-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-view-registry.d.ts","sourceRoot":"","sources":["../../../src/ui/react/create-view-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC;IAChD,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,iBAAiB,CAAC;IAC3B,YAAY,CAAC,EAAE,QAAQ,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,WAAW,mBAAmB,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9E,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,eAAO,MAAM,kBAAkB,GAAI,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,UAAU,GAAG,CAAC,IAAI,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAE;iBAA9D,CAAC;;CA4Bf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/ui/react/index.ts
|
|
31
|
+
var react_exports = {};
|
|
32
|
+
__export(react_exports, {
|
|
33
|
+
createViewRegistry: () => createViewRegistry,
|
|
34
|
+
isValidSafeUrl: () => isValidSafeUrl
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(react_exports);
|
|
37
|
+
|
|
38
|
+
// src/ui/react/create-view-registry.ts
|
|
39
|
+
var import_react = __toESM(require("react"));
|
|
40
|
+
var createViewRegistry = (registry) => {
|
|
41
|
+
const CanvasRenderer = ({
|
|
42
|
+
state,
|
|
43
|
+
context = {}
|
|
44
|
+
}) => {
|
|
45
|
+
if (!state?.content) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const kind = state.content.kind;
|
|
49
|
+
const Component = registry[kind];
|
|
50
|
+
if (!Component) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return import_react.default.createElement(Component, {
|
|
54
|
+
data: state.content,
|
|
55
|
+
context,
|
|
56
|
+
activeIntent: state.activeIntent
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
registry,
|
|
61
|
+
CanvasRenderer
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/ui/react/sanitize.ts
|
|
66
|
+
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
67
|
+
var isValidSafeUrl = (rawUrl) => {
|
|
68
|
+
if (!rawUrl || typeof rawUrl !== "string") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const trimmed = rawUrl.trim();
|
|
72
|
+
if (!trimmed) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if (trimmed.startsWith("#")) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const parsed = new URL(trimmed);
|
|
83
|
+
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
89
|
+
0 && (module.exports = {
|
|
90
|
+
createViewRegistry,
|
|
91
|
+
isValidSafeUrl
|
|
92
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/ui/react/sanitize.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OAwBlE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolExecutionEnvelope, UIIntent } from "./envelope";
|
|
2
|
+
export type CanvasContentState<TContentMap extends Record<string, unknown>> = {
|
|
3
|
+
[K in keyof TContentMap]: {
|
|
4
|
+
kind: K;
|
|
5
|
+
} & TContentMap[K];
|
|
6
|
+
}[keyof TContentMap] | null;
|
|
7
|
+
export interface CanvasState<TContentMap extends Record<string, unknown>> {
|
|
8
|
+
content: CanvasContentState<TContentMap>;
|
|
9
|
+
activeIntent?: UIIntent;
|
|
10
|
+
}
|
|
11
|
+
export declare const isSafeKey: (key: string) => boolean;
|
|
12
|
+
export declare const mergeUniqueEntities: (prevContent: Record<string, any>, data: any, dedupeKey: string) => Record<string, any>;
|
|
13
|
+
export declare const updateEntityInPlace: (prevContent: Record<string, any>, data: any, dedupeKey: string) => Record<string, any>;
|
|
14
|
+
export declare const createCanvasReducer: <TContentMap extends Record<string, unknown>>() => (currentState: CanvasState<TContentMap> | null | undefined, envelope: ToolExecutionEnvelope<unknown, Extract<keyof TContentMap, string>>) => CanvasState<TContentMap>;
|
|
15
|
+
//# sourceMappingURL=reducer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/ui/reducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,kBAAkB,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KAC3E,CAAC,IAAI,MAAM,WAAW,GAAG;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,GAAG,WAAW,CAAC,CAAC,CAAC;CACvD,CAAC,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC;AAE5B,MAAM,WAAW,WAAW,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtE,OAAO,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,KAAG,OAEvC,CAAC;AAmCF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,MAAM,GAAG,EACT,WAAW,MAAM,KAChB,MAAM,CAAC,MAAM,EAAE,GAAG,CAoBpB,CAAC;AAuCF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,MAAM,GAAG,EACT,WAAW,MAAM,KAChB,MAAM,CAAC,MAAM,EAAE,GAAG,CAmBpB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAE3E,cAAc,WAAW,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS,EACzD,UAAU,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,WAAW,EAAE,MAAM,CAAC,CAAC,KAC3E,WAAW,CAAC,WAAW,CA8B3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avantgate",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Zero-infrastructure, in-process AI Application Firewall (AI-WAF)
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"description": "Zero-infrastructure, in-process AI Application Firewall (AI-WAF), privacy control plane & headless UI canvas for TypeScript: real-time prompt guardrails, zero-egress PII redaction, deterministic tool envelopes, anti-IDOR defense, pre-flight token budgets, and multi-model failover.",
|
|
5
5
|
"author": "Gatewall Team",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"llm",
|
|
17
17
|
"ai",
|
|
18
18
|
"agent",
|
|
19
|
+
"canvas",
|
|
20
|
+
"headless-ui",
|
|
21
|
+
"tool-envelope",
|
|
22
|
+
"copilot-ui",
|
|
19
23
|
"dual-channel",
|
|
20
24
|
"tool-governance",
|
|
21
25
|
"blast-radius",
|
|
@@ -65,6 +69,16 @@
|
|
|
65
69
|
"import": "./dist/client/index.mjs",
|
|
66
70
|
"require": "./dist/client/index.js"
|
|
67
71
|
},
|
|
72
|
+
"./ui/react": {
|
|
73
|
+
"types": "./dist/ui/react/index.d.ts",
|
|
74
|
+
"import": "./dist/ui/react/index.mjs",
|
|
75
|
+
"require": "./dist/ui/react/index.js"
|
|
76
|
+
},
|
|
77
|
+
"./ui": {
|
|
78
|
+
"types": "./dist/ui/index.d.ts",
|
|
79
|
+
"import": "./dist/ui/index.mjs",
|
|
80
|
+
"require": "./dist/ui/index.js"
|
|
81
|
+
},
|
|
68
82
|
"./package.json": "./package.json"
|
|
69
83
|
},
|
|
70
84
|
"peerDependencies": {
|
|
@@ -81,8 +95,9 @@
|
|
|
81
95
|
"LICENSE"
|
|
82
96
|
],
|
|
83
97
|
"scripts": {
|
|
84
|
-
"build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts src/workflow/index.ts src/client/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
|
|
85
|
-
"test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/sqlite-pricing-adapter.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && tsx tests/output-dlp-secret-guard.test.ts && npm run test:agent && npm run test:workflow && npm run test:client",
|
|
98
|
+
"build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts src/workflow/index.ts src/client/index.ts src/ui/index.ts src/ui/react/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
|
|
99
|
+
"test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/sqlite-pricing-adapter.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && tsx tests/output-dlp-secret-guard.test.ts && npm run test:agent && npm run test:workflow && npm run test:client && npm run test:ui",
|
|
100
|
+
"test:ui": "tsx tests/ui/envelope.test.ts && tsx tests/ui/reducer.test.ts && tsx tests/ui/sanitize.test.ts && tsx tests/ui/react-registry.test.tsx",
|
|
86
101
|
"test:secrets": "tsx tests/output-dlp-secret-guard.test.ts",
|
|
87
102
|
"test:pricing": "tsx tests/sqlite-pricing-adapter.test.ts",
|
|
88
103
|
"test:finance": "tsx tests/financial-normalizer.test.ts",
|
|
@@ -92,12 +107,6 @@
|
|
|
92
107
|
"test:workflow": "tsx tests/workflow/workflow-saga.test.ts && tsx tests/workflow/workflow-abort.test.ts",
|
|
93
108
|
"test:client": "tsx tests/client/browser-exporter.test.ts && tsx tests/client/use-avantgate-task.test.ts && tsx tests/client/task-runner.test.ts",
|
|
94
109
|
"test:demo": "tsx tests/agent/prospect-ai-demo-scenario.test.ts",
|
|
95
|
-
"gatewall": "npm --prefix gatewall run dev",
|
|
96
|
-
"gatewall:dev": "npm --prefix gatewall run dev",
|
|
97
|
-
"gatewall:build": "npm --prefix gatewall run build",
|
|
98
|
-
"gatewall:seed": "npm --prefix gatewall run seed:mock",
|
|
99
|
-
"gatewall:start": "npm --prefix gatewall run start",
|
|
100
|
-
"gatewall:docker": "docker compose up -d",
|
|
101
110
|
"lint": "tsc --noEmit",
|
|
102
111
|
"prepublishOnly": "npm run build && npm test"
|
|
103
112
|
},
|
|
@@ -124,3 +133,4 @@
|
|
|
124
133
|
"url": "https://github.com/thienban/avantGate/issues"
|
|
125
134
|
}
|
|
126
135
|
}
|
|
136
|
+
|