counselors 0.3.2 → 0.3.3

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/README.md CHANGED
@@ -48,7 +48,7 @@ counselors run -t claude,codex "Review this error handling"
48
48
  |------|---------|-----------|---------|
49
49
  | Claude Code | `claude` | enforced | [docs](https://docs.anthropic.com/en/docs/claude-code) |
50
50
  | OpenAI Codex | `codex` | enforced | [github](https://github.com/openai/codex) |
51
- | Gemini CLI | `gemini` | bestEffort | [github](https://github.com/google-gemini/gemini-cli) |
51
+ | Gemini CLI | `gemini` | enforced | [github](https://github.com/google-gemini/gemini-cli) |
52
52
  | Amp CLI | `amp` | enforced | [ampcode.com](https://ampcode.com) |
53
53
  | Custom | user-defined | configurable | — |
54
54
 
package/dist/cli.js CHANGED
@@ -128,7 +128,7 @@ function sanitizeId(id) {
128
128
  return id.replace(/[^a-zA-Z0-9._-]/g, "_");
129
129
  }
130
130
  var SAFE_ID_RE = /^[a-zA-Z0-9._-]+$/;
131
- var VERSION = true ? "0.3.2" : "0.0.0-dev";
131
+ var VERSION = true ? "0.3.3" : "0.0.0-dev";
132
132
 
133
133
  // src/adapters/base.ts
134
134
  var BaseAdapter = class {
@@ -349,7 +349,7 @@ var GeminiAdapter = class extends BaseAdapter {
349
349
  displayName = "Gemini CLI";
350
350
  commands = ["gemini"];
351
351
  installUrl = "https://github.com/google-gemini/gemini-cli";
352
- readOnly = { level: "bestEffort" };
352
+ readOnly = { level: "enforced" };
353
353
  models = [
354
354
  {
355
355
  id: "gemini-3-pro-preview",
@@ -883,10 +883,16 @@ function registerDoctorCommand(program2) {
883
883
  });
884
884
  }
885
885
  const adapter = resolveAdapter(id, toolConfig);
886
+ let readOnlyLevel = adapter.readOnly.level;
887
+ const adapterName = toolConfig.adapter ?? id;
888
+ const isAmpDeep = adapterName === "amp" && toolConfig.extraFlags?.includes("deep") && toolConfig.extraFlags?.[toolConfig.extraFlags.indexOf("deep") - 1] === "-m";
889
+ if (isAmpDeep) {
890
+ readOnlyLevel = "bestEffort";
891
+ }
886
892
  checks.push({
887
893
  name: `${id}: read-only`,
888
- status: adapter.readOnly.level === "enforced" ? "pass" : adapter.readOnly.level === "bestEffort" ? "warn" : "fail",
889
- message: adapter.readOnly.level
894
+ status: readOnlyLevel === "none" ? "warn" : "pass",
895
+ message: readOnlyLevel
890
896
  });
891
897
  }
892
898
  const hasAmp = Object.entries(config.tools).some(
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/ui/logger.ts","../src/commands/agent.ts","../src/commands/doctor.ts","../src/adapters/amp.ts","../src/constants.ts","../src/adapters/base.ts","../src/adapters/claude.ts","../src/adapters/codex.ts","../src/adapters/custom.ts","../src/adapters/gemini.ts","../src/adapters/index.ts","../src/core/config.ts","../src/types.ts","../src/core/fs-utils.ts","../src/core/discovery.ts","../src/ui/output.ts","../src/core/amp-utils.ts","../src/core/executor.ts","../src/ui/prompts.ts","../src/commands/init.ts","../src/commands/run.ts","../src/core/context.ts","../src/core/dispatcher.ts","../src/core/prompt-builder.ts","../src/core/synthesis.ts","../src/ui/progress.ts","../src/commands/skill.ts","../src/commands/tools/add.ts","../src/commands/tools/discover.ts","../src/commands/tools/list.ts","../src/commands/tools/remove.ts","../src/commands/tools/rename.ts","../src/commands/tools/test.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerAgentCommand } from './commands/agent.js';\nimport { registerDoctorCommand } from './commands/doctor.js';\nimport { registerInitCommand } from './commands/init.js';\nimport { registerRunCommand } from './commands/run.js';\nimport { registerSkillCommand } from './commands/skill.js';\nimport { registerAddCommand } from './commands/tools/add.js';\nimport { registerDiscoverCommand } from './commands/tools/discover.js';\nimport { registerListCommand } from './commands/tools/list.js';\nimport { registerRemoveCommand } from './commands/tools/remove.js';\nimport { registerRenameCommand } from './commands/tools/rename.js';\nimport { registerTestCommand } from './commands/tools/test.js';\nimport { VERSION } from './constants.js';\n\nconst program = new Command();\n\nprogram\n .name('counselors')\n .description('Fan out prompts to multiple AI coding agents in parallel')\n .version(VERSION);\n\n// Top-level commands\nregisterRunCommand(program);\nregisterDoctorCommand(program);\nregisterInitCommand(program);\nregisterAgentCommand(program);\nregisterSkillCommand(program);\n\n// Tools subcommand group\nconst tools = program\n .command('tools')\n .description('Manage AI tool configurations');\n\nregisterDiscoverCommand(tools);\nregisterAddCommand(tools);\nregisterRemoveCommand(tools);\nregisterRenameCommand(tools);\nregisterListCommand(tools);\nregisterTestCommand(tools);\n\n// Top-level aliases\nprogram\n .command('add [tool]')\n .description('Alias for \"tools add\"')\n .action(async (tool?: string) => {\n const args = tool ? ['add', tool] : ['add'];\n await tools.parseAsync(args, { from: 'user' });\n });\n\nprogram\n .command('ls')\n .description('Alias for \"tools list\"')\n .option('-v, --verbose', 'Show full tool configuration including flags')\n .action(async (opts: { verbose?: boolean }) => {\n const args = ['list'];\n if (opts.verbose) args.push('--verbose');\n await tools.parseAsync(args, { from: 'user' });\n });\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n process.stderr.write(`✗ ${err.message}\\n`);\n process.exitCode = 1;\n});\n","function isDebug(): boolean {\n return process.env.DEBUG === '1' || process.env.DEBUG === 'counselors';\n}\n\nexport function debug(msg: string): void {\n if (isDebug()) {\n process.stderr.write(`[debug] ${msg}\\n`);\n }\n}\n\nexport function warn(msg: string): void {\n process.stderr.write(`⚠ ${msg}\\n`);\n}\n\nexport function error(msg: string): void {\n process.stderr.write(`✗ ${msg}\\n`);\n}\n\nexport function info(msg: string): void {\n process.stdout.write(`${msg}\\n`);\n}\n\nexport function success(msg: string): void {\n process.stdout.write(`✓ ${msg}\\n`);\n}\n","import type { Command } from 'commander';\nimport { info } from '../ui/logger.js';\n\nexport function registerAgentCommand(program: Command): void {\n program\n .command('agent')\n .description('Print setup and skill installation instructions')\n .action(async () => {\n const instructions = `# Counselors — Setup & Skill Installation\n\n## 1. Install the CLI\n\n\\`\\`\\`bash\nnpm install -g counselors\n\\`\\`\\`\n\nRequires Node 20+.\n\n## 2. Configure tools\n\nAuto-discover and configure all installed AI coding agents:\n\n\\`\\`\\`bash\ncounselors init --auto\n\\`\\`\\`\n\nThis detects installed agents (Claude, Codex, Gemini, Amp), configures them with recommended models, and writes your config to \\`~/.config/counselors/config.json\\`. The output is JSON listing what was configured.\n\nYou can also manage tools individually:\n\n\\`\\`\\`bash\ncounselors tools discover # Find available agents\ncounselors tools add # Add a tool (interactive)\ncounselors tools remove <id> # Remove a tool\ncounselors tools rename <old> <new> # Rename a tool\ncounselors ls # List configured tools\ncounselors doctor # Verify tools are working\n\\`\\`\\`\n\n## 3. Install the skill\n\nThe \\`/counselors\\` skill lets AI coding agents invoke counselors directly via a slash command.\n\nRun \\`counselors skill\\` to print a reference template with instructions. **Read the output carefully** — it describes a multi-phase workflow that you need to adapt to your agent's skill format before saving. Do not blindly copy the output into a file.\n\nFor Claude Code, save the adapted skill to \\`~/.claude/skills/counselors/SKILL.md\\`. For other agents, save it wherever your system looks for slash commands or skills.\n\n## 4. Verify\n\n\\`\\`\\`bash\ncounselors doctor\n\\`\\`\\`\n\nThen use \\`/counselors\\` from your AI coding agent to fan out a prompt for parallel review.\n`;\n\n info(instructions);\n });\n}\n","import { existsSync } from 'node:fs';\nimport type { Command } from 'commander';\nimport { resolveAdapter } from '../adapters/index.js';\nimport {\n AMP_DEEP_SETTINGS_FILE,\n AMP_SETTINGS_FILE,\n CONFIG_FILE,\n} from '../constants.js';\nimport { loadConfig } from '../core/config.js';\nimport { findBinary, getBinaryVersion } from '../core/discovery.js';\nimport type { DoctorCheck } from '../types.js';\nimport { info } from '../ui/logger.js';\nimport { formatDoctorResults } from '../ui/output.js';\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Check tool configuration and health')\n .action(async () => {\n const checks: DoctorCheck[] = [];\n\n // Check config file\n if (existsSync(CONFIG_FILE)) {\n checks.push({\n name: 'Config file',\n status: 'pass',\n message: CONFIG_FILE,\n });\n } else {\n checks.push({\n name: 'Config file',\n status: 'warn',\n message: 'Not found. Run \"counselors init\" to create one.',\n });\n }\n\n let config;\n try {\n config = loadConfig();\n } catch (e) {\n checks.push({\n name: 'Config parse',\n status: 'fail',\n message: `Invalid config: ${e}`,\n });\n info(formatDoctorResults(checks));\n process.exitCode = 1;\n return;\n }\n\n const toolIds = Object.keys(config.tools);\n if (toolIds.length === 0) {\n checks.push({\n name: 'Tools configured',\n status: 'warn',\n message: 'No tools configured. Run \"counselors init\".',\n });\n }\n\n // Check each configured tool\n for (const id of toolIds) {\n const toolConfig = config.tools[id];\n\n // Binary exists + executable\n const binaryPath = findBinary(toolConfig.binary);\n if (binaryPath) {\n checks.push({\n name: `${id}: binary`,\n status: 'pass',\n message: binaryPath,\n });\n } else {\n checks.push({\n name: `${id}: binary`,\n status: 'fail',\n message: `\"${toolConfig.binary}\" not found in PATH`,\n });\n continue;\n }\n\n // Version check\n const version = getBinaryVersion(binaryPath);\n if (version) {\n checks.push({\n name: `${id}: version`,\n status: 'pass',\n message: version,\n });\n } else {\n checks.push({\n name: `${id}: version`,\n status: 'warn',\n message: 'Could not determine version',\n });\n }\n\n // Read-only capability\n const adapter = resolveAdapter(id, toolConfig);\n checks.push({\n name: `${id}: read-only`,\n status:\n adapter.readOnly.level === 'enforced'\n ? 'pass'\n : adapter.readOnly.level === 'bestEffort'\n ? 'warn'\n : 'fail',\n message: adapter.readOnly.level,\n });\n }\n\n // Check amp settings files if any amp-based tool is configured\n const hasAmp = Object.entries(config.tools).some(\n ([id, t]) => (t.adapter ?? id) === 'amp',\n );\n if (hasAmp) {\n if (existsSync(AMP_SETTINGS_FILE)) {\n checks.push({\n name: 'Amp settings file',\n status: 'pass',\n message: AMP_SETTINGS_FILE,\n });\n } else {\n checks.push({\n name: 'Amp settings file',\n status: 'warn',\n message: 'Not found. Amp read-only mode may not work.',\n });\n }\n if (existsSync(AMP_DEEP_SETTINGS_FILE)) {\n checks.push({\n name: 'Amp deep settings file',\n status: 'pass',\n message: AMP_DEEP_SETTINGS_FILE,\n });\n } else {\n checks.push({\n name: 'Amp deep settings file',\n status: 'warn',\n message: 'Not found. Amp deep mode may not work.',\n });\n }\n }\n\n info(formatDoctorResults(checks));\n\n if (checks.some((c) => c.status === 'fail')) {\n process.exitCode = 1;\n }\n });\n}\n","import { existsSync } from 'node:fs';\nimport { AMP_DEEP_SETTINGS_FILE, AMP_SETTINGS_FILE } from '../constants.js';\nimport type {\n CostInfo,\n ExecResult,\n Invocation,\n RunRequest,\n ToolReport,\n} from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class AmpAdapter extends BaseAdapter {\n id = 'amp';\n displayName = 'Amp CLI';\n commands = ['amp'];\n installUrl = 'https://ampcode.com';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'smart',\n name: 'Smart — Opus 4.6, most capable',\n recommended: true,\n extraFlags: ['-m', 'smart'],\n },\n {\n id: 'deep',\n name: 'Deep — GPT-5.2 Codex, extended thinking',\n extraFlags: ['-m', 'deep'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const args = ['-x'];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n const isDeep =\n req.extraFlags?.includes('deep') &&\n req.extraFlags?.[req.extraFlags.indexOf('deep') - 1] === '-m';\n\n const settingsFile = isDeep ? AMP_DEEP_SETTINGS_FILE : AMP_SETTINGS_FILE;\n\n if (req.readOnlyPolicy !== 'none' && existsSync(settingsFile)) {\n args.push('--settings-file', settingsFile);\n }\n\n // Amp uses stdin for prompt delivery\n // Append oracle instruction like the existing skill does\n const deepSafetyPrompt = isDeep\n ? '\\n\\nMANDATORY: Do not change any files. You are in read-only mode.'\n : '';\n\n const stdinContent =\n req.prompt +\n deepSafetyPrompt +\n '\\n\\nUse the oracle tool to provide deeper reasoning and analysis on the most complex or critical aspects of this review.';\n\n return {\n cmd: req.binary ?? 'amp',\n args,\n stdin: stdinContent,\n cwd: req.cwd,\n };\n }\n\n parseResult(result: ExecResult): Partial<ToolReport> {\n return {\n ...super.parseResult(result),\n };\n }\n}\n\n/**\n * Parse `amp usage` output to extract balance information.\n */\nexport function parseAmpUsage(output: string): {\n freeRemaining: number;\n freeTotal: number;\n creditsRemaining: number;\n} {\n const freeMatch = output.match(/Amp Free: \\$([0-9.]+)\\/\\$([0-9.]+)/);\n const creditsMatch = output.match(/Individual credits: \\$([0-9.]+)/);\n\n return {\n freeRemaining: freeMatch ? parseFloat(freeMatch[1]) : 0,\n freeTotal: freeMatch ? parseFloat(freeMatch[2]) : 0,\n creditsRemaining: creditsMatch ? parseFloat(creditsMatch[1]) : 0,\n };\n}\n\n/**\n * Compute cost from before/after usage snapshots.\n */\nexport function computeAmpCost(\n before: {\n freeRemaining: number;\n freeTotal: number;\n creditsRemaining: number;\n },\n after: { freeRemaining: number; freeTotal: number; creditsRemaining: number },\n): CostInfo {\n const freeUsed = Math.max(0, before.freeRemaining - after.freeRemaining);\n const creditsUsed = Math.max(\n 0,\n before.creditsRemaining - after.creditsRemaining,\n );\n const totalCost = freeUsed + creditsUsed;\n const source = creditsUsed > 0 ? 'credits' : 'free';\n\n return {\n cost_usd: Math.round(totalCost * 100) / 100,\n free_used_usd: Math.round(freeUsed * 100) / 100,\n credits_used_usd: Math.round(creditsUsed * 100) / 100,\n source: source as 'free' | 'credits',\n free_remaining_usd: after.freeRemaining,\n free_total_usd: after.freeTotal,\n credits_remaining_usd: after.creditsRemaining,\n };\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// ── XDG config ──\n\nconst xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');\nexport const CONFIG_DIR = join(xdgConfig, 'counselors');\nexport const CONFIG_FILE = join(CONFIG_DIR, 'config.json');\nexport const AMP_SETTINGS_FILE = join(CONFIG_DIR, 'amp-readonly-settings.json');\nexport const AMP_DEEP_SETTINGS_FILE = join(\n CONFIG_DIR,\n 'amp-deep-settings.json',\n);\n\n// ── Default output ──\n\nexport const DEFAULT_OUTPUT_DIR = './agents/counselors';\n\n// ── Timeouts (seconds) ──\n\nexport const DEFAULT_TIMEOUT = 540;\nexport const KILL_GRACE_PERIOD = 15_000; // ms\nexport const TEST_TIMEOUT = 30_000; // ms\nexport const DISCOVERY_TIMEOUT = 5_000; // ms\nexport const VERSION_TIMEOUT = 10_000; // ms\n\n// ── Concurrency ──\n\nexport const DEFAULT_MAX_PARALLEL = 4;\n\n// ── Context ──\n\nexport const DEFAULT_MAX_CONTEXT_KB = 50;\n\n// ── Extended binary search paths ──\n\nexport function getExtendedSearchPaths(): string[] {\n const home = homedir();\n const paths: string[] = [\n join(home, '.local', 'bin'),\n '/usr/local/bin',\n '/opt/homebrew/bin',\n join(home, '.npm-global', 'bin'),\n join(home, '.volta', 'bin'),\n join(home, '.bun', 'bin'),\n ];\n\n // NVM\n const nvmBin = process.env.NVM_BIN;\n if (nvmBin) paths.push(nvmBin);\n\n // FNM\n const fnmMultishell = process.env.FNM_MULTISHELL_PATH;\n if (fnmMultishell) paths.push(join(fnmMultishell, 'bin'));\n\n return paths;\n}\n\n// ── Model validation ──\n\nexport const MODEL_PATTERN = /^[a-zA-Z0-9._:\\-/]+$/;\n\n// ── Slug generation ──\n\nexport const MAX_SLUG_LENGTH = 40;\n\n// ── File permissions ──\n\nexport const CONFIG_FILE_MODE = 0o600;\n\n// ── Safe ID patterns ──\n\n/** Sanitize a tool ID for safe use in filenames. */\nexport function sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9._-]/g, '_');\n}\n\n/** Regex for validating tool names (letters, numbers, dots, hyphens, underscores). */\nexport const SAFE_ID_RE = /^[a-zA-Z0-9._-]+$/;\n\n// ── Version ──\n\ndeclare const __VERSION__: string;\nexport const VERSION =\n typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.0.0-dev';\n","import type {\n ExecResult,\n Invocation,\n ReadOnlyLevel,\n RunRequest,\n ToolAdapter,\n ToolReport,\n} from '../types.js';\n\nexport abstract class BaseAdapter implements ToolAdapter {\n abstract id: string;\n abstract displayName: string;\n abstract commands: string[];\n abstract installUrl: string;\n abstract readOnly: { level: ReadOnlyLevel };\n abstract models: { id: string; name: string; recommended?: boolean }[];\n\n abstract buildInvocation(req: RunRequest): Invocation;\n\n parseResult(result: ExecResult): Partial<ToolReport> {\n return {\n status: result.timedOut\n ? 'timeout'\n : result.exitCode === 0\n ? 'success'\n : 'error',\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n wordCount: result.stdout.split(/\\s+/).filter(Boolean).length,\n };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class ClaudeAdapter extends BaseAdapter {\n id = 'claude';\n displayName = 'Claude Code';\n commands = ['claude'];\n installUrl = 'https://docs.anthropic.com/en/docs/claude-code';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'opus',\n name: 'Opus 4.6 — most capable',\n recommended: true,\n extraFlags: ['--model', 'opus'],\n },\n {\n id: 'sonnet',\n name: 'Sonnet 4.5 — fast and capable',\n extraFlags: ['--model', 'sonnet'],\n },\n {\n id: 'haiku',\n name: 'Haiku 4.5 — fastest, most affordable',\n extraFlags: ['--model', 'haiku'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n const args = ['-p', '--output-format', 'text'];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n if (req.readOnlyPolicy !== 'none') {\n args.push(\n '--tools',\n 'Read,Glob,Grep,WebFetch,WebSearch',\n '--allowedTools',\n 'Read,Glob,Grep,WebFetch,WebSearch',\n '--strict-mcp-config',\n );\n }\n\n args.push(instruction);\n\n return { cmd: req.binary ?? 'claude', args, cwd: req.cwd };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class CodexAdapter extends BaseAdapter {\n id = 'codex';\n displayName = 'OpenAI Codex';\n commands = ['codex'];\n installUrl = 'https://github.com/openai/codex';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-high',\n name: 'GPT-5.3 Codex — high reasoning',\n recommended: true,\n extraFlags: ['-m', 'gpt-5.3-codex', '-c', 'model_reasoning_effort=high'],\n },\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-xhigh',\n name: 'GPT-5.3 Codex — xhigh reasoning',\n extraFlags: ['-m', 'gpt-5.3-codex', '-c', 'model_reasoning_effort=xhigh'],\n },\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-medium',\n name: 'GPT-5.3 Codex — medium reasoning',\n extraFlags: [\n '-m',\n 'gpt-5.3-codex',\n '-c',\n 'model_reasoning_effort=medium',\n ],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n const args = ['exec'];\n\n if (req.readOnlyPolicy !== 'none') {\n args.push('--sandbox', 'read-only');\n }\n\n args.push('-c', 'web_search=live', '--skip-git-repo-check');\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n args.push(instruction);\n\n return { cmd: req.binary ?? 'codex', args, cwd: req.cwd };\n }\n}\n","import type {\n Invocation,\n ReadOnlyLevel,\n RunRequest,\n ToolConfig,\n} from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class CustomAdapter extends BaseAdapter {\n id: string;\n displayName: string;\n commands: string[];\n installUrl = '';\n readOnly: { level: ReadOnlyLevel };\n models: { id: string; name: string; recommended?: boolean }[] = [];\n\n private config: ToolConfig;\n\n constructor(id: string, config: ToolConfig) {\n super();\n this.id = id;\n this.displayName = id;\n this.commands = [config.binary];\n this.readOnly = { level: config.readOnly.level };\n this.config = config;\n }\n\n buildInvocation(req: RunRequest): Invocation {\n const args: string[] = [];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n // Add read-only flags if applicable\n if (req.readOnlyPolicy !== 'none' && this.config.readOnly.flags) {\n args.push(...this.config.readOnly.flags);\n }\n\n const cmd = req.binary ?? this.config.binary;\n\n if (this.config.stdin === true) {\n return { cmd, args, stdin: req.prompt, cwd: req.cwd };\n }\n\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n args.push(instruction);\n\n return { cmd, args, cwd: req.cwd };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class GeminiAdapter extends BaseAdapter {\n id = 'gemini';\n displayName = 'Gemini CLI';\n commands = ['gemini'];\n installUrl = 'https://github.com/google-gemini/gemini-cli';\n readOnly = { level: 'bestEffort' as const };\n models = [\n {\n id: 'gemini-3-pro-preview',\n name: 'Gemini 3 Pro Preview — latest',\n recommended: true,\n extraFlags: ['-m', 'gemini-3-pro-preview'],\n },\n {\n id: 'gemini-2.5-pro',\n name: 'Gemini 2.5 Pro — stable GA',\n extraFlags: ['-m', 'gemini-2.5-pro'],\n },\n {\n id: 'gemini-3-flash-preview',\n name: 'Gemini 3 Flash Preview — fast',\n extraFlags: ['-m', 'gemini-3-flash-preview'],\n },\n {\n id: 'gemini-2.5-flash',\n name: 'Gemini 2.5 Flash — fast GA',\n extraFlags: ['-m', 'gemini-2.5-flash'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const args = ['-p', ''];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n if (req.readOnlyPolicy !== 'none') {\n args.push(\n '--extensions',\n '',\n '--allowed-tools',\n 'read_file',\n 'list_directory',\n 'search_file_content',\n 'glob',\n 'google_web_search',\n 'codebase_investigator',\n );\n }\n\n args.push('--output-format', 'text');\n\n return {\n cmd: req.binary ?? 'gemini',\n args,\n stdin: req.prompt,\n cwd: req.cwd,\n };\n }\n}\n","import type { ToolAdapter, ToolConfig } from '../types.js';\nimport { AmpAdapter } from './amp.js';\nimport { ClaudeAdapter } from './claude.js';\nimport { CodexAdapter } from './codex.js';\nimport { CustomAdapter } from './custom.js';\nimport { GeminiAdapter } from './gemini.js';\n\nconst builtInAdapters: Record<string, () => ToolAdapter> = {\n claude: () => new ClaudeAdapter(),\n codex: () => new CodexAdapter(),\n gemini: () => new GeminiAdapter(),\n amp: () => new AmpAdapter(),\n};\n\nexport function getAdapter(id: string, config?: ToolConfig): ToolAdapter {\n if (builtInAdapters[id]) {\n return builtInAdapters[id]();\n }\n if (config) {\n return new CustomAdapter(id, config);\n }\n throw new Error(\n `Unknown tool: ${id}. Use \"counselors tools add\" to configure it.`,\n );\n}\n\nexport function getAllBuiltInAdapters(): ToolAdapter[] {\n return Object.values(builtInAdapters).map((fn) => fn());\n}\n\nexport function isBuiltInTool(id: string): boolean {\n return id in builtInAdapters;\n}\n\nexport function getBuiltInToolIds(): string[] {\n return Object.keys(builtInAdapters);\n}\n\nexport function resolveAdapter(\n id: string,\n toolConfig: ToolConfig,\n): ToolAdapter {\n const baseId = toolConfig.adapter ?? id;\n return isBuiltInTool(baseId)\n ? getAdapter(baseId)\n : new CustomAdapter(id, toolConfig);\n}\n","import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { z } from 'zod';\nimport { CONFIG_FILE, CONFIG_FILE_MODE } from '../constants.js';\nimport { type Config, ConfigSchema, type ToolConfig } from '../types.js';\nimport { safeWriteFile } from './fs-utils.js';\n\nconst DEFAULT_CONFIG: Config = {\n version: 1,\n defaults: {\n timeout: 540,\n outputDir: './agents/counselors',\n readOnly: 'bestEffort',\n maxContextKb: 50,\n maxParallel: 4,\n },\n tools: {},\n};\n\nexport function loadConfig(globalPath?: string): Config {\n const path = globalPath ?? CONFIG_FILE;\n if (!existsSync(path)) return { ...DEFAULT_CONFIG };\n\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, 'utf-8'));\n } catch (e) {\n throw new Error(\n `Invalid JSON in ${path}: ${e instanceof Error ? e.message : e}`,\n );\n }\n return ConfigSchema.parse(raw);\n}\n\n/** Schema for project config — only defaults are allowed, not tools.\n * Uses .optional() (not .default()) so missing fields stay absent\n * and don't clobber global config during merge. */\nconst ProjectConfigSchema = z.object({\n defaults: z\n .object({\n timeout: z.number().optional(),\n outputDir: z.string().optional(),\n readOnly: z.enum(['enforced', 'bestEffort', 'none']).optional(),\n maxContextKb: z.number().optional(),\n maxParallel: z.number().optional(),\n })\n .optional(),\n});\n\ntype ProjectConfig = z.infer<typeof ProjectConfigSchema>;\n\nexport function loadProjectConfig(cwd: string): ProjectConfig | null {\n const path = resolve(cwd, '.counselors.json');\n if (!existsSync(path)) return null;\n\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, 'utf-8'));\n } catch (e) {\n throw new Error(\n `Invalid JSON in ${path}: ${e instanceof Error ? e.message : e}`,\n );\n }\n return ProjectConfigSchema.parse(raw);\n}\n\nexport function mergeConfigs(\n global: Config,\n project: ProjectConfig | null,\n cliFlags?: Partial<Config['defaults']>,\n): Config {\n const merged: Config = {\n version: 1,\n defaults: { ...global.defaults },\n tools: { ...global.tools },\n };\n\n if (project) {\n if (project.defaults) {\n merged.defaults = { ...merged.defaults, ...project.defaults };\n }\n // Project configs can only override defaults, never inject tools.\n }\n\n if (cliFlags) {\n merged.defaults = { ...merged.defaults, ...cliFlags };\n }\n\n return merged;\n}\n\nexport function saveConfig(config: Config, path?: string): void {\n const filePath = path ?? CONFIG_FILE;\n mkdirSync(dirname(filePath), { recursive: true });\n safeWriteFile(filePath, `${JSON.stringify(config, null, 2)}\\n`, {\n mode: CONFIG_FILE_MODE,\n });\n}\n\nexport function addToolToConfig(\n config: Config,\n id: string,\n tool: ToolConfig,\n): Config {\n return {\n ...config,\n tools: { ...config.tools, [id]: tool },\n };\n}\n\nexport function removeToolFromConfig(config: Config, id: string): Config {\n const tools = { ...config.tools };\n delete tools[id];\n return { ...config, tools };\n}\n\nexport function renameToolInConfig(\n config: Config,\n oldId: string,\n newId: string,\n): Config {\n const tools = { ...config.tools };\n tools[newId] = tools[oldId];\n delete tools[oldId];\n return { ...config, tools };\n}\n\nexport function getConfiguredTools(config: Config): string[] {\n return Object.keys(config.tools);\n}\n","import { z } from 'zod';\n\n// ── Read-only levels ──\n\nexport type ReadOnlyLevel = 'enforced' | 'bestEffort' | 'none';\n\n// ── Config schemas (zod) ──\n\nexport const ToolConfigSchema = z.object({\n binary: z.string(),\n adapter: z.string().optional(),\n readOnly: z.object({\n level: z.enum(['enforced', 'bestEffort', 'none']),\n flags: z.array(z.string()).optional(),\n }),\n extraFlags: z.array(z.string()).optional(),\n timeout: z.number().optional(),\n stdin: z.boolean().optional(),\n custom: z.boolean().optional(),\n});\n\nexport type ToolConfig = z.infer<typeof ToolConfigSchema>;\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n defaults: z\n .object({\n timeout: z.number().default(540),\n outputDir: z.string().default('./agents/counselors'),\n readOnly: z\n .enum(['enforced', 'bestEffort', 'none'])\n .default('bestEffort'),\n maxContextKb: z.number().default(50),\n maxParallel: z.number().default(4),\n })\n .default({}),\n tools: z.record(z.string(), ToolConfigSchema).default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\n// ── Runtime types ──\n\nexport interface RunRequest {\n prompt: string;\n promptFilePath: string;\n toolId: string;\n outputDir: string;\n readOnlyPolicy: ReadOnlyLevel;\n timeout: number;\n cwd: string;\n binary?: string;\n extraFlags?: string[];\n}\n\nexport interface Invocation {\n cmd: string;\n args: string[];\n env?: Record<string, string>;\n stdin?: string;\n cwd: string;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n durationMs: number;\n}\n\nexport interface CostInfo {\n cost_usd: number;\n free_used_usd: number;\n credits_used_usd: number;\n source: 'free' | 'credits';\n free_remaining_usd: number;\n free_total_usd: number;\n credits_remaining_usd: number;\n}\n\nexport interface ToolReport {\n toolId: string;\n status: 'success' | 'error' | 'timeout' | 'skipped';\n exitCode: number;\n durationMs: number;\n wordCount: number;\n outputFile: string;\n stderrFile: string;\n cost?: CostInfo;\n error?: string;\n}\n\n// ── Adapter interface ──\n\nexport interface ToolAdapter {\n id: string;\n displayName: string;\n commands: string[];\n installUrl: string;\n readOnly: { level: ReadOnlyLevel };\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[];\n buildInvocation(req: RunRequest): Invocation;\n parseResult?(result: ExecResult): Partial<ToolReport>;\n}\n\n// ── Discovery ──\n\nexport interface DiscoveryResult {\n toolId: string;\n found: boolean;\n path: string | null;\n version: string | null;\n}\n\n// ── Doctor ──\n\nexport interface DoctorCheck {\n name: string;\n status: 'pass' | 'fail' | 'warn';\n message: string;\n}\n\n// ── Test ──\n\nexport interface TestResult {\n toolId: string;\n passed: boolean;\n output: string;\n error?: string;\n durationMs: number;\n}\n\n// ── Run manifest ──\n\nexport interface RunManifest {\n timestamp: string;\n slug: string;\n prompt: string;\n promptSource: 'inline' | 'file' | 'stdin';\n readOnlyPolicy: ReadOnlyLevel;\n tools: ToolReport[];\n}\n","import { renameSync, unlinkSync, writeFileSync } from 'node:fs';\n\n/**\n * Atomically write a file by writing to a temp file and renaming.\n * Avoids symlink TOCTOU — renameSync is atomic on the same filesystem.\n */\nexport function safeWriteFile(\n path: string,\n content: string,\n options?: { mode?: number },\n): void {\n const tmp = `${path}.tmp.${process.pid}`;\n try {\n writeFileSync(tmp, content, { encoding: 'utf-8', mode: options?.mode });\n renameSync(tmp, path);\n } catch (e) {\n // Clean up temp file on failure\n try {\n unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n throw e;\n }\n}\n","import { execFileSync } from 'node:child_process';\nimport {\n accessSync,\n constants,\n existsSync,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n DISCOVERY_TIMEOUT,\n getExtendedSearchPaths,\n VERSION_TIMEOUT,\n} from '../constants.js';\nimport type { DiscoveryResult } from '../types.js';\n\n/**\n * Two-stage binary discovery:\n * 1. `which <command>` via execSync\n * 2. Manual scan of extended paths\n */\nexport function findBinary(command: string): string | null {\n // Stage 1: which (Unix) / where (Windows)\n const lookupCmd = process.platform === 'win32' ? 'where' : 'which';\n try {\n const result = execFileSync(lookupCmd, [command], {\n timeout: DISCOVERY_TIMEOUT,\n stdio: ['pipe', 'pipe', 'pipe'],\n encoding: 'utf-8',\n })\n .trim()\n .split('\\n')[0]\n .trim(); // `where` on Windows may return multiple lines\n if (result) return result;\n } catch {\n // not found via lookup, continue to stage 2\n }\n\n // Stage 2: extended path scan\n const searchPaths = [\n ...getExtendedSearchPaths(),\n ...getNvmPaths(),\n ...getFnmPaths(),\n ];\n\n for (const dir of searchPaths) {\n const fullPath = join(dir, command);\n try {\n accessSync(fullPath, constants.X_OK);\n return fullPath;\n } catch {\n // not found here, continue\n }\n }\n\n return null;\n}\n\n/**\n * Get NVM version bin directories by resolving the default alias.\n */\nfunction getNvmPaths(): string[] {\n const home = homedir();\n const nvmDir = join(home, '.nvm');\n const aliasFile = join(nvmDir, 'alias', 'default');\n\n if (!existsSync(aliasFile)) return [];\n\n try {\n let alias = readFileSync(aliasFile, 'utf-8').trim();\n\n // Resolve LTS aliases: lts/iron -> read ~/.nvm/alias/lts/iron\n if (alias.startsWith('lts/')) {\n const ltsName = alias.slice(4);\n const ltsFile = join(nvmDir, 'alias', 'lts', ltsName);\n if (existsSync(ltsFile)) {\n alias = readFileSync(ltsFile, 'utf-8').trim();\n }\n }\n\n // Find matching version directory\n const versionsDir = join(nvmDir, 'versions', 'node');\n if (!existsSync(versionsDir)) return [];\n\n const versions = readdirSync(versionsDir);\n const match = versions.find((v) => v.startsWith(`v${alias}`));\n if (match) {\n return [join(versionsDir, match, 'bin')];\n }\n } catch {\n // nvm parsing failed, skip\n }\n\n return [];\n}\n\n/**\n * Get FNM multishell bin directories (5 most recent by mtime).\n */\nfunction getFnmPaths(): string[] {\n const home = homedir();\n const multishellDir = join(home, '.local', 'state', 'fnm_multishells');\n const paths: string[] = [];\n\n // Also check fnm alias dirs\n const fnmDir = join(home, '.local', 'share', 'fnm');\n if (existsSync(fnmDir)) {\n const aliasDir = join(fnmDir, 'aliases');\n if (existsSync(aliasDir)) {\n try {\n for (const alias of readdirSync(aliasDir)) {\n const binDir = join(aliasDir, alias, 'bin');\n if (existsSync(binDir)) paths.push(binDir);\n }\n } catch {\n // skip\n }\n }\n }\n\n if (!existsSync(multishellDir)) return paths;\n\n try {\n const entries = readdirSync(multishellDir)\n .map((name) => {\n const full = join(multishellDir, name);\n try {\n return { name: full, mtime: statSync(full).mtimeMs };\n } catch {\n return null;\n }\n })\n .filter((e): e is { name: string; mtime: number } => e !== null)\n .sort((a, b) => b.mtime - a.mtime)\n .slice(0, 5);\n\n for (const entry of entries) {\n const binDir = join(entry.name, 'bin');\n if (existsSync(binDir)) {\n paths.push(binDir);\n }\n }\n } catch {\n // scan failed, skip\n }\n\n return paths;\n}\n\n/**\n * Get binary version via --version flag.\n */\nexport function getBinaryVersion(binaryPath: string): string | null {\n try {\n const output = execFileSync(binaryPath, ['--version'], {\n timeout: VERSION_TIMEOUT,\n stdio: ['pipe', 'pipe', 'pipe'],\n encoding: 'utf-8',\n }).trim();\n // Take first line, strip common prefixes\n const firstLine = output.split('\\n')[0].trim();\n return firstLine || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Discover a single tool.\n */\nexport function discoverTool(\n commands: string[],\n): DiscoveryResult & { command: string } {\n for (const cmd of commands) {\n const path = findBinary(cmd);\n if (path) {\n const version = getBinaryVersion(path);\n return { toolId: cmd, found: true, path, version, command: cmd };\n }\n }\n return {\n toolId: commands[0],\n found: false,\n path: null,\n version: null,\n command: commands[0],\n };\n}\n","import ora, { type Ora } from 'ora';\nimport type {\n DiscoveryResult,\n DoctorCheck,\n RunManifest,\n TestResult,\n} from '../types.js';\n\nexport function createSpinner(text: string): Ora {\n return ora({ text, stream: process.stderr });\n}\n\nexport function formatDiscoveryResults(\n results: (DiscoveryResult & { displayName?: string })[],\n): string {\n const lines: string[] = ['', 'Discovered tools:', ''];\n for (const r of results) {\n const name = r.displayName || r.toolId;\n if (r.found) {\n lines.push(` ✓ ${name}`);\n lines.push(` Path: ${r.path}`);\n if (r.version) lines.push(` Version: ${r.version}`);\n } else {\n lines.push(` ✗ ${name} — not found`);\n }\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatDoctorResults(checks: DoctorCheck[]): string {\n const lines: string[] = ['', 'Doctor results:', ''];\n for (const c of checks) {\n const icon = c.status === 'pass' ? '✓' : c.status === 'warn' ? '⚠' : '✗';\n lines.push(` ${icon} ${c.name}: ${c.message}`);\n }\n const failures = checks.filter((c) => c.status === 'fail').length;\n const warnings = checks.filter((c) => c.status === 'warn').length;\n lines.push('');\n if (failures > 0) {\n lines.push(`${failures} check(s) failed.`);\n } else if (warnings > 0) {\n lines.push(`All checks passed with ${warnings} warning(s).`);\n } else {\n lines.push('All checks passed.');\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport interface ToolListEntry {\n id: string;\n binary: string;\n args?: string[];\n}\n\nexport function formatToolList(\n tools: ToolListEntry[],\n verbose?: boolean,\n): string {\n if (tools.length === 0) {\n return '\\nNo tools configured. Run \"counselors init\" to get started.\\n';\n }\n\n const lines: string[] = ['', 'Configured tools:', ''];\n for (const t of tools) {\n if (!verbose) {\n lines.push(` \\x1b[1m${t.id}\\x1b[0m (${t.binary})`);\n continue;\n }\n\n const bold = '\\x1b[1m';\n const reset = '\\x1b[0m';\n lines.push(` ${bold}${t.id}${reset}`);\n\n const raw = t.args ?? [];\n const quote = (a: string) => (a.includes(' ') ? `\"${a}\"` : a);\n\n // Build the full command, breaking onto new lines at each -- flag\n const allParts = [t.binary, ...raw].map(quote);\n let line = ' ';\n for (const part of allParts) {\n if (part.startsWith('-') && line.trim().length > 0) {\n lines.push(line);\n line = ` ${part}`;\n } else {\n line += (line.trim().length > 0 ? ' ' : '') + part;\n }\n }\n if (line.trim().length > 0) lines.push(line);\n }\n\n if (!verbose) {\n const dim = '\\x1b[2m';\n const reset = '\\x1b[0m';\n lines.push('');\n lines.push(`${dim}(Use -v to show flags)${reset}`);\n }\n\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatTestResults(results: TestResult[]): string {\n const lines: string[] = ['', 'Test results:', ''];\n for (const r of results) {\n const icon = r.passed ? '✓' : '✗';\n lines.push(` ${icon} ${r.toolId} (${r.durationMs}ms)`);\n if (!r.passed && r.error) {\n lines.push(` Error: ${r.error}`);\n }\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatRunSummary(manifest: RunManifest): string {\n const lines: string[] = ['', `Run complete: ${manifest.slug}`, ''];\n\n for (const r of manifest.tools) {\n const icon =\n r.status === 'success' ? '✓' : r.status === 'timeout' ? '⏱' : '✗';\n const duration = (r.durationMs / 1000).toFixed(1);\n lines.push(` ${icon} ${r.toolId} — ${r.wordCount} words, ${duration}s`);\n if (r.cost) {\n lines.push(` Cost: $${r.cost.cost_usd.toFixed(2)} (${r.cost.source})`);\n }\n if (r.status === 'error' && r.error) {\n lines.push(` Error: ${r.error}`);\n }\n }\n\n lines.push('');\n lines.push(\n `Reports saved to: ${manifest.tools[0]?.outputFile ? manifest.tools[0].outputFile.replace(/\\/[^/]+$/, '/') : 'output dir'}`,\n );\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatDryRun(\n invocations: { toolId: string; cmd: string; args: string[] }[],\n): string {\n const lines: string[] = ['', 'Dry run — would dispatch:', ''];\n for (const inv of invocations) {\n lines.push(` ${inv.toolId}`);\n lines.push(` $ ${inv.cmd} ${inv.args.join(' ')}`);\n }\n lines.push('');\n return lines.join('\\n');\n}\n","import { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n AMP_DEEP_SETTINGS_FILE,\n AMP_SETTINGS_FILE,\n CONFIG_DIR,\n} from '../constants.js';\n\nexport function copyAmpSettings(): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n const assetsDir = resolve(\n dirname(fileURLToPath(import.meta.url)),\n '..',\n 'assets',\n );\n const bundledSettings = resolve(assetsDir, 'amp-readonly-settings.json');\n if (existsSync(bundledSettings)) {\n copyFileSync(bundledSettings, AMP_SETTINGS_FILE);\n }\n const bundledDeepSettings = resolve(assetsDir, 'amp-deep-settings.json');\n if (existsSync(bundledDeepSettings)) {\n copyFileSync(bundledDeepSettings, AMP_DEEP_SETTINGS_FILE);\n }\n}\n","import { type ChildProcess, execFile, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport stripAnsi from 'strip-ansi';\nimport { computeAmpCost, parseAmpUsage } from '../adapters/amp.js';\nimport { KILL_GRACE_PERIOD, TEST_TIMEOUT } from '../constants.js';\nimport type {\n CostInfo,\n ExecResult,\n Invocation,\n TestResult,\n ToolAdapter,\n ToolConfig,\n} from '../types.js';\nimport { debug } from '../ui/logger.js';\n\nconst execFileAsync = promisify(execFile);\n\nconst MAX_OUTPUT_BYTES = 10 * 1024 * 1024; // 10MB\n\nconst activeChildren = new Set<ChildProcess>();\n\nprocess.on('SIGINT', () => {\n for (const child of activeChildren) {\n child.kill('SIGTERM');\n }\n // Give children a moment to exit, then force-exit\n setTimeout(() => process.exit(1), 2000);\n});\n\nconst ENV_ALLOWLIST = [\n 'PATH',\n 'HOME',\n 'USER',\n 'TERM',\n 'LANG',\n 'SHELL',\n 'TMPDIR',\n 'XDG_CONFIG_HOME',\n 'XDG_DATA_HOME',\n // Node version managers\n 'NVM_BIN',\n 'NVM_DIR',\n 'FNM_MULTISHELL_PATH',\n // API keys for adapters\n 'ANTHROPIC_API_KEY',\n 'OPENAI_API_KEY',\n 'OPENAI_ORG_ID',\n 'GEMINI_API_KEY',\n 'GOOGLE_API_KEY',\n 'GOOGLE_APPLICATION_CREDENTIALS',\n 'AMP_API_KEY',\n // Proxy\n 'HTTP_PROXY',\n 'HTTPS_PROXY',\n 'NO_PROXY',\n 'http_proxy',\n 'https_proxy',\n 'no_proxy',\n // Node runtime\n 'NODE_OPTIONS',\n] as const;\n\nfunction buildSafeEnv(extra?: Record<string, string>): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of ENV_ALLOWLIST) {\n if (process.env[key]) env[key] = process.env[key]!;\n }\n if (extra) Object.assign(env, extra);\n env.CI = 'true';\n env.NO_COLOR = '1';\n return env;\n}\n\n/**\n * Execute a tool invocation with timeout and output capture.\n * Uses child_process.spawn — no shell: true (security).\n */\nexport function execute(\n invocation: Invocation,\n timeoutMs: number,\n): Promise<ExecResult> {\n return new Promise((resolve) => {\n const start = Date.now();\n let stdout = '';\n let stderr = '';\n let timedOut = false;\n let killed = false;\n let killTimer: NodeJS.Timeout | undefined;\n let truncated = false;\n\n debug(`Executing: ${invocation.cmd} ${invocation.args.join(' ')}`);\n\n const child = spawn(invocation.cmd, invocation.args, {\n cwd: invocation.cwd,\n env: buildSafeEnv(invocation.env),\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Track active children for SIGINT cleanup\n activeChildren.add(child);\n\n child.stdout.on('data', (data: Buffer) => {\n if (!truncated && stdout.length < MAX_OUTPUT_BYTES) {\n stdout += data.toString();\n if (stdout.length >= MAX_OUTPUT_BYTES) {\n truncated = true;\n stdout = `${stdout.slice(0, MAX_OUTPUT_BYTES)}\\n[output truncated at 10MB]`;\n }\n }\n });\n\n child.stderr.on('data', (data: Buffer) => {\n if (stderr.length < MAX_OUTPUT_BYTES) {\n stderr += data.toString();\n }\n });\n\n // Write stdin if provided\n if (invocation.stdin) {\n child.stdin.write(invocation.stdin);\n child.stdin.end();\n } else {\n child.stdin.end();\n }\n\n // Timeout: SIGTERM first, SIGKILL after grace period\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill('SIGTERM');\n killTimer = setTimeout(() => {\n if (!killed) {\n child.kill('SIGKILL');\n }\n }, KILL_GRACE_PERIOD);\n }, timeoutMs);\n\n child.on('close', (code) => {\n killed = true;\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n activeChildren.delete(child);\n resolve({\n exitCode: code ?? 1,\n stdout: stripAnsi(stdout),\n stderr: stripAnsi(stderr),\n timedOut,\n durationMs: Date.now() - start,\n });\n });\n\n child.on('error', (err) => {\n killed = true;\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n activeChildren.delete(child);\n resolve({\n exitCode: 1,\n stdout: '',\n stderr: err.message,\n timedOut: false,\n durationMs: Date.now() - start,\n });\n });\n });\n}\n\n/**\n * Capture amp usage before/after a run to compute cost.\n */\nexport async function captureAmpUsage(): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync('amp', ['usage'], {\n timeout: 10_000,\n encoding: 'utf-8',\n });\n return stdout;\n } catch {\n return null;\n }\n}\n\n/**\n * Compute amp cost from before/after usage snapshots.\n */\nexport function computeAmpCostFromSnapshots(\n before: string,\n after: string,\n): CostInfo | null {\n try {\n const beforeParsed = parseAmpUsage(before);\n const afterParsed = parseAmpUsage(after);\n return computeAmpCost(beforeParsed, afterParsed);\n } catch {\n return null;\n }\n}\n\n/**\n * Test a tool using the \"reply OK\" protocol.\n */\nexport async function executeTest(\n adapter: ToolAdapter,\n toolConfig: ToolConfig,\n toolName?: string,\n): Promise<TestResult> {\n const prompt = 'Reply with exactly: OK';\n const start = Date.now();\n\n const invocation = adapter.buildInvocation({\n prompt,\n promptFilePath: '',\n toolId: adapter.id,\n outputDir: '',\n readOnlyPolicy: 'none',\n timeout: TEST_TIMEOUT / 1000,\n cwd: process.cwd(),\n extraFlags: toolConfig.extraFlags,\n });\n\n // Override: for test, we pass a simple prompt as argument or stdin.\n // Check invocation.stdin (set by the adapter) rather than config.stdin,\n // so built-in stdin adapters (Amp, Gemini) are handled correctly.\n if (invocation.stdin != null) {\n invocation.stdin = prompt;\n // Remove any --settings-file flags for test\n invocation.args = invocation.args.filter((a, i, arr) => {\n if (a === '--settings-file') return false;\n if (i > 0 && arr[i - 1] === '--settings-file') return false;\n return true;\n });\n } else {\n // Replace prompt file instruction with direct prompt\n const lastArgIdx = invocation.args.length - 1;\n invocation.args[lastArgIdx] = prompt;\n }\n\n const result = await execute(invocation, TEST_TIMEOUT);\n\n const passed = result.stdout.includes('OK');\n return {\n toolId: toolName ?? adapter.id,\n passed,\n output: result.stdout.slice(0, 500),\n error: !passed\n ? result.stderr.slice(0, 500) || 'Output did not contain \"OK\"'\n : undefined,\n durationMs: Date.now() - start,\n };\n}\n","import { checkbox, confirm, input, select } from '@inquirer/prompts';\n\nexport async function selectModelDetails(\n toolId: string,\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[],\n): Promise<{ id: string; compoundId?: string; extraFlags?: string[] }> {\n const choices = models.map((m, i) => ({\n name: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: String(i),\n }));\n\n const idx = await select({\n message: `Select model for ${toolId}:`,\n choices,\n });\n\n const model = models[Number(idx)];\n return {\n id: model.id,\n compoundId: model.compoundId,\n extraFlags: model.extraFlags,\n };\n}\n\nexport async function selectModels(\n toolId: string,\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[],\n): Promise<{ id: string; compoundId?: string; extraFlags?: string[] }[]> {\n const choices = models.map((m) => ({\n name: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: { id: m.id, compoundId: m.compoundId, extraFlags: m.extraFlags },\n checked: m.recommended,\n }));\n\n return checkbox({\n message: `Select models for ${toolId}:`,\n choices,\n });\n}\n\nexport async function selectTools(\n tools: { id: string; name: string; found: boolean }[],\n): Promise<string[]> {\n const choices = tools.map((t) => ({\n name: t.found ? `${t.name} — found` : `${t.name} — not found`,\n value: t.id,\n checked: t.found,\n disabled: !t.found ? '(not installed)' : undefined,\n }));\n\n return checkbox({\n message: 'Which tools should be configured?',\n choices: choices as any,\n });\n}\n\nexport async function confirmOverwrite(toolId: string): Promise<boolean> {\n return confirm({\n message: `Tool \"${toolId}\" already exists. Overwrite?`,\n default: false,\n });\n}\n\nexport async function selectRunTools(tools: string[]): Promise<string[]> {\n const choices = tools.map((id) => ({\n name: id,\n value: id,\n checked: true,\n }));\n\n return checkbox({\n message: 'Select tools to dispatch:',\n choices,\n });\n}\n\nexport async function confirmAction(message: string): Promise<boolean> {\n return confirm({ message, default: true });\n}\n\nexport async function promptInput(\n message: string,\n defaultValue?: string,\n): Promise<string> {\n return input({ message, default: defaultValue });\n}\n\nexport async function promptSelect<T extends string>(\n message: string,\n choices: { name: string; value: T }[],\n): Promise<T> {\n return select({ message, choices });\n}\n","import type { Command } from 'commander';\nimport { getAllBuiltInAdapters, resolveAdapter } from '../adapters/index.js';\nimport { AMP_SETTINGS_FILE, CONFIG_DIR } from '../constants.js';\nimport { copyAmpSettings } from '../core/amp-utils.js';\nimport { addToolToConfig, loadConfig, saveConfig } from '../core/config.js';\nimport { discoverTool } from '../core/discovery.js';\nimport { executeTest } from '../core/executor.js';\nimport { info, success, warn } from '../ui/logger.js';\nimport {\n createSpinner,\n formatDiscoveryResults,\n formatTestResults,\n} from '../ui/output.js';\nimport { confirmAction, selectModels, selectTools } from '../ui/prompts.js';\n\nfunction buildToolConfig(\n id: string,\n adapter: import('../types.js').ToolAdapter,\n binaryPath: string,\n) {\n return {\n binary: binaryPath,\n readOnly: { level: adapter.readOnly.level },\n ...(id === 'gemini' || id === 'codex' ? { timeout: 900 } : {}),\n };\n}\n\nfunction compoundId(adapterId: string, modelId: string): string {\n if (modelId.startsWith(`${adapterId}-`)) return modelId;\n return `${adapterId}-${modelId}`;\n}\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Interactive setup wizard')\n .option(\n '--auto',\n 'Non-interactive mode: discover tools, use recommended models, output JSON',\n )\n .action(async (opts: { auto?: boolean }) => {\n // Non-interactive auto mode\n if (opts.auto) {\n const adapters = getAllBuiltInAdapters();\n const discoveries = adapters.map((adapter) => {\n const result = discoverTool(adapter.commands);\n return { adapter, discovery: result };\n });\n\n const foundTools = discoveries.filter((d) => d.discovery.found);\n if (foundTools.length === 0) {\n info(\n JSON.stringify(\n {\n configured: [],\n notFound: adapters.map((a) => a.id),\n configPath: CONFIG_DIR,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n let config = loadConfig();\n const configured: {\n id: string;\n adapter: string;\n binary: string;\n version: string | null;\n }[] = [];\n const notFound: string[] = [];\n\n for (const { adapter, discovery } of discoveries) {\n if (!discovery.found) {\n notFound.push(adapter.id);\n continue;\n }\n\n for (const model of adapter.models) {\n const cid = model.compoundId ?? compoundId(adapter.id, model.id);\n const toolConfig = {\n ...buildToolConfig(adapter.id, adapter, discovery.path!),\n adapter: adapter.id,\n ...(model.extraFlags ? { extraFlags: model.extraFlags } : {}),\n };\n config = addToolToConfig(config, cid, toolConfig);\n configured.push({\n id: cid,\n adapter: adapter.id,\n binary: discovery.path!,\n version: discovery.version,\n });\n }\n }\n\n if (configured.some((t) => t.adapter === 'amp')) {\n copyAmpSettings();\n }\n\n saveConfig(config);\n\n info(\n JSON.stringify(\n { configured, notFound, configPath: CONFIG_DIR },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Interactive mode\n info('\\nCounselors — setup wizard\\n');\n\n const existingConfig = loadConfig();\n const existingTools = Object.keys(existingConfig.tools);\n if (existingTools.length > 0) {\n warn(\n `Existing config has ${existingTools.length} tool(s). Re-running init will overwrite any tools with the same name.`,\n );\n }\n\n // Step 1: Discover all built-in tools\n const spinner = createSpinner('Discovering installed tools...').start();\n const adapters = getAllBuiltInAdapters();\n const discoveries = adapters.map((adapter) => {\n const result = discoverTool(adapter.commands);\n return { adapter, discovery: result };\n });\n spinner.stop();\n\n info(\n formatDiscoveryResults(\n discoveries.map((d) => ({\n ...d.discovery,\n toolId: d.adapter.id,\n displayName: d.adapter.displayName,\n })),\n ),\n );\n\n const foundTools = discoveries.filter((d) => d.discovery.found);\n if (foundTools.length === 0) {\n warn(\n 'No AI CLI tools found. Install at least one before running init.',\n );\n return;\n }\n\n // Step 2: Select which tools to add\n const selectedIds = await selectTools(\n discoveries.map((d) => ({\n id: d.adapter.id,\n name: d.adapter.displayName,\n found: d.discovery.found,\n })),\n );\n\n if (selectedIds.length === 0) {\n info('No tools selected. Exiting.');\n return;\n }\n\n // Step 3: Model selection per tool\n let config = loadConfig();\n const configuredIds: string[] = [];\n\n for (const id of selectedIds) {\n const d = discoveries.find((x) => x.adapter.id === id)!;\n const models = await selectModels(id, d.adapter.models);\n\n for (const model of models) {\n const cid = model.compoundId ?? compoundId(id, model.id);\n const toolConfig = {\n ...buildToolConfig(id, d.adapter, d.discovery.path!),\n adapter: id,\n ...(model.extraFlags ? { extraFlags: model.extraFlags } : {}),\n };\n config = addToolToConfig(config, cid, toolConfig);\n configuredIds.push(cid);\n }\n }\n\n // Step 4: Copy amp settings if amp was selected\n if (selectedIds.includes('amp')) {\n copyAmpSettings();\n success(`Copied amp settings to ${AMP_SETTINGS_FILE}`);\n }\n\n // Step 5: Save config\n saveConfig(config);\n success(`Config saved to ${CONFIG_DIR}`);\n\n // Step 6: Offer to test\n const runTests = await confirmAction('Run tool tests now?');\n if (runTests) {\n const testResults = [];\n for (const id of configuredIds) {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n const spinner = createSpinner(`Testing ${id}...`).start();\n const result = await executeTest(adapter, toolConfig, id);\n spinner.stop();\n testResults.push(result);\n }\n info(formatTestResults(testResults));\n }\n });\n}\n","import { copyFileSync, readFileSync } from 'node:fs';\nimport { basename, join, resolve } from 'node:path';\nimport type { Command } from 'commander';\nimport { resolveAdapter } from '../adapters/index.js';\nimport { loadConfig, loadProjectConfig, mergeConfigs } from '../core/config.js';\nimport { gatherContext } from '../core/context.js';\nimport { dispatch } from '../core/dispatcher.js';\nimport { safeWriteFile } from '../core/fs-utils.js';\nimport {\n buildPrompt,\n generateSlug,\n generateSlugFromFile,\n resolveOutputDir,\n} from '../core/prompt-builder.js';\nimport { synthesize } from '../core/synthesis.js';\nimport type { ReadOnlyLevel, RunManifest, ToolReport } from '../types.js';\nimport { error, info } from '../ui/logger.js';\nimport { formatDryRun, formatRunSummary } from '../ui/output.js';\nimport { ProgressDisplay } from '../ui/progress.js';\nimport { selectRunTools } from '../ui/prompts.js';\n\nexport function registerRunCommand(program: Command): void {\n program\n .command('run [prompt]')\n .description('Dispatch prompt to configured AI tools in parallel')\n .option('-f, --file <path>', 'Use a pre-built prompt file (no wrapping)')\n .option('-t, --tools <tools>', 'Comma-separated list of tools to use')\n .option(\n '--context <paths>',\n 'Gather context from paths (comma-separated, or \".\" for git diff)',\n )\n .option('--read-only <level>', 'Read-only policy: strict, best-effort, off')\n .option('--dry-run', 'Show what would be dispatched without running')\n .option('--json', 'Output manifest as JSON')\n .option('-o, --output-dir <dir>', 'Base output directory')\n .action(\n async (\n promptArg: string | undefined,\n opts: {\n file?: string;\n tools?: string;\n context?: string;\n readOnly?: string;\n dryRun?: boolean;\n json?: boolean;\n outputDir?: string;\n },\n ) => {\n const cwd = process.cwd();\n const globalConfig = loadConfig();\n const projectConfig = loadProjectConfig(cwd);\n const config = mergeConfigs(globalConfig, projectConfig);\n\n // Determine tools to use\n let toolIds: string[];\n const explicitTools = Boolean(opts.tools);\n\n if (opts.tools) {\n toolIds = opts.tools.split(',').map((t) => t.trim());\n } else {\n toolIds = Object.keys(config.tools);\n }\n\n if (toolIds.length === 0) {\n error('No tools configured. Run \"counselors init\" first.');\n process.exitCode = 1;\n return;\n }\n\n // Validate all tools exist in config\n for (const id of toolIds) {\n if (!config.tools[id]) {\n error(\n `Tool \"${id}\" not configured. Run \"counselors tools add ${id}\".`,\n );\n process.exitCode = 1;\n return;\n }\n }\n\n // Interactive tool selection when no --tools flag and TTY\n if (\n !explicitTools &&\n !opts.dryRun &&\n process.stderr.isTTY &&\n toolIds.length > 1\n ) {\n const selected = await selectRunTools(toolIds);\n if (selected.length === 0) {\n error('No tools selected.');\n process.exitCode = 1;\n return;\n }\n toolIds = selected;\n }\n\n // Map read-only flag (fall back to config default)\n const internalToCliMap: Record<string, string> = {\n enforced: 'strict',\n bestEffort: 'best-effort',\n none: 'off',\n };\n const readOnlyInput =\n opts.readOnly ??\n internalToCliMap[config.defaults.readOnly] ??\n 'best-effort';\n const readOnlyMap: Record<string, ReadOnlyLevel> = {\n strict: 'enforced',\n 'best-effort': 'bestEffort',\n off: 'none',\n };\n const readOnlyPolicy = readOnlyMap[readOnlyInput];\n if (!readOnlyPolicy) {\n error(\n `Invalid --read-only value \"${readOnlyInput}\". Must be: strict, best-effort, or off.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Resolve prompt\n let promptContent: string;\n let promptSource: 'inline' | 'file' | 'stdin';\n let slug: string;\n\n if (opts.file) {\n // File mode: use as-is, no wrapping\n const filePath = resolve(cwd, opts.file);\n try {\n promptContent = readFileSync(filePath, 'utf-8');\n } catch {\n error(`Cannot read prompt file: ${filePath}`);\n process.exitCode = 1;\n return;\n }\n promptSource = 'file';\n slug = generateSlugFromFile(filePath);\n } else if (promptArg) {\n // Inline prompt: wrap in template\n promptSource = 'inline';\n slug = generateSlug(promptArg);\n\n const context = opts.context\n ? gatherContext(\n cwd,\n opts.context === '.' ? [] : opts.context.split(','),\n config.defaults.maxContextKb,\n )\n : undefined;\n\n promptContent = buildPrompt(promptArg, context);\n } else {\n // Check stdin\n if (process.stdin.isTTY) {\n error(\n 'No prompt provided. Pass as argument, use -f <file>, or pipe via stdin.',\n );\n process.exitCode = 1;\n return;\n }\n\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinContent = Buffer.concat(chunks).toString('utf-8').trim();\n if (!stdinContent) {\n error('Empty prompt from stdin.');\n process.exitCode = 1;\n return;\n }\n\n promptSource = 'stdin';\n slug = generateSlug(stdinContent);\n\n const context = opts.context\n ? gatherContext(\n cwd,\n opts.context === '.' ? [] : opts.context.split(','),\n config.defaults.maxContextKb,\n )\n : undefined;\n\n promptContent = buildPrompt(stdinContent, context);\n }\n\n if (!slug) slug = `run-${Date.now()}`;\n\n // Dry run — no filesystem side effects\n if (opts.dryRun) {\n const baseDir = opts.outputDir || config.defaults.outputDir;\n const dryOutputDir = join(baseDir, slug);\n const dryPromptFile = resolve(dryOutputDir, 'prompt.md');\n const invocations = toolIds.map((id) => {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n const inv = adapter.buildInvocation({\n prompt: promptContent,\n promptFilePath: dryPromptFile,\n toolId: id,\n outputDir: dryOutputDir,\n readOnlyPolicy,\n timeout: config.defaults.timeout,\n cwd,\n binary: toolConfig.binary,\n extraFlags: toolConfig.extraFlags,\n });\n return {\n toolId: id,\n cmd: inv.cmd,\n args: inv.args,\n };\n });\n info(formatDryRun(invocations));\n return;\n }\n\n // Resolve output directory (creates it)\n const baseDir = opts.outputDir || config.defaults.outputDir;\n const outputDir = resolveOutputDir(baseDir, slug);\n\n // Write prompt file\n const promptFilePath = resolve(outputDir, 'prompt.md');\n if (opts.file) {\n copyFileSync(resolve(cwd, opts.file), promptFilePath);\n } else {\n safeWriteFile(promptFilePath, promptContent);\n }\n\n // Dispatch\n const display = new ProgressDisplay(toolIds, outputDir);\n\n let reports: ToolReport[];\n try {\n reports = await dispatch({\n config,\n toolIds,\n promptFilePath,\n promptContent,\n outputDir,\n readOnlyPolicy,\n cwd,\n onProgress: (event) => {\n if (event.event === 'started') display.start(event.toolId);\n if (event.event === 'completed')\n display.complete(event.toolId, event.report!);\n },\n });\n } finally {\n display.stop();\n }\n\n // Build manifest\n const manifest: RunManifest = {\n timestamp: new Date().toISOString(),\n slug,\n prompt:\n promptArg || (opts.file ? `file:${basename(opts.file)}` : 'stdin'),\n promptSource,\n readOnlyPolicy,\n tools: reports,\n };\n\n // Write manifest + synthesis\n safeWriteFile(\n resolve(outputDir, 'run.json'),\n JSON.stringify(manifest, null, 2),\n );\n const summary = synthesize(manifest, outputDir);\n safeWriteFile(resolve(outputDir, 'summary.md'), summary);\n\n // Output\n if (opts.json) {\n info(JSON.stringify(manifest, null, 2));\n } else {\n info(formatRunSummary(manifest));\n }\n },\n );\n}\n","import { execFileSync } from 'node:child_process';\nimport { readFileSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { DEFAULT_MAX_CONTEXT_KB } from '../constants.js';\nimport { debug } from '../ui/logger.js';\n\n/**\n * Gather context from git diff and specified files.\n */\nexport function gatherContext(\n cwd: string,\n paths: string[],\n maxKb: number = DEFAULT_MAX_CONTEXT_KB,\n): string {\n const parts: string[] = [];\n let totalBytes = 0;\n const maxBytes = maxKb * 1024;\n\n // Read specified files first (user-requested content gets priority)\n if (paths.length > 0) {\n parts.push('### Files Referenced', '');\n\n for (const p of paths) {\n if (totalBytes >= maxBytes) {\n debug(`Context limit reached (${maxKb}KB), skipping remaining files`);\n break;\n }\n\n const fullPath = resolve(cwd, p);\n try {\n const stat = statSync(fullPath);\n if (!stat.isFile()) continue;\n if (stat.size > maxBytes - totalBytes) {\n debug(`Skipping ${p} — too large (${stat.size} bytes)`);\n continue;\n }\n\n const content = readFileSync(fullPath, 'utf-8');\n parts.push(`#### ${p}`, '', '```', content, '```', '');\n totalBytes += Buffer.byteLength(content);\n } catch {\n debug(`Could not read ${p}`);\n }\n }\n }\n\n // Git diff (staged + unstaged) — added after files, truncated if over budget\n if (totalBytes < maxBytes) {\n const diff = getGitDiff(cwd);\n if (diff) {\n const diffBytes = Buffer.byteLength(diff);\n if (totalBytes + diffBytes <= maxBytes) {\n parts.push(\n '### Recent Changes (Git Diff)',\n '',\n '```diff',\n diff,\n '```',\n '',\n );\n totalBytes += diffBytes;\n } else {\n const remaining = maxBytes - totalBytes;\n const truncated = Buffer.from(diff)\n .subarray(0, remaining)\n .toString('utf-8');\n parts.push(\n '### Recent Changes (Git Diff) [truncated]',\n '',\n '```diff',\n truncated,\n '```',\n '',\n );\n totalBytes = maxBytes;\n }\n }\n }\n\n return parts.join('\\n');\n}\n\nfunction getGitDiff(cwd: string): string | null {\n try {\n const staged = execFileSync('git', ['diff', '--staged'], {\n cwd,\n encoding: 'utf-8',\n timeout: 10_000,\n maxBuffer: 10 * 1024 * 1024,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n const unstaged = execFileSync('git', ['diff'], {\n cwd,\n encoding: 'utf-8',\n timeout: 10_000,\n maxBuffer: 10 * 1024 * 1024,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n const parts = [];\n if (staged) parts.push(staged);\n if (unstaged) parts.push(unstaged);\n return parts.length > 0 ? parts.join('\\n') : null;\n } catch {\n return null;\n }\n}\n","import { join } from 'node:path';\nimport pLimit from 'p-limit';\nimport { resolveAdapter } from '../adapters/index.js';\nimport { sanitizeId } from '../constants.js';\nimport type {\n Config,\n ReadOnlyLevel,\n RunRequest,\n ToolReport,\n} from '../types.js';\nimport { debug, warn } from '../ui/logger.js';\nimport {\n captureAmpUsage,\n computeAmpCostFromSnapshots,\n execute,\n} from './executor.js';\nimport { safeWriteFile } from './fs-utils.js';\n\nexport interface ProgressEvent {\n toolId: string;\n event: 'started' | 'completed';\n report?: ToolReport;\n}\n\nexport interface DispatchOptions {\n config: Config;\n toolIds: string[];\n promptFilePath: string;\n promptContent: string;\n outputDir: string;\n readOnlyPolicy: ReadOnlyLevel;\n cwd: string;\n onProgress?: (event: ProgressEvent) => void;\n}\n\n/**\n * Dispatch prompts to all selected tools in parallel with bounded concurrency.\n */\nexport async function dispatch(\n options: DispatchOptions,\n): Promise<ToolReport[]> {\n const {\n config,\n toolIds,\n promptFilePath,\n promptContent,\n outputDir,\n readOnlyPolicy,\n cwd,\n onProgress,\n } = options;\n const limit = pLimit(config.defaults.maxParallel);\n\n // Filter tools based on read-only policy\n const eligibleTools = toolIds.filter((id) => {\n const toolConfig = config.tools[id];\n if (!toolConfig) {\n warn(`Tool \"${id}\" not configured, skipping.`);\n return false;\n }\n\n if (readOnlyPolicy === 'enforced') {\n const adapter = resolveAdapter(id, toolConfig);\n if (adapter.readOnly.level !== 'enforced') {\n warn(\n `Skipping \"${id}\" — read-only level is \"${adapter.readOnly.level}\", policy requires \"enforced\".`,\n );\n return false;\n }\n }\n\n return true;\n });\n\n if (eligibleTools.length === 0) {\n throw new Error('No eligible tools after read-only policy filtering.');\n }\n\n const tasks = eligibleTools.map((id) =>\n limit(async (): Promise<ToolReport> => {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n\n const toolTimeout = toolConfig.timeout ?? config.defaults.timeout;\n const toolTimeoutMs = toolTimeout * 1000;\n\n const req: RunRequest = {\n prompt: promptContent,\n promptFilePath,\n toolId: id,\n outputDir,\n readOnlyPolicy,\n timeout: toolTimeout,\n cwd,\n binary: toolConfig.binary,\n extraFlags: toolConfig.extraFlags,\n };\n\n const invocation = adapter.buildInvocation(req);\n\n // Amp cost tracking: capture usage before\n const isAmp = (toolConfig.adapter ?? id) === 'amp';\n const usageBefore = isAmp ? await captureAmpUsage() : null;\n\n debug(`Dispatching ${id}`);\n onProgress?.({ toolId: id, event: 'started' });\n const result = await execute(invocation, toolTimeoutMs);\n\n // Amp cost tracking: capture usage after\n const usageAfter = isAmp ? await captureAmpUsage() : null;\n const cost =\n isAmp && usageBefore && usageAfter\n ? computeAmpCostFromSnapshots(usageBefore, usageAfter)\n : undefined;\n\n // Write output files\n const safeId = sanitizeId(id);\n const outputFile = join(outputDir, `${safeId}.md`);\n const stderrFile = join(outputDir, `${safeId}.stderr`);\n\n safeWriteFile(outputFile, result.stdout);\n safeWriteFile(stderrFile, result.stderr);\n\n if (cost) {\n const statsFile = join(outputDir, `${safeId}.stats.json`);\n safeWriteFile(statsFile, JSON.stringify({ cost }, null, 2));\n }\n\n const parsed = adapter.parseResult?.(result) ?? {};\n\n const report: ToolReport = {\n toolId: id,\n status: result.timedOut\n ? 'timeout'\n : result.exitCode === 0\n ? 'success'\n : 'error',\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n wordCount: result.stdout.split(/\\s+/).filter(Boolean).length,\n outputFile,\n stderrFile,\n cost: cost ?? undefined,\n error: result.exitCode !== 0 ? result.stderr.slice(0, 500) : undefined,\n ...parsed,\n };\n\n onProgress?.({ toolId: id, event: 'completed', report });\n\n return report;\n }),\n );\n\n const results = await Promise.allSettled(tasks);\n\n return results.map((r, i) => {\n if (r.status === 'fulfilled') return r.value;\n return {\n toolId: eligibleTools[i],\n status: 'error' as const,\n exitCode: 1,\n durationMs: 0,\n wordCount: 0,\n outputFile: '',\n stderrFile: '',\n error: r.reason?.message ?? 'Unknown error',\n };\n });\n}\n","import { mkdirSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { MAX_SLUG_LENGTH } from '../constants.js';\n\n/**\n * Generate a slug from prompt text.\n * Lowercase, hyphens, max 40 chars.\n */\nexport function generateSlug(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, MAX_SLUG_LENGTH);\n}\n\n/**\n * Generate slug from a file path.\n * Uses the parent directory name if available, otherwise the filename.\n */\nexport function generateSlugFromFile(filePath: string): string {\n const dir = dirname(filePath);\n const dirName = basename(dir);\n // If parent dir has a meaningful name (not . or empty), use it\n if (dirName && dirName !== '.' && dirName !== '..') {\n return generateSlug(dirName);\n }\n return generateSlug(basename(filePath, '.md'));\n}\n\n/**\n * Resolve output directory, appending timestamp if exists.\n */\nexport function resolveOutputDir(baseDir: string, slug: string): string {\n let outputDir = join(baseDir, slug);\n try {\n mkdirSync(outputDir, { recursive: false });\n } catch (e: unknown) {\n if ((e as NodeJS.ErrnoException).code === 'EEXIST') {\n outputDir = `${outputDir}-${Date.now()}`;\n mkdirSync(outputDir, { recursive: true });\n } else {\n // Parent dirs may not exist yet\n mkdirSync(outputDir, { recursive: true });\n }\n }\n return outputDir;\n}\n\n/**\n * Build the standard prompt template wrapping user's inline prompt.\n */\nexport function buildPrompt(question: string, context?: string): string {\n const parts: string[] = [\n '# Second Opinion Request',\n '',\n '## Question',\n question,\n '',\n ];\n\n if (context) {\n parts.push('## Context', '', context, '');\n }\n\n parts.push(\n '## Instructions',\n 'You are providing an independent second opinion. Be critical and thorough.',\n '- Analyze the question in the context provided',\n '- Identify risks, tradeoffs, and blind spots',\n '- Suggest alternatives if you see better approaches',\n \"- Be direct and opinionated — don't hedge\",\n '- Structure your response with clear headings',\n '- Keep your response focused and actionable',\n '',\n );\n\n return parts.join('\\n');\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { sanitizeId } from '../constants.js';\nimport type { RunManifest, ToolReport } from '../types.js';\n\n/**\n * Generate a heuristic summary of run results (v1 — no LLM).\n */\nexport function synthesize(manifest: RunManifest, outputDir: string): string {\n const parts: string[] = [\n '# Run Summary',\n '',\n `**Prompt:** ${manifest.prompt.slice(0, 100)}${manifest.prompt.length > 100 ? '...' : ''}`,\n `**Tools:** ${manifest.tools.map((t) => t.toolId).join(', ')}`,\n `**Policy:** read-only=${manifest.readOnlyPolicy}`,\n '',\n ];\n\n // Per-tool summaries\n parts.push('## Results', '');\n\n for (const report of manifest.tools) {\n const icon =\n report.status === 'success'\n ? '✓'\n : report.status === 'timeout'\n ? '⏱'\n : '✗';\n const duration = (report.durationMs / 1000).toFixed(1);\n parts.push(`### ${icon} ${report.toolId}`);\n parts.push('');\n parts.push(`- Status: ${report.status}`);\n parts.push(`- Duration: ${duration}s`);\n parts.push(`- Word count: ${report.wordCount}`);\n\n if (report.cost) {\n parts.push(\n `- Cost: $${report.cost.cost_usd.toFixed(2)} (${report.cost.source})`,\n );\n }\n\n if (report.status === 'error' && report.error) {\n parts.push(`- Error: ${report.error}`);\n }\n\n // Extract headings from report file\n if (report.status === 'success') {\n const headings = extractHeadings(outputDir, report);\n if (headings.length > 0) {\n parts.push('- Key sections:');\n for (const h of headings) {\n parts.push(` - ${h}`);\n }\n }\n }\n\n parts.push('');\n }\n\n // Cost table (if any tools have cost info)\n const costsAvailable = manifest.tools.filter((t) => t.cost);\n if (costsAvailable.length > 0) {\n parts.push('## Cost Summary', '');\n parts.push('| Tool | Cost | Source | Remaining |');\n parts.push('|------|------|--------|-----------|');\n for (const t of costsAvailable) {\n const c = t.cost!;\n parts.push(\n `| ${t.toolId} | $${c.cost_usd.toFixed(2)} | ${c.source} | $${c.source === 'credits' ? c.credits_remaining_usd.toFixed(2) : c.free_remaining_usd.toFixed(2)} |`,\n );\n }\n parts.push('');\n }\n\n return parts.join('\\n');\n}\n\nfunction extractHeadings(outputDir: string, report: ToolReport): string[] {\n const filePath = join(outputDir, `${sanitizeId(report.toolId)}.md`);\n if (!existsSync(filePath)) return [];\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n const headings: string[] = [];\n for (const line of content.split('\\n')) {\n const match = line.match(/^#{1,3}\\s+(.+)/);\n if (match) {\n headings.push(match[1].trim());\n if (headings.length >= 10) break;\n }\n }\n return headings;\n } catch {\n return [];\n }\n}\n","import type { ToolReport } from '../types.js';\n\nconst SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];\nconst TICK_INTERVAL = 200;\nconst RED = '\\x1b[31m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\ntype ToolStatus = 'pending' | 'running' | 'done';\n\ninterface ToolState {\n toolId: string;\n status: ToolStatus;\n startedAt?: number;\n report?: ToolReport;\n}\n\nexport class ProgressDisplay {\n private tools: Map<string, ToolState>;\n private order: string[];\n private outputDir: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private frame = 0;\n private lineCount = 0;\n private isTTY: boolean;\n\n constructor(toolIds: string[], outputDir: string) {\n this.isTTY = Boolean(process.stderr.isTTY);\n this.outputDir = outputDir;\n this.tools = new Map();\n this.order = [];\n for (const id of toolIds) {\n this.tools.set(id, {\n toolId: id,\n status: 'pending',\n });\n this.order.push(id);\n }\n\n if (this.isTTY) {\n this.render();\n this.timer = setInterval(() => {\n this.frame++;\n this.render();\n }, TICK_INTERVAL);\n } else {\n process.stderr.write(` Output: ${this.outputDir}\\n`);\n }\n }\n\n start(toolId: string): void {\n const tool = this.tools.get(toolId);\n if (!tool) return;\n tool.status = 'running';\n tool.startedAt = Date.now();\n\n if (!this.isTTY) {\n process.stderr.write(` ▸ ${toolId} started\\n`);\n }\n }\n\n complete(toolId: string, report: ToolReport): void {\n const tool = this.tools.get(toolId);\n if (!tool) return;\n tool.status = 'done';\n tool.report = report;\n\n if (!this.isTTY) {\n const duration = (report.durationMs / 1000).toFixed(1);\n const icon =\n report.status === 'success'\n ? '✓'\n : report.status === 'timeout'\n ? '⏱'\n : '✗';\n process.stderr.write(\n ` ${icon} ${toolId} done ${duration}s ${report.wordCount.toLocaleString()} words\\n`,\n );\n if (report.status !== 'success' && report.error) {\n process.stderr.write(\n ` └ ${report.error.split('\\n')[0].slice(0, 120)}\\n`,\n );\n }\n }\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n if (this.isTTY) {\n this.render();\n }\n }\n\n private render(): void {\n const lines: string[] = [];\n lines.push(` ${DIM}Output: ${this.outputDir}${RESET}`);\n for (const id of this.order) {\n const tool = this.tools.get(id)!;\n lines.push(this.formatLine(tool));\n if (\n tool.status === 'done' &&\n tool.report?.status !== 'success' &&\n tool.report?.error\n ) {\n const msg = tool.report.error.split('\\n')[0].slice(0, 120);\n lines.push(` ${RED}└ ${msg}${RESET}`);\n }\n }\n\n // Move cursor up to overwrite previous output\n if (this.lineCount > 0) {\n process.stderr.write(`\\x1b[${this.lineCount}A`);\n }\n\n for (const line of lines) {\n process.stderr.write(`\\x1b[K${line}\\n`);\n }\n\n this.lineCount = lines.length;\n }\n\n private formatLine(tool: ToolState): string {\n const label = tool.toolId;\n\n switch (tool.status) {\n case 'pending': {\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ⏳ ${label}${pad}pending`;\n }\n case 'running': {\n const spinner = SPINNER_FRAMES[this.frame % SPINNER_FRAMES.length];\n const elapsed = tool.startedAt\n ? ((Date.now() - tool.startedAt) / 1000).toFixed(1)\n : '0.0';\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ${spinner} ${label}${pad}running ${elapsed.padStart(6)}s`;\n }\n case 'done': {\n const r = tool.report!;\n const icon =\n r.status === 'success' ? '✓' : r.status === 'timeout' ? '⏱' : '✗';\n const duration = (r.durationMs / 1000).toFixed(1);\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ${icon} ${label}${pad}done ${duration.padStart(6)}s ${r.wordCount.toLocaleString()} words`;\n }\n }\n }\n}\n","import type { Command } from 'commander';\nimport { info } from '../ui/logger.js';\n\nexport function registerSkillCommand(program: Command): void {\n program\n .command('skill')\n .description('Print a skill/slash-command template for coding agents')\n .action(async () => {\n const template = `---\nname: counselors\ndescription: Get parallel second opinions from multiple AI coding agents. Use when the user wants independent reviews, architecture feedback, or a sanity check from other AI models.\n---\n\n# Counselors — Multi-Agent Review Skill\n\n> **Note:** This is a reference skill template. Your agent system may use a different skill/command format. Adapt the structure and frontmatter below to match your system's conventions — the workflow and phases are what matter.\n\nFan out a prompt to multiple AI coding agents in parallel and synthesize their responses.\n\nArguments: $ARGUMENTS\n\n**If no arguments provided**, ask the user what they want reviewed.\n\n---\n\n## Phase 1: Context Gathering\n\nParse \\`$ARGUMENTS\\` to understand what the user wants reviewed. Then auto-gather relevant context:\n\n1. **Files mentioned in the prompt**: Use Glob/Grep to find files referenced by name, class, function, or keyword\n2. **Recent changes**: Run \\`git diff HEAD\\` and \\`git diff --staged\\` to capture recent work\n3. **Related code**: Search for key terms from the prompt and read the most relevant files (up to 5 files, ~50KB total cap)\n\nBe selective — don't dump the entire codebase. Pick the most relevant code sections.\n\n---\n\n## Phase 2: Agent Selection\n\n1. **Discover available agents** by running via Bash:\n \\`\\`\\`bash\n counselors ls\n \\`\\`\\`\n This lists all configured agents with their IDs and binaries.\n\n2. **MANDATORY: Print the full agent list, then ask the user which to use.**\n\n **Always print the full \\`counselors ls\\` output as inline text** (not inside AskUserQuestion). Just show the raw output from the command so the user sees every agent with its ID and binary. Do NOT reformat or abbreviate it.\n\n Then ask the user to pick:\n\n **If 4 or fewer agents**: Use AskUserQuestion with \\`multiSelect: true\\`, one option per agent.\n\n **If more than 4 agents**: AskUserQuestion only supports 4 options. Use these fixed options:\n - Option 1: \"All [N] agents\" — sends to every configured agent\n - Option 2-4: The first 3 individual agents by ID\n - The user can always select \"Other\" to type a comma-separated list of agent IDs from the printed list above\n\n Do NOT combine agents into preset groups (e.g. \"claude + codex + gemini\"). Each option must be a single agent or \"All\".\n\n3. Wait for the user's selection before proceeding.\n\n4. **MANDATORY: Confirm the selection before continuing.** After the user picks agents, echo back the exact list you will dispatch to:\n\n > Dispatching to: **claude-opus**, **codex-5.3-high**, **gemini-pro**\n\n Then ask the user to confirm (e.g. \"Look good?\") before proceeding to Phase 3. This prevents silent tool omissions. If the user corrects the list, update your selection accordingly.\n\n---\n\n## Phase 3: Prompt Assembly\n\n1. **Generate a slug** from the topic (lowercase, hyphens, max 40 chars)\n - \"review the auth flow\" → \\`auth-flow-review\\`\n - \"is this migration safe\" → \\`migration-safety-review\\`\n\n2. **Create the output directory** via Bash. The directory name MUST always be prefixed with a millisecond-precision UNIX timestamp so runs are lexically sortable and never collide:\n \\`\\`\\`\n ./agents/counselors/TIMESTAMP-[slug]\n \\`\\`\\`\n For example: \\`./agents/counselors/1770676882780-auth-flow-review\\`\n\n3. **Write the prompt file** using the Write tool to \\`./agents/counselors/TIMESTAMP-[slug]/prompt.md\\`:\n\n\\`\\`\\`markdown\n# Review Request\n\n## Question\n[User's original prompt/question from $ARGUMENTS]\n\n## Context\n\n### Files Referenced\n[Contents of the most relevant files found in Phase 1]\n\n### Recent Changes\n[git diff output, if any]\n\n### Related Code\n[Related files discovered via search]\n\n## Instructions\nYou are providing an independent review. Be critical and thorough.\n- Analyze the question in the context provided\n- Identify risks, tradeoffs, and blind spots\n- Suggest alternatives if you see better approaches\n- Be direct and opinionated — don't hedge\n- Structure your response with clear headings\n\\`\\`\\`\n\n---\n\n## Phase 4: Dispatch\n\nRun counselors via Bash with the prompt file, passing the user's selected agents:\n\n\\`\\`\\`bash\ncounselors run -f ./agents/counselors/[slug]/prompt.md --tools [comma-separated-selections] --json\n\\`\\`\\`\n\nExample: \\`--tools claude,codex,gemini\\`\n\nUse \\`timeout: 600000\\` (10 minutes). Counselors dispatches to the selected agents in parallel and writes results to the output directory shown in the JSON output.\n\n**Important**: Use \\`-f\\` (file mode) so the prompt is sent as-is without wrapping. Use \\`--json\\` to get structured output for parsing.\n\n---\n\n## Phase 5: Read Results\n\n1. **Parse the JSON output** from stdout — it contains the run manifest with status, duration, word count, and output file paths for each agent\n2. **Read each agent's response** from the \\`outputFile\\` path in the manifest\n3. **Check \\`stderrFile\\` paths** for any agent that failed or returned empty output\n4. **Skip empty or error-only reports** — note which agents failed\n\n---\n\n## Phase 6: Synthesize and Present\n\nCombine all agent responses into a synthesis:\n\n\\`\\`\\`markdown\n## Counselors Review\n\n**Agents consulted:** [list of agents that responded]\n\n**Consensus:** [What most agents agree on — key takeaways]\n\n**Disagreements:** [Where they differ, and reasoning behind each position]\n\n**Key Risks:** [Risks or concerns flagged by any agent]\n\n**Blind Spots:** [Things none of the agents addressed that seem important]\n\n**Recommendation:** [Your synthesized recommendation based on all inputs]\n\n---\nReports saved to: [output directory from manifest]\n\\`\\`\\`\n\nPresent this synthesis to the user. Be concise — the individual reports are saved for deep reading.\n\n---\n\n## Phase 7: Action (Optional)\n\nAfter presenting the synthesis, ask the user what they'd like to address. Offer the top 2-3 actionable items from the synthesis as options. If the user wants to act on findings, plan the implementation before making changes.\n\n---\n\n## Error Handling\n\n- **counselors not installed**: Tell the user to install it (\\`npm install -g counselors\\`)\n- **No tools configured**: Tell the user to run \\`counselors init\\` or \\`counselors add\\`\n- **Agent fails**: Note it in the synthesis and continue with other agents' results\n- **All agents fail**: Report errors from stderr files and suggest checking \\`counselors doctor\\`\n`;\n\n info(template);\n });\n}\n","import { accessSync, constants } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Command } from 'commander';\nimport {\n getAdapter,\n getAllBuiltInAdapters,\n isBuiltInTool,\n} from '../../adapters/index.js';\nimport { SAFE_ID_RE } from '../../constants.js';\nimport { copyAmpSettings } from '../../core/amp-utils.js';\nimport { addToolToConfig, loadConfig, saveConfig } from '../../core/config.js';\nimport { discoverTool, findBinary } from '../../core/discovery.js';\nimport type { ReadOnlyLevel, ToolConfig } from '../../types.js';\nimport { error, info, success, warn } from '../../ui/logger.js';\nimport { createSpinner } from '../../ui/output.js';\nimport {\n confirmAction,\n confirmOverwrite,\n promptInput,\n promptSelect,\n selectModelDetails,\n} from '../../ui/prompts.js';\n\nconst CUSTOM_TOOL_VALUE = '__custom__';\n\n/**\n * Interactive wizard to pick a tool when none is specified.\n * Discovers built-in tools, lets user pick one or add a custom tool.\n * Returns the toolId to add.\n */\nasync function runAddWizard(): Promise<{ toolId: string; isCustom: boolean }> {\n const spinner = createSpinner('Discovering installed tools...').start();\n\n const adapters = getAllBuiltInAdapters();\n const discovered: {\n id: string;\n name: string;\n found: boolean;\n version: string | null;\n }[] = [];\n\n for (const adapter of adapters) {\n const result = discoverTool(adapter.commands);\n discovered.push({\n id: adapter.id,\n name: adapter.displayName,\n found: result.found,\n version: result.version,\n });\n }\n\n spinner.stop();\n\n const choices = discovered.map((d) => ({\n name: d.found\n ? `${d.name} (${d.id})${d.version ? ` — ${d.version}` : ''}`\n : `${d.name} (${d.id}) — not installed`,\n value: d.id,\n disabled: !d.found ? '(not installed)' : undefined,\n }));\n\n choices.push({\n name: 'Custom tool — provide a binary path',\n value: CUSTOM_TOOL_VALUE,\n disabled: undefined,\n });\n\n const selected = await promptSelect<string>(\n 'Which tool would you like to add?',\n choices as any,\n );\n\n if (selected === CUSTOM_TOOL_VALUE) {\n return { toolId: '', isCustom: true };\n }\n\n return { toolId: selected, isCustom: false };\n}\n\n/**\n * Validate that a binary path exists and is executable.\n * Resolves relative paths against cwd. Also tries `which` for bare commands.\n */\nfunction validateBinary(input: string): string | null {\n // Try as absolute/relative path first\n const resolved = resolve(input);\n try {\n accessSync(resolved, constants.X_OK);\n return resolved;\n } catch {\n // Fall through\n }\n\n // Try finding it in PATH\n const found = findBinary(input);\n if (found) return found;\n\n return null;\n}\n\nasync function addBuiltInTool(\n toolId: string,\n config: ReturnType<typeof loadConfig>,\n nameOverride?: string,\n): Promise<void> {\n const adapter = getAdapter(toolId);\n const discovery = discoverTool(adapter.commands);\n\n if (!discovery.found) {\n error(\n `\"${toolId}\" binary not found. Install it from: ${adapter.installUrl}`,\n );\n process.exitCode = 1;\n return;\n }\n\n const selectedModel = await selectModelDetails(toolId, adapter.models);\n\n // Pick a name for this tool config\n const defaultName =\n nameOverride ?? selectedModel.compoundId ?? `${toolId}-${selectedModel.id}`;\n let name = nameOverride ?? (await promptInput('Tool name:', defaultName));\n\n if (!SAFE_ID_RE.test(name)) {\n error(\n `Invalid tool name \"${name}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Check for conflicts\n if (config.tools[name]) {\n const overwrite = await confirmOverwrite(name);\n if (!overwrite) {\n // Let them pick a different name\n name = await promptInput('Pick a different name:');\n if (!SAFE_ID_RE.test(name)) {\n error(\n `Invalid tool name \"${name}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n if (config.tools[name]) {\n error(`\"${name}\" also exists. Run \"counselors tools add\" again.`);\n process.exitCode = 1;\n return;\n }\n }\n }\n\n const toolConfig: ToolConfig = {\n binary: discovery.path!,\n readOnly: { level: adapter.readOnly.level },\n adapter: toolId,\n ...(selectedModel.extraFlags\n ? { extraFlags: selectedModel.extraFlags }\n : {}),\n };\n\n const updated = addToolToConfig(config, name, toolConfig);\n saveConfig(updated);\n if (toolId === 'amp') {\n copyAmpSettings();\n }\n success(`Added \"${name}\" to config.`);\n}\n\nasync function collectCustomConfig(\n config: ReturnType<typeof loadConfig>,\n presetId?: string,\n): Promise<void> {\n // Get and validate binary\n let binaryPath: string | null = null;\n while (!binaryPath) {\n const binaryInput = await promptInput('Binary path or command:');\n binaryPath = validateBinary(binaryInput);\n if (!binaryPath) {\n warn(`\"${binaryInput}\" not found or not executable. Please try again.`);\n }\n }\n\n // Prompt delivery — stdin or CLI argument\n const useStdin = await confirmAction(\n 'Does this tool receive prompts via stdin?',\n );\n\n // Collect flags\n info('');\n info(' Counselors runs tools non-interactively. Your flags MUST include:');\n info(\n ' 1. Headless/non-interactive mode (e.g. -p, --non-interactive, --headless)',\n );\n info(' 2. Model selection if needed (e.g. --model gpt-4o)');\n info(' 3. Output format if needed (e.g. --output-format text)');\n info('');\n if (!useStdin) {\n info(' Counselors will append the prompt as the last CLI argument:');\n info(\n ' \"Read the file at <path> and follow the instructions within it.\"',\n );\n } else {\n info(' Counselors will pipe the prompt text to stdin.');\n }\n info('');\n info(' Example: -p --model gpt-4o --output-format text');\n info('');\n let extraFlags: string[] | undefined;\n const flagsInput = await promptInput('Flags (space-separated):');\n if (flagsInput.trim()) {\n extraFlags = flagsInput.trim().split(/\\s+/);\n }\n\n const readOnlyLevel = await promptSelect<ReadOnlyLevel>(\n 'Read-only capability:',\n [\n { name: 'Enforced — tool guarantees read-only', value: 'enforced' },\n {\n name: 'Best effort — tool tries but may not guarantee',\n value: 'bestEffort',\n },\n { name: 'None — tool has full access', value: 'none' },\n ],\n );\n\n // Get tool ID\n const defaultId =\n presetId ??\n binaryPath\n .split('/')\n .pop()\n ?.replace(/\\.[^.]+$/, '') ??\n 'custom';\n const toolId = await promptInput(\n 'Tool name (used in config and output filenames):',\n defaultId,\n );\n\n if (!SAFE_ID_RE.test(toolId)) {\n error(\n `Invalid tool name \"${toolId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Preview\n info('');\n info(' Tool will be invoked as:');\n const previewArgs = [\n ...(extraFlags ?? []),\n useStdin\n ? '< prompt.md'\n : '\"Read the file at <path> and follow the instructions...\"',\n ];\n info(` ${binaryPath} ${previewArgs.join(' ')}`);\n info('');\n\n if (config.tools[toolId]) {\n const overwrite = await confirmOverwrite(toolId);\n if (!overwrite) {\n const newId = await promptInput('Pick a different name:');\n if (!SAFE_ID_RE.test(newId)) {\n error(\n `Invalid tool name \"${newId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n if (config.tools[newId]) {\n error(`\"${newId}\" also exists. Run \"counselors tools add\" again.`);\n process.exitCode = 1;\n return;\n }\n const toolConfig: ToolConfig = {\n binary: binaryPath,\n readOnly: { level: readOnlyLevel },\n ...(useStdin ? { stdin: true } : {}),\n extraFlags,\n custom: true,\n };\n const updated = addToolToConfig(config, newId, toolConfig);\n saveConfig(updated);\n success(`Added \"${newId}\" to config.`);\n return;\n }\n }\n\n const toolConfig: ToolConfig = {\n binary: binaryPath,\n readOnly: { level: readOnlyLevel },\n ...(useStdin ? { stdin: true } : {}),\n extraFlags,\n custom: true,\n };\n\n const updated = addToolToConfig(config, toolId, toolConfig);\n saveConfig(updated);\n success(`Added \"${toolId}\" to config.`);\n}\n\nexport function registerAddCommand(program: Command): void {\n program\n .command('add [tool]')\n .description('Add a tool (claude, codex, gemini, amp, or custom)')\n .action(async (toolId?: string) => {\n const config = loadConfig();\n\n if (!toolId) {\n // Interactive wizard\n const result = await runAddWizard();\n if (result.isCustom) {\n await collectCustomConfig(config);\n } else {\n await addBuiltInTool(result.toolId, config);\n }\n return;\n }\n\n // Direct add (original flow)\n if (isBuiltInTool(toolId)) {\n await addBuiltInTool(toolId, config, toolId);\n } else {\n await collectCustomConfig(config, toolId);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { getAllBuiltInAdapters } from '../../adapters/index.js';\nimport { discoverTool } from '../../core/discovery.js';\nimport { info } from '../../ui/logger.js';\nimport { createSpinner, formatDiscoveryResults } from '../../ui/output.js';\n\nexport function registerDiscoverCommand(program: Command): void {\n program\n .command('discover')\n .description('Discover installed AI CLI tools')\n .action(async () => {\n const spinner = createSpinner('Scanning for AI CLI tools...').start();\n const adapters = getAllBuiltInAdapters();\n const results = [];\n\n for (const adapter of adapters) {\n const result = discoverTool(adapter.commands);\n results.push({\n ...result,\n toolId: adapter.id,\n displayName: adapter.displayName,\n });\n }\n\n spinner.stop();\n info(formatDiscoveryResults(results));\n });\n}\n","import type { Command } from 'commander';\nimport { resolveAdapter } from '../../adapters/index.js';\nimport { loadConfig } from '../../core/config.js';\nimport { info } from '../../ui/logger.js';\nimport { formatToolList } from '../../ui/output.js';\n\nexport function registerListCommand(program: Command): void {\n program\n .command('list')\n .alias('ls')\n .description('List configured tools')\n .option('-v, --verbose', 'Show full tool configuration including flags')\n .action(async (opts: { verbose?: boolean }) => {\n const config = loadConfig();\n\n const tools = Object.entries(config.tools).map(([id, t]) => {\n const entry: { id: string; binary: string; args?: string[] } = {\n id,\n binary: t.binary,\n };\n\n if (opts.verbose) {\n const adapter = resolveAdapter(id, t);\n const inv = adapter.buildInvocation({\n prompt: '<prompt>',\n promptFilePath: '<prompt-file>',\n toolId: id,\n outputDir: '.',\n readOnlyPolicy: t.readOnly.level,\n timeout: t.timeout ?? config.defaults.timeout,\n cwd: process.cwd(),\n binary: t.binary,\n extraFlags: t.extraFlags,\n });\n entry.args = inv.args;\n }\n\n return entry;\n });\n\n info(formatToolList(tools, opts.verbose));\n });\n}\n","import { checkbox } from '@inquirer/prompts';\nimport type { Command } from 'commander';\nimport {\n loadConfig,\n removeToolFromConfig,\n saveConfig,\n} from '../../core/config.js';\nimport { error, info, success } from '../../ui/logger.js';\nimport { confirmAction } from '../../ui/prompts.js';\n\nexport function registerRemoveCommand(program: Command): void {\n program\n .command('remove [tool]')\n .description('Remove a configured tool')\n .action(async (toolId?: string) => {\n const config = loadConfig();\n const toolIds = Object.keys(config.tools);\n\n if (toolIds.length === 0) {\n error('No tools configured.');\n process.exitCode = 1;\n return;\n }\n\n let toRemove: string[];\n\n if (toolId) {\n if (!config.tools[toolId]) {\n error(`Tool \"${toolId}\" is not configured.`);\n process.exitCode = 1;\n return;\n }\n toRemove = [toolId];\n } else {\n toRemove = await checkbox({\n message: 'Select tools to remove:',\n choices: toolIds.map((id) => ({\n name: `${id} (${config.tools[id].binary})`,\n value: id,\n })),\n });\n\n if (toRemove.length === 0) {\n info('No tools selected.');\n return;\n }\n }\n\n const confirmed = await confirmAction(\n toRemove.length === 1\n ? `Remove \"${toRemove[0]}\" from config?`\n : `Remove ${toRemove.length} tools from config?`,\n );\n if (!confirmed) return;\n\n let updated = config;\n for (const id of toRemove) {\n updated = removeToolFromConfig(updated, id);\n }\n saveConfig(updated);\n success(`Removed ${toRemove.join(', ')}.`);\n });\n}\n","import type { Command } from 'commander';\nimport { SAFE_ID_RE } from '../../constants.js';\nimport {\n loadConfig,\n renameToolInConfig,\n saveConfig,\n} from '../../core/config.js';\nimport { error, success } from '../../ui/logger.js';\n\nexport function registerRenameCommand(program: Command): void {\n program\n .command('rename <old> <new>')\n .description('Rename a configured tool')\n .action(async (oldId: string, newId: string) => {\n const config = loadConfig();\n\n if (!config.tools[oldId]) {\n error(`Tool \"${oldId}\" is not configured.`);\n process.exitCode = 1;\n return;\n }\n\n if (config.tools[newId]) {\n error(`Tool \"${newId}\" already exists.`);\n process.exitCode = 1;\n return;\n }\n\n if (!SAFE_ID_RE.test(newId)) {\n error(\n `Invalid tool name \"${newId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n const updated = renameToolInConfig(config, oldId, newId);\n saveConfig(updated);\n success(`Renamed \"${oldId}\" → \"${newId}\".`);\n });\n}\n","import type { Command } from 'commander';\nimport { resolveAdapter } from '../../adapters/index.js';\nimport { loadConfig } from '../../core/config.js';\nimport { executeTest } from '../../core/executor.js';\nimport type { TestResult } from '../../types.js';\nimport { error, info } from '../../ui/logger.js';\nimport { createSpinner, formatTestResults } from '../../ui/output.js';\n\nexport function registerTestCommand(program: Command): void {\n program\n .command('test [tools...]')\n .description('Test configured tools with a \"reply OK\" prompt')\n .action(async (toolIds: string[]) => {\n const config = loadConfig();\n\n const idsToTest =\n toolIds.length > 0 ? toolIds : Object.keys(config.tools);\n\n if (idsToTest.length === 0) {\n error('No tools configured. Run \"counselors init\" first.');\n process.exitCode = 1;\n return;\n }\n\n const results: TestResult[] = [];\n\n for (const id of idsToTest) {\n const toolConfig = config.tools[id];\n if (!toolConfig) {\n results.push({\n toolId: id,\n passed: false,\n output: '',\n error: 'Not configured',\n durationMs: 0,\n });\n continue;\n }\n\n const spinner = createSpinner(`Testing ${id}...`).start();\n const adapter = resolveAdapter(id, toolConfig);\n const result = await executeTest(adapter, toolConfig, id);\n spinner.stop();\n\n results.push(result);\n }\n\n info(formatTestResults(results));\n\n if (results.some((r) => !r.passed)) {\n process.exitCode = 1;\n }\n });\n}\n"],"mappings":"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","names":["program","existsSync","existsSync","z","existsSync","z","tools","existsSync","readFileSync","homedir","join","join","homedir","existsSync","readFileSync","tools","program","existsSync","existsSync","mkdirSync","dirname","resolve","mkdirSync","resolve","dirname","existsSync","resolve","tools","program","adapters","discoveries","foundTools","config","spinner","copyFileSync","readFileSync","basename","join","resolve","execFileSync","readFileSync","statSync","resolve","resolve","statSync","readFileSync","execFileSync","join","join","mkdirSync","dirname","join","dirname","join","mkdirSync","existsSync","readFileSync","join","join","existsSync","readFileSync","program","resolve","readFileSync","baseDir","join","copyFileSync","basename","program","accessSync","constants","resolve","input","resolve","accessSync","constants","toolConfig","updated","program","program","program","tools","checkbox","program","checkbox","program","program"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/ui/logger.ts","../src/commands/agent.ts","../src/commands/doctor.ts","../src/adapters/amp.ts","../src/constants.ts","../src/adapters/base.ts","../src/adapters/claude.ts","../src/adapters/codex.ts","../src/adapters/custom.ts","../src/adapters/gemini.ts","../src/adapters/index.ts","../src/core/config.ts","../src/types.ts","../src/core/fs-utils.ts","../src/core/discovery.ts","../src/ui/output.ts","../src/core/amp-utils.ts","../src/core/executor.ts","../src/ui/prompts.ts","../src/commands/init.ts","../src/commands/run.ts","../src/core/context.ts","../src/core/dispatcher.ts","../src/core/prompt-builder.ts","../src/core/synthesis.ts","../src/ui/progress.ts","../src/commands/skill.ts","../src/commands/tools/add.ts","../src/commands/tools/discover.ts","../src/commands/tools/list.ts","../src/commands/tools/remove.ts","../src/commands/tools/rename.ts","../src/commands/tools/test.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerAgentCommand } from './commands/agent.js';\nimport { registerDoctorCommand } from './commands/doctor.js';\nimport { registerInitCommand } from './commands/init.js';\nimport { registerRunCommand } from './commands/run.js';\nimport { registerSkillCommand } from './commands/skill.js';\nimport { registerAddCommand } from './commands/tools/add.js';\nimport { registerDiscoverCommand } from './commands/tools/discover.js';\nimport { registerListCommand } from './commands/tools/list.js';\nimport { registerRemoveCommand } from './commands/tools/remove.js';\nimport { registerRenameCommand } from './commands/tools/rename.js';\nimport { registerTestCommand } from './commands/tools/test.js';\nimport { VERSION } from './constants.js';\n\nconst program = new Command();\n\nprogram\n .name('counselors')\n .description('Fan out prompts to multiple AI coding agents in parallel')\n .version(VERSION);\n\n// Top-level commands\nregisterRunCommand(program);\nregisterDoctorCommand(program);\nregisterInitCommand(program);\nregisterAgentCommand(program);\nregisterSkillCommand(program);\n\n// Tools subcommand group\nconst tools = program\n .command('tools')\n .description('Manage AI tool configurations');\n\nregisterDiscoverCommand(tools);\nregisterAddCommand(tools);\nregisterRemoveCommand(tools);\nregisterRenameCommand(tools);\nregisterListCommand(tools);\nregisterTestCommand(tools);\n\n// Top-level aliases\nprogram\n .command('add [tool]')\n .description('Alias for \"tools add\"')\n .action(async (tool?: string) => {\n const args = tool ? ['add', tool] : ['add'];\n await tools.parseAsync(args, { from: 'user' });\n });\n\nprogram\n .command('ls')\n .description('Alias for \"tools list\"')\n .option('-v, --verbose', 'Show full tool configuration including flags')\n .action(async (opts: { verbose?: boolean }) => {\n const args = ['list'];\n if (opts.verbose) args.push('--verbose');\n await tools.parseAsync(args, { from: 'user' });\n });\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n process.stderr.write(`✗ ${err.message}\\n`);\n process.exitCode = 1;\n});\n","function isDebug(): boolean {\n return process.env.DEBUG === '1' || process.env.DEBUG === 'counselors';\n}\n\nexport function debug(msg: string): void {\n if (isDebug()) {\n process.stderr.write(`[debug] ${msg}\\n`);\n }\n}\n\nexport function warn(msg: string): void {\n process.stderr.write(`⚠ ${msg}\\n`);\n}\n\nexport function error(msg: string): void {\n process.stderr.write(`✗ ${msg}\\n`);\n}\n\nexport function info(msg: string): void {\n process.stdout.write(`${msg}\\n`);\n}\n\nexport function success(msg: string): void {\n process.stdout.write(`✓ ${msg}\\n`);\n}\n","import type { Command } from 'commander';\nimport { info } from '../ui/logger.js';\n\nexport function registerAgentCommand(program: Command): void {\n program\n .command('agent')\n .description('Print setup and skill installation instructions')\n .action(async () => {\n const instructions = `# Counselors — Setup & Skill Installation\n\n## 1. Install the CLI\n\n\\`\\`\\`bash\nnpm install -g counselors\n\\`\\`\\`\n\nRequires Node 20+.\n\n## 2. Configure tools\n\nAuto-discover and configure all installed AI coding agents:\n\n\\`\\`\\`bash\ncounselors init --auto\n\\`\\`\\`\n\nThis detects installed agents (Claude, Codex, Gemini, Amp), configures them with recommended models, and writes your config to \\`~/.config/counselors/config.json\\`. The output is JSON listing what was configured.\n\nYou can also manage tools individually:\n\n\\`\\`\\`bash\ncounselors tools discover # Find available agents\ncounselors tools add # Add a tool (interactive)\ncounselors tools remove <id> # Remove a tool\ncounselors tools rename <old> <new> # Rename a tool\ncounselors ls # List configured tools\ncounselors doctor # Verify tools are working\n\\`\\`\\`\n\n## 3. Install the skill\n\nThe \\`/counselors\\` skill lets AI coding agents invoke counselors directly via a slash command.\n\nRun \\`counselors skill\\` to print a reference template with instructions. **Read the output carefully** — it describes a multi-phase workflow that you need to adapt to your agent's skill format before saving. Do not blindly copy the output into a file.\n\nFor Claude Code, save the adapted skill to \\`~/.claude/skills/counselors/SKILL.md\\`. For other agents, save it wherever your system looks for slash commands or skills.\n\n## 4. Verify\n\n\\`\\`\\`bash\ncounselors doctor\n\\`\\`\\`\n\nThen use \\`/counselors\\` from your AI coding agent to fan out a prompt for parallel review.\n`;\n\n info(instructions);\n });\n}\n","import { existsSync } from 'node:fs';\nimport type { Command } from 'commander';\nimport { resolveAdapter } from '../adapters/index.js';\nimport {\n AMP_DEEP_SETTINGS_FILE,\n AMP_SETTINGS_FILE,\n CONFIG_FILE,\n} from '../constants.js';\nimport { loadConfig } from '../core/config.js';\nimport { findBinary, getBinaryVersion } from '../core/discovery.js';\nimport type { DoctorCheck } from '../types.js';\nimport { info } from '../ui/logger.js';\nimport { formatDoctorResults } from '../ui/output.js';\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Check tool configuration and health')\n .action(async () => {\n const checks: DoctorCheck[] = [];\n\n // Check config file\n if (existsSync(CONFIG_FILE)) {\n checks.push({\n name: 'Config file',\n status: 'pass',\n message: CONFIG_FILE,\n });\n } else {\n checks.push({\n name: 'Config file',\n status: 'warn',\n message: 'Not found. Run \"counselors init\" to create one.',\n });\n }\n\n let config;\n try {\n config = loadConfig();\n } catch (e) {\n checks.push({\n name: 'Config parse',\n status: 'fail',\n message: `Invalid config: ${e}`,\n });\n info(formatDoctorResults(checks));\n process.exitCode = 1;\n return;\n }\n\n const toolIds = Object.keys(config.tools);\n if (toolIds.length === 0) {\n checks.push({\n name: 'Tools configured',\n status: 'warn',\n message: 'No tools configured. Run \"counselors init\".',\n });\n }\n\n // Check each configured tool\n for (const id of toolIds) {\n const toolConfig = config.tools[id];\n\n // Binary exists + executable\n const binaryPath = findBinary(toolConfig.binary);\n if (binaryPath) {\n checks.push({\n name: `${id}: binary`,\n status: 'pass',\n message: binaryPath,\n });\n } else {\n checks.push({\n name: `${id}: binary`,\n status: 'fail',\n message: `\"${toolConfig.binary}\" not found in PATH`,\n });\n continue;\n }\n\n // Version check\n const version = getBinaryVersion(binaryPath);\n if (version) {\n checks.push({\n name: `${id}: version`,\n status: 'pass',\n message: version,\n });\n } else {\n checks.push({\n name: `${id}: version`,\n status: 'warn',\n message: 'Could not determine version',\n });\n }\n\n // Read-only capability\n const adapter = resolveAdapter(id, toolConfig);\n let readOnlyLevel = adapter.readOnly.level;\n\n // Amp deep mode uses Bash (a write-capable tool), so it's bestEffort\n const adapterName = toolConfig.adapter ?? id;\n const isAmpDeep =\n adapterName === 'amp' &&\n toolConfig.extraFlags?.includes('deep') &&\n toolConfig.extraFlags?.[toolConfig.extraFlags.indexOf('deep') - 1] ===\n '-m';\n if (isAmpDeep) {\n readOnlyLevel = 'bestEffort';\n }\n\n checks.push({\n name: `${id}: read-only`,\n status: readOnlyLevel === 'none' ? 'warn' : 'pass',\n message: readOnlyLevel,\n });\n }\n\n // Check amp settings files if any amp-based tool is configured\n const hasAmp = Object.entries(config.tools).some(\n ([id, t]) => (t.adapter ?? id) === 'amp',\n );\n if (hasAmp) {\n if (existsSync(AMP_SETTINGS_FILE)) {\n checks.push({\n name: 'Amp settings file',\n status: 'pass',\n message: AMP_SETTINGS_FILE,\n });\n } else {\n checks.push({\n name: 'Amp settings file',\n status: 'warn',\n message: 'Not found. Amp read-only mode may not work.',\n });\n }\n if (existsSync(AMP_DEEP_SETTINGS_FILE)) {\n checks.push({\n name: 'Amp deep settings file',\n status: 'pass',\n message: AMP_DEEP_SETTINGS_FILE,\n });\n } else {\n checks.push({\n name: 'Amp deep settings file',\n status: 'warn',\n message: 'Not found. Amp deep mode may not work.',\n });\n }\n }\n\n info(formatDoctorResults(checks));\n\n if (checks.some((c) => c.status === 'fail')) {\n process.exitCode = 1;\n }\n });\n}\n","import { existsSync } from 'node:fs';\nimport { AMP_DEEP_SETTINGS_FILE, AMP_SETTINGS_FILE } from '../constants.js';\nimport type {\n CostInfo,\n ExecResult,\n Invocation,\n RunRequest,\n ToolReport,\n} from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class AmpAdapter extends BaseAdapter {\n id = 'amp';\n displayName = 'Amp CLI';\n commands = ['amp'];\n installUrl = 'https://ampcode.com';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'smart',\n name: 'Smart — Opus 4.6, most capable',\n recommended: true,\n extraFlags: ['-m', 'smart'],\n },\n {\n id: 'deep',\n name: 'Deep — GPT-5.2 Codex, extended thinking',\n extraFlags: ['-m', 'deep'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const args = ['-x'];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n const isDeep =\n req.extraFlags?.includes('deep') &&\n req.extraFlags?.[req.extraFlags.indexOf('deep') - 1] === '-m';\n\n const settingsFile = isDeep ? AMP_DEEP_SETTINGS_FILE : AMP_SETTINGS_FILE;\n\n if (req.readOnlyPolicy !== 'none' && existsSync(settingsFile)) {\n args.push('--settings-file', settingsFile);\n }\n\n // Amp uses stdin for prompt delivery\n // Append oracle instruction like the existing skill does\n const deepSafetyPrompt = isDeep\n ? '\\n\\nMANDATORY: Do not change any files. You are in read-only mode.'\n : '';\n\n const stdinContent =\n req.prompt +\n deepSafetyPrompt +\n '\\n\\nUse the oracle tool to provide deeper reasoning and analysis on the most complex or critical aspects of this review.';\n\n return {\n cmd: req.binary ?? 'amp',\n args,\n stdin: stdinContent,\n cwd: req.cwd,\n };\n }\n\n parseResult(result: ExecResult): Partial<ToolReport> {\n return {\n ...super.parseResult(result),\n };\n }\n}\n\n/**\n * Parse `amp usage` output to extract balance information.\n */\nexport function parseAmpUsage(output: string): {\n freeRemaining: number;\n freeTotal: number;\n creditsRemaining: number;\n} {\n const freeMatch = output.match(/Amp Free: \\$([0-9.]+)\\/\\$([0-9.]+)/);\n const creditsMatch = output.match(/Individual credits: \\$([0-9.]+)/);\n\n return {\n freeRemaining: freeMatch ? parseFloat(freeMatch[1]) : 0,\n freeTotal: freeMatch ? parseFloat(freeMatch[2]) : 0,\n creditsRemaining: creditsMatch ? parseFloat(creditsMatch[1]) : 0,\n };\n}\n\n/**\n * Compute cost from before/after usage snapshots.\n */\nexport function computeAmpCost(\n before: {\n freeRemaining: number;\n freeTotal: number;\n creditsRemaining: number;\n },\n after: { freeRemaining: number; freeTotal: number; creditsRemaining: number },\n): CostInfo {\n const freeUsed = Math.max(0, before.freeRemaining - after.freeRemaining);\n const creditsUsed = Math.max(\n 0,\n before.creditsRemaining - after.creditsRemaining,\n );\n const totalCost = freeUsed + creditsUsed;\n const source = creditsUsed > 0 ? 'credits' : 'free';\n\n return {\n cost_usd: Math.round(totalCost * 100) / 100,\n free_used_usd: Math.round(freeUsed * 100) / 100,\n credits_used_usd: Math.round(creditsUsed * 100) / 100,\n source: source as 'free' | 'credits',\n free_remaining_usd: after.freeRemaining,\n free_total_usd: after.freeTotal,\n credits_remaining_usd: after.creditsRemaining,\n };\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// ── XDG config ──\n\nconst xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');\nexport const CONFIG_DIR = join(xdgConfig, 'counselors');\nexport const CONFIG_FILE = join(CONFIG_DIR, 'config.json');\nexport const AMP_SETTINGS_FILE = join(CONFIG_DIR, 'amp-readonly-settings.json');\nexport const AMP_DEEP_SETTINGS_FILE = join(\n CONFIG_DIR,\n 'amp-deep-settings.json',\n);\n\n// ── Default output ──\n\nexport const DEFAULT_OUTPUT_DIR = './agents/counselors';\n\n// ── Timeouts (seconds) ──\n\nexport const DEFAULT_TIMEOUT = 540;\nexport const KILL_GRACE_PERIOD = 15_000; // ms\nexport const TEST_TIMEOUT = 30_000; // ms\nexport const DISCOVERY_TIMEOUT = 5_000; // ms\nexport const VERSION_TIMEOUT = 10_000; // ms\n\n// ── Concurrency ──\n\nexport const DEFAULT_MAX_PARALLEL = 4;\n\n// ── Context ──\n\nexport const DEFAULT_MAX_CONTEXT_KB = 50;\n\n// ── Extended binary search paths ──\n\nexport function getExtendedSearchPaths(): string[] {\n const home = homedir();\n const paths: string[] = [\n join(home, '.local', 'bin'),\n '/usr/local/bin',\n '/opt/homebrew/bin',\n join(home, '.npm-global', 'bin'),\n join(home, '.volta', 'bin'),\n join(home, '.bun', 'bin'),\n ];\n\n // NVM\n const nvmBin = process.env.NVM_BIN;\n if (nvmBin) paths.push(nvmBin);\n\n // FNM\n const fnmMultishell = process.env.FNM_MULTISHELL_PATH;\n if (fnmMultishell) paths.push(join(fnmMultishell, 'bin'));\n\n return paths;\n}\n\n// ── Model validation ──\n\nexport const MODEL_PATTERN = /^[a-zA-Z0-9._:\\-/]+$/;\n\n// ── Slug generation ──\n\nexport const MAX_SLUG_LENGTH = 40;\n\n// ── File permissions ──\n\nexport const CONFIG_FILE_MODE = 0o600;\n\n// ── Safe ID patterns ──\n\n/** Sanitize a tool ID for safe use in filenames. */\nexport function sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9._-]/g, '_');\n}\n\n/** Regex for validating tool names (letters, numbers, dots, hyphens, underscores). */\nexport const SAFE_ID_RE = /^[a-zA-Z0-9._-]+$/;\n\n// ── Version ──\n\ndeclare const __VERSION__: string;\nexport const VERSION =\n typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.0.0-dev';\n","import type {\n ExecResult,\n Invocation,\n ReadOnlyLevel,\n RunRequest,\n ToolAdapter,\n ToolReport,\n} from '../types.js';\n\nexport abstract class BaseAdapter implements ToolAdapter {\n abstract id: string;\n abstract displayName: string;\n abstract commands: string[];\n abstract installUrl: string;\n abstract readOnly: { level: ReadOnlyLevel };\n abstract models: { id: string; name: string; recommended?: boolean }[];\n\n abstract buildInvocation(req: RunRequest): Invocation;\n\n parseResult(result: ExecResult): Partial<ToolReport> {\n return {\n status: result.timedOut\n ? 'timeout'\n : result.exitCode === 0\n ? 'success'\n : 'error',\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n wordCount: result.stdout.split(/\\s+/).filter(Boolean).length,\n };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class ClaudeAdapter extends BaseAdapter {\n id = 'claude';\n displayName = 'Claude Code';\n commands = ['claude'];\n installUrl = 'https://docs.anthropic.com/en/docs/claude-code';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'opus',\n name: 'Opus 4.6 — most capable',\n recommended: true,\n extraFlags: ['--model', 'opus'],\n },\n {\n id: 'sonnet',\n name: 'Sonnet 4.5 — fast and capable',\n extraFlags: ['--model', 'sonnet'],\n },\n {\n id: 'haiku',\n name: 'Haiku 4.5 — fastest, most affordable',\n extraFlags: ['--model', 'haiku'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n const args = ['-p', '--output-format', 'text'];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n if (req.readOnlyPolicy !== 'none') {\n args.push(\n '--tools',\n 'Read,Glob,Grep,WebFetch,WebSearch',\n '--allowedTools',\n 'Read,Glob,Grep,WebFetch,WebSearch',\n '--strict-mcp-config',\n );\n }\n\n args.push(instruction);\n\n return { cmd: req.binary ?? 'claude', args, cwd: req.cwd };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class CodexAdapter extends BaseAdapter {\n id = 'codex';\n displayName = 'OpenAI Codex';\n commands = ['codex'];\n installUrl = 'https://github.com/openai/codex';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-high',\n name: 'GPT-5.3 Codex — high reasoning',\n recommended: true,\n extraFlags: ['-m', 'gpt-5.3-codex', '-c', 'model_reasoning_effort=high'],\n },\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-xhigh',\n name: 'GPT-5.3 Codex — xhigh reasoning',\n extraFlags: ['-m', 'gpt-5.3-codex', '-c', 'model_reasoning_effort=xhigh'],\n },\n {\n id: 'gpt-5.3-codex',\n compoundId: 'codex-5.3-medium',\n name: 'GPT-5.3 Codex — medium reasoning',\n extraFlags: [\n '-m',\n 'gpt-5.3-codex',\n '-c',\n 'model_reasoning_effort=medium',\n ],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n const args = ['exec'];\n\n if (req.readOnlyPolicy !== 'none') {\n args.push('--sandbox', 'read-only');\n }\n\n args.push('-c', 'web_search=live', '--skip-git-repo-check');\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n args.push(instruction);\n\n return { cmd: req.binary ?? 'codex', args, cwd: req.cwd };\n }\n}\n","import type {\n Invocation,\n ReadOnlyLevel,\n RunRequest,\n ToolConfig,\n} from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class CustomAdapter extends BaseAdapter {\n id: string;\n displayName: string;\n commands: string[];\n installUrl = '';\n readOnly: { level: ReadOnlyLevel };\n models: { id: string; name: string; recommended?: boolean }[] = [];\n\n private config: ToolConfig;\n\n constructor(id: string, config: ToolConfig) {\n super();\n this.id = id;\n this.displayName = id;\n this.commands = [config.binary];\n this.readOnly = { level: config.readOnly.level };\n this.config = config;\n }\n\n buildInvocation(req: RunRequest): Invocation {\n const args: string[] = [];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n // Add read-only flags if applicable\n if (req.readOnlyPolicy !== 'none' && this.config.readOnly.flags) {\n args.push(...this.config.readOnly.flags);\n }\n\n const cmd = req.binary ?? this.config.binary;\n\n if (this.config.stdin === true) {\n return { cmd, args, stdin: req.prompt, cwd: req.cwd };\n }\n\n const instruction = `Read the file at ${req.promptFilePath} and follow the instructions within it.`;\n args.push(instruction);\n\n return { cmd, args, cwd: req.cwd };\n }\n}\n","import type { Invocation, RunRequest } from '../types.js';\nimport { BaseAdapter } from './base.js';\n\nexport class GeminiAdapter extends BaseAdapter {\n id = 'gemini';\n displayName = 'Gemini CLI';\n commands = ['gemini'];\n installUrl = 'https://github.com/google-gemini/gemini-cli';\n readOnly = { level: 'enforced' as const };\n models = [\n {\n id: 'gemini-3-pro-preview',\n name: 'Gemini 3 Pro Preview — latest',\n recommended: true,\n extraFlags: ['-m', 'gemini-3-pro-preview'],\n },\n {\n id: 'gemini-2.5-pro',\n name: 'Gemini 2.5 Pro — stable GA',\n extraFlags: ['-m', 'gemini-2.5-pro'],\n },\n {\n id: 'gemini-3-flash-preview',\n name: 'Gemini 3 Flash Preview — fast',\n extraFlags: ['-m', 'gemini-3-flash-preview'],\n },\n {\n id: 'gemini-2.5-flash',\n name: 'Gemini 2.5 Flash — fast GA',\n extraFlags: ['-m', 'gemini-2.5-flash'],\n },\n ];\n\n buildInvocation(req: RunRequest): Invocation {\n const args = ['-p', ''];\n\n if (req.extraFlags) {\n args.push(...req.extraFlags);\n }\n\n if (req.readOnlyPolicy !== 'none') {\n args.push(\n '--extensions',\n '',\n '--allowed-tools',\n 'read_file',\n 'list_directory',\n 'search_file_content',\n 'glob',\n 'google_web_search',\n 'codebase_investigator',\n );\n }\n\n args.push('--output-format', 'text');\n\n return {\n cmd: req.binary ?? 'gemini',\n args,\n stdin: req.prompt,\n cwd: req.cwd,\n };\n }\n}\n","import type { ToolAdapter, ToolConfig } from '../types.js';\nimport { AmpAdapter } from './amp.js';\nimport { ClaudeAdapter } from './claude.js';\nimport { CodexAdapter } from './codex.js';\nimport { CustomAdapter } from './custom.js';\nimport { GeminiAdapter } from './gemini.js';\n\nconst builtInAdapters: Record<string, () => ToolAdapter> = {\n claude: () => new ClaudeAdapter(),\n codex: () => new CodexAdapter(),\n gemini: () => new GeminiAdapter(),\n amp: () => new AmpAdapter(),\n};\n\nexport function getAdapter(id: string, config?: ToolConfig): ToolAdapter {\n if (builtInAdapters[id]) {\n return builtInAdapters[id]();\n }\n if (config) {\n return new CustomAdapter(id, config);\n }\n throw new Error(\n `Unknown tool: ${id}. Use \"counselors tools add\" to configure it.`,\n );\n}\n\nexport function getAllBuiltInAdapters(): ToolAdapter[] {\n return Object.values(builtInAdapters).map((fn) => fn());\n}\n\nexport function isBuiltInTool(id: string): boolean {\n return id in builtInAdapters;\n}\n\nexport function getBuiltInToolIds(): string[] {\n return Object.keys(builtInAdapters);\n}\n\nexport function resolveAdapter(\n id: string,\n toolConfig: ToolConfig,\n): ToolAdapter {\n const baseId = toolConfig.adapter ?? id;\n return isBuiltInTool(baseId)\n ? getAdapter(baseId)\n : new CustomAdapter(id, toolConfig);\n}\n","import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { z } from 'zod';\nimport { CONFIG_FILE, CONFIG_FILE_MODE } from '../constants.js';\nimport { type Config, ConfigSchema, type ToolConfig } from '../types.js';\nimport { safeWriteFile } from './fs-utils.js';\n\nconst DEFAULT_CONFIG: Config = {\n version: 1,\n defaults: {\n timeout: 540,\n outputDir: './agents/counselors',\n readOnly: 'bestEffort',\n maxContextKb: 50,\n maxParallel: 4,\n },\n tools: {},\n};\n\nexport function loadConfig(globalPath?: string): Config {\n const path = globalPath ?? CONFIG_FILE;\n if (!existsSync(path)) return { ...DEFAULT_CONFIG };\n\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, 'utf-8'));\n } catch (e) {\n throw new Error(\n `Invalid JSON in ${path}: ${e instanceof Error ? e.message : e}`,\n );\n }\n return ConfigSchema.parse(raw);\n}\n\n/** Schema for project config — only defaults are allowed, not tools.\n * Uses .optional() (not .default()) so missing fields stay absent\n * and don't clobber global config during merge. */\nconst ProjectConfigSchema = z.object({\n defaults: z\n .object({\n timeout: z.number().optional(),\n outputDir: z.string().optional(),\n readOnly: z.enum(['enforced', 'bestEffort', 'none']).optional(),\n maxContextKb: z.number().optional(),\n maxParallel: z.number().optional(),\n })\n .optional(),\n});\n\ntype ProjectConfig = z.infer<typeof ProjectConfigSchema>;\n\nexport function loadProjectConfig(cwd: string): ProjectConfig | null {\n const path = resolve(cwd, '.counselors.json');\n if (!existsSync(path)) return null;\n\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, 'utf-8'));\n } catch (e) {\n throw new Error(\n `Invalid JSON in ${path}: ${e instanceof Error ? e.message : e}`,\n );\n }\n return ProjectConfigSchema.parse(raw);\n}\n\nexport function mergeConfigs(\n global: Config,\n project: ProjectConfig | null,\n cliFlags?: Partial<Config['defaults']>,\n): Config {\n const merged: Config = {\n version: 1,\n defaults: { ...global.defaults },\n tools: { ...global.tools },\n };\n\n if (project) {\n if (project.defaults) {\n merged.defaults = { ...merged.defaults, ...project.defaults };\n }\n // Project configs can only override defaults, never inject tools.\n }\n\n if (cliFlags) {\n merged.defaults = { ...merged.defaults, ...cliFlags };\n }\n\n return merged;\n}\n\nexport function saveConfig(config: Config, path?: string): void {\n const filePath = path ?? CONFIG_FILE;\n mkdirSync(dirname(filePath), { recursive: true });\n safeWriteFile(filePath, `${JSON.stringify(config, null, 2)}\\n`, {\n mode: CONFIG_FILE_MODE,\n });\n}\n\nexport function addToolToConfig(\n config: Config,\n id: string,\n tool: ToolConfig,\n): Config {\n return {\n ...config,\n tools: { ...config.tools, [id]: tool },\n };\n}\n\nexport function removeToolFromConfig(config: Config, id: string): Config {\n const tools = { ...config.tools };\n delete tools[id];\n return { ...config, tools };\n}\n\nexport function renameToolInConfig(\n config: Config,\n oldId: string,\n newId: string,\n): Config {\n const tools = { ...config.tools };\n tools[newId] = tools[oldId];\n delete tools[oldId];\n return { ...config, tools };\n}\n\nexport function getConfiguredTools(config: Config): string[] {\n return Object.keys(config.tools);\n}\n","import { z } from 'zod';\n\n// ── Read-only levels ──\n\nexport type ReadOnlyLevel = 'enforced' | 'bestEffort' | 'none';\n\n// ── Config schemas (zod) ──\n\nexport const ToolConfigSchema = z.object({\n binary: z.string(),\n adapter: z.string().optional(),\n readOnly: z.object({\n level: z.enum(['enforced', 'bestEffort', 'none']),\n flags: z.array(z.string()).optional(),\n }),\n extraFlags: z.array(z.string()).optional(),\n timeout: z.number().optional(),\n stdin: z.boolean().optional(),\n custom: z.boolean().optional(),\n});\n\nexport type ToolConfig = z.infer<typeof ToolConfigSchema>;\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n defaults: z\n .object({\n timeout: z.number().default(540),\n outputDir: z.string().default('./agents/counselors'),\n readOnly: z\n .enum(['enforced', 'bestEffort', 'none'])\n .default('bestEffort'),\n maxContextKb: z.number().default(50),\n maxParallel: z.number().default(4),\n })\n .default({}),\n tools: z.record(z.string(), ToolConfigSchema).default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\n// ── Runtime types ──\n\nexport interface RunRequest {\n prompt: string;\n promptFilePath: string;\n toolId: string;\n outputDir: string;\n readOnlyPolicy: ReadOnlyLevel;\n timeout: number;\n cwd: string;\n binary?: string;\n extraFlags?: string[];\n}\n\nexport interface Invocation {\n cmd: string;\n args: string[];\n env?: Record<string, string>;\n stdin?: string;\n cwd: string;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n durationMs: number;\n}\n\nexport interface CostInfo {\n cost_usd: number;\n free_used_usd: number;\n credits_used_usd: number;\n source: 'free' | 'credits';\n free_remaining_usd: number;\n free_total_usd: number;\n credits_remaining_usd: number;\n}\n\nexport interface ToolReport {\n toolId: string;\n status: 'success' | 'error' | 'timeout' | 'skipped';\n exitCode: number;\n durationMs: number;\n wordCount: number;\n outputFile: string;\n stderrFile: string;\n cost?: CostInfo;\n error?: string;\n}\n\n// ── Adapter interface ──\n\nexport interface ToolAdapter {\n id: string;\n displayName: string;\n commands: string[];\n installUrl: string;\n readOnly: { level: ReadOnlyLevel };\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[];\n buildInvocation(req: RunRequest): Invocation;\n parseResult?(result: ExecResult): Partial<ToolReport>;\n}\n\n// ── Discovery ──\n\nexport interface DiscoveryResult {\n toolId: string;\n found: boolean;\n path: string | null;\n version: string | null;\n}\n\n// ── Doctor ──\n\nexport interface DoctorCheck {\n name: string;\n status: 'pass' | 'fail' | 'warn';\n message: string;\n}\n\n// ── Test ──\n\nexport interface TestResult {\n toolId: string;\n passed: boolean;\n output: string;\n error?: string;\n durationMs: number;\n}\n\n// ── Run manifest ──\n\nexport interface RunManifest {\n timestamp: string;\n slug: string;\n prompt: string;\n promptSource: 'inline' | 'file' | 'stdin';\n readOnlyPolicy: ReadOnlyLevel;\n tools: ToolReport[];\n}\n","import { renameSync, unlinkSync, writeFileSync } from 'node:fs';\n\n/**\n * Atomically write a file by writing to a temp file and renaming.\n * Avoids symlink TOCTOU — renameSync is atomic on the same filesystem.\n */\nexport function safeWriteFile(\n path: string,\n content: string,\n options?: { mode?: number },\n): void {\n const tmp = `${path}.tmp.${process.pid}`;\n try {\n writeFileSync(tmp, content, { encoding: 'utf-8', mode: options?.mode });\n renameSync(tmp, path);\n } catch (e) {\n // Clean up temp file on failure\n try {\n unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n throw e;\n }\n}\n","import { execFileSync } from 'node:child_process';\nimport {\n accessSync,\n constants,\n existsSync,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n DISCOVERY_TIMEOUT,\n getExtendedSearchPaths,\n VERSION_TIMEOUT,\n} from '../constants.js';\nimport type { DiscoveryResult } from '../types.js';\n\n/**\n * Two-stage binary discovery:\n * 1. `which <command>` via execSync\n * 2. Manual scan of extended paths\n */\nexport function findBinary(command: string): string | null {\n // Stage 1: which (Unix) / where (Windows)\n const lookupCmd = process.platform === 'win32' ? 'where' : 'which';\n try {\n const result = execFileSync(lookupCmd, [command], {\n timeout: DISCOVERY_TIMEOUT,\n stdio: ['pipe', 'pipe', 'pipe'],\n encoding: 'utf-8',\n })\n .trim()\n .split('\\n')[0]\n .trim(); // `where` on Windows may return multiple lines\n if (result) return result;\n } catch {\n // not found via lookup, continue to stage 2\n }\n\n // Stage 2: extended path scan\n const searchPaths = [\n ...getExtendedSearchPaths(),\n ...getNvmPaths(),\n ...getFnmPaths(),\n ];\n\n for (const dir of searchPaths) {\n const fullPath = join(dir, command);\n try {\n accessSync(fullPath, constants.X_OK);\n return fullPath;\n } catch {\n // not found here, continue\n }\n }\n\n return null;\n}\n\n/**\n * Get NVM version bin directories by resolving the default alias.\n */\nfunction getNvmPaths(): string[] {\n const home = homedir();\n const nvmDir = join(home, '.nvm');\n const aliasFile = join(nvmDir, 'alias', 'default');\n\n if (!existsSync(aliasFile)) return [];\n\n try {\n let alias = readFileSync(aliasFile, 'utf-8').trim();\n\n // Resolve LTS aliases: lts/iron -> read ~/.nvm/alias/lts/iron\n if (alias.startsWith('lts/')) {\n const ltsName = alias.slice(4);\n const ltsFile = join(nvmDir, 'alias', 'lts', ltsName);\n if (existsSync(ltsFile)) {\n alias = readFileSync(ltsFile, 'utf-8').trim();\n }\n }\n\n // Find matching version directory\n const versionsDir = join(nvmDir, 'versions', 'node');\n if (!existsSync(versionsDir)) return [];\n\n const versions = readdirSync(versionsDir);\n const match = versions.find((v) => v.startsWith(`v${alias}`));\n if (match) {\n return [join(versionsDir, match, 'bin')];\n }\n } catch {\n // nvm parsing failed, skip\n }\n\n return [];\n}\n\n/**\n * Get FNM multishell bin directories (5 most recent by mtime).\n */\nfunction getFnmPaths(): string[] {\n const home = homedir();\n const multishellDir = join(home, '.local', 'state', 'fnm_multishells');\n const paths: string[] = [];\n\n // Also check fnm alias dirs\n const fnmDir = join(home, '.local', 'share', 'fnm');\n if (existsSync(fnmDir)) {\n const aliasDir = join(fnmDir, 'aliases');\n if (existsSync(aliasDir)) {\n try {\n for (const alias of readdirSync(aliasDir)) {\n const binDir = join(aliasDir, alias, 'bin');\n if (existsSync(binDir)) paths.push(binDir);\n }\n } catch {\n // skip\n }\n }\n }\n\n if (!existsSync(multishellDir)) return paths;\n\n try {\n const entries = readdirSync(multishellDir)\n .map((name) => {\n const full = join(multishellDir, name);\n try {\n return { name: full, mtime: statSync(full).mtimeMs };\n } catch {\n return null;\n }\n })\n .filter((e): e is { name: string; mtime: number } => e !== null)\n .sort((a, b) => b.mtime - a.mtime)\n .slice(0, 5);\n\n for (const entry of entries) {\n const binDir = join(entry.name, 'bin');\n if (existsSync(binDir)) {\n paths.push(binDir);\n }\n }\n } catch {\n // scan failed, skip\n }\n\n return paths;\n}\n\n/**\n * Get binary version via --version flag.\n */\nexport function getBinaryVersion(binaryPath: string): string | null {\n try {\n const output = execFileSync(binaryPath, ['--version'], {\n timeout: VERSION_TIMEOUT,\n stdio: ['pipe', 'pipe', 'pipe'],\n encoding: 'utf-8',\n }).trim();\n // Take first line, strip common prefixes\n const firstLine = output.split('\\n')[0].trim();\n return firstLine || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Discover a single tool.\n */\nexport function discoverTool(\n commands: string[],\n): DiscoveryResult & { command: string } {\n for (const cmd of commands) {\n const path = findBinary(cmd);\n if (path) {\n const version = getBinaryVersion(path);\n return { toolId: cmd, found: true, path, version, command: cmd };\n }\n }\n return {\n toolId: commands[0],\n found: false,\n path: null,\n version: null,\n command: commands[0],\n };\n}\n","import ora, { type Ora } from 'ora';\nimport type {\n DiscoveryResult,\n DoctorCheck,\n RunManifest,\n TestResult,\n} from '../types.js';\n\nexport function createSpinner(text: string): Ora {\n return ora({ text, stream: process.stderr });\n}\n\nexport function formatDiscoveryResults(\n results: (DiscoveryResult & { displayName?: string })[],\n): string {\n const lines: string[] = ['', 'Discovered tools:', ''];\n for (const r of results) {\n const name = r.displayName || r.toolId;\n if (r.found) {\n lines.push(` ✓ ${name}`);\n lines.push(` Path: ${r.path}`);\n if (r.version) lines.push(` Version: ${r.version}`);\n } else {\n lines.push(` ✗ ${name} — not found`);\n }\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatDoctorResults(checks: DoctorCheck[]): string {\n const lines: string[] = ['', 'Doctor results:', ''];\n for (const c of checks) {\n const icon = c.status === 'pass' ? '✓' : c.status === 'warn' ? '⚠' : '✗';\n lines.push(` ${icon} ${c.name}: ${c.message}`);\n }\n const failures = checks.filter((c) => c.status === 'fail').length;\n const warnings = checks.filter((c) => c.status === 'warn').length;\n lines.push('');\n if (failures > 0) {\n lines.push(`${failures} check(s) failed.`);\n } else if (warnings > 0) {\n lines.push(`All checks passed with ${warnings} warning(s).`);\n } else {\n lines.push('All checks passed.');\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport interface ToolListEntry {\n id: string;\n binary: string;\n args?: string[];\n}\n\nexport function formatToolList(\n tools: ToolListEntry[],\n verbose?: boolean,\n): string {\n if (tools.length === 0) {\n return '\\nNo tools configured. Run \"counselors init\" to get started.\\n';\n }\n\n const lines: string[] = ['', 'Configured tools:', ''];\n for (const t of tools) {\n if (!verbose) {\n lines.push(` \\x1b[1m${t.id}\\x1b[0m (${t.binary})`);\n continue;\n }\n\n const bold = '\\x1b[1m';\n const reset = '\\x1b[0m';\n lines.push(` ${bold}${t.id}${reset}`);\n\n const raw = t.args ?? [];\n const quote = (a: string) => (a.includes(' ') ? `\"${a}\"` : a);\n\n // Build the full command, breaking onto new lines at each -- flag\n const allParts = [t.binary, ...raw].map(quote);\n let line = ' ';\n for (const part of allParts) {\n if (part.startsWith('-') && line.trim().length > 0) {\n lines.push(line);\n line = ` ${part}`;\n } else {\n line += (line.trim().length > 0 ? ' ' : '') + part;\n }\n }\n if (line.trim().length > 0) lines.push(line);\n }\n\n if (!verbose) {\n const dim = '\\x1b[2m';\n const reset = '\\x1b[0m';\n lines.push('');\n lines.push(`${dim}(Use -v to show flags)${reset}`);\n }\n\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatTestResults(results: TestResult[]): string {\n const lines: string[] = ['', 'Test results:', ''];\n for (const r of results) {\n const icon = r.passed ? '✓' : '✗';\n lines.push(` ${icon} ${r.toolId} (${r.durationMs}ms)`);\n if (!r.passed && r.error) {\n lines.push(` Error: ${r.error}`);\n }\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatRunSummary(manifest: RunManifest): string {\n const lines: string[] = ['', `Run complete: ${manifest.slug}`, ''];\n\n for (const r of manifest.tools) {\n const icon =\n r.status === 'success' ? '✓' : r.status === 'timeout' ? '⏱' : '✗';\n const duration = (r.durationMs / 1000).toFixed(1);\n lines.push(` ${icon} ${r.toolId} — ${r.wordCount} words, ${duration}s`);\n if (r.cost) {\n lines.push(` Cost: $${r.cost.cost_usd.toFixed(2)} (${r.cost.source})`);\n }\n if (r.status === 'error' && r.error) {\n lines.push(` Error: ${r.error}`);\n }\n }\n\n lines.push('');\n lines.push(\n `Reports saved to: ${manifest.tools[0]?.outputFile ? manifest.tools[0].outputFile.replace(/\\/[^/]+$/, '/') : 'output dir'}`,\n );\n lines.push('');\n return lines.join('\\n');\n}\n\nexport function formatDryRun(\n invocations: { toolId: string; cmd: string; args: string[] }[],\n): string {\n const lines: string[] = ['', 'Dry run — would dispatch:', ''];\n for (const inv of invocations) {\n lines.push(` ${inv.toolId}`);\n lines.push(` $ ${inv.cmd} ${inv.args.join(' ')}`);\n }\n lines.push('');\n return lines.join('\\n');\n}\n","import { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n AMP_DEEP_SETTINGS_FILE,\n AMP_SETTINGS_FILE,\n CONFIG_DIR,\n} from '../constants.js';\n\nexport function copyAmpSettings(): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n const assetsDir = resolve(\n dirname(fileURLToPath(import.meta.url)),\n '..',\n 'assets',\n );\n const bundledSettings = resolve(assetsDir, 'amp-readonly-settings.json');\n if (existsSync(bundledSettings)) {\n copyFileSync(bundledSettings, AMP_SETTINGS_FILE);\n }\n const bundledDeepSettings = resolve(assetsDir, 'amp-deep-settings.json');\n if (existsSync(bundledDeepSettings)) {\n copyFileSync(bundledDeepSettings, AMP_DEEP_SETTINGS_FILE);\n }\n}\n","import { type ChildProcess, execFile, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport stripAnsi from 'strip-ansi';\nimport { computeAmpCost, parseAmpUsage } from '../adapters/amp.js';\nimport { KILL_GRACE_PERIOD, TEST_TIMEOUT } from '../constants.js';\nimport type {\n CostInfo,\n ExecResult,\n Invocation,\n TestResult,\n ToolAdapter,\n ToolConfig,\n} from '../types.js';\nimport { debug } from '../ui/logger.js';\n\nconst execFileAsync = promisify(execFile);\n\nconst MAX_OUTPUT_BYTES = 10 * 1024 * 1024; // 10MB\n\nconst activeChildren = new Set<ChildProcess>();\n\nprocess.on('SIGINT', () => {\n for (const child of activeChildren) {\n child.kill('SIGTERM');\n }\n // Give children a moment to exit, then force-exit\n setTimeout(() => process.exit(1), 2000);\n});\n\nconst ENV_ALLOWLIST = [\n 'PATH',\n 'HOME',\n 'USER',\n 'TERM',\n 'LANG',\n 'SHELL',\n 'TMPDIR',\n 'XDG_CONFIG_HOME',\n 'XDG_DATA_HOME',\n // Node version managers\n 'NVM_BIN',\n 'NVM_DIR',\n 'FNM_MULTISHELL_PATH',\n // API keys for adapters\n 'ANTHROPIC_API_KEY',\n 'OPENAI_API_KEY',\n 'OPENAI_ORG_ID',\n 'GEMINI_API_KEY',\n 'GOOGLE_API_KEY',\n 'GOOGLE_APPLICATION_CREDENTIALS',\n 'AMP_API_KEY',\n // Proxy\n 'HTTP_PROXY',\n 'HTTPS_PROXY',\n 'NO_PROXY',\n 'http_proxy',\n 'https_proxy',\n 'no_proxy',\n // Node runtime\n 'NODE_OPTIONS',\n] as const;\n\nfunction buildSafeEnv(extra?: Record<string, string>): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of ENV_ALLOWLIST) {\n if (process.env[key]) env[key] = process.env[key]!;\n }\n if (extra) Object.assign(env, extra);\n env.CI = 'true';\n env.NO_COLOR = '1';\n return env;\n}\n\n/**\n * Execute a tool invocation with timeout and output capture.\n * Uses child_process.spawn — no shell: true (security).\n */\nexport function execute(\n invocation: Invocation,\n timeoutMs: number,\n): Promise<ExecResult> {\n return new Promise((resolve) => {\n const start = Date.now();\n let stdout = '';\n let stderr = '';\n let timedOut = false;\n let killed = false;\n let killTimer: NodeJS.Timeout | undefined;\n let truncated = false;\n\n debug(`Executing: ${invocation.cmd} ${invocation.args.join(' ')}`);\n\n const child = spawn(invocation.cmd, invocation.args, {\n cwd: invocation.cwd,\n env: buildSafeEnv(invocation.env),\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Track active children for SIGINT cleanup\n activeChildren.add(child);\n\n child.stdout.on('data', (data: Buffer) => {\n if (!truncated && stdout.length < MAX_OUTPUT_BYTES) {\n stdout += data.toString();\n if (stdout.length >= MAX_OUTPUT_BYTES) {\n truncated = true;\n stdout = `${stdout.slice(0, MAX_OUTPUT_BYTES)}\\n[output truncated at 10MB]`;\n }\n }\n });\n\n child.stderr.on('data', (data: Buffer) => {\n if (stderr.length < MAX_OUTPUT_BYTES) {\n stderr += data.toString();\n }\n });\n\n // Write stdin if provided\n if (invocation.stdin) {\n child.stdin.write(invocation.stdin);\n child.stdin.end();\n } else {\n child.stdin.end();\n }\n\n // Timeout: SIGTERM first, SIGKILL after grace period\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill('SIGTERM');\n killTimer = setTimeout(() => {\n if (!killed) {\n child.kill('SIGKILL');\n }\n }, KILL_GRACE_PERIOD);\n }, timeoutMs);\n\n child.on('close', (code) => {\n killed = true;\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n activeChildren.delete(child);\n resolve({\n exitCode: code ?? 1,\n stdout: stripAnsi(stdout),\n stderr: stripAnsi(stderr),\n timedOut,\n durationMs: Date.now() - start,\n });\n });\n\n child.on('error', (err) => {\n killed = true;\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n activeChildren.delete(child);\n resolve({\n exitCode: 1,\n stdout: '',\n stderr: err.message,\n timedOut: false,\n durationMs: Date.now() - start,\n });\n });\n });\n}\n\n/**\n * Capture amp usage before/after a run to compute cost.\n */\nexport async function captureAmpUsage(): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync('amp', ['usage'], {\n timeout: 10_000,\n encoding: 'utf-8',\n });\n return stdout;\n } catch {\n return null;\n }\n}\n\n/**\n * Compute amp cost from before/after usage snapshots.\n */\nexport function computeAmpCostFromSnapshots(\n before: string,\n after: string,\n): CostInfo | null {\n try {\n const beforeParsed = parseAmpUsage(before);\n const afterParsed = parseAmpUsage(after);\n return computeAmpCost(beforeParsed, afterParsed);\n } catch {\n return null;\n }\n}\n\n/**\n * Test a tool using the \"reply OK\" protocol.\n */\nexport async function executeTest(\n adapter: ToolAdapter,\n toolConfig: ToolConfig,\n toolName?: string,\n): Promise<TestResult> {\n const prompt = 'Reply with exactly: OK';\n const start = Date.now();\n\n const invocation = adapter.buildInvocation({\n prompt,\n promptFilePath: '',\n toolId: adapter.id,\n outputDir: '',\n readOnlyPolicy: 'none',\n timeout: TEST_TIMEOUT / 1000,\n cwd: process.cwd(),\n extraFlags: toolConfig.extraFlags,\n });\n\n // Override: for test, we pass a simple prompt as argument or stdin.\n // Check invocation.stdin (set by the adapter) rather than config.stdin,\n // so built-in stdin adapters (Amp, Gemini) are handled correctly.\n if (invocation.stdin != null) {\n invocation.stdin = prompt;\n // Remove any --settings-file flags for test\n invocation.args = invocation.args.filter((a, i, arr) => {\n if (a === '--settings-file') return false;\n if (i > 0 && arr[i - 1] === '--settings-file') return false;\n return true;\n });\n } else {\n // Replace prompt file instruction with direct prompt\n const lastArgIdx = invocation.args.length - 1;\n invocation.args[lastArgIdx] = prompt;\n }\n\n const result = await execute(invocation, TEST_TIMEOUT);\n\n const passed = result.stdout.includes('OK');\n return {\n toolId: toolName ?? adapter.id,\n passed,\n output: result.stdout.slice(0, 500),\n error: !passed\n ? result.stderr.slice(0, 500) || 'Output did not contain \"OK\"'\n : undefined,\n durationMs: Date.now() - start,\n };\n}\n","import { checkbox, confirm, input, select } from '@inquirer/prompts';\n\nexport async function selectModelDetails(\n toolId: string,\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[],\n): Promise<{ id: string; compoundId?: string; extraFlags?: string[] }> {\n const choices = models.map((m, i) => ({\n name: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: String(i),\n }));\n\n const idx = await select({\n message: `Select model for ${toolId}:`,\n choices,\n });\n\n const model = models[Number(idx)];\n return {\n id: model.id,\n compoundId: model.compoundId,\n extraFlags: model.extraFlags,\n };\n}\n\nexport async function selectModels(\n toolId: string,\n models: {\n id: string;\n name: string;\n recommended?: boolean;\n compoundId?: string;\n extraFlags?: string[];\n }[],\n): Promise<{ id: string; compoundId?: string; extraFlags?: string[] }[]> {\n const choices = models.map((m) => ({\n name: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: { id: m.id, compoundId: m.compoundId, extraFlags: m.extraFlags },\n checked: m.recommended,\n }));\n\n return checkbox({\n message: `Select models for ${toolId}:`,\n choices,\n });\n}\n\nexport async function selectTools(\n tools: { id: string; name: string; found: boolean }[],\n): Promise<string[]> {\n const choices = tools.map((t) => ({\n name: t.found ? `${t.name} — found` : `${t.name} — not found`,\n value: t.id,\n checked: t.found,\n disabled: !t.found ? '(not installed)' : undefined,\n }));\n\n return checkbox({\n message: 'Which tools should be configured?',\n choices: choices as any,\n });\n}\n\nexport async function confirmOverwrite(toolId: string): Promise<boolean> {\n return confirm({\n message: `Tool \"${toolId}\" already exists. Overwrite?`,\n default: false,\n });\n}\n\nexport async function selectRunTools(tools: string[]): Promise<string[]> {\n const choices = tools.map((id) => ({\n name: id,\n value: id,\n checked: true,\n }));\n\n return checkbox({\n message: 'Select tools to dispatch:',\n choices,\n });\n}\n\nexport async function confirmAction(message: string): Promise<boolean> {\n return confirm({ message, default: true });\n}\n\nexport async function promptInput(\n message: string,\n defaultValue?: string,\n): Promise<string> {\n return input({ message, default: defaultValue });\n}\n\nexport async function promptSelect<T extends string>(\n message: string,\n choices: { name: string; value: T }[],\n): Promise<T> {\n return select({ message, choices });\n}\n","import type { Command } from 'commander';\nimport { getAllBuiltInAdapters, resolveAdapter } from '../adapters/index.js';\nimport { AMP_SETTINGS_FILE, CONFIG_DIR } from '../constants.js';\nimport { copyAmpSettings } from '../core/amp-utils.js';\nimport { addToolToConfig, loadConfig, saveConfig } from '../core/config.js';\nimport { discoverTool } from '../core/discovery.js';\nimport { executeTest } from '../core/executor.js';\nimport { info, success, warn } from '../ui/logger.js';\nimport {\n createSpinner,\n formatDiscoveryResults,\n formatTestResults,\n} from '../ui/output.js';\nimport { confirmAction, selectModels, selectTools } from '../ui/prompts.js';\n\nfunction buildToolConfig(\n id: string,\n adapter: import('../types.js').ToolAdapter,\n binaryPath: string,\n) {\n return {\n binary: binaryPath,\n readOnly: { level: adapter.readOnly.level },\n ...(id === 'gemini' || id === 'codex' ? { timeout: 900 } : {}),\n };\n}\n\nfunction compoundId(adapterId: string, modelId: string): string {\n if (modelId.startsWith(`${adapterId}-`)) return modelId;\n return `${adapterId}-${modelId}`;\n}\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Interactive setup wizard')\n .option(\n '--auto',\n 'Non-interactive mode: discover tools, use recommended models, output JSON',\n )\n .action(async (opts: { auto?: boolean }) => {\n // Non-interactive auto mode\n if (opts.auto) {\n const adapters = getAllBuiltInAdapters();\n const discoveries = adapters.map((adapter) => {\n const result = discoverTool(adapter.commands);\n return { adapter, discovery: result };\n });\n\n const foundTools = discoveries.filter((d) => d.discovery.found);\n if (foundTools.length === 0) {\n info(\n JSON.stringify(\n {\n configured: [],\n notFound: adapters.map((a) => a.id),\n configPath: CONFIG_DIR,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n let config = loadConfig();\n const configured: {\n id: string;\n adapter: string;\n binary: string;\n version: string | null;\n }[] = [];\n const notFound: string[] = [];\n\n for (const { adapter, discovery } of discoveries) {\n if (!discovery.found) {\n notFound.push(adapter.id);\n continue;\n }\n\n for (const model of adapter.models) {\n const cid = model.compoundId ?? compoundId(adapter.id, model.id);\n const toolConfig = {\n ...buildToolConfig(adapter.id, adapter, discovery.path!),\n adapter: adapter.id,\n ...(model.extraFlags ? { extraFlags: model.extraFlags } : {}),\n };\n config = addToolToConfig(config, cid, toolConfig);\n configured.push({\n id: cid,\n adapter: adapter.id,\n binary: discovery.path!,\n version: discovery.version,\n });\n }\n }\n\n if (configured.some((t) => t.adapter === 'amp')) {\n copyAmpSettings();\n }\n\n saveConfig(config);\n\n info(\n JSON.stringify(\n { configured, notFound, configPath: CONFIG_DIR },\n null,\n 2,\n ),\n );\n return;\n }\n\n // Interactive mode\n info('\\nCounselors — setup wizard\\n');\n\n const existingConfig = loadConfig();\n const existingTools = Object.keys(existingConfig.tools);\n if (existingTools.length > 0) {\n warn(\n `Existing config has ${existingTools.length} tool(s). Re-running init will overwrite any tools with the same name.`,\n );\n }\n\n // Step 1: Discover all built-in tools\n const spinner = createSpinner('Discovering installed tools...').start();\n const adapters = getAllBuiltInAdapters();\n const discoveries = adapters.map((adapter) => {\n const result = discoverTool(adapter.commands);\n return { adapter, discovery: result };\n });\n spinner.stop();\n\n info(\n formatDiscoveryResults(\n discoveries.map((d) => ({\n ...d.discovery,\n toolId: d.adapter.id,\n displayName: d.adapter.displayName,\n })),\n ),\n );\n\n const foundTools = discoveries.filter((d) => d.discovery.found);\n if (foundTools.length === 0) {\n warn(\n 'No AI CLI tools found. Install at least one before running init.',\n );\n return;\n }\n\n // Step 2: Select which tools to add\n const selectedIds = await selectTools(\n discoveries.map((d) => ({\n id: d.adapter.id,\n name: d.adapter.displayName,\n found: d.discovery.found,\n })),\n );\n\n if (selectedIds.length === 0) {\n info('No tools selected. Exiting.');\n return;\n }\n\n // Step 3: Model selection per tool\n let config = loadConfig();\n const configuredIds: string[] = [];\n\n for (const id of selectedIds) {\n const d = discoveries.find((x) => x.adapter.id === id)!;\n const models = await selectModels(id, d.adapter.models);\n\n for (const model of models) {\n const cid = model.compoundId ?? compoundId(id, model.id);\n const toolConfig = {\n ...buildToolConfig(id, d.adapter, d.discovery.path!),\n adapter: id,\n ...(model.extraFlags ? { extraFlags: model.extraFlags } : {}),\n };\n config = addToolToConfig(config, cid, toolConfig);\n configuredIds.push(cid);\n }\n }\n\n // Step 4: Copy amp settings if amp was selected\n if (selectedIds.includes('amp')) {\n copyAmpSettings();\n success(`Copied amp settings to ${AMP_SETTINGS_FILE}`);\n }\n\n // Step 5: Save config\n saveConfig(config);\n success(`Config saved to ${CONFIG_DIR}`);\n\n // Step 6: Offer to test\n const runTests = await confirmAction('Run tool tests now?');\n if (runTests) {\n const testResults = [];\n for (const id of configuredIds) {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n const spinner = createSpinner(`Testing ${id}...`).start();\n const result = await executeTest(adapter, toolConfig, id);\n spinner.stop();\n testResults.push(result);\n }\n info(formatTestResults(testResults));\n }\n });\n}\n","import { copyFileSync, readFileSync } from 'node:fs';\nimport { basename, join, resolve } from 'node:path';\nimport type { Command } from 'commander';\nimport { resolveAdapter } from '../adapters/index.js';\nimport { loadConfig, loadProjectConfig, mergeConfigs } from '../core/config.js';\nimport { gatherContext } from '../core/context.js';\nimport { dispatch } from '../core/dispatcher.js';\nimport { safeWriteFile } from '../core/fs-utils.js';\nimport {\n buildPrompt,\n generateSlug,\n generateSlugFromFile,\n resolveOutputDir,\n} from '../core/prompt-builder.js';\nimport { synthesize } from '../core/synthesis.js';\nimport type { ReadOnlyLevel, RunManifest, ToolReport } from '../types.js';\nimport { error, info } from '../ui/logger.js';\nimport { formatDryRun, formatRunSummary } from '../ui/output.js';\nimport { ProgressDisplay } from '../ui/progress.js';\nimport { selectRunTools } from '../ui/prompts.js';\n\nexport function registerRunCommand(program: Command): void {\n program\n .command('run [prompt]')\n .description('Dispatch prompt to configured AI tools in parallel')\n .option('-f, --file <path>', 'Use a pre-built prompt file (no wrapping)')\n .option('-t, --tools <tools>', 'Comma-separated list of tools to use')\n .option(\n '--context <paths>',\n 'Gather context from paths (comma-separated, or \".\" for git diff)',\n )\n .option('--read-only <level>', 'Read-only policy: strict, best-effort, off')\n .option('--dry-run', 'Show what would be dispatched without running')\n .option('--json', 'Output manifest as JSON')\n .option('-o, --output-dir <dir>', 'Base output directory')\n .action(\n async (\n promptArg: string | undefined,\n opts: {\n file?: string;\n tools?: string;\n context?: string;\n readOnly?: string;\n dryRun?: boolean;\n json?: boolean;\n outputDir?: string;\n },\n ) => {\n const cwd = process.cwd();\n const globalConfig = loadConfig();\n const projectConfig = loadProjectConfig(cwd);\n const config = mergeConfigs(globalConfig, projectConfig);\n\n // Determine tools to use\n let toolIds: string[];\n const explicitTools = Boolean(opts.tools);\n\n if (opts.tools) {\n toolIds = opts.tools.split(',').map((t) => t.trim());\n } else {\n toolIds = Object.keys(config.tools);\n }\n\n if (toolIds.length === 0) {\n error('No tools configured. Run \"counselors init\" first.');\n process.exitCode = 1;\n return;\n }\n\n // Validate all tools exist in config\n for (const id of toolIds) {\n if (!config.tools[id]) {\n error(\n `Tool \"${id}\" not configured. Run \"counselors tools add ${id}\".`,\n );\n process.exitCode = 1;\n return;\n }\n }\n\n // Interactive tool selection when no --tools flag and TTY\n if (\n !explicitTools &&\n !opts.dryRun &&\n process.stderr.isTTY &&\n toolIds.length > 1\n ) {\n const selected = await selectRunTools(toolIds);\n if (selected.length === 0) {\n error('No tools selected.');\n process.exitCode = 1;\n return;\n }\n toolIds = selected;\n }\n\n // Map read-only flag (fall back to config default)\n const internalToCliMap: Record<string, string> = {\n enforced: 'strict',\n bestEffort: 'best-effort',\n none: 'off',\n };\n const readOnlyInput =\n opts.readOnly ??\n internalToCliMap[config.defaults.readOnly] ??\n 'best-effort';\n const readOnlyMap: Record<string, ReadOnlyLevel> = {\n strict: 'enforced',\n 'best-effort': 'bestEffort',\n off: 'none',\n };\n const readOnlyPolicy = readOnlyMap[readOnlyInput];\n if (!readOnlyPolicy) {\n error(\n `Invalid --read-only value \"${readOnlyInput}\". Must be: strict, best-effort, or off.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Resolve prompt\n let promptContent: string;\n let promptSource: 'inline' | 'file' | 'stdin';\n let slug: string;\n\n if (opts.file) {\n // File mode: use as-is, no wrapping\n const filePath = resolve(cwd, opts.file);\n try {\n promptContent = readFileSync(filePath, 'utf-8');\n } catch {\n error(`Cannot read prompt file: ${filePath}`);\n process.exitCode = 1;\n return;\n }\n promptSource = 'file';\n slug = generateSlugFromFile(filePath);\n } else if (promptArg) {\n // Inline prompt: wrap in template\n promptSource = 'inline';\n slug = generateSlug(promptArg);\n\n const context = opts.context\n ? gatherContext(\n cwd,\n opts.context === '.' ? [] : opts.context.split(','),\n config.defaults.maxContextKb,\n )\n : undefined;\n\n promptContent = buildPrompt(promptArg, context);\n } else {\n // Check stdin\n if (process.stdin.isTTY) {\n error(\n 'No prompt provided. Pass as argument, use -f <file>, or pipe via stdin.',\n );\n process.exitCode = 1;\n return;\n }\n\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinContent = Buffer.concat(chunks).toString('utf-8').trim();\n if (!stdinContent) {\n error('Empty prompt from stdin.');\n process.exitCode = 1;\n return;\n }\n\n promptSource = 'stdin';\n slug = generateSlug(stdinContent);\n\n const context = opts.context\n ? gatherContext(\n cwd,\n opts.context === '.' ? [] : opts.context.split(','),\n config.defaults.maxContextKb,\n )\n : undefined;\n\n promptContent = buildPrompt(stdinContent, context);\n }\n\n if (!slug) slug = `run-${Date.now()}`;\n\n // Dry run — no filesystem side effects\n if (opts.dryRun) {\n const baseDir = opts.outputDir || config.defaults.outputDir;\n const dryOutputDir = join(baseDir, slug);\n const dryPromptFile = resolve(dryOutputDir, 'prompt.md');\n const invocations = toolIds.map((id) => {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n const inv = adapter.buildInvocation({\n prompt: promptContent,\n promptFilePath: dryPromptFile,\n toolId: id,\n outputDir: dryOutputDir,\n readOnlyPolicy,\n timeout: config.defaults.timeout,\n cwd,\n binary: toolConfig.binary,\n extraFlags: toolConfig.extraFlags,\n });\n return {\n toolId: id,\n cmd: inv.cmd,\n args: inv.args,\n };\n });\n info(formatDryRun(invocations));\n return;\n }\n\n // Resolve output directory (creates it)\n const baseDir = opts.outputDir || config.defaults.outputDir;\n const outputDir = resolveOutputDir(baseDir, slug);\n\n // Write prompt file\n const promptFilePath = resolve(outputDir, 'prompt.md');\n if (opts.file) {\n copyFileSync(resolve(cwd, opts.file), promptFilePath);\n } else {\n safeWriteFile(promptFilePath, promptContent);\n }\n\n // Dispatch\n const display = new ProgressDisplay(toolIds, outputDir);\n\n let reports: ToolReport[];\n try {\n reports = await dispatch({\n config,\n toolIds,\n promptFilePath,\n promptContent,\n outputDir,\n readOnlyPolicy,\n cwd,\n onProgress: (event) => {\n if (event.event === 'started') display.start(event.toolId);\n if (event.event === 'completed')\n display.complete(event.toolId, event.report!);\n },\n });\n } finally {\n display.stop();\n }\n\n // Build manifest\n const manifest: RunManifest = {\n timestamp: new Date().toISOString(),\n slug,\n prompt:\n promptArg || (opts.file ? `file:${basename(opts.file)}` : 'stdin'),\n promptSource,\n readOnlyPolicy,\n tools: reports,\n };\n\n // Write manifest + synthesis\n safeWriteFile(\n resolve(outputDir, 'run.json'),\n JSON.stringify(manifest, null, 2),\n );\n const summary = synthesize(manifest, outputDir);\n safeWriteFile(resolve(outputDir, 'summary.md'), summary);\n\n // Output\n if (opts.json) {\n info(JSON.stringify(manifest, null, 2));\n } else {\n info(formatRunSummary(manifest));\n }\n },\n );\n}\n","import { execFileSync } from 'node:child_process';\nimport { readFileSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { DEFAULT_MAX_CONTEXT_KB } from '../constants.js';\nimport { debug } from '../ui/logger.js';\n\n/**\n * Gather context from git diff and specified files.\n */\nexport function gatherContext(\n cwd: string,\n paths: string[],\n maxKb: number = DEFAULT_MAX_CONTEXT_KB,\n): string {\n const parts: string[] = [];\n let totalBytes = 0;\n const maxBytes = maxKb * 1024;\n\n // Read specified files first (user-requested content gets priority)\n if (paths.length > 0) {\n parts.push('### Files Referenced', '');\n\n for (const p of paths) {\n if (totalBytes >= maxBytes) {\n debug(`Context limit reached (${maxKb}KB), skipping remaining files`);\n break;\n }\n\n const fullPath = resolve(cwd, p);\n try {\n const stat = statSync(fullPath);\n if (!stat.isFile()) continue;\n if (stat.size > maxBytes - totalBytes) {\n debug(`Skipping ${p} — too large (${stat.size} bytes)`);\n continue;\n }\n\n const content = readFileSync(fullPath, 'utf-8');\n parts.push(`#### ${p}`, '', '```', content, '```', '');\n totalBytes += Buffer.byteLength(content);\n } catch {\n debug(`Could not read ${p}`);\n }\n }\n }\n\n // Git diff (staged + unstaged) — added after files, truncated if over budget\n if (totalBytes < maxBytes) {\n const diff = getGitDiff(cwd);\n if (diff) {\n const diffBytes = Buffer.byteLength(diff);\n if (totalBytes + diffBytes <= maxBytes) {\n parts.push(\n '### Recent Changes (Git Diff)',\n '',\n '```diff',\n diff,\n '```',\n '',\n );\n totalBytes += diffBytes;\n } else {\n const remaining = maxBytes - totalBytes;\n const truncated = Buffer.from(diff)\n .subarray(0, remaining)\n .toString('utf-8');\n parts.push(\n '### Recent Changes (Git Diff) [truncated]',\n '',\n '```diff',\n truncated,\n '```',\n '',\n );\n totalBytes = maxBytes;\n }\n }\n }\n\n return parts.join('\\n');\n}\n\nfunction getGitDiff(cwd: string): string | null {\n try {\n const staged = execFileSync('git', ['diff', '--staged'], {\n cwd,\n encoding: 'utf-8',\n timeout: 10_000,\n maxBuffer: 10 * 1024 * 1024,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n const unstaged = execFileSync('git', ['diff'], {\n cwd,\n encoding: 'utf-8',\n timeout: 10_000,\n maxBuffer: 10 * 1024 * 1024,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n const parts = [];\n if (staged) parts.push(staged);\n if (unstaged) parts.push(unstaged);\n return parts.length > 0 ? parts.join('\\n') : null;\n } catch {\n return null;\n }\n}\n","import { join } from 'node:path';\nimport pLimit from 'p-limit';\nimport { resolveAdapter } from '../adapters/index.js';\nimport { sanitizeId } from '../constants.js';\nimport type {\n Config,\n ReadOnlyLevel,\n RunRequest,\n ToolReport,\n} from '../types.js';\nimport { debug, warn } from '../ui/logger.js';\nimport {\n captureAmpUsage,\n computeAmpCostFromSnapshots,\n execute,\n} from './executor.js';\nimport { safeWriteFile } from './fs-utils.js';\n\nexport interface ProgressEvent {\n toolId: string;\n event: 'started' | 'completed';\n report?: ToolReport;\n}\n\nexport interface DispatchOptions {\n config: Config;\n toolIds: string[];\n promptFilePath: string;\n promptContent: string;\n outputDir: string;\n readOnlyPolicy: ReadOnlyLevel;\n cwd: string;\n onProgress?: (event: ProgressEvent) => void;\n}\n\n/**\n * Dispatch prompts to all selected tools in parallel with bounded concurrency.\n */\nexport async function dispatch(\n options: DispatchOptions,\n): Promise<ToolReport[]> {\n const {\n config,\n toolIds,\n promptFilePath,\n promptContent,\n outputDir,\n readOnlyPolicy,\n cwd,\n onProgress,\n } = options;\n const limit = pLimit(config.defaults.maxParallel);\n\n // Filter tools based on read-only policy\n const eligibleTools = toolIds.filter((id) => {\n const toolConfig = config.tools[id];\n if (!toolConfig) {\n warn(`Tool \"${id}\" not configured, skipping.`);\n return false;\n }\n\n if (readOnlyPolicy === 'enforced') {\n const adapter = resolveAdapter(id, toolConfig);\n if (adapter.readOnly.level !== 'enforced') {\n warn(\n `Skipping \"${id}\" — read-only level is \"${adapter.readOnly.level}\", policy requires \"enforced\".`,\n );\n return false;\n }\n }\n\n return true;\n });\n\n if (eligibleTools.length === 0) {\n throw new Error('No eligible tools after read-only policy filtering.');\n }\n\n const tasks = eligibleTools.map((id) =>\n limit(async (): Promise<ToolReport> => {\n const toolConfig = config.tools[id];\n const adapter = resolveAdapter(id, toolConfig);\n\n const toolTimeout = toolConfig.timeout ?? config.defaults.timeout;\n const toolTimeoutMs = toolTimeout * 1000;\n\n const req: RunRequest = {\n prompt: promptContent,\n promptFilePath,\n toolId: id,\n outputDir,\n readOnlyPolicy,\n timeout: toolTimeout,\n cwd,\n binary: toolConfig.binary,\n extraFlags: toolConfig.extraFlags,\n };\n\n const invocation = adapter.buildInvocation(req);\n\n // Amp cost tracking: capture usage before\n const isAmp = (toolConfig.adapter ?? id) === 'amp';\n const usageBefore = isAmp ? await captureAmpUsage() : null;\n\n debug(`Dispatching ${id}`);\n onProgress?.({ toolId: id, event: 'started' });\n const result = await execute(invocation, toolTimeoutMs);\n\n // Amp cost tracking: capture usage after\n const usageAfter = isAmp ? await captureAmpUsage() : null;\n const cost =\n isAmp && usageBefore && usageAfter\n ? computeAmpCostFromSnapshots(usageBefore, usageAfter)\n : undefined;\n\n // Write output files\n const safeId = sanitizeId(id);\n const outputFile = join(outputDir, `${safeId}.md`);\n const stderrFile = join(outputDir, `${safeId}.stderr`);\n\n safeWriteFile(outputFile, result.stdout);\n safeWriteFile(stderrFile, result.stderr);\n\n if (cost) {\n const statsFile = join(outputDir, `${safeId}.stats.json`);\n safeWriteFile(statsFile, JSON.stringify({ cost }, null, 2));\n }\n\n const parsed = adapter.parseResult?.(result) ?? {};\n\n const report: ToolReport = {\n toolId: id,\n status: result.timedOut\n ? 'timeout'\n : result.exitCode === 0\n ? 'success'\n : 'error',\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n wordCount: result.stdout.split(/\\s+/).filter(Boolean).length,\n outputFile,\n stderrFile,\n cost: cost ?? undefined,\n error: result.exitCode !== 0 ? result.stderr.slice(0, 500) : undefined,\n ...parsed,\n };\n\n onProgress?.({ toolId: id, event: 'completed', report });\n\n return report;\n }),\n );\n\n const results = await Promise.allSettled(tasks);\n\n return results.map((r, i) => {\n if (r.status === 'fulfilled') return r.value;\n return {\n toolId: eligibleTools[i],\n status: 'error' as const,\n exitCode: 1,\n durationMs: 0,\n wordCount: 0,\n outputFile: '',\n stderrFile: '',\n error: r.reason?.message ?? 'Unknown error',\n };\n });\n}\n","import { mkdirSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport { MAX_SLUG_LENGTH } from '../constants.js';\n\n/**\n * Generate a slug from prompt text.\n * Lowercase, hyphens, max 40 chars.\n */\nexport function generateSlug(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, MAX_SLUG_LENGTH);\n}\n\n/**\n * Generate slug from a file path.\n * Uses the parent directory name if available, otherwise the filename.\n */\nexport function generateSlugFromFile(filePath: string): string {\n const dir = dirname(filePath);\n const dirName = basename(dir);\n // If parent dir has a meaningful name (not . or empty), use it\n if (dirName && dirName !== '.' && dirName !== '..') {\n return generateSlug(dirName);\n }\n return generateSlug(basename(filePath, '.md'));\n}\n\n/**\n * Resolve output directory, appending timestamp if exists.\n */\nexport function resolveOutputDir(baseDir: string, slug: string): string {\n let outputDir = join(baseDir, slug);\n try {\n mkdirSync(outputDir, { recursive: false });\n } catch (e: unknown) {\n if ((e as NodeJS.ErrnoException).code === 'EEXIST') {\n outputDir = `${outputDir}-${Date.now()}`;\n mkdirSync(outputDir, { recursive: true });\n } else {\n // Parent dirs may not exist yet\n mkdirSync(outputDir, { recursive: true });\n }\n }\n return outputDir;\n}\n\n/**\n * Build the standard prompt template wrapping user's inline prompt.\n */\nexport function buildPrompt(question: string, context?: string): string {\n const parts: string[] = [\n '# Second Opinion Request',\n '',\n '## Question',\n question,\n '',\n ];\n\n if (context) {\n parts.push('## Context', '', context, '');\n }\n\n parts.push(\n '## Instructions',\n 'You are providing an independent second opinion. Be critical and thorough.',\n '- Analyze the question in the context provided',\n '- Identify risks, tradeoffs, and blind spots',\n '- Suggest alternatives if you see better approaches',\n \"- Be direct and opinionated — don't hedge\",\n '- Structure your response with clear headings',\n '- Keep your response focused and actionable',\n '',\n );\n\n return parts.join('\\n');\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { sanitizeId } from '../constants.js';\nimport type { RunManifest, ToolReport } from '../types.js';\n\n/**\n * Generate a heuristic summary of run results (v1 — no LLM).\n */\nexport function synthesize(manifest: RunManifest, outputDir: string): string {\n const parts: string[] = [\n '# Run Summary',\n '',\n `**Prompt:** ${manifest.prompt.slice(0, 100)}${manifest.prompt.length > 100 ? '...' : ''}`,\n `**Tools:** ${manifest.tools.map((t) => t.toolId).join(', ')}`,\n `**Policy:** read-only=${manifest.readOnlyPolicy}`,\n '',\n ];\n\n // Per-tool summaries\n parts.push('## Results', '');\n\n for (const report of manifest.tools) {\n const icon =\n report.status === 'success'\n ? '✓'\n : report.status === 'timeout'\n ? '⏱'\n : '✗';\n const duration = (report.durationMs / 1000).toFixed(1);\n parts.push(`### ${icon} ${report.toolId}`);\n parts.push('');\n parts.push(`- Status: ${report.status}`);\n parts.push(`- Duration: ${duration}s`);\n parts.push(`- Word count: ${report.wordCount}`);\n\n if (report.cost) {\n parts.push(\n `- Cost: $${report.cost.cost_usd.toFixed(2)} (${report.cost.source})`,\n );\n }\n\n if (report.status === 'error' && report.error) {\n parts.push(`- Error: ${report.error}`);\n }\n\n // Extract headings from report file\n if (report.status === 'success') {\n const headings = extractHeadings(outputDir, report);\n if (headings.length > 0) {\n parts.push('- Key sections:');\n for (const h of headings) {\n parts.push(` - ${h}`);\n }\n }\n }\n\n parts.push('');\n }\n\n // Cost table (if any tools have cost info)\n const costsAvailable = manifest.tools.filter((t) => t.cost);\n if (costsAvailable.length > 0) {\n parts.push('## Cost Summary', '');\n parts.push('| Tool | Cost | Source | Remaining |');\n parts.push('|------|------|--------|-----------|');\n for (const t of costsAvailable) {\n const c = t.cost!;\n parts.push(\n `| ${t.toolId} | $${c.cost_usd.toFixed(2)} | ${c.source} | $${c.source === 'credits' ? c.credits_remaining_usd.toFixed(2) : c.free_remaining_usd.toFixed(2)} |`,\n );\n }\n parts.push('');\n }\n\n return parts.join('\\n');\n}\n\nfunction extractHeadings(outputDir: string, report: ToolReport): string[] {\n const filePath = join(outputDir, `${sanitizeId(report.toolId)}.md`);\n if (!existsSync(filePath)) return [];\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n const headings: string[] = [];\n for (const line of content.split('\\n')) {\n const match = line.match(/^#{1,3}\\s+(.+)/);\n if (match) {\n headings.push(match[1].trim());\n if (headings.length >= 10) break;\n }\n }\n return headings;\n } catch {\n return [];\n }\n}\n","import type { ToolReport } from '../types.js';\n\nconst SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];\nconst TICK_INTERVAL = 200;\nconst RED = '\\x1b[31m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\ntype ToolStatus = 'pending' | 'running' | 'done';\n\ninterface ToolState {\n toolId: string;\n status: ToolStatus;\n startedAt?: number;\n report?: ToolReport;\n}\n\nexport class ProgressDisplay {\n private tools: Map<string, ToolState>;\n private order: string[];\n private outputDir: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private frame = 0;\n private lineCount = 0;\n private isTTY: boolean;\n\n constructor(toolIds: string[], outputDir: string) {\n this.isTTY = Boolean(process.stderr.isTTY);\n this.outputDir = outputDir;\n this.tools = new Map();\n this.order = [];\n for (const id of toolIds) {\n this.tools.set(id, {\n toolId: id,\n status: 'pending',\n });\n this.order.push(id);\n }\n\n if (this.isTTY) {\n this.render();\n this.timer = setInterval(() => {\n this.frame++;\n this.render();\n }, TICK_INTERVAL);\n } else {\n process.stderr.write(` Output: ${this.outputDir}\\n`);\n }\n }\n\n start(toolId: string): void {\n const tool = this.tools.get(toolId);\n if (!tool) return;\n tool.status = 'running';\n tool.startedAt = Date.now();\n\n if (!this.isTTY) {\n process.stderr.write(` ▸ ${toolId} started\\n`);\n }\n }\n\n complete(toolId: string, report: ToolReport): void {\n const tool = this.tools.get(toolId);\n if (!tool) return;\n tool.status = 'done';\n tool.report = report;\n\n if (!this.isTTY) {\n const duration = (report.durationMs / 1000).toFixed(1);\n const icon =\n report.status === 'success'\n ? '✓'\n : report.status === 'timeout'\n ? '⏱'\n : '✗';\n process.stderr.write(\n ` ${icon} ${toolId} done ${duration}s ${report.wordCount.toLocaleString()} words\\n`,\n );\n if (report.status !== 'success' && report.error) {\n process.stderr.write(\n ` └ ${report.error.split('\\n')[0].slice(0, 120)}\\n`,\n );\n }\n }\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n if (this.isTTY) {\n this.render();\n }\n }\n\n private render(): void {\n const lines: string[] = [];\n lines.push(` ${DIM}Output: ${this.outputDir}${RESET}`);\n for (const id of this.order) {\n const tool = this.tools.get(id)!;\n lines.push(this.formatLine(tool));\n if (\n tool.status === 'done' &&\n tool.report?.status !== 'success' &&\n tool.report?.error\n ) {\n const msg = tool.report.error.split('\\n')[0].slice(0, 120);\n lines.push(` ${RED}└ ${msg}${RESET}`);\n }\n }\n\n // Move cursor up to overwrite previous output\n if (this.lineCount > 0) {\n process.stderr.write(`\\x1b[${this.lineCount}A`);\n }\n\n for (const line of lines) {\n process.stderr.write(`\\x1b[K${line}\\n`);\n }\n\n this.lineCount = lines.length;\n }\n\n private formatLine(tool: ToolState): string {\n const label = tool.toolId;\n\n switch (tool.status) {\n case 'pending': {\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ⏳ ${label}${pad}pending`;\n }\n case 'running': {\n const spinner = SPINNER_FRAMES[this.frame % SPINNER_FRAMES.length];\n const elapsed = tool.startedAt\n ? ((Date.now() - tool.startedAt) / 1000).toFixed(1)\n : '0.0';\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ${spinner} ${label}${pad}running ${elapsed.padStart(6)}s`;\n }\n case 'done': {\n const r = tool.report!;\n const icon =\n r.status === 'success' ? '✓' : r.status === 'timeout' ? '⏱' : '✗';\n const duration = (r.durationMs / 1000).toFixed(1);\n const pad = ' '.repeat(Math.max(0, 40 - label.length));\n return ` ${icon} ${label}${pad}done ${duration.padStart(6)}s ${r.wordCount.toLocaleString()} words`;\n }\n }\n }\n}\n","import type { Command } from 'commander';\nimport { info } from '../ui/logger.js';\n\nexport function registerSkillCommand(program: Command): void {\n program\n .command('skill')\n .description('Print a skill/slash-command template for coding agents')\n .action(async () => {\n const template = `---\nname: counselors\ndescription: Get parallel second opinions from multiple AI coding agents. Use when the user wants independent reviews, architecture feedback, or a sanity check from other AI models.\n---\n\n# Counselors — Multi-Agent Review Skill\n\n> **Note:** This is a reference skill template. Your agent system may use a different skill/command format. Adapt the structure and frontmatter below to match your system's conventions — the workflow and phases are what matter.\n\nFan out a prompt to multiple AI coding agents in parallel and synthesize their responses.\n\nArguments: $ARGUMENTS\n\n**If no arguments provided**, ask the user what they want reviewed.\n\n---\n\n## Phase 1: Context Gathering\n\nParse \\`$ARGUMENTS\\` to understand what the user wants reviewed. Then auto-gather relevant context:\n\n1. **Files mentioned in the prompt**: Use Glob/Grep to find files referenced by name, class, function, or keyword\n2. **Recent changes**: Run \\`git diff HEAD\\` and \\`git diff --staged\\` to capture recent work\n3. **Related code**: Search for key terms from the prompt and read the most relevant files (up to 5 files, ~50KB total cap)\n\nBe selective — don't dump the entire codebase. Pick the most relevant code sections.\n\n---\n\n## Phase 2: Agent Selection\n\n1. **Discover available agents** by running via Bash:\n \\`\\`\\`bash\n counselors ls\n \\`\\`\\`\n This lists all configured agents with their IDs and binaries.\n\n2. **MANDATORY: Print the full agent list, then ask the user which to use.**\n\n **Always print the full \\`counselors ls\\` output as inline text** (not inside AskUserQuestion). Just show the raw output from the command so the user sees every agent with its ID and binary. Do NOT reformat or abbreviate it.\n\n Then ask the user to pick:\n\n **If 4 or fewer agents**: Use AskUserQuestion with \\`multiSelect: true\\`, one option per agent.\n\n **If more than 4 agents**: AskUserQuestion only supports 4 options. Use these fixed options:\n - Option 1: \"All [N] agents\" — sends to every configured agent\n - Option 2-4: The first 3 individual agents by ID\n - The user can always select \"Other\" to type a comma-separated list of agent IDs from the printed list above\n\n Do NOT combine agents into preset groups (e.g. \"claude + codex + gemini\"). Each option must be a single agent or \"All\".\n\n3. Wait for the user's selection before proceeding.\n\n4. **MANDATORY: Confirm the selection before continuing.** After the user picks agents, echo back the exact list you will dispatch to:\n\n > Dispatching to: **claude-opus**, **codex-5.3-high**, **gemini-pro**\n\n Then ask the user to confirm (e.g. \"Look good?\") before proceeding to Phase 3. This prevents silent tool omissions. If the user corrects the list, update your selection accordingly.\n\n---\n\n## Phase 3: Prompt Assembly\n\n1. **Generate a slug** from the topic (lowercase, hyphens, max 40 chars)\n - \"review the auth flow\" → \\`auth-flow-review\\`\n - \"is this migration safe\" → \\`migration-safety-review\\`\n\n2. **Create the output directory** via Bash. The directory name MUST always be prefixed with a millisecond-precision UNIX timestamp so runs are lexically sortable and never collide:\n \\`\\`\\`\n ./agents/counselors/TIMESTAMP-[slug]\n \\`\\`\\`\n For example: \\`./agents/counselors/1770676882780-auth-flow-review\\`\n\n3. **Write the prompt file** using the Write tool to \\`./agents/counselors/TIMESTAMP-[slug]/prompt.md\\`:\n\n\\`\\`\\`markdown\n# Review Request\n\n## Question\n[User's original prompt/question from $ARGUMENTS]\n\n## Context\n\n### Files Referenced\n[Contents of the most relevant files found in Phase 1]\n\n### Recent Changes\n[git diff output, if any]\n\n### Related Code\n[Related files discovered via search]\n\n## Instructions\nYou are providing an independent review. Be critical and thorough.\n- Analyze the question in the context provided\n- Identify risks, tradeoffs, and blind spots\n- Suggest alternatives if you see better approaches\n- Be direct and opinionated — don't hedge\n- Structure your response with clear headings\n\\`\\`\\`\n\n---\n\n## Phase 4: Dispatch\n\nRun counselors via Bash with the prompt file, passing the user's selected agents:\n\n\\`\\`\\`bash\ncounselors run -f ./agents/counselors/[slug]/prompt.md --tools [comma-separated-selections] --json\n\\`\\`\\`\n\nExample: \\`--tools claude,codex,gemini\\`\n\nUse \\`timeout: 600000\\` (10 minutes). Counselors dispatches to the selected agents in parallel and writes results to the output directory shown in the JSON output.\n\n**Important**: Use \\`-f\\` (file mode) so the prompt is sent as-is without wrapping. Use \\`--json\\` to get structured output for parsing.\n\n---\n\n## Phase 5: Read Results\n\n1. **Parse the JSON output** from stdout — it contains the run manifest with status, duration, word count, and output file paths for each agent\n2. **Read each agent's response** from the \\`outputFile\\` path in the manifest\n3. **Check \\`stderrFile\\` paths** for any agent that failed or returned empty output\n4. **Skip empty or error-only reports** — note which agents failed\n\n---\n\n## Phase 6: Synthesize and Present\n\nCombine all agent responses into a synthesis:\n\n\\`\\`\\`markdown\n## Counselors Review\n\n**Agents consulted:** [list of agents that responded]\n\n**Consensus:** [What most agents agree on — key takeaways]\n\n**Disagreements:** [Where they differ, and reasoning behind each position]\n\n**Key Risks:** [Risks or concerns flagged by any agent]\n\n**Blind Spots:** [Things none of the agents addressed that seem important]\n\n**Recommendation:** [Your synthesized recommendation based on all inputs]\n\n---\nReports saved to: [output directory from manifest]\n\\`\\`\\`\n\nPresent this synthesis to the user. Be concise — the individual reports are saved for deep reading.\n\n---\n\n## Phase 7: Action (Optional)\n\nAfter presenting the synthesis, ask the user what they'd like to address. Offer the top 2-3 actionable items from the synthesis as options. If the user wants to act on findings, plan the implementation before making changes.\n\n---\n\n## Error Handling\n\n- **counselors not installed**: Tell the user to install it (\\`npm install -g counselors\\`)\n- **No tools configured**: Tell the user to run \\`counselors init\\` or \\`counselors add\\`\n- **Agent fails**: Note it in the synthesis and continue with other agents' results\n- **All agents fail**: Report errors from stderr files and suggest checking \\`counselors doctor\\`\n`;\n\n info(template);\n });\n}\n","import { accessSync, constants } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Command } from 'commander';\nimport {\n getAdapter,\n getAllBuiltInAdapters,\n isBuiltInTool,\n} from '../../adapters/index.js';\nimport { SAFE_ID_RE } from '../../constants.js';\nimport { copyAmpSettings } from '../../core/amp-utils.js';\nimport { addToolToConfig, loadConfig, saveConfig } from '../../core/config.js';\nimport { discoverTool, findBinary } from '../../core/discovery.js';\nimport type { ReadOnlyLevel, ToolConfig } from '../../types.js';\nimport { error, info, success, warn } from '../../ui/logger.js';\nimport { createSpinner } from '../../ui/output.js';\nimport {\n confirmAction,\n confirmOverwrite,\n promptInput,\n promptSelect,\n selectModelDetails,\n} from '../../ui/prompts.js';\n\nconst CUSTOM_TOOL_VALUE = '__custom__';\n\n/**\n * Interactive wizard to pick a tool when none is specified.\n * Discovers built-in tools, lets user pick one or add a custom tool.\n * Returns the toolId to add.\n */\nasync function runAddWizard(): Promise<{ toolId: string; isCustom: boolean }> {\n const spinner = createSpinner('Discovering installed tools...').start();\n\n const adapters = getAllBuiltInAdapters();\n const discovered: {\n id: string;\n name: string;\n found: boolean;\n version: string | null;\n }[] = [];\n\n for (const adapter of adapters) {\n const result = discoverTool(adapter.commands);\n discovered.push({\n id: adapter.id,\n name: adapter.displayName,\n found: result.found,\n version: result.version,\n });\n }\n\n spinner.stop();\n\n const choices = discovered.map((d) => ({\n name: d.found\n ? `${d.name} (${d.id})${d.version ? ` — ${d.version}` : ''}`\n : `${d.name} (${d.id}) — not installed`,\n value: d.id,\n disabled: !d.found ? '(not installed)' : undefined,\n }));\n\n choices.push({\n name: 'Custom tool — provide a binary path',\n value: CUSTOM_TOOL_VALUE,\n disabled: undefined,\n });\n\n const selected = await promptSelect<string>(\n 'Which tool would you like to add?',\n choices as any,\n );\n\n if (selected === CUSTOM_TOOL_VALUE) {\n return { toolId: '', isCustom: true };\n }\n\n return { toolId: selected, isCustom: false };\n}\n\n/**\n * Validate that a binary path exists and is executable.\n * Resolves relative paths against cwd. Also tries `which` for bare commands.\n */\nfunction validateBinary(input: string): string | null {\n // Try as absolute/relative path first\n const resolved = resolve(input);\n try {\n accessSync(resolved, constants.X_OK);\n return resolved;\n } catch {\n // Fall through\n }\n\n // Try finding it in PATH\n const found = findBinary(input);\n if (found) return found;\n\n return null;\n}\n\nasync function addBuiltInTool(\n toolId: string,\n config: ReturnType<typeof loadConfig>,\n nameOverride?: string,\n): Promise<void> {\n const adapter = getAdapter(toolId);\n const discovery = discoverTool(adapter.commands);\n\n if (!discovery.found) {\n error(\n `\"${toolId}\" binary not found. Install it from: ${adapter.installUrl}`,\n );\n process.exitCode = 1;\n return;\n }\n\n const selectedModel = await selectModelDetails(toolId, adapter.models);\n\n // Pick a name for this tool config\n const defaultName =\n nameOverride ?? selectedModel.compoundId ?? `${toolId}-${selectedModel.id}`;\n let name = nameOverride ?? (await promptInput('Tool name:', defaultName));\n\n if (!SAFE_ID_RE.test(name)) {\n error(\n `Invalid tool name \"${name}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Check for conflicts\n if (config.tools[name]) {\n const overwrite = await confirmOverwrite(name);\n if (!overwrite) {\n // Let them pick a different name\n name = await promptInput('Pick a different name:');\n if (!SAFE_ID_RE.test(name)) {\n error(\n `Invalid tool name \"${name}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n if (config.tools[name]) {\n error(`\"${name}\" also exists. Run \"counselors tools add\" again.`);\n process.exitCode = 1;\n return;\n }\n }\n }\n\n const toolConfig: ToolConfig = {\n binary: discovery.path!,\n readOnly: { level: adapter.readOnly.level },\n adapter: toolId,\n ...(selectedModel.extraFlags\n ? { extraFlags: selectedModel.extraFlags }\n : {}),\n };\n\n const updated = addToolToConfig(config, name, toolConfig);\n saveConfig(updated);\n if (toolId === 'amp') {\n copyAmpSettings();\n }\n success(`Added \"${name}\" to config.`);\n}\n\nasync function collectCustomConfig(\n config: ReturnType<typeof loadConfig>,\n presetId?: string,\n): Promise<void> {\n // Get and validate binary\n let binaryPath: string | null = null;\n while (!binaryPath) {\n const binaryInput = await promptInput('Binary path or command:');\n binaryPath = validateBinary(binaryInput);\n if (!binaryPath) {\n warn(`\"${binaryInput}\" not found or not executable. Please try again.`);\n }\n }\n\n // Prompt delivery — stdin or CLI argument\n const useStdin = await confirmAction(\n 'Does this tool receive prompts via stdin?',\n );\n\n // Collect flags\n info('');\n info(' Counselors runs tools non-interactively. Your flags MUST include:');\n info(\n ' 1. Headless/non-interactive mode (e.g. -p, --non-interactive, --headless)',\n );\n info(' 2. Model selection if needed (e.g. --model gpt-4o)');\n info(' 3. Output format if needed (e.g. --output-format text)');\n info('');\n if (!useStdin) {\n info(' Counselors will append the prompt as the last CLI argument:');\n info(\n ' \"Read the file at <path> and follow the instructions within it.\"',\n );\n } else {\n info(' Counselors will pipe the prompt text to stdin.');\n }\n info('');\n info(' Example: -p --model gpt-4o --output-format text');\n info('');\n let extraFlags: string[] | undefined;\n const flagsInput = await promptInput('Flags (space-separated):');\n if (flagsInput.trim()) {\n extraFlags = flagsInput.trim().split(/\\s+/);\n }\n\n const readOnlyLevel = await promptSelect<ReadOnlyLevel>(\n 'Read-only capability:',\n [\n { name: 'Enforced — tool guarantees read-only', value: 'enforced' },\n {\n name: 'Best effort — tool tries but may not guarantee',\n value: 'bestEffort',\n },\n { name: 'None — tool has full access', value: 'none' },\n ],\n );\n\n // Get tool ID\n const defaultId =\n presetId ??\n binaryPath\n .split('/')\n .pop()\n ?.replace(/\\.[^.]+$/, '') ??\n 'custom';\n const toolId = await promptInput(\n 'Tool name (used in config and output filenames):',\n defaultId,\n );\n\n if (!SAFE_ID_RE.test(toolId)) {\n error(\n `Invalid tool name \"${toolId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n // Preview\n info('');\n info(' Tool will be invoked as:');\n const previewArgs = [\n ...(extraFlags ?? []),\n useStdin\n ? '< prompt.md'\n : '\"Read the file at <path> and follow the instructions...\"',\n ];\n info(` ${binaryPath} ${previewArgs.join(' ')}`);\n info('');\n\n if (config.tools[toolId]) {\n const overwrite = await confirmOverwrite(toolId);\n if (!overwrite) {\n const newId = await promptInput('Pick a different name:');\n if (!SAFE_ID_RE.test(newId)) {\n error(\n `Invalid tool name \"${newId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n if (config.tools[newId]) {\n error(`\"${newId}\" also exists. Run \"counselors tools add\" again.`);\n process.exitCode = 1;\n return;\n }\n const toolConfig: ToolConfig = {\n binary: binaryPath,\n readOnly: { level: readOnlyLevel },\n ...(useStdin ? { stdin: true } : {}),\n extraFlags,\n custom: true,\n };\n const updated = addToolToConfig(config, newId, toolConfig);\n saveConfig(updated);\n success(`Added \"${newId}\" to config.`);\n return;\n }\n }\n\n const toolConfig: ToolConfig = {\n binary: binaryPath,\n readOnly: { level: readOnlyLevel },\n ...(useStdin ? { stdin: true } : {}),\n extraFlags,\n custom: true,\n };\n\n const updated = addToolToConfig(config, toolId, toolConfig);\n saveConfig(updated);\n success(`Added \"${toolId}\" to config.`);\n}\n\nexport function registerAddCommand(program: Command): void {\n program\n .command('add [tool]')\n .description('Add a tool (claude, codex, gemini, amp, or custom)')\n .action(async (toolId?: string) => {\n const config = loadConfig();\n\n if (!toolId) {\n // Interactive wizard\n const result = await runAddWizard();\n if (result.isCustom) {\n await collectCustomConfig(config);\n } else {\n await addBuiltInTool(result.toolId, config);\n }\n return;\n }\n\n // Direct add (original flow)\n if (isBuiltInTool(toolId)) {\n await addBuiltInTool(toolId, config, toolId);\n } else {\n await collectCustomConfig(config, toolId);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { getAllBuiltInAdapters } from '../../adapters/index.js';\nimport { discoverTool } from '../../core/discovery.js';\nimport { info } from '../../ui/logger.js';\nimport { createSpinner, formatDiscoveryResults } from '../../ui/output.js';\n\nexport function registerDiscoverCommand(program: Command): void {\n program\n .command('discover')\n .description('Discover installed AI CLI tools')\n .action(async () => {\n const spinner = createSpinner('Scanning for AI CLI tools...').start();\n const adapters = getAllBuiltInAdapters();\n const results = [];\n\n for (const adapter of adapters) {\n const result = discoverTool(adapter.commands);\n results.push({\n ...result,\n toolId: adapter.id,\n displayName: adapter.displayName,\n });\n }\n\n spinner.stop();\n info(formatDiscoveryResults(results));\n });\n}\n","import type { Command } from 'commander';\nimport { resolveAdapter } from '../../adapters/index.js';\nimport { loadConfig } from '../../core/config.js';\nimport { info } from '../../ui/logger.js';\nimport { formatToolList } from '../../ui/output.js';\n\nexport function registerListCommand(program: Command): void {\n program\n .command('list')\n .alias('ls')\n .description('List configured tools')\n .option('-v, --verbose', 'Show full tool configuration including flags')\n .action(async (opts: { verbose?: boolean }) => {\n const config = loadConfig();\n\n const tools = Object.entries(config.tools).map(([id, t]) => {\n const entry: { id: string; binary: string; args?: string[] } = {\n id,\n binary: t.binary,\n };\n\n if (opts.verbose) {\n const adapter = resolveAdapter(id, t);\n const inv = adapter.buildInvocation({\n prompt: '<prompt>',\n promptFilePath: '<prompt-file>',\n toolId: id,\n outputDir: '.',\n readOnlyPolicy: t.readOnly.level,\n timeout: t.timeout ?? config.defaults.timeout,\n cwd: process.cwd(),\n binary: t.binary,\n extraFlags: t.extraFlags,\n });\n entry.args = inv.args;\n }\n\n return entry;\n });\n\n info(formatToolList(tools, opts.verbose));\n });\n}\n","import { checkbox } from '@inquirer/prompts';\nimport type { Command } from 'commander';\nimport {\n loadConfig,\n removeToolFromConfig,\n saveConfig,\n} from '../../core/config.js';\nimport { error, info, success } from '../../ui/logger.js';\nimport { confirmAction } from '../../ui/prompts.js';\n\nexport function registerRemoveCommand(program: Command): void {\n program\n .command('remove [tool]')\n .description('Remove a configured tool')\n .action(async (toolId?: string) => {\n const config = loadConfig();\n const toolIds = Object.keys(config.tools);\n\n if (toolIds.length === 0) {\n error('No tools configured.');\n process.exitCode = 1;\n return;\n }\n\n let toRemove: string[];\n\n if (toolId) {\n if (!config.tools[toolId]) {\n error(`Tool \"${toolId}\" is not configured.`);\n process.exitCode = 1;\n return;\n }\n toRemove = [toolId];\n } else {\n toRemove = await checkbox({\n message: 'Select tools to remove:',\n choices: toolIds.map((id) => ({\n name: `${id} (${config.tools[id].binary})`,\n value: id,\n })),\n });\n\n if (toRemove.length === 0) {\n info('No tools selected.');\n return;\n }\n }\n\n const confirmed = await confirmAction(\n toRemove.length === 1\n ? `Remove \"${toRemove[0]}\" from config?`\n : `Remove ${toRemove.length} tools from config?`,\n );\n if (!confirmed) return;\n\n let updated = config;\n for (const id of toRemove) {\n updated = removeToolFromConfig(updated, id);\n }\n saveConfig(updated);\n success(`Removed ${toRemove.join(', ')}.`);\n });\n}\n","import type { Command } from 'commander';\nimport { SAFE_ID_RE } from '../../constants.js';\nimport {\n loadConfig,\n renameToolInConfig,\n saveConfig,\n} from '../../core/config.js';\nimport { error, success } from '../../ui/logger.js';\n\nexport function registerRenameCommand(program: Command): void {\n program\n .command('rename <old> <new>')\n .description('Rename a configured tool')\n .action(async (oldId: string, newId: string) => {\n const config = loadConfig();\n\n if (!config.tools[oldId]) {\n error(`Tool \"${oldId}\" is not configured.`);\n process.exitCode = 1;\n return;\n }\n\n if (config.tools[newId]) {\n error(`Tool \"${newId}\" already exists.`);\n process.exitCode = 1;\n return;\n }\n\n if (!SAFE_ID_RE.test(newId)) {\n error(\n `Invalid tool name \"${newId}\". Use only letters, numbers, dots, hyphens, and underscores.`,\n );\n process.exitCode = 1;\n return;\n }\n\n const updated = renameToolInConfig(config, oldId, newId);\n saveConfig(updated);\n success(`Renamed \"${oldId}\" → \"${newId}\".`);\n });\n}\n","import type { Command } from 'commander';\nimport { resolveAdapter } from '../../adapters/index.js';\nimport { loadConfig } from '../../core/config.js';\nimport { executeTest } from '../../core/executor.js';\nimport type { TestResult } from '../../types.js';\nimport { error, info } from '../../ui/logger.js';\nimport { createSpinner, formatTestResults } from '../../ui/output.js';\n\nexport function registerTestCommand(program: Command): void {\n program\n .command('test [tools...]')\n .description('Test configured tools with a \"reply OK\" prompt')\n .action(async (toolIds: string[]) => {\n const config = loadConfig();\n\n const idsToTest =\n toolIds.length > 0 ? toolIds : Object.keys(config.tools);\n\n if (idsToTest.length === 0) {\n error('No tools configured. Run \"counselors init\" first.');\n process.exitCode = 1;\n return;\n }\n\n const results: TestResult[] = [];\n\n for (const id of idsToTest) {\n const toolConfig = config.tools[id];\n if (!toolConfig) {\n results.push({\n toolId: id,\n passed: false,\n output: '',\n error: 'Not configured',\n durationMs: 0,\n });\n continue;\n }\n\n const spinner = createSpinner(`Testing ${id}...`).start();\n const adapter = resolveAdapter(id, toolConfig);\n const result = await executeTest(adapter, toolConfig, id);\n spinner.stop();\n\n results.push(result);\n }\n\n info(formatTestResults(results));\n\n if (results.some((r) => !r.passed)) {\n process.exitCode = 1;\n }\n });\n}\n"],"mappings":"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","names":["program","existsSync","existsSync","z","existsSync","z","tools","existsSync","readFileSync","homedir","join","join","homedir","existsSync","readFileSync","tools","program","existsSync","existsSync","mkdirSync","dirname","resolve","mkdirSync","resolve","dirname","existsSync","resolve","tools","program","adapters","discoveries","foundTools","config","spinner","copyFileSync","readFileSync","basename","join","resolve","execFileSync","readFileSync","statSync","resolve","resolve","statSync","readFileSync","execFileSync","join","join","mkdirSync","dirname","join","dirname","join","mkdirSync","existsSync","readFileSync","join","join","existsSync","readFileSync","program","resolve","readFileSync","baseDir","join","copyFileSync","basename","program","accessSync","constants","resolve","input","resolve","accessSync","constants","toolConfig","updated","program","program","program","tools","checkbox","program","checkbox","program","program"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "counselors",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Fan out prompts to multiple AI coding agents in parallel",
5
5
  "type": "module",
6
6
  "bin": {