llm-cli-gateway 1.17.3 → 1.17.5

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 (64) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +1 -1
  3. package/dist/approval-manager.js +0 -8
  4. package/dist/async-job-manager.d.ts +0 -113
  5. package/dist/async-job-manager.js +6 -124
  6. package/dist/cache-stats.d.ts +0 -89
  7. package/dist/cache-stats.js +0 -62
  8. package/dist/claude-mcp-config.js +0 -1
  9. package/dist/cli-updater.d.ts +0 -8
  10. package/dist/cli-updater.js +0 -12
  11. package/dist/codex-json-parser.d.ts +0 -20
  12. package/dist/codex-json-parser.js +0 -21
  13. package/dist/config.d.ts +0 -31
  14. package/dist/config.js +2 -72
  15. package/dist/db.d.ts +0 -18
  16. package/dist/db.js +0 -22
  17. package/dist/doctor.d.ts +0 -49
  18. package/dist/doctor.js +0 -47
  19. package/dist/endpoint-exposure.js +0 -1
  20. package/dist/executor.d.ts +0 -19
  21. package/dist/executor.js +3 -38
  22. package/dist/flight-recorder.d.ts +0 -26
  23. package/dist/flight-recorder.js +1 -70
  24. package/dist/gemini-json-parser.d.ts +0 -25
  25. package/dist/gemini-json-parser.js +0 -28
  26. package/dist/health.d.ts +0 -3
  27. package/dist/health.js +0 -3
  28. package/dist/index.d.ts +12 -208
  29. package/dist/index.js +116 -588
  30. package/dist/job-store.d.ts +0 -74
  31. package/dist/job-store.js +1 -73
  32. package/dist/logger.d.ts +0 -7
  33. package/dist/logger.js +0 -6
  34. package/dist/migrate-sessions.d.ts +0 -3
  35. package/dist/migrate-sessions.js +0 -16
  36. package/dist/migrate.js +1 -18
  37. package/dist/mistral-meta-json-parser.js +0 -67
  38. package/dist/model-registry.js +0 -13
  39. package/dist/pricing.d.ts +0 -46
  40. package/dist/pricing.js +0 -47
  41. package/dist/process-monitor.d.ts +0 -15
  42. package/dist/process-monitor.js +2 -31
  43. package/dist/prompt-parts.d.ts +6 -31
  44. package/dist/prompt-parts.js +0 -11
  45. package/dist/provider-status.d.ts +0 -8
  46. package/dist/provider-status.js +0 -11
  47. package/dist/request-helpers.d.ts +4 -316
  48. package/dist/request-helpers.js +13 -231
  49. package/dist/resources.d.ts +0 -20
  50. package/dist/resources.js +1 -34
  51. package/dist/retry.d.ts +0 -45
  52. package/dist/retry.js +3 -40
  53. package/dist/session-manager-pg.d.ts +0 -32
  54. package/dist/session-manager-pg.js +0 -32
  55. package/dist/session-manager.d.ts +0 -21
  56. package/dist/session-manager.js +1 -15
  57. package/dist/stream-json-parser.d.ts +0 -18
  58. package/dist/stream-json-parser.js +0 -22
  59. package/dist/upstream-contracts.d.ts +0 -55
  60. package/dist/upstream-contracts.js +86 -64
  61. package/dist/validation-orchestrator.js +0 -3
  62. package/dist/worktree-manager.d.ts +0 -9
  63. package/dist/worktree-manager.js +0 -21
  64. package/package.json +1 -1
@@ -1,33 +1,14 @@
1
- /**
2
- * Pure, side-effect-free helpers for request argument planning.
3
- * Zero I/O, zero dependencies on index-scoped collaborators.
4
- */
5
1
  import { existsSync, unlinkSync, writeFileSync } from "fs";
6
2
  import { tmpdir } from "os";
7
3
  import { join, isAbsolute } from "path";
8
4
  import { randomUUID } from "crypto";
9
5
  import { z } from "zod/v3";
10
- /** Prefix for gateway-generated session IDs. Enforces provenance structurally. */
11
6
  export const GATEWAY_SESSION_PREFIX = "gw-";
12
- /**
13
- * Validate that a user-provided sessionId doesn't use the reserved gateway prefix.
14
- * Throws if the ID starts with "gw-" — this namespace is reserved for gateway-generated IDs.
15
- */
16
7
  export function validateSessionId(sessionId) {
17
8
  if (sessionId.startsWith(GATEWAY_SESSION_PREFIX)) {
18
9
  throw new Error(`Session ID "${sessionId}" uses reserved prefix "${GATEWAY_SESSION_PREFIX}". Gateway-generated session IDs cannot be used for --resume.`);
19
10
  }
20
11
  }
21
- /**
22
- * Pure function: determine --resume args and session provenance from request flags.
23
- * Does NOT perform any session I/O — callers handle create/update separately.
24
- */
25
- /**
26
- * Reject CLI arg values that start with "-" to prevent argument injection.
27
- * spawn() doesn't invoke a shell so there's no shell injection, but a value
28
- * like "--dangerously-skip-permissions" passed as a tool name would be
29
- * interpreted as a flag by the child CLI.
30
- */
31
12
  export function sanitizeCliArgValues(values, fieldName) {
32
13
  for (const v of values) {
33
14
  if (v.startsWith("-")) {
@@ -70,12 +51,6 @@ export function resolveCodexSessionArgs(opts) {
70
51
  }
71
52
  return { mode: "new" };
72
53
  }
73
- /**
74
- * Grok-specific resume args. Grok accepts `--resume <id>` to resume a named session,
75
- * and `--continue` to resume the most recent session for the current working directory.
76
- * Unlike `resolveSessionResumeArgs`, "resume latest" maps to `--continue` (not `--resume latest`)
77
- * because Grok would interpret a literal "latest" as a session ID.
78
- */
79
54
  export function resolveGrokSessionArgs(opts) {
80
55
  if (opts.createNewSession) {
81
56
  return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
@@ -97,16 +72,6 @@ export function resolveGrokSessionArgs(opts) {
97
72
  }
98
73
  return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
99
74
  }
100
- /**
101
- * Mistral Vibe-specific resume args.
102
- *
103
- * Current Vibe defaults session logging on; older configs can explicitly set
104
- * `[session_logging] enabled = false`. The doctor checks that toggle before
105
- * callers rely on session continuity; this pure helper just emits the args.
106
- *
107
- * The args shape mirrors Grok (`--continue` for latest, `--resume <id>` for a
108
- * specific session) because Vibe exposes the same surface for its session log.
109
- */
110
75
  export function resolveMistralSessionArgs(opts) {
111
76
  if (opts.createNewSession) {
112
77
  return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
@@ -128,13 +93,6 @@ export function resolveMistralSessionArgs(opts) {
128
93
  }
129
94
  return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
130
95
  }
131
- /**
132
- * Vibe-specific permission mode mapping. Vibe replaces Grok's `--always-approve`
133
- * with an `--agent <mode>` enum. When the caller does not set a permissionMode,
134
- * the gateway emits `--agent auto-approve` explicitly: omitting the flag would
135
- * let Vibe pick its own default which may not be auto-approve, surprising
136
- * programmatic callers.
137
- */
138
96
  export const MISTRAL_AGENT_MODES = [
139
97
  "default",
140
98
  "plan",
@@ -145,16 +103,6 @@ export const MISTRAL_AGENT_MODES = [
145
103
  "lean",
146
104
  ];
147
105
  export const MISTRAL_DEFAULT_AGENT_MODE = "auto-approve";
148
- /**
149
- * Pure helper that builds Vibe's argv and env.
150
- *
151
- * - Model is selected via `VIBE_ACTIVE_MODEL` env var (NOT a `--model` flag).
152
- * - Permission mode emits `--agent <mode>` (defaults to `auto-approve` when unset).
153
- * - Allowed tools emit `--enabled-tools <tool>` once per tool (allowlist only).
154
- * - Output format emits `--output <text|json|streaming>` (legacy gateway
155
- * aliases `plain` and `stream-json` are normalized before spawn).
156
- * - Disallowed tools are accepted but ignored at the CLI boundary.
157
- */
158
106
  export function prepareMistralRequest(input) {
159
107
  const args = ["-p", input.prompt];
160
108
  const env = {};
@@ -166,12 +114,6 @@ export function prepareMistralRequest(input) {
166
114
  }
167
115
  const mode = input.permissionMode ?? MISTRAL_DEFAULT_AGENT_MODE;
168
116
  args.push("--agent", mode);
169
- if (input.effort) {
170
- args.push("--effort", input.effort);
171
- }
172
- if (input.reasoningEffort) {
173
- args.push("--reasoning-effort", input.reasoningEffort);
174
- }
175
117
  if (input.allowedTools && input.allowedTools.length > 0) {
176
118
  sanitizeCliArgValues(input.allowedTools, "allowedTools");
177
119
  for (const tool of input.allowedTools) {
@@ -208,14 +150,6 @@ function normalizeMistralOutputFormat(format) {
208
150
  return "streaming";
209
151
  return format;
210
152
  }
211
- //──────────────────────────────────────────────────────────────────────────────
212
- // U24: Permission / approval mode parity helpers
213
- //──────────────────────────────────────────────────────────────────────────────
214
- /**
215
- * Claude `--permission-mode` values. `default` is a no-op (no flag emitted) —
216
- * matches the CLI's behavior when the flag is absent, and avoids hard-coding an
217
- * undocumented literal.
218
- */
219
153
  export const CLAUDE_PERMISSION_MODES = [
220
154
  "default",
221
155
  "acceptEdits",
@@ -224,16 +158,6 @@ export const CLAUDE_PERMISSION_MODES = [
224
158
  "dontAsk",
225
159
  "bypassPermissions",
226
160
  ];
227
- /**
228
- * Resolve Claude's `--permission-mode` args.
229
- *
230
- * Precedence:
231
- * 1. If `permissionMode` is set, it wins. A warning is returned when
232
- * `dangerouslySkipPermissions: true` is also set (legacy + new conflict).
233
- * 2. Else if `dangerouslySkipPermissions: true`, emit `--permission-mode
234
- * bypassPermissions`.
235
- * 3. Else (or `permissionMode === "default"`) emit nothing.
236
- */
237
161
  export function resolveClaudePermissionFlags(input) {
238
162
  const { permissionMode, dangerouslySkipPermissions } = input;
239
163
  let warning;
@@ -252,33 +176,9 @@ export function resolveClaudePermissionFlags(input) {
252
176
  }
253
177
  return { args: [] };
254
178
  }
255
- /**
256
- * Gemini `--approval-mode` values. Preserves existing values (`default`,
257
- * `auto_edit`, `yolo`) and adds `plan` for parity with Claude's plan mode.
258
- */
259
179
  export const GEMINI_APPROVAL_MODES = ["default", "auto_edit", "yolo", "plan"];
260
- /**
261
- * Codex sandbox modes (for `--sandbox <mode>`).
262
- */
263
180
  export const CODEX_SANDBOX_MODES = ["read-only", "workspace-write", "danger-full-access"];
264
- /**
265
- * Deprecated Codex approval modes. Current Codex no longer exposes an
266
- * `--ask-for-approval` flag; the MCP input is temporarily retained so older
267
- * callers do not fail schema validation, but it emits no CLI argv.
268
- */
269
181
  export const CODEX_ASK_FOR_APPROVAL_MODES = ["untrusted", "on-request", "never"];
270
- /**
271
- * Resolve current Codex sandbox args from the modern params + legacy
272
- * `fullAuto` shorthand. Current Codex exposes `--sandbox`, but no longer
273
- * exposes `--ask-for-approval` or `--full-auto`.
274
- *
275
- * Precedence:
276
- * 1. Explicit `sandboxMode` emits `--sandbox <mode>`.
277
- * 2. Else if `fullAuto: true`, expand to `--sandbox workspace-write`.
278
- * 3. Deprecated `askForApproval` and `useLegacyFullAutoFlag` emit no argv
279
- * and return warnings for callers to surface/log.
280
- * 4. Else emit nothing.
281
- */
282
182
  export function resolveCodexSandboxFlags(input) {
283
183
  const { sandboxMode, askForApproval, fullAuto, useLegacyFullAutoFlag } = input;
284
184
  const args = [];
@@ -300,17 +200,6 @@ export function resolveCodexSandboxFlags(input) {
300
200
  }
301
201
  return { args, warning: warnings.length > 0 ? warnings.join(" ") : undefined };
302
202
  }
303
- /**
304
- * Flags that `codex exec resume` rejects (the original session's policy is
305
- * inherited). Callers must drop these when building resume argv.
306
- *
307
- * Verified against `codex exec resume --help` (codex-cli 0.135.0):
308
- * `--sandbox`, `--add-dir`, `-C`, `--cd`, `--profile`, and `--search` are rejected.
309
- * Deprecated `--full-auto` / `--ask-for-approval` are kept here defensively so
310
- * legacy pre-filtered segments are stripped instead of reaching spawn.
311
- * `--output-schema` and `-c key=value` ARE accepted on resume and therefore are
312
- * NOT in this filter (Phase 4 slice α restored the previously-silent drop of those two).
313
- */
314
203
  export const CODEX_RESUME_FILTERED_FLAGS = new Set([
315
204
  "--full-auto",
316
205
  "--sandbox",
@@ -321,10 +210,6 @@ export const CODEX_RESUME_FILTERED_FLAGS = new Set([
321
210
  "--profile",
322
211
  "--search",
323
212
  ]);
324
- /**
325
- * Codex flags that take exactly one value (consumed together with the flag).
326
- * `--full-auto` and `--search` are bare booleans and intentionally absent.
327
- */
328
213
  const CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE = new Set([
329
214
  "--sandbox",
330
215
  "--ask-for-approval",
@@ -333,13 +218,6 @@ const CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE = new Set([
333
218
  "--cd",
334
219
  "--profile",
335
220
  ]);
336
- /**
337
- * Strip resume-incompatible flag/value pairs from a Codex argv segment.
338
- *
339
- * Bare flags (`--full-auto`, `--search`) drop without consuming a value.
340
- * Value-taking flags (`--sandbox`, `--ask-for-approval`, `--add-dir`, `-C`, `--cd`,
341
- * `--profile`) drop together with their immediately-following value.
342
- */
343
221
  export function filterCodexResumeFlags(args) {
344
222
  const out = [];
345
223
  for (let i = 0; i < args.length; i++) {
@@ -349,26 +227,12 @@ export function filterCodexResumeFlags(args) {
349
227
  continue;
350
228
  }
351
229
  if (CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE.has(a)) {
352
- i += 1; // also skip the value
230
+ i += 1;
353
231
  }
354
232
  }
355
233
  return out;
356
234
  }
357
- //──────────────────────────────────────────────────────────────────────────────
358
- // U25: Claude high-impact features
359
- //──────────────────────────────────────────────────────────────────────────────
360
- /**
361
- * Claude `--effort` enum values. Mirrors the model-side effort axis.
362
- */
363
235
  export const CLAUDE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
364
- /**
365
- * Standalone Zod object for U25's high-impact param subset. Enforces the
366
- * `systemPrompt` / `appendSystemPrompt` mutual-exclusion via `.refine(...)`.
367
- *
368
- * The MCP SDK's `server.tool` takes a raw shape (no top-level refine), so the
369
- * tool callback re-checks the constraint and returns an error response. This
370
- * exported schema is what tests use to verify Zod-level enforcement.
371
- */
372
236
  export const CLAUDE_HIGH_IMPACT_PARAMS_SCHEMA = z
373
237
  .object({
374
238
  agent: z.string().optional(),
@@ -385,12 +249,6 @@ export const CLAUDE_HIGH_IMPACT_PARAMS_SCHEMA = z
385
249
  message: "systemPrompt and appendSystemPrompt are mutually exclusive; use one or the other (not both).",
386
250
  path: ["appendSystemPrompt"],
387
251
  });
388
- /**
389
- * Minimal Anthropic agent-definition schema. Mirrors the shape expected by
390
- * Claude CLI's `--agents` inline JSON argument. We validate the *required*
391
- * keys (`description`, `prompt`) up-front so a malformed payload fails fast
392
- * with an actionable error instead of producing an opaque CLI exit.
393
- */
394
252
  export const CLAUDE_AGENT_DEFINITION_SCHEMA = z
395
253
  .object({
396
254
  description: z.string().min(1, "agent.description must be a non-empty string"),
@@ -399,13 +257,6 @@ export const CLAUDE_AGENT_DEFINITION_SCHEMA = z
399
257
  model: z.string().optional(),
400
258
  })
401
259
  .passthrough();
402
- /**
403
- * Validate an `agents` map against {@link CLAUDE_AGENT_DEFINITION_SCHEMA}.
404
- *
405
- * Returns `{ ok: true, value }` on success and `{ ok: false, agentKey, message }`
406
- * on the first failing entry. The caller is responsible for turning the failure
407
- * into a tool-level error response (e.g. via `createErrorResponse`).
408
- */
409
260
  export function validateClaudeAgentsMap(agents) {
410
261
  const validated = {};
411
262
  for (const [key, raw] of Object.entries(agents)) {
@@ -423,13 +274,6 @@ export function validateClaudeAgentsMap(agents) {
423
274
  }
424
275
  return { ok: true, value: validated };
425
276
  }
426
- /**
427
- * Emit Claude high-impact feature flags (U25) as a flat argv segment.
428
- *
429
- * Mutual-exclusion of `systemPrompt`/`appendSystemPrompt` is enforced upstream
430
- * at the Zod schema (`.refine(...)`); this helper does *not* re-check it, so
431
- * tests can exercise either flag in isolation.
432
- */
433
277
  export function prepareClaudeHighImpactFlags(input) {
434
278
  const args = [];
435
279
  if (input.agent) {
@@ -471,23 +315,20 @@ export function prepareClaudeHighImpactFlags(input) {
471
315
  args.push("--add-dir", dir);
472
316
  }
473
317
  }
318
+ if (input.noSessionPersistence) {
319
+ args.push("--no-session-persistence");
320
+ }
321
+ if (input.settingSources !== undefined) {
322
+ args.push("--setting-sources", input.settingSources);
323
+ }
324
+ if (input.settings !== undefined) {
325
+ args.push("--settings", input.settings);
326
+ }
327
+ if (input.tools && input.tools.length > 0) {
328
+ args.push("--tools", ...input.tools);
329
+ }
474
330
  return args;
475
331
  }
476
- //──────────────────────────────────────────────────────────────────────────────
477
- // U26: Codex high-impact features
478
- //──────────────────────────────────────────────────────────────────────────────
479
- /**
480
- * Zod schema for Codex `configOverrides` map.
481
- *
482
- * Hard requirements (argv-injection prevention):
483
- * - Keys MUST match /^[a-zA-Z0-9._]+$/ (no whitespace, no equals, no flag-like prefixes).
484
- * - Values MUST NOT contain CR or LF — newlines could be re-interpreted by the
485
- * CLI's TOML parser as new keys.
486
- *
487
- * The CLI consumes overrides as `-c key=value`. We rely on `spawn(..., args)`
488
- * passing argv directly without a shell, so we forbid shape-breaking
489
- * characters rather than shell-escaping values.
490
- */
491
332
  export const CODEX_CONFIG_OVERRIDES_SCHEMA = z
492
333
  .record(z
493
334
  .string()
@@ -495,10 +336,6 @@ export const CODEX_CONFIG_OVERRIDES_SCHEMA = z
495
336
  message: "configOverrides values must not contain CR or LF characters",
496
337
  }))
497
338
  .optional();
498
- /**
499
- * Emit `-c key=value` pairs for each override. Caller MUST have validated the
500
- * map with {@link CODEX_CONFIG_OVERRIDES_SCHEMA} first.
501
- */
502
339
  export function emitCodexConfigOverrideArgs(overrides) {
503
340
  if (!overrides)
504
341
  return [];
@@ -526,15 +363,10 @@ export function prepareCodexOutputSchema(outputSchema) {
526
363
  unlinkSync(path);
527
364
  }
528
365
  catch {
529
- // Best-effort: if the file is already gone, ignore.
530
366
  }
531
367
  };
532
368
  return { path, cleanup };
533
369
  }
534
- /**
535
- * Validate that every image path exists on disk. Returns the first missing
536
- * path on failure; `null` on success.
537
- */
538
370
  export function findMissingImagePath(images) {
539
371
  if (!images || images.length === 0)
540
372
  return null;
@@ -544,11 +376,6 @@ export function findMissingImagePath(images) {
544
376
  }
545
377
  return null;
546
378
  }
547
- /**
548
- * Zod schema for the U26 Codex high-impact feature subset. Used by the
549
- * `codex_request` / `codex_request_async` tool schemas to validate the new
550
- * params before they reach `prepareCodexRequest`.
551
- */
552
379
  export const CODEX_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
553
380
  outputSchema: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
554
381
  search: z.boolean().optional(),
@@ -559,14 +386,6 @@ export const CODEX_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
559
386
  ignoreUserConfig: z.boolean().optional(),
560
387
  ignoreRules: z.boolean().optional(),
561
388
  });
562
- /**
563
- * Build the U26 argv segment AND any required side-effect handles.
564
- *
565
- * IMPORTANT: When this function writes a temp file for `outputSchema`, the
566
- * returned `cleanup` function MUST be invoked by the caller (typically in a
567
- * `finally` block around the spawn). Failing to do so leaks `0o600` temp
568
- * files into `os.tmpdir()`.
569
- */
570
389
  export function prepareCodexHighImpactFlags(input) {
571
390
  const missingImagePath = findMissingImagePath(input.images);
572
391
  if (missingImagePath) {
@@ -621,20 +440,9 @@ export function prepareCodexForkRequest(input) {
621
440
  if (forkLast) {
622
441
  return { args: ["fork", "--last", prompt] };
623
442
  }
624
- // sessionId path
625
443
  validateSessionId(sessionId);
626
444
  return { args: ["fork", sessionId, prompt] };
627
445
  }
628
- //──────────────────────────────────────────────────────────────────────────────
629
- // U27: Gemini high-impact features
630
- //──────────────────────────────────────────────────────────────────────────────
631
- /**
632
- * Prepend `@<abs-path>` tokens to a Gemini prompt so the CLI's attachment
633
- * resolver picks them up. Each path MUST be absolute and exist on disk.
634
- *
635
- * Returns the mutated prompt. Throws on validation failure so the caller can
636
- * convert to a `createErrorResponse`.
637
- */
638
446
  export function prependGeminiAttachments(prompt, attachments) {
639
447
  if (!attachments || attachments.length === 0)
640
448
  return prompt;
@@ -648,10 +456,6 @@ export function prependGeminiAttachments(prompt, attachments) {
648
456
  validateGeminiAttachmentTokenPath(p);
649
457
  }
650
458
  const tokens = attachments.map(p => `@${p}`).join(" ");
651
- // Gemini attachments are prompt-level @path tokens rather than shell
652
- // commands. Paths are absolute, existing, and token-safe before this join.
653
- //
654
- // codeql[js/shell-command-constructed-from-input]
655
459
  return `${tokens} ${prompt}`;
656
460
  }
657
461
  function validateGeminiAttachmentTokenPath(path) {
@@ -661,14 +465,6 @@ function validateGeminiAttachmentTokenPath(path) {
661
465
  }
662
466
  }
663
467
  }
664
- /**
665
- * Zod schema for the U27 Gemini high-impact feature subset. Used by the
666
- * `gemini_request` / `gemini_request_async` tool schemas to validate the new
667
- * params before they reach `prepareGeminiRequest`.
668
- *
669
- * `attachments` paths are validated to be absolute at the Zod layer; existence
670
- * is enforced at execution time via `prependGeminiAttachments`.
671
- */
672
468
  export const GEMINI_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
673
469
  sandbox: z.boolean().optional(),
674
470
  policyFiles: z.array(z.string()).optional(),
@@ -679,15 +475,6 @@ export const GEMINI_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
679
475
  }))
680
476
  .optional(),
681
477
  });
682
- /**
683
- * Emit Gemini U27 high-impact flags. Policy paths are existence-checked here
684
- * so a missing file fails fast with an actionable error rather than producing
685
- * an opaque CLI exit.
686
- *
687
- * Does NOT handle `attachments` — those are mutated into the prompt string
688
- * via {@link prependGeminiAttachments} BEFORE the `-p <prompt>` pair is
689
- * emitted, preserving the U21 `-p` ordering invariant.
690
- */
691
478
  export function prepareGeminiHighImpactFlags(input) {
692
479
  if (input.policyFiles) {
693
480
  for (const p of input.policyFiles) {
@@ -723,11 +510,6 @@ export function prepareGeminiHighImpactFlags(input) {
723
510
  }
724
511
  return { args, missingPolicyPath: null, missingPolicyField: null };
725
512
  }
726
- /**
727
- * Resolve Gemini session args. Gemini CLI 0.43 exposes `--resume` but not a
728
- * supported `--session-id` flag for fresh sessions, so new-session requests
729
- * intentionally emit no session flag and let the CLI create its own session.
730
- */
731
513
  export function resolveGeminiSessionPlan(opts) {
732
514
  if (opts.sessionId && !opts.createNewSession) {
733
515
  validateSessionId(opts.sessionId);
@@ -26,31 +26,11 @@ export declare class ResourceProvider {
26
26
  private flightRecorder;
27
27
  private cacheAwareness;
28
28
  constructor(sessionManager: ISessionManager, performanceMetrics: PerformanceMetrics, flightRecorder?: FlightRecorderQuery, cacheAwareness?: CacheAwarenessConfig | null);
29
- /** Read-only flight-recorder accessor for cache-state resource readers. */
30
29
  getFlightRecorderQuery(): FlightRecorderQuery;
31
- /**
32
- * cache_state://global — aggregates across the entire flight recorder.
33
- * Optionally restrict to a recent window via `lastNHours`. Returns
34
- * tokens/hashes/aggregates ONLY — no prompt text fields. The redaction is
35
- * structural: the response shape (GlobalCacheStats) has no `prompt`,
36
- * `response`, `system`, or `task` field by construction.
37
- */
38
30
  readCacheStateGlobal(opts?: {
39
31
  lastNHours?: number;
40
32
  }): GlobalCacheStats;
41
- /**
42
- * cache_state://session/{sessionId} — per-session aggregates. Returns
43
- * empty defaults when the session has no rows. Token/hash fields only.
44
- *
45
- * Slice 3: populates `ttlRemainingMs` by applying the configured TTL
46
- * policy. Null for non-claude sessions or when the gateway has no
47
- * cache-awareness config loaded (defaults to 5-min policy).
48
- */
49
33
  readCacheStateSession(sessionId: string): SessionCacheStats;
50
- /**
51
- * cache_state://prefix/{hash} — per-stable-prefix-hash aggregates.
52
- * Returns empty defaults for unknown hashes. Token/hash fields only.
53
- */
54
34
  readCacheStateForPrefix(stablePrefixHash: string): PrefixCacheStats;
55
35
  listResources(): ResourceDefinition[];
56
36
  readResource(uri: string): Promise<ResourceContents | null>;
package/dist/resources.js CHANGED
@@ -5,43 +5,18 @@ export class ResourceProvider {
5
5
  performanceMetrics;
6
6
  flightRecorder;
7
7
  cacheAwareness;
8
- constructor(sessionManager, performanceMetrics,
9
- // Optional read access to the flight recorder. Used by cache-state
10
- // resources (slice 2). Falls back to a stub returning [] when not
11
- // injected so existing call sites continue to work without changes.
12
- flightRecorder = { queryRequests: () => [] },
13
- // Slice 3: optional cache-awareness config. When present, drives the
14
- // TTL policy applied to ttlRemainingMs on session-scoped reads.
15
- // When absent, the default Anthropic 5-min TTL applies (matches the
16
- // 1.x default of `[cache_awareness].anthropic_ttl_seconds = 300`).
17
- cacheAwareness = null) {
8
+ constructor(sessionManager, performanceMetrics, flightRecorder = { queryRequests: () => [] }, cacheAwareness = null) {
18
9
  this.sessionManager = sessionManager;
19
10
  this.performanceMetrics = performanceMetrics;
20
11
  this.flightRecorder = flightRecorder;
21
12
  this.cacheAwareness = cacheAwareness;
22
13
  }
23
- /** Read-only flight-recorder accessor for cache-state resource readers. */
24
14
  getFlightRecorderQuery() {
25
15
  return this.flightRecorder;
26
16
  }
27
- /**
28
- * cache_state://global — aggregates across the entire flight recorder.
29
- * Optionally restrict to a recent window via `lastNHours`. Returns
30
- * tokens/hashes/aggregates ONLY — no prompt text fields. The redaction is
31
- * structural: the response shape (GlobalCacheStats) has no `prompt`,
32
- * `response`, `system`, or `task` field by construction.
33
- */
34
17
  readCacheStateGlobal(opts = {}) {
35
18
  return computeGlobalCacheStats(this.flightRecorder, opts);
36
19
  }
37
- /**
38
- * cache_state://session/{sessionId} — per-session aggregates. Returns
39
- * empty defaults when the session has no rows. Token/hash fields only.
40
- *
41
- * Slice 3: populates `ttlRemainingMs` by applying the configured TTL
42
- * policy. Null for non-claude sessions or when the gateway has no
43
- * cache-awareness config loaded (defaults to 5-min policy).
44
- */
45
20
  readCacheStateSession(sessionId) {
46
21
  const stats = computeSessionCacheStats(this.flightRecorder, sessionId);
47
22
  const ttlSeconds = this.cacheAwareness?.anthropicTtlSeconds ?? 300;
@@ -50,14 +25,9 @@ export class ResourceProvider {
50
25
  });
51
26
  return stats;
52
27
  }
53
- /**
54
- * cache_state://prefix/{hash} — per-stable-prefix-hash aggregates.
55
- * Returns empty defaults for unknown hashes. Token/hash fields only.
56
- */
57
28
  readCacheStateForPrefix(stablePrefixHash) {
58
29
  return computePrefixCacheStats(this.flightRecorder, stablePrefixHash);
59
30
  }
60
- // List all available resources
61
31
  listResources() {
62
32
  return [
63
33
  {
@@ -195,9 +165,7 @@ export class ResourceProvider {
195
165
  },
196
166
  ];
197
167
  }
198
- // Read a specific resource by URI
199
168
  async readResource(uri) {
200
- // Session resources
201
169
  if (uri === "sessions://all") {
202
170
  const sessions = await this.sessionManager.listSessions();
203
171
  return {
@@ -287,7 +255,6 @@ export class ResourceProvider {
287
255
  }, null, 2),
288
256
  };
289
257
  }
290
- // Model capability resources
291
258
  if (uri === "models://claude") {
292
259
  const cliInfo = getAvailableCliInfo();
293
260
  return {
package/dist/retry.d.ts CHANGED
@@ -1,23 +1,9 @@
1
- /**
2
- * A module for adding retry and circuit breaker logic to asynchronous operations.
3
- *
4
- * @module retry
5
- */
6
1
  import type { Logger } from "./logger.js";
7
- /**
8
- * Defines the possible states of the circuit breaker.
9
- */
10
2
  export declare enum CircuitBreakerState {
11
- /** The circuit is closed and allows operations to execute. */
12
3
  CLOSED = "CLOSED",
13
- /** The circuit is open and fails operations immediately. */
14
4
  OPEN = "OPEN",
15
- /** The circuit is half-open and allows a single trial operation. */
16
5
  HALF_OPEN = "HALF_OPEN"
17
6
  }
18
- /**
19
- * Represents the state and configuration of a circuit breaker.
20
- */
21
7
  export interface CircuitBreaker {
22
8
  state: CircuitBreakerState;
23
9
  failures: number;
@@ -26,47 +12,16 @@ export interface CircuitBreaker {
26
12
  readonly failureThreshold: number;
27
13
  onStateChange?: (newState: CircuitBreakerState, error?: Error) => void;
28
14
  }
29
- /**
30
- * Configuration options for the retry logic.
31
- */
32
15
  export interface RetryOptions {
33
- /** The initial delay in milliseconds before the first retry. */
34
16
  initialDelay: number;
35
- /** The maximum delay in milliseconds between retries. */
36
17
  maxDelay: number;
37
- /** The exponential backoff factor. */
38
18
  factor: number;
39
- /**
40
- * A function that determines if an error is transient and should be retried.
41
- * @param error The error to check.
42
- * @returns `true` if the error is transient, otherwise `false`.
43
- */
44
19
  isTransient: (error: any) => boolean;
45
- /**
46
- * A callback function executed on each retry attempt.
47
- * @param error The error that caused the retry.
48
- * @param attempt The current retry attempt number.
49
- * @param delay The delay in milliseconds before the next attempt.
50
- */
51
20
  onRetry: (error: any, attempt: number, delay: number) => void;
52
21
  }
53
- /**
54
- * Creates a new CircuitBreaker instance with default settings.
55
- * @param options Partial options to override defaults.
56
- * @returns A new CircuitBreaker instance.
57
- */
58
22
  export declare function createCircuitBreaker(options?: {
59
23
  resetTimeout?: number;
60
24
  failureThreshold?: number;
61
25
  onStateChange?: (newState: CircuitBreakerState, error?: Error) => void;
62
26
  }): CircuitBreaker;
63
- /**
64
- * Wraps an asynchronous operation with retry and circuit breaker logic.
65
- *
66
- * @template T The return type of the operation.
67
- * @param {() => Promise<T>} operation The asynchronous operation to execute.
68
- * @param {CircuitBreaker} circuitBreaker The circuit breaker instance to use.
69
- * @param {Partial<RetryOptions>} [retryOptions] Options for retry behavior.
70
- * @returns {Promise<T>} A promise that resolves with the result of the operation.
71
- */
72
27
  export declare function withRetry<T>(operation: () => Promise<T>, circuitBreaker: CircuitBreaker, retryOptions?: Partial<RetryOptions>, logger?: Logger): Promise<T>;