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.
- package/README.md +182 -0
- package/dist/bin/ag-flow.js +127 -0
- package/dist/src/adapters/ConsoleLoggerAdapter.js +52 -0
- package/dist/src/adapters/EjsTemplateAdapter.js +66 -0
- package/dist/src/adapters/JsonLocalizationAdapter.js +81 -0
- package/dist/src/adapters/NodeFileSystemAdapter.js +52 -0
- package/dist/src/adapters/index.js +20 -0
- package/dist/src/commands/guide.js +89 -0
- package/dist/src/commands/index.js +19 -0
- package/dist/src/commands/init.js +581 -0
- package/dist/src/commands/templates.js +143 -0
- package/dist/src/core/ConfigService.js +75 -0
- package/dist/src/core/ContextGenerator.js +27 -0
- package/dist/src/core/DockerfileGenerator.js +151 -0
- package/dist/src/core/GitignoreGenerator.js +129 -0
- package/dist/src/core/PipelineGenerator.js +68 -0
- package/dist/src/core/RulesComposer.js +62 -0
- package/dist/src/core/StackDetector.js +115 -0
- package/dist/src/core/WorkflowGenerator.js +137 -0
- package/dist/src/core/index.js +26 -0
- package/dist/src/core/interfaces.js +2 -0
- package/dist/src/core/pipelines/PipelineStrategy.js +97 -0
- package/dist/src/core/types.js +300 -0
- package/dist/src/locales/en.json +293 -0
- package/dist/src/locales/fr.json +293 -0
- package/dist/src/templates/docker/django.Dockerfile.ejs +21 -0
- package/dist/src/templates/docker/dockerignore.ejs +12 -0
- package/dist/src/templates/docker/go.Dockerfile.ejs +20 -0
- package/dist/src/templates/docker/nestjs.Dockerfile.ejs +25 -0
- package/dist/src/templates/docker/node.Dockerfile.ejs +13 -0
- package/dist/src/templates/docker/python.Dockerfile.ejs +13 -0
- package/dist/src/templates/docker/springboot.Dockerfile.ejs +25 -0
- package/dist/src/templates/en/architect.md.ejs +85 -0
- package/dist/src/templates/en/ba.md.ejs +88 -0
- package/dist/src/templates/en/data.md.ejs +47 -0
- package/dist/src/templates/en/dev.md.ejs +77 -0
- package/dist/src/templates/en/devops.md.ejs +54 -0
- package/dist/src/templates/en/fragments/arch/feature-sliced.md.ejs +12 -0
- package/dist/src/templates/en/fragments/arch/hexagonal.md.ejs +14 -0
- package/dist/src/templates/en/fragments/arch/mvc.md.ejs +11 -0
- package/dist/src/templates/en/fragments/aspnet-core.md.ejs +11 -0
- package/dist/src/templates/en/fragments/base-rules.md.ejs +5 -0
- package/dist/src/templates/en/fragments/django.md.ejs +12 -0
- package/dist/src/templates/en/fragments/fastapi.md.ejs +11 -0
- package/dist/src/templates/en/fragments/flutter.md.ejs +11 -0
- package/dist/src/templates/en/fragments/nestjs.md.ejs +5 -0
- package/dist/src/templates/en/fragments/nextjs.md.ejs +10 -0
- package/dist/src/templates/en/fragments/react-native.md.ejs +12 -0
- package/dist/src/templates/en/fragments/react.md.ejs +5 -0
- package/dist/src/templates/en/fragments/rigor/legacy.md.ejs +6 -0
- package/dist/src/templates/en/fragments/rigor/prototype.md.ejs +6 -0
- package/dist/src/templates/en/fragments/rigor/strict.md.ejs +7 -0
- package/dist/src/templates/en/fragments/rust.md.ejs +11 -0
- package/dist/src/templates/en/fragments/scrypto.md.ejs +8 -0
- package/dist/src/templates/en/fragments/solidity.md.ejs +20 -0
- package/dist/src/templates/en/fragments/spring-boot.md.ejs +13 -0
- package/dist/src/templates/en/guide.txt +48 -0
- package/dist/src/templates/en/lead.md.ejs +76 -0
- package/dist/src/templates/en/pipelines/github-dotnet.yml.ejs +24 -0
- package/dist/src/templates/en/pipelines/github-flutter.yml.ejs +24 -0
- package/dist/src/templates/en/pipelines/github-nestjs.yml.ejs +26 -0
- package/dist/src/templates/en/pipelines/github-react.yml.ejs +26 -0
- package/dist/src/templates/en/pipelines/github-rust.yml.ejs +38 -0
- package/dist/src/templates/en/pipelines/github-scrypto.yml.ejs +34 -0
- package/dist/src/templates/en/po.md.ejs +86 -0
- package/dist/src/templates/en/project-context.md.ejs +26 -0
- package/dist/src/templates/en/qa.md.ejs +103 -0
- package/dist/src/templates/en/rules.md.ejs +30 -0
- package/dist/src/templates/en/security.md.ejs +55 -0
- package/dist/src/templates/en/techwriter.md.ejs +46 -0
- package/dist/src/templates/fr/architect.md.ejs +15 -0
- package/dist/src/templates/fr/ba.md.ejs +11 -0
- package/dist/src/templates/fr/data.md.ejs +47 -0
- package/dist/src/templates/fr/dev.md.ejs +11 -0
- package/dist/src/templates/fr/devops.md.ejs +54 -0
- package/dist/src/templates/fr/fragments/arch/feature-sliced.md.ejs +12 -0
- package/dist/src/templates/fr/fragments/arch/hexagonal.md.ejs +14 -0
- package/dist/src/templates/fr/fragments/arch/mvc.md.ejs +11 -0
- package/dist/src/templates/fr/fragments/aspnet-core.md.ejs +11 -0
- package/dist/src/templates/fr/fragments/flutter.md.ejs +11 -0
- package/dist/src/templates/fr/fragments/rigor/legacy.md.ejs +6 -0
- package/dist/src/templates/fr/fragments/rigor/prototype.md.ejs +6 -0
- package/dist/src/templates/fr/fragments/rigor/strict.md.ejs +7 -0
- package/dist/src/templates/fr/fragments/rust.md.ejs +10 -0
- package/dist/src/templates/fr/fragments/scrypto.md.ejs +8 -0
- package/dist/src/templates/fr/guide.txt +47 -0
- package/dist/src/templates/fr/lead.md.ejs +12 -0
- package/dist/src/templates/fr/po.md.ejs +11 -0
- package/dist/src/templates/fr/project-context.md.ejs +28 -0
- package/dist/src/templates/fr/qa.md.ejs +14 -0
- package/dist/src/templates/fr/rules.md.ejs +30 -0
- package/dist/src/templates/fr/security.md.ejs +55 -0
- package/dist/src/templates/fr/techwriter.md.ejs +46 -0
- package/dist/src/templates/gitignore/dotnet.txt +6 -0
- package/dist/src/templates/gitignore/go.txt +15 -0
- package/dist/src/templates/gitignore/java.txt +4 -0
- package/dist/src/templates/gitignore/jetbrains.txt +4 -0
- package/dist/src/templates/gitignore/linux.txt +5 -0
- package/dist/src/templates/gitignore/macos.txt +3 -0
- package/dist/src/templates/gitignore/node.txt +11 -0
- package/dist/src/templates/gitignore/python.txt +10 -0
- package/dist/src/templates/gitignore/rust.txt +3 -0
- package/dist/src/templates/gitignore/solidity.txt +19 -0
- package/dist/src/templates/gitignore/vscode.txt +6 -0
- package/dist/src/templates/gitignore/windows.txt +4 -0
- package/dist/tests/commands/InitCommand.spec.js +529 -0
- package/dist/tests/commands/InitConfig.spec.js +108 -0
- package/dist/tests/core/ConfigService.spec.js +97 -0
- package/dist/tests/core/ContextGenerator.spec.js +51 -0
- package/dist/tests/core/PipelineGenerator.spec.js +206 -0
- package/dist/tests/core/RulesComposer.spec.js +89 -0
- package/dist/tests/core/StackDetector.spec.js +69 -0
- package/dist/tests/core/Types.spec.js +243 -0
- package/dist/tests/core/WorkflowGenerator.spec.js +99 -0
- 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;
|