pi-anchor 0.3.0 → 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 -170
- package/README_zh.md +32 -176
- package/assets/hero-en.svg +23 -39
- package/assets/hero-zh.svg +23 -39
- package/bin/anchor.js +36 -69
- 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 +369 -1315
- package/dist/extension.d.cts +2 -20
- package/dist/extension.d.ts +2 -20
- package/dist/extension.js +4 -536
- package/dist/index.cjs +317 -1143
- package/dist/index.d.cts +17 -250
- package/dist/index.d.ts +17 -250
- package/dist/index.js +15 -103
- package/package.json +2 -2
- package/src/extension.ts +124 -362
- package/src/index.ts +1 -6
- package/src/store.ts +294 -424
- package/src/tui.ts +102 -297
- package/src/types.ts +24 -65
- package/dist/chunk-Q7IILJFA.js +0 -1563
- package/dist/store-t2_TDhJn.d.cts +0 -210
- package/dist/store-t2_TDhJn.d.ts +0 -210
- package/src/context_injector.ts +0 -166
- package/src/decay.ts +0 -125
- package/src/matcher.ts +0 -202
- package/src/observer.ts +0 -141
- package/src/protocol.ts +0 -95
- package/src/settlement.ts +0 -140
package/dist/index.d.cts
CHANGED
|
@@ -1,275 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { c as
|
|
1
|
+
import { A as Anchor, a as AnchorStore } from './extension-B1-fzCox.cjs';
|
|
2
|
+
export { b as AnchorEvidence, c as AnchorPriority, d as AnchorStatus, e as AnchorStoreState, C as COMMENT_FORMATS, M as MS_PER_DAY, Q as QUIET_AFTER_DAYS, T as TouchMatchResult, f as acquireSyncLock, g as atomicRenameWithRetry, h as extractPathsFromText, i as findMatchedAnchors, j as getDefaultStorageDir, k as globToRegExp, l as isAnchorTargetingWorkspace, m as isSameOrSubPath, n as makeSafeTaskAnnotation, o as matchAnchorAgainstTouchedFiles, p as matchesCommitMessage, q as normalizePath, r as parseAnchorCommandInput, s as renderActiveAnchorsContext, t as renderColdStartAnchorsContext, u as resolveAnchorTarget, v as sweepQuietNotes } from './extension-B1-fzCox.cjs';
|
|
3
3
|
import { ExtensionContext } from '@earendil-works/pi-coding-agent';
|
|
4
4
|
|
|
5
|
-
interface DecayEvaluation {
|
|
6
|
-
currentStatus: AnchorStatus;
|
|
7
|
-
nextStatus: AnchorStatus;
|
|
8
|
-
daysUntouched: number;
|
|
9
|
-
remainingActiveDays: number;
|
|
10
|
-
remainingSleepDays: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Calculate precise decay status based on elapsed time since last touch
|
|
14
|
-
*/
|
|
15
|
-
declare function evaluateAnchorDecay(anchor: Anchor, now?: number): DecayEvaluation;
|
|
16
|
-
interface SweepResult {
|
|
17
|
-
transitionedToSleeping: string[];
|
|
18
|
-
wokenToActive: string[];
|
|
19
|
-
evictedToGraveyard: string[];
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Run decay sweep across store: transitions statuses and evicts expired anchors
|
|
23
|
-
*/
|
|
24
|
-
declare function sweepStore(store: AnchorStore, now?: number): SweepResult;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Convert simple glob pattern (e.g. *.ts, src/**\/*.ts, src/auth/*.ts) to RegExp
|
|
28
|
-
*/
|
|
29
|
-
declare function globToRegExp(pattern: string): RegExp;
|
|
30
|
-
/**
|
|
31
|
-
* Normalize path separators to POSIX forward slashes and optionally relative to baseCwd
|
|
32
|
-
*/
|
|
33
|
-
declare function normalizePath(filePath: string, baseCwd?: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Compare two workspace CWDs safely (case-insensitive on Windows, supports subdirectory scoping)
|
|
36
|
-
*/
|
|
37
|
-
declare function isSameOrSubPath(anchorCwd?: string, targetCwd?: string): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Extract explicit file or directory paths mentioned in natural language title/description
|
|
40
|
-
* (e.g. "D:/College/优化/EXTERNAL_ARCHITECTURE_INSPIRATIONS.md", "src/auth/jwt.ts")
|
|
41
|
-
*/
|
|
42
|
-
declare function extractPathsFromText(text?: string): string[];
|
|
43
|
-
/**
|
|
44
|
-
* Determine whether an anchor specifically targets a given workspace directory (`targetCwd`),
|
|
45
|
-
* checking `anchor.cwd`, `anchor.project`, and `anchor.files`.
|
|
46
|
-
*/
|
|
47
|
-
declare function isAnchorTargetingWorkspace(anchor: Anchor, targetCwd?: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Match touched files against an anchor's registered physical patterns
|
|
50
|
-
* Only anchors with explicit files/globs/prefixes are matched against file touches.
|
|
51
|
-
* Anchors with files: [] (pure mental notes or macro tasks) NEVER trigger on file operations.
|
|
52
|
-
*/
|
|
53
|
-
declare function matchAnchorAgainstTouchedFiles(anchor: Anchor, touchedFiles: string[]): TouchMatchResult | null;
|
|
54
|
-
/**
|
|
55
|
-
* Filter and sort anchors that match a set of touched files
|
|
56
|
-
* Prioritizes high confidence (exact > prefix > keyword) and priority (P0 > P1 > P2).
|
|
57
|
-
*/
|
|
58
|
-
declare function findMatchedAnchors(anchors: Anchor[], touchedFiles: string[]): TouchMatchResult[];
|
|
59
|
-
|
|
60
|
-
declare class SessionTouchObserver {
|
|
61
|
-
private touchedFiles;
|
|
62
|
-
private modifiedFiles;
|
|
63
|
-
private inspectedFiles;
|
|
64
|
-
private committed;
|
|
65
|
-
private commitMessages;
|
|
66
|
-
clear(): void;
|
|
67
|
-
/**
|
|
68
|
-
* Observe and record a tool call invocation, separating inspection from mutation
|
|
69
|
-
*/
|
|
70
|
-
recordToolCall(toolName: string, input: Record<string, unknown>): void;
|
|
71
|
-
/**
|
|
72
|
-
* Add a file path manually (e.g. from git status diff)
|
|
73
|
-
*/
|
|
74
|
-
addTouchedFile(filePath: string, isModified?: boolean): void;
|
|
75
|
-
getModifiedFiles(): string[];
|
|
76
|
-
getInspectedFiles(): string[];
|
|
77
|
-
getTouchedFiles(): string[];
|
|
78
|
-
hasCommitted(): boolean;
|
|
79
|
-
getCommitMessages(): string[];
|
|
80
|
-
/**
|
|
81
|
-
* Check if any commit message explicitly references or resolves an anchor
|
|
82
|
-
*/
|
|
83
|
-
matchesCommit(anchor: Anchor): {
|
|
84
|
-
matched: boolean;
|
|
85
|
-
message?: string;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Execute physical verification test command for an anchor
|
|
91
|
-
*/
|
|
92
|
-
declare function runPhysicalVerification(anchor: Anchor, cwd: string): {
|
|
93
|
-
success: boolean;
|
|
94
|
-
output: string;
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Real-time autonomous settlement during active session:
|
|
98
|
-
* Triggered immediately when a non-error shell command runs `git commit` or a matching `verifyCommand`.
|
|
99
|
-
* Works for BOTH file-bound and file-less (`files: []`) anchors!
|
|
100
|
-
*/
|
|
101
|
-
declare function tryRealtimeAutoSettle(store: AnchorStore, observer: SessionTouchObserver, cwd?: string, executedCommand?: string): Array<{
|
|
102
|
-
anchor: Anchor;
|
|
103
|
-
reason: string;
|
|
104
|
-
}>;
|
|
105
|
-
/**
|
|
106
|
-
* Generate settlement candidates based on files touched or commits made during the session
|
|
107
|
-
*/
|
|
108
|
-
declare function generateSettlementProposals(store: AnchorStore, touchedFiles: string[], cwd?: string, observer?: SessionTouchObserver): SettlementProposal[];
|
|
109
|
-
/**
|
|
110
|
-
* Format settlement proposal into terminal-ready card
|
|
111
|
-
*/
|
|
112
|
-
declare function formatSettlementCard(proposal: SettlementProposal): string;
|
|
113
|
-
|
|
114
|
-
type AnchorQuadrant = 'Today' | 'Upcoming' | 'Habits' | 'Backlog';
|
|
115
|
-
interface GroupedAnchors {
|
|
116
|
-
today: Anchor[];
|
|
117
|
-
upcoming: Anchor[];
|
|
118
|
-
habits: Anchor[];
|
|
119
|
-
backlog: Anchor[];
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Classify anchor into one of four cognitive quadrants:
|
|
123
|
-
* - 'Today': Due today or overdue
|
|
124
|
-
* - 'Upcoming': Due in the future (tomorrow, in 2d, specific dates)
|
|
125
|
-
* - 'Habits': Daily recurring habits
|
|
126
|
-
* - 'Backlog': Open-ended long-term vision
|
|
127
|
-
*/
|
|
128
|
-
declare function classifyAnchor(anchor: Anchor, now?: number): AnchorQuadrant;
|
|
129
|
-
/**
|
|
130
|
-
* Group active anchors by cognitive quadrant
|
|
131
|
-
*/
|
|
132
|
-
declare function groupAnchorsByQuadrant(anchors: Anchor[], now?: number): GroupedAnchors;
|
|
133
|
-
/**
|
|
134
|
-
* Sort unfinished anchors into a single compact, priority-driven engineering list:
|
|
135
|
-
* 1. Active before Sleeping (quiet)
|
|
136
|
-
* 2. Matching current workspace before other workspaces
|
|
137
|
-
* 3. Due Today / Overdue before open-ended
|
|
138
|
-
* 4. Priority (P0 -> P1 -> P2)
|
|
139
|
-
*/
|
|
140
|
-
declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string, now?: number): Anchor[];
|
|
141
|
-
/**
|
|
142
|
-
* Strip ANSI escape codes from string
|
|
143
|
-
*/
|
|
144
5
|
declare function stripAnsi(str: string): string;
|
|
145
6
|
/**
|
|
146
|
-
* Calculate
|
|
147
|
-
* - ANSI escape codes (width 0)
|
|
148
|
-
* - CJK ideographs & fullwidth forms (width 2)
|
|
149
|
-
* - Japanese Kana (width 2)
|
|
150
|
-
* - Korean Hangul syllables & Jamo (width 2)
|
|
151
|
-
* - Emojis & Pictographs (width 2)
|
|
152
|
-
* - Zero-width characters & joiners (width 0)
|
|
153
|
-
* - Standard ASCII (width 1)
|
|
7
|
+
* Calculate visual terminal column width (CJK/Kana/Hangul/Emoji = 2 cells, ASCII = 1 cell)
|
|
154
8
|
*/
|
|
155
9
|
declare function getDisplayWidth(str: string): number;
|
|
156
10
|
declare function hasActiveUI(ctx: ExtensionContext | null | undefined): ctx is ExtensionContext;
|
|
157
|
-
/**
|
|
158
|
-
* Truncate string to target terminal visual width with ellipsis
|
|
159
|
-
*/
|
|
160
11
|
declare function truncateToWidth(str: string, maxWidth: number, ellipsis?: string): string;
|
|
161
|
-
/**
|
|
162
|
-
* Pad and/or truncate string to exact visual column width, eliminating column tearing
|
|
163
|
-
*/
|
|
164
12
|
declare function padToWidth(str: string, targetWidth: number): string;
|
|
165
13
|
/**
|
|
166
|
-
* Format
|
|
167
|
-
* - 'Daily' for daily recurring habits
|
|
168
|
-
* - 'Today' if targetDate is today
|
|
169
|
-
* - 'Tomorrow' if targetDate is tomorrow
|
|
170
|
-
* - 'In 2d' / 'In 3d' for near-term dates
|
|
171
|
-
* - 'MM-DD' for future dates
|
|
172
|
-
* - 'Overdue' if targetDate is past
|
|
173
|
-
* - 'Someday' for open-ended architecture/long-term vision
|
|
174
|
-
*/
|
|
175
|
-
declare function formatTargetDate(anchor: Anchor, now?: number): string;
|
|
176
|
-
/**
|
|
177
|
-
* Format creation timestamp as concise date/time:
|
|
178
|
-
* - 'Today HH:MM' if created today
|
|
179
|
-
* - 'Yesterday HH:MM' if created yesterday
|
|
180
|
-
* - 'MM-DD HH:MM' if created this year
|
|
181
|
-
* - 'YYYY-MM-DD' if older
|
|
182
|
-
*/
|
|
183
|
-
declare function formatCreationTime(timestamp: number, now?: number): string;
|
|
184
|
-
/**
|
|
185
|
-
* Backward compatibility alias
|
|
14
|
+
* Format relative sticky-note age cleanly: 'just now', '15m ago', '3h ago', '2d ago'
|
|
186
15
|
*/
|
|
187
|
-
declare function
|
|
16
|
+
declare function formatRelativeAge(timestamp: number, now?: number): string;
|
|
188
17
|
/**
|
|
189
|
-
*
|
|
18
|
+
* Format workspace & first file context concisely (e.g. 'anchor · src/auth.ts' or 'College/优化')
|
|
190
19
|
*/
|
|
191
|
-
declare function
|
|
20
|
+
declare function formatOrigin(anchor: Anchor | string): string;
|
|
192
21
|
/**
|
|
193
|
-
*
|
|
22
|
+
* Sort sticky notes naturally:
|
|
23
|
+
* 1. Active notes before quiet (>7d untouched) notes
|
|
24
|
+
* 2. Notes belonging to current workspace first
|
|
25
|
+
* 3. Most recently touched first
|
|
194
26
|
*/
|
|
195
|
-
declare function
|
|
27
|
+
declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string): Anchor[];
|
|
196
28
|
/**
|
|
197
|
-
* Update
|
|
29
|
+
* Update status bar badge: `⌖ 2` (invisible when 0 active notes)
|
|
198
30
|
*/
|
|
199
31
|
declare function updateAnchorStatusBar(ctx: ExtensionContext, store: AnchorStore): void;
|
|
200
32
|
/**
|
|
201
|
-
* Render
|
|
202
|
-
*
|
|
203
|
-
* Automatically cleared on agent_start (when user sends first message).
|
|
33
|
+
* Render clean sticky-note card above editor on session startup.
|
|
34
|
+
* Automatically disappears as soon as the user sends their first message.
|
|
204
35
|
*/
|
|
205
36
|
declare function updateStartupBanner(ctx: ExtensionContext, store: AnchorStore): void;
|
|
206
37
|
/**
|
|
207
|
-
*
|
|
38
|
+
* Interactive `/anchor` sticky-note board
|
|
208
39
|
*/
|
|
209
40
|
declare function openAnchorDashboard(ctx: ExtensionContext, store: AnchorStore): Promise<void>;
|
|
210
41
|
|
|
211
|
-
|
|
212
|
-
* Universal multi-language comment generator.
|
|
213
|
-
* Maps file extension to safe comment syntax.
|
|
214
|
-
* Formats that do not safely support comments (e.g. .json, .env, binary) return null.
|
|
215
|
-
*/
|
|
216
|
-
declare const COMMENT_FORMATS: Record<string, (msg: string) => string>;
|
|
217
|
-
/**
|
|
218
|
-
* Format safe task context comment for a specific file.
|
|
219
|
-
* Returns null for formats that do not safely support comments (e.g. .json, .env, .lock)
|
|
220
|
-
*/
|
|
221
|
-
declare function makeSafeTaskAnnotation(filePath: string, anchor: Anchor): string | null;
|
|
222
|
-
/**
|
|
223
|
-
* Render ultra-compact cold-start context block for session turn 1.
|
|
224
|
-
* Only active anchors for the current project context are injected.
|
|
225
|
-
* From turn 2 onwards, this returns empty string (0 tokens).
|
|
226
|
-
*/
|
|
227
|
-
declare function renderColdStartAnchorsContext(store: AnchorStore, cwdOrNow?: string | number, nowArg?: number, preflightFailures?: Map<string, string>): string;
|
|
228
|
-
/** Legacy alias for backwards compatibility */
|
|
229
|
-
declare const renderActiveAnchorsContext: typeof renderColdStartAnchorsContext;
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Universal Agent Adapter Interface.
|
|
233
|
-
* Any AI coding harness (Pi, Claude Code, Cursor, Aider, custom MCP server) implements this thin layer.
|
|
234
|
-
*/
|
|
235
|
-
interface AgentAdapter {
|
|
236
|
-
readonly name: string;
|
|
237
|
-
getCwd(): string;
|
|
238
|
-
notify?(message: string, level: 'info' | 'warn' | 'error'): void;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Anchor protocol engine for cross-session task management.
|
|
242
|
-
* Decoupled, harness-agnostic core managing state, decay, JIT annotations, and settlement.
|
|
243
|
-
*/
|
|
244
|
-
declare class AnchorProtocol {
|
|
245
|
-
readonly store: AnchorStore;
|
|
246
|
-
readonly observer: SessionTouchObserver;
|
|
247
|
-
private readonly annotatedThisSession;
|
|
248
|
-
constructor(store: AnchorStore);
|
|
249
|
-
/**
|
|
250
|
-
* Run session initialization lifecycle: sweeps stale anchors and resets session state
|
|
251
|
-
*/
|
|
252
|
-
handleSessionStart(now?: number): {
|
|
253
|
-
sleepingCount: number;
|
|
254
|
-
};
|
|
255
|
-
/**
|
|
256
|
-
* Handle turn lifecycle: injects cold-start prompt on turn 1, returns null (0 tokens) on turn 2+
|
|
257
|
-
*/
|
|
258
|
-
handleBeforeTurn(turnCount: number, cwd: string, now?: number): string | null;
|
|
259
|
-
/**
|
|
260
|
-
* Handle tool execution result: detects touched paths, refreshes mutation touch timers,
|
|
261
|
-
* and returns safe language-specific JIT annotation (or null if syntax incompatible/already annotated).
|
|
262
|
-
*/
|
|
263
|
-
handleToolResult(input: {
|
|
264
|
-
toolName: string;
|
|
265
|
-
filePath?: string;
|
|
266
|
-
isError?: boolean;
|
|
267
|
-
isMutation?: boolean;
|
|
268
|
-
cwd: string;
|
|
269
|
-
}): {
|
|
270
|
-
annotation: string | null;
|
|
271
|
-
matchedAnchors: Anchor[];
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
export { type AgentAdapter, Anchor, AnchorProtocol, type AnchorQuadrant, AnchorStatus, AnchorStore, COMMENT_FORMATS, type DecayEvaluation, type GroupedAnchors, SessionTouchObserver, SettlementProposal, type SweepResult, TouchMatchResult, classifyAnchor, evaluateAnchorDecay, extractPathsFromText, findMatchedAnchors, formatCreationTime, formatOrigin, formatRelativeTime, formatRemainingTtl, formatSettlementCard, formatTargetDate, generateSettlementProposals, getDisplayWidth, globToRegExp, groupAnchorsByQuadrant, hasActiveUI, isAnchorTargetingWorkspace, isSameOrSubPath, makeSafeTaskAnnotation, matchAnchorAgainstTouchedFiles, normalizePath, openAnchorDashboard, padToWidth, renderActiveAnchorsContext, renderColdStartAnchorsContext, runPhysicalVerification, sortAnchorsForDisplay, stripAnsi, sweepStore, truncateToWidth, tryRealtimeAutoSettle, updateAnchorStatusBar, updateStartupBanner };
|
|
42
|
+
export { Anchor, AnchorStore, formatOrigin, formatRelativeAge, getDisplayWidth, hasActiveUI, openAnchorDashboard, padToWidth, sortAnchorsForDisplay, stripAnsi, truncateToWidth, updateAnchorStatusBar, updateStartupBanner };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,275 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { c as
|
|
1
|
+
import { A as Anchor, a as AnchorStore } from './extension-B1-fzCox.js';
|
|
2
|
+
export { b as AnchorEvidence, c as AnchorPriority, d as AnchorStatus, e as AnchorStoreState, C as COMMENT_FORMATS, M as MS_PER_DAY, Q as QUIET_AFTER_DAYS, T as TouchMatchResult, f as acquireSyncLock, g as atomicRenameWithRetry, h as extractPathsFromText, i as findMatchedAnchors, j as getDefaultStorageDir, k as globToRegExp, l as isAnchorTargetingWorkspace, m as isSameOrSubPath, n as makeSafeTaskAnnotation, o as matchAnchorAgainstTouchedFiles, p as matchesCommitMessage, q as normalizePath, r as parseAnchorCommandInput, s as renderActiveAnchorsContext, t as renderColdStartAnchorsContext, u as resolveAnchorTarget, v as sweepQuietNotes } from './extension-B1-fzCox.js';
|
|
3
3
|
import { ExtensionContext } from '@earendil-works/pi-coding-agent';
|
|
4
4
|
|
|
5
|
-
interface DecayEvaluation {
|
|
6
|
-
currentStatus: AnchorStatus;
|
|
7
|
-
nextStatus: AnchorStatus;
|
|
8
|
-
daysUntouched: number;
|
|
9
|
-
remainingActiveDays: number;
|
|
10
|
-
remainingSleepDays: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Calculate precise decay status based on elapsed time since last touch
|
|
14
|
-
*/
|
|
15
|
-
declare function evaluateAnchorDecay(anchor: Anchor, now?: number): DecayEvaluation;
|
|
16
|
-
interface SweepResult {
|
|
17
|
-
transitionedToSleeping: string[];
|
|
18
|
-
wokenToActive: string[];
|
|
19
|
-
evictedToGraveyard: string[];
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Run decay sweep across store: transitions statuses and evicts expired anchors
|
|
23
|
-
*/
|
|
24
|
-
declare function sweepStore(store: AnchorStore, now?: number): SweepResult;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Convert simple glob pattern (e.g. *.ts, src/**\/*.ts, src/auth/*.ts) to RegExp
|
|
28
|
-
*/
|
|
29
|
-
declare function globToRegExp(pattern: string): RegExp;
|
|
30
|
-
/**
|
|
31
|
-
* Normalize path separators to POSIX forward slashes and optionally relative to baseCwd
|
|
32
|
-
*/
|
|
33
|
-
declare function normalizePath(filePath: string, baseCwd?: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Compare two workspace CWDs safely (case-insensitive on Windows, supports subdirectory scoping)
|
|
36
|
-
*/
|
|
37
|
-
declare function isSameOrSubPath(anchorCwd?: string, targetCwd?: string): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Extract explicit file or directory paths mentioned in natural language title/description
|
|
40
|
-
* (e.g. "D:/College/优化/EXTERNAL_ARCHITECTURE_INSPIRATIONS.md", "src/auth/jwt.ts")
|
|
41
|
-
*/
|
|
42
|
-
declare function extractPathsFromText(text?: string): string[];
|
|
43
|
-
/**
|
|
44
|
-
* Determine whether an anchor specifically targets a given workspace directory (`targetCwd`),
|
|
45
|
-
* checking `anchor.cwd`, `anchor.project`, and `anchor.files`.
|
|
46
|
-
*/
|
|
47
|
-
declare function isAnchorTargetingWorkspace(anchor: Anchor, targetCwd?: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Match touched files against an anchor's registered physical patterns
|
|
50
|
-
* Only anchors with explicit files/globs/prefixes are matched against file touches.
|
|
51
|
-
* Anchors with files: [] (pure mental notes or macro tasks) NEVER trigger on file operations.
|
|
52
|
-
*/
|
|
53
|
-
declare function matchAnchorAgainstTouchedFiles(anchor: Anchor, touchedFiles: string[]): TouchMatchResult | null;
|
|
54
|
-
/**
|
|
55
|
-
* Filter and sort anchors that match a set of touched files
|
|
56
|
-
* Prioritizes high confidence (exact > prefix > keyword) and priority (P0 > P1 > P2).
|
|
57
|
-
*/
|
|
58
|
-
declare function findMatchedAnchors(anchors: Anchor[], touchedFiles: string[]): TouchMatchResult[];
|
|
59
|
-
|
|
60
|
-
declare class SessionTouchObserver {
|
|
61
|
-
private touchedFiles;
|
|
62
|
-
private modifiedFiles;
|
|
63
|
-
private inspectedFiles;
|
|
64
|
-
private committed;
|
|
65
|
-
private commitMessages;
|
|
66
|
-
clear(): void;
|
|
67
|
-
/**
|
|
68
|
-
* Observe and record a tool call invocation, separating inspection from mutation
|
|
69
|
-
*/
|
|
70
|
-
recordToolCall(toolName: string, input: Record<string, unknown>): void;
|
|
71
|
-
/**
|
|
72
|
-
* Add a file path manually (e.g. from git status diff)
|
|
73
|
-
*/
|
|
74
|
-
addTouchedFile(filePath: string, isModified?: boolean): void;
|
|
75
|
-
getModifiedFiles(): string[];
|
|
76
|
-
getInspectedFiles(): string[];
|
|
77
|
-
getTouchedFiles(): string[];
|
|
78
|
-
hasCommitted(): boolean;
|
|
79
|
-
getCommitMessages(): string[];
|
|
80
|
-
/**
|
|
81
|
-
* Check if any commit message explicitly references or resolves an anchor
|
|
82
|
-
*/
|
|
83
|
-
matchesCommit(anchor: Anchor): {
|
|
84
|
-
matched: boolean;
|
|
85
|
-
message?: string;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Execute physical verification test command for an anchor
|
|
91
|
-
*/
|
|
92
|
-
declare function runPhysicalVerification(anchor: Anchor, cwd: string): {
|
|
93
|
-
success: boolean;
|
|
94
|
-
output: string;
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Real-time autonomous settlement during active session:
|
|
98
|
-
* Triggered immediately when a non-error shell command runs `git commit` or a matching `verifyCommand`.
|
|
99
|
-
* Works for BOTH file-bound and file-less (`files: []`) anchors!
|
|
100
|
-
*/
|
|
101
|
-
declare function tryRealtimeAutoSettle(store: AnchorStore, observer: SessionTouchObserver, cwd?: string, executedCommand?: string): Array<{
|
|
102
|
-
anchor: Anchor;
|
|
103
|
-
reason: string;
|
|
104
|
-
}>;
|
|
105
|
-
/**
|
|
106
|
-
* Generate settlement candidates based on files touched or commits made during the session
|
|
107
|
-
*/
|
|
108
|
-
declare function generateSettlementProposals(store: AnchorStore, touchedFiles: string[], cwd?: string, observer?: SessionTouchObserver): SettlementProposal[];
|
|
109
|
-
/**
|
|
110
|
-
* Format settlement proposal into terminal-ready card
|
|
111
|
-
*/
|
|
112
|
-
declare function formatSettlementCard(proposal: SettlementProposal): string;
|
|
113
|
-
|
|
114
|
-
type AnchorQuadrant = 'Today' | 'Upcoming' | 'Habits' | 'Backlog';
|
|
115
|
-
interface GroupedAnchors {
|
|
116
|
-
today: Anchor[];
|
|
117
|
-
upcoming: Anchor[];
|
|
118
|
-
habits: Anchor[];
|
|
119
|
-
backlog: Anchor[];
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Classify anchor into one of four cognitive quadrants:
|
|
123
|
-
* - 'Today': Due today or overdue
|
|
124
|
-
* - 'Upcoming': Due in the future (tomorrow, in 2d, specific dates)
|
|
125
|
-
* - 'Habits': Daily recurring habits
|
|
126
|
-
* - 'Backlog': Open-ended long-term vision
|
|
127
|
-
*/
|
|
128
|
-
declare function classifyAnchor(anchor: Anchor, now?: number): AnchorQuadrant;
|
|
129
|
-
/**
|
|
130
|
-
* Group active anchors by cognitive quadrant
|
|
131
|
-
*/
|
|
132
|
-
declare function groupAnchorsByQuadrant(anchors: Anchor[], now?: number): GroupedAnchors;
|
|
133
|
-
/**
|
|
134
|
-
* Sort unfinished anchors into a single compact, priority-driven engineering list:
|
|
135
|
-
* 1. Active before Sleeping (quiet)
|
|
136
|
-
* 2. Matching current workspace before other workspaces
|
|
137
|
-
* 3. Due Today / Overdue before open-ended
|
|
138
|
-
* 4. Priority (P0 -> P1 -> P2)
|
|
139
|
-
*/
|
|
140
|
-
declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string, now?: number): Anchor[];
|
|
141
|
-
/**
|
|
142
|
-
* Strip ANSI escape codes from string
|
|
143
|
-
*/
|
|
144
5
|
declare function stripAnsi(str: string): string;
|
|
145
6
|
/**
|
|
146
|
-
* Calculate
|
|
147
|
-
* - ANSI escape codes (width 0)
|
|
148
|
-
* - CJK ideographs & fullwidth forms (width 2)
|
|
149
|
-
* - Japanese Kana (width 2)
|
|
150
|
-
* - Korean Hangul syllables & Jamo (width 2)
|
|
151
|
-
* - Emojis & Pictographs (width 2)
|
|
152
|
-
* - Zero-width characters & joiners (width 0)
|
|
153
|
-
* - Standard ASCII (width 1)
|
|
7
|
+
* Calculate visual terminal column width (CJK/Kana/Hangul/Emoji = 2 cells, ASCII = 1 cell)
|
|
154
8
|
*/
|
|
155
9
|
declare function getDisplayWidth(str: string): number;
|
|
156
10
|
declare function hasActiveUI(ctx: ExtensionContext | null | undefined): ctx is ExtensionContext;
|
|
157
|
-
/**
|
|
158
|
-
* Truncate string to target terminal visual width with ellipsis
|
|
159
|
-
*/
|
|
160
11
|
declare function truncateToWidth(str: string, maxWidth: number, ellipsis?: string): string;
|
|
161
|
-
/**
|
|
162
|
-
* Pad and/or truncate string to exact visual column width, eliminating column tearing
|
|
163
|
-
*/
|
|
164
12
|
declare function padToWidth(str: string, targetWidth: number): string;
|
|
165
13
|
/**
|
|
166
|
-
* Format
|
|
167
|
-
* - 'Daily' for daily recurring habits
|
|
168
|
-
* - 'Today' if targetDate is today
|
|
169
|
-
* - 'Tomorrow' if targetDate is tomorrow
|
|
170
|
-
* - 'In 2d' / 'In 3d' for near-term dates
|
|
171
|
-
* - 'MM-DD' for future dates
|
|
172
|
-
* - 'Overdue' if targetDate is past
|
|
173
|
-
* - 'Someday' for open-ended architecture/long-term vision
|
|
174
|
-
*/
|
|
175
|
-
declare function formatTargetDate(anchor: Anchor, now?: number): string;
|
|
176
|
-
/**
|
|
177
|
-
* Format creation timestamp as concise date/time:
|
|
178
|
-
* - 'Today HH:MM' if created today
|
|
179
|
-
* - 'Yesterday HH:MM' if created yesterday
|
|
180
|
-
* - 'MM-DD HH:MM' if created this year
|
|
181
|
-
* - 'YYYY-MM-DD' if older
|
|
182
|
-
*/
|
|
183
|
-
declare function formatCreationTime(timestamp: number, now?: number): string;
|
|
184
|
-
/**
|
|
185
|
-
* Backward compatibility alias
|
|
14
|
+
* Format relative sticky-note age cleanly: 'just now', '15m ago', '3h ago', '2d ago'
|
|
186
15
|
*/
|
|
187
|
-
declare function
|
|
16
|
+
declare function formatRelativeAge(timestamp: number, now?: number): string;
|
|
188
17
|
/**
|
|
189
|
-
*
|
|
18
|
+
* Format workspace & first file context concisely (e.g. 'anchor · src/auth.ts' or 'College/优化')
|
|
190
19
|
*/
|
|
191
|
-
declare function
|
|
20
|
+
declare function formatOrigin(anchor: Anchor | string): string;
|
|
192
21
|
/**
|
|
193
|
-
*
|
|
22
|
+
* Sort sticky notes naturally:
|
|
23
|
+
* 1. Active notes before quiet (>7d untouched) notes
|
|
24
|
+
* 2. Notes belonging to current workspace first
|
|
25
|
+
* 3. Most recently touched first
|
|
194
26
|
*/
|
|
195
|
-
declare function
|
|
27
|
+
declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string): Anchor[];
|
|
196
28
|
/**
|
|
197
|
-
* Update
|
|
29
|
+
* Update status bar badge: `⌖ 2` (invisible when 0 active notes)
|
|
198
30
|
*/
|
|
199
31
|
declare function updateAnchorStatusBar(ctx: ExtensionContext, store: AnchorStore): void;
|
|
200
32
|
/**
|
|
201
|
-
* Render
|
|
202
|
-
*
|
|
203
|
-
* Automatically cleared on agent_start (when user sends first message).
|
|
33
|
+
* Render clean sticky-note card above editor on session startup.
|
|
34
|
+
* Automatically disappears as soon as the user sends their first message.
|
|
204
35
|
*/
|
|
205
36
|
declare function updateStartupBanner(ctx: ExtensionContext, store: AnchorStore): void;
|
|
206
37
|
/**
|
|
207
|
-
*
|
|
38
|
+
* Interactive `/anchor` sticky-note board
|
|
208
39
|
*/
|
|
209
40
|
declare function openAnchorDashboard(ctx: ExtensionContext, store: AnchorStore): Promise<void>;
|
|
210
41
|
|
|
211
|
-
|
|
212
|
-
* Universal multi-language comment generator.
|
|
213
|
-
* Maps file extension to safe comment syntax.
|
|
214
|
-
* Formats that do not safely support comments (e.g. .json, .env, binary) return null.
|
|
215
|
-
*/
|
|
216
|
-
declare const COMMENT_FORMATS: Record<string, (msg: string) => string>;
|
|
217
|
-
/**
|
|
218
|
-
* Format safe task context comment for a specific file.
|
|
219
|
-
* Returns null for formats that do not safely support comments (e.g. .json, .env, .lock)
|
|
220
|
-
*/
|
|
221
|
-
declare function makeSafeTaskAnnotation(filePath: string, anchor: Anchor): string | null;
|
|
222
|
-
/**
|
|
223
|
-
* Render ultra-compact cold-start context block for session turn 1.
|
|
224
|
-
* Only active anchors for the current project context are injected.
|
|
225
|
-
* From turn 2 onwards, this returns empty string (0 tokens).
|
|
226
|
-
*/
|
|
227
|
-
declare function renderColdStartAnchorsContext(store: AnchorStore, cwdOrNow?: string | number, nowArg?: number, preflightFailures?: Map<string, string>): string;
|
|
228
|
-
/** Legacy alias for backwards compatibility */
|
|
229
|
-
declare const renderActiveAnchorsContext: typeof renderColdStartAnchorsContext;
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Universal Agent Adapter Interface.
|
|
233
|
-
* Any AI coding harness (Pi, Claude Code, Cursor, Aider, custom MCP server) implements this thin layer.
|
|
234
|
-
*/
|
|
235
|
-
interface AgentAdapter {
|
|
236
|
-
readonly name: string;
|
|
237
|
-
getCwd(): string;
|
|
238
|
-
notify?(message: string, level: 'info' | 'warn' | 'error'): void;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Anchor protocol engine for cross-session task management.
|
|
242
|
-
* Decoupled, harness-agnostic core managing state, decay, JIT annotations, and settlement.
|
|
243
|
-
*/
|
|
244
|
-
declare class AnchorProtocol {
|
|
245
|
-
readonly store: AnchorStore;
|
|
246
|
-
readonly observer: SessionTouchObserver;
|
|
247
|
-
private readonly annotatedThisSession;
|
|
248
|
-
constructor(store: AnchorStore);
|
|
249
|
-
/**
|
|
250
|
-
* Run session initialization lifecycle: sweeps stale anchors and resets session state
|
|
251
|
-
*/
|
|
252
|
-
handleSessionStart(now?: number): {
|
|
253
|
-
sleepingCount: number;
|
|
254
|
-
};
|
|
255
|
-
/**
|
|
256
|
-
* Handle turn lifecycle: injects cold-start prompt on turn 1, returns null (0 tokens) on turn 2+
|
|
257
|
-
*/
|
|
258
|
-
handleBeforeTurn(turnCount: number, cwd: string, now?: number): string | null;
|
|
259
|
-
/**
|
|
260
|
-
* Handle tool execution result: detects touched paths, refreshes mutation touch timers,
|
|
261
|
-
* and returns safe language-specific JIT annotation (or null if syntax incompatible/already annotated).
|
|
262
|
-
*/
|
|
263
|
-
handleToolResult(input: {
|
|
264
|
-
toolName: string;
|
|
265
|
-
filePath?: string;
|
|
266
|
-
isError?: boolean;
|
|
267
|
-
isMutation?: boolean;
|
|
268
|
-
cwd: string;
|
|
269
|
-
}): {
|
|
270
|
-
annotation: string | null;
|
|
271
|
-
matchedAnchors: Anchor[];
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
export { type AgentAdapter, Anchor, AnchorProtocol, type AnchorQuadrant, AnchorStatus, AnchorStore, COMMENT_FORMATS, type DecayEvaluation, type GroupedAnchors, SessionTouchObserver, SettlementProposal, type SweepResult, TouchMatchResult, classifyAnchor, evaluateAnchorDecay, extractPathsFromText, findMatchedAnchors, formatCreationTime, formatOrigin, formatRelativeTime, formatRemainingTtl, formatSettlementCard, formatTargetDate, generateSettlementProposals, getDisplayWidth, globToRegExp, groupAnchorsByQuadrant, hasActiveUI, isAnchorTargetingWorkspace, isSameOrSubPath, makeSafeTaskAnnotation, matchAnchorAgainstTouchedFiles, normalizePath, openAnchorDashboard, padToWidth, renderActiveAnchorsContext, renderColdStartAnchorsContext, runPhysicalVerification, sortAnchorsForDisplay, stripAnsi, sweepStore, truncateToWidth, tryRealtimeAutoSettle, updateAnchorStatusBar, updateStartupBanner };
|
|
42
|
+
export { Anchor, AnchorStore, formatOrigin, formatRelativeAge, getDisplayWidth, hasActiveUI, openAnchorDashboard, padToWidth, sortAnchorsForDisplay, stripAnsi, truncateToWidth, updateAnchorStatusBar, updateStartupBanner };
|