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.
- package/README.md +33 -166
- package/README_zh.md +32 -172
- package/assets/hero-en.svg +33 -70
- package/assets/hero-zh.svg +33 -70
- package/bin/anchor.js +49 -95
- package/dist/chunk-LKY6WIKH.js +1100 -0
- package/dist/extension-B1-fzCox.d.cts +167 -0
- package/dist/extension-B1-fzCox.d.ts +167 -0
- package/dist/extension.cjs +428 -1240
- package/dist/extension.d.cts +2 -20
- package/dist/extension.d.ts +2 -20
- package/dist/extension.js +4 -518
- package/dist/index.cjs +370 -1070
- package/dist/index.d.cts +17 -223
- package/dist/index.d.ts +17 -223
- package/dist/index.js +21 -101
- package/package.json +2 -2
- package/src/extension.ts +142 -356
- package/src/index.ts +1 -6
- package/src/store.ts +308 -422
- package/src/tui.ts +112 -259
- package/src/types.ts +24 -65
- package/dist/chunk-G72UHPBN.js +0 -1441
- package/dist/store-BNKjzhS_.d.cts +0 -209
- package/dist/store-BNKjzhS_.d.ts +0 -209
- package/src/context_injector.ts +0 -166
- package/src/decay.ts +0 -125
- package/src/matcher.ts +0 -151
- package/src/observer.ts +0 -141
- package/src/protocol.ts +0 -95
- package/src/settlement.ts +0 -74
package/assets/hero-en.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840
|
|
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="
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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="#
|
|
53
|
-
<tspan fill="#
|
|
54
|
-
<tspan fill="#
|
|
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
|
-
|
|
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="#
|
|
66
|
-
<tspan fill="#
|
|
67
|
-
<tspan fill="#
|
|
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="
|
|
49
|
+
<text x="45" y="210">
|
|
73
50
|
<tspan fill="#859289"> 03 </tspan>
|
|
74
|
-
<tspan fill="#
|
|
75
|
-
<tspan fill="#
|
|
76
|
-
<tspan fill="#
|
|
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
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<tspan fill="#d3c6aa">Polish CLI interactive dashboard & 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 <id>`</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
|
-
|
|
98
|
-
|
|
99
|
-
<tspan fill="#
|
|
100
|
-
<tspan
|
|
101
|
-
<tspan fill="#7fbbb3"
|
|
102
|
-
<tspan
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
60
|
+
<text x="45" y="334" fill="#7a8478">
|
|
61
|
+
<tspan> Commands: </tspan>
|
|
62
|
+
<tspan fill="#7fbbb3" font-weight="bold">`/pin <note>`</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/assets/hero-zh.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 840
|
|
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="
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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="#
|
|
53
|
-
<tspan fill="#
|
|
54
|
-
<tspan fill="#
|
|
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
|
-
|
|
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="#
|
|
66
|
-
<tspan fill="#
|
|
67
|
-
<tspan fill="#
|
|
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="
|
|
49
|
+
<text x="45" y="210">
|
|
73
50
|
<tspan fill="#859289"> 03 </tspan>
|
|
74
|
-
<tspan fill="#
|
|
75
|
-
<tspan fill="#
|
|
76
|
-
<tspan fill="#
|
|
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
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
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 <id>`</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
|
-
|
|
98
|
-
|
|
99
|
-
<tspan fill="#
|
|
100
|
-
<tspan
|
|
101
|
-
<tspan fill="#7fbbb3"
|
|
102
|
-
<tspan
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
60
|
+
<text x="45" y="334" fill="#7a8478">
|
|
61
|
+
<tspan> 常用命令: </tspan>
|
|
62
|
+
<tspan fill="#7fbbb3" font-weight="bold">`/pin <便签>`</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
|
|
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
|
-
|
|
13
|
-
|
|
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
|
|
18
|
+
// 1. View sticky notes: `anchor` or `anchor list`
|
|
22
19
|
if (args.length === 0 || args[0] === 'list' || args[0] === 'ls') {
|
|
23
|
-
const
|
|
20
|
+
const allNotes = store
|
|
21
|
+
.list({ cwd: process.cwd(), all: true })
|
|
22
|
+
.filter(a => a.status === 'active' || a.status === 'sleeping');
|
|
24
23
|
|
|
25
|
-
if (
|
|
26
|
-
console.log('\n⌖ No
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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.
|
|
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(`⌖
|
|
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`
|
|
62
|
+
// 3. Help: `anchor --help`
|
|
86
63
|
if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
87
64
|
console.log(`
|
|
88
|
-
⌖ Anchor
|
|
65
|
+
⌖ Anchor — Digital sticky notes for AI coding sessions
|
|
89
66
|
|
|
90
67
|
Usage:
|
|
91
|
-
anchor
|
|
92
|
-
anchor <
|
|
93
|
-
anchor done <
|
|
94
|
-
anchor undo
|
|
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.
|
|
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 <
|
|
80
|
+
console.error('Usage: anchor done <num>');
|
|
109
81
|
process.exit(1);
|
|
110
82
|
}
|
|
111
83
|
try {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
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
|
-
|
|
124
|
-
if (numMatch) {
|
|
90
|
+
if (/^\d+$/.test(idInput)) {
|
|
125
91
|
const seqIndex = parseInt(idInput, 10);
|
|
126
|
-
if (seqIndex >= 1 && seqIndex <=
|
|
127
|
-
targetId =
|
|
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
|
|
132
|
-
|
|
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.
|
|
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:
|
|
109
|
+
console.error('Error: Note text cannot be empty');
|
|
154
110
|
process.exit(1);
|
|
155
111
|
}
|
|
156
112
|
|
|
157
|
-
const
|
|
113
|
+
const created = store.create({
|
|
158
114
|
title,
|
|
159
|
-
targetDate: targetDateFlag,
|
|
160
115
|
cwd: process.cwd()
|
|
161
116
|
});
|
|
162
|
-
|
|
163
|
-
console.log(`⌖ Pinned #${anc.id}: "${anc.title}" [${anc.project}]${targetBadge}`);
|
|
117
|
+
console.log(`⌖ Pinned #${created.id.replace(/^anc-/, '')}: "${created.title}"`);
|