Files
jackwener__opencli/src/capabilityRouting.ts
jakevin 383d28fcf7 refactor: normalize strategy into runtime fields at registration time (#941)
Strategy is a 5-value enum (PUBLIC/COOKIE/HEADER/INTERCEPT/UI) that
the execution path was reading at two points — resolvePreNav() and
shouldUseBrowserSession() — to make decisions that are already fully
expressible by the existing `browser` and `navigateBefore` fields.

This commit introduces normalizeCommand() inside registerCommand(),
which expands strategy into concrete runtime fields at registration
time. After normalization, execution code never reads cmd.strategy.

normalizeCommand expansion rules:
  - strategy → browser: PUBLIC defaults to false, others to true.
    Explicit browser value always wins.
  - strategy + domain → navigateBefore:
    · COOKIE/HEADER + domain → 'https://{domain}' (pre-navigate)
    · Non-PUBLIC without domain → true (needs auth context, no URL)
    · PUBLIC → undefined (no auth needed)
    Explicit navigateBefore (false or string) always wins.

This matters because commands enter the registry from 4 sources
(cli(), manifest, generate-verified, tests), and previously only
cli() did strategy derivation. The other 3 constructed CliCommand
directly, leaving strategy as a runtime dependency. Now all sources
converge through registerCommand → normalizeCommand.

Changes:
  - registry.ts: add normalizeCommand(); simplify cli() to delegate
    all derivation to normalizeCommand via registerCommand()
  - execution.ts: resolvePreNav() no longer reads strategy; just
    reads the already-expanded navigateBefore field. Strategy import
    removed.
  - capabilityRouting.ts: shouldUseBrowserSession() checks
    cmd.navigateBefore (truthy = needs browser session) instead of
    cmd.strategy !== PUBLIC. Strategy import removed.
  - discovery.ts: manifest path no longer hardcodes browser default;
    delegates to normalizeCommand.
  - capabilityRouting.test.ts: test now reflects normalized command
    shape (navigateBefore: true for COOKIE without domain).

strategy is preserved as metadata on CliCommand — opencli list,
cascade probe, adapter generation, and documentation continue to
read it. Only the execution path stops consuming it.
2026-04-11 00:37:31 +08:00

33 lines
1.0 KiB
TypeScript

import type { CliCommand } from './registry.js';
/** Pipeline steps that require a live browser session. */
export const BROWSER_ONLY_STEPS = new Set([
'navigate',
'click',
'type',
'wait',
'press',
'snapshot',
'evaluate',
'intercept',
'tap',
]);
function pipelineNeedsBrowserSession(pipeline: Record<string, unknown>[]): boolean {
return pipeline.some((step) => {
if (!step || typeof step !== 'object') return false;
return Object.keys(step).some((op) => BROWSER_ONLY_STEPS.has(op));
});
}
export function shouldUseBrowserSession(cmd: CliCommand): boolean {
if (!cmd.browser) return false;
if (cmd.func) return true;
if (!cmd.pipeline || cmd.pipeline.length === 0) return true;
// normalizeCommand sets navigateBefore to a URL string (needs pre-nav) or
// boolean true (needs authenticated context, no specific URL). Either way
// the pipeline requires a browser session even if no step is browser-only.
if (cmd.navigateBefore) return true;
return pipelineNeedsBrowserSession(cmd.pipeline as Record<string, unknown>[]);
}