pi-anchor 0.2.4 → 0.4.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.
@@ -1,4 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840 430" width="840" height="430">
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840 390" width="840" height="390">
2
2
  <defs>
3
3
  <filter id="shadow" x="-5%" y="-5%" width="110%" height="115%" filterUnits="userSpaceOnUse">
4
4
  <feDropShadow dx="0" dy="12" stdDeviation="16" flood-color="#000000" flood-opacity="0.45" />
@@ -9,100 +9,63 @@
9
9
  </linearGradient>
10
10
  </defs>
11
11
 
12
- <!-- Window Container with Shadow -->
13
12
  <g filter="url(#shadow)">
14
- <rect x="20" y="15" width="800" height="390" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
15
-
16
- <!-- Titlebar -->
13
+ <rect x="20" y="15" width="800" height="350" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
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 · A Digital Sticky Note for Your Terminal
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">
35
- <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
24
+ <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
25
+ <text x="45" y="86">
26
+ <tspan fill="#a7c080" font-weight="bold">~/Workspace/app</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">
42
- <tspan fill="#7fbbb3" font-weight="bold">⌖ Anchors </tspan>
43
- <tspan fill="#859289">(4 active):</tspan>
31
+ <text x="45" y="120">
32
+ <tspan fill="#7fbbb3" font-weight="bold">⌖ Notes (3):</tspan>
44
33
  </text>
45
34
 
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">
35
+ <text x="45" y="154">
51
36
  <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>
56
- <tspan fill="#7a8478">Today 10:02</tspan>
37
+ <tspan fill="#d3c6aa">Switch session token to HttpOnly cookie </tspan>
38
+ <tspan fill="#7fbbb3">app · auth.ts </tspan>
39
+ <tspan fill="#7a8478">25m ago</tspan>
57
40
  </text>
58
41
 
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">
42
+ <text x="45" y="182">
64
43
  <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>
69
- <tspan fill="#7a8478">Yesterday 21:34</tspan>
44
+ <tspan fill="#d3c6aa">Double-check rate limit fallback on timeout </tspan>
45
+ <tspan fill="#7fbbb3">app · gateway.ts </tspan>
46
+ <tspan fill="#7a8478">3h ago</tspan>
70
47
  </text>
71
48
 
72
- <text x="45" y="270">
49
+ <text x="45" y="210">
73
50
  <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>
78
- <tspan fill="#7a8478">Today 10:02</tspan>
51
+ <tspan fill="#859289">Read external architecture notes first </tspan>
52
+ <tspan fill="#7a8478">College/优化 · notes.md </tspan>
53
+ <tspan fill="#56635f">8d ago · quiet</tspan>
79
54
  </text>
80
55
 
81
- <text x="45" y="296">
82
- <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>
88
- </text>
89
-
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>
56
+ <rect x="45" y="242" width="750" height="58" rx="6" fill="#232a2e" stroke="#3a464c" stroke-width="1" />
57
+ <text x="62" y="266" fill="#dbbc7f">1. Stick a note: /pin Switch session token to HttpOnly cookie in src/auth.ts</text>
58
+ <text x="62" y="287" fill="#a7c080">2. Auto-tear off: git commit -m "feat: switch session token to HttpOnly cookie" ➔ ⌖ Torn off #1</text>
96
59
 
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>
60
+ <text x="45" y="334" fill="#7a8478">
61
+ <tspan> Commands: </tspan>
62
+ <tspan fill="#7fbbb3" font-weight="bold">`/pin &lt;note&gt;`</tspan>
63
+ <tspan> · </tspan>
64
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor`</tspan>
65
+ <tspan> · </tspan>
66
+ <tspan fill="#7fbbb3" font-weight="bold">`/done 1`</tspan>
67
+ <tspan> · </tspan>
68
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor undo`</tspan>
106
69
  </text>
107
70
  </g>
108
71
  </svg>
@@ -1,4 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840 430" width="840" height="430">
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840 390" width="840" height="390">
2
2
  <defs>
3
3
  <filter id="shadow" x="-5%" y="-5%" width="110%" height="115%" filterUnits="userSpaceOnUse">
4
4
  <feDropShadow dx="0" dy="12" stdDeviation="16" flood-color="#000000" flood-opacity="0.45" />
@@ -9,100 +9,63 @@
9
9
  </linearGradient>
10
10
  </defs>
11
11
 
12
- <!-- Window Container with Shadow -->
13
12
  <g filter="url(#shadow)">
14
- <rect x="20" y="15" width="800" height="390" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
15
-
16
- <!-- Titlebar -->
13
+ <rect x="20" y="15" width="800" height="350" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
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 · 贴在终端边框上的电子便签
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">
35
- <tspan fill="#a7c080" font-weight="bold">~/Workspace</tspan>
24
+ <g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
25
+ <text x="45" y="86">
26
+ <tspan fill="#a7c080" font-weight="bold">~/Workspace/app</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">
42
- <tspan fill="#7fbbb3" font-weight="bold">⌖ Anchors </tspan>
43
- <tspan fill="#859289">(4 active):</tspan>
31
+ <text x="45" y="120">
32
+ <tspan fill="#7fbbb3" font-weight="bold">⌖ Notes (3):</tspan>
44
33
  </text>
45
34
 
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">
35
+ <text x="45" y="154">
51
36
  <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>
56
- <tspan fill="#7a8478">Today 10:02</tspan>
37
+ <tspan fill="#d3c6aa">把登录 Token 改用 HttpOnly Cookie 存储 </tspan>
38
+ <tspan fill="#7fbbb3">app · auth.ts </tspan>
39
+ <tspan fill="#7a8478">25m ago</tspan>
57
40
  </text>
58
41
 
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">
42
+ <text x="45" y="182">
64
43
  <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>
69
- <tspan fill="#7a8478">Yesterday 21:34</tspan>
44
+ <tspan fill="#d3c6aa">检查网关超时后的降级重试边界 </tspan>
45
+ <tspan fill="#7fbbb3">app · gateway.ts </tspan>
46
+ <tspan fill="#7a8478">3h ago</tspan>
70
47
  </text>
71
48
 
72
- <text x="45" y="270">
49
+ <text x="45" y="210">
73
50
  <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>
78
- <tspan fill="#7a8478">Today 10:02</tspan>
51
+ <tspan fill="#859289">College 重构前置查阅外部架构参考库 </tspan>
52
+ <tspan fill="#7a8478">College/优化 · notes.md </tspan>
53
+ <tspan fill="#56635f">8d ago · quiet</tspan>
79
54
  </text>
80
55
 
81
- <text x="45" y="296">
82
- <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>
88
- </text>
89
-
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>
56
+ <rect x="45" y="242" width="750" height="58" rx="6" fill="#232a2e" stroke="#3a464c" stroke-width="1" />
57
+ <text x="62" y="266" fill="#dbbc7f">1. 随手贴一张: /pin 把 src/auth.ts 的登录改用 HttpOnly Cookie</text>
58
+ <text x="62" y="287" fill="#a7c080">2. 提交自动撕: git commit -m "feat: 登录改用 HttpOnly Cookie" ➔ ⌖ Torn off #1</text>
96
59
 
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>
60
+ <text x="45" y="334" fill="#7a8478">
61
+ <tspan> 常用命令: </tspan>
62
+ <tspan fill="#7fbbb3" font-weight="bold">`/pin &lt;便签&gt;`</tspan>
63
+ <tspan> · </tspan>
64
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor`</tspan>
65
+ <tspan> · </tspan>
66
+ <tspan fill="#7fbbb3" font-weight="bold">`/done 1`</tspan>
67
+ <tspan> · </tspan>
68
+ <tspan fill="#7fbbb3" font-weight="bold">`/anchor undo`</tspan>
106
69
  </text>
107
70
  </g>
108
71
  </svg>
package/bin/anchor.js CHANGED
@@ -1,80 +1,57 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Anchor CLI - Minimalist task protocol for AI coding workflows
5
- * Production-ready executable with dual-timeline & 4-quadrant cognitive grouping
4
+ * Anchor CLI — Minimalist terminal sticky notes for AI coding
6
5
  */
7
6
 
8
7
  import {
9
8
  AnchorStore,
10
- classifyAnchor,
11
9
  formatOrigin,
12
- formatTargetDate,
13
- formatCreationTime,
14
- groupAnchorsByQuadrant,
10
+ formatRelativeAge,
11
+ sortAnchorsForDisplay,
15
12
  padToWidth
16
13
  } from '../dist/index.js';
17
14
 
18
15
  const store = new AnchorStore();
19
16
  const args = process.argv.slice(2);
20
17
 
21
- // 1. View pending tasks: `anchor` or `anchor list`
18
+ // 1. View sticky notes: `anchor` or `anchor list`
22
19
  if (args.length === 0 || args[0] === 'list' || args[0] === 'ls') {
23
- const active = store.list({ status: 'active', cwd: process.cwd() });
20
+ const allNotes = store
21
+ .list({ cwd: process.cwd(), all: true })
22
+ .filter(a => a.status === 'active' || a.status === 'sleeping');
24
23
 
25
- if (active.length === 0) {
26
- console.log('\n⌖ No active anchors. Use `anchor <task>` to record.\n');
24
+ if (allNotes.length === 0) {
25
+ console.log('\n⌖ No sticky notes. Run `anchor "<note>"` to stick one.\n');
27
26
  process.exit(0);
28
27
  }
29
28
 
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
- }
29
+ const sorted = sortAnchorsForDisplay(allNotes, process.cwd());
30
+ console.log(`\n⌖ Notes (${sorted.length}):\n`);
31
+
32
+ sorted.forEach((a, idx) => {
33
+ const num = String(idx + 1).padStart(2, '0');
34
+ const origin = formatOrigin(a);
35
+ const age = a.status === 'sleeping'
36
+ ? `${formatRelativeAge(a.createdAt)} · quiet`
37
+ : formatRelativeAge(a.createdAt);
38
+
39
+ const colNum = ` ${num} `;
40
+ const colTitle = padToWidth(a.title, 42);
41
+ const colOrigin = padToWidth(origin, 22);
68
42
 
69
- console.log(' Use `anchor done <id>` to complete.\n');
43
+ console.log(`${colNum}${colTitle} ${colOrigin} ${age}`);
44
+ });
45
+
46
+ console.log('\n Run `anchor done <num>` to tear off, or `anchor undo` to put back.\n');
70
47
  process.exit(0);
71
48
  }
72
49
 
73
- // 2. Undo settlement: `anchor undo`
50
+ // 2. Put back last torn-off note: `anchor undo`
74
51
  if (args[0] === 'undo') {
75
52
  try {
76
53
  const restored = store.undoSettle();
77
- console.log(`⌖ Restored #${restored.id}: "${restored.title}"`);
54
+ console.log(`⌖ Put back #${restored.id.replace(/^anc-/, '')}: "${restored.title}"`);
78
55
  } catch (err) {
79
56
  console.error(`Error: ${err.message}`);
80
57
  process.exit(1);
@@ -82,57 +59,43 @@ if (args[0] === 'undo') {
82
59
  process.exit(0);
83
60
  }
84
61
 
85
- // 3. Help: `anchor --help` or `anchor -h`
62
+ // 3. Help: `anchor --help`
86
63
  if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
87
64
  console.log(`
88
- ⌖ Anchor CLI - Cross-session task protocol for AI coding agents
65
+ ⌖ Anchor — Digital sticky notes for AI coding sessions
89
66
 
90
67
  Usage:
91
- anchor List active anchors
92
- anchor <task> Pin a new task across sessions
93
- anchor done <id> Settle and evict a task (e.g. anchor done 1)
94
- anchor undo Restore the last settled task
95
-
96
- Options:
97
- -h, --help Show this help message
98
- -v, --version Show version
99
- -d, --due <date> Specify expected completion date (e.g. tomorrow, friday, 2026-09-28)
68
+ anchor View all sticky notes
69
+ anchor "<note>" Stick a new note
70
+ anchor done <num> Tear off a completed note (e.g. anchor done 1)
71
+ anchor undo Put back the last torn-off note
100
72
  `);
101
73
  process.exit(0);
102
74
  }
103
75
 
104
- // 4. Close task: `anchor done <id>` or `anchor rm <id>`
76
+ // 4. Tear off note: `anchor done <num>`
105
77
  if (args[0] === 'done' || args[0] === 'rm' || args[0] === 'close') {
106
78
  const idInput = args[1];
107
79
  if (!idInput) {
108
- console.error('Usage: anchor done <id>');
80
+ console.error('Usage: anchor done <num>');
109
81
  process.exit(1);
110
82
  }
111
83
  try {
112
- // 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
- ];
84
+ const allNotes = store
85
+ .list({ cwd: process.cwd(), all: true })
86
+ .filter(a => a.status === 'active' || a.status === 'sleeping');
87
+ const sorted = sortAnchorsForDisplay(allNotes, process.cwd());
121
88
 
122
89
  let targetId = idInput;
123
- const numMatch = idInput.match(/^\d+$/);
124
- if (numMatch) {
90
+ if (/^\d+$/.test(idInput)) {
125
91
  const seqIndex = parseInt(idInput, 10);
126
- if (seqIndex >= 1 && seqIndex <= sortedActive.length) {
127
- targetId = sortedActive[seqIndex - 1].id;
92
+ if (seqIndex >= 1 && seqIndex <= sorted.length) {
93
+ targetId = sorted[seqIndex - 1].id;
128
94
  }
129
95
  }
130
96
 
131
- const settled = store.settle(targetId, { settledBy: 'manual-command' });
132
- const successMsg = settled.recurrence === 'daily'
133
- ? `⌖ Completed for today: "${settled.title}" (resets tomorrow)`
134
- : `⌖ Settled: "${settled.title}"`;
135
- console.log(successMsg);
97
+ const settled = store.settle(targetId, { settledBy: 'manual' });
98
+ console.log(`⌖ Torn off: "${settled.title}"`);
136
99
  } catch (err) {
137
100
  console.error(`Error: ${err.message}`);
138
101
  process.exit(1);
@@ -140,24 +103,15 @@ if (args[0] === 'done' || args[0] === 'rm' || args[0] === 'close') {
140
103
  process.exit(0);
141
104
  }
142
105
 
143
- // 5. Pin new task: `anchor <task description> [--due <date>]`
144
- let targetDateFlag;
145
- const dueIdx = args.findIndex(a => a === '--due' || a === '-d');
146
- if (dueIdx !== -1 && args[dueIdx + 1]) {
147
- targetDateFlag = args[dueIdx + 1];
148
- args.splice(dueIdx, 2);
149
- }
150
-
106
+ // 5. Stick a new note: `anchor <note text>`
151
107
  const title = args.join(' ').trim();
152
108
  if (!title) {
153
- console.error('Error: task description cannot be empty.');
109
+ console.error('Error: Note text cannot be empty');
154
110
  process.exit(1);
155
111
  }
156
112
 
157
- const anc = store.create({
113
+ const created = store.create({
158
114
  title,
159
- targetDate: targetDateFlag,
160
115
  cwd: process.cwd()
161
116
  });
162
- const targetBadge = anc.targetDate ? ` · ${formatTargetDate(anc)}` : '';
163
- console.log(`⌖ Pinned #${anc.id}: "${anc.title}" [${anc.project}]${targetBadge}`);
117
+ console.log(`⌖ Pinned #${created.id.replace(/^anc-/, '')}: "${created.title}"`);