"use strict";
/**
 * Claude subcommand detection.
 *
 * Claude Code's CLI accepts both an interactive session form (`claude [prompt]`,
 * possibly with `--print`) and explicit subcommands (`claude agents`,
 * `claude doctor`, `claude mcp`, ...). Subcommand parsers reject most top-level
 * session flags — e.g. `claude agents --append-system-prompt foo` exits with
 * `error: unknown option '--append-system-prompt'`.
 *
 * CCS injects WebSearch / image-analysis / browser steering args
 * (`--append-system-prompt`, `--disallowedTools`) for interactive sessions.
 * Those flags must be skipped when the user is actually invoking a Claude
 * subcommand, otherwise the subcommand fails or falls back to non-interactive
 * mode (e.g. `claude agents` printing the list instead of opening the agent
 * view — see issue #1218).
 *
 * Detection walks args left-to-right, skipping known value-taking top-level
 * flags, and reports whether the first positional token matches a known
 * Claude subcommand.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.stripSubcommandBlockingEnv = exports.stripClaudeCodeFeatureBlockingEnv = exports.stripClaudeSubcommandSessionArgs = exports.getClaudeSubcommandName = exports.isClaudeSubcommandInvocation = void 0;
/**
 * Known Claude CLI subcommands. Sourced from `claude --help` (v2.1.139).
 * Keep in sync with upstream — additions are safe (over-skipping injection
 * for an unknown command is acceptable; under-skipping is the bug).
 */
const CLAUDE_SUBCOMMANDS = new Set([
    'agents',
    'auth',
    'auto-mode',
    'doctor',
    'install',
    'mcp',
    'plugin',
    'plugins',
    'project',
    'remote-control',
    'setup-token',
    'ultrareview',
    'update',
    'upgrade',
]);
/**
 * Top-level Claude flags that consume the next argv token as their value.
 * Used so the detector doesn't mistake a flag value (e.g. `--name auth`) for
 * a subcommand. Boolean flags are intentionally absent.
 *
 * Variadic flags (`--add-dir`, `--mcp-config`, etc.) only consume their
 * immediate next token here; Commander.js' real variadic parsing isn't worth
 * replicating since the goal is just to skip past one obvious value safely.
 */
const VALUE_TAKING_FLAGS = new Set([
    '--add-dir',
    '--agent',
    '--agents',
    '--allowedTools',
    '--allowed-tools',
    '--append-system-prompt',
    '--betas',
    '--channels',
    '--debug-file',
    '--disallowedTools',
    '--disallowed-tools',
    '--effort',
    '--fallback-model',
    '--file',
    '--input-format',
    '--json-schema',
    '--max-budget-usd',
    '--mcp-config',
    '--model',
    '--name',
    '-n',
    '--output-format',
    '--permission-mode',
    '--plugin-dir',
    '--plugin-url',
    '--remote-control-session-name-prefix',
    '--session-id',
    '--setting-sources',
    '--settings',
    '--system-prompt',
    '--teammate-mode',
    '--tools',
]);
const SUBCOMMAND_SESSION_ONLY_FLAGS = new Set([
    '--allow-dangerously-skip-permissions',
    '--dangerously-skip-permissions',
]);
const SUBCOMMAND_SESSION_ONLY_VALUE_FLAGS = new Set([
    '--permission-mode',
    '--teammate-mode',
]);
/**
 * Flags that look session-only but are actually accepted by specific Claude
 * subcommands. Keep these intact instead of stripping. Sourced from
 * `claude <sub> --help` (v2.1.139); add new entries when upstream extends a
 * subcommand parser.
 *
 * - `agents` accepts `--permission-mode`, `--dangerously-skip-permissions`,
 *   and `--allow-dangerously-skip-permissions` as defaults for dispatched
 *   sessions (see `claude agents --help`). Stripping these breaks
 *   `ccs <profile> agents --permission-mode bypassPermissions`.
 */
const SUBCOMMAND_ALLOWED_SESSION_FLAGS = {
    agents: new Set([
        '--allow-dangerously-skip-permissions',
        '--dangerously-skip-permissions',
        '--permission-mode',
    ]),
};
/**
 * Returns true when `args` look like a Claude subcommand invocation.
 *
 * Heuristic:
 *   1. Walk args until the `--` terminator or end.
 *   2. If `--print` is present before the first positional token, treat as
 *      prompt/headless session mode (never a subcommand launch).
 *   3. Skip known value-taking flags together with their next token.
 *   4. Skip unknown `--flag=value` forms and bare `--flag` / `-x` tokens.
 *   5. The first remaining positional token is the candidate.
 *   5. Match against CLAUDE_SUBCOMMANDS.
 *
 * Anything after the candidate is irrelevant — once a subcommand is in play,
 * the rest of the line belongs to that subcommand.
 */
function isClaudeSubcommandInvocation(args) {
    return getClaudeSubcommandName(args) !== null;
}
exports.isClaudeSubcommandInvocation = isClaudeSubcommandInvocation;
/**
 * Returns the Claude subcommand name when `args` look like a subcommand
 * invocation, otherwise null. Uses the same scan as
 * `isClaudeSubcommandInvocation` so callers can branch on the specific
 * subcommand (e.g. `agents` allows flags that other subcommands reject).
 */
function getClaudeSubcommandName(args) {
    for (let i = 0; i < args.length; i += 1) {
        const arg = args[i];
        if (arg === '--')
            return null;
        if (arg === '--print' || arg === '-p')
            return null;
        if (arg.startsWith('-')) {
            if (VALUE_TAKING_FLAGS.has(arg)) {
                // Skip the next token as the flag's value (when present and not another flag).
                const next = args[i + 1];
                if (next !== undefined && !next.startsWith('-')) {
                    i += 1;
                }
            }
            // `--flag=value`, bare boolean flags, and unknown short/long flags fall through.
            continue;
        }
        return CLAUDE_SUBCOMMANDS.has(arg) ? arg : null;
    }
    return null;
}
exports.getClaudeSubcommandName = getClaudeSubcommandName;
function stripClaudeSubcommandSessionArgs(args) {
    const subcommand = getClaudeSubcommandName(args);
    if (subcommand === null) {
        return [...args];
    }
    const allowed = SUBCOMMAND_ALLOWED_SESSION_FLAGS[subcommand];
    const isAllowed = (flag) => allowed?.has(flag) === true;
    const out = [];
    for (let i = 0; i < args.length; i += 1) {
        const arg = args[i];
        if (SUBCOMMAND_SESSION_ONLY_FLAGS.has(arg) && !isAllowed(arg)) {
            continue;
        }
        if (arg.startsWith('--permission-mode=')) {
            if (isAllowed('--permission-mode')) {
                out.push(arg);
                continue;
            }
            continue;
        }
        if (arg.startsWith('--teammate-mode=')) {
            if (isAllowed('--teammate-mode')) {
                out.push(arg);
                continue;
            }
            continue;
        }
        if (SUBCOMMAND_SESSION_ONLY_VALUE_FLAGS.has(arg) && !isAllowed(arg)) {
            const next = args[i + 1];
            if (next !== undefined && !next.startsWith('-')) {
                i += 1;
            }
            continue;
        }
        out.push(arg);
    }
    return out;
}
exports.stripClaudeSubcommandSessionArgs = stripClaudeSubcommandSessionArgs;
/**
 * Claude Code treats DISABLE_TELEMETRY as a feature kill switch for agent-view
 * and background-session surfaces, not only as telemetry preference.
 */
const CLAUDE_CODE_FEATURE_BLOCKING_ENV_KEYS = ['DISABLE_TELEMETRY'];
function stripClaudeCodeFeatureBlockingEnv(env) {
    const out = {};
    for (const [key, value] of Object.entries(env)) {
        if (CLAUDE_CODE_FEATURE_BLOCKING_ENV_KEYS.includes(key)) {
            continue;
        }
        out[key] = value;
    }
    return out;
}
exports.stripClaudeCodeFeatureBlockingEnv = stripClaudeCodeFeatureBlockingEnv;
/**
 * Return a shallow copy of `env` with subcommand-blocking telemetry vars
 * removed. Caller is responsible for only invoking this when args are a
 * Claude subcommand invocation.
 */
function stripSubcommandBlockingEnv(env) {
    return stripClaudeCodeFeatureBlockingEnv(env);
}
exports.stripSubcommandBlockingEnv = stripSubcommandBlockingEnv;
//# sourceMappingURL=claude-subcommand-detector.js.map