pi-anchor 0.2.4 → 0.3.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.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # ⌖ Anchor
2
2
 
3
- > **Never lose unfinished tasks when closing Pi — pin reminders across sessions, wake them when touching matching files, and auto-complete on `git commit` with zero `TODO.md` clutter.**
3
+ > **Compact, Autonomous, Persistent Task Memory for Pi Coding Agent**
4
+ > Pin tasks across sessions (`/pin`), wake them automatically when entering the project or touching files, and settle them in real time on `git commit` — with **0 `TODO.md` repo clutter** and **0 idle tokens**.
4
5
 
5
6
  [![CI Status](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml/badge.svg)](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml)
6
7
  [![Node v20+](https://img.shields.io/badge/Node-v20+-22c55e.svg)](package.json)
7
8
  [![TypeScript Strict](https://img.shields.io/badge/TypeScript-Strict-3b82f6.svg)](tsconfig.json)
8
- [![Tests: 31 Passed](https://img.shields.io/badge/Tests-31%20Passed-22c55e.svg)](tests/store.test.ts)
9
+ [![Tests: 34 Passed](https://img.shields.io/badge/Tests-34%20Passed-22c55e.svg)](tests/store.test.ts)
9
10
  [![Startup: < 90ms](https://img.shields.io/badge/Startup-%3C%2090ms-success.svg)](package.json)
10
11
  [![Zero Repo Pollution](https://img.shields.io/badge/Storage-Zero%20Repo%20Pollution-success.svg)](#1-zero-repository-contamination--storage-topology)
11
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-f97316.svg)](LICENSE)
@@ -20,26 +21,29 @@ pi install npm:pi-anchor
20
21
  <img src="assets/hero-en.svg" alt="Anchor Terminal Dashboard" width="820">
21
22
  </p>
22
23
 
23
- ### How It Works in 3 Steps
24
-
25
- 1. **Pin in 1 second**: Tell the AI *"Remember to migrate auth tomorrow"* or type `/pin Migrate auth to HttpOnly cookies --due tomorrow`. Stored in `~/.anchor/state.json` (zero `TODO.md` files in your git repo).
26
- 2. **Wake up next session (0 idle tokens)**: Next time you open Pi, Anchor shows a 3-line summary above your editor and briefs the AI on Turn 1. From Turn 2 onwards, it consumes **0 tokens** — waking up only with a 1-line comment when the AI reads or edits matching files.
27
- 3. **Auto-complete on commit or test pass**: Commit related code (`git commit`), pass a `verifyCommand`, or run `/done 1` — Anchor archives the task automatically.
28
-
29
24
  ```text
30
- ⌖ Anchors (4 active):
31
-
32
- [Today · Today's Focus]
33
- 01 [Today] Optimize token truncation & JIT safety Desktop Today Today 10:02
25
+ ⌖ Anchors (3 active, 1 quiet):
34
26
 
35
- [Upcoming · Scheduled]
36
- 02 [Upcoming] Add concurrent file lock unit tests Desktop Tomorrow Yesterday 21:34
37
- 03 [Upcoming] Migrate auth module to HttpOnly cookies Desktop Tomorrow Today 10:02
38
- 04 [Upcoming] Polish CLI interactive dashboard & TUI Desktop In 2d Today 10:02
27
+ 01 [P0] Migrate auth module to HttpOnly cookies [src/auth.ts] anchor Today Today 10:02
28
+ 02 [P1] Add concurrent file lock unit tests anchor Tomorrow Yesterday 21:34
29
+ 03 [P1] Polish CLI interactive dashboard & TUI Desktop In 2d Today 10:02
30
+ 04 [Quiet] Read external architecture notes before refactor College/优化 Quiet (0 tok) 09-28 14:20
39
31
 
40
- Use `anchor done <id>` to complete.
32
+ Use `anchor done <id>` to complete, or `anchor undo` to restore.
41
33
  ```
42
34
 
35
+ ### The Three Pillars: Compact · Autonomous · Persistent
36
+
37
+ 1. **Compact (小巧 · Zero Bloat & 0 Idle Tokens)**:
38
+ - Pure TypeScript (~20KB bundle, zero external runtime dependencies, zero background daemons, zero SQL databases in your repo).
39
+ - Flat, priority-sorted engineering list (`/anchor`, `/pin`, `/done 1`). Briefs the AI on Turn 1 of a session, then drops to **0 tokens** from Turn 2+ while you code.
40
+ 2. **Autonomous (自主 · Smart Path Inference & Real-Time Commit Settlement)**:
41
+ - Automatically extracts file/folder paths mentioned in your task description and binds them to the target workspace even if you pinned the task from another directory.
42
+ - Settles tasks **in real time during the session** the moment `git commit` or a verification test command (`verifyCommand`) succeeds — works for both file-bound and plain-text tasks (`files: []`).
43
+ 3. **Persistent (持久 · Never Loses Unfinished Work)**:
44
+ - Stored safely in `~/.anchor/state.json` outside your git working tree.
45
+ - Unfinished tasks are **never silently deleted**. Tasks untouched for 7+ days enter `[Quiet]` mode (saving Turn 1 prompt tokens), stay 100% visible in `/anchor`, and automatically wake up the moment you open their target project or touch matching files.
46
+
43
47
  ---
44
48
 
45
49
  ## Why Anchor?
@@ -197,7 +201,7 @@ Engineered with strict TypeScript and 100% standard library test coverage using
197
201
 
198
202
  ```bash
199
203
  npm run typecheck # Strict tsc --noEmit check (0 errors)
200
- npm test # Native Node test runner (31/31 passing)
204
+ npm test # Native Node test runner (34/34 passing)
201
205
  npm run build # Dual ESM/CJS compilation via tsup + declaration emit
202
206
  ```
203
207
 
package/README_zh.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # ⌖ Anchor
2
2
 
3
- > **关掉终端也不丢待办 —— 一句话钉住跨会话任务(`/pin`),触碰关联代码时自动提醒 AI,提交代码(`git commit`)自动销账,0 `TODO.md` 污染。**
3
+ > **面向 Pi Coding Agent 的「小巧 · 自主 · 持久」跨会话任务记忆**
4
+ > 一句话钉住待办(`/pin`),进入目标工程或触碰关联文件自动唤醒,会话内执行 `git commit` 当场实时自动销账 —— **0 `TODO.md` 仓库污染,0 闲置 Token 损耗**。
4
5
 
5
6
  [![CI 状态](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml/badge.svg)](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml)
6
7
  [![Node v20+](https://img.shields.io/badge/Node-v20+-22c55e.svg)](package.json)
7
8
  [![TypeScript Strict](https://img.shields.io/badge/TypeScript-Strict-3b82f6.svg)](tsconfig.json)
8
- [![Tests: 31 Passed](https://img.shields.io/badge/Tests-31%20通过-22c55e.svg)](tests/store.test.ts)
9
+ [![Tests: 34 Passed](https://img.shields.io/badge/Tests-34%20通过-22c55e.svg)](tests/store.test.ts)
9
10
  [![启动耗时: < 90ms](https://img.shields.io/badge/启动耗时-%3C%2090ms-success.svg)](package.json)
10
11
  [![零仓库污染](https://img.shields.io/badge/存储-零仓库污染-success.svg)](#1-绝对零仓库污染与跨进程文件锁)
11
12
  [![开源协议: MIT](https://img.shields.io/badge/开源协议-MIT-f97316.svg)](LICENSE)
@@ -20,26 +21,29 @@ pi install npm:pi-anchor
20
21
  <img src="assets/hero-zh.svg" alt="Anchor 终端仪表盘实录" width="820">
21
22
  </p>
22
23
 
23
- ### 3 步看懂它怎么工作
24
-
25
- 1. **随手钉住待办**:直接对 AI 说 *“记一下明天把鉴权改成 HttpOnly Cookie”*,或敲 `/pin 重构鉴权模块 --due tomorrow`。保存在全局 `~/.anchor/state.json`,不在项目里留任何 `TODO.md` 垃圾文件。
26
- 2. **下次开终端自动唤醒(平时 0 Token)**:重新打开 Pi 时,编辑器上方展示 3 行今日聚焦清单,并在第 1 轮自动提醒 AI;从第 2 轮起 **0 Token 损耗**,只有当 AI 读/改关联代码文件时才附带 1 行注释精准提醒。
27
- 3. **提交代码自动销账**:`git commit` 提交关联代码、单测命令通过、或敲 `/done 1`,任务自动归档结案。
28
-
29
24
  ```text
30
- ⌖ Anchors (4 active):
31
-
32
- [Today · 今日聚焦]
33
- 01 [Today] 今天完成anchor项目后端优化 Desktop Today Today 10:02
25
+ ⌖ Anchors (3 active, 1 quiet):
34
26
 
35
- [Upcoming · 近期排期]
36
- 02 [Upcoming] 明天优化并发文件锁单元测试 Desktop Tomorrow Yesterday 21:34
37
- 03 [Upcoming] 重构鉴权模块为HttpOnly Cookie Desktop Tomorrow Today 10:02
38
- 04 [Upcoming] 完善CLI交互式仪表盘与TUI组件 Desktop In 2d Today 10:02
27
+ 01 [P0] 重构鉴权模块为 HttpOnly Cookie [src/auth.ts] anchor Today Today 10:02
28
+ 02 [P1] 补充并发文件锁单元测试 anchor Tomorrow Yesterday 21:34
29
+ 03 [P1] 打磨 CLI 交互式极简工程列表 Desktop In 2d Today 10:02
30
+ 04 [Quiet] College 重构前置查阅外部架构参考库 College/优化 Quiet (0 tok) 09-28 14:20
39
31
 
40
- Use `anchor done <id>` to complete.
32
+ Use `anchor done <id>` to complete, or `anchor undo` to restore.
41
33
  ```
42
34
 
35
+ ### 三大核心设计:小巧 · 自主 · 持久
36
+
37
+ 1. **小巧 (Compact · 极简顺手 & 0 闲置 Token)**:
38
+ - 纯 TypeScript 实现(~20KB 产物,0 外部二进制依赖,不在仓库塞数据库,不开后台常驻进程)。
39
+ - 砍掉繁琐的四象限与打卡分类,回归一屏看清的优先级工程列表(`/anchor`、`/pin`、`/done 1`)。第 1 轮冷启动简要提醒 AI,第 2 轮起 **0 Token 损耗**。
40
+ 2. **自主 (Autonomous · 智能路径识别 & 会话内实时核销)**:
41
+ - 即使你在别的目录随口记下一句任务,也会自动提取标题/描述里的文件与目录路径并绑定目标工程,下次切换到该目录时自动唤醒。
42
+ - **不等关闭终端**:会话内一旦执行 `git commit` 或通过测试命令(`verifyCommand`),哪怕没填 `files` 也能根据提交信息当场实时自动核销,状态栏 `⌖` 即刻更新。
43
+ 3. **持久 (Persistent · 永不莫名丢任务)**:
44
+ - 独立托管于全局 `~/.anchor/state.json`,项目 Git 树 100% 纯净。
45
+ - **绝不因过期而静默删任务**:超过 7 天未触碰的任务自动转为 `[Quiet]` 静默省流态(不在无关会话塞 Prompt),但在 `/anchor` 面板中始终可见,可随时一键唤醒或在进入对应工程时自动激活。
46
+
43
47
  ---
44
48
 
45
49
  ## 核心价值:为什么需要 Anchor?
@@ -204,7 +208,7 @@ Anchor 选择了一条极度克制的工程路径:把状态移出代码仓库
204
208
 
205
209
  ```bash
206
210
  npm run typecheck # TypeScript 严格类型检查 (0 错误)
207
- npm test # 全套自动化单元测试 (31/31 全绿通过)
211
+ npm test # 全套自动化单元测试 (34/34 全绿通过)
208
212
  npm run build # tsup 双格式打包 (ESM/CJS) 与 .d.ts 类型生成
209
213
  ```
210
214
 
@@ -9,100 +9,79 @@
9
9
  </linearGradient>
10
10
  </defs>
11
11
 
12
- <!-- Window Container with Shadow -->
13
12
  <g filter="url(#shadow)">
14
13
  <rect x="20" y="15" width="800" height="390" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
15
-
16
- <!-- Titlebar -->
17
14
  <path d="M 20,27 A 12,12 0 0,1 32,15 L 808,15 A 12,12 0 0,1 820,27 L 820,52 L 20,52 Z" fill="url(#headerGrad)" stroke="#343f44" stroke-width="1" />
18
15
  <line x1="20" y1="52" x2="820" y2="52" stroke="#2d353b" stroke-width="1" />
19
-
20
- <!-- Window Controls (macOS Dots) -->
21
16
  <circle cx="42" cy="33.5" r="5.5" fill="#e67e80" />
22
17
  <circle cx="60" cy="33.5" r="5.5" fill="#dbbc7f" />
23
18
  <circle cx="78" cy="33.5" r="5.5" fill="#a7c080" />
24
-
25
- <!-- Window Title -->
26
- <text x="420" y="38" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="12" font-weight="500" fill="#859289" letter-spacing="0.3">
27
- Jason@laptop ~ ⌖ anchor (v0.2.1)
19
+ <text x="420" y="38" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="12" font-weight="500" fill="#859289">
20
+ ⌖ anchor (v0.3.0) · Compact · Autonomous · Persistent
28
21
  </text>
29
22
  </g>
30
23
 
31
- <!-- Terminal Text Content -->
32
- <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Menlo, Consolas, monospace" font-size="13" xml:space="preserve">
33
- <!-- Prompt Command Line -->
34
- <text x="45" y="85">
24
+ <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
25
+ <text x="45" y="84">
35
26
  <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
36
27
  <tspan fill="#7fbbb3"> ❯ </tspan>
37
28
  <tspan fill="#d3c6aa" font-weight="bold">anchor</tspan>
38
29
  </text>
39
30
 
40
- <!-- Header Line -->
41
- <text x="45" y="118">
31
+ <text x="45" y="116">
42
32
  <tspan fill="#7fbbb3" font-weight="bold">⌖ Anchors </tspan>
43
- <tspan fill="#859289">(4 active):</tspan>
33
+ <tspan fill="#859289">(3 active, 1 quiet · 0 repo clutter · 0 idle tokens):</tspan>
44
34
  </text>
45
35
 
46
- <!-- Today Section Header -->
47
- <text x="45" y="152" fill="#e67e80" font-weight="bold"> [Today · Today's Focus]</text>
48
-
49
- <!-- Today Item -->
50
- <text x="45" y="178">
36
+ <text x="45" y="152">
51
37
  <tspan fill="#859289"> 01 </tspan>
52
- <tspan fill="#e67e80" font-weight="bold">[Today] </tspan>
53
- <tspan fill="#d3c6aa">Optimize token truncation &amp; JIT safety </tspan>
54
- <tspan fill="#859289">Desktop </tspan>
55
- <tspan fill="#e67e80" font-weight="bold">Today </tspan>
38
+ <tspan fill="#e67e80" font-weight="bold">[P0] </tspan>
39
+ <tspan fill="#d3c6aa">Migrate auth to HttpOnly cookies [src/auth.ts]</tspan>
40
+ <tspan fill="#7fbbb3"> anchor </tspan>
41
+ <tspan fill="#e67e80" font-weight="bold">Today </tspan>
56
42
  <tspan fill="#7a8478">Today 10:02</tspan>
57
43
  </text>
58
44
 
59
- <!-- Upcoming Section Header -->
60
- <text x="45" y="218" fill="#dbbc7f" font-weight="bold"> [Upcoming · Scheduled]</text>
61
-
62
- <!-- Upcoming Items -->
63
- <text x="45" y="244">
45
+ <text x="45" y="182">
64
46
  <tspan fill="#859289"> 02 </tspan>
65
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
66
- <tspan fill="#d3c6aa">Add concurrent file lock unit tests </tspan>
67
- <tspan fill="#859289">Desktop </tspan>
68
- <tspan fill="#dbbc7f">Tomorrow </tspan>
47
+ <tspan fill="#dbbc7f" font-weight="bold">[P1] </tspan>
48
+ <tspan fill="#d3c6aa">Add concurrent file lock unit tests </tspan>
49
+ <tspan fill="#7fbbb3"> anchor </tspan>
50
+ <tspan fill="#dbbc7f">Tomorrow </tspan>
69
51
  <tspan fill="#7a8478">Yesterday 21:34</tspan>
70
52
  </text>
71
53
 
72
- <text x="45" y="270">
54
+ <text x="45" y="212">
73
55
  <tspan fill="#859289"> 03 </tspan>
74
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
75
- <tspan fill="#d3c6aa">Migrate auth module to HttpOnly cookies</tspan>
76
- <tspan fill="#859289">Desktop </tspan>
77
- <tspan fill="#dbbc7f">Tomorrow </tspan>
56
+ <tspan fill="#dbbc7f" font-weight="bold">[P1] </tspan>
57
+ <tspan fill="#d3c6aa">Polish CLI interactive dashboard &amp; TUI </tspan>
58
+ <tspan fill="#7fbbb3"> Desktop </tspan>
59
+ <tspan fill="#a7c080">In 2d </tspan>
78
60
  <tspan fill="#7a8478">Today 10:02</tspan>
79
61
  </text>
80
62
 
81
- <text x="45" y="296">
63
+ <text x="45" y="242">
82
64
  <tspan fill="#859289"> 04 </tspan>
83
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
84
- <tspan fill="#d3c6aa">Polish CLI interactive dashboard &amp; TUI </tspan>
85
- <tspan fill="#859289">Desktop </tspan>
86
- <tspan fill="#dbbc7f">In 2d </tspan>
87
- <tspan fill="#7a8478">Today 10:02</tspan>
65
+ <tspan fill="#7a8478" font-weight="bold">[Quiet] </tspan>
66
+ <tspan fill="#859289">Review external architecture reference notes </tspan>
67
+ <tspan fill="#7a8478"> College/Opt </tspan>
68
+ <tspan fill="#7a8478">Quiet (0 tok) </tspan>
69
+ <tspan fill="#56635f">09-28 14:20</tspan>
88
70
  </text>
89
71
 
90
- <!-- Footer Action -->
91
- <text x="45" y="340" fill="#7a8478">
92
- <tspan> Use </tspan>
93
- <tspan fill="#7fbbb3" font-weight="bold">`anchor done &lt;id&gt;`</tspan>
94
- <tspan> to complete.</tspan>
95
- </text>
72
+ <rect x="45" y="274" width="750" height="58" rx="6" fill="#232a2e" stroke="#3a464c" stroke-width="1" />
73
+ <text x="62" y="298" fill="#a7c080" font-weight="bold">⚡ Real-Time Autonomous Settlement (on `git commit` or passing `verifyCommand`):</text>
74
+ <text x="62" y="319" fill="#d3c6aa"> git commit -m "feat(auth): migrate auth to HttpOnly cookies" ➔ ⌖ Auto-settled #anc-1</text>
96
75
 
97
- <!-- Active Input Cursor -->
98
- <text x="45" y="378">
99
- <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
100
- <tspan fill="#7fbbb3"> ❯ </tspan>
101
- <tspan fill="#7fbbb3">⌖</tspan>
102
- <tspan fill="#d3c6aa"> </tspan>
103
- <rect x="175" y="364" width="8" height="16" fill="#a7c080" opacity="0.8">
104
- <animate attributeName="opacity" values="0.8;0.1;0.8" dur="1.1s" repeatCount="indefinite" />
105
- </rect>
76
+ <text x="45" y="366" fill="#7a8478">
77
+ <tspan> Commands: </tspan>
78
+ <tspan fill="#7fbbb3" font-weight="bold">`/pin &lt;task&gt;`</tspan>
79
+ <tspan> · </tspan>
80
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor`</tspan>
81
+ <tspan> · </tspan>
82
+ <tspan fill="#7fbbb3" font-weight="bold">`/done 1`</tspan>
83
+ <tspan> · </tspan>
84
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor undo`</tspan>
106
85
  </text>
107
86
  </g>
108
87
  </svg>
@@ -9,100 +9,79 @@
9
9
  </linearGradient>
10
10
  </defs>
11
11
 
12
- <!-- Window Container with Shadow -->
13
12
  <g filter="url(#shadow)">
14
13
  <rect x="20" y="15" width="800" height="390" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
15
-
16
- <!-- Titlebar -->
17
14
  <path d="M 20,27 A 12,12 0 0,1 32,15 L 808,15 A 12,12 0 0,1 820,27 L 820,52 L 20,52 Z" fill="url(#headerGrad)" stroke="#343f44" stroke-width="1" />
18
15
  <line x1="20" y1="52" x2="820" y2="52" stroke="#2d353b" stroke-width="1" />
19
-
20
- <!-- Window Controls (macOS Dots) -->
21
16
  <circle cx="42" cy="33.5" r="5.5" fill="#e67e80" />
22
17
  <circle cx="60" cy="33.5" r="5.5" fill="#dbbc7f" />
23
18
  <circle cx="78" cy="33.5" r="5.5" fill="#a7c080" />
24
-
25
- <!-- Window Title -->
26
- <text x="420" y="38" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="12" font-weight="500" fill="#859289" letter-spacing="0.3">
27
- Jason@laptop ~ ⌖ anchor (v0.2.1)
19
+ <text x="420" y="38" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="12" font-weight="500" fill="#859289">
20
+ ⌖ anchor (v0.3.0) · 小巧 · 自主 · 持久
28
21
  </text>
29
22
  </g>
30
23
 
31
- <!-- Terminal Text Content -->
32
- <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Menlo, Consolas, monospace" font-size="13" xml:space="preserve">
33
- <!-- Prompt Command Line -->
34
- <text x="45" y="85">
24
+ <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
25
+ <text x="45" y="84">
35
26
  <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
36
27
  <tspan fill="#7fbbb3"> ❯ </tspan>
37
28
  <tspan fill="#d3c6aa" font-weight="bold">anchor</tspan>
38
29
  </text>
39
30
 
40
- <!-- Header Line -->
41
- <text x="45" y="118">
31
+ <text x="45" y="116">
42
32
  <tspan fill="#7fbbb3" font-weight="bold">⌖ Anchors </tspan>
43
- <tspan fill="#859289">(4 active):</tspan>
33
+ <tspan fill="#859289">(3 active, 1 quiet · 0 仓库污染 · 0 闲置 Token):</tspan>
44
34
  </text>
45
35
 
46
- <!-- Today Section Header -->
47
- <text x="45" y="152" fill="#e67e80" font-weight="bold"> [Today · 今日聚焦]</text>
48
-
49
- <!-- Today Item -->
50
- <text x="45" y="178">
36
+ <text x="45" y="152">
51
37
  <tspan fill="#859289"> 01 </tspan>
52
- <tspan fill="#e67e80" font-weight="bold">[Today] </tspan>
53
- <tspan fill="#d3c6aa">今天完成anchor项目后端优化 </tspan>
54
- <tspan fill="#859289"> Desktop </tspan>
55
- <tspan fill="#e67e80" font-weight="bold">Today </tspan>
38
+ <tspan fill="#e67e80" font-weight="bold">[P0] </tspan>
39
+ <tspan fill="#d3c6aa">重构鉴权模块为 HttpOnly Cookie [src/auth.ts]</tspan>
40
+ <tspan fill="#7fbbb3"> anchor </tspan>
41
+ <tspan fill="#e67e80" font-weight="bold">Today </tspan>
56
42
  <tspan fill="#7a8478">Today 10:02</tspan>
57
43
  </text>
58
44
 
59
- <!-- Upcoming Section Header -->
60
- <text x="45" y="218" fill="#dbbc7f" font-weight="bold"> [Upcoming · 近期排期]</text>
61
-
62
- <!-- Upcoming Items -->
63
- <text x="45" y="244">
45
+ <text x="45" y="182">
64
46
  <tspan fill="#859289"> 02 </tspan>
65
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
66
- <tspan fill="#d3c6aa">明天优化并发文件锁单元测试 </tspan>
67
- <tspan fill="#859289"> Desktop </tspan>
68
- <tspan fill="#dbbc7f">Tomorrow </tspan>
47
+ <tspan fill="#dbbc7f" font-weight="bold">[P1] </tspan>
48
+ <tspan fill="#d3c6aa">补充并发文件锁单元测试 </tspan>
49
+ <tspan fill="#7fbbb3"> anchor </tspan>
50
+ <tspan fill="#dbbc7f">Tomorrow </tspan>
69
51
  <tspan fill="#7a8478">Yesterday 21:34</tspan>
70
52
  </text>
71
53
 
72
- <text x="45" y="270">
54
+ <text x="45" y="212">
73
55
  <tspan fill="#859289"> 03 </tspan>
74
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
75
- <tspan fill="#d3c6aa">重构鉴权模块为HttpOnly Cookie </tspan>
76
- <tspan fill="#859289"> Desktop </tspan>
77
- <tspan fill="#dbbc7f">Tomorrow </tspan>
56
+ <tspan fill="#dbbc7f" font-weight="bold">[P1] </tspan>
57
+ <tspan fill="#d3c6aa">打磨 CLI 交互式极简工程列表 </tspan>
58
+ <tspan fill="#7fbbb3"> Desktop </tspan>
59
+ <tspan fill="#a7c080">In 2d </tspan>
78
60
  <tspan fill="#7a8478">Today 10:02</tspan>
79
61
  </text>
80
62
 
81
- <text x="45" y="296">
63
+ <text x="45" y="242">
82
64
  <tspan fill="#859289"> 04 </tspan>
83
- <tspan fill="#dbbc7f">[Upcoming] </tspan>
84
- <tspan fill="#d3c6aa">完善CLI交互式仪表盘与TUI组件 </tspan>
85
- <tspan fill="#859289"> Desktop </tspan>
86
- <tspan fill="#dbbc7f">In 2d </tspan>
87
- <tspan fill="#7a8478">Today 10:02</tspan>
65
+ <tspan fill="#7a8478" font-weight="bold">[Quiet] </tspan>
66
+ <tspan fill="#859289">College 重构前置查阅外部架构参考库 </tspan>
67
+ <tspan fill="#7a8478"> College/优化 </tspan>
68
+ <tspan fill="#7a8478">Quiet (0 tok) </tspan>
69
+ <tspan fill="#56635f">09-28 14:20</tspan>
88
70
  </text>
89
71
 
90
- <!-- Footer Action -->
91
- <text x="45" y="340" fill="#7a8478">
92
- <tspan> Use </tspan>
93
- <tspan fill="#7fbbb3" font-weight="bold">`anchor done &lt;id&gt;`</tspan>
94
- <tspan> to complete.</tspan>
95
- </text>
72
+ <rect x="45" y="274" width="750" height="58" rx="6" fill="#232a2e" stroke="#3a464c" stroke-width="1" />
73
+ <text x="62" y="298" fill="#a7c080" font-weight="bold">⚡ 会话内实时自主核销(执行 git commit 或测试通过当场自动结案):</text>
74
+ <text x="62" y="319" fill="#d3c6aa"> git commit -m "feat(auth): 重构鉴权模块为 HttpOnly Cookie" ➔ ⌖ Auto-settled #anc-1</text>
96
75
 
97
- <!-- Active Input Cursor -->
98
- <text x="45" y="378">
99
- <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
100
- <tspan fill="#7fbbb3"> ❯ </tspan>
101
- <tspan fill="#7fbbb3">⌖</tspan>
102
- <tspan fill="#d3c6aa"> </tspan>
103
- <rect x="175" y="364" width="8" height="16" fill="#a7c080" opacity="0.8">
104
- <animate attributeName="opacity" values="0.8;0.1;0.8" dur="1.1s" repeatCount="indefinite" />
105
- </rect>
76
+ <text x="45" y="366" fill="#7a8478">
77
+ <tspan> 常用命令: </tspan>
78
+ <tspan fill="#7fbbb3" font-weight="bold">`/pin &lt;任务&gt;`</tspan>
79
+ <tspan> · </tspan>
80
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor`</tspan>
81
+ <tspan> · </tspan>
82
+ <tspan fill="#7fbbb3" font-weight="bold">`/done 1`</tspan>
83
+ <tspan> · </tspan>
84
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor undo`</tspan>
106
85
  </text>
107
86
  </g>
108
87
  </svg>
package/bin/anchor.js CHANGED
@@ -7,11 +7,10 @@
7
7
 
8
8
  import {
9
9
  AnchorStore,
10
- classifyAnchor,
11
10
  formatOrigin,
12
11
  formatTargetDate,
13
12
  formatCreationTime,
14
- groupAnchorsByQuadrant,
13
+ sortAnchorsForDisplay,
15
14
  padToWidth
16
15
  } from '../dist/index.js';
17
16
 
@@ -20,53 +19,45 @@ const args = process.argv.slice(2);
20
19
 
21
20
  // 1. View pending tasks: `anchor` or `anchor list`
22
21
  if (args.length === 0 || args[0] === 'list' || args[0] === 'ls') {
23
- const active = store.list({ status: 'active', cwd: process.cwd() });
22
+ const allUnfinished = store
23
+ .list({ cwd: process.cwd(), all: true })
24
+ .filter(a => a.status === 'active' || a.status === 'sleeping');
24
25
 
25
- if (active.length === 0) {
26
+ if (allUnfinished.length === 0) {
26
27
  console.log('\n⌖ No active anchors. Use `anchor <task>` to record.\n');
27
28
  process.exit(0);
28
29
  }
29
30
 
30
- console.log(`\n⌖ Anchors (${active.length} active):\n`);
31
-
32
- const groups = groupAnchorsByQuadrant(active);
33
- const sections = [
34
- { title: "Today · Today's Focus", list: groups.today },
35
- { title: 'Upcoming · Scheduled', list: groups.upcoming },
36
- { title: 'Habits · Daily Loop', list: groups.habits },
37
- { title: 'Backlog · Someday', list: groups.backlog },
38
- ];
39
-
40
- let seqNum = 1;
41
-
42
- for (const sec of sections) {
43
- if (sec.list.length === 0) continue;
44
- console.log(` [${sec.title}]`);
45
- sec.list.forEach((a) => {
46
- const num = seqNum.toString().padStart(2, '0');
47
- seqNum++;
48
-
49
- const category = padToWidth(`[${classifyAnchor(a)}]`, 12);
50
- const origin = formatOrigin(a);
51
- const target = formatTargetDate(a);
52
- const created = formatCreationTime(a.createdAt);
53
-
54
- const titleWithFiles = (a.files && a.files.length > 0)
55
- ? `${a.title} [${a.files.slice(0, 1).join(', ')}]`
56
- : a.title;
57
-
58
- const colNum = ` ${num} `;
59
- const colTitle = padToWidth(titleWithFiles, 28);
60
- const colOrigin = padToWidth(origin, 10);
61
- const colTarget = padToWidth(target, 12);
62
- const colCreated = created;
63
-
64
- console.log(`${colNum}${category}${colTitle} ${colOrigin} ${colTarget} ${colCreated}`);
65
- });
66
- console.log('');
67
- }
31
+ const sorted = sortAnchorsForDisplay(allUnfinished, process.cwd());
32
+ const activeCount = sorted.filter(a => a.status === 'active').length;
33
+ const quietCount = sorted.length - activeCount;
34
+ const headerSuffix = quietCount > 0 ? `${activeCount} active, ${quietCount} quiet` : `${activeCount} active`;
35
+
36
+ console.log(`\n⌖ Anchors (${headerSuffix}):\n`);
37
+
38
+ sorted.forEach((a, idx) => {
39
+ const num = String(idx + 1).padStart(2, '0');
40
+ const badge = a.status === 'sleeping'
41
+ ? padToWidth('[Quiet]', 10)
42
+ : padToWidth(`[${a.priority.toUpperCase()}]`, 10);
43
+ const origin = formatOrigin(a);
44
+ const target = a.status === 'sleeping' ? 'Quiet (0 tok)' : formatTargetDate(a);
45
+ const created = formatCreationTime(a.createdAt);
46
+
47
+ const titleWithFiles = (a.files && a.files.length > 0)
48
+ ? `${a.title} [${a.files.slice(0, 1).join(', ')}]`
49
+ : a.title;
50
+
51
+ const colNum = ` ${num} `;
52
+ const colTitle = padToWidth(titleWithFiles, 36);
53
+ const colOrigin = padToWidth(origin, 14);
54
+ const colTarget = padToWidth(target, 14);
55
+ const colCreated = created;
56
+
57
+ console.log(`${colNum}${badge}${colTitle} ${colOrigin} ${colTarget} ${colCreated}`);
58
+ });
68
59
 
69
- console.log(' Use `anchor done <id>` to complete.\n');
60
+ console.log('\n Use `anchor done <id>` to complete, or `anchor undo` to restore.\n');
70
61
  process.exit(0);
71
62
  }
72
63
 
@@ -110,14 +101,10 @@ if (args[0] === 'done' || args[0] === 'rm' || args[0] === 'close') {
110
101
  }
111
102
  try {
112
103
  // 1. Check if idInput is a 1-based sequential display number (e.g. '1', '01')
113
- const active = store.list({ status: 'active', cwd: process.cwd() });
114
- const groups = groupAnchorsByQuadrant(active);
115
- const sortedActive = [
116
- ...groups.today,
117
- ...groups.upcoming,
118
- ...groups.habits,
119
- ...groups.backlog
120
- ];
104
+ const allUnfinished = store
105
+ .list({ cwd: process.cwd(), all: true })
106
+ .filter(a => a.status === 'active' || a.status === 'sleeping');
107
+ const sortedActive = sortAnchorsForDisplay(allUnfinished, process.cwd());
121
108
 
122
109
  let targetId = idInput;
123
110
  const numMatch = idInput.match(/^\d+$/);