pi-anchor 0.4.0 → 0.5.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 +35 -34
- package/README_zh.md +33 -37
- package/assets/hero-en.svg +47 -30
- package/assets/hero-zh.svg +45 -28
- package/bin/anchor.js +39 -8
- package/dist/{chunk-LKY6WIKH.js → chunk-VXEQDTK4.js} +270 -60
- package/dist/{extension-B1-fzCox.d.cts → extension-Cq1NH1jT.d.cts} +42 -4
- package/dist/{extension-B1-fzCox.d.ts → extension-Cq1NH1jT.d.ts} +42 -4
- package/dist/extension.cjs +269 -60
- package/dist/extension.d.cts +1 -1
- package/dist/extension.d.ts +1 -1
- package/dist/extension.js +3 -1
- package/dist/index.cjs +156 -30
- package/dist/index.d.cts +15 -10
- package/dist/index.d.ts +15 -10
- package/dist/index.js +7 -1
- package/package.json +2 -2
- package/src/extension.ts +169 -42
- package/src/pi-types.d.ts +5 -1
- package/src/store.ts +93 -5
- package/src/tui.ts +89 -35
- package/src/types.ts +14 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# ⌖ Anchor
|
|
2
2
|
|
|
3
|
-
> **A digital sticky note
|
|
4
|
-
> Stick a
|
|
3
|
+
> **A digital sticky note docked below your Pi editor — with four clever touches.**
|
|
4
|
+
> Stick a note in 0ms (`pin: ...`), see it persistently below your editor (`belowEditor`, zero collision with `aboveEditor` extensions), track long tasks with micro progress bars `[■■□□ 2/4]`, jump straight back to the original conversation session (`↪`), and auto-tear off on `git commit`.
|
|
5
5
|
|
|
6
6
|
[](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml)
|
|
7
7
|
[](package.json)
|
|
8
8
|
[](tsconfig.json)
|
|
9
|
-
[](tests/store.test.ts)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
|
|
12
12
|
**English** | [简体中文](./README_zh.md)
|
|
@@ -20,53 +20,54 @@ pi install npm:pi-anchor
|
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
```text
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
03 Read external architecture notes first College/优化 · notes.md 8d ago · quiet
|
|
28
|
-
|
|
29
|
-
Run `anchor done <num>` to tear off, or `anchor undo` to put back.
|
|
23
|
+
╭─ Pi Editor ──────────────────────────────────────────────────────────────────────╮
|
|
24
|
+
│ ❯ pin: Refactor auth flow: 1. Extract interface 2. HttpOnly cookie 3. Unit tests │
|
|
25
|
+
╰──────────────────────────────────────────────────────────────────────────────────╯
|
|
26
|
+
⌖ #1 [■■□□ 2/4] Refactor auth flow ▸ Unit tests (app · auth.ts ↪)
|
|
30
27
|
```
|
|
31
28
|
|
|
32
29
|
---
|
|
33
30
|
|
|
34
|
-
## Why
|
|
31
|
+
## Why Anchor?
|
|
35
32
|
|
|
36
|
-
When you're deep in a coding session
|
|
37
|
-
-
|
|
38
|
-
-
|
|
33
|
+
When you're deep in a coding session and think *"Wait — I need to check the rate-limit fallback in `src/gateway.ts` after this"*, or when you pause a multi-day task for the night:
|
|
34
|
+
- Writing a `TODO.md` inside your repo pollutes `git status` and burns prompt tokens on every turn.
|
|
35
|
+
- Normal startup banners vanish the second you send a message, so you forget what you wrote.
|
|
39
36
|
|
|
40
|
-
**Anchor is
|
|
37
|
+
**Anchor is a real sticky note stuck right under your Pi input box (`belowEditor`)** — stored outside your repo in `~/.anchor/state.json` (4 source files, 0 dependencies), designed for **human hands first**:
|
|
41
38
|
|
|
42
|
-
### 1.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/pin Switch session token to HttpOnly cookie in src/auth.ts
|
|
46
|
-
```
|
|
47
|
-
Anchor spots `src/auth.ts` (or any project path like `D:/College/...`) directly from your sentence — no forms or tags to fill out. Next time you open Pi in that project, a quiet card sits above your editor (`⌖ 1 note`) and disappears the moment you start typing.
|
|
39
|
+
### 1. Docked Below Your Editor & 0ms Instant Stick (`pin: ...`)
|
|
40
|
+
- **Zero Widget Collision**: Anchor docks its 1-line strip **below** your editor (`placement: "belowEditor"`), leaving the space above your editor (`aboveEditor`) 100% free for tools like `pi-lingual`.
|
|
41
|
+
- **0ms Human Input**: Type `pin: Check token expiry` (or `note: ...`, `便签: ...`, `/pin ...`) directly in the editor. Anchor intercepts it in **0.00ms** without triggering an LLM call or burning tokens, and automatically links the file you were just editing.
|
|
48
42
|
|
|
49
|
-
### 2.
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
### 2. Micro Progress Bar for Long Tasks (`[■■□□ 2/4]`)
|
|
44
|
+
- Write a ratio (`[2/4]` or `5/30`) or numbered steps (`1. Extract interface 2. HttpOnly cookie 3. Unit tests`) in your note:
|
|
45
|
+
```text
|
|
46
|
+
/pin Refactor auth flow: 1. Extract interface 2. HttpOnly cookie 3. Unit tests
|
|
47
|
+
```
|
|
48
|
+
- Anchor renders a crisp micro progress bar (`[■■□□ 2/3] ▸ Unit tests`) right on the sticky strip. Run `/step 1` (or select `▶ Advance step` in `/anchor`) to tick it forward. Simple one-off notes stay 100% bar-free.
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
### 3. Conversation Session Bookmark (`↪ Jump to session`)
|
|
51
|
+
- Every sticky note automatically bookmarks the Pi conversation session (`sessionFile`) where it was created or last worked on.
|
|
52
|
+
- Days later, open `/anchor` and pick **`↪ Jump to session`** (or run `/anchor jump 1`) to teleport Pi straight back into that exact conversation history.
|
|
54
53
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
### 4. File Whisper & Auto-Tear on `git commit`
|
|
55
|
+
- **1-Line File Whisper (0 Idle Tokens)**: Briefs the AI once on Turn 1, then consumes **0 tokens** on Turn 2+. When the AI reads or edits a matching file, Anchor slips a 1-line comment (`// ⌖ Note #1: ...`) onto that file result (strictly skipping `.json` and `.env`).
|
|
56
|
+
- **Auto-Tear on Commit**: When `git commit -m "..."` matches your note, Anchor tears the note off automatically (`⌖ Auto-torn off #1`). Run `/anchor undo` anytime to put it back.
|
|
58
57
|
|
|
59
58
|
---
|
|
60
59
|
|
|
61
60
|
## Commands
|
|
62
61
|
|
|
63
|
-
| Where | Command | What It Does |
|
|
62
|
+
| Where | Input / Command | What It Does |
|
|
64
63
|
| :--- | :--- | :--- |
|
|
65
|
-
| **
|
|
66
|
-
| **
|
|
67
|
-
| **
|
|
68
|
-
| **
|
|
69
|
-
| **
|
|
64
|
+
| **Pi Editor** | `pin: <note>` or `便签: <note>` | Stick a note in **0ms** without calling the LLM |
|
|
65
|
+
| **Pi Slash** | `/pin <note>` | Stick a note (supports `[1/4]` or `1. A 2. B` steps) |
|
|
66
|
+
| **Pi Slash** | `/anchor` | Open interactive board (tear off, `+1` step, or `↪` jump to session) |
|
|
67
|
+
| **Pi Slash** | `/step 1` | Advance progress bar on note `#1` by `+1` |
|
|
68
|
+
| **Pi Slash** | `/anchor jump 1` | Switch Pi back to the conversation session linked to note `#1` |
|
|
69
|
+
| **Pi Slash** | `/done 1` / `/anchor undo` | Tear off note `#1`, or put back the last torn-off note |
|
|
70
|
+
| **Terminal CLI** | `anchor` / `anchor step 1` / `anchor done 1` | View, step, or tear off notes outside Pi |
|
|
70
71
|
|
|
71
72
|
---
|
|
72
73
|
|
package/README_zh.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# ⌖ Anchor
|
|
2
2
|
|
|
3
|
-
> **贴在 Pi
|
|
4
|
-
>
|
|
3
|
+
> **贴在 Pi 输入框正下方的电子便签 —— 专为顺手盲打与跨会话续传设计。**
|
|
4
|
+
> 敲 `便签: ...` 0ms 瞬贴上屏,在输入框**正下方 (`belowEditor`)** 常驻 1 行极简便签条(与上方 `pi-lingual` 零冲突),支持长线任务**迷你进度条 `[■■□□ 2/4]`**、**一键穿越回当时的对话上下文 (`↪`)**,以及 **`git commit` 自动撕便签**。
|
|
5
5
|
|
|
6
6
|
[](https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml)
|
|
7
7
|
[](package.json)
|
|
8
8
|
[](tsconfig.json)
|
|
9
|
-
[](tests/store.test.ts)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
|
|
12
12
|
[English](./README.md) | **简体中文**
|
|
@@ -20,53 +20,49 @@ pi install npm:pi-anchor
|
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
```text
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
03 College 重构前置查阅外部架构参考库 College/优化 · notes.md 8d ago · quiet
|
|
28
|
-
|
|
29
|
-
Run `anchor done <num>` to tear off, or `anchor undo` to put back.
|
|
23
|
+
╭─ Pi 输入框 ──────────────────────────────────────────────────────────────────────╮
|
|
24
|
+
│ ❯ 便签: 重构登录鉴权流: 1. 抽出接口 2. 替换Cookie 3. 补单测 4. 压测 │
|
|
25
|
+
╰──────────────────────────────────────────────────────────────────────────────────╯
|
|
26
|
+
⌖ #1 [■■□□ 2/4] 重构登录鉴权流 ▸ 补单测 (app · auth.ts ↪)
|
|
30
27
|
```
|
|
31
28
|
|
|
32
29
|
---
|
|
33
30
|
|
|
34
|
-
##
|
|
35
|
-
|
|
36
|
-
深夜写代码准备关机时,你突然想到 *“明天得把 `src/auth.ts` 里的 Token 改成 Cookie”*。这时候你不需要一套沉重的项目管理系统:
|
|
37
|
-
- 往仓库里塞 `TODO.md` 会弄脏 `git status`,而且每一轮对话都在白白消耗上下文 Token;
|
|
38
|
-
- 直接关掉终端,AI 的内存记忆瞬间清空。
|
|
31
|
+
## 为什么这次真正顺手了?(四大巧思)
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```text
|
|
45
|
-
/pin 把 src/auth.ts 的登录改用 HttpOnly Cookie
|
|
46
|
-
```
|
|
47
|
-
Anchor 会自动从这句话里认出文件名 `src/auth.ts`(或诸如 `D:/College/...` 的目录路径),自动绑定到对应工程。下次打开终端时,输入框上方安静浮现小便签(`⌖ 1 note`),你一开始打字它就自动收起,绝不挡视线。
|
|
33
|
+
### 1. 输入框正下方常驻 1 行便签条 (`belowEditor`) + 0ms 瞬贴
|
|
34
|
+
* **绝不跟上方插件抢地盘**:便签条挂载在输入框**正下方 (`belowEditor`)**,把输入框上方 (`aboveEditor`) 完全留给 `pi-lingual` 等高频伴学卡片,上下分工井然有序。
|
|
35
|
+
* **真·便签常驻视野**:有便签时在输入框下沿安静显示 1 行,不再像以前那样“刚发第一句话就神秘消失”;无便签时 0 行完全隐形。
|
|
36
|
+
* **自己随手写,0ms 上屏**:直接在输入框敲 `便签: 明天检查网关重试`(或 `pin: ...`、`/pin ...`),**0.00ms 当场拦截贴上便签条**,不用苦等大模型转圈调工具,不花 1 个 Token,还会自动关联你当前正在改的代码文件。
|
|
48
37
|
|
|
49
|
-
### 2.
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
### 2. 长线任务迷你进度条 (`[■■□□ 2/4]`)
|
|
39
|
+
* 遇到跨天或分步任务,随手在便签里写上进度比(如 `[5/30]`)或分步序号(`1. 抽出接口 2. 替换Cookie 3. 补单测`):
|
|
40
|
+
```text
|
|
41
|
+
便签: 重构登录鉴权流: 1. 抽出接口 2. 替换Cookie 3. 补单测
|
|
42
|
+
```
|
|
43
|
+
* 便签条会自动渲染出 4 格迷你进度条与下一步提示:`[■■□□ 2/3] ▸ 补单测`。敲 `/step 1`(或在 `/anchor` 菜单里点 `▶ Advance step`)即可推进一格;普通单句备忘则保持纯粹文字,绝不画蛇添足。
|
|
52
44
|
|
|
53
|
-
|
|
45
|
+
### 3. 绑定原对话 Session,一键穿越回去 (`↪ Jump to session`)
|
|
46
|
+
* 贴便签或修改关联代码时,Anchor 会自动记录当前对话的 `sessionFile` 书签(显示 `↪` 标记)。
|
|
47
|
+
* 哪怕过了好几天、开了十几个新窗口,当你看到便签想接着干时,打开 `/anchor` 选中它点击 **`↪ Jump to session`**(或敲 `/anchor jump 1`),Pi 就会**直接切换回当时那场对话的完整上下文**!
|
|
54
48
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
### 4. 碰文件顺手递纸条 & `git commit` 自动撕便签
|
|
50
|
+
* **碰文件递纸条(平时 0 Token)**:首轮对话简要提醒,第 2 轮起 **0 Token**;当 AI 读取或修改关联文件时,在文件结果末尾顺手附带 1 行语法安全注释(`// ⌖ Note #1: ...`,严格跳过 `.json`/`.env`)。
|
|
51
|
+
* **提交代码自动撕下**:执行 `git commit -m "..."` 命中便签内容时,当场自动撕下归档;撕错了敲 `/anchor undo` 一秒贴回。
|
|
58
52
|
|
|
59
53
|
---
|
|
60
54
|
|
|
61
|
-
##
|
|
55
|
+
## 常用操作速查
|
|
62
56
|
|
|
63
|
-
|
|
|
57
|
+
| 位置 | 输入 / 命令 | 作用 |
|
|
64
58
|
| :--- | :--- | :--- |
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
59
|
+
| **输入框直接敲** | `便签: <内容>` 或 `pin: <内容>` | **0ms 直接贴便签**(不触发大模型请求,自动绑定当前改过的文件与 Session) |
|
|
60
|
+
| **斜杠命令** | `/pin <内容>` | 贴一张新便签(支持写 `[2/5]` 或 `1. A 2. B` 自动生成进度条) |
|
|
61
|
+
| **斜杠命令** | `/anchor` | 打开交互面板(支持撕便签、推进度 `+1`、`↪` 穿越回原对话 Session) |
|
|
62
|
+
| **斜杠命令** | `/step 1` | 将 `#1` 便签的进度条往前推进 `+1` 步 |
|
|
63
|
+
| **斜杠命令** | `/anchor jump 1` | 直接切换回 `#1` 便签绑定的那次历史对话 (`switchSession`) |
|
|
64
|
+
| **斜杠命令** | `/done 1` / `/anchor undo` | 撕掉 `#1` 便签,或把刚撕掉的便签重新贴回来 |
|
|
65
|
+
| **终端 CLI** | `anchor` / `anchor step 1` / `anchor done 1` | 不进 Pi 也能在外部终端查看、推进度或撕便签 |
|
|
70
66
|
|
|
71
67
|
---
|
|
72
68
|
|
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 410" width="840" height="410">
|
|
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" />
|
|
@@ -10,62 +10,79 @@
|
|
|
10
10
|
</defs>
|
|
11
11
|
|
|
12
12
|
<g filter="url(#shadow)">
|
|
13
|
-
<rect x="20" y="15" width="800" height="
|
|
13
|
+
<rect x="20" y="15" width="800" height="370" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
|
|
14
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" />
|
|
15
15
|
<line x1="20" y1="52" x2="820" y2="52" stroke="#2d353b" stroke-width="1" />
|
|
16
16
|
<circle cx="42" cy="33.5" r="5.5" fill="#e67e80" />
|
|
17
17
|
<circle cx="60" cy="33.5" r="5.5" fill="#dbbc7f" />
|
|
18
18
|
<circle cx="78" cy="33.5" r="5.5" fill="#a7c080" />
|
|
19
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 ·
|
|
20
|
+
⌖ anchor (v0.5.0) · Below-Editor Sticky Strip · Progress Bar · Session Teleport
|
|
21
21
|
</text>
|
|
22
22
|
</g>
|
|
23
23
|
|
|
24
24
|
<g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
|
|
25
|
-
<text x="45" y="
|
|
26
|
-
<tspan fill="#a7c080" font-weight="bold">~/Workspace/app</tspan>
|
|
27
|
-
<tspan fill="#7fbbb3"> ❯ </tspan>
|
|
28
|
-
<tspan fill="#d3c6aa" font-weight="bold">anchor</tspan>
|
|
29
|
-
</text>
|
|
30
|
-
|
|
31
|
-
<text x="45" y="120">
|
|
25
|
+
<text x="45" y="84">
|
|
32
26
|
<tspan fill="#7fbbb3" font-weight="bold">⌖ Notes (3):</tspan>
|
|
33
27
|
</text>
|
|
34
28
|
|
|
35
|
-
<text x="45" y="
|
|
29
|
+
<text x="45" y="116">
|
|
36
30
|
<tspan fill="#859289"> 01 </tspan>
|
|
37
|
-
<tspan fill="#
|
|
38
|
-
<tspan fill="#
|
|
31
|
+
<tspan fill="#a7c080" font-weight="bold">[■■□□ 2/4] </tspan>
|
|
32
|
+
<tspan fill="#d3c6aa">Refactor auth flow </tspan>
|
|
33
|
+
<tspan fill="#7fbbb3">app · auth.ts ↪ </tspan>
|
|
39
34
|
<tspan fill="#7a8478">25m ago</tspan>
|
|
40
35
|
</text>
|
|
41
36
|
|
|
42
|
-
<text x="45" y="
|
|
37
|
+
<text x="45" y="144">
|
|
43
38
|
<tspan fill="#859289"> 02 </tspan>
|
|
44
|
-
<tspan fill="#d3c6aa">Double-check rate limit fallback on timeout
|
|
45
|
-
<tspan fill="#7fbbb3">app · gateway.ts
|
|
39
|
+
<tspan fill="#d3c6aa">Double-check rate limit fallback on timeout </tspan>
|
|
40
|
+
<tspan fill="#7fbbb3">app · gateway.ts ↪ </tspan>
|
|
46
41
|
<tspan fill="#7a8478">3h ago</tspan>
|
|
47
42
|
</text>
|
|
48
43
|
|
|
49
|
-
<text x="45" y="
|
|
44
|
+
<text x="45" y="172">
|
|
50
45
|
<tspan fill="#859289"> 03 </tspan>
|
|
51
|
-
<tspan fill="#859289">Read external architecture notes first
|
|
46
|
+
<tspan fill="#859289">Read external architecture notes first </tspan>
|
|
52
47
|
<tspan fill="#7a8478">College/优化 · notes.md </tspan>
|
|
53
48
|
<tspan fill="#56635f">8d ago · quiet</tspan>
|
|
54
49
|
</text>
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
<text x="62" y="
|
|
51
|
+
<!-- Simulated Pi Input Box + Below-Editor Persistent Sticky Strip -->
|
|
52
|
+
<rect x="45" y="204" width="750" height="44" rx="6" fill="#232a2e" stroke="#4f5b58" stroke-width="1.2" />
|
|
53
|
+
<text x="62" y="231">
|
|
54
|
+
<tspan fill="#a7c080" font-weight="bold">❯ </tspan>
|
|
55
|
+
<tspan fill="#d3c6aa">pin: Refactor auth flow: 1. Extract interface 2. HttpOnly cookie 3. Unit tests</tspan>
|
|
56
|
+
</text>
|
|
57
|
+
|
|
58
|
+
<!-- Below-Editor Sticky Strip -->
|
|
59
|
+
<rect x="45" y="256" width="750" height="36" rx="6" fill="#292b28" stroke="#a7c080" stroke-width="1" stroke-dasharray="4,3" />
|
|
60
|
+
<text x="62" y="279">
|
|
61
|
+
<tspan fill="#a7c080" font-weight="bold">⌖ </tspan>
|
|
62
|
+
<tspan fill="#859289">#1 </tspan>
|
|
63
|
+
<tspan fill="#dbbc7f" font-weight="bold">[■■□□ 2/4] </tspan>
|
|
64
|
+
<tspan fill="#d3c6aa">Refactor auth flow </tspan>
|
|
65
|
+
<tspan fill="#7fbbb3">▸ HttpOnly cookie </tspan>
|
|
66
|
+
<tspan fill="#859289">(app · auth.ts ↪)</tspan>
|
|
67
|
+
</text>
|
|
59
68
|
|
|
60
|
-
<text x="45" y="
|
|
61
|
-
<tspan>
|
|
62
|
-
<tspan fill="#
|
|
63
|
-
<tspan
|
|
64
|
-
<tspan fill="#7fbbb3"
|
|
65
|
-
<tspan>
|
|
66
|
-
<tspan fill="#7fbbb3"
|
|
67
|
-
<tspan>
|
|
68
|
-
|
|
69
|
+
<text x="45" y="324" fill="#859289">
|
|
70
|
+
<tspan> • </tspan>
|
|
71
|
+
<tspan fill="#d3c6aa" font-weight="bold">0ms Instant Stick</tspan>
|
|
72
|
+
<tspan>: Type </tspan>
|
|
73
|
+
<tspan fill="#7fbbb3">`pin: <note>`</tspan>
|
|
74
|
+
<tspan> (or </tspan>
|
|
75
|
+
<tspan fill="#7fbbb3">`/pin`</tspan>
|
|
76
|
+
<tspan>) — docked below editor, never collides with aboveEditor HUDs.</tspan>
|
|
77
|
+
</text>
|
|
78
|
+
<text x="45" y="348" fill="#859289">
|
|
79
|
+
<tspan> • </tspan>
|
|
80
|
+
<tspan fill="#d3c6aa" font-weight="bold">Session Teleport (↪)</tspan>
|
|
81
|
+
<tspan>: Select any note in </tspan>
|
|
82
|
+
<tspan fill="#7fbbb3">`/anchor`</tspan>
|
|
83
|
+
<tspan> or run </tspan>
|
|
84
|
+
<tspan fill="#7fbbb3">`/anchor jump 1`</tspan>
|
|
85
|
+
<tspan> to resume its conversation.</tspan>
|
|
69
86
|
</text>
|
|
70
87
|
</g>
|
|
71
88
|
</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 410" width="840" height="410">
|
|
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" />
|
|
@@ -10,62 +10,79 @@
|
|
|
10
10
|
</defs>
|
|
11
11
|
|
|
12
12
|
<g filter="url(#shadow)">
|
|
13
|
-
<rect x="20" y="15" width="800" height="
|
|
13
|
+
<rect x="20" y="15" width="800" height="370" rx="12" fill="#1e2326" stroke="#343f44" stroke-width="1.2" />
|
|
14
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" />
|
|
15
15
|
<line x1="20" y1="52" x2="820" y2="52" stroke="#2d353b" stroke-width="1" />
|
|
16
16
|
<circle cx="42" cy="33.5" r="5.5" fill="#e67e80" />
|
|
17
17
|
<circle cx="60" cy="33.5" r="5.5" fill="#dbbc7f" />
|
|
18
18
|
<circle cx="78" cy="33.5" r="5.5" fill="#a7c080" />
|
|
19
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 ·
|
|
20
|
+
⌖ anchor (v0.5.0) · 输入框下方常驻便签条 · 迷你进度条 · 原对话一键穿越
|
|
21
21
|
</text>
|
|
22
22
|
</g>
|
|
23
23
|
|
|
24
24
|
<g font-family="'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace" font-size="13" xml:space="preserve">
|
|
25
|
-
<text x="45" y="
|
|
26
|
-
<tspan fill="#a7c080" font-weight="bold">~/Workspace/app</tspan>
|
|
27
|
-
<tspan fill="#7fbbb3"> ❯ </tspan>
|
|
28
|
-
<tspan fill="#d3c6aa" font-weight="bold">anchor</tspan>
|
|
29
|
-
</text>
|
|
30
|
-
|
|
31
|
-
<text x="45" y="120">
|
|
25
|
+
<text x="45" y="84">
|
|
32
26
|
<tspan fill="#7fbbb3" font-weight="bold">⌖ Notes (3):</tspan>
|
|
33
27
|
</text>
|
|
34
28
|
|
|
35
|
-
<text x="45" y="
|
|
29
|
+
<text x="45" y="116">
|
|
36
30
|
<tspan fill="#859289"> 01 </tspan>
|
|
37
|
-
<tspan fill="#
|
|
38
|
-
<tspan fill="#
|
|
31
|
+
<tspan fill="#a7c080" font-weight="bold">[■■□□ 2/4] </tspan>
|
|
32
|
+
<tspan fill="#d3c6aa">重构登录鉴权流 </tspan>
|
|
33
|
+
<tspan fill="#7fbbb3">app · auth.ts ↪ </tspan>
|
|
39
34
|
<tspan fill="#7a8478">25m ago</tspan>
|
|
40
35
|
</text>
|
|
41
36
|
|
|
42
|
-
<text x="45" y="
|
|
37
|
+
<text x="45" y="144">
|
|
43
38
|
<tspan fill="#859289"> 02 </tspan>
|
|
44
39
|
<tspan fill="#d3c6aa">检查网关超时后的降级重试边界 </tspan>
|
|
45
|
-
<tspan fill="#7fbbb3">app · gateway.ts
|
|
40
|
+
<tspan fill="#7fbbb3">app · gateway.ts ↪ </tspan>
|
|
46
41
|
<tspan fill="#7a8478">3h ago</tspan>
|
|
47
42
|
</text>
|
|
48
43
|
|
|
49
|
-
<text x="45" y="
|
|
44
|
+
<text x="45" y="172">
|
|
50
45
|
<tspan fill="#859289"> 03 </tspan>
|
|
51
46
|
<tspan fill="#859289">College 重构前置查阅外部架构参考库 </tspan>
|
|
52
47
|
<tspan fill="#7a8478">College/优化 · notes.md </tspan>
|
|
53
48
|
<tspan fill="#56635f">8d ago · quiet</tspan>
|
|
54
49
|
</text>
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
<text x="62" y="
|
|
51
|
+
<!-- Simulated Pi Input Box + Below-Editor Persistent Sticky Strip -->
|
|
52
|
+
<rect x="45" y="204" width="750" height="44" rx="6" fill="#232a2e" stroke="#4f5b58" stroke-width="1.2" />
|
|
53
|
+
<text x="62" y="231">
|
|
54
|
+
<tspan fill="#a7c080" font-weight="bold">❯ </tspan>
|
|
55
|
+
<tspan fill="#d3c6aa">便签: 重构登录鉴权流: 1. 抽出接口 2. 替换Cookie 3. 补单测 4. 压测</tspan>
|
|
56
|
+
</text>
|
|
57
|
+
|
|
58
|
+
<!-- Below-Editor Sticky Strip -->
|
|
59
|
+
<rect x="45" y="256" width="750" height="36" rx="6" fill="#292b28" stroke="#a7c080" stroke-width="1" stroke-dasharray="4,3" />
|
|
60
|
+
<text x="62" y="279">
|
|
61
|
+
<tspan fill="#a7c080" font-weight="bold">⌖ </tspan>
|
|
62
|
+
<tspan fill="#859289">#1 </tspan>
|
|
63
|
+
<tspan fill="#dbbc7f" font-weight="bold">[■■□□ 2/4] </tspan>
|
|
64
|
+
<tspan fill="#d3c6aa">重构登录鉴权流 </tspan>
|
|
65
|
+
<tspan fill="#7fbbb3">▸ 补单测 </tspan>
|
|
66
|
+
<tspan fill="#859289">(app · auth.ts ↪)</tspan>
|
|
67
|
+
</text>
|
|
59
68
|
|
|
60
|
-
<text x="45" y="
|
|
61
|
-
<tspan>
|
|
62
|
-
<tspan fill="#
|
|
63
|
-
<tspan
|
|
64
|
-
<tspan fill="#7fbbb3"
|
|
65
|
-
<tspan>
|
|
66
|
-
<tspan fill="#7fbbb3"
|
|
67
|
-
<tspan>
|
|
68
|
-
<tspan fill="#7fbbb3"
|
|
69
|
+
<text x="45" y="324" fill="#859289">
|
|
70
|
+
<tspan> • </tspan>
|
|
71
|
+
<tspan fill="#d3c6aa" font-weight="bold">输入框下方常驻 1 行便签条</tspan>
|
|
72
|
+
<tspan>:采用 </tspan>
|
|
73
|
+
<tspan fill="#7fbbb3">belowEditor</tspan>
|
|
74
|
+
<tspan> 挂载,与上方 </tspan>
|
|
75
|
+
<tspan fill="#7fbbb3">pi-lingual</tspan>
|
|
76
|
+
<tspan> 零冲突;敲 </tspan>
|
|
77
|
+
<tspan fill="#7fbbb3">便签: ...</tspan>
|
|
78
|
+
<tspan> 0ms 瞬贴。</tspan>
|
|
79
|
+
</text>
|
|
80
|
+
<text x="45" y="348" fill="#859289">
|
|
81
|
+
<tspan> • </tspan>
|
|
82
|
+
<tspan fill="#d3c6aa" font-weight="bold">原对话一键穿越 (↪)</tspan>
|
|
83
|
+
<tspan>:自动记录贴便签时的 Session,在 </tspan>
|
|
84
|
+
<tspan fill="#7fbbb3">/anchor</tspan>
|
|
85
|
+
<tspan> 中点击即可直接切回当时的对话上下文。</tspan>
|
|
69
86
|
</text>
|
|
70
87
|
</g>
|
|
71
88
|
</svg>
|
package/bin/anchor.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import {
|
|
8
8
|
AnchorStore,
|
|
9
9
|
formatOrigin,
|
|
10
|
+
formatProgressBar,
|
|
10
11
|
formatRelativeAge,
|
|
11
12
|
sortAnchorsForDisplay,
|
|
12
13
|
padToWidth
|
|
@@ -31,19 +32,20 @@ if (args.length === 0 || args[0] === 'list' || args[0] === 'ls') {
|
|
|
31
32
|
|
|
32
33
|
sorted.forEach((a, idx) => {
|
|
33
34
|
const num = String(idx + 1).padStart(2, '0');
|
|
34
|
-
const
|
|
35
|
+
const bar = a.progress ? `${formatProgressBar(a.progress)} ` : '';
|
|
36
|
+
const origin = formatOrigin(a) + (a.sessionFile ? ' ↪' : '');
|
|
35
37
|
const age = a.status === 'sleeping'
|
|
36
38
|
? `${formatRelativeAge(a.createdAt)} · quiet`
|
|
37
39
|
: formatRelativeAge(a.createdAt);
|
|
38
40
|
|
|
39
41
|
const colNum = ` ${num} `;
|
|
40
|
-
const colTitle = padToWidth(a.title
|
|
42
|
+
const colTitle = padToWidth(`${bar}${a.title}`, 42);
|
|
41
43
|
const colOrigin = padToWidth(origin, 22);
|
|
42
44
|
|
|
43
45
|
console.log(`${colNum}${colTitle} ${colOrigin} ${age}`);
|
|
44
46
|
});
|
|
45
47
|
|
|
46
|
-
console.log('\n Run `anchor done <num>`
|
|
48
|
+
console.log('\n Run `anchor step <num>` (+1 step), `anchor done <num>` (tear off), or `anchor undo`.\n');
|
|
47
49
|
process.exit(0);
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -59,21 +61,49 @@ if (args[0] === 'undo') {
|
|
|
59
61
|
process.exit(0);
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
// 3.
|
|
64
|
+
// 3. Advance progress bar: `anchor step <num>`
|
|
65
|
+
if (args[0] === 'step' || args[0] === '+') {
|
|
66
|
+
const idInput = args[1] || '1';
|
|
67
|
+
const delta = args[2] ? parseInt(args[2], 10) : 1;
|
|
68
|
+
try {
|
|
69
|
+
const allNotes = store
|
|
70
|
+
.list({ cwd: process.cwd(), all: true })
|
|
71
|
+
.filter(a => a.status === 'active' || a.status === 'sleeping');
|
|
72
|
+
const sorted = sortAnchorsForDisplay(allNotes, process.cwd());
|
|
73
|
+
|
|
74
|
+
let targetId = idInput;
|
|
75
|
+
if (/^\d+$/.test(idInput)) {
|
|
76
|
+
const seqIndex = parseInt(idInput, 10);
|
|
77
|
+
if (seqIndex >= 1 && seqIndex <= sorted.length) {
|
|
78
|
+
targetId = sorted[seqIndex - 1].id;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { anchor: updated } = store.step(targetId, isNaN(delta) ? 1 : delta);
|
|
83
|
+
console.log(`⌖ Advanced #${updated.id.replace(/^anc-/, '')} to ${formatProgressBar(updated.progress)}: "${updated.title}"`);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.error(`Error: ${err.message}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 4. Help: `anchor --help`
|
|
63
92
|
if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
64
93
|
console.log(`
|
|
65
94
|
⌖ Anchor — Digital sticky notes for AI coding sessions
|
|
66
95
|
|
|
67
96
|
Usage:
|
|
68
97
|
anchor View all sticky notes
|
|
69
|
-
anchor "<note>" Stick a new note
|
|
98
|
+
anchor "<note>" Stick a new note (supports [1/4] or 1. A 2. B progress steps)
|
|
99
|
+
anchor step <num> Advance progress bar on a note (e.g. anchor step 1)
|
|
70
100
|
anchor done <num> Tear off a completed note (e.g. anchor done 1)
|
|
71
101
|
anchor undo Put back the last torn-off note
|
|
72
102
|
`);
|
|
73
103
|
process.exit(0);
|
|
74
104
|
}
|
|
75
105
|
|
|
76
|
-
//
|
|
106
|
+
// 5. Tear off note: `anchor done <num>`
|
|
77
107
|
if (args[0] === 'done' || args[0] === 'rm' || args[0] === 'close') {
|
|
78
108
|
const idInput = args[1];
|
|
79
109
|
if (!idInput) {
|
|
@@ -103,7 +133,7 @@ if (args[0] === 'done' || args[0] === 'rm' || args[0] === 'close') {
|
|
|
103
133
|
process.exit(0);
|
|
104
134
|
}
|
|
105
135
|
|
|
106
|
-
//
|
|
136
|
+
// 6. Stick a new note: `anchor <note text>`
|
|
107
137
|
const title = args.join(' ').trim();
|
|
108
138
|
if (!title) {
|
|
109
139
|
console.error('Error: Note text cannot be empty');
|
|
@@ -114,4 +144,5 @@ const created = store.create({
|
|
|
114
144
|
title,
|
|
115
145
|
cwd: process.cwd()
|
|
116
146
|
});
|
|
117
|
-
|
|
147
|
+
const bar = created.progress ? ` ${formatProgressBar(created.progress)}` : '';
|
|
148
|
+
console.log(`⌖ Pinned #${created.id.replace(/^anc-/, '')}${bar}: "${created.title}"`);
|