moicle 2.2.0 → 2.2.2
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 +3 -2
- package/assets/architecture/hexagonal-architecture.md +128 -0
- package/assets/commands/bootstrap.md +4 -2
- package/dist/commands/install/generic-editor.d.ts +3 -0
- package/dist/commands/install/generic-editor.d.ts.map +1 -0
- package/dist/commands/install/generic-editor.js +41 -0
- package/dist/commands/install/generic-editor.js.map +1 -0
- package/dist/commands/install/index.d.ts +3 -0
- package/dist/commands/install/index.d.ts.map +1 -0
- package/dist/commands/install/index.js +71 -0
- package/dist/commands/install/index.js.map +1 -0
- package/dist/commands/install/native.d.ts +3 -0
- package/dist/commands/install/native.d.ts.map +1 -0
- package/dist/commands/install/native.js +75 -0
- package/dist/commands/install/native.js.map +1 -0
- package/dist/commands/install/print.d.ts +6 -0
- package/dist/commands/install/print.d.ts.map +1 -0
- package/dist/commands/install/print.js +31 -0
- package/dist/commands/install/print.js.map +1 -0
- package/dist/commands/install/prompts.d.ts +4 -0
- package/dist/commands/install/prompts.d.ts.map +1 -0
- package/dist/commands/install/prompts.js +40 -0
- package/dist/commands/install/prompts.js.map +1 -0
- package/dist/commands/install/skill-editor.d.ts +4 -0
- package/dist/commands/install/skill-editor.d.ts.map +1 -0
- package/dist/commands/install/skill-editor.js +130 -0
- package/dist/commands/install/skill-editor.js.map +1 -0
- package/dist/commands/install/transform.d.ts +15 -0
- package/dist/commands/install/transform.d.ts.map +1 -0
- package/dist/commands/install/transform.js +47 -0
- package/dist/commands/install/transform.js.map +1 -0
- package/dist/commands/install/usage.d.ts +3 -0
- package/dist/commands/install/usage.d.ts.map +1 -0
- package/dist/commands/install/usage.js +72 -0
- package/dist/commands/install/usage.js.map +1 -0
- package/dist/commands/install.d.ts +1 -2
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +1 -657
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/postinstall.d.ts.map +1 -1
- package/dist/commands/postinstall.js +4 -1
- package/dist/commands/postinstall.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ A toolkit to bootstrap and accelerate project development with Claude Code throu
|
|
|
17
17
|
- **16 AI Agents** - 6 developer agents + 10 utility agents
|
|
18
18
|
- **4 Commands** - Wizards for bootstrap, brainstorm, documentation, and marketing
|
|
19
19
|
- **21 Skills** - Auto-triggered workflows for the full SDLC (feature, bug, review, release, ops, content)
|
|
20
|
-
- **
|
|
20
|
+
- **9 Architecture References** - DDD + Hexagonal + stack-specific patterns
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
## Current Support
|
|
@@ -68,11 +68,12 @@ moicle install --target antigravity --global
|
|
|
68
68
|
|
|
69
69
|
## What's Included
|
|
70
70
|
|
|
71
|
-
### Architecture References (
|
|
71
|
+
### Architecture References (9)
|
|
72
72
|
|
|
73
73
|
| File | Description |
|
|
74
74
|
|------|-------------|
|
|
75
75
|
| `clean-architecture.md` | Core Clean Architecture principles |
|
|
76
|
+
| `hexagonal-architecture.md` | Ports & Adapters boundary pattern |
|
|
76
77
|
| `go-backend.md` | Go + Gin project structure |
|
|
77
78
|
| `laravel-backend.md` | Laravel + PHP project structure |
|
|
78
79
|
| `nodejs-nestjs.md` | Node.js + NestJS + Prisma (DDD + Hexagonal) |
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Hexagonal Architecture Reference (Ports & Adapters)
|
|
2
|
+
|
|
3
|
+
> **Structural pattern** behind the standard architecture. This doc focuses on the *Ports & Adapters* mechanics — how the application core is isolated from the outside world. For the tactical building blocks (entities, value objects, usecases, events) see [`ddd-architecture.md`](./ddd-architecture.md), which applies this pattern.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Hexagonal Architecture (Alistair Cockburn, a.k.a. **Ports & Adapters**) isolates the **application core** (business logic) from everything external — UI, DB, HTTP, message brokers, third-party APIs. The core neither knows nor cares *what* drives it or *what* it drives. Everything crosses the boundary through a **port** (interface) implemented by an **adapter**.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
DRIVING SIDE (primary) DRIVEN SIDE (secondary)
|
|
11
|
+
actors that USE the app resources the app DEPENDS ON
|
|
12
|
+
┌──────────────┐ ┌──────────────┐
|
|
13
|
+
│ HTTP handler │──┐ ┌──▶│ PostgreSQL │
|
|
14
|
+
├──────────────┤ │ ┌───────────────────────┐ │ ├──────────────┤
|
|
15
|
+
│ CLI / UI │──┼──▶│ ▶ port APP CORE port ▶ │──▶│ Redis cache │
|
|
16
|
+
├──────────────┤ │ │ (domain + usecases)│ │ ├──────────────┤
|
|
17
|
+
│ Event/Cron │──┘ └───────────────────────┘ └──▶│ Payment API │
|
|
18
|
+
└──────────────┘ ▲ implements implements ▲
|
|
19
|
+
primary adapters driving ports driven ports secondary adapters
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Dependency Rule:** all arrows point **inward, toward the core**. The core defines the ports; adapters depend on the core, never the reverse. Swap any adapter (Postgres → Mongo, REST → gRPC) without touching the core.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## The Two Kinds of Ports
|
|
27
|
+
|
|
28
|
+
| | Driving / Primary port | Driven / Secondary port |
|
|
29
|
+
|---|------------------------|--------------------------|
|
|
30
|
+
| **Who calls whom** | Outside calls the core | Core calls the outside |
|
|
31
|
+
| **Defined by** | The use case the app offers | The need the core has |
|
|
32
|
+
| **Example** | `PlaceOrder`, `GetWallet` | `OrderStore`, `PaymentGateway`, `Clock` |
|
|
33
|
+
| **Implemented by** | The use case / service (core) | An infrastructure adapter |
|
|
34
|
+
| **In this repo** | `application/services/` calling `domain/.../usecases/` | `domain/{domain}/ports/` |
|
|
35
|
+
|
|
36
|
+
> Rule of thumb: a **driving** port is "what the app *does*"; a **driven** port is "what the app *needs*". Both are interfaces; both keep the framework out of the core.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## The Two Kinds of Adapters
|
|
41
|
+
|
|
42
|
+
### Primary / Driving adapters — `application/ports/{transport}/`
|
|
43
|
+
Translate an external trigger into a core call. They adapt *the world → the core*.
|
|
44
|
+
|
|
45
|
+
- HTTP controllers, GraphQL resolvers, CLI commands, UI screens, queue/cron consumers
|
|
46
|
+
- **Thin:** parse input → call a driving port (service/usecase) → map result to a response
|
|
47
|
+
- NO business logic, NO direct DB/infra access
|
|
48
|
+
- One transport = one adapter; the same core is reachable from many adapters
|
|
49
|
+
|
|
50
|
+
### Secondary / Driven adapters — `infrastructure/`
|
|
51
|
+
Implement a driven port so the core can reach a resource. They adapt *the core → the world*.
|
|
52
|
+
|
|
53
|
+
- Repositories (DB), API clients, cache, message publishers, mailers, clock/uuid wrappers
|
|
54
|
+
- **Implement an interface from `domain/{domain}/ports/`** — compile-time checked where the language allows
|
|
55
|
+
- Map between domain types and persistence/wire models; no business rules
|
|
56
|
+
- The only place framework/driver imports are allowed
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Folder Mapping
|
|
61
|
+
|
|
62
|
+
The hexagon maps onto the standard directory structure (same layout as [`ddd-architecture.md`](./ddd-architecture.md)):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
domain/{domain}/
|
|
66
|
+
├── ports/ # DRIVEN ports (interfaces the core needs) ← secondary
|
|
67
|
+
├── usecases/ # DRIVING ports realized (what the app offers) ← primary core
|
|
68
|
+
├── entities/ valueobjects/ events/ ← pure core
|
|
69
|
+
|
|
70
|
+
application/
|
|
71
|
+
├── ports/{transport}/ # PRIMARY adapters (http / ui / cli / consumers) ← driving
|
|
72
|
+
├── services/ # entry into driving ports (thin delegation)
|
|
73
|
+
└── listeners/ # event-driven primary adapters
|
|
74
|
+
|
|
75
|
+
infrastructure/ # SECONDARY adapters (implement domain/ports) ← driven
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Hexagon concept | Lives in | Direction |
|
|
79
|
+
|-----------------|----------|-----------|
|
|
80
|
+
| Application core | `domain/` | depends on nothing |
|
|
81
|
+
| Driving port | `domain/.../usecases/` (+ `application/services/` facade) | core offers |
|
|
82
|
+
| Primary adapter | `application/ports/{transport}/`, `application/listeners/` | world → core |
|
|
83
|
+
| Driven port | `domain/{domain}/ports/` | core needs |
|
|
84
|
+
| Secondary adapter | `infrastructure/` | core → world |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Hard Rules
|
|
89
|
+
|
|
90
|
+
| # | Rule | Violation = |
|
|
91
|
+
|---|------|-------------|
|
|
92
|
+
| HX1 | The core (`domain/`) imports ZERO framework/driver/adapter code | CRITICAL |
|
|
93
|
+
| HX2 | Every crossing of the boundary goes through a port (interface) | CRITICAL |
|
|
94
|
+
| HX3 | Driven ports are **defined by the core**, in `domain/{domain}/ports/` | HIGH |
|
|
95
|
+
| HX4 | Secondary adapters depend on the core, never the core on adapters | CRITICAL |
|
|
96
|
+
| HX5 | Primary adapters are thin: translate + delegate, no business logic | HIGH |
|
|
97
|
+
| HX6 | A port uses domain types in its signature, not framework/DTO types | MEDIUM |
|
|
98
|
+
| HX7 | Wiring (adapter → port → core) happens only at the composition root | HIGH |
|
|
99
|
+
| HX8 | Side effects (time, randomness, I/O) sit behind driven ports for testability | MEDIUM |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Why It Pays Off
|
|
104
|
+
|
|
105
|
+
- **Testable core:** drive use cases directly and stub driven ports — no HTTP server, no DB.
|
|
106
|
+
- **Swappable edges:** replace Postgres with Mongo, REST with gRPC, or a real payment API with a fake, by writing a new adapter only.
|
|
107
|
+
- **Delivery-agnostic:** the same use case is reachable from HTTP, CLI, a queue, or a test, with no core changes.
|
|
108
|
+
- **Clear blast radius:** infrastructure churn stops at the adapter; business rules stay put.
|
|
109
|
+
|
|
110
|
+
## Anti-patterns
|
|
111
|
+
|
|
112
|
+
- **Leaky port:** an interface that exposes `*sql.Rows`, `http.Request`, or an ORM model — drags the framework into the core.
|
|
113
|
+
- **Fat primary adapter:** business logic inside a controller/resolver instead of a use case.
|
|
114
|
+
- **Core reaching out:** `domain/` importing the DB client or HTTP package directly (skipping the port).
|
|
115
|
+
- **Port defined by the adapter:** the interface living in `infrastructure/` instead of `domain/ports/` — inverts the dependency.
|
|
116
|
+
- **Anemic hexagon:** ports/adapters in place but logic still in services/controllers (see anemic-domain anti-pattern in `ddd-architecture.md`).
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Relationship to the Other Docs
|
|
121
|
+
|
|
122
|
+
| Doc | Covers |
|
|
123
|
+
|-----|--------|
|
|
124
|
+
| `hexagonal-architecture.md` (this) | The structural **Ports & Adapters** boundary |
|
|
125
|
+
| `ddd-architecture.md` | Tactical building blocks that fill the core (entities, VOs, usecases, events) + hard rules |
|
|
126
|
+
| `{stack}.md` (go-backend, laravel, nodejs-nestjs, react-frontend, remix-fullstack, flutter-mobile) | How ports/adapters map to a specific framework |
|
|
127
|
+
|
|
128
|
+
Use this doc to reason about **boundaries and direction**; use `ddd-architecture.md` to reason about **what lives inside the core**. Backend stacks (Go, Laravel, NestJS) follow this pattern most strictly; frontends apply a lighter form (driven ports for API/storage adapters).
|
|
@@ -75,13 +75,15 @@ Based on selection, READ the corresponding architecture file:
|
|
|
75
75
|
|
|
76
76
|
| Stack | Architecture File |
|
|
77
77
|
|-------|-------------------|
|
|
78
|
-
| Go + Gin | `go-backend.md` + `clean-architecture.md` |
|
|
79
|
-
| Laravel | `laravel-backend.md` + `clean-architecture.md` |
|
|
78
|
+
| Go + Gin | `go-backend.md` + `clean-architecture.md` + `hexagonal-architecture.md` |
|
|
79
|
+
| Laravel | `laravel-backend.md` + `clean-architecture.md` + `hexagonal-architecture.md` |
|
|
80
80
|
| React + Vite | `react-frontend.md` + `clean-architecture.md` |
|
|
81
81
|
| Remix | `remix-fullstack.md` + `clean-architecture.md` |
|
|
82
82
|
| Flutter | `flutter-mobile.md` + `clean-architecture.md` |
|
|
83
83
|
| Monorepo | `monorepo.md` + relevant app architectures |
|
|
84
84
|
|
|
85
|
+
> **Hexagonal (Ports & Adapters)** is the standard boundary pattern for backend stacks — read `hexagonal-architecture.md` alongside the stack doc. Frontends apply a lighter form (driven ports for API/storage).
|
|
86
|
+
|
|
85
87
|
## Step 3: Get Project Info
|
|
86
88
|
|
|
87
89
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic-editor.d.ts","sourceRoot":"","sources":["../../../src/commands/install/generic-editor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAgCtE,eAAO,MAAM,qBAAqB,GAAU,QAAQ,YAAY,EAAE,OAAO,KAAK,KAAG,OAAO,CAAC,UAAU,EAAE,CA2BpG,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { ASSETS_DIR, ensureDir, copyFile, getEditorConfig, getEditorDir, getFiles, mergeAgentsToFile, } from '../../utils/symlink.js';
|
|
5
|
+
import { printSummary } from './print.js';
|
|
6
|
+
/**
|
|
7
|
+
* Rules-file editors (Cursor, Windsurf). These do not support discrete
|
|
8
|
+
* agents/commands/skills — agent personas are merged into a single rules file
|
|
9
|
+
* (AGENTS.md / global_rules.md), and architecture docs are copied alongside.
|
|
10
|
+
*/
|
|
11
|
+
const installArchitectureForEditor = (targetDir) => {
|
|
12
|
+
const archDir = path.join(ASSETS_DIR, 'architecture');
|
|
13
|
+
const targetArchDir = path.join(targetDir, 'architecture');
|
|
14
|
+
ensureDir(targetArchDir);
|
|
15
|
+
if (!fs.existsSync(archDir)) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return getFiles(archDir).map((file) => copyFile(file, path.join(targetArchDir, path.basename(file))));
|
|
19
|
+
};
|
|
20
|
+
export const installForOtherEditor = async (target, scope) => {
|
|
21
|
+
const config = getEditorConfig(target);
|
|
22
|
+
const targetDir = getEditorDir(target, scope);
|
|
23
|
+
const results = [];
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log(chalk.cyan(`>>> ${config.name} Installation`));
|
|
26
|
+
console.log(chalk.gray(` Target: ${targetDir}`));
|
|
27
|
+
console.log('');
|
|
28
|
+
ensureDir(targetDir);
|
|
29
|
+
results.push(...installArchitectureForEditor(targetDir));
|
|
30
|
+
console.log(chalk.green(` ✓ Architecture installed to ${chalk.cyan(path.join(targetDir, 'architecture'))}`));
|
|
31
|
+
if (config.rulesFile) {
|
|
32
|
+
const result = mergeAgentsToFile(path.join(targetDir, config.rulesFile), target);
|
|
33
|
+
results.push(result);
|
|
34
|
+
console.log(chalk.green(` ✓ Agents merged to ${chalk.cyan(config.rulesFile)}`));
|
|
35
|
+
}
|
|
36
|
+
printSummary(results);
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(chalk.green(`✓ ${config.name} installation complete!`));
|
|
39
|
+
return results;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=generic-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic-editor.js","sourceRoot":"","sources":["../../../src/commands/install/generic-editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EACL,UAAU,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;GAIG;AAEH,MAAM,4BAA4B,GAAG,CAAC,SAAiB,EAAgB,EAAE;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC3D,SAAS,CAAC,aAAa,CAAC,CAAC;IAEzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACpC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,MAAoB,EAAE,KAAY,EAAyB,EAAE;IACvG,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,SAAS,CAAC,SAAS,CAAC,CAAC;IAErB,OAAO,CAAC,IAAI,CAAC,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9G,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,YAAY,CAAC,OAAO,CAAC,CAAC;IAEtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,IAAI,yBAAyB,CAAC,CAAC,CAAC;IAEpE,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/install/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,gBAAgB,CAAC;AA6C1E,eAAO,MAAM,cAAc,GAAU,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CAsC1E,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { ASSETS_DIR, isSymlinkSupported } from '../../utils/symlink.js';
|
|
4
|
+
import { addTarget } from '../../utils/config.js';
|
|
5
|
+
import { printHeader } from './print.js';
|
|
6
|
+
import { installScope } from './native.js';
|
|
7
|
+
import { installSkillEditorScope } from './skill-editor.js';
|
|
8
|
+
import { installForOtherEditor } from './generic-editor.js';
|
|
9
|
+
import { showTargetMenu, showInteractiveMenu } from './prompts.js';
|
|
10
|
+
import { printUsage } from './usage.js';
|
|
11
|
+
const isScopedTarget = (target) => target === 'claude' || target === 'codex' || target === 'antigravity';
|
|
12
|
+
const resolveStrategy = (options) => {
|
|
13
|
+
if (options.symlink === true)
|
|
14
|
+
return true;
|
|
15
|
+
if (options.symlink === false)
|
|
16
|
+
return false;
|
|
17
|
+
return isSymlinkSupported();
|
|
18
|
+
};
|
|
19
|
+
const resolveInstallType = async (options, target) => {
|
|
20
|
+
if (options.global)
|
|
21
|
+
return 'global';
|
|
22
|
+
if (options.project)
|
|
23
|
+
return 'project';
|
|
24
|
+
if (options.all)
|
|
25
|
+
return 'all';
|
|
26
|
+
return showInteractiveMenu(target);
|
|
27
|
+
};
|
|
28
|
+
/** Install a scoped target (claude/codex/antigravity) into one scope. */
|
|
29
|
+
const installScopedTarget = async (target, scope, useSymlink) => {
|
|
30
|
+
if (target === 'claude') {
|
|
31
|
+
// Symlinks only make sense for the global, shared install.
|
|
32
|
+
await installScope(scope, scope === 'global' ? useSymlink : false);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await installSkillEditorScope(scope, target);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export const installCommand = async (options) => {
|
|
39
|
+
printHeader();
|
|
40
|
+
if (!fs.existsSync(ASSETS_DIR)) {
|
|
41
|
+
console.log(chalk.red('Error: Assets directory not found.'));
|
|
42
|
+
console.log(chalk.gray(`Expected: ${ASSETS_DIR}`));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const useSymlink = resolveStrategy(options);
|
|
46
|
+
const strategyLabel = useSymlink ? 'symlinks' : 'file copy';
|
|
47
|
+
if (options.symlink === undefined) {
|
|
48
|
+
console.log(chalk.gray(` Auto-detected file strategy: ${strategyLabel} (${process.platform})`));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.log(chalk.gray(` File strategy: ${strategyLabel} (user override)`));
|
|
52
|
+
}
|
|
53
|
+
console.log('');
|
|
54
|
+
const targets = options.target ? [options.target] : [await showTargetMenu()];
|
|
55
|
+
for (const target of targets) {
|
|
56
|
+
addTarget(target);
|
|
57
|
+
if (!isScopedTarget(target)) {
|
|
58
|
+
await installForOtherEditor(target, 'global');
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const installType = await resolveInstallType(options, target);
|
|
62
|
+
if (installType === 'global' || installType === 'all') {
|
|
63
|
+
await installScopedTarget(target, 'global', useSymlink);
|
|
64
|
+
}
|
|
65
|
+
if (installType === 'project' || installType === 'all') {
|
|
66
|
+
await installScopedTarget(target, 'project', useSymlink);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
printUsage(targets);
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/install/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/commands/install/native.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAuExD,eAAO,MAAM,YAAY,GAAU,OAAO,KAAK,EAAE,YAAY,OAAO,KAAG,OAAO,CAAC,IAAI,CAyBlF,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { ASSETS_DIR, ensureDir, createSymlink, copyFile, copyDir, getAgentsDir, getCommandsDir, getSkillsDir, getArchitectureDir, getClaudeDir, getFiles, getDirs, } from '../../utils/symlink.js';
|
|
5
|
+
import { printInstalled } from './print.js';
|
|
6
|
+
/**
|
|
7
|
+
* Claude native install: assets are symlinked (or copied) verbatim into
|
|
8
|
+
* ~/.claude/{agents,commands,skills,architecture}. This is the only target
|
|
9
|
+
* that supports symlinks and the full agents/commands/skills layout.
|
|
10
|
+
*/
|
|
11
|
+
/** Symlink or copy every file from a source dir into the target dir. */
|
|
12
|
+
const linkFiles = (sourceDir, targetDir, useSymlink) => {
|
|
13
|
+
if (!fs.existsSync(sourceDir)) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
return getFiles(sourceDir).map((file) => {
|
|
17
|
+
const target = path.join(targetDir, path.basename(file));
|
|
18
|
+
return useSymlink ? createSymlink(file, target) : copyFile(file, target);
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const installAgents = (targetDir, useSymlink) => {
|
|
22
|
+
ensureDir(targetDir);
|
|
23
|
+
const results = [
|
|
24
|
+
...linkFiles(path.join(ASSETS_DIR, 'agents', 'developers'), targetDir, useSymlink),
|
|
25
|
+
...linkFiles(path.join(ASSETS_DIR, 'agents', 'utilities'), targetDir, useSymlink),
|
|
26
|
+
];
|
|
27
|
+
printInstalled('Agents', targetDir, results);
|
|
28
|
+
return results;
|
|
29
|
+
};
|
|
30
|
+
const installCommands = (targetDir, useSymlink) => {
|
|
31
|
+
ensureDir(targetDir);
|
|
32
|
+
const results = linkFiles(path.join(ASSETS_DIR, 'commands'), targetDir, useSymlink);
|
|
33
|
+
printInstalled('Commands', targetDir, results);
|
|
34
|
+
return results;
|
|
35
|
+
};
|
|
36
|
+
const installSkills = (targetDir, useSymlink) => {
|
|
37
|
+
ensureDir(targetDir);
|
|
38
|
+
const skillsDir = path.join(ASSETS_DIR, 'skills');
|
|
39
|
+
const results = fs.existsSync(skillsDir)
|
|
40
|
+
? getDirs(skillsDir).map((dir) => {
|
|
41
|
+
const target = path.join(targetDir, path.basename(dir));
|
|
42
|
+
return useSymlink ? createSymlink(dir, target) : copyDir(dir, target);
|
|
43
|
+
})
|
|
44
|
+
: [];
|
|
45
|
+
printInstalled('Skills', targetDir, results);
|
|
46
|
+
return results;
|
|
47
|
+
};
|
|
48
|
+
const installArchitecture = (targetDir, useSymlink) => {
|
|
49
|
+
ensureDir(targetDir);
|
|
50
|
+
const results = linkFiles(path.join(ASSETS_DIR, 'architecture'), targetDir, useSymlink);
|
|
51
|
+
printInstalled('Architecture', targetDir, results);
|
|
52
|
+
return results;
|
|
53
|
+
};
|
|
54
|
+
export const installScope = async (scope, useSymlink) => {
|
|
55
|
+
const isGlobal = scope === 'global';
|
|
56
|
+
const label = isGlobal ? 'Global' : 'Project';
|
|
57
|
+
const targetPath = isGlobal ? '~/.claude/' : `${process.cwd()}/.claude/`;
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log(chalk.cyan(`>>> ${label} Installation`));
|
|
60
|
+
console.log(chalk.gray(` Target: ${targetPath}`));
|
|
61
|
+
console.log('');
|
|
62
|
+
ensureDir(getClaudeDir(scope));
|
|
63
|
+
installAgents(getAgentsDir(scope), useSymlink);
|
|
64
|
+
if (isGlobal) {
|
|
65
|
+
installCommands(getCommandsDir(scope), useSymlink);
|
|
66
|
+
}
|
|
67
|
+
installSkills(getSkillsDir(scope), useSymlink);
|
|
68
|
+
installArchitecture(getArchitectureDir(scope), useSymlink);
|
|
69
|
+
if (!isGlobal) {
|
|
70
|
+
console.log(chalk.gray(' Note: Commands are installed globally only'));
|
|
71
|
+
}
|
|
72
|
+
console.log('');
|
|
73
|
+
console.log(chalk.green(`✓ ${label} installation complete!`));
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/commands/install/native.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FileResult } from '../../types.js';
|
|
2
|
+
export declare const printHeader: () => void;
|
|
3
|
+
export declare const printSummary: (results: FileResult[]) => void;
|
|
4
|
+
/** Print "✓ <what> installed to <dir>" followed by the status summary. */
|
|
5
|
+
export declare const printInstalled: (what: string, targetDir: string, results: FileResult[]) => void;
|
|
6
|
+
//# sourceMappingURL=print.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print.d.ts","sourceRoot":"","sources":["../../../src/commands/install/print.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,WAAW,QAAO,IAM9B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,UAAU,EAAE,KAAG,IAYpD,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,EAAE,SAAS,UAAU,EAAE,KAAG,IAGvF,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export const printHeader = () => {
|
|
3
|
+
console.log('');
|
|
4
|
+
console.log(chalk.cyan('════════════════════════════════════════'));
|
|
5
|
+
console.log(chalk.cyan(' MoiCle Installer'));
|
|
6
|
+
console.log(chalk.cyan('════════════════════════════════════════'));
|
|
7
|
+
console.log('');
|
|
8
|
+
};
|
|
9
|
+
export const printSummary = (results) => {
|
|
10
|
+
const created = results.filter((r) => r.status === 'created').length;
|
|
11
|
+
const updated = results.filter((r) => r.status === 'updated').length;
|
|
12
|
+
const exists = results.filter((r) => r.status === 'exists').length;
|
|
13
|
+
const skipped = results.filter((r) => r.status === 'skipped').length;
|
|
14
|
+
const errors = results.filter((r) => r.status === 'error').length;
|
|
15
|
+
if (created > 0)
|
|
16
|
+
console.log(chalk.green(` Created: ${created}`));
|
|
17
|
+
if (updated > 0)
|
|
18
|
+
console.log(chalk.yellow(` Updated: ${updated}`));
|
|
19
|
+
if (exists > 0)
|
|
20
|
+
console.log(chalk.gray(` Already exists: ${exists}`));
|
|
21
|
+
if (skipped > 0)
|
|
22
|
+
console.log(chalk.gray(` Skipped: ${skipped}`));
|
|
23
|
+
if (errors > 0)
|
|
24
|
+
console.log(chalk.red(` Errors: ${errors}`));
|
|
25
|
+
};
|
|
26
|
+
/** Print "✓ <what> installed to <dir>" followed by the status summary. */
|
|
27
|
+
export const printInstalled = (what, targetDir, results) => {
|
|
28
|
+
console.log(chalk.green(` ✓ ${what} installed to ${chalk.cyan(targetDir)}`));
|
|
29
|
+
printSummary(results);
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=print.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/commands/install/print.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,CAAC,MAAM,WAAW,GAAG,GAAS,EAAE;IACpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAqB,EAAQ,EAAE;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACnE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IAElE,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC;IACvE,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAE,OAAqB,EAAQ,EAAE;IAC7F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,iBAAiB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,YAAY,CAAC,OAAO,CAAC,CAAC;AACxB,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EditorTarget } from '../../types.js';
|
|
2
|
+
export declare const showTargetMenu: () => Promise<EditorTarget>;
|
|
3
|
+
export declare const showInteractiveMenu: (target: "claude" | "codex" | "antigravity") => Promise<"global" | "project" | "all">;
|
|
4
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/install/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,YAAY,CAiB3D,CAAC;AAQF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,QAAQ,GAAG,OAAO,GAAG,aAAa,KACzC,OAAO,CAAC,QAAQ,GAAG,SAAS,GAAG,KAAK,CAiBtC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
export const showTargetMenu = async () => {
|
|
3
|
+
const { target } = await inquirer.prompt([
|
|
4
|
+
{
|
|
5
|
+
type: 'list',
|
|
6
|
+
name: 'target',
|
|
7
|
+
message: 'Which editor would you like to configure?',
|
|
8
|
+
choices: [
|
|
9
|
+
{ name: 'Claude Code', value: 'claude' },
|
|
10
|
+
{ name: 'Codex CLI', value: 'codex' },
|
|
11
|
+
{ name: 'Antigravity', value: 'antigravity' },
|
|
12
|
+
{ name: 'Cursor', value: 'cursor' },
|
|
13
|
+
{ name: 'Windsurf', value: 'windsurf' },
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
return target;
|
|
18
|
+
};
|
|
19
|
+
const SCOPE_PATHS = {
|
|
20
|
+
claude: { global: '~/.claude/', project: './.claude/' },
|
|
21
|
+
codex: { global: '~/.codex/', project: './.codex/' },
|
|
22
|
+
antigravity: { global: '~/.gemini/', project: './.gemini/' },
|
|
23
|
+
};
|
|
24
|
+
export const showInteractiveMenu = async (target) => {
|
|
25
|
+
const { global: globalPath, project: projectPath } = SCOPE_PATHS[target];
|
|
26
|
+
const { installType } = await inquirer.prompt([
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
name: 'installType',
|
|
30
|
+
message: 'Where would you like to install?',
|
|
31
|
+
choices: [
|
|
32
|
+
{ name: `Global (${globalPath}) - Available for all projects`, value: 'global' },
|
|
33
|
+
{ name: `Project (${projectPath}) - This project only`, value: 'project' },
|
|
34
|
+
{ name: 'Both - Global and current project', value: 'all' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
38
|
+
return installType;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/install/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAGhC,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAA2B,EAAE;IAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACvC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2CAA2C;YACpD,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE;gBACxC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE;gBACrC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;gBAC7C,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;gBACnC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;aACxC;SACF;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,WAAW,GAAoF;IACnG,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;IACvD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE;IACpD,WAAW,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;CAC7D,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,MAA0C,EACH,EAAE;IACzC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC5C;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,kCAAkC;YAC3C,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,WAAW,UAAU,gCAAgC,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAChF,EAAE,IAAI,EAAE,YAAY,WAAW,uBAAuB,EAAE,KAAK,EAAE,SAAS,EAAE;gBAC1E,EAAE,IAAI,EAAE,mCAAmC,EAAE,KAAK,EAAE,KAAK,EAAE;aAC5D;SACF;KACF,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-editor.d.ts","sourceRoot":"","sources":["../../../src/commands/install/skill-editor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EACL,KAAK,iBAAiB,EAIvB,MAAM,gBAAgB,CAAC;AA4IxB,eAAO,MAAM,uBAAuB,GAAU,OAAO,KAAK,EAAE,QAAQ,iBAAiB,KAAG,OAAO,CAAC,IAAI,CAuBnG,CAAC"}
|