@ryan_nookpi/pi-extension-todo-write-overlay 0.1.1 → 0.1.2
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.md +12 -0
- package/index.ts +56 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ pi install npm:@ryan_nookpi/pi-extension-todo-write-overlay
|
|
|
20
20
|
- 세션 단위 todo 상태 저장 및 복원
|
|
21
21
|
- 우측 상단 오버레이 렌더링
|
|
22
22
|
- 입력 포커스를 뺏지 않는 `nonCapturing` overlay 사용
|
|
23
|
+
- `/todo-overlay show` / `/todo-overlay hide` 명령으로 오버레이 표시 토글
|
|
23
24
|
- 진행 중 작업 스피너 표시
|
|
24
25
|
- 완료/진행/대기 상태별 색상과 아이콘 표시
|
|
25
26
|
- `notes`는 상태에는 보존하지만 오버레이에는 표시하지 않음
|
|
@@ -37,6 +38,17 @@ pi install npm:@ryan_nookpi/pi-extension-todo-write-overlay
|
|
|
37
38
|
|
|
38
39
|
기존 `todo-write`의 `완료 +2` 같은 완료 항목 접기 로직은 사용하지 않습니다. 완료된 항목도 모두 그대로 표시합니다.
|
|
39
40
|
|
|
41
|
+
## 명령어
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
/todo-overlay show
|
|
45
|
+
/todo-overlay hide
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- 기본값은 `show`입니다.
|
|
49
|
+
- `hide`는 todo 상태와 reminder 주입은 유지하고, 우측 상단 오버레이 UI만 숨깁니다.
|
|
50
|
+
- 인자 없이 `/todo-overlay`를 실행하면 현재 표시 상태를 알려줍니다.
|
|
51
|
+
|
|
40
52
|
## 사용 예
|
|
41
53
|
|
|
42
54
|
```json
|
package/index.ts
CHANGED
|
@@ -53,6 +53,7 @@ const todoStateStore = new Map<string, TodoState>();
|
|
|
53
53
|
const todoOverlayStore = new Map<string, TodoOverlayRecord>();
|
|
54
54
|
const todoOverlayMetaStore = new Map<string, { completedAt?: number; completedTurn?: number }>();
|
|
55
55
|
const todoOverlayAgentRunningStore = new Map<string, boolean>();
|
|
56
|
+
const todoOverlayHiddenStore = new Map<string, boolean>();
|
|
56
57
|
const todoTurnStore = new Map<string, number>();
|
|
57
58
|
const TODO_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] as const;
|
|
58
59
|
const TODO_SPINNER_INTERVAL_MS = 120;
|
|
@@ -327,6 +328,23 @@ function setTodoOverlayAgentRunning(ctx: Pick<ExtensionContext, "cwd" | "session
|
|
|
327
328
|
todoOverlayAgentRunningStore.set(key, running);
|
|
328
329
|
}
|
|
329
330
|
|
|
331
|
+
export type TodoOverlayCommandAction = "show" | "hide" | "status" | "invalid";
|
|
332
|
+
|
|
333
|
+
export function parseTodoOverlayCommand(args: string): TodoOverlayCommandAction {
|
|
334
|
+
const action = args.trim().toLowerCase();
|
|
335
|
+
if (action === "") return "status";
|
|
336
|
+
if (action === "show" || action === "hide") return action;
|
|
337
|
+
return "invalid";
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function isTodoOverlayHidden(key: string): boolean {
|
|
341
|
+
return todoOverlayHiddenStore.get(key) ?? false;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function setTodoOverlayHidden(key: string, hidden: boolean): void {
|
|
345
|
+
todoOverlayHiddenStore.set(key, hidden);
|
|
346
|
+
}
|
|
347
|
+
|
|
330
348
|
function hideTodoOverlay(key: string): void {
|
|
331
349
|
const record = todoOverlayStore.get(key);
|
|
332
350
|
if (!record) return;
|
|
@@ -510,10 +528,47 @@ async function syncTodoOverlay(ctx: ExtensionContext, pi: Pick<ExtensionAPI, "ap
|
|
|
510
528
|
return;
|
|
511
529
|
}
|
|
512
530
|
|
|
531
|
+
if (isTodoOverlayHidden(key)) {
|
|
532
|
+
hideTodoOverlay(key);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
|
|
513
536
|
showOrUpdateTodoOverlay(ctx, key, state);
|
|
514
537
|
}
|
|
515
538
|
|
|
516
539
|
export default function todoWriteOverlayExtension(pi: ExtensionAPI): void {
|
|
540
|
+
pi.registerCommand("todo-overlay", {
|
|
541
|
+
description: "Show or hide the todo overlay. Usage: /todo-overlay show|hide",
|
|
542
|
+
getArgumentCompletions(prefix: string) {
|
|
543
|
+
const filtered = ["show", "hide"].filter((value) => value.startsWith(prefix.trim().toLowerCase()));
|
|
544
|
+
return filtered.length > 0 ? filtered.map((value) => ({ value, label: value })) : null;
|
|
545
|
+
},
|
|
546
|
+
async handler(args, ctx) {
|
|
547
|
+
const key = getTodoStateKey(ctx);
|
|
548
|
+
const action = parseTodoOverlayCommand(args);
|
|
549
|
+
|
|
550
|
+
if (action === "invalid") {
|
|
551
|
+
ctx.ui.notify("사용법: /todo-overlay show 또는 /todo-overlay hide", "warning");
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if (action === "status") {
|
|
556
|
+
ctx.ui.notify(`todo overlay: ${isTodoOverlayHidden(key) ? "hidden" : "shown"}`, "info");
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
setTodoOverlayHidden(key, action === "hide");
|
|
561
|
+
if (action === "hide") {
|
|
562
|
+
hideTodoOverlay(key);
|
|
563
|
+
ctx.ui.notify("todo overlay를 숨겼습니다. /todo-overlay show로 다시 표시할 수 있습니다.", "info");
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
await syncTodoOverlay(ctx, pi);
|
|
568
|
+
ctx.ui.notify("todo overlay를 표시합니다.", "info");
|
|
569
|
+
},
|
|
570
|
+
});
|
|
571
|
+
|
|
517
572
|
pi.registerTool({
|
|
518
573
|
name: "todo_write",
|
|
519
574
|
label: "할 일 관리",
|
|
@@ -642,6 +697,7 @@ export default function todoWriteOverlayExtension(pi: ExtensionAPI): void {
|
|
|
642
697
|
hideTodoOverlay(key);
|
|
643
698
|
todoOverlayMetaStore.delete(key);
|
|
644
699
|
todoOverlayAgentRunningStore.delete(key);
|
|
700
|
+
todoOverlayHiddenStore.delete(key);
|
|
645
701
|
todoTurnStore.delete(key);
|
|
646
702
|
});
|
|
647
703
|
}
|