archrip 0.2.10 → 0.2.12
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/dist/install/slash-commands.d.ts +2 -0
- package/dist/install/slash-commands.d.ts.map +1 -1
- package/dist/install/slash-commands.js +23 -18
- package/dist/install/slash-commands.js.map +1 -1
- package/dist/schema/architecture.schema.json +0 -1
- package/dist/templates/slash-commands/{claude → shared}/archrip-scan.md +37 -9
- package/dist/utils/layout.js +10 -8
- package/dist/utils/layout.js.map +1 -1
- package/dist/utils/layout.spec.js +69 -36
- package/dist/utils/layout.spec.js.map +1 -1
- package/dist/utils/validate.d.ts +0 -1
- package/dist/utils/validate.d.ts.map +1 -1
- package/dist/utils/validate.js +0 -3
- package/dist/utils/validate.js.map +1 -1
- package/dist/utils/validate.spec.js +14 -41
- package/dist/utils/validate.spec.js.map +1 -1
- package/dist/viewer-template/package.json +0 -1
- package/dist/viewer-template/src/App.tsx +6 -11
- package/dist/viewer-template/src/components/DetailPanel.tsx +1 -79
- package/dist/viewer-template/src/components/Legend.tsx +1 -1
- package/dist/viewer-template/src/data/loader.ts +1 -14
- package/dist/viewer-template/src/hooks/useArchitecture.ts +1 -3
- package/dist/viewer-template/src/hooks/useUseCaseFilter.ts +1 -8
- package/dist/viewer-template/src/index.css +12 -6
- package/dist/viewer-template/src/types.ts +5 -64
- package/package.json +1 -1
- package/dist/templates/slash-commands/codex/archrip-scan.md +0 -222
- package/dist/templates/slash-commands/codex/archrip-update.md +0 -39
- package/dist/templates/slash-commands/gemini/archrip-scan.md +0 -222
- package/dist/templates/slash-commands/gemini/archrip-update.md +0 -39
- package/dist/viewer-template/src/components/DepthFilter.tsx +0 -43
- package/dist/viewer-template/src/components/nodes/GroupNode.tsx +0 -62
- package/dist/viewer-template/src/hooks/useDepthFilter.ts +0 -192
- package/dist/viewer-template/src/utils/layout.ts +0 -229
- /package/dist/templates/slash-commands/{claude → shared}/archrip-update.md +0 -0
|
@@ -48,12 +48,15 @@
|
|
|
48
48
|
--cat-adapter-bg: #ffedd5;
|
|
49
49
|
--cat-adapter-border: #f97316;
|
|
50
50
|
--cat-adapter-text: #9a3412;
|
|
51
|
-
--cat-
|
|
52
|
-
--cat-
|
|
53
|
-
--cat-
|
|
51
|
+
--cat-entity-bg: #fee2e2;
|
|
52
|
+
--cat-entity-border: #ef4444;
|
|
53
|
+
--cat-entity-text: #991b1b;
|
|
54
54
|
--cat-database-bg: #fef3c7;
|
|
55
55
|
--cat-database-border: #d97706;
|
|
56
56
|
--cat-database-text: #92400e;
|
|
57
|
+
--cat-infrastructure-bg: #e0e7ff;
|
|
58
|
+
--cat-infrastructure-border: #6366f1;
|
|
59
|
+
--cat-infrastructure-text: #3730a3;
|
|
57
60
|
--cat-external-bg: #f3f4f6;
|
|
58
61
|
--cat-external-border: #6b7280;
|
|
59
62
|
--cat-external-text: #374151;
|
|
@@ -107,12 +110,15 @@
|
|
|
107
110
|
--cat-adapter-bg: #2b1a0a;
|
|
108
111
|
--cat-adapter-border: #fb923c;
|
|
109
112
|
--cat-adapter-text: #fdba74;
|
|
110
|
-
--cat-
|
|
111
|
-
--cat-
|
|
112
|
-
--cat-
|
|
113
|
+
--cat-entity-bg: #2b1111;
|
|
114
|
+
--cat-entity-border: #f87171;
|
|
115
|
+
--cat-entity-text: #fca5a5;
|
|
113
116
|
--cat-database-bg: #2b1f06;
|
|
114
117
|
--cat-database-border: #fbbf24;
|
|
115
118
|
--cat-database-text: #fde68a;
|
|
119
|
+
--cat-infrastructure-bg: #1e1b4b;
|
|
120
|
+
--cat-infrastructure-border: #818cf8;
|
|
121
|
+
--cat-infrastructure-text: #a5b4fc;
|
|
116
122
|
--cat-external-bg: #1e2330;
|
|
117
123
|
--cat-external-border: #9ca3af;
|
|
118
124
|
--cat-external-text: #d1d5db;
|
|
@@ -1,47 +1,3 @@
|
|
|
1
|
-
// ─── Depth system ───
|
|
2
|
-
|
|
3
|
-
export type DepthLevel = 0 | 1 | 2;
|
|
4
|
-
|
|
5
|
-
export function computeDepths(nodes: { layer: number }[]): Map<number, DepthLevel> {
|
|
6
|
-
if (nodes.length === 0) return new Map();
|
|
7
|
-
const layers = [...new Set(nodes.map(n => n.layer))].sort((a, b) => a - b);
|
|
8
|
-
|
|
9
|
-
const map = new Map<number, DepthLevel>();
|
|
10
|
-
|
|
11
|
-
// Flat / workflow: filtering not useful — always show all
|
|
12
|
-
if (layers.length <= 2) {
|
|
13
|
-
for (const l of layers) map.set(l, 0);
|
|
14
|
-
return map;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Exactly 3 layers: 1:1:1 mapping
|
|
18
|
-
if (layers.length === 3) {
|
|
19
|
-
map.set(layers[0], 0);
|
|
20
|
-
map.set(layers[1], 1);
|
|
21
|
-
map.set(layers[2], 2);
|
|
22
|
-
return map;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// 4+ layers: equal thirds
|
|
26
|
-
const min = layers[0];
|
|
27
|
-
const max = layers[layers.length - 1];
|
|
28
|
-
const range = max - min;
|
|
29
|
-
const t1 = min + range / 3;
|
|
30
|
-
const t2 = min + (2 * range) / 3;
|
|
31
|
-
for (const l of layers) {
|
|
32
|
-
if (l <= t1) map.set(l, 0);
|
|
33
|
-
else if (l <= t2) map.set(l, 1);
|
|
34
|
-
else map.set(l, 2);
|
|
35
|
-
}
|
|
36
|
-
return map;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const DEPTH_LEVELS = [
|
|
40
|
-
{ level: 0 as const, label: 'Overview' },
|
|
41
|
-
{ level: 1 as const, label: 'Structure' },
|
|
42
|
-
{ level: 2 as const, label: 'Detail' },
|
|
43
|
-
] as const;
|
|
44
|
-
|
|
45
1
|
// ─── Category system ───
|
|
46
2
|
// Standard 8 categories. Custom categories are allowed — they get a fallback color.
|
|
47
3
|
|
|
@@ -62,9 +18,10 @@ const CATEGORY_META = {
|
|
|
62
18
|
service: { label: 'Service', icon: '\u{2699}\u{FE0F}', color: { bg: '#dcfce7', border: '#22c55e', text: '#166534' } },
|
|
63
19
|
port: { label: 'Port', icon: '\u{1F50C}', color: { bg: '#ede9fe', border: '#8b5cf6', text: '#5b21b6' } },
|
|
64
20
|
adapter: { label: 'Adapter', icon: '\u{1F527}', color: { bg: '#ffedd5', border: '#f97316', text: '#9a3412' } },
|
|
65
|
-
|
|
66
|
-
database:
|
|
67
|
-
|
|
21
|
+
entity: { label: 'Entity', icon: '\u{1F4BE}', color: { bg: '#fee2e2', border: '#ef4444', text: '#991b1b' } },
|
|
22
|
+
database: { label: 'Database', icon: '\u{1F5C4}\u{FE0F}', color: { bg: '#fef3c7', border: '#d97706', text: '#92400e' } },
|
|
23
|
+
infrastructure: { label: 'Infrastructure', icon: '\u{1F3D7}\u{FE0F}', color: { bg: '#e0e7ff', border: '#6366f1', text: '#3730a3' } },
|
|
24
|
+
external: { label: 'External', icon: '\u{2601}\u{FE0F}', color: { bg: '#f3f4f6', border: '#6b7280', text: '#374151' } },
|
|
68
25
|
job: { label: 'Job', icon: '\u{23F0}', color: { bg: '#fef9c3', border: '#eab308', text: '#854d0e' } },
|
|
69
26
|
dto: { label: 'DTO', icon: '\u{1F4E6}', color: { bg: '#cffafe', border: '#06b6d4', text: '#155e75' } },
|
|
70
27
|
} as const satisfies Record<string, CategoryMeta>;
|
|
@@ -77,7 +34,7 @@ function getMeta(category: string): CategoryMeta {
|
|
|
77
34
|
return CATEGORY_META[category as StandardCategory] ?? FALLBACK_META;
|
|
78
35
|
}
|
|
79
36
|
|
|
80
|
-
const STANDARD_CATEGORIES = ['controller', 'service', 'port', 'adapter', '
|
|
37
|
+
const STANDARD_CATEGORIES = ['controller', 'service', 'port', 'adapter', 'entity', 'database', 'infrastructure', 'external', 'job', 'dto'] as const;
|
|
81
38
|
|
|
82
39
|
export function getCategoryColors(category: string): CategoryStyle {
|
|
83
40
|
const key = (STANDARD_CATEGORIES as readonly string[]).includes(category) ? category : 'fallback';
|
|
@@ -127,19 +84,10 @@ export interface MetadataEntry {
|
|
|
127
84
|
type?: 'text' | 'code' | 'link' | 'list';
|
|
128
85
|
}
|
|
129
86
|
|
|
130
|
-
export interface MemberNodeSummary {
|
|
131
|
-
id: string;
|
|
132
|
-
label: string;
|
|
133
|
-
description: string;
|
|
134
|
-
filePath: string;
|
|
135
|
-
sourceUrl: string;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
87
|
export interface ArchNodeData {
|
|
139
88
|
[key: string]: unknown;
|
|
140
89
|
label: string;
|
|
141
90
|
category: string;
|
|
142
|
-
depth: DepthLevel;
|
|
143
91
|
description: string;
|
|
144
92
|
filePath: string;
|
|
145
93
|
sourceUrl: string;
|
|
@@ -152,13 +100,6 @@ export interface ArchNodeData {
|
|
|
152
100
|
implements?: string;
|
|
153
101
|
externalService?: string;
|
|
154
102
|
metadata?: MetadataEntry[];
|
|
155
|
-
isGroup?: boolean;
|
|
156
|
-
memberCount?: number;
|
|
157
|
-
memberNodes?: MemberNodeSummary[];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function isGroupNode(data: ArchNodeData): boolean {
|
|
161
|
-
return data.isGroup === true;
|
|
162
103
|
}
|
|
163
104
|
|
|
164
105
|
export interface UseCase {
|
package/package.json
CHANGED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Scan codebase and generate architecture diagram data
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# archrip scan — Analyze codebase architecture
|
|
6
|
-
|
|
7
|
-
Analyze the current codebase and generate `.archrip/architecture.json`.
|
|
8
|
-
|
|
9
|
-
**Language rule:** Respond in the same language as the user's message or `$ARGUMENTS`. If no user text is available, detect the project's primary language from README/docs and match it. The `architecture.json` fields (labels, descriptions) should also use that language.
|
|
10
|
-
|
|
11
|
-
## Phase 1: Project Discovery
|
|
12
|
-
1. Read top-level files (package.json, composer.json, go.mod, Cargo.toml, pom.xml, pyproject.toml, etc.)
|
|
13
|
-
2. Identify language, framework, source root
|
|
14
|
-
3. List directory structure (2 levels deep)
|
|
15
|
-
4. Auto-detect `sourceUrl`: Run `git remote get-url origin` and convert to browse URL:
|
|
16
|
-
- `git@github.com:org/repo.git` → `https://github.com/org/repo/blob/main/{filePath}`
|
|
17
|
-
- `https://github.com/org/repo.git` → `https://github.com/org/repo/blob/main/{filePath}`
|
|
18
|
-
- `git@gitlab.com:org/repo.git` → `https://gitlab.com/org/repo/-/blob/main/{filePath}`
|
|
19
|
-
- If no git remote, leave empty (ask in Phase 7)
|
|
20
|
-
|
|
21
|
-
## Phase 2: Documentation Discovery
|
|
22
|
-
Read existing documentation to understand architecture context:
|
|
23
|
-
1. Check for: README.md, CLAUDE.md, docs/, doc/, wiki/, ARCHITECTURE.md, CONTRIBUTING.md, ADR/
|
|
24
|
-
2. For each document, extract and take notes on:
|
|
25
|
-
- **Business context**: What problem does this system solve? Who are the users?
|
|
26
|
-
- **Component responsibilities**: What each module/service does and why it exists
|
|
27
|
-
- **Design decisions & constraints**: Why certain patterns/libraries were chosen, known limitations
|
|
28
|
-
- **Data flow**: How data moves through the system (request lifecycle, event flow, etc.)
|
|
29
|
-
- **External integrations**: What external services are used, why, and how
|
|
30
|
-
- **Non-functional requirements**: SLAs, performance targets, security policies
|
|
31
|
-
- **Deployment & infrastructure**: Hosting, CI/CD, environment details
|
|
32
|
-
3. Keep these notes — you will use them in Phase 4 to write rich node/edge descriptions and metadata
|
|
33
|
-
|
|
34
|
-
## Phase 3: Layer Identification
|
|
35
|
-
Assign each component a `layer` integer. The rule: **higher layer = closer to domain core (more stable, fewer external dependencies). Lower layer = closer to external world (more volatile, I/O-bound).**
|
|
36
|
-
|
|
37
|
-
Both layouts use this value — dagre places higher layers lower on screen, concentric places them at the center.
|
|
38
|
-
|
|
39
|
-
**Reference mappings** (layer numbers in parentheses — adapt to actual project structure):
|
|
40
|
-
|
|
41
|
-
MVC / Layered:
|
|
42
|
-
- Laravel: External(0) → Controllers(1) → Services(2) → Domain(3)
|
|
43
|
-
- Rails: External(0) → Controllers(1) → Services(2) → Domain(3)
|
|
44
|
-
- Django: External(0) → Views(1) → Serializers(2) → Services(3) → Domain(4)
|
|
45
|
-
- Spring Boot: External(0) → Controllers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
46
|
-
- NestJS: External(0) → Controllers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
47
|
-
- Next.js App Router: External(0) → Route Handlers/Pages(1) → Components(2) → Hooks/Services(3) → Data Access(4)
|
|
48
|
-
- FastAPI: External(0) → Routers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
49
|
-
|
|
50
|
-
DDD / Clean Architecture / Hexagonal (use `"layout": "concentric"`):
|
|
51
|
-
- Generic: External(0) → Adapters(1) [Controllers, DB impl, API clients] → Application Core(2) [Use Cases / Application Services, Ports] → Domain(3)
|
|
52
|
-
- Go (Hex): External(0) → Adapters(1) [Handlers, Repositories] → Application Core(2) [Use Cases, Ports] → Domain(3)
|
|
53
|
-
- Flutter (Clean): External(0) → Data Sources(1) → Repositories(2) → Use Cases(3) → Domain(4)
|
|
54
|
-
- Note: Ports are interfaces owned by the **application core** (use cases / application services; sometimes placed in domain, but not required). Adapters implement outbound Ports and call inbound Ports. For layering, Ports should be at the same layer as the application core (or 1 step closer to Domain), never at the adapter layer.
|
|
55
|
-
|
|
56
|
-
CQRS / Event-Driven:
|
|
57
|
-
- CQRS: External(0) → Command Handlers / Query Handlers(1) → Application Services(2) → Domain(3). Command and Query sides share the same layer structure but separate models
|
|
58
|
-
- Event Sourcing: External(0) → Command Handlers(1) → Event Store(2) → Projections(3) → Read Models(4)
|
|
59
|
-
- Event-Driven (Motia, Temporal, etc.): External(0) → API Steps(1) → Event Steps(2) → Services(3) → Domain(4)
|
|
60
|
-
|
|
61
|
-
Serverless / Microservices:
|
|
62
|
-
- SST/Lambda: External(0) → API Gateway(1) → Lambda Handlers(2) → Services(3) → Domain(4)
|
|
63
|
-
- Microservices: External(0) → Gateway/BFF(1) → Service Boundaries(2) → Internal Services(3) → Shared Domain(4)
|
|
64
|
-
|
|
65
|
-
Modular Monolith:
|
|
66
|
-
- Generic: External(0) → Module APIs(1) [public interfaces] → Module Internal Services(2) → Shared Kernel / Domain(3)
|
|
67
|
-
|
|
68
|
-
For unlisted frameworks: group by directory responsibility and apply the abstract rule above.
|
|
69
|
-
|
|
70
|
-
## Phase 4: Read Key Files
|
|
71
|
-
For each layer, read representative files to extract:
|
|
72
|
-
- Component names and purposes
|
|
73
|
-
- Dependencies (imports, injections)
|
|
74
|
-
- Public methods/routes
|
|
75
|
-
- Database schemas (from migrations or model definitions)
|
|
76
|
-
|
|
77
|
-
**Enrich descriptions from documentation:** Cross-reference code with your Phase 2 notes.
|
|
78
|
-
For each component, compose a `description` (1-3 sentences) that covers:
|
|
79
|
-
- **What**: Its responsibility (from code analysis)
|
|
80
|
-
- **Why**: Business context or design rationale (from docs)
|
|
81
|
-
- **How**: Key implementation details, constraints, or patterns worth noting
|
|
82
|
-
|
|
83
|
-
A good description tells the reader something they cannot see from the label alone.
|
|
84
|
-
- BAD: "User service" (just echoes the label)
|
|
85
|
-
- GOOD: "Handles user registration, login, and profile management. Uses JWT for session tokens with 24h expiry. Password hashing via bcrypt (cost=12)."
|
|
86
|
-
|
|
87
|
-
Also identify metadata candidates:
|
|
88
|
-
- SLA/performance notes → `metadata` with `type: "list"`
|
|
89
|
-
- Related doc links → `metadata` with `type: "link"`
|
|
90
|
-
- Infrastructure details (Lambda ARN, DB engine, etc.) → `metadata` with `type: "code"` or `"text"`
|
|
91
|
-
|
|
92
|
-
**Do NOT read every file.** Focus on entry points, core logic, interfaces, and data models.
|
|
93
|
-
|
|
94
|
-
## Phase 5: Map Relationships
|
|
95
|
-
For each component, identify:
|
|
96
|
-
- What it depends on (imports, constructor injection)
|
|
97
|
-
- What depends on it
|
|
98
|
-
- External service connections
|
|
99
|
-
|
|
100
|
-
**Connectivity check:** After mapping, verify every node has at least one edge. If a node is orphaned:
|
|
101
|
-
- DTOs/entities → connect to the service or adapter that references them
|
|
102
|
-
- External services → connect to the adapter/controller that integrates with them
|
|
103
|
-
- Models → connect to the adapter/repository that queries them
|
|
104
|
-
|
|
105
|
-
## Phase 6: Identify Use Cases
|
|
106
|
-
Group related components into user-facing features.
|
|
107
|
-
|
|
108
|
-
## Phase 7: Draft Review — STOP and ask the developer
|
|
109
|
-
|
|
110
|
-
**IMPORTANT: Do NOT proceed to Phase 8 until the developer responds. You MUST stop here and wait for input.**
|
|
111
|
-
|
|
112
|
-
Present a summary of what you found:
|
|
113
|
-
- **Documents read**: List all docs you read in Phase 2 (e.g., README.md, CLAUDE.md, docs/architecture.md)
|
|
114
|
-
- List of discovered nodes (grouped by layer/category)
|
|
115
|
-
- List of discovered use cases
|
|
116
|
-
- External services found
|
|
117
|
-
|
|
118
|
-
Then ask:
|
|
119
|
-
- Are there other documents you should read? (e.g., docs/, wiki/, design docs)
|
|
120
|
-
- Are there missing components, external services, or use cases?
|
|
121
|
-
- Should anything be excluded?
|
|
122
|
-
- `sourceUrl` auto-detected as: `<detected-url>` — correct? (If not detected, ask for the `sourceUrl` template, e.g., `https://github.com/org/repo/blob/main/{filePath}`)
|
|
123
|
-
|
|
124
|
-
End your message with: **"Please review and reply with corrections, or type 'go' to generate."**
|
|
125
|
-
|
|
126
|
-
**Do NOT write architecture.json yet. Wait for the developer to respond.**
|
|
127
|
-
|
|
128
|
-
If the developer replies with corrections, apply them and present the updated summary. Repeat until they say "go" / "ok" / "skip".
|
|
129
|
-
|
|
130
|
-
## Phase 8: Generate architecture.json
|
|
131
|
-
Only run this phase AFTER the developer has approved the draft in Phase 7.
|
|
132
|
-
|
|
133
|
-
Create `.archrip/` directory if it doesn't exist, then write the complete `.archrip/architecture.json` following the schema, incorporating developer feedback.
|
|
134
|
-
|
|
135
|
-
After writing the file:
|
|
136
|
-
1. Run `npx archrip serve` in the terminal — it auto-builds and opens the browser. **Do NOT run `npx archrip build` separately or open the browser manually** (serve handles everything).
|
|
137
|
-
2. Tell the developer: Run `/archrip-update` to make further adjustments (add/remove nodes, fix relationships, etc.)
|
|
138
|
-
|
|
139
|
-
### Required structure (use EXACTLY these field names)
|
|
140
|
-
|
|
141
|
-
```json
|
|
142
|
-
{
|
|
143
|
-
"version": "1.0",
|
|
144
|
-
"project": { "name": "...", "sourceUrl": "https://github.com/org/repo/blob/main/{filePath}" },
|
|
145
|
-
"nodes": [
|
|
146
|
-
{ "id": "ctrl-users", "category": "controller", "label": "UsersController", "layer": 1, "filePath": "src/controllers/users.ts", "useCases": ["uc-user-mgmt"] }
|
|
147
|
-
],
|
|
148
|
-
"edges": [
|
|
149
|
-
{ "source": "ctrl-users", "target": "svc-users", "type": "dependency" }
|
|
150
|
-
],
|
|
151
|
-
"useCases": [
|
|
152
|
-
{ "id": "uc-user-mgmt", "name": "User Management", "nodeIds": ["ctrl-users", "svc-users"] }
|
|
153
|
-
]
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Critical field names — do NOT use alternatives:**
|
|
158
|
-
- Node: `id`, `category`, `label` (NOT name), `layer` — all required
|
|
159
|
-
- Edge: `source`, `target` (NOT from/to) — all required
|
|
160
|
-
- UseCase: `id`, `name`, `nodeIds` — all required
|
|
161
|
-
|
|
162
|
-
### Node Rules
|
|
163
|
-
- `id`: kebab-case, prefixed by category abbreviation (ctrl-, svc-, port-, adpt-, model-, db-, ext-, job-, dto-)
|
|
164
|
-
- `layer`: non-negative integer. **Higher = closer to domain core / more stable. Lower = closer to external world / more volatile.** Dagre (TB) places higher layers lower on screen; concentric places them at center. Use as many layers as the architecture requires (typically 3-6). Example for DDD/Hex: 0=external, 1=adapters (controllers + infra), 2=application core (use cases/app services + ports), 3=domain. Example for MVC: 0=external, 1=controllers, 2=services, 3=domain.
|
|
165
|
-
- `category`: one of controller, service, port, adapter, model, database, external, job, dto (or custom). Use `model` for domain entities/value objects (core business logic). Use `database` for DB tables, migrations, ORMs, and infrastructure persistence.
|
|
166
|
-
- `label`: display name for the node
|
|
167
|
-
- `description`: 1-3 sentences explaining responsibility + business context. Do NOT just echo the label. Cross-reference documentation for richer context (see Description Guidelines below)
|
|
168
|
-
- `filePath`: relative from project root
|
|
169
|
-
- `depth` (optional): 0=overview, 1=structure, 2=detail. Auto-inferred from `layer` if omitted: with 3+ unique layers, lowest → 0, middle → 1, highest → 2. With 1-2 layers, all nodes get depth 0 (always visible).
|
|
170
|
-
- `useCases`: array of use case IDs this node participates in
|
|
171
|
-
- `metadata` (optional): array of `{ label, value, type? }` entries for supplementary info (AWS ARNs, doc links, SLA notes, etc.). `type` is `text` (default), `code`, `link`, or `list`. `value` is a string, or `string[]` when `type` is `list`. Example:
|
|
172
|
-
```json
|
|
173
|
-
"metadata": [
|
|
174
|
-
{ "label": "Lambda ARN", "value": "arn:aws:lambda:ap-northeast-1:123:function:auth", "type": "code" },
|
|
175
|
-
{ "label": "API Docs", "value": "https://docs.example.com/auth", "type": "link" },
|
|
176
|
-
{ "label": "SLA", "value": ["99.9% uptime", "p95 < 200ms"], "type": "list" }
|
|
177
|
-
]
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Edge Rules
|
|
181
|
-
- `source`: source node id
|
|
182
|
-
- `target`: target node id
|
|
183
|
-
- `type`: dependency | implements | relation
|
|
184
|
-
- `description` (optional): human-readable description of the edge's purpose
|
|
185
|
-
- `metadata` (optional): same format as node metadata — array of `{ label, value, type? }` entries
|
|
186
|
-
- Only include significant architectural dependencies (not utility imports)
|
|
187
|
-
- **Every node MUST have at least one edge.** If a node has no obvious dependency, connect it with a `relation` edge to the component that uses or contains it.
|
|
188
|
-
|
|
189
|
-
### Layout Selection
|
|
190
|
-
- DDD / Clean Architecture / Hexagonal / Onion Architecture → add `"layout": "concentric"` to `project`
|
|
191
|
-
- MVC / standard layered → `"layout": "dagre"` (default, can be omitted)
|
|
192
|
-
|
|
193
|
-
### Description Guidelines
|
|
194
|
-
|
|
195
|
-
#### Node `description`
|
|
196
|
-
Write 1-3 sentences that explain responsibility AND business context.
|
|
197
|
-
Cross-reference project documentation (README, CLAUDE.md, docs/) for richer context.
|
|
198
|
-
- BAD: "User service" (just echoes the label)
|
|
199
|
-
- BAD: "Handles users" (too vague)
|
|
200
|
-
- GOOD: "Handles user registration, authentication, and profile management. Uses JWT for session tokens; password hashing via bcrypt. Rate-limited to 10 req/s per IP."
|
|
201
|
-
|
|
202
|
-
#### Edge `description`
|
|
203
|
-
Explain WHY the dependency exists, not just THAT it exists.
|
|
204
|
-
- BAD: "calls" / "depends on"
|
|
205
|
-
- GOOD: "Delegates payment processing via Stripe SDK; retries on timeout (3x with exponential backoff)"
|
|
206
|
-
|
|
207
|
-
#### `metadata` for supplementary details
|
|
208
|
-
Use `metadata` to capture information from docs that doesn't fit in `description`:
|
|
209
|
-
```json
|
|
210
|
-
"metadata": [
|
|
211
|
-
{ "label": "SLA", "value": ["99.9% uptime", "p95 < 200ms"], "type": "list" },
|
|
212
|
-
{ "label": "Design Doc", "value": "https://...", "type": "link" },
|
|
213
|
-
{ "label": "Infrastructure", "value": "Lambda + DynamoDB (on-demand)", "type": "text" },
|
|
214
|
-
{ "label": "Rate Limit", "value": "10 req/s per IP", "type": "text" }
|
|
215
|
-
]
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Schema Rules
|
|
219
|
-
- Include table schema only when migration files or model annotations are available
|
|
220
|
-
- Reference from node data using schema key name
|
|
221
|
-
|
|
222
|
-
$ARGUMENTS
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Update or refine the architecture diagram
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# archrip update — Update architecture diagram
|
|
6
|
-
|
|
7
|
-
Read `.archrip/architecture.json` and update it.
|
|
8
|
-
|
|
9
|
-
## Mode 1: Auto-detect from git diff (no arguments)
|
|
10
|
-
|
|
11
|
-
If `$ARGUMENTS` is empty:
|
|
12
|
-
|
|
13
|
-
1. Run `git diff --name-only HEAD~10` to find changed files
|
|
14
|
-
2. Read the current `.archrip/architecture.json`
|
|
15
|
-
3. For each changed file:
|
|
16
|
-
- New component? → Add node + edges
|
|
17
|
-
- Removed component? → Remove node + edges + use case references
|
|
18
|
-
- Changed dependencies? → Update edges
|
|
19
|
-
4. Preserve existing node IDs for unchanged components
|
|
20
|
-
5. Write updated `.archrip/architecture.json`
|
|
21
|
-
|
|
22
|
-
## Mode 2: Apply requested changes (with arguments)
|
|
23
|
-
|
|
24
|
-
If `$ARGUMENTS` is provided, apply the user's requested changes:
|
|
25
|
-
- Add/remove/modify nodes
|
|
26
|
-
- Fix relationships
|
|
27
|
-
- Add/modify use cases
|
|
28
|
-
- Adjust layer assignments
|
|
29
|
-
- Add database schemas
|
|
30
|
-
- Add/modify metadata entries
|
|
31
|
-
- Improve descriptions
|
|
32
|
-
|
|
33
|
-
Write the updated `.archrip/architecture.json`.
|
|
34
|
-
|
|
35
|
-
## After Update
|
|
36
|
-
|
|
37
|
-
After writing the file, run `npx archrip serve` in the terminal to rebuild and preview the updated diagram.
|
|
38
|
-
|
|
39
|
-
$ARGUMENTS
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Scan codebase and generate architecture diagram data
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# archrip scan — Analyze codebase architecture
|
|
6
|
-
|
|
7
|
-
Analyze the current codebase and generate `.archrip/architecture.json`.
|
|
8
|
-
|
|
9
|
-
**Language rule:** Respond in the same language as the user's message or `$ARGUMENTS`. If no user text is available, detect the project's primary language from README/docs and match it. The `architecture.json` fields (labels, descriptions) should also use that language.
|
|
10
|
-
|
|
11
|
-
## Phase 1: Project Discovery
|
|
12
|
-
1. Read top-level files (package.json, composer.json, go.mod, Cargo.toml, pom.xml, pyproject.toml, etc.)
|
|
13
|
-
2. Identify language, framework, source root
|
|
14
|
-
3. List directory structure (2 levels deep)
|
|
15
|
-
4. Auto-detect `sourceUrl`: Run `git remote get-url origin` and convert to browse URL:
|
|
16
|
-
- `git@github.com:org/repo.git` → `https://github.com/org/repo/blob/main/{filePath}`
|
|
17
|
-
- `https://github.com/org/repo.git` → `https://github.com/org/repo/blob/main/{filePath}`
|
|
18
|
-
- `git@gitlab.com:org/repo.git` → `https://gitlab.com/org/repo/-/blob/main/{filePath}`
|
|
19
|
-
- If no git remote, leave empty (ask in Phase 7)
|
|
20
|
-
|
|
21
|
-
## Phase 2: Documentation Discovery
|
|
22
|
-
Read existing documentation to understand architecture context:
|
|
23
|
-
1. Check for: README.md, CLAUDE.md, docs/, doc/, wiki/, ARCHITECTURE.md, CONTRIBUTING.md, ADR/
|
|
24
|
-
2. For each document, extract and take notes on:
|
|
25
|
-
- **Business context**: What problem does this system solve? Who are the users?
|
|
26
|
-
- **Component responsibilities**: What each module/service does and why it exists
|
|
27
|
-
- **Design decisions & constraints**: Why certain patterns/libraries were chosen, known limitations
|
|
28
|
-
- **Data flow**: How data moves through the system (request lifecycle, event flow, etc.)
|
|
29
|
-
- **External integrations**: What external services are used, why, and how
|
|
30
|
-
- **Non-functional requirements**: SLAs, performance targets, security policies
|
|
31
|
-
- **Deployment & infrastructure**: Hosting, CI/CD, environment details
|
|
32
|
-
3. Keep these notes — you will use them in Phase 4 to write rich node/edge descriptions and metadata
|
|
33
|
-
|
|
34
|
-
## Phase 3: Layer Identification
|
|
35
|
-
Assign each component a `layer` integer. The rule: **higher layer = closer to domain core (more stable, fewer external dependencies). Lower layer = closer to external world (more volatile, I/O-bound).**
|
|
36
|
-
|
|
37
|
-
Both layouts use this value — dagre places higher layers lower on screen, concentric places them at the center.
|
|
38
|
-
|
|
39
|
-
**Reference mappings** (layer numbers in parentheses — adapt to actual project structure):
|
|
40
|
-
|
|
41
|
-
MVC / Layered:
|
|
42
|
-
- Laravel: External(0) → Controllers(1) → Services(2) → Domain(3)
|
|
43
|
-
- Rails: External(0) → Controllers(1) → Services(2) → Domain(3)
|
|
44
|
-
- Django: External(0) → Views(1) → Serializers(2) → Services(3) → Domain(4)
|
|
45
|
-
- Spring Boot: External(0) → Controllers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
46
|
-
- NestJS: External(0) → Controllers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
47
|
-
- Next.js App Router: External(0) → Route Handlers/Pages(1) → Components(2) → Hooks/Services(3) → Data Access(4)
|
|
48
|
-
- FastAPI: External(0) → Routers(1) → Services(2) → Repositories(3) → Domain(4)
|
|
49
|
-
|
|
50
|
-
DDD / Clean Architecture / Hexagonal (use `"layout": "concentric"`):
|
|
51
|
-
- Generic: External(0) → Adapters(1) [Controllers, DB impl, API clients] → Application Core(2) [Use Cases / Application Services, Ports] → Domain(3)
|
|
52
|
-
- Go (Hex): External(0) → Adapters(1) [Handlers, Repositories] → Application Core(2) [Use Cases, Ports] → Domain(3)
|
|
53
|
-
- Flutter (Clean): External(0) → Data Sources(1) → Repositories(2) → Use Cases(3) → Domain(4)
|
|
54
|
-
- Note: Ports are interfaces owned by the **application core** (use cases / application services; sometimes placed in domain, but not required). Adapters implement outbound Ports and call inbound Ports. For layering, Ports should be at the same layer as the application core (or 1 step closer to Domain), never at the adapter layer.
|
|
55
|
-
|
|
56
|
-
CQRS / Event-Driven:
|
|
57
|
-
- CQRS: External(0) → Command Handlers / Query Handlers(1) → Application Services(2) → Domain(3). Command and Query sides share the same layer structure but separate models
|
|
58
|
-
- Event Sourcing: External(0) → Command Handlers(1) → Event Store(2) → Projections(3) → Read Models(4)
|
|
59
|
-
- Event-Driven (Motia, Temporal, etc.): External(0) → API Steps(1) → Event Steps(2) → Services(3) → Domain(4)
|
|
60
|
-
|
|
61
|
-
Serverless / Microservices:
|
|
62
|
-
- SST/Lambda: External(0) → API Gateway(1) → Lambda Handlers(2) → Services(3) → Domain(4)
|
|
63
|
-
- Microservices: External(0) → Gateway/BFF(1) → Service Boundaries(2) → Internal Services(3) → Shared Domain(4)
|
|
64
|
-
|
|
65
|
-
Modular Monolith:
|
|
66
|
-
- Generic: External(0) → Module APIs(1) [public interfaces] → Module Internal Services(2) → Shared Kernel / Domain(3)
|
|
67
|
-
|
|
68
|
-
For unlisted frameworks: group by directory responsibility and apply the abstract rule above.
|
|
69
|
-
|
|
70
|
-
## Phase 4: Read Key Files
|
|
71
|
-
For each layer, read representative files to extract:
|
|
72
|
-
- Component names and purposes
|
|
73
|
-
- Dependencies (imports, injections)
|
|
74
|
-
- Public methods/routes
|
|
75
|
-
- Database schemas (from migrations or model definitions)
|
|
76
|
-
|
|
77
|
-
**Enrich descriptions from documentation:** Cross-reference code with your Phase 2 notes.
|
|
78
|
-
For each component, compose a `description` (1-3 sentences) that covers:
|
|
79
|
-
- **What**: Its responsibility (from code analysis)
|
|
80
|
-
- **Why**: Business context or design rationale (from docs)
|
|
81
|
-
- **How**: Key implementation details, constraints, or patterns worth noting
|
|
82
|
-
|
|
83
|
-
A good description tells the reader something they cannot see from the label alone.
|
|
84
|
-
- BAD: "User service" (just echoes the label)
|
|
85
|
-
- GOOD: "Handles user registration, login, and profile management. Uses JWT for session tokens with 24h expiry. Password hashing via bcrypt (cost=12)."
|
|
86
|
-
|
|
87
|
-
Also identify metadata candidates:
|
|
88
|
-
- SLA/performance notes → `metadata` with `type: "list"`
|
|
89
|
-
- Related doc links → `metadata` with `type: "link"`
|
|
90
|
-
- Infrastructure details (Lambda ARN, DB engine, etc.) → `metadata` with `type: "code"` or `"text"`
|
|
91
|
-
|
|
92
|
-
**Do NOT read every file.** Focus on entry points, core logic, interfaces, and data models.
|
|
93
|
-
|
|
94
|
-
## Phase 5: Map Relationships
|
|
95
|
-
For each component, identify:
|
|
96
|
-
- What it depends on (imports, constructor injection)
|
|
97
|
-
- What depends on it
|
|
98
|
-
- External service connections
|
|
99
|
-
|
|
100
|
-
**Connectivity check:** After mapping, verify every node has at least one edge. If a node is orphaned:
|
|
101
|
-
- DTOs/entities → connect to the service or adapter that references them
|
|
102
|
-
- External services → connect to the adapter/controller that integrates with them
|
|
103
|
-
- Models → connect to the adapter/repository that queries them
|
|
104
|
-
|
|
105
|
-
## Phase 6: Identify Use Cases
|
|
106
|
-
Group related components into user-facing features.
|
|
107
|
-
|
|
108
|
-
## Phase 7: Draft Review — STOP and ask the developer
|
|
109
|
-
|
|
110
|
-
**IMPORTANT: Do NOT proceed to Phase 8 until the developer responds. You MUST stop here and wait for input.**
|
|
111
|
-
|
|
112
|
-
Present a summary of what you found:
|
|
113
|
-
- **Documents read**: List all docs you read in Phase 2 (e.g., README.md, CLAUDE.md, docs/architecture.md)
|
|
114
|
-
- List of discovered nodes (grouped by layer/category)
|
|
115
|
-
- List of discovered use cases
|
|
116
|
-
- External services found
|
|
117
|
-
|
|
118
|
-
Then ask:
|
|
119
|
-
- Are there other documents you should read? (e.g., docs/, wiki/, design docs)
|
|
120
|
-
- Are there missing components, external services, or use cases?
|
|
121
|
-
- Should anything be excluded?
|
|
122
|
-
- `sourceUrl` auto-detected as: `<detected-url>` — correct? (If not detected, ask for the `sourceUrl` template, e.g., `https://github.com/org/repo/blob/main/{filePath}`)
|
|
123
|
-
|
|
124
|
-
End your message with: **"Please review and reply with corrections, or type 'go' to generate."**
|
|
125
|
-
|
|
126
|
-
**Do NOT write architecture.json yet. Wait for the developer to respond.**
|
|
127
|
-
|
|
128
|
-
If the developer replies with corrections, apply them and present the updated summary. Repeat until they say "go" / "ok" / "skip".
|
|
129
|
-
|
|
130
|
-
## Phase 8: Generate architecture.json
|
|
131
|
-
Only run this phase AFTER the developer has approved the draft in Phase 7.
|
|
132
|
-
|
|
133
|
-
Create `.archrip/` directory if it doesn't exist, then write the complete `.archrip/architecture.json` following the schema, incorporating developer feedback.
|
|
134
|
-
|
|
135
|
-
After writing the file:
|
|
136
|
-
1. Run `npx archrip serve` in the terminal — it auto-builds and opens the browser. **Do NOT run `npx archrip build` separately or open the browser manually** (serve handles everything).
|
|
137
|
-
2. Tell the developer: Run `/archrip-update` to make further adjustments (add/remove nodes, fix relationships, etc.)
|
|
138
|
-
|
|
139
|
-
### Required structure (use EXACTLY these field names)
|
|
140
|
-
|
|
141
|
-
```json
|
|
142
|
-
{
|
|
143
|
-
"version": "1.0",
|
|
144
|
-
"project": { "name": "...", "sourceUrl": "https://github.com/org/repo/blob/main/{filePath}" },
|
|
145
|
-
"nodes": [
|
|
146
|
-
{ "id": "ctrl-users", "category": "controller", "label": "UsersController", "layer": 1, "filePath": "src/controllers/users.ts", "useCases": ["uc-user-mgmt"] }
|
|
147
|
-
],
|
|
148
|
-
"edges": [
|
|
149
|
-
{ "source": "ctrl-users", "target": "svc-users", "type": "dependency" }
|
|
150
|
-
],
|
|
151
|
-
"useCases": [
|
|
152
|
-
{ "id": "uc-user-mgmt", "name": "User Management", "nodeIds": ["ctrl-users", "svc-users"] }
|
|
153
|
-
]
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Critical field names — do NOT use alternatives:**
|
|
158
|
-
- Node: `id`, `category`, `label` (NOT name), `layer` — all required
|
|
159
|
-
- Edge: `source`, `target` (NOT from/to) — all required
|
|
160
|
-
- UseCase: `id`, `name`, `nodeIds` — all required
|
|
161
|
-
|
|
162
|
-
### Node Rules
|
|
163
|
-
- `id`: kebab-case, prefixed by category abbreviation (ctrl-, svc-, port-, adpt-, model-, db-, ext-, job-, dto-)
|
|
164
|
-
- `layer`: non-negative integer. **Higher = closer to domain core / more stable. Lower = closer to external world / more volatile.** Dagre (TB) places higher layers lower on screen; concentric places them at center. Use as many layers as the architecture requires (typically 3-6). Example for DDD/Hex: 0=external, 1=adapters (controllers + infra), 2=application core (use cases/app services + ports), 3=domain. Example for MVC: 0=external, 1=controllers, 2=services, 3=domain.
|
|
165
|
-
- `category`: one of controller, service, port, adapter, model, database, external, job, dto (or custom). Use `model` for domain entities/value objects (core business logic). Use `database` for DB tables, migrations, ORMs, and infrastructure persistence.
|
|
166
|
-
- `label`: display name for the node
|
|
167
|
-
- `description`: 1-3 sentences explaining responsibility + business context. Do NOT just echo the label. Cross-reference documentation for richer context (see Description Guidelines below)
|
|
168
|
-
- `filePath`: relative from project root
|
|
169
|
-
- `depth` (optional): 0=overview, 1=structure, 2=detail. Auto-inferred from `layer` if omitted: with 3+ unique layers, lowest → 0, middle → 1, highest → 2. With 1-2 layers, all nodes get depth 0 (always visible).
|
|
170
|
-
- `useCases`: array of use case IDs this node participates in
|
|
171
|
-
- `metadata` (optional): array of `{ label, value, type? }` entries for supplementary info (AWS ARNs, doc links, SLA notes, etc.). `type` is `text` (default), `code`, `link`, or `list`. `value` is a string, or `string[]` when `type` is `list`. Example:
|
|
172
|
-
```json
|
|
173
|
-
"metadata": [
|
|
174
|
-
{ "label": "Lambda ARN", "value": "arn:aws:lambda:ap-northeast-1:123:function:auth", "type": "code" },
|
|
175
|
-
{ "label": "API Docs", "value": "https://docs.example.com/auth", "type": "link" },
|
|
176
|
-
{ "label": "SLA", "value": ["99.9% uptime", "p95 < 200ms"], "type": "list" }
|
|
177
|
-
]
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Edge Rules
|
|
181
|
-
- `source`: source node id
|
|
182
|
-
- `target`: target node id
|
|
183
|
-
- `type`: dependency | implements | relation
|
|
184
|
-
- `description` (optional): human-readable description of the edge's purpose
|
|
185
|
-
- `metadata` (optional): same format as node metadata — array of `{ label, value, type? }` entries
|
|
186
|
-
- Only include significant architectural dependencies (not utility imports)
|
|
187
|
-
- **Every node MUST have at least one edge.** If a node has no obvious dependency, connect it with a `relation` edge to the component that uses or contains it.
|
|
188
|
-
|
|
189
|
-
### Layout Selection
|
|
190
|
-
- DDD / Clean Architecture / Hexagonal / Onion Architecture → add `"layout": "concentric"` to `project`
|
|
191
|
-
- MVC / standard layered → `"layout": "dagre"` (default, can be omitted)
|
|
192
|
-
|
|
193
|
-
### Description Guidelines
|
|
194
|
-
|
|
195
|
-
#### Node `description`
|
|
196
|
-
Write 1-3 sentences that explain responsibility AND business context.
|
|
197
|
-
Cross-reference project documentation (README, CLAUDE.md, docs/) for richer context.
|
|
198
|
-
- BAD: "User service" (just echoes the label)
|
|
199
|
-
- BAD: "Handles users" (too vague)
|
|
200
|
-
- GOOD: "Handles user registration, authentication, and profile management. Uses JWT for session tokens; password hashing via bcrypt. Rate-limited to 10 req/s per IP."
|
|
201
|
-
|
|
202
|
-
#### Edge `description`
|
|
203
|
-
Explain WHY the dependency exists, not just THAT it exists.
|
|
204
|
-
- BAD: "calls" / "depends on"
|
|
205
|
-
- GOOD: "Delegates payment processing via Stripe SDK; retries on timeout (3x with exponential backoff)"
|
|
206
|
-
|
|
207
|
-
#### `metadata` for supplementary details
|
|
208
|
-
Use `metadata` to capture information from docs that doesn't fit in `description`:
|
|
209
|
-
```json
|
|
210
|
-
"metadata": [
|
|
211
|
-
{ "label": "SLA", "value": ["99.9% uptime", "p95 < 200ms"], "type": "list" },
|
|
212
|
-
{ "label": "Design Doc", "value": "https://...", "type": "link" },
|
|
213
|
-
{ "label": "Infrastructure", "value": "Lambda + DynamoDB (on-demand)", "type": "text" },
|
|
214
|
-
{ "label": "Rate Limit", "value": "10 req/s per IP", "type": "text" }
|
|
215
|
-
]
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Schema Rules
|
|
219
|
-
- Include table schema only when migration files or model annotations are available
|
|
220
|
-
- Reference from node data using schema key name
|
|
221
|
-
|
|
222
|
-
$ARGUMENTS
|