@intutic/shared-types 2.2.0 → 2.4.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/dist/anomaly.d.ts +6 -10
- package/dist/anomaly.d.ts.map +1 -1
- package/dist/anomaly.js +0 -2
- package/dist/anomaly.js.map +1 -1
- package/dist/api-contracts.d.ts +1 -1
- package/dist/api-contracts.js +1 -1
- package/dist/attenuation.d.ts +1 -1
- package/dist/attenuation.js +1 -1
- package/dist/auth.d.ts +116 -9
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +20 -5
- package/dist/auth.js.map +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/billing.js +1 -1
- package/dist/cloudProbe.d.ts +54 -0
- package/dist/cloudProbe.d.ts.map +1 -0
- package/dist/cloudProbe.js +254 -0
- package/dist/cloudProbe.js.map +1 -0
- package/dist/destructiveSql.d.ts +48 -0
- package/dist/destructiveSql.d.ts.map +1 -0
- package/dist/destructiveSql.js +43 -0
- package/dist/destructiveSql.js.map +1 -0
- package/dist/devInventory.d.ts +120 -0
- package/dist/devInventory.d.ts.map +1 -0
- package/dist/devInventory.js +80 -0
- package/dist/devInventory.js.map +1 -0
- package/dist/enums.d.ts +66 -21
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +55 -31
- package/dist/enums.js.map +1 -1
- package/dist/errors.js +3 -3
- package/dist/errors.js.map +1 -1
- package/dist/finops.d.ts +52 -2
- package/dist/finops.d.ts.map +1 -1
- package/dist/finops.js +15 -1
- package/dist/finops.js.map +1 -1
- package/dist/gateDecisions.d.ts +18 -0
- package/dist/gateDecisions.d.ts.map +1 -0
- package/dist/gateDecisions.js +20 -0
- package/dist/gateDecisions.js.map +1 -0
- package/dist/gateIdentity.d.ts +23 -0
- package/dist/gateIdentity.d.ts.map +1 -0
- package/dist/gateIdentity.js +32 -0
- package/dist/gateIdentity.js.map +1 -0
- package/dist/gateKind.d.ts +172 -0
- package/dist/gateKind.d.ts.map +1 -0
- package/dist/gateKind.js +160 -0
- package/dist/gateKind.js.map +1 -0
- package/dist/gateLimits.d.ts +170 -0
- package/dist/gateLimits.d.ts.map +1 -0
- package/dist/gateLimits.js +96 -0
- package/dist/gateLimits.js.map +1 -0
- package/dist/gitRemote.d.ts +17 -0
- package/dist/gitRemote.d.ts.map +1 -0
- package/dist/gitRemote.js +71 -0
- package/dist/gitRemote.js.map +1 -0
- package/dist/governanceCoverage.d.ts +1 -1
- package/dist/governanceCoverage.js +1 -1
- package/dist/guardrailIr.d.ts +9 -9
- package/dist/guardrailIr.d.ts.map +1 -1
- package/dist/guardrailIr.js +3 -3
- package/dist/guardrailIr.js.map +1 -1
- package/dist/guardrailRender.d.ts +1 -1
- package/dist/guardrailRender.js +1 -1
- package/dist/harnessRules.d.ts +74 -0
- package/dist/harnessRules.d.ts.map +1 -0
- package/dist/harnessRules.js +142 -0
- package/dist/harnessRules.js.map +1 -0
- package/dist/holdMessages.d.ts +25 -0
- package/dist/holdMessages.d.ts.map +1 -0
- package/dist/holdMessages.js +34 -0
- package/dist/holdMessages.js.map +1 -0
- package/dist/identity.d.ts +1 -1
- package/dist/identity.js +2 -2
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +42 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +161 -10
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +1 -1
- package/dist/mcpBudgets.d.ts +191 -0
- package/dist/mcpBudgets.d.ts.map +1 -0
- package/dist/mcpBudgets.js +144 -0
- package/dist/mcpBudgets.js.map +1 -0
- package/dist/mcpRegistryRecord.d.ts +143 -0
- package/dist/mcpRegistryRecord.d.ts.map +1 -0
- package/dist/mcpRegistryRecord.js +229 -0
- package/dist/mcpRegistryRecord.js.map +1 -0
- package/dist/mcpToolRisk.d.ts +82 -0
- package/dist/mcpToolRisk.d.ts.map +1 -0
- package/dist/mcpToolRisk.js +334 -0
- package/dist/mcpToolRisk.js.map +1 -0
- package/dist/modelCatalog.d.ts +2 -2
- package/dist/modelCatalog.generated.js +1 -1
- package/dist/modelCatalog.generated.js.map +1 -1
- package/dist/modelCatalog.js +2 -2
- package/dist/notifications.d.ts +24 -151
- package/dist/notifications.d.ts.map +1 -1
- package/dist/notifications.js +266 -1
- package/dist/notifications.js.map +1 -1
- package/dist/phrases.d.ts +87 -0
- package/dist/phrases.d.ts.map +1 -0
- package/dist/phrases.js +241 -0
- package/dist/phrases.js.map +1 -0
- package/dist/piiDetectors.d.ts +97 -0
- package/dist/piiDetectors.d.ts.map +1 -0
- package/dist/piiDetectors.js +96 -0
- package/dist/piiDetectors.js.map +1 -0
- package/dist/piiDetectors.json +71 -0
- package/dist/policy.d.ts +1 -1
- package/dist/policy.js +1 -1
- package/dist/policyGuardrails.d.ts +127 -10
- package/dist/policyGuardrails.d.ts.map +1 -1
- package/dist/policyGuardrails.js +59 -6
- package/dist/policyGuardrails.js.map +1 -1
- package/dist/posturePresets.js +1 -1
- package/dist/posturePresets.js.map +1 -1
- package/dist/providerVerification.d.ts +36 -10
- package/dist/providerVerification.d.ts.map +1 -1
- package/dist/providerVerification.js +80 -20
- package/dist/providerVerification.js.map +1 -1
- package/dist/providers.d.ts +54 -17
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +135 -26
- package/dist/providers.js.map +1 -1
- package/dist/regoBuiltins.d.ts +42 -0
- package/dist/regoBuiltins.d.ts.map +1 -0
- package/dist/regoBuiltins.js +732 -0
- package/dist/regoBuiltins.js.map +1 -0
- package/dist/regoRules.d.ts +105 -0
- package/dist/regoRules.d.ts.map +1 -0
- package/dist/regoRules.js +407 -0
- package/dist/regoRules.js.map +1 -0
- package/dist/ruleLoadFailures.d.ts +15 -0
- package/dist/ruleLoadFailures.d.ts.map +1 -0
- package/dist/ruleLoadFailures.js +26 -0
- package/dist/ruleLoadFailures.js.map +1 -0
- package/dist/scriptScan.d.ts +5 -5
- package/dist/scriptScan.js +3 -3
- package/dist/sequence.d.ts +52 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +127 -0
- package/dist/sequence.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/dist/skillScan.d.ts +3 -3
- package/dist/skillScan.d.ts.map +1 -1
- package/dist/skillScan.js +26 -4
- package/dist/skillScan.js.map +1 -1
- package/dist/sop.d.ts +5 -5
- package/dist/sop.js +2 -2
- package/dist/sourceProviders.d.ts +1 -8
- package/dist/sourceProviders.d.ts.map +1 -1
- package/dist/sourceProviders.js +2 -9
- package/dist/sourceProviders.js.map +1 -1
- package/dist/spendBudgets.d.ts +122 -0
- package/dist/spendBudgets.d.ts.map +1 -0
- package/dist/spendBudgets.js +92 -0
- package/dist/spendBudgets.js.map +1 -0
- package/dist/ssoGroupClearance.d.ts +18 -2
- package/dist/ssoGroupClearance.d.ts.map +1 -1
- package/dist/ssoGroupClearance.js +43 -4
- package/dist/ssoGroupClearance.js.map +1 -1
- package/dist/sync.d.ts +0 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +0 -1
- package/dist/sync.js.map +1 -1
- package/dist/taskManagement.d.ts +0 -2
- package/dist/taskManagement.d.ts.map +1 -1
- package/dist/taskManagement.js +0 -2
- package/dist/taskManagement.js.map +1 -1
- package/dist/toolPoison.d.ts +33 -0
- package/dist/toolPoison.d.ts.map +1 -0
- package/dist/toolPoison.js +85 -0
- package/dist/toolPoison.js.map +1 -0
- package/dist/upstreamRetry.d.ts +121 -0
- package/dist/upstreamRetry.d.ts.map +1 -0
- package/dist/upstreamRetry.js +90 -0
- package/dist/upstreamRetry.js.map +1 -0
- package/dist/usage.d.ts +186 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/wasmBinary.d.ts +25 -0
- package/dist/wasmBinary.d.ts.map +1 -0
- package/dist/wasmBinary.js +111 -0
- package/dist/wasmBinary.js.map +1 -0
- package/dist/wasmFuel.d.ts +52 -0
- package/dist/wasmFuel.d.ts.map +1 -0
- package/dist/wasmFuel.js +320 -0
- package/dist/wasmFuel.js.map +1 -0
- package/dist/wasmMemoryCap.d.ts +21 -0
- package/dist/wasmMemoryCap.d.ts.map +1 -0
- package/dist/wasmMemoryCap.js +58 -0
- package/dist/wasmMemoryCap.js.map +1 -0
- package/dist/wasmRuleDescriptor.d.ts +43 -0
- package/dist/wasmRuleDescriptor.d.ts.map +1 -0
- package/dist/wasmRuleDescriptor.js +65 -0
- package/dist/wasmRuleDescriptor.js.map +1 -0
- package/dist/workspaceSettings.d.ts +95 -17
- package/dist/workspaceSettings.d.ts.map +1 -1
- package/dist/workspaceSettings.js +2 -1
- package/dist/workspaceSettings.js.map +1 -1
- package/package.json +2 -2
package/dist/modelCatalog.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Model catalog (
|
|
3
|
+
* Model catalog (model catalog & cohort wizard).
|
|
4
4
|
*
|
|
5
5
|
* `packages/shared-types/src/providers.ts` describes what a provider's
|
|
6
6
|
* CREDENTIAL looks like — field names, types, docs URL. It says nothing about
|
|
@@ -78,7 +78,7 @@ function findCatalogModel(input) {
|
|
|
78
78
|
/**
|
|
79
79
|
* Providers whose models run on infrastructure the operator controls. Every
|
|
80
80
|
* other registry provider is a hosted API. Judges are self-hosted only (owner
|
|
81
|
-
* rule, 2026-10-03
|
|
81
|
+
* rule, 2026-10-03), so these are the only providers a judge model
|
|
82
82
|
* may come from.
|
|
83
83
|
*/
|
|
84
84
|
exports.SELF_HOSTED_MODEL_PROVIDER_IDS = new Set(['ollama']);
|
package/dist/notifications.d.ts
CHANGED
|
@@ -1,155 +1,11 @@
|
|
|
1
1
|
export type NotificationChannel = 'slack' | 'email' | 'webhook' | 'pagerduty';
|
|
2
|
-
export type NotificationEventType = 'anomaly.detected'
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* classifier after the fact and only for requests that produced an incident.
|
|
8
|
-
* This one fires for every finding on every trace — including the advisory and
|
|
9
|
-
* reask ones on requests that proceeded — which is what makes "see everything,
|
|
10
|
-
* block nothing" possible.
|
|
11
|
-
*
|
|
12
|
-
* Carries `detectorId`, so a rule can target one detector rather than a whole
|
|
13
|
-
* taxonomy kind that sixteen of twenty-two detectors share.
|
|
3
|
+
* Every event a notification rule can subscribe to. The API refuses a rule
|
|
4
|
+
* naming anything else, and the CLI and the Terraform provider check
|
|
5
|
+
* against this list before they send one.
|
|
14
6
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| 'sop.upstream.changed'
|
|
18
|
-
/** A SHADOW guardrail crossed the promotion thresholds; a named member decides. */
|
|
19
|
-
| 'guardrail.ready'
|
|
20
|
-
/** The passage a guardrail cites changed upstream; promotion is refused until re-confirmed. */
|
|
21
|
-
| 'guardrail.stale'
|
|
22
|
-
/** An MCP proxy reported a server this workspace's registry had never seen; it waits as a candidate for an OWNER or ADMIN to approve or block. */
|
|
23
|
-
| 'mcp.server.candidate'
|
|
24
|
-
/** A judged response is waiting for a person in the judge review queue: the typed judge was unsure, or it is a spot check of one it cleared (LLD #72). */
|
|
25
|
-
| 'judge.review.queued' | 'finops.budget.exceeded' | 'finops.budget.threshold' | 'finops.tokens.classified' | 'trial.started' | 'trial.expired_downgraded' | 'trial.day7_report_sent' | 'trial.day13_report_sent' | 'plan.captured' | 'plan.approved' | 'plan.deviation.detected' | 'identity.offboarding.completed' | 'workspace.context.updated'
|
|
26
|
-
/**
|
|
27
|
-
* A registered, non-revoked self-hosted gateway has gone past
|
|
28
|
-
* GATEWAY_HEARTBEAT_TTL without a heartbeat -- fired once per member
|
|
29
|
-
* workspace of the gateway's org (gateways are org-scoped; notification
|
|
30
|
-
* rules are workspace-scoped), not once per gateway.
|
|
31
|
-
*/
|
|
32
|
-
| 'gateway.stale.detected'
|
|
33
|
-
/**
|
|
34
|
-
* A managed cell (`deployment_target='managed_cell'`) has sat `pending`
|
|
35
|
-
* (registered, never heartbeated) past `CELL_STUCK_PENDING_THRESHOLD_MS`
|
|
36
|
-
* (15 min) -- the provisioner is failing to converge it (TD-342(c)).
|
|
37
|
-
* Fired by `detectStuckPendingCells` (gatewayHealthService.ts), same
|
|
38
|
-
* org→workspace fan-out and stable-reason dedup as `gateway.stale.detected`.
|
|
39
|
-
* Already wired into `notificationRouterService.ts`'s dispatch and
|
|
40
|
-
* severity map before this union entry existed -- this only adds the type
|
|
41
|
-
* contract those call sites were relying on via an `as` cast.
|
|
42
|
-
*/
|
|
43
|
-
| 'gateway.cell.stuck_pending'
|
|
44
|
-
/**
|
|
45
|
-
* The control plane's CP→region Valkey sync heartbeat
|
|
46
|
-
* (`intutic:cp:last-sync`) is missing or stale in a remote region --
|
|
47
|
-
* cells there keep serving, but on progressively stale control metadata.
|
|
48
|
-
* Fired by `detectStaleRegionSync` (gatewayHealthService.ts) per member
|
|
49
|
-
* workspace of every org with a live cell in the affected region. Same
|
|
50
|
-
* pre-existing-dispatch note as `gateway.cell.stuck_pending` above.
|
|
51
|
-
*/
|
|
52
|
-
| 'region.sync.stale'
|
|
53
|
-
/**
|
|
54
|
-
* A managed cell was marked for removal because its org's plan tier no
|
|
55
|
-
* longer covers it (`maxCellsPerOrg` in planSkuMap.ts) -- either a
|
|
56
|
-
* voluntary downgrade or an involuntary loss of paid status (cancellation,
|
|
57
|
-
* dunning). Fired by `scheduleCellReconciliation`
|
|
58
|
-
* (cellDeprovisionService.ts) at most once per scheduled removal
|
|
59
|
-
* (`deprovision_notified_at` is the idempotence gate). Carries
|
|
60
|
-
* `deprovision_at` -- the grace-period deadline -- and `reason`.
|
|
61
|
-
*/
|
|
62
|
-
| 'org.cells.deprovision_scheduled'
|
|
63
|
-
/**
|
|
64
|
-
* A previously-scheduled cell removal was cancelled because the org's
|
|
65
|
-
* cell count is no longer over its plan-tier capacity -- typically a
|
|
66
|
-
* re-upgrade landing before the grace period expired. Fired by the same
|
|
67
|
-
* reconciler as `org.cells.deprovision_scheduled` above, the bidirectional
|
|
68
|
-
* half of the same bidirectional-reconcile-marks design. MEDIUM, not
|
|
69
|
-
* HIGH: this is good news for the org, not an incident.
|
|
70
|
-
*/
|
|
71
|
-
| 'org.cells.deprovision_canceled'
|
|
72
|
-
/**
|
|
73
|
-
* A managed cell's deprovision grace period actually expired and the cell
|
|
74
|
-
* was revoked -- fired by `sweepCellCapacity`'s deadline pass
|
|
75
|
-
* (cellDeprovisionService.ts), the same revoke shape as a manual
|
|
76
|
-
* `DELETE /api/v1/gateways/:id`. HIGH: an org's traffic capacity for that
|
|
77
|
-
* region just changed, same tier as `gateway.stale.detected`.
|
|
78
|
-
*/
|
|
79
|
-
| 'org.cells.deprovisioned'
|
|
80
|
-
/**
|
|
81
|
-
* A device's reported enforcement posture (firewall/CA-trust/system-hooks)
|
|
82
|
-
* hasn't been refreshed past DEVICE_STALE_THRESHOLD_MS (72h) -- fired by
|
|
83
|
-
* deviceHealthCron.ts. Most staleness is a closed laptop, not a
|
|
84
|
-
* compromise -- MEDIUM, unlike gateway.stale.detected's HIGH.
|
|
85
|
-
*/
|
|
86
|
-
| 'device.enforcement.stale'
|
|
87
|
-
/**
|
|
88
|
-
* A device's firewall went from active:true to active:false on a live
|
|
89
|
-
* report -- an active bypass just occurred, not merely unreported.
|
|
90
|
-
*/
|
|
91
|
-
| 'device.enforcement.disabled'
|
|
92
|
-
/**
|
|
93
|
-
* A harness installed in the workspace has sent no hook event of any kind,
|
|
94
|
-
* allows included, for the whole liveness window: its gate may not be
|
|
95
|
-
* running. Fired once when the gate goes silent, not on every hourly sweep.
|
|
96
|
-
* Carries `harnessType` and `incidentId`.
|
|
97
|
-
*/
|
|
98
|
-
| 'governance.gate.silent'
|
|
99
|
-
/**
|
|
100
|
-
* A harness with an open `governance.gate.silent` alert is reporting again.
|
|
101
|
-
* Same `incidentId` as the alert it closes; PagerDuty resolves that incident.
|
|
102
|
-
*/
|
|
103
|
-
| 'governance.gate.recovered'
|
|
104
|
-
/**
|
|
105
|
-
* The hourly audit-log integrity check found a failure of one kind
|
|
106
|
-
* (`kind`: `chain_break`, `mirror_copy_mismatch`, `signature_invalid`,
|
|
107
|
-
* `root_mismatch` or `guard_tampered`). Fired once per kind while it keeps
|
|
108
|
-
* failing; a recurrence after it clears fires again.
|
|
109
|
-
*/
|
|
110
|
-
| 'governance.integrity.failed'
|
|
111
|
-
/**
|
|
112
|
-
* A NEW provider_incidents window opened for a provider (Anthropic,
|
|
113
|
-
* OpenAI, ...) -- fired once per incident open, not on every coalesced
|
|
114
|
-
* failure that extends an already-open incident. Fired scoped to the
|
|
115
|
-
* workspace whose trace triggered the open, since provider_incidents
|
|
116
|
-
* itself is not workspace-scoped (see migration 157) and no complete
|
|
117
|
-
* "every workspace routing through this provider" fan-out exists the way
|
|
118
|
-
* gateway.stale.detected's org-membership join provides for gateways.
|
|
119
|
-
*/
|
|
120
|
-
| 'provider.outage.detected'
|
|
121
|
-
/**
|
|
122
|
-
* A Stripe subscription reported `status: 'past_due'` or `'unpaid'` via
|
|
123
|
-
* `customer.subscription.updated` -- visibility only, not a tier change
|
|
124
|
-
* (repeated payment failure is the dunning flow's job, via
|
|
125
|
-
* `invoice.payment_failed`'s own 3rd-attempt downgrade). MEDIUM: worth a
|
|
126
|
-
* support/ops look, not yet the incident a full cancellation is.
|
|
127
|
-
*/
|
|
128
|
-
| 'billing.subscription.past_due'
|
|
129
|
-
/**
|
|
130
|
-
* An opt-in `GET /api/v3/files/{sha256}` VirusTotal lookup on a
|
|
131
|
-
* skill-bundled SCRIPT (never `SKILL.md` prose, never uploaded content —
|
|
132
|
-
* see `virusTotalService.ts`'s doc comment) returned at least one AV
|
|
133
|
-
* engine detection. HIGH: a confirmed-malicious file already sitting in a
|
|
134
|
-
* developer's skill directory is a live incident, the same tier as
|
|
135
|
-
* `provider.outage.detected` and `device.enforcement.disabled` above, not
|
|
136
|
-
* a usage-pattern signal to review later.
|
|
137
|
-
*/
|
|
138
|
-
| 'skill.malware.detected'
|
|
139
|
-
/**
|
|
140
|
-
* The opt-in LLM judge (`semanticSkillAnalysisEnabled`) called a skill's
|
|
141
|
-
* `SKILL.md` prose `'suspicious'` or `'malicious'` — content that
|
|
142
|
-
* `scanSkillContent`'s deterministic patterns may have missed entirely,
|
|
143
|
-
* since the whole point of this judge is catching a rephrasing that
|
|
144
|
-
* avoids every pattern's literal wording. Fired by
|
|
145
|
-
* `analyzeSkillSemantics` (`services/semanticSkillAnalysisService.ts`)
|
|
146
|
-
* only for a judge call that actually ran and returned one of those two
|
|
147
|
-
* verdicts — never for `'clean'`, and never for `'unjudged'` (a failed or
|
|
148
|
-
* capped-out call is an absence of signal, not a finding). Severity is
|
|
149
|
-
* dynamic: HIGH for `'malicious'`, MEDIUM for `'suspicious'` — see
|
|
150
|
-
* `mapSeverity` in `notificationRouterService.ts`.
|
|
151
|
-
*/
|
|
152
|
-
| 'skill.semantic.flagged';
|
|
7
|
+
export declare const NOTIFICATION_EVENT_TYPES: readonly ["anomaly.detected", "anomaly.finding", "incident.created", "incident.escalated", "sop.status_changed", "session.ended", "adapter.write_back.failed", "decision.pending", "decision.approved", "decision.rejected", "ssl.enforcement.violation", "context_gap.auto_injected", "trajectory.alert", "calibration.threshold_breach", "anomaly.drift.detected", "anomaly.capability_miss", "anomaly.trust.updated", "sop.stale.detected", "sop.cascade.alert", "sop.cascade.invalidated", "sop.integrity.drift", "sop.lifecycle.transitioned", "sop.upstream.changed", "guardrail.ready", "guardrail.stale", "mcp.server.candidate", "mcp.server.tool_change_risk", "mcp.server.decided", "mcp.server.tool_toggled", "mcp.budget.threshold", "mcp.budget.exceeded", "judge.review.queued", "finops.budget.exceeded", "finops.budget.threshold", "finops.tokens.classified", "trial.started", "trial.expired_downgraded", "trial.day7_report_sent", "trial.day13_report_sent", "plan.captured", "plan.approved", "plan.deviation.detected", "identity.offboarding.completed", "auth.login.failed", "scim.user.changed", "scim.group.changed", "webhook.secret.rotated", "evidence.exported", "credential.changed", "workspace.context.updated", "gateway.stale.detected", "gateway.cell.stuck_pending", "region.sync.stale", "org.cells.deprovision_scheduled", "org.cells.deprovision_canceled", "org.cells.deprovisioned", "device.enforcement.stale", "device.enforcement.disabled", "governance.gate.silent", "governance.gate.recovered", "governance.integrity.failed", "inventory.ungoverned.detected", "provider.outage.detected", "billing.subscription.past_due", "skill.malware.detected", "skill.semantic.flagged"];
|
|
8
|
+
export type NotificationEventType = (typeof NOTIFICATION_EVENT_TYPES)[number];
|
|
153
9
|
export type NotificationStatus = 'sent' | 'failed' | 'deduplicated' | 'filtered';
|
|
154
10
|
export interface NotificationRule {
|
|
155
11
|
ruleId: string;
|
|
@@ -182,7 +38,7 @@ export interface ChannelConfig {
|
|
|
182
38
|
webhookSecretEnc?: string;
|
|
183
39
|
/** PagerDuty Events API v2 integration/routing key. A credential — see
|
|
184
40
|
* `notificationHubService.ts`'s `getChannelTarget` for why it is masked
|
|
185
|
-
* (
|
|
41
|
+
* (`${key.slice(0,6)}…`) before ever reaching `notification_log`,
|
|
186
42
|
* which is append-only and so unredactable forever once written. */
|
|
187
43
|
pagerdutyRoutingKey?: string;
|
|
188
44
|
}
|
|
@@ -219,15 +75,30 @@ export interface NotificationLogEntry {
|
|
|
219
75
|
latencyMs: number | null;
|
|
220
76
|
createdAt: string;
|
|
221
77
|
}
|
|
78
|
+
/** The severity a notification is sent at, which a rule's severity filter matches on. */
|
|
79
|
+
export type NotificationSeverity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO';
|
|
222
80
|
export interface GovernanceEvent {
|
|
223
81
|
type: NotificationEventType;
|
|
224
82
|
workspaceId: string;
|
|
225
83
|
sessionId?: string;
|
|
226
|
-
severity:
|
|
84
|
+
severity: NotificationSeverity;
|
|
227
85
|
summary: string;
|
|
228
86
|
description: string;
|
|
229
87
|
metadata: Record<string, unknown>;
|
|
230
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* The severity `incident.created` is sent at, from the incident's own
|
|
91
|
+
* (`governance_incidents.severity`). Until 2.4.0 every incident was sent at
|
|
92
|
+
* CRITICAL whatever its severity, so a rule filtered on CRITICAL received a
|
|
93
|
+
* MEDIUM incident and a rule filtered on HIGH received none.
|
|
94
|
+
*/
|
|
95
|
+
export declare const INCIDENT_NOTIFICATION_SEVERITY: Readonly<Record<'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW', NotificationSeverity>>;
|
|
96
|
+
/**
|
|
97
|
+
* {@link INCIDENT_NOTIFICATION_SEVERITY} for an incident event's `severity`.
|
|
98
|
+
* One the map does not name (absent, or from an emitter that sent something
|
|
99
|
+
* else) is sent at CRITICAL: a malformed event must not quieten an alert.
|
|
100
|
+
*/
|
|
101
|
+
export declare function incidentNotificationSeverity(severity: unknown): NotificationSeverity;
|
|
231
102
|
export interface DispatchResult {
|
|
232
103
|
ruleId: string;
|
|
233
104
|
channel: NotificationChannel;
|
|
@@ -312,6 +183,8 @@ export interface SlackInteraction {
|
|
|
312
183
|
message: {
|
|
313
184
|
ts: string;
|
|
314
185
|
};
|
|
186
|
+
/** Where a reply to the clicker goes; Slack ignores the HTTP response body. */
|
|
187
|
+
response_url?: string;
|
|
315
188
|
}
|
|
316
189
|
export interface SlackSlashCommand {
|
|
317
190
|
command: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAA;AAE7E,
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"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"}
|
package/dist/notifications.js
CHANGED
|
@@ -1,6 +1,271 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ============================================
|
|
3
|
-
//
|
|
3
|
+
// Notification Hub + Slack Adapter
|
|
4
4
|
// ============================================
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.INCIDENT_NOTIFICATION_SEVERITY = exports.NOTIFICATION_EVENT_TYPES = void 0;
|
|
7
|
+
exports.incidentNotificationSeverity = incidentNotificationSeverity;
|
|
8
|
+
/**
|
|
9
|
+
* Every event a notification rule can subscribe to. The API refuses a rule
|
|
10
|
+
* naming anything else, and the CLI and the Terraform provider check
|
|
11
|
+
* against this list before they send one.
|
|
12
|
+
*/
|
|
13
|
+
exports.NOTIFICATION_EVENT_TYPES = [
|
|
14
|
+
// ── Core governance events (already wired) ──
|
|
15
|
+
'anomaly.detected',
|
|
16
|
+
/**
|
|
17
|
+
* One attributed detector finding from the proxy, allowed or blocked.
|
|
18
|
+
*
|
|
19
|
+
* Distinct from `anomaly.detected`, which is raised by the control plane's own
|
|
20
|
+
* classifier after the fact and only for requests that produced an incident.
|
|
21
|
+
* This one fires for every finding on every trace — including the advisory and
|
|
22
|
+
* reask ones on requests that proceeded — which is what makes "see everything,
|
|
23
|
+
* block nothing" possible.
|
|
24
|
+
*
|
|
25
|
+
* Carries `detectorId`, so a rule can target one detector rather than a whole
|
|
26
|
+
* taxonomy kind that sixteen of twenty-two detectors share.
|
|
27
|
+
*/
|
|
28
|
+
'anomaly.finding',
|
|
29
|
+
'incident.created',
|
|
30
|
+
'incident.escalated',
|
|
31
|
+
'sop.status_changed',
|
|
32
|
+
'session.ended',
|
|
33
|
+
'adapter.write_back.failed',
|
|
34
|
+
'decision.pending',
|
|
35
|
+
/** An OWNER, ADMIN or EM approved a held decision, in Slack or through the API and CLI. Carries `entryId`, `reviewerId` and `via`. */
|
|
36
|
+
'decision.approved',
|
|
37
|
+
/** An OWNER, ADMIN or EM rejected a held decision, in Slack or through the API and CLI. */
|
|
38
|
+
'decision.rejected',
|
|
39
|
+
'ssl.enforcement.violation',
|
|
40
|
+
'context_gap.auto_injected',
|
|
41
|
+
'trajectory.alert',
|
|
42
|
+
// ── Calibration & drift (Q10 orphan audit) ──
|
|
43
|
+
'calibration.threshold_breach',
|
|
44
|
+
'anomaly.drift.detected',
|
|
45
|
+
'anomaly.capability_miss',
|
|
46
|
+
'anomaly.trust.updated',
|
|
47
|
+
// ── SOP lifecycle & integrity ──
|
|
48
|
+
'sop.stale.detected',
|
|
49
|
+
'sop.cascade.alert',
|
|
50
|
+
'sop.cascade.invalidated',
|
|
51
|
+
'sop.integrity.drift',
|
|
52
|
+
'sop.lifecycle.transitioned',
|
|
53
|
+
/** A source-connector sync found an enforced SOP's upstream document changed and created a DRAFT successor awaiting review. */
|
|
54
|
+
'sop.upstream.changed',
|
|
55
|
+
// ── Policy guardrails ──
|
|
56
|
+
/** A SHADOW guardrail crossed the promotion thresholds; a named member decides. */
|
|
57
|
+
'guardrail.ready',
|
|
58
|
+
/** The passage a guardrail cites changed upstream; promotion is refused until re-confirmed. */
|
|
59
|
+
'guardrail.stale',
|
|
60
|
+
// ── MCP server registry ──
|
|
61
|
+
/** An MCP proxy reported a server this workspace's registry had never seen; it waits as a candidate for an OWNER or ADMIN to approve or block. */
|
|
62
|
+
'mcp.server.candidate',
|
|
63
|
+
/** A server the registry knew declared a different tool set, and the change scored high risk (`mcpToolRisk.ts`). */
|
|
64
|
+
'mcp.server.tool_change_risk',
|
|
65
|
+
/** An OWNER or ADMIN approved, blocked or reset (returned to the approval queue) an MCP server. Carries `action`, `previousStatus` and `actorId`. */
|
|
66
|
+
'mcp.server.decided',
|
|
67
|
+
/** An OWNER or ADMIN switched one tool of an MCP server on or off. Carries `toolName`, `enabled` and `actorId`. */
|
|
68
|
+
'mcp.server.tool_toggled',
|
|
69
|
+
/** An MCP call budget reached its warning threshold for the period (sent once per budget per period). */
|
|
70
|
+
'mcp.budget.threshold',
|
|
71
|
+
/** An MCP call budget ran out and the proxy refused a call (sent once per budget per period). */
|
|
72
|
+
'mcp.budget.exceeded',
|
|
73
|
+
// ── Governance judge ──
|
|
74
|
+
/** A judged response is waiting for a person in the judge review queue: the typed judge was unsure, or it is a spot check of one it cleared. */
|
|
75
|
+
'judge.review.queued',
|
|
76
|
+
// ── FinOps & budget ──
|
|
77
|
+
'finops.budget.exceeded',
|
|
78
|
+
'finops.budget.threshold',
|
|
79
|
+
'finops.tokens.classified',
|
|
80
|
+
// ── Enterprise & trial ──
|
|
81
|
+
'trial.started',
|
|
82
|
+
'trial.expired_downgraded',
|
|
83
|
+
'trial.day7_report_sent',
|
|
84
|
+
'trial.day13_report_sent',
|
|
85
|
+
// ── Plans ──
|
|
86
|
+
'plan.captured',
|
|
87
|
+
'plan.approved',
|
|
88
|
+
'plan.deviation.detected',
|
|
89
|
+
// ── Identity & compliance ──
|
|
90
|
+
'identity.offboarding.completed',
|
|
91
|
+
/** A sign-in to the workspace was refused (wrong password, deactivated member, an SSO identity the workspace does not admit, a response that failed verification). The `login_events` row. */
|
|
92
|
+
'auth.login.failed',
|
|
93
|
+
/** The identity provider provisioned, changed or deprovisioned a user through SCIM. Carries `action` and the SCIM user id. */
|
|
94
|
+
'scim.user.changed',
|
|
95
|
+
/** The identity provider created, changed (members, name, mapped role) or deleted a group through SCIM. */
|
|
96
|
+
'scim.group.changed',
|
|
97
|
+
/** An OWNER or ADMIN replaced the signing secret of a notification webhook, a SIEM webhook destination or the GitHub pull-request webhook. Carries `target` and `targetId`, never the secret. */
|
|
98
|
+
'webhook.secret.rotated',
|
|
99
|
+
/** A member downloaded compliance evidence: a SOC 2 archive, a framework coverage report file or the human-oversight export. The `evidence_exports` row. */
|
|
100
|
+
'evidence.exported',
|
|
101
|
+
/** An API key, gateway token or SCIM token was created, rotated or revoked, or a provider credential was provisioned, replaced or removed. The `credential_changes` row: `credential_type`, `credential_id`, `action` and who; never the value. */
|
|
102
|
+
'credential.changed',
|
|
103
|
+
// ── Workspace context ──
|
|
104
|
+
'workspace.context.updated',
|
|
105
|
+
// ── Self-hosted gateway ──
|
|
106
|
+
/**
|
|
107
|
+
* A registered, non-revoked self-hosted gateway has gone past
|
|
108
|
+
* GATEWAY_HEARTBEAT_TTL without a heartbeat -- fired once per member
|
|
109
|
+
* workspace of the gateway's org (gateways are org-scoped; notification
|
|
110
|
+
* rules are workspace-scoped), not once per gateway.
|
|
111
|
+
*/
|
|
112
|
+
'gateway.stale.detected',
|
|
113
|
+
/**
|
|
114
|
+
* A managed cell (`deployment_target='managed_cell'`) has sat `pending`
|
|
115
|
+
* (registered, never heartbeated) past `CELL_STUCK_PENDING_THRESHOLD_MS`
|
|
116
|
+
* (15 min) -- the provisioner is failing to converge it.
|
|
117
|
+
* Fired by `detectStuckPendingCells` (gatewayHealthService.ts), same
|
|
118
|
+
* org→workspace fan-out and stable-reason dedup as `gateway.stale.detected`.
|
|
119
|
+
* Already wired into `notificationRouterService.ts`'s dispatch and
|
|
120
|
+
* severity map before this union entry existed -- this only adds the type
|
|
121
|
+
* contract those call sites were relying on via an `as` cast.
|
|
122
|
+
*/
|
|
123
|
+
'gateway.cell.stuck_pending',
|
|
124
|
+
/**
|
|
125
|
+
* The control plane's CP→region Valkey sync heartbeat
|
|
126
|
+
* (`intutic:cp:last-sync`) is missing or stale in a remote region --
|
|
127
|
+
* cells there keep serving, but on progressively stale control metadata.
|
|
128
|
+
* Fired by `detectStaleRegionSync` (gatewayHealthService.ts) per member
|
|
129
|
+
* workspace of every org with a live cell in the affected region. Same
|
|
130
|
+
* pre-existing-dispatch note as `gateway.cell.stuck_pending` above.
|
|
131
|
+
*/
|
|
132
|
+
'region.sync.stale',
|
|
133
|
+
// ── Managed gateway cell deprovisioning ──
|
|
134
|
+
/**
|
|
135
|
+
* A managed cell was marked for removal because its org's plan tier no
|
|
136
|
+
* longer covers it (`maxCellsPerOrg` in planSkuMap.ts) -- either a
|
|
137
|
+
* voluntary downgrade or an involuntary loss of paid status (cancellation,
|
|
138
|
+
* dunning). Fired by `scheduleCellReconciliation`
|
|
139
|
+
* (cellDeprovisionService.ts) at most once per scheduled removal
|
|
140
|
+
* (`deprovision_notified_at` is the idempotence gate). Carries
|
|
141
|
+
* `deprovision_at` -- the grace-period deadline -- and `reason`.
|
|
142
|
+
*/
|
|
143
|
+
'org.cells.deprovision_scheduled',
|
|
144
|
+
/**
|
|
145
|
+
* A previously-scheduled cell removal was cancelled because the org's
|
|
146
|
+
* cell count is no longer over its plan-tier capacity -- typically a
|
|
147
|
+
* re-upgrade landing before the grace period expired. Fired by the same
|
|
148
|
+
* reconciler as `org.cells.deprovision_scheduled` above, the bidirectional
|
|
149
|
+
* half of the same bidirectional-reconcile-marks design. MEDIUM, not
|
|
150
|
+
* HIGH: this is good news for the org, not an incident.
|
|
151
|
+
*/
|
|
152
|
+
'org.cells.deprovision_canceled',
|
|
153
|
+
/**
|
|
154
|
+
* A managed cell's deprovision grace period actually expired and the cell
|
|
155
|
+
* was revoked -- fired by `sweepCellCapacity`'s deadline pass
|
|
156
|
+
* (cellDeprovisionService.ts), the same revoke shape as a manual
|
|
157
|
+
* `DELETE /api/v1/gateways/:id`. HIGH: an org's traffic capacity for that
|
|
158
|
+
* region just changed, same tier as `gateway.stale.detected`.
|
|
159
|
+
*/
|
|
160
|
+
'org.cells.deprovisioned',
|
|
161
|
+
// ── Enforcement device visibility ──
|
|
162
|
+
/**
|
|
163
|
+
* A device's reported enforcement posture (firewall/CA-trust/system-hooks)
|
|
164
|
+
* hasn't been refreshed past DEVICE_STALE_THRESHOLD_MS (72h) -- fired by
|
|
165
|
+
* deviceHealthCron.ts. Most staleness is a closed laptop, not a
|
|
166
|
+
* compromise -- MEDIUM, unlike gateway.stale.detected's HIGH.
|
|
167
|
+
*/
|
|
168
|
+
'device.enforcement.stale',
|
|
169
|
+
/**
|
|
170
|
+
* A device's firewall went from active:true to active:false on a live
|
|
171
|
+
* report -- an active bypass just occurred, not merely unreported.
|
|
172
|
+
*/
|
|
173
|
+
'device.enforcement.disabled',
|
|
174
|
+
// ── Gate liveness ──
|
|
175
|
+
/**
|
|
176
|
+
* A harness installed in the workspace has sent no hook event of any kind,
|
|
177
|
+
* allows included, for the whole liveness window: its gate may not be
|
|
178
|
+
* running. Fired once when the gate goes silent, not on every hourly sweep.
|
|
179
|
+
* Carries `harnessType` and `incidentId`.
|
|
180
|
+
*/
|
|
181
|
+
'governance.gate.silent',
|
|
182
|
+
/**
|
|
183
|
+
* A harness with an open `governance.gate.silent` alert is reporting again.
|
|
184
|
+
* Same `incidentId` as the alert it closes; PagerDuty resolves that incident.
|
|
185
|
+
*/
|
|
186
|
+
'governance.gate.recovered',
|
|
187
|
+
// ── Trace integrity ──
|
|
188
|
+
/**
|
|
189
|
+
* The hourly audit-log integrity check found a failure of one kind
|
|
190
|
+
* (`kind`: `chain_break`, `mirror_copy_mismatch`, `signature_invalid`,
|
|
191
|
+
* `root_mismatch` or `guard_tampered`). Fired once per kind while it keeps
|
|
192
|
+
* failing; a recurrence after it clears fires again.
|
|
193
|
+
*/
|
|
194
|
+
'governance.integrity.failed',
|
|
195
|
+
// ── AI inventory of developer machines ──
|
|
196
|
+
/**
|
|
197
|
+
* A machine's AI inventory listed an ungoverned harness or MCP server for
|
|
198
|
+
* the first time: a harness with no gate installed or none possible, or an
|
|
199
|
+
* MCP server the MCP proxy does not front. Once per machine and item.
|
|
200
|
+
*/
|
|
201
|
+
'inventory.ungoverned.detected',
|
|
202
|
+
// ── Provider outage tracking (Phase 8b) ──
|
|
203
|
+
/**
|
|
204
|
+
* A NEW provider_incidents window opened for a provider (Anthropic,
|
|
205
|
+
* OpenAI, ...) -- fired once per incident open, not on every coalesced
|
|
206
|
+
* failure that extends an already-open incident. Fired scoped to the
|
|
207
|
+
* workspace whose trace triggered the open, since provider_incidents
|
|
208
|
+
* itself is not workspace-scoped (see migration 157) and no complete
|
|
209
|
+
* "every workspace routing through this provider" fan-out exists the way
|
|
210
|
+
* gateway.stale.detected's org-membership join provides for gateways.
|
|
211
|
+
*/
|
|
212
|
+
'provider.outage.detected',
|
|
213
|
+
// ── Billing (customer.subscription.updated handling) ──
|
|
214
|
+
/**
|
|
215
|
+
* A Stripe subscription reported `status: 'past_due'` or `'unpaid'` via
|
|
216
|
+
* `customer.subscription.updated` -- visibility only, not a tier change
|
|
217
|
+
* (repeated payment failure is the dunning flow's job, via
|
|
218
|
+
* `invoice.payment_failed`'s own 3rd-attempt downgrade). MEDIUM: worth a
|
|
219
|
+
* support/ops look, not yet the incident a full cancellation is.
|
|
220
|
+
*/
|
|
221
|
+
'billing.subscription.past_due',
|
|
222
|
+
// ── Skill-bundled-script malware detection (Phase S4, opt-in VirusTotal hash lookup) ──
|
|
223
|
+
/**
|
|
224
|
+
* An opt-in `GET /api/v3/files/{sha256}` VirusTotal lookup on a
|
|
225
|
+
* skill-bundled SCRIPT (never `SKILL.md` prose, never uploaded content —
|
|
226
|
+
* see `virusTotalService.ts`'s doc comment) returned at least one AV
|
|
227
|
+
* engine detection. HIGH: a confirmed-malicious file already sitting in a
|
|
228
|
+
* developer's skill directory is a live incident, the same tier as
|
|
229
|
+
* `provider.outage.detected` and `device.enforcement.disabled` above, not
|
|
230
|
+
* a usage-pattern signal to review later.
|
|
231
|
+
*/
|
|
232
|
+
'skill.malware.detected',
|
|
233
|
+
// ── Semantic skill analysis (Phase S5) ──
|
|
234
|
+
/**
|
|
235
|
+
* The opt-in LLM judge (`semanticSkillAnalysisEnabled`) called a skill's
|
|
236
|
+
* `SKILL.md` prose `'suspicious'` or `'malicious'` — content that
|
|
237
|
+
* `scanSkillContent`'s deterministic patterns may have missed entirely,
|
|
238
|
+
* since the whole point of this judge is catching a rephrasing that
|
|
239
|
+
* avoids every pattern's literal wording. Fired by
|
|
240
|
+
* `analyzeSkillSemantics` (`services/semanticSkillAnalysisService.ts`)
|
|
241
|
+
* only for a judge call that actually ran and returned one of those two
|
|
242
|
+
* verdicts — never for `'clean'`, and never for `'unjudged'` (a failed or
|
|
243
|
+
* capped-out call is an absence of signal, not a finding). Severity is
|
|
244
|
+
* dynamic: HIGH for `'malicious'`, MEDIUM for `'suspicious'` — see
|
|
245
|
+
* `mapSeverity` in `notificationRouterService.ts`.
|
|
246
|
+
*/
|
|
247
|
+
'skill.semantic.flagged',
|
|
248
|
+
];
|
|
249
|
+
/**
|
|
250
|
+
* The severity `incident.created` is sent at, from the incident's own
|
|
251
|
+
* (`governance_incidents.severity`). Until 2.4.0 every incident was sent at
|
|
252
|
+
* CRITICAL whatever its severity, so a rule filtered on CRITICAL received a
|
|
253
|
+
* MEDIUM incident and a rule filtered on HIGH received none.
|
|
254
|
+
*/
|
|
255
|
+
exports.INCIDENT_NOTIFICATION_SEVERITY = {
|
|
256
|
+
CRITICAL: 'CRITICAL',
|
|
257
|
+
HIGH: 'HIGH',
|
|
258
|
+
MEDIUM: 'MEDIUM',
|
|
259
|
+
LOW: 'LOW',
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* {@link INCIDENT_NOTIFICATION_SEVERITY} for an incident event's `severity`.
|
|
263
|
+
* One the map does not name (absent, or from an emitter that sent something
|
|
264
|
+
* else) is sent at CRITICAL: a malformed event must not quieten an alert.
|
|
265
|
+
*/
|
|
266
|
+
function incidentNotificationSeverity(severity) {
|
|
267
|
+
return typeof severity === 'string' && Object.hasOwn(exports.INCIDENT_NOTIFICATION_SEVERITY, severity)
|
|
268
|
+
? exports.INCIDENT_NOTIFICATION_SEVERITY[severity]
|
|
269
|
+
: 'CRITICAL';
|
|
270
|
+
}
|
|
6
271
|
//# sourceMappingURL=notifications.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":";AAAA,+CAA+C;AAC/C,
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phrase matching for shell commands and SQL in linear time.
|
|
3
|
+
*
|
|
4
|
+
* Every command classifier asks the same question: does this text contain
|
|
5
|
+
* `git push`, `drop table`, `curl --data`, whatever separates the words? The
|
|
6
|
+
* separators that count are the ones the shell or the database reads as a
|
|
7
|
+
* word break:
|
|
8
|
+
*
|
|
9
|
+
* - whitespace, a two-character escaped `\n`, `\t` or `\r`, and a backslash
|
|
10
|
+
* before whitespace (a line continuation, or an escaped space);
|
|
11
|
+
* - a `/* … *\/` comment;
|
|
12
|
+
* - a `-- …` comment that runs to a newline (real or escaped);
|
|
13
|
+
* - a run of options starting with `--` (`git --no-pager push`,
|
|
14
|
+
* `kubectl --context prod apply`), which stops at `;`, `&`, `|` or a real
|
|
15
|
+
* newline — the end of the shell command it is in.
|
|
16
|
+
*
|
|
17
|
+
* The proxy's Rust classifier expresses this as a regex (`SQL_GAP` in
|
|
18
|
+
* `actions.rs`), which is safe there: Rust's engine is linear. JavaScript's
|
|
19
|
+
* and Python's backtrack, and that regex took seconds on a few hundred
|
|
20
|
+
* kilobytes of `git -- git -- …` — text an agent can be talked into producing.
|
|
21
|
+
* So here the text is cut into words in one pass, and a phrase is matched over
|
|
22
|
+
* the words right to left with one array per phrase word: O(length × words).
|
|
23
|
+
* No regex runs on the input.
|
|
24
|
+
*
|
|
25
|
+
* The two functions are self-contained on purpose — no imports, no module
|
|
26
|
+
* state — because the hook gates emit them as source (`phraseText.toString()`)
|
|
27
|
+
* and run them outside this package. `packages/gate-js/src/phrases.ts` is a
|
|
28
|
+
* byte-identical copy and `intutic_clawde/gate/phrases.py` a transliteration;
|
|
29
|
+
* all of them run `action_vectors.json` beside the proxy's `actions.rs`.
|
|
30
|
+
*
|
|
31
|
+
* @module
|
|
32
|
+
*/
|
|
33
|
+
/** A text cut into words, ready for any number of {@link hasPhrase} calls. */
|
|
34
|
+
export interface PhraseText {
|
|
35
|
+
/** The whole text, lower-cased: one-word phrases are plain substrings of it. */
|
|
36
|
+
raw: string;
|
|
37
|
+
/** The words, lower-cased, separated by single spaces: a cheap filter. */
|
|
38
|
+
joined: string;
|
|
39
|
+
toks: string[];
|
|
40
|
+
/** A separator (not a glued `--`) stands before the word. */
|
|
41
|
+
sep: boolean[];
|
|
42
|
+
/** A real newline stands before the word: the end of an option run. */
|
|
43
|
+
nl: boolean[];
|
|
44
|
+
/** A real or escaped newline stands before the word: the end of a `--` comment. */
|
|
45
|
+
eol: boolean[];
|
|
46
|
+
/** The word starts with `--`. */
|
|
47
|
+
dash: boolean[];
|
|
48
|
+
/** The word contains `;`, `&` or `|`: an option run cannot cross it. */
|
|
49
|
+
bar: boolean[];
|
|
50
|
+
/** A separator follows the last word. */
|
|
51
|
+
tail: boolean;
|
|
52
|
+
/** Per-word match arrays already computed, by mode and word. */
|
|
53
|
+
memo: Record<string, Uint8Array>;
|
|
54
|
+
/**
|
|
55
|
+
* Per word x: the first word at or after x containing `;&|`, with a real
|
|
56
|
+
* newline before it, and with any newline before it (the word count when
|
|
57
|
+
* none). Built by the first {@link hasPhrase} call that needs them.
|
|
58
|
+
*/
|
|
59
|
+
next: {
|
|
60
|
+
bar: Int32Array;
|
|
61
|
+
nl: Int32Array;
|
|
62
|
+
eol: Int32Array;
|
|
63
|
+
} | null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Cuts `input` into words in one pass. A `--` inside a word starts a new one
|
|
67
|
+
* (`drop--why` is `drop` and `--why`), glued rather than separated, so it can
|
|
68
|
+
* open a comment or an option run but cannot stand for a plain gap.
|
|
69
|
+
*/
|
|
70
|
+
export declare function phraseText(input: unknown): PhraseText;
|
|
71
|
+
/**
|
|
72
|
+
* Whether `t` contains `needle`, a phrase whose words are separated by single
|
|
73
|
+
* spaces. A one-word needle is a plain substring. In a longer one the first
|
|
74
|
+
* word may end a word of the text (`digit push` contains `git push`, as a
|
|
75
|
+
* substring would), the last may begin one, and the words between must be
|
|
76
|
+
* whole; a trailing space (`'update '`) asks for a separator after the last
|
|
77
|
+
* word. `bounded` additionally requires a non-word character (or the edge of
|
|
78
|
+
* the word) before the first word and after the last, where `.` also counts
|
|
79
|
+
* as part of a word (`table.log` is not `table`).
|
|
80
|
+
*/
|
|
81
|
+
export declare function hasPhrase(t: PhraseText, needle: string, bounded?: boolean): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Both functions as JavaScript source, for a hook gate to emit: the gates run
|
|
84
|
+
* this exact code, not a retyped copy.
|
|
85
|
+
*/
|
|
86
|
+
export declare const PHRASES_JS_SOURCE: string;
|
|
87
|
+
//# sourceMappingURL=phrases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phrases.d.ts","sourceRoot":"","sources":["../src/phrases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAA;IACX,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,6DAA6D;IAC7D,GAAG,EAAE,OAAO,EAAE,CAAA;IACd,uEAAuE;IACvE,EAAE,EAAE,OAAO,EAAE,CAAA;IACb,mFAAmF;IACnF,GAAG,EAAE,OAAO,EAAE,CAAA;IACd,iCAAiC;IACjC,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,wEAAwE;IACxE,GAAG,EAAE,OAAO,EAAE,CAAA;IACd,yCAAyC;IACzC,IAAI,EAAE,OAAO,CAAA;IACb,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAChC;;;;OAIG;IACH,IAAI,EAAE;QAAE,GAAG,EAAE,UAAU,CAAC;QAAC,EAAE,EAAE,UAAU,CAAC;QAAC,GAAG,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAA;CAClE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CA8DrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CA6FnF;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAsD,CAAA"}
|