agent-workflow-kit-cli 1.0.0-mvp
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/LICENSE +21 -0
- package/README.md +303 -0
- package/dist/cli/commands/doctor.js +96 -0
- package/dist/cli/commands/export.js +118 -0
- package/dist/cli/commands/init.js +163 -0
- package/dist/cli/commands/sync.js +12 -0
- package/dist/cli/index.js +72 -0
- package/dist/core/detector.js +123 -0
- package/dist/core/emitter.js +119 -0
- package/dist/core/renderer.js +70 -0
- package/dist/index.js +7 -0
- package/dist/utils/clipboard.js +36 -0
- package/package.json +35 -0
- package/templates/common/AGENTS.md.hbs +44 -0
- package/templates/fastapi/AGENTS.md.hbs +28 -0
- package/templates/fastapi/rules/python-style.md +22 -0
- package/templates/fastapi/skills/fastapi-feature/SKILL.md +18 -0
- package/templates/react-ts/AGENTS.md.hbs +47 -0
- package/templates/react-ts/rules/react-style.md +34 -0
- package/templates/react-ts/skills/react-feature/SKILL.md +25 -0
- package/templates/spring-boot/AGENTS.md.hbs +79 -0
- package/templates/spring-boot/rules/java-style.md +14 -0
- package/templates/spring-boot/skills/spring-feature/SKILL.md +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TruongTXK18FPT
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/TruongTXK18FPT/agent-workflow-kit-cli/main/src/assets/Logo.png" alt="agent-workflow-kit-cli Logo" width="180" style="border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.15);" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">agent-workflow-kit-cli</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>A Repo-First AI Workflow Generator & Guideline Optimizer for Codex and Antigravity</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center" style="display: flex; align-items: center; justify-content: center; gap: 20px;">
|
|
12
|
+
<span>Designed & Optimized for:</span>
|
|
13
|
+
<br />
|
|
14
|
+
<a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli" style="text-decoration: none; display: inline-flex; align-items: center; gap: 6px; font-weight: bold; color: #fff;">
|
|
15
|
+
<img src="src/assets/Codex.png" alt="Codex Logo" width="24" style="vertical-align: middle; border-radius: 4px;" /> Codex
|
|
16
|
+
</a>
|
|
17
|
+
<span style="color: #4b5563;">|</span>
|
|
18
|
+
<a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli" style="text-decoration: none; display: inline-flex; align-items: center; gap: 6px; font-weight: bold; color: #fff;">
|
|
19
|
+
<img src="src/assets/Antigravity.webp" alt="Antigravity Logo" width="24" style="vertical-align: middle; border-radius: 4px;" /> Antigravity
|
|
20
|
+
</a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli">
|
|
25
|
+
<img src="https://img.shields.io/github/license/TruongTXK18FPT/agent-workflow-kit-cli?style=for-the-badge&color=blue" alt="License" />
|
|
26
|
+
</a>
|
|
27
|
+
<a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli/stargazers">
|
|
28
|
+
<img src="https://img.shields.io/github/stars/TruongTXK18FPT/agent-workflow-kit-cli?style=for-the-badge&color=gold" alt="Stars" />
|
|
29
|
+
</a>
|
|
30
|
+
<a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli/issues">
|
|
31
|
+
<img src="https://img.shields.io/github/issues/TruongTXK18FPT/agent-workflow-kit-cli?style=for-the-badge&color=red" alt="Issues" />
|
|
32
|
+
</a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## š Introduction
|
|
38
|
+
|
|
39
|
+
`agent-workflow-kit-cli` is an open-source, CLI-driven **repo-first workflow package generator** built specifically for software development teams utilizing AI coding agents like **OpenAI Codex** and **Google Antigravity**.
|
|
40
|
+
|
|
41
|
+
Rather than relying on model fine-tuning or heavy ad-hoc prompting, this kit allows you to generate standardized coding structures, workspace rule-bases, custom skill files, and automated testing validations directly inside your repository. By placing machine-readable instructions directly in your repository layout (`AGENTS.md`, `.agents/skills`, `.agents/rules`), AI agents are instantly aligned with your technology stacks, architecture principles, formatting conventions, and done criteria from their very first command.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## ā” Key Features
|
|
46
|
+
|
|
47
|
+
- **Automatic Stack Detection:** Scans repository manifests (`pom.xml`, `package.json`, `pyproject.toml`) to automatically configure directory architectures and templates.
|
|
48
|
+
- **Unified Multi-Agent Compatibility:** Seamlessly generates standard instructions compatible with both Codex (`AGENTS.md`) and Antigravity (`GEMINI.md`).
|
|
49
|
+
- **Standardized Skills & Rules:** Auto-emits persistent agent skills (slash command extensions) and syntax/lint constraints.
|
|
50
|
+
- **Opinionated Architectural Presets:** Encourages clean-ish, modular layouts (e.g. `feature-first` structure) that minimize AI token consumption and narrow down execution context.
|
|
51
|
+
- **Verification Hook Validation:** Integrates with local toolchains (Maven verify, Vitest, Ruff, pytest, Checkstyle, Spotless) to verify agent edits before commits.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## šļø Core Architecture
|
|
56
|
+
|
|
57
|
+
The kit is structured around a decoupled pipelines approach to separate stack logic from specific agent formats.
|
|
58
|
+
|
|
59
|
+
```mermaid
|
|
60
|
+
flowchart TB
|
|
61
|
+
A[npx agent-workflow-kit-cli] --> B[CLI Commands: init / add / sync / doctor]
|
|
62
|
+
B --> C[Core Parser & Orchestrator]
|
|
63
|
+
C --> D[Stack Detectors: Maven / NPM / Poetry]
|
|
64
|
+
C --> E[Stack Packs: Spring Boot / React / FastAPI]
|
|
65
|
+
C --> F[Agent Emitters: Codex / Antigravity]
|
|
66
|
+
|
|
67
|
+
F --> G1[AGENTS.md & GEMINI.md]
|
|
68
|
+
F --> G2[.agents/skills/*.md]
|
|
69
|
+
F --> G3[.agents/rules/*.md]
|
|
70
|
+
F --> G4[.codex/rules/*.rules]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Module Structure
|
|
74
|
+
|
|
75
|
+
- **`src/cli/`**: Parses commands and argument settings via Commander.
|
|
76
|
+
- **`src/core/`**: Controls code generation flow, schemas, file merges, and dry-run comparisons.
|
|
77
|
+
- **`src/detectors/`**: Identifies local build configurations and monorepos.
|
|
78
|
+
- **`src/presets/`**: Manages default templates for architectural designs, styles, linters, tests, and CI/CD pipelines.
|
|
79
|
+
- **`src/packs/`**: Holds modular logic packs for Spring Boot, React + TS, and FastAPI.
|
|
80
|
+
- **`src/emitters/`**: Translates templates into target markdown configs.
|
|
81
|
+
- **`templates/`**: Multi-language Handlebars templates.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## š¦ Supported Stack Packs & Workflows
|
|
86
|
+
|
|
87
|
+
### ā Java Spring Boot Pack
|
|
88
|
+
Designed for robust enterprise backend environments.
|
|
89
|
+
- **Default Architecture:** Feature-first modular packages containing inner layers (dto, entity, repository, mapper, service, web).
|
|
90
|
+
- **Tooling Defaults:** Checkstyle (coding formatting), Spotless (auto-format validation), Maven compiler (Java 17+).
|
|
91
|
+
- **Test Slices:** Service Unit Tests, Web Controllers (`@WebMvcTest`), JPA repositories (`@DataJpaTest`).
|
|
92
|
+
|
|
93
|
+
#### Spring Boot Folder Structure Example:
|
|
94
|
+
```text
|
|
95
|
+
src/main/java/com/acme/app/
|
|
96
|
+
customer/
|
|
97
|
+
dto/
|
|
98
|
+
CreateCustomerRequest.java
|
|
99
|
+
CustomerResponse.java
|
|
100
|
+
entity/
|
|
101
|
+
Customer.java
|
|
102
|
+
mapper/
|
|
103
|
+
CustomerMapper.java
|
|
104
|
+
repository/
|
|
105
|
+
CustomerRepository.java
|
|
106
|
+
service/
|
|
107
|
+
CustomerService.java
|
|
108
|
+
impl/CustomerServiceImpl.java
|
|
109
|
+
web/
|
|
110
|
+
CustomerController.java
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### āļø React + TypeScript Pack
|
|
116
|
+
Tailored for scalable component-driven frontend developments.
|
|
117
|
+
- **Default Architecture:** Feature-first modules with localized state hooks, routing wrappers, and style files.
|
|
118
|
+
- **Tooling Defaults:** Vite (bundler), TypeScript Strict Compiler Settings, ESLint Flat Config, Prettier.
|
|
119
|
+
- **Test Slices:** React Testing Library + Vitest + jest-dom.
|
|
120
|
+
|
|
121
|
+
#### React + TypeScript Configs:
|
|
122
|
+
```ts
|
|
123
|
+
// eslint.config.mjs
|
|
124
|
+
import js from "@eslint/js";
|
|
125
|
+
import tseslint from "typescript-eslint";
|
|
126
|
+
|
|
127
|
+
export default tseslint.config(
|
|
128
|
+
js.configs.recommended,
|
|
129
|
+
...tseslint.configs.recommended,
|
|
130
|
+
{
|
|
131
|
+
files: ["src/**/*.{ts,tsx}"],
|
|
132
|
+
rules: {
|
|
133
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
134
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### š Python FastAPI Pack
|
|
143
|
+
Optimized for high-performance python API layers.
|
|
144
|
+
- **Default Architecture:** Feature router packages with localized schema, service, and database models.
|
|
145
|
+
- **Tooling Defaults:** Ruff (extremely fast Python linter & formatter), mypy (strict type-checking), Python 3.11+.
|
|
146
|
+
- **Test Slices:** Pytest + TestClient (HTTPX).
|
|
147
|
+
|
|
148
|
+
#### FastAPI Configuration:
|
|
149
|
+
```toml
|
|
150
|
+
# pyproject.toml
|
|
151
|
+
[tool.ruff]
|
|
152
|
+
line-length = 100
|
|
153
|
+
|
|
154
|
+
[tool.ruff.lint]
|
|
155
|
+
select = ["E", "F", "I", "B", "UP"]
|
|
156
|
+
|
|
157
|
+
[tool.mypy]
|
|
158
|
+
python_version = "3.11"
|
|
159
|
+
strict = true
|
|
160
|
+
packages = ["src"]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## š Quick Start
|
|
166
|
+
|
|
167
|
+
Initialize the toolkit instantly inside your project repository using `npx` (no local installation required):
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# 1. Initialize rules and custom skills for the project
|
|
171
|
+
npx agent-workflow-kit-cli init
|
|
172
|
+
|
|
173
|
+
# 2. View the generated AGENTS.md guidelines at your repository root
|
|
174
|
+
cat AGENTS.md
|
|
175
|
+
|
|
176
|
+
# 3. Export custom skills to register them with Antigravity
|
|
177
|
+
npx agent-workflow-kit-cli export antigravity
|
|
178
|
+
|
|
179
|
+
# 4. Enable pre-commit auto-validation hook
|
|
180
|
+
npx agent-workflow-kit-cli doctor --install-hook
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## š ļø CLI Reference
|
|
186
|
+
|
|
187
|
+
You can run `agent-workflow-kit-cli` directly via `npx` or install it locally:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npx agent-workflow-kit-cli <command> [options]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 1. `init`
|
|
194
|
+
Analyzes the directory manifests (`package.json`, `pom.xml`, `pyproject.toml`) and bootstraps agent guidelines (`AGENTS.md`) and custom skills (`.agents/`).
|
|
195
|
+
|
|
196
|
+
* **Usage:** `npx agent-workflow-kit-cli init [options]`
|
|
197
|
+
* **Options:**
|
|
198
|
+
* `--stack <stack>`: Specify the target project stack.
|
|
199
|
+
* Values: `auto`, `spring-boot`, `react-ts`, `fastapi`
|
|
200
|
+
* Default: `auto` (auto-detects project manifests)
|
|
201
|
+
* `--agent <agent>`: Target profile settings.
|
|
202
|
+
* Values: `both`, `codex`, `antigravity`
|
|
203
|
+
* Default: `both`
|
|
204
|
+
* `--dry-run`: Run the command in simulation mode. Logs actions to the console without writing any files to disk.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### 2. `sync`
|
|
209
|
+
Re-evaluates the manifests and updates existing guidelines/skills inside the workspace without touching user modifications. It writes changes inside the `<!-- AWK-START: <id> -->` managed blocks.
|
|
210
|
+
|
|
211
|
+
* **Usage:** `npx agent-workflow-kit-cli sync [options]`
|
|
212
|
+
* **Options:**
|
|
213
|
+
* `--dry-run`: Simulation mode. Logs planned sync modifications to the console without updating files.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### 3. `doctor`
|
|
218
|
+
Checks consistency of active agent configurations, environment setups, and executes the validation test commands configured for detected stacks.
|
|
219
|
+
|
|
220
|
+
* **Usage:** `npx agent-workflow-kit-cli doctor [options]`
|
|
221
|
+
* **Options:**
|
|
222
|
+
* `--install-hook`: Installs a local Git `pre-commit` hook to automatically trigger `doctor` checks before commit validation. If the checks fail, the commit is aborted.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### 4. `export <target>`
|
|
227
|
+
Exports and bundles custom workflows and skills in `.agents/skills/` into a single consolidated string optimized for the target AI agent console.
|
|
228
|
+
|
|
229
|
+
* **Usage:** `npx agent-workflow-kit-cli export <target> [options]`
|
|
230
|
+
* **Arguments:**
|
|
231
|
+
* `<target>`: The name of the target agent (e.g., `antigravity`).
|
|
232
|
+
* **Options:**
|
|
233
|
+
* `--no-clipboard`: Prevents the CLI from copying the bundled instructions directly to the system clipboard (by default, it will attempt to copy to the clipboard first, fallback to printing on stdout).
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## š¤ Agent Integration Details
|
|
238
|
+
|
|
239
|
+
### Shared Directives Layer (`AGENTS.md`)
|
|
240
|
+
Placed in the workspace root, `AGENTS.md` is automatically ingested at the beginning of the agent session. It sets expectations for file naming, layering constraints, package manager usage, and completion checklists.
|
|
241
|
+
|
|
242
|
+
### Slash-Command Skills (`.agents/skills/`)
|
|
243
|
+
Custom agent capabilities are placed inside `.agents/skills/<skill-name>/SKILL.md`. Both Codex and Antigravity ingest these to expose custom workflows invoked via commands (like `/spring-feature` or `/react-route`).
|
|
244
|
+
|
|
245
|
+
#### Typical `SKILL.md` Example:
|
|
246
|
+
```md
|
|
247
|
+
---
|
|
248
|
+
name: react-feature
|
|
249
|
+
description: Generates custom React component hooks and routes
|
|
250
|
+
---
|
|
251
|
+
Inputs:
|
|
252
|
+
- component name
|
|
253
|
+
- target path
|
|
254
|
+
|
|
255
|
+
Steps:
|
|
256
|
+
1. Examine neighboring route components
|
|
257
|
+
2. Create types.ts contract
|
|
258
|
+
3. Implement hooks and main UI components
|
|
259
|
+
4. Run validation checks: npm run lint && npm run build
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Antigravity-Specific Constraints (`.agents/rules/`)
|
|
263
|
+
Google Antigravity rules are written as Markdown documents in `.agents/rules/*.md`.
|
|
264
|
+
> [!IMPORTANT]
|
|
265
|
+
> Antigravity enforces a strict limit of **12,000 characters** per rule file. Keep generated rules thin and refer to external documents like `@AGENTS.md` to avoid truncations.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## š§Ŗ Development & Testing
|
|
270
|
+
|
|
271
|
+
We maintain a rigorous pipeline to test changes made to this CLI toolkit.
|
|
272
|
+
|
|
273
|
+
### Local Setup
|
|
274
|
+
Ensure you have Node.js 20+ installed. Clone the repository and install dependencies:
|
|
275
|
+
```bash
|
|
276
|
+
git clone https://github.com/TruongTXK18FPT/agent-workflow-kit-cli.git
|
|
277
|
+
cd agent-workflow-kit-cli
|
|
278
|
+
npm install
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Running Tests
|
|
282
|
+
We use **Vitest** for testing:
|
|
283
|
+
- **Unit Tests:** Validates manifest detectors and template parsing.
|
|
284
|
+
- **Fixture Tests:** Performs snapshot checks against baseline directories to check for file output drifts.
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Run all vitest suites
|
|
288
|
+
npm test
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## āļø License
|
|
294
|
+
|
|
295
|
+
Distributed under the MIT License. See `LICENSE` for more details.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
<p align="center">
|
|
300
|
+
For more details, issues, and feature requests, visit the official repository:
|
|
301
|
+
<br />
|
|
302
|
+
<strong><a href="https://github.com/TruongTXK18FPT/agent-workflow-kit-cli">https://github.com/TruongTXK18FPT/agent-workflow-kit-cli</a></strong>
|
|
303
|
+
</p>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { promises as fs } from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { execa } from "execa";
|
|
9
|
+
import { detectProjectStack } from "../../core/detector.js";
|
|
10
|
+
export async function runDoctor(options) {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
if (options.installHook) {
|
|
13
|
+
console.log(chalk.blue("Installing Git pre-commit hook..."));
|
|
14
|
+
const gitPath = path.join(cwd, ".git");
|
|
15
|
+
try {
|
|
16
|
+
const gitStat = await fs.stat(gitPath);
|
|
17
|
+
if (!gitStat.isDirectory()) {
|
|
18
|
+
throw new Error(".git is not a directory");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
console.error(chalk.red("Error: Git repository not detected in the current directory."));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const hooksPath = path.join(gitPath, "hooks");
|
|
26
|
+
await fs.mkdir(hooksPath, { recursive: true });
|
|
27
|
+
const preCommitPath = path.join(hooksPath, "pre-commit");
|
|
28
|
+
const hookScript = `#!/bin/sh
|
|
29
|
+
# AWK-START: DOCTOR_HOOK
|
|
30
|
+
npx agent-workflow-kit-cli doctor || exit 1
|
|
31
|
+
# AWK-END: DOCTOR_HOOK
|
|
32
|
+
`;
|
|
33
|
+
let existingHook = "";
|
|
34
|
+
try {
|
|
35
|
+
existingHook = await fs.readFile(preCommitPath, "utf8");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// File doesn't exist
|
|
39
|
+
}
|
|
40
|
+
if (existingHook.includes("AWK-START: DOCTOR_HOOK")) {
|
|
41
|
+
console.log(chalk.yellow("Git pre-commit hook is already installed."));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const separator = existingHook ? "\n" : "";
|
|
45
|
+
await fs.writeFile(preCommitPath, `${existingHook}${separator}${hookScript}`, "utf8");
|
|
46
|
+
// Make it executable (cross-platform safe)
|
|
47
|
+
try {
|
|
48
|
+
await fs.chmod(preCommitPath, 0o755);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
console.warn(chalk.yellow(`Could not set executable permissions on hook: ${err instanceof Error ? err.message : String(err)}`));
|
|
52
|
+
}
|
|
53
|
+
console.log(chalk.green("Git pre-commit hook installed successfully!"));
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log(chalk.blue("Running doctor checks on repository..."));
|
|
58
|
+
// 1. Detect Stack
|
|
59
|
+
const stacks = await detectProjectStack(cwd);
|
|
60
|
+
console.log(chalk.gray(`Detected stacks: ${stacks.join(", ") || "None"}`));
|
|
61
|
+
if (stacks.length === 0) {
|
|
62
|
+
console.log(chalk.yellow("No standard stack pack detected. Nothing to validate."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// 2. Validate
|
|
66
|
+
let passed = true;
|
|
67
|
+
for (const stack of stacks) {
|
|
68
|
+
console.log(chalk.blue(`\nValidating stack: ${stack}...`));
|
|
69
|
+
try {
|
|
70
|
+
if (stack === "spring-boot") {
|
|
71
|
+
console.log(chalk.gray("Running: ./mvnw clean compile"));
|
|
72
|
+
await execa("./mvnw", ["clean", "compile"], { cwd, stdio: "inherit" });
|
|
73
|
+
}
|
|
74
|
+
else if (stack === "fastapi") {
|
|
75
|
+
console.log(chalk.gray("Running: ruff check ."));
|
|
76
|
+
await execa("ruff", ["check", "."], { cwd, stdio: "inherit" });
|
|
77
|
+
}
|
|
78
|
+
else if (stack === "react-ts") {
|
|
79
|
+
console.log(chalk.gray("Running: npx tsc --noEmit"));
|
|
80
|
+
await execa("npx", ["tsc", "--noEmit"], { cwd, stdio: "inherit" });
|
|
81
|
+
}
|
|
82
|
+
console.log(chalk.green(`āļø ${stack} validation passed!`));
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.error(chalk.red(`ā ${stack} validation failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
86
|
+
passed = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (passed) {
|
|
90
|
+
console.log(chalk.green("\nš All doctor checks passed successfully!"));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.error(chalk.red("\nā Some doctor checks failed. Please fix the issues before proceeding."));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { promises as fs } from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { writeToClipboard } from "../../utils/clipboard.js";
|
|
9
|
+
/**
|
|
10
|
+
* Recursively find all skill files (.md or SKILL.md) in a directory.
|
|
11
|
+
*/
|
|
12
|
+
async function findSkillFiles(dir) {
|
|
13
|
+
const files = [];
|
|
14
|
+
try {
|
|
15
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const fullPath = path.join(dir, entry.name);
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
files.push(...(await findSkillFiles(fullPath)));
|
|
20
|
+
}
|
|
21
|
+
else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
22
|
+
files.push(fullPath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Ignore if directory doesn't exist
|
|
28
|
+
}
|
|
29
|
+
return files;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse a markdown file with optional YAML frontmatter.
|
|
33
|
+
*/
|
|
34
|
+
export function parseSkillFile(content, defaultName) {
|
|
35
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
|
|
36
|
+
const match = content.match(frontmatterRegex);
|
|
37
|
+
let name = defaultName;
|
|
38
|
+
let description = "";
|
|
39
|
+
let body = content;
|
|
40
|
+
if (match) {
|
|
41
|
+
const yamlText = match[1];
|
|
42
|
+
body = match[2];
|
|
43
|
+
const lines = yamlText.split("\n");
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
const colonIndex = line.indexOf(":");
|
|
46
|
+
if (colonIndex !== -1) {
|
|
47
|
+
const key = line.slice(0, colonIndex).trim().toLowerCase();
|
|
48
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
49
|
+
if (key === "name") {
|
|
50
|
+
name = value.replace(/^['"]|['"]$/g, ""); // strip quotes
|
|
51
|
+
}
|
|
52
|
+
else if (key === "description") {
|
|
53
|
+
description = value.replace(/^['"]|['"]$/g, ""); // strip quotes
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { name, description, body: body.trim() };
|
|
59
|
+
}
|
|
60
|
+
export async function runExport(target, options) {
|
|
61
|
+
if (target.toLowerCase() !== "antigravity") {
|
|
62
|
+
console.warn(chalk.yellow(`Warning: Currently, only 'antigravity' target is officially optimized, but trying to export custom rules anyway.`));
|
|
63
|
+
}
|
|
64
|
+
const cwd = process.cwd();
|
|
65
|
+
const skillsDir = path.join(cwd, ".agents", "skills");
|
|
66
|
+
console.log(chalk.blue(`Scanning for custom agent skills in ${skillsDir}...`));
|
|
67
|
+
const skillFiles = await findSkillFiles(skillsDir);
|
|
68
|
+
if (skillFiles.length === 0) {
|
|
69
|
+
console.log(chalk.yellow(`No skill files (.md) found under '.agents/skills/'.`));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const parsedSkills = [];
|
|
73
|
+
for (const file of skillFiles) {
|
|
74
|
+
try {
|
|
75
|
+
const content = await fs.readFile(file, "utf8");
|
|
76
|
+
// Default name to parent dir or file name
|
|
77
|
+
const ext = path.extname(file);
|
|
78
|
+
const baseName = path.basename(file, ext);
|
|
79
|
+
const parentDirName = path.basename(path.dirname(file));
|
|
80
|
+
const defaultName = baseName.toLowerCase() === "skill" ? parentDirName : baseName;
|
|
81
|
+
const parsed = parseSkillFile(content, defaultName);
|
|
82
|
+
parsedSkills.push(parsed);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.warn(chalk.red(`Failed to parse ${file}: ${err instanceof Error ? err.message : String(err)}`));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (parsedSkills.length === 0) {
|
|
89
|
+
console.log(chalk.yellow(`No valid skills were successfully parsed.`));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Format the consolidated prompts
|
|
93
|
+
let output = `System update: The repository has the following workflows/skills configured. You are trained to execute them upon request:\n\n`;
|
|
94
|
+
for (const skill of parsedSkills) {
|
|
95
|
+
output += `=== SKILL: ${skill.name} ===\n`;
|
|
96
|
+
if (skill.description) {
|
|
97
|
+
output += `Description: ${skill.description}\n`;
|
|
98
|
+
}
|
|
99
|
+
output += `Instructions:\n${skill.body}\n`;
|
|
100
|
+
output += `=============================\n\n`;
|
|
101
|
+
}
|
|
102
|
+
output = output.trim();
|
|
103
|
+
if (options.clipboard) {
|
|
104
|
+
console.log(chalk.blue("Copying exported workflows to clipboard..."));
|
|
105
|
+
const success = await writeToClipboard(output);
|
|
106
|
+
if (success) {
|
|
107
|
+
console.log(chalk.green(`āļø Successfully copied ${parsedSkills.length} custom workflow(s) to clipboard!`));
|
|
108
|
+
console.log(chalk.gray("You can now paste them directly into your Antigravity chat console to register these commands."));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
console.warn(chalk.yellow("ā ļø Failed to write to clipboard. Outputting to stdout instead:"));
|
|
112
|
+
console.log("\n" + output + "\n");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.log("\n" + output + "\n");
|
|
117
|
+
}
|
|
118
|
+
}
|