pi-anchor 0.1.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/LICENSE +21 -0
- package/README.md +273 -0
- package/README_zh.md +272 -0
- package/bin/anchor.js +163 -0
- package/dist/chunk-NNYUD5O7.js +1295 -0
- package/dist/extension.cjs +1560 -0
- package/dist/extension.d.cts +5 -0
- package/dist/extension.d.ts +5 -0
- package/dist/extension.js +312 -0
- package/dist/index.cjs +1433 -0
- package/dist/index.d.cts +448 -0
- package/dist/index.d.ts +448 -0
- package/dist/index.js +144 -0
- package/package.json +64 -0
- package/src/context_injector.ts +157 -0
- package/src/decay.ts +123 -0
- package/src/extension.ts +363 -0
- package/src/index.ts +9 -0
- package/src/matcher.ts +130 -0
- package/src/observer.ts +141 -0
- package/src/pi-types.d.ts +42 -0
- package/src/protocol.ts +95 -0
- package/src/settlement.ts +72 -0
- package/src/store.ts +682 -0
- package/src/tui.ts +386 -0
- package/src/types.ts +104 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jason Song (@3ZEROS12)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# ⌖ Anchor
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Zero-Pollution, 0-Idle-Token Task Memory for AI Coding Agents.</strong><br>
|
|
5
|
+
<em>Stop cluttering your git history with stagnant TODOs. Maintain cross-session intent with 0 idle tokens and zero workspace pollution.</em>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="README_zh.md">🇨🇳 简体中文</a> •
|
|
10
|
+
<a href="#why-anchor">💡 Why Anchor?</a> •
|
|
11
|
+
<a href="#core-architecture">✨ Core Architecture</a> •
|
|
12
|
+
<a href="#interface-design">🖥️ Interface</a> •
|
|
13
|
+
<a href="#comparison">📊 Comparison</a> •
|
|
14
|
+
<a href="#quick-start">🚀 Quick Start</a> •
|
|
15
|
+
<a href="#verification--quality-assurance">🧪 Verification</a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml">
|
|
20
|
+
<img src="https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml/badge.svg" alt="CI Status">
|
|
21
|
+
</a>
|
|
22
|
+
<img src="https://img.shields.io/badge/Node-v20+-22c55e.svg" alt="Node v20+">
|
|
23
|
+
<img src="https://img.shields.io/badge/TypeScript-Strict-3b82f6.svg" alt="TypeScript Strict">
|
|
24
|
+
<img src="https://img.shields.io/badge/Tests-24%20Passed-22c55e.svg" alt="Tests: 24 Passed">
|
|
25
|
+
<img src="https://img.shields.io/badge/Startup-%3C%2090ms-success.svg" alt="Startup: < 90ms">
|
|
26
|
+
<img src="https://img.shields.io/badge/Storage-Zero%20Repo%20Pollution-success.svg" alt="Zero Repo Pollution">
|
|
27
|
+
<img src="https://img.shields.io/badge/License-MIT-f97316.svg" alt="License: MIT">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="assets/hero.svg" alt="Anchor Terminal Dashboard" width="820">
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Why Anchor?
|
|
37
|
+
|
|
38
|
+
When building software with terminal-based AI coding agents (Claude Code, Pi, Aider), developers encounter three recurring points of friction:
|
|
39
|
+
|
|
40
|
+
1. **Session Amnesia**: Pressing `Ctrl+C` terminates the agent process, clearing working memory. Unfinished refactoring plans, temporary milestones, and cross-session agreements vanish instantly.
|
|
41
|
+
2. **Context Window Pollution & Token Bloat**: Writing tasks into `TODO.md` or `AGENTS.md` creates unwanted git commit noise. Worse, **every single turn injects dozens of stagnant lines into the system prompt**, burning token budgets and diluting LLM attention on active code.
|
|
42
|
+
3. **Stale Task Debt**: Once code is committed, developers rarely reopen markdown files to check boxes manually. Incomplete task lists rot inside the repository indefinitely.
|
|
43
|
+
|
|
44
|
+
Existing alternatives introduce heavy trade-offs:
|
|
45
|
+
* `gastownhall/beads` forces a 200MB Dolt SQL relational database directly into your repository to manage issue graphs.
|
|
46
|
+
* `Gentleman-Programming/engram` runs a persistent background Go daemon with SQLite and continuous vector retrieval, adding daemon overhead and cross-process latency.
|
|
47
|
+
|
|
48
|
+
**Anchor takes a lean, pragmatic approach**: task state is stored globally in `~/.anchor/`, leaving your project git tree 100% clean; active tasks consume 0 tokens during normal working turns, resurfacing via a single-line code comment only when associated files are touched; and tasks automatically settle upon git commits or on session exit.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Core Architecture
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
56
|
+
│ Anchor Lifecycle State Machine │
|
|
57
|
+
└──────────────────────────────────────┬───────────────────────────────────────┘
|
|
58
|
+
│ Pin task: /pin "Migrate auth to HTTP-only cookies"
|
|
59
|
+
▼
|
|
60
|
+
┌───────────────────────────────────────────────┐
|
|
61
|
+
│ [ACTIVE Tier] (Turn 1 Injected) │
|
|
62
|
+
│ - Status indicator: ⌖ 4 │
|
|
63
|
+
│ - Turn 2+ : Excluded from prompt (0 Tokens) │
|
|
64
|
+
└───────┬───────────────────────────────┬───────┘
|
|
65
|
+
│ │
|
|
66
|
+
Git Commit / │ │ Inactivity Decay
|
|
67
|
+
Code Touch ▼ ▼
|
|
68
|
+
┌──────────────────────────────┐ ┌────────────────────────────────┐
|
|
69
|
+
│ [Syntax-Safe JIT Wakeup] │ │ [SLEEPING Tier] (0 Tokens) │
|
|
70
|
+
│ Language-accurate comments │ │ Preserved safely in global │
|
|
71
|
+
│ JSON/ENV strictly skipped │ │ state; wakes upon code touch │
|
|
72
|
+
└──────────────┬───────────────┘ └────────────────┬───────────────┘
|
|
73
|
+
│ │
|
|
74
|
+
Exit Prompt / Commit Match │ Silent Sweep
|
|
75
|
+
▼ ▼
|
|
76
|
+
┌──────────────────────────────┐ ┌────────────────────────────────┐
|
|
77
|
+
│ [SETTLED / Archived] │ │ [GRAVEYARD / Evicted] │
|
|
78
|
+
│ Appended to archive.jsonl │ │ Swept to graveyard.jsonl │
|
|
79
|
+
│ Evicted from active context │ │ (Auto-pruned after decay) │
|
|
80
|
+
└──────────────────────────────┘ └────────────────────────────────┘
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 1. Zero Repository Contamination & Concurrent File Safety
|
|
84
|
+
Anchor never creates local `.anchor` folders or touches your project git tree. All state lives safely in user-global storage:
|
|
85
|
+
```text
|
|
86
|
+
~/.anchor/
|
|
87
|
+
├── state.json # Active and sleeping task state (< 10KB, atomic write)
|
|
88
|
+
├── state.lock # Cross-process sync atomic lock (Zero dependencies)
|
|
89
|
+
├── archive.jsonl # Append-only log of settled tasks
|
|
90
|
+
└── graveyard.jsonl # Append-only log of decayed and evicted items
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
* **Zero-Dependency Exclusive Lock**: Uses Node's native `fs.openSync(lockPath, 'wx')` to ensure atomic serialization across multiple terminal tabs or concurrent agents.
|
|
94
|
+
* **Dead PID Reclamation**: Automatically reads lock owner metadata. If the owning process has terminated (`process.kill(pid, 0)` fails) or exceeded the 5000ms stale timeout, Anchor safely reclaims the lock.
|
|
95
|
+
* **Resilient Atomic Writes**: State writes use a temporary file (`state.tmp.${pid}.${timestamp}`) followed by atomic `fs.renameSync` with spin-retries for Windows NTFS locks. Corrupted states trigger automatic timestamped backups (`state.corrupt.${timestamp}.json`) and fall back to clean initialization.
|
|
96
|
+
|
|
97
|
+
### 2. 0-Token Idle Economy & Multi-Language Syntax-Safe JIT
|
|
98
|
+
Context windows stay lean throughout extended sessions:
|
|
99
|
+
* **Turn 1 (Cold Start)**: The `before_agent_start` hook identifies the session turn count via `sessionManager.getEntries()`. It injects active commitments for the current workspace alongside natural conversational guidelines.
|
|
100
|
+
* **Turn 2+ (Working Turns)**: Anchor strips task lists from subsequent turns. Stored tasks consume **0 tokens** while the agent writes code.
|
|
101
|
+
* **Language-Accurate Comment Formats**: When an agent touches files, Anchor formats annotations matching the file extension:
|
|
102
|
+
- Double slash `//`: `ts`, `tsx`, `js`, `jsx`, `go`, `rs`, `java`, `c`, `cpp`, `cs`, `swift`, `dart`, `zig`
|
|
103
|
+
- Hash `#`: `py`, `rb`, `sh`, `bash`, `zsh`, `yaml`, `yml`, `toml`, `dockerfile`, `ps1`
|
|
104
|
+
- HTML markup `<!-- -->`: `html`, `xml`, `svg`, `vue`, `svelte`
|
|
105
|
+
- Block comments `/* */`: `css`, `scss`, `less`
|
|
106
|
+
- SQL dashes `--`: `sql`, `lua`, `hs`
|
|
107
|
+
* **Syntax-Safe Guard (Strict Null)**: For **JSON, ENV, Lockfiles, and binary assets**, Anchor explicitly returns `null`, preventing corrupted parsers or invalid syntax.
|
|
108
|
+
* **Session Deduplication**: Matched tasks are injected only once per session per file to keep tool results clean.
|
|
109
|
+
|
|
110
|
+
### 3. Decoupled Universal Agent Protocol
|
|
111
|
+
Anchor separates its core state management from host environments:
|
|
112
|
+
* **`AnchorProtocol`**: Harness-agnostic engine orchestrating state transitions, decay sweeps, JIT annotations, and settlement matching.
|
|
113
|
+
* **`AgentAdapter`**: A lightweight bridge (`name`, `getCwd()`, `notify()`) enabling drop-in integration with Pi, Claude Code, Cursor, Aider, or custom MCP servers.
|
|
114
|
+
|
|
115
|
+
### 4. Dual-Timeline: Deadlines & Task Aging
|
|
116
|
+
Anchor organizes tasks along two complementary temporal axes:
|
|
117
|
+
* **Target Delivery (`targetDate`)**: Expected completion date. Natural language keywords (today, tonight, tomorrow, friday, next week) map directly to structured ISO dates. Rendered in UI as `Today`, `Tomorrow`, `In 2d`, `Daily`, `Someday`.
|
|
118
|
+
* **Creation Timestamp (`createdAt`)**: Physical creation time. Rendered in UI as `Today 10:02`, `Yesterday 21:34`, or `09-24 15:30`.
|
|
119
|
+
|
|
120
|
+
The dashboard groups active tasks into four categories:
|
|
121
|
+
* **`[Today]`**: Items due today or overdue. Priority target for the current session.
|
|
122
|
+
* **`[Upcoming]`**: Scheduled future commitments (tomorrow, upcoming weekdays, specific dates via `--due friday`).
|
|
123
|
+
* **`[Habits]`**: Recurring daily practices (such as regular backups or review habits). Completing today auto-reawakens the task tomorrow.
|
|
124
|
+
* **`[Backlog]`**: Architectural visions without explicit deadlines (`Someday`).
|
|
125
|
+
|
|
126
|
+
### 5. Zero-Friction Evidence Settlement
|
|
127
|
+
* **Git Commit Resolution**: Recognizes commit messages across Latin and CJK character sets via standard `Intl.Segmenter`. Commits matching task descriptions auto-settle the corresponding anchor.
|
|
128
|
+
* **Exit Settlement Interception**: Session exit evaluates files modified in Git. If touched files intersect with active anchors, Anchor prompts a single-keypress resolution dialog:
|
|
129
|
+
```text
|
|
130
|
+
⌖ Settle Anchor Task
|
|
131
|
+
Task #anc-1 [Migrate auth to HTTP-only cookies] touched files (src/auth/jwt.ts).
|
|
132
|
+
Mark as completed and archive? [Enter Confirm] / [Esc Keep]
|
|
133
|
+
```
|
|
134
|
+
* **Instant Reversion**: Run `anchor undo` to restore the last settled task back into `state.json`.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Interface Design
|
|
139
|
+
|
|
140
|
+
### Status Bar Indicator
|
|
141
|
+
* When active tasks exist: Displays task count `⌖ 4` in the terminal status row.
|
|
142
|
+
* Zero tasks: 100% invisible (0 characters rendered).
|
|
143
|
+
|
|
144
|
+
### Global CLI (`anchor`) & Interactive TUI (`/anchor`)
|
|
145
|
+
```text
|
|
146
|
+
⌖ Anchors (4 active):
|
|
147
|
+
|
|
148
|
+
[Today · Today's Focus]
|
|
149
|
+
01 [Today] Optimize token truncation & JIT safety Desktop Today Today 10:02
|
|
150
|
+
|
|
151
|
+
[Upcoming · Scheduled]
|
|
152
|
+
02 [Upcoming] Add concurrent file lock unit tests Desktop Tomorrow Yesterday 21:34
|
|
153
|
+
03 [Upcoming] Polish CLI interactive dashboard Desktop Tomorrow Today 10:02
|
|
154
|
+
04 [Upcoming] Publish npm package v0.2.0 Desktop In 2d Today 10:02
|
|
155
|
+
|
|
156
|
+
Use `anchor done <id>` to complete.
|
|
157
|
+
```
|
|
158
|
+
* **Continuous Numbering**: Ordered index rows (`01`, `02`, `03`) prevent visual disorientation.
|
|
159
|
+
* **Dual-Channel Input**: `anchor done 1` completes displayed line 1; `anchor done anc-5` targets an explicit ID.
|
|
160
|
+
* **Unicode / Emoji / Hangul Alignment**: Pure terminal column calculation prevents row tearing across mixed ASCII, full-width CJK, and emoji sequences.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Comparison
|
|
165
|
+
|
|
166
|
+
| Feature | `gastownhall/beads` | `Gentleman-Programming/engram` | `AGENTS.md` / `TODO.md` | **Anchor ⚓** |
|
|
167
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
168
|
+
| **Core Architecture** | Distributed SQL Graph | Vector/SQLite Memory | Static Markdown | **Decoupled Universal Protocol + Atomic State** |
|
|
169
|
+
| **Concurrency Safety** | SQL Transaction locks | Daemon single-point | Git merge conflicts | **Zero-dep cross-process atomic file lock** |
|
|
170
|
+
| **Workspace Hygiene** | Pollutes repo with 200MB Dolt | System daemon | **Pollutes git commit history** | **100% Zero repo pollution (`~/.anchor/`)** |
|
|
171
|
+
| **Token Cost** | Medium/High per turn | High (full prompt injection) | Severe (stale text accumulates) | **0 Tokens idle (JIT file touch only)** |
|
|
172
|
+
| **JIT Syntax Safety** | N/A | Raw text injection | Static unformatted | **Language-aware comments, strictly skips JSON** |
|
|
173
|
+
| **Task Timeline** | Flat list | Flat list | Static checklist | **Dual-timeline (Due Date + Task Age)** |
|
|
174
|
+
| **Closure Mechanism** | Manual CLI close | Passive storage | Manual file edit | **Git Commit auto-match + One-tap exit settlement** |
|
|
175
|
+
| **Decay Management** | Manual pruning | None | Stagnates permanently | **Silent decay (ephemeral 48h vs durable backlog)** |
|
|
176
|
+
| **Startup Overhead** | Heavy CLI init | Go daemon | None | **< 90ms pre-bundled production artifact** |
|
|
177
|
+
| **Dependencies** | External Dolt binary | External Go binary | None | **Zero native binary dependencies (Pure TS)** |
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Quick Start
|
|
182
|
+
|
|
183
|
+
### 1. Global CLI
|
|
184
|
+
```bash
|
|
185
|
+
# Global installation
|
|
186
|
+
npm install -g pi-anchor
|
|
187
|
+
|
|
188
|
+
# Or instant invocation via npx
|
|
189
|
+
npx pi-anchor
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Command summary:
|
|
193
|
+
```bash
|
|
194
|
+
anchor # List active tasks
|
|
195
|
+
anchor "Refactor auth cookies" # Pin new commitment
|
|
196
|
+
anchor "Submit report" --due friday # Pin with explicit deadline
|
|
197
|
+
anchor done 1 # Complete row 1
|
|
198
|
+
anchor undo # Restore last archived task
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 2. Universal Protocol Library
|
|
202
|
+
```typescript
|
|
203
|
+
import { AnchorStore, AnchorProtocol } from 'pi-anchor';
|
|
204
|
+
|
|
205
|
+
const store = new AnchorStore();
|
|
206
|
+
const protocol = new AnchorProtocol(store);
|
|
207
|
+
|
|
208
|
+
// Initialize session
|
|
209
|
+
protocol.handleSessionStart();
|
|
210
|
+
|
|
211
|
+
// Turn 1 injects cold-start context; Turn 2+ returns null (0 tokens)
|
|
212
|
+
const turn1Prompt = protocol.handleBeforeTurn(1, process.cwd());
|
|
213
|
+
|
|
214
|
+
// Tool result file touch generates language-accurate safe comments
|
|
215
|
+
const { annotation } = protocol.handleToolResult({
|
|
216
|
+
toolName: 'read',
|
|
217
|
+
filePath: 'src/auth.ts',
|
|
218
|
+
cwd: process.cwd()
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 3. Pi Coding Agent Extension
|
|
223
|
+
Install into user extensions:
|
|
224
|
+
```bash
|
|
225
|
+
pi install npm:pi-anchor
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Verification & Quality Assurance
|
|
231
|
+
|
|
232
|
+
Engineered with strict TypeScript and 100% standard library test coverage using Node's native test runner:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run build # Dual ESM/CJS compilation via tsup + declaration emit
|
|
236
|
+
npm run typecheck # Strict tsc --noEmit check (0 errors)
|
|
237
|
+
npm test # Native Node test runner (24/24 passing)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
✔ Lock - acquireSyncLock acquires, holds, and releases exclusive lockfile (32ms)
|
|
242
|
+
✔ Lock - acquireSyncLock safely reclaims stale lock from dead PID (18ms)
|
|
243
|
+
✔ Context - makeSafeTaskAnnotation produces language-accurate comments and skips JSON (3.1ms)
|
|
244
|
+
✔ Protocol - AnchorProtocol lifecycle handles cold-start and safe JIT (21ms)
|
|
245
|
+
✔ ContextInjector - renders only active anchors, sleeping consume 0 tokens (59ms)
|
|
246
|
+
✔ ContextInjector - renders targetDate and task aging in prompt (10ms)
|
|
247
|
+
✔ AnchorDecay - status evaluation transitions (1.2ms)
|
|
248
|
+
✔ AnchorDecay - sweepStore transitions and graveyard eviction (102ms)
|
|
249
|
+
✔ AnchorMatcher - exact, prefix, and tag matching (2.5ms)
|
|
250
|
+
✔ AnchorMatcher - glob pattern matching (*.ts, src/**/*.ts) (0.7ms)
|
|
251
|
+
✔ AnchorMatcher - findMatchedAnchors prioritizes high-confidence & high-priority (0.4ms)
|
|
252
|
+
✔ SessionTouchObserver - records read, edit, write and commits (25ms)
|
|
253
|
+
✔ SessionTouchObserver - matches CJK commit messages with segmentation (2.0ms)
|
|
254
|
+
✔ SessionTouchObserver - separates read inspection from edit mutation (12ms)
|
|
255
|
+
✔ AnchorStore - basic CRUD & atomic writes (77ms)
|
|
256
|
+
✔ AnchorStore - corrupt state recovery (9.1ms)
|
|
257
|
+
✔ AnchorStore - daily recurring task completes for today and wakes tomorrow (19ms)
|
|
258
|
+
✔ AnchorStore - temporal durability keywords and project detection (10ms)
|
|
259
|
+
✔ AnchorStore - atomicRenameWithRetry successfully replaces files atomically (22ms)
|
|
260
|
+
✔ AnchorTUI - status bar reflects active state cleanly with ⌖ N (23ms)
|
|
261
|
+
✔ AnchorTUI - formatTargetDate and formatCreationTime render clear dual-timeline (38ms)
|
|
262
|
+
✔ AnchorTUI - openAnchorDashboard renders Plan 2 Neovim/Geek layout with folder metadata (26ms)
|
|
263
|
+
✔ AnchorTUI - getDisplayWidth and padToWidth properly align CJK full-width columns (0.3ms)
|
|
264
|
+
✔ AnchorTUI - updateStartupBanner renders clean widget above editor (8.7ms)
|
|
265
|
+
|
|
266
|
+
ℹ pass 24, fail 0 (416ms total runtime)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT License © 2025 [Jason Song (@3ZEROS12)](https://github.com/3ZEROS12)
|
package/README_zh.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# ⌖ Anchor
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>面向 AI 编程智能体的零污染、零闲置 Token 跨会话任务记忆。</strong><br>
|
|
5
|
+
<em>告别发霉的 TODO.md。零 Git 历史污染,0 闲置 Token 损耗,写完代码自动闭环核销。</em>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="README.md">English</a> •
|
|
10
|
+
<a href="#为什么需要-anchor">💡 核心痛点</a> •
|
|
11
|
+
<a href="#核心机制">✨ 核心机制</a> •
|
|
12
|
+
<a href="#终端交互设计">🖥️ 界面设计</a> •
|
|
13
|
+
<a href="#横向技术对比">📊 竞品对比</a> •
|
|
14
|
+
<a href="#快速上手">🚀 快速开始</a> •
|
|
15
|
+
<a href="#测试与质量保障">🧪 质量验证</a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml">
|
|
20
|
+
<img src="https://github.com/3ZEROS12/anchor/actions/workflows/ci.yml/badge.svg" alt="CI 状态">
|
|
21
|
+
</a>
|
|
22
|
+
<img src="https://img.shields.io/badge/Node-v20+-22c55e.svg" alt="Node v20+">
|
|
23
|
+
<img src="https://img.shields.io/badge/TypeScript-Strict-3b82f6.svg" alt="TypeScript Strict">
|
|
24
|
+
<img src="https://img.shields.io/badge/Tests-24%20通过-22c55e.svg" alt="Tests: 24 Passed">
|
|
25
|
+
<img src="https://img.shields.io/badge/启动耗时-%3C%2090ms-success.svg" alt="启动耗时: < 90ms">
|
|
26
|
+
<img src="https://img.shields.io/badge/存储-零仓库污染-success.svg" alt="零仓库污染">
|
|
27
|
+
<img src="https://img.shields.io/badge/开源协议-MIT-f97316.svg" alt="License: MIT">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="assets/hero.svg" alt="Anchor 终端仪表盘" width="820">
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 为什么需要 Anchor?
|
|
37
|
+
|
|
38
|
+
使用终端编程智能体(Claude Code、Pi、Aider 等)进行实际项目开发时,开发者普遍面临三个摩擦:
|
|
39
|
+
|
|
40
|
+
1. **终端退出即失忆**:按下 `Ctrl+C` 退出终端,Agent 内存中的上下文被全部清空。未完成的代码重构计划、临时交代的排期与多步约定瞬间丢失。
|
|
41
|
+
2. **TODO.md 污染与 Token 泥潭**:直接在工程根目录写 `TODO.md` 或 `AGENTS.md`,不仅会产生大量 Git 杂质提交,而且**每一轮对话都要把几十行陈旧清单塞入 System Prompt**,白白消耗大量 Token 预算,并分散模型对当前核心代码的注意力。
|
|
42
|
+
3. **静态清单无限腐烂**:写完代码后,工程师极少会专程打开 Markdown 逐个打勾。未勾选的旧任务烂在仓库里,越积越多。
|
|
43
|
+
|
|
44
|
+
现有的解决方案大多走向了两个重型极端:
|
|
45
|
+
* `gastownhall/beads`:往代码仓库里硬塞一个 200MB 的 Dolt 关系型数据库来跟踪任务关系;
|
|
46
|
+
* `Gentleman-Programming/engram`:启动常驻后台的 Go 守护进程,搭配 SQLite 与持续向量检索,带来额外的进程驻留开销与通信延迟。
|
|
47
|
+
|
|
48
|
+
**Anchor 选择了最克制、轻量的工程路径**:任务状态统一保存在用户主目录 `~/.anchor/`,被管项目 100% 保持干净;日常工作轮次保持 0 Token 损耗,仅在 Agent 触碰关联代码文件时精准唤醒;代码提交或退出终端时自动核销归档。
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 核心机制
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
┌──────────────────────────────────────────────────────────────────────────────┐
|
|
56
|
+
│ Anchor 生命周期状态机 │
|
|
57
|
+
└──────────────────────────────────────┬───────────────────────────────────────┘
|
|
58
|
+
│ 记录任务: /pin "重构鉴权为 HttpOnly Cookie"
|
|
59
|
+
▼
|
|
60
|
+
┌───────────────────────────────────────────────┐
|
|
61
|
+
│ [活跃期 ACTIVE] (首轮注入提示) │
|
|
62
|
+
│ - 底部状态栏指示: ⌖ 4 │
|
|
63
|
+
│ - 第 2 轮起完全脱离提示词 (0 Token 稳态) │
|
|
64
|
+
└───────┬───────────────────────────────┬───────┘
|
|
65
|
+
│ │
|
|
66
|
+
Git 提交命中 / │ │ 闲置时间衰减
|
|
67
|
+
触碰关联代码文件 ▼ ▼
|
|
68
|
+
┌──────────────────────────────┐ ┌────────────────────────────────┐
|
|
69
|
+
│ [多语言语法安全 JIT 唤醒] │ │ [休眠期 SLEEPING] (0 Token) │
|
|
70
|
+
│ 触碰代码时注入语言对应注释 │ │ 全局安全封存,不打扰当前心流, │
|
|
71
|
+
│ JSON/ENV 等格式绝对跳过 │ │ 触碰关联文件时重新唤醒 │
|
|
72
|
+
└──────────────┬───────────────┘ └────────────────┬───────────────┘
|
|
73
|
+
│ │
|
|
74
|
+
退出自动提议 / Commit 命中 │ 静默定期清理
|
|
75
|
+
▼ ▼
|
|
76
|
+
┌──────────────────────────────┐ ┌────────────────────────────────┐
|
|
77
|
+
│ [已完成归档 SETTLED] │ │ [超期淘汰 GRAVEYARD] │
|
|
78
|
+
│ 追加写入 archive.jsonl 归档 │ │ 超期自动清理,防止陈旧堆积 │
|
|
79
|
+
│ 从当前活跃上下文中物理移除 │ │ │
|
|
80
|
+
└──────────────────────────────┘ └────────────────────────────────┘
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 1. 绝对零仓库污染与跨进程并发文件锁
|
|
84
|
+
Anchor 绝不在被管理的代码工程内创建 `.anchor/` 目录,也不修改本地 Git 树。所有状态统一保存在用户全局主目录:
|
|
85
|
+
```text
|
|
86
|
+
~/.anchor/
|
|
87
|
+
├── state.json # 活跃与休眠任务状态表(原子写入,< 10KB)
|
|
88
|
+
├── state.lock # 跨进程排他原子锁(零依赖,PID 自动回收)
|
|
89
|
+
├── archive.jsonl # 已完成任务的追加归档日志
|
|
90
|
+
└── graveyard.jsonl # 超期衰减淘汰的清理日志
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
* **零依赖排他锁**:使用 Node 原生 `fs.openSync(lockPath, 'wx')` 实现跨进程排他锁,彻底消除多终端窗口并发读写 `state.json` 时的竞争覆盖风险。
|
|
94
|
+
* **僵尸锁自动熔断**:写入持有锁进程的 PID 与时间戳。若检测到持有者进程已死亡(`process.kill(pid, 0)`)或锁持有超时(>5000ms),自动安全回收重占。
|
|
95
|
+
* **Windows NTFS 写入重试**:落盘采用临时文件(`state.tmp.${pid}.${timestamp}`)配合原子重命名与自旋重试,彻底杜绝断电或杀进程时的半截文件损坏。
|
|
96
|
+
|
|
97
|
+
### 2. 0-Token 稳态与多语言语法安全 JIT 唤醒
|
|
98
|
+
* **第 1 轮(冷启动注入)**:通过 `before_agent_start` 识别会话轮次,仅在第一轮为大模型注入当前工程未完成的 Anchor 概览与极简指引。
|
|
99
|
+
* **第 2 轮起(工作流零损耗)**:任务清单彻底从 System Prompt 中隐形。正常写代码轮次消耗 **0 Token**,绝不稀释模型注意力。
|
|
100
|
+
* **多语言精确语法适配**:当 Agent 读写关联文件时,Anchor 依据文件后缀精确匹配合法注释语法,绝不污染代码:
|
|
101
|
+
- 双斜杠 `//`:`ts`, `tsx`, `js`, `jsx`, `go`, `rs`, `java`, `c`, `cpp`, `cs`, `swift`, `dart`, `zig`
|
|
102
|
+
- 井号 `#`:`py`, `rb`, `sh`, `bash`, `zsh`, `yaml`, `yml`, `toml`, `dockerfile`, `ps1`
|
|
103
|
+
- 标记语言 `<!-- -->`:`html`, `xml`, `svg`, `vue`, `svelte`
|
|
104
|
+
- 块注释 `/* */`:`css`, `scss`, `less`
|
|
105
|
+
- 短横线 `--`:`sql`, `lua`, `hs`
|
|
106
|
+
* **语法安全防护(严格跳过)**:对 **JSON、ENV、Lockfile 及二进制文件**坚决返回 `null`,绝不强行注入注释,从根本上防止破坏格式解析器。
|
|
107
|
+
* **单会话去重防刷屏**:同一任务在同一会话中多次触碰仅在首次注入单行提示,后续操作保持静默。
|
|
108
|
+
|
|
109
|
+
### 3. 通用智能体协议解耦 (Universal Agent Protocol)
|
|
110
|
+
Anchor 采用分层解耦架构,核心调度逻辑与具体 Agent 运行时彻底分离:
|
|
111
|
+
* **`AnchorProtocol`(纯核心)**:独立管理状态机、生命周期钩子、JIT 语法过滤与任务匹配,不绑定任何第三方 Agent 运行环境。
|
|
112
|
+
* **`AgentAdapter`(极薄适配层)**:提供统一的宿主桥接接口(`getCwd`, `notify`),几行代码即可适配 Pi 扩展、Claude Code、Cursor、Aider 或自定义 MCP 协议服务。
|
|
113
|
+
|
|
114
|
+
### 4. 双时间维度:交付排期与立项时效
|
|
115
|
+
Anchor 从两个正交的时间维度管理任务,兼顾“何时要交”与“立项多久”:
|
|
116
|
+
* **交付排期(`targetDate`)**:计划交工日期。支持自然语言词汇(今天、今晚、明天、后天、周五、下周一)自动折算为标准公历日期。界面呈现为 `Today`、`Tomorrow`、`In 2d`、`Daily`、`Someday`。
|
|
117
|
+
* **立项时效(`createdAt`)**:创建时的物理时间戳。界面直观显示为 `Today 10:02`、`Yesterday 21:34` 等。
|
|
118
|
+
|
|
119
|
+
任务按时间与类型自动分组:
|
|
120
|
+
* **`[Today]`(今日聚焦 & 逾期)**:今日到期或已逾期的任务,当前会话的核心攻坚项。
|
|
121
|
+
* **`[Upcoming]`(近期排期)**:明天、后天或未来指定截期的任务(支持 `--due friday`)。
|
|
122
|
+
* **`[Habits]`(每日循环)**:日常例行循环任务。当天打勾后隐身,明日零点自动复苏。
|
|
123
|
+
* **`[Backlog]`(长期备忘)**:无指定日期的宏观架构愿景(`Someday`)。
|
|
124
|
+
|
|
125
|
+
### 5. 零心智负担的自动核销闭环
|
|
126
|
+
* **Git Commit 自动语义匹配**:内置基于标准 `Intl.Segmenter` 的多语系分词引擎。代码提交信息(如 `git commit -m "fix(auth): migrate to HttpOnly cookies"`)命中任务描述时自动核销结案。
|
|
127
|
+
* **退出终端一键确认**:检测到本会话修改了任务关联的文件时,退出终端前弹出极简单键确认:
|
|
128
|
+
```text
|
|
129
|
+
⌖ 任务核销确认
|
|
130
|
+
任务 #anc-1 [重构鉴权模块] 关联的文件已在本会话中修改 (src/auth/jwt.ts)。
|
|
131
|
+
是否标记已完成并归档? [回车确认] / [Esc 保留]
|
|
132
|
+
```
|
|
133
|
+
* **一键撤销(Undo)**:手抖误划掉任务时,敲入 `anchor undo` 瞬间逆向回滚恢复。
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 终端交互设计
|
|
138
|
+
|
|
139
|
+
### 终端状态栏指示
|
|
140
|
+
* 存在活跃任务时:终端底部状态栏显示任务计数 `⌖ 4`。
|
|
141
|
+
* 无活跃任务时:100% 物理隐身(0 字符输出)。
|
|
142
|
+
|
|
143
|
+
### 全局命令行 (`anchor`) 与交互面板 (`/anchor`)
|
|
144
|
+
```text
|
|
145
|
+
⌖ Anchors (4 active):
|
|
146
|
+
|
|
147
|
+
[Today · 今日聚焦]
|
|
148
|
+
01 [Today] 优化 Token 截断逻辑与注入安全 Desktop Today Today 10:02
|
|
149
|
+
|
|
150
|
+
[Upcoming · 近期排期]
|
|
151
|
+
02 [Upcoming] 补齐多终端并发文件锁单元测试 Desktop Tomorrow Yesterday 21:34
|
|
152
|
+
03 [Upcoming] 升级 CLI 交互动画与高亮样式 Desktop Tomorrow Today 10:02
|
|
153
|
+
04 [Upcoming] 梳理并发布 npm 0.2.0 版本制品 Desktop In 2d Today 10:02
|
|
154
|
+
|
|
155
|
+
Use `anchor done <id>` to complete.
|
|
156
|
+
```
|
|
157
|
+
* **严格连续行号**:显示清晰连续的序号 `01`、`02`、`03`,告别跳号困扰。
|
|
158
|
+
* **双通道智能结案**:敲 `anchor done 1` 划掉当前屏幕第 1 行;敲 `anchor done anc-5` 精准结算特定 ID。
|
|
159
|
+
* **Unicode 全角 / Emoji / 谚文 等宽对齐**:终端纯列宽严格计算,彻底解决中英文混排、Emoji 表情符号渲染时的横向锯齿撕裂。
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 横向技术对比
|
|
164
|
+
|
|
165
|
+
| 对比维度 | `gastownhall/beads` | `Gentleman-Programming/engram` | `AGENTS.md` / `TODO.md` | **Anchor ⚓** |
|
|
166
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
167
|
+
| **底层架构** | 分布式 SQL 关系图谱 | 向量与 SQLite 外部库 | 静态 Markdown 纯文本 | **轻量解耦协议核心 + 原子状态机** |
|
|
168
|
+
| **并发安全** | 依赖 SQL 事务 | 守护进程单点处理 | 多终端编辑直接产生冲突 | **跨进程原子排他锁 (死进程自愈)** |
|
|
169
|
+
| **工作区清洁度** | 仓库内塞入 200MB Dolt 数据库 | 外部系统服务 | **频繁产生 Git 杂质提交** | **100% 零仓库污染 (`~/.anchor/`)** |
|
|
170
|
+
| **Token 损耗** | 每轮中/高消耗 | 高(注入长文历史) | 极高(陈旧文本成倍累积) | **0 Token 闲置(仅文件触碰 JIT 唤醒)** |
|
|
171
|
+
| **JIT 语法安全** | 不支持文件注释 | 无语法感知 | 静态文本无防护 | **精确匹配 30+ 语言注释,跳过 JSON** |
|
|
172
|
+
| **任务时效** | 单层平铺 | 单层平铺 | 静态复选框 | **双时间维度(交付排期 + 立项时间)** |
|
|
173
|
+
| **核销闭环** | 手动命令 `close` | 无闭环机制 | 人工修改文本打勾 | **Git Commit 自动识别 + 退出前一键核销** |
|
|
174
|
+
| **衰减清理** | 手动 prune | 无衰退机制 | 长期堆积发霉 | **静默衰退(临时任务 48h 自动清理)** |
|
|
175
|
+
| **启动耗时** | 重型 CLI 初始化 | Go 守护进程常驻 | 无 | **< 90ms 预打包瞬时秒开** |
|
|
176
|
+
| **环境依赖** | 外部 Dolt 二进制 | 外部 Go 编译产物 | 无 | **零原生外部依赖(纯 TypeScript)** |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 快速上手
|
|
181
|
+
|
|
182
|
+
### 1. 全局独立命令行 CLI
|
|
183
|
+
```bash
|
|
184
|
+
# 全局安装
|
|
185
|
+
npm install -g pi-anchor
|
|
186
|
+
|
|
187
|
+
# 或直接通过 npx 免安装即用
|
|
188
|
+
npx pi-anchor
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
常用命令:
|
|
192
|
+
```bash
|
|
193
|
+
anchor # 查看待办清单
|
|
194
|
+
anchor "重构鉴权 Cookie" # 记录新任务
|
|
195
|
+
anchor "提交周报" --due friday # 指定预期交付时间
|
|
196
|
+
anchor done 1 # 划掉第 1 行任务
|
|
197
|
+
anchor undo # 撤销上次结案
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 2. 作为通用协议库引入
|
|
201
|
+
```typescript
|
|
202
|
+
import { AnchorStore, AnchorProtocol } from 'pi-anchor';
|
|
203
|
+
|
|
204
|
+
const store = new AnchorStore();
|
|
205
|
+
const protocol = new AnchorProtocol(store);
|
|
206
|
+
|
|
207
|
+
// 监听会话启动
|
|
208
|
+
protocol.handleSessionStart();
|
|
209
|
+
|
|
210
|
+
// 第 1 轮注入提示,第 2 轮返回 null (0 Tokens)
|
|
211
|
+
const coldStartPrompt = protocol.handleBeforeTurn(1, process.cwd());
|
|
212
|
+
|
|
213
|
+
// 工具触碰文件时获取安全注释
|
|
214
|
+
const { annotation } = protocol.handleToolResult({
|
|
215
|
+
toolName: 'read',
|
|
216
|
+
filePath: 'src/auth.ts',
|
|
217
|
+
cwd: process.cwd()
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 3. 作为 Pi Coding Agent 扩展
|
|
222
|
+
在 Pi 扩展目录中安装:
|
|
223
|
+
```bash
|
|
224
|
+
pi install npm:pi-anchor
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 测试与质量保障
|
|
230
|
+
|
|
231
|
+
采用标准 TypeScript 严格模式构建,使用 Node.js 原生测试运行器实现核心链路 100% 测试覆盖:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npm run build # tsup 双格式打包 (ESM/CJS) 与 .d.ts 类型生成
|
|
235
|
+
npm run typecheck # TypeScript 严格类型检查 (0 错误)
|
|
236
|
+
npm test # 全套自动化单元测试 (24/24 全绿通过)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
```text
|
|
240
|
+
✔ Lock - acquireSyncLock acquires, holds, and releases exclusive lockfile (32ms)
|
|
241
|
+
✔ Lock - acquireSyncLock safely reclaims stale lock from dead PID (18ms)
|
|
242
|
+
✔ Context - makeSafeTaskAnnotation produces language-accurate comments and skips JSON (3.1ms)
|
|
243
|
+
✔ Protocol - AnchorProtocol lifecycle handles cold-start and safe JIT (21ms)
|
|
244
|
+
✔ ContextInjector - renders only active anchors, sleeping consume 0 tokens (59ms)
|
|
245
|
+
✔ ContextInjector - renders targetDate and task aging in prompt (10ms)
|
|
246
|
+
✔ AnchorDecay - status evaluation transitions (1.2ms)
|
|
247
|
+
✔ AnchorDecay - sweepStore transitions and graveyard eviction (102ms)
|
|
248
|
+
✔ AnchorMatcher - exact, prefix, and tag matching (2.5ms)
|
|
249
|
+
✔ AnchorMatcher - glob pattern matching (*.ts, src/**/*.ts) (0.7ms)
|
|
250
|
+
✔ AnchorMatcher - findMatchedAnchors prioritizes high-confidence & high-priority (0.4ms)
|
|
251
|
+
✔ SessionTouchObserver - records read, edit, write and commits (25ms)
|
|
252
|
+
✔ SessionTouchObserver - matches CJK commit messages with segmentation (2.0ms)
|
|
253
|
+
✔ SessionTouchObserver - separates read inspection from edit mutation (12ms)
|
|
254
|
+
✔ AnchorStore - basic CRUD & atomic writes (77ms)
|
|
255
|
+
✔ AnchorStore - corrupt state recovery (9.1ms)
|
|
256
|
+
✔ AnchorStore - daily recurring task completes for today and wakes tomorrow (19ms)
|
|
257
|
+
✔ AnchorStore - temporal durability keywords and project detection (10ms)
|
|
258
|
+
✔ AnchorStore - atomicRenameWithRetry successfully replaces files atomically (22ms)
|
|
259
|
+
✔ AnchorTUI - status bar reflects active state cleanly with ⌖ N (23ms)
|
|
260
|
+
✔ AnchorTUI - formatTargetDate and formatCreationTime render clear dual-timeline (38ms)
|
|
261
|
+
✔ AnchorTUI - openAnchorDashboard renders Plan 2 Neovim/Geek layout with folder metadata (26ms)
|
|
262
|
+
✔ AnchorTUI - getDisplayWidth and padToWidth properly align CJK full-width columns (0.3ms)
|
|
263
|
+
✔ AnchorTUI - updateStartupBanner renders clean widget above editor (8.7ms)
|
|
264
|
+
|
|
265
|
+
ℹ pass 24, fail 0 (416ms total runtime)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 开源协议
|
|
271
|
+
|
|
272
|
+
MIT License © 2025 [Jason Song (@3ZEROS12)](https://github.com/3ZEROS12)
|