moicle 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +20 -9
  2. package/assets/architecture/_shared/severity-levels.md +34 -0
  3. package/assets/architecture/_shared/stack-detection.md +34 -0
  4. package/assets/commands/marketing.md +7 -7
  5. package/assets/skills/docs/sync/SKILL.md +159 -519
  6. package/assets/skills/docs/write/SKILL.md +89 -186
  7. package/assets/skills/feature/new/SKILL.md +152 -192
  8. package/assets/skills/feature/refactor/SKILL.md +152 -233
  9. package/assets/skills/fix/hotfix/SKILL.md +139 -305
  10. package/assets/skills/fix/incident/SKILL.md +107 -19
  11. package/assets/skills/fix/pr-comment/SKILL.md +98 -224
  12. package/assets/skills/fix/root-cause/SKILL.md +161 -104
  13. package/assets/skills/{docs → marketing}/content/SKILL.md +4 -4
  14. package/assets/skills/marketing/logo/SKILL.md +252 -0
  15. package/assets/skills/marketing/seo-blog/SKILL.md +367 -0
  16. package/assets/skills/marketing/video/SKILL.md +258 -0
  17. package/assets/skills/research/onboarding/SKILL.md +127 -510
  18. package/assets/skills/research/spike/SKILL.md +128 -436
  19. package/assets/skills/research/web/SKILL.md +124 -83
  20. package/assets/skills/review/architect/SKILL.md +157 -306
  21. package/assets/skills/review/branch/SKILL.md +153 -208
  22. package/assets/skills/review/pr/SKILL.md +129 -519
  23. package/assets/skills/review/tdd/SKILL.md +108 -69
  24. package/bin/cli.js +2 -2
  25. package/dist/commands/install.d.ts.map +1 -1
  26. package/dist/commands/install.js +176 -8
  27. package/dist/commands/install.js.map +1 -1
  28. package/dist/commands/list.d.ts.map +1 -1
  29. package/dist/commands/list.js +31 -1
  30. package/dist/commands/list.js.map +1 -1
  31. package/dist/commands/status.d.ts.map +1 -1
  32. package/dist/commands/status.js +30 -1
  33. package/dist/commands/status.js.map +1 -1
  34. package/dist/commands/uninstall.d.ts.map +1 -1
  35. package/dist/commands/uninstall.js +64 -8
  36. package/dist/commands/uninstall.js.map +1 -1
  37. package/dist/utils/symlink.d.ts +1 -0
  38. package/dist/utils/symlink.d.ts.map +1 -1
  39. package/dist/utils/symlink.js +8 -6
  40. package/dist/utils/symlink.js.map +1 -1
  41. package/package.json +1 -1
  42. package/assets/skills/docs/logo/SKILL.md +0 -492
  43. package/assets/skills/docs/video/SKILL.md +0 -666
@@ -5,17 +5,25 @@ description: Test-Driven Development workflow. Use when doing TDD, writing tests
5
5
 
6
6
  # Test-Driven Development (TDD) Workflow
7
7
 
8
- Red-Green-Refactor cycle: write failing test → write minimal code to pass → refactor while keeping tests green.
8
+ Red-Green-Refactor cycle: write failing test → write minimal code to pass → refactor while green.
9
9
 
10
10
  ## When to use this skill
11
11
 
12
- - ✅ Implementing logic with clear input → output behavior (parsers, validators, business rules, usecases)
13
- - ✅ Fixing a bug — write the failing test first, then fix (regression guard)
12
+ - ✅ Logic with clear input → output behavior (parsers, validators, business rules, usecases)
13
+ - ✅ Fixing a bug — failing test first, then fix (regression guard)
14
14
  - ✅ Refactoring critical code where you need a safety net
15
15
  - ❌ UI prototyping / visual tweaks → manual is faster
16
- - ❌ Exploratory spike → use `/research:spike` (throwaway code, no tests needed)
16
+ - ❌ Exploratory spike → use `/research:spike` (throwaway, no tests)
17
17
  - ❌ One-line config change → just change it
18
18
 
19
+ ## Read Architecture First
20
+
21
+ Detect stack via `~/.claude/architecture/_shared/stack-detection.md`. Architecture doc tells you:
22
+ - Test file location convention (`_test.go` next to source, `__tests__/`, `tests/Feature/`, etc.)
23
+ - Test framework (Go `testing`, Jest, Pest, `flutter_test`)
24
+ - Mocking pattern for ports
25
+ - AAA layout convention
26
+
19
27
  ---
20
28
 
21
29
  ## The TDD Cycle
@@ -29,62 +37,54 @@ Red-Green-Refactor cycle: write failing test → write minimal code to pass →
29
37
  next requirement
30
38
  ```
31
39
 
32
- ## Read Architecture First
33
-
34
- Read the stack architecture doc for:
35
- - Test file location convention (e.g., `_test.go` next to source, `__tests__/` for Jest)
36
- - Test framework (Go testing, Jest, Pest, Flutter test)
37
- - Mocking patterns for ports (interfaces)
38
- - AAA (Arrange-Act-Assert) layout
39
-
40
40
  ---
41
41
 
42
- ## Phase 1: RED — Write a failing test
42
+ ## Phase 1: RED — failing test
43
43
 
44
- **Goal:** describe the behavior you want with a test that fails because the code doesn't exist yet.
44
+ **Goal:** describe wanted behavior with a test that fails because the code doesn't exist yet.
45
45
 
46
46
  ### Steps
47
- 1. Pick ONE small requirement (the smallest behavior you can verify)
48
- 2. Write the test name as a sentence describing the behavior
49
- 3. Arrange: set up inputs and mocks
47
+ 1. Pick ONE small requirement (smallest verifiable behavior)
48
+ 2. Name the test as a sentence describing behavior
49
+ 3. Arrange: inputs + mocks
50
50
  4. Act: call the method
51
- 5. Assert: verify the expected output / state change / event raised
52
- 6. Run the test — it MUST fail (compile error or assertion fail). If it passes, the test is wrong.
51
+ 5. Assert: verify output / state / interaction
52
+ 6. Run — it MUST fail (compile error or assertion fail). If it passes, the test is wrong.
53
53
 
54
- ### Test name conventions
55
- - `should_<expected_behavior>_when_<condition>` (snake_case for Go/Python)
54
+ ### Test naming
55
+ - `should_<behavior>_when_<condition>` (snake_case for Go / Python)
56
56
  - `it("returns X when Y", ...)` (Jest / Mocha)
57
- - `test_<behavior>_<condition>` (PHPUnit)
57
+ - `test_<behavior>_<condition>` (PHPUnit / Pest)
58
58
 
59
59
  ### AAA pattern
60
60
  ```
61
61
  // Arrange — set up inputs and mocks
62
- // Act — call the function under test
62
+ // Act — call function under test
63
63
  // Assert — verify result / state / interactions
64
64
  ```
65
65
 
66
66
  ### Gate
67
- - [ ] Test fails for the RIGHT reason (compile error or assertion fail, not a typo)
68
- - [ ] Test name describes behavior, not implementation
69
- - [ ] Only ONE behavior tested per test
67
+ - [ ] Test fails for the RIGHT reason (not a typo / missing import)
68
+ - [ ] Name describes behavior, not implementation
69
+ - [ ] One behavior per test
70
70
 
71
71
  ---
72
72
 
73
- ## Phase 2: GREEN — Make it pass with minimal code
73
+ ## Phase 2: GREEN — minimal code to pass
74
74
 
75
- **Goal:** write the smallest amount of code that makes the test pass. **Resist** the urge to "do it properly" — refactor comes next.
75
+ **Goal:** smallest amount of code to pass. **Resist** "doing it properly" — refactor is next.
76
76
 
77
77
  ### Rules
78
- - **Minimal** means: hardcode return values if the test allows it; you'll triangulate with more tests
78
+ - **Minimal** means: hardcode return values if the test allows it; triangulate with more tests
79
79
  - Don't add code not required by a test
80
80
  - Don't add error handling unless a test requires it
81
- - Don't generalize until 3+ tests force you to
81
+ - Don't generalize until 3+ tests force it
82
82
 
83
83
  ### Steps
84
- 1. Run the failing test (confirm RED)
85
- 2. Write just enough code to make it green
86
- 3. Run all tests — all must pass (not just the new one)
87
- 4. If other tests broke, you're not minimal — revert and try smaller
84
+ 1. Confirm RED
85
+ 2. Write just enough code to pass
86
+ 3. Run all tests — all must stay green
87
+ 4. If others broke, you're not minimal — revert + try smaller
88
88
 
89
89
  ### Gate
90
90
  - [ ] New test passes
@@ -93,31 +93,31 @@ Read the stack architecture doc for:
93
93
 
94
94
  ---
95
95
 
96
- ## Phase 3: REFACTOR — Clean up while green
96
+ ## Phase 3: REFACTOR — clean up while green
97
97
 
98
- **Goal:** improve structure without changing behavior. Tests must stay green throughout.
98
+ **Goal:** improve structure without changing behavior. Tests stay green throughout.
99
99
 
100
100
  ### What to refactor
101
101
  - **Duplication** — extract function / method / class
102
- - **Long methods** — split when one method does multiple things
103
- - **Bad names** — rename to reveal intent (most underrated refactor)
102
+ - **Long methods** — split when one does multiple things
103
+ - **Bad names** — rename to reveal intent (the most underrated refactor)
104
104
  - **Dead branches** — remove code no test exercises
105
105
  - **Coupling** — break dependencies that make tests painful
106
106
 
107
107
  ### Rules
108
- - **Run tests after every change** — green is the safety net
108
+ - **Run tests after every change** — green is your safety net
109
109
  - **One refactor at a time** — extract method, run tests, rename, run tests, …
110
- - **No new behavior** — if a refactor needs a new test, you're not refactoring, go back to RED
110
+ - **No new behavior** — if a refactor needs a new test, go back to RED
111
111
 
112
112
  ### When NOT to refactor
113
- - Tests are flaky fix the flakiness first
114
- - You're under time pressure skip refactor, leave a TODO with link to a follow-up task
115
- - The code will be deleted soon don't polish trash
113
+ - Tests are flaky fix flakiness first
114
+ - Under time pressure skip, leave a `// TODO: refactor` linked to a follow-up
115
+ - Code about to be deleted don't polish trash
116
116
 
117
117
  ### Gate
118
118
  - [ ] All tests still green
119
119
  - [ ] No new public API added
120
- - [ ] Code is easier to read than before
120
+ - [ ] Code easier to read than before
121
121
 
122
122
  ---
123
123
 
@@ -128,14 +128,51 @@ Read the stack architecture doc for:
128
128
  | Value Object | Unit (pure) | None | `Money.add()` |
129
129
  | Entity | Unit (pure) | None | `Order.cancel()` raises event |
130
130
  | UseCase | Unit | Mock ports | `CreateOrder` calls `OrderStore.save()` |
131
+ | Service | Unit | Mock usecase | Delegates correctly |
131
132
  | Handler / Controller | Integration | Real router, mock service | `POST /orders` returns 201 |
132
133
  | Infrastructure | Integration | Real DB / testcontainers | `OrderRepository.save()` persists |
133
134
  | Listener | Unit | Mock infra | `on_order_created` sends email |
135
+ | API contract (cross-service) | Contract test | Real / sandboxed external | OpenAPI / Pact / Wiremock |
136
+
137
+ ### Mock vs real — decision table
138
+
139
+ | Dependency type | Use real | Use stub / fake | Use mock |
140
+ |-----------------|----------|-----------------|----------|
141
+ | Value objects, entities (pure) | ✅ always | — | never (brittle) |
142
+ | Stdlib (time, fs, env) | mostly — use clock / fs abstraction in domain | for determinism | rarely |
143
+ | Repository / port | testcontainers in infra tests | in-memory fake for usecase tests | only when verifying call args |
144
+ | External HTTP API | sandbox URL in integration | wiremock / msw for predictable cases | for failure-mode tests |
145
+ | Auth / session | real in integration | fake user in unit | rarely |
146
+ | Time | clock abstraction | fixed clock in tests | rarely |
147
+
148
+ **Stub vs fake vs mock:**
149
+ - **Stub** — returns canned values (`returnsBalance(100)`)
150
+ - **Fake** — working in-memory implementation (`InMemoryOrderStore`)
151
+ - **Mock** — records calls + verifies them (`expect(store.save).toHaveBeenCalledWith(...)`)
134
152
 
135
- ### Mock vs real
136
- - Mock **interfaces** (ports), not concrete classes
137
- - Use real value objects and entities in tests — they're pure, no need to mock
138
- - Use real DB in infra tests via testcontainers or in-memory variant
153
+ Prefer **fake** for repository tests (closest to real behavior). Use **mock** only when call args are the assertion.
154
+
155
+ ### Property-based testing
156
+
157
+ For pure logic with many edge cases (parsers, math, encoders), use property-based tests:
158
+
159
+ - Go: `testing/quick`, `gopter`
160
+ - TS / JS: `fast-check`
161
+ - Python: `hypothesis`
162
+ - Dart: `glados`
163
+
164
+ Pattern: "for all valid input X, property P holds." Generates 100s of cases including edge cases you wouldn't think of.
165
+
166
+ Example (TS, fast-check):
167
+ ```ts
168
+ test("reverse twice = identity", () => {
169
+ fc.assert(fc.property(fc.array(fc.string()), (arr) => {
170
+ expect(reverse(reverse(arr))).toEqual(arr);
171
+ }));
172
+ });
173
+ ```
174
+
175
+ Use it for: serializers, parsers, math, sorting, encoding/decoding. Not for: business workflows.
139
176
 
140
177
  ---
141
178
 
@@ -143,12 +180,14 @@ Read the stack architecture doc for:
143
180
 
144
181
  | Mistake | Why it's bad | Fix |
145
182
  |---------|--------------|-----|
146
- | Writing tests AFTER the code | You'll test what's written, not what's needed | Always RED first |
147
- | Testing implementation, not behavior | Refactor breaks tests | Assert on outputs / observable state |
148
- | One test covers many behaviors | Fail message is unclear | One behavior per test |
149
- | Mocking value objects | Brittle, no real benefit | Use real ones — they're pure |
150
- | Skipping the REFACTOR phase | Tech debt accumulates | It's a phase, not optional |
183
+ | Writing tests AFTER the code | Tests what's written, not what's needed | Always RED first |
184
+ | Testing implementation, not behavior | Refactor breaks tests | Assert outputs / observable state |
185
+ | One test, many behaviors | Failure message unclear | One behavior per test |
186
+ | Mocking value objects | Brittle, no benefit | Use real — they're pure |
187
+ | Skipping REFACTOR | Tech debt accumulates | It's a phase, not optional |
151
188
  | Test depends on order | Flaky | Each test sets up its own state |
189
+ | Slow tests (>1s each) | People stop running them | Move to integration tier; keep unit <100ms |
190
+ | 100% coverage chase | Forces tests for trivial code | Aim for high-value coverage on domain |
152
191
 
153
192
  ---
154
193
 
@@ -157,30 +196,32 @@ Read the stack architecture doc for:
157
196
  ```markdown
158
197
  ## TDD Cycle Complete: {feature}
159
198
 
160
- ### Cycles Done
161
- | # | RED behavior | GREEN | REFACTOR |
162
- |---|-------------|-------|----------|
163
- | 1 | {behavior} | {code added} | {what cleaned} |
164
- | 2 | ... | ... | ... |
199
+ ### Cycles
200
+ | # | RED (behavior) | GREEN (code added) | REFACTOR |
201
+ |---|----------------|--------------------|----------|
202
+ | 1 | rejects negative amount | guard in constructor | extracted validator |
203
+ | 2 | transitions PENDING → ACTIVE | added transition method | |
165
204
 
166
205
  ### Test Coverage
167
206
  - {N} tests, all passing
168
- - Coverage: {%} (target: ≥80% for domain layer)
207
+ - Domain coverage: {%} (target ≥80%)
169
208
 
170
209
  ### Files
171
210
  - Tests: {paths}
172
- - Code: {paths}
211
+ - Code: {paths}
173
212
  ```
174
213
 
175
214
  ---
176
215
 
177
216
  ## Hard Rules
178
217
 
179
- - **RED first, always** — never write production code without a failing test driving it
180
- - **Minimal GREEN** — hardcode if the test allows it; triangulate later
218
+ - **RED first, always** — no production code without a failing test driving it
219
+ - **Minimal GREEN** — hardcode if test allows; triangulate later
181
220
  - **REFACTOR is a phase, not optional**
182
221
  - **All tests green at all times** (except briefly during RED)
183
222
  - **One behavior per test**, named after the behavior
223
+ - **Unit tests <100ms each** — slow tests don't get run
224
+ - **Test behavior, not implementation** — refactor must not break tests
184
225
 
185
226
  ---
186
227
 
@@ -188,19 +229,17 @@ Read the stack architecture doc for:
188
229
 
189
230
  | When | Use |
190
231
  |------|-----|
191
- | Building a feature from scratch (with TDD inside) | `/feature:new` + this skill |
232
+ | Building feature from scratch (with TDD inside) | `/feature:new` + this skill |
192
233
  | Adding regression test for a bug | `/fix:hotfix` or `/fix:root-cause` → then this skill |
193
- | Refactoring untested legacy code (add tests first) | `refactor` |
234
+ | Refactoring untested legacy code | `/feature:refactor` (add tests first) |
194
235
  | Reviewing test quality on a PR | `/review:pr` |
195
236
 
196
- ---
197
-
198
237
  ## Recommended Agents
199
238
 
200
239
  | Phase | Agent | Purpose |
201
240
  |-------|-------|---------|
202
- | RED | `@test-writer` | Write failing tests first |
241
+ | RED | `@test-writer` | Failing tests first |
203
242
  | GREEN | Stack-specific dev agent | Minimal implementation |
204
- | REFACTOR | `@refactor` | Clean up patterns |
243
+ | REFACTOR | `@refactor` | Patterns + cleanup |
205
244
  | REFACTOR | `@code-reviewer` | Review refactored code |
206
- | REFACTOR | `@perf-optimizer` | Performance tweaks (only with benchmarks) |
245
+ | REFACTOR | `@perf-optimizer` | Perf tweaks (only with benchmarks) |
package/bin/cli.js CHANGED
@@ -46,7 +46,7 @@ program
46
46
  .description('List installed agents, commands, and skills')
47
47
  .option('-g, --global', 'List global installations')
48
48
  .option('-p, --project', 'List project installations')
49
- .option('-t, --target <editor>', 'Target editor (claude, codex)')
49
+ .option('-t, --target <editor>', 'Target editor (claude, codex, antigravity)')
50
50
  .action(listCommand);
51
51
 
52
52
  program
@@ -75,7 +75,7 @@ program
75
75
  .description('Show enabled/disabled status of all items')
76
76
  .option('-g, --global', 'Show global status')
77
77
  .option('-p, --project', 'Show project status')
78
- .option('-t, --target <editor>', 'Target editor (claude, codex)')
78
+ .option('-t, --target <editor>', 'Target editor (claude, codex, antigravity)')
79
79
  .action(statusCommand);
80
80
 
81
81
  program
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,aAAa,CAAC;AAyenF,eAAO,MAAM,cAAc,GAAU,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CA0H1E,CAAC"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,aAAa,CAAC;AAkrBnF,eAAO,MAAM,cAAc,GAAU,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CAwI1E,CAAC"}
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import inquirer from 'inquirer';
3
3
  import path from 'path';
4
4
  import fs from 'fs';
5
- import { ASSETS_DIR, EDITOR_CONFIGS, isSymlinkSupported, ensureDir, createSymlink, copyFile, copyDir, getAgentsDir, getCommandsDir, getSkillsDir, getArchitectureDir, getClaudeDir, getCodexDir, getEditorDir, getEditorConfig, getFiles, getDirs, mergeAgentsToFile, } from '../utils/symlink.js';
5
+ import { ASSETS_DIR, EDITOR_CONFIGS, isSymlinkSupported, ensureDir, createSymlink, copyFile, copyDir, getAgentsDir, getCommandsDir, getSkillsDir, getArchitectureDir, getClaudeDir, getCodexDir, getAntigravityDir, getEditorDir, getEditorConfig, getFiles, getDirs, mergeAgentsToFile, } from '../utils/symlink.js';
6
6
  import { addTarget } from '../utils/config.js';
7
7
  const printHeader = () => {
8
8
  console.log('');
@@ -133,6 +133,13 @@ const rewriteClaudePaths = (content, target) => {
133
133
  if (target === 'claude') {
134
134
  return content;
135
135
  }
136
+ if (target === 'antigravity') {
137
+ return content
138
+ .replace(/~\/\.claude\//g, '~/.gemini/')
139
+ .replace(/\.claude\//g, '.gemini/')
140
+ .replace(/Claude Code/g, 'Antigravity')
141
+ .replace(/CLAUDE\.md/g, 'GEMINI.md');
142
+ }
136
143
  return content
137
144
  .replace(/~\/\.claude\//g, '~/.codex/')
138
145
  .replace(/\.claude\//g, '.codex/')
@@ -297,6 +304,150 @@ const installCodexScope = async (scope) => {
297
304
  console.log('');
298
305
  console.log(chalk.green(`✓ ${label} Codex installation complete!`));
299
306
  };
307
+ const ensureAntigravitySkillDir = (baseDir, name) => {
308
+ const skillDir = path.join(baseDir, name);
309
+ ensureDir(skillDir);
310
+ return skillDir;
311
+ };
312
+ const installAntigravitySkillFolder = (sourceDir, targetSkillsDir) => {
313
+ const skillName = path.basename(sourceDir);
314
+ const targetDir = ensureAntigravitySkillDir(targetSkillsDir, skillName);
315
+ const sourceFiles = getFiles(sourceDir, 8);
316
+ let status = 'created';
317
+ for (const file of sourceFiles) {
318
+ const relativePath = path.relative(sourceDir, file);
319
+ const targetFile = path.join(targetDir, relativePath);
320
+ ensureDir(path.dirname(targetFile));
321
+ const content = rewriteClaudePaths(fs.readFileSync(file, 'utf-8'), 'antigravity');
322
+ const existed = fs.existsSync(targetFile);
323
+ if (existed && fs.readFileSync(targetFile, 'utf-8') === content) {
324
+ status = status === 'created' ? 'exists' : status;
325
+ continue;
326
+ }
327
+ fs.writeFileSync(targetFile, content);
328
+ if (existed) {
329
+ status = 'updated';
330
+ }
331
+ }
332
+ return { status, name: skillName };
333
+ };
334
+ const buildGeneratedAntigravitySkill = (name, description, body) => `---
335
+ name: ${name}
336
+ description: ${description}
337
+ ---
338
+
339
+ ${body}
340
+ `;
341
+ const installGeneratedAntigravitySkill = (targetSkillsDir, name, description, body) => {
342
+ const skillDir = ensureAntigravitySkillDir(targetSkillsDir, name);
343
+ const targetFile = path.join(skillDir, 'SKILL.md');
344
+ const content = buildGeneratedAntigravitySkill(name, description, rewriteClaudePaths(body, 'antigravity'));
345
+ if (fs.existsSync(targetFile)) {
346
+ if (fs.readFileSync(targetFile, 'utf-8') === content) {
347
+ return { status: 'exists', name };
348
+ }
349
+ fs.writeFileSync(targetFile, content);
350
+ return { status: 'updated', name };
351
+ }
352
+ fs.writeFileSync(targetFile, content);
353
+ return { status: 'created', name };
354
+ };
355
+ const installDirectAntigravitySkill = (targetSkillsDir, name, content) => {
356
+ const skillDir = ensureAntigravitySkillDir(targetSkillsDir, name);
357
+ const targetFile = path.join(skillDir, 'SKILL.md');
358
+ const rewritten = rewriteClaudePaths(content, 'antigravity');
359
+ if (fs.existsSync(targetFile)) {
360
+ if (fs.readFileSync(targetFile, 'utf-8') === rewritten) {
361
+ return { status: 'exists', name };
362
+ }
363
+ fs.writeFileSync(targetFile, rewritten);
364
+ return { status: 'updated', name };
365
+ }
366
+ fs.writeFileSync(targetFile, rewritten);
367
+ return { status: 'created', name };
368
+ };
369
+ const installAntigravityArchitecture = (targetDir) => {
370
+ const results = [];
371
+ const archDir = path.join(ASSETS_DIR, 'architecture');
372
+ const targetArchDir = path.join(targetDir, 'architecture');
373
+ ensureDir(targetArchDir);
374
+ if (!fs.existsSync(archDir)) {
375
+ return results;
376
+ }
377
+ for (const file of getFiles(archDir)) {
378
+ const targetFile = path.join(targetArchDir, path.basename(file));
379
+ const content = rewriteClaudePaths(fs.readFileSync(file, 'utf-8'), 'antigravity');
380
+ if (fs.existsSync(targetFile)) {
381
+ if (fs.readFileSync(targetFile, 'utf-8') === content) {
382
+ results.push({ status: 'exists', name: path.basename(file) });
383
+ continue;
384
+ }
385
+ fs.writeFileSync(targetFile, content);
386
+ results.push({ status: 'updated', name: path.basename(file) });
387
+ continue;
388
+ }
389
+ fs.writeFileSync(targetFile, content);
390
+ results.push({ status: 'created', name: path.basename(file) });
391
+ }
392
+ return results;
393
+ };
394
+ const installAntigravitySkills = (targetDir) => {
395
+ const results = [];
396
+ const targetSkillsDir = path.join(targetDir, 'skills');
397
+ ensureDir(targetSkillsDir);
398
+ const skillsDir = path.join(ASSETS_DIR, 'skills');
399
+ if (fs.existsSync(skillsDir)) {
400
+ for (const dir of getDirs(skillsDir)) {
401
+ results.push(installAntigravitySkillFolder(dir, targetSkillsDir));
402
+ }
403
+ }
404
+ const commandsDir = path.join(ASSETS_DIR, 'commands');
405
+ if (fs.existsSync(commandsDir)) {
406
+ for (const file of getFiles(commandsDir)) {
407
+ const name = path.basename(file, '.md');
408
+ const content = fs.readFileSync(file, 'utf-8');
409
+ results.push(installDirectAntigravitySkill(targetSkillsDir, name, content));
410
+ }
411
+ }
412
+ const agentDirs = ['developers', 'utilities'];
413
+ for (const dirName of agentDirs) {
414
+ const sourceDir = path.join(ASSETS_DIR, 'agents', dirName);
415
+ if (!fs.existsSync(sourceDir)) {
416
+ continue;
417
+ }
418
+ for (const file of getFiles(sourceDir)) {
419
+ const name = path.basename(file, '.md');
420
+ const rawContent = fs.readFileSync(file, 'utf-8');
421
+ const parsed = extractFrontmatter(rawContent);
422
+ const description = parsed.description
423
+ ? parsed.description
424
+ : dirName === 'developers'
425
+ ? `Imported MoiCle developer persona for ${name}. Use when the task matches this stack specialist.`
426
+ : `Imported MoiCle utility persona for ${name}. Use when the task matches this specialist.`;
427
+ results.push(installGeneratedAntigravitySkill(targetSkillsDir, name, description, parsed.body.trimStart()));
428
+ }
429
+ }
430
+ return results;
431
+ };
432
+ const installAntigravityScope = async (scope) => {
433
+ const isGlobal = scope === 'global';
434
+ const label = isGlobal ? 'Global' : 'Project';
435
+ const targetPath = isGlobal ? '~/.gemini/' : `${process.cwd()}/.gemini/`;
436
+ console.log('');
437
+ console.log(chalk.cyan(`>>> ${label} Antigravity Installation`));
438
+ console.log(chalk.gray(` Target: ${targetPath}`));
439
+ console.log('');
440
+ const antigravityDir = getAntigravityDir(scope);
441
+ ensureDir(antigravityDir);
442
+ const archResults = installAntigravityArchitecture(antigravityDir);
443
+ console.log(chalk.green(` ✓ Architecture installed to ${chalk.cyan(path.join(antigravityDir, 'architecture'))}`));
444
+ printSummary(archResults);
445
+ const skillResults = installAntigravitySkills(antigravityDir);
446
+ console.log(chalk.green(` ✓ Antigravity skills installed to ${chalk.cyan(path.join(antigravityDir, 'skills'))}`));
447
+ printSummary(skillResults);
448
+ console.log('');
449
+ console.log(chalk.green(`✓ ${label} Antigravity installation complete!`));
450
+ };
300
451
  const showTargetMenu = async () => {
301
452
  const { target } = await inquirer.prompt([
302
453
  {
@@ -306,14 +457,15 @@ const showTargetMenu = async () => {
306
457
  choices: [
307
458
  { name: 'Claude Code', value: 'claude' },
308
459
  { name: 'Codex CLI', value: 'codex' },
460
+ { name: 'Antigravity', value: 'antigravity' },
309
461
  ],
310
462
  },
311
463
  ]);
312
464
  return target;
313
465
  };
314
466
  const showInteractiveMenu = async (target) => {
315
- const globalPath = target === 'claude' ? '~/.claude/' : '~/.codex/';
316
- const projectPath = target === 'claude' ? './.claude/' : './.codex/';
467
+ const globalPath = target === 'claude' ? '~/.claude/' : target === 'codex' ? '~/.codex/' : '~/.gemini/';
468
+ const projectPath = target === 'claude' ? './.claude/' : target === 'codex' ? './.codex/' : './.gemini/';
317
469
  const { installType } = await inquirer.prompt([
318
470
  {
319
471
  type: 'list',
@@ -401,7 +553,7 @@ export const installCommand = async (options) => {
401
553
  }
402
554
  for (const target of targets) {
403
555
  addTarget(target);
404
- if (target === 'claude' || target === 'codex') {
556
+ if (target === 'claude' || target === 'codex' || target === 'antigravity') {
405
557
  let installType;
406
558
  if (options.global) {
407
559
  installType = 'global';
@@ -420,27 +572,37 @@ export const installCommand = async (options) => {
420
572
  if (target === 'claude') {
421
573
  await installScope('global', useSymlink);
422
574
  }
423
- else {
575
+ else if (target === 'codex') {
424
576
  await installCodexScope('global');
425
577
  }
578
+ else {
579
+ await installAntigravityScope('global');
580
+ }
426
581
  break;
427
582
  case 'project':
428
583
  if (target === 'claude') {
429
584
  await installScope('project', false);
430
585
  }
431
- else {
586
+ else if (target === 'codex') {
432
587
  await installCodexScope('project');
433
588
  }
589
+ else {
590
+ await installAntigravityScope('project');
591
+ }
434
592
  break;
435
593
  case 'all':
436
594
  if (target === 'claude') {
437
595
  await installScope('global', useSymlink);
438
596
  await installScope('project', false);
439
597
  }
440
- else {
598
+ else if (target === 'codex') {
441
599
  await installCodexScope('global');
442
600
  await installCodexScope('project');
443
601
  }
602
+ else {
603
+ await installAntigravityScope('global');
604
+ await installAntigravityScope('project');
605
+ }
444
606
  break;
445
607
  }
446
608
  }
@@ -477,7 +639,13 @@ export const installCommand = async (options) => {
477
639
  console.log(chalk.gray(' Restart Codex after global skill installation to pick up new skills'));
478
640
  console.log('');
479
641
  }
480
- const otherTargets = targets.filter((t) => t !== 'claude' && t !== 'codex');
642
+ if (targets.includes('antigravity')) {
643
+ console.log(chalk.bold(' Antigravity:'));
644
+ console.log(chalk.gray(' Skills installed under ~/.gemini/skills or ./.gemini/skills'));
645
+ console.log(chalk.gray(' Architecture docs installed under ~/.gemini/architecture or ./.gemini/architecture'));
646
+ console.log('');
647
+ }
648
+ const otherTargets = targets.filter((t) => t !== 'claude' && t !== 'codex' && t !== 'antigravity');
481
649
  if (otherTargets.length > 0) {
482
650
  console.log(chalk.bold(' Other Editors:'));
483
651
  for (const target of otherTargets) {