@girardelli/architect 2.1.0 → 4.0.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 +105 -116
- package/__test_agent_output__/INDEX.md +1 -0
- package/__test_agent_output__/agents/AGENT-ORCHESTRATOR.md +1 -0
- package/__test_agent_output__/agents/DATABASE-ENGINEER.md +174 -0
- package/__test_agent_output__/agents/QA-TEST-ENGINEER.md +138 -0
- package/__test_agent_output__/agents/SECURITY-AUDITOR.md +106 -0
- package/__test_agent_output__/agents/TECH-DEBT-CONTROLLER.md +104 -0
- package/__test_agent_output__/agents/TYPESCRIPT-BACKEND-DEVELOPER.md +135 -0
- package/__test_agent_output__/guards/CODE-REVIEW-CHECKLIST.md +95 -0
- package/__test_agent_output__/guards/PREFLIGHT.md +200 -0
- package/__test_agent_output__/guards/QUALITY-GATES.md +1 -0
- package/__test_agent_output__/rules/00-general.md +229 -0
- package/__test_agent_output__/rules/01-architecture.md +191 -0
- package/__test_agent_output__/rules/02-security.md +402 -0
- package/__test_agent_output__/rules/03-nestjs.md +124 -0
- package/__test_agent_output__/templates/ADR.md +95 -0
- package/__test_agent_output__/templates/BDD.md +58 -0
- package/__test_agent_output__/templates/C4.md +68 -0
- package/__test_agent_output__/templates/TDD.md +86 -0
- package/__test_agent_output__/templates/THREAT-MODEL.md +82 -0
- package/__test_agent_output__/workflows/fix-bug.md +228 -0
- package/__test_agent_output__/workflows/new-feature.md +311 -0
- package/__test_agent_output__/workflows/review.md +95 -0
- package/__test_context_7RvUrO/src/modules/empty/empty.ts +0 -0
- package/__test_context_Rf5fNJ/src/modules/mixed/mixed.ts +5 -0
- package/__test_context_WRCnYH/src/modules/test/test.ts +10 -0
- package/__test_context_YsnVS3/src/modules/test/test.ts +10 -0
- package/__test_context_w7XZeH/src/modules/mixed/mixed.ts +5 -0
- package/__test_context_y5noh6/src/modules/empty/empty.ts +0 -0
- package/__test_framework__24OjAu/package.json +1 -0
- package/__test_framework__3ZDZsx/pyproject.toml +8 -0
- package/__test_framework__4T54Jn/package.json +1 -0
- package/__test_framework__4tlXu9/pyproject.toml +8 -0
- package/__test_framework__6boWqQ/Pipfile +6 -0
- package/__test_framework__6gygMU/pom.xml +10 -0
- package/__test_framework__6kxj0N/go.mod +8 -0
- package/__test_framework__7CEoXw/pom.xml +10 -0
- package/__test_framework__85DDz0/Pipfile +6 -0
- package/__test_framework__9WrRIr/pom.xml +7 -0
- package/__test_framework__ANqGKl/Gemfile +5 -0
- package/__test_framework__BCXTEM/go.mod +3 -0
- package/__test_framework__BHiPNq/setup.py +2 -0
- package/__test_framework__BqkiKv/package.json +1 -0
- package/__test_framework__C5yd8X/Pipfile.lock +1 -0
- package/__test_framework__C5yd8X/requirements.txt +1 -0
- package/__test_framework__C87d3a/manage.py +1 -0
- package/__test_framework__C87d3a/requirements.txt +2 -0
- package/__test_framework__DXNwc5/build.gradle +7 -0
- package/__test_framework__GhHSt3/build.gradle.kts +4 -0
- package/__test_framework__GzklJP/Cargo.toml +7 -0
- package/__test_framework__H4hd13/go.mod +8 -0
- package/__test_framework__HKjOXO/composer.json +1 -0
- package/__test_framework__HaDN45/Gemfile +3 -0
- package/__test_framework__IBO7YG/pyproject.toml +9 -0
- package/__test_framework__JwSOyF/pyproject.toml +6 -0
- package/__test_framework__K6HrCr/build.gradle +2 -0
- package/__test_framework__KzRPlh/pubspec.yaml +9 -0
- package/__test_framework__L6uIym/pyproject.toml +6 -0
- package/__test_framework__LOdoGK/requirements.txt +4 -0
- package/__test_framework__LgHzss/package.json +1 -0
- package/__test_framework__M76M6q/Gemfile +5 -0
- package/__test_framework__Mr9vWW/composer.json +1 -0
- package/__test_framework__N03Gnv/package.json +1 -0
- package/__test_framework__Num4UE/requirements +1 -0
- package/__test_framework__OAGw3Y/build.gradle +7 -0
- package/__test_framework__OQc8yG/pubspec.yaml +9 -0
- package/__test_framework__OwKZcd/requirements.txt +3 -0
- package/__test_framework__P0gFv7/requirements +1 -0
- package/__test_framework__PN55Rq/package.json +1 -0
- package/__test_framework__PQiqX8/pubspec.yaml +3 -0
- package/__test_framework__RBHsg7/composer.json +1 -0
- package/__test_framework__RHxif4/Cargo.toml +7 -0
- package/__test_framework__T0v0p1/Cargo.toml +4 -0
- package/__test_framework__Tu0clt/Pipfile.lock +1 -0
- package/__test_framework__Tu0clt/requirements.txt +1 -0
- package/__test_framework__TwDj9P/Cargo.toml +4 -0
- package/__test_framework__VQJNC4/pom.xml +7 -0
- package/__test_framework__W6sm05/package.json +1 -0
- package/__test_framework__W7vBLy/pyproject.toml +4 -0
- package/__test_framework__WNJOWT/setup.py +2 -0
- package/__test_framework__WSJs7U/package.json +1 -0
- package/__test_framework__YQ5VpA/build.gradle.kts +4 -0
- package/__test_framework__ZNEUEs/package.json +1 -0
- package/__test_framework__Znt922/pom.xml +7 -0
- package/__test_framework__azyg0h/pom.xml +7 -0
- package/__test_framework__c6otLr/package.json +1 -0
- package/__test_framework__cl9S9G/build.gradle +2 -0
- package/__test_framework__eilvV4/composer.json +1 -0
- package/__test_framework__gQZxXO/manage.py +1 -0
- package/__test_framework__gQZxXO/requirements.txt +2 -0
- package/__test_framework__ghvl26/poetry.lock +1 -0
- package/__test_framework__ghvl26/pyproject.toml +2 -0
- package/__test_framework__hR7b9U/Makefile +11 -0
- package/__test_framework__iESVsi/composer.json +1 -0
- package/__test_framework__jm6TJy/package.json +1 -0
- package/__test_framework__kBUpjs/pyproject.toml +9 -0
- package/__test_framework__kqoZrw/requirements.txt +4 -0
- package/__test_framework__lWkoyO/pyproject.toml +4 -0
- package/__test_framework__mTKnUO/package.json +1 -0
- package/__test_framework__nCeZwe/Makefile +11 -0
- package/__test_framework__oljsU0/package.json +1 -0
- package/__test_framework__osRG4q/go.mod +3 -0
- package/__test_framework__pCHH4F/package.json +1 -0
- package/__test_framework__pExx6E/Gemfile +3 -0
- package/__test_framework__pyBoGd/pyproject.toml +5 -0
- package/__test_framework__qw16VQ/package.json +1 -0
- package/__test_framework__rRayrG/package.json +1 -0
- package/__test_framework__s82zO5/package.json +1 -0
- package/__test_framework__tp8MFK/pyproject.toml +5 -0
- package/__test_framework__w44k4w/composer.json +1 -0
- package/__test_framework__yefPZY/poetry.lock +1 -0
- package/__test_framework__yefPZY/pyproject.toml +2 -0
- package/__test_framework__zCiyDT/requirements.txt +3 -0
- package/__test_framework__zGZN3j/pubspec.yaml +3 -0
- package/__test_framework__zXpnxL/package.json +1 -0
- package/architect-run.sh +431 -0
- package/assets/banner-v3.html +561 -0
- package/dist/agent-generator/context-enricher.d.ts +58 -0
- package/dist/agent-generator/context-enricher.d.ts.map +1 -0
- package/dist/agent-generator/context-enricher.js +581 -0
- package/dist/agent-generator/context-enricher.js.map +1 -0
- package/dist/agent-generator/domain-inferrer.d.ts +52 -0
- package/dist/agent-generator/domain-inferrer.d.ts.map +1 -0
- package/dist/agent-generator/domain-inferrer.js +575 -0
- package/dist/agent-generator/domain-inferrer.js.map +1 -0
- package/dist/agent-generator/framework-detector.d.ts +40 -0
- package/dist/agent-generator/framework-detector.d.ts.map +1 -0
- package/dist/agent-generator/framework-detector.js +611 -0
- package/dist/agent-generator/framework-detector.js.map +1 -0
- package/dist/agent-generator/index.d.ts +33 -0
- package/dist/agent-generator/index.d.ts.map +1 -0
- package/dist/agent-generator/index.js +477 -0
- package/dist/agent-generator/index.js.map +1 -0
- package/dist/agent-generator/stack-detector.d.ts +12 -0
- package/dist/agent-generator/stack-detector.d.ts.map +1 -0
- package/dist/agent-generator/stack-detector.js +128 -0
- package/dist/agent-generator/stack-detector.js.map +1 -0
- package/dist/agent-generator/templates/core/agents.d.ts +17 -0
- package/dist/agent-generator/templates/core/agents.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/agents.js +1252 -0
- package/dist/agent-generator/templates/core/agents.js.map +1 -0
- package/dist/agent-generator/templates/core/architecture-rules.d.ts +7 -0
- package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/architecture-rules.js +274 -0
- package/dist/agent-generator/templates/core/architecture-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/general-rules.d.ts +8 -0
- package/dist/agent-generator/templates/core/general-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/general-rules.js +301 -0
- package/dist/agent-generator/templates/core/general-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/index-md.d.ts +7 -0
- package/dist/agent-generator/templates/core/index-md.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/index-md.js +246 -0
- package/dist/agent-generator/templates/core/index-md.js.map +1 -0
- package/dist/agent-generator/templates/core/orchestrator.d.ts +8 -0
- package/dist/agent-generator/templates/core/orchestrator.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/orchestrator.js +422 -0
- package/dist/agent-generator/templates/core/orchestrator.js.map +1 -0
- package/dist/agent-generator/templates/core/preflight.d.ts +8 -0
- package/dist/agent-generator/templates/core/preflight.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/preflight.js +213 -0
- package/dist/agent-generator/templates/core/preflight.js.map +1 -0
- package/dist/agent-generator/templates/core/quality-gates.d.ts +11 -0
- package/dist/agent-generator/templates/core/quality-gates.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/quality-gates.js +254 -0
- package/dist/agent-generator/templates/core/quality-gates.js.map +1 -0
- package/dist/agent-generator/templates/core/security-rules.d.ts +7 -0
- package/dist/agent-generator/templates/core/security-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/security-rules.js +528 -0
- package/dist/agent-generator/templates/core/security-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/skills-generator.d.ts +6 -0
- package/dist/agent-generator/templates/core/skills-generator.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/skills-generator.js +207 -0
- package/dist/agent-generator/templates/core/skills-generator.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +7 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.js +237 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +8 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.js +321 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-review.d.ts +7 -0
- package/dist/agent-generator/templates/core/workflow-review.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-review.js +104 -0
- package/dist/agent-generator/templates/core/workflow-review.js.map +1 -0
- package/dist/agent-generator/templates/domain/index.d.ts +22 -0
- package/dist/agent-generator/templates/domain/index.d.ts.map +1 -0
- package/dist/agent-generator/templates/domain/index.js +1176 -0
- package/dist/agent-generator/templates/domain/index.js.map +1 -0
- package/dist/agent-generator/templates/stack/index.d.ts +8 -0
- package/dist/agent-generator/templates/stack/index.d.ts.map +1 -0
- package/dist/agent-generator/templates/stack/index.js +695 -0
- package/dist/agent-generator/templates/stack/index.js.map +1 -0
- package/dist/agent-generator/templates/template-helpers.d.ts +75 -0
- package/dist/agent-generator/templates/template-helpers.d.ts.map +1 -0
- package/dist/agent-generator/templates/template-helpers.js +726 -0
- package/dist/agent-generator/templates/template-helpers.js.map +1 -0
- package/dist/agent-generator/types.d.ts +196 -0
- package/dist/agent-generator/types.d.ts.map +1 -0
- package/dist/agent-generator/types.js +27 -0
- package/dist/agent-generator/types.js.map +1 -0
- package/dist/analyzer.d.ts +5 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +35 -4
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzers/forecast.d.ts +85 -0
- package/dist/analyzers/forecast.d.ts.map +1 -0
- package/dist/analyzers/forecast.js +337 -0
- package/dist/analyzers/forecast.js.map +1 -0
- package/dist/analyzers/git-cache.d.ts +7 -0
- package/dist/analyzers/git-cache.d.ts.map +1 -0
- package/dist/analyzers/git-cache.js +41 -0
- package/dist/analyzers/git-cache.js.map +1 -0
- package/dist/analyzers/git-history.d.ts +113 -0
- package/dist/analyzers/git-history.d.ts.map +1 -0
- package/dist/analyzers/git-history.js +333 -0
- package/dist/analyzers/git-history.js.map +1 -0
- package/dist/analyzers/index.d.ts +10 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +7 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/temporal-scorer.d.ts +72 -0
- package/dist/analyzers/temporal-scorer.d.ts.map +1 -0
- package/dist/analyzers/temporal-scorer.js +140 -0
- package/dist/analyzers/temporal-scorer.js.map +1 -0
- package/dist/cli.d.ts +2 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +287 -82
- package/dist/cli.js.map +1 -1
- package/dist/html-reporter.d.ts +3 -1
- package/dist/html-reporter.d.ts.map +1 -1
- package/dist/html-reporter.js +594 -100
- package/dist/html-reporter.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -4
- package/dist/index.js.map +1 -1
- package/dist/project-summarizer.d.ts +18 -0
- package/dist/project-summarizer.d.ts.map +1 -0
- package/dist/project-summarizer.js +306 -0
- package/dist/project-summarizer.js.map +1 -0
- package/dist/refactor-reporter.js +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -3
- package/src/agent-generator/context-enricher.ts +643 -0
- package/src/agent-generator/domain-inferrer.ts +625 -0
- package/src/agent-generator/framework-detector.ts +669 -0
- package/src/agent-generator/index.ts +555 -0
- package/src/agent-generator/stack-detector.ts +103 -0
- package/src/agent-generator/templates/core/agents.ts +1293 -0
- package/src/agent-generator/templates/core/architecture-rules.ts +287 -0
- package/src/agent-generator/templates/core/general-rules.ts +306 -0
- package/src/agent-generator/templates/core/index-md.ts +260 -0
- package/src/agent-generator/templates/core/orchestrator.ts +459 -0
- package/src/agent-generator/templates/core/preflight.ts +215 -0
- package/src/agent-generator/templates/core/quality-gates.ts +256 -0
- package/src/agent-generator/templates/core/security-rules.ts +543 -0
- package/src/agent-generator/templates/core/skills-generator.ts +236 -0
- package/src/agent-generator/templates/core/workflow-fix-bug.ts +239 -0
- package/src/agent-generator/templates/core/workflow-new-feature.ts +323 -0
- package/src/agent-generator/templates/core/workflow-review.ts +106 -0
- package/src/agent-generator/templates/domain/index.ts +1201 -0
- package/src/agent-generator/templates/stack/index.ts +705 -0
- package/src/agent-generator/templates/template-helpers.ts +776 -0
- package/src/agent-generator/types.ts +232 -0
- package/src/analyzer.ts +38 -4
- package/src/analyzers/forecast.ts +496 -0
- package/src/analyzers/git-cache.ts +52 -0
- package/src/analyzers/git-history.ts +488 -0
- package/src/analyzers/index.ts +33 -0
- package/src/analyzers/temporal-scorer.ts +227 -0
- package/src/cli.ts +336 -83
- package/src/html-reporter.ts +616 -108
- package/src/index.ts +92 -9
- package/src/project-summarizer.ts +347 -0
- package/src/refactor-reporter.ts +1 -1
- package/src/types.ts +10 -0
- package/tests/agent-generator.test.ts +411 -0
- package/tests/analyzers-integration.test.ts +174 -0
- package/tests/architect-adapter-enrichment.test.ts +9 -0
- package/tests/context-enricher.test.ts +971 -0
- package/tests/forecast.test.ts +509 -0
- package/tests/framework-detector.test.ts +1172 -0
- package/tests/git-history.test.ts +254 -0
- package/tests/scanner.test.ts +7 -8
- package/tests/scorer.test.ts +588 -0
- package/tests/stack-detector.test.ts +241 -0
- package/tests/template-generation.test.ts +706 -0
- package/tests/template-helpers.test.ts +1152 -0
- package/tests/temporal-scorer.test.ts +307 -0
- package/dist/agent-generator.d.ts +0 -95
- package/dist/agent-generator.d.ts.map +0 -1
- package/dist/agent-generator.js +0 -1295
- package/dist/agent-generator.js.map +0 -1
- package/src/agent-generator.ts +0 -1401
package/src/cli.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Architect CLI
|
|
5
|
-
*
|
|
4
|
+
* Architect CLI v3.1
|
|
5
|
+
* Enterprise Architecture Analysis — @girardelli/architect
|
|
6
6
|
*
|
|
7
7
|
* Uso:
|
|
8
8
|
* npx architect analyze ./src
|
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
* npx architect diagram ./src
|
|
11
11
|
* npx architect score ./src
|
|
12
12
|
* npx architect anti-patterns ./src
|
|
13
|
-
* npx architect layers ./src
|
|
14
13
|
*/
|
|
15
14
|
|
|
16
|
-
import { architect } from './index.js';
|
|
15
|
+
import { architect, ProgressEvent } from './index.js';
|
|
17
16
|
import { ReportGenerator } from './reporter.js';
|
|
18
17
|
import { HtmlReportGenerator } from './html-reporter.js';
|
|
19
18
|
import { RefactorReportGenerator } from './refactor-reporter.js';
|
|
@@ -29,6 +28,242 @@ interface CliOptions {
|
|
|
29
28
|
output?: string;
|
|
30
29
|
}
|
|
31
30
|
|
|
31
|
+
// ── ANSI Colors & Styles ──
|
|
32
|
+
const c = {
|
|
33
|
+
reset: '\x1b[0m',
|
|
34
|
+
bold: '\x1b[1m',
|
|
35
|
+
dim: '\x1b[2m',
|
|
36
|
+
italic: '\x1b[3m',
|
|
37
|
+
// Colors
|
|
38
|
+
red: '\x1b[38;5;196m',
|
|
39
|
+
green: '\x1b[38;5;46m',
|
|
40
|
+
blue: '\x1b[38;5;33m',
|
|
41
|
+
cyan: '\x1b[38;5;51m',
|
|
42
|
+
yellow: '\x1b[38;5;220m',
|
|
43
|
+
magenta: '\x1b[38;5;201m',
|
|
44
|
+
orange: '\x1b[38;5;208m',
|
|
45
|
+
white: '\x1b[38;5;255m',
|
|
46
|
+
gray: '\x1b[38;5;240m',
|
|
47
|
+
darkGray: '\x1b[38;5;236m',
|
|
48
|
+
// Bg
|
|
49
|
+
bgBlue: '\x1b[48;5;17m',
|
|
50
|
+
bgGreen: '\x1b[48;5;22m',
|
|
51
|
+
bgRed: '\x1b[48;5;52m',
|
|
52
|
+
bgCyan: '\x1b[48;5;23m',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// ── Phase config ──
|
|
56
|
+
interface PhaseConfig {
|
|
57
|
+
icon: string;
|
|
58
|
+
label: string;
|
|
59
|
+
verb: string;
|
|
60
|
+
color: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const PHASES: Record<string, PhaseConfig> = {
|
|
64
|
+
scan: { icon: '◉', label: 'FILE SCANNER', verb: 'Scanning filesystem', color: c.cyan },
|
|
65
|
+
dependencies: { icon: '◉', label: 'DEPENDENCY MAPPER', verb: 'Mapping import graph', color: c.blue },
|
|
66
|
+
layers: { icon: '◉', label: 'LAYER DETECTOR', verb: 'Classifying architecture', color: c.magenta },
|
|
67
|
+
antipatterns: { icon: '◉', label: 'PATTERN ANALYZER', verb: 'Detecting anti-patterns', color: c.orange },
|
|
68
|
+
scoring: { icon: '◉', label: 'QUALITY ENGINE', verb: 'Computing quality metrics', color: c.yellow },
|
|
69
|
+
normalize: { icon: '◉', label: 'PATH NORMALIZER', verb: 'Normalizing paths', color: c.gray },
|
|
70
|
+
summarize: { icon: '◉', label: 'AI SUMMARIZER', verb: 'Generating project summary', color: c.green },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const PHASE_ORDER = ['scan', 'dependencies', 'layers', 'antipatterns', 'scoring', 'normalize', 'summarize'];
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Enterprise-Grade Progress Reporter
|
|
77
|
+
* Real-time phase tracking with visual feedback
|
|
78
|
+
*/
|
|
79
|
+
class ProgressReporter {
|
|
80
|
+
private startTime: number;
|
|
81
|
+
private phaseStart: number = 0;
|
|
82
|
+
private completedPhases: string[] = [];
|
|
83
|
+
private totalPhases: number;
|
|
84
|
+
private scanMetrics: Record<string, number | string> = {};
|
|
85
|
+
|
|
86
|
+
constructor() {
|
|
87
|
+
this.startTime = Date.now();
|
|
88
|
+
this.totalPhases = PHASE_ORDER.length;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Print the stylized header */
|
|
92
|
+
printHeader(projectPath: string): void {
|
|
93
|
+
const name = basename(projectPath);
|
|
94
|
+
const w = process.stderr;
|
|
95
|
+
|
|
96
|
+
w.write('\n');
|
|
97
|
+
w.write(`${c.darkGray} ┌─────────────────────────────────────────────────────────────────┐${c.reset}\n`);
|
|
98
|
+
w.write(`${c.darkGray} │${c.reset} ${c.cyan}${c.bold}⚡ ARCHITECT v3.1${c.reset} ${c.dim}Enterprise Architecture Intelligence${c.reset} ${c.darkGray}│${c.reset}\n`);
|
|
99
|
+
w.write(`${c.darkGray} │${c.reset} ${c.dim}@girardelli/architect — powered by Girardelli Tecnologia${c.reset} ${c.darkGray}│${c.reset}\n`);
|
|
100
|
+
w.write(`${c.darkGray} └─────────────────────────────────────────────────────────────────┘${c.reset}\n`);
|
|
101
|
+
w.write('\n');
|
|
102
|
+
w.write(` ${c.dim}Target:${c.reset} ${c.white}${c.bold}${name}${c.reset}\n`);
|
|
103
|
+
w.write(` ${c.dim}Path:${c.reset} ${c.gray}${projectPath}${c.reset}\n`);
|
|
104
|
+
w.write('\n');
|
|
105
|
+
w.write(` ${c.dim}──── Analysis Pipeline ────────────────────────────────────────${c.reset}\n`);
|
|
106
|
+
w.write('\n');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Handle a progress event from the analyzer */
|
|
110
|
+
onProgress(event: ProgressEvent): void {
|
|
111
|
+
const phase = PHASES[event.phase];
|
|
112
|
+
if (!phase) return;
|
|
113
|
+
|
|
114
|
+
if (event.status === 'start') {
|
|
115
|
+
this.phaseStart = Date.now();
|
|
116
|
+
this.printPhaseStart(event.phase, phase);
|
|
117
|
+
} else if (event.status === 'complete') {
|
|
118
|
+
this.completedPhases.push(event.phase);
|
|
119
|
+
this.printPhaseComplete(event.phase, phase, event.metrics);
|
|
120
|
+
if (event.metrics) {
|
|
121
|
+
Object.assign(this.scanMetrics, event.metrics);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private printPhaseStart(key: string, phase: PhaseConfig): void {
|
|
127
|
+
const idx = PHASE_ORDER.indexOf(key) + 1;
|
|
128
|
+
const bar = this.buildProgressBar(this.completedPhases.length, this.totalPhases);
|
|
129
|
+
process.stderr.write(
|
|
130
|
+
` ${c.dim}[${idx}/${this.totalPhases}]${c.reset} ${phase.color}${phase.icon}${c.reset} ${c.bold}${phase.label}${c.reset} ${c.dim}— ${phase.verb}...${c.reset} ${bar}\n`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private printPhaseComplete(key: string, phase: PhaseConfig, metrics?: Record<string, number | string>): void {
|
|
135
|
+
const elapsed = Date.now() - this.phaseStart;
|
|
136
|
+
const metricStr = metrics ? this.formatMetrics(key, metrics) : '';
|
|
137
|
+
process.stderr.write(
|
|
138
|
+
` ${c.dim} └─${c.reset} ${c.green}✓${c.reset} ${c.dim}${this.formatTime(elapsed)}${c.reset}${metricStr}\n`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private formatMetrics(phase: string, m: Record<string, number | string>): string {
|
|
143
|
+
const parts: string[] = [];
|
|
144
|
+
switch (phase) {
|
|
145
|
+
case 'scan':
|
|
146
|
+
parts.push(`${c.white}${m.files}${c.reset}${c.dim} files${c.reset}`);
|
|
147
|
+
parts.push(`${c.white}${Number(m.lines).toLocaleString()}${c.reset}${c.dim} lines${c.reset}`);
|
|
148
|
+
parts.push(`${c.white}${m.languages}${c.reset}${c.dim} langs${c.reset}`);
|
|
149
|
+
break;
|
|
150
|
+
case 'dependencies':
|
|
151
|
+
parts.push(`${c.white}${m.edges}${c.reset}${c.dim} edges${c.reset}`);
|
|
152
|
+
parts.push(`${c.white}${m.modules}${c.reset}${c.dim} modules${c.reset}`);
|
|
153
|
+
break;
|
|
154
|
+
case 'layers':
|
|
155
|
+
parts.push(`${c.white}${m.layers}${c.reset}${c.dim} layers${c.reset}`);
|
|
156
|
+
parts.push(`${c.white}${m.classified}${c.reset}${c.dim} classified${c.reset}`);
|
|
157
|
+
break;
|
|
158
|
+
case 'antipatterns':
|
|
159
|
+
if (Number(m.total) === 0) {
|
|
160
|
+
parts.push(`${c.green}clean${c.reset}`);
|
|
161
|
+
} else {
|
|
162
|
+
parts.push(`${c.yellow}${m.total}${c.reset}${c.dim} found${c.reset}`);
|
|
163
|
+
if (Number(m.critical) > 0) parts.push(`${c.red}${m.critical} critical${c.reset}`);
|
|
164
|
+
if (Number(m.high) > 0) parts.push(`${c.orange}${m.high} high${c.reset}`);
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
case 'scoring': {
|
|
168
|
+
const overall = Number(m.overall);
|
|
169
|
+
const scoreColor = overall >= 80 ? c.green : overall >= 60 ? c.yellow : c.red;
|
|
170
|
+
parts.push(`${scoreColor}${c.bold}${overall}/100${c.reset}`);
|
|
171
|
+
parts.push(`${c.dim}M:${m.modularity} C:${m.coupling} Co:${m.cohesion} L:${m.layering}${c.reset}`);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case 'summarize':
|
|
175
|
+
parts.push(`${c.white}${m.modules}${c.reset}${c.dim} modules${c.reset}`);
|
|
176
|
+
parts.push(`${c.white}${m.techStack}${c.reset}${c.dim} technologies${c.reset}`);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
return parts.length ? ` ${c.dim}│${c.reset} ${parts.join(`${c.dim} · ${c.reset}`)}` : '';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private buildProgressBar(done: number, total: number): string {
|
|
183
|
+
const width = 20;
|
|
184
|
+
const filled = Math.round((done / total) * width);
|
|
185
|
+
const empty = width - filled;
|
|
186
|
+
const pct = Math.round((done / total) * 100);
|
|
187
|
+
const bar = `${c.cyan}${'█'.repeat(filled)}${c.darkGray}${'░'.repeat(empty)}${c.reset}`;
|
|
188
|
+
return `${c.dim}[${c.reset}${bar}${c.dim}]${c.reset} ${c.dim}${pct}%${c.reset}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private formatTime(ms: number): string {
|
|
192
|
+
if (ms < 1000) return `${ms}ms`;
|
|
193
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Print extra phase for refactor/agents/report generation */
|
|
197
|
+
printExtraPhase(label: string, verb: string, color: string = c.cyan): void {
|
|
198
|
+
this.phaseStart = Date.now();
|
|
199
|
+
const idx = this.completedPhases.length + 1;
|
|
200
|
+
process.stderr.write(
|
|
201
|
+
` ${c.dim}[${idx}/—]${c.reset} ${color}◉${c.reset} ${c.bold}${label}${c.reset} ${c.dim}— ${verb}...${c.reset}\n`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
printExtraComplete(detail: string): void {
|
|
206
|
+
const elapsed = Date.now() - this.phaseStart;
|
|
207
|
+
process.stderr.write(
|
|
208
|
+
` ${c.dim} └─${c.reset} ${c.green}✓${c.reset} ${c.dim}${this.formatTime(elapsed)}${c.reset} ${detail}\n`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Final summary with score visualization */
|
|
213
|
+
printSummary(score: number, breakdown: Record<string, number>, stats: {
|
|
214
|
+
files: number; lines: number; antiPatterns: number;
|
|
215
|
+
refactorSteps?: number; refactorOps?: number; agents?: number;
|
|
216
|
+
}): void {
|
|
217
|
+
const totalTime = Date.now() - this.startTime;
|
|
218
|
+
const w = process.stderr;
|
|
219
|
+
|
|
220
|
+
w.write('\n');
|
|
221
|
+
w.write(` ${c.dim}──── Results ──────────────────────────────────────────────────${c.reset}\n`);
|
|
222
|
+
w.write('\n');
|
|
223
|
+
|
|
224
|
+
// Score meter
|
|
225
|
+
const scoreColor = score >= 80 ? c.green : score >= 60 ? c.yellow : c.red;
|
|
226
|
+
const meterWidth = 40;
|
|
227
|
+
const filled = Math.round((score / 100) * meterWidth);
|
|
228
|
+
const meter = `${scoreColor}${'━'.repeat(filled)}${c.darkGray}${'━'.repeat(meterWidth - filled)}${c.reset}`;
|
|
229
|
+
const grade = score >= 90 ? 'A+' : score >= 80 ? 'A' : score >= 70 ? 'B' : score >= 60 ? 'C' : score >= 50 ? 'D' : 'F';
|
|
230
|
+
|
|
231
|
+
w.write(` ${c.bold} ARCHITECTURE SCORE${c.reset}\n`);
|
|
232
|
+
w.write(` ${meter} ${scoreColor}${c.bold}${score}/100${c.reset} ${c.dim}(${grade})${c.reset}\n`);
|
|
233
|
+
w.write('\n');
|
|
234
|
+
w.write(` ${c.dim} Modularity${c.reset} ${this.miniBar(breakdown.modularity)} ${c.white}${breakdown.modularity}${c.reset}\n`);
|
|
235
|
+
w.write(` ${c.dim} Coupling${c.reset} ${this.miniBar(breakdown.coupling)} ${c.white}${breakdown.coupling}${c.reset}\n`);
|
|
236
|
+
w.write(` ${c.dim} Cohesion${c.reset} ${this.miniBar(breakdown.cohesion)} ${c.white}${breakdown.cohesion}${c.reset}\n`);
|
|
237
|
+
w.write(` ${c.dim} Layering${c.reset} ${this.miniBar(breakdown.layering)} ${c.white}${breakdown.layering}${c.reset}\n`);
|
|
238
|
+
w.write('\n');
|
|
239
|
+
|
|
240
|
+
// Stats line
|
|
241
|
+
w.write(` ${c.cyan}📁${c.reset} ${c.white}${stats.files}${c.reset}${c.dim} files${c.reset}`);
|
|
242
|
+
w.write(` ${c.cyan}📝${c.reset} ${c.white}${stats.lines.toLocaleString()}${c.reset}${c.dim} lines${c.reset}`);
|
|
243
|
+
w.write(` ${c.cyan}⚠️${c.reset} ${c.white}${stats.antiPatterns}${c.reset}${c.dim} anti-patterns${c.reset}`);
|
|
244
|
+
if (stats.refactorSteps !== undefined) {
|
|
245
|
+
w.write(` ${c.cyan}🔧${c.reset} ${c.white}${stats.refactorSteps}${c.reset}${c.dim} steps${c.reset}`);
|
|
246
|
+
}
|
|
247
|
+
if (stats.agents !== undefined) {
|
|
248
|
+
w.write(` ${c.cyan}🤖${c.reset} ${c.white}${stats.agents}${c.reset}${c.dim} agents${c.reset}`);
|
|
249
|
+
}
|
|
250
|
+
w.write('\n');
|
|
251
|
+
|
|
252
|
+
// Timing
|
|
253
|
+
w.write(`\n ${c.dim}⏱ Completed in ${this.formatTime(totalTime)}${c.reset}\n`);
|
|
254
|
+
w.write('\n');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private miniBar(value: number): string {
|
|
258
|
+
const w = 15;
|
|
259
|
+
const f = Math.round((value / 100) * w);
|
|
260
|
+
const color = value >= 80 ? c.green : value >= 60 ? c.yellow : c.red;
|
|
261
|
+
return `${color}${'▓'.repeat(f)}${c.darkGray}${'░'.repeat(w - f)}${c.reset}`;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ── CLI Parsing ──
|
|
266
|
+
|
|
32
267
|
function parseArgs(args: string[]): CliOptions {
|
|
33
268
|
const command = args[0] || 'analyze';
|
|
34
269
|
const pathArg = args.find((a) => !a.startsWith('--') && a !== command) || '.';
|
|
@@ -42,30 +277,31 @@ function parseArgs(args: string[]): CliOptions {
|
|
|
42
277
|
|
|
43
278
|
function printUsage(): void {
|
|
44
279
|
console.log(`
|
|
45
|
-
|
|
280
|
+
${c.cyan}${c.bold}⚡ Architect v3.1${c.reset} — Enterprise Architecture Intelligence
|
|
46
281
|
|
|
47
|
-
Usage
|
|
282
|
+
${c.bold}Usage:${c.reset}
|
|
48
283
|
architect <command> [path] [options]
|
|
49
284
|
|
|
50
|
-
Commands
|
|
51
|
-
analyze Full architecture analysis (default)
|
|
52
|
-
refactor Generate refactoring plan with actionable steps
|
|
53
|
-
agents Generate/audit .agent/ directory with AI agents
|
|
54
|
-
diagram Generate architecture diagram only
|
|
55
|
-
score Calculate quality score only
|
|
56
|
-
anti-patterns Detect anti-patterns only
|
|
57
|
-
layers Analyze layer structure only
|
|
285
|
+
${c.bold}Commands:${c.reset}
|
|
286
|
+
${c.cyan}analyze${c.reset} Full architecture analysis (default)
|
|
287
|
+
${c.cyan}refactor${c.reset} Generate refactoring plan with actionable steps
|
|
288
|
+
${c.cyan}agents${c.reset} Generate/audit .agent/ directory with AI agents
|
|
289
|
+
${c.cyan}diagram${c.reset} Generate architecture diagram only
|
|
290
|
+
${c.cyan}score${c.reset} Calculate quality score only
|
|
291
|
+
${c.cyan}anti-patterns${c.reset} Detect anti-patterns only
|
|
292
|
+
${c.cyan}layers${c.reset} Analyze layer structure only
|
|
58
293
|
|
|
59
|
-
Options
|
|
294
|
+
${c.bold}Options:${c.reset}
|
|
60
295
|
--format <type> Output format: html, json, markdown (default: html)
|
|
61
|
-
--output <file> Output file path
|
|
296
|
+
--output <file> Output file path
|
|
62
297
|
--help Show this help message
|
|
63
298
|
|
|
64
|
-
Examples
|
|
65
|
-
architect analyze ./src
|
|
66
|
-
architect analyze ./src --format html --output report.html
|
|
67
|
-
architect score ./src --format json
|
|
68
|
-
|
|
299
|
+
${c.bold}Examples:${c.reset}
|
|
300
|
+
${c.dim}$${c.reset} architect analyze ./src
|
|
301
|
+
${c.dim}$${c.reset} architect analyze ./src --format html --output report.html
|
|
302
|
+
${c.dim}$${c.reset} architect score ./src --format json
|
|
303
|
+
|
|
304
|
+
${c.dim}@girardelli/architect — Girardelli Tecnologia${c.reset}
|
|
69
305
|
`);
|
|
70
306
|
}
|
|
71
307
|
|
|
@@ -79,98 +315,113 @@ async function main(): Promise<void> {
|
|
|
79
315
|
|
|
80
316
|
const options = parseArgs(args);
|
|
81
317
|
|
|
82
|
-
console.log('🏗️ Architect — Architecture Analysis');
|
|
83
|
-
console.log(`📂 Path: ${options.path}`);
|
|
84
|
-
console.log(`📋 Command: ${options.command}`);
|
|
85
|
-
console.log(`📄 Format: ${options.format}\n`);
|
|
86
|
-
|
|
87
318
|
try {
|
|
88
319
|
switch (options.command) {
|
|
89
320
|
case 'analyze': {
|
|
90
|
-
const
|
|
321
|
+
const progress = new ProgressReporter();
|
|
322
|
+
progress.printHeader(options.path);
|
|
323
|
+
|
|
324
|
+
const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
|
|
325
|
+
|
|
326
|
+
// Refactoring
|
|
327
|
+
progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
|
|
91
328
|
const plan = architect.refactor(report, options.path);
|
|
329
|
+
progress.printExtraComplete(
|
|
330
|
+
`${c.white}${plan.steps.length}${c.reset}${c.dim} steps · ${c.reset}${c.white}${plan.totalOperations}${c.reset}${c.dim} operations · est. +${plan.estimatedScoreAfter.overall - plan.currentScore.overall} pts${c.reset}`
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
// Agent suggestion
|
|
334
|
+
progress.printExtraPhase('AGENT SYSTEM', 'Analyzing agent requirements', c.magenta);
|
|
92
335
|
const agentSuggestion = architect.suggestAgents(report, plan, options.path);
|
|
336
|
+
progress.printExtraComplete(
|
|
337
|
+
`${c.white}${agentSuggestion.suggestedAgents.length}${c.reset}${c.dim} agents suggested${agentSuggestion.hasExistingAgents ? ' (existing .agent/ audited)' : ''}${c.reset}`
|
|
338
|
+
);
|
|
339
|
+
|
|
93
340
|
const projectName = report.projectInfo.name || basename(options.path);
|
|
94
341
|
|
|
342
|
+
// Report generation
|
|
95
343
|
if (options.format === 'html') {
|
|
344
|
+
progress.printExtraPhase('REPORT BUILDER', 'Generating interactive HTML report', c.cyan);
|
|
96
345
|
const htmlGenerator = new HtmlReportGenerator();
|
|
97
346
|
const html = htmlGenerator.generateHtml(report, plan, agentSuggestion);
|
|
98
347
|
const outputPath = options.output || `architect-report-${projectName}.html`;
|
|
99
348
|
writeFileSync(outputPath, html);
|
|
100
|
-
|
|
101
|
-
console.log(`📊 Score: ${report.score.overall}/100`);
|
|
102
|
-
console.log(`⚠️ Anti-patterns: ${report.antiPatterns.length}`);
|
|
103
|
-
console.log(`🔧 Refactoring steps: ${plan.steps.length}`);
|
|
104
|
-
console.log(`🤖 Suggested agents: ${agentSuggestion.suggestedAgents.length}`);
|
|
349
|
+
progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
|
|
105
350
|
} else if (options.format === 'markdown') {
|
|
351
|
+
progress.printExtraPhase('REPORT BUILDER', 'Generating Markdown report', c.cyan);
|
|
106
352
|
const mdGenerator = new ReportGenerator();
|
|
107
353
|
const markdown = mdGenerator.generateMarkdownReport(report);
|
|
108
354
|
const outputPath = options.output || `architect-report-${projectName}.md`;
|
|
109
355
|
writeFileSync(outputPath, markdown);
|
|
110
|
-
|
|
356
|
+
progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
|
|
111
357
|
} else {
|
|
358
|
+
progress.printExtraPhase('REPORT BUILDER', 'Generating JSON report', c.cyan);
|
|
112
359
|
const outputPath = options.output || `architect-report-${projectName}.json`;
|
|
113
360
|
writeFileSync(outputPath, JSON.stringify({ report, plan, agentSuggestion }, null, 2));
|
|
114
|
-
|
|
361
|
+
progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
|
|
115
362
|
}
|
|
116
363
|
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
console.log(`⚠️ Anti-patterns: ${report.antiPatterns.length}`);
|
|
127
|
-
console.log(`🤖 Agents: ${agentSuggestion.suggestedAgents.length} suggested | ${agentSuggestion.hasExistingAgents ? 'Existing .agent/ audited' : 'No .agent/ found'}`);
|
|
364
|
+
// Summary
|
|
365
|
+
progress.printSummary(report.score.overall, report.score.breakdown, {
|
|
366
|
+
files: report.projectInfo.totalFiles,
|
|
367
|
+
lines: report.projectInfo.totalLines,
|
|
368
|
+
antiPatterns: report.antiPatterns.length,
|
|
369
|
+
refactorSteps: plan.steps.length,
|
|
370
|
+
refactorOps: plan.totalOperations,
|
|
371
|
+
agents: agentSuggestion.suggestedAgents.length,
|
|
372
|
+
});
|
|
128
373
|
break;
|
|
129
374
|
}
|
|
130
375
|
|
|
131
376
|
case 'refactor': {
|
|
132
|
-
const
|
|
377
|
+
const progress = new ProgressReporter();
|
|
378
|
+
progress.printHeader(options.path);
|
|
379
|
+
|
|
380
|
+
const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
|
|
381
|
+
|
|
382
|
+
progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
|
|
133
383
|
const plan = architect.refactor(report, options.path);
|
|
134
384
|
const projectName = report.projectInfo.name || basename(options.path);
|
|
135
385
|
|
|
136
386
|
if (options.format === 'json') {
|
|
137
387
|
const outputPath = options.output || `refactor-plan-${projectName}.json`;
|
|
138
388
|
writeFileSync(outputPath, JSON.stringify(plan, null, 2));
|
|
139
|
-
|
|
389
|
+
progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
|
|
140
390
|
} else {
|
|
141
391
|
const refactorReporter = new RefactorReportGenerator();
|
|
142
392
|
const html = refactorReporter.generateHtml(plan);
|
|
143
393
|
const outputPath = options.output || `refactor-plan-${projectName}.html`;
|
|
144
394
|
writeFileSync(outputPath, html);
|
|
145
|
-
|
|
395
|
+
progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
|
|
146
396
|
}
|
|
147
397
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
console.log(`├─ Steps: ${plan.steps.length}`);
|
|
152
|
-
console.log(`├─ Operations: ${plan.totalOperations}`);
|
|
153
|
-
console.log(`├─ Tier 1: ${plan.tier1Steps} (rule-based)`);
|
|
154
|
-
console.log(`├─ Tier 2: ${plan.tier2Steps} (AST-based)`);
|
|
155
|
-
console.log(`├─ Current: ${plan.currentScore.overall}/100`);
|
|
156
|
-
console.log(`└─ Estimated: ${plan.estimatedScoreAfter.overall}/100 (+${plan.estimatedScoreAfter.overall - plan.currentScore.overall})`);
|
|
398
|
+
process.stderr.write(`\n ${c.bold}REFACTORING PLAN${c.reset}\n`);
|
|
399
|
+
process.stderr.write(` ${c.dim}Steps:${c.reset} ${c.white}${plan.steps.length}${c.reset} ${c.dim}Ops:${c.reset} ${c.white}${plan.totalOperations}${c.reset} ${c.dim}Tier1:${c.reset} ${c.white}${plan.tier1Steps}${c.reset} ${c.dim}Tier2:${c.reset} ${c.white}${plan.tier2Steps}${c.reset}\n`);
|
|
400
|
+
process.stderr.write(` ${c.dim}Score:${c.reset} ${c.white}${plan.currentScore.overall}${c.reset}${c.dim} → ${c.reset}${c.green}${plan.estimatedScoreAfter.overall}${c.reset} ${c.dim}(+${plan.estimatedScoreAfter.overall - plan.currentScore.overall})${c.reset}\n\n`);
|
|
157
401
|
break;
|
|
158
402
|
}
|
|
159
403
|
|
|
160
404
|
case 'agents': {
|
|
161
|
-
const
|
|
405
|
+
const progress = new ProgressReporter();
|
|
406
|
+
progress.printHeader(options.path);
|
|
407
|
+
|
|
408
|
+
const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
|
|
409
|
+
|
|
410
|
+
progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
|
|
162
411
|
const plan = architect.refactor(report, options.path);
|
|
412
|
+
progress.printExtraComplete(`${c.white}${plan.steps.length}${c.reset}${c.dim} steps${c.reset}`);
|
|
413
|
+
|
|
414
|
+
progress.printExtraPhase('AGENT GENERATOR', 'Generating .agent/ framework', c.magenta);
|
|
163
415
|
const outputDir = options.output || undefined;
|
|
164
416
|
const result = architect.agents(report, plan, options.path, outputDir);
|
|
417
|
+
progress.printExtraComplete(`${c.white}${result.generated.length}${c.reset}${c.dim} files generated${c.reset}`);
|
|
165
418
|
|
|
166
|
-
|
|
167
|
-
console.log(` 🤖 AGENT SYSTEM`);
|
|
168
|
-
console.log(`═══════════════════════════════════════`);
|
|
419
|
+
process.stderr.write(`\n ${c.bold}🤖 AGENT SYSTEM${c.reset}\n\n`);
|
|
169
420
|
|
|
170
421
|
if (result.generated.length > 0) {
|
|
171
|
-
|
|
422
|
+
process.stderr.write(` ${c.green}Generated:${c.reset}\n`);
|
|
172
423
|
for (const file of result.generated) {
|
|
173
|
-
|
|
424
|
+
process.stderr.write(` ${c.dim} 📄${c.reset} ${file}\n`);
|
|
174
425
|
}
|
|
175
426
|
}
|
|
176
427
|
|
|
@@ -179,25 +430,20 @@ async function main(): Promise<void> {
|
|
|
179
430
|
const improvements = result.audit.filter(f => f.type === 'IMPROVEMENT');
|
|
180
431
|
const ok = result.audit.filter(f => f.type === 'OK');
|
|
181
432
|
|
|
182
|
-
if (ok.length > 0) {
|
|
183
|
-
console.log(`\n✅ ${ok.length} checks passed`);
|
|
184
|
-
}
|
|
433
|
+
if (ok.length > 0) process.stderr.write(`\n ${c.green}✓ ${ok.length} checks passed${c.reset}\n`);
|
|
185
434
|
if (missing.length > 0) {
|
|
186
|
-
|
|
187
|
-
for (const f of missing) {
|
|
188
|
-
console.log(` 📄 ${f.file} — ${f.description}`);
|
|
189
|
-
}
|
|
435
|
+
process.stderr.write(`\n ${c.red}✗ ${missing.length} missing (auto-generated):${c.reset}\n`);
|
|
436
|
+
for (const f of missing) process.stderr.write(` ${c.dim}📄${c.reset} ${f.file} — ${f.description}\n`);
|
|
190
437
|
}
|
|
191
438
|
if (improvements.length > 0) {
|
|
192
|
-
|
|
439
|
+
process.stderr.write(`\n ${c.yellow}💡 ${improvements.length} improvements:${c.reset}\n`);
|
|
193
440
|
for (const f of improvements) {
|
|
194
|
-
|
|
195
|
-
if (f.suggestion)
|
|
441
|
+
process.stderr.write(` ${c.dim}⚡${c.reset} ${f.description}\n`);
|
|
442
|
+
if (f.suggestion) process.stderr.write(` ${c.dim}→ ${f.suggestion}${c.reset}\n`);
|
|
196
443
|
}
|
|
197
444
|
}
|
|
198
445
|
}
|
|
199
|
-
|
|
200
|
-
console.log(`\n📊 Score: ${report.score.overall}/100`);
|
|
446
|
+
process.stderr.write(`\n ${c.dim}Score: ${report.score.overall}/100${c.reset}\n\n`);
|
|
201
447
|
break;
|
|
202
448
|
}
|
|
203
449
|
|
|
@@ -205,7 +451,7 @@ async function main(): Promise<void> {
|
|
|
205
451
|
const diagram = await architect.diagram(options.path);
|
|
206
452
|
if (options.output) {
|
|
207
453
|
writeFileSync(options.output, diagram);
|
|
208
|
-
|
|
454
|
+
process.stderr.write(` ${c.green}✓${c.reset} Diagram saved: ${options.output}\n`);
|
|
209
455
|
} else {
|
|
210
456
|
console.log(diagram);
|
|
211
457
|
}
|
|
@@ -217,10 +463,13 @@ async function main(): Promise<void> {
|
|
|
217
463
|
if (options.format === 'json') {
|
|
218
464
|
console.log(JSON.stringify(score, null, 2));
|
|
219
465
|
} else {
|
|
220
|
-
|
|
466
|
+
const scoreColor = score.overall >= 80 ? c.green : score.overall >= 60 ? c.yellow : c.red;
|
|
467
|
+
process.stderr.write(`\n ${c.bold}ARCHITECTURE SCORE${c.reset}\n`);
|
|
468
|
+
process.stderr.write(` ${scoreColor}${c.bold}${score.overall}/100${c.reset}\n\n`);
|
|
221
469
|
for (const [name, value] of Object.entries(score.breakdown)) {
|
|
222
|
-
|
|
470
|
+
process.stderr.write(` ${c.dim}${name}:${c.reset} ${c.white}${value}${c.reset}\n`);
|
|
223
471
|
}
|
|
472
|
+
process.stderr.write('\n');
|
|
224
473
|
}
|
|
225
474
|
break;
|
|
226
475
|
}
|
|
@@ -230,10 +479,12 @@ async function main(): Promise<void> {
|
|
|
230
479
|
if (options.format === 'json') {
|
|
231
480
|
console.log(JSON.stringify(patterns, null, 2));
|
|
232
481
|
} else {
|
|
233
|
-
|
|
482
|
+
process.stderr.write(`\n ${c.bold}ANTI-PATTERNS${c.reset} — ${patterns.length} found\n\n`);
|
|
234
483
|
for (const p of patterns) {
|
|
235
|
-
|
|
484
|
+
const sevColor = p.severity === 'CRITICAL' ? c.red : p.severity === 'HIGH' ? c.orange : c.yellow;
|
|
485
|
+
process.stderr.write(` ${sevColor}[${p.severity}]${c.reset} ${c.bold}${p.name}${c.reset}: ${p.description}\n`);
|
|
236
486
|
}
|
|
487
|
+
process.stderr.write('\n');
|
|
237
488
|
}
|
|
238
489
|
break;
|
|
239
490
|
}
|
|
@@ -243,20 +494,22 @@ async function main(): Promise<void> {
|
|
|
243
494
|
if (options.format === 'json') {
|
|
244
495
|
console.log(JSON.stringify(layers, null, 2));
|
|
245
496
|
} else {
|
|
497
|
+
process.stderr.write(`\n ${c.bold}ARCHITECTURE LAYERS${c.reset}\n\n`);
|
|
246
498
|
for (const l of layers) {
|
|
247
|
-
|
|
499
|
+
process.stderr.write(` ${c.cyan}${l.name}${c.reset}: ${c.white}${l.files.length}${c.reset} files\n`);
|
|
248
500
|
}
|
|
501
|
+
process.stderr.write('\n');
|
|
249
502
|
}
|
|
250
503
|
break;
|
|
251
504
|
}
|
|
252
505
|
|
|
253
506
|
default:
|
|
254
|
-
console.error(
|
|
507
|
+
console.error(`${c.red}✗${c.reset} Unknown command: ${options.command}`);
|
|
255
508
|
printUsage();
|
|
256
509
|
process.exit(1);
|
|
257
510
|
}
|
|
258
511
|
} catch (error) {
|
|
259
|
-
|
|
512
|
+
process.stderr.write(`\n ${c.red}${c.bold}✗ ERROR${c.reset}: ${error instanceof Error ? error.message : error}\n\n`);
|
|
260
513
|
process.exit(1);
|
|
261
514
|
}
|
|
262
515
|
}
|