diff --git a/packages/cli/src/commands/config.ts b/packages/cli/src/commands/config.ts index 4d33ddc0..f3b51f90 100644 --- a/packages/cli/src/commands/config.ts +++ b/packages/cli/src/commands/config.ts @@ -283,13 +283,46 @@ webhooksCmd console.log(kleur.green(`[stub] webhooks test ${target} · event=${opts.event}`)); }); -webhooksCmd +const webhooksListCmd = webhooksCmd .command('list') .description('All configured outbound targets + subscription URLs') .option('--json') - .action((opts: { json?: boolean }) => { - if (opts.json) { console.log(JSON.stringify({ targets: [], subscriptions: [] }, null, 2)); return; } - console.log(kleur.dim('[stub] webhooks list')); + .action(async (opts: { json?: boolean }) => { + // Read registered targets from the sh1pt config + let targets: string[] = []; + let subscriptions: Array<{ url: string; events: string; description?: string }> = []; + try { + const { loadSync } = await import('../local-vault.js'); + const vault = loadSync(); + const raw = vault.get('webhooks'); + if (raw) { + const parsed = JSON.parse(typeof raw === 'string' ? raw : String(raw)); + if (Array.isArray(parsed.targets)) targets = parsed.targets; + if (Array.isArray(parsed.subscriptions)) subscriptions = parsed.subscriptions; + } + } catch { + // Vault not available — show empty state silently + } + if (opts.json) { + console.log(JSON.stringify({ targets, subscriptions }, null, 2)); + return; + } + if (targets.length === 0 && subscriptions.length === 0) { + console.log(kleur.dim('No webhook targets or subscriptions configured.')); + console.log(` Add one: ${kleur.cyan('sh1pt config webhooks add ')}`); + return; + } + if (targets.length > 0) { + console.log(kleur.bold('\nTargets:')); + for (const t of targets) console.log(` • ${t}`); + } + if (subscriptions.length > 0) { + console.log(kleur.bold('\nSubscriptions:')); + for (const s of subscriptions) { + const desc = s.description ? ` (${s.description})` : ''; + console.log(` • ${s.url} events: ${s.events}${desc}`); + } + } }); // Customer-supplied subscriptions — sh1pt cloud fires these on events. diff --git a/packages/cli/src/commands/iterate.ts b/packages/cli/src/commands/iterate.ts index 383ecf58..1ad27b6c 100644 --- a/packages/cli/src/commands/iterate.ts +++ b/packages/cli/src/commands/iterate.ts @@ -1,7 +1,8 @@ import { Command } from 'commander'; import kleur from 'kleur'; import { describeInput, resolveInput } from '../input.js'; -import { agentsCmd } from './agents.js'; + +// agentsCmd moved to root level — see https://github.com/profullstack/sh1pt/issues/235 export const iterateCmd = new Command('iterate') .description('Observe metrics, have an agent propose changes, ship, measure. Powered by Claude / Codex / Qwen.') @@ -18,10 +19,7 @@ export const iterateCmd = new Command('iterate') iterateCmd.help(); }); -// AI-CLI orchestration lives under iterate (was top-level `sh1pt agents`). -// sh1pt iterate agents [list|setup|talk|run|generate] -iterateCmd.addCommand(agentsCmd); - +// AI-CLI agents moved to root level — see #235. iterateCmd .command('run') .description('Single-shot cycle: pull metrics → have agent propose changes → apply (with confirmation) → ship') diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index ba35351f..72ea3e3b 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -14,6 +14,7 @@ import { makeCategoryCmd } from './commands/adapter-cmd.js'; import { CATEGORIES } from './adapter-registry.js'; import { skillsCmd } from './commands/skills.js'; import { agentsCmd } from './commands/agents.js'; +import { deployCmd } from './commands/deploy.js'; const program = new Command(); @@ -44,6 +45,7 @@ program.addCommand(secretsCmd); program.addCommand(configCmd); program.addCommand(skillsCmd); // skills · package/promote SKILL.md agent skills across marketplaces program.addCommand(agentsCmd); // agents · generate/run/talk with AI coding CLIs +program.addCommand(deployCmd); // deploy · provision cloud infrastructure // Self-management — sh1pt update / upgrade / remove / uninstall. program.addCommand(updateCmd);