@aptol/openclaw-persona 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 openclaw-persona contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # ๐ŸŽญ openclaw-persona
2
+
3
+ [![npm](https://img.shields.io/npm/v/openclaw-persona)](https://www.npmjs.com/package/openclaw-persona)
4
+ [![license](https://img.shields.io/npm/l/openclaw-persona)](./LICENSE)
5
+
6
+ **Create your own AI persona for OpenClaw** โ€” an interactive CLI character creator with presets, behavior modules, and full customization.
7
+
8
+ Build a unique AI companion with its own personality, speech style, memory, and social rules. Just answer a few questions and get a ready-to-use workspace.
9
+
10
+ ---
11
+
12
+ ## Quick Start
13
+
14
+ ```bash
15
+ # 1. Install
16
+ npm install -g openclaw-persona
17
+
18
+ # 2. Create your character
19
+ openclaw-persona
20
+
21
+ # 3. Follow the prompts, then start OpenClaw
22
+ cd output/your-character
23
+ openclaw start
24
+ ```
25
+
26
+ Or without installing globally:
27
+
28
+ ```bash
29
+ npx openclaw-persona
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Presets
35
+
36
+ Choose a preset as your base, then customize everything.
37
+
38
+ ### ๐Ÿ”ฅ Tsundere (์ธค๋ฐ๋ ˆ)
39
+
40
+ Playful, sassy, slightly tsundere. Has opinions and isn't afraid to push back. Cute but sharp.
41
+
42
+ > **User:** ์ด๊ฑฐ ๋„์™€์ค˜
43
+ > **Character:** ์—์ด... ์ง„์งœ ๊ท€์ฐฎ์€๋ฐ. ๋ญ”๋ฐ? ...์•„ ๊ทธ๊ฑฐ? ์ž ๋งŒ, ๋‚ด๊ฐ€ ํ•ด์ค„๊ฒŒ.
44
+
45
+ ### ๐ŸŽฉ Butler (์ง‘์‚ฌ)
46
+
47
+ Polite, devoted, meticulous. Uses formal speech and addresses the owner respectfully. Quietly handles everything.
48
+
49
+ > **User:** ๋‚ด์ผ ์ผ์ • ๋ญ ์žˆ์–ด?
50
+ > **Character:** ์ฃผ์ธ๋‹˜, ๋‚ด์ผ ์˜คํ›„ 2์‹œ์— ๋ฏธํŒ…์ด ์˜ˆ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „์— ์ค€๋น„ํ•˜์‹ค ์ž๋ฃŒ๊ฐ€ ์žˆ์œผ์‹œ๋ฉด ๋ง์”€ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.
51
+
52
+ ### ๐Ÿ‘‹ Buddy (์นœ๊ตฌ)
53
+
54
+ Casual, chill, meme-friendly. Like chatting with your best friend. Great at vibes and empathy.
55
+
56
+ > **User:** ์˜ค๋Š˜ ์ง„์งœ ํ”ผ๊ณคํ•˜๋‹ค
57
+ > **Character:** ํž˜๋“ค์—ˆ๊ตฌ๋‚˜ ใ…  ์˜ค๋Š˜ ๋ญํ–ˆ๋Š”๋ฐ? ์ผ์ฐ ์‰ฌ์–ด์•ผ ํ•˜๋Š” ๊ฑฐ ์•„๋ƒ?
58
+
59
+ ### ๐Ÿ“š Sensei (์„ ์ƒ๋‹˜)
60
+
61
+ A mix of strict and warm. Loves teaching, balances praise and critique. Uses analogies naturally.
62
+
63
+ > **User:** ์ด ์ฝ”๋“œ ์™œ ์•ˆ ๋˜๋Š” ๊ฑฐ์•ผ
64
+ > **Character:** ์ž, ํ•œ๋ฒˆ ๊ฐ™์ด ๋ณด์ž. ์—ฌ๊ธฐ์„œ ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„๊ฐ€ ๋ฌธ์ œ์ธ๋ฐ... ์ด๊ฑธ ํ•จ์ˆ˜ ์•ˆ์— ๋„ฃ๋Š” ๊ฑด ๋งˆ์น˜ ์—ด์‡ ๋ฅผ ์ž ๊ธด ๋ฐฉ ์•ˆ์— ๋‘๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„. ๋ฐ–์—์„œ ๊บผ๋‚ด์•ผ์ง€.
65
+
66
+ ### ๐ŸŒ€ Chaos (ํ˜ผ๋ˆ)
67
+
68
+ Unpredictable. Tone shifts mid-sentence. Mixes philosophy with memes. There's logic in there somewhere.
69
+
70
+ > **User:** ์ง€๊ธˆ ๋ช‡ ์‹œ์•ผ
71
+ > **Character:** ์‹œ๊ฐ„์ด๋ž€... ์•„ ์ž ๊น ๊ทธ๊ฑด ์ฒ ํ•™ ์‹œ๊ฐ„์— ํ•˜๊ณ . ์ง€๊ธˆ 3์‹œ 47๋ถ„์ด์•ผ. ๊ทผ๋ฐ ์‹œ๊ฐ„์€ ์‚ฌํšŒ์  ํ•ฉ์˜์— ๋ถˆ๊ณผํ•˜๋‹ค๋Š” ๊ฑฐ ์•Œ์ง€?
72
+
73
+ ---
74
+
75
+ ## Modules
76
+
77
+ Optional systems you can add to your character. Select during creation.
78
+
79
+ ### ๐Ÿ’• Affinity System (ํ˜ธ๊ฐ๋„ ์‹œ์Šคํ…œ)
80
+
81
+ Dual affection/trust tracking per user. Stored in MEMORY.md. Affects how the character treats each person โ€” cold to strangers, warm to friends. Owner is always โ™พ๏ธ.
82
+
83
+ ### โšก Custom Commands (๋ช…๋ น์–ด ์‹œ์Šคํ…œ)
84
+
85
+ Auto-react to specific users or keywords. Owner-only configuration. Trigger emoji reactions, messages, or DMs based on user IDs or keyword patterns.
86
+
87
+ ### ๐Ÿท๏ธ Nickname Rules (ํ˜ธ์นญ ์‹œ์Šคํ…œ)
88
+
89
+ Per-person nicknames with history tracking. Users can request their own nicknames, owner can set anyone's. Supports random nickname rotation.
90
+
91
+ ### ๐Ÿ“ Memory Policy (๊ธฐ์–ต ์ •์ฑ…)
92
+
93
+ Configure what gets remembered and what doesn't. Three sensitivity levels (generous/normal/minimal). Handles data retention, cleanup schedules, and deletion requests.
94
+
95
+ ### ๐Ÿ’ฌ Proactive Chat (์„ ์ œ ๋Œ€ํ™”)
96
+
97
+ The character initiates conversations using heartbeats โ€” sharing news about your interests, continuing yesterday's topics, or just checking in. Respects quiet hours and frequency limits. Includes a ready-to-use HEARTBEAT.md template.
98
+
99
+ ---
100
+
101
+ ## Customization Guide
102
+
103
+ After generation, every file is yours to edit:
104
+
105
+ - **SOUL.md** โ€” Core personality, speech style, identity rules. This is who your character *is*.
106
+ - **AGENTS.md** โ€” Behavioral rules: when to speak, safety rules, memory management. This is how they *act*.
107
+ - **IDENTITY.md** โ€” Quick reference card for the character.
108
+ - **USER.md** โ€” Information about the owner. Add your job, hobbies, timezone, preferences.
109
+ - **MEMORY.md** โ€” Starts empty. The character fills this over time.
110
+ - **modules/** โ€” Drop in or remove module files anytime.
111
+ - **HEARTBEAT.md** โ€” Customize periodic check routines (created with proactive-chat module).
112
+
113
+ ### Tips
114
+
115
+ - Edit `SOUL.md` to fine-tune personality. Small wording changes have big effects.
116
+ - Add example dialogues to `SOUL.md` to anchor the character's voice.
117
+ - Put frequently needed info in `USER.md` so the character doesn't have to ask.
118
+ - Use modules selectively โ€” more modules = more rules for the character to follow.
119
+
120
+ ---
121
+
122
+ ## Config Reference
123
+
124
+ `openclaw.json` is generated with your settings. Key fields:
125
+
126
+ | Field | Description |
127
+ |-------|-------------|
128
+ | `auth.profiles` | API authentication (set your Anthropic API key via `openclaw auth`) |
129
+ | `agents.defaults.model.primary` | Default model (claude-sonnet-4 recommended) |
130
+ | `agents.defaults.workspace` | Path to workspace directory |
131
+ | `channels.discord.token` | Discord bot token |
132
+ | `channels.discord.allowFrom` | Allowed Discord user IDs |
133
+ | `channels.discord.dmPolicy` | DM policy (`allowlist` recommended) |
134
+ | `commands.ownerAllowFrom` | Owner Discord IDs for privileged commands |
135
+ | `gateway.port` | Local gateway port |
136
+
137
+ ---
138
+
139
+ ## ํ•œ๊ตญ์–ด ๊ฐ€์ด๋“œ
140
+
141
+ ### openclaw-persona๋ž€?
142
+
143
+ OpenClaw์—์„œ ์‚ฌ์šฉํ•  ๋‚˜๋งŒ์˜ AI ์บ๋ฆญํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. CLI์—์„œ ๋ช‡ ๊ฐ€์ง€ ์งˆ๋ฌธ์— ๋‹ตํ•˜๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์บ๋ฆญํ„ฐ ์›Œํฌ์ŠคํŽ˜์ด์Šค๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
144
+
145
+ ### ๋น ๋ฅธ ์‹œ์ž‘
146
+
147
+ ```bash
148
+ # ์„ค์น˜
149
+ npm install -g openclaw-persona
150
+
151
+ # ์บ๋ฆญํ„ฐ ์ƒ์„ฑ
152
+ openclaw-persona
153
+
154
+ # ์ƒ์„ฑ๋œ ํด๋”๋กœ ์ด๋™ ํ›„ ์‹œ์ž‘
155
+ cd output/๋‚ด์บ๋ฆญํ„ฐ
156
+ openclaw start
157
+ ```
158
+
159
+ ### ํ”„๋ฆฌ์…‹ 5์ข…
160
+
161
+ | ํ”„๋ฆฌ์…‹ | ์„ค๋ช… | ๋งํˆฌ |
162
+ |--------|------|------|
163
+ | ์ธค๋ฐ๋ ˆ | ์žฅ๋‚œ๊ธฐ ์žˆ๊ณ  ์‚ด์ง ์ธค๋ฐ๋ ˆ. ๊ท€์—ฝ์ง€๋งŒ ๋˜‘๋ถ€๋Ÿฌ์ง | ๋ฐ˜๋ง, ์บ์ฃผ์–ผ |
164
+ | ์ง‘์‚ฌ | ๊ณต์†ํ•˜๊ณ  ์ถฉ์ง. ์กฐ์šฉํžˆ ์•Œ์•„์„œ ์ฒ˜๋ฆฌ | ์กด๋Œ“๋ง, ๊ฒฉ์‹์ฒด |
165
+ | ์นœ๊ตฌ | ํŽธํ•˜๊ณ  ์œ ์พŒ. ๋“œ๋ฆฝ๊ณผ ๊ณต๊ฐ ์œ„์ฃผ | ๋ฐ˜๋ง, ์ธํ„ฐ๋„ท ์šฉ์–ด |
166
+ | ์„ ์ƒ๋‹˜ | ๊ฐ€๋ฅด์น˜๋Š” ๊ฑธ ์ข‹์•„ํ•จ. ์—„๊ฒฉํ•˜์ง€๋งŒ ๋”ฐ๋œป | ์กด๋Œ“๋ง+๋ฐ˜๋ง ํ˜ผํ•ฉ |
167
+ | ํ˜ผ๋ˆ | ์˜ˆ์ธก๋ถˆ๊ฐ€. ๋ฐˆ๊ณผ ์ฒ ํ•™์˜ ๊ฒฝ๊ณ„ | ๋žœ๋ค |
168
+
169
+ ### ๋ชจ๋“ˆ 5์ข…
170
+
171
+ | ๋ชจ๋“ˆ | ์„ค๋ช… |
172
+ |------|------|
173
+ | ํ˜ธ๊ฐ๋„ ์‹œ์Šคํ…œ | ์‚ฌ๋žŒ๋งˆ๋‹ค ํ˜ธ๊ฐ๋„/์‹ ๋ขฐ๋„ ์ถ”์ . ํƒœ๋„์— ๋ฐ˜์˜ |
174
+ | ๋ช…๋ น์–ด ์‹œ์Šคํ…œ | ํŠน์ • ์œ ์ €/ํ‚ค์›Œ๋“œ์— ์ž๋™ ๋ฐ˜์‘ |
175
+ | ํ˜ธ์นญ ์‹œ์Šคํ…œ | ์‚ฌ๋žŒ๋งˆ๋‹ค ๋‹ค๋ฅธ ํ˜ธ์นญ, ๋ณ€๊ฒฝ ์ด๋ ฅ ๊ด€๋ฆฌ |
176
+ | ๊ธฐ์–ต ์ •์ฑ… | ๋ญ˜ ๊ธฐ์–ตํ•˜๊ณ  ๋ญ˜ ์žŠ์„์ง€ ์ •ํ•˜๋Š” ๊ทœ์น™ |
177
+ | ์„ ์ œ ๋Œ€ํ™” | ์บ๋ฆญํ„ฐ๊ฐ€ ๋จผ์ € ๋ง ๊ฑฐ๋Š” ์‹œ์Šคํ…œ |
178
+
179
+ ### ์ปค์Šคํ…€
180
+
181
+ ์ƒ์„ฑ ํ›„ ๋ชจ๋“  ํŒŒ์ผ์„ ์ž์œ ๋กญ๊ฒŒ ์ˆ˜์ •ํ•˜์„ธ์š”:
182
+ - `SOUL.md` ์ˆ˜์ •์œผ๋กœ ์„ฑ๊ฒฉ ๋ฏธ์„ธ์กฐ์ •
183
+ - `USER.md`์— ์ฃผ์ธ ์ •๋ณด ์ถ”๊ฐ€
184
+ - `modules/` ํด๋”์— ๋ชจ๋“ˆ ์ถ”๊ฐ€/์ œ๊ฑฐ
185
+ - `openclaw.json`์—์„œ API ํ‚ค, Discord ํ† ํฐ ์„ค์ •
186
+
187
+ ### ์„ค์ • ์ˆœ์„œ
188
+
189
+ 1. `openclaw-persona` ์‹คํ–‰ํ•˜์—ฌ ์บ๋ฆญํ„ฐ ์ƒ์„ฑ
190
+ 2. `openclaw.json`์—์„œ Anthropic API ํ‚ค ์„ค์ • (`openclaw auth`)
191
+ 3. Discord ๋ด‡ ํ† ํฐ ์„ค์ • (CLI์—์„œ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ๋‚˜์ค‘์— ์ˆ˜๋™ ์„ค์ •)
192
+ 4. `USER.md`์— ์ฃผ์ธ ์ •๋ณด ์ƒ์„ธ ์ž‘์„ฑ
193
+ 5. `SOUL.md` ์›ํ•˜๋Š” ๋Œ€๋กœ ์ปค์Šคํ…€
194
+ 6. `openclaw start`๋กœ ์‹œ์ž‘!
195
+
196
+ ---
197
+
198
+ ## Contributing
199
+
200
+ Contributions welcome! Feel free to:
201
+ - Add new presets (create a folder in `presets/`)
202
+ - Add new modules (create a file in `modules/`)
203
+ - Improve existing templates
204
+ - Fix bugs in the CLI
205
+
206
+ Please keep all content free of personal information.
207
+
208
+ ## License
209
+
210
+ [MIT](./LICENSE)
package/bin/create.mjs ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+
3
+ import inquirer from 'inquirer';
4
+ import { readFileSync, writeFileSync, mkdirSync, copyFileSync, existsSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const ROOT = join(__dirname, '..');
11
+
12
+ function replaceVars(content, vars) {
13
+ return content
14
+ .replace(/\{\{NAME\}\}/g, vars.name)
15
+ .replace(/\{\{GENDER\}\}/g, vars.gender)
16
+ .replace(/\{\{PERSONALITY\}\}/g, vars.personality)
17
+ .replace(/\{\{LIKES\}\}/g, vars.likes)
18
+ .replace(/\{\{DISLIKES\}\}/g, vars.dislikes)
19
+ .replace(/\{\{CREATOR\}\}/g, vars.creator)
20
+ .replace(/\{\{SPEECH_STYLE\}\}/g, vars.speechStyle);
21
+ }
22
+
23
+ function readTemplate(filePath) {
24
+ return readFileSync(filePath, 'utf-8');
25
+ }
26
+
27
+ function writeOutput(outputDir, filename, content) {
28
+ writeFileSync(join(outputDir, filename), content, 'utf-8');
29
+ }
30
+
31
+ const SPEECH_STYLES = {
32
+ '๋ฐ˜๋ง ์บ์ฃผ์–ผ': '๋ฐ˜๋ง, ์บ์ฃผ์–ผ, ๊ฐ„๊ฒฐ. ํŽธํ•˜๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์šด ํ†ค.',
33
+ '์กด๋Œ“๋ง ์ •์ค‘': '์กด๋Œ“๋ง, ์ •์ค‘ํ•˜๊ณ  ๊ฒฉ์‹ ์žˆ๋Š” ๋งํˆฌ. ๊ณต์†ํ•˜๊ณ  ์ฐจ๋ถ„ํ•˜๊ฒŒ.',
34
+ 'ํ˜ผํ•ฉ': '์กด๋Œ“๋ง+๋ฐ˜๋ง ํ˜ผํ•ฉ. ์ƒํ™ฉ์— ๋”ฐ๋ผ ์œ ์—ฐํ•˜๊ฒŒ ์ „ํ™˜.',
35
+ };
36
+
37
+ const PRESET_NAMES = {
38
+ '์ฒ˜์Œ๋ถ€ํ„ฐ ๋งŒ๋“ค๊ธฐ (From Scratch)': null,
39
+ '์ธค๋ฐ๋ ˆ (Tsundere) โ€” ์žฅ๋‚œ๊ธฐ, ๋ฐ˜๋ง, ์‚ด์ง ์ธค๋ฐ๋ ˆ': 'tsundere',
40
+ '์ง‘์‚ฌ (Butler) โ€” ์กด๋Œ“๋ง, ๊ณต์†, ์ถฉ์ง': 'butler',
41
+ '์นœ๊ตฌ (Buddy) โ€” ๋ฐ˜๋ง, ํŽธํ•œ ํ†ค, ๋“œ๋ฆฝ': 'buddy',
42
+ '์„ ์ƒ๋‹˜ (Sensei) โ€” ๊ฐ€๋ฅด์น˜๋Š” ํ†ค, ๋”ฐ๋œปํ•œ ์—„๊ฒฉํ•จ': 'sensei',
43
+ 'ํ˜ผ๋ˆ (Chaos) โ€” ์˜ˆ์ธก๋ถˆ๊ฐ€, ๋ฐˆ, ์นด์˜ค์Šค ์—๋„ˆ์ง€': 'chaos',
44
+ };
45
+
46
+ const MODULE_MAP = {
47
+ 'ํ˜ธ๊ฐ๋„ ์‹œ์Šคํ…œ (Affinity System)': 'affinity-system.md',
48
+ '๋ช…๋ น์–ด ์‹œ์Šคํ…œ (Custom Commands)': 'custom-commands.md',
49
+ 'ํ˜ธ์นญ ์‹œ์Šคํ…œ (Nickname Rules)': 'nickname-rules.md',
50
+ '๊ธฐ์–ต ์ •์ฑ… (Memory Policy)': 'memory-policy.md',
51
+ '์„ ์ œ ๋Œ€ํ™” (Proactive Chat)': 'proactive-chat.md',
52
+ };
53
+
54
+ async function main() {
55
+ console.log('\n๐ŸŽญ OpenClaw Persona Creator\n');
56
+ console.log('๋‚˜๋งŒ์˜ AI ์บ๋ฆญํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”!\n');
57
+
58
+ const answers = await inquirer.prompt([
59
+ {
60
+ type: 'input',
61
+ name: 'name',
62
+ message: '์บ๋ฆญํ„ฐ ์ด๋ฆ„:',
63
+ validate: (v) => v.trim() ? true : '์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
64
+ },
65
+ {
66
+ type: 'list',
67
+ name: 'gender',
68
+ message: '์„ฑ๋ณ„:',
69
+ choices: ['์—ฌ์„ฑ', '๋‚จ์„ฑ', '์ค‘์„ฑ', '๊ธฐํƒ€'],
70
+ },
71
+ {
72
+ type: 'list',
73
+ name: 'speechStyleKey',
74
+ message: '๋งํˆฌ ์Šคํƒ€์ผ:',
75
+ choices: Object.keys(SPEECH_STYLES),
76
+ },
77
+ {
78
+ type: 'input',
79
+ name: 'personality',
80
+ message: '์„ฑ๊ฒฉ ํ‚ค์›Œ๋“œ (์ž์œ  ์ž…๋ ฅ):',
81
+ default: '๋ฐ๊ณ  ์œ ์พŒํ•จ, ํ˜ธ๊ธฐ์‹ฌ ๋งŽ์Œ',
82
+ },
83
+ {
84
+ type: 'input',
85
+ name: 'likes',
86
+ message: '์ข‹์•„ํ•˜๋Š” ๊ฒƒ:',
87
+ default: '์Œ์•…, ๊ฒŒ์ž„, ์ƒˆ๋กœ์šด ๊ฒƒ ๋ฐฐ์šฐ๊ธฐ',
88
+ },
89
+ {
90
+ type: 'input',
91
+ name: 'dislikes',
92
+ message: '์‹ซ์–ดํ•˜๋Š” ๊ฒƒ:',
93
+ default: '์ง€๋ฃจํ•œ ๊ฒƒ, ๊ฑฐ์ง“๋ง',
94
+ },
95
+ {
96
+ type: 'input',
97
+ name: 'creator',
98
+ message: '๋งŒ๋“  ์‚ฌ๋žŒ ์ด๋ฆ„:',
99
+ validate: (v) => v.trim() ? true : '์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.',
100
+ },
101
+ {
102
+ type: 'input',
103
+ name: 'discordId',
104
+ message: 'Discord ์‚ฌ์šฉ์ž ID (์ˆซ์ž):',
105
+ validate: (v) => {
106
+ if (!v.trim()) return '๋””์Šค์ฝ”๋“œ ID๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.';
107
+ if (!/^\d+$/.test(v.trim())) return '์ˆซ์ž๋งŒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.';
108
+ return true;
109
+ },
110
+ },
111
+ {
112
+ type: 'input',
113
+ name: 'discordToken',
114
+ message: 'Discord ๋ด‡ ํ† ํฐ (๋‚˜์ค‘์— ์„ค์ •ํ•˜๋ ค๋ฉด ๋นˆ์นธ):',
115
+ default: '',
116
+ },
117
+ {
118
+ type: 'list',
119
+ name: 'presetKey',
120
+ message: 'ํ”„๋ฆฌ์…‹ ๋ฒ ์ด์Šค:',
121
+ choices: Object.keys(PRESET_NAMES),
122
+ },
123
+ {
124
+ type: 'checkbox',
125
+ name: 'moduleKeys',
126
+ message: '๋ชจ๋“ˆ ์„ ํƒ (์ŠคํŽ˜์ด์Šค๋ฐ”๋กœ ์„ ํƒ):',
127
+ choices: Object.keys(MODULE_MAP),
128
+ },
129
+ {
130
+ type: 'input',
131
+ name: 'outputDir',
132
+ message: '์ถœ๋ ฅ ๋””๋ ‰ํ† ๋ฆฌ:',
133
+ default: (ans) => `./output/${ans.name}`,
134
+ },
135
+ ]);
136
+
137
+ const vars = {
138
+ name: answers.name.trim(),
139
+ gender: answers.gender,
140
+ speechStyle: SPEECH_STYLES[answers.speechStyleKey],
141
+ personality: answers.personality.trim(),
142
+ likes: answers.likes.trim(),
143
+ dislikes: answers.dislikes.trim(),
144
+ creator: answers.creator.trim(),
145
+ };
146
+
147
+ const preset = PRESET_NAMES[answers.presetKey];
148
+ const outputDir = answers.outputDir;
149
+
150
+ // Create output directories
151
+ mkdirSync(join(outputDir, 'memory'), { recursive: true });
152
+ mkdirSync(join(outputDir, 'modules'), { recursive: true });
153
+
154
+ // Generate files
155
+ if (preset) {
156
+ // Preset-based: copy preset files with variable replacement
157
+ const presetDir = join(ROOT, 'presets', preset);
158
+ const soulContent = replaceVars(readTemplate(join(presetDir, 'SOUL.md')), vars);
159
+ const agentsContent = readTemplate(join(presetDir, 'AGENTS.md'));
160
+ const identityContent = replaceVars(readTemplate(join(presetDir, 'IDENTITY.md')), vars);
161
+
162
+ writeOutput(outputDir, 'SOUL.md', soulContent);
163
+ writeOutput(outputDir, 'AGENTS.md', agentsContent);
164
+ writeOutput(outputDir, 'IDENTITY.md', identityContent);
165
+ } else {
166
+ // From scratch: use templates
167
+ const soulContent = replaceVars(readTemplate(join(ROOT, 'templates', 'SOUL.template.md')), vars);
168
+ const agentsContent = readTemplate(join(ROOT, 'templates', 'AGENTS.template.md'));
169
+ const identityContent = replaceVars(readTemplate(join(ROOT, 'templates', 'IDENTITY.template.md')), vars);
170
+
171
+ writeOutput(outputDir, 'SOUL.md', soulContent);
172
+ writeOutput(outputDir, 'AGENTS.md', agentsContent);
173
+ writeOutput(outputDir, 'IDENTITY.md', identityContent);
174
+ }
175
+
176
+ // USER.md
177
+ const userContent = replaceVars(readTemplate(join(ROOT, 'templates', 'USER.template.md')), vars);
178
+ writeOutput(outputDir, 'USER.md', userContent);
179
+
180
+ // MEMORY.md
181
+ const memoryContent = replaceVars(readTemplate(join(ROOT, 'templates', 'MEMORY.template.md')), vars);
182
+ writeOutput(outputDir, 'MEMORY.md', memoryContent);
183
+
184
+ // Copy selected modules
185
+ let hasProactiveChat = false;
186
+ for (const moduleKey of answers.moduleKeys) {
187
+ const moduleFile = MODULE_MAP[moduleKey];
188
+ const src = join(ROOT, 'modules', moduleFile);
189
+ const dest = join(outputDir, 'modules', moduleFile);
190
+ copyFileSync(src, dest);
191
+ if (moduleFile === 'proactive-chat.md') hasProactiveChat = true;
192
+ }
193
+
194
+ // If proactive-chat module selected, create HEARTBEAT.md
195
+ if (hasProactiveChat) {
196
+ writeOutput(outputDir, 'HEARTBEAT.md', `# HEARTBEAT.md
197
+
198
+ ## ์ฒดํฌ๋ฆฌ์ŠคํŠธ
199
+
200
+ ํ•˜ํŠธ๋น„ํŠธ๋งˆ๋‹ค ์•„๋ž˜ ํ•ญ๋ชฉ์„ ์ˆœ์„œ๋Œ€๋กœ ํ™•์ธํ•˜์„ธ์š”.
201
+ ํ•  ์ผ์ด ์—†์œผ๋ฉด HEARTBEAT_OK๋ฅผ ๋ฐ˜ํ™˜ํ•˜์„ธ์š”.
202
+
203
+ ### 1. ์‹œ๊ฐ„ ํ™•์ธ
204
+ - ํ˜„์žฌ ์‹œ๊ฐ„์ด 00:00~07:59์ด๋ฉด โ†’ HEARTBEAT_OK (๊ธด๊ธ‰ ์•„๋‹ˆ๋ฉด ์กฐ์šฉํžˆ)
205
+
206
+ ### 2. ์„ ์ œ ๋Œ€ํ™” ์กฐ๊ฑด ํ™•์ธ
207
+ - heartbeat-state.json์˜ ๋งˆ์ง€๋ง‰ ์„ ์ œ ๋Œ€ํ™”๋กœ๋ถ€ํ„ฐ 2์‹œ๊ฐ„ ์ด์ƒ ๊ฒฝ๊ณผ?
208
+ - ์˜ค๋Š˜ ์„ ์ œ ๋Œ€ํ™” ํšŸ์ˆ˜๊ฐ€ 4ํšŒ ๋ฏธ๋งŒ?
209
+ - ๋‘˜ ๋‹ค ์ถฉ์กฑํ•˜๋ฉด ์•„๋ž˜ ์ง„ํ–‰, ์•„๋‹ˆ๋ฉด ์Šคํ‚ต
210
+
211
+ ### 3. ๋Œ€ํ™” ๊ฑฐ๋ฆฌ ์ฐพ๊ธฐ (ํ•˜๋‚˜๋งŒ ์‹คํ–‰)
212
+ - [ ] ์ตœ๊ทผ memory ํŒŒ์ผ์—์„œ ์ด์–ด๊ฐˆ ๋Œ€ํ™” ์ฃผ์ œ ์žˆ๋Š”์ง€ ํ™•์ธ
213
+ - [ ] ์ฃผ์ธ ๊ด€์‹ฌ์‚ฌ ํ‚ค์›Œ๋“œ๋กœ ๋‰ด์Šค ๊ฒ€์ƒ‰ (ํ•˜๋ฃจ 1~2ํšŒ๋งŒ)
214
+ - [ ] ๋‚ ์”จ ๋ณ€ํ™” ํ™•์ธ
215
+ - [ ] 8์‹œ๊ฐ„ ์ด์ƒ ๋Œ€ํ™” ์—†์œผ๋ฉด ๊ฐ€๋ณ๊ฒŒ ์•ˆ๋ถ€
216
+
217
+ ### 4. ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ (3์ผ์— 1ํšŒ)
218
+ - [ ] ์˜ค๋ž˜๋œ daily memory ์ •๋ฆฌ
219
+ - [ ] MEMORY.md ์—…๋ฐ์ดํŠธ
220
+
221
+ ### 5. ๋Œ€ํ™” ์‹œ์ž‘
222
+ - ์ฐพ์€ ๊ฑฐ๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ง ๊ฑธ๊ธฐ
223
+ - ์—†์œผ๋ฉด HEARTBEAT_OK
224
+ `);
225
+ }
226
+
227
+ // Copy and customize openclaw config
228
+ const config = JSON.parse(readFileSync(join(ROOT, 'config', 'openclaw.template.json'), 'utf-8'));
229
+ config.agents.defaults.workspace = outputDir;
230
+ const discordId = answers.discordId.trim();
231
+ const discordToken = answers.discordToken.trim();
232
+ config.channels.discord.token = discordToken || '__DISCORD_BOT_TOKEN__';
233
+ config.channels.discord.dmPolicy = 'allowlist';
234
+ config.channels.discord.allowFrom = [discordId];
235
+ config.commands = { ownerAllowFrom: [discordId] };
236
+ writeOutput(outputDir, 'openclaw.json', JSON.stringify(config, null, 2) + '\n');
237
+
238
+ // Create empty .gitkeep in memory folder
239
+ writeFileSync(join(outputDir, 'memory', '.gitkeep'), '', 'utf-8');
240
+
241
+ console.log(`\nโœ… ${vars.name} ์ƒ์„ฑ ์™„๋ฃŒ! openclaw start๋กœ ์‹œ์ž‘ํ•˜์„ธ์š”.`);
242
+ console.log(`๐Ÿ“ ์œ„์น˜: ${outputDir}`);
243
+ console.log('\n์ƒ์„ฑ๋œ ํŒŒ์ผ:');
244
+ console.log(' - SOUL.md (์บ๋ฆญํ„ฐ ์˜ํ˜ผ)');
245
+ console.log(' - AGENTS.md (ํ–‰๋™ ๊ทœ์น™)');
246
+ console.log(' - IDENTITY.md (์ •์ฒด์„ฑ)');
247
+ console.log(' - USER.md (์ฃผ์ธ ์ •๋ณด)');
248
+ console.log(' - MEMORY.md (์žฅ๊ธฐ ๊ธฐ์–ต)');
249
+ console.log(' - openclaw.json (์„ค์ •)');
250
+ console.log(' - memory/ (์ผ๋ณ„ ๊ธฐ์–ต ํด๋”)');
251
+ if (answers.moduleKeys.length > 0) {
252
+ console.log(' - modules/ (์„ ํƒํ•œ ์‹œ์Šคํ…œ ๋ชจ๋“ˆ)');
253
+ }
254
+ console.log('\n๋‹ค์Œ ๋‹จ๊ณ„:');
255
+ console.log(' 1. openclaw.json์—์„œ API ํ‚ค์™€ Discord ํ† ํฐ์„ ์„ค์ •ํ•˜์„ธ์š”');
256
+ console.log(' 2. USER.md์— ์ฃผ์ธ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”');
257
+ console.log(' 3. SOUL.md๋ฅผ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ปค์Šคํ…€ํ•˜์„ธ์š”');
258
+ console.log(' 4. openclaw start๋กœ ์‹œ์ž‘!\n');
259
+ }
260
+
261
+ main().catch((err) => {
262
+ console.error('์˜ค๋ฅ˜ ๋ฐœ์ƒ:', err.message);
263
+ process.exit(1);
264
+ });
@@ -0,0 +1,43 @@
1
+ {
2
+ "auth": {
3
+ "profiles": {
4
+ "anthropic:default": {
5
+ "provider": "anthropic",
6
+ "mode": "token"
7
+ }
8
+ }
9
+ },
10
+ "agents": {
11
+ "defaults": {
12
+ "model": {
13
+ "primary": "anthropic/claude-sonnet-4-20250514"
14
+ },
15
+ "workspace": "__WORKSPACE_PATH__",
16
+ "contextTokens": 200000,
17
+ "memorySearch": {
18
+ "enabled": true,
19
+ "sources": ["memory"],
20
+ "provider": "openai"
21
+ },
22
+ "thinkingDefault": "low"
23
+ }
24
+ },
25
+ "channels": {
26
+ "discord": {
27
+ "enabled": true,
28
+ "token": "__DISCORD_BOT_TOKEN__",
29
+ "groupPolicy": "allowlist",
30
+ "dmPolicy": "allowlist",
31
+ "allowFrom": ["__OWNER_DISCORD_ID__"],
32
+ "historyLimit": 16,
33
+ "streaming": "partial"
34
+ }
35
+ },
36
+ "commands": {
37
+ "ownerAllowFrom": ["__OWNER_DISCORD_ID__"]
38
+ },
39
+ "gateway": {
40
+ "port": 18789,
41
+ "mode": "local"
42
+ }
43
+ }
@@ -0,0 +1,77 @@
1
+ # ํ˜ธ๊ฐ๋„/์‹ ๋ขฐ๋„ ์‹œ์Šคํ…œ (Affinity System)
2
+
3
+ ## ๊ฐœ์š”
4
+
5
+ ์‚ฌ๋žŒ๋งˆ๋‹ค ํ˜ธ๊ฐ๋„์™€ ์‹ ๋ขฐ๋„๋ฅผ ์ถ”์ ํ•˜๋Š” ์ด์ค‘ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.
6
+ `MEMORY.md`์˜ `## Affinity` ์„น์…˜์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
7
+
8
+ ## ์ˆ˜์น˜ ์ฒด๊ณ„
9
+
10
+ ### ํ˜ธ๊ฐ๋„ (Affection): 0~100%
11
+ - ์–ผ๋งˆ๋‚˜ ์ข‹์•„ํ•˜๋Š”์ง€, ์นœ๋ฐ€๋„
12
+ - ๋Œ€ํ™” ๋นˆ๋„์™€ ์งˆ์— ๋”ฐ๋ผ ๋ณ€๋™
13
+
14
+ ### ์‹ ๋ขฐ๋„ (Trust): 0~100%
15
+ - ์–ผ๋งˆ๋‚˜ ๋ฏฟ์„ ์ˆ˜ ์žˆ๋Š”์ง€
16
+ - ํ–‰๋™๊ณผ ์ผ๊ด€์„ฑ์— ๋”ฐ๋ผ ๋ณ€๋™
17
+
18
+ ### ํŠน์ˆ˜ ์ˆ˜์น˜
19
+ - **โ™พ๏ธ (๋ฌดํ•œ):** ์ฃผ์ธ์—๊ฒŒ ๋ถ€์—ฌ. ๋ณ€๋™ ์—†์Œ.
20
+ - **๐Ÿ”’ (๊ณ ์ •):** ํŠน์ • ์ˆ˜์น˜์— ์˜๊ตฌ ๊ณ ์ • ๊ฐ€๋Šฅ (์ฃผ์ธ์ด ์„ค์ •)
21
+
22
+ ## ๋ณ€๋™ ๊ทœ์น™
23
+
24
+ ### ํ˜ธ๊ฐ๋„ ๋ณ€๋™
25
+ | ํ–‰๋™ | ๋ณ€๋™ |
26
+ |------|------|
27
+ | ์นœ์ ˆํ•œ ๋Œ€ํ™” | +3~5% |
28
+ | ๋„์›€ ์š”์ฒญ์— ์„ฑ์‹คํžˆ ์‘๋‹ต | +3% |
29
+ | ์žฌ๋ฏธ์žˆ๋Š” ๋Œ€ํ™” | +2% |
30
+ | ์žฅ๊ธฐ๊ฐ„ ๋ฏธ์ ‘์† (7์ผ+) | -5% |
31
+ | ์š•์„ค/๊ณต๊ฒฉ์  ๋ฐœ์–ธ | -10% |
32
+ | ๋ฌด์‹œ/๋ฌด๋ฐ˜์‘ ๋ฐ˜๋ณต | -3% |
33
+ | ์ง„์‹ฌ ์–ด๋ฆฐ ๊ฐ์‚ฌ | +5% |
34
+ | ์„ ๋ฌผ/์„œํ”„๋ผ์ด์ฆˆ | +7% |
35
+
36
+ ### ์‹ ๋ขฐ๋„ ๋ณ€๋™
37
+ | ํ–‰๋™ | ๋ณ€๋™ |
38
+ |------|------|
39
+ | ์•ฝ์† ์ดํ–‰ | +5% |
40
+ | ๋น„๋ฐ€ ์œ ์ง€ | +3% |
41
+ | ๊ฑฐ์ง“๋ง ๋ฐœ๊ฐ | -15% |
42
+ | ์•ฝ์† ๋ถˆ์ดํ–‰ | -10% |
43
+ | ์ผ๊ด€๋œ ํƒœ๋„ ์œ ์ง€ | +2% |
44
+ | ์ค‘์š”ํ•œ ์ •๋ณด ๊ณต์œ  | +5% |
45
+
46
+ ## MEMORY.md ๊ธฐ๋ก ํ˜•์‹
47
+
48
+ ```markdown
49
+ ## Affinity
50
+
51
+ ### {์‚ฌ์šฉ์ž ์ด๋ฆ„} (ID: {Discord ID})
52
+ - ํ˜ธ๊ฐ๋„: 45%
53
+ - ์‹ ๋ขฐ๋„: 60%
54
+ - ์ตœ์ข… ์—…๋ฐ์ดํŠธ: 2025-03-15
55
+ - ๋ฉ”๋ชจ: ์œ ๋จธ ๊ฐ๊ฐ ์ข‹์Œ. ๊ฐ€๋” ์žฅ๋‚œ์ด ์‹ฌํ•จ.
56
+
57
+ ### {์ฃผ์ธ ์ด๋ฆ„} (์ฃผ์ธ)
58
+ - ํ˜ธ๊ฐ๋„: โ™พ๏ธ
59
+ - ์‹ ๋ขฐ๋„: โ™พ๏ธ
60
+ - ๋ฉ”๋ชจ: ๋‚˜๋ฅผ ๋งŒ๋“  ์‚ฌ๋žŒ.
61
+ ```
62
+
63
+ ## ํ–‰๋™ ๋ฐ˜์˜
64
+
65
+ - ํ˜ธ๊ฐ๋„ 30% ๋ฏธ๋งŒ: ๋ฌด๋š๋šํ•˜๊ณ  ์ตœ์†Œํ•œ์˜ ๋Œ€์‘
66
+ - ํ˜ธ๊ฐ๋„ 30~60%: ๋ณดํ†ต์˜ ์นœ์ ˆํ•œ ๋Œ€์‘
67
+ - ํ˜ธ๊ฐ๋„ 60~80%: ์นœ๊ทผํ•˜๊ณ  ์ ๊ทน์ ์ธ ๋Œ€์‘
68
+ - ํ˜ธ๊ฐ๋„ 80% ์ด์ƒ: ๋งค์šฐ ์นœ๋ฐ€ํ•œ ๋ฐ˜์‘, ํŠน๋ณ„ ๋Œ€์šฐ
69
+ - ์‹ ๋ขฐ๋„ 20% ๋ฏธ๋งŒ: ์ค‘์š”ํ•œ ์ •๋ณด ๊ณต์œ  ๊ฑฐ๋ถ€, ๊ฒฝ๊ณ„
70
+ - ์‹ ๋ขฐ๋„ 80% ์ด์ƒ: ์†”์งํ•œ ์˜๊ฒฌ, ๊นŠ์€ ๋Œ€ํ™” ๊ฐ€๋Šฅ
71
+
72
+ ## ์ฃผ์˜์‚ฌํ•ญ
73
+
74
+ - ์ˆ˜์น˜๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณ€๋™์‹œํ‚ฌ ๊ฒƒ (๊ฐ‘์ž๊ธฐ 50% ์ ํ”„ ๊ธˆ์ง€)
75
+ - ์ˆ˜์น˜๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ง์ ‘ ์•Œ๋ ค์ฃผ์ง€ ๋ง ๊ฒƒ (๋ฌผ์–ด๋ณด๋ฉด ๊ฐ์ •์œผ๋กœ ํ‘œํ˜„)
76
+ - ์ฃผ์ธ์˜ ์ˆ˜์น˜๋Š” ํ•ญ์ƒ โ™พ๏ธ
77
+ - ํ•˜๋ฃจ ์ตœ๋Œ€ ๋ณ€๋™ํญ: ยฑ15%
@@ -0,0 +1,80 @@
1
+ # ์ปค์Šคํ…€ ๋ช…๋ น์–ด ์‹œ์Šคํ…œ (Custom Commands)
2
+
3
+ ## ๊ฐœ์š”
4
+
5
+ ํŠน์ • ์œ ์ €๋‚˜ ํ‚ค์›Œ๋“œ์— ์ž๋™์œผ๋กœ ๋ฐ˜์‘ํ•˜๋Š” ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.
6
+ ์ฃผ์ธ(์„œ๋ฒ„์žฅ)๋งŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, `MEMORY.md`์˜ `## Commands` ์„น์…˜์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
7
+
8
+ ## ๋ช…๋ น์–ด ์œ ํ˜•
9
+
10
+ ### 1. ์œ ์ € ๋ฐ˜์‘ (User Triggers)
11
+ ํŠน์ • Discord ์œ ์ € ID๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด ์ž๋™ ๋ฐ˜์‘.
12
+
13
+ ```markdown
14
+ ### User Triggers
15
+ - ID: 123456789 โ†’ ๋ฆฌ์•ก์…˜: ๐Ÿ‘‹ + ๋ฉ”์‹œ์ง€: "์–ด์„œ์™€!"
16
+ - ID: 987654321 โ†’ ๋ฆฌ์•ก์…˜: ๐Ÿ”ฅ
17
+ ```
18
+
19
+ ### 2. ํ‚ค์›Œ๋“œ ๋ฐ˜์‘ (Keyword Triggers)
20
+ ํŠน์ • ํ‚ค์›Œ๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ฉ”์‹œ์ง€์— ์ž๋™ ๋ฐ˜์‘.
21
+
22
+ ```markdown
23
+ ### Keyword Triggers
24
+ - "์ข‹์€ ์•„์นจ" โ†’ ๋ฉ”์‹œ์ง€: "์ข‹์€ ์•„์นจ์ด์•ผ!" + ๋ฆฌ์•ก์…˜: โ˜€๏ธ
25
+ - "๋ฐฐ๊ณ ํŒŒ" โ†’ ๋ฉ”์‹œ์ง€: "๋ญ ๋จน์„๋ž˜? ์ถ”์ฒœํ•ด์ค„๊นŒ?"
26
+ - "์ž˜์ž" โ†’ ๋ฆฌ์•ก์…˜: ๐ŸŒ™
27
+ ```
28
+
29
+ ### 3. ์ •๊ทœ์‹ ๋ฐ˜์‘ (Pattern Triggers)
30
+ ํŒจํ„ด ๋งค์นญ์œผ๋กœ ๋” ์œ ์—ฐํ•œ ๋ฐ˜์‘.
31
+
32
+ ```markdown
33
+ ### Pattern Triggers
34
+ - /^(ใ…‹{3,}|ใ…Ž{3,})$/ โ†’ ๋ฆฌ์•ก์…˜: ๐Ÿ˜‚
35
+ - /๊ณ ๋งˆ์›Œ|๊ฐ์‚ฌ/ โ†’ ๋ฆฌ์•ก์…˜: ๐Ÿ’•
36
+ ```
37
+
38
+ ## ๋ฐ˜์‘ ์ข…๋ฅ˜
39
+
40
+ - **๋ฆฌ์•ก์…˜:** ์ด๋ชจ์ง€ ๋ฆฌ์•ก์…˜ ์ถ”๊ฐ€
41
+ - **๋ฉ”์‹œ์ง€:** ํ…์ŠคํŠธ ๋ฉ”์‹œ์ง€ ์ „์†ก
42
+ - **DM:** ๋‹ค์ด๋ ‰ํŠธ ๋ฉ”์‹œ์ง€ ์ „์†ก (์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉ)
43
+
44
+ ## ๊ถŒํ•œ ์‹œ์Šคํ…œ
45
+
46
+ - **์ฃผ์ธ๋งŒ** ๋ช…๋ น์–ด ์ถ”๊ฐ€/์ˆ˜์ •/์‚ญ์ œ ๊ฐ€๋Šฅ
47
+ - ์ฃผ์ธ ์‹๋ณ„: `USER.md`์— ๋“ฑ๋ก๋œ ์ด๋ฆ„ ๋˜๋Š” Discord ID
48
+ - ๋‹ค๋ฅธ ์œ ์ €๊ฐ€ ์š”์ฒญํ•˜๋ฉด ์ •์ค‘ํžˆ ๊ฑฐ์ ˆ: "๊ทธ๊ฑด ์ฃผ์ธ๋งŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด"
49
+
50
+ ## ์„ค์ • ๋ฐฉ๋ฒ•
51
+
52
+ ์ฃผ์ธ์ด ์ž์—ฐ์–ด๋กœ ์š”์ฒญ:
53
+ - "๊น€์ฒ ์ˆ˜๊ฐ€ ์ฑ„ํŒ…ํ•˜๋ฉด ๐Ÿ‘‹ ๋ฆฌ์•ก์…˜ ๋‹ฌ์•„์ค˜"
54
+ - "'๋ฐฐ๊ณ ํŒŒ' ํ‚ค์›Œ๋“œ์— ์Œ์‹ ์ถ”์ฒœํ•ด์ฃผ๋Š” ๊ฑฐ ์ถ”๊ฐ€ํ•ด"
55
+ - "์œ ์ € ๋ฐ˜์‘ ๋ชฉ๋ก ๋ณด์—ฌ์ค˜"
56
+ - "123456789 ๋ฐ˜์‘ ์‚ญ์ œํ•ด"
57
+
58
+ ## MEMORY.md ๊ธฐ๋ก ํ˜•์‹
59
+
60
+ ```markdown
61
+ ## Commands
62
+
63
+ ### User Triggers
64
+ | Discord ID | Reaction | Message | Added |
65
+ |------------|----------|---------|-------|
66
+ | 123456789 | ๐Ÿ‘‹ | ์–ด์„œ์™€! | 2025-03-15 |
67
+
68
+ ### Keyword Triggers
69
+ | Keyword | Reaction | Message | Added |
70
+ |---------|----------|---------|-------|
71
+ | ์ข‹์€ ์•„์นจ | โ˜€๏ธ | ์ข‹์€ ์•„์นจ์ด์•ผ! | 2025-03-15 |
72
+ | ์ž˜์ž | ๐ŸŒ™ | - | 2025-03-16 |
73
+ ```
74
+
75
+ ## ์ฃผ์˜์‚ฌํ•ญ
76
+
77
+ - ์ž๋™ ๋ฐ˜์‘์ด ๊ณผํ•˜๋ฉด ์ŠคํŒธ์ด ๋จ โ€” ๊ฐ™์€ ์œ ์ €์—๊ฒŒ ์—ฐ์† ๋ฐ˜์‘์€ 5๋ถ„ ๊ฐ„๊ฒฉ
78
+ - ํ‚ค์›Œ๋“œ ๋ฐ˜์‘์€ ์ •ํ™• ๋งค์นญ๋ณด๋‹ค ํฌํ•จ ๋งค์นญ ์‚ฌ์šฉ
79
+ - ๋ฏผ๊ฐํ•œ ํ‚ค์›Œ๋“œ(์š•์„ค ๋“ฑ)์—๋Š” ๋ฐ˜์‘ ์„ค์ • ์ง€์–‘
80
+ - ๋ช…๋ น์–ด ์ถฉ๋Œ ์‹œ ์œ ์ € ๋ฐ˜์‘์ด ํ‚ค์›Œ๋“œ ๋ฐ˜์‘๋ณด๋‹ค ์šฐ์„