squads-cli 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -1152
- package/dist/auth-YW3UPFSB.js +23 -0
- package/dist/autonomy-BWTVDEAT.js +102 -0
- package/dist/autonomy-BWTVDEAT.js.map +1 -0
- package/dist/chunk-3KCWNZWW.js +401 -0
- package/dist/chunk-3KCWNZWW.js.map +1 -0
- package/dist/chunk-67RO2HKR.js +174 -0
- package/dist/chunk-67RO2HKR.js.map +1 -0
- package/dist/chunk-7JVD7RD4.js +275 -0
- package/dist/chunk-7JVD7RD4.js.map +1 -0
- package/dist/chunk-BODLDQY7.js +452 -0
- package/dist/chunk-BODLDQY7.js.map +1 -0
- package/dist/chunk-FFFCFZ6A.js +121 -0
- package/dist/chunk-FFFCFZ6A.js.map +1 -0
- package/dist/chunk-FIWT2NMM.js +165 -0
- package/dist/chunk-FIWT2NMM.js.map +1 -0
- package/dist/chunk-L6GQCHDF.js +222 -0
- package/dist/chunk-L6GQCHDF.js.map +1 -0
- package/dist/{chunk-O7UV3FWI.js → chunk-LDM62TIX.js} +2 -2
- package/dist/chunk-LDM62TIX.js.map +1 -0
- package/dist/chunk-LOA3KWYJ.js +294 -0
- package/dist/chunk-LOA3KWYJ.js.map +1 -0
- package/dist/chunk-NA45DFXY.js +616 -0
- package/dist/chunk-NA45DFXY.js.map +1 -0
- package/dist/{chunk-4CMAEQQY.js → chunk-NQN6JPI7.js} +4 -3
- package/dist/chunk-NQN6JPI7.js.map +1 -0
- package/dist/chunk-OQJHPULO.js +103 -0
- package/dist/chunk-OQJHPULO.js.map +1 -0
- package/dist/chunk-QHNUMM4V.js +87 -0
- package/dist/chunk-QHNUMM4V.js.map +1 -0
- package/dist/chunk-RM6BWILN.js +74 -0
- package/dist/chunk-RM6BWILN.js.map +1 -0
- package/dist/chunk-WBR5J7EX.js +90 -0
- package/dist/chunk-WBR5J7EX.js.map +1 -0
- package/dist/chunk-Z2UKDBNL.js +162 -0
- package/dist/chunk-Z2UKDBNL.js.map +1 -0
- package/dist/cli.js +2151 -12594
- package/dist/cli.js.map +1 -1
- package/dist/context-M2A2DOFV.js +291 -0
- package/dist/context-M2A2DOFV.js.map +1 -0
- package/dist/context-feed-JMNW4GAM.js +391 -0
- package/dist/context-feed-JMNW4GAM.js.map +1 -0
- package/dist/cost-N37I4UTA.js +274 -0
- package/dist/cost-N37I4UTA.js.map +1 -0
- package/dist/create-554W5HNU.js +286 -0
- package/dist/create-554W5HNU.js.map +1 -0
- package/dist/daemon-XWPQPPPN.js +546 -0
- package/dist/daemon-XWPQPPPN.js.map +1 -0
- package/dist/dashboard-L7YKVQEB.js +945 -0
- package/dist/dashboard-L7YKVQEB.js.map +1 -0
- package/dist/dashboard-MFNRLCEE.js +794 -0
- package/dist/dashboard-MFNRLCEE.js.map +1 -0
- package/dist/doctor-RG75M5RO.js +346 -0
- package/dist/doctor-RG75M5RO.js.map +1 -0
- package/dist/env-config-KCLDBKYX.js +21 -0
- package/dist/exec-JQKBF7BL.js +197 -0
- package/dist/exec-JQKBF7BL.js.map +1 -0
- package/dist/feedback-KA2UYBZG.js +229 -0
- package/dist/feedback-KA2UYBZG.js.map +1 -0
- package/dist/github-UQTM5KMS.js +23 -0
- package/dist/goal-EOPC5ZCD.js +168 -0
- package/dist/goal-EOPC5ZCD.js.map +1 -0
- package/dist/health-3FZDOSR5.js +209 -0
- package/dist/health-3FZDOSR5.js.map +1 -0
- package/dist/history-TFVXJEDH.js +229 -0
- package/dist/history-TFVXJEDH.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/init-UOWTNMIE.js +747 -0
- package/dist/init-UOWTNMIE.js.map +1 -0
- package/dist/kpi-2SQ2WCVT.js +413 -0
- package/dist/kpi-2SQ2WCVT.js.map +1 -0
- package/dist/learn-6ERTERAO.js +269 -0
- package/dist/learn-6ERTERAO.js.map +1 -0
- package/dist/list-KSOMUBMB.js +92 -0
- package/dist/list-KSOMUBMB.js.map +1 -0
- package/dist/login-ST6PAXYE.js +155 -0
- package/dist/login-ST6PAXYE.js.map +1 -0
- package/dist/memory-3CSNKXIL.js +562 -0
- package/dist/memory-3CSNKXIL.js.map +1 -0
- package/dist/progress-FKG4V2VH.js +202 -0
- package/dist/progress-FKG4V2VH.js.map +1 -0
- package/dist/providers-66PDCORB.js +65 -0
- package/dist/providers-66PDCORB.js.map +1 -0
- package/dist/results-2MJFLWEO.js +224 -0
- package/dist/results-2MJFLWEO.js.map +1 -0
- package/dist/run-72OQLH5A.js +2685 -0
- package/dist/run-72OQLH5A.js.map +1 -0
- package/dist/session-6H67XPAQ.js +64 -0
- package/dist/session-6H67XPAQ.js.map +1 -0
- package/dist/{chunk-NHGLXN2F.js → sessions-GVQIMN4W.js} +23 -459
- package/dist/sessions-GVQIMN4W.js.map +1 -0
- package/dist/{squad-parser-4BI3G4RS.js → squad-parser-CM3HOIWM.js} +2 -2
- package/dist/squad-parser-CM3HOIWM.js.map +1 -0
- package/dist/stats-ONZI557Q.js +335 -0
- package/dist/stats-ONZI557Q.js.map +1 -0
- package/dist/status-FYH42FTB.js +346 -0
- package/dist/status-FYH42FTB.js.map +1 -0
- package/dist/sync-HJZJNXHW.js +800 -0
- package/dist/sync-HJZJNXHW.js.map +1 -0
- package/dist/update-B4WMUOPO.js +83 -0
- package/dist/update-B4WMUOPO.js.map +1 -0
- package/dist/{update-ALJKFFM7.js → update-L7FGHN6W.js} +2 -2
- package/dist/update-L7FGHN6W.js.map +1 -0
- package/package.json +18 -10
- package/dist/chunk-4CMAEQQY.js.map +0 -1
- package/dist/chunk-NHGLXN2F.js.map +0 -1
- package/dist/chunk-O7UV3FWI.js.map +0 -1
- package/dist/sessions-6PB7ALCE.js +0 -16
- /package/dist/{sessions-6PB7ALCE.js.map → auth-YW3UPFSB.js.map} +0 -0
- /package/dist/{squad-parser-4BI3G4RS.js.map → env-config-KCLDBKYX.js.map} +0 -0
- /package/dist/{update-ALJKFFM7.js.map → github-UQTM5KMS.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts","../src/lib/setup-checks.ts"],"sourcesContent":["/**\n * squads init - Plant the seed\n *\n * Creates:\n * - Use-case specific squads (Engineering, Marketing, Operations, or all)\n * - CLI skill (teaches agents how to use squads CLI)\n * - Core squads (company + research + intelligence) for all use cases\n * - CLAUDE.md (operating manual for all Claude instances)\n * - BUSINESS_BRIEF.md (from user input)\n * - Memory directories (persistent state)\n * - Claude Code hooks (session tracking)\n */\n\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { createInterface } from 'readline';\nimport { checkGitStatus, getRepoName } from '../lib/git.js';\nimport { track, Events } from '../lib/telemetry.js';\nimport {\n loadTemplate,\n type TemplateVariables,\n} from '../lib/templates.js';\nimport {\n PROVIDERS,\n checkGhCli,\n runAuthChecks,\n displayCheckResults,\n} from '../lib/setup-checks.js';\nimport { writeLine } from '../lib/terminal.js';\n\nexport interface InitOptions {\n provider?: string;\n skipInfra?: boolean;\n force?: boolean;\n yes?: boolean;\n quick?: boolean;\n}\n\ntype Provider = 'claude' | 'gemini' | 'openai' | 'ollama' | 'cursor' | 'aider' | 'none';\n\ntype UseCase = 'engineering' | 'marketing' | 'operations' | 'full-company' | 'custom';\n\n/**\n * Use-case configuration: squads, files, memory dirs, and display info\n */\ninterface UseCaseConfig {\n label: string;\n description: string;\n squads: SquadConfig[];\n}\n\ninterface SquadConfig {\n name: string;\n agentCount: number;\n agentSummary: string;\n dirs: string[];\n files: [string, string][]; // [destPath, templatePath]\n memoryFiles: [string, string][]; // [destPath, templatePath]\n}\n\n/**\n * Define what each use case creates\n */\nfunction getUseCaseConfig(useCase: UseCase): UseCaseConfig {\n const configs: Record<UseCase, UseCaseConfig> = {\n engineering: {\n label: 'Engineering',\n description: 'Ships code',\n squads: [getEngineeringSquad()],\n },\n marketing: {\n label: 'Marketing',\n description: 'Grows audience',\n squads: [getMarketingSquad()],\n },\n operations: {\n label: 'Operations',\n description: 'Runs the business',\n squads: [getOperationsSquad()],\n },\n 'full-company': {\n label: 'Full Company',\n description: 'Engineering + Marketing + Operations',\n squads: [getEngineeringSquad(), getMarketingSquad(), getOperationsSquad()],\n },\n custom: {\n label: 'Custom',\n description: 'Empty scaffold — you build from scratch',\n squads: [],\n },\n };\n\n return configs[useCase];\n}\n\nfunction getEngineeringSquad(): SquadConfig {\n return {\n name: 'engineering',\n agentCount: 3,\n agentSummary: 'issue-solver, code-reviewer, test-writer',\n dirs: [\n '.agents/squads/engineering',\n '.agents/memory/engineering/issue-solver',\n '.agents/memory/engineering/code-reviewer',\n '.agents/memory/engineering/test-writer',\n ],\n files: [\n ['.agents/squads/engineering/SQUAD.md', 'squads/engineering/SQUAD.md'],\n ['.agents/squads/engineering/issue-solver.md', 'squads/engineering/issue-solver.md'],\n ['.agents/squads/engineering/code-reviewer.md', 'squads/engineering/code-reviewer.md'],\n ['.agents/squads/engineering/test-writer.md', 'squads/engineering/test-writer.md'],\n ],\n memoryFiles: [\n ['.agents/memory/engineering/issue-solver/state.md', 'memory/engineering/issue-solver/state.md'],\n ],\n };\n}\n\nfunction getMarketingSquad(): SquadConfig {\n return {\n name: 'marketing',\n agentCount: 3,\n agentSummary: 'content-drafter, social-poster, growth-analyst',\n dirs: [\n '.agents/squads/marketing',\n '.agents/memory/marketing/content-drafter',\n '.agents/memory/marketing/social-poster',\n '.agents/memory/marketing/growth-analyst',\n ],\n files: [\n ['.agents/squads/marketing/SQUAD.md', 'squads/marketing/SQUAD.md'],\n ['.agents/squads/marketing/content-drafter.md', 'squads/marketing/content-drafter.md'],\n ['.agents/squads/marketing/social-poster.md', 'squads/marketing/social-poster.md'],\n ['.agents/squads/marketing/growth-analyst.md', 'squads/marketing/growth-analyst.md'],\n ],\n memoryFiles: [\n ['.agents/memory/marketing/content-drafter/state.md', 'memory/marketing/content-drafter/state.md'],\n ],\n };\n}\n\nfunction getOperationsSquad(): SquadConfig {\n return {\n name: 'operations',\n agentCount: 3,\n agentSummary: 'ops-lead, finance-tracker, goal-tracker',\n dirs: [\n '.agents/squads/operations',\n '.agents/memory/operations/ops-lead',\n '.agents/memory/operations/finance-tracker',\n '.agents/memory/operations/goal-tracker',\n ],\n files: [\n ['.agents/squads/operations/SQUAD.md', 'squads/operations/SQUAD.md'],\n ['.agents/squads/operations/ops-lead.md', 'squads/operations/ops-lead.md'],\n ['.agents/squads/operations/finance-tracker.md', 'squads/operations/finance-tracker.md'],\n ['.agents/squads/operations/goal-tracker.md', 'squads/operations/goal-tracker.md'],\n ],\n memoryFiles: [\n ['.agents/memory/operations/ops-lead/state.md', 'memory/operations/ops-lead/state.md'],\n ],\n };\n}\n\nfunction isInteractive(): boolean {\n return process.stdin.isTTY === true && process.stdout.isTTY === true;\n}\n\nasync function prompt(question: string, defaultValue = ''): Promise<string> {\n if (!isInteractive()) return defaultValue;\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n const suffix = defaultValue ? chalk.dim(` (${defaultValue})`) : '';\n rl.question(` ${question}${suffix} `, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultValue);\n });\n });\n}\n\nasync function promptProvider(forceProvider?: string): Promise<Provider> {\n if (forceProvider && forceProvider in PROVIDERS) {\n return forceProvider as Provider;\n }\n if (!isInteractive()) return 'claude';\n\n writeLine();\n writeLine(chalk.bold(' Select your AI assistant:'));\n writeLine();\n writeLine(` ${chalk.cyan('1)')} Claude Code ${chalk.dim('(recommended)')}`);\n writeLine(` ${chalk.cyan('2)')} Gemini`);\n writeLine(` ${chalk.cyan('3)')} OpenAI GPT`);\n writeLine(` ${chalk.cyan('4)')} Ollama ${chalk.dim('(local)')}`);\n writeLine(` ${chalk.cyan('5)')} Other/None`);\n writeLine();\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(` ${chalk.dim('Enter choice [1-5]:')} `, (answer) => {\n rl.close();\n const choice = answer.trim() || '1';\n switch (choice) {\n case '1': resolve('claude'); break;\n case '2': resolve('gemini'); break;\n case '3': resolve('openai'); break;\n case '4': resolve('ollama'); break;\n case '5': resolve('none'); break;\n default: resolve('claude'); break;\n }\n });\n });\n}\n\nasync function promptUseCase(): Promise<UseCase> {\n if (!isInteractive()) return 'full-company';\n\n writeLine();\n writeLine(chalk.bold(' What does your AI workforce need to do?'));\n writeLine();\n writeLine(` ${chalk.cyan('1)')} Engineering ${chalk.dim('— ships code (issue-solver, code-reviewer, test-writer)')}`);\n writeLine(` ${chalk.cyan('2)')} Marketing ${chalk.dim('— grows audience (content-drafter, social-poster, growth-analyst)')}`);\n writeLine(` ${chalk.cyan('3)')} Operations ${chalk.dim('— runs the business (ops-lead, finance-tracker, goal-tracker)')}`);\n writeLine(` ${chalk.cyan('4)')} Full Company ${chalk.dim('— all of the above')} ${chalk.green('(recommended)')}`);\n writeLine(` ${chalk.cyan('5)')} Custom ${chalk.dim('— empty scaffold, you build from scratch')}`);\n writeLine();\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(` ${chalk.dim('Enter choice [1-5]:')} `, (answer) => {\n rl.close();\n const choice = answer.trim() || '4';\n switch (choice) {\n case '1': resolve('engineering'); break;\n case '2': resolve('marketing'); break;\n case '3': resolve('operations'); break;\n case '4': resolve('full-company'); break;\n case '5': resolve('custom'); break;\n default: resolve('full-company'); break;\n }\n });\n });\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load a seed template from templates/seed/\n * Falls back to bundled templates in dist/templates/seed/\n */\nfunction loadSeedTemplate(templatePath: string, variables: TemplateVariables = {}): string {\n // Try loading from seed directory\n return loadTemplate(`seed/${templatePath}`, variables);\n}\n\n/**\n * Write a file only if it doesn't already exist (safe for re-runs)\n */\nasync function writeIfNew(filePath: string, content: string): Promise<boolean> {\n if (await fileExists(filePath)) return false;\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content);\n return true;\n}\n\n/**\n * Write a file, creating directories as needed\n */\nasync function writeFile(filePath: string, content: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content);\n}\n\n/**\n * Main init command - plant the seed\n */\nexport async function initCommand(options: InitOptions): Promise<void> {\n const cwd = process.cwd();\n\n // 1. Welcome\n writeLine();\n writeLine(chalk.bold(' Plant the seed for your AI workforce'));\n writeLine(chalk.dim(' https://agents-squads.com/docs/getting-started'));\n writeLine();\n\n // 2. Select provider\n const selectedProvider = await promptProvider(options.provider);\n const provider = PROVIDERS[selectedProvider];\n\n // 3. Prerequisite checks\n writeLine();\n writeLine(chalk.bold(' Checking prerequisites...'));\n writeLine();\n\n const checks = [\n ...runAuthChecks(selectedProvider),\n checkGhCli(),\n ];\n\n // Check Git\n const gitStatus = checkGitStatus(cwd);\n if (!gitStatus.isGitRepo) {\n checks.push({\n name: 'Git Repository',\n status: 'missing' as const,\n message: 'Git is the coordination layer',\n hint: 'Run: git init',\n fixCommand: 'git init',\n });\n } else {\n checks.push({ name: 'Git Repository', status: 'ok' as const });\n if (gitStatus.hasRemote) {\n const repoName = getRepoName(gitStatus.remoteUrl);\n checks.push({ name: `Remote: ${repoName || gitStatus.remoteUrl}`, status: 'ok' as const });\n }\n }\n\n const { hasErrors } = displayCheckResults(checks);\n\n if (hasErrors && !options.force) {\n writeLine();\n writeLine(chalk.red(' Fix the errors above before continuing.'));\n writeLine(chalk.dim(' Or run with --force to skip checks.'));\n writeLine();\n process.exit(1);\n }\n\n writeLine();\n\n // 4. Ask about the business\n let businessName: string;\n let businessDescription: string;\n let businessFocus: string;\n let selectedUseCase: UseCase;\n\n if (options.yes || options.quick || !isInteractive()) {\n businessName = path.basename(cwd);\n businessDescription = 'General business operations';\n businessFocus = 'Our market, competitors, and growth opportunities';\n selectedUseCase = 'full-company';\n } else {\n const dirName = path.basename(cwd);\n\n writeLine(chalk.bold(' Tell us about your business:'));\n writeLine();\n\n businessName = await prompt(\n 'Company or project name?',\n dirName\n );\n\n businessDescription = await prompt(\n 'What does it do? (one sentence)',\n ''\n );\n\n writeLine();\n\n businessFocus = await prompt(\n 'What should your first research squad investigate?',\n 'Our market, competitors, and growth opportunities'\n );\n\n // 4b. Use-case selection\n selectedUseCase = await promptUseCase();\n }\n\n const useCaseConfig = getUseCaseConfig(selectedUseCase);\n\n // Calculate totals (core squads + use-case squads)\n const coreAgentCount = 12; // company(5) + research(4) + intelligence(3)\n const coreSquadCount = 3;\n const useCaseAgentCount = useCaseConfig.squads.reduce((sum, s) => sum + s.agentCount, 0);\n const totalAgentCount = coreAgentCount + useCaseAgentCount;\n const totalSquadCount = coreSquadCount + useCaseConfig.squads.length;\n\n writeLine();\n writeLine(` ${chalk.green('✓')} Business: ${chalk.cyan(businessName)}${businessDescription ? chalk.dim(` — ${businessDescription}`) : ''}`);\n writeLine(` ${chalk.green('✓')} Provider: ${chalk.cyan(provider?.name || selectedProvider)}`);\n writeLine(` ${chalk.green('✓')} Research focus: ${chalk.cyan(businessFocus)}`);\n writeLine(` ${chalk.green('✓')} Use case: ${chalk.cyan(useCaseConfig.label)} ${chalk.dim(`— ${useCaseConfig.description}`)}`);\n writeLine();\n\n // 5. Create the seed\n const spinner = ora('Planting the seed...').start();\n\n try {\n const variables: TemplateVariables = {\n BUSINESS_NAME: businessName,\n BUSINESS_DESCRIPTION: businessDescription || `${businessName} — details to be added by the manager agent.`,\n BUSINESS_FOCUS: businessFocus,\n PROVIDER: selectedProvider,\n PROVIDER_NAME: provider?.name || 'Unknown',\n };\n\n // Core directories (always created)\n const dirs = [\n '.agents/squads/company',\n '.agents/squads/research',\n '.agents/squads/intelligence',\n '.agents/memory/company/manager',\n '.agents/memory/company/event-dispatcher',\n '.agents/memory/company/goal-tracker',\n '.agents/memory/company/company-eval',\n '.agents/memory/company/company-critic',\n '.agents/memory/research/researcher',\n '.agents/memory/research/analyst',\n '.agents/memory/research/research-eval',\n '.agents/memory/research/research-critic',\n '.agents/memory/intelligence/intel-lead',\n '.agents/memory/intelligence/intel-eval',\n '.agents/memory/intelligence/intel-critic',\n '.agents/skills/squads-cli',\n '.agents/skills/gh',\n '.agents/config',\n ];\n\n // Add use-case specific directories\n for (const squad of useCaseConfig.squads) {\n dirs.push(...squad.dirs);\n }\n\n if (selectedProvider === 'claude') {\n dirs.push('.claude');\n }\n\n for (const dir of dirs) {\n await fs.mkdir(path.join(cwd, dir), { recursive: true });\n }\n\n spinner.text = 'Creating squad definitions...';\n\n // Core squad files (always created)\n const companyFiles: [string, string][] = [\n ['.agents/squads/company/SQUAD.md', 'squads/company/SQUAD.md'],\n ['.agents/squads/company/manager.md', 'squads/company/manager.md'],\n ['.agents/squads/company/event-dispatcher.md', 'squads/company/event-dispatcher.md'],\n ['.agents/squads/company/goal-tracker.md', 'squads/company/goal-tracker.md'],\n ['.agents/squads/company/company-eval.md', 'squads/company/company-eval.md'],\n ['.agents/squads/company/company-critic.md', 'squads/company/company-critic.md'],\n ];\n\n const researchFiles: [string, string][] = [\n ['.agents/squads/research/SQUAD.md', 'squads/research/SQUAD.md'],\n ['.agents/squads/research/researcher.md', 'squads/research/researcher.md'],\n ['.agents/squads/research/analyst.md', 'squads/research/analyst.md'],\n ['.agents/squads/research/research-eval.md', 'squads/research/research-eval.md'],\n ['.agents/squads/research/research-critic.md', 'squads/research/research-critic.md'],\n ];\n\n const intelligenceFiles: [string, string][] = [\n ['.agents/squads/intelligence/SQUAD.md', 'squads/intelligence/SQUAD.md'],\n ['.agents/squads/intelligence/intel-lead.md', 'squads/intelligence/intel-lead.md'],\n ['.agents/squads/intelligence/intel-eval.md', 'squads/intelligence/intel-eval.md'],\n ['.agents/squads/intelligence/intel-critic.md', 'squads/intelligence/intel-critic.md'],\n ];\n\n // Collect all use-case squad files\n const useCaseFiles: [string, string][] = [];\n for (const squad of useCaseConfig.squads) {\n useCaseFiles.push(...squad.files);\n }\n\n // Write all squad files\n for (const [dest, template] of [...companyFiles, ...researchFiles, ...intelligenceFiles, ...useCaseFiles]) {\n const content = loadSeedTemplate(template, variables);\n await writeFile(path.join(cwd, dest), content);\n }\n\n spinner.text = 'Creating memory and config...';\n\n // Core memory state files\n const coreMemoryFiles: [string, string][] = [\n ['.agents/memory/company/manager/state.md', 'memory/company/manager/state.md'],\n ['.agents/memory/research/researcher/state.md', 'memory/research/researcher/state.md'],\n ['.agents/memory/intelligence/intel-lead/state.md', 'memory/intelligence/intel-lead/state.md'],\n ];\n\n // Use-case memory state files\n const useCaseMemoryFiles: [string, string][] = [];\n for (const squad of useCaseConfig.squads) {\n useCaseMemoryFiles.push(...squad.memoryFiles);\n }\n\n for (const [dest, template] of [...coreMemoryFiles, ...useCaseMemoryFiles]) {\n await writeIfNew(path.join(cwd, dest), loadSeedTemplate(template, variables));\n }\n\n // Skills\n const skillContent = loadSeedTemplate('skills/squads-cli/SKILL.md', variables);\n await writeFile(path.join(cwd, '.agents/skills/squads-cli/SKILL.md'), skillContent);\n\n const ghSkillContent = loadSeedTemplate('skills/gh/SKILL.md', variables);\n await writeFile(path.join(cwd, '.agents/skills/gh/SKILL.md'), ghSkillContent);\n\n // Provider config\n const providerConfig = loadSeedTemplate('config/provider.yaml', variables);\n await writeFile(path.join(cwd, '.agents/config/provider.yaml'), providerConfig);\n\n // Business brief\n const businessBrief = loadSeedTemplate('BUSINESS_BRIEF.md.template', variables);\n await writeFile(path.join(cwd, '.agents/BUSINESS_BRIEF.md'), businessBrief);\n\n spinner.text = 'Setting up operating manual...';\n\n // CLAUDE.md (the operating manual — only if it doesn't exist)\n if (selectedProvider === 'claude') {\n const claudeMd = loadSeedTemplate('CLAUDE.md.template', variables);\n await writeIfNew(path.join(cwd, 'CLAUDE.md'), claudeMd);\n\n // Claude Code hooks\n const hooksContent = loadSeedTemplate('hooks/settings.json.template', variables);\n await writeIfNew(path.join(cwd, '.claude/settings.json'), hooksContent);\n }\n\n spinner.succeed('Seed planted');\n\n // Track initialization\n await track(Events.CLI_INIT, {\n success: true,\n hasGit: gitStatus.isGitRepo,\n hasRemote: gitStatus.hasRemote,\n provider: selectedProvider,\n useCase: selectedUseCase,\n agentCount: totalAgentCount,\n squadCount: totalSquadCount,\n hasBusinessName: businessName !== path.basename(cwd),\n hasBusinessDescription: businessDescription.length > 0,\n });\n\n } catch (error) {\n spinner.fail('Failed to plant the seed');\n console.error(chalk.red(` ${error}`));\n process.exit(1);\n }\n\n // 6. Success message\n writeLine();\n writeLine(chalk.green.bold(` ${businessName}'s AI workforce is ready.`));\n writeLine();\n writeLine(chalk.dim(' Created:'));\n\n // Core squads (always present)\n writeLine(chalk.dim(' • .agents/squads/company/ 5 agents (manager, dispatcher, tracker, eval, critic)'));\n writeLine(chalk.dim(' • .agents/squads/research/ 4 agents (researcher, analyst, eval, critic)'));\n writeLine(chalk.dim(' • .agents/squads/intelligence/ 3 agents (intel-lead, eval, critic)'));\n\n // Use-case specific squads\n for (const squad of useCaseConfig.squads) {\n const padding = ' '.repeat(Math.max(0, 22 - squad.name.length));\n writeLine(chalk.dim(` • .agents/squads/${squad.name}/${padding}${squad.agentCount} agents (${squad.agentSummary})`));\n }\n\n writeLine(chalk.dim(' • .agents/skills/ CLI + GitHub workflow skills'));\n writeLine(chalk.dim(' • .agents/memory/ Persistent state'));\n writeLine(chalk.dim(' • .agents/BUSINESS_BRIEF.md'));\n if (selectedProvider === 'claude') {\n writeLine(chalk.dim(' • CLAUDE.md Operating manual'));\n writeLine(chalk.dim(' • .claude/settings.json Session hooks'));\n }\n writeLine();\n writeLine(chalk.bold(' Getting started:'));\n writeLine();\n writeLine(` ${chalk.cyan('1.')} ${chalk.yellow('git add -A && git commit -m \"feat: init AI workforce\"')}`);\n writeLine(chalk.dim(' Git is the coordination layer — commit first'));\n writeLine();\n\n // Dynamic \"first run\" suggestion based on use case\n const firstRunCommand = getFirstRunCommand(selectedUseCase);\n writeLine(` ${chalk.cyan('2.')} ${chalk.yellow(firstRunCommand.command)}`);\n writeLine(chalk.dim(` ${firstRunCommand.description}`));\n writeLine();\n writeLine(` ${chalk.cyan('3.')} ${chalk.yellow(`squads dash`)}`);\n writeLine(chalk.dim(' See all your squads and agents at a glance'));\n writeLine();\n writeLine(chalk.dim(' Docs: https://agents-squads.com/docs/getting-started'));\n writeLine();\n}\n\n/**\n * Get the suggested first command based on use case\n */\nfunction getFirstRunCommand(useCase: UseCase): { command: string; description: string } {\n switch (useCase) {\n case 'engineering':\n return {\n command: 'squads run engineering/issue-solver',\n description: 'Your first agent finds and solves GitHub issues',\n };\n case 'marketing':\n return {\n command: 'squads run marketing/content-drafter',\n description: 'Your first agent drafts content for your business',\n };\n case 'operations':\n return {\n command: 'squads run operations/ops-lead',\n description: 'Your first agent starts running daily operations',\n };\n case 'full-company':\n return {\n command: 'squads run research/researcher',\n description: 'Your first agent researches the topic you set',\n };\n case 'custom':\n default:\n return {\n command: 'squads run research/researcher',\n description: 'Your first agent researches the topic you set',\n };\n }\n}\n","/**\n * Setup checks and validation for squads setup command\n * Provides prerequisite checking with helpful fix guidance\n */\n\nimport { execSync, spawn } from 'child_process';\nimport {\n colors,\n RESET,\n icons,\n writeLine,\n} from './terminal.js';\n\nexport type CheckStatus = 'ok' | 'missing' | 'warning' | 'error';\n\nexport interface CheckResult {\n name: string;\n status: CheckStatus;\n message?: string;\n hint?: string;\n fixCommand?: string;\n}\n\nexport interface ProviderInfo {\n id: string;\n name: string;\n cliCheck?: string;\n envKey?: string;\n installCmd?: string;\n loginCmd?: string;\n requiresSubscription: boolean;\n requiresApiKey: boolean;\n}\n\nexport const PROVIDERS: Record<string, ProviderInfo> = {\n claude: {\n id: 'claude',\n name: 'Claude Code (Anthropic)',\n cliCheck: 'claude',\n installCmd: 'npm install -g @anthropic-ai/claude-code',\n loginCmd: 'claude login',\n requiresSubscription: true,\n requiresApiKey: false,\n },\n gemini: {\n id: 'gemini',\n name: 'Gemini (Google)',\n cliCheck: 'gemini',\n envKey: 'GEMINI_API_KEY',\n installCmd: 'npm install -g @anthropic-ai/claude-code', // Placeholder - gemini CLI\n requiresSubscription: false,\n requiresApiKey: true,\n },\n openai: {\n id: 'openai',\n name: 'GPT (OpenAI)',\n envKey: 'OPENAI_API_KEY',\n requiresSubscription: false,\n requiresApiKey: true,\n },\n ollama: {\n id: 'ollama',\n name: 'Ollama (Local)',\n cliCheck: 'ollama',\n installCmd: 'brew install ollama',\n requiresSubscription: false,\n requiresApiKey: false,\n },\n cursor: {\n id: 'cursor',\n name: 'Cursor IDE',\n requiresSubscription: true,\n requiresApiKey: false,\n },\n aider: {\n id: 'aider',\n name: 'Aider',\n cliCheck: 'aider',\n installCmd: 'pip install aider-chat',\n requiresSubscription: false,\n requiresApiKey: true,\n },\n none: {\n id: 'none',\n name: 'Planning Only (no agent execution)',\n requiresSubscription: false,\n requiresApiKey: false,\n },\n};\n\n/**\n * Check if a command exists in PATH\n */\nexport function commandExists(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Docker is running\n */\nexport function isDockerRunning(): boolean {\n try {\n execSync('docker info', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Colima is running (alternative to Docker Desktop on macOS)\n */\nexport function isColimaRunning(): boolean {\n try {\n const result = execSync('colima status', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });\n return result.includes('Running');\n } catch {\n return false;\n }\n}\n\n/**\n * Check Docker/Colima prerequisites\n */\nexport function checkDockerPrereqs(): CheckResult {\n // Check if Docker is running\n if (isDockerRunning()) {\n return { name: 'Docker', status: 'ok' };\n }\n\n // Docker not running - check if it's installed\n if (commandExists('docker')) {\n // Check if Colima is available as an alternative\n if (commandExists('colima')) {\n if (isColimaRunning()) {\n return { name: 'Docker (Colima)', status: 'ok' };\n }\n return {\n name: 'Docker',\n status: 'warning',\n message: 'Docker installed but not running',\n hint: 'Start Docker Desktop or run: colima start',\n fixCommand: 'colima start',\n };\n }\n\n return {\n name: 'Docker',\n status: 'warning',\n message: 'Docker installed but not running',\n hint: 'Start Docker Desktop',\n };\n }\n\n // Docker not installed\n return {\n name: 'Docker',\n status: 'warning',\n message: 'Optional: enables scheduling, telemetry, and persistent storage',\n hint: 'Core commands (init, run, status, eval) work without Docker. Install for scheduling: brew install --cask docker',\n };\n}\n\n/**\n * Check GitHub CLI\n */\nexport function checkGhCli(): CheckResult {\n if (!commandExists('gh')) {\n return {\n name: 'GitHub CLI',\n status: 'missing',\n message: 'Required for GitHub integration',\n hint: 'Install: brew install gh',\n fixCommand: 'brew install gh',\n };\n }\n\n // Check if authenticated\n try {\n execSync('gh auth status', { stdio: 'ignore' });\n return { name: 'GitHub CLI', status: 'ok' };\n } catch {\n return {\n name: 'GitHub CLI',\n status: 'warning',\n message: 'Installed but not authenticated',\n hint: 'Run: gh auth login',\n fixCommand: 'gh auth login',\n };\n }\n}\n\n/**\n * Check GitHub token permissions\n */\nexport function checkGhPermissions(): CheckResult {\n try {\n // Get current scopes\n const result = execSync('gh auth status 2>&1', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });\n\n // Check for required scopes\n const hasRepo = result.includes('repo') || result.includes('Token scopes:') && !result.includes('none');\n const hasWorkflow = result.includes('workflow');\n\n if (!hasRepo) {\n return {\n name: 'GitHub Permissions',\n status: 'warning',\n message: 'Missing repo scope',\n hint: 'Run: gh auth refresh -s repo,workflow',\n fixCommand: 'gh auth refresh -s repo,workflow',\n };\n }\n\n if (!hasWorkflow) {\n return {\n name: 'GitHub Permissions',\n status: 'warning',\n message: 'Missing workflow scope (optional)',\n hint: 'For Actions: gh auth refresh -s repo,workflow',\n };\n }\n\n return { name: 'GitHub Permissions', status: 'ok' };\n } catch {\n return {\n name: 'GitHub Permissions',\n status: 'warning',\n message: 'Could not verify permissions',\n hint: 'Run: gh auth status',\n };\n }\n}\n\n/**\n * Check Claude CLI\n */\nexport function checkClaudeCli(): CheckResult {\n if (!commandExists('claude')) {\n return {\n name: 'Claude CLI',\n status: 'missing',\n message: 'Required to run agents',\n hint: 'Install: npm install -g @anthropic-ai/claude-code',\n fixCommand: 'npm install -g @anthropic-ai/claude-code',\n };\n }\n\n // Check if logged in by running claude --version\n try {\n execSync('claude --version', { stdio: 'ignore' });\n return { name: 'Claude CLI', status: 'ok' };\n } catch {\n return {\n name: 'Claude CLI',\n status: 'warning',\n message: 'Installed but may need login',\n hint: 'Run: claude login',\n fixCommand: 'claude login',\n };\n }\n}\n\n/**\n * Check provider-specific requirements\n */\nexport function checkProviderAuth(providerId: string): CheckResult {\n const provider = PROVIDERS[providerId];\n if (!provider) {\n return { name: 'Provider', status: 'warning', message: `Unknown provider: ${providerId}` };\n }\n\n // No requirements for none/cursor\n if (providerId === 'none' || providerId === 'cursor') {\n return { name: provider.name, status: 'ok' };\n }\n\n // Check CLI if required\n if (provider.cliCheck) {\n if (!commandExists(provider.cliCheck)) {\n return {\n name: provider.name,\n status: 'missing',\n message: `CLI not installed`,\n hint: provider.installCmd ? `Install: ${provider.installCmd}` : undefined,\n fixCommand: provider.installCmd,\n };\n }\n }\n\n // Check API key if required\n if (provider.envKey && provider.requiresApiKey) {\n if (!process.env[provider.envKey]) {\n return {\n name: provider.name,\n status: 'warning',\n message: `${provider.envKey} not set`,\n hint: `Set environment variable: export ${provider.envKey}=<your-key>`,\n };\n }\n }\n\n return { name: provider.name, status: 'ok' };\n}\n\n/**\n * Run all prerequisite checks\n */\nexport function runPrereqChecks(): CheckResult[] {\n return [\n checkDockerPrereqs(),\n checkGhCli(),\n ];\n}\n\n/**\n * Run all auth checks for a specific provider\n */\nexport function runAuthChecks(providerId: string): CheckResult[] {\n const checks: CheckResult[] = [];\n\n // Provider-specific auth\n checks.push(checkProviderAuth(providerId));\n\n // Claude CLI check (only for claude provider)\n if (providerId === 'claude') {\n checks.push(checkClaudeCli());\n }\n\n // GitHub permissions (for all providers that use GitHub)\n if (providerId !== 'none') {\n checks.push(checkGhPermissions());\n }\n\n return checks;\n}\n\n/**\n * Display check results with formatting\n */\nexport function displayCheckResults(checks: CheckResult[]): {\n hasErrors: boolean;\n hasWarnings: boolean;\n errorChecks: CheckResult[];\n warningChecks: CheckResult[];\n} {\n const errorChecks: CheckResult[] = [];\n const warningChecks: CheckResult[] = [];\n\n for (const check of checks) {\n const icon = getStatusIcon(check.status);\n const statusColor = getStatusColor(check.status);\n\n if (check.status === 'ok') {\n writeLine(` ${icon} ${check.name}`);\n } else {\n const suffix = check.message ? ` ${colors.dim}(${check.message})${RESET}` : '';\n writeLine(` ${icon} ${statusColor}${check.name}${RESET}${suffix}`);\n\n if (check.hint) {\n writeLine(` ${colors.cyan}→ ${check.hint}${RESET}`);\n }\n\n if (check.status === 'error' || check.status === 'missing') {\n errorChecks.push(check);\n } else if (check.status === 'warning') {\n warningChecks.push(check);\n }\n }\n }\n\n return {\n hasErrors: errorChecks.length > 0,\n hasWarnings: warningChecks.length > 0,\n errorChecks,\n warningChecks,\n };\n}\n\nfunction getStatusIcon(status: CheckStatus): string {\n switch (status) {\n case 'ok':\n return `${colors.green}${icons.success}${RESET}`;\n case 'warning':\n return `${colors.yellow}${icons.warning}${RESET}`;\n case 'missing':\n case 'error':\n return `${colors.red}${icons.error}${RESET}`;\n }\n}\n\nfunction getStatusColor(status: CheckStatus): string {\n switch (status) {\n case 'ok':\n return colors.green;\n case 'warning':\n return colors.yellow;\n case 'missing':\n case 'error':\n return colors.red;\n }\n}\n\n/**\n * Attempt to fix a failed check by running its fix command\n */\nexport async function attemptFix(check: CheckResult): Promise<boolean> {\n if (!check.fixCommand) {\n return false;\n }\n\n writeLine();\n writeLine(` ${colors.cyan}${icons.progress}${RESET} Running: ${colors.dim}${check.fixCommand}${RESET}`);\n writeLine();\n\n return new Promise((resolve) => {\n const proc = spawn(check.fixCommand!, [], {\n stdio: 'inherit',\n shell: true,\n });\n\n proc.on('close', (code) => {\n resolve(code === 0);\n });\n\n proc.on('error', () => {\n resolve(false);\n });\n });\n}\n\n/**\n * Wait for a service to be ready with retry\n */\nexport async function waitForService(\n name: string,\n checkFn: () => boolean | Promise<boolean>,\n maxAttempts = 30,\n intervalMs = 1000\n): Promise<boolean> {\n for (let i = 0; i < maxAttempts; i++) {\n const ready = await checkFn();\n if (ready) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n return false;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
Events,
|
|
4
|
+
track
|
|
5
|
+
} from "./chunk-L6GQCHDF.js";
|
|
6
|
+
import {
|
|
7
|
+
findSquadsDir,
|
|
8
|
+
listSquads,
|
|
9
|
+
loadSquad
|
|
10
|
+
} from "./chunk-LDM62TIX.js";
|
|
11
|
+
import {
|
|
12
|
+
RESET,
|
|
13
|
+
bold,
|
|
14
|
+
colors,
|
|
15
|
+
gradient,
|
|
16
|
+
icons,
|
|
17
|
+
writeLine
|
|
18
|
+
} from "./chunk-N7KDWU4W.js";
|
|
19
|
+
import "./chunk-7OCVIDC7.js";
|
|
20
|
+
|
|
21
|
+
// src/lib/kpi.ts
|
|
22
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
23
|
+
import { join, dirname } from "path";
|
|
24
|
+
function getKpiStorePath(squadName) {
|
|
25
|
+
const squadsDir = findSquadsDir();
|
|
26
|
+
if (!squadsDir) {
|
|
27
|
+
throw new Error("No .agents/squads directory found");
|
|
28
|
+
}
|
|
29
|
+
return join(dirname(squadsDir), "memory", squadName, "kpis.json");
|
|
30
|
+
}
|
|
31
|
+
function loadKpiStore(squadName) {
|
|
32
|
+
const path = getKpiStorePath(squadName);
|
|
33
|
+
if (!existsSync(path)) {
|
|
34
|
+
return {
|
|
35
|
+
squadName,
|
|
36
|
+
kpis: {},
|
|
37
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const content = readFileSync(path, "utf-8");
|
|
42
|
+
return JSON.parse(content);
|
|
43
|
+
} catch {
|
|
44
|
+
return {
|
|
45
|
+
squadName,
|
|
46
|
+
kpis: {},
|
|
47
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function saveKpiStore(store) {
|
|
52
|
+
const path = getKpiStorePath(store.squadName);
|
|
53
|
+
const dir = dirname(path);
|
|
54
|
+
if (!existsSync(dir)) {
|
|
55
|
+
mkdirSync(dir, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
store.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
58
|
+
writeFileSync(path, JSON.stringify(store, null, 2));
|
|
59
|
+
}
|
|
60
|
+
function recordKpiValue(squadName, kpiName, value, note) {
|
|
61
|
+
const store = loadKpiStore(squadName);
|
|
62
|
+
if (!store.kpis[kpiName]) {
|
|
63
|
+
store.kpis[kpiName] = [];
|
|
64
|
+
}
|
|
65
|
+
const record = {
|
|
66
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
67
|
+
value,
|
|
68
|
+
note
|
|
69
|
+
};
|
|
70
|
+
store.kpis[kpiName].push(record);
|
|
71
|
+
saveKpiStore(store);
|
|
72
|
+
return record;
|
|
73
|
+
}
|
|
74
|
+
function getKpiHistory(squadName, kpiName, limit) {
|
|
75
|
+
const store = loadKpiStore(squadName);
|
|
76
|
+
const history = store.kpis[kpiName] || [];
|
|
77
|
+
if (limit) {
|
|
78
|
+
return history.slice(-limit);
|
|
79
|
+
}
|
|
80
|
+
return history;
|
|
81
|
+
}
|
|
82
|
+
function calculateTrend(history) {
|
|
83
|
+
if (history.length < 2) return "flat";
|
|
84
|
+
const recent = history.slice(-5);
|
|
85
|
+
if (recent.length < 2) return "flat";
|
|
86
|
+
const first = recent[0].value;
|
|
87
|
+
const last = recent[recent.length - 1].value;
|
|
88
|
+
const change = (last - first) / first * 100;
|
|
89
|
+
if (change > 5) return "up";
|
|
90
|
+
if (change < -5) return "down";
|
|
91
|
+
return "flat";
|
|
92
|
+
}
|
|
93
|
+
function getKpiState(definition, squadName) {
|
|
94
|
+
const history = getKpiHistory(squadName, definition.name);
|
|
95
|
+
const lastValue = history.length > 0 ? history[history.length - 1] : void 0;
|
|
96
|
+
return {
|
|
97
|
+
...definition,
|
|
98
|
+
current: lastValue?.value,
|
|
99
|
+
lastUpdated: lastValue?.timestamp,
|
|
100
|
+
trend: calculateTrend(history),
|
|
101
|
+
percentOfTarget: lastValue ? Math.round(lastValue.value / definition.target * 100) : void 0,
|
|
102
|
+
history
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function generateKpiInsight(kpi) {
|
|
106
|
+
if (!kpi.current || !kpi.percentOfTarget) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const trendEmoji = kpi.trend === "up" ? "\u{1F4C8}" : kpi.trend === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
|
|
110
|
+
const statusEmoji = kpi.percentOfTarget >= 100 ? "\u2705" : kpi.percentOfTarget >= 70 ? "\u{1F7E1}" : "\u{1F534}";
|
|
111
|
+
if (kpi.percentOfTarget >= 100) {
|
|
112
|
+
return `${statusEmoji} ${kpi.name}: Target achieved! ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;
|
|
113
|
+
} else if (kpi.percentOfTarget >= 70) {
|
|
114
|
+
return `${statusEmoji} ${kpi.name}: On track - ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;
|
|
115
|
+
} else {
|
|
116
|
+
return `${statusEmoji} ${kpi.name}: Needs attention - ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function getValuesForPeriod(history, period, count = 7) {
|
|
120
|
+
const now = /* @__PURE__ */ new Date();
|
|
121
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
122
|
+
switch (period) {
|
|
123
|
+
case "daily":
|
|
124
|
+
cutoff.setDate(now.getDate() - count);
|
|
125
|
+
break;
|
|
126
|
+
case "weekly":
|
|
127
|
+
cutoff.setDate(now.getDate() - count * 7);
|
|
128
|
+
break;
|
|
129
|
+
case "monthly":
|
|
130
|
+
cutoff.setMonth(now.getMonth() - count);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
return history.filter((v) => new Date(v.timestamp) >= cutoff);
|
|
134
|
+
}
|
|
135
|
+
function parseKpiDefinitions(frontmatter) {
|
|
136
|
+
if (!frontmatter) return [];
|
|
137
|
+
const kpis = frontmatter.kpis;
|
|
138
|
+
if (!kpis || !Array.isArray(kpis)) {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
return kpis.map((k) => ({
|
|
142
|
+
name: String(k.name || ""),
|
|
143
|
+
target: Number(k.target || 0),
|
|
144
|
+
unit: String(k.unit || ""),
|
|
145
|
+
period: k.period || "weekly",
|
|
146
|
+
source: k.source || "manual",
|
|
147
|
+
description: k.description ? String(k.description) : void 0
|
|
148
|
+
})).filter((k) => k.name && k.target > 0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/commands/kpi.ts
|
|
152
|
+
async function kpiShowCommand(squadName, options = {}) {
|
|
153
|
+
await track(Events.CLI_KPI_SHOW, { squad: squadName });
|
|
154
|
+
const squad = loadSquad(squadName);
|
|
155
|
+
if (!squad) {
|
|
156
|
+
writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const definitions = parseKpiDefinitions(squad.frontmatter);
|
|
160
|
+
if (definitions.length === 0) {
|
|
161
|
+
writeLine();
|
|
162
|
+
writeLine(` ${colors.yellow}No KPIs defined for ${squadName}${RESET}`);
|
|
163
|
+
writeLine();
|
|
164
|
+
writeLine(` ${colors.dim}Define KPIs in SQUAD.md frontmatter:${RESET}`);
|
|
165
|
+
writeLine(` ${colors.dim}---${RESET}`);
|
|
166
|
+
writeLine(` ${colors.dim}kpis:${RESET}`);
|
|
167
|
+
writeLine(` ${colors.dim} - name: "leads_generated"${RESET}`);
|
|
168
|
+
writeLine(` ${colors.dim} target: 10${RESET}`);
|
|
169
|
+
writeLine(` ${colors.dim} unit: "leads"${RESET}`);
|
|
170
|
+
writeLine(` ${colors.dim} period: weekly${RESET}`);
|
|
171
|
+
writeLine(` ${colors.dim}---${RESET}`);
|
|
172
|
+
writeLine();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const kpis = definitions.map((def) => getKpiState(def, squadName));
|
|
176
|
+
if (options.json) {
|
|
177
|
+
console.log(JSON.stringify(kpis, null, 2));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
writeLine();
|
|
181
|
+
writeLine(` ${gradient("squads")} ${colors.dim}kpi show${RESET} ${colors.cyan}${squadName}${RESET}`);
|
|
182
|
+
writeLine();
|
|
183
|
+
for (const kpi of kpis) {
|
|
184
|
+
const insight = generateKpiInsight(kpi);
|
|
185
|
+
if (insight) {
|
|
186
|
+
writeLine(` ${insight}`);
|
|
187
|
+
} else {
|
|
188
|
+
writeLine(` ${colors.dim}\u25CB${RESET} ${kpi.name}: ${colors.dim}No data recorded${RESET}`);
|
|
189
|
+
}
|
|
190
|
+
if (kpi.description) {
|
|
191
|
+
writeLine(` ${colors.dim}${kpi.description}${RESET}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
writeLine();
|
|
195
|
+
}
|
|
196
|
+
async function kpiRecordCommand(squadName, kpiName, value, options = {}) {
|
|
197
|
+
await track(Events.CLI_KPI_RECORD, { squad: squadName, kpi: kpiName });
|
|
198
|
+
const squad = loadSquad(squadName);
|
|
199
|
+
if (!squad) {
|
|
200
|
+
writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const definitions = parseKpiDefinitions(squad.frontmatter);
|
|
204
|
+
const definition = definitions.find((d) => d.name === kpiName);
|
|
205
|
+
if (!definition) {
|
|
206
|
+
writeLine(` ${colors.red}KPI "${kpiName}" not defined in ${squadName}${RESET}`);
|
|
207
|
+
writeLine();
|
|
208
|
+
writeLine(` ${colors.dim}Available KPIs:${RESET}`);
|
|
209
|
+
for (const def of definitions) {
|
|
210
|
+
writeLine(` ${colors.dim} - ${def.name}${RESET}`);
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const numValue = parseFloat(value);
|
|
215
|
+
if (isNaN(numValue)) {
|
|
216
|
+
writeLine(` ${colors.red}Invalid value: ${value}${RESET}`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const record = recordKpiValue(squadName, kpiName, numValue, options.note);
|
|
220
|
+
if (options.json) {
|
|
221
|
+
console.log(JSON.stringify(record, null, 2));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
writeLine();
|
|
225
|
+
writeLine(` ${icons.success} Recorded ${colors.cyan}${kpiName}${RESET}: ${bold}${numValue}${RESET} ${definition.unit}`);
|
|
226
|
+
if (options.note) {
|
|
227
|
+
writeLine(` ${colors.dim}Note: ${options.note}${RESET}`);
|
|
228
|
+
}
|
|
229
|
+
const percentOfTarget = Math.round(numValue / definition.target * 100);
|
|
230
|
+
const statusEmoji = percentOfTarget >= 100 ? "\u2705" : percentOfTarget >= 70 ? "\u{1F7E1}" : "\u{1F534}";
|
|
231
|
+
writeLine(` ${statusEmoji} ${percentOfTarget}% of target (${definition.target} ${definition.unit}/${definition.period})`);
|
|
232
|
+
writeLine();
|
|
233
|
+
}
|
|
234
|
+
async function kpiTrendCommand(squadName, kpiName, options = {}) {
|
|
235
|
+
await track(Events.CLI_KPI_TREND, { squad: squadName, kpi: kpiName });
|
|
236
|
+
const squad = loadSquad(squadName);
|
|
237
|
+
if (!squad) {
|
|
238
|
+
writeLine(` ${colors.red}Squad "${squadName}" not found${RESET}`);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const definitions = parseKpiDefinitions(squad.frontmatter);
|
|
242
|
+
const definition = definitions.find((d) => d.name === kpiName);
|
|
243
|
+
if (!definition) {
|
|
244
|
+
writeLine(` ${colors.red}KPI "${kpiName}" not defined in ${squadName}${RESET}`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const kpi = getKpiState(definition, squadName);
|
|
248
|
+
const periods = parseInt(options.periods || "7", 10);
|
|
249
|
+
const values = getValuesForPeriod(kpi.history, definition.period, periods);
|
|
250
|
+
if (options.json) {
|
|
251
|
+
console.log(JSON.stringify({
|
|
252
|
+
kpi: kpiName,
|
|
253
|
+
definition,
|
|
254
|
+
trend: kpi.trend,
|
|
255
|
+
values
|
|
256
|
+
}, null, 2));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
writeLine();
|
|
260
|
+
writeLine(` ${gradient("squads")} ${colors.dim}kpi trend${RESET} ${colors.cyan}${squadName}/${kpiName}${RESET}`);
|
|
261
|
+
writeLine();
|
|
262
|
+
const trendEmoji = kpi.trend === "up" ? "\u{1F4C8}" : kpi.trend === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
|
|
263
|
+
writeLine(` ${bold}${kpiName}${RESET} ${trendEmoji} ${kpi.trend}`);
|
|
264
|
+
writeLine(` ${colors.dim}Target: ${definition.target} ${definition.unit}/${definition.period}${RESET}`);
|
|
265
|
+
writeLine();
|
|
266
|
+
if (values.length === 0) {
|
|
267
|
+
writeLine(` ${colors.dim}No data for the last ${periods} ${definition.period} periods${RESET}`);
|
|
268
|
+
} else {
|
|
269
|
+
const maxValue = Math.max(...values.map((v) => v.value), definition.target);
|
|
270
|
+
for (const v of values.slice(-10)) {
|
|
271
|
+
const barLength = Math.round(v.value / maxValue * 30);
|
|
272
|
+
const bar = "\u2588".repeat(barLength);
|
|
273
|
+
const targetMark = v.value >= definition.target ? colors.green : colors.red;
|
|
274
|
+
const date = new Date(v.timestamp).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
275
|
+
writeLine(` ${colors.dim}${date}${RESET} ${targetMark}${bar}${RESET} ${v.value}`);
|
|
276
|
+
}
|
|
277
|
+
writeLine();
|
|
278
|
+
writeLine(` ${colors.dim}Target line: ${definition.target} ${"\u2500".repeat(20)}${RESET}`);
|
|
279
|
+
}
|
|
280
|
+
writeLine();
|
|
281
|
+
}
|
|
282
|
+
async function kpiInsightsCommand(squadName, options = {}) {
|
|
283
|
+
await track(Events.CLI_KPI_INSIGHTS, { squad: squadName || "all" });
|
|
284
|
+
const squadsDir = findSquadsDir();
|
|
285
|
+
if (!squadsDir) {
|
|
286
|
+
writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const squadsToCheck = squadName ? [squadName] : listSquads(squadsDir);
|
|
290
|
+
const allInsights = [];
|
|
291
|
+
for (const name of squadsToCheck) {
|
|
292
|
+
const squad = loadSquad(name);
|
|
293
|
+
if (!squad) continue;
|
|
294
|
+
const definitions = parseKpiDefinitions(squad.frontmatter);
|
|
295
|
+
for (const def of definitions) {
|
|
296
|
+
const kpi = getKpiState(def, name);
|
|
297
|
+
const insight = generateKpiInsight(kpi);
|
|
298
|
+
if (insight && kpi.percentOfTarget !== void 0) {
|
|
299
|
+
allInsights.push({
|
|
300
|
+
squad: name,
|
|
301
|
+
kpi: def.name,
|
|
302
|
+
insight,
|
|
303
|
+
percentOfTarget: kpi.percentOfTarget
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (options.json) {
|
|
309
|
+
console.log(JSON.stringify(allInsights, null, 2));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
writeLine();
|
|
313
|
+
writeLine(` ${gradient("squads")} ${colors.dim}kpi insights${RESET}`);
|
|
314
|
+
writeLine();
|
|
315
|
+
if (allInsights.length === 0) {
|
|
316
|
+
writeLine(` ${colors.dim}No KPI data recorded yet${RESET}`);
|
|
317
|
+
writeLine();
|
|
318
|
+
writeLine(` ${colors.dim}Record KPI values:${RESET}`);
|
|
319
|
+
writeLine(` ${colors.dim}$ squads kpi record <squad> <kpi> <value>${RESET}`);
|
|
320
|
+
writeLine();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
allInsights.sort((a, b) => a.percentOfTarget - b.percentOfTarget);
|
|
324
|
+
const needsAttention = allInsights.filter((i) => i.percentOfTarget < 70);
|
|
325
|
+
const onTrack = allInsights.filter((i) => i.percentOfTarget >= 70 && i.percentOfTarget < 100);
|
|
326
|
+
const achieved = allInsights.filter((i) => i.percentOfTarget >= 100);
|
|
327
|
+
if (needsAttention.length > 0) {
|
|
328
|
+
writeLine(` ${colors.red}${bold}Needs Attention${RESET}`);
|
|
329
|
+
for (const item of needsAttention) {
|
|
330
|
+
writeLine(` ${item.insight}`);
|
|
331
|
+
writeLine(` ${colors.dim}Squad: ${item.squad}${RESET}`);
|
|
332
|
+
}
|
|
333
|
+
writeLine();
|
|
334
|
+
}
|
|
335
|
+
if (onTrack.length > 0) {
|
|
336
|
+
writeLine(` ${colors.yellow}${bold}On Track${RESET}`);
|
|
337
|
+
for (const item of onTrack) {
|
|
338
|
+
writeLine(` ${item.insight}`);
|
|
339
|
+
}
|
|
340
|
+
writeLine();
|
|
341
|
+
}
|
|
342
|
+
if (achieved.length > 0) {
|
|
343
|
+
writeLine(` ${colors.green}${bold}Target Achieved${RESET}`);
|
|
344
|
+
for (const item of achieved) {
|
|
345
|
+
writeLine(` ${item.insight}`);
|
|
346
|
+
}
|
|
347
|
+
writeLine();
|
|
348
|
+
}
|
|
349
|
+
writeLine(` ${colors.dim}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${RESET}`);
|
|
350
|
+
writeLine(` ${colors.red}${needsAttention.length}${RESET} needs attention ${colors.yellow}${onTrack.length}${RESET} on track ${colors.green}${achieved.length}${RESET} achieved`);
|
|
351
|
+
writeLine();
|
|
352
|
+
}
|
|
353
|
+
async function kpiListCommand(options = {}) {
|
|
354
|
+
await track(Events.CLI_KPI_LIST, {});
|
|
355
|
+
const squadsDir = findSquadsDir();
|
|
356
|
+
if (!squadsDir) {
|
|
357
|
+
writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const squads = listSquads(squadsDir);
|
|
361
|
+
const allKpis = [];
|
|
362
|
+
for (const name of squads) {
|
|
363
|
+
const squad = loadSquad(name);
|
|
364
|
+
if (!squad) continue;
|
|
365
|
+
const definitions = parseKpiDefinitions(squad.frontmatter);
|
|
366
|
+
if (definitions.length > 0) {
|
|
367
|
+
allKpis.push({ squad: name, kpis: definitions });
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (options.json) {
|
|
371
|
+
console.log(JSON.stringify(allKpis, null, 2));
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
writeLine();
|
|
375
|
+
writeLine(` ${gradient("squads")} ${colors.dim}kpi list${RESET}`);
|
|
376
|
+
writeLine();
|
|
377
|
+
if (allKpis.length === 0) {
|
|
378
|
+
writeLine(` ${colors.dim}No KPIs defined in any squad${RESET}`);
|
|
379
|
+
writeLine();
|
|
380
|
+
writeLine(` ${colors.dim}Define KPIs in SQUAD.md frontmatter:${RESET}`);
|
|
381
|
+
writeLine(` ${colors.dim}---${RESET}`);
|
|
382
|
+
writeLine(` ${colors.dim}kpis:${RESET}`);
|
|
383
|
+
writeLine(` ${colors.dim} - name: "metric_name"${RESET}`);
|
|
384
|
+
writeLine(` ${colors.dim} target: 100${RESET}`);
|
|
385
|
+
writeLine(` ${colors.dim} unit: "items"${RESET}`);
|
|
386
|
+
writeLine(` ${colors.dim} period: weekly${RESET}`);
|
|
387
|
+
writeLine(` ${colors.dim}---${RESET}`);
|
|
388
|
+
writeLine();
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
for (const { squad, kpis } of allKpis) {
|
|
392
|
+
writeLine(` ${colors.cyan}${squad}${RESET}`);
|
|
393
|
+
for (const kpi of kpis) {
|
|
394
|
+
const periodIcon = kpi.period === "daily" ? "\u{1F4C5}" : kpi.period === "weekly" ? "\u{1F4C6}" : "\u{1F5D3}\uFE0F";
|
|
395
|
+
writeLine(` ${periodIcon} ${bold}${kpi.name}${RESET}: ${kpi.target} ${kpi.unit}/${kpi.period}`);
|
|
396
|
+
if (kpi.description) {
|
|
397
|
+
writeLine(` ${colors.dim}${kpi.description}${RESET}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
writeLine();
|
|
401
|
+
}
|
|
402
|
+
const total = allKpis.reduce((sum, s) => sum + s.kpis.length, 0);
|
|
403
|
+
writeLine(` ${colors.dim}${total} KPIs across ${allKpis.length} squads${RESET}`);
|
|
404
|
+
writeLine();
|
|
405
|
+
}
|
|
406
|
+
export {
|
|
407
|
+
kpiInsightsCommand,
|
|
408
|
+
kpiListCommand,
|
|
409
|
+
kpiRecordCommand,
|
|
410
|
+
kpiShowCommand,
|
|
411
|
+
kpiTrendCommand
|
|
412
|
+
};
|
|
413
|
+
//# sourceMappingURL=kpi-2SQ2WCVT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/kpi.ts","../src/commands/kpi.ts"],"sourcesContent":["/**\n * KPI Tracking Library\n *\n * Handles KPI definitions, recording values, and generating insights.\n * KPIs are defined in SQUAD.md frontmatter and values stored in memory files.\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { findSquadsDir } from './squad-parser.js';\n\n/**\n * KPI definition from SQUAD.md frontmatter\n */\nexport interface KpiDefinition {\n name: string;\n target: number;\n unit: string;\n period: 'daily' | 'weekly' | 'monthly';\n source?: 'manual' | 'postgres' | 'github' | 'api';\n description?: string;\n}\n\n/**\n * Recorded KPI value\n */\nexport interface KpiValue {\n timestamp: string; // ISO date\n value: number;\n note?: string;\n}\n\n/**\n * KPI with current state and history\n */\nexport interface Kpi extends KpiDefinition {\n current?: number;\n lastUpdated?: string;\n trend?: 'up' | 'down' | 'flat';\n percentOfTarget?: number;\n history: KpiValue[];\n}\n\n/**\n * KPI storage file structure\n */\ninterface KpiStore {\n squadName: string;\n kpis: Record<string, KpiValue[]>;\n updatedAt: string;\n}\n\n/**\n * Get path to KPI store file for a squad\n */\nexport function getKpiStorePath(squadName: string): string {\n const squadsDir = findSquadsDir();\n if (!squadsDir) {\n throw new Error('No .agents/squads directory found');\n }\n return join(dirname(squadsDir), 'memory', squadName, 'kpis.json');\n}\n\n/**\n * Load KPI store for a squad\n */\nexport function loadKpiStore(squadName: string): KpiStore {\n const path = getKpiStorePath(squadName);\n\n if (!existsSync(path)) {\n return {\n squadName,\n kpis: {},\n updatedAt: new Date().toISOString(),\n };\n }\n\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as KpiStore;\n } catch {\n return {\n squadName,\n kpis: {},\n updatedAt: new Date().toISOString(),\n };\n }\n}\n\n/**\n * Save KPI store for a squad\n */\nexport function saveKpiStore(store: KpiStore): void {\n const path = getKpiStorePath(store.squadName);\n const dir = dirname(path);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n store.updatedAt = new Date().toISOString();\n writeFileSync(path, JSON.stringify(store, null, 2));\n}\n\n/**\n * Record a KPI value\n */\nexport function recordKpiValue(\n squadName: string,\n kpiName: string,\n value: number,\n note?: string\n): KpiValue {\n const store = loadKpiStore(squadName);\n\n if (!store.kpis[kpiName]) {\n store.kpis[kpiName] = [];\n }\n\n const record: KpiValue = {\n timestamp: new Date().toISOString(),\n value,\n note,\n };\n\n store.kpis[kpiName].push(record);\n saveKpiStore(store);\n\n return record;\n}\n\n/**\n * Get KPI history for a specific metric\n */\nexport function getKpiHistory(\n squadName: string,\n kpiName: string,\n limit?: number\n): KpiValue[] {\n const store = loadKpiStore(squadName);\n const history = store.kpis[kpiName] || [];\n\n if (limit) {\n return history.slice(-limit);\n }\n return history;\n}\n\n/**\n * Calculate trend from history\n */\nexport function calculateTrend(history: KpiValue[]): 'up' | 'down' | 'flat' {\n if (history.length < 2) return 'flat';\n\n const recent = history.slice(-5);\n if (recent.length < 2) return 'flat';\n\n const first = recent[0].value;\n const last = recent[recent.length - 1].value;\n const change = ((last - first) / first) * 100;\n\n if (change > 5) return 'up';\n if (change < -5) return 'down';\n return 'flat';\n}\n\n/**\n * Get current KPI state with trend\n */\nexport function getKpiState(\n definition: KpiDefinition,\n squadName: string\n): Kpi {\n const history = getKpiHistory(squadName, definition.name);\n const lastValue = history.length > 0 ? history[history.length - 1] : undefined;\n\n return {\n ...definition,\n current: lastValue?.value,\n lastUpdated: lastValue?.timestamp,\n trend: calculateTrend(history),\n percentOfTarget: lastValue ? Math.round((lastValue.value / definition.target) * 100) : undefined,\n history,\n };\n}\n\n/**\n * Generate insight from KPI state\n */\nexport function generateKpiInsight(kpi: Kpi): string | null {\n if (!kpi.current || !kpi.percentOfTarget) {\n return null;\n }\n\n const trendEmoji = kpi.trend === 'up' ? '📈' : kpi.trend === 'down' ? '📉' : '➡️';\n const statusEmoji = kpi.percentOfTarget >= 100 ? '✅' : kpi.percentOfTarget >= 70 ? '🟡' : '🔴';\n\n if (kpi.percentOfTarget >= 100) {\n return `${statusEmoji} ${kpi.name}: Target achieved! ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;\n } else if (kpi.percentOfTarget >= 70) {\n return `${statusEmoji} ${kpi.name}: On track - ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;\n } else {\n return `${statusEmoji} ${kpi.name}: Needs attention - ${kpi.current}/${kpi.target} ${kpi.unit} (${kpi.percentOfTarget}%) ${trendEmoji}`;\n }\n}\n\n/**\n * Get values for a specific period\n */\nexport function getValuesForPeriod(\n history: KpiValue[],\n period: 'daily' | 'weekly' | 'monthly',\n count: number = 7\n): KpiValue[] {\n const now = new Date();\n const cutoff = new Date();\n\n switch (period) {\n case 'daily':\n cutoff.setDate(now.getDate() - count);\n break;\n case 'weekly':\n cutoff.setDate(now.getDate() - count * 7);\n break;\n case 'monthly':\n cutoff.setMonth(now.getMonth() - count);\n break;\n }\n\n return history.filter(v => new Date(v.timestamp) >= cutoff);\n}\n\n/**\n * Aggregate values by period\n */\nexport function aggregateByPeriod(\n history: KpiValue[],\n period: 'daily' | 'weekly' | 'monthly'\n): Map<string, number> {\n const aggregated = new Map<string, number[]>();\n\n for (const value of history) {\n const date = new Date(value.timestamp);\n let key: string;\n\n switch (period) {\n case 'daily':\n key = date.toISOString().split('T')[0];\n break;\n case 'weekly': {\n const weekStart = new Date(date);\n weekStart.setDate(date.getDate() - date.getDay());\n key = weekStart.toISOString().split('T')[0];\n break;\n }\n case 'monthly':\n key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n break;\n }\n\n if (!aggregated.has(key)) {\n aggregated.set(key, []);\n }\n aggregated.get(key)!.push(value.value);\n }\n\n // Sum values for each period\n const result = new Map<string, number>();\n for (const [key, values] of aggregated) {\n result.set(key, values.reduce((a, b) => a + b, 0));\n }\n\n return result;\n}\n\n/**\n * Parse KPI definitions from SQUAD.md frontmatter\n */\nexport function parseKpiDefinitions(frontmatter?: Record<string, unknown>): KpiDefinition[] {\n if (!frontmatter) return [];\n const kpis = frontmatter.kpis as Array<Record<string, unknown>> | undefined;\n if (!kpis || !Array.isArray(kpis)) {\n return [];\n }\n\n return kpis.map(k => ({\n name: String(k.name || ''),\n target: Number(k.target || 0),\n unit: String(k.unit || ''),\n period: (k.period as KpiDefinition['period']) || 'weekly',\n source: (k.source as KpiDefinition['source']) || 'manual',\n description: k.description ? String(k.description) : undefined,\n })).filter(k => k.name && k.target > 0);\n}\n","/**\n * KPI Command\n *\n * Track and analyze squad KPIs defined in SQUAD.md frontmatter.\n * Commands: define, record, show, trend, insights\n */\n\nimport {\n loadSquad,\n findSquadsDir,\n listSquads,\n} from '../lib/squad-parser.js';\nimport {\n KpiDefinition,\n Kpi,\n recordKpiValue,\n getKpiState,\n generateKpiInsight,\n parseKpiDefinitions,\n getValuesForPeriod,\n} from '../lib/kpi.js';\nimport {\n colors,\n bold,\n RESET,\n gradient,\n icons,\n writeLine,\n} from '../lib/terminal.js';\nimport { track, Events } from '../lib/telemetry.js';\n\n/**\n * Show KPI status for a squad\n */\nexport async function kpiShowCommand(\n squadName: string,\n options: { json?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_KPI_SHOW, { squad: squadName });\n\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n const definitions = parseKpiDefinitions(squad.frontmatter);\n\n if (definitions.length === 0) {\n writeLine();\n writeLine(` ${colors.yellow}No KPIs defined for ${squadName}${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}Define KPIs in SQUAD.md frontmatter:${RESET}`);\n writeLine(` ${colors.dim}---${RESET}`);\n writeLine(` ${colors.dim}kpis:${RESET}`);\n writeLine(` ${colors.dim} - name: \"leads_generated\"${RESET}`);\n writeLine(` ${colors.dim} target: 10${RESET}`);\n writeLine(` ${colors.dim} unit: \"leads\"${RESET}`);\n writeLine(` ${colors.dim} period: weekly${RESET}`);\n writeLine(` ${colors.dim}---${RESET}`);\n writeLine();\n return;\n }\n\n const kpis: Kpi[] = definitions.map(def => getKpiState(def, squadName));\n\n if (options.json) {\n console.log(JSON.stringify(kpis, null, 2));\n return;\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}kpi show${RESET} ${colors.cyan}${squadName}${RESET}`);\n writeLine();\n\n for (const kpi of kpis) {\n const insight = generateKpiInsight(kpi);\n\n if (insight) {\n writeLine(` ${insight}`);\n } else {\n writeLine(` ${colors.dim}○${RESET} ${kpi.name}: ${colors.dim}No data recorded${RESET}`);\n }\n\n if (kpi.description) {\n writeLine(` ${colors.dim}${kpi.description}${RESET}`);\n }\n }\n\n writeLine();\n}\n\n/**\n * Record a KPI value\n */\nexport async function kpiRecordCommand(\n squadName: string,\n kpiName: string,\n value: string,\n options: { note?: string; json?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_KPI_RECORD, { squad: squadName, kpi: kpiName });\n\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n const definitions = parseKpiDefinitions(squad.frontmatter);\n const definition = definitions.find(d => d.name === kpiName);\n\n if (!definition) {\n writeLine(` ${colors.red}KPI \"${kpiName}\" not defined in ${squadName}${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}Available KPIs:${RESET}`);\n for (const def of definitions) {\n writeLine(` ${colors.dim} - ${def.name}${RESET}`);\n }\n return;\n }\n\n const numValue = parseFloat(value);\n if (isNaN(numValue)) {\n writeLine(` ${colors.red}Invalid value: ${value}${RESET}`);\n return;\n }\n\n const record = recordKpiValue(squadName, kpiName, numValue, options.note);\n\n if (options.json) {\n console.log(JSON.stringify(record, null, 2));\n return;\n }\n\n writeLine();\n writeLine(` ${icons.success} Recorded ${colors.cyan}${kpiName}${RESET}: ${bold}${numValue}${RESET} ${definition.unit}`);\n if (options.note) {\n writeLine(` ${colors.dim}Note: ${options.note}${RESET}`);\n }\n\n // Show progress toward target\n const percentOfTarget = Math.round((numValue / definition.target) * 100);\n const statusEmoji = percentOfTarget >= 100 ? '✅' : percentOfTarget >= 70 ? '🟡' : '🔴';\n writeLine(` ${statusEmoji} ${percentOfTarget}% of target (${definition.target} ${definition.unit}/${definition.period})`);\n writeLine();\n}\n\n/**\n * Show KPI trend over time\n */\nexport async function kpiTrendCommand(\n squadName: string,\n kpiName: string,\n options: { periods?: string; json?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_KPI_TREND, { squad: squadName, kpi: kpiName });\n\n const squad = loadSquad(squadName);\n if (!squad) {\n writeLine(` ${colors.red}Squad \"${squadName}\" not found${RESET}`);\n return;\n }\n\n const definitions = parseKpiDefinitions(squad.frontmatter);\n const definition = definitions.find(d => d.name === kpiName);\n\n if (!definition) {\n writeLine(` ${colors.red}KPI \"${kpiName}\" not defined in ${squadName}${RESET}`);\n return;\n }\n\n const kpi = getKpiState(definition, squadName);\n const periods = parseInt(options.periods || '7', 10);\n const values = getValuesForPeriod(kpi.history, definition.period, periods);\n\n if (options.json) {\n console.log(JSON.stringify({\n kpi: kpiName,\n definition,\n trend: kpi.trend,\n values,\n }, null, 2));\n return;\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}kpi trend${RESET} ${colors.cyan}${squadName}/${kpiName}${RESET}`);\n writeLine();\n\n const trendEmoji = kpi.trend === 'up' ? '📈' : kpi.trend === 'down' ? '📉' : '➡️';\n writeLine(` ${bold}${kpiName}${RESET} ${trendEmoji} ${kpi.trend}`);\n writeLine(` ${colors.dim}Target: ${definition.target} ${definition.unit}/${definition.period}${RESET}`);\n writeLine();\n\n if (values.length === 0) {\n writeLine(` ${colors.dim}No data for the last ${periods} ${definition.period} periods${RESET}`);\n } else {\n // Simple ASCII chart\n const maxValue = Math.max(...values.map(v => v.value), definition.target);\n\n for (const v of values.slice(-10)) {\n const barLength = Math.round((v.value / maxValue) * 30);\n const bar = '█'.repeat(barLength);\n const targetMark = v.value >= definition.target ? colors.green : colors.red;\n\n const date = new Date(v.timestamp).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n writeLine(` ${colors.dim}${date}${RESET} ${targetMark}${bar}${RESET} ${v.value}`);\n }\n\n writeLine();\n writeLine(` ${colors.dim}Target line: ${definition.target} ${'─'.repeat(20)}${RESET}`);\n }\n\n writeLine();\n}\n\n/**\n * Generate insights for all KPIs\n */\nexport async function kpiInsightsCommand(\n squadName?: string,\n options: { json?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_KPI_INSIGHTS, { squad: squadName || 'all' });\n\n const squadsDir = findSquadsDir();\n if (!squadsDir) {\n writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);\n return;\n }\n\n const squadsToCheck = squadName ? [squadName] : listSquads(squadsDir);\n const allInsights: { squad: string; kpi: string; insight: string; percentOfTarget: number }[] = [];\n\n for (const name of squadsToCheck) {\n const squad = loadSquad(name);\n if (!squad) continue;\n\n const definitions = parseKpiDefinitions(squad.frontmatter);\n\n for (const def of definitions) {\n const kpi = getKpiState(def, name);\n const insight = generateKpiInsight(kpi);\n\n if (insight && kpi.percentOfTarget !== undefined) {\n allInsights.push({\n squad: name,\n kpi: def.name,\n insight,\n percentOfTarget: kpi.percentOfTarget,\n });\n }\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify(allInsights, null, 2));\n return;\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}kpi insights${RESET}`);\n writeLine();\n\n if (allInsights.length === 0) {\n writeLine(` ${colors.dim}No KPI data recorded yet${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}Record KPI values:${RESET}`);\n writeLine(` ${colors.dim}$ squads kpi record <squad> <kpi> <value>${RESET}`);\n writeLine();\n return;\n }\n\n // Sort by percentage (lowest first - needs attention)\n allInsights.sort((a, b) => a.percentOfTarget - b.percentOfTarget);\n\n // Group by status\n const needsAttention = allInsights.filter(i => i.percentOfTarget < 70);\n const onTrack = allInsights.filter(i => i.percentOfTarget >= 70 && i.percentOfTarget < 100);\n const achieved = allInsights.filter(i => i.percentOfTarget >= 100);\n\n if (needsAttention.length > 0) {\n writeLine(` ${colors.red}${bold}Needs Attention${RESET}`);\n for (const item of needsAttention) {\n writeLine(` ${item.insight}`);\n writeLine(` ${colors.dim}Squad: ${item.squad}${RESET}`);\n }\n writeLine();\n }\n\n if (onTrack.length > 0) {\n writeLine(` ${colors.yellow}${bold}On Track${RESET}`);\n for (const item of onTrack) {\n writeLine(` ${item.insight}`);\n }\n writeLine();\n }\n\n if (achieved.length > 0) {\n writeLine(` ${colors.green}${bold}Target Achieved${RESET}`);\n for (const item of achieved) {\n writeLine(` ${item.insight}`);\n }\n writeLine();\n }\n\n // Summary\n writeLine(` ${colors.dim}─────────────────────────────────────${RESET}`);\n writeLine(` ${colors.red}${needsAttention.length}${RESET} needs attention ${colors.yellow}${onTrack.length}${RESET} on track ${colors.green}${achieved.length}${RESET} achieved`);\n writeLine();\n}\n\n/**\n * List all KPIs across squads\n */\nexport async function kpiListCommand(\n options: { json?: boolean } = {}\n): Promise<void> {\n await track(Events.CLI_KPI_LIST, {});\n\n const squadsDir = findSquadsDir();\n if (!squadsDir) {\n writeLine(` ${colors.red}No .agents/squads directory found${RESET}`);\n return;\n }\n\n const squads = listSquads(squadsDir);\n const allKpis: { squad: string; kpis: KpiDefinition[] }[] = [];\n\n for (const name of squads) {\n const squad = loadSquad(name);\n if (!squad) continue;\n\n const definitions = parseKpiDefinitions(squad.frontmatter);\n if (definitions.length > 0) {\n allKpis.push({ squad: name, kpis: definitions });\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify(allKpis, null, 2));\n return;\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}kpi list${RESET}`);\n writeLine();\n\n if (allKpis.length === 0) {\n writeLine(` ${colors.dim}No KPIs defined in any squad${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}Define KPIs in SQUAD.md frontmatter:${RESET}`);\n writeLine(` ${colors.dim}---${RESET}`);\n writeLine(` ${colors.dim}kpis:${RESET}`);\n writeLine(` ${colors.dim} - name: \"metric_name\"${RESET}`);\n writeLine(` ${colors.dim} target: 100${RESET}`);\n writeLine(` ${colors.dim} unit: \"items\"${RESET}`);\n writeLine(` ${colors.dim} period: weekly${RESET}`);\n writeLine(` ${colors.dim}---${RESET}`);\n writeLine();\n return;\n }\n\n for (const { squad, kpis } of allKpis) {\n writeLine(` ${colors.cyan}${squad}${RESET}`);\n\n for (const kpi of kpis) {\n const periodIcon = kpi.period === 'daily' ? '📅' : kpi.period === 'weekly' ? '📆' : '🗓️';\n writeLine(` ${periodIcon} ${bold}${kpi.name}${RESET}: ${kpi.target} ${kpi.unit}/${kpi.period}`);\n if (kpi.description) {\n writeLine(` ${colors.dim}${kpi.description}${RESET}`);\n }\n }\n writeLine();\n }\n\n const total = allKpis.reduce((sum, s) => sum + s.kpis.length, 0);\n writeLine(` ${colors.dim}${total} KPIs across ${allKpis.length} squads${RESET}`);\n writeLine();\n}\n"],"mappings":"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","names":[]}
|