oh-my-adhd 0.2.3 → 0.2.5

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.
@@ -275,7 +275,7 @@ export async function getThreads() {
275
275
  return sorted;
276
276
  }
277
277
  export async function getThread(threadId) {
278
- if (!threadId || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(threadId))
278
+ if (!threadId || !/^[a-zA-Z0-9_-]+$/.test(threadId))
279
279
  return null;
280
280
  try {
281
281
  return await fs.readFile(path.join(THREADS_DIR, `${threadId}.md`), "utf-8");
@@ -339,7 +339,7 @@ export async function savePage(slug, content) {
339
339
  await fs.writeFile(tmpPage, content, "utf-8");
340
340
  await fs.rename(tmpPage, pageFile);
341
341
  }
342
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
342
+ const UUID_RE = /^[a-zA-Z0-9_-]+$/;
343
343
  const TRASH_DIR = path.join(BRAIN_DIR, ".trash");
344
344
  export async function deleteThread(threadId) {
345
345
  if (!UUID_RE.test(threadId)) {
@@ -162,12 +162,30 @@ export function registerWikiRecall(server) {
162
162
  lines.push(`>`);
163
163
  lines.push(`> thread: \`${top.threadId}\``);
164
164
  }
165
- // Stale-open threads the user has forgotten — flag them separately
166
- const forgottenThreads = others.filter(t => t.is_open && t.status === "stale");
165
+ // Stale-open threads: split by depth of abandonment
166
+ const GHOST_THRESHOLD_H = 336; // 2 weeks "진짜 잊혀진 것"
167
+ const ghostThreads = others.filter(t => t.is_open && t.status === "stale" && (t.gap_hours ?? 0) >= GHOST_THRESHOLD_H);
168
+ const forgottenThreads = others.filter(t => t.is_open && t.status === "stale" && (t.gap_hours ?? 0) < GHOST_THRESHOLD_H);
167
169
  const activeOthers = others.filter(t => !(t.is_open && t.status === "stale"));
170
+ // Ghost projects: 2+ weeks untouched — direct question
171
+ if (ghostThreads.length > 0) {
172
+ lines.push("\n---");
173
+ lines.push("## 💀 아직도 할 거야?");
174
+ lines.push(`_${Math.floor(GHOST_THRESHOLD_H / 168)}주 이상 못 봤어. 계속할 건지, 정리할 건지 결정해줘._`);
175
+ for (const t of ghostThreads) {
176
+ const weeks = t.gap_hours !== null ? Math.floor(t.gap_hours / 168) : null;
177
+ const gapStr = weeks !== null ? `${weeks}주 전` : "";
178
+ const preview = t.next_action || t.last_action?.replace(/^(?:결정|가설|막힌것|다음할것|블로커|요약)\s*:\s*/i, "").slice(0, 80) || "";
179
+ lines.push(`💀 **${t.title}**${gapStr ? ` (${gapStr})` : ""}`);
180
+ if (preview)
181
+ lines.push(` 마지막: ${preview}`);
182
+ lines.push(` → 이어서? \`wiki_dump({ threadId: "${t.threadId}", content: "계속" })\``);
183
+ lines.push(` → 정리? \`wiki_dump({ threadId: "${t.threadId}", content: "결정: 이 프로젝트 종료" })\``);
184
+ }
185
+ }
168
186
  if (forgottenThreads.length > 0) {
169
187
  lines.push("\n---");
170
- lines.push("## 📌 잊고 있던 거 (열려있는데 오랫동안 못 봄)");
188
+ lines.push("## 📌 잊고 있던 거");
171
189
  for (const t of forgottenThreads) {
172
190
  const gap = gapLabel(t.gap_hours);
173
191
  const preview = t.next_action || t.last_action?.replace(/^(?:결정|가설|막힌것|다음할것|블로커|요약)\s*:\s*/i, "").slice(0, 80) || "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-adhd",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "ADHD second brain — zero-friction capture, auto context restore, unstick. MCP-native Claude Code plugin.",
5
5
  "author": "Yeachan Heo",
6
6
  "repository": {