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/dist/index.d.cts CHANGED
@@ -1,275 +1,42 @@
1
- import { a as AnchorStatus, b as Anchor, A as AnchorStore, T as TouchMatchResult, S as SettlementProposal } from './store-t2_TDhJn.cjs';
2
- export { c as AnchorDecayPolicy, d as AnchorDurability, e as AnchorEvidence, f as AnchorPriority, g as AnchorStoreState, D as DEFAULT_DECAY_POLICY, h as DURABLE_DECAY_POLICY, E as EPHEMERAL_DECAY_POLICY, i as acquireSyncLock, j as atomicRenameWithRetry, k as detectDurability, l as detectRecurrence, m as detectTargetDate, n as getDefaultStorageDir, o as getEphemeralDecayPolicy, p as getTodayDateString } from './store-t2_TDhJn.cjs';
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 display width in terminal columns, accounting for:
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 expected completion date in human-intuitive terms:
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 formatRelativeTime(timestamp: number, now?: number): string;
16
+ declare function formatRelativeAge(timestamp: number, now?: number): string;
188
17
  /**
189
- * Backward compatibility alias (now returns target date representation)
18
+ * Format workspace & first file context concisely (e.g. 'anchor · src/auth.ts' or 'College/优化')
190
19
  */
191
- declare function formatRemainingTtl(anchor: Anchor, now?: number): string | undefined;
20
+ declare function formatOrigin(anchor: Anchor | string): string;
192
21
  /**
193
- * Format origin workspace / project label concisely
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 formatOrigin(anchor: Anchor | string): string;
27
+ declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string): Anchor[];
196
28
  /**
197
- * Update footer status bar capsule: `⌖ 1`
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 lightweight startup banner widget above the editor.
202
- * Features 3-4 lines with quadrant badges and target date hints.
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
- * Clean, flat priority-sorted engineering checklist (includes both active and quiet/sleeping tasks so nothing is ever lost)
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 { a as AnchorStatus, b as Anchor, A as AnchorStore, T as TouchMatchResult, S as SettlementProposal } from './store-t2_TDhJn.js';
2
- export { c as AnchorDecayPolicy, d as AnchorDurability, e as AnchorEvidence, f as AnchorPriority, g as AnchorStoreState, D as DEFAULT_DECAY_POLICY, h as DURABLE_DECAY_POLICY, E as EPHEMERAL_DECAY_POLICY, i as acquireSyncLock, j as atomicRenameWithRetry, k as detectDurability, l as detectRecurrence, m as detectTargetDate, n as getDefaultStorageDir, o as getEphemeralDecayPolicy, p as getTodayDateString } from './store-t2_TDhJn.js';
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 display width in terminal columns, accounting for:
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 expected completion date in human-intuitive terms:
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 formatRelativeTime(timestamp: number, now?: number): string;
16
+ declare function formatRelativeAge(timestamp: number, now?: number): string;
188
17
  /**
189
- * Backward compatibility alias (now returns target date representation)
18
+ * Format workspace & first file context concisely (e.g. 'anchor · src/auth.ts' or 'College/优化')
190
19
  */
191
- declare function formatRemainingTtl(anchor: Anchor, now?: number): string | undefined;
20
+ declare function formatOrigin(anchor: Anchor | string): string;
192
21
  /**
193
- * Format origin workspace / project label concisely
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 formatOrigin(anchor: Anchor | string): string;
27
+ declare function sortAnchorsForDisplay(anchors: Anchor[], cwd?: string): Anchor[];
196
28
  /**
197
- * Update footer status bar capsule: `⌖ 1`
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 lightweight startup banner widget above the editor.
202
- * Features 3-4 lines with quadrant badges and target date hints.
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
- * Clean, flat priority-sorted engineering checklist (includes both active and quiet/sleeping tasks so nothing is ever lost)
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 };