@integrity-labs/agt-cli 0.27.76 → 0.27.77
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.
package/dist/bin/agt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/agt.ts","../../src/commands/whoami.ts","../../src/commands/team.ts","../../src/lib/auth-guard.ts","../../src/commands/init.ts","../../src/commands/lint.ts","../../src/commands/channels.ts","../../src/commands/channel-slack.ts","../../src/commands/channel-beam.ts","../../src/commands/deploy.ts","../../src/commands/provision.ts","../../src/commands/impersonate.ts","../../src/lib/impersonate-flag.ts","../../src/lib/impersonate-state.ts","../../src/lib/impersonate-fs-ops.ts","../../src/lib/impersonate-hook.ts","../../src/lib/impersonate-statusline.ts","../../src/lib/impersonate-introduce.ts","../../src/lib/impersonate-mcp-rewrite.ts","../../src/commands/drift.ts","../../../../packages/core/src/drift/live-state-reader.ts","../../src/commands/host.ts","../../src/commands/host-pair.ts","../../src/commands/manager-watch.tsx","../../src/commands/agent.ts","../../src/commands/kanban-recurring.ts","../../src/commands/setup.ts","../../src/commands/kanban.ts","../../../../packages/core/src/acp/agent-registry.ts","../../../../packages/core/src/acp/client.ts","../../src/commands/acpx.ts","../../src/commands/update.ts","../../src/commands/audit-subagents.ts","../../src/lib/subagent-mcp-audit.ts","../../src/lib/mcp-render-allowlist-audit.ts","../../src/commands/audit-mcp-render.ts","../../src/commands/audit-secrets.ts","../../src/lib/secret-leak-audit.ts","../../src/commands/integration.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// Register framework adapters (side-effect imports — must be before any provisioning code)\nimport '@augmented/core/provisioning/frameworks/openclaw/index.js';\nimport '@augmented/core/provisioning/frameworks/nemoclaw/index.js';\nimport '@augmented/core/provisioning/frameworks/claudecode/index.js';\nimport '@augmented/core/provisioning/frameworks/managed-agents/index.js';\n\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { Command } from 'commander';\nimport { setJsonMode } from '../lib/globals.js';\nimport { whoamiCommand } from '../commands/whoami.js';\nimport {\n teamListCommand,\n teamCreateCommand,\n teamSwitchCommand,\n} from '../commands/team.js';\nimport { initCommand } from '../commands/init.js';\nimport { lintCommand } from '../commands/lint.js';\nimport { channelsListCommand, channelsCheckCommand } from '../commands/channels.js';\nimport { channelSlackSetupCommand, channelSlackStatusCommand, channelSlackRemoveCommand } from '../commands/channel-slack.js';\nimport { channelBeamSetupCommand, channelBeamStatusCommand, channelBeamRemoveCommand } from '../commands/channel-beam.js';\nimport { deployCommand } from '../commands/deploy.js';\nimport { provisionCommand } from '../commands/provision.js';\nimport {\n impersonateConnectCommand,\n impersonateCurrentCommand,\n impersonateExitCommand,\n impersonateIntroduceCommand,\n autoExitExpiredImpersonation,\n} from '../commands/impersonate.js';\nimport { driftCheckCommand, driftWatchCommand } from '../commands/drift.js';\nimport {\n hostListCommand,\n hostAssignCommand,\n hostUnassignCommand,\n hostAgentsCommand,\n hostRotateKeyCommand,\n hostDecommissionCommand,\n hostMaintenanceWindowCommand,\n} from '../commands/host.js';\nimport { hostPairCommand } from '../commands/host-pair.js';\nimport {\n managerStartCommand,\n managerStopCommand,\n managerStatusCommand,\n managerInstallCommand,\n managerUninstallCommand,\n managerInstallSystemUnitCommand,\n managerUninstallSystemUnitCommand,\n} from '../commands/manager.js';\nimport { managerWatchCommand } from '../commands/manager-watch.js';\nimport { agentShowCommand } from '../commands/agent.js';\nimport {\n kanbanRecurringAddCommand,\n kanbanRecurringListCommand,\n kanbanRecurringDisableCommand,\n} from '../commands/kanban-recurring.js';\nimport { setupCommand } from '../commands/setup.js';\nimport {\n kanbanListCommand,\n kanbanAddCommand,\n kanbanMoveCommand,\n kanbanUpdateCommand,\n kanbanDoneCommand,\n} from '../commands/kanban.js';\nimport {\n acpxSpawnCommand,\n acpxPromptCommand,\n acpxExecCommand,\n acpxListSessionsCommand,\n acpxCancelCommand,\n acpxCloseCommand,\n} from '../commands/acpx.js';\nimport { updateCommand, checkForUpdateOnStartup } from '../commands/update.js';\nimport { auditSubagentsCommand } from '../commands/audit-subagents.js';\nimport { auditMcpRenderCommand } from '../commands/audit-mcp-render.js';\nimport { auditSecretsCommand } from '../commands/audit-secrets.js';\nimport {\n integrationListCommand,\n integrationShowCommand,\n integrationInstallCommand,\n integrationUninstallCommand,\n integrationRequestsCommand,\n integrationApproveCommand,\n integrationDenyCommand,\n integrationEnrolCommand,\n} from '../commands/integration.js';\n\ndeclare const __CLI_VERSION__: string;\n\nconst cliVersion = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : 'dev';\n\nconst program = new Command();\n\nprogram\n .name('agt')\n .description('Augmented CLI — agent provisioning and management')\n .version(cliVersion)\n .option('--json', 'Emit machine-readable JSON output (suppress spinners and colors)')\n .option('--skip-update-check', 'Skip the automatic update check on startup');\n\n// ── Global pre-action hook ──────────────────────────────────────────────────\n\nprogram.hook('preAction', async (thisCommand, actionCommand) => {\n const root = thisCommand.optsWithGlobals();\n if (root.json) {\n setJsonMode(true);\n }\n\n // ENG-5911: on any command, lazily auto-exit an expired impersonation\n // session (restore the operator's files + clear state) so a dead session\n // never lingers needing a manual `agt impersonate exit`. Skip the two\n // commands where it would be wrong or redundant:\n // - `impersonate introduce`: the SessionStart hook — must never restore\n // files / post /stop mid-session-boot (it already self-guards on expiry).\n // - `impersonate exit`: redundant; it runs the cleanup itself.\n const segs: string[] = [];\n for (let c = actionCommand; c && c.parent; c = c.parent) segs.unshift(c.name());\n const cmdPath = segs.join(' ');\n if (cmdPath !== 'impersonate introduce' && cmdPath !== 'impersonate exit') {\n await autoExitExpiredImpersonation();\n }\n});\n\n// ── Auth commands ──────────────────────────────────────────────────────────\n\nprogram\n .command('whoami')\n .description('Show the authenticated host, team, and user from AGT_API_KEY')\n .action(whoamiCommand);\n\nprogram\n .command('setup <token>')\n .description('One-command host setup: exchange provisioning token, configure env vars, verify, and start manager')\n .option(\n '--api-host <url>',\n // ENG-5831: required when AGT_HOST is not set in the shell — the setup\n // command no longer silently defaults to prod. Mirrors `agt impersonate\n // connect --api-host` (ENG-5773).\n 'API host to exchange the provisioning token against. Takes precedence over AGT_HOST. Required when AGT_HOST is unset (e.g. https://test.api.staging.augmented.team for the test stage; https://api.augmented.team for prod).',\n )\n .action(setupCommand);\n\n// ── Team commands ─────────────────────────────────────────────────────\n\nconst team = program\n .command('team')\n .description('Manage teams');\n\nteam\n .command('list')\n .description('List teams you belong to')\n .action(teamListCommand);\n\nteam\n .command('create <name>')\n .description('Create a new team and set it as active')\n .action(teamCreateCommand);\n\nteam\n .command('switch <slug>')\n .description('Switch the active team')\n .action(teamSwitchCommand);\n\n// ── Impersonation commands ────────────────────────────────────────────────\n// ENG-5688 (redesigned): operator-impersonates-agent v0. The webapp\n// (ENG-5702) mints a redeem token; the operator pastes\n// `agt impersonate connect <token>` to enter, `exit` to leave.\n// All gated behind AGT_IMPERSONATE_ENABLED until the surrounding pieces\n// (ENG-5689 channel-MCP refusal, ENG-5702 webapp button) land and the\n// end-to-end smoke test runs against prod.\n\nconst impersonate = program\n .command('impersonate')\n .description(\n 'Operate as a managed agent locally (experimental, gated by AGT_IMPERSONATE_ENABLED)',\n );\n\nimpersonate\n .command('connect <token>')\n .description(\n \"Redeem a XXXX-XXXX token from the webapp, render the agent's CLAUDE.md + .mcp.json, swap them into the current project, and launch Claude Code (use --no-launch to skip the launch)\",\n )\n .option(\n '--no-launch',\n \"Skip launching Claude Code after the swap (operator manages their own session)\",\n )\n .option(\n '--workdir',\n \"Swap into an auto-provisioned dedicated directory (~/.augmented-impersonate/<agent>/workdir) instead of the current directory — required when the current directory is inside a git repo\",\n )\n .option(\n '--api-host <url>',\n \"Override the API host used to redeem the token. Defaults to https://api.augmented.team — AGT_HOST is intentionally ignored so a dev/Tailscale AGT_HOST doesn't accidentally 502 against a token minted on prod.\",\n )\n .action(\n (token: string, opts: { launch?: boolean; workdir?: boolean; apiHost?: string }) =>\n // Commander negates --no-FLAG into opts.flag, so --no-launch arrives\n // as opts.launch === false. Translate to the command's noLaunch\n // option, defaulting to launching when the flag isn't passed.\n impersonateConnectCommand(token, {\n noLaunch: opts.launch === false,\n workdir: opts.workdir === true,\n apiHost: opts.apiHost,\n }),\n );\n\nimpersonate\n .command('current')\n .description('Print the active impersonation for this directory (or \"none\")')\n .option('--all', 'List every active impersonation session on this machine')\n .action((opts: { all?: boolean }) =>\n impersonateCurrentCommand({ all: opts.all === true }),\n );\n\nimpersonate\n .command('exit')\n .description(\"End this directory's impersonation, restore project files, and notify the server\")\n .option('--all', 'Exit every active impersonation session on this machine')\n .action((opts: { all?: boolean }) =>\n impersonateExitCommand({ all: opts.all === true }),\n );\n\n// Hidden: invoked by the SessionStart hook `connect` registers (ENG-5750),\n// not meant to be run by operators directly. Prints the impersonated\n// agent's introduction; silent no-op when no active impersonation.\nimpersonate\n .command('introduce', { hidden: true })\n .description(\"Print the impersonated agent's self-introduction (SessionStart hook target)\")\n .action(impersonateIntroduceCommand);\n\n// ── Agent commands ─────────────────────────────────────────────────────────\n\nprogram\n .command('init')\n .description('Create a new agent (interactive wizard, or non-interactive with --name)')\n .option('--name <display-name>', 'Agent display name (triggers non-interactive mode)')\n .option('--code-name <code-name>', 'Agent code name (kebab-case, derived from --name if omitted)')\n .option('--description <text>', 'Short agent description')\n .option('--env <environment>', 'Environment: dev | stage | prod', 'dev')\n .option('--risk-tier <tier>', 'Risk tier: Low | Medium | High', 'Low')\n .option('--budget-type <type>', 'Budget type: tokens | dollars | both', 'tokens')\n .option('--budget-tokens <number>', 'Token budget limit', '10000')\n .option('--budget-dollars <number>', 'Dollar budget limit', '10')\n .option('--budget-window <window>', 'Budget window: daily | weekly | monthly', 'daily')\n .option('--budget-enforcement <mode>', 'Budget enforcement: block | throttle | alert | degrade', 'block')\n .option('--channels <list>', 'Comma-separated channel IDs')\n .option('--logging <mode>', 'Logging mode: redacted | hash-only | full-local', 'redacted')\n .action(initCommand);\n\nprogram\n .command('lint')\n .argument('[path]', 'Path to agent directory (default: all agents in .augmented/)')\n .description('Lint CHARTER.md and TOOLS.md files')\n .action(lintCommand);\n\n// ── Channel commands ───────────────────────────────────────────────────────\n\nconst channels = program\n .command('channels')\n .description('Manage and inspect channel configuration');\n\nchannels\n .command('list')\n .description('Print the full channel registry with security metadata')\n .action(channelsListCommand);\n\nchannels\n .command('check <agent>')\n .description('Resolve the effective channel list for an agent')\n .action(channelsCheckCommand);\n\nconst slack = channels\n .command('slack')\n .description('Manage Slack channel configuration');\n\nslack\n .command('setup <agent-code-name>')\n .description('Configure Slack bot scopes, generate manifest, and store credentials')\n .option('--preset <preset>', 'Scope preset: minimal | standard | full')\n .option('--scopes <scopes>', 'Comma-separated list of Slack bot scopes')\n .option('--skip-create', 'Skip Slack CLI app creation step')\n .option('--bot-token <token>', 'Slack bot token (xoxb-…)')\n .option('--signing-secret <secret>', 'Slack signing secret')\n .option('--config-token <token>', 'Slack app configuration token (xoxe-…) for API-based app creation')\n .action(channelSlackSetupCommand);\n\nslack\n .command('status <agent-code-name>')\n .description('Show current Slack configuration for an agent')\n .action(channelSlackStatusCommand);\n\nslack\n .command('remove <agent-code-name>')\n .description('Remove Slack bot configuration for an agent')\n .action(channelSlackRemoveCommand);\n\nconst beam = channels\n .command('beam')\n .description('Manage Beam Protocol channel configuration');\n\nbeam\n .command('setup <agent-code-name>')\n .description('Generate Beam identity, register in directory, and configure channel')\n .option('--directory-url <url>', 'Beam directory URL (default: hosted)')\n .option('--skip-register', 'Skip directory registration')\n .option('--auto-publish', 'Auto-publish capabilities from TOOLS.md', true)\n .action(channelBeamSetupCommand);\n\nbeam\n .command('status <agent-code-name>')\n .description('Show Beam configuration and directory status')\n .action(channelBeamStatusCommand);\n\nbeam\n .command('remove <agent-code-name>')\n .description('Remove Beam identity for an agent')\n .action(channelBeamRemoveCommand);\n\n// ── Provision commands ─────────────────────────────────────────────────────\n\nprogram\n .command('provision <code-name>')\n .description('Provision an agent: build OpenClaw config, generate files, store snapshot')\n .option('--target <target>', 'Deployment target', 'local_docker')\n .option('--output <dir>', 'Output directory for generated files')\n .option('--dry-run', 'Print what would be generated without writing files')\n .action(provisionCommand);\n\n// ── Deploy commands ────────────────────────────────────────────────────────\n\nprogram\n .command('deploy')\n .description('Generate deployment config from a template')\n .option('--template <id>', 'Template ID (triggers non-interactive mode)')\n .option('--port <number>', 'Base port for gateway', '9000')\n .action(deployCommand);\n\n// ── Drift commands ────────────────────────────────────────────────────────\n\nconst drift = program\n .command('drift')\n .description('Detect configuration drift from provisioned state');\n\ndrift\n .command('check <code-name>')\n .description('Compare live state against provisioned snapshot')\n .option('--json', 'Output as JSON')\n .option('--audit', 'Run openclaw security audit')\n .option('--config <path>', 'Path to openclaw.json')\n .action(driftCheckCommand);\n\ndrift\n .command('watch <code-name>')\n .description('Continuously monitor for drift')\n .option('--interval <seconds>', 'Check interval in seconds', '60')\n .option('--webhook <url>', 'POST webhook URL on new findings')\n .option('--json', 'Output as JSON')\n .option('--config <path>', 'Path to openclaw.json')\n .action(driftWatchCommand);\n\n// ── Host commands ─────────────────────────────────────────────────────────\n\nconst host = program\n .command('host')\n .description('Manage hosts (OpenClaw servers/gateways) and their API keys');\n\nhost\n .command('list')\n .description('List hosts in the active team')\n .action(hostListCommand);\n\nhost\n .command('assign <host-name> <agent-code-names...>')\n .description('Assign agents to a host')\n .option('--force', 'Reassign agents already assigned to another host')\n .action(hostAssignCommand);\n\nhost\n .command('unassign <host-name> <agent-code-names...>')\n .description('Unassign agents from a host')\n .action(hostUnassignCommand);\n\nhost\n .command('agents [host-name]')\n .description('List agents assigned to a host (omit name to auto-resolve from AGT_API_KEY)')\n .action(hostAgentsCommand);\n\nhost\n .command('rotate-key <host-name>')\n .description('Rotate the API key for a host (revokes the old key)')\n .action(hostRotateKeyCommand);\n\nhost\n .command('decommission <host-name>')\n .description('Decommission a host (revokes key, marks inactive)')\n .action(hostDecommissionCommand);\n\nhost\n .command('maintenance-window <host-name>')\n .description('View or set the host maintenance window for restart-causing updates')\n .option('--start <HH:MM>', 'Window start, 24h local time (e.g. 01:00)')\n .option('--end <HH:MM>', 'Window end, 24h local time (e.g. 02:00)')\n .option('--tz <IANA>', 'Window timezone (e.g. Australia/Sydney)')\n .option('--clear', 'Clear the override and follow the default 01:00–02:00')\n .action(hostMaintenanceWindowCommand);\n\nhost\n .command('pair <host-name>')\n .description('Start an SSM port-forward + shell to re-authenticate Claude Code on an EC2 host')\n .option('--port <port>', 'Local port to forward for the OAuth callback', '54545')\n // Commander produces `opts.shell` (boolean, default true) for `--no-shell`.\n // Adapt to the hostPairCommand signature which expects `opts.noShell`.\n .option('--no-shell', 'Start the tunnel only; do not open an interactive shell')\n .action((hostName: string, opts: { port?: string; shell?: boolean }) =>\n hostPairCommand(hostName, {\n port: opts.port,\n noShell: opts.shell === false,\n })\n );\n\n// ── Manager commands ──────────────────────────────────────────────────────\n\nconst manager = program\n .command('manager')\n .description('Host config sync daemon — keeps local agent files in sync with API');\n\nmanager\n .command('start')\n .description('Start the manager daemon (polls API for config changes and detects local drift)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .option('--supervise', 'Wrap the manager in a respawn-on-clean-exit loop so auto-upgrades can restart it transparently (ENG-4488)', false)\n .action(managerStartCommand);\n\nmanager\n .command('stop')\n .description('Stop the running manager daemon')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerStopCommand);\n\nmanager\n .command('status')\n .description('Show the current manager daemon status and discovered agents')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerStatusCommand);\n\nmanager\n .command('watch')\n .description('Live TUI dashboard — per-agent boxes, drill-in, log tail. Read-only (ENG-4555).')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .option('--no-tui', 'Skip the TUI and stream the manager log to stdout instead (CI / scripts)')\n .action(managerWatchCommand);\n\nmanager\n .command('install')\n .description('Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerInstallCommand);\n\nmanager\n .command('uninstall')\n .description('Remove the OS-level supervisor (launchctl unload + delete plist on macOS). Idempotent.')\n .action(managerUninstallCommand);\n\nmanager\n .command('install-system-unit')\n .description('Install a system-level systemd unit (Linux, root) so the manager auto-starts on every boot. For headless EC2 hosts — survives reboot without `loginctl enable-linger`. (ENG-4706)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files (defaults to /root/.augmented or /home/<user>/.augmented)')\n .option('--user <name>', 'Unix user the manager runs as', 'root')\n .action(managerInstallSystemUnitCommand);\n\nmanager\n .command('uninstall-system-unit')\n .description('Remove the system-level systemd unit (Linux, root). Idempotent. (ENG-4706)')\n .action(managerUninstallSystemUnitCommand);\n\n// ── Agent inspect commands ────────────────────────────────────────────────\n\nconst agent = program\n .command('agent')\n .description('Inspect and manage agents');\n\nagent\n .command('show <code-name>')\n .description(\"Display an agent's provisioned OpenClaw configuration\")\n .option('--config-dir <dir>', 'Config directory', join(homedir(), '.augmented'))\n .option('--all-channels', 'Show all channels (including disabled)')\n .action(agentShowCommand);\n\n// ── Kanban commands ──────────────────────────────────────────────────────\n\nconst kanban = program\n .command('kanban')\n .description('Manage agent kanban boards');\n\nkanban\n .command('list')\n .description('List kanban board items for an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanListCommand);\n\nkanban\n .command('add <title>')\n .description('Add a new item to an agent kanban board')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--priority <1|2|3>', 'Priority: 1=high, 2=medium, 3=low', '2')\n .option('--status <status>', 'Initial status: backlog | todo | in_progress', 'todo')\n .option('--description <text>', 'Item description')\n .option('--estimate <minutes>', 'Estimated time in minutes')\n .option('--deliverable <text>', 'Expected output/deliverable')\n .action(kanbanAddCommand);\n\nkanban\n .command('move <title-or-id> <status>')\n .description('Move a kanban item to a different status')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--notes <text>', 'Progress notes')\n .action(kanbanMoveCommand);\n\nkanban\n .command('update <title-or-id>')\n .description('Update notes or result on a kanban item')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--notes <text>', 'Progress notes')\n .option('--result <text>', 'Result/output produced')\n .action(kanbanUpdateCommand);\n\nkanban\n .command('done <title-or-id>')\n .description('Mark a kanban item as done')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--result <text>', 'What was produced/delivered')\n .option('--notes <text>', 'Completion notes')\n .action(kanbanDoneCommand);\n\nconst recurring = kanban\n .command('recurring')\n .description('Manage recurring kanban tasks');\n\nrecurring\n .command('add <title>')\n .description('Create a recurring kanban task')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .requiredOption('--every <schedule>', 'Schedule: \"every Monday at 9am\", \"daily at 8:30am\", \"every 2 hours\", or cron')\n .option('--priority <1|2|3>', 'Priority: 1=high, 2=medium, 3=low', '2')\n .option('--description <text>', 'Task description')\n .option('--estimate <minutes>', 'Estimated time in minutes')\n .option('--deliverable <text>', 'Expected output/deliverable')\n .option('--timezone <tz>', 'Timezone (default: UTC)')\n .action(kanbanRecurringAddCommand);\n\nrecurring\n .command('list')\n .description('List recurring kanban templates for an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanRecurringListCommand);\n\nrecurring\n .command('disable <title-or-id>')\n .description('Disable a recurring kanban template')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanRecurringDisableCommand);\n\n// ── ACPX commands ────────────────────────────────────────────────────────\n\nconst acpx = program\n .command('acpx')\n .description('Agent Client Protocol (ACP) session management via acpx')\n .option('--cwd <path>', 'Working directory for session routing')\n .option('-s, --name <name>', 'Named session for parallel workstreams')\n .option('--approve-all', 'Auto-approve all agent tool permissions')\n .option('--format <type>', 'Output format: text | json | json-strict | quiet', 'text')\n .option('--ttl <seconds>', 'Queue owner idle TTL in seconds (0 = indefinite)')\n .option('--timeout <seconds>', 'Prompt execution timeout')\n .option('--no-wait', 'Submit prompt without waiting for completion');\n\nacpx\n .command('spawn <agent>')\n .description('Spawn or ensure an ACP session for an agent (claude, codex, openclaw)')\n .action(acpxSpawnCommand);\n\nacpx\n .command('prompt <agent> <prompt>')\n .description('Send a prompt to an ACP session')\n .action(acpxPromptCommand);\n\nacpx\n .command('exec <agent> <prompt>')\n .description('One-shot execution (no session reuse)')\n .action(acpxExecCommand);\n\nacpx\n .command('list-sessions <agent>')\n .description('List active ACP sessions for an agent')\n .action(acpxListSessionsCommand);\n\nacpx\n .command('cancel <agent>')\n .description('Send cooperative cancel to the running ACP session')\n .action(acpxCancelCommand);\n\nacpx\n .command('close <agent>')\n .description('Soft-close an ACP session (preserves history)')\n .action(acpxCloseCommand);\n\n// ── Integration commands ─────────────────────────────────────────────────\n\nconst integration = program\n .command('integration')\n .description('Manage integrations — install, configure, and control permission scopes');\n\nintegration\n .command('list')\n .description('List available integrations for the active team')\n .action(integrationListCommand);\n\nintegration\n .command('show <slug>')\n .description('Show integration details including permission scopes')\n .action(integrationShowCommand);\n\nintegration\n .command('install <slug>')\n .description('Install an integration on an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--scopes <scopes>', 'Comma-separated scope IDs to grant')\n .action(integrationInstallCommand);\n\nintegration\n .command('uninstall <slug>')\n .description('Remove an integration from an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(integrationUninstallCommand);\n\nintegration\n .command('requests')\n .description('List pending scope approval requests for the team')\n .action(integrationRequestsCommand);\n\nintegration\n .command('approve <request-id>')\n .description('Approve a scope request')\n .option('--notes <text>', 'Review notes')\n .action(integrationApproveCommand);\n\nintegration\n .command('deny <request-id>')\n .description('Deny a scope request')\n .option('--reason <text>', 'Denial reason')\n .action(integrationDenyCommand);\n\nintegration\n .command('enrol')\n .description('Enrol an integration with an API key or webhook secret (no OAuth flow)')\n .requiredOption('--def <code-name>', 'Integration definition code_name (e.g. resend, xero)')\n .requiredOption('--scope <org|team|agent>', 'Install scope')\n .option('--api-key <value>', 'API key (sets auth_type=api_key)')\n .option('--access-token <value>', 'Bearer access token (sets auth_type=oauth2)')\n .option('--webhook-secret <value>', 'Webhook signing secret (sets auth_type=webhook)')\n .option('--display-name <name>', 'Override display name (defaults to the definition’s display_name)')\n .option('--agent <code-name>', 'Agent code name (required for agent scope)')\n .action(integrationEnrolCommand);\n\n// ── Update command ───────────────────────────────────────────────────────\n\nprogram\n .command('update')\n .description('Check for and install CLI updates')\n .option('--force', 'Update even if manager or agent sessions are running')\n .action(updateCommand);\n\n// ENG-5897: regression check for sub-agent MCP-binding gaps. Walks\n// `~/.claude/agents/`, `~/.claude/plugins/<plugin>/agents/`, and the\n// current dir's `.claude/agents/` and reports sub-agents whose\n// `tools:` allowlist would silently block every `mcp__*` tool on\n// dispatch.\nconst audit = program\n .command('audit')\n .description('Operator audits — sub-agent MCP bindings, etc.');\naudit\n .command('subagents')\n .description('Find sub-agents whose tools allowlist would block mcp__* calls on dispatch (ENG-5897)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditSubagentsCommand);\n\n// ENG-5922: runtime check that every managed agent's rendered\n// sub-agent .md `tools:` allowlist covers every server in its actual\n// `.mcp.json`. Catches the staleness Don found on his host (.md had 3\n// wildcards, .mcp.json had 9 keys → sub-agent calls failed with \"No\n// such tool available\" even when the tool was provisioned).\naudit\n .command('mcp-render')\n .description('Find managed agents whose subagent .md tools allowlist is stale vs .mcp.json (ENG-5922)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditMcpRenderCommand);\n\n// ENG-5901 (ADR-0018 Phase 1): operator-side scan for literal secrets in\n// `~/.augmented/<agent>/{provision,project}/.mcp.json` (should be `${VAR}`\n// placeholders) and world-readable secret files (.mcp.json / .env.integrations\n// should be 0600). Companion to the contributor-side runtime lint.\naudit\n .command('secrets')\n .description('Find literal secrets in .mcp.json and world-readable secret files (ENG-5901)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditSecretsCommand);\n\n// ── Parse & run ────────────────────────────────────────────────────────────\n\n// Non-blocking startup update check (fire-and-forget, resolves after parse)\nconst skipUpdateCheck =\n process.argv.includes('--skip-update-check') ||\n process.argv.includes('--json') ||\n process.argv[2] === 'update';\n\nif (!skipUpdateCheck) {\n // Fire the check but don't await — it prints to stderr if an update is found\n checkForUpdateOnStartup().catch(() => {});\n}\n\n// parseAsync (not parse) so the async pre-action hook — which may auto-exit an\n// expired impersonation session — is awaited before the command's action runs.\nprogram.parseAsync().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n});\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { getApiKey, getHost } from '../lib/config.js';\nimport { exchangeApiKey } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nexport async function whoamiCommand(): Promise<void> {\n const json = isJsonMode();\n const apiKey = getApiKey();\n\n if (!apiKey) {\n if (json) {\n jsonOutput({ ok: false, error: 'AGT_API_KEY is not set' });\n } else {\n error('AGT_API_KEY is not set. Export it with your host API key (tlk_...)');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Exchanging API key\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const exchange = await exchangeApiKey(apiKey);\n spinner.stop();\n\n const framework = exchange.framework ?? 'unset';\n const claudeAuthLabel = exchange.claudeAuthMode === 'api_key'\n ? `api_key (fp: ${exchange.anthropicApiKeyFingerprint ?? 'unknown'})`\n : 'subscription';\n\n if (json) {\n jsonOutput({\n ok: true,\n api_key_prefix: apiKey.slice(0, 8) + '****',\n host: getHost(),\n host_id: exchange.hostId,\n team: exchange.teamSlug,\n team_id: exchange.teamId,\n email: exchange.userEmail,\n framework: exchange.framework,\n claude_auth_mode: exchange.claudeAuthMode,\n anthropic_api_key_fingerprint: exchange.anthropicApiKeyFingerprint,\n });\n return;\n }\n\n success('Authenticated via API key');\n info(`API Key: ${chalk.bold(apiKey.slice(0, 8) + '****')}`);\n info(`Host: ${chalk.bold(getHost())}`);\n info(`Host ID: ${exchange.hostId}`);\n info(`Team: ${chalk.bold(exchange.teamSlug ?? exchange.teamId)}`);\n info(`User: ${chalk.bold(exchange.userEmail ?? 'unknown')}`);\n info(`Framework: ${chalk.bold(framework)}`);\n if (framework === 'claude-code') {\n info(`Claude Auth: ${chalk.bold(claudeAuthLabel)}`);\n }\n } catch (err) {\n spinner.fail('Failed to exchange API key.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { setActiveTeam, getActiveTeam } from '../lib/config.js';\nimport { api } from '../lib/api-client.js';\nimport { requireAuth } from '../lib/auth-guard.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\n/**\n * `agt team list`\n * Fetch teams where the current user is a member and display as a table.\n */\nexport async function teamListCommand(): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching teams\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n teams: Array<{\n id: string;\n name: string;\n slug: string;\n plan: string;\n role: string;\n created_at: string;\n }>;\n }>('/teams');\n\n spinner.stop();\n\n if (!data.teams || data.teams.length === 0) {\n if (json) {\n jsonOutput({ ok: true, teams: [] });\n } else {\n info('You are not a member of any teams. Create one with `agt team create <name>`.');\n }\n return;\n }\n\n const activeSlug = getActiveTeam();\n\n if (json) {\n const teams = data.teams.map((ws) => ({\n name: ws.name,\n slug: ws.slug,\n role: ws.role,\n active: ws.slug === activeSlug,\n }));\n jsonOutput({ ok: true, teams });\n return;\n }\n\n const rows = data.teams.map((ws) => {\n const active = ws.slug === activeSlug ? chalk.green('*') : '';\n return [active, ws.name, ws.slug, ws.role];\n });\n\n table(['', 'Name', 'Slug', 'Role'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch teams.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt team create <name>`\n * Create a new team, add the creator as owner, and set it as active.\n */\nexport async function teamCreateCommand(name: string): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const slug = name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n if (!slug) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid team name' });\n } else {\n error('Invalid team name. It must contain at least one alphanumeric character.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: `Creating team \"${name}\" (${slug})\\u2026`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.post<{\n team: { id: string; name: string; slug: string; plan: string; role: string };\n }>('/teams', { name, slug });\n\n // Set as active\n setActiveTeam(data.team.slug);\n\n spinner.succeed(`Team \"${chalk.bold(name)}\" created.`);\n\n if (json) {\n jsonOutput({ ok: true, name, slug: data.team.slug, role: data.team.role });\n return;\n }\n\n info(`Slug: ${chalk.bold(data.team.slug)}`);\n success(`Active team set to ${chalk.bold(data.team.slug)}.`);\n } catch (err) {\n spinner.fail('Failed to create team.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt team switch <slug>`\n * Verify the user is a member of the team and set it as active.\n */\nexport async function teamSwitchCommand(slug: string): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Switching to team \"${slug}\"\\u2026`, isSilent: json });\n spinner.start();\n\n try {\n await api.get(`/teams/${encodeURIComponent(slug)}`);\n\n setActiveTeam(slug);\n spinner.succeed(`Active team set to ${chalk.bold(slug)}.`);\n\n if (json) {\n jsonOutput({ ok: true, team: slug });\n }\n } catch (err) {\n spinner.fail(`Could not switch to team \"${slug}\".`);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { getApiKey } from './config.js';\nimport { error } from './output.js';\n\n/**\n * Guard: checks that AGT_API_KEY is set.\n * Returns false (and prints an error) if not.\n */\nexport function requireAuth(): boolean {\n const key = getApiKey();\n if (!key) {\n error('AGT_API_KEY is not set. Export it with your host API key (tlk_...)');\n process.exitCode = 1;\n return false;\n }\n return true;\n}\n\n/**\n * Guard: checks that AGT_API_KEY is set.\n * Team auto-resolves from the API key exchange.\n * Returns a truthy string on success, or null on failure.\n */\nexport function requireTeam(): string | null {\n if (!requireAuth()) return null;\n return 'auto'; // team resolves from exchange\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { input, select, checkbox, confirm } from '@inquirer/prompts';\nimport { randomUUID } from 'node:crypto';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n generateCharterMd,\n generateToolsMd,\n lintAll,\n getAllChannelIds,\n type CharterGenerationInput,\n type ToolsGenerationInput,\n type ChannelId,\n type LintDiagnostic,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction toSlug(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} [${d.code}] ${d.message}${path}`);\n }\n}\n\n/** Options passed from Commander flags. */\ninterface InitOptions {\n name?: string;\n codeName?: string;\n description?: string;\n env?: string;\n riskTier?: string;\n budgetType?: string;\n budgetTokens?: string;\n budgetDollars?: string;\n budgetWindow?: string;\n budgetEnforcement?: string;\n channels?: string;\n logging?: string;\n}\n\n/**\n * `agt init`\n * Interactive wizard to create a new agent, generate CHARTER.md + TOOLS.md,\n * register via the API, and write files to `.augmented/<code_name>/`.\n */\nexport async function initCommand(opts: InitOptions): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const nonInteractive = !!opts.name;\n const json = isJsonMode();\n\n let displayName: string;\n let codeName: string;\n let description: string;\n let environment: 'dev' | 'stage' | 'prod';\n let riskTier: 'Low' | 'Medium' | 'High';\n let budgetType: 'tokens' | 'dollars' | 'both';\n let budgetLimitTokens: number | undefined;\n let budgetLimitDollars: number | undefined;\n let budgetLimit: number;\n let budgetWindow: 'daily' | 'weekly' | 'monthly';\n let budgetEnforcement: 'alert' | 'throttle' | 'block' | 'degrade';\n let selectedChannels: ChannelId[];\n let loggingMode: 'hash-only' | 'redacted' | 'full-local';\n\n if (nonInteractive) {\n displayName = opts.name!;\n codeName = opts.codeName ?? toSlug(displayName);\n description = opts.description ?? `${displayName} agent`;\n environment = (opts.env ?? 'dev') as 'dev' | 'stage' | 'prod';\n riskTier = (opts.riskTier ?? 'Low') as 'Low' | 'Medium' | 'High';\n budgetType = (opts.budgetType ?? 'tokens') as 'tokens' | 'dollars' | 'both';\n budgetLimitTokens = (budgetType === 'tokens' || budgetType === 'both')\n ? Number(opts.budgetTokens ?? '10000')\n : undefined;\n budgetLimitDollars = (budgetType === 'dollars' || budgetType === 'both')\n ? Number(opts.budgetDollars ?? '10')\n : undefined;\n budgetLimit = budgetLimitTokens ?? budgetLimitDollars ?? 10000;\n budgetWindow = (opts.budgetWindow ?? 'daily') as 'daily' | 'weekly' | 'monthly';\n budgetEnforcement = (opts.budgetEnforcement ?? 'block') as 'alert' | 'throttle' | 'block' | 'degrade';\n selectedChannels = opts.channels\n ? opts.channels.split(',').map((c) => c.trim()) as ChannelId[]\n : [];\n loggingMode = (opts.logging ?? 'redacted') as 'hash-only' | 'redacted' | 'full-local';\n } else {\n console.log(chalk.bold('\\nAugmented — Agent Init Wizard\\n'));\n\n displayName = await input({\n message: 'Agent display name:',\n validate: (v) => v.trim().length > 0 || 'Name is required',\n });\n\n const suggestedSlug = toSlug(displayName);\n codeName = await input({\n message: 'Code name (kebab-case):',\n default: suggestedSlug,\n validate: (v) => /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(v) || 'Must be lowercase alphanumeric with hyphens',\n });\n\n description = await input({\n message: 'Short description:',\n default: `${displayName} agent`,\n });\n\n environment = await select({\n message: 'Environment:',\n choices: [\n { value: 'dev', name: 'dev' },\n { value: 'stage', name: 'stage' },\n { value: 'prod', name: 'prod' },\n ],\n }) as 'dev' | 'stage' | 'prod';\n\n riskTier = await select({\n message: 'Risk tier:',\n choices: [\n { value: 'Low', name: 'Low — read-only tools, no PII' },\n { value: 'Medium', name: 'Medium — write access, limited scope' },\n { value: 'High', name: 'High — broad access, PII, external comms' },\n ],\n }) as 'Low' | 'Medium' | 'High';\n\n budgetType = await select({\n message: 'Budget type:',\n choices: [\n { value: 'tokens', name: 'Tokens' },\n { value: 'dollars', name: 'Dollars' },\n { value: 'both', name: 'Both' },\n ],\n }) as 'tokens' | 'dollars' | 'both';\n\n budgetLimit = 10000;\n budgetLimitTokens = undefined;\n budgetLimitDollars = undefined;\n\n if (budgetType === 'tokens' || budgetType === 'both') {\n const val = await input({\n message: 'Token budget limit:',\n default: '10000',\n validate: (v) => !isNaN(Number(v)) && Number(v) > 0 || 'Must be a positive number',\n });\n budgetLimitTokens = Number(val);\n budgetLimit = budgetLimitTokens;\n }\n\n if (budgetType === 'dollars' || budgetType === 'both') {\n const val = await input({\n message: 'Dollar budget limit:',\n default: '10',\n validate: (v) => !isNaN(Number(v)) && Number(v) > 0 || 'Must be a positive number',\n });\n budgetLimitDollars = Number(val);\n if (budgetType === 'dollars') budgetLimit = budgetLimitDollars;\n }\n\n budgetWindow = await select({\n message: 'Budget window:',\n choices: [\n { value: 'daily', name: 'Daily' },\n { value: 'weekly', name: 'Weekly' },\n { value: 'monthly', name: 'Monthly' },\n ],\n }) as 'daily' | 'weekly' | 'monthly';\n\n budgetEnforcement = await select({\n message: 'Budget enforcement:',\n choices: [\n { value: 'block', name: 'Block — hard stop when limit reached' },\n { value: 'throttle', name: 'Throttle — slow down near limit' },\n { value: 'alert', name: 'Alert — warn but do not stop' },\n { value: 'degrade', name: 'Degrade — switch to cheaper model' },\n ],\n }) as 'alert' | 'throttle' | 'block' | 'degrade';\n\n const allChannels = getAllChannelIds();\n selectedChannels = await checkbox({\n message: 'Select allowed channels:',\n choices: allChannels.map((c) => ({ value: c, name: c })),\n }) as ChannelId[];\n\n loggingMode = await select({\n message: 'Logging mode:',\n choices: [\n { value: 'redacted', name: 'Redacted — PII stripped' },\n { value: 'hash-only', name: 'Hash-only — content is hashed' },\n { value: 'full-local', name: 'Full local — plain text (dev only)' },\n ],\n }) as 'hash-only' | 'redacted' | 'full-local';\n }\n\n // ── Resolve user info via API ─────────────────────────────────────────\n\n const spinner = ora({ text: 'Creating agent…', isSilent: json });\n spinner.start();\n\n let userEmail: string;\n let userId: string;\n try {\n const me = await api.get<{ id: string; email: string | null }>('/auth/me');\n userId = me.id;\n userEmail = me.email ?? me.id;\n } catch (err) {\n spinner.fail('Could not determine current user.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const agentId = randomUUID();\n\n // ── Generate CHARTER.md + TOOLS.md ─────────────────────────────────────\n\n const charterInput: CharterGenerationInput = {\n agent_id: agentId,\n code_name: codeName,\n display_name: displayName,\n environment,\n owner: {\n id: userId,\n name: userEmail,\n email: userEmail,\n },\n risk_tier: riskTier,\n logging_mode: loggingMode,\n description,\n };\n\n const toolsInput: ToolsGenerationInput = {\n agent_id: agentId,\n code_name: codeName,\n environment,\n owner: userEmail,\n display_name: displayName,\n logging_redaction: loggingMode,\n };\n\n const charterMd = generateCharterMd(charterInput);\n const toolsMd = generateToolsMd(toolsInput);\n\n // ── Lint ────────────────────────────────────────────────────────────────\n\n const lintResult = lintAll(charterMd, toolsMd);\n\n // ── Register via API ───────────────────────────────────────────────────\n\n try {\n await api.post('/agents', {\n code_name: codeName,\n display_name: displayName,\n description,\n environment,\n risk_tier: riskTier,\n channels: selectedChannels,\n charter_content: charterMd,\n charter_version: '0.1',\n tools_content: toolsMd,\n tools_version: '0.1',\n });\n } catch (err) {\n spinner.fail('Failed to register agent.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Write files to .augmented/<code_name>/ ─────────────────────────────\n\n const agentDir = join(process.cwd(), '.augmented', codeName);\n mkdirSync(agentDir, { recursive: true });\n writeFileSync(join(agentDir, 'CHARTER.md'), charterMd);\n writeFileSync(join(agentDir, 'TOOLS.md'), toolsMd);\n\n spinner.succeed(`Agent \"${chalk.bold(displayName)}\" created.`);\n\n // ── Output ─────────────────────────────────────────────────────────────\n\n if (json) {\n jsonOutput({\n ok: true,\n agent_id: agentId,\n code_name: codeName,\n display_name: displayName,\n environment,\n risk_tier: riskTier,\n channels: selectedChannels,\n directory: agentDir,\n lint: {\n ok: lintResult.ok,\n errors: lintResult.errors.length,\n warnings: lintResult.warnings.length,\n diagnostics: [...lintResult.errors, ...lintResult.warnings],\n },\n });\n return;\n }\n\n console.log();\n info(`Agent ID: ${agentId}`);\n info(`Code Name: ${codeName}`);\n info(`Environment: ${environment}`);\n info(`Risk Tier: ${riskTier}`);\n info(`Channels: ${selectedChannels.length > 0 ? selectedChannels.join(', ') : 'none'}`);\n info(`Files: ${agentDir}/CHARTER.md, TOOLS.md`);\n console.log();\n\n if (lintResult.ok && lintResult.warnings.length === 0) {\n success('Lint passed — no errors or warnings.');\n } else {\n if (lintResult.errors.length > 0) {\n error(`Lint: ${lintResult.errors.length} error(s)`);\n printDiagnostics(lintResult.errors);\n }\n if (lintResult.warnings.length > 0) {\n warn(`Lint: ${lintResult.warnings.length} warning(s)`);\n printDiagnostics(lintResult.warnings);\n }\n }\n\n console.log();\n info(`Next steps:`);\n info(` 1. Edit ${chalk.bold('.augmented/' + codeName + '/CHARTER.md')} to refine the agent charter`);\n info(` 2. Edit ${chalk.bold('.augmented/' + codeName + '/TOOLS.md')} to add tools`);\n info(` 3. Run ${chalk.bold('agt lint')} to validate`);\n info(` 4. Run ${chalk.bold('agt deploy')} to generate deployment config`);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport {\n lintCharter,\n lintTools,\n lintAll,\n type LintDiagnostic,\n type LintResult,\n type OrgChannelPolicy,\n type ChannelId,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const file = chalk.dim(`[${d.file}]`);\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} ${file} ${d.code}: ${d.message}${path}`);\n }\n}\n\nfunction printResult(label: string, result: LintResult): void {\n if (result.ok && result.warnings.length === 0) {\n success(`${label}: passed`);\n return;\n }\n if (result.errors.length > 0) {\n error(`${label}: ${result.errors.length} error(s)`);\n printDiagnostics(result.errors);\n }\n if (result.warnings.length > 0) {\n warn(`${label}: ${result.warnings.length} warning(s)`);\n printDiagnostics(result.warnings);\n }\n}\n\n/**\n * `agt lint [path]`\n */\nexport async function lintCommand(path?: string): Promise<void> {\n const json = isJsonMode();\n\n const dirs: { name: string; dir: string }[] = [];\n\n if (path) {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n if (json) {\n jsonOutput({ ok: false, error: `Path not found: ${resolved}` });\n } else {\n error(`Path not found: ${resolved}`);\n }\n process.exitCode = 1;\n return;\n }\n dirs.push({ name: path, dir: resolved });\n } else {\n const augmentedDir = join(process.cwd(), '.augmented');\n if (!existsSync(augmentedDir)) {\n if (json) {\n jsonOutput({ ok: false, error: 'No .augmented/ directory found' });\n } else {\n error('No .augmented/ directory found. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n\n const { readdirSync, statSync } = await import('node:fs');\n const entries = readdirSync(augmentedDir);\n for (const entry of entries) {\n const entryPath = join(augmentedDir, entry);\n if (statSync(entryPath).isDirectory()) {\n dirs.push({ name: entry, dir: entryPath });\n }\n }\n\n if (dirs.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'No agent directories found in .augmented/' });\n } else {\n error('No agent directories found in .augmented/. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n // Optionally fetch team channel policy via API\n let orgPolicy: OrgChannelPolicy | undefined;\n const teamSlug = requireTeam();\n if (teamSlug) {\n const spinner = ora({ text: 'Fetching org channel policy…', isSilent: json });\n spinner.start();\n try {\n const data = await api.get<{\n channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n }>(`/teams/${encodeURIComponent(teamSlug)}/channel-policy`);\n\n if (data.channel_policy) {\n orgPolicy = {\n organization_id: data.channel_policy.team_id,\n allowed_channels: (data.channel_policy.allowed_channels ?? []) as ChannelId[],\n denied_channels: (data.channel_policy.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: data.channel_policy.require_elevated_for_pii ?? false,\n };\n }\n spinner.stop();\n } catch {\n spinner.stop();\n // Non-fatal — lint without org policy\n }\n }\n\n let totalErrors = 0;\n let totalWarnings = 0;\n const jsonResults: Record<string, unknown>[] = [];\n\n for (const { name, dir } of dirs) {\n if (!json) console.log(chalk.bold(`\\nLinting ${name}:`));\n\n const charterPath = join(dir, 'CHARTER.md');\n const toolsPath = join(dir, 'TOOLS.md');\n const hasCharter = existsSync(charterPath);\n const hasTools = existsSync(toolsPath);\n\n if (!hasCharter && !hasTools) {\n if (!json) warn('No CHARTER.md or TOOLS.md found — skipping.');\n if (json) jsonResults.push({ agent: name, skipped: true });\n continue;\n }\n\n const charterContent = hasCharter ? readFileSync(charterPath, 'utf-8') : undefined;\n const toolsContent = hasTools ? readFileSync(toolsPath, 'utf-8') : undefined;\n\n let result: LintResult;\n if (charterContent && toolsContent) {\n result = lintAll(charterContent, toolsContent, { orgChannelPolicy: orgPolicy });\n if (!json) printResult('Full lint', result);\n } else if (charterContent) {\n result = lintCharter(charterContent, { orgChannelPolicy: orgPolicy });\n if (!json) printResult('CHARTER.md', result);\n } else {\n result = lintTools(toolsContent!);\n if (!json) printResult('TOOLS.md', result);\n }\n\n totalErrors += result.errors.length;\n totalWarnings += result.warnings.length;\n\n if (json) {\n jsonResults.push({\n agent: name,\n ok: result.ok,\n errors: result.errors.length,\n warnings: result.warnings.length,\n diagnostics: [...result.errors, ...result.warnings],\n });\n }\n }\n\n if (json) {\n jsonOutput({\n ok: totalErrors === 0,\n agents: jsonResults,\n total_errors: totalErrors,\n total_warnings: totalWarnings,\n });\n if (totalErrors > 0) process.exitCode = 1;\n return;\n }\n\n console.log();\n if (totalErrors === 0 && totalWarnings === 0) {\n success(`All ${dirs.length} agent(s) passed lint.`);\n } else {\n if (totalErrors > 0) {\n error(`Total: ${totalErrors} error(s) across ${dirs.length} agent(s)`);\n process.exitCode = 1;\n }\n if (totalWarnings > 0) {\n warn(`Total: ${totalWarnings} warning(s) across ${dirs.length} agent(s)`);\n }\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport {\n CHANNEL_REGISTRY,\n getChannel,\n resolveChannels,\n type ChannelId,\n type ChannelPolicy,\n type OrgChannelPolicy,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n/**\n * `agt channels list`\n */\nexport function channelsListCommand(): void {\n const json = isJsonMode();\n\n if (json) {\n const channels = CHANNEL_REGISTRY.map((ch) => ({\n id: ch.id,\n name: ch.name,\n security_tier: ch.securityTier,\n e2e_encrypted: ch.e2eEncrypted,\n audit_trail: ch.auditTrail,\n public_exposure_risk: ch.publicExposureRisk,\n }));\n jsonOutput({ ok: true, channels });\n return;\n }\n\n console.log(chalk.bold('\\nChannel Registry (18 channels)\\n'));\n\n const rows = CHANNEL_REGISTRY.map((ch) => [\n ch.id,\n ch.name,\n ch.securityTier === 'elevated'\n ? chalk.green(ch.securityTier)\n : ch.securityTier === 'limited'\n ? chalk.red(ch.securityTier)\n : chalk.cyan(ch.securityTier),\n typeof ch.e2eEncrypted === 'boolean'\n ? (ch.e2eEncrypted ? chalk.green('yes') : chalk.dim('no'))\n : chalk.yellow(ch.e2eEncrypted),\n typeof ch.auditTrail === 'boolean'\n ? (ch.auditTrail ? chalk.green('yes') : chalk.dim('no'))\n : chalk.yellow(ch.auditTrail),\n ch.publicExposureRisk === 'High'\n ? chalk.red(ch.publicExposureRisk)\n : ch.publicExposureRisk === 'Medium'\n ? chalk.yellow(ch.publicExposureRisk)\n : chalk.green(ch.publicExposureRisk),\n ]);\n\n table(['ID', 'Name', 'Security Tier', 'E2E Encrypted', 'Audit Trail', 'Public Risk'], rows);\n}\n\n/**\n * `agt channels check <agent>`\n */\nexport async function channelsCheckCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Resolving channels for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n agent_channels: string[];\n channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channels`);\n\n const agentPolicy: ChannelPolicy = {\n policy: 'allowlist',\n allowed: (data.agent_channels ?? []) as ChannelId[],\n denied: [],\n require_approval_to_change: false,\n };\n\n const orgPolicy: OrgChannelPolicy | undefined = data.channel_policy\n ? {\n organization_id: data.channel_policy.team_id,\n allowed_channels: (data.channel_policy.allowed_channels ?? []) as ChannelId[],\n denied_channels: (data.channel_policy.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: data.channel_policy.require_elevated_for_pii ?? false,\n }\n : undefined;\n\n const resolved = resolveChannels(agentPolicy, orgPolicy);\n\n spinner.stop();\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n agent_allowlist: agentPolicy.allowed,\n org_policy: orgPolicy\n ? {\n allowed: orgPolicy.allowed_channels,\n denied: orgPolicy.denied_channels,\n require_elevated_for_pii: orgPolicy.require_elevated_for_pii,\n }\n : null,\n resolved_channels: resolved,\n count: resolved.length,\n });\n return;\n }\n\n console.log(chalk.bold(`\\nChannel Resolution: ${agentCodeName}\\n`));\n\n info(`Agent allowlist: ${agentPolicy.allowed.length > 0 ? agentPolicy.allowed.join(', ') : 'none'}`);\n\n if (orgPolicy) {\n info(`Org allowed: ${orgPolicy.allowed_channels.length > 0 ? orgPolicy.allowed_channels.join(', ') : 'all (no restriction)'}`);\n info(`Org denied: ${orgPolicy.denied_channels.length > 0 ? orgPolicy.denied_channels.join(', ') : 'none'}`);\n if (orgPolicy.require_elevated_for_pii) {\n info('Org requires elevated tier for PII channels');\n }\n } else {\n info('No org channel policy configured.');\n }\n\n console.log();\n\n if (resolved.length === 0) {\n error('No channels available after resolution. The agent cannot communicate.');\n process.exitCode = 1;\n return;\n }\n\n const rows = resolved.map((chId) => {\n const ch = getChannel(chId);\n return [\n chId,\n ch?.name ?? 'Unknown',\n ch?.securityTier ?? '-',\n ch?.publicExposureRisk ?? '-',\n ];\n });\n\n success(`${resolved.length} channel(s) available:`);\n table(['ID', 'Name', 'Security Tier', 'Public Risk'], rows);\n } catch (err) {\n spinner.fail('Failed to resolve channels.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { checkbox, confirm, input } from '@inquirer/prompts';\nimport {\n getDefaultSlackScopes,\n getScopesByCategory,\n SLACK_SCOPE_CATEGORY_LABELS,\n SLACK_SCOPE_PRESETS,\n generateSlackAppManifest,\n serializeManifestForSlackCli,\n createSlackApp,\n SlackApiError,\n type SlackScope,\n type SlackScopeCategory,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, warn, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nimport { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\n/**\n * `agt channels slack setup <agent-code-name>`\n */\nexport async function channelSlackSetupCommand(\n agentCodeName: string,\n options: {\n preset?: string;\n scopes?: string;\n skipCreate?: boolean;\n botToken?: string;\n signingSecret?: string;\n configToken?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Look up agent via API\n const agentData = await api.get<{\n agent: {\n agent_id: string;\n code_name: string;\n display_name: string;\n channels: string[];\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}`);\n\n const agent = agentData.agent;\n\n // Verify slack is in the agent's channel list\n const channels: string[] = agent.channels ?? [];\n if (!channels.includes('slack')) {\n spinner.fail(`Agent \"${agentCodeName}\" does not have Slack in its channel list.`);\n error('Enable Slack in the agent\\'s channels first (add \"slack\" to the channels array).');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed(`Found agent \"${agentCodeName}\"`);\n\n // ── Scope selection ─────────────────────────────────────────────────\n let selectedScopes: SlackScope[];\n\n if (options.scopes) {\n selectedScopes = options.scopes.split(',').map((s) => s.trim()) as SlackScope[];\n } else if (options.preset) {\n const preset = options.preset as keyof typeof SLACK_SCOPE_PRESETS;\n if (!(preset in SLACK_SCOPE_PRESETS)) {\n error(`Unknown preset \"${options.preset}\". Available: minimal, standard, full`);\n process.exitCode = 1;\n return;\n }\n selectedScopes = [...SLACK_SCOPE_PRESETS[preset]];\n info(`Using \"${preset}\" preset (${selectedScopes.length} scopes)`);\n } else if (json) {\n selectedScopes = [...SLACK_SCOPE_PRESETS.standard];\n } else {\n const scopesByCategory = getScopesByCategory();\n const defaults = getDefaultSlackScopes();\n\n type CheckboxChoice = { name: string; value: SlackScope; checked: boolean };\n type CheckboxSeparator = { type: 'separator'; separator: string };\n const choices: Array<CheckboxChoice | CheckboxSeparator> = [];\n for (const [category, defs] of scopesByCategory) {\n const label = SLACK_SCOPE_CATEGORY_LABELS[category as SlackScopeCategory];\n choices.push({ type: 'separator', separator: `── ${label} ──` });\n for (const def of defs) {\n const riskColor =\n def.risk === 'high' ? chalk.red : def.risk === 'medium' ? chalk.yellow : chalk.green;\n choices.push({\n name: `${def.scope} ${chalk.dim(`— ${def.description}`)} ${riskColor(`[${def.risk}]`)}`,\n value: def.scope,\n checked: defaults.includes(def.scope),\n });\n }\n }\n\n selectedScopes = await checkbox({\n message: 'Select Slack bot scopes:',\n choices,\n pageSize: 30,\n });\n }\n\n if (selectedScopes.length === 0) {\n error('No scopes selected. At least one scope is required.');\n process.exitCode = 1;\n return;\n }\n\n info(`Selected ${selectedScopes.length} scope(s): ${selectedScopes.join(', ')}`);\n\n // ── Generate manifest ───────────────────────────────────────────────\n const manifest = generateSlackAppManifest({\n agent_name: agent.display_name ?? agentCodeName,\n description: `Augmented-managed Slack bot for agent ${agentCodeName}`,\n scopes: selectedScopes,\n });\n\n const manifestObj = serializeManifestForSlackCli(manifest);\n\n const manifestJson = JSON.stringify(manifestObj, null, 2);\n const manifestPath = join(tmpdir(), `augmented-slack-manifest-${agentCodeName}.json`);\n await writeFile(manifestPath, manifestJson, 'utf-8');\n\n success(`Manifest written to ${manifestPath}`);\n console.log(chalk.dim(manifestJson));\n\n // ── Slack app creation via API ──────────────────────────────────────\n let appId: string | undefined;\n let botTokenRef: string | undefined = options.botToken;\n let signingSecretRef: string | undefined = options.signingSecret;\n\n if (!options.skipCreate) {\n let token = options.configToken;\n if (!token && !json) {\n token = (await input({\n message: 'Paste your Slack config token (xoxe-…) to create the app automatically, or leave empty to skip:',\n })).trim() || undefined;\n }\n\n if (token) {\n const createSpinner = ora({ text: 'Creating Slack app via API…', isSilent: json });\n createSpinner.start();\n\n try {\n const result = await createSlackApp(token, manifest);\n appId = result.app_id;\n signingSecretRef = `secret_ref://slack/${agentCodeName}/signing_secret`;\n createSpinner.succeed(`Slack app created: ${result.app_id}`);\n info(`OAuth URL: ${result.oauth_authorize_url}`);\n } catch (err) {\n createSpinner.fail('Failed to create Slack app via API.');\n if (err instanceof SlackApiError) {\n warn(`Slack API error: ${err.message}`);\n } else {\n warn((err as Error).message);\n }\n info(`Manifest saved at: ${manifestPath}`);\n info('Create the app manually via https://api.slack.com/apps and paste the manifest.');\n }\n } else {\n info(`Manifest saved at: ${manifestPath}`);\n info('Create the app manually via https://api.slack.com/apps and paste the manifest.');\n }\n }\n\n if (!signingSecretRef && !json) {\n const secret = await input({\n message: 'Paste your Slack Signing Secret, or leave empty to skip:',\n });\n if (secret.trim()) {\n signingSecretRef = `secret_ref://slack/${agentCodeName}/signing_secret`;\n }\n }\n\n if (!botTokenRef && !json) {\n const token = await input({\n message: 'Paste your Slack Bot Token (xoxb-…), or leave empty to skip:',\n });\n if (token.trim()) {\n botTokenRef = `secret_ref://slack/${agentCodeName}/bot_token`;\n }\n }\n\n // ── Store config via API ────────────────────────────────────────────\n const configSpinner = ora({ text: 'Saving channel config…', isSilent: json });\n configSpinner.start();\n\n const config = {\n channel_type: 'slack' as const,\n app_name: agent.display_name ?? agentCodeName,\n scopes: selectedScopes,\n ...(appId ? { app_id: appId } : {}),\n ...(botTokenRef ? { bot_token_ref: botTokenRef } : {}),\n ...(signingSecretRef ? { signing_secret_ref: signingSecretRef } : {}),\n manifest,\n };\n\n try {\n await api.put(\n `/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`,\n {\n config,\n status: botTokenRef ? 'configured' : 'pending',\n },\n );\n } catch (err) {\n configSpinner.fail('Failed to save channel config.');\n error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n\n configSpinner.succeed('Slack channel config saved.');\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n channel: 'slack',\n scopes: selectedScopes,\n status: botTokenRef ? 'configured' : 'pending',\n manifest_path: manifestPath,\n });\n } else {\n console.log();\n success(`Slack setup complete for \"${agentCodeName}\"`);\n info(`Status: ${botTokenRef ? 'configured' : 'pending (add credentials to activate)'}`);\n }\n } catch (err) {\n spinner.fail('Slack setup failed.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels slack status <agent-code-name>`\n */\nexport async function channelSlackStatusCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Fetching Slack config for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n config: {\n channel_type: string;\n app_name?: string;\n scopes?: string[];\n bot_token_ref?: string;\n signing_secret_ref?: string;\n app_id?: string;\n team_id?: string;\n status?: string;\n created_at?: string;\n updated_at?: string;\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n\n spinner.stop();\n\n const config = data.config;\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n channel: 'slack',\n configured: true,\n config,\n });\n return;\n }\n\n console.log(chalk.bold(`\\nSlack Configuration: ${agentCodeName}\\n`));\n\n const rows: string[][] = [\n ['App Name', config.app_name ?? '-'],\n ['App ID', config.app_id ?? '-'],\n ['Team ID', config.team_id ?? '-'],\n ['Bot Token', config.bot_token_ref ? chalk.green('configured') : chalk.dim('not set')],\n ['Signing Secret', config.signing_secret_ref ? chalk.green('configured') : chalk.dim('not set')],\n ['Scopes', (config.scopes ?? []).join(', ') || '-'],\n ];\n\n table(['Field', 'Value'], rows);\n } catch (err) {\n spinner.stop();\n if ((err as any).status === 404) {\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', configured: false });\n } else {\n warn(`No Slack configuration found for \"${agentCodeName}\".`);\n info('Run `agt channels slack setup ' + agentCodeName + '` to configure.');\n }\n return;\n }\n\n spinner.fail('Failed to fetch Slack status.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels slack remove <agent-code-name>`\n */\nexport async function channelSlackRemoveCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Check if config exists\n let config: { app_id?: string; app_name?: string } | null = null;\n try {\n const data = await api.get<{ config: { app_id?: string; app_name?: string } | null }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n config = data.config;\n } catch (err) {\n if ((err as any).status === 404) {\n spinner.info(`No Slack configuration found for \"${agentCodeName}\".`);\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', removed: false, reason: 'not_configured' });\n }\n return;\n }\n throw err;\n }\n\n spinner.stop();\n\n // Confirm removal\n if (!json) {\n const appLabel = config?.app_id\n ? ` (App ID: ${config.app_id})`\n : config?.app_name\n ? ` (${config.app_name})`\n : '';\n const confirmed = await confirm({\n message: `Remove Slack bot configuration${appLabel} for \"${agentCodeName}\"?`,\n default: false,\n });\n\n if (!confirmed) {\n warn('Aborted.');\n return;\n }\n }\n\n const removeSpinner = ora({ text: 'Removing Slack configuration…', isSilent: json });\n removeSpinner.start();\n\n await api.del(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n\n removeSpinner.succeed('Slack configuration removed.');\n\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', removed: true });\n } else {\n if (config?.app_id) {\n console.log();\n info(`Note: The Slack app (${config.app_id}) still exists in your Slack workspace.`);\n info('Delete it manually at https://api.slack.com/apps if no longer needed.');\n }\n }\n } catch (err) {\n error((err as Error).message);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { confirm } from '@inquirer/prompts';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n/**\n * `agt channels beam setup <agent-code-name>`\n */\nexport async function channelBeamSetupCommand(\n agentCodeName: string,\n options: {\n directoryUrl?: string;\n skipRegister?: boolean;\n autoPublish?: boolean;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Look up agent via API\n const agentData = await api.get<{\n agent: {\n agent_id: string;\n code_name: string;\n display_name: string;\n team_id: string;\n channels: string[];\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}`);\n\n const agent = agentData.agent;\n\n // Verify beam is in the agent's channel list\n const channels: string[] = agent.channels ?? [];\n if (!channels.includes('beam')) {\n spinner.fail(`Agent \"${agentCodeName}\" does not have Beam in its channel list.`);\n error('Enable Beam in the agent\\'s channels first (add \"beam\" to the channels array).');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed(`Found agent \"${agentCodeName}\"`);\n\n // Check for existing config\n const existingConfig = await api.get<{\n config: Record<string, unknown> | null;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`).catch(() => ({ config: null }));\n\n if (existingConfig.config?.beam_id) {\n info(`Agent already has Beam identity: ${chalk.cyan(String(existingConfig.config.beam_id))}`);\n const proceed = await confirm({\n message: 'Regenerate identity? This will create a new keypair and re-register.',\n default: false,\n });\n if (!proceed) return;\n }\n\n // Generate identity and register\n spinner.start('Generating Ed25519 identity and registering with Beam directory…');\n\n const result = await api.post<{\n ok: boolean;\n beam_id: string;\n did: string;\n public_key: string;\n trust_score: number;\n verification_tier: string;\n published_capabilities: string[];\n error?: string;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam/setup`, {\n auto_publish_capabilities: options.autoPublish ?? true,\n directory_url: options.directoryUrl,\n });\n\n if (!result.ok) {\n spinner.fail('Registration failed');\n error(result.error ?? 'Unknown error');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed('Beam identity created and registered');\n\n if (json) {\n jsonOutput({\n beam_id: result.beam_id,\n did: result.did,\n public_key: result.public_key,\n trust_score: result.trust_score,\n verification_tier: result.verification_tier,\n published_capabilities: result.published_capabilities,\n });\n return;\n }\n\n console.log();\n table(\n ['Field', 'Value'],\n [\n ['Beam ID', chalk.cyan(result.beam_id)],\n ['DID', chalk.dim(result.did)],\n ['Trust Score', String(result.trust_score)],\n ['Verification', result.verification_tier],\n ['Capabilities', result.published_capabilities.length > 0\n ? result.published_capabilities.join(', ')\n : chalk.dim('none published')],\n ],\n );\n console.log();\n success(`Agent \"${agentCodeName}\" is now reachable at ${chalk.cyan(result.beam_id)}`);\n } catch (err) {\n spinner.fail('Setup failed');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels beam status <agent-code-name>`\n */\nexport async function channelBeamStatusCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Fetching Beam config for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n config: Record<string, unknown> | null;\n status?: string;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`);\n\n if (!data.config?.beam_id) {\n spinner.info('No Beam identity configured for this agent.');\n return;\n }\n\n spinner.succeed('Beam configuration found');\n const cfg = data.config;\n\n if (json) {\n jsonOutput(cfg);\n return;\n }\n\n console.log();\n table(\n ['Field', 'Value'],\n [\n ['Beam ID', chalk.cyan(String(cfg.beam_id))],\n ['DID', chalk.dim(String(cfg.did ?? '—'))],\n ['Public Key', chalk.dim(String(cfg.public_key ?? '').slice(0, 24) + '…')],\n ['Trust Score', String(cfg.trust_score ?? 0)],\n ['Verification', String(cfg.verification_tier ?? 'basic')],\n ['Auto-publish', cfg.auto_publish_capabilities ? chalk.green('yes') : chalk.dim('no')],\n ['Capabilities', Array.isArray(cfg.published_capabilities) && cfg.published_capabilities.length > 0\n ? cfg.published_capabilities.join(', ')\n : chalk.dim('none')],\n ['Status', data.status ?? '—'],\n ],\n );\n console.log();\n } catch (err) {\n spinner.fail('Failed to fetch config');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels beam remove <agent-code-name>`\n */\nexport async function channelBeamRemoveCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!json) {\n const proceed = await confirm({\n message: `Remove Beam identity from \"${agentCodeName}\"? The directory entry will expire.`,\n default: false,\n });\n if (!proceed) return;\n }\n\n const spinner = ora({ text: 'Removing Beam identity…', isSilent: json });\n spinner.start();\n\n try {\n await api.del(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`);\n spinner.succeed('Beam identity removed');\n\n if (json) {\n jsonOutput({ ok: true });\n }\n } catch (err) {\n spinner.fail('Failed to remove');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { select, input } from '@inquirer/prompts';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n DEPLOYMENT_TEMPLATES,\n getTemplate,\n renderTemplate,\n type TemplateContext,\n type TemplateAgent,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface DeployOptions {\n template?: string;\n port?: string;\n}\n\n/**\n * `agt deploy`\n */\nexport async function deployCommand(opts: DeployOptions): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const nonInteractive = !!opts.template;\n const json = isJsonMode();\n\n let templateId: string;\n let basePort: number;\n\n if (nonInteractive) {\n templateId = opts.template!;\n basePort = Number(opts.port ?? '9000');\n if (isNaN(basePort) || basePort < 1 || basePort > 65535) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid port number' });\n } else {\n error('Invalid port number. Must be between 1 and 65535.');\n }\n process.exitCode = 1;\n return;\n }\n } else {\n console.log(chalk.bold('\\nAugmented — Deploy\\n'));\n\n templateId = await select({\n message: 'Deployment template:',\n choices: DEPLOYMENT_TEMPLATES.map((t) => ({\n value: t.id,\n name: `${t.name} — ${t.description}`,\n })),\n });\n\n const basePortStr = await input({\n message: 'Base port for gateway:',\n default: '9000',\n validate: (v) => {\n const n = Number(v);\n return (!isNaN(n) && n > 0 && n < 65536) || 'Must be a valid port number';\n },\n });\n basePort = Number(basePortStr);\n }\n\n const tmpl = getTemplate(templateId);\n if (!tmpl) {\n if (json) {\n jsonOutput({ ok: false, error: `Template \"${templateId}\" not found` });\n } else {\n error(`Template \"${templateId}\" not found.`);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Fetch agents via API ──────────────────────────────────────────────\n\n const spinner = ora({ text: 'Fetching agents…', isSilent: json });\n spinner.start();\n\n let agents: Array<{\n agent_id: string;\n code_name: string;\n display_name: string;\n environment: string;\n }>;\n\n try {\n const data = await api.get<{ agents: typeof agents }>('/agents');\n agents = data.agents;\n } catch (err) {\n spinner.fail('Failed to fetch agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n if (!agents || agents.length === 0) {\n spinner.fail('No agents found in team.');\n if (json) {\n jsonOutput({ ok: false, error: 'No agents found in team. Run `agt init` first.' });\n } else {\n error('No agents found in team. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Build template context ────────────────────────────────────────────\n\n const templateAgents: TemplateAgent[] = agents.map((a, i) => ({\n agent_id: a.agent_id,\n code_name: a.code_name,\n display_name: a.display_name,\n environment: a.environment,\n port: basePort + i,\n }));\n\n const context: TemplateContext = {\n agents: templateAgents,\n gateway: { port: basePort },\n variables: {},\n };\n\n let rendered: string;\n try {\n rendered = renderTemplate(tmpl.template, context);\n } catch (err) {\n spinner.fail('Template rendering failed.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Record deployment via API ─────────────────────────────────────────\n\n try {\n await api.post('/deployments', {\n template_id: tmpl.id,\n agent_ids: agents.map((a) => a.agent_id),\n variables: { base_port: basePort },\n });\n } catch (deployErr) {\n spinner.stop();\n if (!json) info(`Warning: could not record deployment in database: ${(deployErr as Error).message}`);\n }\n\n // ── Write output file ─────────────────────────────────────────────────\n\n const outDir = join(process.cwd(), '.augmented', 'deploy');\n mkdirSync(outDir, { recursive: true });\n const outPath = join(outDir, 'docker-compose.yaml');\n writeFileSync(outPath, rendered);\n\n spinner.succeed('Deployment config generated.');\n\n if (json) {\n jsonOutput({\n ok: true,\n template: tmpl.id,\n agents: agents.map((a) => a.code_name),\n output_path: outPath,\n });\n return;\n }\n\n console.log();\n info(`Template: ${chalk.bold(tmpl.name)}`);\n info(`Agents: ${agents.map((a) => a.code_name).join(', ')}`);\n info(`Output: ${outPath}`);\n console.log();\n info(`Next steps:`);\n info(` cd .augmented/deploy && docker compose up`);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n extractFrontmatter,\n resolveChannels,\n lintAll,\n getFramework,\n getTemplate,\n renderTemplate,\n type CharterFrontmatter,\n type ToolsFrontmatter,\n type ChannelId,\n type ChannelPolicy,\n type OrgChannelPolicy,\n type DeploymentTarget,\n type LintDiagnostic,\n type ProvisionInput,\n type TemplateContext,\n} from '@augmented/core';\nimport { provision } from '@augmented/core/provisioning/provisioner.js';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} [${d.code}] ${d.message}${path}`);\n }\n}\n\n/**\n * `agt provision <code-name>`\n */\nexport async function provisionCommand(\n codeName: string,\n options: { target?: string; output?: string; dryRun?: boolean },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const target = (options.target ?? 'local_docker') as DeploymentTarget;\n const outputDir = options.output ?? join(process.cwd(), '.augmented', codeName, 'provision');\n const dryRun = options.dryRun ?? false;\n\n if (!json) console.log(chalk.bold('\\nAugmented — Provision\\n'));\n\n const spinner = ora({ text: 'Fetching agent data…', isSilent: json });\n spinner.start();\n\n // ── Fetch all provision data in one call ──────────────────────────────\n\n let provisionData: {\n agent: Record<string, unknown>;\n charter: { raw_content: string; version: string } | null;\n tools: { raw_content: string; version: string } | null;\n channel_configs: Record<string, { config: unknown; status: string }> | null;\n team_channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n };\n\n try {\n provisionData = await api.get(`/agents/${encodeURIComponent(codeName)}/provision-data`);\n } catch (err) {\n spinner.fail(`Could not fetch provision data for \"${codeName}\".`);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const agentData = provisionData.agent;\n\n if (!provisionData.charter) {\n spinner.fail('No CHARTER.md version found.');\n if (json) jsonOutput({ ok: false, error: 'No CHARTER.md version found' });\n else error('No CHARTER.md version found for this agent');\n process.exitCode = 1;\n return;\n }\n\n if (!provisionData.tools) {\n spinner.fail('No TOOLS.md version found.');\n if (json) jsonOutput({ ok: false, error: 'No TOOLS.md version found' });\n else error('No TOOLS.md version found for this agent');\n process.exitCode = 1;\n return;\n }\n\n spinner.text = 'Parsing frontmatter…';\n\n const charterContent = provisionData.charter.raw_content;\n const toolsContent = provisionData.tools.raw_content;\n\n const charterParsed = extractFrontmatter(charterContent);\n if (!charterParsed.frontmatter) {\n spinner.fail('Failed to parse CHARTER.md frontmatter.');\n if (json) jsonOutput({ ok: false, error: charterParsed.error ?? 'Unknown parse error' });\n else error(charterParsed.error ?? 'Unknown parse error');\n process.exitCode = 1;\n return;\n }\n\n const toolsParsed = extractFrontmatter(toolsContent);\n if (!toolsParsed.frontmatter) {\n spinner.fail('Failed to parse TOOLS.md frontmatter.');\n if (json) jsonOutput({ ok: false, error: toolsParsed.error ?? 'Unknown parse error' });\n else error(toolsParsed.error ?? 'Unknown parse error');\n process.exitCode = 1;\n return;\n }\n\n const charterFrontmatter = charterParsed.frontmatter as unknown as CharterFrontmatter;\n const toolsFrontmatter = toolsParsed.frontmatter as unknown as ToolsFrontmatter;\n\n // ── Lint ───────────────────────────────────────────────────────────────\n\n spinner.text = 'Linting…';\n const lintResult = lintAll(charterContent, toolsContent);\n\n if (!lintResult.ok) {\n spinner.fail('Lint errors — cannot provision.');\n if (json) {\n jsonOutput({\n ok: false,\n error: 'Lint errors — cannot provision',\n lint: {\n errors: lintResult.errors.length,\n warnings: lintResult.warnings.length,\n diagnostics: [...lintResult.errors, ...lintResult.warnings],\n },\n });\n } else {\n printDiagnostics(lintResult.errors);\n if (lintResult.warnings.length > 0) printDiagnostics(lintResult.warnings);\n }\n process.exitCode = 1;\n return;\n }\n\n if (lintResult.warnings.length > 0 && !json) {\n spinner.stop();\n warn(`Lint: ${lintResult.warnings.length} warning(s)`);\n printDiagnostics(lintResult.warnings);\n spinner.start('Provisioning…');\n }\n\n // ── Resolve channels ──────────────────────────────────────────────────\n\n spinner.text = 'Resolving channels…';\n\n // Derive channels from agent_channel_configs (source of truth)\n const configuredChannels = Object.keys(provisionData.channel_configs ?? {}) as ChannelId[];\n\n const agentChannelPolicy: ChannelPolicy = {\n policy: 'allowlist',\n allowed: configuredChannels,\n denied: [],\n require_approval_to_change: true,\n };\n\n let orgChannelPolicy: OrgChannelPolicy | undefined;\n const policyData = provisionData.team_channel_policy;\n\n if (policyData) {\n orgChannelPolicy = {\n organization_id: policyData.team_id,\n allowed_channels: (policyData.allowed_channels ?? []) as ChannelId[],\n denied_channels: (policyData.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: policyData.require_elevated_for_pii ?? false,\n };\n }\n\n const resolvedChannels = resolveChannels(agentChannelPolicy, orgChannelPolicy);\n\n // ── Fetch integrations ────────────────────────────────────────────────\n //\n // ENG-5923: the provision input previously omitted integrations entirely,\n // so `buildMcpJson` defaulted `input.integrations ?? []` and the rendered\n // `.mcp.json` lost every Composio + native (granola, postiz, xero, …) MCP\n // server. Re-provisioning an agent wiped its `.mcp.json` down to the\n // `augmented` server + channel-credential entries. Fetch the decrypted,\n // scope-resolved integrations from the same host endpoint manager-worker\n // uses — credentials are decrypted server-side, so hosts never see\n // ciphertext — and pass them through so the renderer has the full picture.\n\n spinner.text = 'Fetching integrations…';\n\n const agentId = agentData.agent_id as string;\n let integrations: NonNullable<ProvisionInput['integrations']> = [];\n let integrationsError: string | null = null;\n try {\n const integrationsData = await api.post<{\n integrations: Array<{\n id: string;\n definition_id: string;\n display_name: string;\n scope: string;\n auth_type: string;\n credentials: Record<string, unknown>;\n config: Record<string, unknown>;\n capabilities: Array<{ id: string; name: string; description: string; access: string }>;\n }>;\n }>('/host/agent-integrations', { agent_id: agentId });\n integrations = (integrationsData.integrations ??\n []) as NonNullable<ProvisionInput['integrations']>;\n } catch (err) {\n // Don't silently strip integrations — that's the exact regression this\n // ticket fixes. An agent with zero integrations returns an empty list\n // (not an error), so only a genuine fetch failure lands here. Surface it\n // loudly and continue rather than writing a stripped `.mcp.json`.\n integrationsError = (err as Error).message;\n if (!json) {\n spinner.stop();\n warn(\n `Could not fetch integrations: ${integrationsError}. ` +\n '.mcp.json may be missing integration servers.',\n );\n spinner.start('Provisioning…');\n }\n }\n\n // ── Provision ─────────────────────────────────────────────────────────\n\n const frameworkId = (agentData.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n\n spinner.text = `Building ${adapter.label} config…`;\n\n const provisionInput: ProvisionInput = {\n agent: agentData as any,\n charterFrontmatter,\n charterContent,\n toolsFrontmatter,\n toolsContent,\n resolvedChannels,\n integrations,\n deploymentTarget: target,\n gatewayPort: 9000,\n };\n\n const provisionOutput = provision(provisionInput, frameworkId);\n\n const templateId = target === 'local_docker' ? 'shared-gateway-local' : 'shared-gateway-local';\n const tmpl = getTemplate(templateId);\n let deploymentYaml = '';\n if (tmpl) {\n const templateContext: TemplateContext = {\n agents: [{\n agent_id: agentData.agent_id as string,\n code_name: agentData.code_name as string,\n display_name: agentData.display_name as string,\n environment: agentData.environment as string,\n port: 9000,\n }],\n gateway: { port: 9000 },\n variables: {},\n };\n deploymentYaml = renderTemplate(tmpl.template, templateContext);\n }\n\n // ── Dry run ───────────────────────────────────────────────────────────\n\n if (dryRun) {\n spinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n dry_run: true,\n agent: codeName,\n framework: frameworkId,\n target,\n charter_hash: provisionOutput.charterHash,\n tools_hash: provisionOutput.toolsHash,\n channels: resolvedChannels.length,\n integrations: integrations.length,\n integrations_error: integrationsError,\n artifacts: provisionOutput.artifacts.map((a) => ({\n path: a.relativePath,\n size: a.content.length,\n })),\n deployment_yaml: deploymentYaml || null,\n });\n return;\n }\n\n console.log();\n info('Dry run — no files written.');\n console.log();\n for (const artifact of provisionOutput.artifacts) {\n console.log(chalk.bold(`${artifact.relativePath}:`));\n console.log(artifact.content);\n }\n if (deploymentYaml) {\n console.log(chalk.bold('Deployment Template:'));\n console.log(deploymentYaml);\n }\n console.log();\n info(`CHARTER hash: ${provisionOutput.charterHash}`);\n info(`TOOLS hash: ${provisionOutput.toolsHash}`);\n return;\n }\n\n // ── Write files ───────────────────────────────────────────────────────\n\n spinner.text = 'Writing files…';\n\n mkdirSync(outputDir, { recursive: true });\n for (const artifact of provisionOutput.artifacts) {\n writeFileSync(join(outputDir, artifact.relativePath), artifact.content);\n }\n if (deploymentYaml) {\n writeFileSync(join(outputDir, 'docker-compose.yaml'), deploymentYaml);\n }\n\n // ── Store provision snapshot via API ───────────────────────────────────\n\n spinner.text = 'Storing provision snapshot…';\n\n try {\n await api.post(`/agents/${encodeURIComponent(codeName)}/provision-snapshots`, {\n charter_version: provisionData.charter.version,\n tools_version: provisionData.tools.version,\n charter_content: charterContent,\n tools_content: toolsContent,\n channels: resolvedChannels,\n });\n } catch (err) {\n spinner.stop();\n if (!json) warn(`Provision completed but could not store snapshot: ${(err as Error).message}`);\n }\n\n // ── Summary ───────────────────────────────────────────────────────────\n\n spinner.succeed(`Agent \"${chalk.bold(agentData.display_name as string)}\" provisioned.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: codeName,\n framework: frameworkId,\n target,\n output_dir: outputDir,\n charter_hash: provisionOutput.charterHash,\n tools_hash: provisionOutput.toolsHash,\n channels: resolvedChannels.length,\n integrations: integrations.length,\n integrations_error: integrationsError,\n artifacts: provisionOutput.artifacts.map((a) => a.relativePath),\n });\n return;\n }\n\n console.log();\n info(`Agent: ${agentData.code_name}`);\n info(`Framework: ${adapter.label}`);\n info(`Target: ${target}`);\n info(`Output: ${outputDir}`);\n info(`CHARTER hash: ${provisionOutput.charterHash.slice(0, 12)}…`);\n info(`TOOLS hash: ${provisionOutput.toolsHash.slice(0, 12)}…`);\n info(`Channels: ${resolvedChannels.length} active`);\n info(`Integrations: ${integrations.length}${integrationsError ? ' (fetch failed)' : ''}`);\n info(`Artifacts: ${provisionOutput.artifacts.map((a) => a.relativePath).join(', ')}`);\n console.log();\n info('Next steps:');\n info(` cd ${outputDir} && docker compose up`);\n info(` agt drift check ${agentData.code_name}`);\n}\n","/**\n * ENG-5688 (redesigned) — `agt impersonate {connect|current|exit}`.\n *\n * The CLI side of the operator-impersonates-agent v0 flow. The operator\n * gets a short redeem token (XXXX-XXXX) from the webapp (ENG-5702's\n * \"Impersonate this agent\" button) and pastes:\n *\n * agt impersonate connect XXXX-XXXX\n *\n * The CLI:\n * 1. Validates the token shape; refuses obvious garbage before any\n * server round-trip.\n * 2. POSTs the token to the API's PUBLIC /impersonate/agent/redeem\n * endpoint (ENG-5701, amended by this PR to use short-token\n * credentials) — no Authorization, no X-Team-Slug. The token IS\n * the credential, so this works in a clean shell with no\n * `AGT_API_KEY` set (ENG-5688 AC4).\n * 3. Receives the bundle:\n * { token, expires_at, session_id, agent { id, code_name, team_id },\n * artifacts: { \"CLAUDE.md\", \".mcp.json\" } }\n * 4. Writes the persona files to ~/.augmented-impersonate/<code-name>/\n * 5. Backs up the operator's existing project files and symlinks the\n * persona files in (preserves CR-feedback invariants on atomicity,\n * strict root check, and refused symlinks — see ../lib/impersonate-fs-ops.ts).\n * 6. Stashes the manifest atomically with the host the token was\n * exchanged against so `exit` calls /stop on the right environment.\n * 7. Prints agent details + restart-Claude-Code prompt.\n *\n * `agt impersonate current` reads the active manifest; `agt impersonate\n * exit` writes the stop audit row, restores backups, and clears the\n * manifest.\n *\n * Gated behind AGT_IMPERSONATE_ENABLED (see ../lib/impersonate-flag.ts)\n * until the surrounding pieces (ENG-5689 channel-MCP refusal, ENG-5702\n * webapp button) land and the end-to-end smoke test runs against prod.\n */\n\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { spawn } from 'node:child_process';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { delimiter, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { ApiError, api } from '../lib/api-client.js';\nimport { PROD_AGT_HOST } from '../lib/config.js';\nimport { error, info, success } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { requireImpersonateEnabled } from '../lib/impersonate-flag.js';\nimport {\n clearActiveManifest,\n ensureCodeNameDir,\n ensureImpersonateWorkdir,\n isExpired,\n listActiveManifests,\n readActiveManifest,\n writeActiveManifest,\n type BackupKind,\n type HookBackup,\n type ImpersonateManifest,\n type StatusLineBackup,\n} from '../lib/impersonate-state.js';\nimport {\n findGitWorkTreeRoot,\n restoreSwapped,\n swapInPersonaFile,\n} from '../lib/impersonate-fs-ops.js';\nimport {\n registerIntroduceHook,\n unregisterIntroduceHook,\n} from '../lib/impersonate-hook.js';\nimport {\n registerStatusLine,\n unregisterStatusLine,\n} from '../lib/impersonate-statusline.js';\nimport {\n buildIntroduction,\n parseIdentityFromClaudeMd,\n parseIntegrationsFromMcpJson,\n type ParsedIdentity,\n} from '../lib/impersonate-introduce.js';\nimport { rewriteMcpJsonForImpersonation } from '../lib/impersonate-mcp-rewrite.js';\n\nconst SWAP_FILES = ['CLAUDE.md', '.mcp.json'] as const;\nconst AGENT_IMPERSONATION_HEADER = 'X-Agent-Impersonation';\n\n// ENG-5688 (+ amends ENG-5701): short-token redeem format. Mirrors\n// /host/setup's provisioning_tokens — two 4-char Crockford-style\n// alphanumeric segments joined by a hyphen, e.g. \"A3K7-NP5V\".\nconst REDEEM_TOKEN_RE = /^[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i;\n\n/** Server response from POST /impersonate/agent/redeem. */\ninterface RedeemBundle {\n token: string;\n /**\n * ENG-5874: the portable agent-session token the augmented MCP server uses\n * directly as Bearer. Absent on older servers / pre-org teams — treat as\n * optional and fall back to the legacy host-key path when missing.\n */\n agent_session_token?: string | null;\n expires_at: number;\n session_id: string;\n agent: { agent_id: string; code_name: string; team_id: string };\n artifacts: { 'CLAUDE.md': string; '.mcp.json': string };\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate connect <token>`\n// ---------------------------------------------------------------------------\n\n/**\n * Options for the connect command.\n *\n * `noLaunch` defaults to `false` — connect spawns Claude Code in the\n * impersonation project directory after a successful swap. Operators\n * opt out with `--no-launch` (useful for scripting, smoke tests, or\n * when they want to manage their own Claude session).\n *\n * ENG-5747.\n */\nexport interface ImpersonateConnectOptions {\n noLaunch?: boolean;\n /**\n * ENG-5756 (AC3): swap into an auto-provisioned dedicated directory\n * (`~/.augmented-impersonate/<code-name>/workdir`) rather than the\n * operator's current directory. Makes a repo clobber structurally\n * impossible — the swap never touches cwd. Also the escape hatch the\n * git-work-tree guard points operators at.\n */\n workdir?: boolean;\n /**\n * Override the API host used to redeem the token. When unset, impersonate\n * always hits the production API (`api.augmented.team`) regardless of\n * `AGT_HOST` — operators routinely point AGT_HOST at a local/Tailscale\n * dev API for day-to-day CLI work, but redeem tokens are minted against\n * prod almost every time. Pin the default to prod and require an explicit\n * `--api-host` to deviate.\n */\n apiHost?: string;\n}\n\nexport async function impersonateConnectCommand(\n token: string,\n options: ImpersonateConnectOptions = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n // In JSON mode we never launch Claude Code — the caller is a script\n // that needs the structured exit, not an interactive shell. This is\n // independent of --no-launch (which is the explicit operator opt-out).\n const shouldLaunchClaude = !options.noLaunch && !json;\n\n // ENG-5688: validate token shape up-front (XXXX-XXXX) so we refuse\n // obvious garbage before a server round-trip. Server does the\n // authoritative validation against impersonation_setup_tokens.\n if (!REDEEM_TOKEN_RE.test(token)) {\n const msg =\n 'Token is not in the expected XXXX-XXXX format. ' +\n 'Copy the full `agt impersonate connect <token>` command from the webapp.';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // ── Guard: refuse a second session for the SAME target directory ──────\n //\n // ENG-5967: impersonation state is keyed per project directory, so\n // different directories (e.g. two separate terminals, each in its own\n // dedicated dir) run concurrently. We only refuse re-connecting a\n // directory that already has an active session. In the default mode the\n // target is process.cwd(), known up-front — check it here so a duplicate\n // refuses BEFORE the single-use redeem token is spent. In `--workdir`\n // mode the target depends on the agent code_name (resolved post-redeem),\n // so that case is guarded again just before the swap (see below).\n if (!options.workdir) {\n const existing = readActiveManifest(process.cwd());\n if (existing) {\n const msg =\n `An impersonation session is already active in this directory (${existing.code_name}). ` +\n `Run \\`agt impersonate exit\\` here first, or connect from a different directory.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n }\n\n // ── Guard: never swap persona files inside a git working tree ─────────\n //\n // ENG-5756: the swap (below) symlinks the agent's CLAUDE.md/.mcp.json\n // into the swap target. In the default mode that target is\n // process.cwd(); if that's inside a git work tree, the swap overwrites\n // the repo's OWN CLAUDE.md/.mcp.json with symlinks — git sees a\n // type-change and a stray `git commit -a` could capture them,\n // corrupting the repo. Impersonation is designed for a standalone /\n // scratch directory, so refuse here — crucially BEFORE the redeem\n // round-trip, so the single-use token isn't spent and no files are\n // touched — and point the operator at `--workdir` or a clean dir.\n //\n // `--workdir` opts into an auto-provisioned dedicated directory under\n // ~/.augmented-impersonate/ (resolved after redeem, once we know the\n // code_name), so cwd is never touched and this guard doesn't apply.\n if (!options.workdir) {\n const workTreeRoot = findGitWorkTreeRoot(process.cwd());\n if (workTreeRoot) {\n const msg =\n `Refusing to impersonate inside a git working tree (${workTreeRoot}). ` +\n `connect swaps the agent's ${SWAP_FILES.join(' + ')} into the current ` +\n `directory, which would overwrite the repo's own files. Re-run with ` +\n `\\`--workdir\\` to use an auto-provisioned dedicated directory, or run ` +\n `from a standalone empty directory.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n }\n\n if (!json) console.log(chalk.bold('\\nAugmented — Impersonate\\n'));\n // The token is opaque (no embedded agent name to display, unlike the\n // old JWT shape) so the spinner message is generic. The success\n // message will show the real agent name from the bundle.\n const spinner = ora({\n text: 'Redeeming token…',\n isSilent: json,\n });\n spinner.start();\n\n // ── Call /redeem WITHOUT auth ────────────────────────────────────────\n //\n // This is the heart of AC4: the redeem token IS the credential, and\n // the server endpoint is PUBLIC. We use plain fetch() (not api.post)\n // because api.post triggers AGT_API_KEY discovery + exchange — which\n // would fail in a clean shell, and which we deliberately don't want\n // to need.\n // Pin to prod by default — see ImpersonateConnectOptions.apiHost.\n const host = (options.apiHost ?? PROD_AGT_HOST).replace(/\\/+$/, '');\n let bundle: RedeemBundle;\n try {\n const res = await fetch(`${host}/impersonate/agent/redeem`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ redeem_token: token }),\n });\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const detail = (body['error'] as string) ?? `HTTP ${res.status}`;\n throw new Error(`${detail} (HTTP ${res.status})`);\n }\n bundle = (await res.json()) as RedeemBundle;\n } catch (err) {\n spinner.fail('Failed to redeem token.');\n const msg = err instanceof Error ? err.message : String(err);\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // ── Write persona files to ~/.augmented-impersonate/<code-name>/ ─────\n spinner.text = 'Writing persona files…';\n const personaDir = ensureCodeNameDir(bundle.agent.code_name);\n writeFileSync(\n join(personaDir, 'CLAUDE.md'),\n bundle.artifacts['CLAUDE.md'],\n );\n // ENG-5812: the server-rendered .mcp.json is shaped for the agent's\n // Lambda/Docker runtime (paths under `/home/sbx_user1051/.augmented/_mcp/`\n // and empty AGT_HOST / AGT_API_KEY / HOME). Rewrite it so the\n // operator's local Claude Code can actually spawn the MCP servers\n // — substitute Lambda paths for the CLI's own bundled `dist/mcp/`\n // and fill the env with operator-side values. See\n // ../lib/impersonate-mcp-rewrite.ts for the contract.\n writeFileSync(\n join(personaDir, '.mcp.json'),\n rewriteMcpJsonForImpersonation(bundle.artifacts['.mcp.json'], {\n operatorHome: process.env.HOME ?? '',\n operatorPath: resolveOperatorPath(),\n cliMcpBundleDir: resolveCliMcpBundleDir(),\n impersonationToken: bundle.token,\n agentSessionToken: bundle.agent_session_token ?? null,\n apiHost: host,\n agentId: bundle.agent.agent_id,\n agentCodeName: bundle.agent.code_name,\n }),\n );\n\n // ── Swap files + write manifest atomically ───────────────────────────\n //\n // CR #3321347793 from PR #1489: this whole step has to be atomic\n // from the operator's perspective. If we swap one file and then\n // the second swap or the manifest write fails, the project ends up\n // modified with no manifest to drive recovery from `exit`. Track\n // each successful swap and roll back on any failure.\n spinner.text = 'Swapping persona files…';\n // Default target is the operator's cwd (guarded above against git work\n // trees). `--workdir` instead provisions a dedicated agent-scoped dir\n // under ~/.augmented-impersonate/<code-name>/workdir so the swap can\n // never touch a repo (ENG-5756 AC3). Everything downstream — manifest\n // project_cwd, the spawn cwd, and `exit`'s restore target — keys off\n // this one value, so the rest of the flow is mode-agnostic.\n const projectCwd = options.workdir\n ? ensureImpersonateWorkdir(bundle.agent.code_name)\n : process.cwd();\n\n // ENG-5967: per-directory guard, second half. The default-mode guard up\n // top already ran against process.cwd(); this catches the `--workdir`\n // case, whose target dir is only known now (it's derived from the\n // code_name in the redeem bundle). Re-connecting the same agent's workdir\n // while a session is live would otherwise clobber its backup state.\n const existingForTarget = readActiveManifest(projectCwd);\n if (existingForTarget) {\n spinner.fail('Impersonation already active for this agent.');\n const msg =\n `An impersonation session is already active in ${projectCwd} (${existingForTarget.code_name}). ` +\n `Run \\`agt impersonate exit\\` there first.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n const backups: Record<string, BackupKind> = {};\n const swapped: Array<{ file: string; kind: BackupKind }> = [];\n // ENG-5750: track the introduce hook so the catch below can roll it\n // back alongside the file swaps if the manifest write fails.\n let hookBackup: HookBackup | undefined;\n let statusLineBackup: StatusLineBackup | undefined;\n\n try {\n for (const file of SWAP_FILES) {\n const projectPath = join(projectCwd, file);\n const kind = swapInPersonaFile(projectPath, join(personaDir, file));\n backups[file] = kind;\n swapped.push({ file, kind });\n }\n\n // ENG-5750: register the SessionStart \"introduce yourself\" hook in\n // the project dir so the fresh Claude Code session opens with the\n // agent introducing itself + its integrations. Folded into the\n // manifest so `exit` removes it and leaves the cwd clean.\n hookBackup = registerIntroduceHook(projectCwd);\n\n // ENG-5801: register the project-scoped statusLine so the operator's\n // Claude Code session shows a 🤖 <agent-name> badge while they're in\n // this project. Backup folded into the manifest so `exit` reverses it\n // byte-for-byte. Shares the same settings.local.json backup file as\n // the introduce hook — whichever register ran first captured the\n // operator's true original.\n statusLineBackup = registerStatusLine(projectCwd);\n\n const manifest: ImpersonateManifest = {\n code_name: bundle.agent.code_name,\n agent_id: bundle.agent.agent_id,\n team_id: bundle.agent.team_id,\n token: bundle.token,\n expires_at: bundle.expires_at,\n session_id: bundle.session_id,\n minted_at: new Date().toISOString(),\n project_cwd: projectCwd,\n host,\n backups,\n hook: hookBackup,\n statusLine: statusLineBackup,\n };\n writeActiveManifest(manifest);\n } catch (err) {\n if (statusLineBackup) {\n try {\n unregisterStatusLine(statusLineBackup);\n } catch {\n // Best-effort; the original error is what matters.\n }\n }\n if (hookBackup) {\n try {\n unregisterIntroduceHook(hookBackup);\n } catch {\n // Best-effort; the original error is what matters.\n }\n }\n for (const { file, kind } of [...swapped].reverse()) {\n try {\n restoreSwapped(join(projectCwd, file), kind);\n } catch {\n // Swallow rollback-of-rollback failures — the original error\n // is what the operator needs to see.\n }\n }\n spinner.fail('Failed to enter impersonation; rolled back changes.');\n throw err;\n }\n\n spinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n code_name: bundle.agent.code_name,\n agent_id: bundle.agent.agent_id,\n session_id: bundle.session_id,\n expires_at: bundle.expires_at,\n project_cwd: projectCwd,\n host,\n swapped_files: SWAP_FILES,\n });\n return;\n }\n\n success(`Impersonating ${chalk.bold(bundle.agent.code_name)}`);\n console.log();\n console.log(` Agent ID: ${chalk.dim(bundle.agent.agent_id)}`);\n console.log(` Team: ${chalk.dim(bundle.agent.team_id)}`);\n console.log(` Session: ${chalk.dim(bundle.session_id)}`);\n console.log(\n ` Expires: ${chalk.dim(new Date(bundle.expires_at * 1000).toISOString())}`,\n );\n console.log(` Project: ${chalk.dim(projectCwd)}`);\n console.log(` Host: ${chalk.dim(host)}`);\n console.log(` Swapped: ${chalk.dim(SWAP_FILES.join(', '))}`);\n console.log();\n if (!shouldLaunchClaude) {\n // --no-launch (or JSON mode, but the JSON branch already returned\n // above). Operator drove their own session start; keep the original\n // copy so they know they have to restart Claude themselves.\n if (options.workdir) {\n // The persona was swapped into the dedicated workdir, not the\n // operator's cwd — tell them where to start their session.\n info(`Start Claude Code in the impersonation workdir: \\`cd ${projectCwd}\\``);\n }\n info(\n \"Restart Claude Code to pick up the agent's persona + MCP server set. \" +\n 'Claude Code 2.1.152 does not honour `tools/list_changed` in-session ' +\n '(spike PoC, ENG-4733).',\n );\n console.log();\n info('When done: `agt impersonate exit`');\n return;\n }\n\n // ── Hand off to Claude Code ──────────────────────────────────────────\n //\n // Spawn `claude` in the impersonation project dir with the parent's\n // stdio so the operator immediately enters an interactive session\n // (foreground replace from their perspective; we wait on the child\n // and mirror its exit code so shells and scripts behave naturally).\n //\n // We deliberately call `claude` via PATH lookup — no config knob in\n // v1, no AGT_CLAUDE_BIN override. Revisit if multiple installs become\n // common; until then keep the contract simple.\n //\n // ENOENT (claude not on PATH) falls back to the manual-restart copy\n // + non-zero exit so the operator knows the auto-launch didn't fire\n // and what to do instead. Anything else surfaces verbatim.\n info('Launching Claude Code… (use `--no-launch` next time to skip)');\n console.log();\n\n const launch = buildImpersonateClaudeLaunch(\n projectCwd,\n process.env,\n bundle.agent.agent_id,\n );\n\n await new Promise<void>((resolve) => {\n const child = spawn('claude', launch.args, {\n stdio: 'inherit',\n cwd: projectCwd,\n env: launch.env,\n });\n child.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'ENOENT') {\n error(\n '`claude` binary not found on PATH. Start Claude Code yourself ' +\n `from ${projectCwd}, or install the CLI from claude.ai/code.`,\n );\n process.exitCode = 1;\n } else {\n error(`Failed to launch Claude Code: ${err.message}`);\n process.exitCode = 1;\n }\n resolve();\n });\n child.on('exit', (code, signal) => {\n // Mirror the child's exit so the operator's shell sees the right\n // status. A signal exit (e.g. operator hit Ctrl-C in Claude) is\n // reported the conventional way (128 + signum is overkill here;\n // Node's process.exitCode = null on signal is fine — the parent\n // already inherited the SIGINT and is being torn down anyway).\n if (code !== null && code !== 0) process.exitCode = code;\n if (signal) process.exitCode = 130; // standard SIGINT semantics\n resolve();\n });\n });\n\n // The impersonation manifest still lives — `agt impersonate exit`\n // will tear it down. Remind the operator on the way out so they don't\n // forget; without it, the persona files stay swapped indefinitely.\n console.log();\n info('When done: `agt impersonate exit` (still active).');\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate current`\n// ---------------------------------------------------------------------------\n\n/** Render one manifest as the human-readable block `current` prints. */\nfunction printManifestText(manifest: ImpersonateManifest): void {\n const expired = isExpired(manifest);\n console.log();\n console.log(chalk.bold(`Impersonating: ${manifest.code_name}`));\n console.log(` Agent ID: ${chalk.dim(manifest.agent_id)}`);\n console.log(` Team: ${chalk.dim(manifest.team_id)}`);\n console.log(` Session: ${chalk.dim(manifest.session_id)}`);\n console.log(` Minted at: ${chalk.dim(manifest.minted_at)}`);\n console.log(\n ` Expires at: ${chalk.dim(new Date(manifest.expires_at * 1000).toISOString())} ` +\n (expired ? chalk.red('(EXPIRED — run `agt impersonate exit`)') : ''),\n );\n console.log(` Project: ${chalk.dim(manifest.project_cwd)}`);\n console.log(` Host: ${chalk.dim(manifest.host)}`);\n console.log();\n}\n\n/** Shape one manifest into the JSON `current` emits. */\nfunction manifestToJson(manifest: ImpersonateManifest) {\n return {\n code_name: manifest.code_name,\n agent_id: manifest.agent_id,\n team_id: manifest.team_id,\n session_id: manifest.session_id,\n minted_at: manifest.minted_at,\n expires_at: manifest.expires_at,\n expired: isExpired(manifest),\n project_cwd: manifest.project_cwd,\n host: manifest.host,\n };\n}\n\nexport async function impersonateCurrentCommand(\n opts: { all?: boolean } = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n\n // ENG-5967: `--all` reports every active session on the machine; the\n // default reports the session for the current directory (with a hint\n // when others are running elsewhere).\n if (opts.all) {\n const manifests = listActiveManifests();\n if (json) {\n jsonOutput({ ok: true, active: manifests.map(manifestToJson) });\n return;\n }\n if (manifests.length === 0) {\n info('No active impersonations.');\n return;\n }\n console.log();\n console.log(chalk.bold(`Active impersonations (${manifests.length}):`));\n for (const m of manifests) printManifestText(m);\n return;\n }\n\n const manifest = readActiveManifest(process.cwd());\n if (!manifest) {\n const others = listActiveManifests();\n if (json) {\n jsonOutput({ ok: true, active: null, others_active: others.length });\n return;\n }\n if (others.length > 0) {\n info(\n `No active impersonation in this directory — ${others.length} active elsewhere. ` +\n 'Run `agt impersonate current --all` to list them.',\n );\n } else {\n info('No active impersonation.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, active: manifestToJson(manifest) });\n return;\n }\n printManifestText(manifest);\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate exit`\n// ---------------------------------------------------------------------------\n\nexport async function impersonateExitCommand(\n opts: { all?: boolean } = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n\n // ENG-5967: `--all` tears down every active session on the machine; the\n // default exits only the session for the current directory, leaving any\n // concurrent sessions in other directories untouched.\n if (opts.all) {\n const manifests = listActiveManifests();\n if (manifests.length === 0) {\n if (json) jsonOutput({ ok: true, was_active: false, exited: [] });\n else info('No active impersonation to exit.');\n return;\n }\n const exited: string[] = [];\n for (const manifest of manifests) {\n // Silent per-session so a single combined result is emitted below\n // instead of N interleaved blocks (and JSON stays one object).\n await performImpersonateExit(manifest, { json, silent: true });\n exited.push(manifest.code_name);\n }\n if (json) {\n jsonOutput({ ok: true, was_active: true, exited });\n } else {\n success(`Exited ${exited.length} impersonation session(s): ${exited.join(', ')}`);\n info('Restart Claude Code to pick up your original persona.');\n }\n return;\n }\n\n const manifest = readActiveManifest(process.cwd());\n if (!manifest) {\n if (json) jsonOutput({ ok: true, was_active: false });\n else info('No active impersonation to exit.');\n return;\n }\n\n await performImpersonateExit(manifest, { json, silent: false });\n}\n\n/**\n * ENG-5911 — the cleanup half of `exit`, factored out so it runs both from\n * the explicit `agt impersonate exit` command and from the lazy auto-exit\n * (autoExitExpiredImpersonation). Deliberately NOT gated on\n * requireImpersonateEnabled(): cleaning up a lingering session must always be\n * allowed, even from a shell where the impersonate flag isn't set. When\n * `silent` (the auto-exit path) it performs the same side effects but emits no\n * stdout result — so it can't corrupt a JSON command's output or spam an\n * unrelated command; the caller prints its own one-line stderr notice.\n */\nasync function performImpersonateExit(\n manifest: ImpersonateManifest,\n opts: { json: boolean; silent: boolean },\n): Promise<void> {\n const { json, silent } = opts;\n\n // ── Notify the server (best-effort) ───────────────────────────────────\n //\n // /stop currently requires Bearer auth too (ENG-5687); a follow-up will\n // let it accept JUST X-Agent-Impersonation. For v0, if AGT_API_KEY is\n // present we use api.post (which auto-attaches Bearer); if not, we go\n // direct via fetch — the server will likely reject, but local cleanup\n // proceeds either way and the token expires naturally.\n let stopOk = true;\n let stopDetail: string | null = null;\n try {\n if (process.env['AGT_API_KEY']) {\n await api.post('/impersonate/agent/stop', undefined, {\n [AGENT_IMPERSONATION_HEADER]: manifest.token,\n });\n } else {\n // Clean-shell fallback. Sends only X-Agent-Impersonation; the\n // server side will reject this in v0 (auth middleware demands\n // Bearer), but the operator's local cleanup is what matters here.\n const res = await fetch(`${manifest.host}/impersonate/agent/stop`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [AGENT_IMPERSONATION_HEADER]: manifest.token,\n },\n });\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const detail = (body['error'] as string) ?? `HTTP ${res.status}`;\n stopOk = false;\n stopDetail = `${detail} (HTTP ${res.status})`;\n }\n }\n } catch (err) {\n stopOk = false;\n stopDetail = err instanceof ApiError\n ? `${err.message} (HTTP ${err.status})`\n : err instanceof Error\n ? err.message\n : String(err);\n // Don't return — local cleanup still has to run.\n }\n\n // ── Restore the operator's project files ──────────────────────────────\n const restored: string[] = [];\n for (const [file, kind] of Object.entries(manifest.backups)) {\n const projectPath = join(manifest.project_cwd, file);\n try {\n restoreSwapped(projectPath, kind);\n restored.push(file);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to restore ${file}: ${msg}`);\n }\n }\n\n // ── Remove the project-scoped statusLine (ENG-5801) ───────────────────\n // Restores the operator's prior statusLine value byte-for-byte from the\n // backup, or removes the settings.local.json we created. Runs BEFORE\n // unregisterIntroduceHook because both touch the same backup file and\n // whichever runs first does the restore — running statusLine first\n // means a malformed-or-stripped fallback path is hit there, not here.\n // Older manifests have no `statusLine` field.\n if (manifest.statusLine) {\n try {\n unregisterStatusLine(manifest.statusLine);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to remove statusLine: ${msg}`);\n }\n\n // The statusline script renames the terminal tab to `🤖 <agent>` on\n // every refresh while impersonation is active. Now that it's gone,\n // emit a one-shot OSC 1 reset so the tab title falls back to the\n // terminal's default instead of staying stuck on the agent name\n // until the next process changes it. JSON-mode skips this — JSON\n // callers are scripts and a control sequence in the JSON stream\n // would corrupt the parse.\n if (!json && process.stdout.isTTY) {\n process.stdout.write('\\x1b]1;\\x07');\n }\n }\n\n // ── Remove the introduce SessionStart hook (ENG-5750) ─────────────────\n // Restores/removes .claude/settings.local.json so the operator's cwd\n // is left exactly as connect found it. Older manifests have no `hook`.\n if (manifest.hook) {\n try {\n unregisterIntroduceHook(manifest.hook);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to remove introduce hook: ${msg}`);\n }\n }\n\n clearActiveManifest(manifest.project_cwd);\n\n // Auto-exit path: side effects done, emit nothing (the caller prints a\n // one-line stderr notice; staying silent keeps unrelated/JSON command\n // output clean).\n if (silent) return;\n\n if (json) {\n jsonOutput({\n ok: true,\n was_active: true,\n session_id: manifest.session_id,\n stop_acknowledged: stopOk,\n stop_detail: stopDetail,\n restored,\n });\n return;\n }\n\n success(`Exited impersonation: ${manifest.code_name}`);\n if (restored.length > 0) {\n info(`Restored: ${restored.join(', ')}`);\n }\n if (!stopOk) {\n info(`Note: server-side stop not acknowledged (${stopDetail}). Token will expire naturally.`);\n }\n info('Restart Claude Code to pick up your original persona.');\n}\n\n/**\n * ENG-5911 — lazy auto-exit. Called from the CLI pre-action hook before\n * (almost) every command: if an impersonation session is active AND its token\n * has expired, run the same cleanup `agt impersonate exit` would — restore the\n * operator's files, post the stop audit (best-effort), clear the manifest — so\n * a dead session never has to be exited by hand. Cheap no-op when nothing is\n * active or the session is still valid; never throws into the caller's command.\n *\n * Skipped by the hook for `impersonate introduce` (the SessionStart hook —\n * must never restore files mid-boot) and `impersonate exit` (redundant).\n * Revocation (ENG-5875) will widen the \"should auto-exit\" predicate beyond\n * pure expiry, reusing performImpersonateExit unchanged.\n */\nexport async function autoExitExpiredImpersonation(): Promise<void> {\n // ENG-5967: state is keyed per directory and sessions can run\n // concurrently, so sweep ALL of them and clean up every expired one —\n // not just whichever the old singleton happened to hold. Cheap when\n // nothing is active (empty list) and never throws into the caller.\n let manifests: ImpersonateManifest[];\n try {\n manifests = listActiveManifests();\n } catch {\n return;\n }\n const expired = manifests.filter((m) => isExpired(m));\n if (expired.length === 0) return;\n for (const manifest of expired) {\n try {\n if (!isJsonMode()) {\n // Notice goes to STDERR (not info()'s stdout) so it can't pollute the\n // stdout of the unrelated command this auto-exit is piggybacking on\n // (e.g. `agt whoami | grep`). Same info styling, different stream.\n console.error(\n chalk.cyan(\n `ℹ Impersonation session for ${manifest.code_name} expired — auto-exiting and restoring your files.`,\n ),\n );\n }\n await performImpersonateExit(manifest, { json: isJsonMode(), silent: true });\n } catch {\n // Auto-exit is best-effort; never break the operator's actual command.\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate introduce` (hidden) — SessionStart hook target\n// ---------------------------------------------------------------------------\n\n/**\n * Print the impersonated agent's first-person introduction to stdout so\n * Claude Code injects it into the fresh session (ENG-5750). Registered\n * by `connect` as a SessionStart (matcher `startup`) hook.\n *\n * - **Guarded**: emits only when an active, unexpired manifest exists.\n * After `exit` (or once the token lapses) it's a silent no-op — that's\n * how a normal operator session in the same cwd produces no intro.\n * - **Snapshot-only**: reads CLAUDE.md / .mcp.json from project_cwd;\n * never the network, never a token.\n * - **Soft-fail**: any error prints whatever is available and exits 0,\n * never blocking session boot. Deliberately NOT gated on\n * requireImpersonateEnabled() — connect only registers the hook when\n * the flag was set, and a hook must never throw into the session.\n */\nexport async function impersonateIntroduceCommand(): Promise<void> {\n try {\n // ENG-5967: the SessionStart hook runs in the impersonation session's\n // own directory (connect spawns Claude with cwd = project_cwd), so the\n // current directory's manifest is the right — and only — one to read.\n const manifest = readActiveManifest(process.cwd());\n if (!manifest || isExpired(manifest)) return;\n\n const cwd = manifest.project_cwd;\n const identity = readClaudeMdIdentity(join(cwd, 'CLAUDE.md'));\n const integrations = readMcpIntegrations(join(cwd, '.mcp.json'));\n\n const intro = buildIntroduction({\n displayName: identity.displayName,\n codeName: manifest.code_name,\n role: identity.role,\n integrations,\n });\n process.stdout.write(intro + '\\n');\n } catch {\n // Soft-fail: never block session boot.\n }\n}\n\nfunction readClaudeMdIdentity(path: string): ParsedIdentity {\n try {\n return parseIdentityFromClaudeMd(readFileSync(path, 'utf-8'));\n } catch {\n return { displayName: null, role: null };\n }\n}\n\nfunction readMcpIntegrations(path: string): string[] {\n try {\n return parseIntegrationsFromMcpJson(readFileSync(path, 'utf-8'));\n } catch {\n return [];\n }\n}\n\n/**\n * ENG-5812 — resolve the CLI's bundled `dist/mcp/` directory, the same\n * one populated by `build:mcp-assets` (copies of @integrity-labs/\n * augmented-mcp's index.js + channel bundles). Used by the .mcp.json\n * rewrite to substitute the server's Lambda paths for operator-side\n * paths.\n *\n * Walks from this module's location to handle the same layouts as\n * resolveBundledAssetPath in impersonate-statusline.ts:\n * - dev (tsx): apps/cli/src/commands → apps/cli/mcp (workspace copy)\n * - built (tsup): apps/cli/dist/<chunk>.js → apps/cli/dist/mcp\n * - installed: <pkg>/dist/<chunk>.js → <pkg>/dist/mcp\n *\n * Returns a best-effort path when no candidate currently exists on\n * disk — CI runs from source without `build:mcp-assets` having\n * executed, and the impersonate-connect tests exercise this code path\n * without actually spawning the MCP servers. The runtime spawn path\n * surfaces \"MCP server failed to start\" loudly enough already; making\n * resolveCliMcpBundleDir throw here would gate the rewrite on a\n * pre-built tree the test environment doesn't have.\n */\nfunction resolveCliMcpBundleDir(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(moduleDir, 'mcp'),\n join(moduleDir, '..', 'mcp'),\n join(moduleDir, '..', '..', 'mcp'),\n ];\n for (const candidate of candidates) {\n if (existsSync(join(candidate, 'index.js'))) return candidate;\n }\n // Best-effort fallback — the most likely \"correct\" path for a built\n // install. An operator whose installed CLI is missing dist/mcp/ would\n // see a spawn ENOENT when the augmented gateway tries to start,\n // which is the right loud failure mode (not a silent rewrite throw).\n return candidates[candidates.length - 1]!;\n}\n\n/**\n * ENG-5818 (Bug 1) — build a host-correct `PATH` for the operator's\n * machine to overwrite the server-baked Lambda PATH in the rendered\n * `.mcp.json`. The server bakes its own runtime PATH at provision time\n * (`/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin` on the redeem\n * Lambda); none of those dirs hold `node` on a macOS nvm/Homebrew host,\n * so the MCP `command: \"node\"` spawn ENOENTs and every server fails.\n *\n * Prepend the running node's own bin dir (`dirname(process.execPath)` —\n * the exact interpreter running `agt`, guaranteed to exist) to the\n * operator's inherited `PATH`, de-duplicated so we don't bloat the\n * variable on repeated connects. This guarantees `node` resolves while\n * preserving the operator's other PATH entries (Homebrew etc.) so `npx`\n * still works for integration MCP servers.\n *\n * Exported for tests.\n */\nexport function resolveOperatorPath(\n execPath: string = process.execPath,\n inheritedPath: string = process.env.PATH ?? '',\n): string {\n const nodeBinDir = dirname(execPath);\n const segments = inheritedPath.split(delimiter).filter((s) => s.length > 0);\n if (!segments.includes(nodeBinDir)) {\n segments.unshift(nodeBinDir);\n }\n return segments.join(delimiter);\n}\n\n/**\n * ENG-5806 — return shape for `buildImpersonateClaudeLaunch`. Named so\n * the contract is reusable and discoverable, per project TS guidelines.\n */\nexport interface ImpersonateClaudeLaunch {\n args: string[];\n env: NodeJS.ProcessEnv;\n}\n\n/**\n * ENG-5806 — build the launch args + env so the impersonated Claude Code\n * session sees ONLY the agent's swapped-in `.mcp.json` and not the\n * operator's user-scope MCP servers (~/.claude.json) or claude.ai\n * connectors (Gmail/Calendar/Drive/Slack/etc.).\n *\n * Without this, Claude Code merges the project-level `.mcp.json` the\n * impersonation flow swapped in WITH the operator's user-scope tools,\n * so the impersonated agent silently wields the operator's credentials.\n * That breaks the contract of `impersonate` and is SOC2-relevant\n * (auditing \"you acted as the agent\" is misleading when the agent had\n * the operator's tools).\n *\n * - `--strict-mcp-config` restricts the session to ONLY the `.mcp.json`\n * files passed via `--mcp-config`, suppressing user-scope, project-\n * scope auto-load, claude.ai connectors, and plugin-provided servers.\n * - `ENABLE_CLAUDEAI_MCP_SERVERS=false` is belt-and-braces: claude.ai\n * connectors only auto-load under claude.ai subscription auth (not\n * API key), but setting it explicitly is cheap and survives an auth\n * mode change mid-session.\n *\n * Exported for tests; not part of the public CLI API.\n */\nexport function buildImpersonateClaudeLaunch(\n projectCwd: string,\n inheritEnv: NodeJS.ProcessEnv = process.env,\n agentId: string | null = null,\n): ImpersonateClaudeLaunch {\n const env: NodeJS.ProcessEnv = {\n ...inheritEnv,\n ENABLE_CLAUDEAI_MCP_SERVERS: 'false',\n };\n // ENG-5689: when we know which agent the operator is impersonating,\n // forward the agent UUID so spawned channel MCP servers (slack /\n // telegram / direct-chat) can refuse send-* tools. Spoof-resistance\n // is out of scope; this is the accidental-foot-gun gate.\n if (agentId !== null && agentId.length > 0) {\n env.AGT_ACT_AS_AGENT_ID = agentId;\n }\n return {\n args: [\n '--strict-mcp-config',\n '--mcp-config',\n join(projectCwd, '.mcp.json'),\n ],\n env,\n };\n}\n","/**\n * ENG-5688 — feature flag for the `agt impersonate` family of commands.\n *\n * The flow is still v0 and there are pieces (channel-MCP refusal under\n * acting-as JWT, slash-command wrappers) that haven't landed yet, so we\n * gate the commands behind an env var to keep them out of general\n * operators' hands until the surrounding pieces are in. Once those land\n * (ENG-5689 + ENG-5690) and the spike's smoke test has been run end-to-end\n * against production data, the flag can be removed and the commands\n * promoted to defaults.\n *\n * Set `AGT_IMPERSONATE_ENABLED=1` (or any truthy value) to enable.\n */\n\nconst ENV_VAR = 'AGT_IMPERSONATE_ENABLED';\n\n/**\n * Returns true if the operator has explicitly opted in to the\n * impersonation commands. Used by every `agt impersonate *` subcommand\n * to gate access.\n */\nexport function impersonateEnabled(): boolean {\n const v = process.env[ENV_VAR];\n if (!v) return false;\n const trimmed = v.trim().toLowerCase();\n // Treat the obvious \"off\" values as disabled to avoid silent footguns\n // (`AGT_IMPERSONATE_ENABLED=0` shouldn't be truthy just because the\n // string is non-empty).\n return !(trimmed === '' || trimmed === '0' || trimmed === 'false' || trimmed === 'no');\n}\n\n/**\n * Bail with a helpful message when the flag is not set. Returns void on\n * success; calls `process.exit(2)` otherwise so the command terminates\n * before any state-mutating work runs.\n *\n * Exit code 2 (rather than 1) so callers / CI scripts can distinguish\n * \"feature gated off\" from \"command failed for some other reason\".\n */\nexport function requireImpersonateEnabled(): void {\n if (impersonateEnabled()) return;\n\n process.stderr.write(\n `\\nThe \\`agt impersonate\\` commands are gated behind a feature flag.\\n` +\n `\\n` +\n `To enable them, set ${ENV_VAR}=1 in your environment:\\n` +\n `\\n` +\n ` export ${ENV_VAR}=1\\n` +\n `\\n` +\n `These commands are part of the operator-impersonates-agent v0 flow\\n` +\n `(ENG-5687 / ENG-5688). The gating will be removed once the\\n` +\n `surrounding pieces (ENG-5689 channel-MCP refusal, ENG-5690 slash\\n` +\n `commands) land and the end-to-end smoke test has been run against\\n` +\n `production.\\n` +\n `\\n`,\n );\n process.exit(2);\n}\n\n// Exported for tests so they don't have to hard-code the variable name.\nexport const IMPERSONATE_FLAG_ENV_VAR = ENV_VAR;\n","/**\n * ENG-5688 / ENG-5967 — on-disk state for `agt impersonate`.\n *\n * Layout under `~/.augmented-impersonate/`:\n *\n * active/session-<hash>.json — one manifest PER impersonation session,\n * keyed by a hash of its project_cwd. This\n * is what lets multiple agents be\n * impersonated concurrently from separate\n * terminals (each `connect` runs in its own\n * dedicated directory — process.cwd() or an\n * auto-provisioned `--workdir`).\n * active/manifest.json — LEGACY singleton from the pre-ENG-5967\n * one-at-a-time design. Migrated into the\n * keyed layout on first access (see\n * `migrateLegacyManifest`) so an in-flight\n * session created by an older CLI survives\n * the upgrade.\n * <code-name>/CLAUDE.md — persona files rendered for THIS agent;\n * <code-name>/.mcp.json kept side-by-side so the operator can diff\n * two agents' configs cheaply.\n *\n * Each manifest records what files we backed up in its project directory so\n * `exit` can restore them precisely. Keying by project_cwd means two\n * sessions never share backup state, and exiting one never disturbs another.\n *\n * Concurrency: every write is atomic (tmp + rename) and each session is its\n * own file, so concurrent `connect`s in different directories never race on\n * shared state.\n */\n\nimport { createHash } from 'node:crypto';\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst IMPERSONATE_ROOT = join(homedir(), '.augmented-impersonate');\nconst ACTIVE_DIR = join(IMPERSONATE_ROOT, 'active');\n/**\n * Legacy singleton path from the pre-ENG-5967 one-session-at-a-time design.\n * Retained only so `migrateLegacyManifest` can fold a pre-upgrade session\n * into the per-cwd layout. New writes never target it.\n */\nconst ACTIVE_MANIFEST_PATH = join(ACTIVE_DIR, 'manifest.json');\nconst SESSION_FILE_PREFIX = 'session-';\nconst SESSION_FILE_SUFFIX = '.json';\n\n/**\n * Per-session manifest path, keyed by a hash of the project directory. The\n * hash keeps the filename filesystem-safe and fixed-length regardless of how\n * long or exotic the project path is; collisions are not a concern at\n * SHA-256/16-hex-chars for the handful of dirs one operator impersonates in.\n */\nfunction sessionManifestPath(projectCwd: string): string {\n const hash = createHash('sha256').update(projectCwd).digest('hex').slice(0, 16);\n return join(ACTIVE_DIR, `${SESSION_FILE_PREFIX}${hash}${SESSION_FILE_SUFFIX}`);\n}\n\n/**\n * Records what `select` found at a given path in the operator's project\n * before swapping it for the impersonation persona, so `exit` can put\n * things back exactly the way they were.\n *\n * - \"had-file\": a regular file existed and was renamed to\n * <path>.pre-impersonate-backup. Restore = rename back.\n * - \"was-symlink\": a symlink existed (e.g. a stale prior impersonation)\n * and was simply removed. Restore = nothing (the operator\n * presumably re-runs select if they wanted it back).\n * - \"didnt-exist\": nothing was there; we just made a symlink. Restore =\n * remove the symlink.\n */\nexport type BackupKind = 'had-file' | 'was-symlink' | 'didnt-exist';\n\n/**\n * ENG-5750 — records what the introduce SessionStart hook touched in the\n * operator's project dir so `exit` can leave it exactly as it found it.\n *\n * - `settings_path`: the `.claude/settings.local.json` we upserted the\n * SessionStart hook into.\n * - `settings_backup`: \"had-file\" → the original was copied to\n * `<path>.pre-impersonate-backup` and must be restored on exit;\n * \"didnt-exist\" → we created it and must remove it on exit.\n * - `created_claude_dir`: we created the `.claude` directory and should\n * remove it on exit if it's empty afterwards.\n */\nexport interface HookBackup {\n settings_path: string;\n settings_backup: 'had-file' | 'didnt-exist';\n created_claude_dir: boolean;\n}\n\n/**\n * ENG-5801 — records what the impersonation statusLine upsert touched in\n * the operator's project dir so `exit` can leave it exactly as it found\n * it. Same shape as HookBackup because both features share the same\n * `.claude/settings.local.json` byte-for-byte backup mechanism (whichever\n * register runs first creates `<path>.pre-impersonate-backup`; whichever\n * unregister runs first restores it — the existence guards in\n * register/unregister make the ordering irrelevant).\n *\n * - `settings_path`: the `.claude/settings.local.json` we upserted the\n * `statusLine` key into.\n * - `settings_backup`: \"had-file\" → original was copied to\n * `<path>.pre-impersonate-backup` and must be restored on exit;\n * \"didnt-exist\" → we created it and must remove it on exit.\n * - `created_claude_dir`: we created the `.claude` directory and should\n * remove it on exit if it's empty afterwards.\n */\nexport interface StatusLineBackup {\n settings_path: string;\n settings_backup: 'had-file' | 'didnt-exist';\n created_claude_dir: boolean;\n}\n\n/**\n * Singleton manifest. Reused for both writing during `connect` and\n * reading during `current` / `exit`. The shape is meant to be append-only\n * — fields added later should be optional so older manifests still load\n * after an upgrade.\n */\nexport interface ImpersonateManifest {\n /** Agent code_name (kebab-case, e.g. `data-jane`). */\n code_name: string;\n /** Agent UUID, mirror of `act_as_agent_id` claim on the JWT. */\n agent_id: string;\n /** Team UUID the agent belongs to. */\n team_id: string;\n /** Server-issued impersonation JWT — keep opaque to the CLI. */\n token: string;\n /** Unix-seconds (matches the API's response.expires_at). */\n expires_at: number;\n /** Server-issued correlator (claim `sid`). */\n session_id: string;\n /** ISO-8601 timestamp the manifest was written (for `current`). */\n minted_at: string;\n /** process.cwd() at the time of `connect`. */\n project_cwd: string;\n /** What we found in project_cwd before swapping (see BackupKind). */\n backups: Record<string, BackupKind>;\n /**\n * Augmented API host (no trailing slash) the redeem token was\n * exchanged against. `exit` calls /impersonate/agent/stop against the\n * same host so the audit row lands on the right environment — operators\n * who flip AGT_HOST between dev/prod between connect and exit otherwise\n * miss the stop server-side. ENG-5688 (redesigned flow).\n */\n host: string;\n /**\n * ENG-5750 — the introduce SessionStart hook registered in\n * project_cwd, if any. Optional so older manifests still load. `exit`\n * uses it to remove/restore the hook and leave the cwd clean.\n */\n hook?: HookBackup;\n /**\n * ENG-5801 — the impersonation statusLine registered in project_cwd,\n * if any. Optional so older manifests still load (same precedent as\n * `hook?`). `exit` uses it to remove/restore the statusLine and leave\n * the cwd clean.\n */\n statusLine?: StatusLineBackup;\n}\n\n/**\n * Per-code-name directory holding the rendered persona files. Created\n * on demand by `ensureCodeNameDir()`.\n */\n\n/**\n * CR #3322333801: codeName flows directly into `join(IMPERSONATE_ROOT,\n * codeName)`. A value like `../...` would let a hostile redeem response\n * write outside ~/.augmented-impersonate/. We can't fully trust the API\n * server's response (defensive depth), and code_name is supposed to be\n * kebab-case anyway per the codebase's naming conventions — validate\n * up-front and throw if it's not.\n */\nconst CODE_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nfunction assertValidCodeName(codeName: string): void {\n if (!CODE_NAME_RE.test(codeName)) {\n throw new Error(\n `Invalid agent code_name \"${codeName}\" — must be lowercase kebab-case (a-z, 0-9, hyphens; no leading/trailing/consecutive hyphens).`,\n );\n }\n}\n\nexport function getImpersonateCodeNameDir(codeName: string): string {\n assertValidCodeName(codeName);\n return join(IMPERSONATE_ROOT, codeName);\n}\n\nexport function ensureCodeNameDir(codeName: string): string {\n // assertValidCodeName runs inside getImpersonateCodeNameDir, but we\n // call it again explicitly so mkdirSync gets a validated input even\n // if a future change unwires the helper.\n assertValidCodeName(codeName);\n const dir = getImpersonateCodeNameDir(codeName);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/**\n * ENG-5756 (AC3) — dedicated, agent-scoped working directory used by\n * `agt impersonate connect --workdir`. Lives under the per-code-name\n * persona dir (so it's clearly owned by impersonation and sits beside\n * the persona files the swap links to). Persona files get symlinked in\n * HERE instead of into the operator's cwd, which makes clobbering a repo\n * working tree structurally impossible rather than merely recoverable.\n */\nexport function ensureImpersonateWorkdir(codeName: string): string {\n const dir = join(ensureCodeNameDir(codeName), 'workdir');\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/**\n * Strict structural validation, factored out so both the single-session\n * read and the multi-session `listActiveManifests` enforce the exact same\n * contract. Returns the validated manifest or null.\n *\n * CR #3321347807: validate EVERY required field, including `backups`. A\n * half-written manifest that passed the old four-field check would later\n * crash `exit` on `Object.entries(manifest.backups)` when backups was\n * undefined. Bail to null rather than throw so callers treat corrupted\n * state as \"nothing to restore\" rather than entering an error loop.\n */\nfunction validateManifest(parsed: unknown): ImpersonateManifest | null {\n if (typeof parsed !== 'object' || parsed === null) return null;\n const m = parsed as Record<string, unknown>;\n\n const backupsOk =\n typeof m.backups === 'object' &&\n m.backups !== null &&\n Object.values(m.backups as Record<string, unknown>).every(\n (v) => v === 'had-file' || v === 'was-symlink' || v === 'didnt-exist',\n );\n\n if (\n typeof m.code_name !== 'string' ||\n typeof m.agent_id !== 'string' ||\n typeof m.team_id !== 'string' ||\n typeof m.token !== 'string' ||\n typeof m.expires_at !== 'number' ||\n typeof m.session_id !== 'string' ||\n typeof m.minted_at !== 'string' ||\n typeof m.project_cwd !== 'string' ||\n // ENG-5688 (redesigned): host required so `exit` calls /stop against\n // the right environment. Required, not optional, because writing the\n // wrong host on an existing session would point exit at a server\n // that has no record of the session — silently misleading.\n typeof m.host !== 'string' ||\n m.host.length === 0 ||\n !backupsOk\n ) {\n return null;\n }\n return parsed as ImpersonateManifest;\n}\n\n/** Read + validate a single manifest file, or null on any problem. */\nfunction readManifestFile(path: string): ImpersonateManifest | null {\n if (!existsSync(path)) return null;\n try {\n return validateManifest(JSON.parse(readFileSync(path, 'utf-8')));\n } catch {\n return null;\n }\n}\n\n/**\n * ENG-5967 — fold a pre-upgrade legacy singleton (`active/manifest.json`)\n * into the per-cwd layout. Idempotent and best-effort: a valid legacy\n * manifest is moved to its keyed path (unless one already exists there,\n * in which case the keyed file wins and the legacy is discarded); an\n * unreadable/invalid legacy file is removed so it can't shadow future\n * reads. Called at the start of every public accessor so an older CLI's\n * in-flight session keeps working after the operator upgrades.\n */\nfunction migrateLegacyManifest(): void {\n if (!existsSync(ACTIVE_MANIFEST_PATH)) return;\n const legacy = readManifestFile(ACTIVE_MANIFEST_PATH);\n try {\n if (!legacy) {\n rmSync(ACTIVE_MANIFEST_PATH, { force: true });\n return;\n }\n const target = sessionManifestPath(legacy.project_cwd);\n if (!existsSync(target)) {\n mkdirSync(ACTIVE_DIR, { recursive: true, mode: 0o700 });\n renameSync(ACTIVE_MANIFEST_PATH, target);\n chmodSync(target, 0o600);\n } else {\n // A keyed session for this dir already exists — it's authoritative.\n rmSync(ACTIVE_MANIFEST_PATH, { force: true });\n }\n } catch {\n // Best-effort: never let a migration hiccup break the caller.\n }\n}\n\n/**\n * Reads the active manifest for `projectCwd` if present. Returns null when\n * no impersonation is active in that directory — `current` and `exit` use\n * this to decide whether there's anything to act on.\n *\n * Does NOT check expiry — that's the caller's call. `current` reports the\n * expiry; `exit` proceeds with cleanup either way (a manifest pointing at\n * an expired JWT is still authoritative for the local backup state).\n */\nexport function readActiveManifest(projectCwd: string): ImpersonateManifest | null {\n migrateLegacyManifest();\n return readManifestFile(sessionManifestPath(projectCwd));\n}\n\n/**\n * ENG-5967 — every active impersonation session on this machine. Used by\n * `current --all` / `exit --all` and by the lazy auto-exit sweep so a\n * single command can reason about (or clean up) all sessions at once.\n * Invalid/half-written files are skipped, not thrown on.\n */\nexport function listActiveManifests(): ImpersonateManifest[] {\n migrateLegacyManifest();\n let entries: string[];\n try {\n entries = readdirSync(ACTIVE_DIR);\n } catch {\n return []; // active dir doesn't exist yet\n }\n const out: ImpersonateManifest[] = [];\n for (const entry of entries) {\n if (!entry.startsWith(SESSION_FILE_PREFIX) || !entry.endsWith(SESSION_FILE_SUFFIX)) {\n continue;\n }\n const manifest = readManifestFile(join(ACTIVE_DIR, entry));\n if (manifest) out.push(manifest);\n }\n return out;\n}\n\n/**\n * Writes the active manifest. Creates the directory if needed and uses\n * `renameSync` to swap atomically so a half-written file doesn't end up\n * on disk if the process is killed mid-write.\n *\n * CR #3322333807: the manifest contains the impersonation token (a\n * bearer credential), so the file and its parent directory are written\n * with restrictive permissions: 0700 on the directory, 0600 on the\n * file (owner read/write only — group/world get nothing). The explicit\n * chmodSync after writeFileSync is belt-and-braces: writeFileSync's\n * `mode` is the create-mode but doesn't take effect if the path already\n * exists. chmodSync forces it down to 0600 either way.\n */\nexport function writeActiveManifest(manifest: ImpersonateManifest): void {\n migrateLegacyManifest();\n mkdirSync(ACTIVE_DIR, { recursive: true, mode: 0o700 });\n const path = sessionManifestPath(manifest.project_cwd);\n const tmp = path + '.tmp';\n writeFileSync(tmp, JSON.stringify(manifest, null, 2), { mode: 0o600 });\n chmodSync(tmp, 0o600);\n renameSync(tmp, path);\n}\n\n/**\n * Removes the active manifest for `projectCwd`. Idempotent — calling it\n * twice, or when no manifest exists for that directory, is a no-op. Other\n * directories' sessions are untouched.\n */\nexport function clearActiveManifest(projectCwd: string): void {\n migrateLegacyManifest();\n const path = sessionManifestPath(projectCwd);\n if (existsSync(path)) {\n rmSync(path);\n }\n}\n\n/**\n * True if the manifest's expires_at has passed. Used by `current` to\n * tell the operator \"your session has expired, you should re-select or\n * exit\".\n */\nexport function isExpired(manifest: ImpersonateManifest, now = Date.now()): boolean {\n return manifest.expires_at * 1000 <= now;\n}\n\n// Exported for tests; intentionally not part of the documented API.\nexport const TEST_ONLY = {\n IMPERSONATE_ROOT,\n ACTIVE_DIR,\n /** Legacy singleton path — retained for migration tests. */\n ACTIVE_MANIFEST_PATH,\n /** Resolve the per-cwd keyed manifest path (ENG-5967). */\n sessionManifestPath,\n};\n","/**\n * ENG-5688 (redesigned) — file-swap helpers for `agt impersonate`.\n *\n * Extracted from the original PR #1489's impersonate.ts so the helpers\n * are unit-testable on their own and reusable from both `connect` and\n * `exit`. Invariants preserved verbatim from the CR feedback on #1489:\n *\n * - Symlink-into-ours check uses realpath + startsWith(\n * $HOME/.augmented-impersonate/), not substring matching.\n * Closed PR #1489 / CR #3321347799.\n * - Broken symlinks refuse explicitly rather than fall through as\n * \"didnt-exist\". Same CR.\n * - Pre-existing .pre-impersonate-backup at the target refuses; manual\n * cleanup needed rather than silent overwrite.\n * - restoreSwapped won't clobber a non-symlink replacement at the\n * project path — if the operator (or some external process) put a\n * real file there during the session, leave it alone.\n */\n\nimport {\n existsSync,\n lstatSync,\n readlinkSync,\n realpathSync,\n renameSync,\n symlinkSync,\n unlinkSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, parse, sep } from 'node:path';\n\nimport type { BackupKind } from './impersonate-state.js';\n\nexport const BACKUP_SUFFIX = '.pre-impersonate-backup';\n\n/**\n * ENG-5756 — find the git working tree `startDir` lives in, if any.\n *\n * Walks `startDir` and its ancestors looking for a `.git` entry; returns\n * the first directory that has one, or `null` if we reach the filesystem\n * root without finding one. `.git` is matched as EITHER a directory\n * (normal clone) OR a file (git worktree / submodule, where `.git` is a\n * gitlink pointing at the real gitdir) — both mean \"inside a working\n * tree\", which is exactly what `connect` must refuse to swap persona\n * files into (it would clobber the repo's own CLAUDE.md / .mcp.json).\n *\n * This is the dependency-free equivalent of\n * `git rev-parse --show-toplevel` / `--is-inside-work-tree`: no `git`\n * binary required (so it works in the clean shells impersonation\n * targets — ENG-5688 AC4) and trivially unit-testable with temp dirs.\n */\nexport function findGitWorkTreeRoot(startDir: string): string | null {\n const { root } = parse(startDir);\n let dir = startDir;\n for (;;) {\n if (existsSync(join(dir, '.git'))) return dir;\n if (dir === root) return null;\n const parent = dirname(dir);\n // dirname() is a fixpoint at the root on every platform; guard\n // against an infinite loop if `root` detection ever disagrees.\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Replace the file at `projectPath` with a symlink to `personaPath`,\n * preserving whatever was there before so `exit` can restore it.\n *\n * Cases:\n * - Regular file → rename to <path>.pre-impersonate-backup, then\n * create symlink. Restore = rename back.\n * - Symlink resolving INTO our persona root → remove silently and\n * re-link (stale prior impersonation that wasn't exited).\n * Restore = unlink the new symlink.\n * - Symlink resolving OUTSIDE our persona root → REFUSE; the operator\n * may have set it up deliberately.\n * - Broken symlink → REFUSE; treating as absent would silently\n * overwrite what the operator put there.\n * - Nothing there → just create the symlink. Restore = unlink.\n */\nexport function swapInPersonaFile(\n projectPath: string,\n personaPath: string,\n): BackupKind {\n let kind: BackupKind;\n\n if (!lstatSafe(projectPath)) {\n // Truly absent.\n kind = 'didnt-exist';\n } else {\n const stat = lstatSync(projectPath);\n if (stat.isSymbolicLink()) {\n const target = readlinkSync(projectPath);\n // Resolve BOTH sides through realpathSync so macOS's /var ↔\n // /private/var indirection (and any other OS-level symlinks in\n // the path to $HOME) doesn't make a legitimate \"ours\" target\n // look foreign because of an unequal-but-equivalent prefix.\n const ourRoot =\n realpathSync(homedir()) + sep + '.augmented-impersonate' + sep;\n let resolvedTarget: string;\n try {\n resolvedTarget = realpathSync(projectPath);\n } catch {\n // realpath fails on broken symlinks. Treat as unknown and refuse —\n // silently treating as absent would overwrite what the operator\n // put there.\n throw new Error(\n `${projectPath} is a broken symlink (target ${target}). ` +\n `Resolve manually and retry.`,\n );\n }\n if (resolvedTarget.startsWith(ourRoot)) {\n unlinkSync(projectPath);\n kind = 'was-symlink';\n } else {\n throw new Error(\n `${projectPath} is a symlink to ${target} (resolved: ${resolvedTarget}). ` +\n `Refusing to replace it — it doesn't live under ${ourRoot}. ` +\n `Resolve manually and retry.`,\n );\n }\n } else {\n const backupPath = projectPath + BACKUP_SUFFIX;\n if (existsSync(backupPath)) {\n // Backup already exists from a previous failed run. Refuse rather\n // than silently overwrite — manual cleanup is safer than wrong\n // restore later.\n throw new Error(\n `${backupPath} already exists from a previous run. ` +\n `Remove it manually if you're sure it's stale, then retry.`,\n );\n }\n renameSync(projectPath, backupPath);\n kind = 'had-file';\n }\n }\n\n symlinkSync(personaPath, projectPath, 'file');\n return kind;\n}\n\n/**\n * Reverse of swapInPersonaFile.\n *\n * Removes the symlink at projectPath (if it's still a symlink — leave\n * non-symlink replacements alone) and restores the backup file when\n * one exists.\n */\nexport function restoreSwapped(projectPath: string, kind: BackupKind): void {\n if (lstatSafe(projectPath)) {\n const stat = lstatSync(projectPath);\n if (stat.isSymbolicLink()) {\n unlinkSync(projectPath);\n } else {\n // Not a symlink — someone replaced it during the session. Don't\n // touch it.\n return;\n }\n }\n\n if (kind === 'had-file') {\n const backupPath = projectPath + BACKUP_SUFFIX;\n if (existsSync(backupPath)) {\n renameSync(backupPath, projectPath);\n }\n }\n // 'was-symlink' and 'didnt-exist': nothing to restore.\n}\n\nfunction lstatSafe(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * ENG-5750 — register/unregister the impersonation \"introduce yourself\"\n * SessionStart hook in the operator's project dir.\n *\n * `connect` calls `registerIntroduceHook(projectCwd)` after scaffolding\n * CLAUDE.md/.mcp.json. It upserts a SessionStart (matcher `startup`) hook\n * into `<projectCwd>/.claude/settings.local.json` that shells out to\n * `agt impersonate introduce` on every fresh Claude Code boot.\n *\n * The upsert mirrors `provisionOrientHook()` in @augmented/core\n * (packages/core/src/provisioning/frameworks/claudecode/index.ts): don't\n * clobber existing SessionStart entries, and stay idempotent so a repeat\n * connect doesn't stack duplicates.\n *\n * Unlike the managed-agent orient hook (which owns a long-lived\n * settings file), impersonation is ephemeral: `exit` must leave the\n * operator's cwd exactly as it found it. So registration records a\n * `HookBackup` — whether settings.local.json pre-existed (backed up vs\n * created) and whether we created the `.claude` dir — and\n * `unregisterIntroduceHook()` reverses precisely.\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmdirSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { join } from 'node:path';\n\nimport { BACKUP_SUFFIX } from './impersonate-fs-ops.js';\nimport type { HookBackup } from './impersonate-state.js';\n\n/**\n * The command the SessionStart hook runs. Bare `agt` (PATH lookup) for\n * the same reason `connect` spawns bare `claude`: the operator just ran\n * `agt impersonate connect`, so the binary is demonstrably on PATH, and\n * the hook inherits that PATH from the launching shell. Exposed as a\n * parameter so tests can assert against a fixed value.\n */\nexport const INTRODUCE_HOOK_COMMAND = 'agt impersonate introduce';\n\nconst SESSION_START_MATCHER = 'startup';\n\n/**\n * Upsert the introduce SessionStart hook into\n * `<projectCwd>/.claude/settings.local.json`. Returns a HookBackup the\n * manifest stores so `exit` can undo exactly what was done.\n */\nexport function registerIntroduceHook(\n projectCwd: string,\n command: string = INTRODUCE_HOOK_COMMAND,\n): HookBackup {\n const claudeDir = join(projectCwd, '.claude');\n const createdClaudeDir = !existsSync(claudeDir);\n mkdirSync(claudeDir, { recursive: true });\n\n const settingsPath = join(claudeDir, 'settings.local.json');\n const settingsExisted = existsSync(settingsPath);\n const backupPath = settingsPath + BACKUP_SUFFIX;\n\n let settings: Record<string, unknown> = {};\n if (settingsExisted) {\n // Back up the original verbatim so exit restores it byte-for-byte,\n // then merge our hook into the parsed copy. Guard the copy: if a\n // backup already exists (a prior register that wasn't exited),\n // DON'T clobber it — otherwise exit would restore an already-hooked\n // file instead of the operator's true original. A malformed or\n // non-object JSON root is preserved as the backup but not merged\n // into (start fresh from {}).\n if (!existsSync(backupPath)) {\n copyFileSync(settingsPath, backupPath);\n }\n settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n }\n\n const hooks = asPlainObject(settings['hooks']);\n const existing = Array.isArray(hooks[SESSION_START_KEY])\n ? [...(hooks[SESSION_START_KEY] as Array<Record<string, unknown>>)]\n : [];\n\n const alreadyRegistered = existing.some((entry) =>\n entryMatchesCommand(entry, command),\n );\n if (!alreadyRegistered) {\n existing.push({\n matcher: SESSION_START_MATCHER,\n hooks: [{ type: 'command', command }],\n });\n }\n hooks[SESSION_START_KEY] = existing;\n settings['hooks'] = hooks;\n\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n\n return {\n settings_path: settingsPath,\n settings_backup: settingsExisted ? 'had-file' : 'didnt-exist',\n created_claude_dir: createdClaudeDir,\n };\n}\n\n/**\n * Reverse registerIntroduceHook: restore the backed-up settings file (or\n * remove the one we created) and drop the `.claude` dir if we created it\n * and it's now empty. Best-effort and idempotent — safe to call twice.\n */\nexport function unregisterIntroduceHook(backup: HookBackup): void {\n const { settings_path, settings_backup, created_claude_dir } = backup;\n const backupPath = settings_path + BACKUP_SUFFIX;\n\n if (settings_backup === 'had-file') {\n // Restore the original over our merged version.\n if (existsSync(backupPath)) {\n renameSync(backupPath, settings_path);\n }\n } else {\n // We created it — remove it (and the stray backup, if any).\n if (existsSync(settings_path)) unlinkSync(settings_path);\n if (existsSync(backupPath)) unlinkSync(backupPath);\n }\n\n if (created_claude_dir) {\n const claudeDir = dirOf(settings_path);\n try {\n if (existsSync(claudeDir) && readdirSync(claudeDir).length === 0) {\n rmdirSync(claudeDir);\n }\n } catch {\n // Non-empty (operator added files) or already gone — leave it.\n }\n }\n}\n\nconst SESSION_START_KEY = 'SessionStart';\n\nfunction entryMatchesCommand(entry: Record<string, unknown>, command: string): boolean {\n if ((entry as { matcher?: unknown }).matcher !== SESSION_START_MATCHER) return false;\n const entryHooks = (entry as { hooks?: unknown }).hooks;\n return (\n Array.isArray(entryHooks) &&\n entryHooks.some(\n (h) =>\n typeof h === 'object' &&\n h !== null &&\n (h as { type?: unknown }).type === 'command' &&\n (h as { command?: unknown }).command === command,\n )\n );\n}\n\nfunction dirOf(filePath: string): string {\n const idx = filePath.lastIndexOf('/');\n return idx === -1 ? filePath : filePath.slice(0, idx);\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Coerce a parsed JSON value to a plain object, or {} for null/array/scalar. */\nfunction asPlainObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","/**\n * ENG-5801 — register/unregister the impersonation statusLine in the\n * operator's project dir.\n *\n * `connect` calls `registerStatusLine(projectCwd)` after registering the\n * SessionStart introduce hook. It upserts a `statusLine` key into\n * `<projectCwd>/.claude/settings.local.json` that runs the bundled shell\n * script `~/.augmented-impersonate/statusline.sh` (installed on first\n * connect from the CLI asset at `<package-root>/assets/impersonate-\n * statusline.sh`).\n *\n * While impersonation is active, the project-level `statusLine` overrides\n * the operator's user-level `~/.claude/settings.json` `statusLine` (Local\n * scope > User scope per Claude Code's settings precedence). This is an\n * intentional, ephemeral trade-off — `exit` restores the operator's prior\n * settings.local.json byte-for-byte from a backup, so their user-level\n * statusLine becomes effective again the moment the session ends.\n *\n * The backup mechanism is shared with `registerIntroduceHook` (both\n * features touch the same settings.local.json). The existence guard\n * `if (!existsSync(backupPath))` in each register makes the call order\n * irrelevant — whichever runs first captures the operator's true original;\n * whichever unregister runs first restores it; the other side is then a\n * no-op.\n */\n\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmdirSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { BACKUP_SUFFIX } from './impersonate-fs-ops.js';\nimport type { StatusLineBackup } from './impersonate-state.js';\n\n/**\n * Where we install the runtime statusline script on first connect. Lives\n * outside the operator's project so a `rm -rf .claude` doesn't kill it\n * for subsequent impersonations. The path is what\n * `<projectCwd>/.claude/settings.local.json` references as `statusLine`.\n */\nexport const INSTALLED_STATUSLINE_PATH = join(\n homedir(),\n '.augmented-impersonate',\n 'statusline.sh',\n);\n\nconst STATUS_LINE_KEY = 'statusLine';\nconst STATUS_LINE_COMMAND_TYPE = 'command';\n\n/**\n * Install the bundled statusline asset to INSTALLED_STATUSLINE_PATH if\n * it isn't already there OR if its content differs from the bundled\n * asset. Recopying on content drift lets a new CLI release ship a fixed\n * script without operators having to manually delete the stale copy —\n * matches the \"ship → next self-update applies it\" loop the rest of the\n * codebase assumes. Exported so tests can drive it against a tmp HOME.\n */\nexport function installStatusLineAsset(\n targetPath: string = INSTALLED_STATUSLINE_PATH,\n): void {\n mkdirSync(dirname(targetPath), { recursive: true });\n const source = resolveBundledAssetPath();\n const needsCopy =\n !existsSync(targetPath) ||\n readFileSync(source, 'utf-8') !== readFileSync(targetPath, 'utf-8');\n if (needsCopy) {\n copyFileSync(source, targetPath);\n chmodSync(targetPath, 0o755);\n }\n}\n\n/**\n * Upsert the impersonation statusLine into\n * `<projectCwd>/.claude/settings.local.json`. Returns a StatusLineBackup\n * the manifest stores so `exit` can undo exactly what was done.\n *\n * Idempotent: a repeat call when our statusLine is already registered is\n * a no-op (the existing backup is preserved). Doesn't clobber a backup\n * left behind by an earlier `registerIntroduceHook` — the existence\n * guard wins.\n */\nexport function registerStatusLine(\n projectCwd: string,\n options: { installAsset?: boolean } = {},\n): StatusLineBackup {\n // Tests pass `installAsset: false` to avoid writing into the real\n // ~/.augmented-impersonate/ during the suite. Production callers\n // (connect) accept the default.\n if (options.installAsset !== false) {\n installStatusLineAsset();\n }\n\n const claudeDir = join(projectCwd, '.claude');\n const createdClaudeDir = !existsSync(claudeDir);\n mkdirSync(claudeDir, { recursive: true });\n\n const settingsPath = join(claudeDir, 'settings.local.json');\n const settingsExisted = existsSync(settingsPath);\n const backupPath = settingsPath + BACKUP_SUFFIX;\n\n let settings: Record<string, unknown> = {};\n if (settingsExisted) {\n // Back up the original verbatim — but ONLY if a sibling\n // registerIntroduceHook didn't already do it. Whichever ran first\n // captures the operator's true pre-impersonation state.\n if (!existsSync(backupPath)) {\n copyFileSync(settingsPath, backupPath);\n }\n settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n }\n\n settings[STATUS_LINE_KEY] = {\n type: STATUS_LINE_COMMAND_TYPE,\n command: INSTALLED_STATUSLINE_PATH,\n };\n\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n\n return {\n settings_path: settingsPath,\n settings_backup: settingsExisted ? 'had-file' : 'didnt-exist',\n created_claude_dir: createdClaudeDir,\n };\n}\n\n/**\n * Reverse registerStatusLine: restore the backed-up settings file (or\n * remove the one we created) and drop the `.claude` dir if we created it\n * and it's now empty. Best-effort and idempotent — safe to call twice,\n * and safe to interleave with unregisterIntroduceHook in either order.\n */\nexport function unregisterStatusLine(backup: StatusLineBackup): void {\n const { settings_path, settings_backup, created_claude_dir } = backup;\n const backupPath = settings_path + BACKUP_SUFFIX;\n\n if (settings_backup === 'had-file') {\n // Restore the original over our merged version. If the sibling\n // unregisterIntroduceHook beat us to it, the backup is already gone\n // and the file is already restored — guarded.\n if (existsSync(backupPath)) {\n renameSync(backupPath, settings_path);\n } else if (existsSync(settings_path)) {\n // No backup left to restore — either it's already been restored by\n // the sibling hook unregister, OR we never had a backup because the\n // file was malformed at register time. Either way, the safe thing\n // is to strip just our statusLine key from the current file so we\n // don't leave a dangling pointer to INSTALLED_STATUSLINE_PATH if\n // the operator later deletes ~/.augmented-impersonate.\n stripStatusLineKey(settings_path);\n }\n } else {\n // We created the file — remove it (and the stray backup, if any).\n if (existsSync(settings_path)) unlinkSync(settings_path);\n if (existsSync(backupPath)) unlinkSync(backupPath);\n }\n\n if (created_claude_dir) {\n const claudeDir = dirname(settings_path);\n try {\n if (existsSync(claudeDir) && readdirSync(claudeDir).length === 0) {\n rmdirSync(claudeDir);\n }\n } catch {\n // Non-empty (operator added files) or already gone — leave it.\n }\n }\n}\n\n/**\n * Walk up from this module's location to find the bundled\n * `assets/impersonate-statusline.sh`. Covers both layouts:\n * - dev (tsx): apps/cli/src/lib → apps/cli/assets\n * - built (tsup): apps/cli/dist/<chunk>.js → apps/cli/dist/assets\n * - installed: <pkg>/dist/<chunk>.js → <pkg>/dist/assets\n *\n * Mirrors the resolver strategy in `persistent-session.ts:getAcpxBin`.\n */\nfunction resolveBundledAssetPath(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Built output: dist/<chunk>.js → dist/assets/...\n join(moduleDir, 'assets', 'impersonate-statusline.sh'),\n // Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/...\n join(moduleDir, '..', 'assets', 'impersonate-statusline.sh'),\n // Dev source: src/lib/impersonate-statusline.ts → ../../assets/...\n join(moduleDir, '..', '..', 'assets', 'impersonate-statusline.sh'),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n throw new Error(\n `[impersonate-statusline] could not locate bundled asset; tried:\\n ${candidates.join('\\n ')}`,\n );\n}\n\nfunction stripStatusLineKey(settingsPath: string): void {\n const settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n if (!(STATUS_LINE_KEY in settings)) return;\n delete settings[STATUS_LINE_KEY];\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Coerce a parsed JSON value to a plain object, or {} for null/array/scalar. */\nfunction asPlainObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","/**\n * ENG-5750 — pure helpers for the impersonation \"introduce yourself\"\n * SessionStart hook.\n *\n * When an operator `agt impersonate connect`s, a SessionStart hook fires\n * on the fresh Claude Code boot and shells out to `agt impersonate\n * introduce`. That command reads the persona snapshot already written to\n * the project dir at connect time — `CLAUDE.md` (identity) and\n * `.mcp.json` (connected MCP servers / integrations) — and prints a\n * short first-person introduction. No network, no token use.\n *\n * These three functions are the testable core: parsing identity out of\n * the generated CLAUDE.md, parsing the integration list out of\n * .mcp.json, and rendering the introduction text. The command wrapper\n * (impersonate.ts) handles the manifest guard, file IO, and soft-fail.\n *\n * The CLAUDE.md shape parsed here is produced by `generateClaudeMd`\n * (packages/core/src/provisioning/frameworks/claudecode/identity.ts):\n *\n * # <display_name>\n *\n * You are **<display_name>**, **<role>** in the **<team>** team at **<org>**.\n * ...\n */\n\nexport interface ParsedIdentity {\n displayName: string | null;\n role: string | null;\n}\n\n/**\n * Extract the agent's display name and role from a generated CLAUDE.md.\n *\n * - `displayName` ← the first `# <heading>` line.\n * - `role` ← the bolded role in the `You are **<name>**, **<role>**…`\n * identity sentence.\n *\n * Either field is `null` when its source line is absent — callers\n * degrade gracefully rather than fail (ENG-5750 soft-fail AC).\n */\nexport function parseIdentityFromClaudeMd(content: string): ParsedIdentity {\n const headingMatch = content.match(/^#\\s+(.+?)\\s*$/m);\n const displayName = headingMatch?.[1]?.trim() || null;\n\n // `You are **Koda**, **Software Developer** in the **…** team…`\n // The role is the SECOND bolded span on the identity line. Anchored to\n // the `You are ` prefix so we don't accidentally match other bold text.\n const roleMatch = content.match(\n /^You are \\*\\*[^*]+\\*\\*,\\s*\\*\\*([^*]+)\\*\\*/m,\n );\n const role = roleMatch?.[1]?.trim() || null;\n\n return { displayName, role };\n}\n\n/**\n * Extract the connected integration / MCP server names from a generated\n * `.mcp.json` (the `mcpServers` object's keys), prettified for display.\n *\n * Returns `[]` on malformed JSON or a missing/empty `mcpServers` map —\n * the caller treats an empty list as \"no integrations\" rather than an\n * error.\n */\nexport function parseIntegrationsFromMcpJson(content: string): string[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return [];\n }\n const servers = (parsed as { mcpServers?: unknown } | null)?.mcpServers;\n if (!servers || typeof servers !== 'object' || Array.isArray(servers)) {\n return [];\n }\n return Object.keys(servers as Record<string, unknown>).map(prettifyServerName);\n}\n\n/**\n * Turn an MCP server key (`direct-chat`, `task_channel`) into a\n * human-readable label (`Direct Chat`, `Task Channel`) for the intro.\n */\nfunction prettifyServerName(key: string): string {\n return key\n .split(/[-_]/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nexport interface IntroductionInput {\n displayName: string | null;\n codeName: string;\n role: string | null;\n integrations: string[];\n}\n\n/**\n * Render the first-person introduction printed into the fresh session.\n *\n * Shape (fields degrade independently when missing):\n *\n * I'm Koda (koda), Software Developer.\n *\n * Connected integrations: Slack, Telegram, Augmented.\n *\n * - No display name → fall back to the code name as the spoken name.\n * - No role → drop the role clause.\n * - No integrations → say so explicitly rather than emit a dangling line.\n */\nexport function buildIntroduction(input: IntroductionInput): string {\n const { displayName, codeName, role, integrations } = input;\n\n const spokenName = displayName || codeName;\n // Show \"(code-name)\" only when it adds information beyond the spoken name.\n const codeSuffix = displayName && displayName !== codeName ? ` (${codeName})` : '';\n const roleClause = role ? `, ${role}` : '';\n\n const lines: string[] = [`I'm ${spokenName}${codeSuffix}${roleClause}.`, ''];\n\n if (integrations.length > 0) {\n lines.push(`Connected integrations: ${integrations.join(', ')}.`);\n // ENG-5812: when the operator asks \"list your integrations\", call\n // `tools/list` on each MCP server above and report what each\n // actually exposes — do NOT narrate the integration list from\n // CHARTER.md. CHARTER describes the agent's design intent;\n // tools/list is the running ground truth. Real example of why:\n // an agent whose CHARTER mentions Linear via Composio + AWS\n // native that's actually only mounted as `augmented` should\n // answer \"augmented exposes the following tools: …\" not\n // \"I have Linear and AWS\".\n lines.push('');\n lines.push(\n \"If the operator asks what you can do, call each MCP server's \" +\n '`tools/list` and report the actual tool inventory. Do not narrate ' +\n 'capabilities from CHARTER.md — it describes intent, not runtime ' +\n 'state. Tools that fail to enumerate (server failed to spawn, env ' +\n 'missing, etc.) should be reported as such, not silently omitted.',\n );\n } else {\n lines.push('No integrations are connected.');\n }\n\n return lines.join('\\n');\n}\n","/**\n * ENG-5812 — rewrite the server-rendered `.mcp.json` so the operator's\n * local Claude Code can actually spawn the agent's MCP servers.\n *\n * Why this exists\n * ---------------\n * The redeem endpoint (`POST /impersonate/agent/redeem` in\n * packages/api/src/routes/impersonate.ts) calls `provision()` with\n * `deploymentTarget: 'local_docker'`. The claudecode framework adapter\n * uses `getHomeDir()` (the SERVER's runtime home — `/home/sbx_user1051`\n * on Lambda) and bakes that path into the rendered `.mcp.json`'s\n * `args`. It also leaves `AGT_HOST` / `AGT_API_KEY` / `HOME` empty\n * because those are normally filled by the deployment process, not by\n * provisioning. The artifact is structurally a *Lambda runtime\n * artifact*, not an *operator-side artifact*.\n *\n * When the operator's Claude Code tries to spawn `node\n * /home/sbx_user1051/.augmented/_mcp/index.js`, it ENOENTs — the path\n * doesn't exist on their Mac. Net effect: every MCP server in the\n * rendered persona fails to start, the impersonated agent has zero\n * working tools, and any \"list your integrations\" answer is the agent\n * narrating from CHARTER.md memory (which is what observably happens\n * — see Sherlock's reproduction in ENG-5812's description).\n *\n * Until the server learns about an \"impersonation\" deployment target\n * (Scope B), the CLI post-processes the artifact before swapping it\n * into the operator's project. We substitute:\n *\n * - Any `args` path matching `/home/<x>/.augmented/_mcp/<file>` with\n * `<cliMcpBundleDir>/<file>`. The CLI ships its own copy of the\n * channel + gateway MCP bundles via `build:mcp-assets`, so the\n * binaries are already on disk wherever the operator installed\n * `@integrity-labs/agt-cli`.\n * - Empty `env.AGT_HOST` with the API host the redeem was performed\n * against (so the gateway calls back to the right env).\n * - Empty `env.AGT_API_KEY` with the impersonation JWT (so the\n * gateway authenticates as the impersonating principal — the JWT\n * carries `act_as_agent_id` for attribution).\n * - Empty `env.HOME` with the operator's `$HOME`.\n * - Empty `env.AGT_AGENT_ID` / `env.AGT_AGENT_CODE_NAME` with the\n * redeem-known values — the renderer fills these but they may be\n * missing on a future server change; defence-in-depth.\n *\n * Pre-populated env values are NOT overwritten — the server's\n * intentional choice wins. Only empty/missing entries get the\n * impersonation-time substitution.\n *\n * Two env keys are the exception and ARE rewritten unconditionally,\n * because the server's value is structurally wrong for the operator\n * (ENG-5818):\n *\n * - `PATH` is baked at provision time as the SERVER's runtime PATH.\n * On the redeem Lambda that's an AWS Lambda PATH\n * (`/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin`) — none of\n * those dirs hold `node` on a typical macOS nvm/Homebrew host, and\n * because `env.PATH` overrides the inherited PATH the `command:\n * \"node\"` spawn ENOENTs (exit 127) and EVERY server fails to start.\n * We replace it with an operator-correct PATH (see `operatorPath`).\n * - `AGT_RUN_ID` is emitted as the literal `${AGT_RUN_ID}` sentinel\n * for a manager to substitute at spawn time. An impersonation\n * session has no manager and no `runs` row, so the placeholder is\n * never expanded. Run-id columns FK `runs(n)`, so the only correct\n * value is \"unset\" — we drop the key (the augmented MCP bridge maps\n * a missing/empty AGT_RUN_ID to a null run id; leaving the literal\n * would leak a bogus non-empty run id into broker calls).\n *\n * Pure function (no I/O); the caller (`impersonateConnectCommand`) does\n * the file-write. Exported for unit tests.\n */\n\nexport interface ImpersonationMcpRewriteContext {\n /** `process.env.HOME` on the operator's machine. */\n operatorHome: string;\n /**\n * ENG-5818: a host-correct `PATH` for the operator's machine, used to\n * overwrite the server-baked (Lambda) PATH so `command: \"node\"` resolves.\n * The caller builds this from the running node's bin dir prepended to\n * the operator's own `process.env.PATH` (see `resolveOperatorPath` in\n * commands/impersonate.ts).\n */\n operatorPath: string;\n /**\n * Absolute path to the CLI's bundled `dist/mcp/` directory (which\n * holds index.js / slack-channel.js / telegram-channel.js /\n * direct-chat-channel.js via build:mcp-assets). The caller resolves\n * this from `import.meta.url` at runtime.\n */\n cliMcpBundleDir: string;\n /** Impersonation JWT (`bundle.token`). Legacy host-key-slot credential. */\n impersonationToken: string;\n /**\n * ENG-5874: the portable agent-session token (`bundle.agent_session_token`)\n * the augmented MCP server presents directly as Bearer (skipping\n * /host/exchange, which 401s the impersonation JWT). Null for pre-org teams /\n * a non-fatal redeem-side mint failure — the server then falls back to the\n * (broken-for-impersonation) host-key path.\n */\n agentSessionToken: string | null;\n /** API host the redeem was exchanged against (e.g. `https://api.augmented.team`). */\n apiHost: string;\n /** The impersonated agent's UUID. */\n agentId: string;\n /** The impersonated agent's `code_name`. */\n agentCodeName: string;\n}\n\n/** Matches `/home/<anything-not-slash>/.augmented/_mcp/<filename>`. */\nconst SERVER_HOME_MCP_PATH_RE =\n /^\\/home\\/[^/]+\\/\\.augmented\\/_mcp\\/([^/]+)$/;\n\n/**\n * ENG-5953 — server keys whose entries are channel MCP servers (Slack /\n * Telegram / Teams / Direct Chat / Discord), injected by the redeem flow\n * for an agent's configured channels. We stamp `AGT_ACT_AS_AGENT_ID` onto\n * their env so the ENG-5689 egress gate (`isImpersonating()` in\n * packages/mcp/src/impersonation.ts) fails CLOSED — channel sends stay\n * refused-by-default — even if Claude Code ever stops passing the launch\n * env (`buildImpersonateClaudeLaunch` sets the same var) through to MCP\n * children. The operator still opts in to sends with\n * `ENABLE_IMPERSONATION_CHANNELS=true`, which flows in via that same\n * inherited env.\n */\nconst CHANNEL_SERVER_KEYS = new Set([\n 'slack',\n 'telegram',\n 'msteams',\n 'direct-chat',\n 'discord',\n]);\n\n/**\n * Rewrite the persona `.mcp.json` so the operator's local Claude Code\n * can spawn the MCP servers. Returns a new JSON string; never mutates\n * the input. Throws if the input isn't valid JSON or doesn't have an\n * object-typed `mcpServers` field — the caller already validated the\n * redeem response shape, so a throw here means the server changed its\n * contract.\n */\nexport function rewriteMcpJsonForImpersonation(\n mcpJson: string,\n ctx: ImpersonationMcpRewriteContext,\n): string {\n const parsed = JSON.parse(mcpJson) as unknown;\n if (!isPlainObject(parsed)) {\n throw new Error(\n `rewriteMcpJsonForImpersonation: expected an object at the JSON root, got ${typeof parsed}`,\n );\n }\n const servers = parsed['mcpServers'];\n if (!isPlainObject(servers)) {\n throw new Error(\n 'rewriteMcpJsonForImpersonation: expected an object-typed `mcpServers` field',\n );\n }\n\n const rewrittenServers: Record<string, unknown> = {};\n for (const [serverName, raw] of Object.entries(servers)) {\n rewrittenServers[serverName] = rewriteServerEntry(serverName, raw, ctx);\n }\n\n const out = { ...parsed, mcpServers: rewrittenServers };\n return JSON.stringify(out, null, 2);\n}\n\nfunction rewriteServerEntry(\n serverName: string,\n raw: unknown,\n ctx: ImpersonationMcpRewriteContext,\n): unknown {\n if (!isPlainObject(raw)) return raw;\n\n // ── args: replace any /home/<x>/.augmented/_mcp/<file> with the\n // operator's CLI bundle dir.\n let args = raw['args'];\n if (Array.isArray(args)) {\n args = args.map((arg) => {\n if (typeof arg !== 'string') return arg;\n const m = SERVER_HOME_MCP_PATH_RE.exec(arg);\n if (!m) return arg;\n return `${ctx.cliMcpBundleDir}/${m[1]}`;\n });\n }\n\n // ── env: fill empty/missing impersonation-time values without\n // clobbering anything the server explicitly populated.\n const env = isPlainObject(raw['env']) ? { ...raw['env'] } : {};\n fillIfEmpty(env, 'AGT_HOST', ctx.apiHost);\n fillIfEmpty(env, 'AGT_API_KEY', ctx.impersonationToken);\n // ENG-5874: the augmented MCP server prefers this token (used directly as\n // Bearer) over AGT_API_KEY. Only set when redeem returned one.\n if (ctx.agentSessionToken) {\n fillIfEmpty(env, 'AGT_AGENT_SESSION_TOKEN', ctx.agentSessionToken);\n }\n fillIfEmpty(env, 'HOME', ctx.operatorHome);\n fillIfEmpty(env, 'AGT_AGENT_ID', ctx.agentId);\n fillIfEmpty(env, 'AGT_AGENT_CODE_NAME', ctx.agentCodeName);\n\n // ── ENG-5818 Bug 1: force a host-correct PATH ────────────────────────\n // The server bakes its own runtime PATH (Lambda PATH on the redeem\n // Lambda). It's never right for the operator, so overwrite it\n // unconditionally rather than only-if-empty. Only do so when the\n // server actually emitted a PATH key — a server entry with no PATH\n // inherits the spawn PATH, which is already correct.\n if ('PATH' in env) {\n env['PATH'] = ctx.operatorPath;\n }\n\n // ── ENG-5818 Bug 3: drop the unsubstituted AGT_RUN_ID placeholder ────\n // No manager + no `runs` row in an impersonation session, so the\n // `${AGT_RUN_ID}` sentinel is never expanded. Run-id columns FK\n // runs(n); the only correct value is \"unset\". Dropping the key lets\n // consumers fall back to their null-run behaviour instead of treating\n // the literal placeholder as a (truthy, bogus) run id.\n if (env['AGT_RUN_ID'] === '${AGT_RUN_ID}') {\n delete env['AGT_RUN_ID'];\n }\n\n // ── ENG-5953: fail-closed impersonation marker on channel servers ────\n // Set unconditionally (not fillIfEmpty) so the egress gate engages even\n // if a future redeem build emitted a stale value. Scoped to channel\n // server keys so the `augmented` gateway + native integrations are\n // untouched.\n if (CHANNEL_SERVER_KEYS.has(serverName)) {\n env['AGT_ACT_AS_AGENT_ID'] = ctx.agentId;\n }\n\n return { ...raw, args, env };\n}\n\n/**\n * Set `env[key] = value` when the current value is missing/empty — or\n * when it is the key's own literal `${KEY}` placeholder. ENG-5901\n * Track D: the server now renders secrets (AGT_API_KEY et al.) as\n * `${VAR}` templates for the manager's spawn env to satisfy; an\n * impersonation session has no manager env, and Claude Code hard-fails\n * config parse on an unset defaultless `${VAR}`, so the self-placeholder\n * must be treated as fillable here. Pre-populated concrete values are\n * still never overwritten.\n */\nfunction fillIfEmpty(\n env: Record<string, unknown>,\n key: string,\n value: string,\n): void {\n const current = env[key];\n if (\n typeof current !== 'string' ||\n current.length === 0 ||\n current === `\\${${key}}`\n ) {\n env[key] = value;\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectDrift,\n getFramework,\n type DriftReport,\n type DriftFinding,\n type RiskTier,\n} from '@augmented/core';\nimport { readLiveState } from '@augmented/core/drift/live-state-reader.js';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info, table } from '../lib/output.js';\nimport { isJsonMode } from '../lib/globals.js';\n\nconst KEBAB_CASE_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;\n\nfunction severityColor(severity: string): string {\n switch (severity) {\n case 'critical':\n return chalk.red(severity);\n case 'warning':\n return chalk.yellow(severity);\n default:\n return chalk.dim(severity);\n }\n}\n\nfunction printDriftReport(report: DriftReport): void {\n console.log(chalk.bold(`\\nDrift Report: ${report.codeName}\\n`));\n\n info(`Agent ID: ${report.agentId}`);\n info(`Checked at: ${report.checkedAt.toISOString()}`);\n console.log();\n\n if (!report.hasDrift) {\n success('No drift detected. Agent matches provisioned state.');\n return;\n }\n\n warn(`Drift detected: ${report.criticalCount} critical, ${report.warningCount} warning`);\n console.log();\n\n const rows = report.findings.map((f: DriftFinding) => [\n severityColor(f.severity),\n f.category,\n f.field,\n f.message,\n ]);\n\n table(['Severity', 'Category', 'Field', 'Message'], rows);\n}\n\ninterface DriftCheckOpts {\n json?: boolean;\n audit?: boolean;\n config?: string;\n}\n\n/**\n * `agt drift check <code-name>`\n */\nexport async function driftCheckCommand(\n codeName: string,\n opts: DriftCheckOpts,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n if (!KEBAB_CASE_RE.test(codeName)) {\n error('Invalid code-name. Must be kebab-case (e.g. \"my-agent\").');\n process.exitCode = 1;\n return;\n }\n\n const useJson = opts.json || isJsonMode();\n\n const spinner = ora({ text: `Checking drift for \"${codeName}\"…`, isSilent: useJson });\n spinner.start();\n\n try {\n // Fetch drift data via API\n const driftData = await api.get<{\n agent: Record<string, unknown>;\n snapshot: Record<string, unknown> | null;\n charter: { raw_content: string; version: string } | null;\n tools: { raw_content: string; version: string } | null;\n }>(`/agents/${encodeURIComponent(codeName)}/drift-data`);\n\n const agent = driftData.agent;\n const snapshot = driftData.snapshot;\n\n if (!snapshot) {\n spinner.fail(`No provision snapshot found for \"${codeName}\". Run \\`agt provision\\` first.`);\n error('No provision snapshot available');\n process.exitCode = 1;\n return;\n }\n\n // Resolve adapter from agent's framework field\n const frameworkId = (agent.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n const trackedFiles = adapter.driftTrackedFiles();\n\n // Read live state from disk (team-scoped to prevent cross-team collisions)\n const defaultDir = `.augmented/${teamSlug}/${codeName}/provision`;\n const configPath = opts.config ?? `${defaultDir}/${trackedFiles[0]}`;\n\n const liveState = await readLiveState({\n configPath,\n teamDir: defaultDir,\n trackedFiles,\n runAudit: opts.audit,\n });\n\n // Run drift detection\n const report = detectDrift(\n {\n frameworkConfig: (snapshot.openclaw_config ?? {}) as Record<string, unknown>,\n charterHash: snapshot.charter_hash as string ?? '',\n toolsHash: snapshot.tools_hash as string ?? '',\n toolAllow: snapshot.tool_allow as string[] ?? [],\n toolDeny: snapshot.tool_deny as string[] ?? [],\n channelsConfig: (snapshot.channels_config ?? {}) as Record<string, unknown>,\n sandboxMode: snapshot.sandbox_mode as string ?? 'all',\n },\n liveState,\n agent.agent_id as string,\n codeName,\n (agent.risk_tier as RiskTier) ?? 'Medium',\n );\n\n spinner.stop();\n\n if (useJson) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n printDriftReport(report);\n }\n\n if (report.hasDrift) {\n process.exitCode = 1;\n }\n } catch (err) {\n spinner.fail('Drift check failed.');\n error((err as Error).message);\n process.exitCode = 1;\n }\n}\n\ninterface DriftWatchOpts {\n interval?: string;\n webhook?: string;\n json?: boolean;\n config?: string;\n}\n\n/**\n * `agt drift watch <code-name>`\n */\nexport async function driftWatchCommand(\n codeName: string,\n opts: DriftWatchOpts,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n if (!KEBAB_CASE_RE.test(codeName)) {\n error('Invalid code-name. Must be kebab-case (e.g. \"my-agent\").');\n process.exitCode = 1;\n return;\n }\n\n const useJson = opts.json || isJsonMode();\n\n const intervalSec = parseInt(opts.interval ?? '60', 10);\n if (isNaN(intervalSec) || intervalSec < 1) {\n error('Interval must be a positive number of seconds.');\n process.exitCode = 1;\n return;\n }\n\n // Resolve agent once up front\n let agent: Record<string, unknown>;\n try {\n const data = await api.get<{ agent: Record<string, unknown> }>(`/agents/${encodeURIComponent(codeName)}`);\n agent = data.agent;\n } catch (err) {\n error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n\n // Resolve adapter from agent's framework field\n const frameworkId = (agent.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n const trackedFiles = adapter.driftTrackedFiles();\n\n if (!useJson) {\n console.log(\n chalk.bold(`\\nWatching drift for \"${codeName}\" every ${intervalSec}s. Press Ctrl+C to stop.\\n`),\n );\n }\n\n let previousFindingCount = -1;\n\n const runCheck = async (): Promise<void> => {\n const spinner = ora({ text: `Checking drift for \"${codeName}\"…`, isSilent: useJson });\n spinner.start();\n\n try {\n const driftData = await api.get<{\n snapshot: Record<string, unknown> | null;\n }>(`/agents/${encodeURIComponent(codeName)}/drift-data`);\n\n const snapshot = driftData.snapshot;\n if (!snapshot) {\n spinner.warn('No provision snapshot found. Skipping check.');\n return;\n }\n\n const watchDefaultDir = `.augmented/${teamSlug}/${codeName}/provision`;\n const configPath = opts.config ?? `${watchDefaultDir}/${trackedFiles[0]}`;\n\n const liveState = await readLiveState({\n configPath,\n teamDir: watchDefaultDir,\n trackedFiles,\n });\n\n const report = detectDrift(\n {\n frameworkConfig: (snapshot.openclaw_config ?? {}) as Record<string, unknown>,\n charterHash: snapshot.charter_hash as string ?? '',\n toolsHash: snapshot.tools_hash as string ?? '',\n toolAllow: snapshot.tool_allow as string[] ?? [],\n toolDeny: snapshot.tool_deny as string[] ?? [],\n channelsConfig: (snapshot.channels_config ?? {}) as Record<string, unknown>,\n sandboxMode: snapshot.sandbox_mode as string ?? 'all',\n },\n liveState,\n agent.agent_id as string,\n codeName,\n (agent.risk_tier as RiskTier) ?? 'Medium',\n );\n\n spinner.stop();\n\n const isNew = report.findings.length !== previousFindingCount;\n previousFindingCount = report.findings.length;\n\n if (useJson) {\n console.log(JSON.stringify(report, null, 2));\n } else if (report.hasDrift) {\n printDriftReport(report);\n } else {\n success(`[${new Date().toLocaleTimeString()}] No drift detected.`);\n }\n\n if (isNew && report.hasDrift && opts.webhook) {\n try {\n await fetch(opts.webhook, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(report),\n });\n if (!useJson) info(`Webhook notified: ${opts.webhook}`);\n } catch (webhookErr) {\n if (!useJson) warn(`Failed to notify webhook: ${(webhookErr as Error).message}`);\n }\n }\n } catch (err) {\n spinner.fail('Drift check failed.');\n error((err as Error).message);\n }\n };\n\n await runCheck();\n\n const timer = setInterval(() => {\n void runCheck();\n }, intervalSec * 1000);\n\n process.on('SIGINT', () => {\n clearInterval(timer);\n if (!useJson) console.log(chalk.dim('\\nStopped watching.'));\n process.exit(0);\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { join } from 'node:path';\nimport JSON5 from 'json5';\nimport type { DriftCheckOptions, LiveState } from './types.js';\n\nasync function hashFile(filePath: string): Promise<string | null> {\n try {\n const content = await readFile(filePath);\n return createHash('sha256').update(content).digest('hex');\n } catch {\n return null;\n }\n}\n\nasync function readJsonFile(filePath: string): Promise<Record<string, unknown> | null> {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON5.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function readLiveState(options: DriftCheckOptions): Promise<LiveState> {\n const trackedFiles = options.trackedFiles ?? ['openclaw.json5', 'CHARTER.md', 'TOOLS.md'];\n\n // Config file is the first tracked file (framework-specific config)\n // CHARTER.md and TOOLS.md are identified by name within the tracked list\n const charterFile = trackedFiles.find((f) => f.includes('CHARTER')) ?? 'CHARTER.md';\n const toolsFile = trackedFiles.find((f) => f.includes('TOOLS')) ?? 'TOOLS.md';\n\n const [frameworkConfig, charterHash, toolsHash] = await Promise.all([\n readJsonFile(options.configPath),\n hashFile(join(options.teamDir, charterFile)),\n hashFile(join(options.teamDir, toolsFile)),\n ]);\n\n return {\n frameworkConfig,\n charterHash,\n toolsHash,\n configPath: options.configPath,\n };\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api, getHostId } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// agt host list\n// ---------------------------------------------------------------------------\n\nexport async function hostListCommand(): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching hosts\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n hosts: Array<{\n name: string;\n status: string;\n description: string | null;\n framework: string;\n agents: number;\n last_seen_at: string | null;\n key_prefix: string | null;\n created_at: string;\n }>;\n }>('/hosts');\n\n spinner.stop();\n\n if (!data.hosts || data.hosts.length === 0) {\n if (json) {\n jsonOutput({ ok: true, hosts: [] });\n } else {\n info('No hosts found. Create one with `agt host create --name <name>`.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, hosts: data.hosts });\n return;\n }\n\n const rows = data.hosts.map((h) => {\n const status = h.status === 'active'\n ? chalk.green('active')\n : chalk.red('decommissioned');\n\n const agents = String(h.agents);\n\n const lastSeen = h.last_seen_at\n ? new Date(h.last_seen_at).toLocaleDateString()\n : chalk.dim('never');\n\n const prefix = h.key_prefix\n ? `tlk_${h.key_prefix}\\u2026`\n : chalk.dim('none');\n\n return [h.name, status, agents, lastSeen, prefix];\n });\n\n table(['Name', 'Status', 'Agents', 'Last Seen', 'Key'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch hosts.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host assign\n// ---------------------------------------------------------------------------\n\ninterface HostAssignOptions {\n force?: boolean;\n}\n\nexport async function hostAssignCommand(\n hostName: string,\n agentCodeNames: string[],\n opts: HostAssignOptions,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!agentCodeNames || agentCodeNames.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'At least one agent code name is required' });\n } else {\n error('At least one agent code name is required.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Assigning agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/assign`, {\n agents: agentCodeNames,\n force: opts.force,\n });\n\n spinner.succeed(`Agents assigned to ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({ ok: true, host: hostName, assigned: agentCodeNames });\n return;\n }\n\n for (const name of agentCodeNames) {\n info(` ${name}`);\n }\n } catch (err) {\n spinner.fail('Failed to assign agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host unassign\n// ---------------------------------------------------------------------------\n\nexport async function hostUnassignCommand(\n hostName: string,\n agentCodeNames: string[],\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!agentCodeNames || agentCodeNames.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'At least one agent code name is required' });\n } else {\n error('At least one agent code name is required.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Unassigning agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/unassign`, {\n agents: agentCodeNames,\n });\n\n spinner.succeed(`Agents unassigned from ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({ ok: true, host: hostName, unassigned: agentCodeNames });\n return;\n }\n\n for (const name of agentCodeNames) {\n info(` ${name}`);\n }\n } catch (err) {\n spinner.fail('Failed to unassign agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host agents [host-name]\n// ---------------------------------------------------------------------------\n\nexport async function hostAgentsCommand(hostName?: string): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching host agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n // If no host name given, use the API key's host identity via /host/agents\n const hostId = await getHostId();\n\n if (!hostName && !hostId) {\n spinner.fail('No host specified.');\n if (json) {\n jsonOutput({ ok: false, error: 'Provide a host name or use an AGT_API_KEY' });\n } else {\n error('Provide a host name, or set AGT_API_KEY to auto-resolve the host.');\n }\n process.exitCode = 1;\n return;\n }\n\n let agents: Array<{\n code_name: string;\n display_name: string;\n status: string;\n environment: string;\n risk_tier?: string;\n assigned_at?: string;\n }>;\n\n if (hostId && !hostName) {\n // Host runtime path — resolve from API key\n const data = await api.post<{\n agents: typeof agents;\n }>('/host/agents', { host_id: hostId });\n agents = data.agents ?? [];\n } else {\n // Dashboard path — look up by name\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const data = await api.get<{\n agents: typeof agents;\n }>(`/hosts/${encodeURIComponent(hostName!)}/agents`);\n agents = data.agents ?? [];\n }\n\n spinner.stop();\n\n if (agents.length === 0) {\n if (json) {\n jsonOutput({ ok: true, agents: [] });\n } else {\n info('No agents assigned to this host.');\n info('Assign agents with `agt host assign <host-name> <agent-code-name>`.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, agents });\n return;\n }\n\n const rows = agents.map((a) => {\n const statusColor = a.status === 'active' ? chalk.green : chalk.yellow;\n return [\n a.code_name,\n a.display_name,\n statusColor(a.status),\n a.environment,\n ];\n });\n\n table(['Code Name', 'Display Name', 'Status', 'Environment'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch host agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host rotate-key\n// ---------------------------------------------------------------------------\n\nexport async function hostRotateKeyCommand(hostName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Rotating host key\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.post<{\n ok: boolean;\n host: string;\n key: { prefix: string; raw_key: string };\n }>(`/hosts/${encodeURIComponent(hostName)}/rotate-key`);\n\n spinner.succeed(`Key rotated for ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n host: hostName,\n key: data.key,\n });\n return;\n }\n\n console.log();\n info(`Host: ${chalk.bold(hostName)}`);\n info(`Prefix: ${data.key.prefix}`);\n console.log();\n console.log(chalk.yellow.bold(' Save this key now \\u2014 it will not be shown again:'));\n console.log();\n console.log(` ${chalk.green.bold(data.key.raw_key)}`);\n console.log();\n } catch (err) {\n spinner.fail('Failed to rotate key.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host maintenance-window\n// ---------------------------------------------------------------------------\n\ninterface HostMaintenanceWindowOptions {\n start?: string;\n end?: string;\n tz?: string;\n clear?: boolean;\n}\n\ninterface MaintenanceWindowResponse {\n override: {\n maintenance_window_start: string | null;\n maintenance_window_end: string | null;\n maintenance_timezone: string | null;\n };\n effective: { start: string; end: string; timezone: string };\n}\n\nexport async function hostMaintenanceWindowCommand(\n hostName: string,\n opts: HostMaintenanceWindowOptions,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const path = `/hosts/${encodeURIComponent(hostName)}/maintenance-window`;\n const setting =\n opts.clear || opts.start !== undefined || opts.end !== undefined || opts.tz !== undefined;\n\n // Show mode — no set flags.\n if (!setting) {\n const spinner = ora({ text: 'Fetching maintenance window…', isSilent: json });\n spinner.start();\n try {\n const data = await api.get<MaintenanceWindowResponse>(path);\n spinner.stop();\n if (json) {\n jsonOutput({ ok: true, ...data });\n return;\n }\n const ov = data.override;\n const hasOverride =\n ov.maintenance_window_start !== null ||\n ov.maintenance_window_end !== null ||\n ov.maintenance_timezone !== null;\n info(`Host: ${chalk.bold(hostName)}`);\n info(\n `Effective: ${chalk.green(`${data.effective.start}–${data.effective.end}`)} ${data.effective.timezone}`,\n );\n info(\n `Override: ${hasOverride ? chalk.cyan('set') : chalk.dim('none (default 01:00–02:00)')}`,\n );\n info('Set with --start/--end/--tz, or --clear to follow the default.');\n } catch (err) {\n spinner.fail('Failed to fetch maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n }\n return;\n }\n\n // Set/clear mode. Require both --start and --end together (the window needs\n // both bounds; clearing one without the other is ambiguous).\n // --clear is exclusive: combining it with set flags is contradictory, and\n // silently honouring --clear while ignoring --start/--end/--tz would do the\n // opposite of what the operator likely intended. Fail fast.\n if (opts.clear && (opts.start !== undefined || opts.end !== undefined || opts.tz !== undefined)) {\n const msg = 'Use --clear on its own — it cannot be combined with --start/--end/--tz.';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n if (!opts.clear && (opts.start === undefined) !== (opts.end === undefined)) {\n const msg = 'Provide both --start and --end (or use --clear).';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n // A timezone without time bounds is meaningless — reject --tz on its own.\n if (!opts.clear && opts.tz !== undefined && opts.start === undefined) {\n const msg = 'Provide --start and --end when setting --tz (or use --clear).';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // When setting times without an explicit --tz, preserve the host's existing\n // timezone override rather than silently clearing it (the API replaces all\n // three fields, so we must send the current tz to keep it).\n let resolvedTz: string | null = opts.tz ?? null;\n if (!opts.clear && opts.tz === undefined) {\n try {\n const cur = await api.get<MaintenanceWindowResponse>(path);\n resolvedTz = cur.override.maintenance_timezone;\n } catch (err) {\n const spinner0 = ora({ isSilent: json });\n spinner0.fail('Failed to read current maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n }\n\n const payload = opts.clear\n ? { maintenance_window_start: null, maintenance_window_end: null, maintenance_timezone: null }\n : {\n maintenance_window_start: opts.start ?? null,\n maintenance_window_end: opts.end ?? null,\n maintenance_timezone: resolvedTz,\n };\n\n const spinner = ora({ text: 'Updating maintenance window…', isSilent: json });\n spinner.start();\n try {\n const data = await api.post<{\n maintenance_window: { start: string | null; end: string | null; timezone: string | null };\n note?: string;\n }>(path, payload);\n spinner.succeed(`Maintenance window updated for ${chalk.bold(hostName)}.`);\n if (json) {\n jsonOutput({ ok: true, ...data });\n return;\n }\n if (data.note) info(data.note);\n } catch (err) {\n spinner.fail('Failed to update maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host decommission\n// ---------------------------------------------------------------------------\n\nexport async function hostDecommissionCommand(hostName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Decommissioning host\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/decommission`);\n\n spinner.succeed(`Host \"${chalk.bold(hostName)}\" decommissioned.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n host: hostName,\n status: 'decommissioned',\n });\n return;\n }\n\n info(`Host: ${hostName}`);\n info(`Status: ${chalk.red('decommissioned')}`);\n info('API key revoked. Agents remain assigned for audit visibility.');\n info('Reassign agents to another host with `agt host assign --force`.');\n } catch (err) {\n spinner.fail('Failed to decommission host.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { spawn, spawnSync, type ChildProcess } from 'node:child_process';\nimport chalk from 'chalk';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { error, info, success } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface HostDetail {\n id: string;\n name: string;\n status: string;\n framework: string;\n provision_source: 'self' | 'augmented-ec2' | null;\n ec2_instance_id: string | null;\n ec2_region: string | null;\n claude_auth_mode: string | null;\n claude_auth_status: string | null;\n claude_auth_expires_at: string | null;\n}\n\n/**\n * agt host pair <name>\n *\n * Orchestrates a Claude Code `/login` flow on a remote EC2 host by:\n * 1. Looking up the host's EC2 instance ID via the API\n * 2. Starting an SSM port-forward tunnel on a chosen local port\n * 3. Opening an interactive SSM shell session on the remote host\n *\n * The operator then runs `claude /login` inside the shell, clicks the URL\n * Claude Code prints, completes OAuth in the browser — the callback lands on\n * localhost:<port>, which tunnels through SSM to the host's loopback where\n * Claude Code is listening.\n *\n * When the operator exits the shell (Ctrl+D), the port-forward tunnel is\n * torn down.\n *\n * Prerequisites on the operator's machine:\n * - AWS CLI v2 with credentials scoped to the host AWS account\n * - session-manager-plugin installed\n * (brew install --cask session-manager-plugin)\n *\n * Note on port matching:\n * Claude Code picks an OAuth callback port dynamically. For the forwarded\n * port to receive the callback, ensure Claude Code binds to the same port\n * as --port (or set CLAUDE_CODE_OAUTH_PORT on the host). If the ports\n * don't match, the OAuth callback won't reach the host.\n */\nexport async function hostPairCommand(\n name: string,\n opts: { port?: string; noShell?: boolean }\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const localPort = Number(opts.port ?? '54545');\n\n if (!Number.isInteger(localPort) || localPort < 1024 || localPort > 65535) {\n error('--port must be an integer between 1024 and 65535');\n process.exitCode = 1;\n return;\n }\n\n // Fetch host detail — we need the EC2 instance ID\n let host: HostDetail;\n try {\n const data = await api.get<{ host: HostDetail }>(`/hosts/${encodeURIComponent(name)}`);\n host = data.host;\n } catch (err) {\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error(`Failed to look up host: ${(err as Error).message}`);\n process.exitCode = 1;\n return;\n }\n\n if (host.provision_source !== 'augmented-ec2') {\n const msg = `Host \"${name}\" is ${host.provision_source ?? 'self'}-provisioned, not an Augmented-managed EC2. ` +\n `agt host pair is only for EC2 hosts provisioned through the Augmented API.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n if (!host.ec2_instance_id) {\n const msg = `Host \"${name}\" has no EC2 instance ID yet. Provision it first with \\`agt host provision\\`.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n const region = host.ec2_region ?? process.env.AWS_REGION ?? 'us-east-2';\n const instanceId = host.ec2_instance_id;\n\n // Preflight: aws + session-manager-plugin\n const preflightErr = preflightAws();\n if (preflightErr) {\n if (json) jsonOutput({ ok: false, error: preflightErr });\n else error(preflightErr);\n process.exitCode = 1;\n return;\n }\n\n if (json) {\n // JSON mode: emit the tunnel parameters, caller orchestrates the shell\n jsonOutput({\n ok: true,\n host: { name: host.name, id: host.id, instance_id: instanceId, region },\n port_forward: {\n command: 'aws',\n args: [\n 'ssm', 'start-session',\n '--region', region,\n '--target', instanceId,\n '--document-name', 'AWS-StartPortForwardingSession',\n '--parameters', JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] }),\n ],\n },\n shell: {\n command: 'aws',\n args: ['ssm', 'start-session', '--region', region, '--target', instanceId],\n },\n });\n return;\n }\n\n info(`Pairing Claude Code on ${chalk.bold(name)} (${instanceId}, ${region})`);\n info(`Local port ${chalk.cyan(String(localPort))} will be forwarded to the host.`);\n console.log();\n console.log(chalk.dim('In the shell that opens, run:'));\n console.log(` ${chalk.cyan(`CLAUDE_CODE_OAUTH_PORT=${localPort} claude /login`)}`);\n console.log(chalk.dim('Then click the printed URL on this machine. The OAuth callback'));\n console.log(chalk.dim(`will reach Claude Code via the port-forward tunnel.`));\n console.log();\n console.log(chalk.dim('Exit the shell (Ctrl+D) when Claude Code reports successful login.'));\n console.log();\n\n // Start the port-forward tunnel in the background\n const tunnel = spawn(\n 'aws',\n [\n 'ssm', 'start-session',\n '--region', region,\n '--target', instanceId,\n '--document-name', 'AWS-StartPortForwardingSession',\n '--parameters',\n JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] }),\n ],\n { stdio: ['ignore', 'pipe', 'pipe'] }\n );\n\n // Surface tunnel errors but don't crash — often it reports \"Waiting for connections...\"\n tunnel.stderr?.on('data', (buf) => {\n const line = buf.toString().trim();\n if (line.startsWith('An error occurred')) {\n console.error(chalk.red(`[tunnel] ${line}`));\n }\n });\n\n // Give the tunnel ~1.5s to establish before launching the interactive shell\n await new Promise((r) => setTimeout(r, 1500));\n\n if (tunnel.exitCode !== null) {\n error('Port-forward tunnel failed to start. Check AWS credentials and session-manager-plugin.');\n process.exitCode = 1;\n return;\n }\n\n // Launch the interactive shell — inherits stdio so the user gets a real TTY.\n // --no-shell: keep the tunnel up in the foreground and wait for SIGINT.\n if (opts.noShell) {\n console.log(chalk.dim('--no-shell set; tunnel is running. Press Ctrl+C to exit.'));\n await new Promise<void>((resolve) => {\n const onSignal = () => {\n terminate(tunnel);\n resolve();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n });\n } else {\n await runInteractive('aws', ['ssm', 'start-session', '--region', region, '--target', instanceId]);\n // User exited the shell — tear the tunnel down\n terminate(tunnel);\n }\n\n success('Pair session ended.');\n}\n\nfunction preflightAws(): string | null {\n const aws = spawnSync('aws', ['--version'], { stdio: 'ignore' });\n if (aws.status !== 0) {\n return 'AWS CLI not found. Install: https://aws.amazon.com/cli/';\n }\n const plugin = spawnSync('session-manager-plugin', [], { stdio: 'ignore' });\n // session-manager-plugin exits non-zero when called without a session, but it exists if the spawn succeeded\n if (plugin.error) {\n return 'session-manager-plugin not found. Install: brew install --cask session-manager-plugin';\n }\n return null;\n}\n\nfunction runInteractive(cmd: string, args: string[]): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, { stdio: 'inherit' });\n child.on('exit', (code) => resolve(code ?? 0));\n child.on('error', () => resolve(1));\n });\n}\n\nfunction terminate(child: ChildProcess) {\n if (child.exitCode !== null) return;\n try {\n child.kill('SIGTERM');\n } catch {\n // process may already be gone\n }\n}\n","import React, { useEffect, useState, useMemo } from 'react';\nimport { render, Box, Text, useApp, useInput } from 'ink';\nimport { existsSync, readFileSync, statSync, openSync, readSync, closeSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ManagerStatus } from '../lib/watchdog.js';\nimport { getManagerPaths } from '../lib/watchdog.js';\n\n// ENG-4555: TUI dashboard for the manager. Reads ~/.augmented/manager-state.json\n// (already maintained by manager-worker.ts:880) and tails ~/.augmented/manager.log\n// so users can observe a running manager without watching log lines scroll past.\n//\n// Read-only in v1 — no agent-level actions (restart/pause/etc). Falls back to a\n// log-streaming message if stdout is not a TTY (CI, scripts) since Ink's full-screen\n// rendering can't function without raw input mode.\n\ninterface ManagerWatchOptions {\n configDir?: string;\n noTui?: boolean;\n}\n\nconst REFRESH_MS = 1000;\nconst LOG_TAIL_LINES = 200;\nconst DETAIL_RECENT_LINES = 50;\n\nexport function managerWatchCommand(opts: ManagerWatchOptions = {}): void {\n const configDir = opts.configDir ?? join(homedir(), '.augmented');\n const paths = getManagerPaths(configDir);\n\n // Non-TTY environments (CI, piped output) can't run a TUI — Ink relies on\n // raw stdin and ANSI cursor control. Fall back to log streaming so the\n // command still produces useful output when scripted.\n const isTty = process.stdout.isTTY === true && process.stdin.isTTY === true;\n if (opts.noTui || !isTty) {\n streamLogFile(paths.logFile);\n return;\n }\n\n // Switch to the terminal's alternate screen buffer (like vim/htop/less) so\n // the TUI takes over the whole window and the user's scrollback is restored\n // verbatim on exit. \\x1b[?1049h enters the alt buffer + clears it,\n // \\x1b[?1049l restores the prior buffer. Hide the cursor while we render\n // (\\x1b[?25l) and re-show on exit (\\x1b[?25h) so it doesn't blink under\n // selected boxes.\n process.stdout.write('\\x1b[?1049h\\x1b[H\\x1b[?25l');\n const restore = (): void => { process.stdout.write('\\x1b[?25h\\x1b[?1049l'); };\n\n // Restore on every exit path: clean exit (waitUntilExit resolves), thrown\n // exception, SIGINT/SIGTERM mid-render, or hard-quit on Ctrl-C. Without\n // this the user's terminal stays on the alt buffer with the cursor hidden.\n const onSignal = (): void => { restore(); process.exit(0); };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', restore);\n\n const { waitUntilExit } = render(<Dashboard stateFile={paths.stateFile} logFile={paths.logFile} />);\n waitUntilExit().catch(() => { /* ignore */ }).finally(restore);\n}\n\n// ---------------------------------------------------------------------------\n// State + log readers\n// ---------------------------------------------------------------------------\n\nfunction readState(stateFile: string): ManagerStatus | null {\n try {\n if (!existsSync(stateFile)) return null;\n const raw = readFileSync(stateFile, 'utf-8');\n return JSON.parse(raw) as ManagerStatus;\n } catch {\n return null;\n }\n}\n\n// Tail the last N lines of a log file. Reads only the trailing window so this\n// stays cheap even when the log grows to many MB. Returns lines oldest-first.\nfunction tailLogFile(logFile: string, lines: number): string[] {\n if (!existsSync(logFile)) return [];\n try {\n const fileSize = statSync(logFile).size;\n if (fileSize === 0) return [];\n // Heuristic: ~200 chars/line average — we read 4× headroom and slice. For\n // the manager log this comfortably fits the requested tail in one read.\n const readSize = Math.min(fileSize, lines * 800);\n const fd = openSync(logFile, 'r');\n try {\n const buf = Buffer.alloc(readSize);\n readSync(fd, buf, 0, readSize, fileSize - readSize);\n const text = buf.toString('utf-8');\n const all = text.split('\\n').filter((l) => l.length > 0);\n return all.slice(-lines);\n } finally {\n closeSync(fd);\n }\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Ink components\n// ---------------------------------------------------------------------------\n\ninterface DashboardProps {\n stateFile: string;\n logFile: string;\n}\n\nconst Dashboard: React.FC<DashboardProps> = ({ stateFile, logFile }) => {\n const { exit } = useApp();\n const [status, setStatus] = useState<ManagerStatus | null>(() => readState(stateFile));\n const [logLines, setLogLines] = useState<string[]>(() => tailLogFile(logFile, LOG_TAIL_LINES));\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [view, setView] = useState<'grid' | 'detail'>('grid');\n const [tick, setTick] = useState(0);\n\n // Refresh state + log tail on a fixed cadence. We don't use fs.watch because\n // the manager rewrites the state file atomically and watch events on macOS\n // are notoriously chatty/unreliable for that pattern.\n useEffect(() => {\n const id = setInterval(() => {\n setStatus(readState(stateFile));\n setLogLines(tailLogFile(logFile, LOG_TAIL_LINES));\n setTick((t) => t + 1);\n }, REFRESH_MS);\n return () => clearInterval(id);\n }, [stateFile, logFile]);\n\n const agents = status?.agents ?? [];\n const selected = agents[selectedIndex];\n\n useInput((input, key) => {\n // Detail view owns 'q' first — pressing 'q' there means \"back to grid\",\n // not \"quit the app\". Only the grid view treats bare 'q' as exit. Ctrl-C\n // remains a hard-quit in either view because users universally expect it.\n if (view === 'detail') {\n if (key.escape || input === 'q') setView('grid');\n else if (key.ctrl && input === 'c') exit();\n return;\n }\n if (input === 'q' || (key.ctrl && input === 'c')) {\n exit();\n return;\n }\n if (agents.length === 0) return;\n if (key.upArrow || key.leftArrow) {\n setSelectedIndex((i) => (i - 1 + agents.length) % agents.length);\n } else if (key.downArrow || key.rightArrow) {\n setSelectedIndex((i) => (i + 1) % agents.length);\n } else if (key.return) {\n setView('detail');\n }\n });\n\n if (!status) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text bold color=\"yellow\">⚠ Manager state not found</Text>\n <Text> </Text>\n <Text>Looked for: <Text color=\"gray\">{stateFile}</Text></Text>\n <Text> </Text>\n <Text>Start the manager first: <Text color=\"cyan\">agt manager start</Text></Text>\n <Text dimColor>Press <Text color=\"white\">q</Text> to quit.</Text>\n </Box>\n );\n }\n\n if (view === 'detail' && selected) {\n return <DetailView agent={selected} logLines={logLines} />;\n }\n\n return <GridView status={status} agents={agents} selectedIndex={selectedIndex} logLines={logLines} tick={tick} />;\n};\n\n// ---------------------------------------------------------------------------\n// Grid view — one box per agent\n// ---------------------------------------------------------------------------\n\ninterface GridViewProps {\n status: ManagerStatus;\n agents: ManagerStatus['agents'];\n selectedIndex: number;\n logLines: string[];\n tick: number;\n}\n\nconst GridView: React.FC<GridViewProps> = ({ status, agents, selectedIndex, logLines, tick }) => {\n const lastLogLine = logLines[logLines.length - 1] ?? '';\n return (\n <Box flexDirection=\"column\">\n <HeaderBar status={status} tick={tick} />\n {agents.length === 0 ? (\n <Box padding={1}>\n <Text dimColor>No agents discovered yet. Manager is polling…</Text>\n </Box>\n ) : (\n <Box flexDirection=\"row\" flexWrap=\"wrap\" paddingX={1}>\n {agents.map((agent, i) => (\n <AgentBox\n key={agent.agentId}\n agent={agent}\n selected={i === selectedIndex}\n recentLogLine={mostRecentLineForAgent(logLines, agent.codeName)}\n />\n ))}\n </Box>\n )}\n <Footer tail={lastLogLine} />\n </Box>\n );\n};\n\nconst HeaderBar: React.FC<{ status: ManagerStatus; tick: number }> = ({ status, tick }) => {\n // The tick counter forces a redraw every refresh so the \"last poll\" relative\n // time stays current even when nothing else changed. Reading `tick` here is\n // intentional — without it React would skip the re-render.\n void tick;\n return (\n <Box paddingX={1} paddingY={0} borderStyle=\"single\" borderColor=\"cyan\">\n <Box flexDirection=\"row\" justifyContent=\"space-between\" width=\"100%\">\n <Text bold color=\"cyan\">agt manager · {status.agents.length} agent{status.agents.length === 1 ? '' : 's'}</Text>\n <Text dimColor>\n PID {status.pid} · polls {status.pollCount} · errors {status.errorCount} · last poll {relativeTime(status.lastPollAt)}\n </Text>\n </Box>\n </Box>\n );\n};\n\nconst Footer: React.FC<{ tail: string }> = ({ tail }) => (\n <Box paddingX={1} flexDirection=\"column\">\n <Box>\n <Text dimColor>↑↓ select · </Text>\n <Text dimColor>Enter detail · </Text>\n <Text dimColor>q quit</Text>\n </Box>\n {tail && (\n <Box>\n <Text dimColor>last log: </Text>\n <Text>{truncate(tail, process.stdout.columns ? process.stdout.columns - 12 : 100)}</Text>\n </Box>\n )}\n </Box>\n);\n\n// ---------------------------------------------------------------------------\n// Agent box (grid cell)\n// ---------------------------------------------------------------------------\n\ninterface AgentBoxProps {\n agent: ManagerStatus['agents'][number];\n selected: boolean;\n recentLogLine: string | null;\n}\n\nconst AgentBox: React.FC<AgentBoxProps> = ({ agent, selected, recentLogLine }) => {\n const isError = agent.status !== 'active' && agent.status !== 'paused' && agent.status !== '';\n const borderColor = selected ? 'yellow' : isError ? 'red' : 'gray';\n const statusColor = agent.status === 'active' ? 'green' : agent.status === 'paused' ? 'yellow' : isError ? 'red' : 'gray';\n const gateway = agent.gatewayRunning\n ? `:${agent.gatewayPort} (PID ${agent.gatewayPid})`\n : agent.gatewayPort\n ? `:${agent.gatewayPort} down`\n : '—';\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginRight={1} marginBottom={0} width={42}>\n <Box>\n <Text bold>{agent.codeName}</Text>\n <Text> </Text>\n <Text color={statusColor}>{agent.status || 'unknown'}</Text>\n </Box>\n <Text dimColor>charter {agent.charterVersion || '—'} · tools {agent.toolsVersion || '—'}</Text>\n <Text dimColor>gateway {gateway}</Text>\n <Text dimColor>acp sessions {agent.acpSessions?.length ?? 0}</Text>\n <Text dimColor>last provision {relativeTime(agent.lastProvisionAt)}</Text>\n {recentLogLine && (\n <Text>\n <Text color=\"cyan\">▸</Text> {truncate(recentLogLine, 36)}\n </Text>\n )}\n </Box>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Detail view — recent activity for the selected agent\n// ---------------------------------------------------------------------------\n\ninterface DetailViewProps {\n agent: ManagerStatus['agents'][number];\n logLines: string[];\n}\n\nconst DetailView: React.FC<DetailViewProps> = ({ agent, logLines }) => {\n const recent = useMemo(\n () => logLines.filter((l) => l.toLowerCase().includes(agent.codeName.toLowerCase())).slice(-DETAIL_RECENT_LINES),\n [logLines, agent.codeName],\n );\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} borderStyle=\"double\" borderColor=\"cyan\">\n <Text bold color=\"cyan\">{agent.codeName}</Text>\n <Text> · </Text>\n <Text>{agent.status || 'unknown'}</Text>\n <Text dimColor> · charter {agent.charterVersion || '—'} · tools {agent.toolsVersion || '—'}</Text>\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>Gateway</Text>\n <Text>\n {agent.gatewayRunning\n ? `running on :${agent.gatewayPort} (PID ${agent.gatewayPid})`\n : agent.gatewayPort\n ? `configured :${agent.gatewayPort} but not running`\n : 'no gateway configured'}\n </Text>\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>ACP sessions ({agent.acpSessions?.length ?? 0})</Text>\n {(agent.acpSessions ?? []).length === 0 ? (\n <Text dimColor>none</Text>\n ) : (\n (agent.acpSessions ?? []).map((s) => (\n <Text key={s.sessionId}>\n · {s.agentCommand} {s.sessionName ?? ''} · {s.queueState} · turns {s.turnCount} · started {relativeTime(s.startedAt)}\n </Text>\n ))\n )}\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>Recent activity ({recent.length} lines, filtered to \"{agent.codeName}\")</Text>\n {recent.length === 0 ? (\n <Text dimColor>nothing in the log mentions this agent yet</Text>\n ) : (\n recent.map((line, i) => (\n <Text key={i}>{truncate(line, process.stdout.columns ? process.stdout.columns - 4 : 120)}</Text>\n ))\n )}\n </Box>\n <Box paddingX={1} marginTop={1}>\n <Text dimColor>esc / q · back to grid</Text>\n </Box>\n </Box>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction mostRecentLineForAgent(lines: string[], codeName: string): string | null {\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i];\n if (line && line.toLowerCase().includes(codeName.toLowerCase())) return line;\n }\n return null;\n}\n\nfunction relativeTime(iso: string | null | undefined): string {\n if (!iso) return 'never';\n const t = new Date(iso).getTime();\n if (isNaN(t)) return 'never';\n const diff = Math.max(0, Date.now() - t);\n const sec = Math.floor(diff / 1000);\n if (sec < 60) return `${sec}s ago`;\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n return `${Math.floor(hr / 24)}d ago`;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, Math.max(0, max - 1))}…` : s;\n}\n\n// ---------------------------------------------------------------------------\n// Headless fallback — stream the log file\n// ---------------------------------------------------------------------------\n\nfunction streamLogFile(logFile: string): void {\n if (!existsSync(logFile)) {\n process.stderr.write(`No manager log found at ${logFile}.\\nStart the manager first: agt manager start\\n`);\n process.exitCode = 1;\n return;\n }\n // Print existing content, then poll for appends. Pure node — no external\n // tail-equivalent library so this works on every host the CLI ships to.\n let lastSize = 0;\n try {\n const initial = readFileSync(logFile, 'utf-8');\n process.stdout.write(initial);\n lastSize = statSync(logFile).size;\n } catch (err) {\n process.stderr.write(`Failed to read log: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n const id = setInterval(() => {\n try {\n const size = statSync(logFile).size;\n // Truncation / rotation: if the file is smaller than we last saw, the\n // log has been rotated or truncated. Reset lastSize to 0 so we resume\n // emitting from the start of the new file on the next tick (or the\n // remainder of this tick, if size > 0). Without this, every subsequent\n // append would be silently swallowed.\n if (size < lastSize) lastSize = 0;\n if (size === lastSize) return;\n const fd = openSync(logFile, 'r');\n try {\n const buf = Buffer.alloc(size - lastSize);\n readSync(fd, buf, 0, buf.length, lastSize);\n process.stdout.write(buf.toString('utf-8'));\n lastSize = size;\n } finally {\n closeSync(fd);\n }\n } catch { /* file deleted between stat and read — keep polling */ }\n }, 500);\n const stop = (): void => {\n clearInterval(id);\n process.exit(0);\n };\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n}\n","import chalk from 'chalk';\nimport JSON5 from 'json5';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n extractFrontmatter,\n getChannel,\n type CharterFrontmatter,\n type ToolsFrontmatter,\n} from '@augmented/core';\nimport { error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { api } from '../lib/api-client.js';\nimport { getApiKey } from '../lib/config.js';\n\ninterface AgentShowOptions {\n configDir: string;\n allChannels?: boolean;\n}\n\nexport async function agentShowCommand(\n codeName: string,\n opts: AgentShowOptions,\n): Promise<void> {\n const json = isJsonMode();\n // ENG-4418: both frameworks collapse to <configDir>/<codeName>/provision/\n // post-migration. This command doesn't go through the adapter, so on a\n // host where the manager hasn't polled yet the legacy\n // <codeName>/claudecode/provision/ may still be the only tree present —\n // prefer the unified path, fall back to legacy so agent show doesn't\n // report 'not found' during the migration window.\n const unifiedDir = join(opts.configDir, codeName, 'provision');\n const legacyDir = join(opts.configDir, codeName, 'claudecode', 'provision');\n const agentDir = existsSync(unifiedDir) ? unifiedDir : legacyDir;\n const hasLocalConfig = existsSync(agentDir);\n\n // ── Try API first for channel data ─────────────────────────────────────\n\n type ApiChannelConfig = {\n channel_id: string;\n config: Record<string, unknown>;\n status: string;\n };\n\n let apiChannels: ApiChannelConfig[] | null = null;\n let apiAgent: Record<string, unknown> | null = null;\n\n if (getApiKey()) {\n try {\n const data = await api.get<{\n agent: Record<string, unknown>;\n channel_configs: Record<string, { config: Record<string, unknown>; status: string }>;\n }>(`/agents/${encodeURIComponent(codeName)}/provision-data`);\n\n apiAgent = data.agent ?? null;\n\n if (data.channel_configs) {\n apiChannels = Object.entries(data.channel_configs).map(\n ([channelId, val]) => ({\n channel_id: channelId,\n config: val.config,\n status: val.status,\n }),\n );\n }\n } catch {\n // API not available or agent not found — continue with local data\n }\n }\n\n // If no local config and no API data, agent doesn't exist anywhere\n if (!hasLocalConfig && !apiAgent) {\n if (json) {\n jsonOutput({ ok: false, error: `Agent '${codeName}' not found` });\n } else {\n error(`Agent '${codeName}' not found`);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Read local files (best-effort) ────────────────────────────────────\n\n let charter: CharterFrontmatter | null = null;\n let tools: ToolsFrontmatter | null = null;\n let openclawConfig: Record<string, unknown> | null = null;\n let agentState: {\n charterVersion: string;\n toolsVersion: string;\n lastProvisionAt: string | null;\n lastDriftCheckAt: string | null;\n } | null = null;\n\n if (hasLocalConfig) {\n // CHARTER.md\n const charterPath = join(agentDir, 'CHARTER.md');\n if (existsSync(charterPath)) {\n const raw = readFileSync(charterPath, 'utf-8');\n const parsed = extractFrontmatter(raw);\n if (parsed.frontmatter) {\n charter = parsed.frontmatter as unknown as CharterFrontmatter;\n }\n }\n\n // TOOLS.md\n const toolsPath = join(agentDir, 'TOOLS.md');\n if (existsSync(toolsPath)) {\n const raw = readFileSync(toolsPath, 'utf-8');\n const parsed = extractFrontmatter(raw);\n if (parsed.frontmatter) {\n tools = parsed.frontmatter as unknown as ToolsFrontmatter;\n }\n }\n\n // openclaw.json5\n const openclawPath = join(agentDir, 'openclaw.json5');\n if (existsSync(openclawPath)) {\n try {\n const raw = readFileSync(openclawPath, 'utf-8');\n openclawConfig = JSON5.parse(raw) as Record<string, unknown>;\n } catch {\n // ignore parse errors — show what we can\n }\n }\n\n // manager-state.json\n const statePath = join(opts.configDir, 'manager-state.json');\n if (existsSync(statePath)) {\n try {\n const raw = readFileSync(statePath, 'utf-8');\n const state = JSON.parse(raw) as {\n agents: Array<{\n codeName: string;\n charterVersion: string;\n toolsVersion: string;\n lastProvisionAt: string | null;\n lastDriftCheckAt: string | null;\n }>;\n };\n agentState = state.agents?.find((a) => a.codeName === codeName) ?? null;\n } catch {\n // ignore\n }\n }\n }\n\n // ── Resolve channel data ────────────────────────────────────────────────\n // Prefer API channel data over local openclaw.json5 since the webapp/API\n // is the source of truth for channel configuration.\n\n type ChannelRow = {\n id: string;\n name: string;\n tier: string;\n enabled: boolean;\n status: string;\n e2e: string;\n };\n\n const channelRows: ChannelRow[] = [];\n\n if (apiChannels && apiChannels.length > 0) {\n // Use API channel configs (source of truth)\n for (const ch of apiChannels) {\n const def = getChannel(ch.channel_id);\n channelRows.push({\n id: ch.channel_id,\n name: def?.name ?? ch.channel_id,\n tier: def?.securityTier ?? 'unknown',\n enabled: true,\n status: ch.status,\n e2e: def ? String(def.e2eEncrypted) : '—',\n });\n }\n } else {\n // Fall back to local openclaw.json5 channels\n const openclawChannels = Array.isArray(openclawConfig?.channels)\n ? (openclawConfig!.channels as Array<{ id: string; enabled?: boolean }>)\n : [];\n\n for (const ch of openclawChannels) {\n const def = getChannel(ch.id);\n channelRows.push({\n id: ch.id,\n name: def?.name ?? ch.id,\n tier: def?.securityTier ?? 'unknown',\n enabled: ch.enabled !== false,\n status: ch.enabled !== false ? 'configured' : 'disabled',\n e2e: def ? String(def.e2eEncrypted) : '—',\n });\n }\n }\n\n // ── JSON output ─────────────────────────────────────────────────────────\n\n if (json) {\n const filtered = opts.allChannels ? channelRows : channelRows.filter((c) => c.enabled);\n jsonOutput({\n ok: true,\n agent: {\n code_name: codeName,\n display_name: (apiAgent?.display_name as string) ?? charter?.display_name ?? null,\n agent_id: (apiAgent?.agent_id as string) ?? charter?.agent_id ?? null,\n environment: (apiAgent?.environment as string) ?? charter?.environment ?? null,\n risk_tier: (apiAgent?.risk_tier as string) ?? charter?.risk_tier ?? null,\n owner: charter?.owner ?? null,\n logging_mode: charter?.logging_mode ?? null,\n budget: charter?.budget ?? null,\n limits: charter?.limits ?? null,\n },\n versions: {\n charter: agentState?.charterVersion ?? charter?.version ?? null,\n tools: agentState?.toolsVersion ?? tools?.version ?? null,\n last_provision: agentState?.lastProvisionAt ?? null,\n last_drift_check: agentState?.lastDriftCheckAt ?? null,\n },\n tools: {\n enforcement_mode: tools?.enforcement_mode ?? null,\n global_controls: tools?.global_controls ?? null,\n count: tools?.tools?.length ?? 0,\n items: tools?.tools ?? [],\n },\n channels: filtered,\n openclaw: openclawConfig\n ? { sandbox: (openclawConfig as any).sandbox ?? null, gateway: (openclawConfig as any).gateway ?? null }\n : null,\n });\n return;\n }\n\n // ── Human output ────────────────────────────────────────────────────────\n\n const displayName = (apiAgent?.display_name as string) ?? charter?.display_name ?? codeName;\n console.log(chalk.bold(`\\nAgent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : '') + '\\n');\n\n if (charter || apiAgent) {\n const agentId = (apiAgent?.agent_id as string) ?? charter?.agent_id;\n const environment = (apiAgent?.environment as string) ?? charter?.environment;\n const riskTier = (apiAgent?.risk_tier as string) ?? charter?.risk_tier;\n\n info(`Agent ID: ${agentId ?? '—'}`);\n info(`Environment: ${environment ?? '—'}`);\n info(`Risk Tier: ${riskTier ?? '—'}`);\n info(`Owner: ${charter?.owner?.name ?? '—'}`);\n\n const charterVer = agentState?.charterVersion ?? charter?.version;\n const toolsVer = agentState?.toolsVersion ?? tools?.version ?? '—';\n const provTs = agentState?.lastProvisionAt\n ? formatTimestamp(agentState.lastProvisionAt)\n : null;\n\n if (charterVer) {\n info(`Charter: v${charterVer}${provTs ? ` (provisioned ${provTs})` : ''}`);\n }\n if (toolsVer !== '—') {\n info(`Tools: v${toolsVer}${provTs ? ` (provisioned ${provTs})` : ''}`);\n }\n\n // Sandbox\n const sandbox = openclawConfig ? (openclawConfig as any).sandbox : null;\n if (sandbox != null) {\n info(`Sandbox: ${sandbox ? 'on' : 'off'}`);\n }\n\n // Budget\n const b = charter?.budget;\n if (b) {\n const budgetStr = `${b.limit.toLocaleString()} ${b.type} / ${b.window} (${b.enforcement ?? 'block'})`;\n info(`Budget: ${budgetStr}`);\n }\n } else {\n info('No agent metadata available');\n }\n\n // ── Channels table ──────────────────────────────────────────────────────\n\n const filtered = opts.allChannels ? channelRows : channelRows.filter((c) => c.enabled);\n\n console.log(chalk.bold('\\nChannels:'));\n\n if (filtered.length === 0) {\n info('(none enabled)');\n } else {\n table(\n ['Channel', 'Name', 'Tier', 'Status', 'E2E'],\n filtered.map((c) => [\n c.id,\n c.name,\n c.tier,\n c.status,\n c.e2e,\n ]),\n );\n }\n\n // ── Tools ───────────────────────────────────────────────────────────────\n\n if (tools) {\n console.log(chalk.bold('\\nTools:'));\n\n if (tools.tools.length === 0) {\n info('(none configured)');\n } else {\n table(\n ['ID', 'Name', 'Type', 'Access', 'Enforcement'],\n tools.tools.map((t) => [t.id, t.name, t.type, t.access, t.enforcement]),\n );\n }\n\n // Global controls\n if (tools.global_controls) {\n const gc = tools.global_controls;\n console.log(chalk.bold('\\nGlobal Controls:'));\n info(`Network: ${gc.default_network_policy === 'deny' ? 'deny-by-default' : 'allow-by-default'}`);\n info(`Timeout: ${gc.default_timeout_ms}ms`);\n info(`Rate: ${gc.default_rate_limit_rpm} rpm`);\n info(`Retries: ${gc.default_retries}`);\n }\n }\n\n console.log();\n}\n\nfunction formatTimestamp(iso: string): string {\n const d = new Date(iso);\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api, ApiError } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface RecurringTemplate {\n id: string;\n title: string;\n kind: string;\n expression?: string;\n every_interval?: string;\n natural_language?: string;\n timezone: string;\n enabled: boolean;\n next_spawn_at?: string;\n last_spawned_at?: string;\n spawn_count: number;\n priority: number;\n created_at: string;\n}\n\nasync function resolveAgentId(codeName: string): Promise<string | null> {\n try {\n const data = await api.get<{ agent_id: string }>(`/agents/${codeName}`);\n return data.agent_id;\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) return null;\n throw err;\n }\n}\n\nfunction priorityLabel(p: number): string {\n return p === 1 ? chalk.red('HIGH') : p === 3 ? chalk.dim('LOW') : chalk.yellow('MED');\n}\n\nfunction formatSpawnTime(isoDate: string | undefined, timezone: string): string {\n if (!isoDate) return chalk.dim('—');\n try {\n return new Intl.DateTimeFormat('en-AU', {\n dateStyle: 'medium',\n timeStyle: 'short',\n timeZone: timezone,\n }).format(new Date(isoDate));\n } catch {\n return new Date(isoDate).toLocaleString();\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring add\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringAddCommand(\n title: string,\n opts: {\n agent: string;\n every: string;\n priority?: string;\n description?: string;\n estimate?: string;\n deliverable?: string;\n timezone?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n // Validate numeric inputs\n let priority: number | undefined;\n if (opts.priority) {\n priority = Number(opts.priority);\n if (!Number.isInteger(priority) || priority < 1 || priority > 3) {\n if (json) {\n jsonOutput({ ok: false, error: 'Priority must be 1, 2, or 3' });\n } else {\n error('Priority must be 1 (high), 2 (medium), or 3 (low)');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n let estimatedMinutes: number | undefined;\n if (opts.estimate) {\n estimatedMinutes = Number(opts.estimate);\n if (!Number.isInteger(estimatedMinutes) || estimatedMinutes <= 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'Estimate must be a positive integer (minutes)' });\n } else {\n error('Estimate must be a positive integer (minutes)');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n const spinner = ora({ text: 'Creating recurring template…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ template: RecurringTemplate }>('/host/kanban/recurring', {\n agent_id: agentId,\n title,\n description: opts.description ?? undefined,\n priority,\n estimated_minutes: estimatedMinutes,\n deliverable: opts.deliverable ?? undefined,\n schedule: opts.every,\n timezone: opts.timezone ?? undefined,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, template: data.template });\n return;\n }\n\n success(`Recurring task created: ${chalk.bold(title)}`);\n info(`Schedule: ${chalk.cyan(data.template.natural_language ?? data.template.expression ?? data.template.every_interval ?? '')}`);\n info(`Next spawn: ${formatSpawnTime(data.template.next_spawn_at, data.template.timezone)}`);\n info(`Timezone: ${data.template.timezone}`);\n } catch (err) {\n spinner.fail('Failed to create recurring template');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring list\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringListCommand(\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Fetching recurring templates…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.get<{ templates: RecurringTemplate[] }>(\n `/host/kanban/recurring?agent_id=${agentId}`,\n );\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, templates: data.templates });\n return;\n }\n\n if (data.templates.length === 0) {\n info('No recurring templates found.');\n return;\n }\n\n const rows = data.templates.map((t) => [\n t.id.slice(0, 8),\n t.title,\n t.natural_language ?? t.expression ?? t.every_interval ?? '—',\n priorityLabel(t.priority),\n t.enabled ? chalk.green('Active') : chalk.dim('Disabled'),\n formatSpawnTime(t.next_spawn_at, t.timezone),\n String(t.spawn_count),\n ]);\n\n table(\n ['ID', 'Title', 'Schedule', 'Priority', 'Status', 'Next Spawn', 'Spawned'],\n rows,\n );\n } catch (err) {\n spinner.fail('Failed to fetch recurring templates');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring disable\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringDisableCommand(\n titleOrId: string,\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Disabling recurring template…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.get<{ templates: RecurringTemplate[] }>(\n `/host/kanban/recurring?agent_id=${agentId}`,\n );\n\n const matches = data.templates.filter(\n (t) => t.id.startsWith(titleOrId) || t.title.toLowerCase() === titleOrId.toLowerCase(),\n );\n\n if (matches.length === 0) {\n spinner.fail(`Recurring template \"${titleOrId}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n if (matches.length > 1) {\n spinner.fail(`Ambiguous match for \"${titleOrId}\" — ${matches.length} templates found:`);\n for (const m of matches) {\n info(` ${m.id.slice(0, 8)} — ${m.title}`);\n }\n info('Use a longer ID prefix to disambiguate.');\n process.exitCode = 1;\n return;\n }\n\n const match = matches[0]!;\n await api.patch(`/host/kanban/recurring/${match.id}`, { enabled: false });\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, id: match.id, title: match.title, enabled: false });\n } else {\n success(`Disabled: ${chalk.bold(match.title)}`);\n }\n } catch (err) {\n spinner.fail('Failed to disable recurring template');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, accessSync, constants as fsConstants } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { deriveConsoleUrl } from '@augmented/core';\nimport { success, error, info, warn } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { exchangeApiKey } from '../lib/api-client.js';\nimport { startWatchdog } from '../lib/watchdog.js';\n\n/**\n * Detect the user's shell profile file.\n * Returns the path to the most appropriate profile file.\n */\nfunction detectShellProfile(): string {\n const shell = process.env['SHELL'] ?? '';\n const home = homedir();\n\n if (shell.includes('zsh')) {\n // Always use .zshrc — it's sourced by interactive shells.\n // .zprofile is only sourced by login shells and won't be read by subprocesses.\n return join(home, '.zshrc');\n }\n\n if (shell.includes('fish')) {\n const fishConfig = join(home, '.config', 'fish', 'config.fish');\n return fishConfig;\n }\n\n // Default to bash\n const bashrc = join(home, '.bashrc');\n if (existsSync(bashrc)) return bashrc;\n return join(home, '.bash_profile');\n}\n\n/**\n * When running as root on a POSIX host, persist AGT_HOST / AGT_API_KEY to\n * every channel that matters for system-wide visibility:\n *\n * /etc/environment — read by PAM (sshd logins).\n * /etc/profile.d/agt.sh — sourced by login shells (bash -l, sh -l).\n * /etc/bashrc — sourced by non-login interactive bash.\n *\n * One channel isn't enough because SSM Session Manager launches `/bin/sh`\n * (bash in sh-compat mode), which skips /etc/profile.d, /etc/bashrc, and\n * isn't guaranteed to go through PAM. Users in an SSM session can `exec\n * bash` / `exec bash -l` to pick up any of these.\n *\n * Returns true if at least one channel was written.\n */\ninterface SystemWideEnvResult {\n etcEnvironment: boolean;\n profileD: boolean;\n bashrc: boolean;\n}\n\nfunction maybeWriteSystemWideEnv(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): SystemWideEnvResult {\n const empty: SystemWideEnvResult = { etcEnvironment: false, profileD: false, bashrc: false };\n if (process.platform === 'win32') return empty;\n if (typeof process.getuid !== 'function' || process.getuid() !== 0) return empty;\n\n return {\n etcEnvironment: writeEtcEnvironment(apiUrl, apiKey, consoleUrl),\n profileD: writeProfileDScript(apiUrl, apiKey, consoleUrl),\n // Run for its side-effect (wiring /etc/bashrc to source agt.sh) but\n // treat it as a supporting channel, not proof that env values were\n // persisted. Success reporting should reflect actual value writes.\n bashrc: ensureBashrcSourcesProfileD(),\n };\n}\n\n/** Quote a value for /etc/environment (pam_env format: KEY=\"value\"). */\nfunction quoteForEtcEnvironment(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\r?\\n/g, '\\\\n')}\"`;\n}\n\n/** Quote a value for a POSIX shell script (single-quoted; safest — no expansion). */\nfunction quoteForPosixShell(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * Quote a value for a fish config.fish `set -gx` line. Fish evaluates `$VAR`\n * (and `$(cmd)`) inside double-quoted strings, so a raw URL containing a `$`\n * would get partially expanded. Single quotes disable expansion; embedded\n * single quotes escape as `\\'`, backslashes as `\\\\`. Parenthesized command\n * substitutions `(cmd)` are not expanded inside double quotes in fish, but\n * single-quoting is uniformly safe.\n */\nfunction quoteForFishShell(value: string): string {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, `\\\\'`)}'`;\n}\n\nexport function writeEtcEnvironment(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): boolean {\n const envPath = '/etc/environment';\n if (!existsSync(envPath)) return false;\n try {\n accessSync(envPath, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const current = readFileSync(envPath, 'utf-8');\n // Strip all three keys (even when CONSOLE_URL isn't being re-written) so\n // a stale value from a prior setup run can't linger while HOST/API_KEY\n // rotate to a new host underneath it.\n const stripped = current\n .split(/\\r?\\n/)\n .filter((line) => !/^\\s*(?:export\\s+)?AGT_(?:HOST|API_KEY|CONSOLE_URL)=/.test(line))\n .join('\\n');\n const base = stripped.endsWith('\\n') || stripped.length === 0 ? stripped : `${stripped}\\n`;\n const lines = [\n `AGT_HOST=${quoteForEtcEnvironment(apiUrl)}`,\n `AGT_API_KEY=${quoteForEtcEnvironment(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`AGT_CONSOLE_URL=${quoteForEtcEnvironment(consoleUrl)}`);\n const appended = `${base}${lines.join('\\n')}\\n`;\n writeFileSync(envPath, appended, { mode: 0o644 });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function writeProfileDScript(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): boolean {\n const profileD = '/etc/profile.d';\n if (!existsSync(profileD)) return false;\n try {\n accessSync(profileD, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const scriptPath = `${profileD}/agt.sh`;\n // Single-quote so the shell does no expansion — safe even if the value\n // contains $, backticks, or double quotes. API keys shouldn't contain\n // these, but defense in depth matters when sourcing into every login shell.\n const lines = [\n '# Augmented — auto-generated by `agt setup`. Do not edit.',\n `export AGT_HOST=${quoteForPosixShell(apiUrl)}`,\n `export AGT_API_KEY=${quoteForPosixShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);\n lines.push('');\n writeFileSync(scriptPath, lines.join('\\n'), { mode: 0o644 });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensureBashrcSourcesProfileD(): boolean {\n const bashrc = '/etc/bashrc';\n if (!existsSync(bashrc)) return false;\n try {\n accessSync(bashrc, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const current = readFileSync(bashrc, 'utf-8');\n const marker = '# Augmented (agt) — source system-wide AGT env';\n if (current.includes(marker)) return true; // already wired up\n const snippet = [\n '',\n marker,\n 'if [ -r /etc/profile.d/agt.sh ]; then',\n ' . /etc/profile.d/agt.sh',\n 'fi',\n '',\n ].join('\\n');\n writeFileSync(bashrc, current + snippet);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Build export lines for the shell profile.\n */\nexport function buildExportLines(\n shell: string,\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): string {\n if (shell.includes('fish')) {\n const lines = [\n '',\n '# Augmented (agt) host configuration',\n `set -gx AGT_HOST ${quoteForFishShell(apiUrl)}`,\n `set -gx AGT_API_KEY ${quoteForFishShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`set -gx AGT_CONSOLE_URL ${quoteForFishShell(consoleUrl)}`);\n lines.push('');\n return lines.join('\\n');\n }\n\n const lines = [\n '',\n '# Augmented (agt) host configuration',\n `export AGT_HOST=${quoteForPosixShell(apiUrl)}`,\n `export AGT_API_KEY=${quoteForPosixShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);\n lines.push('');\n return lines.join('\\n');\n}\n\nexport interface SetupOptions {\n /**\n * Override the API host the provisioning token is exchanged against.\n * Takes precedence over `AGT_HOST`. ENG-5831: required when `AGT_HOST`\n * is not set — the setup command no longer silently defaults to prod,\n * since a non-prod-stage token would otherwise be exchanged against the\n * wrong API and the failure looks like opaque connectivity loss.\n */\n apiHost?: string;\n}\n\nexport async function setupCommand(token: string, options: SetupOptions = {}): Promise<void> {\n const json = isJsonMode();\n\n // Accept both new short format (XXXX-XXXX) and legacy prov_ format\n const shortTokenPattern = /^[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i;\n const legacyTokenPattern = /^prov_[a-f0-9]{64}$/i;\n if (!token || (!shortTokenPattern.test(token) && !legacyTokenPattern.test(token))) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>' });\n } else {\n error('Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>');\n info('Get a provisioning token from the Augmented dashboard after creating a host.');\n }\n process.exitCode = 1;\n return;\n }\n\n // Normalize: short tokens to uppercase, legacy tokens to lowercase\n const normalizedToken = shortTokenPattern.test(token) ? token.toUpperCase() : token.toLowerCase();\n\n // Step 1: Determine API URL\n // ENG-5831: resolution chain is --api-host flag → AGT_HOST env → fail\n // loud. The previous silent prod default routed non-prod-stage tokens\n // against prod and the failure surfaced as opaque connectivity loss.\n // setupResult.api_url (returned by /host/setup) is the authoritative\n // value that gets persisted to the shell profile; this `apiUrl` is just\n // the bootstrap address used to reach /host/setup in the first place.\n const apiHostFlag = options.apiHost?.trim();\n const envHost = process.env['AGT_HOST']?.trim();\n const apiUrl = apiHostFlag || envHost;\n if (!apiUrl) {\n const msg =\n 'Cannot determine API host for token exchange. Pass --api-host <url> or set AGT_HOST before running `agt setup`.\\n' +\n ' Production: --api-host https://api.augmented.team\\n' +\n ' Non-prod stage: --api-host https://<stage>.api.staging.augmented.team\\n' +\n ' Local development: --api-host http://api.agt.localhost:1355';\n if (json) {\n jsonOutput({ ok: false, error: msg });\n } else {\n error(msg);\n }\n process.exitCode = 1;\n return;\n }\n if (!json) {\n if (apiHostFlag) {\n info(`Exchanging token against ${chalk.bold(apiUrl)} (from --api-host)`);\n } else {\n info(`Exchanging token against ${chalk.bold(apiUrl)} (from AGT_HOST)`);\n }\n }\n\n // Step 2: Exchange provisioning token\n const spinner = ora({ text: 'Exchanging provisioning token\\u2026', isSilent: json });\n spinner.start();\n\n let setupResult: {\n host_name: string;\n host_id: string;\n team_slug: string | null;\n api_url: string;\n api_key: string;\n agents: string[];\n };\n\n try {\n const res = await fetch(`${apiUrl}/host/setup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: normalizedToken }),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({})) as Record<string, unknown>;\n throw new Error((body['error'] as string) ?? `Setup failed: HTTP ${res.status}`);\n }\n\n setupResult = await res.json() as typeof setupResult;\n spinner.succeed('Provisioning token accepted');\n } catch (err) {\n spinner.fail('Failed to exchange provisioning token');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // Use the API URL returned by the server (more authoritative)\n const finalApiUrl = setupResult.api_url || apiUrl;\n\n // Set for current process so verification can run\n process.env['AGT_HOST'] = finalApiUrl;\n process.env['AGT_API_KEY'] = setupResult.api_key;\n\n // Step 3: Verify connection before writing anything to disk\n const verifySpinner = ora({ text: 'Verifying connection\\u2026', isSilent: json });\n verifySpinner.start();\n\n try {\n const exchange = await exchangeApiKey(setupResult.api_key);\n verifySpinner.succeed('Connection verified');\n\n if (!json) {\n info(`Host: ${chalk.bold(setupResult.host_name)}`);\n info(`Host ID: ${exchange.hostId}`);\n info(`Team: ${chalk.bold(exchange.teamSlug ?? setupResult.team_slug ?? 'unknown')}`);\n if (exchange.userEmail) {\n info(`User: ${chalk.bold(exchange.userEmail)}`);\n }\n }\n } catch (err) {\n verifySpinner.fail('Connection verification failed');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n info('Connection could not be verified. No changes were written to your shell profile.');\n info('Check your network connection and try: agt whoami');\n }\n process.exitCode = 1;\n return;\n }\n\n // Step 4: Write env vars to shell profile (only after successful verification)\n const profilePath = detectShellProfile();\n const shell = process.env['SHELL'] ?? 'bash';\n\n // ENG-4495: derive the webapp console URL from the API URL so the\n // schedule-edit deep-link footer (ENG-4462) works on fresh hosts without\n // the operator having to export AGT_CONSOLE_URL manually. Returns null\n // for non-standard api.<host> shapes; we persist HOST/API_KEY anyway and\n // flag the gap so the operator can set CONSOLE_URL themselves.\n const consoleUrl = deriveConsoleUrl(finalApiUrl);\n // Propagate to the current process so the watchdog started later in this\n // same command inherits it — otherwise the first-run schedule deep-link\n // footer would stay disabled until the next restart even though we wrote\n // the value to the shell rc file.\n if (consoleUrl) {\n process.env['AGT_CONSOLE_URL'] = consoleUrl;\n }\n if (!json && !consoleUrl) {\n warn(\n `Could not derive AGT_CONSOLE_URL from ${finalApiUrl} — scheduled-delivery deep links will be disabled until you set it manually.`,\n );\n }\n\n const exportLines = buildExportLines(shell, finalApiUrl, setupResult.api_key, consoleUrl);\n const profileDir = dirname(profilePath);\n if (!existsSync(profileDir)) {\n mkdirSync(profileDir, { recursive: true });\n }\n\n // Replace existing block if present, otherwise append\n const marker = '# Augmented (agt) host configuration';\n const current = existsSync(profilePath) ? readFileSync(profilePath, 'utf-8') : '';\n let updated: string;\n if (current.includes(marker)) {\n // Match the marker line and all subsequent export/set lines (bash + fish),\n // plus any surrounding blank lines that were part of the original block.\n updated = current.replace(\n /\\n?# Augmented \\(agt\\) host configuration\\n(?:(?:export\\s+AGT_\\w+=.*|set\\s+-gx\\s+AGT_\\w+\\s+.*)\\n)*\\n?/,\n exportLines,\n );\n if (!json) {\n info('Replacing existing Augmented config block in shell profile.');\n }\n } else {\n updated = current + exportLines;\n }\n writeFileSync(profilePath, updated.endsWith('\\n') ? updated : `${updated}\\n`);\n\n if (!json) {\n success(`Environment variables written to ${chalk.bold(profilePath)}`);\n }\n\n // Step 4b: When running as root, fan out AGT_HOST / AGT_API_KEY to the\n // system-wide channels (/etc/environment, /etc/profile.d/agt.sh, and a\n // one-time /etc/bashrc source line). No single channel covers every\n // session type — SSM Session Manager launches `sh` which skips most of\n // them, so we write to all and let operators `exec bash -l` if needed.\n const sys = maybeWriteSystemWideEnv(finalApiUrl, setupResult.api_key, consoleUrl);\n // Bashrc only wires up the source — if neither of the value channels\n // actually persisted the vars, we shouldn't claim success.\n const valueChannelsWritten = sys.etcEnvironment || sys.profileD;\n if (!json && valueChannelsWritten) {\n const channels = [\n sys.etcEnvironment ? '/etc/environment' : null,\n sys.profileD ? '/etc/profile.d/agt.sh' : null,\n sys.bashrc ? '/etc/bashrc' : null,\n ].filter(Boolean).join(' + ');\n success(`System-wide env updated: ${channels}`);\n }\n\n // Step 5: Start manager daemon.\n // Detach so the setup process can exit cleanly — critical for JSON-mode\n // callers like the EC2 bootstrap that capture stdout via `$(...)`. Without\n // detach, in-process timers keep Node alive and the capture hangs forever.\n const managerSpinner = ora({ text: 'Starting manager daemon\\u2026', isSilent: json });\n managerSpinner.start();\n\n try {\n const configDir = join(homedir(), '.augmented');\n const { pid } = startWatchdog({ intervalMs: 10_000, configDir, detached: true });\n managerSpinner.succeed(`Manager started (PID ${pid})`);\n } catch (err) {\n managerSpinner.warn('Could not start manager daemon');\n if (!json) {\n warn((err as Error).message);\n info('Start it manually with: agt manager start');\n }\n }\n\n // Step 6: Print summary\n //\n // The raw API key is emitted to stdout only when the caller explicitly\n // opts in via AGT_SETUP_INCLUDE_API_KEY=1. Default-off because --json\n // output can end up in automation logs; trusted bootstrap flows (EC2\n // user-data) set the env var before invoking so they can persist the\n // key system-wide.\n const includeApiKey = process.env['AGT_SETUP_INCLUDE_API_KEY'] === '1';\n if (json) {\n jsonOutput({\n ok: true,\n host_name: setupResult.host_name,\n host_id: setupResult.host_id,\n team_slug: setupResult.team_slug,\n api_url: finalApiUrl,\n ...(includeApiKey ? { api_key: setupResult.api_key } : {}),\n agents: setupResult.agents,\n profile: profilePath,\n });\n // Force-exit so bootstrap scripts using `$(agt setup --json TOKEN)`\n // don't hang on stray open handles (fetch keepalive, Supabase realtime\n // warmup, etc.). The manager daemon runs in a detached child and keeps\n // going regardless.\n process.exit(0);\n } else {\n console.log();\n console.log(chalk.green.bold(' Setup complete!'));\n console.log();\n if (setupResult.agents.length > 0) {\n info(`Agents: ${setupResult.agents.map((a) => chalk.cyan(a)).join(', ')}`);\n } else {\n info('No agents assigned yet. Assign agents in the dashboard or with: agt host assign');\n }\n console.log();\n info(`Restart your shell or run: ${chalk.bold(`source ${profilePath}`)}`);\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface KanbanItem {\n id: string;\n title: string;\n description?: string;\n priority: number;\n status: string;\n estimated_minutes?: number;\n notes?: string;\n deliverable?: string;\n result?: string;\n completed_at?: string;\n created_at: string;\n}\n\nasync function resolveAgentId(codeName: string): Promise<string | null> {\n try {\n const data = await api.get<{ agent_id: string }>(`/agents/${codeName}`);\n return data.agent_id;\n } catch {\n return null;\n }\n}\n\nfunction priorityLabel(p: number): string {\n return p === 1 ? chalk.red('HIGH') : p === 3 ? chalk.dim('LOW') : chalk.yellow('MED');\n}\n\nfunction statusLabel(s: string): string {\n const map: Record<string, string> = {\n in_progress: chalk.blue('In Progress'),\n todo: chalk.green('To Do'),\n backlog: chalk.dim('Backlog'),\n done: chalk.gray('Done'),\n };\n return map[s] ?? s;\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban list\n// ---------------------------------------------------------------------------\n\nexport async function kanbanListCommand(\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Fetching kanban board…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ items: KanbanItem[] }>('/host/my-kanban', {\n agent_id: agentId,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, items: data.items });\n return;\n }\n\n if (!data.items.length) {\n info(`Board for ${opts.agent} is empty.`);\n return;\n }\n\n const rows = data.items.map((item) => [\n priorityLabel(item.priority),\n statusLabel(item.status),\n item.title.length > 50 ? item.title.slice(0, 47) + '…' : item.title,\n item.estimated_minutes ? `~${item.estimated_minutes}min` : '',\n item.id.slice(0, 8),\n ]);\n\n console.log(chalk.bold(`\\nKanban: ${opts.agent}\\n`));\n table(['Pri', 'Status', 'Title', 'Est', 'ID'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch board.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban add\n// ---------------------------------------------------------------------------\n\nexport async function kanbanAddCommand(\n title: string,\n opts: {\n agent: string;\n priority?: string;\n status?: string;\n description?: string;\n estimate?: string;\n deliverable?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ ok: boolean; added: number }>('/host/kanban', {\n agent_id: agentId,\n add: [\n {\n title,\n description: opts.description,\n priority: opts.priority ? Number(opts.priority) : 2,\n status: opts.status ?? 'todo',\n estimated_minutes: opts.estimate ? Number(opts.estimate) : undefined,\n deliverable: opts.deliverable,\n source: 'manual',\n },\n ],\n });\n\n if (json) {\n jsonOutput({ ok: true, added: data.added });\n } else {\n success(`Added \"${title}\" to ${opts.agent}'s board.`);\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban move\n// ---------------------------------------------------------------------------\n\nexport async function kanbanMoveCommand(\n titleOrId: string,\n status: string,\n opts: { agent: string; notes?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const validStatuses = ['backlog', 'todo', 'in_progress', 'done'];\n if (!validStatuses.includes(status)) {\n error(`Invalid status \"${status}\". Must be one of: ${validStatuses.join(', ')}`);\n process.exitCode = 1;\n return;\n }\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const update: Record<string, unknown> = {\n status,\n notes: opts.notes,\n };\n if (isUuid) {\n update.id = titleOrId;\n } else {\n update.title = titleOrId;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [update],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else if (data.updated > 0) {\n success(`Moved \"${titleOrId}\" → ${status}.`);\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n process.exitCode = 1;\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban update\n// ---------------------------------------------------------------------------\n\nexport async function kanbanUpdateCommand(\n titleOrId: string,\n opts: { agent: string; notes?: string; result?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Fetch current item to get its status\n let board: { items: KanbanItem[] };\n try {\n board = await api.post<{ items: KanbanItem[] }>('/host/my-kanban', {\n agent_id: agentId,\n });\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const match = board.items.find(\n (i) => (isUuid && i.id === titleOrId) || i.title === titleOrId,\n );\n\n if (!match) {\n if (json) {\n jsonOutput({ ok: false, error: `Item \"${titleOrId}\" not found.` });\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n }\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [\n {\n id: match.id,\n status: match.status,\n notes: opts.notes,\n result: opts.result,\n },\n ],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else {\n success(`Updated \"${match.title}\".`);\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban done\n// ---------------------------------------------------------------------------\n\nexport async function kanbanDoneCommand(\n titleOrId: string,\n opts: { agent: string; result?: string; notes?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const update: Record<string, unknown> = {\n status: 'done',\n result: opts.result,\n notes: opts.notes,\n };\n if (isUuid) {\n update.id = titleOrId;\n } else {\n update.title = titleOrId;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [update],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else if (data.updated > 0) {\n success(`Marked \"${titleOrId}\" as done.`);\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n process.exitCode = 1;\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import type { AcpAgentAdapter } from './types.js';\n\n/**\n * Built-in ACP agent adapters.\n * Only the three agents specified in ENG-4119 scope: Claude Code, OpenClaw, Codex.\n */\nexport const ACP_AGENT_REGISTRY: readonly AcpAgentAdapter[] = [\n {\n name: 'claude',\n label: 'Claude Code',\n adapter_package: 'claude-agent-acp',\n command: 'npx',\n args: ['-y', 'claude-agent-acp'],\n type: 'npx-wrapper',\n },\n {\n name: 'openclaw',\n label: 'OpenClaw',\n command: 'openclaw',\n args: ['acp'],\n type: 'native',\n },\n {\n name: 'codex',\n label: 'Codex',\n adapter_package: 'codex-acp',\n command: 'npx',\n args: ['-y', 'codex-acp'],\n type: 'npx-wrapper',\n },\n] as const;\n\nconst agentMap = new Map<string, AcpAgentAdapter>(\n ACP_AGENT_REGISTRY.map((a) => [a.name, a]),\n);\n\nexport function getAcpAgent(name: string): AcpAgentAdapter | undefined {\n return agentMap.get(name);\n}\n\nexport function getAllAcpAgentNames(): string[] {\n return ACP_AGENT_REGISTRY.map((a) => a.name);\n}\n","import { spawn } from 'node:child_process';\nimport type {\n AcpSessionMetadata,\n AcpEvent,\n AcpPermissionMode,\n AcpAgentAdapter,\n} from './types.js';\nimport { getAcpAgent } from './agent-registry.js';\n\nexport interface AcpSpawnOptions {\n /** Agent name or custom command */\n agent: string;\n /** Working directory for the session */\n cwd: string;\n /** Named session for parallel workstreams */\n sessionName?: string;\n /** Permission mode */\n permissions?: AcpPermissionMode;\n /** Queue owner idle TTL in seconds */\n ttl?: number;\n /** Prompt execution timeout in seconds */\n timeout?: number;\n /** Auto-approve all tool permissions */\n approveAll?: boolean;\n}\n\nexport interface AcpPromptOptions {\n /** Agent name */\n agent: string;\n /** Prompt text */\n prompt: string;\n /** Working directory */\n cwd: string;\n /** Named session */\n sessionName?: string;\n /** Output format */\n format?: 'text' | 'json' | 'json-strict' | 'quiet';\n /** Don't wait for completion */\n noWait?: boolean;\n /** Timeout in seconds */\n timeout?: number;\n}\n\nexport interface AcpExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n events: AcpEvent[];\n}\n\n/**\n * Resolves the acpx command and arguments for a given agent.\n * Falls back to raw command execution for unknown agents.\n */\nfunction resolveAgentCommand(agentName: string): { command: string; args: string[] } {\n const adapter = getAcpAgent(agentName);\n if (adapter) {\n return {\n command: 'acpx',\n args: [adapter.name],\n };\n }\n // Unknown agent — use raw command via --agent flag\n return {\n command: 'acpx',\n args: ['--agent', agentName],\n };\n}\n\n/**\n * Runs an acpx command and returns the result.\n */\nexport async function runAcpx(\n args: string[],\n options: { cwd?: string; timeout?: number } = {},\n): Promise<AcpExecResult> {\n return new Promise((resolve) => {\n const child = spawn('acpx', args, {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n });\n\n let stdout = '';\n let stderr = '';\n const events: AcpEvent[] = [];\n\n child.stdout?.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdout += chunk;\n // Parse NDJSON events if format is json\n for (const line of chunk.split('\\n').filter(Boolean)) {\n try {\n const parsed = JSON.parse(line) as AcpEvent;\n if (parsed.eventVersion === 1) {\n events.push(parsed);\n }\n } catch {\n // Not JSON — plain text output\n }\n }\n });\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const timer = options.timeout\n ? setTimeout(() => child.kill('SIGTERM'), options.timeout * 1000)\n : undefined;\n\n child.on('close', (code) => {\n if (timer) clearTimeout(timer);\n resolve({ exitCode: code ?? 1, stdout, stderr, events });\n });\n });\n}\n\n/**\n * Spawns a new ACP session via acpx.\n */\nexport async function acpSpawnSession(opts: AcpSpawnOptions): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(opts.agent);\n const args = [...agentArgs, 'sessions', 'ensure'];\n\n if (opts.sessionName) args.push('-s', opts.sessionName);\n if (opts.approveAll) args.unshift('--approve-all');\n if (opts.ttl !== undefined) args.unshift('--ttl', String(opts.ttl));\n\n args.unshift('--format', 'json');\n\n return runAcpx(args, { cwd: opts.cwd });\n}\n\n/**\n * Sends a prompt to an ACP session.\n */\nexport async function acpPrompt(opts: AcpPromptOptions): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(opts.agent);\n const args = [...agentArgs, 'prompt', opts.prompt];\n\n if (opts.sessionName) args.push('-s', opts.sessionName);\n if (opts.noWait) args.push('--no-wait');\n if (opts.format) args.unshift('--format', opts.format);\n if (opts.timeout) args.unshift('--timeout', String(opts.timeout));\n\n return runAcpx(args, { cwd: opts.cwd, timeout: opts.timeout });\n}\n\n/**\n * Executes a one-shot prompt (no session reuse).\n */\nexport async function acpExec(\n agent: string,\n prompt: string,\n options: { cwd?: string; format?: string; timeout?: number } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'exec', prompt];\n\n if (options.format) args.unshift('--format', options.format);\n if (options.timeout) args.unshift('--timeout', String(options.timeout));\n\n return runAcpx(args, { cwd: options.cwd, timeout: options.timeout });\n}\n\n/**\n * Lists active sessions for an agent.\n */\nexport async function acpListSessions(\n agent: string,\n options: { cwd?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'sessions', 'list', '--format', 'json'];\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Cancels the current prompt in an ACP session.\n */\nexport async function acpCancel(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'cancel'];\n\n if (options.sessionName) args.push('-s', options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Closes (soft-close) an ACP session.\n */\nexport async function acpCloseSession(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'sessions', 'close'];\n\n if (options.sessionName) args.push(options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Gets status of the current ACP session.\n */\nexport async function acpStatus(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'status', '--format', 'json'];\n\n if (options.sessionName) args.push('-s', options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n","import {\n acpSpawnSession,\n acpPrompt,\n acpExec,\n acpListSessions,\n acpCancel,\n acpCloseSession,\n} from '@augmented/core/acp';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// agt acpx spawn\n// ---------------------------------------------------------------------------\n\nexport async function acpxSpawnCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n const approveAll = Boolean(parentOpts.approveAll);\n const ttl = parentOpts.ttl !== undefined ? Number(parentOpts.ttl) : undefined;\n\n info(`Spawning ACP session for \"${agent}\"...`);\n\n const result = await acpSpawnSession({\n agent,\n cwd,\n sessionName,\n approveAll,\n ttl,\n });\n\n if (result.exitCode !== 0) {\n error(`Failed to spawn session: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonMode()) {\n process.stdout.write(result.stdout);\n } else {\n success(`ACP session spawned for \"${agent}\"`);\n if (sessionName) info(`Session name: ${sessionName}`);\n info(`Working directory: ${cwd}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx prompt\n// ---------------------------------------------------------------------------\n\nexport async function acpxPromptCommand(\n agent: string,\n prompt: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n const format = (parentOpts.format as string) ?? 'text';\n const noWait = Boolean(parentOpts.noWait);\n const timeout = parentOpts.timeout !== undefined ? Number(parentOpts.timeout) : undefined;\n\n if (!isJsonMode()) info(`Sending prompt to \"${agent}\"...`);\n\n const result = await acpPrompt({\n agent,\n prompt,\n cwd,\n sessionName,\n format: format as 'text' | 'json' | 'json-strict' | 'quiet',\n noWait,\n timeout,\n });\n\n process.stdout.write(result.stdout);\n if (result.stderr) process.stderr.write(result.stderr);\n process.exitCode = result.exitCode;\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx exec\n// ---------------------------------------------------------------------------\n\nexport async function acpxExecCommand(\n agent: string,\n prompt: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const format = (parentOpts.format as string) ?? 'text';\n const timeout = parentOpts.timeout !== undefined ? Number(parentOpts.timeout) : undefined;\n\n if (!isJsonMode()) info(`Running one-shot exec with \"${agent}\"...`);\n\n const result = await acpExec(agent, prompt, { cwd, format, timeout });\n\n process.stdout.write(result.stdout);\n if (result.stderr) process.stderr.write(result.stderr);\n process.exitCode = result.exitCode;\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx list-sessions\n// ---------------------------------------------------------------------------\n\nexport async function acpxListSessionsCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n\n const result = await acpListSessions(agent, { cwd });\n\n if (isJsonMode()) {\n process.stdout.write(result.stdout);\n } else {\n if (result.exitCode !== 0) {\n error(`Failed to list sessions: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n // Parse and display as table\n try {\n const sessions = JSON.parse(result.stdout);\n if (Array.isArray(sessions) && sessions.length > 0) {\n info(`Active sessions for \"${agent}\":`);\n process.stdout.write(result.stdout);\n } else {\n info(`No active sessions for \"${agent}\".`);\n }\n } catch {\n process.stdout.write(result.stdout);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx cancel\n// ---------------------------------------------------------------------------\n\nexport async function acpxCancelCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n\n info(`Sending cancel to \"${agent}\"...`);\n\n const result = await acpCancel(agent, { cwd, sessionName });\n\n if (result.exitCode !== 0) {\n error(`Cancel failed: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n success('Cancel sent (cooperative).');\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx close\n// ---------------------------------------------------------------------------\n\nexport async function acpxCloseCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n\n info(`Closing ACP session for \"${agent}\"...`);\n\n const result = await acpCloseSession(agent, { cwd, sessionName });\n\n if (result.exitCode !== 0) {\n error(`Close failed: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n success('Session closed (soft-close — history retained).');\n}\n","import { execFileSync, execSync } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getHost } from '../lib/config.js';\nimport { success, error, info, warn } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ndeclare const __CLI_VERSION__: string;\n\nconst cliVersion = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : 'dev';\n\nexport interface VersionInfo {\n latest: string;\n download_url: string;\n changelog_url?: string;\n}\n\n/**\n * Fetch the latest CLI version from the API.\n * Returns null if the API is unreachable (silent fail).\n */\nexport async function fetchLatestVersion(): Promise<VersionInfo | null> {\n const host = getHost();\n if (!host) return null;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5_000);\n timeout.unref();\n\n const res = await fetch(`${host}/cli/version`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!res.ok) return null;\n\n return (await res.json()) as VersionInfo;\n } catch {\n // Network error, timeout, etc. — silently fail\n return null;\n }\n}\n\n/**\n * Compare two semver strings. Returns true if remote > local.\n */\nfunction isNewerVersion(local: string, remote: string): boolean {\n if (local === 'dev') return false;\n\n const parse = (v: string) => v.replace(/^v/, '').split('.').map(Number);\n const lParts = parse(local);\n const rParts = parse(remote);\n const lMaj = lParts[0] ?? 0, lMin = lParts[1] ?? 0, lPat = lParts[2] ?? 0;\n const rMaj = rParts[0] ?? 0, rMin = rParts[1] ?? 0, rPat = rParts[2] ?? 0;\n\n if (rMaj !== lMaj) return rMaj > lMaj;\n if (rMin !== lMin) return rMin > lMin;\n return rPat > lPat;\n}\n\n/**\n * Detect running manager process and active agent tmux sessions.\n * Returns a summary of what's running.\n *\n * ENG-4635: pgrep can race with process exit — by the time we report\n * \"Manager running PID X\", X may already be a tombstone. The agt-update\n * report-then-exit pattern made this acutely visible (operators saw\n * warnings about phantom PIDs that ps -p couldn't find). Verify each\n * candidate PID with kill(pid, 0) before reporting it. kill(pid, 0)\n * doesn't actually signal — it just probes whether the OS still\n * recognises the PID and whether we have permission to signal it.\n * ESRCH means dead/recycled; we treat that as \"not running\". EPERM\n * means alive but owned by someone else — still alive, count it.\n */\n// Exported for unit testing — see __tests__/update-pid-check.test.ts.\nexport function isPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n // EPERM = process exists but owned by a different uid; still alive.\n // ESRCH = no such process. Anything else is unexpected — treat as\n // \"unknown\" and assume not alive so we don't block updates on a\n // weird PID lookup error.\n return (err as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nfunction detectActiveSessions(): { managerPid: string | null; tmuxSessions: string[] } {\n let managerPid: string | null = null;\n try {\n const pid = execSync('pgrep -f \"agt.*(manage|manager)\" 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n // Filter out our own PID and verify the survivors are actually alive.\n // pgrep can win the race with a fleeting process (e.g. another\n // `agt manager status` from a concurrent script) and report a PID\n // that has already exited — without the kill(0) check we'd warn\n // operators about a phantom manager and block their update.\n const ownPid = String(process.pid);\n const pids = pid\n .split('\\n')\n .map((p) => p.trim())\n .filter((p) => p && p !== ownPid)\n .filter((p) => isPidAlive(Number(p)));\n managerPid = pids[0] ?? null;\n } catch { /* no manager running */ }\n\n const tmuxSessions: string[] = [];\n try {\n const sessions = execSync('tmux ls 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n if (sessions) {\n for (const line of sessions.split('\\n')) {\n // Agent sessions use patterns like \"claude-{codeName}\" or \"agt-{codeName}\"\n if (line.match(/^(claude-|agt-)/)) {\n const name = line.split(':')[0];\n if (name) tmuxSessions.push(name);\n }\n }\n }\n } catch { /* tmux not available or no sessions */ }\n\n return { managerPid, tmuxSessions };\n}\n\n/**\n * Detect how the currently running `agt` binary was installed.\n *\n * Returns 'brew' only when the resolved path is inside a Homebrew Cellar\n * (the canonical formula install location: `.../Cellar/<formula>/<version>/bin/…`).\n * A bare `/home/linuxbrew/` or `/opt/homebrew/` prefix isn't enough —\n * Homebrew's Node hosts `npm install -g` targets like\n * `/opt/homebrew/lib/node_modules/@integrity-labs/agt-cli/...`, which is\n * an npm install *managed by* npm, not a brew formula.\n */\nfunction detectInstallSource(): 'brew' | 'npm' {\n try {\n const resolved = realpathSync(process.argv[1] ?? '');\n // Match /Cellar/<formula>/ specifically — works for both\n // /home/linuxbrew/.linuxbrew/Cellar and /opt/homebrew/Cellar.\n if (/\\/Cellar\\/[^/]+\\//.test(resolved)) {\n return 'brew';\n }\n } catch { /* fall through */ }\n return 'npm';\n}\n\n/**\n * Perform the actual update. Uses brew if the CLI was installed that way,\n * otherwise npm from the public registry (where we actually publish —\n * the earlier implementation pointed at GitHub Packages, which is wrong).\n */\nfunction performUpdate(version: string): void {\n const source = detectInstallSource();\n if (source === 'brew') {\n try {\n execFileSync('brew', ['upgrade', 'integrity-labs/tap/agt'], { stdio: 'inherit' });\n return;\n } catch (err) {\n // Only attempt the sudo -u <owner> retry when running as root —\n // otherwise a genuine failure (network, formula syntax error,\n // missing dependency) gets masked by a second auth error.\n const isRoot = typeof process.getuid === 'function' && process.getuid() === 0;\n if (!isRoot) throw err;\n const cellarOwner = detectBrewOwner();\n if (!cellarOwner) throw err;\n execFileSync('sudo', [\n '-u', cellarOwner,\n '-H',\n 'bash', '-c',\n 'brew tap integrity-labs/tap 2>/dev/null || true; brew upgrade integrity-labs/tap/agt',\n ], { stdio: 'inherit' });\n }\n return;\n }\n // npm path — public registry (this is where publishConfig points).\n // Use execFileSync with an argv array so the version string (which\n // originates from a remote API response) can't be interpreted by a\n // shell. Any attacker controlling the API can still push a malicious\n // package, but they can't also inject shell metacharacters via the\n // version field on top of that.\n execFileSync('npm', [\n 'install',\n '-g',\n `@integrity-labs/agt-cli@${version}`,\n '--registry=https://registry.npmjs.org',\n ], { stdio: 'inherit' });\n}\n\nfunction detectBrewOwner(): string | null {\n for (const prefix of ['/home/linuxbrew/.linuxbrew', '/opt/homebrew', '/usr/local']) {\n const cellar = `${prefix}/Cellar`;\n if (!existsSync(cellar)) continue;\n try {\n return execSync(`stat -c %U \"${cellar}\" 2>/dev/null || stat -f %Su \"${cellar}\"`, { encoding: 'utf-8' }).trim() || null;\n } catch { /* try next */ }\n }\n return null;\n}\n\n/**\n * `agt update` command handler.\n */\nexport async function updateCommand(opts: { force?: boolean } = {}): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Checking for updates…', isSilent: json });\n spinner.start();\n\n const versionInfo = await fetchLatestVersion();\n\n if (!versionInfo) {\n spinner.stop();\n if (json) {\n jsonOutput({ ok: false, error: 'Could not reach API to check for updates' });\n } else {\n warn('Could not reach the API to check for updates. Check AGT_HOST is set and the API is reachable.');\n }\n process.exitCode = 1;\n return;\n }\n\n const updateAvailable = isNewerVersion(cliVersion, versionInfo.latest);\n\n if (!updateAvailable) {\n spinner.stop();\n if (json) {\n jsonOutput({ ok: true, current: cliVersion, latest: versionInfo.latest, update_available: false });\n } else {\n success(`You're on the latest version (${chalk.bold(cliVersion)})`);\n }\n return;\n }\n\n spinner.stop();\n\n if (!json) {\n info(`Update available: ${chalk.dim(cliVersion)} → ${chalk.bold.green(versionInfo.latest)}`);\n if (versionInfo.changelog_url) {\n info(`Changelog: ${versionInfo.changelog_url}`);\n }\n }\n\n // Check for active sessions unless --force is set\n if (!opts.force) {\n const { managerPid, tmuxSessions } = detectActiveSessions();\n\n if (managerPid || tmuxSessions.length > 0) {\n if (!json) {\n warn('Active processes detected:');\n if (managerPid) {\n console.error(chalk.yellow(` • Manager process running (PID ${managerPid})`));\n }\n if (tmuxSessions.length > 0) {\n console.error(chalk.yellow(` • ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(', ')}`));\n }\n console.error();\n warn('Updating while the manager is running will leave it on the old version until restarted.');\n warn('Active agent sessions will continue with stale MCP servers.');\n console.error();\n info(`Run ${chalk.bold('agt update --force')} to update anyway, then restart the manager.`);\n } else {\n jsonOutput({\n ok: false,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: false,\n blocked: true,\n manager_running: !!managerPid,\n active_sessions: tmuxSessions,\n error: 'Active manager or agent sessions detected. Use --force to override.',\n });\n }\n process.exitCode = 1;\n return;\n }\n }\n\n const updateSpinner = ora({ text: 'Installing update…', isSilent: json });\n updateSpinner.start();\n\n try {\n performUpdate(versionInfo.latest);\n updateSpinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: true,\n });\n } else {\n success(`Updated to ${chalk.bold(versionInfo.latest)}`);\n info(`If you have a running manager, restart it: ${chalk.bold('agt manager stop && agt manager start')}`);\n }\n } catch (err) {\n updateSpinner.fail('Update failed');\n if (json) {\n jsonOutput({\n ok: false,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: false,\n error: (err as Error).message,\n });\n } else {\n error(`Failed to install update: ${(err as Error).message}`);\n const source = detectInstallSource();\n if (source === 'brew') {\n info(`You can manually update with: brew upgrade integrity-labs/tap/agt`);\n } else {\n info(`You can manually update with: sudo npm install -g @integrity-labs/agt-cli@${versionInfo.latest}`);\n }\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * Non-blocking startup version check. Prints a one-liner if an update is available.\n * Silently does nothing on failure.\n */\nexport async function checkForUpdateOnStartup(): Promise<void> {\n try {\n const versionInfo = await fetchLatestVersion();\n if (!versionInfo) return;\n\n if (isNewerVersion(cliVersion, versionInfo.latest)) {\n console.error(\n chalk.yellow(`\\n Update available: ${cliVersion} → ${versionInfo.latest}. Run ${chalk.bold('agt update')} to install.`)\n + chalk.dim('\\n Note: Restart the manager after updating.\\n')\n );\n }\n } catch {\n // Silent fail — never block CLI usage\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { auditSubagentMcpBindings, formatFinding } from '../lib/subagent-mcp-audit.js';\n\n/**\n * ENG-5897 — `agt audit subagents` command.\n *\n * Walks the conventional sub-agent definition roots visible to a\n * Claude Code session — the user's `~/.claude/agents/`, every\n * installed plugin under `~/.claude/plugins/<plugin>/agents/`, and\n * the current working directory's `.claude/agents/` (if any) — and\n * reports each sub-agent whose `tools:` allowlist would block every\n * `mcp__*` tool on dispatch. That's the silent-fallback failure mode\n * ENG-5897 / ENG-5898 are closing the door on: a parent agent\n * dispatches one of these sub-agents to do MCP-tool work, the child\n * reports \"No such tool available.\" for every `mcp__*` call, and (in\n * the worst case) reaches for raw secrets out of `.mcp.json` to\n * complete the task off-policy.\n *\n * Exit codes:\n * 0 — no findings (or some findings; we still exit 0 because\n * restrictive plugin sub-agents are sometimes intentional)\n * 2 — only used by `--strict`, when at least one finding exists.\n * Useful in CI to gate a deploy on a clean audit.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n}\n\nfunction defaultRoots(): string[] {\n const home = homedir();\n return [\n join(home, '.claude', 'agents'),\n join(home, '.claude', 'plugins'),\n join(process.cwd(), '.claude', 'agents'),\n ];\n}\n\nexport async function auditSubagentsCommand(options: AuditOptions = {}): Promise<void> {\n const roots = defaultRoots();\n const findings = auditSubagentMcpBindings(roots);\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings, roots }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write('No restrictive sub-agents found — every sub-agent under the scanned roots either inherits the parent toolset or explicitly includes mcp__* wildcards.\\n');\n } else {\n process.stdout.write(`Found ${findings.length} sub-agent${findings.length === 1 ? '' : 's'} whose tools allowlist excludes mcp__*:\\n\\n`);\n for (const f of findings) {\n process.stdout.write(` • ${f.name} (${f.file})\\n`);\n process.stdout.write(` tools: ${f.tools}\\n`);\n }\n process.stdout.write(\n '\\nThese sub-agents will return \"No such tool available.\" for every mcp__* call when dispatched from a managed agent. ' +\n \"If the parent needs to do MCP-tool work, dispatch the Augmented plugin's `augmented-worker` sub-agent instead — \" +\n \"it omits `tools:` so it inherits the parent's full toolset including every MCP server. See ENG-5897.\\n\",\n );\n // Structured log line per finding for log-grep workflows.\n for (const f of findings) {\n process.stderr.write(`${formatFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * ENG-5897 — regression check that surfaces sub-agent definitions whose\n * `tools:` allowlist structurally excludes every `mcp__*` MCP tool.\n *\n * Why this exists: per Anthropic's Claude Code sub-agent docs\n * (https://code.claude.com/docs/en/sub-agents) a sub-agent inherits the\n * parent's full toolset (including MCPs) when its frontmatter omits the\n * `tools:` field. The moment the field is set as an allowlist, only the\n * exact entries listed are exposed to the child. Many community-plugin\n * sub-agents ship restrictive `tools:` lists like `tools: Read, Grep`\n * with no `mcp__*` entries. When a managed agent's parent dispatches\n * one of those for multi-step tool work, the child silently reports\n * \"No such tool available.\" for every MCP call and may fall back to\n * unsafe paths (reading raw secrets from .mcp.json — see ENG-5898).\n *\n * This module gives the manager a way to detect that class of sub-agent\n * at boot and log a structured warning, so the gap is visible at the\n * earliest possible moment rather than at first dispatch on a real\n * inbound task. Strictly read-only — no file mutation, no side effects\n * beyond `fs.readFileSync`.\n *\n * The audit deliberately does NOT fail boot — a restrictive plugin\n * sub-agent may be intentional (e.g. a read-only researcher). The\n * caller (manager-worker boot) logs findings as warnings and lets the\n * operator decide. Augmented's own `augmented-worker` is the canonical\n * antidote: it ships in `claudecode-plugin-augmented/agents/` with\n * `tools:` deliberately omitted so the parent can dispatch to it for\n * any MCP-heavy work.\n */\n\nexport interface SubagentFinding {\n /** Absolute path to the sub-agent definition that triggered the finding. */\n file: string;\n /** The `name:` declared in the sub-agent's frontmatter, or `<unknown>`. */\n name: string;\n /** Raw value of the `tools:` field as it appears in the frontmatter. */\n tools: string;\n /** One-line classification — used by the caller's log line. */\n reason: 'restrictive-tools-no-mcp';\n}\n\ninterface ParsedFrontmatter {\n name?: string;\n tools?: string;\n background?: string;\n}\n\n/**\n * Pull the YAML frontmatter block from a sub-agent markdown file and\n * return the three fields we care about (`name`, `tools`, `background`)\n * as raw strings. Anything else in the frontmatter is ignored.\n *\n * Returns `null` when the file does not start with a `---` frontmatter\n * fence — those files are not Claude Code sub-agent definitions and we\n * silently skip them rather than emit a noisy parse error.\n *\n * Handles both line-ending conventions (LF and CRLF — Windows\n * contributors / cross-platform plugin authors are a real population)\n * and both `tools:` shapes Claude Code accepts:\n *\n * tools: Read, Grep, Glob # inline comma list (docs default)\n *\n * tools: # YAML sequence (also supported,\n * - Read # GitHub issue\n * - Grep # anthropics/claude-code#19114)\n * - mcp__augmented__*\n *\n * For the sequence form we collect items into a comma-joined string\n * shape `toolsExcludeMcp` already understands. Without this, an\n * MCP-blind sub-agent that uses the array form would slip past the\n * audit because the `tools:` line itself looks empty.\n */\nfunction parseFrontmatter(content: string): ParsedFrontmatter | null {\n // Accept LF or CRLF line endings on the frontmatter fences.\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) return null;\n const out: ParsedFrontmatter = {};\n const lines = match[1]!.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n // Match `key: value` at the start of the line. We don't support\n // arbitrary multi-line YAML values, but we special-case the YAML\n // sequence form for `tools:` below because Claude Code accepts it\n // and at least one community plugin uses it.\n const m = line.match(/^(name|tools|background):\\s*(.*)$/);\n if (!m) continue;\n const [, key, rawValue] = m as unknown as [string, 'name' | 'tools' | 'background', string];\n const trimmed = rawValue.trim();\n\n // YAML sequence for `tools:` — empty inline value followed by\n // indented `- item` lines. Collect them into a comma-joined\n // string. Any line that isn't indented `- item` (including blank\n // lines or the next top-level key) ends the sequence; the outer\n // loop's index walks past whatever we consumed.\n if (key === 'tools' && trimmed === '') {\n const items: string[] = [];\n let j = i + 1;\n while (j < lines.length) {\n const nextRaw = lines[j]!;\n const itemMatch = nextRaw.match(/^(\\s+)-\\s*(.+?)\\s*$/);\n if (!itemMatch) break;\n // Strip surrounding quotes if the YAML author wrote them.\n items.push(itemMatch[2]!.replace(/^['\"](.*)['\"]$/, '$1'));\n j++;\n }\n if (items.length > 0) {\n out.tools = items.join(', ');\n i = j - 1; // resume the outer loop after the consumed items\n continue;\n }\n }\n\n out[key] = trimmed;\n }\n return out;\n}\n\n/**\n * True when the `tools:` frontmatter value would prevent the sub-agent\n * from receiving any `mcp__*` tool on dispatch. The allowlist is\n * considered MCP-safe if it contains either:\n *\n * - a literal `mcp__` substring (an explicit MCP wildcard or tool\n * name like `mcp__granola__*` or `mcp__augmented__list_tools`), or\n * - a bare `*` / `All tools` token (the convention the docs use for\n * full inheritance; Claude Code treats these as \"everything\").\n *\n * If the value is empty, the frontmatter line is effectively absent and\n * the caller falls back to the \"tools: omitted\" inheritance path —\n * this helper returns `false` in that case.\n */\nfunction toolsExcludeMcp(tools: string): boolean {\n if (tools.length === 0) return false;\n if (/\\bmcp__/.test(tools)) return false;\n // Anthropic's convention strings for full inheritance.\n if (/\\*/.test(tools)) return false;\n if (/\\bAll tools\\b/i.test(tools)) return false;\n return true;\n}\n\n/**\n * Walk `dir` recursively and yield absolute paths of every `*.md` file\n * directly under an `agents/` directory. We only care about the\n * `agents/` location because that's where Claude Code looks for\n * sub-agent definitions — `skills/`, `commands/`, etc. live alongside\n * but are unrelated.\n *\n * Symlinks are followed by readdirSync's default behaviour, but we\n * cap directory depth at 6 to avoid getting stuck if a plugin\n * accidentally creates a cycle.\n */\nfunction findSubagentFiles(dir: string, depth = 0): string[] {\n if (depth > 6) return [];\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return []; // Directory missing or unreadable — silently skip.\n }\n const out: string[] = [];\n const isAgentsDir = dir.endsWith('/agents') || dir.endsWith('\\\\agents');\n for (const entry of entries) {\n const full = join(dir, entry);\n let s: ReturnType<typeof statSync>;\n try {\n s = statSync(full);\n } catch {\n continue;\n }\n if (s.isDirectory()) {\n out.push(...findSubagentFiles(full, depth + 1));\n } else if (s.isFile() && isAgentsDir && entry.endsWith('.md')) {\n out.push(full);\n }\n }\n return out;\n}\n\n/**\n * Scan the given root directories for sub-agent definitions whose\n * `tools:` allowlist would block every `mcp__*` tool. The caller\n * passes paths like `~/.claude/agents`, `~/.claude/plugins`, and the\n * agent's project `.claude` dir; we walk each and filter by the\n * `agents/` location convention.\n */\nexport function auditSubagentMcpBindings(rootDirs: string[]): SubagentFinding[] {\n const findings: SubagentFinding[] = [];\n const seen = new Set<string>();\n for (const root of rootDirs) {\n for (const file of findSubagentFiles(root)) {\n if (seen.has(file)) continue;\n seen.add(file);\n let content: string;\n try {\n content = readFileSync(file, 'utf-8');\n } catch {\n continue;\n }\n const fm = parseFrontmatter(content);\n if (!fm || typeof fm.tools !== 'string') continue;\n if (!toolsExcludeMcp(fm.tools)) continue;\n findings.push({\n file,\n name: fm.name ?? '<unknown>',\n tools: fm.tools,\n reason: 'restrictive-tools-no-mcp',\n });\n }\n }\n return findings;\n}\n\n/**\n * Format an audit finding as a single-line structured log entry that\n * matches the manager-worker stderr convention\n * (`[manager-worker] [<subsystem>] ...`). The caller picks where to\n * emit (stderr / manager.log / both).\n */\nexport function formatFinding(f: SubagentFinding): string {\n // Quote the tools value so a comma-bearing list doesn't confuse a\n // future log-parser that splits on whitespace.\n return `[manager-worker] [subagent-mcp-audit] file=${f.file} name=${f.name} reason=${f.reason} tools=${JSON.stringify(f.tools)}`;\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * ENG-5922 — runtime audit for subagent .md `tools:` allowlist\n * staleness vs the agent's actual `.mcp.json` `mcpServers` keys.\n *\n * Why this exists: ENG-5897 + ENG-5905 added the `augmented-worker`\n * sub-agent on the same dynamic-render path as the existing\n * `channel-message-handler` sub-agent. Don's empirical re-test\n * 2026-06-02 showed the rendered `tools:` allowlist on his host was\n * stale — only a subset of the actual `.mcp.json` keys. Causes:\n * (a) the direct-chat manager-worker write bypassed the render\n * chokepoint (fixed in this PR), and (b) the `agt provision` command\n * builds `.mcp.json` without integration data, producing a 1-server\n * file that pollutes the rendered .md (tracked separately as a\n * follow-up). The render-vs-.mcp.json drift had been hidden in\n * production for months because nobody empirically tested the\n * matching invariant.\n *\n * The runtime audit closes the gap by checking, for each managed\n * agent on the host, whether the rendered `tools:` allowlist in\n * `channel-message-handler.md` and `augmented-worker.md` is a\n * superset of the live `.mcp.json` `mcpServers` keys. Drift surfaces\n * as a finding the operator (and CI in `--strict`) can act on\n * without waiting for an agent to silently fail on a missing MCP\n * tool. Strictly read-only — no file mutation.\n */\n\nexport interface RenderDriftFinding {\n /** Agent code_name (the directory name under `~/.augmented/`). */\n agent: string;\n /** Which sub-agent .md is out of sync. */\n subagent: 'channel-message-handler' | 'augmented-worker';\n /** Whether the file we read lives in the provision/ canonical or project/ mirror. */\n scope: 'provision' | 'project';\n /** Server keys present in .mcp.json that the .md's tools allowlist DOESN'T cover. */\n missing: string[];\n /** Absolute path to the .md file with the stale allowlist. */\n file: string;\n}\n\n/**\n * Sanitise an MCP server key to the wildcard form Claude Code emits\n * (`<key>` → `mcp__<key_with_hyphens_to_underscores>__*`). Mirror of\n * the `sanitizeMcpName` function in\n * `packages/core/src/provisioning/frameworks/claudecode/index.ts`.\n */\nfunction expectedWildcard(serverKey: string): string {\n return `mcp__${serverKey.replace(/-/g, '_')}__*`;\n}\n\n/**\n * Extract the `tools:` allowlist tokens from a rendered sub-agent\n * .md file. Returns the list of `mcp__*` wildcards (NOT the\n * built-ins like `Bash`/`Read`/etc., which are out of scope here).\n * Returns `null` when the file has no `tools:` line at all (would be\n * the inheritance-omitted shape ENG-5897 originally shipped — kept\n * as a distinct return so the caller can decide).\n */\nexport function parseMcpWildcardsFromToolsLine(content: string): string[] | null {\n const toolsLine = content.split('\\n').find((l) => l.startsWith('tools:'));\n if (!toolsLine) return null;\n const value = toolsLine.replace(/^tools:\\s*/, '').trim();\n if (value.length === 0) return [];\n return value\n .split(/\\s*,\\s*/)\n .map((t) => t.trim())\n .filter((t) => t.startsWith('mcp__'));\n}\n\n/**\n * Read an agent's `.mcp.json` (provision-scope) and return the\n * top-level `mcpServers` keys, or `null` when the file is missing\n * or unreadable — the caller silently skips that agent in those\n * cases.\n */\nfunction readMcpServerKeys(mcpJsonPath: string): string[] | null {\n try {\n const config = JSON.parse(readFileSync(mcpJsonPath, 'utf-8')) as {\n mcpServers?: Record<string, unknown>;\n };\n return Object.keys(config.mcpServers ?? {});\n } catch {\n return null;\n }\n}\n\n/**\n * Scan every managed-agent directory under `~/.augmented/` (one\n * directory per `code_name`) and report any sub-agent .md whose\n * `tools:` allowlist is missing a wildcard for a server present in\n * the agent's `.mcp.json`. Both the `provision/` canonical and the\n * `project/` mirror are checked — the mirror is what Claude Code\n * actually reads at session-spawn time, but a provision/ drift is\n * still a bug (the next sync will propagate it to project/).\n */\nexport function auditMcpRenderAllowlist(\n rootDir: string = join(homedir(), '.augmented'),\n): RenderDriftFinding[] {\n const findings: RenderDriftFinding[] = [];\n\n let entries: string[];\n try {\n entries = readdirSync(rootDir);\n } catch {\n return findings; // Root missing — no managed agents on this host.\n }\n\n for (const entry of entries) {\n const agentDir = join(rootDir, entry);\n let s: ReturnType<typeof statSync>;\n try {\n s = statSync(agentDir);\n } catch {\n continue;\n }\n if (!s.isDirectory() || entry.startsWith('_') || entry.startsWith('.')) continue;\n\n // For each scope, audit both sub-agent files against the\n // canonical .mcp.json from THAT scope (provision vs project).\n // A provision/ drift indicates the render at agt-provision time\n // missed a server; a project/ drift indicates a subsequent\n // mutation didn't re-trigger the render.\n for (const scope of ['provision', 'project'] as const) {\n const mcpJsonPath = scope === 'provision'\n ? join(agentDir, 'provision', '.mcp.json')\n : join(agentDir, 'project', '.mcp.json');\n const keys = readMcpServerKeys(mcpJsonPath);\n if (keys === null || keys.length === 0) continue;\n const expected = new Set(keys.map(expectedWildcard));\n\n for (const subagent of ['channel-message-handler', 'augmented-worker'] as const) {\n const mdPath = scope === 'provision'\n ? join(agentDir, '.claude', 'agents', `${subagent}.md`)\n : join(agentDir, 'project', '.claude', 'agents', `${subagent}.md`);\n let content: string;\n try {\n content = readFileSync(mdPath, 'utf-8');\n } catch {\n continue; // .md not yet rendered (new agent or agt-pre-ENG-5905) — skip.\n }\n const declared = parseMcpWildcardsFromToolsLine(content);\n if (declared === null) continue; // no tools: line → inheritance mode (different shape).\n const declaredSet = new Set(declared);\n const missing = [...expected].filter((w) => !declaredSet.has(w));\n if (missing.length > 0) {\n findings.push({ agent: entry, subagent, scope, missing, file: mdPath });\n }\n }\n }\n }\n\n return findings;\n}\n\n/**\n * Single-line structured log entry matching the manager-worker\n * stderr convention. Callers (the CLI + the manager boot probe)\n * decide where to emit.\n */\nexport function formatRenderDriftFinding(f: RenderDriftFinding): string {\n return `[manager-worker] [mcp-render-drift] agent=${f.agent} subagent=${f.subagent} scope=${f.scope} missing=${JSON.stringify(f.missing)} file=${f.file}`;\n}\n","import { auditMcpRenderAllowlist, formatRenderDriftFinding } from '../lib/mcp-render-allowlist-audit.js';\n\n/**\n * ENG-5922 — `agt audit mcp-render` command.\n *\n * Walks `~/.augmented/<agent>/` directories on the host and reports\n * every sub-agent .md whose `tools:` allowlist is missing a wildcard\n * for an MCP server present in that agent's `.mcp.json`. Catches the\n * staleness Don found on his host (rendered allowlist diverged from\n * actual server set; trivially-correct sub-agent calls failed).\n *\n * Exit codes:\n * 0 — no findings (or some findings; we still exit 0 because the\n * drift may be transient mid-poll-cycle)\n * 2 — only used with `--strict`. CI / post-deploy verification\n * gates a deploy on a clean audit.\n *\n * Same shape as `agt audit subagents` (ENG-5897) and `agt audit\n * secrets` (ENG-5901). Three audit CLIs, three different invariants.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n}\n\nexport async function auditMcpRenderCommand(options: AuditOptions = {}): Promise<void> {\n const findings = auditMcpRenderAllowlist();\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write(\n 'No render drift found. Every managed agent\\'s sub-agent .md `tools:` allowlist covers every server in its `.mcp.json`.\\n',\n );\n } else {\n process.stdout.write(\n `Found ${findings.length} sub-agent .md file${findings.length === 1 ? '' : 's'} with a stale tools allowlist:\\n\\n`,\n );\n for (const f of findings) {\n process.stdout.write(` • ${f.agent}/${f.scope}/${f.subagent}.md\\n`);\n process.stdout.write(` missing: ${f.missing.join(', ')}\\n`);\n process.stdout.write(` file: ${f.file}\\n`);\n }\n process.stdout.write(\n '\\nA missing wildcard means the sub-agent will get \"No such tool available.\" on any call ' +\n 'to that MCP server. The fix is to force a re-render (e.g. by adding/removing any MCP server, ' +\n 'which routes through syncMcpToProject), OR restart the manager so the next poll picks up the ' +\n 'live `.mcp.json` state. The root-cause write path that bypassed the render chokepoint is ' +\n 'tracked in ENG-5922.\\n',\n );\n for (const f of findings) {\n process.stderr.write(`${formatRenderDriftFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n auditSecretLeaks,\n formatSecretFinding,\n type SecretAuditFinding,\n} from '../lib/secret-leak-audit.js';\n\n/**\n * ENG-5901 (Phase 1 of ADR-0018) — `agt audit secrets` command.\n *\n * Walks `~/.augmented/<agent>/{provision,project}/.mcp.json` and\n * `~/.augmented/<agent>/.env.integrations` and reports:\n * - literal (non-templated) secrets in secret-named `.mcp.json`\n * env/header fields (should be `${VAR}` placeholders), and\n * - secret files that are group/other-readable (should be 0600).\n *\n * Exit codes:\n * 0 — no findings, OR findings present without `--strict`.\n * 2 — `--strict` and at least one finding (CI deploy gate).\n *\n * Never prints a secret value — only file / agent / server / field.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n /** Override the scan root (defaults to ~/.augmented). Used by tests. */\n root?: string;\n}\n\nfunction describe(f: SecretAuditFinding): string {\n if (f.kind === 'literal-secret-in-mcp') {\n return `literal secret in ${f.location} field '${f.field}' of server '${f.server}'`;\n }\n return `secret file is mode ${f.mode} (expected 0600)`;\n}\n\nexport async function auditSecretsCommand(options: AuditOptions = {}): Promise<void> {\n const root = options.root ?? join(homedir(), '.augmented');\n const findings = auditSecretLeaks(root);\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings, root }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write(\n `No literal secrets or world-readable secret files found under ${root}.\\n`,\n );\n } else {\n process.stdout.write(\n `Found ${findings.length} secret-handling issue${findings.length === 1 ? '' : 's'} under ${root}:\\n\\n`,\n );\n for (const f of findings) {\n process.stdout.write(` • [${f.agent}] ${describe(f)}\\n`);\n process.stdout.write(` ${f.file}\\n`);\n }\n process.stdout.write(\n '\\nLiteral secrets in .mcp.json should be `${VAR}` placeholders with the raw value in ' +\n '.env.integrations (mode 0600). See docs/operator/credential-migration-eng5898.md.\\n',\n );\n for (const f of findings) {\n process.stderr.write(`${formatSecretFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { LITERAL_SECRET_PATTERNS } from '@augmented/core/provisioning/mcp-secret-lint.js';\n\n/**\n * ENG-5901 (Phase 1 of ADR-0018) — operator-side audit for literal\n * secrets in on-disk agent config. Sibling to `agt audit subagents`\n * (ENG-5897) and `agt audit mcp-render` (ENG-5922).\n *\n * Why this exists (vs. the runtime lint in @augmented/core's\n * mcp-secret-lint): the runtime lint is a *contributor-side* gate that\n * rejects a bad write at provision/sync time. This audit is the\n * *operator-side* counterpart that walks what's already on disk:\n *\n * - `~/.augmented/<agent>/provision/.mcp.json`\n * - `~/.augmented/<agent>/project/.mcp.json`\n * - `~/.augmented/<agent>/.env.integrations`\n *\n * It catches three things the runtime lint structurally can't:\n * 1. historical leaks written before the lint existed,\n * 2. drift where a writer was bypassed,\n * 3. world-readable secret files (mode 0644 — the audit-observed\n * default for `.mcp.json`; `.env.integrations` should be 0600).\n *\n * Strictly read-only: `fs.readFileSync` / `fs.statSync` only, never a\n * write. `--strict` exits 2 so CI can gate a deploy on a clean audit.\n *\n * Secret VALUES never appear in findings or output — only the file,\n * agent, server, and field name. The whole point is not to leak.\n */\n\n/** Field-name shapes that conventionally hold a secret. */\nexport const SECRET_KEY_NAME_RE = /TOKEN|KEY|SECRET|BEARER|PASSWORD/i;\n\n/** A value is considered safely templated if it defers to a `${VAR}`\n * placeholder (e.g. `${SLACK_BOT_TOKEN}` or `Bearer ${API_KEY}`). The\n * literal secret never reaches disk in that case — Claude Code\n * substitutes it at MCP-launch time. */\nfunction isTemplated(value: string): boolean {\n return value.includes('${');\n}\n\n/** A value matching one of the shared literal-secret shapes (xoxb-/xapp-/\n * tlk_/ak_/Telegram/JWT — same list the runtime lint enforces) is a leak\n * regardless of what the field is called. Catches e.g. a literal\n * `Authorization: Bearer eyJ…` whose key name carries no secret hint\n * (CodeRabbit #1731). */\nfunction matchesKnownSecretShape(value: string): boolean {\n return LITERAL_SECRET_PATTERNS.some(({ re }) => re.test(value));\n}\n\nexport type SecretAuditKind =\n | 'literal-secret-in-mcp'\n | 'world-readable-secret-file';\n\nexport interface SecretAuditFinding {\n kind: SecretAuditKind;\n /** Absolute path of the offending file. */\n file: string;\n /** Agent code_name (the directory under the augmented root). */\n agent: string;\n /** MCP server key — only for `literal-secret-in-mcp`. */\n server?: string;\n /** env key / header name — only for `literal-secret-in-mcp`. */\n field?: string;\n /** Whether the literal sat in an `env` value or a `headers` value. */\n location?: 'env' | 'header';\n /** Octal mode (e.g. `0644`) — only for `world-readable-secret-file`. */\n mode?: string;\n}\n\ninterface McpServerEntry {\n env?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n}\n\n/** A secret file should be 0600. Any group/other permission bit is a leak. */\nfunction isWorldReadable(mode: number): boolean {\n return (mode & 0o077) !== 0;\n}\n\nfunction octal(mode: number): string {\n return `0${(mode & 0o777).toString(8)}`;\n}\n\nfunction scanMcpFile(\n file: string,\n agent: string,\n findings: SecretAuditFinding[],\n): void {\n let mode: number | null = null;\n try {\n mode = statSync(file).mode;\n } catch {\n return; // missing file — nothing to audit\n }\n if (mode !== null && isWorldReadable(mode)) {\n findings.push({ kind: 'world-readable-secret-file', file, agent, mode: octal(mode) });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(file, 'utf-8'));\n } catch {\n return; // unreadable / malformed JSON — mode finding (if any) still stands\n }\n const servers = (parsed as { mcpServers?: Record<string, unknown> })?.mcpServers;\n if (typeof servers !== 'object' || servers === null) return;\n\n for (const [server, raw] of Object.entries(servers)) {\n if (typeof raw !== 'object' || raw === null) continue;\n const entry = raw as McpServerEntry;\n const blocks: Array<[Record<string, unknown> | undefined, 'env' | 'header']> = [\n [entry.env, 'env'],\n [entry.headers, 'header'],\n ];\n for (const [block, location] of blocks) {\n if (!block) continue;\n for (const [field, value] of Object.entries(block)) {\n if (typeof value !== 'string' || value.length === 0) continue;\n if (isTemplated(value)) continue;\n // Union of two detectors (CodeRabbit #1731): a secret-NAMED field\n // holding any untemplated literal (drift catch — covers tokens\n // with no recognisable prefix), OR any field whose VALUE matches a\n // known secret shape (covers e.g. `Authorization: Bearer eyJ…`\n // where the key name carries no hint). Replacing the name check\n // entirely would regress the first class, so both run.\n if (!SECRET_KEY_NAME_RE.test(field) && !matchesKnownSecretShape(value)) continue;\n findings.push({ kind: 'literal-secret-in-mcp', file, agent, server, field, location });\n }\n }\n }\n}\n\n/** `.env.integrations` legitimately holds raw secrets, so we only check\n * its file mode (must be 0600), never its contents. */\nfunction scanEnvIntegrations(\n file: string,\n agent: string,\n findings: SecretAuditFinding[],\n): void {\n let mode: number;\n try {\n mode = statSync(file).mode;\n } catch {\n return;\n }\n if (isWorldReadable(mode)) {\n findings.push({ kind: 'world-readable-secret-file', file, agent, mode: octal(mode) });\n }\n}\n\n/**\n * Walk every agent under `augmentedRoot` (default `~/.augmented`) and\n * return findings. Pure read-only; takes the root as a parameter so\n * tests can point it at a fixture.\n */\nexport function auditSecretLeaks(augmentedRoot: string): SecretAuditFinding[] {\n const findings: SecretAuditFinding[] = [];\n let agents: string[];\n try {\n agents = readdirSync(augmentedRoot);\n } catch {\n return findings; // root missing — nothing provisioned locally\n }\n for (const agent of agents) {\n const agentDir = join(augmentedRoot, agent);\n try {\n if (!statSync(agentDir).isDirectory()) continue;\n } catch {\n continue;\n }\n scanMcpFile(join(agentDir, 'provision', '.mcp.json'), agent, findings);\n scanMcpFile(join(agentDir, 'project', '.mcp.json'), agent, findings);\n scanEnvIntegrations(join(agentDir, '.env.integrations'), agent, findings);\n }\n return findings;\n}\n\n/** Single-line structured log entry, secret-free. Mirrors the\n * `agt audit subagents` stderr convention. */\nexport function formatSecretFinding(f: SecretAuditFinding): string {\n const parts = [\n '[audit-secrets]',\n `kind=${f.kind}`,\n `agent=${f.agent}`,\n `file=${f.file}`,\n ];\n if (f.server) parts.push(`server=${f.server}`);\n if (f.field) parts.push(`field=${f.field}`);\n if (f.location) parts.push(`location=${f.location}`);\n if (f.mode) parts.push(`mode=${f.mode}`);\n return parts.join(' ');\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { api, ApiError } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface IntegrationSummary {\n id: string;\n name: string;\n slug: string;\n category: string;\n status: string;\n version: number;\n skills: unknown[];\n defined_scopes: unknown[];\n}\n\ninterface IntegrationDetail extends IntegrationSummary {\n description: string | null;\n required_toolkits: string[];\n allowed_tools: string[];\n scripts: Record<string, string>;\n defined_scopes: Array<{\n id: string;\n name: string;\n description: string;\n default_min_role: string;\n }>;\n}\n\ninterface AgentIntegrationRow {\n id: string;\n agent_id: string;\n plugin_id: string;\n plugin_version: number;\n granted_scopes: string[];\n installed_at: string;\n}\n\ninterface ScopeRequest {\n id: string;\n agent_id: string;\n plugin_id: string;\n requested_scopes: string[];\n reason: string | null;\n status: string;\n requested_by: string;\n created_at: string;\n}\n\n// ── List ──────────────────────────────────────────────────────────────────\n\nexport async function integrationListCommand(): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching integrations…', isSilent: json }).start();\n\n try {\n const data = await api.get<IntegrationSummary[]>('/integrations/bindings');\n spinner.stop();\n\n if (json) {\n jsonOutput({ integrations: data });\n return;\n }\n\n if (!data.length) {\n info('No integrations found for this team.');\n return;\n }\n\n console.log(chalk.bold('\\nAvailable Integrations:\\n'));\n for (const p of data) {\n const statusColor = p.status === 'published' ? chalk.green : p.status === 'archived' ? chalk.gray : chalk.yellow;\n console.log(\n ` ${chalk.bold(p.name)} ${chalk.dim(`(${p.slug})`)} ${statusColor(p.status)} v${p.version} ${chalk.dim(`${p.skills?.length ?? 0} skills, ${p.defined_scopes?.length ?? 0} scopes`)}`,\n );\n }\n console.log();\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Show ──────────────────────────────────────────────────────────────────\n\nexport async function integrationShowCommand(slug: string): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching integration…', isSilent: json }).start();\n\n try {\n // List all and find by slug\n const all = await api.get<IntegrationDetail[]>('/integrations/bindings');\n const integration = all.find((p) => p.slug === slug);\n\n if (!integration) {\n spinner.stop();\n error(`Integration \"${slug}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Fetch effective scopes\n const scopes = await api.get<Array<{\n id: string;\n name: string;\n effective_min_role: string;\n is_overridden: boolean;\n can_grant: boolean;\n }>>(`/integrations/bindings/${integration.id}/scopes`);\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ integration, scopes });\n return;\n }\n\n console.log(chalk.bold(`\\n${integration.name}`), chalk.dim(`(${integration.slug})`));\n if (integration.description) console.log(chalk.dim(integration.description));\n console.log();\n console.log(` Status: ${integration.status} v${integration.version}`);\n console.log(` Category: ${integration.category}`);\n console.log(` Toolkits: ${integration.required_toolkits.join(', ') || 'none'}`);\n console.log(` Skills: ${integration.skills?.length ?? 0}`);\n\n if (scopes.length > 0) {\n console.log(chalk.bold('\\n Permission Scopes:\\n'));\n for (const s of scopes) {\n const roleColor = s.can_grant ? chalk.green : chalk.red;\n const overrideTag = s.is_overridden ? chalk.cyan(' [team override]') : '';\n console.log(\n ` ${chalk.bold(s.id)} ${s.name} min: ${roleColor(s.effective_min_role)}${overrideTag} ${s.can_grant ? chalk.green('✓ grantable') : chalk.red('✗ needs approval')}`,\n );\n }\n }\n console.log();\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Install ───────────────────────────────────────────────────────────────\n\nexport async function integrationInstallCommand(\n slug: string,\n options: { agent: string; scopes?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Installing integration…', isSilent: json }).start();\n\n try {\n // Resolve integration ID from slug\n const all = await api.get<IntegrationDetail[]>('/integrations/bindings');\n const integration = all.find((p) => p.slug === slug);\n if (!integration) {\n spinner.stop();\n error(`Integration \"${slug}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Resolve agent ID from code name\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const agent = agents.find((a) => a.code_name === options.agent);\n if (!agent) {\n spinner.stop();\n error(`Agent \"${options.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const scopes = options.scopes?.split(',').map((s) => s.trim()).filter(Boolean) ?? [];\n\n const result = await api.post<AgentIntegrationRow>('/integrations/bindings/install', {\n agent_id: agent.agent_id,\n plugin_id: integration.id,\n scopes,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ agent_integration: result });\n return;\n }\n\n success(`Installed \"${integration.name}\" on agent \"${options.agent}\"`);\n if (scopes.length) {\n info(`Granted scopes: ${scopes.join(', ')}`);\n }\n } catch (err) {\n spinner.stop();\n if (err instanceof ApiError && err.status === 403 && err.body['needs_approval']) {\n const needsApproval = err.body['needs_approval'] as string[];\n error('Some scopes exceed your role ceiling:');\n for (const s of needsApproval) {\n console.log(chalk.yellow(` - ${s}`));\n }\n info('To request elevated scopes, use the web dashboard or contact your team admin.');\n process.exitCode = 1;\n return;\n }\n handleError(err);\n }\n}\n\n// ── Uninstall ─────────────────────────────────────────────────────────────\n\nexport async function integrationUninstallCommand(\n slug: string,\n options: { agent: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Uninstalling integration…', isSilent: json }).start();\n\n try {\n const all = await api.get<IntegrationDetail[]>('/integrations/bindings');\n const integration = all.find((p) => p.slug === slug);\n if (!integration) { spinner.stop(); error(`Integration \"${slug}\" not found.`); process.exitCode = 1; return; }\n\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const agent = agents.find((a) => a.code_name === options.agent);\n if (!agent) { spinner.stop(); error(`Agent \"${options.agent}\" not found.`); process.exitCode = 1; return; }\n\n await api.post('/integrations/bindings/uninstall', {\n agent_id: agent.agent_id,\n plugin_id: integration.id,\n });\n spinner.stop();\n success(`Uninstalled \"${integration.name}\" from agent \"${options.agent}\"`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Scope Requests ────────────────────────────────────────────────────────\n\nexport async function integrationRequestsCommand(): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching scope requests…', isSilent: json }).start();\n\n try {\n const requests = await api.get<ScopeRequest[]>('/integrations/bindings/scope-requests');\n spinner.stop();\n\n if (json) {\n jsonOutput({ requests });\n return;\n }\n\n if (!requests.length) {\n info('No pending scope requests.');\n return;\n }\n\n console.log(chalk.bold('\\nPending Scope Requests:\\n'));\n for (const r of requests) {\n console.log(` ${chalk.bold(r.id)} scopes: ${r.requested_scopes.join(', ')}`);\n if (r.reason) console.log(` reason: ${chalk.dim(r.reason)}`);\n console.log(` status: ${r.status} requested: ${r.created_at}`);\n console.log();\n }\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Approve ───────────────────────────────────────────────────────────────\n\nexport async function integrationApproveCommand(\n requestId: string,\n options: { notes?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Approving request…', isSilent: json }).start();\n\n try {\n const result = await api.put(`/integrations/bindings/scope-requests/${requestId}`, {\n status: 'approved',\n review_notes: options.notes,\n });\n spinner.stop();\n\n if (json) {\n jsonOutput(result);\n return;\n }\n\n success(`Scope request ${requestId} approved. Scopes have been granted.`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Deny ──────────────────────────────────────────────────────────────────\n\nexport async function integrationDenyCommand(\n requestId: string,\n options: { reason?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Denying request…', isSilent: json }).start();\n\n try {\n const result = await api.put(`/integrations/bindings/scope-requests/${requestId}`, {\n status: 'denied',\n review_notes: options.reason,\n });\n spinner.stop();\n\n if (json) {\n jsonOutput(result);\n return;\n }\n\n success(`Scope request ${requestId} denied.`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Enrol ─────────────────────────────────────────────────────────────────\n//\n// ENG-4962: wraps POST /integrations/ for API-key onboarding so adding a\n// new integration is one command instead of raw SQL. The endpoint runs\n// the ENG-4953 fail-closed encryption gate, so a credential supplied here\n// is encrypted before it lands in organization_integrations /\n// team_integrations / agent_integrations.\n//\n// OAuth integrations follow a different path (callback-driven); this\n// command intentionally only covers api_key / webhook auth types where\n// the secret is known at enrolment time.\n\ninterface EnrolledIntegrationRow {\n id: string;\n definition_id: string;\n status: string;\n}\n\ninterface EnrolOptions {\n def: string;\n scope: 'org' | 'team' | 'agent' | 'organization';\n apiKey?: string;\n accessToken?: string;\n webhookSecret?: string;\n displayName?: string;\n agent?: string;\n authType?: 'api_key' | 'oauth2' | 'webhook';\n}\n\nexport async function integrationEnrolCommand(options: EnrolOptions): Promise<void> {\n const json = isJsonMode();\n\n // Normalise scope: `org` is the runtime-scope vocabulary; the API\n // accepts the historical `organization` form. Both map to the same row.\n const apiScope = options.scope === 'org' ? 'organization' : options.scope;\n if (!['organization', 'team', 'agent'].includes(apiScope)) {\n error(`Invalid scope \"${options.scope}\". Use org, team, or agent.`);\n process.exitCode = 1;\n return;\n }\n\n // Build the credentials object from the secret-bearing flags. The\n // endpoint accepts {access_token} (OAuth-style) and {api_key} as\n // alternative bearer fields — exactly one secret flag should be set.\n const secrets: Array<[string, string]> = [];\n if (options.apiKey) secrets.push(['api_key', options.apiKey]);\n if (options.accessToken) secrets.push(['access_token', options.accessToken]);\n if (options.webhookSecret) secrets.push(['webhook_secret', options.webhookSecret]);\n if (secrets.length === 0) {\n error('One of --api-key, --access-token, or --webhook-secret is required.');\n process.exitCode = 1;\n return;\n }\n if (secrets.length > 1) {\n error('Only one of --api-key, --access-token, --webhook-secret may be set.');\n process.exitCode = 1;\n return;\n }\n const [secretKey, secretValue] = secrets[0]!;\n const credentials: Record<string, string> = { [secretKey]: secretValue };\n\n const authType = options.authType\n ?? (options.webhookSecret ? 'webhook'\n : options.apiKey ? 'api_key'\n : 'oauth2');\n\n const spinner = ora({ text: `Enrolling ${options.def} at ${apiScope} scope…`, isSilent: json }).start();\n\n try {\n // For agent scope, resolve the agent's UUID from its code_name. Team\n // scope auto-resolves from the team header; org scope derives from\n // the team's organization_id server-side (ENG-4962 endpoint tweak).\n let agentId: string | undefined;\n if (apiScope === 'agent') {\n if (!options.agent) {\n spinner.stop();\n error('--agent <code-name> is required for agent scope.');\n process.exitCode = 1;\n return;\n }\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const found = agents.find((a) => a.code_name === options.agent);\n if (!found) {\n spinner.stop();\n error(`Agent \"${options.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n agentId = found.agent_id;\n }\n\n // Resolve a display_name from the definition if the caller didn't\n // supply one. Saves the user from having to type \"Resend\" twice.\n let displayName = options.displayName;\n if (!displayName) {\n const defs = await api.get<IntegrationDetail[]>('/integrations/bindings');\n const def = defs.find((d) => d.slug === options.def);\n displayName = def?.name ?? options.def;\n }\n\n const result = await api.post<{ integration: EnrolledIntegrationRow }>('/integrations', {\n scope: apiScope,\n definition_id: options.def,\n display_name: displayName,\n auth_type: authType,\n credentials,\n config: {},\n ...(agentId ? { agent_id: agentId } : {}),\n });\n\n spinner.stop();\n\n const row = result.integration;\n if (json) {\n jsonOutput({ integration: row });\n return;\n }\n\n success(`Enrolled \"${displayName}\" (${options.def}) at ${apiScope} scope`);\n info(`Integration ID: ${row.id}`);\n info(`Status: ${row.status}`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction handleError(err: unknown): void {\n if (err instanceof ApiError) {\n error(`API error (${err.status}): ${err.message}`);\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAS,QAAAA,cAAY;AACrB,SAAS,WAAAC,gBAAe;AACxB,SAAS,eAAe;;;ACVxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAMhB,eAAsB,gBAA+B;AACnD,QAAM,OAAO,WAAW;AACxB,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,QAAQ;AACX,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,yBAAyB,CAAC;AAAA,IAC3D,OAAO;AACL,YAAM,oEAAoE;AAAA,IAC5E;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,EAAE,MAAM,4BAA4B,UAAU,KAAK,CAAC;AACxE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,WAAW,MAAM,eAAe,MAAM;AAC5C,YAAQ,KAAK;AAEb,UAAM,YAAY,SAAS,aAAa;AACxC,UAAM,kBAAkB,SAAS,mBAAmB,YAChD,gBAAgB,SAAS,8BAA8B,SAAS,MAChE;AAEJ,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,gBAAgB,OAAO,MAAM,GAAG,CAAC,IAAI;AAAA,QACrC,MAAM,QAAQ;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,MAAM,SAAS;AAAA,QACf,SAAS,SAAS;AAAA,QAClB,OAAO,SAAS;AAAA,QAChB,WAAW,SAAS;AAAA,QACpB,kBAAkB,SAAS;AAAA,QAC3B,+BAA+B,SAAS;AAAA,MAC1C,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,2BAA2B;AACnC,SAAK,eAAe,MAAM,KAAK,OAAO,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE;AAC7D,SAAK,eAAe,MAAM,KAAK,QAAQ,CAAC,CAAC,EAAE;AAC3C,SAAK,eAAe,SAAS,MAAM,EAAE;AACrC,SAAK,eAAe,MAAM,KAAK,SAAS,YAAY,SAAS,MAAM,CAAC,EAAE;AACtE,SAAK,eAAe,MAAM,KAAK,SAAS,aAAa,SAAS,CAAC,EAAE;AACjE,SAAK,eAAe,MAAM,KAAK,SAAS,CAAC,EAAE;AAC3C,QAAI,cAAc,eAAe;AAC/B,WAAK,gBAAgB,MAAM,KAAK,eAAe,CAAC,EAAE;AAAA,IACpD;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,6BAA6B;AAC1C,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;ACpEA,OAAOC,YAAW;AAClB,OAAOC,UAAS;;;ACMT,SAAS,cAAuB;AACrC,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,UAAM,oEAAoE;AAC1E,YAAQ,WAAW;AACnB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,cAA6B;AAC3C,MAAI,CAAC,YAAY,EAAG,QAAO;AAC3B,SAAO;AACT;;;ADTA,eAAsB,kBAAiC;AACrD,MAAI,CAAC,YAAY,EAAG;AAEpB,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,KAAI,EAAE,MAAM,wBAAwB,UAAU,KAAK,CAAC;AACpE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IASpB,QAAQ;AAEX,YAAQ,KAAK;AAEb,QAAI,CAAC,KAAK,SAAS,KAAK,MAAM,WAAW,GAAG;AAC1C,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,MACpC,OAAO;AACL,aAAK,8EAA8E;AAAA,MACrF;AACA;AAAA,IACF;AAEA,UAAM,aAAa,cAAc;AAEjC,QAAI,MAAM;AACR,YAAM,QAAQ,KAAK,MAAM,IAAI,CAAC,QAAQ;AAAA,QACpC,MAAM,GAAG;AAAA,QACT,MAAM,GAAG;AAAA,QACT,MAAM,GAAG;AAAA,QACT,QAAQ,GAAG,SAAS;AAAA,MACtB,EAAE;AACF,iBAAW,EAAE,IAAI,MAAM,MAAM,CAAC;AAC9B;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,MAAM,IAAI,CAAC,OAAO;AAClC,YAAM,SAAS,GAAG,SAAS,aAAaC,OAAM,MAAM,GAAG,IAAI;AAC3D,aAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;AAAA,IAC3C,CAAC;AAED,UAAM,CAAC,IAAI,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,EAC1C,SAAS,KAAK;AACZ,YAAQ,KAAK,wBAAwB;AACrC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBAAkB,MAA6B;AACnE,MAAI,CAAC,YAAY,EAAG;AAEpB,QAAM,OAAO,WAAW;AACxB,QAAM,OAAO,KACV,YAAY,EACZ,KAAK,EACL,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAEzB,MAAI,CAAC,MAAM;AACT,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,oBAAoB,CAAC;AAAA,IACtD,OAAO;AACL,YAAM,yEAAyE;AAAA,IACjF;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAUD,KAAI,EAAE,MAAM,kBAAkB,IAAI,MAAM,IAAI,WAAW,UAAU,KAAK,CAAC;AACvF,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAEpB,UAAU,EAAE,MAAM,KAAK,CAAC;AAG3B,kBAAc,KAAK,KAAK,IAAI;AAE5B,YAAQ,QAAQ,SAASC,OAAM,KAAK,IAAI,CAAC,YAAY;AAErD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,MAAM,MAAM,KAAK,KAAK,MAAM,MAAM,KAAK,KAAK,KAAK,CAAC;AACzE;AAAA,IACF;AAEA,SAAK,SAASA,OAAM,KAAK,KAAK,KAAK,IAAI,CAAC,EAAE;AAC1C,YAAQ,sBAAsBA,OAAM,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG;AAAA,EAC7D,SAAS,KAAK;AACZ,YAAQ,KAAK,wBAAwB;AACrC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBAAkB,MAA6B;AACnE,MAAI,CAAC,YAAY,EAAG;AAEpB,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,KAAI,EAAE,MAAM,sBAAsB,IAAI,WAAW,UAAU,KAAK,CAAC;AACjF,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,IAAI,IAAI,UAAU,mBAAmB,IAAI,CAAC,EAAE;AAElD,kBAAc,IAAI;AAClB,YAAQ,QAAQ,sBAAsBC,OAAM,KAAK,IAAI,CAAC,GAAG;AAEzD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,MAAM,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,6BAA6B,IAAI,IAAI;AAClD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;AEhKA,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,OAAO,QAAQ,gBAAyB;AACjD,SAAS,kBAAkB;AAC3B,SAAS,WAAW,qBAAqB;AACzC,SAAS,YAAY;AAgBrB,SAAS,OAAO,MAAsB;AACpC,SAAO,KACJ,YAAY,EACZ,KAAK,EACL,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AAC3B;AAEA,SAAS,iBAAiB,aAAqC;AAC7D,aAAW,KAAK,aAAa;AAC3B,UAAM,SAAS,EAAE,aAAa,UAAUC,OAAM,IAAI,KAAK,IAAIA,OAAM,OAAO,MAAM;AAC9E,UAAM,OAAO,EAAE,OAAOA,OAAM,IAAI,KAAK,EAAE,IAAI,GAAG,IAAI;AAClD,YAAQ,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE;AAAA,EAC3D;AACF;AAuBA,eAAsB,YAAY,MAAkC;AAClE,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,iBAAiB,CAAC,CAAC,KAAK;AAC9B,QAAM,OAAO,WAAW;AAExB,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,gBAAgB;AAClB,kBAAc,KAAK;AACnB,eAAW,KAAK,YAAY,OAAO,WAAW;AAC9C,kBAAc,KAAK,eAAe,GAAG,WAAW;AAChD,kBAAe,KAAK,OAAO;AAC3B,eAAY,KAAK,YAAY;AAC7B,iBAAc,KAAK,cAAc;AACjC,wBAAqB,eAAe,YAAY,eAAe,SAC3D,OAAO,KAAK,gBAAgB,OAAO,IACnC;AACJ,yBAAsB,eAAe,aAAa,eAAe,SAC7D,OAAO,KAAK,iBAAiB,IAAI,IACjC;AACJ,kBAAc,qBAAqB,sBAAsB;AACzD,mBAAgB,KAAK,gBAAgB;AACrC,wBAAqB,KAAK,qBAAqB;AAC/C,uBAAmB,KAAK,WACpB,KAAK,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAC5C,CAAC;AACL,kBAAe,KAAK,WAAW;AAAA,EACjC,OAAO;AACL,YAAQ,IAAIA,OAAM,KAAK,wCAAmC,CAAC;AAE3D,kBAAc,MAAM,MAAM;AAAA,MACxB,SAAS;AAAA,MACT,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK;AAAA,IAC1C,CAAC;AAED,UAAM,gBAAgB,OAAO,WAAW;AACxC,eAAW,MAAM,MAAM;AAAA,MACrB,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,MAAM,0CAA0C,KAAK,CAAC,KAAK;AAAA,IACxE,CAAC;AAED,kBAAc,MAAM,MAAM;AAAA,MACxB,SAAS;AAAA,MACT,SAAS,GAAG,WAAW;AAAA,IACzB,CAAC;AAED,kBAAc,MAAM,OAAO;AAAA,MACzB,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,OAAO,MAAM,MAAM;AAAA,QAC5B,EAAE,OAAO,SAAS,MAAM,QAAQ;AAAA,QAChC,EAAE,OAAO,QAAQ,MAAM,OAAO;AAAA,MAChC;AAAA,IACF,CAAC;AAED,eAAW,MAAM,OAAO;AAAA,MACtB,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,OAAO,MAAM,qCAAgC;AAAA,QACtD,EAAE,OAAO,UAAU,MAAM,4CAAuC;AAAA,QAChE,EAAE,OAAO,QAAQ,MAAM,gDAA2C;AAAA,MACpE;AAAA,IACF,CAAC;AAED,iBAAa,MAAM,OAAO;AAAA,MACxB,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,MAAM,SAAS;AAAA,QAClC,EAAE,OAAO,WAAW,MAAM,UAAU;AAAA,QACpC,EAAE,OAAO,QAAQ,MAAM,OAAO;AAAA,MAChC;AAAA,IACF,CAAC;AAED,kBAAc;AACd,wBAAoB;AACpB,yBAAqB;AAErB,QAAI,eAAe,YAAY,eAAe,QAAQ;AACpD,YAAM,MAAM,MAAM,MAAM;AAAA,QACtB,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,KAAK;AAAA,MACzD,CAAC;AACD,0BAAoB,OAAO,GAAG;AAC9B,oBAAc;AAAA,IAChB;AAEA,QAAI,eAAe,aAAa,eAAe,QAAQ;AACrD,YAAM,MAAM,MAAM,MAAM;AAAA,QACtB,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,KAAK;AAAA,MACzD,CAAC;AACD,2BAAqB,OAAO,GAAG;AAC/B,UAAI,eAAe,UAAW,eAAc;AAAA,IAC9C;AAEA,mBAAe,MAAM,OAAO;AAAA,MAC1B,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,SAAS,MAAM,QAAQ;AAAA,QAChC,EAAE,OAAO,UAAU,MAAM,SAAS;AAAA,QAClC,EAAE,OAAO,WAAW,MAAM,UAAU;AAAA,MACtC;AAAA,IACF,CAAC;AAED,wBAAoB,MAAM,OAAO;AAAA,MAC/B,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,SAAS,MAAM,4CAAuC;AAAA,QAC/D,EAAE,OAAO,YAAY,MAAM,uCAAkC;AAAA,QAC7D,EAAE,OAAO,SAAS,MAAM,oCAA+B;AAAA,QACvD,EAAE,OAAO,WAAW,MAAM,yCAAoC;AAAA,MAChE;AAAA,IACF,CAAC;AAED,UAAM,cAAc,iBAAiB;AACrC,uBAAmB,MAAM,SAAS;AAAA,MAChC,SAAS;AAAA,MACT,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,EAAE;AAAA,IACzD,CAAC;AAED,kBAAc,MAAM,OAAO;AAAA,MACzB,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,YAAY,MAAM,+BAA0B;AAAA,QACrD,EAAE,OAAO,aAAa,MAAM,qCAAgC;AAAA,QAC5D,EAAE,OAAO,cAAc,MAAM,0CAAqC;AAAA,MACpE;AAAA,IACF,CAAC;AAAA,EACH;AAIA,QAAM,UAAUC,KAAI,EAAE,MAAM,wBAAmB,UAAU,KAAK,CAAC;AAC/D,UAAQ,MAAM;AAEd,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,KAAK,MAAM,IAAI,IAA0C,UAAU;AACzE,aAAS,GAAG;AACZ,gBAAY,GAAG,SAAS,GAAG;AAAA,EAC7B,SAAS,KAAK;AACZ,YAAQ,KAAK,mCAAmC;AAChD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,WAAW;AAI3B,QAAM,eAAuC;AAAA,IAC3C,UAAU;AAAA,IACV,WAAW;AAAA,IACX,cAAc;AAAA,IACd;AAAA,IACA,OAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,IACA,WAAW;AAAA,IACX,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,aAAmC;AAAA,IACvC,UAAU;AAAA,IACV,WAAW;AAAA,IACX;AAAA,IACA,OAAO;AAAA,IACP,cAAc;AAAA,IACd,mBAAmB;AAAA,EACrB;AAEA,QAAM,YAAY,kBAAkB,YAAY;AAChD,QAAM,UAAU,gBAAgB,UAAU;AAI1C,QAAM,aAAa,QAAQ,WAAW,OAAO;AAI7C,MAAI;AACF,UAAM,IAAI,KAAK,WAAW;AAAA,MACxB,WAAW;AAAA,MACX,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,eAAe;AAAA,IACjB,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK,2BAA2B;AACxC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,QAAM,WAAW,KAAK,QAAQ,IAAI,GAAG,cAAc,QAAQ;AAC3D,YAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AACvC,gBAAc,KAAK,UAAU,YAAY,GAAG,SAAS;AACrD,gBAAc,KAAK,UAAU,UAAU,GAAG,OAAO;AAEjD,UAAQ,QAAQ,UAAUD,OAAM,KAAK,WAAW,CAAC,YAAY;AAI7D,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,cAAc;AAAA,MACd;AAAA,MACA,WAAW;AAAA,MACX,UAAU;AAAA,MACV,WAAW;AAAA,MACX,MAAM;AAAA,QACJ,IAAI,WAAW;AAAA,QACf,QAAQ,WAAW,OAAO;AAAA,QAC1B,UAAU,WAAW,SAAS;AAAA,QAC9B,aAAa,CAAC,GAAG,WAAW,QAAQ,GAAG,WAAW,QAAQ;AAAA,MAC5D;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,OAAK,iBAAiB,OAAO,EAAE;AAC/B,OAAK,iBAAiB,QAAQ,EAAE;AAChC,OAAK,iBAAiB,WAAW,EAAE;AACnC,OAAK,iBAAiB,QAAQ,EAAE;AAChC,OAAK,iBAAiB,iBAAiB,SAAS,IAAI,iBAAiB,KAAK,IAAI,IAAI,MAAM,EAAE;AAC1F,OAAK,iBAAiB,QAAQ,uBAAuB;AACrD,UAAQ,IAAI;AAEZ,MAAI,WAAW,MAAM,WAAW,SAAS,WAAW,GAAG;AACrD,YAAQ,2CAAsC;AAAA,EAChD,OAAO;AACL,QAAI,WAAW,OAAO,SAAS,GAAG;AAChC,YAAM,SAAS,WAAW,OAAO,MAAM,WAAW;AAClD,uBAAiB,WAAW,MAAM;AAAA,IACpC;AACA,QAAI,WAAW,SAAS,SAAS,GAAG;AAClC,WAAK,SAAS,WAAW,SAAS,MAAM,aAAa;AACrD,uBAAiB,WAAW,QAAQ;AAAA,IACtC;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,OAAK,aAAa;AAClB,OAAK,aAAaA,OAAM,KAAK,gBAAgB,WAAW,aAAa,CAAC,8BAA8B;AACpG,OAAK,aAAaA,OAAM,KAAK,gBAAgB,WAAW,WAAW,CAAC,eAAe;AACnF,OAAK,YAAYA,OAAM,KAAK,UAAU,CAAC,cAAc;AACrD,OAAK,YAAYA,OAAM,KAAK,YAAY,CAAC,gCAAgC;AAC3E;;;AC3VA,OAAOE,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,cAAc,kBAAkB;AACzC,SAAS,QAAAC,OAAM,eAAe;AAe9B,SAASC,kBAAiB,aAAqC;AAC7D,aAAW,KAAK,aAAa;AAC3B,UAAM,SAAS,EAAE,aAAa,UAAUC,OAAM,IAAI,KAAK,IAAIA,OAAM,OAAO,MAAM;AAC9E,UAAM,OAAOA,OAAM,IAAI,IAAI,EAAE,IAAI,GAAG;AACpC,UAAM,OAAO,EAAE,OAAOA,OAAM,IAAI,KAAK,EAAE,IAAI,GAAG,IAAI;AAClD,YAAQ,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,IAAI,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE;AAAA,EAClE;AACF;AAEA,SAAS,YAAY,OAAe,QAA0B;AAC5D,MAAI,OAAO,MAAM,OAAO,SAAS,WAAW,GAAG;AAC7C,YAAQ,GAAG,KAAK,UAAU;AAC1B;AAAA,EACF;AACA,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,GAAG,KAAK,KAAK,OAAO,OAAO,MAAM,WAAW;AAClD,IAAAD,kBAAiB,OAAO,MAAM;AAAA,EAChC;AACA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,SAAK,GAAG,KAAK,KAAK,OAAO,SAAS,MAAM,aAAa;AACrD,IAAAA,kBAAiB,OAAO,QAAQ;AAAA,EAClC;AACF;AAKA,eAAsB,YAAY,MAA8B;AAC9D,QAAM,OAAO,WAAW;AAExB,QAAM,OAAwC,CAAC;AAE/C,MAAI,MAAM;AACR,UAAM,WAAW,QAAQ,IAAI;AAC7B,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,mBAAmB,QAAQ,GAAG,CAAC;AAAA,MAChE,OAAO;AACL,cAAM,mBAAmB,QAAQ,EAAE;AAAA,MACrC;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,SAAK,KAAK,EAAE,MAAM,MAAM,KAAK,SAAS,CAAC;AAAA,EACzC,OAAO;AACL,UAAM,eAAeE,MAAK,QAAQ,IAAI,GAAG,YAAY;AACrD,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,iCAAiC,CAAC;AAAA,MACnE,OAAO;AACL,cAAM,uDAAuD;AAAA,MAC/D;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,EAAE,aAAAC,cAAa,UAAAC,UAAS,IAAI,MAAM,OAAO,IAAS;AACxD,UAAM,UAAUD,aAAY,YAAY;AACxC,eAAW,SAAS,SAAS;AAC3B,YAAM,YAAYD,MAAK,cAAc,KAAK;AAC1C,UAAIE,UAAS,SAAS,EAAE,YAAY,GAAG;AACrC,aAAK,KAAK,EAAE,MAAM,OAAO,KAAK,UAAU,CAAC;AAAA,MAC3C;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,GAAG;AACrB,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,4CAA4C,CAAC;AAAA,MAC9E,OAAO;AACL,cAAM,kEAAkE;AAAA,MAC1E;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACJ,QAAM,WAAW,YAAY;AAC7B,MAAI,UAAU;AACZ,UAAM,UAAUC,KAAI,EAAE,MAAM,qCAAgC,UAAU,KAAK,CAAC;AAC5E,YAAQ,MAAM;AACd,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,IAOpB,UAAU,mBAAmB,QAAQ,CAAC,iBAAiB;AAE1D,UAAI,KAAK,gBAAgB;AACvB,oBAAY;AAAA,UACV,iBAAiB,KAAK,eAAe;AAAA,UACrC,kBAAmB,KAAK,eAAe,oBAAoB,CAAC;AAAA,UAC5D,iBAAkB,KAAK,eAAe,mBAAmB,CAAC;AAAA,UAC1D,0BAA0B,KAAK,eAAe,4BAA4B;AAAA,QAC5E;AAAA,MACF;AACA,cAAQ,KAAK;AAAA,IACf,QAAQ;AACN,cAAQ,KAAK;AAAA,IAEf;AAAA,EACF;AAEA,MAAI,cAAc;AAClB,MAAI,gBAAgB;AACpB,QAAM,cAAyC,CAAC;AAEhD,aAAW,EAAE,MAAM,IAAI,KAAK,MAAM;AAChC,QAAI,CAAC,KAAM,SAAQ,IAAIJ,OAAM,KAAK;AAAA,UAAa,IAAI,GAAG,CAAC;AAEvD,UAAM,cAAcC,MAAK,KAAK,YAAY;AAC1C,UAAM,YAAYA,MAAK,KAAK,UAAU;AACtC,UAAM,aAAa,WAAW,WAAW;AACzC,UAAM,WAAW,WAAW,SAAS;AAErC,QAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,UAAI,CAAC,KAAM,MAAK,kDAA6C;AAC7D,UAAI,KAAM,aAAY,KAAK,EAAE,OAAO,MAAM,SAAS,KAAK,CAAC;AACzD;AAAA,IACF;AAEA,UAAM,iBAAiB,aAAa,aAAa,aAAa,OAAO,IAAI;AACzE,UAAM,eAAe,WAAW,aAAa,WAAW,OAAO,IAAI;AAEnE,QAAI;AACJ,QAAI,kBAAkB,cAAc;AAClC,eAAS,QAAQ,gBAAgB,cAAc,EAAE,kBAAkB,UAAU,CAAC;AAC9E,UAAI,CAAC,KAAM,aAAY,aAAa,MAAM;AAAA,IAC5C,WAAW,gBAAgB;AACzB,eAAS,YAAY,gBAAgB,EAAE,kBAAkB,UAAU,CAAC;AACpE,UAAI,CAAC,KAAM,aAAY,cAAc,MAAM;AAAA,IAC7C,OAAO;AACL,eAAS,UAAU,YAAa;AAChC,UAAI,CAAC,KAAM,aAAY,YAAY,MAAM;AAAA,IAC3C;AAEA,mBAAe,OAAO,OAAO;AAC7B,qBAAiB,OAAO,SAAS;AAEjC,QAAI,MAAM;AACR,kBAAY,KAAK;AAAA,QACf,OAAO;AAAA,QACP,IAAI,OAAO;AAAA,QACX,QAAQ,OAAO,OAAO;AAAA,QACtB,UAAU,OAAO,SAAS;AAAA,QAC1B,aAAa,CAAC,GAAG,OAAO,QAAQ,GAAG,OAAO,QAAQ;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI,gBAAgB;AAAA,MACpB,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAI,cAAc,EAAG,SAAQ,WAAW;AACxC;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,MAAI,gBAAgB,KAAK,kBAAkB,GAAG;AAC5C,YAAQ,OAAO,KAAK,MAAM,wBAAwB;AAAA,EACpD,OAAO;AACL,QAAI,cAAc,GAAG;AACnB,YAAM,UAAU,WAAW,oBAAoB,KAAK,MAAM,WAAW;AACrE,cAAQ,WAAW;AAAA,IACrB;AACA,QAAI,gBAAgB,GAAG;AACrB,WAAK,UAAU,aAAa,sBAAsB,KAAK,MAAM,WAAW;AAAA,IAC1E;AAAA,EACF;AACF;;;ACnMA,OAAOI,YAAW;AAClB,OAAOC,UAAS;AAiBT,SAAS,sBAA4B;AAC1C,QAAM,OAAO,WAAW;AAExB,MAAI,MAAM;AACR,UAAMC,YAAW,iBAAiB,IAAI,CAAC,QAAQ;AAAA,MAC7C,IAAI,GAAG;AAAA,MACP,MAAM,GAAG;AAAA,MACT,eAAe,GAAG;AAAA,MAClB,eAAe,GAAG;AAAA,MAClB,aAAa,GAAG;AAAA,MAChB,sBAAsB,GAAG;AAAA,IAC3B,EAAE;AACF,eAAW,EAAE,IAAI,MAAM,UAAAA,UAAS,CAAC;AACjC;AAAA,EACF;AAEA,UAAQ,IAAIC,OAAM,KAAK,oCAAoC,CAAC;AAE5D,QAAM,OAAO,iBAAiB,IAAI,CAAC,OAAO;AAAA,IACxC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,iBAAiB,aAChBA,OAAM,MAAM,GAAG,YAAY,IAC3B,GAAG,iBAAiB,YAClBA,OAAM,IAAI,GAAG,YAAY,IACzBA,OAAM,KAAK,GAAG,YAAY;AAAA,IAChC,OAAO,GAAG,iBAAiB,YACtB,GAAG,eAAeA,OAAM,MAAM,KAAK,IAAIA,OAAM,IAAI,IAAI,IACtDA,OAAM,OAAO,GAAG,YAAY;AAAA,IAChC,OAAO,GAAG,eAAe,YACpB,GAAG,aAAaA,OAAM,MAAM,KAAK,IAAIA,OAAM,IAAI,IAAI,IACpDA,OAAM,OAAO,GAAG,UAAU;AAAA,IAC9B,GAAG,uBAAuB,SACtBA,OAAM,IAAI,GAAG,kBAAkB,IAC/B,GAAG,uBAAuB,WACxBA,OAAM,OAAO,GAAG,kBAAkB,IAClCA,OAAM,MAAM,GAAG,kBAAkB;AAAA,EACzC,CAAC;AAED,QAAM,CAAC,MAAM,QAAQ,iBAAiB,iBAAiB,eAAe,aAAa,GAAG,IAAI;AAC5F;AAKA,eAAsB,qBAAqB,eAAsC;AAC/E,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,KAAI,EAAE,MAAM,2BAA2B,aAAa,WAAM,UAAU,KAAK,CAAC;AAC1F,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAQpB,WAAW,mBAAmB,aAAa,CAAC,WAAW;AAE1D,UAAM,cAA6B;AAAA,MACjC,QAAQ;AAAA,MACR,SAAU,KAAK,kBAAkB,CAAC;AAAA,MAClC,QAAQ,CAAC;AAAA,MACT,4BAA4B;AAAA,IAC9B;AAEA,UAAM,YAA0C,KAAK,iBACjD;AAAA,MACE,iBAAiB,KAAK,eAAe;AAAA,MACrC,kBAAmB,KAAK,eAAe,oBAAoB,CAAC;AAAA,MAC5D,iBAAkB,KAAK,eAAe,mBAAmB,CAAC;AAAA,MAC1D,0BAA0B,KAAK,eAAe,4BAA4B;AAAA,IAC5E,IACA;AAEJ,UAAM,WAAW,gBAAgB,aAAa,SAAS;AAEvD,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,iBAAiB,YAAY;AAAA,QAC7B,YAAY,YACR;AAAA,UACE,SAAS,UAAU;AAAA,UACnB,QAAQ,UAAU;AAAA,UAClB,0BAA0B,UAAU;AAAA,QACtC,IACA;AAAA,QACJ,mBAAmB;AAAA,QACnB,OAAO,SAAS;AAAA,MAClB,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,IAAID,OAAM,KAAK;AAAA,sBAAyB,aAAa;AAAA,CAAI,CAAC;AAElE,SAAK,oBAAoB,YAAY,QAAQ,SAAS,IAAI,YAAY,QAAQ,KAAK,IAAI,IAAI,MAAM,EAAE;AAEnG,QAAI,WAAW;AACb,WAAK,gBAAgB,UAAU,iBAAiB,SAAS,IAAI,UAAU,iBAAiB,KAAK,IAAI,IAAI,sBAAsB,EAAE;AAC7H,WAAK,gBAAgB,UAAU,gBAAgB,SAAS,IAAI,UAAU,gBAAgB,KAAK,IAAI,IAAI,MAAM,EAAE;AAC3G,UAAI,UAAU,0BAA0B;AACtC,aAAK,6CAA6C;AAAA,MACpD;AAAA,IACF,OAAO;AACL,WAAK,mCAAmC;AAAA,IAC1C;AAEA,YAAQ,IAAI;AAEZ,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,uEAAuE;AAC7E,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,OAAO,SAAS,IAAI,CAAC,SAAS;AAClC,YAAM,KAAK,WAAW,IAAI;AAC1B,aAAO;AAAA,QACL;AAAA,QACA,IAAI,QAAQ;AAAA,QACZ,IAAI,gBAAgB;AAAA,QACpB,IAAI,sBAAsB;AAAA,MAC5B;AAAA,IACF,CAAC;AAED,YAAQ,GAAG,SAAS,MAAM,wBAAwB;AAClD,UAAM,CAAC,MAAM,QAAQ,iBAAiB,aAAa,GAAG,IAAI;AAAA,EAC5D,SAAS,KAAK;AACZ,YAAQ,KAAK,6BAA6B;AAC1C,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;ACnKA,OAAOE,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,YAAAC,WAAU,WAAAC,UAAS,SAAAC,cAAa;AAkBzC,SAAS,iBAAiB;AAC1B,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAc;AAKvB,eAAsB,yBACpB,eACA,SAQe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,KAAI,EAAE,MAAM,qBAAqB,aAAa,WAAM,UAAU,KAAK,CAAC;AACpF,UAAQ,MAAM;AAEd,MAAI;AAEF,UAAM,YAAY,MAAM,IAAI,IAOzB,WAAW,mBAAmB,aAAa,CAAC,EAAE;AAEjD,UAAMC,SAAQ,UAAU;AAGxB,UAAMC,YAAqBD,OAAM,YAAY,CAAC;AAC9C,QAAI,CAACC,UAAS,SAAS,OAAO,GAAG;AAC/B,cAAQ,KAAK,UAAU,aAAa,4CAA4C;AAChF,YAAM,iFAAkF;AACxF,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,YAAQ,QAAQ,gBAAgB,aAAa,GAAG;AAGhD,QAAI;AAEJ,QAAI,QAAQ,QAAQ;AAClB,uBAAiB,QAAQ,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IAChE,WAAW,QAAQ,QAAQ;AACzB,YAAM,SAAS,QAAQ;AACvB,UAAI,EAAE,UAAU,sBAAsB;AACpC,cAAM,mBAAmB,QAAQ,MAAM,uCAAuC;AAC9E,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,uBAAiB,CAAC,GAAG,oBAAoB,MAAM,CAAC;AAChD,WAAK,UAAU,MAAM,aAAa,eAAe,MAAM,UAAU;AAAA,IACnE,WAAW,MAAM;AACf,uBAAiB,CAAC,GAAG,oBAAoB,QAAQ;AAAA,IACnD,OAAO;AACL,YAAM,mBAAmB,oBAAoB;AAC7C,YAAM,WAAW,sBAAsB;AAIvC,YAAM,UAAqD,CAAC;AAC5D,iBAAW,CAAC,UAAU,IAAI,KAAK,kBAAkB;AAC/C,cAAM,QAAQ,4BAA4B,QAA8B;AACxE,gBAAQ,KAAK,EAAE,MAAM,aAAa,WAAW,gBAAM,KAAK,gBAAM,CAAC;AAC/D,mBAAW,OAAO,MAAM;AACtB,gBAAM,YACJ,IAAI,SAAS,SAASC,OAAM,MAAM,IAAI,SAAS,WAAWA,OAAM,SAASA,OAAM;AACjF,kBAAQ,KAAK;AAAA,YACX,MAAM,GAAG,IAAI,KAAK,IAAIA,OAAM,IAAI,UAAK,IAAI,WAAW,EAAE,CAAC,IAAI,UAAU,IAAI,IAAI,IAAI,GAAG,CAAC;AAAA,YACrF,OAAO,IAAI;AAAA,YACX,SAAS,SAAS,SAAS,IAAI,KAAK;AAAA,UACtC,CAAC;AAAA,QACH;AAAA,MACF;AAEA,uBAAiB,MAAMC,UAAS;AAAA,QAC9B,SAAS;AAAA,QACT;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,QAAI,eAAe,WAAW,GAAG;AAC/B,YAAM,qDAAqD;AAC3D,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,SAAK,YAAY,eAAe,MAAM,cAAc,eAAe,KAAK,IAAI,CAAC,EAAE;AAG/E,UAAM,WAAW,yBAAyB;AAAA,MACxC,YAAYH,OAAM,gBAAgB;AAAA,MAClC,aAAa,yCAAyC,aAAa;AAAA,MACnE,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,cAAc,6BAA6B,QAAQ;AAEzD,UAAM,eAAe,KAAK,UAAU,aAAa,MAAM,CAAC;AACxD,UAAM,eAAeF,MAAK,OAAO,GAAG,4BAA4B,aAAa,OAAO;AACpF,UAAM,UAAU,cAAc,cAAc,OAAO;AAEnD,YAAQ,uBAAuB,YAAY,EAAE;AAC7C,YAAQ,IAAII,OAAM,IAAI,YAAY,CAAC;AAGnC,QAAI;AACJ,QAAI,cAAkC,QAAQ;AAC9C,QAAI,mBAAuC,QAAQ;AAEnD,QAAI,CAAC,QAAQ,YAAY;AACvB,UAAI,QAAQ,QAAQ;AACpB,UAAI,CAAC,SAAS,CAAC,MAAM;AACnB,iBAAS,MAAME,OAAM;AAAA,UACnB,SAAS;AAAA,QACX,CAAC,GAAG,KAAK,KAAK;AAAA,MAChB;AAEA,UAAI,OAAO;AACT,cAAM,gBAAgBL,KAAI,EAAE,MAAM,oCAA+B,UAAU,KAAK,CAAC;AACjF,sBAAc,MAAM;AAEpB,YAAI;AACF,gBAAM,SAAS,MAAM,eAAe,OAAO,QAAQ;AACnD,kBAAQ,OAAO;AACf,6BAAmB,sBAAsB,aAAa;AACtD,wBAAc,QAAQ,sBAAsB,OAAO,MAAM,EAAE;AAC3D,eAAK,cAAc,OAAO,mBAAmB,EAAE;AAAA,QACjD,SAAS,KAAK;AACZ,wBAAc,KAAK,qCAAqC;AACxD,cAAI,eAAe,eAAe;AAChC,iBAAK,oBAAoB,IAAI,OAAO,EAAE;AAAA,UACxC,OAAO;AACL,iBAAM,IAAc,OAAO;AAAA,UAC7B;AACA,eAAK,sBAAsB,YAAY,EAAE;AACzC,eAAK,gFAAgF;AAAA,QACvF;AAAA,MACF,OAAO;AACL,aAAK,sBAAsB,YAAY,EAAE;AACzC,aAAK,gFAAgF;AAAA,MACvF;AAAA,IACF;AAEA,QAAI,CAAC,oBAAoB,CAAC,MAAM;AAC9B,YAAM,SAAS,MAAMK,OAAM;AAAA,QACzB,SAAS;AAAA,MACX,CAAC;AACD,UAAI,OAAO,KAAK,GAAG;AACjB,2BAAmB,sBAAsB,aAAa;AAAA,MACxD;AAAA,IACF;AAEA,QAAI,CAAC,eAAe,CAAC,MAAM;AACzB,YAAM,QAAQ,MAAMA,OAAM;AAAA,QACxB,SAAS;AAAA,MACX,CAAC;AACD,UAAI,MAAM,KAAK,GAAG;AAChB,sBAAc,sBAAsB,aAAa;AAAA,MACnD;AAAA,IACF;AAGA,UAAM,gBAAgBL,KAAI,EAAE,MAAM,+BAA0B,UAAU,KAAK,CAAC;AAC5E,kBAAc,MAAM;AAEpB,UAAM,SAAS;AAAA,MACb,cAAc;AAAA,MACd,UAAUC,OAAM,gBAAgB;AAAA,MAChC,QAAQ;AAAA,MACR,GAAI,QAAQ,EAAE,QAAQ,MAAM,IAAI,CAAC;AAAA,MACjC,GAAI,cAAc,EAAE,eAAe,YAAY,IAAI,CAAC;AAAA,MACpD,GAAI,mBAAmB,EAAE,oBAAoB,iBAAiB,IAAI,CAAC;AAAA,MACnE;AAAA,IACF;AAEA,QAAI;AACF,YAAM,IAAI;AAAA,QACR,WAAW,mBAAmB,aAAa,CAAC;AAAA,QAC5C;AAAA,UACE;AAAA,UACA,QAAQ,cAAc,eAAe;AAAA,QACvC;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,oBAAc,KAAK,gCAAgC;AACnD,YAAO,IAAc,OAAO;AAC5B,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,kBAAc,QAAQ,6BAA6B;AAEnD,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,cAAc,eAAe;AAAA,QACrC,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,IAAI;AACZ,cAAQ,6BAA6B,aAAa,GAAG;AACrD,WAAK,WAAW,cAAc,eAAe,uCAAuC,EAAE;AAAA,IACxF;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,qBAAqB;AAClC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAKA,eAAsB,0BAA0B,eAAsC;AACpF,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,KAAI,EAAE,MAAM,8BAA8B,aAAa,WAAM,UAAU,KAAK,CAAC;AAC7F,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAapB,WAAW,mBAAmB,aAAa,CAAC,wBAAwB;AAEvE,YAAQ,KAAK;AAEb,UAAM,SAAS,KAAK;AAEpB,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,IAAIG,OAAM,KAAK;AAAA,uBAA0B,aAAa;AAAA,CAAI,CAAC;AAEnE,UAAM,OAAmB;AAAA,MACvB,CAAC,YAAY,OAAO,YAAY,GAAG;AAAA,MACnC,CAAC,UAAU,OAAO,UAAU,GAAG;AAAA,MAC/B,CAAC,WAAW,OAAO,WAAW,GAAG;AAAA,MACjC,CAAC,aAAa,OAAO,gBAAgBA,OAAM,MAAM,YAAY,IAAIA,OAAM,IAAI,SAAS,CAAC;AAAA,MACrF,CAAC,kBAAkB,OAAO,qBAAqBA,OAAM,MAAM,YAAY,IAAIA,OAAM,IAAI,SAAS,CAAC;AAAA,MAC/F,CAAC,WAAW,OAAO,UAAU,CAAC,GAAG,KAAK,IAAI,KAAK,GAAG;AAAA,IACpD;AAEA,UAAM,CAAC,SAAS,OAAO,GAAG,IAAI;AAAA,EAChC,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,QAAK,IAAY,WAAW,KAAK;AAC/B,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,MAAM,OAAO,eAAe,SAAS,SAAS,YAAY,MAAM,CAAC;AAAA,MACpF,OAAO;AACL,aAAK,qCAAqC,aAAa,IAAI;AAC3D,aAAK,mCAAmC,gBAAgB,iBAAiB;AAAA,MAC3E;AACA;AAAA,IACF;AAEA,YAAQ,KAAK,+BAA+B;AAC5C,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAKA,eAAsB,0BAA0B,eAAsC;AACpF,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUH,KAAI,EAAE,MAAM,qBAAqB,aAAa,WAAM,UAAU,KAAK,CAAC;AACpF,UAAQ,MAAM;AAEd,MAAI;AAEF,QAAI,SAAwD;AAC5D,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,IAA+D,WAAW,mBAAmB,aAAa,CAAC,wBAAwB;AAC1J,eAAS,KAAK;AAAA,IAChB,SAAS,KAAK;AACZ,UAAK,IAAY,WAAW,KAAK;AAC/B,gBAAQ,KAAK,qCAAqC,aAAa,IAAI;AACnE,YAAI,MAAM;AACR,qBAAW,EAAE,IAAI,MAAM,OAAO,eAAe,SAAS,SAAS,SAAS,OAAO,QAAQ,iBAAiB,CAAC;AAAA,QAC3G;AACA;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAEA,YAAQ,KAAK;AAGb,QAAI,CAAC,MAAM;AACT,YAAM,WAAW,QAAQ,SACrB,aAAa,OAAO,MAAM,MAC1B,QAAQ,WACN,KAAK,OAAO,QAAQ,MACpB;AACN,YAAM,YAAY,MAAMM,SAAQ;AAAA,QAC9B,SAAS,iCAAiC,QAAQ,SAAS,aAAa;AAAA,QACxE,SAAS;AAAA,MACX,CAAC;AAED,UAAI,CAAC,WAAW;AACd,aAAK,UAAU;AACf;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgBN,KAAI,EAAE,MAAM,sCAAiC,UAAU,KAAK,CAAC;AACnF,kBAAc,MAAM;AAEpB,UAAM,IAAI,IAAI,WAAW,mBAAmB,aAAa,CAAC,wBAAwB;AAElF,kBAAc,QAAQ,8BAA8B;AAEpD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,OAAO,eAAe,SAAS,SAAS,SAAS,KAAK,CAAC;AAAA,IAChF,OAAO;AACL,UAAI,QAAQ,QAAQ;AAClB,gBAAQ,IAAI;AACZ,aAAK,wBAAwB,OAAO,MAAM,yCAAyC;AACnF,aAAK,uEAAuE;AAAA,MAC9E;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAO,IAAc,OAAO;AAC5B,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;AC7YA,OAAOO,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,WAAAC,gBAAe;AASxB,eAAsB,wBACpB,eACA,SAKe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,KAAI,EAAE,MAAM,qBAAqB,aAAa,WAAM,UAAU,KAAK,CAAC;AACpF,UAAQ,MAAM;AAEd,MAAI;AAEF,UAAM,YAAY,MAAM,IAAI,IAQzB,WAAW,mBAAmB,aAAa,CAAC,EAAE;AAEjD,UAAMC,SAAQ,UAAU;AAGxB,UAAMC,YAAqBD,OAAM,YAAY,CAAC;AAC9C,QAAI,CAACC,UAAS,SAAS,MAAM,GAAG;AAC9B,cAAQ,KAAK,UAAU,aAAa,2CAA2C;AAC/E,YAAM,+EAAgF;AACtF,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,YAAQ,QAAQ,gBAAgB,aAAa,GAAG;AAGhD,UAAM,iBAAiB,MAAM,IAAI,IAE9B,WAAW,mBAAmB,aAAa,CAAC,uBAAuB,EAAE,MAAM,OAAO,EAAE,QAAQ,KAAK,EAAE;AAEtG,QAAI,eAAe,QAAQ,SAAS;AAClC,WAAK,oCAAoCC,OAAM,KAAK,OAAO,eAAe,OAAO,OAAO,CAAC,CAAC,EAAE;AAC5F,YAAM,UAAU,MAAMC,SAAQ;AAAA,QAC5B,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AACD,UAAI,CAAC,QAAS;AAAA,IAChB;AAGA,YAAQ,MAAM,uEAAkE;AAEhF,UAAM,SAAS,MAAM,IAAI,KAStB,WAAW,mBAAmB,aAAa,CAAC,+BAA+B;AAAA,MAC5E,2BAA2B,QAAQ,eAAe;AAAA,MAClD,eAAe,QAAQ;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,OAAO,IAAI;AACd,cAAQ,KAAK,qBAAqB;AAClC,YAAM,OAAO,SAAS,eAAe;AACrC,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,YAAQ,QAAQ,sCAAsC;AAEtD,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,SAAS,OAAO;AAAA,QAChB,KAAK,OAAO;AAAA,QACZ,YAAY,OAAO;AAAA,QACnB,aAAa,OAAO;AAAA,QACpB,mBAAmB,OAAO;AAAA,QAC1B,wBAAwB,OAAO;AAAA,MACjC,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ;AAAA,MACE,CAAC,SAAS,OAAO;AAAA,MACjB;AAAA,QACE,CAAC,WAAWD,OAAM,KAAK,OAAO,OAAO,CAAC;AAAA,QACtC,CAAC,OAAOA,OAAM,IAAI,OAAO,GAAG,CAAC;AAAA,QAC7B,CAAC,eAAe,OAAO,OAAO,WAAW,CAAC;AAAA,QAC1C,CAAC,gBAAgB,OAAO,iBAAiB;AAAA,QACzC,CAAC,gBAAgB,OAAO,uBAAuB,SAAS,IACpD,OAAO,uBAAuB,KAAK,IAAI,IACvCA,OAAM,IAAI,gBAAgB,CAAC;AAAA,MACjC;AAAA,IACF;AACA,YAAQ,IAAI;AACZ,YAAQ,UAAU,aAAa,yBAAyBA,OAAM,KAAK,OAAO,OAAO,CAAC,EAAE;AAAA,EACtF,SAAS,KAAK;AACZ,YAAQ,KAAK,cAAc;AAC3B,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,WAAW;AAAA,EACrB;AACF;AAKA,eAAsB,yBAAyB,eAAsC;AACnF,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUH,KAAI,EAAE,MAAM,6BAA6B,aAAa,WAAM,UAAU,KAAK,CAAC;AAC5F,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAGpB,WAAW,mBAAmB,aAAa,CAAC,uBAAuB;AAEtE,QAAI,CAAC,KAAK,QAAQ,SAAS;AACzB,cAAQ,KAAK,6CAA6C;AAC1D;AAAA,IACF;AAEA,YAAQ,QAAQ,0BAA0B;AAC1C,UAAM,MAAM,KAAK;AAEjB,QAAI,MAAM;AACR,iBAAW,GAAG;AACd;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ;AAAA,MACE,CAAC,SAAS,OAAO;AAAA,MACjB;AAAA,QACE,CAAC,WAAWG,OAAM,KAAK,OAAO,IAAI,OAAO,CAAC,CAAC;AAAA,QAC3C,CAAC,OAAOA,OAAM,IAAI,OAAO,IAAI,OAAO,QAAG,CAAC,CAAC;AAAA,QACzC,CAAC,cAAcA,OAAM,IAAI,OAAO,IAAI,cAAc,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,QAAG,CAAC;AAAA,QACzE,CAAC,eAAe,OAAO,IAAI,eAAe,CAAC,CAAC;AAAA,QAC5C,CAAC,gBAAgB,OAAO,IAAI,qBAAqB,OAAO,CAAC;AAAA,QACzD,CAAC,gBAAgB,IAAI,4BAA4BA,OAAM,MAAM,KAAK,IAAIA,OAAM,IAAI,IAAI,CAAC;AAAA,QACrF,CAAC,gBAAgB,MAAM,QAAQ,IAAI,sBAAsB,KAAK,IAAI,uBAAuB,SAAS,IAC9F,IAAI,uBAAuB,KAAK,IAAI,IACpCA,OAAM,IAAI,MAAM,CAAC;AAAA,QACrB,CAAC,UAAU,KAAK,UAAU,QAAG;AAAA,MAC/B;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd,SAAS,KAAK;AACZ,YAAQ,KAAK,wBAAwB;AACrC,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,WAAW;AAAA,EACrB;AACF;AAKA,eAAsB,yBAAyB,eAAsC;AACnF,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AAExB,MAAI,CAAC,MAAM;AACT,UAAM,UAAU,MAAMC,SAAQ;AAAA,MAC5B,SAAS,8BAA8B,aAAa;AAAA,MACpD,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,QAAS;AAAA,EAChB;AAEA,QAAM,UAAUJ,KAAI,EAAE,MAAM,gCAA2B,UAAU,KAAK,CAAC;AACvE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,IAAI,IAAI,WAAW,mBAAmB,aAAa,CAAC,uBAAuB;AACjF,YAAQ,QAAQ,uBAAuB;AAEvC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,KAAK,CAAC;AAAA,IACzB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,kBAAkB;AAC/B,UAAM,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC1D,YAAQ,WAAW;AAAA,EACrB;AACF;;;ACnNA,OAAOK,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,UAAAC,SAAQ,SAAAC,cAAa;AAC9B,SAAS,iBAAAC,gBAAe,aAAAC,kBAAiB;AACzC,SAAS,QAAAC,aAAY;AAqBrB,eAAsB,cAAc,MAAoC;AACtE,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,iBAAiB,CAAC,CAAC,KAAK;AAC9B,QAAM,OAAO,WAAW;AAExB,MAAI;AACJ,MAAI;AAEJ,MAAI,gBAAgB;AAClB,iBAAa,KAAK;AAClB,eAAW,OAAO,KAAK,QAAQ,MAAM;AACrC,QAAI,MAAM,QAAQ,KAAK,WAAW,KAAK,WAAW,OAAO;AACvD,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,sBAAsB,CAAC;AAAA,MACxD,OAAO;AACL,cAAM,mDAAmD;AAAA,MAC3D;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,IAAIC,OAAM,KAAK,6BAAwB,CAAC;AAEhD,iBAAa,MAAMC,QAAO;AAAA,MACxB,SAAS;AAAA,MACT,SAAS,qBAAqB,IAAI,CAAC,OAAO;AAAA,QACxC,OAAO,EAAE;AAAA,QACT,MAAM,GAAG,EAAE,IAAI,WAAM,EAAE,WAAW;AAAA,MACpC,EAAE;AAAA,IACJ,CAAC;AAED,UAAM,cAAc,MAAMC,OAAM;AAAA,MAC9B,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,MAAM;AACf,cAAM,IAAI,OAAO,CAAC;AAClB,eAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,IAAI,SAAU;AAAA,MAC9C;AAAA,IACF,CAAC;AACD,eAAW,OAAO,WAAW;AAAA,EAC/B;AAEA,QAAM,OAAO,YAAY,UAAU;AACnC,MAAI,CAAC,MAAM;AACT,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,aAAa,UAAU,cAAc,CAAC;AAAA,IACvE,OAAO;AACL,YAAM,aAAa,UAAU,cAAc;AAAA,IAC7C;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,QAAM,UAAUC,KAAI,EAAE,MAAM,yBAAoB,UAAU,KAAK,CAAC;AAChE,UAAQ,MAAM;AAEd,MAAI;AAOJ,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAA+B,SAAS;AAC/D,aAAS,KAAK;AAAA,EAChB,SAAS,KAAK;AACZ,YAAQ,KAAK,yBAAyB;AACtC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,YAAQ,KAAK,0BAA0B;AACvC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,iDAAiD,CAAC;AAAA,IACnF,OAAO;AACL,YAAM,gDAAgD;AAAA,IACxD;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,QAAM,iBAAkC,OAAO,IAAI,CAAC,GAAG,OAAO;AAAA,IAC5D,UAAU,EAAE;AAAA,IACZ,WAAW,EAAE;AAAA,IACb,cAAc,EAAE;AAAA,IAChB,aAAa,EAAE;AAAA,IACf,MAAM,WAAW;AAAA,EACnB,EAAE;AAEF,QAAM,UAA2B;AAAA,IAC/B,QAAQ;AAAA,IACR,SAAS,EAAE,MAAM,SAAS;AAAA,IAC1B,WAAW,CAAC;AAAA,EACd;AAEA,MAAI;AACJ,MAAI;AACF,eAAW,eAAe,KAAK,UAAU,OAAO;AAAA,EAClD,SAAS,KAAK;AACZ,YAAQ,KAAK,4BAA4B;AACzC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,MAAI;AACF,UAAM,IAAI,KAAK,gBAAgB;AAAA,MAC7B,aAAa,KAAK;AAAA,MAClB,WAAW,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,MACvC,WAAW,EAAE,WAAW,SAAS;AAAA,IACnC,CAAC;AAAA,EACH,SAAS,WAAW;AAClB,YAAQ,KAAK;AACb,QAAI,CAAC,KAAM,MAAK,qDAAsD,UAAoB,OAAO,EAAE;AAAA,EACrG;AAIA,QAAM,SAASC,MAAK,QAAQ,IAAI,GAAG,cAAc,QAAQ;AACzD,EAAAC,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC,QAAM,UAAUD,MAAK,QAAQ,qBAAqB;AAClD,EAAAE,eAAc,SAAS,QAAQ;AAE/B,UAAQ,QAAQ,8BAA8B;AAE9C,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,UAAU,KAAK;AAAA,MACf,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MACrC,aAAa;AAAA,IACf,CAAC;AACD;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,OAAK,aAAaN,OAAM,KAAK,KAAK,IAAI,CAAC,EAAE;AACzC,OAAK,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC,EAAE;AAC7D,OAAK,aAAa,OAAO,EAAE;AAC3B,UAAQ,IAAI;AACZ,OAAK,aAAa;AAClB,OAAK,6CAA6C;AACpD;;;AC1LA,OAAOO,YAAW;AAClB,OAAOC,UAAS;AAChB,SAAS,iBAAAC,gBAAe,aAAAC,kBAAiB;AACzC,SAAS,QAAAC,aAAY;AAwBrB,SAASC,kBAAiB,aAAqC;AAC7D,aAAW,KAAK,aAAa;AAC3B,UAAM,SAAS,EAAE,aAAa,UAAUC,OAAM,IAAI,KAAK,IAAIA,OAAM,OAAO,MAAM;AAC9E,UAAM,OAAO,EAAE,OAAOA,OAAM,IAAI,KAAK,EAAE,IAAI,GAAG,IAAI;AAClD,YAAQ,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE;AAAA,EAC3D;AACF;AAKA,eAAsB,iBACpB,UACA,SACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,SAAU,QAAQ,UAAU;AAClC,QAAM,YAAY,QAAQ,UAAUC,MAAK,QAAQ,IAAI,GAAG,cAAc,UAAU,WAAW;AAC3F,QAAM,SAAS,QAAQ,UAAU;AAEjC,MAAI,CAAC,KAAM,SAAQ,IAAID,OAAM,KAAK,gCAA2B,CAAC;AAE9D,QAAM,UAAUE,KAAI,EAAE,MAAM,6BAAwB,UAAU,KAAK,CAAC;AACpE,UAAQ,MAAM;AAId,MAAI;AAaJ,MAAI;AACF,oBAAgB,MAAM,IAAI,IAAI,WAAW,mBAAmB,QAAQ,CAAC,iBAAiB;AAAA,EACxF,SAAS,KAAK;AACZ,YAAQ,KAAK,uCAAuC,QAAQ,IAAI;AAChE,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,YAAY,cAAc;AAEhC,MAAI,CAAC,cAAc,SAAS;AAC1B,YAAQ,KAAK,8BAA8B;AAC3C,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,8BAA8B,CAAC;AAAA,QACnE,OAAM,4CAA4C;AACvD,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,CAAC,cAAc,OAAO;AACxB,YAAQ,KAAK,4BAA4B;AACzC,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,4BAA4B,CAAC;AAAA,QACjE,OAAM,0CAA0C;AACrD,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,UAAQ,OAAO;AAEf,QAAM,iBAAiB,cAAc,QAAQ;AAC7C,QAAM,eAAe,cAAc,MAAM;AAEzC,QAAM,gBAAgB,mBAAmB,cAAc;AACvD,MAAI,CAAC,cAAc,aAAa;AAC9B,YAAQ,KAAK,yCAAyC;AACtD,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,cAAc,SAAS,sBAAsB,CAAC;AAAA,QAClF,OAAM,cAAc,SAAS,qBAAqB;AACvD,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,cAAc,mBAAmB,YAAY;AACnD,MAAI,CAAC,YAAY,aAAa;AAC5B,YAAQ,KAAK,uCAAuC;AACpD,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,YAAY,SAAS,sBAAsB,CAAC;AAAA,QAChF,OAAM,YAAY,SAAS,qBAAqB;AACrD,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,qBAAqB,cAAc;AACzC,QAAM,mBAAmB,YAAY;AAIrC,UAAQ,OAAO;AACf,QAAM,aAAa,QAAQ,gBAAgB,YAAY;AAEvD,MAAI,CAAC,WAAW,IAAI;AAClB,YAAQ,KAAK,sCAAiC;AAC9C,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,WAAW,OAAO;AAAA,UAC1B,UAAU,WAAW,SAAS;AAAA,UAC9B,aAAa,CAAC,GAAG,WAAW,QAAQ,GAAG,WAAW,QAAQ;AAAA,QAC5D;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,MAAAH,kBAAiB,WAAW,MAAM;AAClC,UAAI,WAAW,SAAS,SAAS,EAAG,CAAAA,kBAAiB,WAAW,QAAQ;AAAA,IAC1E;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,WAAW,SAAS,SAAS,KAAK,CAAC,MAAM;AAC3C,YAAQ,KAAK;AACb,SAAK,SAAS,WAAW,SAAS,MAAM,aAAa;AACrD,IAAAA,kBAAiB,WAAW,QAAQ;AACpC,YAAQ,MAAM,oBAAe;AAAA,EAC/B;AAIA,UAAQ,OAAO;AAGf,QAAM,qBAAqB,OAAO,KAAK,cAAc,mBAAmB,CAAC,CAAC;AAE1E,QAAM,qBAAoC;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ,CAAC;AAAA,IACT,4BAA4B;AAAA,EAC9B;AAEA,MAAI;AACJ,QAAM,aAAa,cAAc;AAEjC,MAAI,YAAY;AACd,uBAAmB;AAAA,MACjB,iBAAiB,WAAW;AAAA,MAC5B,kBAAmB,WAAW,oBAAoB,CAAC;AAAA,MACnD,iBAAkB,WAAW,mBAAmB,CAAC;AAAA,MACjD,0BAA0B,WAAW,4BAA4B;AAAA,IACnE;AAAA,EACF;AAEA,QAAM,mBAAmB,gBAAgB,oBAAoB,gBAAgB;AAa7E,UAAQ,OAAO;AAEf,QAAM,UAAU,UAAU;AAC1B,MAAI,eAA4D,CAAC;AACjE,MAAI,oBAAmC;AACvC,MAAI;AACF,UAAM,mBAAmB,MAAM,IAAI,KAWhC,4BAA4B,EAAE,UAAU,QAAQ,CAAC;AACpD,mBAAgB,iBAAiB,gBAC/B,CAAC;AAAA,EACL,SAAS,KAAK;AAKZ,wBAAqB,IAAc;AACnC,QAAI,CAAC,MAAM;AACT,cAAQ,KAAK;AACb;AAAA,QACE,iCAAiC,iBAAiB;AAAA,MAEpD;AACA,cAAQ,MAAM,oBAAe;AAAA,IAC/B;AAAA,EACF;AAIA,QAAM,cAAe,UAAU,aAAwB;AACvD,QAAM,UAAU,aAAa,WAAW;AAExC,UAAQ,OAAO,YAAY,QAAQ,KAAK;AAExC,QAAM,iBAAiC;AAAA,IACrC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,aAAa;AAAA,EACf;AAEA,QAAM,kBAAkB,UAAU,gBAAgB,WAAW;AAE7D,QAAM,aAAa,WAAW,iBAAiB,yBAAyB;AACxE,QAAM,OAAO,YAAY,UAAU;AACnC,MAAI,iBAAiB;AACrB,MAAI,MAAM;AACR,UAAM,kBAAmC;AAAA,MACvC,QAAQ,CAAC;AAAA,QACP,UAAU,UAAU;AAAA,QACpB,WAAW,UAAU;AAAA,QACrB,cAAc,UAAU;AAAA,QACxB,aAAa,UAAU;AAAA,QACvB,MAAM;AAAA,MACR,CAAC;AAAA,MACD,SAAS,EAAE,MAAM,IAAK;AAAA,MACtB,WAAW,CAAC;AAAA,IACd;AACA,qBAAiB,eAAe,KAAK,UAAU,eAAe;AAAA,EAChE;AAIA,MAAI,QAAQ;AACV,YAAQ,KAAK;AACb,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,QACP,WAAW;AAAA,QACX;AAAA,QACA,cAAc,gBAAgB;AAAA,QAC9B,YAAY,gBAAgB;AAAA,QAC5B,UAAU,iBAAiB;AAAA,QAC3B,cAAc,aAAa;AAAA,QAC3B,oBAAoB;AAAA,QACpB,WAAW,gBAAgB,UAAU,IAAI,CAAC,OAAO;AAAA,UAC/C,MAAM,EAAE;AAAA,UACR,MAAM,EAAE,QAAQ;AAAA,QAClB,EAAE;AAAA,QACF,iBAAiB,kBAAkB;AAAA,MACrC,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,SAAK,kCAA6B;AAClC,YAAQ,IAAI;AACZ,eAAW,YAAY,gBAAgB,WAAW;AAChD,cAAQ,IAAIC,OAAM,KAAK,GAAG,SAAS,YAAY,GAAG,CAAC;AACnD,cAAQ,IAAI,SAAS,OAAO;AAAA,IAC9B;AACA,QAAI,gBAAgB;AAClB,cAAQ,IAAIA,OAAM,KAAK,sBAAsB,CAAC;AAC9C,cAAQ,IAAI,cAAc;AAAA,IAC5B;AACA,YAAQ,IAAI;AACZ,SAAK,kBAAkB,gBAAgB,WAAW,EAAE;AACpD,SAAK,eAAe,gBAAgB,SAAS,EAAE;AAC/C;AAAA,EACF;AAIA,UAAQ,OAAO;AAEf,EAAAG,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,aAAW,YAAY,gBAAgB,WAAW;AAChD,IAAAC,eAAcH,MAAK,WAAW,SAAS,YAAY,GAAG,SAAS,OAAO;AAAA,EACxE;AACA,MAAI,gBAAgB;AAClB,IAAAG,eAAcH,MAAK,WAAW,qBAAqB,GAAG,cAAc;AAAA,EACtE;AAIA,UAAQ,OAAO;AAEf,MAAI;AACF,UAAM,IAAI,KAAK,WAAW,mBAAmB,QAAQ,CAAC,wBAAwB;AAAA,MAC5E,iBAAiB,cAAc,QAAQ;AAAA,MACvC,eAAe,cAAc,MAAM;AAAA,MACnC,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,QAAI,CAAC,KAAM,MAAK,qDAAsD,IAAc,OAAO,EAAE;AAAA,EAC/F;AAIA,UAAQ,QAAQ,UAAUD,OAAM,KAAK,UAAU,YAAsB,CAAC,gBAAgB;AAEtF,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,WAAW;AAAA,MACX;AAAA,MACA,YAAY;AAAA,MACZ,cAAc,gBAAgB;AAAA,MAC9B,YAAY,gBAAgB;AAAA,MAC5B,UAAU,iBAAiB;AAAA,MAC3B,cAAc,aAAa;AAAA,MAC3B,oBAAoB;AAAA,MACpB,WAAW,gBAAgB,UAAU,IAAI,CAAC,MAAM,EAAE,YAAY;AAAA,IAChE,CAAC;AACD;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,OAAK,gBAAgB,UAAU,SAAS,EAAE;AAC1C,OAAK,gBAAgB,QAAQ,KAAK,EAAE;AACpC,OAAK,gBAAgB,MAAM,EAAE;AAC7B,OAAK,gBAAgB,SAAS,EAAE;AAChC,OAAK,mBAAmB,gBAAgB,YAAY,MAAM,GAAG,EAAE,CAAC,QAAG;AACnE,OAAK,gBAAgB,gBAAgB,UAAU,MAAM,GAAG,EAAE,CAAC,QAAG;AAC9D,OAAK,gBAAgB,iBAAiB,MAAM,SAAS;AACrD,OAAK,iBAAiB,aAAa,MAAM,GAAG,oBAAoB,oBAAoB,EAAE,EAAE;AACxF,OAAK,gBAAgB,gBAAgB,UAAU,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE;AACtF,UAAQ,IAAI;AACZ,OAAK,aAAa;AAClB,OAAK,QAAQ,SAAS,uBAAuB;AAC7C,OAAK,qBAAqB,UAAU,SAAS,EAAE;AACjD;;;ACtVA,OAAOK,aAAW;AAClB,OAAOC,WAAS;AAChB,SAAS,aAAa;AACtB,SAAS,cAAAC,aAAY,gBAAAC,eAAc,iBAAAC,sBAAqB;AACxD,SAAS,WAAW,WAAAC,UAAS,QAAAC,cAAY;AACzC,SAAS,iBAAAC,sBAAqB;;;AC5B9B,IAAM,UAAU;AAOT,SAAS,qBAA8B;AAC5C,QAAM,IAAI,QAAQ,IAAI,OAAO;AAC7B,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,UAAU,EAAE,KAAK,EAAE,YAAY;AAIrC,SAAO,EAAE,YAAY,MAAM,YAAY,OAAO,YAAY,WAAW,YAAY;AACnF;AAUO,SAAS,4BAAkC;AAChD,MAAI,mBAAmB,EAAG;AAE1B,UAAQ,OAAO;AAAA,IACb;AAAA;AAAA;AAAA,sBAEyB,OAAO;AAAA;AAAA,WAElB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvB;AACA,UAAQ,KAAK,CAAC;AAChB;;;AC1BA,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAErB,IAAM,mBAAmBA,MAAK,QAAQ,GAAG,wBAAwB;AACjE,IAAM,aAAaA,MAAK,kBAAkB,QAAQ;AAMlD,IAAM,uBAAuBA,MAAK,YAAY,eAAe;AAC7D,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAQ5B,SAAS,oBAAoB,YAA4B;AACvD,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC9E,SAAOA,MAAK,YAAY,GAAG,mBAAmB,GAAG,IAAI,GAAG,mBAAmB,EAAE;AAC/E;AAuHA,IAAM,eAAe;AAErB,SAAS,oBAAoB,UAAwB;AACnD,MAAI,CAAC,aAAa,KAAK,QAAQ,GAAG;AAChC,UAAM,IAAI;AAAA,MACR,4BAA4B,QAAQ;AAAA,IACtC;AAAA,EACF;AACF;AAEO,SAAS,0BAA0B,UAA0B;AAClE,sBAAoB,QAAQ;AAC5B,SAAOA,MAAK,kBAAkB,QAAQ;AACxC;AAEO,SAAS,kBAAkB,UAA0B;AAI1D,sBAAoB,QAAQ;AAC5B,QAAM,MAAM,0BAA0B,QAAQ;AAC9C,EAAAH,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,SAAO;AACT;AAUO,SAAS,yBAAyB,UAA0B;AACjE,QAAM,MAAMG,MAAK,kBAAkB,QAAQ,GAAG,SAAS;AACvD,EAAAH,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,SAAO;AACT;AAaA,SAAS,iBAAiB,QAA6C;AACrE,MAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO;AAC1D,QAAM,IAAI;AAEV,QAAM,YACJ,OAAO,EAAE,YAAY,YACrB,EAAE,YAAY,QACd,OAAO,OAAO,EAAE,OAAkC,EAAE;AAAA,IAClD,CAAC,MAAM,MAAM,cAAc,MAAM,iBAAiB,MAAM;AAAA,EAC1D;AAEF,MACE,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,aAAa,YACtB,OAAO,EAAE,YAAY,YACrB,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,eAAe,YACxB,OAAO,EAAE,cAAc,YACvB,OAAO,EAAE,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAKzB,OAAO,EAAE,SAAS,YAClB,EAAE,KAAK,WAAW,KAClB,CAAC,WACD;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGA,SAAS,iBAAiB,MAA0C;AAClE,MAAI,CAACD,YAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,WAAO,iBAAiB,KAAK,MAAME,cAAa,MAAM,OAAO,CAAC,CAAC;AAAA,EACjE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAWA,SAAS,wBAA8B;AACrC,MAAI,CAACF,YAAW,oBAAoB,EAAG;AACvC,QAAM,SAAS,iBAAiB,oBAAoB;AACpD,MAAI;AACF,QAAI,CAAC,QAAQ;AACX,aAAO,sBAAsB,EAAE,OAAO,KAAK,CAAC;AAC5C;AAAA,IACF;AACA,UAAM,SAAS,oBAAoB,OAAO,WAAW;AACrD,QAAI,CAACA,YAAW,MAAM,GAAG;AACvB,MAAAC,WAAU,YAAY,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACtD,iBAAW,sBAAsB,MAAM;AACvC,gBAAU,QAAQ,GAAK;AAAA,IACzB,OAAO;AAEL,aAAO,sBAAsB,EAAE,OAAO,KAAK,CAAC;AAAA,IAC9C;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAWO,SAAS,mBAAmB,YAAgD;AACjF,wBAAsB;AACtB,SAAO,iBAAiB,oBAAoB,UAAU,CAAC;AACzD;AAQO,SAAS,sBAA6C;AAC3D,wBAAsB;AACtB,MAAI;AACJ,MAAI;AACF,cAAU,YAAY,UAAU;AAAA,EAClC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,MAA6B,CAAC;AACpC,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,WAAW,mBAAmB,KAAK,CAAC,MAAM,SAAS,mBAAmB,GAAG;AAClF;AAAA,IACF;AACA,UAAM,WAAW,iBAAiBG,MAAK,YAAY,KAAK,CAAC;AACzD,QAAI,SAAU,KAAI,KAAK,QAAQ;AAAA,EACjC;AACA,SAAO;AACT;AAeO,SAAS,oBAAoB,UAAqC;AACvE,wBAAsB;AACtB,EAAAH,WAAU,YAAY,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACtD,QAAM,OAAO,oBAAoB,SAAS,WAAW;AACrD,QAAM,MAAM,OAAO;AACnB,EAAAE,eAAc,KAAK,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AACrE,YAAU,KAAK,GAAK;AACpB,aAAW,KAAK,IAAI;AACtB;AAOO,SAAS,oBAAoB,YAA0B;AAC5D,wBAAsB;AACtB,QAAM,OAAO,oBAAoB,UAAU;AAC3C,MAAIH,YAAW,IAAI,GAAG;AACpB,WAAO,IAAI;AAAA,EACb;AACF;AAOO,SAAS,UAAU,UAA+B,MAAM,KAAK,IAAI,GAAY;AAClF,SAAO,SAAS,aAAa,OAAQ;AACvC;;;ACnXA;AAAA,EACE,cAAAK;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAAC,gBAAe;AACxB,SAAS,SAAS,QAAAC,OAAM,OAAO,WAAW;AAInC,IAAM,gBAAgB;AAkBtB,SAAS,oBAAoB,UAAiC;AACnE,QAAM,EAAE,KAAK,IAAI,MAAM,QAAQ;AAC/B,MAAI,MAAM;AACV,aAAS;AACP,QAAIH,YAAWG,MAAK,KAAK,MAAM,CAAC,EAAG,QAAO;AAC1C,QAAI,QAAQ,KAAM,QAAO;AACzB,UAAM,SAAS,QAAQ,GAAG;AAG1B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACF;AAkBO,SAAS,kBACd,aACA,aACY;AACZ,MAAI;AAEJ,MAAI,CAAC,UAAU,WAAW,GAAG;AAE3B,WAAO;AAAA,EACT,OAAO;AACL,UAAM,OAAO,UAAU,WAAW;AAClC,QAAI,KAAK,eAAe,GAAG;AACzB,YAAM,SAAS,aAAa,WAAW;AAKvC,YAAM,UACJ,aAAaD,SAAQ,CAAC,IAAI,MAAM,2BAA2B;AAC7D,UAAI;AACJ,UAAI;AACF,yBAAiB,aAAa,WAAW;AAAA,MAC3C,QAAQ;AAIN,cAAM,IAAI;AAAA,UACR,GAAG,WAAW,gCAAgC,MAAM;AAAA,QAEtD;AAAA,MACF;AACA,UAAI,eAAe,WAAW,OAAO,GAAG;AACtC,mBAAW,WAAW;AACtB,eAAO;AAAA,MACT,OAAO;AACL,cAAM,IAAI;AAAA,UACR,GAAG,WAAW,oBAAoB,MAAM,eAAe,cAAc,0DACjB,OAAO;AAAA,QAE7D;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,aAAa,cAAc;AACjC,UAAIF,YAAW,UAAU,GAAG;AAI1B,cAAM,IAAI;AAAA,UACR,GAAG,UAAU;AAAA,QAEf;AAAA,MACF;AACA,MAAAC,YAAW,aAAa,UAAU;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,cAAY,aAAa,aAAa,MAAM;AAC5C,SAAO;AACT;AASO,SAAS,eAAe,aAAqB,MAAwB;AAC1E,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,OAAO,UAAU,WAAW;AAClC,QAAI,KAAK,eAAe,GAAG;AACzB,iBAAW,WAAW;AAAA,IACxB,OAAO;AAGL;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,aAAa,cAAc;AACjC,QAAID,YAAW,UAAU,GAAG;AAC1B,MAAAC,YAAW,YAAY,WAAW;AAAA,IACpC;AAAA,EACF;AAEF;AAEA,SAAS,UAAU,MAAuB;AACxC,MAAI;AACF,cAAU,IAAI;AACd,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC3JA;AAAA,EACE;AAAA,EACA,cAAAG;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,OACK;AACP,SAAS,QAAAC,aAAY;AAYd,IAAM,yBAAyB;AAEtC,IAAM,wBAAwB;AAOvB,SAAS,sBACd,YACA,UAAkB,wBACN;AACZ,QAAM,YAAYC,MAAK,YAAY,SAAS;AAC5C,QAAM,mBAAmB,CAACC,YAAW,SAAS;AAC9C,EAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,eAAeF,MAAK,WAAW,qBAAqB;AAC1D,QAAM,kBAAkBC,YAAW,YAAY;AAC/C,QAAM,aAAa,eAAe;AAElC,MAAI,WAAoC,CAAC;AACzC,MAAI,iBAAiB;AAQnB,QAAI,CAACA,YAAW,UAAU,GAAG;AAC3B,mBAAa,cAAc,UAAU;AAAA,IACvC;AACA,eAAW,cAAc,cAAcE,cAAa,cAAc,OAAO,CAAC,CAAC;AAAA,EAC7E;AAEA,QAAM,QAAQ,cAAc,SAAS,OAAO,CAAC;AAC7C,QAAM,WAAW,MAAM,QAAQ,MAAM,iBAAiB,CAAC,IACnD,CAAC,GAAI,MAAM,iBAAiB,CAAoC,IAChE,CAAC;AAEL,QAAM,oBAAoB,SAAS;AAAA,IAAK,CAAC,UACvC,oBAAoB,OAAO,OAAO;AAAA,EACpC;AACA,MAAI,CAAC,mBAAmB;AACtB,aAAS,KAAK;AAAA,MACZ,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,QAAQ,CAAC;AAAA,IACtC,CAAC;AAAA,EACH;AACA,QAAM,iBAAiB,IAAI;AAC3B,WAAS,OAAO,IAAI;AAEpB,EAAAC,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AAEpE,SAAO;AAAA,IACL,eAAe;AAAA,IACf,iBAAiB,kBAAkB,aAAa;AAAA,IAChD,oBAAoB;AAAA,EACtB;AACF;AAOO,SAAS,wBAAwB,QAA0B;AAChE,QAAM,EAAE,eAAe,iBAAiB,mBAAmB,IAAI;AAC/D,QAAM,aAAa,gBAAgB;AAEnC,MAAI,oBAAoB,YAAY;AAElC,QAAIH,YAAW,UAAU,GAAG;AAC1B,MAAAI,YAAW,YAAY,aAAa;AAAA,IACtC;AAAA,EACF,OAAO;AAEL,QAAIJ,YAAW,aAAa,EAAG,CAAAK,YAAW,aAAa;AACvD,QAAIL,YAAW,UAAU,EAAG,CAAAK,YAAW,UAAU;AAAA,EACnD;AAEA,MAAI,oBAAoB;AACtB,UAAM,YAAY,MAAM,aAAa;AACrC,QAAI;AACF,UAAIL,YAAW,SAAS,KAAKM,aAAY,SAAS,EAAE,WAAW,GAAG;AAChE,kBAAU,SAAS;AAAA,MACrB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,IAAM,oBAAoB;AAE1B,SAAS,oBAAoB,OAAgC,SAA0B;AACrF,MAAK,MAAgC,YAAY,sBAAuB,QAAO;AAC/E,QAAM,aAAc,MAA8B;AAClD,SACE,MAAM,QAAQ,UAAU,KACxB,WAAW;AAAA,IACT,CAAC,MACC,OAAO,MAAM,YACb,MAAM,QACL,EAAyB,SAAS,aAClC,EAA4B,YAAY;AAAA,EAC7C;AAEJ;AAEA,SAAS,MAAM,UAA0B;AACvC,QAAM,MAAM,SAAS,YAAY,GAAG;AACpC,SAAO,QAAQ,KAAK,WAAW,SAAS,MAAM,GAAG,GAAG;AACtD;AAEA,SAAS,cAAc,MAAuB;AAC5C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,cAAc,OAAyC;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD,CAAC;AACP;;;ACpJA;AAAA,EACE,aAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,OACK;AACP,SAAS,WAAAC,gBAAe;AACxB,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;AAWvB,IAAM,4BAA4BC;AAAA,EACvCC,SAAQ;AAAA,EACR;AAAA,EACA;AACF;AAEA,IAAM,kBAAkB;AACxB,IAAM,2BAA2B;AAU1B,SAAS,uBACd,aAAqB,2BACf;AACN,EAAAC,WAAUC,SAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAM,SAAS,wBAAwB;AACvC,QAAM,YACJ,CAACC,YAAW,UAAU,KACtBC,cAAa,QAAQ,OAAO,MAAMA,cAAa,YAAY,OAAO;AACpE,MAAI,WAAW;AACb,IAAAC,cAAa,QAAQ,UAAU;AAC/B,IAAAC,WAAU,YAAY,GAAK;AAAA,EAC7B;AACF;AAYO,SAAS,mBACd,YACA,UAAsC,CAAC,GACrB;AAIlB,MAAI,QAAQ,iBAAiB,OAAO;AAClC,2BAAuB;AAAA,EACzB;AAEA,QAAM,YAAYP,MAAK,YAAY,SAAS;AAC5C,QAAM,mBAAmB,CAACI,YAAW,SAAS;AAC9C,EAAAF,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,eAAeF,MAAK,WAAW,qBAAqB;AAC1D,QAAM,kBAAkBI,YAAW,YAAY;AAC/C,QAAM,aAAa,eAAe;AAElC,MAAI,WAAoC,CAAC;AACzC,MAAI,iBAAiB;AAInB,QAAI,CAACA,YAAW,UAAU,GAAG;AAC3B,MAAAE,cAAa,cAAc,UAAU;AAAA,IACvC;AACA,eAAWE,eAAcC,eAAcJ,cAAa,cAAc,OAAO,CAAC,CAAC;AAAA,EAC7E;AAEA,WAAS,eAAe,IAAI;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAEA,EAAAK,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AAEpE,SAAO;AAAA,IACL,eAAe;AAAA,IACf,iBAAiB,kBAAkB,aAAa;AAAA,IAChD,oBAAoB;AAAA,EACtB;AACF;AAQO,SAAS,qBAAqB,QAAgC;AACnE,QAAM,EAAE,eAAe,iBAAiB,mBAAmB,IAAI;AAC/D,QAAM,aAAa,gBAAgB;AAEnC,MAAI,oBAAoB,YAAY;AAIlC,QAAIN,YAAW,UAAU,GAAG;AAC1B,MAAAO,YAAW,YAAY,aAAa;AAAA,IACtC,WAAWP,YAAW,aAAa,GAAG;AAOpC,yBAAmB,aAAa;AAAA,IAClC;AAAA,EACF,OAAO;AAEL,QAAIA,YAAW,aAAa,EAAG,CAAAQ,YAAW,aAAa;AACvD,QAAIR,YAAW,UAAU,EAAG,CAAAQ,YAAW,UAAU;AAAA,EACnD;AAEA,MAAI,oBAAoB;AACtB,UAAM,YAAYT,SAAQ,aAAa;AACvC,QAAI;AACF,UAAIC,YAAW,SAAS,KAAKS,aAAY,SAAS,EAAE,WAAW,GAAG;AAChE,QAAAC,WAAU,SAAS;AAAA,MACrB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAWA,SAAS,0BAAkC;AACzC,QAAM,YAAYX,SAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,aAAa;AAAA;AAAA,IAEjBH,MAAK,WAAW,UAAU,2BAA2B;AAAA;AAAA,IAErDA,MAAK,WAAW,MAAM,UAAU,2BAA2B;AAAA;AAAA,IAE3DA,MAAK,WAAW,MAAM,MAAM,UAAU,2BAA2B;AAAA,EACnE;AACA,aAAW,aAAa,YAAY;AAClC,QAAII,YAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AACA,QAAM,IAAI;AAAA,IACR;AAAA,IAAsE,WAAW,KAAK,MAAM,CAAC;AAAA,EAC/F;AACF;AAEA,SAAS,mBAAmB,cAA4B;AACtD,QAAM,WAAWI,eAAcC,eAAcJ,cAAa,cAAc,OAAO,CAAC,CAAC;AACjF,MAAI,EAAE,mBAAmB,UAAW;AACpC,SAAO,SAAS,eAAe;AAC/B,EAAAK,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,IAAI;AACtE;AAEA,SAASD,eAAc,MAAuB;AAC5C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAASD,eAAc,OAAyC;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD,CAAC;AACP;;;AC1LO,SAAS,0BAA0B,SAAiC;AACzE,QAAM,eAAe,QAAQ,MAAM,iBAAiB;AACpD,QAAM,cAAc,eAAe,CAAC,GAAG,KAAK,KAAK;AAKjD,QAAM,YAAY,QAAQ;AAAA,IACxB;AAAA,EACF;AACA,QAAM,OAAO,YAAY,CAAC,GAAG,KAAK,KAAK;AAEvC,SAAO,EAAE,aAAa,KAAK;AAC7B;AAUO,SAAS,6BAA6B,SAA2B;AACtE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,OAAO;AAAA,EAC7B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAW,QAA4C;AAC7D,MAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACrE,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO,KAAK,OAAkC,EAAE,IAAI,kBAAkB;AAC/E;AAMA,SAAS,mBAAmB,KAAqB;AAC/C,SAAO,IACJ,MAAM,MAAM,EACZ,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAsBO,SAAS,kBAAkBO,QAAkC;AAClE,QAAM,EAAE,aAAa,UAAU,MAAM,aAAa,IAAIA;AAEtD,QAAM,aAAa,eAAe;AAElC,QAAM,aAAa,eAAe,gBAAgB,WAAW,KAAK,QAAQ,MAAM;AAChF,QAAM,aAAa,OAAO,KAAK,IAAI,KAAK;AAExC,QAAM,QAAkB,CAAC,OAAO,UAAU,GAAG,UAAU,GAAG,UAAU,KAAK,EAAE;AAE3E,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAK,2BAA2B,aAAa,KAAK,IAAI,CAAC,GAAG;AAUhE,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ;AAAA,IAKF;AAAA,EACF,OAAO;AACL,UAAM,KAAK,gCAAgC;AAAA,EAC7C;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACpCA,IAAM,0BACJ;AAcF,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUM,SAAS,+BACd,SACA,KACQ;AACR,QAAM,SAAS,KAAK,MAAM,OAAO;AACjC,MAAI,CAAC,cAAc,MAAM,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR,4EAA4E,OAAO,MAAM;AAAA,IAC3F;AAAA,EACF;AACA,QAAM,UAAU,OAAO,YAAY;AACnC,MAAI,CAAC,cAAc,OAAO,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAA4C,CAAC;AACnD,aAAW,CAAC,YAAY,GAAG,KAAK,OAAO,QAAQ,OAAO,GAAG;AACvD,qBAAiB,UAAU,IAAI,mBAAmB,YAAY,KAAK,GAAG;AAAA,EACxE;AAEA,QAAM,MAAM,EAAE,GAAG,QAAQ,YAAY,iBAAiB;AACtD,SAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AACpC;AAEA,SAAS,mBACP,YACA,KACA,KACS;AACT,MAAI,CAAC,cAAc,GAAG,EAAG,QAAO;AAIhC,MAAI,OAAO,IAAI,MAAM;AACrB,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,YAAM,IAAI,wBAAwB,KAAK,GAAG;AAC1C,UAAI,CAAC,EAAG,QAAO;AACf,aAAO,GAAG,IAAI,eAAe,IAAI,EAAE,CAAC,CAAC;AAAA,IACvC,CAAC;AAAA,EACH;AAIA,QAAM,MAAM,cAAc,IAAI,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE,IAAI,CAAC;AAC7D,cAAY,KAAK,YAAY,IAAI,OAAO;AACxC,cAAY,KAAK,eAAe,IAAI,kBAAkB;AAGtD,MAAI,IAAI,mBAAmB;AACzB,gBAAY,KAAK,2BAA2B,IAAI,iBAAiB;AAAA,EACnE;AACA,cAAY,KAAK,QAAQ,IAAI,YAAY;AACzC,cAAY,KAAK,gBAAgB,IAAI,OAAO;AAC5C,cAAY,KAAK,uBAAuB,IAAI,aAAa;AAQzD,MAAI,UAAU,KAAK;AACjB,QAAI,MAAM,IAAI,IAAI;AAAA,EACpB;AAQA,MAAI,IAAI,YAAY,MAAM,iBAAiB;AACzC,WAAO,IAAI,YAAY;AAAA,EACzB;AAOA,MAAI,oBAAoB,IAAI,UAAU,GAAG;AACvC,QAAI,qBAAqB,IAAI,IAAI;AAAA,EACnC;AAEA,SAAO,EAAE,GAAG,KAAK,MAAM,IAAI;AAC7B;AAYA,SAAS,YACP,KACA,KACA,OACM;AACN,QAAM,UAAU,IAAI,GAAG;AACvB,MACE,OAAO,YAAY,YACnB,QAAQ,WAAW,KACnB,YAAY,MAAM,GAAG,KACrB;AACA,QAAI,GAAG,IAAI;AAAA,EACb;AACF;AAEA,SAAS,cAAc,GAA0C;AAC/D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;;;AP7KA,IAAM,aAAa,CAAC,aAAa,WAAW;AAC5C,IAAM,6BAA6B;AAKnC,IAAM,kBAAkB;AAoDxB,eAAsB,0BACpB,OACA,UAAqC,CAAC,GACvB;AACf,4BAA0B;AAE1B,QAAM,OAAO,WAAW;AAIxB,QAAM,qBAAqB,CAAC,QAAQ,YAAY,CAAC;AAKjD,MAAI,CAAC,gBAAgB,KAAK,KAAK,GAAG;AAChC,UAAM,MACJ;AAEF,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAYA,MAAI,CAAC,QAAQ,SAAS;AACpB,UAAM,WAAW,mBAAmB,QAAQ,IAAI,CAAC;AACjD,QAAI,UAAU;AACZ,YAAM,MACJ,iEAAiE,SAAS,SAAS;AAErF,UAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,UACzC,OAAM,GAAG;AACd,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAiBA,MAAI,CAAC,QAAQ,SAAS;AACpB,UAAM,eAAe,oBAAoB,QAAQ,IAAI,CAAC;AACtD,QAAI,cAAc;AAChB,YAAM,MACJ,sDAAsD,YAAY,gCACrC,WAAW,KAAK,KAAK,CAAC;AAIrD,UAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,UACzC,OAAM,GAAG;AACd,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,KAAM,SAAQ,IAAIC,QAAM,KAAK,kCAA6B,CAAC;AAIhE,QAAM,UAAUC,MAAI;AAAA,IAClB,MAAM;AAAA,IACN,UAAU;AAAA,EACZ,CAAC;AACD,UAAQ,MAAM;AAUd,QAAMC,SAAQ,QAAQ,WAAW,eAAe,QAAQ,QAAQ,EAAE;AAClE,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAGA,KAAI,6BAA6B;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,cAAc,MAAM,CAAC;AAAA,IAC9C,CAAC;AACD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,YAAM,SAAU,KAAK,OAAO,KAAgB,QAAQ,IAAI,MAAM;AAC9D,YAAM,IAAI,MAAM,GAAG,MAAM,UAAU,IAAI,MAAM,GAAG;AAAA,IAClD;AACA,aAAU,MAAM,IAAI,KAAK;AAAA,EAC3B,SAAS,KAAK;AACZ,YAAQ,KAAK,yBAAyB;AACtC,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,UAAQ,OAAO;AACf,QAAM,aAAa,kBAAkB,OAAO,MAAM,SAAS;AAC3D,EAAAC;AAAA,IACEC,OAAK,YAAY,WAAW;AAAA,IAC5B,OAAO,UAAU,WAAW;AAAA,EAC9B;AAQA,EAAAD;AAAA,IACEC,OAAK,YAAY,WAAW;AAAA,IAC5B,+BAA+B,OAAO,UAAU,WAAW,GAAG;AAAA,MAC5D,cAAc,QAAQ,IAAI,QAAQ;AAAA,MAClC,cAAc,oBAAoB;AAAA,MAClC,iBAAiB,uBAAuB;AAAA,MACxC,oBAAoB,OAAO;AAAA,MAC3B,mBAAmB,OAAO,uBAAuB;AAAA,MACjD,SAASF;AAAA,MACT,SAAS,OAAO,MAAM;AAAA,MACtB,eAAe,OAAO,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AASA,UAAQ,OAAO;AAOf,QAAM,aAAa,QAAQ,UACvB,yBAAyB,OAAO,MAAM,SAAS,IAC/C,QAAQ,IAAI;AAOhB,QAAM,oBAAoB,mBAAmB,UAAU;AACvD,MAAI,mBAAmB;AACrB,YAAQ,KAAK,8CAA8C;AAC3D,UAAM,MACJ,iDAAiD,UAAU,KAAK,kBAAkB,SAAS;AAE7F,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,QAAM,UAAsC,CAAC;AAC7C,QAAM,UAAqD,CAAC;AAG5D,MAAI;AACJ,MAAI;AAEJ,MAAI;AACF,eAAW,QAAQ,YAAY;AAC7B,YAAM,cAAcE,OAAK,YAAY,IAAI;AACzC,YAAM,OAAO,kBAAkB,aAAaA,OAAK,YAAY,IAAI,CAAC;AAClE,cAAQ,IAAI,IAAI;AAChB,cAAQ,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,IAC7B;AAMA,iBAAa,sBAAsB,UAAU;AAQ7C,uBAAmB,mBAAmB,UAAU;AAEhD,UAAM,WAAgC;AAAA,MACpC,WAAW,OAAO,MAAM;AAAA,MACxB,UAAU,OAAO,MAAM;AAAA,MACvB,SAAS,OAAO,MAAM;AAAA,MACtB,OAAO,OAAO;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,YAAY,OAAO;AAAA,MACnB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,aAAa;AAAA,MACb,MAAAF;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AACA,wBAAoB,QAAQ;AAAA,EAC9B,SAAS,KAAK;AACZ,QAAI,kBAAkB;AACpB,UAAI;AACF,6BAAqB,gBAAgB;AAAA,MACvC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,YAAY;AACd,UAAI;AACF,gCAAwB,UAAU;AAAA,MACpC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,eAAW,EAAE,MAAM,KAAK,KAAK,CAAC,GAAG,OAAO,EAAE,QAAQ,GAAG;AACnD,UAAI;AACF,uBAAeE,OAAK,YAAY,IAAI,GAAG,IAAI;AAAA,MAC7C,QAAQ;AAAA,MAGR;AAAA,IACF;AACA,YAAQ,KAAK,qDAAqD;AAClE,UAAM;AAAA,EACR;AAEA,UAAQ,KAAK;AACb,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,WAAW,OAAO,MAAM;AAAA,MACxB,UAAU,OAAO,MAAM;AAAA,MACvB,YAAY,OAAO;AAAA,MACnB,YAAY,OAAO;AAAA,MACnB,aAAa;AAAA,MACb,MAAAF;AAAA,MACA,eAAe;AAAA,IACjB,CAAC;AACD;AAAA,EACF;AAEA,UAAQ,iBAAiBF,QAAM,KAAK,OAAO,MAAM,SAAS,CAAC,EAAE;AAC7D,UAAQ,IAAI;AACZ,UAAQ,IAAI,iBAAiBA,QAAM,IAAI,OAAO,MAAM,QAAQ,CAAC,EAAE;AAC/D,UAAQ,IAAI,iBAAiBA,QAAM,IAAI,OAAO,MAAM,OAAO,CAAC,EAAE;AAC9D,UAAQ,IAAI,iBAAiBA,QAAM,IAAI,OAAO,UAAU,CAAC,EAAE;AAC3D,UAAQ;AAAA,IACN,iBAAiBA,QAAM,IAAI,IAAI,KAAK,OAAO,aAAa,GAAI,EAAE,YAAY,CAAC,CAAC;AAAA,EAC9E;AACA,UAAQ,IAAI,iBAAiBA,QAAM,IAAI,UAAU,CAAC,EAAE;AACpD,UAAQ,IAAI,iBAAiBA,QAAM,IAAIE,KAAI,CAAC,EAAE;AAC9C,UAAQ,IAAI,iBAAiBF,QAAM,IAAI,WAAW,KAAK,IAAI,CAAC,CAAC,EAAE;AAC/D,UAAQ,IAAI;AACZ,MAAI,CAAC,oBAAoB;AAIvB,QAAI,QAAQ,SAAS;AAGnB,WAAK,wDAAwD,UAAU,IAAI;AAAA,IAC7E;AACA;AAAA,MACE;AAAA,IAGF;AACA,YAAQ,IAAI;AACZ,SAAK,mCAAmC;AACxC;AAAA,EACF;AAgBA,OAAK,mEAA8D;AACnE,UAAQ,IAAI;AAEZ,QAAM,SAAS;AAAA,IACb;AAAA,IACA,QAAQ;AAAA,IACR,OAAO,MAAM;AAAA,EACf;AAEA,QAAM,IAAI,QAAc,CAACK,aAAY;AACnC,UAAM,QAAQ,MAAM,UAAU,OAAO,MAAM;AAAA,MACzC,OAAO;AAAA,MACP,KAAK;AAAA,MACL,KAAK,OAAO;AAAA,IACd,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,QAA+B;AAChD,UAAI,IAAI,SAAS,UAAU;AACzB;AAAA,UACE,wEACU,UAAU;AAAA,QACtB;AACA,gBAAQ,WAAW;AAAA,MACrB,OAAO;AACL,cAAM,iCAAiC,IAAI,OAAO,EAAE;AACpD,gBAAQ,WAAW;AAAA,MACrB;AACA,MAAAA,SAAQ;AAAA,IACV,CAAC;AACD,UAAM,GAAG,QAAQ,CAAC,MAAM,WAAW;AAMjC,UAAI,SAAS,QAAQ,SAAS,EAAG,SAAQ,WAAW;AACpD,UAAI,OAAQ,SAAQ,WAAW;AAC/B,MAAAA,SAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAKD,UAAQ,IAAI;AACZ,OAAK,mDAAmD;AAC1D;AAOA,SAAS,kBAAkB,UAAqC;AAC9D,QAAM,UAAU,UAAU,QAAQ;AAClC,UAAQ,IAAI;AACZ,UAAQ,IAAIL,QAAM,KAAK,kBAAkB,SAAS,SAAS,EAAE,CAAC;AAC9D,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,QAAQ,CAAC,EAAE;AAC5D,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,OAAO,CAAC,EAAE;AAC3D,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,UAAU,CAAC,EAAE;AAC9D,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,SAAS,CAAC,EAAE;AAC7D,UAAQ;AAAA,IACN,kBAAkBA,QAAM,IAAI,IAAI,KAAK,SAAS,aAAa,GAAI,EAAE,YAAY,CAAC,CAAC,OAC5E,UAAUA,QAAM,IAAI,6CAAwC,IAAI;AAAA,EACrE;AACA,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,WAAW,CAAC,EAAE;AAC/D,UAAQ,IAAI,kBAAkBA,QAAM,IAAI,SAAS,IAAI,CAAC,EAAE;AACxD,UAAQ,IAAI;AACd;AAGA,SAAS,eAAe,UAA+B;AACrD,SAAO;AAAA,IACL,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,IACnB,SAAS,SAAS;AAAA,IAClB,YAAY,SAAS;AAAA,IACrB,WAAW,SAAS;AAAA,IACpB,YAAY,SAAS;AAAA,IACrB,SAAS,UAAU,QAAQ;AAAA,IAC3B,aAAa,SAAS;AAAA,IACtB,MAAM,SAAS;AAAA,EACjB;AACF;AAEA,eAAsB,0BACpB,OAA0B,CAAC,GACZ;AACf,4BAA0B;AAE1B,QAAM,OAAO,WAAW;AAKxB,MAAI,KAAK,KAAK;AACZ,UAAM,YAAY,oBAAoB;AACtC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,QAAQ,UAAU,IAAI,cAAc,EAAE,CAAC;AAC9D;AAAA,IACF;AACA,QAAI,UAAU,WAAW,GAAG;AAC1B,WAAK,2BAA2B;AAChC;AAAA,IACF;AACA,YAAQ,IAAI;AACZ,YAAQ,IAAIA,QAAM,KAAK,0BAA0B,UAAU,MAAM,IAAI,CAAC;AACtE,eAAW,KAAK,UAAW,mBAAkB,CAAC;AAC9C;AAAA,EACF;AAEA,QAAM,WAAW,mBAAmB,QAAQ,IAAI,CAAC;AACjD,MAAI,CAAC,UAAU;AACb,UAAM,SAAS,oBAAoB;AACnC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,QAAQ,MAAM,eAAe,OAAO,OAAO,CAAC;AACnE;AAAA,IACF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB;AAAA,QACE,oDAA+C,OAAO,MAAM;AAAA,MAE9D;AAAA,IACF,OAAO;AACL,WAAK,0BAA0B;AAAA,IACjC;AACA;AAAA,EACF;AAEA,MAAI,MAAM;AACR,eAAW,EAAE,IAAI,MAAM,QAAQ,eAAe,QAAQ,EAAE,CAAC;AACzD;AAAA,EACF;AACA,oBAAkB,QAAQ;AAC5B;AAMA,eAAsB,uBACpB,OAA0B,CAAC,GACZ;AACf,4BAA0B;AAE1B,QAAM,OAAO,WAAW;AAKxB,MAAI,KAAK,KAAK;AACZ,UAAM,YAAY,oBAAoB;AACtC,QAAI,UAAU,WAAW,GAAG;AAC1B,UAAI,KAAM,YAAW,EAAE,IAAI,MAAM,YAAY,OAAO,QAAQ,CAAC,EAAE,CAAC;AAAA,UAC3D,MAAK,kCAAkC;AAC5C;AAAA,IACF;AACA,UAAM,SAAmB,CAAC;AAC1B,eAAWM,aAAY,WAAW;AAGhC,YAAM,uBAAuBA,WAAU,EAAE,MAAM,QAAQ,KAAK,CAAC;AAC7D,aAAO,KAAKA,UAAS,SAAS;AAAA,IAChC;AACA,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,IACnD,OAAO;AACL,cAAQ,UAAU,OAAO,MAAM,8BAA8B,OAAO,KAAK,IAAI,CAAC,EAAE;AAChF,WAAK,uDAAuD;AAAA,IAC9D;AACA;AAAA,EACF;AAEA,QAAM,WAAW,mBAAmB,QAAQ,IAAI,CAAC;AACjD,MAAI,CAAC,UAAU;AACb,QAAI,KAAM,YAAW,EAAE,IAAI,MAAM,YAAY,MAAM,CAAC;AAAA,QAC/C,MAAK,kCAAkC;AAC5C;AAAA,EACF;AAEA,QAAM,uBAAuB,UAAU,EAAE,MAAM,QAAQ,MAAM,CAAC;AAChE;AAYA,eAAe,uBACb,UACA,MACe;AACf,QAAM,EAAE,MAAM,OAAO,IAAI;AASzB,MAAI,SAAS;AACb,MAAI,aAA4B;AAChC,MAAI;AACF,QAAI,QAAQ,IAAI,aAAa,GAAG;AAC9B,YAAM,IAAI,KAAK,2BAA2B,QAAW;AAAA,QACnD,CAAC,0BAA0B,GAAG,SAAS;AAAA,MACzC,CAAC;AAAA,IACH,OAAO;AAIL,YAAM,MAAM,MAAM,MAAM,GAAG,SAAS,IAAI,2BAA2B;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,CAAC,0BAA0B,GAAG,SAAS;AAAA,QACzC;AAAA,MACF,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,cAAM,SAAU,KAAK,OAAO,KAAgB,QAAQ,IAAI,MAAM;AAC9D,iBAAS;AACT,qBAAa,GAAG,MAAM,UAAU,IAAI,MAAM;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,aAAS;AACT,iBAAa,eAAe,WACxB,GAAG,IAAI,OAAO,UAAU,IAAI,MAAM,MAClC,eAAe,QACb,IAAI,UACJ,OAAO,GAAG;AAAA,EAElB;AAGA,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,SAAS,OAAO,GAAG;AAC3D,UAAM,cAAcF,OAAK,SAAS,aAAa,IAAI;AACnD,QAAI;AACF,qBAAe,aAAa,IAAI;AAChC,eAAS,KAAK,IAAI;AAAA,IACpB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,CAAC,KAAM,OAAM,qBAAqB,IAAI,KAAK,GAAG,EAAE;AAAA,IACtD;AAAA,EACF;AASA,MAAI,SAAS,YAAY;AACvB,QAAI;AACF,2BAAqB,SAAS,UAAU;AAAA,IAC1C,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,CAAC,KAAM,OAAM,gCAAgC,GAAG,EAAE;AAAA,IACxD;AASA,QAAI,CAAC,QAAQ,QAAQ,OAAO,OAAO;AACjC,cAAQ,OAAO,MAAM,aAAa;AAAA,IACpC;AAAA,EACF;AAKA,MAAI,SAAS,MAAM;AACjB,QAAI;AACF,8BAAwB,SAAS,IAAI;AAAA,IACvC,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,CAAC,KAAM,OAAM,oCAAoC,GAAG,EAAE;AAAA,IAC5D;AAAA,EACF;AAEA,sBAAoB,SAAS,WAAW;AAKxC,MAAI,OAAQ;AAEZ,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,YAAY;AAAA,MACZ,YAAY,SAAS;AAAA,MACrB,mBAAmB;AAAA,MACnB,aAAa;AAAA,MACb;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,UAAQ,yBAAyB,SAAS,SAAS,EAAE;AACrD,MAAI,SAAS,SAAS,GAAG;AACvB,SAAK,aAAa,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,EACzC;AACA,MAAI,CAAC,QAAQ;AACX,SAAK,4CAA4C,UAAU,iCAAiC;AAAA,EAC9F;AACA,OAAK,uDAAuD;AAC9D;AAeA,eAAsB,+BAA8C;AAKlE,MAAI;AACJ,MAAI;AACF,gBAAY,oBAAoB;AAAA,EAClC,QAAQ;AACN;AAAA,EACF;AACA,QAAM,UAAU,UAAU,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;AACpD,MAAI,QAAQ,WAAW,EAAG;AAC1B,aAAW,YAAY,SAAS;AAC9B,QAAI;AACF,UAAI,CAAC,WAAW,GAAG;AAIjB,gBAAQ;AAAA,UACNJ,QAAM;AAAA,YACJ,oCAA+B,SAAS,SAAS;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AACA,YAAM,uBAAuB,UAAU,EAAE,MAAM,WAAW,GAAG,QAAQ,KAAK,CAAC;AAAA,IAC7E,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAqBA,eAAsB,8BAA6C;AACjE,MAAI;AAIF,UAAM,WAAW,mBAAmB,QAAQ,IAAI,CAAC;AACjD,QAAI,CAAC,YAAY,UAAU,QAAQ,EAAG;AAEtC,UAAM,MAAM,SAAS;AACrB,UAAM,WAAW,qBAAqBI,OAAK,KAAK,WAAW,CAAC;AAC5D,UAAM,eAAe,oBAAoBA,OAAK,KAAK,WAAW,CAAC;AAE/D,UAAM,QAAQ,kBAAkB;AAAA,MAC9B,aAAa,SAAS;AAAA,MACtB,UAAU,SAAS;AAAA,MACnB,MAAM,SAAS;AAAA,MACf;AAAA,IACF,CAAC;AACD,YAAQ,OAAO,MAAM,QAAQ,IAAI;AAAA,EACnC,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,qBAAqB,MAA8B;AAC1D,MAAI;AACF,WAAO,0BAA0BG,cAAa,MAAM,OAAO,CAAC;AAAA,EAC9D,QAAQ;AACN,WAAO,EAAE,aAAa,MAAM,MAAM,KAAK;AAAA,EACzC;AACF;AAEA,SAAS,oBAAoB,MAAwB;AACnD,MAAI;AACF,WAAO,6BAA6BA,cAAa,MAAM,OAAO,CAAC;AAAA,EACjE,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAuBA,SAAS,yBAAiC;AACxC,QAAM,YAAYC,SAAQC,eAAc,YAAY,GAAG,CAAC;AACxD,QAAM,aAAa;AAAA,IACjBL,OAAK,WAAW,KAAK;AAAA,IACrBA,OAAK,WAAW,MAAM,KAAK;AAAA,IAC3BA,OAAK,WAAW,MAAM,MAAM,KAAK;AAAA,EACnC;AACA,aAAW,aAAa,YAAY;AAClC,QAAIM,YAAWN,OAAK,WAAW,UAAU,CAAC,EAAG,QAAO;AAAA,EACtD;AAKA,SAAO,WAAW,WAAW,SAAS,CAAC;AACzC;AAmBO,SAAS,oBACd,WAAmB,QAAQ,UAC3B,gBAAwB,QAAQ,IAAI,QAAQ,IACpC;AACR,QAAM,aAAaI,SAAQ,QAAQ;AACnC,QAAM,WAAW,cAAc,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC1E,MAAI,CAAC,SAAS,SAAS,UAAU,GAAG;AAClC,aAAS,QAAQ,UAAU;AAAA,EAC7B;AACA,SAAO,SAAS,KAAK,SAAS;AAChC;AAkCO,SAAS,6BACd,YACA,aAAgC,QAAQ,KACxC,UAAyB,MACA;AACzB,QAAM,MAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,6BAA6B;AAAA,EAC/B;AAKA,MAAI,YAAY,QAAQ,QAAQ,SAAS,GAAG;AAC1C,QAAI,sBAAsB;AAAA,EAC5B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACAJ,OAAK,YAAY,WAAW;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AACF;;;AQ1+BA,OAAOO,aAAW;AAClB,OAAOC,WAAS;;;ACDhB,SAAS,gBAAgB;AACzB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,cAAY;AACrB,OAAO,WAAW;AAGlB,eAAe,SAAS,UAAgB;AACtC,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,WAAOD,YAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;EAC1D,QAAQ;AACN,WAAO;EACT;AACF;AAEA,eAAe,aAAa,UAAgB;AAC1C,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,UAAU,OAAO;AAChD,WAAO,MAAM,MAAM,OAAO;EAC5B,QAAQ;AACN,WAAO;EACT;AACF;AAEA,eAAsB,cAAc,SAA0B;AAC5D,QAAM,eAAe,QAAQ,gBAAgB,CAAC,kBAAkB,cAAc,UAAU;AAIxF,QAAM,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,CAAC,KAAK;AACvE,QAAM,YAAY,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,KAAK;AAEnE,QAAM,CAAC,iBAAiB,aAAa,SAAS,IAAI,MAAM,QAAQ,IAAI;IAClE,aAAa,QAAQ,UAAU;IAC/B,SAASC,OAAK,QAAQ,SAAS,WAAW,CAAC;IAC3C,SAASA,OAAK,QAAQ,SAAS,SAAS,CAAC;GAC1C;AAED,SAAO;IACL;IACA;IACA;IACA,YAAY,QAAQ;;AAExB;;;AD7BA,IAAM,gBAAgB;AAEtB,SAAS,cAAc,UAA0B;AAC/C,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAOC,QAAM,IAAI,QAAQ;AAAA,IAC3B,KAAK;AACH,aAAOA,QAAM,OAAO,QAAQ;AAAA,IAC9B;AACE,aAAOA,QAAM,IAAI,QAAQ;AAAA,EAC7B;AACF;AAEA,SAAS,iBAAiB,QAA2B;AACnD,UAAQ,IAAIA,QAAM,KAAK;AAAA,gBAAmB,OAAO,QAAQ;AAAA,CAAI,CAAC;AAE9D,OAAK,gBAAgB,OAAO,OAAO,EAAE;AACrC,OAAK,gBAAgB,OAAO,UAAU,YAAY,CAAC,EAAE;AACrD,UAAQ,IAAI;AAEZ,MAAI,CAAC,OAAO,UAAU;AACpB,YAAQ,qDAAqD;AAC7D;AAAA,EACF;AAEA,OAAK,mBAAmB,OAAO,aAAa,cAAc,OAAO,YAAY,UAAU;AACvF,UAAQ,IAAI;AAEZ,QAAM,OAAO,OAAO,SAAS,IAAI,CAAC,MAAoB;AAAA,IACpD,cAAc,EAAE,QAAQ;AAAA,IACxB,EAAE;AAAA,IACF,EAAE;AAAA,IACF,EAAE;AAAA,EACJ,CAAC;AAED,QAAM,CAAC,YAAY,YAAY,SAAS,SAAS,GAAG,IAAI;AAC1D;AAWA,eAAsB,kBACpB,UACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,MAAI,CAAC,cAAc,KAAK,QAAQ,GAAG;AACjC,UAAM,0DAA0D;AAChE,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,QAAQ,WAAW;AAExC,QAAM,UAAUC,MAAI,EAAE,MAAM,uBAAuB,QAAQ,WAAM,UAAU,QAAQ,CAAC;AACpF,UAAQ,MAAM;AAEd,MAAI;AAEF,UAAM,YAAY,MAAM,IAAI,IAKzB,WAAW,mBAAmB,QAAQ,CAAC,aAAa;AAEvD,UAAMC,SAAQ,UAAU;AACxB,UAAM,WAAW,UAAU;AAE3B,QAAI,CAAC,UAAU;AACb,cAAQ,KAAK,oCAAoC,QAAQ,iCAAiC;AAC1F,YAAM,iCAAiC;AACvC,cAAQ,WAAW;AACnB;AAAA,IACF;AAGA,UAAM,cAAeA,OAAM,aAAwB;AACnD,UAAM,UAAU,aAAa,WAAW;AACxC,UAAM,eAAe,QAAQ,kBAAkB;AAG/C,UAAM,aAAa,cAAc,QAAQ,IAAI,QAAQ;AACrD,UAAM,aAAa,KAAK,UAAU,GAAG,UAAU,IAAI,aAAa,CAAC,CAAC;AAElE,UAAM,YAAY,MAAM,cAAc;AAAA,MACpC;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,UAAU,KAAK;AAAA,IACjB,CAAC;AAGD,UAAM,SAAS;AAAA,MACb;AAAA,QACE,iBAAkB,SAAS,mBAAmB,CAAC;AAAA,QAC/C,aAAa,SAAS,gBAA0B;AAAA,QAChD,WAAW,SAAS,cAAwB;AAAA,QAC5C,WAAW,SAAS,cAA0B,CAAC;AAAA,QAC/C,UAAU,SAAS,aAAyB,CAAC;AAAA,QAC7C,gBAAiB,SAAS,mBAAmB,CAAC;AAAA,QAC9C,aAAa,SAAS,gBAA0B;AAAA,MAClD;AAAA,MACA;AAAA,MACAA,OAAM;AAAA,MACN;AAAA,MACCA,OAAM,aAA0B;AAAA,IACnC;AAEA,YAAQ,KAAK;AAEb,QAAI,SAAS;AACX,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC7C,OAAO;AACL,uBAAiB,MAAM;AAAA,IACzB;AAEA,QAAI,OAAO,UAAU;AACnB,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,qBAAqB;AAClC,UAAO,IAAc,OAAO;AAC5B,YAAQ,WAAW;AAAA,EACrB;AACF;AAYA,eAAsB,kBACpB,UACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,MAAI,CAAC,cAAc,KAAK,QAAQ,GAAG;AACjC,UAAM,0DAA0D;AAChE,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,QAAQ,WAAW;AAExC,QAAM,cAAc,SAAS,KAAK,YAAY,MAAM,EAAE;AACtD,MAAI,MAAM,WAAW,KAAK,cAAc,GAAG;AACzC,UAAM,gDAAgD;AACtD,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,MAAIA;AACJ,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAAwC,WAAW,mBAAmB,QAAQ,CAAC,EAAE;AACxG,IAAAA,SAAQ,KAAK;AAAA,EACf,SAAS,KAAK;AACZ,UAAO,IAAc,OAAO;AAC5B,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,cAAeA,OAAM,aAAwB;AACnD,QAAM,UAAU,aAAa,WAAW;AACxC,QAAM,eAAe,QAAQ,kBAAkB;AAE/C,MAAI,CAAC,SAAS;AACZ,YAAQ;AAAA,MACNF,QAAM,KAAK;AAAA,sBAAyB,QAAQ,WAAW,WAAW;AAAA,CAA4B;AAAA,IAChG;AAAA,EACF;AAEA,MAAI,uBAAuB;AAE3B,QAAM,WAAW,YAA2B;AAC1C,UAAM,UAAUC,MAAI,EAAE,MAAM,uBAAuB,QAAQ,WAAM,UAAU,QAAQ,CAAC;AACpF,YAAQ,MAAM;AAEd,QAAI;AACF,YAAM,YAAY,MAAM,IAAI,IAEzB,WAAW,mBAAmB,QAAQ,CAAC,aAAa;AAEvD,YAAM,WAAW,UAAU;AAC3B,UAAI,CAAC,UAAU;AACb,gBAAQ,KAAK,8CAA8C;AAC3D;AAAA,MACF;AAEA,YAAM,kBAAkB,cAAc,QAAQ,IAAI,QAAQ;AAC1D,YAAM,aAAa,KAAK,UAAU,GAAG,eAAe,IAAI,aAAa,CAAC,CAAC;AAEvE,YAAM,YAAY,MAAM,cAAc;AAAA,QACpC;AAAA,QACA,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAED,YAAM,SAAS;AAAA,QACb;AAAA,UACE,iBAAkB,SAAS,mBAAmB,CAAC;AAAA,UAC/C,aAAa,SAAS,gBAA0B;AAAA,UAChD,WAAW,SAAS,cAAwB;AAAA,UAC5C,WAAW,SAAS,cAA0B,CAAC;AAAA,UAC/C,UAAU,SAAS,aAAyB,CAAC;AAAA,UAC7C,gBAAiB,SAAS,mBAAmB,CAAC;AAAA,UAC9C,aAAa,SAAS,gBAA0B;AAAA,QAClD;AAAA,QACA;AAAA,QACAC,OAAM;AAAA,QACN;AAAA,QACCA,OAAM,aAA0B;AAAA,MACnC;AAEA,cAAQ,KAAK;AAEb,YAAM,QAAQ,OAAO,SAAS,WAAW;AACzC,6BAAuB,OAAO,SAAS;AAEvC,UAAI,SAAS;AACX,gBAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MAC7C,WAAW,OAAO,UAAU;AAC1B,yBAAiB,MAAM;AAAA,MACzB,OAAO;AACL,gBAAQ,KAAI,oBAAI,KAAK,GAAE,mBAAmB,CAAC,sBAAsB;AAAA,MACnE;AAEA,UAAI,SAAS,OAAO,YAAY,KAAK,SAAS;AAC5C,YAAI;AACF,gBAAM,MAAM,KAAK,SAAS;AAAA,YACxB,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU,MAAM;AAAA,UAC7B,CAAC;AACD,cAAI,CAAC,QAAS,MAAK,qBAAqB,KAAK,OAAO,EAAE;AAAA,QACxD,SAAS,YAAY;AACnB,cAAI,CAAC,QAAS,MAAK,6BAA8B,WAAqB,OAAO,EAAE;AAAA,QACjF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,qBAAqB;AAClC,YAAO,IAAc,OAAO;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,SAAS;AAEf,QAAM,QAAQ,YAAY,MAAM;AAC9B,SAAK,SAAS;AAAA,EAChB,GAAG,cAAc,GAAI;AAErB,UAAQ,GAAG,UAAU,MAAM;AACzB,kBAAc,KAAK;AACnB,QAAI,CAAC,QAAS,SAAQ,IAAIF,QAAM,IAAI,qBAAqB,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;;;AEhSA,OAAOG,aAAW;AAClB,OAAOC,WAAS;AAUhB,eAAsB,kBAAiC;AACrD,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,MAAI,EAAE,MAAM,wBAAwB,UAAU,KAAK,CAAC;AACpE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAWpB,QAAQ;AAEX,YAAQ,KAAK;AAEb,QAAI,CAAC,KAAK,SAAS,KAAK,MAAM,WAAW,GAAG;AAC1C,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,MACpC,OAAO;AACL,aAAK,kEAAkE;AAAA,MACzE;AACA;AAAA,IACF;AAEA,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,OAAO,KAAK,MAAM,CAAC;AAC1C;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,MAAM,IAAI,CAAC,MAAM;AACjC,YAAM,SAAS,EAAE,WAAW,WACxBC,QAAM,MAAM,QAAQ,IACpBA,QAAM,IAAI,gBAAgB;AAE9B,YAAM,SAAS,OAAO,EAAE,MAAM;AAE9B,YAAM,WAAW,EAAE,eACf,IAAI,KAAK,EAAE,YAAY,EAAE,mBAAmB,IAC5CA,QAAM,IAAI,OAAO;AAErB,YAAM,SAAS,EAAE,aACb,OAAO,EAAE,UAAU,WACnBA,QAAM,IAAI,MAAM;AAEpB,aAAO,CAAC,EAAE,MAAM,QAAQ,QAAQ,UAAU,MAAM;AAAA,IAClD,CAAC;AAED,UAAM,CAAC,QAAQ,UAAU,UAAU,aAAa,KAAK,GAAG,IAAI;AAAA,EAC9D,SAAS,KAAK;AACZ,YAAQ,KAAK,wBAAwB;AACrC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAUA,eAAsB,kBACpB,UACA,gBACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AAExB,MAAI,CAAC,kBAAkB,eAAe,WAAW,GAAG;AAClD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,2CAA2C,CAAC;AAAA,IAC7E,OAAO;AACL,YAAM,2CAA2C;AAAA,IACnD;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAUD,MAAI,EAAE,MAAM,0BAA0B,UAAU,KAAK,CAAC;AACtE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,IAAI,KAAK,UAAU,mBAAmB,QAAQ,CAAC,WAAW;AAAA,MAC9D,QAAQ;AAAA,MACR,OAAO,KAAK;AAAA,IACd,CAAC;AAED,YAAQ,QAAQ,sBAAsBC,QAAM,KAAK,QAAQ,CAAC,GAAG;AAE7D,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,MAAM,UAAU,UAAU,eAAe,CAAC;AACjE;AAAA,IACF;AAEA,eAAW,QAAQ,gBAAgB;AACjC,WAAK,KAAK,IAAI,EAAE;AAAA,IAClB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,0BAA0B;AACvC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,oBACpB,UACA,gBACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AAExB,MAAI,CAAC,kBAAkB,eAAe,WAAW,GAAG;AAClD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,2CAA2C,CAAC;AAAA,IAC7E,OAAO;AACL,YAAM,2CAA2C;AAAA,IACnD;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAUD,MAAI,EAAE,MAAM,4BAA4B,UAAU,KAAK,CAAC;AACxE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,IAAI,KAAK,UAAU,mBAAmB,QAAQ,CAAC,aAAa;AAAA,MAChE,QAAQ;AAAA,IACV,CAAC;AAED,YAAQ,QAAQ,0BAA0BC,QAAM,KAAK,QAAQ,CAAC,GAAG;AAEjE,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,MAAM,UAAU,YAAY,eAAe,CAAC;AACnE;AAAA,IACF;AAEA,eAAW,QAAQ,gBAAgB;AACjC,WAAK,KAAK,IAAI,EAAE;AAAA,IAClB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,4BAA4B;AACzC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBAAkB,UAAkC;AACxE,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,8BAA8B,UAAU,KAAK,CAAC;AAC1E,UAAQ,MAAM;AAEd,MAAI;AAEF,UAAM,SAAS,MAAM,UAAU;AAE/B,QAAI,CAAC,YAAY,CAAC,QAAQ;AACxB,cAAQ,KAAK,oBAAoB;AACjC,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,4CAA4C,CAAC;AAAA,MAC9E,OAAO;AACL,cAAM,mEAAmE;AAAA,MAC3E;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI;AASJ,QAAI,UAAU,CAAC,UAAU;AAEvB,YAAM,OAAO,MAAM,IAAI,KAEpB,gBAAgB,EAAE,SAAS,OAAO,CAAC;AACtC,eAAS,KAAK,UAAU,CAAC;AAAA,IAC3B,OAAO;AAEL,YAAM,WAAW,YAAY;AAC7B,UAAI,CAAC,SAAU;AAEf,YAAM,OAAO,MAAM,IAAI,IAEpB,UAAU,mBAAmB,QAAS,CAAC,SAAS;AACnD,eAAS,KAAK,UAAU,CAAC;AAAA,IAC3B;AAEA,YAAQ,KAAK;AAEb,QAAI,OAAO,WAAW,GAAG;AACvB,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,MAAM,QAAQ,CAAC,EAAE,CAAC;AAAA,MACrC,OAAO;AACL,aAAK,kCAAkC;AACvC,aAAK,qEAAqE;AAAA,MAC5E;AACA;AAAA,IACF;AAEA,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,OAAO,CAAC;AAC/B;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,IAAI,CAAC,MAAM;AAC7B,YAAM,cAAc,EAAE,WAAW,WAAWC,QAAM,QAAQA,QAAM;AAChE,aAAO;AAAA,QACL,EAAE;AAAA,QACF,EAAE;AAAA,QACF,YAAY,EAAE,MAAM;AAAA,QACpB,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,CAAC,aAAa,gBAAgB,UAAU,aAAa,GAAG,IAAI;AAAA,EACpE,SAAS,KAAK;AACZ,YAAQ,KAAK,8BAA8B;AAC3C,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,qBAAqB,UAAiC;AAC1E,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,2BAA2B,UAAU,KAAK,CAAC;AACvE,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAIpB,UAAU,mBAAmB,QAAQ,CAAC,aAAa;AAEtD,YAAQ,QAAQ,mBAAmBC,QAAM,KAAK,QAAQ,CAAC,GAAG;AAE1D,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,KAAK,KAAK;AAAA,MACZ,CAAC;AACD;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,SAAK,WAAWA,QAAM,KAAK,QAAQ,CAAC,EAAE;AACtC,SAAK,WAAW,KAAK,IAAI,MAAM,EAAE;AACjC,YAAQ,IAAI;AACZ,YAAQ,IAAIA,QAAM,OAAO,KAAK,wDAAwD,CAAC;AACvF,YAAQ,IAAI;AACZ,YAAQ,IAAI,KAAKA,QAAM,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,EAAE;AACrD,YAAQ,IAAI;AAAA,EACd,SAAS,KAAK;AACZ,YAAQ,KAAK,uBAAuB;AACpC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAsBA,eAAsB,6BACpB,UACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,OAAO,UAAU,mBAAmB,QAAQ,CAAC;AACnD,QAAM,UACJ,KAAK,SAAS,KAAK,UAAU,UAAa,KAAK,QAAQ,UAAa,KAAK,OAAO;AAGlF,MAAI,CAAC,SAAS;AACZ,UAAMC,WAAUF,MAAI,EAAE,MAAM,qCAAgC,UAAU,KAAK,CAAC;AAC5E,IAAAE,SAAQ,MAAM;AACd,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,IAA+B,IAAI;AAC1D,MAAAA,SAAQ,KAAK;AACb,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,MAAM,GAAG,KAAK,CAAC;AAChC;AAAA,MACF;AACA,YAAM,KAAK,KAAK;AAChB,YAAM,cACJ,GAAG,6BAA6B,QAChC,GAAG,2BAA2B,QAC9B,GAAG,yBAAyB;AAC9B,WAAK,cAAcD,QAAM,KAAK,QAAQ,CAAC,EAAE;AACzC;AAAA,QACE,cAAcA,QAAM,MAAM,GAAG,KAAK,UAAU,KAAK,SAAI,KAAK,UAAU,GAAG,EAAE,CAAC,IAAI,KAAK,UAAU,QAAQ;AAAA,MACvG;AACA;AAAA,QACE,cAAc,cAAcA,QAAM,KAAK,KAAK,IAAIA,QAAM,IAAI,iCAA4B,CAAC;AAAA,MACzF;AACA,WAAK,gEAAgE;AAAA,IACvE,SAAS,KAAK;AACZ,MAAAC,SAAQ,KAAK,qCAAqC;AAClD,UAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,UAC5D,OAAO,IAAc,OAAO;AACjC,cAAQ,WAAW;AAAA,IACrB;AACA;AAAA,EACF;AAOA,MAAI,KAAK,UAAU,KAAK,UAAU,UAAa,KAAK,QAAQ,UAAa,KAAK,OAAO,SAAY;AAC/F,UAAM,MAAM;AACZ,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,MAAI,CAAC,KAAK,SAAU,KAAK,UAAU,YAAgB,KAAK,QAAQ,SAAY;AAC1E,UAAM,MAAM;AACZ,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,CAAC,KAAK,SAAS,KAAK,OAAO,UAAa,KAAK,UAAU,QAAW;AACpE,UAAM,MAAM;AACZ,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAKA,MAAI,aAA4B,KAAK,MAAM;AAC3C,MAAI,CAAC,KAAK,SAAS,KAAK,OAAO,QAAW;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,IAA+B,IAAI;AACzD,mBAAa,IAAI,SAAS;AAAA,IAC5B,SAAS,KAAK;AACZ,YAAM,WAAWF,MAAI,EAAE,UAAU,KAAK,CAAC;AACvC,eAAS,KAAK,4CAA4C;AAC1D,UAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,UAC5D,OAAO,IAAc,OAAO;AACjC,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,QACjB,EAAE,0BAA0B,MAAM,wBAAwB,MAAM,sBAAsB,KAAK,IAC3F;AAAA,IACE,0BAA0B,KAAK,SAAS;AAAA,IACxC,wBAAwB,KAAK,OAAO;AAAA,IACpC,sBAAsB;AAAA,EACxB;AAEJ,QAAM,UAAUA,MAAI,EAAE,MAAM,qCAAgC,UAAU,KAAK,CAAC;AAC5E,UAAQ,MAAM;AACd,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAGpB,MAAM,OAAO;AAChB,YAAQ,QAAQ,kCAAkCC,QAAM,KAAK,QAAQ,CAAC,GAAG;AACzE,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,GAAG,KAAK,CAAC;AAChC;AAAA,IACF;AACA,QAAI,KAAK,KAAM,MAAK,KAAK,IAAI;AAAA,EAC/B,SAAS,KAAK;AACZ,YAAQ,KAAK,sCAAsC;AACnD,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,QAC5D,OAAO,IAAc,OAAO;AACjC,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,wBAAwB,UAAiC;AAC7E,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,8BAA8B,UAAU,KAAK,CAAC;AAC1E,UAAQ,MAAM;AAEd,MAAI;AACF,UAAM,IAAI,KAAK,UAAU,mBAAmB,QAAQ,CAAC,eAAe;AAEpE,YAAQ,QAAQ,SAASC,QAAM,KAAK,QAAQ,CAAC,mBAAmB;AAEhE,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AACD;AAAA,IACF;AAEA,SAAK,WAAW,QAAQ,EAAE;AAC1B,SAAK,WAAWA,QAAM,IAAI,gBAAgB,CAAC,EAAE;AAC7C,SAAK,+DAA+D;AACpE,SAAK,iEAAiE;AAAA,EACxE,SAAS,KAAK;AACZ,YAAQ,KAAK,8BAA8B;AAC3C,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;AC1fA,SAAS,SAAAE,QAAO,iBAAoC;AACpD,OAAOC,aAAW;AA8ClB,eAAsB,gBACpB,MACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AAEf,QAAM,OAAO,WAAW;AACxB,QAAM,YAAY,OAAO,KAAK,QAAQ,OAAO;AAE7C,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,QAAQ,YAAY,OAAO;AACzE,UAAM,kDAAkD;AACxD,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,MAAIC;AACJ,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAA0B,UAAU,mBAAmB,IAAI,CAAC,EAAE;AACrF,IAAAA,QAAO,KAAK;AAAA,EACd,SAAS,KAAK;AACZ,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,QAC5D,OAAM,2BAA4B,IAAc,OAAO,EAAE;AAC9D,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAIA,MAAK,qBAAqB,iBAAiB;AAC7C,UAAM,MAAM,SAAS,IAAI,QAAQA,MAAK,oBAAoB,MAAM;AAEhE,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,CAACA,MAAK,iBAAiB;AACzB,UAAM,MAAM,SAAS,IAAI;AACzB,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,QACzC,OAAM,GAAG;AACd,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,SAASA,MAAK,cAAc,QAAQ,IAAI,cAAc;AAC5D,QAAM,aAAaA,MAAK;AAGxB,QAAM,eAAe,aAAa;AAClC,MAAI,cAAc;AAChB,QAAI,KAAM,YAAW,EAAE,IAAI,OAAO,OAAO,aAAa,CAAC;AAAA,QAClD,OAAM,YAAY;AACvB,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,MAAM;AAER,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,MAAM,EAAE,MAAMA,MAAK,MAAM,IAAIA,MAAK,IAAI,aAAa,YAAY,OAAO;AAAA,MACtE,cAAc;AAAA,QACZ,SAAS;AAAA,QACT,MAAM;AAAA,UACJ;AAAA,UAAO;AAAA,UACP;AAAA,UAAY;AAAA,UACZ;AAAA,UAAY;AAAA,UACZ;AAAA,UAAmB;AAAA,UACnB;AAAA,UAAgB,KAAK,UAAU,EAAE,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,iBAAiB,CAAC,OAAO,SAAS,CAAC,EAAE,CAAC;AAAA,QAC1G;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM,CAAC,OAAO,iBAAiB,YAAY,QAAQ,YAAY,UAAU;AAAA,MAC3E;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,OAAK,0BAA0BC,QAAM,KAAK,IAAI,CAAC,KAAK,UAAU,KAAK,MAAM,GAAG;AAC5E,OAAK,cAAcA,QAAM,KAAK,OAAO,SAAS,CAAC,CAAC,iCAAiC;AACjF,UAAQ,IAAI;AACZ,UAAQ,IAAIA,QAAM,IAAI,+BAA+B,CAAC;AACtD,UAAQ,IAAI,KAAKA,QAAM,KAAK,0BAA0B,SAAS,gBAAgB,CAAC,EAAE;AAClF,UAAQ,IAAIA,QAAM,IAAI,gEAAgE,CAAC;AACvF,UAAQ,IAAIA,QAAM,IAAI,qDAAqD,CAAC;AAC5E,UAAQ,IAAI;AACZ,UAAQ,IAAIA,QAAM,IAAI,oEAAoE,CAAC;AAC3F,UAAQ,IAAI;AAGZ,QAAM,SAASC;AAAA,IACb;AAAA,IACA;AAAA,MACE;AAAA,MAAO;AAAA,MACP;AAAA,MAAY;AAAA,MACZ;AAAA,MAAY;AAAA,MACZ;AAAA,MAAmB;AAAA,MACnB;AAAA,MACA,KAAK,UAAU,EAAE,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,iBAAiB,CAAC,OAAO,SAAS,CAAC,EAAE,CAAC;AAAA,IAC1F;AAAA,IACA,EAAE,OAAO,CAAC,UAAU,QAAQ,MAAM,EAAE;AAAA,EACtC;AAGA,SAAO,QAAQ,GAAG,QAAQ,CAAC,QAAQ;AACjC,UAAM,OAAO,IAAI,SAAS,EAAE,KAAK;AACjC,QAAI,KAAK,WAAW,mBAAmB,GAAG;AACxC,cAAQ,MAAMD,QAAM,IAAI,YAAY,IAAI,EAAE,CAAC;AAAA,IAC7C;AAAA,EACF,CAAC;AAGD,QAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAE5C,MAAI,OAAO,aAAa,MAAM;AAC5B,UAAM,wFAAwF;AAC9F,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,MAAI,KAAK,SAAS;AAChB,YAAQ,IAAIA,QAAM,IAAI,0DAA0D,CAAC;AACjF,UAAM,IAAI,QAAc,CAACE,aAAY;AACnC,YAAM,WAAW,MAAM;AACrB,kBAAU,MAAM;AAChB,QAAAA,SAAQ;AAAA,MACV;AACA,cAAQ,KAAK,UAAU,QAAQ;AAC/B,cAAQ,KAAK,WAAW,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH,OAAO;AACL,UAAM,eAAe,OAAO,CAAC,OAAO,iBAAiB,YAAY,QAAQ,YAAY,UAAU,CAAC;AAEhG,cAAU,MAAM;AAAA,EAClB;AAEA,UAAQ,qBAAqB;AAC/B;AAEA,SAAS,eAA8B;AACrC,QAAM,MAAM,UAAU,OAAO,CAAC,WAAW,GAAG,EAAE,OAAO,SAAS,CAAC;AAC/D,MAAI,IAAI,WAAW,GAAG;AACpB,WAAO;AAAA,EACT;AACA,QAAM,SAAS,UAAU,0BAA0B,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC;AAE1E,MAAI,OAAO,OAAO;AAChB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAa,MAAiC;AACpE,SAAO,IAAI,QAAQ,CAACA,aAAY;AAC9B,UAAM,QAAQD,OAAM,KAAK,MAAM,EAAE,OAAO,UAAU,CAAC;AACnD,UAAM,GAAG,QAAQ,CAAC,SAASC,SAAQ,QAAQ,CAAC,CAAC;AAC7C,UAAM,GAAG,SAAS,MAAMA,SAAQ,CAAC,CAAC;AAAA,EACpC,CAAC;AACH;AAEA,SAAS,UAAU,OAAqB;AACtC,MAAI,MAAM,aAAa,KAAM;AAC7B,MAAI;AACF,UAAM,KAAK,SAAS;AAAA,EACtB,QAAQ;AAAA,EAER;AACF;;;AC1NA,SAAgB,WAAW,UAAU,eAAe;AACpD,SAAS,QAAQ,KAAK,MAAM,QAAQ,gBAAgB;AACpD,SAAS,cAAAC,aAAY,gBAAAC,eAAc,UAAU,UAAU,UAAU,iBAAiB;AAClF,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,cAAY;AAmDc,cAuG3B,YAvG2B;AAlCnC,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,sBAAsB;AAErB,SAAS,oBAAoB,OAA4B,CAAC,GAAS;AACxE,QAAM,YAAY,KAAK,aAAaC,OAAKC,SAAQ,GAAG,YAAY;AAChE,QAAM,QAAQ,gBAAgB,SAAS;AAKvC,QAAM,QAAQ,QAAQ,OAAO,UAAU,QAAQ,QAAQ,MAAM,UAAU;AACvE,MAAI,KAAK,SAAS,CAAC,OAAO;AACxB,kBAAc,MAAM,OAAO;AAC3B;AAAA,EACF;AAQA,UAAQ,OAAO,MAAM,4BAA4B;AACjD,QAAM,UAAU,MAAY;AAAE,YAAQ,OAAO,MAAM,sBAAsB;AAAA,EAAG;AAK5E,QAAM,WAAW,MAAY;AAAE,YAAQ;AAAG,YAAQ,KAAK,CAAC;AAAA,EAAG;AAC3D,UAAQ,KAAK,UAAU,QAAQ;AAC/B,UAAQ,KAAK,WAAW,QAAQ;AAChC,UAAQ,KAAK,QAAQ,OAAO;AAE5B,QAAM,EAAE,cAAc,IAAI,OAAO,oBAAC,aAAU,WAAW,MAAM,WAAW,SAAS,MAAM,SAAS,CAAE;AAClG,gBAAc,EAAE,MAAM,MAAM;AAAA,EAAe,CAAC,EAAE,QAAQ,OAAO;AAC/D;AAMA,SAAS,UAAU,WAAyC;AAC1D,MAAI;AACF,QAAI,CAACC,YAAW,SAAS,EAAG,QAAO;AACnC,UAAM,MAAMC,cAAa,WAAW,OAAO;AAC3C,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,YAAY,SAAiB,OAAyB;AAC7D,MAAI,CAACD,YAAW,OAAO,EAAG,QAAO,CAAC;AAClC,MAAI;AACF,UAAM,WAAW,SAAS,OAAO,EAAE;AACnC,QAAI,aAAa,EAAG,QAAO,CAAC;AAG5B,UAAM,WAAW,KAAK,IAAI,UAAU,QAAQ,GAAG;AAC/C,UAAM,KAAK,SAAS,SAAS,GAAG;AAChC,QAAI;AACF,YAAM,MAAM,OAAO,MAAM,QAAQ;AACjC,eAAS,IAAI,KAAK,GAAG,UAAU,WAAW,QAAQ;AAClD,YAAM,OAAO,IAAI,SAAS,OAAO;AACjC,YAAM,MAAM,KAAK,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACvD,aAAO,IAAI,MAAM,CAAC,KAAK;AAAA,IACzB,UAAE;AACA,gBAAU,EAAE;AAAA,IACd;AAAA,EACF,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAWA,IAAM,YAAsC,CAAC,EAAE,WAAW,QAAQ,MAAM;AACtE,QAAM,EAAE,KAAK,IAAI,OAAO;AACxB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA+B,MAAM,UAAU,SAAS,CAAC;AACrF,QAAM,CAAC,UAAU,WAAW,IAAI,SAAmB,MAAM,YAAY,SAAS,cAAc,CAAC;AAC7F,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,CAAC;AACpD,QAAM,CAAC,MAAM,OAAO,IAAI,SAA4B,MAAM;AAC1D,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,CAAC;AAKlC,YAAU,MAAM;AACd,UAAM,KAAK,YAAY,MAAM;AAC3B,gBAAU,UAAU,SAAS,CAAC;AAC9B,kBAAY,YAAY,SAAS,cAAc,CAAC;AAChD,cAAQ,CAAC,MAAM,IAAI,CAAC;AAAA,IACtB,GAAG,UAAU;AACb,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,WAAW,OAAO,CAAC;AAEvB,QAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,QAAM,WAAW,OAAO,aAAa;AAErC,WAAS,CAACE,QAAO,QAAQ;AAIvB,QAAI,SAAS,UAAU;AACrB,UAAI,IAAI,UAAUA,WAAU,IAAK,SAAQ,MAAM;AAAA,eACtC,IAAI,QAAQA,WAAU,IAAK,MAAK;AACzC;AAAA,IACF;AACA,QAAIA,WAAU,OAAQ,IAAI,QAAQA,WAAU,KAAM;AAChD,WAAK;AACL;AAAA,IACF;AACA,QAAI,OAAO,WAAW,EAAG;AACzB,QAAI,IAAI,WAAW,IAAI,WAAW;AAChC,uBAAiB,CAAC,OAAO,IAAI,IAAI,OAAO,UAAU,OAAO,MAAM;AAAA,IACjE,WAAW,IAAI,aAAa,IAAI,YAAY;AAC1C,uBAAiB,CAAC,OAAO,IAAI,KAAK,OAAO,MAAM;AAAA,IACjD,WAAW,IAAI,QAAQ;AACrB,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,WACE,qBAAC,OAAI,eAAc,UAAS,SAAS,GACnC;AAAA,0BAAC,QAAK,MAAI,MAAC,OAAM,UAAS,4CAAyB;AAAA,MACnD,oBAAC,QAAK,eAAC;AAAA,MACP,qBAAC,QAAK;AAAA;AAAA,QAAY,oBAAC,QAAK,OAAM,QAAQ,qBAAU;AAAA,SAAO;AAAA,MACvD,oBAAC,QAAK,eAAC;AAAA,MACP,qBAAC,QAAK;AAAA;AAAA,QAAyB,oBAAC,QAAK,OAAM,QAAO,+BAAiB;AAAA,SAAO;AAAA,MAC1E,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,QAAM,oBAAC,QAAK,OAAM,SAAQ,eAAC;AAAA,QAAO;AAAA,SAAS;AAAA,OAC5D;AAAA,EAEJ;AAEA,MAAI,SAAS,YAAY,UAAU;AACjC,WAAO,oBAAC,cAAW,OAAO,UAAU,UAAoB;AAAA,EAC1D;AAEA,SAAO,oBAAC,YAAS,QAAgB,QAAgB,eAA8B,UAAoB,MAAY;AACjH;AAcA,IAAM,WAAoC,CAAC,EAAE,QAAQ,QAAQ,eAAe,UAAU,KAAK,MAAM;AAC/F,QAAM,cAAc,SAAS,SAAS,SAAS,CAAC,KAAK;AACrD,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,wBAAC,aAAU,QAAgB,MAAY;AAAA,IACtC,OAAO,WAAW,IACjB,oBAAC,OAAI,SAAS,GACZ,8BAAC,QAAK,UAAQ,MAAC,gEAA6C,GAC9D,IAEA,oBAAC,OAAI,eAAc,OAAM,UAAS,QAAO,UAAU,GAChD,iBAAO,IAAI,CAACC,QAAO,MAClB;AAAA,MAAC;AAAA;AAAA,QAEC,OAAOA;AAAA,QACP,UAAU,MAAM;AAAA,QAChB,eAAe,uBAAuB,UAAUA,OAAM,QAAQ;AAAA;AAAA,MAHzDA,OAAM;AAAA,IAIb,CACD,GACH;AAAA,IAEF,oBAAC,UAAO,MAAM,aAAa;AAAA,KAC7B;AAEJ;AAEA,IAAM,YAA+D,CAAC,EAAE,QAAQ,KAAK,MAAM;AAIzF,OAAK;AACL,SACE,oBAAC,OAAI,UAAU,GAAG,UAAU,GAAG,aAAY,UAAS,aAAY,QAC9D,+BAAC,OAAI,eAAc,OAAM,gBAAe,iBAAgB,OAAM,QAC5D;AAAA,yBAAC,QAAK,MAAI,MAAC,OAAM,QAAO;AAAA;AAAA,MAAe,OAAO,OAAO;AAAA,MAAO;AAAA,MAAO,OAAO,OAAO,WAAW,IAAI,KAAK;AAAA,OAAI;AAAA,IACzG,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,MACR,OAAO;AAAA,MAAI;AAAA,MAAU,OAAO;AAAA,MAAU;AAAA,MAAW,OAAO;AAAA,MAAW;AAAA,MAAc,aAAa,OAAO,UAAU;AAAA,OACtH;AAAA,KACF,GACF;AAEJ;AAEA,IAAM,SAAqC,CAAC,EAAE,KAAK,MACjD,qBAAC,OAAI,UAAU,GAAG,eAAc,UAC9B;AAAA,uBAAC,OACC;AAAA,wBAAC,QAAK,UAAQ,MAAC,uCAAY;AAAA,IAC3B,oBAAC,QAAK,UAAQ,MAAC,gCAAe;AAAA,IAC9B,oBAAC,QAAK,UAAQ,MAAC,oBAAM;AAAA,KACvB;AAAA,EACC,QACC,qBAAC,OACC;AAAA,wBAAC,QAAK,UAAQ,MAAC,wBAAU;AAAA,IACzB,oBAAC,QAAM,mBAAS,MAAM,QAAQ,OAAO,UAAU,QAAQ,OAAO,UAAU,KAAK,GAAG,GAAE;AAAA,KACpF;AAAA,GAEJ;AAaF,IAAM,WAAoC,CAAC,EAAE,OAAAA,QAAO,UAAU,cAAc,MAAM;AAChF,QAAM,UAAUA,OAAM,WAAW,YAAYA,OAAM,WAAW,YAAYA,OAAM,WAAW;AAC3F,QAAM,cAAc,WAAW,WAAW,UAAU,QAAQ;AAC5D,QAAM,cAAcA,OAAM,WAAW,WAAW,UAAUA,OAAM,WAAW,WAAW,WAAW,UAAU,QAAQ;AACnH,QAAM,UAAUA,OAAM,iBAClB,IAAIA,OAAM,WAAW,SAASA,OAAM,UAAU,MAC9CA,OAAM,cACJ,IAAIA,OAAM,WAAW,UACrB;AACN,SACE,qBAAC,OAAI,eAAc,UAAS,aAAY,SAAQ,aAA0B,UAAU,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,IAC7H;AAAA,yBAAC,OACC;AAAA,0BAAC,QAAK,MAAI,MAAE,UAAAA,OAAM,UAAS;AAAA,MAC3B,oBAAC,QAAK,eAAC;AAAA,MACP,oBAAC,QAAK,OAAO,aAAc,UAAAA,OAAM,UAAU,WAAU;AAAA,OACvD;AAAA,IACA,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,MAASA,OAAM,kBAAkB;AAAA,MAAI;AAAA,MAAUA,OAAM,gBAAgB;AAAA,OAAI;AAAA,IACxF,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,MAAS;AAAA,OAAQ;AAAA,IAChC,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,MAAcA,OAAM,aAAa,UAAU;AAAA,OAAE;AAAA,IAC5D,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,MAAgB,aAAaA,OAAM,eAAe;AAAA,OAAE;AAAA,IAClE,iBACC,qBAAC,QACC;AAAA,0BAAC,QAAK,OAAM,QAAO,oBAAC;AAAA,MAAO;AAAA,MAAE,SAAS,eAAe,EAAE;AAAA,OACzD;AAAA,KAEJ;AAEJ;AAWA,IAAM,aAAwC,CAAC,EAAE,OAAAA,QAAO,SAAS,MAAM;AACrE,QAAM,SAAS;AAAA,IACb,MAAM,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,SAASA,OAAM,SAAS,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,mBAAmB;AAAA,IAC/G,CAAC,UAAUA,OAAM,QAAQ;AAAA,EAC3B;AACA,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,yBAAC,OAAI,UAAU,GAAG,aAAY,UAAS,aAAY,QACjD;AAAA,0BAAC,QAAK,MAAI,MAAC,OAAM,QAAQ,UAAAA,OAAM,UAAS;AAAA,MACxC,oBAAC,QAAK,oBAAG;AAAA,MACT,oBAAC,QAAM,UAAAA,OAAM,UAAU,WAAU;AAAA,MACjC,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,QAAYA,OAAM,kBAAkB;AAAA,QAAI;AAAA,QAAUA,OAAM,gBAAgB;AAAA,SAAI;AAAA,OAC7F;AAAA,IACA,qBAAC,OAAI,UAAU,GAAG,WAAW,GAAG,eAAc,UAC5C;AAAA,0BAAC,QAAK,MAAI,MAAC,qBAAO;AAAA,MAClB,oBAAC,QACE,UAAAA,OAAM,iBACH,eAAeA,OAAM,WAAW,SAASA,OAAM,UAAU,MACzDA,OAAM,cACJ,eAAeA,OAAM,WAAW,qBAChC,yBACR;AAAA,OACF;AAAA,IACA,qBAAC,OAAI,UAAU,GAAG,WAAW,GAAG,eAAc,UAC5C;AAAA,2BAAC,QAAK,MAAI,MAAC;AAAA;AAAA,QAAeA,OAAM,aAAa,UAAU;AAAA,QAAE;AAAA,SAAC;AAAA,OACxDA,OAAM,eAAe,CAAC,GAAG,WAAW,IACpC,oBAAC,QAAK,UAAQ,MAAC,kBAAI,KAElBA,OAAM,eAAe,CAAC,GAAG,IAAI,CAAC,MAC7B,qBAAC,QAAuB;AAAA;AAAA,QACnB,EAAE;AAAA,QAAa;AAAA,QAAE,EAAE,eAAe;AAAA,QAAG;AAAA,QAAI,EAAE;AAAA,QAAW;AAAA,QAAU,EAAE;AAAA,QAAU;AAAA,QAAY,aAAa,EAAE,SAAS;AAAA,WAD1G,EAAE,SAEb,CACD;AAAA,OAEL;AAAA,IACA,qBAAC,OAAI,UAAU,GAAG,WAAW,GAAG,eAAc,UAC5C;AAAA,2BAAC,QAAK,MAAI,MAAC;AAAA;AAAA,QAAkB,OAAO;AAAA,QAAO;AAAA,QAAsBA,OAAM;AAAA,QAAS;AAAA,SAAE;AAAA,MACjF,OAAO,WAAW,IACjB,oBAAC,QAAK,UAAQ,MAAC,wDAA0C,IAEzD,OAAO,IAAI,CAAC,MAAM,MAChB,oBAAC,QAAc,mBAAS,MAAM,QAAQ,OAAO,UAAU,QAAQ,OAAO,UAAU,IAAI,GAAG,KAA5E,CAA8E,CAC1F;AAAA,OAEL;AAAA,IACA,oBAAC,OAAI,UAAU,GAAG,WAAW,GAC3B,8BAAC,QAAK,UAAQ,MAAC,uCAAsB,GACvC;AAAA,KACF;AAEJ;AAMA,SAAS,uBAAuB,OAAiB,UAAiC;AAChF,WAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC1C,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,QAAQ,KAAK,YAAY,EAAE,SAAS,SAAS,YAAY,CAAC,EAAG,QAAO;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,aAAa,KAAwC;AAC5D,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,IAAI,KAAK,GAAG,EAAE,QAAQ;AAChC,MAAI,MAAM,CAAC,EAAG,QAAO;AACrB,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC;AACvC,QAAM,MAAM,KAAK,MAAM,OAAO,GAAI;AAClC,MAAI,MAAM,GAAI,QAAO,GAAG,GAAG;AAC3B,QAAM,MAAM,KAAK,MAAM,MAAM,EAAE;AAC/B,MAAI,MAAM,GAAI,QAAO,GAAG,GAAG;AAC3B,QAAM,KAAK,KAAK,MAAM,MAAM,EAAE;AAC9B,MAAI,KAAK,GAAI,QAAO,GAAG,EAAE;AACzB,SAAO,GAAG,KAAK,MAAM,KAAK,EAAE,CAAC;AAC/B;AAEA,SAAS,SAAS,GAAW,KAAqB;AAChD,SAAO,EAAE,SAAS,MAAM,GAAG,EAAE,MAAM,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,WAAM;AACnE;AAMA,SAAS,cAAc,SAAuB;AAC5C,MAAI,CAACH,YAAW,OAAO,GAAG;AACxB,YAAQ,OAAO,MAAM,2BAA2B,OAAO;AAAA;AAAA,CAAiD;AACxG,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,MAAI,WAAW;AACf,MAAI;AACF,UAAM,UAAUC,cAAa,SAAS,OAAO;AAC7C,YAAQ,OAAO,MAAM,OAAO;AAC5B,eAAW,SAAS,OAAO,EAAE;AAAA,EAC/B,SAAS,KAAK;AACZ,YAAQ,OAAO,MAAM,uBAAwB,IAAc,OAAO;AAAA,CAAI;AACtE,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,QAAM,KAAK,YAAY,MAAM;AAC3B,QAAI;AACF,YAAM,OAAO,SAAS,OAAO,EAAE;AAM/B,UAAI,OAAO,SAAU,YAAW;AAChC,UAAI,SAAS,SAAU;AACvB,YAAM,KAAK,SAAS,SAAS,GAAG;AAChC,UAAI;AACF,cAAM,MAAM,OAAO,MAAM,OAAO,QAAQ;AACxC,iBAAS,IAAI,KAAK,GAAG,IAAI,QAAQ,QAAQ;AACzC,gBAAQ,OAAO,MAAM,IAAI,SAAS,OAAO,CAAC;AAC1C,mBAAW;AAAA,MACb,UAAE;AACA,kBAAU,EAAE;AAAA,MACd;AAAA,IACF,QAAQ;AAAA,IAA0D;AAAA,EACpE,GAAG,GAAG;AACN,QAAM,OAAO,MAAY;AACvB,kBAAc,EAAE;AAChB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,IAAI;AACzB,UAAQ,GAAG,WAAW,IAAI;AAC5B;;;ACvaA,OAAOG,aAAW;AAClB,OAAOC,YAAW;AAClB,SAAS,gBAAAC,eAAc,cAAAC,mBAAkB;AACzC,SAAS,QAAAC,cAAY;AAiBrB,eAAsB,iBACpB,UACA,MACe;AACf,QAAM,OAAO,WAAW;AAOxB,QAAM,aAAaC,OAAK,KAAK,WAAW,UAAU,WAAW;AAC7D,QAAM,YAAYA,OAAK,KAAK,WAAW,UAAU,cAAc,WAAW;AAC1E,QAAM,WAAWC,YAAW,UAAU,IAAI,aAAa;AACvD,QAAM,iBAAiBA,YAAW,QAAQ;AAU1C,MAAI,cAAyC;AAC7C,MAAI,WAA2C;AAE/C,MAAI,UAAU,GAAG;AACf,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,IAGpB,WAAW,mBAAmB,QAAQ,CAAC,iBAAiB;AAE3D,iBAAW,KAAK,SAAS;AAEzB,UAAI,KAAK,iBAAiB;AACxB,sBAAc,OAAO,QAAQ,KAAK,eAAe,EAAE;AAAA,UACjD,CAAC,CAAC,WAAW,GAAG,OAAO;AAAA,YACrB,YAAY;AAAA,YACZ,QAAQ,IAAI;AAAA,YACZ,QAAQ,IAAI;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,MAAI,CAAC,kBAAkB,CAAC,UAAU;AAChC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,UAAU,QAAQ,cAAc,CAAC;AAAA,IAClE,OAAO;AACL,YAAM,UAAU,QAAQ,aAAa;AAAA,IACvC;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAIA,MAAI,UAAqC;AACzC,MAAI,QAAiC;AACrC,MAAI,iBAAiD;AACrD,MAAI,aAKO;AAEX,MAAI,gBAAgB;AAElB,UAAM,cAAcD,OAAK,UAAU,YAAY;AAC/C,QAAIC,YAAW,WAAW,GAAG;AAC3B,YAAM,MAAMC,cAAa,aAAa,OAAO;AAC7C,YAAM,SAAS,mBAAmB,GAAG;AACrC,UAAI,OAAO,aAAa;AACtB,kBAAU,OAAO;AAAA,MACnB;AAAA,IACF;AAGA,UAAM,YAAYF,OAAK,UAAU,UAAU;AAC3C,QAAIC,YAAW,SAAS,GAAG;AACzB,YAAM,MAAMC,cAAa,WAAW,OAAO;AAC3C,YAAM,SAAS,mBAAmB,GAAG;AACrC,UAAI,OAAO,aAAa;AACtB,gBAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAGA,UAAM,eAAeF,OAAK,UAAU,gBAAgB;AACpD,QAAIC,YAAW,YAAY,GAAG;AAC5B,UAAI;AACF,cAAM,MAAMC,cAAa,cAAc,OAAO;AAC9C,yBAAiBC,OAAM,MAAM,GAAG;AAAA,MAClC,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,UAAM,YAAYH,OAAK,KAAK,WAAW,oBAAoB;AAC3D,QAAIC,YAAW,SAAS,GAAG;AACzB,UAAI;AACF,cAAM,MAAMC,cAAa,WAAW,OAAO;AAC3C,cAAM,QAAQ,KAAK,MAAM,GAAG;AAS5B,qBAAa,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ,KAAK;AAAA,MACrE,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAeA,QAAM,cAA4B,CAAC;AAEnC,MAAI,eAAe,YAAY,SAAS,GAAG;AAEzC,eAAW,MAAM,aAAa;AAC5B,YAAM,MAAM,WAAW,GAAG,UAAU;AACpC,kBAAY,KAAK;AAAA,QACf,IAAI,GAAG;AAAA,QACP,MAAM,KAAK,QAAQ,GAAG;AAAA,QACtB,MAAM,KAAK,gBAAgB;AAAA,QAC3B,SAAS;AAAA,QACT,QAAQ,GAAG;AAAA,QACX,KAAK,MAAM,OAAO,IAAI,YAAY,IAAI;AAAA,MACxC,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AAEL,UAAM,mBAAmB,MAAM,QAAQ,gBAAgB,QAAQ,IAC1D,eAAgB,WACjB,CAAC;AAEL,eAAW,MAAM,kBAAkB;AACjC,YAAM,MAAM,WAAW,GAAG,EAAE;AAC5B,kBAAY,KAAK;AAAA,QACf,IAAI,GAAG;AAAA,QACP,MAAM,KAAK,QAAQ,GAAG;AAAA,QACtB,MAAM,KAAK,gBAAgB;AAAA,QAC3B,SAAS,GAAG,YAAY;AAAA,QACxB,QAAQ,GAAG,YAAY,QAAQ,eAAe;AAAA,QAC9C,KAAK,MAAM,OAAO,IAAI,YAAY,IAAI;AAAA,MACxC,CAAC;AAAA,IACH;AAAA,EACF;AAIA,MAAI,MAAM;AACR,UAAME,YAAW,KAAK,cAAc,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO;AACrF,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,WAAW;AAAA,QACX,cAAe,UAAU,gBAA2B,SAAS,gBAAgB;AAAA,QAC7E,UAAW,UAAU,YAAuB,SAAS,YAAY;AAAA,QACjE,aAAc,UAAU,eAA0B,SAAS,eAAe;AAAA,QAC1E,WAAY,UAAU,aAAwB,SAAS,aAAa;AAAA,QACpE,OAAO,SAAS,SAAS;AAAA,QACzB,cAAc,SAAS,gBAAgB;AAAA,QACvC,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU;AAAA,MAC7B;AAAA,MACA,UAAU;AAAA,QACR,SAAS,YAAY,kBAAkB,SAAS,WAAW;AAAA,QAC3D,OAAO,YAAY,gBAAgB,OAAO,WAAW;AAAA,QACrD,gBAAgB,YAAY,mBAAmB;AAAA,QAC/C,kBAAkB,YAAY,oBAAoB;AAAA,MACpD;AAAA,MACA,OAAO;AAAA,QACL,kBAAkB,OAAO,oBAAoB;AAAA,QAC7C,iBAAiB,OAAO,mBAAmB;AAAA,QAC3C,OAAO,OAAO,OAAO,UAAU;AAAA,QAC/B,OAAO,OAAO,SAAS,CAAC;AAAA,MAC1B;AAAA,MACA,UAAUA;AAAA,MACV,UAAU,iBACN,EAAE,SAAU,eAAuB,WAAW,MAAM,SAAU,eAAuB,WAAW,KAAK,IACrG;AAAA,IACN,CAAC;AACD;AAAA,EACF;AAIA,QAAM,cAAe,UAAU,gBAA2B,SAAS,gBAAgB;AACnF,UAAQ,IAAIC,QAAM,KAAK;AAAA,SAAY,QAAQ,EAAE,KAAK,gBAAgB,WAAW,KAAK,WAAW,MAAM,MAAM,IAAI;AAE7G,MAAI,WAAW,UAAU;AACvB,UAAM,UAAW,UAAU,YAAuB,SAAS;AAC3D,UAAM,cAAe,UAAU,eAA0B,SAAS;AAClE,UAAM,WAAY,UAAU,aAAwB,SAAS;AAE7D,SAAK,iBAAiB,WAAW,QAAG,EAAE;AACtC,SAAK,iBAAiB,eAAe,QAAG,EAAE;AAC1C,SAAK,iBAAiB,YAAY,QAAG,EAAE;AACvC,SAAK,iBAAiB,SAAS,OAAO,QAAQ,QAAG,EAAE;AAEnD,UAAM,aAAa,YAAY,kBAAkB,SAAS;AAC1D,UAAM,WAAW,YAAY,gBAAgB,OAAO,WAAW;AAC/D,UAAM,SAAS,YAAY,kBACvB,gBAAgB,WAAW,eAAe,IAC1C;AAEJ,QAAI,YAAY;AACd,WAAK,kBAAkB,UAAU,GAAG,SAAS,iBAAiB,MAAM,MAAM,EAAE,EAAE;AAAA,IAChF;AACA,QAAI,aAAa,UAAK;AACpB,WAAK,kBAAkB,QAAQ,GAAG,SAAS,iBAAiB,MAAM,MAAM,EAAE,EAAE;AAAA,IAC9E;AAGA,UAAM,UAAU,iBAAkB,eAAuB,UAAU;AACnE,QAAI,WAAW,MAAM;AACnB,WAAK,iBAAiB,UAAU,OAAO,KAAK,EAAE;AAAA,IAChD;AAGA,UAAM,IAAI,SAAS;AACnB,QAAI,GAAG;AACL,YAAM,YAAY,GAAG,EAAE,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,KAAK,EAAE,eAAe,OAAO;AAClG,WAAK,iBAAiB,SAAS,EAAE;AAAA,IACnC;AAAA,EACF,OAAO;AACL,SAAK,6BAA6B;AAAA,EACpC;AAIA,QAAM,WAAW,KAAK,cAAc,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO;AAErF,UAAQ,IAAIA,QAAM,KAAK,aAAa,CAAC;AAErC,MAAI,SAAS,WAAW,GAAG;AACzB,SAAK,gBAAgB;AAAA,EACvB,OAAO;AACL;AAAA,MACE,CAAC,WAAW,QAAQ,QAAQ,UAAU,KAAK;AAAA,MAC3C,SAAS,IAAI,CAAC,MAAM;AAAA,QAClB,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AAIA,MAAI,OAAO;AACT,YAAQ,IAAIA,QAAM,KAAK,UAAU,CAAC;AAElC,QAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,WAAK,mBAAmB;AAAA,IAC1B,OAAO;AACL;AAAA,QACE,CAAC,MAAM,QAAQ,QAAQ,UAAU,aAAa;AAAA,QAC9C,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC;AAAA,MACxE;AAAA,IACF;AAGA,QAAI,MAAM,iBAAiB;AACzB,YAAM,KAAK,MAAM;AACjB,cAAQ,IAAIA,QAAM,KAAK,oBAAoB,CAAC;AAC5C,WAAK,cAAc,GAAG,2BAA2B,SAAS,oBAAoB,kBAAkB,EAAE;AAClG,WAAK,cAAc,GAAG,kBAAkB,IAAI;AAC5C,WAAK,cAAc,GAAG,sBAAsB,MAAM;AAClD,WAAK,cAAc,GAAG,eAAe,EAAE;AAAA,IACzC;AAAA,EACF;AAEA,UAAQ,IAAI;AACd;AAEA,SAAS,gBAAgB,KAAqB;AAC5C,QAAM,IAAI,IAAI,KAAK,GAAG;AACtB,QAAM,MAAM,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,SAAO,GAAG,EAAE,YAAY,CAAC,IAAI,IAAI,EAAE,SAAS,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,IAAI,EAAE,WAAW,CAAC,CAAC;AACpH;;;ACvUA,OAAOC,aAAW;AAClB,OAAOC,WAAS;AA0BhB,eAAe,eAAe,UAA0C;AACtE,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAA0B,WAAW,QAAQ,EAAE;AACtE,WAAO,KAAK;AAAA,EACd,SAAS,KAAK;AACZ,QAAI,eAAe,YAAY,IAAI,WAAW,IAAK,QAAO;AAC1D,UAAM;AAAA,EACR;AACF;AAEA,SAAS,cAAc,GAAmB;AACxC,SAAO,MAAM,IAAIC,QAAM,IAAI,MAAM,IAAI,MAAM,IAAIA,QAAM,IAAI,KAAK,IAAIA,QAAM,OAAO,KAAK;AACtF;AAEA,SAAS,gBAAgB,SAA6B,UAA0B;AAC9E,MAAI,CAAC,QAAS,QAAOA,QAAM,IAAI,QAAG;AAClC,MAAI;AACF,WAAO,IAAI,KAAK,eAAe,SAAS;AAAA,MACtC,WAAW;AAAA,MACX,WAAW;AAAA,MACX,UAAU;AAAA,IACZ,CAAC,EAAE,OAAO,IAAI,KAAK,OAAO,CAAC;AAAA,EAC7B,QAAQ;AACN,WAAO,IAAI,KAAK,OAAO,EAAE,eAAe;AAAA,EAC1C;AACF;AAMA,eAAsB,0BACpB,OACA,MASe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAGxB,MAAI;AACJ,MAAI,KAAK,UAAU;AACjB,eAAW,OAAO,KAAK,QAAQ;AAC/B,QAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,KAAK,WAAW,GAAG;AAC/D,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,8BAA8B,CAAC;AAAA,MAChE,OAAO;AACL,cAAM,mDAAmD;AAAA,MAC3D;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,KAAK,UAAU;AACjB,uBAAmB,OAAO,KAAK,QAAQ;AACvC,QAAI,CAAC,OAAO,UAAU,gBAAgB,KAAK,oBAAoB,GAAG;AAChE,UAAI,MAAM;AACR,mBAAW,EAAE,IAAI,OAAO,OAAO,gDAAgD,CAAC;AAAA,MAClF,OAAO;AACL,cAAM,+CAA+C;AAAA,MACvD;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAUC,MAAI,EAAE,MAAM,qCAAgC,UAAU,KAAK,CAAC;AAC5E,UAAQ,MAAM;AAEd,QAAM,UAAU,MAAM,eAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,YAAQ,KAAK,UAAU,KAAK,KAAK,aAAa;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAAsC,0BAA0B;AAAA,MACrF,UAAU;AAAA,MACV;AAAA,MACA,aAAa,KAAK,eAAe;AAAA,MACjC;AAAA,MACA,mBAAmB;AAAA,MACnB,aAAa,KAAK,eAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,UAAU,KAAK,YAAY;AAAA,IAC7B,CAAC;AAED,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,UAAU,KAAK,SAAS,CAAC;AAChD;AAAA,IACF;AAEA,YAAQ,2BAA2BD,QAAM,KAAK,KAAK,CAAC,EAAE;AACtD,SAAK,eAAeA,QAAM,KAAK,KAAK,SAAS,oBAAoB,KAAK,SAAS,cAAc,KAAK,SAAS,kBAAkB,EAAE,CAAC,EAAE;AAClI,SAAK,eAAe,gBAAgB,KAAK,SAAS,eAAe,KAAK,SAAS,QAAQ,CAAC,EAAE;AAC1F,SAAK,eAAe,KAAK,SAAS,QAAQ,EAAE;AAAA,EAC9C,SAAS,KAAK;AACZ,YAAQ,KAAK,qCAAqC;AAClD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,2BACpB,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAUC,MAAI,EAAE,MAAM,sCAAiC,UAAU,KAAK,CAAC;AAC7E,UAAQ,MAAM;AAEd,QAAM,UAAU,MAAM,eAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,YAAQ,KAAK,UAAU,KAAK,KAAK,aAAa;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI;AAAA,MACrB,mCAAmC,OAAO;AAAA,IAC5C;AAEA,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,WAAW,KAAK,UAAU,CAAC;AAClD;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,WAAW,GAAG;AAC/B,WAAK,+BAA+B;AACpC;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,UAAU,IAAI,CAAC,MAAM;AAAA,MACrC,EAAE,GAAG,MAAM,GAAG,CAAC;AAAA,MACf,EAAE;AAAA,MACF,EAAE,oBAAoB,EAAE,cAAc,EAAE,kBAAkB;AAAA,MAC1D,cAAc,EAAE,QAAQ;AAAA,MACxB,EAAE,UAAUD,QAAM,MAAM,QAAQ,IAAIA,QAAM,IAAI,UAAU;AAAA,MACxD,gBAAgB,EAAE,eAAe,EAAE,QAAQ;AAAA,MAC3C,OAAO,EAAE,WAAW;AAAA,IACtB,CAAC;AAED;AAAA,MACE,CAAC,MAAM,SAAS,YAAY,YAAY,UAAU,cAAc,SAAS;AAAA,MACzE;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,qCAAqC;AAClD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,8BACpB,WACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAUC,MAAI,EAAE,MAAM,sCAAiC,UAAU,KAAK,CAAC;AAC7E,UAAQ,MAAM;AAEd,QAAM,UAAU,MAAM,eAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,YAAQ,KAAK,UAAU,KAAK,KAAK,aAAa;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI;AAAA,MACrB,mCAAmC,OAAO;AAAA,IAC5C;AAEA,UAAM,UAAU,KAAK,UAAU;AAAA,MAC7B,CAAC,MAAM,EAAE,GAAG,WAAW,SAAS,KAAK,EAAE,MAAM,YAAY,MAAM,UAAU,YAAY;AAAA,IACvF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,KAAK,uBAAuB,SAAS,aAAa;AAC1D,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ,KAAK,wBAAwB,SAAS,YAAO,QAAQ,MAAM,mBAAmB;AACtF,iBAAW,KAAK,SAAS;AACvB,aAAK,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC,WAAM,EAAE,KAAK,EAAE;AAAA,MAC3C;AACA,WAAK,yCAAyC;AAC9C,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,CAAC;AACxE,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,MAAM,OAAO,SAAS,MAAM,CAAC;AAAA,IAC3E,OAAO;AACL,cAAQ,aAAaD,QAAM,KAAK,MAAM,KAAK,CAAC,EAAE;AAAA,IAChD;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK,sCAAsC;AACnD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;ACnRA,SAAS,cAAAE,aAAY,gBAAAC,eAAc,iBAAAC,gBAAe,aAAAC,YAAW,YAAY,aAAa,mBAAmB;AACzG,SAAS,QAAAC,QAAM,WAAAC,gBAAe;AAC9B,SAAS,WAAAC,gBAAe;AACxB,OAAOC,aAAW;AAClB,OAAOC,WAAS;AAWhB,SAAS,qBAA6B;AACpC,QAAM,QAAQ,QAAQ,IAAI,OAAO,KAAK;AACtC,QAAM,OAAOC,SAAQ;AAErB,MAAI,MAAM,SAAS,KAAK,GAAG;AAGzB,WAAOC,OAAK,MAAM,QAAQ;AAAA,EAC5B;AAEA,MAAI,MAAM,SAAS,MAAM,GAAG;AAC1B,UAAM,aAAaA,OAAK,MAAM,WAAW,QAAQ,aAAa;AAC9D,WAAO;AAAA,EACT;AAGA,QAAM,SAASA,OAAK,MAAM,SAAS;AACnC,MAAIC,YAAW,MAAM,EAAG,QAAO;AAC/B,SAAOD,OAAK,MAAM,eAAe;AACnC;AAuBA,SAAS,wBACP,QACA,QACA,YACqB;AACrB,QAAM,QAA6B,EAAE,gBAAgB,OAAO,UAAU,OAAO,QAAQ,MAAM;AAC3F,MAAI,QAAQ,aAAa,QAAS,QAAO;AACzC,MAAI,OAAO,QAAQ,WAAW,cAAc,QAAQ,OAAO,MAAM,EAAG,QAAO;AAE3E,SAAO;AAAA,IACL,gBAAgB,oBAAoB,QAAQ,QAAQ,UAAU;AAAA,IAC9D,UAAU,oBAAoB,QAAQ,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA,IAIxD,QAAQ,4BAA4B;AAAA,EACtC;AACF;AAGA,SAAS,uBAAuB,OAAuB;AACrD,SAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,EAAE,QAAQ,UAAU,KAAK,CAAC;AACvF;AAGA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,IAAI,MAAM,QAAQ,MAAM,OAAO,CAAC;AACzC;AAUA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC;AAC9D;AAEO,SAAS,oBACd,QACA,QACA,YACS;AACT,QAAM,UAAU;AAChB,MAAI,CAACC,YAAW,OAAO,EAAG,QAAO;AACjC,MAAI;AACF,eAAW,SAAS,YAAY,IAAI;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,UAAUC,cAAa,SAAS,OAAO;AAI7C,UAAM,WAAW,QACd,MAAM,OAAO,EACb,OAAO,CAAC,SAAS,CAAC,sDAAsD,KAAK,IAAI,CAAC,EAClF,KAAK,IAAI;AACZ,UAAM,OAAO,SAAS,SAAS,IAAI,KAAK,SAAS,WAAW,IAAI,WAAW,GAAG,QAAQ;AAAA;AACtF,UAAM,QAAQ;AAAA,MACZ,YAAY,uBAAuB,MAAM,CAAC;AAAA,MAC1C,eAAe,uBAAuB,MAAM,CAAC;AAAA,IAC/C;AACA,QAAI,WAAY,OAAM,KAAK,mBAAmB,uBAAuB,UAAU,CAAC,EAAE;AAClF,UAAM,WAAW,GAAG,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC3C,IAAAC,eAAc,SAAS,UAAU,EAAE,MAAM,IAAM,CAAC;AAChD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,oBACd,QACA,QACA,YACS;AACT,QAAM,WAAW;AACjB,MAAI,CAACF,YAAW,QAAQ,EAAG,QAAO;AAClC,MAAI;AACF,eAAW,UAAU,YAAY,IAAI;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,aAAa,GAAG,QAAQ;AAI9B,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,mBAAmB,mBAAmB,MAAM,CAAC;AAAA,MAC7C,sBAAsB,mBAAmB,MAAM,CAAC;AAAA,IAClD;AACA,QAAI,WAAY,OAAM,KAAK,0BAA0B,mBAAmB,UAAU,CAAC,EAAE;AACrF,UAAM,KAAK,EAAE;AACb,IAAAE,eAAc,YAAY,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,IAAM,CAAC;AAC3D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,8BAAuC;AAC9C,QAAM,SAAS;AACf,MAAI,CAACF,YAAW,MAAM,EAAG,QAAO;AAChC,MAAI;AACF,eAAW,QAAQ,YAAY,IAAI;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,UAAUC,cAAa,QAAQ,OAAO;AAC5C,UAAM,SAAS;AACf,QAAI,QAAQ,SAAS,MAAM,EAAG,QAAO;AACrC,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AACX,IAAAC,eAAc,QAAQ,UAAU,OAAO;AACvC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,iBACd,OACA,QACA,QACA,YACQ;AACR,MAAI,MAAM,SAAS,MAAM,GAAG;AAC1B,UAAMC,SAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,oBAAoB,kBAAkB,MAAM,CAAC;AAAA,MAC7C,uBAAuB,kBAAkB,MAAM,CAAC;AAAA,IAClD;AACA,QAAI,WAAY,CAAAA,OAAM,KAAK,2BAA2B,kBAAkB,UAAU,CAAC,EAAE;AACrF,IAAAA,OAAM,KAAK,EAAE;AACb,WAAOA,OAAM,KAAK,IAAI;AAAA,EACxB;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,mBAAmB,mBAAmB,MAAM,CAAC;AAAA,IAC7C,sBAAsB,mBAAmB,MAAM,CAAC;AAAA,EAClD;AACA,MAAI,WAAY,OAAM,KAAK,0BAA0B,mBAAmB,UAAU,CAAC,EAAE;AACrF,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAaA,eAAsB,aAAa,OAAe,UAAwB,CAAC,GAAkB;AAC3F,QAAM,OAAO,WAAW;AAGxB,QAAM,oBAAoB;AAC1B,QAAM,qBAAqB;AAC3B,MAAI,CAAC,SAAU,CAAC,kBAAkB,KAAK,KAAK,KAAK,CAAC,mBAAmB,KAAK,KAAK,GAAI;AACjF,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,0EAA0E,CAAC;AAAA,IAC5G,OAAO;AACL,YAAM,yEAAyE;AAC/E,WAAK,8EAA8E;AAAA,IACrF;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,kBAAkB,kBAAkB,KAAK,KAAK,IAAI,MAAM,YAAY,IAAI,MAAM,YAAY;AAShG,QAAM,cAAc,QAAQ,SAAS,KAAK;AAC1C,QAAM,UAAU,QAAQ,IAAI,UAAU,GAAG,KAAK;AAC9C,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,QAAQ;AACX,UAAM,MACJ;AAIF,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,IACtC,OAAO;AACL,YAAM,GAAG;AAAA,IACX;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,QAAI,aAAa;AACf,WAAK,4BAA4BC,QAAM,KAAK,MAAM,CAAC,oBAAoB;AAAA,IACzE,OAAO;AACL,WAAK,4BAA4BA,QAAM,KAAK,MAAM,CAAC,kBAAkB;AAAA,IACvE;AAAA,EACF;AAGA,QAAM,UAAUC,MAAI,EAAE,MAAM,uCAAuC,UAAU,KAAK,CAAC;AACnF,UAAQ,MAAM;AAEd,MAAI;AASJ,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,eAAe;AAAA,MAC9C,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,gBAAgB,CAAC;AAAA,IACjD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,YAAM,IAAI,MAAO,KAAK,OAAO,KAAgB,sBAAsB,IAAI,MAAM,EAAE;AAAA,IACjF;AAEA,kBAAc,MAAM,IAAI,KAAK;AAC7B,YAAQ,QAAQ,6BAA6B;AAAA,EAC/C,SAAS,KAAK;AACZ,YAAQ,KAAK,uCAAuC;AACpD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,cAAc,YAAY,WAAW;AAG3C,UAAQ,IAAI,UAAU,IAAI;AAC1B,UAAQ,IAAI,aAAa,IAAI,YAAY;AAGzC,QAAM,gBAAgBA,MAAI,EAAE,MAAM,8BAA8B,UAAU,KAAK,CAAC;AAChF,gBAAc,MAAM;AAEpB,MAAI;AACF,UAAM,WAAW,MAAM,eAAe,YAAY,OAAO;AACzD,kBAAc,QAAQ,qBAAqB;AAE3C,QAAI,CAAC,MAAM;AACT,WAAK,eAAeD,QAAM,KAAK,YAAY,SAAS,CAAC,EAAE;AACvD,WAAK,eAAe,SAAS,MAAM,EAAE;AACrC,WAAK,eAAeA,QAAM,KAAK,SAAS,YAAY,YAAY,aAAa,SAAS,CAAC,EAAE;AACzF,UAAI,SAAS,WAAW;AACtB,aAAK,eAAeA,QAAM,KAAK,SAAS,SAAS,CAAC,EAAE;AAAA,MACtD;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,kBAAc,KAAK,gCAAgC;AACnD,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAC5B,WAAK,kFAAkF;AACvF,WAAK,mDAAmD;AAAA,IAC1D;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,QAAM,cAAc,mBAAmB;AACvC,QAAM,QAAQ,QAAQ,IAAI,OAAO,KAAK;AAOtC,QAAM,aAAa,iBAAiB,WAAW;AAK/C,MAAI,YAAY;AACd,YAAQ,IAAI,iBAAiB,IAAI;AAAA,EACnC;AACA,MAAI,CAAC,QAAQ,CAAC,YAAY;AACxB;AAAA,MACE,yCAAyC,WAAW;AAAA,IACtD;AAAA,EACF;AAEA,QAAM,cAAc,iBAAiB,OAAO,aAAa,YAAY,SAAS,UAAU;AACxF,QAAM,aAAaE,SAAQ,WAAW;AACtC,MAAI,CAACN,YAAW,UAAU,GAAG;AAC3B,IAAAO,WAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAGA,QAAM,SAAS;AACf,QAAM,UAAUP,YAAW,WAAW,IAAIC,cAAa,aAAa,OAAO,IAAI;AAC/E,MAAI;AACJ,MAAI,QAAQ,SAAS,MAAM,GAAG;AAG5B,cAAU,QAAQ;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,MAAM;AACT,WAAK,6DAA6D;AAAA,IACpE;AAAA,EACF,OAAO;AACL,cAAU,UAAU;AAAA,EACtB;AACA,EAAAC,eAAc,aAAa,QAAQ,SAAS,IAAI,IAAI,UAAU,GAAG,OAAO;AAAA,CAAI;AAE5E,MAAI,CAAC,MAAM;AACT,YAAQ,oCAAoCE,QAAM,KAAK,WAAW,CAAC,EAAE;AAAA,EACvE;AAOA,QAAM,MAAM,wBAAwB,aAAa,YAAY,SAAS,UAAU;AAGhF,QAAM,uBAAuB,IAAI,kBAAkB,IAAI;AACvD,MAAI,CAAC,QAAQ,sBAAsB;AACjC,UAAMI,YAAW;AAAA,MACf,IAAI,iBAAiB,qBAAqB;AAAA,MAC1C,IAAI,WAAW,0BAA0B;AAAA,MACzC,IAAI,SAAS,gBAAgB;AAAA,IAC/B,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK;AAC5B,YAAQ,4BAA4BA,SAAQ,EAAE;AAAA,EAChD;AAMA,QAAM,iBAAiBH,MAAI,EAAE,MAAM,iCAAiC,UAAU,KAAK,CAAC;AACpF,iBAAe,MAAM;AAErB,MAAI;AACF,UAAM,YAAYN,OAAKD,SAAQ,GAAG,YAAY;AAC9C,UAAM,EAAE,IAAI,IAAI,cAAc,EAAE,YAAY,KAAQ,WAAW,UAAU,KAAK,CAAC;AAC/E,mBAAe,QAAQ,wBAAwB,GAAG,GAAG;AAAA,EACvD,SAAS,KAAK;AACZ,mBAAe,KAAK,gCAAgC;AACpD,QAAI,CAAC,MAAM;AACT,WAAM,IAAc,OAAO;AAC3B,WAAK,2CAA2C;AAAA,IAClD;AAAA,EACF;AASA,QAAM,gBAAgB,QAAQ,IAAI,2BAA2B,MAAM;AACnE,MAAI,MAAM;AACR,eAAW;AAAA,MACT,IAAI;AAAA,MACJ,WAAW,YAAY;AAAA,MACvB,SAAS,YAAY;AAAA,MACrB,WAAW,YAAY;AAAA,MACvB,SAAS;AAAA,MACT,GAAI,gBAAgB,EAAE,SAAS,YAAY,QAAQ,IAAI,CAAC;AAAA,MACxD,QAAQ,YAAY;AAAA,MACpB,SAAS;AAAA,IACX,CAAC;AAKD,YAAQ,KAAK,CAAC;AAAA,EAChB,OAAO;AACL,YAAQ,IAAI;AACZ,YAAQ,IAAIM,QAAM,MAAM,KAAK,mBAAmB,CAAC;AACjD,YAAQ,IAAI;AACZ,QAAI,YAAY,OAAO,SAAS,GAAG;AACjC,WAAK,eAAe,YAAY,OAAO,IAAI,CAAC,MAAMA,QAAM,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IAC/E,OAAO;AACL,WAAK,iFAAiF;AAAA,IACxF;AACA,YAAQ,IAAI;AACZ,SAAK,8BAA8BA,QAAM,KAAK,UAAU,WAAW,EAAE,CAAC,EAAE;AAAA,EAC1E;AACF;;;ACreA,OAAOK,aAAW;AAClB,OAAOC,WAAS;AAwBhB,eAAeC,gBAAe,UAA0C;AACtE,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAA0B,WAAW,QAAQ,EAAE;AACtE,WAAO,KAAK;AAAA,EACd,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,eAAc,GAAmB;AACxC,SAAO,MAAM,IAAIC,QAAM,IAAI,MAAM,IAAI,MAAM,IAAIA,QAAM,IAAI,KAAK,IAAIA,QAAM,OAAO,KAAK;AACtF;AAEA,SAAS,YAAY,GAAmB;AACtC,QAAM,MAA8B;AAAA,IAClC,aAAaA,QAAM,KAAK,aAAa;AAAA,IACrC,MAAMA,QAAM,MAAM,OAAO;AAAA,IACzB,SAASA,QAAM,IAAI,SAAS;AAAA,IAC5B,MAAMA,QAAM,KAAK,MAAM;AAAA,EACzB;AACA,SAAO,IAAI,CAAC,KAAK;AACnB;AAMA,eAAsB,kBACpB,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAUC,MAAI,EAAE,MAAM,+BAA0B,UAAU,KAAK,CAAC;AACtE,UAAQ,MAAM;AAEd,QAAM,UAAU,MAAMH,gBAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,YAAQ,KAAK,UAAU,KAAK,KAAK,cAAc;AAC/C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAA8B,mBAAmB;AAAA,MACtE,UAAU;AAAA,IACZ,CAAC;AAED,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,OAAO,KAAK,MAAM,CAAC;AAC1C;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,MAAM,QAAQ;AACtB,WAAK,aAAa,KAAK,KAAK,YAAY;AACxC;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS;AAAA,MACpCC,eAAc,KAAK,QAAQ;AAAA,MAC3B,YAAY,KAAK,MAAM;AAAA,MACvB,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,MAAM,GAAG,EAAE,IAAI,WAAM,KAAK;AAAA,MAC9D,KAAK,oBAAoB,IAAI,KAAK,iBAAiB,QAAQ;AAAA,MAC3D,KAAK,GAAG,MAAM,GAAG,CAAC;AAAA,IACpB,CAAC;AAED,YAAQ,IAAIC,QAAM,KAAK;AAAA,UAAa,KAAK,KAAK;AAAA,CAAI,CAAC;AACnD,UAAM,CAAC,OAAO,UAAU,SAAS,OAAO,IAAI,GAAG,IAAI;AAAA,EACrD,SAAS,KAAK;AACZ,YAAQ,KAAK,wBAAwB;AACrC,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,iBACpB,OACA,MAQe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAU,MAAMF,gBAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,KAAK,KAAK,cAAc;AACxC,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAAqC,gBAAgB;AAAA,MAC1E,UAAU;AAAA,MACV,KAAK;AAAA,QACH;AAAA,UACE;AAAA,UACA,aAAa,KAAK;AAAA,UAClB,UAAU,KAAK,WAAW,OAAO,KAAK,QAAQ,IAAI;AAAA,UAClD,QAAQ,KAAK,UAAU;AAAA,UACvB,mBAAmB,KAAK,WAAW,OAAO,KAAK,QAAQ,IAAI;AAAA,UAC3D,aAAa,KAAK;AAAA,UAClB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,IAC5C,OAAO;AACL,cAAQ,UAAU,KAAK,QAAQ,KAAK,KAAK,WAAW;AAAA,IACtD;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBACpB,WACA,QACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,gBAAgB,CAAC,WAAW,QAAQ,eAAe,MAAM;AAC/D,MAAI,CAAC,cAAc,SAAS,MAAM,GAAG;AACnC,UAAM,mBAAmB,MAAM,sBAAsB,cAAc,KAAK,IAAI,CAAC,EAAE;AAC/E,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,MAAMA,gBAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,KAAK,KAAK,cAAc;AACxC,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB,KAAK,SAAS;AAC7C,QAAM,SAAkC;AAAA,IACtC;AAAA,IACA,OAAO,KAAK;AAAA,EACd;AACA,MAAI,QAAQ;AACV,WAAO,KAAK;AAAA,EACd,OAAO;AACL,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAAuC,gBAAgB;AAAA,MAC5E,UAAU;AAAA,MACV,QAAQ,CAAC,MAAM;AAAA,IACjB,CAAC;AAED,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,SAAS,KAAK,QAAQ,CAAC;AAAA,IAChD,WAAW,KAAK,UAAU,GAAG;AAC3B,cAAQ,UAAU,SAAS,YAAO,MAAM,GAAG;AAAA,IAC7C,OAAO;AACL,YAAM,SAAS,SAAS,cAAc;AACtC,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,oBACpB,WACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAU,MAAMA,gBAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,KAAK,KAAK,cAAc;AACxC,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,IAAI,KAA8B,mBAAmB;AAAA,MACjE,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB,KAAK,SAAS;AAC7C,QAAM,QAAQ,MAAM,MAAM;AAAA,IACxB,CAAC,MAAO,UAAU,EAAE,OAAO,aAAc,EAAE,UAAU;AAAA,EACvD;AAEA,MAAI,CAAC,OAAO;AACV,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,SAAS,SAAS,eAAe,CAAC;AAAA,IACnE,OAAO;AACL,YAAM,SAAS,SAAS,cAAc;AAAA,IACxC;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAAuC,gBAAgB;AAAA,MAC5E,UAAU;AAAA,MACV,QAAQ;AAAA,QACN;AAAA,UACE,IAAI,MAAM;AAAA,UACV,QAAQ,MAAM;AAAA,UACd,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,SAAS,KAAK,QAAQ,CAAC;AAAA,IAChD,OAAO;AACL,cAAQ,YAAY,MAAM,KAAK,IAAI;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBACpB,WACA,MACe;AACf,QAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;AACf,QAAM,OAAO,WAAW;AAExB,QAAM,UAAU,MAAMA,gBAAe,KAAK,KAAK;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,UAAU,KAAK,KAAK,cAAc;AACxC,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB,KAAK,SAAS;AAC7C,QAAM,SAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,EACd;AACA,MAAI,QAAQ;AACV,WAAO,KAAK;AAAA,EACd,OAAO;AACL,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,KAAuC,gBAAgB;AAAA,MAC5E,UAAU;AAAA,MACV,QAAQ,CAAC,MAAM;AAAA,IACjB,CAAC;AAED,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,SAAS,KAAK,QAAQ,CAAC;AAAA,IAChD,WAAW,KAAK,UAAU,GAAG;AAC3B,cAAQ,WAAW,SAAS,YAAY;AAAA,IAC1C,OAAO;AACL,YAAM,SAAS,SAAS,cAAc;AACtC,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,IACzD,OAAO;AACL,YAAO,IAAc,OAAO;AAAA,IAC9B;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;;;AC/VO,IAAM,qBAAiD;EAC5D;IACE,MAAM;IACN,OAAO;IACP,iBAAiB;IACjB,SAAS;IACT,MAAM,CAAC,MAAM,kBAAkB;IAC/B,MAAM;;EAER;IACE,MAAM;IACN,OAAO;IACP,SAAS;IACT,MAAM,CAAC,KAAK;IACZ,MAAM;;EAER;IACE,MAAM;IACN,OAAO;IACP,iBAAiB;IACjB,SAAS;IACT,MAAM,CAAC,MAAM,WAAW;IACxB,MAAM;;;AAIV,IAAM,WAAW,IAAI,IACnB,mBAAmB,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAGtC,SAAU,YAAY,MAAY;AACtC,SAAO,SAAS,IAAI,IAAI;AAC1B;;;ACtCA,SAAS,SAAAI,cAAa;AAsDtB,SAAS,oBAAoB,WAAiB;AAC5C,QAAM,UAAU,YAAY,SAAS;AACrC,MAAI,SAAS;AACX,WAAO;MACL,SAAS;MACT,MAAM,CAAC,QAAQ,IAAI;;EAEvB;AAEA,SAAO;IACL,SAAS;IACT,MAAM,CAAC,WAAW,SAAS;;AAE/B;AAKA,eAAsB,QACpB,MACA,UAA8C,CAAA,GAAE;AAEhD,SAAO,IAAI,QAAQ,CAACC,aAAW;AAC7B,UAAM,QAAQC,OAAM,QAAQ,MAAM;MAChC,KAAK,QAAQ;MACb,OAAO,CAAC,QAAQ,QAAQ,MAAM;MAC9B,KAAK,EAAE,GAAG,QAAQ,IAAG;KACtB;AAED,QAAI,SAAS;AACb,QAAI,SAAS;AACb,UAAM,SAAqB,CAAA;AAE3B,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAgB;AACxC,YAAM,QAAQ,KAAK,SAAQ;AAC3B,gBAAU;AAEV,iBAAW,QAAQ,MAAM,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACpD,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cAAI,OAAO,iBAAiB,GAAG;AAC7B,mBAAO,KAAK,MAAM;UACpB;QACF,QAAQ;QAER;MACF;IACF,CAAC;AAED,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAgB;AACxC,gBAAU,KAAK,SAAQ;IACzB,CAAC;AAED,UAAM,QAAQ,QAAQ,UAClB,WAAW,MAAM,MAAM,KAAK,SAAS,GAAG,QAAQ,UAAU,GAAI,IAC9D;AAEJ,UAAM,GAAG,SAAS,CAAC,SAAQ;AACzB,UAAI;AAAO,qBAAa,KAAK;AAC7B,MAAAD,SAAQ,EAAE,UAAU,QAAQ,GAAG,QAAQ,QAAQ,OAAM,CAAE;IACzD,CAAC;EACH,CAAC;AACH;AAKA,eAAsB,gBAAgB,MAAqB;AACzD,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoB,KAAK,KAAK;AACzE,QAAM,OAAO,CAAC,GAAG,WAAW,YAAY,QAAQ;AAEhD,MAAI,KAAK;AAAa,SAAK,KAAK,MAAM,KAAK,WAAW;AACtD,MAAI,KAAK;AAAY,SAAK,QAAQ,eAAe;AACjD,MAAI,KAAK,QAAQ;AAAW,SAAK,QAAQ,SAAS,OAAO,KAAK,GAAG,CAAC;AAElE,OAAK,QAAQ,YAAY,MAAM;AAE/B,SAAO,QAAQ,MAAM,EAAE,KAAK,KAAK,IAAG,CAAE;AACxC;AAKA,eAAsB,UAAU,MAAsB;AACpD,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoB,KAAK,KAAK;AACzE,QAAM,OAAO,CAAC,GAAG,WAAW,UAAU,KAAK,MAAM;AAEjD,MAAI,KAAK;AAAa,SAAK,KAAK,MAAM,KAAK,WAAW;AACtD,MAAI,KAAK;AAAQ,SAAK,KAAK,WAAW;AACtC,MAAI,KAAK;AAAQ,SAAK,QAAQ,YAAY,KAAK,MAAM;AACrD,MAAI,KAAK;AAAS,SAAK,QAAQ,aAAa,OAAO,KAAK,OAAO,CAAC;AAEhE,SAAO,QAAQ,MAAM,EAAE,KAAK,KAAK,KAAK,SAAS,KAAK,QAAO,CAAE;AAC/D;AAKA,eAAsB,QACpBE,QACA,QACA,UAA+D,CAAA,GAAE;AAEjE,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoBA,MAAK;AACpE,QAAM,OAAO,CAAC,GAAG,WAAW,QAAQ,MAAM;AAE1C,MAAI,QAAQ;AAAQ,SAAK,QAAQ,YAAY,QAAQ,MAAM;AAC3D,MAAI,QAAQ;AAAS,SAAK,QAAQ,aAAa,OAAO,QAAQ,OAAO,CAAC;AAEtE,SAAO,QAAQ,MAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAO,CAAE;AACrE;AAKA,eAAsB,gBACpBA,QACA,UAA4B,CAAA,GAAE;AAE9B,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoBA,MAAK;AACpE,QAAM,OAAO,CAAC,GAAG,WAAW,YAAY,QAAQ,YAAY,MAAM;AAElE,SAAO,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAG,CAAE;AAC3C;AAKA,eAAsB,UACpBA,QACA,UAAkD,CAAA,GAAE;AAEpD,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoBA,MAAK;AACpE,QAAM,OAAO,CAAC,GAAG,WAAW,QAAQ;AAEpC,MAAI,QAAQ;AAAa,SAAK,KAAK,MAAM,QAAQ,WAAW;AAE5D,SAAO,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAG,CAAE;AAC3C;AAKA,eAAsB,gBACpBA,QACA,UAAkD,CAAA,GAAE;AAEpD,QAAM,EAAE,SAAS,MAAM,MAAM,UAAS,IAAK,oBAAoBA,MAAK;AACpE,QAAM,OAAO,CAAC,GAAG,WAAW,YAAY,OAAO;AAE/C,MAAI,QAAQ;AAAa,SAAK,KAAK,QAAQ,WAAW;AAEtD,SAAO,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAG,CAAE;AAC3C;;;AChMA,eAAsB,iBACpBC,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AACtD,QAAM,cAAc,WAAW;AAC/B,QAAM,aAAa,QAAQ,WAAW,UAAU;AAChD,QAAM,MAAM,WAAW,QAAQ,SAAY,OAAO,WAAW,GAAG,IAAI;AAEpE,OAAK,6BAA6BA,MAAK,MAAM;AAE7C,QAAM,SAAS,MAAM,gBAAgB;AAAA,IACnC,OAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,4BAA4B,OAAO,UAAU,eAAe,EAAE;AACpE,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,MAAI,WAAW,GAAG;AAChB,YAAQ,OAAO,MAAM,OAAO,MAAM;AAAA,EACpC,OAAO;AACL,YAAQ,4BAA4BA,MAAK,GAAG;AAC5C,QAAI,YAAa,MAAK,iBAAiB,WAAW,EAAE;AACpD,SAAK,sBAAsB,GAAG,EAAE;AAAA,EAClC;AACF;AAMA,eAAsB,kBACpBA,QACA,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AACtD,QAAM,cAAc,WAAW;AAC/B,QAAM,SAAU,WAAW,UAAqB;AAChD,QAAM,SAAS,QAAQ,WAAW,MAAM;AACxC,QAAM,UAAU,WAAW,YAAY,SAAY,OAAO,WAAW,OAAO,IAAI;AAEhF,MAAI,CAAC,WAAW,EAAG,MAAK,sBAAsBA,MAAK,MAAM;AAEzD,QAAM,SAAS,MAAM,UAAU;AAAA,IAC7B,OAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,UAAQ,OAAO,MAAM,OAAO,MAAM;AAClC,MAAI,OAAO,OAAQ,SAAQ,OAAO,MAAM,OAAO,MAAM;AACrD,UAAQ,WAAW,OAAO;AAC5B;AAMA,eAAsB,gBACpBA,QACA,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AACtD,QAAM,SAAU,WAAW,UAAqB;AAChD,QAAM,UAAU,WAAW,YAAY,SAAY,OAAO,WAAW,OAAO,IAAI;AAEhF,MAAI,CAAC,WAAW,EAAG,MAAK,+BAA+BA,MAAK,MAAM;AAElE,QAAM,SAAS,MAAM,QAAQA,QAAO,QAAQ,EAAE,KAAK,QAAQ,QAAQ,CAAC;AAEpE,UAAQ,OAAO,MAAM,OAAO,MAAM;AAClC,MAAI,OAAO,OAAQ,SAAQ,OAAO,MAAM,OAAO,MAAM;AACrD,UAAQ,WAAW,OAAO;AAC5B;AAMA,eAAsB,wBACpBA,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AAEtD,QAAM,SAAS,MAAM,gBAAgBA,QAAO,EAAE,IAAI,CAAC;AAEnD,MAAI,WAAW,GAAG;AAChB,YAAQ,OAAO,MAAM,OAAO,MAAM;AAAA,EACpC,OAAO;AACL,QAAI,OAAO,aAAa,GAAG;AACzB,YAAM,4BAA4B,OAAO,UAAU,eAAe,EAAE;AACpE,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,OAAO,MAAM;AACzC,UAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAAG;AAClD,aAAK,wBAAwBA,MAAK,IAAI;AACtC,gBAAQ,OAAO,MAAM,OAAO,MAAM;AAAA,MACpC,OAAO;AACL,aAAK,2BAA2BA,MAAK,IAAI;AAAA,MAC3C;AAAA,IACF,QAAQ;AACN,cAAQ,OAAO,MAAM,OAAO,MAAM;AAAA,IACpC;AAAA,EACF;AACF;AAMA,eAAsB,kBACpBA,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AACtD,QAAM,cAAc,WAAW;AAE/B,OAAK,sBAAsBA,MAAK,MAAM;AAEtC,QAAM,SAAS,MAAM,UAAUA,QAAO,EAAE,KAAK,YAAY,CAAC;AAE1D,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,kBAAkB,OAAO,UAAU,eAAe,EAAE;AAC1D,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,UAAQ,4BAA4B;AACtC;AAMA,eAAsB,iBACpBA,QACA,OACA,KACe;AACf,QAAM,aAAa,IAAI,OAAO,KAAK;AACnC,QAAM,MAAO,WAAW,OAAkB,QAAQ,IAAI;AACtD,QAAM,cAAc,WAAW;AAE/B,OAAK,4BAA4BA,MAAK,MAAM;AAE5C,QAAM,SAAS,MAAM,gBAAgBA,QAAO,EAAE,KAAK,YAAY,CAAC;AAEhE,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,iBAAiB,OAAO,UAAU,eAAe,EAAE;AACzD,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,UAAQ,sDAAiD;AAC3D;;;ACpMA,SAAS,cAAc,gBAAgB;AACvC,SAAS,cAAAC,cAAY,gBAAAC,qBAAoB;AACzC,OAAOC,aAAW;AAClB,OAAOC,WAAS;AAOhB,IAAM,aAAa,OAAyC,YAAkB;AAY9E,eAAsB,qBAAkD;AACtE,QAAMC,QAAO,QAAQ;AACrB,MAAI,CAACA,MAAM,QAAO;AAElB,MAAI;AACF,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,GAAK;AAC1D,YAAQ,MAAM;AAEd,UAAM,MAAM,MAAM,MAAM,GAAGA,KAAI,gBAAgB;AAAA,MAC7C,QAAQ,WAAW;AAAA,IACrB,CAAC;AAED,iBAAa,OAAO;AAEpB,QAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,eAAe,OAAe,QAAyB;AAC9D,MAAI,UAAU,MAAO,QAAO;AAE5B,QAAMC,SAAQ,CAAC,MAAc,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACtE,QAAM,SAASA,OAAM,KAAK;AAC1B,QAAM,SAASA,OAAM,MAAM;AAC3B,QAAM,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO,OAAO,CAAC,KAAK;AACxE,QAAM,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO,OAAO,CAAC,KAAK;AAExE,MAAI,SAAS,KAAM,QAAO,OAAO;AACjC,MAAI,SAAS,KAAM,QAAO,OAAO;AACjC,SAAO,OAAO;AAChB;AAiBO,SAAS,WAAW,KAAsB;AAC/C,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,OAAO,EAAG,QAAO;AAC/C,MAAI;AACF,YAAQ,KAAK,KAAK,CAAC;AACnB,WAAO;AAAA,EACT,SAAS,KAAK;AAKZ,WAAQ,IAA8B,SAAS;AAAA,EACjD;AACF;AAEA,SAAS,uBAA8E;AACrF,MAAI,aAA4B;AAChC,MAAI;AACF,UAAM,MAAM,SAAS,wDAAwD,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK;AAMzG,UAAM,SAAS,OAAO,QAAQ,GAAG;AACjC,UAAM,OAAO,IACV,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,KAAK,MAAM,MAAM,EAC/B,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,CAAC,CAAC;AACtC,iBAAa,KAAK,CAAC,KAAK;AAAA,EAC1B,QAAQ;AAAA,EAA2B;AAEnC,QAAM,eAAyB,CAAC;AAChC,MAAI;AACF,UAAM,WAAW,SAAS,+BAA+B,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK;AACrF,QAAI,UAAU;AACZ,iBAAW,QAAQ,SAAS,MAAM,IAAI,GAAG;AAEvC,YAAI,KAAK,MAAM,iBAAiB,GAAG;AACjC,gBAAM,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC;AAC9B,cAAI,KAAM,cAAa,KAAK,IAAI;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAA0C;AAElD,SAAO,EAAE,YAAY,aAAa;AACpC;AAYA,SAAS,sBAAsC;AAC7C,MAAI;AACF,UAAM,WAAWC,cAAa,QAAQ,KAAK,CAAC,KAAK,EAAE;AAGnD,QAAI,oBAAoB,KAAK,QAAQ,GAAG;AACtC,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAAqB;AAC7B,SAAO;AACT;AAOA,SAAS,cAAc,SAAuB;AAC5C,QAAM,SAAS,oBAAoB;AACnC,MAAI,WAAW,QAAQ;AACrB,QAAI;AACF,mBAAa,QAAQ,CAAC,WAAW,wBAAwB,GAAG,EAAE,OAAO,UAAU,CAAC;AAChF;AAAA,IACF,SAAS,KAAK;AAIZ,YAAM,SAAS,OAAO,QAAQ,WAAW,cAAc,QAAQ,OAAO,MAAM;AAC5E,UAAI,CAAC,OAAQ,OAAM;AACnB,YAAM,cAAc,gBAAgB;AACpC,UAAI,CAAC,YAAa,OAAM;AACxB,mBAAa,QAAQ;AAAA,QACnB;AAAA,QAAM;AAAA,QACN;AAAA,QACA;AAAA,QAAQ;AAAA,QACR;AAAA,MACF,GAAG,EAAE,OAAO,UAAU,CAAC;AAAA,IACzB;AACA;AAAA,EACF;AAOA,eAAa,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,IACA,2BAA2B,OAAO;AAAA,IAClC;AAAA,EACF,GAAG,EAAE,OAAO,UAAU,CAAC;AACzB;AAEA,SAAS,kBAAiC;AACxC,aAAW,UAAU,CAAC,8BAA8B,iBAAiB,YAAY,GAAG;AAClF,UAAM,SAAS,GAAG,MAAM;AACxB,QAAI,CAACC,aAAW,MAAM,EAAG;AACzB,QAAI;AACF,aAAO,SAAS,eAAe,MAAM,iCAAiC,MAAM,KAAK,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK,KAAK;AAAA,IACpH,QAAQ;AAAA,IAAiB;AAAA,EAC3B;AACA,SAAO;AACT;AAKA,eAAsB,cAAc,OAA4B,CAAC,GAAkB;AACjF,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,MAAI,EAAE,MAAM,8BAAyB,UAAU,KAAK,CAAC;AACrE,UAAQ,MAAM;AAEd,QAAM,cAAc,MAAM,mBAAmB;AAE7C,MAAI,CAAC,aAAa;AAChB,YAAQ,KAAK;AACb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,OAAO,OAAO,2CAA2C,CAAC;AAAA,IAC7E,OAAO;AACL,WAAK,+FAA+F;AAAA,IACtG;AACA,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,kBAAkB,eAAe,YAAY,YAAY,MAAM;AAErE,MAAI,CAAC,iBAAiB;AACpB,YAAQ,KAAK;AACb,QAAI,MAAM;AACR,iBAAW,EAAE,IAAI,MAAM,SAAS,YAAY,QAAQ,YAAY,QAAQ,kBAAkB,MAAM,CAAC;AAAA,IACnG,OAAO;AACL,cAAQ,iCAAiCC,QAAM,KAAK,UAAU,CAAC,GAAG;AAAA,IACpE;AACA;AAAA,EACF;AAEA,UAAQ,KAAK;AAEb,MAAI,CAAC,MAAM;AACT,SAAK,qBAAqBA,QAAM,IAAI,UAAU,CAAC,WAAMA,QAAM,KAAK,MAAM,YAAY,MAAM,CAAC,EAAE;AAC3F,QAAI,YAAY,eAAe;AAC7B,WAAK,cAAc,YAAY,aAAa,EAAE;AAAA,IAChD;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,OAAO;AACf,UAAM,EAAE,YAAY,aAAa,IAAI,qBAAqB;AAE1D,QAAI,cAAc,aAAa,SAAS,GAAG;AACzC,UAAI,CAAC,MAAM;AACT,aAAK,4BAA4B;AACjC,YAAI,YAAY;AACd,kBAAQ,MAAMA,QAAM,OAAO,yCAAoC,UAAU,GAAG,CAAC;AAAA,QAC/E;AACA,YAAI,aAAa,SAAS,GAAG;AAC3B,kBAAQ,MAAMA,QAAM,OAAO,YAAO,aAAa,MAAM,6BAA6B,aAAa,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,QAC9G;AACA,gBAAQ,MAAM;AACd,aAAK,yFAAyF;AAC9F,aAAK,6DAA6D;AAClE,gBAAQ,MAAM;AACd,aAAK,OAAOA,QAAM,KAAK,oBAAoB,CAAC,8CAA8C;AAAA,MAC5F,OAAO;AACL,mBAAW;AAAA,UACT,IAAI;AAAA,UACJ,SAAS;AAAA,UACT,QAAQ,YAAY;AAAA,UACpB,kBAAkB;AAAA,UAClB,SAAS;AAAA,UACT,SAAS;AAAA,UACT,iBAAiB,CAAC,CAAC;AAAA,UACnB,iBAAiB;AAAA,UACjB,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgBD,MAAI,EAAE,MAAM,2BAAsB,UAAU,KAAK,CAAC;AACxE,gBAAc,MAAM;AAEpB,MAAI;AACF,kBAAc,YAAY,MAAM;AAChC,kBAAc,KAAK;AACnB,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,QAAQ,YAAY;AAAA,QACpB,kBAAkB;AAAA,QAClB,SAAS;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,cAAcC,QAAM,KAAK,YAAY,MAAM,CAAC,EAAE;AACtD,WAAK,8CAA8CA,QAAM,KAAK,uCAAuC,CAAC,EAAE;AAAA,IAC1G;AAAA,EACF,SAAS,KAAK;AACZ,kBAAc,KAAK,eAAe;AAClC,QAAI,MAAM;AACR,iBAAW;AAAA,QACT,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,QAAQ,YAAY;AAAA,QACpB,kBAAkB;AAAA,QAClB,SAAS;AAAA,QACT,OAAQ,IAAc;AAAA,MACxB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,6BAA8B,IAAc,OAAO,EAAE;AAC3D,YAAM,SAAS,oBAAoB;AACnC,UAAI,WAAW,QAAQ;AACrB,aAAK,mEAAmE;AAAA,MAC1E,OAAO;AACL,aAAK,6EAA6E,YAAY,MAAM,EAAE;AAAA,MACxG;AAAA,IACF;AACA,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,0BAAyC;AAC7D,MAAI;AACF,UAAM,cAAc,MAAM,mBAAmB;AAC7C,QAAI,CAAC,YAAa;AAElB,QAAI,eAAe,YAAY,YAAY,MAAM,GAAG;AAClD,cAAQ;AAAA,QACNA,QAAM,OAAO;AAAA,sBAAyB,UAAU,WAAM,YAAY,MAAM,SAASA,QAAM,KAAK,YAAY,CAAC,cAAc,IACrHA,QAAM,IAAI,iDAAiD;AAAA,MAC/D;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;ACpVA,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,cAAY;;;ACDrB,SAAS,eAAAC,cAAa,gBAAAC,eAAc,YAAAC,iBAAgB;AACpD,SAAS,QAAAC,cAAY;AA0ErB,SAAS,iBAAiB,SAA2C;AAEnE,QAAM,QAAQ,QAAQ,MAAM,6BAA6B;AACzD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,MAAyB,CAAC;AAChC,QAAM,QAAQ,MAAM,CAAC,EAAG,MAAM,OAAO;AACrC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAKpB,UAAM,IAAI,KAAK,MAAM,mCAAmC;AACxD,QAAI,CAAC,EAAG;AACR,UAAM,CAAC,EAAE,KAAK,QAAQ,IAAI;AAC1B,UAAM,UAAU,SAAS,KAAK;AAO9B,QAAI,QAAQ,WAAW,YAAY,IAAI;AACrC,YAAM,QAAkB,CAAC;AACzB,UAAI,IAAI,IAAI;AACZ,aAAO,IAAI,MAAM,QAAQ;AACvB,cAAM,UAAU,MAAM,CAAC;AACvB,cAAM,YAAY,QAAQ,MAAM,qBAAqB;AACrD,YAAI,CAAC,UAAW;AAEhB,cAAM,KAAK,UAAU,CAAC,EAAG,QAAQ,kBAAkB,IAAI,CAAC;AACxD;AAAA,MACF;AACA,UAAI,MAAM,SAAS,GAAG;AACpB,YAAI,QAAQ,MAAM,KAAK,IAAI;AAC3B,YAAI,IAAI;AACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAgBA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,UAAU,KAAK,KAAK,EAAG,QAAO;AAElC,MAAI,KAAK,KAAK,KAAK,EAAG,QAAO;AAC7B,MAAI,iBAAiB,KAAK,KAAK,EAAG,QAAO;AACzC,SAAO;AACT;AAaA,SAAS,kBAAkB,KAAa,QAAQ,GAAa;AAC3D,MAAI,QAAQ,EAAG,QAAO,CAAC;AACvB,MAAI;AACJ,MAAI;AACF,cAAUH,aAAY,GAAG;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,MAAgB,CAAC;AACvB,QAAM,cAAc,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,UAAU;AACtE,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAOG,OAAK,KAAK,KAAK;AAC5B,QAAI;AACJ,QAAI;AACF,UAAID,UAAS,IAAI;AAAA,IACnB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,EAAE,YAAY,GAAG;AACnB,UAAI,KAAK,GAAG,kBAAkB,MAAM,QAAQ,CAAC,CAAC;AAAA,IAChD,WAAW,EAAE,OAAO,KAAK,eAAe,MAAM,SAAS,KAAK,GAAG;AAC7D,UAAI,KAAK,IAAI;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;AASO,SAAS,yBAAyB,UAAuC;AAC9E,QAAM,WAA8B,CAAC;AACrC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,UAAU;AAC3B,eAAW,QAAQ,kBAAkB,IAAI,GAAG;AAC1C,UAAI,KAAK,IAAI,IAAI,EAAG;AACpB,WAAK,IAAI,IAAI;AACb,UAAI;AACJ,UAAI;AACF,kBAAUD,cAAa,MAAM,OAAO;AAAA,MACtC,QAAQ;AACN;AAAA,MACF;AACA,YAAM,KAAK,iBAAiB,OAAO;AACnC,UAAI,CAAC,MAAM,OAAO,GAAG,UAAU,SAAU;AACzC,UAAI,CAAC,gBAAgB,GAAG,KAAK,EAAG;AAChC,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,MAAM,GAAG,QAAQ;AAAA,QACjB,OAAO,GAAG;AAAA,QACV,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,cAAc,GAA4B;AAGxD,SAAO,8CAA8C,EAAE,IAAI,SAAS,EAAE,IAAI,WAAW,EAAE,MAAM,UAAU,KAAK,UAAU,EAAE,KAAK,CAAC;AAChI;;;ADlMA,SAAS,eAAyB;AAChC,QAAM,OAAOG,SAAQ;AACrB,SAAO;AAAA,IACLC,OAAK,MAAM,WAAW,QAAQ;AAAA,IAC9BA,OAAK,MAAM,WAAW,SAAS;AAAA,IAC/BA,OAAK,QAAQ,IAAI,GAAG,WAAW,QAAQ;AAAA,EACzC;AACF;AAEA,eAAsB,sBAAsB,UAAwB,CAAC,GAAkB;AACrF,QAAM,QAAQ,aAAa;AAC3B,QAAM,WAAW,yBAAyB,KAAK;AAE/C,MAAI,QAAQ,MAAM;AAChB,YAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,UAAU,MAAM,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAC1E,WAAW,SAAS,WAAW,GAAG;AAChC,YAAQ,OAAO,MAAM,8JAAyJ;AAAA,EAChL,OAAO;AACL,YAAQ,OAAO,MAAM,SAAS,SAAS,MAAM,aAAa,SAAS,WAAW,IAAI,KAAK,GAAG;AAAA;AAAA,CAA6C;AACvI,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,YAAO,EAAE,IAAI,MAAM,EAAE,IAAI;AAAA,CAAK;AACnD,cAAQ,OAAO,MAAM,cAAc,EAAE,KAAK;AAAA,CAAI;AAAA,IAChD;AACA,YAAQ,OAAO;AAAA,MACb;AAAA,IAGF;AAEA,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,GAAG,cAAc,CAAC,CAAC;AAAA,CAAI;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,QAAQ,UAAU,SAAS,SAAS,GAAG;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AEpEA,SAAS,eAAAC,cAAa,gBAAAC,gBAAc,YAAAC,iBAAgB;AACpD,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,cAAY;AA+CrB,SAAS,iBAAiB,WAA2B;AACnD,SAAO,QAAQ,UAAU,QAAQ,MAAM,GAAG,CAAC;AAC7C;AAUO,SAAS,+BAA+B,SAAkC;AAC/E,QAAM,YAAY,QAAQ,MAAM,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,CAAC;AACxE,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,QAAQ,UAAU,QAAQ,cAAc,EAAE,EAAE,KAAK;AACvD,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,SAAO,MACJ,MAAM,SAAS,EACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC;AACxC;AAQA,SAAS,kBAAkB,aAAsC;AAC/D,MAAI;AACF,UAAM,SAAS,KAAK,MAAMH,eAAa,aAAa,OAAO,CAAC;AAG5D,WAAO,OAAO,KAAK,OAAO,cAAc,CAAC,CAAC;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAWO,SAAS,wBACd,UAAkBG,OAAKD,SAAQ,GAAG,YAAY,GACxB;AACtB,QAAM,WAAiC,CAAC;AAExC,MAAI;AACJ,MAAI;AACF,cAAUH,aAAY,OAAO;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,WAAWI,OAAK,SAAS,KAAK;AACpC,QAAI;AACJ,QAAI;AACF,UAAIF,UAAS,QAAQ;AAAA,IACvB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,EAAE,YAAY,KAAK,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,EAAG;AAOxE,eAAW,SAAS,CAAC,aAAa,SAAS,GAAY;AACrD,YAAM,cAAc,UAAU,cAC1BE,OAAK,UAAU,aAAa,WAAW,IACvCA,OAAK,UAAU,WAAW,WAAW;AACzC,YAAM,OAAO,kBAAkB,WAAW;AAC1C,UAAI,SAAS,QAAQ,KAAK,WAAW,EAAG;AACxC,YAAM,WAAW,IAAI,IAAI,KAAK,IAAI,gBAAgB,CAAC;AAEnD,iBAAW,YAAY,CAAC,2BAA2B,kBAAkB,GAAY;AAC/E,cAAM,SAAS,UAAU,cACrBA,OAAK,UAAU,WAAW,UAAU,GAAG,QAAQ,KAAK,IACpDA,OAAK,UAAU,WAAW,WAAW,UAAU,GAAG,QAAQ,KAAK;AACnE,YAAI;AACJ,YAAI;AACF,oBAAUH,eAAa,QAAQ,OAAO;AAAA,QACxC,QAAQ;AACN;AAAA,QACF;AACA,cAAM,WAAW,+BAA+B,OAAO;AACvD,YAAI,aAAa,KAAM;AACvB,cAAM,cAAc,IAAI,IAAI,QAAQ;AACpC,cAAM,UAAU,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;AAC/D,YAAI,QAAQ,SAAS,GAAG;AACtB,mBAAS,KAAK,EAAE,OAAO,OAAO,UAAU,OAAO,SAAS,MAAM,OAAO,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,yBAAyB,GAA+B;AACtE,SAAO,6CAA6C,EAAE,KAAK,aAAa,EAAE,QAAQ,UAAU,EAAE,KAAK,YAAY,KAAK,UAAU,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI;AACzJ;;;AC1IA,eAAsB,sBAAsB,UAAwB,CAAC,GAAkB;AACrF,QAAM,WAAW,wBAAwB;AAEzC,MAAI,QAAQ,MAAM;AAChB,YAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EACnE,WAAW,SAAS,WAAW,GAAG;AAChC,YAAQ,OAAO;AAAA,MACb;AAAA,IACF;AAAA,EACF,OAAO;AACL,YAAQ,OAAO;AAAA,MACb,SAAS,SAAS,MAAM,sBAAsB,SAAS,WAAW,IAAI,KAAK,GAAG;AAAA;AAAA;AAAA,IAChF;AACA,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,YAAO,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,QAAQ;AAAA,CAAO;AACnE,cAAQ,OAAO,MAAM,gBAAgB,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,CAAI;AAC7D,cAAQ,OAAO,MAAM,gBAAgB,EAAE,IAAI;AAAA,CAAI;AAAA,IACjD;AACA,YAAQ,OAAO;AAAA,MACb;AAAA,IAKF;AACA,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,GAAG,yBAAyB,CAAC,CAAC;AAAA,CAAI;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,QAAQ,UAAU,SAAS,SAAS,GAAG;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AC3DA,SAAS,WAAAI,gBAAe;AACxB,SAAS,QAAAC,cAAY;;;ACDrB,SAAS,eAAAC,cAAa,gBAAAC,gBAAc,YAAAC,iBAAgB;AACpD,SAAS,QAAAC,cAAY;AA+Bd,IAAM,qBAAqB;AAMlC,SAAS,YAAY,OAAwB;AAC3C,SAAO,MAAM,SAAS,IAAI;AAC5B;AAOA,SAAS,wBAAwB,OAAwB;AACvD,SAAO,wBAAwB,KAAK,CAAC,EAAE,GAAG,MAAM,GAAG,KAAK,KAAK,CAAC;AAChE;AA4BA,SAAS,gBAAgB,MAAuB;AAC9C,UAAQ,OAAO,QAAW;AAC5B;AAEA,SAAS,MAAM,MAAsB;AACnC,SAAO,KAAK,OAAO,KAAO,SAAS,CAAC,CAAC;AACvC;AAEA,SAAS,YACP,MACAC,QACA,UACM;AACN,MAAI,OAAsB;AAC1B,MAAI;AACF,WAAOC,UAAS,IAAI,EAAE;AAAA,EACxB,QAAQ;AACN;AAAA,EACF;AACA,MAAI,SAAS,QAAQ,gBAAgB,IAAI,GAAG;AAC1C,aAAS,KAAK,EAAE,MAAM,8BAA8B,MAAM,OAAAD,QAAO,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,EACtF;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAME,eAAa,MAAM,OAAO,CAAC;AAAA,EACjD,QAAQ;AACN;AAAA,EACF;AACA,QAAM,UAAW,QAAqD;AACtE,MAAI,OAAO,YAAY,YAAY,YAAY,KAAM;AAErD,aAAW,CAAC,QAAQ,GAAG,KAAK,OAAO,QAAQ,OAAO,GAAG;AACnD,QAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM;AAC7C,UAAM,QAAQ;AACd,UAAM,SAAyE;AAAA,MAC7E,CAAC,MAAM,KAAK,KAAK;AAAA,MACjB,CAAC,MAAM,SAAS,QAAQ;AAAA,IAC1B;AACA,eAAW,CAAC,OAAO,QAAQ,KAAK,QAAQ;AACtC,UAAI,CAAC,MAAO;AACZ,iBAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAClD,YAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAAG;AACrD,YAAI,YAAY,KAAK,EAAG;AAOxB,YAAI,CAAC,mBAAmB,KAAK,KAAK,KAAK,CAAC,wBAAwB,KAAK,EAAG;AACxE,iBAAS,KAAK,EAAE,MAAM,yBAAyB,MAAM,OAAAF,QAAO,QAAQ,OAAO,SAAS,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AACF;AAIA,SAAS,oBACP,MACAA,QACA,UACM;AACN,MAAI;AACJ,MAAI;AACF,WAAOC,UAAS,IAAI,EAAE;AAAA,EACxB,QAAQ;AACN;AAAA,EACF;AACA,MAAI,gBAAgB,IAAI,GAAG;AACzB,aAAS,KAAK,EAAE,MAAM,8BAA8B,MAAM,OAAAD,QAAO,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,EACtF;AACF;AAOO,SAAS,iBAAiB,eAA6C;AAC5E,QAAM,WAAiC,CAAC;AACxC,MAAI;AACJ,MAAI;AACF,aAASG,aAAY,aAAa;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,aAAWH,UAAS,QAAQ;AAC1B,UAAM,WAAWI,OAAK,eAAeJ,MAAK;AAC1C,QAAI;AACF,UAAI,CAACC,UAAS,QAAQ,EAAE,YAAY,EAAG;AAAA,IACzC,QAAQ;AACN;AAAA,IACF;AACA,gBAAYG,OAAK,UAAU,aAAa,WAAW,GAAGJ,QAAO,QAAQ;AACrE,gBAAYI,OAAK,UAAU,WAAW,WAAW,GAAGJ,QAAO,QAAQ;AACnE,wBAAoBI,OAAK,UAAU,mBAAmB,GAAGJ,QAAO,QAAQ;AAAA,EAC1E;AACA,SAAO;AACT;AAIO,SAAS,oBAAoB,GAA+B;AACjE,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,QAAQ,EAAE,IAAI;AAAA,IACd,SAAS,EAAE,KAAK;AAAA,IAChB,QAAQ,EAAE,IAAI;AAAA,EAChB;AACA,MAAI,EAAE,OAAQ,OAAM,KAAK,UAAU,EAAE,MAAM,EAAE;AAC7C,MAAI,EAAE,MAAO,OAAM,KAAK,SAAS,EAAE,KAAK,EAAE;AAC1C,MAAI,EAAE,SAAU,OAAM,KAAK,YAAY,EAAE,QAAQ,EAAE;AACnD,MAAI,EAAE,KAAM,OAAM,KAAK,QAAQ,EAAE,IAAI,EAAE;AACvC,SAAO,MAAM,KAAK,GAAG;AACvB;;;ADlKA,SAAS,SAAS,GAA+B;AAC/C,MAAI,EAAE,SAAS,yBAAyB;AACtC,WAAO,qBAAqB,EAAE,QAAQ,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM;AAAA,EAClF;AACA,SAAO,uBAAuB,EAAE,IAAI;AACtC;AAEA,eAAsB,oBAAoB,UAAwB,CAAC,GAAkB;AACnF,QAAM,OAAO,QAAQ,QAAQK,OAAKC,SAAQ,GAAG,YAAY;AACzD,QAAM,WAAW,iBAAiB,IAAI;AAEtC,MAAI,QAAQ,MAAM;AAChB,YAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,UAAU,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EACzE,WAAW,SAAS,WAAW,GAAG;AAChC,YAAQ,OAAO;AAAA,MACb,iEAAiE,IAAI;AAAA;AAAA,IACvE;AAAA,EACF,OAAO;AACL,YAAQ,OAAO;AAAA,MACb,SAAS,SAAS,MAAM,yBAAyB,SAAS,WAAW,IAAI,KAAK,GAAG,UAAU,IAAI;AAAA;AAAA;AAAA,IACjG;AACA,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,aAAQ,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,CAAI;AACxD,cAAQ,OAAO,MAAM,OAAO,EAAE,IAAI;AAAA,CAAI;AAAA,IACxC;AACA,YAAQ,OAAO;AAAA,MACb;AAAA,IAEF;AACA,eAAW,KAAK,UAAU;AACxB,cAAQ,OAAO,MAAM,GAAG,oBAAoB,CAAC,CAAC;AAAA,CAAI;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,QAAQ,UAAU,SAAS,SAAS,GAAG;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AEpEA,OAAOC,aAAW;AAClB,OAAOC,WAAS;AAmDhB,eAAsB,yBAAwC;AAC5D,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUC,MAAI,EAAE,MAAM,+BAA0B,UAAU,KAAK,CAAC,EAAE,MAAM;AAE9E,MAAI;AACF,UAAM,OAAO,MAAM,IAAI,IAA0B,wBAAwB;AACzE,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,cAAc,KAAK,CAAC;AACjC;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,sCAAsC;AAC3C;AAAA,IACF;AAEA,YAAQ,IAAIC,QAAM,KAAK,6BAA6B,CAAC;AACrD,eAAW,KAAK,MAAM;AACpB,YAAM,cAAc,EAAE,WAAW,cAAcA,QAAM,QAAQ,EAAE,WAAW,aAAaA,QAAM,OAAOA,QAAM;AAC1G,cAAQ;AAAA,QACN,KAAKA,QAAM,KAAK,EAAE,IAAI,CAAC,IAAIA,QAAM,IAAI,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,KAAKA,QAAM,IAAI,GAAG,EAAE,QAAQ,UAAU,CAAC,YAAY,EAAE,gBAAgB,UAAU,CAAC,SAAS,CAAC;AAAA,MACvL;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,uBAAuB,MAA6B;AACxE,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,8BAAyB,UAAU,KAAK,CAAC,EAAE,MAAM;AAE7E,MAAI;AAEF,UAAM,MAAM,MAAM,IAAI,IAAyB,wBAAwB;AACvE,UAAME,eAAc,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAEnD,QAAI,CAACA,cAAa;AAChB,cAAQ,KAAK;AACb,YAAM,gBAAgB,IAAI,cAAc;AACxC,cAAQ,WAAW;AACnB;AAAA,IACF;AAGA,UAAM,SAAS,MAAM,IAAI,IAMrB,0BAA0BA,aAAY,EAAE,SAAS;AAErD,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,aAAAA,cAAa,OAAO,CAAC;AAClC;AAAA,IACF;AAEA,YAAQ,IAAID,QAAM,KAAK;AAAA,EAAKC,aAAY,IAAI,EAAE,GAAGD,QAAM,IAAI,IAAIC,aAAY,IAAI,GAAG,CAAC;AACnF,QAAIA,aAAY,YAAa,SAAQ,IAAID,QAAM,IAAIC,aAAY,WAAW,CAAC;AAC3E,YAAQ,IAAI;AACZ,YAAQ,IAAI,gBAAgBA,aAAY,MAAM,KAAKA,aAAY,OAAO,EAAE;AACxE,YAAQ,IAAI,gBAAgBA,aAAY,QAAQ,EAAE;AAClD,YAAQ,IAAI,gBAAgBA,aAAY,kBAAkB,KAAK,IAAI,KAAK,MAAM,EAAE;AAChF,YAAQ,IAAI,gBAAgBA,aAAY,QAAQ,UAAU,CAAC,EAAE;AAE7D,QAAI,OAAO,SAAS,GAAG;AACrB,cAAQ,IAAID,QAAM,KAAK,0BAA0B,CAAC;AAClD,iBAAW,KAAK,QAAQ;AACtB,cAAM,YAAY,EAAE,YAAYA,QAAM,QAAQA,QAAM;AACpD,cAAM,cAAc,EAAE,gBAAgBA,QAAM,KAAK,kBAAkB,IAAI;AACvE,gBAAQ;AAAA,UACN,OAAOA,QAAM,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,UAAU,UAAU,EAAE,kBAAkB,CAAC,GAAG,WAAW,KAAK,EAAE,YAAYA,QAAM,MAAM,kBAAa,IAAIA,QAAM,IAAI,uBAAkB,CAAC;AAAA,QACxK;AAAA,MACF;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,0BACpB,MACA,SACe;AACf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,gCAA2B,UAAU,KAAK,CAAC,EAAE,MAAM;AAE/E,MAAI;AAEF,UAAM,MAAM,MAAM,IAAI,IAAyB,wBAAwB;AACvE,UAAME,eAAc,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACnD,QAAI,CAACA,cAAa;AAChB,cAAQ,KAAK;AACb,YAAM,gBAAgB,IAAI,cAAc;AACxC,cAAQ,WAAW;AACnB;AAAA,IACF;AAGA,UAAM,SAAS,MAAM,IAAI,IAAoD,SAAS;AACtF,UAAMC,SAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,cAAc,QAAQ,KAAK;AAC9D,QAAI,CAACA,QAAO;AACV,cAAQ,KAAK;AACb,YAAM,UAAU,QAAQ,KAAK,cAAc;AAC3C,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,QAAQ,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,KAAK,CAAC;AAEnF,UAAM,SAAS,MAAM,IAAI,KAA0B,kCAAkC;AAAA,MACnF,UAAUA,OAAM;AAAA,MAChB,WAAWD,aAAY;AAAA,MACvB;AAAA,IACF,CAAC;AAED,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,mBAAmB,OAAO,CAAC;AACxC;AAAA,IACF;AAEA,YAAQ,cAAcA,aAAY,IAAI,eAAe,QAAQ,KAAK,GAAG;AACrE,QAAI,OAAO,QAAQ;AACjB,WAAK,mBAAmB,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7C;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,QAAI,eAAe,YAAY,IAAI,WAAW,OAAO,IAAI,KAAK,gBAAgB,GAAG;AAC/E,YAAM,gBAAgB,IAAI,KAAK,gBAAgB;AAC/C,YAAM,uCAAuC;AAC7C,iBAAW,KAAK,eAAe;AAC7B,gBAAQ,IAAID,QAAM,OAAO,OAAO,CAAC,EAAE,CAAC;AAAA,MACtC;AACA,WAAK,+EAA+E;AACpF,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,4BACpB,MACA,SACe;AACf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,kCAA6B,UAAU,KAAK,CAAC,EAAE,MAAM;AAEjF,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,IAAyB,wBAAwB;AACvE,UAAME,eAAc,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACnD,QAAI,CAACA,cAAa;AAAE,cAAQ,KAAK;AAAG,YAAM,gBAAgB,IAAI,cAAc;AAAG,cAAQ,WAAW;AAAG;AAAA,IAAQ;AAE7G,UAAM,SAAS,MAAM,IAAI,IAAoD,SAAS;AACtF,UAAMC,SAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,cAAc,QAAQ,KAAK;AAC9D,QAAI,CAACA,QAAO;AAAE,cAAQ,KAAK;AAAG,YAAM,UAAU,QAAQ,KAAK,cAAc;AAAG,cAAQ,WAAW;AAAG;AAAA,IAAQ;AAE1G,UAAM,IAAI,KAAK,oCAAoC;AAAA,MACjD,UAAUA,OAAM;AAAA,MAChB,WAAWD,aAAY;AAAA,IACzB,CAAC;AACD,YAAQ,KAAK;AACb,YAAQ,gBAAgBA,aAAY,IAAI,iBAAiB,QAAQ,KAAK,GAAG;AAAA,EAC3E,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,6BAA4C;AAChE,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUF,MAAI,EAAE,MAAM,iCAA4B,UAAU,KAAK,CAAC,EAAE,MAAM;AAEhF,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,IAAoB,uCAAuC;AACtF,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,EAAE,SAAS,CAAC;AACvB;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,QAAQ;AACpB,WAAK,4BAA4B;AACjC;AAAA,IACF;AAEA,YAAQ,IAAIC,QAAM,KAAK,6BAA6B,CAAC;AACrD,eAAW,KAAK,UAAU;AACxB,cAAQ,IAAI,KAAKA,QAAM,KAAK,EAAE,EAAE,CAAC,aAAa,EAAE,iBAAiB,KAAK,IAAI,CAAC,EAAE;AAC7E,UAAI,EAAE,OAAQ,SAAQ,IAAI,eAAeA,QAAM,IAAI,EAAE,MAAM,CAAC,EAAE;AAC9D,cAAQ,IAAI,eAAe,EAAE,MAAM,gBAAgB,EAAE,UAAU,EAAE;AACjE,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,0BACpB,WACA,SACe;AACf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUD,MAAI,EAAE,MAAM,2BAAsB,UAAU,KAAK,CAAC,EAAE,MAAM;AAE1E,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,IAAI,yCAAyC,SAAS,IAAI;AAAA,MACjF,QAAQ;AAAA,MACR,cAAc,QAAQ;AAAA,IACxB,CAAC;AACD,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,MAAM;AACjB;AAAA,IACF;AAEA,YAAQ,iBAAiB,SAAS,sCAAsC;AAAA,EAC1E,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,eAAsB,uBACpB,WACA,SACe;AACf,QAAM,OAAO,WAAW;AACxB,QAAM,UAAUA,MAAI,EAAE,MAAM,yBAAoB,UAAU,KAAK,CAAC,EAAE,MAAM;AAExE,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,IAAI,yCAAyC,SAAS,IAAI;AAAA,MACjF,QAAQ;AAAA,MACR,cAAc,QAAQ;AAAA,IACxB,CAAC;AACD,YAAQ,KAAK;AAEb,QAAI,MAAM;AACR,iBAAW,MAAM;AACjB;AAAA,IACF;AAEA,YAAQ,iBAAiB,SAAS,UAAU;AAAA,EAC9C,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AA+BA,eAAsB,wBAAwB,SAAsC;AAClF,QAAM,OAAO,WAAW;AAIxB,QAAM,WAAW,QAAQ,UAAU,QAAQ,iBAAiB,QAAQ;AACpE,MAAI,CAAC,CAAC,gBAAgB,QAAQ,OAAO,EAAE,SAAS,QAAQ,GAAG;AACzD,UAAM,kBAAkB,QAAQ,KAAK,6BAA6B;AAClE,YAAQ,WAAW;AACnB;AAAA,EACF;AAKA,QAAM,UAAmC,CAAC;AAC1C,MAAI,QAAQ,OAAQ,SAAQ,KAAK,CAAC,WAAW,QAAQ,MAAM,CAAC;AAC5D,MAAI,QAAQ,YAAa,SAAQ,KAAK,CAAC,gBAAgB,QAAQ,WAAW,CAAC;AAC3E,MAAI,QAAQ,cAAe,SAAQ,KAAK,CAAC,kBAAkB,QAAQ,aAAa,CAAC;AACjF,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,oEAAoE;AAC1E,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,qEAAqE;AAC3E,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,QAAM,CAAC,WAAW,WAAW,IAAI,QAAQ,CAAC;AAC1C,QAAM,cAAsC,EAAE,CAAC,SAAS,GAAG,YAAY;AAEvE,QAAM,WAAW,QAAQ,aACnB,QAAQ,gBAAgB,YACxB,QAAQ,SAAS,YACjB;AAEN,QAAM,UAAUA,MAAI,EAAE,MAAM,aAAa,QAAQ,GAAG,OAAO,QAAQ,gBAAW,UAAU,KAAK,CAAC,EAAE,MAAM;AAEtG,MAAI;AAIF,QAAI;AACJ,QAAI,aAAa,SAAS;AACxB,UAAI,CAAC,QAAQ,OAAO;AAClB,gBAAQ,KAAK;AACb,cAAM,kDAAkD;AACxD,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,YAAM,SAAS,MAAM,IAAI,IAAoD,SAAS;AACtF,YAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,cAAc,QAAQ,KAAK;AAC9D,UAAI,CAAC,OAAO;AACV,gBAAQ,KAAK;AACb,cAAM,UAAU,QAAQ,KAAK,cAAc;AAC3C,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,gBAAU,MAAM;AAAA,IAClB;AAIA,QAAI,cAAc,QAAQ;AAC1B,QAAI,CAAC,aAAa;AAChB,YAAM,OAAO,MAAM,IAAI,IAAyB,wBAAwB;AACxE,YAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,GAAG;AACnD,oBAAc,KAAK,QAAQ,QAAQ;AAAA,IACrC;AAEA,UAAM,SAAS,MAAM,IAAI,KAA8C,iBAAiB;AAAA,MACtF,OAAO;AAAA,MACP,eAAe,QAAQ;AAAA,MACvB,cAAc;AAAA,MACd,WAAW;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,GAAI,UAAU,EAAE,UAAU,QAAQ,IAAI,CAAC;AAAA,IACzC,CAAC;AAED,YAAQ,KAAK;AAEb,UAAM,MAAM,OAAO;AACnB,QAAI,MAAM;AACR,iBAAW,EAAE,aAAa,IAAI,CAAC;AAC/B;AAAA,IACF;AAEA,YAAQ,aAAa,WAAW,MAAM,QAAQ,GAAG,QAAQ,QAAQ,QAAQ;AACzE,SAAK,mBAAmB,IAAI,EAAE,EAAE;AAChC,SAAK,mBAAmB,IAAI,MAAM,EAAE;AAAA,EACtC,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,gBAAY,GAAG;AAAA,EACjB;AACF;AAIA,SAAS,YAAY,KAAoB;AACvC,MAAI,eAAe,UAAU;AAC3B,UAAM,cAAc,IAAI,MAAM,MAAM,IAAI,OAAO,EAAE;AAAA,EACnD,OAAO;AACL,UAAO,IAAc,OAAO;AAAA,EAC9B;AACA,UAAQ,WAAW;AACrB;;;AtCnXA,IAAMI,cAAa,OAAyC,YAAkB;AAE9E,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,KAAK,EACV,YAAY,wDAAmD,EAC/D,QAAQA,WAAU,EAClB,OAAO,UAAU,kEAAkE,EACnF,OAAO,uBAAuB,4CAA4C;AAI7E,QAAQ,KAAK,aAAa,OAAO,aAAa,kBAAkB;AAC9D,QAAM,OAAO,YAAY,gBAAgB;AACzC,MAAI,KAAK,MAAM;AACb,gBAAY,IAAI;AAAA,EAClB;AASA,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,eAAe,KAAK,EAAE,QAAQ,IAAI,EAAE,OAAQ,MAAK,QAAQ,EAAE,KAAK,CAAC;AAC9E,QAAM,UAAU,KAAK,KAAK,GAAG;AAC7B,MAAI,YAAY,2BAA2B,YAAY,oBAAoB;AACzE,UAAM,6BAA6B;AAAA,EACrC;AACF,CAAC;AAID,QACG,QAAQ,QAAQ,EAChB,YAAY,8DAA8D,EAC1E,OAAO,aAAa;AAEvB,QACG,QAAQ,eAAe,EACvB,YAAY,oGAAoG,EAChH;AAAA,EACC;AAAA;AAAA;AAAA;AAAA,EAIA;AACF,EACC,OAAO,YAAY;AAItB,IAAM,OAAO,QACV,QAAQ,MAAM,EACd,YAAY,cAAc;AAE7B,KACG,QAAQ,MAAM,EACd,YAAY,0BAA0B,EACtC,OAAO,eAAe;AAEzB,KACG,QAAQ,eAAe,EACvB,YAAY,wCAAwC,EACpD,OAAO,iBAAiB;AAE3B,KACG,QAAQ,eAAe,EACvB,YAAY,wBAAwB,EACpC,OAAO,iBAAiB;AAU3B,IAAM,cAAc,QACjB,QAAQ,aAAa,EACrB;AAAA,EACC;AACF;AAEF,YACG,QAAQ,iBAAiB,EACzB;AAAA,EACC;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC,CAAC,OAAe;AAAA;AAAA;AAAA;AAAA,IAId,0BAA0B,OAAO;AAAA,MAC/B,UAAU,KAAK,WAAW;AAAA,MAC1B,SAAS,KAAK,YAAY;AAAA,MAC1B,SAAS,KAAK;AAAA,IAChB,CAAC;AAAA;AACL;AAEF,YACG,QAAQ,SAAS,EACjB,YAAY,+DAA+D,EAC3E,OAAO,SAAS,yDAAyD,EACzE;AAAA,EAAO,CAAC,SACP,0BAA0B,EAAE,KAAK,KAAK,QAAQ,KAAK,CAAC;AACtD;AAEF,YACG,QAAQ,MAAM,EACd,YAAY,kFAAkF,EAC9F,OAAO,SAAS,yDAAyD,EACzE;AAAA,EAAO,CAAC,SACP,uBAAuB,EAAE,KAAK,KAAK,QAAQ,KAAK,CAAC;AACnD;AAKF,YACG,QAAQ,aAAa,EAAE,QAAQ,KAAK,CAAC,EACrC,YAAY,6EAA6E,EACzF,OAAO,2BAA2B;AAIrC,QACG,QAAQ,MAAM,EACd,YAAY,yEAAyE,EACrF,OAAO,yBAAyB,oDAAoD,EACpF,OAAO,2BAA2B,8DAA8D,EAChG,OAAO,wBAAwB,yBAAyB,EACxD,OAAO,uBAAuB,mCAAmC,KAAK,EACtE,OAAO,sBAAsB,kCAAkC,KAAK,EACpE,OAAO,wBAAwB,wCAAwC,QAAQ,EAC/E,OAAO,4BAA4B,sBAAsB,OAAO,EAChE,OAAO,6BAA6B,uBAAuB,IAAI,EAC/D,OAAO,4BAA4B,2CAA2C,OAAO,EACrF,OAAO,+BAA+B,0DAA0D,OAAO,EACvG,OAAO,qBAAqB,6BAA6B,EACzD,OAAO,oBAAoB,mDAAmD,UAAU,EACxF,OAAO,WAAW;AAErB,QACG,QAAQ,MAAM,EACd,SAAS,UAAU,8DAA8D,EACjF,YAAY,oCAAoC,EAChD,OAAO,WAAW;AAIrB,IAAM,WAAW,QACd,QAAQ,UAAU,EAClB,YAAY,0CAA0C;AAEzD,SACG,QAAQ,MAAM,EACd,YAAY,wDAAwD,EACpE,OAAO,mBAAmB;AAE7B,SACG,QAAQ,eAAe,EACvB,YAAY,iDAAiD,EAC7D,OAAO,oBAAoB;AAE9B,IAAM,QAAQ,SACX,QAAQ,OAAO,EACf,YAAY,oCAAoC;AAEnD,MACG,QAAQ,yBAAyB,EACjC,YAAY,sEAAsE,EAClF,OAAO,qBAAqB,yCAAyC,EACrE,OAAO,qBAAqB,0CAA0C,EACtE,OAAO,iBAAiB,kCAAkC,EAC1D,OAAO,uBAAuB,+BAA0B,EACxD,OAAO,6BAA6B,sBAAsB,EAC1D,OAAO,0BAA0B,wEAAmE,EACpG,OAAO,wBAAwB;AAElC,MACG,QAAQ,0BAA0B,EAClC,YAAY,+CAA+C,EAC3D,OAAO,yBAAyB;AAEnC,MACG,QAAQ,0BAA0B,EAClC,YAAY,6CAA6C,EACzD,OAAO,yBAAyB;AAEnC,IAAM,OAAO,SACV,QAAQ,MAAM,EACd,YAAY,4CAA4C;AAE3D,KACG,QAAQ,yBAAyB,EACjC,YAAY,sEAAsE,EAClF,OAAO,yBAAyB,sCAAsC,EACtE,OAAO,mBAAmB,6BAA6B,EACvD,OAAO,kBAAkB,2CAA2C,IAAI,EACxE,OAAO,uBAAuB;AAEjC,KACG,QAAQ,0BAA0B,EAClC,YAAY,8CAA8C,EAC1D,OAAO,wBAAwB;AAElC,KACG,QAAQ,0BAA0B,EAClC,YAAY,mCAAmC,EAC/C,OAAO,wBAAwB;AAIlC,QACG,QAAQ,uBAAuB,EAC/B,YAAY,2EAA2E,EACvF,OAAO,qBAAqB,qBAAqB,cAAc,EAC/D,OAAO,kBAAkB,sCAAsC,EAC/D,OAAO,aAAa,qDAAqD,EACzE,OAAO,gBAAgB;AAI1B,QACG,QAAQ,QAAQ,EAChB,YAAY,4CAA4C,EACxD,OAAO,mBAAmB,6CAA6C,EACvE,OAAO,mBAAmB,yBAAyB,MAAM,EACzD,OAAO,aAAa;AAIvB,IAAM,QAAQ,QACX,QAAQ,OAAO,EACf,YAAY,mDAAmD;AAElE,MACG,QAAQ,mBAAmB,EAC3B,YAAY,iDAAiD,EAC7D,OAAO,UAAU,gBAAgB,EACjC,OAAO,WAAW,6BAA6B,EAC/C,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,iBAAiB;AAE3B,MACG,QAAQ,mBAAmB,EAC3B,YAAY,gCAAgC,EAC5C,OAAO,wBAAwB,6BAA6B,IAAI,EAChE,OAAO,mBAAmB,kCAAkC,EAC5D,OAAO,UAAU,gBAAgB,EACjC,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,iBAAiB;AAI3B,IAAM,OAAO,QACV,QAAQ,MAAM,EACd,YAAY,6DAA6D;AAE5E,KACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,eAAe;AAEzB,KACG,QAAQ,0CAA0C,EAClD,YAAY,yBAAyB,EACrC,OAAO,WAAW,kDAAkD,EACpE,OAAO,iBAAiB;AAE3B,KACG,QAAQ,4CAA4C,EACpD,YAAY,6BAA6B,EACzC,OAAO,mBAAmB;AAE7B,KACG,QAAQ,oBAAoB,EAC5B,YAAY,6EAA6E,EACzF,OAAO,iBAAiB;AAE3B,KACG,QAAQ,wBAAwB,EAChC,YAAY,qDAAqD,EACjE,OAAO,oBAAoB;AAE9B,KACG,QAAQ,0BAA0B,EAClC,YAAY,mDAAmD,EAC/D,OAAO,uBAAuB;AAEjC,KACG,QAAQ,gCAAgC,EACxC,YAAY,qEAAqE,EACjF,OAAO,mBAAmB,2CAA2C,EACrE,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,eAAe,yCAAyC,EAC/D,OAAO,WAAW,4DAAuD,EACzE,OAAO,4BAA4B;AAEtC,KACG,QAAQ,kBAAkB,EAC1B,YAAY,iFAAiF,EAC7F,OAAO,iBAAiB,gDAAgD,OAAO,EAG/E,OAAO,cAAc,yDAAyD,EAC9E;AAAA,EAAO,CAAC,UAAkB,SACzB,gBAAgB,UAAU;AAAA,IACxB,MAAM,KAAK;AAAA,IACX,SAAS,KAAK,UAAU;AAAA,EAC1B,CAAC;AACH;AAIF,IAAM,UAAU,QACb,QAAQ,SAAS,EACjB,YAAY,yEAAoE;AAEnF,QACG,QAAQ,OAAO,EACf,YAAY,iFAAiF,EAC7F,OAAO,wBAAwB,oCAAoC,IAAI,EACvE,OAAO,sBAAsB,oCAAoCC,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9F,OAAO,eAAe,6GAA6G,KAAK,EACxI,OAAO,mBAAmB;AAE7B,QACG,QAAQ,MAAM,EACd,YAAY,iCAAiC,EAC7C,OAAO,sBAAsB,oCAAoCD,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9F,OAAO,kBAAkB;AAE5B,QACG,QAAQ,QAAQ,EAChB,YAAY,8DAA8D,EAC1E,OAAO,sBAAsB,oCAAoCD,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9F,OAAO,oBAAoB;AAE9B,QACG,QAAQ,OAAO,EACf,YAAY,sFAAiF,EAC7F,OAAO,sBAAsB,oCAAoCD,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9F,OAAO,YAAY,0EAA0E,EAC7F,OAAO,mBAAmB;AAE7B,QACG,QAAQ,SAAS,EACjB,YAAY,wIAAwI,EACpJ,OAAO,wBAAwB,oCAAoC,IAAI,EACvE,OAAO,sBAAsB,oCAAoCD,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9F,OAAO,qBAAqB;AAE/B,QACG,QAAQ,WAAW,EACnB,YAAY,wFAAwF,EACpG,OAAO,uBAAuB;AAEjC,QACG,QAAQ,qBAAqB,EAC7B,YAAY,wLAAmL,EAC/L,OAAO,wBAAwB,oCAAoC,IAAI,EACvE,OAAO,sBAAsB,4FAA4F,EACzH,OAAO,iBAAiB,iCAAiC,MAAM,EAC/D,OAAO,+BAA+B;AAEzC,QACG,QAAQ,uBAAuB,EAC/B,YAAY,4EAA4E,EACxF,OAAO,iCAAiC;AAI3C,IAAM,QAAQ,QACX,QAAQ,OAAO,EACf,YAAY,2BAA2B;AAE1C,MACG,QAAQ,kBAAkB,EAC1B,YAAY,uDAAuD,EACnE,OAAO,sBAAsB,oBAAoBD,OAAKC,SAAQ,GAAG,YAAY,CAAC,EAC9E,OAAO,kBAAkB,wCAAwC,EACjE,OAAO,gBAAgB;AAI1B,IAAM,SAAS,QACZ,QAAQ,QAAQ,EAChB,YAAY,4BAA4B;AAE3C,OACG,QAAQ,MAAM,EACd,YAAY,sCAAsC,EAClD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,iBAAiB;AAE3B,OACG,QAAQ,aAAa,EACrB,YAAY,yCAAyC,EACrD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,sBAAsB,qCAAqC,GAAG,EACrE,OAAO,qBAAqB,gDAAgD,MAAM,EAClF,OAAO,wBAAwB,kBAAkB,EACjD,OAAO,wBAAwB,2BAA2B,EAC1D,OAAO,wBAAwB,6BAA6B,EAC5D,OAAO,gBAAgB;AAE1B,OACG,QAAQ,6BAA6B,EACrC,YAAY,0CAA0C,EACtD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,kBAAkB,gBAAgB,EACzC,OAAO,iBAAiB;AAE3B,OACG,QAAQ,sBAAsB,EAC9B,YAAY,yCAAyC,EACrD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,kBAAkB,gBAAgB,EACzC,OAAO,mBAAmB,wBAAwB,EAClD,OAAO,mBAAmB;AAE7B,OACG,QAAQ,oBAAoB,EAC5B,YAAY,4BAA4B,EACxC,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,mBAAmB,6BAA6B,EACvD,OAAO,kBAAkB,kBAAkB,EAC3C,OAAO,iBAAiB;AAE3B,IAAM,YAAY,OACf,QAAQ,WAAW,EACnB,YAAY,+BAA+B;AAE9C,UACG,QAAQ,aAAa,EACrB,YAAY,gCAAgC,EAC5C,eAAe,uBAAuB,iBAAiB,EACvD,eAAe,sBAAsB,8EAA8E,EACnH,OAAO,sBAAsB,qCAAqC,GAAG,EACrE,OAAO,wBAAwB,kBAAkB,EACjD,OAAO,wBAAwB,2BAA2B,EAC1D,OAAO,wBAAwB,6BAA6B,EAC5D,OAAO,mBAAmB,yBAAyB,EACnD,OAAO,yBAAyB;AAEnC,UACG,QAAQ,MAAM,EACd,YAAY,8CAA8C,EAC1D,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,0BAA0B;AAEpC,UACG,QAAQ,uBAAuB,EAC/B,YAAY,qCAAqC,EACjD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,6BAA6B;AAIvC,IAAM,OAAO,QACV,QAAQ,MAAM,EACd,YAAY,yDAAyD,EACrE,OAAO,gBAAgB,uCAAuC,EAC9D,OAAO,qBAAqB,wCAAwC,EACpE,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,mBAAmB,oDAAoD,MAAM,EACpF,OAAO,mBAAmB,kDAAkD,EAC5E,OAAO,uBAAuB,0BAA0B,EACxD,OAAO,aAAa,8CAA8C;AAErE,KACG,QAAQ,eAAe,EACvB,YAAY,uEAAuE,EACnF,OAAO,gBAAgB;AAE1B,KACG,QAAQ,yBAAyB,EACjC,YAAY,iCAAiC,EAC7C,OAAO,iBAAiB;AAE3B,KACG,QAAQ,uBAAuB,EAC/B,YAAY,uCAAuC,EACnD,OAAO,eAAe;AAEzB,KACG,QAAQ,uBAAuB,EAC/B,YAAY,uCAAuC,EACnD,OAAO,uBAAuB;AAEjC,KACG,QAAQ,gBAAgB,EACxB,YAAY,oDAAoD,EAChE,OAAO,iBAAiB;AAE3B,KACG,QAAQ,eAAe,EACvB,YAAY,+CAA+C,EAC3D,OAAO,gBAAgB;AAI1B,IAAM,cAAc,QACjB,QAAQ,aAAa,EACrB,YAAY,8EAAyE;AAExF,YACG,QAAQ,MAAM,EACd,YAAY,iDAAiD,EAC7D,OAAO,sBAAsB;AAEhC,YACG,QAAQ,aAAa,EACrB,YAAY,sDAAsD,EAClE,OAAO,sBAAsB;AAEhC,YACG,QAAQ,gBAAgB,EACxB,YAAY,oCAAoC,EAChD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,qBAAqB,oCAAoC,EAChE,OAAO,yBAAyB;AAEnC,YACG,QAAQ,kBAAkB,EAC1B,YAAY,qCAAqC,EACjD,eAAe,uBAAuB,iBAAiB,EACvD,OAAO,2BAA2B;AAErC,YACG,QAAQ,UAAU,EAClB,YAAY,mDAAmD,EAC/D,OAAO,0BAA0B;AAEpC,YACG,QAAQ,sBAAsB,EAC9B,YAAY,yBAAyB,EACrC,OAAO,kBAAkB,cAAc,EACvC,OAAO,yBAAyB;AAEnC,YACG,QAAQ,mBAAmB,EAC3B,YAAY,sBAAsB,EAClC,OAAO,mBAAmB,eAAe,EACzC,OAAO,sBAAsB;AAEhC,YACG,QAAQ,OAAO,EACf,YAAY,wEAAwE,EACpF,eAAe,qBAAqB,sDAAsD,EAC1F,eAAe,4BAA4B,eAAe,EAC1D,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,0BAA0B,6CAA6C,EAC9E,OAAO,4BAA4B,iDAAiD,EACpF,OAAO,yBAAyB,wEAAmE,EACnG,OAAO,uBAAuB,4CAA4C,EAC1E,OAAO,uBAAuB;AAIjC,QACG,QAAQ,QAAQ,EAChB,YAAY,mCAAmC,EAC/C,OAAO,WAAW,sDAAsD,EACxE,OAAO,aAAa;AAOvB,IAAM,QAAQ,QACX,QAAQ,OAAO,EACf,YAAY,qDAAgD;AAC/D,MACG,QAAQ,WAAW,EACnB,YAAY,uFAAuF,EACnG,OAAO,YAAY,2DAA2D,EAC9E,OAAO,UAAU,iCAAiC,EAClD,OAAO,qBAAqB;AAO/B,MACG,QAAQ,YAAY,EACpB,YAAY,yFAAyF,EACrG,OAAO,YAAY,2DAA2D,EAC9E,OAAO,UAAU,iCAAiC,EAClD,OAAO,qBAAqB;AAM/B,MACG,QAAQ,SAAS,EACjB,YAAY,8EAA8E,EAC1F,OAAO,YAAY,2DAA2D,EAC9E,OAAO,UAAU,iCAAiC,EAClD,OAAO,mBAAmB;AAK7B,IAAM,kBACJ,QAAQ,KAAK,SAAS,qBAAqB,KAC3C,QAAQ,KAAK,SAAS,QAAQ,KAC9B,QAAQ,KAAK,CAAC,MAAM;AAEtB,IAAI,CAAC,iBAAiB;AAEpB,0BAAwB,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAC1C;AAIA,QAAQ,WAAW,EAAE,MAAM,CAAC,QAAQ;AAClC,UAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC9D,UAAQ,WAAW;AACrB,CAAC;","names":["join","homedir","chalk","ora","ora","chalk","chalk","ora","chalk","ora","chalk","ora","join","printDiagnostics","chalk","join","readdirSync","statSync","ora","chalk","ora","channels","chalk","ora","chalk","ora","checkbox","confirm","input","join","ora","agent","channels","chalk","checkbox","input","confirm","chalk","ora","confirm","ora","agent","channels","chalk","confirm","chalk","ora","select","input","writeFileSync","mkdirSync","join","chalk","select","input","ora","join","mkdirSync","writeFileSync","chalk","ora","writeFileSync","mkdirSync","join","printDiagnostics","chalk","join","ora","mkdirSync","writeFileSync","chalk","ora","existsSync","readFileSync","writeFileSync","dirname","join","fileURLToPath","existsSync","mkdirSync","readFileSync","writeFileSync","join","existsSync","renameSync","homedir","join","existsSync","mkdirSync","readdirSync","readFileSync","renameSync","unlinkSync","writeFileSync","join","join","existsSync","mkdirSync","readFileSync","writeFileSync","renameSync","unlinkSync","readdirSync","chmodSync","copyFileSync","existsSync","mkdirSync","readdirSync","readFileSync","renameSync","rmdirSync","unlinkSync","writeFileSync","homedir","dirname","join","join","homedir","mkdirSync","dirname","existsSync","readFileSync","copyFileSync","chmodSync","asPlainObject","safeParseJson","writeFileSync","renameSync","unlinkSync","readdirSync","rmdirSync","input","chalk","ora","host","writeFileSync","join","resolve","manifest","readFileSync","dirname","fileURLToPath","existsSync","chalk","ora","createHash","join","chalk","ora","agent","chalk","ora","ora","chalk","spinner","spawn","chalk","host","chalk","spawn","resolve","existsSync","readFileSync","homedir","join","join","homedir","existsSync","readFileSync","input","agent","chalk","JSON5","readFileSync","existsSync","join","join","existsSync","readFileSync","JSON5","filtered","chalk","chalk","ora","chalk","ora","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","homedir","chalk","ora","homedir","join","existsSync","readFileSync","writeFileSync","lines","chalk","ora","dirname","mkdirSync","channels","chalk","ora","resolveAgentId","priorityLabel","chalk","ora","spawn","resolve","spawn","agent","agent","existsSync","realpathSync","chalk","ora","host","parse","realpathSync","existsSync","ora","chalk","homedir","join","readdirSync","readFileSync","statSync","join","homedir","join","readdirSync","readFileSync","statSync","homedir","join","homedir","join","readdirSync","readFileSync","statSync","join","agent","statSync","readFileSync","readdirSync","join","join","homedir","chalk","ora","ora","chalk","integration","agent","cliVersion","join","homedir"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/agt.ts","../../src/commands/whoami.ts","../../src/commands/team.ts","../../src/lib/auth-guard.ts","../../src/commands/init.ts","../../src/commands/lint.ts","../../src/commands/channels.ts","../../src/commands/channel-slack.ts","../../src/commands/channel-beam.ts","../../src/commands/deploy.ts","../../src/commands/provision.ts","../../src/commands/impersonate.ts","../../src/lib/impersonate-flag.ts","../../src/lib/impersonate-state.ts","../../src/lib/impersonate-fs-ops.ts","../../src/lib/impersonate-hook.ts","../../src/lib/impersonate-statusline.ts","../../src/lib/impersonate-introduce.ts","../../src/lib/impersonate-mcp-rewrite.ts","../../src/commands/drift.ts","../../../../packages/core/src/drift/live-state-reader.ts","../../src/commands/host.ts","../../src/commands/host-pair.ts","../../src/commands/manager-watch.tsx","../../src/commands/agent.ts","../../src/commands/kanban-recurring.ts","../../src/commands/setup.ts","../../src/commands/kanban.ts","../../../../packages/core/src/acp/agent-registry.ts","../../../../packages/core/src/acp/client.ts","../../src/commands/acpx.ts","../../src/commands/update.ts","../../src/commands/audit-subagents.ts","../../src/lib/subagent-mcp-audit.ts","../../src/lib/mcp-render-allowlist-audit.ts","../../src/commands/audit-mcp-render.ts","../../src/commands/audit-secrets.ts","../../src/lib/secret-leak-audit.ts","../../src/commands/integration.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// Register framework adapters (side-effect imports — must be before any provisioning code)\nimport '@augmented/core/provisioning/frameworks/openclaw/index.js';\nimport '@augmented/core/provisioning/frameworks/nemoclaw/index.js';\nimport '@augmented/core/provisioning/frameworks/claudecode/index.js';\nimport '@augmented/core/provisioning/frameworks/managed-agents/index.js';\n\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { Command } from 'commander';\nimport { setJsonMode } from '../lib/globals.js';\nimport { whoamiCommand } from '../commands/whoami.js';\nimport {\n teamListCommand,\n teamCreateCommand,\n teamSwitchCommand,\n} from '../commands/team.js';\nimport { initCommand } from '../commands/init.js';\nimport { lintCommand } from '../commands/lint.js';\nimport { channelsListCommand, channelsCheckCommand } from '../commands/channels.js';\nimport { channelSlackSetupCommand, channelSlackStatusCommand, channelSlackRemoveCommand } from '../commands/channel-slack.js';\nimport { channelBeamSetupCommand, channelBeamStatusCommand, channelBeamRemoveCommand } from '../commands/channel-beam.js';\nimport { deployCommand } from '../commands/deploy.js';\nimport { provisionCommand } from '../commands/provision.js';\nimport {\n impersonateConnectCommand,\n impersonateCurrentCommand,\n impersonateExitCommand,\n impersonateIntroduceCommand,\n autoExitExpiredImpersonation,\n} from '../commands/impersonate.js';\nimport { driftCheckCommand, driftWatchCommand } from '../commands/drift.js';\nimport {\n hostListCommand,\n hostAssignCommand,\n hostUnassignCommand,\n hostAgentsCommand,\n hostRotateKeyCommand,\n hostDecommissionCommand,\n hostMaintenanceWindowCommand,\n} from '../commands/host.js';\nimport { hostPairCommand } from '../commands/host-pair.js';\nimport {\n managerStartCommand,\n managerStopCommand,\n managerStatusCommand,\n managerInstallCommand,\n managerUninstallCommand,\n managerInstallSystemUnitCommand,\n managerUninstallSystemUnitCommand,\n} from '../commands/manager.js';\nimport { managerWatchCommand } from '../commands/manager-watch.js';\nimport { agentShowCommand } from '../commands/agent.js';\nimport {\n kanbanRecurringAddCommand,\n kanbanRecurringListCommand,\n kanbanRecurringDisableCommand,\n} from '../commands/kanban-recurring.js';\nimport { setupCommand } from '../commands/setup.js';\nimport {\n kanbanListCommand,\n kanbanAddCommand,\n kanbanMoveCommand,\n kanbanUpdateCommand,\n kanbanDoneCommand,\n} from '../commands/kanban.js';\nimport {\n acpxSpawnCommand,\n acpxPromptCommand,\n acpxExecCommand,\n acpxListSessionsCommand,\n acpxCancelCommand,\n acpxCloseCommand,\n} from '../commands/acpx.js';\nimport { updateCommand, checkForUpdateOnStartup } from '../commands/update.js';\nimport { auditSubagentsCommand } from '../commands/audit-subagents.js';\nimport { auditMcpRenderCommand } from '../commands/audit-mcp-render.js';\nimport { auditSecretsCommand } from '../commands/audit-secrets.js';\nimport {\n integrationListCommand,\n integrationShowCommand,\n integrationInstallCommand,\n integrationUninstallCommand,\n integrationRequestsCommand,\n integrationApproveCommand,\n integrationDenyCommand,\n integrationEnrolCommand,\n} from '../commands/integration.js';\n\ndeclare const __CLI_VERSION__: string;\n\nconst cliVersion = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : 'dev';\n\nconst program = new Command();\n\nprogram\n .name('agt')\n .description('Augmented CLI — agent provisioning and management')\n .version(cliVersion)\n .option('--json', 'Emit machine-readable JSON output (suppress spinners and colors)')\n .option('--skip-update-check', 'Skip the automatic update check on startup');\n\n// ── Global pre-action hook ──────────────────────────────────────────────────\n\nprogram.hook('preAction', async (thisCommand, actionCommand) => {\n const root = thisCommand.optsWithGlobals();\n if (root.json) {\n setJsonMode(true);\n }\n\n // ENG-5911: on any command, lazily auto-exit an expired impersonation\n // session (restore the operator's files + clear state) so a dead session\n // never lingers needing a manual `agt impersonate exit`. Skip the two\n // commands where it would be wrong or redundant:\n // - `impersonate introduce`: the SessionStart hook — must never restore\n // files / post /stop mid-session-boot (it already self-guards on expiry).\n // - `impersonate exit`: redundant; it runs the cleanup itself.\n const segs: string[] = [];\n for (let c = actionCommand; c && c.parent; c = c.parent) segs.unshift(c.name());\n const cmdPath = segs.join(' ');\n if (cmdPath !== 'impersonate introduce' && cmdPath !== 'impersonate exit') {\n await autoExitExpiredImpersonation();\n }\n});\n\n// ── Auth commands ──────────────────────────────────────────────────────────\n\nprogram\n .command('whoami')\n .description('Show the authenticated host, team, and user from AGT_API_KEY')\n .action(whoamiCommand);\n\nprogram\n .command('setup <token>')\n .description('One-command host setup: exchange provisioning token, configure env vars, verify, and start manager')\n .option(\n '--api-host <url>',\n // ENG-5831: required when AGT_HOST is not set in the shell — the setup\n // command no longer silently defaults to prod. Mirrors `agt impersonate\n // connect --api-host` (ENG-5773).\n 'API host to exchange the provisioning token against. Takes precedence over AGT_HOST. Required when AGT_HOST is unset (e.g. https://test.api.staging.augmented.team for the test stage; https://api.augmented.team for prod).',\n )\n .action(setupCommand);\n\n// ── Team commands ─────────────────────────────────────────────────────\n\nconst team = program\n .command('team')\n .description('Manage teams');\n\nteam\n .command('list')\n .description('List teams you belong to')\n .action(teamListCommand);\n\nteam\n .command('create <name>')\n .description('Create a new team and set it as active')\n .action(teamCreateCommand);\n\nteam\n .command('switch <slug>')\n .description('Switch the active team')\n .action(teamSwitchCommand);\n\n// ── Impersonation commands ────────────────────────────────────────────────\n// ENG-5688 (redesigned): operator-impersonates-agent v0. The webapp\n// (ENG-5702) mints a redeem token; the operator pastes\n// `agt impersonate connect <token>` to enter, `exit` to leave.\n// All gated behind AGT_IMPERSONATE_ENABLED until the surrounding pieces\n// (ENG-5689 channel-MCP refusal, ENG-5702 webapp button) land and the\n// end-to-end smoke test runs against prod.\n\nconst impersonate = program\n .command('impersonate')\n .description(\n 'Operate as a managed agent locally (experimental, gated by AGT_IMPERSONATE_ENABLED)',\n );\n\nimpersonate\n .command('connect <token>')\n .description(\n \"Redeem a XXXX-XXXX token from the webapp, render the agent's CLAUDE.md + .mcp.json, swap them into the current project, and launch Claude Code (use --no-launch to skip the launch)\",\n )\n .option(\n '--no-launch',\n \"Skip launching Claude Code after the swap (operator manages their own session)\",\n )\n .option(\n '--workdir',\n \"Swap into an auto-provisioned dedicated directory (~/.augmented-impersonate/<agent>/workdir) instead of the current directory — required when the current directory is inside a git repo\",\n )\n .option(\n '--api-host <url>',\n \"Override the API host used to redeem the token. Defaults to https://api.augmented.team — AGT_HOST is intentionally ignored so a dev/Tailscale AGT_HOST doesn't accidentally 502 against a token minted on prod.\",\n )\n .action(\n (token: string, opts: { launch?: boolean; workdir?: boolean; apiHost?: string }) =>\n // Commander negates --no-FLAG into opts.flag, so --no-launch arrives\n // as opts.launch === false. Translate to the command's noLaunch\n // option, defaulting to launching when the flag isn't passed.\n impersonateConnectCommand(token, {\n noLaunch: opts.launch === false,\n workdir: opts.workdir === true,\n apiHost: opts.apiHost,\n }),\n );\n\nimpersonate\n .command('current')\n .description('Print the active impersonation for this directory (or \"none\")')\n .option('--all', 'List every active impersonation session on this machine')\n .action((opts: { all?: boolean }) =>\n impersonateCurrentCommand({ all: opts.all === true }),\n );\n\nimpersonate\n .command('exit')\n .description(\"End this directory's impersonation, restore project files, and notify the server\")\n .option('--all', 'Exit every active impersonation session on this machine')\n .action((opts: { all?: boolean }) =>\n impersonateExitCommand({ all: opts.all === true }),\n );\n\n// Hidden: invoked by the SessionStart hook `connect` registers (ENG-5750),\n// not meant to be run by operators directly. Prints the impersonated\n// agent's introduction; silent no-op when no active impersonation.\nimpersonate\n .command('introduce', { hidden: true })\n .description(\"Print the impersonated agent's self-introduction (SessionStart hook target)\")\n .action(impersonateIntroduceCommand);\n\n// ── Agent commands ─────────────────────────────────────────────────────────\n\nprogram\n .command('init')\n .description('Create a new agent (interactive wizard, or non-interactive with --name)')\n .option('--name <display-name>', 'Agent display name (triggers non-interactive mode)')\n .option('--code-name <code-name>', 'Agent code name (kebab-case, derived from --name if omitted)')\n .option('--description <text>', 'Short agent description')\n .option('--env <environment>', 'Environment: dev | stage | prod', 'dev')\n .option('--risk-tier <tier>', 'Risk tier: Low | Medium | High', 'Low')\n .option('--budget-type <type>', 'Budget type: tokens | dollars | both', 'tokens')\n .option('--budget-tokens <number>', 'Token budget limit', '10000')\n .option('--budget-dollars <number>', 'Dollar budget limit', '10')\n .option('--budget-window <window>', 'Budget window: daily | weekly | monthly', 'daily')\n .option('--budget-enforcement <mode>', 'Budget enforcement: block | throttle | alert | degrade', 'block')\n .option('--channels <list>', 'Comma-separated channel IDs')\n .option('--logging <mode>', 'Logging mode: redacted | hash-only | full-local', 'redacted')\n .action(initCommand);\n\nprogram\n .command('lint')\n .argument('[path]', 'Path to agent directory (default: all agents in .augmented/)')\n .description('Lint CHARTER.md and TOOLS.md files')\n .action(lintCommand);\n\n// ── Channel commands ───────────────────────────────────────────────────────\n\nconst channels = program\n .command('channels')\n .description('Manage and inspect channel configuration');\n\nchannels\n .command('list')\n .description('Print the full channel registry with security metadata')\n .action(channelsListCommand);\n\nchannels\n .command('check <agent>')\n .description('Resolve the effective channel list for an agent')\n .action(channelsCheckCommand);\n\nconst slack = channels\n .command('slack')\n .description('Manage Slack channel configuration');\n\nslack\n .command('setup <agent-code-name>')\n .description('Configure Slack bot scopes, generate manifest, and store credentials')\n .option('--preset <preset>', 'Scope preset: minimal | standard | full')\n .option('--scopes <scopes>', 'Comma-separated list of Slack bot scopes')\n .option('--skip-create', 'Skip Slack CLI app creation step')\n .option('--bot-token <token>', 'Slack bot token (xoxb-…)')\n .option('--signing-secret <secret>', 'Slack signing secret')\n .option('--config-token <token>', 'Slack app configuration token (xoxe-…) for API-based app creation')\n .action(channelSlackSetupCommand);\n\nslack\n .command('status <agent-code-name>')\n .description('Show current Slack configuration for an agent')\n .action(channelSlackStatusCommand);\n\nslack\n .command('remove <agent-code-name>')\n .description('Remove Slack bot configuration for an agent')\n .action(channelSlackRemoveCommand);\n\nconst beam = channels\n .command('beam')\n .description('Manage Beam Protocol channel configuration');\n\nbeam\n .command('setup <agent-code-name>')\n .description('Generate Beam identity, register in directory, and configure channel')\n .option('--directory-url <url>', 'Beam directory URL (default: hosted)')\n .option('--skip-register', 'Skip directory registration')\n .option('--auto-publish', 'Auto-publish capabilities from TOOLS.md', true)\n .action(channelBeamSetupCommand);\n\nbeam\n .command('status <agent-code-name>')\n .description('Show Beam configuration and directory status')\n .action(channelBeamStatusCommand);\n\nbeam\n .command('remove <agent-code-name>')\n .description('Remove Beam identity for an agent')\n .action(channelBeamRemoveCommand);\n\n// ── Provision commands ─────────────────────────────────────────────────────\n\nprogram\n .command('provision <code-name>')\n .description('Provision an agent: build OpenClaw config, generate files, store snapshot')\n .option('--target <target>', 'Deployment target', 'local_docker')\n .option('--output <dir>', 'Output directory for generated files')\n .option('--dry-run', 'Print what would be generated without writing files')\n .action(provisionCommand);\n\n// ── Deploy commands ────────────────────────────────────────────────────────\n\nprogram\n .command('deploy')\n .description('Generate deployment config from a template')\n .option('--template <id>', 'Template ID (triggers non-interactive mode)')\n .option('--port <number>', 'Base port for gateway', '9000')\n .action(deployCommand);\n\n// ── Drift commands ────────────────────────────────────────────────────────\n\nconst drift = program\n .command('drift')\n .description('Detect configuration drift from provisioned state');\n\ndrift\n .command('check <code-name>')\n .description('Compare live state against provisioned snapshot')\n .option('--json', 'Output as JSON')\n .option('--audit', 'Run openclaw security audit')\n .option('--config <path>', 'Path to openclaw.json')\n .action(driftCheckCommand);\n\ndrift\n .command('watch <code-name>')\n .description('Continuously monitor for drift')\n .option('--interval <seconds>', 'Check interval in seconds', '60')\n .option('--webhook <url>', 'POST webhook URL on new findings')\n .option('--json', 'Output as JSON')\n .option('--config <path>', 'Path to openclaw.json')\n .action(driftWatchCommand);\n\n// ── Host commands ─────────────────────────────────────────────────────────\n\nconst host = program\n .command('host')\n .description('Manage hosts (OpenClaw servers/gateways) and their API keys');\n\nhost\n .command('list')\n .description('List hosts in the active team')\n .action(hostListCommand);\n\nhost\n .command('assign <host-name> <agent-code-names...>')\n .description('Assign agents to a host')\n .option('--force', 'Reassign agents already assigned to another host')\n .action(hostAssignCommand);\n\nhost\n .command('unassign <host-name> <agent-code-names...>')\n .description('Unassign agents from a host')\n .action(hostUnassignCommand);\n\nhost\n .command('agents [host-name]')\n .description('List agents assigned to a host (omit name to auto-resolve from AGT_API_KEY)')\n .action(hostAgentsCommand);\n\nhost\n .command('rotate-key <host-name>')\n .description('Rotate the API key for a host (revokes the old key)')\n .action(hostRotateKeyCommand);\n\nhost\n .command('decommission <host-name>')\n .description('Decommission a host (revokes key, marks inactive)')\n .action(hostDecommissionCommand);\n\nhost\n .command('maintenance-window <host-name>')\n .description('View or set the host maintenance window for restart-causing updates')\n .option('--start <HH:MM>', 'Window start, 24h local time (e.g. 01:00)')\n .option('--end <HH:MM>', 'Window end, 24h local time (e.g. 02:00)')\n .option('--tz <IANA>', 'Window timezone (e.g. Australia/Sydney)')\n .option('--clear', 'Clear the override and follow the default 01:00–02:00')\n .action(hostMaintenanceWindowCommand);\n\nhost\n .command('pair <host-name>')\n .description('Start an SSM port-forward + shell to re-authenticate Claude Code on an EC2 host')\n .option('--port <port>', 'Local port to forward for the OAuth callback', '54545')\n // Commander produces `opts.shell` (boolean, default true) for `--no-shell`.\n // Adapt to the hostPairCommand signature which expects `opts.noShell`.\n .option('--no-shell', 'Start the tunnel only; do not open an interactive shell')\n .action((hostName: string, opts: { port?: string; shell?: boolean }) =>\n hostPairCommand(hostName, {\n port: opts.port,\n noShell: opts.shell === false,\n })\n );\n\n// ── Manager commands ──────────────────────────────────────────────────────\n\nconst manager = program\n .command('manager')\n .description('Host config sync daemon — keeps local agent files in sync with API');\n\nmanager\n .command('start')\n .description('Start the manager daemon (polls API for config changes and detects local drift)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .option('--supervise', 'Wrap the manager in a respawn-on-clean-exit loop so auto-upgrades can restart it transparently (ENG-4488)', false)\n .action(managerStartCommand);\n\nmanager\n .command('stop')\n .description('Stop the running manager daemon')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerStopCommand);\n\nmanager\n .command('status')\n .description('Show the current manager daemon status and discovered agents')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerStatusCommand);\n\nmanager\n .command('watch')\n .description('Live TUI dashboard — per-agent boxes, drill-in, log tail. Read-only (ENG-4555).')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .option('--no-tui', 'Skip the TUI and stream the manager log to stdout instead (CI / scripts)')\n .action(managerWatchCommand);\n\nmanager\n .command('install')\n .description('Install OS-level supervisor (launchd LaunchAgent on macOS) so the manager auto-restarts after crash, reboot, or self-update (ENG-4593)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files', join(homedir(), '.augmented'))\n .action(managerInstallCommand);\n\nmanager\n .command('uninstall')\n .description('Remove the OS-level supervisor (launchctl unload + delete plist on macOS). Idempotent.')\n .action(managerUninstallCommand);\n\nmanager\n .command('install-system-unit')\n .description('Install a system-level systemd unit (Linux, root) so the manager auto-starts on every boot. For headless EC2 hosts — survives reboot without `loginctl enable-linger`. (ENG-4706)')\n .option('--interval <seconds>', 'Poll interval in seconds (min 5)', '10')\n .option('--config-dir <dir>', 'Config directory for agent files (defaults to /root/.augmented or /home/<user>/.augmented)')\n .option('--user <name>', 'Unix user the manager runs as', 'root')\n .action(managerInstallSystemUnitCommand);\n\nmanager\n .command('uninstall-system-unit')\n .description('Remove the system-level systemd unit (Linux, root). Idempotent. (ENG-4706)')\n .action(managerUninstallSystemUnitCommand);\n\n// ── Agent inspect commands ────────────────────────────────────────────────\n\nconst agent = program\n .command('agent')\n .description('Inspect and manage agents');\n\nagent\n .command('show <code-name>')\n .description(\"Display an agent's provisioned OpenClaw configuration\")\n .option('--config-dir <dir>', 'Config directory', join(homedir(), '.augmented'))\n .option('--all-channels', 'Show all channels (including disabled)')\n .action(agentShowCommand);\n\n// ── Kanban commands ──────────────────────────────────────────────────────\n\nconst kanban = program\n .command('kanban')\n .description('Manage agent kanban boards');\n\nkanban\n .command('list')\n .description('List kanban board items for an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanListCommand);\n\nkanban\n .command('add <title>')\n .description('Add a new item to an agent kanban board')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--priority <1|2|3>', 'Priority: 1=high, 2=medium, 3=low', '2')\n .option('--status <status>', 'Initial status: backlog | todo | in_progress', 'todo')\n .option('--description <text>', 'Item description')\n .option('--estimate <minutes>', 'Estimated time in minutes')\n .option('--deliverable <text>', 'Expected output/deliverable')\n .action(kanbanAddCommand);\n\nkanban\n .command('move <title-or-id> <status>')\n .description('Move a kanban item to a different status')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--notes <text>', 'Progress notes')\n .action(kanbanMoveCommand);\n\nkanban\n .command('update <title-or-id>')\n .description('Update notes or result on a kanban item')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--notes <text>', 'Progress notes')\n .option('--result <text>', 'Result/output produced')\n .action(kanbanUpdateCommand);\n\nkanban\n .command('done <title-or-id>')\n .description('Mark a kanban item as done')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--result <text>', 'What was produced/delivered')\n .option('--notes <text>', 'Completion notes')\n .action(kanbanDoneCommand);\n\nconst recurring = kanban\n .command('recurring')\n .description('Manage recurring kanban tasks');\n\nrecurring\n .command('add <title>')\n .description('Create a recurring kanban task')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .requiredOption('--every <schedule>', 'Schedule: \"every Monday at 9am\", \"daily at 8:30am\", \"every 2 hours\", or cron')\n .option('--priority <1|2|3>', 'Priority: 1=high, 2=medium, 3=low', '2')\n .option('--description <text>', 'Task description')\n .option('--estimate <minutes>', 'Estimated time in minutes')\n .option('--deliverable <text>', 'Expected output/deliverable')\n .option('--timezone <tz>', 'Timezone (default: UTC)')\n .action(kanbanRecurringAddCommand);\n\nrecurring\n .command('list')\n .description('List recurring kanban templates for an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanRecurringListCommand);\n\nrecurring\n .command('disable <title-or-id>')\n .description('Disable a recurring kanban template')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(kanbanRecurringDisableCommand);\n\n// ── ACPX commands ────────────────────────────────────────────────────────\n\nconst acpx = program\n .command('acpx')\n .description('Agent Client Protocol (ACP) session management via acpx')\n .option('--cwd <path>', 'Working directory for session routing')\n .option('-s, --name <name>', 'Named session for parallel workstreams')\n .option('--approve-all', 'Auto-approve all agent tool permissions')\n .option('--format <type>', 'Output format: text | json | json-strict | quiet', 'text')\n .option('--ttl <seconds>', 'Queue owner idle TTL in seconds (0 = indefinite)')\n .option('--timeout <seconds>', 'Prompt execution timeout')\n .option('--no-wait', 'Submit prompt without waiting for completion');\n\nacpx\n .command('spawn <agent>')\n .description('Spawn or ensure an ACP session for an agent (claude, codex, openclaw)')\n .action(acpxSpawnCommand);\n\nacpx\n .command('prompt <agent> <prompt>')\n .description('Send a prompt to an ACP session')\n .action(acpxPromptCommand);\n\nacpx\n .command('exec <agent> <prompt>')\n .description('One-shot execution (no session reuse)')\n .action(acpxExecCommand);\n\nacpx\n .command('list-sessions <agent>')\n .description('List active ACP sessions for an agent')\n .action(acpxListSessionsCommand);\n\nacpx\n .command('cancel <agent>')\n .description('Send cooperative cancel to the running ACP session')\n .action(acpxCancelCommand);\n\nacpx\n .command('close <agent>')\n .description('Soft-close an ACP session (preserves history)')\n .action(acpxCloseCommand);\n\n// ── Integration commands ─────────────────────────────────────────────────\n\nconst integration = program\n .command('integration')\n .description('Manage integrations — install, configure, and control permission scopes');\n\nintegration\n .command('list')\n .description('List available integrations for the active team')\n .action(integrationListCommand);\n\nintegration\n .command('show <slug>')\n .description('Show integration details including permission scopes')\n .action(integrationShowCommand);\n\nintegration\n .command('install <slug>')\n .description('Install an integration on an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .option('--scopes <scopes>', 'Comma-separated scope IDs to grant')\n .action(integrationInstallCommand);\n\nintegration\n .command('uninstall <slug>')\n .description('Remove an integration from an agent')\n .requiredOption('--agent <code-name>', 'Agent code name')\n .action(integrationUninstallCommand);\n\nintegration\n .command('requests')\n .description('List pending scope approval requests for the team')\n .action(integrationRequestsCommand);\n\nintegration\n .command('approve <request-id>')\n .description('Approve a scope request')\n .option('--notes <text>', 'Review notes')\n .action(integrationApproveCommand);\n\nintegration\n .command('deny <request-id>')\n .description('Deny a scope request')\n .option('--reason <text>', 'Denial reason')\n .action(integrationDenyCommand);\n\nintegration\n .command('enrol')\n .description('Enrol an integration with an API key or webhook secret (no OAuth flow)')\n .requiredOption('--def <code-name>', 'Integration definition code_name (e.g. resend, xero)')\n .requiredOption('--scope <org|team|agent>', 'Install scope')\n .option('--api-key <value>', 'API key (sets auth_type=api_key)')\n .option('--access-token <value>', 'Bearer access token (sets auth_type=oauth2)')\n .option('--webhook-secret <value>', 'Webhook signing secret (sets auth_type=webhook)')\n .option('--display-name <name>', 'Override display name (defaults to the definition’s display_name)')\n .option('--agent <code-name>', 'Agent code name (required for agent scope)')\n .action(integrationEnrolCommand);\n\n// ── Update command ───────────────────────────────────────────────────────\n\nprogram\n .command('update')\n .description('Check for and install CLI updates')\n .option('--force', 'Update even if manager or agent sessions are running')\n .action(updateCommand);\n\n// ENG-5897: regression check for sub-agent MCP-binding gaps. Walks\n// `~/.claude/agents/`, `~/.claude/plugins/<plugin>/agents/`, and the\n// current dir's `.claude/agents/` and reports sub-agents whose\n// `tools:` allowlist would silently block every `mcp__*` tool on\n// dispatch.\nconst audit = program\n .command('audit')\n .description('Operator audits — sub-agent MCP bindings, etc.');\naudit\n .command('subagents')\n .description('Find sub-agents whose tools allowlist would block mcp__* calls on dispatch (ENG-5897)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditSubagentsCommand);\n\n// ENG-5922: runtime check that every managed agent's rendered\n// sub-agent .md `tools:` allowlist covers every server in its actual\n// `.mcp.json`. Catches the staleness Don found on his host (.md had 3\n// wildcards, .mcp.json had 9 keys → sub-agent calls failed with \"No\n// such tool available\" even when the tool was provisioned).\naudit\n .command('mcp-render')\n .description('Find managed agents whose subagent .md tools allowlist is stale vs .mcp.json (ENG-5922)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditMcpRenderCommand);\n\n// ENG-5901 (ADR-0018 Phase 1): operator-side scan for literal secrets in\n// `~/.augmented/<agent>/{provision,project}/.mcp.json` (should be `${VAR}`\n// placeholders) and world-readable secret files (.mcp.json / .env.integrations\n// should be 0600). Companion to the contributor-side runtime lint.\naudit\n .command('secrets')\n .description('Find literal secrets in .mcp.json and world-readable secret files (ENG-5901)')\n .option('--strict', 'Exit with code 2 if any findings (suitable for CI gating)')\n .option('--json', 'Emit findings as JSON to stdout')\n .action(auditSecretsCommand);\n\n// ── Parse & run ────────────────────────────────────────────────────────────\n\n// Non-blocking startup update check (fire-and-forget, resolves after parse)\nconst skipUpdateCheck =\n process.argv.includes('--skip-update-check') ||\n process.argv.includes('--json') ||\n process.argv[2] === 'update';\n\nif (!skipUpdateCheck) {\n // Fire the check but don't await — it prints to stderr if an update is found\n checkForUpdateOnStartup().catch(() => {});\n}\n\n// parseAsync (not parse) so the async pre-action hook — which may auto-exit an\n// expired impersonation session — is awaited before the command's action runs.\nprogram.parseAsync().catch((err) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n});\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { getApiKey, getHost } from '../lib/config.js';\nimport { exchangeApiKey } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nexport async function whoamiCommand(): Promise<void> {\n const json = isJsonMode();\n const apiKey = getApiKey();\n\n if (!apiKey) {\n if (json) {\n jsonOutput({ ok: false, error: 'AGT_API_KEY is not set' });\n } else {\n error('AGT_API_KEY is not set. Export it with your host API key (tlk_...)');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Exchanging API key\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const exchange = await exchangeApiKey(apiKey);\n spinner.stop();\n\n const framework = exchange.framework ?? 'unset';\n const claudeAuthLabel = exchange.claudeAuthMode === 'api_key'\n ? `api_key (fp: ${exchange.anthropicApiKeyFingerprint ?? 'unknown'})`\n : 'subscription';\n\n if (json) {\n jsonOutput({\n ok: true,\n api_key_prefix: apiKey.slice(0, 8) + '****',\n host: getHost(),\n host_id: exchange.hostId,\n team: exchange.teamSlug,\n team_id: exchange.teamId,\n email: exchange.userEmail,\n framework: exchange.framework,\n claude_auth_mode: exchange.claudeAuthMode,\n anthropic_api_key_fingerprint: exchange.anthropicApiKeyFingerprint,\n });\n return;\n }\n\n success('Authenticated via API key');\n info(`API Key: ${chalk.bold(apiKey.slice(0, 8) + '****')}`);\n info(`Host: ${chalk.bold(getHost())}`);\n info(`Host ID: ${exchange.hostId}`);\n info(`Team: ${chalk.bold(exchange.teamSlug ?? exchange.teamId)}`);\n info(`User: ${chalk.bold(exchange.userEmail ?? 'unknown')}`);\n info(`Framework: ${chalk.bold(framework)}`);\n if (framework === 'claude-code') {\n info(`Claude Auth: ${chalk.bold(claudeAuthLabel)}`);\n }\n } catch (err) {\n spinner.fail('Failed to exchange API key.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { setActiveTeam, getActiveTeam } from '../lib/config.js';\nimport { api } from '../lib/api-client.js';\nimport { requireAuth } from '../lib/auth-guard.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\n/**\n * `agt team list`\n * Fetch teams where the current user is a member and display as a table.\n */\nexport async function teamListCommand(): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching teams\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n teams: Array<{\n id: string;\n name: string;\n slug: string;\n plan: string;\n role: string;\n created_at: string;\n }>;\n }>('/teams');\n\n spinner.stop();\n\n if (!data.teams || data.teams.length === 0) {\n if (json) {\n jsonOutput({ ok: true, teams: [] });\n } else {\n info('You are not a member of any teams. Create one with `agt team create <name>`.');\n }\n return;\n }\n\n const activeSlug = getActiveTeam();\n\n if (json) {\n const teams = data.teams.map((ws) => ({\n name: ws.name,\n slug: ws.slug,\n role: ws.role,\n active: ws.slug === activeSlug,\n }));\n jsonOutput({ ok: true, teams });\n return;\n }\n\n const rows = data.teams.map((ws) => {\n const active = ws.slug === activeSlug ? chalk.green('*') : '';\n return [active, ws.name, ws.slug, ws.role];\n });\n\n table(['', 'Name', 'Slug', 'Role'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch teams.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt team create <name>`\n * Create a new team, add the creator as owner, and set it as active.\n */\nexport async function teamCreateCommand(name: string): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const slug = name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n if (!slug) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid team name' });\n } else {\n error('Invalid team name. It must contain at least one alphanumeric character.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: `Creating team \"${name}\" (${slug})\\u2026`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.post<{\n team: { id: string; name: string; slug: string; plan: string; role: string };\n }>('/teams', { name, slug });\n\n // Set as active\n setActiveTeam(data.team.slug);\n\n spinner.succeed(`Team \"${chalk.bold(name)}\" created.`);\n\n if (json) {\n jsonOutput({ ok: true, name, slug: data.team.slug, role: data.team.role });\n return;\n }\n\n info(`Slug: ${chalk.bold(data.team.slug)}`);\n success(`Active team set to ${chalk.bold(data.team.slug)}.`);\n } catch (err) {\n spinner.fail('Failed to create team.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt team switch <slug>`\n * Verify the user is a member of the team and set it as active.\n */\nexport async function teamSwitchCommand(slug: string): Promise<void> {\n if (!requireAuth()) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Switching to team \"${slug}\"\\u2026`, isSilent: json });\n spinner.start();\n\n try {\n await api.get(`/teams/${encodeURIComponent(slug)}`);\n\n setActiveTeam(slug);\n spinner.succeed(`Active team set to ${chalk.bold(slug)}.`);\n\n if (json) {\n jsonOutput({ ok: true, team: slug });\n }\n } catch (err) {\n spinner.fail(`Could not switch to team \"${slug}\".`);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { getApiKey } from './config.js';\nimport { error } from './output.js';\n\n/**\n * Guard: checks that AGT_API_KEY is set.\n * Returns false (and prints an error) if not.\n */\nexport function requireAuth(): boolean {\n const key = getApiKey();\n if (!key) {\n error('AGT_API_KEY is not set. Export it with your host API key (tlk_...)');\n process.exitCode = 1;\n return false;\n }\n return true;\n}\n\n/**\n * Guard: checks that AGT_API_KEY is set.\n * Team auto-resolves from the API key exchange.\n * Returns a truthy string on success, or null on failure.\n */\nexport function requireTeam(): string | null {\n if (!requireAuth()) return null;\n return 'auto'; // team resolves from exchange\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { input, select, checkbox, confirm } from '@inquirer/prompts';\nimport { randomUUID } from 'node:crypto';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n generateCharterMd,\n generateToolsMd,\n lintAll,\n getAllChannelIds,\n type CharterGenerationInput,\n type ToolsGenerationInput,\n type ChannelId,\n type LintDiagnostic,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction toSlug(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} [${d.code}] ${d.message}${path}`);\n }\n}\n\n/** Options passed from Commander flags. */\ninterface InitOptions {\n name?: string;\n codeName?: string;\n description?: string;\n env?: string;\n riskTier?: string;\n budgetType?: string;\n budgetTokens?: string;\n budgetDollars?: string;\n budgetWindow?: string;\n budgetEnforcement?: string;\n channels?: string;\n logging?: string;\n}\n\n/**\n * `agt init`\n * Interactive wizard to create a new agent, generate CHARTER.md + TOOLS.md,\n * register via the API, and write files to `.augmented/<code_name>/`.\n */\nexport async function initCommand(opts: InitOptions): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const nonInteractive = !!opts.name;\n const json = isJsonMode();\n\n let displayName: string;\n let codeName: string;\n let description: string;\n let environment: 'dev' | 'stage' | 'prod';\n let riskTier: 'Low' | 'Medium' | 'High';\n let budgetType: 'tokens' | 'dollars' | 'both';\n let budgetLimitTokens: number | undefined;\n let budgetLimitDollars: number | undefined;\n let budgetLimit: number;\n let budgetWindow: 'daily' | 'weekly' | 'monthly';\n let budgetEnforcement: 'alert' | 'throttle' | 'block' | 'degrade';\n let selectedChannels: ChannelId[];\n let loggingMode: 'hash-only' | 'redacted' | 'full-local';\n\n if (nonInteractive) {\n displayName = opts.name!;\n codeName = opts.codeName ?? toSlug(displayName);\n description = opts.description ?? `${displayName} agent`;\n environment = (opts.env ?? 'dev') as 'dev' | 'stage' | 'prod';\n riskTier = (opts.riskTier ?? 'Low') as 'Low' | 'Medium' | 'High';\n budgetType = (opts.budgetType ?? 'tokens') as 'tokens' | 'dollars' | 'both';\n budgetLimitTokens = (budgetType === 'tokens' || budgetType === 'both')\n ? Number(opts.budgetTokens ?? '10000')\n : undefined;\n budgetLimitDollars = (budgetType === 'dollars' || budgetType === 'both')\n ? Number(opts.budgetDollars ?? '10')\n : undefined;\n budgetLimit = budgetLimitTokens ?? budgetLimitDollars ?? 10000;\n budgetWindow = (opts.budgetWindow ?? 'daily') as 'daily' | 'weekly' | 'monthly';\n budgetEnforcement = (opts.budgetEnforcement ?? 'block') as 'alert' | 'throttle' | 'block' | 'degrade';\n selectedChannels = opts.channels\n ? opts.channels.split(',').map((c) => c.trim()) as ChannelId[]\n : [];\n loggingMode = (opts.logging ?? 'redacted') as 'hash-only' | 'redacted' | 'full-local';\n } else {\n console.log(chalk.bold('\\nAugmented — Agent Init Wizard\\n'));\n\n displayName = await input({\n message: 'Agent display name:',\n validate: (v) => v.trim().length > 0 || 'Name is required',\n });\n\n const suggestedSlug = toSlug(displayName);\n codeName = await input({\n message: 'Code name (kebab-case):',\n default: suggestedSlug,\n validate: (v) => /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(v) || 'Must be lowercase alphanumeric with hyphens',\n });\n\n description = await input({\n message: 'Short description:',\n default: `${displayName} agent`,\n });\n\n environment = await select({\n message: 'Environment:',\n choices: [\n { value: 'dev', name: 'dev' },\n { value: 'stage', name: 'stage' },\n { value: 'prod', name: 'prod' },\n ],\n }) as 'dev' | 'stage' | 'prod';\n\n riskTier = await select({\n message: 'Risk tier:',\n choices: [\n { value: 'Low', name: 'Low — read-only tools, no PII' },\n { value: 'Medium', name: 'Medium — write access, limited scope' },\n { value: 'High', name: 'High — broad access, PII, external comms' },\n ],\n }) as 'Low' | 'Medium' | 'High';\n\n budgetType = await select({\n message: 'Budget type:',\n choices: [\n { value: 'tokens', name: 'Tokens' },\n { value: 'dollars', name: 'Dollars' },\n { value: 'both', name: 'Both' },\n ],\n }) as 'tokens' | 'dollars' | 'both';\n\n budgetLimit = 10000;\n budgetLimitTokens = undefined;\n budgetLimitDollars = undefined;\n\n if (budgetType === 'tokens' || budgetType === 'both') {\n const val = await input({\n message: 'Token budget limit:',\n default: '10000',\n validate: (v) => !isNaN(Number(v)) && Number(v) > 0 || 'Must be a positive number',\n });\n budgetLimitTokens = Number(val);\n budgetLimit = budgetLimitTokens;\n }\n\n if (budgetType === 'dollars' || budgetType === 'both') {\n const val = await input({\n message: 'Dollar budget limit:',\n default: '10',\n validate: (v) => !isNaN(Number(v)) && Number(v) > 0 || 'Must be a positive number',\n });\n budgetLimitDollars = Number(val);\n if (budgetType === 'dollars') budgetLimit = budgetLimitDollars;\n }\n\n budgetWindow = await select({\n message: 'Budget window:',\n choices: [\n { value: 'daily', name: 'Daily' },\n { value: 'weekly', name: 'Weekly' },\n { value: 'monthly', name: 'Monthly' },\n ],\n }) as 'daily' | 'weekly' | 'monthly';\n\n budgetEnforcement = await select({\n message: 'Budget enforcement:',\n choices: [\n { value: 'block', name: 'Block — hard stop when limit reached' },\n { value: 'throttle', name: 'Throttle — slow down near limit' },\n { value: 'alert', name: 'Alert — warn but do not stop' },\n { value: 'degrade', name: 'Degrade — switch to cheaper model' },\n ],\n }) as 'alert' | 'throttle' | 'block' | 'degrade';\n\n const allChannels = getAllChannelIds();\n selectedChannels = await checkbox({\n message: 'Select allowed channels:',\n choices: allChannels.map((c) => ({ value: c, name: c })),\n }) as ChannelId[];\n\n loggingMode = await select({\n message: 'Logging mode:',\n choices: [\n { value: 'redacted', name: 'Redacted — PII stripped' },\n { value: 'hash-only', name: 'Hash-only — content is hashed' },\n { value: 'full-local', name: 'Full local — plain text (dev only)' },\n ],\n }) as 'hash-only' | 'redacted' | 'full-local';\n }\n\n // ── Resolve user info via API ─────────────────────────────────────────\n\n const spinner = ora({ text: 'Creating agent…', isSilent: json });\n spinner.start();\n\n let userEmail: string;\n let userId: string;\n try {\n const me = await api.get<{ id: string; email: string | null }>('/auth/me');\n userId = me.id;\n userEmail = me.email ?? me.id;\n } catch (err) {\n spinner.fail('Could not determine current user.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const agentId = randomUUID();\n\n // ── Generate CHARTER.md + TOOLS.md ─────────────────────────────────────\n\n const charterInput: CharterGenerationInput = {\n agent_id: agentId,\n code_name: codeName,\n display_name: displayName,\n environment,\n owner: {\n id: userId,\n name: userEmail,\n email: userEmail,\n },\n risk_tier: riskTier,\n logging_mode: loggingMode,\n description,\n };\n\n const toolsInput: ToolsGenerationInput = {\n agent_id: agentId,\n code_name: codeName,\n environment,\n owner: userEmail,\n display_name: displayName,\n logging_redaction: loggingMode,\n };\n\n const charterMd = generateCharterMd(charterInput);\n const toolsMd = generateToolsMd(toolsInput);\n\n // ── Lint ────────────────────────────────────────────────────────────────\n\n const lintResult = lintAll(charterMd, toolsMd);\n\n // ── Register via API ───────────────────────────────────────────────────\n\n try {\n await api.post('/agents', {\n code_name: codeName,\n display_name: displayName,\n description,\n environment,\n risk_tier: riskTier,\n channels: selectedChannels,\n charter_content: charterMd,\n charter_version: '0.1',\n tools_content: toolsMd,\n tools_version: '0.1',\n });\n } catch (err) {\n spinner.fail('Failed to register agent.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Write files to .augmented/<code_name>/ ─────────────────────────────\n\n const agentDir = join(process.cwd(), '.augmented', codeName);\n mkdirSync(agentDir, { recursive: true });\n writeFileSync(join(agentDir, 'CHARTER.md'), charterMd);\n writeFileSync(join(agentDir, 'TOOLS.md'), toolsMd);\n\n spinner.succeed(`Agent \"${chalk.bold(displayName)}\" created.`);\n\n // ── Output ─────────────────────────────────────────────────────────────\n\n if (json) {\n jsonOutput({\n ok: true,\n agent_id: agentId,\n code_name: codeName,\n display_name: displayName,\n environment,\n risk_tier: riskTier,\n channels: selectedChannels,\n directory: agentDir,\n lint: {\n ok: lintResult.ok,\n errors: lintResult.errors.length,\n warnings: lintResult.warnings.length,\n diagnostics: [...lintResult.errors, ...lintResult.warnings],\n },\n });\n return;\n }\n\n console.log();\n info(`Agent ID: ${agentId}`);\n info(`Code Name: ${codeName}`);\n info(`Environment: ${environment}`);\n info(`Risk Tier: ${riskTier}`);\n info(`Channels: ${selectedChannels.length > 0 ? selectedChannels.join(', ') : 'none'}`);\n info(`Files: ${agentDir}/CHARTER.md, TOOLS.md`);\n console.log();\n\n if (lintResult.ok && lintResult.warnings.length === 0) {\n success('Lint passed — no errors or warnings.');\n } else {\n if (lintResult.errors.length > 0) {\n error(`Lint: ${lintResult.errors.length} error(s)`);\n printDiagnostics(lintResult.errors);\n }\n if (lintResult.warnings.length > 0) {\n warn(`Lint: ${lintResult.warnings.length} warning(s)`);\n printDiagnostics(lintResult.warnings);\n }\n }\n\n console.log();\n info(`Next steps:`);\n info(` 1. Edit ${chalk.bold('.augmented/' + codeName + '/CHARTER.md')} to refine the agent charter`);\n info(` 2. Edit ${chalk.bold('.augmented/' + codeName + '/TOOLS.md')} to add tools`);\n info(` 3. Run ${chalk.bold('agt lint')} to validate`);\n info(` 4. Run ${chalk.bold('agt deploy')} to generate deployment config`);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport {\n lintCharter,\n lintTools,\n lintAll,\n type LintDiagnostic,\n type LintResult,\n type OrgChannelPolicy,\n type ChannelId,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const file = chalk.dim(`[${d.file}]`);\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} ${file} ${d.code}: ${d.message}${path}`);\n }\n}\n\nfunction printResult(label: string, result: LintResult): void {\n if (result.ok && result.warnings.length === 0) {\n success(`${label}: passed`);\n return;\n }\n if (result.errors.length > 0) {\n error(`${label}: ${result.errors.length} error(s)`);\n printDiagnostics(result.errors);\n }\n if (result.warnings.length > 0) {\n warn(`${label}: ${result.warnings.length} warning(s)`);\n printDiagnostics(result.warnings);\n }\n}\n\n/**\n * `agt lint [path]`\n */\nexport async function lintCommand(path?: string): Promise<void> {\n const json = isJsonMode();\n\n const dirs: { name: string; dir: string }[] = [];\n\n if (path) {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n if (json) {\n jsonOutput({ ok: false, error: `Path not found: ${resolved}` });\n } else {\n error(`Path not found: ${resolved}`);\n }\n process.exitCode = 1;\n return;\n }\n dirs.push({ name: path, dir: resolved });\n } else {\n const augmentedDir = join(process.cwd(), '.augmented');\n if (!existsSync(augmentedDir)) {\n if (json) {\n jsonOutput({ ok: false, error: 'No .augmented/ directory found' });\n } else {\n error('No .augmented/ directory found. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n\n const { readdirSync, statSync } = await import('node:fs');\n const entries = readdirSync(augmentedDir);\n for (const entry of entries) {\n const entryPath = join(augmentedDir, entry);\n if (statSync(entryPath).isDirectory()) {\n dirs.push({ name: entry, dir: entryPath });\n }\n }\n\n if (dirs.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'No agent directories found in .augmented/' });\n } else {\n error('No agent directories found in .augmented/. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n // Optionally fetch team channel policy via API\n let orgPolicy: OrgChannelPolicy | undefined;\n const teamSlug = requireTeam();\n if (teamSlug) {\n const spinner = ora({ text: 'Fetching org channel policy…', isSilent: json });\n spinner.start();\n try {\n const data = await api.get<{\n channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n }>(`/teams/${encodeURIComponent(teamSlug)}/channel-policy`);\n\n if (data.channel_policy) {\n orgPolicy = {\n organization_id: data.channel_policy.team_id,\n allowed_channels: (data.channel_policy.allowed_channels ?? []) as ChannelId[],\n denied_channels: (data.channel_policy.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: data.channel_policy.require_elevated_for_pii ?? false,\n };\n }\n spinner.stop();\n } catch {\n spinner.stop();\n // Non-fatal — lint without org policy\n }\n }\n\n let totalErrors = 0;\n let totalWarnings = 0;\n const jsonResults: Record<string, unknown>[] = [];\n\n for (const { name, dir } of dirs) {\n if (!json) console.log(chalk.bold(`\\nLinting ${name}:`));\n\n const charterPath = join(dir, 'CHARTER.md');\n const toolsPath = join(dir, 'TOOLS.md');\n const hasCharter = existsSync(charterPath);\n const hasTools = existsSync(toolsPath);\n\n if (!hasCharter && !hasTools) {\n if (!json) warn('No CHARTER.md or TOOLS.md found — skipping.');\n if (json) jsonResults.push({ agent: name, skipped: true });\n continue;\n }\n\n const charterContent = hasCharter ? readFileSync(charterPath, 'utf-8') : undefined;\n const toolsContent = hasTools ? readFileSync(toolsPath, 'utf-8') : undefined;\n\n let result: LintResult;\n if (charterContent && toolsContent) {\n result = lintAll(charterContent, toolsContent, { orgChannelPolicy: orgPolicy });\n if (!json) printResult('Full lint', result);\n } else if (charterContent) {\n result = lintCharter(charterContent, { orgChannelPolicy: orgPolicy });\n if (!json) printResult('CHARTER.md', result);\n } else {\n result = lintTools(toolsContent!);\n if (!json) printResult('TOOLS.md', result);\n }\n\n totalErrors += result.errors.length;\n totalWarnings += result.warnings.length;\n\n if (json) {\n jsonResults.push({\n agent: name,\n ok: result.ok,\n errors: result.errors.length,\n warnings: result.warnings.length,\n diagnostics: [...result.errors, ...result.warnings],\n });\n }\n }\n\n if (json) {\n jsonOutput({\n ok: totalErrors === 0,\n agents: jsonResults,\n total_errors: totalErrors,\n total_warnings: totalWarnings,\n });\n if (totalErrors > 0) process.exitCode = 1;\n return;\n }\n\n console.log();\n if (totalErrors === 0 && totalWarnings === 0) {\n success(`All ${dirs.length} agent(s) passed lint.`);\n } else {\n if (totalErrors > 0) {\n error(`Total: ${totalErrors} error(s) across ${dirs.length} agent(s)`);\n process.exitCode = 1;\n }\n if (totalWarnings > 0) {\n warn(`Total: ${totalWarnings} warning(s) across ${dirs.length} agent(s)`);\n }\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport {\n CHANNEL_REGISTRY,\n getChannel,\n resolveChannels,\n type ChannelId,\n type ChannelPolicy,\n type OrgChannelPolicy,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n/**\n * `agt channels list`\n */\nexport function channelsListCommand(): void {\n const json = isJsonMode();\n\n if (json) {\n const channels = CHANNEL_REGISTRY.map((ch) => ({\n id: ch.id,\n name: ch.name,\n security_tier: ch.securityTier,\n e2e_encrypted: ch.e2eEncrypted,\n audit_trail: ch.auditTrail,\n public_exposure_risk: ch.publicExposureRisk,\n }));\n jsonOutput({ ok: true, channels });\n return;\n }\n\n console.log(chalk.bold('\\nChannel Registry (18 channels)\\n'));\n\n const rows = CHANNEL_REGISTRY.map((ch) => [\n ch.id,\n ch.name,\n ch.securityTier === 'elevated'\n ? chalk.green(ch.securityTier)\n : ch.securityTier === 'limited'\n ? chalk.red(ch.securityTier)\n : chalk.cyan(ch.securityTier),\n typeof ch.e2eEncrypted === 'boolean'\n ? (ch.e2eEncrypted ? chalk.green('yes') : chalk.dim('no'))\n : chalk.yellow(ch.e2eEncrypted),\n typeof ch.auditTrail === 'boolean'\n ? (ch.auditTrail ? chalk.green('yes') : chalk.dim('no'))\n : chalk.yellow(ch.auditTrail),\n ch.publicExposureRisk === 'High'\n ? chalk.red(ch.publicExposureRisk)\n : ch.publicExposureRisk === 'Medium'\n ? chalk.yellow(ch.publicExposureRisk)\n : chalk.green(ch.publicExposureRisk),\n ]);\n\n table(['ID', 'Name', 'Security Tier', 'E2E Encrypted', 'Audit Trail', 'Public Risk'], rows);\n}\n\n/**\n * `agt channels check <agent>`\n */\nexport async function channelsCheckCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Resolving channels for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n agent_channels: string[];\n channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channels`);\n\n const agentPolicy: ChannelPolicy = {\n policy: 'allowlist',\n allowed: (data.agent_channels ?? []) as ChannelId[],\n denied: [],\n require_approval_to_change: false,\n };\n\n const orgPolicy: OrgChannelPolicy | undefined = data.channel_policy\n ? {\n organization_id: data.channel_policy.team_id,\n allowed_channels: (data.channel_policy.allowed_channels ?? []) as ChannelId[],\n denied_channels: (data.channel_policy.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: data.channel_policy.require_elevated_for_pii ?? false,\n }\n : undefined;\n\n const resolved = resolveChannels(agentPolicy, orgPolicy);\n\n spinner.stop();\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n agent_allowlist: agentPolicy.allowed,\n org_policy: orgPolicy\n ? {\n allowed: orgPolicy.allowed_channels,\n denied: orgPolicy.denied_channels,\n require_elevated_for_pii: orgPolicy.require_elevated_for_pii,\n }\n : null,\n resolved_channels: resolved,\n count: resolved.length,\n });\n return;\n }\n\n console.log(chalk.bold(`\\nChannel Resolution: ${agentCodeName}\\n`));\n\n info(`Agent allowlist: ${agentPolicy.allowed.length > 0 ? agentPolicy.allowed.join(', ') : 'none'}`);\n\n if (orgPolicy) {\n info(`Org allowed: ${orgPolicy.allowed_channels.length > 0 ? orgPolicy.allowed_channels.join(', ') : 'all (no restriction)'}`);\n info(`Org denied: ${orgPolicy.denied_channels.length > 0 ? orgPolicy.denied_channels.join(', ') : 'none'}`);\n if (orgPolicy.require_elevated_for_pii) {\n info('Org requires elevated tier for PII channels');\n }\n } else {\n info('No org channel policy configured.');\n }\n\n console.log();\n\n if (resolved.length === 0) {\n error('No channels available after resolution. The agent cannot communicate.');\n process.exitCode = 1;\n return;\n }\n\n const rows = resolved.map((chId) => {\n const ch = getChannel(chId);\n return [\n chId,\n ch?.name ?? 'Unknown',\n ch?.securityTier ?? '-',\n ch?.publicExposureRisk ?? '-',\n ];\n });\n\n success(`${resolved.length} channel(s) available:`);\n table(['ID', 'Name', 'Security Tier', 'Public Risk'], rows);\n } catch (err) {\n spinner.fail('Failed to resolve channels.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { checkbox, confirm, input } from '@inquirer/prompts';\nimport {\n getDefaultSlackScopes,\n getScopesByCategory,\n SLACK_SCOPE_CATEGORY_LABELS,\n SLACK_SCOPE_PRESETS,\n generateSlackAppManifest,\n serializeManifestForSlackCli,\n createSlackApp,\n SlackApiError,\n type SlackScope,\n type SlackScopeCategory,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, warn, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nimport { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\n/**\n * `agt channels slack setup <agent-code-name>`\n */\nexport async function channelSlackSetupCommand(\n agentCodeName: string,\n options: {\n preset?: string;\n scopes?: string;\n skipCreate?: boolean;\n botToken?: string;\n signingSecret?: string;\n configToken?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Look up agent via API\n const agentData = await api.get<{\n agent: {\n agent_id: string;\n code_name: string;\n display_name: string;\n channels: string[];\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}`);\n\n const agent = agentData.agent;\n\n // Verify slack is in the agent's channel list\n const channels: string[] = agent.channels ?? [];\n if (!channels.includes('slack')) {\n spinner.fail(`Agent \"${agentCodeName}\" does not have Slack in its channel list.`);\n error('Enable Slack in the agent\\'s channels first (add \"slack\" to the channels array).');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed(`Found agent \"${agentCodeName}\"`);\n\n // ── Scope selection ─────────────────────────────────────────────────\n let selectedScopes: SlackScope[];\n\n if (options.scopes) {\n selectedScopes = options.scopes.split(',').map((s) => s.trim()) as SlackScope[];\n } else if (options.preset) {\n const preset = options.preset as keyof typeof SLACK_SCOPE_PRESETS;\n if (!(preset in SLACK_SCOPE_PRESETS)) {\n error(`Unknown preset \"${options.preset}\". Available: minimal, standard, full`);\n process.exitCode = 1;\n return;\n }\n selectedScopes = [...SLACK_SCOPE_PRESETS[preset]];\n info(`Using \"${preset}\" preset (${selectedScopes.length} scopes)`);\n } else if (json) {\n selectedScopes = [...SLACK_SCOPE_PRESETS.standard];\n } else {\n const scopesByCategory = getScopesByCategory();\n const defaults = getDefaultSlackScopes();\n\n type CheckboxChoice = { name: string; value: SlackScope; checked: boolean };\n type CheckboxSeparator = { type: 'separator'; separator: string };\n const choices: Array<CheckboxChoice | CheckboxSeparator> = [];\n for (const [category, defs] of scopesByCategory) {\n const label = SLACK_SCOPE_CATEGORY_LABELS[category as SlackScopeCategory];\n choices.push({ type: 'separator', separator: `── ${label} ──` });\n for (const def of defs) {\n const riskColor =\n def.risk === 'high' ? chalk.red : def.risk === 'medium' ? chalk.yellow : chalk.green;\n choices.push({\n name: `${def.scope} ${chalk.dim(`— ${def.description}`)} ${riskColor(`[${def.risk}]`)}`,\n value: def.scope,\n checked: defaults.includes(def.scope),\n });\n }\n }\n\n selectedScopes = await checkbox({\n message: 'Select Slack bot scopes:',\n choices,\n pageSize: 30,\n });\n }\n\n if (selectedScopes.length === 0) {\n error('No scopes selected. At least one scope is required.');\n process.exitCode = 1;\n return;\n }\n\n info(`Selected ${selectedScopes.length} scope(s): ${selectedScopes.join(', ')}`);\n\n // ── Generate manifest ───────────────────────────────────────────────\n const manifest = generateSlackAppManifest({\n agent_name: agent.display_name ?? agentCodeName,\n description: `Augmented-managed Slack bot for agent ${agentCodeName}`,\n scopes: selectedScopes,\n });\n\n const manifestObj = serializeManifestForSlackCli(manifest);\n\n const manifestJson = JSON.stringify(manifestObj, null, 2);\n const manifestPath = join(tmpdir(), `augmented-slack-manifest-${agentCodeName}.json`);\n await writeFile(manifestPath, manifestJson, 'utf-8');\n\n success(`Manifest written to ${manifestPath}`);\n console.log(chalk.dim(manifestJson));\n\n // ── Slack app creation via API ──────────────────────────────────────\n let appId: string | undefined;\n let botTokenRef: string | undefined = options.botToken;\n let signingSecretRef: string | undefined = options.signingSecret;\n\n if (!options.skipCreate) {\n let token = options.configToken;\n if (!token && !json) {\n token = (await input({\n message: 'Paste your Slack config token (xoxe-…) to create the app automatically, or leave empty to skip:',\n })).trim() || undefined;\n }\n\n if (token) {\n const createSpinner = ora({ text: 'Creating Slack app via API…', isSilent: json });\n createSpinner.start();\n\n try {\n const result = await createSlackApp(token, manifest);\n appId = result.app_id;\n signingSecretRef = `secret_ref://slack/${agentCodeName}/signing_secret`;\n createSpinner.succeed(`Slack app created: ${result.app_id}`);\n info(`OAuth URL: ${result.oauth_authorize_url}`);\n } catch (err) {\n createSpinner.fail('Failed to create Slack app via API.');\n if (err instanceof SlackApiError) {\n warn(`Slack API error: ${err.message}`);\n } else {\n warn((err as Error).message);\n }\n info(`Manifest saved at: ${manifestPath}`);\n info('Create the app manually via https://api.slack.com/apps and paste the manifest.');\n }\n } else {\n info(`Manifest saved at: ${manifestPath}`);\n info('Create the app manually via https://api.slack.com/apps and paste the manifest.');\n }\n }\n\n if (!signingSecretRef && !json) {\n const secret = await input({\n message: 'Paste your Slack Signing Secret, or leave empty to skip:',\n });\n if (secret.trim()) {\n signingSecretRef = `secret_ref://slack/${agentCodeName}/signing_secret`;\n }\n }\n\n if (!botTokenRef && !json) {\n const token = await input({\n message: 'Paste your Slack Bot Token (xoxb-…), or leave empty to skip:',\n });\n if (token.trim()) {\n botTokenRef = `secret_ref://slack/${agentCodeName}/bot_token`;\n }\n }\n\n // ── Store config via API ────────────────────────────────────────────\n const configSpinner = ora({ text: 'Saving channel config…', isSilent: json });\n configSpinner.start();\n\n const config = {\n channel_type: 'slack' as const,\n app_name: agent.display_name ?? agentCodeName,\n scopes: selectedScopes,\n ...(appId ? { app_id: appId } : {}),\n ...(botTokenRef ? { bot_token_ref: botTokenRef } : {}),\n ...(signingSecretRef ? { signing_secret_ref: signingSecretRef } : {}),\n manifest,\n };\n\n try {\n await api.put(\n `/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`,\n {\n config,\n status: botTokenRef ? 'configured' : 'pending',\n },\n );\n } catch (err) {\n configSpinner.fail('Failed to save channel config.');\n error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n\n configSpinner.succeed('Slack channel config saved.');\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n channel: 'slack',\n scopes: selectedScopes,\n status: botTokenRef ? 'configured' : 'pending',\n manifest_path: manifestPath,\n });\n } else {\n console.log();\n success(`Slack setup complete for \"${agentCodeName}\"`);\n info(`Status: ${botTokenRef ? 'configured' : 'pending (add credentials to activate)'}`);\n }\n } catch (err) {\n spinner.fail('Slack setup failed.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels slack status <agent-code-name>`\n */\nexport async function channelSlackStatusCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Fetching Slack config for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n config: {\n channel_type: string;\n app_name?: string;\n scopes?: string[];\n bot_token_ref?: string;\n signing_secret_ref?: string;\n app_id?: string;\n team_id?: string;\n status?: string;\n created_at?: string;\n updated_at?: string;\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n\n spinner.stop();\n\n const config = data.config;\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: agentCodeName,\n channel: 'slack',\n configured: true,\n config,\n });\n return;\n }\n\n console.log(chalk.bold(`\\nSlack Configuration: ${agentCodeName}\\n`));\n\n const rows: string[][] = [\n ['App Name', config.app_name ?? '-'],\n ['App ID', config.app_id ?? '-'],\n ['Team ID', config.team_id ?? '-'],\n ['Bot Token', config.bot_token_ref ? chalk.green('configured') : chalk.dim('not set')],\n ['Signing Secret', config.signing_secret_ref ? chalk.green('configured') : chalk.dim('not set')],\n ['Scopes', (config.scopes ?? []).join(', ') || '-'],\n ];\n\n table(['Field', 'Value'], rows);\n } catch (err) {\n spinner.stop();\n if ((err as any).status === 404) {\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', configured: false });\n } else {\n warn(`No Slack configuration found for \"${agentCodeName}\".`);\n info('Run `agt channels slack setup ' + agentCodeName + '` to configure.');\n }\n return;\n }\n\n spinner.fail('Failed to fetch Slack status.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels slack remove <agent-code-name>`\n */\nexport async function channelSlackRemoveCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Check if config exists\n let config: { app_id?: string; app_name?: string } | null = null;\n try {\n const data = await api.get<{ config: { app_id?: string; app_name?: string } | null }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n config = data.config;\n } catch (err) {\n if ((err as any).status === 404) {\n spinner.info(`No Slack configuration found for \"${agentCodeName}\".`);\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', removed: false, reason: 'not_configured' });\n }\n return;\n }\n throw err;\n }\n\n spinner.stop();\n\n // Confirm removal\n if (!json) {\n const appLabel = config?.app_id\n ? ` (App ID: ${config.app_id})`\n : config?.app_name\n ? ` (${config.app_name})`\n : '';\n const confirmed = await confirm({\n message: `Remove Slack bot configuration${appLabel} for \"${agentCodeName}\"?`,\n default: false,\n });\n\n if (!confirmed) {\n warn('Aborted.');\n return;\n }\n }\n\n const removeSpinner = ora({ text: 'Removing Slack configuration…', isSilent: json });\n removeSpinner.start();\n\n await api.del(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/slack`);\n\n removeSpinner.succeed('Slack configuration removed.');\n\n if (json) {\n jsonOutput({ ok: true, agent: agentCodeName, channel: 'slack', removed: true });\n } else {\n if (config?.app_id) {\n console.log();\n info(`Note: The Slack app (${config.app_id}) still exists in your Slack workspace.`);\n info('Delete it manually at https://api.slack.com/apps if no longer needed.');\n }\n }\n } catch (err) {\n error((err as Error).message);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n }\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { confirm } from '@inquirer/prompts';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n/**\n * `agt channels beam setup <agent-code-name>`\n */\nexport async function channelBeamSetupCommand(\n agentCodeName: string,\n options: {\n directoryUrl?: string;\n skipRegister?: boolean;\n autoPublish?: boolean;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Looking up agent \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n // Look up agent via API\n const agentData = await api.get<{\n agent: {\n agent_id: string;\n code_name: string;\n display_name: string;\n team_id: string;\n channels: string[];\n };\n }>(`/agents/${encodeURIComponent(agentCodeName)}`);\n\n const agent = agentData.agent;\n\n // Verify beam is in the agent's channel list\n const channels: string[] = agent.channels ?? [];\n if (!channels.includes('beam')) {\n spinner.fail(`Agent \"${agentCodeName}\" does not have Beam in its channel list.`);\n error('Enable Beam in the agent\\'s channels first (add \"beam\" to the channels array).');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed(`Found agent \"${agentCodeName}\"`);\n\n // Check for existing config\n const existingConfig = await api.get<{\n config: Record<string, unknown> | null;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`).catch(() => ({ config: null }));\n\n if (existingConfig.config?.beam_id) {\n info(`Agent already has Beam identity: ${chalk.cyan(String(existingConfig.config.beam_id))}`);\n const proceed = await confirm({\n message: 'Regenerate identity? This will create a new keypair and re-register.',\n default: false,\n });\n if (!proceed) return;\n }\n\n // Generate identity and register\n spinner.start('Generating Ed25519 identity and registering with Beam directory…');\n\n const result = await api.post<{\n ok: boolean;\n beam_id: string;\n did: string;\n public_key: string;\n trust_score: number;\n verification_tier: string;\n published_capabilities: string[];\n error?: string;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam/setup`, {\n auto_publish_capabilities: options.autoPublish ?? true,\n directory_url: options.directoryUrl,\n });\n\n if (!result.ok) {\n spinner.fail('Registration failed');\n error(result.error ?? 'Unknown error');\n process.exitCode = 1;\n return;\n }\n\n spinner.succeed('Beam identity created and registered');\n\n if (json) {\n jsonOutput({\n beam_id: result.beam_id,\n did: result.did,\n public_key: result.public_key,\n trust_score: result.trust_score,\n verification_tier: result.verification_tier,\n published_capabilities: result.published_capabilities,\n });\n return;\n }\n\n console.log();\n table(\n ['Field', 'Value'],\n [\n ['Beam ID', chalk.cyan(result.beam_id)],\n ['DID', chalk.dim(result.did)],\n ['Trust Score', String(result.trust_score)],\n ['Verification', result.verification_tier],\n ['Capabilities', result.published_capabilities.length > 0\n ? result.published_capabilities.join(', ')\n : chalk.dim('none published')],\n ],\n );\n console.log();\n success(`Agent \"${agentCodeName}\" is now reachable at ${chalk.cyan(result.beam_id)}`);\n } catch (err) {\n spinner.fail('Setup failed');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels beam status <agent-code-name>`\n */\nexport async function channelBeamStatusCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: `Fetching Beam config for \"${agentCodeName}\"…`, isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n config: Record<string, unknown> | null;\n status?: string;\n }>(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`);\n\n if (!data.config?.beam_id) {\n spinner.info('No Beam identity configured for this agent.');\n return;\n }\n\n spinner.succeed('Beam configuration found');\n const cfg = data.config;\n\n if (json) {\n jsonOutput(cfg);\n return;\n }\n\n console.log();\n table(\n ['Field', 'Value'],\n [\n ['Beam ID', chalk.cyan(String(cfg.beam_id))],\n ['DID', chalk.dim(String(cfg.did ?? '—'))],\n ['Public Key', chalk.dim(String(cfg.public_key ?? '').slice(0, 24) + '…')],\n ['Trust Score', String(cfg.trust_score ?? 0)],\n ['Verification', String(cfg.verification_tier ?? 'basic')],\n ['Auto-publish', cfg.auto_publish_capabilities ? chalk.green('yes') : chalk.dim('no')],\n ['Capabilities', Array.isArray(cfg.published_capabilities) && cfg.published_capabilities.length > 0\n ? cfg.published_capabilities.join(', ')\n : chalk.dim('none')],\n ['Status', data.status ?? '—'],\n ],\n );\n console.log();\n } catch (err) {\n spinner.fail('Failed to fetch config');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\n/**\n * `agt channels beam remove <agent-code-name>`\n */\nexport async function channelBeamRemoveCommand(agentCodeName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!json) {\n const proceed = await confirm({\n message: `Remove Beam identity from \"${agentCodeName}\"? The directory entry will expire.`,\n default: false,\n });\n if (!proceed) return;\n }\n\n const spinner = ora({ text: 'Removing Beam identity…', isSilent: json });\n spinner.start();\n\n try {\n await api.del(`/agents/${encodeURIComponent(agentCodeName)}/channel-configs/beam`);\n spinner.succeed('Beam identity removed');\n\n if (json) {\n jsonOutput({ ok: true });\n }\n } catch (err) {\n spinner.fail('Failed to remove');\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { select, input } from '@inquirer/prompts';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n DEPLOYMENT_TEMPLATES,\n getTemplate,\n renderTemplate,\n type TemplateContext,\n type TemplateAgent,\n} from '@augmented/core';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface DeployOptions {\n template?: string;\n port?: string;\n}\n\n/**\n * `agt deploy`\n */\nexport async function deployCommand(opts: DeployOptions): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const nonInteractive = !!opts.template;\n const json = isJsonMode();\n\n let templateId: string;\n let basePort: number;\n\n if (nonInteractive) {\n templateId = opts.template!;\n basePort = Number(opts.port ?? '9000');\n if (isNaN(basePort) || basePort < 1 || basePort > 65535) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid port number' });\n } else {\n error('Invalid port number. Must be between 1 and 65535.');\n }\n process.exitCode = 1;\n return;\n }\n } else {\n console.log(chalk.bold('\\nAugmented — Deploy\\n'));\n\n templateId = await select({\n message: 'Deployment template:',\n choices: DEPLOYMENT_TEMPLATES.map((t) => ({\n value: t.id,\n name: `${t.name} — ${t.description}`,\n })),\n });\n\n const basePortStr = await input({\n message: 'Base port for gateway:',\n default: '9000',\n validate: (v) => {\n const n = Number(v);\n return (!isNaN(n) && n > 0 && n < 65536) || 'Must be a valid port number';\n },\n });\n basePort = Number(basePortStr);\n }\n\n const tmpl = getTemplate(templateId);\n if (!tmpl) {\n if (json) {\n jsonOutput({ ok: false, error: `Template \"${templateId}\" not found` });\n } else {\n error(`Template \"${templateId}\" not found.`);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Fetch agents via API ──────────────────────────────────────────────\n\n const spinner = ora({ text: 'Fetching agents…', isSilent: json });\n spinner.start();\n\n let agents: Array<{\n agent_id: string;\n code_name: string;\n display_name: string;\n environment: string;\n }>;\n\n try {\n const data = await api.get<{ agents: typeof agents }>('/agents');\n agents = data.agents;\n } catch (err) {\n spinner.fail('Failed to fetch agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n if (!agents || agents.length === 0) {\n spinner.fail('No agents found in team.');\n if (json) {\n jsonOutput({ ok: false, error: 'No agents found in team. Run `agt init` first.' });\n } else {\n error('No agents found in team. Run `agt init` first.');\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Build template context ────────────────────────────────────────────\n\n const templateAgents: TemplateAgent[] = agents.map((a, i) => ({\n agent_id: a.agent_id,\n code_name: a.code_name,\n display_name: a.display_name,\n environment: a.environment,\n port: basePort + i,\n }));\n\n const context: TemplateContext = {\n agents: templateAgents,\n gateway: { port: basePort },\n variables: {},\n };\n\n let rendered: string;\n try {\n rendered = renderTemplate(tmpl.template, context);\n } catch (err) {\n spinner.fail('Template rendering failed.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Record deployment via API ─────────────────────────────────────────\n\n try {\n await api.post('/deployments', {\n template_id: tmpl.id,\n agent_ids: agents.map((a) => a.agent_id),\n variables: { base_port: basePort },\n });\n } catch (deployErr) {\n spinner.stop();\n if (!json) info(`Warning: could not record deployment in database: ${(deployErr as Error).message}`);\n }\n\n // ── Write output file ─────────────────────────────────────────────────\n\n const outDir = join(process.cwd(), '.augmented', 'deploy');\n mkdirSync(outDir, { recursive: true });\n const outPath = join(outDir, 'docker-compose.yaml');\n writeFileSync(outPath, rendered);\n\n spinner.succeed('Deployment config generated.');\n\n if (json) {\n jsonOutput({\n ok: true,\n template: tmpl.id,\n agents: agents.map((a) => a.code_name),\n output_path: outPath,\n });\n return;\n }\n\n console.log();\n info(`Template: ${chalk.bold(tmpl.name)}`);\n info(`Agents: ${agents.map((a) => a.code_name).join(', ')}`);\n info(`Output: ${outPath}`);\n console.log();\n info(`Next steps:`);\n info(` cd .augmented/deploy && docker compose up`);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n extractFrontmatter,\n resolveChannels,\n lintAll,\n getFramework,\n getTemplate,\n renderTemplate,\n type CharterFrontmatter,\n type ToolsFrontmatter,\n type ChannelId,\n type ChannelPolicy,\n type OrgChannelPolicy,\n type DeploymentTarget,\n type LintDiagnostic,\n type ProvisionInput,\n type TemplateContext,\n} from '@augmented/core';\nimport { provision } from '@augmented/core/provisioning/provisioner.js';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\nfunction printDiagnostics(diagnostics: LintDiagnostic[]): void {\n for (const d of diagnostics) {\n const prefix = d.severity === 'error' ? chalk.red('ERR') : chalk.yellow('WARN');\n const path = d.path ? chalk.dim(` (${d.path})`) : '';\n console.log(` ${prefix} [${d.code}] ${d.message}${path}`);\n }\n}\n\n/**\n * `agt provision <code-name>`\n */\nexport async function provisionCommand(\n codeName: string,\n options: { target?: string; output?: string; dryRun?: boolean },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const target = (options.target ?? 'local_docker') as DeploymentTarget;\n const outputDir = options.output ?? join(process.cwd(), '.augmented', codeName, 'provision');\n const dryRun = options.dryRun ?? false;\n\n if (!json) console.log(chalk.bold('\\nAugmented — Provision\\n'));\n\n const spinner = ora({ text: 'Fetching agent data…', isSilent: json });\n spinner.start();\n\n // ── Fetch all provision data in one call ──────────────────────────────\n\n let provisionData: {\n agent: Record<string, unknown>;\n charter: { raw_content: string; version: string } | null;\n tools: { raw_content: string; version: string } | null;\n channel_configs: Record<string, { config: unknown; status: string }> | null;\n team_channel_policy: {\n team_id: string;\n allowed_channels: string[];\n denied_channels: string[];\n require_elevated_for_pii: boolean;\n } | null;\n };\n\n try {\n provisionData = await api.get(`/agents/${encodeURIComponent(codeName)}/provision-data`);\n } catch (err) {\n spinner.fail(`Could not fetch provision data for \"${codeName}\".`);\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const agentData = provisionData.agent;\n\n if (!provisionData.charter) {\n spinner.fail('No CHARTER.md version found.');\n if (json) jsonOutput({ ok: false, error: 'No CHARTER.md version found' });\n else error('No CHARTER.md version found for this agent');\n process.exitCode = 1;\n return;\n }\n\n if (!provisionData.tools) {\n spinner.fail('No TOOLS.md version found.');\n if (json) jsonOutput({ ok: false, error: 'No TOOLS.md version found' });\n else error('No TOOLS.md version found for this agent');\n process.exitCode = 1;\n return;\n }\n\n spinner.text = 'Parsing frontmatter…';\n\n const charterContent = provisionData.charter.raw_content;\n const toolsContent = provisionData.tools.raw_content;\n\n const charterParsed = extractFrontmatter(charterContent);\n if (!charterParsed.frontmatter) {\n spinner.fail('Failed to parse CHARTER.md frontmatter.');\n if (json) jsonOutput({ ok: false, error: charterParsed.error ?? 'Unknown parse error' });\n else error(charterParsed.error ?? 'Unknown parse error');\n process.exitCode = 1;\n return;\n }\n\n const toolsParsed = extractFrontmatter(toolsContent);\n if (!toolsParsed.frontmatter) {\n spinner.fail('Failed to parse TOOLS.md frontmatter.');\n if (json) jsonOutput({ ok: false, error: toolsParsed.error ?? 'Unknown parse error' });\n else error(toolsParsed.error ?? 'Unknown parse error');\n process.exitCode = 1;\n return;\n }\n\n const charterFrontmatter = charterParsed.frontmatter as unknown as CharterFrontmatter;\n const toolsFrontmatter = toolsParsed.frontmatter as unknown as ToolsFrontmatter;\n\n // ── Lint ───────────────────────────────────────────────────────────────\n\n spinner.text = 'Linting…';\n const lintResult = lintAll(charterContent, toolsContent);\n\n if (!lintResult.ok) {\n spinner.fail('Lint errors — cannot provision.');\n if (json) {\n jsonOutput({\n ok: false,\n error: 'Lint errors — cannot provision',\n lint: {\n errors: lintResult.errors.length,\n warnings: lintResult.warnings.length,\n diagnostics: [...lintResult.errors, ...lintResult.warnings],\n },\n });\n } else {\n printDiagnostics(lintResult.errors);\n if (lintResult.warnings.length > 0) printDiagnostics(lintResult.warnings);\n }\n process.exitCode = 1;\n return;\n }\n\n if (lintResult.warnings.length > 0 && !json) {\n spinner.stop();\n warn(`Lint: ${lintResult.warnings.length} warning(s)`);\n printDiagnostics(lintResult.warnings);\n spinner.start('Provisioning…');\n }\n\n // ── Resolve channels ──────────────────────────────────────────────────\n\n spinner.text = 'Resolving channels…';\n\n // Derive channels from agent_channel_configs (source of truth)\n const configuredChannels = Object.keys(provisionData.channel_configs ?? {}) as ChannelId[];\n\n const agentChannelPolicy: ChannelPolicy = {\n policy: 'allowlist',\n allowed: configuredChannels,\n denied: [],\n require_approval_to_change: true,\n };\n\n let orgChannelPolicy: OrgChannelPolicy | undefined;\n const policyData = provisionData.team_channel_policy;\n\n if (policyData) {\n orgChannelPolicy = {\n organization_id: policyData.team_id,\n allowed_channels: (policyData.allowed_channels ?? []) as ChannelId[],\n denied_channels: (policyData.denied_channels ?? []) as ChannelId[],\n require_elevated_for_pii: policyData.require_elevated_for_pii ?? false,\n };\n }\n\n const resolvedChannels = resolveChannels(agentChannelPolicy, orgChannelPolicy);\n\n // ── Fetch integrations ────────────────────────────────────────────────\n //\n // ENG-5923: the provision input previously omitted integrations entirely,\n // so `buildMcpJson` defaulted `input.integrations ?? []` and the rendered\n // `.mcp.json` lost every Composio + native (granola, postiz, xero, …) MCP\n // server. Re-provisioning an agent wiped its `.mcp.json` down to the\n // `augmented` server + channel-credential entries. Fetch the decrypted,\n // scope-resolved integrations from the same host endpoint manager-worker\n // uses — credentials are decrypted server-side, so hosts never see\n // ciphertext — and pass them through so the renderer has the full picture.\n\n spinner.text = 'Fetching integrations…';\n\n const agentId = agentData.agent_id as string;\n let integrations: NonNullable<ProvisionInput['integrations']> = [];\n let integrationsError: string | null = null;\n try {\n const integrationsData = await api.post<{\n integrations: Array<{\n id: string;\n definition_id: string;\n display_name: string;\n scope: string;\n auth_type: string;\n credentials: Record<string, unknown>;\n config: Record<string, unknown>;\n capabilities: Array<{ id: string; name: string; description: string; access: string }>;\n }>;\n }>('/host/agent-integrations', { agent_id: agentId });\n integrations = (integrationsData.integrations ??\n []) as NonNullable<ProvisionInput['integrations']>;\n } catch (err) {\n // Don't silently strip integrations — that's the exact regression this\n // ticket fixes. An agent with zero integrations returns an empty list\n // (not an error), so only a genuine fetch failure lands here. Surface it\n // loudly and continue rather than writing a stripped `.mcp.json`.\n integrationsError = (err as Error).message;\n if (!json) {\n spinner.stop();\n warn(\n `Could not fetch integrations: ${integrationsError}. ` +\n '.mcp.json may be missing integration servers.',\n );\n spinner.start('Provisioning…');\n }\n }\n\n // ── Provision ─────────────────────────────────────────────────────────\n\n const frameworkId = (agentData.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n\n spinner.text = `Building ${adapter.label} config…`;\n\n const provisionInput: ProvisionInput = {\n agent: agentData as any,\n charterFrontmatter,\n charterContent,\n toolsFrontmatter,\n toolsContent,\n resolvedChannels,\n integrations,\n deploymentTarget: target,\n gatewayPort: 9000,\n };\n\n const provisionOutput = provision(provisionInput, frameworkId);\n\n const templateId = target === 'local_docker' ? 'shared-gateway-local' : 'shared-gateway-local';\n const tmpl = getTemplate(templateId);\n let deploymentYaml = '';\n if (tmpl) {\n const templateContext: TemplateContext = {\n agents: [{\n agent_id: agentData.agent_id as string,\n code_name: agentData.code_name as string,\n display_name: agentData.display_name as string,\n environment: agentData.environment as string,\n port: 9000,\n }],\n gateway: { port: 9000 },\n variables: {},\n };\n deploymentYaml = renderTemplate(tmpl.template, templateContext);\n }\n\n // ── Dry run ───────────────────────────────────────────────────────────\n\n if (dryRun) {\n spinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n dry_run: true,\n agent: codeName,\n framework: frameworkId,\n target,\n charter_hash: provisionOutput.charterHash,\n tools_hash: provisionOutput.toolsHash,\n channels: resolvedChannels.length,\n integrations: integrations.length,\n integrations_error: integrationsError,\n artifacts: provisionOutput.artifacts.map((a) => ({\n path: a.relativePath,\n size: a.content.length,\n })),\n deployment_yaml: deploymentYaml || null,\n });\n return;\n }\n\n console.log();\n info('Dry run — no files written.');\n console.log();\n for (const artifact of provisionOutput.artifacts) {\n console.log(chalk.bold(`${artifact.relativePath}:`));\n console.log(artifact.content);\n }\n if (deploymentYaml) {\n console.log(chalk.bold('Deployment Template:'));\n console.log(deploymentYaml);\n }\n console.log();\n info(`CHARTER hash: ${provisionOutput.charterHash}`);\n info(`TOOLS hash: ${provisionOutput.toolsHash}`);\n return;\n }\n\n // ── Write files ───────────────────────────────────────────────────────\n\n spinner.text = 'Writing files…';\n\n mkdirSync(outputDir, { recursive: true });\n for (const artifact of provisionOutput.artifacts) {\n writeFileSync(join(outputDir, artifact.relativePath), artifact.content);\n }\n if (deploymentYaml) {\n writeFileSync(join(outputDir, 'docker-compose.yaml'), deploymentYaml);\n }\n\n // ── Store provision snapshot via API ───────────────────────────────────\n\n spinner.text = 'Storing provision snapshot…';\n\n try {\n await api.post(`/agents/${encodeURIComponent(codeName)}/provision-snapshots`, {\n charter_version: provisionData.charter.version,\n tools_version: provisionData.tools.version,\n charter_content: charterContent,\n tools_content: toolsContent,\n channels: resolvedChannels,\n });\n } catch (err) {\n spinner.stop();\n if (!json) warn(`Provision completed but could not store snapshot: ${(err as Error).message}`);\n }\n\n // ── Summary ───────────────────────────────────────────────────────────\n\n spinner.succeed(`Agent \"${chalk.bold(agentData.display_name as string)}\" provisioned.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n agent: codeName,\n framework: frameworkId,\n target,\n output_dir: outputDir,\n charter_hash: provisionOutput.charterHash,\n tools_hash: provisionOutput.toolsHash,\n channels: resolvedChannels.length,\n integrations: integrations.length,\n integrations_error: integrationsError,\n artifacts: provisionOutput.artifacts.map((a) => a.relativePath),\n });\n return;\n }\n\n console.log();\n info(`Agent: ${agentData.code_name}`);\n info(`Framework: ${adapter.label}`);\n info(`Target: ${target}`);\n info(`Output: ${outputDir}`);\n info(`CHARTER hash: ${provisionOutput.charterHash.slice(0, 12)}…`);\n info(`TOOLS hash: ${provisionOutput.toolsHash.slice(0, 12)}…`);\n info(`Channels: ${resolvedChannels.length} active`);\n info(`Integrations: ${integrations.length}${integrationsError ? ' (fetch failed)' : ''}`);\n info(`Artifacts: ${provisionOutput.artifacts.map((a) => a.relativePath).join(', ')}`);\n console.log();\n info('Next steps:');\n info(` cd ${outputDir} && docker compose up`);\n info(` agt drift check ${agentData.code_name}`);\n}\n","/**\n * ENG-5688 (redesigned) — `agt impersonate {connect|current|exit}`.\n *\n * The CLI side of the operator-impersonates-agent v0 flow. The operator\n * gets a short redeem token (XXXX-XXXX) from the webapp (ENG-5702's\n * \"Impersonate this agent\" button) and pastes:\n *\n * agt impersonate connect XXXX-XXXX\n *\n * The CLI:\n * 1. Validates the token shape; refuses obvious garbage before any\n * server round-trip.\n * 2. POSTs the token to the API's PUBLIC /impersonate/agent/redeem\n * endpoint (ENG-5701, amended by this PR to use short-token\n * credentials) — no Authorization, no X-Team-Slug. The token IS\n * the credential, so this works in a clean shell with no\n * `AGT_API_KEY` set (ENG-5688 AC4).\n * 3. Receives the bundle:\n * { token, expires_at, session_id, agent { id, code_name, team_id },\n * artifacts: { \"CLAUDE.md\", \".mcp.json\" } }\n * 4. Writes the persona files to ~/.augmented-impersonate/<code-name>/\n * 5. Backs up the operator's existing project files and symlinks the\n * persona files in (preserves CR-feedback invariants on atomicity,\n * strict root check, and refused symlinks — see ../lib/impersonate-fs-ops.ts).\n * 6. Stashes the manifest atomically with the host the token was\n * exchanged against so `exit` calls /stop on the right environment.\n * 7. Prints agent details + restart-Claude-Code prompt.\n *\n * `agt impersonate current` reads the active manifest; `agt impersonate\n * exit` writes the stop audit row, restores backups, and clears the\n * manifest.\n *\n * Gated behind AGT_IMPERSONATE_ENABLED (see ../lib/impersonate-flag.ts)\n * until the surrounding pieces (ENG-5689 channel-MCP refusal, ENG-5702\n * webapp button) land and the end-to-end smoke test runs against prod.\n */\n\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { spawn } from 'node:child_process';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { delimiter, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { ApiError, api } from '../lib/api-client.js';\nimport { PROD_AGT_HOST } from '../lib/config.js';\nimport { error, info, success } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { requireImpersonateEnabled } from '../lib/impersonate-flag.js';\nimport {\n clearActiveManifest,\n ensureCodeNameDir,\n ensureImpersonateWorkdir,\n isExpired,\n listActiveManifests,\n readActiveManifest,\n writeActiveManifest,\n type BackupKind,\n type HookBackup,\n type ImpersonateManifest,\n type StatusLineBackup,\n} from '../lib/impersonate-state.js';\nimport {\n findGitWorkTreeRoot,\n restoreSwapped,\n swapInPersonaFile,\n} from '../lib/impersonate-fs-ops.js';\nimport {\n registerIntroduceHook,\n unregisterIntroduceHook,\n} from '../lib/impersonate-hook.js';\nimport {\n registerStatusLine,\n unregisterStatusLine,\n} from '../lib/impersonate-statusline.js';\nimport {\n buildIntroduction,\n parseIdentityFromClaudeMd,\n parseIntegrationsFromMcpJson,\n type ParsedIdentity,\n} from '../lib/impersonate-introduce.js';\nimport { rewriteMcpJsonForImpersonation } from '../lib/impersonate-mcp-rewrite.js';\n\nconst SWAP_FILES = ['CLAUDE.md', '.mcp.json'] as const;\nconst AGENT_IMPERSONATION_HEADER = 'X-Agent-Impersonation';\n\n// ENG-5688 (+ amends ENG-5701): short-token redeem format. Mirrors\n// /host/setup's provisioning_tokens — two 4-char Crockford-style\n// alphanumeric segments joined by a hyphen, e.g. \"A3K7-NP5V\".\nconst REDEEM_TOKEN_RE = /^[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i;\n\n/** Server response from POST /impersonate/agent/redeem. */\ninterface RedeemBundle {\n token: string;\n /**\n * ENG-5874: the portable agent-session token the augmented MCP server uses\n * directly as Bearer. Absent on older servers / pre-org teams — treat as\n * optional and fall back to the legacy host-key path when missing.\n */\n agent_session_token?: string | null;\n expires_at: number;\n session_id: string;\n agent: { agent_id: string; code_name: string; team_id: string };\n artifacts: { 'CLAUDE.md': string; '.mcp.json': string };\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate connect <token>`\n// ---------------------------------------------------------------------------\n\n/**\n * Options for the connect command.\n *\n * `noLaunch` defaults to `false` — connect spawns Claude Code in the\n * impersonation project directory after a successful swap. Operators\n * opt out with `--no-launch` (useful for scripting, smoke tests, or\n * when they want to manage their own Claude session).\n *\n * ENG-5747.\n */\nexport interface ImpersonateConnectOptions {\n noLaunch?: boolean;\n /**\n * ENG-5756 (AC3): swap into an auto-provisioned dedicated directory\n * (`~/.augmented-impersonate/<code-name>/workdir`) rather than the\n * operator's current directory. Makes a repo clobber structurally\n * impossible — the swap never touches cwd. Also the escape hatch the\n * git-work-tree guard points operators at.\n */\n workdir?: boolean;\n /**\n * Override the API host used to redeem the token. When unset, impersonate\n * always hits the production API (`api.augmented.team`) regardless of\n * `AGT_HOST` — operators routinely point AGT_HOST at a local/Tailscale\n * dev API for day-to-day CLI work, but redeem tokens are minted against\n * prod almost every time. Pin the default to prod and require an explicit\n * `--api-host` to deviate.\n */\n apiHost?: string;\n}\n\nexport async function impersonateConnectCommand(\n token: string,\n options: ImpersonateConnectOptions = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n // In JSON mode we never launch Claude Code — the caller is a script\n // that needs the structured exit, not an interactive shell. This is\n // independent of --no-launch (which is the explicit operator opt-out).\n const shouldLaunchClaude = !options.noLaunch && !json;\n\n // ENG-5688: validate token shape up-front (XXXX-XXXX) so we refuse\n // obvious garbage before a server round-trip. Server does the\n // authoritative validation against impersonation_setup_tokens.\n if (!REDEEM_TOKEN_RE.test(token)) {\n const msg =\n 'Token is not in the expected XXXX-XXXX format. ' +\n 'Copy the full `agt impersonate connect <token>` command from the webapp.';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // ── Guard: refuse a second session for the SAME target directory ──────\n //\n // ENG-5967: impersonation state is keyed per project directory, so\n // different directories (e.g. two separate terminals, each in its own\n // dedicated dir) run concurrently. We only refuse re-connecting a\n // directory that already has an active session. In the default mode the\n // target is process.cwd(), known up-front — check it here so a duplicate\n // refuses BEFORE the single-use redeem token is spent. In `--workdir`\n // mode the target depends on the agent code_name (resolved post-redeem),\n // so that case is guarded again just before the swap (see below).\n if (!options.workdir) {\n const existing = readActiveManifest(process.cwd());\n if (existing) {\n const msg =\n `An impersonation session is already active in this directory (${existing.code_name}). ` +\n `Run \\`agt impersonate exit\\` here first, or connect from a different directory.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n }\n\n // ── Guard: never swap persona files inside a git working tree ─────────\n //\n // ENG-5756: the swap (below) symlinks the agent's CLAUDE.md/.mcp.json\n // into the swap target. In the default mode that target is\n // process.cwd(); if that's inside a git work tree, the swap overwrites\n // the repo's OWN CLAUDE.md/.mcp.json with symlinks — git sees a\n // type-change and a stray `git commit -a` could capture them,\n // corrupting the repo. Impersonation is designed for a standalone /\n // scratch directory, so refuse here — crucially BEFORE the redeem\n // round-trip, so the single-use token isn't spent and no files are\n // touched — and point the operator at `--workdir` or a clean dir.\n //\n // `--workdir` opts into an auto-provisioned dedicated directory under\n // ~/.augmented-impersonate/ (resolved after redeem, once we know the\n // code_name), so cwd is never touched and this guard doesn't apply.\n if (!options.workdir) {\n const workTreeRoot = findGitWorkTreeRoot(process.cwd());\n if (workTreeRoot) {\n const msg =\n `Refusing to impersonate inside a git working tree (${workTreeRoot}). ` +\n `connect swaps the agent's ${SWAP_FILES.join(' + ')} into the current ` +\n `directory, which would overwrite the repo's own files. Re-run with ` +\n `\\`--workdir\\` to use an auto-provisioned dedicated directory, or run ` +\n `from a standalone empty directory.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n }\n\n if (!json) console.log(chalk.bold('\\nAugmented — Impersonate\\n'));\n // The token is opaque (no embedded agent name to display, unlike the\n // old JWT shape) so the spinner message is generic. The success\n // message will show the real agent name from the bundle.\n const spinner = ora({\n text: 'Redeeming token…',\n isSilent: json,\n });\n spinner.start();\n\n // ── Call /redeem WITHOUT auth ────────────────────────────────────────\n //\n // This is the heart of AC4: the redeem token IS the credential, and\n // the server endpoint is PUBLIC. We use plain fetch() (not api.post)\n // because api.post triggers AGT_API_KEY discovery + exchange — which\n // would fail in a clean shell, and which we deliberately don't want\n // to need.\n // Pin to prod by default — see ImpersonateConnectOptions.apiHost.\n const host = (options.apiHost ?? PROD_AGT_HOST).replace(/\\/+$/, '');\n let bundle: RedeemBundle;\n try {\n const res = await fetch(`${host}/impersonate/agent/redeem`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ redeem_token: token }),\n });\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const detail = (body['error'] as string) ?? `HTTP ${res.status}`;\n throw new Error(`${detail} (HTTP ${res.status})`);\n }\n bundle = (await res.json()) as RedeemBundle;\n } catch (err) {\n spinner.fail('Failed to redeem token.');\n const msg = err instanceof Error ? err.message : String(err);\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // ── Write persona files to ~/.augmented-impersonate/<code-name>/ ─────\n spinner.text = 'Writing persona files…';\n const personaDir = ensureCodeNameDir(bundle.agent.code_name);\n writeFileSync(\n join(personaDir, 'CLAUDE.md'),\n bundle.artifacts['CLAUDE.md'],\n );\n // ENG-5812: the server-rendered .mcp.json is shaped for the agent's\n // Lambda/Docker runtime (paths under `/home/sbx_user1051/.augmented/_mcp/`\n // and empty AGT_HOST / AGT_API_KEY / HOME). Rewrite it so the\n // operator's local Claude Code can actually spawn the MCP servers\n // — substitute Lambda paths for the CLI's own bundled `dist/mcp/`\n // and fill the env with operator-side values. See\n // ../lib/impersonate-mcp-rewrite.ts for the contract.\n writeFileSync(\n join(personaDir, '.mcp.json'),\n rewriteMcpJsonForImpersonation(bundle.artifacts['.mcp.json'], {\n operatorHome: process.env.HOME ?? '',\n operatorPath: resolveOperatorPath(),\n cliMcpBundleDir: resolveCliMcpBundleDir(),\n impersonationToken: bundle.token,\n agentSessionToken: bundle.agent_session_token ?? null,\n apiHost: host,\n agentId: bundle.agent.agent_id,\n agentCodeName: bundle.agent.code_name,\n }),\n );\n\n // ── Swap files + write manifest atomically ───────────────────────────\n //\n // CR #3321347793 from PR #1489: this whole step has to be atomic\n // from the operator's perspective. If we swap one file and then\n // the second swap or the manifest write fails, the project ends up\n // modified with no manifest to drive recovery from `exit`. Track\n // each successful swap and roll back on any failure.\n spinner.text = 'Swapping persona files…';\n // Default target is the operator's cwd (guarded above against git work\n // trees). `--workdir` instead provisions a dedicated agent-scoped dir\n // under ~/.augmented-impersonate/<code-name>/workdir so the swap can\n // never touch a repo (ENG-5756 AC3). Everything downstream — manifest\n // project_cwd, the spawn cwd, and `exit`'s restore target — keys off\n // this one value, so the rest of the flow is mode-agnostic.\n const projectCwd = options.workdir\n ? ensureImpersonateWorkdir(bundle.agent.code_name)\n : process.cwd();\n\n // ENG-5967: per-directory guard, second half. The default-mode guard up\n // top already ran against process.cwd(); this catches the `--workdir`\n // case, whose target dir is only known now (it's derived from the\n // code_name in the redeem bundle). Re-connecting the same agent's workdir\n // while a session is live would otherwise clobber its backup state.\n const existingForTarget = readActiveManifest(projectCwd);\n if (existingForTarget) {\n spinner.fail('Impersonation already active for this agent.');\n const msg =\n `An impersonation session is already active in ${projectCwd} (${existingForTarget.code_name}). ` +\n `Run \\`agt impersonate exit\\` there first.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n const backups: Record<string, BackupKind> = {};\n const swapped: Array<{ file: string; kind: BackupKind }> = [];\n // ENG-5750: track the introduce hook so the catch below can roll it\n // back alongside the file swaps if the manifest write fails.\n let hookBackup: HookBackup | undefined;\n let statusLineBackup: StatusLineBackup | undefined;\n\n try {\n for (const file of SWAP_FILES) {\n const projectPath = join(projectCwd, file);\n const kind = swapInPersonaFile(projectPath, join(personaDir, file));\n backups[file] = kind;\n swapped.push({ file, kind });\n }\n\n // ENG-5750: register the SessionStart \"introduce yourself\" hook in\n // the project dir so the fresh Claude Code session opens with the\n // agent introducing itself + its integrations. Folded into the\n // manifest so `exit` removes it and leaves the cwd clean.\n hookBackup = registerIntroduceHook(projectCwd);\n\n // ENG-5801: register the project-scoped statusLine so the operator's\n // Claude Code session shows a 🤖 <agent-name> badge while they're in\n // this project. Backup folded into the manifest so `exit` reverses it\n // byte-for-byte. Shares the same settings.local.json backup file as\n // the introduce hook — whichever register ran first captured the\n // operator's true original.\n statusLineBackup = registerStatusLine(projectCwd);\n\n const manifest: ImpersonateManifest = {\n code_name: bundle.agent.code_name,\n agent_id: bundle.agent.agent_id,\n team_id: bundle.agent.team_id,\n token: bundle.token,\n expires_at: bundle.expires_at,\n session_id: bundle.session_id,\n minted_at: new Date().toISOString(),\n project_cwd: projectCwd,\n host,\n backups,\n hook: hookBackup,\n statusLine: statusLineBackup,\n };\n writeActiveManifest(manifest);\n } catch (err) {\n if (statusLineBackup) {\n try {\n unregisterStatusLine(statusLineBackup);\n } catch {\n // Best-effort; the original error is what matters.\n }\n }\n if (hookBackup) {\n try {\n unregisterIntroduceHook(hookBackup);\n } catch {\n // Best-effort; the original error is what matters.\n }\n }\n for (const { file, kind } of [...swapped].reverse()) {\n try {\n restoreSwapped(join(projectCwd, file), kind);\n } catch {\n // Swallow rollback-of-rollback failures — the original error\n // is what the operator needs to see.\n }\n }\n spinner.fail('Failed to enter impersonation; rolled back changes.');\n throw err;\n }\n\n spinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n code_name: bundle.agent.code_name,\n agent_id: bundle.agent.agent_id,\n session_id: bundle.session_id,\n expires_at: bundle.expires_at,\n project_cwd: projectCwd,\n host,\n swapped_files: SWAP_FILES,\n });\n return;\n }\n\n success(`Impersonating ${chalk.bold(bundle.agent.code_name)}`);\n console.log();\n console.log(` Agent ID: ${chalk.dim(bundle.agent.agent_id)}`);\n console.log(` Team: ${chalk.dim(bundle.agent.team_id)}`);\n console.log(` Session: ${chalk.dim(bundle.session_id)}`);\n console.log(\n ` Expires: ${chalk.dim(new Date(bundle.expires_at * 1000).toISOString())}`,\n );\n console.log(` Project: ${chalk.dim(projectCwd)}`);\n console.log(` Host: ${chalk.dim(host)}`);\n console.log(` Swapped: ${chalk.dim(SWAP_FILES.join(', '))}`);\n console.log();\n if (!shouldLaunchClaude) {\n // --no-launch (or JSON mode, but the JSON branch already returned\n // above). Operator drove their own session start; keep the original\n // copy so they know they have to restart Claude themselves.\n if (options.workdir) {\n // The persona was swapped into the dedicated workdir, not the\n // operator's cwd — tell them where to start their session.\n info(`Start Claude Code in the impersonation workdir: \\`cd ${projectCwd}\\``);\n }\n info(\n \"Restart Claude Code to pick up the agent's persona + MCP server set. \" +\n 'Claude Code 2.1.152 does not honour `tools/list_changed` in-session ' +\n '(spike PoC, ENG-4733).',\n );\n console.log();\n info('When done: `agt impersonate exit`');\n return;\n }\n\n // ── Hand off to Claude Code ──────────────────────────────────────────\n //\n // Spawn `claude` in the impersonation project dir with the parent's\n // stdio so the operator immediately enters an interactive session\n // (foreground replace from their perspective; we wait on the child\n // and mirror its exit code so shells and scripts behave naturally).\n //\n // We deliberately call `claude` via PATH lookup — no config knob in\n // v1, no AGT_CLAUDE_BIN override. Revisit if multiple installs become\n // common; until then keep the contract simple.\n //\n // ENOENT (claude not on PATH) falls back to the manual-restart copy\n // + non-zero exit so the operator knows the auto-launch didn't fire\n // and what to do instead. Anything else surfaces verbatim.\n info('Launching Claude Code… (use `--no-launch` next time to skip)');\n console.log();\n\n const launch = buildImpersonateClaudeLaunch(\n projectCwd,\n process.env,\n bundle.agent.agent_id,\n );\n\n await new Promise<void>((resolve) => {\n const child = spawn('claude', launch.args, {\n stdio: 'inherit',\n cwd: projectCwd,\n env: launch.env,\n });\n child.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'ENOENT') {\n error(\n '`claude` binary not found on PATH. Start Claude Code yourself ' +\n `from ${projectCwd}, or install the CLI from claude.ai/code.`,\n );\n process.exitCode = 1;\n } else {\n error(`Failed to launch Claude Code: ${err.message}`);\n process.exitCode = 1;\n }\n resolve();\n });\n child.on('exit', (code, signal) => {\n // Mirror the child's exit so the operator's shell sees the right\n // status. A signal exit (e.g. operator hit Ctrl-C in Claude) is\n // reported the conventional way (128 + signum is overkill here;\n // Node's process.exitCode = null on signal is fine — the parent\n // already inherited the SIGINT and is being torn down anyway).\n if (code !== null && code !== 0) process.exitCode = code;\n if (signal) process.exitCode = 130; // standard SIGINT semantics\n resolve();\n });\n });\n\n // The impersonation manifest still lives — `agt impersonate exit`\n // will tear it down. Remind the operator on the way out so they don't\n // forget; without it, the persona files stay swapped indefinitely.\n console.log();\n info('When done: `agt impersonate exit` (still active).');\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate current`\n// ---------------------------------------------------------------------------\n\n/** Render one manifest as the human-readable block `current` prints. */\nfunction printManifestText(manifest: ImpersonateManifest): void {\n const expired = isExpired(manifest);\n console.log();\n console.log(chalk.bold(`Impersonating: ${manifest.code_name}`));\n console.log(` Agent ID: ${chalk.dim(manifest.agent_id)}`);\n console.log(` Team: ${chalk.dim(manifest.team_id)}`);\n console.log(` Session: ${chalk.dim(manifest.session_id)}`);\n console.log(` Minted at: ${chalk.dim(manifest.minted_at)}`);\n console.log(\n ` Expires at: ${chalk.dim(new Date(manifest.expires_at * 1000).toISOString())} ` +\n (expired ? chalk.red('(EXPIRED — run `agt impersonate exit`)') : ''),\n );\n console.log(` Project: ${chalk.dim(manifest.project_cwd)}`);\n console.log(` Host: ${chalk.dim(manifest.host)}`);\n console.log();\n}\n\n/** Shape one manifest into the JSON `current` emits. */\nfunction manifestToJson(manifest: ImpersonateManifest) {\n return {\n code_name: manifest.code_name,\n agent_id: manifest.agent_id,\n team_id: manifest.team_id,\n session_id: manifest.session_id,\n minted_at: manifest.minted_at,\n expires_at: manifest.expires_at,\n expired: isExpired(manifest),\n project_cwd: manifest.project_cwd,\n host: manifest.host,\n };\n}\n\nexport async function impersonateCurrentCommand(\n opts: { all?: boolean } = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n\n // ENG-5967: `--all` reports every active session on the machine; the\n // default reports the session for the current directory (with a hint\n // when others are running elsewhere).\n if (opts.all) {\n const manifests = listActiveManifests();\n if (json) {\n jsonOutput({ ok: true, active: manifests.map(manifestToJson) });\n return;\n }\n if (manifests.length === 0) {\n info('No active impersonations.');\n return;\n }\n console.log();\n console.log(chalk.bold(`Active impersonations (${manifests.length}):`));\n for (const m of manifests) printManifestText(m);\n return;\n }\n\n const manifest = readActiveManifest(process.cwd());\n if (!manifest) {\n const others = listActiveManifests();\n if (json) {\n jsonOutput({ ok: true, active: null, others_active: others.length });\n return;\n }\n if (others.length > 0) {\n info(\n `No active impersonation in this directory — ${others.length} active elsewhere. ` +\n 'Run `agt impersonate current --all` to list them.',\n );\n } else {\n info('No active impersonation.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, active: manifestToJson(manifest) });\n return;\n }\n printManifestText(manifest);\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate exit`\n// ---------------------------------------------------------------------------\n\nexport async function impersonateExitCommand(\n opts: { all?: boolean } = {},\n): Promise<void> {\n requireImpersonateEnabled();\n\n const json = isJsonMode();\n\n // ENG-5967: `--all` tears down every active session on the machine; the\n // default exits only the session for the current directory, leaving any\n // concurrent sessions in other directories untouched.\n if (opts.all) {\n const manifests = listActiveManifests();\n if (manifests.length === 0) {\n if (json) jsonOutput({ ok: true, was_active: false, exited: [] });\n else info('No active impersonation to exit.');\n return;\n }\n const exited: string[] = [];\n for (const manifest of manifests) {\n // Silent per-session so a single combined result is emitted below\n // instead of N interleaved blocks (and JSON stays one object).\n await performImpersonateExit(manifest, { json, silent: true });\n exited.push(manifest.code_name);\n }\n if (json) {\n jsonOutput({ ok: true, was_active: true, exited });\n } else {\n success(`Exited ${exited.length} impersonation session(s): ${exited.join(', ')}`);\n info('Restart Claude Code to pick up your original persona.');\n }\n return;\n }\n\n const manifest = readActiveManifest(process.cwd());\n if (!manifest) {\n if (json) jsonOutput({ ok: true, was_active: false });\n else info('No active impersonation to exit.');\n return;\n }\n\n await performImpersonateExit(manifest, { json, silent: false });\n}\n\n/**\n * ENG-5911 — the cleanup half of `exit`, factored out so it runs both from\n * the explicit `agt impersonate exit` command and from the lazy auto-exit\n * (autoExitExpiredImpersonation). Deliberately NOT gated on\n * requireImpersonateEnabled(): cleaning up a lingering session must always be\n * allowed, even from a shell where the impersonate flag isn't set. When\n * `silent` (the auto-exit path) it performs the same side effects but emits no\n * stdout result — so it can't corrupt a JSON command's output or spam an\n * unrelated command; the caller prints its own one-line stderr notice.\n */\nasync function performImpersonateExit(\n manifest: ImpersonateManifest,\n opts: { json: boolean; silent: boolean },\n): Promise<void> {\n const { json, silent } = opts;\n\n // ── Notify the server (best-effort) ───────────────────────────────────\n //\n // /stop currently requires Bearer auth too (ENG-5687); a follow-up will\n // let it accept JUST X-Agent-Impersonation. For v0, if AGT_API_KEY is\n // present we use api.post (which auto-attaches Bearer); if not, we go\n // direct via fetch — the server will likely reject, but local cleanup\n // proceeds either way and the token expires naturally.\n let stopOk = true;\n let stopDetail: string | null = null;\n try {\n if (process.env['AGT_API_KEY']) {\n await api.post('/impersonate/agent/stop', undefined, {\n [AGENT_IMPERSONATION_HEADER]: manifest.token,\n });\n } else {\n // Clean-shell fallback. Sends only X-Agent-Impersonation; the\n // server side will reject this in v0 (auth middleware demands\n // Bearer), but the operator's local cleanup is what matters here.\n const res = await fetch(`${manifest.host}/impersonate/agent/stop`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n [AGENT_IMPERSONATION_HEADER]: manifest.token,\n },\n });\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n const detail = (body['error'] as string) ?? `HTTP ${res.status}`;\n stopOk = false;\n stopDetail = `${detail} (HTTP ${res.status})`;\n }\n }\n } catch (err) {\n stopOk = false;\n stopDetail = err instanceof ApiError\n ? `${err.message} (HTTP ${err.status})`\n : err instanceof Error\n ? err.message\n : String(err);\n // Don't return — local cleanup still has to run.\n }\n\n // ── Restore the operator's project files ──────────────────────────────\n const restored: string[] = [];\n for (const [file, kind] of Object.entries(manifest.backups)) {\n const projectPath = join(manifest.project_cwd, file);\n try {\n restoreSwapped(projectPath, kind);\n restored.push(file);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to restore ${file}: ${msg}`);\n }\n }\n\n // ── Remove the project-scoped statusLine (ENG-5801) ───────────────────\n // Restores the operator's prior statusLine value byte-for-byte from the\n // backup, or removes the settings.local.json we created. Runs BEFORE\n // unregisterIntroduceHook because both touch the same backup file and\n // whichever runs first does the restore — running statusLine first\n // means a malformed-or-stripped fallback path is hit there, not here.\n // Older manifests have no `statusLine` field.\n if (manifest.statusLine) {\n try {\n unregisterStatusLine(manifest.statusLine);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to remove statusLine: ${msg}`);\n }\n\n // The statusline script renames the terminal tab to `🤖 <agent>` on\n // every refresh while impersonation is active. Now that it's gone,\n // emit a one-shot OSC 1 reset so the tab title falls back to the\n // terminal's default instead of staying stuck on the agent name\n // until the next process changes it. JSON-mode skips this — JSON\n // callers are scripts and a control sequence in the JSON stream\n // would corrupt the parse.\n if (!json && process.stdout.isTTY) {\n process.stdout.write('\\x1b]1;\\x07');\n }\n }\n\n // ── Remove the introduce SessionStart hook (ENG-5750) ─────────────────\n // Restores/removes .claude/settings.local.json so the operator's cwd\n // is left exactly as connect found it. Older manifests have no `hook`.\n if (manifest.hook) {\n try {\n unregisterIntroduceHook(manifest.hook);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!json) error(`Failed to remove introduce hook: ${msg}`);\n }\n }\n\n clearActiveManifest(manifest.project_cwd);\n\n // Auto-exit path: side effects done, emit nothing (the caller prints a\n // one-line stderr notice; staying silent keeps unrelated/JSON command\n // output clean).\n if (silent) return;\n\n if (json) {\n jsonOutput({\n ok: true,\n was_active: true,\n session_id: manifest.session_id,\n stop_acknowledged: stopOk,\n stop_detail: stopDetail,\n restored,\n });\n return;\n }\n\n success(`Exited impersonation: ${manifest.code_name}`);\n if (restored.length > 0) {\n info(`Restored: ${restored.join(', ')}`);\n }\n if (!stopOk) {\n info(`Note: server-side stop not acknowledged (${stopDetail}). Token will expire naturally.`);\n }\n info('Restart Claude Code to pick up your original persona.');\n}\n\n/**\n * ENG-5911 — lazy auto-exit. Called from the CLI pre-action hook before\n * (almost) every command: if an impersonation session is active AND its token\n * has expired, run the same cleanup `agt impersonate exit` would — restore the\n * operator's files, post the stop audit (best-effort), clear the manifest — so\n * a dead session never has to be exited by hand. Cheap no-op when nothing is\n * active or the session is still valid; never throws into the caller's command.\n *\n * Skipped by the hook for `impersonate introduce` (the SessionStart hook —\n * must never restore files mid-boot) and `impersonate exit` (redundant).\n * Revocation (ENG-5875) will widen the \"should auto-exit\" predicate beyond\n * pure expiry, reusing performImpersonateExit unchanged.\n */\nexport async function autoExitExpiredImpersonation(): Promise<void> {\n // ENG-5967: state is keyed per directory and sessions can run\n // concurrently, so sweep ALL of them and clean up every expired one —\n // not just whichever the old singleton happened to hold. Cheap when\n // nothing is active (empty list) and never throws into the caller.\n let manifests: ImpersonateManifest[];\n try {\n manifests = listActiveManifests();\n } catch {\n return;\n }\n const expired = manifests.filter((m) => isExpired(m));\n if (expired.length === 0) return;\n for (const manifest of expired) {\n try {\n if (!isJsonMode()) {\n // Notice goes to STDERR (not info()'s stdout) so it can't pollute the\n // stdout of the unrelated command this auto-exit is piggybacking on\n // (e.g. `agt whoami | grep`). Same info styling, different stream.\n console.error(\n chalk.cyan(\n `ℹ Impersonation session for ${manifest.code_name} expired — auto-exiting and restoring your files.`,\n ),\n );\n }\n await performImpersonateExit(manifest, { json: isJsonMode(), silent: true });\n } catch {\n // Auto-exit is best-effort; never break the operator's actual command.\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// `agt impersonate introduce` (hidden) — SessionStart hook target\n// ---------------------------------------------------------------------------\n\n/**\n * Print the impersonated agent's first-person introduction to stdout so\n * Claude Code injects it into the fresh session (ENG-5750). Registered\n * by `connect` as a SessionStart (matcher `startup`) hook.\n *\n * - **Guarded**: emits only when an active, unexpired manifest exists.\n * After `exit` (or once the token lapses) it's a silent no-op — that's\n * how a normal operator session in the same cwd produces no intro.\n * - **Snapshot-only**: reads CLAUDE.md / .mcp.json from project_cwd;\n * never the network, never a token.\n * - **Soft-fail**: any error prints whatever is available and exits 0,\n * never blocking session boot. Deliberately NOT gated on\n * requireImpersonateEnabled() — connect only registers the hook when\n * the flag was set, and a hook must never throw into the session.\n */\nexport async function impersonateIntroduceCommand(): Promise<void> {\n try {\n // ENG-5967: the SessionStart hook runs in the impersonation session's\n // own directory (connect spawns Claude with cwd = project_cwd), so the\n // current directory's manifest is the right — and only — one to read.\n const manifest = readActiveManifest(process.cwd());\n if (!manifest || isExpired(manifest)) return;\n\n const cwd = manifest.project_cwd;\n const identity = readClaudeMdIdentity(join(cwd, 'CLAUDE.md'));\n const integrations = readMcpIntegrations(join(cwd, '.mcp.json'));\n\n const intro = buildIntroduction({\n displayName: identity.displayName,\n codeName: manifest.code_name,\n role: identity.role,\n integrations,\n });\n process.stdout.write(intro + '\\n');\n } catch {\n // Soft-fail: never block session boot.\n }\n}\n\nfunction readClaudeMdIdentity(path: string): ParsedIdentity {\n try {\n return parseIdentityFromClaudeMd(readFileSync(path, 'utf-8'));\n } catch {\n return { displayName: null, role: null };\n }\n}\n\nfunction readMcpIntegrations(path: string): string[] {\n try {\n return parseIntegrationsFromMcpJson(readFileSync(path, 'utf-8'));\n } catch {\n return [];\n }\n}\n\n/**\n * ENG-5812 — resolve the CLI's bundled `dist/mcp/` directory, the same\n * one populated by `build:mcp-assets` (copies of @integrity-labs/\n * augmented-mcp's index.js + channel bundles). Used by the .mcp.json\n * rewrite to substitute the server's Lambda paths for operator-side\n * paths.\n *\n * Walks from this module's location to handle the same layouts as\n * resolveBundledAssetPath in impersonate-statusline.ts:\n * - dev (tsx): apps/cli/src/commands → apps/cli/mcp (workspace copy)\n * - built (tsup): apps/cli/dist/<chunk>.js → apps/cli/dist/mcp\n * - installed: <pkg>/dist/<chunk>.js → <pkg>/dist/mcp\n *\n * Returns a best-effort path when no candidate currently exists on\n * disk — CI runs from source without `build:mcp-assets` having\n * executed, and the impersonate-connect tests exercise this code path\n * without actually spawning the MCP servers. The runtime spawn path\n * surfaces \"MCP server failed to start\" loudly enough already; making\n * resolveCliMcpBundleDir throw here would gate the rewrite on a\n * pre-built tree the test environment doesn't have.\n */\nfunction resolveCliMcpBundleDir(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(moduleDir, 'mcp'),\n join(moduleDir, '..', 'mcp'),\n join(moduleDir, '..', '..', 'mcp'),\n ];\n for (const candidate of candidates) {\n if (existsSync(join(candidate, 'index.js'))) return candidate;\n }\n // Best-effort fallback — the most likely \"correct\" path for a built\n // install. An operator whose installed CLI is missing dist/mcp/ would\n // see a spawn ENOENT when the augmented gateway tries to start,\n // which is the right loud failure mode (not a silent rewrite throw).\n return candidates[candidates.length - 1]!;\n}\n\n/**\n * ENG-5818 (Bug 1) — build a host-correct `PATH` for the operator's\n * machine to overwrite the server-baked Lambda PATH in the rendered\n * `.mcp.json`. The server bakes its own runtime PATH at provision time\n * (`/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin` on the redeem\n * Lambda); none of those dirs hold `node` on a macOS nvm/Homebrew host,\n * so the MCP `command: \"node\"` spawn ENOENTs and every server fails.\n *\n * Prepend the running node's own bin dir (`dirname(process.execPath)` —\n * the exact interpreter running `agt`, guaranteed to exist) to the\n * operator's inherited `PATH`, de-duplicated so we don't bloat the\n * variable on repeated connects. This guarantees `node` resolves while\n * preserving the operator's other PATH entries (Homebrew etc.) so `npx`\n * still works for integration MCP servers.\n *\n * Exported for tests.\n */\nexport function resolveOperatorPath(\n execPath: string = process.execPath,\n inheritedPath: string = process.env.PATH ?? '',\n): string {\n const nodeBinDir = dirname(execPath);\n const segments = inheritedPath.split(delimiter).filter((s) => s.length > 0);\n if (!segments.includes(nodeBinDir)) {\n segments.unshift(nodeBinDir);\n }\n return segments.join(delimiter);\n}\n\n/**\n * ENG-5806 — return shape for `buildImpersonateClaudeLaunch`. Named so\n * the contract is reusable and discoverable, per project TS guidelines.\n */\nexport interface ImpersonateClaudeLaunch {\n args: string[];\n env: NodeJS.ProcessEnv;\n}\n\n/**\n * ENG-5806 — build the launch args + env so the impersonated Claude Code\n * session sees ONLY the agent's swapped-in `.mcp.json` and not the\n * operator's user-scope MCP servers (~/.claude.json) or claude.ai\n * connectors (Gmail/Calendar/Drive/Slack/etc.).\n *\n * Without this, Claude Code merges the project-level `.mcp.json` the\n * impersonation flow swapped in WITH the operator's user-scope tools,\n * so the impersonated agent silently wields the operator's credentials.\n * That breaks the contract of `impersonate` and is SOC2-relevant\n * (auditing \"you acted as the agent\" is misleading when the agent had\n * the operator's tools).\n *\n * - `--strict-mcp-config` restricts the session to ONLY the `.mcp.json`\n * files passed via `--mcp-config`, suppressing user-scope, project-\n * scope auto-load, claude.ai connectors, and plugin-provided servers.\n * - `ENABLE_CLAUDEAI_MCP_SERVERS=false` is belt-and-braces: claude.ai\n * connectors only auto-load under claude.ai subscription auth (not\n * API key), but setting it explicitly is cheap and survives an auth\n * mode change mid-session.\n *\n * Exported for tests; not part of the public CLI API.\n */\nexport function buildImpersonateClaudeLaunch(\n projectCwd: string,\n inheritEnv: NodeJS.ProcessEnv = process.env,\n agentId: string | null = null,\n): ImpersonateClaudeLaunch {\n const env: NodeJS.ProcessEnv = {\n ...inheritEnv,\n ENABLE_CLAUDEAI_MCP_SERVERS: 'false',\n };\n // ENG-5689: when we know which agent the operator is impersonating,\n // forward the agent UUID so spawned channel MCP servers (slack /\n // telegram / direct-chat) can refuse send-* tools. Spoof-resistance\n // is out of scope; this is the accidental-foot-gun gate.\n if (agentId !== null && agentId.length > 0) {\n env.AGT_ACT_AS_AGENT_ID = agentId;\n }\n return {\n args: [\n '--strict-mcp-config',\n '--mcp-config',\n join(projectCwd, '.mcp.json'),\n ],\n env,\n };\n}\n","/**\n * ENG-5688 — feature flag for the `agt impersonate` family of commands.\n *\n * The flow is still v0 and there are pieces (channel-MCP refusal under\n * acting-as JWT, slash-command wrappers) that haven't landed yet, so we\n * gate the commands behind an env var to keep them out of general\n * operators' hands until the surrounding pieces are in. Once those land\n * (ENG-5689 + ENG-5690) and the spike's smoke test has been run end-to-end\n * against production data, the flag can be removed and the commands\n * promoted to defaults.\n *\n * Set `AGT_IMPERSONATE_ENABLED=1` (or any truthy value) to enable.\n */\n\nconst ENV_VAR = 'AGT_IMPERSONATE_ENABLED';\n\n/**\n * Returns true if the operator has explicitly opted in to the\n * impersonation commands. Used by every `agt impersonate *` subcommand\n * to gate access.\n */\nexport function impersonateEnabled(): boolean {\n const v = process.env[ENV_VAR];\n if (!v) return false;\n const trimmed = v.trim().toLowerCase();\n // Treat the obvious \"off\" values as disabled to avoid silent footguns\n // (`AGT_IMPERSONATE_ENABLED=0` shouldn't be truthy just because the\n // string is non-empty).\n return !(trimmed === '' || trimmed === '0' || trimmed === 'false' || trimmed === 'no');\n}\n\n/**\n * Bail with a helpful message when the flag is not set. Returns void on\n * success; calls `process.exit(2)` otherwise so the command terminates\n * before any state-mutating work runs.\n *\n * Exit code 2 (rather than 1) so callers / CI scripts can distinguish\n * \"feature gated off\" from \"command failed for some other reason\".\n */\nexport function requireImpersonateEnabled(): void {\n if (impersonateEnabled()) return;\n\n process.stderr.write(\n `\\nThe \\`agt impersonate\\` commands are gated behind a feature flag.\\n` +\n `\\n` +\n `To enable them, set ${ENV_VAR}=1 in your environment:\\n` +\n `\\n` +\n ` export ${ENV_VAR}=1\\n` +\n `\\n` +\n `These commands are part of the operator-impersonates-agent v0 flow\\n` +\n `(ENG-5687 / ENG-5688). The gating will be removed once the\\n` +\n `surrounding pieces (ENG-5689 channel-MCP refusal, ENG-5690 slash\\n` +\n `commands) land and the end-to-end smoke test has been run against\\n` +\n `production.\\n` +\n `\\n`,\n );\n process.exit(2);\n}\n\n// Exported for tests so they don't have to hard-code the variable name.\nexport const IMPERSONATE_FLAG_ENV_VAR = ENV_VAR;\n","/**\n * ENG-5688 / ENG-5967 — on-disk state for `agt impersonate`.\n *\n * Layout under `~/.augmented-impersonate/`:\n *\n * active/session-<hash>.json — one manifest PER impersonation session,\n * keyed by a hash of its project_cwd. This\n * is what lets multiple agents be\n * impersonated concurrently from separate\n * terminals (each `connect` runs in its own\n * dedicated directory — process.cwd() or an\n * auto-provisioned `--workdir`).\n * active/manifest.json — LEGACY singleton from the pre-ENG-5967\n * one-at-a-time design. Migrated into the\n * keyed layout on first access (see\n * `migrateLegacyManifest`) so an in-flight\n * session created by an older CLI survives\n * the upgrade.\n * <code-name>/CLAUDE.md — persona files rendered for THIS agent;\n * <code-name>/.mcp.json kept side-by-side so the operator can diff\n * two agents' configs cheaply.\n *\n * Each manifest records what files we backed up in its project directory so\n * `exit` can restore them precisely. Keying by project_cwd means two\n * sessions never share backup state, and exiting one never disturbs another.\n *\n * Concurrency: every write is atomic (tmp + rename) and each session is its\n * own file, so concurrent `connect`s in different directories never race on\n * shared state.\n */\n\nimport { createHash } from 'node:crypto';\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst IMPERSONATE_ROOT = join(homedir(), '.augmented-impersonate');\nconst ACTIVE_DIR = join(IMPERSONATE_ROOT, 'active');\n/**\n * Legacy singleton path from the pre-ENG-5967 one-session-at-a-time design.\n * Retained only so `migrateLegacyManifest` can fold a pre-upgrade session\n * into the per-cwd layout. New writes never target it.\n */\nconst ACTIVE_MANIFEST_PATH = join(ACTIVE_DIR, 'manifest.json');\nconst SESSION_FILE_PREFIX = 'session-';\nconst SESSION_FILE_SUFFIX = '.json';\n\n/**\n * Per-session manifest path, keyed by a hash of the project directory. The\n * hash keeps the filename filesystem-safe and fixed-length regardless of how\n * long or exotic the project path is; collisions are not a concern at\n * SHA-256/16-hex-chars for the handful of dirs one operator impersonates in.\n */\nfunction sessionManifestPath(projectCwd: string): string {\n const hash = createHash('sha256').update(projectCwd).digest('hex').slice(0, 16);\n return join(ACTIVE_DIR, `${SESSION_FILE_PREFIX}${hash}${SESSION_FILE_SUFFIX}`);\n}\n\n/**\n * Records what `select` found at a given path in the operator's project\n * before swapping it for the impersonation persona, so `exit` can put\n * things back exactly the way they were.\n *\n * - \"had-file\": a regular file existed and was renamed to\n * <path>.pre-impersonate-backup. Restore = rename back.\n * - \"was-symlink\": a symlink existed (e.g. a stale prior impersonation)\n * and was simply removed. Restore = nothing (the operator\n * presumably re-runs select if they wanted it back).\n * - \"didnt-exist\": nothing was there; we just made a symlink. Restore =\n * remove the symlink.\n */\nexport type BackupKind = 'had-file' | 'was-symlink' | 'didnt-exist';\n\n/**\n * ENG-5750 — records what the introduce SessionStart hook touched in the\n * operator's project dir so `exit` can leave it exactly as it found it.\n *\n * - `settings_path`: the `.claude/settings.local.json` we upserted the\n * SessionStart hook into.\n * - `settings_backup`: \"had-file\" → the original was copied to\n * `<path>.pre-impersonate-backup` and must be restored on exit;\n * \"didnt-exist\" → we created it and must remove it on exit.\n * - `created_claude_dir`: we created the `.claude` directory and should\n * remove it on exit if it's empty afterwards.\n */\nexport interface HookBackup {\n settings_path: string;\n settings_backup: 'had-file' | 'didnt-exist';\n created_claude_dir: boolean;\n}\n\n/**\n * ENG-5801 — records what the impersonation statusLine upsert touched in\n * the operator's project dir so `exit` can leave it exactly as it found\n * it. Same shape as HookBackup because both features share the same\n * `.claude/settings.local.json` byte-for-byte backup mechanism (whichever\n * register runs first creates `<path>.pre-impersonate-backup`; whichever\n * unregister runs first restores it — the existence guards in\n * register/unregister make the ordering irrelevant).\n *\n * - `settings_path`: the `.claude/settings.local.json` we upserted the\n * `statusLine` key into.\n * - `settings_backup`: \"had-file\" → original was copied to\n * `<path>.pre-impersonate-backup` and must be restored on exit;\n * \"didnt-exist\" → we created it and must remove it on exit.\n * - `created_claude_dir`: we created the `.claude` directory and should\n * remove it on exit if it's empty afterwards.\n */\nexport interface StatusLineBackup {\n settings_path: string;\n settings_backup: 'had-file' | 'didnt-exist';\n created_claude_dir: boolean;\n}\n\n/**\n * Singleton manifest. Reused for both writing during `connect` and\n * reading during `current` / `exit`. The shape is meant to be append-only\n * — fields added later should be optional so older manifests still load\n * after an upgrade.\n */\nexport interface ImpersonateManifest {\n /** Agent code_name (kebab-case, e.g. `data-jane`). */\n code_name: string;\n /** Agent UUID, mirror of `act_as_agent_id` claim on the JWT. */\n agent_id: string;\n /** Team UUID the agent belongs to. */\n team_id: string;\n /** Server-issued impersonation JWT — keep opaque to the CLI. */\n token: string;\n /** Unix-seconds (matches the API's response.expires_at). */\n expires_at: number;\n /** Server-issued correlator (claim `sid`). */\n session_id: string;\n /** ISO-8601 timestamp the manifest was written (for `current`). */\n minted_at: string;\n /** process.cwd() at the time of `connect`. */\n project_cwd: string;\n /** What we found in project_cwd before swapping (see BackupKind). */\n backups: Record<string, BackupKind>;\n /**\n * Augmented API host (no trailing slash) the redeem token was\n * exchanged against. `exit` calls /impersonate/agent/stop against the\n * same host so the audit row lands on the right environment — operators\n * who flip AGT_HOST between dev/prod between connect and exit otherwise\n * miss the stop server-side. ENG-5688 (redesigned flow).\n */\n host: string;\n /**\n * ENG-5750 — the introduce SessionStart hook registered in\n * project_cwd, if any. Optional so older manifests still load. `exit`\n * uses it to remove/restore the hook and leave the cwd clean.\n */\n hook?: HookBackup;\n /**\n * ENG-5801 — the impersonation statusLine registered in project_cwd,\n * if any. Optional so older manifests still load (same precedent as\n * `hook?`). `exit` uses it to remove/restore the statusLine and leave\n * the cwd clean.\n */\n statusLine?: StatusLineBackup;\n}\n\n/**\n * Per-code-name directory holding the rendered persona files. Created\n * on demand by `ensureCodeNameDir()`.\n */\n\n/**\n * CR #3322333801: codeName flows directly into `join(IMPERSONATE_ROOT,\n * codeName)`. A value like `../...` would let a hostile redeem response\n * write outside ~/.augmented-impersonate/. We can't fully trust the API\n * server's response (defensive depth), and code_name is supposed to be\n * kebab-case anyway per the codebase's naming conventions — validate\n * up-front and throw if it's not.\n */\nconst CODE_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nfunction assertValidCodeName(codeName: string): void {\n if (!CODE_NAME_RE.test(codeName)) {\n throw new Error(\n `Invalid agent code_name \"${codeName}\" — must be lowercase kebab-case (a-z, 0-9, hyphens; no leading/trailing/consecutive hyphens).`,\n );\n }\n}\n\nexport function getImpersonateCodeNameDir(codeName: string): string {\n assertValidCodeName(codeName);\n return join(IMPERSONATE_ROOT, codeName);\n}\n\nexport function ensureCodeNameDir(codeName: string): string {\n // assertValidCodeName runs inside getImpersonateCodeNameDir, but we\n // call it again explicitly so mkdirSync gets a validated input even\n // if a future change unwires the helper.\n assertValidCodeName(codeName);\n const dir = getImpersonateCodeNameDir(codeName);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/**\n * ENG-5756 (AC3) — dedicated, agent-scoped working directory used by\n * `agt impersonate connect --workdir`. Lives under the per-code-name\n * persona dir (so it's clearly owned by impersonation and sits beside\n * the persona files the swap links to). Persona files get symlinked in\n * HERE instead of into the operator's cwd, which makes clobbering a repo\n * working tree structurally impossible rather than merely recoverable.\n */\nexport function ensureImpersonateWorkdir(codeName: string): string {\n const dir = join(ensureCodeNameDir(codeName), 'workdir');\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/**\n * Strict structural validation, factored out so both the single-session\n * read and the multi-session `listActiveManifests` enforce the exact same\n * contract. Returns the validated manifest or null.\n *\n * CR #3321347807: validate EVERY required field, including `backups`. A\n * half-written manifest that passed the old four-field check would later\n * crash `exit` on `Object.entries(manifest.backups)` when backups was\n * undefined. Bail to null rather than throw so callers treat corrupted\n * state as \"nothing to restore\" rather than entering an error loop.\n */\nfunction validateManifest(parsed: unknown): ImpersonateManifest | null {\n if (typeof parsed !== 'object' || parsed === null) return null;\n const m = parsed as Record<string, unknown>;\n\n const backupsOk =\n typeof m.backups === 'object' &&\n m.backups !== null &&\n Object.values(m.backups as Record<string, unknown>).every(\n (v) => v === 'had-file' || v === 'was-symlink' || v === 'didnt-exist',\n );\n\n if (\n typeof m.code_name !== 'string' ||\n typeof m.agent_id !== 'string' ||\n typeof m.team_id !== 'string' ||\n typeof m.token !== 'string' ||\n typeof m.expires_at !== 'number' ||\n typeof m.session_id !== 'string' ||\n typeof m.minted_at !== 'string' ||\n typeof m.project_cwd !== 'string' ||\n // ENG-5688 (redesigned): host required so `exit` calls /stop against\n // the right environment. Required, not optional, because writing the\n // wrong host on an existing session would point exit at a server\n // that has no record of the session — silently misleading.\n typeof m.host !== 'string' ||\n m.host.length === 0 ||\n !backupsOk\n ) {\n return null;\n }\n return parsed as ImpersonateManifest;\n}\n\n/** Read + validate a single manifest file, or null on any problem. */\nfunction readManifestFile(path: string): ImpersonateManifest | null {\n if (!existsSync(path)) return null;\n try {\n return validateManifest(JSON.parse(readFileSync(path, 'utf-8')));\n } catch {\n return null;\n }\n}\n\n/**\n * ENG-5967 — fold a pre-upgrade legacy singleton (`active/manifest.json`)\n * into the per-cwd layout. Idempotent and best-effort: a valid legacy\n * manifest is moved to its keyed path (unless one already exists there,\n * in which case the keyed file wins and the legacy is discarded); an\n * unreadable/invalid legacy file is removed so it can't shadow future\n * reads. Called at the start of every public accessor so an older CLI's\n * in-flight session keeps working after the operator upgrades.\n */\nfunction migrateLegacyManifest(): void {\n if (!existsSync(ACTIVE_MANIFEST_PATH)) return;\n const legacy = readManifestFile(ACTIVE_MANIFEST_PATH);\n try {\n if (!legacy) {\n rmSync(ACTIVE_MANIFEST_PATH, { force: true });\n return;\n }\n const target = sessionManifestPath(legacy.project_cwd);\n if (!existsSync(target)) {\n mkdirSync(ACTIVE_DIR, { recursive: true, mode: 0o700 });\n renameSync(ACTIVE_MANIFEST_PATH, target);\n chmodSync(target, 0o600);\n } else {\n // A keyed session for this dir already exists — it's authoritative.\n rmSync(ACTIVE_MANIFEST_PATH, { force: true });\n }\n } catch {\n // Best-effort: never let a migration hiccup break the caller.\n }\n}\n\n/**\n * Reads the active manifest for `projectCwd` if present. Returns null when\n * no impersonation is active in that directory — `current` and `exit` use\n * this to decide whether there's anything to act on.\n *\n * Does NOT check expiry — that's the caller's call. `current` reports the\n * expiry; `exit` proceeds with cleanup either way (a manifest pointing at\n * an expired JWT is still authoritative for the local backup state).\n */\nexport function readActiveManifest(projectCwd: string): ImpersonateManifest | null {\n migrateLegacyManifest();\n return readManifestFile(sessionManifestPath(projectCwd));\n}\n\n/**\n * ENG-5967 — every active impersonation session on this machine. Used by\n * `current --all` / `exit --all` and by the lazy auto-exit sweep so a\n * single command can reason about (or clean up) all sessions at once.\n * Invalid/half-written files are skipped, not thrown on.\n */\nexport function listActiveManifests(): ImpersonateManifest[] {\n migrateLegacyManifest();\n let entries: string[];\n try {\n entries = readdirSync(ACTIVE_DIR);\n } catch {\n return []; // active dir doesn't exist yet\n }\n const out: ImpersonateManifest[] = [];\n for (const entry of entries) {\n if (!entry.startsWith(SESSION_FILE_PREFIX) || !entry.endsWith(SESSION_FILE_SUFFIX)) {\n continue;\n }\n const manifest = readManifestFile(join(ACTIVE_DIR, entry));\n if (manifest) out.push(manifest);\n }\n return out;\n}\n\n/**\n * Writes the active manifest. Creates the directory if needed and uses\n * `renameSync` to swap atomically so a half-written file doesn't end up\n * on disk if the process is killed mid-write.\n *\n * CR #3322333807: the manifest contains the impersonation token (a\n * bearer credential), so the file and its parent directory are written\n * with restrictive permissions: 0700 on the directory, 0600 on the\n * file (owner read/write only — group/world get nothing). The explicit\n * chmodSync after writeFileSync is belt-and-braces: writeFileSync's\n * `mode` is the create-mode but doesn't take effect if the path already\n * exists. chmodSync forces it down to 0600 either way.\n */\nexport function writeActiveManifest(manifest: ImpersonateManifest): void {\n migrateLegacyManifest();\n mkdirSync(ACTIVE_DIR, { recursive: true, mode: 0o700 });\n const path = sessionManifestPath(manifest.project_cwd);\n const tmp = path + '.tmp';\n writeFileSync(tmp, JSON.stringify(manifest, null, 2), { mode: 0o600 });\n chmodSync(tmp, 0o600);\n renameSync(tmp, path);\n}\n\n/**\n * Removes the active manifest for `projectCwd`. Idempotent — calling it\n * twice, or when no manifest exists for that directory, is a no-op. Other\n * directories' sessions are untouched.\n */\nexport function clearActiveManifest(projectCwd: string): void {\n migrateLegacyManifest();\n const path = sessionManifestPath(projectCwd);\n if (existsSync(path)) {\n rmSync(path);\n }\n}\n\n/**\n * True if the manifest's expires_at has passed. Used by `current` to\n * tell the operator \"your session has expired, you should re-select or\n * exit\".\n */\nexport function isExpired(manifest: ImpersonateManifest, now = Date.now()): boolean {\n return manifest.expires_at * 1000 <= now;\n}\n\n// Exported for tests; intentionally not part of the documented API.\nexport const TEST_ONLY = {\n IMPERSONATE_ROOT,\n ACTIVE_DIR,\n /** Legacy singleton path — retained for migration tests. */\n ACTIVE_MANIFEST_PATH,\n /** Resolve the per-cwd keyed manifest path (ENG-5967). */\n sessionManifestPath,\n};\n","/**\n * ENG-5688 (redesigned) — file-swap helpers for `agt impersonate`.\n *\n * Extracted from the original PR #1489's impersonate.ts so the helpers\n * are unit-testable on their own and reusable from both `connect` and\n * `exit`. Invariants preserved verbatim from the CR feedback on #1489:\n *\n * - Symlink-into-ours check uses realpath + startsWith(\n * $HOME/.augmented-impersonate/), not substring matching.\n * Closed PR #1489 / CR #3321347799.\n * - Broken symlinks refuse explicitly rather than fall through as\n * \"didnt-exist\". Same CR.\n * - Pre-existing .pre-impersonate-backup at the target refuses; manual\n * cleanup needed rather than silent overwrite.\n * - restoreSwapped won't clobber a non-symlink replacement at the\n * project path — if the operator (or some external process) put a\n * real file there during the session, leave it alone.\n */\n\nimport {\n existsSync,\n lstatSync,\n readlinkSync,\n realpathSync,\n renameSync,\n symlinkSync,\n unlinkSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, parse, sep } from 'node:path';\n\nimport type { BackupKind } from './impersonate-state.js';\n\nexport const BACKUP_SUFFIX = '.pre-impersonate-backup';\n\n/**\n * ENG-5756 — find the git working tree `startDir` lives in, if any.\n *\n * Walks `startDir` and its ancestors looking for a `.git` entry; returns\n * the first directory that has one, or `null` if we reach the filesystem\n * root without finding one. `.git` is matched as EITHER a directory\n * (normal clone) OR a file (git worktree / submodule, where `.git` is a\n * gitlink pointing at the real gitdir) — both mean \"inside a working\n * tree\", which is exactly what `connect` must refuse to swap persona\n * files into (it would clobber the repo's own CLAUDE.md / .mcp.json).\n *\n * This is the dependency-free equivalent of\n * `git rev-parse --show-toplevel` / `--is-inside-work-tree`: no `git`\n * binary required (so it works in the clean shells impersonation\n * targets — ENG-5688 AC4) and trivially unit-testable with temp dirs.\n */\nexport function findGitWorkTreeRoot(startDir: string): string | null {\n const { root } = parse(startDir);\n let dir = startDir;\n for (;;) {\n if (existsSync(join(dir, '.git'))) return dir;\n if (dir === root) return null;\n const parent = dirname(dir);\n // dirname() is a fixpoint at the root on every platform; guard\n // against an infinite loop if `root` detection ever disagrees.\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Replace the file at `projectPath` with a symlink to `personaPath`,\n * preserving whatever was there before so `exit` can restore it.\n *\n * Cases:\n * - Regular file → rename to <path>.pre-impersonate-backup, then\n * create symlink. Restore = rename back.\n * - Symlink resolving INTO our persona root → remove silently and\n * re-link (stale prior impersonation that wasn't exited).\n * Restore = unlink the new symlink.\n * - Symlink resolving OUTSIDE our persona root → REFUSE; the operator\n * may have set it up deliberately.\n * - Broken symlink → REFUSE; treating as absent would silently\n * overwrite what the operator put there.\n * - Nothing there → just create the symlink. Restore = unlink.\n */\nexport function swapInPersonaFile(\n projectPath: string,\n personaPath: string,\n): BackupKind {\n let kind: BackupKind;\n\n if (!lstatSafe(projectPath)) {\n // Truly absent.\n kind = 'didnt-exist';\n } else {\n const stat = lstatSync(projectPath);\n if (stat.isSymbolicLink()) {\n const target = readlinkSync(projectPath);\n // Resolve BOTH sides through realpathSync so macOS's /var ↔\n // /private/var indirection (and any other OS-level symlinks in\n // the path to $HOME) doesn't make a legitimate \"ours\" target\n // look foreign because of an unequal-but-equivalent prefix.\n const ourRoot =\n realpathSync(homedir()) + sep + '.augmented-impersonate' + sep;\n let resolvedTarget: string;\n try {\n resolvedTarget = realpathSync(projectPath);\n } catch {\n // realpath fails on broken symlinks. Treat as unknown and refuse —\n // silently treating as absent would overwrite what the operator\n // put there.\n throw new Error(\n `${projectPath} is a broken symlink (target ${target}). ` +\n `Resolve manually and retry.`,\n );\n }\n if (resolvedTarget.startsWith(ourRoot)) {\n unlinkSync(projectPath);\n kind = 'was-symlink';\n } else {\n throw new Error(\n `${projectPath} is a symlink to ${target} (resolved: ${resolvedTarget}). ` +\n `Refusing to replace it — it doesn't live under ${ourRoot}. ` +\n `Resolve manually and retry.`,\n );\n }\n } else {\n const backupPath = projectPath + BACKUP_SUFFIX;\n if (existsSync(backupPath)) {\n // Backup already exists from a previous failed run. Refuse rather\n // than silently overwrite — manual cleanup is safer than wrong\n // restore later.\n throw new Error(\n `${backupPath} already exists from a previous run. ` +\n `Remove it manually if you're sure it's stale, then retry.`,\n );\n }\n renameSync(projectPath, backupPath);\n kind = 'had-file';\n }\n }\n\n symlinkSync(personaPath, projectPath, 'file');\n return kind;\n}\n\n/**\n * Reverse of swapInPersonaFile.\n *\n * Removes the symlink at projectPath (if it's still a symlink — leave\n * non-symlink replacements alone) and restores the backup file when\n * one exists.\n */\nexport function restoreSwapped(projectPath: string, kind: BackupKind): void {\n if (lstatSafe(projectPath)) {\n const stat = lstatSync(projectPath);\n if (stat.isSymbolicLink()) {\n unlinkSync(projectPath);\n } else {\n // Not a symlink — someone replaced it during the session. Don't\n // touch it.\n return;\n }\n }\n\n if (kind === 'had-file') {\n const backupPath = projectPath + BACKUP_SUFFIX;\n if (existsSync(backupPath)) {\n renameSync(backupPath, projectPath);\n }\n }\n // 'was-symlink' and 'didnt-exist': nothing to restore.\n}\n\nfunction lstatSafe(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * ENG-5750 — register/unregister the impersonation \"introduce yourself\"\n * SessionStart hook in the operator's project dir.\n *\n * `connect` calls `registerIntroduceHook(projectCwd)` after scaffolding\n * CLAUDE.md/.mcp.json. It upserts a SessionStart (matcher `startup`) hook\n * into `<projectCwd>/.claude/settings.local.json` that shells out to\n * `agt impersonate introduce` on every fresh Claude Code boot.\n *\n * The upsert mirrors `provisionOrientHook()` in @augmented/core\n * (packages/core/src/provisioning/frameworks/claudecode/index.ts): don't\n * clobber existing SessionStart entries, and stay idempotent so a repeat\n * connect doesn't stack duplicates.\n *\n * Unlike the managed-agent orient hook (which owns a long-lived\n * settings file), impersonation is ephemeral: `exit` must leave the\n * operator's cwd exactly as it found it. So registration records a\n * `HookBackup` — whether settings.local.json pre-existed (backed up vs\n * created) and whether we created the `.claude` dir — and\n * `unregisterIntroduceHook()` reverses precisely.\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmdirSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { join } from 'node:path';\n\nimport { BACKUP_SUFFIX } from './impersonate-fs-ops.js';\nimport type { HookBackup } from './impersonate-state.js';\n\n/**\n * The command the SessionStart hook runs. Bare `agt` (PATH lookup) for\n * the same reason `connect` spawns bare `claude`: the operator just ran\n * `agt impersonate connect`, so the binary is demonstrably on PATH, and\n * the hook inherits that PATH from the launching shell. Exposed as a\n * parameter so tests can assert against a fixed value.\n */\nexport const INTRODUCE_HOOK_COMMAND = 'agt impersonate introduce';\n\nconst SESSION_START_MATCHER = 'startup';\n\n/**\n * Upsert the introduce SessionStart hook into\n * `<projectCwd>/.claude/settings.local.json`. Returns a HookBackup the\n * manifest stores so `exit` can undo exactly what was done.\n */\nexport function registerIntroduceHook(\n projectCwd: string,\n command: string = INTRODUCE_HOOK_COMMAND,\n): HookBackup {\n const claudeDir = join(projectCwd, '.claude');\n const createdClaudeDir = !existsSync(claudeDir);\n mkdirSync(claudeDir, { recursive: true });\n\n const settingsPath = join(claudeDir, 'settings.local.json');\n const settingsExisted = existsSync(settingsPath);\n const backupPath = settingsPath + BACKUP_SUFFIX;\n\n let settings: Record<string, unknown> = {};\n if (settingsExisted) {\n // Back up the original verbatim so exit restores it byte-for-byte,\n // then merge our hook into the parsed copy. Guard the copy: if a\n // backup already exists (a prior register that wasn't exited),\n // DON'T clobber it — otherwise exit would restore an already-hooked\n // file instead of the operator's true original. A malformed or\n // non-object JSON root is preserved as the backup but not merged\n // into (start fresh from {}).\n if (!existsSync(backupPath)) {\n copyFileSync(settingsPath, backupPath);\n }\n settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n }\n\n const hooks = asPlainObject(settings['hooks']);\n const existing = Array.isArray(hooks[SESSION_START_KEY])\n ? [...(hooks[SESSION_START_KEY] as Array<Record<string, unknown>>)]\n : [];\n\n const alreadyRegistered = existing.some((entry) =>\n entryMatchesCommand(entry, command),\n );\n if (!alreadyRegistered) {\n existing.push({\n matcher: SESSION_START_MATCHER,\n hooks: [{ type: 'command', command }],\n });\n }\n hooks[SESSION_START_KEY] = existing;\n settings['hooks'] = hooks;\n\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n\n return {\n settings_path: settingsPath,\n settings_backup: settingsExisted ? 'had-file' : 'didnt-exist',\n created_claude_dir: createdClaudeDir,\n };\n}\n\n/**\n * Reverse registerIntroduceHook: restore the backed-up settings file (or\n * remove the one we created) and drop the `.claude` dir if we created it\n * and it's now empty. Best-effort and idempotent — safe to call twice.\n */\nexport function unregisterIntroduceHook(backup: HookBackup): void {\n const { settings_path, settings_backup, created_claude_dir } = backup;\n const backupPath = settings_path + BACKUP_SUFFIX;\n\n if (settings_backup === 'had-file') {\n // Restore the original over our merged version.\n if (existsSync(backupPath)) {\n renameSync(backupPath, settings_path);\n }\n } else {\n // We created it — remove it (and the stray backup, if any).\n if (existsSync(settings_path)) unlinkSync(settings_path);\n if (existsSync(backupPath)) unlinkSync(backupPath);\n }\n\n if (created_claude_dir) {\n const claudeDir = dirOf(settings_path);\n try {\n if (existsSync(claudeDir) && readdirSync(claudeDir).length === 0) {\n rmdirSync(claudeDir);\n }\n } catch {\n // Non-empty (operator added files) or already gone — leave it.\n }\n }\n}\n\nconst SESSION_START_KEY = 'SessionStart';\n\nfunction entryMatchesCommand(entry: Record<string, unknown>, command: string): boolean {\n if ((entry as { matcher?: unknown }).matcher !== SESSION_START_MATCHER) return false;\n const entryHooks = (entry as { hooks?: unknown }).hooks;\n return (\n Array.isArray(entryHooks) &&\n entryHooks.some(\n (h) =>\n typeof h === 'object' &&\n h !== null &&\n (h as { type?: unknown }).type === 'command' &&\n (h as { command?: unknown }).command === command,\n )\n );\n}\n\nfunction dirOf(filePath: string): string {\n const idx = filePath.lastIndexOf('/');\n return idx === -1 ? filePath : filePath.slice(0, idx);\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Coerce a parsed JSON value to a plain object, or {} for null/array/scalar. */\nfunction asPlainObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","/**\n * ENG-5801 — register/unregister the impersonation statusLine in the\n * operator's project dir.\n *\n * `connect` calls `registerStatusLine(projectCwd)` after registering the\n * SessionStart introduce hook. It upserts a `statusLine` key into\n * `<projectCwd>/.claude/settings.local.json` that runs the bundled shell\n * script `~/.augmented-impersonate/statusline.sh` (installed on first\n * connect from the CLI asset at `<package-root>/assets/impersonate-\n * statusline.sh`).\n *\n * While impersonation is active, the project-level `statusLine` overrides\n * the operator's user-level `~/.claude/settings.json` `statusLine` (Local\n * scope > User scope per Claude Code's settings precedence). This is an\n * intentional, ephemeral trade-off — `exit` restores the operator's prior\n * settings.local.json byte-for-byte from a backup, so their user-level\n * statusLine becomes effective again the moment the session ends.\n *\n * The backup mechanism is shared with `registerIntroduceHook` (both\n * features touch the same settings.local.json). The existence guard\n * `if (!existsSync(backupPath))` in each register makes the call order\n * irrelevant — whichever runs first captures the operator's true original;\n * whichever unregister runs first restores it; the other side is then a\n * no-op.\n */\n\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmdirSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { BACKUP_SUFFIX } from './impersonate-fs-ops.js';\nimport type { StatusLineBackup } from './impersonate-state.js';\n\n/**\n * Where we install the runtime statusline script on first connect. Lives\n * outside the operator's project so a `rm -rf .claude` doesn't kill it\n * for subsequent impersonations. The path is what\n * `<projectCwd>/.claude/settings.local.json` references as `statusLine`.\n */\nexport const INSTALLED_STATUSLINE_PATH = join(\n homedir(),\n '.augmented-impersonate',\n 'statusline.sh',\n);\n\nconst STATUS_LINE_KEY = 'statusLine';\nconst STATUS_LINE_COMMAND_TYPE = 'command';\n\n/**\n * Install the bundled statusline asset to INSTALLED_STATUSLINE_PATH if\n * it isn't already there OR if its content differs from the bundled\n * asset. Recopying on content drift lets a new CLI release ship a fixed\n * script without operators having to manually delete the stale copy —\n * matches the \"ship → next self-update applies it\" loop the rest of the\n * codebase assumes. Exported so tests can drive it against a tmp HOME.\n */\nexport function installStatusLineAsset(\n targetPath: string = INSTALLED_STATUSLINE_PATH,\n): void {\n mkdirSync(dirname(targetPath), { recursive: true });\n const source = resolveBundledAssetPath();\n const needsCopy =\n !existsSync(targetPath) ||\n readFileSync(source, 'utf-8') !== readFileSync(targetPath, 'utf-8');\n if (needsCopy) {\n copyFileSync(source, targetPath);\n chmodSync(targetPath, 0o755);\n }\n}\n\n/**\n * Upsert the impersonation statusLine into\n * `<projectCwd>/.claude/settings.local.json`. Returns a StatusLineBackup\n * the manifest stores so `exit` can undo exactly what was done.\n *\n * Idempotent: a repeat call when our statusLine is already registered is\n * a no-op (the existing backup is preserved). Doesn't clobber a backup\n * left behind by an earlier `registerIntroduceHook` — the existence\n * guard wins.\n */\nexport function registerStatusLine(\n projectCwd: string,\n options: { installAsset?: boolean } = {},\n): StatusLineBackup {\n // Tests pass `installAsset: false` to avoid writing into the real\n // ~/.augmented-impersonate/ during the suite. Production callers\n // (connect) accept the default.\n if (options.installAsset !== false) {\n installStatusLineAsset();\n }\n\n const claudeDir = join(projectCwd, '.claude');\n const createdClaudeDir = !existsSync(claudeDir);\n mkdirSync(claudeDir, { recursive: true });\n\n const settingsPath = join(claudeDir, 'settings.local.json');\n const settingsExisted = existsSync(settingsPath);\n const backupPath = settingsPath + BACKUP_SUFFIX;\n\n let settings: Record<string, unknown> = {};\n if (settingsExisted) {\n // Back up the original verbatim — but ONLY if a sibling\n // registerIntroduceHook didn't already do it. Whichever ran first\n // captures the operator's true pre-impersonation state.\n if (!existsSync(backupPath)) {\n copyFileSync(settingsPath, backupPath);\n }\n settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n }\n\n settings[STATUS_LINE_KEY] = {\n type: STATUS_LINE_COMMAND_TYPE,\n command: INSTALLED_STATUSLINE_PATH,\n };\n\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n\n return {\n settings_path: settingsPath,\n settings_backup: settingsExisted ? 'had-file' : 'didnt-exist',\n created_claude_dir: createdClaudeDir,\n };\n}\n\n/**\n * Reverse registerStatusLine: restore the backed-up settings file (or\n * remove the one we created) and drop the `.claude` dir if we created it\n * and it's now empty. Best-effort and idempotent — safe to call twice,\n * and safe to interleave with unregisterIntroduceHook in either order.\n */\nexport function unregisterStatusLine(backup: StatusLineBackup): void {\n const { settings_path, settings_backup, created_claude_dir } = backup;\n const backupPath = settings_path + BACKUP_SUFFIX;\n\n if (settings_backup === 'had-file') {\n // Restore the original over our merged version. If the sibling\n // unregisterIntroduceHook beat us to it, the backup is already gone\n // and the file is already restored — guarded.\n if (existsSync(backupPath)) {\n renameSync(backupPath, settings_path);\n } else if (existsSync(settings_path)) {\n // No backup left to restore — either it's already been restored by\n // the sibling hook unregister, OR we never had a backup because the\n // file was malformed at register time. Either way, the safe thing\n // is to strip just our statusLine key from the current file so we\n // don't leave a dangling pointer to INSTALLED_STATUSLINE_PATH if\n // the operator later deletes ~/.augmented-impersonate.\n stripStatusLineKey(settings_path);\n }\n } else {\n // We created the file — remove it (and the stray backup, if any).\n if (existsSync(settings_path)) unlinkSync(settings_path);\n if (existsSync(backupPath)) unlinkSync(backupPath);\n }\n\n if (created_claude_dir) {\n const claudeDir = dirname(settings_path);\n try {\n if (existsSync(claudeDir) && readdirSync(claudeDir).length === 0) {\n rmdirSync(claudeDir);\n }\n } catch {\n // Non-empty (operator added files) or already gone — leave it.\n }\n }\n}\n\n/**\n * Walk up from this module's location to find the bundled\n * `assets/impersonate-statusline.sh`. Covers both layouts:\n * - dev (tsx): apps/cli/src/lib → apps/cli/assets\n * - built (tsup): apps/cli/dist/<chunk>.js → apps/cli/dist/assets\n * - installed: <pkg>/dist/<chunk>.js → <pkg>/dist/assets\n *\n * Mirrors the resolver strategy in `persistent-session.ts:getAcpxBin`.\n */\nfunction resolveBundledAssetPath(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Built output: dist/<chunk>.js → dist/assets/...\n join(moduleDir, 'assets', 'impersonate-statusline.sh'),\n // Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/...\n join(moduleDir, '..', 'assets', 'impersonate-statusline.sh'),\n // Dev source: src/lib/impersonate-statusline.ts → ../../assets/...\n join(moduleDir, '..', '..', 'assets', 'impersonate-statusline.sh'),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n throw new Error(\n `[impersonate-statusline] could not locate bundled asset; tried:\\n ${candidates.join('\\n ')}`,\n );\n}\n\nfunction stripStatusLineKey(settingsPath: string): void {\n const settings = asPlainObject(safeParseJson(readFileSync(settingsPath, 'utf-8')));\n if (!(STATUS_LINE_KEY in settings)) return;\n delete settings[STATUS_LINE_KEY];\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\\n');\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Coerce a parsed JSON value to a plain object, or {} for null/array/scalar. */\nfunction asPlainObject(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","/**\n * ENG-5750 — pure helpers for the impersonation \"introduce yourself\"\n * SessionStart hook.\n *\n * When an operator `agt impersonate connect`s, a SessionStart hook fires\n * on the fresh Claude Code boot and shells out to `agt impersonate\n * introduce`. That command reads the persona snapshot already written to\n * the project dir at connect time — `CLAUDE.md` (identity) and\n * `.mcp.json` (connected MCP servers / integrations) — and prints a\n * short first-person introduction. No network, no token use.\n *\n * These three functions are the testable core: parsing identity out of\n * the generated CLAUDE.md, parsing the integration list out of\n * .mcp.json, and rendering the introduction text. The command wrapper\n * (impersonate.ts) handles the manifest guard, file IO, and soft-fail.\n *\n * The CLAUDE.md shape parsed here is produced by `generateClaudeMd`\n * (packages/core/src/provisioning/frameworks/claudecode/identity.ts):\n *\n * # <display_name>\n *\n * You are **<display_name>**, **<role>** in the **<team>** team at **<org>**.\n * ...\n */\n\nexport interface ParsedIdentity {\n displayName: string | null;\n role: string | null;\n}\n\n/**\n * Extract the agent's display name and role from a generated CLAUDE.md.\n *\n * - `displayName` ← the first `# <heading>` line.\n * - `role` ← the bolded role in the `You are **<name>**, **<role>**…`\n * identity sentence.\n *\n * Either field is `null` when its source line is absent — callers\n * degrade gracefully rather than fail (ENG-5750 soft-fail AC).\n */\nexport function parseIdentityFromClaudeMd(content: string): ParsedIdentity {\n const headingMatch = content.match(/^#\\s+(.+?)\\s*$/m);\n const displayName = headingMatch?.[1]?.trim() || null;\n\n // `You are **Koda**, **Software Developer** in the **…** team…`\n // The role is the SECOND bolded span on the identity line. Anchored to\n // the `You are ` prefix so we don't accidentally match other bold text.\n const roleMatch = content.match(\n /^You are \\*\\*[^*]+\\*\\*,\\s*\\*\\*([^*]+)\\*\\*/m,\n );\n const role = roleMatch?.[1]?.trim() || null;\n\n return { displayName, role };\n}\n\n/**\n * Extract the connected integration / MCP server names from a generated\n * `.mcp.json` (the `mcpServers` object's keys), prettified for display.\n *\n * Returns `[]` on malformed JSON or a missing/empty `mcpServers` map —\n * the caller treats an empty list as \"no integrations\" rather than an\n * error.\n */\nexport function parseIntegrationsFromMcpJson(content: string): string[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return [];\n }\n const servers = (parsed as { mcpServers?: unknown } | null)?.mcpServers;\n if (!servers || typeof servers !== 'object' || Array.isArray(servers)) {\n return [];\n }\n return Object.keys(servers as Record<string, unknown>).map(prettifyServerName);\n}\n\n/**\n * Turn an MCP server key (`direct-chat`, `task_channel`) into a\n * human-readable label (`Direct Chat`, `Task Channel`) for the intro.\n */\nfunction prettifyServerName(key: string): string {\n return key\n .split(/[-_]/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nexport interface IntroductionInput {\n displayName: string | null;\n codeName: string;\n role: string | null;\n integrations: string[];\n}\n\n/**\n * Render the first-person introduction printed into the fresh session.\n *\n * Shape (fields degrade independently when missing):\n *\n * I'm Koda (koda), Software Developer.\n *\n * Connected integrations: Slack, Telegram, Augmented.\n *\n * - No display name → fall back to the code name as the spoken name.\n * - No role → drop the role clause.\n * - No integrations → say so explicitly rather than emit a dangling line.\n */\nexport function buildIntroduction(input: IntroductionInput): string {\n const { displayName, codeName, role, integrations } = input;\n\n const spokenName = displayName || codeName;\n // Show \"(code-name)\" only when it adds information beyond the spoken name.\n const codeSuffix = displayName && displayName !== codeName ? ` (${codeName})` : '';\n const roleClause = role ? `, ${role}` : '';\n\n const lines: string[] = [`I'm ${spokenName}${codeSuffix}${roleClause}.`, ''];\n\n if (integrations.length > 0) {\n lines.push(`Connected integrations: ${integrations.join(', ')}.`);\n // ENG-5812: when the operator asks \"list your integrations\", call\n // `tools/list` on each MCP server above and report what each\n // actually exposes — do NOT narrate the integration list from\n // CHARTER.md. CHARTER describes the agent's design intent;\n // tools/list is the running ground truth. Real example of why:\n // an agent whose CHARTER mentions Linear via Composio + AWS\n // native that's actually only mounted as `augmented` should\n // answer \"augmented exposes the following tools: …\" not\n // \"I have Linear and AWS\".\n lines.push('');\n lines.push(\n \"If the operator asks what you can do, call each MCP server's \" +\n '`tools/list` and report the actual tool inventory. Do not narrate ' +\n 'capabilities from CHARTER.md — it describes intent, not runtime ' +\n 'state. Tools that fail to enumerate (server failed to spawn, env ' +\n 'missing, etc.) should be reported as such, not silently omitted.',\n );\n } else {\n lines.push('No integrations are connected.');\n }\n\n return lines.join('\\n');\n}\n","/**\n * ENG-5812 — rewrite the server-rendered `.mcp.json` so the operator's\n * local Claude Code can actually spawn the agent's MCP servers.\n *\n * Why this exists\n * ---------------\n * The redeem endpoint (`POST /impersonate/agent/redeem` in\n * packages/api/src/routes/impersonate.ts) calls `provision()` with\n * `deploymentTarget: 'local_docker'`. The claudecode framework adapter\n * uses `getHomeDir()` (the SERVER's runtime home — `/home/sbx_user1051`\n * on Lambda) and bakes that path into the rendered `.mcp.json`'s\n * `args`. It also leaves `AGT_HOST` / `AGT_API_KEY` / `HOME` empty\n * because those are normally filled by the deployment process, not by\n * provisioning. The artifact is structurally a *Lambda runtime\n * artifact*, not an *operator-side artifact*.\n *\n * When the operator's Claude Code tries to spawn `node\n * /home/sbx_user1051/.augmented/_mcp/index.js`, it ENOENTs — the path\n * doesn't exist on their Mac. Net effect: every MCP server in the\n * rendered persona fails to start, the impersonated agent has zero\n * working tools, and any \"list your integrations\" answer is the agent\n * narrating from CHARTER.md memory (which is what observably happens\n * — see Sherlock's reproduction in ENG-5812's description).\n *\n * Until the server learns about an \"impersonation\" deployment target\n * (Scope B), the CLI post-processes the artifact before swapping it\n * into the operator's project. We substitute:\n *\n * - Any `args` path matching `/home/<x>/.augmented/_mcp/<file>` with\n * `<cliMcpBundleDir>/<file>`. The CLI ships its own copy of the\n * channel + gateway MCP bundles via `build:mcp-assets`, so the\n * binaries are already on disk wherever the operator installed\n * `@integrity-labs/agt-cli`.\n * - Empty `env.AGT_HOST` with the API host the redeem was performed\n * against (so the gateway calls back to the right env).\n * - Empty `env.AGT_API_KEY` with the impersonation JWT (so the\n * gateway authenticates as the impersonating principal — the JWT\n * carries `act_as_agent_id` for attribution).\n * - Empty `env.HOME` with the operator's `$HOME`.\n * - Empty `env.AGT_AGENT_ID` / `env.AGT_AGENT_CODE_NAME` with the\n * redeem-known values — the renderer fills these but they may be\n * missing on a future server change; defence-in-depth.\n *\n * Pre-populated env values are NOT overwritten — the server's\n * intentional choice wins. Only empty/missing entries get the\n * impersonation-time substitution.\n *\n * Two env keys are the exception and ARE rewritten unconditionally,\n * because the server's value is structurally wrong for the operator\n * (ENG-5818):\n *\n * - `PATH` is baked at provision time as the SERVER's runtime PATH.\n * On the redeem Lambda that's an AWS Lambda PATH\n * (`/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin`) — none of\n * those dirs hold `node` on a typical macOS nvm/Homebrew host, and\n * because `env.PATH` overrides the inherited PATH the `command:\n * \"node\"` spawn ENOENTs (exit 127) and EVERY server fails to start.\n * We replace it with an operator-correct PATH (see `operatorPath`).\n * - `AGT_RUN_ID` is emitted as the literal `${AGT_RUN_ID}` sentinel\n * for a manager to substitute at spawn time. An impersonation\n * session has no manager and no `runs` row, so the placeholder is\n * never expanded. Run-id columns FK `runs(n)`, so the only correct\n * value is \"unset\" — we drop the key (the augmented MCP bridge maps\n * a missing/empty AGT_RUN_ID to a null run id; leaving the literal\n * would leak a bogus non-empty run id into broker calls).\n *\n * Pure function (no I/O); the caller (`impersonateConnectCommand`) does\n * the file-write. Exported for unit tests.\n */\n\nexport interface ImpersonationMcpRewriteContext {\n /** `process.env.HOME` on the operator's machine. */\n operatorHome: string;\n /**\n * ENG-5818: a host-correct `PATH` for the operator's machine, used to\n * overwrite the server-baked (Lambda) PATH so `command: \"node\"` resolves.\n * The caller builds this from the running node's bin dir prepended to\n * the operator's own `process.env.PATH` (see `resolveOperatorPath` in\n * commands/impersonate.ts).\n */\n operatorPath: string;\n /**\n * Absolute path to the CLI's bundled `dist/mcp/` directory (which\n * holds index.js / slack-channel.js / telegram-channel.js /\n * direct-chat-channel.js via build:mcp-assets). The caller resolves\n * this from `import.meta.url` at runtime.\n */\n cliMcpBundleDir: string;\n /** Impersonation JWT (`bundle.token`). Legacy host-key-slot credential. */\n impersonationToken: string;\n /**\n * ENG-5874: the portable agent-session token (`bundle.agent_session_token`)\n * the augmented MCP server presents directly as Bearer (skipping\n * /host/exchange, which 401s the impersonation JWT). Null for pre-org teams /\n * a non-fatal redeem-side mint failure — the server then falls back to the\n * (broken-for-impersonation) host-key path.\n */\n agentSessionToken: string | null;\n /** API host the redeem was exchanged against (e.g. `https://api.augmented.team`). */\n apiHost: string;\n /** The impersonated agent's UUID. */\n agentId: string;\n /** The impersonated agent's `code_name`. */\n agentCodeName: string;\n}\n\n/** Matches `/home/<anything-not-slash>/.augmented/_mcp/<filename>`. */\nconst SERVER_HOME_MCP_PATH_RE =\n /^\\/home\\/[^/]+\\/\\.augmented\\/_mcp\\/([^/]+)$/;\n\n/**\n * ENG-5953 — server keys whose entries are channel MCP servers (Slack /\n * Telegram / Teams / Direct Chat / Discord), injected by the redeem flow\n * for an agent's configured channels. We stamp `AGT_ACT_AS_AGENT_ID` onto\n * their env so the ENG-5689 egress gate (`isImpersonating()` in\n * packages/mcp/src/impersonation.ts) fails CLOSED — channel sends stay\n * refused-by-default — even if Claude Code ever stops passing the launch\n * env (`buildImpersonateClaudeLaunch` sets the same var) through to MCP\n * children. The operator still opts in to sends with\n * `ENABLE_IMPERSONATION_CHANNELS=true`, which flows in via that same\n * inherited env.\n */\nconst CHANNEL_SERVER_KEYS = new Set([\n 'slack',\n 'telegram',\n 'msteams',\n 'direct-chat',\n 'discord',\n]);\n\n/**\n * Rewrite the persona `.mcp.json` so the operator's local Claude Code\n * can spawn the MCP servers. Returns a new JSON string; never mutates\n * the input. Throws if the input isn't valid JSON or doesn't have an\n * object-typed `mcpServers` field — the caller already validated the\n * redeem response shape, so a throw here means the server changed its\n * contract.\n */\nexport function rewriteMcpJsonForImpersonation(\n mcpJson: string,\n ctx: ImpersonationMcpRewriteContext,\n): string {\n const parsed = JSON.parse(mcpJson) as unknown;\n if (!isPlainObject(parsed)) {\n throw new Error(\n `rewriteMcpJsonForImpersonation: expected an object at the JSON root, got ${typeof parsed}`,\n );\n }\n const servers = parsed['mcpServers'];\n if (!isPlainObject(servers)) {\n throw new Error(\n 'rewriteMcpJsonForImpersonation: expected an object-typed `mcpServers` field',\n );\n }\n\n const rewrittenServers: Record<string, unknown> = {};\n for (const [serverName, raw] of Object.entries(servers)) {\n rewrittenServers[serverName] = rewriteServerEntry(serverName, raw, ctx);\n }\n\n const out = { ...parsed, mcpServers: rewrittenServers };\n return JSON.stringify(out, null, 2);\n}\n\nfunction rewriteServerEntry(\n serverName: string,\n raw: unknown,\n ctx: ImpersonationMcpRewriteContext,\n): unknown {\n if (!isPlainObject(raw)) return raw;\n\n // ── args: replace any /home/<x>/.augmented/_mcp/<file> with the\n // operator's CLI bundle dir.\n let args = raw['args'];\n if (Array.isArray(args)) {\n args = args.map((arg) => {\n if (typeof arg !== 'string') return arg;\n const m = SERVER_HOME_MCP_PATH_RE.exec(arg);\n if (!m) return arg;\n return `${ctx.cliMcpBundleDir}/${m[1]}`;\n });\n }\n\n // ── env: fill empty/missing impersonation-time values without\n // clobbering anything the server explicitly populated.\n const env = isPlainObject(raw['env']) ? { ...raw['env'] } : {};\n fillIfEmpty(env, 'AGT_HOST', ctx.apiHost);\n fillIfEmpty(env, 'AGT_API_KEY', ctx.impersonationToken);\n // ENG-5874: the augmented MCP server prefers this token (used directly as\n // Bearer) over AGT_API_KEY. Only set when redeem returned one.\n if (ctx.agentSessionToken) {\n fillIfEmpty(env, 'AGT_AGENT_SESSION_TOKEN', ctx.agentSessionToken);\n }\n fillIfEmpty(env, 'HOME', ctx.operatorHome);\n fillIfEmpty(env, 'AGT_AGENT_ID', ctx.agentId);\n fillIfEmpty(env, 'AGT_AGENT_CODE_NAME', ctx.agentCodeName);\n\n // ── ENG-5818 Bug 1: force a host-correct PATH ────────────────────────\n // The server bakes its own runtime PATH (Lambda PATH on the redeem\n // Lambda). It's never right for the operator, so overwrite it\n // unconditionally rather than only-if-empty. Only do so when the\n // server actually emitted a PATH key — a server entry with no PATH\n // inherits the spawn PATH, which is already correct.\n if ('PATH' in env) {\n env['PATH'] = ctx.operatorPath;\n }\n\n // ── ENG-5818 Bug 3: drop the unsubstituted AGT_RUN_ID placeholder ────\n // No manager + no `runs` row in an impersonation session, so the\n // `${AGT_RUN_ID}` sentinel is never expanded. Run-id columns FK\n // runs(n); the only correct value is \"unset\". Dropping the key lets\n // consumers fall back to their null-run behaviour instead of treating\n // the literal placeholder as a (truthy, bogus) run id.\n if (env['AGT_RUN_ID'] === '${AGT_RUN_ID}') {\n delete env['AGT_RUN_ID'];\n }\n\n // ── ENG-5953: fail-closed impersonation marker on channel servers ────\n // Set unconditionally (not fillIfEmpty) so the egress gate engages even\n // if a future redeem build emitted a stale value. Scoped to channel\n // server keys so the `augmented` gateway + native integrations are\n // untouched.\n if (CHANNEL_SERVER_KEYS.has(serverName)) {\n env['AGT_ACT_AS_AGENT_ID'] = ctx.agentId;\n }\n\n return { ...raw, args, env };\n}\n\n/**\n * Set `env[key] = value` when the current value is missing/empty — or\n * when it is the key's own literal `${KEY}` placeholder. ENG-5901\n * Track D: the server now renders secrets (AGT_API_KEY et al.) as\n * `${VAR}` templates for the manager's spawn env to satisfy; an\n * impersonation session has no manager env, and Claude Code hard-fails\n * config parse on an unset defaultless `${VAR}`, so the self-placeholder\n * must be treated as fillable here. Pre-populated concrete values are\n * still never overwritten.\n */\nfunction fillIfEmpty(\n env: Record<string, unknown>,\n key: string,\n value: string,\n): void {\n const current = env[key];\n if (\n typeof current !== 'string' ||\n current.length === 0 ||\n current === `\\${${key}}`\n ) {\n env[key] = value;\n }\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport {\n detectDrift,\n getFramework,\n type DriftReport,\n type DriftFinding,\n type RiskTier,\n} from '@augmented/core';\nimport { readLiveState } from '@augmented/core/drift/live-state-reader.js';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, warn, info, table } from '../lib/output.js';\nimport { isJsonMode } from '../lib/globals.js';\n\nconst KEBAB_CASE_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;\n\nfunction severityColor(severity: string): string {\n switch (severity) {\n case 'critical':\n return chalk.red(severity);\n case 'warning':\n return chalk.yellow(severity);\n default:\n return chalk.dim(severity);\n }\n}\n\nfunction printDriftReport(report: DriftReport): void {\n console.log(chalk.bold(`\\nDrift Report: ${report.codeName}\\n`));\n\n info(`Agent ID: ${report.agentId}`);\n info(`Checked at: ${report.checkedAt.toISOString()}`);\n console.log();\n\n if (!report.hasDrift) {\n success('No drift detected. Agent matches provisioned state.');\n return;\n }\n\n warn(`Drift detected: ${report.criticalCount} critical, ${report.warningCount} warning`);\n console.log();\n\n const rows = report.findings.map((f: DriftFinding) => [\n severityColor(f.severity),\n f.category,\n f.field,\n f.message,\n ]);\n\n table(['Severity', 'Category', 'Field', 'Message'], rows);\n}\n\ninterface DriftCheckOpts {\n json?: boolean;\n audit?: boolean;\n config?: string;\n}\n\n/**\n * `agt drift check <code-name>`\n */\nexport async function driftCheckCommand(\n codeName: string,\n opts: DriftCheckOpts,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n if (!KEBAB_CASE_RE.test(codeName)) {\n error('Invalid code-name. Must be kebab-case (e.g. \"my-agent\").');\n process.exitCode = 1;\n return;\n }\n\n const useJson = opts.json || isJsonMode();\n\n const spinner = ora({ text: `Checking drift for \"${codeName}\"…`, isSilent: useJson });\n spinner.start();\n\n try {\n // Fetch drift data via API\n const driftData = await api.get<{\n agent: Record<string, unknown>;\n snapshot: Record<string, unknown> | null;\n charter: { raw_content: string; version: string } | null;\n tools: { raw_content: string; version: string } | null;\n }>(`/agents/${encodeURIComponent(codeName)}/drift-data`);\n\n const agent = driftData.agent;\n const snapshot = driftData.snapshot;\n\n if (!snapshot) {\n spinner.fail(`No provision snapshot found for \"${codeName}\". Run \\`agt provision\\` first.`);\n error('No provision snapshot available');\n process.exitCode = 1;\n return;\n }\n\n // Resolve adapter from agent's framework field\n const frameworkId = (agent.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n const trackedFiles = adapter.driftTrackedFiles();\n\n // Read live state from disk (team-scoped to prevent cross-team collisions)\n const defaultDir = `.augmented/${teamSlug}/${codeName}/provision`;\n const configPath = opts.config ?? `${defaultDir}/${trackedFiles[0]}`;\n\n const liveState = await readLiveState({\n configPath,\n teamDir: defaultDir,\n trackedFiles,\n runAudit: opts.audit,\n });\n\n // Run drift detection\n const report = detectDrift(\n {\n frameworkConfig: (snapshot.openclaw_config ?? {}) as Record<string, unknown>,\n charterHash: snapshot.charter_hash as string ?? '',\n toolsHash: snapshot.tools_hash as string ?? '',\n toolAllow: snapshot.tool_allow as string[] ?? [],\n toolDeny: snapshot.tool_deny as string[] ?? [],\n channelsConfig: (snapshot.channels_config ?? {}) as Record<string, unknown>,\n sandboxMode: snapshot.sandbox_mode as string ?? 'all',\n },\n liveState,\n agent.agent_id as string,\n codeName,\n (agent.risk_tier as RiskTier) ?? 'Medium',\n );\n\n spinner.stop();\n\n if (useJson) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n printDriftReport(report);\n }\n\n if (report.hasDrift) {\n process.exitCode = 1;\n }\n } catch (err) {\n spinner.fail('Drift check failed.');\n error((err as Error).message);\n process.exitCode = 1;\n }\n}\n\ninterface DriftWatchOpts {\n interval?: string;\n webhook?: string;\n json?: boolean;\n config?: string;\n}\n\n/**\n * `agt drift watch <code-name>`\n */\nexport async function driftWatchCommand(\n codeName: string,\n opts: DriftWatchOpts,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n if (!KEBAB_CASE_RE.test(codeName)) {\n error('Invalid code-name. Must be kebab-case (e.g. \"my-agent\").');\n process.exitCode = 1;\n return;\n }\n\n const useJson = opts.json || isJsonMode();\n\n const intervalSec = parseInt(opts.interval ?? '60', 10);\n if (isNaN(intervalSec) || intervalSec < 1) {\n error('Interval must be a positive number of seconds.');\n process.exitCode = 1;\n return;\n }\n\n // Resolve agent once up front\n let agent: Record<string, unknown>;\n try {\n const data = await api.get<{ agent: Record<string, unknown> }>(`/agents/${encodeURIComponent(codeName)}`);\n agent = data.agent;\n } catch (err) {\n error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n\n // Resolve adapter from agent's framework field\n const frameworkId = (agent.framework as string) ?? 'openclaw';\n const adapter = getFramework(frameworkId);\n const trackedFiles = adapter.driftTrackedFiles();\n\n if (!useJson) {\n console.log(\n chalk.bold(`\\nWatching drift for \"${codeName}\" every ${intervalSec}s. Press Ctrl+C to stop.\\n`),\n );\n }\n\n let previousFindingCount = -1;\n\n const runCheck = async (): Promise<void> => {\n const spinner = ora({ text: `Checking drift for \"${codeName}\"…`, isSilent: useJson });\n spinner.start();\n\n try {\n const driftData = await api.get<{\n snapshot: Record<string, unknown> | null;\n }>(`/agents/${encodeURIComponent(codeName)}/drift-data`);\n\n const snapshot = driftData.snapshot;\n if (!snapshot) {\n spinner.warn('No provision snapshot found. Skipping check.');\n return;\n }\n\n const watchDefaultDir = `.augmented/${teamSlug}/${codeName}/provision`;\n const configPath = opts.config ?? `${watchDefaultDir}/${trackedFiles[0]}`;\n\n const liveState = await readLiveState({\n configPath,\n teamDir: watchDefaultDir,\n trackedFiles,\n });\n\n const report = detectDrift(\n {\n frameworkConfig: (snapshot.openclaw_config ?? {}) as Record<string, unknown>,\n charterHash: snapshot.charter_hash as string ?? '',\n toolsHash: snapshot.tools_hash as string ?? '',\n toolAllow: snapshot.tool_allow as string[] ?? [],\n toolDeny: snapshot.tool_deny as string[] ?? [],\n channelsConfig: (snapshot.channels_config ?? {}) as Record<string, unknown>,\n sandboxMode: snapshot.sandbox_mode as string ?? 'all',\n },\n liveState,\n agent.agent_id as string,\n codeName,\n (agent.risk_tier as RiskTier) ?? 'Medium',\n );\n\n spinner.stop();\n\n const isNew = report.findings.length !== previousFindingCount;\n previousFindingCount = report.findings.length;\n\n if (useJson) {\n console.log(JSON.stringify(report, null, 2));\n } else if (report.hasDrift) {\n printDriftReport(report);\n } else {\n success(`[${new Date().toLocaleTimeString()}] No drift detected.`);\n }\n\n if (isNew && report.hasDrift && opts.webhook) {\n try {\n await fetch(opts.webhook, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(report),\n });\n if (!useJson) info(`Webhook notified: ${opts.webhook}`);\n } catch (webhookErr) {\n if (!useJson) warn(`Failed to notify webhook: ${(webhookErr as Error).message}`);\n }\n }\n } catch (err) {\n spinner.fail('Drift check failed.');\n error((err as Error).message);\n }\n };\n\n await runCheck();\n\n const timer = setInterval(() => {\n void runCheck();\n }, intervalSec * 1000);\n\n process.on('SIGINT', () => {\n clearInterval(timer);\n if (!useJson) console.log(chalk.dim('\\nStopped watching.'));\n process.exit(0);\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { join } from 'node:path';\nimport JSON5 from 'json5';\nimport type { DriftCheckOptions, LiveState } from './types.js';\n\nasync function hashFile(filePath: string): Promise<string | null> {\n try {\n const content = await readFile(filePath);\n return createHash('sha256').update(content).digest('hex');\n } catch {\n return null;\n }\n}\n\nasync function readJsonFile(filePath: string): Promise<Record<string, unknown> | null> {\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON5.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function readLiveState(options: DriftCheckOptions): Promise<LiveState> {\n const trackedFiles = options.trackedFiles ?? ['openclaw.json5', 'CHARTER.md', 'TOOLS.md'];\n\n // Config file is the first tracked file (framework-specific config)\n // CHARTER.md and TOOLS.md are identified by name within the tracked list\n const charterFile = trackedFiles.find((f) => f.includes('CHARTER')) ?? 'CHARTER.md';\n const toolsFile = trackedFiles.find((f) => f.includes('TOOLS')) ?? 'TOOLS.md';\n\n const [frameworkConfig, charterHash, toolsHash] = await Promise.all([\n readJsonFile(options.configPath),\n hashFile(join(options.teamDir, charterFile)),\n hashFile(join(options.teamDir, toolsFile)),\n ]);\n\n return {\n frameworkConfig,\n charterHash,\n toolsHash,\n configPath: options.configPath,\n };\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api, getHostId } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// agt host list\n// ---------------------------------------------------------------------------\n\nexport async function hostListCommand(): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching hosts\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.get<{\n hosts: Array<{\n name: string;\n status: string;\n description: string | null;\n framework: string;\n agents: number;\n last_seen_at: string | null;\n key_prefix: string | null;\n created_at: string;\n }>;\n }>('/hosts');\n\n spinner.stop();\n\n if (!data.hosts || data.hosts.length === 0) {\n if (json) {\n jsonOutput({ ok: true, hosts: [] });\n } else {\n info('No hosts found. Create one with `agt host create --name <name>`.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, hosts: data.hosts });\n return;\n }\n\n const rows = data.hosts.map((h) => {\n const status = h.status === 'active'\n ? chalk.green('active')\n : chalk.red('decommissioned');\n\n const agents = String(h.agents);\n\n const lastSeen = h.last_seen_at\n ? new Date(h.last_seen_at).toLocaleDateString()\n : chalk.dim('never');\n\n const prefix = h.key_prefix\n ? `tlk_${h.key_prefix}\\u2026`\n : chalk.dim('none');\n\n return [h.name, status, agents, lastSeen, prefix];\n });\n\n table(['Name', 'Status', 'Agents', 'Last Seen', 'Key'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch hosts.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host assign\n// ---------------------------------------------------------------------------\n\ninterface HostAssignOptions {\n force?: boolean;\n}\n\nexport async function hostAssignCommand(\n hostName: string,\n agentCodeNames: string[],\n opts: HostAssignOptions,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!agentCodeNames || agentCodeNames.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'At least one agent code name is required' });\n } else {\n error('At least one agent code name is required.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Assigning agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/assign`, {\n agents: agentCodeNames,\n force: opts.force,\n });\n\n spinner.succeed(`Agents assigned to ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({ ok: true, host: hostName, assigned: agentCodeNames });\n return;\n }\n\n for (const name of agentCodeNames) {\n info(` ${name}`);\n }\n } catch (err) {\n spinner.fail('Failed to assign agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host unassign\n// ---------------------------------------------------------------------------\n\nexport async function hostUnassignCommand(\n hostName: string,\n agentCodeNames: string[],\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n\n if (!agentCodeNames || agentCodeNames.length === 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'At least one agent code name is required' });\n } else {\n error('At least one agent code name is required.');\n }\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora({ text: 'Unassigning agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/unassign`, {\n agents: agentCodeNames,\n });\n\n spinner.succeed(`Agents unassigned from ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({ ok: true, host: hostName, unassigned: agentCodeNames });\n return;\n }\n\n for (const name of agentCodeNames) {\n info(` ${name}`);\n }\n } catch (err) {\n spinner.fail('Failed to unassign agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host agents [host-name]\n// ---------------------------------------------------------------------------\n\nexport async function hostAgentsCommand(hostName?: string): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching host agents\\u2026', isSilent: json });\n spinner.start();\n\n try {\n // If no host name given, use the API key's host identity via /host/agents\n const hostId = await getHostId();\n\n if (!hostName && !hostId) {\n spinner.fail('No host specified.');\n if (json) {\n jsonOutput({ ok: false, error: 'Provide a host name or use an AGT_API_KEY' });\n } else {\n error('Provide a host name, or set AGT_API_KEY to auto-resolve the host.');\n }\n process.exitCode = 1;\n return;\n }\n\n let agents: Array<{\n code_name: string;\n display_name: string;\n status: string;\n environment: string;\n risk_tier?: string;\n assigned_at?: string;\n }>;\n\n if (hostId && !hostName) {\n // Host runtime path — resolve from API key\n const data = await api.post<{\n agents: typeof agents;\n }>('/host/agents', { host_id: hostId });\n agents = data.agents ?? [];\n } else {\n // Dashboard path — look up by name\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const data = await api.get<{\n agents: typeof agents;\n }>(`/hosts/${encodeURIComponent(hostName!)}/agents`);\n agents = data.agents ?? [];\n }\n\n spinner.stop();\n\n if (agents.length === 0) {\n if (json) {\n jsonOutput({ ok: true, agents: [] });\n } else {\n info('No agents assigned to this host.');\n info('Assign agents with `agt host assign <host-name> <agent-code-name>`.');\n }\n return;\n }\n\n if (json) {\n jsonOutput({ ok: true, agents });\n return;\n }\n\n const rows = agents.map((a) => {\n const statusColor = a.status === 'active' ? chalk.green : chalk.yellow;\n return [\n a.code_name,\n a.display_name,\n statusColor(a.status),\n a.environment,\n ];\n });\n\n table(['Code Name', 'Display Name', 'Status', 'Environment'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch host agents.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host rotate-key\n// ---------------------------------------------------------------------------\n\nexport async function hostRotateKeyCommand(hostName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Rotating host key\\u2026', isSilent: json });\n spinner.start();\n\n try {\n const data = await api.post<{\n ok: boolean;\n host: string;\n key: { prefix: string; raw_key: string };\n }>(`/hosts/${encodeURIComponent(hostName)}/rotate-key`);\n\n spinner.succeed(`Key rotated for ${chalk.bold(hostName)}.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n host: hostName,\n key: data.key,\n });\n return;\n }\n\n console.log();\n info(`Host: ${chalk.bold(hostName)}`);\n info(`Prefix: ${data.key.prefix}`);\n console.log();\n console.log(chalk.yellow.bold(' Save this key now \\u2014 it will not be shown again:'));\n console.log();\n console.log(` ${chalk.green.bold(data.key.raw_key)}`);\n console.log();\n } catch (err) {\n spinner.fail('Failed to rotate key.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host maintenance-window\n// ---------------------------------------------------------------------------\n\ninterface HostMaintenanceWindowOptions {\n start?: string;\n end?: string;\n tz?: string;\n clear?: boolean;\n}\n\ninterface MaintenanceWindowResponse {\n override: {\n maintenance_window_start: string | null;\n maintenance_window_end: string | null;\n maintenance_timezone: string | null;\n };\n effective: { start: string; end: string; timezone: string };\n}\n\nexport async function hostMaintenanceWindowCommand(\n hostName: string,\n opts: HostMaintenanceWindowOptions,\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const path = `/hosts/${encodeURIComponent(hostName)}/maintenance-window`;\n const setting =\n opts.clear || opts.start !== undefined || opts.end !== undefined || opts.tz !== undefined;\n\n // Show mode — no set flags.\n if (!setting) {\n const spinner = ora({ text: 'Fetching maintenance window…', isSilent: json });\n spinner.start();\n try {\n const data = await api.get<MaintenanceWindowResponse>(path);\n spinner.stop();\n if (json) {\n jsonOutput({ ok: true, ...data });\n return;\n }\n const ov = data.override;\n const hasOverride =\n ov.maintenance_window_start !== null ||\n ov.maintenance_window_end !== null ||\n ov.maintenance_timezone !== null;\n info(`Host: ${chalk.bold(hostName)}`);\n info(\n `Effective: ${chalk.green(`${data.effective.start}–${data.effective.end}`)} ${data.effective.timezone}`,\n );\n info(\n `Override: ${hasOverride ? chalk.cyan('set') : chalk.dim('none (default 01:00–02:00)')}`,\n );\n info('Set with --start/--end/--tz, or --clear to follow the default.');\n } catch (err) {\n spinner.fail('Failed to fetch maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n }\n return;\n }\n\n // Set/clear mode. Require both --start and --end together (the window needs\n // both bounds; clearing one without the other is ambiguous).\n // --clear is exclusive: combining it with set flags is contradictory, and\n // silently honouring --clear while ignoring --start/--end/--tz would do the\n // opposite of what the operator likely intended. Fail fast.\n if (opts.clear && (opts.start !== undefined || opts.end !== undefined || opts.tz !== undefined)) {\n const msg = 'Use --clear on its own — it cannot be combined with --start/--end/--tz.';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n if (!opts.clear && (opts.start === undefined) !== (opts.end === undefined)) {\n const msg = 'Provide both --start and --end (or use --clear).';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n // A timezone without time bounds is meaningless — reject --tz on its own.\n if (!opts.clear && opts.tz !== undefined && opts.start === undefined) {\n const msg = 'Provide --start and --end when setting --tz (or use --clear).';\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n // When setting times without an explicit --tz, preserve the host's existing\n // timezone override rather than silently clearing it (the API replaces all\n // three fields, so we must send the current tz to keep it).\n let resolvedTz: string | null = opts.tz ?? null;\n if (!opts.clear && opts.tz === undefined) {\n try {\n const cur = await api.get<MaintenanceWindowResponse>(path);\n resolvedTz = cur.override.maintenance_timezone;\n } catch (err) {\n const spinner0 = ora({ isSilent: json });\n spinner0.fail('Failed to read current maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n return;\n }\n }\n\n const payload = opts.clear\n ? { maintenance_window_start: null, maintenance_window_end: null, maintenance_timezone: null }\n : {\n maintenance_window_start: opts.start ?? null,\n maintenance_window_end: opts.end ?? null,\n maintenance_timezone: resolvedTz,\n };\n\n const spinner = ora({ text: 'Updating maintenance window…', isSilent: json });\n spinner.start();\n try {\n const data = await api.post<{\n maintenance_window: { start: string | null; end: string | null; timezone: string | null };\n note?: string;\n }>(path, payload);\n spinner.succeed(`Maintenance window updated for ${chalk.bold(hostName)}.`);\n if (json) {\n jsonOutput({ ok: true, ...data });\n return;\n }\n if (data.note) info(data.note);\n } catch (err) {\n spinner.fail('Failed to update maintenance window.');\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error((err as Error).message);\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt host decommission\n// ---------------------------------------------------------------------------\n\nexport async function hostDecommissionCommand(hostName: string): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const spinner = ora({ text: 'Decommissioning host\\u2026', isSilent: json });\n spinner.start();\n\n try {\n await api.post(`/hosts/${encodeURIComponent(hostName)}/decommission`);\n\n spinner.succeed(`Host \"${chalk.bold(hostName)}\" decommissioned.`);\n\n if (json) {\n jsonOutput({\n ok: true,\n host: hostName,\n status: 'decommissioned',\n });\n return;\n }\n\n info(`Host: ${hostName}`);\n info(`Status: ${chalk.red('decommissioned')}`);\n info('API key revoked. Agents remain assigned for audit visibility.');\n info('Reassign agents to another host with `agt host assign --force`.');\n } catch (err) {\n spinner.fail('Failed to decommission host.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { spawn, spawnSync, type ChildProcess } from 'node:child_process';\nimport chalk from 'chalk';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { error, info, success } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface HostDetail {\n id: string;\n name: string;\n status: string;\n framework: string;\n provision_source: 'self' | 'augmented-ec2' | null;\n ec2_instance_id: string | null;\n ec2_region: string | null;\n claude_auth_mode: string | null;\n claude_auth_status: string | null;\n claude_auth_expires_at: string | null;\n}\n\n/**\n * agt host pair <name>\n *\n * Orchestrates a Claude Code `/login` flow on a remote EC2 host by:\n * 1. Looking up the host's EC2 instance ID via the API\n * 2. Starting an SSM port-forward tunnel on a chosen local port\n * 3. Opening an interactive SSM shell session on the remote host\n *\n * The operator then runs `claude /login` inside the shell, clicks the URL\n * Claude Code prints, completes OAuth in the browser — the callback lands on\n * localhost:<port>, which tunnels through SSM to the host's loopback where\n * Claude Code is listening.\n *\n * When the operator exits the shell (Ctrl+D), the port-forward tunnel is\n * torn down.\n *\n * Prerequisites on the operator's machine:\n * - AWS CLI v2 with credentials scoped to the host AWS account\n * - session-manager-plugin installed\n * (brew install --cask session-manager-plugin)\n *\n * Note on port matching:\n * Claude Code picks an OAuth callback port dynamically. For the forwarded\n * port to receive the callback, ensure Claude Code binds to the same port\n * as --port (or set CLAUDE_CODE_OAUTH_PORT on the host). If the ports\n * don't match, the OAuth callback won't reach the host.\n */\nexport async function hostPairCommand(\n name: string,\n opts: { port?: string; noShell?: boolean }\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n\n const json = isJsonMode();\n const localPort = Number(opts.port ?? '54545');\n\n if (!Number.isInteger(localPort) || localPort < 1024 || localPort > 65535) {\n error('--port must be an integer between 1024 and 65535');\n process.exitCode = 1;\n return;\n }\n\n // Fetch host detail — we need the EC2 instance ID\n let host: HostDetail;\n try {\n const data = await api.get<{ host: HostDetail }>(`/hosts/${encodeURIComponent(name)}`);\n host = data.host;\n } catch (err) {\n if (json) jsonOutput({ ok: false, error: (err as Error).message });\n else error(`Failed to look up host: ${(err as Error).message}`);\n process.exitCode = 1;\n return;\n }\n\n if (host.provision_source !== 'augmented-ec2') {\n const msg = `Host \"${name}\" is ${host.provision_source ?? 'self'}-provisioned, not an Augmented-managed EC2. ` +\n `agt host pair is only for EC2 hosts provisioned through the Augmented API.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n if (!host.ec2_instance_id) {\n const msg = `Host \"${name}\" has no EC2 instance ID yet. Provision it first with \\`agt host provision\\`.`;\n if (json) jsonOutput({ ok: false, error: msg });\n else error(msg);\n process.exitCode = 1;\n return;\n }\n\n const region = host.ec2_region ?? process.env.AWS_REGION ?? 'us-east-2';\n const instanceId = host.ec2_instance_id;\n\n // Preflight: aws + session-manager-plugin\n const preflightErr = preflightAws();\n if (preflightErr) {\n if (json) jsonOutput({ ok: false, error: preflightErr });\n else error(preflightErr);\n process.exitCode = 1;\n return;\n }\n\n if (json) {\n // JSON mode: emit the tunnel parameters, caller orchestrates the shell\n jsonOutput({\n ok: true,\n host: { name: host.name, id: host.id, instance_id: instanceId, region },\n port_forward: {\n command: 'aws',\n args: [\n 'ssm', 'start-session',\n '--region', region,\n '--target', instanceId,\n '--document-name', 'AWS-StartPortForwardingSession',\n '--parameters', JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] }),\n ],\n },\n shell: {\n command: 'aws',\n args: ['ssm', 'start-session', '--region', region, '--target', instanceId],\n },\n });\n return;\n }\n\n info(`Pairing Claude Code on ${chalk.bold(name)} (${instanceId}, ${region})`);\n info(`Local port ${chalk.cyan(String(localPort))} will be forwarded to the host.`);\n console.log();\n console.log(chalk.dim('In the shell that opens, run:'));\n console.log(` ${chalk.cyan(`CLAUDE_CODE_OAUTH_PORT=${localPort} claude /login`)}`);\n console.log(chalk.dim('Then click the printed URL on this machine. The OAuth callback'));\n console.log(chalk.dim(`will reach Claude Code via the port-forward tunnel.`));\n console.log();\n console.log(chalk.dim('Exit the shell (Ctrl+D) when Claude Code reports successful login.'));\n console.log();\n\n // Start the port-forward tunnel in the background\n const tunnel = spawn(\n 'aws',\n [\n 'ssm', 'start-session',\n '--region', region,\n '--target', instanceId,\n '--document-name', 'AWS-StartPortForwardingSession',\n '--parameters',\n JSON.stringify({ portNumber: [String(localPort)], localPortNumber: [String(localPort)] }),\n ],\n { stdio: ['ignore', 'pipe', 'pipe'] }\n );\n\n // Surface tunnel errors but don't crash — often it reports \"Waiting for connections...\"\n tunnel.stderr?.on('data', (buf) => {\n const line = buf.toString().trim();\n if (line.startsWith('An error occurred')) {\n console.error(chalk.red(`[tunnel] ${line}`));\n }\n });\n\n // Give the tunnel ~1.5s to establish before launching the interactive shell\n await new Promise((r) => setTimeout(r, 1500));\n\n if (tunnel.exitCode !== null) {\n error('Port-forward tunnel failed to start. Check AWS credentials and session-manager-plugin.');\n process.exitCode = 1;\n return;\n }\n\n // Launch the interactive shell — inherits stdio so the user gets a real TTY.\n // --no-shell: keep the tunnel up in the foreground and wait for SIGINT.\n if (opts.noShell) {\n console.log(chalk.dim('--no-shell set; tunnel is running. Press Ctrl+C to exit.'));\n await new Promise<void>((resolve) => {\n const onSignal = () => {\n terminate(tunnel);\n resolve();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n });\n } else {\n await runInteractive('aws', ['ssm', 'start-session', '--region', region, '--target', instanceId]);\n // User exited the shell — tear the tunnel down\n terminate(tunnel);\n }\n\n success('Pair session ended.');\n}\n\nfunction preflightAws(): string | null {\n const aws = spawnSync('aws', ['--version'], { stdio: 'ignore' });\n if (aws.status !== 0) {\n return 'AWS CLI not found. Install: https://aws.amazon.com/cli/';\n }\n const plugin = spawnSync('session-manager-plugin', [], { stdio: 'ignore' });\n // session-manager-plugin exits non-zero when called without a session, but it exists if the spawn succeeded\n if (plugin.error) {\n return 'session-manager-plugin not found. Install: brew install --cask session-manager-plugin';\n }\n return null;\n}\n\nfunction runInteractive(cmd: string, args: string[]): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, { stdio: 'inherit' });\n child.on('exit', (code) => resolve(code ?? 0));\n child.on('error', () => resolve(1));\n });\n}\n\nfunction terminate(child: ChildProcess) {\n if (child.exitCode !== null) return;\n try {\n child.kill('SIGTERM');\n } catch {\n // process may already be gone\n }\n}\n","import React, { useEffect, useState, useMemo } from 'react';\nimport { render, Box, Text, useApp, useInput } from 'ink';\nimport { existsSync, readFileSync, statSync, openSync, readSync, closeSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ManagerStatus } from '../lib/watchdog.js';\nimport { getManagerPaths } from '../lib/watchdog.js';\n\n// ENG-4555: TUI dashboard for the manager. Reads ~/.augmented/manager-state.json\n// (already maintained by manager-worker.ts:880) and tails ~/.augmented/manager.log\n// so users can observe a running manager without watching log lines scroll past.\n//\n// Read-only in v1 — no agent-level actions (restart/pause/etc). Falls back to a\n// log-streaming message if stdout is not a TTY (CI, scripts) since Ink's full-screen\n// rendering can't function without raw input mode.\n\ninterface ManagerWatchOptions {\n configDir?: string;\n noTui?: boolean;\n}\n\nconst REFRESH_MS = 1000;\nconst LOG_TAIL_LINES = 200;\nconst DETAIL_RECENT_LINES = 50;\n\nexport function managerWatchCommand(opts: ManagerWatchOptions = {}): void {\n const configDir = opts.configDir ?? join(homedir(), '.augmented');\n const paths = getManagerPaths(configDir);\n\n // Non-TTY environments (CI, piped output) can't run a TUI — Ink relies on\n // raw stdin and ANSI cursor control. Fall back to log streaming so the\n // command still produces useful output when scripted.\n const isTty = process.stdout.isTTY === true && process.stdin.isTTY === true;\n if (opts.noTui || !isTty) {\n streamLogFile(paths.logFile);\n return;\n }\n\n // Switch to the terminal's alternate screen buffer (like vim/htop/less) so\n // the TUI takes over the whole window and the user's scrollback is restored\n // verbatim on exit. \\x1b[?1049h enters the alt buffer + clears it,\n // \\x1b[?1049l restores the prior buffer. Hide the cursor while we render\n // (\\x1b[?25l) and re-show on exit (\\x1b[?25h) so it doesn't blink under\n // selected boxes.\n process.stdout.write('\\x1b[?1049h\\x1b[H\\x1b[?25l');\n const restore = (): void => { process.stdout.write('\\x1b[?25h\\x1b[?1049l'); };\n\n // Restore on every exit path: clean exit (waitUntilExit resolves), thrown\n // exception, SIGINT/SIGTERM mid-render, or hard-quit on Ctrl-C. Without\n // this the user's terminal stays on the alt buffer with the cursor hidden.\n const onSignal = (): void => { restore(); process.exit(0); };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', restore);\n\n const { waitUntilExit } = render(<Dashboard stateFile={paths.stateFile} logFile={paths.logFile} />);\n waitUntilExit().catch(() => { /* ignore */ }).finally(restore);\n}\n\n// ---------------------------------------------------------------------------\n// State + log readers\n// ---------------------------------------------------------------------------\n\nfunction readState(stateFile: string): ManagerStatus | null {\n try {\n if (!existsSync(stateFile)) return null;\n const raw = readFileSync(stateFile, 'utf-8');\n return JSON.parse(raw) as ManagerStatus;\n } catch {\n return null;\n }\n}\n\n// Tail the last N lines of a log file. Reads only the trailing window so this\n// stays cheap even when the log grows to many MB. Returns lines oldest-first.\nfunction tailLogFile(logFile: string, lines: number): string[] {\n if (!existsSync(logFile)) return [];\n try {\n const fileSize = statSync(logFile).size;\n if (fileSize === 0) return [];\n // Heuristic: ~200 chars/line average — we read 4× headroom and slice. For\n // the manager log this comfortably fits the requested tail in one read.\n const readSize = Math.min(fileSize, lines * 800);\n const fd = openSync(logFile, 'r');\n try {\n const buf = Buffer.alloc(readSize);\n readSync(fd, buf, 0, readSize, fileSize - readSize);\n const text = buf.toString('utf-8');\n const all = text.split('\\n').filter((l) => l.length > 0);\n return all.slice(-lines);\n } finally {\n closeSync(fd);\n }\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Ink components\n// ---------------------------------------------------------------------------\n\ninterface DashboardProps {\n stateFile: string;\n logFile: string;\n}\n\nconst Dashboard: React.FC<DashboardProps> = ({ stateFile, logFile }) => {\n const { exit } = useApp();\n const [status, setStatus] = useState<ManagerStatus | null>(() => readState(stateFile));\n const [logLines, setLogLines] = useState<string[]>(() => tailLogFile(logFile, LOG_TAIL_LINES));\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [view, setView] = useState<'grid' | 'detail'>('grid');\n const [tick, setTick] = useState(0);\n\n // Refresh state + log tail on a fixed cadence. We don't use fs.watch because\n // the manager rewrites the state file atomically and watch events on macOS\n // are notoriously chatty/unreliable for that pattern.\n useEffect(() => {\n const id = setInterval(() => {\n setStatus(readState(stateFile));\n setLogLines(tailLogFile(logFile, LOG_TAIL_LINES));\n setTick((t) => t + 1);\n }, REFRESH_MS);\n return () => clearInterval(id);\n }, [stateFile, logFile]);\n\n const agents = status?.agents ?? [];\n const selected = agents[selectedIndex];\n\n useInput((input, key) => {\n // Detail view owns 'q' first — pressing 'q' there means \"back to grid\",\n // not \"quit the app\". Only the grid view treats bare 'q' as exit. Ctrl-C\n // remains a hard-quit in either view because users universally expect it.\n if (view === 'detail') {\n if (key.escape || input === 'q') setView('grid');\n else if (key.ctrl && input === 'c') exit();\n return;\n }\n if (input === 'q' || (key.ctrl && input === 'c')) {\n exit();\n return;\n }\n if (agents.length === 0) return;\n if (key.upArrow || key.leftArrow) {\n setSelectedIndex((i) => (i - 1 + agents.length) % agents.length);\n } else if (key.downArrow || key.rightArrow) {\n setSelectedIndex((i) => (i + 1) % agents.length);\n } else if (key.return) {\n setView('detail');\n }\n });\n\n if (!status) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Text bold color=\"yellow\">⚠ Manager state not found</Text>\n <Text> </Text>\n <Text>Looked for: <Text color=\"gray\">{stateFile}</Text></Text>\n <Text> </Text>\n <Text>Start the manager first: <Text color=\"cyan\">agt manager start</Text></Text>\n <Text dimColor>Press <Text color=\"white\">q</Text> to quit.</Text>\n </Box>\n );\n }\n\n if (view === 'detail' && selected) {\n return <DetailView agent={selected} logLines={logLines} />;\n }\n\n return <GridView status={status} agents={agents} selectedIndex={selectedIndex} logLines={logLines} tick={tick} />;\n};\n\n// ---------------------------------------------------------------------------\n// Grid view — one box per agent\n// ---------------------------------------------------------------------------\n\ninterface GridViewProps {\n status: ManagerStatus;\n agents: ManagerStatus['agents'];\n selectedIndex: number;\n logLines: string[];\n tick: number;\n}\n\nconst GridView: React.FC<GridViewProps> = ({ status, agents, selectedIndex, logLines, tick }) => {\n const lastLogLine = logLines[logLines.length - 1] ?? '';\n return (\n <Box flexDirection=\"column\">\n <HeaderBar status={status} tick={tick} />\n {agents.length === 0 ? (\n <Box padding={1}>\n <Text dimColor>No agents discovered yet. Manager is polling…</Text>\n </Box>\n ) : (\n <Box flexDirection=\"row\" flexWrap=\"wrap\" paddingX={1}>\n {agents.map((agent, i) => (\n <AgentBox\n key={agent.agentId}\n agent={agent}\n selected={i === selectedIndex}\n recentLogLine={mostRecentLineForAgent(logLines, agent.codeName)}\n />\n ))}\n </Box>\n )}\n <Footer tail={lastLogLine} />\n </Box>\n );\n};\n\nconst HeaderBar: React.FC<{ status: ManagerStatus; tick: number }> = ({ status, tick }) => {\n // The tick counter forces a redraw every refresh so the \"last poll\" relative\n // time stays current even when nothing else changed. Reading `tick` here is\n // intentional — without it React would skip the re-render.\n void tick;\n return (\n <Box paddingX={1} paddingY={0} borderStyle=\"single\" borderColor=\"cyan\">\n <Box flexDirection=\"row\" justifyContent=\"space-between\" width=\"100%\">\n <Text bold color=\"cyan\">agt manager · {status.agents.length} agent{status.agents.length === 1 ? '' : 's'}</Text>\n <Text dimColor>\n PID {status.pid} · polls {status.pollCount} · errors {status.errorCount} · last poll {relativeTime(status.lastPollAt)}\n </Text>\n </Box>\n </Box>\n );\n};\n\nconst Footer: React.FC<{ tail: string }> = ({ tail }) => (\n <Box paddingX={1} flexDirection=\"column\">\n <Box>\n <Text dimColor>↑↓ select · </Text>\n <Text dimColor>Enter detail · </Text>\n <Text dimColor>q quit</Text>\n </Box>\n {tail && (\n <Box>\n <Text dimColor>last log: </Text>\n <Text>{truncate(tail, process.stdout.columns ? process.stdout.columns - 12 : 100)}</Text>\n </Box>\n )}\n </Box>\n);\n\n// ---------------------------------------------------------------------------\n// Agent box (grid cell)\n// ---------------------------------------------------------------------------\n\ninterface AgentBoxProps {\n agent: ManagerStatus['agents'][number];\n selected: boolean;\n recentLogLine: string | null;\n}\n\nconst AgentBox: React.FC<AgentBoxProps> = ({ agent, selected, recentLogLine }) => {\n const isError = agent.status !== 'active' && agent.status !== 'paused' && agent.status !== '';\n const borderColor = selected ? 'yellow' : isError ? 'red' : 'gray';\n const statusColor = agent.status === 'active' ? 'green' : agent.status === 'paused' ? 'yellow' : isError ? 'red' : 'gray';\n const gateway = agent.gatewayRunning\n ? `:${agent.gatewayPort} (PID ${agent.gatewayPid})`\n : agent.gatewayPort\n ? `:${agent.gatewayPort} down`\n : '—';\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginRight={1} marginBottom={0} width={42}>\n <Box>\n <Text bold>{agent.codeName}</Text>\n <Text> </Text>\n <Text color={statusColor}>{agent.status || 'unknown'}</Text>\n </Box>\n <Text dimColor>charter {agent.charterVersion || '—'} · tools {agent.toolsVersion || '—'}</Text>\n <Text dimColor>gateway {gateway}</Text>\n <Text dimColor>acp sessions {agent.acpSessions?.length ?? 0}</Text>\n <Text dimColor>last provision {relativeTime(agent.lastProvisionAt)}</Text>\n {recentLogLine && (\n <Text>\n <Text color=\"cyan\">▸</Text> {truncate(recentLogLine, 36)}\n </Text>\n )}\n </Box>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Detail view — recent activity for the selected agent\n// ---------------------------------------------------------------------------\n\ninterface DetailViewProps {\n agent: ManagerStatus['agents'][number];\n logLines: string[];\n}\n\nconst DetailView: React.FC<DetailViewProps> = ({ agent, logLines }) => {\n const recent = useMemo(\n () => logLines.filter((l) => l.toLowerCase().includes(agent.codeName.toLowerCase())).slice(-DETAIL_RECENT_LINES),\n [logLines, agent.codeName],\n );\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} borderStyle=\"double\" borderColor=\"cyan\">\n <Text bold color=\"cyan\">{agent.codeName}</Text>\n <Text> · </Text>\n <Text>{agent.status || 'unknown'}</Text>\n <Text dimColor> · charter {agent.charterVersion || '—'} · tools {agent.toolsVersion || '—'}</Text>\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>Gateway</Text>\n <Text>\n {agent.gatewayRunning\n ? `running on :${agent.gatewayPort} (PID ${agent.gatewayPid})`\n : agent.gatewayPort\n ? `configured :${agent.gatewayPort} but not running`\n : 'no gateway configured'}\n </Text>\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>ACP sessions ({agent.acpSessions?.length ?? 0})</Text>\n {(agent.acpSessions ?? []).length === 0 ? (\n <Text dimColor>none</Text>\n ) : (\n (agent.acpSessions ?? []).map((s) => (\n <Text key={s.sessionId}>\n · {s.agentCommand} {s.sessionName ?? ''} · {s.queueState} · turns {s.turnCount} · started {relativeTime(s.startedAt)}\n </Text>\n ))\n )}\n </Box>\n <Box paddingX={1} marginTop={1} flexDirection=\"column\">\n <Text bold>Recent activity ({recent.length} lines, filtered to \"{agent.codeName}\")</Text>\n {recent.length === 0 ? (\n <Text dimColor>nothing in the log mentions this agent yet</Text>\n ) : (\n recent.map((line, i) => (\n <Text key={i}>{truncate(line, process.stdout.columns ? process.stdout.columns - 4 : 120)}</Text>\n ))\n )}\n </Box>\n <Box paddingX={1} marginTop={1}>\n <Text dimColor>esc / q · back to grid</Text>\n </Box>\n </Box>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction mostRecentLineForAgent(lines: string[], codeName: string): string | null {\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i];\n if (line && line.toLowerCase().includes(codeName.toLowerCase())) return line;\n }\n return null;\n}\n\nfunction relativeTime(iso: string | null | undefined): string {\n if (!iso) return 'never';\n const t = new Date(iso).getTime();\n if (isNaN(t)) return 'never';\n const diff = Math.max(0, Date.now() - t);\n const sec = Math.floor(diff / 1000);\n if (sec < 60) return `${sec}s ago`;\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n return `${Math.floor(hr / 24)}d ago`;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, Math.max(0, max - 1))}…` : s;\n}\n\n// ---------------------------------------------------------------------------\n// Headless fallback — stream the log file\n// ---------------------------------------------------------------------------\n\nfunction streamLogFile(logFile: string): void {\n if (!existsSync(logFile)) {\n process.stderr.write(`No manager log found at ${logFile}.\\nStart the manager first: agt manager start\\n`);\n process.exitCode = 1;\n return;\n }\n // Print existing content, then poll for appends. Pure node — no external\n // tail-equivalent library so this works on every host the CLI ships to.\n let lastSize = 0;\n try {\n const initial = readFileSync(logFile, 'utf-8');\n process.stdout.write(initial);\n lastSize = statSync(logFile).size;\n } catch (err) {\n process.stderr.write(`Failed to read log: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n const id = setInterval(() => {\n try {\n const size = statSync(logFile).size;\n // Truncation / rotation: if the file is smaller than we last saw, the\n // log has been rotated or truncated. Reset lastSize to 0 so we resume\n // emitting from the start of the new file on the next tick (or the\n // remainder of this tick, if size > 0). Without this, every subsequent\n // append would be silently swallowed.\n if (size < lastSize) lastSize = 0;\n if (size === lastSize) return;\n const fd = openSync(logFile, 'r');\n try {\n const buf = Buffer.alloc(size - lastSize);\n readSync(fd, buf, 0, buf.length, lastSize);\n process.stdout.write(buf.toString('utf-8'));\n lastSize = size;\n } finally {\n closeSync(fd);\n }\n } catch { /* file deleted between stat and read — keep polling */ }\n }, 500);\n const stop = (): void => {\n clearInterval(id);\n process.exit(0);\n };\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n}\n","import chalk from 'chalk';\nimport JSON5 from 'json5';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n extractFrontmatter,\n getChannel,\n type CharterFrontmatter,\n type ToolsFrontmatter,\n} from '@augmented/core';\nimport { error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { api } from '../lib/api-client.js';\nimport { getApiKey } from '../lib/config.js';\n\ninterface AgentShowOptions {\n configDir: string;\n allChannels?: boolean;\n}\n\nexport async function agentShowCommand(\n codeName: string,\n opts: AgentShowOptions,\n): Promise<void> {\n const json = isJsonMode();\n // ENG-4418: both frameworks collapse to <configDir>/<codeName>/provision/\n // post-migration. This command doesn't go through the adapter, so on a\n // host where the manager hasn't polled yet the legacy\n // <codeName>/claudecode/provision/ may still be the only tree present —\n // prefer the unified path, fall back to legacy so agent show doesn't\n // report 'not found' during the migration window.\n const unifiedDir = join(opts.configDir, codeName, 'provision');\n const legacyDir = join(opts.configDir, codeName, 'claudecode', 'provision');\n const agentDir = existsSync(unifiedDir) ? unifiedDir : legacyDir;\n const hasLocalConfig = existsSync(agentDir);\n\n // ── Try API first for channel data ─────────────────────────────────────\n\n type ApiChannelConfig = {\n channel_id: string;\n config: Record<string, unknown>;\n status: string;\n };\n\n let apiChannels: ApiChannelConfig[] | null = null;\n let apiAgent: Record<string, unknown> | null = null;\n\n if (getApiKey()) {\n try {\n const data = await api.get<{\n agent: Record<string, unknown>;\n channel_configs: Record<string, { config: Record<string, unknown>; status: string }>;\n }>(`/agents/${encodeURIComponent(codeName)}/provision-data`);\n\n apiAgent = data.agent ?? null;\n\n if (data.channel_configs) {\n apiChannels = Object.entries(data.channel_configs).map(\n ([channelId, val]) => ({\n channel_id: channelId,\n config: val.config,\n status: val.status,\n }),\n );\n }\n } catch {\n // API not available or agent not found — continue with local data\n }\n }\n\n // If no local config and no API data, agent doesn't exist anywhere\n if (!hasLocalConfig && !apiAgent) {\n if (json) {\n jsonOutput({ ok: false, error: `Agent '${codeName}' not found` });\n } else {\n error(`Agent '${codeName}' not found`);\n }\n process.exitCode = 1;\n return;\n }\n\n // ── Read local files (best-effort) ────────────────────────────────────\n\n let charter: CharterFrontmatter | null = null;\n let tools: ToolsFrontmatter | null = null;\n let openclawConfig: Record<string, unknown> | null = null;\n let agentState: {\n charterVersion: string;\n toolsVersion: string;\n lastProvisionAt: string | null;\n lastDriftCheckAt: string | null;\n } | null = null;\n\n if (hasLocalConfig) {\n // CHARTER.md\n const charterPath = join(agentDir, 'CHARTER.md');\n if (existsSync(charterPath)) {\n const raw = readFileSync(charterPath, 'utf-8');\n const parsed = extractFrontmatter(raw);\n if (parsed.frontmatter) {\n charter = parsed.frontmatter as unknown as CharterFrontmatter;\n }\n }\n\n // TOOLS.md\n const toolsPath = join(agentDir, 'TOOLS.md');\n if (existsSync(toolsPath)) {\n const raw = readFileSync(toolsPath, 'utf-8');\n const parsed = extractFrontmatter(raw);\n if (parsed.frontmatter) {\n tools = parsed.frontmatter as unknown as ToolsFrontmatter;\n }\n }\n\n // openclaw.json5\n const openclawPath = join(agentDir, 'openclaw.json5');\n if (existsSync(openclawPath)) {\n try {\n const raw = readFileSync(openclawPath, 'utf-8');\n openclawConfig = JSON5.parse(raw) as Record<string, unknown>;\n } catch {\n // ignore parse errors — show what we can\n }\n }\n\n // manager-state.json\n const statePath = join(opts.configDir, 'manager-state.json');\n if (existsSync(statePath)) {\n try {\n const raw = readFileSync(statePath, 'utf-8');\n const state = JSON.parse(raw) as {\n agents: Array<{\n codeName: string;\n charterVersion: string;\n toolsVersion: string;\n lastProvisionAt: string | null;\n lastDriftCheckAt: string | null;\n }>;\n };\n agentState = state.agents?.find((a) => a.codeName === codeName) ?? null;\n } catch {\n // ignore\n }\n }\n }\n\n // ── Resolve channel data ────────────────────────────────────────────────\n // Prefer API channel data over local openclaw.json5 since the webapp/API\n // is the source of truth for channel configuration.\n\n type ChannelRow = {\n id: string;\n name: string;\n tier: string;\n enabled: boolean;\n status: string;\n e2e: string;\n };\n\n const channelRows: ChannelRow[] = [];\n\n if (apiChannels && apiChannels.length > 0) {\n // Use API channel configs (source of truth)\n for (const ch of apiChannels) {\n const def = getChannel(ch.channel_id);\n channelRows.push({\n id: ch.channel_id,\n name: def?.name ?? ch.channel_id,\n tier: def?.securityTier ?? 'unknown',\n enabled: true,\n status: ch.status,\n e2e: def ? String(def.e2eEncrypted) : '—',\n });\n }\n } else {\n // Fall back to local openclaw.json5 channels\n const openclawChannels = Array.isArray(openclawConfig?.channels)\n ? (openclawConfig!.channels as Array<{ id: string; enabled?: boolean }>)\n : [];\n\n for (const ch of openclawChannels) {\n const def = getChannel(ch.id);\n channelRows.push({\n id: ch.id,\n name: def?.name ?? ch.id,\n tier: def?.securityTier ?? 'unknown',\n enabled: ch.enabled !== false,\n status: ch.enabled !== false ? 'configured' : 'disabled',\n e2e: def ? String(def.e2eEncrypted) : '—',\n });\n }\n }\n\n // ── JSON output ─────────────────────────────────────────────────────────\n\n if (json) {\n const filtered = opts.allChannels ? channelRows : channelRows.filter((c) => c.enabled);\n jsonOutput({\n ok: true,\n agent: {\n code_name: codeName,\n display_name: (apiAgent?.display_name as string) ?? charter?.display_name ?? null,\n agent_id: (apiAgent?.agent_id as string) ?? charter?.agent_id ?? null,\n environment: (apiAgent?.environment as string) ?? charter?.environment ?? null,\n risk_tier: (apiAgent?.risk_tier as string) ?? charter?.risk_tier ?? null,\n owner: charter?.owner ?? null,\n logging_mode: charter?.logging_mode ?? null,\n budget: charter?.budget ?? null,\n limits: charter?.limits ?? null,\n },\n versions: {\n charter: agentState?.charterVersion ?? charter?.version ?? null,\n tools: agentState?.toolsVersion ?? tools?.version ?? null,\n last_provision: agentState?.lastProvisionAt ?? null,\n last_drift_check: agentState?.lastDriftCheckAt ?? null,\n },\n tools: {\n enforcement_mode: tools?.enforcement_mode ?? null,\n global_controls: tools?.global_controls ?? null,\n count: tools?.tools?.length ?? 0,\n items: tools?.tools ?? [],\n },\n channels: filtered,\n openclaw: openclawConfig\n ? { sandbox: (openclawConfig as any).sandbox ?? null, gateway: (openclawConfig as any).gateway ?? null }\n : null,\n });\n return;\n }\n\n // ── Human output ────────────────────────────────────────────────────────\n\n const displayName = (apiAgent?.display_name as string) ?? charter?.display_name ?? codeName;\n console.log(chalk.bold(`\\nAgent: ${codeName}`) + (displayName !== codeName ? ` (${displayName})` : '') + '\\n');\n\n if (charter || apiAgent) {\n const agentId = (apiAgent?.agent_id as string) ?? charter?.agent_id;\n const environment = (apiAgent?.environment as string) ?? charter?.environment;\n const riskTier = (apiAgent?.risk_tier as string) ?? charter?.risk_tier;\n\n info(`Agent ID: ${agentId ?? '—'}`);\n info(`Environment: ${environment ?? '—'}`);\n info(`Risk Tier: ${riskTier ?? '—'}`);\n info(`Owner: ${charter?.owner?.name ?? '—'}`);\n\n const charterVer = agentState?.charterVersion ?? charter?.version;\n const toolsVer = agentState?.toolsVersion ?? tools?.version ?? '—';\n const provTs = agentState?.lastProvisionAt\n ? formatTimestamp(agentState.lastProvisionAt)\n : null;\n\n if (charterVer) {\n info(`Charter: v${charterVer}${provTs ? ` (provisioned ${provTs})` : ''}`);\n }\n if (toolsVer !== '—') {\n info(`Tools: v${toolsVer}${provTs ? ` (provisioned ${provTs})` : ''}`);\n }\n\n // Sandbox\n const sandbox = openclawConfig ? (openclawConfig as any).sandbox : null;\n if (sandbox != null) {\n info(`Sandbox: ${sandbox ? 'on' : 'off'}`);\n }\n\n // Budget\n const b = charter?.budget;\n if (b) {\n const budgetStr = `${b.limit.toLocaleString()} ${b.type} / ${b.window} (${b.enforcement ?? 'block'})`;\n info(`Budget: ${budgetStr}`);\n }\n } else {\n info('No agent metadata available');\n }\n\n // ── Channels table ──────────────────────────────────────────────────────\n\n const filtered = opts.allChannels ? channelRows : channelRows.filter((c) => c.enabled);\n\n console.log(chalk.bold('\\nChannels:'));\n\n if (filtered.length === 0) {\n info('(none enabled)');\n } else {\n table(\n ['Channel', 'Name', 'Tier', 'Status', 'E2E'],\n filtered.map((c) => [\n c.id,\n c.name,\n c.tier,\n c.status,\n c.e2e,\n ]),\n );\n }\n\n // ── Tools ───────────────────────────────────────────────────────────────\n\n if (tools) {\n console.log(chalk.bold('\\nTools:'));\n\n if (tools.tools.length === 0) {\n info('(none configured)');\n } else {\n table(\n ['ID', 'Name', 'Type', 'Access', 'Enforcement'],\n tools.tools.map((t) => [t.id, t.name, t.type, t.access, t.enforcement]),\n );\n }\n\n // Global controls\n if (tools.global_controls) {\n const gc = tools.global_controls;\n console.log(chalk.bold('\\nGlobal Controls:'));\n info(`Network: ${gc.default_network_policy === 'deny' ? 'deny-by-default' : 'allow-by-default'}`);\n info(`Timeout: ${gc.default_timeout_ms}ms`);\n info(`Rate: ${gc.default_rate_limit_rpm} rpm`);\n info(`Retries: ${gc.default_retries}`);\n }\n }\n\n console.log();\n}\n\nfunction formatTimestamp(iso: string): string {\n const d = new Date(iso);\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api, ApiError } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface RecurringTemplate {\n id: string;\n title: string;\n kind: string;\n expression?: string;\n every_interval?: string;\n natural_language?: string;\n timezone: string;\n enabled: boolean;\n next_spawn_at?: string;\n last_spawned_at?: string;\n spawn_count: number;\n priority: number;\n created_at: string;\n}\n\nasync function resolveAgentId(codeName: string): Promise<string | null> {\n try {\n const data = await api.get<{ agent_id: string }>(`/agents/${codeName}`);\n return data.agent_id;\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) return null;\n throw err;\n }\n}\n\nfunction priorityLabel(p: number): string {\n return p === 1 ? chalk.red('HIGH') : p === 3 ? chalk.dim('LOW') : chalk.yellow('MED');\n}\n\nfunction formatSpawnTime(isoDate: string | undefined, timezone: string): string {\n if (!isoDate) return chalk.dim('—');\n try {\n return new Intl.DateTimeFormat('en-AU', {\n dateStyle: 'medium',\n timeStyle: 'short',\n timeZone: timezone,\n }).format(new Date(isoDate));\n } catch {\n return new Date(isoDate).toLocaleString();\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring add\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringAddCommand(\n title: string,\n opts: {\n agent: string;\n every: string;\n priority?: string;\n description?: string;\n estimate?: string;\n deliverable?: string;\n timezone?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n // Validate numeric inputs\n let priority: number | undefined;\n if (opts.priority) {\n priority = Number(opts.priority);\n if (!Number.isInteger(priority) || priority < 1 || priority > 3) {\n if (json) {\n jsonOutput({ ok: false, error: 'Priority must be 1, 2, or 3' });\n } else {\n error('Priority must be 1 (high), 2 (medium), or 3 (low)');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n let estimatedMinutes: number | undefined;\n if (opts.estimate) {\n estimatedMinutes = Number(opts.estimate);\n if (!Number.isInteger(estimatedMinutes) || estimatedMinutes <= 0) {\n if (json) {\n jsonOutput({ ok: false, error: 'Estimate must be a positive integer (minutes)' });\n } else {\n error('Estimate must be a positive integer (minutes)');\n }\n process.exitCode = 1;\n return;\n }\n }\n\n const spinner = ora({ text: 'Creating recurring template…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ template: RecurringTemplate }>('/host/kanban/recurring', {\n agent_id: agentId,\n title,\n description: opts.description ?? undefined,\n priority,\n estimated_minutes: estimatedMinutes,\n deliverable: opts.deliverable ?? undefined,\n schedule: opts.every,\n timezone: opts.timezone ?? undefined,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, template: data.template });\n return;\n }\n\n success(`Recurring task created: ${chalk.bold(title)}`);\n info(`Schedule: ${chalk.cyan(data.template.natural_language ?? data.template.expression ?? data.template.every_interval ?? '')}`);\n info(`Next spawn: ${formatSpawnTime(data.template.next_spawn_at, data.template.timezone)}`);\n info(`Timezone: ${data.template.timezone}`);\n } catch (err) {\n spinner.fail('Failed to create recurring template');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring list\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringListCommand(\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Fetching recurring templates…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.get<{ templates: RecurringTemplate[] }>(\n `/host/kanban/recurring?agent_id=${agentId}`,\n );\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, templates: data.templates });\n return;\n }\n\n if (data.templates.length === 0) {\n info('No recurring templates found.');\n return;\n }\n\n const rows = data.templates.map((t) => [\n t.id.slice(0, 8),\n t.title,\n t.natural_language ?? t.expression ?? t.every_interval ?? '—',\n priorityLabel(t.priority),\n t.enabled ? chalk.green('Active') : chalk.dim('Disabled'),\n formatSpawnTime(t.next_spawn_at, t.timezone),\n String(t.spawn_count),\n ]);\n\n table(\n ['ID', 'Title', 'Schedule', 'Priority', 'Status', 'Next Spawn', 'Spawned'],\n rows,\n );\n } catch (err) {\n spinner.fail('Failed to fetch recurring templates');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban recurring disable\n// ---------------------------------------------------------------------------\n\nexport async function kanbanRecurringDisableCommand(\n titleOrId: string,\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Disabling recurring template…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.get<{ templates: RecurringTemplate[] }>(\n `/host/kanban/recurring?agent_id=${agentId}`,\n );\n\n const matches = data.templates.filter(\n (t) => t.id.startsWith(titleOrId) || t.title.toLowerCase() === titleOrId.toLowerCase(),\n );\n\n if (matches.length === 0) {\n spinner.fail(`Recurring template \"${titleOrId}\" not found`);\n process.exitCode = 1;\n return;\n }\n\n if (matches.length > 1) {\n spinner.fail(`Ambiguous match for \"${titleOrId}\" — ${matches.length} templates found:`);\n for (const m of matches) {\n info(` ${m.id.slice(0, 8)} — ${m.title}`);\n }\n info('Use a longer ID prefix to disambiguate.');\n process.exitCode = 1;\n return;\n }\n\n const match = matches[0]!;\n await api.patch(`/host/kanban/recurring/${match.id}`, { enabled: false });\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, id: match.id, title: match.title, enabled: false });\n } else {\n success(`Disabled: ${chalk.bold(match.title)}`);\n }\n } catch (err) {\n spinner.fail('Failed to disable recurring template');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, accessSync, constants as fsConstants } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { deriveConsoleUrl } from '@augmented/core';\nimport { success, error, info, warn } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\nimport { exchangeApiKey } from '../lib/api-client.js';\nimport { startWatchdog } from '../lib/watchdog.js';\n\n/**\n * Detect the user's shell profile file.\n * Returns the path to the most appropriate profile file.\n */\nfunction detectShellProfile(): string {\n const shell = process.env['SHELL'] ?? '';\n const home = homedir();\n\n if (shell.includes('zsh')) {\n // Always use .zshrc — it's sourced by interactive shells.\n // .zprofile is only sourced by login shells and won't be read by subprocesses.\n return join(home, '.zshrc');\n }\n\n if (shell.includes('fish')) {\n const fishConfig = join(home, '.config', 'fish', 'config.fish');\n return fishConfig;\n }\n\n // Default to bash\n const bashrc = join(home, '.bashrc');\n if (existsSync(bashrc)) return bashrc;\n return join(home, '.bash_profile');\n}\n\n/**\n * When running as root on a POSIX host, persist AGT_HOST / AGT_API_KEY to\n * every channel that matters for system-wide visibility:\n *\n * /etc/environment — read by PAM (sshd logins).\n * /etc/profile.d/agt.sh — sourced by login shells (bash -l, sh -l).\n * /etc/bashrc — sourced by non-login interactive bash.\n *\n * One channel isn't enough because SSM Session Manager launches `/bin/sh`\n * (bash in sh-compat mode), which skips /etc/profile.d, /etc/bashrc, and\n * isn't guaranteed to go through PAM. Users in an SSM session can `exec\n * bash` / `exec bash -l` to pick up any of these.\n *\n * Returns true if at least one channel was written.\n */\ninterface SystemWideEnvResult {\n etcEnvironment: boolean;\n profileD: boolean;\n bashrc: boolean;\n}\n\nfunction maybeWriteSystemWideEnv(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): SystemWideEnvResult {\n const empty: SystemWideEnvResult = { etcEnvironment: false, profileD: false, bashrc: false };\n if (process.platform === 'win32') return empty;\n if (typeof process.getuid !== 'function' || process.getuid() !== 0) return empty;\n\n return {\n etcEnvironment: writeEtcEnvironment(apiUrl, apiKey, consoleUrl),\n profileD: writeProfileDScript(apiUrl, apiKey, consoleUrl),\n // Run for its side-effect (wiring /etc/bashrc to source agt.sh) but\n // treat it as a supporting channel, not proof that env values were\n // persisted. Success reporting should reflect actual value writes.\n bashrc: ensureBashrcSourcesProfileD(),\n };\n}\n\n/** Quote a value for /etc/environment (pam_env format: KEY=\"value\"). */\nfunction quoteForEtcEnvironment(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\r?\\n/g, '\\\\n')}\"`;\n}\n\n/** Quote a value for a POSIX shell script (single-quoted; safest — no expansion). */\nfunction quoteForPosixShell(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/**\n * Quote a value for a fish config.fish `set -gx` line. Fish evaluates `$VAR`\n * (and `$(cmd)`) inside double-quoted strings, so a raw URL containing a `$`\n * would get partially expanded. Single quotes disable expansion; embedded\n * single quotes escape as `\\'`, backslashes as `\\\\`. Parenthesized command\n * substitutions `(cmd)` are not expanded inside double quotes in fish, but\n * single-quoting is uniformly safe.\n */\nfunction quoteForFishShell(value: string): string {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, `\\\\'`)}'`;\n}\n\nexport function writeEtcEnvironment(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): boolean {\n const envPath = '/etc/environment';\n if (!existsSync(envPath)) return false;\n try {\n accessSync(envPath, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const current = readFileSync(envPath, 'utf-8');\n // Strip all three keys (even when CONSOLE_URL isn't being re-written) so\n // a stale value from a prior setup run can't linger while HOST/API_KEY\n // rotate to a new host underneath it.\n const stripped = current\n .split(/\\r?\\n/)\n .filter((line) => !/^\\s*(?:export\\s+)?AGT_(?:HOST|API_KEY|CONSOLE_URL)=/.test(line))\n .join('\\n');\n const base = stripped.endsWith('\\n') || stripped.length === 0 ? stripped : `${stripped}\\n`;\n const lines = [\n `AGT_HOST=${quoteForEtcEnvironment(apiUrl)}`,\n `AGT_API_KEY=${quoteForEtcEnvironment(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`AGT_CONSOLE_URL=${quoteForEtcEnvironment(consoleUrl)}`);\n const appended = `${base}${lines.join('\\n')}\\n`;\n writeFileSync(envPath, appended, { mode: 0o644 });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function writeProfileDScript(\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): boolean {\n const profileD = '/etc/profile.d';\n if (!existsSync(profileD)) return false;\n try {\n accessSync(profileD, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const scriptPath = `${profileD}/agt.sh`;\n // Single-quote so the shell does no expansion — safe even if the value\n // contains $, backticks, or double quotes. API keys shouldn't contain\n // these, but defense in depth matters when sourcing into every login shell.\n const lines = [\n '# Augmented — auto-generated by `agt setup`. Do not edit.',\n `export AGT_HOST=${quoteForPosixShell(apiUrl)}`,\n `export AGT_API_KEY=${quoteForPosixShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);\n lines.push('');\n writeFileSync(scriptPath, lines.join('\\n'), { mode: 0o644 });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensureBashrcSourcesProfileD(): boolean {\n const bashrc = '/etc/bashrc';\n if (!existsSync(bashrc)) return false;\n try {\n accessSync(bashrc, fsConstants.W_OK);\n } catch {\n return false;\n }\n try {\n const current = readFileSync(bashrc, 'utf-8');\n const marker = '# Augmented (agt) — source system-wide AGT env';\n if (current.includes(marker)) return true; // already wired up\n const snippet = [\n '',\n marker,\n 'if [ -r /etc/profile.d/agt.sh ]; then',\n ' . /etc/profile.d/agt.sh',\n 'fi',\n '',\n ].join('\\n');\n writeFileSync(bashrc, current + snippet);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Build export lines for the shell profile.\n */\nexport function buildExportLines(\n shell: string,\n apiUrl: string,\n apiKey: string,\n consoleUrl: string | null,\n): string {\n if (shell.includes('fish')) {\n const lines = [\n '',\n '# Augmented (agt) host configuration',\n `set -gx AGT_HOST ${quoteForFishShell(apiUrl)}`,\n `set -gx AGT_API_KEY ${quoteForFishShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`set -gx AGT_CONSOLE_URL ${quoteForFishShell(consoleUrl)}`);\n lines.push('');\n return lines.join('\\n');\n }\n\n const lines = [\n '',\n '# Augmented (agt) host configuration',\n `export AGT_HOST=${quoteForPosixShell(apiUrl)}`,\n `export AGT_API_KEY=${quoteForPosixShell(apiKey)}`,\n ];\n if (consoleUrl) lines.push(`export AGT_CONSOLE_URL=${quoteForPosixShell(consoleUrl)}`);\n lines.push('');\n return lines.join('\\n');\n}\n\nexport interface SetupOptions {\n /**\n * Override the API host the provisioning token is exchanged against.\n * Takes precedence over `AGT_HOST`. ENG-5831: required when `AGT_HOST`\n * is not set — the setup command no longer silently defaults to prod,\n * since a non-prod-stage token would otherwise be exchanged against the\n * wrong API and the failure looks like opaque connectivity loss.\n */\n apiHost?: string;\n}\n\nexport async function setupCommand(token: string, options: SetupOptions = {}): Promise<void> {\n const json = isJsonMode();\n\n // Accept both new short format (XXXX-XXXX) and legacy prov_ format\n const shortTokenPattern = /^[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4}$/i;\n const legacyTokenPattern = /^prov_[a-f0-9]{64}$/i;\n if (!token || (!shortTokenPattern.test(token) && !legacyTokenPattern.test(token))) {\n if (json) {\n jsonOutput({ ok: false, error: 'Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>' });\n } else {\n error('Invalid provisioning token. Expected format: XXXX-XXXX or prov_<64 hex>');\n info('Get a provisioning token from the Augmented dashboard after creating a host.');\n }\n process.exitCode = 1;\n return;\n }\n\n // Normalize: short tokens to uppercase, legacy tokens to lowercase\n const normalizedToken = shortTokenPattern.test(token) ? token.toUpperCase() : token.toLowerCase();\n\n // Step 1: Determine API URL\n // ENG-5831: resolution chain is --api-host flag → AGT_HOST env → fail\n // loud. The previous silent prod default routed non-prod-stage tokens\n // against prod and the failure surfaced as opaque connectivity loss.\n // setupResult.api_url (returned by /host/setup) is the authoritative\n // value that gets persisted to the shell profile; this `apiUrl` is just\n // the bootstrap address used to reach /host/setup in the first place.\n const apiHostFlag = options.apiHost?.trim();\n const envHost = process.env['AGT_HOST']?.trim();\n const apiUrl = apiHostFlag || envHost;\n if (!apiUrl) {\n const msg =\n 'Cannot determine API host for token exchange. Pass --api-host <url> or set AGT_HOST before running `agt setup`.\\n' +\n ' Production: --api-host https://api.augmented.team\\n' +\n ' Non-prod stage: --api-host https://<stage>.api.staging.augmented.team\\n' +\n ' Local development: --api-host http://api.agt.localhost:1355';\n if (json) {\n jsonOutput({ ok: false, error: msg });\n } else {\n error(msg);\n }\n process.exitCode = 1;\n return;\n }\n if (!json) {\n if (apiHostFlag) {\n info(`Exchanging token against ${chalk.bold(apiUrl)} (from --api-host)`);\n } else {\n info(`Exchanging token against ${chalk.bold(apiUrl)} (from AGT_HOST)`);\n }\n }\n\n // Step 2: Exchange provisioning token\n const spinner = ora({ text: 'Exchanging provisioning token\\u2026', isSilent: json });\n spinner.start();\n\n let setupResult: {\n host_name: string;\n host_id: string;\n team_slug: string | null;\n api_url: string;\n api_key: string;\n agents: string[];\n };\n\n try {\n const res = await fetch(`${apiUrl}/host/setup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: normalizedToken }),\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({})) as Record<string, unknown>;\n throw new Error((body['error'] as string) ?? `Setup failed: HTTP ${res.status}`);\n }\n\n setupResult = await res.json() as typeof setupResult;\n spinner.succeed('Provisioning token accepted');\n } catch (err) {\n spinner.fail('Failed to exchange provisioning token');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n // Use the API URL returned by the server (more authoritative)\n const finalApiUrl = setupResult.api_url || apiUrl;\n\n // Set for current process so verification can run\n process.env['AGT_HOST'] = finalApiUrl;\n process.env['AGT_API_KEY'] = setupResult.api_key;\n\n // Step 3: Verify connection before writing anything to disk\n const verifySpinner = ora({ text: 'Verifying connection\\u2026', isSilent: json });\n verifySpinner.start();\n\n try {\n const exchange = await exchangeApiKey(setupResult.api_key);\n verifySpinner.succeed('Connection verified');\n\n if (!json) {\n info(`Host: ${chalk.bold(setupResult.host_name)}`);\n info(`Host ID: ${exchange.hostId}`);\n info(`Team: ${chalk.bold(exchange.teamSlug ?? setupResult.team_slug ?? 'unknown')}`);\n if (exchange.userEmail) {\n info(`User: ${chalk.bold(exchange.userEmail)}`);\n }\n }\n } catch (err) {\n verifySpinner.fail('Connection verification failed');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n info('Connection could not be verified. No changes were written to your shell profile.');\n info('Check your network connection and try: agt whoami');\n }\n process.exitCode = 1;\n return;\n }\n\n // Step 4: Write env vars to shell profile (only after successful verification)\n const profilePath = detectShellProfile();\n const shell = process.env['SHELL'] ?? 'bash';\n\n // ENG-4495: derive the webapp console URL from the API URL so the\n // schedule-edit deep-link footer (ENG-4462) works on fresh hosts without\n // the operator having to export AGT_CONSOLE_URL manually. Returns null\n // for non-standard api.<host> shapes; we persist HOST/API_KEY anyway and\n // flag the gap so the operator can set CONSOLE_URL themselves.\n const consoleUrl = deriveConsoleUrl(finalApiUrl);\n // Propagate to the current process so the watchdog started later in this\n // same command inherits it — otherwise the first-run schedule deep-link\n // footer would stay disabled until the next restart even though we wrote\n // the value to the shell rc file.\n if (consoleUrl) {\n process.env['AGT_CONSOLE_URL'] = consoleUrl;\n }\n if (!json && !consoleUrl) {\n warn(\n `Could not derive AGT_CONSOLE_URL from ${finalApiUrl} — scheduled-delivery deep links will be disabled until you set it manually.`,\n );\n }\n\n const exportLines = buildExportLines(shell, finalApiUrl, setupResult.api_key, consoleUrl);\n const profileDir = dirname(profilePath);\n if (!existsSync(profileDir)) {\n mkdirSync(profileDir, { recursive: true });\n }\n\n // Replace existing block if present, otherwise append\n const marker = '# Augmented (agt) host configuration';\n const current = existsSync(profilePath) ? readFileSync(profilePath, 'utf-8') : '';\n let updated: string;\n if (current.includes(marker)) {\n // Match the marker line and all subsequent export/set lines (bash + fish),\n // plus any surrounding blank lines that were part of the original block.\n updated = current.replace(\n /\\n?# Augmented \\(agt\\) host configuration\\n(?:(?:export\\s+AGT_\\w+=.*|set\\s+-gx\\s+AGT_\\w+\\s+.*)\\n)*\\n?/,\n exportLines,\n );\n if (!json) {\n info('Replacing existing Augmented config block in shell profile.');\n }\n } else {\n updated = current + exportLines;\n }\n writeFileSync(profilePath, updated.endsWith('\\n') ? updated : `${updated}\\n`);\n\n if (!json) {\n success(`Environment variables written to ${chalk.bold(profilePath)}`);\n }\n\n // Step 4b: When running as root, fan out AGT_HOST / AGT_API_KEY to the\n // system-wide channels (/etc/environment, /etc/profile.d/agt.sh, and a\n // one-time /etc/bashrc source line). No single channel covers every\n // session type — SSM Session Manager launches `sh` which skips most of\n // them, so we write to all and let operators `exec bash -l` if needed.\n const sys = maybeWriteSystemWideEnv(finalApiUrl, setupResult.api_key, consoleUrl);\n // Bashrc only wires up the source — if neither of the value channels\n // actually persisted the vars, we shouldn't claim success.\n const valueChannelsWritten = sys.etcEnvironment || sys.profileD;\n if (!json && valueChannelsWritten) {\n const channels = [\n sys.etcEnvironment ? '/etc/environment' : null,\n sys.profileD ? '/etc/profile.d/agt.sh' : null,\n sys.bashrc ? '/etc/bashrc' : null,\n ].filter(Boolean).join(' + ');\n success(`System-wide env updated: ${channels}`);\n }\n\n // Step 5: Start manager daemon.\n // Detach so the setup process can exit cleanly — critical for JSON-mode\n // callers like the EC2 bootstrap that capture stdout via `$(...)`. Without\n // detach, in-process timers keep Node alive and the capture hangs forever.\n const managerSpinner = ora({ text: 'Starting manager daemon\\u2026', isSilent: json });\n managerSpinner.start();\n\n try {\n const configDir = join(homedir(), '.augmented');\n const { pid } = startWatchdog({ intervalMs: 10_000, configDir, detached: true });\n managerSpinner.succeed(`Manager started (PID ${pid})`);\n } catch (err) {\n managerSpinner.warn('Could not start manager daemon');\n if (!json) {\n warn((err as Error).message);\n info('Start it manually with: agt manager start');\n }\n }\n\n // Step 6: Print summary\n //\n // The raw API key is emitted to stdout only when the caller explicitly\n // opts in via AGT_SETUP_INCLUDE_API_KEY=1. Default-off because --json\n // output can end up in automation logs; trusted bootstrap flows (EC2\n // user-data) set the env var before invoking so they can persist the\n // key system-wide.\n const includeApiKey = process.env['AGT_SETUP_INCLUDE_API_KEY'] === '1';\n if (json) {\n jsonOutput({\n ok: true,\n host_name: setupResult.host_name,\n host_id: setupResult.host_id,\n team_slug: setupResult.team_slug,\n api_url: finalApiUrl,\n ...(includeApiKey ? { api_key: setupResult.api_key } : {}),\n agents: setupResult.agents,\n profile: profilePath,\n });\n // Force-exit so bootstrap scripts using `$(agt setup --json TOKEN)`\n // don't hang on stray open handles (fetch keepalive, Supabase realtime\n // warmup, etc.). The manager daemon runs in a detached child and keeps\n // going regardless.\n process.exit(0);\n } else {\n console.log();\n console.log(chalk.green.bold(' Setup complete!'));\n console.log();\n if (setupResult.agents.length > 0) {\n info(`Agents: ${setupResult.agents.map((a) => chalk.cyan(a)).join(', ')}`);\n } else {\n info('No agents assigned yet. Assign agents in the dashboard or with: agt host assign');\n }\n console.log();\n info(`Restart your shell or run: ${chalk.bold(`source ${profilePath}`)}`);\n }\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { requireTeam } from '../lib/auth-guard.js';\nimport { api } from '../lib/api-client.js';\nimport { success, error, info, table } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface KanbanItem {\n id: string;\n title: string;\n description?: string;\n priority: number;\n status: string;\n estimated_minutes?: number;\n notes?: string;\n deliverable?: string;\n result?: string;\n completed_at?: string;\n created_at: string;\n}\n\nasync function resolveAgentId(codeName: string): Promise<string | null> {\n try {\n const data = await api.get<{ agent_id: string }>(`/agents/${codeName}`);\n return data.agent_id;\n } catch {\n return null;\n }\n}\n\nfunction priorityLabel(p: number): string {\n return p === 1 ? chalk.red('HIGH') : p === 3 ? chalk.dim('LOW') : chalk.yellow('MED');\n}\n\nfunction statusLabel(s: string): string {\n const map: Record<string, string> = {\n in_progress: chalk.blue('In Progress'),\n todo: chalk.green('To Do'),\n backlog: chalk.dim('Backlog'),\n done: chalk.gray('Done'),\n };\n return map[s] ?? s;\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban list\n// ---------------------------------------------------------------------------\n\nexport async function kanbanListCommand(\n opts: { agent: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const spinner = ora({ text: 'Fetching kanban board…', isSilent: json });\n spinner.start();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n spinner.fail(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ items: KanbanItem[] }>('/host/my-kanban', {\n agent_id: agentId,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ ok: true, items: data.items });\n return;\n }\n\n if (!data.items.length) {\n info(`Board for ${opts.agent} is empty.`);\n return;\n }\n\n const rows = data.items.map((item) => [\n priorityLabel(item.priority),\n statusLabel(item.status),\n item.title.length > 50 ? item.title.slice(0, 47) + '…' : item.title,\n item.estimated_minutes ? `~${item.estimated_minutes}min` : '',\n item.id.slice(0, 8),\n ]);\n\n console.log(chalk.bold(`\\nKanban: ${opts.agent}\\n`));\n table(['Pri', 'Status', 'Title', 'Est', 'ID'], rows);\n } catch (err) {\n spinner.fail('Failed to fetch board.');\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban add\n// ---------------------------------------------------------------------------\n\nexport async function kanbanAddCommand(\n title: string,\n opts: {\n agent: string;\n priority?: string;\n status?: string;\n description?: string;\n estimate?: string;\n deliverable?: string;\n },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ ok: boolean; added: number }>('/host/kanban', {\n agent_id: agentId,\n add: [\n {\n title,\n description: opts.description,\n priority: opts.priority ? Number(opts.priority) : 2,\n status: opts.status ?? 'todo',\n estimated_minutes: opts.estimate ? Number(opts.estimate) : undefined,\n deliverable: opts.deliverable,\n source: 'manual',\n },\n ],\n });\n\n if (json) {\n jsonOutput({ ok: true, added: data.added });\n } else {\n success(`Added \"${title}\" to ${opts.agent}'s board.`);\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban move\n// ---------------------------------------------------------------------------\n\nexport async function kanbanMoveCommand(\n titleOrId: string,\n status: string,\n opts: { agent: string; notes?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const validStatuses = ['backlog', 'todo', 'in_progress', 'done'];\n if (!validStatuses.includes(status)) {\n error(`Invalid status \"${status}\". Must be one of: ${validStatuses.join(', ')}`);\n process.exitCode = 1;\n return;\n }\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const update: Record<string, unknown> = {\n status,\n notes: opts.notes,\n };\n if (isUuid) {\n update.id = titleOrId;\n } else {\n update.title = titleOrId;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [update],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else if (data.updated > 0) {\n success(`Moved \"${titleOrId}\" → ${status}.`);\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n process.exitCode = 1;\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban update\n// ---------------------------------------------------------------------------\n\nexport async function kanbanUpdateCommand(\n titleOrId: string,\n opts: { agent: string; notes?: string; result?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Fetch current item to get its status\n let board: { items: KanbanItem[] };\n try {\n board = await api.post<{ items: KanbanItem[] }>('/host/my-kanban', {\n agent_id: agentId,\n });\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const match = board.items.find(\n (i) => (isUuid && i.id === titleOrId) || i.title === titleOrId,\n );\n\n if (!match) {\n if (json) {\n jsonOutput({ ok: false, error: `Item \"${titleOrId}\" not found.` });\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n }\n process.exitCode = 1;\n return;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [\n {\n id: match.id,\n status: match.status,\n notes: opts.notes,\n result: opts.result,\n },\n ],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else {\n success(`Updated \"${match.title}\".`);\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt kanban done\n// ---------------------------------------------------------------------------\n\nexport async function kanbanDoneCommand(\n titleOrId: string,\n opts: { agent: string; result?: string; notes?: string },\n): Promise<void> {\n const teamSlug = requireTeam();\n if (!teamSlug) return;\n const json = isJsonMode();\n\n const agentId = await resolveAgentId(opts.agent);\n if (!agentId) {\n error(`Agent \"${opts.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const isUuid = /^[0-9a-f]{8}-/.test(titleOrId);\n const update: Record<string, unknown> = {\n status: 'done',\n result: opts.result,\n notes: opts.notes,\n };\n if (isUuid) {\n update.id = titleOrId;\n } else {\n update.title = titleOrId;\n }\n\n try {\n const data = await api.post<{ ok: boolean; updated: number }>('/host/kanban', {\n agent_id: agentId,\n update: [update],\n });\n\n if (json) {\n jsonOutput({ ok: true, updated: data.updated });\n } else if (data.updated > 0) {\n success(`Marked \"${titleOrId}\" as done.`);\n } else {\n error(`Item \"${titleOrId}\" not found.`);\n process.exitCode = 1;\n }\n } catch (err) {\n if (json) {\n jsonOutput({ ok: false, error: (err as Error).message });\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n }\n}\n","import type { AcpAgentAdapter } from './types.js';\n\n/**\n * Built-in ACP agent adapters.\n * Only the three agents specified in ENG-4119 scope: Claude Code, OpenClaw, Codex.\n */\nexport const ACP_AGENT_REGISTRY: readonly AcpAgentAdapter[] = [\n {\n name: 'claude',\n label: 'Claude Code',\n adapter_package: 'claude-agent-acp',\n command: 'npx',\n args: ['-y', 'claude-agent-acp'],\n type: 'npx-wrapper',\n },\n {\n name: 'openclaw',\n label: 'OpenClaw',\n command: 'openclaw',\n args: ['acp'],\n type: 'native',\n },\n {\n name: 'codex',\n label: 'Codex',\n adapter_package: 'codex-acp',\n command: 'npx',\n args: ['-y', 'codex-acp'],\n type: 'npx-wrapper',\n },\n] as const;\n\nconst agentMap = new Map<string, AcpAgentAdapter>(\n ACP_AGENT_REGISTRY.map((a) => [a.name, a]),\n);\n\nexport function getAcpAgent(name: string): AcpAgentAdapter | undefined {\n return agentMap.get(name);\n}\n\nexport function getAllAcpAgentNames(): string[] {\n return ACP_AGENT_REGISTRY.map((a) => a.name);\n}\n","import { spawn } from 'node:child_process';\nimport type {\n AcpSessionMetadata,\n AcpEvent,\n AcpPermissionMode,\n AcpAgentAdapter,\n} from './types.js';\nimport { getAcpAgent } from './agent-registry.js';\n\nexport interface AcpSpawnOptions {\n /** Agent name or custom command */\n agent: string;\n /** Working directory for the session */\n cwd: string;\n /** Named session for parallel workstreams */\n sessionName?: string;\n /** Permission mode */\n permissions?: AcpPermissionMode;\n /** Queue owner idle TTL in seconds */\n ttl?: number;\n /** Prompt execution timeout in seconds */\n timeout?: number;\n /** Auto-approve all tool permissions */\n approveAll?: boolean;\n}\n\nexport interface AcpPromptOptions {\n /** Agent name */\n agent: string;\n /** Prompt text */\n prompt: string;\n /** Working directory */\n cwd: string;\n /** Named session */\n sessionName?: string;\n /** Output format */\n format?: 'text' | 'json' | 'json-strict' | 'quiet';\n /** Don't wait for completion */\n noWait?: boolean;\n /** Timeout in seconds */\n timeout?: number;\n}\n\nexport interface AcpExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n events: AcpEvent[];\n}\n\n/**\n * Resolves the acpx command and arguments for a given agent.\n * Falls back to raw command execution for unknown agents.\n */\nfunction resolveAgentCommand(agentName: string): { command: string; args: string[] } {\n const adapter = getAcpAgent(agentName);\n if (adapter) {\n return {\n command: 'acpx',\n args: [adapter.name],\n };\n }\n // Unknown agent — use raw command via --agent flag\n return {\n command: 'acpx',\n args: ['--agent', agentName],\n };\n}\n\n/**\n * Runs an acpx command and returns the result.\n */\nexport async function runAcpx(\n args: string[],\n options: { cwd?: string; timeout?: number } = {},\n): Promise<AcpExecResult> {\n return new Promise((resolve) => {\n const child = spawn('acpx', args, {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n });\n\n let stdout = '';\n let stderr = '';\n const events: AcpEvent[] = [];\n\n child.stdout?.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdout += chunk;\n // Parse NDJSON events if format is json\n for (const line of chunk.split('\\n').filter(Boolean)) {\n try {\n const parsed = JSON.parse(line) as AcpEvent;\n if (parsed.eventVersion === 1) {\n events.push(parsed);\n }\n } catch {\n // Not JSON — plain text output\n }\n }\n });\n\n child.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const timer = options.timeout\n ? setTimeout(() => child.kill('SIGTERM'), options.timeout * 1000)\n : undefined;\n\n child.on('close', (code) => {\n if (timer) clearTimeout(timer);\n resolve({ exitCode: code ?? 1, stdout, stderr, events });\n });\n });\n}\n\n/**\n * Spawns a new ACP session via acpx.\n */\nexport async function acpSpawnSession(opts: AcpSpawnOptions): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(opts.agent);\n const args = [...agentArgs, 'sessions', 'ensure'];\n\n if (opts.sessionName) args.push('-s', opts.sessionName);\n if (opts.approveAll) args.unshift('--approve-all');\n if (opts.ttl !== undefined) args.unshift('--ttl', String(opts.ttl));\n\n args.unshift('--format', 'json');\n\n return runAcpx(args, { cwd: opts.cwd });\n}\n\n/**\n * Sends a prompt to an ACP session.\n */\nexport async function acpPrompt(opts: AcpPromptOptions): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(opts.agent);\n const args = [...agentArgs, 'prompt', opts.prompt];\n\n if (opts.sessionName) args.push('-s', opts.sessionName);\n if (opts.noWait) args.push('--no-wait');\n if (opts.format) args.unshift('--format', opts.format);\n if (opts.timeout) args.unshift('--timeout', String(opts.timeout));\n\n return runAcpx(args, { cwd: opts.cwd, timeout: opts.timeout });\n}\n\n/**\n * Executes a one-shot prompt (no session reuse).\n */\nexport async function acpExec(\n agent: string,\n prompt: string,\n options: { cwd?: string; format?: string; timeout?: number } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'exec', prompt];\n\n if (options.format) args.unshift('--format', options.format);\n if (options.timeout) args.unshift('--timeout', String(options.timeout));\n\n return runAcpx(args, { cwd: options.cwd, timeout: options.timeout });\n}\n\n/**\n * Lists active sessions for an agent.\n */\nexport async function acpListSessions(\n agent: string,\n options: { cwd?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'sessions', 'list', '--format', 'json'];\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Cancels the current prompt in an ACP session.\n */\nexport async function acpCancel(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'cancel'];\n\n if (options.sessionName) args.push('-s', options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Closes (soft-close) an ACP session.\n */\nexport async function acpCloseSession(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'sessions', 'close'];\n\n if (options.sessionName) args.push(options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n\n/**\n * Gets status of the current ACP session.\n */\nexport async function acpStatus(\n agent: string,\n options: { cwd?: string; sessionName?: string } = {},\n): Promise<AcpExecResult> {\n const { command: _cmd, args: agentArgs } = resolveAgentCommand(agent);\n const args = [...agentArgs, 'status', '--format', 'json'];\n\n if (options.sessionName) args.push('-s', options.sessionName);\n\n return runAcpx(args, { cwd: options.cwd });\n}\n","import {\n acpSpawnSession,\n acpPrompt,\n acpExec,\n acpListSessions,\n acpCancel,\n acpCloseSession,\n} from '@augmented/core/acp';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\n// ---------------------------------------------------------------------------\n// agt acpx spawn\n// ---------------------------------------------------------------------------\n\nexport async function acpxSpawnCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n const approveAll = Boolean(parentOpts.approveAll);\n const ttl = parentOpts.ttl !== undefined ? Number(parentOpts.ttl) : undefined;\n\n info(`Spawning ACP session for \"${agent}\"...`);\n\n const result = await acpSpawnSession({\n agent,\n cwd,\n sessionName,\n approveAll,\n ttl,\n });\n\n if (result.exitCode !== 0) {\n error(`Failed to spawn session: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonMode()) {\n process.stdout.write(result.stdout);\n } else {\n success(`ACP session spawned for \"${agent}\"`);\n if (sessionName) info(`Session name: ${sessionName}`);\n info(`Working directory: ${cwd}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx prompt\n// ---------------------------------------------------------------------------\n\nexport async function acpxPromptCommand(\n agent: string,\n prompt: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n const format = (parentOpts.format as string) ?? 'text';\n const noWait = Boolean(parentOpts.noWait);\n const timeout = parentOpts.timeout !== undefined ? Number(parentOpts.timeout) : undefined;\n\n if (!isJsonMode()) info(`Sending prompt to \"${agent}\"...`);\n\n const result = await acpPrompt({\n agent,\n prompt,\n cwd,\n sessionName,\n format: format as 'text' | 'json' | 'json-strict' | 'quiet',\n noWait,\n timeout,\n });\n\n process.stdout.write(result.stdout);\n if (result.stderr) process.stderr.write(result.stderr);\n process.exitCode = result.exitCode;\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx exec\n// ---------------------------------------------------------------------------\n\nexport async function acpxExecCommand(\n agent: string,\n prompt: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const format = (parentOpts.format as string) ?? 'text';\n const timeout = parentOpts.timeout !== undefined ? Number(parentOpts.timeout) : undefined;\n\n if (!isJsonMode()) info(`Running one-shot exec with \"${agent}\"...`);\n\n const result = await acpExec(agent, prompt, { cwd, format, timeout });\n\n process.stdout.write(result.stdout);\n if (result.stderr) process.stderr.write(result.stderr);\n process.exitCode = result.exitCode;\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx list-sessions\n// ---------------------------------------------------------------------------\n\nexport async function acpxListSessionsCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n\n const result = await acpListSessions(agent, { cwd });\n\n if (isJsonMode()) {\n process.stdout.write(result.stdout);\n } else {\n if (result.exitCode !== 0) {\n error(`Failed to list sessions: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n // Parse and display as table\n try {\n const sessions = JSON.parse(result.stdout);\n if (Array.isArray(sessions) && sessions.length > 0) {\n info(`Active sessions for \"${agent}\":`);\n process.stdout.write(result.stdout);\n } else {\n info(`No active sessions for \"${agent}\".`);\n }\n } catch {\n process.stdout.write(result.stdout);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx cancel\n// ---------------------------------------------------------------------------\n\nexport async function acpxCancelCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n\n info(`Sending cancel to \"${agent}\"...`);\n\n const result = await acpCancel(agent, { cwd, sessionName });\n\n if (result.exitCode !== 0) {\n error(`Cancel failed: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n success('Cancel sent (cooperative).');\n}\n\n// ---------------------------------------------------------------------------\n// agt acpx close\n// ---------------------------------------------------------------------------\n\nexport async function acpxCloseCommand(\n agent: string,\n _opts: Record<string, unknown>,\n cmd: { parent: { opts: () => Record<string, unknown> } },\n): Promise<void> {\n const parentOpts = cmd.parent.opts();\n const cwd = (parentOpts.cwd as string) ?? process.cwd();\n const sessionName = parentOpts.name as string | undefined;\n\n info(`Closing ACP session for \"${agent}\"...`);\n\n const result = await acpCloseSession(agent, { cwd, sessionName });\n\n if (result.exitCode !== 0) {\n error(`Close failed: ${result.stderr || 'unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n success('Session closed (soft-close — history retained).');\n}\n","import { execFileSync, execSync } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { getHost } from '../lib/config.js';\nimport { success, error, info, warn } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ndeclare const __CLI_VERSION__: string;\n\nconst cliVersion = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : 'dev';\n\nexport interface VersionInfo {\n latest: string;\n download_url: string;\n changelog_url?: string;\n}\n\n/**\n * Fetch the latest CLI version from the API.\n * Returns null if the API is unreachable (silent fail).\n */\nexport async function fetchLatestVersion(): Promise<VersionInfo | null> {\n const host = getHost();\n if (!host) return null;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5_000);\n timeout.unref();\n\n const res = await fetch(`${host}/cli/version`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!res.ok) return null;\n\n return (await res.json()) as VersionInfo;\n } catch {\n // Network error, timeout, etc. — silently fail\n return null;\n }\n}\n\n/**\n * Compare two semver strings. Returns true if remote > local.\n */\nfunction isNewerVersion(local: string, remote: string): boolean {\n if (local === 'dev') return false;\n\n const parse = (v: string) => v.replace(/^v/, '').split('.').map(Number);\n const lParts = parse(local);\n const rParts = parse(remote);\n const lMaj = lParts[0] ?? 0, lMin = lParts[1] ?? 0, lPat = lParts[2] ?? 0;\n const rMaj = rParts[0] ?? 0, rMin = rParts[1] ?? 0, rPat = rParts[2] ?? 0;\n\n if (rMaj !== lMaj) return rMaj > lMaj;\n if (rMin !== lMin) return rMin > lMin;\n return rPat > lPat;\n}\n\n/**\n * Detect running manager process and active agent tmux sessions.\n * Returns a summary of what's running.\n *\n * ENG-4635: pgrep can race with process exit — by the time we report\n * \"Manager running PID X\", X may already be a tombstone. The agt-update\n * report-then-exit pattern made this acutely visible (operators saw\n * warnings about phantom PIDs that ps -p couldn't find). Verify each\n * candidate PID with kill(pid, 0) before reporting it. kill(pid, 0)\n * doesn't actually signal — it just probes whether the OS still\n * recognises the PID and whether we have permission to signal it.\n * ESRCH means dead/recycled; we treat that as \"not running\". EPERM\n * means alive but owned by someone else — still alive, count it.\n */\n// Exported for unit testing — see __tests__/update-pid-check.test.ts.\nexport function isPidAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n // EPERM = process exists but owned by a different uid; still alive.\n // ESRCH = no such process. Anything else is unexpected — treat as\n // \"unknown\" and assume not alive so we don't block updates on a\n // weird PID lookup error.\n return (err as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nfunction detectActiveSessions(): { managerPid: string | null; tmuxSessions: string[] } {\n let managerPid: string | null = null;\n try {\n const pid = execSync('pgrep -f \"agt.*(manage|manager)\" 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n // Filter out our own PID and verify the survivors are actually alive.\n // pgrep can win the race with a fleeting process (e.g. another\n // `agt manager status` from a concurrent script) and report a PID\n // that has already exited — without the kill(0) check we'd warn\n // operators about a phantom manager and block their update.\n const ownPid = String(process.pid);\n const pids = pid\n .split('\\n')\n .map((p) => p.trim())\n .filter((p) => p && p !== ownPid)\n .filter((p) => isPidAlive(Number(p)));\n managerPid = pids[0] ?? null;\n } catch { /* no manager running */ }\n\n const tmuxSessions: string[] = [];\n try {\n const sessions = execSync('tmux ls 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n if (sessions) {\n for (const line of sessions.split('\\n')) {\n // Agent sessions use patterns like \"claude-{codeName}\" or \"agt-{codeName}\"\n if (line.match(/^(claude-|agt-)/)) {\n const name = line.split(':')[0];\n if (name) tmuxSessions.push(name);\n }\n }\n }\n } catch { /* tmux not available or no sessions */ }\n\n return { managerPid, tmuxSessions };\n}\n\n/**\n * Detect how the currently running `agt` binary was installed.\n *\n * Returns 'brew' only when the resolved path is inside a Homebrew Cellar\n * (the canonical formula install location: `.../Cellar/<formula>/<version>/bin/…`).\n * A bare `/home/linuxbrew/` or `/opt/homebrew/` prefix isn't enough —\n * Homebrew's Node hosts `npm install -g` targets like\n * `/opt/homebrew/lib/node_modules/@integrity-labs/agt-cli/...`, which is\n * an npm install *managed by* npm, not a brew formula.\n */\nfunction detectInstallSource(): 'brew' | 'npm' {\n try {\n const resolved = realpathSync(process.argv[1] ?? '');\n // Match /Cellar/<formula>/ specifically — works for both\n // /home/linuxbrew/.linuxbrew/Cellar and /opt/homebrew/Cellar.\n if (/\\/Cellar\\/[^/]+\\//.test(resolved)) {\n return 'brew';\n }\n } catch { /* fall through */ }\n return 'npm';\n}\n\n/**\n * Perform the actual update. Uses brew if the CLI was installed that way,\n * otherwise npm from the public registry (where we actually publish —\n * the earlier implementation pointed at GitHub Packages, which is wrong).\n */\nfunction performUpdate(version: string): void {\n const source = detectInstallSource();\n if (source === 'brew') {\n try {\n execFileSync('brew', ['upgrade', 'integrity-labs/tap/agt'], { stdio: 'inherit' });\n return;\n } catch (err) {\n // Only attempt the sudo -u <owner> retry when running as root —\n // otherwise a genuine failure (network, formula syntax error,\n // missing dependency) gets masked by a second auth error.\n const isRoot = typeof process.getuid === 'function' && process.getuid() === 0;\n if (!isRoot) throw err;\n const cellarOwner = detectBrewOwner();\n if (!cellarOwner) throw err;\n execFileSync('sudo', [\n '-u', cellarOwner,\n '-H',\n 'bash', '-c',\n 'brew tap integrity-labs/tap 2>/dev/null || true; brew upgrade integrity-labs/tap/agt',\n ], { stdio: 'inherit' });\n }\n return;\n }\n // npm path — public registry (this is where publishConfig points).\n // Use execFileSync with an argv array so the version string (which\n // originates from a remote API response) can't be interpreted by a\n // shell. Any attacker controlling the API can still push a malicious\n // package, but they can't also inject shell metacharacters via the\n // version field on top of that.\n execFileSync('npm', [\n 'install',\n '-g',\n `@integrity-labs/agt-cli@${version}`,\n '--registry=https://registry.npmjs.org',\n ], { stdio: 'inherit' });\n}\n\nfunction detectBrewOwner(): string | null {\n for (const prefix of ['/home/linuxbrew/.linuxbrew', '/opt/homebrew', '/usr/local']) {\n const cellar = `${prefix}/Cellar`;\n if (!existsSync(cellar)) continue;\n try {\n return execSync(`stat -c %U \"${cellar}\" 2>/dev/null || stat -f %Su \"${cellar}\"`, { encoding: 'utf-8' }).trim() || null;\n } catch { /* try next */ }\n }\n return null;\n}\n\n/**\n * `agt update` command handler.\n */\nexport async function updateCommand(opts: { force?: boolean } = {}): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Checking for updates…', isSilent: json });\n spinner.start();\n\n const versionInfo = await fetchLatestVersion();\n\n if (!versionInfo) {\n spinner.stop();\n if (json) {\n jsonOutput({ ok: false, error: 'Could not reach API to check for updates' });\n } else {\n warn('Could not reach the API to check for updates. Check AGT_HOST is set and the API is reachable.');\n }\n process.exitCode = 1;\n return;\n }\n\n const updateAvailable = isNewerVersion(cliVersion, versionInfo.latest);\n\n if (!updateAvailable) {\n spinner.stop();\n if (json) {\n jsonOutput({ ok: true, current: cliVersion, latest: versionInfo.latest, update_available: false });\n } else {\n success(`You're on the latest version (${chalk.bold(cliVersion)})`);\n }\n return;\n }\n\n spinner.stop();\n\n if (!json) {\n info(`Update available: ${chalk.dim(cliVersion)} → ${chalk.bold.green(versionInfo.latest)}`);\n if (versionInfo.changelog_url) {\n info(`Changelog: ${versionInfo.changelog_url}`);\n }\n }\n\n // Check for active sessions unless --force is set\n if (!opts.force) {\n const { managerPid, tmuxSessions } = detectActiveSessions();\n\n if (managerPid || tmuxSessions.length > 0) {\n if (!json) {\n warn('Active processes detected:');\n if (managerPid) {\n console.error(chalk.yellow(` • Manager process running (PID ${managerPid})`));\n }\n if (tmuxSessions.length > 0) {\n console.error(chalk.yellow(` • ${tmuxSessions.length} active agent session(s): ${tmuxSessions.join(', ')}`));\n }\n console.error();\n warn('Updating while the manager is running will leave it on the old version until restarted.');\n warn('Active agent sessions will continue with stale MCP servers.');\n console.error();\n info(`Run ${chalk.bold('agt update --force')} to update anyway, then restart the manager.`);\n } else {\n jsonOutput({\n ok: false,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: false,\n blocked: true,\n manager_running: !!managerPid,\n active_sessions: tmuxSessions,\n error: 'Active manager or agent sessions detected. Use --force to override.',\n });\n }\n process.exitCode = 1;\n return;\n }\n }\n\n const updateSpinner = ora({ text: 'Installing update…', isSilent: json });\n updateSpinner.start();\n\n try {\n performUpdate(versionInfo.latest);\n updateSpinner.stop();\n if (json) {\n jsonOutput({\n ok: true,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: true,\n });\n } else {\n success(`Updated to ${chalk.bold(versionInfo.latest)}`);\n info(`If you have a running manager, restart it: ${chalk.bold('agt manager stop && agt manager start')}`);\n }\n } catch (err) {\n updateSpinner.fail('Update failed');\n if (json) {\n jsonOutput({\n ok: false,\n current: cliVersion,\n latest: versionInfo.latest,\n update_available: true,\n updated: false,\n error: (err as Error).message,\n });\n } else {\n error(`Failed to install update: ${(err as Error).message}`);\n const source = detectInstallSource();\n if (source === 'brew') {\n info(`You can manually update with: brew upgrade integrity-labs/tap/agt`);\n } else {\n info(`You can manually update with: sudo npm install -g @integrity-labs/agt-cli@${versionInfo.latest}`);\n }\n }\n process.exitCode = 1;\n }\n}\n\n/**\n * Non-blocking startup version check. Prints a one-liner if an update is available.\n * Silently does nothing on failure.\n */\nexport async function checkForUpdateOnStartup(): Promise<void> {\n try {\n const versionInfo = await fetchLatestVersion();\n if (!versionInfo) return;\n\n if (isNewerVersion(cliVersion, versionInfo.latest)) {\n console.error(\n chalk.yellow(`\\n Update available: ${cliVersion} → ${versionInfo.latest}. Run ${chalk.bold('agt update')} to install.`)\n + chalk.dim('\\n Note: Restart the manager after updating.\\n')\n );\n }\n } catch {\n // Silent fail — never block CLI usage\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { auditSubagentMcpBindings, formatFinding } from '../lib/subagent-mcp-audit.js';\n\n/**\n * ENG-5897 — `agt audit subagents` command.\n *\n * Walks the conventional sub-agent definition roots visible to a\n * Claude Code session — the user's `~/.claude/agents/`, every\n * installed plugin under `~/.claude/plugins/<plugin>/agents/`, and\n * the current working directory's `.claude/agents/` (if any) — and\n * reports each sub-agent whose `tools:` allowlist would block every\n * `mcp__*` tool on dispatch. That's the silent-fallback failure mode\n * ENG-5897 / ENG-5898 are closing the door on: a parent agent\n * dispatches one of these sub-agents to do MCP-tool work, the child\n * reports \"No such tool available.\" for every `mcp__*` call, and (in\n * the worst case) reaches for raw secrets out of `.mcp.json` to\n * complete the task off-policy.\n *\n * Exit codes:\n * 0 — no findings (or some findings; we still exit 0 because\n * restrictive plugin sub-agents are sometimes intentional)\n * 2 — only used by `--strict`, when at least one finding exists.\n * Useful in CI to gate a deploy on a clean audit.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n}\n\nfunction defaultRoots(): string[] {\n const home = homedir();\n return [\n join(home, '.claude', 'agents'),\n join(home, '.claude', 'plugins'),\n join(process.cwd(), '.claude', 'agents'),\n ];\n}\n\nexport async function auditSubagentsCommand(options: AuditOptions = {}): Promise<void> {\n const roots = defaultRoots();\n const findings = auditSubagentMcpBindings(roots);\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings, roots }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write('No restrictive sub-agents found — every sub-agent under the scanned roots either inherits the parent toolset or explicitly includes mcp__* wildcards.\\n');\n } else {\n process.stdout.write(`Found ${findings.length} sub-agent${findings.length === 1 ? '' : 's'} whose tools allowlist excludes mcp__*:\\n\\n`);\n for (const f of findings) {\n process.stdout.write(` • ${f.name} (${f.file})\\n`);\n process.stdout.write(` tools: ${f.tools}\\n`);\n }\n process.stdout.write(\n '\\nThese sub-agents will return \"No such tool available.\" for every mcp__* call when dispatched from a managed agent. ' +\n \"If the parent needs to do MCP-tool work, dispatch the Augmented plugin's `augmented-worker` sub-agent instead — \" +\n \"it omits `tools:` so it inherits the parent's full toolset including every MCP server. See ENG-5897.\\n\",\n );\n // Structured log line per finding for log-grep workflows.\n for (const f of findings) {\n process.stderr.write(`${formatFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * ENG-5897 — regression check that surfaces sub-agent definitions whose\n * `tools:` allowlist structurally excludes every `mcp__*` MCP tool.\n *\n * Why this exists: per Anthropic's Claude Code sub-agent docs\n * (https://code.claude.com/docs/en/sub-agents) a sub-agent inherits the\n * parent's full toolset (including MCPs) when its frontmatter omits the\n * `tools:` field. The moment the field is set as an allowlist, only the\n * exact entries listed are exposed to the child. Many community-plugin\n * sub-agents ship restrictive `tools:` lists like `tools: Read, Grep`\n * with no `mcp__*` entries. When a managed agent's parent dispatches\n * one of those for multi-step tool work, the child silently reports\n * \"No such tool available.\" for every MCP call and may fall back to\n * unsafe paths (reading raw secrets from .mcp.json — see ENG-5898).\n *\n * This module gives the manager a way to detect that class of sub-agent\n * at boot and log a structured warning, so the gap is visible at the\n * earliest possible moment rather than at first dispatch on a real\n * inbound task. Strictly read-only — no file mutation, no side effects\n * beyond `fs.readFileSync`.\n *\n * The audit deliberately does NOT fail boot — a restrictive plugin\n * sub-agent may be intentional (e.g. a read-only researcher). The\n * caller (manager-worker boot) logs findings as warnings and lets the\n * operator decide. Augmented's own `augmented-worker` is the canonical\n * antidote: it ships in `claudecode-plugin-augmented/agents/` with\n * `tools:` deliberately omitted so the parent can dispatch to it for\n * any MCP-heavy work.\n */\n\nexport interface SubagentFinding {\n /** Absolute path to the sub-agent definition that triggered the finding. */\n file: string;\n /** The `name:` declared in the sub-agent's frontmatter, or `<unknown>`. */\n name: string;\n /** Raw value of the `tools:` field as it appears in the frontmatter. */\n tools: string;\n /** One-line classification — used by the caller's log line. */\n reason: 'restrictive-tools-no-mcp';\n}\n\ninterface ParsedFrontmatter {\n name?: string;\n tools?: string;\n background?: string;\n}\n\n/**\n * Pull the YAML frontmatter block from a sub-agent markdown file and\n * return the three fields we care about (`name`, `tools`, `background`)\n * as raw strings. Anything else in the frontmatter is ignored.\n *\n * Returns `null` when the file does not start with a `---` frontmatter\n * fence — those files are not Claude Code sub-agent definitions and we\n * silently skip them rather than emit a noisy parse error.\n *\n * Handles both line-ending conventions (LF and CRLF — Windows\n * contributors / cross-platform plugin authors are a real population)\n * and both `tools:` shapes Claude Code accepts:\n *\n * tools: Read, Grep, Glob # inline comma list (docs default)\n *\n * tools: # YAML sequence (also supported,\n * - Read # GitHub issue\n * - Grep # anthropics/claude-code#19114)\n * - mcp__augmented__*\n *\n * For the sequence form we collect items into a comma-joined string\n * shape `toolsExcludeMcp` already understands. Without this, an\n * MCP-blind sub-agent that uses the array form would slip past the\n * audit because the `tools:` line itself looks empty.\n */\nfunction parseFrontmatter(content: string): ParsedFrontmatter | null {\n // Accept LF or CRLF line endings on the frontmatter fences.\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) return null;\n const out: ParsedFrontmatter = {};\n const lines = match[1]!.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n // Match `key: value` at the start of the line. We don't support\n // arbitrary multi-line YAML values, but we special-case the YAML\n // sequence form for `tools:` below because Claude Code accepts it\n // and at least one community plugin uses it.\n const m = line.match(/^(name|tools|background):\\s*(.*)$/);\n if (!m) continue;\n const [, key, rawValue] = m as unknown as [string, 'name' | 'tools' | 'background', string];\n const trimmed = rawValue.trim();\n\n // YAML sequence for `tools:` — empty inline value followed by\n // indented `- item` lines. Collect them into a comma-joined\n // string. Any line that isn't indented `- item` (including blank\n // lines or the next top-level key) ends the sequence; the outer\n // loop's index walks past whatever we consumed.\n if (key === 'tools' && trimmed === '') {\n const items: string[] = [];\n let j = i + 1;\n while (j < lines.length) {\n const nextRaw = lines[j]!;\n const itemMatch = nextRaw.match(/^(\\s+)-\\s*(.+?)\\s*$/);\n if (!itemMatch) break;\n // Strip surrounding quotes if the YAML author wrote them.\n items.push(itemMatch[2]!.replace(/^['\"](.*)['\"]$/, '$1'));\n j++;\n }\n if (items.length > 0) {\n out.tools = items.join(', ');\n i = j - 1; // resume the outer loop after the consumed items\n continue;\n }\n }\n\n out[key] = trimmed;\n }\n return out;\n}\n\n/**\n * True when the `tools:` frontmatter value would prevent the sub-agent\n * from receiving any `mcp__*` tool on dispatch. The allowlist is\n * considered MCP-safe if it contains either:\n *\n * - a literal `mcp__` substring (an explicit MCP wildcard or tool\n * name like `mcp__granola__*` or `mcp__augmented__list_tools`), or\n * - a bare `*` / `All tools` token (the convention the docs use for\n * full inheritance; Claude Code treats these as \"everything\").\n *\n * If the value is empty, the frontmatter line is effectively absent and\n * the caller falls back to the \"tools: omitted\" inheritance path —\n * this helper returns `false` in that case.\n */\nfunction toolsExcludeMcp(tools: string): boolean {\n if (tools.length === 0) return false;\n if (/\\bmcp__/.test(tools)) return false;\n // Anthropic's convention strings for full inheritance.\n if (/\\*/.test(tools)) return false;\n if (/\\bAll tools\\b/i.test(tools)) return false;\n return true;\n}\n\n/**\n * Walk `dir` recursively and yield absolute paths of every `*.md` file\n * directly under an `agents/` directory. We only care about the\n * `agents/` location because that's where Claude Code looks for\n * sub-agent definitions — `skills/`, `commands/`, etc. live alongside\n * but are unrelated.\n *\n * Symlinks are followed by readdirSync's default behaviour, but we\n * cap directory depth at 6 to avoid getting stuck if a plugin\n * accidentally creates a cycle.\n */\nfunction findSubagentFiles(dir: string, depth = 0): string[] {\n if (depth > 6) return [];\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return []; // Directory missing or unreadable — silently skip.\n }\n const out: string[] = [];\n const isAgentsDir = dir.endsWith('/agents') || dir.endsWith('\\\\agents');\n for (const entry of entries) {\n const full = join(dir, entry);\n let s: ReturnType<typeof statSync>;\n try {\n s = statSync(full);\n } catch {\n continue;\n }\n if (s.isDirectory()) {\n out.push(...findSubagentFiles(full, depth + 1));\n } else if (s.isFile() && isAgentsDir && entry.endsWith('.md')) {\n out.push(full);\n }\n }\n return out;\n}\n\n/**\n * Scan the given root directories for sub-agent definitions whose\n * `tools:` allowlist would block every `mcp__*` tool. The caller\n * passes paths like `~/.claude/agents`, `~/.claude/plugins`, and the\n * agent's project `.claude` dir; we walk each and filter by the\n * `agents/` location convention.\n */\nexport function auditSubagentMcpBindings(rootDirs: string[]): SubagentFinding[] {\n const findings: SubagentFinding[] = [];\n const seen = new Set<string>();\n for (const root of rootDirs) {\n for (const file of findSubagentFiles(root)) {\n if (seen.has(file)) continue;\n seen.add(file);\n let content: string;\n try {\n content = readFileSync(file, 'utf-8');\n } catch {\n continue;\n }\n const fm = parseFrontmatter(content);\n if (!fm || typeof fm.tools !== 'string') continue;\n if (!toolsExcludeMcp(fm.tools)) continue;\n findings.push({\n file,\n name: fm.name ?? '<unknown>',\n tools: fm.tools,\n reason: 'restrictive-tools-no-mcp',\n });\n }\n }\n return findings;\n}\n\n/**\n * Format an audit finding as a single-line structured log entry that\n * matches the manager-worker stderr convention\n * (`[manager-worker] [<subsystem>] ...`). The caller picks where to\n * emit (stderr / manager.log / both).\n */\nexport function formatFinding(f: SubagentFinding): string {\n // Quote the tools value so a comma-bearing list doesn't confuse a\n // future log-parser that splits on whitespace.\n return `[manager-worker] [subagent-mcp-audit] file=${f.file} name=${f.name} reason=${f.reason} tools=${JSON.stringify(f.tools)}`;\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * ENG-5922 — runtime audit for subagent .md `tools:` allowlist\n * staleness vs the agent's actual `.mcp.json` `mcpServers` keys.\n *\n * Why this exists: ENG-5897 + ENG-5905 added the `augmented-worker`\n * sub-agent on the same dynamic-render path as the existing\n * `channel-message-handler` sub-agent. Don's empirical re-test\n * 2026-06-02 showed the rendered `tools:` allowlist on his host was\n * stale — only a subset of the actual `.mcp.json` keys. Causes:\n * (a) the direct-chat manager-worker write bypassed the render\n * chokepoint (fixed in this PR), and (b) the `agt provision` command\n * builds `.mcp.json` without integration data, producing a 1-server\n * file that pollutes the rendered .md (tracked separately as a\n * follow-up). The render-vs-.mcp.json drift had been hidden in\n * production for months because nobody empirically tested the\n * matching invariant.\n *\n * The runtime audit closes the gap by checking, for each managed\n * agent on the host, whether the rendered `tools:` allowlist in\n * `channel-message-handler.md` and `augmented-worker.md` is a\n * superset of the live `.mcp.json` `mcpServers` keys. Drift surfaces\n * as a finding the operator (and CI in `--strict`) can act on\n * without waiting for an agent to silently fail on a missing MCP\n * tool. Strictly read-only — no file mutation.\n */\n\nexport interface RenderDriftFinding {\n /** Agent code_name (the directory name under `~/.augmented/`). */\n agent: string;\n /** Which sub-agent .md is out of sync. */\n subagent: 'channel-message-handler' | 'augmented-worker';\n /** Whether the file we read lives in the provision/ canonical or project/ mirror. */\n scope: 'provision' | 'project';\n /** Server keys present in .mcp.json that the .md's tools allowlist DOESN'T cover. */\n missing: string[];\n /** Absolute path to the .md file with the stale allowlist. */\n file: string;\n}\n\n/**\n * Sanitise an MCP server key to the wildcard form Claude Code emits\n * (`<key>` → `mcp__<key_with_hyphens_to_underscores>__*`). Mirror of\n * the `sanitizeMcpName` function in\n * `packages/core/src/provisioning/frameworks/claudecode/index.ts`.\n */\nfunction expectedWildcard(serverKey: string): string {\n return `mcp__${serverKey.replace(/-/g, '_')}__*`;\n}\n\n/**\n * Extract the `tools:` allowlist tokens from a rendered sub-agent\n * .md file. Returns the list of `mcp__*` wildcards (NOT the\n * built-ins like `Bash`/`Read`/etc., which are out of scope here).\n * Returns `null` when the file has no `tools:` line at all (would be\n * the inheritance-omitted shape ENG-5897 originally shipped — kept\n * as a distinct return so the caller can decide).\n */\nexport function parseMcpWildcardsFromToolsLine(content: string): string[] | null {\n const toolsLine = content.split('\\n').find((l) => l.startsWith('tools:'));\n if (!toolsLine) return null;\n const value = toolsLine.replace(/^tools:\\s*/, '').trim();\n if (value.length === 0) return [];\n return value\n .split(/\\s*,\\s*/)\n .map((t) => t.trim())\n .filter((t) => t.startsWith('mcp__'));\n}\n\n/**\n * Read an agent's `.mcp.json` (provision-scope) and return the\n * top-level `mcpServers` keys, or `null` when the file is missing\n * or unreadable — the caller silently skips that agent in those\n * cases.\n */\nfunction readMcpServerKeys(mcpJsonPath: string): string[] | null {\n try {\n const config = JSON.parse(readFileSync(mcpJsonPath, 'utf-8')) as {\n mcpServers?: Record<string, unknown>;\n };\n return Object.keys(config.mcpServers ?? {});\n } catch {\n return null;\n }\n}\n\n/**\n * Scan every managed-agent directory under `~/.augmented/` (one\n * directory per `code_name`) and report any sub-agent .md whose\n * `tools:` allowlist is missing a wildcard for a server present in\n * the agent's `.mcp.json`. Both the `provision/` canonical and the\n * `project/` mirror are checked — the mirror is what Claude Code\n * actually reads at session-spawn time, but a provision/ drift is\n * still a bug (the next sync will propagate it to project/).\n */\nexport function auditMcpRenderAllowlist(\n rootDir: string = join(homedir(), '.augmented'),\n): RenderDriftFinding[] {\n const findings: RenderDriftFinding[] = [];\n\n let entries: string[];\n try {\n entries = readdirSync(rootDir);\n } catch {\n return findings; // Root missing — no managed agents on this host.\n }\n\n for (const entry of entries) {\n const agentDir = join(rootDir, entry);\n let s: ReturnType<typeof statSync>;\n try {\n s = statSync(agentDir);\n } catch {\n continue;\n }\n if (!s.isDirectory() || entry.startsWith('_') || entry.startsWith('.')) continue;\n\n // For each scope, audit both sub-agent files against the\n // canonical .mcp.json from THAT scope (provision vs project).\n // A provision/ drift indicates the render at agt-provision time\n // missed a server; a project/ drift indicates a subsequent\n // mutation didn't re-trigger the render.\n for (const scope of ['provision', 'project'] as const) {\n const mcpJsonPath = scope === 'provision'\n ? join(agentDir, 'provision', '.mcp.json')\n : join(agentDir, 'project', '.mcp.json');\n const keys = readMcpServerKeys(mcpJsonPath);\n if (keys === null || keys.length === 0) continue;\n const expected = new Set(keys.map(expectedWildcard));\n\n for (const subagent of ['channel-message-handler', 'augmented-worker'] as const) {\n const mdPath = scope === 'provision'\n ? join(agentDir, '.claude', 'agents', `${subagent}.md`)\n : join(agentDir, 'project', '.claude', 'agents', `${subagent}.md`);\n let content: string;\n try {\n content = readFileSync(mdPath, 'utf-8');\n } catch {\n continue; // .md not yet rendered (new agent or agt-pre-ENG-5905) — skip.\n }\n const declared = parseMcpWildcardsFromToolsLine(content);\n if (declared === null) continue; // no tools: line → inheritance mode (different shape).\n const declaredSet = new Set(declared);\n const missing = [...expected].filter((w) => !declaredSet.has(w));\n if (missing.length > 0) {\n findings.push({ agent: entry, subagent, scope, missing, file: mdPath });\n }\n }\n }\n }\n\n return findings;\n}\n\n/**\n * Single-line structured log entry matching the manager-worker\n * stderr convention. Callers (the CLI + the manager boot probe)\n * decide where to emit.\n */\nexport function formatRenderDriftFinding(f: RenderDriftFinding): string {\n return `[manager-worker] [mcp-render-drift] agent=${f.agent} subagent=${f.subagent} scope=${f.scope} missing=${JSON.stringify(f.missing)} file=${f.file}`;\n}\n","import { auditMcpRenderAllowlist, formatRenderDriftFinding } from '../lib/mcp-render-allowlist-audit.js';\n\n/**\n * ENG-5922 — `agt audit mcp-render` command.\n *\n * Walks `~/.augmented/<agent>/` directories on the host and reports\n * every sub-agent .md whose `tools:` allowlist is missing a wildcard\n * for an MCP server present in that agent's `.mcp.json`. Catches the\n * staleness Don found on his host (rendered allowlist diverged from\n * actual server set; trivially-correct sub-agent calls failed).\n *\n * Exit codes:\n * 0 — no findings (or some findings; we still exit 0 because the\n * drift may be transient mid-poll-cycle)\n * 2 — only used with `--strict`. CI / post-deploy verification\n * gates a deploy on a clean audit.\n *\n * Same shape as `agt audit subagents` (ENG-5897) and `agt audit\n * secrets` (ENG-5901). Three audit CLIs, three different invariants.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n}\n\nexport async function auditMcpRenderCommand(options: AuditOptions = {}): Promise<void> {\n const findings = auditMcpRenderAllowlist();\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write(\n 'No render drift found. Every managed agent\\'s sub-agent .md `tools:` allowlist covers every server in its `.mcp.json`.\\n',\n );\n } else {\n process.stdout.write(\n `Found ${findings.length} sub-agent .md file${findings.length === 1 ? '' : 's'} with a stale tools allowlist:\\n\\n`,\n );\n for (const f of findings) {\n process.stdout.write(` • ${f.agent}/${f.scope}/${f.subagent}.md\\n`);\n process.stdout.write(` missing: ${f.missing.join(', ')}\\n`);\n process.stdout.write(` file: ${f.file}\\n`);\n }\n process.stdout.write(\n '\\nA missing wildcard means the sub-agent will get \"No such tool available.\" on any call ' +\n 'to that MCP server. The fix is to force a re-render (e.g. by adding/removing any MCP server, ' +\n 'which routes through syncMcpToProject), OR restart the manager so the next poll picks up the ' +\n 'live `.mcp.json` state. The root-cause write path that bypassed the render chokepoint is ' +\n 'tracked in ENG-5922.\\n',\n );\n for (const f of findings) {\n process.stderr.write(`${formatRenderDriftFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n auditSecretLeaks,\n formatSecretFinding,\n type SecretAuditFinding,\n} from '../lib/secret-leak-audit.js';\n\n/**\n * ENG-5901 (Phase 1 of ADR-0018) — `agt audit secrets` command.\n *\n * Walks `~/.augmented/<agent>/{provision,project}/.mcp.json` and\n * `~/.augmented/<agent>/.env.integrations` and reports:\n * - literal (non-templated) secrets in secret-named `.mcp.json`\n * env/header fields (should be `${VAR}` placeholders), and\n * - secret files that are group/other-readable (should be 0600).\n *\n * Exit codes:\n * 0 — no findings, OR findings present without `--strict`.\n * 2 — `--strict` and at least one finding (CI deploy gate).\n *\n * Never prints a secret value — only file / agent / server / field.\n */\n\ninterface AuditOptions {\n strict?: boolean;\n json?: boolean;\n /** Override the scan root (defaults to ~/.augmented). Used by tests. */\n root?: string;\n}\n\nfunction describe(f: SecretAuditFinding): string {\n if (f.kind === 'literal-secret-in-mcp') {\n return `literal secret in ${f.location} field '${f.field}' of server '${f.server}'`;\n }\n return `secret file is mode ${f.mode} (expected 0600)`;\n}\n\nexport async function auditSecretsCommand(options: AuditOptions = {}): Promise<void> {\n const root = options.root ?? join(homedir(), '.augmented');\n const findings = auditSecretLeaks(root);\n\n if (options.json) {\n process.stdout.write(`${JSON.stringify({ findings, root }, null, 2)}\\n`);\n } else if (findings.length === 0) {\n process.stdout.write(\n `No literal secrets or world-readable secret files found under ${root}.\\n`,\n );\n } else {\n process.stdout.write(\n `Found ${findings.length} secret-handling issue${findings.length === 1 ? '' : 's'} under ${root}:\\n\\n`,\n );\n for (const f of findings) {\n process.stdout.write(` • [${f.agent}] ${describe(f)}\\n`);\n process.stdout.write(` ${f.file}\\n`);\n }\n process.stdout.write(\n '\\nLiteral secrets in .mcp.json should be `${VAR}` placeholders with the raw value in ' +\n '.env.integrations (mode 0600). See docs/operator/credential-migration-eng5898.md.\\n',\n );\n for (const f of findings) {\n process.stderr.write(`${formatSecretFinding(f)}\\n`);\n }\n }\n\n if (options.strict && findings.length > 0) {\n process.exit(2);\n }\n}\n","import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { LITERAL_SECRET_PATTERNS } from '@augmented/core/provisioning/mcp-secret-lint.js';\n\n/**\n * ENG-5901 (Phase 1 of ADR-0018) — operator-side audit for literal\n * secrets in on-disk agent config. Sibling to `agt audit subagents`\n * (ENG-5897) and `agt audit mcp-render` (ENG-5922).\n *\n * Why this exists (vs. the runtime lint in @augmented/core's\n * mcp-secret-lint): the runtime lint is a *contributor-side* gate that\n * rejects a bad write at provision/sync time. This audit is the\n * *operator-side* counterpart that walks what's already on disk:\n *\n * - `~/.augmented/<agent>/provision/.mcp.json`\n * - `~/.augmented/<agent>/project/.mcp.json`\n * - `~/.augmented/<agent>/.env.integrations`\n *\n * It catches three things the runtime lint structurally can't:\n * 1. historical leaks written before the lint existed,\n * 2. drift where a writer was bypassed,\n * 3. world-readable secret files (mode 0644 — the audit-observed\n * default for `.mcp.json`; `.env.integrations` should be 0600).\n *\n * Strictly read-only: `fs.readFileSync` / `fs.statSync` only, never a\n * write. `--strict` exits 2 so CI can gate a deploy on a clean audit.\n *\n * Secret VALUES never appear in findings or output — only the file,\n * agent, server, and field name. The whole point is not to leak.\n */\n\n/** Field-name shapes that conventionally hold a secret. */\nexport const SECRET_KEY_NAME_RE = /TOKEN|KEY|SECRET|BEARER|PASSWORD/i;\n\n/** A value is considered safely templated if it defers to a `${VAR}`\n * placeholder (e.g. `${SLACK_BOT_TOKEN}` or `Bearer ${API_KEY}`). The\n * literal secret never reaches disk in that case — Claude Code\n * substitutes it at MCP-launch time. */\nfunction isTemplated(value: string): boolean {\n return value.includes('${');\n}\n\n/** A value matching one of the shared literal-secret shapes (xoxb-/xapp-/\n * tlk_/ak_/Telegram/JWT — same list the runtime lint enforces) is a leak\n * regardless of what the field is called. Catches e.g. a literal\n * `Authorization: Bearer eyJ…` whose key name carries no secret hint\n * (CodeRabbit #1731). */\nfunction matchesKnownSecretShape(value: string): boolean {\n return LITERAL_SECRET_PATTERNS.some(({ re }) => re.test(value));\n}\n\nexport type SecretAuditKind =\n | 'literal-secret-in-mcp'\n | 'world-readable-secret-file';\n\nexport interface SecretAuditFinding {\n kind: SecretAuditKind;\n /** Absolute path of the offending file. */\n file: string;\n /** Agent code_name (the directory under the augmented root). */\n agent: string;\n /** MCP server key — only for `literal-secret-in-mcp`. */\n server?: string;\n /** env key / header name — only for `literal-secret-in-mcp`. */\n field?: string;\n /** Whether the literal sat in an `env` value or a `headers` value. */\n location?: 'env' | 'header';\n /** Octal mode (e.g. `0644`) — only for `world-readable-secret-file`. */\n mode?: string;\n}\n\ninterface McpServerEntry {\n env?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n}\n\n/** A secret file should be 0600. Any group/other permission bit is a leak. */\nfunction isWorldReadable(mode: number): boolean {\n return (mode & 0o077) !== 0;\n}\n\nfunction octal(mode: number): string {\n return `0${(mode & 0o777).toString(8)}`;\n}\n\nfunction scanMcpFile(\n file: string,\n agent: string,\n findings: SecretAuditFinding[],\n): void {\n let mode: number | null = null;\n try {\n mode = statSync(file).mode;\n } catch {\n return; // missing file — nothing to audit\n }\n if (mode !== null && isWorldReadable(mode)) {\n findings.push({ kind: 'world-readable-secret-file', file, agent, mode: octal(mode) });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(file, 'utf-8'));\n } catch {\n return; // unreadable / malformed JSON — mode finding (if any) still stands\n }\n const servers = (parsed as { mcpServers?: Record<string, unknown> })?.mcpServers;\n if (typeof servers !== 'object' || servers === null) return;\n\n for (const [server, raw] of Object.entries(servers)) {\n if (typeof raw !== 'object' || raw === null) continue;\n const entry = raw as McpServerEntry;\n const blocks: Array<[Record<string, unknown> | undefined, 'env' | 'header']> = [\n [entry.env, 'env'],\n [entry.headers, 'header'],\n ];\n for (const [block, location] of blocks) {\n if (!block) continue;\n for (const [field, value] of Object.entries(block)) {\n if (typeof value !== 'string' || value.length === 0) continue;\n if (isTemplated(value)) continue;\n // Union of two detectors (CodeRabbit #1731): a secret-NAMED field\n // holding any untemplated literal (drift catch — covers tokens\n // with no recognisable prefix), OR any field whose VALUE matches a\n // known secret shape (covers e.g. `Authorization: Bearer eyJ…`\n // where the key name carries no hint). Replacing the name check\n // entirely would regress the first class, so both run.\n if (!SECRET_KEY_NAME_RE.test(field) && !matchesKnownSecretShape(value)) continue;\n findings.push({ kind: 'literal-secret-in-mcp', file, agent, server, field, location });\n }\n }\n }\n}\n\n/** `.env.integrations` legitimately holds raw secrets, so we only check\n * its file mode (must be 0600), never its contents. */\nfunction scanEnvIntegrations(\n file: string,\n agent: string,\n findings: SecretAuditFinding[],\n): void {\n let mode: number;\n try {\n mode = statSync(file).mode;\n } catch {\n return;\n }\n if (isWorldReadable(mode)) {\n findings.push({ kind: 'world-readable-secret-file', file, agent, mode: octal(mode) });\n }\n}\n\n/**\n * Walk every agent under `augmentedRoot` (default `~/.augmented`) and\n * return findings. Pure read-only; takes the root as a parameter so\n * tests can point it at a fixture.\n */\nexport function auditSecretLeaks(augmentedRoot: string): SecretAuditFinding[] {\n const findings: SecretAuditFinding[] = [];\n let agents: string[];\n try {\n agents = readdirSync(augmentedRoot);\n } catch {\n return findings; // root missing — nothing provisioned locally\n }\n for (const agent of agents) {\n const agentDir = join(augmentedRoot, agent);\n try {\n if (!statSync(agentDir).isDirectory()) continue;\n } catch {\n continue;\n }\n scanMcpFile(join(agentDir, 'provision', '.mcp.json'), agent, findings);\n scanMcpFile(join(agentDir, 'project', '.mcp.json'), agent, findings);\n scanEnvIntegrations(join(agentDir, '.env.integrations'), agent, findings);\n }\n return findings;\n}\n\n/** Single-line structured log entry, secret-free. Mirrors the\n * `agt audit subagents` stderr convention. */\nexport function formatSecretFinding(f: SecretAuditFinding): string {\n const parts = [\n '[audit-secrets]',\n `kind=${f.kind}`,\n `agent=${f.agent}`,\n `file=${f.file}`,\n ];\n if (f.server) parts.push(`server=${f.server}`);\n if (f.field) parts.push(`field=${f.field}`);\n if (f.location) parts.push(`location=${f.location}`);\n if (f.mode) parts.push(`mode=${f.mode}`);\n return parts.join(' ');\n}\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { api, ApiError } from '../lib/api-client.js';\nimport { success, error, info } from '../lib/output.js';\nimport { isJsonMode, jsonOutput } from '../lib/globals.js';\n\ninterface IntegrationSummary {\n id: string;\n name: string;\n slug: string;\n category: string;\n status: string;\n version: number;\n skills: unknown[];\n defined_scopes: unknown[];\n}\n\ninterface IntegrationDetail extends IntegrationSummary {\n description: string | null;\n required_toolkits: string[];\n allowed_tools: string[];\n scripts: Record<string, string>;\n defined_scopes: Array<{\n id: string;\n name: string;\n description: string;\n default_min_role: string;\n }>;\n}\n\ninterface AgentIntegrationRow {\n id: string;\n agent_id: string;\n plugin_id: string;\n plugin_version: number;\n granted_scopes: string[];\n installed_at: string;\n}\n\ninterface ScopeRequest {\n id: string;\n agent_id: string;\n plugin_id: string;\n requested_scopes: string[];\n reason: string | null;\n status: string;\n requested_by: string;\n created_at: string;\n}\n\n// ── List ──────────────────────────────────────────────────────────────────\n\nexport async function integrationListCommand(): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching integrations…', isSilent: json }).start();\n\n try {\n const data = await api.get<IntegrationSummary[]>('/integrations/installs');\n spinner.stop();\n\n if (json) {\n jsonOutput({ integrations: data });\n return;\n }\n\n if (!data.length) {\n info('No integrations found for this team.');\n return;\n }\n\n console.log(chalk.bold('\\nAvailable Integrations:\\n'));\n for (const p of data) {\n const statusColor = p.status === 'published' ? chalk.green : p.status === 'archived' ? chalk.gray : chalk.yellow;\n console.log(\n ` ${chalk.bold(p.name)} ${chalk.dim(`(${p.slug})`)} ${statusColor(p.status)} v${p.version} ${chalk.dim(`${p.skills?.length ?? 0} skills, ${p.defined_scopes?.length ?? 0} scopes`)}`,\n );\n }\n console.log();\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Show ──────────────────────────────────────────────────────────────────\n\nexport async function integrationShowCommand(slug: string): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching integration…', isSilent: json }).start();\n\n try {\n // List all and find by slug\n const all = await api.get<IntegrationDetail[]>('/integrations/installs');\n const integration = all.find((p) => p.slug === slug);\n\n if (!integration) {\n spinner.stop();\n error(`Integration \"${slug}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Fetch effective scopes\n const scopes = await api.get<Array<{\n id: string;\n name: string;\n effective_min_role: string;\n is_overridden: boolean;\n can_grant: boolean;\n }>>(`/integrations/installs/${integration.id}/scopes`);\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ integration, scopes });\n return;\n }\n\n console.log(chalk.bold(`\\n${integration.name}`), chalk.dim(`(${integration.slug})`));\n if (integration.description) console.log(chalk.dim(integration.description));\n console.log();\n console.log(` Status: ${integration.status} v${integration.version}`);\n console.log(` Category: ${integration.category}`);\n console.log(` Toolkits: ${integration.required_toolkits.join(', ') || 'none'}`);\n console.log(` Skills: ${integration.skills?.length ?? 0}`);\n\n if (scopes.length > 0) {\n console.log(chalk.bold('\\n Permission Scopes:\\n'));\n for (const s of scopes) {\n const roleColor = s.can_grant ? chalk.green : chalk.red;\n const overrideTag = s.is_overridden ? chalk.cyan(' [team override]') : '';\n console.log(\n ` ${chalk.bold(s.id)} ${s.name} min: ${roleColor(s.effective_min_role)}${overrideTag} ${s.can_grant ? chalk.green('✓ grantable') : chalk.red('✗ needs approval')}`,\n );\n }\n }\n console.log();\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Install ───────────────────────────────────────────────────────────────\n\nexport async function integrationInstallCommand(\n slug: string,\n options: { agent: string; scopes?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Installing integration…', isSilent: json }).start();\n\n try {\n // Resolve integration ID from slug\n const all = await api.get<IntegrationDetail[]>('/integrations/installs');\n const integration = all.find((p) => p.slug === slug);\n if (!integration) {\n spinner.stop();\n error(`Integration \"${slug}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n // Resolve agent ID from code name\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const agent = agents.find((a) => a.code_name === options.agent);\n if (!agent) {\n spinner.stop();\n error(`Agent \"${options.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n const scopes = options.scopes?.split(',').map((s) => s.trim()).filter(Boolean) ?? [];\n\n const result = await api.post<AgentIntegrationRow>('/integrations/installs/install', {\n agent_id: agent.agent_id,\n plugin_id: integration.id,\n scopes,\n });\n\n spinner.stop();\n\n if (json) {\n jsonOutput({ agent_integration: result });\n return;\n }\n\n success(`Installed \"${integration.name}\" on agent \"${options.agent}\"`);\n if (scopes.length) {\n info(`Granted scopes: ${scopes.join(', ')}`);\n }\n } catch (err) {\n spinner.stop();\n if (err instanceof ApiError && err.status === 403 && err.body['needs_approval']) {\n const needsApproval = err.body['needs_approval'] as string[];\n error('Some scopes exceed your role ceiling:');\n for (const s of needsApproval) {\n console.log(chalk.yellow(` - ${s}`));\n }\n info('To request elevated scopes, use the web dashboard or contact your team admin.');\n process.exitCode = 1;\n return;\n }\n handleError(err);\n }\n}\n\n// ── Uninstall ─────────────────────────────────────────────────────────────\n\nexport async function integrationUninstallCommand(\n slug: string,\n options: { agent: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Uninstalling integration…', isSilent: json }).start();\n\n try {\n const all = await api.get<IntegrationDetail[]>('/integrations/installs');\n const integration = all.find((p) => p.slug === slug);\n if (!integration) { spinner.stop(); error(`Integration \"${slug}\" not found.`); process.exitCode = 1; return; }\n\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const agent = agents.find((a) => a.code_name === options.agent);\n if (!agent) { spinner.stop(); error(`Agent \"${options.agent}\" not found.`); process.exitCode = 1; return; }\n\n await api.post('/integrations/installs/uninstall', {\n agent_id: agent.agent_id,\n plugin_id: integration.id,\n });\n spinner.stop();\n success(`Uninstalled \"${integration.name}\" from agent \"${options.agent}\"`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Scope Requests ────────────────────────────────────────────────────────\n\nexport async function integrationRequestsCommand(): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Fetching scope requests…', isSilent: json }).start();\n\n try {\n const requests = await api.get<ScopeRequest[]>('/integrations/installs/scope-requests');\n spinner.stop();\n\n if (json) {\n jsonOutput({ requests });\n return;\n }\n\n if (!requests.length) {\n info('No pending scope requests.');\n return;\n }\n\n console.log(chalk.bold('\\nPending Scope Requests:\\n'));\n for (const r of requests) {\n console.log(` ${chalk.bold(r.id)} scopes: ${r.requested_scopes.join(', ')}`);\n if (r.reason) console.log(` reason: ${chalk.dim(r.reason)}`);\n console.log(` status: ${r.status} requested: ${r.created_at}`);\n console.log();\n }\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Approve ───────────────────────────────────────────────────────────────\n\nexport async function integrationApproveCommand(\n requestId: string,\n options: { notes?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Approving request…', isSilent: json }).start();\n\n try {\n const result = await api.put(`/integrations/installs/scope-requests/${requestId}`, {\n status: 'approved',\n review_notes: options.notes,\n });\n spinner.stop();\n\n if (json) {\n jsonOutput(result);\n return;\n }\n\n success(`Scope request ${requestId} approved. Scopes have been granted.`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Deny ──────────────────────────────────────────────────────────────────\n\nexport async function integrationDenyCommand(\n requestId: string,\n options: { reason?: string },\n): Promise<void> {\n const json = isJsonMode();\n const spinner = ora({ text: 'Denying request…', isSilent: json }).start();\n\n try {\n const result = await api.put(`/integrations/installs/scope-requests/${requestId}`, {\n status: 'denied',\n review_notes: options.reason,\n });\n spinner.stop();\n\n if (json) {\n jsonOutput(result);\n return;\n }\n\n success(`Scope request ${requestId} denied.`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Enrol ─────────────────────────────────────────────────────────────────\n//\n// ENG-4962: wraps POST /integrations/ for API-key onboarding so adding a\n// new integration is one command instead of raw SQL. The endpoint runs\n// the ENG-4953 fail-closed encryption gate, so a credential supplied here\n// is encrypted before it lands in organization_integrations /\n// team_integrations / agent_integrations.\n//\n// OAuth integrations follow a different path (callback-driven); this\n// command intentionally only covers api_key / webhook auth types where\n// the secret is known at enrolment time.\n\ninterface EnrolledIntegrationRow {\n id: string;\n definition_id: string;\n status: string;\n}\n\ninterface EnrolOptions {\n def: string;\n scope: 'org' | 'team' | 'agent' | 'organization';\n apiKey?: string;\n accessToken?: string;\n webhookSecret?: string;\n displayName?: string;\n agent?: string;\n authType?: 'api_key' | 'oauth2' | 'webhook';\n}\n\nexport async function integrationEnrolCommand(options: EnrolOptions): Promise<void> {\n const json = isJsonMode();\n\n // Normalise scope: `org` is the runtime-scope vocabulary; the API\n // accepts the historical `organization` form. Both map to the same row.\n const apiScope = options.scope === 'org' ? 'organization' : options.scope;\n if (!['organization', 'team', 'agent'].includes(apiScope)) {\n error(`Invalid scope \"${options.scope}\". Use org, team, or agent.`);\n process.exitCode = 1;\n return;\n }\n\n // Build the credentials object from the secret-bearing flags. The\n // endpoint accepts {access_token} (OAuth-style) and {api_key} as\n // alternative bearer fields — exactly one secret flag should be set.\n const secrets: Array<[string, string]> = [];\n if (options.apiKey) secrets.push(['api_key', options.apiKey]);\n if (options.accessToken) secrets.push(['access_token', options.accessToken]);\n if (options.webhookSecret) secrets.push(['webhook_secret', options.webhookSecret]);\n if (secrets.length === 0) {\n error('One of --api-key, --access-token, or --webhook-secret is required.');\n process.exitCode = 1;\n return;\n }\n if (secrets.length > 1) {\n error('Only one of --api-key, --access-token, --webhook-secret may be set.');\n process.exitCode = 1;\n return;\n }\n const [secretKey, secretValue] = secrets[0]!;\n const credentials: Record<string, string> = { [secretKey]: secretValue };\n\n const authType = options.authType\n ?? (options.webhookSecret ? 'webhook'\n : options.apiKey ? 'api_key'\n : 'oauth2');\n\n const spinner = ora({ text: `Enrolling ${options.def} at ${apiScope} scope…`, isSilent: json }).start();\n\n try {\n // For agent scope, resolve the agent's UUID from its code_name. Team\n // scope auto-resolves from the team header; org scope derives from\n // the team's organization_id server-side (ENG-4962 endpoint tweak).\n let agentId: string | undefined;\n if (apiScope === 'agent') {\n if (!options.agent) {\n spinner.stop();\n error('--agent <code-name> is required for agent scope.');\n process.exitCode = 1;\n return;\n }\n const agents = await api.get<Array<{ agent_id: string; code_name: string }>>('/agents');\n const found = agents.find((a) => a.code_name === options.agent);\n if (!found) {\n spinner.stop();\n error(`Agent \"${options.agent}\" not found.`);\n process.exitCode = 1;\n return;\n }\n agentId = found.agent_id;\n }\n\n // Resolve a display_name from the definition if the caller didn't\n // supply one. Saves the user from having to type \"Resend\" twice.\n let displayName = options.displayName;\n if (!displayName) {\n const defs = await api.get<IntegrationDetail[]>('/integrations/installs');\n const def = defs.find((d) => d.slug === options.def);\n displayName = def?.name ?? options.def;\n }\n\n const result = await api.post<{ integration: EnrolledIntegrationRow }>('/integrations', {\n scope: apiScope,\n definition_id: options.def,\n display_name: displayName,\n auth_type: authType,\n credentials,\n config: {},\n ...(agentId ? { agent_id: agentId } : {}),\n });\n\n spinner.stop();\n\n const row = result.integration;\n if (json) {\n jsonOutput({ integration: row });\n return;\n }\n\n success(`Enrolled \"${displayName}\" (${options.def}) at ${apiScope} scope`);\n info(`Integration ID: ${row.id}`);\n info(`Status: ${row.status}`);\n } catch (err) {\n spinner.stop();\n handleError(err);\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────\n\nfunction handleError(err: unknown): void {\n if (err instanceof ApiError) {\n error(`API error (${err.status}): ${err.message}`);\n } else {\n error((err as Error).message);\n }\n process.exitCode = 1;\n}\n"],"mappings":"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","names":["join","homedir","chalk","ora","ora","chalk","chalk","ora","chalk","ora","chalk","ora","join","printDiagnostics","chalk","join","readdirSync","statSync","ora","chalk","ora","channels","chalk","ora","chalk","ora","checkbox","confirm","input","join","ora","agent","channels","chalk","checkbox","input","confirm","chalk","ora","confirm","ora","agent","channels","chalk","confirm","chalk","ora","select","input","writeFileSync","mkdirSync","join","chalk","select","input","ora","join","mkdirSync","writeFileSync","chalk","ora","writeFileSync","mkdirSync","join","printDiagnostics","chalk","join","ora","mkdirSync","writeFileSync","chalk","ora","existsSync","readFileSync","writeFileSync","dirname","join","fileURLToPath","existsSync","mkdirSync","readFileSync","writeFileSync","join","existsSync","renameSync","homedir","join","existsSync","mkdirSync","readdirSync","readFileSync","renameSync","unlinkSync","writeFileSync","join","join","existsSync","mkdirSync","readFileSync","writeFileSync","renameSync","unlinkSync","readdirSync","chmodSync","copyFileSync","existsSync","mkdirSync","readdirSync","readFileSync","renameSync","rmdirSync","unlinkSync","writeFileSync","homedir","dirname","join","join","homedir","mkdirSync","dirname","existsSync","readFileSync","copyFileSync","chmodSync","asPlainObject","safeParseJson","writeFileSync","renameSync","unlinkSync","readdirSync","rmdirSync","input","chalk","ora","host","writeFileSync","join","resolve","manifest","readFileSync","dirname","fileURLToPath","existsSync","chalk","ora","createHash","join","chalk","ora","agent","chalk","ora","ora","chalk","spinner","spawn","chalk","host","chalk","spawn","resolve","existsSync","readFileSync","homedir","join","join","homedir","existsSync","readFileSync","input","agent","chalk","JSON5","readFileSync","existsSync","join","join","existsSync","readFileSync","JSON5","filtered","chalk","chalk","ora","chalk","ora","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","homedir","chalk","ora","homedir","join","existsSync","readFileSync","writeFileSync","lines","chalk","ora","dirname","mkdirSync","channels","chalk","ora","resolveAgentId","priorityLabel","chalk","ora","spawn","resolve","spawn","agent","agent","existsSync","realpathSync","chalk","ora","host","parse","realpathSync","existsSync","ora","chalk","homedir","join","readdirSync","readFileSync","statSync","join","homedir","join","readdirSync","readFileSync","statSync","homedir","join","homedir","join","readdirSync","readFileSync","statSync","join","agent","statSync","readFileSync","readdirSync","join","join","homedir","chalk","ora","ora","chalk","integration","agent","cliVersion","join","homedir"]}
|