@agentic-patterns/cli 0.1.6 → 0.1.8
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.
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Agentic Patterns Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-D4qwNZMb.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-whvaenaU.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/dist/cli.js
CHANGED
|
@@ -1106,7 +1106,7 @@ function detectRunnerFromEnv() {
|
|
|
1106
1106
|
return { provider: "ollama", detail: `env OLLAMA_HOST \u2192 ${pinned} (AGENT_MODEL)` };
|
|
1107
1107
|
}
|
|
1108
1108
|
const tier = process.env.AGENT_TIER ?? "sonnet";
|
|
1109
|
-
const model = tier === "opus" ? "qwen3:
|
|
1109
|
+
const model = tier === "opus" ? "qwen3.6:35b-a3b" : tier === "haiku" ? "qwen3.5:4b" : "qwen3.5:9b";
|
|
1110
1110
|
return {
|
|
1111
1111
|
provider: "ollama",
|
|
1112
1112
|
detail: `env OLLAMA_HOST \u2192 ${model} (tier=${tier})`
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/agents.ts","../src/commands/config.ts","../src/commands/init.ts","../src/constants.ts","../src/commands/playground.ts","../src/commands/run.ts","../src/commands/status.ts","../src/helpers/config.ts","../src/helpers/discover.ts"],"sourcesContent":["/**\n * `ap` — agentic patterns CLI.\n *\n * Single-dispatch shape (mirrors codegen-patterns/cli.ts):\n * parseArgs → switch(command) → run<Name>Command(...).\n *\n * Bare `ap` shows a status dashboard (mirrors `st`).\n */\n\nimport { parseArgs } from \"node:util\";\nimport { runAgentsCommand } from \"./commands/agents.js\";\nimport { runConfigSetCommand, runConfigStatusCommand } from \"./commands/config.js\";\nimport { type Provider, runInitCommand } from \"./commands/init.js\";\nimport { runPlaygroundCommand } from \"./commands/playground.js\";\nimport { runRunCommand } from \"./commands/run.js\";\nimport { runStatusCommand } from \"./commands/status.js\";\nimport { resolveProjectConfig } from \"./helpers/config.js\";\nimport { discoverAgents } from \"./helpers/discover.js\";\n\nconst USAGE = `\nap — agentic patterns\n\nUsage:\n ap status dashboard\n ap <command> [options]\n\nCommands:\n agents list discovered agents\n run <agent> [message] chat in terminal — interactive or one-shot\n playground launch UI environment (server + dashboard)\n init [<dir>] scaffold a new agent project\n config show env detection status\n config set interactive .env editor\n\nOptions:\n -h, --help show this help\n --port <port> server port for playground (default 3456)\n --no-dashboard playground without dashboard (API only)\n --no-open don't auto-open the browser\n --agents <glob> override agent discovery glob\n --with-plugin (init) drop the Claude Code plugin too\n --provider <p> (init) anthropic | openai | ollama\n --link (init) use file: deps against the local\n monorepo (dogfooding before publish)\n`;\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: { type: \"boolean\", short: \"h\" },\n port: { type: \"string\" },\n \"no-dashboard\": { type: \"boolean\" },\n \"no-open\": { type: \"boolean\" },\n agents: { type: \"string\" },\n \"with-plugin\": { type: \"boolean\" },\n provider: { type: \"string\" },\n link: { type: \"boolean\" },\n },\n allowPositionals: true,\n strict: false,\n });\n\n if (values.help) {\n process.stdout.write(`${USAGE}\\n`);\n return;\n }\n\n const command = positionals[0];\n\n // `init` scaffolds a NEW project — it must NOT require an existing\n // package.json upward of CWD, so dispatch it before project context.\n if (command === \"init\") {\n const targetDir = positionals[1];\n const providerRaw = values.provider ? String(values.provider) : undefined;\n await runInitCommand({\n targetDir,\n withPlugin: Boolean(values[\"with-plugin\"]),\n provider: providerRaw as Provider | undefined,\n link: Boolean(values.link),\n });\n return;\n }\n\n // Project context — every other command needs it.\n const config = resolveProjectConfig();\n const globs = values.agents ? [String(values.agents)] : config.agents;\n const { agents, errors } = await discoverAgents(config.root, globs);\n\n switch (command) {\n case undefined: {\n runStatusCommand({ config, agents, loadErrors: errors });\n return;\n }\n\n case \"agents\": {\n runAgentsCommand({ agents, loadErrors: errors, root: config.root });\n return;\n }\n\n case \"run\": {\n const agentId = positionals[1];\n if (!agentId) {\n process.stderr.write(`error: ap run requires an agent id\\n${USAGE}\\n`);\n process.exit(1);\n }\n const message = positionals.slice(2).join(\" \") || undefined;\n await runRunCommand({ agents, agentId, message });\n return;\n }\n\n case \"playground\": {\n const port = values.port ? Number.parseInt(String(values.port), 10) : config.port;\n await runPlaygroundCommand({\n agents,\n port,\n noDashboard: Boolean(values[\"no-dashboard\"]),\n open: !values[\"no-open\"],\n });\n return;\n }\n\n case \"config\": {\n const sub = positionals[1];\n if (sub === \"set\") {\n await runConfigSetCommand({ config });\n } else if (sub === undefined) {\n runConfigStatusCommand({ config });\n } else {\n process.stderr.write(`error: unknown config subcommand \"${sub}\"\\n${USAGE}\\n`);\n process.exit(1);\n }\n return;\n }\n\n default: {\n process.stderr.write(`error: unknown command \"${command}\"\\n${USAGE}\\n`);\n process.exit(1);\n }\n }\n}\n\nmain().catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`\\x1b[31merror:\\x1b[0m ${msg}\\n`);\n process.exit(1);\n});\n","/**\n * `ap agents` — full list of discovered agents.\n *\n * Verbose form of the bare `ap` status's `agents` row. Shows each agent's\n * id, name, source file, and (if present) description.\n */\n\nimport path from \"node:path\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst YELLOW = \"\\x1b[33m\";\n\ninterface AgentsInput {\n agents: DiscoveredAgent[];\n loadErrors: { file: string; error: Error }[];\n root: string;\n}\n\nexport function runAgentsCommand(input: AgentsInput): void {\n const { agents, loadErrors, root } = input;\n\n process.stdout.write(\"\\n\");\n\n if (agents.length === 0) {\n process.stdout.write(\n ` ${DIM}no agents discovered. Drop a file at ./agents/<name>/agent.ts that default-exports { id, name, agent }.${RESET}\\n\\n`,\n );\n } else {\n process.stdout.write(\n ` ${BOLD}${agents.length} agent${agents.length === 1 ? \"\" : \"s\"}${RESET}\\n\\n`,\n );\n const idCol = Math.max(...agents.map((a) => a.id.length), 8);\n for (const a of agents) {\n const rel = path.relative(root, a.file);\n process.stdout.write(` ${a.id.padEnd(idCol)} ${a.name} ${DIM}${rel}${RESET}\\n`);\n if (a.description) {\n process.stdout.write(` ${\"\".padEnd(idCol)} ${DIM}${a.description}${RESET}\\n`);\n }\n }\n process.stdout.write(\"\\n\");\n }\n\n if (loadErrors.length > 0) {\n process.stdout.write(` ${YELLOW}${loadErrors.length} load error(s):${RESET}\\n`);\n for (const err of loadErrors) {\n process.stdout.write(` ${YELLOW}!${RESET} ${err.file}: ${err.error.message}\\n`);\n }\n process.stdout.write(\"\\n\");\n }\n}\n","/**\n * `ap config` (no args) — show env detection status.\n * `ap config set` — interactive .env editor.\n *\n * Mirrors the noun-as-status pattern: bare `config` reports state,\n * `config set` performs the action.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isCancel, password, select, text } from \"@clack/prompts\";\nimport type { ProjectConfig } from \"../helpers/config.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\n\ninterface ConfigInput {\n config: ProjectConfig;\n}\n\ninterface EnvVarSpec {\n key: string;\n label: string;\n /** Should the value be hidden when prompting? */\n secret: boolean;\n}\n\nconst TRACKED_ENV: readonly EnvVarSpec[] = [\n { key: \"ANTHROPIC_API_KEY\", label: \"Anthropic API key\", secret: true },\n { key: \"OPENAI_API_KEY\", label: \"OpenAI API key\", secret: true },\n { key: \"GOOGLE_GENERATIVE_AI_API_KEY\", label: \"Google API key\", secret: true },\n { key: \"GROQ_API_KEY\", label: \"Groq API key\", secret: true },\n { key: \"MISTRAL_API_KEY\", label: \"Mistral API key\", secret: true },\n { key: \"XAI_API_KEY\", label: \"xAI API key\", secret: true },\n { key: \"DEEPSEEK_API_KEY\", label: \"DeepSeek API key\", secret: true },\n { key: \"OPENROUTER_API_KEY\", label: \"OpenRouter API key\", secret: true },\n { key: \"OLLAMA_HOST\", label: \"Ollama host URL\", secret: false },\n { key: \"AGENT_TIER\", label: \"Default tier (opus | sonnet | haiku)\", secret: false },\n { key: \"AGENT_MODEL\", label: \"Pinned model id (overrides tier)\", secret: false },\n];\n\n/** Bare `ap config` — show status. */\nexport function runConfigStatusCommand(input: ConfigInput): void {\n const { config } = input;\n const envFile = path.join(config.root, \".env\");\n const envExists = fs.existsSync(envFile);\n\n process.stdout.write(\"\\n\");\n process.stdout.write(` ${BOLD}config${RESET}\\n\\n`);\n process.stdout.write(\n ` .env ${envExists ? `${GREEN}loaded${RESET} ${DIM}from ${path.relative(process.cwd(), envFile)}${RESET}` : `${DIM}not present${RESET}`}\\n`,\n );\n\n const longestKey = Math.max(...TRACKED_ENV.map((e) => e.key.length));\n for (const spec of TRACKED_ENV) {\n const value = process.env[spec.key];\n const padded = spec.key.padEnd(longestKey);\n if (value) {\n const display = spec.secret ? maskSecret(value) : value;\n process.stdout.write(` ${padded} ${GREEN}✓${RESET} ${DIM}${display}${RESET}\\n`);\n } else {\n process.stdout.write(` ${padded} ${DIM}— not set${RESET}\\n`);\n }\n }\n process.stdout.write(\"\\n\");\n process.stdout.write(` ${DIM}ap config set to edit interactively${RESET}\\n\\n`);\n}\n\n/** `ap config set` — interactive editor that writes to `.env`. */\nexport async function runConfigSetCommand(input: ConfigInput): Promise<void> {\n const { config } = input;\n const envFile = path.join(config.root, \".env\");\n\n // Pick which var to set\n const choice = await select({\n message: \"Which env var?\",\n options: TRACKED_ENV.map((spec) => {\n const current = process.env[spec.key];\n const hint = current ? (spec.secret ? maskSecret(current) : current) : \"not set\";\n return {\n value: spec.key,\n label: spec.key,\n hint,\n };\n }),\n });\n\n if (isCancel(choice)) {\n process.stdout.write(`\\n${DIM}cancelled${RESET}\\n`);\n return;\n }\n\n const spec = TRACKED_ENV.find((e) => e.key === choice);\n if (!spec) return;\n\n const prompt = spec.secret ? password : text;\n const value = await prompt({\n message: `${spec.label} (${spec.key}):`,\n placeholder: process.env[spec.key] ?? \"\",\n });\n\n if (isCancel(value)) {\n process.stdout.write(`\\n${DIM}cancelled${RESET}\\n`);\n return;\n }\n\n upsertEnvFile(envFile, spec.key, String(value));\n process.stdout.write(\n `\\n ${GREEN}✓${RESET} wrote ${BOLD}${spec.key}${RESET} to ${path.relative(process.cwd(), envFile)}\\n\\n`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// helpers\n// ---------------------------------------------------------------------------\n\nfunction maskSecret(v: string): string {\n if (v.length <= 8) return \"•\".repeat(v.length);\n return `${v.slice(0, 4)}${\"•\".repeat(Math.min(8, v.length - 8))}${v.slice(-4)}`;\n}\n\n/** Insert or replace a single KEY=VALUE line in the .env file. Creates if missing. */\nfunction upsertEnvFile(file: string, key: string, value: string): void {\n let lines: string[] = [];\n if (fs.existsSync(file)) {\n lines = fs.readFileSync(file, \"utf-8\").split(\"\\n\");\n }\n const prefix = `${key}=`;\n const idx = lines.findIndex((l) => l.trim().startsWith(prefix));\n const formatted = `${key}=${value}`;\n if (idx === -1) {\n if (lines.length > 0 && lines[lines.length - 1] !== \"\") lines.push(\"\");\n lines.push(formatted);\n } else {\n lines[idx] = formatted;\n }\n fs.writeFileSync(\n file,\n `${lines.filter((l, i, arr) => !(l === \"\" && i === arr.length - 1)).join(\"\\n\")}\\n`,\n );\n\n // Reflect immediately in the current process's env so subsequent commands see it.\n if (!process.env[key] || process.env[key] !== value) {\n process.env[key] = value;\n }\n}\n","/**\n * `ap init [--with-plugin] [--provider=anthropic|openai|ollama] [<project-name>]`\n *\n * Scaffolds a consumer project: package.json, .env.example, tsconfig.json, and\n * a working `agents/demo/agent.ts`. Optionally also drops a Claude Code plugin\n * (`.claude-plugin/` + `hooks/`) by copying from the monorepo root when the CLI\n * is being run from source.\n *\n * Project layout produced:\n *\n * <target>/\n * ├── package.json\n * ├── .env.example\n * ├── tsconfig.json\n * ├── agents/\n * │ └── demo/\n * │ └── agent.ts\n * └── [if --with-plugin]\n * ├── .claude-plugin/plugin.json\n * └── hooks/{hooks.json,emit.mjs}\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isCancel, select, text } from \"@clack/prompts\";\nimport { DEFAULT_DASHBOARD_URL } from \"../constants.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport type Provider = \"anthropic\" | \"openai\" | \"ollama\";\n\nexport interface InitOptions {\n /**\n * Where to scaffold. If absent, prompt for a project name and create\n * `<cwd>/<name>/`. If present and equal to `\".\"`, scaffold into cwd directly.\n */\n targetDir?: string;\n /** Drop `.claude-plugin/` + `hooks/` next to the project. */\n withPlugin?: boolean;\n /** Which AI SDK provider to wire into the demo agent. */\n provider?: Provider;\n /**\n * Scaffold INTO the local monorepo's `examples/<name>/` with `workspace:*`\n * deps. Required for dogfooding until the `@agentic-patterns/*` packages\n * are published. Overrides `targetDir`.\n */\n link?: boolean;\n}\n\nconst DIM = \"\\x1b[2m\";\nconst BOLD = \"\\x1b[1m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\nconst RESET = \"\\x1b[0m\";\n\nconst VALID_PROVIDERS: readonly Provider[] = [\"anthropic\", \"openai\", \"ollama\"] as const;\n\n/**\n * Entry point. Resolves missing options interactively, writes files, then\n * prints next-steps banner.\n */\nexport async function runInitCommand(opts: InitOptions): Promise<void> {\n // -------------------------------------------------------------------------\n // 1. Resolve target directory\n //\n // `--link` scaffolds into `<monorepoRoot>/examples/<name>/` so `workspace:*`\n // deps resolve — the only pre-publish path that actually produces a working\n // `pnpm install`. Otherwise, target is `<cwd>/<name>/` (or `.` for in-place).\n // -------------------------------------------------------------------------\n let targetDir: string;\n let projectName: string;\n let monorepoRoot: string | null = null;\n\n if (opts.link) {\n monorepoRoot = resolveMonorepoRoot();\n if (!monorepoRoot) {\n process.stderr.write(\n \"error: --link requires the CLI to be run from the agentic-patterns-ts source tree\\n\",\n );\n process.exit(1);\n }\n const name = opts.targetDir ?? (await promptName());\n if (name === null) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n projectName = name;\n targetDir = path.join(monorepoRoot, \"examples\", projectName);\n } else if (opts.targetDir === undefined) {\n const name = await promptName();\n if (name === null) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n projectName = name;\n targetDir = path.resolve(process.cwd(), projectName);\n } else if (opts.targetDir === \".\") {\n targetDir = process.cwd();\n projectName = path.basename(targetDir);\n } else {\n targetDir = path.resolve(process.cwd(), opts.targetDir);\n projectName = path.basename(targetDir);\n }\n\n // -------------------------------------------------------------------------\n // 2. Resolve provider\n // -------------------------------------------------------------------------\n let provider: Provider;\n if (opts.provider !== undefined) {\n if (!VALID_PROVIDERS.includes(opts.provider)) {\n process.stderr.write(\n `error: invalid --provider \"${opts.provider}\" (expected anthropic | openai | ollama)\\n`,\n );\n process.exit(1);\n }\n provider = opts.provider;\n } else {\n const answer = await select({\n message: \"provider\",\n options: [\n { value: \"anthropic\" as const, label: \"Anthropic (Claude)\" },\n { value: \"openai\" as const, label: \"OpenAI (GPT)\" },\n { value: \"ollama\" as const, label: \"Ollama (local)\" },\n ],\n initialValue: \"anthropic\" as const,\n });\n if (isCancel(answer)) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n provider = answer as Provider;\n }\n\n // -------------------------------------------------------------------------\n // 3. Pre-flight: target dir must be empty (or not exist)\n // -------------------------------------------------------------------------\n if (fs.existsSync(targetDir)) {\n const stat = fs.statSync(targetDir);\n if (!stat.isDirectory()) {\n process.stderr.write(`error: target ${targetDir} exists and is not a directory\\n`);\n process.exit(1);\n }\n const conflicts = [\"package.json\", \"agents\", \"tsconfig.json\"].filter((n) =>\n fs.existsSync(path.join(targetDir, n)),\n );\n if (conflicts.length > 0) {\n process.stderr.write(\n `error: target ${targetDir} already contains: ${conflicts.join(\", \")}\\n`,\n );\n process.exit(1);\n }\n } else {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // -------------------------------------------------------------------------\n // 4. Write project files\n // -------------------------------------------------------------------------\n const created: string[] = [];\n\n writeFile(\n targetDir,\n \"package.json\",\n renderPackageJson(projectName, provider, opts.link === true),\n created,\n );\n writeFile(targetDir, \".env.example\", renderEnvExample(provider), created);\n writeFile(targetDir, \"tsconfig.json\", renderTsConfig(), created);\n writeFile(targetDir, path.join(\"agents\", \"demo\", \"agent.ts\"), renderAgent(provider), created);\n\n // -------------------------------------------------------------------------\n // 5. Optional plugin\n // -------------------------------------------------------------------------\n let pluginNote: string | null = null;\n if (opts.withPlugin) {\n const pluginSrc = resolvePluginSource();\n if (pluginSrc) {\n copyDir(pluginSrc.pluginDir, path.join(targetDir, \".claude-plugin\"));\n copyDir(pluginSrc.hooksDir, path.join(targetDir, \"hooks\"));\n created.push(\".claude-plugin/\", \"hooks/\");\n\n // Mirror hooks.json into .claude/settings.json so Claude Code activates\n // them immediately for sessions started in this directory. If the user\n // already has a settings.json, merge our hooks into it non-destructively\n // (preserve their other keys; skip events where our hook is already\n // registered so re-running `ap init` is idempotent).\n const settingsDir = path.join(targetDir, \".claude\");\n const settingsPath = path.join(settingsDir, \"settings.json\");\n const hooksSource = fs.readFileSync(path.join(pluginSrc.hooksDir, \"hooks.json\"), \"utf8\");\n const ourHooks = JSON.parse(\n hooksSource.replaceAll(\"${CLAUDE_PLUGIN_ROOT}\", \"${CLAUDE_PROJECT_DIR}\"),\n ) as HookSettings;\n\n const mergeOutcome = mergeHookSettings(settingsPath, ourHooks);\n fs.mkdirSync(settingsDir, { recursive: true });\n fs.writeFileSync(settingsPath, `${JSON.stringify(mergeOutcome.merged, null, 2)}\\n`);\n if (mergeOutcome.kind === \"created\") {\n created.push(\".claude/settings.json\");\n } else if (mergeOutcome.kind === \"merged\") {\n created.push(\n `.claude/settings.json ${DIM}(merged ${mergeOutcome.added} hook entries)${RESET}`,\n );\n } else {\n created.push(`.claude/settings.json ${DIM}(already up to date)${RESET}`);\n }\n } else {\n // TODO(phase-2): package the plugin template inside\n // packages/agent-cli/assets/plugin-template/ during build so this works\n // when the CLI is installed via npm.\n pluginNote = `${YELLOW}warning${RESET}: --with-plugin requested but plugin source not found.\\n ${DIM}Run from the agentic-patterns-ts source tree, or wait for plugin packaging (Phase 2).${RESET}`;\n }\n }\n\n // -------------------------------------------------------------------------\n // 6. Banner\n // -------------------------------------------------------------------------\n const rel = path.relative(process.cwd(), targetDir) || \".\";\n process.stdout.write(`\\n ${GREEN}created${RESET} ${BOLD}${rel}${RESET}\\n\\n`);\n for (const f of created) {\n process.stdout.write(` ${DIM}+ ${f}${RESET}\\n`);\n }\n if (pluginNote) {\n process.stdout.write(`\\n ${pluginNote}\\n`);\n }\n process.stdout.write(`\\n ${BOLD}next${RESET}\\n`);\n\n if (opts.link && monorepoRoot) {\n // Install runs at the monorepo root so workspace:* resolves for every\n // transitive @agentic-patterns/* dep.\n const rootRel = path.relative(process.cwd(), monorepoRoot) || \".\";\n const projRel = path.relative(monorepoRoot, targetDir);\n if (rootRel !== \".\") {\n process.stdout.write(` cd ${rootRel}\\n`);\n }\n process.stdout.write(\n ` bun install ${DIM}# picks up the new example${RESET}\\n`,\n );\n process.stdout.write(` cd ${projRel}\\n`);\n process.stdout.write(\n ` cp .env.example .env ${DIM}# fill in your ${envKeyFor(provider)}${RESET}\\n`,\n );\n process.stdout.write(` bun run dev ${DIM}# launch playground${RESET}\\n\\n`);\n } else {\n if (rel !== \".\") {\n process.stdout.write(` cd ${rel}\\n`);\n }\n process.stdout.write(\n ` cp .env.example .env ${DIM}# fill in your ${envKeyFor(provider)}${RESET}\\n`,\n );\n process.stdout.write(\" bun install\\n\");\n process.stdout.write(` bun run dev ${DIM}# launch playground${RESET}\\n\\n`);\n }\n}\n\nasync function promptName(): Promise<string | null> {\n const answer = await text({\n message: \"project name\",\n placeholder: \"my-agents\",\n validate: (v) => (v.trim().length === 0 ? \"name is required\" : undefined),\n });\n if (isCancel(answer)) return null;\n return String(answer).trim();\n}\n\n// ---------------------------------------------------------------------------\n// File templates\n// ---------------------------------------------------------------------------\n\nfunction renderPackageJson(name: string, provider: Provider, link: boolean): string {\n const providerDep = providerSdkPackage(provider);\n const apVersion = link ? \"workspace:*\" : \"^0.1.0\";\n\n const pkg = {\n name,\n private: true,\n version: \"0.0.1\",\n type: \"module\",\n scripts: {\n dev: \"ap playground\",\n start: \"ap playground\",\n agents: \"ap agents\",\n },\n dependencies: {\n \"@agentic-patterns/core\": apVersion,\n \"@agentic-patterns/runtime\": apVersion,\n \"@agentic-patterns/cli\": apVersion,\n ai: \"^4.0.0\",\n [providerDep]: \"^1.0.0\",\n zod: \"^3.23.0\",\n },\n devDependencies: {\n \"@types/node\": \"^22.0.0\",\n typescript: \"^5.7.0\",\n },\n };\n return `${JSON.stringify(pkg, null, 2)}\\n`;\n}\n\nfunction renderEnvExample(provider: Provider): string {\n const lines = [\n \"# Dashboard URL — used by the Claude Code plugin to ship lifecycle events\",\n `AP_DASHBOARD_URL=${DEFAULT_DASHBOARD_URL}`,\n \"\",\n \"# Default model tier — opus | sonnet | haiku (used by the agent runner)\",\n \"AGENT_TIER=sonnet\",\n \"\",\n \"# Optional: pin an exact model id; wins over AGENT_TIER. Useful when\",\n \"# your provider has a model the framework's tier map doesn't list\",\n \"# (e.g. AGENT_MODEL=qwen3.6:27b for an Ollama box).\",\n \"# AGENT_MODEL=\",\n \"\",\n ];\n if (provider === \"anthropic\") {\n lines.push(\"# Anthropic API key (https://console.anthropic.com/)\");\n lines.push(\"ANTHROPIC_API_KEY=sk-ant-...\");\n } else if (provider === \"openai\") {\n lines.push(\"# OpenAI API key (https://platform.openai.com/api-keys)\");\n lines.push(\"OPENAI_API_KEY=sk-...\");\n } else {\n lines.push(\"# Ollama host (default http://localhost:11434)\");\n lines.push(\"OLLAMA_HOST=http://localhost:11434\");\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction renderTsConfig(): string {\n const cfg = {\n compilerOptions: {\n target: \"es2022\",\n module: \"nodenext\",\n moduleResolution: \"nodenext\",\n lib: [\"es2022\"],\n outDir: \"dist\",\n rootDir: \"src\",\n strict: true,\n noUncheckedIndexedAccess: true,\n noUnusedLocals: true,\n noUnusedParameters: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n declaration: true,\n sourceMap: true,\n },\n include: [\"agents/**/*.ts\", \"src/**/*.ts\"],\n exclude: [\"node_modules\", \"dist\"],\n };\n return `${JSON.stringify(cfg, null, 2)}\\n`;\n}\n\nfunction renderAgent(provider: Provider): string {\n // The agent file conforms to the discovery contract: default-export an\n // AgentRegistration `{ id, name, description, agent }`. The CLI's playground\n // injects the runner — we don't need to construct one here, but we leave the\n // provider import wired up so users can graduate to a custom runner easily.\n return `/**\n * Demo agent — generated by \\`ap init\\`.\n *\n * The default export is an AgentRegistration. The \\`ap\\` CLI discovers this\n * file (via \\`agents/**\\\\/agent.ts\\`), builds a runner from your environment\n * (using ${provider}), and wires it into the playground dashboard.\n *\n * bun run dev # launch the dashboard at http://localhost:3456\n * ap run demo # chat with this agent in the terminal\n */\n\nimport {\n AgentBuilder,\n Capability,\n Judgment,\n Mission,\n Persona,\n Responsibility,\n RoleBuilder,\n type ToolDefinition,\n Toolbox,\n} from \"@agentic-patterns/core\";\nimport { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// A tiny toolbox so the agent has something concrete to do.\n// ---------------------------------------------------------------------------\n\nclass GreetingToolbox extends Toolbox {\n readonly name = \"greeting_tools\";\n readonly description = \"Friendly greeting helpers\";\n\n readonly tools: Record<string, ToolDefinition> = {\n greet: {\n description: \"Produce a friendly greeting for a person\",\n parameters: z.object({\n name: z.string().describe(\"Person's name\"),\n }),\n execute: async (args) => {\n const { name } = args as { name: string };\n return { greeting: \\`Hello, \\${name}! Welcome to agentic-patterns.\\` };\n },\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Build the agent.\n// ---------------------------------------------------------------------------\n\nconst role = new RoleBuilder(\"demo-assistant\")\n .withPersona(\n new Persona({\n identity: \"A friendly demo assistant that greets people warmly\",\n tone: \"warm and concise\",\n priorities: [\"being helpful\", \"showing the framework off\"],\n principles: [\"Always use the greet tool when greeting someone\"],\n }),\n )\n .withJudgment(\n new Judgment({\n domain: \"greetings and small talk\",\n heuristics: [\"Use the greet tool for any name-based greeting\"],\n constraints: [\"Stay friendly and concise\"],\n }),\n )\n .withCapability(\n new Capability(\"greeting_tools\", \"Friendly greeting helpers\", new GreetingToolbox()),\n )\n .withResponsibility(\n new Responsibility({\n key: \"greet\",\n name: \"Greet People\",\n description: \"Greet people warmly using the greet tool\",\n }),\n )\n .withDefaultModel(\"sonnet\")\n .build();\n\nconst mission = new Mission({\n objective: \"Demonstrate the @agentic-patterns/core building blocks end-to-end\",\n success_criteria: [\"Greets users by name\", \"Uses the greet tool for every greeting\"],\n});\n\nconst agent = new AgentBuilder(role).withMission(mission).build();\n\n// ---------------------------------------------------------------------------\n// Default export — discovered by \\`ap\\`. The runner is injected by the CLI.\n// ---------------------------------------------------------------------------\n\nexport default {\n id: \"demo\",\n name: \"Demo\",\n description: \"A friendly demo assistant generated by \\`ap init\\`\",\n agent,\n};\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction envKeyFor(provider: Provider): string {\n switch (provider) {\n case \"anthropic\":\n return \"ANTHROPIC_API_KEY\";\n case \"openai\":\n return \"OPENAI_API_KEY\";\n case \"ollama\":\n return \"OLLAMA_HOST\";\n }\n}\n\nfunction providerSdkPackage(provider: Provider): string {\n switch (provider) {\n case \"anthropic\":\n return \"@ai-sdk/anthropic\";\n case \"openai\":\n return \"@ai-sdk/openai\";\n case \"ollama\":\n return \"ollama-ai-provider\";\n }\n}\n\nfunction writeFile(root: string, rel: string, contents: string, log: string[]): void {\n const dest = path.join(root, rel);\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, contents, \"utf8\");\n log.push(rel);\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.cpSync(src, dest, { recursive: true });\n}\n\n// ---------------------------------------------------------------------------\n// Hook settings merge\n//\n// Claude Code users frequently already have a `.claude/settings.json` with\n// their own hooks, permissions, or model preferences. We must not clobber it.\n// `mergeHookSettings` preserves existing top-level keys and adds our hook\n// entries only where they don't already exist — same command string under the\n// same event + matcher counts as \"already registered\", so re-running\n// `ap init --with-plugin` is idempotent.\n// ---------------------------------------------------------------------------\n\ntype HookEntry = { type: string; command: string; async?: boolean; timeout?: number };\ntype HookMatcher = { matcher: string; hooks: HookEntry[] };\ntype HookSettings = { hooks: Record<string, HookMatcher[]>; [key: string]: unknown };\n\ntype MergeOutcome =\n | { kind: \"created\"; merged: HookSettings }\n | { kind: \"merged\"; merged: HookSettings; added: number }\n | { kind: \"unchanged\"; merged: HookSettings };\n\nfunction mergeHookSettings(settingsPath: string, ours: HookSettings): MergeOutcome {\n if (!fs.existsSync(settingsPath)) {\n return { kind: \"created\", merged: ours };\n }\n\n let existing: HookSettings;\n try {\n existing = JSON.parse(fs.readFileSync(settingsPath, \"utf8\")) as HookSettings;\n } catch {\n // Malformed user file — back up and treat as fresh write, so we never\n // silently drop their content.\n const backup = `${settingsPath}.ap-backup-${Date.now()}`;\n fs.renameSync(settingsPath, backup);\n process.stdout.write(\n `${YELLOW}warning${RESET}: existing .claude/settings.json was malformed; moved to ${path.basename(backup)}\\n`,\n );\n return { kind: \"created\", merged: ours };\n }\n\n const merged: HookSettings = { ...existing, hooks: { ...(existing.hooks ?? {}) } };\n let added = 0;\n\n for (const event of Object.keys(ours.hooks)) {\n const ourMatchers = ours.hooks[event] ?? [];\n const theirMatchers = merged.hooks[event] ?? [];\n const result = [...theirMatchers];\n\n for (const ourMatcher of ourMatchers) {\n const theirMatcher = result.find((m) => m.matcher === ourMatcher.matcher);\n if (!theirMatcher) {\n result.push(ourMatcher);\n added += ourMatcher.hooks.length;\n continue;\n }\n for (const ourHook of ourMatcher.hooks) {\n const duplicate = theirMatcher.hooks.some(\n (h) => h.type === ourHook.type && h.command === ourHook.command,\n );\n if (!duplicate) {\n theirMatcher.hooks.push(ourHook);\n added += 1;\n }\n }\n }\n\n merged.hooks[event] = result;\n }\n\n if (added === 0) return { kind: \"unchanged\", merged };\n return { kind: \"merged\", merged, added };\n}\n\n/**\n * Try to find `.claude-plugin/` and `hooks/`.\n *\n * Two possible locations:\n * 1. Bundled inside the published CLI tarball at\n * `packages/agent-cli/assets/plugin-template/` (checked first — works\n * when the CLI is installed via `npm install -g @agentic-patterns/cli`)\n * 2. The monorepo root (dogfood path — walks up from the running script)\n */\nfunction resolvePluginSource(): { pluginDir: string; hooksDir: string } | null {\n const here = path.dirname(fileURLToPath(import.meta.url));\n\n // Candidate 1 (priority): bundled plugin-template inside the CLI package.\n // Source run: src/commands/init.ts → ../../assets/plugin-template/\n // Dist run: dist/cli.js → ../assets/plugin-template/\n const bundledCandidates = [\n path.resolve(here, \"../assets/plugin-template\"),\n path.resolve(here, \"../../assets/plugin-template\"),\n ];\n for (const base of bundledCandidates) {\n const pluginDir = path.join(base, \".claude-plugin\");\n const hooksDir = path.join(base, \"hooks\");\n if (fs.existsSync(pluginDir) && fs.existsSync(hooksDir)) {\n return { pluginDir, hooksDir };\n }\n }\n\n // Candidate 2: monorepo root (for local `bun --filter` / tsx runs).\n const root = resolveMonorepoRoot();\n if (root) {\n return { pluginDir: path.join(root, \".claude-plugin\"), hooksDir: path.join(root, \"hooks\") };\n }\n return null;\n}\n\n/**\n * Locate the monorepo root by walking up from this file. The root is\n * identified by having `packages/agent-core/` and a `workspaces` field in\n * package.json (bun workspace marker — replaces the old pnpm-workspace.yaml).\n */\nfunction resolveMonorepoRoot(): string | null {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n let cur = here;\n for (let i = 0; i < 8; i++) {\n const rootPkgPath = path.join(cur, \"package.json\");\n if (fs.existsSync(rootPkgPath) && fs.existsSync(path.join(cur, \"packages\", \"agent-core\"))) {\n try {\n const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, \"utf8\")) as {\n workspaces?: string[];\n };\n if (rootPkg.workspaces && rootPkg.workspaces.length > 0) {\n return cur;\n }\n } catch {\n // malformed json — fall through\n }\n }\n const parent = path.dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Single source of truth for CLI-level defaults.\n *\n * Anything hardcoded here (ports, URLs, timeouts) should be imported by\n * consumers rather than duplicated. The one exception is `hooks/emit.mjs` —\n * it's a zero-dependency standalone script that runs in user projects and\n * can't import from the workspace. Its inlined fallback must be kept in sync\n * manually; see the comment in that file.\n */\n\n/**\n * Default port for `ap playground` and the Hono server.\n *\n * Chosen to avoid the crowded :3000 range (Next.js, Create React App, Vite,\n * most template-generated dev servers). Users with existing setups on :3000\n * don't have to stop anything to try us out.\n */\nexport const DEFAULT_DASHBOARD_PORT = 3456;\n\n/** Default URL the Claude Code hook plugin POSTs to. */\nexport const DEFAULT_DASHBOARD_URL = `http://localhost:${DEFAULT_DASHBOARD_PORT}`;\n","/**\n * `ap playground` — start the full UI environment (Hono API + admin dashboard)\n * for a project's discovered agents.\n *\n * This command is the \"one command to chat with my agents\" UX: it wires the\n * standard observability stack (event bus + collector + admin service + SSE\n * exporter), picks a runner via `createRunner()` (env-driven), attaches that\n * runner to each `AgentRegistration`, mounts the pre-built dashboard as a\n * SPA at `/`, and opens the browser.\n *\n * The caller (`cli.ts`) is responsible for discovering agents from the user's\n * project and passing them in as `opts.agents`.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { createReadStream, existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n AgentEventBus,\n InMemoryAdminService,\n InMemoryEventCollector,\n SSEExporter,\n createRunner,\n createToolboxExecutor,\n} from \"@agentic-patterns/runtime\";\nimport { createServer } from \"@agentic-patterns/server\";\nimport type { AgentRegistration } from \"@agentic-patterns/server\";\nimport { serve } from \"@hono/node-server\";\nimport { DEFAULT_DASHBOARD_PORT } from \"../constants.js\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface PlaygroundOptions {\n /** Agents discovered by the caller (without runners — playground attaches one). */\n agents: DiscoveredAgent[];\n /** Port for the HTTP server. Defaults to {@link DEFAULT_DASHBOARD_PORT}. */\n port?: number;\n /** Skip the dashboard — API only. */\n noDashboard?: boolean;\n /** Auto-open the dashboard URL in a browser. Defaults to true. */\n open?: boolean;\n}\n\n/**\n * Start the playground: Hono server + dashboard + observability stack,\n * wired to the caller's pre-discovered agents.\n *\n * Resolves once the server is listening. Does not return; the Node process\n * stays alive holding the HTTP server until the user kills it.\n */\nexport async function runPlaygroundCommand(opts: PlaygroundOptions): Promise<void> {\n const port = opts.port ?? DEFAULT_DASHBOARD_PORT;\n const shouldOpen = opts.open !== false;\n const serveDashboard = opts.noDashboard !== true;\n\n // -------------------------------------------------------------------------\n // 1. Observability stack\n // -------------------------------------------------------------------------\n\n const eventBus = new AgentEventBus();\n\n const collector = new InMemoryEventCollector();\n collector.attach(eventBus);\n\n const adminService = new InMemoryAdminService(collector);\n\n const sseExporter = new SSEExporter();\n sseExporter.attach(eventBus);\n\n // -------------------------------------------------------------------------\n // 2. Runner — env-driven auto-detection\n // -------------------------------------------------------------------------\n\n const selection = await createRunner({\n eventBus,\n tier: (process.env.AGENT_TIER as \"opus\" | \"sonnet\" | \"haiku\" | undefined) ?? \"sonnet\",\n verbose: false,\n });\n const { runner } = selection;\n\n // -------------------------------------------------------------------------\n // 3. Attach runner to each registration\n // -------------------------------------------------------------------------\n\n const registrations: AgentRegistration[] = opts.agents.map((reg) => ({\n id: reg.id,\n name: reg.name,\n description: reg.description,\n agent: reg.agent,\n runner,\n }));\n // Mark createToolboxExecutor as \"imported for re-export discoverability\" —\n // the conversation route already builds executors per request.\n void createToolboxExecutor;\n\n // -------------------------------------------------------------------------\n // 4. Build the Hono app with API routes FIRST\n // -------------------------------------------------------------------------\n\n const app = createServer({\n agents: registrations,\n adminService,\n eventBus,\n sseExporter,\n });\n\n // -------------------------------------------------------------------------\n // 5. Mount the dashboard SPA (after API routes so API wins)\n // -------------------------------------------------------------------------\n\n const dashboardDir = resolveDashboardDir();\n let dashboardMounted = false;\n\n if (serveDashboard) {\n if (dashboardDir && existsSync(dashboardDir)) {\n mountDashboard(app, dashboardDir);\n dashboardMounted = true;\n } else {\n const where = dashboardDir ?? \"<unresolved>\";\n process.stderr.write(\n `[playground] warning: dashboard assets not found at ${where} — API-only mode.\\n run \\`pnpm --filter @agentic-patterns/cli build\\` (or \\`build:dashboard\\`) to build the SPA bundle.\\n`,\n );\n }\n }\n\n // -------------------------------------------------------------------------\n // 6. Start the HTTP server\n // -------------------------------------------------------------------------\n\n await new Promise<void>((resolve) => {\n serve({ fetch: app.fetch, port }, () => {\n resolve();\n });\n });\n\n // -------------------------------------------------------------------------\n // 7. Banner\n // -------------------------------------------------------------------------\n\n const baseUrl = `http://localhost:${port}`;\n const agentList = registrations.map((a) => a.name).join(\", \") || \"(none)\";\n const lines = [\n \"\",\n ` api ${baseUrl}`,\n dashboardMounted ? ` dashboard ${baseUrl}` : \" dashboard (disabled)\",\n ` agents ${agentList}`,\n ` runner ${selection.source} — ${selection.reason}`,\n \"\",\n ];\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n\n // -------------------------------------------------------------------------\n // 8. Open the browser\n // -------------------------------------------------------------------------\n\n if (shouldOpen && dashboardMounted) {\n openBrowser(baseUrl);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the absolute path to the bundled dashboard assets.\n *\n * Layout after `pnpm --filter @agentic-patterns/cli build`:\n * packages/agent-cli/\n * dist/cli.js ← import.meta.url lands here\n * assets/dashboard/ ← built SPA\n *\n * When running from source (tsx), the same `../assets/dashboard/` relative\n * layout holds if `build:dashboard` has been run at least once.\n */\nfunction resolveDashboardDir(): string | null {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(here, \"../assets/dashboard\");\n } catch {\n return null;\n }\n}\n\n/**\n * Known API route prefixes — any GET that matches one of these is never\n * rewritten to `index.html`. Keep in sync with `createServer()` routes.\n */\nconst API_PREFIXES = [\"/agents\", \"/conversations\", \"/admin\", \"/health\"];\n\nfunction isApiPath(pathname: string): boolean {\n return API_PREFIXES.some((p) => pathname === p || pathname.startsWith(`${p}/`));\n}\n\n/**\n * Register a static-file + SPA-fallback handler on the Hono app. This is\n * mounted after `createServer()`'s routes, so API endpoints win the match.\n *\n * We avoid `@hono/node-server/serve-static` because it requires a\n * cwd-relative root; the CLI needs an absolute path resolved from\n * `import.meta.url`.\n */\nfunction mountDashboard(app: ReturnType<typeof createServer>, dashboardDir: string): void {\n const indexPath = path.join(dashboardDir, \"index.html\");\n\n app.get(\"*\", async (c) => {\n if (c.req.method !== \"GET\") {\n return c.notFound();\n }\n\n const url = new URL(c.req.url);\n const pathname = decodeURIComponent(url.pathname);\n\n if (isApiPath(pathname)) {\n return c.notFound();\n }\n\n // Try the literal asset first; fall back to index.html for SPA routes.\n const assetPath = pathname === \"/\" ? indexPath : safeJoin(dashboardDir, pathname);\n\n if (assetPath && existsSync(assetPath) && statSync(assetPath).isFile()) {\n return streamFile(assetPath);\n }\n\n if (existsSync(indexPath)) {\n return streamFile(indexPath);\n }\n\n return c.notFound();\n });\n}\n\n/**\n * Join `base` + `rel` and reject the result if it escapes `base` (defense\n * against `..`-traversal). Returns `null` on any escape attempt.\n */\nfunction safeJoin(base: string, rel: string): string | null {\n const joined = path.join(base, rel);\n const normalizedBase = path.resolve(base);\n const normalizedJoined = path.resolve(joined);\n if (\n normalizedJoined !== normalizedBase &&\n !normalizedJoined.startsWith(`${normalizedBase}${path.sep}`)\n ) {\n return null;\n }\n return normalizedJoined;\n}\n\n/**\n * Stream a file from disk as a Fetch `Response`. Sets a minimal content-type\n * based on the extension — good enough for a dashboard SPA (html/js/css/svg/png).\n */\nfunction streamFile(filePath: string): Response {\n const ext = path.extname(filePath).toLowerCase();\n const contentType = MIME[ext] ?? \"application/octet-stream\";\n\n const nodeStream = createReadStream(filePath);\n const webStream = new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on(\"data\", (chunk) => {\n const bytes =\n typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : new Uint8Array(chunk);\n controller.enqueue(bytes);\n });\n nodeStream.on(\"end\", () => controller.close());\n nodeStream.on(\"error\", (err) => controller.error(err));\n },\n cancel() {\n nodeStream.destroy();\n },\n });\n\n return new Response(webStream, {\n status: 200,\n headers: { \"content-type\": contentType },\n });\n}\n\nconst MIME: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n};\n\n/**\n * Cross-platform \"open this URL in the default browser\". Best-effort —\n * swallows errors so a headless environment doesn't crash the playground.\n */\nfunction openBrowser(url: string): void {\n const { platform } = process;\n const { cmd, args } =\n platform === \"darwin\"\n ? { cmd: \"open\", args: [url] }\n : platform === \"win32\"\n ? { cmd: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n : { cmd: \"xdg-open\", args: [url] };\n\n try {\n const child = spawn(cmd, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {\n /* ignore — e.g. xdg-open missing in a container */\n });\n child.unref();\n } catch {\n /* ignore */\n }\n}\n","/**\n * `ap run <agentId> [message]` — chat with a single agent from the terminal.\n *\n * Two modes:\n * • one-shot — `message` provided; stream once, print, exit.\n * • interactive — no `message`; REPL loop via @clack/prompts.\n *\n * Rendering is raw ANSI (no chalk dep). Events come from the runtime as a\n * discriminated `AgentEvent` union; we project each type to a terminal line.\n */\n\nimport {\n Conversation,\n createRunner,\n createToolboxExecutor,\n getAgentEventBus,\n} from \"@agentic-patterns/runtime\";\nimport type { AgentEvent } from \"@agentic-patterns/runtime\";\nimport { isCancel, text } from \"@clack/prompts\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface RunOptions {\n /** All discovered agents; the caller owns discovery. */\n agents: DiscoveredAgent[];\n /** Which agent to chat with. Matched against `AgentRegistration.id`. */\n agentId: string;\n /** If present → one-shot mode; if absent → interactive REPL. */\n message?: string;\n}\n\n/**\n * Entry point for the `ap run` command. Returns when the chat session ends.\n * Exits the process non-zero on agent-not-found.\n */\nexport async function runRunCommand(opts: RunOptions): Promise<void> {\n const reg = opts.agents.find((a) => a.id === opts.agentId);\n if (!reg) {\n const available = opts.agents.map((a) => a.id).join(\", \") || \"(none)\";\n process.stderr.write(\n `${red(`agent \"${opts.agentId}\" not found`)}\\n available: ${available}\\n`,\n );\n process.exit(1);\n }\n\n const eventBus = getAgentEventBus();\n const { runner } = await createRunner({ eventBus, verbose: false });\n\n const conversation = new Conversation(reg.agent, runner, {\n toolExecutor: createToolboxExecutor(reg.agent),\n });\n\n if (opts.message !== undefined) {\n await streamOnce(conversation, opts.message);\n return;\n }\n\n await runRepl(conversation, reg);\n}\n\n// ---------------------------------------------------------------------------\n// Modes\n// ---------------------------------------------------------------------------\n\nasync function streamOnce(conversation: Conversation, message: string): Promise<void> {\n const controller = new AbortController();\n const onSigint = (): void => {\n controller.abort();\n };\n process.on(\"SIGINT\", onSigint);\n try {\n await renderStream(conversation.stream(message), controller.signal);\n } finally {\n process.off(\"SIGINT\", onSigint);\n }\n}\n\nasync function runRepl(conversation: Conversation, reg: DiscoveredAgent): Promise<void> {\n const banner = `chatting with ${bold(reg.agent.role.name)} ${dim(\"·\")} ${dim(\n \"type /exit to quit\",\n )}`;\n process.stdout.write(`${banner}\\n\\n`);\n\n for (;;) {\n const input = await text({ message: \"you\" });\n if (isCancel(input)) {\n process.stdout.write(`${dim(\"bye.\")}\\n`);\n return;\n }\n const line = (input as string).trim();\n if (line === \"\") continue;\n if (line === \"/exit\" || line === \"/quit\") {\n process.stdout.write(`${dim(\"bye.\")}\\n`);\n return;\n }\n\n const controller = new AbortController();\n const onSigint = (): void => {\n controller.abort();\n };\n process.on(\"SIGINT\", onSigint);\n try {\n await renderStream(conversation.stream(line), controller.signal);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stdout.write(`\\n${red(`error: ${msg}`)}\\n`);\n } finally {\n process.off(\"SIGINT\", onSigint);\n }\n process.stdout.write(\"\\n\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Event rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Drain an AgentEvent stream to the terminal. Honours `signal` so Ctrl+C in\n * interactive mode can abort the current exchange.\n */\nasync function renderStream(\n stream: AsyncGenerator<AgentEvent>,\n signal: AbortSignal,\n): Promise<void> {\n let inThinking = false;\n for await (const event of stream) {\n if (signal.aborted) {\n // Drop the rest; the runner will eventually settle.\n await safeReturn(stream);\n process.stdout.write(`\\n${yellow(\"aborted.\")}\\n`);\n return;\n }\n inThinking = renderEvent(event, inThinking);\n }\n}\n\n/**\n * Render a single event. Returns the updated `inThinking` flag so the caller\n * can close a reasoning block cleanly when the next non-thinking event fires.\n */\nfunction renderEvent(event: AgentEvent, inThinking: boolean): boolean {\n switch (event.type) {\n case \"agent.message.start\":\n process.stdout.write(`${bold(\"assistant\")}: `);\n return inThinking;\n\n case \"agent.message.chunk\":\n process.stdout.write(event.delta);\n return inThinking;\n\n case \"agent.thinking.start\":\n process.stdout.write(`\\n ${dim(\"💭 thinking…\")}\\n`);\n return true;\n\n case \"agent.reasoning\":\n if (event.isComplete) {\n process.stdout.write(\"\\n\");\n return false;\n }\n process.stdout.write(` ${dim(`💭 ${event.content}`)}\\n`);\n return true;\n\n case \"agent.tool.start\": {\n const args = formatArgs(event.arguments);\n process.stdout.write(`\\n ${cyan(`🔧 ${event.toolName}(${args})`)}\\n`);\n return inThinking;\n }\n\n case \"agent.tool.end\": {\n if (event.error) {\n process.stdout.write(` ${red(`✗ ${event.error}`)}\\n`);\n } else {\n const preview = previewResult(event.result);\n process.stdout.write(` ${dim(`→ ${preview}`)}\\n`);\n }\n return inThinking;\n }\n\n case \"agent.message.complete\": {\n const footer = `${event.model} · ${event.inputTokens}↓ ${event.outputTokens}↑`;\n process.stdout.write(`\\n${dim(footer)}\\n`);\n return inThinking;\n }\n\n case \"agent.error\":\n process.stdout.write(`\\n ${red(`⚠ ${event.errorType}: ${event.message}`)}\\n`);\n return inThinking;\n\n default:\n // Ignore iteration/llm/conversation/tool.intent/tool.rejected/etc.\n return inThinking;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Best-effort early-terminate of an async generator without throwing. */\nasync function safeReturn(stream: AsyncGenerator<AgentEvent>): Promise<void> {\n try {\n await stream.return(undefined);\n } catch {\n // swallow — abort path is best-effort\n }\n}\n\n/** Render a tool-call args object compactly; fall back to JSON.stringify. */\nfunction formatArgs(args: Record<string, unknown>): string {\n try {\n const entries = Object.entries(args);\n if (entries.length === 0) return \"\";\n const parts = entries.map(([k, v]) => `${k}=${shortJson(v)}`);\n const joined = parts.join(\", \");\n return joined.length > 120 ? `${joined.slice(0, 117)}...` : joined;\n } catch {\n return \"…\";\n }\n}\n\n/** Collapse a tool result into a single readable line. */\nfunction previewResult(result: unknown): string {\n const s = typeof result === \"string\" ? result : shortJson(result);\n const oneLine = s.replace(/\\s+/g, \" \").trim();\n return oneLine.length > 240 ? `${oneLine.slice(0, 237)}...` : oneLine;\n}\n\nfunction shortJson(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\n// ---------------------------------------------------------------------------\n// ANSI\n// ---------------------------------------------------------------------------\n\nfunction bold(s: string): string {\n return `\\x1b[1m${s}\\x1b[0m`;\n}\nfunction dim(s: string): string {\n return `\\x1b[2m${s}\\x1b[0m`;\n}\nfunction cyan(s: string): string {\n return `\\x1b[36m${s}\\x1b[0m`;\n}\nfunction red(s: string): string {\n return `\\x1b[31m${s}\\x1b[0m`;\n}\nfunction yellow(s: string): string {\n return `\\x1b[33m${s}\\x1b[0m`;\n}\n","/**\n * `ap` (no args) — status dashboard.\n *\n * Mirrors `st`'s bare-command pattern: print a compact overview of what's\n * discovered, which runner the env will pick, and a few hint actions.\n */\n\nimport path from \"node:path\";\nimport type { ProjectConfig } from \"../helpers/config.js\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\n\ninterface StatusInput {\n config: ProjectConfig;\n agents: DiscoveredAgent[];\n loadErrors: { file: string; error: Error }[];\n}\n\ninterface RunnerHint {\n provider: string;\n detail: string;\n}\n\n/** Print the bare-`ap` dashboard. */\nexport function runStatusCommand(input: StatusInput): void {\n const { config, agents, loadErrors } = input;\n const runner = detectRunnerFromEnv();\n\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(`${BOLD}agentic-patterns${RESET}`);\n lines.push(\"\");\n lines.push(formatAgentsRow(agents, config.root));\n for (const a of agents) {\n lines.push(` ${GREEN}●${RESET} ${a.id}`);\n }\n if (loadErrors.length > 0) {\n for (const err of loadErrors) {\n lines.push(` ${YELLOW}!${RESET} ${err.file}: ${err.error.message}`);\n }\n }\n lines.push(` runner ${runner.provider} ${DIM}(${runner.detail})${RESET}`);\n lines.push(` config ${formatConfigRow(config)}`);\n lines.push(\"\");\n lines.push(` ${DIM}ap run <agent> · ap playground · ap -h${RESET}`);\n lines.push(\"\");\n\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n}\n\nfunction formatAgentsRow(agents: DiscoveredAgent[], root: string): string {\n const count = agents.length;\n if (count === 0) {\n return ` agents ${DIM}none discovered (looked in ${path.relative(process.cwd(), root) || \".\"}/agents/)${RESET}`;\n }\n return ` agents ${count} discovered ${DIM}(./agents/)${RESET}`;\n}\n\nfunction formatConfigRow(config: ProjectConfig): string {\n const parts: string[] = [];\n if (config.hasManifest) parts.push(\"package.json overrides\");\n parts.push(\"see ap config\");\n return parts.join(\" · \");\n}\n\nfunction detectRunnerFromEnv(): RunnerHint {\n // AGENT_MODEL pins an exact model regardless of provider/tier.\n const pinned = process.env.AGENT_MODEL;\n if (process.env.ANTHROPIC_API_KEY) {\n return {\n provider: \"anthropic\",\n detail: `env ANTHROPIC_API_KEY → ${pinned ?? \"claude-sonnet-4-5\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.OPENAI_API_KEY) {\n return {\n provider: \"openai\",\n detail: `env OPENAI_API_KEY → ${pinned ?? \"gpt-4o\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.GOOGLE_GENERATIVE_AI_API_KEY || process.env.GOOGLE_API_KEY) {\n return {\n provider: \"google\",\n detail: `env GOOGLE_*_API_KEY → ${pinned ?? \"gemini-2.5-flash\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.OLLAMA_HOST) {\n if (pinned) {\n return { provider: \"ollama\", detail: `env OLLAMA_HOST → ${pinned} (AGENT_MODEL)` };\n }\n const tier = (process.env.AGENT_TIER ?? \"sonnet\") as \"opus\" | \"sonnet\" | \"haiku\";\n const model = tier === \"opus\" ? \"qwen3:30b-a3b\" : tier === \"haiku\" ? \"qwen3:4b\" : \"qwen3:14b\";\n return {\n provider: \"ollama\",\n detail: `env OLLAMA_HOST → ${model} (tier=${tier})`,\n };\n }\n return {\n provider: `${YELLOW}none${RESET}`,\n detail: \"set ANTHROPIC_API_KEY, OLLAMA_HOST, or have `claude` CLI on PATH\",\n };\n}\n","/**\n * Project config — find the project root, load `.env`, read the optional\n * `agentic` field from package.json for overrides.\n *\n * Resolution rules:\n * • Walk up from CWD looking for the first `package.json` — that's the root.\n * • If `.env` exists at the root, parse it into `process.env`.\n * • If `package.json` has an `agentic` field, return it as the project config.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { DEFAULT_DASHBOARD_PORT } from \"../constants.js\";\n\nexport interface ProjectConfig {\n /** Absolute path to the project root (where package.json was found). */\n readonly root: string;\n /** Glob(s) for agent file discovery. Default: `[\"agents/**\\/agent.{ts,js,mjs}\"]`. */\n readonly agents: readonly string[];\n /** Default port for `playground`. */\n readonly port: number;\n /** Whether the project package.json has an `agentic` block. */\n readonly hasManifest: boolean;\n}\n\ninterface PackageManifest {\n agentic?: {\n agents?: string | string[];\n port?: number;\n };\n}\n\nconst DEFAULT_AGENT_GLOBS = [\"agents/**/agent.{ts,js,mjs}\"];\n\n/**\n * Walk up from `from` (default: CWD) looking for the nearest `package.json`.\n * Returns the directory containing it, or `null` if none found.\n */\nexport function findProjectRoot(from: string = process.cwd()): string | null {\n let dir = path.resolve(from);\n while (true) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/** Load `.env` at the given root (no-op if file missing). Idempotent. */\nexport function loadDotEnv(root: string): void {\n const file = path.join(root, \".env\");\n if (!fs.existsSync(file)) return;\n const text = fs.readFileSync(file, \"utf-8\");\n for (const rawLine of text.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const eq = line.indexOf(\"=\");\n if (eq === -1) continue;\n const key = line.slice(0, eq).trim();\n const value = line\n .slice(eq + 1)\n .trim()\n .replace(/^[\"'](.*)[\"']$/, \"$1\");\n if (process.env[key] === undefined) process.env[key] = value;\n }\n}\n\n/**\n * Resolve project config. Walks up from CWD to find a project root, loads\n * `.env`, and reads the optional `agentic` block from package.json.\n */\nexport function resolveProjectConfig(from: string = process.cwd()): ProjectConfig {\n const root = findProjectRoot(from) ?? from;\n loadDotEnv(root);\n\n let manifest: PackageManifest = {};\n let hasManifest = false;\n const pkgPath = path.join(root, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const parsed = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")) as PackageManifest;\n manifest = parsed;\n hasManifest = Boolean(parsed.agentic);\n } catch {\n // Malformed package.json — fall through to defaults.\n }\n }\n\n const agents = normalizeGlobs(manifest.agentic?.agents) ?? DEFAULT_AGENT_GLOBS;\n const envPort = process.env.PORT;\n const port =\n manifest.agentic?.port ??\n (envPort !== undefined ? Number.parseInt(envPort, 10) : DEFAULT_DASHBOARD_PORT);\n\n return { root, agents, port, hasManifest };\n}\n\nfunction normalizeGlobs(value: string | string[] | undefined): readonly string[] | undefined {\n if (!value) return undefined;\n return Array.isArray(value) ? value : [value];\n}\n","/**\n * Agent discovery — crawl the project for agent files, dynamic-import each,\n * and normalize the export into an `AgentRegistration` shape.\n *\n * Convention: each agent is a file at `agents/<name>/agent.{ts,js,mjs}`\n * (or `agents/<name>.agent.ts`) that default-exports either:\n * • an `AgentRegistration` object directly:\n * export default { id, name, description?, agent }\n * • a function that returns one (sync or async):\n * export default () => ({ id, name, agent })\n *\n * The `runner` field is NOT defined by the user — the CLI injects it\n * after discovery via `createRunner()`.\n */\n\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { glob } from \"tinyglobby\";\nimport { register } from \"tsx/esm/api\";\n\n// Register tsx as the ESM loader globally — once per process. After this,\n// Node's regular dynamic import() handles `.ts` files transparently AND\n// resolves bare specifiers from the importing file's location like normal.\nlet _tsxRegistered = false;\nfunction ensureTsxRegistered(): void {\n if (_tsxRegistered) return;\n register();\n _tsxRegistered = true;\n}\n\n/** What an agent file is expected to export (sans runner). */\nexport interface DiscoveredAgent {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n // biome-ignore lint/suspicious/noExplicitAny: agent shape comes from agent-core/server, kept loose at the discovery boundary\n readonly agent: any;\n /** Absolute path to the source file (for `ap agents` rendering). */\n readonly file: string;\n}\n\ninterface AgentExport {\n id?: string;\n name?: string;\n description?: string;\n agent?: unknown;\n}\n\n/**\n * Find agent files matching the given globs, rooted at `root`.\n * Returns absolute file paths sorted alphabetically.\n */\nexport async function findAgentFiles(root: string, globs: readonly string[]): Promise<string[]> {\n const matches = await glob([...globs], {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n ignore: [\"**/node_modules/**\", \"**/dist/**\"],\n });\n return matches.sort();\n}\n\n/**\n * Dynamically import an agent file and normalize the export into a\n * `DiscoveredAgent`. Throws a descriptive error on bad shape.\n */\nexport async function loadAgentFile(file: string): Promise<DiscoveredAgent> {\n // tsx's tsImport handles .ts at runtime via on-the-fly transpile.\n // Plain .js/.mjs files go through Node's native import.\n const isTs = file.endsWith(\".ts\") || file.endsWith(\".tsx\") || file.endsWith(\".mts\");\n if (isTs) ensureTsxRegistered();\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown };\n let exported = mod.default;\n\n if (typeof exported === \"function\") {\n exported = await (exported as () => unknown | Promise<unknown>)();\n }\n\n if (!exported || typeof exported !== \"object\") {\n throw new Error(\n `${file}: default export must be an AgentRegistration object or a function returning one`,\n );\n }\n\n const { id, name, description, agent } = exported as AgentExport;\n\n if (!id || typeof id !== \"string\") {\n throw new Error(`${file}: missing or invalid 'id' (must be a non-empty string)`);\n }\n if (!name || typeof name !== \"string\") {\n throw new Error(`${file}: missing or invalid 'name' (must be a non-empty string)`);\n }\n if (!agent || typeof agent !== \"object\") {\n throw new Error(`${file}: missing or invalid 'agent' (must be an Agent object)`);\n }\n\n return {\n id,\n name,\n description,\n agent,\n file,\n };\n}\n\n/**\n * Discover all agents under the given root + globs. Returns successfully\n * loaded agents AND a separate list of load errors (so callers can choose\n * to surface failures without aborting discovery).\n */\nexport async function discoverAgents(\n root: string,\n globs: readonly string[],\n): Promise<{\n agents: DiscoveredAgent[];\n errors: { file: string; error: Error }[];\n}> {\n const files = await findAgentFiles(root, globs);\n const agents: DiscoveredAgent[] = [];\n const errors: { file: string; error: Error }[] = [];\n\n for (const file of files) {\n try {\n const a = await loadAgentFile(file);\n agents.push(a);\n } catch (e) {\n errors.push({\n file: path.relative(root, file),\n error: e instanceof Error ? e : new Error(String(e)),\n });\n }\n }\n\n // Detect duplicate ids — first wins, others surface as errors.\n const seen = new Set<string>();\n const deduped: DiscoveredAgent[] = [];\n for (const a of agents) {\n if (seen.has(a.id)) {\n errors.push({\n file: path.relative(root, a.file),\n error: new Error(`duplicate agent id \"${a.id}\" (already registered)`),\n });\n } else {\n seen.add(a.id);\n deduped.push(a);\n }\n }\n\n return { agents: deduped, errors };\n}\n"],"mappings":"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","names":["path","BOLD","DIM","RESET","spec","fs","path","isCancel","select","text","DIM","BOLD","GREEN","YELLOW","RESET","path","select","isCancel","fs","text","path","fileURLToPath","path","fileURLToPath","createRunner","createToolboxExecutor","isCancel","text","path","BOLD","DIM","RESET","GREEN","YELLOW","fs","path","path","fs","text","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/agents.ts","../src/commands/config.ts","../src/commands/init.ts","../src/constants.ts","../src/commands/playground.ts","../src/commands/run.ts","../src/commands/status.ts","../src/helpers/config.ts","../src/helpers/discover.ts"],"sourcesContent":["/**\n * `ap` — agentic patterns CLI.\n *\n * Single-dispatch shape (mirrors codegen-patterns/cli.ts):\n * parseArgs → switch(command) → run<Name>Command(...).\n *\n * Bare `ap` shows a status dashboard (mirrors `st`).\n */\n\nimport { parseArgs } from \"node:util\";\nimport { runAgentsCommand } from \"./commands/agents.js\";\nimport { runConfigSetCommand, runConfigStatusCommand } from \"./commands/config.js\";\nimport { type Provider, runInitCommand } from \"./commands/init.js\";\nimport { runPlaygroundCommand } from \"./commands/playground.js\";\nimport { runRunCommand } from \"./commands/run.js\";\nimport { runStatusCommand } from \"./commands/status.js\";\nimport { resolveProjectConfig } from \"./helpers/config.js\";\nimport { discoverAgents } from \"./helpers/discover.js\";\n\nconst USAGE = `\nap — agentic patterns\n\nUsage:\n ap status dashboard\n ap <command> [options]\n\nCommands:\n agents list discovered agents\n run <agent> [message] chat in terminal — interactive or one-shot\n playground launch UI environment (server + dashboard)\n init [<dir>] scaffold a new agent project\n config show env detection status\n config set interactive .env editor\n\nOptions:\n -h, --help show this help\n --port <port> server port for playground (default 3456)\n --no-dashboard playground without dashboard (API only)\n --no-open don't auto-open the browser\n --agents <glob> override agent discovery glob\n --with-plugin (init) drop the Claude Code plugin too\n --provider <p> (init) anthropic | openai | ollama\n --link (init) use file: deps against the local\n monorepo (dogfooding before publish)\n`;\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: { type: \"boolean\", short: \"h\" },\n port: { type: \"string\" },\n \"no-dashboard\": { type: \"boolean\" },\n \"no-open\": { type: \"boolean\" },\n agents: { type: \"string\" },\n \"with-plugin\": { type: \"boolean\" },\n provider: { type: \"string\" },\n link: { type: \"boolean\" },\n },\n allowPositionals: true,\n strict: false,\n });\n\n if (values.help) {\n process.stdout.write(`${USAGE}\\n`);\n return;\n }\n\n const command = positionals[0];\n\n // `init` scaffolds a NEW project — it must NOT require an existing\n // package.json upward of CWD, so dispatch it before project context.\n if (command === \"init\") {\n const targetDir = positionals[1];\n const providerRaw = values.provider ? String(values.provider) : undefined;\n await runInitCommand({\n targetDir,\n withPlugin: Boolean(values[\"with-plugin\"]),\n provider: providerRaw as Provider | undefined,\n link: Boolean(values.link),\n });\n return;\n }\n\n // Project context — every other command needs it.\n const config = resolveProjectConfig();\n const globs = values.agents ? [String(values.agents)] : config.agents;\n const { agents, errors } = await discoverAgents(config.root, globs);\n\n switch (command) {\n case undefined: {\n runStatusCommand({ config, agents, loadErrors: errors });\n return;\n }\n\n case \"agents\": {\n runAgentsCommand({ agents, loadErrors: errors, root: config.root });\n return;\n }\n\n case \"run\": {\n const agentId = positionals[1];\n if (!agentId) {\n process.stderr.write(`error: ap run requires an agent id\\n${USAGE}\\n`);\n process.exit(1);\n }\n const message = positionals.slice(2).join(\" \") || undefined;\n await runRunCommand({ agents, agentId, message });\n return;\n }\n\n case \"playground\": {\n const port = values.port ? Number.parseInt(String(values.port), 10) : config.port;\n await runPlaygroundCommand({\n agents,\n port,\n noDashboard: Boolean(values[\"no-dashboard\"]),\n open: !values[\"no-open\"],\n });\n return;\n }\n\n case \"config\": {\n const sub = positionals[1];\n if (sub === \"set\") {\n await runConfigSetCommand({ config });\n } else if (sub === undefined) {\n runConfigStatusCommand({ config });\n } else {\n process.stderr.write(`error: unknown config subcommand \"${sub}\"\\n${USAGE}\\n`);\n process.exit(1);\n }\n return;\n }\n\n default: {\n process.stderr.write(`error: unknown command \"${command}\"\\n${USAGE}\\n`);\n process.exit(1);\n }\n }\n}\n\nmain().catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`\\x1b[31merror:\\x1b[0m ${msg}\\n`);\n process.exit(1);\n});\n","/**\n * `ap agents` — full list of discovered agents.\n *\n * Verbose form of the bare `ap` status's `agents` row. Shows each agent's\n * id, name, source file, and (if present) description.\n */\n\nimport path from \"node:path\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst YELLOW = \"\\x1b[33m\";\n\ninterface AgentsInput {\n agents: DiscoveredAgent[];\n loadErrors: { file: string; error: Error }[];\n root: string;\n}\n\nexport function runAgentsCommand(input: AgentsInput): void {\n const { agents, loadErrors, root } = input;\n\n process.stdout.write(\"\\n\");\n\n if (agents.length === 0) {\n process.stdout.write(\n ` ${DIM}no agents discovered. Drop a file at ./agents/<name>/agent.ts that default-exports { id, name, agent }.${RESET}\\n\\n`,\n );\n } else {\n process.stdout.write(\n ` ${BOLD}${agents.length} agent${agents.length === 1 ? \"\" : \"s\"}${RESET}\\n\\n`,\n );\n const idCol = Math.max(...agents.map((a) => a.id.length), 8);\n for (const a of agents) {\n const rel = path.relative(root, a.file);\n process.stdout.write(` ${a.id.padEnd(idCol)} ${a.name} ${DIM}${rel}${RESET}\\n`);\n if (a.description) {\n process.stdout.write(` ${\"\".padEnd(idCol)} ${DIM}${a.description}${RESET}\\n`);\n }\n }\n process.stdout.write(\"\\n\");\n }\n\n if (loadErrors.length > 0) {\n process.stdout.write(` ${YELLOW}${loadErrors.length} load error(s):${RESET}\\n`);\n for (const err of loadErrors) {\n process.stdout.write(` ${YELLOW}!${RESET} ${err.file}: ${err.error.message}\\n`);\n }\n process.stdout.write(\"\\n\");\n }\n}\n","/**\n * `ap config` (no args) — show env detection status.\n * `ap config set` — interactive .env editor.\n *\n * Mirrors the noun-as-status pattern: bare `config` reports state,\n * `config set` performs the action.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isCancel, password, select, text } from \"@clack/prompts\";\nimport type { ProjectConfig } from \"../helpers/config.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\n\ninterface ConfigInput {\n config: ProjectConfig;\n}\n\ninterface EnvVarSpec {\n key: string;\n label: string;\n /** Should the value be hidden when prompting? */\n secret: boolean;\n}\n\nconst TRACKED_ENV: readonly EnvVarSpec[] = [\n { key: \"ANTHROPIC_API_KEY\", label: \"Anthropic API key\", secret: true },\n { key: \"OPENAI_API_KEY\", label: \"OpenAI API key\", secret: true },\n { key: \"GOOGLE_GENERATIVE_AI_API_KEY\", label: \"Google API key\", secret: true },\n { key: \"GROQ_API_KEY\", label: \"Groq API key\", secret: true },\n { key: \"MISTRAL_API_KEY\", label: \"Mistral API key\", secret: true },\n { key: \"XAI_API_KEY\", label: \"xAI API key\", secret: true },\n { key: \"DEEPSEEK_API_KEY\", label: \"DeepSeek API key\", secret: true },\n { key: \"OPENROUTER_API_KEY\", label: \"OpenRouter API key\", secret: true },\n { key: \"OLLAMA_HOST\", label: \"Ollama host URL\", secret: false },\n { key: \"AGENT_TIER\", label: \"Default tier (opus | sonnet | haiku)\", secret: false },\n { key: \"AGENT_MODEL\", label: \"Pinned model id (overrides tier)\", secret: false },\n];\n\n/** Bare `ap config` — show status. */\nexport function runConfigStatusCommand(input: ConfigInput): void {\n const { config } = input;\n const envFile = path.join(config.root, \".env\");\n const envExists = fs.existsSync(envFile);\n\n process.stdout.write(\"\\n\");\n process.stdout.write(` ${BOLD}config${RESET}\\n\\n`);\n process.stdout.write(\n ` .env ${envExists ? `${GREEN}loaded${RESET} ${DIM}from ${path.relative(process.cwd(), envFile)}${RESET}` : `${DIM}not present${RESET}`}\\n`,\n );\n\n const longestKey = Math.max(...TRACKED_ENV.map((e) => e.key.length));\n for (const spec of TRACKED_ENV) {\n const value = process.env[spec.key];\n const padded = spec.key.padEnd(longestKey);\n if (value) {\n const display = spec.secret ? maskSecret(value) : value;\n process.stdout.write(` ${padded} ${GREEN}✓${RESET} ${DIM}${display}${RESET}\\n`);\n } else {\n process.stdout.write(` ${padded} ${DIM}— not set${RESET}\\n`);\n }\n }\n process.stdout.write(\"\\n\");\n process.stdout.write(` ${DIM}ap config set to edit interactively${RESET}\\n\\n`);\n}\n\n/** `ap config set` — interactive editor that writes to `.env`. */\nexport async function runConfigSetCommand(input: ConfigInput): Promise<void> {\n const { config } = input;\n const envFile = path.join(config.root, \".env\");\n\n // Pick which var to set\n const choice = await select({\n message: \"Which env var?\",\n options: TRACKED_ENV.map((spec) => {\n const current = process.env[spec.key];\n const hint = current ? (spec.secret ? maskSecret(current) : current) : \"not set\";\n return {\n value: spec.key,\n label: spec.key,\n hint,\n };\n }),\n });\n\n if (isCancel(choice)) {\n process.stdout.write(`\\n${DIM}cancelled${RESET}\\n`);\n return;\n }\n\n const spec = TRACKED_ENV.find((e) => e.key === choice);\n if (!spec) return;\n\n const prompt = spec.secret ? password : text;\n const value = await prompt({\n message: `${spec.label} (${spec.key}):`,\n placeholder: process.env[spec.key] ?? \"\",\n });\n\n if (isCancel(value)) {\n process.stdout.write(`\\n${DIM}cancelled${RESET}\\n`);\n return;\n }\n\n upsertEnvFile(envFile, spec.key, String(value));\n process.stdout.write(\n `\\n ${GREEN}✓${RESET} wrote ${BOLD}${spec.key}${RESET} to ${path.relative(process.cwd(), envFile)}\\n\\n`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// helpers\n// ---------------------------------------------------------------------------\n\nfunction maskSecret(v: string): string {\n if (v.length <= 8) return \"•\".repeat(v.length);\n return `${v.slice(0, 4)}${\"•\".repeat(Math.min(8, v.length - 8))}${v.slice(-4)}`;\n}\n\n/** Insert or replace a single KEY=VALUE line in the .env file. Creates if missing. */\nfunction upsertEnvFile(file: string, key: string, value: string): void {\n let lines: string[] = [];\n if (fs.existsSync(file)) {\n lines = fs.readFileSync(file, \"utf-8\").split(\"\\n\");\n }\n const prefix = `${key}=`;\n const idx = lines.findIndex((l) => l.trim().startsWith(prefix));\n const formatted = `${key}=${value}`;\n if (idx === -1) {\n if (lines.length > 0 && lines[lines.length - 1] !== \"\") lines.push(\"\");\n lines.push(formatted);\n } else {\n lines[idx] = formatted;\n }\n fs.writeFileSync(\n file,\n `${lines.filter((l, i, arr) => !(l === \"\" && i === arr.length - 1)).join(\"\\n\")}\\n`,\n );\n\n // Reflect immediately in the current process's env so subsequent commands see it.\n if (!process.env[key] || process.env[key] !== value) {\n process.env[key] = value;\n }\n}\n","/**\n * `ap init [--with-plugin] [--provider=anthropic|openai|ollama] [<project-name>]`\n *\n * Scaffolds a consumer project: package.json, .env.example, tsconfig.json, and\n * a working `agents/demo/agent.ts`. Optionally also drops a Claude Code plugin\n * (`.claude-plugin/` + `hooks/`) by copying from the monorepo root when the CLI\n * is being run from source.\n *\n * Project layout produced:\n *\n * <target>/\n * ├── package.json\n * ├── .env.example\n * ├── tsconfig.json\n * ├── agents/\n * │ └── demo/\n * │ └── agent.ts\n * └── [if --with-plugin]\n * ├── .claude-plugin/plugin.json\n * └── hooks/{hooks.json,emit.mjs}\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isCancel, select, text } from \"@clack/prompts\";\nimport { DEFAULT_DASHBOARD_URL } from \"../constants.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport type Provider = \"anthropic\" | \"openai\" | \"ollama\";\n\nexport interface InitOptions {\n /**\n * Where to scaffold. If absent, prompt for a project name and create\n * `<cwd>/<name>/`. If present and equal to `\".\"`, scaffold into cwd directly.\n */\n targetDir?: string;\n /** Drop `.claude-plugin/` + `hooks/` next to the project. */\n withPlugin?: boolean;\n /** Which AI SDK provider to wire into the demo agent. */\n provider?: Provider;\n /**\n * Scaffold INTO the local monorepo's `examples/<name>/` with `workspace:*`\n * deps. Required for dogfooding until the `@agentic-patterns/*` packages\n * are published. Overrides `targetDir`.\n */\n link?: boolean;\n}\n\nconst DIM = \"\\x1b[2m\";\nconst BOLD = \"\\x1b[1m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\nconst RESET = \"\\x1b[0m\";\n\nconst VALID_PROVIDERS: readonly Provider[] = [\"anthropic\", \"openai\", \"ollama\"] as const;\n\n/**\n * Entry point. Resolves missing options interactively, writes files, then\n * prints next-steps banner.\n */\nexport async function runInitCommand(opts: InitOptions): Promise<void> {\n // -------------------------------------------------------------------------\n // 1. Resolve target directory\n //\n // `--link` scaffolds into `<monorepoRoot>/examples/<name>/` so `workspace:*`\n // deps resolve — the only pre-publish path that actually produces a working\n // `pnpm install`. Otherwise, target is `<cwd>/<name>/` (or `.` for in-place).\n // -------------------------------------------------------------------------\n let targetDir: string;\n let projectName: string;\n let monorepoRoot: string | null = null;\n\n if (opts.link) {\n monorepoRoot = resolveMonorepoRoot();\n if (!monorepoRoot) {\n process.stderr.write(\n \"error: --link requires the CLI to be run from the agentic-patterns-ts source tree\\n\",\n );\n process.exit(1);\n }\n const name = opts.targetDir ?? (await promptName());\n if (name === null) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n projectName = name;\n targetDir = path.join(monorepoRoot, \"examples\", projectName);\n } else if (opts.targetDir === undefined) {\n const name = await promptName();\n if (name === null) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n projectName = name;\n targetDir = path.resolve(process.cwd(), projectName);\n } else if (opts.targetDir === \".\") {\n targetDir = process.cwd();\n projectName = path.basename(targetDir);\n } else {\n targetDir = path.resolve(process.cwd(), opts.targetDir);\n projectName = path.basename(targetDir);\n }\n\n // -------------------------------------------------------------------------\n // 2. Resolve provider\n // -------------------------------------------------------------------------\n let provider: Provider;\n if (opts.provider !== undefined) {\n if (!VALID_PROVIDERS.includes(opts.provider)) {\n process.stderr.write(\n `error: invalid --provider \"${opts.provider}\" (expected anthropic | openai | ollama)\\n`,\n );\n process.exit(1);\n }\n provider = opts.provider;\n } else {\n const answer = await select({\n message: \"provider\",\n options: [\n { value: \"anthropic\" as const, label: \"Anthropic (Claude)\" },\n { value: \"openai\" as const, label: \"OpenAI (GPT)\" },\n { value: \"ollama\" as const, label: \"Ollama (local)\" },\n ],\n initialValue: \"anthropic\" as const,\n });\n if (isCancel(answer)) {\n process.stdout.write(`${DIM}cancelled.${RESET}\\n`);\n return;\n }\n provider = answer as Provider;\n }\n\n // -------------------------------------------------------------------------\n // 3. Pre-flight: target dir must be empty (or not exist)\n // -------------------------------------------------------------------------\n if (fs.existsSync(targetDir)) {\n const stat = fs.statSync(targetDir);\n if (!stat.isDirectory()) {\n process.stderr.write(`error: target ${targetDir} exists and is not a directory\\n`);\n process.exit(1);\n }\n const conflicts = [\"package.json\", \"agents\", \"tsconfig.json\"].filter((n) =>\n fs.existsSync(path.join(targetDir, n)),\n );\n if (conflicts.length > 0) {\n process.stderr.write(\n `error: target ${targetDir} already contains: ${conflicts.join(\", \")}\\n`,\n );\n process.exit(1);\n }\n } else {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // -------------------------------------------------------------------------\n // 4. Write project files\n // -------------------------------------------------------------------------\n const created: string[] = [];\n\n writeFile(\n targetDir,\n \"package.json\",\n renderPackageJson(projectName, provider, opts.link === true),\n created,\n );\n writeFile(targetDir, \".env.example\", renderEnvExample(provider), created);\n writeFile(targetDir, \"tsconfig.json\", renderTsConfig(), created);\n writeFile(targetDir, path.join(\"agents\", \"demo\", \"agent.ts\"), renderAgent(provider), created);\n\n // -------------------------------------------------------------------------\n // 5. Optional plugin\n // -------------------------------------------------------------------------\n let pluginNote: string | null = null;\n if (opts.withPlugin) {\n const pluginSrc = resolvePluginSource();\n if (pluginSrc) {\n copyDir(pluginSrc.pluginDir, path.join(targetDir, \".claude-plugin\"));\n copyDir(pluginSrc.hooksDir, path.join(targetDir, \"hooks\"));\n created.push(\".claude-plugin/\", \"hooks/\");\n\n // Mirror hooks.json into .claude/settings.json so Claude Code activates\n // them immediately for sessions started in this directory. If the user\n // already has a settings.json, merge our hooks into it non-destructively\n // (preserve their other keys; skip events where our hook is already\n // registered so re-running `ap init` is idempotent).\n const settingsDir = path.join(targetDir, \".claude\");\n const settingsPath = path.join(settingsDir, \"settings.json\");\n const hooksSource = fs.readFileSync(path.join(pluginSrc.hooksDir, \"hooks.json\"), \"utf8\");\n const ourHooks = JSON.parse(\n hooksSource.replaceAll(\"${CLAUDE_PLUGIN_ROOT}\", \"${CLAUDE_PROJECT_DIR}\"),\n ) as HookSettings;\n\n const mergeOutcome = mergeHookSettings(settingsPath, ourHooks);\n fs.mkdirSync(settingsDir, { recursive: true });\n fs.writeFileSync(settingsPath, `${JSON.stringify(mergeOutcome.merged, null, 2)}\\n`);\n if (mergeOutcome.kind === \"created\") {\n created.push(\".claude/settings.json\");\n } else if (mergeOutcome.kind === \"merged\") {\n created.push(\n `.claude/settings.json ${DIM}(merged ${mergeOutcome.added} hook entries)${RESET}`,\n );\n } else {\n created.push(`.claude/settings.json ${DIM}(already up to date)${RESET}`);\n }\n } else {\n // TODO(phase-2): package the plugin template inside\n // packages/agent-cli/assets/plugin-template/ during build so this works\n // when the CLI is installed via npm.\n pluginNote = `${YELLOW}warning${RESET}: --with-plugin requested but plugin source not found.\\n ${DIM}Run from the agentic-patterns-ts source tree, or wait for plugin packaging (Phase 2).${RESET}`;\n }\n }\n\n // -------------------------------------------------------------------------\n // 6. Banner\n // -------------------------------------------------------------------------\n const rel = path.relative(process.cwd(), targetDir) || \".\";\n process.stdout.write(`\\n ${GREEN}created${RESET} ${BOLD}${rel}${RESET}\\n\\n`);\n for (const f of created) {\n process.stdout.write(` ${DIM}+ ${f}${RESET}\\n`);\n }\n if (pluginNote) {\n process.stdout.write(`\\n ${pluginNote}\\n`);\n }\n process.stdout.write(`\\n ${BOLD}next${RESET}\\n`);\n\n if (opts.link && monorepoRoot) {\n // Install runs at the monorepo root so workspace:* resolves for every\n // transitive @agentic-patterns/* dep.\n const rootRel = path.relative(process.cwd(), monorepoRoot) || \".\";\n const projRel = path.relative(monorepoRoot, targetDir);\n if (rootRel !== \".\") {\n process.stdout.write(` cd ${rootRel}\\n`);\n }\n process.stdout.write(\n ` bun install ${DIM}# picks up the new example${RESET}\\n`,\n );\n process.stdout.write(` cd ${projRel}\\n`);\n process.stdout.write(\n ` cp .env.example .env ${DIM}# fill in your ${envKeyFor(provider)}${RESET}\\n`,\n );\n process.stdout.write(` bun run dev ${DIM}# launch playground${RESET}\\n\\n`);\n } else {\n if (rel !== \".\") {\n process.stdout.write(` cd ${rel}\\n`);\n }\n process.stdout.write(\n ` cp .env.example .env ${DIM}# fill in your ${envKeyFor(provider)}${RESET}\\n`,\n );\n process.stdout.write(\" bun install\\n\");\n process.stdout.write(` bun run dev ${DIM}# launch playground${RESET}\\n\\n`);\n }\n}\n\nasync function promptName(): Promise<string | null> {\n const answer = await text({\n message: \"project name\",\n placeholder: \"my-agents\",\n validate: (v) => (v.trim().length === 0 ? \"name is required\" : undefined),\n });\n if (isCancel(answer)) return null;\n return String(answer).trim();\n}\n\n// ---------------------------------------------------------------------------\n// File templates\n// ---------------------------------------------------------------------------\n\nfunction renderPackageJson(name: string, provider: Provider, link: boolean): string {\n const providerDep = providerSdkPackage(provider);\n const apVersion = link ? \"workspace:*\" : \"^0.1.0\";\n\n const pkg = {\n name,\n private: true,\n version: \"0.0.1\",\n type: \"module\",\n scripts: {\n dev: \"ap playground\",\n start: \"ap playground\",\n agents: \"ap agents\",\n },\n dependencies: {\n \"@agentic-patterns/core\": apVersion,\n \"@agentic-patterns/runtime\": apVersion,\n \"@agentic-patterns/cli\": apVersion,\n ai: \"^4.0.0\",\n [providerDep]: \"^1.0.0\",\n zod: \"^3.23.0\",\n },\n devDependencies: {\n \"@types/node\": \"^22.0.0\",\n typescript: \"^5.7.0\",\n },\n };\n return `${JSON.stringify(pkg, null, 2)}\\n`;\n}\n\nfunction renderEnvExample(provider: Provider): string {\n const lines = [\n \"# Dashboard URL — used by the Claude Code plugin to ship lifecycle events\",\n `AP_DASHBOARD_URL=${DEFAULT_DASHBOARD_URL}`,\n \"\",\n \"# Default model tier — opus | sonnet | haiku (used by the agent runner)\",\n \"AGENT_TIER=sonnet\",\n \"\",\n \"# Optional: pin an exact model id; wins over AGENT_TIER. Useful when\",\n \"# your provider has a model the framework's tier map doesn't list\",\n \"# (e.g. AGENT_MODEL=qwen3.6:27b for an Ollama box).\",\n \"# AGENT_MODEL=\",\n \"\",\n ];\n if (provider === \"anthropic\") {\n lines.push(\"# Anthropic API key (https://console.anthropic.com/)\");\n lines.push(\"ANTHROPIC_API_KEY=sk-ant-...\");\n } else if (provider === \"openai\") {\n lines.push(\"# OpenAI API key (https://platform.openai.com/api-keys)\");\n lines.push(\"OPENAI_API_KEY=sk-...\");\n } else {\n lines.push(\"# Ollama host (default http://localhost:11434)\");\n lines.push(\"OLLAMA_HOST=http://localhost:11434\");\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction renderTsConfig(): string {\n const cfg = {\n compilerOptions: {\n target: \"es2022\",\n module: \"nodenext\",\n moduleResolution: \"nodenext\",\n lib: [\"es2022\"],\n outDir: \"dist\",\n rootDir: \"src\",\n strict: true,\n noUncheckedIndexedAccess: true,\n noUnusedLocals: true,\n noUnusedParameters: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n declaration: true,\n sourceMap: true,\n },\n include: [\"agents/**/*.ts\", \"src/**/*.ts\"],\n exclude: [\"node_modules\", \"dist\"],\n };\n return `${JSON.stringify(cfg, null, 2)}\\n`;\n}\n\nfunction renderAgent(provider: Provider): string {\n // The agent file conforms to the discovery contract: default-export an\n // AgentRegistration `{ id, name, description, agent }`. The CLI's playground\n // injects the runner — we don't need to construct one here, but we leave the\n // provider import wired up so users can graduate to a custom runner easily.\n return `/**\n * Demo agent — generated by \\`ap init\\`.\n *\n * The default export is an AgentRegistration. The \\`ap\\` CLI discovers this\n * file (via \\`agents/**\\\\/agent.ts\\`), builds a runner from your environment\n * (using ${provider}), and wires it into the playground dashboard.\n *\n * bun run dev # launch the dashboard at http://localhost:3456\n * ap run demo # chat with this agent in the terminal\n */\n\nimport {\n AgentBuilder,\n Capability,\n Judgment,\n Mission,\n Persona,\n Responsibility,\n RoleBuilder,\n type ToolDefinition,\n Toolbox,\n} from \"@agentic-patterns/core\";\nimport { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// A tiny toolbox so the agent has something concrete to do.\n// ---------------------------------------------------------------------------\n\nclass GreetingToolbox extends Toolbox {\n readonly name = \"greeting_tools\";\n readonly description = \"Friendly greeting helpers\";\n\n readonly tools: Record<string, ToolDefinition> = {\n greet: {\n description: \"Produce a friendly greeting for a person\",\n parameters: z.object({\n name: z.string().describe(\"Person's name\"),\n }),\n execute: async (args) => {\n const { name } = args as { name: string };\n return { greeting: \\`Hello, \\${name}! Welcome to agentic-patterns.\\` };\n },\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Build the agent.\n// ---------------------------------------------------------------------------\n\nconst role = new RoleBuilder(\"demo-assistant\")\n .withPersona(\n new Persona({\n identity: \"A friendly demo assistant that greets people warmly\",\n tone: \"warm and concise\",\n priorities: [\"being helpful\", \"showing the framework off\"],\n principles: [\"Always use the greet tool when greeting someone\"],\n }),\n )\n .withJudgment(\n new Judgment({\n domain: \"greetings and small talk\",\n heuristics: [\"Use the greet tool for any name-based greeting\"],\n constraints: [\"Stay friendly and concise\"],\n }),\n )\n .withCapability(\n new Capability(\"greeting_tools\", \"Friendly greeting helpers\", new GreetingToolbox()),\n )\n .withResponsibility(\n new Responsibility({\n key: \"greet\",\n name: \"Greet People\",\n description: \"Greet people warmly using the greet tool\",\n }),\n )\n .withDefaultModel(\"sonnet\")\n .build();\n\nconst mission = new Mission({\n objective: \"Demonstrate the @agentic-patterns/core building blocks end-to-end\",\n success_criteria: [\"Greets users by name\", \"Uses the greet tool for every greeting\"],\n});\n\nconst agent = new AgentBuilder(role).withMission(mission).build();\n\n// ---------------------------------------------------------------------------\n// Default export — discovered by \\`ap\\`. The runner is injected by the CLI.\n// ---------------------------------------------------------------------------\n\nexport default {\n id: \"demo\",\n name: \"Demo\",\n description: \"A friendly demo assistant generated by \\`ap init\\`\",\n agent,\n};\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction envKeyFor(provider: Provider): string {\n switch (provider) {\n case \"anthropic\":\n return \"ANTHROPIC_API_KEY\";\n case \"openai\":\n return \"OPENAI_API_KEY\";\n case \"ollama\":\n return \"OLLAMA_HOST\";\n }\n}\n\nfunction providerSdkPackage(provider: Provider): string {\n switch (provider) {\n case \"anthropic\":\n return \"@ai-sdk/anthropic\";\n case \"openai\":\n return \"@ai-sdk/openai\";\n case \"ollama\":\n return \"ollama-ai-provider\";\n }\n}\n\nfunction writeFile(root: string, rel: string, contents: string, log: string[]): void {\n const dest = path.join(root, rel);\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, contents, \"utf8\");\n log.push(rel);\n}\n\nfunction copyDir(src: string, dest: string): void {\n fs.cpSync(src, dest, { recursive: true });\n}\n\n// ---------------------------------------------------------------------------\n// Hook settings merge\n//\n// Claude Code users frequently already have a `.claude/settings.json` with\n// their own hooks, permissions, or model preferences. We must not clobber it.\n// `mergeHookSettings` preserves existing top-level keys and adds our hook\n// entries only where they don't already exist — same command string under the\n// same event + matcher counts as \"already registered\", so re-running\n// `ap init --with-plugin` is idempotent.\n// ---------------------------------------------------------------------------\n\ntype HookEntry = { type: string; command: string; async?: boolean; timeout?: number };\ntype HookMatcher = { matcher: string; hooks: HookEntry[] };\ntype HookSettings = { hooks: Record<string, HookMatcher[]>; [key: string]: unknown };\n\ntype MergeOutcome =\n | { kind: \"created\"; merged: HookSettings }\n | { kind: \"merged\"; merged: HookSettings; added: number }\n | { kind: \"unchanged\"; merged: HookSettings };\n\nfunction mergeHookSettings(settingsPath: string, ours: HookSettings): MergeOutcome {\n if (!fs.existsSync(settingsPath)) {\n return { kind: \"created\", merged: ours };\n }\n\n let existing: HookSettings;\n try {\n existing = JSON.parse(fs.readFileSync(settingsPath, \"utf8\")) as HookSettings;\n } catch {\n // Malformed user file — back up and treat as fresh write, so we never\n // silently drop their content.\n const backup = `${settingsPath}.ap-backup-${Date.now()}`;\n fs.renameSync(settingsPath, backup);\n process.stdout.write(\n `${YELLOW}warning${RESET}: existing .claude/settings.json was malformed; moved to ${path.basename(backup)}\\n`,\n );\n return { kind: \"created\", merged: ours };\n }\n\n const merged: HookSettings = { ...existing, hooks: { ...(existing.hooks ?? {}) } };\n let added = 0;\n\n for (const event of Object.keys(ours.hooks)) {\n const ourMatchers = ours.hooks[event] ?? [];\n const theirMatchers = merged.hooks[event] ?? [];\n const result = [...theirMatchers];\n\n for (const ourMatcher of ourMatchers) {\n const theirMatcher = result.find((m) => m.matcher === ourMatcher.matcher);\n if (!theirMatcher) {\n result.push(ourMatcher);\n added += ourMatcher.hooks.length;\n continue;\n }\n for (const ourHook of ourMatcher.hooks) {\n const duplicate = theirMatcher.hooks.some(\n (h) => h.type === ourHook.type && h.command === ourHook.command,\n );\n if (!duplicate) {\n theirMatcher.hooks.push(ourHook);\n added += 1;\n }\n }\n }\n\n merged.hooks[event] = result;\n }\n\n if (added === 0) return { kind: \"unchanged\", merged };\n return { kind: \"merged\", merged, added };\n}\n\n/**\n * Try to find `.claude-plugin/` and `hooks/`.\n *\n * Two possible locations:\n * 1. Bundled inside the published CLI tarball at\n * `packages/agent-cli/assets/plugin-template/` (checked first — works\n * when the CLI is installed via `npm install -g @agentic-patterns/cli`)\n * 2. The monorepo root (dogfood path — walks up from the running script)\n */\nfunction resolvePluginSource(): { pluginDir: string; hooksDir: string } | null {\n const here = path.dirname(fileURLToPath(import.meta.url));\n\n // Candidate 1 (priority): bundled plugin-template inside the CLI package.\n // Source run: src/commands/init.ts → ../../assets/plugin-template/\n // Dist run: dist/cli.js → ../assets/plugin-template/\n const bundledCandidates = [\n path.resolve(here, \"../assets/plugin-template\"),\n path.resolve(here, \"../../assets/plugin-template\"),\n ];\n for (const base of bundledCandidates) {\n const pluginDir = path.join(base, \".claude-plugin\");\n const hooksDir = path.join(base, \"hooks\");\n if (fs.existsSync(pluginDir) && fs.existsSync(hooksDir)) {\n return { pluginDir, hooksDir };\n }\n }\n\n // Candidate 2: monorepo root (for local `bun --filter` / tsx runs).\n const root = resolveMonorepoRoot();\n if (root) {\n return { pluginDir: path.join(root, \".claude-plugin\"), hooksDir: path.join(root, \"hooks\") };\n }\n return null;\n}\n\n/**\n * Locate the monorepo root by walking up from this file. The root is\n * identified by having `packages/agent-core/` and a `workspaces` field in\n * package.json (bun workspace marker — replaces the old pnpm-workspace.yaml).\n */\nfunction resolveMonorepoRoot(): string | null {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n let cur = here;\n for (let i = 0; i < 8; i++) {\n const rootPkgPath = path.join(cur, \"package.json\");\n if (fs.existsSync(rootPkgPath) && fs.existsSync(path.join(cur, \"packages\", \"agent-core\"))) {\n try {\n const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, \"utf8\")) as {\n workspaces?: string[];\n };\n if (rootPkg.workspaces && rootPkg.workspaces.length > 0) {\n return cur;\n }\n } catch {\n // malformed json — fall through\n }\n }\n const parent = path.dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Single source of truth for CLI-level defaults.\n *\n * Anything hardcoded here (ports, URLs, timeouts) should be imported by\n * consumers rather than duplicated. The one exception is `hooks/emit.mjs` —\n * it's a zero-dependency standalone script that runs in user projects and\n * can't import from the workspace. Its inlined fallback must be kept in sync\n * manually; see the comment in that file.\n */\n\n/**\n * Default port for `ap playground` and the Hono server.\n *\n * Chosen to avoid the crowded :3000 range (Next.js, Create React App, Vite,\n * most template-generated dev servers). Users with existing setups on :3000\n * don't have to stop anything to try us out.\n */\nexport const DEFAULT_DASHBOARD_PORT = 3456;\n\n/** Default URL the Claude Code hook plugin POSTs to. */\nexport const DEFAULT_DASHBOARD_URL = `http://localhost:${DEFAULT_DASHBOARD_PORT}`;\n","/**\n * `ap playground` — start the full UI environment (Hono API + admin dashboard)\n * for a project's discovered agents.\n *\n * This command is the \"one command to chat with my agents\" UX: it wires the\n * standard observability stack (event bus + collector + admin service + SSE\n * exporter), picks a runner via `createRunner()` (env-driven), attaches that\n * runner to each `AgentRegistration`, mounts the pre-built dashboard as a\n * SPA at `/`, and opens the browser.\n *\n * The caller (`cli.ts`) is responsible for discovering agents from the user's\n * project and passing them in as `opts.agents`.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { createReadStream, existsSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n AgentEventBus,\n InMemoryAdminService,\n InMemoryEventCollector,\n SSEExporter,\n createRunner,\n createToolboxExecutor,\n} from \"@agentic-patterns/runtime\";\nimport { createServer } from \"@agentic-patterns/server\";\nimport type { AgentRegistration } from \"@agentic-patterns/server\";\nimport { serve } from \"@hono/node-server\";\nimport { DEFAULT_DASHBOARD_PORT } from \"../constants.js\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface PlaygroundOptions {\n /** Agents discovered by the caller (without runners — playground attaches one). */\n agents: DiscoveredAgent[];\n /** Port for the HTTP server. Defaults to {@link DEFAULT_DASHBOARD_PORT}. */\n port?: number;\n /** Skip the dashboard — API only. */\n noDashboard?: boolean;\n /** Auto-open the dashboard URL in a browser. Defaults to true. */\n open?: boolean;\n}\n\n/**\n * Start the playground: Hono server + dashboard + observability stack,\n * wired to the caller's pre-discovered agents.\n *\n * Resolves once the server is listening. Does not return; the Node process\n * stays alive holding the HTTP server until the user kills it.\n */\nexport async function runPlaygroundCommand(opts: PlaygroundOptions): Promise<void> {\n const port = opts.port ?? DEFAULT_DASHBOARD_PORT;\n const shouldOpen = opts.open !== false;\n const serveDashboard = opts.noDashboard !== true;\n\n // -------------------------------------------------------------------------\n // 1. Observability stack\n // -------------------------------------------------------------------------\n\n const eventBus = new AgentEventBus();\n\n const collector = new InMemoryEventCollector();\n collector.attach(eventBus);\n\n const adminService = new InMemoryAdminService(collector);\n\n const sseExporter = new SSEExporter();\n sseExporter.attach(eventBus);\n\n // -------------------------------------------------------------------------\n // 2. Runner — env-driven auto-detection\n // -------------------------------------------------------------------------\n\n const selection = await createRunner({\n eventBus,\n tier: (process.env.AGENT_TIER as \"opus\" | \"sonnet\" | \"haiku\" | undefined) ?? \"sonnet\",\n verbose: false,\n });\n const { runner } = selection;\n\n // -------------------------------------------------------------------------\n // 3. Attach runner to each registration\n // -------------------------------------------------------------------------\n\n const registrations: AgentRegistration[] = opts.agents.map((reg) => ({\n id: reg.id,\n name: reg.name,\n description: reg.description,\n agent: reg.agent,\n runner,\n }));\n // Mark createToolboxExecutor as \"imported for re-export discoverability\" —\n // the conversation route already builds executors per request.\n void createToolboxExecutor;\n\n // -------------------------------------------------------------------------\n // 4. Build the Hono app with API routes FIRST\n // -------------------------------------------------------------------------\n\n const app = createServer({\n agents: registrations,\n adminService,\n eventBus,\n sseExporter,\n });\n\n // -------------------------------------------------------------------------\n // 5. Mount the dashboard SPA (after API routes so API wins)\n // -------------------------------------------------------------------------\n\n const dashboardDir = resolveDashboardDir();\n let dashboardMounted = false;\n\n if (serveDashboard) {\n if (dashboardDir && existsSync(dashboardDir)) {\n mountDashboard(app, dashboardDir);\n dashboardMounted = true;\n } else {\n const where = dashboardDir ?? \"<unresolved>\";\n process.stderr.write(\n `[playground] warning: dashboard assets not found at ${where} — API-only mode.\\n run \\`pnpm --filter @agentic-patterns/cli build\\` (or \\`build:dashboard\\`) to build the SPA bundle.\\n`,\n );\n }\n }\n\n // -------------------------------------------------------------------------\n // 6. Start the HTTP server\n // -------------------------------------------------------------------------\n\n await new Promise<void>((resolve) => {\n serve({ fetch: app.fetch, port }, () => {\n resolve();\n });\n });\n\n // -------------------------------------------------------------------------\n // 7. Banner\n // -------------------------------------------------------------------------\n\n const baseUrl = `http://localhost:${port}`;\n const agentList = registrations.map((a) => a.name).join(\", \") || \"(none)\";\n const lines = [\n \"\",\n ` api ${baseUrl}`,\n dashboardMounted ? ` dashboard ${baseUrl}` : \" dashboard (disabled)\",\n ` agents ${agentList}`,\n ` runner ${selection.source} — ${selection.reason}`,\n \"\",\n ];\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n\n // -------------------------------------------------------------------------\n // 8. Open the browser\n // -------------------------------------------------------------------------\n\n if (shouldOpen && dashboardMounted) {\n openBrowser(baseUrl);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the absolute path to the bundled dashboard assets.\n *\n * Layout after `pnpm --filter @agentic-patterns/cli build`:\n * packages/agent-cli/\n * dist/cli.js ← import.meta.url lands here\n * assets/dashboard/ ← built SPA\n *\n * When running from source (tsx), the same `../assets/dashboard/` relative\n * layout holds if `build:dashboard` has been run at least once.\n */\nfunction resolveDashboardDir(): string | null {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(here, \"../assets/dashboard\");\n } catch {\n return null;\n }\n}\n\n/**\n * Known API route prefixes — any GET that matches one of these is never\n * rewritten to `index.html`. Keep in sync with `createServer()` routes.\n */\nconst API_PREFIXES = [\"/agents\", \"/conversations\", \"/admin\", \"/health\"];\n\nfunction isApiPath(pathname: string): boolean {\n return API_PREFIXES.some((p) => pathname === p || pathname.startsWith(`${p}/`));\n}\n\n/**\n * Register a static-file + SPA-fallback handler on the Hono app. This is\n * mounted after `createServer()`'s routes, so API endpoints win the match.\n *\n * We avoid `@hono/node-server/serve-static` because it requires a\n * cwd-relative root; the CLI needs an absolute path resolved from\n * `import.meta.url`.\n */\nfunction mountDashboard(app: ReturnType<typeof createServer>, dashboardDir: string): void {\n const indexPath = path.join(dashboardDir, \"index.html\");\n\n app.get(\"*\", async (c) => {\n if (c.req.method !== \"GET\") {\n return c.notFound();\n }\n\n const url = new URL(c.req.url);\n const pathname = decodeURIComponent(url.pathname);\n\n if (isApiPath(pathname)) {\n return c.notFound();\n }\n\n // Try the literal asset first; fall back to index.html for SPA routes.\n const assetPath = pathname === \"/\" ? indexPath : safeJoin(dashboardDir, pathname);\n\n if (assetPath && existsSync(assetPath) && statSync(assetPath).isFile()) {\n return streamFile(assetPath);\n }\n\n if (existsSync(indexPath)) {\n return streamFile(indexPath);\n }\n\n return c.notFound();\n });\n}\n\n/**\n * Join `base` + `rel` and reject the result if it escapes `base` (defense\n * against `..`-traversal). Returns `null` on any escape attempt.\n */\nfunction safeJoin(base: string, rel: string): string | null {\n const joined = path.join(base, rel);\n const normalizedBase = path.resolve(base);\n const normalizedJoined = path.resolve(joined);\n if (\n normalizedJoined !== normalizedBase &&\n !normalizedJoined.startsWith(`${normalizedBase}${path.sep}`)\n ) {\n return null;\n }\n return normalizedJoined;\n}\n\n/**\n * Stream a file from disk as a Fetch `Response`. Sets a minimal content-type\n * based on the extension — good enough for a dashboard SPA (html/js/css/svg/png).\n */\nfunction streamFile(filePath: string): Response {\n const ext = path.extname(filePath).toLowerCase();\n const contentType = MIME[ext] ?? \"application/octet-stream\";\n\n const nodeStream = createReadStream(filePath);\n const webStream = new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on(\"data\", (chunk) => {\n const bytes =\n typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : new Uint8Array(chunk);\n controller.enqueue(bytes);\n });\n nodeStream.on(\"end\", () => controller.close());\n nodeStream.on(\"error\", (err) => controller.error(err));\n },\n cancel() {\n nodeStream.destroy();\n },\n });\n\n return new Response(webStream, {\n status: 200,\n headers: { \"content-type\": contentType },\n });\n}\n\nconst MIME: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".map\": \"application/json; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n};\n\n/**\n * Cross-platform \"open this URL in the default browser\". Best-effort —\n * swallows errors so a headless environment doesn't crash the playground.\n */\nfunction openBrowser(url: string): void {\n const { platform } = process;\n const { cmd, args } =\n platform === \"darwin\"\n ? { cmd: \"open\", args: [url] }\n : platform === \"win32\"\n ? { cmd: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n : { cmd: \"xdg-open\", args: [url] };\n\n try {\n const child = spawn(cmd, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {\n /* ignore — e.g. xdg-open missing in a container */\n });\n child.unref();\n } catch {\n /* ignore */\n }\n}\n","/**\n * `ap run <agentId> [message]` — chat with a single agent from the terminal.\n *\n * Two modes:\n * • one-shot — `message` provided; stream once, print, exit.\n * • interactive — no `message`; REPL loop via @clack/prompts.\n *\n * Rendering is raw ANSI (no chalk dep). Events come from the runtime as a\n * discriminated `AgentEvent` union; we project each type to a terminal line.\n */\n\nimport {\n Conversation,\n createRunner,\n createToolboxExecutor,\n getAgentEventBus,\n} from \"@agentic-patterns/runtime\";\nimport type { AgentEvent } from \"@agentic-patterns/runtime\";\nimport { isCancel, text } from \"@clack/prompts\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface RunOptions {\n /** All discovered agents; the caller owns discovery. */\n agents: DiscoveredAgent[];\n /** Which agent to chat with. Matched against `AgentRegistration.id`. */\n agentId: string;\n /** If present → one-shot mode; if absent → interactive REPL. */\n message?: string;\n}\n\n/**\n * Entry point for the `ap run` command. Returns when the chat session ends.\n * Exits the process non-zero on agent-not-found.\n */\nexport async function runRunCommand(opts: RunOptions): Promise<void> {\n const reg = opts.agents.find((a) => a.id === opts.agentId);\n if (!reg) {\n const available = opts.agents.map((a) => a.id).join(\", \") || \"(none)\";\n process.stderr.write(\n `${red(`agent \"${opts.agentId}\" not found`)}\\n available: ${available}\\n`,\n );\n process.exit(1);\n }\n\n const eventBus = getAgentEventBus();\n const { runner } = await createRunner({ eventBus, verbose: false });\n\n const conversation = new Conversation(reg.agent, runner, {\n toolExecutor: createToolboxExecutor(reg.agent),\n });\n\n if (opts.message !== undefined) {\n await streamOnce(conversation, opts.message);\n return;\n }\n\n await runRepl(conversation, reg);\n}\n\n// ---------------------------------------------------------------------------\n// Modes\n// ---------------------------------------------------------------------------\n\nasync function streamOnce(conversation: Conversation, message: string): Promise<void> {\n const controller = new AbortController();\n const onSigint = (): void => {\n controller.abort();\n };\n process.on(\"SIGINT\", onSigint);\n try {\n await renderStream(conversation.stream(message), controller.signal);\n } finally {\n process.off(\"SIGINT\", onSigint);\n }\n}\n\nasync function runRepl(conversation: Conversation, reg: DiscoveredAgent): Promise<void> {\n const banner = `chatting with ${bold(reg.agent.role.name)} ${dim(\"·\")} ${dim(\n \"type /exit to quit\",\n )}`;\n process.stdout.write(`${banner}\\n\\n`);\n\n for (;;) {\n const input = await text({ message: \"you\" });\n if (isCancel(input)) {\n process.stdout.write(`${dim(\"bye.\")}\\n`);\n return;\n }\n const line = (input as string).trim();\n if (line === \"\") continue;\n if (line === \"/exit\" || line === \"/quit\") {\n process.stdout.write(`${dim(\"bye.\")}\\n`);\n return;\n }\n\n const controller = new AbortController();\n const onSigint = (): void => {\n controller.abort();\n };\n process.on(\"SIGINT\", onSigint);\n try {\n await renderStream(conversation.stream(line), controller.signal);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n process.stdout.write(`\\n${red(`error: ${msg}`)}\\n`);\n } finally {\n process.off(\"SIGINT\", onSigint);\n }\n process.stdout.write(\"\\n\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Event rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Drain an AgentEvent stream to the terminal. Honours `signal` so Ctrl+C in\n * interactive mode can abort the current exchange.\n */\nasync function renderStream(\n stream: AsyncGenerator<AgentEvent>,\n signal: AbortSignal,\n): Promise<void> {\n let inThinking = false;\n for await (const event of stream) {\n if (signal.aborted) {\n // Drop the rest; the runner will eventually settle.\n await safeReturn(stream);\n process.stdout.write(`\\n${yellow(\"aborted.\")}\\n`);\n return;\n }\n inThinking = renderEvent(event, inThinking);\n }\n}\n\n/**\n * Render a single event. Returns the updated `inThinking` flag so the caller\n * can close a reasoning block cleanly when the next non-thinking event fires.\n */\nfunction renderEvent(event: AgentEvent, inThinking: boolean): boolean {\n switch (event.type) {\n case \"agent.message.start\":\n process.stdout.write(`${bold(\"assistant\")}: `);\n return inThinking;\n\n case \"agent.message.chunk\":\n process.stdout.write(event.delta);\n return inThinking;\n\n case \"agent.thinking.start\":\n process.stdout.write(`\\n ${dim(\"💭 thinking…\")}\\n`);\n return true;\n\n case \"agent.reasoning\":\n if (event.isComplete) {\n process.stdout.write(\"\\n\");\n return false;\n }\n process.stdout.write(` ${dim(`💭 ${event.content}`)}\\n`);\n return true;\n\n case \"agent.tool.start\": {\n const args = formatArgs(event.arguments);\n process.stdout.write(`\\n ${cyan(`🔧 ${event.toolName}(${args})`)}\\n`);\n return inThinking;\n }\n\n case \"agent.tool.end\": {\n if (event.error) {\n process.stdout.write(` ${red(`✗ ${event.error}`)}\\n`);\n } else {\n const preview = previewResult(event.result);\n process.stdout.write(` ${dim(`→ ${preview}`)}\\n`);\n }\n return inThinking;\n }\n\n case \"agent.message.complete\": {\n const footer = `${event.model} · ${event.inputTokens}↓ ${event.outputTokens}↑`;\n process.stdout.write(`\\n${dim(footer)}\\n`);\n return inThinking;\n }\n\n case \"agent.error\":\n process.stdout.write(`\\n ${red(`⚠ ${event.errorType}: ${event.message}`)}\\n`);\n return inThinking;\n\n default:\n // Ignore iteration/llm/conversation/tool.intent/tool.rejected/etc.\n return inThinking;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Best-effort early-terminate of an async generator without throwing. */\nasync function safeReturn(stream: AsyncGenerator<AgentEvent>): Promise<void> {\n try {\n await stream.return(undefined);\n } catch {\n // swallow — abort path is best-effort\n }\n}\n\n/** Render a tool-call args object compactly; fall back to JSON.stringify. */\nfunction formatArgs(args: Record<string, unknown>): string {\n try {\n const entries = Object.entries(args);\n if (entries.length === 0) return \"\";\n const parts = entries.map(([k, v]) => `${k}=${shortJson(v)}`);\n const joined = parts.join(\", \");\n return joined.length > 120 ? `${joined.slice(0, 117)}...` : joined;\n } catch {\n return \"…\";\n }\n}\n\n/** Collapse a tool result into a single readable line. */\nfunction previewResult(result: unknown): string {\n const s = typeof result === \"string\" ? result : shortJson(result);\n const oneLine = s.replace(/\\s+/g, \" \").trim();\n return oneLine.length > 240 ? `${oneLine.slice(0, 237)}...` : oneLine;\n}\n\nfunction shortJson(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\n// ---------------------------------------------------------------------------\n// ANSI\n// ---------------------------------------------------------------------------\n\nfunction bold(s: string): string {\n return `\\x1b[1m${s}\\x1b[0m`;\n}\nfunction dim(s: string): string {\n return `\\x1b[2m${s}\\x1b[0m`;\n}\nfunction cyan(s: string): string {\n return `\\x1b[36m${s}\\x1b[0m`;\n}\nfunction red(s: string): string {\n return `\\x1b[31m${s}\\x1b[0m`;\n}\nfunction yellow(s: string): string {\n return `\\x1b[33m${s}\\x1b[0m`;\n}\n","/**\n * `ap` (no args) — status dashboard.\n *\n * Mirrors `st`'s bare-command pattern: print a compact overview of what's\n * discovered, which runner the env will pick, and a few hint actions.\n */\n\nimport path from \"node:path\";\nimport type { ProjectConfig } from \"../helpers/config.js\";\nimport type { DiscoveredAgent } from \"../helpers/discover.js\";\n\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\n\ninterface StatusInput {\n config: ProjectConfig;\n agents: DiscoveredAgent[];\n loadErrors: { file: string; error: Error }[];\n}\n\ninterface RunnerHint {\n provider: string;\n detail: string;\n}\n\n/** Print the bare-`ap` dashboard. */\nexport function runStatusCommand(input: StatusInput): void {\n const { config, agents, loadErrors } = input;\n const runner = detectRunnerFromEnv();\n\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(`${BOLD}agentic-patterns${RESET}`);\n lines.push(\"\");\n lines.push(formatAgentsRow(agents, config.root));\n for (const a of agents) {\n lines.push(` ${GREEN}●${RESET} ${a.id}`);\n }\n if (loadErrors.length > 0) {\n for (const err of loadErrors) {\n lines.push(` ${YELLOW}!${RESET} ${err.file}: ${err.error.message}`);\n }\n }\n lines.push(` runner ${runner.provider} ${DIM}(${runner.detail})${RESET}`);\n lines.push(` config ${formatConfigRow(config)}`);\n lines.push(\"\");\n lines.push(` ${DIM}ap run <agent> · ap playground · ap -h${RESET}`);\n lines.push(\"\");\n\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n}\n\nfunction formatAgentsRow(agents: DiscoveredAgent[], root: string): string {\n const count = agents.length;\n if (count === 0) {\n return ` agents ${DIM}none discovered (looked in ${path.relative(process.cwd(), root) || \".\"}/agents/)${RESET}`;\n }\n return ` agents ${count} discovered ${DIM}(./agents/)${RESET}`;\n}\n\nfunction formatConfigRow(config: ProjectConfig): string {\n const parts: string[] = [];\n if (config.hasManifest) parts.push(\"package.json overrides\");\n parts.push(\"see ap config\");\n return parts.join(\" · \");\n}\n\nfunction detectRunnerFromEnv(): RunnerHint {\n // AGENT_MODEL pins an exact model regardless of provider/tier.\n const pinned = process.env.AGENT_MODEL;\n if (process.env.ANTHROPIC_API_KEY) {\n return {\n provider: \"anthropic\",\n detail: `env ANTHROPIC_API_KEY → ${pinned ?? \"claude-sonnet-4-5\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.OPENAI_API_KEY) {\n return {\n provider: \"openai\",\n detail: `env OPENAI_API_KEY → ${pinned ?? \"gpt-4o\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.GOOGLE_GENERATIVE_AI_API_KEY || process.env.GOOGLE_API_KEY) {\n return {\n provider: \"google\",\n detail: `env GOOGLE_*_API_KEY → ${pinned ?? \"gemini-2.5-flash\"}${pinned ? \" (AGENT_MODEL)\" : \"\"}`,\n };\n }\n if (process.env.OLLAMA_HOST) {\n if (pinned) {\n return { provider: \"ollama\", detail: `env OLLAMA_HOST → ${pinned} (AGENT_MODEL)` };\n }\n const tier = (process.env.AGENT_TIER ?? \"sonnet\") as \"opus\" | \"sonnet\" | \"haiku\";\n const model = tier === \"opus\" ? \"qwen3.6:35b-a3b\" : tier === \"haiku\" ? \"qwen3.5:4b\" : \"qwen3.5:9b\";\n return {\n provider: \"ollama\",\n detail: `env OLLAMA_HOST → ${model} (tier=${tier})`,\n };\n }\n return {\n provider: `${YELLOW}none${RESET}`,\n detail: \"set ANTHROPIC_API_KEY, OLLAMA_HOST, or have `claude` CLI on PATH\",\n };\n}\n","/**\n * Project config — find the project root, load `.env`, read the optional\n * `agentic` field from package.json for overrides.\n *\n * Resolution rules:\n * • Walk up from CWD looking for the first `package.json` — that's the root.\n * • If `.env` exists at the root, parse it into `process.env`.\n * • If `package.json` has an `agentic` field, return it as the project config.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { DEFAULT_DASHBOARD_PORT } from \"../constants.js\";\n\nexport interface ProjectConfig {\n /** Absolute path to the project root (where package.json was found). */\n readonly root: string;\n /** Glob(s) for agent file discovery. Default: `[\"agents/**\\/agent.{ts,js,mjs}\"]`. */\n readonly agents: readonly string[];\n /** Default port for `playground`. */\n readonly port: number;\n /** Whether the project package.json has an `agentic` block. */\n readonly hasManifest: boolean;\n}\n\ninterface PackageManifest {\n agentic?: {\n agents?: string | string[];\n port?: number;\n };\n}\n\nconst DEFAULT_AGENT_GLOBS = [\"agents/**/agent.{ts,js,mjs}\"];\n\n/**\n * Walk up from `from` (default: CWD) looking for the nearest `package.json`.\n * Returns the directory containing it, or `null` if none found.\n */\nexport function findProjectRoot(from: string = process.cwd()): string | null {\n let dir = path.resolve(from);\n while (true) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/** Load `.env` at the given root (no-op if file missing). Idempotent. */\nexport function loadDotEnv(root: string): void {\n const file = path.join(root, \".env\");\n if (!fs.existsSync(file)) return;\n const text = fs.readFileSync(file, \"utf-8\");\n for (const rawLine of text.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const eq = line.indexOf(\"=\");\n if (eq === -1) continue;\n const key = line.slice(0, eq).trim();\n const value = line\n .slice(eq + 1)\n .trim()\n .replace(/^[\"'](.*)[\"']$/, \"$1\");\n if (process.env[key] === undefined) process.env[key] = value;\n }\n}\n\n/**\n * Resolve project config. Walks up from CWD to find a project root, loads\n * `.env`, and reads the optional `agentic` block from package.json.\n */\nexport function resolveProjectConfig(from: string = process.cwd()): ProjectConfig {\n const root = findProjectRoot(from) ?? from;\n loadDotEnv(root);\n\n let manifest: PackageManifest = {};\n let hasManifest = false;\n const pkgPath = path.join(root, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const parsed = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")) as PackageManifest;\n manifest = parsed;\n hasManifest = Boolean(parsed.agentic);\n } catch {\n // Malformed package.json — fall through to defaults.\n }\n }\n\n const agents = normalizeGlobs(manifest.agentic?.agents) ?? DEFAULT_AGENT_GLOBS;\n const envPort = process.env.PORT;\n const port =\n manifest.agentic?.port ??\n (envPort !== undefined ? Number.parseInt(envPort, 10) : DEFAULT_DASHBOARD_PORT);\n\n return { root, agents, port, hasManifest };\n}\n\nfunction normalizeGlobs(value: string | string[] | undefined): readonly string[] | undefined {\n if (!value) return undefined;\n return Array.isArray(value) ? value : [value];\n}\n","/**\n * Agent discovery — crawl the project for agent files, dynamic-import each,\n * and normalize the export into an `AgentRegistration` shape.\n *\n * Convention: each agent is a file at `agents/<name>/agent.{ts,js,mjs}`\n * (or `agents/<name>.agent.ts`) that default-exports either:\n * • an `AgentRegistration` object directly:\n * export default { id, name, description?, agent }\n * • a function that returns one (sync or async):\n * export default () => ({ id, name, agent })\n *\n * The `runner` field is NOT defined by the user — the CLI injects it\n * after discovery via `createRunner()`.\n */\n\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { glob } from \"tinyglobby\";\nimport { register } from \"tsx/esm/api\";\n\n// Register tsx as the ESM loader globally — once per process. After this,\n// Node's regular dynamic import() handles `.ts` files transparently AND\n// resolves bare specifiers from the importing file's location like normal.\nlet _tsxRegistered = false;\nfunction ensureTsxRegistered(): void {\n if (_tsxRegistered) return;\n register();\n _tsxRegistered = true;\n}\n\n/** What an agent file is expected to export (sans runner). */\nexport interface DiscoveredAgent {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n // biome-ignore lint/suspicious/noExplicitAny: agent shape comes from agent-core/server, kept loose at the discovery boundary\n readonly agent: any;\n /** Absolute path to the source file (for `ap agents` rendering). */\n readonly file: string;\n}\n\ninterface AgentExport {\n id?: string;\n name?: string;\n description?: string;\n agent?: unknown;\n}\n\n/**\n * Find agent files matching the given globs, rooted at `root`.\n * Returns absolute file paths sorted alphabetically.\n */\nexport async function findAgentFiles(root: string, globs: readonly string[]): Promise<string[]> {\n const matches = await glob([...globs], {\n cwd: root,\n absolute: true,\n onlyFiles: true,\n ignore: [\"**/node_modules/**\", \"**/dist/**\"],\n });\n return matches.sort();\n}\n\n/**\n * Dynamically import an agent file and normalize the export into a\n * `DiscoveredAgent`. Throws a descriptive error on bad shape.\n */\nexport async function loadAgentFile(file: string): Promise<DiscoveredAgent> {\n // tsx's tsImport handles .ts at runtime via on-the-fly transpile.\n // Plain .js/.mjs files go through Node's native import.\n const isTs = file.endsWith(\".ts\") || file.endsWith(\".tsx\") || file.endsWith(\".mts\");\n if (isTs) ensureTsxRegistered();\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown };\n let exported = mod.default;\n\n if (typeof exported === \"function\") {\n exported = await (exported as () => unknown | Promise<unknown>)();\n }\n\n if (!exported || typeof exported !== \"object\") {\n throw new Error(\n `${file}: default export must be an AgentRegistration object or a function returning one`,\n );\n }\n\n const { id, name, description, agent } = exported as AgentExport;\n\n if (!id || typeof id !== \"string\") {\n throw new Error(`${file}: missing or invalid 'id' (must be a non-empty string)`);\n }\n if (!name || typeof name !== \"string\") {\n throw new Error(`${file}: missing or invalid 'name' (must be a non-empty string)`);\n }\n if (!agent || typeof agent !== \"object\") {\n throw new Error(`${file}: missing or invalid 'agent' (must be an Agent object)`);\n }\n\n return {\n id,\n name,\n description,\n agent,\n file,\n };\n}\n\n/**\n * Discover all agents under the given root + globs. Returns successfully\n * loaded agents AND a separate list of load errors (so callers can choose\n * to surface failures without aborting discovery).\n */\nexport async function discoverAgents(\n root: string,\n globs: readonly string[],\n): Promise<{\n agents: DiscoveredAgent[];\n errors: { file: string; error: Error }[];\n}> {\n const files = await findAgentFiles(root, globs);\n const agents: DiscoveredAgent[] = [];\n const errors: { file: string; error: Error }[] = [];\n\n for (const file of files) {\n try {\n const a = await loadAgentFile(file);\n agents.push(a);\n } catch (e) {\n errors.push({\n file: path.relative(root, file),\n error: e instanceof Error ? e : new Error(String(e)),\n });\n }\n }\n\n // Detect duplicate ids — first wins, others surface as errors.\n const seen = new Set<string>();\n const deduped: DiscoveredAgent[] = [];\n for (const a of agents) {\n if (seen.has(a.id)) {\n errors.push({\n file: path.relative(root, a.file),\n error: new Error(`duplicate agent id \"${a.id}\" (already registered)`),\n });\n } else {\n seen.add(a.id);\n deduped.push(a);\n }\n }\n\n return { agents: deduped, errors };\n}\n"],"mappings":"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","names":["path","BOLD","DIM","RESET","spec","fs","path","isCancel","select","text","DIM","BOLD","GREEN","YELLOW","RESET","path","select","isCancel","fs","text","path","fileURLToPath","path","fileURLToPath","createRunner","createToolboxExecutor","isCancel","text","path","BOLD","DIM","RESET","GREEN","YELLOW","fs","path","path","fs","text","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentic-patterns/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "agentic — CLI for running agent projects. Crawls ./agents/, wires observability, serves chat + admin dashboard.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"lint": "biome check src/"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@agentic-patterns/core": "0.1.
|
|
41
|
-
"@agentic-patterns/runtime": "0.1.
|
|
42
|
-
"@agentic-patterns/server": "0.1.
|
|
40
|
+
"@agentic-patterns/core": "0.1.8",
|
|
41
|
+
"@agentic-patterns/runtime": "0.1.8",
|
|
42
|
+
"@agentic-patterns/server": "0.1.8",
|
|
43
43
|
"@hono/node-server": "^1.13.0",
|
|
44
44
|
"@clack/prompts": "^0.8.0",
|
|
45
45
|
"hono": "^4.0.0",
|