opencode-plugin-mimic 0.1.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.
- package/README.ko.md +189 -0
- package/README.md +289 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1789 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
package/README.ko.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# opencode-plugin-mimic
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/opencode-plugin-mimic)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
[English](./README.md) | **한국어**
|
|
7
|
+
|
|
8
|
+
> 사용자의 작업 패턴을 학습하고 워크플로에 맞게 적응하는 OpenCode 플러그인입니다.
|
|
9
|
+
|
|
10
|
+
Mimic은 작업 방식을 관찰하고, 세션 간 기억을 유지하며, 반복되는 행동을 기반으로 제안을 제공합니다.
|
|
11
|
+
|
|
12
|
+
## 기능
|
|
13
|
+
|
|
14
|
+
- **패턴 감지**: 반복되는 도구 사용, 파일 편집, git 커밋 메시지 감지
|
|
15
|
+
- **세션 기억**: 관찰/마일스톤을 세션 간 보존
|
|
16
|
+
- **여정 기록**: 프로젝트의 진화를 내러티브로 정리
|
|
17
|
+
- **Git 히스토리 분석**: 커밋 메시지/변경 파일 분석
|
|
18
|
+
- **스마트 제안**: 반복 행동에 대한 지름길 제안
|
|
19
|
+
- **프로젝트별 상태**: 프로젝트마다 독립적인 패턴/상태 저장
|
|
20
|
+
- **설정 가능**: 학습/제안 활성화, 임계치 조정
|
|
21
|
+
- **다국어**: 사용자 설정에 따라 영어/한국어 출력
|
|
22
|
+
|
|
23
|
+
## 동작 방식
|
|
24
|
+
|
|
25
|
+
1. **추적**: 도구 호출/파일 편집/git 히스토리 추적
|
|
26
|
+
2. **감지**: 패턴 유형별 분류 (tool/file/commit)
|
|
27
|
+
3. **기억**: 관찰과 마일스톤을 여정에 기록
|
|
28
|
+
4. **제안**: 임계치 도달 시 제안 표면화 및 도구/훅 진화 가능
|
|
29
|
+
5. **지속**: 모든 상태를 `.opencode/mimic/`에 저장
|
|
30
|
+
|
|
31
|
+
## 설치
|
|
32
|
+
|
|
33
|
+
### npm (권장)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g opencode-plugin-mimic
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`~/.config/opencode/opencode.json`에 추가:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"$schema": "https://opencode.ai/config.json",
|
|
44
|
+
"plugin": ["opencode-plugin-mimic"]
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 설정
|
|
49
|
+
|
|
50
|
+
Mimic은 `~/.config/opencode/mimic.json`을 읽어 사용자 설정을 적용합니다.
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"language": "ko-KR"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
기본값은 `en-US`입니다.
|
|
59
|
+
|
|
60
|
+
프로젝트 설정은 `.opencode/mimic/state.json`에 저장되며 `mimic:configure`로 변경할 수 있습니다.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
mimic:configure({ learningEnabled: false })
|
|
64
|
+
mimic:configure({ suggestionEnabled: false })
|
|
65
|
+
mimic:configure({ minPatternCount: 5 })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 기능 흐름도 (draw.io)
|
|
69
|
+
|
|
70
|
+
- 다이어그램 파일: `docs/mimic-flow.drawio`
|
|
71
|
+
- diagrams.net(draw.io)에서 열어 확인/편집 가능합니다.
|
|
72
|
+
|
|
73
|
+
## 사용법
|
|
74
|
+
|
|
75
|
+
Mimic은 다음 도구들을 제공합니다:
|
|
76
|
+
|
|
77
|
+
- `mimic:init`
|
|
78
|
+
- `mimic:status`
|
|
79
|
+
- `mimic:journey`
|
|
80
|
+
- `mimic:patterns`
|
|
81
|
+
- `mimic:observe`
|
|
82
|
+
- `mimic:milestone`
|
|
83
|
+
- `mimic:stats`
|
|
84
|
+
- `mimic:configure`
|
|
85
|
+
- `mimic:surface`
|
|
86
|
+
- `mimic:reset`
|
|
87
|
+
- `mimic:grow`
|
|
88
|
+
- `mimic:evolve`
|
|
89
|
+
- `mimic:level`
|
|
90
|
+
- `mimic:focus`
|
|
91
|
+
- `mimic:mcp-search`
|
|
92
|
+
- `mimic:mcp`
|
|
93
|
+
- `mimic:capabilities`
|
|
94
|
+
|
|
95
|
+
> 참고:
|
|
96
|
+
> - `mimic:evolve` 수락 시 프로젝트에 파일이 생성됩니다 (`.opencode/plugins/`, `.opencode/agents/`) 또는 `opencode.json`이 업데이트됩니다.
|
|
97
|
+
> - `mimic:mcp-search`는 mcpmarket.com 검색 링크와 인기 MCP 서버 목록을 제공합니다.
|
|
98
|
+
> - `mimic:mcp`는 **프로젝트 루트**의 `opencode.json`에 MCP 설정을 추가합니다.
|
|
99
|
+
> - `mimic:level`은 상태에 저장되어 개인화에 사용됩니다.
|
|
100
|
+
|
|
101
|
+
## 상태 구조
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
your-project/
|
|
105
|
+
├── .opencode/
|
|
106
|
+
│ └── mimic/
|
|
107
|
+
│ ├── state.json # 메인 상태 파일
|
|
108
|
+
│ └── sessions/ # 세션별 기록
|
|
109
|
+
│ └── {session-id}.json
|
|
110
|
+
└── opencode.json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### state.json 예시
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"version": "0.3.0",
|
|
118
|
+
"project": {
|
|
119
|
+
"name": "your-project",
|
|
120
|
+
"creatorLevel": null,
|
|
121
|
+
"firstSession": 1705940400000,
|
|
122
|
+
"stack": ["node", "typescript"],
|
|
123
|
+
"focus": "auth refactor"
|
|
124
|
+
},
|
|
125
|
+
"journey": {
|
|
126
|
+
"observations": [
|
|
127
|
+
{ "observation": "Intensive session with 25 tool calls", "timestamp": "..." }
|
|
128
|
+
],
|
|
129
|
+
"milestones": [
|
|
130
|
+
{ "milestone": "Major refactoring session: 15 files edited", "timestamp": "..." }
|
|
131
|
+
],
|
|
132
|
+
"sessionCount": 10,
|
|
133
|
+
"lastSession": "2026-01-22T12:00:00.000Z"
|
|
134
|
+
},
|
|
135
|
+
"patterns": [
|
|
136
|
+
{
|
|
137
|
+
"id": "uuid",
|
|
138
|
+
"type": "tool",
|
|
139
|
+
"description": "Read",
|
|
140
|
+
"count": 50,
|
|
141
|
+
"firstSeen": 1705940400000,
|
|
142
|
+
"lastSeen": 1706026800000,
|
|
143
|
+
"surfaced": false,
|
|
144
|
+
"examples": [{ "tool": "read", "callID": "abc", "timestamp": 1706026800000 }]
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"evolution": {
|
|
148
|
+
"capabilities": [],
|
|
149
|
+
"lastEvolution": null,
|
|
150
|
+
"pendingSuggestions": []
|
|
151
|
+
},
|
|
152
|
+
"preferences": {
|
|
153
|
+
"learningEnabled": true,
|
|
154
|
+
"suggestionEnabled": true,
|
|
155
|
+
"minPatternCount": 3
|
|
156
|
+
},
|
|
157
|
+
"statistics": {
|
|
158
|
+
"totalSessions": 10,
|
|
159
|
+
"totalToolCalls": 250,
|
|
160
|
+
"filesModified": { "src/index.ts": 15 },
|
|
161
|
+
"lastSessionId": null
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 패턴 임계치
|
|
167
|
+
|
|
168
|
+
| 패턴 유형 | 임계치 | 결과 |
|
|
169
|
+
|-----------|--------|------|
|
|
170
|
+
| 도구 사용 | 기본 3회 이상 | 동작 제안 |
|
|
171
|
+
| 도구 사용 | 10회 이상 | 단축키 진화 제안 |
|
|
172
|
+
| 파일 수정 | 5회 이상 | 훅 진화 제안 |
|
|
173
|
+
| 커밋 메시지 | 3회 동일 | 커맨드 진화 제안 |
|
|
174
|
+
|
|
175
|
+
> 참고: 파일/커밋 패턴은 해당 임계치에 도달해야 생성됩니다. 도구 패턴은 첫 사용부터 누적됩니다.
|
|
176
|
+
|
|
177
|
+
## 자동 동작
|
|
178
|
+
|
|
179
|
+
- **세션 시작**: 세션 카운트 증가, 장기 이탈 감지
|
|
180
|
+
- **도구 실행**: 도구 호출 패턴 추적
|
|
181
|
+
- **파일 편집**: 파일 수정 빈도 추적
|
|
182
|
+
- **세션 유휴**: 커밋/파일 패턴 분석 및 제안 출력
|
|
183
|
+
- **세션 종료**: 집중 세션/대규모 리팩터링 기록
|
|
184
|
+
|
|
185
|
+
> Git 기반 기능은 git 저장소가 필요합니다. 저장소가 없으면 관련 섹션이 비어 보일 수 있습니다.
|
|
186
|
+
|
|
187
|
+
## 라이선스
|
|
188
|
+
|
|
189
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# opencode-plugin-mimic
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/opencode-plugin-mimic)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**English** | [한국어](./README.ko.md)
|
|
7
|
+
|
|
8
|
+
> An OpenCode plugin that learns from your patterns and adapts to your workflow.
|
|
9
|
+
|
|
10
|
+
Mimic watches how you work, remembers across sessions, and suggests actions based on what you do repeatedly.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Pattern Detection**: Automatically detects repeated tool usage, file edits, and git commit messages
|
|
15
|
+
- **Session Memory**: Remembers observations and milestones across sessions
|
|
16
|
+
- **Journey Tracking**: Narrative storytelling of your project's evolution
|
|
17
|
+
- **Git History Analysis**: Analyzes commit messages and file modifications
|
|
18
|
+
- **Smart Suggestions**: Offers to create shortcuts for repeated actions
|
|
19
|
+
- **Per-Project State**: Each project gets its own learned patterns
|
|
20
|
+
- **Configurable**: Enable/disable learning and suggestions, adjust thresholds
|
|
21
|
+
- **Internationalization**: English or Korean UI based on user config
|
|
22
|
+
|
|
23
|
+
## How It Works
|
|
24
|
+
|
|
25
|
+
1. **Track**: Mimic tracks tool calls, file edits, and analyzes git history
|
|
26
|
+
2. **Detect**: Patterns are categorized by type (tool, file, commit)
|
|
27
|
+
3. **Remember**: Observations and milestones are recorded for your project's journey
|
|
28
|
+
4. **Suggest**: When patterns reach thresholds, Mimic surfaces suggestions and can evolve them into tools/hooks
|
|
29
|
+
5. **Persist**: All state persists in `.opencode/mimic/`
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
### Via npm (Recommended)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g opencode-plugin-mimic
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then add to your `~/.config/opencode/opencode.json`:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"$schema": "https://opencode.ai/config.json",
|
|
44
|
+
"plugin": ["opencode-plugin-mimic"]
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
Mimic reads `~/.config/opencode/mimic.json` for user-level settings.
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"language": "ko-KR"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Default language is `en-US`.
|
|
59
|
+
|
|
60
|
+
Project preferences live in `.opencode/mimic/state.json` and can be adjusted via `mimic:configure`:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
mimic:configure({ learningEnabled: false })
|
|
64
|
+
mimic:configure({ suggestionEnabled: false })
|
|
65
|
+
mimic:configure({ minPatternCount: 5 })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Flow Diagram (draw.io)
|
|
69
|
+
|
|
70
|
+
- Diagram file: `docs/mimic-flow.drawio`
|
|
71
|
+
- Open it in diagrams.net (draw.io) to view or edit.
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Custom Tools
|
|
76
|
+
|
|
77
|
+
Mimic adds the following tools to OpenCode:
|
|
78
|
+
|
|
79
|
+
#### `mimic:init`
|
|
80
|
+
|
|
81
|
+
Initialize or wake up Mimic for this project. Shows welcome message with session stats and recent observations.
|
|
82
|
+
|
|
83
|
+
#### `mimic:status`
|
|
84
|
+
|
|
85
|
+
Check current status including:
|
|
86
|
+
|
|
87
|
+
- Session count and pattern stats
|
|
88
|
+
- Recently modified files (from git)
|
|
89
|
+
- Recent commits
|
|
90
|
+
- Active suggestions
|
|
91
|
+
|
|
92
|
+
#### `mimic:journey`
|
|
93
|
+
|
|
94
|
+
View the narrative story of your project's evolution:
|
|
95
|
+
|
|
96
|
+
- Milestones achieved
|
|
97
|
+
- Recent observations
|
|
98
|
+
- Git activity timeline
|
|
99
|
+
|
|
100
|
+
#### `mimic:patterns`
|
|
101
|
+
|
|
102
|
+
View all detected patterns organized by type:
|
|
103
|
+
|
|
104
|
+
- **Tool patterns**: Frequently used tools
|
|
105
|
+
- **File patterns**: Frequently modified files
|
|
106
|
+
- **Commit patterns**: Repeated commit messages
|
|
107
|
+
- **Sequence patterns**: Reserved for future detection
|
|
108
|
+
|
|
109
|
+
#### `mimic:observe`
|
|
110
|
+
|
|
111
|
+
Manually add an observation:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
mimic:observe({ observation: "Refactored auth module for better security" })
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `mimic:milestone`
|
|
118
|
+
|
|
119
|
+
Record a project milestone:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
mimic:milestone({ milestone: "v1.0.0 released" })
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `mimic:stats`
|
|
126
|
+
|
|
127
|
+
View detailed statistics:
|
|
128
|
+
|
|
129
|
+
- Total sessions and tool calls
|
|
130
|
+
- Pattern and milestone counts
|
|
131
|
+
- Session records
|
|
132
|
+
- Configuration status
|
|
133
|
+
|
|
134
|
+
#### `mimic:configure`
|
|
135
|
+
|
|
136
|
+
Adjust Mimic's behavior:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
mimic:configure({ learningEnabled: false }) # Stop learning
|
|
140
|
+
mimic:configure({ suggestionEnabled: false }) # Stop suggestions
|
|
141
|
+
mimic:configure({ minPatternCount: 5 }) # Require 5 repetitions
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### `mimic:surface`
|
|
145
|
+
|
|
146
|
+
Mark a pattern as acknowledged:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
mimic:surface({ patternId: "pattern-uuid" })
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### `mimic:reset`
|
|
153
|
+
|
|
154
|
+
Clear all learned data:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
mimic:reset({ confirm: true })
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### `mimic:grow`
|
|
161
|
+
|
|
162
|
+
Analyze project direction and growth opportunities.
|
|
163
|
+
|
|
164
|
+
#### `mimic:evolve`
|
|
165
|
+
|
|
166
|
+
Suggest and create new capabilities based on detected patterns.
|
|
167
|
+
|
|
168
|
+
> When you accept a suggestion, Mimic writes files into your project:
|
|
169
|
+
> - `shortcut` / `command` / `hook` / `skill`: `.opencode/plugins/<name>.js`
|
|
170
|
+
> - `agent`: `.opencode/agents/<name>.md`
|
|
171
|
+
> - `mcp`: updates `opencode.json`
|
|
172
|
+
|
|
173
|
+
#### `mimic:level`
|
|
174
|
+
|
|
175
|
+
Set your technical level (technical, semi-technical, non-technical, chaotic). This is stored in state and used for personalization.
|
|
176
|
+
|
|
177
|
+
#### `mimic:focus`
|
|
178
|
+
|
|
179
|
+
Set current project focus or tech stack.
|
|
180
|
+
|
|
181
|
+
#### `mimic:mcp-search`
|
|
182
|
+
|
|
183
|
+
Returns a search link to mcpmarket.com and a list of popular MCP servers.
|
|
184
|
+
|
|
185
|
+
#### `mimic:mcp`
|
|
186
|
+
|
|
187
|
+
Add an MCP server configuration to the **project-level** `opencode.json`.
|
|
188
|
+
|
|
189
|
+
#### `mimic:capabilities`
|
|
190
|
+
|
|
191
|
+
List all evolved capabilities.
|
|
192
|
+
|
|
193
|
+
## State Structure
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
your-project/
|
|
197
|
+
├── .opencode/
|
|
198
|
+
│ └── mimic/
|
|
199
|
+
│ ├── state.json # Main state file
|
|
200
|
+
│ └── sessions/ # Individual session records
|
|
201
|
+
│ └── {session-id}.json
|
|
202
|
+
└── opencode.json
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### state.json
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"version": "0.3.0",
|
|
210
|
+
"project": {
|
|
211
|
+
"name": "your-project",
|
|
212
|
+
"creatorLevel": null,
|
|
213
|
+
"firstSession": 1705940400000,
|
|
214
|
+
"stack": ["node", "typescript"],
|
|
215
|
+
"focus": "auth refactor"
|
|
216
|
+
},
|
|
217
|
+
"journey": {
|
|
218
|
+
"observations": [
|
|
219
|
+
{ "observation": "Intensive session with 25 tool calls", "timestamp": "..." }
|
|
220
|
+
],
|
|
221
|
+
"milestones": [
|
|
222
|
+
{ "milestone": "Major refactoring session: 15 files edited", "timestamp": "..." }
|
|
223
|
+
],
|
|
224
|
+
"sessionCount": 10,
|
|
225
|
+
"lastSession": "2026-01-22T12:00:00.000Z"
|
|
226
|
+
},
|
|
227
|
+
"patterns": [
|
|
228
|
+
{
|
|
229
|
+
"id": "uuid",
|
|
230
|
+
"type": "tool",
|
|
231
|
+
"description": "Read",
|
|
232
|
+
"count": 50,
|
|
233
|
+
"firstSeen": 1705940400000,
|
|
234
|
+
"lastSeen": 1706026800000,
|
|
235
|
+
"surfaced": false,
|
|
236
|
+
"examples": [{ "tool": "read", "callID": "abc", "timestamp": 1706026800000 }]
|
|
237
|
+
}
|
|
238
|
+
],
|
|
239
|
+
"evolution": {
|
|
240
|
+
"capabilities": [],
|
|
241
|
+
"lastEvolution": null,
|
|
242
|
+
"pendingSuggestions": []
|
|
243
|
+
},
|
|
244
|
+
"preferences": {
|
|
245
|
+
"learningEnabled": true,
|
|
246
|
+
"suggestionEnabled": true,
|
|
247
|
+
"minPatternCount": 3
|
|
248
|
+
},
|
|
249
|
+
"statistics": {
|
|
250
|
+
"totalSessions": 10,
|
|
251
|
+
"totalToolCalls": 250,
|
|
252
|
+
"filesModified": { "src/index.ts": 15 },
|
|
253
|
+
"lastSessionId": null
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Pattern Thresholds
|
|
259
|
+
|
|
260
|
+
| Pattern Type | Threshold | Result |
|
|
261
|
+
|--------------|-----------|--------|
|
|
262
|
+
| Tool usage | 3+ times (default) | Suggest action |
|
|
263
|
+
| Tool usage | 10+ times | Offer shortcut evolution |
|
|
264
|
+
| File modified | 5+ times | Offer hook evolution |
|
|
265
|
+
| Commit message | 3+ identical | Offer command evolution |
|
|
266
|
+
|
|
267
|
+
> Note: File/commit patterns are only created after their thresholds. Tool patterns accumulate from the first use.
|
|
268
|
+
|
|
269
|
+
## Automatic Behaviors
|
|
270
|
+
|
|
271
|
+
- **Session Start**: Increments session count, detects long breaks
|
|
272
|
+
- **Tool Execution**: Tracks every tool call for pattern detection
|
|
273
|
+
- **File Edit**: Tracks file modification frequency
|
|
274
|
+
- **Session Idle**: Analyzes commit/file patterns and surfaces suggestions
|
|
275
|
+
- **Session End**: Records intensive sessions, major refactoring milestones
|
|
276
|
+
|
|
277
|
+
> Git-based insights require a git repository. If none is available, git sections will be empty.
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
pnpm install
|
|
283
|
+
pnpm run build
|
|
284
|
+
pnpm run dev # watch mode
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## License
|
|
288
|
+
|
|
289
|
+
MIT
|