k0ntext 3.7.0 → 3.8.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 +281 -382
- package/dist/agent-system/timestamp-tracker.d.ts +159 -0
- package/dist/agent-system/timestamp-tracker.d.ts.map +1 -0
- package/dist/agent-system/timestamp-tracker.js +405 -0
- package/dist/agent-system/timestamp-tracker.js.map +1 -0
- package/dist/agent-system/todolist-manager.d.ts +244 -0
- package/dist/agent-system/todolist-manager.d.ts.map +1 -0
- package/dist/agent-system/todolist-manager.js +580 -0
- package/dist/agent-system/todolist-manager.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +28 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +408 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/version/comparator.d.ts +1 -0
- package/dist/cli/version/comparator.d.ts.map +1 -1
- package/dist/cli/version/comparator.js +1 -0
- package/dist/cli/version/comparator.js.map +1 -1
- package/dist/db/client.d.ts +5 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +7 -0
- package/dist/db/client.js.map +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +1 -1
- package/dist/services/snapshot-manager.d.ts +251 -0
- package/dist/services/snapshot-manager.d.ts.map +1 -0
- package/dist/services/snapshot-manager.js +541 -0
- package/dist/services/snapshot-manager.js.map +1 -0
- package/docs/QUICKSTART.md +1 -1
- package/docs/TROUBLESHOOTING.md +51 -76
- package/docs/plans/2026-02-11-context-engineering-enhancement.md +1402 -0
- package/package.json +8 -2
- package/src/agent-system/timestamp-tracker.ts +520 -0
- package/src/agent-system/todolist-manager.ts +753 -0
- package/src/cli/commands/snapshot.ts +471 -0
- package/src/cli/version/comparator.ts +1 -0
- package/src/db/client.ts +8 -0
- package/src/db/migrations/0016_add_context_system_tables.sql +38 -0
- package/src/db/schema.ts +1 -1
- package/src/services/snapshot-manager.ts +719 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timestamp Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks file timestamps for synchronization and drift detection.
|
|
5
|
+
* Stores and retrieves file modification times from the database.
|
|
6
|
+
*/
|
|
7
|
+
import type { DatabaseClient } from '../db/client.js';
|
|
8
|
+
/**
|
|
9
|
+
* File timestamp record
|
|
10
|
+
*/
|
|
11
|
+
export interface FileTimestamp {
|
|
12
|
+
/** Relative file path from project root */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Last modified time from filesystem */
|
|
15
|
+
modifiedTime: string;
|
|
16
|
+
/** File size in bytes */
|
|
17
|
+
size: number;
|
|
18
|
+
/** SHA-256 hash of file contents */
|
|
19
|
+
hash: string;
|
|
20
|
+
/** When timestamp was last checked */
|
|
21
|
+
lastChecked: string;
|
|
22
|
+
/** Git commit SHA if available */
|
|
23
|
+
gitCommit?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Timestamp tracker options
|
|
27
|
+
*/
|
|
28
|
+
export interface TimestampTrackerOptions {
|
|
29
|
+
/** Project root directory */
|
|
30
|
+
projectRoot?: string;
|
|
31
|
+
/** Verbose logging */
|
|
32
|
+
verbose?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sync status for a file
|
|
36
|
+
*/
|
|
37
|
+
export interface SyncStatus {
|
|
38
|
+
/** File path */
|
|
39
|
+
path: string;
|
|
40
|
+
/** Whether file is in sync */
|
|
41
|
+
inSync: boolean;
|
|
42
|
+
/** Expected vs actual modified time */
|
|
43
|
+
timeDiff?: number;
|
|
44
|
+
/** Expected vs actual hash */
|
|
45
|
+
hashDiff?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Timestamp Tracker
|
|
49
|
+
*
|
|
50
|
+
* Manages file timestamps for synchronization tracking.
|
|
51
|
+
*/
|
|
52
|
+
export declare class TimestampTracker {
|
|
53
|
+
private db;
|
|
54
|
+
private projectRoot;
|
|
55
|
+
private verbose;
|
|
56
|
+
constructor(db: DatabaseClient, options?: TimestampTrackerOptions);
|
|
57
|
+
/**
|
|
58
|
+
* Record file timestamp
|
|
59
|
+
*
|
|
60
|
+
* @param filePath - Relative or absolute file path
|
|
61
|
+
* @param gitCommit - Optional git commit SHA
|
|
62
|
+
*/
|
|
63
|
+
recordTimestamp(filePath: string, gitCommit?: string): Promise<FileTimestamp | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Get stored timestamp for a file
|
|
66
|
+
*
|
|
67
|
+
* @param filePath - Relative or absolute file path
|
|
68
|
+
* @returns Timestamp record or null
|
|
69
|
+
*/
|
|
70
|
+
getTimestamp(filePath: string): Promise<FileTimestamp | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Check if file is in sync
|
|
73
|
+
*
|
|
74
|
+
* Compares current file state with stored timestamp.
|
|
75
|
+
*
|
|
76
|
+
* @param filePath - Relative or absolute file path
|
|
77
|
+
* @returns Sync status
|
|
78
|
+
*/
|
|
79
|
+
checkSync(filePath: string): Promise<SyncStatus>;
|
|
80
|
+
/**
|
|
81
|
+
* Check multiple files for sync status
|
|
82
|
+
*
|
|
83
|
+
* @param filePaths - Array of file paths
|
|
84
|
+
* @returns Array of sync statuses
|
|
85
|
+
*/
|
|
86
|
+
checkMultipleSync(filePaths: string[]): Promise<SyncStatus[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Update timestamp for a file
|
|
89
|
+
*
|
|
90
|
+
* @param filePath - Relative or absolute file path
|
|
91
|
+
* @param gitCommit - Optional git commit SHA
|
|
92
|
+
*/
|
|
93
|
+
updateTimestamp(filePath: string, gitCommit?: string): Promise<FileTimestamp | null>;
|
|
94
|
+
/**
|
|
95
|
+
* Batch update timestamps for multiple files
|
|
96
|
+
*
|
|
97
|
+
* @param filePaths - Array of file paths
|
|
98
|
+
* @returns Array of updated timestamps
|
|
99
|
+
*/
|
|
100
|
+
batchUpdateTimestamps(filePaths: string[]): Promise<FileTimestamp[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Remove timestamp record
|
|
103
|
+
*
|
|
104
|
+
* @param filePath - File path to remove
|
|
105
|
+
*/
|
|
106
|
+
removeTimestamp(filePath: string): Promise<boolean>;
|
|
107
|
+
/**
|
|
108
|
+
* Get all tracked timestamps
|
|
109
|
+
*
|
|
110
|
+
* @returns Array of all timestamp records
|
|
111
|
+
*/
|
|
112
|
+
getAllTimestamps(): Promise<FileTimestamp[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Get stale timestamp records
|
|
115
|
+
*
|
|
116
|
+
* @param daysOld - Consider records older than this many days as stale
|
|
117
|
+
* @returns Array of stale timestamps
|
|
118
|
+
*/
|
|
119
|
+
getStaleTimestamps(daysOld?: number): Promise<FileTimestamp[]>;
|
|
120
|
+
/**
|
|
121
|
+
* Clean up old timestamp records
|
|
122
|
+
*
|
|
123
|
+
* @param daysOld - Remove records older than this many days
|
|
124
|
+
* @returns Number of records removed
|
|
125
|
+
*/
|
|
126
|
+
cleanupOldTimestamps(daysOld?: number): Promise<number>;
|
|
127
|
+
/**
|
|
128
|
+
* Get sync summary for tracked files
|
|
129
|
+
*
|
|
130
|
+
* @returns Summary of sync status
|
|
131
|
+
*/
|
|
132
|
+
getSyncSummary(): Promise<{
|
|
133
|
+
total: number;
|
|
134
|
+
inSync: number;
|
|
135
|
+
outOfSync: number;
|
|
136
|
+
stale: number;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Convert to relative path if absolute
|
|
140
|
+
*/
|
|
141
|
+
private toRelativePath;
|
|
142
|
+
/**
|
|
143
|
+
* Convert to absolute path if relative
|
|
144
|
+
*/
|
|
145
|
+
private toAbsolutePath;
|
|
146
|
+
/**
|
|
147
|
+
* Format file size for display
|
|
148
|
+
*/
|
|
149
|
+
private formatSize;
|
|
150
|
+
/**
|
|
151
|
+
* Format timestamp for display
|
|
152
|
+
*/
|
|
153
|
+
private formatTimestamp;
|
|
154
|
+
/**
|
|
155
|
+
* Generate detailed status report
|
|
156
|
+
*/
|
|
157
|
+
generateStatusReport(): Promise<string>;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=timestamp-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp-tracker.d.ts","sourceRoot":"","sources":["../../src/agent-system/timestamp-tracker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAU;gBAEb,EAAE,EAAE,cAAc,EAAE,OAAO,GAAE,uBAA4B;IAMrE;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IA2C1F;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAyBnE;;;;;;;OAOG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuDtD;;;;;OAKG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAWnE;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAI1F;;;;;OAKG;IACG,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiB1E;;;;OAIG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBzD;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAyBlD;;;;;OAKG;IACG,kBAAkB,CAAC,OAAO,GAAE,MAAW,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA2BxE;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBjE;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IA6BF;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAsC9C"}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timestamp Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks file timestamps for synchronization and drift detection.
|
|
5
|
+
* Stores and retrieves file modification times from the database.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
/**
|
|
10
|
+
* Timestamp Tracker
|
|
11
|
+
*
|
|
12
|
+
* Manages file timestamps for synchronization tracking.
|
|
13
|
+
*/
|
|
14
|
+
export class TimestampTracker {
|
|
15
|
+
db;
|
|
16
|
+
projectRoot;
|
|
17
|
+
verbose;
|
|
18
|
+
constructor(db, options = {}) {
|
|
19
|
+
this.db = db;
|
|
20
|
+
this.projectRoot = options.projectRoot || process.cwd();
|
|
21
|
+
this.verbose = options.verbose || false;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Record file timestamp
|
|
25
|
+
*
|
|
26
|
+
* @param filePath - Relative or absolute file path
|
|
27
|
+
* @param gitCommit - Optional git commit SHA
|
|
28
|
+
*/
|
|
29
|
+
async recordTimestamp(filePath, gitCommit) {
|
|
30
|
+
try {
|
|
31
|
+
const relativePath = this.toRelativePath(filePath);
|
|
32
|
+
const absolutePath = this.toAbsolutePath(relativePath);
|
|
33
|
+
const stats = await fs.stat(absolutePath);
|
|
34
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
35
|
+
const hash = this.db.hashContent(content);
|
|
36
|
+
const timestamp = {
|
|
37
|
+
path: relativePath,
|
|
38
|
+
modifiedTime: stats.mtime.toISOString(),
|
|
39
|
+
size: stats.size,
|
|
40
|
+
hash,
|
|
41
|
+
lastChecked: new Date().toISOString(),
|
|
42
|
+
gitCommit
|
|
43
|
+
};
|
|
44
|
+
// Store in database
|
|
45
|
+
this.db.prepare('INSERT OR REPLACE INTO file_timestamps (path, modified_time, size, hash, last_checked, git_commit) VALUES (?, ?, ?, ?, ?, ?)').run(relativePath, timestamp.modifiedTime, timestamp.size, timestamp.hash, timestamp.lastChecked, gitCommit || null);
|
|
46
|
+
if (this.verbose) {
|
|
47
|
+
console.log(`Recorded timestamp: ${relativePath}`);
|
|
48
|
+
}
|
|
49
|
+
return timestamp;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (this.verbose) {
|
|
53
|
+
console.warn(`Failed to record timestamp for ${filePath}:`, error);
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get stored timestamp for a file
|
|
60
|
+
*
|
|
61
|
+
* @param filePath - Relative or absolute file path
|
|
62
|
+
* @returns Timestamp record or null
|
|
63
|
+
*/
|
|
64
|
+
async getTimestamp(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
const relativePath = this.toRelativePath(filePath);
|
|
67
|
+
const row = this.db.prepare('SELECT * FROM file_timestamps WHERE path = ?').get(relativePath);
|
|
68
|
+
if (!row)
|
|
69
|
+
return null;
|
|
70
|
+
return {
|
|
71
|
+
path: typeof row.path === 'string' ? row.path : relativePath,
|
|
72
|
+
modifiedTime: typeof row.modified_time === 'string' ? row.modified_time : '',
|
|
73
|
+
size: typeof row.size === 'number' ? row.size : 0,
|
|
74
|
+
hash: typeof row.hash === 'string' ? row.hash : '',
|
|
75
|
+
lastChecked: typeof row.last_checked === 'string' ? row.last_checked : '',
|
|
76
|
+
gitCommit: typeof row.git_commit === 'string' ? row.git_commit : undefined
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (this.verbose) {
|
|
81
|
+
console.warn(`Failed to get timestamp for ${filePath}:`, error);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if file is in sync
|
|
88
|
+
*
|
|
89
|
+
* Compares current file state with stored timestamp.
|
|
90
|
+
*
|
|
91
|
+
* @param filePath - Relative or absolute file path
|
|
92
|
+
* @returns Sync status
|
|
93
|
+
*/
|
|
94
|
+
async checkSync(filePath) {
|
|
95
|
+
try {
|
|
96
|
+
const relativePath = this.toRelativePath(filePath);
|
|
97
|
+
const absolutePath = this.toAbsolutePath(relativePath);
|
|
98
|
+
// Get stored timestamp
|
|
99
|
+
const stored = await this.getTimestamp(relativePath);
|
|
100
|
+
if (!stored) {
|
|
101
|
+
return {
|
|
102
|
+
path: relativePath,
|
|
103
|
+
inSync: false,
|
|
104
|
+
hashDiff: true
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Get current file state
|
|
108
|
+
const stats = await fs.stat(absolutePath);
|
|
109
|
+
const content = await fs.readFile(absolutePath, 'utf-8');
|
|
110
|
+
const currentHash = this.db.hashContent(content);
|
|
111
|
+
// Check if hash matches
|
|
112
|
+
const hashDiff = currentHash !== stored.hash;
|
|
113
|
+
if (hashDiff) {
|
|
114
|
+
return {
|
|
115
|
+
path: relativePath,
|
|
116
|
+
inSync: false,
|
|
117
|
+
hashDiff: true
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Check time difference (allow 1 second tolerance for filesystem precision)
|
|
121
|
+
const storedTime = new Date(stored.modifiedTime).getTime();
|
|
122
|
+
const currentTime = stats.mtime.getTime();
|
|
123
|
+
const timeDiff = Math.abs(currentTime - storedTime);
|
|
124
|
+
// Consider out of sync if time differs by more than 1 second
|
|
125
|
+
const inSync = timeDiff <= 1000;
|
|
126
|
+
return {
|
|
127
|
+
path: relativePath,
|
|
128
|
+
inSync,
|
|
129
|
+
timeDiff: timeDiff
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (this.verbose) {
|
|
134
|
+
console.warn(`Failed to check sync for ${filePath}:`, error);
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
path: this.toRelativePath(filePath),
|
|
138
|
+
inSync: false,
|
|
139
|
+
hashDiff: true
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check multiple files for sync status
|
|
145
|
+
*
|
|
146
|
+
* @param filePaths - Array of file paths
|
|
147
|
+
* @returns Array of sync statuses
|
|
148
|
+
*/
|
|
149
|
+
async checkMultipleSync(filePaths) {
|
|
150
|
+
const results = [];
|
|
151
|
+
for (const filePath of filePaths) {
|
|
152
|
+
const status = await this.checkSync(filePath);
|
|
153
|
+
results.push(status);
|
|
154
|
+
}
|
|
155
|
+
return results;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Update timestamp for a file
|
|
159
|
+
*
|
|
160
|
+
* @param filePath - Relative or absolute file path
|
|
161
|
+
* @param gitCommit - Optional git commit SHA
|
|
162
|
+
*/
|
|
163
|
+
async updateTimestamp(filePath, gitCommit) {
|
|
164
|
+
return await this.recordTimestamp(filePath, gitCommit);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Batch update timestamps for multiple files
|
|
168
|
+
*
|
|
169
|
+
* @param filePaths - Array of file paths
|
|
170
|
+
* @returns Array of updated timestamps
|
|
171
|
+
*/
|
|
172
|
+
async batchUpdateTimestamps(filePaths) {
|
|
173
|
+
const results = [];
|
|
174
|
+
for (const filePath of filePaths) {
|
|
175
|
+
const timestamp = await this.updateTimestamp(filePath);
|
|
176
|
+
if (timestamp) {
|
|
177
|
+
results.push(timestamp);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (this.verbose) {
|
|
181
|
+
console.log(`Batch updated ${results.length} timestamps`);
|
|
182
|
+
}
|
|
183
|
+
return results;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Remove timestamp record
|
|
187
|
+
*
|
|
188
|
+
* @param filePath - File path to remove
|
|
189
|
+
*/
|
|
190
|
+
async removeTimestamp(filePath) {
|
|
191
|
+
try {
|
|
192
|
+
const relativePath = this.toRelativePath(filePath);
|
|
193
|
+
const result = this.db.prepare('DELETE FROM file_timestamps WHERE path = ?').run(relativePath);
|
|
194
|
+
const removed = result.changes > 0;
|
|
195
|
+
if (removed && this.verbose) {
|
|
196
|
+
console.log(`Removed timestamp: ${relativePath}`);
|
|
197
|
+
}
|
|
198
|
+
return removed;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (this.verbose) {
|
|
202
|
+
console.warn(`Failed to remove timestamp for ${filePath}:`, error);
|
|
203
|
+
}
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get all tracked timestamps
|
|
209
|
+
*
|
|
210
|
+
* @returns Array of all timestamp records
|
|
211
|
+
*/
|
|
212
|
+
async getAllTimestamps() {
|
|
213
|
+
try {
|
|
214
|
+
const rows = this.db.prepare('SELECT * FROM file_timestamps ORDER BY last_checked DESC').all();
|
|
215
|
+
return rows.map((row) => {
|
|
216
|
+
const r = row;
|
|
217
|
+
return {
|
|
218
|
+
path: typeof r.path === 'string' ? r.path : '',
|
|
219
|
+
modifiedTime: typeof r.modified_time === 'string' ? r.modified_time : '',
|
|
220
|
+
size: typeof r.size === 'number' ? r.size : 0,
|
|
221
|
+
hash: typeof r.hash === 'string' ? r.hash : '',
|
|
222
|
+
lastChecked: typeof r.last_checked === 'string' ? r.last_checked : '',
|
|
223
|
+
gitCommit: typeof r.git_commit === 'string' ? r.git_commit : undefined
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
if (this.verbose) {
|
|
229
|
+
console.warn('Failed to get all timestamps:', error);
|
|
230
|
+
}
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get stale timestamp records
|
|
236
|
+
*
|
|
237
|
+
* @param daysOld - Consider records older than this many days as stale
|
|
238
|
+
* @returns Array of stale timestamps
|
|
239
|
+
*/
|
|
240
|
+
async getStaleTimestamps(daysOld = 30) {
|
|
241
|
+
try {
|
|
242
|
+
const cutoff = new Date(Date.now() - (daysOld * 24 * 60 * 60 * 1000)).toISOString();
|
|
243
|
+
const rows = this.db.prepare('SELECT * FROM file_timestamps WHERE last_checked < ? ORDER BY last_checked ASC').all(cutoff);
|
|
244
|
+
return rows.map((row) => {
|
|
245
|
+
const r = row;
|
|
246
|
+
return {
|
|
247
|
+
path: typeof r.path === 'string' ? r.path : '',
|
|
248
|
+
modifiedTime: typeof r.modified_time === 'string' ? r.modified_time : '',
|
|
249
|
+
size: typeof r.size === 'number' ? r.size : 0,
|
|
250
|
+
hash: typeof r.hash === 'string' ? r.hash : '',
|
|
251
|
+
lastChecked: typeof r.last_checked === 'string' ? r.last_checked : '',
|
|
252
|
+
gitCommit: typeof r.git_commit === 'string' ? r.git_commit : undefined
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
if (this.verbose) {
|
|
258
|
+
console.warn('Failed to get stale timestamps:', error);
|
|
259
|
+
}
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Clean up old timestamp records
|
|
265
|
+
*
|
|
266
|
+
* @param daysOld - Remove records older than this many days
|
|
267
|
+
* @returns Number of records removed
|
|
268
|
+
*/
|
|
269
|
+
async cleanupOldTimestamps(daysOld = 90) {
|
|
270
|
+
try {
|
|
271
|
+
const cutoff = new Date(Date.now() - (daysOld * 24 * 60 * 60 * 1000)).toISOString();
|
|
272
|
+
const result = this.db.prepare('DELETE FROM file_timestamps WHERE last_checked < ?').run(cutoff);
|
|
273
|
+
const removed = result.changes;
|
|
274
|
+
if (this.verbose) {
|
|
275
|
+
console.log(`Cleaned up ${removed} old timestamp records`);
|
|
276
|
+
}
|
|
277
|
+
return removed;
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
if (this.verbose) {
|
|
281
|
+
console.warn('Failed to cleanup old timestamps:', error);
|
|
282
|
+
}
|
|
283
|
+
return 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get sync summary for tracked files
|
|
288
|
+
*
|
|
289
|
+
* @returns Summary of sync status
|
|
290
|
+
*/
|
|
291
|
+
async getSyncSummary() {
|
|
292
|
+
try {
|
|
293
|
+
const all = await this.getAllTimestamps();
|
|
294
|
+
const syncStatuses = await Promise.all(all.map(t => this.checkSync(t.path)));
|
|
295
|
+
const inSync = syncStatuses.filter(s => s.inSync).length;
|
|
296
|
+
const stale = await this.getStaleTimestamps(30);
|
|
297
|
+
return {
|
|
298
|
+
total: all.length,
|
|
299
|
+
inSync,
|
|
300
|
+
outOfSync: syncStatuses.length - inSync,
|
|
301
|
+
stale: stale.length
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
if (this.verbose) {
|
|
306
|
+
console.warn('Failed to get sync summary:', error);
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
total: 0,
|
|
310
|
+
inSync: 0,
|
|
311
|
+
outOfSync: 0,
|
|
312
|
+
stale: 0
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Convert to relative path if absolute
|
|
318
|
+
*/
|
|
319
|
+
toRelativePath(filePath) {
|
|
320
|
+
if (path.isAbsolute(filePath)) {
|
|
321
|
+
return path.relative(this.projectRoot, filePath);
|
|
322
|
+
}
|
|
323
|
+
return filePath;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Convert to absolute path if relative
|
|
327
|
+
*/
|
|
328
|
+
toAbsolutePath(filePath) {
|
|
329
|
+
if (path.isAbsolute(filePath)) {
|
|
330
|
+
return filePath;
|
|
331
|
+
}
|
|
332
|
+
return path.join(this.projectRoot, filePath);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Format file size for display
|
|
336
|
+
*/
|
|
337
|
+
formatSize(bytes) {
|
|
338
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
339
|
+
let size = bytes;
|
|
340
|
+
let unitIndex = 0;
|
|
341
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
342
|
+
size /= 1024;
|
|
343
|
+
unitIndex++;
|
|
344
|
+
}
|
|
345
|
+
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Format timestamp for display
|
|
349
|
+
*/
|
|
350
|
+
formatTimestamp(isoString) {
|
|
351
|
+
const date = new Date(isoString);
|
|
352
|
+
const now = new Date();
|
|
353
|
+
const diffMs = now.getTime() - date.getTime();
|
|
354
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
355
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
356
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
357
|
+
if (diffDays > 0) {
|
|
358
|
+
return `${date.toLocaleDateString()} (${diffDays}d ago)`;
|
|
359
|
+
}
|
|
360
|
+
else if (diffHours > 0) {
|
|
361
|
+
return `${date.toLocaleDateString()} (${diffHours}h ago)`;
|
|
362
|
+
}
|
|
363
|
+
else if (diffMins > 0) {
|
|
364
|
+
return `${date.toLocaleDateString()} (${diffMins}m ago)`;
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
return date.toLocaleTimeString();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Generate detailed status report
|
|
372
|
+
*/
|
|
373
|
+
async generateStatusReport() {
|
|
374
|
+
const summary = await this.getSyncSummary();
|
|
375
|
+
const allTimestamps = await this.getAllTimestamps();
|
|
376
|
+
let report = '# Timestamp Tracker Status Report\n\n';
|
|
377
|
+
report += `**Generated:** ${new Date().toISOString()}\n\n`;
|
|
378
|
+
report += `## Summary\n\n`;
|
|
379
|
+
report += `- **Total Tracked:** ${summary.total} files\n`;
|
|
380
|
+
report += `- **In Sync:** ${summary.inSync} files\n`;
|
|
381
|
+
report += `- **Out of Sync:** ${summary.outOfSync} files\n`;
|
|
382
|
+
report += `- **Stale (>30 days):** ${summary.stale} files\n\n`;
|
|
383
|
+
if (summary.outOfSync > 0) {
|
|
384
|
+
report += `## Out of Sync Files\n\n`;
|
|
385
|
+
const syncStatuses = await Promise.all(allTimestamps.map(t => this.checkSync(t.path)));
|
|
386
|
+
const outOfSync = syncStatuses.filter(s => !s.inSync);
|
|
387
|
+
for (const status of outOfSync.slice(0, 20)) {
|
|
388
|
+
report += `### ${status.path}\n`;
|
|
389
|
+
report += `- **Status:** Out of sync\n`;
|
|
390
|
+
if (status.timeDiff) {
|
|
391
|
+
report += `- **Time Diff:** ${status.timeDiff}ms\n`;
|
|
392
|
+
}
|
|
393
|
+
if (status.hashDiff) {
|
|
394
|
+
report += `- **Hash:** Different\n`;
|
|
395
|
+
}
|
|
396
|
+
report += '\n';
|
|
397
|
+
}
|
|
398
|
+
if (outOfSync.length > 20) {
|
|
399
|
+
report += `\n... and ${outOfSync.length - 20} more\n`;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return report;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=timestamp-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp-tracker.js","sourceRoot":"","sources":["../../src/agent-system/timestamp-tracker.ts"],"names":[],"mappings":"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"}
|