@gethelio/proxy 0.13.1 → 0.14.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 +7 -1
- package/dist/cli.js +774 -152
- package/dist/dashboard-assets/assets/{index-BRvkMXWl.js → index-D9zeFAzU.js} +2 -2
- package/dist/dashboard-assets/index.html +1 -1
- package/dist/index.d.ts +75 -9
- package/dist/index.js +167 -77
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="referrer" content="no-referrer" />
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
8
8
|
<title>Helio Dashboard</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-D9zeFAzU.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-DtnT1Y9r.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
package/dist/index.d.ts
CHANGED
|
@@ -735,6 +735,10 @@ declare class ConfigError extends Error {
|
|
|
735
735
|
*/
|
|
736
736
|
declare function loadConfig(filePath: string, env?: Record<string, string | undefined>): Promise<HelioConfig>;
|
|
737
737
|
|
|
738
|
+
/** Every outcome a reload attempt can record. `watch_failed` means the watch itself failed; nothing was read. */
|
|
739
|
+
declare const POLICY_RELOAD_OUTCOMES: readonly ["applied", "rejected_invalid", "rejected_unroutable", "rejected_budget_flush", "rejected_pinned", "watch_failed"];
|
|
740
|
+
type PolicyReloadOutcome = (typeof POLICY_RELOAD_OUTCOMES)[number];
|
|
741
|
+
|
|
738
742
|
/** Pre-compiled glob matcher for tool names. */
|
|
739
743
|
interface ToolMatcher {
|
|
740
744
|
/** Original glob pattern string (e.g. "send_*") for audit/logging. */
|
|
@@ -1461,9 +1465,12 @@ interface AuditRecord {
|
|
|
1461
1465
|
* records; `'install_scan'` for sideband install evaluations; and
|
|
1462
1466
|
* `'evaluation_expired'` for sideband evaluations whose `/audit` never
|
|
1463
1467
|
* arrived (the bypass/tamper signal — block_reason stays null so they do not
|
|
1464
|
-
* count as enforcement blocks)
|
|
1468
|
+
* count as enforcement blocks); and `'policy_reload'` for a config reload
|
|
1469
|
+
* attempt the proxy records about itself (issue #341): the outcome is in
|
|
1470
|
+
* `block_reason` and under `evidence_chain.policy_reload`, and the decision
|
|
1471
|
+
* column holds the constant `policy_reload` so analytics can exclude the kind.
|
|
1465
1472
|
*/
|
|
1466
|
-
readonly record_kind: 'tool_call' | 'drift_event' | 'install_scan' | 'evaluation_expired';
|
|
1473
|
+
readonly record_kind: 'tool_call' | 'drift_event' | 'install_scan' | 'evaluation_expired' | 'policy_reload';
|
|
1467
1474
|
/**
|
|
1468
1475
|
* Enforcement origin: `'mcp'` for the proxy path, or an adapter-supplied
|
|
1469
1476
|
* origin string (e.g. `'openclaw'`) for sideband-governed calls. Surfaces
|
|
@@ -1492,9 +1499,20 @@ interface AuditRecord {
|
|
|
1492
1499
|
* could silently omit it would exempt that door from attribution.
|
|
1493
1500
|
*/
|
|
1494
1501
|
readonly upstream: string | null;
|
|
1502
|
+
/**
|
|
1503
|
+
* SHA-256 (lowercase hex) of the config file bytes in force when the
|
|
1504
|
+
* record was written (issue #341); the value `helio config hash` prints.
|
|
1505
|
+
* Stamped by the writer, never by a record builder. Null on rows written
|
|
1506
|
+
* before the column existed.
|
|
1507
|
+
*/
|
|
1508
|
+
readonly config_sha256: string | null;
|
|
1495
1509
|
/** ISO 8601 timestamp of when the record was persisted. */
|
|
1496
1510
|
readonly created_at: string;
|
|
1497
1511
|
}
|
|
1512
|
+
/** What a record builder produces: the stored shape without the ids and with the writer-stamped hash optional. */
|
|
1513
|
+
type AuditRecordInput = Omit<AuditRecord, 'id' | 'created_at' | 'config_sha256'> & {
|
|
1514
|
+
readonly config_sha256?: string | null;
|
|
1515
|
+
};
|
|
1498
1516
|
/** Fields available for filtering audit record queries. */
|
|
1499
1517
|
interface AuditQueryFilters {
|
|
1500
1518
|
/** Filter by tool name (exact match). */
|
|
@@ -1687,7 +1705,7 @@ declare class AuditStore {
|
|
|
1687
1705
|
* @param createdAt - Optional override for the created_at timestamp (for testing).
|
|
1688
1706
|
* @param id - Optional pre-generated ID (used by AuditWriter to share ID with SSE event bus).
|
|
1689
1707
|
*/
|
|
1690
|
-
insert(record:
|
|
1708
|
+
insert(record: AuditRecordInput, createdAt?: string, id?: string): string;
|
|
1691
1709
|
/**
|
|
1692
1710
|
* Insert multiple audit records in a single SQLite transaction.
|
|
1693
1711
|
*
|
|
@@ -1703,7 +1721,7 @@ declare class AuditStore {
|
|
|
1703
1721
|
* the SSE event bus before the record is persisted.
|
|
1704
1722
|
* @returns The number of records successfully inserted.
|
|
1705
1723
|
*/
|
|
1706
|
-
insertBatch(records: ReadonlyArray<
|
|
1724
|
+
insertBatch(records: ReadonlyArray<AuditRecordInput>, onError?: (record: AuditRecordInput, err: unknown) => void, ids?: ReadonlyArray<string>, onPersist?: (record: AuditRecordInput, id: string) => void): number;
|
|
1707
1725
|
/** Get a single record by ID, or undefined if not found. */
|
|
1708
1726
|
get(id: string): AuditRecord | undefined;
|
|
1709
1727
|
/** Query records with filters and pagination. Capped at 1,000 per page. */
|
|
@@ -1743,9 +1761,11 @@ interface AuditWriterOptions {
|
|
|
1743
1761
|
/** Max milliseconds between flushes (default: 100). */
|
|
1744
1762
|
readonly flushIntervalMs?: number;
|
|
1745
1763
|
/** Optional callback invoked when a record enters the in-memory buffer. */
|
|
1746
|
-
readonly onPush?: (record:
|
|
1764
|
+
readonly onPush?: (record: AuditRecordInput, id: string) => void;
|
|
1747
1765
|
/** Optional callback invoked after a record is successfully persisted. */
|
|
1748
|
-
readonly onPersist?: (record:
|
|
1766
|
+
readonly onPersist?: (record: AuditRecordInput, id: string) => void;
|
|
1767
|
+
/** The hash of the config in force at construction; every record that leaves `config_sha256` nullish is stamped with the current value. */
|
|
1768
|
+
readonly configSha256?: string;
|
|
1749
1769
|
}
|
|
1750
1770
|
/**
|
|
1751
1771
|
* Async buffered audit record writer.
|
|
@@ -1759,6 +1779,15 @@ declare class AuditWriter {
|
|
|
1759
1779
|
private readonly bufferSize;
|
|
1760
1780
|
private readonly onPush;
|
|
1761
1781
|
private readonly onPersist;
|
|
1782
|
+
/**
|
|
1783
|
+
* The hash of the config file in force (issue #341), stamped onto every
|
|
1784
|
+
* record whose builder left `config_sha256` nullish. Seeded at
|
|
1785
|
+
* construction so no record is pushed unstamped before the first
|
|
1786
|
+
* `setConfigSha256`; replaced by the reload path once the new policy is
|
|
1787
|
+
* in force. Null only when the caller never had a hash (library
|
|
1788
|
+
* embeddings without a config file).
|
|
1789
|
+
*/
|
|
1790
|
+
private configSha256;
|
|
1762
1791
|
private buffer;
|
|
1763
1792
|
private timer;
|
|
1764
1793
|
private flushSoonTimer;
|
|
@@ -1774,7 +1803,7 @@ declare class AuditWriter {
|
|
|
1774
1803
|
* is scheduled. This keeps request-path latency bounded even under bursty
|
|
1775
1804
|
* write load.
|
|
1776
1805
|
*/
|
|
1777
|
-
push(
|
|
1806
|
+
push(input: AuditRecordInput, id?: string): void;
|
|
1778
1807
|
/**
|
|
1779
1808
|
* Push a record and schedule a high-priority async flush.
|
|
1780
1809
|
*
|
|
@@ -1783,7 +1812,20 @@ declare class AuditWriter {
|
|
|
1783
1812
|
* A fatal-process crash still invokes the crash-drain hook, which calls
|
|
1784
1813
|
* `flush()` synchronously before exit.
|
|
1785
1814
|
*/
|
|
1786
|
-
pushImmediate(
|
|
1815
|
+
pushImmediate(input: AuditRecordInput, id?: string): void;
|
|
1816
|
+
/**
|
|
1817
|
+
* Replace the config hash every later record is stamped with. Called by
|
|
1818
|
+
* the reload path after the new policy is in force, before the reload's
|
|
1819
|
+
* own record is pushed, so the reload record and every call it governs
|
|
1820
|
+
* carry the new hash.
|
|
1821
|
+
*/
|
|
1822
|
+
setConfigSha256(hash: string): void;
|
|
1823
|
+
/**
|
|
1824
|
+
* Stamp the active config hash onto a record whose builder left the field
|
|
1825
|
+
* nullish; a record that already carries a hash is passed through. The
|
|
1826
|
+
* stamped record is what `onPush`, the store, and `onPersist` see.
|
|
1827
|
+
*/
|
|
1828
|
+
private stamp;
|
|
1787
1829
|
/**
|
|
1788
1830
|
* Schedule a flush on the next tick, coalescing multiple calls into one.
|
|
1789
1831
|
*/
|
|
@@ -3463,7 +3505,23 @@ declare class GovernanceConfigError extends Error {
|
|
|
3463
3505
|
* reserved `'<header_mismatch>'` sentinel — either way `top_tools` already
|
|
3464
3506
|
* excludes rejected records, so these rows never pollute tool rankings.
|
|
3465
3507
|
*/
|
|
3466
|
-
declare function buildHeaderMismatchAuditRecord(rejection: HeaderMismatchRejection, environment?: string, upstream?: string):
|
|
3508
|
+
declare function buildHeaderMismatchAuditRecord(rejection: HeaderMismatchRejection, environment?: string, upstream?: string): AuditRecordInput;
|
|
3509
|
+
|
|
3510
|
+
interface PolicyReloadEvidence {
|
|
3511
|
+
readonly outcome: PolicyReloadOutcome;
|
|
3512
|
+
readonly config_path: string;
|
|
3513
|
+
readonly sha256_before: string;
|
|
3514
|
+
readonly sha256_after: string | null;
|
|
3515
|
+
readonly rule_count_before: number;
|
|
3516
|
+
readonly rule_count_after: number | null;
|
|
3517
|
+
readonly default_action_before: 'allow' | 'deny';
|
|
3518
|
+
readonly default_action_after: 'allow' | 'deny' | null;
|
|
3519
|
+
readonly budget_count_before: number;
|
|
3520
|
+
readonly budget_count_after: number | null;
|
|
3521
|
+
readonly rules_removed: readonly string[];
|
|
3522
|
+
readonly restart_required_paths: readonly string[];
|
|
3523
|
+
readonly error: string | null;
|
|
3524
|
+
}
|
|
3467
3525
|
|
|
3468
3526
|
/** @internal Exported for testing only. */
|
|
3469
3527
|
declare class QueueChannel implements ApprovalChannel {
|
|
@@ -3659,6 +3717,13 @@ type BudgetUpdateEvent = BudgetCommitEvent;
|
|
|
3659
3717
|
* engine's breach-event DTO.
|
|
3660
3718
|
*/
|
|
3661
3719
|
type BudgetBreachedEvent = BudgetBreachEvent;
|
|
3720
|
+
/** A policy reload attempt, emitted beside the record's own `action` event (issue #341). */
|
|
3721
|
+
interface PolicyReloadEvent extends PolicyReloadEvidence {
|
|
3722
|
+
/** The audit record's id. */
|
|
3723
|
+
readonly id: string;
|
|
3724
|
+
/** The record's timestamp. */
|
|
3725
|
+
readonly at: string;
|
|
3726
|
+
}
|
|
3662
3727
|
/** Map of event type names to their payload types. */
|
|
3663
3728
|
interface DashboardEvents {
|
|
3664
3729
|
action: ActionEvent;
|
|
@@ -3668,6 +3733,7 @@ interface DashboardEvents {
|
|
|
3668
3733
|
approval_notification_failed: ApprovalNotificationFailedEvent;
|
|
3669
3734
|
budget_update: BudgetUpdateEvent;
|
|
3670
3735
|
budget_breached: BudgetBreachedEvent;
|
|
3736
|
+
policy_reload: PolicyReloadEvent;
|
|
3671
3737
|
}
|
|
3672
3738
|
/** Union of all dashboard event type names. */
|
|
3673
3739
|
type DashboardEventType = keyof DashboardEvents;
|