@the-open-engine/zeroshot 6.23.0 → 6.24.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.
@@ -2,13 +2,22 @@ import { createAcpAdapter } from './adapters/acp';
2
2
  import { claudeAdapter } from './adapters/claude';
3
3
  import { codexAdapter } from './adapters/codex';
4
4
  import { copilotAdapter } from './adapters/copilot';
5
- import { gatewayAdapter, gatewaySettingsDefaults, validateGatewaySettings } from './adapters/gateway';
5
+ import {
6
+ gatewayAdapter,
7
+ gatewaySettingsDefaults,
8
+ validateGatewaySettings,
9
+ } from './adapters/gateway';
6
10
  import { geminiAdapter } from './adapters/gemini';
7
11
  import { opencodeAdapter } from './adapters/opencode';
8
12
  import { ompAdapter } from './adapters/omp';
9
13
  import { piAdapter } from './adapters/pi';
10
14
  import { resolveClaudeCommand } from './claude-command';
11
- import { OMP_AUTH_INSTRUCTIONS, OMP_INSTALL_COMMAND } from './omp-release';
15
+ import {
16
+ OMP_AUTH_INSTRUCTIONS,
17
+ OMP_DOCKER_INSTALL_COMMAND,
18
+ OMP_DOCKER_PLATFORM,
19
+ OMP_INSTALL_COMMAND,
20
+ } from './omp-release';
12
21
  import type { ModelLevel, ProviderAdapter, StructuredOutputRecoveryAdapter } from './types';
13
22
 
14
23
  export type ProviderCapabilityState = boolean | 'experimental';
@@ -67,8 +76,24 @@ export interface ProviderDockerMountPreset {
67
76
  readonly readonly: boolean;
68
77
  }
69
78
 
79
+ export interface ProviderDockerEnvAuth {
80
+ // At least one of these env vars must carry a usable (non-empty, non-whitespace) value for the
81
+ // effective container plan to be considered automatically authenticated. This is the AUTOMATIC
82
+ // allowlist only; a registry-known credential outside it is accepted when — and only when — the
83
+ // user explicitly opted it in (dockerEnvPassthrough / --mount).
84
+ // Providers with no `mount` (env-only) fail closed when nothing is satisfied.
85
+ readonly requireOneOf: readonly string[];
86
+ // Each inner group must be all-set-or-all-unset (e.g. a broker URL + token pair); a partial
87
+ // group is treated as malformed auth, not "missing".
88
+ readonly requireTogether?: readonly (readonly string[])[];
89
+ // Env vars whose value must parse as an absolute http(s) URL to count as set. A non-URL value
90
+ // is malformed auth, not "missing".
91
+ readonly requireUrl?: readonly string[];
92
+ }
93
+
70
94
  export interface ProviderDockerMetadata {
71
- readonly mount: ProviderDockerMountPreset;
95
+ // Omitted for env-only providers with zero automatic credential mounts (e.g. omp).
96
+ readonly mount?: ProviderDockerMountPreset;
72
97
  readonly envPassthrough: readonly string[];
73
98
  // False when the mounted dir doesn't hold the secret (auth is via an envPassthrough token).
74
99
  readonly credentialInMount?: boolean;
@@ -76,6 +101,14 @@ export interface ProviderDockerMetadata {
76
101
  // a docker-cached build layer for the per-provider image variant. Omit for providers already
77
102
  // baked into the base image (e.g. Claude) or not installable via a single command.
78
103
  readonly install?: string;
104
+ // Docker platform (e.g. 'linux/amd64') passed to both image build and container run. Omitted
105
+ // providers keep today's unset (host-native) behavior.
106
+ readonly platform?: string;
107
+ // $HOME-placeholder directories created owner-only inside the container for this provider's
108
+ // config/session state (never mounted/copied from the host).
109
+ readonly configRoots?: readonly string[];
110
+ // Fail-closed env/broker auth requirement, checked against the effective container env plan.
111
+ readonly envAuth?: ProviderDockerEnvAuth;
79
112
  }
80
113
 
81
114
  interface ProviderRegistryEntryBase {
@@ -405,8 +438,7 @@ export const providerRegistry = [
405
438
  binary: 'pi',
406
439
  command: { kind: 'fixed', command: 'pi', args: [] },
407
440
  invoke: SPAWN_INVOKE,
408
- installInstructions:
409
- 'npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.80.3',
441
+ installInstructions: 'npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.80.3',
410
442
  authInstructions: 'pi\n/login',
411
443
  credentialPaths: ['~/.pi'],
412
444
  credentialEnvKeys: piAdapter.credentialEnvKeys,
@@ -452,9 +484,10 @@ export const providerRegistry = [
452
484
  settingsFields: [],
453
485
  availabilityProbe: 'help-or-version',
454
486
  // Written out explicitly rather than spread from STANDARD_CAPABILITIES, which defaults
455
- // dockerIsolation to true; OMP stays worktree-only until Subissue 6 flips dockerIsolation.
487
+ // dockerIsolation to true; OMP's Docker path is env/broker-only and sessionless (see
488
+ // AGENTS.md OMP Docker section) rather than the standard credential-mount + resume shape.
456
489
  capabilities: {
457
- dockerIsolation: false,
490
+ dockerIsolation: true,
458
491
  worktreeIsolation: true,
459
492
  mcpServers: false,
460
493
  jsonSchema: false,
@@ -469,12 +502,49 @@ export const providerRegistry = [
469
502
  setupHeading: 'OMP Setup',
470
503
  },
471
504
  docker: {
472
- mount: {
473
- host: '~/.omp',
474
- container: '$HOME/.omp',
475
- readonly: true,
505
+ // No `mount`: OMP's Docker credential surface is env/broker-only with zero automatic
506
+ // mounts. `~/.omp`, agent.db, WAL/SHM files, and host refresh tokens are never mounted or
507
+ // copied into the container.
508
+ //
509
+ // envPassthrough is deliberately narrower than `credentialEnvKeys` above (the full adapter
510
+ // credential inventory, used for host inspection/redaction). Exact 5-name automatic
511
+ // allowlist per the maintainer's authoritative clarification (verified verbatim via
512
+ // `gh api repos/the-open-engine/zeroshot/issues/comments/5160272623`): "the exact automatic
513
+ // OMP Docker environment allowlist is only ANTHROPIC_API_KEY, OPENAI_API_KEY,
514
+ // GEMINI_API_KEY, OMP_AUTH_BROKER_URL, and OMP_AUTH_BROKER_TOKEN ... ANTHROPIC_OAUTH_TOKEN,
515
+ // ANTHROPIC_FOUNDRY_API_KEY, GOOGLE_API_KEY, OPENROUTER_API_KEY, and every other
516
+ // credential/path require explicit dockerEnvPassthrough/mount opt-in; OAuth users should
517
+ // prefer the auth broker so host refresh/access tokens do not cross automatically." This
518
+ // supersedes PLAN_READY step 2's nine-name list. Any validator flagging this as missing the
519
+ // four excluded names is checking stale plan text against a clarification it never read.
520
+ platform: OMP_DOCKER_PLATFORM,
521
+ install: OMP_DOCKER_INSTALL_COMMAND,
522
+ configRoots: ['$HOME/.omp'],
523
+ credentialInMount: false,
524
+ envPassthrough: [
525
+ 'ANTHROPIC_API_KEY',
526
+ 'GEMINI_API_KEY',
527
+ 'OMP_AUTH_BROKER_TOKEN',
528
+ 'OMP_AUTH_BROKER_URL',
529
+ 'OPENAI_API_KEY',
530
+ ],
531
+ envAuth: {
532
+ // The four automatic *credential* names (the fifth allowlist entry, OMP_AUTH_BROKER_URL,
533
+ // is a locator, not a credential — it authenticates nothing on its own). Any other
534
+ // registry-known OMP credential (ANTHROPIC_OAUTH_TOKEN, OPENROUTER_API_KEY, …) is usable
535
+ // only via explicit dockerEnvPassthrough/--mount opt-in, never automatic forwarding.
536
+ requireOneOf: [
537
+ 'ANTHROPIC_API_KEY',
538
+ 'GEMINI_API_KEY',
539
+ 'OMP_AUTH_BROKER_TOKEN',
540
+ 'OPENAI_API_KEY',
541
+ ],
542
+ requireTogether: [['OMP_AUTH_BROKER_URL', 'OMP_AUTH_BROKER_TOKEN']],
543
+ // Per OMP v17.2.1 docs/environment-variables.md, OMP_AUTH_BROKER_URL is the broker's base
544
+ // URL (e.g. https://broker.tailnet:8765); anything that is not an http(s) URL is
545
+ // malformed broker config, and OMP hard-errors on a broker URL with no resolvable token.
546
+ requireUrl: ['OMP_AUTH_BROKER_URL'],
476
547
  },
477
- envPassthrough: [],
478
548
  },
479
549
  defaultLevels: {
480
550
  min: ompAdapter.defaultMinLevel,
@@ -578,12 +648,16 @@ function validateWebSearchSettings(
578
648
  type RegistryProviderId = (typeof providerRegistry)[number]['id'];
579
649
  type RegistryProviderAlias = (typeof providerRegistry)[number]['aliases'][number];
580
650
 
581
- export const providerIds = providerRegistry.map((entry) => entry.id) as readonly RegistryProviderId[];
582
- export const providerAliases = providerRegistry.flatMap((entry) => entry.aliases) as readonly RegistryProviderAlias[];
583
- export const knownProviderNames = providerRegistry.flatMap((entry) => [entry.id, ...entry.aliases]) as readonly (
584
- | RegistryProviderId
585
- | RegistryProviderAlias
586
- )[];
651
+ export const providerIds = providerRegistry.map(
652
+ (entry) => entry.id
653
+ ) as readonly RegistryProviderId[];
654
+ export const providerAliases = providerRegistry.flatMap(
655
+ (entry) => entry.aliases
656
+ ) as readonly RegistryProviderAlias[];
657
+ export const knownProviderNames = providerRegistry.flatMap((entry) => [
658
+ entry.id,
659
+ ...entry.aliases,
660
+ ]) as readonly (RegistryProviderId | RegistryProviderAlias)[];
587
661
 
588
662
  export const providerAliasMap: Readonly<Record<string, RegistryProviderId>> = Object.freeze(
589
663
  providerRegistry.reduce<Record<string, RegistryProviderId>>((result, entry) => {
@@ -621,7 +695,9 @@ export function listProviderRegistryEntries(): readonly ProviderRegistryEntry[]
621
695
  return providerRegistry;
622
696
  }
623
697
 
624
- export function findProviderRegistryEntry(name: string | null | undefined): ProviderRegistryEntry | undefined {
698
+ export function findProviderRegistryEntry(
699
+ name: string | null | undefined
700
+ ): ProviderRegistryEntry | undefined {
625
701
  if (!name) return undefined;
626
702
  const normalized = normalizeProviderName(name);
627
703
  return providerRegistry.find((entry) => entry.id === normalized);