agcel 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/workflows/api-gen.md +59 -0
- package/.agent/workflows/architect.md +44 -0
- package/.agent/workflows/brainstorm.md +223 -0
- package/.agent/workflows/build.md +38 -0
- package/.agent/workflows/changelog.md +51 -0
- package/.agent/workflows/checkpoint.md +138 -0
- package/.agent/workflows/commit.md +223 -0
- package/.agent/workflows/debug.md +57 -0
- package/.agent/workflows/deploy.md +76 -0
- package/.agent/workflows/doc.md +247 -0
- package/.agent/workflows/execute-plan.md +225 -0
- package/.agent/workflows/feature.md +255 -0
- package/.agent/workflows/fix.md +323 -0
- package/.agent/workflows/help.md +63 -0
- package/.agent/workflows/index.md +148 -0
- package/.agent/workflows/load.md +112 -0
- package/.agent/workflows/mode.md +170 -0
- package/.agent/workflows/optimize.md +53 -0
- package/.agent/workflows/plan.md +337 -0
- package/.agent/workflows/pr.md +74 -0
- package/.agent/workflows/product-plan.md +36 -0
- package/.agent/workflows/production-deploy.md +39 -0
- package/.agent/workflows/refactor.md +63 -0
- package/.agent/workflows/research.md +116 -0
- package/.agent/workflows/review.md +344 -0
- package/.agent/workflows/security-scan.md +56 -0
- package/.agent/workflows/ship.md +221 -0
- package/.agent/workflows/spawn.md +177 -0
- package/.agent/workflows/status.md +59 -0
- package/.agent/workflows/tdd.md +139 -0
- package/.agent/workflows/test.md +340 -0
- package/.agent/workflows/verify.md +35 -0
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/commands/init.js +142 -0
- package/dist/commands/install.js +98 -0
- package/dist/commands/list.js +49 -0
- package/dist/commands/restart.js +17 -0
- package/dist/commands/start.js +41 -0
- package/dist/commands/status.js +24 -0
- package/dist/commands/stop.js +29 -0
- package/dist/commands/uninstall.js +78 -0
- package/dist/index.js +58 -0
- package/dist/server/index.js +174 -0
- package/dist/utils/index.js +63 -0
- package/package.json +54 -0
- package/skills/api-security-best-practices/SKILL.md +291 -0
- package/skills/api-security-best-practices/references/examples.md +617 -0
- package/skills/architecture/SKILL.md +59 -0
- package/skills/architecture/context-discovery.md +43 -0
- package/skills/architecture/examples.md +94 -0
- package/skills/architecture/pattern-selection.md +68 -0
- package/skills/architecture/patterns-reference.md +50 -0
- package/skills/architecture/trade-off-analysis.md +77 -0
- package/skills/aws-serverless/SKILL.md +327 -0
- package/skills/brainstorming/SKILL.md +234 -0
- package/skills/c4-context/SKILL.md +154 -0
- package/skills/ci-cd-engineer/SKILL.md +50 -0
- package/skills/code-auditing/SKILL.md +55 -0
- package/skills/copywriting/SKILL.md +248 -0
- package/skills/database-engineer/SKILL.md +47 -0
- package/skills/doc-coauthoring/SKILL.md +379 -0
- package/skills/docker-expert/SKILL.md +412 -0
- package/skills/langgraph/SKILL.md +291 -0
- package/skills/postgresql/SKILL.md +73 -0
- package/skills/pricing-strategy/SKILL.md +360 -0
- package/skills/product-manager/SKILL.md +57 -0
- package/skills/prompt-engineer/README.md +659 -0
- package/skills/prompt-engineer/SKILL.md +256 -0
- package/skills/python-patterns/SKILL.md +445 -0
- package/skills/qa-engineer/SKILL.md +42 -0
- package/skills/rag-engineer/SKILL.md +94 -0
- package/skills/react-patterns/SKILL.md +202 -0
- package/skills/secure-refactoring/SKILL.md +54 -0
- package/skills/security-documentation/SKILL.md +53 -0
- package/skills/senior-architect/SKILL.md +213 -0
- package/skills/senior-architect/references/architecture_patterns.md +103 -0
- package/skills/senior-architect/references/system_design_workflows.md +103 -0
- package/skills/senior-architect/references/tech_decision_guide.md +103 -0
- package/skills/senior-architect/scripts/architecture_diagram_generator.py +114 -0
- package/skills/senior-architect/scripts/dependency_analyzer.py +114 -0
- package/skills/senior-architect/scripts/project_architect.py +114 -0
- package/skills/seo-audit/SKILL.md +491 -0
- package/skills/sql-injection-testing/SKILL.md +452 -0
- package/skills/test-driven-development/SKILL.md +375 -0
- package/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/test-fixing/SKILL.md +123 -0
- package/skills/testing-patterns/SKILL.md +263 -0
- package/skills/typescript-expert/SKILL.md +202 -0
- package/skills/typescript-expert/references/advanced-topics.md +252 -0
- package/skills/typescript-expert/references/tsconfig-strict.json +92 -0
- package/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
- package/skills/typescript-expert/references/utility-types.ts +335 -0
- package/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
- package/skills/ui-ux-designer/SKILL.md +46 -0
- package/skills/vercel-deployment/SKILL.md +83 -0
- package/skills/vulnerability-scanner/SKILL.md +280 -0
- package/skills/vulnerability-scanner/checklists.md +121 -0
- package/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/skills/writing-plans/SKILL.md +120 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# /test - Test Generation Command
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Generate comprehensive tests for specified code including unit tests, integration tests, and edge cases.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
/test [file path | function name | 'coverage' | 'all']
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Arguments
|
|
14
|
+
|
|
15
|
+
- `$ARGUMENTS`:
|
|
16
|
+
- File path: Generate tests for specific file
|
|
17
|
+
- Function name: Generate tests for specific function
|
|
18
|
+
- `coverage`: Analyze and improve test coverage
|
|
19
|
+
- `all`: Run all tests and report results
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
Generate comprehensive tests for: **$ARGUMENTS**
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### For File/Function Testing
|
|
28
|
+
|
|
29
|
+
1. **Analyze Target Code**
|
|
30
|
+
- Read the code to understand functionality
|
|
31
|
+
- Identify inputs, outputs, and side effects
|
|
32
|
+
- Note dependencies to mock
|
|
33
|
+
- Find existing tests for patterns
|
|
34
|
+
|
|
35
|
+
2. **Design Test Cases**
|
|
36
|
+
- **Happy Path**: Normal operation with valid inputs
|
|
37
|
+
- **Edge Cases**: Boundary values, empty inputs, limits
|
|
38
|
+
- **Error Cases**: Invalid inputs, exceptions
|
|
39
|
+
- **Integration Points**: External dependencies
|
|
40
|
+
|
|
41
|
+
3. **Generate Tests**
|
|
42
|
+
- Follow project testing conventions
|
|
43
|
+
- Use appropriate mocking strategies
|
|
44
|
+
- Write clear, descriptive test names
|
|
45
|
+
- Include setup and teardown
|
|
46
|
+
|
|
47
|
+
4. **Run and Verify**
|
|
48
|
+
```bash
|
|
49
|
+
# Python
|
|
50
|
+
pytest [test_file] -v
|
|
51
|
+
|
|
52
|
+
# TypeScript
|
|
53
|
+
pnpm test [test_file]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### For Coverage Analysis
|
|
57
|
+
|
|
58
|
+
1. **Run Coverage Report**
|
|
59
|
+
```bash
|
|
60
|
+
# Python
|
|
61
|
+
pytest --cov=src --cov-report=term-missing
|
|
62
|
+
|
|
63
|
+
# TypeScript
|
|
64
|
+
pnpm test --coverage
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. **Identify Gaps**
|
|
68
|
+
- Find untested functions
|
|
69
|
+
- Identify untested branches
|
|
70
|
+
- Note missing edge cases
|
|
71
|
+
|
|
72
|
+
3. **Generate Missing Tests**
|
|
73
|
+
- Prioritize by risk
|
|
74
|
+
- Focus on critical paths
|
|
75
|
+
- Add edge case coverage
|
|
76
|
+
|
|
77
|
+
## Test Templates
|
|
78
|
+
|
|
79
|
+
### Python (pytest)
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import pytest
|
|
83
|
+
from unittest.mock import Mock, patch
|
|
84
|
+
from src.module import function_under_test
|
|
85
|
+
|
|
86
|
+
class TestFunctionUnderTest:
|
|
87
|
+
"""Tests for function_under_test."""
|
|
88
|
+
|
|
89
|
+
def test_with_valid_input_returns_expected(self):
|
|
90
|
+
"""Test that valid input produces expected output."""
|
|
91
|
+
result = function_under_test("valid_input")
|
|
92
|
+
assert result == "expected_output"
|
|
93
|
+
|
|
94
|
+
def test_with_empty_input_returns_default(self):
|
|
95
|
+
"""Test that empty input returns default value."""
|
|
96
|
+
result = function_under_test("")
|
|
97
|
+
assert result == "default"
|
|
98
|
+
|
|
99
|
+
def test_with_invalid_input_raises_error(self):
|
|
100
|
+
"""Test that invalid input raises ValueError."""
|
|
101
|
+
with pytest.raises(ValueError, match="Invalid input"):
|
|
102
|
+
function_under_test(None)
|
|
103
|
+
|
|
104
|
+
@pytest.mark.parametrize("input_val,expected", [
|
|
105
|
+
("a", "result_a"),
|
|
106
|
+
("b", "result_b"),
|
|
107
|
+
("c", "result_c"),
|
|
108
|
+
])
|
|
109
|
+
def test_parametrized_inputs(self, input_val, expected):
|
|
110
|
+
"""Test multiple input variations."""
|
|
111
|
+
assert function_under_test(input_val) == expected
|
|
112
|
+
|
|
113
|
+
@patch('src.module.external_service')
|
|
114
|
+
def test_with_mocked_dependency(self, mock_service):
|
|
115
|
+
"""Test with mocked external dependency."""
|
|
116
|
+
mock_service.call.return_value = "mocked_result"
|
|
117
|
+
result = function_under_test("input")
|
|
118
|
+
assert result == "expected_with_mock"
|
|
119
|
+
mock_service.call.assert_called_once_with("input")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### TypeScript (vitest)
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
126
|
+
import { functionUnderTest } from './module';
|
|
127
|
+
|
|
128
|
+
describe('functionUnderTest', () => {
|
|
129
|
+
beforeEach(() => {
|
|
130
|
+
vi.clearAllMocks();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should return expected output for valid input', () => {
|
|
134
|
+
const result = functionUnderTest('valid_input');
|
|
135
|
+
expect(result).toBe('expected_output');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should return default for empty input', () => {
|
|
139
|
+
const result = functionUnderTest('');
|
|
140
|
+
expect(result).toBe('default');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should throw error for invalid input', () => {
|
|
144
|
+
expect(() => functionUnderTest(null)).toThrow('Invalid input');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it.each([
|
|
148
|
+
['a', 'result_a'],
|
|
149
|
+
['b', 'result_b'],
|
|
150
|
+
['c', 'result_c'],
|
|
151
|
+
])('should handle input %s correctly', (input, expected) => {
|
|
152
|
+
expect(functionUnderTest(input)).toBe(expected);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should work with mocked dependency', async () => {
|
|
156
|
+
vi.mock('./external-service', () => ({
|
|
157
|
+
call: vi.fn().mockResolvedValue('mocked_result'),
|
|
158
|
+
}));
|
|
159
|
+
|
|
160
|
+
const result = await functionUnderTest('input');
|
|
161
|
+
expect(result).toBe('expected_with_mock');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### React Component (Testing Library)
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
170
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
171
|
+
import { UserForm } from './UserForm';
|
|
172
|
+
|
|
173
|
+
describe('UserForm', () => {
|
|
174
|
+
it('should render form fields', () => {
|
|
175
|
+
render(<UserForm onSubmit={vi.fn()} />);
|
|
176
|
+
|
|
177
|
+
expect(screen.getByLabelText(/name/i)).toBeInTheDocument();
|
|
178
|
+
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
|
|
179
|
+
expect(screen.getByRole('button', { name: /submit/i })).toBeInTheDocument();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should call onSubmit with form data', async () => {
|
|
183
|
+
const onSubmit = vi.fn();
|
|
184
|
+
render(<UserForm onSubmit={onSubmit} />);
|
|
185
|
+
|
|
186
|
+
fireEvent.change(screen.getByLabelText(/name/i), {
|
|
187
|
+
target: { value: 'John' },
|
|
188
|
+
});
|
|
189
|
+
fireEvent.change(screen.getByLabelText(/email/i), {
|
|
190
|
+
target: { value: 'john@example.com' },
|
|
191
|
+
});
|
|
192
|
+
fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
|
193
|
+
|
|
194
|
+
await waitFor(() => {
|
|
195
|
+
expect(onSubmit).toHaveBeenCalledWith({
|
|
196
|
+
name: 'John',
|
|
197
|
+
email: 'john@example.com',
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should show validation error for invalid email', async () => {
|
|
203
|
+
render(<UserForm onSubmit={vi.fn()} />);
|
|
204
|
+
|
|
205
|
+
fireEvent.change(screen.getByLabelText(/email/i), {
|
|
206
|
+
target: { value: 'invalid' },
|
|
207
|
+
});
|
|
208
|
+
fireEvent.blur(screen.getByLabelText(/email/i));
|
|
209
|
+
|
|
210
|
+
expect(await screen.findByText(/invalid email/i)).toBeInTheDocument();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Output
|
|
216
|
+
|
|
217
|
+
### Test Generation Report
|
|
218
|
+
|
|
219
|
+
```markdown
|
|
220
|
+
## Tests Generated
|
|
221
|
+
|
|
222
|
+
### Target
|
|
223
|
+
`src/services/auth.ts` - AuthService class
|
|
224
|
+
|
|
225
|
+
### Tests Created
|
|
226
|
+
- `tests/services/auth.test.ts`
|
|
227
|
+
|
|
228
|
+
### Test Cases
|
|
229
|
+
1. `login_with_valid_credentials_returns_token` - Happy path
|
|
230
|
+
2. `login_with_invalid_password_throws_error` - Error case
|
|
231
|
+
3. `login_with_nonexistent_user_throws_error` - Error case
|
|
232
|
+
4. `refresh_token_with_valid_token_returns_new_token` - Happy path
|
|
233
|
+
5. `refresh_token_with_expired_token_throws_error` - Edge case
|
|
234
|
+
6. `logout_invalidates_session` - Happy path
|
|
235
|
+
|
|
236
|
+
### Coverage Impact
|
|
237
|
+
- Before: 65%
|
|
238
|
+
- After: 88%
|
|
239
|
+
- New lines covered: 42
|
|
240
|
+
|
|
241
|
+
### Run Tests
|
|
242
|
+
```bash
|
|
243
|
+
pytest tests/services/auth.test.ts -v
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Notes
|
|
247
|
+
- Mocked database calls using pytest-mock
|
|
248
|
+
- Added edge case for token expiration
|
|
249
|
+
- Consider adding integration tests for full auth flow
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Flags
|
|
253
|
+
|
|
254
|
+
| Flag | Description | Example |
|
|
255
|
+
|------|-------------|---------|
|
|
256
|
+
| `--coverage` | Generate coverage-focused tests | `--coverage` |
|
|
257
|
+
| `--type=[type]` | Test type to generate | `--type=integration` |
|
|
258
|
+
| `--format=[fmt]` | Output format (concise/detailed) | `--format=concise` |
|
|
259
|
+
| `--framework=[fw]` | Specify test framework | `--framework=vitest` |
|
|
260
|
+
| `--tdd` | Generate TDD-style with failing tests first | `--tdd` |
|
|
261
|
+
| `--edge-cases` | Focus on edge case coverage | `--edge-cases` |
|
|
262
|
+
|
|
263
|
+
### Flag Usage Examples
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
/test --coverage src/services/
|
|
267
|
+
/test --type=integration src/api/users.ts
|
|
268
|
+
/test --tdd src/utils/validator.ts
|
|
269
|
+
/test --edge-cases --framework=pytest src/models/user.py
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Test Types
|
|
273
|
+
|
|
274
|
+
| Type | Description |
|
|
275
|
+
|------|-------------|
|
|
276
|
+
| `unit` | Isolated function tests (default) |
|
|
277
|
+
| `integration` | Multi-component tests |
|
|
278
|
+
| `e2e` | End-to-end workflow tests |
|
|
279
|
+
| `snapshot` | Snapshot tests for UI |
|
|
280
|
+
| `property` | Property-based testing |
|
|
281
|
+
|
|
282
|
+
### Framework Options
|
|
283
|
+
|
|
284
|
+
| Framework | Language |
|
|
285
|
+
|-----------|----------|
|
|
286
|
+
| `pytest` | Python |
|
|
287
|
+
| `vitest` | TypeScript/JavaScript |
|
|
288
|
+
| `jest` | JavaScript |
|
|
289
|
+
| `playwright` | E2E (any) |
|
|
290
|
+
|
|
291
|
+
## MCP Integration
|
|
292
|
+
|
|
293
|
+
This command leverages MCP servers for enhanced testing:
|
|
294
|
+
|
|
295
|
+
### Browser tools - E2E Testing (Primary for UI)
|
|
296
|
+
```
|
|
297
|
+
For E2E and browser tests:
|
|
298
|
+
- Use Browser tools for cross-browser testing
|
|
299
|
+
- Automate user flow verification
|
|
300
|
+
- Capture screenshots for visual testing
|
|
301
|
+
- Test on different device emulations
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Filesystem - Test File Management
|
|
305
|
+
```
|
|
306
|
+
For test file operations:
|
|
307
|
+
- Use list_dir to find test directories
|
|
308
|
+
- Use grep_search to find existing tests
|
|
309
|
+
- Use view_file to check test patterns
|
|
310
|
+
- Use write_to_file to create new test files
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Web Search - Testing Best Practices
|
|
314
|
+
```
|
|
315
|
+
For framework-specific testing:
|
|
316
|
+
- Fetch current testing library docs
|
|
317
|
+
- Get latest assertions and matchers
|
|
318
|
+
- Find recommended testing patterns
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Memory - Test Patterns
|
|
322
|
+
```
|
|
323
|
+
Recall testing context:
|
|
324
|
+
- Remember project testing conventions
|
|
325
|
+
- Recall mock patterns used previously
|
|
326
|
+
- Store common test fixtures
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
<!-- CUSTOMIZATION POINT -->
|
|
330
|
+
## Variations
|
|
331
|
+
|
|
332
|
+
Modify behavior via CLAUDE.md:
|
|
333
|
+
- Preferred test framework
|
|
334
|
+
- Minimum coverage targets
|
|
335
|
+
- Test naming conventions
|
|
336
|
+
- Required test categories
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
## Gap Analysis Rule
|
|
340
|
+
Always identify gaps and suggest next steps to users. In case there is no gaps anymore, then AI should clearly state that there is no gap left.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Verification, Testing, and Auditing
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /verify Workflow
|
|
6
|
+
|
|
7
|
+
This workflow audits the codebase for bugs, quality issues, and security vulnerabilities.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. **Static Analysis & Audit**
|
|
12
|
+
- Use key: `code-auditing`
|
|
13
|
+
- Goal: General code quality review and linting.
|
|
14
|
+
- Output: List of code style issues or potential bugs.
|
|
15
|
+
|
|
16
|
+
2. **Security Scan**
|
|
17
|
+
- Use key: `vulnerability-scanner`
|
|
18
|
+
- Goal: Scan dependencies and code patterns for known vulnerabilities.
|
|
19
|
+
- Instruction: Check `package.json` / `requirements.txt` against known CVE databases (simulated).
|
|
20
|
+
|
|
21
|
+
3. **SQL Injection Check**
|
|
22
|
+
- Use key: `sql-injection-testing`
|
|
23
|
+
- Goal: Specifically check database queries for injection risks.
|
|
24
|
+
|
|
25
|
+
4. **Test Verification**
|
|
26
|
+
- Use key: `qa-engineer` / `test-fixing`
|
|
27
|
+
- Goal: Run all tests and attempt to fix any failures.
|
|
28
|
+
- Instruction: Ensure all tests pass before completing the workflow.
|
|
29
|
+
|
|
30
|
+
## Iron Rules
|
|
31
|
+
1. If there is anything unclear, ask the user instead of inventing new stuff. Unless the user explicitly tells the AI to invent or suggest ideas.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Gap Analysis Rule
|
|
35
|
+
Always identify gaps and suggest next steps to users. In case there is no gaps anymore, then AI should clearly state that there is no gap left.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bennie Ng
|
|
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,67 @@
|
|
|
1
|
+
# AgCel
|
|
2
|
+
|
|
3
|
+
AgCel is a local MCP (Model Context Protocol) Skills Server that functions both as a command-line tool and a backend for Antigravity workflows. It bridges the gap between local execution and AI agent capabilities by providing structured "Skills".
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The project consists of two main components:
|
|
8
|
+
1. **AgCel CLI**: A command-line interface to manage and interact with the MCP server.
|
|
9
|
+
2. **AgCel MCP Skills Server**: A local server that hosts skills and capabilities, enabling AI agents to perform complex tasks.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
To install the AgCel CLI globally and set up the local MCP server:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx agcel install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## CLI Usage
|
|
20
|
+
|
|
21
|
+
The `agc` command-line tool is your primary interface. Application data is stored in the `.agc` directory in your project root, and `~/.agcel` for global configuration.
|
|
22
|
+
|
|
23
|
+
| Command | Description |
|
|
24
|
+
| :--- | :--- |
|
|
25
|
+
| `agc start` | Start the MCP server locally. |
|
|
26
|
+
| `agc stop` | Stop the running MCP server. |
|
|
27
|
+
| `agc restart` | Restart the MCP server. |
|
|
28
|
+
| `agc status` | Check the status of the local MCP server. |
|
|
29
|
+
| `agc init` | Initialize AgCel in the current project (copies workflows to `.agent/workflows`). |
|
|
30
|
+
| `agc skills list` | List all available skills. |
|
|
31
|
+
| `agc workflows list` | List all available workflows. |
|
|
32
|
+
| `agc --help` | Show the help menu. |
|
|
33
|
+
| `agc --version` | Show the CLI version. |
|
|
34
|
+
|
|
35
|
+
## Concepts
|
|
36
|
+
|
|
37
|
+
### Skills
|
|
38
|
+
|
|
39
|
+
**Skills** are specialized capabilities that allow the AI to perform complex tasks. AgCel comes with a rich set of built-in skills:
|
|
40
|
+
|
|
41
|
+
- **Languages**: Python, TypeScript, JavaScript
|
|
42
|
+
- **Frameworks**: React, Next.js, FastAPI, Django
|
|
43
|
+
- **DevOps**: Docker, GitHub Actions, Vercel
|
|
44
|
+
- **Security**: OWASP, Vulnerability Scanning
|
|
45
|
+
- **Methodology**: TDD, Systematic Debugging, Code Review, Architecture
|
|
46
|
+
|
|
47
|
+
### Workflows
|
|
48
|
+
|
|
49
|
+
**Workflows** are standard operating procedures for common development tasks.
|
|
50
|
+
|
|
51
|
+
- **Development**: `/feature`, `/fix`, `/test`, `/refactor`
|
|
52
|
+
- **Planning**: `/plan`, `/brainstorm`, `/research`
|
|
53
|
+
- **Operations**: `/ship`, `/deploy`, `/security-scan`
|
|
54
|
+
|
|
55
|
+
### Rules
|
|
56
|
+
|
|
57
|
+
**Rules** serve as guardrails for the AI.
|
|
58
|
+
|
|
59
|
+
- **Boundary Rules**: "Do not use external libraries."
|
|
60
|
+
- **Operational Rules**: "Always ask for clarification."
|
|
61
|
+
- **Security Rules**: "Never share API keys."
|
|
62
|
+
|
|
63
|
+
## Integration with Antigravity
|
|
64
|
+
|
|
65
|
+
When working with the Antigravity IDE:
|
|
66
|
+
1. Run `agc init` to set up the environment.
|
|
67
|
+
2. Use workflows in the Agent Window (e.g., `/agc idea` for ideation).
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.initCommand = initCommand;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
11
|
+
const index_js_1 = require("../utils/index.js");
|
|
12
|
+
async function initCommand() {
|
|
13
|
+
const globalDir = (0, index_js_1.getGlobalAgCelDir)();
|
|
14
|
+
const globalWorkflowsDir = path_1.default.join(globalDir, 'workflows');
|
|
15
|
+
console.log(chalk_1.default.blue('Initializing AgCel in current project...'));
|
|
16
|
+
// 1. Check if global install exists
|
|
17
|
+
if (!fs_1.default.existsSync(globalDir)) {
|
|
18
|
+
console.error(chalk_1.default.red('Error: AgCel is not installed globally.'));
|
|
19
|
+
console.error(chalk_1.default.yellow('Please run "npx agcel install" first to set up the global environment.'));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!fs_1.default.existsSync(globalWorkflowsDir)) {
|
|
23
|
+
console.error(chalk_1.default.red(`Error: Workflows directory not found in global install at ${globalWorkflowsDir}`));
|
|
24
|
+
console.error(chalk_1.default.yellow('Please try running "npx agcel install" again to fix the installation.'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// 2. Setup local .agc and .agent directories
|
|
28
|
+
const projectAgcDir = path_1.default.join(process.cwd(), '.agc');
|
|
29
|
+
const projectSkillsDir = path_1.default.join(projectAgcDir, 'skills');
|
|
30
|
+
const projectAgentDir = path_1.default.join(process.cwd(), '.agent');
|
|
31
|
+
const projectWorkflowsDir = path_1.default.join(projectAgentDir, 'workflows');
|
|
32
|
+
// Create .agc directory (Critical for isInitialized check)
|
|
33
|
+
if (!fs_1.default.existsSync(projectAgcDir)) {
|
|
34
|
+
console.log(chalk_1.default.blue('Creating .agc directory...'));
|
|
35
|
+
fs_1.default.mkdirSync(projectAgcDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
// Copy skills from global install to .agc/skills
|
|
38
|
+
const globalSkillsDir = path_1.default.join(globalDir, 'skills');
|
|
39
|
+
if (fs_1.default.existsSync(globalSkillsDir)) {
|
|
40
|
+
if (!fs_1.default.existsSync(projectSkillsDir)) {
|
|
41
|
+
console.log(chalk_1.default.blue('Creating .agc/skills directory...'));
|
|
42
|
+
fs_1.default.mkdirSync(projectSkillsDir, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
console.log(chalk_1.default.blue('Copying skills...'));
|
|
45
|
+
fs_1.default.cpSync(globalSkillsDir, projectSkillsDir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.warn(chalk_1.default.yellow(`Warning: Global skills not found at ${globalSkillsDir}`));
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
if (!fs_1.default.existsSync(projectAgentDir)) {
|
|
52
|
+
console.log(chalk_1.default.blue('Creating .agent directory...'));
|
|
53
|
+
fs_1.default.mkdirSync(projectAgentDir, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
if (!fs_1.default.existsSync(projectWorkflowsDir)) {
|
|
56
|
+
console.log(chalk_1.default.blue('Creating .agent/workflows directory...'));
|
|
57
|
+
fs_1.default.mkdirSync(projectWorkflowsDir, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
// 3. Copy workflows
|
|
60
|
+
console.log(chalk_1.default.blue('Copying workflows...'));
|
|
61
|
+
const workflows = fs_1.default.readdirSync(globalWorkflowsDir);
|
|
62
|
+
let overwriteAll = false;
|
|
63
|
+
for (const workflow of workflows) {
|
|
64
|
+
const srcPath = path_1.default.join(globalWorkflowsDir, workflow);
|
|
65
|
+
const destPath = path_1.default.join(projectWorkflowsDir, workflow);
|
|
66
|
+
if (fs_1.default.lstatSync(srcPath).isFile()) {
|
|
67
|
+
const content = fs_1.default.readFileSync(srcPath, 'utf-8');
|
|
68
|
+
if (fs_1.default.existsSync(destPath)) {
|
|
69
|
+
const destContent = fs_1.default.readFileSync(destPath, 'utf-8');
|
|
70
|
+
if (content !== destContent) {
|
|
71
|
+
let action = 'skip';
|
|
72
|
+
if (overwriteAll) {
|
|
73
|
+
action = 'overwrite';
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const answer = await inquirer_1.default.prompt([{
|
|
77
|
+
type: 'expand',
|
|
78
|
+
name: 'action',
|
|
79
|
+
message: `Workflow ${workflow} already exists and is different.`,
|
|
80
|
+
choices: [
|
|
81
|
+
{ key: 'y', name: 'Overwrite', value: 'overwrite' },
|
|
82
|
+
{ key: 'n', name: 'Skip', value: 'skip' },
|
|
83
|
+
{ key: 'a', name: 'Overwrite All', value: 'all' }
|
|
84
|
+
],
|
|
85
|
+
default: 1
|
|
86
|
+
}]);
|
|
87
|
+
if (answer.action === 'all') {
|
|
88
|
+
overwriteAll = true;
|
|
89
|
+
action = 'overwrite';
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
action = answer.action;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (action === 'overwrite') {
|
|
96
|
+
fs_1.default.writeFileSync(destPath, content);
|
|
97
|
+
console.log(chalk_1.default.green(`Updated ${workflow}`));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.log(chalk_1.default.yellow(`Skipped ${workflow}`));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
fs_1.default.writeFileSync(destPath, content);
|
|
106
|
+
console.log(chalk_1.default.green(`Created ${workflow}`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
console.log(chalk_1.default.green('AgCel project initialization complete!'));
|
|
111
|
+
console.log(chalk_1.default.cyan('Workflows installed to .agent/workflows'));
|
|
112
|
+
console.log(chalk_1.default.cyan('Skills installed to .agc/skills'));
|
|
113
|
+
// 4. Update .gitignore
|
|
114
|
+
updateGitIgnore(process.cwd());
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throw error; // Re-throw to be caught by outer catch
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function updateGitIgnore(cwd) {
|
|
121
|
+
const gitIgnorePath = path_1.default.join(cwd, '.gitignore');
|
|
122
|
+
const entriesToAdd = ['.agc', '.agents', '.agent'];
|
|
123
|
+
let content = '';
|
|
124
|
+
if (fs_1.default.existsSync(gitIgnorePath)) {
|
|
125
|
+
content = fs_1.default.readFileSync(gitIgnorePath, 'utf-8');
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log(chalk_1.default.blue('Creating .gitignore...'));
|
|
129
|
+
}
|
|
130
|
+
const lines = content.split('\n').map(line => line.trim());
|
|
131
|
+
const newEntries = [];
|
|
132
|
+
for (const entry of entriesToAdd) {
|
|
133
|
+
if (!lines.includes(entry)) {
|
|
134
|
+
newEntries.push(entry);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (newEntries.length > 0) {
|
|
138
|
+
const appendContent = (content && !content.endsWith('\n') ? '\n' : '') + newEntries.join('\n') + '\n';
|
|
139
|
+
fs_1.default.appendFileSync(gitIgnorePath, appendContent);
|
|
140
|
+
console.log(chalk_1.default.green(`Added ${newEntries.join(', ')} to .gitignore`));
|
|
141
|
+
}
|
|
142
|
+
}
|