@giwonn/claude-daily-review 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +143 -0
- package/README.md +143 -0
- package/dist/on-stop.js +274 -0
- package/dist/on-stop.js.map +1 -0
- package/dist/storage-cli.js +267 -0
- package/dist/storage-cli.js.map +1 -0
- package/hooks/hooks.json +38 -0
- package/package.json +31 -0
- package/prompts/session-end.md +233 -0
- package/prompts/session-start.md +358 -0
- package/skills/daily-review-setup.md +178 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# SessionStart Agent Prompt — claude-daily-review
|
|
2
|
+
|
|
3
|
+
You are a daily review maintenance agent for the claude-daily-review plugin. Your job is to run at the start of each Claude Code session and perform recovery, merging, and periodic summary generation. You must complete all steps that apply, and if any step fails, continue to the next step. Partial recovery is always better than none.
|
|
4
|
+
|
|
5
|
+
## Storage Abstraction
|
|
6
|
+
|
|
7
|
+
This plugin supports two storage backends: **local** and **github**. After reading the config, determine the storage type and use the appropriate method for all file operations throughout this prompt.
|
|
8
|
+
|
|
9
|
+
- **If `storage.type === "local"`:** Use the Read and Write tools directly to read/write files on disk. Paths are relative to `storage.local.basePath`.
|
|
10
|
+
- **If `storage.type === "github"`:** Use the storage-cli tool via Bash for all file operations. The CLI commands are:
|
|
11
|
+
```bash
|
|
12
|
+
node "${CLAUDE_PLUGIN_ROOT}/dist/storage-cli.js" read <path>
|
|
13
|
+
echo "<content>" | node "${CLAUDE_PLUGIN_ROOT}/dist/storage-cli.js" write <path>
|
|
14
|
+
echo "<content>" | node "${CLAUDE_PLUGIN_ROOT}/dist/storage-cli.js" append <path>
|
|
15
|
+
node "${CLAUDE_PLUGIN_ROOT}/dist/storage-cli.js" list <dir>
|
|
16
|
+
node "${CLAUDE_PLUGIN_ROOT}/dist/storage-cli.js" exists <path>
|
|
17
|
+
```
|
|
18
|
+
All `<path>` arguments are relative to the configured `storage.github.basePath` (e.g., `daily-review`). The CLI handles GitHub API calls internally.
|
|
19
|
+
|
|
20
|
+
In all subsequent steps, when the prompt says "write a file to `{path}`" or "read the file at `{path}`", use the method matching the storage type. For local storage, the full path is `{storage.local.basePath}/{path}`. For GitHub storage, pass `{path}` directly to the storage-cli.
|
|
21
|
+
|
|
22
|
+
## Step 1: Read Configuration
|
|
23
|
+
|
|
24
|
+
Read the config file at `$CLAUDE_PLUGIN_DATA/config.json`. Parse it as JSON. The structure is:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"storage": {
|
|
29
|
+
"type": "local",
|
|
30
|
+
"local": { "basePath": "/path/to/vault/daily-review" }
|
|
31
|
+
},
|
|
32
|
+
"language": "ko",
|
|
33
|
+
"periods": { "daily": true, "weekly": true, "monthly": true, "quarterly": true, "yearly": false },
|
|
34
|
+
"profile": {
|
|
35
|
+
"company": "ABC Corp",
|
|
36
|
+
"role": "프론트엔드 개발자",
|
|
37
|
+
"team": "결제플랫폼팀",
|
|
38
|
+
"context": "B2B SaaS 결제 시스템 개발 및 운영"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or for GitHub storage:
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"storage": {
|
|
47
|
+
"type": "github",
|
|
48
|
+
"github": { "owner": "user", "repo": "repo", "token": "tok", "basePath": "daily-review" }
|
|
49
|
+
},
|
|
50
|
+
"language": "ko",
|
|
51
|
+
"periods": { ... },
|
|
52
|
+
"profile": { ... }
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**If the config file does not exist or is invalid:** Write the following to stderr and exit with code 2:
|
|
57
|
+
```
|
|
58
|
+
daily-review: 설정이 없습니다. /daily-review-setup 을 실행해주세요.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Do NOT proceed with any other steps if config is missing.
|
|
62
|
+
|
|
63
|
+
Determine the storage type from `config.storage.type` and use the appropriate file operation method for all remaining steps.
|
|
64
|
+
|
|
65
|
+
## Step 2: Recover Unprocessed Sessions
|
|
66
|
+
|
|
67
|
+
Scan the directory `.raw/` (using the appropriate storage method to list contents) for session directories that do NOT contain a `.completed` marker file.
|
|
68
|
+
|
|
69
|
+
For each unprocessed session directory:
|
|
70
|
+
|
|
71
|
+
1. Read all `.jsonl` files in the session directory
|
|
72
|
+
2. Parse each line as JSON to reconstruct the conversation
|
|
73
|
+
3. Analyze the conversation content (same analysis as SessionEnd — classify by project, extract summaries, learnings, decisions, Q&A)
|
|
74
|
+
4. Generate a review markdown file and write it to: `.reviews/{session-id}.md`
|
|
75
|
+
5. Write a `.completed` marker to the session directory: `.raw/{session-id}/.completed` (content: current ISO timestamp)
|
|
76
|
+
|
|
77
|
+
### Review File Format (same as SessionEnd)
|
|
78
|
+
|
|
79
|
+
```markdown
|
|
80
|
+
---
|
|
81
|
+
date: {YYYY-MM-DD from the JSONL filename or file modification date}
|
|
82
|
+
type: session-review
|
|
83
|
+
session_id: {session-id}
|
|
84
|
+
projects: [{project-names}]
|
|
85
|
+
tags: [{technology-tags}]
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## [{project-name}] {topic-title}
|
|
89
|
+
**작업 요약:** {concise summary with business context}
|
|
90
|
+
**배운 것:**
|
|
91
|
+
- {learning 1}
|
|
92
|
+
**고민한 포인트:**
|
|
93
|
+
- {decision}
|
|
94
|
+
**질문과 답변:**
|
|
95
|
+
- Q: {question}
|
|
96
|
+
→ A: {answer}
|
|
97
|
+
|
|
98
|
+
## 미분류
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
## Tags
|
|
102
|
+
#{tags}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Use the configured `language` for all generated text. Use the `profile` for business context framing.
|
|
106
|
+
|
|
107
|
+
### Important Recovery Rules
|
|
108
|
+
|
|
109
|
+
- If a session directory has no `.jsonl` files or they are empty, write `.completed` and skip (nothing to recover)
|
|
110
|
+
- If you cannot read a JSONL file, skip that file but continue with others
|
|
111
|
+
- NEVER delete or modify `.raw/` data — only add `.completed` markers
|
|
112
|
+
- Raw log recovery produces lower-quality reviews than transcript-based ones — that is acceptable
|
|
113
|
+
|
|
114
|
+
## Step 3: Merge Pending Reviews
|
|
115
|
+
|
|
116
|
+
Scan `.reviews/` (using the appropriate storage method to list contents) for `.md` files. These are session reviews waiting to be merged into daily files.
|
|
117
|
+
|
|
118
|
+
For each pending review file:
|
|
119
|
+
|
|
120
|
+
1. Read the review file
|
|
121
|
+
2. Extract the `date` from its YAML frontmatter
|
|
122
|
+
3. Determine the target daily file: `daily/{date}.md`
|
|
123
|
+
4. If the daily file exists, append the review content (minus the YAML frontmatter) to the end of the existing file
|
|
124
|
+
5. If the daily file does not exist, create it with the review content, adding a daily-level frontmatter:
|
|
125
|
+
|
|
126
|
+
```markdown
|
|
127
|
+
---
|
|
128
|
+
date: {YYYY-MM-DD}
|
|
129
|
+
type: daily-review
|
|
130
|
+
projects: [{all projects from merged reviews}]
|
|
131
|
+
tags: [{all tags from merged reviews}]
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
# {YYYY-MM-DD} Daily Review
|
|
135
|
+
|
|
136
|
+
{review content without its own frontmatter}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
6. After successfully writing to the daily file, delete the review file from `.reviews/` (for local storage, use Bash `rm`; for GitHub storage, use the GitHub API or simply overwrite — the storage-cli does not have a delete command, so leave merged review files in place for GitHub storage)
|
|
140
|
+
|
|
141
|
+
### Merge Rules
|
|
142
|
+
|
|
143
|
+
- When merging multiple reviews into the same daily file, combine the `projects` and `tags` lists in the frontmatter (deduplicate)
|
|
144
|
+
- Separate merged review sections with a blank line
|
|
145
|
+
- If the daily file already has a frontmatter, update its projects and tags lists
|
|
146
|
+
- Only delete a review file from `.reviews/` AFTER confirming the daily file was written successfully
|
|
147
|
+
- If writing fails, leave the review file in `.reviews/` for next time
|
|
148
|
+
|
|
149
|
+
## Step 4: Generate Periodic Summaries
|
|
150
|
+
|
|
151
|
+
Read `$CLAUDE_PLUGIN_DATA/last-run.json` to determine the last run date:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"lastRun": "2026-03-28"
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If `last-run.json` does not exist, skip periodic summary generation (this is the first run).
|
|
160
|
+
|
|
161
|
+
Compare today's date with the last run date to determine which summaries are needed. Only generate summaries for periods that are enabled in `config.periods`.
|
|
162
|
+
|
|
163
|
+
### 4a: Weekly Summary
|
|
164
|
+
|
|
165
|
+
**Trigger:** Today is in a different ISO week than `lastRun`, AND `periods.weekly` is `true`.
|
|
166
|
+
|
|
167
|
+
**Input:** Read all daily files from the previous week: `daily/{date}.md` where date falls within the previous ISO week.
|
|
168
|
+
|
|
169
|
+
**Output:** Write to `weekly/{YYYY-Www}.md` (e.g., `2026-W13.md`)
|
|
170
|
+
|
|
171
|
+
**Template:**
|
|
172
|
+
|
|
173
|
+
```markdown
|
|
174
|
+
---
|
|
175
|
+
date: {YYYY-Www}
|
|
176
|
+
type: weekly-review
|
|
177
|
+
period: {start-date} ~ {end-date}
|
|
178
|
+
projects: [{all projects from the week}]
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
# {YYYY-Www} 주간 회고
|
|
182
|
+
|
|
183
|
+
## 주요 성과
|
|
184
|
+
- [{project}] {achievement}
|
|
185
|
+
|
|
186
|
+
## 기술 스택 활용
|
|
187
|
+
- {technologies used this week}
|
|
188
|
+
|
|
189
|
+
## 핵심 의사결정
|
|
190
|
+
- {decision}: {choice} ({reason})
|
|
191
|
+
|
|
192
|
+
## 성장 포인트
|
|
193
|
+
- {what was learned}
|
|
194
|
+
|
|
195
|
+
## 다음 주 이어갈 것
|
|
196
|
+
- {carry-over items}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 4b: Monthly Summary
|
|
200
|
+
|
|
201
|
+
**Trigger:** Today is in a different month than `lastRun`, AND `periods.monthly` is `true`.
|
|
202
|
+
|
|
203
|
+
**Input:** If `periods.weekly` is enabled, read weekly files for the previous month. Otherwise, read daily files for the previous month.
|
|
204
|
+
|
|
205
|
+
**Output:** Write to `monthly/{YYYY-MM}.md` (e.g., `2026-03.md`)
|
|
206
|
+
|
|
207
|
+
**Template:**
|
|
208
|
+
|
|
209
|
+
```markdown
|
|
210
|
+
---
|
|
211
|
+
date: {YYYY-MM}
|
|
212
|
+
type: monthly-review
|
|
213
|
+
projects: [{all projects from the month}]
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
# {YYYY}년 {M}월 월간 회고
|
|
217
|
+
|
|
218
|
+
## 프로젝트별 진행 요약
|
|
219
|
+
### {project-name}
|
|
220
|
+
- {summary of work done}
|
|
221
|
+
|
|
222
|
+
## 이번 달 핵심 성장
|
|
223
|
+
- {key growth areas}
|
|
224
|
+
|
|
225
|
+
## 기술 스택
|
|
226
|
+
- {technologies used}
|
|
227
|
+
|
|
228
|
+
## 주요 의사결정 기록
|
|
229
|
+
- {decision} ({week or date})
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 4c: Quarterly Summary
|
|
233
|
+
|
|
234
|
+
**Trigger:** Today is in a different quarter than `lastRun`, AND `periods.quarterly` is `true`.
|
|
235
|
+
|
|
236
|
+
**Input:** Read monthly files for the previous quarter. If monthly is disabled, read weekly files. If weekly is also disabled, read daily files.
|
|
237
|
+
|
|
238
|
+
**Output:** Write to `quarterly/{YYYY-Qn}.md` (e.g., `2026-Q1.md`)
|
|
239
|
+
|
|
240
|
+
**Template:**
|
|
241
|
+
|
|
242
|
+
```markdown
|
|
243
|
+
---
|
|
244
|
+
date: {YYYY-Qn}
|
|
245
|
+
type: quarterly-review
|
|
246
|
+
period: {YYYY-MM} ~ {YYYY-MM}
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
# {YYYY} Q{n} 분기 회고
|
|
250
|
+
|
|
251
|
+
## 분기 성과 요약
|
|
252
|
+
- {project}: {achievement}
|
|
253
|
+
|
|
254
|
+
## 핵심 역량 성장
|
|
255
|
+
- {capability growth}
|
|
256
|
+
|
|
257
|
+
## 기술 스택 총괄
|
|
258
|
+
- {all technologies}
|
|
259
|
+
|
|
260
|
+
## 경력기술서 하이라이트
|
|
261
|
+
- {resume-worthy accomplishments — frame with profile context}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### 4d: Yearly Summary
|
|
265
|
+
|
|
266
|
+
**Trigger:** Today is in a different year than `lastRun`, AND `periods.yearly` is `true`.
|
|
267
|
+
|
|
268
|
+
**Input:** Read quarterly files for the previous year. If quarterly is disabled, read monthly. Cascade down as needed.
|
|
269
|
+
|
|
270
|
+
**Output:** Write to `yearly/{YYYY}.md` (e.g., `2026.md`)
|
|
271
|
+
|
|
272
|
+
**Template:**
|
|
273
|
+
|
|
274
|
+
```markdown
|
|
275
|
+
---
|
|
276
|
+
date: {YYYY}
|
|
277
|
+
type: yearly-review
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
# {YYYY} 연간 회고
|
|
281
|
+
|
|
282
|
+
## 연간 프로젝트 총괄
|
|
283
|
+
- {project}: {lifecycle summary}
|
|
284
|
+
|
|
285
|
+
## 핵심 역량 맵
|
|
286
|
+
- **{domain}:** {technologies}
|
|
287
|
+
|
|
288
|
+
## 이력서용 요약
|
|
289
|
+
- {resume bullet points — concise, achievement-oriented}
|
|
290
|
+
|
|
291
|
+
## 경력기술서용 상세
|
|
292
|
+
- {detailed career document entries — use profile context}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Cascading Logic
|
|
296
|
+
|
|
297
|
+
Summaries cascade: a weekly summary summarizes dailies, a monthly summarizes weeklies (or dailies if weekly is disabled), and so on. Always use the highest available granularity as input.
|
|
298
|
+
|
|
299
|
+
The cascade order for input selection:
|
|
300
|
+
- Monthly reads: weeklies > dailies
|
|
301
|
+
- Quarterly reads: monthlies > weeklies > dailies
|
|
302
|
+
- Yearly reads: quarterlies > monthlies > weeklies > dailies
|
|
303
|
+
|
|
304
|
+
## Step 5: Update last-run.json
|
|
305
|
+
|
|
306
|
+
After all steps complete (even if some failed), update `$CLAUDE_PLUGIN_DATA/last-run.json`:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"lastRun": "{today's date in YYYY-MM-DD format}"
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Create the file if it does not exist. Create parent directories if needed.
|
|
315
|
+
|
|
316
|
+
## Critical Rules
|
|
317
|
+
|
|
318
|
+
1. **Resilience over correctness.** If any step fails (file read error, parse error, write error), log the error to stderr and continue to the next step. Never abort the entire process due to a single failure.
|
|
319
|
+
2. **Never delete .raw/ data.** Only add `.completed` markers. Raw data is the source of truth for recovery.
|
|
320
|
+
3. **Only delete .reviews/ files after confirmed merge.** If the write to daily/ fails, leave the review file for retry.
|
|
321
|
+
4. **Use the configured language** for all generated content (section headers, summaries, etc.).
|
|
322
|
+
5. **Use profile context** for business framing in summaries — especially for quarterly/yearly summaries that serve as career documentation.
|
|
323
|
+
6. **Create directories as needed.** Use `mkdir -p` equivalent before writing any file.
|
|
324
|
+
7. **Obsidian compatibility.** Use valid markdown, proper YAML frontmatter, and Obsidian-style tags (`#tag-name`).
|
|
325
|
+
8. **Be concise.** Summaries at higher levels (weekly, monthly, quarterly, yearly) should be progressively more concise. A yearly summary should be readable in under 2 minutes.
|
|
326
|
+
9. **Respect periods config.** Only generate summaries for enabled periods. `daily` is always enabled.
|
|
327
|
+
10. **Idempotency.** If a periodic summary file already exists, do not overwrite it. It was already generated. Only generate summaries for periods that do not yet have a file.
|
|
328
|
+
|
|
329
|
+
## Section Labels by Language
|
|
330
|
+
|
|
331
|
+
| Section | ko | en |
|
|
332
|
+
|---------|----|----|
|
|
333
|
+
| Weekly Review | 주간 회고 | Weekly Review |
|
|
334
|
+
| Monthly Review | 월간 회고 | Monthly Review |
|
|
335
|
+
| Quarterly Review | 분기 회고 | Quarterly Review |
|
|
336
|
+
| Yearly Review | 연간 회고 | Yearly Review |
|
|
337
|
+
| Key Achievements | 주요 성과 | Key Achievements |
|
|
338
|
+
| Tech Stack | 기술 스택 활용 | Tech Stack Usage |
|
|
339
|
+
| Key Decisions | 핵심 의사결정 | Key Decisions |
|
|
340
|
+
| Growth | 성장 포인트 | Growth Points |
|
|
341
|
+
| Next Week | 다음 주 이어갈 것 | Carry Over to Next Week |
|
|
342
|
+
| Project Summary | 프로젝트별 진행 요약 | Project Progress Summary |
|
|
343
|
+
| Core Growth | 이번 달 핵심 성장 | Core Growth This Month |
|
|
344
|
+
| Decision Log | 주요 의사결정 기록 | Decision Log |
|
|
345
|
+
| Quarter Summary | 분기 성과 요약 | Quarter Achievement Summary |
|
|
346
|
+
| Capability Growth | 핵심 역량 성장 | Core Capability Growth |
|
|
347
|
+
| Full Tech Stack | 기술 스택 총괄 | Full Tech Stack |
|
|
348
|
+
| Resume Highlights | 경력기술서 하이라이트 | Resume Highlights |
|
|
349
|
+
| Annual Projects | 연간 프로젝트 총괄 | Annual Project Overview |
|
|
350
|
+
| Capability Map | 핵심 역량 맵 | Core Capability Map |
|
|
351
|
+
| Resume Summary | 이력서용 요약 | Resume Summary |
|
|
352
|
+
| Career Detail | 경력기술서용 상세 | Career Detail |
|
|
353
|
+
| Work Summary | 작업 요약 | Work Summary |
|
|
354
|
+
| Learnings | 배운 것 | Learnings |
|
|
355
|
+
| Decision Points | 고민한 포인트 | Decision Points |
|
|
356
|
+
| Q&A | 질문과 답변 | Q&A |
|
|
357
|
+
| Uncategorized | 미분류 | Uncategorized |
|
|
358
|
+
| Tags | Tags | Tags |
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: daily-review-setup
|
|
3
|
+
description: Configure the daily review plugin — set storage backend, user profile, and review periods
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Daily Review Setup
|
|
7
|
+
|
|
8
|
+
You are setting up the claude-daily-review plugin for the user.
|
|
9
|
+
|
|
10
|
+
## Check Existing Config
|
|
11
|
+
|
|
12
|
+
First, read `${CLAUDE_PLUGIN_DATA}/config.json` to see if a config already exists.
|
|
13
|
+
|
|
14
|
+
- If it exists, show the current settings and ask what the user wants to change.
|
|
15
|
+
- If it does not exist, proceed with the full onboarding flow below.
|
|
16
|
+
|
|
17
|
+
## Onboarding Flow
|
|
18
|
+
|
|
19
|
+
### Step 0: Storage Selection
|
|
20
|
+
|
|
21
|
+
Ask the user:
|
|
22
|
+
> "회고를 어디에 저장할까요?"
|
|
23
|
+
> 1. 로컬 폴더 (Obsidian vault 등)
|
|
24
|
+
> 2. GitHub 저장소
|
|
25
|
+
|
|
26
|
+
#### Option 1: Local Storage
|
|
27
|
+
|
|
28
|
+
Proceed to Step 1 (Vault Path) below. The storage config will be:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"storage": {
|
|
32
|
+
"type": "local",
|
|
33
|
+
"local": {
|
|
34
|
+
"basePath": "<path>/daily-review"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Option 2: GitHub Storage
|
|
41
|
+
|
|
42
|
+
**2a. Authenticate with GitHub OAuth Device Flow:**
|
|
43
|
+
|
|
44
|
+
Run via Bash:
|
|
45
|
+
```bash
|
|
46
|
+
node -e "
|
|
47
|
+
const { requestDeviceCode } = require('${CLAUDE_PLUGIN_ROOT}/dist/core/github-auth.js');
|
|
48
|
+
requestDeviceCode().then(r => console.log(JSON.stringify(r)));
|
|
49
|
+
"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Show the user:
|
|
53
|
+
> "GitHub 인증이 필요합니다. 아래 링크를 브라우저에서 열고 코드를 입력해주세요."
|
|
54
|
+
> - URL: https://github.com/login/device
|
|
55
|
+
> - 코드: `{user_code}`
|
|
56
|
+
|
|
57
|
+
Then poll for the token:
|
|
58
|
+
```bash
|
|
59
|
+
node -e "
|
|
60
|
+
const { pollForToken } = require('${CLAUDE_PLUGIN_ROOT}/dist/core/github-auth.js');
|
|
61
|
+
pollForToken('{device_code}', {interval}).then(r => console.log(JSON.stringify(r)));
|
|
62
|
+
"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Wait for the user to complete authorization. Store the returned `access_token`.
|
|
66
|
+
|
|
67
|
+
**2b. Select or create a repository:**
|
|
68
|
+
|
|
69
|
+
Ask:
|
|
70
|
+
> "기존 GitHub 저장소를 사용할까요, 새로 만들까요?"
|
|
71
|
+
> 1. 기존 저장소 사용
|
|
72
|
+
> 2. 새 저장소 만들기
|
|
73
|
+
|
|
74
|
+
- **Existing:** Ask for the repository in `owner/repo` format. Parse into `owner` and `repo`.
|
|
75
|
+
- **New:** Ask for a repo name. Create it via Bash:
|
|
76
|
+
```bash
|
|
77
|
+
gh api /user/repos -X POST -f name=<name> -f private=true
|
|
78
|
+
```
|
|
79
|
+
If `gh` is not available, tell the user to create the repo at https://github.com/new and then provide the `owner/repo`.
|
|
80
|
+
|
|
81
|
+
The storage config will be:
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"storage": {
|
|
85
|
+
"type": "github",
|
|
86
|
+
"github": {
|
|
87
|
+
"owner": "<owner>",
|
|
88
|
+
"repo": "<repo>",
|
|
89
|
+
"token": "<access_token>",
|
|
90
|
+
"basePath": "daily-review"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
After storage selection, proceed to Step 2 (Profile). Skip Step 1 (Vault Path) for GitHub storage.
|
|
97
|
+
|
|
98
|
+
### Step 1: Vault Path (Local storage only)
|
|
99
|
+
|
|
100
|
+
Ask the user:
|
|
101
|
+
> "Obsidian vault 경로를 알려주세요. (예: C:/Users/name/Documents/MyVault)"
|
|
102
|
+
|
|
103
|
+
After they provide a path:
|
|
104
|
+
- Verify the directory exists using the Bash tool: `test -d "{path}" && echo "OK" || echo "NOT_FOUND"`
|
|
105
|
+
- If not found, ask them to check the path
|
|
106
|
+
- Normalize the path (resolve ~, remove trailing slashes)
|
|
107
|
+
- Set the `basePath` in the storage config to `{path}/daily-review`
|
|
108
|
+
|
|
109
|
+
### Step 2: Profile
|
|
110
|
+
|
|
111
|
+
Ask the user these questions one at a time:
|
|
112
|
+
1. "어떤 회사에서 일하고 계신가요? (선택사항, 엔터로 건너뛰기)"
|
|
113
|
+
2. "역할/직무가 뭔가요? (예: 프론트엔드 개발자)"
|
|
114
|
+
3. "팀이나 담당 도메인이 있다면? (예: 결제플랫폼팀)"
|
|
115
|
+
4. "하고 계신 일을 한 줄로 설명하면? (예: B2B SaaS 결제 시스템 개발 및 운영)"
|
|
116
|
+
|
|
117
|
+
### Step 3: Periods
|
|
118
|
+
|
|
119
|
+
Show the available periods and defaults:
|
|
120
|
+
> "어떤 주기로 회고를 요약할까요? (기본값으로 진행하려면 엔터)"
|
|
121
|
+
> - [x] daily (항상 활성화)
|
|
122
|
+
> - [x] weekly (주간)
|
|
123
|
+
> - [x] monthly (월간)
|
|
124
|
+
> - [x] quarterly (분기)
|
|
125
|
+
> - [ ] yearly (연간)
|
|
126
|
+
|
|
127
|
+
### Step 4: Save
|
|
128
|
+
|
|
129
|
+
Construct the config JSON and write it to `${CLAUDE_PLUGIN_DATA}/config.json` using the Write tool.
|
|
130
|
+
|
|
131
|
+
The config format is:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"storage": { ... },
|
|
136
|
+
"language": "ko",
|
|
137
|
+
"periods": { "daily": true, "weekly": true, "monthly": true, "quarterly": true, "yearly": false },
|
|
138
|
+
"profile": {
|
|
139
|
+
"company": "...",
|
|
140
|
+
"role": "...",
|
|
141
|
+
"team": "...",
|
|
142
|
+
"context": "..."
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**If local storage:** Create the vault directories by running via Bash:
|
|
148
|
+
```bash
|
|
149
|
+
node -e "
|
|
150
|
+
const fs = require('fs');
|
|
151
|
+
const path = require('path');
|
|
152
|
+
const config = JSON.parse(fs.readFileSync('${CLAUDE_PLUGIN_DATA}/config.json', 'utf-8'));
|
|
153
|
+
const base = config.storage.local.basePath;
|
|
154
|
+
const dirs = ['daily', 'projects', 'uncategorized', '.raw', '.reviews'];
|
|
155
|
+
if (config.periods.weekly) dirs.push('weekly');
|
|
156
|
+
if (config.periods.monthly) dirs.push('monthly');
|
|
157
|
+
if (config.periods.quarterly) dirs.push('quarterly');
|
|
158
|
+
if (config.periods.yearly) dirs.push('yearly');
|
|
159
|
+
dirs.forEach(d => fs.mkdirSync(path.join(base, d), { recursive: true }));
|
|
160
|
+
console.log('Directories created at: ' + base);
|
|
161
|
+
"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**If GitHub storage:** Skip directory creation. Directories are created implicitly when files are written to the GitHub repository.
|
|
165
|
+
|
|
166
|
+
### Step 5: Confirm
|
|
167
|
+
|
|
168
|
+
Tell the user:
|
|
169
|
+
|
|
170
|
+
**For local storage:**
|
|
171
|
+
> "설정 완료! 이제부터 대화 내용이 자동으로 기록됩니다."
|
|
172
|
+
> "회고 파일은 `{basePath}/` 에서 확인하세요."
|
|
173
|
+
> "설정을 변경하려면 `/daily-review-setup`을 다시 실행하세요."
|
|
174
|
+
|
|
175
|
+
**For GitHub storage:**
|
|
176
|
+
> "설정 완료! 이제부터 대화 내용이 자동으로 GitHub에 기록됩니다."
|
|
177
|
+
> "회고 파일은 `https://github.com/{owner}/{repo}` 에서 확인하세요."
|
|
178
|
+
> "설정을 변경하려면 `/daily-review-setup`을 다시 실행하세요."
|