antigravity-flow 1.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.
Files changed (115) hide show
  1. package/README.md +182 -0
  2. package/dist/bin/ag-flow.js +127 -0
  3. package/dist/src/adapters/ConsoleLoggerAdapter.js +52 -0
  4. package/dist/src/adapters/EjsTemplateAdapter.js +66 -0
  5. package/dist/src/adapters/JsonLocalizationAdapter.js +81 -0
  6. package/dist/src/adapters/NodeFileSystemAdapter.js +52 -0
  7. package/dist/src/adapters/index.js +20 -0
  8. package/dist/src/commands/guide.js +89 -0
  9. package/dist/src/commands/index.js +19 -0
  10. package/dist/src/commands/init.js +581 -0
  11. package/dist/src/commands/templates.js +143 -0
  12. package/dist/src/core/ConfigService.js +75 -0
  13. package/dist/src/core/ContextGenerator.js +27 -0
  14. package/dist/src/core/DockerfileGenerator.js +151 -0
  15. package/dist/src/core/GitignoreGenerator.js +129 -0
  16. package/dist/src/core/PipelineGenerator.js +68 -0
  17. package/dist/src/core/RulesComposer.js +62 -0
  18. package/dist/src/core/StackDetector.js +115 -0
  19. package/dist/src/core/WorkflowGenerator.js +137 -0
  20. package/dist/src/core/index.js +26 -0
  21. package/dist/src/core/interfaces.js +2 -0
  22. package/dist/src/core/pipelines/PipelineStrategy.js +97 -0
  23. package/dist/src/core/types.js +300 -0
  24. package/dist/src/locales/en.json +293 -0
  25. package/dist/src/locales/fr.json +293 -0
  26. package/dist/src/templates/docker/django.Dockerfile.ejs +21 -0
  27. package/dist/src/templates/docker/dockerignore.ejs +12 -0
  28. package/dist/src/templates/docker/go.Dockerfile.ejs +20 -0
  29. package/dist/src/templates/docker/nestjs.Dockerfile.ejs +25 -0
  30. package/dist/src/templates/docker/node.Dockerfile.ejs +13 -0
  31. package/dist/src/templates/docker/python.Dockerfile.ejs +13 -0
  32. package/dist/src/templates/docker/springboot.Dockerfile.ejs +25 -0
  33. package/dist/src/templates/en/architect.md.ejs +85 -0
  34. package/dist/src/templates/en/ba.md.ejs +88 -0
  35. package/dist/src/templates/en/data.md.ejs +47 -0
  36. package/dist/src/templates/en/dev.md.ejs +77 -0
  37. package/dist/src/templates/en/devops.md.ejs +54 -0
  38. package/dist/src/templates/en/fragments/arch/feature-sliced.md.ejs +12 -0
  39. package/dist/src/templates/en/fragments/arch/hexagonal.md.ejs +14 -0
  40. package/dist/src/templates/en/fragments/arch/mvc.md.ejs +11 -0
  41. package/dist/src/templates/en/fragments/aspnet-core.md.ejs +11 -0
  42. package/dist/src/templates/en/fragments/base-rules.md.ejs +5 -0
  43. package/dist/src/templates/en/fragments/django.md.ejs +12 -0
  44. package/dist/src/templates/en/fragments/fastapi.md.ejs +11 -0
  45. package/dist/src/templates/en/fragments/flutter.md.ejs +11 -0
  46. package/dist/src/templates/en/fragments/nestjs.md.ejs +5 -0
  47. package/dist/src/templates/en/fragments/nextjs.md.ejs +10 -0
  48. package/dist/src/templates/en/fragments/react-native.md.ejs +12 -0
  49. package/dist/src/templates/en/fragments/react.md.ejs +5 -0
  50. package/dist/src/templates/en/fragments/rigor/legacy.md.ejs +6 -0
  51. package/dist/src/templates/en/fragments/rigor/prototype.md.ejs +6 -0
  52. package/dist/src/templates/en/fragments/rigor/strict.md.ejs +7 -0
  53. package/dist/src/templates/en/fragments/rust.md.ejs +11 -0
  54. package/dist/src/templates/en/fragments/scrypto.md.ejs +8 -0
  55. package/dist/src/templates/en/fragments/solidity.md.ejs +20 -0
  56. package/dist/src/templates/en/fragments/spring-boot.md.ejs +13 -0
  57. package/dist/src/templates/en/guide.txt +48 -0
  58. package/dist/src/templates/en/lead.md.ejs +76 -0
  59. package/dist/src/templates/en/pipelines/github-dotnet.yml.ejs +24 -0
  60. package/dist/src/templates/en/pipelines/github-flutter.yml.ejs +24 -0
  61. package/dist/src/templates/en/pipelines/github-nestjs.yml.ejs +26 -0
  62. package/dist/src/templates/en/pipelines/github-react.yml.ejs +26 -0
  63. package/dist/src/templates/en/pipelines/github-rust.yml.ejs +38 -0
  64. package/dist/src/templates/en/pipelines/github-scrypto.yml.ejs +34 -0
  65. package/dist/src/templates/en/po.md.ejs +86 -0
  66. package/dist/src/templates/en/project-context.md.ejs +26 -0
  67. package/dist/src/templates/en/qa.md.ejs +103 -0
  68. package/dist/src/templates/en/rules.md.ejs +30 -0
  69. package/dist/src/templates/en/security.md.ejs +55 -0
  70. package/dist/src/templates/en/techwriter.md.ejs +46 -0
  71. package/dist/src/templates/fr/architect.md.ejs +15 -0
  72. package/dist/src/templates/fr/ba.md.ejs +11 -0
  73. package/dist/src/templates/fr/data.md.ejs +47 -0
  74. package/dist/src/templates/fr/dev.md.ejs +11 -0
  75. package/dist/src/templates/fr/devops.md.ejs +54 -0
  76. package/dist/src/templates/fr/fragments/arch/feature-sliced.md.ejs +12 -0
  77. package/dist/src/templates/fr/fragments/arch/hexagonal.md.ejs +14 -0
  78. package/dist/src/templates/fr/fragments/arch/mvc.md.ejs +11 -0
  79. package/dist/src/templates/fr/fragments/aspnet-core.md.ejs +11 -0
  80. package/dist/src/templates/fr/fragments/flutter.md.ejs +11 -0
  81. package/dist/src/templates/fr/fragments/rigor/legacy.md.ejs +6 -0
  82. package/dist/src/templates/fr/fragments/rigor/prototype.md.ejs +6 -0
  83. package/dist/src/templates/fr/fragments/rigor/strict.md.ejs +7 -0
  84. package/dist/src/templates/fr/fragments/rust.md.ejs +10 -0
  85. package/dist/src/templates/fr/fragments/scrypto.md.ejs +8 -0
  86. package/dist/src/templates/fr/guide.txt +47 -0
  87. package/dist/src/templates/fr/lead.md.ejs +12 -0
  88. package/dist/src/templates/fr/po.md.ejs +11 -0
  89. package/dist/src/templates/fr/project-context.md.ejs +28 -0
  90. package/dist/src/templates/fr/qa.md.ejs +14 -0
  91. package/dist/src/templates/fr/rules.md.ejs +30 -0
  92. package/dist/src/templates/fr/security.md.ejs +55 -0
  93. package/dist/src/templates/fr/techwriter.md.ejs +46 -0
  94. package/dist/src/templates/gitignore/dotnet.txt +6 -0
  95. package/dist/src/templates/gitignore/go.txt +15 -0
  96. package/dist/src/templates/gitignore/java.txt +4 -0
  97. package/dist/src/templates/gitignore/jetbrains.txt +4 -0
  98. package/dist/src/templates/gitignore/linux.txt +5 -0
  99. package/dist/src/templates/gitignore/macos.txt +3 -0
  100. package/dist/src/templates/gitignore/node.txt +11 -0
  101. package/dist/src/templates/gitignore/python.txt +10 -0
  102. package/dist/src/templates/gitignore/rust.txt +3 -0
  103. package/dist/src/templates/gitignore/solidity.txt +19 -0
  104. package/dist/src/templates/gitignore/vscode.txt +6 -0
  105. package/dist/src/templates/gitignore/windows.txt +4 -0
  106. package/dist/tests/commands/InitCommand.spec.js +529 -0
  107. package/dist/tests/commands/InitConfig.spec.js +108 -0
  108. package/dist/tests/core/ConfigService.spec.js +97 -0
  109. package/dist/tests/core/ContextGenerator.spec.js +51 -0
  110. package/dist/tests/core/PipelineGenerator.spec.js +206 -0
  111. package/dist/tests/core/RulesComposer.spec.js +89 -0
  112. package/dist/tests/core/StackDetector.spec.js +69 -0
  113. package/dist/tests/core/Types.spec.js +243 -0
  114. package/dist/tests/core/WorkflowGenerator.spec.js +99 -0
  115. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # 🚀 Antigravity Workflow CLI
2
+
3
+ **Enforce strict, agentic workflows in your development projects.**
4
+
5
+ Antigravity Flow (`ag-flow`) is a CLI tool originally built to prepare projects for **Google Antigravity**. It has since evolved into a **universal context generator** that standardizes development workflows for all AI-native IDEs, including **Cursor**, **Windsurf**, **Gemini Code Assist**, and **GitHub Copilot**.
6
+
7
+ It generates context-aware rules, workflows, and CI/CD pipelines tailored to your project's technology stack and architecture.
8
+
9
+ ## ✨ Features
10
+
11
+ - **🎭 Role-Based Workflows**: Generate specific prompt instructions for:
12
+ - Developers, QA, Lead Devs, Architects, POs, BAs
13
+ - **NEW**: DevOps, Security Engineers, Tech Writers, Data Engineers
14
+ - **🏗️ Architecture-Aware**: Supports **Hexagonal**, **Clean**, **Vertical Slice (FSD)**, **MVC**, **Layered**, **Microservices**.
15
+ - **🌐 Internationalization (I18n)**: Fully localized in **English** 🇺🇸 and **French** 🇫🇷.
16
+ - **📏 Rigor Modes**:
17
+ - **Strict**: Enforces TDD, 100% coverage, no `any`, mandatory docs.
18
+ - **Standard**: Balanced approach with 80% coverage target.
19
+ - **Prototype**: Speed-focused, allows `// TODO` debt, optional TDD.
20
+ - **Legacy**: For maintaining older codebases with characterization tests.
21
+ - **🤖 Agent Context**: Generates `.agent/project-context.md` to prime your AI agent.
22
+ - **🔌 IDE Integration**: Automatically configures:
23
+ - **Cursor** (`.cursor/rules/*.mdc`)
24
+ - **Windsurf** (`.windsurfrules`, `.windsurf/rules/`)
25
+ - **Gemini Code Assist** (`.gemini/settings.json`)
26
+ - **GitHub Copilot**
27
+ - **🚀 Generators**:
28
+ - **CI/CD**: GitHub Actions pipelines.
29
+ - **Dockerfile**: Production-ready, multi-stage builds.
30
+ - **.gitignore**: Optimized rules for your stack.
31
+ - **💡 Intelligent Discovery**: Auto-detects your tech stack to pre-fill prompts.
32
+ - **💾 Configuration Persistence**: Saves your choices to `.agent/antigravity.json`.
33
+ - **📦 Monorepo Support**: Turborepo, Nx, Lerna, pnpm/yarn workspaces.
34
+
35
+ ## 📦 Installation
36
+
37
+ ```bash
38
+ npm install -g antigravity-flow
39
+ # Or run without installing:
40
+ npx antigravity-flow init
41
+ ```
42
+
43
+ ## 🚀 Usage
44
+
45
+ Navigate to your project root and run:
46
+
47
+ ```bash
48
+ ag-flow init
49
+ # or with configuration file (Non-interactive):
50
+ ag-flow init --config ./antigravity.json
51
+ # or
52
+ npx antigravity-flow init
53
+ ```
54
+
55
+ To view the comprehensive user guide directly in your terminal:
56
+
57
+ ```bash
58
+ ag-flow guide
59
+ # or for French:
60
+ ag-flow guide fr
61
+ ```
62
+
63
+ ### Interactive Prompts
64
+
65
+ The CLI will guide you through:
66
+
67
+ 1. **Language**: English (en) or French (fr).
68
+ 2. **Project Description**: Brief overview of your project.
69
+ 3. **Tech Stack**:
70
+ - Frontend, Backend, Mobile, Smart Contracts
71
+ 4. **Database & ORM**: PostgreSQL, MySQL, SQL Server, Oracle, MongoDB, etc.
72
+ 5. **Architecture**: Hexagonal, Clean, MVC, Feature-Sliced, Microservices.
73
+ 6. **Rigor Mode**: Strict, Standard, Prototype, Legacy.
74
+ 7. **Version Control**: GitHub, GitLab, Azure DevOps, Bitbucket.
75
+ 8. **Branching Strategy**: GitFlow, GitHub Flow, Trunk-Based.
76
+ 9. **Package Manager**: npm, yarn, pnpm, bun, pip, poetry, cargo, etc.
77
+ 10. **Testing Framework**: Jest, Vitest, Playwright, Cypress, pytest, etc.
78
+ 11. **Deployment Platform**: Vercel, Netlify, AWS, Azure, GCP, Railway, etc.
79
+ 12. **Security Scanning**: Snyk, Dependabot, Renovate, SonarQube.
80
+ 13. **Monorepo**: Turborepo, Nx, Lerna, pnpm/yarn workspaces.
81
+ 14. **Roles**: Select which workflows to generate.
82
+ 15. **IDE Integration**: Cursor, Windsurf, Gemini, Copilot.
83
+
84
+ ## 📂 Output Structure
85
+
86
+ ```
87
+ .
88
+ ├── .github/workflows/
89
+ │ └── ci.yml # Generated CI/CD pipeline
90
+ ├── .agent/
91
+ │ ├── workflows/ # Role-specific prompt templates
92
+ │ │ ├── dev.md # Developer workflow
93
+ │ │ ├── qa.md # QA workflow
94
+ │ │ ├── architect.md # Architect workflow
95
+ │ │ ├── devops.md # DevOps workflow (NEW)
96
+ │ │ ├── security.md # Security Engineer (NEW)
97
+ │ │ ├── techwriter.md # Tech Writer (NEW)
98
+ │ │ └── data.md # Data Engineer (NEW)
99
+ │ ├── rules/
100
+ │ │ └── coding-standards.md # Dynamic rules based on stack & rigor
101
+ │ ├── project-context.md # High-level context for AI
102
+ │ └── antigravity.json # Persisted configuration
103
+ ├── .cursor/rules/ # Cursor IDE rules (if selected)
104
+ ├── .windsurf/rules/ # Windsurf IDE rules (if selected)
105
+ └── .gemini/settings.json # Gemini Code Assist (if selected)
106
+ ```
107
+
108
+ ## 🛠️ Supported Stacks
109
+
110
+ ### Frontend
111
+
112
+ | Framework | Type |
113
+ | ---------------- | ---------- |
114
+ | React | SPA |
115
+ | Next.js | SSR/SSG |
116
+ | Vue.js | SPA |
117
+ | Nuxt.js | SSR/SSG |
118
+ | Angular | SPA |
119
+ | Svelte/SvelteKit | SPA/SSR |
120
+ | Remix | SSR |
121
+ | Astro | SSG |
122
+ | Flutter | Mobile/Web |
123
+ | React Native | Mobile |
124
+
125
+ ### Backend
126
+
127
+ | Framework | Language |
128
+ | -------------- | ---------- |
129
+ | NestJS | TypeScript |
130
+ | Express | JavaScript |
131
+ | Fastify | TypeScript |
132
+ | FastAPI | Python |
133
+ | Django | Python |
134
+ | Flask | Python |
135
+ | ASP.NET Core | C# |
136
+ | Spring Boot | Java |
137
+ | Go/Gin | Go |
138
+ | Rust | Rust |
139
+ | Elixir/Phoenix | Elixir |
140
+
141
+ ### Databases
142
+
143
+ | Relational | NoSQL | Cloud |
144
+ | ---------- | --------- | ----------- |
145
+ | PostgreSQL | MongoDB | Supabase |
146
+ | MySQL | Redis | Firebase |
147
+ | SQL Server | Cassandra | DynamoDB |
148
+ | Oracle | | PlanetScale |
149
+ | SQLite | | Neon |
150
+
151
+ ### Smart Contracts
152
+
153
+ | Platform | Framework |
154
+ | --------- | --------- |
155
+ | Radix | Scrypto |
156
+ | Ethereum | Solidity |
157
+ | Solana | Anchor |
158
+ | Sui/Aptos | Move |
159
+ | Polkadot | ink! |
160
+
161
+ ## 🎭 Available Roles
162
+
163
+ | Role | Description |
164
+ | ----------------- | ----------------------------------- |
165
+ | Developer | Standard development loop with TDD |
166
+ | QA | Testing, coverage, security testing |
167
+ | Lead Developer | Code review, standards, mentoring |
168
+ | Architect | System design, ADRs, observability |
169
+ | Product Owner | Backlog, INVEST, DoD/DoR |
170
+ | Business Analyst | DDD, Event Storming, specs |
171
+ | **DevOps** | CI/CD, IaC, monitoring |
172
+ | **Security** | Audits, pentesting, compliance |
173
+ | **Tech Writer** | API docs, guides, standards |
174
+ | **Data Engineer** | Pipelines, ETL, data quality |
175
+
176
+ ## 🤝 Contributing
177
+
178
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
179
+
180
+ ## 📄 License
181
+
182
+ [MIT](https://choosealicense.com/licenses/mit/)
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const path = __importStar(require("path"));
39
+ const commands_1 = require("../src/commands");
40
+ const core_1 = require("../src/core");
41
+ const adapters_1 = require("../src/adapters");
42
+ const program = new commander_1.Command();
43
+ // Wired Dependencies (Pure DI)
44
+ const logger = new adapters_1.ConsoleLoggerAdapter();
45
+ const fileSystem = new adapters_1.NodeFileSystemAdapter();
46
+ const templatesDir = path.join(__dirname, '../src/templates');
47
+ const localesDir = path.join(__dirname, '../src/locales');
48
+ const localizationService = new adapters_1.JsonLocalizationAdapter(localesDir);
49
+ // Allow override from .agent/templates
50
+ const customTemplatesDir = path.join(process.cwd(), '.agent/templates');
51
+ const templateProvider = new adapters_1.EjsTemplateAdapter(templatesDir, customTemplatesDir);
52
+ const rulesComposer = new core_1.RulesComposer(templateProvider, localizationService);
53
+ const contextGenerator = new core_1.ContextGenerator(templateProvider, localizationService);
54
+ const pipelineGenerator = new core_1.PipelineGenerator(fileSystem, templateProvider, logger);
55
+ const configService = new core_1.ConfigService(fileSystem, logger);
56
+ const stackDetector = new core_1.StackDetector(fileSystem, logger);
57
+ const gitignoreGenerator = new core_1.GitignoreGenerator(fileSystem, logger);
58
+ const dockerfileGenerator = new core_1.DockerfileGenerator(fileSystem, templateProvider, logger);
59
+ const workflowGenerator = new core_1.WorkflowGenerator(fileSystem, templateProvider, logger, localizationService, rulesComposer, contextGenerator);
60
+ const initCommand = new commands_1.InitCommand(workflowGenerator, logger, localizationService, pipelineGenerator, configService, stackDetector, gitignoreGenerator, dockerfileGenerator, fileSystem);
61
+ const guideCommand = new commands_1.GuideCommand(logger, localizationService, templateProvider, configService);
62
+ const templatesCommand = new commands_1.TemplatesCommand(logger, localizationService, templatesDir, customTemplatesDir);
63
+ program
64
+ .name('antigravity-flow')
65
+ .description('Antigravity Agent Workflow CLI')
66
+ .version('1.0.0');
67
+ program
68
+ .command('init')
69
+ .description('Initialize agent workflows in the current directory')
70
+ .addHelpText('after', `
71
+
72
+ Examples:
73
+ $ ag-flow init
74
+
75
+ Description:
76
+ Starts an interactive wizard to configure the project.
77
+ It will ask for:
78
+ - Project Description
79
+ - Tech Stack (Frontend, Backend, Contracts)
80
+ - Rigor Mode (Strict vs Prototype)
81
+ - Monorepo Configuration
82
+
83
+ It saves configuration to .agent/antigravity.json
84
+ It saves configuration to .agent/antigravity.json
85
+ `)
86
+ .option('-c, --config <path>', 'Path to configuration file')
87
+ .action(async (options) => {
88
+ await initCommand.execute(options);
89
+ });
90
+ program
91
+ .command('guide')
92
+ .description('Show comprehensive usage guide')
93
+ .argument('[lang]', 'Language (en/fr)', 'en')
94
+ .addHelpText('after', `
95
+
96
+ Examples:
97
+ $ ag-flow guide
98
+ $ ag-flow guide fr
99
+
100
+ Description:
101
+ Displays the full user manual in the terminal.
102
+ If .agent/antigravity.json exists, it tries to use the configured language.
103
+ Otherwise, it defaults to English (or the provided argument).
104
+ `)
105
+ .action(async (lang) => {
106
+ await guideCommand.execute(lang);
107
+ await guideCommand.execute(lang);
108
+ });
109
+ program
110
+ .command('templates')
111
+ .description('Manage and customize templates')
112
+ .argument('[action]', 'Action to perform (list, update)', 'list')
113
+ .argument('[template]', 'Template name (for update action)')
114
+ .addHelpText('after', `
115
+
116
+ Examples:
117
+ $ ag-flow templates list
118
+ $ ag-flow templates update docker/django.Dockerfile.ejs
119
+
120
+ Description:
121
+ - list: Shows all available templates and indicates if they are customized.
122
+ - update: Opens the template in your default editor and saves a custom copy to .agent/templates/.
123
+ `)
124
+ .action(async (action, template) => {
125
+ await templatesCommand.execute(action, template);
126
+ });
127
+ program.parse(process.argv);
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ConsoleLoggerAdapter = void 0;
37
+ const chalk = __importStar(require("chalk"));
38
+ class ConsoleLoggerAdapter {
39
+ info(message) {
40
+ console.log(chalk.blue('ℹ'), message);
41
+ }
42
+ warn(message) {
43
+ console.log(chalk.yellow('⚠'), message);
44
+ }
45
+ error(message) {
46
+ console.error(chalk.red('✖'), message);
47
+ }
48
+ success(message) {
49
+ console.log(chalk.green('✔'), message);
50
+ }
51
+ }
52
+ exports.ConsoleLoggerAdapter = ConsoleLoggerAdapter;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.EjsTemplateAdapter = void 0;
37
+ const ejs = __importStar(require("ejs"));
38
+ const path = __importStar(require("path"));
39
+ const fs = __importStar(require("fs-extra"));
40
+ class EjsTemplateAdapter {
41
+ templatesDir;
42
+ customTemplatesDir;
43
+ constructor(templatesDir, customTemplatesDir) {
44
+ this.templatesDir = templatesDir;
45
+ this.customTemplatesDir = customTemplatesDir;
46
+ }
47
+ async getTemplate(templatePath) {
48
+ // 1. Check custom override
49
+ if (this.customTemplatesDir) {
50
+ const customPath = path.join(this.customTemplatesDir, templatePath);
51
+ if (await fs.pathExists(customPath)) {
52
+ return fs.readFile(customPath, 'utf8');
53
+ }
54
+ }
55
+ // 2. Fallback to built-in
56
+ const fullPath = path.join(this.templatesDir, templatePath);
57
+ if (!(await fs.pathExists(fullPath))) {
58
+ throw new Error(`Template not found: ${fullPath}`);
59
+ }
60
+ return fs.readFile(fullPath, 'utf8');
61
+ }
62
+ render(templateContent, data) {
63
+ return ejs.render(templateContent, data);
64
+ }
65
+ }
66
+ exports.EjsTemplateAdapter = EjsTemplateAdapter;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.JsonLocalizationAdapter = void 0;
37
+ const fs = __importStar(require("fs-extra"));
38
+ const path = __importStar(require("path"));
39
+ class JsonLocalizationAdapter {
40
+ localesPath;
41
+ currentLang = 'en';
42
+ translations = {};
43
+ constructor(localesPath) {
44
+ this.localesPath = localesPath;
45
+ }
46
+ setLanguage(lang) {
47
+ this.currentLang = lang;
48
+ this.loadTranslations();
49
+ }
50
+ getLanguage() {
51
+ return this.currentLang;
52
+ }
53
+ translate(key, args) {
54
+ const keys = key.split('.');
55
+ let value = this.translations;
56
+ for (const k of keys) {
57
+ value = value?.[k];
58
+ }
59
+ if (typeof value !== 'string') {
60
+ console.warn(`Translation key '${key}' returned non-string value.`, value);
61
+ return key;
62
+ }
63
+ if (args) {
64
+ for (const [k, v] of Object.entries(args)) {
65
+ value = value.replace(`{{${k}}}`, v);
66
+ }
67
+ }
68
+ return value;
69
+ }
70
+ loadTranslations() {
71
+ const filePath = path.join(this.localesPath, `${this.currentLang}.json`);
72
+ if (fs.existsSync(filePath)) {
73
+ this.translations = fs.readJSONSync(filePath);
74
+ }
75
+ else {
76
+ console.warn(`Locale file not found: ${filePath}`);
77
+ this.translations = {};
78
+ }
79
+ }
80
+ }
81
+ exports.JsonLocalizationAdapter = JsonLocalizationAdapter;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.NodeFileSystemAdapter = void 0;
37
+ const fs = __importStar(require("fs-extra"));
38
+ class NodeFileSystemAdapter {
39
+ async exists(path) {
40
+ return fs.pathExists(path);
41
+ }
42
+ async readFile(path) {
43
+ return fs.readFile(path, 'utf8');
44
+ }
45
+ async writeFile(path, content) {
46
+ await fs.writeFile(path, content, 'utf8');
47
+ }
48
+ async createDirectory(path) {
49
+ await fs.ensureDir(path);
50
+ }
51
+ }
52
+ exports.NodeFileSystemAdapter = NodeFileSystemAdapter;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./NodeFileSystemAdapter"), exports);
18
+ __exportStar(require("./ConsoleLoggerAdapter"), exports);
19
+ __exportStar(require("./EjsTemplateAdapter"), exports);
20
+ __exportStar(require("./JsonLocalizationAdapter"), exports);
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.GuideCommand = void 0;
37
+ const path = __importStar(require("path"));
38
+ class GuideCommand {
39
+ logger;
40
+ localizationService;
41
+ templateProvider;
42
+ configService;
43
+ constructor(logger, localizationService, templateProvider, configService) {
44
+ this.logger = logger;
45
+ this.localizationService = localizationService;
46
+ this.templateProvider = templateProvider;
47
+ this.configService = configService;
48
+ }
49
+ async execute(language) {
50
+ try {
51
+ // 1. Determine Language
52
+ let lang = language;
53
+ if (!lang) {
54
+ // Try to load from config
55
+ const projectRoot = process.cwd();
56
+ try {
57
+ const config = await this.configService.loadConfig(projectRoot);
58
+ if (config && config.language) {
59
+ lang = config.language;
60
+ }
61
+ }
62
+ catch (e) {
63
+ // Ignore config load error, default to English
64
+ }
65
+ }
66
+ lang = lang || 'en';
67
+ this.localizationService.setLanguage(lang);
68
+ // 2. Load Guide Template
69
+ // Template provider usually expects paths relative to templates dir
70
+ // e.g. "en/guide.txt"
71
+ const templatePath = path.join(lang, 'guide.txt');
72
+ try {
73
+ const content = await this.templateProvider.getTemplate(templatePath);
74
+ // 3. Print
75
+ console.log(content);
76
+ }
77
+ catch (e) {
78
+ this.logger.error(`Could not load guide for language '${lang}'. Falling back to English.`);
79
+ const fallbackPath = path.join('en', 'guide.txt');
80
+ const content = await this.templateProvider.getTemplate(fallbackPath);
81
+ console.log(content);
82
+ }
83
+ }
84
+ catch (error) {
85
+ this.logger.error(`Failed to show guide: ${error.message}`);
86
+ }
87
+ }
88
+ }
89
+ exports.GuideCommand = GuideCommand;