@agenthippo-ai/agenthippo 0.1.1 → 1.110.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/out/agentpack/index.js +2 -1
  2. package/out/agentpack/paths.js +23 -0
  3. package/out/analytics/dashboard/fleetDisplayUtils.js +3 -0
  4. package/out/analytics/dashboard/provider.js +13 -2
  5. package/out/analytics/dashboard/webview/panel.js +293 -82
  6. package/out/analytics/identity.js +0 -0
  7. package/out/analytics/service.js +23 -25
  8. package/out/analytics/sessionEvents.js +109 -22
  9. package/out/auth/authBaseUrl.js +59 -0
  10. package/out/auth/bootstrapApply.js +9 -10
  11. package/out/auth/brokerClient.js +49 -15
  12. package/out/auth/onboardingPrompt.js +112 -0
  13. package/out/auth/provider.js +9 -22
  14. package/out/auth/sessionStore.js +3 -40
  15. package/out/auth/signInFlow.js +2 -1
  16. package/out/auth-broker/config.js +54 -4
  17. package/out/auth-broker/server.js +152 -20
  18. package/out/auth-broker/store.js +25 -24
  19. package/out/authority/warrant.js +206 -0
  20. package/out/branding.js +27 -1
  21. package/out/cli/commands/ask.js +3 -0
  22. package/out/cli/commands/chat.js +3 -0
  23. package/out/cli/commands/conformance.js +249 -0
  24. package/out/cli/commands/data-plane.js +67 -0
  25. package/out/cli/commands/deploy.js +50 -10
  26. package/out/cli/commands/gateway.js +58 -0
  27. package/out/cli/commands/idp.js +85 -0
  28. package/out/cli/commands/pack.js +182 -3
  29. package/out/cli/commands/sandbox.js +332 -0
  30. package/out/cli/commands/serve.js +1165 -82
  31. package/out/cli/commands/store.js +12 -4
  32. package/out/cli/credential-context.js +42 -80
  33. package/out/cli/data-plane/broker.js +78 -0
  34. package/out/cli/data-plane/connector-host.js +121 -0
  35. package/out/cli/data-plane/egress.js +189 -0
  36. package/out/cli/data-plane/gateway.js +218 -0
  37. package/out/cli/data-plane/index.js +152 -0
  38. package/out/cli/data-plane/registry.js +89 -0
  39. package/out/cli/data-plane/remote.js +106 -0
  40. package/out/cli/data-plane/sidecar.js +161 -0
  41. package/out/cli/deploy/blueprints/registry.js +84 -0
  42. package/out/cli/deploy/layers/identity.js +172 -0
  43. package/out/cli/deploy-init.js +1182 -347
  44. package/out/cli/deps.js +106 -2
  45. package/out/cli/idp-init.js +338 -0
  46. package/out/cli/index.js +192 -23
  47. package/out/cli/pack-install-ref.js +15 -0
  48. package/out/cli/pack-loader.js +45 -3
  49. package/out/cli/pack-runtime.js +61 -0
  50. package/out/cli/runtime.js +44 -3
  51. package/out/cli/serve-hardening.js +139 -3
  52. package/out/cli/state-sync.js +16 -15
  53. package/out/cli/utils.js +12 -1
  54. package/out/engines/base.js +32 -3
  55. package/out/engines/claude.js +47 -8
  56. package/out/engines/codex.js +125 -22
  57. package/out/engines/custom.js +54 -12
  58. package/out/evidence/sessionShip.js +610 -0
  59. package/out/extension.js +13 -2
  60. package/out/gateway/bridge.js +40 -2
  61. package/out/gateway/client.js +34 -1
  62. package/out/gateway/installSource.js +68 -0
  63. package/out/gateway/lifecycle.js +185 -51
  64. package/out/gateway/outboundPaths.js +4 -1
  65. package/out/gateway/outboundSend.js +6 -6
  66. package/out/gateway/secretsPreflight.js +90 -0
  67. package/out/gateway/service.js +7 -2
  68. package/out/headless/index.js +40 -9
  69. package/out/live-e2e/mcp-demo/server.mjs +32 -0
  70. package/out/live-probe/connector.mjs +8 -0
  71. package/out/live-probe/env-report.mjs +8 -0
  72. package/out/mcp.js +115 -67
  73. package/out/pack/caps.js +271 -0
  74. package/out/pack/governor.js +309 -0
  75. package/out/pack/lease-schema.js +270 -0
  76. package/out/pack/lease.js +640 -0
  77. package/out/pack/reconcile.js +217 -0
  78. package/out/pack/signature.js +839 -0
  79. package/out/remote/handleRemoteChat.js +44 -3
  80. package/out/remote/remoteTrust.js +277 -0
  81. package/out/remote/serveClient.js +52 -5
  82. package/out/runner/host.js +131 -0
  83. package/out/runner/protocol.js +108 -0
  84. package/out/runner/remoteEngine.js +130 -0
  85. package/out/runtime/interfaces/edit-tracker.js +2 -0
  86. package/out/runtime/vscode/vscode-edit-tracker.js +2 -0
  87. package/out/sandbox/containerDriver.js +570 -0
  88. package/out/sandbox/processDriver.js +315 -0
  89. package/out/sandbox/sandboxRunner.js +191 -0
  90. package/out/sandbox/support.js +301 -0
  91. package/out/sandbox/types.js +55 -0
  92. package/out/scripts/agentide-litellm.sh +67 -5
  93. package/out/scripts/agentide_litellm_hooks_v1.py +182 -21
  94. package/out/scripts/analytics/agentide-litellm-otel.config.yaml +94 -118
  95. package/out/scripts/analytics/setup-analytics.ps1 +37 -13
  96. package/out/scripts/analytics/setup-analytics.sh +93 -13
  97. package/out/scripts/analytics/start-analytics.sh +86 -14
  98. package/out/scripts/gateway/setup-gateway.sh +72 -32
  99. package/out/shared/models.js +12 -111
  100. package/out/shared/providers.js +2 -2
  101. package/out/spotlight/install.js +7 -1
  102. package/out/store/index.js +41 -10
  103. package/out/sync.js +3 -1
  104. package/out/test/analytics.test.js +198 -34
  105. package/out/test/auth-baseurl.test.js +132 -0
  106. package/out/test/auth-bootstrapApply.test.js +27 -6
  107. package/out/test/auth-broker-hardening.test.js +227 -0
  108. package/out/test/auth-broker.test.js +112 -9
  109. package/out/test/blueprint-registry.test.js +105 -0
  110. package/out/test/branding.test.js +13 -0
  111. package/out/test/caps-governor.test.js +455 -0
  112. package/out/test/codex-new-file-survival.test.js +119 -0
  113. package/out/test/configuration-scopes.test.js +131 -0
  114. package/out/test/credential-context.test.js +23 -28
  115. package/out/test/custom-env-layering.test.js +151 -0
  116. package/out/test/data-plane-engine-wiring.test.js +250 -0
  117. package/out/test/data-plane.test.js +311 -0
  118. package/out/test/deploy-init.test.js +295 -4
  119. package/out/test/egress-broker.test.js +172 -0
  120. package/out/test/fleetDisplayUtils.test.js +4 -0
  121. package/out/test/gateway-client.test.js +28 -0
  122. package/out/test/gateway-install-source.test.js +111 -0
  123. package/out/test/gateway-lifecycle.test.js +1 -1
  124. package/out/test/gateway-outbound.test.js +7 -0
  125. package/out/test/gateway-secrets-preflight.test.js +127 -0
  126. package/out/test/gateway-session-routing.test.js +18 -0
  127. package/out/test/governor-hardening.test.js +217 -0
  128. package/out/test/headless-sync.test.js +22 -0
  129. package/out/test/idp-init.test.js +151 -0
  130. package/out/test/lease-signature.test.js +357 -0
  131. package/out/test/lease-trust-root.test.js +273 -0
  132. package/out/test/lease-validation.test.js +169 -0
  133. package/out/test/lease.test.js +114 -0
  134. package/out/test/mcp-obo.test.js +52 -27
  135. package/out/test/mcp.test.js +69 -3
  136. package/out/test/model-routing.test.js +133 -0
  137. package/out/test/pack-admission.test.js +216 -0
  138. package/out/test/pack-digest-parity.test.js +140 -0
  139. package/out/test/pack-reconcile.test.js +183 -0
  140. package/out/test/pack-signature-artifact.test.js +103 -0
  141. package/out/test/pack-signature.test.js +176 -0
  142. package/out/test/pack-trust-root.test.js +202 -0
  143. package/out/test/remote-trust.test.js +242 -0
  144. package/out/test/runner-protocol.test.js +249 -0
  145. package/out/test/sandbox-driver.test.js +553 -0
  146. package/out/test/sandbox-hardening.test.js +395 -0
  147. package/out/test/sandbox-runner.test.js +343 -0
  148. package/out/test/serve-gateway-turn.test.js +267 -0
  149. package/out/test/serve-hardening.test.js +125 -6
  150. package/out/test/serveClient.test.js +38 -5
  151. package/out/test/sessionShip.test.js +560 -0
  152. package/out/test/spotlightPublish.test.js +28 -0
  153. package/out/test/state-sync-peer.test.js +18 -5
  154. package/out/test/store-install-safe.test.js +69 -0
  155. package/out/test/tls-bypass.test.js +90 -0
  156. package/out/test/warrant.test.js +138 -0
  157. package/out/utils.js +73 -20
  158. package/package.json +1 -1
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) AgentHippo.ai. All rights reserved.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DENY_SCOPE_ALIASES = exports.DENY_MODE_ALIASES = exports.STRICTEST_DENY_MODE = exports.DENY_MODES = exports.DENY_SCOPES = exports.STRICTEST_ON_BREACH = exports.ON_BREACH_ALIASES = exports.ON_BREACH_ACTIONS = exports.DEPRECATED_CAP_SPELLINGS = exports.LEASE_CAP_ALIASES = exports.LEASE_CAP_FIELDS = void 0;
7
+ exports.parseCapPolicy = parseCapPolicy;
8
+ exports.parseLease = parseLease;
9
+ // ---------------------------------------------------------------------------------------------
10
+ // Vocabulary tables — extend these, not the code below
11
+ // ---------------------------------------------------------------------------------------------
12
+ /** Numeric cap fields, and what a valid value looks like. */
13
+ exports.LEASE_CAP_FIELDS = {
14
+ maxTurnsPerSession: { kind: 'positive-int' },
15
+ maxSessionSeconds: { kind: 'positive-int' },
16
+ maxConcurrentSandboxes: { kind: 'positive-int' },
17
+ };
18
+ /**
19
+ * Alternative spellings for cap fields, mapped onto the canonical name.
20
+ *
21
+ * The extension point for vocabulary migrations. Adding a row is the entire change — there is no
22
+ * second place that reads a cap field, so an alias added here works for leases, env and CLI flags
23
+ * at once.
24
+ */
25
+ exports.LEASE_CAP_ALIASES = {
26
+ /** Pre-rename vocabulary: a "cell" is what a sandbox used to be called. */
27
+ maxConcurrentCells: 'maxConcurrentSandboxes',
28
+ };
29
+ /** Deprecated cap spellings → the message an operator should see. Keyed by the OLD name. */
30
+ exports.DEPRECATED_CAP_SPELLINGS = {
31
+ maxConcurrentCells: 'maxConcurrentSandboxes',
32
+ AGENTHIPPO_MAX_CONCURRENT_CELLS: 'AGENTHIPPO_MAX_CONCURRENT_SANDBOXES',
33
+ 'destroy-cell': 'destroy-sandbox',
34
+ '--max-concurrent-cells': '--max-concurrent-sandboxes',
35
+ };
36
+ /**
37
+ * Breach actions, ordered by STRICTNESS. An unrecognised value clamps to the highest strictness
38
+ * in this table, never to the lowest and never to "unset".
39
+ */
40
+ exports.ON_BREACH_ACTIONS = {
41
+ 'revoke-inference': { strictness: 1 },
42
+ 'destroy-sandbox': { strictness: 2 },
43
+ };
44
+ /** Alternative spellings for breach actions. Same extension point as `LEASE_CAP_ALIASES`. */
45
+ exports.ON_BREACH_ALIASES = {
46
+ /** Pre-rename vocabulary. Deliberately mapped rather than dropped: dropping it SOFTENED the action. */
47
+ 'destroy-cell': 'destroy-sandbox',
48
+ };
49
+ /** The strictest action this build knows about — where an unrecognised value lands. */
50
+ exports.STRICTEST_ON_BREACH = Object.keys(exports.ON_BREACH_ACTIONS)
51
+ .reduce((a, b) => (exports.ON_BREACH_ACTIONS[a].strictness >= exports.ON_BREACH_ACTIONS[b].strictness ? a : b));
52
+ /** Deny-rule scopes. An unknown scope rejects the document — see rule 1 above. */
53
+ exports.DENY_SCOPES = ['session', 'user', 'pack'];
54
+ /** Deny-rule modes, ordered by strictness for the same reason `onBreach` is. */
55
+ exports.DENY_MODES = { drain: { strictness: 1 }, kill: { strictness: 2 } };
56
+ exports.STRICTEST_DENY_MODE = 'kill';
57
+ /** Alternative spellings for deny modes / scopes, for the back-compat layer. */
58
+ exports.DENY_MODE_ALIASES = {};
59
+ exports.DENY_SCOPE_ALIASES = {};
60
+ const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
61
+ /**
62
+ * A cap value the meter can actually compare against.
63
+ *
64
+ * Rejects — never coerces — strings. `parseInt("lots")` is NaN and `Number("")` is 0; both would
65
+ * turn a control-plane typo into a disabled or absurd cap. A cap that cannot be read is a lease
66
+ * that cannot be trusted.
67
+ */
68
+ function parseCapNumber(field, raw) {
69
+ if (typeof raw !== 'number') {
70
+ return { ok: false, reason: `${field} must be a number, got ${typeof raw} (${JSON.stringify(raw)})` };
71
+ }
72
+ if (!Number.isFinite(raw)) {
73
+ return { ok: false, reason: `${field} must be finite, got ${raw}` };
74
+ }
75
+ if (raw <= 0) {
76
+ // 0 has meant "unlimited" for --max-turns-per-session since before caps existed, but from a
77
+ // control plane it is far more likely to be an unset field serialised as a number. Refuse
78
+ // rather than guess which meaning was intended.
79
+ return { ok: false, reason: `${field} must be greater than 0, got ${raw} (omit the field for "unbounded")` };
80
+ }
81
+ if (!Number.isInteger(raw)) {
82
+ return { ok: false, reason: `${field} must be a whole number, got ${raw}` };
83
+ }
84
+ return { ok: true, value: raw };
85
+ }
86
+ /**
87
+ * Validate a cap policy from an untrusted source.
88
+ *
89
+ * Also used by `capsFromEnv`, so a local flag and a control-plane field are held to exactly the
90
+ * same standard — the alternative is two vocabularies that drift.
91
+ */
92
+ function parseCapPolicy(raw, where = 'caps') {
93
+ if (raw === undefined || raw === null) {
94
+ return { ok: true, caps: {}, warnings: [] };
95
+ }
96
+ if (!isPlainObject(raw)) {
97
+ return { ok: false, reason: `${where} must be an object` };
98
+ }
99
+ const warnings = [];
100
+ const caps = {};
101
+ for (const [key, value] of Object.entries(raw)) {
102
+ if (value === undefined || value === null) {
103
+ continue;
104
+ }
105
+ if (key === 'onBreach') {
106
+ continue;
107
+ }
108
+ const canonical = (key in exports.LEASE_CAP_FIELDS ? key : exports.LEASE_CAP_ALIASES[key]);
109
+ if (!canonical) {
110
+ // Unknown cap fields are TOLERATED (a newer control plane may send a cap this build does
111
+ // not implement) but never silently: an operator must be able to see that the bound they
112
+ // configured is not being enforced by this version.
113
+ warnings.push(`${where}.${key} is not a cap this build understands and is NOT being enforced`);
114
+ continue;
115
+ }
116
+ const parsed = parseCapNumber(`${where}.${key}`, value);
117
+ if (!parsed.ok) {
118
+ return { ok: false, reason: parsed.reason };
119
+ }
120
+ caps[canonical] = parsed.value;
121
+ }
122
+ const rawBreach = raw.onBreach;
123
+ if (rawBreach !== undefined && rawBreach !== null) {
124
+ if (typeof rawBreach !== 'string') {
125
+ return { ok: false, reason: `${where}.onBreach must be a string, got ${typeof rawBreach}` };
126
+ }
127
+ const canonical = (rawBreach in exports.ON_BREACH_ACTIONS ? rawBreach : exports.ON_BREACH_ALIASES[rawBreach]);
128
+ if (canonical) {
129
+ caps.onBreach = canonical;
130
+ }
131
+ else {
132
+ // FAIL CLOSED, LOUDLY. Leaving it unset let an unrecognised value fall through mergeCaps
133
+ // and soften the breach action from destroy-sandbox to revoke-inference — a typo in the
134
+ // control plane weakening enforcement is the exact failure mode this guards.
135
+ caps.onBreach = exports.STRICTEST_ON_BREACH;
136
+ warnings.push(`${where}.onBreach="${rawBreach}" is not an action this build understands. ` +
137
+ `Failing CLOSED to "${exports.STRICTEST_ON_BREACH}" (the strictest known action). ` +
138
+ `Known actions: ${Object.keys(exports.ON_BREACH_ACTIONS).join(', ')}.`);
139
+ }
140
+ }
141
+ return { ok: true, caps, warnings };
142
+ }
143
+ function parseDenyRule(raw, index) {
144
+ if (!isPlainObject(raw)) {
145
+ return { ok: false, reason: `deny[${index}] must be an object` };
146
+ }
147
+ const warnings = [];
148
+ const rawScope = raw.scope;
149
+ if (typeof rawScope !== 'string') {
150
+ return { ok: false, reason: `deny[${index}].scope must be a string` };
151
+ }
152
+ const scope = exports.DENY_SCOPES.includes(rawScope)
153
+ ? rawScope
154
+ : exports.DENY_SCOPE_ALIASES[rawScope];
155
+ if (!scope) {
156
+ // Rejecting the document is the fail-closed choice: a rule this build cannot evaluate is a
157
+ // stop order it would silently not apply, while the console reports it as applied.
158
+ return { ok: false, reason: `deny[${index}].scope "${rawScope}" is not a scope this build understands (known: ${exports.DENY_SCOPES.join(', ')})` };
159
+ }
160
+ if (typeof raw.match !== 'string' || raw.match.length === 0) {
161
+ return { ok: false, reason: `deny[${index}].match must be a non-empty string` };
162
+ }
163
+ const rawMode = raw.mode;
164
+ if (typeof rawMode !== 'string') {
165
+ return { ok: false, reason: `deny[${index}].mode must be a string` };
166
+ }
167
+ let mode = (rawMode in exports.DENY_MODES ? rawMode : exports.DENY_MODE_ALIASES[rawMode]);
168
+ if (!mode) {
169
+ // Same asymmetry as onBreach: clamp UP. A stop order whose mode we cannot read is treated as
170
+ // the strictest one, never dropped and never softened.
171
+ mode = exports.STRICTEST_DENY_MODE;
172
+ warnings.push(`deny[${index}].mode="${rawMode}" is not a mode this build understands. ` +
173
+ `Failing CLOSED to "${exports.STRICTEST_DENY_MODE}". Known modes: ${Object.keys(exports.DENY_MODES).join(', ')}.`);
174
+ }
175
+ const rule = { scope, match: raw.match, mode };
176
+ if (raw.reason !== undefined) {
177
+ if (typeof raw.reason !== 'string') {
178
+ return { ok: false, reason: `deny[${index}].reason must be a string` };
179
+ }
180
+ rule.reason = raw.reason;
181
+ }
182
+ if (raw.until !== undefined && raw.until !== null) {
183
+ if (typeof raw.until !== 'number' || !Number.isFinite(raw.until)) {
184
+ return { ok: false, reason: `deny[${index}].until must be a finite epoch-seconds number` };
185
+ }
186
+ rule.until = raw.until;
187
+ }
188
+ if (raw.user !== undefined && raw.user !== null) {
189
+ if (typeof raw.user !== 'string') {
190
+ return { ok: false, reason: `deny[${index}].user must be a string` };
191
+ }
192
+ rule.user = raw.user;
193
+ }
194
+ if (raw.followUser !== undefined && raw.followUser !== null) {
195
+ if (typeof raw.followUser !== 'boolean') {
196
+ return { ok: false, reason: `deny[${index}].followUser must be a boolean` };
197
+ }
198
+ rule.followUser = raw.followUser;
199
+ }
200
+ return { ok: true, rule, warnings };
201
+ }
202
+ /**
203
+ * Parse and validate a whole lease document.
204
+ *
205
+ * **This is the exported validator the back-compat/alias work layers onto.** Adding a row to
206
+ * `LEASE_CAP_ALIASES`, `ON_BREACH_ALIASES`, `DENY_MODE_ALIASES` or `DENY_SCOPE_ALIASES` is
207
+ * sufficient; there is no second place that reads a lease field.
208
+ */
209
+ function parseLease(raw) {
210
+ if (!isPlainObject(raw)) {
211
+ return { ok: false, reason: 'lease must be a JSON object' };
212
+ }
213
+ const warnings = [];
214
+ if (typeof raw.pack !== 'string' || raw.pack.length === 0) {
215
+ return { ok: false, reason: 'lease.pack must be a non-empty string' };
216
+ }
217
+ if (typeof raw.enabled !== 'boolean') {
218
+ // Not coerced. `enabled: "false"` is truthy in JavaScript, so a string here would lift the
219
+ // kill switch rather than apply it — the single most dangerous coercion in this document.
220
+ return { ok: false, reason: `lease.enabled must be a boolean, got ${typeof raw.enabled}` };
221
+ }
222
+ if (typeof raw.expiresAt !== 'number' || !Number.isFinite(raw.expiresAt)) {
223
+ return { ok: false, reason: `lease.expiresAt must be a finite epoch-seconds number, got ${JSON.stringify(raw.expiresAt)}` };
224
+ }
225
+ const lease = { pack: raw.pack, enabled: raw.enabled, expiresAt: raw.expiresAt };
226
+ for (const key of ['version', 'imageDigest', 'reason']) {
227
+ const v = raw[key];
228
+ if (v === undefined || v === null) {
229
+ continue;
230
+ }
231
+ if (typeof v !== 'string') {
232
+ return { ok: false, reason: `lease.${key} must be a string, got ${typeof v}` };
233
+ }
234
+ lease[key] = v;
235
+ }
236
+ for (const key of ['requireSignedPack', 'requireSignedLease']) {
237
+ const v = raw[key];
238
+ if (v === undefined || v === null) {
239
+ continue;
240
+ }
241
+ if (typeof v !== 'boolean') {
242
+ return { ok: false, reason: `lease.${key} must be a boolean, got ${typeof v}` };
243
+ }
244
+ lease[key] = v;
245
+ }
246
+ if (raw.caps !== undefined && raw.caps !== null) {
247
+ const caps = parseCapPolicy(raw.caps, 'lease.caps');
248
+ if (!caps.ok) {
249
+ return { ok: false, reason: caps.reason };
250
+ }
251
+ lease.caps = caps.caps;
252
+ warnings.push(...caps.warnings);
253
+ }
254
+ if (raw.deny !== undefined && raw.deny !== null) {
255
+ if (!Array.isArray(raw.deny)) {
256
+ return { ok: false, reason: 'lease.deny must be an array' };
257
+ }
258
+ const rules = [];
259
+ for (let i = 0; i < raw.deny.length; i++) {
260
+ const parsed = parseDenyRule(raw.deny[i], i);
261
+ if (!parsed.ok) {
262
+ return { ok: false, reason: parsed.reason };
263
+ }
264
+ rules.push(parsed.rule);
265
+ warnings.push(...parsed.warnings);
266
+ }
267
+ lease.deny = rules;
268
+ }
269
+ return { ok: true, lease, warnings };
270
+ }