@aida-dev/cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @aida/cli
1
+ # @aida-dev/cli
2
2
 
3
3
  Command-line interface for AIDA (AI Development Accounting) metrics.
4
4
 
@@ -12,6 +12,7 @@ pnpm build
12
12
  ## Usage
13
13
 
14
14
  ### Basic workflow
15
+
15
16
  ```bash
16
17
  # Collect commits from last 90 days
17
18
  aida collect --since 90d
@@ -26,9 +27,11 @@ aida report --format both
26
27
  ### Commands
27
28
 
28
29
  #### `aida collect`
30
+
29
31
  Collect commits and generate `commit-stream.json`
30
32
 
31
33
  Options:
34
+
32
35
  - `--repo <path>` - Repository path (default: current directory)
33
36
  - `--since <date>` - Start date (ISO or relative like 90d)
34
37
  - `--until <date>` - End date (ISO or relative)
@@ -38,17 +41,20 @@ Options:
38
41
  - `--verbose` - Verbose logging
39
42
 
40
43
  #### `aida analyze`
44
+
41
45
  Analyze commit stream and generate `metrics.json`
42
46
 
43
47
  #### `aida report`
48
+
44
49
  Generate human-readable reports from metrics
45
50
 
46
51
  Options:
52
+
47
53
  - `--format <format>` - Output format: json, md, both (default: both)
48
54
 
49
55
  ## Output Files
50
56
 
51
57
  - `commit-stream.json` - Normalized commit data with AI tagging
52
- - `metrics.json` - Calculated merge ratio and persistence metrics
58
+ - `metrics.json` - Calculated merge ratio and persistence metrics
53
59
  - `report.json` - JSON report (same as metrics.json)
54
60
  - `report.md` - Human-readable Markdown report
package/dist/index.js CHANGED
@@ -23,9 +23,14 @@ var CLIConfig = z.object({
23
23
 
24
24
  // src/commands/collect.ts
25
25
  function createCollectCommand() {
26
- return new Command("collect").description("Collect commits and generate commit-stream.json").option("--repo <path>", "Repository path", process.cwd()).option("--since <date>", "Start date (ISO or relative like 90d)").option("--until <date>", "End date (ISO or relative)").option("--ai-pattern <pattern>", "AI detection pattern (repeatable)", (value, previous) => {
27
- return previous ? [...previous, value] : [value];
28
- }, []).option("--default-branch <name>", "Default branch name").option("--out-dir <path>", "Output directory", "./aida-output").option("--verbose", "Verbose logging", false).action(async (options) => {
26
+ return new Command("collect").description("Collect commits and generate commit-stream.json").option("--repo <path>", "Repository path", process.cwd()).option("--since <date>", "Start date (ISO or relative like 90d)").option("--until <date>", "End date (ISO or relative)").option(
27
+ "--ai-pattern <pattern>",
28
+ "AI detection pattern (repeatable)",
29
+ (value, previous) => {
30
+ return previous ? [...previous, value] : [value];
31
+ },
32
+ []
33
+ ).option("--default-branch <name>", "Default branch name").option("--out-dir <path>", "Output directory", "./aida-output").option("--verbose", "Verbose logging", false).action(async (options) => {
29
34
  const config = CLIConfig.parse(options);
30
35
  const logger = createLogger(config.verbose);
31
36
  try {
@@ -44,7 +49,9 @@ function createCollectCommand() {
44
49
  logger.info(`AI-tagged commits: ${commitStream.commits.filter((c) => c.tags.ai).length}`);
45
50
  logger.info(`Output written to: ${outputPath}`);
46
51
  } catch (error) {
47
- logger.error(`Collection failed: ${error instanceof Error ? error.message : String(error)}`);
52
+ logger.error(
53
+ `Collection failed: ${error instanceof Error ? error.message : String(error)}`
54
+ );
48
55
  process.exit(1);
49
56
  }
50
57
  });
@@ -130,7 +137,9 @@ function createReportCommand() {
130
137
  }
131
138
  logger.info("Report generation completed");
132
139
  } catch (error) {
133
- logger.error(`Report generation failed: ${error instanceof Error ? error.message : String(error)}`);
140
+ logger.error(
141
+ `Report generation failed: ${error instanceof Error ? error.message : String(error)}`
142
+ );
134
143
  process.exit(1);
135
144
  }
136
145
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/collect.ts","../src/schema/config.ts","../src/commands/analyze.ts","../src/commands/report.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { createCollectCommand } from './commands/collect.js';\nimport { createAnalyzeCommand } from './commands/analyze.js';\nimport { createReportCommand } from './commands/report.js';\n\nconst program = new Command();\n\nprogram\n .name('aida')\n .description('AIDA (AI Development Accounting) - Metrics for AI-assisted development')\n .version('0.0.0');\n\n// Add commands\nprogram.addCommand(createCollectCommand());\nprogram.addCommand(createAnalyzeCommand());\nprogram.addCommand(createReportCommand());\n\n// Global options\nprogram\n .option('--repo <path>', 'Repository path (default: current directory)')\n .option('--since <date>', 'Start date (ISO or relative like 90d)')\n .option('--until <date>', 'End date (ISO or relative)')\n .option('--ai-pattern <pattern>', 'AI detection pattern (repeatable)')\n .option('--default-branch <name>', 'Default branch name (auto-detect if omitted)')\n .option('--out-dir <path>', 'Output directory (default: ./aida-output)')\n .option('--format <format>', 'Output format: json, md, both (default: both)')\n .option('--verbose', 'Verbose logging');\n\nprogram.parse();\n","import { Command } from 'commander';\nimport { collectCommits, writeJSON, createLogger } from '@aida-dev/core';\nimport { join } from 'path';\nimport { CLIConfig } from '../schema/config.js';\n\nexport function createCollectCommand(): Command {\n return new Command('collect')\n .description('Collect commits and generate commit-stream.json')\n .option('--repo <path>', 'Repository path', process.cwd())\n .option('--since <date>', 'Start date (ISO or relative like 90d)')\n .option('--until <date>', 'End date (ISO or relative)')\n .option('--ai-pattern <pattern>', 'AI detection pattern (repeatable)', (value, previous) => {\n return previous ? [...previous, value] : [value];\n }, [])\n .option('--default-branch <name>', 'Default branch name')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n \n try {\n logger.info('Starting commit collection...');\n \n const commitStream = await collectCommits({\n repoPath: config.repo,\n since: config.since,\n until: config.until,\n aiPatterns: config.aiPatterns,\n defaultBranch: config.defaultBranch,\n logger,\n });\n \n const outputPath = join(config.outDir, 'commit-stream.json');\n await writeJSON(outputPath, commitStream);\n \n logger.info(`Collected ${commitStream.commits.length} commits`);\n logger.info(`AI-tagged commits: ${commitStream.commits.filter(c => c.tags.ai).length}`);\n logger.info(`Output written to: ${outputPath}`);\n } catch (error) {\n logger.error(`Collection failed: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n}\n","import { z } from \"zod\";\n\nexport const CLIConfig = z.object({\n repo: z.string().default(process.cwd()),\n since: z.string().optional(),\n until: z.string().optional(),\n aiPatterns: z.array(z.string()).default([]),\n defaultBranch: z.string().optional(),\n outDir: z.string().default('./aida-output'),\n format: z.enum(['json', 'md', 'both']).default('both'),\n verbose: z.boolean().default(false),\n});\n\nexport type CLIConfig = z.infer<typeof CLIConfig>;\n","import { Command } from 'commander';\nimport { readJSON, writeJSON, createLogger } from '@aida-dev/core';\nimport { calculateMetrics } from '@aida-dev/metrics';\nimport { join } from 'path';\nimport { CLIConfig } from '../schema/config.js';\n\nexport function createAnalyzeCommand(): Command {\n return new Command('analyze')\n .description('Analyze commit stream and generate metrics.json')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n \n try {\n logger.info('Starting metrics analysis...');\n \n const inputPath = join(config.outDir, 'commit-stream.json');\n const commitStream = await readJSON(inputPath);\n \n logger.info(`Analyzing ${commitStream.commits.length} commits`);\n \n const metrics = calculateMetrics(commitStream);\n \n const outputPath = join(config.outDir, 'metrics.json');\n await writeJSON(outputPath, metrics);\n \n logger.info(`Merge ratio: ${(metrics.mergeRatio.mergeRatio * 100).toFixed(1)}%`);\n logger.info(`Average persistence: ${metrics.persistence.avgDays} days`);\n logger.info(`Output written to: ${outputPath}`);\n } catch (error) {\n logger.error(`Analysis failed: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { readJSON, writeJSON, createLogger } from '@aida-dev/core';\nimport { Metrics } from '@aida-dev/metrics';\nimport { join } from 'path';\nimport { promises as fs } from 'fs';\nimport { CLIConfig } from '../schema/config.js';\n\nfunction generateMarkdownReport(metrics: Metrics): string {\n const mergeRatioPct = (metrics.mergeRatio.mergeRatio * 100).toFixed(1);\n \n return `# AIDA Report\n\n**Repo:** ${metrics.repoPath} \n**Default branch:** ${metrics.defaultBranch} \n**Window:** ${metrics.window.since || 'beginning'} → ${metrics.window.until || 'now'} \n**Generated:** ${metrics.generatedAt}\n\n## Merge Ratio\n- AI-tagged commits (total): ${metrics.mergeRatio.aiCommitsTotal}\n- AI-tagged commits merged: ${metrics.mergeRatio.aiCommitsMerged}\n- **Merge Ratio:** ${mergeRatioPct}%\n\n## Persistence (file-level proxy)\n- Commits considered: ${metrics.persistence.commitsConsidered}\n- Average days: ${metrics.persistence.avgDays}\n- Median days: ${metrics.persistence.medianDays}\n\n| 0–1d | 2–7d | 8–30d | 31–90d | 90d+ |\n|---:|---:|---:|---:|---:|\n| ${metrics.persistence.buckets.d0_1} | ${metrics.persistence.buckets.d2_7} | ${metrics.persistence.buckets.d8_30} | ${metrics.persistence.buckets.d31_90} | ${metrics.persistence.buckets.d90_plus} |\n\n### Caveats\n${metrics.caveats.map(caveat => `- ${caveat}`).join('\\n')}\n`;\n}\n\nexport function createReportCommand(): Command {\n return new Command('report')\n .description('Generate report from metrics.json')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--format <format>', 'Output format: json, md, both', 'both')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n \n try {\n logger.info('Generating report...');\n \n const inputPath = join(config.outDir, 'metrics.json');\n const metrics: Metrics = await readJSON(inputPath);\n \n if (config.format === 'json' || config.format === 'both') {\n const jsonPath = join(config.outDir, 'report.json');\n await writeJSON(jsonPath, metrics);\n logger.info(`JSON report written to: ${jsonPath}`);\n }\n \n if (config.format === 'md' || config.format === 'both') {\n const markdown = generateMarkdownReport(metrics);\n const mdPath = join(config.outDir, 'report.md');\n await fs.writeFile(mdPath, markdown, 'utf-8');\n logger.info(`Markdown report written to: ${mdPath}`);\n }\n \n logger.info('Report generation completed');\n } catch (error) {\n logger.error(`Report generation failed: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["Command","Command","writeJSON","createLogger","join","Command","createLogger","join","writeJSON","Command","readJSON","writeJSON","createLogger","join","Command","createLogger","join","readJSON","writeJSON","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/collect.ts","../src/schema/config.ts","../src/commands/analyze.ts","../src/commands/report.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { createCollectCommand } from './commands/collect.js';\nimport { createAnalyzeCommand } from './commands/analyze.js';\nimport { createReportCommand } from './commands/report.js';\n\nconst program = new Command();\n\nprogram\n .name('aida')\n .description('AIDA (AI Development Accounting) - Metrics for AI-assisted development')\n .version('0.0.0');\n\n// Add commands\nprogram.addCommand(createCollectCommand());\nprogram.addCommand(createAnalyzeCommand());\nprogram.addCommand(createReportCommand());\n\n// Global options\nprogram\n .option('--repo <path>', 'Repository path (default: current directory)')\n .option('--since <date>', 'Start date (ISO or relative like 90d)')\n .option('--until <date>', 'End date (ISO or relative)')\n .option('--ai-pattern <pattern>', 'AI detection pattern (repeatable)')\n .option('--default-branch <name>', 'Default branch name (auto-detect if omitted)')\n .option('--out-dir <path>', 'Output directory (default: ./aida-output)')\n .option('--format <format>', 'Output format: json, md, both (default: both)')\n .option('--verbose', 'Verbose logging');\n\nprogram.parse();\n","import { Command } from 'commander';\nimport { collectCommits, writeJSON, createLogger } from '@aida-dev/core';\nimport { join } from 'path';\nimport { CLIConfig } from '../schema/config.js';\n\nexport function createCollectCommand(): Command {\n return new Command('collect')\n .description('Collect commits and generate commit-stream.json')\n .option('--repo <path>', 'Repository path', process.cwd())\n .option('--since <date>', 'Start date (ISO or relative like 90d)')\n .option('--until <date>', 'End date (ISO or relative)')\n .option(\n '--ai-pattern <pattern>',\n 'AI detection pattern (repeatable)',\n (value, previous) => {\n return previous ? [...previous, value] : [value];\n },\n []\n )\n .option('--default-branch <name>', 'Default branch name')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n\n try {\n logger.info('Starting commit collection...');\n\n const commitStream = await collectCommits({\n repoPath: config.repo,\n since: config.since,\n until: config.until,\n aiPatterns: config.aiPatterns,\n defaultBranch: config.defaultBranch,\n logger,\n });\n\n const outputPath = join(config.outDir, 'commit-stream.json');\n await writeJSON(outputPath, commitStream);\n\n logger.info(`Collected ${commitStream.commits.length} commits`);\n logger.info(`AI-tagged commits: ${commitStream.commits.filter((c) => c.tags.ai).length}`);\n logger.info(`Output written to: ${outputPath}`);\n } catch (error) {\n logger.error(\n `Collection failed: ${error instanceof Error ? error.message : String(error)}`\n );\n process.exit(1);\n }\n });\n}\n","import { z } from 'zod';\n\nexport const CLIConfig = z.object({\n repo: z.string().default(process.cwd()),\n since: z.string().optional(),\n until: z.string().optional(),\n aiPatterns: z.array(z.string()).default([]),\n defaultBranch: z.string().optional(),\n outDir: z.string().default('./aida-output'),\n format: z.enum(['json', 'md', 'both']).default('both'),\n verbose: z.boolean().default(false),\n});\n\nexport type CLIConfig = z.infer<typeof CLIConfig>;\n","import { Command } from 'commander';\nimport { readJSON, writeJSON, createLogger } from '@aida-dev/core';\nimport { calculateMetrics } from '@aida-dev/metrics';\nimport { join } from 'path';\nimport { CLIConfig } from '../schema/config.js';\n\nexport function createAnalyzeCommand(): Command {\n return new Command('analyze')\n .description('Analyze commit stream and generate metrics.json')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n\n try {\n logger.info('Starting metrics analysis...');\n\n const inputPath = join(config.outDir, 'commit-stream.json');\n const commitStream = await readJSON(inputPath);\n\n logger.info(`Analyzing ${commitStream.commits.length} commits`);\n\n const metrics = calculateMetrics(commitStream);\n\n const outputPath = join(config.outDir, 'metrics.json');\n await writeJSON(outputPath, metrics);\n\n logger.info(`Merge ratio: ${(metrics.mergeRatio.mergeRatio * 100).toFixed(1)}%`);\n logger.info(`Average persistence: ${metrics.persistence.avgDays} days`);\n logger.info(`Output written to: ${outputPath}`);\n } catch (error) {\n logger.error(`Analysis failed: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { readJSON, writeJSON, createLogger } from '@aida-dev/core';\nimport { Metrics } from '@aida-dev/metrics';\nimport { join } from 'path';\nimport { promises as fs } from 'fs';\nimport { CLIConfig } from '../schema/config.js';\n\nfunction generateMarkdownReport(metrics: Metrics): string {\n const mergeRatioPct = (metrics.mergeRatio.mergeRatio * 100).toFixed(1);\n\n return `# AIDA Report\n\n**Repo:** ${metrics.repoPath} \n**Default branch:** ${metrics.defaultBranch} \n**Window:** ${metrics.window.since || 'beginning'} → ${metrics.window.until || 'now'} \n**Generated:** ${metrics.generatedAt}\n\n## Merge Ratio\n- AI-tagged commits (total): ${metrics.mergeRatio.aiCommitsTotal}\n- AI-tagged commits merged: ${metrics.mergeRatio.aiCommitsMerged}\n- **Merge Ratio:** ${mergeRatioPct}%\n\n## Persistence (file-level proxy)\n- Commits considered: ${metrics.persistence.commitsConsidered}\n- Average days: ${metrics.persistence.avgDays}\n- Median days: ${metrics.persistence.medianDays}\n\n| 0–1d | 2–7d | 8–30d | 31–90d | 90d+ |\n|---:|---:|---:|---:|---:|\n| ${metrics.persistence.buckets.d0_1} | ${metrics.persistence.buckets.d2_7} | ${metrics.persistence.buckets.d8_30} | ${metrics.persistence.buckets.d31_90} | ${metrics.persistence.buckets.d90_plus} |\n\n### Caveats\n${metrics.caveats.map((caveat) => `- ${caveat}`).join('\\n')}\n`;\n}\n\nexport function createReportCommand(): Command {\n return new Command('report')\n .description('Generate report from metrics.json')\n .option('--out-dir <path>', 'Output directory', './aida-output')\n .option('--format <format>', 'Output format: json, md, both', 'both')\n .option('--verbose', 'Verbose logging', false)\n .action(async (options) => {\n const config = CLIConfig.parse(options);\n const logger = createLogger(config.verbose);\n\n try {\n logger.info('Generating report...');\n\n const inputPath = join(config.outDir, 'metrics.json');\n const metrics: Metrics = await readJSON(inputPath);\n\n if (config.format === 'json' || config.format === 'both') {\n const jsonPath = join(config.outDir, 'report.json');\n await writeJSON(jsonPath, metrics);\n logger.info(`JSON report written to: ${jsonPath}`);\n }\n\n if (config.format === 'md' || config.format === 'both') {\n const markdown = generateMarkdownReport(metrics);\n const mdPath = join(config.outDir, 'report.md');\n await fs.writeFile(mdPath, markdown, 'utf-8');\n logger.info(`Markdown report written to: ${mdPath}`);\n }\n\n logger.info('Report generation completed');\n } catch (error) {\n logger.error(\n `Report generation failed: ${error instanceof Error ? error.message : String(error)}`\n );\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["Command","Command","writeJSON","createLogger","join","Command","createLogger","join","writeJSON","Command","readJSON","writeJSON","createLogger","join","Command","createLogger","join","readJSON","writeJSON","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aida-dev/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -17,8 +17,8 @@
17
17
  "dependencies": {
18
18
  "commander": "^11.1.0",
19
19
  "zod": "^3.22.4",
20
- "@aida-dev/core": "0.2.0",
21
- "@aida-dev/metrics": "0.1.0"
20
+ "@aida-dev/core": "0.2.1",
21
+ "@aida-dev/metrics": "0.1.1"
22
22
  },
23
23
  "devDependencies": {
24
24
  "tsup": "^8.0.0",
@@ -32,7 +32,7 @@
32
32
  "build": "tsup src/index.ts --dts",
33
33
  "dev": "tsup src/index.ts --dts --watch",
34
34
  "test": "vitest run",
35
- "lint": "eslint . --ext .ts",
35
+ "lint": "eslint .",
36
36
  "format": "prettier -w ."
37
37
  }
38
38
  }